Explorar el Código

STL-Exporter: fix division by zero in normalize method during update

Kim Kulling hace 7 años
padre
commit
037a213bb4

+ 2 - 3
code/Exporter.cpp

@@ -477,7 +477,7 @@ size_t Exporter::GetExportFormatCount() const {
 // ------------------------------------------------------------------------------------------------
 const aiExportFormatDesc* Exporter::GetExportFormatDescription( size_t index ) const {
     if (index >= GetExportFormatCount()) {
-        return NULL;
+        return nullptr;
     }
 
     // Return from static storage if the requested index is built-in.
@@ -539,8 +539,7 @@ bool ExportProperties::SetPropertyFloat(const char* szName, ai_real iValue) {
 
 // ------------------------------------------------------------------------------------------------
 // Set a configuration property
-bool ExportProperties :: SetPropertyString(const char* szName, const std::string& value)
-{
+bool ExportProperties::SetPropertyString(const char* szName, const std::string& value) {
     return SetGenericProperty<std::string>(mStringProperties, szName,value);
 }
 

+ 4 - 4
code/STLExporter.cpp

@@ -143,7 +143,7 @@ STLExporter::STLExporter(const char* _filename, const aiScene* pScene, bool expo
 
         // Export the assimp mesh 
         const std::string name = "AssimpScene";
-        mOutput << SolidToken << name << endl;
+        mOutput << SolidToken << " " << name << endl;
         for(unsigned int i = 0; i < pScene->mNumMeshes; ++i) {
             WriteMesh(pScene->mMeshes[ i ]);
         }
@@ -169,7 +169,7 @@ void STLExporter::WritePointCloud(const std::string &name, const aiScene* pScene
             mOutput << "  vertex " << v.x << " " << v.y << " " << v.z << endl;
         }
     }
-    mOutput << EndSolidToken << name << endl;
+    mOutput << EndSolidToken << " " << name << endl;
 }
 
 // ------------------------------------------------------------------------------------------------
@@ -185,7 +185,7 @@ void STLExporter::WriteMesh(const aiMesh* m)
             for(unsigned int a = 0; a < f.mNumIndices; ++a) {
                 nor += m->mNormals[f.mIndices[a]];
             }
-            nor.Normalize();
+            nor.NormalizeSafe();
         }
         mOutput << " facet normal " << nor.x << " " << nor.y << " " << nor.z << endl;
         mOutput << "  outer loop" << endl;
@@ -199,7 +199,7 @@ void STLExporter::WriteMesh(const aiMesh* m)
     }
 }
 
-void STLExporter :: WriteMeshBinary(const aiMesh* m)
+void STLExporter::WriteMeshBinary(const aiMesh* m)
 {
     for (unsigned int i = 0; i < m->mNumFaces; ++i) {
         const aiFace& f = m->mFaces[i];

+ 7 - 1
include/assimp/Exporter.hpp

@@ -115,8 +115,14 @@ public:
         }
     };
 
-public:
+    /**
+     *  @brief  The class constructor.
+     */
     Exporter();
+
+    /**
+    *  @brief  The class destructor.
+    */
     ~Exporter();
 
     // -------------------------------------------------------------------

+ 27 - 21
include/assimp/GenericProperty.h

@@ -46,15 +46,15 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include <assimp/Importer.hpp>
 #include <assimp/ai_assert.h>
 #include "Hash.h"
-#include <map>
 
+#include <map>
 
 // ------------------------------------------------------------------------------------------------
 template <class T>
-inline bool SetGenericProperty(std::map< unsigned int, T >& list,
-    const char* szName, const T& value)
-{
-    ai_assert(NULL != szName);
+inline
+bool SetGenericProperty(std::map< unsigned int, T >& list,
+        const char* szName, const T& value) {
+    ai_assert(nullptr != szName);
     const uint32_t hash = SuperFastHash(szName);
 
     typename std::map<unsigned int, T>::iterator it = list.find(hash);
@@ -63,20 +63,22 @@ inline bool SetGenericProperty(std::map< unsigned int, T >& list,
         return false;
     }
     (*it).second = value;
+
     return true;
 }
 
 // ------------------------------------------------------------------------------------------------
 template <class T>
-inline const T& GetGenericProperty(const std::map< unsigned int, T >& list,
-    const char* szName, const T& errorReturn)
-{
-    ai_assert(NULL != szName);
+inline
+const T& GetGenericProperty(const std::map< unsigned int, T >& list,
+        const char* szName, const T& errorReturn) {
+    ai_assert(nullptr != szName);
     const uint32_t hash = SuperFastHash(szName);
 
     typename std::map<unsigned int, T>::const_iterator it = list.find(hash);
-    if (it == list.end())
+    if (it == list.end()) {
         return errorReturn;
+    }
 
     return (*it).second;
 }
@@ -85,16 +87,17 @@ inline const T& GetGenericProperty(const std::map< unsigned int, T >& list,
 // Special version for pointer types - they will be deleted when replaced with another value
 // passing NULL removes the whole property
 template <class T>
-inline void SetGenericPropertyPtr(std::map< unsigned int, T* >& list,
-    const char* szName, T* value, bool* bWasExisting = NULL)
-{
-    ai_assert(NULL != szName);
+inline
+void SetGenericPropertyPtr(std::map< unsigned int, T* >& list,
+        const char* szName, T* value, bool* bWasExisting = nullptr ) {
+    ai_assert(nullptr != szName);
     const uint32_t hash = SuperFastHash(szName);
 
     typename std::map<unsigned int, T*>::iterator it = list.find(hash);
     if (it == list.end())   {
-        if (bWasExisting)
+        if (bWasExisting) {
             *bWasExisting = false;
+        }
 
         list.insert(std::pair<unsigned int,T*>( hash, value ));
         return;
@@ -106,20 +109,23 @@ inline void SetGenericPropertyPtr(std::map< unsigned int, T* >& list,
     if (!value) {
         list.erase(it);
     }
-    if (bWasExisting)
+    if (bWasExisting) {
         *bWasExisting = true;
+    }
 }
 
 // ------------------------------------------------------------------------------------------------
 template <class T>
-inline bool HasGenericProperty(const std::map< unsigned int, T >& list,
-    const char* szName)
-{
-    ai_assert(NULL != szName);
+inline
+bool HasGenericProperty(const std::map< unsigned int, T >& list,
+        const char* szName) {
+    ai_assert(nullptr != szName);
     const uint32_t hash = SuperFastHash(szName);
 
     typename std::map<unsigned int, T>::const_iterator it = list.find(hash);
-    if (it == list.end()) return false;
+    if (it == list.end()) {
+        return false;
+    }
 
     return true;
 }

+ 13 - 0
test/unit/utSTLImportExport.cpp

@@ -75,6 +75,17 @@ TEST_F( utSTLImporterExporter, test_with_two_solids ) {
 
 #ifndef ASSIMP_BUILD_NO_EXPORT
 
+TEST_F(utSTLImporterExporter, exporterTest) {
+    Assimp::Importer importer;
+    const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/STL/Spider_ascii.stl", aiProcess_ValidateDataStructure);
+
+    Assimp::Exporter mAiExporter;
+    mAiExporter.Export( scene, "stl", "spiderExport.stl" );
+
+    const aiScene *scene2 = importer.ReadFile("spiderExport.stl", aiProcess_ValidateDataStructure);
+    //EXPECT_NE(nullptr, scene2);
+}
+
 TEST_F(utSTLImporterExporter, test_export_pointclouds) {
     struct XYZ {
         float x, y, z;
@@ -126,6 +137,8 @@ TEST_F(utSTLImporterExporter, test_export_pointclouds) {
     ExportProperties *properties = new ExportProperties;
     properties->SetPropertyBool(AI_CONFIG_EXPORT_POINT_CLOUDS, true);
     mAiExporter.Export(&scene, "stl", "testExport.stl", 0, properties );
+
+    delete properties;
 }
 
 #endif