Skip to content

Commit bdc42bb

Browse files
committed
improve geometry processing
1 parent 212c5ae commit bdc42bb

File tree

18 files changed

+1757
-2409
lines changed

18 files changed

+1757
-2409
lines changed

IfcPlusPlus/src/external/Carve/src/include/carve/mesh_impl.hpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -356,6 +356,11 @@ bool Face<ndim>::recalc(double CARVE_EPSILON) {
356356
edgePtr = edgePtr->next;
357357
}
358358

359+
if (longestEdge == nullptr)
360+
{
361+
return false;
362+
}
363+
359364
edge_t* edge1 = longestEdge->next;
360365
const vector_t& pA = longestEdge->v1()->v; // vert
361366
const vector_t& B = longestEdge->v2()->v; // next->vert

IfcPlusPlus/src/ifcpp/geometry/CSG_Adapter.h

Lines changed: 97 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OU
3737
#ifdef _DEBUG
3838
static int csg_compute_count = 0;
3939
#endif
40-
#define _USE_CLASSIFY_NORMAL
4140

4241
namespace CSG_Adapter
4342
{
@@ -80,24 +79,22 @@ namespace CSG_Adapter
8079
return false;
8180
}
8281

83-
if( op1Orig->vertex_storage.size() > 2000 )
82+
if( op1Orig->vertex_storage.size() > 4000 )
8483
{
8584
assignResultOnFail(op1Orig, op2Orig, operation, result);
8685
return false;
8786
}
8887

89-
if( op2Orig->vertex_storage.size() > 2000 )
88+
if( op2Orig->vertex_storage.size() > 4000 )
9089
{
9190
assignResultOnFail(op1Orig, op2Orig, operation, result);
9291
return false;
9392
}
9493

95-
9694
carve::geom::aabb<3> bbox1 = op1Orig->getAABB();
9795
carve::geom::aabb<3> bbox2 = op2Orig->getAABB();
9896
bool result_meshset_ok = false;
99-
bool normalizeCoordsInsteadOfEpsilon = normalizeCoords;
100-
CarveMeshNormalizer normMesh(bbox1, bbox2, normalizeCoordsInsteadOfEpsilon);
97+
CarveMeshNormalizer normMesh(bbox1, bbox2, normalizeCoords);
10198
normMesh.m_disableNormalizeAll = false;
10299

103100
GeomProcessingParams paramsUnscaled(geomSettingsDefault, false);
@@ -109,10 +106,9 @@ namespace CSG_Adapter
109106
}
110107
double epsDefault = geomSettings->getEpsilonCoplanarDistance();
111108
double epsMinFaceAreaDefault = geomSettings->getMinTriangleArea();
112-
double CARVE_EPSILON = 10.0 * epsDefault * scale;
109+
double CARVE_EPSILON = epsDefault;// 10.0 * epsDefault * scale;
113110
double epsMinFaceArea = epsMinFaceAreaDefault * ( scale * scale );
114111
double epsCoplanarAngle = geomSettings->getEpsilonCoplanarAngle() * scale;
115-
double CARVE_EPSILON_restore = epsDefault;
116112
geomSettings->setEpsilonCoplanarDistance(CARVE_EPSILON);
117113
geomSettings->setEpsilonCoplanarAngle(epsCoplanarAngle);
118114
geomSettings->setMinTriangleArea(epsMinFaceArea);
@@ -121,18 +117,10 @@ namespace CSG_Adapter
121117
paramsScaled.callbackFunc = report_callback;
122118
paramsUnscaled.ifc_entity = entity.get();
123119
paramsUnscaled.callbackFunc = report_callback;
124-
120+
125121
bool intersecting = checkBoundinbBoxIntersection(bbox1, bbox2, operation, CARVE_EPSILON);
126122
if (!intersecting)
127123
{
128-
#ifdef _DEBUG
129-
shared_ptr<carve::mesh::MeshSet<3> > op1(op1Orig->clone());
130-
shared_ptr<carve::mesh::MeshSet<3> > op2(op2Orig->clone());
131-
int tag = 0;
132-
bool op1_dumped = false, op2_dumped = false;
133-
DumpSettingsStruct dumpColorSettings;
134-
dumpOperands(op1, op2, result, tag, op1_dumped, op2_dumped, dumpColorSettings, paramsUnscaled);
135-
#endif
136124
assignResultOnFail(op1Orig, op2Orig, operation, result);
137125
return true;
138126
}
@@ -159,7 +147,6 @@ namespace CSG_Adapter
159147

160148
shared_ptr<carve::mesh::MeshSet<3> > op1(op1Orig->clone());
161149
shared_ptr<carve::mesh::MeshSet<3> > op2(op2Orig->clone());
162-
163150

164151
std::stringstream strs_err;
165152
try
@@ -177,25 +164,38 @@ namespace CSG_Adapter
177164
++csg_compute_count;
178165
DumpSettingsStruct dumpColorSettings;
179166
dumpColorSettings.eps = CARVE_EPSILON;
167+
CarveMeshNormalizer normMesh_scaleMeshDump(normMesh);
180168
if (!normalizeCoords)
181169
{
182-
dumpColorSettings.normalizer = &normMesh;
170+
normMesh_scaleMeshDump.m_normalizeCoordsInsteadOfEpsilon = true;
171+
paramsScaled.normalizer = &normMesh_scaleMeshDump;
172+
paramsUnscaled.normalizer = &normMesh_scaleMeshDump;
183173
}
184174

185-
if (csg_compute_count == 24 || tag == 20896)
175+
if (csg_compute_count == 24 || tag == 99427)
176+
{
177+
dumpOperands(op1, op2, result, tag, op1_dumped, op2_dumped, dumpColorSettings, paramsScaled);
178+
}
179+
180+
if (infoMesh1orig.zeroAreaFaces.size() > 0)
181+
{
182+
dumpOperands(op1, op2, result, tag, op1_dumped, op2_dumped, dumpColorSettings, paramsScaled);
183+
}
184+
185+
if (infoMesh1orig.finEdges.size() > 0)
186+
{
187+
dumpOperands(op1, op2, result, tag, op1_dumped, op2_dumped, dumpColorSettings, paramsScaled);
188+
}
189+
if (infoMesh2orig.finEdges.size() > 0)
186190
{
187191
dumpOperands(op1, op2, result, tag, op1_dumped, op2_dumped, dumpColorSettings, paramsScaled);
188-
//dumpMeshes = true;
189192
}
190193
#endif
191194

192195
bool triangulateOperands = true;
193196
bool shouldBeClosedManifold = true;
194-
MeshOps::simplifyMeshSet(op1, geomSettings, paramsScaled, triangulateOperands, shouldBeClosedManifold);
195-
MeshOps::simplifyMeshSet(op2, geomSettings, paramsScaled, triangulateOperands, shouldBeClosedManifold);
196-
197-
MeshOps::retriangulateMeshSetSimple(op1, false, paramsScaled, 0);
198-
MeshOps::retriangulateMeshSetSimple(op2, false, paramsScaled, 0);
197+
MeshOps::simplifyMeshSet(op1, paramsScaled, triangulateOperands, shouldBeClosedManifold);
198+
MeshOps::simplifyMeshSet(op2, paramsScaled, triangulateOperands, shouldBeClosedManifold);
199199

200200
MeshSetInfo infoMesh1(report_callback, entity.get());
201201
MeshSetInfo infoMesh2(report_callback, entity.get());
@@ -213,18 +213,63 @@ namespace CSG_Adapter
213213
paramsUnscaled.allowFinEdges = true;
214214
}
215215

216+
if (infoMesh1orig.zeroAreaFaces.size() > 0)
217+
{
218+
paramsScaled.allowZeroAreaFaces = true; // temp
219+
paramsUnscaled.allowZeroAreaFaces = true; // temp
220+
}
221+
216222
if (!operand1valid && operand1origvalid)
217223
{
224+
#ifdef _DEBUG
225+
dumpOperands(op1, op2, result, tag, op1_dumped, op2_dumped, dumpColorSettings, paramsScaled);
226+
double vol1 = MeshOps::computeMeshsetVolume(op1.get());
227+
{
228+
shared_ptr<carve::mesh::MeshSet<3> > op1Clone(op1Orig->clone());
229+
MeshSetInfo infoMesh1copy(report_callback, entity.get());
230+
MeshOps::checkMeshSetValidAndClosed(op1Clone, infoMesh1copy, paramsScaled);
231+
normMesh.normalizeMesh(op1Clone, "op1Clone", CARVE_EPSILON);
232+
233+
MeshOps::simplifyMeshSet(op1Clone, paramsScaled, triangulateOperands, shouldBeClosedManifold);
234+
235+
MeshSetInfo infoMesh1AfterSimplify(report_callback, entity.get());
236+
bool operand1CloneValid = MeshOps::checkMeshSetValidAndClosed(op1Clone, infoMesh1AfterSimplify, paramsScaled);
237+
if (operand1CloneValid)
238+
{
239+
int wait = 0;
240+
}
241+
}
242+
243+
#endif
244+
218245
op1 = shared_ptr<carve::mesh::MeshSet<3> >(op1Orig->clone());
219246
MeshSetInfo infoMesh1copy(report_callback, entity.get());
220-
bool operand1copy_valid = MeshOps::checkMeshSetValidAndClosed(op1, infoMesh1copy, paramsUnscaled);
247+
MeshOps::checkMeshSetValidAndClosed(op1, infoMesh1copy, paramsUnscaled);
221248

222249
normMesh.normalizeMesh(op1, "op1orig", CARVE_EPSILON);
223250
operand1valid = MeshOps::checkMeshSetValidAndClosed(op1, infoMesh1, paramsScaled);
224251
if (!operand1valid && operand1origvalid)
225252
{
226253
// normalizing changed the validity, should not happen
227254
#ifdef _DEBUG
255+
dumpOperands(op1, op2, result, tag, op1_dumped, op2_dumped, dumpColorSettings, paramsScaled);
256+
double vol1 = MeshOps::computeMeshsetVolume(op1.get());
257+
#endif
258+
}
259+
}
260+
261+
if (!operand2valid && operand2origvalid)
262+
{
263+
op1 = shared_ptr<carve::mesh::MeshSet<3> >(op2Orig->clone());
264+
MeshSetInfo infoMesh2copy(report_callback, entity.get());
265+
bool operand2copy_valid = MeshOps::checkMeshSetValidAndClosed(op2, infoMesh2copy, paramsUnscaled);
266+
267+
normMesh.normalizeMesh(op2, "op2orig", CARVE_EPSILON);
268+
operand2valid = MeshOps::checkMeshSetValidAndClosed(op2, infoMesh2, paramsScaled);
269+
if (!operand2valid && operand2origvalid)
270+
{
271+
// normalizing changed the validity, should not happen
272+
#ifdef _DEBUG
228273

229274
dumpOperands(op1, op2, result, tag, op1_dumped, op2_dumped, dumpColorSettings, paramsScaled);
230275
double vol2 = MeshOps::computeMeshsetVolume(op2.get());
@@ -234,6 +279,11 @@ namespace CSG_Adapter
234279

235280
if( !operand1valid || !operand2valid )
236281
{
282+
#ifdef _DEBUG
283+
284+
dumpOperands(op1, op2, result, tag, op1_dumped, op2_dumped, dumpColorSettings, paramsScaled);
285+
double vol2 = MeshOps::computeMeshsetVolume(op2.get());
286+
#endif
237287
assignResultOnFail(op1Orig, op2Orig, operation, result);
238288
return false;
239289
}
@@ -269,22 +319,29 @@ namespace CSG_Adapter
269319

270320
dumpOperands(op1, op2, result, tag, op1_dumped, op2_dumped, dumpColorSettings, paramsScaled);
271321
double vol2 = MeshOps::computeMeshsetVolume(op2.get());
322+
double volume_result = MeshOps::computeMeshsetVolume(result.get());
323+
324+
if (triangulateOperands)
325+
{
326+
if (infoMesh1.maxNumberOfEdgesPerFace != 3 || infoMesh2.maxNumberOfEdgesPerFace != 3)
327+
{
328+
std::cout << "not triangulated" << std::endl;
329+
}
330+
}
272331
#endif
273-
MeshOps::fixMeshset(result, geomSettings, paramsScaled.debugDump);
332+
MeshOps::simplifyMeshSet(result, paramsScaled, triangulateOperands, shouldBeClosedManifold);
274333
result_meshset_ok = MeshOps::checkMeshSetValidAndClosed(result, infoResult, paramsScaled);
275334
}
276335

277336
#ifdef _DEBUG
278-
if (csg_compute_count > 15)
337+
if (!result_meshset_ok)
279338
{
280339
double vol2 = MeshOps::computeMeshsetVolume(op2.get());
281340
dumpOperands(op1, op2, result, tag, op1_dumped, op2_dumped, dumpColorSettings, paramsScaled);
282341
}
283342
#endif
284343

285344
// TODO: check for fail with closed mesh, but not fully sliced through.
286-
287-
#ifdef _USE_CLASSIFY_NORMAL
288345
if (!result_meshset_ok)
289346
{
290347
carve::csg::CSG csg(CARVE_EPSILON);
@@ -296,11 +353,11 @@ namespace CSG_Adapter
296353
#ifdef _DEBUG
297354
dumpOperands(op1, op2, result, tag, op1_dumped, op2_dumped, dumpColorSettings, paramsScaled);
298355
#endif
299-
MeshOps::fixMeshset(result, geomSettings, paramsScaled.debugDump);
356+
357+
MeshOps::simplifyMeshSet(result, paramsScaled, triangulateOperands, shouldBeClosedManifold);
300358
result_meshset_ok = MeshOps::checkMeshSetValidAndClosed(result, infoResult, paramsScaled);
301359
}
302360
}
303-
#endif
304361

305362
#ifdef _DEBUG
306363
double vol = MeshOps::computeMeshsetVolume(result.get());
@@ -366,7 +423,6 @@ namespace CSG_Adapter
366423

367424
normMesh.deNormalizeMesh(result, "", CARVE_EPSILON);
368425

369-
370426
#ifdef _DEBUG
371427
{
372428
// de-normalized:
@@ -411,6 +467,7 @@ namespace CSG_Adapter
411467
MeshSetInfo infoMesh1(report_callback, entity.get());
412468
bool allowFinEdges = false;
413469
GeomProcessingParams params(geomSettings, false);
470+
params.allowZeroAreaFaces = true; // will be removed later
414471
bool operand1valid = MeshOps::checkMeshSetValidAndClosed(op1, infoMesh1, params);
415472

416473
if (!operand1valid)
@@ -432,14 +489,16 @@ namespace CSG_Adapter
432489

433490
#ifdef _DEBUG
434491

435-
MeshSetInfo infoMesh1(report_callback, entity.get());
492+
MeshSetInfo infoMesh1_2(report_callback, entity.get());
436493
bool allowFinEdges = false;
437494
GeomProcessingParams params(geomSettings, false);
438-
bool operand1valid_2 = MeshOps::checkMeshSetValidAndClosed(op1, infoMesh1, params);
495+
bool operand1valid_2 = MeshOps::checkMeshSetValidAndClosed(op1, infoMesh1_2, params);
439496

440497
if (!operand1valid_2)
441498
{
442-
std::cout << "!operand1valid" << std::endl;
499+
std::cout << "!operand1valid after computeCSG_Carve" << std::endl;
500+
DumpSettingsStruct dumpSet;
501+
dumpWithLabel("computeCSG_Carve:result:op1 ", op1, dumpSet, params, true, true);
443502
}
444503
#endif
445504
continue;
@@ -463,7 +522,7 @@ namespace CSG_Adapter
463522

464523
if (!operand1valid_3)
465524
{
466-
std::cout << "!operand1valid" << std::endl;
525+
std::cout << "!operand1valid_3 computeCSG_Carve" << std::endl;
467526
}
468527
}
469528
#endif

IfcPlusPlus/src/ifcpp/geometry/ConverterOSG.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -730,8 +730,8 @@ class ConverterOSG : public StatusCallback
730730
double epsCoplanarFacesAngle = eps;
731731
double minFaceArea = eps;
732732
bool dumpMeshes = false;
733-
GeomProcessingParams params(eps, epsCoplanarFacesAngle, minFaceArea, dumpMeshes);
734-
MeshOps::retriangulateMeshSetSimple(item_meshset, true, params, 0);
733+
GeomProcessingParams params( m_geom_settings, dumpMeshes);
734+
MeshOps::retriangulateMeshSetForExport(item_meshset, params);
735735
drawMeshSet(item_meshset, geode, crease_angle, min_triangle_area, false, disableBackfaceCulling);
736736

737737
if (m_render_crease_edges)

0 commit comments

Comments
 (0)