2 // Created by: Eugeny MALTCHIKOV
3 // Copyright (c) 2016 OPEN CASCADE SAS
5 // This file is part of Open CASCADE Technology software library.
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
17 // This is the implementation of the extension of the 3D offset algorithm
18 // to work in mode Complete and Join Type Intersection.
19 // Currently only the Planar cases are supported.
22 #include <BRepOffset_MakeOffset.hxx>
24 #include <Precision.hxx>
27 #include <BRepAlgo_AsDes.hxx>
28 #include <BRepAlgo_Image.hxx>
30 #include <BRep_Builder.hxx>
31 #include <BRep_Tool.hxx>
33 #include <BRepTools.hxx>
35 #include <BRepAdaptor_Curve.hxx>
38 #include <TopExp_Explorer.hxx>
40 #include <TopTools_DataMapOfShapeInteger.hxx>
42 #include <BRepOffset_Tool.hxx>
44 #include <BRepClass3d_SolidClassifier.hxx>
46 #include <BOPDS_DS.hxx>
48 #include <BOPAlgo_PaveFiller.hxx>
49 #include <BOPAlgo_Builder.hxx>
50 #include <BOPAlgo_Section.hxx>
51 #include <BOPAlgo_MakerVolume.hxx>
52 #include <BOPAlgo_BuilderFace.hxx>
54 #include <BOPCol_ListOfShape.hxx>
55 #include <BOPCol_DataMapOfShapeShape.hxx>
56 #include <BOPCol_IndexedDataMapOfShapeListOfShape.hxx>
58 #include <BOPTools.hxx>
59 #include <BOPTools_AlgoTools3D.hxx>
60 #include <BOPTools_AlgoTools.hxx>
61 #include <BOPTools_AlgoTools2D.hxx>
63 #include <IntTools_Context.hxx>
64 #include <IntTools_ShrunkRange.hxx>
66 typedef NCollection_DataMap
67 <TopoDS_Shape, TopTools_MapOfShape, TopTools_ShapeMapHasher> BRepOffset_DataMapOfShapeMapOfShape;
70 void IntersectTrimmedEdges(const TopTools_ListOfShape& theLF,
71 const Handle(BRepAlgo_AsDes)& theAsDes,
72 TopTools_DataMapOfShapeListOfShape& theOEImages,
73 TopTools_DataMapOfShapeListOfShape& theOEOrigins,
74 TopTools_DataMapOfShapeListOfShape& theEdgesOrigins,
75 Handle(IntTools_Context)& theCtx,
76 TopTools_MapOfShape& theNewEdges,
77 TopTools_DataMapOfShapeShape& theETrimEInf);
80 Standard_Boolean GetEdges(const TopoDS_Face& theFace,
81 const Handle(BRepAlgo_AsDes)& theAsDes,
82 const TopTools_DataMapOfShapeListOfShape& theEImages,
83 const TopTools_MapOfShape& theLastInvEdges,
84 const TopTools_IndexedMapOfShape& theInvEdges,
85 Handle(IntTools_Context)& theCtx,
86 const TopTools_MapOfShape& theModifiedEdges,
87 TopoDS_Shape& theEdges,
88 TopTools_IndexedMapOfShape& theInv);
91 void BuildSplitsOfTrimmedFace(const TopoDS_Face& theFace,
92 const TopoDS_Shape& theEdges,
93 TopTools_ListOfShape& theLFImages);
96 void BuildSplitsOfFace(const TopoDS_Face& theFace,
97 const TopoDS_Shape& theEdges,
98 TopTools_DataMapOfShapeShape& theOrigins,
99 TopTools_ListOfShape& theLFImages);
102 void BuildSplitsOfFaces(const TopTools_ListOfShape& theLF,
103 const TopTools_MapOfShape& theModifiedEdges,
104 const TopTools_DataMapOfShapeListOfShape& theEdgesOrigins,
105 Handle(BRepAlgo_AsDes)& theAsDes,
106 TopTools_DataMapOfShapeShape& theFacesOrigins,
107 TopTools_DataMapOfShapeListOfShape& theOEImages,
108 TopTools_DataMapOfShapeListOfShape& theOEOrigins,
109 TopTools_MapOfShape& theLastInvEdges,
110 TopTools_IndexedMapOfShape& theEdgesToAvoid,
111 TopTools_IndexedMapOfShape& theInvEdges,
112 TopTools_IndexedMapOfShape& theValidEdges,
113 TopTools_MapOfShape& theInvertedEdges,
114 TopTools_DataMapOfShapeInteger& theAlreadyInvFaces,
115 TopTools_IndexedDataMapOfShapeListOfShape& theInvFaces,
116 TopTools_DataMapOfShapeShape& theArtInvFaces,
117 TopTools_IndexedDataMapOfShapeListOfShape& theFImages,
118 TopTools_DataMapOfShapeListOfShape& theDMFNewHoles,
119 TopoDS_Shape& theSolids,
120 TopTools_DataMapOfShapeListOfShape& theSSInterfs);
123 void BuildSplitsOfInvFaces(const TopTools_IndexedDataMapOfShapeListOfShape& theFToRebuild,
124 const TopTools_MapOfShape& theModifiedEdges,
125 TopTools_IndexedDataMapOfShapeListOfShape& theFImages,
126 TopTools_DataMapOfShapeListOfShape& theDMFNewHoles,
127 TopTools_DataMapOfShapeListOfShape& theEdgesOrigins,
128 TopTools_DataMapOfShapeShape& theFacesOrigins,
129 TopTools_DataMapOfShapeListOfShape& theOEImages,
130 TopTools_DataMapOfShapeListOfShape& theOEOrigins,
131 TopTools_MapOfShape& theLastInvEdges,
132 TopTools_IndexedMapOfShape& theEdgesToAvoid,
133 TopTools_MapOfShape& theVertsToAvoid,
134 TopTools_DataMapOfShapeInteger& theAlreadyInvFaces,
135 TopTools_IndexedMapOfShape& theValidEdges,
136 TopTools_DataMapOfShapeShape& theETrimEInf,
137 Handle(BRepAlgo_AsDes)& theAsDes);
140 Standard_Boolean CheckIfArtificial(const TopoDS_Shape& theF,
141 const TopTools_ListOfShape& theLFImages,
142 const TopoDS_Shape& theCE,
143 const TopTools_IndexedMapOfShape& theMapEInv,
144 const TopTools_DataMapOfShapeListOfShape& theOEImages,
145 TopTools_MapOfShape& theMENInv,
146 Handle(BRepAlgo_AsDes)& theAsDes);
149 void FindInvalidEdges(const TopoDS_Face& theF,
150 const TopTools_ListOfShape& theLFImages,
151 const TopTools_DataMapOfShapeListOfShape& theEdgesOrigins,
152 const TopTools_DataMapOfShapeShape& theFacesOrigins,
153 const TopTools_DataMapOfShapeListOfShape& theOEImages,
154 const TopTools_DataMapOfShapeListOfShape& theOEOrigins,
155 TopTools_IndexedMapOfShape& theInvEdges,
156 TopTools_IndexedMapOfShape& theValidEdges,
157 TopTools_DataMapOfShapeListOfShape& theDMFLVE,
158 TopTools_DataMapOfShapeListOfShape& theDMFLNE,
159 TopTools_DataMapOfShapeListOfShape& theDMFLIE,
160 TopTools_DataMapOfShapeListOfShape& theDMFLVIE,
161 TopTools_DataMapOfShapeListOfShape& theDMEOrLEIm,
162 TopTools_MapOfShape& theMEInverted,
163 TopTools_MapOfShape& theEdgesInvalidByVertex);
166 void FindInvalidFaces(TopTools_ListOfShape& theLFImages,
167 const TopTools_IndexedMapOfShape& theInvEdges,
168 const TopTools_IndexedMapOfShape& theValidEdges,
169 const TopTools_DataMapOfShapeListOfShape& theDMFLVE,
170 const TopTools_DataMapOfShapeListOfShape& theDMFLIE,
171 const TopTools_ListOfShape& theLENeutral,
172 const TopTools_ListOfShape& theLEValInverted,
173 const TopTools_MapOfShape& theMEInverted,
174 const TopTools_MapOfShape& theEdgesInvalidByVertex,
175 const TopTools_MapOfShape& theMFHoles,
176 TopTools_IndexedMapOfShape& theMFInvInHole,
177 TopTools_ListOfShape& theInvFaces);
180 void FindFacesInsideHoleWires(const TopoDS_Face& theFOrigin,
181 const TopoDS_Face& theFOffset,
182 const TopTools_ListOfShape& theLFImages,
183 const TopTools_MapOfShape& theInvertedEdges,
184 const TopTools_DataMapOfShapeListOfShape& theDMEOrLEIm,
185 TopTools_MapOfShape& theMFHoles,
186 TopTools_DataMapOfShapeListOfShape& theDMFNewHoles,
187 Handle(IntTools_Context)& theContext);
190 gp_Vec GetAverageTangent(const TopoDS_Shape& theS,
191 const Standard_Integer theNbP);
194 Standard_Boolean CheckInverted(const TopoDS_Edge& theEIm,
195 const TopoDS_Face& theFOr,
196 const TopTools_DataMapOfShapeListOfShape& theOEImages,
197 const TopTools_DataMapOfShapeListOfShape& theOEOrigins,
198 const TopTools_DataMapOfShapeListOfShape& theEdgesOrigins,
199 const TopTools_IndexedDataMapOfShapeListOfShape& theDMVE,
200 const TopTools_IndexedMapOfShape& theMEdges,
201 TopTools_MapOfShape& theMEInverted);
204 Standard_Boolean CheckInvertedBlock(const TopoDS_Shape& theCB,
205 const TopTools_ListOfShape& theLCBF,
206 const TopTools_MapOfShape& theMEInverted,
207 const TopTools_DataMapOfShapeListOfShape& theOEOrigins,
208 BRepOffset_DataMapOfShapeMapOfShape& theDMCBVInverted,
209 BRepOffset_DataMapOfShapeMapOfShape& theDMCBVAll);
212 void GetVerticesOnEdges(const TopoDS_Shape& theCB,
213 const TopTools_MapOfShape& theEdges,
214 TopTools_MapOfShape& theVerticesOnEdges,
215 TopTools_MapOfShape& theAllVertices);
218 void RemoveInvalidSplitsByInvertedEdges(const TopTools_MapOfShape& theMEInverted,
219 const TopTools_DataMapOfShapeListOfShape& theOEOrigins,
220 TopTools_IndexedDataMapOfShapeListOfShape& theInvFaces,
221 TopTools_IndexedDataMapOfShapeListOfShape& theFImages,
222 TopTools_IndexedMapOfShape& theMERemoved);
225 void RemoveInvalidSplitsFromValid(const TopTools_IndexedDataMapOfShapeListOfShape& theInvFaces,
226 const TopTools_DataMapOfShapeShape& theArtInvFaces,
227 const TopTools_MapOfShape& theMEInverted,
228 TopTools_IndexedDataMapOfShapeListOfShape& theFImages);
231 void RemoveInsideFaces(TopTools_IndexedDataMapOfShapeListOfShape& theFImages,
232 TopTools_IndexedDataMapOfShapeListOfShape& theInvFaces,
233 const TopTools_DataMapOfShapeShape& theArtInvFaces,
234 const TopTools_IndexedMapOfShape& theInvEdges,
235 const TopTools_IndexedMapOfShape& theMFToCheckInt,
236 const TopTools_IndexedMapOfShape& theMFInvInHole,
237 const TopoDS_Shape& theFHoles,
238 TopTools_DataMapOfShapeListOfShape& theSSInterfs,
239 TopTools_IndexedMapOfShape& theMERemoved,
240 TopTools_IndexedMapOfShape& theMEInside,
241 TopoDS_Shape& theSolids);
244 void ShapesConnections(const TopTools_IndexedDataMapOfShapeListOfShape& theInvFaces,
245 const TopTools_IndexedMapOfShape& theInvEdges,
246 const TopTools_DataMapOfShapeShape& theDMFOr,
247 BOPAlgo_Builder& theBuilder,
248 TopTools_DataMapOfShapeListOfShape& theSSInterfs);
251 void RemoveValidSplits(const TopTools_MapOfShape& theSpRem,
252 TopTools_IndexedDataMapOfShapeListOfShape& theImages,
253 BOPAlgo_Builder& theGF,
254 TopTools_IndexedMapOfShape& theMERemoved);
257 void RemoveInvalidSplits(const TopTools_MapOfShape& theSpRem,
258 const TopTools_DataMapOfShapeShape& theArtInvFaces,
259 const TopTools_IndexedMapOfShape& theInvEdges,
260 TopTools_IndexedDataMapOfShapeListOfShape& theImages,
261 BOPAlgo_Builder& theGF,
262 TopTools_IndexedMapOfShape& theMERemoved);
265 void FilterEdgesImages(const TopoDS_Shape& theS,
266 TopTools_DataMapOfShapeListOfShape& theOEImages,
267 TopTools_DataMapOfShapeListOfShape& theOEOrigins);
270 void FilterInvalidFaces(const TopTools_IndexedDataMapOfShapeListOfShape& theFImages,
271 const TopTools_IndexedDataMapOfShapeListOfShape& theDMEF,
272 const TopTools_IndexedMapOfShape& theMERemoved,
273 TopTools_IndexedDataMapOfShapeListOfShape& theInvFaces,
274 TopTools_DataMapOfShapeShape& theArtInvFaces);
277 void FilterInvalidEdges(const TopTools_IndexedDataMapOfShapeListOfShape& theInvFaces,
278 const TopTools_DataMapOfShapeShape& theArtInvFaces,
279 const TopTools_DataMapOfShapeListOfShape& theDMFLIE,
280 const TopTools_IndexedMapOfShape& theMERemoved,
281 TopTools_IndexedMapOfShape& theInvEdges);
284 void FindFacesToRebuild(const TopTools_IndexedDataMapOfShapeListOfShape& theLFImages,
285 const TopTools_IndexedMapOfShape& theInvEdges,
286 const TopTools_IndexedDataMapOfShapeListOfShape& theInvFaces,
287 const TopTools_DataMapOfShapeListOfShape& theSSInterfs,
288 TopTools_IndexedDataMapOfShapeListOfShape& theFToRebuild,
289 TopTools_MapOfShape& theFSelfRebAvoid);
292 void RebuildFaces(const TopTools_IndexedDataMapOfShapeListOfShape& theFToRebuild,
293 const TopTools_MapOfShape& theFSelfRebAvoid,
294 const TopoDS_Shape& theSolids,
295 const TopTools_DataMapOfShapeListOfShape& theSSInterfs,
296 TopTools_IndexedDataMapOfShapeListOfShape& theFImages,
297 TopTools_DataMapOfShapeListOfShape& theDMFNewHoles,
298 TopTools_DataMapOfShapeListOfShape& theEdgesOrigins,
299 TopTools_DataMapOfShapeShape& theFacesOrigins,
300 TopTools_DataMapOfShapeListOfShape& theOEImages,
301 TopTools_DataMapOfShapeListOfShape& theOEOrigins,
302 TopTools_MapOfShape& theLastInvEdges,
303 TopTools_IndexedMapOfShape& theEdgesToAvoid,
304 TopTools_IndexedMapOfShape& theInvEdges,
305 TopTools_IndexedMapOfShape& theValidEdges,
306 const TopTools_MapOfShape& theInvertedEdges,
307 TopTools_DataMapOfShapeInteger& theAlreadyInvFaces,
308 TopTools_IndexedDataMapOfShapeListOfShape& theInvFaces,
309 const TopTools_DataMapOfShapeShape& theArtInvFaces,
310 TopTools_MapOfShape& theVertsToAvoid,
311 TopTools_DataMapOfShapeShape& theETrimEInf,
312 Handle(BRepAlgo_AsDes)& theAsDes);
315 void IntersectFaces(const TopTools_IndexedDataMapOfShapeListOfShape& theFToRebuild,
316 const TopTools_MapOfShape& theFSelfRebAvoid,
317 const TopoDS_Shape& theSolids,
318 const TopTools_DataMapOfShapeListOfShape& theSSInterfs,
319 TopTools_IndexedDataMapOfShapeListOfShape& theFImages,
320 TopTools_DataMapOfShapeListOfShape& theEdgesOrigins,
321 TopTools_DataMapOfShapeListOfShape& theOEImages,
322 TopTools_DataMapOfShapeListOfShape& theOEOrigins,
323 TopTools_IndexedMapOfShape& theInvEdges,
324 TopTools_IndexedMapOfShape& theValidEdges,
325 const TopTools_MapOfShape& theInvertedEdges,
326 TopTools_IndexedMapOfShape& theEdgesToAvoid,
327 TopTools_IndexedDataMapOfShapeListOfShape& theInvFaces,
328 const TopTools_DataMapOfShapeShape& theArtInvFaces,
329 TopTools_MapOfShape& theVertsToAvoid,
330 TopTools_DataMapOfShapeShape& theETrimEInf,
331 TopTools_MapOfShape& theModifiedEdges,
332 Handle(BRepAlgo_AsDes)& theAsDes);
335 void PrepareFacesForIntersection(const TopTools_IndexedDataMapOfShapeListOfShape& theFToRebuild,
336 const TopTools_IndexedDataMapOfShapeListOfShape& theFImages,
337 const TopTools_IndexedDataMapOfShapeListOfShape& theInvFaces,
338 const TopTools_DataMapOfShapeShape& theArtInvFaces,
339 const Standard_Boolean bLookVertToAvoid,
340 TopTools_IndexedDataMapOfShapeListOfShape& theFLE,
341 TopTools_DataMapOfShapeListOfShape& theMDone,
342 TopTools_DataMapOfShapeListOfShape& theDMSF,
343 TopTools_DataMapOfShapeListOfShape& theMEInfETrim,
344 TopTools_DataMapOfShapeListOfShape& theDMVEFull,
345 TopTools_DataMapOfShapeShape& theETrimEInf,
346 TopTools_IndexedDataMapOfShapeListOfShape& theDMEFInv);
349 void FindVerticesToAvoid(const TopTools_IndexedDataMapOfShapeListOfShape& theDMEFInv,
350 const TopTools_IndexedMapOfShape& theInvEdges,
351 const TopTools_IndexedMapOfShape& theValidEdges,
352 TopTools_DataMapOfShapeListOfShape& theDMVEFull,
353 TopTools_MapOfShape& theMVRInv);
356 void FindFacesForIntersection(const TopoDS_Shape& theFInv,
357 const TopTools_IndexedMapOfShape& theME,
358 const TopTools_IndexedDataMapOfShapeListOfShape& theFImages,
359 const TopTools_DataMapOfShapeListOfShape& theDMSF,
360 const TopTools_MapOfShape& theMVInvAll,
361 const TopTools_DataMapOfShapeShape& theArtInvFaces,
362 const Standard_Boolean theArtCase,
363 const TopTools_DataMapOfShapeListOfShape& theSSInterfs,
364 TopTools_IndexedMapOfShape& theMFAvoid,
365 TopTools_IndexedMapOfShape& theMFInt,
366 TopTools_IndexedMapOfShape& theMFIntExt,
367 TopTools_ListOfShape& theLFImInt);
370 void ProcessCommonEdges(const TopTools_ListOfShape& theLEC,
371 const TopTools_IndexedMapOfShape& theInvEdges,
372 const TopTools_IndexedMapOfShape& theValidEdges,
373 const TopTools_IndexedMapOfShape& theME,
374 const TopTools_DataMapOfShapeShape& theETrimEInf,
375 const TopTools_DataMapOfShapeListOfShape& theMEInfETrim,
376 const TopTools_DataMapOfShapeListOfShape& theOEOrigins,
377 const TopTools_MapOfShape& theAllInvs,
378 const Standard_Boolean theForceUse,
379 TopTools_IndexedMapOfShape& theMECV,
380 TopTools_MapOfShape& theMECheckExt,
381 TopTools_DataMapOfShapeListOfShape& theDMEETrim,
382 TopTools_ListOfShape& theLFEi,
383 TopTools_ListOfShape& theLFEj,
384 TopTools_IndexedMapOfShape& theMEToInt);
387 void UpdateIntersectedFaces(const TopoDS_Shape& theFInv,
388 const TopoDS_Shape& theFi,
389 const TopoDS_Shape& theFj,
390 const TopTools_ListOfShape& theLFInv,
391 const TopTools_ListOfShape& theLFImi,
392 const TopTools_ListOfShape& theLFImj,
393 const TopTools_ListOfShape& theLFEi,
394 const TopTools_ListOfShape& theLFEj,
395 TopTools_DataMapOfShapeListOfShape& theEdgesOrigins,
396 TopTools_IndexedMapOfShape& theMEToInt);
399 void IntersectFaces(const TopoDS_Shape& theFInv,
400 const TopoDS_Shape& theFi,
401 const TopoDS_Shape& theFj,
402 const TopTools_ListOfShape& theLFInv,
403 const TopTools_ListOfShape& theLFImi,
404 const TopTools_ListOfShape& theLFImj,
405 TopTools_ListOfShape& theLFEi,
406 TopTools_ListOfShape& theLFEj,
407 TopTools_DataMapOfShapeListOfShape& theEdgesOrigins,
408 TopTools_IndexedMapOfShape& theMECV,
409 TopTools_IndexedMapOfShape& theMEToInt);
412 void FindOrigins(const TopTools_ListOfShape& theLFIm1,
413 const TopTools_ListOfShape& theLFIm2,
414 const TopTools_IndexedMapOfShape& theME,
415 const TopTools_DataMapOfShapeListOfShape& theOrigins,
416 TopTools_ListOfShape& theLEOr);
419 void IntersectAndTrimEdges(const TopTools_IndexedDataMapOfShapeListOfShape& theFToRebuild,
420 const TopTools_IndexedMapOfShape& theMFInt,
421 const TopTools_IndexedMapOfShape& theMEInt,
422 const TopTools_DataMapOfShapeListOfShape& theDMEETrim,
423 const TopTools_IndexedMapOfShape& theMSInv,
424 const TopTools_IndexedMapOfShape& theMVE,
425 const TopTools_MapOfShape& theVertsToAvoid,
426 const TopTools_MapOfShape& theNewVertsToAvoid,
427 const TopTools_MapOfShape& theMECheckExt,
428 TopTools_MapOfShape& theMVBounds,
429 TopTools_DataMapOfShapeListOfShape& theEImages);
432 void GetInvalidEdges(const TopTools_MapOfShape& theVertsToAvoid,
433 const TopTools_MapOfShape& theMVBounds,
434 BOPAlgo_Builder& theGF,
435 TopTools_MapOfShape& theMEInv);
438 void UpdateValidEdges(const TopTools_IndexedDataMapOfShapeListOfShape& theFImages,
439 const TopTools_IndexedDataMapOfShapeListOfShape& theFLE,
440 const TopTools_MapOfShape& theMVBounds,
441 const TopoDS_Shape& theSolids,
442 const TopTools_IndexedMapOfShape& theInvEdges,
443 const TopTools_MapOfShape& theInvertedEdges,
444 const TopTools_MapOfShape& theMEInvOnArt,
445 TopTools_MapOfShape& theMECheckExt,
446 TopTools_IndexedMapOfShape& theEdgesToAvoid,
447 TopTools_DataMapOfShapeListOfShape& theEdgesOrigins,
448 TopTools_DataMapOfShapeListOfShape& theOEImages,
449 TopTools_DataMapOfShapeListOfShape& theOEOrigins,
450 TopTools_MapOfShape& theVertsToAvoid,
451 TopTools_DataMapOfShapeShape& theETrimEInf,
452 TopTools_DataMapOfShapeListOfShape& theEImages,
453 TopTools_DataMapOfShapeListOfShape& theEETrim,
454 TopTools_MapOfShape& theModifiedEdges,
455 Handle(BRepAlgo_AsDes)& theAsDes);
458 void TrimNewIntersectionEdges(const TopTools_ListOfShape& theLE,
459 const TopTools_DataMapOfShapeListOfShape& theEETrim,
460 const TopTools_MapOfShape& theMVBounds,
461 TopTools_MapOfShape& theMECheckExt,
462 TopTools_DataMapOfShapeListOfShape& theEImages,
463 TopTools_MapOfShape& theMEB,
464 TopTools_MapOfShape& theMVOld,
465 TopTools_ListOfShape& theLENew,
466 BOPCol_ListOfShape& theLA,
467 TopTools_DataMapOfShapeListOfShape& theDMEOr,
468 TopTools_DataMapOfShapeListOfShape& theMELF);
471 void IntersectEdges(const BOPCol_ListOfShape& theLA,
472 const TopTools_ListOfShape& theLE,
473 const TopTools_ListOfShape& theLENew,
474 const TopTools_MapOfShape& theMVBounds,
475 const TopTools_MapOfShape& theVertsToAvoid,
476 TopTools_MapOfShape& theMECheckExt,
477 TopTools_DataMapOfShapeListOfShape& theEImages,
478 TopTools_MapOfShape& theModifiedEdges,
479 TopTools_DataMapOfShapeListOfShape& theDMEOr,
480 TopTools_DataMapOfShapeListOfShape& theMELF,
481 TopTools_MapOfShape& theMENew,
482 TopoDS_Shape& theSplits);
485 void GetBounds(const TopTools_IndexedDataMapOfShapeListOfShape& theFImages,
486 const TopTools_MapOfShape& theMEB,
487 TopoDS_Shape& theBounds);
490 void GetBoundsToUpdate(const TopTools_ListOfShape& theLF,
491 const TopTools_DataMapOfShapeListOfShape& theOEImages,
492 const TopTools_DataMapOfShapeListOfShape& theOEOrigins,
493 const TopTools_MapOfShape& theMEB,
494 TopTools_ListOfShape& theLABounds,
495 TopTools_ListOfShape& theLAValid,
496 TopoDS_Shape& theBounds,
497 Handle(BRepAlgo_AsDes)& theAsDes);
500 void GetInvalidEdgesByBounds(const TopoDS_Shape& theSplits,
501 const TopoDS_Shape& theBounds,
502 const TopTools_IndexedDataMapOfShapeListOfShape& theFImages,
503 const TopoDS_Shape& theSolids,
504 const TopTools_IndexedMapOfShape& theInvEdges,
505 const TopTools_MapOfShape& theMVOld,
506 const TopTools_MapOfShape& theMENew,
507 const TopTools_DataMapOfShapeListOfShape& theDMEOr,
508 const TopTools_DataMapOfShapeListOfShape& theMELF,
509 const TopTools_DataMapOfShapeListOfShape& theEImages,
510 const TopTools_MapOfShape& theMECheckExt,
511 const TopTools_MapOfShape& theMEInvOnArt,
512 TopTools_MapOfShape& theVertsToAvoid,
513 TopTools_MapOfShape& theMEInv);
516 void UpdateNewIntersectionEdges(const TopTools_ListOfShape& theLE,
517 const TopTools_DataMapOfShapeListOfShape& theMELF,
518 const TopTools_DataMapOfShapeListOfShape& theEImages,
519 const TopTools_IndexedMapOfShape& theInvEdges,
520 const TopTools_MapOfShape& theInvertedEdges,
521 TopTools_DataMapOfShapeListOfShape& theEdgesOrigins,
522 TopTools_DataMapOfShapeListOfShape& theOEImages,
523 TopTools_DataMapOfShapeListOfShape& theOEOrigins,
524 TopTools_DataMapOfShapeShape& theETrimEInf,
525 TopTools_DataMapOfShapeListOfShape& theEETrim,
526 TopTools_MapOfShape& theModifiedEdges,
527 Handle(BRepAlgo_AsDes)& theAsDes);
530 void FillHistory(const TopTools_IndexedDataMapOfShapeListOfShape& theFImages,
531 const TopTools_DataMapOfShapeListOfShape& theEImages,
532 BRepAlgo_Image& theImage);
535 void UpdateOrigins(const TopTools_ListOfShape& theLA,
536 TopTools_DataMapOfShapeListOfShape& theOrigins,
537 BOPAlgo_Builder& theGF);
540 void UpdateImages(const TopTools_ListOfShape& theLA,
541 TopTools_DataMapOfShapeListOfShape& theImages,
542 BOPAlgo_Builder& theGF,
543 TopTools_MapOfShape& theModified);
546 void UpdateIntersectedEdges(const TopTools_ListOfShape& theLA,
547 TopTools_DataMapOfShapeShape& theETrimEInf,
548 BOPAlgo_Builder& theGF);
551 Standard_Boolean ProcessMicroEdge(const TopoDS_Edge& theEdge,
552 const Handle(IntTools_Context)& theCtx);
555 void FindCommonParts(const TopTools_ListOfShape& theLS1,
556 const TopTools_ListOfShape& theLS2,
557 TopTools_ListOfShape& theLSC,
558 const TopAbs_ShapeEnum theType = TopAbs_EDGE);
561 Standard_Integer NbPoints(const TopoDS_Edge& theE);
564 Standard_Boolean FindShape(const TopoDS_Shape& theSWhat,
565 const TopoDS_Shape& theSWhere,
566 TopoDS_Shape& theRes);
569 void AppendToList(TopTools_ListOfShape& theL,
570 const TopoDS_Shape& theS);
572 //=======================================================================
573 //function : BuildSplitsOfTrimmedFaces
574 //purpose : Building splits of already trimmed faces
575 //=======================================================================
576 void BRepOffset_MakeOffset::BuildSplitsOfTrimmedFaces(const TopTools_ListOfShape& theLF,
577 Handle(BRepAlgo_AsDes)& theAsDes,
578 BRepAlgo_Image& theImage)
580 TopTools_DataMapOfShapeListOfShape anEImages, anEOrigins;
581 TopTools_IndexedDataMapOfShapeListOfShape aDMFFIm;
582 TopTools_IndexedMapOfShape anEmptyIM;
583 TopTools_DataMapOfShapeListOfShape anEmptyDMSLS;
584 TopTools_DataMapOfShapeShape anEmptyDMSS;
585 TopTools_MapOfShape aNewEdges, anEmptyM;
587 // firstly it is necessary to fuse all the edges
588 Handle(IntTools_Context) aCtx = new IntTools_Context();
590 IntersectTrimmedEdges(theLF, theAsDes, anEImages, anEOrigins, anEmptyDMSLS, aCtx, aNewEdges, anEmptyDMSS);
592 TopTools_ListIteratorOfListOfShape aItLF(theLF);
593 for (; aItLF.More(); aItLF.Next()) {
594 const TopoDS_Face& aF = *(TopoDS_Face*)&aItLF.Value();
597 TopTools_ListOfShape aLFImages;
599 Standard_Boolean bFound = GetEdges(aF, theAsDes, anEImages, anEmptyM,
600 anEmptyIM, aCtx, aNewEdges, aCE, anEmptyIM);
601 // split the face by the edges
603 if (!theImage.HasImage(aF)) {
604 aLFImages.Append(aF);
605 aDMFFIm.Add(aF, aLFImages);
610 BuildSplitsOfTrimmedFace(aF, aCE, aLFImages);
611 aDMFFIm.Add(aF, aLFImages);
613 // Fill history for faces and edges
614 FillHistory(aDMFFIm, anEImages, theImage);
617 //=======================================================================
618 //function : BuildSplitsOfExtendedFaces
619 //purpose : Building splits of not-trimmed offset faces.
620 // For the cases in which invalidity will be found,
621 // these invalidities will be rebuilt.
622 //=======================================================================
623 void BRepOffset_MakeOffset::BuildSplitsOfExtendedFaces(const TopTools_ListOfShape& theLF,
624 Handle(BRepAlgo_AsDes)& theAsDes,
625 TopTools_DataMapOfShapeListOfShape& theEdgesOrigins,
626 TopTools_DataMapOfShapeShape& theFacesOrigins,
627 TopTools_DataMapOfShapeShape& theETrimEInf,
628 BRepAlgo_Image& theImage)
630 Handle(IntTools_Context) aCtx = new IntTools_Context();
631 // images and origins for offset edges
632 TopTools_DataMapOfShapeListOfShape anOEImages, anOEOrigins;
633 TopTools_MapOfShape aNewEdges;
634 // fusing all trimmed offset edges to avoid self-intersections in the splits
635 IntersectTrimmedEdges(theLF, theAsDes, anOEImages, anOEOrigins,
636 theEdgesOrigins, aCtx, aNewEdges, theETrimEInf);
638 // valid/invalid edges
639 TopTools_IndexedMapOfShape anInvEdges, aValidEdges, anEdgesToAvoid;
641 TopTools_MapOfShape anInvertedEdges;
643 TopTools_IndexedDataMapOfShapeListOfShape aFImages;
644 // found invalid faces
645 TopTools_IndexedDataMapOfShapeListOfShape anInvFaces;
646 // artificially invalid faces - it will be empty here,
647 // but may be filled on the following rebuilding steps
648 TopTools_DataMapOfShapeShape anArtInvFaces;
649 // shapes connections for using in rebuilding
650 TopTools_DataMapOfShapeListOfShape aSSInterfs;
651 // edges to avoid on second steps
652 TopTools_MapOfShape aLastInvEdges;
653 // keep information of already invalid faces to avoid
654 // infinite rebuilding of the same invalid face
655 TopTools_DataMapOfShapeInteger anAlreadyInvFaces;
656 // images of the hole faces of the original faces
657 TopTools_DataMapOfShapeListOfShape aDMFNewHoles;
658 // solid build from the new splits
659 TopoDS_Shape aSolids;
660 // now we can split the faces
661 BuildSplitsOfFaces(theLF, aNewEdges, theEdgesOrigins, theAsDes, theFacesOrigins,
662 anOEImages, anOEOrigins, aLastInvEdges, anEdgesToAvoid, anInvEdges, aValidEdges,
663 anInvertedEdges, anAlreadyInvFaces, anInvFaces, anArtInvFaces, aFImages,
664 aDMFNewHoles, aSolids, aSSInterfs);
666 // Find faces to rebuild
667 if (anInvFaces.Extent()) {
668 TopTools_IndexedDataMapOfShapeListOfShape aFToRebuild;
669 TopTools_MapOfShape aFSelfRebAvoid;
670 FindFacesToRebuild(aFImages, anInvEdges, anInvFaces, aSSInterfs, aFToRebuild, aFSelfRebAvoid);
672 if (aFToRebuild.Extent()) {
674 TopTools_MapOfShape aVAEmpty;
675 RebuildFaces(aFToRebuild, aFSelfRebAvoid, aSolids, aSSInterfs, aFImages, aDMFNewHoles,
676 theEdgesOrigins, theFacesOrigins, anOEImages, anOEOrigins, aLastInvEdges,
677 anEdgesToAvoid, anInvEdges, aValidEdges, anInvertedEdges, anAlreadyInvFaces,
678 anInvFaces, anArtInvFaces, aVAEmpty, theETrimEInf, theAsDes);
681 // Fill history for faces and edges
682 FillHistory(aFImages, anOEImages, theImage);
685 //=======================================================================
686 //function : BuildSplitsOfInvFaces
687 //purpose : Rebuilding splits of faces with new intersection edges
688 //=======================================================================
689 void BuildSplitsOfInvFaces(const TopTools_IndexedDataMapOfShapeListOfShape& theFToRebuild,
690 const TopTools_MapOfShape& theModifiedEdges,
691 TopTools_IndexedDataMapOfShapeListOfShape& theFImages,
692 TopTools_DataMapOfShapeListOfShape& theDMFNewHoles,
693 TopTools_DataMapOfShapeListOfShape& theEdgesOrigins,
694 TopTools_DataMapOfShapeShape& theFacesOrigins,
695 TopTools_DataMapOfShapeListOfShape& theOEImages,
696 TopTools_DataMapOfShapeListOfShape& theOEOrigins,
697 TopTools_MapOfShape& theLastInvEdges,
698 TopTools_IndexedMapOfShape& theEdgesToAvoid,
699 TopTools_MapOfShape& theVertsToAvoid,
700 TopTools_DataMapOfShapeInteger& theAlreadyInvFaces,
701 TopTools_IndexedMapOfShape& theValidEdges,
702 TopTools_DataMapOfShapeShape& theETrimEInf,
703 Handle(BRepAlgo_AsDes)& theAsDes)
705 Standard_Integer aNb = theFToRebuild.Extent();
710 TopTools_ListOfShape aLF;
711 aNb = theFImages.Extent();
712 for (Standard_Integer i = 1; i <= aNb; ++i) {
713 const TopoDS_Shape& aF = theFImages.FindKey(i);
718 TopTools_IndexedDataMapOfShapeListOfShape anInvFaces;
719 // artificially invalid faces
720 TopTools_DataMapOfShapeShape anArtInvFaces;
722 TopTools_IndexedMapOfShape anInvEdges;
724 TopTools_MapOfShape anInvertedEdges;
725 // shapes connection for using in rebuilding process
726 TopTools_DataMapOfShapeListOfShape aSSInterfs;
728 TopoDS_Shape aSolids;
730 BuildSplitsOfFaces(aLF, theModifiedEdges, theEdgesOrigins, theAsDes, theFacesOrigins,
731 theOEImages, theOEOrigins, theLastInvEdges, theEdgesToAvoid, anInvEdges, theValidEdges,
732 anInvertedEdges, theAlreadyInvFaces, anInvFaces, anArtInvFaces, theFImages,
733 theDMFNewHoles, aSolids, aSSInterfs);
735 if (anInvFaces.Extent()) {
736 TopTools_IndexedDataMapOfShapeListOfShape aFToRebuild;
737 TopTools_MapOfShape aFSelfRebAvoid;
738 FindFacesToRebuild(theFImages, anInvEdges, anInvFaces, aSSInterfs, aFToRebuild, aFSelfRebAvoid);
740 if (aFToRebuild.Extent()) {
741 RebuildFaces(aFToRebuild, aFSelfRebAvoid, aSolids, aSSInterfs, theFImages, theDMFNewHoles,
742 theEdgesOrigins, theFacesOrigins, theOEImages, theOEOrigins, theLastInvEdges,
743 theEdgesToAvoid, anInvEdges, theValidEdges, anInvertedEdges, theAlreadyInvFaces,
744 anInvFaces, anArtInvFaces, theVertsToAvoid, theETrimEInf, theAsDes);
749 //=======================================================================
750 //function : BuildSplitsOfFaces
751 //purpose : Building the splits of offset faces and
752 // looking for the invalid splits
753 //=======================================================================
754 void BuildSplitsOfFaces(const TopTools_ListOfShape& theLF,
755 const TopTools_MapOfShape& theModifiedEdges,
756 const TopTools_DataMapOfShapeListOfShape& theEdgesOrigins,
757 Handle(BRepAlgo_AsDes)& theAsDes,
758 TopTools_DataMapOfShapeShape& theFacesOrigins,
759 TopTools_DataMapOfShapeListOfShape& theOEImages,
760 TopTools_DataMapOfShapeListOfShape& theOEOrigins,
761 TopTools_MapOfShape& theLastInvEdges,
762 TopTools_IndexedMapOfShape& theEdgesToAvoid,
763 TopTools_IndexedMapOfShape& theInvEdges,
764 TopTools_IndexedMapOfShape& theValidEdges,
765 TopTools_MapOfShape& theInvertedEdges,
766 TopTools_DataMapOfShapeInteger& theAlreadyInvFaces,
767 TopTools_IndexedDataMapOfShapeListOfShape& theInvFaces,
768 TopTools_DataMapOfShapeShape& theArtInvFaces,
769 TopTools_IndexedDataMapOfShapeListOfShape& theFImages,
770 TopTools_DataMapOfShapeListOfShape& theDMFNewHoles,
771 TopoDS_Shape& theSolids,
772 TopTools_DataMapOfShapeListOfShape& theSSInterfs)
774 if (theLF.IsEmpty()) {
779 Standard_Integer i, aNb;
782 TopTools_ListOfShape aLFDone;
783 // extended face - list of neutral edges, i.e. in one splits - valid and in others - invalid
784 TopTools_DataMapOfShapeListOfShape aDMFLNE;
785 // list of valid edges for each face
786 TopTools_DataMapOfShapeListOfShape aDMFLVE;
787 // list of invalid edges for each face
788 TopTools_DataMapOfShapeListOfShape aDMFLIE;
789 // map of valid inverted edges for the face
790 TopTools_DataMapOfShapeListOfShape aDMFLVIE;
791 // map of splits to check for internals
792 TopTools_IndexedMapOfShape aMFToCheckInt;
793 // map of edges created from vertex and marked as invalid
794 TopTools_MapOfShape aMEdgeInvalidByVertex;
795 // connection map from old edges to new ones
796 TopTools_DataMapOfShapeListOfShape aDMEOrLEIm;
798 Handle(IntTools_Context) aCtx = new IntTools_Context;
799 // build splits of faces
800 TopTools_ListIteratorOfListOfShape aItLF(theLF);
801 for (; aItLF.More(); aItLF.Next()) {
802 const TopoDS_Face& aF = *(TopoDS_Face*)&aItLF.Value();
804 TopTools_ListOfShape* pLFIm = theFImages.ChangeSeek(aF);
805 if (pLFIm && pLFIm->IsEmpty()) {
808 // get edges by which the face should be split
810 TopTools_IndexedMapOfShape aMapEInv;
811 Standard_Boolean bFound =
812 GetEdges(aF, theAsDes, theOEImages, theLastInvEdges,
813 theEdgesToAvoid, aCtx, theModifiedEdges, aCE, aMapEInv);
819 TopTools_ListOfShape aLFImages;
820 BuildSplitsOfFace(aF, aCE, theFacesOrigins, aLFImages);
822 if (aMapEInv.Extent()) {
823 // check if all possible faces are built
824 TopTools_MapOfShape aMENInv;
825 Standard_Boolean bArtificialCase = aLFImages.IsEmpty() ||
826 CheckIfArtificial(aF, aLFImages, aCE, aMapEInv, theOEImages, aMENInv, theAsDes);
828 // try to build splits using invalid edges
829 TopoDS_Compound aCE1;
830 aBB.MakeCompound(aCE1);
832 for (i = 1; i <= aMapEInv.Extent(); ++i) {
833 aBB.Add(aCE1, aMapEInv(i));
836 TopTools_ListOfShape aLFImages1;
837 BuildSplitsOfFace(aF, aCE1, theFacesOrigins, aLFImages1);
839 // check if the rebuilding has added some new faces to the splits
840 for (TopTools_ListIteratorOfListOfShape aItLFIm(aLFImages1); aItLFIm.More();)
842 Standard_Boolean bAllInv = Standard_True;
843 const TopoDS_Shape& aFIm = aItLFIm.Value();
844 TopExp_Explorer aExpE(aFIm, TopAbs_EDGE);
845 for (; aExpE.More(); aExpE.Next()) {
846 const TopoDS_Shape& aE = aExpE.Current();
847 if (!aMapEInv.Contains(aE)) {
848 bAllInv = Standard_False;
849 if (!aMENInv.Contains(aE)) {
857 aMFToCheckInt.Add(aFIm);
859 aLFImages1.Remove(aItLFIm);
866 if (bArtificialCase) {
867 if (aLFImages.Extent() == aLFImages1.Extent()) {
868 bArtificialCase = Standard_False;
871 aLFImages = aLFImages1;
875 if (bArtificialCase) {
876 TopTools_ListOfShape aLEInv;
877 // make the face invalid
878 theArtInvFaces.Bind(aF, aCE);
881 TopTools_ListIteratorOfListOfShape aItLFIm(aLFImages);
882 for (; aItLFIm.More(); aItLFIm.Next()) {
883 const TopoDS_Shape& aFIm = aItLFIm.Value();
884 TopExp_Explorer aExpE(aFIm, TopAbs_EDGE);
885 for (; aExpE.More(); aExpE.Next()) {
886 const TopoDS_Shape& aE = aExpE.Current();
887 if (aMapEInv.Contains(aE)) {
889 AppendToList(aLEInv, aE);
892 theValidEdges.Add(aE);
897 aDMFLIE.Bind(aF, aLEInv);
904 // find invalid edges
905 FindInvalidEdges(aF, aLFImages, theEdgesOrigins, theFacesOrigins, theOEImages,
906 theOEOrigins, theInvEdges, theValidEdges, aDMFLVE, aDMFLNE, aDMFLIE,
907 aDMFLVIE, aDMEOrLEIm, theInvertedEdges, aMEdgeInvalidByVertex);
909 // save the new splits
911 pLFIm = &theFImages(theFImages.Add(aF, TopTools_ListOfShape()));
916 pLFIm->Append(aLFImages);
921 if (theInvEdges.IsEmpty() && theArtInvFaces.IsEmpty()) {
926 // show invalid edges
927 TopoDS_Compound aCEInv1;
928 BRep_Builder().MakeCompound(aCEInv1);
929 Standard_Integer aNbEInv = theInvEdges.Extent();
930 for (i = 1; i <= aNbEInv; ++i) {
931 const TopoDS_Shape& aE = theInvEdges(i);
932 BRep_Builder().Add(aCEInv1, aE);
935 TopoDS_Compound aCEVal1;
936 BRep_Builder().MakeCompound(aCEVal1);
937 aNbEInv = theValidEdges.Extent();
938 for (i = 1; i <= aNbEInv; ++i) {
939 const TopoDS_Shape& aE = theValidEdges(i);
940 BRep_Builder().Add(aCEVal1, aE);
942 // show inverted edges
943 TopoDS_Compound aCEInverted;
944 BRep_Builder().MakeCompound(aCEInverted);
945 TopTools_MapIteratorOfMapOfShape aItM(theInvertedEdges);
946 for (; aItM.More(); aItM.Next()) {
947 BRep_Builder().Add(aCEInverted, aItM.Value());
951 TopTools_ListOfShape anEmptyList;
952 // invalid faces inside the holes
953 TopTools_IndexedMapOfShape aMFInvInHole;
955 TopoDS_Compound aFHoles;
956 aBB.MakeCompound(aFHoles);
957 // find invalid faces
958 // considering faces containing only invalid edges as invalid
959 aItLF.Initialize(aLFDone);
960 for (; aItLF.More(); aItLF.Next()) {
961 const TopoDS_Face& aF = TopoDS::Face(aItLF.Value());
962 TopTools_ListOfShape& aLFImages = theFImages.ChangeFromKey(aF);
964 TopTools_ListOfShape aLFInv;
965 Standard_Boolean bArtificialCase = theArtInvFaces.IsBound(aF);
966 if (bArtificialCase) {
971 TopTools_ListOfShape* pLNE = aDMFLNE.ChangeSeek(aF);
975 // valid inverted edges
976 TopTools_ListOfShape* pLIVE = aDMFLVIE.ChangeSeek(aF);
978 pLIVE = &anEmptyList;
981 // find faces inside holes wires
982 TopTools_MapOfShape aMFHoles;
983 const TopoDS_Face& aFOr = TopoDS::Face(theFacesOrigins.Find(aF));
984 FindFacesInsideHoleWires(aFOr, aF, aLFImages, theInvertedEdges,
985 aDMEOrLEIm, aMFHoles, theDMFNewHoles, aCtx);
987 TopTools_MapIteratorOfMapOfShape aItMH(aMFHoles);
988 for (; aItMH.More(); aItMH.Next()) {
989 aBB.Add(aFHoles, aItMH.Value());
992 // find invalid faces
993 FindInvalidFaces(aLFImages, theInvEdges, theValidEdges, aDMFLVE, aDMFLIE,
994 *pLNE, *pLIVE, theInvertedEdges, aMEdgeInvalidByVertex,
995 aMFHoles, aMFInvInHole, aLFInv);
998 if (aLFInv.Extent()) {
999 if (theAlreadyInvFaces.IsBound(aF)) {
1000 if (theAlreadyInvFaces.Find(aF) > 2) {
1001 if (aLFInv.Extent() == aLFImages.Extent() && !bArtificialCase) {
1008 theInvFaces.Add(aF, aLFInv);
1012 if (theInvFaces.IsEmpty()) {
1013 theInvEdges.Clear();
1018 // show invalid faces
1019 TopoDS_Compound aCFInv1;
1020 BRep_Builder().MakeCompound(aCFInv1);
1021 Standard_Integer aNbFInv = theInvFaces.Extent();
1022 for (i = 1; i <= aNbFInv; ++i) {
1023 const TopTools_ListOfShape& aLFInv = theInvFaces(i);
1024 TopTools_ListIteratorOfListOfShape aItLFInv(aLFInv);
1025 for (; aItLFInv.More(); aItLFInv.Next()) {
1026 const TopoDS_Shape& aFIm = aItLFInv.Value();
1027 BRep_Builder().Add(aCFInv1, aFIm);
1032 TopTools_IndexedMapOfShape aMERemoved;
1033 // remove invalid splits of faces using inverted edges
1034 RemoveInvalidSplitsByInvertedEdges(theInvertedEdges, theOEOrigins,
1035 theInvFaces, theFImages, aMERemoved);
1036 if (theInvFaces.IsEmpty()) {
1037 theInvEdges.Clear();
1041 // remove invalid splits from valid splits
1042 RemoveInvalidSplitsFromValid(theInvFaces, theArtInvFaces, theInvertedEdges, theFImages);
1044 // remove inside faces
1045 TopTools_IndexedMapOfShape aMEInside;
1046 RemoveInsideFaces(theFImages, theInvFaces, theArtInvFaces, theInvEdges,
1047 aMFToCheckInt, aMFInvInHole, aFHoles, theSSInterfs,
1048 aMERemoved, aMEInside, theSolids);
1050 // make compound of valid splits
1051 TopoDS_Compound aCFIm;
1052 aBB.MakeCompound(aCFIm);
1054 aNb = theFImages.Extent();
1055 for (i = 1; i <= aNb; ++i) {
1056 const TopTools_ListOfShape& aLFIm = theFImages(i);
1057 aItLF.Initialize(aLFIm);
1058 for (; aItLF.More(); aItLF.Next()) {
1059 const TopoDS_Shape& aFIm = aItLF.Value();
1060 aBB.Add(aCFIm, aFIm);
1064 TopTools_IndexedDataMapOfShapeListOfShape aDMEF;
1065 TopExp::MapShapesAndAncestors(aCFIm, TopAbs_EDGE, TopAbs_FACE, aDMEF);
1067 // filter maps of images and origins
1068 FilterEdgesImages(aCFIm, theOEImages, theOEOrigins);
1070 // filter invalid faces
1071 FilterInvalidFaces(theFImages, aDMEF, aMEInside, theInvFaces, theArtInvFaces);
1072 aNb = theInvFaces.Extent();
1074 theInvEdges.Clear();
1079 // show invalid faces
1080 TopoDS_Compound aCFInv;
1081 BRep_Builder().MakeCompound(aCFInv);
1082 aNbFInv = theInvFaces.Extent();
1083 for (i = 1; i <= aNbFInv; ++i) {
1084 const TopTools_ListOfShape& aLFInv = theInvFaces(i);
1085 TopTools_ListIteratorOfListOfShape aItLFInv(aLFInv);
1086 for (; aItLFInv.More(); aItLFInv.Next()) {
1087 const TopoDS_Shape& aFIm = aItLFInv.Value();
1088 BRep_Builder().Add(aCFInv, aFIm);
1093 // filter invalid edges
1094 FilterInvalidEdges(theInvFaces, theArtInvFaces, aDMFLIE, aMERemoved, theInvEdges);
1097 // show invalid edges
1098 TopoDS_Compound aCEInv;
1099 BRep_Builder().MakeCompound(aCEInv);
1100 aNbEInv = theInvEdges.Extent();
1101 for (i = 1; i <= aNbEInv; ++i) {
1102 const TopoDS_Shape& aE = theInvEdges(i);
1103 BRep_Builder().Add(aCEInv, aE);
1107 theLastInvEdges.Clear();
1108 aNb = theInvEdges.Extent();
1109 for (i = 1; i <= aNb; ++i) {
1110 const TopoDS_Shape& aE = theInvEdges(i);
1111 theEdgesToAvoid.Add(aE);
1112 theLastInvEdges.Add(aE);
1115 aNb = theInvFaces.Extent();
1116 for (i = 1; i <= aNb; ++i) {
1117 const TopoDS_Shape& aF = theInvFaces.FindKey(i);
1118 if (theAlreadyInvFaces.IsBound(aF)) {
1119 theAlreadyInvFaces.ChangeFind(aF)++;
1122 theAlreadyInvFaces.Bind(aF, 1);
1127 //=======================================================================
1128 //function : IntersectTrimmedEdges
1129 //purpose : Intersection of the trimmed edges among themselves
1130 //=======================================================================
1131 void IntersectTrimmedEdges(const TopTools_ListOfShape& theLF,
1132 const Handle(BRepAlgo_AsDes)& theAsDes,
1133 TopTools_DataMapOfShapeListOfShape& theOEImages,
1134 TopTools_DataMapOfShapeListOfShape& theOEOrigins,
1135 TopTools_DataMapOfShapeListOfShape& theEdgesOrigins,
1136 Handle(IntTools_Context)& theCtx,
1137 TopTools_MapOfShape& theNewEdges,
1138 TopTools_DataMapOfShapeShape& theETrimEInf)
1140 if (theLF.IsEmpty()) {
1144 // get edges to intersect from descendants of the offset faces
1145 BOPCol_ListOfShape aLS;
1147 TopTools_ListIteratorOfListOfShape aItLF(theLF);
1148 for (; aItLF.More(); aItLF.Next()) {
1149 const TopoDS_Face& aF = *(TopoDS_Face*)&aItLF.Value();
1151 const TopTools_ListOfShape& aLE = theAsDes->Descendant(aF);
1152 TopTools_ListIteratorOfListOfShape aItLE(aLE);
1153 for (; aItLE.More(); aItLE.Next()) {
1154 const TopoDS_Edge& aE = *(TopoDS_Edge*)&aItLE.Value();
1156 if (ProcessMicroEdge(aE, theCtx)) {
1160 if (theNewEdges.Add(aE)) {
1166 if (aLS.Extent() < 2) {
1167 // nothing to intersect
1171 // perform intersection of the edges
1172 BOPAlgo_Builder aGFE;
1173 aGFE.SetArguments(aLS);
1175 if (aGFE.ErrorStatus()) {
1179 TopTools_ListOfShape aLA;
1180 // fill map with edges images
1181 BOPCol_ListIteratorOfListOfShape aIt(aLS);
1182 for (; aIt.More(); aIt.Next()) {
1183 const TopoDS_Shape& aE = aIt.Value();
1184 const TopTools_ListOfShape& aLEIm = aGFE.Modified(aE);
1185 if (aLEIm.IsEmpty()) {
1191 theOEImages.Bind(aE, aLEIm);
1193 TopTools_ListIteratorOfListOfShape aItLE(aLEIm);
1194 for (; aItLE.More(); aItLE.Next()) {
1195 const TopoDS_Shape& aEIm = aItLE.Value();
1196 TopTools_ListOfShape* pLEOr = theOEOrigins.ChangeSeek(aEIm);
1198 pLEOr = theOEOrigins.Bound(aEIm, TopTools_ListOfShape());
1200 AppendToList(*pLEOr, aE);
1204 UpdateOrigins(aLA, theEdgesOrigins, aGFE);
1205 UpdateIntersectedEdges(aLA, theETrimEInf, aGFE);
1208 //=======================================================================
1209 //function : GetEdges
1210 //purpose : Getting edges from AsDes map to build the splits of faces
1211 //=======================================================================
1212 Standard_Boolean GetEdges(const TopoDS_Face& theFace,
1213 const Handle(BRepAlgo_AsDes)& theAsDes,
1214 const TopTools_DataMapOfShapeListOfShape& theEImages,
1215 const TopTools_MapOfShape& theLastInvEdges,
1216 const TopTools_IndexedMapOfShape& theInvEdges,
1217 Handle(IntTools_Context)& theCtx,
1218 const TopTools_MapOfShape& theModifiedEdges,
1219 TopoDS_Shape& theEdges,
1220 TopTools_IndexedMapOfShape& theInv)
1222 // get boundary edges
1223 TopTools_MapOfShape aMFBounds;
1224 TopExp_Explorer aExp(theFace, TopAbs_EDGE);
1225 for (; aExp.More(); aExp.Next()) {
1226 const TopoDS_Shape& aE = aExp.Current();
1227 const TopTools_ListOfShape* pLEIm = theEImages.Seek(aE);
1232 TopTools_ListIteratorOfListOfShape aItLE(*pLEIm);
1233 for (; aItLE.More(); aItLE.Next()) {
1234 const TopoDS_Shape& aEIm = aItLE.Value();
1235 aMFBounds.Add(aEIm);
1241 Standard_Boolean bFound(Standard_False), bUpdate(Standard_False);
1242 // the resulting edges
1243 TopoDS_Compound anEdges;
1244 aBB.MakeCompound(anEdges);
1246 // the edges by which the offset face should be split
1247 const TopTools_ListOfShape& aLE = theAsDes->Descendant(theFace);
1248 TopTools_ListIteratorOfListOfShape aItLE(aLE);
1249 for (; aItLE.More(); aItLE.Next()) {
1250 const TopoDS_Edge& aE = TopoDS::Edge(aItLE.Value());
1253 bUpdate = theModifiedEdges.Contains(aE);
1256 const TopTools_ListOfShape* pLEIm = theEImages.Seek(aE);
1258 TopTools_ListIteratorOfListOfShape aItLEIm(*pLEIm);
1259 for (; aItLEIm.More(); aItLEIm.Next()) {
1260 const TopoDS_Edge& aEIm = TopoDS::Edge(aItLEIm.Value());
1262 if (theInvEdges.Contains(aEIm)) {
1265 bUpdate = theLastInvEdges.Contains(aEIm);
1269 // check for micro edge
1270 if (ProcessMicroEdge(aEIm, theCtx)) {
1274 aBB.Add(anEdges, aEIm);
1276 bFound = !aMFBounds.Contains(aEIm);
1280 bUpdate = theModifiedEdges.Contains(aEIm);
1285 if (theInvEdges.Contains(aE)) {
1288 bUpdate = theLastInvEdges.Contains(aE);
1293 if (ProcessMicroEdge(aE, theCtx)) {
1296 aBB.Add(anEdges, aE);
1298 bFound = !aMFBounds.Contains(aE);
1304 return bFound && bUpdate;
1307 //=======================================================================
1308 //function : BuildSplitsOfFace
1309 //purpose : Building the splits of offset face
1310 //=======================================================================
1311 void BuildSplitsOfFace(const TopoDS_Face& theFace,
1312 const TopoDS_Shape& theEdges,
1313 TopTools_DataMapOfShapeShape& theFacesOrigins,
1314 TopTools_ListOfShape& theLFImages)
1316 theLFImages.Clear();
1318 // take edges to split the face
1319 BOPCol_ListOfShape aLE;
1320 TopExp_Explorer aExp(theEdges, TopAbs_EDGE);
1321 for (; aExp.More(); aExp.Next()) {
1322 TopoDS_Edge aE = TopoDS::Edge(aExp.Current());
1323 aE.Orientation(TopAbs_FORWARD);
1325 aE.Orientation(TopAbs_REVERSED);
1329 TopoDS_Face aFF = theFace;
1330 TopAbs_Orientation anOr = theFace.Orientation();
1331 aFF.Orientation(TopAbs_FORWARD);
1333 // build pcurves for edges on the face
1334 BOPTools_AlgoTools2D::BuildPCurveForEdgesOnPlane(aLE, aFF);
1336 // build splits of faces
1337 BOPAlgo_BuilderFace aBF;
1342 const BOPCol_ListOfShape& aLFSp = aBF.Areas();
1343 BOPCol_ListIteratorOfListOfShape aItLF(aLFSp);
1344 for (; aItLF.More(); aItLF.Next()) {
1345 TopoDS_Shape& aFSp = aItLF.ChangeValue();
1346 aFSp.Orientation(anOr);
1347 theLFImages.Append(aFSp);
1349 theFacesOrigins.Bind(aFSp, theFace);
1353 //=======================================================================
1354 //function : BuildSplitsOfFace
1355 //purpose : Building the splits of offset face
1356 //=======================================================================
1357 void BuildSplitsOfTrimmedFace(const TopoDS_Face& theFace,
1358 const TopoDS_Shape& theEdges,
1359 TopTools_ListOfShape& theLFImages)
1361 BOPAlgo_Builder aGF;
1363 aGF.AddArgument(theFace);
1364 aGF.AddArgument(theEdges);
1366 if (aGF.ErrorStatus()) {
1370 // splits of the offset shape
1371 theLFImages = aGF.Modified(theFace);
1374 //=======================================================================
1375 //function : CheckIfArtificial
1376 //purpose : Checks if the face is artificially invalid
1377 //=======================================================================
1378 Standard_Boolean CheckIfArtificial(const TopoDS_Shape& theF,
1379 const TopTools_ListOfShape& theLFImages,
1380 const TopoDS_Shape& theCE,
1381 const TopTools_IndexedMapOfShape& theMapEInv,
1382 const TopTools_DataMapOfShapeListOfShape& theOEImages,
1383 TopTools_MapOfShape& theMENInv,
1384 Handle(BRepAlgo_AsDes)& theAsDes)
1386 // all boundary edges should be used
1387 TopTools_IndexedMapOfShape aMEUsed;
1388 TopTools_ListIteratorOfListOfShape aItLFIm(theLFImages);
1389 for (; aItLFIm.More(); aItLFIm.Next()) {
1390 const TopoDS_Shape& aFIm = aItLFIm.Value();
1391 TopExp::MapShapes(aFIm, TopAbs_EDGE, aMEUsed);
1392 TopExp::MapShapes(aFIm, TopAbs_VERTEX, aMEUsed);
1395 TopTools_IndexedDataMapOfShapeListOfShape aMVE;
1396 TopExp::MapShapesAndAncestors(theCE, TopAbs_VERTEX, TopAbs_EDGE, aMVE);
1398 Standard_Integer i, aNb = theMapEInv.Extent();
1399 for (i = 1; i <= aNb; ++i) {
1400 const TopoDS_Shape& aEInv = theMapEInv(i);
1401 TopExp_Explorer aExpV(aEInv, TopAbs_VERTEX);
1402 for (; aExpV.More(); aExpV.Next()) {
1403 const TopoDS_Shape& aVEInv = aExpV.Current();
1404 const TopTools_ListOfShape* pLENInv = aMVE.Seek(aVEInv);
1406 TopTools_ListIteratorOfListOfShape aItLEInv(*pLENInv);
1407 for (; aItLEInv.More(); aItLEInv.Next()) {
1408 const TopoDS_Shape& aENInv = aItLEInv.Value();
1409 if (!aMEUsed.Contains(aENInv)) {
1410 theMENInv.Add(aENInv);
1417 if (theMENInv.IsEmpty()) {
1418 return Standard_False;
1421 TopTools_IndexedMapOfShape aMEFound;
1422 TopExp::MapShapes(theCE, TopAbs_EDGE, aMEFound);
1424 const TopTools_ListOfShape& aLE = theAsDes->Descendant(theF);
1425 TopTools_ListIteratorOfListOfShape aItLE(aLE);
1426 for (; aItLE.More(); aItLE.Next()) {
1427 const TopoDS_Edge& aE = TopoDS::Edge(aItLE.Value());
1429 if (theOEImages.IsBound(aE)) {
1430 Standard_Boolean bChecked = Standard_False;
1431 const TopTools_ListOfShape& aLEIm = theOEImages.Find(aE);
1432 TopTools_ListIteratorOfListOfShape aItLEIm(aLEIm);
1433 for (; aItLEIm.More(); aItLEIm.Next()) {
1434 const TopoDS_Edge& aEIm = TopoDS::Edge(aItLEIm.Value());
1435 if (!aMEFound.Contains(aEIm) || theMENInv.Contains(aEIm)) {
1439 bChecked = Standard_True;
1440 if (aMEUsed.Contains(aEIm)) {
1445 if (bChecked && !aItLEIm.More()) {
1450 if (aMEFound.Contains(aE) && !theMENInv.Contains(aE) && !aMEUsed.Contains(aE)) {
1456 return aItLE.More();
1459 //=======================================================================
1460 //function : FindInvalidEdges
1461 //purpose : Looking for the invalid edges
1462 //=======================================================================
1463 void FindInvalidEdges(const TopoDS_Face& theF,
1464 const TopTools_ListOfShape& theLFImages,
1465 const TopTools_DataMapOfShapeListOfShape& theEdgesOrigins,
1466 const TopTools_DataMapOfShapeShape& theFacesOrigins,
1467 const TopTools_DataMapOfShapeListOfShape& theOEImages,
1468 const TopTools_DataMapOfShapeListOfShape& theOEOrigins,
1469 TopTools_IndexedMapOfShape& theInvEdges,
1470 TopTools_IndexedMapOfShape& theValidEdges,
1471 TopTools_DataMapOfShapeListOfShape& theDMFLVE,
1472 TopTools_DataMapOfShapeListOfShape& theDMFLNE,
1473 TopTools_DataMapOfShapeListOfShape& theDMFLIE,
1474 TopTools_DataMapOfShapeListOfShape& theDMFLVIE,
1475 TopTools_DataMapOfShapeListOfShape& theDMEOrLEIm,
1476 TopTools_MapOfShape& theMEInverted,
1477 TopTools_MapOfShape& theEdgesInvalidByVertex)
1479 // Edge is considered as invalid in the following cases:
1480 // 1. Its orientation on the face has changed comparing to the originals edge and face;
1481 // 2. The vertices of the edge have changed places comparing to the originals edge and face.
1483 // The edges created from vertices, i.e. as intersection between two faces connected only
1484 // by VERTEX, will also be checked on validity. For these edges the correct orientation will
1485 // be defined by the edges on the original face adjacent to the connection vertex
1488 const TopoDS_Face& aFOr = *(TopoDS_Face*)&theFacesOrigins.Find(theF);
1490 TopTools_IndexedMapOfShape aMEInv;
1492 TopTools_MapOfShape aMEVal;
1494 TopTools_MapOfShape aMEInt;
1496 // maps for checking the inverted edges
1497 TopTools_IndexedDataMapOfShapeListOfShape aDMVE, aDMEF;
1498 TopTools_IndexedMapOfShape aMEdges;
1500 TopTools_ListIteratorOfListOfShape aItLF(theLFImages);
1501 for (; aItLF.More(); aItLF.Next()) {
1502 const TopoDS_Face& aFIm = *(TopoDS_Face*)&aItLF.Value();
1504 TopExp_Explorer aExp(aFIm, TopAbs_EDGE);
1505 for (; aExp.More(); aExp.Next()) {
1506 const TopoDS_Shape& aE = aExp.Current();
1510 // keep connection from edges to faces
1511 TopTools_ListOfShape* pLF = aDMEF.ChangeSeek(aE);
1513 pLF = &aDMEF(aDMEF.Add(aE, TopTools_ListOfShape()));
1515 AppendToList(*pLF, aFIm);
1517 // keep connection from vertices to edges
1518 TopoDS_Iterator aItV(aE);
1519 for (; aItV.More(); aItV.Next()) {
1520 const TopoDS_Shape& aV = aItV.Value();
1522 TopTools_ListOfShape* pLE = aDMVE.ChangeSeek(aV);
1524 pLE = &aDMVE(aDMVE.Add(aV, TopTools_ListOfShape()));
1526 AppendToList(*pLE, aE);
1531 // the map will be used to find the edges on the original face
1532 // adjacent to the same vertex. It will be filled at first necessity;
1533 TopTools_IndexedDataMapOfShapeListOfShape aDMVEFOr;
1535 aItLF.Initialize(theLFImages);
1536 for (; aItLF.More(); aItLF.Next()) {
1537 const TopoDS_Face& aFIm = *(TopoDS_Face*)&aItLF.Value();
1539 // valid edges for this split
1540 TopTools_ListOfShape aLVE;
1541 // invalid edges for this split
1542 TopTools_ListOfShape aLIE;
1544 TopExp_Explorer aExp(aFIm, TopAbs_EDGE);
1545 for (; aExp.More(); aExp.Next()) {
1546 const TopoDS_Edge& aEIm = *(TopoDS_Edge*)&aExp.Current();
1548 if (aEIm.Orientation() == TopAbs_INTERNAL) {
1553 if (!theEdgesOrigins.IsBound(aEIm)) {
1557 const TopTools_ListOfShape& aLEOr = theEdgesOrigins.Find(aEIm);
1558 if (aLEOr.IsEmpty()) {
1562 Standard_Integer aNbVOr = 0;
1563 TopTools_ListIteratorOfListOfShape aItLEO(aLEOr);
1564 for (; aItLEO.More(); aItLEO.Next()) {
1565 if (aItLEO.Value().ShapeType() == TopAbs_VERTEX) {
1570 TopTools_MapOfShape aME, aMV;
1571 Standard_Boolean bInvalid = Standard_False, bChecked = Standard_False;
1572 Standard_Integer aNbP = NbPoints(aEIm);
1573 Standard_Boolean bUseVertex = !aNbVOr ? Standard_False :
1575 aDMEF.FindFromKey(aEIm).Extent() == 1 &&
1576 !theOEOrigins.IsBound(aEIm));
1578 aItLEO.Initialize(aLEOr);
1579 for (; aItLEO.More(); aItLEO.Next()) {
1580 const TopoDS_Shape& aSOr = aItLEO.Value();
1581 Standard_Boolean bVertex = (aSOr.ShapeType() == TopAbs_VERTEX);
1585 // for some cases it is impossible to check the validity of the edge
1589 // find edges on the original face adjacent to this vertex
1590 if (aDMVEFOr.IsEmpty()) {
1592 TopExp::MapShapesAndAncestors(aFOr, TopAbs_VERTEX, TopAbs_EDGE, aDMVEFOr);
1595 TopTools_ListOfShape *pLEFOr = aDMVEFOr.ChangeSeek(aSOr);
1597 TopoDS_Compound aCEOr;
1598 BRep_Builder().MakeCompound(aCEOr);
1599 TopTools_ListIteratorOfListOfShape aItLEFOr(*pLEFOr);
1600 for (; aItLEFOr.More(); aItLEFOr.Next()) {
1601 const TopoDS_Shape& aEOr = aItLEFOr.Value();
1602 BRep_Builder().Add(aCEOr, aEOr);
1608 FindShape(aSOr, aFOr, aEOrF);
1610 TopTools_ListOfShape *pLEIm = theDMEOrLEIm.ChangeSeek(aSOr);
1612 pLEIm = theDMEOrLEIm.Bound(aSOr, TopTools_ListOfShape());
1614 AppendToList(*pLEIm, aEIm);
1617 if (aEOrF.IsNull()) {
1618 // the edge has not been found
1622 // Check orientations of the image edge and original edge.
1623 // In case the 3d curves are having the same direction the orientations
1624 // must be the same. Otherwise the orientations should also be different.
1626 // get average tangent vector for each curve taking into account
1627 // the orientations of the edges, i.e. the edge is reversed
1628 // the vector is reversed as well
1629 gp_Vec aVSum1 = GetAverageTangent(aEIm, aNbP);
1630 gp_Vec aVSum2 = GetAverageTangent(aEOrF, aNbP);
1635 Standard_Real aCos = aVSum1.Dot(aVSum2);
1637 if (Abs(aCos) < 0.9999) {
1642 TopExp_Explorer aExpE(aEOrF, TopAbs_VERTEX);
1643 for (; aExpE.More(); aExpE.Next()) {
1644 const TopoDS_Shape& aV = aExpE.Current();
1649 if (aCos < Precision::Confusion()) {
1650 bInvalid = Standard_True;
1652 theEdgesInvalidByVertex.Add(aEIm);
1655 bChecked = Standard_True;
1662 Standard_Integer aNbE = aME.Extent(), aNbV = aMV.Extent();
1663 if ((aNbE > 1) && (aNbV == 2*aNbE)) {
1668 theInvEdges.Add(aEIm);
1674 // check if the edge has been inverted
1675 Standard_Boolean bInverted = !aNbE ? Standard_False :
1676 CheckInverted(aEIm, aFOr, theOEImages, theOEOrigins,
1677 theEdgesOrigins, aDMVE, aMEdges, theMEInverted);
1679 if (!bInverted || !aNbVOr) {
1680 theValidEdges.Add(aEIm);
1687 if (aLVE.Extent()) {
1688 theDMFLVE.Bind(aFIm, aLVE);
1692 if (aLIE.Extent()) {
1693 theDMFLIE.Bind(aFIm, aLIE);
1697 // process invalid edges:
1698 // check for the inverted edges
1699 TopTools_ListOfShape aLVIE;
1700 // fill neutral edges
1701 TopTools_ListOfShape aLNE;
1703 Standard_Integer i, aNbEInv = aMEInv.Extent();
1704 for (i = 1; i <= aNbEInv; ++i) {
1705 const TopoDS_Shape& aEIm = aMEInv(i);
1707 // neutral edges - on the splits of the same offset face
1708 // it is valid for one split and invalid for other
1709 if (aMEVal.Contains(aEIm)) {
1714 // the inverted images of the origins of invalid edges should also be invalid
1715 if (!theMEInverted.Contains(aEIm)) {
1719 const TopTools_ListOfShape* pLOEOr = theOEOrigins.Seek(aEIm);
1724 TopTools_ListIteratorOfListOfShape aItLOEOr(*pLOEOr);
1725 for (; aItLOEOr.More(); aItLOEOr.Next()) {
1726 const TopoDS_Shape& aOEOr = aItLOEOr.Value();
1727 const TopTools_ListOfShape& aLEIm1 = theOEImages.Find(aOEOr);
1729 TopTools_ListIteratorOfListOfShape aItLEIm1(aLEIm1);
1730 for (; aItLEIm1.More(); aItLEIm1.Next()) {
1731 const TopoDS_Shape& aEIm1 = aItLEIm1.Value();
1732 if (aMEdges.Contains(aEIm1) &&
1733 !aMEInv.Contains(aEIm1) && !aMEInt.Contains(aEIm1) &&
1734 theMEInverted.Contains(aEIm1)) {
1735 theInvEdges.Add(aEIm1);
1736 aLVIE.Append(aEIm1);
1742 if (aLNE.Extent()) {
1743 theDMFLNE.Bind(theF, aLNE);
1746 if (aLVIE.Extent()) {
1747 theDMFLVIE.Bind(theF, aLVIE);
1751 //=======================================================================
1752 //function : FindInvalidFaces
1753 //purpose : Looking for the invalid faces by analyzing their invalid edges
1754 //=======================================================================
1755 void FindInvalidFaces(TopTools_ListOfShape& theLFImages,
1756 const TopTools_IndexedMapOfShape& theInvEdges,
1757 const TopTools_IndexedMapOfShape& theValidEdges,
1758 const TopTools_DataMapOfShapeListOfShape& theDMFLVE,
1759 const TopTools_DataMapOfShapeListOfShape& theDMFLIE,
1760 const TopTools_ListOfShape& theLENeutral,
1761 const TopTools_ListOfShape& theLEValInverted,
1762 const TopTools_MapOfShape& theMEInverted,
1763 const TopTools_MapOfShape& theEdgesInvalidByVertex,
1764 const TopTools_MapOfShape& theMFHoles,
1765 TopTools_IndexedMapOfShape& theMFInvInHole,
1766 TopTools_ListOfShape& theInvFaces)
1768 // The face should be considered as invalid in the following cases:
1769 // 1. It has been reverted, i.e. at least two not connected edges
1770 // have changed orientation (i.e. invalid). In this case all edges,
1771 // should be invalid for that face, because edges have also been reverted;
1772 // 2. All checked edges of the face are invalid for this face;
1773 // The face should be removed from the splits in the following cases:
1774 // 1. All checked edges of the face are invalid for this one, but valid for
1775 // some other face in this list of splits.
1776 // The face will be kept in the following cases:
1777 // 1. Some of the edges are valid for this face.
1778 Standard_Boolean bHasValid, bAllValid, bAllInvalid, bHasReallyInvalid, bAllInvNeutral;
1779 Standard_Boolean bValid, bValidLoc, bInvalid, bInvalidLoc, bNeutral;
1780 Standard_Integer i, aNbChecked;
1783 TopTools_MapOfShape aMEN;
1784 for (TopTools_ListIteratorOfListOfShape aItLE(theLENeutral); aItLE.More(); aItLE.Next())
1786 aMEN.Add(aItLE.Value());
1789 // valid inverted edges
1790 TopTools_MapOfShape aMEValInverted;
1791 for (TopTools_ListIteratorOfListOfShape aItLE(theLEValInverted); aItLE.More(); aItLE.Next())
1793 aMEValInverted.Add(aItLE.Value());
1796 Standard_Boolean bCheckInverted = (theLFImages.Extent() == 1);
1798 // neutral edges to remove
1799 TopTools_IndexedMapOfShape aMENRem;
1801 // faces for post treat
1802 TopTools_ListOfShape aLFPT;
1804 TopTools_ListIteratorOfListOfShape aItLF(theLFImages);
1805 for (; aItLF.More(); ) {
1806 const TopoDS_Face& aFIm = *(TopoDS_Face*)&aItLF.Value();
1808 // valid edges for this split
1809 TopTools_MapOfShape aMVE;
1810 // invalid edges for this split
1811 TopTools_MapOfShape aMIE;
1813 for (i = 0; i < 2; ++i) {
1814 TopTools_MapOfShape& aME = !i ? aMVE : aMIE;
1815 const TopTools_ListOfShape* pLE = !i ? theDMFLVE.Seek(aFIm) : theDMFLIE.Seek(aFIm);
1817 TopTools_ListIteratorOfListOfShape aItLE(*pLE);
1818 for (; aItLE.More(); aItLE.Next()) {
1819 const TopoDS_Shape& aE = aItLE.Value();
1825 bHasValid = Standard_False;
1826 bAllValid = Standard_True;
1827 bAllInvalid = Standard_True;
1828 bHasReallyInvalid = Standard_False;
1829 bAllInvNeutral = Standard_True;
1832 const TopoDS_Wire& aWIm = BRepTools::OuterWire(aFIm);
1833 TopExp_Explorer aExp(aWIm, TopAbs_EDGE);
1834 for (; aExp.More(); aExp.Next()) {
1835 const TopoDS_Shape& aEIm = aExp.Current();
1837 bValid = theValidEdges.Contains(aEIm);
1838 bInvalid = theInvEdges.Contains(aEIm);
1840 if (!bValid && !bInvalid) {
1841 // edge has not been checked for some reason
1847 bInvalidLoc = aMIE.Contains(aEIm);
1848 bHasReallyInvalid = bInvalidLoc && !bValid && !theEdgesInvalidByVertex.Contains(aEIm);
1849 if (bHasReallyInvalid) {
1853 bNeutral = aMEN.Contains(aEIm);
1854 bValidLoc = aMVE.Contains(aEIm);
1856 if (!bInvalid && bCheckInverted) {
1857 bInvalid = theMEInverted.Contains(aEIm);
1860 if (bValidLoc && (bNeutral || aMEValInverted.Contains(aEIm))) {
1861 bHasValid = Standard_True;
1864 bAllValid = bAllValid && bValidLoc;
1865 bAllInvalid = bAllInvalid && bInvalid;
1866 bAllInvNeutral = bAllInvNeutral && bAllInvalid && bNeutral;
1874 if (!bHasReallyInvalid && (bAllInvNeutral && !bHasValid) && (aNbChecked > 1)) {
1875 // remove edges from neutral
1876 TopExp::MapShapes(aFIm, TopAbs_EDGE, aMENRem);
1878 theLFImages.Remove(aItLF);
1882 if (bHasReallyInvalid || (bAllInvalid &&
1883 !(bHasValid || bAllValid) &&
1884 !(bAllInvNeutral && (aNbChecked == 1)))) {
1885 theInvFaces.Append(aFIm);
1886 if (theMFHoles.Contains(aFIm)) {
1887 theMFInvInHole.Add(aFIm);
1893 if (theMFHoles.Contains(aFIm)) {
1894 // remove edges from neutral
1895 TopExp::MapShapes(aFIm, TopAbs_EDGE, aMENRem);
1897 theLFImages.Remove(aItLF);
1901 if (!bAllInvNeutral) {
1905 // remove edges from neutral
1906 TopExp::MapShapes(aFIm, TopAbs_EDGE, aMENRem);
1911 if (aLFPT.IsEmpty() || aMENRem.IsEmpty()) {
1915 Standard_Integer aNb = aMENRem.Extent();
1916 for (i = 1; i <= aNb; ++i) {
1917 aMEN.Remove(aMENRem(i));
1920 // check the splits once more
1921 aItLF.Initialize(aLFPT);
1922 for (; aItLF.More(); aItLF.Next()) {
1923 const TopoDS_Face& aFIm = *(TopoDS_Face*)&aItLF.Value();
1925 // valid edges for this split
1926 TopTools_MapOfShape aMVE;
1927 const TopTools_ListOfShape* pLVE = theDMFLVE.Seek(aFIm);
1929 TopTools_ListIteratorOfListOfShape aItLE(*pLVE);
1930 for (; aItLE.More(); aItLE.Next()) {
1931 const TopoDS_Shape& aE = aItLE.Value();
1936 bHasValid = Standard_False;
1937 bAllValid = Standard_True;
1938 bAllInvalid = Standard_True;
1940 const TopoDS_Wire& aWIm = BRepTools::OuterWire(aFIm);
1941 TopExp_Explorer aExp(aWIm, TopAbs_EDGE);
1942 for (; aExp.More(); aExp.Next()) {
1943 const TopoDS_Shape& aEIm = aExp.Current();
1945 bValid = theValidEdges.Contains(aEIm);
1946 bInvalid = theInvEdges.Contains(aEIm);
1947 bNeutral = aMEN.Contains(aEIm);
1948 bValidLoc = aMVE.Contains(aEIm);
1950 if (!bInvalid && bCheckInverted) {
1951 bInvalid = theMEInverted.Contains(aEIm);
1954 if (bValidLoc && (bNeutral || aMEValInverted.Contains(aEIm))) {
1955 bHasValid = Standard_True;
1958 bAllValid = bAllValid && bValidLoc;
1959 bAllInvalid = bAllInvalid && bInvalid;
1962 if (bAllInvalid && !bHasValid && !bAllValid) {
1963 theInvFaces.Append(aFIm);
1968 //=======================================================================
1969 //function : FindFacesInsideHoleWires
1970 //purpose : Find faces inside holes wires from the original face
1971 //=======================================================================
1972 void FindFacesInsideHoleWires(const TopoDS_Face& theFOrigin,
1973 const TopoDS_Face& theFOffset,
1974 const TopTools_ListOfShape& theLFImages,
1975 const TopTools_MapOfShape& theInvertedEdges,
1976 const TopTools_DataMapOfShapeListOfShape& theDMEOrLEIm,
1977 TopTools_MapOfShape& theMFHoles,
1978 TopTools_DataMapOfShapeListOfShape& theDMFNewHoles,
1979 Handle(IntTools_Context)& theContext)
1981 if (theLFImages.IsEmpty()) {
1985 // find all hole wires in the original face
1986 TopTools_ListOfShape aLHoleWires;
1987 const TopoDS_Wire& anOuterWire = BRepTools::OuterWire(theFOrigin);
1988 TopExp_Explorer aExpW(theFOrigin, TopAbs_WIRE);
1989 for (; aExpW.More(); aExpW.Next()) {
1990 const TopoDS_Wire& aHoleWire = TopoDS::Wire(aExpW.Current());
1991 if (!aHoleWire.IsSame(anOuterWire) && aHoleWire.Orientation() != TopAbs_INTERNAL) {
1992 aLHoleWires.Append(aHoleWire);
1996 if (aLHoleWires.IsEmpty()) {
1997 // no holes in the face
2001 TopTools_ListOfShape *pLFNewHoles = theDMFNewHoles.ChangeSeek(theFOrigin);
2004 pLFNewHoles = theDMFNewHoles.Bound(theFOrigin, TopTools_ListOfShape());
2006 if (pLFNewHoles->IsEmpty()) {
2008 // find the faces representing holes in the images of the faces:
2009 // 1. for each original hole wire try to build its image
2010 // 2. build the new planar face from the images
2012 // map vertices and edges of the splits
2013 TopTools_IndexedMapOfShape aMESplits;
2014 TopTools_ListIteratorOfListOfShape aItLF(theLFImages);
2015 for (; aItLF.More(); aItLF.Next()) {
2016 TopExp::MapShapes(aItLF.Value(), TopAbs_EDGE, aMESplits);
2019 TopTools_ListIteratorOfListOfShape aItLW(aLHoleWires);
2020 for (; aItLW.More(); aItLW.Next()) {
2021 const TopoDS_Wire& aHoleWire = TopoDS::Wire(aItLW.Value());
2022 // find images of all edges of the original wire
2023 TopTools_IndexedMapOfShape aMEImWire;
2024 TopoDS_Iterator aItE(aHoleWire);
2025 for (; aItE.More(); aItE.Next()) {
2026 const TopoDS_Shape& aEOr = aItE.Value();
2027 const TopTools_ListOfShape *pLEIm = theDMEOrLEIm.Seek(aEOr);
2028 if (!pLEIm || pLEIm->IsEmpty()) {
2031 TopTools_ListIteratorOfListOfShape aItLEIm(*pLEIm);
2032 for (; aItLEIm.More(); aItLEIm.Next()) {
2033 const TopoDS_Shape& aEIm = aItLEIm.Value();
2034 if (aMESplits.Contains(aEIm)) {
2035 aMEImWire.Add(aEIm);
2040 if (aMEImWire.IsEmpty()) {
2044 // build new planar face using these edges
2045 BOPCol_ListOfShape aLE;
2046 Standard_Integer i, aNbE = aMEImWire.Extent();
2047 for (i = 1; i <= aNbE; ++i) {
2048 aLE.Append(aMEImWire(i).Oriented(TopAbs_FORWARD));
2049 aLE.Append(aMEImWire(i).Oriented(TopAbs_REVERSED));
2052 BOPAlgo_BuilderFace aBF;
2053 aBF.SetFace(TopoDS::Face(theFOffset.Oriented(TopAbs_FORWARD)));
2057 const BOPCol_ListOfShape& aLFNew = aBF.Areas();
2058 if (aLFNew.IsEmpty()) {
2062 // check if outer edges in the new faces are not inverted
2063 // because the inverted edges mean that the hole has been
2064 // filled during offset and there will be no faces to remove
2065 TopTools_IndexedDataMapOfShapeListOfShape aDMEFNew;
2066 TopTools_ListIteratorOfListOfShape aItLFNew(aLFNew);
2067 for (; aItLFNew.More(); aItLFNew.Next()) {
2068 TopExp::MapShapesAndAncestors(aItLFNew.Value(), TopAbs_EDGE, TopAbs_FACE, aDMEFNew);
2071 aNbE = aDMEFNew.Extent();
2072 for (i = 1; i <= aNbE; ++i) {
2073 if (aDMEFNew(i).Extent() == 1) {
2074 const TopoDS_Shape& aE = aDMEFNew.FindKey(i);
2075 if (theInvertedEdges.Contains(aE)) {
2085 aItLFNew.Initialize(aLFNew);
2086 for (; aItLFNew.More(); aItLFNew.Next()) {
2087 pLFNewHoles->Append(aItLFNew.Value());
2092 // among the splits of the offset face find those that are
2093 // located inside the hole faces
2095 TopTools_ListIteratorOfListOfShape aItLF(theLFImages);
2096 for (; aItLF.More(); aItLF.Next()) {
2097 const TopoDS_Face& aFIm = TopoDS::Face(aItLF.Value());
2099 // get the point inside the face and classify it relatively hole faces
2102 Standard_Integer iErr = BOPTools_AlgoTools3D::PointInFace(aFIm, aP3D, aP2D, theContext);
2107 Standard_Real aTol = BRep_Tool::Tolerance(aFIm);
2109 TopTools_ListIteratorOfListOfShape aItLFNew(*pLFNewHoles);
2110 for (; aItLFNew.More(); aItLFNew.Next()) {
2111 const TopoDS_Face& aFNew = TopoDS::Face(aItLFNew.Value());
2112 if (theContext->IsValidPointForFace(aP3D, aFNew, aTol)) {
2113 // the face is classified as IN
2114 theMFHoles.Add(aFIm);
2121 //=======================================================================
2122 //function : GetAverageTangent
2123 //purpose : Computes average tangent vector along the curve
2124 //=======================================================================
2125 gp_Vec GetAverageTangent(const TopoDS_Shape& theS,
2126 const Standard_Integer theNbP)
2129 TopExp_Explorer aExp(theS, TopAbs_EDGE);
2130 for (; aExp.More(); aExp.Next()) {
2131 const TopoDS_Edge& aE = *(TopoDS_Edge*)&aExp.Current();
2133 Standard_Real aT1, aT2;
2134 const Handle(Geom_Curve)& aC = BRep_Tool::Curve(aE, aT1, aT2);
2138 Standard_Real aT = aT1;
2139 Standard_Real aDt = (aT2 - aT1) / theNbP;
2142 aVSum += aV.Normalized();
2146 if (aE.Orientation() == TopAbs_REVERSED) {
2155 //=======================================================================
2156 //function : CheckInverted
2157 //purpose : Checks if the edge has been inverted
2158 //=======================================================================
2159 Standard_Boolean CheckInverted(const TopoDS_Edge& theEIm,
2160 const TopoDS_Face& theFOr,
2161 const TopTools_DataMapOfShapeListOfShape& theOEImages,
2162 const TopTools_DataMapOfShapeListOfShape& theOEOrigins,
2163 const TopTools_DataMapOfShapeListOfShape& theEdgesOrigins,
2164 const TopTools_IndexedDataMapOfShapeListOfShape& theDMVE,
2165 const TopTools_IndexedMapOfShape& theMEdges,
2166 TopTools_MapOfShape& theMEInverted)
2168 // It is necessary to compare the direction from first vertex
2169 // to the last vertex on the original edge with the
2170 // same direction on the new edge. If the directions
2171 // will be different - the edge has been inverted.
2173 TopoDS_Vertex aVI1, aVI2; // vertices on the offset edge
2174 TopoDS_Vertex aVO1, aVO2; // vertices on the original edge
2177 // find vertices of the offset shape
2178 TopExp::Vertices(theEIm, aVI1, aVI2);
2181 TopTools_ListOfShape aLEImages;
2182 if (theOEOrigins.IsBound(theEIm)) {
2183 TopoDS_Wire anImages;
2184 BRep_Builder().MakeWire(anImages);
2186 TopTools_MapOfShape aMImFence;
2187 const TopTools_ListOfShape& aLOffsetOr = theOEOrigins.Find(theEIm);
2188 TopTools_ListIteratorOfListOfShape aItOffset(aLOffsetOr);
2189 for (; aItOffset.More(); aItOffset.Next()) {
2190 const TopoDS_Shape& aEOffsetOr = aItOffset.Value();
2191 const TopTools_ListOfShape& aLImages = theOEImages.Find(aEOffsetOr);
2193 TopTools_ListIteratorOfListOfShape aItImages(aLImages);
2194 for (; aItImages.More(); aItImages.Next()) {
2195 const TopoDS_Edge& anIm = *(TopoDS_Edge*)&aItImages.Value();
2196 if (theMEdges.Contains(anIm) && aMImFence.Add(anIm)) {
2197 BRep_Builder().Add(anImages, anIm);
2198 aLEImages.Append(anIm);
2203 // find alone vertices
2204 TopoDS_Vertex aVW1, aVW2;
2205 TopTools_IndexedDataMapOfShapeListOfShape aDMImVE;
2206 TopExp::MapShapesAndAncestors(anImages, TopAbs_VERTEX, TopAbs_EDGE, aDMImVE);
2208 TopTools_ListOfShape aLVAlone;
2209 Standard_Integer aNb = aDMImVE.Extent();
2210 for (i = 1; i <= aNb; ++i) {
2211 const TopTools_ListOfShape& aLImE = aDMImVE(i);
2212 if (aLImE.Extent() == 1) {
2213 aLVAlone.Append(aDMImVE.FindKey(i));
2217 if (aLVAlone.Extent() > 1) {
2218 aVW1 = *(TopoDS_Vertex*)&aLVAlone.First();
2219 aVW2 = *(TopoDS_Vertex*)&aLVAlone.Last();
2222 const gp_Pnt& aPI1 = BRep_Tool::Pnt(aVI1);
2223 const gp_Pnt& aPW1 = BRep_Tool::Pnt(aVW1);
2224 const gp_Pnt& aPW2 = BRep_Tool::Pnt(aVW2);
2226 Standard_Real aDist1 = aPI1.SquareDistance(aPW1);
2227 Standard_Real aDist2 = aPI1.SquareDistance(aPW2);
2229 if (aDist1 < aDist2) {
2240 aLEImages.Append(theEIm);
2243 // Find edges connected to these vertices
2244 const TopTools_ListOfShape& aLIE1 = theDMVE.FindFromKey(aVI1);
2245 const TopTools_ListOfShape& aLIE2 = theDMVE.FindFromKey(aVI2);
2247 // Find vertices on the original face corresponding to vertices on the offset edge
2249 // find original edges for both lists
2250 TopTools_ListOfShape aLOE1, aLOE2;
2251 for (i = 0; i < 2; ++i) {
2252 const TopTools_ListOfShape& aLIE = !i ? aLIE1 : aLIE2;
2253 TopTools_ListOfShape& aLOE = !i ? aLOE1 : aLOE2;
2255 TopTools_MapOfShape aMFence;
2257 TopTools_ListIteratorOfListOfShape aItLIE(aLIE);
2258 for (; aItLIE.More(); aItLIE.Next()) {
2259 const TopoDS_Shape& aEI = aItLIE.Value();
2260 if (theEdgesOrigins.IsBound(aEI)) {
2261 const TopTools_ListOfShape& aLEOrigins = theEdgesOrigins.Find(aEI);
2263 TopTools_ListIteratorOfListOfShape aItLOE(aLEOrigins);
2264 for (; aItLOE.More(); aItLOE.Next()) {
2265 const TopoDS_Shape& aEO = aItLOE.Value();
2266 if (aEO.ShapeType() == TopAbs_EDGE && aMFence.Add(aEO)) {
2268 if (FindShape(aEO, theFOr, aEOin)) {
2269 AppendToList(aLOE, aEO);
2277 if (aLOE1.Extent() < 2 || aLOE2.Extent() < 2) {
2278 return Standard_False;
2281 // find vertices common for all edges in the lists
2282 for (i = 0; i < 2; ++i) {
2283 const TopTools_ListOfShape& aLOE = !i ? aLOE1 : aLOE2;
2284 TopoDS_Vertex& aVO = !i ? aVO1 : aVO2;
2286 const TopoDS_Shape& aEO = aLOE.First();
2287 TopExp_Explorer aExpV(aEO, TopAbs_VERTEX);
2288 for (; aExpV.More(); aExpV.Next()) {
2289 const TopoDS_Vertex& aV = *(TopoDS_Vertex*)&aExpV.Current();
2291 Standard_Boolean bVertValid = Standard_True;
2292 TopTools_ListIteratorOfListOfShape aItLOE(aLOE);
2293 for (aItLOE.Next(); aItLOE.More(); aItLOE.Next()) {
2294 const TopoDS_Shape& aEOx = aItLOE.Value();
2295 TopExp_Explorer aExpVx(aEOx, TopAbs_VERTEX);
2296 for (; aExpVx.More(); aExpVx.Next()) {
2297 const TopoDS_Shape& aVx = aExpVx.Current();
2298 if (aVx.IsSame(aV)) {
2303 if (!aExpVx.More()) {
2304 bVertValid = Standard_False;
2316 if (aVO1.IsNull() || aVO2.IsNull() || aVO1.IsSame(aVO2)) {
2317 return Standard_False;
2320 // check positions of the offset and original vertices
2321 const gp_Pnt& aPI1 = BRep_Tool::Pnt(aVI1);
2322 const gp_Pnt& aPI2 = BRep_Tool::Pnt(aVI2);
2323 const gp_Pnt& aPO1 = BRep_Tool::Pnt(aVO1);
2324 const gp_Pnt& aPO2 = BRep_Tool::Pnt(aVO2);
2326 gp_Vec aVI(aPI1, aPI2);
2327 gp_Vec aVO(aPO1, aPO2);
2329 Standard_Real anAngle = aVI.Angle(aVO);
2330 Standard_Boolean bInverted = Abs(anAngle - M_PI) < 1.e-4;
2332 TopTools_ListIteratorOfListOfShape aItLEIm(aLEImages);
2333 for (; aItLEIm.More(); aItLEIm.Next()) {
2334 const TopoDS_Shape& aEInvr = aItLEIm.Value();
2335 theMEInverted.Add(aEInvr);
2341 //=======================================================================
2342 //function : CheckInvertedBlock
2343 //purpose : Checks if it is possible to remove the block containing
2345 //=======================================================================
2346 Standard_Boolean CheckInvertedBlock(const TopoDS_Shape& theCB,
2347 const TopTools_ListOfShape& theLCBF,
2348 const TopTools_MapOfShape& theMEInverted,
2349 const TopTools_DataMapOfShapeListOfShape& theOEOrigins,
2350 BRepOffset_DataMapOfShapeMapOfShape& theDMCBVInverted,
2351 BRepOffset_DataMapOfShapeMapOfShape& theDMCBVAll)
2353 // For possible removal of the block:
2354 // 1. There should be more than just one face in the block
2355 TopoDS_Iterator aItF(theCB);
2358 return Standard_False;
2361 // 2. The block should at least contain two connected inverted edges with
2362 // different origins (not just two images/splits of the same edge)
2363 TopTools_MapOfShape aMECBInv;
2364 TopoDS_Compound aCECBInv;
2365 BRep_Builder().MakeCompound(aCECBInv);
2367 TopExp_Explorer aExp(theCB, TopAbs_EDGE);
2368 for (; aExp.More(); aExp.Next()) {
2369 const TopoDS_Shape& aE = aExp.Current();
2370 if (theMEInverted.Contains(aE)) {
2371 if (aMECBInv.Add(aE)) {
2372 BRep_Builder().Add(aCECBInv, aE);
2377 if (aMECBInv.Extent() < 2) {
2378 return Standard_False;
2381 // check that the edges are connected and different
2382 TopTools_ListOfShape aLCBE;
2383 BOPTools_AlgoTools::MakeConnexityBlocks(aCECBInv, TopAbs_VERTEX, TopAbs_EDGE, aLCBE);
2385 TopTools_ListIteratorOfListOfShape aItLCBE(aLCBE);
2386 for (; aItLCBE.More(); aItLCBE.Next()) {
2387 const TopoDS_Shape& aCBE = aItLCBE.Value();
2388 // count the unique edges in the block
2389 Standard_Integer aNbUnique = 0;
2390 TopTools_MapOfShape aMEOrigins;
2391 TopoDS_Iterator aItE(aCBE);
2392 for (; aItE.More(); aItE.Next()) {
2393 const TopoDS_Shape& aE = aItE.Value();
2394 const TopTools_ListOfShape *pLEOr = theOEOrigins.Seek(aE);
2400 TopTools_ListIteratorOfListOfShape aItLEOr(*pLEOr);
2401 for (; aItLEOr.More(); aItLEOr.Next()) {
2402 const TopoDS_Shape& aEOr = aItLEOr.Value();
2403 if (aMEOrigins.Add(aEOr)) {
2409 if (aNbUnique >= 2) {
2414 if (!aItLCBE.More()) {
2415 return Standard_False;
2418 // 3. the block should not contain inverted edges which vertices
2419 // are contained in other blocks
2421 // collect vertices from inverted edges and compare them with
2422 // vertices from other blocks
2423 TopTools_MapOfShape* pMVInverted = theDMCBVInverted.ChangeSeek(theCB);
2424 TopTools_MapOfShape* pMVAll = theDMCBVAll.ChangeSeek(theCB);
2426 pMVInverted = theDMCBVInverted.Bound(theCB, TopTools_MapOfShape());
2427 pMVAll = theDMCBVAll.Bound(theCB, TopTools_MapOfShape());
2429 GetVerticesOnEdges(theCB, theMEInverted, *pMVInverted, *pMVAll);
2432 TopTools_ListIteratorOfListOfShape aItLCB1(theLCBF);
2433 for (; aItLCB1.More(); aItLCB1.Next()) {
2434 const TopoDS_Shape& aCB1 = aItLCB1.Value();
2435 if (aCB1.IsSame(theCB)) {
2439 // collect vertices from inverted edges
2440 TopTools_MapOfShape* pMVInverted1 = theDMCBVInverted.ChangeSeek(aCB1);
2441 TopTools_MapOfShape* pMVAll1 = theDMCBVAll.ChangeSeek(aCB1);
2442 if (!pMVInverted1) {
2443 pMVInverted1 = theDMCBVInverted.Bound(aCB1, TopTools_MapOfShape());
2444 pMVAll1 = theDMCBVAll.Bound(aCB1, TopTools_MapOfShape());
2446 GetVerticesOnEdges(aCB1, theMEInverted, *pMVInverted1, *pMVAll1);
2449 if (pMVInverted->HasIntersection(*pMVAll1)) {
2450 return Standard_False;
2454 return Standard_True;
2457 //=======================================================================
2458 //function : GetVerticesOnEdges
2459 //purpose : Get vertices from the given shape belonging to the given edges
2460 //=======================================================================
2461 void GetVerticesOnEdges(const TopoDS_Shape& theCB,
2462 const TopTools_MapOfShape& theEdges,
2463 TopTools_MapOfShape& theVerticesOnEdges,
2464 TopTools_MapOfShape& theAllVertices)
2466 TopExp_Explorer aExp(theCB, TopAbs_EDGE);
2467 for (; aExp.More(); aExp.Next()) {
2468 const TopoDS_Shape& aE = aExp.Current();
2469 Standard_Boolean bOnGivenEdge = theEdges.Contains(aE);
2470 for (TopoDS_Iterator aItV(aE); aItV.More(); aItV.Next()) {
2471 theAllVertices.Add(aItV.Value());
2473 theVerticesOnEdges.Add(aItV.Value());
2479 //=======================================================================
2480 //function : RemoveInvalidSplitsByInvertedEdges
2481 //purpose : Looking for the invalid faces containing inverted edges
2482 // that can be safely removed
2483 //=======================================================================
2484 void RemoveInvalidSplitsByInvertedEdges(const TopTools_MapOfShape& theMEInverted,
2485 const TopTools_DataMapOfShapeListOfShape& theOEOrigins,
2486 TopTools_IndexedDataMapOfShapeListOfShape& theInvFaces,
2487 TopTools_IndexedDataMapOfShapeListOfShape& theFImages,
2488 TopTools_IndexedMapOfShape& theMERemoved)
2490 if (theMEInverted.IsEmpty()) {
2494 // check the faces on regularity, i.e. the splits of the same face
2495 // should not be connected only by vertex. Such irregular splits
2496 // will have to be rebuilt and cannot be removed.
2499 TopTools_IndexedMapOfShape aMEAvoid;
2500 TopTools_DataMapOfShapeListOfShape aDMVF;
2501 Standard_Integer aNb = theFImages.Extent(), i;
2502 for (i = 1; i <= aNb; ++i) {
2503 const TopTools_ListOfShape& aLFIm = theFImages(i);
2505 TopoDS_Compound aCFIm;
2506 aBB.MakeCompound(aCFIm);
2508 TopTools_DataMapOfShapeListOfShape aDMEF;
2509 TopTools_ListIteratorOfListOfShape aIt(aLFIm);
2510 for (; aIt.More(); aIt.Next()) {
2511 const TopoDS_Shape& aF = aIt.Value();
2514 // make a map to use only outer edges
2515 TopExp_Explorer aExp(aF, TopAbs_EDGE);
2516 for (; aExp.More(); aExp.Next()) {
2517 const TopoDS_Shape& aE = aExp.Current();
2519 TopTools_ListOfShape *pLF = aDMEF.ChangeSeek(aE);
2521 pLF = aDMEF.Bound(aE, TopTools_ListOfShape());
2524 // internal edges should not be used
2527 AppendToList(*pLF, aF);
2530 // fill connection map of the vertices of inverted edges to faces
2531 aExp.Init(aF, TopAbs_VERTEX);
2532 for (; aExp.More(); aExp.Next()) {
2533 const TopoDS_Shape& aV = aExp.Current();
2535 TopTools_ListOfShape *pLF = aDMVF.ChangeSeek(aV);
2537 pLF = aDMVF.Bound(aV, TopTools_ListOfShape());
2539 AppendToList(*pLF, aF);
2543 // for the splits to be regular they should form only one block
2544 TopTools_ListOfShape aLCBF;
2545 BOPTools_AlgoTools::MakeConnexityBlocks(aCFIm, TopAbs_EDGE, TopAbs_FACE, aLCBF);
2546 if (aLCBF.Extent() == 1) {
2550 // check if the inverted edges create the irregularity
2551 BRepOffset_DataMapOfShapeMapOfShape aDMCBVInverted, aDMCBVAll;
2553 TopTools_ListIteratorOfListOfShape aItLCB(aLCBF);
2554 for (; aItLCB.More(); aItLCB.Next()) {
2555 const TopoDS_Shape& aCB = aItLCB.Value();
2557 // check if it is possible to remove the block
2558 if (!CheckInvertedBlock(aCB, aLCBF, theMEInverted, theOEOrigins, aDMCBVInverted, aDMCBVAll)) {
2559 // non of the edges in this block should be removed
2560 TopExp::MapShapes(aCB, TopAbs_EDGE, aMEAvoid);
2566 // all edges not included in aMEAvoid can be removed
2567 TopTools_MapOfShape aMERem;
2568 TopTools_MapIteratorOfMapOfShape aItM(theMEInverted);
2569 for (; aItM.More(); aItM.Next()) {
2570 const TopoDS_Shape& aE = aItM.Value();
2571 if (!aMEAvoid.Contains(aE)) {
2572 TopoDS_Iterator aIt(aE);
2573 for (; aIt.More(); aIt.Next()) {
2574 const TopoDS_Shape& aV = aIt.Value();
2575 const TopTools_ListOfShape *pLF = aDMVF.Seek(aV);
2576 if (pLF && (pLF->Extent() > 3)) {
2584 if (aMERem.IsEmpty()) {
2588 // all invalid faces containing these edges can be removed
2589 TopTools_IndexedDataMapOfShapeListOfShape aInvFaces;
2590 TopTools_MapOfShape aMFRem;
2591 TopTools_IndexedMapOfShape aMFToUpdate;
2592 aNb = theInvFaces.Extent();
2593 for (i = 1; i <= aNb; ++i) {
2594 const TopoDS_Shape& aF = theInvFaces.FindKey(i);
2595 TopTools_ListOfShape& aLFIm = theInvFaces(i);
2597 TopTools_ListIteratorOfListOfShape aIt(aLFIm);
2598 for (; aIt.More(); ) {
2599 const TopoDS_Shape& aFIm = aIt.Value();
2601 // to be removed the face should have at least two not connected
2603 TopoDS_Compound aCEInv;
2604 aBB.MakeCompound(aCEInv);
2605 TopExp_Explorer aExp(aFIm, TopAbs_EDGE);
2606 for (; aExp.More(); aExp.Next()) {
2607 const TopoDS_Shape& aE = aExp.Current();
2608 if (aMERem.Contains(aE)) {
2609 aBB.Add(aCEInv, aE);
2613 // check connectivity
2614 TopTools_ListOfShape aLCBE;
2615 BOPTools_AlgoTools::MakeConnexityBlocks(aCEInv, TopAbs_VERTEX, TopAbs_EDGE, aLCBE);
2617 if (aLCBE.Extent() >= 2) {
2618 aMFToUpdate.Add(aF);
2627 if (aLFIm.Extent()) {
2628 aInvFaces.Add(aF, aLFIm);
2632 if (aMFRem.IsEmpty()) {
2636 theInvFaces = aInvFaces;
2637 // remove from splits
2638 aNb = aMFToUpdate.Extent();
2639 for (i = 1; i <= aNb; ++i) {
2640 const TopoDS_Shape& aF = aMFToUpdate(i);
2641 TopTools_ListOfShape& aLFIm = theFImages.ChangeFromKey(aF);
2643 TopTools_ListIteratorOfListOfShape aIt(aLFIm);
2644 for (; aIt.More(); ) {
2645 const TopoDS_Shape& aFIm = aIt.Value();
2646 if (aMFRem.Contains(aFIm)) {
2647 TopExp::MapShapes(aFIm, TopAbs_EDGE, theMERemoved);
2657 //=======================================================================
2658 //function : RemoveInvalidSplitsFromValid
2659 //purpose : Removing invalid splits of faces from valid
2660 //=======================================================================
2661 void RemoveInvalidSplitsFromValid(const TopTools_IndexedDataMapOfShapeListOfShape& theInvFaces,
2662 const TopTools_DataMapOfShapeShape& theArtInvFaces,
2663 const TopTools_MapOfShape& theMEInverted,
2664 TopTools_IndexedDataMapOfShapeListOfShape& theFImages)
2666 // Decide whether to remove the found invalid faces or not.
2667 // The procedure is the following:
2668 // 1. Make connexity blocks from invalid faces;
2669 // 2. Find free edges in this blocks;
2670 // 3. If all free edges are valid for the faces - remove block.
2672 TopTools_MapOfShape aMFence, aMFToRem;
2673 TopoDS_Compound aCFInv;
2675 aBB.MakeCompound(aCFInv);
2676 TopTools_ListIteratorOfListOfShape aItLF;
2678 // make compound of invalid faces
2679 TopTools_DataMapOfShapeShape aDMIFOF;
2680 Standard_Integer i, aNb = theInvFaces.Extent();
2681 for (i = 1; i <= aNb; ++i) {
2682 const TopoDS_Shape& aF = theInvFaces.FindKey(i);
2683 // artificially invalid faces should not be removed
2684 if (theArtInvFaces.IsBound(aF)) {
2687 const TopTools_ListOfShape& aLFInv = theInvFaces(i);
2688 aItLF.Initialize(aLFInv);
2689 for (; aItLF.More(); aItLF.Next()) {
2690 const TopoDS_Shape& aFIm = aItLF.Value();
2691 if (aMFence.Add(aFIm)) {
2692 aBB.Add(aCFInv, aFIm);
2693 aDMIFOF.Bind(aFIm, aF);
2698 // make connexity blocks
2699 TopTools_ListOfShape aLCBInv;
2700 BOPTools_AlgoTools::MakeConnexityBlocks(aCFInv, TopAbs_EDGE, TopAbs_FACE, aLCBInv);
2702 // analyze each block
2703 aItLF.Initialize(aLCBInv);
2704 for (; aItLF.More(); aItLF.Next()) {
2705 const TopoDS_Shape& aCB = aItLF.Value();
2707 // if connexity block contains only one face - it should be removed;
2708 TopExp_Explorer aExp(aCB, TopAbs_FACE);
2711 // check if there are valid images left
2712 aExp.Init(aCB, TopAbs_FACE);
2713 for (; aExp.More(); aExp.Next()) {
2714 const TopoDS_Shape& aFIm = aExp.Current();
2715 const TopoDS_Shape& aF = aDMIFOF.Find(aFIm);
2717 const TopTools_ListOfShape& aLFIm = theFImages.FindFromKey(aF);
2718 const TopTools_ListOfShape& aLFInv = theInvFaces.FindFromKey(aF);
2720 if (aLFIm.Extent() == aLFInv.Extent()) {
2727 aExp.Init(aCB, TopAbs_FACE);
2728 for (; aExp.More(); aExp.Next()) {
2729 const TopoDS_Shape& aF = aExp.Current();
2735 // remove faces connected by inverted edges
2736 TopTools_IndexedDataMapOfShapeListOfShape aDMEF;
2737 TopExp::MapShapesAndAncestors(aCB, TopAbs_EDGE, TopAbs_FACE, aDMEF);
2739 aExp.Init(aCB, TopAbs_FACE);
2740 for (; aExp.More(); aExp.Next()) {
2741 const TopoDS_Shape& aFCB = aExp.Current();
2743 TopExp_Explorer aExpE(aFCB, TopAbs_EDGE);
2744 for (; aExpE.More(); aExpE.Next()) {
2745 const TopoDS_Shape& aECB = aExpE.Current();
2746 if (aDMEF.FindFromKey(aECB).Extent() > 1) {
2747 if (!theMEInverted.Contains(aECB)) {
2753 if (!aExpE.More()) {
2759 if (aMFToRem.Extent()) {
2760 // remove invalid faces from images
2761 aNb = theInvFaces.Extent();
2762 for (i = 1; i <= aNb; ++i) {
2763 const TopoDS_Shape& aF = theInvFaces.FindKey(i);
2764 TopTools_ListOfShape& aLFImages = theFImages.ChangeFromKey(aF);
2765 aItLF.Initialize(aLFImages);
2766 for (; aItLF.More();) {
2767 const TopoDS_Shape& aFIm = aItLF.Value();
2768 if (aMFToRem.Contains(aFIm)) {
2769 aLFImages.Remove(aItLF);
2779 //=======================================================================
2780 //function : RemoveInsideFaces
2781 //purpose : Looking for the inside faces that can be safely removed
2782 //=======================================================================
2783 void RemoveInsideFaces(TopTools_IndexedDataMapOfShapeListOfShape& theFImages,
2784 TopTools_IndexedDataMapOfShapeListOfShape& theInvFaces,
2785 const TopTools_DataMapOfShapeShape& theArtInvFaces,
2786 const TopTools_IndexedMapOfShape& theInvEdges,
2787 const TopTools_IndexedMapOfShape& theMFToCheckInt,
2788 const TopTools_IndexedMapOfShape& theMFInvInHole,
2789 const TopoDS_Shape& theFHoles,
2790 TopTools_DataMapOfShapeListOfShape& theSSInterfs,
2791 TopTools_IndexedMapOfShape& theMERemoved,
2792 TopTools_IndexedMapOfShape& theMEInside,
2793 TopoDS_Shape& theSolids)
2795 BOPCol_ListOfShape aLS;
2796 TopTools_MapOfShape aMFence;
2797 TopTools_IndexedMapOfShape aMFInv;
2798 TopTools_ListIteratorOfListOfShape aItLF;
2799 TopTools_DataMapOfShapeShape aDMFImF;
2801 Standard_Integer i, aNb = theFImages.Extent();
2802 for (i = 1; i <= aNb; ++i) {
2803 const TopoDS_Shape& aF = theFImages.FindKey(i);
2804 // to avoid intersection of the splits of the same
2805 // offset faces among themselves make compound of the
2806 // splits and use it as one argument
2807 TopoDS_Compound aCFImi;
2808 BRep_Builder().MakeCompound(aCFImi);
2810 for (Standard_Integer j = 0; j < 2; ++j) {
2811 const TopTools_ListOfShape* pLFSp = !j ? theInvFaces.Seek(aF) : &theFImages(i);
2816 aItLF.Initialize(*pLFSp);
2817 for (; aItLF.More(); aItLF.Next()) {
2818 const TopoDS_Shape& aFIm = aItLF.Value();
2819 if (aMFence.Add(aFIm)) {
2820 BRep_Builder().Add(aCFImi, aFIm);
2821 aDMFImF.Bind(aFIm, aF);
2832 // to make the solids more complete add for intersection also the faces
2833 // consisting only of invalid edges and not included into splits
2834 aNb = theMFToCheckInt.Extent();
2835 for (i = 1; i <= aNb; ++i) {
2836 const TopoDS_Shape& aFSp = theMFToCheckInt(i);
2837 if (aMFence.Add(aFSp)) {
2842 BOPAlgo_MakerVolume aMV;
2843 aMV.SetArguments(aLS);
2844 aMV.SetIntersect(Standard_True);
2847 // get shapes connection for using in the rebuilding process
2848 // for the cases in which some of the intersection left undetected
2849 ShapesConnections(theInvFaces, theInvEdges, aDMFImF, aMV, theSSInterfs);
2851 // find faces to remove
2852 const TopoDS_Shape& aSols = aMV.Shape();
2854 TopTools_IndexedDataMapOfShapeListOfShape aDMFS;
2855 TopExp::MapShapesAndAncestors(aSols, TopAbs_FACE, TopAbs_SOLID, aDMFS);
2857 aNb = aDMFS.Extent();
2862 // To use the created solids for classifications, firstly, it is necessary
2863 // to check them on validity - the created solids should be complete,
2864 // i.e. all faces should be included.
2866 TopTools_MapOfShape aMFToRem;
2867 // Check completeness
2868 if (aMV.HasDeleted()) {
2869 TopTools_IndexedMapOfShape aMEHoles;
2870 TopExp::MapShapes(theFHoles, TopAbs_EDGE, aMEHoles);
2872 // perform additional check on faces
2873 aNb = theFImages.Extent();
2874 for (i = 1; i <= aNb; ++i) {
2875 const TopTools_ListOfShape& aLFIm = theFImages(i);
2876 if (aLFIm.IsEmpty()) {
2880 Standard_Boolean bFaceKept = Standard_False;
2881 aItLF.Initialize(aLFIm);
2882 for (; aItLF.More(); aItLF.Next()) {
2883 const TopoDS_Shape& aFIm = aItLF.Value();
2884 if (!aMV.IsDeleted(aFIm)) {
2885 bFaceKept = Standard_True;
2889 TopExp_Explorer aExpE(aFIm, TopAbs_EDGE);
2890 for (; aExpE.More(); aExpE.Next()) {
2891 if (aMEHoles.Contains(aExpE.Current())) {
2892 bFaceKept = Standard_True;
2905 TopTools_IndexedMapOfShape aMEBoundary;
2906 aNb = aDMFS.Extent();
2907 for (i = 1; i <= aNb; ++i) {
2908 const TopoDS_Shape& aFIm = aDMFS.FindKey(i);
2909 const TopTools_ListOfShape& aLSol = aDMFS(i);
2910 if (aLSol.Extent() > 1) {
2913 else if (aFIm.Orientation() != TopAbs_INTERNAL) {
2914 TopExp::MapShapes(aFIm, TopAbs_EDGE, aMEBoundary);
2918 // update invalid faces with images
2919 aNb = aMFInv.Extent();
2920 for (i = 1; i <= aNb; ++i) {
2921 const TopoDS_Shape& aFInv = aMFInv(i);
2922 const TopTools_ListOfShape& aLFInvIm = aMV.Modified(aFInv);
2923 TopTools_ListIteratorOfListOfShape aItLFInvIm(aLFInvIm);
2924 for (; aItLFInvIm.More(); aItLFInvIm.Next()) {
2925 const TopoDS_Shape& aFInvIm = aItLFInvIm.Value();
2926 aMFInv.Add(aFInvIm);
2930 // check if the invalid faces inside the holes are really invalid:
2931 // check its normal direction - if it has changed relatively the
2932 // original face the offset face is invalid and should be kept for rebuilding
2933 Standard_Integer aNbFH = theMFInvInHole.Extent();
2934 for (i = 1; i <= aNbFH; ++i) {
2935 const TopoDS_Shape& aFInv = theMFInvInHole(i);
2936 TopTools_ListOfShape aLFInvIm = aMV.Modified(aFInv);
2937 if (aLFInvIm.IsEmpty()) {
2938 aLFInvIm.Append(aFInv);
2941 const TopoDS_Shape *pFOffset = aDMFImF.Seek(aFInv);
2945 TopTools_ListIteratorOfListOfShape aItLFInv(aLFInvIm);
2946 for (; aItLFInv.More(); aItLFInv.Next()) {
2947 const TopoDS_Shape& aFInvIm = aItLFInv.Value();
2948 const TopTools_ListOfShape* pLSols = aDMFS.Seek(aFInvIm);
2949 if (!pLSols || pLSols->Extent() != 1) {
2953 const TopoDS_Shape& aFSol = pLSols->First();
2956 if (!FindShape(aFInvIm, aFSol, aFx)) {
2960 if (BRepOffset_Tool::CheckPlanesNormals(TopoDS::Face(aFx), TopoDS::Face(*pFOffset))) {
2961 // the normal direction has not changed, thus the face can be removed
2962 aMFToRem.Add(aFInvIm);
2967 TopoDS_Compound aSolids;
2968 BRep_Builder().MakeCompound(aSolids);
2969 TopTools_MapOfShape aMFKeep;
2971 TopExp_Explorer aExpS(aSols, TopAbs_SOLID);
2972 for (; aExpS.More(); aExpS.Next()) {
2973 const TopoDS_Shape& aSol = aExpS.Current();
2975 Standard_Boolean bAllInv(Standard_True), bAllRemoved(Standard_True);
2977 for (TopExp_Explorer aExpF(aSol, TopAbs_FACE); aExpF.More(); aExpF.Next())
2979 const TopoDS_Shape& aFS = aExpF.Current();
2981 if (aFS.Orientation() == TopAbs_INTERNAL) {
2985 bAllRemoved = bAllRemoved && aMFToRem.Contains(aFS);
2986 bAllInv = bAllInv && (aMFToRem.Contains(aFS) || aMFInv.Contains(aFS));
2989 if (bAllInv && !bAllRemoved) {
2990 // remove invalid faces but keep those that have already been marked for removal
2991 TopExp_Explorer aExpF(aSol, TopAbs_FACE);
2992 for (; aExpF.More(); aExpF.Next()) {
2993 const TopoDS_Shape& aFS = aExpF.Current();
2995 if (aMFToRem.Contains(aFS)) {
2996 if (!aMFKeep.Add(aFS)) {
2997 aMFKeep.Remove(aFS);
3006 BRep_Builder().Add(aSolids, aSol);
3007 theSolids = aSolids;
3011 TopTools_MapIteratorOfMapOfShape aItM(aMFKeep);
3012 for (; aItM.More(); aItM.Next()) {
3013 aMFToRem.Remove(aItM.Value());
3016 // remove newly found internal faces
3017 RemoveValidSplits(aMFToRem, theFImages, aMV, theMERemoved);
3018 RemoveInvalidSplits(aMFToRem, theArtInvFaces, theInvEdges, theInvFaces, aMV, theMERemoved);
3020 // Get inside faces from the removed ones comparing them with boundary edges
3021 aNb = theMERemoved.Extent();
3022 for (i = 1; i <= aNb; ++i) {
3023 const TopoDS_Shape& aE = theMERemoved(i);
3024 if (!aMEBoundary.Contains(aE)) {
3025 theMEInside.Add(aE);
3030 //=======================================================================
3031 //function : ShapesConnections
3032 //purpose : Looking for the connections between faces not to miss
3033 // some necessary intersection
3034 //=======================================================================
3035 void ShapesConnections(const TopTools_IndexedDataMapOfShapeListOfShape& theInvFaces,
3036 const TopTools_IndexedMapOfShape& theInvEdges,
3037 const TopTools_DataMapOfShapeShape& theDMFOr,
3038 BOPAlgo_Builder& theBuilder,
3039 TopTools_DataMapOfShapeListOfShape& theSSInterfs)
3041 // update invalid edges with images and keep connection to original edge
3042 TopTools_DataMapOfShapeListOfShape aDMEOr;
3043 Standard_Integer aNb = theInvEdges.Extent();
3044 for (Standard_Integer i = 1; i <= aNb; ++i) {
3045 const TopoDS_Shape& aEInv = theInvEdges(i);
3046 const TopTools_ListOfShape& aLEIm = theBuilder.Modified(aEInv);
3047 if (aLEIm.IsEmpty()) {
3048 aDMEOr.Bound(aEInv, TopTools_ListOfShape())->Append(aEInv);
3052 TopTools_ListIteratorOfListOfShape aItLEIm(aLEIm);
3053 for (; aItLEIm.More(); aItLEIm.Next()) {
3054 const TopoDS_Shape& aEIm = aItLEIm.Value();
3056 TopTools_ListOfShape* pLEOr = aDMEOr.ChangeSeek(aEIm);
3058 pLEOr = aDMEOr.Bound(aEIm, TopTools_ListOfShape());
3060 AppendToList(*pLEOr, aEInv);
3064 // get shapes connections for using in the rebuilding process
3065 const BOPDS_PDS& pDS = theBuilder.PDS();
3066 // analyze all Face/Face intersections
3067 const BOPDS_VectorOfInterfFF& aFFs = pDS->InterfFF();
3068 Standard_Integer iInt, aNbFF = aFFs.Extent();
3069 for (iInt = 0; iInt < aNbFF; ++iInt) {
3070 const BOPDS_InterfFF& aFF = aFFs(iInt);
3071 const BOPDS_VectorOfCurve& aVNC = aFF.Curves();
3072 Standard_Integer aNbC = aVNC.Extent();
3077 const TopoDS_Shape& aFIm1 = pDS->Shape(aFF.Index1());
3078 const TopoDS_Shape& aFIm2 = pDS->Shape(aFF.Index2());
3080 const TopoDS_Shape* pF1 = theDMFOr.Seek(aFIm1);
3081 const TopoDS_Shape* pF2 = theDMFOr.Seek(aFIm2);
3087 if (pF1->IsSame(*pF2)) {
3091 Standard_Boolean bInv1 = theInvFaces.Contains(*pF1);
3092 Standard_Boolean bInv2 = theInvFaces.Contains(*pF2);
3094 if (!bInv1 && !bInv2) {
3098 // check if it is real Face/Face intersection
3099 TopTools_MapOfShape aMEInt;
3100 for (Standard_Integer iC = 0; iC < aNbC; ++iC) {
3101 const BOPDS_Curve& aNC = aVNC(iC);
3102 const BOPDS_ListOfPaveBlock& aLPB = aNC.PaveBlocks();
3103 BOPDS_ListIteratorOfListOfPaveBlock aItLPB(aLPB);
3104 for (; aItLPB.More(); aItLPB.Next()) {
3105 const Handle(BOPDS_PaveBlock)& aPB = aItLPB.Value();
3106 Standard_Integer nEInt;
3107 if (aPB->HasEdge(nEInt)) {
3108 const TopoDS_Shape& aEInt = pDS->Shape(nEInt);
3114 if (aMEInt.IsEmpty()) {
3118 // check if invalid edges of the face are in the same splits with intersection edges
3119 for (Standard_Integer i = 0; i < 2; ++i) {
3120 if ((!i && !bInv1) || (i && !bInv2)) {
3124 const TopoDS_Shape& aF = !i ? *pF1 : *pF2;
3125 const TopoDS_Shape& aFOp = !i ? *pF2 : *pF1;
3126 const TopoDS_Shape& aFIm = !i ? aFIm1 : aFIm2;
3128 Standard_Boolean bFound = Standard_False;
3130 TopTools_ListOfShape aLFIm = theBuilder.Modified(aFIm);
3131 if (aLFIm.IsEmpty()) {
3135 TopTools_ListIteratorOfListOfShape aItLFIm(aLFIm);
3136 for (; aItLFIm.More(); aItLFIm.Next()) {
3137 const TopoDS_Shape& aFImIm = aItLFIm.Value();
3139 Standard_Boolean bInv(Standard_False), bInt(Standard_False);
3140 TopExp_Explorer aExpE(aFImIm, TopAbs_EDGE);
3141 for (; aExpE.More(); aExpE.Next()) {
3142 const TopoDS_Shape& aE = aExpE.Current();
3144 bInv = aDMEOr.IsBound(aE);
3147 bInt = aMEInt.Contains(aE);
3154 if (!bInt || !bInv) {
3158 bFound = Standard_True;
3160 // append opposite face to all invalid edges in the split
3161 aExpE.Init(aFImIm, TopAbs_EDGE);
3162 for (; aExpE.More(); aExpE.Next()) {
3163 const TopoDS_Shape& aE = aExpE.Current();
3164 const TopTools_ListOfShape* pLEOr = aDMEOr.Seek(aE);
3169 TopTools_ListIteratorOfListOfShape aItLE(*pLEOr);
3170 for (; aItLE.More(); aItLE.Next()) {
3171 const TopoDS_Shape& aEOr = aItLE.Value();
3172 TopTools_ListOfShape *pLFE = theSSInterfs.ChangeSeek(aEOr);
3174 pLFE = theSSInterfs.Bound(aEOr, TopTools_ListOfShape());
3176 AppendToList(*pLFE, aFOp);
3181 // save connection between offset faces
3182 TopTools_ListOfShape *pLF = theSSInterfs.ChangeSeek(aF);
3184 pLF = theSSInterfs.Bound(aF, TopTools_ListOfShape());
3186 AppendToList(*pLF, aFOp);
3192 //=======================================================================
3193 //function : RemoveValidSplits
3194 //purpose : Removing valid splits according to results of intersection
3195 //=======================================================================
3196 void RemoveValidSplits(const TopTools_MapOfShape& theSpRem,
3197 TopTools_IndexedDataMapOfShapeListOfShape& theImages,
3198 BOPAlgo_Builder& theGF,
3199 TopTools_IndexedMapOfShape& theMERemoved)
3201 Standard_Integer i, aNb = theImages.Extent();
3206 for (i = 1; i <= aNb; ++i) {
3207 TopTools_ListOfShape& aLSIm = theImages(i);
3208 TopTools_ListIteratorOfListOfShape aIt(aLSIm);
3209 for (; aIt.More(); ) {
3210 const TopoDS_Shape& aSIm = aIt.Value();
3211 if (theSpRem.Contains(aSIm)) {
3212 TopExp::MapShapes(aSIm, TopAbs_EDGE, theMERemoved);
3217 // check if all its images are have to be removed
3218 const TopTools_ListOfShape& aLSImIm = theGF.Modified(aSIm);
3219 if (aLSImIm.Extent()) {
3220 Standard_Boolean bAllRem = Standard_True;
3221 TopTools_ListIteratorOfListOfShape aIt1(aLSImIm);
3222 for (; aIt1.More(); aIt1.Next()) {
3223 const TopoDS_Shape& aSImIm = aIt1.Value();
3224 if (theSpRem.Contains(aSImIm)) {
3225 TopExp::MapShapes(aSImIm, TopAbs_EDGE, theMERemoved);
3228 bAllRem = Standard_False;
3233 TopExp::MapShapes(aSIm, TopAbs_EDGE, theMERemoved);
3243 //=======================================================================
3244 //function : RemoveInvalidSplits
3245 //purpose : Removing invalid splits according to the results of intersection
3246 //=======================================================================
3247 void RemoveInvalidSplits(const TopTools_MapOfShape& theSpRem,
3248 const TopTools_DataMapOfShapeShape& theArtInvFaces,
3249 const TopTools_IndexedMapOfShape& theInvEdges,
3250 TopTools_IndexedDataMapOfShapeListOfShape& theImages,
3251 BOPAlgo_Builder& theGF,
3252 TopTools_IndexedMapOfShape& theMERemoved)
3254 Standard_Integer i, aNb = theImages.Extent();