Skip to content

Commit def1328

Browse files
committed
Some more checks and fixes in the IfcBooleanResult code. Most notably set the result to FirstOperand in case healing the result fails.
1 parent a7c0c08 commit def1328

File tree

2 files changed

+27
-12
lines changed

2 files changed

+27
-12
lines changed

src/ifcgeom/IfcGeomFunctions.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -765,6 +765,8 @@ bool IfcGeom::Kernel::flatten_shape_list(const IfcGeom::IfcRepresentationShapeIt
765765

766766
if (shapes.size() == 1) {
767767
result = moved_shape;
768+
const double precision = getValue(GV_PRECISION);
769+
apply_tolerance(result, precision);
768770
return true;
769771
}
770772

@@ -791,7 +793,13 @@ bool IfcGeom::Kernel::flatten_shape_list(const IfcGeom::IfcRepresentationShapeIt
791793
}
792794
}
793795

794-
return !result.IsNull();
796+
const bool success = !result.IsNull();
797+
if (success) {
798+
const double precision = getValue(GV_PRECISION);
799+
apply_tolerance(result, precision);
800+
}
801+
802+
return success;
795803
}
796804

797805
void IfcGeom::Kernel::remove_redundant_points_from_loop(TColgp_SequenceOfPnt& polygon, bool closed, double tol) {

src/ifcgeom/IfcGeomShapes.cpp

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -283,9 +283,11 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcBooleanResult* l, TopoDS_Shape
283283
return false;
284284
}
285285
} else {
286-
if ( ! convert_shape(operand1,s1) ) {
286+
if ( ! convert_shape(operand1, s1) ) {
287287
return false;
288288
}
289+
{ TopoDS_Solid temp_solid;
290+
s1 = ensure_fit_for_subtraction(s1, temp_solid); }
289291
}
290292

291293
const double first_operand_volume = shape_volume(s1);
@@ -297,6 +299,10 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcBooleanResult* l, TopoDS_Shape
297299
shape2_processed = convert_shapes(operand2, items2) && flatten_shape_list(items2, s2, true);
298300
} else {
299301
shape2_processed = convert_shape(operand2,s2);
302+
if (shape2_processed && !is_halfspace) {
303+
TopoDS_Solid temp_solid;
304+
s2 = ensure_fit_for_subtraction(s2, temp_solid);
305+
}
300306
}
301307

302308
if (!shape2_processed) {
@@ -305,7 +311,7 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcBooleanResult* l, TopoDS_Shape
305311
return true;
306312
}
307313

308-
if ( ! is_halfspace ) {
314+
if (!is_halfspace) {
309315
const double second_operand_volume = shape_volume(s2);
310316
if ( second_operand_volume <= ALMOST_ZERO )
311317
Logger::Message(Logger::LOG_WARNING,"Empty solid for:",operand2->entity);
@@ -321,8 +327,12 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcBooleanResult* l, TopoDS_Shape
321327
TopoDS_Shape result = brep_cut;
322328

323329
ShapeFix_Shape fix(result);
324-
fix.Perform();
325-
result = fix.Shape();
330+
try {
331+
fix.Perform();
332+
result = fix.Shape();
333+
} catch (...) {
334+
Logger::Message(Logger::LOG_WARNING, "Shape healing failed on boolean result", l->entity);
335+
}
326336

327337
bool is_valid = BRepCheck_Analyzer(result).IsValid() != 0;
328338
if ( is_valid ) {
@@ -355,10 +365,9 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcBooleanResult* l, TopoDS_Shape
355365
bool is_valid = BRepCheck_Analyzer(result).IsValid() != 0;
356366
if ( is_valid ) {
357367
shape = result;
368+
return true;
358369
}
359-
}
360-
361-
return true;
370+
}
362371

363372
} else if (op == IfcSchema::IfcBooleanOperator::IfcBooleanOperator_INTERSECTION) {
364373

@@ -373,14 +382,12 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcBooleanResult* l, TopoDS_Shape
373382
bool is_valid = BRepCheck_Analyzer(result).IsValid() != 0;
374383
if ( is_valid ) {
375384
shape = result;
385+
return true;
376386
}
377387
}
378388

379-
return true;
380-
381-
} else {
382-
return false;
383389
}
390+
return false;
384391
}
385392

386393
bool IfcGeom::Kernel::convert(const IfcSchema::IfcConnectedFaceSet* l, TopoDS_Shape& shape) {

0 commit comments

Comments
 (0)