Skip to content

Commit 99a66c8

Browse files
implemented simplify
1 parent c8ed113 commit 99a66c8

File tree

2 files changed

+135
-14
lines changed

2 files changed

+135
-14
lines changed

generate.h

+124-9
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,9 @@ inline Mesh cutAndGetBack(Mesh mesh, VectorF planeNormal, float planeD)
165165
return std::move(mesh);
166166
}
167167

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)
169171
{
170172
vector<Vertex> vertexList;
171173
unordered_map<Vertex, size_t> vertexMap;
@@ -175,8 +177,7 @@ inline Mesh simplify(Mesh mesh)
175177
vector<vector<STList::iterator>> trianglesMap;
176178
STList triangles;
177179
deque<STList::iterator> changedQueue;
178-
triangles.reserve(mesh.triangles.size());
179-
for(Triangle tri : mesh.triangles)
180+
for(Triangle tri : meshTriangles)
180181
{
181182
STList::iterator triangleIter = triangles.insert(triangles.end(), SimpTriangle());
182183
changedQueue.push_back(triangleIter);
@@ -205,27 +206,141 @@ inline Mesh simplify(Mesh mesh)
205206
}
206207
std::get<1>(triangle) = tri.normal();
207208
}
208-
#if 0
209209
while(!changedQueue.empty())
210210
{
211211
STList::iterator triangleIter = changedQueue.front();
212212
changedQueue.pop_front();
213+
if(std::get<1>(*triangleIter) == VectorF(0))
214+
continue;
215+
bool done = false;
213216
for(size_t i = 0; i < verticesPerTriangle; i++)
214217
{
215218
for(STList::iterator secondTriangle : trianglesMap[std::get<0>(*triangleIter)[i]])
216219
{
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;
217226
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;
218326
}
327+
if(done)
328+
break;
219329
}
220330
}
221-
#else
222-
#warning finish
223-
#endif
224-
mesh.triangles.clear();
331+
meshTriangles.clear();
225332
for(const SimpTriangle &triangle : triangles)
226333
{
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]]));
228337
}
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);
229344
return std::move(mesh);
230345
}
231346

main.cpp

+11-5
Original file line numberDiff line numberDiff line change
@@ -180,15 +180,21 @@ int main(int argc, char **argv)
180180
static Mesh m3;
181181
if(!model)
182182
{
183-
m3 = makeSphereMesh(10, 5, 6, nullptr, RGBF(1, 0, 1));
183+
m3 = makeSphereMesh(20, 10, 12 * 0.9, nullptr, RGBF(1, 0, 1));
184184
TextureDescriptor td(testTexture);
185-
BSPTree csgObject = BSPTree(((Mesh)transform(Matrix::translate(VectorF(-0.5)).concat(Matrix::scale(2 * 5)), Generate::unitBox(td, td, td, td, td, td))).triangles);
185+
BSPTree csgObject = BSPTree(((Mesh)transform(Matrix::translate(VectorF(-0.5)).concat(Matrix::scale(2 * 10 * 0.9)), Generate::unitBox(td, td, td, td, td, td))).triangles);
186186
BSPTree t = BSPTree(m3.triangles);
187-
BSPTree cylinder = BSPTree(makeCylinderMesh(5, 2, 10, RGBF(1, 1, 0)).triangles);
188-
t = csgDifference(csgIntersection(std::move(t), std::move(csgObject)), cylinder);
187+
BSPTree cylinder = BSPTree(makeCylinderMesh(10, 4 * 0.9, 20, RGBF(1, 1, 0)).triangles);
188+
t = csgIntersection(std::move(t), std::move(csgObject));
189+
t = BSPTree(simplify(t.getTriangles()));
190+
t = csgDifference(std::move(t), cylinder);
191+
t = BSPTree(simplify(t.getTriangles()));
189192
t = csgDifference(std::move(t), transform(Matrix::rotateZ(M_PI / 2), cylinder));
193+
t = BSPTree(simplify(t.getTriangles()));
190194
t = csgDifference(std::move(t), transform(Matrix::rotateX(M_PI / 2), std::move(cylinder)));
191-
m3 = colorize(RGBAF(1, 1, 1, 0.95), Mesh(t.getTriangles(std::move(m3.triangles)), m3.image));
195+
m3 = Mesh(t.getTriangles(std::move(m3.triangles)), m3.image);
196+
cout << "model has " << m3.triangleCount() << " triangles." << endl;
197+
m3 = simplify(std::move(m3));
192198
cout << "model has " << m3.triangleCount() << " triangles." << endl;
193199
}
194200

0 commit comments

Comments
 (0)