diff --git a/code/FBXBinaryTokenizer.cpp b/code/FBXBinaryTokenizer.cpp index 9ae38386b..519f2e176 100644 --- a/code/FBXBinaryTokenizer.cpp +++ b/code/FBXBinaryTokenizer.cpp @@ -422,7 +422,6 @@ bool ReadScope(TokenList& output_tokens, const char* input, const char*& cursor, return true; } - } // ------------------------------------------------------------------------------------------------ diff --git a/code/FindDegenerates.cpp b/code/FindDegenerates.cpp index 32a09f0c0..5b321312a 100644 --- a/code/FindDegenerates.cpp +++ b/code/FindDegenerates.cpp @@ -56,98 +56,131 @@ using namespace Assimp; // ------------------------------------------------------------------------------------------------ // Constructor to be privately used by Importer FindDegeneratesProcess::FindDegeneratesProcess() -: configRemoveDegenerates (false) -{} +: configRemoveDegenerates (false) { + // empty +} // ------------------------------------------------------------------------------------------------ // Destructor, private as well -FindDegeneratesProcess::~FindDegeneratesProcess() -{ +FindDegeneratesProcess::~FindDegeneratesProcess() { // nothing to do here } // ------------------------------------------------------------------------------------------------ // Returns whether the processing step is present in the given flag field. -bool FindDegeneratesProcess::IsActive( unsigned int pFlags) const -{ +bool FindDegeneratesProcess::IsActive( unsigned int pFlags) const { return 0 != (pFlags & aiProcess_FindDegenerates); } // ------------------------------------------------------------------------------------------------ // Setup import configuration -void FindDegeneratesProcess::SetupProperties(const Importer* pImp) -{ +void FindDegeneratesProcess::SetupProperties(const Importer* pImp) { // Get the current value of AI_CONFIG_PP_FD_REMOVE configRemoveDegenerates = (0 != pImp->GetPropertyInteger(AI_CONFIG_PP_FD_REMOVE,0)); } // ------------------------------------------------------------------------------------------------ // Executes the post processing step on the given imported data. -void FindDegeneratesProcess::Execute( aiScene* pScene) -{ +void FindDegeneratesProcess::Execute( aiScene* pScene) { DefaultLogger::get()->debug("FindDegeneratesProcess begin"); for (unsigned int i = 0; i < pScene->mNumMeshes;++i){ - ExecuteOnMesh( pScene->mMeshes[i]); + ExecuteOnMesh( pScene->mMeshes[ i ] ); } DefaultLogger::get()->debug("FindDegeneratesProcess finished"); } +static ai_real heron( ai_real a, ai_real b, ai_real c ) { + ai_real s = (a + b + c) / 2; + ai_real area = pow((s * ( s - a ) * ( s - b ) * ( s - c ) ), 0.5 ); + return area; +} + +static ai_real distance3D( const aiVector3D &vA, aiVector3D &vB ) { + const ai_real lx = ( vB.x - vA.x ); + const ai_real ly = ( vB.y - vA.y ); + const ai_real lz = ( vB.z - vA.z ); + ai_real a = lx*lx + ly*ly + lz*lz; + ai_real d = pow( a, 0.5 ); + + return d; +} + +static ai_real calculateAreaOfTriangle( const aiFace& face, aiMesh* mesh ) { + ai_real area = 0; + + aiVector3D vA( mesh->mVertices[ face.mIndices[ 0 ] ] ); + aiVector3D vB( mesh->mVertices[ face.mIndices[ 1 ] ] ); + aiVector3D vC( mesh->mVertices[ face.mIndices[ 2 ] ] ); + + ai_real a( distance3D( vA, vB ) ); + ai_real b( distance3D( vB, vC ) ); + ai_real c( distance3D( vC, vA ) ); + area = heron( a, b, c ); + + return area; +} + // ------------------------------------------------------------------------------------------------ // Executes the post processing step on the given imported mesh -void FindDegeneratesProcess::ExecuteOnMesh( aiMesh* mesh) -{ +void FindDegeneratesProcess::ExecuteOnMesh( aiMesh* mesh) { mesh->mPrimitiveTypes = 0; std::vector remove_me; - if (configRemoveDegenerates) - remove_me.resize(mesh->mNumFaces,false); + if (configRemoveDegenerates) { + remove_me.resize( mesh->mNumFaces, false ); + } unsigned int deg = 0, limit; - for (unsigned int a = 0; a < mesh->mNumFaces; ++a) - { + for ( unsigned int a = 0; a < mesh->mNumFaces; ++a ) { aiFace& face = mesh->mFaces[a]; bool first = true; // check whether the face contains degenerated entries - for (unsigned int i = 0; i < face.mNumIndices; ++i) - { + for (unsigned int i = 0; i < face.mNumIndices; ++i) { // Polygons with more than 4 points are allowed to have double points, that is // simulating polygons with holes just with concave polygons. However, // double points may not come directly after another. limit = face.mNumIndices; - if (face.mNumIndices > 4) - limit = std::min(limit,i+2); + if (face.mNumIndices > 4) { + limit = std::min( limit, i+2 ); + } - for (unsigned int t = i+1; t < limit; ++t) - { - if (mesh->mVertices[face.mIndices[i]] == mesh->mVertices[face.mIndices[t]]) - { + for (unsigned int t = i+1; t < limit; ++t) { + if (mesh->mVertices[face.mIndices[ i ] ] == mesh->mVertices[ face.mIndices[ t ] ]) { // we have found a matching vertex position // remove the corresponding index from the array - --face.mNumIndices;--limit; - for (unsigned int m = t; m < face.mNumIndices; ++m) - { - face.mIndices[m] = face.mIndices[m+1]; + --face.mNumIndices; + --limit; + for (unsigned int m = t; m < face.mNumIndices; ++m) { + face.mIndices[ m ] = face.mIndices[ m+1 ]; } --t; // NOTE: we set the removed vertex index to an unique value // to make sure the developer gets notified when his // application attemps to access this data. - face.mIndices[face.mNumIndices] = 0xdeadbeef; + face.mIndices[ face.mNumIndices ] = 0xdeadbeef; - if(first) - { + if(first) { ++deg; first = false; } - if (configRemoveDegenerates) { - remove_me[a] = true; + if ( configRemoveDegenerates ) { + remove_me[ a ] = true; goto evil_jump_outside; // hrhrhrh ... yeah, this rocks baby! } } } + ai_real area = calculateAreaOfTriangle( face, mesh ); + if ( area < 1e-6 ) { + if ( configRemoveDegenerates ) { + remove_me[ a ] = true; + goto evil_jump_outside; + } + + // todo: check for index which is corrupt. + } } // We need to update the primitive flags array of the mesh. diff --git a/code/STLLoader.cpp b/code/STLLoader.cpp index 600c4275d..41f8aad03 100644 --- a/code/STLLoader.cpp +++ b/code/STLLoader.cpp @@ -207,12 +207,6 @@ void STLImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOS throw DeadlyImportError( "Failed to determine STL storage representation for " + pFile + "."); } - // add all created meshes to the single node - /*pScene->mRootNode->mNumMeshes = pScene->mNumMeshes; - pScene->mRootNode->mMeshes = new unsigned int[pScene->mNumMeshes]; - for (unsigned int i = 0; i < pScene->mNumMeshes; i++) - pScene->mRootNode->mMeshes[i] = i; - */ // create a single default material, using a white diffuse color for consistency with // other geometric types (e.g., PLY). aiMaterial* pcMat = new aiMaterial(); diff --git a/code/XFileImporter.h b/code/XFileImporter.h index 528dcb851..0fa6b52eb 100644 --- a/code/XFileImporter.h +++ b/code/XFileImporter.h @@ -65,14 +65,11 @@ struct Node; /** The XFileImporter is a worker class capable of importing a scene from a * DirectX file .x */ -class XFileImporter : public BaseImporter -{ +class XFileImporter : public BaseImporter { public: XFileImporter(); ~XFileImporter(); - -public: // ------------------------------------------------------------------- /** Returns whether the class can handle the format of the given file. * See BaseImporter::CanRead() for details. */