vrshoot
view libs/assimp/FindDegenerates.cpp @ 0:b2f14e535253
initial commit
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Sat, 01 Feb 2014 19:58:19 +0200 |
parents | |
children |
line source
1 /*
2 ---------------------------------------------------------------------------
3 Open Asset Import Library (assimp)
4 ---------------------------------------------------------------------------
6 Copyright (c) 2006-2012, assimp team
8 All rights reserved.
10 Redistribution and use of this software in source and binary forms,
11 with or without modification, are permitted provided that the following
12 conditions are met:
14 * Redistributions of source code must retain the above
15 copyright notice, this list of conditions and the
16 following disclaimer.
18 * Redistributions in binary form must reproduce the above
19 copyright notice, this list of conditions and the
20 following disclaimer in the documentation and/or other
21 materials provided with the distribution.
23 * Neither the name of the assimp team, nor the names of its
24 contributors may be used to endorse or promote products
25 derived from this software without specific prior
26 written permission of the assimp team.
28 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
31 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
33 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
34 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
36 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
38 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 ---------------------------------------------------------------------------
40 */
42 /** @file FindDegenerates.cpp
43 * @brief Implementation of the FindDegenerates post-process step.
44 */
46 #include "AssimpPCH.h"
48 // internal headers
49 #include "ProcessHelper.h"
50 #include "FindDegenerates.h"
52 using namespace Assimp;
54 // ------------------------------------------------------------------------------------------------
55 // Constructor to be privately used by Importer
56 FindDegeneratesProcess::FindDegeneratesProcess()
57 : configRemoveDegenerates (false)
58 {}
60 // ------------------------------------------------------------------------------------------------
61 // Destructor, private as well
62 FindDegeneratesProcess::~FindDegeneratesProcess()
63 {
64 // nothing to do here
65 }
67 // ------------------------------------------------------------------------------------------------
68 // Returns whether the processing step is present in the given flag field.
69 bool FindDegeneratesProcess::IsActive( unsigned int pFlags) const
70 {
71 return 0 != (pFlags & aiProcess_FindDegenerates);
72 }
74 // ------------------------------------------------------------------------------------------------
75 // Setup import configuration
76 void FindDegeneratesProcess::SetupProperties(const Importer* pImp)
77 {
78 // Get the current value of AI_CONFIG_PP_FD_REMOVE
79 configRemoveDegenerates = (0 != pImp->GetPropertyInteger(AI_CONFIG_PP_FD_REMOVE,0));
80 }
82 // ------------------------------------------------------------------------------------------------
83 // Executes the post processing step on the given imported data.
84 void FindDegeneratesProcess::Execute( aiScene* pScene)
85 {
86 DefaultLogger::get()->debug("FindDegeneratesProcess begin");
87 for (unsigned int i = 0; i < pScene->mNumMeshes;++i){
88 ExecuteOnMesh( pScene->mMeshes[i]);
89 }
90 DefaultLogger::get()->debug("FindDegeneratesProcess finished");
91 }
93 // ------------------------------------------------------------------------------------------------
94 // Executes the post processing step on the given imported mesh
95 void FindDegeneratesProcess::ExecuteOnMesh( aiMesh* mesh)
96 {
97 mesh->mPrimitiveTypes = 0;
99 std::vector<bool> remove_me;
100 if (configRemoveDegenerates)
101 remove_me.resize(mesh->mNumFaces,false);
103 unsigned int deg = 0, limit;
104 for (unsigned int a = 0; a < mesh->mNumFaces; ++a)
105 {
106 aiFace& face = mesh->mFaces[a];
107 bool first = true;
109 // check whether the face contains degenerated entries
110 for (register unsigned int i = 0; i < face.mNumIndices; ++i)
111 {
112 // Polygons with more than 4 points are allowed to have double points, that is
113 // simulating polygons with holes just with concave polygons. However,
114 // double points may not come directly after another.
115 limit = face.mNumIndices;
116 if (face.mNumIndices > 4)
117 limit = std::min(limit,i+2);
119 for (register unsigned int t = i+1; t < limit; ++t)
120 {
121 if (mesh->mVertices[face.mIndices[i]] == mesh->mVertices[face.mIndices[t]])
122 {
123 // we have found a matching vertex position
124 // remove the corresponding index from the array
125 --face.mNumIndices;--limit;
126 for (unsigned int m = t; m < face.mNumIndices; ++m)
127 {
128 face.mIndices[m] = face.mIndices[m+1];
129 }
130 --t;
132 // NOTE: we set the removed vertex index to an unique value
133 // to make sure the developer gets notified when his
134 // application attemps to access this data.
135 face.mIndices[face.mNumIndices] = 0xdeadbeef;
137 if(first)
138 {
139 ++deg;
140 first = false;
141 }
143 if (configRemoveDegenerates) {
144 remove_me[a] = true;
145 goto evil_jump_outside; // hrhrhrh ... yeah, this rocks baby!
146 }
147 }
148 }
149 }
151 // We need to update the primitive flags array of the mesh.
152 switch (face.mNumIndices)
153 {
154 case 1u:
155 mesh->mPrimitiveTypes |= aiPrimitiveType_POINT;
156 break;
157 case 2u:
158 mesh->mPrimitiveTypes |= aiPrimitiveType_LINE;
159 break;
160 case 3u:
161 mesh->mPrimitiveTypes |= aiPrimitiveType_TRIANGLE;
162 break;
163 default:
164 mesh->mPrimitiveTypes |= aiPrimitiveType_POLYGON;
165 break;
166 };
167 evil_jump_outside:
168 continue;
169 }
171 // If AI_CONFIG_PP_FD_REMOVE is true, remove degenerated faces from the import
172 if (configRemoveDegenerates && deg) {
173 unsigned int n = 0;
174 for (unsigned int a = 0; a < mesh->mNumFaces; ++a)
175 {
176 aiFace& face_src = mesh->mFaces[a];
177 if (!remove_me[a]) {
178 aiFace& face_dest = mesh->mFaces[n++];
180 // Do a manual copy, keep the index array
181 face_dest.mNumIndices = face_src.mNumIndices;
182 face_dest.mIndices = face_src.mIndices;
184 if (&face_src != &face_dest) {
185 // clear source
186 face_src.mNumIndices = 0;
187 face_src.mIndices = NULL;
188 }
189 }
190 else {
191 // Otherwise delete it if we don't need this face
192 delete[] face_src.mIndices;
193 face_src.mIndices = NULL;
194 face_src.mNumIndices = 0;
195 }
196 }
197 // Just leave the rest of the array unreferenced, we don't care for now
198 mesh->mNumFaces = n;
199 if (!mesh->mNumFaces) {
200 // WTF!?
201 // OK ... for completeness and because I'm not yet tired,
202 // let's write code that willl hopefully never be called
203 // (famous last words)
205 // OK ... bad idea.
206 throw DeadlyImportError("Mesh is empty after removal of degenerated primitives ... WTF!?");
207 }
208 }
210 if (deg && !DefaultLogger::isNullLogger())
211 {
212 char s[64];
213 ASSIMP_itoa10(s,deg);
214 DefaultLogger::get()->warn(std::string("Found ") + s + " degenerated primitives");
215 }
216 }