|
156 | 156 | #endif |
157 | 157 | #endif |
158 | 158 |
|
| 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 | + |
159 | 279 | bool IfcGeom::Kernel::create_solid_from_compound(const TopoDS_Shape& compound, TopoDS_Shape& shape) { |
160 | 280 | TopTools_ListOfShape face_list; |
161 | 281 | TopExp_Explorer exp(compound, TopAbs_FACE); |
@@ -2937,7 +3057,7 @@ bool IfcGeom::Kernel::wire_intersections(const TopoDS_Wire& wire, TopTools_ListO |
2937 | 3057 | // TopoDS_Face face = BRepBuilderAPI_MakeFace(wire, true).Face(); |
2938 | 3058 | // ShapeAnalysis_Wire saw(wd, face, getValue(GV_PRECISION)); |
2939 | 3059 |
|
2940 | | - const double eps = getValue(GV_PRECISION) * 10.; |
| 3060 | + const double eps = (std::min)(min_edge_length(wire) / 2., getValue(GV_PRECISION) * 10.); |
2941 | 3061 |
|
2942 | 3062 | for (int i = 2; i < n; ++i) { |
2943 | 3063 |
|
@@ -2974,6 +3094,7 @@ bool IfcGeom::Kernel::wire_intersections(const TopoDS_Wire& wire, TopTools_ListO |
2974 | 3094 | BRep_Tool::Curve(wd->Edge(j + 1), u21, u22) |
2975 | 3095 | ); |
2976 | 3096 |
|
| 3097 | + // @todo: extend this to work in case of multiple extrema and curved segments. |
2977 | 3098 | if ((unbounded_intersects = (ecc.NbExtrema() == 1 && ecc.Distance(1) < eps))) { |
2978 | 3099 | ecc.Parameters(1, U1, U2); |
2979 | 3100 | } |
@@ -3257,127 +3378,6 @@ bool IfcGeom::Kernel::boolean_operation(const TopoDS_Shape& a, const TopoDS_Shap |
3257 | 3378 | return succesful; |
3258 | 3379 | } |
3259 | 3380 | #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 | | - |
3381 | 3381 | bool IfcGeom::Kernel::boolean_operation(const TopoDS_Shape& a, const TopTools_ListOfShape& b_, BOPAlgo_Operation op, TopoDS_Shape& result, double fuzziness) { |
3382 | 3382 | bool success = false; |
3383 | 3383 | BRepAlgoAPI_BooleanOperation* builder; |
|
0 commit comments