Skip to content

Commit 3840bd1

Browse files
committed
Limit tolerance on wire self-intersection to edge segment length
1 parent 622853d commit 3840bd1

File tree

1 file changed

+122
-122
lines changed

1 file changed

+122
-122
lines changed

src/ifcgeom/IfcGeomFunctions.cpp

Lines changed: 122 additions & 122 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,126 @@
156156
#endif
157157
#endif
158158

159+
namespace {
160+
TopTools_ListOfShape copy_operand(const TopTools_ListOfShape& l) {
161+
#if OCC_VERSION_HEX < 0x70000
162+
TopTools_ListOfShape r;
163+
TopTools_ListIteratorOfListOfShape it(l);
164+
for (; it.More(); it.Next()) {
165+
r.Append(BRepBuilderAPI_Copy(it.Value()));
166+
}
167+
return r;
168+
#else
169+
// On OCCT 7.0 and higher BRepAlgoAPI_BuilderAlgo::SetNonDestructive(true) is
170+
// called. Not entirely sure on the behaviour before 7.0, so overcautiously
171+
// create copies.
172+
return l;
173+
#endif
174+
}
175+
176+
TopoDS_Shape copy_operand(const TopoDS_Shape& s) {
177+
#if OCC_VERSION_HEX < 0x70000
178+
return BRepBuilderAPI_Copy(s);
179+
#else
180+
return s;
181+
#endif
182+
}
183+
184+
double min_edge_length(const TopoDS_Shape& a) {
185+
double min_edge_len = std::numeric_limits<double>::infinity();
186+
TopExp_Explorer exp(a, TopAbs_EDGE);
187+
for (; exp.More(); exp.Next()) {
188+
GProp_GProps prop;
189+
BRepGProp::LinearProperties(exp.Current(), prop);
190+
double l = prop.Mass();
191+
if (l < min_edge_len) {
192+
min_edge_len = l;
193+
}
194+
}
195+
return min_edge_len;
196+
}
197+
198+
double min_vertex_edge_distance(const TopoDS_Shape& a, double t) {
199+
TopExp_Explorer exp(a, TopAbs_VERTEX);
200+
201+
double M = std::numeric_limits<double>::infinity();
202+
203+
for (; exp.More(); exp.Next()) {
204+
if (exp.Current().Orientation() != TopAbs_FORWARD) {
205+
continue;
206+
}
207+
208+
const TopoDS_Vertex& v = TopoDS::Vertex(exp.Current());
209+
gp_Pnt p = BRep_Tool::Pnt(v);
210+
211+
TopExp_Explorer exp2(a, TopAbs_EDGE);
212+
for (; exp2.More(); exp2.Next()) {
213+
const TopoDS_Edge& e = TopoDS::Edge(exp2.Current());
214+
TopoDS_Vertex v1, v2;
215+
TopExp::Vertices(e, v1, v2);
216+
217+
if (v.IsSame(v1) || v.IsSame(v2)) {
218+
continue;
219+
}
220+
221+
BRepAdaptor_Curve crv(e);
222+
Extrema_ExtPC ext(p, crv);
223+
if (!ext.IsDone()) {
224+
continue;
225+
}
226+
227+
for (int i = 1; i <= ext.NbExt(); ++i) {
228+
const double m = sqrt(ext.SquareDistance(i));
229+
if (m < M && m > t) {
230+
M = m;
231+
}
232+
}
233+
}
234+
}
235+
236+
return M;
237+
}
238+
239+
bool is_manifold(const TopoDS_Shape& a) {
240+
TopTools_IndexedDataMapOfShapeListOfShape map;
241+
TopExp::MapShapesAndAncestors(a, TopAbs_EDGE, TopAbs_FACE, map);
242+
243+
for (int i = 1; i <= map.Extent(); ++i) {
244+
if (map.FindFromIndex(i).Extent() != 2) {
245+
return false;
246+
}
247+
}
248+
249+
return true;
250+
}
251+
252+
bool is_manifold(const TopTools_ListOfShape& l) {
253+
TopTools_ListOfShape r;
254+
TopTools_ListIteratorOfListOfShape it(l);
255+
for (; it.More(); it.Next()) {
256+
if (!is_manifold(it.Value())) {
257+
return false;
258+
}
259+
}
260+
return true;
261+
}
262+
263+
void bounding_box_overlap(double p, const TopoDS_Shape& a, const TopTools_ListOfShape& b, TopTools_ListOfShape& c) {
264+
Bnd_Box A;
265+
BRepBndLib::Add(a, A);
266+
267+
TopTools_ListIteratorOfListOfShape it(b);
268+
for (; it.More(); it.Next()) {
269+
Bnd_Box B;
270+
BRepBndLib::Add(it.Value(), B);
271+
272+
if (A.Distance(B) < p) {
273+
c.Append(it.Value());
274+
}
275+
}
276+
}
277+
}
278+
159279
bool IfcGeom::Kernel::create_solid_from_compound(const TopoDS_Shape& compound, TopoDS_Shape& shape) {
160280
TopTools_ListOfShape face_list;
161281
TopExp_Explorer exp(compound, TopAbs_FACE);
@@ -2937,7 +3057,7 @@ bool IfcGeom::Kernel::wire_intersections(const TopoDS_Wire& wire, TopTools_ListO
29373057
// TopoDS_Face face = BRepBuilderAPI_MakeFace(wire, true).Face();
29383058
// ShapeAnalysis_Wire saw(wd, face, getValue(GV_PRECISION));
29393059

2940-
const double eps = getValue(GV_PRECISION) * 10.;
3060+
const double eps = (std::min)(min_edge_length(wire) / 2., getValue(GV_PRECISION) * 10.);
29413061

29423062
for (int i = 2; i < n; ++i) {
29433063

@@ -2974,6 +3094,7 @@ bool IfcGeom::Kernel::wire_intersections(const TopoDS_Wire& wire, TopTools_ListO
29743094
BRep_Tool::Curve(wd->Edge(j + 1), u21, u22)
29753095
);
29763096

3097+
// @todo: extend this to work in case of multiple extrema and curved segments.
29773098
if ((unbounded_intersects = (ecc.NbExtrema() == 1 && ecc.Distance(1) < eps))) {
29783099
ecc.Parameters(1, U1, U2);
29793100
}
@@ -3257,127 +3378,6 @@ bool IfcGeom::Kernel::boolean_operation(const TopoDS_Shape& a, const TopoDS_Shap
32573378
return succesful;
32583379
}
32593380
#else
3260-
3261-
namespace {
3262-
TopTools_ListOfShape copy_operand(const TopTools_ListOfShape& l) {
3263-
#if OCC_VERSION_HEX < 0x70000
3264-
TopTools_ListOfShape r;
3265-
TopTools_ListIteratorOfListOfShape it(l);
3266-
for (; it.More(); it.Next()) {
3267-
r.Append(BRepBuilderAPI_Copy(it.Value()));
3268-
}
3269-
return r;
3270-
#else
3271-
// On OCCT 7.0 and higher BRepAlgoAPI_BuilderAlgo::SetNonDestructive(true) is
3272-
// called. Not entirely sure on the behaviour before 7.0, so overcautiously
3273-
// create copies.
3274-
return l;
3275-
#endif
3276-
}
3277-
3278-
TopoDS_Shape copy_operand(const TopoDS_Shape& s) {
3279-
#if OCC_VERSION_HEX < 0x70000
3280-
return BRepBuilderAPI_Copy(s);
3281-
#else
3282-
return s;
3283-
#endif
3284-
}
3285-
3286-
double min_edge_length(const TopoDS_Shape& a) {
3287-
double min_edge_len = std::numeric_limits<double>::infinity();
3288-
TopExp_Explorer exp(a, TopAbs_EDGE);
3289-
for (; exp.More(); exp.Next()) {
3290-
GProp_GProps prop;
3291-
BRepGProp::LinearProperties(exp.Current(), prop);
3292-
double l = prop.Mass();
3293-
if (l < min_edge_len) {
3294-
min_edge_len = l;
3295-
}
3296-
}
3297-
return min_edge_len;
3298-
}
3299-
3300-
double min_vertex_edge_distance(const TopoDS_Shape& a, double t) {
3301-
TopExp_Explorer exp(a, TopAbs_VERTEX);
3302-
3303-
double M = std::numeric_limits<double>::infinity();
3304-
3305-
for (; exp.More(); exp.Next()) {
3306-
if (exp.Current().Orientation() != TopAbs_FORWARD) {
3307-
continue;
3308-
}
3309-
3310-
const TopoDS_Vertex& v = TopoDS::Vertex(exp.Current());
3311-
gp_Pnt p = BRep_Tool::Pnt(v);
3312-
3313-
TopExp_Explorer exp2(a, TopAbs_EDGE);
3314-
for (; exp2.More(); exp2.Next()) {
3315-
const TopoDS_Edge& e = TopoDS::Edge(exp2.Current());
3316-
TopoDS_Vertex v1, v2;
3317-
TopExp::Vertices(e, v1, v2);
3318-
3319-
if (v.IsSame(v1) || v.IsSame(v2)) {
3320-
continue;
3321-
}
3322-
3323-
BRepAdaptor_Curve crv(e);
3324-
Extrema_ExtPC ext(p, crv);
3325-
if (!ext.IsDone()) {
3326-
continue;
3327-
}
3328-
3329-
for (int i = 1; i <= ext.NbExt(); ++i) {
3330-
const double m = sqrt(ext.SquareDistance(i));
3331-
if (m < M && m > t) {
3332-
M = m;
3333-
}
3334-
}
3335-
}
3336-
}
3337-
3338-
return M;
3339-
}
3340-
3341-
bool is_manifold(const TopoDS_Shape& a) {
3342-
TopTools_IndexedDataMapOfShapeListOfShape map;
3343-
TopExp::MapShapesAndAncestors(a, TopAbs_EDGE, TopAbs_FACE, map);
3344-
3345-
for (int i = 1; i <= map.Extent(); ++i) {
3346-
if (map.FindFromIndex(i).Extent() != 2) {
3347-
return false;
3348-
}
3349-
}
3350-
3351-
return true;
3352-
}
3353-
3354-
bool is_manifold(const TopTools_ListOfShape& l) {
3355-
TopTools_ListOfShape r;
3356-
TopTools_ListIteratorOfListOfShape it(l);
3357-
for (; it.More(); it.Next()) {
3358-
if (!is_manifold(it.Value())) {
3359-
return false;
3360-
}
3361-
}
3362-
return true;
3363-
}
3364-
3365-
void bounding_box_overlap(double p, const TopoDS_Shape& a, const TopTools_ListOfShape& b, TopTools_ListOfShape& c) {
3366-
Bnd_Box A;
3367-
BRepBndLib::Add(a, A);
3368-
3369-
TopTools_ListIteratorOfListOfShape it(b);
3370-
for (; it.More(); it.Next()) {
3371-
Bnd_Box B;
3372-
BRepBndLib::Add(it.Value(), B);
3373-
3374-
if (A.Distance(B) < p) {
3375-
c.Append(it.Value());
3376-
}
3377-
}
3378-
}
3379-
}
3380-
33813381
bool IfcGeom::Kernel::boolean_operation(const TopoDS_Shape& a, const TopTools_ListOfShape& b_, BOPAlgo_Operation op, TopoDS_Shape& result, double fuzziness) {
33823382
bool success = false;
33833383
BRepAlgoAPI_BooleanOperation* builder;

0 commit comments

Comments
 (0)