diff --git a/src/ifcgeom/IfcGeom.h b/src/ifcgeom/IfcGeom.h index 453fba0f79..4035c1c107 100644 --- a/src/ifcgeom/IfcGeom.h +++ b/src/ifcgeom/IfcGeom.h @@ -121,6 +121,7 @@ private: MAKE_TYPE_NAME(Kernel)* kernel_; std::map vertex_mapping_; std::map, TopoDS_Edge> edges_; + double eps_; template void loop_(IfcSchema::IfcCartesianPoint::list::ptr& ps, const Fn& callback) { @@ -184,11 +185,22 @@ private: }); if (count >= 3) { wire.Closed(true); + + TopTools_ListOfShape results; + if (kernel_->wire_intersections(wire, results)) { + Logger::Error("Self-intersections with " + boost::lexical_cast(results.Extent()) + " cycles detected", loop); + kernel_->select_largest(results, wire); + } + return true; } else { return false; } } + + double epsilon() const { + return eps_; + } }; double deflection_tolerance; diff --git a/src/ifcgeom/IfcGeomFunctions.cpp b/src/ifcgeom/IfcGeomFunctions.cpp index c44ba771e4..156353f790 100644 --- a/src/ifcgeom/IfcGeomFunctions.cpp +++ b/src/ifcgeom/IfcGeomFunctions.cpp @@ -3300,7 +3300,9 @@ bool IfcGeom::Kernel::wire_intersections(const TopoDS_Wire& wire, TopTools_ListO // TopoDS_Face face = BRepBuilderAPI_MakeFace(wire, true).Face(); // ShapeAnalysis_Wire saw(wd, face, getValue(GV_PRECISION)); - const double eps = (std::min)(min_edge_length(wire) / 2., getValue(GV_PRECISION) * 10.); + const double eps = faceset_helper_ + ? faceset_helper_->epsilon() + : (std::min)(min_edge_length(wire) / 2., getValue(GV_PRECISION) * 10.); for (int i = 2; i < n; ++i) { @@ -3788,14 +3790,14 @@ IfcGeom::Kernel::faceset_helper::faceset_helper(Kernel* kernel, const IfcSchema: } } - const double eps = kernel->getValue(GV_PRECISION) * 10. * bdiff; + eps_ = kernel->getValue(GV_PRECISION) * 10. * (std::min)(1.0, bdiff); std::map, int> edge_use; for (int i = 0; i < pnts.size(); ++i) { if (pnts[i]) { std::set vs; - find_neighbours(tree, pnts, vs, i, eps); + find_neighbours(tree, pnts, vs, i, eps_); for (int v : vs) { auto pt = *(points->begin() + v);