@@ -165,7 +165,9 @@ inline Mesh cutAndGetBack(Mesh mesh, VectorF planeNormal, float planeD)
165
165
return std::move (mesh);
166
166
}
167
167
168
- inline Mesh simplify (Mesh mesh)
168
+ constexpr const float simplifyDefaultEps = 1e-6 ;
169
+
170
+ inline vector<Triangle> simplify (vector<Triangle> meshTriangles, float faceNormalEps = simplifyDefaultEps, float distanceEps = simplifyDefaultEps, float vertexNormalEps = simplifyDefaultEps, float vertexTextureEps = simplifyDefaultEps, float vertexColorEps = simplifyDefaultEps)
169
171
{
170
172
vector<Vertex> vertexList;
171
173
unordered_map<Vertex, size_t > vertexMap;
@@ -175,8 +177,7 @@ inline Mesh simplify(Mesh mesh)
175
177
vector<vector<STList::iterator>> trianglesMap;
176
178
STList triangles;
177
179
deque<STList::iterator> changedQueue;
178
- triangles.reserve (mesh.triangles .size ());
179
- for (Triangle tri : mesh.triangles )
180
+ for (Triangle tri : meshTriangles)
180
181
{
181
182
STList::iterator triangleIter = triangles.insert (triangles.end (), SimpTriangle ());
182
183
changedQueue.push_back (triangleIter);
@@ -205,27 +206,141 @@ inline Mesh simplify(Mesh mesh)
205
206
}
206
207
std::get<1 >(triangle) = tri.normal ();
207
208
}
208
- #if 0
209
209
while (!changedQueue.empty ())
210
210
{
211
211
STList::iterator triangleIter = changedQueue.front ();
212
212
changedQueue.pop_front ();
213
+ if (std::get<1 >(*triangleIter) == VectorF (0 ))
214
+ continue ;
215
+ bool done = false ;
213
216
for (size_t i = 0 ; i < verticesPerTriangle; i++)
214
217
{
215
218
for (STList::iterator secondTriangle : trianglesMap[std::get<0 >(*triangleIter)[i]])
216
219
{
220
+ if (secondTriangle == triangleIter)
221
+ continue ;
222
+ if (std::get<1 >(*secondTriangle) == VectorF (0 ))
223
+ continue ;
224
+ if (absSquared (std::get<1 >(*triangleIter) - std::get<1 >(*secondTriangle)) > faceNormalEps * faceNormalEps)
225
+ continue ;
217
226
array<int , verticesPerTriangle> matchIndices;
227
+ array<bool , verticesPerTriangle> used;
228
+ for (bool &v : used)
229
+ v = false ;
230
+ size_t matchCount = 0 ;
231
+ for (size_t j = 0 ; j < verticesPerTriangle; j++)
232
+ {
233
+ matchIndices[j] = -1 ;
234
+ for (size_t k = 0 ; k < verticesPerTriangle; k++)
235
+ {
236
+ if (std::get<0 >(*triangleIter)[j] == std::get<0 >(*secondTriangle)[k])
237
+ {
238
+ matchIndices[j] = k;
239
+ used[k] = true ;
240
+ matchCount++;
241
+ break ;
242
+ }
243
+ }
244
+ }
245
+ if (matchCount >= 3 )
246
+ {
247
+ std::get<1 >(*triangleIter) = VectorF (0 ); // delete duplicates
248
+ continue ;
249
+ }
250
+ if (matchCount < 2 )
251
+ continue ;
252
+ size_t firstTriangleNonTouchingIndex = 0 , secondTriangleNonTouchingIndex = 0 ;
253
+ for (size_t j = 0 ; j < verticesPerTriangle; j++)
254
+ {
255
+ if (matchIndices[j] == -1 )
256
+ {
257
+ firstTriangleNonTouchingIndex = j;
258
+ break ;
259
+ }
260
+ }
261
+ for (size_t j = 0 ; j < verticesPerTriangle; j++)
262
+ {
263
+ if (!used[j])
264
+ {
265
+ secondTriangleNonTouchingIndex = j;
266
+ break ;
267
+ }
268
+ }
269
+ array<size_t , verticesPerTriangle> tri1, tri2;
270
+ for (size_t j = 0 , k = firstTriangleNonTouchingIndex; j < verticesPerTriangle; j++, k = (k >= verticesPerTriangle - 1 ? k + 1 - verticesPerTriangle : k + 1 ))
271
+ {
272
+ tri1[j] = std::get<0 >(*triangleIter)[k];
273
+ }
274
+ for (size_t j = 0 , k = secondTriangleNonTouchingIndex; j < verticesPerTriangle; j++, k = (k >= verticesPerTriangle - 1 ? k + 1 - verticesPerTriangle : k + 1 ))
275
+ {
276
+ tri2[j] = std::get<0 >(*secondTriangle)[k];
277
+ }
278
+ Vertex lineStartVertex = vertexList[tri1[0 ]], lineEndVertex = vertexList[tri2[0 ]];
279
+ VectorF deltaPosition = lineEndVertex.p - lineStartVertex.p ;
280
+ float planeD = -dot (deltaPosition, lineStartVertex.p );
281
+ if (absSquared (deltaPosition) < distanceEps * distanceEps)
282
+ continue ;
283
+ size_t removeVertex = 0 ;
284
+ for (size_t j = 1 ; j < verticesPerTriangle; j++)
285
+ {
286
+ Vertex middleVertex = vertexList[tri1[j]];
287
+ float t = (dot (middleVertex.p , deltaPosition) + planeD) / absSquared (deltaPosition);
288
+ Vertex calculatedMiddleVertex = interpolate (t, lineStartVertex, lineEndVertex);
289
+ if (absSquared (calculatedMiddleVertex.p - middleVertex.p ) > distanceEps * distanceEps)
290
+ continue ;
291
+ if (absSquared (calculatedMiddleVertex.n - middleVertex.n ) > vertexNormalEps * vertexNormalEps)
292
+ continue ;
293
+ if (abs (calculatedMiddleVertex.c .r - middleVertex.c .r ) > vertexColorEps)
294
+ continue ;
295
+ if (abs (calculatedMiddleVertex.c .g - middleVertex.c .g ) > vertexColorEps)
296
+ continue ;
297
+ if (abs (calculatedMiddleVertex.c .b - middleVertex.c .b ) > vertexColorEps)
298
+ continue ;
299
+ if (abs (calculatedMiddleVertex.c .a - middleVertex.c .a ) > vertexColorEps)
300
+ continue ;
301
+ if (abs (calculatedMiddleVertex.t .u - middleVertex.t .u ) > vertexTextureEps)
302
+ continue ;
303
+ if (abs (calculatedMiddleVertex.t .v - middleVertex.t .v ) > vertexTextureEps)
304
+ continue ;
305
+ removeVertex = j;
306
+ break ;
307
+ }
308
+ if (removeVertex == 0 )
309
+ continue ;
310
+ std::get<1 >(*secondTriangle) = VectorF (0 ); // remove second triangle
311
+ if (removeVertex == 1 )
312
+ {
313
+ std::get<0 >(*triangleIter)[0 ] = tri1[0 ];
314
+ std::get<0 >(*triangleIter)[1 ] = tri2[0 ];
315
+ std::get<0 >(*triangleIter)[2 ] = tri1[2 ];
316
+ }
317
+ else
318
+ {
319
+ std::get<0 >(*triangleIter)[0 ] = tri1[0 ];
320
+ std::get<0 >(*triangleIter)[1 ] = tri1[1 ];
321
+ std::get<0 >(*triangleIter)[2 ] = tri2[0 ];
322
+ }
323
+ changedQueue.push_back (triangleIter);
324
+ done = true ;
325
+ break ;
218
326
}
327
+ if (done)
328
+ break ;
219
329
}
220
330
}
221
- #else
222
- #warning finish
223
- #endif
224
- mesh.triangles .clear ();
331
+ meshTriangles.clear ();
225
332
for (const SimpTriangle &triangle : triangles)
226
333
{
227
- mesh.triangles .push_back (Triangle (vertexList[std::get<0 >(triangle)[0 ]], vertexList[std::get<0 >(triangle)[1 ]], vertexList[std::get<0 >(triangle)[2 ]]));
334
+ if (std::get<1 >(triangle) == VectorF (0 ))
335
+ continue ;
336
+ meshTriangles.push_back (Triangle (vertexList[std::get<0 >(triangle)[0 ]], vertexList[std::get<0 >(triangle)[1 ]], vertexList[std::get<0 >(triangle)[2 ]]));
228
337
}
338
+ return std::move (meshTriangles);
339
+ }
340
+
341
+ inline Mesh simplify (Mesh mesh, float faceNormalEps = simplifyDefaultEps, float distanceEps = simplifyDefaultEps, float vertexNormalEps = simplifyDefaultEps, float vertexTextureEps = simplifyDefaultEps, float vertexColorEps = simplifyDefaultEps)
342
+ {
343
+ mesh.triangles = simplify (std::move (mesh.triangles ), faceNormalEps, distanceEps, vertexNormalEps, vertexTextureEps, vertexColorEps);
229
344
return std::move (mesh);
230
345
}
231
346
0 commit comments