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

pull/1935/head
Kim Kulling 2018-05-01 15:06:56 +02:00
parent eced86b949
commit 037a213bb4
5 changed files with 53 additions and 29 deletions

View File

@ -477,7 +477,7 @@ size_t Exporter::GetExportFormatCount() const {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
const aiExportFormatDesc* Exporter::GetExportFormatDescription( size_t index ) const { const aiExportFormatDesc* Exporter::GetExportFormatDescription( size_t index ) const {
if (index >= GetExportFormatCount()) { if (index >= GetExportFormatCount()) {
return NULL; return nullptr;
} }
// Return from static storage if the requested index is built-in. // 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 // 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); return SetGenericProperty<std::string>(mStringProperties, szName,value);
} }

View File

@ -143,7 +143,7 @@ STLExporter::STLExporter(const char* _filename, const aiScene* pScene, bool expo
// Export the assimp mesh // Export the assimp mesh
const std::string name = "AssimpScene"; const std::string name = "AssimpScene";
mOutput << SolidToken << name << endl; mOutput << SolidToken << " " << name << endl;
for(unsigned int i = 0; i < pScene->mNumMeshes; ++i) { for(unsigned int i = 0; i < pScene->mNumMeshes; ++i) {
WriteMesh(pScene->mMeshes[ 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 << " 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) { for(unsigned int a = 0; a < f.mNumIndices; ++a) {
nor += m->mNormals[f.mIndices[a]]; nor += m->mNormals[f.mIndices[a]];
} }
nor.Normalize(); nor.NormalizeSafe();
} }
mOutput << " facet normal " << nor.x << " " << nor.y << " " << nor.z << endl; mOutput << " facet normal " << nor.x << " " << nor.y << " " << nor.z << endl;
mOutput << " outer loop" << endl; mOutput << " outer loop" << endl;

View File

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

View File

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

View File

@ -75,6 +75,17 @@ TEST_F( utSTLImporterExporter, test_with_two_solids ) {
#ifndef ASSIMP_BUILD_NO_EXPORT #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) { TEST_F(utSTLImporterExporter, test_export_pointclouds) {
struct XYZ { struct XYZ {
float x, y, z; float x, y, z;
@ -126,6 +137,8 @@ TEST_F(utSTLImporterExporter, test_export_pointclouds) {
ExportProperties *properties = new ExportProperties; ExportProperties *properties = new ExportProperties;
properties->SetPropertyBool(AI_CONFIG_EXPORT_POINT_CLOUDS, true); properties->SetPropertyBool(AI_CONFIG_EXPORT_POINT_CLOUDS, true);
mAiExporter.Export(&scene, "stl", "testExport.stl", 0, properties ); mAiExporter.Export(&scene, "stl", "testExport.stl", 0, properties );
delete properties;
} }
#endif #endif