ecf4f17c |
1 | // Created on: 2016 |
2 | // Created by: Eugeny MALTCHIKOV |
3 | // Copyright (c) 2016 OPEN CASCADE SAS |
4 | // |
5 | // This file is part of Open CASCADE Technology software library. |
6 | // |
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. |
12 | // |
13 | // Alternatively, this file may be used under the terms of Open CASCADE |
14 | // commercial license or contractual agreement. |
15 | |
16 | |
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. |
20 | |
21 | |
22 | #include <BRepOffset_MakeOffset.hxx> |
23 | |
24 | #include <Precision.hxx> |
25 | #include <TopoDS.hxx> |
26 | |
27 | #include <BRepAlgo_AsDes.hxx> |
28 | #include <BRepAlgo_Image.hxx> |
29 | |
30 | #include <BRep_Builder.hxx> |
31 | #include <BRep_Tool.hxx> |
32 | |
f16a6cc5 |
33 | #include <BRepLib.hxx> |
ecf4f17c |
34 | #include <BRepTools.hxx> |
35 | |
36 | #include <BRepAdaptor_Curve.hxx> |
37 | |
38 | #include <TopExp.hxx> |
39 | #include <TopExp_Explorer.hxx> |
40 | |
41 | #include <TopTools_DataMapOfShapeInteger.hxx> |
42 | |
43 | #include <BRepOffset_Tool.hxx> |
44 | |
45 | #include <BRepClass3d_SolidClassifier.hxx> |
46 | |
47 | #include <BOPDS_DS.hxx> |
48 | |
49 | #include <BOPAlgo_PaveFiller.hxx> |
50 | #include <BOPAlgo_Builder.hxx> |
51 | #include <BOPAlgo_Section.hxx> |
52 | #include <BOPAlgo_MakerVolume.hxx> |
a8232603 |
53 | #include <BOPAlgo_BuilderFace.hxx> |
ecf4f17c |
54 | |
1155d05a |
55 | #include <TopTools_ListOfShape.hxx> |
56 | #include <TopTools_DataMapOfShapeShape.hxx> |
57 | #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx> |
2ebb1098 |
58 | #include <TopTools_MapOfOrientedShape.hxx> |
ecf4f17c |
59 | |
ecf4f17c |
60 | #include <BOPTools_AlgoTools3D.hxx> |
61 | #include <BOPTools_AlgoTools.hxx> |
a8232603 |
62 | #include <BOPTools_AlgoTools2D.hxx> |
bea10656 |
63 | #include <BOPTools_Set.hxx> |
ecf4f17c |
64 | |
65 | #include <IntTools_Context.hxx> |
66 | #include <IntTools_ShrunkRange.hxx> |
67 | |
bc4a3867 |
68 | #ifdef OFFSET_DEBUG |
69 | #include <BRepAlgoAPI_Check.hxx> |
70 | #endif |
71 | |
baaacd46 |
72 | typedef NCollection_DataMap |
73 | <TopoDS_Shape, TopTools_MapOfShape, TopTools_ShapeMapHasher> BRepOffset_DataMapOfShapeMapOfShape; |
9e9b826a |
74 | typedef NCollection_DataMap |
75 | <TopoDS_Shape, TopTools_IndexedMapOfShape, TopTools_ShapeMapHasher> BRepOffset_DataMapOfShapeIndexedMapOfShape; |
ecf4f17c |
76 | |
77 | static |
78 | void IntersectTrimmedEdges(const TopTools_ListOfShape& theLF, |
79 | const Handle(BRepAlgo_AsDes)& theAsDes, |
80 | TopTools_DataMapOfShapeListOfShape& theOEImages, |
81 | TopTools_DataMapOfShapeListOfShape& theOEOrigins, |
82 | TopTools_DataMapOfShapeListOfShape& theEdgesOrigins, |
83 | Handle(IntTools_Context)& theCtx, |
84 | TopTools_MapOfShape& theNewEdges, |
85 | TopTools_DataMapOfShapeShape& theETrimEInf); |
86 | |
87 | static |
88 | Standard_Boolean GetEdges(const TopoDS_Face& theFace, |
89 | const Handle(BRepAlgo_AsDes)& theAsDes, |
90 | const TopTools_DataMapOfShapeListOfShape& theEImages, |
91 | const TopTools_MapOfShape& theLastInvEdges, |
92 | const TopTools_IndexedMapOfShape& theInvEdges, |
93 | Handle(IntTools_Context)& theCtx, |
94 | const TopTools_MapOfShape& theModifiedEdges, |
95 | TopoDS_Shape& theEdges, |
96 | TopTools_IndexedMapOfShape& theInv); |
97 | |
a8232603 |
98 | static |
99 | void BuildSplitsOfTrimmedFace(const TopoDS_Face& theFace, |
100 | const TopoDS_Shape& theEdges, |
101 | TopTools_ListOfShape& theLFImages); |
102 | |
ecf4f17c |
103 | static |
104 | void BuildSplitsOfFace(const TopoDS_Face& theFace, |
105 | const TopoDS_Shape& theEdges, |
ecf4f17c |
106 | TopTools_DataMapOfShapeShape& theOrigins, |
107 | TopTools_ListOfShape& theLFImages); |
108 | |
6f04cbb1 |
109 | //! Auxiliary structure to contain intersection information |
110 | struct BRepOffset_MakeOffset_InterResults |
111 | { |
112 | TopTools_DataMapOfShapeListOfShape SSInterfs; //!< Intersection information, used to add pair for intersection |
113 | NCollection_DataMap <TopoDS_Shape, |
114 | BRepOffset_DataMapOfShapeMapOfShape, |
115 | TopTools_ShapeMapHasher> InterPairs; //!< All possible intersection pairs, used to avoid |
116 | //! some of the intersection |
117 | }; |
118 | |
ecf4f17c |
119 | static |
120 | void BuildSplitsOfFaces(const TopTools_ListOfShape& theLF, |
121 | const TopTools_MapOfShape& theModifiedEdges, |
122 | const TopTools_DataMapOfShapeListOfShape& theEdgesOrigins, |
420b38fd |
123 | const BRepOffset_Analyse* theAnalyse, |
ecf4f17c |
124 | Handle(BRepAlgo_AsDes)& theAsDes, |
125 | TopTools_DataMapOfShapeShape& theFacesOrigins, |
126 | TopTools_DataMapOfShapeListOfShape& theOEImages, |
127 | TopTools_DataMapOfShapeListOfShape& theOEOrigins, |
128 | TopTools_MapOfShape& theLastInvEdges, |
129 | TopTools_IndexedMapOfShape& theEdgesToAvoid, |
130 | TopTools_IndexedMapOfShape& theInvEdges, |
131 | TopTools_IndexedMapOfShape& theValidEdges, |
132 | TopTools_MapOfShape& theInvertedEdges, |
133 | TopTools_DataMapOfShapeInteger& theAlreadyInvFaces, |
134 | TopTools_IndexedDataMapOfShapeListOfShape& theInvFaces, |
135 | TopTools_DataMapOfShapeShape& theArtInvFaces, |
136 | TopTools_IndexedDataMapOfShapeListOfShape& theFImages, |
0da0275c |
137 | TopTools_DataMapOfShapeListOfShape& theDMFNewHoles, |
ecf4f17c |
138 | TopoDS_Shape& theSolids, |
6f04cbb1 |
139 | BRepOffset_MakeOffset_InterResults& theIntRes); |
ecf4f17c |
140 | |
141 | static |
142 | void BuildSplitsOfInvFaces(const TopTools_IndexedDataMapOfShapeListOfShape& theFToRebuild, |
143 | const TopTools_MapOfShape& theModifiedEdges, |
bea10656 |
144 | const BRepOffset_Analyse* theAnalyse, |
ecf4f17c |
145 | TopTools_IndexedDataMapOfShapeListOfShape& theFImages, |
0da0275c |
146 | TopTools_DataMapOfShapeListOfShape& theDMFNewHoles, |
ecf4f17c |
147 | TopTools_DataMapOfShapeListOfShape& theEdgesOrigins, |
148 | TopTools_DataMapOfShapeShape& theFacesOrigins, |
149 | TopTools_DataMapOfShapeListOfShape& theOEImages, |
150 | TopTools_DataMapOfShapeListOfShape& theOEOrigins, |
151 | TopTools_MapOfShape& theLastInvEdges, |
152 | TopTools_IndexedMapOfShape& theEdgesToAvoid, |
153 | TopTools_MapOfShape& theVertsToAvoid, |
154 | TopTools_DataMapOfShapeInteger& theAlreadyInvFaces, |
155 | TopTools_IndexedMapOfShape& theValidEdges, |
156 | TopTools_DataMapOfShapeShape& theETrimEInf, |
157 | Handle(BRepAlgo_AsDes)& theAsDes); |
158 | |
159 | static |
160 | Standard_Boolean CheckIfArtificial(const TopoDS_Shape& theF, |
161 | const TopTools_ListOfShape& theLFImages, |
162 | const TopoDS_Shape& theCE, |
163 | const TopTools_IndexedMapOfShape& theMapEInv, |
164 | const TopTools_DataMapOfShapeListOfShape& theOEImages, |
165 | TopTools_MapOfShape& theMENInv, |
166 | Handle(BRepAlgo_AsDes)& theAsDes); |
167 | |
168 | static |
169 | void FindInvalidEdges(const TopoDS_Face& theF, |
170 | const TopTools_ListOfShape& theLFImages, |
171 | const TopTools_DataMapOfShapeListOfShape& theEdgesOrigins, |
172 | const TopTools_DataMapOfShapeShape& theFacesOrigins, |
420b38fd |
173 | const BRepOffset_Analyse* theAnalyse, |
ecf4f17c |
174 | const TopTools_DataMapOfShapeListOfShape& theOEImages, |
175 | const TopTools_DataMapOfShapeListOfShape& theOEOrigins, |
176 | TopTools_IndexedMapOfShape& theInvEdges, |
177 | TopTools_IndexedMapOfShape& theValidEdges, |
9e9b826a |
178 | BRepOffset_DataMapOfShapeMapOfShape& theDMFMVE, |
179 | BRepOffset_DataMapOfShapeMapOfShape& theDMFMNE, |
180 | BRepOffset_DataMapOfShapeIndexedMapOfShape& theDMFMIE, |
181 | BRepOffset_DataMapOfShapeMapOfShape& theDMFMVIE, |
0da0275c |
182 | TopTools_DataMapOfShapeListOfShape& theDMEOrLEIm, |
ecf4f17c |
183 | TopTools_MapOfShape& theMEInverted, |
9e9b826a |
184 | TopTools_MapOfShape& theEdgesInvalidByVertex, |
185 | TopTools_MapOfShape& theEdgesValidByVertex); |
ecf4f17c |
186 | |
bea10656 |
187 | static |
188 | void FindInvalidEdges (const TopTools_ListOfShape& theLFOffset, |
189 | const TopTools_IndexedDataMapOfShapeListOfShape& theFImages, |
190 | const TopTools_DataMapOfShapeShape& theFacesOrigins, |
191 | const BRepOffset_Analyse* theAnalyse, |
192 | const TopTools_IndexedMapOfShape& theInvEdges, |
193 | const TopTools_IndexedMapOfShape& theValidEdges, |
194 | BRepOffset_DataMapOfShapeIndexedMapOfShape& theLocInvEdges, |
195 | BRepOffset_DataMapOfShapeMapOfShape& theLocValidEdges, |
196 | BRepOffset_DataMapOfShapeMapOfShape& theNeutralEdges); |
197 | |
62eafa5a |
198 | static |
199 | void MakeInvertedEdgesInvalid(const TopTools_ListOfShape& theLFOffset, |
200 | const TopTools_IndexedDataMapOfShapeListOfShape& theFImages, |
201 | const TopTools_MapOfShape& theInvertedEdges, |
202 | TopTools_IndexedMapOfShape& theInvEdges); |
203 | |
ecf4f17c |
204 | static |
205 | void FindInvalidFaces(TopTools_ListOfShape& theLFImages, |
206 | const TopTools_IndexedMapOfShape& theInvEdges, |
207 | const TopTools_IndexedMapOfShape& theValidEdges, |
9e9b826a |
208 | const BRepOffset_DataMapOfShapeMapOfShape& theDMFMVE, |
209 | const BRepOffset_DataMapOfShapeIndexedMapOfShape& theDMFMIE, |
210 | const TopTools_MapOfShape& theLENeutral, |
ecf4f17c |
211 | const TopTools_MapOfShape& theMEInverted, |
212 | const TopTools_MapOfShape& theEdgesInvalidByVertex, |
9e9b826a |
213 | const TopTools_MapOfShape& theEdgesValidByVertex, |
0da0275c |
214 | const TopTools_MapOfShape& theMFHoles, |
215 | TopTools_IndexedMapOfShape& theMFInvInHole, |
e08a9b03 |
216 | TopTools_ListOfShape& theInvFaces, |
217 | TopTools_ListOfShape& theInvertedFaces); |
ecf4f17c |
218 | |
0da0275c |
219 | static |
220 | void FindFacesInsideHoleWires(const TopoDS_Face& theFOrigin, |
221 | const TopoDS_Face& theFOffset, |
222 | const TopTools_ListOfShape& theLFImages, |
223 | const TopTools_MapOfShape& theInvertedEdges, |
224 | const TopTools_DataMapOfShapeListOfShape& theDMEOrLEIm, |
2ebb1098 |
225 | const TopTools_IndexedDataMapOfShapeListOfShape& theEFMap, |
0da0275c |
226 | TopTools_MapOfShape& theMFHoles, |
227 | TopTools_DataMapOfShapeListOfShape& theDMFNewHoles, |
228 | Handle(IntTools_Context)& theContext); |
229 | |
ecf4f17c |
230 | static |
231 | gp_Vec GetAverageTangent(const TopoDS_Shape& theS, |
232 | const Standard_Integer theNbP); |
233 | |
234 | static |
235 | Standard_Boolean CheckInverted(const TopoDS_Edge& theEIm, |
236 | const TopoDS_Face& theFOr, |
237 | const TopTools_DataMapOfShapeListOfShape& theOEImages, |
238 | const TopTools_DataMapOfShapeListOfShape& theOEOrigins, |
239 | const TopTools_DataMapOfShapeListOfShape& theEdgesOrigins, |
ecf4f17c |
240 | const TopTools_IndexedDataMapOfShapeListOfShape& theDMVE, |
241 | const TopTools_IndexedMapOfShape& theMEdges, |
242 | TopTools_MapOfShape& theMEInverted); |
243 | |
baaacd46 |
244 | static |
245 | Standard_Boolean CheckInvertedBlock(const TopoDS_Shape& theCB, |
246 | const TopTools_ListOfShape& theLCBF, |
247 | const TopTools_MapOfShape& theMEInverted, |
248 | const TopTools_DataMapOfShapeListOfShape& theOEOrigins, |
249 | BRepOffset_DataMapOfShapeMapOfShape& theDMCBVInverted, |
250 | BRepOffset_DataMapOfShapeMapOfShape& theDMCBVAll); |
251 | |
252 | static |
253 | void GetVerticesOnEdges(const TopoDS_Shape& theCB, |
254 | const TopTools_MapOfShape& theEdges, |
255 | TopTools_MapOfShape& theVerticesOnEdges, |
256 | TopTools_MapOfShape& theAllVertices); |
ecf4f17c |
257 | |
258 | static |
259 | void RemoveInvalidSplitsByInvertedEdges(const TopTools_MapOfShape& theMEInverted, |
baaacd46 |
260 | const TopTools_DataMapOfShapeListOfShape& theOEOrigins, |
ecf4f17c |
261 | TopTools_IndexedDataMapOfShapeListOfShape& theInvFaces, |
262 | TopTools_IndexedDataMapOfShapeListOfShape& theFImages, |
263 | TopTools_IndexedMapOfShape& theMERemoved); |
264 | |
265 | static |
266 | void RemoveInvalidSplitsFromValid(const TopTools_IndexedDataMapOfShapeListOfShape& theInvFaces, |
267 | const TopTools_DataMapOfShapeShape& theArtInvFaces, |
268 | const TopTools_MapOfShape& theMEInverted, |
9e9b826a |
269 | const BRepOffset_DataMapOfShapeMapOfShape& theDMFMVIE, |
ecf4f17c |
270 | TopTools_IndexedDataMapOfShapeListOfShape& theFImages); |
271 | |
272 | static |
273 | void RemoveInsideFaces(TopTools_IndexedDataMapOfShapeListOfShape& theFImages, |
274 | TopTools_IndexedDataMapOfShapeListOfShape& theInvFaces, |
275 | const TopTools_DataMapOfShapeShape& theArtInvFaces, |
276 | const TopTools_IndexedMapOfShape& theInvEdges, |
e08a9b03 |
277 | const TopTools_MapOfShape& theInvertedEdges, |
278 | const TopTools_ListOfShape& theInvertedFaces, |
ecf4f17c |
279 | const TopTools_IndexedMapOfShape& theMFToCheckInt, |
0da0275c |
280 | const TopTools_IndexedMapOfShape& theMFInvInHole, |
281 | const TopoDS_Shape& theFHoles, |
6f04cbb1 |
282 | BRepOffset_MakeOffset_InterResults& theIntRes, |
ecf4f17c |
283 | TopTools_IndexedMapOfShape& theMERemoved, |
baaacd46 |
284 | TopTools_IndexedMapOfShape& theMEInside, |
ecf4f17c |
285 | TopoDS_Shape& theSolids); |
286 | |
287 | static |
288 | void ShapesConnections(const TopTools_IndexedDataMapOfShapeListOfShape& theInvFaces, |
289 | const TopTools_IndexedMapOfShape& theInvEdges, |
290 | const TopTools_DataMapOfShapeShape& theDMFOr, |
291 | BOPAlgo_Builder& theBuilder, |
292 | TopTools_DataMapOfShapeListOfShape& theSSInterfs); |
293 | |
bc4a3867 |
294 | static |
295 | void RemoveHangingParts(const BOPAlgo_MakerVolume& theMV, |
296 | const TopTools_DataMapOfShapeShape& theDMFImF, |
297 | const TopTools_IndexedMapOfShape& theMFInv, |
298 | const TopTools_IndexedMapOfShape& theInvEdges, |
e08a9b03 |
299 | const TopTools_MapOfShape& theInvertedEdges, |
bc4a3867 |
300 | TopTools_MapOfShape& theMFToRem); |
301 | |
ecf4f17c |
302 | static |
303 | void RemoveValidSplits(const TopTools_MapOfShape& theSpRem, |
304 | TopTools_IndexedDataMapOfShapeListOfShape& theImages, |
305 | BOPAlgo_Builder& theGF, |
306 | TopTools_IndexedMapOfShape& theMERemoved); |
307 | |
308 | static |
309 | void RemoveInvalidSplits(const TopTools_MapOfShape& theSpRem, |
310 | const TopTools_DataMapOfShapeShape& theArtInvFaces, |
311 | const TopTools_IndexedMapOfShape& theInvEdges, |
312 | TopTools_IndexedDataMapOfShapeListOfShape& theImages, |
313 | BOPAlgo_Builder& theGF, |
314 | TopTools_IndexedMapOfShape& theMERemoved); |
315 | |
316 | static |
317 | void FilterEdgesImages(const TopoDS_Shape& theS, |
318 | TopTools_DataMapOfShapeListOfShape& theOEImages, |
319 | TopTools_DataMapOfShapeListOfShape& theOEOrigins); |
320 | |
321 | static |
9e9b826a |
322 | void FilterInvalidFaces(TopTools_IndexedDataMapOfShapeListOfShape& theFImages, |
baaacd46 |
323 | const TopTools_IndexedDataMapOfShapeListOfShape& theDMEF, |
9e9b826a |
324 | const TopTools_IndexedMapOfShape& theInvEdges, |
baaacd46 |
325 | const TopTools_IndexedMapOfShape& theMERemoved, |
ecf4f17c |
326 | TopTools_IndexedDataMapOfShapeListOfShape& theInvFaces, |
327 | TopTools_DataMapOfShapeShape& theArtInvFaces); |
328 | |
329 | static |
330 | void FilterInvalidEdges(const TopTools_IndexedDataMapOfShapeListOfShape& theInvFaces, |
331 | const TopTools_DataMapOfShapeShape& theArtInvFaces, |
9e9b826a |
332 | const BRepOffset_DataMapOfShapeIndexedMapOfShape& theDMFMIE, |
ecf4f17c |
333 | const TopTools_IndexedMapOfShape& theMERemoved, |
334 | TopTools_IndexedMapOfShape& theInvEdges); |
335 | |
4b59685a |
336 | static |
337 | void CheckEdgesCreatedByVertex (const TopTools_IndexedDataMapOfShapeListOfShape& theInvFaces, |
338 | const TopTools_DataMapOfShapeShape& theArtInvFaces, |
339 | const TopTools_DataMapOfShapeListOfShape& theEdgesOrigins, |
340 | const TopTools_IndexedMapOfShape& theValidEdges, |
341 | TopTools_IndexedMapOfShape& theInvEdges); |
342 | |
ecf4f17c |
343 | static |
344 | void FindFacesToRebuild(const TopTools_IndexedDataMapOfShapeListOfShape& theLFImages, |
345 | const TopTools_IndexedMapOfShape& theInvEdges, |
346 | const TopTools_IndexedDataMapOfShapeListOfShape& theInvFaces, |
347 | const TopTools_DataMapOfShapeListOfShape& theSSInterfs, |
348 | TopTools_IndexedDataMapOfShapeListOfShape& theFToRebuild, |
349 | TopTools_MapOfShape& theFSelfRebAvoid); |
350 | |
351 | static |
352 | void RebuildFaces(const TopTools_IndexedDataMapOfShapeListOfShape& theFToRebuild, |
353 | const TopTools_MapOfShape& theFSelfRebAvoid, |
354 | const TopoDS_Shape& theSolids, |
6f04cbb1 |
355 | const BRepOffset_MakeOffset_InterResults& theIntRes, |
bea10656 |
356 | const BRepOffset_Analyse* theAnalyse, |
ecf4f17c |
357 | TopTools_IndexedDataMapOfShapeListOfShape& theFImages, |
0da0275c |
358 | TopTools_DataMapOfShapeListOfShape& theDMFNewHoles, |
ecf4f17c |
359 | TopTools_DataMapOfShapeListOfShape& theEdgesOrigins, |
360 | TopTools_DataMapOfShapeShape& theFacesOrigins, |
361 | TopTools_DataMapOfShapeListOfShape& theOEImages, |
362 | TopTools_DataMapOfShapeListOfShape& theOEOrigins, |
363 | TopTools_MapOfShape& theLastInvEdges, |
364 | TopTools_IndexedMapOfShape& theEdgesToAvoid, |
365 | TopTools_IndexedMapOfShape& theInvEdges, |
366 | TopTools_IndexedMapOfShape& theValidEdges, |
367 | const TopTools_MapOfShape& theInvertedEdges, |
368 | TopTools_DataMapOfShapeInteger& theAlreadyInvFaces, |
369 | TopTools_IndexedDataMapOfShapeListOfShape& theInvFaces, |
370 | const TopTools_DataMapOfShapeShape& theArtInvFaces, |
371 | TopTools_MapOfShape& theVertsToAvoid, |
372 | TopTools_DataMapOfShapeShape& theETrimEInf, |
373 | Handle(BRepAlgo_AsDes)& theAsDes); |
374 | |
375 | static |
376 | void IntersectFaces(const TopTools_IndexedDataMapOfShapeListOfShape& theFToRebuild, |
377 | const TopTools_MapOfShape& theFSelfRebAvoid, |
378 | const TopoDS_Shape& theSolids, |
6f04cbb1 |
379 | const BRepOffset_MakeOffset_InterResults& theIntRes, |
ecf4f17c |
380 | TopTools_IndexedDataMapOfShapeListOfShape& theFImages, |
381 | TopTools_DataMapOfShapeListOfShape& theEdgesOrigins, |
382 | TopTools_DataMapOfShapeListOfShape& theOEImages, |
383 | TopTools_DataMapOfShapeListOfShape& theOEOrigins, |
384 | TopTools_IndexedMapOfShape& theInvEdges, |
385 | TopTools_IndexedMapOfShape& theValidEdges, |
386 | const TopTools_MapOfShape& theInvertedEdges, |
387 | TopTools_IndexedMapOfShape& theEdgesToAvoid, |
388 | TopTools_IndexedDataMapOfShapeListOfShape& theInvFaces, |
389 | const TopTools_DataMapOfShapeShape& theArtInvFaces, |
390 | TopTools_MapOfShape& theVertsToAvoid, |
391 | TopTools_DataMapOfShapeShape& theETrimEInf, |
392 | TopTools_MapOfShape& theModifiedEdges, |
393 | Handle(BRepAlgo_AsDes)& theAsDes); |
394 | |
395 | static |
396 | void PrepareFacesForIntersection(const TopTools_IndexedDataMapOfShapeListOfShape& theFToRebuild, |
397 | const TopTools_IndexedDataMapOfShapeListOfShape& theFImages, |
398 | const TopTools_IndexedDataMapOfShapeListOfShape& theInvFaces, |
399 | const TopTools_DataMapOfShapeShape& theArtInvFaces, |
400 | const Standard_Boolean bLookVertToAvoid, |
401 | TopTools_IndexedDataMapOfShapeListOfShape& theFLE, |
402 | TopTools_DataMapOfShapeListOfShape& theMDone, |
403 | TopTools_DataMapOfShapeListOfShape& theDMSF, |
404 | TopTools_DataMapOfShapeListOfShape& theMEInfETrim, |
405 | TopTools_DataMapOfShapeListOfShape& theDMVEFull, |
406 | TopTools_DataMapOfShapeShape& theETrimEInf, |
407 | TopTools_IndexedDataMapOfShapeListOfShape& theDMEFInv); |
408 | |
409 | static |
410 | void FindVerticesToAvoid(const TopTools_IndexedDataMapOfShapeListOfShape& theDMEFInv, |
411 | const TopTools_IndexedMapOfShape& theInvEdges, |
412 | const TopTools_IndexedMapOfShape& theValidEdges, |
bc4a3867 |
413 | const TopTools_MapOfShape& theInvertedEdges, |
414 | const TopTools_DataMapOfShapeListOfShape& theDMVEFull, |
415 | const TopTools_DataMapOfShapeListOfShape& theOEImages, |
416 | const TopTools_DataMapOfShapeListOfShape& theOEOrigins, |
ecf4f17c |
417 | TopTools_MapOfShape& theMVRInv); |
418 | |
419 | static |
420 | void FindFacesForIntersection(const TopoDS_Shape& theFInv, |
421 | const TopTools_IndexedMapOfShape& theME, |
422 | const TopTools_IndexedDataMapOfShapeListOfShape& theFImages, |
423 | const TopTools_DataMapOfShapeListOfShape& theDMSF, |
424 | const TopTools_MapOfShape& theMVInvAll, |
425 | const TopTools_DataMapOfShapeShape& theArtInvFaces, |
426 | const Standard_Boolean theArtCase, |
427 | const TopTools_DataMapOfShapeListOfShape& theSSInterfs, |
428 | TopTools_IndexedMapOfShape& theMFAvoid, |
429 | TopTools_IndexedMapOfShape& theMFInt, |
430 | TopTools_IndexedMapOfShape& theMFIntExt, |
431 | TopTools_ListOfShape& theLFImInt); |
432 | |
433 | static |
434 | void ProcessCommonEdges(const TopTools_ListOfShape& theLEC, |
435 | const TopTools_IndexedMapOfShape& theInvEdges, |
436 | const TopTools_IndexedMapOfShape& theValidEdges, |
437 | const TopTools_IndexedMapOfShape& theME, |
438 | const TopTools_DataMapOfShapeShape& theETrimEInf, |
439 | const TopTools_DataMapOfShapeListOfShape& theMEInfETrim, |
440 | const TopTools_DataMapOfShapeListOfShape& theOEOrigins, |
41aa3c3d |
441 | const TopTools_MapOfShape& theAllInvs, |
ecf4f17c |
442 | const Standard_Boolean theForceUse, |
443 | TopTools_IndexedMapOfShape& theMECV, |
41aa3c3d |
444 | TopTools_MapOfShape& theMECheckExt, |
ecf4f17c |
445 | TopTools_DataMapOfShapeListOfShape& theDMEETrim, |
446 | TopTools_ListOfShape& theLFEi, |
447 | TopTools_ListOfShape& theLFEj, |
448 | TopTools_IndexedMapOfShape& theMEToInt); |
449 | |
450 | static |
451 | void UpdateIntersectedFaces(const TopoDS_Shape& theFInv, |
452 | const TopoDS_Shape& theFi, |
453 | const TopoDS_Shape& theFj, |
454 | const TopTools_ListOfShape& theLFInv, |
455 | const TopTools_ListOfShape& theLFImi, |
456 | const TopTools_ListOfShape& theLFImj, |
457 | const TopTools_ListOfShape& theLFEi, |
458 | const TopTools_ListOfShape& theLFEj, |
459 | TopTools_DataMapOfShapeListOfShape& theEdgesOrigins, |
460 | TopTools_IndexedMapOfShape& theMEToInt); |
461 | |
462 | static |
463 | void IntersectFaces(const TopoDS_Shape& theFInv, |
464 | const TopoDS_Shape& theFi, |
465 | const TopoDS_Shape& theFj, |
466 | const TopTools_ListOfShape& theLFInv, |
467 | const TopTools_ListOfShape& theLFImi, |
468 | const TopTools_ListOfShape& theLFImj, |
469 | TopTools_ListOfShape& theLFEi, |
470 | TopTools_ListOfShape& theLFEj, |
471 | TopTools_DataMapOfShapeListOfShape& theEdgesOrigins, |
472 | TopTools_IndexedMapOfShape& theMECV, |
473 | TopTools_IndexedMapOfShape& theMEToInt); |
474 | |
475 | static |
476 | void FindOrigins(const TopTools_ListOfShape& theLFIm1, |
477 | const TopTools_ListOfShape& theLFIm2, |
478 | const TopTools_IndexedMapOfShape& theME, |
479 | const TopTools_DataMapOfShapeListOfShape& theOrigins, |
480 | TopTools_ListOfShape& theLEOr); |
481 | |
482 | static |
483 | void IntersectAndTrimEdges(const TopTools_IndexedDataMapOfShapeListOfShape& theFToRebuild, |
484 | const TopTools_IndexedMapOfShape& theMFInt, |
485 | const TopTools_IndexedMapOfShape& theMEInt, |
486 | const TopTools_DataMapOfShapeListOfShape& theDMEETrim, |
487 | const TopTools_IndexedMapOfShape& theMSInv, |
488 | const TopTools_IndexedMapOfShape& theMVE, |
489 | const TopTools_MapOfShape& theVertsToAvoid, |
490 | const TopTools_MapOfShape& theNewVertsToAvoid, |
41aa3c3d |
491 | const TopTools_MapOfShape& theMECheckExt, |
ecf4f17c |
492 | TopTools_MapOfShape& theMVBounds, |
493 | TopTools_DataMapOfShapeListOfShape& theEImages); |
494 | |
495 | static |
496 | void GetInvalidEdges(const TopTools_MapOfShape& theVertsToAvoid, |
497 | const TopTools_MapOfShape& theMVBounds, |
498 | BOPAlgo_Builder& theGF, |
499 | TopTools_MapOfShape& theMEInv); |
500 | |
41aa3c3d |
501 | static |
502 | void UpdateValidEdges(const TopTools_IndexedDataMapOfShapeListOfShape& theFImages, |
ecf4f17c |
503 | const TopTools_IndexedDataMapOfShapeListOfShape& theFLE, |
dcba2e5c |
504 | const TopTools_IndexedDataMapOfShapeListOfShape& theOENEdges, |
ecf4f17c |
505 | const TopTools_MapOfShape& theMVBounds, |
506 | const TopoDS_Shape& theSolids, |
507 | const TopTools_IndexedMapOfShape& theInvEdges, |
508 | const TopTools_MapOfShape& theInvertedEdges, |
a8232603 |
509 | const TopTools_MapOfShape& theMEInvOnArt, |
41aa3c3d |
510 | TopTools_MapOfShape& theMECheckExt, |
ecf4f17c |
511 | TopTools_IndexedMapOfShape& theEdgesToAvoid, |
512 | TopTools_DataMapOfShapeListOfShape& theEdgesOrigins, |
513 | TopTools_DataMapOfShapeListOfShape& theOEImages, |
514 | TopTools_DataMapOfShapeListOfShape& theOEOrigins, |
515 | TopTools_MapOfShape& theVertsToAvoid, |
516 | TopTools_DataMapOfShapeShape& theETrimEInf, |
517 | TopTools_DataMapOfShapeListOfShape& theEImages, |
518 | TopTools_DataMapOfShapeListOfShape& theEETrim, |
519 | TopTools_MapOfShape& theModifiedEdges, |
520 | Handle(BRepAlgo_AsDes)& theAsDes); |
521 | |
522 | static |
523 | void TrimNewIntersectionEdges(const TopTools_ListOfShape& theLE, |
524 | const TopTools_DataMapOfShapeListOfShape& theEETrim, |
525 | const TopTools_MapOfShape& theMVBounds, |
41aa3c3d |
526 | TopTools_MapOfShape& theMECheckExt, |
ecf4f17c |
527 | TopTools_DataMapOfShapeListOfShape& theEImages, |
528 | TopTools_MapOfShape& theMEB, |
529 | TopTools_MapOfShape& theMVOld, |
dcba2e5c |
530 | TopTools_MapOfShape& theMENew, |
41aa3c3d |
531 | TopTools_DataMapOfShapeListOfShape& theDMEOr, |
532 | TopTools_DataMapOfShapeListOfShape& theMELF); |
ecf4f17c |
533 | |
534 | static |
1155d05a |
535 | void IntersectEdges(const TopTools_ListOfShape& theLA, |
ecf4f17c |
536 | const TopTools_ListOfShape& theLE, |
ecf4f17c |
537 | const TopTools_MapOfShape& theMVBounds, |
538 | const TopTools_MapOfShape& theVertsToAvoid, |
dcba2e5c |
539 | TopTools_MapOfShape& theMENew, |
41aa3c3d |
540 | TopTools_MapOfShape& theMECheckExt, |
ecf4f17c |
541 | TopTools_DataMapOfShapeListOfShape& theEImages, |
542 | TopTools_MapOfShape& theModifiedEdges, |
543 | TopTools_DataMapOfShapeListOfShape& theDMEOr, |
41aa3c3d |
544 | TopTools_DataMapOfShapeListOfShape& theMELF, |
ecf4f17c |
545 | TopoDS_Shape& theSplits); |
546 | |
547 | static |
dcba2e5c |
548 | void GetBounds(const TopTools_ListOfShape& theLFaces, |
549 | const TopTools_IndexedDataMapOfShapeListOfShape& theFImages, |
ecf4f17c |
550 | const TopTools_MapOfShape& theMEB, |
551 | TopoDS_Shape& theBounds); |
552 | |
553 | static |
554 | void GetBoundsToUpdate(const TopTools_ListOfShape& theLF, |
555 | const TopTools_DataMapOfShapeListOfShape& theOEImages, |
556 | const TopTools_DataMapOfShapeListOfShape& theOEOrigins, |
557 | const TopTools_MapOfShape& theMEB, |
558 | TopTools_ListOfShape& theLABounds, |
559 | TopTools_ListOfShape& theLAValid, |
560 | TopoDS_Shape& theBounds, |
561 | Handle(BRepAlgo_AsDes)& theAsDes); |
562 | |
563 | static |
564 | void GetInvalidEdgesByBounds(const TopoDS_Shape& theSplits, |
565 | const TopoDS_Shape& theBounds, |
ecf4f17c |
566 | const TopTools_IndexedDataMapOfShapeListOfShape& theFImages, |
567 | const TopoDS_Shape& theSolids, |
568 | const TopTools_IndexedMapOfShape& theInvEdges, |
569 | const TopTools_MapOfShape& theMVOld, |
570 | const TopTools_MapOfShape& theMENew, |
571 | const TopTools_DataMapOfShapeListOfShape& theDMEOr, |
41aa3c3d |
572 | const TopTools_DataMapOfShapeListOfShape& theMELF, |
ecf4f17c |
573 | const TopTools_DataMapOfShapeListOfShape& theEImages, |
41aa3c3d |
574 | const TopTools_MapOfShape& theMECheckExt, |
a8232603 |
575 | const TopTools_MapOfShape& theMEInvOnArt, |
dcba2e5c |
576 | Handle(IntTools_Context)& theCtx, |
ecf4f17c |
577 | TopTools_MapOfShape& theVertsToAvoid, |
578 | TopTools_MapOfShape& theMEInv); |
579 | |
dcba2e5c |
580 | static |
581 | void FilterSplits(const TopTools_ListOfShape& theLE, |
582 | const TopTools_MapOfShape& theMEFilter, |
583 | const Standard_Boolean theIsInv, |
584 | TopTools_DataMapOfShapeListOfShape& theEImages, |
585 | TopoDS_Shape& theSplits); |
586 | |
ecf4f17c |
587 | static |
588 | void UpdateNewIntersectionEdges(const TopTools_ListOfShape& theLE, |
589 | const TopTools_DataMapOfShapeListOfShape& theMELF, |
590 | const TopTools_DataMapOfShapeListOfShape& theEImages, |
591 | const TopTools_IndexedMapOfShape& theInvEdges, |
592 | const TopTools_MapOfShape& theInvertedEdges, |
593 | TopTools_DataMapOfShapeListOfShape& theEdgesOrigins, |
594 | TopTools_DataMapOfShapeListOfShape& theOEImages, |
595 | TopTools_DataMapOfShapeListOfShape& theOEOrigins, |
596 | TopTools_DataMapOfShapeShape& theETrimEInf, |
597 | TopTools_DataMapOfShapeListOfShape& theEETrim, |
598 | TopTools_MapOfShape& theModifiedEdges, |
599 | Handle(BRepAlgo_AsDes)& theAsDes); |
600 | |
2ebb1098 |
601 | static |
602 | void FillGaps(TopTools_IndexedDataMapOfShapeListOfShape& theFImages); |
603 | |
ecf4f17c |
604 | static |
605 | void FillHistory(const TopTools_IndexedDataMapOfShapeListOfShape& theFImages, |
606 | const TopTools_DataMapOfShapeListOfShape& theEImages, |
607 | BRepAlgo_Image& theImage); |
608 | |
609 | static |
610 | void UpdateOrigins(const TopTools_ListOfShape& theLA, |
611 | TopTools_DataMapOfShapeListOfShape& theOrigins, |
612 | BOPAlgo_Builder& theGF); |
613 | |
614 | static |
615 | void UpdateImages(const TopTools_ListOfShape& theLA, |
616 | TopTools_DataMapOfShapeListOfShape& theImages, |
617 | BOPAlgo_Builder& theGF, |
618 | TopTools_MapOfShape& theModified); |
619 | |
620 | static |
621 | void UpdateIntersectedEdges(const TopTools_ListOfShape& theLA, |
622 | TopTools_DataMapOfShapeShape& theETrimEInf, |
623 | BOPAlgo_Builder& theGF); |
624 | |
625 | static |
626 | Standard_Boolean ProcessMicroEdge(const TopoDS_Edge& theEdge, |
627 | const Handle(IntTools_Context)& theCtx); |
628 | |
629 | static |
630 | void FindCommonParts(const TopTools_ListOfShape& theLS1, |
631 | const TopTools_ListOfShape& theLS2, |
632 | TopTools_ListOfShape& theLSC, |
633 | const TopAbs_ShapeEnum theType = TopAbs_EDGE); |
634 | |
635 | static |
636 | Standard_Integer NbPoints(const TopoDS_Edge& theE); |
637 | |
638 | static |
639 | Standard_Boolean FindShape(const TopoDS_Shape& theSWhat, |
640 | const TopoDS_Shape& theSWhere, |
420b38fd |
641 | const BRepOffset_Analyse* theAnalyse, |
ecf4f17c |
642 | TopoDS_Shape& theRes); |
643 | |
644 | static |
645 | void AppendToList(TopTools_ListOfShape& theL, |
646 | const TopoDS_Shape& theS); |
647 | |
e08a9b03 |
648 | template <class ContainerType, class FenceMapType> |
649 | static Standard_Boolean TakeModified(const TopoDS_Shape& theS, |
650 | const TopTools_DataMapOfShapeListOfShape& theImages, |
651 | ContainerType& theMapOut, |
652 | FenceMapType* theMFence); |
653 | |
654 | template <class ContainerType> |
655 | static Standard_Boolean TakeModified(const TopoDS_Shape& theS, |
656 | const TopTools_DataMapOfShapeListOfShape& theImages, |
657 | ContainerType& theMapOut) |
658 | { |
659 | TopTools_MapOfShape* aDummy = NULL; |
660 | return TakeModified (theS, theImages, theMapOut, aDummy); |
661 | } |
662 | |
ecf4f17c |
663 | //======================================================================= |
664 | //function : BuildSplitsOfTrimmedFaces |
665 | //purpose : Building splits of already trimmed faces |
666 | //======================================================================= |
667 | void BRepOffset_MakeOffset::BuildSplitsOfTrimmedFaces(const TopTools_ListOfShape& theLF, |
668 | Handle(BRepAlgo_AsDes)& theAsDes, |
669 | BRepAlgo_Image& theImage) |
670 | { |
671 | TopTools_DataMapOfShapeListOfShape anEImages, anEOrigins; |
672 | TopTools_IndexedDataMapOfShapeListOfShape aDMFFIm; |
673 | TopTools_IndexedMapOfShape anEmptyIM; |
674 | TopTools_DataMapOfShapeListOfShape anEmptyDMSLS; |
675 | TopTools_DataMapOfShapeShape anEmptyDMSS; |
676 | TopTools_MapOfShape aNewEdges, anEmptyM; |
677 | // |
678 | // firstly it is necessary to fuse all the edges |
679 | Handle(IntTools_Context) aCtx = new IntTools_Context(); |
680 | // |
681 | IntersectTrimmedEdges(theLF, theAsDes, anEImages, anEOrigins, anEmptyDMSLS, aCtx, aNewEdges, anEmptyDMSS); |
682 | // |
683 | TopTools_ListIteratorOfListOfShape aItLF(theLF); |
684 | for (; aItLF.More(); aItLF.Next()) { |
685 | const TopoDS_Face& aF = *(TopoDS_Face*)&aItLF.Value(); |
686 | // |
687 | TopoDS_Shape aCE; |
688 | TopTools_ListOfShape aLFImages; |
689 | // |
690 | Standard_Boolean bFound = GetEdges(aF, theAsDes, anEImages, anEmptyM, |
691 | anEmptyIM, aCtx, aNewEdges, aCE, anEmptyIM); |
692 | // split the face by the edges |
693 | if (!bFound) { |
694 | if (!theImage.HasImage(aF)) { |
695 | aLFImages.Append(aF); |
696 | aDMFFIm.Add(aF, aLFImages); |
697 | } |
698 | continue; |
699 | } |
700 | // |
a8232603 |
701 | BuildSplitsOfTrimmedFace(aF, aCE, aLFImages); |
ecf4f17c |
702 | aDMFFIm.Add(aF, aLFImages); |
703 | } |
704 | // Fill history for faces and edges |
705 | FillHistory(aDMFFIm, anEImages, theImage); |
706 | } |
707 | |
708 | //======================================================================= |
709 | //function : BuildSplitsOfExtendedFaces |
710 | //purpose : Building splits of not-trimmed offset faces. |
711 | // For the cases in which invalidity will be found, |
712 | // these invalidities will be rebuilt. |
713 | //======================================================================= |
714 | void BRepOffset_MakeOffset::BuildSplitsOfExtendedFaces(const TopTools_ListOfShape& theLF, |
420b38fd |
715 | const BRepOffset_Analyse& theAnalyse, |
ecf4f17c |
716 | Handle(BRepAlgo_AsDes)& theAsDes, |
717 | TopTools_DataMapOfShapeListOfShape& theEdgesOrigins, |
718 | TopTools_DataMapOfShapeShape& theFacesOrigins, |
719 | TopTools_DataMapOfShapeShape& theETrimEInf, |
720 | BRepAlgo_Image& theImage) |
721 | { |
722 | Handle(IntTools_Context) aCtx = new IntTools_Context(); |
723 | // images and origins for offset edges |
724 | TopTools_DataMapOfShapeListOfShape anOEImages, anOEOrigins; |
725 | TopTools_MapOfShape aNewEdges; |
726 | // fusing all trimmed offset edges to avoid self-intersections in the splits |
727 | IntersectTrimmedEdges(theLF, theAsDes, anOEImages, anOEOrigins, |
728 | theEdgesOrigins, aCtx, aNewEdges, theETrimEInf); |
729 | // |
730 | // valid/invalid edges |
731 | TopTools_IndexedMapOfShape anInvEdges, aValidEdges, anEdgesToAvoid; |
732 | // inverted edges |
733 | TopTools_MapOfShape anInvertedEdges; |
734 | // splits of faces |
735 | TopTools_IndexedDataMapOfShapeListOfShape aFImages; |
736 | // found invalid faces |
737 | TopTools_IndexedDataMapOfShapeListOfShape anInvFaces; |
738 | // artificially invalid faces - it will be empty here, |
739 | // but may be filled on the following rebuilding steps |
740 | TopTools_DataMapOfShapeShape anArtInvFaces; |
741 | // shapes connections for using in rebuilding |
6f04cbb1 |
742 | BRepOffset_MakeOffset_InterResults aIntRes; |
ecf4f17c |
743 | // edges to avoid on second steps |
744 | TopTools_MapOfShape aLastInvEdges; |
745 | // keep information of already invalid faces to avoid |
746 | // infinite rebuilding of the same invalid face |
747 | TopTools_DataMapOfShapeInteger anAlreadyInvFaces; |
0da0275c |
748 | // images of the hole faces of the original faces |
749 | TopTools_DataMapOfShapeListOfShape aDMFNewHoles; |
ecf4f17c |
750 | // solid build from the new splits |
751 | TopoDS_Shape aSolids; |
752 | // now we can split the faces |
420b38fd |
753 | BuildSplitsOfFaces(theLF, aNewEdges, theEdgesOrigins, &theAnalyse, theAsDes, theFacesOrigins, |
ecf4f17c |
754 | anOEImages, anOEOrigins, aLastInvEdges, anEdgesToAvoid, anInvEdges, aValidEdges, |
0da0275c |
755 | anInvertedEdges, anAlreadyInvFaces, anInvFaces, anArtInvFaces, aFImages, |
6f04cbb1 |
756 | aDMFNewHoles, aSolids, aIntRes); |
ecf4f17c |
757 | // |
758 | // Find faces to rebuild |
759 | if (anInvFaces.Extent()) { |
760 | TopTools_IndexedDataMapOfShapeListOfShape aFToRebuild; |
761 | TopTools_MapOfShape aFSelfRebAvoid; |
6f04cbb1 |
762 | FindFacesToRebuild(aFImages, anInvEdges, anInvFaces, aIntRes.SSInterfs, aFToRebuild, aFSelfRebAvoid); |
ecf4f17c |
763 | // |
764 | if (aFToRebuild.Extent()) { |
765 | // vertices to avoid |
766 | TopTools_MapOfShape aVAEmpty; |
6f04cbb1 |
767 | RebuildFaces(aFToRebuild, aFSelfRebAvoid, aSolids, aIntRes, &theAnalyse, aFImages, aDMFNewHoles, |
0da0275c |
768 | theEdgesOrigins, theFacesOrigins, anOEImages, anOEOrigins, aLastInvEdges, |
769 | anEdgesToAvoid, anInvEdges, aValidEdges, anInvertedEdges, anAlreadyInvFaces, |
770 | anInvFaces, anArtInvFaces, aVAEmpty, theETrimEInf, theAsDes); |
ecf4f17c |
771 | } |
772 | } |
2ebb1098 |
773 | |
774 | // Fill possible gaps in the splits of offset faces to increase possibility of |
775 | // creating closed volume from these splits |
776 | FillGaps(aFImages); |
777 | |
ecf4f17c |
778 | // Fill history for faces and edges |
779 | FillHistory(aFImages, anOEImages, theImage); |
780 | } |
781 | |
782 | //======================================================================= |
783 | //function : BuildSplitsOfInvFaces |
784 | //purpose : Rebuilding splits of faces with new intersection edges |
785 | //======================================================================= |
786 | void BuildSplitsOfInvFaces(const TopTools_IndexedDataMapOfShapeListOfShape& theFToRebuild, |
787 | const TopTools_MapOfShape& theModifiedEdges, |
bea10656 |
788 | const BRepOffset_Analyse* theAnalyse, |
ecf4f17c |
789 | TopTools_IndexedDataMapOfShapeListOfShape& theFImages, |
0da0275c |
790 | TopTools_DataMapOfShapeListOfShape& theDMFNewHoles, |
ecf4f17c |
791 | TopTools_DataMapOfShapeListOfShape& theEdgesOrigins, |
792 | TopTools_DataMapOfShapeShape& theFacesOrigins, |
793 | TopTools_DataMapOfShapeListOfShape& theOEImages, |
794 | TopTools_DataMapOfShapeListOfShape& theOEOrigins, |
795 | TopTools_MapOfShape& theLastInvEdges, |
796 | TopTools_IndexedMapOfShape& theEdgesToAvoid, |
797 | TopTools_MapOfShape& theVertsToAvoid, |
798 | TopTools_DataMapOfShapeInteger& theAlreadyInvFaces, |
799 | TopTools_IndexedMapOfShape& theValidEdges, |
800 | TopTools_DataMapOfShapeShape& theETrimEInf, |
801 | Handle(BRepAlgo_AsDes)& theAsDes) |
802 | { |
803 | Standard_Integer aNb = theFToRebuild.Extent(); |
804 | if (!aNb) { |
805 | return; |
806 | } |
807 | // |
808 | TopTools_ListOfShape aLF; |
809 | aNb = theFImages.Extent(); |
810 | for (Standard_Integer i = 1; i <= aNb; ++i) { |
811 | const TopoDS_Shape& aF = theFImages.FindKey(i); |
812 | aLF.Append(aF); |
813 | } |
814 | // |
815 | // invalid faces |
816 | TopTools_IndexedDataMapOfShapeListOfShape anInvFaces; |
817 | // artificially invalid faces |
818 | TopTools_DataMapOfShapeShape anArtInvFaces; |
819 | // invalid edges |
820 | TopTools_IndexedMapOfShape anInvEdges; |
821 | // inverted edges |
822 | TopTools_MapOfShape anInvertedEdges; |
823 | // shapes connection for using in rebuilding process |
6f04cbb1 |
824 | BRepOffset_MakeOffset_InterResults aIntRes; |
ecf4f17c |
825 | // |
826 | TopoDS_Shape aSolids; |
827 | // |
bea10656 |
828 | BuildSplitsOfFaces(aLF, theModifiedEdges, theEdgesOrigins, theAnalyse, theAsDes, theFacesOrigins, |
ecf4f17c |
829 | theOEImages, theOEOrigins, theLastInvEdges, theEdgesToAvoid, anInvEdges, theValidEdges, |
0da0275c |
830 | anInvertedEdges, theAlreadyInvFaces, anInvFaces, anArtInvFaces, theFImages, |
6f04cbb1 |
831 | theDMFNewHoles, aSolids, aIntRes); |
ecf4f17c |
832 | // |
833 | if (anInvFaces.Extent()) { |
834 | TopTools_IndexedDataMapOfShapeListOfShape aFToRebuild; |
835 | TopTools_MapOfShape aFSelfRebAvoid; |
6f04cbb1 |
836 | FindFacesToRebuild(theFImages, anInvEdges, anInvFaces, aIntRes.SSInterfs, aFToRebuild, aFSelfRebAvoid); |
ecf4f17c |
837 | // |
838 | if (aFToRebuild.Extent()) { |
6f04cbb1 |
839 | RebuildFaces(aFToRebuild, aFSelfRebAvoid, aSolids, aIntRes, theAnalyse, theFImages, theDMFNewHoles, |
0da0275c |
840 | theEdgesOrigins, theFacesOrigins, theOEImages, theOEOrigins, theLastInvEdges, |
841 | theEdgesToAvoid, anInvEdges, theValidEdges, anInvertedEdges, theAlreadyInvFaces, |
842 | anInvFaces, anArtInvFaces, theVertsToAvoid, theETrimEInf, theAsDes); |
ecf4f17c |
843 | } |
844 | } |
845 | } |
846 | |
847 | //======================================================================= |
848 | //function : BuildSplitsOfFaces |
849 | //purpose : Building the splits of offset faces and |
850 | // looking for the invalid splits |
851 | //======================================================================= |
852 | void BuildSplitsOfFaces(const TopTools_ListOfShape& theLF, |
853 | const TopTools_MapOfShape& theModifiedEdges, |
854 | const TopTools_DataMapOfShapeListOfShape& theEdgesOrigins, |
420b38fd |
855 | const BRepOffset_Analyse* theAnalyse, |
ecf4f17c |
856 | Handle(BRepAlgo_AsDes)& theAsDes, |
857 | TopTools_DataMapOfShapeShape& theFacesOrigins, |
858 | TopTools_DataMapOfShapeListOfShape& theOEImages, |
859 | TopTools_DataMapOfShapeListOfShape& theOEOrigins, |
860 | TopTools_MapOfShape& theLastInvEdges, |
861 | TopTools_IndexedMapOfShape& theEdgesToAvoid, |
862 | TopTools_IndexedMapOfShape& theInvEdges, |
863 | TopTools_IndexedMapOfShape& theValidEdges, |
864 | TopTools_MapOfShape& theInvertedEdges, |
865 | TopTools_DataMapOfShapeInteger& theAlreadyInvFaces, |
866 | TopTools_IndexedDataMapOfShapeListOfShape& theInvFaces, |
867 | TopTools_DataMapOfShapeShape& theArtInvFaces, |
868 | TopTools_IndexedDataMapOfShapeListOfShape& theFImages, |
0da0275c |
869 | TopTools_DataMapOfShapeListOfShape& theDMFNewHoles, |
ecf4f17c |
870 | TopoDS_Shape& theSolids, |
6f04cbb1 |
871 | BRepOffset_MakeOffset_InterResults& theIntRes) |
ecf4f17c |
872 | { |
873 | if (theLF.IsEmpty()) { |
874 | return; |
875 | } |
876 | // |
877 | BRep_Builder aBB; |
878 | Standard_Integer i, aNb; |
879 | // |
880 | // processed faces |
881 | TopTools_ListOfShape aLFDone; |
9e9b826a |
882 | // extended face - map of neutral edges, i.e. in one split - valid and in other - invalid |
883 | BRepOffset_DataMapOfShapeMapOfShape aDMFMNE; |
884 | // map of valid edges for each face |
885 | BRepOffset_DataMapOfShapeMapOfShape aDMFMVE; |
886 | // map of invalid edges for each face |
887 | BRepOffset_DataMapOfShapeIndexedMapOfShape aDMFMIE; |
ecf4f17c |
888 | // map of valid inverted edges for the face |
9e9b826a |
889 | BRepOffset_DataMapOfShapeMapOfShape aDMFMVIE; |
ecf4f17c |
890 | // map of splits to check for internals |
891 | TopTools_IndexedMapOfShape aMFToCheckInt; |
892 | // map of edges created from vertex and marked as invalid |
893 | TopTools_MapOfShape aMEdgeInvalidByVertex; |
9e9b826a |
894 | // map of edges created from vertex and marked as valid |
895 | TopTools_MapOfShape aMEdgeValidByVertex; |
0da0275c |
896 | // connection map from old edges to new ones |
897 | TopTools_DataMapOfShapeListOfShape aDMEOrLEIm; |
ecf4f17c |
898 | // |
899 | Handle(IntTools_Context) aCtx = new IntTools_Context; |
900 | // build splits of faces |
901 | TopTools_ListIteratorOfListOfShape aItLF(theLF); |
902 | for (; aItLF.More(); aItLF.Next()) { |
903 | const TopoDS_Face& aF = *(TopoDS_Face*)&aItLF.Value(); |
904 | // |
905 | TopTools_ListOfShape* pLFIm = theFImages.ChangeSeek(aF); |
906 | if (pLFIm && pLFIm->IsEmpty()) { |
907 | continue; |
908 | } |
909 | // get edges by which the face should be split |
910 | TopoDS_Shape aCE; |
911 | TopTools_IndexedMapOfShape aMapEInv; |
912 | Standard_Boolean bFound = |
913 | GetEdges(aF, theAsDes, theOEImages, theLastInvEdges, |
914 | theEdgesToAvoid, aCtx, theModifiedEdges, aCE, aMapEInv); |
915 | if (!bFound) { |
916 | continue; |
917 | } |
918 | // |
bc4a3867 |
919 | #ifdef OFFSET_DEBUG |
920 | // check the found edges on self-intersection |
921 | BRepAlgoAPI_Check aChecker(aCE); |
922 | if (!aChecker.IsValid()) |
923 | { |
04232180 |
924 | std::cout << "Offset_i_c Error: set of edges to build faces is self-intersecting\n"; |
bc4a3867 |
925 | } |
926 | #endif |
ecf4f17c |
927 | // build splits |
928 | TopTools_ListOfShape aLFImages; |
a8232603 |
929 | BuildSplitsOfFace(aF, aCE, theFacesOrigins, aLFImages); |
ecf4f17c |
930 | // |
931 | if (aMapEInv.Extent()) { |
932 | // check if all possible faces are built |
933 | TopTools_MapOfShape aMENInv; |
934 | Standard_Boolean bArtificialCase = aLFImages.IsEmpty() || |
935 | CheckIfArtificial(aF, aLFImages, aCE, aMapEInv, theOEImages, aMENInv, theAsDes); |
936 | // |
937 | // try to build splits using invalid edges |
938 | TopoDS_Compound aCE1; |
939 | aBB.MakeCompound(aCE1); |
940 | aBB.Add(aCE1, aCE); |
941 | for (i = 1; i <= aMapEInv.Extent(); ++i) { |
942 | aBB.Add(aCE1, aMapEInv(i)); |
943 | } |
944 | // |
945 | TopTools_ListOfShape aLFImages1; |
a8232603 |
946 | BuildSplitsOfFace(aF, aCE1, theFacesOrigins, aLFImages1); |
ecf4f17c |
947 | // |
b443d536 |
948 | // check if the rebuilding has added some new faces to the splits |
45d0af05 |
949 | for (TopTools_ListIteratorOfListOfShape aItLFIm(aLFImages1); aItLFIm.More();) |
950 | { |
b443d536 |
951 | Standard_Boolean bAllInv = Standard_True; |
ecf4f17c |
952 | const TopoDS_Shape& aFIm = aItLFIm.Value(); |
953 | TopExp_Explorer aExpE(aFIm, TopAbs_EDGE); |
954 | for (; aExpE.More(); aExpE.Next()) { |
955 | const TopoDS_Shape& aE = aExpE.Current(); |
b443d536 |
956 | if (!aMapEInv.Contains(aE)) { |
957 | bAllInv = Standard_False; |
958 | if (!aMENInv.Contains(aE)) { |
959 | break; |
960 | } |
ecf4f17c |
961 | } |
962 | } |
963 | // |
964 | if (!aExpE.More()) { |
965 | if (bAllInv) { |
966 | aMFToCheckInt.Add(aFIm); |
967 | } |
968 | aLFImages1.Remove(aItLFIm); |
969 | } |
970 | else { |
971 | aItLFIm.Next(); |
972 | } |
973 | } |
974 | // |
975 | if (bArtificialCase) { |
976 | if (aLFImages.Extent() == aLFImages1.Extent()) { |
977 | bArtificialCase = Standard_False; |
978 | } |
979 | else { |
980 | aLFImages = aLFImages1; |
981 | } |
982 | } |
983 | // |
984 | if (bArtificialCase) { |
9e9b826a |
985 | TopTools_IndexedMapOfShape aMEInv; |
ecf4f17c |
986 | // make the face invalid |
987 | theArtInvFaces.Bind(aF, aCE); |
988 | // |
989 | *pLFIm = aLFImages; |
990 | TopTools_ListIteratorOfListOfShape aItLFIm(aLFImages); |
991 | for (; aItLFIm.More(); aItLFIm.Next()) { |
992 | const TopoDS_Shape& aFIm = aItLFIm.Value(); |
993 | TopExp_Explorer aExpE(aFIm, TopAbs_EDGE); |
994 | for (; aExpE.More(); aExpE.Next()) { |
995 | const TopoDS_Shape& aE = aExpE.Current(); |
996 | if (aMapEInv.Contains(aE)) { |
997 | theInvEdges.Add(aE); |
9e9b826a |
998 | aMEInv.Add (aE); |
ecf4f17c |
999 | } |
1000 | else { |
1001 | theValidEdges.Add(aE); |
1002 | } |
1003 | } |
1004 | } |
1005 | // |
9e9b826a |
1006 | aDMFMIE.Bind(aF, aMEInv); |
ecf4f17c |
1007 | aLFDone.Append(aF); |
1008 | // |
1009 | continue; |
1010 | } |
1011 | } |
1012 | // |
1013 | // find invalid edges |
420b38fd |
1014 | FindInvalidEdges(aF, aLFImages, theEdgesOrigins, theFacesOrigins, theAnalyse, theOEImages, |
9e9b826a |
1015 | theOEOrigins, theInvEdges, theValidEdges, aDMFMVE, aDMFMNE, aDMFMIE, |
1016 | aDMFMVIE, aDMEOrLEIm, theInvertedEdges, aMEdgeInvalidByVertex, aMEdgeValidByVertex); |
ecf4f17c |
1017 | // |
1018 | // save the new splits |
1019 | if (!pLFIm) { |
1020 | pLFIm = &theFImages(theFImages.Add(aF, TopTools_ListOfShape())); |
1021 | } |
1022 | else { |
1023 | pLFIm->Clear(); |
1024 | } |
1025 | pLFIm->Append(aLFImages); |
1026 | // |
1027 | aLFDone.Append(aF); |
1028 | } |
1029 | // |
9e9b826a |
1030 | if (theInvEdges.IsEmpty() && theArtInvFaces.IsEmpty() && aDMFMIE.IsEmpty()) { |
ecf4f17c |
1031 | return; |
1032 | } |
bea10656 |
1033 | |
1034 | // Additional step to find invalid edges by checking unclassified edges |
1035 | // in the splits of SD faces |
1036 | FindInvalidEdges (aLFDone, theFImages, theFacesOrigins, theAnalyse, |
1037 | theInvEdges, theValidEdges, aDMFMIE, aDMFMVE, aDMFMNE); |
1038 | |
62eafa5a |
1039 | // Additional step to mark inverted edges located inside loops |
1040 | // of invalid edges as invalid as well |
1041 | MakeInvertedEdgesInvalid(aLFDone, theFImages, theInvertedEdges, theInvEdges); |
1042 | |
ecf4f17c |
1043 | #ifdef OFFSET_DEBUG |
1044 | // show invalid edges |
1045 | TopoDS_Compound aCEInv1; |
1046 | BRep_Builder().MakeCompound(aCEInv1); |
1047 | Standard_Integer aNbEInv = theInvEdges.Extent(); |
1048 | for (i = 1; i <= aNbEInv; ++i) { |
1049 | const TopoDS_Shape& aE = theInvEdges(i); |
1050 | BRep_Builder().Add(aCEInv1, aE); |
1051 | } |
baaacd46 |
1052 | // show valid edges |
ecf4f17c |
1053 | TopoDS_Compound aCEVal1; |
1054 | BRep_Builder().MakeCompound(aCEVal1); |
1055 | aNbEInv = theValidEdges.Extent(); |
1056 | for (i = 1; i <= aNbEInv; ++i) { |
1057 | const TopoDS_Shape& aE = theValidEdges(i); |
1058 | BRep_Builder().Add(aCEVal1, aE); |
1059 | } |
baaacd46 |
1060 | // show inverted edges |
1061 | TopoDS_Compound aCEInverted; |
1062 | BRep_Builder().MakeCompound(aCEInverted); |
1063 | TopTools_MapIteratorOfMapOfShape aItM(theInvertedEdges); |
1064 | for (; aItM.More(); aItM.Next()) { |
1065 | BRep_Builder().Add(aCEInverted, aItM.Value()); |
1066 | } |
ecf4f17c |
1067 | #endif |
2ebb1098 |
1068 | |
e08a9b03 |
1069 | #ifdef OFFSET_DEBUG |
1070 | // Show all obtained splits of faces |
1071 | TopoDS_Compound aCFIm1; |
1072 | BRep_Builder().MakeCompound(aCFIm1); |
1073 | #endif |
1074 | |
2ebb1098 |
1075 | // Build Edge-Face connectivity map to find faces which removal |
1076 | // may potentially lead to creation of the holes in the faces |
1077 | // preventing from obtaining closed volume in the result |
1078 | TopTools_IndexedDataMapOfShapeListOfShape anEFMap; |
1079 | const Standard_Integer aNbF = theFImages.Extent(); |
1080 | for (i = 1; i <= aNbF; ++i) |
1081 | { |
1082 | TopTools_ListIteratorOfListOfShape itLFIm(theFImages(i)); |
1083 | for (; itLFIm.More(); itLFIm.Next()) |
e08a9b03 |
1084 | { |
2ebb1098 |
1085 | TopExp::MapShapesAndAncestors(itLFIm.Value(), TopAbs_EDGE, TopAbs_FACE, anEFMap); |
e08a9b03 |
1086 | #ifdef OFFSET_DEBUG |
1087 | BRep_Builder().Add(aCFIm1, itLFIm.Value()); |
1088 | #endif |
1089 | } |
2ebb1098 |
1090 | } |
1091 | |
9e9b826a |
1092 | TopTools_MapOfShape anEmptyMap; |
0da0275c |
1093 | // invalid faces inside the holes |
1094 | TopTools_IndexedMapOfShape aMFInvInHole; |
1095 | // all hole faces |
1096 | TopoDS_Compound aFHoles; |
1097 | aBB.MakeCompound(aFHoles); |
e08a9b03 |
1098 | // Find the faces containing only the inverted edges and the invalid ones |
1099 | TopTools_ListOfShape anInvertedFaces; |
ecf4f17c |
1100 | // find invalid faces |
1101 | // considering faces containing only invalid edges as invalid |
1102 | aItLF.Initialize(aLFDone); |
1103 | for (; aItLF.More(); aItLF.Next()) { |
0da0275c |
1104 | const TopoDS_Face& aF = TopoDS::Face(aItLF.Value()); |
ecf4f17c |
1105 | TopTools_ListOfShape& aLFImages = theFImages.ChangeFromKey(aF); |
1106 | // |
1107 | TopTools_ListOfShape aLFInv; |
1108 | Standard_Boolean bArtificialCase = theArtInvFaces.IsBound(aF); |
1109 | if (bArtificialCase) { |
1110 | aLFInv = aLFImages; |
1111 | } |
9e9b826a |
1112 | else |
1113 | { |
ecf4f17c |
1114 | // neutral edges |
9e9b826a |
1115 | const TopTools_MapOfShape* pMNE = aDMFMNE.ChangeSeek(aF); |
1116 | if (!pMNE) { |
1117 | pMNE = &anEmptyMap; |
ecf4f17c |
1118 | } |
0da0275c |
1119 | // find faces inside holes wires |
1120 | TopTools_MapOfShape aMFHoles; |
1121 | const TopoDS_Face& aFOr = TopoDS::Face(theFacesOrigins.Find(aF)); |
1122 | FindFacesInsideHoleWires(aFOr, aF, aLFImages, theInvertedEdges, |
2ebb1098 |
1123 | aDMEOrLEIm, anEFMap, aMFHoles, theDMFNewHoles, aCtx); |
0da0275c |
1124 | // |
1125 | TopTools_MapIteratorOfMapOfShape aItMH(aMFHoles); |
1126 | for (; aItMH.More(); aItMH.Next()) { |
1127 | aBB.Add(aFHoles, aItMH.Value()); |
1128 | } |
1129 | // |
1130 | // find invalid faces |
9e9b826a |
1131 | FindInvalidFaces(aLFImages, theInvEdges, theValidEdges, aDMFMVE, aDMFMIE, |
1132 | *pMNE, theInvertedEdges, aMEdgeInvalidByVertex, aMEdgeValidByVertex, |
e08a9b03 |
1133 | aMFHoles, aMFInvInHole, aLFInv, anInvertedFaces); |
ecf4f17c |
1134 | } |
1135 | // |
1136 | if (aLFInv.Extent()) { |
1137 | if (theAlreadyInvFaces.IsBound(aF)) { |
1138 | if (theAlreadyInvFaces.Find(aF) > 2) { |
1139 | if (aLFInv.Extent() == aLFImages.Extent() && !bArtificialCase) { |
1140 | aLFImages.Clear(); |
1141 | } |
1142 | // |
1143 | aLFInv.Clear(); |
1144 | } |
1145 | } |
1146 | theInvFaces.Add(aF, aLFInv); |
1147 | } |
1148 | } |
1149 | // |
1150 | if (theInvFaces.IsEmpty()) { |
1151 | theInvEdges.Clear(); |
1152 | return; |
1153 | } |
1154 | // |
1155 | #ifdef OFFSET_DEBUG |
1156 | // show invalid faces |
1157 | TopoDS_Compound aCFInv1; |
1158 | BRep_Builder().MakeCompound(aCFInv1); |
1159 | Standard_Integer aNbFInv = theInvFaces.Extent(); |
1160 | for (i = 1; i <= aNbFInv; ++i) { |
1161 | const TopTools_ListOfShape& aLFInv = theInvFaces(i); |
1162 | TopTools_ListIteratorOfListOfShape aItLFInv(aLFInv); |
1163 | for (; aItLFInv.More(); aItLFInv.Next()) { |
1164 | const TopoDS_Shape& aFIm = aItLFInv.Value(); |
1165 | BRep_Builder().Add(aCFInv1, aFIm); |
1166 | } |
1167 | } |
1168 | #endif |
1169 | // |
1170 | TopTools_IndexedMapOfShape aMERemoved; |
1171 | // remove invalid splits of faces using inverted edges |
baaacd46 |
1172 | RemoveInvalidSplitsByInvertedEdges(theInvertedEdges, theOEOrigins, |
1173 | theInvFaces, theFImages, aMERemoved); |
ecf4f17c |
1174 | if (theInvFaces.IsEmpty()) { |
1175 | theInvEdges.Clear(); |
1176 | return; |
1177 | } |
1178 | // |
1179 | // remove invalid splits from valid splits |
9e9b826a |
1180 | RemoveInvalidSplitsFromValid (theInvFaces, theArtInvFaces, theInvertedEdges, |
1181 | aDMFMVIE, theFImages); |
ecf4f17c |
1182 | // |
1183 | // remove inside faces |
baaacd46 |
1184 | TopTools_IndexedMapOfShape aMEInside; |
e08a9b03 |
1185 | RemoveInsideFaces(theFImages, theInvFaces, theArtInvFaces, theInvEdges, theInvertedEdges, |
6f04cbb1 |
1186 | anInvertedFaces, aMFToCheckInt, aMFInvInHole, aFHoles, theIntRes, |
0da0275c |
1187 | aMERemoved, aMEInside, theSolids); |
ecf4f17c |
1188 | // |
1189 | // make compound of valid splits |
1190 | TopoDS_Compound aCFIm; |
1191 | aBB.MakeCompound(aCFIm); |
1192 | // |
1193 | aNb = theFImages.Extent(); |
1194 | for (i = 1; i <= aNb; ++i) { |
1195 | const TopTools_ListOfShape& aLFIm = theFImages(i); |
1196 | aItLF.Initialize(aLFIm); |
1197 | for (; aItLF.More(); aItLF.Next()) { |
1198 | const TopoDS_Shape& aFIm = aItLF.Value(); |
1199 | aBB.Add(aCFIm, aFIm); |
1200 | } |
1201 | } |
1202 | // |
baaacd46 |
1203 | TopTools_IndexedDataMapOfShapeListOfShape aDMEF; |
1204 | TopExp::MapShapesAndAncestors(aCFIm, TopAbs_EDGE, TopAbs_FACE, aDMEF); |
ecf4f17c |
1205 | // |
1206 | // filter maps of images and origins |
1207 | FilterEdgesImages(aCFIm, theOEImages, theOEOrigins); |
1208 | // |
1209 | // filter invalid faces |
9e9b826a |
1210 | FilterInvalidFaces(theFImages, aDMEF, theInvEdges, aMEInside, theInvFaces, theArtInvFaces); |
ecf4f17c |
1211 | aNb = theInvFaces.Extent(); |
1212 | if (!aNb) { |
1213 | theInvEdges.Clear(); |
1214 | return; |
1215 | } |
1216 | // |
1217 | #ifdef OFFSET_DEBUG |
1218 | // show invalid faces |
1219 | TopoDS_Compound aCFInv; |
1220 | BRep_Builder().MakeCompound(aCFInv); |
1221 | aNbFInv = theInvFaces.Extent(); |
1222 | for (i = 1; i <= aNbFInv; ++i) { |
1223 | const TopTools_ListOfShape& aLFInv = theInvFaces(i); |
1224 | TopTools_ListIteratorOfListOfShape aItLFInv(aLFInv); |
1225 | for (; aItLFInv.More(); aItLFInv.Next()) { |
1226 | const TopoDS_Shape& aFIm = aItLFInv.Value(); |
1227 | BRep_Builder().Add(aCFInv, aFIm); |
1228 | } |
1229 | } |
1230 | #endif |
1231 | // |
1232 | // filter invalid edges |
9e9b826a |
1233 | FilterInvalidEdges(theInvFaces, theArtInvFaces, aDMFMIE, aMERemoved, theInvEdges); |
ecf4f17c |
1234 | // |
4b59685a |
1235 | // Check additionally validity of edges originated from vertices. |
1236 | CheckEdgesCreatedByVertex (theInvFaces, theArtInvFaces, theEdgesOrigins, |
1237 | theValidEdges, theEdgesToAvoid); |
1238 | |
ecf4f17c |
1239 | #ifdef OFFSET_DEBUG |
1240 | // show invalid edges |
1241 | TopoDS_Compound aCEInv; |
1242 | BRep_Builder().MakeCompound(aCEInv); |
1243 | aNbEInv = theInvEdges.Extent(); |
1244 | for (i = 1; i <= aNbEInv; ++i) { |
1245 | const TopoDS_Shape& aE = theInvEdges(i); |
1246 | BRep_Builder().Add(aCEInv, aE); |
1247 | } |
1248 | #endif |
1249 | // |
1250 | theLastInvEdges.Clear(); |
1251 | aNb = theInvEdges.Extent(); |
1252 | for (i = 1; i <= aNb; ++i) { |
1253 | const TopoDS_Shape& aE = theInvEdges(i); |
1254 | theEdgesToAvoid.Add(aE); |
1255 | theLastInvEdges.Add(aE); |
1256 | } |
1257 | // |
1258 | aNb = theInvFaces.Extent(); |
1259 | for (i = 1; i <= aNb; ++i) { |
1260 | const TopoDS_Shape& aF = theInvFaces.FindKey(i); |
1261 | if (theAlreadyInvFaces.IsBound(aF)) { |
1262 | theAlreadyInvFaces.ChangeFind(aF)++; |
1263 | } |
1264 | else { |
1265 | theAlreadyInvFaces.Bind(aF, 1); |
1266 | } |
1267 | } |
1268 | } |
1269 | |
1270 | //======================================================================= |
1271 | //function : IntersectTrimmedEdges |
1272 | //purpose : Intersection of the trimmed edges among themselves |
1273 | //======================================================================= |
1274 | void IntersectTrimmedEdges(const TopTools_ListOfShape& theLF, |
1275 | const Handle(BRepAlgo_AsDes)& theAsDes, |
1276 | TopTools_DataMapOfShapeListOfShape& theOEImages, |
1277 | TopTools_DataMapOfShapeListOfShape& theOEOrigins, |
1278 | TopTools_DataMapOfShapeListOfShape& theEdgesOrigins, |
1279 | Handle(IntTools_Context)& theCtx, |
1280 | TopTools_MapOfShape& theNewEdges, |
1281 | TopTools_DataMapOfShapeShape& theETrimEInf) |
1282 | { |
1283 | if (theLF.IsEmpty()) { |
1284 | return; |
1285 | } |
1286 | // |
1287 | // get edges to intersect from descendants of the offset faces |
1155d05a |
1288 | TopTools_ListOfShape aLS; |
ecf4f17c |
1289 | // |
1290 | TopTools_ListIteratorOfListOfShape aItLF(theLF); |
1291 | for (; aItLF.More(); aItLF.Next()) { |
1292 | const TopoDS_Face& aF = *(TopoDS_Face*)&aItLF.Value(); |
1293 | // |
1294 | const TopTools_ListOfShape& aLE = theAsDes->Descendant(aF); |
1295 | TopTools_ListIteratorOfListOfShape aItLE(aLE); |
1296 | for (; aItLE.More(); aItLE.Next()) { |
1297 | const TopoDS_Edge& aE = *(TopoDS_Edge*)&aItLE.Value(); |
1298 | // |
1299 | if (ProcessMicroEdge(aE, theCtx)) { |
1300 | continue; |
1301 | } |
1302 | // |
1303 | if (theNewEdges.Add(aE)) { |
1304 | aLS.Append(aE); |
1305 | } |
1306 | } |
1307 | } |
1308 | // |
1309 | if (aLS.Extent() < 2) { |
1310 | // nothing to intersect |
1311 | return; |
1312 | } |
1313 | // |
1314 | // perform intersection of the edges |
1315 | BOPAlgo_Builder aGFE; |
1316 | aGFE.SetArguments(aLS); |
1317 | aGFE.Perform(); |
33ba8565 |
1318 | if (aGFE.HasErrors()) { |
ecf4f17c |
1319 | return; |
1320 | } |
1321 | // |
1322 | TopTools_ListOfShape aLA; |
1323 | // fill map with edges images |
1155d05a |
1324 | TopTools_ListIteratorOfListOfShape aIt(aLS); |
ecf4f17c |
1325 | for (; aIt.More(); aIt.Next()) { |
1326 | const TopoDS_Shape& aE = aIt.Value(); |
1327 | const TopTools_ListOfShape& aLEIm = aGFE.Modified(aE); |
1328 | if (aLEIm.IsEmpty()) { |
1329 | continue; |
1330 | } |
1331 | // |
1332 | aLA.Append(aE); |
1333 | // save images |
1334 | theOEImages.Bind(aE, aLEIm); |
1335 | // save origins |
1336 | TopTools_ListIteratorOfListOfShape aItLE(aLEIm); |
1337 | for (; aItLE.More(); aItLE.Next()) { |
1338 | const TopoDS_Shape& aEIm = aItLE.Value(); |
1339 | TopTools_ListOfShape* pLEOr = theOEOrigins.ChangeSeek(aEIm); |
1340 | if (!pLEOr) { |
1341 | pLEOr = theOEOrigins.Bound(aEIm, TopTools_ListOfShape()); |
1342 | } |
1343 | AppendToList(*pLEOr, aE); |
1344 | } |
1345 | } |
1346 | // |
1347 | UpdateOrigins(aLA, theEdgesOrigins, aGFE); |
1348 | UpdateIntersectedEdges(aLA, theETrimEInf, aGFE); |
1349 | } |
1350 | |
1351 | //======================================================================= |
1352 | //function : GetEdges |
1353 | //purpose : Getting edges from AsDes map to build the splits of faces |
1354 | //======================================================================= |
1355 | Standard_Boolean GetEdges(const TopoDS_Face& theFace, |
1356 | const Handle(BRepAlgo_AsDes)& theAsDes, |
1357 | const TopTools_DataMapOfShapeListOfShape& theEImages, |
1358 | const TopTools_MapOfShape& theLastInvEdges, |
1359 | const TopTools_IndexedMapOfShape& theInvEdges, |
1360 | Handle(IntTools_Context)& theCtx, |
1361 | const TopTools_MapOfShape& theModifiedEdges, |
1362 | TopoDS_Shape& theEdges, |
1363 | TopTools_IndexedMapOfShape& theInv) |
1364 | { |
1365 | // get boundary edges |
1366 | TopTools_MapOfShape aMFBounds; |
1367 | TopExp_Explorer aExp(theFace, TopAbs_EDGE); |
1368 | for (; aExp.More(); aExp.Next()) { |
1369 | const TopoDS_Shape& aE = aExp.Current(); |
1370 | const TopTools_ListOfShape* pLEIm = theEImages.Seek(aE); |
1371 | if (!pLEIm) { |
1372 | aMFBounds.Add(aE); |
1373 | } |
1374 | else { |
1375 | TopTools_ListIteratorOfListOfShape aItLE(*pLEIm); |
1376 | for (; aItLE.More(); aItLE.Next()) { |
1377 | const TopoDS_Shape& aEIm = aItLE.Value(); |
1378 | aMFBounds.Add(aEIm); |
1379 | } |
1380 | } |
1381 | } |
1382 | // |
1383 | BRep_Builder aBB; |
1384 | Standard_Boolean bFound(Standard_False), bUpdate(Standard_False); |
1385 | // the resulting edges |
1386 | TopoDS_Compound anEdges; |
1387 | aBB.MakeCompound(anEdges); |
bc4a3867 |
1388 | // Fence map |
1389 | TopTools_MapOfShape aMEFence; |
ecf4f17c |
1390 | // the edges by which the offset face should be split |
1391 | const TopTools_ListOfShape& aLE = theAsDes->Descendant(theFace); |
1392 | TopTools_ListIteratorOfListOfShape aItLE(aLE); |
1393 | for (; aItLE.More(); aItLE.Next()) { |
1394 | const TopoDS_Edge& aE = TopoDS::Edge(aItLE.Value()); |
1395 | // |
1396 | if (!bUpdate) { |
1397 | bUpdate = theModifiedEdges.Contains(aE); |
1398 | } |
1399 | // |
1400 | const TopTools_ListOfShape* pLEIm = theEImages.Seek(aE); |
1401 | if (pLEIm) { |
1402 | TopTools_ListIteratorOfListOfShape aItLEIm(*pLEIm); |
1403 | for (; aItLEIm.More(); aItLEIm.Next()) { |
1404 | const TopoDS_Edge& aEIm = TopoDS::Edge(aItLEIm.Value()); |
1405 | // |
bc4a3867 |
1406 | if (!aMEFence.Add(aEIm)) |
1407 | continue; |
1408 | |
ecf4f17c |
1409 | if (theInvEdges.Contains(aEIm)) { |
1410 | theInv.Add(aEIm); |
1411 | if (!bUpdate) { |
1412 | bUpdate = theLastInvEdges.Contains(aEIm); |
1413 | } |
1414 | continue; |
1415 | } |
1416 | // check for micro edge |
1417 | if (ProcessMicroEdge(aEIm, theCtx)) { |
1418 | continue; |
1419 | } |
1420 | // |
1421 | aBB.Add(anEdges, aEIm); |
1422 | if (!bFound) { |
1423 | bFound = !aMFBounds.Contains(aEIm); |
1424 | } |
1425 | // |
1426 | if (!bUpdate) { |
1427 | bUpdate = theModifiedEdges.Contains(aEIm); |
1428 | } |
1429 | } |
1430 | } |
1431 | else { |
1432 | if (theInvEdges.Contains(aE)) { |
1433 | theInv.Add(aE); |
1434 | if (!bUpdate) { |
1435 | bUpdate = theLastInvEdges.Contains(aE); |
1436 | } |
1437 | continue; |
1438 | } |
1439 | // |
1440 | if (ProcessMicroEdge(aE, theCtx)) { |
1441 | continue; |
1442 | } |
1443 | aBB.Add(anEdges, aE); |
1444 | if (!bFound) { |
1445 | bFound = !aMFBounds.Contains(aE); |
1446 | } |
1447 | } |
1448 | } |
1449 | // |
1450 | theEdges = anEdges; |
1451 | return bFound && bUpdate; |
1452 | } |
1453 | |
1454 | //======================================================================= |
1455 | //function : BuildSplitsOfFace |
1456 | //purpose : Building the splits of offset face |
1457 | //======================================================================= |
1458 | void BuildSplitsOfFace(const TopoDS_Face& theFace, |
1459 | const TopoDS_Shape& theEdges, |
ecf4f17c |
1460 | TopTools_DataMapOfShapeShape& theFacesOrigins, |
1461 | TopTools_ListOfShape& theLFImages) |
a8232603 |
1462 | { |
1463 | theLFImages.Clear(); |
1464 | // |
1465 | // take edges to split the face |
1155d05a |
1466 | TopTools_ListOfShape aLE; |
a8232603 |
1467 | TopExp_Explorer aExp(theEdges, TopAbs_EDGE); |
1468 | for (; aExp.More(); aExp.Next()) { |
1469 | TopoDS_Edge aE = TopoDS::Edge(aExp.Current()); |
1470 | aE.Orientation(TopAbs_FORWARD); |
1471 | aLE.Append(aE); |
1472 | aE.Orientation(TopAbs_REVERSED); |
1473 | aLE.Append(aE); |
1474 | } |
1475 | // |
1476 | TopoDS_Face aFF = theFace; |
1477 | TopAbs_Orientation anOr = theFace.Orientation(); |
1478 | aFF.Orientation(TopAbs_FORWARD); |
1479 | // |
1480 | // build pcurves for edges on the face |
f16a6cc5 |
1481 | BRepLib::BuildPCurveForEdgesOnPlane(aLE, aFF); |
a8232603 |
1482 | // |
1483 | // build splits of faces |
1484 | BOPAlgo_BuilderFace aBF; |
1485 | aBF.SetFace(aFF); |
1486 | aBF.SetShapes(aLE); |
1487 | aBF.Perform(); |
1488 | // |
1155d05a |
1489 | const TopTools_ListOfShape& aLFSp = aBF.Areas(); |
1490 | TopTools_ListIteratorOfListOfShape aItLF(aLFSp); |
a8232603 |
1491 | for (; aItLF.More(); aItLF.Next()) { |
1492 | TopoDS_Shape& aFSp = aItLF.ChangeValue(); |
1493 | aFSp.Orientation(anOr); |
1494 | theLFImages.Append(aFSp); |
1495 | // |
1496 | theFacesOrigins.Bind(aFSp, theFace); |
1497 | } |
1498 | } |
1499 | |
1500 | //======================================================================= |
1501 | //function : BuildSplitsOfFace |
1502 | //purpose : Building the splits of offset face |
1503 | //======================================================================= |
1504 | void BuildSplitsOfTrimmedFace(const TopoDS_Face& theFace, |
1505 | const TopoDS_Shape& theEdges, |
1506 | TopTools_ListOfShape& theLFImages) |
ecf4f17c |
1507 | { |
1508 | BOPAlgo_Builder aGF; |
1509 | // |
1510 | aGF.AddArgument(theFace); |
1511 | aGF.AddArgument(theEdges); |
1512 | aGF.Perform(); |
33ba8565 |
1513 | if (aGF.HasErrors()) { |
ecf4f17c |
1514 | return; |
1515 | } |
1516 | // |
1517 | // splits of the offset shape |
1518 | theLFImages = aGF.Modified(theFace); |
ecf4f17c |
1519 | } |
1520 | |
1521 | //======================================================================= |
1522 | //function : CheckIfArtificial |
1523 | //purpose : Checks if the face is artificially invalid |
1524 | //======================================================================= |
1525 | Standard_Boolean CheckIfArtificial(const TopoDS_Shape& theF, |
1526 | const TopTools_ListOfShape& theLFImages, |
1527 | const TopoDS_Shape& theCE, |
1528 | const TopTools_IndexedMapOfShape& theMapEInv, |
1529 | const TopTools_DataMapOfShapeListOfShape& theOEImages, |
1530 | TopTools_MapOfShape& theMENInv, |
1531 | Handle(BRepAlgo_AsDes)& theAsDes) |
1532 | { |
1533 | // all boundary edges should be used |
1534 | TopTools_IndexedMapOfShape aMEUsed; |
1535 | TopTools_ListIteratorOfListOfShape aItLFIm(theLFImages); |
1536 | for (; aItLFIm.More(); aItLFIm.Next()) { |
1537 | const TopoDS_Shape& aFIm = aItLFIm.Value(); |
1538 | TopExp::MapShapes(aFIm, TopAbs_EDGE, aMEUsed); |
1539 | TopExp::MapShapes(aFIm, TopAbs_VERTEX, aMEUsed); |
1540 | } |
1541 | // |
1542 | TopTools_IndexedDataMapOfShapeListOfShape aMVE; |
1543 | TopExp::MapShapesAndAncestors(theCE, TopAbs_VERTEX, TopAbs_EDGE, aMVE); |
1544 | // |
1545 | Standard_Integer i, aNb = theMapEInv.Extent(); |
1546 | for (i = 1; i <= aNb; ++i) { |
1547 | const TopoDS_Shape& aEInv = theMapEInv(i); |
1548 | TopExp_Explorer aExpV(aEInv, TopAbs_VERTEX); |
1549 | for (; aExpV.More(); aExpV.Next()) { |
1550 | const TopoDS_Shape& aVEInv = aExpV.Current(); |
b443d536 |
1551 | const TopTools_ListOfShape* pLENInv = aMVE.Seek(aVEInv); |
1552 | if (pLENInv) { |
1553 | TopTools_ListIteratorOfListOfShape aItLEInv(*pLENInv); |
ecf4f17c |
1554 | for (; aItLEInv.More(); aItLEInv.Next()) { |
1555 | const TopoDS_Shape& aENInv = aItLEInv.Value(); |
b443d536 |
1556 | if (!aMEUsed.Contains(aENInv)) { |
1557 | theMENInv.Add(aENInv); |
1558 | } |
ecf4f17c |
1559 | } |
1560 | } |
1561 | } |
1562 | } |
1563 | // |
1564 | if (theMENInv.IsEmpty()) { |
1565 | return Standard_False; |
1566 | } |
1567 | // |
1568 | TopTools_IndexedMapOfShape aMEFound; |
1569 | TopExp::MapShapes(theCE, TopAbs_EDGE, aMEFound); |
1570 | // |
1571 | const TopTools_ListOfShape& aLE = theAsDes->Descendant(theF); |
1572 | TopTools_ListIteratorOfListOfShape aItLE(aLE); |
1573 | for (; aItLE.More(); aItLE.Next()) { |
1574 | const TopoDS_Edge& aE = TopoDS::Edge(aItLE.Value()); |
1575 | // |
1576 | if (theOEImages.IsBound(aE)) { |
1577 | Standard_Boolean bChecked = Standard_False; |
1578 | const TopTools_ListOfShape& aLEIm = theOEImages.Find(aE); |
1579 | TopTools_ListIteratorOfListOfShape aItLEIm(aLEIm); |
1580 | for (; aItLEIm.More(); aItLEIm.Next()) { |
1581 | const TopoDS_Edge& aEIm = TopoDS::Edge(aItLEIm.Value()); |
1582 | if (!aMEFound.Contains(aEIm) || theMENInv.Contains(aEIm)) { |
1583 | continue; |
1584 | } |
1585 | // |
1586 | bChecked = Standard_True; |
1587 | if (aMEUsed.Contains(aEIm)) { |
1588 | break; |
1589 | } |
1590 | } |
1591 | // |
1592 | if (bChecked && !aItLEIm.More()) { |
1593 | break; |
1594 | } |
1595 | } |
1596 | else { |
1597 | if (aMEFound.Contains(aE) && !theMENInv.Contains(aE) && !aMEUsed.Contains(aE)) { |
1598 | break; |
1599 | } |
1600 | } |
1601 | } |
1602 | // |
1603 | return aItLE.More(); |
1604 | } |
1605 | |
1606 | //======================================================================= |
1607 | //function : FindInvalidEdges |
1608 | //purpose : Looking for the invalid edges |
1609 | //======================================================================= |
1610 | void FindInvalidEdges(const TopoDS_Face& theF, |
1611 | const TopTools_ListOfShape& theLFImages, |
1612 | const TopTools_DataMapOfShapeListOfShape& theEdgesOrigins, |
1613 | const TopTools_DataMapOfShapeShape& theFacesOrigins, |
420b38fd |
1614 | const BRepOffset_Analyse* theAnalyse, |
ecf4f17c |
1615 | const TopTools_DataMapOfShapeListOfShape& theOEImages, |
1616 | const TopTools_DataMapOfShapeListOfShape& theOEOrigins, |
1617 | TopTools_IndexedMapOfShape& theInvEdges, |
1618 | TopTools_IndexedMapOfShape& theValidEdges, |
9e9b826a |
1619 | BRepOffset_DataMapOfShapeMapOfShape& theDMFMVE, |
1620 | BRepOffset_DataMapOfShapeMapOfShape& theDMFMNE, |
1621 | BRepOffset_DataMapOfShapeIndexedMapOfShape& theDMFMIE, |
1622 | BRepOffset_DataMapOfShapeMapOfShape& theDMFMVIE, |
0da0275c |
1623 | TopTools_DataMapOfShapeListOfShape& theDMEOrLEIm, |
ecf4f17c |
1624 | TopTools_MapOfShape& theMEInverted, |
9e9b826a |
1625 | TopTools_MapOfShape& theEdgesInvalidByVertex, |
1626 | TopTools_MapOfShape& theEdgesValidByVertex) |
ecf4f17c |
1627 | { |
1628 | // Edge is considered as invalid in the following cases: |
1629 | // 1. Its orientation on the face has changed comparing to the originals edge and face; |
1630 | // 2. The vertices of the edge have changed places comparing to the originals edge and face. |
1631 | // |
1632 | // The edges created from vertices, i.e. as intersection between two faces connected only |
1633 | // by VERTEX, will also be checked on validity. For these edges the correct orientation will |
1634 | // be defined by the edges on the original face adjacent to the connection vertex |
0da0275c |
1635 | |
1636 | // original face |
ecf4f17c |
1637 | const TopoDS_Face& aFOr = *(TopoDS_Face*)&theFacesOrigins.Find(theF); |
b443d536 |
1638 | // invalid edges |
ecf4f17c |
1639 | TopTools_IndexedMapOfShape aMEInv; |
1640 | // valid edges |
1641 | TopTools_MapOfShape aMEVal; |
1642 | // internal edges |
1643 | TopTools_MapOfShape aMEInt; |
1644 | // |
1645 | // maps for checking the inverted edges |
1646 | TopTools_IndexedDataMapOfShapeListOfShape aDMVE, aDMEF; |
1647 | TopTools_IndexedMapOfShape aMEdges; |
9e9b826a |
1648 | // back map from the original shapes to their offset images |
1649 | TopTools_DataMapOfShapeListOfShape anImages; |
ecf4f17c |
1650 | // |
1651 | TopTools_ListIteratorOfListOfShape aItLF(theLFImages); |
1652 | for (; aItLF.More(); aItLF.Next()) { |
1653 | const TopoDS_Face& aFIm = *(TopoDS_Face*)&aItLF.Value(); |
1654 | // |
1655 | TopExp_Explorer aExp(aFIm, TopAbs_EDGE); |
1656 | for (; aExp.More(); aExp.Next()) { |
1657 | const TopoDS_Shape& aE = aExp.Current(); |
1658 | // keep all edges |
1659 | aMEdges.Add(aE); |
1660 | // |
1661 | // keep connection from edges to faces |
1662 | TopTools_ListOfShape* pLF = aDMEF.ChangeSeek(aE); |
1663 | if (!pLF) { |
1664 | pLF = &aDMEF(aDMEF.Add(aE, TopTools_ListOfShape())); |
1665 | } |
1666 | AppendToList(*pLF, aFIm); |
1667 | // |
1668 | // keep connection from vertices to edges |
1669 | TopoDS_Iterator aItV(aE); |
1670 | for (; aItV.More(); aItV.Next()) { |
1671 | const TopoDS_Shape& aV = aItV.Value(); |
1672 | // |
1673 | TopTools_ListOfShape* pLE = aDMVE.ChangeSeek(aV); |
1674 | if (!pLE) { |
1675 | pLE = &aDMVE(aDMVE.Add(aV, TopTools_ListOfShape())); |
1676 | } |
1677 | AppendToList(*pLE, aE); |
1678 | } |
9e9b826a |
1679 | |
1680 | // back map from original edges to their offset images |
1681 | const TopTools_ListOfShape* pLOr = theEdgesOrigins.Seek (aE); |
1682 | if (!pLOr) |
1683 | continue; |
1684 | for (TopTools_ListOfShape::Iterator itOr (*pLOr); itOr.More(); itOr.Next()) |
1685 | { |
1686 | const TopoDS_Shape& aSOr = itOr.Value(); |
1687 | TopoDS_Shape aSInF; |
1688 | if (!FindShape (aSOr, aFOr, theAnalyse, aSInF)) |
1689 | continue; |
1690 | TopTools_ListOfShape* pImages = anImages.ChangeSeek (aSInF); |
1691 | if (!pImages) |
1692 | pImages = anImages.Bound (aSInF, TopTools_ListOfShape()); |
1693 | AppendToList (*pImages, aE); |
1694 | } |
ecf4f17c |
1695 | } |
1696 | } |
1697 | // |
1698 | // the map will be used to find the edges on the original face |
1699 | // adjacent to the same vertex. It will be filled at first necessity; |
1700 | TopTools_IndexedDataMapOfShapeListOfShape aDMVEFOr; |
1701 | // |
1702 | aItLF.Initialize(theLFImages); |
1703 | for (; aItLF.More(); aItLF.Next()) { |
1704 | const TopoDS_Face& aFIm = *(TopoDS_Face*)&aItLF.Value(); |
1705 | // |
1706 | // valid edges for this split |
9e9b826a |
1707 | TopTools_MapOfShape aMVE; |
ecf4f17c |
1708 | // invalid edges for this split |
9e9b826a |
1709 | TopTools_IndexedMapOfShape aMIE; |
ecf4f17c |
1710 | // |
1711 | TopExp_Explorer aExp(aFIm, TopAbs_EDGE); |
1712 | for (; aExp.More(); aExp.Next()) { |
1713 | const TopoDS_Edge& aEIm = *(TopoDS_Edge*)&aExp.Current(); |
1714 | // |
1715 | if (aEIm.Orientation() == TopAbs_INTERNAL) { |
1716 | aMEInt.Add(aEIm); |
1717 | continue; |
1718 | } |
1719 | // |
1720 | if (!theEdgesOrigins.IsBound(aEIm)) { |
1721 | continue; |
1722 | } |
1723 | // |
1724 | const TopTools_ListOfShape& aLEOr = theEdgesOrigins.Find(aEIm); |
1725 | if (aLEOr.IsEmpty()) { |
1726 | continue; |
1727 | } |
1728 | // |
1729 | Standard_Integer aNbVOr = 0; |
1730 | TopTools_ListIteratorOfListOfShape aItLEO(aLEOr); |
1731 | for (; aItLEO.More(); aItLEO.Next()) { |
1732 | if (aItLEO.Value().ShapeType() == TopAbs_VERTEX) { |
1733 | ++aNbVOr; |
1734 | } |
1735 | } |
9e9b826a |
1736 | if (aNbVOr > 1 && (aLEOr.Extent() - aNbVOr) > 1) |
1737 | continue; |
ecf4f17c |
1738 | // |
420b38fd |
1739 | TopTools_MapOfShape aME, aMV, aMF; |
ecf4f17c |
1740 | Standard_Boolean bInvalid = Standard_False, bChecked = Standard_False; |
420b38fd |
1741 | Standard_Integer aNbP = NbPoints(aEIm), aNbInv = 0; |
b443d536 |
1742 | Standard_Boolean bUseVertex = !aNbVOr ? Standard_False : |
1743 | (aNbVOr == 1 && |
1744 | aDMEF.FindFromKey(aEIm).Extent() == 1 && |
1745 | !theOEOrigins.IsBound(aEIm)); |
1746 | // |
ecf4f17c |
1747 | aItLEO.Initialize(aLEOr); |
1748 | for (; aItLEO.More(); aItLEO.Next()) { |
1749 | const TopoDS_Shape& aSOr = aItLEO.Value(); |
1750 | Standard_Boolean bVertex = (aSOr.ShapeType() == TopAbs_VERTEX); |
1751 | // |
1752 | TopoDS_Shape aEOrF; |
1753 | if (bVertex) { |
1754 | // for some cases it is impossible to check the validity of the edge |
b443d536 |
1755 | if (!bUseVertex) { |
ecf4f17c |
1756 | continue; |
1757 | } |
ecf4f17c |
1758 | // find edges on the original face adjacent to this vertex |
1759 | if (aDMVEFOr.IsEmpty()) { |
1760 | // fill the map |
1761 | TopExp::MapShapesAndAncestors(aFOr, TopAbs_VERTEX, TopAbs_EDGE, aDMVEFOr); |
1762 | } |
1763 | // |
1764 | TopTools_ListOfShape *pLEFOr = aDMVEFOr.ChangeSeek(aSOr); |
1765 | if (pLEFOr) { |
1766 | TopoDS_Compound aCEOr; |
1767 | BRep_Builder().MakeCompound(aCEOr); |
9e9b826a |
1768 | // Avoid classification of edges originated from vertices |
1769 | // located between tangent edges |
1770 | Standard_Boolean bAllTgt = Standard_True; |
ecf4f17c |
1771 | TopTools_ListIteratorOfListOfShape aItLEFOr(*pLEFOr); |
9e9b826a |
1772 | gp_Vec aVRef = GetAverageTangent (aItLEFOr.Value(), aNbP); |
1773 | for (; aItLEFOr.More(); aItLEFOr.Next()) |
1774 | { |
ecf4f17c |
1775 | const TopoDS_Shape& aEOr = aItLEFOr.Value(); |
1776 | BRep_Builder().Add(aCEOr, aEOr); |
9e9b826a |
1777 | |
1778 | gp_Vec aVCur = GetAverageTangent (aEOr, aNbP); |
1779 | if (!aVRef.IsParallel (aVCur, Precision::Angular())) |
1780 | bAllTgt = Standard_False; |
ecf4f17c |
1781 | } |
9e9b826a |
1782 | if (!bAllTgt) |
1783 | aEOrF = aCEOr; |
ecf4f17c |
1784 | } |
1785 | } |
1786 | else { |
420b38fd |
1787 | FindShape(aSOr, aFOr, theAnalyse, aEOrF); |
0da0275c |
1788 | // |
1789 | TopTools_ListOfShape *pLEIm = theDMEOrLEIm.ChangeSeek(aSOr); |
1790 | if (!pLEIm) { |
1791 | pLEIm = theDMEOrLEIm.Bound(aSOr, TopTools_ListOfShape()); |
1792 | } |
1793 | AppendToList(*pLEIm, aEIm); |
ecf4f17c |
1794 | } |
1795 | // |
1796 | if (aEOrF.IsNull()) { |
1797 | // the edge has not been found |
1798 | continue; |
1799 | } |
9e9b826a |
1800 | |
1801 | if (bVertex) |
1802 | { |
1803 | TopTools_MapOfShape aMVTotal; |
1804 | Standard_Integer aNbChecked = 0; |
1805 | // Just check if the original edges sharing the vertex do not share it any more. |
1806 | for (TopoDS_Iterator it (aEOrF); it.More(); it.Next()) |
1807 | { |
1808 | const TopoDS_Shape& aEOr = it.Value(); |
1809 | const TopTools_ListOfShape* aLIm = anImages.Seek (aEOr); |
1810 | if (!aLIm) |
1811 | continue; |
1812 | ++aNbChecked; |
1813 | TopTools_IndexedDataMapOfShapeListOfShape aMVLoc; |
1814 | for (TopTools_ListOfShape::Iterator itLIM (*aLIm); itLIM.More(); itLIM.Next()) |
1815 | TopExp::MapShapesAndAncestors (itLIM.Value(), TopAbs_VERTEX, TopAbs_EDGE, aMVLoc); |
1816 | for (Standard_Integer i = 1; i <= aMVLoc.Extent(); ++i) |
1817 | { |
1818 | if (aMVLoc(i).Extent() > 1 && !aMVTotal.Add (aMVLoc.FindKey (i))) |
1819 | { |
1820 | bInvalid = Standard_True; |
1821 | theEdgesInvalidByVertex.Add(aEIm); |
1822 | break; |
1823 | } |
1824 | } |
1825 | if (bInvalid) |
1826 | break; |
1827 | } |
1828 | if (!bInvalid && aNbChecked < 2) |
1829 | continue; |
1830 | else |
1831 | theEdgesValidByVertex.Add (aEIm); |
1832 | } |
1833 | else |
1834 | { |
1835 | // |
1836 | // Check orientations of the image edge and original edge. |
1837 | // In case the 3d curves are having the same direction the orientations |
1838 | // must be the same. Otherwise the orientations should also be different. |
1839 | // |
1840 | // get average tangent vector for each curve taking into account |
1841 | // the orientations of the edges, i.e. the edge is reversed |
1842 | // the vector is reversed as well |
1843 | gp_Vec aVSum1 = GetAverageTangent(aEIm, aNbP); |
1844 | gp_Vec aVSum2 = GetAverageTangent(aEOrF, aNbP); |
1845 | // |
1846 | aVSum1.Normalize(); |
1847 | aVSum2.Normalize(); |
1848 | // |
1849 | Standard_Real aCos = aVSum1.Dot(aVSum2); |
ecf4f17c |
1850 | if (Abs(aCos) < 0.9999) { |
1851 | continue; |
1852 | } |
1853 | // |
1854 | aME.Add(aEOrF); |
1855 | TopExp_Explorer aExpE(aEOrF, TopAbs_VERTEX); |
1856 | for (; aExpE.More(); aExpE.Next()) { |
1857 | const TopoDS_Shape& aV = aExpE.Current(); |
1858 | aMV.Add(aV); |
1859 | } |
420b38fd |
1860 | if (theAnalyse) |
1861 | { |
1862 | for (TopTools_ListOfShape::Iterator itFA (theAnalyse->Ancestors (aEOrF)); |
1863 | itFA.More(); itFA.Next()) |
1864 | aMF.Add (itFA.Value()); |
1865 | } |
9e9b826a |
1866 | // |
1867 | if (aCos < Precision::Confusion()) { |
1868 | bInvalid = Standard_True; |
1869 | aNbInv++; |
ecf4f17c |
1870 | } |
1871 | } |
1872 | bChecked = Standard_True; |
1873 | } |
1874 | // |
1875 | if (!bChecked) { |
1876 | continue; |
1877 | } |
1878 | // |
9e9b826a |
1879 | Standard_Boolean bLocalOnly = (aNbVOr > 1 && (aLEOr.Extent() - aNbVOr) > 1); |
ecf4f17c |
1880 | Standard_Integer aNbE = aME.Extent(), aNbV = aMV.Extent(); |
420b38fd |
1881 | if (aNbE > 1 && aNbV == 2*aNbE) |
1882 | { |
1883 | Standard_Boolean bSkip = Standard_True; |
1884 | |
1885 | // Allow the edge to be analyzed if it is: |
1886 | // * originated from more than two faces |
1887 | // * unanimously considered valid or invalid |
1888 | // * not a boundary edge in the splits |
1889 | if (aMF.Extent () > 2 && (aNbInv == 0 || aNbInv == aNbE)) |
1890 | { |
1891 | if (theLFImages.Extent() > 2) |
1892 | { |
1893 | TopoDS_Iterator itV (aEIm); |
1894 | for (; itV.More(); itV.Next()) |
1895 | { |
1896 | TopTools_ListOfShape::Iterator itE (aDMVE.FindFromKey (itV.Value())); |
1897 | for (; itE.More(); itE.Next()) |
1898 | if (aDMEF.FindFromKey (itE.Value()).Extent() < 2) |
1899 | break; |
1900 | if (itE.More()) |
1901 | break; |
1902 | } |
1903 | bSkip = itV.More(); |
1904 | } |
1905 | } |
1906 | if (bSkip) |
1907 | continue; |
1908 | else |
1909 | bLocalOnly = Standard_True; |
ecf4f17c |
1910 | } |
1911 | // |
1912 | if (bInvalid) { |
420b38fd |
1913 | if (!bLocalOnly) |
1914 | theInvEdges.Add(aEIm); |
9e9b826a |
1915 | aMIE.Add (aEIm); |
ecf4f17c |
1916 | aMEInv.Add(aEIm); |
1917 | continue; |
1918 | } |
1919 | // |
1920 | // check if the edge has been inverted |
420b38fd |
1921 | Standard_Boolean bInverted = !aNbE || bLocalOnly ? Standard_False : |
b443d536 |
1922 | CheckInverted(aEIm, aFOr, theOEImages, theOEOrigins, |
b6725456 |
1923 | theEdgesOrigins, aDMVE, aMEdges, theMEInverted); |
ecf4f17c |
1924 | // |
1925 | if (!bInverted || !aNbVOr) { |
420b38fd |
1926 | if (!bLocalOnly) |
1927 | theValidEdges.Add(aEIm); |
9e9b826a |
1928 | aMVE.Add (aEIm); |
ecf4f17c |
1929 | aMEVal.Add(aEIm); |
1930 | } |
1931 | } |
1932 | // |
1933 | // valid edges |
9e9b826a |
1934 | if (aMVE.Extent()) |
1935 | { |
1936 | theDMFMVE.Bind (aFIm, aMVE); |
ecf4f17c |
1937 | } |
1938 | // |
1939 | // invalid edges |
9e9b826a |
1940 | if (aMIE.Extent()) |
1941 | { |
1942 | theDMFMIE.Bind (aFIm, aMIE); |
ecf4f17c |
1943 | } |
1944 | } |
1945 | // |
1946 | // process invalid edges: |
1947 | // check for the inverted edges |
9e9b826a |
1948 | TopTools_MapOfShape aMVIE; |
ecf4f17c |
1949 | // fill neutral edges |
9e9b826a |
1950 | TopTools_MapOfShape aMNE; |
ecf4f17c |
1951 | // |
1952 | Standard_Integer i, aNbEInv = aMEInv.Extent(); |
1953 | for (i = 1; i <= aNbEInv; ++i) { |
1954 | const TopoDS_Shape& aEIm = aMEInv(i); |
1955 | // |
1956 | // neutral edges - on the splits of the same offset face |
1957 | // it is valid for one split and invalid for other |
9e9b826a |
1958 | if (aMEVal.Contains(aEIm)) |
1959 | { |
1960 | aMNE.Add (aEIm); |
ecf4f17c |
1961 | continue; |
1962 | } |
1963 | // |
1964 | // the inverted images of the origins of invalid edges should also be invalid |
1965 | if (!theMEInverted.Contains(aEIm)) { |
1966 | continue; |
1967 | } |
1968 | // |
1969 | const TopTools_ListOfShape* pLOEOr = theOEOrigins.Seek(aEIm); |
1970 | if (!pLOEOr) { |
1971 | continue; |
1972 | } |
1973 | // |
1974 | TopTools_ListIteratorOfListOfShape aItLOEOr(*pLOEOr); |
1975 | for (; aItLOEOr.More(); aItLOEOr.Next()) { |
1976 | const TopoDS_Shape& aOEOr = aItLOEOr.Value(); |
1977 | const TopTools_ListOfShape& aLEIm1 = theOEImages.Find(aOEOr); |
1978 | // |
1979 | TopTools_ListIteratorOfListOfShape aItLEIm1(aLEIm1); |
1980 | for (; aItLEIm1.More(); aItLEIm1.Next()) { |
1981 | const TopoDS_Shape& aEIm1 = aItLEIm1.Value(); |
1982 | if (aMEdges.Contains(aEIm1) && |
1983 | !aMEInv.Contains(aEIm1) && !aMEInt.Contains(aEIm1) && |
1984 | theMEInverted.Contains(aEIm1)) { |
1985 | theInvEdges.Add(aEIm1); |
9e9b826a |
1986 | aMVIE.Add (aEIm1); |
ecf4f17c |
1987 | } |
1988 | } |
1989 | } |
1990 | } |
1991 | // |
9e9b826a |
1992 | if (aMNE.Extent()) |
1993 | { |
1994 | theDMFMNE.Bind (theF, aMNE); |
ecf4f17c |
1995 | } |
1996 | // |
9e9b826a |
1997 | if (aMVIE.Extent()) |
1998 | { |
1999 | theDMFMVIE.Bind (theF, aMVIE); |
ecf4f17c |
2000 | } |
2001 | } |
2002 | |
bea10656 |
2003 | namespace |
2004 | { |
2005 | static void addAsNeutral (const TopoDS_Shape& theE, |
2006 | const TopoDS_Shape& theFInv, |
2007 | const TopoDS_Shape& theFVal, |
2008 | BRepOffset_DataMapOfShapeIndexedMapOfShape& theLocInvEdges, |
2009 | BRepOffset_DataMapOfShapeMapOfShape& theLocValidEdges) |
2010 | { |
2011 | TopTools_IndexedMapOfShape* pMEInv = theLocInvEdges.ChangeSeek (theFInv); |
2012 | if (!pMEInv) |
2013 | pMEInv = theLocInvEdges.Bound (theFInv, TopTools_IndexedMapOfShape()); |
2014 | pMEInv->Add (theE); |
2015 | |
2016 | TopTools_MapOfShape* pMEVal = theLocValidEdges.ChangeSeek (theFVal); |
2017 | if (!pMEVal) |
2018 | pMEVal = theLocValidEdges.Bound (theFVal, TopTools_MapOfShape()); |
2019 | pMEVal->Add (theE); |
2020 | } |
2021 | |
2022 | } |
2023 | //======================================================================= |
2024 | //function : FindInvalidEdges |
2025 | //purpose : Additional method to look for invalid faces |
2026 | //======================================================================= |
2027 | void FindInvalidEdges (const TopTools_ListOfShape& theLFOffset, |
2028 | const TopTools_IndexedDataMapOfShapeListOfShape& theFImages, |
2029 | const TopTools_DataMapOfShapeShape& theFacesOrigins, |
2030 | const BRepOffset_Analyse* theAnalyse, |
2031 | const TopTools_IndexedMapOfShape& theInvEdges, |
2032 | const TopTools_IndexedMapOfShape& theValidEdges, |
2033 | BRepOffset_DataMapOfShapeIndexedMapOfShape& theLocInvEdges, |
2034 | BRepOffset_DataMapOfShapeMapOfShape& theLocValidEdges, |
2035 | BRepOffset_DataMapOfShapeMapOfShape& theNeutralEdges) |
2036 | { |
2037 | // 1. Find edges unclassified in faces |
2038 | // 2. Find SD faces in which the same edge is classified |
2039 | // 3. Check if the edge is neutral in face in which it wasn't classified |
2040 | |
2041 | NCollection_IndexedDataMap<TopoDS_Shape, TopTools_MapOfShape, TopTools_ShapeMapHasher> aMEUnclassified; |
2042 | TopTools_DataMapOfShapeShape aFSplitFOffset; |
2043 | |
2044 | // Avoid artificial faces |
2045 | TopTools_MapOfShape aNewFaces; |
2046 | if (theAnalyse) |
2047 | { |
2048 | TopTools_MapOfShape aMapNewTmp; |
2049 | for (TopTools_ListOfShape::Iterator it (theAnalyse->NewFaces()); it.More(); it.Next()) |
2050 | aMapNewTmp.Add (it.Value()); |
2051 | |
2052 | for (TopTools_ListOfShape::Iterator it (theLFOffset); it.More(); it.Next()) |
2053 | { |
2054 | const TopoDS_Shape& aFOffset = it.Value(); |
2055 | const TopoDS_Shape& aFOrigin = theFacesOrigins.Find (aFOffset); |
2056 | if (aMapNewTmp.Contains (aFOrigin)) |
2057 | aNewFaces.Add (aFOffset); |
2058 | } |
2059 | } |
2060 | |
2061 | TopTools_IndexedDataMapOfShapeListOfShape anEFMap; |
2062 | for (TopTools_ListOfShape::Iterator itLFO (theLFOffset); itLFO.More(); itLFO.Next()) |
2063 | { |
2064 | const TopoDS_Shape& aF = itLFO.Value(); |
2065 | if (aNewFaces.Contains (aF)) |
2066 | continue; |
2067 | |
2068 | const TopTools_ListOfShape& aLFImages = theFImages.FindFromKey (aF); |
2069 | for (TopTools_ListOfShape::Iterator itLF (aLFImages); itLF.More(); itLF.Next()) |
2070 | { |
2071 | const TopoDS_Shape& aFIm = itLF.Value(); |
2072 | |
2073 | TopExp::MapShapesAndAncestors (aFIm, TopAbs_EDGE, TopAbs_FACE, anEFMap); |
2074 | |
2075 | const TopTools_IndexedMapOfShape* pMEInvalid = theLocInvEdges.Seek (aFIm); |
2076 | const TopTools_MapOfShape* pMEValid = theLocValidEdges.Seek (aFIm); |
2077 | |
2078 | for (TopExp_Explorer expE (aFIm, TopAbs_EDGE); expE.More(); expE.Next()) |
2079 | { |
2080 | const TopoDS_Shape& aE = expE.Current(); |
2081 | if (theInvEdges.Contains (aE) != theValidEdges.Contains (aE)) |
2082 | { |
2083 | // edge is classified in some face |
2084 | |
2085 | if ((!pMEInvalid || !pMEInvalid->Contains (aE)) && |
2086 | (!pMEValid || !pMEValid->Contains (aE))) |
2087 | { |
2088 | // but not in the current one |
2089 | TopTools_MapOfShape *pMap = aMEUnclassified.ChangeSeek (aE); |
2090 | if (!pMap) |
2091 | pMap = &aMEUnclassified (aMEUnclassified.Add (aE, TopTools_MapOfShape())); |
2092 | pMap->Add (aFIm); |
2093 | |
2094 | aFSplitFOffset.Bind (aFIm, aF); |
2095 | } |
2096 | } |
2097 | } |
2098 | } |
2099 | } |
2100 | |
2101 | if (aMEUnclassified.IsEmpty()) |
2102 | return; |
2103 | |
2104 | // Analyze unclassified edges |
2105 | const Standard_Integer aNbE = aMEUnclassified.Extent(); |
2106 | for (Standard_Integer iE = 1; iE <= aNbE; ++iE) |
2107 | { |
2108 | const TopoDS_Shape& aE = aMEUnclassified.FindKey (iE); |
2109 | const TopTools_MapOfShape& aMFUnclassified = aMEUnclassified (iE); |
2110 | |
2111 | const TopTools_ListOfShape& aLF = anEFMap.FindFromKey (aE); |
2112 | |
2113 | for (TopTools_ListOfShape::Iterator itLF (aLF); itLF.More(); itLF.Next()) |
2114 | { |
2115 | const TopoDS_Shape& aFClassified = itLF.Value(); |
2116 | if (aMFUnclassified.Contains (aFClassified)) |
2117 | continue; |
2118 | |
2119 | BOPTools_Set anEdgeSetClass; |
2120 | anEdgeSetClass.Add (aFClassified, TopAbs_EDGE); |
2121 | |
2122 | TopoDS_Shape aEClassified; |
2123 | FindShape (aE, aFClassified, NULL, aEClassified); |
2124 | TopAbs_Orientation anOriClass = aEClassified.Orientation(); |
2125 | |
2126 | gp_Dir aDNClass; |
2127 | BOPTools_AlgoTools3D::GetNormalToFaceOnEdge (TopoDS::Edge (aEClassified), TopoDS::Face (aFClassified), aDNClass); |
2128 | |
2129 | const TopTools_IndexedMapOfShape* pMEInvalid = theLocInvEdges.Seek (aFClassified); |
2130 | Standard_Boolean isInvalid = pMEInvalid && pMEInvalid->Contains (aE); |
2131 | |
2132 | for (TopTools_MapOfShape::Iterator itM (aMFUnclassified); itM.More(); itM.Next()) |
2133 | { |
2134 | const TopoDS_Shape& aFUnclassified = itM.Value(); |
2135 | |
2136 | BOPTools_Set anEdgeSetUnclass; |
2137 | anEdgeSetUnclass.Add (aFUnclassified, TopAbs_EDGE); |
2138 | |
2139 | if (anEdgeSetClass.IsEqual (anEdgeSetUnclass)) |
2140 | { |
2141 | gp_Dir aDNUnclass; |
2142 | BOPTools_AlgoTools3D::GetNormalToFaceOnEdge (TopoDS::Edge (aE), TopoDS::Face (aFUnclassified), aDNUnclass); |
2143 | |
2144 | Standard_Boolean isSameOri = aDNClass.IsEqual (aDNUnclass, Precision::Angular()); |
2145 | |
2146 | // Among other splits of the same face find those where the edge is contained with different |
2147 | // orientation |
2148 | const TopoDS_Shape& aFOffset = aFSplitFOffset.Find (aFUnclassified); |
2149 | const TopTools_ListOfShape& aLFSplits = theFImages.FindFromKey (aFOffset); |
2150 | TopTools_ListOfShape::Iterator itLFSp (aLFSplits); |
2151 | for (; itLFSp.More(); itLFSp.Next()) |
2152 | { |
2153 | const TopoDS_Shape& aFSp = itLFSp.Value(); |
2154 | |
2155 | if (!aFSp.IsSame (aFUnclassified) && aMFUnclassified.Contains (aFSp)) |
2156 | { |
2157 | TopoDS_Shape aEUnclassified; |
2158 | FindShape (aE, aFSp, NULL, aEUnclassified); |
2159 | |
2160 | TopAbs_Orientation anOriUnclass = aEUnclassified.Orientation(); |
2161 | if (!isSameOri) |
2162 | anOriUnclass = TopAbs::Reverse (anOriUnclass); |
2163 | |
2164 | if (anOriClass != anOriUnclass) |
2165 | { |
2166 | // make the edge neutral for the face |
2167 | TopTools_MapOfShape* pMENeutral = theNeutralEdges.ChangeSeek (aFOffset); |
2168 | if (!pMENeutral) |
2169 | pMENeutral = theNeutralEdges.Bound (aFOffset, TopTools_MapOfShape()); |
2170 | pMENeutral->Add (aE); |
2171 | |
2172 | if (isInvalid && isSameOri) |
2173 | { |
2174 | // make edge invalid in aFUnclassified and valid in aFSp |
2175 | addAsNeutral (aE, aFClassified, aFSp, theLocInvEdges, theLocValidEdges); |
2176 | } |
2177 | else |
2178 | { |
2179 | // make edge invalid in aFSp and valid in aFUnclassified |
2180 | addAsNeutral (aE, aFSp, aFClassified, theLocInvEdges, theLocValidEdges); |
2181 | } |
2182 | } |
2183 | } |
2184 | } |
2185 | if (itLFSp.More()) |
2186 | break; |
2187 | } |
2188 | } |
2189 | } |
2190 | } |
2191 | } |
2192 | |
62eafa5a |
2193 | //======================================================================= |
2194 | //function : MakeInvertedEdgesInvalid |
2195 | //purpose : Makes inverted edges located inside loop of invalid edges, invalid as well |
2196 | //======================================================================= |
2197 | void MakeInvertedEdgesInvalid(const TopTools_ListOfShape& theLFOffset, |
2198 | const TopTools_IndexedDataMapOfShapeListOfShape& theFImages, |
2199 | const TopTools_MapOfShape& theInvertedEdges, |
2200 | TopTools_IndexedMapOfShape& theInvEdges) |
2201 | { |
2202 | if (theInvEdges.IsEmpty() || theInvertedEdges.IsEmpty()) |
2203 | return; |
2204 | |
2205 | // Map all invalid edges |
2206 | TopoDS_Compound aCBEInv; |
2207 | BRep_Builder().MakeCompound(aCBEInv); |
2208 | for (Standard_Integer i = 1; i <= theInvEdges.Extent(); ++i) |
2209 | { |
2210 | BRep_Builder().Add(aCBEInv, theInvEdges(i)); |
2211 | } |
2212 | |
2213 | // Make loops of invalid edges |
2214 | TopTools_ListOfShape aLCB; |
2215 | BOPTools_AlgoTools::MakeConnexityBlocks(aCBEInv, TopAbs_VERTEX, TopAbs_EDGE, aLCB); |
2216 | |
2217 | // Analyze each loop on closeness and use only closed ones |
2218 | TopTools_DataMapOfShapeShape aDMVCB; |
2219 | |
2220 | for (TopTools_ListOfShape::Iterator itLCB(aLCB); itLCB.More(); itLCB.Next()) |
2221 | { |
2222 | const TopoDS_Shape& aCB = itLCB.Value(); |
2223 | |
2224 | TopTools_IndexedDataMapOfShapeListOfShape aDMVE; |
2225 | TopExp::MapShapesAndAncestors(aCB, TopAbs_VERTEX, TopAbs_EDGE, aDMVE); |
2226 | Standard_Boolean isClosed = Standard_True; |
2227 | for (Standard_Integer iV = 1; iV <= aDMVE.Extent(); ++iV) |
2228 | { |
2229 | if (aDMVE(iV).Extent() != 2) |
2230 | { |
2231 | isClosed = Standard_False; |
2232 | break; |
2233 | } |
2234 | } |
2235 | if (!isClosed) |
2236 | continue; |
2237 | |
2238 | // Bind loop to each vertex of the loop |
2239 | for (Standard_Integer iV = 1; iV <= aDMVE.Extent(); ++iV) |
2240 | { |
2241 | aDMVCB.Bind(aDMVE.FindKey(iV), aCB); |
2242 | } |
2243 | } |
2244 | |
2245 | // Check if any inverted edges of offset faces are locked inside the loops of invalid edges. |
2246 | // Make such edges invalid as well. |
2247 | for (TopTools_ListOfShape::Iterator itLF(theLFOffset); itLF.More(); itLF.Next()) |
2248 | { |
2249 | const TopTools_ListOfShape& aLFIm = theFImages.FindFromKey(itLF.Value()); |
2250 | for (TopTools_ListOfShape::Iterator itLFIm(aLFIm); itLFIm.More(); itLFIm.Next()) |
2251 | { |
2252 | for (TopExp_Explorer expE(itLFIm.Value(), TopAbs_EDGE); expE.More(); expE.Next()) |
2253 | { |
2254 | const TopoDS_Edge& aE = TopoDS::Edge(expE.Current()); |
2255 | if (!theInvEdges.Contains(aE) && theInvertedEdges.Contains(aE)) |
2256 | { |
2257 | const TopoDS_Shape* pCB1 = aDMVCB.Seek (TopExp::FirstVertex(aE)); |
2258 | const TopoDS_Shape* pCB2 = aDMVCB.Seek (TopExp::LastVertex(aE)); |
2259 | if (pCB1 && pCB2 && pCB1->IsSame(*pCB2)) |
2260 | { |
2261 | theInvEdges.Add(aE); |
2262 | } |
2263 | } |
2264 | } |
2265 | } |
2266 | } |
2267 | } |
2268 | |
ecf4f17c |
2269 | //======================================================================= |
2270 | //function : FindInvalidFaces |
2271 | //purpose : Looking for the invalid faces by analyzing their invalid edges |
2272 | //======================================================================= |
2273 | void FindInvalidFaces(TopTools_ListOfShape& theLFImages, |
2274 | const TopTools_IndexedMapOfShape& theInvEdges, |
2275 | const TopTools_IndexedMapOfShape& theValidEdges, |
9e9b826a |
2276 | const BRepOffset_DataMapOfShapeMapOfShape& theDMFMVE, |
2277 | const BRepOffset_DataMapOfShapeIndexedMapOfShape& theDMFMIE, |
2278 | const TopTools_MapOfShape& theMENeutral, |
ecf4f17c |
2279 | const TopTools_MapOfShape& theMEInverted, |
2280 | const TopTools_MapOfShape& theEdgesInvalidByVertex, |
9e9b826a |
2281 | const TopTools_MapOfShape& theEdgesValidByVertex, |
0da0275c |
2282 | const TopTools_MapOfShape& theMFHoles, |
2283 | TopTools_IndexedMapOfShape& theMFInvInHole, |
e08a9b03 |
2284 | TopTools_ListOfShape& theInvFaces, |
2285 | TopTools_ListOfShape& theInvertedFaces) |
ecf4f17c |
2286 | { |
2287 | // The face should be considered as invalid in the following cases: |
2288 | // 1. It has been reverted, i.e. at least two not connected edges |
2289 | // have changed orientation (i.e. invalid). In this case all edges, |
2290 | // should be invalid for that face, because edges have also been reverted; |
2291 | // 2. All checked edges of the face are invalid for this face; |
2292 | // The face should be removed from the splits in the following cases: |
2293 | // 1. All checked edges of the face are invalid for this one, but valid for |
2294 | // some other face in this list of splits. |
2295 | // The face will be kept in the following cases: |
2296 | // 1. Some of the edges are valid for this face. |
2297 | Standard_Boolean bHasValid, bAllValid, bAllInvalid, bHasReallyInvalid, bAllInvNeutral; |
e08a9b03 |
2298 | Standard_Boolean bValid, bValidLoc, bInvalid, bInvalidLoc, bNeutral, bInverted; |
2299 | Standard_Boolean bIsInvalidByInverted; |
9e9b826a |
2300 | Standard_Integer aNbChecked; |
ecf4f17c |
2301 | // |
e08a9b03 |
2302 | Standard_Boolean bTreatInvertedAsInvalid = (theLFImages.Extent() == 1); |
ecf4f17c |
2303 | // |
2304 | // neutral edges to remove |
2305 | TopTools_IndexedMapOfShape aMENRem; |
2306 | // |
2307 | // faces for post treat |
2308 | TopTools_ListOfShape aLFPT; |
2309 | // |
9e9b826a |
2310 | TopTools_IndexedDataMapOfShapeListOfShape aDMEF; |
ecf4f17c |
2311 | TopTools_ListIteratorOfListOfShape aItLF(theLFImages); |
9e9b826a |
2312 | for (; aItLF.More(); aItLF.Next()) |
2313 | { |
2314 | const TopoDS_Face& aFIm = *(TopoDS_Face*)&aItLF.Value(); |
2315 | TopExp::MapShapesAndAncestors (aFIm, TopAbs_EDGE, TopAbs_FACE, aDMEF); |
2316 | } |
2317 | |
2318 | aItLF.Initialize (theLFImages); |
ecf4f17c |
2319 | for (; aItLF.More(); ) { |
2320 | const TopoDS_Face& aFIm = *(TopoDS_Face*)&aItLF.Value(); |
2321 | // |
2322 | // valid edges for this split |
9e9b826a |
2323 | const TopTools_MapOfShape* pMVE = theDMFMVE.Seek (aFIm); |
ecf4f17c |
2324 | // invalid edges for this split |
9e9b826a |
2325 | const TopTools_IndexedMapOfShape* pMIE = theDMFMIE.Seek (aFIm); |
ecf4f17c |
2326 | // |
2327 | bHasValid = Standard_False; |
2328 | bAllValid = Standard_True; |
2329 | bAllInvalid = Standard_True; |
2330 | bHasReallyInvalid = Standard_False; |
2331 | bAllInvNeutral = Standard_True; |
e08a9b03 |
2332 | bIsInvalidByInverted = Standard_True; |
ecf4f17c |
2333 | aNbChecked = 0; |
2334 | // |
2335 | const TopoDS_Wire& aWIm = BRepTools::OuterWire(aFIm); |
2336 | TopExp_Explorer aExp(aWIm, TopAbs_EDGE); |
2337 | for (; aExp.More(); aExp.Next()) { |
2338 | const TopoDS_Shape& aEIm = aExp.Current(); |
2339 | // |
2340 | bValid = theValidEdges.Contains(aEIm); |
2341 | bInvalid = theInvEdges.Contains(aEIm); |
9e9b826a |
2342 | bNeutral = theMENeutral.Contains(aEIm); |
ecf4f17c |
2343 | // |
420b38fd |
2344 | if (!bValid && !bInvalid && !bNeutral) { |
ecf4f17c |
2345 | // edge has not been checked for some reason |
2346 | continue; |
2347 | } |
9e9b826a |
2348 | |
2349 | // skip not-boundary edges originated from vertex |
2350 | if ((theEdgesInvalidByVertex.Contains (aEIm) || |
2351 | theEdgesValidByVertex.Contains (aEIm)) && |
2352 | aDMEF.FindFromKey (aEIm).Extent() != 1) |
2353 | continue; |
2354 | |
ecf4f17c |
2355 | ++aNbChecked; |
2356 | // |
9e9b826a |
2357 | bInvalidLoc = pMIE && pMIE->Contains (aEIm); |
420b38fd |
2358 | bHasReallyInvalid = bInvalid && bInvalidLoc && !bValid && !theEdgesInvalidByVertex.Contains(aEIm); |
ecf4f17c |
2359 | if (bHasReallyInvalid) { |
2360 | break; |
2361 | } |
2362 | // |
9e9b826a |
2363 | bValidLoc = pMVE && pMVE->Contains(aEIm); |
e08a9b03 |
2364 | bInverted = theMEInverted.Contains(aEIm); |
420b38fd |
2365 | if (!bInvalid && !bInvalidLoc && bTreatInvertedAsInvalid) { |
e08a9b03 |
2366 | bInvalid = bInverted; |
ecf4f17c |
2367 | } |
2368 | // |
9e9b826a |
2369 | if (bValidLoc && bNeutral) { |
ecf4f17c |
2370 | bHasValid = Standard_True; |
2371 | } |
2372 | // |
e08a9b03 |
2373 | bAllValid &= bValidLoc; |
420b38fd |
2374 | bAllInvalid &= (bInvalid || bInvalidLoc); |
e08a9b03 |
2375 | bAllInvNeutral &= (bAllInvalid && bNeutral); |
2376 | bIsInvalidByInverted &= (bInvalidLoc || bInverted); |
ecf4f17c |
2377 | } |
2378 | // |
2379 | if (!aNbChecked) { |
2380 | aItLF.Next(); |
2381 | continue; |
2382 | } |
2383 | // |
2384 | if (!bHasReallyInvalid && (bAllInvNeutral && !bHasValid) && (aNbChecked > 1)) { |
2385 | // remove edges from neutral |
2386 | TopExp::MapShapes(aFIm, TopAbs_EDGE, aMENRem); |
2387 | // remove face |
2388 | theLFImages.Remove(aItLF); |
2389 | continue; |
2390 | } |
2391 | // |
2392 | if (bHasReallyInvalid || (bAllInvalid && |
2393 | !(bHasValid || bAllValid) && |
2394 | !(bAllInvNeutral && (aNbChecked == 1)))) { |
2395 | theInvFaces.Append(aFIm); |
0da0275c |
2396 | if (theMFHoles.Contains(aFIm)) { |
2397 | theMFInvInHole.Add(aFIm); |
2398 | } |
a8232603 |
2399 | aItLF.Next(); |
2400 | continue; |
ecf4f17c |
2401 | } |
2402 | // |
0da0275c |
2403 | if (theMFHoles.Contains(aFIm)) { |
2404 | // remove edges from neutral |
2405 | TopExp::MapShapes(aFIm, TopAbs_EDGE, aMENRem); |
2406 | // remove face |
2407 | theLFImages.Remove(aItLF); |
2408 | continue; |
2409 | } |
2410 | // |
e08a9b03 |
2411 | if (bIsInvalidByInverted && !(bHasValid || bAllValid)) |
2412 | { |
2413 | // The face contains only the inverted and locally invalid edges |
2414 | theInvertedFaces.Append(aFIm); |
2415 | } |
2416 | |
ecf4f17c |
2417 | if (!bAllInvNeutral) { |
2418 | aLFPT.Append(aFIm); |
2419 | } |
2420 | else { |
2421 | // remove edges from neutral |
2422 | TopExp::MapShapes(aFIm, TopAbs_EDGE, aMENRem); |
2423 | } |
2424 | aItLF.Next(); |
2425 | } |
2426 | // |
2427 | if (aLFPT.IsEmpty() || aMENRem.IsEmpty()) { |
2428 | return; |
2429 | } |
9e9b826a |
2430 | |
ecf4f17c |
2431 | // check the splits once more |
2432 | aItLF.Initialize(aLFPT); |
2433 | for (; aItLF.More(); aItLF.Next()) { |
2434 | const TopoDS_Face& aFIm = *(TopoDS_Face*)&aItLF.Value(); |
2435 | // |
2436 | // valid edges for this split |
9e9b826a |
2437 | const TopTools_MapOfShape* pMVE = theDMFMVE.Seek(aFIm); |
ecf4f17c |
2438 | // |
2439 | bHasValid = Standard_False; |
2440 | bAllValid = Standard_True; |
2441 | bAllInvalid = Standard_True; |
2442 | // |
2443 | const TopoDS_Wire& aWIm = BRepTools::OuterWire(aFIm); |
2444 | TopExp_Explorer aExp(aWIm, TopAbs_EDGE); |
2445 | for (; aExp.More(); aExp.Next()) { |
2446 | const TopoDS_Shape& aEIm = aExp.Current(); |
2447 | // |
2448 | bValid = theValidEdges.Contains(aEIm); |
2449 | bInvalid = theInvEdges.Contains(aEIm); |
9e9b826a |
2450 | bNeutral = theMENeutral.Contains(aEIm) && !aMENRem.Contains (aEIm); |
2451 | bValidLoc = pMVE && pMVE->Contains(aEIm); |
ecf4f17c |
2452 | // |
e08a9b03 |
2453 | if (!bInvalid && bTreatInvertedAsInvalid) { |
ecf4f17c |
2454 | bInvalid = theMEInverted.Contains(aEIm); |
2455 | } |
2456 | // |
9e9b826a |
2457 | if (bValidLoc && bNeutral) { |
ecf4f17c |
2458 | bHasValid = Standard_True; |
2459 | } |
2460 | // |
2461 | bAllValid = bAllValid && bValidLoc; |
2462 | bAllInvalid = bAllInvalid && bInvalid; |
2463 | } |
2464 | // |
2465 | if (bAllInvalid && !bHasValid && !bAllValid) { |
2466 | theInvFaces.Append(aFIm); |
2467 | } |
2468 | } |
2469 | } |
2470 | |
0da0275c |
2471 | //======================================================================= |
2472 | //function : FindFacesInsideHoleWires |
2473 | //purpose : Find faces inside holes wires from the original face |
2474 | //======================================================================= |
2475 | void FindFacesInsideHoleWires(const TopoDS_Face& theFOrigin, |
2476 | const TopoDS_Face& theFOffset, |
2477 | const TopTools_ListOfShape& theLFImages, |
2478 | const TopTools_MapOfShape& theInvertedEdges, |
2479 | const TopTools_DataMapOfShapeListOfShape& theDMEOrLEIm, |
2ebb1098 |
2480 | const TopTools_IndexedDataMapOfShapeListOfShape& theEFMap, |
0da0275c |
2481 | TopTools_MapOfShape& theMFHoles, |
2482 | TopTools_DataMapOfShapeListOfShape& theDMFNewHoles, |
2483 | Handle(IntTools_Context)& theContext) |
2484 | { |
2485 | if (theLFImages.IsEmpty()) { |
2486 | return; |
2487 | } |
2488 | // |
2489 | // find all hole wires in the original face |
2490 | TopTools_ListOfShape aLHoleWires; |
2491 | const TopoDS_Wire& anOuterWire = BRepTools::OuterWire(theFOrigin); |
2492 | TopExp_Explorer aExpW(theFOrigin, TopAbs_WIRE); |
2493 | for (; aExpW.More(); aExpW.Next()) { |
2494 | const TopoDS_Wire& aHoleWire = TopoDS::Wire(aExpW.Current()); |
2495 | if (!aHoleWire.IsSame(anOuterWire) && aHoleWire.Orientation() != TopAbs_INTERNAL) { |
2496 | aLHoleWires.Append(aHoleWire); |
2497 | } |
2498 | } |
2499 | // |
2500 | if (aLHoleWires.IsEmpty()) { |
2501 | // no holes in the face |
2502 | return; |
2503 | } |
2504 | // |
2505 | TopTools_ListOfShape *pLFNewHoles = theDMFNewHoles.ChangeSeek(theFOrigin); |
2506 | // |
2507 | if (!pLFNewHoles) { |
2508 | pLFNewHoles = theDMFNewHoles.Bound(theFOrigin, TopTools_ListOfShape()); |
2509 | } |
2510 | if (pLFNewHoles->IsEmpty()) { |
2511 | // |
2512 | // find the faces representing holes in the images of the faces: |
2513 | // 1. for each original hole wire try to build its image |
2514 | // 2. build the new planar face from the images |
2515 | // |
2516 | // map vertices and edges of the splits |
2517 | TopTools_IndexedMapOfShape aMESplits; |
2518 | TopTools_ListIteratorOfListOfShape aItLF(theLFImages); |
2519 | for (; aItLF.More(); aItLF.Next()) { |
2520 | TopExp::MapShapes(aItLF.Value(), TopAbs_EDGE, aMESplits); |
2521 | } |
2522 | // |
2523 | TopTools_ListIteratorOfListOfShape aItLW(aLHoleWires); |
2524 | for (; aItLW.More(); aItLW.Next()) { |
2525 | const TopoDS_Wire& aHoleWire = TopoDS::Wire(aItLW.Value()); |
2526 | // find images of all edges of the original wire |
2527 | TopTools_IndexedMapOfShape aMEImWire; |
2528 | TopoDS_Iterator aItE(aHoleWire); |
2529 | for (; aItE.More(); aItE.Next()) { |
2530 | const TopoDS_Shape& aEOr = aItE.Value(); |
2531 | const TopTools_ListOfShape *pLEIm = theDMEOrLEIm.Seek(aEOr); |
2532 | if (!pLEIm || pLEIm->IsEmpty()) { |
2533 | continue; |
2534 | } |
2535 | TopTools_ListIteratorOfListOfShape aItLEIm(*pLEIm); |
2536 | for (; aItLEIm.More(); aItLEIm.Next()) { |
2537 | const TopoDS_Shape& aEIm = aItLEIm.Value(); |
2538 | if (aMESplits.Contains(aEIm)) { |
2539 | aMEImWire.Add(aEIm); |
2540 | } |
2541 | } |
2542 | } |
2543 | // |
2544 | if (aMEImWire.IsEmpty()) { |
2545 | continue; |
2546 | } |
2547 | // |
2548 | // build new planar face using these edges |
1155d05a |
2549 | TopTools_ListOfShape aLE; |
0da0275c |
2550 | Standard_Integer i, aNbE = aMEImWire.Extent(); |
2551 | for (i = 1; i <= aNbE; ++i) { |
2552 | aLE.Append(aMEImWire(i).Oriented(TopAbs_FORWARD)); |
2553 | aLE.Append(aMEImWire(i).Oriented(TopAbs_REVERSED)); |
2554 | } |
2555 | // |
2556 | BOPAlgo_BuilderFace aBF; |
2557 | aBF.SetFace(TopoDS::Face(theFOffset.Oriented(TopAbs_FORWARD))); |
2558 | aBF.SetShapes(aLE); |
2559 | aBF.Perform(); |
2560 | // |
1155d05a |
2561 | const TopTools_ListOfShape& aLFNew = aBF.Areas(); |
0da0275c |
2562 | if (aLFNew.IsEmpty()) { |
2563 | continue; |
2564 | } |
2565 | // |
2566 | // check if outer edges in the new faces are not inverted |
2567 | // because the inverted edges mean that the hole has been |
2568 | // filled during offset and there will be no faces to remove |
2569 | TopTools_IndexedDataMapOfShapeListOfShape aDMEFNew; |
2570 | TopTools_ListIteratorOfListOfShape aItLFNew(aLFNew); |
2571 | for (; aItLFNew.More(); aItLFNew.Next()) { |
2572 | TopExp::MapShapesAndAncestors(aItLFNew.Value(), TopAbs_EDGE, TopAbs_FACE, aDMEFNew); |
2573 | } |
2574 | // |
2575 | aNbE = aDMEFNew.Extent(); |
2576 | for (i = 1; i <= aNbE; ++i) { |
2577 | if (aDMEFNew(i).Extent() == 1) { |
2578 | const TopoDS_Shape& aE = aDMEFNew.FindKey(i); |
2579 | if (theInvertedEdges.Contains(aE)) { |
2580 | break; |
2581 | } |
2582 | } |
2583 | } |
2584 | // |
2585 | if (i <= aNbE) { |
2586 | continue; |
2587 | } |
2588 | // |
2589 | aItLFNew.Initialize(aLFNew); |
2590 | for (; aItLFNew.More(); aItLFNew.Next()) { |
2591 | pLFNewHoles->Append(aItLFNew.Value()); |
2592 | } |
2593 | } |
2594 | } |
2ebb1098 |
2595 | |
2596 | // Build Edge-Face map for splits of current offset face |
2597 | TopTools_IndexedDataMapOfShapeListOfShape anEFSplitsMap; |
2598 | // Build Edge-Face map for holes |
2599 | TopTools_IndexedDataMapOfShapeListOfShape anEFHolesMap; |
2600 | |
0da0275c |
2601 | // among the splits of the offset face find those that are |
2602 | // located inside the hole faces |
0da0275c |
2603 | TopTools_ListIteratorOfListOfShape aItLF(theLFImages); |
2604 | for (; aItLF.More(); aItLF.Next()) { |
2605 | const TopoDS_Face& aFIm = TopoDS::Face(aItLF.Value()); |
2ebb1098 |
2606 | TopExp::MapShapesAndAncestors(aFIm, TopAbs_EDGE, TopAbs_FACE, anEFSplitsMap); |
0da0275c |
2607 | // get the point inside the face and classify it relatively hole faces |
2608 | gp_Pnt aP3D; |
2609 | gp_Pnt2d aP2D; |
2610 | Standard_Integer iErr = BOPTools_AlgoTools3D::PointInFace(aFIm, aP3D, aP2D, theContext); |
2611 | if (iErr) { |
2612 | continue; |
2613 | } |
2614 | // |
2615 | Standard_Real aTol = BRep_Tool::Tolerance(aFIm); |
2616 | // |
2617 | TopTools_ListIteratorOfListOfShape aItLFNew(*pLFNewHoles); |
2618 | for (; aItLFNew.More(); aItLFNew.Next()) { |
2619 | const TopoDS_Face& aFNew = TopoDS::Face(aItLFNew.Value()); |
2620 | if (theContext->IsValidPointForFace(aP3D, aFNew, aTol)) { |
2621 | // the face is classified as IN |
2622 | theMFHoles.Add(aFIm); |
2ebb1098 |
2623 | TopExp::MapShapesAndAncestors(aFIm, TopAbs_EDGE, TopAbs_FACE, anEFHolesMap); |
0da0275c |
2624 | break; |
2625 | } |
2626 | } |
2627 | } |
2ebb1098 |
2628 | |
2629 | // Out of all found holes find those which cannot be removed |
2630 | // by checking their connectivity to splits of other offset faces. |
2631 | // These are the faces, which will create uncovered holes if removed. |
2632 | const Standard_Integer aNbE = anEFHolesMap.Extent(); |
2633 | for (Standard_Integer i = 1; i <= aNbE; ++i) |
2634 | { |
2635 | const TopoDS_Shape& anEdge = anEFHolesMap.FindKey(i); |
2636 | const TopTools_ListOfShape& aLFHoles = anEFHolesMap(i); |
2637 | // Check if the edge is outer for holes |
2638 | if (aLFHoles.Extent() != 1) |
2639 | continue; |
2640 | |
2641 | const TopoDS_Shape& aFHole = aLFHoles.First(); |
2642 | if (!theMFHoles.Contains(aFHole)) |
2643 | // Already removed |
2644 | continue; |
2645 | |
2646 | // Check if the edge is not outer for splits |
2647 | const TopTools_ListOfShape& aLSplits = anEFSplitsMap.FindFromKey(anEdge); |
2648 | if (aLSplits.Extent() == 1) |
2649 | continue; |
2650 | |
2651 | // Check if edge is only connected to splits of the current offset face |
2652 | const TopTools_ListOfShape& aLFAll = theEFMap.FindFromKey(anEdge); |
2653 | if (aLFAll.Extent() == 2) |
2654 | // Avoid removal of the hole from the splits |
2655 | theMFHoles.Remove(aFHole); |
2656 | } |
0da0275c |
2657 | } |
2658 | |
ecf4f17c |
2659 | //======================================================================= |
2660 | //function : GetAverageTangent |
2661 | //purpose : Computes average tangent vector along the curve |
2662 | //======================================================================= |
2663 | gp_Vec GetAverageTangent(const TopoDS_Shape& theS, |
2664 | const Standard_Integer theNbP) |
2665 | { |
2666 | gp_Vec aVA; |
2667 | TopExp_Explorer aExp(theS, TopAbs_EDGE); |
2668 | for (; aExp.More(); aExp.Next()) { |
2669 | const TopoDS_Edge& aE = *(TopoDS_Edge*)&aExp.Current(); |
2670 | // |
2671 | Standard_Real aT1, aT2; |
2672 | const Handle(Geom_Curve)& aC = BRep_Tool::Curve(aE, aT1, aT2); |
2673 | // |
2674 | gp_Pnt aP; |
2675 | gp_Vec aV, aVSum; |
2676 | Standard_Real aT = aT1; |
2677 | Standard_Real aDt = (aT2 - aT1) / theNbP; |
2678 | while (aT <= aT2) { |
2679 | aC->D1(aT, aP, aV); |
2680 | aVSum += aV.Normalized(); |
2681 | aT += aDt; |
2682 | } |
2683 | // |
2684 | if (aE.Orientation() == TopAbs_REVERSED) { |
2685 | aVSum.Reverse(); |
2686 | } |
2687 | // |
2688 | aVA += aVSum; |
2689 | } |
2690 | return aVA; |
2691 | } |
2692 | |
2693 | //======================================================================= |
2694 | //function : CheckInverted |
2695 | //purpose : Checks if the edge has been inverted |
2696 | //======================================================================= |
2697 | Standard_Boolean CheckInverted(const TopoDS_Edge& theEIm, |
2698 | const TopoDS_Face& theFOr, |
2699 | const TopTools_DataMapOfShapeListOfShape& theOEImages, |
2700 | const TopTools_DataMapOfShapeListOfShape& theOEOrigins, |
2701 | const TopTools_DataMapOfShapeListOfShape& theEdgesOrigins, |
ecf4f17c |
2702 | const TopTools_IndexedDataMapOfShapeListOfShape& theDMVE, |
2703 | const TopTools_IndexedMapOfShape& theMEdges, |
2704 | TopTools_MapOfShape& theMEInverted) |
2705 | { |
b6725456 |
2706 | // It is necessary to compare the direction from first vertex |
ecf4f17c |
2707 | // to the last vertex on the original edge with the |
2708 | // same direction on the new edge. If the directions |
2709 | // will be different - the edge has been inverted. |
2710 | // |
2711 | TopoDS_Vertex aVI1, aVI2; // vertices on the offset edge |
2712 | TopoDS_Vertex aVO1, aVO2; // vertices on the original edge |
2713 | // |
2714 | Standard_Integer i; |
2715 | // find vertices of the offset shape |
2716 | TopExp::Vertices(theEIm, aVI1, aVI2); |
2717 | // |
2718 | // find images |
2719 | TopTools_ListOfShape aLEImages; |
2720 | if (theOEOrigins.IsBound(theEIm)) { |
2721 | TopoDS_Wire anImages; |
2722 | BRep_Builder().MakeWire(anImages); |
2723 | // |
2724 | TopTools_MapOfShape aMImFence; |
2725 | const TopTools_ListOfShape& aLOffsetOr = theOEOrigins.Find(theEIm); |
2726 | TopTools_ListIteratorOfListOfShape aItOffset(aLOffsetOr); |
2727 | for (; aItOffset.More(); aItOffset.Next()) { |
2728 | const TopoDS_Shape& aEOffsetOr = aItOffset.Value(); |
2729 | const TopTools_ListOfShape& aLImages = theOEImages.Find(aEOffsetOr); |
2730 | // |
2731 | TopTools_ListIteratorOfListOfShape aItImages(aLImages); |
2732 | for (; aItImages.More(); aItImages.Next()) { |
2733 | const TopoDS_Edge& anIm = *(TopoDS_Edge*)&aItImages.Value(); |
2734 | if (theMEdges.Contains(anIm) && aMImFence.Add(anIm)) { |
2735 | BRep_Builder().Add(anImages, anIm); |
2736 | aLEImages.Append(anIm); |
2737 | } |
2738 | } |
2739 | } |
2740 | // |
2741 | // find alone vertices |
2742 | TopoDS_Vertex aVW1, aVW2; |
2743 | TopTools_IndexedDataMapOfShapeListOfShape aDMImVE; |
2744 | TopExp::MapShapesAndAncestors(anImages, TopAbs_VERTEX, TopAbs_EDGE, aDMImVE); |
2745 | // |
2746 | TopTools_ListOfShape aLVAlone; |
2747 | Standard_Integer aNb = aDMImVE.Extent(); |
2748 | for (i = 1; i <= aNb; ++i) { |
2749 | const TopTools_ListOfShape& aLImE = aDMImVE(i); |
2750 | if (aLImE.Extent() == 1) { |
2751 | aLVAlone.Append(aDMImVE.FindKey(i)); |
2752 | } |
2753 | } |
2754 | // |
2755 | if (aLVAlone.Extent() > 1) { |
2756 | aVW1 = *(TopoDS_Vertex*)&aLVAlone.First(); |
2757 | aVW2 = *(TopoDS_Vertex*)&aLVAlone.Last(); |
2758 | // |
2759 | // check distances |
2760 | const gp_Pnt& aPI1 = BRep_Tool::Pnt(aVI1); |
2761 | const gp_Pnt& aPW1 = BRep_Tool::Pnt(aVW1); |
2762 | const gp_Pnt& aPW2 = BRep_Tool::Pnt(aVW2); |
2763 | // |
2764 | Standard_Real aDist1 = aPI1.SquareDistance(aPW1); |
2765 | Standard_Real aDist2 = aPI1.SquareDistance(aPW2); |
2766 | // |
2767 | if (aDist1 < aDist2) { |
2768 | aVI1 = aVW1; |
2769 | aVI2 = aVW2; |
2770 | } |
2771 | else { |
2772 | aVI1 = aVW2; |
2773 | aVI2 = aVW1; |
2774 | } |
2775 | } |
2776 | } |
2777 | else { |
2778 | aLEImages.Append(theEIm); |
2779 | } |
2780 | // |
2781 | // Find edges connected to these vertices |
2782 | const TopTools_ListOfShape& aLIE1 = theDMVE.FindFromKey(aVI1); |
2783 | const TopTools_ListOfShape& aLIE2 = theDMVE.FindFromKey(aVI2); |
2784 | // |
2785 | // Find vertices on the original face corresponding to vertices on the offset edge |
2786 | // |
2787 | // find original edges for both lists |
2788 | TopTools_ListOfShape aLOE1, aLOE2; |
2789 | for (i = 0; i < 2; ++i) { |
2790 | const TopTools_ListOfShape& aLIE = !i ? aLIE1 : aLIE2; |
2791 | TopTools_ListOfShape& aLOE = !i ? aLOE1 : aLOE2; |
2792 | // |
2793 | TopTools_MapOfShape aMFence; |
2794 | // |
2795 | TopTools_ListIteratorOfListOfShape aItLIE(aLIE); |
2796 | for (; aItLIE.More(); aItLIE.Next()) { |
2797 | const TopoDS_Shape& aEI = aItLIE.Value(); |
2798 | if (theEdgesOrigins.IsBound(aEI)) { |
2799 | const TopTools_ListOfShape& aLEOrigins = theEdgesOrigins.Find(aEI); |
2800 | // |
2801 | TopTools_ListIteratorOfListOfShape aItLOE(aLEOrigins); |
2802 | for (; aItLOE.More(); aItLOE.Next()) { |
2803 | const TopoDS_Shape& aEO = aItLOE.Value(); |
2804 | if (aEO.ShapeType() == TopAbs_EDGE && aMFence.Add(aEO)) { |
2805 | TopoDS_Shape aEOin; |
420b38fd |
2806 | if (FindShape(aEO, theFOr, NULL, aEOin)) { |
b443d536 |
2807 | AppendToList(aLOE, aEO); |
ecf4f17c |
2808 | } |
2809 | } |
2810 | } |
2811 | } |
2812 | } |
2813 | } |
2814 | // |
2815 | if (aLOE1.Extent() < 2 || aLOE2.Extent() < 2) { |
2816 | return Standard_False; |
2817 | } |
2818 | // |
2819 | // find vertices common for all edges in the lists |
2820 | for (i = 0; i < 2; ++i) { |
2821 | const TopTools_ListOfShape& aLOE = !i ? aLOE1 : aLOE2; |
2822 | TopoDS_Vertex& aVO = !i ? aVO1 : aVO2; |
2823 | // |
2824 | const TopoDS_Shape& aEO = aLOE.First(); |
2825 | TopExp_Explorer aExpV(aEO, TopAbs_VERTEX); |
2826 | for (; aExpV.More(); aExpV.Next()) { |
2827 | const TopoDS_Vertex& aV = *(TopoDS_Vertex*)&aExpV.Current(); |
2828 | // |
2829 | Standard_Boolean bVertValid = Standard_True; |
2830 | TopTools_ListIteratorOfListOfShape aItLOE(aLOE); |
2831 | for (aItLOE.Next(); aItLOE.More(); aItLOE.Next()) { |
2832 | const TopoDS_Shape& aEOx = aItLOE.Value(); |
2833 | TopExp_Explorer aExpVx(aEOx, TopAbs_VERTEX); |
2834 | for (; aExpVx.More(); aExpVx.Next()) { |
2835 | const TopoDS_Shape& aVx = aExpVx.Current(); |
2836 | if (aVx.IsSame(aV)) { |
2837 | break; |
2838 | } |
2839 | } |
2840 | // |
2841 | if (!aExpVx.More()) { |
2842 | bVertValid = Standard_False; |
2843 | break; |
2844 | } |
2845 | } |
2846 | // |
2847 | if (bVertValid) { |
2848 | aVO = aV; |
2849 | break; |
2850 | } |
2851 | } |
2852 | } |
2853 | // |
2854 | if (aVO1.IsNull() || aVO2.IsNull() || aVO1.IsSame(aVO2)) { |
2855 | return Standard_False; |
2856 | } |
2857 | // |
2858 | // check positions of the offset and original vertices |
2859 | const gp_Pnt& aPI1 = BRep_Tool::Pnt(aVI1); |
2860 | const gp_Pnt& aPI2 = BRep_Tool::Pnt(aVI2); |
2861 | const gp_Pnt& aPO1 = BRep_Tool::Pnt(aVO1); |
2862 | const gp_Pnt& aPO2 = BRep_Tool::Pnt(aVO2); |
2863 | // |
2864 | gp_Vec aVI(aPI1, aPI2); |
2865 | gp_Vec aVO(aPO1, aPO2); |
2866 | // |
2867 | Standard_Real anAngle = aVI.Angle(aVO); |
2868 | Standard_Boolean bInverted = Abs(anAngle - M_PI) < 1.e-4; |
2869 | if (bInverted) { |
2870 | TopTools_ListIteratorOfListOfShape aItLEIm(aLEImages); |
2871 | for (; aItLEIm.More(); aItLEIm.Next()) { |
2872 | const TopoDS_Shape& aEInvr = aItLEIm.Value(); |
2873 | theMEInverted.Add(aEInvr); |
2874 | } |
2875 | } |
2876 | return bInverted; |
2877 | } |
2878 | |
baaacd46 |
2879 | //======================================================================= |
2880 | //function : CheckInvertedBlock |
2881 | //purpose : Checks if it is possible to remove the block containing |
2882 | // inverted edges |
2883 | //======================================================================= |
2884 | Standard_Boolean CheckInvertedBlock(const TopoDS_Shape& theCB, |
2885 | const TopTools_ListOfShape& theLCBF, |
2886 | const TopTools_MapOfShape& theMEInverted, |
2887 | const TopTools_DataMapOfShapeListOfShape& theOEOrigins, |
2888 | BRepOffset_DataMapOfShapeMapOfShape& theDMCBVInverted, |
2889 | BRepOffset_DataMapOfShapeMapOfShape& theDMCBVAll) |
2890 | { |
2891 | // For possible removal of the block: |
2892 | // 1. There should be more than just one face in the block |
b2d1851c |
2893 | if (theCB.NbChildren() < 2) { |
baaacd46 |
2894 | return Standard_False; |
2895 | } |
2896 | // |
2897 | // 2. The block should at least contain two connected inverted edges with |
2898 | // different origins (not just two images/splits of the same edge) |
2899 | TopTools_MapOfShape aMECBInv; |
2900 | TopoDS_Compound aCECBInv; |
2901 | BRep_Builder().MakeCompound(aCECBInv); |
2902 | // |
2903 | TopExp_Explorer aExp(theCB, TopAbs_EDGE); |
2904 | for (; aExp.More(); aExp.Next()) { |
2905 | const TopoDS_Shape& aE = aExp.Current(); |
2906 | if (theMEInverted.Contains(aE)) { |
2907 | if (aMECBInv.Add(aE)) { |
2908 | BRep_Builder().Add(aCECBInv, aE); |
2909 | } |
2910 | } |
2911 | } |
2912 | // |
2913 | if (aMECBInv.Extent() < 2) { |
2914 | return Standard_False; |
2915 | } |
2916 | // |
2917 | // check that the edges are connected and different |
2918 | TopTools_ListOfShape aLCBE; |
2919 | BOPTools_AlgoTools::MakeConnexityBlocks(aCECBInv, TopAbs_VERTEX, TopAbs_EDGE, aLCBE); |
2920 | // |
2921 | TopTools_ListIteratorOfListOfShape aItLCBE(aLCBE); |
2922 | for (; aItLCBE.More(); aItLCBE.Next()) { |
2923 | const TopoDS_Shape& aCBE = aItLCBE.Value(); |
2924 | // count the unique edges in the block |
2925 | Standard_Integer aNbUnique = 0; |
2926 | TopTools_MapOfShape aMEOrigins; |
2927 | TopoDS_Iterator aItE(aCBE); |
2928 | for (; aItE.More(); aItE.Next()) { |
2929 | const TopoDS_Shape& aE = aItE.Value(); |
2930 | const TopTools_ListOfShape *pLEOr = theOEOrigins.Seek(aE); |
2931 | if (!pLEOr) { |
2932 | aMEOrigins.Add(aE); |
2933 | ++aNbUnique; |
2934 | continue; |
2935 | } |
2936 | TopTools_ListIteratorOfListOfShape aItLEOr(*pLEOr); |
2937 | for (; aItLEOr.More(); aItLEOr.Next()) { |
2938 | const TopoDS_Shape& aEOr = aItLEOr.Value(); |
2939 | if (aMEOrigins.Add(aEOr)) { |
2940 | ++aNbUnique; |
2941 | } |
2942 | } |
2943 | } |
2944 | // |
2945 | if (aNbUnique >= 2) { |
2946 | break; |
2947 | } |
2948 | } |
2949 | // |
2950 | if (!aItLCBE.More()) { |
2951 | return Standard_False; |
2952 | } |
2953 | // |
2954 | // 3. the block should not contain inverted edges which vertices |
2955 | // are contained in other blocks |
2956 | // |
2957 | // collect vertices from inverted edges and compare them with |
2958 | // vertices from other blocks |
2959 | TopTools_MapOfShape* pMVInverted = theDMCBVInverted.ChangeSeek(theCB); |
2960 | TopTools_MapOfShape* pMVAll = theDMCBVAll.ChangeSeek(theCB); |
2961 | if (!pMVInverted) { |
2962 | pMVInverted = theDMCBVInverted.Bound(theCB, TopTools_MapOfShape()); |
2963 | pMVAll = theDMCBVAll.Bound(theCB, TopTools_MapOfShape()); |
2964 | // |
2965 | GetVerticesOnEdges(theCB, theMEInverted, *pMVInverted, *pMVAll); |
2966 | } |
2967 | // |
2968 | TopTools_ListIteratorOfListOfShape aItLCB1(theLCBF); |
2969 | for (; aItLCB1.More(); aItLCB1.Next()) { |
2970 | const TopoDS_Shape& aCB1 = aItLCB1.Value(); |
2971 | if (aCB1.IsSame(theCB)) { |
2972 | continue; |
2973 | } |
2974 | // |
2975 | // collect vertices from inverted edges |
2976 | TopTools_MapOfShape* pMVInverted1 = theDMCBVInverted.ChangeSeek(aCB1); |
2977 | TopTools_MapOfShape* pMVAll1 = theDMCBVAll.ChangeSeek(aCB1); |
2978 | if (!pMVInverted1) { |
2979 | pMVInverted1 = theDMCBVInverted.Bound(aCB1, TopTools_MapOfShape()); |
2980 | pMVAll1 = theDMCBVAll.Bound(aCB1, TopTools_MapOfShape()); |
2981 | // |
2982 | GetVerticesOnEdges(aCB1, theMEInverted, *pMVInverted1, *pMVAll1); |
2983 | } |
2984 | // |
2985 | if (pMVInverted->HasIntersection(*pMVAll1)) { |
2986 | return Standard_False; |
2987 | } |
2988 | } |
2989 | // |
2990 | return Standard_True; |
2991 | } |
2992 | |
2993 | //======================================================================= |
2994 | //function : GetVerticesOnEdges |
2995 | //purpose : Get vertices from the given shape belonging to the given edges |
2996 | //======================================================================= |
2997 | void GetVerticesOnEdges(const TopoDS_Shape& theCB, |
2998 | const TopTools_MapOfShape& theEdges, |
2999 | TopTools_MapOfShape& theVerticesOnEdges, |
3000 | TopTools_MapOfShape& theAllVertices) |
3001 | { |
3002 | TopExp_Explorer aExp(theCB, TopAbs_EDGE); |
3003 | for (; aExp.More(); aExp.Next()) { |
3004 | const TopoDS_Shape& aE = aExp.Current(); |
3005 | Standard_Boolean bOnGivenEdge = theEdges.Contains(aE); |
3006 | for (TopoDS_Iterator aItV(aE); aItV.More(); aItV.Next()) { |
3007 | theAllVertices.Add(aItV.Value()); |
3008 | if (bOnGivenEdge) { |
3009 | theVerticesOnEdges.Add(aItV.Value()); |
3010 | } |
3011 | } |
3012 | } |
3013 | } |
3014 | |
ecf4f17c |
3015 | //======================================================================= |
3016 | //function : RemoveInvalidSplitsByInvertedEdges |
3017 | //purpose : Looking for the invalid faces containing inverted edges |
3018 | // that can be safely removed |
3019 | //======================================================================= |
3020 | void RemoveInvalidSplitsByInvertedEdges(const TopTools_MapOfShape& theMEInverted, |
baaacd46 |
3021 | const TopTools_DataMapOfShapeListOfShape& theOEOrigins, |
ecf4f17c |
3022 | TopTools_IndexedDataMapOfShapeListOfShape& theInvFaces, |
3023 | TopTools_IndexedDataMapOfShapeListOfShape& theFImages, |
3024 | TopTools_IndexedMapOfShape& theMERemoved) |
3025 | { |
3026 | if (theMEInverted.IsEmpty()) { |
3027 | return; |
3028 | } |
3029 | // |
3030 | // check the faces on regularity, i.e. the splits of the same face |
3031 | // should not be connected only by vertex. Such irregular splits |
3032 | // will have to be rebuilt and cannot be removed. |
3033 | // |
baaacd46 |
3034 | BRep_Builder aBB; |
3035 | TopTools_IndexedMapOfShape aMEAvoid; |
ecf4f17c |
3036 | TopTools_DataMapOfShapeListOfShape aDMVF; |
3037 | Standard_Integer aNb = theFImages.Extent(), i; |
3038 | for (i = 1; i <= aNb; ++i) { |
3039 | const TopTools_ListOfShape& aLFIm = theFImages(i); |
3040 | // |
3041 | TopoDS_Compound aCFIm; |
baaacd46 |
3042 | aBB.MakeCompound(aCFIm); |
ecf4f17c |
3043 | // |
3044 | TopTools_DataMapOfShapeListOfShape aDMEF; |
3045 | TopTools_ListIteratorOfListOfShape aIt(aLFIm); |
3046 | for (; aIt.More(); aIt.Next()) { |
3047 | const TopoDS_Shape& aF = aIt.Value(); |
baaacd46 |
3048 | aBB.Add(aCFIm, aF); |
ecf4f17c |
3049 | // |
3050 | // make a map to use only outer edges |
3051 | TopExp_Explorer aExp(aF, TopAbs_EDGE); |
3052 | for (; aExp.More(); aExp.Next()) { |
3053 | const TopoDS_Shape& aE = aExp.Current(); |
3054 | // |
3055 | TopTools_ListOfShape *pLF = aDMEF.ChangeSeek(aE); |
3056 | if (!pLF) { |
baaacd46 |
3057 | pLF = aDMEF.Bound(aE, TopTools_ListOfShape()); |
ecf4f17c |
3058 | } |
3059 | else { |
ecf4f17c |
3060 | // internal edges should not be used |
3061 | aMEAvoid.Add(aE); |
3062 | } |
baaacd46 |
3063 | AppendToList(*pLF, aF); |
ecf4f17c |
3064 | } |
3065 | // |
3066 | // fill connection map of the vertices of inverted edges to faces |
3067 | aExp.Init(aF, TopAbs_VERTEX); |
3068 | for (; aExp.More(); aExp.Next()) { |
3069 | const TopoDS_Shape& aV = aExp.Current(); |
3070 | // |
3071 | TopTools_ListOfShape *pLF = aDMVF.ChangeSeek(aV); |
3072 | if (!pLF) { |
baaacd46 |
3073 | pLF = aDMVF.Bound(aV, TopTools_ListOfShape()); |
ecf4f17c |
3074 | } |
baaacd46 |
3075 | AppendToList(*pLF, aF); |
ecf4f17c |
3076 | } |
3077 | } |
3078 | // |
3079 | // for the splits to be regular they should form only one block |
3080 | TopTools_ListOfShape aLCBF; |
3081 | BOPTools_AlgoTools::MakeConnexityBlocks(aCFIm, TopAbs_EDGE, TopAbs_FACE, aLCBF); |
baaacd46 |
3082 | if (aLCBF.Extent() == 1) { |
3083 | continue; |
3084 | } |
ecf4f17c |
3085 | // |
baaacd46 |
3086 | // check if the inverted edges create the irregularity |
3087 | BRepOffset_DataMapOfShapeMapOfShape aDMCBVInverted, aDMCBVAll; |
3088 | // |
3089 | TopTools_ListIteratorOfListOfShape aItLCB(aLCBF); |
3090 | for (; aItLCB.More(); aItLCB.Next()) { |
3091 | const TopoDS_Shape& aCB = aItLCB.Value(); |
3092 | // |
3093 | // check if it is possible to remove the block |
3094 | if (!CheckInvertedBlock(aCB, aLCBF, theMEInverted, theOEOrigins, aDMCBVInverted, aDMCBVAll)) { |
3095 | // non of the edges in this block should be removed |
3096 | TopExp::MapShapes(aCB, TopAbs_EDGE, aMEAvoid); |
3097 | continue; |
ecf4f17c |
3098 | } |
3099 | } |
3100 | } |
3101 | // |
3102 | // all edges not included in aMEAvoid can be removed |
3103 | TopTools_MapOfShape aMERem; |
3104 | TopTools_MapIteratorOfMapOfShape aItM(theMEInverted); |
3105 | for (; aItM.More(); aItM.Next()) { |
3106 | const TopoDS_Shape& aE = aItM.Value(); |
3107 | if (!aMEAvoid.Contains(aE)) { |
3108 | TopoDS_Iterator aIt(aE); |
3109 | for (; aIt.More(); aIt.Next()) { |
3110 | const TopoDS_Shape& aV = aIt.Value(); |
3111 | const TopTools_ListOfShape *pLF = aDMVF.Seek(aV); |
3112 | if (pLF && (pLF->Extent() > 3)) { |
3113 | aMERem.Add(aE); |
3114 | break; |
3115 | } |
3116 | } |
3117 | } |
3118 | } |
3119 | // |
3120 | if (aMERem.IsEmpty()) { |
3121 | return; |
3122 | } |
3123 | // |
3124 | // all invalid faces containing these edges can be removed |
3125 | TopTools_IndexedDataMapOfShapeListOfShape aInvFaces; |
3126 | TopTools_MapOfShape aMFRem; |
3127 | TopTools_IndexedMapOfShape aMFToUpdate; |
3128 | aNb = theInvFaces.Extent(); |
3129 | for (i = 1; i <= aNb; ++i) { |
3130 | const TopoDS_Shape& aF = theInvFaces.FindKey(i); |
3131 | TopTools_ListOfShape& aLFIm = theInvFaces(i); |
3132 | // |
3133 | TopTools_ListIteratorOfListOfShape aIt(aLFIm); |
3134 | for (; aIt.More(); ) { |
3135 | const TopoDS_Shape& aFIm = aIt.Value(); |
3136 | // |
3137 | // to be removed the face should have at least two not connected |
3138 | // inverted edges |
3139 | TopoDS_Compound aCEInv; |
baaacd46 |
3140 | aBB.MakeCompound(aCEInv); |
ecf4f17c |
3141 | TopExp_Explorer aExp(aFIm, TopAbs_EDGE); |
3142 | for (; aExp.More(); aExp.Next()) { |
3143 | const TopoDS_Shape& aE = aExp.Current(); |
ecf4f17c |
3144 | if (aMERem.Contains(aE)) { |
baaacd46 |
3145 | aBB.Add(aCEInv, aE); |
ecf4f17c |
3146 | } |
3147 | } |
3148 | // |
3149 | // check connectivity |
3150 | TopTools_ListOfShape aLCBE; |
3151 | BOPTools_AlgoTools::MakeConnexityBlocks(aCEInv, TopAbs_VERTEX, TopAbs_EDGE, aLCBE); |
3152 | // |
3153 | if (aLCBE.Extent() >= 2) { |
3154 | aMFToUpdate.Add(aF); |
3155 | aMFRem.Add(aFIm); |
3156 | aLFIm.Remove(aIt); |
3157 | } |
3158 | else { |
3159 | aIt.Next(); |
3160 | } |
3161 | } |
3162 | // |
3163 | if (aLFIm.Extent()) { |
3164 | aInvFaces.Add(aF, aLFIm); |
3165 | } |
3166 | } |
3167 | // |
3168 | if (aMFRem.IsEmpty()) { |
3169 | return; |
3170 | } |
3171 | // |
3172 | theInvFaces = aInvFaces; |
3173 | // remove from splits |
3174 | aNb = aMFToUpdate.Extent(); |
3175 | for (i = 1; i <= aNb; ++i) { |
3176 | const TopoDS_Shape& aF = aMFToUpdate(i); |
3177 | TopTools_ListOfShape& aLFIm = theFImages.ChangeFromKey(aF); |
3178 | // |
3179 | TopTools_ListIteratorOfListOfShape aIt(aLFIm); |
3180 | for (; aIt.More(); ) { |
3181 | const TopoDS_Shape& aFIm = aIt.Value(); |
3182 | if (aMFRem.Contains(aFIm)) { |
3183 | TopExp::MapShapes(aFIm, TopAbs_EDGE, theMERemoved); |
3184 | aLFIm.Remove(aIt); |
3185 | } |
3186 | else { |
3187 | aIt.Next(); |
3188 | } |
3189 | } |
3190 | } |
3191 | } |
3192 | |
3193 | //======================================================================= |
3194 | //function : RemoveInvalidSplitsFromValid |
3195 | //purpose : Removing invalid splits of faces from valid |
3196 | //======================================================================= |
3197 | void RemoveInvalidSplitsFromValid(const TopTools_IndexedDataMapOfShapeListOfShape& theInvFaces, |
3198 | const TopTools_DataMapOfShapeShape& theArtInvFaces, |
3199 | const TopTools_MapOfShape& theMEInverted, |
9e9b826a |
3200 | const BRepOffset_DataMapOfShapeMapOfShape& theDMFMVIE, |
ecf4f17c |
3201 | TopTools_IndexedDataMapOfShapeListOfShape& theFImages) |
3202 | { |
3203 | // Decide whether to remove the found invalid faces or not. |
3204 | // The procedure is the following: |
3205 | // 1. Make connexity blocks from invalid faces; |
3206 | // 2. Find free edges in this blocks; |
3207 | // 3. If all free edges are valid for the faces - remove block. |
3208 | // |
3209 | TopTools_MapOfShape aMFence, aMFToRem; |
3210 | TopoDS_Compound aCFInv; |
3211 | BRep_Builder aBB; |
3212 | aBB.MakeCompound(aCFInv); |
3213 | TopTools_ListIteratorOfListOfShape aItLF; |
3214 | // |
3215 | // make compound of invalid faces |
3216 | TopTools_DataMapOfShapeShape aDMIFOF; |
3217 | Standard_Integer i, aNb = theInvFaces.Extent(); |
3218 | for (i = 1; i <= aNb; ++i) { |
3219 | const TopoDS_Shape& aF = theInvFaces.FindKey(i); |
3220 | // artificially invalid faces should not be removed |
3221 | if (theArtInvFaces.IsBound(aF)) { |
3222 | continue; |
3223 | } |
3224 | const TopTools_ListOfShape& aLFInv = theInvFaces(i); |
3225 | aItLF.Initialize(aLFInv); |
3226 | for (; aItLF.More(); aItLF.Next()) { |
3227 | const TopoDS_Shape& aFIm = aItLF.Value(); |
3228 | if (aMFence.Add(aFIm)) { |
3229 | aBB.Add(aCFInv, aFIm); |
3230 | aDMIFOF.Bind(aFIm, aF); |
3231 | } |
3232 | } |
3233 | } |
3234 | // |
3235 | // make connexity blocks |
3236 | TopTools_ListOfShape aLCBInv; |
3237 | BOPTools_AlgoTools::MakeConnexityBlocks(aCFInv, TopAbs_EDGE, TopAbs_FACE, aLCBInv); |
3238 | // |
3239 | // analyze each block |
3240 | aItLF.Initialize(aLCBInv); |
3241 | for (; aItLF.More(); aItLF.Next()) { |
3242 | const TopoDS_Shape& aCB = aItLF.Value(); |
3243 | // |
3244 | // if connexity block contains only one face - it should be removed; |
3245 | TopExp_Explorer aExp(aCB, TopAbs_FACE); |
3246 | aExp.Next(); |
3247 | if (aExp.More()) { |
3248 | // check if there are valid images left |
3249 | aExp.Init(aCB, TopAbs_FACE); |
3250 | for (; aExp.More(); aExp.Next()) { |
3251 | const TopoDS_Shape& aFIm = aExp.Current(); |
3252 | const TopoDS_Shape& aF = aDMIFOF.Find(aFIm); |
3253 | // |
3254 | const TopTools_ListOfShape& aLFIm = theFImages.FindFromKey(aF); |
3255 | const TopTools_ListOfShape& aLFInv = theInvFaces.FindFromKey(aF); |
3256 | // |
3257 | if (aLFIm.Extent() == aLFInv.Extent()) { |
3258 | break; |
3259 | } |
3260 | } |
3261 | } |
3262 | // |
3263 | if (!aExp.More()) { |
3264 | aExp.Init(aCB, TopAbs_FACE); |
3265 | for (; aExp.More(); aExp.Next()) { |
3266 | const TopoDS_Shape& aF = aExp.Current(); |
3267 | aMFToRem.Add(aF); |
3268 | } |
3269 | continue; |
3270 | } |
3271 | // |
3272 | // remove faces connected by inverted edges |
3273 | TopTools_IndexedDataMapOfShapeListOfShape aDMEF; |
3274 | TopExp::MapShapesAndAncestors(aCB, TopAbs_EDGE, TopAbs_FACE, aDMEF); |
3275 | // |
9e9b826a |
3276 | TopTools_DataMapOfShapeListOfShape aDMFF; |
ecf4f17c |
3277 | aExp.Init(aCB, TopAbs_FACE); |
3278 | for (; aExp.More(); aExp.Next()) { |
3279 | const TopoDS_Shape& aFCB = aExp.Current(); |
9e9b826a |
3280 | const TopoDS_Shape& aF = aDMIFOF.Find (aFCB); |
3281 | TopTools_ListOfShape* pList = aDMFF.ChangeSeek (aF); |
3282 | if (!pList) |
3283 | pList = aDMFF.Bound (aF, TopTools_ListOfShape()); |
3284 | pList->Append (aFCB); |
3285 | } |
3286 | |
3287 | for (TopTools_DataMapOfShapeListOfShape::Iterator itM (aDMFF); itM.More(); itM.Next()) |
3288 | { |
3289 | const TopoDS_Shape& aF = itM.Key(); |
3290 | const TopTools_MapOfShape* pValidInverted = theDMFMVIE.Seek (aF); |
3291 | |
3292 | // either remove all of these faces or none. |
3293 | const TopTools_ListOfShape& aLFCB = itM.Value(); |
3294 | TopTools_ListOfShape::Iterator itL (aLFCB); |
3295 | for (; itL.More(); itL.Next()) |
3296 | { |
3297 | const TopoDS_Shape& aFCB = itL.Value(); |
3298 | TopExp_Explorer aExpE(aFCB, TopAbs_EDGE); |
3299 | for (; aExpE.More(); aExpE.Next()) { |
3300 | const TopoDS_Shape& aECB = aExpE.Current(); |
3301 | if (pValidInverted && pValidInverted->Contains (aECB)) |
ecf4f17c |
3302 | break; |
9e9b826a |
3303 | if (aDMEF.FindFromKey(aECB).Extent() > 1) |
3304 | { |
3305 | if (!theMEInverted.Contains(aECB)) |
3306 | break; |
ecf4f17c |
3307 | } |
3308 | } |
9e9b826a |
3309 | if (!aExpE.More()) |
3310 | // if one removed - remove all |
3311 | break; |
ecf4f17c |
3312 | } |
9e9b826a |
3313 | if (itL.More()) |
3314 | { |
3315 | for (itL.Initialize (aLFCB); itL.More(); itL.Next()) |
3316 | { |
3317 | aMFToRem.Add (itL.Value()); |
3318 | } |
ecf4f17c |
3319 | } |
3320 | } |
3321 | } |
3322 | // |
3323 | if (aMFToRem.Extent()) { |
3324 | // remove invalid faces from images |
3325 | aNb = theInvFaces.Extent(); |
3326 | for (i = 1; i <= aNb; ++i) { |
3327 | const TopoDS_Shape& aF = theInvFaces.FindKey(i); |
3328 | TopTools_ListOfShape& aLFImages = theFImages.ChangeFromKey(aF); |
3329 | aItLF.Initialize(aLFImages); |
3330 | for (; aItLF.More();) { |
3331 | const TopoDS_Shape& aFIm = aItLF.Value(); |
3332 | if (aMFToRem.Contains(aFIm)) { |
3333 | aLFImages.Remove(aItLF); |
3334 | } |
3335 | else { |
3336 | aItLF.Next(); |
3337 | } |
3338 | } |
3339 | } |
3340 | } |
3341 | } |
3342 | |
6f04cbb1 |
3343 | namespace |
3344 | { |
3345 | //======================================================================= |
3346 | //function : buildPairs |
3347 | //purpose : builds pairs of shapes |
3348 | //======================================================================= |
3349 | static void buildPairs (const TopTools_IndexedMapOfShape& theSMap, |
3350 | BRepOffset_DataMapOfShapeMapOfShape& theIntPairs) |
3351 | { |
3352 | const Standard_Integer aNbS = theSMap.Extent(); |
3353 | if (aNbS < 2) |
3354 | return; |
3355 | for (Standard_Integer it1 = 1; it1 <= aNbS; ++it1) |
3356 | { |
3357 | const TopoDS_Shape& aS = theSMap (it1); |
3358 | if (!theIntPairs.IsBound (aS)) |
3359 | theIntPairs.Bind (aS, TopTools_MapOfShape()); |
3360 | } |
3361 | |
3362 | for (Standard_Integer it1 = 1; it1 <= aNbS; ++it1) |
3363 | { |
3364 | const TopoDS_Shape& aS1 = theSMap (it1); |
3365 | TopTools_MapOfShape& aMap1 = theIntPairs (aS1); |
3366 | for (Standard_Integer it2 = it1 + 1; it2 <= aNbS; ++it2) |
3367 | { |
3368 | const TopoDS_Shape& aS2 = theSMap (it2); |
3369 | aMap1.Add (aS2); |
3370 | theIntPairs (aS2).Add (aS1); |
3371 | } |
3372 | } |
3373 | } |
3374 | |
3375 | //======================================================================= |
3376 | //function : buildIntersectionPairs |
3377 | //purpose : builds intersection pairs |
3378 | //======================================================================= |
3379 | static void buildIntersectionPairs (const TopTools_IndexedDataMapOfShapeListOfShape& theFImages, |
3380 | const TopTools_IndexedDataMapOfShapeListOfShape& theInvFaces, |
3381 | const BOPAlgo_Builder& theBuilder, |
3382 | const TopTools_MapOfShape& theMFRemoved, |
3383 | const TopTools_DataMapOfShapeShape& theFOrigins, |
3384 | NCollection_DataMap<TopoDS_Shape, |
3385 | BRepOffset_DataMapOfShapeMapOfShape, |
3386 | TopTools_ShapeMapHasher>& theIntPairs) |
3387 | { |
3388 | TopAbs_ShapeEnum aCType = TopAbs_VERTEX; |
3389 | // Build connection map from vertices to faces |
3390 | TopTools_IndexedDataMapOfShapeListOfShape aDMVF; |
3391 | TopExp::MapShapesAndAncestors (theBuilder.Shape(), aCType, TopAbs_FACE, aDMVF); |
3392 | |
3393 | const TopTools_DataMapOfShapeListOfShape& anImages = theBuilder.Images(); |
3394 | const TopTools_DataMapOfShapeListOfShape& anOrigins = theBuilder.Origins(); |
3395 | |
3396 | // Find all faces connected to the not removed faces and build intersection pairs among them. |
3397 | // For removed faces intersect only those connected to each other. |
3398 | |
3399 | for (Standard_Integer iF = 1; iF <= theInvFaces.Extent(); ++iF) |
3400 | { |
3401 | const TopoDS_Shape& aFInv = theInvFaces.FindKey (iF); |
3402 | |
3403 | TopoDS_Compound aCF, aCFRem; |
3404 | BRep_Builder().MakeCompound (aCF); |
3405 | BRep_Builder().MakeCompound (aCFRem); |
3406 | |
3407 | for (Standard_Integer iC = 0; iC < 2; ++iC) |
3408 | { |
3409 | const TopTools_ListOfShape& aLF = !iC ? theInvFaces (iF) : theFImages.FindFromKey (aFInv); |
3410 | |
3411 | for (TopTools_ListOfShape::Iterator it (aLF); it.More(); it.Next()) |
3412 | { |
3413 | TopTools_ListOfShape aLFIm; |
3414 | TakeModified (it.Value(), anImages, aLFIm); |
3415 | |
3416 | for (TopTools_ListOfShape::Iterator itIm (aLFIm); itIm.More(); itIm.Next()) |
3417 | { |
3418 | const TopoDS_Shape& aFIm = itIm.Value(); |
3419 | |
3420 | if (theMFRemoved.Contains (aFIm)) |
3421 | BRep_Builder().Add (aCFRem, aFIm); |
3422 | else |
3423 | BRep_Builder().Add (aCF, aFIm); |
3424 | } |
3425 | } |
3426 | } |
3427 | |
3428 | TopTools_ListOfShape aLCB; |
3429 | BOPTools_AlgoTools::MakeConnexityBlocks (aCF, TopAbs_EDGE, TopAbs_FACE, aLCB); |
3430 | |
3431 | if (aLCB.IsEmpty()) |
3432 | continue; |
3433 | |
3434 | BRepOffset_DataMapOfShapeMapOfShape* pFInterMap = |
3435 | theIntPairs.Bound (aFInv, BRepOffset_DataMapOfShapeMapOfShape()); |
3436 | |
3437 | // build pairs for not removed faces |
3438 | for (TopTools_ListOfShape::Iterator itCB (aLCB); itCB.More(); itCB.Next()) |
3439 | { |
3440 | const TopoDS_Shape& aCB = itCB.Value(); |
3441 | |
3442 | TopTools_IndexedMapOfShape aMFInter; |
3443 | for (TopExp_Explorer exp (aCB, aCType); exp.More(); exp.Next()) |
3444 | { |
3445 | const TopoDS_Shape& aCS = exp.Current(); |
3446 | const TopTools_ListOfShape* pLFV = aDMVF.Seek (aCS); |
3447 | if (!pLFV) |
3448 | continue; |
3449 | |
3450 | for (TopTools_ListOfShape::Iterator itFV (*pLFV); itFV.More(); itFV.Next()) |
3451 | { |
3452 | const TopoDS_Shape& aFConnected = itFV.Value(); |
3453 | |
3454 | TopTools_ListOfShape aLFOr; |
3455 | TakeModified (aFConnected, anOrigins, aLFOr); |
3456 | for (TopTools_ListOfShape::Iterator itOr (aLFOr); itOr.More(); itOr.Next()) |
3457 | { |
3458 | const TopoDS_Shape* pFOr = theFOrigins.Seek (itOr.Value()); |
3459 | if (pFOr) |
3460 | aMFInter.Add (*pFOr); |
3461 | } |
3462 | } |
3463 | } |
3464 | |
3465 | // build intersection pairs |
3466 | buildPairs (aMFInter, *pFInterMap); |
3467 | } |
3468 | |
3469 | aLCB.Clear(); |
3470 | BOPTools_AlgoTools::MakeConnexityBlocks (aCFRem, TopAbs_EDGE, TopAbs_FACE, aLCB); |
3471 | |
3472 | if (aLCB.IsEmpty()) |
3473 | continue; |
3474 | |
3475 | for (TopTools_ListOfShape::Iterator itCB (aLCB); itCB.More(); itCB.Next()) |
3476 | { |
3477 | const TopoDS_Shape& aCB = itCB.Value(); |
3478 | |
3479 | TopTools_IndexedDataMapOfShapeListOfShape aDMEF; |
3480 | for (TopExp_Explorer exp (aCB, aCType); exp.More(); exp.Next()) |
3481 | { |
3482 | const TopoDS_Shape& aCS = exp.Current(); |
3483 | const TopTools_ListOfShape* pLFV = aDMVF.Seek (aCS); |
3484 | if (!pLFV) |
3485 | continue; |
3486 | |
3487 | for (TopTools_ListOfShape::Iterator itFV (*pLFV); itFV.More(); itFV.Next()) |
3488 | { |
3489 | const TopoDS_Shape& aFConnected = itFV.Value(); |
3490 | TopExp::MapShapesAndAncestors (aFConnected, TopAbs_EDGE, TopAbs_FACE, aDMEF); |
3491 | } |
3492 | } |
3493 | |
3494 | for (Standard_Integer iE = 1; iE <= aDMEF.Extent(); ++iE) |
3495 | { |
3496 | const TopTools_ListOfShape& aLFConnected = aDMEF (iE); |
3497 | if (aLFConnected.Extent() < 2) |
3498 | continue; |
3499 | |
3500 | TopTools_IndexedMapOfShape aMFInter; |
3501 | for (TopTools_ListOfShape::Iterator itLF (aLFConnected); itLF.More(); itLF.Next()) |
3502 | { |
3503 | const TopoDS_Shape& aFConnected = itLF.Value(); |
3504 | |
3505 | TopTools_ListOfShape aLFOr; |
3506 | TakeModified (aFConnected, anOrigins, aLFOr); |
3507 | for (TopTools_ListOfShape::Iterator itOr (aLFOr); itOr.More(); itOr.Next()) |
3508 | { |
3509 | const TopoDS_Shape* pFOr = theFOrigins.Seek (itOr.Value()); |
3510 | if (pFOr) |
3511 | aMFInter.Add (*pFOr); |
3512 | } |
3513 | } |
3514 | |
3515 | buildPairs (aMFInter, *pFInterMap); |
3516 | } |
3517 | } |
3518 | } |
3519 | } |
3520 | |
3521 | } |
3522 | |
ecf4f17c |
3523 | //======================================================================= |
3524 | //function : RemoveInsideFaces |
3525 | //purpose : Looking for the inside faces that can be safely removed |
3526 | //======================================================================= |
3527 | void RemoveInsideFaces(TopTools_IndexedDataMapOfShapeListOfShape& theFImages, |
3528 | TopTools_IndexedDataMapOfShapeListOfShape& theInvFaces, |
3529 | const TopTools_DataMapOfShapeShape& theArtInvFaces, |
3530 | const TopTools_IndexedMapOfShape& theInvEdges, |
e08a9b03 |
3531 | const TopTools_MapOfShape& theInvertedEdges, |
3532 | const TopTools_ListOfShape& theInvertedFaces, |
ecf4f17c |
3533 | const TopTools_IndexedMapOfShape& theMFToCheckInt, |
0da0275c |
3534 | const TopTools_IndexedMapOfShape& theMFInvInHole, |
3535 | const TopoDS_Shape& theFHoles, |
6f04cbb1 |
3536 | BRepOffset_MakeOffset_InterResults& theIntRes, |
ecf4f17c |
3537 | TopTools_IndexedMapOfShape& theMERemoved, |
baaacd46 |
3538 | TopTools_IndexedMapOfShape& theMEInside, |
ecf4f17c |
3539 | TopoDS_Shape& theSolids) |
3540 | { |
1155d05a |
3541 | TopTools_ListOfShape aLS; |
ecf4f17c |
3542 | TopTools_MapOfShape aMFence; |
3543 | TopTools_IndexedMapOfShape aMFInv; |
3544 | TopTools_ListIteratorOfListOfShape aItLF; |
3545 | TopTools_DataMapOfShapeShape aDMFImF; |
3546 | // |
3547 | Standard_Integer i, aNb = theFImages.Extent(); |
3548 | for (i = 1; i <= aNb; ++i) { |
3549 | const TopoDS_Shape& aF = theFImages.FindKey(i); |
3550 | // to avoid intersection of the splits of the same |
3551 | // offset faces among themselves make compound of the |
3552 | // splits and use it as one argument |
3553 | TopoDS_Compound aCFImi; |
3554 | BRep_Builder().MakeCompound(aCFImi); |
3555 | // |
3556 | for (Standard_Integer j = 0; j < 2; ++j) { |
3557 | const TopTools_ListOfShape* pLFSp = !j ? theInvFaces.Seek(aF) : &theFImages(i); |
3558 | if (!pLFSp) { |
3559 | continue; |
3560 | } |
3561 | // |
3562 | aItLF.Initialize(*pLFSp); |
3563 | for (; aItLF.More(); aItLF.Next()) { |
3564 | const TopoDS_Shape& aFIm = aItLF.Value(); |
3565 | if (aMFence.Add(aFIm)) { |
3566 | BRep_Builder().Add(aCFImi, aFIm); |
3567 | aDMFImF.Bind(aFIm, aF); |
3568 | if (!j) { |
3569 | aMFInv.Add(aFIm); |
3570 | } |
3571 | } |
3572 | } |
3573 | } |
3574 | // |
3575 | aLS.Append(aCFImi); |
3576 | } |
3577 | // |
3578 | // to make the solids more complete add for intersection also the faces |
3579 | // consisting only of invalid edges and not included into splits |
3580 | aNb = theMFToCheckInt.Extent(); |
3581 | for (i = 1; i <= aNb; ++i) { |
3582 | const TopoDS_Shape& aFSp = theMFToCheckInt(i); |
3583 | if (aMFence.Add(aFSp)) { |
3584 | aLS.Append(aFSp); |
3585 | } |
3586 | } |
3587 | // |
3588 | BOPAlgo_MakerVolume aMV; |
3589 | aMV.SetArguments(aLS); |
3590 | aMV.SetIntersect(Standard_True); |
3591 | aMV.Perform(); |
e08a9b03 |
3592 | if (aMV.HasErrors()) |
3593 | return; |
3594 | |
ecf4f17c |
3595 | // |
3596 | // get shapes connection for using in the rebuilding process |
3597 | // for the cases in which some of the intersection left undetected |
6f04cbb1 |
3598 | ShapesConnections(theInvFaces, theInvEdges, aDMFImF, aMV, theIntRes.SSInterfs); |
ecf4f17c |
3599 | // |
3600 | // find faces to remove |
3601 | const TopoDS_Shape& aSols = aMV.Shape(); |
3602 | // |
3603 | TopTools_IndexedDataMapOfShapeListOfShape aDMFS; |
3604 | TopExp::MapShapesAndAncestors(aSols, TopAbs_FACE, TopAbs_SOLID, aDMFS); |
3605 | // |
3606 | aNb = aDMFS.Extent(); |
3607 | if (!aNb) { |
3608 | return; |
3609 | } |
3610 | // |
3611 | // To use the created solids for classifications, firstly, it is necessary |
3612 | // to check them on validity - the created solids should be complete, |
3613 | // i.e. all faces should be included. |
3614 | // |
0da0275c |
3615 | TopTools_MapOfShape aMFToRem; |
ecf4f17c |
3616 | // Check completeness |
3617 | if (aMV.HasDeleted()) { |
0da0275c |
3618 | TopTools_IndexedMapOfShape aMEHoles; |
3619 | TopExp::MapShapes(theFHoles, TopAbs_EDGE, aMEHoles); |
bc4a3867 |
3620 | |
3621 | // Map edges of the solids to check the connectivity |
3622 | // of the removed invalid splits |
3623 | TopTools_IndexedMapOfShape aMESols; |
3624 | TopExp::MapShapes(aSols, TopAbs_EDGE, aMESols); |
3625 | |
ecf4f17c |
3626 | // perform additional check on faces |
3627 | aNb = theFImages.Extent(); |
3628 | for (i = 1; i <= aNb; ++i) { |
3629 | const TopTools_ListOfShape& aLFIm = theFImages(i); |
3630 | if (aLFIm.IsEmpty()) { |
3631 | continue; |
3632 | } |
bc4a3867 |
3633 | |
3634 | const TopoDS_Shape& aF = theFImages.FindKey(i); |
3635 | Standard_Boolean bInvalid = theInvFaces.Contains(aF); |
3636 | // For invalid faces it is allowed to be at least connected |
3637 | // to the solids, otherwise the solids are considered as broken |
3638 | Standard_Boolean bConnected = Standard_False; |
3639 | |
0da0275c |
3640 | Standard_Boolean bFaceKept = Standard_False; |
ecf4f17c |
3641 | aItLF.Initialize(aLFIm); |
3642 | for (; aItLF.More(); aItLF.Next()) { |
3643 | const TopoDS_Shape& aFIm = aItLF.Value(); |
3644 | if (!aMV.IsDeleted(aFIm)) { |
0da0275c |
3645 | bFaceKept = Standard_True; |
3646 | continue; |
3647 | } |
3648 | // |
3649 | TopExp_Explorer aExpE(aFIm, TopAbs_EDGE); |
3650 | for (; aExpE.More(); aExpE.Next()) { |
3651 | if (aMEHoles.Contains(aExpE.Current())) { |
3652 | bFaceKept = Standard_True; |
3653 | aMFToRem.Add(aFIm); |
3654 | break; |
3655 | } |
bc4a3867 |
3656 | if (!bFaceKept && bInvalid && !bConnected) |
3657 | bConnected = aMESols.Contains(aExpE.Current()); |
ecf4f17c |
3658 | } |
3659 | } |
3660 | // |
bc4a3867 |
3661 | if (!bFaceKept && !bConnected) { |
ecf4f17c |
3662 | return; |
3663 | } |
3664 | } |
3665 | } |
3666 | // |
baaacd46 |
3667 | TopTools_IndexedMapOfShape aMEBoundary; |
ecf4f17c |
3668 | aNb = aDMFS.Extent(); |
3669 | for (i = 1; i <= aNb; ++i) { |
baaacd46 |
3670 | const TopoDS_Shape& aFIm = aDMFS.FindKey(i); |
ecf4f17c |
3671 | const TopTools_ListOfShape& aLSol = aDMFS(i); |
3672 | if (aLSol.Extent() > 1) { |
ecf4f17c |
3673 | aMFToRem.Add(aFIm); |
3674 | } |
baaacd46 |
3675 | else if (aFIm.Orientation() != TopAbs_INTERNAL) { |
3676 | TopExp::MapShapes(aFIm, TopAbs_EDGE, aMEBoundary); |
3677 | } |
ecf4f17c |
3678 | } |
e08a9b03 |
3679 | |
3680 | // Tool for getting the splits of faces |
3681 | const TopTools_DataMapOfShapeListOfShape& aMVIms = aMV.Images(); |
3682 | |
ecf4f17c |
3683 | // update invalid faces with images |
3684 | aNb = aMFInv.Extent(); |
3685 | for (i = 1; i <= aNb; ++i) { |
3686 | const TopoDS_Shape& aFInv = aMFInv(i); |
e08a9b03 |
3687 | TakeModified(aFInv, aMVIms, aMFInv); |
ecf4f17c |
3688 | } |
e08a9b03 |
3689 | |
3690 | // Take into account the faces invalid by inverted edges |
3691 | for (TopTools_ListOfShape::Iterator itLF(theInvertedFaces); itLF.More(); itLF.Next()) |
3692 | TakeModified(itLF.Value(), aMVIms, aMFInv); |
3693 | |
0da0275c |
3694 | // check if the invalid faces inside the holes are really invalid: |
3695 | // check its normal direction - if it has changed relatively the |
3696 | // original face the offset face is invalid and should be kept for rebuilding |
3697 | Standard_Integer aNbFH = theMFInvInHole.Extent(); |
3698 | for (i = 1; i <= aNbFH; ++i) { |
3699 | const TopoDS_Shape& aFInv = theMFInvInHole(i); |
3700 | TopTools_ListOfShape aLFInvIm = aMV.Modified(aFInv); |
3701 | if (aLFInvIm.IsEmpty()) { |
3702 | aLFInvIm.Append(aFInv); |
3703 | } |
3704 | // |
3705 | const TopoDS_Shape *pFOffset = aDMFImF.Seek(aFInv); |
3706 | if (!pFOffset) { |
3707 | continue; |
3708 | } |
3709 | TopTools_ListIteratorOfListOfShape aItLFInv(aLFInvIm); |
3710 | for (; aItLFInv.More(); aItLFInv.Next()) { |
3711 | const TopoDS_Shape& aFInvIm = aItLFInv.Value(); |
3712 | const TopTools_ListOfShape* pLSols = aDMFS.Seek(aFInvIm); |
3713 | if (!pLSols || pLSols->Extent() != 1) { |
3714 | continue; |
3715 | } |
3716 | // |
3717 | const TopoDS_Shape& aFSol = pLSols->First(); |
3718 | // |
3719 | TopoDS_Shape aFx; |
420b38fd |
3720 | if (!FindShape(aFInvIm, aFSol, NULL, aFx)) { |
0da0275c |
3721 | continue; |
3722 | } |
3723 | // |
3724 | if (BRepOffset_Tool::CheckPlanesNormals(TopoDS::Face(aFx), TopoDS::Face(*pFOffset))) { |
3725 | // the normal direction has not changed, thus the face can be removed |
3726 | aMFToRem.Add(aFInvIm); |
3727 | } |
3728 | } |
3729 | } |
3730 | // |
ecf4f17c |
3731 | TopoDS_Compound aSolids; |
3732 | BRep_Builder().MakeCompound(aSolids); |
b443d536 |
3733 | TopTools_MapOfShape aMFKeep; |
ecf4f17c |
3734 | // |
3735 | TopExp_Explorer aExpS(aSols, TopAbs_SOLID); |
3736 | for (; aExpS.More(); aExpS.Next()) { |
3737 | const TopoDS_Shape& aSol = aExpS.Current(); |
3738 | // |
3739 | Standard_Boolean bAllInv(Standard_True), bAllRemoved(Standard_True); |
3740 | |
45d0af05 |
3741 | for (TopExp_Explorer aExpF(aSol, TopAbs_FACE); aExpF.More(); aExpF.Next()) |
3742 | { |
ecf4f17c |
3743 | const TopoDS_Shape& aFS = aExpF.Current(); |
3744 | // |
3745 | if (aFS.Orientation() == TopAbs_INTERNAL) { |
3746 | aMFToRem.Add(aFS); |
e08a9b03 |
3747 | continue; |
ecf4f17c |
3748 | } |
e08a9b03 |
3749 | |
3750 | if (aMFToRem.Contains(aFS)) |
3751 | continue; |
3752 | |
3753 | bAllRemoved = false; |
3754 | bAllInv &= aMFInv.Contains(aFS); |
ecf4f17c |
3755 | } |
3756 | // |
3757 | if (bAllInv && !bAllRemoved) { |
3758 | // remove invalid faces but keep those that have already been marked for removal |
3759 | TopExp_Explorer aExpF(aSol, TopAbs_FACE); |
3760 | for (; aExpF.More(); aExpF.Next()) { |
3761 | const TopoDS_Shape& aFS = aExpF.Current(); |
3762 | // |
3763 | if (aMFToRem.Contains(aFS)) { |
b443d536 |
3764 | if (!aMFKeep.Add(aFS)) { |
3765 | aMFKeep.Remove(aFS); |
3766 | } |
ecf4f17c |
3767 | } |
3768 | else { |
3769 | aMFToRem.Add(aFS); |
3770 | } |
3771 | } |
3772 | } |
3773 | else { |
3774 | BRep_Builder().Add(aSolids, aSol); |
3775 | theSolids = aSolids; |
3776 | } |
3777 | } |
3778 | // |
b443d536 |
3779 | TopTools_MapIteratorOfMapOfShape aItM(aMFKeep); |
3780 | for (; aItM.More(); aItM.Next()) { |
3781 | aMFToRem.Remove(aItM.Value()); |
3782 | } |
bc4a3867 |
3783 | |
3784 | // Remove the invalid hanging parts external to the solids |
e08a9b03 |
3785 | RemoveHangingParts(aMV, aDMFImF, aMFInv, theInvEdges, theInvertedEdges, aMFToRem); |
bc4a3867 |
3786 | |
3787 | // Remove newly found internal and hanging faces |
ecf4f17c |
3788 | RemoveValidSplits(aMFToRem, theFImages, aMV, theMERemoved); |
3789 | RemoveInvalidSplits(aMFToRem, theArtInvFaces, theInvEdges, theInvFaces, aMV, theMERemoved); |
baaacd46 |
3790 | // |
3791 | // Get inside faces from the removed ones comparing them with boundary edges |
3792 | aNb = theMERemoved.Extent(); |
3793 | for (i = 1; i <= aNb; ++i) { |
3794 | const TopoDS_Shape& aE = theMERemoved(i); |
3795 | if (!aMEBoundary.Contains(aE)) { |
3796 | theMEInside.Add(aE); |
3797 | } |
3798 | } |
6f04cbb1 |
3799 | |
3800 | // build all possible intersection pairs basing on the intersection results |
3801 | // taking into account removed faces. |
3802 | if (aMFToRem.Extent()) |
3803 | buildIntersectionPairs (theFImages, theInvFaces, aMV, aMFToRem, aDMFImF, theIntRes.InterPairs); |
ecf4f17c |
3804 | } |
3805 | |
3806 | //======================================================================= |
3807 | //function : ShapesConnections |
3808 | //purpose : Looking for the connections between faces not to miss |
3809 | // some necessary intersection |
3810 | //======================================================================= |
3811 | void ShapesConnections(const TopTools_IndexedDataMapOfShapeListOfShape& theInvFaces, |
3812 | const TopTools_IndexedMapOfShape& theInvEdges, |
3813 | const TopTools_DataMapOfShapeShape& theDMFOr, |
3814 | BOPAlgo_Builder& theBuilder, |
3815 | TopTools_DataMapOfShapeListOfShape& theSSInterfs) |
3816 | { |
3817 | // update invalid edges with images and keep connection to original edge |
3818 | TopTools_DataMapOfShapeListOfShape aDMEOr; |
45d0af05 |
3819 | Standard_Integer aNb = theInvEdges.Extent(); |
3820 | for (Standard_Integer i = 1; i <= aNb; ++i) { |
ecf4f17c |
3821 | const TopoDS_Shape& aEInv = theInvEdges(i); |
3822 | const TopTools_ListOfShape& aLEIm = theBuilder.Modified(aEInv); |
3823 | if (aLEIm.IsEmpty()) { |
3824 | aDMEOr.Bound(aEInv, TopTools_ListOfShape())->Append(aEInv); |
3825 | continue; |
3826 | } |
3827 | // |
3828 | TopTools_ListIteratorOfListOfShape aItLEIm(aLEIm); |
3829 | for (; aItLEIm.More(); aItLEIm.Next()) { |
3830 | const TopoDS_Shape& aEIm = aItLEIm.Value(); |
3831 | // |
3832 | TopTools_ListOfShape* pLEOr = aDMEOr.ChangeSeek(aEIm); |
3833 | if (!pLEOr) { |
3834 | pLEOr = aDMEOr.Bound(aEIm, TopTools_ListOfShape()); |
3835 | } |
3836 | AppendToList(*pLEOr, aEInv); |
3837 | } |
3838 | } |
3839 | // |
3840 | // get shapes connections for using in the rebuilding process |
3841 | const BOPDS_PDS& pDS = theBuilder.PDS(); |
3842 | // analyze all Face/Face intersections |
3843 | const BOPDS_VectorOfInterfFF& aFFs = pDS->InterfFF(); |
1155d05a |
3844 | Standard_Integer iInt, aNbFF = aFFs.Length(); |
ecf4f17c |
3845 | for (iInt = 0; iInt < aNbFF; ++iInt) { |
3846 | const BOPDS_InterfFF& aFF = aFFs(iInt); |
3847 | const BOPDS_VectorOfCurve& aVNC = aFF.Curves(); |
1155d05a |
3848 | Standard_Integer aNbC = aVNC.Length(); |
ecf4f17c |
3849 | if (!aNbC) { |
3850 | continue; |
3851 | } |
3852 | // |
3853 | const TopoDS_Shape& aFIm1 = pDS->Shape(aFF.Index1()); |
3854 | const TopoDS_Shape& aFIm2 = pDS->Shape(aFF.Index2()); |
3855 | // |
3856 | const TopoDS_Shape* pF1 = theDMFOr.Seek(aFIm1); |
3857 | const TopoDS_Shape* pF2 = theDMFOr.Seek(aFIm2); |
3858 | // |
3859 | if (!pF1 || !pF2) { |
3860 | continue; |
3861 | } |
3862 | // |
3863 | if (pF1->IsSame(*pF2)) { |
3864 | continue; |
3865 | } |
3866 | // |
3867 | Standard_Boolean bInv1 = theInvFaces.Contains(*pF1); |
3868 | Standard_Boolean bInv2 = theInvFaces.Contains(*pF2); |
3869 | // |
3870 | if (!bInv1 && !bInv2) { |
3871 | continue; |
3872 | } |
3873 | // |
3874 | // check if it is real Face/Face intersection |
3875 | TopTools_MapOfShape aMEInt; |
3876 | for (Standard_Integer iC = 0; iC < aNbC; ++iC) { |
3877 | const BOPDS_Curve& aNC = aVNC(iC); |
3878 | const BOPDS_ListOfPaveBlock& aLPB = aNC.PaveBlocks(); |
3879 | BOPDS_ListIteratorOfListOfPaveBlock aItLPB(aLPB); |
3880 | for (; aItLPB.More(); aItLPB.Next()) { |
3881 | const Handle(BOPDS_PaveBlock)& aPB = aItLPB.Value(); |
3882 | Standard_Integer nEInt; |
3883 | if (aPB->HasEdge(nEInt)) { |
3884 | const TopoDS_Shape& aEInt = pDS->Shape(nEInt); |
3885 | aMEInt.Add(aEInt); |
3886 | } |
3887 | } |
3888 | } |
3889 | // |
3890 | if (aMEInt.IsEmpty()) { |
3891 | continue; |
3892 | } |
3893 | // |
3894 | // check if invalid edges of the face are in the same splits with intersection edges |
3895 | for (Standard_Integer i = 0; i < 2; ++i) { |
3896 | if ((!i && !bInv1) || (i && !bInv2)) { |
3897 | continue; |
3898 | } |
3899 | // |
3900 | const TopoDS_Shape& aF = !i ? *pF1 : *pF2; |
3901 | const TopoDS_Shape& aFOp = !i ? *pF2 : *pF1; |
3902 | const TopoDS_Shape& aFIm = !i ? aFIm1 : aFIm2; |
3903 | // |
3904 | Standard_Boolean bFound = Standard_False; |
3905 | // |
3906 | TopTools_ListOfShape aLFIm = theBuilder.Modified(aFIm); |
3907 | if (aLFIm.IsEmpty()) { |
3908 | aLFIm.Append(aFIm); |
3909 | } |
3910 | // |
3911 | TopTools_ListIteratorOfListOfShape aItLFIm(aLFIm); |
3912 | for (; aItLFIm.More(); aItLFIm.Next()) { |
3913 | const TopoDS_Shape& aFImIm = aItLFIm.Value(); |
3914 | // |
3915 | Standard_Boolean bInv(Standard_False), bInt(Standard_False); |
3916 | TopExp_Explorer aExpE(aFImIm, TopAbs_EDGE); |
3917 | for (; aExpE.More(); aExpE.Next()) { |
3918 | const TopoDS_Shape& aE = aExpE.Current(); |
3919 | if (!bInv) { |
3920 | bInv = aDMEOr.IsBound(aE); |
3921 | } |
3922 | if (!bInt) { |
3923 | bInt = aMEInt.Contains(aE); |
3924 | } |
3925 | if (bInv && bInt) { |
3926 | break; |
3927 | } |
3928 | } |
3929 | // |
3930 | if (!bInt || !bInv) { |
3931 | continue; |
3932 | } |
3933 | // |
3934 | bFound = Standard_True; |
3935 | // |
3936 | // append opposite face to all invalid edges in the split |
3937 | aExpE.Init(aFImIm, TopAbs_EDGE); |
3938 | for (; aExpE.More(); aExpE.Next()) { |
3939 | const TopoDS_Shape& aE = aExpE.Current(); |
3940 | const TopTools_ListOfShape* pLEOr = aDMEOr.Seek(aE); |
3941 | if (!pLEOr) { |
3942 | continue; |
3943 | } |
3944 | // |
3945 | TopTools_ListIteratorOfListOfShape aItLE(*pLEOr); |
3946 | for (; aItLE.More(); aItLE.Next()) { |
3947 | const TopoDS_Shape& aEOr = aItLE.Value(); |
3948 | TopTools_ListOfShape *pLFE = theSSInterfs.ChangeSeek(aEOr); |
3949 | if (!pLFE) { |
3950 | pLFE = theSSInterfs.Bound(aEOr, TopTools_ListOfShape()); |
3951 | } |
3952 | AppendToList(*pLFE, aFOp); |
3953 | } |
3954 | } |
3955 | } |
3956 | if (bFound) { |
3957 | // save connection between offset faces |
3958 | TopTools_ListOfShape *pLF = theSSInterfs.ChangeSeek(aF); |
3959 | if (!pLF) { |
3960 | pLF = theSSInterfs.Bound(aF, TopTools_ListOfShape()); |
3961 | } |
3962 | AppendToList(*pLF, aFOp); |
3963 | } |
3964 | } |
3965 | } |
3966 | } |
3967 | |
bc4a3867 |
3968 | //======================================================================= |
3969 | //function : RemoveHangingParts |
3970 | //purpose : Remove isolated invalid hanging parts |
3971 | //======================================================================= |
3972 | void RemoveHangingParts(const BOPAlgo_MakerVolume& theMV, |
3973 | const TopTools_DataMapOfShapeShape& theDMFImF, |
3974 | const TopTools_IndexedMapOfShape& theMFInv, |
3975 | const TopTools_IndexedMapOfShape& theInvEdges, |
e08a9b03 |
3976 | const TopTools_MapOfShape& theInvertedEdges, |
bc4a3867 |
3977 | TopTools_MapOfShape& theMFToRem) |
3978 | { |
3979 | // Map the faces of the result solids to filter them from avoided faces |
3980 | TopTools_IndexedMapOfShape aMFS; |
3981 | TopExp::MapShapes(theMV.Shape(), TopAbs_FACE, aMFS); |
3982 | |
3983 | BRep_Builder aBB; |
3984 | // Build compound of all faces not included into solids |
3985 | TopoDS_Compound aCFHangs; |
3986 | aBB.MakeCompound(aCFHangs); |
3987 | |
3988 | // Tool for getting the splits of faces |
1155d05a |
3989 | const TopTools_DataMapOfShapeListOfShape& aMVIms = theMV.Images(); |
bc4a3867 |
3990 | |
3991 | TopTools_ListIteratorOfListOfShape aItLArgs(theMV.Arguments()); |
3992 | for (; aItLArgs.More(); aItLArgs.Next()) |
3993 | { |
3994 | TopExp_Explorer anExpF(aItLArgs.Value(), TopAbs_FACE); |
3995 | for (; anExpF.More(); anExpF.Next()) |
3996 | { |
3997 | const TopoDS_Shape& aF = anExpF.Current(); |
e08a9b03 |
3998 | TakeModified(aF, aMVIms, aCFHangs, &aMFS); |
bc4a3867 |
3999 | } |
4000 | } |
4001 | |
4002 | // Make connexity blocks of all hanging parts and check that they are isolated |
1155d05a |
4003 | TopTools_ListOfShape aLCBHangs; |
bc4a3867 |
4004 | BOPTools_AlgoTools::MakeConnexityBlocks(aCFHangs, TopAbs_EDGE, TopAbs_FACE, aLCBHangs); |
4005 | if (aLCBHangs.IsEmpty()) |
4006 | return; |
4007 | |
4008 | // To be removed, the block should contain invalid splits of offset faces and should |
4009 | // meet one of the following conditions: |
4010 | // 1. The block should not be connected to any invalid parts (Faces or Edges) |
4011 | // contained in solids; |
4012 | // 2. The block should be isolated from other faces, i.e. it should consist of |
4013 | // the splits of the single offset face. |
4014 | |
4015 | // Map the edges and vertices of the result solids to check connectivity |
4016 | // of the hanging blocks to invalid parts contained in solids |
4017 | TopTools_IndexedDataMapOfShapeListOfShape aDMEF, aDMVE; |
4018 | TopExp::MapShapesAndAncestors(theMV.Shape(), TopAbs_EDGE , TopAbs_FACE, aDMEF); |
4019 | TopExp::MapShapesAndAncestors(theMV.Shape(), TopAbs_VERTEX, TopAbs_EDGE, aDMVE); |
4020 | |
4021 | // Update invalid edges with intersection results |
4022 | TopTools_MapOfShape aMEInv; |
4023 | Standard_Integer i, aNbE = theInvEdges.Extent(); |
e08a9b03 |
4024 | for (i = 1; i <= aNbE; ++i) |
4025 | TakeModified(theInvEdges(i), aMVIms, aMEInv); |
4026 | |
4027 | // Update inverted edges with intersection results |
4028 | TopTools_MapOfShape aMEInverted; |
4029 | for (TopTools_MapIteratorOfMapOfShape itM(theInvertedEdges); itM.More(); itM.Next()) |
4030 | TakeModified(itM.Value(), aMVIms, aMEInverted); |
bc4a3867 |
4031 | |
4032 | // Tool for getting the origins of the splits |
1155d05a |
4033 | const TopTools_DataMapOfShapeListOfShape& aMVOrs = theMV.Origins(); |
bc4a3867 |
4034 | |
e08a9b03 |
4035 | // Find hanging blocks to remove |
4036 | TopTools_ListOfShape aBlocksToRemove; |
4037 | |
1155d05a |
4038 | TopTools_ListIteratorOfListOfShape aItLCBH(aLCBHangs); |
bc4a3867 |
4039 | for (; aItLCBH.More(); aItLCBH.Next()) |
4040 | { |
4041 | const TopoDS_Shape& aCBH = aItLCBH.Value(); |
4042 | |
e08a9b03 |
4043 | // Remove the block containing the inverted edges |
4044 | Standard_Boolean bHasInverted = Standard_False; |
4045 | TopExp_Explorer anExpE(aCBH, TopAbs_EDGE); |
4046 | for (; anExpE.More() && !bHasInverted; anExpE.Next()) |
4047 | { |
4048 | const TopoDS_Shape& aE = anExpE.Current(); |
4049 | bHasInverted = !aDMEF .Contains(aE) && |
4050 | aMEInverted.Contains(aE); |
4051 | } |
4052 | |
4053 | if (bHasInverted) |
4054 | { |
4055 | aBlocksToRemove.Append(aCBH); |
4056 | continue; |
4057 | } |
4058 | |
bc4a3867 |
4059 | // Check the block to contain invalid split |
4060 | Standard_Boolean bHasInvalidFace = Standard_False; |
4061 | // Check connectivity to invalid parts |
4062 | Standard_Boolean bIsConnected = Standard_False; |
4063 | TopTools_IndexedMapOfShape aBlockME; |
4064 | TopExp::MapShapes(aCBH, TopAbs_EDGE, aBlockME); |
4065 | // Map to collect all original faces |
4066 | TopTools_MapOfShape aMOffsetF; |
4067 | |
4068 | TopExp_Explorer anExpF(aCBH, TopAbs_FACE); |
4069 | for (; anExpF.More(); anExpF.Next()) |
4070 | { |
4071 | const TopoDS_Shape& aF = anExpF.Current(); |
4072 | // Check block to contain invalid face |
4073 | if (!bHasInvalidFace) |
4074 | bHasInvalidFace = theMFInv.Contains(aF); |
4075 | |
4076 | // Check block for connectivity to invalid parts |
4077 | if (!bIsConnected) |
4078 | { |
4079 | // check edges |
e08a9b03 |
4080 | anExpE.Init(aF, TopAbs_EDGE); |
bc4a3867 |
4081 | for (; anExpE.More() && !bIsConnected; anExpE.Next()) |
4082 | { |
4083 | const TopoDS_Shape& aE = anExpE.Current(); |
4084 | const TopTools_ListOfShape *pLF = aDMEF.Seek(aE); |
4085 | if (pLF) |
4086 | { |
4087 | TopTools_ListIteratorOfListOfShape aItLF(*pLF); |
4088 | for (; aItLF.More() && !bIsConnected; aItLF.Next()) |
4089 | bIsConnected = theMFInv.Contains(aItLF.Value()); |
4090 | } |
4091 | } |
4092 | // check vertices |
e08a9b03 |
4093 | if (!bIsConnected) |
bc4a3867 |
4094 | { |
e08a9b03 |
4095 | TopExp_Explorer anExpV(aF, TopAbs_VERTEX); |
4096 | for (; anExpV.More() && !bIsConnected; anExpV.Next()) |
bc4a3867 |
4097 | { |
e08a9b03 |
4098 | const TopoDS_Shape& aV = anExpV.Current(); |
4099 | const TopTools_ListOfShape *pLE = aDMVE.Seek(aV); |
4100 | if (pLE) |
4101 | { |
4102 | TopTools_ListIteratorOfListOfShape aItLE(*pLE); |
4103 | for (; aItLE.More() && !bIsConnected; aItLE.Next()) |
4104 | bIsConnected = !aBlockME.Contains(aItLE.Value()) && |
4105 | aMEInv .Contains(aItLE.Value()); |
4106 | } |
bc4a3867 |
4107 | } |
4108 | } |
4109 | } |
4110 | |
4111 | // Check block to be isolated |
1155d05a |
4112 | const TopTools_ListOfShape* pLFOr = aMVOrs.Seek(aF); |
bc4a3867 |
4113 | if (pLFOr) |
4114 | { |
4115 | TopTools_ListIteratorOfListOfShape aItLFOr(*pLFOr); |
4116 | for (; aItLFOr.More(); aItLFOr.Next()) |
4117 | { |
4118 | const TopoDS_Shape* pFOffset = theDMFImF.Seek(aItLFOr.Value()); |
4119 | if (pFOffset) |
4120 | aMOffsetF.Add(*pFOffset); |
4121 | } |
4122 | } |
4123 | else |
4124 | { |
4125 | const TopoDS_Shape* pFOffset = theDMFImF.Seek(aF); |
4126 | if (pFOffset) |
4127 | aMOffsetF.Add(*pFOffset); |
4128 | } |
4129 | } |
4130 | |
4131 | Standard_Boolean bRemove = bHasInvalidFace && |
4132 | (!bIsConnected || aMOffsetF.Extent() == 1); |
4133 | |
4134 | if (bRemove) |
e08a9b03 |
4135 | aBlocksToRemove.Append(aCBH); |
4136 | } |
4137 | |
4138 | // remove the invalidated blocks |
4139 | aItLCBH.Initialize(aBlocksToRemove); |
4140 | for (; aItLCBH.More(); aItLCBH.Next()) |
4141 | { |
4142 | const TopoDS_Shape& aCBH = aItLCBH.Value(); |
4143 | TopExp_Explorer anExpF(aCBH, TopAbs_FACE); |
4144 | for (; anExpF.More(); anExpF.Next()) |
4145 | theMFToRem.Add(anExpF.Current()); |
bc4a3867 |
4146 | } |
4147 | } |
4148 | |
ecf4f17c |
4149 | //======================================================================= |
4150 | //function : RemoveValidSplits |
4151 | //purpose : Removing valid splits according to results of intersection |
4152 | //======================================================================= |
4153 | void RemoveValidSplits(const TopTools_MapOfShape& theSpRem, |
4154 | TopTools_IndexedDataMapOfShapeListOfShape& theImages, |
4155 | BOPAlgo_Builder& theGF, |
4156 | TopTools_IndexedMapOfShape& theMERemoved) |
4157 | { |
4158 | Standard_Integer i, aNb = theImages.Extent(); |
4159 | if (!aNb) { |
4160 | return; |
4161 | } |
4162 | // |
4163 | for (i = 1; i <= aNb; ++i) { |
4164 | TopTools_ListOfShape& aLSIm = theImages(i); |
4165 | TopTools_ListIteratorOfListOfShape aIt(aLSIm); |
4166 | for (; aIt.More(); ) { |
4167 | const TopoDS_Shape& aSIm = aIt.Value(); |
4168 | if (theSpRem.Contains(aSIm)) { |
4169 | TopExp::MapShapes(aSIm, TopAbs_EDGE, theMERemoved); |
4170 | aLSIm.Remove(aIt); |
4171 | continue; |
4172 | } |
4173 | // |
4174 | // check if all its images are have to be removed |
4175 | const TopTools_ListOfShape& aLSImIm = theGF.Modified(aSIm); |
4176 | if (aLSImIm.Extent()) { |
4177 | Standard_Boolean bAllRem = Standard_True; |
4178 | TopTools_ListIteratorOfListOfShape aIt1(aLSImIm); |
4179 | for (; aIt1.More(); aIt1.Next()) { |
4180 | const TopoDS_Shape& aSImIm = aIt1.Value(); |
4181 | if (theSpRem.Contains(aSImIm)) { |
4182 | TopExp::MapShapes(aSImIm, TopAbs_EDGE, theMERemoved); |
4183 | } |
4184 | else { |
4185 | bAllRem = Standard_False; |
4186 | } |
4187 | } |
4188 | // |
4189 | if (bAllRem) { |
4190 | TopExp::MapShapes(aSIm, TopAbs_EDGE, theMERemoved); |
4191 | aLSIm.Remove(aIt); |
4192 | continue; |
4193 | } |
4194 | } |
4195 | aIt.Next(); |
4196 | } |
4197 | } |
4198 | } |
4199 | |
4200 | //======================================================================= |
4201 | //function : RemoveInvalidSplits |
4202 | //purpose : Removing invalid splits according to the results of intersection |
4203 | //======================================================================= |
4204 | void RemoveInvalidSplits(const TopTools_MapOfShape& theSpRem, |
4205 | const TopTools_DataMapOfShapeShape& theArtInvFaces, |
4206 | const TopTools_IndexedMapOfShape& theInvEdges, |
4207 | TopTools_IndexedDataMapOfShapeListOfShape& theImages, |
4208 | BOPAlgo_Builder& theGF, |
4209 | TopTools_IndexedMapOfShape& theMERemoved) |
4210 | { |
4211 | Standard_Integer i, aNb = theImages.Extent(); |
4212 | if (!aNb) { |
4213 | return; |
4214 | } |
4215 | // |
4216 | for (i = 1; i <= aNb; ++i) { |
4217 | const TopoDS_Shape& aS = theImages.FindKey(i); |
4218 | Standard_Boolean bArt = theArtInvFaces.IsBound(aS); |
4219 | // |
4220 | TopTools_ListOfShape& aLSIm = theImages(i); |
4221 | TopTools_ListIteratorOfListOfShape aIt(aLSIm); |
4222 | for (; aIt.More();) { |
4223 | const TopoDS_Shape& aSIm = aIt.Value(); |
4224 | if (theSpRem.Contains(aSIm)) { |
4225 | TopExp::MapShapes(aSIm, TopAbs_EDGE, theMERemoved); |
4226 | aLSIm.Remove(aIt); |
4227 | continue; |
4228 | } |
4229 | // |
4230 | // check if all its images are have to be removed |
4231 | const TopTools_ListOfShape& aLSImIm = theGF.Modified(aSIm); |
4232 | if (aLSImIm.IsEmpty()) { |
4233 | aIt.Next(); |
4234 | continue; |
4235 | } |
4236 | // |
4237 | Standard_Boolean bAllRem = Standard_True; |
4238 | TopTools_IndexedMapOfShape aMERemoved; |
4239 | TopTools_ListIteratorOfListOfShape aIt1(aLSImIm); |
4240 | for (; aIt1.More(); aIt1.Next()) { |
4241 | const TopoDS_Shape& aSImIm = aIt1.Value(); |
4242 | if (theSpRem.Contains(aSImIm)) { |
4243 | TopExp::MapShapes(aSImIm, TopAbs_EDGE, aMERemoved); |
4244 | } |
4245 | else { |
4246 | bAllRem = Standard_False; |
4247 | } |
4248 | } |
4249 | // |
4250 | if (bAllRem) { |
4251 | aLSIm.Remove(aIt); |
4252 | continue; |
4253 | } |
4254 | // |
4255 | if (bArt) { |
4256 | aIt.Next(); |
4257 | continue; |
4258 | } |
4259 | // |
4260 | // remove the face from invalid if all invalid edges of this face |
4261 | // have been marked for removal |
4262 | TopExp_Explorer aExpE(aSIm, TopAbs_EDGE); |
4263 | for (; aExpE.More(); aExpE.Next()) { |
4264 | const TopoDS_Shape& aEInv = aExpE.Current(); |
4265 | if (theInvEdges.Contains(aEInv) && !aMERemoved.Contains(aEInv)) { |
4266 | break; |
4267 | } |
4268 | } |
4269 | if (!aExpE.More()) { |
4270 | TopExp::MapShapes(aSIm, TopAbs_EDGE, theMERemoved); |
4271 | aLSIm.Remove(aIt); |
4272 | } |
4273 | else { |
4274 | aIt.Next(); |
4275 | } |
4276 | } |
4277 | } |
4278 | } |
4279 | |
4280 | //======================================================================= |
4281 | //function : FilterEdgesImages |
4282 | //purpose : Updating the maps of images and origins of the offset edges |
4283 | //======================================================================= |
4284 | void FilterEdgesImages(const TopoDS_Shape& theS, |
4285 | TopTools_DataMapOfShapeListOfShape& theOEImages, |
4286 | TopTools_DataMapOfShapeListOfShape& theOEOrigins) |
4287 | { |
4288 | // map edges |
4289 | TopTools_IndexedMapOfShape aME; |
4290 | TopExp::MapShapes(theS, TopAbs_EDGE, aME); |
4291 | // |
4292 | theOEOrigins.Clear(); |
4293 | TopTools_DataMapIteratorOfDataMapOfShapeListOfShape aItDM(theOEImages); |
4294 | for (; aItDM.More(); aItDM.Next()) { |
4295 | const TopoDS_Shape& aE = aItDM.Key(); |
4296 | TopTools_ListOfShape& aLEIm = aItDM.ChangeValue(); |
4297 | // |
4298 | TopTools_ListIteratorOfListOfShape aIt(aLEIm); |
4299 | for (; aIt.More(); ) { |
4300 | const TopoDS_Shape& aEIm = aIt.Value(); |
4301 | // filter images |
4302 | if (!aME.Contains(aEIm)) { |
4303 | // remove the image |
4304 | // edges with no images left should be kept in the map |
4305 | // to avoid their usage when building the splits of faces |
4306 | aLEIm.Remove(aIt); |
4307 | continue; |
4308 | } |
4309 | // |
4310 | // save origins |
4311 | if (theOEOrigins.IsBound(aEIm)) { |
4312 | AppendToList(theOEOrigins.ChangeFind(aEIm), aE); |
4313 | } |
4314 | else { |
4315 | TopTools_ListOfShape aLOr; |
4316 | aLOr.Append(aE); |
4317 | theOEOrigins.Bind(aEIm, aLOr); |
4318 | } |
4319 | // |
4320 | aIt.Next(); |
4321 | } |
4322 | } |
4323 | } |
4324 | |
4325 | //======================================================================= |
4326 | //function : FilterInvalidFaces |
4327 | //purpose : Filtering of the invalid faces |
4328 | //======================================================================= |
9e9b826a |
4329 | void FilterInvalidFaces(TopTools_IndexedDataMapOfShapeListOfShape& theFImages, |
baaacd46 |
4330 | const TopTools_IndexedDataMapOfShapeListOfShape& theDMEF, |
9e9b826a |
4331 | const TopTools_IndexedMapOfShape& theInvEdges, |
baaacd46 |
4332 | const TopTools_IndexedMapOfShape& theMERemoved, |
ecf4f17c |
4333 | TopTools_IndexedDataMapOfShapeListOfShape& theInvFaces, |
4334 | TopTools_DataMapOfShapeShape& theArtInvFaces) |
4335 | { |
4336 | // |
4337 | // filter invalid faces, considering faces having only valid |
4338 | // images left with non-free edges as valid |
4339 | // do not remove invalid faces if it creates free edges |
4340 | // |
4341 | TopTools_IndexedDataMapOfShapeListOfShape aReallyInvFaces; |
9e9b826a |
4342 | // Edge-Face connexity map of all splits, both invalid and valid |
4343 | TopTools_IndexedDataMapOfShapeListOfShape aDMEFAll; |
ecf4f17c |
4344 | TopTools_ListIteratorOfListOfShape aItLF; |
4345 | // |
9e9b826a |
4346 | const Standard_Integer aNb = theInvFaces.Extent(); |
4347 | for (Standard_Integer i = 1; i <= aNb; ++i) { |
ecf4f17c |
4348 | const TopoDS_Shape& aF = theInvFaces.FindKey(i); |
4349 | const TopTools_ListOfShape& aLFInv = theInvFaces(i); |
4350 | // |
4351 | if (theArtInvFaces.IsBound(aF)) { |
4352 | if (aLFInv.IsEmpty()) { |
4353 | theArtInvFaces.UnBind(aF); |
4354 | } |
4355 | else { |
4356 | aReallyInvFaces.Add(aF, aLFInv); |
4357 | } |
4358 | continue; |
4359 | } |
4360 | // |
4361 | if (aLFInv.IsEmpty()) { |
4362 | continue; |
4363 | } |
4364 | // |
9e9b826a |
4365 | TopTools_ListOfShape& aLFIm = theFImages.ChangeFromKey(aF); |
ecf4f17c |
4366 | Standard_Boolean bInvalid = aLFIm.IsEmpty(); |
4367 | // |
4368 | if (!bInvalid) { |
4369 | // check two lists on common splits |
4370 | aItLF.Initialize(aLFInv); |
4371 | for (; aItLF.More(); aItLF.Next()) { |
4372 | const TopoDS_Shape& aFInv = aItLF.Value(); |
4373 | // |
4374 | TopTools_ListIteratorOfListOfShape aItLFIm(aLFIm); |
4375 | for (; aItLFIm.More(); aItLFIm.Next()) { |
4376 | const TopoDS_Shape& aFIm = aItLFIm.Value(); |
4377 | // |
4378 | if (aFInv.IsSame(aFIm)) { |
4379 | break; |
4380 | } |
4381 | } |
4382 | // |
4383 | if (aItLFIm.More()) { |
4384 | break; |
4385 | } |
4386 | } |
4387 | // |
4388 | bInvalid = aItLF.More(); |
4389 | } |
4390 | // |
4391 | if (!bInvalid) { |
4392 | // check for free edges |
4393 | for (Standard_Integer j = 0; !bInvalid && j < 2; ++j) { |
4394 | const TopTools_ListOfShape& aLI = !j ? aLFIm : aLFInv; |
4395 | aItLF.Initialize(aLI); |
4396 | for (; aItLF.More(); aItLF.Next()) { |
4397 | const TopoDS_Shape& aFIm = aItLF.Value(); |
4398 | // |
4399 | TopExp_Explorer aExp(aFIm, TopAbs_EDGE); |
4400 | for (; aExp.More(); aExp.Next()) { |
4401 | const TopoDS_Shape& aE = aExp.Current(); |
baaacd46 |
4402 | if (!theMERemoved.Contains(aE)) { |
4403 | const TopTools_ListOfShape* pLEF = theDMEF.Seek(aE); |
4404 | if (pLEF && pLEF->Extent() == 1) { |
ecf4f17c |
4405 | break; |
4406 | } |
4407 | } |
4408 | } |
4409 | // |
4410 | if (aExp.More()) { |
4411 | break; |
4412 | } |
4413 | } |
4414 | bInvalid = aItLF.More(); |
4415 | } |
4416 | } |
9e9b826a |
4417 | if (bInvalid) |
4418 | { |
4419 | if (aDMEFAll.IsEmpty()) |
4420 | { |
4421 | aDMEFAll = theDMEF; |
4422 | for (Standard_Integer iF = 1; iF <= aNb; ++iF) |
4423 | for (TopTools_ListOfShape::Iterator itLFInv (theInvFaces(iF)); itLFInv.More(); itLFInv.Next()) |
4424 | TopExp::MapShapesAndAncestors (itLFInv.Value(), TopAbs_EDGE, TopAbs_FACE, aDMEFAll); |
4425 | } |
4426 | |
4427 | TopTools_MapOfShape aLocalSplits; |
4428 | for (Standard_Integer j = 0; j < 2; ++j) |
4429 | for (aItLF.Initialize((!j ? aLFIm : aLFInv)); aItLF.More(); aItLF.Next()) |
4430 | aLocalSplits.Add (aItLF.Value()); |
4431 | |
4432 | // Check if all invalid edges are located inside the split and do not touch |
4433 | // any other faces both invalid and valid |
4434 | aItLF.Initialize(aLFInv); |
4435 | for (; aItLF.More(); aItLF.Next()) |
4436 | { |
4437 | const TopoDS_Shape& aFIm = aItLF.Value(); |
4438 | TopExp_Explorer aExp(aFIm, TopAbs_EDGE); |
4439 | for (; aExp.More(); aExp.Next()) |
4440 | { |
4441 | const TopoDS_Shape& aE = aExp.Current(); |
4442 | if (theInvEdges.Contains (aE) && !theMERemoved.Contains (aE)) |
4443 | { |
4444 | const TopTools_ListOfShape& aLF = aDMEFAll.FindFromKey (aE); |
4445 | TopTools_ListOfShape::Iterator itLF (aLF); |
4446 | for (; itLF.More(); itLF.Next()) |
4447 | { |
4448 | if (!aLocalSplits.Contains (itLF.Value())) |
4449 | break; |
4450 | } |
4451 | if (itLF.More()) |
4452 | break; |
4453 | } |
4454 | } |
4455 | if (aExp.More()) |
4456 | break; |
4457 | } |
4458 | bInvalid = aItLF.More(); |
4459 | if (!bInvalid) |
4460 | { |
4461 | aItLF.Initialize(aLFInv); |
4462 | for (; aItLF.More(); aItLF.Next()) |
4463 | AppendToList (aLFIm, aItLF.Value()); |
4464 | } |
4465 | } |
ecf4f17c |
4466 | // |
4467 | if (bInvalid) { |
4468 | aReallyInvFaces.Add(aF, aLFInv); |
4469 | } |
4470 | } |
4471 | // |
4472 | theInvFaces = aReallyInvFaces; |
4473 | } |
4474 | |
4b59685a |
4475 | //======================================================================= |
4476 | //function : CheckEdgesCreatedByVertex |
4477 | //purpose : Checks additionally the unchecked edges originated from vertices |
4478 | //======================================================================= |
4479 | void CheckEdgesCreatedByVertex (const TopTools_IndexedDataMapOfShapeListOfShape& theInvFaces, |
4480 | const TopTools_DataMapOfShapeShape& theArtInvFaces, |
4481 | const TopTools_DataMapOfShapeListOfShape& theEdgesOrigins, |
4482 | const TopTools_IndexedMapOfShape& theValidEdges, |
4483 | TopTools_IndexedMapOfShape& theInvEdges) |
4484 | { |
4485 | // Mark the unchecked edges contained in invalid faces as invalid |
4486 | const Standard_Integer aNbF = theInvFaces.Extent(); |
4487 | for (Standard_Integer i = 1; i <= aNbF; ++i) |
4488 | { |
4489 | const TopoDS_Shape& aF = theInvFaces.FindKey (i); |
4490 | if (theArtInvFaces.IsBound (aF)) |
4491 | continue; |
4492 | |
4493 | const TopTools_ListOfShape& aLFIm = theInvFaces (i); |
4494 | for (TopTools_ListOfShape::Iterator it (aLFIm); it.More(); it.Next()) |
4495 | { |
4496 | const TopoDS_Shape& aFIm = it.Value(); |
4497 | for (TopExp_Explorer expE (aFIm, TopAbs_EDGE); expE.More(); expE.Next()) |
4498 | { |
4499 | const TopoDS_Shape& aE = expE.Current(); |
4500 | if (theInvEdges.Contains (aE) |
4501 | || theValidEdges.Contains (aE)) |
4502 | { |
4503 | continue; |
4504 | } |
4505 | |
4506 | // check if this edges is created by vertex |
4507 | const TopTools_ListOfShape* pLEOr = theEdgesOrigins.Seek (aE); |
4508 | if (!pLEOr) |
4509 | continue; |
4510 | TopTools_ListOfShape::Iterator itLEO (*pLEOr); |
4511 | for (; itLEO.More(); itLEO.Next()) |
4512 | { |
4513 | if (itLEO.Value().ShapeType() != TopAbs_VERTEX) |
4514 | break; |
4515 | } |
4516 | if (!itLEO.More()) |
4517 | { |
4518 | theInvEdges.Add (aE); |
4519 | } |
4520 | } |
4521 | } |
4522 | } |
4523 | } |
4524 | |
ecf4f17c |
4525 | //======================================================================= |
4526 | //function : FilterInvalidEdges |
4527 | //purpose : Filtering the invalid edges according to currently invalid faces |
4528 | //======================================================================= |
4529 | void FilterInvalidEdges(const TopTools_IndexedDataMapOfShapeListOfShape& theInvFaces, |
4530 | const TopTools_DataMapOfShapeShape& theArtInvFaces, |
9e9b826a |
4531 | const BRepOffset_DataMapOfShapeIndexedMapOfShape& theDMFMIE, |
ecf4f17c |
4532 | const TopTools_IndexedMapOfShape& theMERemoved, |
4533 | TopTools_IndexedMapOfShape& theInvEdges) |
4534 | { |
4535 | TopoDS_Compound aCEInv; |
4536 | TopTools_IndexedMapOfShape aMEInv; |
4537 | BRep_Builder aBB; |
4538 | aBB.MakeCompound(aCEInv); |
4539 | TopTools_ListIteratorOfListOfShape aItLF; |
4540 | // |
4541 | Standard_Integer i, aNb = theInvFaces.Extent(); |
4542 | for (i = 1; i <= aNb; ++i) { |
4543 | const TopTools_ListOfShape& aLFInv = theInvFaces(i); |
4544 | aItLF.Initialize(aLFInv); |
4545 | for (; aItLF.More(); aItLF.Next()) { |
4546 | const TopoDS_Shape& aFIm = aItLF.Value(); |
4547 | TopExp::MapShapes(aFIm, TopAbs_EDGE, aMEInv); |
4548 | // |
4549 | TopExp_Explorer aExpE(aFIm, TopAbs_EDGE); |
4550 | for (; aExpE.More(); aExpE.Next()) { |
4551 | const TopoDS_Shape& aE = aExpE.Current(); |
4552 | if (theInvEdges.Contains(aE)) { |
4553 | aBB.Add(aCEInv, aE); |
4554 | } |
4555 | } |
4556 | } |
4557 | } |
4558 | // |
4559 | // remove edges which have been marked for removal |
4560 | TopTools_IndexedMapOfShape aMEInvToAvoid; |
4561 | TopTools_ListOfShape aLCBE; |
4562 | BOPTools_AlgoTools::MakeConnexityBlocks(aCEInv, TopAbs_VERTEX, TopAbs_EDGE, aLCBE); |
4563 | // |
4564 | TopTools_ListIteratorOfListOfShape aItLCBE(aLCBE); |
4565 | for (; aItLCBE.More(); aItLCBE.Next()) { |
4566 | const TopoDS_Shape& aCBE = aItLCBE.Value(); |
4567 | TopExp_Explorer aExpCB(aCBE, TopAbs_EDGE); |
4568 | for (; aExpCB.More(); aExpCB.Next()) { |
4569 | const TopoDS_Shape& aE = aExpCB.Current(); |
4570 | if (!theMERemoved.Contains(aE)) { |
4571 | break; |
4572 | } |
4573 | } |
4574 | // |
4575 | if (!aExpCB.More()) { |
4576 | TopExp::MapShapes(aCBE, TopAbs_EDGE, aMEInvToAvoid); |
4577 | } |
4578 | } |
4579 | // |
4580 | TopTools_IndexedMapOfShape aReallyInvEdges; |
4581 | // |
4582 | aNb = theInvFaces.Extent(); |
4583 | for (i = 1; i <= aNb; ++i) { |
4584 | const TopoDS_Shape& aF = theInvFaces.FindKey(i); |
4585 | if (theArtInvFaces.IsBound(aF)) { |
9e9b826a |
4586 | const TopTools_IndexedMapOfShape& aMIE = theDMFMIE.Find(aF); |
4587 | const Standard_Integer aNbIE = aMIE.Extent(); |
4588 | for (Standard_Integer iE = 1; iE <= aNbIE; ++iE) |
4589 | { |
4590 | const TopoDS_Shape& aE = aMIE (iE); |
ecf4f17c |
4591 | if (aMEInv.Contains(aE) && !aMEInvToAvoid.Contains(aE)) { |
4592 | aReallyInvEdges.Add(aE); |
4593 | } |
4594 | } |
4595 | } |
4596 | else { |
4597 | const TopTools_ListOfShape& aLFInv = theInvFaces(i); |
4598 | aItLF.Initialize(aLFInv); |
4599 | for (; aItLF.More(); aItLF.Next()) { |
4600 | const TopoDS_Shape& aFIm = aItLF.Value(); |
4601 | TopExp_Explorer aExpE(aFIm, TopAbs_EDGE); |
4602 | for (; aExpE.More(); aExpE.Next()) { |
4603 | const TopoDS_Shape& aE = aExpE.Current(); |
4604 | if (theInvEdges.Contains(aE) && !aMEInvToAvoid.Contains(aE)) { |
4605 | aReallyInvEdges.Add(aE); |
4606 | } |
4607 | } |
4608 | } |
4609 | } |
4610 | } |
4611 | // |
4612 | theInvEdges = aReallyInvEdges; |
4613 | } |
4614 | |
4615 | //======================================================================= |
4616 | //function : FindFacesToRebuild |
4617 | //purpose : Looking for the faces that have to be rebuilt: |
4618 | // 1. Faces close to invalidity |
4619 | // 2. Faces containing some invalid parts |
4620 | //======================================================================= |
4621 | void FindFacesToRebuild(const TopTools_IndexedDataMapOfShapeListOfShape& theLFImages, |
4622 | const TopTools_IndexedMapOfShape& theInvEdges, |
4623 | const TopTools_IndexedDataMapOfShapeListOfShape& theInvFaces, |
4624 | const TopTools_DataMapOfShapeListOfShape& theSSInterfs, |
4625 | TopTools_IndexedDataMapOfShapeListOfShape& theFToRebuild, |
4626 | TopTools_MapOfShape& theFSelfRebAvoid) |
4627 | { |
4628 | Standard_Integer i, aNb = theLFImages.Extent(); |
4629 | if (!aNb) { |
4630 | return; |
4631 | } |
4632 | // |
4633 | Standard_Boolean bRebuild; |
4634 | TopTools_ListIteratorOfListOfShape aItLF; |
4635 | TopTools_ListOfShape aLEValid; |
4636 | TopTools_MapOfShape aMFence, aMEReb, aMFReb; |
4637 | TopExp_Explorer aExp; |
4638 | // |
4639 | TopTools_DataMapOfShapeListOfShape aDMFLV; |
4640 | // get edges from invalid faces |
4641 | aNb = theInvFaces.Extent(); |
4642 | for (i = 1; i <= aNb; i++) { |
4643 | const TopoDS_Shape& aF = theInvFaces.FindKey(i); |
4644 | aMFence.Clear(); |
4645 | TopTools_ListOfShape aLVAvoid; |
4646 | const TopTools_ListOfShape& aLFIm = theInvFaces(i); |
4647 | aItLF.Initialize(aLFIm); |
4648 | for (; aItLF.More(); aItLF.Next()) { |
4649 | const TopoDS_Shape& aFIm = aItLF.Value(); |
4650 | aExp.Init(aFIm, TopAbs_EDGE); |
4651 | for (; aExp.More(); aExp.Next()) { |
4652 | const TopoDS_Shape& aE = aExp.Current(); |
4653 | aMEReb.Add(aE); |
4654 | if (theInvEdges.Contains(aE)) { |
4655 | TopExp_Explorer aExpV(aE, TopAbs_VERTEX); |
4656 | for (; aExpV.More(); aExpV.Next()) { |
4657 | const TopoDS_Shape& aV = aExpV.Current(); |
4658 | if (aMFence.Add(aV)) { |
4659 | aLVAvoid.Append(aV); |
4660 | aMEReb.Add(aV); |
4661 | } |
4662 | } |
4663 | } |
4664 | } |
4665 | } |
4666 | // |
4667 | if (aLVAvoid.Extent()) { |
4668 | aDMFLV.Bind(aF, aLVAvoid); |
4669 | } |
4670 | // |
4671 | const TopTools_ListOfShape* pLF = theSSInterfs.Seek(aF); |
4672 | if (pLF) { |
4673 | TopTools_ListIteratorOfListOfShape aItLFE(*pLF); |
4674 | for (; aItLFE.More(); aItLFE.Next()) { |
4675 | const TopoDS_Shape& aFE = aItLFE.Value(); |
4676 | aMFReb.Add(aFE); |
4677 | } |
4678 | } |
4679 | } |
4680 | // |
4681 | // get face to rebuild |
4682 | aNb = theLFImages.Extent(); |
4683 | for (i = 1; i <= aNb; i++) { |
4684 | const TopoDS_Shape& aF = theLFImages.FindKey(i); |
4685 | const TopTools_ListOfShape& aLFIm = theLFImages(i); |
4686 | TopTools_MapOfShape aMVAvoid; |
4687 | if (aDMFLV.IsBound(aF)) { |
4688 | const TopTools_ListOfShape& aLVAvoid = aDMFLV.Find(aF); |
4689 | TopTools_ListIteratorOfListOfShape aItLV(aLVAvoid); |
4690 | for (; aItLV.More(); aItLV.Next()) { |
4691 | const TopoDS_Shape& aV = aItLV.Value(); |
4692 | aMVAvoid.Add(aV); |
4693 | } |
4694 | } |
4695 | // |
4696 | bRebuild = aMFReb.Contains(aF); |
4697 | aLEValid.Clear(); |
4698 | aMFence.Clear(); |
4699 | // |
4700 | aItLF.Initialize(aLFIm); |
4701 | for (; aItLF.More(); aItLF.Next()) { |
4702 | const TopoDS_Shape& aFIm = aItLF.Value(); |
4703 | aExp.Init(aFIm, TopAbs_EDGE); |
4704 | for (; aExp.More(); aExp.Next()) { |
4705 | const TopoDS_Edge& anEIm = TopoDS::Edge(aExp.Current()); |
4706 | if (!theInvEdges.Contains(anEIm)) { |
4707 | if (aMFence.Add(anEIm)) { |
4708 | aLEValid.Append(anEIm); |
4709 | } |
4710 | } |
4711 | // |
4712 | if (!bRebuild) { |
4713 | bRebuild = aMEReb.Contains(anEIm); |
4714 | } |
4715 | // |
4716 | if (!bRebuild) { |
4717 | // check vertices |
4718 | TopExp_Explorer aExpV(anEIm, TopAbs_VERTEX); |
4719 | for (; aExpV.More() && !bRebuild; aExpV.Next()) { |
4720 | const TopoDS_Shape& aV = aExpV.Current(); |
4721 | if (!aMVAvoid.Contains(aV)) { |
4722 | bRebuild = aMEReb.Contains(aV); |
4723 | } |
4724 | } |
4725 | } |
4726 | } |
4727 | } |
4728 | // |
4729 | if (!bRebuild) { |
4730 | bRebuild = aLFIm.Extent() && theInvFaces.Contains(aF); |
4731 | if (bRebuild) { |
4732 | theFSelfRebAvoid.Add(aF); |
4733 | } |
4734 | } |
4735 | // |
4736 | if (bRebuild) { |
4737 | theFToRebuild.Add(aF, aLEValid); |
4738 | } |
4739 | } |
4740 | } |
4741 | |
4742 | //======================================================================= |
4743 | //function : RebuildFaces |
4744 | //purpose : Rebuilding of the faces |
4745 | //======================================================================= |
4746 | void RebuildFaces(const TopTools_IndexedDataMapOfShapeListOfShape& theFToRebuild, |
4747 | const TopTools_MapOfShape& theFSelfRebAvoid, |
4748 | const TopoDS_Shape& theSolids, |
6f04cbb1 |
4749 | const BRepOffset_MakeOffset_InterResults& theIntRes, |
bea10656 |
4750 | const BRepOffset_Analyse* theAnalyse, |
ecf4f17c |
4751 | TopTools_IndexedDataMapOfShapeListOfShape& theFImages, |
0da0275c |
4752 | TopTools_DataMapOfShapeListOfShape& theDMFNewHoles, |
ecf4f17c |
4753 | TopTools_DataMapOfShapeListOfShape& theEdgesOrigins, |
4754 | TopTools_DataMapOfShapeShape& theFacesOrigins, |
4755 | TopTools_DataMapOfShapeListOfShape& theOEImages, |
4756 | TopTools_DataMapOfShapeListOfShape& theOEOrigins, |
4757 | TopTools_MapOfShape& theLastInvEdges, |
4758 | TopTools_IndexedMapOfShape& theEdgesToAvoid, |
4759 | TopTools_IndexedMapOfShape& theInvEdges, |
4760 | TopTools_IndexedMapOfShape& theValidEdges, |
4761 | const TopTools_MapOfShape& theInvertedEdges, |
4762 | TopTools_DataMapOfShapeInteger& theAlreadyInvFaces, |
4763 | TopTools_IndexedDataMapOfShapeListOfShape& theInvFaces, |
4764 | const TopTools_DataMapOfShapeShape& theArtInvFaces, |
4765 | TopTools_MapOfShape& theVertsToAvoid, |
4766 | TopTools_DataMapOfShapeShape& theETrimEInf, |
4767 | Handle(BRepAlgo_AsDes)& theAsDes) |
4768 | { |
4769 | TopTools_MapOfShape aModifiedEdges; |
4770 | // |
4771 | // 1. Intersect faces |
6f04cbb1 |
4772 | IntersectFaces(theFToRebuild, theFSelfRebAvoid, theSolids, theIntRes, theFImages, theEdgesOrigins, theOEImages, |
ecf4f17c |
4773 | theOEOrigins, theInvEdges, theValidEdges, theInvertedEdges, theEdgesToAvoid, |
4774 | theInvFaces, theArtInvFaces, theVertsToAvoid, theETrimEInf, aModifiedEdges, theAsDes); |
4775 | // |
4776 | // 2. Repeat steps to build the correct faces |
bea10656 |
4777 | BuildSplitsOfInvFaces(theFToRebuild, aModifiedEdges, theAnalyse, theFImages, theDMFNewHoles, theEdgesOrigins, |
ecf4f17c |
4778 | theFacesOrigins, theOEImages, theOEOrigins, theLastInvEdges, |
4779 | theEdgesToAvoid, theVertsToAvoid, theAlreadyInvFaces, theValidEdges, |
4780 | theETrimEInf, theAsDes); |
4781 | } |
4782 | |
4783 | //======================================================================= |
4784 | //function : IntersectFaces |
4785 | //purpose : Intersection of the faces that should be rebuild |
4786 | // to resolve all invalidities |
4787 | //======================================================================= |
4788 | void IntersectFaces(const TopTools_IndexedDataMapOfShapeListOfShape& theFToRebuild, |
4789 | const TopTools_MapOfShape& theFSelfRebAvoid, |
4790 | const TopoDS_Shape& theSolids, |
6f04cbb1 |
4791 | const BRepOffset_MakeOffset_InterResults& theIntRes, |
ecf4f17c |
4792 | TopTools_IndexedDataMapOfShapeListOfShape& theFImages, |
4793 | TopTools_DataMapOfShapeListOfShape& theEdgesOrigins, |
4794 | TopTools_DataMapOfShapeListOfShape& theOEImages, |
4795 | TopTools_DataMapOfShapeListOfShape& theOEOrigins, |
4796 | TopTools_IndexedMapOfShape& theInvEdges, |
4797 | TopTools_IndexedMapOfShape& theValidEdges, |
4798 | const TopTools_MapOfShape& theInvertedEdges, |
4799 | TopTools_IndexedMapOfShape& theEdgesToAvoid, |
4800 | TopTools_IndexedDataMapOfShapeListOfShape& theInvFaces, |
4801 | const TopTools_DataMapOfShapeShape& theArtInvFaces, |
4802 | TopTools_MapOfShape& theVertsToAvoid, |
4803 | TopTools_DataMapOfShapeShape& theETrimEInf, |
4804 | TopTools_MapOfShape& theModifiedEdges, |
4805 | Handle(BRepAlgo_AsDes)& theAsDes) |
4806 | { |
4807 | Standard_Integer aNbFR = theFToRebuild.Extent(); |
4808 | if (!aNbFR) { |
4809 | return; |
4810 | } |
4811 | // |
4812 | Standard_Integer i, j, k, aNbInv; |
4813 | TopTools_ListIteratorOfListOfShape aItLF, aItLE; |
ecf4f17c |
4814 | // |
4815 | // get vertices from invalid edges |
4816 | TopTools_MapOfShape aMVInv, aMVInvAll; |
4817 | aNbInv = theInvEdges.Extent(); |
4818 | for (i = 1; i <= aNbInv; ++i) { |
4819 | const TopoDS_Shape& aEInv = theInvEdges(i); |
4820 | Standard_Boolean bValid = theValidEdges.Contains(aEInv); |
45d0af05 |
4821 | for (TopExp_Explorer aExp (aEInv, TopAbs_VERTEX); aExp.More(); aExp.Next()) { |
ecf4f17c |
4822 | const TopoDS_Shape& aV = aExp.Current(); |
4823 | aMVInvAll.Add(aV); |
4824 | if (!bValid) { |
4825 | aMVInv.Add(aV); |
4826 | } |
4827 | } |
4828 | } |
4829 | // |
4830 | Standard_Boolean bLookVertToAvoid = (aMVInv.Extent() > 0); |
4831 | // |
4832 | TopTools_DataMapOfShapeListOfShape aDMSF, aMDone, aMEInfETrim, aDMVEFull; |
4833 | TopTools_IndexedDataMapOfShapeListOfShape aFLE, aDMEFInv; |
4834 | // |
4835 | // Add all faces to rebuild to outgoing map <aFLE>, |
4836 | // plus link edges and vertices to the faces to |
4837 | // define intersection faces |
4838 | PrepareFacesForIntersection(theFToRebuild, theFImages, theInvFaces, theArtInvFaces, |
4839 | bLookVertToAvoid, aFLE, aMDone, aDMSF, aMEInfETrim, |
4840 | aDMVEFull, theETrimEInf, aDMEFInv); |
4841 | |
4842 | // Find vertices to avoid while trimming the edges. |
4843 | // These vertices are taken from the invalid edges common between |
4844 | // splits of different invalid, but not artificially, faces. |
4845 | // Additional condition for these vertices is that all |
4846 | // edges adjacent to this vertex must be either invalid |
4847 | // or contained in invalid faces |
4848 | TopTools_MapOfShape aMVRInv = theVertsToAvoid; |
bc4a3867 |
4849 | FindVerticesToAvoid(aDMEFInv, theInvEdges, theValidEdges, theInvertedEdges, |
4850 | aDMVEFull, theOEImages, theOEOrigins, aMVRInv); |
ecf4f17c |
4851 | // |
4852 | // The faces should be intersected selectively - |
4853 | // intersect only faces neighboring to the same invalid face |
4854 | // and connected to its invalid edges; |
4855 | // when dealing with artificially invalid faces for intersection to be |
4856 | // complete we need to use not only invalid edges, but also the |
4857 | // edges connected to invalid ones |
b443d536 |
4858 | |
4859 | // find blocks of artificially invalid faces |
4860 | TopTools_DataMapOfShapeShape aDMFImF; |
4861 | TopoDS_Compound aCFArt; |
4862 | BRep_Builder().MakeCompound(aCFArt); |
ecf4f17c |
4863 | TopTools_DataMapIteratorOfDataMapOfShapeShape aItM(theArtInvFaces); |
4864 | for (; aItM.More(); aItM.Next()) { |
4865 | const TopoDS_Shape& aF = aItM.Key(); |
4866 | const TopTools_ListOfShape& aLFInv = theInvFaces.FindFromKey(aF); |
4867 | aItLF.Initialize(aLFInv); |
4868 | for (; aItLF.More(); aItLF.Next()) { |
b443d536 |
4869 | BRep_Builder().Add(aCFArt, aItLF.Value()); |
4870 | aDMFImF.Bind(aItLF.Value(), aF); |
ecf4f17c |
4871 | } |
4872 | } |
4873 | // |
b443d536 |
4874 | // make connexity blocks |
4875 | TopTools_ListOfShape aLCBArt; |
4876 | BOPTools_AlgoTools::MakeConnexityBlocks(aCFArt, TopAbs_VERTEX, TopAbs_FACE, aLCBArt); |
4877 | // |
4878 | // alone edges |
a8232603 |
4879 | TopTools_MapOfShape aMEAlone, aMEInvOnArt; |
b443d536 |
4880 | // |
4881 | TopTools_ListIteratorOfListOfShape aItLCBArt(aLCBArt); |
4882 | for (; aItLCBArt.More(); aItLCBArt.Next()) { |
4883 | const TopoDS_Shape& aCB = aItLCBArt.Value(); |
41aa3c3d |
4884 | // |
b443d536 |
4885 | // check if aCB contains splits of only one offset face |
4886 | TopTools_MapOfShape aMFArt; |
4887 | TopExp_Explorer aExpF(aCB, TopAbs_FACE); |
4888 | for (; aExpF.More(); aExpF.Next()) { |
4889 | aMFArt.Add(aDMFImF.Find(aExpF.Current())); |
41aa3c3d |
4890 | } |
4891 | // |
b443d536 |
4892 | Standard_Boolean bAlone = (aMFArt.Extent() == 1); |
41aa3c3d |
4893 | // |
b443d536 |
4894 | // vertices on invalid edges |
4895 | TopTools_MapOfShape aMVEInv; |
4896 | TopTools_MapOfShape aMFence; |
4897 | // edges that should not be marked as alone - edges having same origins as invalid ones |
4898 | TopTools_MapOfShape aMEAvoid; |
4899 | // map to find alone edges by looking for free vertices |
4900 | TopTools_IndexedDataMapOfShapeListOfShape aDMVEVal; |
4901 | // |
4902 | TopExp_Explorer aExpE(aCB, TopAbs_EDGE); |
4903 | for (; aExpE.More(); aExpE.Next()) { |
4904 | const TopoDS_Shape& aE = aExpE.Current(); |
4905 | if (theInvEdges.Contains(aE)) { |
a8232603 |
4906 | aMEInvOnArt.Add(aE); |
b443d536 |
4907 | for (TopoDS_Iterator aItV(aE); aItV.More(); aItV.Next()) { |
4908 | aMVEInv.Add(aItV.Value()); |
4909 | } |
4910 | // |
4911 | if (bAlone) { |
4912 | const TopTools_ListOfShape *pLEOr = theOEOrigins.Seek(aE); |
4913 | if (pLEOr) { |
4914 | TopTools_ListIteratorOfListOfShape aItLEOr(*pLEOr); |
4915 | for (; aItLEOr.More(); aItLEOr.Next()) { |
4916 | TopTools_ListIteratorOfListOfShape aItLEIm(theOEImages.Find(aItLEOr.Value())); |
4917 | for (; aItLEIm.More(); aItLEIm.Next()) { |
4918 | aMEAvoid.Add(aItLEIm.Value()); |
4919 | } |
4920 | } |
4921 | } |
4922 | } |
4923 | continue; |
4924 | } |
4925 | // |
4926 | if (aMFence.Add(aE)) { |
4927 | TopExp::MapShapesAndAncestors(aE, TopAbs_VERTEX, TopAbs_EDGE, aDMVEVal); |
ecf4f17c |
4928 | } |
41aa3c3d |
4929 | } |
4930 | // |
b443d536 |
4931 | // find edges with free vertices |
4932 | Standard_Integer aNbV = aDMVEVal.Extent(); |
4933 | for (i = 1; i <= aNbV; ++i) { |
4934 | const TopoDS_Shape& aV = aDMVEVal.FindKey(i); |
4935 | if (!aMVEInv.Contains(aV)) { |
4936 | continue; |
4937 | } |
ecf4f17c |
4938 | // |
b443d536 |
4939 | const TopTools_ListOfShape& aLEV = aDMVEVal(i); |
4940 | if (aLEV.Extent() > 1) { |
4941 | continue; |
4942 | } |
4943 | // |
4944 | const TopoDS_Shape& aE = aLEV.First(); |
4945 | if (aMEAvoid.Contains(aE)) { |
4946 | continue; |
4947 | } |
4948 | // |
4949 | aMEAlone.Add(aE); |
4950 | // |
4951 | // if this alone edge adds nothing to the intersection list |
4952 | // it means that the origin of this edge has been split and we need to |
4953 | // add the neighboring images of the same origins |
4954 | if (aDMSF.Find(aE).Extent() > 1) { |
4955 | continue; |
4956 | } |
4957 | // |
4958 | // check also its vertices |
4959 | TopoDS_Iterator aItE(aE); |
4960 | for (; aItE.More(); aItE.Next()) { |
4961 | const TopoDS_Shape& aVE = aItE.Value(); |
4962 | if (aDMSF.Find(aVE).Extent() > 2) { |
4963 | break; |
4964 | } |
4965 | } |
4966 | // |
4967 | if (aItE.More()) { |
4968 | continue; |
4969 | } |
4970 | // |
4971 | // the edge is useless - look for other images |
4972 | const TopTools_ListOfShape *pLEOr = theOEOrigins.Seek(aE); |
4973 | if (!pLEOr) { |
4974 | continue; |
4975 | } |
4976 | // |
4977 | TopTools_ListIteratorOfListOfShape aItLEOr(*pLEOr); |
4978 | for (; aItLEOr.More(); aItLEOr.Next()) { |
4979 | const TopoDS_Shape& aEOr = aItLEOr.Value(); |
41aa3c3d |
4980 | // |
b443d536 |
4981 | const TopTools_ListOfShape& aLEIm = theOEImages.Find(aEOr); |
4982 | TopTools_ListIteratorOfListOfShape aItLEIm(aLEIm); |
4983 | for (; aItLEIm.More(); aItLEIm.Next()) { |
4984 | const TopoDS_Shape& aEIm = aItLEIm.Value(); |
4985 | // |
4986 | if (aMFence.Contains(aEIm)) { |
4987 | aMEAlone.Add(aEIm); |
4988 | } |
ecf4f17c |
4989 | } |
4990 | } |
41aa3c3d |
4991 | } |
4992 | } |
4993 | // |
4994 | // Get all invalidities from all faces to be used for avoiding |
4995 | // repeated usage of the common edges |
4996 | TopTools_MapOfShape aMAllInvs; |
4997 | aNbInv = theInvFaces.Extent(); |
4998 | for (k = 1; k <= aNbInv; ++k) { |
4999 | TopTools_ListIteratorOfListOfShape aIt(theInvFaces(k)); |
5000 | for (; aIt.More(); aIt.Next()) { |
5001 | TopExp_Explorer aExp(aIt.Value(), TopAbs_EDGE); |
5002 | for (; aExp.More(); aExp.Next()) { |
5003 | const TopoDS_Shape& aE = aExp.Current(); |
5004 | if (theInvEdges.Contains(aE) || aMEAlone.Contains(aE)) { |
5005 | aMAllInvs.Add(aE); |
5006 | TopoDS_Iterator aItV(aE); |
5007 | for (; aItV.More(); aItV.Next()) { |
5008 | aMAllInvs.Add(aItV.Value()); |
ecf4f17c |
5009 | } |
5010 | } |
5011 | } |
5012 | } |
5013 | } |
5014 | // |
5015 | // Bounding vertices of not trimmed edges |
5016 | TopTools_MapOfShape aMVBounds; |
41aa3c3d |
5017 | // |
5018 | TopTools_MapOfShape aMECheckExt; |
ecf4f17c |
5019 | // Save connections between not trimmed edge and its trimmed parts |
5020 | TopTools_DataMapOfShapeListOfShape aDMEETrim; |
5021 | // Splits of the new edges |
5022 | TopTools_DataMapOfShapeListOfShape aEImages; |
5023 | BRep_Builder aBB; |
dcba2e5c |
5024 | |
5025 | // Keep connection between blocks of invalid edges to the lists of |
5026 | // found edges to be intersected for its treatment |
5027 | TopTools_IndexedDataMapOfShapeListOfShape aDMOENEdges; |
5028 | |
ecf4f17c |
5029 | aNbInv = theInvFaces.Extent(); |
5030 | for (k = 1; k <= aNbInv; ++k) { |
5031 | const TopoDS_Shape& aFInv = theInvFaces.FindKey(k); |
5032 | Standard_Boolean bSelfRebAvoid = theFSelfRebAvoid.Contains(aFInv); |
5033 | const TopTools_ListOfShape& aLFInv = theInvFaces(k); |
5034 | // |
5035 | TopTools_ListOfShape aLCB; |
5036 | if (aLFInv.Extent() > 1) { |
5037 | // make compound of invalid faces |
5038 | TopoDS_Compound aCFInv; |
5039 | aBB.MakeCompound(aCFInv); |
5040 | // |
5041 | TopTools_ListIteratorOfListOfShape aIt(aLFInv); |
5042 | for (; aIt.More(); aIt.Next()) { |
5043 | const TopoDS_Shape& aFIm = aIt.Value(); |
5044 | aBB.Add(aCFInv, aFIm); |
5045 | } |
5046 | // |
5047 | // make connexity blocks |
5048 | BOPTools_AlgoTools::MakeConnexityBlocks(aCFInv, TopAbs_EDGE, TopAbs_FACE, aLCB); |
5049 | } |
5050 | else { |
5051 | aLCB = aLFInv; |
5052 | } |
5053 | // |
5054 | Standard_Boolean bArtificial = theArtInvFaces.IsBound(aFInv); |
5055 | TopTools_ListIteratorOfListOfShape aItLCB(aLCB); |
5056 | for (; aItLCB.More(); aItLCB.Next()) { |
5057 | const TopoDS_Shape& aCBInv = aItLCB.Value(); |
5058 | // |
5059 | TopTools_MapOfShape aMEFence; |
5060 | // |
5061 | TopoDS_Compound aCBE; |
5062 | aBB.MakeCompound(aCBE); |
5063 | // |
5064 | TopExp_Explorer aExp(aCBInv, TopAbs_EDGE); |
5065 | for (; aExp.More(); aExp.Next()) { |
5066 | const TopoDS_Shape& aE = aExp.Current(); |
5067 | if (theInvEdges.Contains(aE) || (bArtificial && aMEAlone.Contains(aE))) { |
5068 | if (aMEFence.Add(aE)) { |
5069 | aBB.Add(aCBE, aE); |
5070 | } |
5071 | } |
5072 | } |
5073 | // |
5074 | // make connexity blocks of edges |
5075 | TopTools_ListOfShape aLCBE; |
5076 | BOPTools_AlgoTools::MakeConnexityBlocks(aCBE, TopAbs_VERTEX, TopAbs_EDGE, aLCBE); |
5077 | // |
5078 | TopTools_ListIteratorOfListOfShape aItLCBE(aLCBE); |
5079 | for (; aItLCBE.More(); aItLCBE.Next()) { |
5080 | const TopoDS_Shape& aCBELoc = aItLCBE.Value(); |
5081 | // |
5082 | // map of edges and vertices of processing invalidity |
5083 | TopTools_IndexedMapOfShape aME; |
5084 | // map of vertices to trim the new edges |
5085 | TopTools_IndexedMapOfShape aMECV; |
5086 | TopExp::MapShapes(aCBELoc, TopAbs_EDGE, aME); |
5087 | aMECV = aME; |
5088 | TopExp::MapShapes(aCBELoc, TopAbs_VERTEX, aME); |
5089 | // |
5090 | // Using the map <aME> find chain of faces to be intersected; |
5091 | // |
5092 | // faces for intersection |
5093 | TopTools_IndexedMapOfShape aMFInt; |
5094 | // additional faces for intersection |
5095 | TopTools_IndexedMapOfShape aMFIntExt; |
5096 | // splits of faces for intersection |
5097 | TopTools_ListOfShape aLFInt; |
5098 | // faces to avoid intersection |
5099 | TopTools_IndexedMapOfShape aMFAvoid; |
5100 | // |
5101 | FindFacesForIntersection(aFInv, aME, theFImages, aDMSF, aMVInvAll, |
6f04cbb1 |
5102 | theArtInvFaces, bArtificial, theIntRes.SSInterfs, aMFAvoid, aMFInt, aMFIntExt, aLFInt); |
ecf4f17c |
5103 | if (aMFInt.Extent() < 3) { |
5104 | // nothing to intersect |
5105 | continue; |
5106 | } |
5107 | // |
6f04cbb1 |
5108 | const BRepOffset_DataMapOfShapeMapOfShape* pMFInter = theIntRes.InterPairs.Seek (aFInv); |
ecf4f17c |
5109 | // intersect the faces, but do not intersect the invalid ones |
5110 | // among each other (except for the artificially invalid faces) |
5111 | TopTools_IndexedMapOfShape aMEToInt; |
5112 | Standard_Integer aNb = aMFInt.Extent(); |
5113 | for (i = 1; i <= aNb; ++i) { |
5114 | const TopoDS_Face& aFi = TopoDS::Face(aMFInt(i)); |
5115 | if (bSelfRebAvoid && aFi.IsSame(aFInv)) { |
5116 | continue; |
5117 | } |
5118 | // |
5119 | const TopTools_ListOfShape& aLFImi = theFImages.FindFromKey(aFi); |
5120 | // |
5121 | TopTools_ListOfShape& aLFEi = aFLE.ChangeFromKey(aFi); |
5122 | // |
5123 | TopTools_ListOfShape& aLFDone = aMDone.ChangeFind(aFi); |
5124 | // |
6f04cbb1 |
5125 | const TopTools_MapOfShape* pInterFi = !pMFInter ? 0 : pMFInter->Seek (aFi); |
5126 | if (pMFInter && !pInterFi) |
5127 | continue; |
5128 | |
ecf4f17c |
5129 | for (j = i + 1; j <= aNb; ++j) { |
5130 | const TopoDS_Face& aFj = TopoDS::Face(aMFInt(j)); |
5131 | if (bSelfRebAvoid && aFj.IsSame(aFInv)) { |
5132 | continue; |
5133 | } |
5134 | // |
6f04cbb1 |
5135 | if (pInterFi && !pInterFi->Contains (aFj)) |
5136 | continue; |
5137 | |
ecf4f17c |
5138 | const TopTools_ListOfShape& aLFImj = theFImages.FindFromKey(aFj); |
5139 | // |
5140 | TopTools_ListOfShape& aLFEj = aFLE.ChangeFromKey(aFj); |
5141 | // |
5142 | // if there are some common edges between faces |
5143 | // we should use these edges and do not intersect again. |
5144 | TopTools_ListOfShape aLEC; |
5145 | FindCommonParts(aLFImi, aLFImj, aLEC); |
5146 | // |
5147 | if (aLEC.Extent()) { |
5148 | // no need to intersect if we have common edges between faces |
5149 | Standard_Boolean bForceUse = aMFIntExt.Contains(aFi) || aMFIntExt.Contains(aFj); |
5150 | ProcessCommonEdges(aLEC, theInvEdges, theValidEdges, aME, theETrimEInf, aMEInfETrim, |
41aa3c3d |
5151 | theOEOrigins, aMAllInvs, bForceUse, aMECV, aMECheckExt, aDMEETrim, aLFEi, aLFEj, aMEToInt); |
ecf4f17c |
5152 | continue; |
5153 | } |
5154 | // |
5155 | // check if both these faces are invalid and sharing edges |
5156 | if (theInvFaces.Contains(aFi) && theInvFaces.Contains(aFj) && |
5157 | !theArtInvFaces.IsBound(aFi) && !theArtInvFaces.IsBound(aFj)) { |
5158 | continue; |
5159 | } |
5160 | // |
5161 | // check if these two faces have already been treated |
5162 | aItLE.Initialize(aLFDone); |
5163 | for (; aItLE.More(); aItLE.Next()) { |
5164 | const TopoDS_Shape& aF = aItLE.Value(); |
5165 | if (aF.IsSame(aFj)) { |
5166 | break; |
5167 | } |
5168 | } |
5169 | // |
5170 | if (aItLE.More()) { |
5171 | // use intersection line obtained on the previous steps |
5172 | // plus, find new origins for these lines |
5173 | UpdateIntersectedFaces(aFInv, aFi, aFj, aLFInv, aLFImi, aLFImj, |
5174 | aLFEi, aLFEj, theEdgesOrigins, aMEToInt); |
5175 | continue; |
5176 | } |
5177 | // |
5178 | if (aMFAvoid.Contains(aFi) || aMFAvoid.Contains(aFj)) { |
5179 | continue; |
5180 | } |
5181 | // |
5182 | aLFDone.Append(aFj); |
5183 | aMDone.ChangeFind(aFj).Append(aFi); |
5184 | // |
5185 | IntersectFaces(aFInv, aFi, aFj, aLFInv, aLFImi, aLFImj, |
5186 | aLFEi, aLFEj, theEdgesOrigins, aMECV, aMEToInt); |
5187 | } |
5188 | } |
5189 | // |
5190 | // intersect and trim edges for this chain |
41aa3c3d |
5191 | IntersectAndTrimEdges(theFToRebuild, aMFInt, aMEToInt, aDMEETrim, aME, aMECV, |
5192 | aMVInv, aMVRInv, aMECheckExt, aMVBounds, aEImages); |
dcba2e5c |
5193 | // |
dcba2e5c |
5194 | Standard_Integer iE, aNbEToInt = aMEToInt.Extent(); |
5195 | for (iE = 1; iE <= aNbEToInt; ++iE) |
bc4a3867 |
5196 | { |
5197 | const TopoDS_Shape& aEInt = aMEToInt(iE); |
5198 | TopExp_Explorer anExpE(aCBELoc, TopAbs_EDGE); |
5199 | for (; anExpE.More(); anExpE.Next()) |
5200 | { |
5201 | const TopoDS_Shape& aE = anExpE.Current(); |
5202 | TopTools_ListOfShape* pLEToInt = aDMOENEdges.ChangeSeek(aE); |
5203 | if (!pLEToInt) |
5204 | pLEToInt = &aDMOENEdges(aDMOENEdges.Add(aE, TopTools_ListOfShape())); |
5205 | AppendToList(*pLEToInt, aEInt); |
5206 | } |
5207 | } |
ecf4f17c |
5208 | } |
5209 | } |
5210 | } |
5211 | // |
5212 | // filter the obtained edges |
dcba2e5c |
5213 | UpdateValidEdges(theFImages, aFLE, aDMOENEdges, aMVBounds, theSolids, theInvEdges, theInvertedEdges, aMEInvOnArt, |
41aa3c3d |
5214 | aMECheckExt, theEdgesToAvoid, theEdgesOrigins, theOEImages, theOEOrigins, |
ecf4f17c |
5215 | theVertsToAvoid, theETrimEInf, aEImages, aDMEETrim, theModifiedEdges, theAsDes); |
5216 | } |
5217 | |
5218 | //======================================================================= |
5219 | //function : PrepareFacesForIntersection |
5220 | //purpose : Preparation of the maps for analyzing intersections of the faces |
5221 | //======================================================================= |
5222 | void PrepareFacesForIntersection(const TopTools_IndexedDataMapOfShapeListOfShape& theFToRebuild, |
5223 | const TopTools_IndexedDataMapOfShapeListOfShape& theFImages, |
5224 | const TopTools_IndexedDataMapOfShapeListOfShape& theInvFaces, |
5225 | const TopTools_DataMapOfShapeShape& theArtInvFaces, |
5226 | const Standard_Boolean bLookVertToAvoid, |
5227 | TopTools_IndexedDataMapOfShapeListOfShape& theFLE, |
5228 | TopTools_DataMapOfShapeListOfShape& theMDone, |
5229 | TopTools_DataMapOfShapeListOfShape& theDMSF, |
5230 | TopTools_DataMapOfShapeListOfShape& theMEInfETrim, |
5231 | TopTools_DataMapOfShapeListOfShape& theDMVEFull, |
5232 | TopTools_DataMapOfShapeShape& theETrimEInf, |
5233 | TopTools_IndexedDataMapOfShapeListOfShape& theDMEFInv) |
5234 | { |
5235 | Standard_Integer i, aNb = theFToRebuild.Extent(); |
5236 | for (i = 1; i <= aNb; ++i) { |
5237 | const TopoDS_Shape& aF = theFToRebuild.FindKey(i); |
5238 | // |
5239 | TopTools_ListOfShape aLE; |
5240 | theFLE.Add(aF, aLE); |
5241 | theMDone.Bind(aF, aLE); |
5242 | // |
5243 | const TopTools_ListOfShape& aLFIm = theFImages.FindFromKey(aF); |
5244 | TopTools_ListIteratorOfListOfShape aItLF(aLFIm); |
5245 | for (; aItLF.More(); aItLF.Next()) { |
5246 | const TopoDS_Shape& aFIm = aItLF.Value(); |
5247 | TopExp_Explorer aExp(aFIm, TopAbs_EDGE); |
5248 | for (; aExp.More(); aExp.Next()) { |
5249 | const TopoDS_Shape& aE = aExp.Current(); |
5250 | // save connection to untrimmed face |
5251 | TopTools_ListOfShape *pLF = theDMSF.ChangeSeek(aE); |
5252 | if (!pLF) { |
5253 | pLF = theDMSF.Bound(aE, TopTools_ListOfShape()); |
5254 | } |
5255 | AppendToList(*pLF, aF); |
5256 | // |
5257 | // save connection to untrimmed edge |
5258 | const TopoDS_Shape& aEInf = theETrimEInf.Find(aE); |
5259 | TopTools_ListOfShape *pLETrim = theMEInfETrim.ChangeSeek(aEInf); |
5260 | if (!pLETrim) { |
5261 | pLETrim = theMEInfETrim.Bound(aEInf, TopTools_ListOfShape()); |
5262 | } |
5263 | AppendToList(*pLETrim, aE); |
5264 | // |
5265 | TopExp_Explorer aExpV(aE, TopAbs_VERTEX); |
5266 | for (; aExpV.More(); aExpV.Next()) { |
5267 | const TopoDS_Shape& aV = aExpV.Current(); |
5268 | // save connection to face |
5269 | TopTools_ListOfShape *pLFV = theDMSF.ChangeSeek(aV); |
5270 | if (!pLFV) { |
5271 | pLFV = theDMSF.Bound(aV, TopTools_ListOfShape()); |
5272 | } |
5273 | AppendToList(*pLFV, aF); |
5274 | // |
5275 | if (bLookVertToAvoid) { |
5276 | // save connection to edges |
5277 | TopTools_ListOfShape *pLEV = theDMVEFull.ChangeSeek(aV); |
5278 | if (!pLEV) { |
5279 | pLEV = theDMVEFull.Bound(aV, TopTools_ListOfShape()); |
5280 | } |
5281 | AppendToList(*pLEV, aE); |
5282 | } |
5283 | } |
5284 | } |
5285 | } |
5286 | // |
5287 | if (bLookVertToAvoid) { |
5288 | // get edges of invalid faces (from invalid splits only) |
5289 | const TopTools_ListOfShape *pLFInv = theInvFaces.Seek(aF); |
5290 | if (!pLFInv || theArtInvFaces.IsBound(aF)) { |
5291 | continue; |
5292 | } |
5293 | // |
5294 | aItLF.Initialize(*pLFInv); |
5295 | for (; aItLF.More(); aItLF.Next()) { |
5296 | const TopoDS_Shape& aFInv = aItLF.Value(); |
5297 | TopExp_Explorer aExp(aFInv, TopAbs_EDGE); |
5298 | for (; aExp.More(); aExp.Next()) { |
5299 | const TopoDS_Shape& aE = aExp.Current(); |
5300 | TopTools_ListOfShape *pLF = theDMEFInv.ChangeSeek(aE); |
5301 | if (!pLF) { |
5302 | pLF = &theDMEFInv(theDMEFInv.Add(aE, TopTools_ListOfShape())); |
5303 | } |
5304 | AppendToList(*pLF, aF); |
5305 | } |
5306 | } |
5307 | } |
5308 | } |
5309 | } |
5310 | |
5311 | //======================================================================= |
5312 | //function : FindVerticesToAvoid |
5313 | //purpose : Looking for the invalid vertices |
5314 | //======================================================================= |
5315 | void FindVerticesToAvoid(const TopTools_IndexedDataMapOfShapeListOfShape& theDMEFInv, |
5316 | const TopTools_IndexedMapOfShape& theInvEdges, |
5317 | const TopTools_IndexedMapOfShape& theValidEdges, |
bc4a3867 |
5318 | const TopTools_MapOfShape& theInvertedEdges, |
5319 | const TopTools_DataMapOfShapeListOfShape& theDMVEFull, |
5320 | const TopTools_DataMapOfShapeListOfShape& theOEImages, |
5321 | const TopTools_DataMapOfShapeListOfShape& theOEOrigins, |
ecf4f17c |
5322 | TopTools_MapOfShape& theMVRInv) |
5323 | { |
5324 | TopTools_MapOfShape aMFence; |
5325 | Standard_Integer i, aNb = theDMEFInv.Extent(); |
5326 | for (i = 1; i <= aNb; ++i) { |
5327 | const TopTools_ListOfShape& aLFInv = theDMEFInv(i); |
5328 | if (aLFInv.Extent() == 1) { |
5329 | continue; |
5330 | } |
5331 | // |
5332 | const TopoDS_Shape& aE = theDMEFInv.FindKey(i); |
5333 | if (!theInvEdges.Contains(aE) || theValidEdges.Contains(aE)) { |
5334 | continue; |
5335 | } |
bc4a3867 |
5336 | |
5337 | if (!aMFence.Add(aE)) |
5338 | continue; |
5339 | |
5340 | TopTools_IndexedDataMapOfShapeListOfShape aMVEEdges; |
5341 | // Do not check the splitting vertices, but check only the ending ones |
5342 | const TopTools_ListOfShape *pLEOr = theOEOrigins.Seek(aE); |
5343 | if (pLEOr) |
5344 | { |
5345 | TopTools_ListIteratorOfListOfShape aItLEOr(*pLEOr); |
5346 | for (; aItLEOr.More(); aItLEOr.Next()) |
5347 | { |
5348 | const TopTools_ListOfShape& aLEIm = theOEImages.Find(aItLEOr.Value()); |
5349 | TopTools_ListIteratorOfListOfShape aItLEIm(aLEIm); |
5350 | for (; aItLEIm.More(); aItLEIm.Next()) |
5351 | { |
5352 | aMFence.Add(aItLEIm.Value()); |
5353 | TopExp::MapShapesAndAncestors(aItLEIm.Value(), TopAbs_VERTEX, TopAbs_EDGE, aMVEEdges); |
5354 | } |
5355 | } |
5356 | } |
5357 | else |
5358 | { |
5359 | TopExp::MapShapesAndAncestors(aE, TopAbs_VERTEX, TopAbs_EDGE, aMVEEdges); |
5360 | } |
5361 | |
5362 | Standard_Integer j, aNbV = aMVEEdges.Extent(); |
5363 | for (j = 1; j <= aNbV; ++j) |
5364 | { |
5365 | if (aMVEEdges(j).Extent() != 1) |
5366 | continue; |
5367 | |
5368 | const TopoDS_Shape& aV = aMVEEdges.FindKey(j); |
5369 | if (!aMFence.Add(aV)) |
5370 | continue; |
5371 | const TopTools_ListOfShape *pLE = theDMVEFull.Seek(aV); |
ecf4f17c |
5372 | if (!pLE) { |
bc4a3867 |
5373 | // isolated vertex |
ecf4f17c |
5374 | theMVRInv.Add(aV); |
5375 | continue; |
5376 | } |
5377 | // |
bc4a3867 |
5378 | // If all edges sharing the vertex are either invalid or |
5379 | // the vertex is connected to at least two inverted edges |
5380 | // mark the vertex to be avoided in the new splits |
5381 | Standard_Integer iNbEInverted = 0; |
5382 | Standard_Boolean bAllEdgesInv = Standard_True; |
ecf4f17c |
5383 | TopTools_ListIteratorOfListOfShape aItLE(*pLE); |
5384 | for (; aItLE.More(); aItLE.Next()) { |
5385 | const TopoDS_Shape& aEV = aItLE.Value(); |
bc4a3867 |
5386 | |
5387 | if (theInvertedEdges.Contains(aEV)) |
5388 | ++iNbEInverted; |
5389 | |
5390 | if (bAllEdgesInv) |
5391 | bAllEdgesInv = theInvEdges.Contains(aEV); |
ecf4f17c |
5392 | } |
bc4a3867 |
5393 | |
5394 | if (iNbEInverted > 1 || bAllEdgesInv) |
5395 | { |
ecf4f17c |
5396 | theMVRInv.Add(aV); |
5397 | } |
5398 | } |
5399 | } |
5400 | } |
5401 | |
5402 | //======================================================================= |
5403 | //function : FindFacesForIntersection |
5404 | //purpose : Looking for the faces around each invalidity for intersection |
5405 | //======================================================================= |
5406 | void FindFacesForIntersection(const TopoDS_Shape& theFInv, |
5407 | const TopTools_IndexedMapOfShape& theME, |
5408 | const TopTools_IndexedDataMapOfShapeListOfShape& theFImages, |
5409 | const TopTools_DataMapOfShapeListOfShape& theDMSF, |
5410 | const TopTools_MapOfShape& theMVInvAll, |
5411 | const TopTools_DataMapOfShapeShape& theArtInvFaces, |
5412 | const Standard_Boolean theArtCase, |
5413 | const TopTools_DataMapOfShapeListOfShape& theSSInterfs, |
5414 | TopTools_IndexedMapOfShape& theMFAvoid, |
5415 | TopTools_IndexedMapOfShape& theMFInt, |
5416 | TopTools_IndexedMapOfShape& theMFIntExt, |
5417 | TopTools_ListOfShape& theLFImInt) |
5418 | { |
5419 | Standard_Integer i, aNbE = theME.Extent(); |
5420 | // |
5421 | TopTools_IndexedMapOfShape aMShapes; |
5422 | // |
5423 | for (i = 1; i <= aNbE; ++i) { |
5424 | const TopoDS_Shape& aS = theME(i); |
5425 | if (!theDMSF.IsBound(aS)) { |
5426 | continue; |
5427 | } |
5428 | // |
5429 | // in artificial case we intersect the faces which are close to invalidity |
5430 | Standard_Boolean bAvoid = theArtCase ? |
5431 | ((aS.ShapeType() == TopAbs_VERTEX) && !theMVInvAll.Contains(aS)) : Standard_False; |
5432 | // |
5433 | const TopTools_ListOfShape& aLF = theDMSF.Find(aS); |
5434 | TopTools_ListIteratorOfListOfShape aItLF(aLF); |
5435 | for (; aItLF.More(); aItLF.Next()) { |
5436 | const TopoDS_Shape& aF = aItLF.Value(); |
5437 | if (theMFInt.Contains(aF)) { |
5438 | continue; |
5439 | } |
5440 | // |
5441 | if (bAvoid && theArtInvFaces.IsBound(aF)) { |
5442 | theMFAvoid.Add(aF); |
5443 | } |
5444 | // |
5445 | theMFInt.Add(aF); |
5446 | // |
5447 | Standard_Boolean bUse = !aF.IsSame(theFInv); |
5448 | // |
5449 | const TopTools_ListOfShape& aLFIm = theFImages.FindFromKey(aF); |
5450 | TopTools_ListIteratorOfListOfShape aItLFIm(aLFIm); |
5451 | for (; aItLFIm.More(); aItLFIm.Next()) { |
5452 | const TopoDS_Shape& aFIm = aItLFIm.Value(); |
5453 | theLFImInt.Append(aFIm); |
5454 | if (bUse) { |
5455 | TopExp::MapShapes(aFIm, TopAbs_EDGE, aMShapes); |
5456 | } |
5457 | } |
5458 | } |
5459 | } |
5460 | // |
5461 | if (theArtCase) { |
5462 | return; |
5463 | } |
5464 | // |
5465 | const TopTools_ListOfShape* pLFInv = theSSInterfs.Seek(theFInv); |
5466 | if (!pLFInv) { |
5467 | return; |
5468 | } |
5469 | // |
5470 | TopTools_MapOfShape aMF; |
5471 | TopTools_ListIteratorOfListOfShape aItLF(*pLFInv); |
5472 | for (; aItLF.More(); aItLF.Next()) { |
5473 | const TopoDS_Shape& aF = aItLF.Value(); |
5474 | aMF.Add(aF); |
5475 | } |
5476 | // |
5477 | // the faces should be unique in each place |
5478 | TopoDS_Compound aCF; |
5479 | BRep_Builder().MakeCompound(aCF); |
5480 | // |
5481 | TopTools_IndexedMapOfShape aMFToAdd; |
5482 | TopTools_DataMapOfShapeShape aDMFOr; |
5483 | // |
5484 | for (i = 1; i <= aNbE; ++i) { |
5485 | const TopoDS_Shape& aS = theME(i); |
5486 | const TopTools_ListOfShape* pLF = theSSInterfs.Seek(aS); |
5487 | if (!pLF) { |
5488 | continue; |
5489 | } |
5490 | // |
5491 | aItLF.Initialize(*pLF); |
5492 | for (; aItLF.More(); aItLF.Next()) { |
5493 | const TopoDS_Shape& aF = aItLF.Value(); |
5494 | if (theMFInt.Contains(aF) || aMFToAdd.Contains(aF) || !aMF.Contains(aF)) { |
5495 | continue; |
5496 | } |
5497 | // |
5498 | // check if the face has some connection to already added for intersection faces |
5499 | const TopTools_ListOfShape& aLFIm = theFImages.FindFromKey(aF); |
5500 | TopTools_ListIteratorOfListOfShape aItLFIm(aLFIm); |
5501 | for (; aItLFIm.More(); aItLFIm.Next()) { |
5502 | const TopoDS_Shape& aFIm = aItLFIm.Value(); |
5503 | TopExp_Explorer aExp(aFIm, TopAbs_EDGE); |
5504 | for (; aExp.More(); aExp.Next()) { |
5505 | if (aMShapes.Contains(aExp.Current())) { |
5506 | break; |
5507 | } |
5508 | } |
5509 | if (aExp.More()) { |
5510 | break; |
5511 | } |
5512 | } |
5513 | if (!aItLFIm.More()) { |
5514 | continue; |
5515 | } |
5516 | // |
5517 | aMFToAdd.Add(aF); |
5518 | aItLFIm.Initialize(aLFIm); |
5519 | for (; aItLFIm.More(); aItLFIm.Next()) { |
5520 | const TopoDS_Shape& aFIm = aItLFIm.Value(); |
5521 | aDMFOr.Bind(aFIm, aF); |
5522 | BRep_Builder().Add(aCF, aFIm); |
5523 | } |
5524 | } |
5525 | } |
5526 | // |
5527 | if (aMFToAdd.IsEmpty()) { |
5528 | return; |
5529 | } |
5530 | // |
5531 | TopTools_ListOfShape aLCB; |
5532 | BOPTools_AlgoTools::MakeConnexityBlocks(aCF, TopAbs_EDGE, TopAbs_FACE, aLCB); |
5533 | // |
5534 | if ((aLCB.Extent() == 1) && (aMFToAdd.Extent() > 1)) { |
5535 | return; |
5536 | } |
5537 | // |
5538 | TopTools_ListIteratorOfListOfShape aItLCB(aLCB); |
5539 | for (; aItLCB.More(); aItLCB.Next()) { |
5540 | const TopoDS_Shape& aCB = aItLCB.Value(); |
5541 | aMFToAdd.Clear(); |
5542 | TopExp_Explorer aExpF(aCB, TopAbs_FACE); |
5543 | for (; aExpF.More(); aExpF.Next()) { |
5544 | const TopoDS_Shape& aFIm = aExpF.Current(); |
5545 | aMFToAdd.Add(aDMFOr.Find(aFIm)); |
5546 | } |
5547 | // |
5548 | if (aMFToAdd.Extent() == 1) { |
5549 | const TopoDS_Shape& aF = aMFToAdd(1); |
5550 | // |
5551 | theMFInt.Add(aF); |
5552 | theMFIntExt.Add(aF); |
5553 | // |
5554 | const TopTools_ListOfShape& aLFIm = theFImages.FindFromKey(aF); |
5555 | TopTools_ListIteratorOfListOfShape aItLFIm(aLFIm); |
5556 | for (; aItLFIm.More(); aItLFIm.Next()) { |
5557 | const TopoDS_Shape& aFIm = aItLFIm.Value(); |
5558 | theLFImInt.Append(aFIm); |
5559 | } |
5560 | } |
5561 | } |
5562 | } |
5563 | |
5564 | //======================================================================= |
5565 | //function : ProcessCommonEdges |
5566 | //purpose : Analyzing the common edges between splits of offset faces |
5567 | //======================================================================= |
5568 | void ProcessCommonEdges(const TopTools_ListOfShape& theLEC, |
5569 | const TopTools_IndexedMapOfShape& theInvEdges, |
5570 | const TopTools_IndexedMapOfShape& theValidEdges, |
5571 | const TopTools_IndexedMapOfShape& theME, |
5572 | const TopTools_DataMapOfShapeShape& theETrimEInf, |
5573 | const TopTools_DataMapOfShapeListOfShape& theMEInfETrim, |
5574 | const TopTools_DataMapOfShapeListOfShape& theOEOrigins, |
41aa3c3d |
5575 | const TopTools_MapOfShape& theAllInvs, |
ecf4f17c |
5576 | const Standard_Boolean theForceUse, |
5577 | TopTools_IndexedMapOfShape& theMECV, |
41aa3c3d |
5578 | TopTools_MapOfShape& theMECheckExt, |
ecf4f17c |
5579 | TopTools_DataMapOfShapeListOfShape& theDMEETrim, |
5580 | TopTools_ListOfShape& theLFEi, |
5581 | TopTools_ListOfShape& theLFEj, |
5582 | TopTools_IndexedMapOfShape& theMEToInt) |
5583 | { |
5584 | TopTools_ListOfShape aLEC; |
5585 | // process common edges |
5586 | TopTools_ListIteratorOfListOfShape aItLE(theLEC); |
5587 | for (; aItLE.More(); aItLE.Next()) { |
5588 | const TopoDS_Shape& aEC = aItLE.Value(); |
5589 | // |
5590 | // check first if common edges are valid |
5591 | if (theInvEdges.Contains(aEC) && !theValidEdges.Contains(aEC)) { |
5592 | continue; |
5593 | } |
5594 | // |
5595 | // common edge should have connection to current invalidity |
5596 | if (theME.Contains(aEC)) { |
5597 | aLEC.Append(aEC); |
5598 | continue; |
5599 | } |
5600 | // |
5601 | TopoDS_Iterator aItV(aEC); |
5602 | for (; aItV.More(); aItV.Next()) { |
5603 | const TopoDS_Shape& aVE = aItV.Value(); |
5604 | if (theME.Contains(aVE)) { |
5605 | aLEC.Append(aEC); |
5606 | break; |
5607 | } |
5608 | } |
5609 | } |
5610 | // |
41aa3c3d |
5611 | Standard_Boolean bUseOnlyInf = aLEC.IsEmpty(); |
ecf4f17c |
5612 | if (bUseOnlyInf) { |
41aa3c3d |
5613 | if (theForceUse) { |
5614 | aLEC = theLEC; |
5615 | } |
5616 | else { |
5617 | aItLE.Initialize(theLEC); |
5618 | for (; aItLE.More(); aItLE.Next()) { |
5619 | const TopoDS_Shape& aEC = aItLE.Value(); |
b443d536 |
5620 | // check if all images of the origin of this edge |
5621 | // are not connected to any invalidity |
5622 | const TopoDS_Shape& aEInt = theETrimEInf.Find(aEC); |
5623 | const TopTools_ListOfShape& aLVE = theMEInfETrim.Find(aEInt); |
5624 | TopTools_ListIteratorOfListOfShape aItLVE(aLVE); |
5625 | for (; aItLVE.More(); aItLVE.Next()) { |
5626 | const TopoDS_Shape& aECx = aItLVE.Value(); |
5627 | if (theAllInvs.Contains(aECx) || theInvEdges.Contains(aECx)) { |
41aa3c3d |
5628 | return; |
5629 | } |
b443d536 |
5630 | // |
5631 | TopoDS_Iterator aItV(aECx); |
5632 | for (; aItV.More(); aItV.Next()) { |
5633 | if (theAllInvs.Contains(aItV.Value())) { |
5634 | return; |
5635 | } |
5636 | } |
41aa3c3d |
5637 | } |
41aa3c3d |
5638 | // use only one element |
5639 | if (aLEC.IsEmpty()) { |
5640 | aLEC.Append(aEC); |
5641 | } |
5642 | } |
5643 | } |
ecf4f17c |
5644 | } |
5645 | // |
5646 | aItLE.Initialize(aLEC); |
5647 | for (; aItLE.More(); aItLE.Next()) { |
5648 | const TopoDS_Shape& aEC = aItLE.Value(); |
5649 | // |
5650 | const TopoDS_Shape& aEInt = theETrimEInf.Find(aEC); |
5651 | if (!bUseOnlyInf) { |
5652 | // find the edges of the same original edge |
5653 | // and take their vertices as well |
5654 | const TopTools_ListOfShape& aLVE = theMEInfETrim.Find(aEInt); |
5655 | TopTools_ListIteratorOfListOfShape aItLVE(aLVE); |
5656 | for (; aItLVE.More(); aItLVE.Next()) { |
5657 | const TopoDS_Shape& aECx = aItLVE.Value(); |
5658 | // |
5659 | const TopTools_ListOfShape* pLEOr = theOEOrigins.Seek(aECx); |
5660 | if (!pLEOr || (pLEOr->Extent() == 1)) { |
5661 | TopExp::MapShapes(aECx, TopAbs_VERTEX, theMECV); |
5662 | } |
5663 | } |
5664 | // |
5665 | // bind unlimited edge to its trimmed part in face to update maps of |
5666 | // images and origins in the future |
5667 | TopTools_ListOfShape* pLTAdded = theDMEETrim.ChangeSeek(aEInt); |
5668 | if (!pLTAdded) { |
5669 | pLTAdded = theDMEETrim.Bound(aEInt, TopTools_ListOfShape()); |
5670 | } |
5671 | AppendToList(*pLTAdded, aEC); |
5672 | } |
41aa3c3d |
5673 | else if (!theForceUse) { |
5674 | theMECheckExt.Add(aEInt); |
5675 | } |
ecf4f17c |
5676 | // |
5677 | AppendToList(theLFEi, aEInt); |
5678 | AppendToList(theLFEj, aEInt); |
5679 | theMEToInt.Add(aEInt); |
5680 | } |
5681 | } |
5682 | |
5683 | //======================================================================= |
5684 | //function : UpdateIntersectedFaces |
5685 | //purpose : Updating the already interfered faces |
5686 | //======================================================================= |
5687 | void UpdateIntersectedFaces(const TopoDS_Shape& theFInv, |
5688 | const TopoDS_Shape& theFi, |
5689 | const TopoDS_Shape& theFj, |
5690 | const TopTools_ListOfShape& theLFInv, |
5691 | const TopTools_ListOfShape& theLFImi, |
5692 | const TopTools_ListOfShape& theLFImj, |
5693 | const TopTools_ListOfShape& theLFEi, |
5694 | const TopTools_ListOfShape& theLFEj, |
5695 | TopTools_DataMapOfShapeListOfShape& theEdgesOrigins, |
5696 | TopTools_IndexedMapOfShape& theMEToInt) |
5697 | { |
5698 | // Find common edges in these two lists |
5699 | TopTools_MapOfShape aMEi; |
5700 | TopTools_ListIteratorOfListOfShape aItLE(theLFEi); |
5701 | for (; aItLE.More(); aItLE.Next()) { |
5702 | const TopoDS_Shape& aE = aItLE.Value(); |
5703 | aMEi.Add(aE); |
5704 | } |
5705 | // |
5706 | // find origins |
5707 | TopTools_IndexedMapOfShape aMEToFindOrigins; |
5708 | TopTools_ListOfShape aLEToFindOrigins; |
5709 | if (!theFi.IsSame(theFInv)) { |
5710 | FindCommonParts(theLFImi, theLFInv, aLEToFindOrigins); |
5711 | } |
5712 | if (!theFj.IsSame(theFInv)) { |
5713 | FindCommonParts(theLFImj, theLFInv, aLEToFindOrigins); |
5714 | } |
5715 | // |
5716 | TopTools_ListOfShape aLEOrInit; |
5717 | aItLE.Initialize(aLEToFindOrigins); |
5718 | for (; aItLE.More(); aItLE.Next()) { |
5719 | const TopoDS_Shape& aEC = aItLE.Value(); |
5720 | aMEToFindOrigins.Add(aEC); |
5721 | } |
5722 | // |
5723 | FindOrigins(theLFImi, theLFImj, aMEToFindOrigins, theEdgesOrigins, aLEOrInit); |
5724 | // |
5725 | aItLE.Initialize(theLFEj); |
5726 | for (; aItLE.More(); aItLE.Next()) { |
5727 | const TopoDS_Shape& aE = aItLE.Value(); |
5728 | if (aMEi.Contains(aE)) { |
5729 | theMEToInt.Add(aE); |
5730 | if (aLEOrInit.Extent()) { |
5731 | if (theEdgesOrigins.IsBound(aE)) { |
5732 | TopTools_ListOfShape& aLEOr = theEdgesOrigins.ChangeFind(aE); |
5733 | TopTools_ListIteratorOfListOfShape aItLEOr(aLEOrInit); |
5734 | for (; aItLEOr.More(); aItLEOr.Next()) { |
5735 | const TopoDS_Shape& aEOr = aItLEOr.Value(); |
5736 | AppendToList(aLEOr, aEOr); |
5737 | } |
5738 | } |
5739 | else { |
5740 | theEdgesOrigins.Bind(aE, aLEOrInit); |
5741 | } |
5742 | } |
5743 | } |
5744 | } |
5745 | } |
5746 | |
5747 | //======================================================================= |
5748 | //function : IntersectFaces |
5749 | //purpose : Intersection of the pair of faces |
5750 | //======================================================================= |
5751 | void IntersectFaces(const TopoDS_Shape& theFInv, |
5752 | const TopoDS_Shape& theFi, |
5753 | const TopoDS_Shape& theFj, |
5754 | const TopTools_ListOfShape& theLFInv, |
5755 | const TopTools_ListOfShape& theLFImi, |
5756 | const TopTools_ListOfShape& theLFImj, |
5757 | TopTools_ListOfShape& theLFEi, |
5758 | TopTools_ListOfShape& theLFEj, |
5759 | TopTools_DataMapOfShapeListOfShape& theEdgesOrigins, |
5760 | TopTools_IndexedMapOfShape& theMECV, |
5761 | TopTools_IndexedMapOfShape& theMEToInt) |
5762 | { |
5763 | // intersect faces |
5764 | TopAbs_State aSide = TopAbs_OUT; |
5765 | TopTools_ListOfShape aLInt1, aLInt2; |
5766 | TopoDS_Edge aNullEdge; |
8948e18d |
5767 | TopoDS_Face aNullFace; |
5768 | BRepOffset_Tool::Inter3D(TopoDS::Face(theFi), TopoDS::Face(theFj), aLInt1, aLInt2, aSide, |
5769 | aNullEdge, aNullFace, aNullFace); |
ecf4f17c |
5770 | // |
5771 | if (aLInt1.IsEmpty()) { |
5772 | return; |
5773 | } |
5774 | // |
5775 | // find common vertices for trimming edges |
5776 | TopTools_ListOfShape aLCV; |
5777 | TopTools_ListIteratorOfListOfShape aItLE; |
5778 | FindCommonParts(theLFImi, theLFImj, aLCV, TopAbs_VERTEX); |
5779 | if (aLCV.Extent() > 1) { |
5780 | aItLE.Initialize(aLCV); |
5781 | for (; aItLE.More(); aItLE.Next()) { |
5782 | const TopoDS_Shape& aCV = aItLE.Value(); |
5783 | theMECV.Add(aCV); |
5784 | } |
5785 | } |
5786 | // |
5787 | // find origins |
5788 | TopTools_IndexedMapOfShape aMEToFindOrigins; |
5789 | TopTools_ListOfShape aLEToFindOrigins; |
5790 | if (!theFi.IsSame(theFInv)) { |
5791 | FindCommonParts(theLFImi, theLFInv, aLEToFindOrigins); |
5792 | } |
5793 | if (!theFj.IsSame(theFInv)) { |
5794 | FindCommonParts(theLFImj, theLFInv, aLEToFindOrigins); |
5795 | } |
5796 | TopTools_ListOfShape aLEOrInit; |
5797 | aItLE.Initialize(aLEToFindOrigins); |
5798 | for (; aItLE.More(); aItLE.Next()) { |
5799 | const TopoDS_Shape& aEC = aItLE.Value(); |
5800 | aMEToFindOrigins.Add(aEC); |
5801 | } |
5802 | // |
5803 | FindOrigins(theLFImi, theLFImj, aMEToFindOrigins, theEdgesOrigins, aLEOrInit); |
5804 | // |
5805 | aItLE.Initialize(aLInt1); |
5806 | for (; aItLE.More(); aItLE.Next()) { |
5807 | const TopoDS_Shape& aEInt = aItLE.Value(); |
5808 | theLFEi.Append(aEInt); |
5809 | theLFEj.Append(aEInt); |
5810 | // |
5811 | if (aLEOrInit.Extent()) { |
5812 | theEdgesOrigins.Bind(aEInt, aLEOrInit); |
5813 | } |
5814 | // |
5815 | theMEToInt.Add(aEInt); |
5816 | } |
5817 | } |
5818 | |
5819 | //======================================================================= |
5820 | //function : FindOrigins |
5821 | //purpose : Looking for the origin edges |
5822 | //======================================================================= |
5823 | void FindOrigins(const TopTools_ListOfShape& theLFIm1, |
5824 | const TopTools_ListOfShape& theLFIm2, |
5825 | const TopTools_IndexedMapOfShape& theME, |
5826 | const TopTools_DataMapOfShapeListOfShape& theOrigins, |
5827 | TopTools_ListOfShape& theLEOr) |
5828 | { |
5829 | Standard_Integer i; |
5830 | TopTools_MapOfShape aMFence; |
5831 | TopExp_Explorer aExp; |
5832 | TopTools_ListIteratorOfListOfShape aIt, aItLE; |
5833 | // |
5834 | for (i = 0; i < 2; ++i) { |
5835 | const TopTools_ListOfShape& aLF = !i ? theLFIm1 : theLFIm2; |
5836 | aIt.Initialize(aLF); |
5837 | for (; aIt.More(); aIt.Next()) { |
5838 | const TopoDS_Shape& aF = aIt.Value(); |
5839 | // |
5840 | aExp.Init(aF, TopAbs_EDGE); |
5841 | for (; aExp.More(); aExp.Next()) { |
5842 | const TopoDS_Shape& aE = aExp.Current(); |
5843 | // |
5844 | if (theME.Contains(aE) && theOrigins.IsBound(aE)) { |
5845 | const TopTools_ListOfShape& aLEOr = theOrigins.Find(aE); |
5846 | aItLE.Initialize(aLEOr); |
5847 | for (; aItLE.More(); aItLE.Next()) { |
5848 | const TopoDS_Shape& aEOr = aItLE.Value(); |
5849 | // |
5850 | if (aMFence.Add(aEOr) && (aEOr.ShapeType() == TopAbs_EDGE)) { |
5851 | theLEOr.Append(aEOr); |
5852 | } |
5853 | } // for (; aItLE.More(); aItLE.Next()) { |
5854 | } // if (theME.Contains(aE) && theOrigins.IsBound(aE)) { |
5855 | } // aExp.Init(aF, TopAbs_EDGE); |
5856 | } // for (; aIt.More(); aIt.Next()) { |
5857 | } // for (i = 0; i < 2; ++i) { |
5858 | } |
5859 | |
5860 | //======================================================================= |
5861 | //function : IntersectAndTrimEdges |
5862 | //purpose : Intersection of the new intersection edges among themselves |
5863 | //======================================================================= |
5864 | void IntersectAndTrimEdges(const TopTools_IndexedDataMapOfShapeListOfShape& theFToRebuild, |
5865 | const TopTools_IndexedMapOfShape& theMFInt, |
5866 | const TopTools_IndexedMapOfShape& theMEInt, |
5867 | const TopTools_DataMapOfShapeListOfShape& theDMEETrim, |
5868 | const TopTools_IndexedMapOfShape& theMSInv, |
5869 | const TopTools_IndexedMapOfShape& theMVE, |
5870 | const TopTools_MapOfShape& theVertsToAvoid, |
5871 | const TopTools_MapOfShape& theNewVertsToAvoid, |
41aa3c3d |
5872 | const TopTools_MapOfShape& theMECheckExt, |
ecf4f17c |
5873 | TopTools_MapOfShape& theMVBounds, |
5874 | TopTools_DataMapOfShapeListOfShape& theEImages) |
5875 | { |
5876 | Standard_Integer i, aNb = theMEInt.Extent(); |
5877 | if (!aNb) { |
5878 | return; |
5879 | } |
5880 | // |
1155d05a |
5881 | TopTools_ListOfShape aLArgs; |
ecf4f17c |
5882 | TopTools_MapOfShape aMFence; |
5883 | TopTools_ListIteratorOfListOfShape aIt, aIt1; |
5884 | TopExp_Explorer aExp; |
5885 | // |
5886 | // get vertices from the splits of intersected faces. |
5887 | // vertices are taken from the edges close to invalidity |
5888 | // |
5889 | TopTools_IndexedDataMapOfShapeListOfShape aDMVE; |
5890 | aNb = theMFInt.Extent(); |
5891 | for (i = 1; i <= aNb; ++i) { |
5892 | const TopoDS_Shape& aF = theMFInt(i); |
5893 | const TopTools_ListOfShape& aLE = theFToRebuild.FindFromKey(aF); |
5894 | // |
5895 | aIt.Initialize(aLE); |
5896 | for (; aIt.More(); aIt.Next()) { |
5897 | const TopoDS_Shape& aE = aIt.Value(); |
5898 | TopExp::MapShapesAndAncestors(aE, TopAbs_VERTEX, TopAbs_EDGE, aDMVE); |
5899 | // |
5900 | aExp.Init(aE, TopAbs_VERTEX); |
5901 | for (; aExp.More(); aExp.Next()) { |
5902 | const TopoDS_Shape& aV1 = aExp.Current(); |
5903 | if (!theVertsToAvoid.Contains(aV1) && theMVE.Contains(aV1) && aMFence.Add(aV1)) { |
5904 | aLArgs.Append(aV1); |
5905 | } |
5906 | } |
5907 | } |
5908 | } |
5909 | // |
5910 | aNb = theMSInv.Extent(); |
5911 | for (i = 1; i <= aNb; ++i) { |
5912 | const TopoDS_Shape& aV = theMSInv(i); |
5913 | if (aV.ShapeType() != TopAbs_VERTEX) { |
5914 | continue; |
5915 | } |
5916 | // |
5917 | TopTools_ListOfShape *pLVE = aDMVE.ChangeSeek(aV); |
5918 | if (!pLVE) { |
5919 | continue; |
5920 | } |
5921 | // |
5922 | aIt.Initialize(*pLVE); |
5923 | for (; aIt.More(); aIt.Next()) { |
5924 | const TopoDS_Shape& aE = aIt.Value(); |
5925 | // |
5926 | aExp.Init(aE, TopAbs_VERTEX); |
5927 | for (; aExp.More(); aExp.Next()) { |
5928 | const TopoDS_Shape& aV1 = aExp.Current(); |
5929 | if (!theVertsToAvoid.Contains(aV1) && aMFence.Add(aV1)) { |
5930 | aLArgs.Append(aV1); |
5931 | } |
5932 | } |
5933 | } |
5934 | } |
5935 | // |
5936 | // bounding vertices of untrimmed edges |
5937 | TopTools_ListOfShape aLVBounds; |
5938 | // new intersection edges |
5939 | TopTools_ListOfShape aLENew; |
5940 | // get edges to intersect |
5941 | TopTools_ListOfShape aLEInt; |
dcba2e5c |
5942 | // Common intersection edges. Should be intersected separately |
41aa3c3d |
5943 | TopTools_ListOfShape aLCE; |
5944 | // |
ecf4f17c |
5945 | aNb = theMEInt.Extent(); |
5946 | for (i = 1; i <= aNb; ++i) { |
5947 | const TopoDS_Shape& aE = theMEInt(i); |
41aa3c3d |
5948 | if (theMECheckExt.Contains(aE)) { |
5949 | // avoid trimming of the intersection edges by additional common edges |
5950 | aLCE.Append(aE); |
ecf4f17c |
5951 | continue; |
5952 | } |
5953 | // |
5954 | if (!theDMEETrim.IsBound(aE)) { |
5955 | aLENew.Append(aE); |
5956 | } |
5957 | // |
5958 | aLEInt.Append(aE); |
5959 | aLArgs.Append(aE); |
5960 | // |
5961 | aExp.Init(aE, TopAbs_VERTEX); |
5962 | for (; aExp.More(); aExp.Next()) { |
5963 | const TopoDS_Shape& aV = aExp.Current(); |
5964 | aLVBounds.Append(aV); |
5965 | } |
5966 | } |
5967 | // |
5968 | // Intersect Edges |
5969 | BOPAlgo_Builder aGF; |
5970 | aGF.SetArguments(aLArgs); |
5971 | aGF.Perform(); |
33ba8565 |
5972 | if (aGF.HasErrors()) { |
ecf4f17c |
5973 | return; |
5974 | } |
5975 | // |
5976 | // update vertices to avoid with SD vertices |
5977 | aIt.Initialize(aLVBounds); |
5978 | for (; aIt.More(); aIt.Next()) { |
5979 | const TopoDS_Shape& aV = aIt.Value(); |
5980 | const TopTools_ListOfShape& aLVIm = aGF.Modified(aV); |
5981 | if (aLVIm.IsEmpty()) { |
5982 | theMVBounds.Add(aV); |
5983 | } |
5984 | else { |
5985 | const TopoDS_Shape& aVIm = aLVIm.First(); |
5986 | theMVBounds.Add(aVIm); |
5987 | } |
5988 | } |
5989 | // |
5990 | // find invalid splits of edges |
5991 | TopTools_MapOfShape aMEInv; |
5992 | GetInvalidEdges(theNewVertsToAvoid, theMVBounds, aGF, aMEInv); |
5993 | // |
41aa3c3d |
5994 | BRep_Builder aBB; |
5995 | // get valid splits to intersect with the commons |
5996 | TopoDS_Compound aCEIm; |
5997 | aBB.MakeCompound(aCEIm); |
5998 | // |
ecf4f17c |
5999 | // remove the splits containing vertices from invalid edges |
6000 | aIt.Initialize(aLEInt); |
6001 | for (; aIt.More(); aIt.Next()) { |
6002 | const TopoDS_Shape& aE = aIt.Value(); |
6003 | // |
6004 | TopTools_ListOfShape aLEIm = aGF.Modified(aE); |
6005 | if (aLEIm.IsEmpty()) { |
6006 | continue; |
6007 | } |
6008 | // |
6009 | aIt1.Initialize(aLEIm); |
6010 | for (; aIt1.More(); ) { |
6011 | const TopoDS_Shape& aEIm = aIt1.Value(); |
6012 | // |
6013 | if (aMEInv.Contains(aEIm)) { |
6014 | aLEIm.Remove(aIt1); |
6015 | } |
6016 | else { |
41aa3c3d |
6017 | aBB.Add(aCEIm, aEIm); |
ecf4f17c |
6018 | aIt1.Next(); |
6019 | } |
6020 | } |
6021 | // |
6022 | if (aLEIm.Extent()) { |
41aa3c3d |
6023 | TopTools_ListOfShape* pLEIm = theEImages.ChangeSeek(aE); |
6024 | if (!pLEIm) { |
6025 | pLEIm = theEImages.Bound(aE, TopTools_ListOfShape()); |
ecf4f17c |
6026 | } |
41aa3c3d |
6027 | pLEIm->Append(aLEIm); |
6028 | } |
6029 | } |
6030 | // |
6031 | if (!aLCE.Extent()) { |
6032 | return; |
6033 | } |
6034 | // |
6035 | // trim common edges by other intersection edges |
6036 | BOPAlgo_Builder aGFCE; |
6037 | aGFCE.SetArguments(aLCE); |
6038 | aGFCE.AddArgument(aCEIm); |
6039 | aGFCE.Perform(); |
6040 | // |
33ba8565 |
6041 | if (aGFCE.HasErrors()) { |
41aa3c3d |
6042 | return; |
6043 | } |
6044 | // |
6045 | const BOPDS_PDS& pDS = aGFCE.PDS(); |
6046 | TopTools_ListIteratorOfListOfShape aItLCE(aLCE); |
6047 | for (; aItLCE.More(); aItLCE.Next()) { |
6048 | const TopoDS_Shape& aE = aItLCE.Value(); |
6049 | TopTools_ListOfShape aLEIm = aGFCE.Modified(aE); |
6050 | if (aLEIm.IsEmpty()) { |
6051 | continue; |
6052 | } |
6053 | // |
6054 | // check if it's not coincide with some intersection edge |
6055 | BOPDS_ListIteratorOfListOfPaveBlock aItLPB(pDS->PaveBlocks(pDS->Index(aE))); |
6056 | for (; aItLPB.More(); aItLPB.Next()) { |
6057 | if (pDS->IsCommonBlock(aItLPB.Value())) { |
6058 | // find with what it is a common |
6059 | const BOPDS_ListOfPaveBlock& aLPBC = pDS->CommonBlock(aItLPB.Value())->PaveBlocks(); |
6060 | BOPDS_ListIteratorOfListOfPaveBlock aItLPBC(aLPBC); |
6061 | for (; aItLPBC.More(); aItLPBC.Next()) { |
6062 | const TopoDS_Shape& aEC = pDS->Shape(aItLPBC.Value()->OriginalEdge()); |
6063 | if (!theMECheckExt.Contains(aEC)) { |
6064 | break; |
6065 | } |
6066 | } |
6067 | if (aItLPBC.More()) { |
6068 | break; |
6069 | } |
ecf4f17c |
6070 | } |
6071 | } |
41aa3c3d |
6072 | if (aItLPB.More()) { |
6073 | // avoid creation of unnecessary splits from commons which |
6074 | // coincide with intersection edges |
6075 | continue; |
6076 | } |
6077 | // |
6078 | // save the images |
6079 | TopTools_ListOfShape* pLEIm = theEImages.ChangeSeek(aE); |
6080 | if (!pLEIm) { |
6081 | pLEIm = theEImages.Bound(aE, TopTools_ListOfShape()); |
6082 | } |
6083 | pLEIm->Append(aLEIm); |
6084 | // |
6085 | // save bounding vertices |
6086 | for (TopoDS_Iterator aItV(aE); aItV.More(); aItV.Next()) { |
6087 | const TopoDS_Shape& aV = aItV.Value(); |
6088 | const TopTools_ListOfShape& aLVIm = aGFCE.Modified(aV); |
6089 | theMVBounds.Add(aLVIm.IsEmpty() ? aV : aLVIm.First()); |
6090 | } |
ecf4f17c |
6091 | } |
6092 | } |
6093 | |
6094 | //======================================================================= |
6095 | //function : GetInvalidEdges |
6096 | //purpose : Looking for the invalid edges by intersecting with invalid vertices |
6097 | //======================================================================= |
6098 | void GetInvalidEdges(const TopTools_MapOfShape& theVertsToAvoid, |
6099 | const TopTools_MapOfShape& theMVBounds, |
6100 | BOPAlgo_Builder& theGF, |
6101 | TopTools_MapOfShape& theMEInv) |
6102 | { |
6103 | if (theVertsToAvoid.IsEmpty()) { |
6104 | return; |
6105 | } |
6106 | // |
6107 | TopTools_ListIteratorOfListOfShape aIt, aIt1; |
6108 | // get vertices created with intersection edges |
6109 | const TopoDS_Shape& aRes = theGF.Shape(); |
6110 | TopTools_IndexedDataMapOfShapeListOfShape aDMVE; |
6111 | TopExp::MapShapesAndAncestors(aRes, TopAbs_VERTEX, TopAbs_EDGE, aDMVE); |
6112 | // |
6113 | const BOPDS_PDS& pDS = theGF.PDS(); |
6114 | // |
6115 | // find invalid splits of edges |
6116 | // check if the vertex is invalid: |
6117 | // a. it may be the vertex SD with the vertices to avoid |
6118 | // b. or it may be the vertex which is created by the intersection |
6119 | // of only existing edges, i.e. no new intersection edges goes |
6120 | // through this vertex |
6121 | // |
6122 | TopTools_MapOfShape aMVInv; |
6123 | Standard_Integer i, aNb = aDMVE.Extent(); |
6124 | for (i = 1; i <= aNb; ++i) { |
6125 | const TopoDS_Vertex& aV = TopoDS::Vertex(aDMVE.FindKey(i)); |
6126 | if (theMVBounds.Contains(aV)) { |
6127 | continue; |
6128 | } |
6129 | // |
6130 | Standard_Integer nV = pDS->Index(aV); |
6131 | if ((nV >= 0) && !pDS->IsNewShape(nV)) { |
6132 | continue; |
6133 | } |
6134 | // |
6135 | TopTools_MapIteratorOfMapOfShape aItM(theVertsToAvoid); |
6136 | for (; aItM.More(); aItM.Next()) { |
6137 | const TopoDS_Vertex& aVInv = *(TopoDS_Vertex*)&aItM.Value(); |
6138 | Standard_Integer iFlag = BOPTools_AlgoTools::ComputeVV(aV, aVInv); |
6139 | if (!iFlag) { |
6140 | aMVInv.Add(aV); |
6141 | break; |
6142 | } |
6143 | } |
6144 | // |
6145 | if (aItM.More()) { |
6146 | const TopTools_ListOfShape& aLVE = aDMVE.FindFromKey(aV); |
6147 | aIt.Initialize(aLVE); |
6148 | for (; aIt.More(); aIt.Next()) { |
6149 | const TopoDS_Shape& aE = aIt.Value(); |
6150 | theMEInv.Add(aE); |
6151 | } |
6152 | } |
6153 | } |
6154 | } |
6155 | |
6156 | //======================================================================= |
6157 | //function : UpdateValidEdges |
6158 | //purpose : Making the new splits and updating the maps |
6159 | //======================================================================= |
41aa3c3d |
6160 | void UpdateValidEdges(const TopTools_IndexedDataMapOfShapeListOfShape& theFImages, |
ecf4f17c |
6161 | const TopTools_IndexedDataMapOfShapeListOfShape& theFLE, |
dcba2e5c |
6162 | const TopTools_IndexedDataMapOfShapeListOfShape& theOENEdges, |
ecf4f17c |
6163 | const TopTools_MapOfShape& theMVBounds, |
6164 | const TopoDS_Shape& theSolids, |
6165 | const TopTools_IndexedMapOfShape& theInvEdges, |
6166 | const TopTools_MapOfShape& theInvertedEdges, |
a8232603 |
6167 | const TopTools_MapOfShape& theMEInvOnArt, |
41aa3c3d |
6168 | TopTools_MapOfShape& theMECheckExt, |
ecf4f17c |
6169 | TopTools_IndexedMapOfShape& theEdgesToAvoid, |
6170 | TopTools_DataMapOfShapeListOfShape& theEdgesOrigins, |
6171 | TopTools_DataMapOfShapeListOfShape& theOEImages, |
6172 | TopTools_DataMapOfShapeListOfShape& theOEOrigins, |
6173 | TopTools_MapOfShape& theVertsToAvoid, |
6174 | TopTools_DataMapOfShapeShape& theETrimEInf, |
6175 | TopTools_DataMapOfShapeListOfShape& theEImages, |
6176 | TopTools_DataMapOfShapeListOfShape& theEETrim, |
6177 | TopTools_MapOfShape& theModifiedEdges, |
6178 | Handle(BRepAlgo_AsDes)& theAsDes) |
6179 | { |
6180 | // update images and origins of edges, plus update AsDes |
6181 | // |
6182 | // new edges |
6183 | TopTools_ListOfShape aLE; |
6184 | // back connection from edges to faces |
6185 | TopTools_DataMapOfShapeListOfShape aMELF; |
6186 | // |
b443d536 |
6187 | TopTools_MapOfShape aMETmp; |
ecf4f17c |
6188 | Standard_Integer i, aNb = theFLE.Extent(); |
6189 | for (i = 1; i <= aNb; ++i) { |
6190 | const TopoDS_Face& aF = TopoDS::Face(theFLE.FindKey(i)); |
6191 | // |
6192 | const TopTools_ListOfShape& aLEInt = theFLE(i); |
6193 | TopTools_ListIteratorOfListOfShape aItLE(aLEInt); |
6194 | for (; aItLE.More(); aItLE.Next()) { |
6195 | const TopoDS_Shape& aE = aItLE.Value(); |
b443d536 |
6196 | if ((theMECheckExt.Contains(aE) || aMETmp.Contains(aE)) && !theEImages.IsBound(aE)) { |
6197 | theMECheckExt.Remove(aE); |
6198 | aMETmp.Add(aE); |
6199 | continue; |
6200 | } |
ecf4f17c |
6201 | TopTools_ListOfShape* pLF = aMELF.ChangeSeek(aE); |
6202 | if (!pLF) { |
6203 | pLF = aMELF.Bound(aE, TopTools_ListOfShape()); |
6204 | aLE.Append(aE); |
6205 | } |
6206 | pLF->Append(aF); |
6207 | } |
6208 | } |
6209 | // |
6210 | if (aLE.IsEmpty()) { |
6211 | return; |
6212 | } |
6213 | // |
6214 | // bounding edges, that are going to be replaced |
6215 | TopTools_MapOfShape aMEB; |
6216 | // |
6217 | // new intersection edges |
ecf4f17c |
6218 | TopTools_MapOfShape aMENew; |
6219 | // map of old vertices |
6220 | TopTools_MapOfShape aMVOld; |
6221 | // back connection to untrimmed edges |
6222 | TopTools_DataMapOfShapeListOfShape aDMEOr; |
6223 | // |
6224 | // trim the new intersection edges |
dcba2e5c |
6225 | TrimNewIntersectionEdges(aLE, theEETrim, theMVBounds, theMECheckExt, |
6226 | theEImages, aMEB, aMVOld, aMENew, aDMEOr, aMELF); |
ecf4f17c |
6227 | // |
dcba2e5c |
6228 | if (theEImages.IsEmpty()) |
6229 | { |
6230 | // No new splits is preserved |
6231 | // update intersection edges and exit |
ecf4f17c |
6232 | UpdateNewIntersectionEdges(aLE, aMELF, theEImages, theInvEdges, theInvertedEdges, theEdgesOrigins, |
6233 | theOEImages, theOEOrigins, theETrimEInf, theEETrim, theModifiedEdges, theAsDes); |
6234 | return; |
6235 | } |
dcba2e5c |
6236 | |
6237 | BRep_Builder aBB; |
6238 | |
6239 | // Make connexity blocks of the invalid edges |
6240 | // and treat each block separately |
6241 | |
6242 | // Compound of all invalid edges to make the blocks |
6243 | TopoDS_Compound aCEAll; |
6244 | aBB.MakeCompound(aCEAll); |
6245 | |
6246 | Standard_Integer aNbE = theOENEdges.Extent(); |
6247 | for (i = 1; i <= aNbE; ++i) |
6248 | aBB.Add(aCEAll, theOENEdges.FindKey(i)); |
6249 | |
6250 | // Separate the edges into blocks |
6251 | TopTools_ListOfShape aLBlocks; |
6252 | BOPTools_AlgoTools::MakeConnexityBlocks(aCEAll, TopAbs_VERTEX, TopAbs_EDGE, aLBlocks); |
6253 | |
6254 | // Perform intersection of the new splits for each block |
6255 | |
6256 | // Intersected splits |
6257 | TopTools_IndexedDataMapOfShapeListOfShape aMBlocksSp; |
6258 | |
6259 | TopTools_ListIteratorOfListOfShape aItLB(aLBlocks); |
6260 | for (; aItLB.More(); aItLB.Next()) |
6261 | { |
6262 | const TopoDS_Shape& aBlock = aItLB.Value(); |
6263 | |
6264 | // Get the list of new edges for the block |
6265 | TopTools_ListOfShape aBlockLENew; |
6266 | { |
6267 | // Fence map |
6268 | TopTools_MapOfShape aMEFence; |
6269 | TopExp_Explorer anExpE(aBlock, TopAbs_EDGE); |
6270 | for (; anExpE.More(); anExpE.Next()) |
6271 | { |
6272 | const TopoDS_Shape& aE = anExpE.Current(); |
6273 | const TopTools_ListOfShape& aLEInt = theOENEdges.FindFromKey(aE); |
6274 | TopTools_ListIteratorOfListOfShape aItLEInt(aLEInt); |
6275 | for (; aItLEInt.More(); aItLEInt.Next()) |
6276 | { |
6277 | if (aMEFence.Add(aItLEInt.Value())) |
6278 | aBlockLENew.Append(aItLEInt.Value()); |
6279 | } |
6280 | } |
6281 | } |
6282 | |
6283 | if (aBlockLENew.IsEmpty()) |
6284 | continue; |
6285 | |
6286 | // Get the splits of new edges to intersect |
1155d05a |
6287 | TopTools_ListOfShape aLSplits; |
dcba2e5c |
6288 | |
6289 | TopTools_ListIteratorOfListOfShape aItLE(aBlockLENew); |
6290 | for (; aItLE.More(); aItLE.Next()) |
6291 | { |
ecf4f17c |
6292 | const TopoDS_Shape& aE = aItLE.Value(); |
ecf4f17c |
6293 | TopTools_ListOfShape* pLEIm = theEImages.ChangeSeek(aE); |
dcba2e5c |
6294 | if (!pLEIm || pLEIm->IsEmpty()) |
ecf4f17c |
6295 | continue; |
dcba2e5c |
6296 | |
ecf4f17c |
6297 | TopTools_ListIteratorOfListOfShape aItLEIm(*pLEIm); |
dcba2e5c |
6298 | for (; aItLEIm.More(); aItLEIm.Next()) |
6299 | aLSplits.Append(aItLEIm.Value()); |
6300 | } |
6301 | |
6302 | if (aLSplits.IsEmpty()) |
6303 | continue; |
6304 | |
6305 | TopoDS_Shape aCE; |
6306 | if (aLSplits.Extent() > 1) |
6307 | // Intersect the new splits among themselves to avoid self-intersections |
6308 | IntersectEdges(aLSplits, aBlockLENew, theMVBounds, theVertsToAvoid, aMENew, theMECheckExt, |
6309 | theEImages, theModifiedEdges, aDMEOr, aMELF, aCE); |
6310 | else |
6311 | aCE = aLSplits.First(); |
6312 | |
6313 | aMBlocksSp.Add(aCE, aBlockLENew); |
6314 | } |
6315 | |
6316 | // Perform filtering of the edges in two steps: |
6317 | // - Check each block separately using localized bounds |
6318 | // taken only from the splits of faces of the current block; |
6319 | // - Intersect all splits together and filter the splits by all bounds. |
6320 | |
6321 | // FIRST STAGE - separate treatment of the blocks |
6322 | |
6323 | // Valid splits to be preserved on the first stage |
6324 | TopTools_MapOfShape aMEVal; |
6325 | |
6326 | // Blocks of valid edges on the first stage |
1155d05a |
6327 | TopTools_ListOfShape aLValBlocks; |
dcba2e5c |
6328 | |
6329 | // Context for caching the classification tools |
6330 | Handle(IntTools_Context) aCtx = new IntTools_Context; |
6331 | |
6332 | Standard_Integer aNbB = aMBlocksSp.Extent(); |
6333 | for (i = 1; i <= aNbB; ++i) |
6334 | { |
6335 | const TopoDS_Shape& aCE = aMBlocksSp.FindKey(i); |
6336 | const TopTools_ListOfShape& aBlockLENew = aMBlocksSp(i); |
6337 | |
6338 | // Get all participating faces to get the bounds |
6339 | TopTools_ListOfShape aLFaces; |
6340 | TopTools_ListIteratorOfListOfShape aItLE(aBlockLENew); |
6341 | for (; aItLE.More(); aItLE.Next()) |
6342 | { |
6343 | const TopTools_ListOfShape *pLF = aMELF.Seek(aItLE.Value()); |
6344 | if (!pLF) |
6345 | continue; |
6346 | TopTools_ListIteratorOfListOfShape aItLF(*pLF); |
6347 | for (; aItLF.More(); aItLF.Next()) |
6348 | AppendToList(aLFaces, aItLF.Value()); |
6349 | } |
6350 | |
6351 | // Localized bounds of the splits of the offset faces |
6352 | // to filter the new splits of the current block |
6353 | TopoDS_Shape aFilterBounds; |
6354 | GetBounds(aLFaces, theFImages, aMEB, aFilterBounds); |
6355 | |
6356 | // Filter the splits by bounds |
6357 | TopTools_MapOfShape aMEInvLoc; |
6358 | GetInvalidEdgesByBounds(aCE, aFilterBounds, theFImages, theSolids, |
6359 | theInvEdges, aMVOld, aMENew, aDMEOr, aMELF, theEImages, |
6360 | theMECheckExt, theMEInvOnArt, aCtx, theVertsToAvoid, aMEInvLoc); |
6361 | |
6362 | // Keep only valid edges of the block |
6363 | TopoDS_Compound aCEVal; |
6364 | aBB.MakeCompound(aCEVal); |
6365 | |
6366 | Standard_Boolean bKept = Standard_False; |
6367 | |
6368 | TopExp_Explorer anExpE(aCE, TopAbs_EDGE); |
6369 | for (; anExpE.More(); anExpE.Next()) |
6370 | { |
6371 | const TopoDS_Shape& aESp = anExpE.Current(); |
6372 | if (!aMEInvLoc.Contains(aESp) && aMEVal.Add(aESp)) |
6373 | { |
6374 | aBB.Add(aCEVal, aESp); |
6375 | bKept = Standard_True; |
ecf4f17c |
6376 | } |
6377 | } |
dcba2e5c |
6378 | |
6379 | if (bKept) |
6380 | aLValBlocks.Append(aCEVal); |
ecf4f17c |
6381 | } |
dcba2e5c |
6382 | |
6383 | // Filter the images of edges after the first filtering stage |
6384 | TopoDS_Shape aSplits1; |
6385 | FilterSplits(aLE, aMEVal, Standard_False, theEImages, aSplits1); |
6386 | |
6387 | if (aLValBlocks.IsEmpty()) |
6388 | { |
6389 | // update intersection edges |
6390 | UpdateNewIntersectionEdges(aLE, aMELF, theEImages, theInvEdges, theInvertedEdges, theEdgesOrigins, |
6391 | theOEImages, theOEOrigins, theETrimEInf, theEETrim, theModifiedEdges, theAsDes); |
6392 | return; |
ecf4f17c |
6393 | } |
dcba2e5c |
6394 | |
6395 | // SECOND STAGE - Filter the remaining splits together |
6396 | |
6397 | // Add for intersection already removed new edges using them |
6398 | // as markers for other invalid edges |
6399 | aNbB = aMBlocksSp.Extent(); |
6400 | for (i = 1; i <= aNbB; ++i) |
6401 | { |
6402 | const TopoDS_Shape& aCE = aMBlocksSp.FindKey(i); |
6403 | for (TopExp_Explorer anExp(aCE, TopAbs_EDGE); anExp.More(); anExp.Next()) |
6404 | { |
6405 | const TopoDS_Shape& aEIm = anExp.Current(); |
6406 | if (aMENew.Contains(aEIm) && !aMEVal.Contains(aEIm)) |
6407 | aLValBlocks.Append(aEIm); |
6408 | } |
6409 | } |
6410 | |
6411 | if (aLValBlocks.Extent() > 1) |
6412 | // intersect the new splits among themselves to avoid self-intersections |
6413 | IntersectEdges(aLValBlocks, aLE, theMVBounds, theVertsToAvoid, aMENew, theMECheckExt, |
6414 | theEImages, theModifiedEdges, aDMEOr, aMELF, aSplits1); |
6415 | else |
6416 | aSplits1 = aLValBlocks.First(); |
6417 | |
6418 | // Get all faces to get the bounds from their splits |
6419 | TopTools_ListOfShape aLFaces; |
6420 | for (i = 1; i <= theFImages.Extent(); ++i) |
6421 | aLFaces.Append(theFImages.FindKey(i)); |
6422 | |
6423 | // Bounds of the splits of the offset faces to filter the new splits |
6424 | TopoDS_Shape aFilterBounds; |
6425 | GetBounds(aLFaces, theFImages, aMEB, aFilterBounds); |
6426 | |
6427 | // Filter the splits by intersection with bounds |
6428 | TopTools_MapOfShape aMEInv; |
6429 | GetInvalidEdgesByBounds(aSplits1, aFilterBounds, theFImages, theSolids, |
6430 | theInvEdges, aMVOld, aMENew, aDMEOr, aMELF, theEImages, |
6431 | theMECheckExt, theMEInvOnArt, aCtx, theVertsToAvoid, aMEInv); |
6432 | |
6433 | // Filter the images of edges after the second filtering stage |
6434 | // and combine all valid edges into a single compound |
6435 | TopoDS_Shape aSplits; |
6436 | FilterSplits(aLE, aMEInv, Standard_True, theEImages, aSplits); |
6437 | |
ecf4f17c |
6438 | // get bounds to update |
6439 | // we need to update the edges of all the affected faces |
6440 | TopTools_ListOfShape aLF; |
6441 | // prepare the vertices from new splits of edges |
6442 | TopTools_IndexedMapOfShape aMVSp; |
6443 | TopExp::MapShapes(aSplits, TopAbs_VERTEX, aMVSp); |
6444 | // |
6445 | Standard_Integer aNbF = theFImages.Extent(); |
6446 | for (i = 1; i <= aNbF; ++i) { |
6447 | const TopoDS_Shape& aF = theFImages.FindKey(i); |
6448 | if (theFLE.Contains(aF)) { |
6449 | aLF.Append(aF); |
6450 | continue; |
6451 | } |
6452 | // |
6453 | // check the splits of faces to have vertices from splits |
6454 | const TopTools_ListOfShape& aLFIm = theFImages(i); |
6455 | TopTools_ListIteratorOfListOfShape aItLFIm(aLFIm); |
6456 | for (; aItLFIm.More(); aItLFIm.Next()) { |
6457 | const TopoDS_Shape& aFIm = aItLFIm.Value(); |
6458 | // |
6459 | TopExp_Explorer aExpV(aFIm, TopAbs_VERTEX); |
6460 | for (; aExpV.More(); aExpV.Next()) { |
6461 | const TopoDS_Shape& aV = aExpV.Current(); |
6462 | if (aMVSp.Contains(aV)) { |
6463 | break; |
6464 | } |
6465 | } |
6466 | // |
6467 | if (aExpV.More()) { |
6468 | break; |
6469 | } |
6470 | } |
6471 | // |
6472 | if (aItLFIm.More()) { |
6473 | aLF.Append(aF); |
6474 | } |
6475 | } |
6476 | // |
6477 | // get bounds from splits of faces of aLF |
6478 | TopoDS_Shape aBounds; |
6479 | TopTools_ListOfShape aLAValid, aLABounds; |
6480 | GetBoundsToUpdate(aLF, theOEImages, theOEOrigins, aMEB, |
6481 | aLABounds, aLAValid, aBounds, theAsDes); |
6482 | // |
81a55a69 |
6483 | // Intersect valid splits with bounds and update both |
ecf4f17c |
6484 | BOPAlgo_Builder aGF; |
ecf4f17c |
6485 | aGF.AddArgument(aBounds); |
edfa30de |
6486 | aGF.AddArgument(aSplits); |
ecf4f17c |
6487 | aGF.Perform(); |
6488 | // |
6489 | // update splits |
6490 | UpdateImages(aLE, theEImages, aGF, theModifiedEdges); |
6491 | // |
6492 | // update new intersection edges |
6493 | UpdateNewIntersectionEdges(aLE, aMELF, theEImages, theInvEdges, theInvertedEdges, theEdgesOrigins, |
6494 | theOEImages, theOEOrigins, theETrimEInf, theEETrim, theModifiedEdges, theAsDes); |
6495 | // |
6496 | // update bounds |
6497 | UpdateImages(aLAValid, theOEImages, aGF, theModifiedEdges); |
6498 | UpdateOrigins(aLABounds, theOEOrigins, aGF); |
6499 | UpdateOrigins(aLABounds, theEdgesOrigins, aGF); |
6500 | UpdateIntersectedEdges(aLABounds, theETrimEInf, aGF); |
6501 | // |
edfa30de |
6502 | // update the EdgesToAvoid with the splits |
ecf4f17c |
6503 | TopTools_IndexedMapOfShape aNewEdges; |
6504 | const TopTools_ListOfShape* pSplitsIm = aGF.Images().Seek(aSplits); |
6505 | if (pSplitsIm) { |
6506 | TopTools_ListIteratorOfListOfShape aItSpIm(*pSplitsIm); |
6507 | for (; aItSpIm.More(); aItSpIm.Next()) { |
6508 | TopExp::MapShapes(aItSpIm.Value(), TopAbs_EDGE, aNewEdges); |
6509 | } |
6510 | } |
6511 | // |
81a55a69 |
6512 | // Rebuild the map of edges to avoid, using the intersection results |
6513 | TopTools_IndexedMapOfShape aMEAvoid; |
6514 | // GF's data structure |
6515 | const BOPDS_PDS& pDS = aGF.PDS(); |
6516 | |
dcba2e5c |
6517 | aNbE = theEdgesToAvoid.Extent(); |
81a55a69 |
6518 | for (i = 1; i <= aNbE; ++i) |
6519 | { |
ecf4f17c |
6520 | const TopoDS_Shape& aE = theEdgesToAvoid(i); |
6521 | const TopTools_ListOfShape& aLEIm = aGF.Modified(aE); |
81a55a69 |
6522 | |
6523 | // Only untouched and fully coinciding edges should be kept in the avoid map |
6524 | Standard_Boolean bKeep = aLEIm.IsEmpty(); |
6525 | if (aLEIm.Extent() == 1 && aE.IsSame(aLEIm.First())) |
6526 | { |
6527 | const BOPDS_ListOfPaveBlock& aLPB = pDS->PaveBlocks(pDS->Index(aE)); |
6528 | if (aLPB.Extent() == 1) |
6529 | { |
6530 | const Handle(BOPDS_PaveBlock)& aPB = aLPB.First(); |
6531 | const Handle(BOPDS_CommonBlock)& aCB = pDS->CommonBlock(aPB); |
6532 | if (!aCB.IsNull()) |
6533 | { |
6534 | const BOPDS_ListOfPaveBlock& aLPBCB = aCB->PaveBlocks(); |
6535 | BOPDS_ListIteratorOfListOfPaveBlock aItLPB(aLPBCB); |
6536 | for (; aItLPB.More(); aItLPB.Next()) |
6537 | { |
6538 | if (pDS->PaveBlocks(aItLPB.Value()->OriginalEdge()).Extent() > 1) |
6539 | break; |
6540 | } |
6541 | bKeep = !aItLPB.More(); |
6542 | } |
6543 | } |
6544 | } |
6545 | |
6546 | if (bKeep) |
6547 | { |
6548 | // keep the original edge |
6549 | aMEAvoid.Add(aE); |
6550 | continue; |
6551 | } |
6552 | |
ecf4f17c |
6553 | TopTools_ListIteratorOfListOfShape aItLEIm(aLEIm); |
81a55a69 |
6554 | for (; aItLEIm.More(); aItLEIm.Next()) |
6555 | { |
ecf4f17c |
6556 | const TopoDS_Shape& aEIm = aItLEIm.Value(); |
81a55a69 |
6557 | if (!aNewEdges.Contains(aEIm)) |
6558 | aMEAvoid.Add(aEIm); |
ecf4f17c |
6559 | } |
6560 | } |
81a55a69 |
6561 | theEdgesToAvoid = aMEAvoid; |
ecf4f17c |
6562 | } |
6563 | |
6564 | //======================================================================= |
6565 | //function : TrimNewIntersectionEdges |
6566 | //purpose : |
6567 | //======================================================================= |
6568 | void TrimNewIntersectionEdges(const TopTools_ListOfShape& theLE, |
6569 | const TopTools_DataMapOfShapeListOfShape& theEETrim, |
6570 | const TopTools_MapOfShape& theMVBounds, |
41aa3c3d |
6571 | TopTools_MapOfShape& theMECheckExt, |
ecf4f17c |
6572 | TopTools_DataMapOfShapeListOfShape& theEImages, |
6573 | TopTools_MapOfShape& theMEB, |
6574 | TopTools_MapOfShape& theMVOld, |
dcba2e5c |
6575 | TopTools_MapOfShape& theMENew, |
41aa3c3d |
6576 | TopTools_DataMapOfShapeListOfShape& theDMEOr, |
6577 | TopTools_DataMapOfShapeListOfShape& theMELF) |
ecf4f17c |
6578 | { |
6579 | TopTools_ListIteratorOfListOfShape aIt, aIt1; |
6580 | aIt.Initialize(theLE); |
6581 | for (; aIt.More(); aIt.Next()) { |
6582 | const TopoDS_Shape& aE = aIt.Value(); |
6583 | // |
b443d536 |
6584 | Standard_Boolean bCheckExt = theMECheckExt.Remove(aE); |
6585 | // |
41aa3c3d |
6586 | Standard_Boolean bOld = theEETrim.IsBound(aE); |
6587 | if (bOld) { |
ecf4f17c |
6588 | const TopTools_ListOfShape& aLET = theEETrim.Find(aE); |
6589 | aIt1.Initialize(aLET); |
6590 | for (; aIt1.More(); aIt1.Next()) { |
6591 | const TopoDS_Shape& aET = aIt1.Value(); |
6592 | theMEB.Add(aET); |
6593 | TopExp_Explorer aExpV(aET, TopAbs_VERTEX); |
6594 | for (; aExpV.More(); aExpV.Next()) { |
6595 | const TopoDS_Shape& aV = aExpV.Current(); |
6596 | theMVOld.Add(aV); |
6597 | } |
6598 | } |
6599 | } |
6600 | // |
6601 | if (!theEImages.IsBound(aE)) { |
6602 | continue; |
6603 | } |
6604 | // |
6605 | TopTools_ListOfShape& aLEIm = theEImages.ChangeFind(aE); |
6606 | if (aLEIm.IsEmpty()) { |
6607 | theEImages.UnBind(aE); |
6608 | continue; |
6609 | } |
6610 | // |
6611 | TopoDS_Shape aCEIm; |
6612 | TopTools_MapOfShape aMEVBounds; |
6613 | // |
a8232603 |
6614 | if (aLEIm.Extent() > 1) { |
ecf4f17c |
6615 | TopTools_IndexedMapOfShape aMV; |
6616 | // fuse these parts |
6617 | BOPAlgo_Builder aGFE; |
6618 | TopTools_ListIteratorOfListOfShape aItLEIm(aLEIm); |
6619 | for (; aItLEIm.More(); aItLEIm.Next()) { |
6620 | const TopoDS_Shape& aEIm = aItLEIm.Value(); |
6621 | aGFE.AddArgument(aEIm); |
6622 | TopExp::MapShapes(aEIm, TopAbs_VERTEX, aMV); |
6623 | } |
6624 | // |
6625 | // add two bounding vertices of this edge to the operation |
6626 | TopoDS_Vertex aV1, aV2; |
6627 | TopExp::Vertices(TopoDS::Edge(aE), aV1, aV2); |
6628 | // |
6629 | aGFE.AddArgument(aV1); |
6630 | aGFE.AddArgument(aV2); |
6631 | aMV.Add(aV1); |
6632 | aMV.Add(aV2); |
6633 | // |
6634 | aGFE.Perform(); |
33ba8565 |
6635 | if (!aGFE.HasErrors()) { |
ecf4f17c |
6636 | // get images of bounding vertices to remove splits containing them |
6637 | // in case some of the bounding edges has been interfered |
6638 | // during operation it is necessary to update their images as well |
6639 | Standard_Integer iV, aNbV = aMV.Extent(); |
6640 | for (iV = 1; iV <= aNbV; ++iV) { |
6641 | const TopoDS_Shape& aV = aMV(iV); |
6642 | if (theMVBounds.Contains(aV) || aV.IsSame(aV1) || aV.IsSame(aV2)) { |
6643 | const TopTools_ListOfShape& aLVIm = aGFE.Modified(aV); |
41aa3c3d |
6644 | aMEVBounds.Add(aLVIm.IsEmpty() ? aV : aLVIm.First()); |
ecf4f17c |
6645 | } |
6646 | } |
6647 | // |
6648 | aCEIm = aGFE.Shape(); |
6649 | } |
6650 | } |
6651 | else { |
6652 | aCEIm = aLEIm.First(); |
6653 | } |
6654 | // |
6655 | aLEIm.Clear(); |
6656 | // |
6657 | TopExp_Explorer aExp(aCEIm, TopAbs_EDGE); |
6658 | for (; aExp.More(); aExp.Next()) { |
6659 | const TopoDS_Shape& aEIm = aExp.Current(); |
6660 | // |
6661 | // check the split not to contain bounding vertices |
6662 | TopoDS_Iterator aItV(aEIm); |
6663 | for (; aItV.More(); aItV.Next()) { |
6664 | const TopoDS_Shape& aV = aItV.Value(); |
6665 | if (aMEVBounds.Contains(aV) || theMVBounds.Contains(aV)) { |
6666 | break; |
6667 | } |
6668 | } |
6669 | // |
6670 | if (!aItV.More()) { |
ecf4f17c |
6671 | aLEIm.Append(aEIm); |
6672 | // |
6673 | theDMEOr.Bound(aEIm, TopTools_ListOfShape())->Append(aE); |
6674 | } |
6675 | } |
6676 | // |
6677 | if (aLEIm.IsEmpty()) { |
6678 | theEImages.UnBind(aE); |
6679 | } |
6680 | else { |
41aa3c3d |
6681 | const TopTools_ListOfShape& aLFE = theMELF.Find(aE); |
6682 | TopTools_ListIteratorOfListOfShape aItLEIm(aLEIm); |
6683 | for (; aItLEIm.More(); aItLEIm.Next()) { |
6684 | const TopoDS_Shape& aEIm = aItLEIm.Value(); |
6685 | TopTools_ListOfShape* pLFEIm = theMELF.ChangeSeek(aEIm); |
6686 | if (!pLFEIm) { |
6687 | pLFEIm = theMELF.Bound(aEIm, TopTools_ListOfShape()); |
6688 | } |
6689 | TopTools_ListIteratorOfListOfShape aItLF(aLFE); |
6690 | for (; aItLF.More(); aItLF.Next()) { |
6691 | AppendToList(*pLFEIm, aItLF.Value()); |
6692 | } |
6693 | // |
6694 | if (bCheckExt) { |
6695 | theMECheckExt.Add(aEIm); |
6696 | } |
6697 | else if (!bOld) { |
dcba2e5c |
6698 | theMENew.Add(aEIm); |
ecf4f17c |
6699 | } |
6700 | } |
6701 | } |
6702 | } |
6703 | } |
6704 | |
6705 | //======================================================================= |
6706 | //function : IntersectEdges |
6707 | //purpose : Intersecting the trimmed edges to avoid self-intersections |
6708 | //======================================================================= |
1155d05a |
6709 | void IntersectEdges(const TopTools_ListOfShape& theLA, |
ecf4f17c |
6710 | const TopTools_ListOfShape& theLE, |
ecf4f17c |
6711 | const TopTools_MapOfShape& theMVBounds, |
6712 | const TopTools_MapOfShape& theVertsToAvoid, |
dcba2e5c |
6713 | TopTools_MapOfShape& theMENew, |
41aa3c3d |
6714 | TopTools_MapOfShape& theMECheckExt, |
ecf4f17c |
6715 | TopTools_DataMapOfShapeListOfShape& theEImages, |
6716 | TopTools_MapOfShape& theModifiedEdges, |
6717 | TopTools_DataMapOfShapeListOfShape& theDMEOr, |
41aa3c3d |
6718 | TopTools_DataMapOfShapeListOfShape& theMELF, |
ecf4f17c |
6719 | TopoDS_Shape& theSplits) |
6720 | { |
6721 | BOPAlgo_Builder aGFA; |
6722 | aGFA.SetArguments(theLA); |
6723 | aGFA.Perform(); |
33ba8565 |
6724 | if (aGFA.HasErrors()) { |
ecf4f17c |
6725 | // just copy input to the result |
6726 | TopoDS_Compound aSp; |
6727 | BRep_Builder aBB; |
6728 | aBB.MakeCompound(aSp); |
1155d05a |
6729 | TopTools_ListIteratorOfListOfShape anIt(theLA); |
ecf4f17c |
6730 | for (; anIt.More(); anIt.Next()) { |
6731 | const TopoDS_Shape& aE = anIt.Value(); |
6732 | aBB.Add(aSp, aE); |
6733 | } |
6734 | theSplits = aSp; |
6735 | return; |
6736 | } |
6737 | // |
6738 | UpdateImages(theLE, theEImages, aGFA, theModifiedEdges); |
6739 | // |
6740 | // compound of valid splits |
6741 | theSplits = aGFA.Shape(); |
6742 | // |
ecf4f17c |
6743 | TopTools_ListIteratorOfListOfShape aIt, aIt1; |
dcba2e5c |
6744 | |
6745 | // prepare list of edges to update |
6746 | TopTools_ListOfShape aLEInput; |
6747 | for (aIt.Initialize(theLA); aIt.More(); aIt.Next()) |
6748 | { |
6749 | TopExp_Explorer anExpE(aIt.Value(), TopAbs_EDGE); |
6750 | for (; anExpE.More(); anExpE.Next()) |
6751 | aLEInput.Append(anExpE.Current()); |
6752 | } |
6753 | |
6754 | // update new edges |
6755 | aIt.Initialize(aLEInput); |
ecf4f17c |
6756 | for (; aIt.More(); aIt.Next()) { |
6757 | const TopoDS_Shape& aE = aIt.Value(); |
dcba2e5c |
6758 | if (!theMENew.Contains(aE)) |
6759 | continue; |
6760 | |
ecf4f17c |
6761 | const TopTools_ListOfShape& aLEIm = aGFA.Modified(aE); |
dcba2e5c |
6762 | if (aLEIm.IsEmpty()) |
6763 | continue; |
6764 | |
6765 | theMENew.Remove(aE); |
6766 | aIt1.Initialize(aLEIm); |
6767 | for (; aIt1.More(); aIt1.Next()) |
6768 | theMENew.Add(aIt1.Value()); |
ecf4f17c |
6769 | } |
6770 | // |
41aa3c3d |
6771 | // update edges after intersection for extended checking |
dcba2e5c |
6772 | aIt.Initialize(aLEInput); |
41aa3c3d |
6773 | for (; aIt.More(); aIt.Next()) { |
6774 | const TopoDS_Shape& aE = aIt.Value(); |
6775 | const TopTools_ListOfShape& aLEIm = aGFA.Modified(aE); |
6776 | if (aLEIm.IsEmpty()) { |
6777 | continue; |
6778 | } |
6779 | // |
6780 | if (theMECheckExt.Contains(aE)) { |
6781 | aIt1.Initialize(aLEIm); |
6782 | for (; aIt1.More(); aIt1.Next()) { |
6783 | theMECheckExt.Add(aIt1.Value()); |
6784 | } |
6785 | theMECheckExt.Remove(aE); |
6786 | } |
6787 | // |
6788 | const TopTools_ListOfShape& aLFE = theMELF.Find(aE); |
6789 | aIt1.Initialize(aLEIm); |
6790 | for (; aIt1.More(); aIt1.Next()) { |
6791 | const TopoDS_Shape& aEIm = aIt1.Value(); |
6792 | TopTools_ListOfShape* pLFEIm = theMELF.ChangeSeek(aEIm); |
6793 | if (!pLFEIm) { |
6794 | pLFEIm = theMELF.Bound(aEIm, TopTools_ListOfShape()); |
6795 | } |
6796 | TopTools_ListIteratorOfListOfShape aItLF(aLFE); |
6797 | for (; aItLF.More(); aItLF.Next()) { |
6798 | AppendToList(*pLFEIm, aItLF.Value()); |
6799 | } |
6800 | } |
6801 | } |
6802 | // |
ecf4f17c |
6803 | TopTools_MapOfShape aMEInv; |
6804 | GetInvalidEdges(theVertsToAvoid, theMVBounds, aGFA, aMEInv); |
6805 | if (aMEInv.Extent()) { |
6806 | // update shape |
6807 | TopoDS_Compound aSp; |
6808 | BRep_Builder aBB; |
6809 | aBB.MakeCompound(aSp); |
6810 | TopExp_Explorer aExp(theSplits, TopAbs_EDGE); |
6811 | for (; aExp.More(); aExp.Next()) { |
6812 | const TopoDS_Shape& aE = aExp.Current(); |
6813 | if (!aMEInv.Contains(aE)) { |
6814 | aBB.Add(aSp, aE); |
6815 | } |
6816 | } |
6817 | theSplits = aSp; |
6818 | } |
6819 | // |
dcba2e5c |
6820 | // update origins |
6821 | UpdateOrigins(aLEInput, theDMEOr, aGFA); |
ecf4f17c |
6822 | } |
6823 | |
6824 | //======================================================================= |
6825 | //function : GetBounds |
6826 | //purpose : Getting edges from the splits of offset faces |
6827 | //======================================================================= |
dcba2e5c |
6828 | void GetBounds(const TopTools_ListOfShape& theLFaces, |
6829 | const TopTools_IndexedDataMapOfShapeListOfShape& theFImages, |
ecf4f17c |
6830 | const TopTools_MapOfShape& theMEB, |
6831 | TopoDS_Shape& theBounds) |
6832 | { |
ecf4f17c |
6833 | BRep_Builder aBB; |
dcba2e5c |
6834 | // Make compound of edges contained in the splits of faces |
6835 | TopoDS_Compound aBounds; |
ecf4f17c |
6836 | aBB.MakeCompound(aBounds); |
dcba2e5c |
6837 | // Fence map |
ecf4f17c |
6838 | TopTools_MapOfShape aMFence; |
dcba2e5c |
6839 | |
6840 | TopTools_ListIteratorOfListOfShape aItLF(theLFaces); |
6841 | for (; aItLF.More(); aItLF.Next()) |
6842 | { |
6843 | const TopTools_ListOfShape* pLFIm = theFImages.Seek(aItLF.Value()); |
6844 | if (!pLFIm) |
6845 | continue; |
6846 | TopTools_ListIteratorOfListOfShape aIt(*pLFIm); |
6847 | for (; aIt.More(); aIt.Next()) |
6848 | { |
ecf4f17c |
6849 | const TopoDS_Shape& aFIm = aIt.Value(); |
6850 | // |
6851 | TopExp_Explorer aExpE(aFIm, TopAbs_EDGE); |
dcba2e5c |
6852 | for (; aExpE.More(); aExpE.Next()) |
6853 | { |
ecf4f17c |
6854 | const TopoDS_Shape& aEIm = aExpE.Current(); |
6855 | if (!theMEB.Contains(aEIm) && aMFence.Add(aEIm)) { |
6856 | aBB.Add(aBounds, aEIm); |
6857 | } |
6858 | } |
6859 | } |
6860 | } |
6861 | theBounds = aBounds; |
6862 | } |
6863 | |
6864 | //======================================================================= |
6865 | //function : GetBoundsToUpdate |
6866 | //purpose : Get bounding edges that should be updated |
6867 | //======================================================================= |
6868 | void GetBoundsToUpdate(const TopTools_ListOfShape& theLF, |
6869 | const TopTools_DataMapOfShapeListOfShape& theOEImages, |
6870 | const TopTools_DataMapOfShapeListOfShape& theOEOrigins, |
6871 | const TopTools_MapOfShape& theMEB, |
6872 | TopTools_ListOfShape& theLABounds, |
6873 | TopTools_ListOfShape& theLAValid, |
6874 | TopoDS_Shape& theBounds, |
6875 | Handle(BRepAlgo_AsDes)& theAsDes) |
6876 | { |
6877 | // get all edges |
6878 | TopoDS_Compound aBounds; |
6879 | BRep_Builder aBB; |
6880 | aBB.MakeCompound(aBounds); |
6881 | // |
6882 | TopTools_MapOfShape aMAValid, aMFence; |
6883 | // |
6884 | TopTools_ListIteratorOfListOfShape aItLF(theLF); |
6885 | for (; aItLF.More(); aItLF.Next()) { |
6886 | const TopoDS_Shape& aF = aItLF.Value(); |
6887 | // |
6888 | TopTools_IndexedMapOfShape aMDE; |
6889 | const TopTools_ListOfShape& aLFDes = theAsDes->Descendant(aF); |
6890 | TopTools_ListIteratorOfListOfShape aItLFDes(aLFDes); |
6891 | for (; aItLFDes.More(); aItLFDes.Next()) { |
6892 | const TopoDS_Shape& aED = aItLFDes.Value(); |
6893 | const TopTools_ListOfShape *pLEDIm = theOEImages.Seek(aED); |
6894 | if (!pLEDIm) { |
6895 | aMDE.Add(aED); |
6896 | continue; |
6897 | } |
6898 | // |
6899 | TopTools_ListIteratorOfListOfShape aItLEDIm(*pLEDIm); |
6900 | for (; aItLEDIm.More(); aItLEDIm.Next()) { |
6901 | const TopoDS_Shape& aEDIm = aItLEDIm.Value(); |
6902 | aMDE.Add(aEDIm); |
6903 | } |
6904 | } |
6905 | // |
6906 | Standard_Integer j, aNbE = aMDE.Extent(); |
6907 | for (j = 1; j <= aNbE; ++j) { |
6908 | const TopoDS_Edge& aEIm = TopoDS::Edge(aMDE(j)); |
6909 | // |
6910 | if (!theMEB.Contains(aEIm) && aMFence.Add(aEIm)) { |
6911 | aBB.Add(aBounds, aEIm); |
6912 | theLABounds.Append(aEIm); |
6913 | } |
6914 | // |
6915 | const TopTools_ListOfShape *pLO = theOEOrigins.Seek(aEIm); |
6916 | if (pLO) { |
6917 | TopTools_ListIteratorOfListOfShape aItLO(*pLO); |
6918 | for (; aItLO.More(); aItLO.Next()) { |
6919 | const TopoDS_Shape& aEO = aItLO.Value(); |
6920 | // |
6921 | if (aMAValid.Add(aEO)) { |
6922 | theLAValid.Append(aEO); |
6923 | } |
6924 | } |
6925 | } |
6926 | else { |
6927 | if (aMAValid.Add(aEIm)) { |
6928 | theLAValid.Append(aEIm); |
6929 | } |
6930 | } |
6931 | } |
6932 | } |
6933 | theBounds = aBounds; |
6934 | } |
6935 | |
6936 | //======================================================================= |
6937 | //function : GetInvalidEdgesByBounds |
6938 | //purpose : Filter new splits by intersection with bounds |
6939 | //======================================================================= |
6940 | void GetInvalidEdgesByBounds(const TopoDS_Shape& theSplits, |
6941 | const TopoDS_Shape& theBounds, |
ecf4f17c |
6942 | const TopTools_IndexedDataMapOfShapeListOfShape& theFImages, |
6943 | const TopoDS_Shape& theSolids, |
6944 | const TopTools_IndexedMapOfShape& theInvEdges, |
6945 | const TopTools_MapOfShape& theMVOld, |
6946 | const TopTools_MapOfShape& theMENew, |
6947 | const TopTools_DataMapOfShapeListOfShape& theDMEOr, |
41aa3c3d |
6948 | const TopTools_DataMapOfShapeListOfShape& theMELF, |
ecf4f17c |
6949 | const TopTools_DataMapOfShapeListOfShape& theEImages, |
41aa3c3d |
6950 | const TopTools_MapOfShape& theMECheckExt, |
a8232603 |
6951 | const TopTools_MapOfShape& theMEInvOnArt, |
dcba2e5c |
6952 | Handle(IntTools_Context)& theCtx, |
ecf4f17c |
6953 | TopTools_MapOfShape& theVertsToAvoid, |
6954 | TopTools_MapOfShape& theMEInv) |
6955 | { |
a8232603 |
6956 | // map splits to check the vertices of edges |
6957 | TopTools_IndexedDataMapOfShapeListOfShape aDMVE; |
6958 | TopExp::MapShapesAndAncestors(theSplits, TopAbs_VERTEX, TopAbs_EDGE, aDMVE); |
6959 | // |
ecf4f17c |
6960 | BOPAlgo_Section aSec; |
6961 | aSec.AddArgument(theSplits); |
6962 | aSec.AddArgument(theBounds); |
6963 | // |
6964 | aSec.Perform(); |
6965 | // |
6966 | // invalid vertices |
6967 | TopTools_IndexedMapOfShape aMVInv; |
6968 | // vertices to check additionally by classification relatively to solid |
6969 | TopTools_MapOfShape aMVCheckAdd; |
6970 | // collect parts for removal |
6971 | const BOPDS_PDS& pDS = aSec.PDS(); |
6972 | // |
6973 | // check edge/edge intersections |
6974 | const BOPDS_VectorOfInterfEE& aEEs = pDS->InterfEE(); |
1155d05a |
6975 | Standard_Integer i, aNb = aEEs.Length(); |
ecf4f17c |
6976 | for (i = 0; i < aNb; ++i) { |
6977 | const BOPDS_InterfEE& aEE = aEEs(i); |
ecf4f17c |
6978 | // |
6979 | const TopoDS_Shape& aE1 = pDS->Shape(aEE.Index1()); |
6980 | const TopoDS_Shape& aE2 = pDS->Shape(aEE.Index2()); |
6981 | // |
41aa3c3d |
6982 | if (!aEE.HasIndexNew()) { |
6983 | if (theMECheckExt.Contains(aE1) && (aEE.CommonPart().Type() == TopAbs_EDGE)) { |
6984 | theMEInv.Add(aE1); |
6985 | } |
6986 | continue; |
6987 | } |
6988 | // |
ecf4f17c |
6989 | if (theInvEdges.Contains(aE2)) { |
6990 | theMEInv.Add(aE1); |
6991 | } |
6992 | // |
a8232603 |
6993 | if (theMEInvOnArt.Contains(aE2)) { |
6994 | // avoid checking of the vertices of the split edge intersected by |
6995 | // the invalid edge from artificial face |
6996 | TopoDS_Vertex aV1, aV2; |
6997 | TopExp::Vertices(TopoDS::Edge(aE2), aV1, aV2); |
6998 | if (aDMVE.Contains(aV1) && aDMVE.Contains(aV2)) { |
6999 | continue; |
7000 | } |
7001 | } |
7002 | // |
41aa3c3d |
7003 | // add vertices of all images of the edge from splits for checking |
ecf4f17c |
7004 | const TopTools_ListOfShape& aLEOr = theDMEOr.Find(aE1); |
7005 | TopTools_ListIteratorOfListOfShape aItLEOr(aLEOr); |
7006 | for (; aItLEOr.More(); aItLEOr.Next()) { |
7007 | const TopoDS_Shape& aEOr = aItLEOr.Value(); |
7008 | // |
dcba2e5c |
7009 | const TopTools_ListOfShape *pLEIm = theEImages.Seek(aEOr); |
7010 | if (!pLEIm) |
7011 | continue; |
7012 | TopTools_ListIteratorOfListOfShape aItLEIm(*pLEIm); |
ecf4f17c |
7013 | for (; aItLEIm.More(); aItLEIm.Next()) { |
7014 | const TopoDS_Shape& aEIm = aItLEIm.Value(); |
7015 | // |
7016 | TopoDS_Iterator aItV(aEIm); |
7017 | for (; aItV.More(); aItV.Next()) { |
7018 | const TopoDS_Shape& aV = aItV.Value(); |
7019 | if (!theMVOld.Contains(aV)) { |
7020 | aMVInv.Add(aV); |
7021 | aMVCheckAdd.Add(aV); |
7022 | } |
7023 | } |
7024 | } |
7025 | } |
7026 | } |
7027 | // |
ecf4f17c |
7028 | // to avoid unnecessary filling of parts due to extra trim of the edges |
41aa3c3d |
7029 | // process Edge/Edge interferences of type EDGE, i.e. common blocks and check |
7030 | // not the bounding vertices of the edges, but check the edge itself |
7031 | // to be lying on some face |
ecf4f17c |
7032 | // |
7033 | // all common blocks are contained in the result of SECTION operation |
7034 | // between sets of edges |
7035 | const TopoDS_Shape& aSecR = aSec.Shape(); |
7036 | // |
7037 | TopTools_IndexedMapOfShape aMSSec; |
7038 | TopExp::MapShapes(aSecR, aMSSec); |
7039 | // |
1155d05a |
7040 | const TopTools_DataMapOfShapeListOfShape& anIm = aSec.Images(); |
45d0af05 |
7041 | for (TopExp_Explorer aExp(theSplits, TopAbs_EDGE); aExp.More(); aExp.Next()) |
7042 | { |
ecf4f17c |
7043 | const TopoDS_Shape& aE = aExp.Current(); |
7044 | if (aSec.IsDeleted(aE)) { |
7045 | // no common blocks for this edge |
7046 | continue; |
7047 | } |
7048 | // |
1155d05a |
7049 | const TopTools_ListOfShape* pLEIm = anIm.Seek(aE); |
ecf4f17c |
7050 | if (!pLEIm) { |
7051 | // no splits, i.e. completely coincides with some edge from boundary |
7052 | continue; |
7053 | } |
7054 | // |
1155d05a |
7055 | TopTools_ListIteratorOfListOfShape aItLEIm(*pLEIm); |
ecf4f17c |
7056 | for (; aItLEIm.More(); aItLEIm.Next()) { |
7057 | const TopoDS_Shape& aEIm = aItLEIm.Value(); |
7058 | if (!aMSSec.Contains(aEIm)) { |
7059 | // the edge included in section only partially. |
41aa3c3d |
7060 | // the part not included in section may be excessive |
ecf4f17c |
7061 | // |
7062 | // check vertices of this edge - if one of them is new |
7063 | // the edge might be removed |
7064 | TopoDS_Vertex aV1, aV2; |
7065 | TopExp::Vertices(TopoDS::Edge(aEIm), aV1, aV2); |
7066 | if (!theMVOld.Contains(aV1) || !theMVOld.Contains(aV2)) { |
41aa3c3d |
7067 | // add this edge for checking by making new vertex in the middle of the edge |
ecf4f17c |
7068 | TopoDS_Vertex aV; |
7069 | Standard_Real f, l; |
7070 | const Handle(Geom_Curve)& aC = BRep_Tool::Curve(TopoDS::Edge(aEIm), f, l); |
7071 | BRep_Builder().MakeVertex(aV, aC->Value((f+l)*0.5), Precision::Confusion()); |
41aa3c3d |
7072 | // and adding this vertex for checking |
7073 | aDMVE.ChangeFromIndex(aDMVE.Add(aV, TopTools_ListOfShape())).Append(aE); |
ecf4f17c |
7074 | aMVInv.Add(aV); |
7075 | break; |
7076 | } |
7077 | } |
7078 | } |
7079 | } |
7080 | // |
41aa3c3d |
7081 | // Add for check also the edges created from common between splits |
7082 | // of offset faces edges not connected to any invalidity. |
7083 | // These edges may also accidentally fill some part. |
7084 | TopTools_MapIteratorOfMapOfShape aItM(theMECheckExt); |
7085 | for (; aItM.More(); aItM.Next()) { |
7086 | const TopoDS_Shape& aE = aItM.Value(); |
7087 | // |
7088 | // make new vertex in the middle of the edge |
7089 | TopoDS_Vertex aV; |
7090 | Standard_Real f, l; |
7091 | const Handle(Geom_Curve)& aC = BRep_Tool::Curve(TopoDS::Edge(aE), f, l); |
7092 | BRep_Builder().MakeVertex(aV, aC->Value((f + l)*0.5), Precision::Confusion()); |
7093 | // add this vertex for checking |
7094 | aDMVE.ChangeFromIndex(aDMVE.Add(aV, TopTools_ListOfShape())).Append(aE); |
7095 | aMVInv.Add(aV); |
7096 | } |
7097 | // |
7098 | // add for check also the vertices connected only to new or old edges |
ecf4f17c |
7099 | aNb = aDMVE.Extent(); |
7100 | for (i = 1; i <= aNb; ++i) { |
7101 | const TopoDS_Shape& aV = aDMVE.FindKey(i); |
7102 | if (theMVOld.Contains(aV)) { |
7103 | continue; |
7104 | } |
7105 | // |
7106 | Standard_Boolean bNew = Standard_False, bOld = Standard_False; |
7107 | const TopTools_ListOfShape& aLEx = aDMVE(i); |
7108 | TopTools_ListIteratorOfListOfShape aIt(aLEx); |
7109 | for (; aIt.More(); aIt.Next()) { |
7110 | const TopoDS_Shape& aE = aIt.Value(); |
41aa3c3d |
7111 | if (theMECheckExt.Contains(aE)) { |
7112 | continue; |
7113 | } |
7114 | // |
ecf4f17c |
7115 | if (theMENew.Contains(aE)) { |
7116 | bNew = Standard_True; |
7117 | } |
7118 | else { |
7119 | bOld = Standard_True; |
7120 | } |
7121 | // |
7122 | if (bNew && bOld) { |
7123 | break; |
7124 | } |
7125 | } |
7126 | // |
7127 | if (!bNew || !bOld) { |
7128 | aMVInv.Add(aV); |
7129 | aMVCheckAdd.Remove(aV); |
7130 | } |
7131 | } |
7132 | // |
dcba2e5c |
7133 | // perform the checking of the vertices |
41aa3c3d |
7134 | Standard_Integer iv, aNbIV = aMVInv.Extent(); |
ecf4f17c |
7135 | for (iv = 1; iv <= aNbIV; ++iv) { |
7136 | const TopoDS_Vertex& aV = TopoDS::Vertex(aMVInv(iv)); |
41aa3c3d |
7137 | if (theMVOld.Contains(aV)) { |
7138 | continue; |
7139 | } |
7140 | // |
7141 | const TopTools_ListOfShape* pLEInv = aDMVE.Seek(aV); |
7142 | if (!pLEInv) { |
7143 | continue; |
7144 | } |
7145 | // find faces by the edges to check the vertex |
7146 | TopTools_IndexedMapOfShape aMF; |
7147 | TopTools_ListIteratorOfListOfShape aItLE(*pLEInv); |
7148 | for (; aItLE.More(); aItLE.Next()) { |
7149 | const TopoDS_Shape& aE = aItLE.Value(); |
7150 | const TopTools_ListOfShape& aLF = theMELF.Find(aE); |
7151 | TopTools_ListIteratorOfListOfShape aItLF(aLF); |
7152 | for (; aItLF.More(); aItLF.Next()) { |
7153 | aMF.Add(aItLF.Value()); |
7154 | } |
7155 | } |
7156 | // |
7157 | // check the vertex to belong to some split of the faces |
ecf4f17c |
7158 | Standard_Boolean bInvalid = Standard_True; |
7159 | // |
41aa3c3d |
7160 | Standard_Integer aNbF = aMF.Extent(); |
ecf4f17c |
7161 | for (i = 1; i <= aNbF && bInvalid; ++i) { |
41aa3c3d |
7162 | const TopoDS_Face& aF = TopoDS::Face(aMF(i)); |
ecf4f17c |
7163 | const TopTools_ListOfShape& aLFIm = theFImages.FindFromKey(aF); |
7164 | // |
7165 | TopTools_ListIteratorOfListOfShape aItLF(aLFIm); |
7166 | for (; aItLF.More() && bInvalid; aItLF.Next()) { |
7167 | const TopoDS_Face& aFIm = TopoDS::Face(aItLF.Value()); |
7168 | TopExp_Explorer aExp(aFIm, TopAbs_VERTEX); |
7169 | for (; aExp.More() && bInvalid; aExp.Next()) { |
7170 | const TopoDS_Shape& aVF = aExp.Current(); |
7171 | bInvalid = !aVF.IsSame(aV); |
7172 | } |
41aa3c3d |
7173 | } |
7174 | // |
7175 | if (bInvalid) { |
7176 | Standard_Real U, V, aTol; |
dcba2e5c |
7177 | Standard_Integer iStatus = theCtx->ComputeVF(aV, aF, U, V, aTol); |
41aa3c3d |
7178 | if (!iStatus) { |
7179 | // classify the point relatively faces |
7180 | gp_Pnt2d aP2d(U, V); |
7181 | aItLF.Initialize(aLFIm); |
7182 | for (; aItLF.More() && bInvalid; aItLF.Next()) { |
7183 | const TopoDS_Face& aFIm = TopoDS::Face(aItLF.Value()); |
dcba2e5c |
7184 | bInvalid = !theCtx->IsPointInOnFace(aFIm, aP2d); |
41aa3c3d |
7185 | } |
ecf4f17c |
7186 | } |
7187 | } |
7188 | } |
7189 | // |
7190 | if (bInvalid && aMVCheckAdd.Contains(aV)) { |
7191 | // the vertex is invalid for all faces |
7192 | // check the same vertex for the solids |
41aa3c3d |
7193 | const gp_Pnt& aP = BRep_Tool::Pnt(aV); |
7194 | Standard_Real aTolV = BRep_Tool::Tolerance(aV); |
7195 | // |
ecf4f17c |
7196 | TopExp_Explorer aExpS(theSolids, TopAbs_SOLID); |
7197 | for (; aExpS.More() && bInvalid; aExpS.Next()) { |
7198 | const TopoDS_Solid& aSol = TopoDS::Solid(aExpS.Current()); |
dcba2e5c |
7199 | BRepClass3d_SolidClassifier& aSC = theCtx->SolidClassifier(aSol); |
ecf4f17c |
7200 | aSC.Perform(aP, aTolV); |
7201 | bInvalid = (aSC.State() == TopAbs_OUT); |
7202 | } |
7203 | } |
7204 | // |
7205 | if (bInvalid) { |
7206 | theVertsToAvoid.Add(aV); |
41aa3c3d |
7207 | aItLE.Initialize(*pLEInv); |
7208 | for (; aItLE.More(); aItLE.Next()) { |
7209 | theMEInv.Add(aItLE.Value()); |
ecf4f17c |
7210 | } |
7211 | } |
7212 | } |
7213 | } |
7214 | |
dcba2e5c |
7215 | //======================================================================= |
7216 | //function : FilterSplits |
7217 | //purpose : Filter the images of edges from the invalid edges |
7218 | //======================================================================= |
7219 | void FilterSplits(const TopTools_ListOfShape& theLE, |
7220 | const TopTools_MapOfShape& theMEFilter, |
7221 | const Standard_Boolean theIsInv, |
7222 | TopTools_DataMapOfShapeListOfShape& theEImages, |
7223 | TopoDS_Shape& theSplits) |
7224 | { |
7225 | TopoDS_Compound aSplits; |
7226 | BRep_Builder().MakeCompound(aSplits); |
7227 | TopTools_MapOfShape aMFence; |
7228 | |
7229 | TopTools_ListIteratorOfListOfShape aItLE(theLE); |
7230 | for (; aItLE.More(); aItLE.Next()) |
7231 | { |
7232 | const TopoDS_Shape& aE = aItLE.Value(); |
7233 | TopTools_ListOfShape *pLEIm = theEImages.ChangeSeek(aE); |
7234 | if (!pLEIm) |
7235 | continue; |
7236 | |
7237 | TopTools_ListIteratorOfListOfShape aItLEIm(*pLEIm); |
7238 | for (; aItLEIm.More();) |
7239 | { |
7240 | const TopoDS_Shape& aEIm = aItLEIm.Value(); |
7241 | if (theMEFilter.Contains(aEIm) == theIsInv) |
7242 | { |
7243 | pLEIm->Remove(aItLEIm); |
7244 | continue; |
7245 | } |
7246 | |
7247 | if (aMFence.Add(aEIm)) |
7248 | BRep_Builder().Add(aSplits, aEIm); |
7249 | aItLEIm.Next(); |
7250 | } |
7251 | |
7252 | if (pLEIm->IsEmpty()) |
7253 | theEImages.UnBind(aE); |
7254 | } |
7255 | theSplits = aSplits; |
7256 | } |
7257 | |
ecf4f17c |
7258 | //======================================================================= |
7259 | //function : UpdateNewIntersectionEdges |
7260 | //purpose : Updating the maps of images and origins of the offset edges |
7261 | //======================================================================= |
7262 | void UpdateNewIntersectionEdges(const TopTools_ListOfShape& theLE, |
7263 | const TopTools_DataMapOfShapeListOfShape& theMELF, |
7264 | const TopTools_DataMapOfShapeListOfShape& theEImages, |
7265 | const TopTools_IndexedMapOfShape& theInvEdges, |
7266 | const TopTools_MapOfShape& theInvertedEdges, |
7267 | TopTools_DataMapOfShapeListOfShape& theEdgesOrigins, |
7268 | TopTools_DataMapOfShapeListOfShape& theOEImages, |
7269 | TopTools_DataMapOfShapeListOfShape& theOEOrigins, |
7270 | TopTools_DataMapOfShapeShape& theETrimEInf, |
7271 | TopTools_DataMapOfShapeListOfShape& theEETrim, |
7272 | TopTools_MapOfShape& theModifiedEdges, |
7273 | Handle(BRepAlgo_AsDes)& theAsDes) |
7274 | { |
7275 | TopTools_ListOfShape aLEImEmpty; |
7276 | TopTools_ListIteratorOfListOfShape aIt, aIt1; |
7277 | // update global maps of images and origins with new splits |
7278 | aIt.Initialize(theLE); |
7279 | for (; aIt.More(); aIt.Next()) { |
7280 | const TopoDS_Shape& aE = aIt.Value(); |
7281 | // |
7282 | if (!theEImages.IsBound(aE)) { |
7283 | TopTools_ListOfShape* pLET = theEETrim.ChangeSeek(aE); |
7284 | if (!pLET) { |
7285 | continue; |
7286 | } |
7287 | // |
7288 | TopTools_ListIteratorOfListOfShape aItLET(*pLET); |
7289 | for (; aItLET.More();) { |
7290 | const TopoDS_Shape& aET = aItLET.Value(); |
7291 | if (!theInvEdges.Contains(aET) && !theInvertedEdges.Contains(aET)) { |
7292 | pLET->Remove(aItLET); |
7293 | } |
7294 | else { |
7295 | aItLET.Next(); |
7296 | } |
7297 | } |
7298 | // |
7299 | if (pLET->IsEmpty()) { |
7300 | continue; |
7301 | } |
7302 | } |
7303 | // new images |
7304 | const TopTools_ListOfShape& aLENew = |
7305 | theEImages.IsBound(aE) ? theEImages.Find(aE) : aLEImEmpty; |
7306 | // |
7307 | // save connection to untrimmed edge for the next steps |
7308 | aIt1.Initialize(aLENew); |
7309 | for (; aIt1.More(); aIt1.Next()) { |
7310 | const TopoDS_Shape& aET = aIt1.Value(); |
7311 | theETrimEInf.Bind(aET, aE); |
7312 | theModifiedEdges.Add(aET); |
7313 | } |
7314 | // |
7315 | // check if it is existing edge |
7316 | if (!theEETrim.IsBound(aE)) { |
7317 | const TopTools_ListOfShape& aLF = theMELF.Find(aE); |
7318 | // the edge is new |
7319 | // add this edge to AsDes |
7320 | aIt1.Initialize(aLF); |
7321 | for (; aIt1.More(); aIt1.Next()) { |
7322 | const TopoDS_Shape& aF = aIt1.Value(); |
7323 | theAsDes->Add(aF, aE); |
7324 | } |
7325 | // |
7326 | // add aE to the images |
7327 | theOEImages.Bind(aE, aLENew); |
7328 | theModifiedEdges.Add(aE); |
7329 | // |
7330 | // add to origins |
7331 | TopTools_ListIteratorOfListOfShape aItNew(aLENew); |
7332 | for (; aItNew.More(); aItNew.Next()) { |
7333 | const TopoDS_Shape& aENew = aItNew.Value(); |
7334 | if (theOEOrigins.IsBound(aENew)) { |
7335 | TopTools_ListOfShape& aEOrigins = theOEOrigins.ChangeFind(aENew); |
7336 | AppendToList(aEOrigins, aE); |
7337 | } |
7338 | else { |
7339 | TopTools_ListOfShape aEOrigins; |
7340 | aEOrigins.Append(aE); |
7341 | theOEOrigins.Bind(aENew, aEOrigins); |
7342 | } |
7343 | } |
7344 | // |
7345 | // update connection to initial origins |
7346 | if (theEdgesOrigins.IsBound(aE)) { |
7347 | const TopTools_ListOfShape& aLEOrInit = theEdgesOrigins.Find(aE); |
7348 | aIt1.Initialize(aLENew); |
7349 | for (; aIt1.More(); aIt1.Next()) { |
7350 | const TopoDS_Shape& aENew = aIt1.Value(); |
7351 | if (theEdgesOrigins.IsBound(aENew)) { |
7352 | TopTools_ListOfShape& aLENewOr = theEdgesOrigins.ChangeFind(aENew); |
7353 | TopTools_ListIteratorOfListOfShape aItOrInit(aLEOrInit); |
7354 | for (; aItOrInit.More(); aItOrInit.Next()) { |
7355 | const TopoDS_Shape& aEOr = aItOrInit.Value(); |
7356 | AppendToList(aLENewOr, aEOr); |
7357 | } |
7358 | } |
7359 | else { |
7360 | theEdgesOrigins.Bind(aENew, aLEOrInit); |
7361 | } |
7362 | } |
7363 | } |
7364 | // |
7365 | continue; |
7366 | } |
7367 | // |
7368 | // old images |
7369 | const TopTools_ListOfShape& aLEOld = theEETrim.Find(aE); |
7370 | // |
7371 | // list of initial origins |
7372 | TopTools_ListOfShape anInitOrigins; |
7373 | // |
7374 | // it is necessary to replace the old edges with new ones |
7375 | aIt1.Initialize(aLEOld); |
7376 | for (; aIt1.More(); aIt1.Next()) { |
7377 | const TopoDS_Shape& aEOld = aIt1.Value(); |
7378 | // |
7379 | if (theOEOrigins.IsBound(aEOld)) { |
7380 | // get its origins |
7381 | const TopTools_ListOfShape& aEOrigins = theOEOrigins.Find(aEOld); |
7382 | // |
7383 | TopTools_ListIteratorOfListOfShape aItOr(aEOrigins); |
7384 | for (; aItOr.More(); aItOr.Next()) { |
7385 | const TopoDS_Shape& aEOr = aItOr.Value(); |
7386 | // |
7387 | theModifiedEdges.Add(aEOr); |
7388 | // |
7389 | TopTools_ListOfShape& aEImages = theOEImages.ChangeFind(aEOr); |
7390 | // |
7391 | // remove old edge from images |
7392 | TopTools_ListIteratorOfListOfShape aItIm(aEImages); |
7393 | for (; aItIm.More(); ) { |
7394 | const TopoDS_Shape& aEIm = aItIm.Value(); |
7395 | if (aEIm.IsSame(aEOld)) { |
7396 | aEImages.Remove(aItIm); |
7397 | } |
7398 | else { |
7399 | aItIm.Next(); |
7400 | } |
7401 | } |
7402 | // |
7403 | // add new images |
7404 | TopTools_ListIteratorOfListOfShape aItNew(aLENew); |
7405 | for (; aItNew.More(); aItNew.Next()) { |
7406 | const TopoDS_Shape& aENew = aItNew.Value(); |
7407 | AppendToList(aEImages, aENew); |
7408 | if (theOEOrigins.IsBound(aENew)) { |
7409 | TopTools_ListOfShape& aENewOrigins = theOEOrigins.ChangeFind(aENew); |
7410 | AppendToList(aENewOrigins, aEOr); |
7411 | } |
7412 | else { |
7413 | TopTools_ListOfShape aENewOrigins; |
7414 | aENewOrigins.Append(aEOr); |
7415 | theOEOrigins.Bind(aENew, aENewOrigins); |
7416 | } |
7417 | } |
7418 | } |
7419 | } |
7420 | else { |
7421 | // add to images |
7422 | theOEImages.Bind(aEOld, aLENew); |
7423 | // |
7424 | theModifiedEdges.Add(aEOld); |
7425 | // |
7426 | // add to origins |
7427 | TopTools_ListIteratorOfListOfShape aItNew(aLENew); |
7428 | for (; aItNew.More(); aItNew.Next()) { |
7429 | const TopoDS_Shape& aENew = aItNew.Value(); |
7430 | if (theOEOrigins.IsBound(aENew)) { |
7431 | TopTools_ListOfShape& aEOrigins = theOEOrigins.ChangeFind(aENew); |
7432 | AppendToList(aEOrigins, aEOld); |
7433 | } |
7434 | else { |
7435 | TopTools_ListOfShape aEOrigins; |
7436 | aEOrigins.Append(aEOld); |
7437 | theOEOrigins.Bind(aENew, aEOrigins); |
7438 | } |
7439 | } |
7440 | } |
7441 | // |
7442 | // update connection to initial shape |
7443 | if (theEdgesOrigins.IsBound(aEOld)) { |
7444 | const TopTools_ListOfShape& aLEOrInit = theEdgesOrigins.Find(aEOld); |
7445 | TopTools_ListIteratorOfListOfShape aItEOrInit(aLEOrInit); |
7446 | for (; aItEOrInit.More(); aItEOrInit.Next()) { |
7447 | const TopoDS_Shape& aEOrInit = aItEOrInit.Value(); |
7448 | AppendToList(anInitOrigins, aEOrInit); |
7449 | } |
7450 | } |
7451 | } |
7452 | // |
7453 | if (anInitOrigins.Extent()) { |
7454 | TopTools_ListIteratorOfListOfShape aItNew(aLENew); |
7455 | for (; aItNew.More(); aItNew.Next()) { |
7456 | const TopoDS_Shape& aENew = aItNew.Value(); |
7457 | if (theEdgesOrigins.IsBound(aENew)) { |
7458 | TopTools_ListOfShape& aLENewOr = theEdgesOrigins.ChangeFind(aENew); |
7459 | TopTools_ListIteratorOfListOfShape aItOrInit(anInitOrigins); |
7460 | for (; aItOrInit.More(); aItOrInit.Next()) { |
7461 | const TopoDS_Shape& aEOr = aItOrInit.Value(); |
7462 | AppendToList(aLENewOr, aEOr); |
7463 | } |
7464 | } |
7465 | else { |
7466 | theEdgesOrigins.Bind(aENew, anInitOrigins); |
7467 | } |
7468 | } |
7469 | } |
7470 | } |
7471 | } |
7472 | |
2ebb1098 |
7473 | //======================================================================= |
7474 | //function : FillGaps |
7475 | //purpose : Fill possible gaps (holes) in the splits of the offset faces |
7476 | //======================================================================= |
7477 | void FillGaps(TopTools_IndexedDataMapOfShapeListOfShape& theFImages) |
7478 | { |
7479 | Standard_Integer aNbF = theFImages.Extent(); |
7480 | if (!aNbF) |
7481 | return; |
7482 | |
7483 | // Check the splits of offset faces on the free edges and fill the gaps (holes) |
7484 | // in created splits, otherwise the closed volume will not be possible to create. |
7485 | |
7486 | // Map the splits of faces to find free edges |
7487 | TopTools_IndexedDataMapOfShapeListOfShape anEFMap; |
7488 | for (Standard_Integer i = 1; i <= aNbF; ++i) |
7489 | { |
7490 | TopTools_ListIteratorOfListOfShape itLF(theFImages(i)); |
7491 | for (; itLF.More(); itLF.Next()) |
7492 | TopExp::MapShapesAndAncestors(itLF.Value(), TopAbs_EDGE, TopAbs_FACE, anEFMap); |
7493 | } |
7494 | |
7495 | // Analyze images of each offset face on the presence of free edges |
7496 | // and try to fill the holes |
7497 | for (Standard_Integer i = 1; i <= aNbF; ++i) |
7498 | { |
7499 | TopTools_ListOfShape& aLFImages = theFImages(i); |
7500 | if (aLFImages.IsEmpty()) |
7501 | continue; |
7502 | |
7503 | // Collect all edges from the splits |
7504 | TopoDS_Compound anEdges; |
7505 | BRep_Builder().MakeCompound(anEdges); |
7506 | |
7507 | // Collect all free edges into a map with reverted orientation |
7508 | TopTools_MapOfOrientedShape aFreeEdgesMap; |
7509 | TopTools_ListIteratorOfListOfShape itLF(aLFImages); |
7510 | for (; itLF.More(); itLF.Next()) |
7511 | { |
7512 | const TopoDS_Shape& aFIm = itLF.Value(); |
7513 | TopExp_Explorer anExpE(aFIm, TopAbs_EDGE); |
7514 | for (; anExpE.More(); anExpE.Next()) |
7515 | { |
7516 | const TopoDS_Shape& aE = anExpE.Current(); |
7517 | if (aE.Orientation() != TopAbs_FORWARD && |
7518 | aE.Orientation() != TopAbs_REVERSED) |
7519 | // Skip internals |
7520 | continue; |
7521 | |
7522 | const TopTools_ListOfShape& aLF = anEFMap.FindFromKey(aE); |
7523 | if (aLF.Extent() == 1) |
7524 | aFreeEdgesMap.Add(aE.Reversed()); |
7525 | |
7526 | BRep_Builder().Add(anEdges, aE); |
7527 | } |
7528 | } |
7529 | |
7530 | if (aFreeEdgesMap.IsEmpty()) |
7531 | // No free edges |
7532 | continue; |
7533 | |
7534 | // Free edges are found - fill the gaps by creating new splits |
7535 | // of the face using these free edges |
7536 | const TopoDS_Shape& aF = theFImages.FindKey(i); |
7537 | |
7538 | // Build new splits using all kept edges and among new splits |
7539 | // find those containing free edges |
7540 | TopTools_ListOfShape aLFNew; |
7541 | TopTools_DataMapOfShapeShape aDummy; |
7542 | |
7543 | BuildSplitsOfFace(TopoDS::Face(aF), anEdges, aDummy, aLFNew); |
7544 | |
7545 | // Find faces filling holes |
7546 | itLF.Initialize(aLFNew); |
7547 | for (; itLF.More(); itLF.Next()) |
7548 | { |
7549 | const TopoDS_Shape& aFNew = itLF.Value(); |
7550 | TopExp_Explorer anExpE(aFNew, TopAbs_EDGE); |
7551 | for (; anExpE.More(); anExpE.Next()) |
7552 | { |
7553 | const TopoDS_Shape& aE = anExpE.Current(); |
7554 | if (aFreeEdgesMap.Contains(aE)) |
7555 | { |
7556 | // Add face to splits |
7557 | aLFImages.Append(aFNew); |
7558 | break; |
7559 | } |
7560 | } |
7561 | } |
7562 | } |
7563 | } |
7564 | |
ecf4f17c |
7565 | //======================================================================= |
7566 | //function : FillHistory |
7567 | //purpose : Saving obtained results in history tools |
7568 | //======================================================================= |
7569 | void FillHistory(const TopTools_IndexedDataMapOfShapeListOfShape& theFImages, |
7570 | const TopTools_DataMapOfShapeListOfShape& theEImages, |
7571 | BRepAlgo_Image& theImage) |
7572 | { |
2ebb1098 |
7573 | Standard_Integer aNbF = theFImages.Extent(); |
7574 | if (!aNbF) |
ecf4f17c |
7575 | return; |
2ebb1098 |
7576 | |
7577 | #ifdef OFFSET_DEBUG |
7578 | // Build compound of faces to see preliminary result |
7579 | TopoDS_Compound aDFaces; |
7580 | BRep_Builder().MakeCompound(aDFaces); |
7581 | #endif |
7582 | |
7583 | // Map of kept edges |
7584 | TopTools_IndexedMapOfShape anEdgesMap; |
7585 | |
ecf4f17c |
7586 | // Fill history for faces |
2ebb1098 |
7587 | for (Standard_Integer i = 1; i <= aNbF; ++i) |
7588 | { |
ecf4f17c |
7589 | const TopTools_ListOfShape& aLFImages = theFImages(i); |
2ebb1098 |
7590 | if (aLFImages.IsEmpty()) |
7591 | continue; |
7592 | |
7593 | // Add the splits to history map |
7594 | const TopoDS_Shape& aF = theFImages.FindKey(i); |
7595 | if (theImage.HasImage(aF)) |
7596 | theImage.Add(aF, aLFImages); |
7597 | else |
7598 | theImage.Bind(aF, aLFImages); |
7599 | |
7600 | // Collect edges from splits |
7601 | TopTools_ListIteratorOfListOfShape itLF(aLFImages); |
7602 | for (; itLF.More(); itLF.Next()) |
7603 | { |
7604 | const TopoDS_Shape& aFIm = itLF.Value(); |
7605 | TopExp::MapShapes(aFIm, TopAbs_EDGE, anEdgesMap); |
7606 | |
7607 | #ifdef OFFSET_DEBUG |
7608 | BRep_Builder().Add(aDFaces, aFIm); |
7609 | #endif |
ecf4f17c |
7610 | } |
7611 | } |
2ebb1098 |
7612 | |
7613 | // Fill history for edges (iteration by the map is safe because the |
7614 | // order is not important here) |
ecf4f17c |
7615 | TopTools_DataMapIteratorOfDataMapOfShapeListOfShape aItEIm(theEImages); |
2ebb1098 |
7616 | for (; aItEIm.More(); aItEIm.Next()) |
7617 | { |
ecf4f17c |
7618 | const TopoDS_Shape& aE = aItEIm.Key(); |
7619 | const TopTools_ListOfShape& aLEIm = aItEIm.Value(); |
2ebb1098 |
7620 | |
ecf4f17c |
7621 | Standard_Boolean bHasImage = theImage.HasImage(aE); |
7622 | TopTools_ListIteratorOfListOfShape aItLE(aLEIm); |
2ebb1098 |
7623 | for (; aItLE.More(); aItLE.Next()) |
7624 | { |
ecf4f17c |
7625 | const TopoDS_Shape& aEIm = aItLE.Value(); |
2ebb1098 |
7626 | if (anEdgesMap.Contains(aEIm)) |
7627 | { |
7628 | if (bHasImage) |
7629 | { |
ecf4f17c |
7630 | theImage.Add(aE, aEIm); |
7631 | } |
2ebb1098 |
7632 | else |
7633 | { |
ecf4f17c |
7634 | theImage.Bind(aE, aEIm); |
7635 | bHasImage = Standard_True; |
7636 | } |
7637 | } |
7638 | } |
7639 | } |
7640 | } |
7641 | |
7642 | //======================================================================= |
7643 | //function : ProcessMicroEdge |
7644 | //purpose : Checking if the edge is micro edge |
7645 | //======================================================================= |
7646 | Standard_Boolean ProcessMicroEdge(const TopoDS_Edge& theEdge, |
7647 | const Handle(IntTools_Context)& theCtx) |
7648 | { |
7649 | TopoDS_Vertex aV1, aV2; |
7650 | TopExp::Vertices(theEdge, aV1, aV2); |
7651 | if (aV1.IsNull() || aV2.IsNull()) { |
7652 | return Standard_False; |
7653 | } |
7654 | // |
7655 | Standard_Boolean bMicro = BOPTools_AlgoTools::IsMicroEdge(theEdge, theCtx); |
7656 | if (bMicro && BRepAdaptor_Curve(theEdge).GetType() == GeomAbs_Line) { |
7657 | Standard_Real aLen = BRep_Tool::Pnt(aV1).Distance(BRep_Tool::Pnt(aV2)); |
7658 | BRep_Builder().UpdateVertex(aV1, aLen / 2.); |
7659 | BRep_Builder().UpdateVertex(aV2, aLen / 2.); |
7660 | } |
7661 | // |
7662 | return bMicro; |
7663 | } |
7664 | |
7665 | //======================================================================= |
7666 | //function : UpdateOrigins |
7667 | //purpose : Updating origins |
7668 | //======================================================================= |
7669 | void UpdateOrigins(const TopTools_ListOfShape& theLA, |
7670 | TopTools_DataMapOfShapeListOfShape& theOrigins, |
7671 | BOPAlgo_Builder& theGF) |
7672 | { |
7673 | TopTools_ListIteratorOfListOfShape aItA(theLA); |
7674 | for (; aItA.More(); aItA.Next()) { |
7675 | const TopoDS_Shape& aS = aItA.Value(); |
7676 | // |
7677 | const TopTools_ListOfShape& aLSIm = theGF.Modified(aS); |
7678 | if (aLSIm.IsEmpty()) { |
7679 | continue; |
7680 | } |
7681 | // |
7682 | TopTools_ListOfShape aLSEmpt; |
7683 | TopTools_ListOfShape *pLS = theOrigins.ChangeSeek(aS); |
7684 | if (!pLS) { |
7685 | pLS = &aLSEmpt; |
7686 | pLS->Append(aS); |
7687 | } |
7688 | // |
7689 | TopTools_ListIteratorOfListOfShape aIt(aLSIm); |
7690 | for (; aIt.More(); aIt.Next()) { |
7691 | const TopoDS_Shape& aSIm = aIt.Value(); |
7692 | // |
7693 | TopTools_ListOfShape *pLSOr = theOrigins.ChangeSeek(aSIm); |
7694 | if (!pLSOr) { |
7695 | // just bind the origins |
7696 | theOrigins.Bind(aSIm, *pLS); |
7697 | } |
7698 | else { |
7699 | // merge two lists |
7700 | TopTools_ListIteratorOfListOfShape aIt1(*pLS); |
7701 | for (; aIt1.More(); aIt1.Next()) { |
7702 | const TopoDS_Shape& aS1 = aIt1.Value(); |
7703 | AppendToList(*pLSOr, aS1); |
7704 | } |
7705 | } |
7706 | } |
7707 | } |
7708 | } |
7709 | |
7710 | //======================================================================= |
7711 | //function : UpdateImages |
7712 | //purpose : Updating images of the shapes |
7713 | //======================================================================= |
7714 | void UpdateImages(const TopTools_ListOfShape& theLA, |
7715 | TopTools_DataMapOfShapeListOfShape& theImages, |
7716 | BOPAlgo_Builder& theGF, |
7717 | TopTools_MapOfShape& theModified) |
7718 | { |
7719 | TopTools_ListIteratorOfListOfShape aIt(theLA); |
e08a9b03 |
7720 | for (; aIt.More(); aIt.Next()) |
7721 | { |
ecf4f17c |
7722 | const TopoDS_Shape& aS = aIt.Value(); |
7723 | // |
7724 | TopTools_ListOfShape* pLSIm = theImages.ChangeSeek(aS); |
e08a9b03 |
7725 | if (!pLSIm) |
7726 | { |
ecf4f17c |
7727 | const TopTools_ListOfShape& aLSIm = theGF.Modified(aS); |
e08a9b03 |
7728 | if (aLSIm.Extent()) |
7729 | { |
ecf4f17c |
7730 | theImages.Bind(aS, aLSIm); |
7731 | theModified.Add(aS); |
7732 | } |
7733 | continue; |
7734 | } |
7735 | // |
7736 | TopTools_MapOfShape aMFence; |
7737 | TopTools_ListOfShape aLSImNew; |
7738 | // |
7739 | Standard_Boolean bModified = Standard_False; |
7740 | // |
7741 | // check modifications of the images |
7742 | TopTools_ListIteratorOfListOfShape aIt1(*pLSIm); |
e08a9b03 |
7743 | for (; aIt1.More(); aIt1.Next()) |
7744 | { |
ecf4f17c |
7745 | const TopoDS_Shape& aSIm = aIt1.Value(); |
e08a9b03 |
7746 | bModified |= TakeModified(aSIm, theGF.Images(), aLSImNew, &aMFence); |
ecf4f17c |
7747 | } |
7748 | // |
e08a9b03 |
7749 | if (bModified) |
7750 | { |
ecf4f17c |
7751 | *pLSIm = aLSImNew; |
7752 | theModified.Add(aS); |
7753 | } |
7754 | } |
7755 | } |
7756 | |
7757 | //======================================================================= |
7758 | //function : UpdateIntersectedEdges |
7759 | //purpose : Saving connection from trimmed edges to not trimmed ones |
7760 | //======================================================================= |
7761 | void UpdateIntersectedEdges(const TopTools_ListOfShape& theLA, |
7762 | TopTools_DataMapOfShapeShape& theETrimEInf, |
7763 | BOPAlgo_Builder& theGF) |
7764 | { |
7765 | TopTools_ListIteratorOfListOfShape aItA(theLA); |
7766 | for (; aItA.More(); aItA.Next()) { |
7767 | const TopoDS_Shape& aS = aItA.Value(); |
7768 | // |
7769 | const TopoDS_Shape* pEInf = theETrimEInf.Seek(aS); |
7770 | if (!pEInf) { |
7771 | continue; |
7772 | } |
7773 | // |
7774 | const TopTools_ListOfShape& aLSIm = theGF.Modified(aS); |
7775 | if (aLSIm.IsEmpty()) { |
7776 | continue; |
7777 | } |
7778 | // |
7779 | TopTools_ListIteratorOfListOfShape aIt(aLSIm); |
7780 | for (; aIt.More(); aIt.Next()) { |
7781 | const TopoDS_Shape& aEIm = aIt.Value(); |
7782 | if (!theETrimEInf.IsBound(aEIm)) { |
7783 | theETrimEInf.Bind(aEIm, *pEInf); |
7784 | } |
7785 | } |
7786 | } |
7787 | } |
7788 | |
7789 | //======================================================================= |
7790 | //function : FindCommonParts |
7791 | //purpose : Looking for the parts of type <theType> contained in both lists |
7792 | //======================================================================= |
7793 | void FindCommonParts(const TopTools_ListOfShape& theLS1, |
7794 | const TopTools_ListOfShape& theLS2, |
7795 | TopTools_ListOfShape& theLSC, |
7796 | const TopAbs_ShapeEnum theType) |
7797 | { |
7798 | // map shapes in the first list |
7799 | TopTools_IndexedMapOfShape aMS1; |
7800 | TopTools_ListIteratorOfListOfShape aIt(theLS1); |
7801 | for (; aIt.More(); aIt.Next()) { |
7802 | const TopoDS_Shape& aS = aIt.Value(); |
7803 | TopExp::MapShapes(aS, theType, aMS1); |
7804 | } |
7805 | // |
7806 | if (aMS1.IsEmpty()) { |
7807 | return; |
7808 | } |
7809 | // |
7810 | TopTools_MapOfShape aMFence; |
7811 | // check for such shapes in the other list |
7812 | aIt.Initialize(theLS2); |
7813 | for (; aIt.More(); aIt.Next()) { |
7814 | const TopoDS_Shape& aS = aIt.Value(); |
7815 | // |
7816 | TopExp_Explorer aExp(aS, theType); |
7817 | for(; aExp.More(); aExp.Next()) { |
7818 | const TopoDS_Shape& aST = aExp.Current(); |
7819 | // |
7820 | if (aMS1.Contains(aST) && aMFence.Add(aST)) { |
7821 | theLSC.Append(aST); |
7822 | } |
7823 | } |
7824 | } |
7825 | } |
7826 | |
7827 | //======================================================================= |
7828 | //function : NbPoints |
7829 | //purpose : Defines number of sample points to get average direction of the edge |
7830 | //======================================================================= |
7831 | Standard_Integer NbPoints(const TopoDS_Edge& theEdge) |
7832 | { |
7833 | Standard_Integer aNbP; |
7834 | BRepAdaptor_Curve aBAC(theEdge); |
7835 | switch (aBAC.GetType()) { |
7836 | case GeomAbs_Line: |
7837 | aNbP = 1; |
7838 | break; |
7839 | default: |
7840 | aNbP = 11; |
7841 | } |
7842 | // |
7843 | return aNbP; |
7844 | } |
7845 | |
7846 | //======================================================================= |
7847 | //function : FindShape |
7848 | //purpose : Looking for the same sub-shape in the shape |
7849 | //======================================================================= |
7850 | Standard_Boolean FindShape(const TopoDS_Shape& theSWhat, |
7851 | const TopoDS_Shape& theSWhere, |
420b38fd |
7852 | const BRepOffset_Analyse* theAnalyse, |
ecf4f17c |
7853 | TopoDS_Shape& theRes) |
7854 | { |
7855 | Standard_Boolean bFound = Standard_False; |
7856 | TopAbs_ShapeEnum aType = theSWhat.ShapeType(); |
7857 | TopExp_Explorer aExp(theSWhere, aType); |
7858 | for (; aExp.More(); aExp.Next()) { |
7859 | const TopoDS_Shape& aS = aExp.Current(); |
7860 | if (aS.IsSame(theSWhat)) { |
7861 | theRes = aS; |
7862 | bFound = Standard_True; |
7863 | break; |
7864 | } |
7865 | } |
420b38fd |
7866 | |
7867 | if (!bFound && theAnalyse) |
7868 | { |
7869 | const TopTools_ListOfShape *pLD = theAnalyse->Descendants (theSWhere); |
7870 | if (pLD) |
7871 | { |
7872 | for (TopTools_ListOfShape::Iterator it (*pLD); it.More(); it.Next()) |
7873 | { |
7874 | const TopoDS_Shape& aS = it.Value(); |
7875 | if (aS.IsSame (theSWhat)) |
7876 | { |
7877 | theRes = aS; |
7878 | bFound = Standard_True; |
7879 | break; |
7880 | } |
7881 | } |
7882 | } |
7883 | } |
7884 | |
ecf4f17c |
7885 | return bFound; |
7886 | } |
7887 | |
7888 | |
7889 | //======================================================================= |
7890 | //function : AppendToList |
7891 | //purpose : Add to a list only unique elements |
7892 | //======================================================================= |
7893 | void AppendToList(TopTools_ListOfShape& theList, |
7894 | const TopoDS_Shape& theShape) |
7895 | { |
7896 | TopTools_ListIteratorOfListOfShape aIt(theList); |
7897 | for (; aIt.More(); aIt.Next()) { |
7898 | const TopoDS_Shape& aS = aIt.Value(); |
7899 | if (aS.IsSame(theShape)) { |
7900 | return; |
7901 | } |
7902 | } |
7903 | theList.Append(theShape); |
7904 | } |
e08a9b03 |
7905 | |
7906 | //======================================================================= |
7907 | //function : AddToContainer |
7908 | //purpose : Set of methods to add a shape into container |
7909 | //======================================================================= |
7910 | static void AddToContainer(const TopoDS_Shape& theS, |
7911 | TopTools_ListOfShape& theList) |
7912 | { |
7913 | theList.Append(theS); |
7914 | } |
7915 | static Standard_Boolean AddToContainer(const TopoDS_Shape& theS, |
7916 | TopTools_MapOfShape& theMap) |
7917 | { |
7918 | return theMap.Add(theS); |
7919 | } |
7920 | static Standard_Boolean AddToContainer(const TopoDS_Shape& theS, |
7921 | TopTools_IndexedMapOfShape& theMap) |
7922 | { |
7923 | const Standard_Integer aNb = theMap.Extent(); |
7924 | const Standard_Integer anInd = theMap.Add(theS); |
7925 | return anInd > aNb; |
7926 | } |
7927 | static void AddToContainer(const TopoDS_Shape& theS, |
7928 | TopoDS_Shape& theSOut) |
7929 | { |
7930 | BRep_Builder().Add(theSOut, theS); |
7931 | } |
7932 | |
7933 | //======================================================================= |
7934 | //function : TakeModified |
7935 | //purpose : Check if the shape has images in the given images map. |
7936 | // Puts in the output map either the images or the shape itself. |
7937 | //======================================================================= |
7938 | template <class ContainerType, class FenceMapType> |
7939 | Standard_Boolean TakeModified(const TopoDS_Shape& theS, |
7940 | const TopTools_DataMapOfShapeListOfShape& theImages, |
7941 | ContainerType& theContainer, |
7942 | FenceMapType* theMFence) |
7943 | { |
7944 | const TopTools_ListOfShape *pLSIm = theImages.Seek(theS); |
7945 | if (pLSIm) |
7946 | { |
7947 | TopTools_ListIteratorOfListOfShape itLSIm(*pLSIm); |
7948 | for (; itLSIm.More(); itLSIm.Next()) |
7949 | { |
7950 | const TopoDS_Shape& aSIm = itLSIm.Value(); |
7951 | if (!theMFence || AddToContainer(aSIm, *theMFence)) |
7952 | AddToContainer(aSIm, theContainer); |
7953 | } |
7954 | return Standard_True; |
7955 | } |
7956 | else |
7957 | { |
7958 | if (!theMFence || AddToContainer(theS, *theMFence)) |
7959 | AddToContainer(theS, theContainer); |
7960 | return Standard_False; |
7961 | } |
7962 | } |