|
@@ -54,6 +54,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
|
|
using namespace Assimp;
|
|
using namespace Assimp;
|
|
|
|
|
|
|
|
+//remove mesh at position 'index' from the scene
|
|
|
|
+static void removeMesh(aiScene* pScene, unsigned const index);
|
|
|
|
+//correct node indices to meshes and remove references to deleted mesh
|
|
|
|
+static void updateSceneGraph(aiNode* pNode, unsigned const index);
|
|
|
|
+
|
|
// ------------------------------------------------------------------------------------------------
|
|
// ------------------------------------------------------------------------------------------------
|
|
// Constructor to be privately used by Importer
|
|
// Constructor to be privately used by Importer
|
|
FindDegeneratesProcess::FindDegeneratesProcess()
|
|
FindDegeneratesProcess::FindDegeneratesProcess()
|
|
@@ -87,11 +92,50 @@ void FindDegeneratesProcess::SetupProperties(const Importer* pImp) {
|
|
void FindDegeneratesProcess::Execute( aiScene* pScene) {
|
|
void FindDegeneratesProcess::Execute( aiScene* pScene) {
|
|
ASSIMP_LOG_DEBUG("FindDegeneratesProcess begin");
|
|
ASSIMP_LOG_DEBUG("FindDegeneratesProcess begin");
|
|
for (unsigned int i = 0; i < pScene->mNumMeshes;++i){
|
|
for (unsigned int i = 0; i < pScene->mNumMeshes;++i){
|
|
- ExecuteOnMesh( pScene->mMeshes[ i ] );
|
|
|
|
|
|
+ if (ExecuteOnMesh(pScene->mMeshes[i])) {
|
|
|
|
+ removeMesh(pScene, i);
|
|
|
|
+ --i; //the current i is removed, do not skip the next one
|
|
|
|
+ }
|
|
}
|
|
}
|
|
ASSIMP_LOG_DEBUG("FindDegeneratesProcess finished");
|
|
ASSIMP_LOG_DEBUG("FindDegeneratesProcess finished");
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static void removeMesh(aiScene* pScene, unsigned const index) {
|
|
|
|
+ //we start at index and copy the pointers one position forward
|
|
|
|
+ //save the mesh pointer to delete it later
|
|
|
|
+ auto delete_me = pScene->mMeshes[index];
|
|
|
|
+ for (unsigned i = index; i < pScene->mNumMeshes - 1; ++i) {
|
|
|
|
+ pScene->mMeshes[i] = pScene->mMeshes[i+1];
|
|
|
|
+ }
|
|
|
|
+ pScene->mMeshes[pScene->mNumMeshes - 1] = nullptr;
|
|
|
|
+ --(pScene->mNumMeshes);
|
|
|
|
+ delete delete_me;
|
|
|
|
+
|
|
|
|
+ //removing a mesh also requires updating all references to it in the scene graph
|
|
|
|
+ updateSceneGraph(pScene->mRootNode, index);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static void updateSceneGraph(aiNode* pNode, unsigned const index) {
|
|
|
|
+ for (unsigned i = 0; i < pNode->mNumMeshes; ++i) {
|
|
|
|
+ if (pNode->mMeshes[i] > index) {
|
|
|
|
+ --(pNode->mMeshes[i]);
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+ if (pNode->mMeshes[i] == index) {
|
|
|
|
+ for (unsigned j = i; j < pNode->mNumMeshes -1; ++j) {
|
|
|
|
+ pNode->mMeshes[j] = pNode->mMeshes[j+1];
|
|
|
|
+ }
|
|
|
|
+ --(pNode->mNumMeshes);
|
|
|
|
+ --i;
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ //recurse to all children
|
|
|
|
+ for (unsigned i = 0; i < pNode->mNumChildren; ++i) {
|
|
|
|
+ updateSceneGraph(pNode->mChildren[i], index);
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
static ai_real heron( ai_real a, ai_real b, ai_real c ) {
|
|
static ai_real heron( ai_real a, ai_real b, ai_real c ) {
|
|
ai_real s = (a + b + c) / 2;
|
|
ai_real s = (a + b + c) / 2;
|
|
ai_real area = pow((s * ( s - a ) * ( s - b ) * ( s - c ) ), (ai_real)0.5 );
|
|
ai_real area = pow((s * ( s - a ) * ( s - b ) * ( s - c ) ), (ai_real)0.5 );
|
|
@@ -125,7 +169,7 @@ static ai_real calculateAreaOfTriangle( const aiFace& face, aiMesh* mesh ) {
|
|
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
// ------------------------------------------------------------------------------------------------
|
|
// Executes the post processing step on the given imported mesh
|
|
// Executes the post processing step on the given imported mesh
|
|
-void FindDegeneratesProcess::ExecuteOnMesh( aiMesh* mesh) {
|
|
|
|
|
|
+bool FindDegeneratesProcess::ExecuteOnMesh( aiMesh* mesh) {
|
|
mesh->mPrimitiveTypes = 0;
|
|
mesh->mPrimitiveTypes = 0;
|
|
|
|
|
|
std::vector<bool> remove_me;
|
|
std::vector<bool> remove_me;
|
|
@@ -227,30 +271,28 @@ evil_jump_outside:
|
|
if (&face_src != &face_dest) {
|
|
if (&face_src != &face_dest) {
|
|
// clear source
|
|
// clear source
|
|
face_src.mNumIndices = 0;
|
|
face_src.mNumIndices = 0;
|
|
- face_src.mIndices = NULL;
|
|
|
|
|
|
+ face_src.mIndices = nullptr;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
else {
|
|
// Otherwise delete it if we don't need this face
|
|
// Otherwise delete it if we don't need this face
|
|
delete[] face_src.mIndices;
|
|
delete[] face_src.mIndices;
|
|
- face_src.mIndices = NULL;
|
|
|
|
|
|
+ face_src.mIndices = nullptr;
|
|
face_src.mNumIndices = 0;
|
|
face_src.mNumIndices = 0;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// Just leave the rest of the array unreferenced, we don't care for now
|
|
// Just leave the rest of the array unreferenced, we don't care for now
|
|
mesh->mNumFaces = n;
|
|
mesh->mNumFaces = n;
|
|
if (!mesh->mNumFaces) {
|
|
if (!mesh->mNumFaces) {
|
|
- // WTF!?
|
|
|
|
- // OK ... for completeness and because I'm not yet tired,
|
|
|
|
- // let's write code that will hopefully never be called
|
|
|
|
- // (famous last words)
|
|
|
|
-
|
|
|
|
- // OK ... bad idea.
|
|
|
|
- throw DeadlyImportError("Mesh is empty after removal of degenerated primitives ... WTF!?");
|
|
|
|
|
|
+ //The whole mesh consists of degenerated faces
|
|
|
|
+ //signal upward, that this mesh should be deleted.
|
|
|
|
+ ASSIMP_LOG_DEBUG("FindDegeneratesProcess removed a mesh full of degenerated primitives");
|
|
|
|
+ return true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
if (deg && !DefaultLogger::isNullLogger()) {
|
|
if (deg && !DefaultLogger::isNullLogger()) {
|
|
ASSIMP_LOG_WARN_F( "Found ", deg, " degenerated primitives");
|
|
ASSIMP_LOG_WARN_F( "Found ", deg, " degenerated primitives");
|
|
}
|
|
}
|
|
|
|
+ return false;
|
|
}
|
|
}
|