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 | |
33 | #include <BRepTools.hxx> |
34 | |
35 | #include <BRepAdaptor_Curve.hxx> |
36 | |
37 | #include <TopExp.hxx> |
38 | #include <TopExp_Explorer.hxx> |
39 | |
40 | #include <TopTools_DataMapOfShapeInteger.hxx> |
41 | |
42 | #include <BRepOffset_Tool.hxx> |
43 | |
44 | #include <BRepClass3d_SolidClassifier.hxx> |
45 | |
46 | #include <BOPDS_DS.hxx> |
47 | |
48 | #include <BOPAlgo_PaveFiller.hxx> |
49 | #include <BOPAlgo_Builder.hxx> |
50 | #include <BOPAlgo_Section.hxx> |
51 | #include <BOPAlgo_MakerVolume.hxx> |
a8232603 |
52 | #include <BOPAlgo_BuilderFace.hxx> |
ecf4f17c |
53 | |
54 | #include <BOPCol_ListOfShape.hxx> |
55 | #include <BOPCol_DataMapOfShapeShape.hxx> |
56 | #include <BOPCol_IndexedDataMapOfShapeListOfShape.hxx> |
57 | |
58 | #include <BOPTools.hxx> |
59 | #include <BOPTools_AlgoTools3D.hxx> |
60 | #include <BOPTools_AlgoTools.hxx> |
a8232603 |
61 | #include <BOPTools_AlgoTools2D.hxx> |
ecf4f17c |
62 | |
63 | #include <IntTools_Context.hxx> |
64 | #include <IntTools_ShrunkRange.hxx> |
65 | |
66 | |
67 | static |
68 | void IntersectTrimmedEdges(const TopTools_ListOfShape& theLF, |
69 | const Handle(BRepAlgo_AsDes)& theAsDes, |
70 | TopTools_DataMapOfShapeListOfShape& theOEImages, |
71 | TopTools_DataMapOfShapeListOfShape& theOEOrigins, |
72 | TopTools_DataMapOfShapeListOfShape& theEdgesOrigins, |
73 | Handle(IntTools_Context)& theCtx, |
74 | TopTools_MapOfShape& theNewEdges, |
75 | TopTools_DataMapOfShapeShape& theETrimEInf); |
76 | |
77 | static |
78 | Standard_Boolean GetEdges(const TopoDS_Face& theFace, |
79 | const Handle(BRepAlgo_AsDes)& theAsDes, |
80 | const TopTools_DataMapOfShapeListOfShape& theEImages, |
81 | const TopTools_MapOfShape& theLastInvEdges, |
82 | const TopTools_IndexedMapOfShape& theInvEdges, |
83 | Handle(IntTools_Context)& theCtx, |
84 | const TopTools_MapOfShape& theModifiedEdges, |
85 | TopoDS_Shape& theEdges, |
86 | TopTools_IndexedMapOfShape& theInv); |
87 | |
a8232603 |
88 | static |
89 | void BuildSplitsOfTrimmedFace(const TopoDS_Face& theFace, |
90 | const TopoDS_Shape& theEdges, |
91 | TopTools_ListOfShape& theLFImages); |
92 | |
ecf4f17c |
93 | static |
94 | void BuildSplitsOfFace(const TopoDS_Face& theFace, |
95 | const TopoDS_Shape& theEdges, |
ecf4f17c |
96 | TopTools_DataMapOfShapeShape& theOrigins, |
97 | TopTools_ListOfShape& theLFImages); |
98 | |
99 | static |
100 | void BuildSplitsOfFaces(const TopTools_ListOfShape& theLF, |
101 | const TopTools_MapOfShape& theModifiedEdges, |
102 | const TopTools_DataMapOfShapeListOfShape& theEdgesOrigins, |
103 | Handle(BRepAlgo_AsDes)& theAsDes, |
104 | TopTools_DataMapOfShapeShape& theFacesOrigins, |
105 | TopTools_DataMapOfShapeListOfShape& theOEImages, |
106 | TopTools_DataMapOfShapeListOfShape& theOEOrigins, |
107 | TopTools_MapOfShape& theLastInvEdges, |
108 | TopTools_IndexedMapOfShape& theEdgesToAvoid, |
109 | TopTools_IndexedMapOfShape& theInvEdges, |
110 | TopTools_IndexedMapOfShape& theValidEdges, |
111 | TopTools_MapOfShape& theInvertedEdges, |
112 | TopTools_DataMapOfShapeInteger& theAlreadyInvFaces, |
113 | TopTools_IndexedDataMapOfShapeListOfShape& theInvFaces, |
114 | TopTools_DataMapOfShapeShape& theArtInvFaces, |
115 | TopTools_IndexedDataMapOfShapeListOfShape& theFImages, |
116 | TopoDS_Shape& theSolids, |
117 | TopTools_DataMapOfShapeListOfShape& theSSInterfs); |
118 | |
119 | static |
120 | void BuildSplitsOfInvFaces(const TopTools_IndexedDataMapOfShapeListOfShape& theFToRebuild, |
121 | const TopTools_MapOfShape& theModifiedEdges, |
122 | TopTools_IndexedDataMapOfShapeListOfShape& theFImages, |
123 | TopTools_DataMapOfShapeListOfShape& theEdgesOrigins, |
124 | TopTools_DataMapOfShapeShape& theFacesOrigins, |
125 | TopTools_DataMapOfShapeListOfShape& theOEImages, |
126 | TopTools_DataMapOfShapeListOfShape& theOEOrigins, |
127 | TopTools_MapOfShape& theLastInvEdges, |
128 | TopTools_IndexedMapOfShape& theEdgesToAvoid, |
129 | TopTools_MapOfShape& theVertsToAvoid, |
130 | TopTools_DataMapOfShapeInteger& theAlreadyInvFaces, |
131 | TopTools_IndexedMapOfShape& theValidEdges, |
132 | TopTools_DataMapOfShapeShape& theETrimEInf, |
133 | Handle(BRepAlgo_AsDes)& theAsDes); |
134 | |
135 | static |
136 | Standard_Boolean CheckIfArtificial(const TopoDS_Shape& theF, |
137 | const TopTools_ListOfShape& theLFImages, |
138 | const TopoDS_Shape& theCE, |
139 | const TopTools_IndexedMapOfShape& theMapEInv, |
140 | const TopTools_DataMapOfShapeListOfShape& theOEImages, |
141 | TopTools_MapOfShape& theMENInv, |
142 | Handle(BRepAlgo_AsDes)& theAsDes); |
143 | |
144 | static |
145 | void FindInvalidEdges(const TopoDS_Face& theF, |
146 | const TopTools_ListOfShape& theLFImages, |
147 | const TopTools_DataMapOfShapeListOfShape& theEdgesOrigins, |
148 | const TopTools_DataMapOfShapeShape& theFacesOrigins, |
149 | const TopTools_DataMapOfShapeListOfShape& theOEImages, |
150 | const TopTools_DataMapOfShapeListOfShape& theOEOrigins, |
151 | TopTools_IndexedMapOfShape& theInvEdges, |
152 | TopTools_IndexedMapOfShape& theValidEdges, |
153 | TopTools_DataMapOfShapeListOfShape& theDMFLVE, |
154 | TopTools_DataMapOfShapeListOfShape& theDMFLNE, |
155 | TopTools_DataMapOfShapeListOfShape& theDMFLIE, |
156 | TopTools_DataMapOfShapeListOfShape& theDMFLVIE, |
157 | TopTools_MapOfShape& theMEInverted, |
158 | TopTools_MapOfShape& theEdgesInvalidByVertex); |
159 | |
160 | static |
161 | void FindInvalidFaces(TopTools_ListOfShape& theLFImages, |
162 | const TopTools_IndexedMapOfShape& theInvEdges, |
163 | const TopTools_IndexedMapOfShape& theValidEdges, |
164 | const TopTools_DataMapOfShapeListOfShape& theDMFLVE, |
165 | const TopTools_DataMapOfShapeListOfShape& theDMFLIE, |
166 | const TopTools_ListOfShape& theLENeutral, |
167 | const TopTools_ListOfShape& theLEValInverted, |
168 | const TopTools_MapOfShape& theMEInverted, |
169 | const TopTools_MapOfShape& theEdgesInvalidByVertex, |
170 | TopTools_ListOfShape& theInvFaces); |
171 | |
172 | static |
173 | gp_Vec GetAverageTangent(const TopoDS_Shape& theS, |
174 | const Standard_Integer theNbP); |
175 | |
176 | static |
177 | Standard_Boolean CheckInverted(const TopoDS_Edge& theEIm, |
178 | const TopoDS_Face& theFOr, |
179 | const TopTools_DataMapOfShapeListOfShape& theOEImages, |
180 | const TopTools_DataMapOfShapeListOfShape& theOEOrigins, |
181 | const TopTools_DataMapOfShapeListOfShape& theEdgesOrigins, |
182 | const TopTools_IndexedDataMapOfShapeListOfShape& theDMEF, |
183 | const TopTools_IndexedDataMapOfShapeListOfShape& theDMVE, |
184 | const TopTools_IndexedMapOfShape& theMEdges, |
185 | TopTools_MapOfShape& theMEInverted); |
186 | |
187 | |
188 | static |
189 | void RemoveInvalidSplitsByInvertedEdges(const TopTools_MapOfShape& theMEInverted, |
190 | TopTools_IndexedDataMapOfShapeListOfShape& theInvFaces, |
191 | TopTools_IndexedDataMapOfShapeListOfShape& theFImages, |
192 | TopTools_IndexedMapOfShape& theMERemoved); |
193 | |
194 | static |
195 | void RemoveInvalidSplitsFromValid(const TopTools_IndexedDataMapOfShapeListOfShape& theInvFaces, |
196 | const TopTools_DataMapOfShapeShape& theArtInvFaces, |
197 | const TopTools_MapOfShape& theMEInverted, |
198 | TopTools_IndexedDataMapOfShapeListOfShape& theFImages); |
199 | |
200 | static |
201 | void RemoveInsideFaces(TopTools_IndexedDataMapOfShapeListOfShape& theFImages, |
202 | TopTools_IndexedDataMapOfShapeListOfShape& theInvFaces, |
203 | const TopTools_DataMapOfShapeShape& theArtInvFaces, |
204 | const TopTools_IndexedMapOfShape& theInvEdges, |
205 | const TopTools_IndexedMapOfShape& theMFToCheckInt, |
206 | TopTools_DataMapOfShapeListOfShape& theSSInterfs, |
207 | TopTools_IndexedMapOfShape& theMERemoved, |
208 | TopoDS_Shape& theSolids); |
209 | |
210 | static |
211 | void ShapesConnections(const TopTools_IndexedDataMapOfShapeListOfShape& theInvFaces, |
212 | const TopTools_IndexedMapOfShape& theInvEdges, |
213 | const TopTools_DataMapOfShapeShape& theDMFOr, |
214 | BOPAlgo_Builder& theBuilder, |
215 | TopTools_DataMapOfShapeListOfShape& theSSInterfs); |
216 | |
217 | static |
218 | void RemoveValidSplits(const TopTools_MapOfShape& theSpRem, |
219 | TopTools_IndexedDataMapOfShapeListOfShape& theImages, |
220 | BOPAlgo_Builder& theGF, |
221 | TopTools_IndexedMapOfShape& theMERemoved); |
222 | |
223 | static |
224 | void RemoveInvalidSplits(const TopTools_MapOfShape& theSpRem, |
225 | const TopTools_DataMapOfShapeShape& theArtInvFaces, |
226 | const TopTools_IndexedMapOfShape& theInvEdges, |
227 | TopTools_IndexedDataMapOfShapeListOfShape& theImages, |
228 | BOPAlgo_Builder& theGF, |
229 | TopTools_IndexedMapOfShape& theMERemoved); |
230 | |
231 | static |
232 | void FilterEdgesImages(const TopoDS_Shape& theS, |
233 | TopTools_DataMapOfShapeListOfShape& theOEImages, |
234 | TopTools_DataMapOfShapeListOfShape& theOEOrigins); |
235 | |
236 | static |
237 | void FilterInvalidFaces(const TopTools_IndexedDataMapOfShapeListOfShape& theFImages, |
238 | const TopTools_IndexedDataMapOfShapeListOfShape& theDMFE, |
239 | TopTools_IndexedDataMapOfShapeListOfShape& theInvFaces, |
240 | TopTools_DataMapOfShapeShape& theArtInvFaces); |
241 | |
242 | static |
243 | void FilterInvalidEdges(const TopTools_IndexedDataMapOfShapeListOfShape& theInvFaces, |
244 | const TopTools_DataMapOfShapeShape& theArtInvFaces, |
245 | const TopTools_DataMapOfShapeListOfShape& theDMFLIE, |
246 | const TopTools_IndexedMapOfShape& theMERemoved, |
247 | TopTools_IndexedMapOfShape& theInvEdges); |
248 | |
249 | static |
250 | void FindFacesToRebuild(const TopTools_IndexedDataMapOfShapeListOfShape& theLFImages, |
251 | const TopTools_IndexedMapOfShape& theInvEdges, |
252 | const TopTools_IndexedDataMapOfShapeListOfShape& theInvFaces, |
253 | const TopTools_DataMapOfShapeListOfShape& theSSInterfs, |
254 | TopTools_IndexedDataMapOfShapeListOfShape& theFToRebuild, |
255 | TopTools_MapOfShape& theFSelfRebAvoid); |
256 | |
257 | static |
258 | void RebuildFaces(const TopTools_IndexedDataMapOfShapeListOfShape& theFToRebuild, |
259 | const TopTools_MapOfShape& theFSelfRebAvoid, |
260 | const TopoDS_Shape& theSolids, |
261 | const TopTools_DataMapOfShapeListOfShape& theSSInterfs, |
262 | TopTools_IndexedDataMapOfShapeListOfShape& theFImages, |
263 | TopTools_DataMapOfShapeListOfShape& theEdgesOrigins, |
264 | TopTools_DataMapOfShapeShape& theFacesOrigins, |
265 | TopTools_DataMapOfShapeListOfShape& theOEImages, |
266 | TopTools_DataMapOfShapeListOfShape& theOEOrigins, |
267 | TopTools_MapOfShape& theLastInvEdges, |
268 | TopTools_IndexedMapOfShape& theEdgesToAvoid, |
269 | TopTools_IndexedMapOfShape& theInvEdges, |
270 | TopTools_IndexedMapOfShape& theValidEdges, |
271 | const TopTools_MapOfShape& theInvertedEdges, |
272 | TopTools_DataMapOfShapeInteger& theAlreadyInvFaces, |
273 | TopTools_IndexedDataMapOfShapeListOfShape& theInvFaces, |
274 | const TopTools_DataMapOfShapeShape& theArtInvFaces, |
275 | TopTools_MapOfShape& theVertsToAvoid, |
276 | TopTools_DataMapOfShapeShape& theETrimEInf, |
277 | Handle(BRepAlgo_AsDes)& theAsDes); |
278 | |
279 | static |
280 | void IntersectFaces(const TopTools_IndexedDataMapOfShapeListOfShape& theFToRebuild, |
281 | const TopTools_MapOfShape& theFSelfRebAvoid, |
282 | const TopoDS_Shape& theSolids, |
283 | const TopTools_DataMapOfShapeListOfShape& theSSInterfs, |
284 | TopTools_IndexedDataMapOfShapeListOfShape& theFImages, |
285 | TopTools_DataMapOfShapeListOfShape& theEdgesOrigins, |
286 | TopTools_DataMapOfShapeListOfShape& theOEImages, |
287 | TopTools_DataMapOfShapeListOfShape& theOEOrigins, |
288 | TopTools_IndexedMapOfShape& theInvEdges, |
289 | TopTools_IndexedMapOfShape& theValidEdges, |
290 | const TopTools_MapOfShape& theInvertedEdges, |
291 | TopTools_IndexedMapOfShape& theEdgesToAvoid, |
292 | TopTools_IndexedDataMapOfShapeListOfShape& theInvFaces, |
293 | const TopTools_DataMapOfShapeShape& theArtInvFaces, |
294 | TopTools_MapOfShape& theVertsToAvoid, |
295 | TopTools_DataMapOfShapeShape& theETrimEInf, |
296 | TopTools_MapOfShape& theModifiedEdges, |
297 | Handle(BRepAlgo_AsDes)& theAsDes); |
298 | |
299 | static |
300 | void PrepareFacesForIntersection(const TopTools_IndexedDataMapOfShapeListOfShape& theFToRebuild, |
301 | const TopTools_IndexedDataMapOfShapeListOfShape& theFImages, |
302 | const TopTools_IndexedDataMapOfShapeListOfShape& theInvFaces, |
303 | const TopTools_DataMapOfShapeShape& theArtInvFaces, |
304 | const Standard_Boolean bLookVertToAvoid, |
305 | TopTools_IndexedDataMapOfShapeListOfShape& theFLE, |
306 | TopTools_DataMapOfShapeListOfShape& theMDone, |
307 | TopTools_DataMapOfShapeListOfShape& theDMSF, |
308 | TopTools_DataMapOfShapeListOfShape& theMEInfETrim, |
309 | TopTools_DataMapOfShapeListOfShape& theDMVEFull, |
310 | TopTools_DataMapOfShapeShape& theETrimEInf, |
311 | TopTools_IndexedDataMapOfShapeListOfShape& theDMEFInv); |
312 | |
313 | static |
314 | void FindVerticesToAvoid(const TopTools_IndexedDataMapOfShapeListOfShape& theDMEFInv, |
315 | const TopTools_IndexedMapOfShape& theInvEdges, |
316 | const TopTools_IndexedMapOfShape& theValidEdges, |
317 | TopTools_DataMapOfShapeListOfShape& theDMVEFull, |
318 | TopTools_MapOfShape& theMVRInv); |
319 | |
320 | static |
321 | void FindFacesForIntersection(const TopoDS_Shape& theFInv, |
322 | const TopTools_IndexedMapOfShape& theME, |
323 | const TopTools_IndexedDataMapOfShapeListOfShape& theFImages, |
324 | const TopTools_DataMapOfShapeListOfShape& theDMSF, |
325 | const TopTools_MapOfShape& theMVInvAll, |
326 | const TopTools_DataMapOfShapeShape& theArtInvFaces, |
327 | const Standard_Boolean theArtCase, |
328 | const TopTools_DataMapOfShapeListOfShape& theSSInterfs, |
329 | TopTools_IndexedMapOfShape& theMFAvoid, |
330 | TopTools_IndexedMapOfShape& theMFInt, |
331 | TopTools_IndexedMapOfShape& theMFIntExt, |
332 | TopTools_ListOfShape& theLFImInt); |
333 | |
334 | static |
335 | void ProcessCommonEdges(const TopTools_ListOfShape& theLEC, |
336 | const TopTools_IndexedMapOfShape& theInvEdges, |
337 | const TopTools_IndexedMapOfShape& theValidEdges, |
338 | const TopTools_IndexedMapOfShape& theME, |
339 | const TopTools_DataMapOfShapeShape& theETrimEInf, |
340 | const TopTools_DataMapOfShapeListOfShape& theMEInfETrim, |
341 | const TopTools_DataMapOfShapeListOfShape& theOEOrigins, |
41aa3c3d |
342 | const TopTools_MapOfShape& theAllInvs, |
ecf4f17c |
343 | const Standard_Boolean theForceUse, |
344 | TopTools_IndexedMapOfShape& theMECV, |
41aa3c3d |
345 | TopTools_MapOfShape& theMECheckExt, |
ecf4f17c |
346 | TopTools_DataMapOfShapeListOfShape& theDMEETrim, |
347 | TopTools_ListOfShape& theLFEi, |
348 | TopTools_ListOfShape& theLFEj, |
349 | TopTools_IndexedMapOfShape& theMEToInt); |
350 | |
351 | static |
352 | void UpdateIntersectedFaces(const TopoDS_Shape& theFInv, |
353 | const TopoDS_Shape& theFi, |
354 | const TopoDS_Shape& theFj, |
355 | const TopTools_ListOfShape& theLFInv, |
356 | const TopTools_ListOfShape& theLFImi, |
357 | const TopTools_ListOfShape& theLFImj, |
358 | const TopTools_ListOfShape& theLFEi, |
359 | const TopTools_ListOfShape& theLFEj, |
360 | TopTools_DataMapOfShapeListOfShape& theEdgesOrigins, |
361 | TopTools_IndexedMapOfShape& theMEToInt); |
362 | |
363 | static |
364 | void IntersectFaces(const TopoDS_Shape& theFInv, |
365 | const TopoDS_Shape& theFi, |
366 | const TopoDS_Shape& theFj, |
367 | const TopTools_ListOfShape& theLFInv, |
368 | const TopTools_ListOfShape& theLFImi, |
369 | const TopTools_ListOfShape& theLFImj, |
370 | TopTools_ListOfShape& theLFEi, |
371 | TopTools_ListOfShape& theLFEj, |
372 | TopTools_DataMapOfShapeListOfShape& theEdgesOrigins, |
373 | TopTools_IndexedMapOfShape& theMECV, |
374 | TopTools_IndexedMapOfShape& theMEToInt); |
375 | |
376 | static |
377 | void FindOrigins(const TopTools_ListOfShape& theLFIm1, |
378 | const TopTools_ListOfShape& theLFIm2, |
379 | const TopTools_IndexedMapOfShape& theME, |
380 | const TopTools_DataMapOfShapeListOfShape& theOrigins, |
381 | TopTools_ListOfShape& theLEOr); |
382 | |
383 | static |
384 | void IntersectAndTrimEdges(const TopTools_IndexedDataMapOfShapeListOfShape& theFToRebuild, |
385 | const TopTools_IndexedMapOfShape& theMFInt, |
386 | const TopTools_IndexedMapOfShape& theMEInt, |
387 | const TopTools_DataMapOfShapeListOfShape& theDMEETrim, |
388 | const TopTools_IndexedMapOfShape& theMSInv, |
389 | const TopTools_IndexedMapOfShape& theMVE, |
390 | const TopTools_MapOfShape& theVertsToAvoid, |
391 | const TopTools_MapOfShape& theNewVertsToAvoid, |
41aa3c3d |
392 | const TopTools_MapOfShape& theMECheckExt, |
ecf4f17c |
393 | TopTools_MapOfShape& theMVBounds, |
394 | TopTools_DataMapOfShapeListOfShape& theEImages); |
395 | |
396 | static |
397 | void GetInvalidEdges(const TopTools_MapOfShape& theVertsToAvoid, |
398 | const TopTools_MapOfShape& theMVBounds, |
399 | BOPAlgo_Builder& theGF, |
400 | TopTools_MapOfShape& theMEInv); |
401 | |
41aa3c3d |
402 | static |
403 | void UpdateValidEdges(const TopTools_IndexedDataMapOfShapeListOfShape& theFImages, |
ecf4f17c |
404 | const TopTools_IndexedDataMapOfShapeListOfShape& theFLE, |
405 | const TopTools_MapOfShape& theMVBounds, |
406 | const TopoDS_Shape& theSolids, |
407 | const TopTools_IndexedMapOfShape& theInvEdges, |
408 | const TopTools_MapOfShape& theInvertedEdges, |
a8232603 |
409 | const TopTools_MapOfShape& theMEInvOnArt, |
41aa3c3d |
410 | TopTools_MapOfShape& theMECheckExt, |
ecf4f17c |
411 | TopTools_IndexedMapOfShape& theEdgesToAvoid, |
412 | TopTools_DataMapOfShapeListOfShape& theEdgesOrigins, |
413 | TopTools_DataMapOfShapeListOfShape& theOEImages, |
414 | TopTools_DataMapOfShapeListOfShape& theOEOrigins, |
415 | TopTools_MapOfShape& theVertsToAvoid, |
416 | TopTools_DataMapOfShapeShape& theETrimEInf, |
417 | TopTools_DataMapOfShapeListOfShape& theEImages, |
418 | TopTools_DataMapOfShapeListOfShape& theEETrim, |
419 | TopTools_MapOfShape& theModifiedEdges, |
420 | Handle(BRepAlgo_AsDes)& theAsDes); |
421 | |
422 | static |
423 | void TrimNewIntersectionEdges(const TopTools_ListOfShape& theLE, |
424 | const TopTools_DataMapOfShapeListOfShape& theEETrim, |
425 | const TopTools_MapOfShape& theMVBounds, |
41aa3c3d |
426 | TopTools_MapOfShape& theMECheckExt, |
ecf4f17c |
427 | TopTools_DataMapOfShapeListOfShape& theEImages, |
428 | TopTools_MapOfShape& theMEB, |
429 | TopTools_MapOfShape& theMVOld, |
430 | TopTools_ListOfShape& theLENew, |
431 | BOPCol_ListOfShape& theLA, |
41aa3c3d |
432 | TopTools_DataMapOfShapeListOfShape& theDMEOr, |
433 | TopTools_DataMapOfShapeListOfShape& theMELF); |
ecf4f17c |
434 | |
435 | static |
436 | void IntersectEdges(const BOPCol_ListOfShape& theLA, |
437 | const TopTools_ListOfShape& theLE, |
438 | const TopTools_ListOfShape& theLENew, |
439 | const TopTools_MapOfShape& theMVBounds, |
440 | const TopTools_MapOfShape& theVertsToAvoid, |
41aa3c3d |
441 | TopTools_MapOfShape& theMECheckExt, |
ecf4f17c |
442 | TopTools_DataMapOfShapeListOfShape& theEImages, |
443 | TopTools_MapOfShape& theModifiedEdges, |
444 | TopTools_DataMapOfShapeListOfShape& theDMEOr, |
41aa3c3d |
445 | TopTools_DataMapOfShapeListOfShape& theMELF, |
ecf4f17c |
446 | TopTools_MapOfShape& theMENew, |
447 | TopoDS_Shape& theSplits); |
448 | |
449 | static |
450 | void GetBounds(const TopTools_IndexedDataMapOfShapeListOfShape& theFImages, |
451 | const TopTools_MapOfShape& theMEB, |
452 | TopoDS_Shape& theBounds); |
453 | |
454 | static |
455 | void GetBoundsToUpdate(const TopTools_ListOfShape& theLF, |
456 | const TopTools_DataMapOfShapeListOfShape& theOEImages, |
457 | const TopTools_DataMapOfShapeListOfShape& theOEOrigins, |
458 | const TopTools_MapOfShape& theMEB, |
459 | TopTools_ListOfShape& theLABounds, |
460 | TopTools_ListOfShape& theLAValid, |
461 | TopoDS_Shape& theBounds, |
462 | Handle(BRepAlgo_AsDes)& theAsDes); |
463 | |
464 | static |
465 | void GetInvalidEdgesByBounds(const TopoDS_Shape& theSplits, |
466 | const TopoDS_Shape& theBounds, |
ecf4f17c |
467 | const TopTools_IndexedDataMapOfShapeListOfShape& theFImages, |
468 | const TopoDS_Shape& theSolids, |
469 | const TopTools_IndexedMapOfShape& theInvEdges, |
470 | const TopTools_MapOfShape& theMVOld, |
471 | const TopTools_MapOfShape& theMENew, |
472 | const TopTools_DataMapOfShapeListOfShape& theDMEOr, |
41aa3c3d |
473 | const TopTools_DataMapOfShapeListOfShape& theMELF, |
ecf4f17c |
474 | const TopTools_DataMapOfShapeListOfShape& theEImages, |
41aa3c3d |
475 | const TopTools_MapOfShape& theMECheckExt, |
a8232603 |
476 | const TopTools_MapOfShape& theMEInvOnArt, |
ecf4f17c |
477 | TopTools_MapOfShape& theVertsToAvoid, |
478 | TopTools_MapOfShape& theMEInv); |
479 | |
480 | static |
481 | void UpdateNewIntersectionEdges(const TopTools_ListOfShape& theLE, |
482 | const TopTools_DataMapOfShapeListOfShape& theMELF, |
483 | const TopTools_DataMapOfShapeListOfShape& theEImages, |
484 | const TopTools_IndexedMapOfShape& theInvEdges, |
485 | const TopTools_MapOfShape& theInvertedEdges, |
486 | TopTools_DataMapOfShapeListOfShape& theEdgesOrigins, |
487 | TopTools_DataMapOfShapeListOfShape& theOEImages, |
488 | TopTools_DataMapOfShapeListOfShape& theOEOrigins, |
489 | TopTools_DataMapOfShapeShape& theETrimEInf, |
490 | TopTools_DataMapOfShapeListOfShape& theEETrim, |
491 | TopTools_MapOfShape& theModifiedEdges, |
492 | Handle(BRepAlgo_AsDes)& theAsDes); |
493 | |
494 | static |
495 | void FillHistory(const TopTools_IndexedDataMapOfShapeListOfShape& theFImages, |
496 | const TopTools_DataMapOfShapeListOfShape& theEImages, |
497 | BRepAlgo_Image& theImage); |
498 | |
499 | static |
500 | void UpdateOrigins(const TopTools_ListOfShape& theLA, |
501 | TopTools_DataMapOfShapeListOfShape& theOrigins, |
502 | BOPAlgo_Builder& theGF); |
503 | |
504 | static |
505 | void UpdateImages(const TopTools_ListOfShape& theLA, |
506 | TopTools_DataMapOfShapeListOfShape& theImages, |
507 | BOPAlgo_Builder& theGF, |
508 | TopTools_MapOfShape& theModified); |
509 | |
510 | static |
511 | void UpdateIntersectedEdges(const TopTools_ListOfShape& theLA, |
512 | TopTools_DataMapOfShapeShape& theETrimEInf, |
513 | BOPAlgo_Builder& theGF); |
514 | |
515 | static |
516 | Standard_Boolean ProcessMicroEdge(const TopoDS_Edge& theEdge, |
517 | const Handle(IntTools_Context)& theCtx); |
518 | |
519 | static |
520 | void FindCommonParts(const TopTools_ListOfShape& theLS1, |
521 | const TopTools_ListOfShape& theLS2, |
522 | TopTools_ListOfShape& theLSC, |
523 | const TopAbs_ShapeEnum theType = TopAbs_EDGE); |
524 | |
525 | static |
526 | Standard_Integer NbPoints(const TopoDS_Edge& theE); |
527 | |
528 | static |
529 | Standard_Boolean FindShape(const TopoDS_Shape& theSWhat, |
530 | const TopoDS_Shape& theSWhere, |
531 | TopoDS_Shape& theRes); |
532 | |
533 | static |
534 | void AppendToList(TopTools_ListOfShape& theL, |
535 | const TopoDS_Shape& theS); |
536 | |
537 | //======================================================================= |
538 | //function : BuildSplitsOfTrimmedFaces |
539 | //purpose : Building splits of already trimmed faces |
540 | //======================================================================= |
541 | void BRepOffset_MakeOffset::BuildSplitsOfTrimmedFaces(const TopTools_ListOfShape& theLF, |
542 | Handle(BRepAlgo_AsDes)& theAsDes, |
543 | BRepAlgo_Image& theImage) |
544 | { |
545 | TopTools_DataMapOfShapeListOfShape anEImages, anEOrigins; |
546 | TopTools_IndexedDataMapOfShapeListOfShape aDMFFIm; |
547 | TopTools_IndexedMapOfShape anEmptyIM; |
548 | TopTools_DataMapOfShapeListOfShape anEmptyDMSLS; |
549 | TopTools_DataMapOfShapeShape anEmptyDMSS; |
550 | TopTools_MapOfShape aNewEdges, anEmptyM; |
551 | // |
552 | // firstly it is necessary to fuse all the edges |
553 | Handle(IntTools_Context) aCtx = new IntTools_Context(); |
554 | // |
555 | IntersectTrimmedEdges(theLF, theAsDes, anEImages, anEOrigins, anEmptyDMSLS, aCtx, aNewEdges, anEmptyDMSS); |
556 | // |
557 | TopTools_ListIteratorOfListOfShape aItLF(theLF); |
558 | for (; aItLF.More(); aItLF.Next()) { |
559 | const TopoDS_Face& aF = *(TopoDS_Face*)&aItLF.Value(); |
560 | // |
561 | TopoDS_Shape aCE; |
562 | TopTools_ListOfShape aLFImages; |
563 | // |
564 | Standard_Boolean bFound = GetEdges(aF, theAsDes, anEImages, anEmptyM, |
565 | anEmptyIM, aCtx, aNewEdges, aCE, anEmptyIM); |
566 | // split the face by the edges |
567 | if (!bFound) { |
568 | if (!theImage.HasImage(aF)) { |
569 | aLFImages.Append(aF); |
570 | aDMFFIm.Add(aF, aLFImages); |
571 | } |
572 | continue; |
573 | } |
574 | // |
a8232603 |
575 | BuildSplitsOfTrimmedFace(aF, aCE, aLFImages); |
ecf4f17c |
576 | aDMFFIm.Add(aF, aLFImages); |
577 | } |
578 | // Fill history for faces and edges |
579 | FillHistory(aDMFFIm, anEImages, theImage); |
580 | } |
581 | |
582 | //======================================================================= |
583 | //function : BuildSplitsOfExtendedFaces |
584 | //purpose : Building splits of not-trimmed offset faces. |
585 | // For the cases in which invalidity will be found, |
586 | // these invalidities will be rebuilt. |
587 | //======================================================================= |
588 | void BRepOffset_MakeOffset::BuildSplitsOfExtendedFaces(const TopTools_ListOfShape& theLF, |
589 | Handle(BRepAlgo_AsDes)& theAsDes, |
590 | TopTools_DataMapOfShapeListOfShape& theEdgesOrigins, |
591 | TopTools_DataMapOfShapeShape& theFacesOrigins, |
592 | TopTools_DataMapOfShapeShape& theETrimEInf, |
593 | BRepAlgo_Image& theImage) |
594 | { |
595 | Handle(IntTools_Context) aCtx = new IntTools_Context(); |
596 | // images and origins for offset edges |
597 | TopTools_DataMapOfShapeListOfShape anOEImages, anOEOrigins; |
598 | TopTools_MapOfShape aNewEdges; |
599 | // fusing all trimmed offset edges to avoid self-intersections in the splits |
600 | IntersectTrimmedEdges(theLF, theAsDes, anOEImages, anOEOrigins, |
601 | theEdgesOrigins, aCtx, aNewEdges, theETrimEInf); |
602 | // |
603 | // valid/invalid edges |
604 | TopTools_IndexedMapOfShape anInvEdges, aValidEdges, anEdgesToAvoid; |
605 | // inverted edges |
606 | TopTools_MapOfShape anInvertedEdges; |
607 | // splits of faces |
608 | TopTools_IndexedDataMapOfShapeListOfShape aFImages; |
609 | // found invalid faces |
610 | TopTools_IndexedDataMapOfShapeListOfShape anInvFaces; |
611 | // artificially invalid faces - it will be empty here, |
612 | // but may be filled on the following rebuilding steps |
613 | TopTools_DataMapOfShapeShape anArtInvFaces; |
614 | // shapes connections for using in rebuilding |
615 | TopTools_DataMapOfShapeListOfShape aSSInterfs; |
616 | // edges to avoid on second steps |
617 | TopTools_MapOfShape aLastInvEdges; |
618 | // keep information of already invalid faces to avoid |
619 | // infinite rebuilding of the same invalid face |
620 | TopTools_DataMapOfShapeInteger anAlreadyInvFaces; |
621 | // solid build from the new splits |
622 | TopoDS_Shape aSolids; |
623 | // now we can split the faces |
624 | BuildSplitsOfFaces(theLF, aNewEdges, theEdgesOrigins, theAsDes, theFacesOrigins, |
625 | anOEImages, anOEOrigins, aLastInvEdges, anEdgesToAvoid, anInvEdges, aValidEdges, |
626 | anInvertedEdges, anAlreadyInvFaces, anInvFaces, anArtInvFaces, aFImages, aSolids, aSSInterfs); |
627 | // |
628 | // Find faces to rebuild |
629 | if (anInvFaces.Extent()) { |
630 | TopTools_IndexedDataMapOfShapeListOfShape aFToRebuild; |
631 | TopTools_MapOfShape aFSelfRebAvoid; |
632 | FindFacesToRebuild(aFImages, anInvEdges, anInvFaces, aSSInterfs, aFToRebuild, aFSelfRebAvoid); |
633 | // |
634 | if (aFToRebuild.Extent()) { |
635 | // vertices to avoid |
636 | TopTools_MapOfShape aVAEmpty; |
637 | RebuildFaces(aFToRebuild, aFSelfRebAvoid, aSolids, aSSInterfs, aFImages, theEdgesOrigins, theFacesOrigins, |
638 | anOEImages, anOEOrigins, aLastInvEdges, anEdgesToAvoid, anInvEdges, aValidEdges, anInvertedEdges, |
639 | anAlreadyInvFaces, anInvFaces, anArtInvFaces, aVAEmpty, theETrimEInf, theAsDes); |
640 | } |
641 | } |
642 | // Fill history for faces and edges |
643 | FillHistory(aFImages, anOEImages, theImage); |
644 | } |
645 | |
646 | //======================================================================= |
647 | //function : BuildSplitsOfInvFaces |
648 | //purpose : Rebuilding splits of faces with new intersection edges |
649 | //======================================================================= |
650 | void BuildSplitsOfInvFaces(const TopTools_IndexedDataMapOfShapeListOfShape& theFToRebuild, |
651 | const TopTools_MapOfShape& theModifiedEdges, |
652 | TopTools_IndexedDataMapOfShapeListOfShape& theFImages, |
653 | TopTools_DataMapOfShapeListOfShape& theEdgesOrigins, |
654 | TopTools_DataMapOfShapeShape& theFacesOrigins, |
655 | TopTools_DataMapOfShapeListOfShape& theOEImages, |
656 | TopTools_DataMapOfShapeListOfShape& theOEOrigins, |
657 | TopTools_MapOfShape& theLastInvEdges, |
658 | TopTools_IndexedMapOfShape& theEdgesToAvoid, |
659 | TopTools_MapOfShape& theVertsToAvoid, |
660 | TopTools_DataMapOfShapeInteger& theAlreadyInvFaces, |
661 | TopTools_IndexedMapOfShape& theValidEdges, |
662 | TopTools_DataMapOfShapeShape& theETrimEInf, |
663 | Handle(BRepAlgo_AsDes)& theAsDes) |
664 | { |
665 | Standard_Integer aNb = theFToRebuild.Extent(); |
666 | if (!aNb) { |
667 | return; |
668 | } |
669 | // |
670 | TopTools_ListOfShape aLF; |
671 | aNb = theFImages.Extent(); |
672 | for (Standard_Integer i = 1; i <= aNb; ++i) { |
673 | const TopoDS_Shape& aF = theFImages.FindKey(i); |
674 | aLF.Append(aF); |
675 | } |
676 | // |
677 | // invalid faces |
678 | TopTools_IndexedDataMapOfShapeListOfShape anInvFaces; |
679 | // artificially invalid faces |
680 | TopTools_DataMapOfShapeShape anArtInvFaces; |
681 | // invalid edges |
682 | TopTools_IndexedMapOfShape anInvEdges; |
683 | // inverted edges |
684 | TopTools_MapOfShape anInvertedEdges; |
685 | // shapes connection for using in rebuilding process |
686 | TopTools_DataMapOfShapeListOfShape aSSInterfs; |
687 | // |
688 | TopoDS_Shape aSolids; |
689 | // |
690 | BuildSplitsOfFaces(aLF, theModifiedEdges, theEdgesOrigins, theAsDes, theFacesOrigins, |
691 | theOEImages, theOEOrigins, theLastInvEdges, theEdgesToAvoid, anInvEdges, theValidEdges, |
692 | anInvertedEdges, theAlreadyInvFaces, anInvFaces, anArtInvFaces, theFImages, aSolids, aSSInterfs); |
693 | // |
694 | if (anInvFaces.Extent()) { |
695 | TopTools_IndexedDataMapOfShapeListOfShape aFToRebuild; |
696 | TopTools_MapOfShape aFSelfRebAvoid; |
697 | FindFacesToRebuild(theFImages, anInvEdges, anInvFaces, aSSInterfs, aFToRebuild, aFSelfRebAvoid); |
698 | // |
699 | if (aFToRebuild.Extent()) { |
700 | RebuildFaces(aFToRebuild, aFSelfRebAvoid, aSolids, aSSInterfs, theFImages, theEdgesOrigins, theFacesOrigins, |
701 | theOEImages, theOEOrigins, theLastInvEdges, theEdgesToAvoid, anInvEdges, theValidEdges, anInvertedEdges, |
702 | theAlreadyInvFaces, anInvFaces, anArtInvFaces, theVertsToAvoid, theETrimEInf, theAsDes); |
703 | } |
704 | } |
705 | } |
706 | |
707 | //======================================================================= |
708 | //function : BuildSplitsOfFaces |
709 | //purpose : Building the splits of offset faces and |
710 | // looking for the invalid splits |
711 | //======================================================================= |
712 | void BuildSplitsOfFaces(const TopTools_ListOfShape& theLF, |
713 | const TopTools_MapOfShape& theModifiedEdges, |
714 | const TopTools_DataMapOfShapeListOfShape& theEdgesOrigins, |
715 | Handle(BRepAlgo_AsDes)& theAsDes, |
716 | TopTools_DataMapOfShapeShape& theFacesOrigins, |
717 | TopTools_DataMapOfShapeListOfShape& theOEImages, |
718 | TopTools_DataMapOfShapeListOfShape& theOEOrigins, |
719 | TopTools_MapOfShape& theLastInvEdges, |
720 | TopTools_IndexedMapOfShape& theEdgesToAvoid, |
721 | TopTools_IndexedMapOfShape& theInvEdges, |
722 | TopTools_IndexedMapOfShape& theValidEdges, |
723 | TopTools_MapOfShape& theInvertedEdges, |
724 | TopTools_DataMapOfShapeInteger& theAlreadyInvFaces, |
725 | TopTools_IndexedDataMapOfShapeListOfShape& theInvFaces, |
726 | TopTools_DataMapOfShapeShape& theArtInvFaces, |
727 | TopTools_IndexedDataMapOfShapeListOfShape& theFImages, |
728 | TopoDS_Shape& theSolids, |
729 | TopTools_DataMapOfShapeListOfShape& theSSInterfs) |
730 | { |
731 | if (theLF.IsEmpty()) { |
732 | return; |
733 | } |
734 | // |
735 | BRep_Builder aBB; |
736 | Standard_Integer i, aNb; |
737 | // |
738 | // processed faces |
739 | TopTools_ListOfShape aLFDone; |
740 | // extended face - list of neutral edges, i.e. in one splits - valid and in others - invalid |
741 | TopTools_DataMapOfShapeListOfShape aDMFLNE; |
742 | // list of valid edges for each face |
743 | TopTools_DataMapOfShapeListOfShape aDMFLVE; |
744 | // list of invalid edges for each face |
745 | TopTools_DataMapOfShapeListOfShape aDMFLIE; |
746 | // map of valid inverted edges for the face |
747 | TopTools_DataMapOfShapeListOfShape aDMFLVIE; |
748 | // map of splits to check for internals |
749 | TopTools_IndexedMapOfShape aMFToCheckInt; |
750 | // map of edges created from vertex and marked as invalid |
751 | TopTools_MapOfShape aMEdgeInvalidByVertex; |
752 | // |
753 | Handle(IntTools_Context) aCtx = new IntTools_Context; |
754 | // build splits of faces |
755 | TopTools_ListIteratorOfListOfShape aItLF(theLF); |
756 | for (; aItLF.More(); aItLF.Next()) { |
757 | const TopoDS_Face& aF = *(TopoDS_Face*)&aItLF.Value(); |
758 | // |
759 | TopTools_ListOfShape* pLFIm = theFImages.ChangeSeek(aF); |
760 | if (pLFIm && pLFIm->IsEmpty()) { |
761 | continue; |
762 | } |
763 | // get edges by which the face should be split |
764 | TopoDS_Shape aCE; |
765 | TopTools_IndexedMapOfShape aMapEInv; |
766 | Standard_Boolean bFound = |
767 | GetEdges(aF, theAsDes, theOEImages, theLastInvEdges, |
768 | theEdgesToAvoid, aCtx, theModifiedEdges, aCE, aMapEInv); |
769 | if (!bFound) { |
770 | continue; |
771 | } |
772 | // |
773 | // build splits |
774 | TopTools_ListOfShape aLFImages; |
a8232603 |
775 | BuildSplitsOfFace(aF, aCE, theFacesOrigins, aLFImages); |
ecf4f17c |
776 | // |
777 | if (aMapEInv.Extent()) { |
778 | // check if all possible faces are built |
779 | TopTools_MapOfShape aMENInv; |
780 | Standard_Boolean bArtificialCase = aLFImages.IsEmpty() || |
781 | CheckIfArtificial(aF, aLFImages, aCE, aMapEInv, theOEImages, aMENInv, theAsDes); |
782 | // |
783 | // try to build splits using invalid edges |
784 | TopoDS_Compound aCE1; |
785 | aBB.MakeCompound(aCE1); |
786 | aBB.Add(aCE1, aCE); |
787 | for (i = 1; i <= aMapEInv.Extent(); ++i) { |
788 | aBB.Add(aCE1, aMapEInv(i)); |
789 | } |
790 | // |
791 | TopTools_ListOfShape aLFImages1; |
a8232603 |
792 | BuildSplitsOfFace(aF, aCE1, theFacesOrigins, aLFImages1); |
ecf4f17c |
793 | // |
b443d536 |
794 | // check if the rebuilding has added some new faces to the splits |
45d0af05 |
795 | for (TopTools_ListIteratorOfListOfShape aItLFIm(aLFImages1); aItLFIm.More();) |
796 | { |
b443d536 |
797 | Standard_Boolean bAllInv = Standard_True; |
ecf4f17c |
798 | const TopoDS_Shape& aFIm = aItLFIm.Value(); |
799 | TopExp_Explorer aExpE(aFIm, TopAbs_EDGE); |
800 | for (; aExpE.More(); aExpE.Next()) { |
801 | const TopoDS_Shape& aE = aExpE.Current(); |
b443d536 |
802 | if (!aMapEInv.Contains(aE)) { |
803 | bAllInv = Standard_False; |
804 | if (!aMENInv.Contains(aE)) { |
805 | break; |
806 | } |
ecf4f17c |
807 | } |
808 | } |
809 | // |
810 | if (!aExpE.More()) { |
811 | if (bAllInv) { |
812 | aMFToCheckInt.Add(aFIm); |
813 | } |
814 | aLFImages1.Remove(aItLFIm); |
815 | } |
816 | else { |
817 | aItLFIm.Next(); |
818 | } |
819 | } |
820 | // |
821 | if (bArtificialCase) { |
822 | if (aLFImages.Extent() == aLFImages1.Extent()) { |
823 | bArtificialCase = Standard_False; |
824 | } |
825 | else { |
826 | aLFImages = aLFImages1; |
827 | } |
828 | } |
829 | // |
830 | if (bArtificialCase) { |
831 | TopTools_ListOfShape aLEInv; |
832 | // make the face invalid |
833 | theArtInvFaces.Bind(aF, aCE); |
834 | // |
835 | *pLFIm = aLFImages; |
836 | TopTools_ListIteratorOfListOfShape aItLFIm(aLFImages); |
837 | for (; aItLFIm.More(); aItLFIm.Next()) { |
838 | const TopoDS_Shape& aFIm = aItLFIm.Value(); |
839 | TopExp_Explorer aExpE(aFIm, TopAbs_EDGE); |
840 | for (; aExpE.More(); aExpE.Next()) { |
841 | const TopoDS_Shape& aE = aExpE.Current(); |
842 | if (aMapEInv.Contains(aE)) { |
843 | theInvEdges.Add(aE); |
844 | AppendToList(aLEInv, aE); |
845 | } |
846 | else { |
847 | theValidEdges.Add(aE); |
848 | } |
849 | } |
850 | } |
851 | // |
852 | aDMFLIE.Bind(aF, aLEInv); |
853 | aLFDone.Append(aF); |
854 | // |
855 | continue; |
856 | } |
857 | } |
858 | // |
859 | // find invalid edges |
860 | FindInvalidEdges(aF, aLFImages, theEdgesOrigins, theFacesOrigins, theOEImages, |
861 | theOEOrigins, theInvEdges, theValidEdges, aDMFLVE, aDMFLNE, aDMFLIE, |
862 | aDMFLVIE, theInvertedEdges, aMEdgeInvalidByVertex); |
863 | // |
864 | // save the new splits |
865 | if (!pLFIm) { |
866 | pLFIm = &theFImages(theFImages.Add(aF, TopTools_ListOfShape())); |
867 | } |
868 | else { |
869 | pLFIm->Clear(); |
870 | } |
871 | pLFIm->Append(aLFImages); |
872 | // |
873 | aLFDone.Append(aF); |
874 | } |
875 | // |
876 | if (theInvEdges.IsEmpty() && theArtInvFaces.IsEmpty()) { |
877 | return; |
878 | } |
879 | // |
880 | #ifdef OFFSET_DEBUG |
881 | // show invalid edges |
882 | TopoDS_Compound aCEInv1; |
883 | BRep_Builder().MakeCompound(aCEInv1); |
884 | Standard_Integer aNbEInv = theInvEdges.Extent(); |
885 | for (i = 1; i <= aNbEInv; ++i) { |
886 | const TopoDS_Shape& aE = theInvEdges(i); |
887 | BRep_Builder().Add(aCEInv1, aE); |
888 | } |
889 | // |
890 | TopoDS_Compound aCEVal1; |
891 | BRep_Builder().MakeCompound(aCEVal1); |
892 | aNbEInv = theValidEdges.Extent(); |
893 | for (i = 1; i <= aNbEInv; ++i) { |
894 | const TopoDS_Shape& aE = theValidEdges(i); |
895 | BRep_Builder().Add(aCEVal1, aE); |
896 | } |
897 | #endif |
898 | // |
899 | TopTools_ListOfShape anEmptyList; |
900 | // find invalid faces |
901 | // considering faces containing only invalid edges as invalid |
902 | aItLF.Initialize(aLFDone); |
903 | for (; aItLF.More(); aItLF.Next()) { |
904 | const TopoDS_Shape& aF = aItLF.Value(); |
905 | TopTools_ListOfShape& aLFImages = theFImages.ChangeFromKey(aF); |
906 | // |
907 | TopTools_ListOfShape aLFInv; |
908 | Standard_Boolean bArtificialCase = theArtInvFaces.IsBound(aF); |
909 | if (bArtificialCase) { |
910 | aLFInv = aLFImages; |
911 | } |
912 | else { |
913 | // neutral edges |
914 | TopTools_ListOfShape* pLNE = aDMFLNE.ChangeSeek(aF); |
915 | if (!pLNE) { |
916 | pLNE = &anEmptyList; |
917 | } |
918 | // valid inverted edges |
919 | TopTools_ListOfShape* pLIVE = aDMFLVIE.ChangeSeek(aF); |
920 | if (!pLIVE) { |
921 | pLIVE = &anEmptyList; |
922 | } |
923 | // |
924 | FindInvalidFaces(aLFImages, theInvEdges, theValidEdges, aDMFLVE, aDMFLIE, |
925 | *pLNE, *pLIVE, theInvertedEdges, aMEdgeInvalidByVertex, aLFInv); |
926 | } |
927 | // |
928 | if (aLFInv.Extent()) { |
929 | if (theAlreadyInvFaces.IsBound(aF)) { |
930 | if (theAlreadyInvFaces.Find(aF) > 2) { |
931 | if (aLFInv.Extent() == aLFImages.Extent() && !bArtificialCase) { |
932 | aLFImages.Clear(); |
933 | } |
934 | // |
935 | aLFInv.Clear(); |
936 | } |
937 | } |
938 | theInvFaces.Add(aF, aLFInv); |
939 | } |
940 | } |
941 | // |
942 | if (theInvFaces.IsEmpty()) { |
943 | theInvEdges.Clear(); |
944 | return; |
945 | } |
946 | // |
947 | #ifdef OFFSET_DEBUG |
948 | // show invalid faces |
949 | TopoDS_Compound aCFInv1; |
950 | BRep_Builder().MakeCompound(aCFInv1); |
951 | Standard_Integer aNbFInv = theInvFaces.Extent(); |
952 | for (i = 1; i <= aNbFInv; ++i) { |
953 | const TopTools_ListOfShape& aLFInv = theInvFaces(i); |
954 | TopTools_ListIteratorOfListOfShape aItLFInv(aLFInv); |
955 | for (; aItLFInv.More(); aItLFInv.Next()) { |
956 | const TopoDS_Shape& aFIm = aItLFInv.Value(); |
957 | BRep_Builder().Add(aCFInv1, aFIm); |
958 | } |
959 | } |
960 | #endif |
961 | // |
962 | TopTools_IndexedMapOfShape aMERemoved; |
963 | // remove invalid splits of faces using inverted edges |
964 | RemoveInvalidSplitsByInvertedEdges(theInvertedEdges, theInvFaces, theFImages, aMERemoved); |
965 | if (theInvFaces.IsEmpty()) { |
966 | theInvEdges.Clear(); |
967 | return; |
968 | } |
969 | // |
970 | // remove invalid splits from valid splits |
971 | RemoveInvalidSplitsFromValid(theInvFaces, theArtInvFaces, theInvertedEdges, theFImages); |
972 | // |
973 | // remove inside faces |
974 | RemoveInsideFaces(theFImages, theInvFaces, theArtInvFaces, |
975 | theInvEdges, aMFToCheckInt, theSSInterfs, aMERemoved, theSolids); |
976 | // |
977 | // make compound of valid splits |
978 | TopoDS_Compound aCFIm; |
979 | aBB.MakeCompound(aCFIm); |
980 | // |
981 | aNb = theFImages.Extent(); |
982 | for (i = 1; i <= aNb; ++i) { |
983 | const TopTools_ListOfShape& aLFIm = theFImages(i); |
984 | aItLF.Initialize(aLFIm); |
985 | for (; aItLF.More(); aItLF.Next()) { |
986 | const TopoDS_Shape& aFIm = aItLF.Value(); |
987 | aBB.Add(aCFIm, aFIm); |
988 | } |
989 | } |
990 | // |
991 | TopTools_IndexedDataMapOfShapeListOfShape aDMFE; |
992 | TopExp::MapShapesAndAncestors(aCFIm, TopAbs_EDGE, TopAbs_FACE, aDMFE); |
993 | // |
994 | // filter maps of images and origins |
995 | FilterEdgesImages(aCFIm, theOEImages, theOEOrigins); |
996 | // |
997 | // filter invalid faces |
998 | FilterInvalidFaces(theFImages, aDMFE, theInvFaces, theArtInvFaces); |
999 | aNb = theInvFaces.Extent(); |
1000 | if (!aNb) { |
1001 | theInvEdges.Clear(); |
1002 | return; |
1003 | } |
1004 | // |
1005 | #ifdef OFFSET_DEBUG |
1006 | // show invalid faces |
1007 | TopoDS_Compound aCFInv; |
1008 | BRep_Builder().MakeCompound(aCFInv); |
1009 | aNbFInv = theInvFaces.Extent(); |
1010 | for (i = 1; i <= aNbFInv; ++i) { |
1011 | const TopTools_ListOfShape& aLFInv = theInvFaces(i); |
1012 | TopTools_ListIteratorOfListOfShape aItLFInv(aLFInv); |
1013 | for (; aItLFInv.More(); aItLFInv.Next()) { |
1014 | const TopoDS_Shape& aFIm = aItLFInv.Value(); |
1015 | BRep_Builder().Add(aCFInv, aFIm); |
1016 | } |
1017 | } |
1018 | #endif |
1019 | // |
1020 | // filter invalid edges |
1021 | FilterInvalidEdges(theInvFaces, theArtInvFaces, aDMFLIE, aMERemoved, theInvEdges); |
1022 | // |
1023 | #ifdef OFFSET_DEBUG |
1024 | // show invalid edges |
1025 | TopoDS_Compound aCEInv; |
1026 | BRep_Builder().MakeCompound(aCEInv); |
1027 | aNbEInv = theInvEdges.Extent(); |
1028 | for (i = 1; i <= aNbEInv; ++i) { |
1029 | const TopoDS_Shape& aE = theInvEdges(i); |
1030 | BRep_Builder().Add(aCEInv, aE); |
1031 | } |
1032 | #endif |
1033 | // |
1034 | theLastInvEdges.Clear(); |
1035 | aNb = theInvEdges.Extent(); |
1036 | for (i = 1; i <= aNb; ++i) { |
1037 | const TopoDS_Shape& aE = theInvEdges(i); |
1038 | theEdgesToAvoid.Add(aE); |
1039 | theLastInvEdges.Add(aE); |
1040 | } |
1041 | // |
1042 | aNb = theInvFaces.Extent(); |
1043 | for (i = 1; i <= aNb; ++i) { |
1044 | const TopoDS_Shape& aF = theInvFaces.FindKey(i); |
1045 | if (theAlreadyInvFaces.IsBound(aF)) { |
1046 | theAlreadyInvFaces.ChangeFind(aF)++; |
1047 | } |
1048 | else { |
1049 | theAlreadyInvFaces.Bind(aF, 1); |
1050 | } |
1051 | } |
1052 | } |
1053 | |
1054 | //======================================================================= |
1055 | //function : IntersectTrimmedEdges |
1056 | //purpose : Intersection of the trimmed edges among themselves |
1057 | //======================================================================= |
1058 | void IntersectTrimmedEdges(const TopTools_ListOfShape& theLF, |
1059 | const Handle(BRepAlgo_AsDes)& theAsDes, |
1060 | TopTools_DataMapOfShapeListOfShape& theOEImages, |
1061 | TopTools_DataMapOfShapeListOfShape& theOEOrigins, |
1062 | TopTools_DataMapOfShapeListOfShape& theEdgesOrigins, |
1063 | Handle(IntTools_Context)& theCtx, |
1064 | TopTools_MapOfShape& theNewEdges, |
1065 | TopTools_DataMapOfShapeShape& theETrimEInf) |
1066 | { |
1067 | if (theLF.IsEmpty()) { |
1068 | return; |
1069 | } |
1070 | // |
1071 | // get edges to intersect from descendants of the offset faces |
1072 | BOPCol_ListOfShape aLS; |
1073 | // |
1074 | TopTools_ListIteratorOfListOfShape aItLF(theLF); |
1075 | for (; aItLF.More(); aItLF.Next()) { |
1076 | const TopoDS_Face& aF = *(TopoDS_Face*)&aItLF.Value(); |
1077 | // |
1078 | const TopTools_ListOfShape& aLE = theAsDes->Descendant(aF); |
1079 | TopTools_ListIteratorOfListOfShape aItLE(aLE); |
1080 | for (; aItLE.More(); aItLE.Next()) { |
1081 | const TopoDS_Edge& aE = *(TopoDS_Edge*)&aItLE.Value(); |
1082 | // |
1083 | if (ProcessMicroEdge(aE, theCtx)) { |
1084 | continue; |
1085 | } |
1086 | // |
1087 | if (theNewEdges.Add(aE)) { |
1088 | aLS.Append(aE); |
1089 | } |
1090 | } |
1091 | } |
1092 | // |
1093 | if (aLS.Extent() < 2) { |
1094 | // nothing to intersect |
1095 | return; |
1096 | } |
1097 | // |
1098 | // perform intersection of the edges |
1099 | BOPAlgo_Builder aGFE; |
1100 | aGFE.SetArguments(aLS); |
1101 | aGFE.Perform(); |
1102 | if (aGFE.ErrorStatus()) { |
1103 | return; |
1104 | } |
1105 | // |
1106 | TopTools_ListOfShape aLA; |
1107 | // fill map with edges images |
1108 | BOPCol_ListIteratorOfListOfShape aIt(aLS); |
1109 | for (; aIt.More(); aIt.Next()) { |
1110 | const TopoDS_Shape& aE = aIt.Value(); |
1111 | const TopTools_ListOfShape& aLEIm = aGFE.Modified(aE); |
1112 | if (aLEIm.IsEmpty()) { |
1113 | continue; |
1114 | } |
1115 | // |
1116 | aLA.Append(aE); |
1117 | // save images |
1118 | theOEImages.Bind(aE, aLEIm); |
1119 | // save origins |
1120 | TopTools_ListIteratorOfListOfShape aItLE(aLEIm); |
1121 | for (; aItLE.More(); aItLE.Next()) { |
1122 | const TopoDS_Shape& aEIm = aItLE.Value(); |
1123 | TopTools_ListOfShape* pLEOr = theOEOrigins.ChangeSeek(aEIm); |
1124 | if (!pLEOr) { |
1125 | pLEOr = theOEOrigins.Bound(aEIm, TopTools_ListOfShape()); |
1126 | } |
1127 | AppendToList(*pLEOr, aE); |
1128 | } |
1129 | } |
1130 | // |
1131 | UpdateOrigins(aLA, theEdgesOrigins, aGFE); |
1132 | UpdateIntersectedEdges(aLA, theETrimEInf, aGFE); |
1133 | } |
1134 | |
1135 | //======================================================================= |
1136 | //function : GetEdges |
1137 | //purpose : Getting edges from AsDes map to build the splits of faces |
1138 | //======================================================================= |
1139 | Standard_Boolean GetEdges(const TopoDS_Face& theFace, |
1140 | const Handle(BRepAlgo_AsDes)& theAsDes, |
1141 | const TopTools_DataMapOfShapeListOfShape& theEImages, |
1142 | const TopTools_MapOfShape& theLastInvEdges, |
1143 | const TopTools_IndexedMapOfShape& theInvEdges, |
1144 | Handle(IntTools_Context)& theCtx, |
1145 | const TopTools_MapOfShape& theModifiedEdges, |
1146 | TopoDS_Shape& theEdges, |
1147 | TopTools_IndexedMapOfShape& theInv) |
1148 | { |
1149 | // get boundary edges |
1150 | TopTools_MapOfShape aMFBounds; |
1151 | TopExp_Explorer aExp(theFace, TopAbs_EDGE); |
1152 | for (; aExp.More(); aExp.Next()) { |
1153 | const TopoDS_Shape& aE = aExp.Current(); |
1154 | const TopTools_ListOfShape* pLEIm = theEImages.Seek(aE); |
1155 | if (!pLEIm) { |
1156 | aMFBounds.Add(aE); |
1157 | } |
1158 | else { |
1159 | TopTools_ListIteratorOfListOfShape aItLE(*pLEIm); |
1160 | for (; aItLE.More(); aItLE.Next()) { |
1161 | const TopoDS_Shape& aEIm = aItLE.Value(); |
1162 | aMFBounds.Add(aEIm); |
1163 | } |
1164 | } |
1165 | } |
1166 | // |
1167 | BRep_Builder aBB; |
1168 | Standard_Boolean bFound(Standard_False), bUpdate(Standard_False); |
1169 | // the resulting edges |
1170 | TopoDS_Compound anEdges; |
1171 | aBB.MakeCompound(anEdges); |
1172 | // |
1173 | // the edges by which the offset face should be split |
1174 | const TopTools_ListOfShape& aLE = theAsDes->Descendant(theFace); |
1175 | TopTools_ListIteratorOfListOfShape aItLE(aLE); |
1176 | for (; aItLE.More(); aItLE.Next()) { |
1177 | const TopoDS_Edge& aE = TopoDS::Edge(aItLE.Value()); |
1178 | // |
1179 | if (!bUpdate) { |
1180 | bUpdate = theModifiedEdges.Contains(aE); |
1181 | } |
1182 | // |
1183 | const TopTools_ListOfShape* pLEIm = theEImages.Seek(aE); |
1184 | if (pLEIm) { |
1185 | TopTools_ListIteratorOfListOfShape aItLEIm(*pLEIm); |
1186 | for (; aItLEIm.More(); aItLEIm.Next()) { |
1187 | const TopoDS_Edge& aEIm = TopoDS::Edge(aItLEIm.Value()); |
1188 | // |
1189 | if (theInvEdges.Contains(aEIm)) { |
1190 | theInv.Add(aEIm); |
1191 | if (!bUpdate) { |
1192 | bUpdate = theLastInvEdges.Contains(aEIm); |
1193 | } |
1194 | continue; |
1195 | } |
1196 | // check for micro edge |
1197 | if (ProcessMicroEdge(aEIm, theCtx)) { |
1198 | continue; |
1199 | } |
1200 | // |
1201 | aBB.Add(anEdges, aEIm); |
1202 | if (!bFound) { |
1203 | bFound = !aMFBounds.Contains(aEIm); |
1204 | } |
1205 | // |
1206 | if (!bUpdate) { |
1207 | bUpdate = theModifiedEdges.Contains(aEIm); |
1208 | } |
1209 | } |
1210 | } |
1211 | else { |
1212 | if (theInvEdges.Contains(aE)) { |
1213 | theInv.Add(aE); |
1214 | if (!bUpdate) { |
1215 | bUpdate = theLastInvEdges.Contains(aE); |
1216 | } |
1217 | continue; |
1218 | } |
1219 | // |
1220 | if (ProcessMicroEdge(aE, theCtx)) { |
1221 | continue; |
1222 | } |
1223 | aBB.Add(anEdges, aE); |
1224 | if (!bFound) { |
1225 | bFound = !aMFBounds.Contains(aE); |
1226 | } |
1227 | } |
1228 | } |
1229 | // |
1230 | theEdges = anEdges; |
1231 | return bFound && bUpdate; |
1232 | } |
1233 | |
1234 | //======================================================================= |
1235 | //function : BuildSplitsOfFace |
1236 | //purpose : Building the splits of offset face |
1237 | //======================================================================= |
1238 | void BuildSplitsOfFace(const TopoDS_Face& theFace, |
1239 | const TopoDS_Shape& theEdges, |
ecf4f17c |
1240 | TopTools_DataMapOfShapeShape& theFacesOrigins, |
1241 | TopTools_ListOfShape& theLFImages) |
a8232603 |
1242 | { |
1243 | theLFImages.Clear(); |
1244 | // |
1245 | // take edges to split the face |
1246 | BOPCol_ListOfShape aLE; |
1247 | TopExp_Explorer aExp(theEdges, TopAbs_EDGE); |
1248 | for (; aExp.More(); aExp.Next()) { |
1249 | TopoDS_Edge aE = TopoDS::Edge(aExp.Current()); |
1250 | aE.Orientation(TopAbs_FORWARD); |
1251 | aLE.Append(aE); |
1252 | aE.Orientation(TopAbs_REVERSED); |
1253 | aLE.Append(aE); |
1254 | } |
1255 | // |
1256 | TopoDS_Face aFF = theFace; |
1257 | TopAbs_Orientation anOr = theFace.Orientation(); |
1258 | aFF.Orientation(TopAbs_FORWARD); |
1259 | // |
1260 | // build pcurves for edges on the face |
1261 | BOPTools_AlgoTools2D::BuildPCurveForEdgesOnPlane(aLE, aFF); |
1262 | // |
1263 | // build splits of faces |
1264 | BOPAlgo_BuilderFace aBF; |
1265 | aBF.SetFace(aFF); |
1266 | aBF.SetShapes(aLE); |
1267 | aBF.Perform(); |
1268 | // |
1269 | const BOPCol_ListOfShape& aLFSp = aBF.Areas(); |
1270 | BOPCol_ListIteratorOfListOfShape aItLF(aLFSp); |
1271 | for (; aItLF.More(); aItLF.Next()) { |
1272 | TopoDS_Shape& aFSp = aItLF.ChangeValue(); |
1273 | aFSp.Orientation(anOr); |
1274 | theLFImages.Append(aFSp); |
1275 | // |
1276 | theFacesOrigins.Bind(aFSp, theFace); |
1277 | } |
1278 | } |
1279 | |
1280 | //======================================================================= |
1281 | //function : BuildSplitsOfFace |
1282 | //purpose : Building the splits of offset face |
1283 | //======================================================================= |
1284 | void BuildSplitsOfTrimmedFace(const TopoDS_Face& theFace, |
1285 | const TopoDS_Shape& theEdges, |
1286 | TopTools_ListOfShape& theLFImages) |
ecf4f17c |
1287 | { |
1288 | BOPAlgo_Builder aGF; |
1289 | // |
1290 | aGF.AddArgument(theFace); |
1291 | aGF.AddArgument(theEdges); |
1292 | aGF.Perform(); |
1293 | if (aGF.ErrorStatus()) { |
1294 | return; |
1295 | } |
1296 | // |
1297 | // splits of the offset shape |
1298 | theLFImages = aGF.Modified(theFace); |
ecf4f17c |
1299 | } |
1300 | |
1301 | //======================================================================= |
1302 | //function : CheckIfArtificial |
1303 | //purpose : Checks if the face is artificially invalid |
1304 | //======================================================================= |
1305 | Standard_Boolean CheckIfArtificial(const TopoDS_Shape& theF, |
1306 | const TopTools_ListOfShape& theLFImages, |
1307 | const TopoDS_Shape& theCE, |
1308 | const TopTools_IndexedMapOfShape& theMapEInv, |
1309 | const TopTools_DataMapOfShapeListOfShape& theOEImages, |
1310 | TopTools_MapOfShape& theMENInv, |
1311 | Handle(BRepAlgo_AsDes)& theAsDes) |
1312 | { |
1313 | // all boundary edges should be used |
1314 | TopTools_IndexedMapOfShape aMEUsed; |
1315 | TopTools_ListIteratorOfListOfShape aItLFIm(theLFImages); |
1316 | for (; aItLFIm.More(); aItLFIm.Next()) { |
1317 | const TopoDS_Shape& aFIm = aItLFIm.Value(); |
1318 | TopExp::MapShapes(aFIm, TopAbs_EDGE, aMEUsed); |
1319 | TopExp::MapShapes(aFIm, TopAbs_VERTEX, aMEUsed); |
1320 | } |
1321 | // |
1322 | TopTools_IndexedDataMapOfShapeListOfShape aMVE; |
1323 | TopExp::MapShapesAndAncestors(theCE, TopAbs_VERTEX, TopAbs_EDGE, aMVE); |
1324 | // |
1325 | Standard_Integer i, aNb = theMapEInv.Extent(); |
1326 | for (i = 1; i <= aNb; ++i) { |
1327 | const TopoDS_Shape& aEInv = theMapEInv(i); |
1328 | TopExp_Explorer aExpV(aEInv, TopAbs_VERTEX); |
1329 | for (; aExpV.More(); aExpV.Next()) { |
1330 | const TopoDS_Shape& aVEInv = aExpV.Current(); |
b443d536 |
1331 | const TopTools_ListOfShape* pLENInv = aMVE.Seek(aVEInv); |
1332 | if (pLENInv) { |
1333 | TopTools_ListIteratorOfListOfShape aItLEInv(*pLENInv); |
ecf4f17c |
1334 | for (; aItLEInv.More(); aItLEInv.Next()) { |
1335 | const TopoDS_Shape& aENInv = aItLEInv.Value(); |
b443d536 |
1336 | if (!aMEUsed.Contains(aENInv)) { |
1337 | theMENInv.Add(aENInv); |
1338 | } |
ecf4f17c |
1339 | } |
1340 | } |
1341 | } |
1342 | } |
1343 | // |
1344 | if (theMENInv.IsEmpty()) { |
1345 | return Standard_False; |
1346 | } |
1347 | // |
1348 | TopTools_IndexedMapOfShape aMEFound; |
1349 | TopExp::MapShapes(theCE, TopAbs_EDGE, aMEFound); |
1350 | // |
1351 | const TopTools_ListOfShape& aLE = theAsDes->Descendant(theF); |
1352 | TopTools_ListIteratorOfListOfShape aItLE(aLE); |
1353 | for (; aItLE.More(); aItLE.Next()) { |
1354 | const TopoDS_Edge& aE = TopoDS::Edge(aItLE.Value()); |
1355 | // |
1356 | if (theOEImages.IsBound(aE)) { |
1357 | Standard_Boolean bChecked = Standard_False; |
1358 | const TopTools_ListOfShape& aLEIm = theOEImages.Find(aE); |
1359 | TopTools_ListIteratorOfListOfShape aItLEIm(aLEIm); |
1360 | for (; aItLEIm.More(); aItLEIm.Next()) { |
1361 | const TopoDS_Edge& aEIm = TopoDS::Edge(aItLEIm.Value()); |
1362 | if (!aMEFound.Contains(aEIm) || theMENInv.Contains(aEIm)) { |
1363 | continue; |
1364 | } |
1365 | // |
1366 | bChecked = Standard_True; |
1367 | if (aMEUsed.Contains(aEIm)) { |
1368 | break; |
1369 | } |
1370 | } |
1371 | // |
1372 | if (bChecked && !aItLEIm.More()) { |
1373 | break; |
1374 | } |
1375 | } |
1376 | else { |
1377 | if (aMEFound.Contains(aE) && !theMENInv.Contains(aE) && !aMEUsed.Contains(aE)) { |
1378 | break; |
1379 | } |
1380 | } |
1381 | } |
1382 | // |
1383 | return aItLE.More(); |
1384 | } |
1385 | |
1386 | //======================================================================= |
1387 | //function : FindInvalidEdges |
1388 | //purpose : Looking for the invalid edges |
1389 | //======================================================================= |
1390 | void FindInvalidEdges(const TopoDS_Face& theF, |
1391 | const TopTools_ListOfShape& theLFImages, |
1392 | const TopTools_DataMapOfShapeListOfShape& theEdgesOrigins, |
1393 | const TopTools_DataMapOfShapeShape& theFacesOrigins, |
1394 | const TopTools_DataMapOfShapeListOfShape& theOEImages, |
1395 | const TopTools_DataMapOfShapeListOfShape& theOEOrigins, |
1396 | TopTools_IndexedMapOfShape& theInvEdges, |
1397 | TopTools_IndexedMapOfShape& theValidEdges, |
1398 | TopTools_DataMapOfShapeListOfShape& theDMFLVE, |
1399 | TopTools_DataMapOfShapeListOfShape& theDMFLNE, |
1400 | TopTools_DataMapOfShapeListOfShape& theDMFLIE, |
1401 | TopTools_DataMapOfShapeListOfShape& theDMFLVIE, |
1402 | TopTools_MapOfShape& theMEInverted, |
1403 | TopTools_MapOfShape& theEdgesInvalidByVertex) |
1404 | { |
1405 | // Edge is considered as invalid in the following cases: |
1406 | // 1. Its orientation on the face has changed comparing to the originals edge and face; |
1407 | // 2. The vertices of the edge have changed places comparing to the originals edge and face. |
1408 | // |
1409 | // The edges created from vertices, i.e. as intersection between two faces connected only |
1410 | // by VERTEX, will also be checked on validity. For these edges the correct orientation will |
1411 | // be defined by the edges on the original face adjacent to the connection vertex |
1412 | // |
1413 | const TopoDS_Face& aFOr = *(TopoDS_Face*)&theFacesOrigins.Find(theF); |
b443d536 |
1414 | // invalid edges |
ecf4f17c |
1415 | TopTools_IndexedMapOfShape aMEInv; |
1416 | // valid edges |
1417 | TopTools_MapOfShape aMEVal; |
1418 | // internal edges |
1419 | TopTools_MapOfShape aMEInt; |
1420 | // |
1421 | // maps for checking the inverted edges |
1422 | TopTools_IndexedDataMapOfShapeListOfShape aDMVE, aDMEF; |
1423 | TopTools_IndexedMapOfShape aMEdges; |
1424 | // |
1425 | TopTools_ListIteratorOfListOfShape aItLF(theLFImages); |
1426 | for (; aItLF.More(); aItLF.Next()) { |
1427 | const TopoDS_Face& aFIm = *(TopoDS_Face*)&aItLF.Value(); |
1428 | // |
1429 | TopExp_Explorer aExp(aFIm, TopAbs_EDGE); |
1430 | for (; aExp.More(); aExp.Next()) { |
1431 | const TopoDS_Shape& aE = aExp.Current(); |
1432 | // keep all edges |
1433 | aMEdges.Add(aE); |
1434 | // |
1435 | // keep connection from edges to faces |
1436 | TopTools_ListOfShape* pLF = aDMEF.ChangeSeek(aE); |
1437 | if (!pLF) { |
1438 | pLF = &aDMEF(aDMEF.Add(aE, TopTools_ListOfShape())); |
1439 | } |
1440 | AppendToList(*pLF, aFIm); |
1441 | // |
1442 | // keep connection from vertices to edges |
1443 | TopoDS_Iterator aItV(aE); |
1444 | for (; aItV.More(); aItV.Next()) { |
1445 | const TopoDS_Shape& aV = aItV.Value(); |
1446 | // |
1447 | TopTools_ListOfShape* pLE = aDMVE.ChangeSeek(aV); |
1448 | if (!pLE) { |
1449 | pLE = &aDMVE(aDMVE.Add(aV, TopTools_ListOfShape())); |
1450 | } |
1451 | AppendToList(*pLE, aE); |
1452 | } |
1453 | } |
1454 | } |
1455 | // |
1456 | // the map will be used to find the edges on the original face |
1457 | // adjacent to the same vertex. It will be filled at first necessity; |
1458 | TopTools_IndexedDataMapOfShapeListOfShape aDMVEFOr; |
1459 | // |
1460 | aItLF.Initialize(theLFImages); |
1461 | for (; aItLF.More(); aItLF.Next()) { |
1462 | const TopoDS_Face& aFIm = *(TopoDS_Face*)&aItLF.Value(); |
1463 | // |
1464 | // valid edges for this split |
1465 | TopTools_ListOfShape aLVE; |
1466 | // invalid edges for this split |
1467 | TopTools_ListOfShape aLIE; |
1468 | // |
1469 | TopExp_Explorer aExp(aFIm, TopAbs_EDGE); |
1470 | for (; aExp.More(); aExp.Next()) { |
1471 | const TopoDS_Edge& aEIm = *(TopoDS_Edge*)&aExp.Current(); |
1472 | // |
1473 | if (aEIm.Orientation() == TopAbs_INTERNAL) { |
1474 | aMEInt.Add(aEIm); |
1475 | continue; |
1476 | } |
1477 | // |
1478 | if (!theEdgesOrigins.IsBound(aEIm)) { |
1479 | continue; |
1480 | } |
1481 | // |
1482 | const TopTools_ListOfShape& aLEOr = theEdgesOrigins.Find(aEIm); |
1483 | if (aLEOr.IsEmpty()) { |
1484 | continue; |
1485 | } |
1486 | // |
1487 | Standard_Integer aNbVOr = 0; |
1488 | TopTools_ListIteratorOfListOfShape aItLEO(aLEOr); |
1489 | for (; aItLEO.More(); aItLEO.Next()) { |
1490 | if (aItLEO.Value().ShapeType() == TopAbs_VERTEX) { |
1491 | ++aNbVOr; |
1492 | } |
1493 | } |
1494 | // |
1495 | TopTools_MapOfShape aME, aMV; |
1496 | Standard_Boolean bInvalid = Standard_False, bChecked = Standard_False; |
1497 | Standard_Integer aNbP = NbPoints(aEIm); |
b443d536 |
1498 | Standard_Boolean bUseVertex = !aNbVOr ? Standard_False : |
1499 | (aNbVOr == 1 && |
1500 | aDMEF.FindFromKey(aEIm).Extent() == 1 && |
1501 | !theOEOrigins.IsBound(aEIm)); |
1502 | // |
ecf4f17c |
1503 | aItLEO.Initialize(aLEOr); |
1504 | for (; aItLEO.More(); aItLEO.Next()) { |
1505 | const TopoDS_Shape& aSOr = aItLEO.Value(); |
1506 | Standard_Boolean bVertex = (aSOr.ShapeType() == TopAbs_VERTEX); |
1507 | // |
1508 | TopoDS_Shape aEOrF; |
1509 | if (bVertex) { |
1510 | // for some cases it is impossible to check the validity of the edge |
b443d536 |
1511 | if (!bUseVertex) { |
ecf4f17c |
1512 | continue; |
1513 | } |
ecf4f17c |
1514 | // find edges on the original face adjacent to this vertex |
1515 | if (aDMVEFOr.IsEmpty()) { |
1516 | // fill the map |
1517 | TopExp::MapShapesAndAncestors(aFOr, TopAbs_VERTEX, TopAbs_EDGE, aDMVEFOr); |
1518 | } |
1519 | // |
1520 | TopTools_ListOfShape *pLEFOr = aDMVEFOr.ChangeSeek(aSOr); |
1521 | if (pLEFOr) { |
1522 | TopoDS_Compound aCEOr; |
1523 | BRep_Builder().MakeCompound(aCEOr); |
1524 | TopTools_ListIteratorOfListOfShape aItLEFOr(*pLEFOr); |
1525 | for (; aItLEFOr.More(); aItLEFOr.Next()) { |
1526 | const TopoDS_Shape& aEOr = aItLEFOr.Value(); |
1527 | BRep_Builder().Add(aCEOr, aEOr); |
1528 | } |
1529 | aEOrF = aCEOr; |
1530 | } |
1531 | } |
1532 | else { |
1533 | FindShape(aSOr, aFOr, aEOrF); |
1534 | } |
1535 | // |
1536 | if (aEOrF.IsNull()) { |
1537 | // the edge has not been found |
1538 | continue; |
1539 | } |
1540 | // |
1541 | // Check orientations of the image edge and original edge. |
1542 | // In case the 3d curves are having the same direction the orientations |
1543 | // must be the same. Otherwise the orientations should also be different. |
1544 | // |
1545 | // get average tangent vector for each curve taking into account |
1546 | // the orientations of the edges, i.e. the edge is reversed |
1547 | // the vector is reversed as well |
1548 | gp_Vec aVSum1 = GetAverageTangent(aEIm, aNbP); |
1549 | gp_Vec aVSum2 = GetAverageTangent(aEOrF, aNbP); |
1550 | // |
1551 | aVSum1.Normalize(); |
1552 | aVSum2.Normalize(); |
1553 | // |
1554 | Standard_Real aCos = aVSum1.Dot(aVSum2); |
1555 | if (!bVertex) { |
1556 | if (Abs(aCos) < 0.9999) { |
1557 | continue; |
1558 | } |
1559 | // |
1560 | aME.Add(aEOrF); |
1561 | TopExp_Explorer aExpE(aEOrF, TopAbs_VERTEX); |
1562 | for (; aExpE.More(); aExpE.Next()) { |
1563 | const TopoDS_Shape& aV = aExpE.Current(); |
1564 | aMV.Add(aV); |
1565 | } |
1566 | } |
1567 | // |
1568 | if (aCos < Precision::Confusion()) { |
1569 | bInvalid = Standard_True; |
1570 | if (bVertex) { |
1571 | theEdgesInvalidByVertex.Add(aEIm); |
1572 | } |
1573 | } |
1574 | bChecked = Standard_True; |
1575 | } |
1576 | // |
1577 | if (!bChecked) { |
1578 | continue; |
1579 | } |
1580 | // |
1581 | Standard_Integer aNbE = aME.Extent(), aNbV = aMV.Extent(); |
1582 | if ((aNbE > 1) && (aNbV == 2*aNbE)) { |
1583 | continue; |
1584 | } |
1585 | // |
1586 | if (bInvalid) { |
1587 | theInvEdges.Add(aEIm); |
1588 | aLIE.Append(aEIm); |
1589 | aMEInv.Add(aEIm); |
1590 | continue; |
1591 | } |
1592 | // |
1593 | // check if the edge has been inverted |
b443d536 |
1594 | Standard_Boolean bInverted = !aNbE ? Standard_False : |
1595 | CheckInverted(aEIm, aFOr, theOEImages, theOEOrigins, |
1596 | theEdgesOrigins, aDMEF, aDMVE, aMEdges, theMEInverted); |
ecf4f17c |
1597 | // |
1598 | if (!bInverted || !aNbVOr) { |
1599 | theValidEdges.Add(aEIm); |
1600 | aLVE.Append(aEIm); |
1601 | aMEVal.Add(aEIm); |
1602 | } |
1603 | } |
1604 | // |
1605 | // valid edges |
1606 | if (aLVE.Extent()) { |
1607 | theDMFLVE.Bind(aFIm, aLVE); |
1608 | } |
1609 | // |
1610 | // invalid edges |
1611 | if (aLIE.Extent()) { |
1612 | theDMFLIE.Bind(aFIm, aLIE); |
1613 | } |
1614 | } |
1615 | // |
1616 | // process invalid edges: |
1617 | // check for the inverted edges |
1618 | TopTools_ListOfShape aLVIE; |
1619 | // fill neutral edges |
1620 | TopTools_ListOfShape aLNE; |
1621 | // |
1622 | Standard_Integer i, aNbEInv = aMEInv.Extent(); |
1623 | for (i = 1; i <= aNbEInv; ++i) { |
1624 | const TopoDS_Shape& aEIm = aMEInv(i); |
1625 | // |
1626 | // neutral edges - on the splits of the same offset face |
1627 | // it is valid for one split and invalid for other |
1628 | if (aMEVal.Contains(aEIm)) { |
1629 | aLNE.Append(aEIm); |
1630 | continue; |
1631 | } |
1632 | // |
1633 | // the inverted images of the origins of invalid edges should also be invalid |
1634 | if (!theMEInverted.Contains(aEIm)) { |
1635 | continue; |
1636 | } |
1637 | // |
1638 | const TopTools_ListOfShape* pLOEOr = theOEOrigins.Seek(aEIm); |
1639 | if (!pLOEOr) { |
1640 | continue; |
1641 | } |
1642 | // |
1643 | TopTools_ListIteratorOfListOfShape aItLOEOr(*pLOEOr); |
1644 | for (; aItLOEOr.More(); aItLOEOr.Next()) { |
1645 | const TopoDS_Shape& aOEOr = aItLOEOr.Value(); |
1646 | const TopTools_ListOfShape& aLEIm1 = theOEImages.Find(aOEOr); |
1647 | // |
1648 | TopTools_ListIteratorOfListOfShape aItLEIm1(aLEIm1); |
1649 | for (; aItLEIm1.More(); aItLEIm1.Next()) { |
1650 | const TopoDS_Shape& aEIm1 = aItLEIm1.Value(); |
1651 | if (aMEdges.Contains(aEIm1) && |
1652 | !aMEInv.Contains(aEIm1) && !aMEInt.Contains(aEIm1) && |
1653 | theMEInverted.Contains(aEIm1)) { |
1654 | theInvEdges.Add(aEIm1); |
1655 | aLVIE.Append(aEIm1); |
1656 | } |
1657 | } |
1658 | } |
1659 | } |
1660 | // |
1661 | if (aLNE.Extent()) { |
1662 | theDMFLNE.Bind(theF, aLNE); |
1663 | } |
1664 | // |
1665 | if (aLVIE.Extent()) { |
1666 | theDMFLVIE.Bind(theF, aLVIE); |
1667 | } |
1668 | } |
1669 | |
1670 | //======================================================================= |
1671 | //function : FindInvalidFaces |
1672 | //purpose : Looking for the invalid faces by analyzing their invalid edges |
1673 | //======================================================================= |
1674 | void FindInvalidFaces(TopTools_ListOfShape& theLFImages, |
1675 | const TopTools_IndexedMapOfShape& theInvEdges, |
1676 | const TopTools_IndexedMapOfShape& theValidEdges, |
1677 | const TopTools_DataMapOfShapeListOfShape& theDMFLVE, |
1678 | const TopTools_DataMapOfShapeListOfShape& theDMFLIE, |
1679 | const TopTools_ListOfShape& theLENeutral, |
1680 | const TopTools_ListOfShape& theLEValInverted, |
1681 | const TopTools_MapOfShape& theMEInverted, |
1682 | const TopTools_MapOfShape& theEdgesInvalidByVertex, |
1683 | TopTools_ListOfShape& theInvFaces) |
1684 | { |
1685 | // The face should be considered as invalid in the following cases: |
1686 | // 1. It has been reverted, i.e. at least two not connected edges |
1687 | // have changed orientation (i.e. invalid). In this case all edges, |
1688 | // should be invalid for that face, because edges have also been reverted; |
1689 | // 2. All checked edges of the face are invalid for this face; |
1690 | // The face should be removed from the splits in the following cases: |
1691 | // 1. All checked edges of the face are invalid for this one, but valid for |
1692 | // some other face in this list of splits. |
1693 | // The face will be kept in the following cases: |
1694 | // 1. Some of the edges are valid for this face. |
1695 | Standard_Boolean bHasValid, bAllValid, bAllInvalid, bHasReallyInvalid, bAllInvNeutral; |
1696 | Standard_Boolean bValid, bValidLoc, bInvalid, bInvalidLoc, bNeutral; |
1697 | Standard_Integer i, aNbChecked; |
1698 | // |
1699 | // neutral edges |
1700 | TopTools_MapOfShape aMEN; |
45d0af05 |
1701 | for (TopTools_ListIteratorOfListOfShape aItLE(theLENeutral); aItLE.More(); aItLE.Next()) |
1702 | { |
ecf4f17c |
1703 | aMEN.Add(aItLE.Value()); |
1704 | } |
1705 | // |
1706 | // valid inverted edges |
1707 | TopTools_MapOfShape aMEValInverted; |
45d0af05 |
1708 | for (TopTools_ListIteratorOfListOfShape aItLE(theLEValInverted); aItLE.More(); aItLE.Next()) |
1709 | { |
ecf4f17c |
1710 | aMEValInverted.Add(aItLE.Value()); |
1711 | } |
1712 | // |
1713 | Standard_Boolean bCheckInverted = (theLFImages.Extent() == 1); |
1714 | // |
1715 | // neutral edges to remove |
1716 | TopTools_IndexedMapOfShape aMENRem; |
1717 | // |
1718 | // faces for post treat |
1719 | TopTools_ListOfShape aLFPT; |
1720 | // |
1721 | TopTools_ListIteratorOfListOfShape aItLF(theLFImages); |
1722 | for (; aItLF.More(); ) { |
1723 | const TopoDS_Face& aFIm = *(TopoDS_Face*)&aItLF.Value(); |
1724 | // |
1725 | // valid edges for this split |
1726 | TopTools_MapOfShape aMVE; |
1727 | // invalid edges for this split |
1728 | TopTools_MapOfShape aMIE; |
1729 | // |
1730 | for (i = 0; i < 2; ++i) { |
1731 | TopTools_MapOfShape& aME = !i ? aMVE : aMIE; |
1732 | const TopTools_ListOfShape* pLE = !i ? theDMFLVE.Seek(aFIm) : theDMFLIE.Seek(aFIm); |
1733 | if (pLE) { |
1734 | TopTools_ListIteratorOfListOfShape aItLE(*pLE); |
1735 | for (; aItLE.More(); aItLE.Next()) { |
1736 | const TopoDS_Shape& aE = aItLE.Value(); |
1737 | aME.Add(aE); |
1738 | } |
1739 | } |
1740 | } |
1741 | // |
1742 | bHasValid = Standard_False; |
1743 | bAllValid = Standard_True; |
1744 | bAllInvalid = Standard_True; |
1745 | bHasReallyInvalid = Standard_False; |
1746 | bAllInvNeutral = Standard_True; |
1747 | aNbChecked = 0; |
1748 | // |
1749 | const TopoDS_Wire& aWIm = BRepTools::OuterWire(aFIm); |
1750 | TopExp_Explorer aExp(aWIm, TopAbs_EDGE); |
1751 | for (; aExp.More(); aExp.Next()) { |
1752 | const TopoDS_Shape& aEIm = aExp.Current(); |
1753 | // |
1754 | bValid = theValidEdges.Contains(aEIm); |
1755 | bInvalid = theInvEdges.Contains(aEIm); |
1756 | // |
1757 | if (!bValid && !bInvalid) { |
1758 | // edge has not been checked for some reason |
1759 | continue; |
1760 | } |
1761 | // |
1762 | ++aNbChecked; |
1763 | // |
1764 | bInvalidLoc = aMIE.Contains(aEIm); |
1765 | bHasReallyInvalid = bInvalidLoc && !bValid && !theEdgesInvalidByVertex.Contains(aEIm); |
1766 | if (bHasReallyInvalid) { |
1767 | break; |
1768 | } |
1769 | // |
1770 | bNeutral = aMEN.Contains(aEIm); |
1771 | bValidLoc = aMVE.Contains(aEIm); |
1772 | // |
1773 | if (!bInvalid && bCheckInverted) { |
1774 | bInvalid = theMEInverted.Contains(aEIm); |
1775 | } |
1776 | // |
1777 | if (bValidLoc && (bNeutral || aMEValInverted.Contains(aEIm))) { |
1778 | bHasValid = Standard_True; |
1779 | } |
1780 | // |
1781 | bAllValid = bAllValid && bValidLoc; |
1782 | bAllInvalid = bAllInvalid && bInvalid; |
1783 | bAllInvNeutral = bAllInvNeutral && bAllInvalid && bNeutral; |
1784 | } |
1785 | // |
1786 | if (!aNbChecked) { |
1787 | aItLF.Next(); |
1788 | continue; |
1789 | } |
1790 | // |
1791 | if (!bHasReallyInvalid && (bAllInvNeutral && !bHasValid) && (aNbChecked > 1)) { |
1792 | // remove edges from neutral |
1793 | TopExp::MapShapes(aFIm, TopAbs_EDGE, aMENRem); |
1794 | // remove face |
1795 | theLFImages.Remove(aItLF); |
1796 | continue; |
1797 | } |
1798 | // |
1799 | if (bHasReallyInvalid || (bAllInvalid && |
1800 | !(bHasValid || bAllValid) && |
1801 | !(bAllInvNeutral && (aNbChecked == 1)))) { |
1802 | theInvFaces.Append(aFIm); |
a8232603 |
1803 | aItLF.Next(); |
1804 | continue; |
ecf4f17c |
1805 | } |
1806 | // |
1807 | if (!bAllInvNeutral) { |
1808 | aLFPT.Append(aFIm); |
1809 | } |
1810 | else { |
1811 | // remove edges from neutral |
1812 | TopExp::MapShapes(aFIm, TopAbs_EDGE, aMENRem); |
1813 | } |
1814 | aItLF.Next(); |
1815 | } |
1816 | // |
1817 | if (aLFPT.IsEmpty() || aMENRem.IsEmpty()) { |
1818 | return; |
1819 | } |
1820 | // |
1821 | Standard_Integer aNb = aMENRem.Extent(); |
1822 | for (i = 1; i <= aNb; ++i) { |
1823 | aMEN.Remove(aMENRem(i)); |
1824 | } |
1825 | // |
1826 | // check the splits once more |
1827 | aItLF.Initialize(aLFPT); |
1828 | for (; aItLF.More(); aItLF.Next()) { |
1829 | const TopoDS_Face& aFIm = *(TopoDS_Face*)&aItLF.Value(); |
1830 | // |
1831 | // valid edges for this split |
1832 | TopTools_MapOfShape aMVE; |
1833 | const TopTools_ListOfShape* pLVE = theDMFLVE.Seek(aFIm); |
1834 | if (pLVE) { |
1835 | TopTools_ListIteratorOfListOfShape aItLE(*pLVE); |
1836 | for (; aItLE.More(); aItLE.Next()) { |
1837 | const TopoDS_Shape& aE = aItLE.Value(); |
1838 | aMVE.Add(aE); |
1839 | } |
1840 | } |
1841 | // |
1842 | bHasValid = Standard_False; |
1843 | bAllValid = Standard_True; |
1844 | bAllInvalid = Standard_True; |
1845 | // |
1846 | const TopoDS_Wire& aWIm = BRepTools::OuterWire(aFIm); |
1847 | TopExp_Explorer aExp(aWIm, TopAbs_EDGE); |
1848 | for (; aExp.More(); aExp.Next()) { |
1849 | const TopoDS_Shape& aEIm = aExp.Current(); |
1850 | // |
1851 | bValid = theValidEdges.Contains(aEIm); |
1852 | bInvalid = theInvEdges.Contains(aEIm); |
1853 | bNeutral = aMEN.Contains(aEIm); |
1854 | bValidLoc = aMVE.Contains(aEIm); |
1855 | // |
1856 | if (!bInvalid && bCheckInverted) { |
1857 | bInvalid = theMEInverted.Contains(aEIm); |
1858 | } |
1859 | // |
1860 | if (bValidLoc && (bNeutral || aMEValInverted.Contains(aEIm))) { |
1861 | bHasValid = Standard_True; |
1862 | } |
1863 | // |
1864 | bAllValid = bAllValid && bValidLoc; |
1865 | bAllInvalid = bAllInvalid && bInvalid; |
1866 | } |
1867 | // |
1868 | if (bAllInvalid && !bHasValid && !bAllValid) { |
1869 | theInvFaces.Append(aFIm); |
1870 | } |
1871 | } |
1872 | } |
1873 | |
1874 | //======================================================================= |
1875 | //function : GetAverageTangent |
1876 | //purpose : Computes average tangent vector along the curve |
1877 | //======================================================================= |
1878 | gp_Vec GetAverageTangent(const TopoDS_Shape& theS, |
1879 | const Standard_Integer theNbP) |
1880 | { |
1881 | gp_Vec aVA; |
1882 | TopExp_Explorer aExp(theS, TopAbs_EDGE); |
1883 | for (; aExp.More(); aExp.Next()) { |
1884 | const TopoDS_Edge& aE = *(TopoDS_Edge*)&aExp.Current(); |
1885 | // |
1886 | Standard_Real aT1, aT2; |
1887 | const Handle(Geom_Curve)& aC = BRep_Tool::Curve(aE, aT1, aT2); |
1888 | // |
1889 | gp_Pnt aP; |
1890 | gp_Vec aV, aVSum; |
1891 | Standard_Real aT = aT1; |
1892 | Standard_Real aDt = (aT2 - aT1) / theNbP; |
1893 | while (aT <= aT2) { |
1894 | aC->D1(aT, aP, aV); |
1895 | aVSum += aV.Normalized(); |
1896 | aT += aDt; |
1897 | } |
1898 | // |
1899 | if (aE.Orientation() == TopAbs_REVERSED) { |
1900 | aVSum.Reverse(); |
1901 | } |
1902 | // |
1903 | aVA += aVSum; |
1904 | } |
1905 | return aVA; |
1906 | } |
1907 | |
1908 | //======================================================================= |
1909 | //function : CheckInverted |
1910 | //purpose : Checks if the edge has been inverted |
1911 | //======================================================================= |
1912 | Standard_Boolean CheckInverted(const TopoDS_Edge& theEIm, |
1913 | const TopoDS_Face& theFOr, |
1914 | const TopTools_DataMapOfShapeListOfShape& theOEImages, |
1915 | const TopTools_DataMapOfShapeListOfShape& theOEOrigins, |
1916 | const TopTools_DataMapOfShapeListOfShape& theEdgesOrigins, |
1917 | const TopTools_IndexedDataMapOfShapeListOfShape& theDMEF, |
1918 | const TopTools_IndexedDataMapOfShapeListOfShape& theDMVE, |
1919 | const TopTools_IndexedMapOfShape& theMEdges, |
1920 | TopTools_MapOfShape& theMEInverted) |
1921 | { |
1922 | if (theDMEF.FindFromKey(theEIm).Extent() > 1) { |
1923 | return Standard_False; |
1924 | } |
1925 | // |
ecf4f17c |
1926 | // it is necessary to compare the direction from first vertex |
1927 | // to the last vertex on the original edge with the |
1928 | // same direction on the new edge. If the directions |
1929 | // will be different - the edge has been inverted. |
1930 | // |
1931 | TopoDS_Vertex aVI1, aVI2; // vertices on the offset edge |
1932 | TopoDS_Vertex aVO1, aVO2; // vertices on the original edge |
1933 | // |
1934 | Standard_Integer i; |
1935 | // find vertices of the offset shape |
1936 | TopExp::Vertices(theEIm, aVI1, aVI2); |
1937 | // |
1938 | // find images |
1939 | TopTools_ListOfShape aLEImages; |
1940 | if (theOEOrigins.IsBound(theEIm)) { |
1941 | TopoDS_Wire anImages; |
1942 | BRep_Builder().MakeWire(anImages); |
1943 | // |
1944 | TopTools_MapOfShape aMImFence; |
1945 | const TopTools_ListOfShape& aLOffsetOr = theOEOrigins.Find(theEIm); |
1946 | TopTools_ListIteratorOfListOfShape aItOffset(aLOffsetOr); |
1947 | for (; aItOffset.More(); aItOffset.Next()) { |
1948 | const TopoDS_Shape& aEOffsetOr = aItOffset.Value(); |
1949 | const TopTools_ListOfShape& aLImages = theOEImages.Find(aEOffsetOr); |
1950 | // |
1951 | TopTools_ListIteratorOfListOfShape aItImages(aLImages); |
1952 | for (; aItImages.More(); aItImages.Next()) { |
1953 | const TopoDS_Edge& anIm = *(TopoDS_Edge*)&aItImages.Value(); |
1954 | if (theMEdges.Contains(anIm) && aMImFence.Add(anIm)) { |
1955 | BRep_Builder().Add(anImages, anIm); |
1956 | aLEImages.Append(anIm); |
1957 | } |
1958 | } |
1959 | } |
1960 | // |
1961 | // find alone vertices |
1962 | TopoDS_Vertex aVW1, aVW2; |
1963 | TopTools_IndexedDataMapOfShapeListOfShape aDMImVE; |
1964 | TopExp::MapShapesAndAncestors(anImages, TopAbs_VERTEX, TopAbs_EDGE, aDMImVE); |
1965 | // |
1966 | TopTools_ListOfShape aLVAlone; |
1967 | Standard_Integer aNb = aDMImVE.Extent(); |
1968 | for (i = 1; i <= aNb; ++i) { |
1969 | const TopTools_ListOfShape& aLImE = aDMImVE(i); |
1970 | if (aLImE.Extent() == 1) { |
1971 | aLVAlone.Append(aDMImVE.FindKey(i)); |
1972 | } |
1973 | } |
1974 | // |
1975 | if (aLVAlone.Extent() > 1) { |
1976 | aVW1 = *(TopoDS_Vertex*)&aLVAlone.First(); |
1977 | aVW2 = *(TopoDS_Vertex*)&aLVAlone.Last(); |
1978 | // |
1979 | // check distances |
1980 | const gp_Pnt& aPI1 = BRep_Tool::Pnt(aVI1); |
1981 | const gp_Pnt& aPW1 = BRep_Tool::Pnt(aVW1); |
1982 | const gp_Pnt& aPW2 = BRep_Tool::Pnt(aVW2); |
1983 | // |
1984 | Standard_Real aDist1 = aPI1.SquareDistance(aPW1); |
1985 | Standard_Real aDist2 = aPI1.SquareDistance(aPW2); |
1986 | // |
1987 | if (aDist1 < aDist2) { |
1988 | aVI1 = aVW1; |
1989 | aVI2 = aVW2; |
1990 | } |
1991 | else { |
1992 | aVI1 = aVW2; |
1993 | aVI2 = aVW1; |
1994 | } |
1995 | } |
1996 | } |
1997 | else { |
1998 | aLEImages.Append(theEIm); |
1999 | } |
2000 | // |
2001 | // Find edges connected to these vertices |
2002 | const TopTools_ListOfShape& aLIE1 = theDMVE.FindFromKey(aVI1); |
2003 | const TopTools_ListOfShape& aLIE2 = theDMVE.FindFromKey(aVI2); |
2004 | // |
2005 | // Find vertices on the original face corresponding to vertices on the offset edge |
2006 | // |
2007 | // find original edges for both lists |
2008 | TopTools_ListOfShape aLOE1, aLOE2; |
2009 | for (i = 0; i < 2; ++i) { |
2010 | const TopTools_ListOfShape& aLIE = !i ? aLIE1 : aLIE2; |
2011 | TopTools_ListOfShape& aLOE = !i ? aLOE1 : aLOE2; |
2012 | // |
2013 | TopTools_MapOfShape aMFence; |
2014 | // |
2015 | TopTools_ListIteratorOfListOfShape aItLIE(aLIE); |
2016 | for (; aItLIE.More(); aItLIE.Next()) { |
2017 | const TopoDS_Shape& aEI = aItLIE.Value(); |
2018 | if (theEdgesOrigins.IsBound(aEI)) { |
2019 | const TopTools_ListOfShape& aLEOrigins = theEdgesOrigins.Find(aEI); |
2020 | // |
2021 | TopTools_ListIteratorOfListOfShape aItLOE(aLEOrigins); |
2022 | for (; aItLOE.More(); aItLOE.Next()) { |
2023 | const TopoDS_Shape& aEO = aItLOE.Value(); |
2024 | if (aEO.ShapeType() == TopAbs_EDGE && aMFence.Add(aEO)) { |
2025 | TopoDS_Shape aEOin; |
2026 | if (FindShape(aEO, theFOr, aEOin)) { |
b443d536 |
2027 | AppendToList(aLOE, aEO); |
ecf4f17c |
2028 | } |
2029 | } |
2030 | } |
2031 | } |
2032 | } |
2033 | } |
2034 | // |
2035 | if (aLOE1.Extent() < 2 || aLOE2.Extent() < 2) { |
2036 | return Standard_False; |
2037 | } |
2038 | // |
2039 | // find vertices common for all edges in the lists |
2040 | for (i = 0; i < 2; ++i) { |
2041 | const TopTools_ListOfShape& aLOE = !i ? aLOE1 : aLOE2; |
2042 | TopoDS_Vertex& aVO = !i ? aVO1 : aVO2; |
2043 | // |
2044 | const TopoDS_Shape& aEO = aLOE.First(); |
2045 | TopExp_Explorer aExpV(aEO, TopAbs_VERTEX); |
2046 | for (; aExpV.More(); aExpV.Next()) { |
2047 | const TopoDS_Vertex& aV = *(TopoDS_Vertex*)&aExpV.Current(); |
2048 | // |
2049 | Standard_Boolean bVertValid = Standard_True; |
2050 | TopTools_ListIteratorOfListOfShape aItLOE(aLOE); |
2051 | for (aItLOE.Next(); aItLOE.More(); aItLOE.Next()) { |
2052 | const TopoDS_Shape& aEOx = aItLOE.Value(); |
2053 | TopExp_Explorer aExpVx(aEOx, TopAbs_VERTEX); |
2054 | for (; aExpVx.More(); aExpVx.Next()) { |
2055 | const TopoDS_Shape& aVx = aExpVx.Current(); |
2056 | if (aVx.IsSame(aV)) { |
2057 | break; |
2058 | } |
2059 | } |
2060 | // |
2061 | if (!aExpVx.More()) { |
2062 | bVertValid = Standard_False; |
2063 | break; |
2064 | } |
2065 | } |
2066 | // |
2067 | if (bVertValid) { |
2068 | aVO = aV; |
2069 | break; |
2070 | } |
2071 | } |
2072 | } |
2073 | // |
2074 | if (aVO1.IsNull() || aVO2.IsNull() || aVO1.IsSame(aVO2)) { |
2075 | return Standard_False; |
2076 | } |
2077 | // |
2078 | // check positions of the offset and original vertices |
2079 | const gp_Pnt& aPI1 = BRep_Tool::Pnt(aVI1); |
2080 | const gp_Pnt& aPI2 = BRep_Tool::Pnt(aVI2); |
2081 | const gp_Pnt& aPO1 = BRep_Tool::Pnt(aVO1); |
2082 | const gp_Pnt& aPO2 = BRep_Tool::Pnt(aVO2); |
2083 | // |
2084 | gp_Vec aVI(aPI1, aPI2); |
2085 | gp_Vec aVO(aPO1, aPO2); |
2086 | // |
2087 | Standard_Real anAngle = aVI.Angle(aVO); |
2088 | Standard_Boolean bInverted = Abs(anAngle - M_PI) < 1.e-4; |
2089 | if (bInverted) { |
2090 | TopTools_ListIteratorOfListOfShape aItLEIm(aLEImages); |
2091 | for (; aItLEIm.More(); aItLEIm.Next()) { |
2092 | const TopoDS_Shape& aEInvr = aItLEIm.Value(); |
2093 | theMEInverted.Add(aEInvr); |
2094 | } |
2095 | } |
2096 | return bInverted; |
2097 | } |
2098 | |
2099 | //======================================================================= |
2100 | //function : RemoveInvalidSplitsByInvertedEdges |
2101 | //purpose : Looking for the invalid faces containing inverted edges |
2102 | // that can be safely removed |
2103 | //======================================================================= |
2104 | void RemoveInvalidSplitsByInvertedEdges(const TopTools_MapOfShape& theMEInverted, |
2105 | TopTools_IndexedDataMapOfShapeListOfShape& theInvFaces, |
2106 | TopTools_IndexedDataMapOfShapeListOfShape& theFImages, |
2107 | TopTools_IndexedMapOfShape& theMERemoved) |
2108 | { |
2109 | if (theMEInverted.IsEmpty()) { |
2110 | return; |
2111 | } |
2112 | // |
2113 | // check the faces on regularity, i.e. the splits of the same face |
2114 | // should not be connected only by vertex. Such irregular splits |
2115 | // will have to be rebuilt and cannot be removed. |
2116 | // |
2117 | TopTools_MapOfShape aMEAvoid; |
2118 | TopTools_DataMapOfShapeListOfShape aDMVF; |
2119 | Standard_Integer aNb = theFImages.Extent(), i; |
2120 | for (i = 1; i <= aNb; ++i) { |
2121 | const TopTools_ListOfShape& aLFIm = theFImages(i); |
2122 | // |
2123 | TopoDS_Compound aCFIm; |
2124 | BRep_Builder().MakeCompound(aCFIm); |
2125 | // |
2126 | TopTools_DataMapOfShapeListOfShape aDMEF; |
2127 | TopTools_ListIteratorOfListOfShape aIt(aLFIm); |
2128 | for (; aIt.More(); aIt.Next()) { |
2129 | const TopoDS_Shape& aF = aIt.Value(); |
2130 | BRep_Builder().Add(aCFIm, aF); |
2131 | // |
2132 | // make a map to use only outer edges |
2133 | TopExp_Explorer aExp(aF, TopAbs_EDGE); |
2134 | for (; aExp.More(); aExp.Next()) { |
2135 | const TopoDS_Shape& aE = aExp.Current(); |
2136 | // |
2137 | TopTools_ListOfShape *pLF = aDMEF.ChangeSeek(aE); |
2138 | if (!pLF) { |
2139 | TopTools_ListOfShape aLF; |
2140 | aLF.Append(aF); |
2141 | aDMEF.Bind(aE, aLF); |
2142 | } |
2143 | else { |
2144 | pLF->Append(aF); |
2145 | // internal edges should not be used |
2146 | aMEAvoid.Add(aE); |
2147 | } |
2148 | } |
2149 | // |
2150 | // fill connection map of the vertices of inverted edges to faces |
2151 | aExp.Init(aF, TopAbs_VERTEX); |
2152 | for (; aExp.More(); aExp.Next()) { |
2153 | const TopoDS_Shape& aV = aExp.Current(); |
2154 | // |
2155 | TopTools_ListOfShape *pLF = aDMVF.ChangeSeek(aV); |
2156 | if (!pLF) { |
2157 | TopTools_ListOfShape aLF; |
2158 | aLF.Append(aF); |
2159 | aDMVF.Bind(aV, aLF); |
2160 | } |
2161 | else { |
2162 | AppendToList(*pLF, aF); |
2163 | } |
2164 | } |
2165 | } |
2166 | // |
2167 | // for the splits to be regular they should form only one block |
2168 | TopTools_ListOfShape aLCBF; |
2169 | BOPTools_AlgoTools::MakeConnexityBlocks(aCFIm, TopAbs_EDGE, TopAbs_FACE, aLCBF); |
2170 | // |
2171 | if (aLCBF.Extent() > 1) { |
2172 | // non of these edges should be removed |
2173 | TopTools_DataMapIteratorOfDataMapOfShapeListOfShape aItDM(aDMEF); |
2174 | for (; aItDM.More(); aItDM.Next()) { |
2175 | aMEAvoid.Add(aItDM.Key()); |
2176 | } |
2177 | } |
2178 | } |
2179 | // |
2180 | // all edges not included in aMEAvoid can be removed |
2181 | TopTools_MapOfShape aMERem; |
2182 | TopTools_MapIteratorOfMapOfShape aItM(theMEInverted); |
2183 | for (; aItM.More(); aItM.Next()) { |
2184 | const TopoDS_Shape& aE = aItM.Value(); |
2185 | if (!aMEAvoid.Contains(aE)) { |
2186 | TopoDS_Iterator aIt(aE); |
2187 | for (; aIt.More(); aIt.Next()) { |
2188 | const TopoDS_Shape& aV = aIt.Value(); |
2189 | const TopTools_ListOfShape *pLF = aDMVF.Seek(aV); |
2190 | if (pLF && (pLF->Extent() > 3)) { |
2191 | aMERem.Add(aE); |
2192 | break; |
2193 | } |
2194 | } |
2195 | } |
2196 | } |
2197 | // |
2198 | if (aMERem.IsEmpty()) { |
2199 | return; |
2200 | } |
2201 | // |
2202 | // all invalid faces containing these edges can be removed |
2203 | TopTools_IndexedDataMapOfShapeListOfShape aInvFaces; |
2204 | TopTools_MapOfShape aMFRem; |
2205 | TopTools_IndexedMapOfShape aMFToUpdate; |
2206 | aNb = theInvFaces.Extent(); |
2207 | for (i = 1; i <= aNb; ++i) { |
2208 | const TopoDS_Shape& aF = theInvFaces.FindKey(i); |
2209 | TopTools_ListOfShape& aLFIm = theInvFaces(i); |
2210 | // |
2211 | TopTools_ListIteratorOfListOfShape aIt(aLFIm); |
2212 | for (; aIt.More(); ) { |
2213 | const TopoDS_Shape& aFIm = aIt.Value(); |
2214 | // |
2215 | // to be removed the face should have at least two not connected |
2216 | // inverted edges |
2217 | TopoDS_Compound aCEInv; |
2218 | BRep_Builder().MakeCompound(aCEInv); |
2219 | TopExp_Explorer aExp(aFIm, TopAbs_EDGE); |
2220 | for (; aExp.More(); aExp.Next()) { |
2221 | const TopoDS_Shape& aE = aExp.Current(); |
2222 | // |
2223 | if (aMERem.Contains(aE)) { |
2224 | BRep_Builder().Add(aCEInv, aE); |
2225 | } |
2226 | } |
2227 | // |
2228 | // check connectivity |
2229 | TopTools_ListOfShape aLCBE; |
2230 | BOPTools_AlgoTools::MakeConnexityBlocks(aCEInv, TopAbs_VERTEX, TopAbs_EDGE, aLCBE); |
2231 | // |
2232 | if (aLCBE.Extent() >= 2) { |
2233 | aMFToUpdate.Add(aF); |
2234 | aMFRem.Add(aFIm); |
2235 | aLFIm.Remove(aIt); |
2236 | } |
2237 | else { |
2238 | aIt.Next(); |
2239 | } |
2240 | } |
2241 | // |
2242 | if (aLFIm.Extent()) { |
2243 | aInvFaces.Add(aF, aLFIm); |
2244 | } |
2245 | } |
2246 | // |
2247 | if (aMFRem.IsEmpty()) { |
2248 | return; |
2249 | } |
2250 | // |
2251 | theInvFaces = aInvFaces; |
2252 | // remove from splits |
2253 | aNb = aMFToUpdate.Extent(); |
2254 | for (i = 1; i <= aNb; ++i) { |
2255 | const TopoDS_Shape& aF = aMFToUpdate(i); |
2256 | TopTools_ListOfShape& aLFIm = theFImages.ChangeFromKey(aF); |
2257 | // |
2258 | TopTools_ListIteratorOfListOfShape aIt(aLFIm); |
2259 | for (; aIt.More(); ) { |
2260 | const TopoDS_Shape& aFIm = aIt.Value(); |
2261 | if (aMFRem.Contains(aFIm)) { |
2262 | TopExp::MapShapes(aFIm, TopAbs_EDGE, theMERemoved); |
2263 | aLFIm.Remove(aIt); |
2264 | } |
2265 | else { |
2266 | aIt.Next(); |
2267 | } |
2268 | } |
2269 | } |
2270 | } |
2271 | |
2272 | //======================================================================= |
2273 | //function : RemoveInvalidSplitsFromValid |
2274 | //purpose : Removing invalid splits of faces from valid |
2275 | //======================================================================= |
2276 | void RemoveInvalidSplitsFromValid(const TopTools_IndexedDataMapOfShapeListOfShape& theInvFaces, |
2277 | const TopTools_DataMapOfShapeShape& theArtInvFaces, |
2278 | const TopTools_MapOfShape& theMEInverted, |
2279 | TopTools_IndexedDataMapOfShapeListOfShape& theFImages) |
2280 | { |
2281 | // Decide whether to remove the found invalid faces or not. |
2282 | // The procedure is the following: |
2283 | // 1. Make connexity blocks from invalid faces; |
2284 | // 2. Find free edges in this blocks; |
2285 | // 3. If all free edges are valid for the faces - remove block. |
2286 | // |
2287 | TopTools_MapOfShape aMFence, aMFToRem; |
2288 | TopoDS_Compound aCFInv; |
2289 | BRep_Builder aBB; |
2290 | aBB.MakeCompound(aCFInv); |
2291 | TopTools_ListIteratorOfListOfShape aItLF; |
2292 | // |
2293 | // make compound of invalid faces |
2294 | TopTools_DataMapOfShapeShape aDMIFOF; |
2295 | Standard_Integer i, aNb = theInvFaces.Extent(); |
2296 | for (i = 1; i <= aNb; ++i) { |
2297 | const TopoDS_Shape& aF = theInvFaces.FindKey(i); |
2298 | // artificially invalid faces should not be removed |
2299 | if (theArtInvFaces.IsBound(aF)) { |
2300 | continue; |
2301 | } |
2302 | const TopTools_ListOfShape& aLFInv = theInvFaces(i); |
2303 | aItLF.Initialize(aLFInv); |
2304 | for (; aItLF.More(); aItLF.Next()) { |
2305 | const TopoDS_Shape& aFIm = aItLF.Value(); |
2306 | if (aMFence.Add(aFIm)) { |
2307 | aBB.Add(aCFInv, aFIm); |
2308 | aDMIFOF.Bind(aFIm, aF); |
2309 | } |
2310 | } |
2311 | } |
2312 | // |
2313 | // make connexity blocks |
2314 | TopTools_ListOfShape aLCBInv; |
2315 | BOPTools_AlgoTools::MakeConnexityBlocks(aCFInv, TopAbs_EDGE, TopAbs_FACE, aLCBInv); |
2316 | // |
2317 | // analyze each block |
2318 | aItLF.Initialize(aLCBInv); |
2319 | for (; aItLF.More(); aItLF.Next()) { |
2320 | const TopoDS_Shape& aCB = aItLF.Value(); |
2321 | // |
2322 | // if connexity block contains only one face - it should be removed; |
2323 | TopExp_Explorer aExp(aCB, TopAbs_FACE); |
2324 | aExp.Next(); |
2325 | if (aExp.More()) { |
2326 | // check if there are valid images left |
2327 | aExp.Init(aCB, TopAbs_FACE); |
2328 | for (; aExp.More(); aExp.Next()) { |
2329 | const TopoDS_Shape& aFIm = aExp.Current(); |
2330 | const TopoDS_Shape& aF = aDMIFOF.Find(aFIm); |
2331 | // |
2332 | const TopTools_ListOfShape& aLFIm = theFImages.FindFromKey(aF); |
2333 | const TopTools_ListOfShape& aLFInv = theInvFaces.FindFromKey(aF); |
2334 | // |
2335 | if (aLFIm.Extent() == aLFInv.Extent()) { |
2336 | break; |
2337 | } |
2338 | } |
2339 | } |
2340 | // |
2341 | if (!aExp.More()) { |
2342 | aExp.Init(aCB, TopAbs_FACE); |
2343 | for (; aExp.More(); aExp.Next()) { |
2344 | const TopoDS_Shape& aF = aExp.Current(); |
2345 | aMFToRem.Add(aF); |
2346 | } |
2347 | continue; |
2348 | } |
2349 | // |
2350 | // remove faces connected by inverted edges |
2351 | TopTools_IndexedDataMapOfShapeListOfShape aDMEF; |
2352 | TopExp::MapShapesAndAncestors(aCB, TopAbs_EDGE, TopAbs_FACE, aDMEF); |
2353 | // |
2354 | aExp.Init(aCB, TopAbs_FACE); |
2355 | for (; aExp.More(); aExp.Next()) { |
2356 | const TopoDS_Shape& aFCB = aExp.Current(); |
2357 | // |
2358 | TopExp_Explorer aExpE(aFCB, TopAbs_EDGE); |
2359 | for (; aExpE.More(); aExpE.Next()) { |
2360 | const TopoDS_Shape& aECB = aExpE.Current(); |
2361 | if (aDMEF.FindFromKey(aECB).Extent() > 1) { |
2362 | if (!theMEInverted.Contains(aECB)) { |
2363 | break; |
2364 | } |
2365 | } |
2366 | } |
2367 | // |
2368 | if (!aExpE.More()) { |
2369 | aMFToRem.Add(aFCB); |
2370 | } |
2371 | } |
2372 | } |
2373 | // |
2374 | if (aMFToRem.Extent()) { |
2375 | // remove invalid faces from images |
2376 | aNb = theInvFaces.Extent(); |
2377 | for (i = 1; i <= aNb; ++i) { |
2378 | const TopoDS_Shape& aF = theInvFaces.FindKey(i); |
2379 | TopTools_ListOfShape& aLFImages = theFImages.ChangeFromKey(aF); |
2380 | aItLF.Initialize(aLFImages); |
2381 | for (; aItLF.More();) { |
2382 | const TopoDS_Shape& aFIm = aItLF.Value(); |
2383 | if (aMFToRem.Contains(aFIm)) { |
2384 | aLFImages.Remove(aItLF); |
2385 | } |
2386 | else { |
2387 | aItLF.Next(); |
2388 | } |
2389 | } |
2390 | } |
2391 | } |
2392 | } |
2393 | |
2394 | //======================================================================= |
2395 | //function : RemoveInsideFaces |
2396 | //purpose : Looking for the inside faces that can be safely removed |
2397 | //======================================================================= |
2398 | void RemoveInsideFaces(TopTools_IndexedDataMapOfShapeListOfShape& theFImages, |
2399 | TopTools_IndexedDataMapOfShapeListOfShape& theInvFaces, |
2400 | const TopTools_DataMapOfShapeShape& theArtInvFaces, |
2401 | const TopTools_IndexedMapOfShape& theInvEdges, |
2402 | const TopTools_IndexedMapOfShape& theMFToCheckInt, |
2403 | TopTools_DataMapOfShapeListOfShape& theSSInterfs, |
2404 | TopTools_IndexedMapOfShape& theMERemoved, |
2405 | TopoDS_Shape& theSolids) |
2406 | { |
2407 | BOPCol_ListOfShape aLS; |
2408 | TopTools_MapOfShape aMFence; |
2409 | TopTools_IndexedMapOfShape aMFInv; |
2410 | TopTools_ListIteratorOfListOfShape aItLF; |
2411 | TopTools_DataMapOfShapeShape aDMFImF; |
2412 | // |
2413 | Standard_Integer i, aNb = theFImages.Extent(); |
2414 | for (i = 1; i <= aNb; ++i) { |
2415 | const TopoDS_Shape& aF = theFImages.FindKey(i); |
2416 | // to avoid intersection of the splits of the same |
2417 | // offset faces among themselves make compound of the |
2418 | // splits and use it as one argument |
2419 | TopoDS_Compound aCFImi; |
2420 | BRep_Builder().MakeCompound(aCFImi); |
2421 | // |
2422 | for (Standard_Integer j = 0; j < 2; ++j) { |
2423 | const TopTools_ListOfShape* pLFSp = !j ? theInvFaces.Seek(aF) : &theFImages(i); |
2424 | if (!pLFSp) { |
2425 | continue; |
2426 | } |
2427 | // |
2428 | aItLF.Initialize(*pLFSp); |
2429 | for (; aItLF.More(); aItLF.Next()) { |
2430 | const TopoDS_Shape& aFIm = aItLF.Value(); |
2431 | if (aMFence.Add(aFIm)) { |
2432 | BRep_Builder().Add(aCFImi, aFIm); |
2433 | aDMFImF.Bind(aFIm, aF); |
2434 | if (!j) { |
2435 | aMFInv.Add(aFIm); |
2436 | } |
2437 | } |
2438 | } |
2439 | } |
2440 | // |
2441 | aLS.Append(aCFImi); |
2442 | } |
2443 | // |
2444 | // to make the solids more complete add for intersection also the faces |
2445 | // consisting only of invalid edges and not included into splits |
2446 | aNb = theMFToCheckInt.Extent(); |
2447 | for (i = 1; i <= aNb; ++i) { |
2448 | const TopoDS_Shape& aFSp = theMFToCheckInt(i); |
2449 | if (aMFence.Add(aFSp)) { |
2450 | aLS.Append(aFSp); |
2451 | } |
2452 | } |
2453 | // |
2454 | BOPAlgo_MakerVolume aMV; |
2455 | aMV.SetArguments(aLS); |
2456 | aMV.SetIntersect(Standard_True); |
2457 | aMV.Perform(); |
2458 | // |
2459 | // get shapes connection for using in the rebuilding process |
2460 | // for the cases in which some of the intersection left undetected |
2461 | ShapesConnections(theInvFaces, theInvEdges, aDMFImF, aMV, theSSInterfs); |
2462 | // |
2463 | // find faces to remove |
2464 | const TopoDS_Shape& aSols = aMV.Shape(); |
2465 | // |
2466 | TopTools_IndexedDataMapOfShapeListOfShape aDMFS; |
2467 | TopExp::MapShapesAndAncestors(aSols, TopAbs_FACE, TopAbs_SOLID, aDMFS); |
2468 | // |
2469 | aNb = aDMFS.Extent(); |
2470 | if (!aNb) { |
2471 | return; |
2472 | } |
2473 | // |
2474 | // To use the created solids for classifications, firstly, it is necessary |
2475 | // to check them on validity - the created solids should be complete, |
2476 | // i.e. all faces should be included. |
2477 | // |
2478 | // Check completeness |
2479 | if (aMV.HasDeleted()) { |
2480 | // perform additional check on faces |
2481 | aNb = theFImages.Extent(); |
2482 | for (i = 1; i <= aNb; ++i) { |
2483 | const TopTools_ListOfShape& aLFIm = theFImages(i); |
2484 | if (aLFIm.IsEmpty()) { |
2485 | continue; |
2486 | } |
2487 | // |
2488 | aItLF.Initialize(aLFIm); |
2489 | for (; aItLF.More(); aItLF.Next()) { |
2490 | const TopoDS_Shape& aFIm = aItLF.Value(); |
2491 | if (!aMV.IsDeleted(aFIm)) { |
2492 | break; |
2493 | } |
2494 | } |
2495 | // |
2496 | if (!aItLF.More()) { |
2497 | return; |
2498 | } |
2499 | } |
2500 | } |
2501 | // |
2502 | TopTools_MapOfShape aMFToRem; |
2503 | aNb = aDMFS.Extent(); |
2504 | for (i = 1; i <= aNb; ++i) { |
2505 | const TopTools_ListOfShape& aLSol = aDMFS(i); |
2506 | if (aLSol.Extent() > 1) { |
2507 | const TopoDS_Shape& aFIm = aDMFS.FindKey(i); |
2508 | aMFToRem.Add(aFIm); |
2509 | } |
2510 | } |
2511 | // |
2512 | // update invalid faces with images |
2513 | aNb = aMFInv.Extent(); |
2514 | for (i = 1; i <= aNb; ++i) { |
2515 | const TopoDS_Shape& aFInv = aMFInv(i); |
2516 | const TopTools_ListOfShape& aLFInvIm = aMV.Modified(aFInv); |
2517 | TopTools_ListIteratorOfListOfShape aItLFInvIm(aLFInvIm); |
2518 | for (; aItLFInvIm.More(); aItLFInvIm.Next()) { |
2519 | const TopoDS_Shape& aFInvIm = aItLFInvIm.Value(); |
2520 | aMFInv.Add(aFInvIm); |
2521 | } |
2522 | } |
2523 | // |
2524 | TopoDS_Compound aSolids; |
2525 | BRep_Builder().MakeCompound(aSolids); |
b443d536 |
2526 | TopTools_MapOfShape aMFKeep; |
ecf4f17c |
2527 | // |
2528 | TopExp_Explorer aExpS(aSols, TopAbs_SOLID); |
2529 | for (; aExpS.More(); aExpS.Next()) { |
2530 | const TopoDS_Shape& aSol = aExpS.Current(); |
2531 | // |
2532 | Standard_Boolean bAllInv(Standard_True), bAllRemoved(Standard_True); |
2533 | |
45d0af05 |
2534 | for (TopExp_Explorer aExpF(aSol, TopAbs_FACE); aExpF.More(); aExpF.Next()) |
2535 | { |
ecf4f17c |
2536 | const TopoDS_Shape& aFS = aExpF.Current(); |
2537 | // |
2538 | if (aFS.Orientation() == TopAbs_INTERNAL) { |
2539 | aMFToRem.Add(aFS); |
2540 | } |
2541 | // |
2542 | bAllRemoved = bAllRemoved && aMFToRem.Contains(aFS); |
2543 | bAllInv = bAllInv && (aMFToRem.Contains(aFS) || aMFInv.Contains(aFS)); |
2544 | } |
2545 | // |
2546 | if (bAllInv && !bAllRemoved) { |
2547 | // remove invalid faces but keep those that have already been marked for removal |
2548 | TopExp_Explorer aExpF(aSol, TopAbs_FACE); |
2549 | for (; aExpF.More(); aExpF.Next()) { |
2550 | const TopoDS_Shape& aFS = aExpF.Current(); |
2551 | // |
2552 | if (aMFToRem.Contains(aFS)) { |
b443d536 |
2553 | if (!aMFKeep.Add(aFS)) { |
2554 | aMFKeep.Remove(aFS); |
2555 | } |
ecf4f17c |
2556 | } |
2557 | else { |
2558 | aMFToRem.Add(aFS); |
2559 | } |
2560 | } |
2561 | } |
2562 | else { |
2563 | BRep_Builder().Add(aSolids, aSol); |
2564 | theSolids = aSolids; |
2565 | } |
2566 | } |
2567 | // |
b443d536 |
2568 | TopTools_MapIteratorOfMapOfShape aItM(aMFKeep); |
2569 | for (; aItM.More(); aItM.Next()) { |
2570 | aMFToRem.Remove(aItM.Value()); |
2571 | } |
2572 | // |
ecf4f17c |
2573 | // remove newly found internal faces |
2574 | RemoveValidSplits(aMFToRem, theFImages, aMV, theMERemoved); |
2575 | RemoveInvalidSplits(aMFToRem, theArtInvFaces, theInvEdges, theInvFaces, aMV, theMERemoved); |
2576 | } |
2577 | |
2578 | //======================================================================= |
2579 | //function : ShapesConnections |
2580 | //purpose : Looking for the connections between faces not to miss |
2581 | // some necessary intersection |
2582 | //======================================================================= |
2583 | void ShapesConnections(const TopTools_IndexedDataMapOfShapeListOfShape& theInvFaces, |
2584 | const TopTools_IndexedMapOfShape& theInvEdges, |
2585 | const TopTools_DataMapOfShapeShape& theDMFOr, |
2586 | BOPAlgo_Builder& theBuilder, |
2587 | TopTools_DataMapOfShapeListOfShape& theSSInterfs) |
2588 | { |
2589 | // update invalid edges with images and keep connection to original edge |
2590 | TopTools_DataMapOfShapeListOfShape aDMEOr; |
45d0af05 |
2591 | Standard_Integer aNb = theInvEdges.Extent(); |
2592 | for (Standard_Integer i = 1; i <= aNb; ++i) { |
ecf4f17c |
2593 | const TopoDS_Shape& aEInv = theInvEdges(i); |
2594 | const TopTools_ListOfShape& aLEIm = theBuilder.Modified(aEInv); |
2595 | if (aLEIm.IsEmpty()) { |
2596 | aDMEOr.Bound(aEInv, TopTools_ListOfShape())->Append(aEInv); |
2597 | continue; |
2598 | } |
2599 | // |
2600 | TopTools_ListIteratorOfListOfShape aItLEIm(aLEIm); |
2601 | for (; aItLEIm.More(); aItLEIm.Next()) { |
2602 | const TopoDS_Shape& aEIm = aItLEIm.Value(); |
2603 | // |
2604 | TopTools_ListOfShape* pLEOr = aDMEOr.ChangeSeek(aEIm); |
2605 | if (!pLEOr) { |
2606 | pLEOr = aDMEOr.Bound(aEIm, TopTools_ListOfShape()); |
2607 | } |
2608 | AppendToList(*pLEOr, aEInv); |
2609 | } |
2610 | } |
2611 | // |
2612 | // get shapes connections for using in the rebuilding process |
2613 | const BOPDS_PDS& pDS = theBuilder.PDS(); |
2614 | // analyze all Face/Face intersections |
2615 | const BOPDS_VectorOfInterfFF& aFFs = pDS->InterfFF(); |
2616 | Standard_Integer iInt, aNbFF = aFFs.Extent(); |
2617 | for (iInt = 0; iInt < aNbFF; ++iInt) { |
2618 | const BOPDS_InterfFF& aFF = aFFs(iInt); |
2619 | const BOPDS_VectorOfCurve& aVNC = aFF.Curves(); |
2620 | Standard_Integer aNbC = aVNC.Extent(); |
2621 | if (!aNbC) { |
2622 | continue; |
2623 | } |
2624 | // |
2625 | const TopoDS_Shape& aFIm1 = pDS->Shape(aFF.Index1()); |
2626 | const TopoDS_Shape& aFIm2 = pDS->Shape(aFF.Index2()); |
2627 | // |
2628 | const TopoDS_Shape* pF1 = theDMFOr.Seek(aFIm1); |
2629 | const TopoDS_Shape* pF2 = theDMFOr.Seek(aFIm2); |
2630 | // |
2631 | if (!pF1 || !pF2) { |
2632 | continue; |
2633 | } |
2634 | // |
2635 | if (pF1->IsSame(*pF2)) { |
2636 | continue; |
2637 | } |
2638 | // |
2639 | Standard_Boolean bInv1 = theInvFaces.Contains(*pF1); |
2640 | Standard_Boolean bInv2 = theInvFaces.Contains(*pF2); |
2641 | // |
2642 | if (!bInv1 && !bInv2) { |
2643 | continue; |
2644 | } |
2645 | // |
2646 | // check if it is real Face/Face intersection |
2647 | TopTools_MapOfShape aMEInt; |
2648 | for (Standard_Integer iC = 0; iC < aNbC; ++iC) { |
2649 | const BOPDS_Curve& aNC = aVNC(iC); |
2650 | const BOPDS_ListOfPaveBlock& aLPB = aNC.PaveBlocks(); |
2651 | BOPDS_ListIteratorOfListOfPaveBlock aItLPB(aLPB); |
2652 | for (; aItLPB.More(); aItLPB.Next()) { |
2653 | const Handle(BOPDS_PaveBlock)& aPB = aItLPB.Value(); |
2654 | Standard_Integer nEInt; |
2655 | if (aPB->HasEdge(nEInt)) { |
2656 | const TopoDS_Shape& aEInt = pDS->Shape(nEInt); |
2657 | aMEInt.Add(aEInt); |
2658 | } |
2659 | } |
2660 | } |
2661 | // |
2662 | if (aMEInt.IsEmpty()) { |
2663 | continue; |
2664 | } |
2665 | // |
2666 | // check if invalid edges of the face are in the same splits with intersection edges |
2667 | for (Standard_Integer i = 0; i < 2; ++i) { |
2668 | if ((!i && !bInv1) || (i && !bInv2)) { |
2669 | continue; |
2670 | } |
2671 | // |
2672 | const TopoDS_Shape& aF = !i ? *pF1 : *pF2; |
2673 | const TopoDS_Shape& aFOp = !i ? *pF2 : *pF1; |
2674 | const TopoDS_Shape& aFIm = !i ? aFIm1 : aFIm2; |
2675 | // |
2676 | Standard_Boolean bFound = Standard_False; |
2677 | // |
2678 | TopTools_ListOfShape aLFIm = theBuilder.Modified(aFIm); |
2679 | if (aLFIm.IsEmpty()) { |
2680 | aLFIm.Append(aFIm); |
2681 | } |
2682 | // |
2683 | TopTools_ListIteratorOfListOfShape aItLFIm(aLFIm); |
2684 | for (; aItLFIm.More(); aItLFIm.Next()) { |
2685 | const TopoDS_Shape& aFImIm = aItLFIm.Value(); |
2686 | // |
2687 | Standard_Boolean bInv(Standard_False), bInt(Standard_False); |
2688 | TopExp_Explorer aExpE(aFImIm, TopAbs_EDGE); |
2689 | for (; aExpE.More(); aExpE.Next()) { |
2690 | const TopoDS_Shape& aE = aExpE.Current(); |
2691 | if (!bInv) { |
2692 | bInv = aDMEOr.IsBound(aE); |
2693 | } |
2694 | if (!bInt) { |
2695 | bInt = aMEInt.Contains(aE); |
2696 | } |
2697 | if (bInv && bInt) { |
2698 | break; |
2699 | } |
2700 | } |
2701 | // |
2702 | if (!bInt || !bInv) { |
2703 | continue; |
2704 | } |
2705 | // |
2706 | bFound = Standard_True; |
2707 | // |
2708 | // append opposite face to all invalid edges in the split |
2709 | aExpE.Init(aFImIm, TopAbs_EDGE); |
2710 | for (; aExpE.More(); aExpE.Next()) { |
2711 | const TopoDS_Shape& aE = aExpE.Current(); |
2712 | const TopTools_ListOfShape* pLEOr = aDMEOr.Seek(aE); |
2713 | if (!pLEOr) { |
2714 | continue; |
2715 | } |
2716 | // |
2717 | TopTools_ListIteratorOfListOfShape aItLE(*pLEOr); |
2718 | for (; aItLE.More(); aItLE.Next()) { |
2719 | const TopoDS_Shape& aEOr = aItLE.Value(); |
2720 | TopTools_ListOfShape *pLFE = theSSInterfs.ChangeSeek(aEOr); |
2721 | if (!pLFE) { |
2722 | pLFE = theSSInterfs.Bound(aEOr, TopTools_ListOfShape()); |
2723 | } |
2724 | AppendToList(*pLFE, aFOp); |
2725 | } |
2726 | } |
2727 | } |
2728 | if (bFound) { |
2729 | // save connection between offset faces |
2730 | TopTools_ListOfShape *pLF = theSSInterfs.ChangeSeek(aF); |
2731 | if (!pLF) { |
2732 | pLF = theSSInterfs.Bound(aF, TopTools_ListOfShape()); |
2733 | } |
2734 | AppendToList(*pLF, aFOp); |
2735 | } |
2736 | } |
2737 | } |
2738 | } |
2739 | |
2740 | //======================================================================= |
2741 | //function : RemoveValidSplits |
2742 | //purpose : Removing valid splits according to results of intersection |
2743 | //======================================================================= |
2744 | void RemoveValidSplits(const TopTools_MapOfShape& theSpRem, |
2745 | TopTools_IndexedDataMapOfShapeListOfShape& theImages, |
2746 | BOPAlgo_Builder& theGF, |
2747 | TopTools_IndexedMapOfShape& theMERemoved) |
2748 | { |
2749 | Standard_Integer i, aNb = theImages.Extent(); |
2750 | if (!aNb) { |
2751 | return; |
2752 | } |
2753 | // |
2754 | for (i = 1; i <= aNb; ++i) { |
2755 | TopTools_ListOfShape& aLSIm = theImages(i); |
2756 | TopTools_ListIteratorOfListOfShape aIt(aLSIm); |
2757 | for (; aIt.More(); ) { |
2758 | const TopoDS_Shape& aSIm = aIt.Value(); |
2759 | if (theSpRem.Contains(aSIm)) { |
2760 | TopExp::MapShapes(aSIm, TopAbs_EDGE, theMERemoved); |
2761 | aLSIm.Remove(aIt); |
2762 | continue; |
2763 | } |
2764 | // |
2765 | // check if all its images are have to be removed |
2766 | const TopTools_ListOfShape& aLSImIm = theGF.Modified(aSIm); |
2767 | if (aLSImIm.Extent()) { |
2768 | Standard_Boolean bAllRem = Standard_True; |
2769 | TopTools_ListIteratorOfListOfShape aIt1(aLSImIm); |
2770 | for (; aIt1.More(); aIt1.Next()) { |
2771 | const TopoDS_Shape& aSImIm = aIt1.Value(); |
2772 | if (theSpRem.Contains(aSImIm)) { |
2773 | TopExp::MapShapes(aSImIm, TopAbs_EDGE, theMERemoved); |
2774 | } |
2775 | else { |
2776 | bAllRem = Standard_False; |
2777 | } |
2778 | } |
2779 | // |
2780 | if (bAllRem) { |
2781 | TopExp::MapShapes(aSIm, TopAbs_EDGE, theMERemoved); |
2782 | aLSIm.Remove(aIt); |
2783 | continue; |
2784 | } |
2785 | } |
2786 | aIt.Next(); |
2787 | } |
2788 | } |
2789 | } |
2790 | |
2791 | //======================================================================= |
2792 | //function : RemoveInvalidSplits |
2793 | //purpose : Removing invalid splits according to the results of intersection |
2794 | //======================================================================= |
2795 | void RemoveInvalidSplits(const TopTools_MapOfShape& theSpRem, |
2796 | const TopTools_DataMapOfShapeShape& theArtInvFaces, |
2797 | const TopTools_IndexedMapOfShape& theInvEdges, |
2798 | TopTools_IndexedDataMapOfShapeListOfShape& theImages, |
2799 | BOPAlgo_Builder& theGF, |
2800 | TopTools_IndexedMapOfShape& theMERemoved) |
2801 | { |
2802 | Standard_Integer i, aNb = theImages.Extent(); |
2803 | if (!aNb) { |
2804 | return; |
2805 | } |
2806 | // |
2807 | for (i = 1; i <= aNb; ++i) { |
2808 | const TopoDS_Shape& aS = theImages.FindKey(i); |
2809 | Standard_Boolean bArt = theArtInvFaces.IsBound(aS); |
2810 | // |
2811 | TopTools_ListOfShape& aLSIm = theImages(i); |
2812 | TopTools_ListIteratorOfListOfShape aIt(aLSIm); |
2813 | for (; aIt.More();) { |
2814 | const TopoDS_Shape& aSIm = aIt.Value(); |
2815 | if (theSpRem.Contains(aSIm)) { |
2816 | TopExp::MapShapes(aSIm, TopAbs_EDGE, theMERemoved); |
2817 | aLSIm.Remove(aIt); |
2818 | continue; |
2819 | } |
2820 | // |
2821 | // check if all its images are have to be removed |
2822 | const TopTools_ListOfShape& aLSImIm = theGF.Modified(aSIm); |
2823 | if (aLSImIm.IsEmpty()) { |
2824 | aIt.Next(); |
2825 | continue; |
2826 | } |
2827 | // |
2828 | Standard_Boolean bAllRem = Standard_True; |
2829 | TopTools_IndexedMapOfShape aMERemoved; |
2830 | TopTools_ListIteratorOfListOfShape aIt1(aLSImIm); |
2831 | for (; aIt1.More(); aIt1.Next()) { |
2832 | const TopoDS_Shape& aSImIm = aIt1.Value(); |
2833 | if (theSpRem.Contains(aSImIm)) { |
2834 | TopExp::MapShapes(aSImIm, TopAbs_EDGE, aMERemoved); |
2835 | } |
2836 | else { |
2837 | bAllRem = Standard_False; |
2838 | } |
2839 | } |
2840 | // |
2841 | if (bAllRem) { |
2842 | aLSIm.Remove(aIt); |
2843 | continue; |
2844 | } |
2845 | // |
2846 | if (bArt) { |
2847 | aIt.Next(); |
2848 | continue; |
2849 | } |
2850 | // |
2851 | // remove the face from invalid if all invalid edges of this face |
2852 | // have been marked for removal |
2853 | TopExp_Explorer aExpE(aSIm, TopAbs_EDGE); |
2854 | for (; aExpE.More(); aExpE.Next()) { |
2855 | const TopoDS_Shape& aEInv = aExpE.Current(); |
2856 | if (theInvEdges.Contains(aEInv) && !aMERemoved.Contains(aEInv)) { |
2857 | break; |
2858 | } |
2859 | } |
2860 | if (!aExpE.More()) { |
2861 | TopExp::MapShapes(aSIm, TopAbs_EDGE, theMERemoved); |
2862 | aLSIm.Remove(aIt); |
2863 | } |
2864 | else { |
2865 | aIt.Next(); |
2866 | } |
2867 | } |
2868 | } |
2869 | } |
2870 | |
2871 | //======================================================================= |
2872 | //function : FilterEdgesImages |
2873 | //purpose : Updating the maps of images and origins of the offset edges |
2874 | //======================================================================= |
2875 | void FilterEdgesImages(const TopoDS_Shape& theS, |
2876 | TopTools_DataMapOfShapeListOfShape& theOEImages, |
2877 | TopTools_DataMapOfShapeListOfShape& theOEOrigins) |
2878 | { |
2879 | // map edges |
2880 | TopTools_IndexedMapOfShape aME; |
2881 | TopExp::MapShapes(theS, TopAbs_EDGE, aME); |
2882 | // |
2883 | theOEOrigins.Clear(); |
2884 | TopTools_DataMapIteratorOfDataMapOfShapeListOfShape aItDM(theOEImages); |
2885 | for (; aItDM.More(); aItDM.Next()) { |
2886 | const TopoDS_Shape& aE = aItDM.Key(); |
2887 | TopTools_ListOfShape& aLEIm = aItDM.ChangeValue(); |
2888 | // |
2889 | TopTools_ListIteratorOfListOfShape aIt(aLEIm); |
2890 | for (; aIt.More(); ) { |
2891 | const TopoDS_Shape& aEIm = aIt.Value(); |
2892 | // filter images |
2893 | if (!aME.Contains(aEIm)) { |
2894 | // remove the image |
2895 | // edges with no images left should be kept in the map |
2896 | // to avoid their usage when building the splits of faces |
2897 | aLEIm.Remove(aIt); |
2898 | continue; |
2899 | } |
2900 | // |
2901 | // save origins |
2902 | if (theOEOrigins.IsBound(aEIm)) { |
2903 | AppendToList(theOEOrigins.ChangeFind(aEIm), aE); |
2904 | } |
2905 | else { |
2906 | TopTools_ListOfShape aLOr; |
2907 | aLOr.Append(aE); |
2908 | theOEOrigins.Bind(aEIm, aLOr); |
2909 | } |
2910 | // |
2911 | aIt.Next(); |
2912 | } |
2913 | } |
2914 | } |
2915 | |
2916 | //======================================================================= |
2917 | //function : FilterInvalidFaces |
2918 | //purpose : Filtering of the invalid faces |
2919 | //======================================================================= |
2920 | void FilterInvalidFaces(const TopTools_IndexedDataMapOfShapeListOfShape& theFImages, |
2921 | const TopTools_IndexedDataMapOfShapeListOfShape& theDMFE, |
2922 | TopTools_IndexedDataMapOfShapeListOfShape& theInvFaces, |
2923 | TopTools_DataMapOfShapeShape& theArtInvFaces) |
2924 | { |
2925 | // |
2926 | // filter invalid faces, considering faces having only valid |
2927 | // images left with non-free edges as valid |
2928 | // do not remove invalid faces if it creates free edges |
2929 | // |
2930 | TopTools_IndexedDataMapOfShapeListOfShape aReallyInvFaces; |
2931 | TopTools_ListIteratorOfListOfShape aItLF; |
2932 | // |
2933 | Standard_Integer i, aNb = theInvFaces.Extent(); |
2934 | for (i = 1; i <= aNb; ++i) { |
2935 | const TopoDS_Shape& aF = theInvFaces.FindKey(i); |
2936 | const TopTools_ListOfShape& aLFInv = theInvFaces(i); |
2937 | // |
2938 | if (theArtInvFaces.IsBound(aF)) { |
2939 | if (aLFInv.IsEmpty()) { |
2940 | theArtInvFaces.UnBind(aF); |
2941 | } |
2942 | else { |
2943 | aReallyInvFaces.Add(aF, aLFInv); |
2944 | } |
2945 | continue; |
2946 | } |
2947 | // |
2948 | if (aLFInv.IsEmpty()) { |
2949 | continue; |
2950 | } |
2951 | // |
2952 | const TopTools_ListOfShape& aLFIm = theFImages.FindFromKey(aF); |
2953 | Standard_Boolean bInvalid = aLFIm.IsEmpty(); |
2954 | // |
2955 | if (!bInvalid) { |
2956 | // check two lists on common splits |
2957 | aItLF.Initialize(aLFInv); |
2958 | for (; aItLF.More(); aItLF.Next()) { |
2959 | const TopoDS_Shape& aFInv = aItLF.Value(); |
2960 | // |
2961 | TopTools_ListIteratorOfListOfShape aItLFIm(aLFIm); |
2962 | for (; aItLFIm.More(); aItLFIm.Next()) { |
2963 | const TopoDS_Shape& aFIm = aItLFIm.Value(); |
2964 | // |
2965 | if (aFInv.IsSame(aFIm)) { |
2966 | break; |
2967 | } |
2968 | } |
2969 | // |
2970 | if (aItLFIm.More()) { |
2971 | break; |
2972 | } |
2973 | } |
2974 | // |
2975 | bInvalid = aItLF.More(); |
2976 | } |
2977 | // |
2978 | if (!bInvalid) { |
2979 | // check for free edges |
2980 | for (Standard_Integer j = 0; !bInvalid && j < 2; ++j) { |
2981 | const TopTools_ListOfShape& aLI = !j ? aLFIm : aLFInv; |
2982 | aItLF.Initialize(aLI); |
2983 | for (; aItLF.More(); aItLF.Next()) { |
2984 | const TopoDS_Shape& aFIm = aItLF.Value(); |
2985 | // |
2986 | TopExp_Explorer aExp(aFIm, TopAbs_EDGE); |
2987 | for (; aExp.More(); aExp.Next()) { |
2988 | const TopoDS_Shape& aE = aExp.Current(); |
2989 | if (theDMFE.Contains(aE)) { |
2990 | const TopTools_ListOfShape& aLEF = theDMFE.FindFromKey(aE); |
2991 | if (aLEF.Extent() == 1) { |
2992 | break; |
2993 | } |
2994 | } |
2995 | } |
2996 | // |
2997 | if (aExp.More()) { |
2998 | break; |
2999 | } |
3000 | } |
3001 | bInvalid = aItLF.More(); |
3002 | } |
3003 | } |
3004 | // |
3005 | if (bInvalid) { |
3006 | aReallyInvFaces.Add(aF, aLFInv); |
3007 | } |
3008 | } |
3009 | // |
3010 | theInvFaces = aReallyInvFaces; |
3011 | } |
3012 | |
3013 | //======================================================================= |
3014 | //function : FilterInvalidEdges |
3015 | //purpose : Filtering the invalid edges according to currently invalid faces |
3016 | //======================================================================= |
3017 | void FilterInvalidEdges(const TopTools_IndexedDataMapOfShapeListOfShape& theInvFaces, |
3018 | const TopTools_DataMapOfShapeShape& theArtInvFaces, |
3019 | const TopTools_DataMapOfShapeListOfShape& theDMFLIE, |
3020 | const TopTools_IndexedMapOfShape& theMERemoved, |
3021 | TopTools_IndexedMapOfShape& theInvEdges) |
3022 | { |
3023 | TopoDS_Compound aCEInv; |
3024 | TopTools_IndexedMapOfShape aMEInv; |
3025 | BRep_Builder aBB; |
3026 | aBB.MakeCompound(aCEInv); |
3027 | TopTools_ListIteratorOfListOfShape aItLF; |
3028 | // |
3029 | Standard_Integer i, aNb = theInvFaces.Extent(); |
3030 | for (i = 1; i <= aNb; ++i) { |
3031 | const TopTools_ListOfShape& aLFInv = theInvFaces(i); |
3032 | aItLF.Initialize(aLFInv); |
3033 | for (; aItLF.More(); aItLF.Next()) { |
3034 | const TopoDS_Shape& aFIm = aItLF.Value(); |
3035 | TopExp::MapShapes(aFIm, TopAbs_EDGE, aMEInv); |
3036 | // |
3037 | TopExp_Explorer aExpE(aFIm, TopAbs_EDGE); |
3038 | for (; aExpE.More(); aExpE.Next()) { |
3039 | const TopoDS_Shape& aE = aExpE.Current(); |
3040 | if (theInvEdges.Contains(aE)) { |
3041 | aBB.Add(aCEInv, aE); |
3042 | } |
3043 | } |
3044 | } |
3045 | } |
3046 | // |
3047 | // remove edges which have been marked for removal |
3048 | TopTools_IndexedMapOfShape aMEInvToAvoid; |
3049 | TopTools_ListOfShape aLCBE; |
3050 | BOPTools_AlgoTools::MakeConnexityBlocks(aCEInv, TopAbs_VERTEX, TopAbs_EDGE, aLCBE); |
3051 | // |
3052 | TopTools_ListIteratorOfListOfShape aItLCBE(aLCBE); |
3053 | for (; aItLCBE.More(); aItLCBE.Next()) { |
3054 | const TopoDS_Shape& aCBE = aItLCBE.Value(); |
3055 | TopExp_Explorer aExpCB(aCBE, TopAbs_EDGE); |
3056 | for (; aExpCB.More(); aExpCB.Next()) { |
3057 | const TopoDS_Shape& aE = aExpCB.Current(); |
3058 | if (!theMERemoved.Contains(aE)) { |
3059 | break; |
3060 | } |
3061 | } |
3062 | // |
3063 | if (!aExpCB.More()) { |
3064 | TopExp::MapShapes(aCBE, TopAbs_EDGE, aMEInvToAvoid); |
3065 | } |
3066 | } |
3067 | // |
3068 | TopTools_IndexedMapOfShape aReallyInvEdges; |
3069 | // |
3070 | aNb = theInvFaces.Extent(); |
3071 | for (i = 1; i <= aNb; ++i) { |
3072 | const TopoDS_Shape& aF = theInvFaces.FindKey(i); |
3073 | if (theArtInvFaces.IsBound(aF)) { |
3074 | const TopTools_ListOfShape& aLEInv = theDMFLIE.Find(aF); |
3075 | aItLF.Initialize(aLEInv); |
3076 | for (; aItLF.More(); aItLF.Next()) { |
3077 | const TopoDS_Shape& aE = aItLF.Value(); |
3078 | if (aMEInv.Contains(aE) && !aMEInvToAvoid.Contains(aE)) { |
3079 | aReallyInvEdges.Add(aE); |
3080 | } |
3081 | } |
3082 | } |
3083 | else { |
3084 | const TopTools_ListOfShape& aLFInv = theInvFaces(i); |
3085 | aItLF.Initialize(aLFInv); |
3086 | for (; aItLF.More(); aItLF.Next()) { |
3087 | const TopoDS_Shape& aFIm = aItLF.Value(); |
3088 | TopExp_Explorer aExpE(aFIm, TopAbs_EDGE); |
3089 | for (; aExpE.More(); aExpE.Next()) { |
3090 | const TopoDS_Shape& aE = aExpE.Current(); |
3091 | if (theInvEdges.Contains(aE) && !aMEInvToAvoid.Contains(aE)) { |
3092 | aReallyInvEdges.Add(aE); |
3093 | } |
3094 | } |
3095 | } |
3096 | } |
3097 | } |
3098 | // |
3099 | theInvEdges = aReallyInvEdges; |
3100 | } |
3101 | |
3102 | //======================================================================= |
3103 | //function : FindFacesToRebuild |
3104 | //purpose : Looking for the faces that have to be rebuilt: |
3105 | // 1. Faces close to invalidity |
3106 | // 2. Faces containing some invalid parts |
3107 | //======================================================================= |
3108 | void FindFacesToRebuild(const TopTools_IndexedDataMapOfShapeListOfShape& theLFImages, |
3109 | const TopTools_IndexedMapOfShape& theInvEdges, |
3110 | const TopTools_IndexedDataMapOfShapeListOfShape& theInvFaces, |
3111 | const TopTools_DataMapOfShapeListOfShape& theSSInterfs, |
3112 | TopTools_IndexedDataMapOfShapeListOfShape& theFToRebuild, |
3113 | TopTools_MapOfShape& theFSelfRebAvoid) |
3114 | { |
3115 | Standard_Integer i, aNb = theLFImages.Extent(); |
3116 | if (!aNb) { |
3117 | return; |
3118 | } |
3119 | // |
3120 | Standard_Boolean bRebuild; |
3121 | TopTools_ListIteratorOfListOfShape aItLF; |
3122 | TopTools_ListOfShape aLEValid; |
3123 | TopTools_MapOfShape aMFence, aMEReb, aMFReb; |
3124 | TopExp_Explorer aExp; |
3125 | // |
3126 | TopTools_DataMapOfShapeListOfShape aDMFLV; |
3127 | // get edges from invalid faces |
3128 | aNb = theInvFaces.Extent(); |
3129 | for (i = 1; i <= aNb; i++) { |
3130 | const TopoDS_Shape& aF = theInvFaces.FindKey(i); |
3131 | aMFence.Clear(); |
3132 | TopTools_ListOfShape aLVAvoid; |
3133 | const TopTools_ListOfShape& aLFIm = theInvFaces(i); |
3134 | aItLF.Initialize(aLFIm); |
3135 | for (; aItLF.More(); aItLF.Next()) { |
3136 | const TopoDS_Shape& aFIm = aItLF.Value(); |
3137 | aExp.Init(aFIm, TopAbs_EDGE); |
3138 | for (; aExp.More(); aExp.Next()) { |
3139 | const TopoDS_Shape& aE = aExp.Current(); |
3140 | aMEReb.Add(aE); |
3141 | if (theInvEdges.Contains(aE)) { |
3142 | TopExp_Explorer aExpV(aE, TopAbs_VERTEX); |
3143 | for (; aExpV.More(); aExpV.Next()) { |
3144 | const TopoDS_Shape& aV = aExpV.Current(); |
3145 | if (aMFence.Add(aV)) { |
3146 | aLVAvoid.Append(aV); |
3147 | aMEReb.Add(aV); |
3148 | } |
3149 | } |
3150 | } |
3151 | } |
3152 | } |
3153 | // |
3154 | if (aLVAvoid.Extent()) { |
3155 | aDMFLV.Bind(aF, aLVAvoid); |
3156 | } |
3157 | // |
3158 | const TopTools_ListOfShape* pLF = theSSInterfs.Seek(aF); |
3159 | if (pLF) { |
3160 | TopTools_ListIteratorOfListOfShape aItLFE(*pLF); |
3161 | for (; aItLFE.More(); aItLFE.Next()) { |
3162 | const TopoDS_Shape& aFE = aItLFE.Value(); |
3163 | aMFReb.Add(aFE); |
3164 | } |
3165 | } |
3166 | } |
3167 | // |
3168 | // get face to rebuild |
3169 | aNb = theLFImages.Extent(); |
3170 | for (i = 1; i <= aNb; i++) { |
3171 | const TopoDS_Shape& aF = theLFImages.FindKey(i); |
3172 | const TopTools_ListOfShape& aLFIm = theLFImages(i); |
3173 | TopTools_MapOfShape aMVAvoid; |
3174 | if (aDMFLV.IsBound(aF)) { |
3175 | const TopTools_ListOfShape& aLVAvoid = aDMFLV.Find(aF); |
3176 | TopTools_ListIteratorOfListOfShape aItLV(aLVAvoid); |
3177 | for (; aItLV.More(); aItLV.Next()) { |
3178 | const TopoDS_Shape& aV = aItLV.Value(); |
3179 | aMVAvoid.Add(aV); |
3180 | } |
3181 | } |
3182 | // |
3183 | bRebuild = aMFReb.Contains(aF); |
3184 | aLEValid.Clear(); |
3185 | aMFence.Clear(); |
3186 | // |
3187 | aItLF.Initialize(aLFIm); |
3188 | for (; aItLF.More(); aItLF.Next()) { |
3189 | const TopoDS_Shape& aFIm = aItLF.Value(); |
3190 | aExp.Init(aFIm, TopAbs_EDGE); |
3191 | for (; aExp.More(); aExp.Next()) { |
3192 | const TopoDS_Edge& anEIm = TopoDS::Edge(aExp.Current()); |
3193 | if (!theInvEdges.Contains(anEIm)) { |
3194 | if (aMFence.Add(anEIm)) { |
3195 | aLEValid.Append(anEIm); |
3196 | } |
3197 | } |
3198 | // |
3199 | if (!bRebuild) { |
3200 | bRebuild = aMEReb.Contains(anEIm); |
3201 | } |
3202 | // |
3203 | if (!bRebuild) { |
3204 | // check vertices |
3205 | TopExp_Explorer aExpV(anEIm, TopAbs_VERTEX); |
3206 | for (; aExpV.More() && !bRebuild; aExpV.Next()) { |
3207 | const TopoDS_Shape& aV = aExpV.Current(); |
3208 | if (!aMVAvoid.Contains(aV)) { |
3209 | bRebuild = aMEReb.Contains(aV); |
3210 | } |
3211 | } |
3212 | } |
3213 | } |
3214 | } |
3215 | // |
3216 | if (!bRebuild) { |
3217 | bRebuild = aLFIm.Extent() && theInvFaces.Contains(aF); |
3218 | if (bRebuild) { |
3219 | theFSelfRebAvoid.Add(aF); |
3220 | } |
3221 | } |
3222 | // |
3223 | if (bRebuild) { |
3224 | theFToRebuild.Add(aF, aLEValid); |
3225 | } |
3226 | } |
3227 | } |
3228 | |
3229 | //======================================================================= |
3230 | //function : RebuildFaces |
3231 | //purpose : Rebuilding of the faces |
3232 | //======================================================================= |
3233 | void RebuildFaces(const TopTools_IndexedDataMapOfShapeListOfShape& theFToRebuild, |
3234 | const TopTools_MapOfShape& theFSelfRebAvoid, |
3235 | const TopoDS_Shape& theSolids, |
3236 | const TopTools_DataMapOfShapeListOfShape& theSSInterfs, |
3237 | TopTools_IndexedDataMapOfShapeListOfShape& theFImages, |
3238 | TopTools_DataMapOfShapeListOfShape& theEdgesOrigins, |
3239 | TopTools_DataMapOfShapeShape& theFacesOrigins, |
3240 | TopTools_DataMapOfShapeListOfShape& theOEImages, |
3241 | TopTools_DataMapOfShapeListOfShape& theOEOrigins, |
3242 | TopTools_MapOfShape& theLastInvEdges, |
3243 | TopTools_IndexedMapOfShape& theEdgesToAvoid, |
3244 | TopTools_IndexedMapOfShape& theInvEdges, |
3245 | TopTools_IndexedMapOfShape& theValidEdges, |
3246 | const TopTools_MapOfShape& theInvertedEdges, |
3247 | TopTools_DataMapOfShapeInteger& theAlreadyInvFaces, |
3248 | TopTools_IndexedDataMapOfShapeListOfShape& theInvFaces, |
3249 | const TopTools_DataMapOfShapeShape& theArtInvFaces, |
3250 | TopTools_MapOfShape& theVertsToAvoid, |
3251 | TopTools_DataMapOfShapeShape& theETrimEInf, |
3252 | Handle(BRepAlgo_AsDes)& theAsDes) |
3253 | { |
3254 | TopTools_MapOfShape aModifiedEdges; |
3255 | // |
3256 | // 1. Intersect faces |
3257 | IntersectFaces(theFToRebuild, theFSelfRebAvoid, theSolids, theSSInterfs, theFImages, theEdgesOrigins, theOEImages, |
3258 | theOEOrigins, theInvEdges, theValidEdges, theInvertedEdges, theEdgesToAvoid, |
3259 | theInvFaces, theArtInvFaces, theVertsToAvoid, theETrimEInf, aModifiedEdges, theAsDes); |
3260 | // |
3261 | // 2. Repeat steps to build the correct faces |
3262 | BuildSplitsOfInvFaces(theFToRebuild, aModifiedEdges, theFImages, theEdgesOrigins, |
3263 | theFacesOrigins, theOEImages, theOEOrigins, theLastInvEdges, |
3264 | theEdgesToAvoid, theVertsToAvoid, theAlreadyInvFaces, theValidEdges, |
3265 | theETrimEInf, theAsDes); |
3266 | } |
3267 | |
3268 | //======================================================================= |
3269 | //function : IntersectFaces |
3270 | //purpose : Intersection of the faces that should be rebuild |
3271 | // to resolve all invalidities |
3272 | //======================================================================= |
3273 | void IntersectFaces(const TopTools_IndexedDataMapOfShapeListOfShape& theFToRebuild, |
3274 | const TopTools_MapOfShape& theFSelfRebAvoid, |
3275 | const TopoDS_Shape& theSolids, |
3276 | const TopTools_DataMapOfShapeListOfShape& theSSInterfs, |
3277 | TopTools_IndexedDataMapOfShapeListOfShape& theFImages, |
3278 | TopTools_DataMapOfShapeListOfShape& theEdgesOrigins, |
3279 | TopTools_DataMapOfShapeListOfShape& theOEImages, |
3280 | TopTools_DataMapOfShapeListOfShape& theOEOrigins, |
3281 | TopTools_IndexedMapOfShape& theInvEdges, |
3282 | TopTools_IndexedMapOfShape& theValidEdges, |
3283 | const TopTools_MapOfShape& theInvertedEdges, |
3284 | TopTools_IndexedMapOfShape& theEdgesToAvoid, |
3285 | TopTools_IndexedDataMapOfShapeListOfShape& theInvFaces, |
3286 | const TopTools_DataMapOfShapeShape& theArtInvFaces, |
3287 | TopTools_MapOfShape& theVertsToAvoid, |
3288 | TopTools_DataMapOfShapeShape& theETrimEInf, |
3289 | TopTools_MapOfShape& theModifiedEdges, |
3290 | Handle(BRepAlgo_AsDes)& theAsDes) |
3291 | { |
3292 | Standard_Integer aNbFR = theFToRebuild.Extent(); |
3293 | if (!aNbFR) { |
3294 | return; |
3295 | } |
3296 | // |
3297 | Standard_Integer i, j, k, aNbInv; |
3298 | TopTools_ListIteratorOfListOfShape aItLF, aItLE; |
ecf4f17c |
3299 | // |
3300 | // get vertices from invalid edges |
3301 | TopTools_MapOfShape aMVInv, aMVInvAll; |
3302 | aNbInv = theInvEdges.Extent(); |
3303 | for (i = 1; i <= aNbInv; ++i) { |
3304 | const TopoDS_Shape& aEInv = theInvEdges(i); |
3305 | Standard_Boolean bValid = theValidEdges.Contains(aEInv); |
45d0af05 |
3306 | for (TopExp_Explorer aExp (aEInv, TopAbs_VERTEX); aExp.More(); aExp.Next()) { |
ecf4f17c |
3307 | const TopoDS_Shape& aV = aExp.Current(); |
3308 | aMVInvAll.Add(aV); |
3309 | if (!bValid) { |
3310 | aMVInv.Add(aV); |
3311 | } |
3312 | } |
3313 | } |
3314 | // |
3315 | Standard_Boolean bLookVertToAvoid = (aMVInv.Extent() > 0); |
3316 | // |
3317 | TopTools_DataMapOfShapeListOfShape aDMSF, aMDone, aMEInfETrim, aDMVEFull; |
3318 | TopTools_IndexedDataMapOfShapeListOfShape aFLE, aDMEFInv; |
3319 | // |
3320 | // Add all faces to rebuild to outgoing map <aFLE>, |
3321 | // plus link edges and vertices to the faces to |
3322 | // define intersection faces |
3323 | PrepareFacesForIntersection(theFToRebuild, theFImages, theInvFaces, theArtInvFaces, |
3324 | bLookVertToAvoid, aFLE, aMDone, aDMSF, aMEInfETrim, |
3325 | aDMVEFull, theETrimEInf, aDMEFInv); |
3326 | |
3327 | // Find vertices to avoid while trimming the edges. |
3328 | // These vertices are taken from the invalid edges common between |
3329 | // splits of different invalid, but not artificially, faces. |
3330 | // Additional condition for these vertices is that all |
3331 | // edges adjacent to this vertex must be either invalid |
3332 | // or contained in invalid faces |
3333 | TopTools_MapOfShape aMVRInv = theVertsToAvoid; |
3334 | FindVerticesToAvoid(aDMEFInv, theInvEdges, theValidEdges, aDMVEFull, aMVRInv); |
3335 | // |
3336 | // The faces should be intersected selectively - |
3337 | // intersect only faces neighboring to the same invalid face |
3338 | // and connected to its invalid edges; |
3339 | // when dealing with artificially invalid faces for intersection to be |
3340 | // complete we need to use not only invalid edges, but also the |
3341 | // edges connected to invalid ones |
b443d536 |
3342 | |
3343 | // find blocks of artificially invalid faces |
3344 | TopTools_DataMapOfShapeShape aDMFImF; |
3345 | TopoDS_Compound aCFArt; |
3346 | BRep_Builder().MakeCompound(aCFArt); |
ecf4f17c |
3347 | TopTools_DataMapIteratorOfDataMapOfShapeShape aItM(theArtInvFaces); |
3348 | for (; aItM.More(); aItM.Next()) { |
3349 | const TopoDS_Shape& aF = aItM.Key(); |
3350 | const TopTools_ListOfShape& aLFInv = theInvFaces.FindFromKey(aF); |
3351 | aItLF.Initialize(aLFInv); |
3352 | for (; aItLF.More(); aItLF.Next()) { |
b443d536 |
3353 | BRep_Builder().Add(aCFArt, aItLF.Value()); |
3354 | aDMFImF.Bind(aItLF.Value(), aF); |
ecf4f17c |
3355 | } |
3356 | } |
3357 | // |
b443d536 |
3358 | // make connexity blocks |
3359 | TopTools_ListOfShape aLCBArt; |
3360 | BOPTools_AlgoTools::MakeConnexityBlocks(aCFArt, TopAbs_VERTEX, TopAbs_FACE, aLCBArt); |
3361 | // |
3362 | // alone edges |
a8232603 |
3363 | TopTools_MapOfShape aMEAlone, aMEInvOnArt; |
b443d536 |
3364 | // |
3365 | TopTools_ListIteratorOfListOfShape aItLCBArt(aLCBArt); |
3366 | for (; aItLCBArt.More(); aItLCBArt.Next()) { |
3367 | const TopoDS_Shape& aCB = aItLCBArt.Value(); |
41aa3c3d |
3368 | // |
b443d536 |
3369 | // check if aCB contains splits of only one offset face |
3370 | TopTools_MapOfShape aMFArt; |
3371 | TopExp_Explorer aExpF(aCB, TopAbs_FACE); |
3372 | for (; aExpF.More(); aExpF.Next()) { |
3373 | aMFArt.Add(aDMFImF.Find(aExpF.Current())); |
41aa3c3d |
3374 | } |
3375 | // |
b443d536 |
3376 | Standard_Boolean bAlone = (aMFArt.Extent() == 1); |
41aa3c3d |
3377 | // |
b443d536 |
3378 | // vertices on invalid edges |
3379 | TopTools_MapOfShape aMVEInv; |
3380 | TopTools_MapOfShape aMFence; |
3381 | // edges that should not be marked as alone - edges having same origins as invalid ones |
3382 | TopTools_MapOfShape aMEAvoid; |
3383 | // map to find alone edges by looking for free vertices |
3384 | TopTools_IndexedDataMapOfShapeListOfShape aDMVEVal; |
3385 | // |
3386 | TopExp_Explorer aExpE(aCB, TopAbs_EDGE); |
3387 | for (; aExpE.More(); aExpE.Next()) { |
3388 | const TopoDS_Shape& aE = aExpE.Current(); |
3389 | if (theInvEdges.Contains(aE)) { |
a8232603 |
3390 | aMEInvOnArt.Add(aE); |
b443d536 |
3391 | for (TopoDS_Iterator aItV(aE); aItV.More(); aItV.Next()) { |
3392 | aMVEInv.Add(aItV.Value()); |
3393 | } |
3394 | // |
3395 | if (bAlone) { |
3396 | const TopTools_ListOfShape *pLEOr = theOEOrigins.Seek(aE); |
3397 | if (pLEOr) { |
3398 | TopTools_ListIteratorOfListOfShape aItLEOr(*pLEOr); |
3399 | for (; aItLEOr.More(); aItLEOr.Next()) { |
3400 | TopTools_ListIteratorOfListOfShape aItLEIm(theOEImages.Find(aItLEOr.Value())); |
3401 | for (; aItLEIm.More(); aItLEIm.Next()) { |
3402 | aMEAvoid.Add(aItLEIm.Value()); |
3403 | } |
3404 | } |
3405 | } |
3406 | } |
3407 | continue; |
3408 | } |
3409 | // |
3410 | if (aMFence.Add(aE)) { |
3411 | TopExp::MapShapesAndAncestors(aE, TopAbs_VERTEX, TopAbs_EDGE, aDMVEVal); |
ecf4f17c |
3412 | } |
41aa3c3d |
3413 | } |
3414 | // |
b443d536 |
3415 | // find edges with free vertices |
3416 | Standard_Integer aNbV = aDMVEVal.Extent(); |
3417 | for (i = 1; i <= aNbV; ++i) { |
3418 | const TopoDS_Shape& aV = aDMVEVal.FindKey(i); |
3419 | if (!aMVEInv.Contains(aV)) { |
3420 | continue; |
3421 | } |
ecf4f17c |
3422 | // |
b443d536 |
3423 | const TopTools_ListOfShape& aLEV = aDMVEVal(i); |
3424 | if (aLEV.Extent() > 1) { |
3425 | continue; |
3426 | } |
3427 | // |
3428 | const TopoDS_Shape& aE = aLEV.First(); |
3429 | if (aMEAvoid.Contains(aE)) { |
3430 | continue; |
3431 | } |
3432 | // |
3433 | aMEAlone.Add(aE); |
3434 | // |
3435 | // if this alone edge adds nothing to the intersection list |
3436 | // it means that the origin of this edge has been split and we need to |
3437 | // add the neighboring images of the same origins |
3438 | if (aDMSF.Find(aE).Extent() > 1) { |
3439 | continue; |
3440 | } |
3441 | // |
3442 | // check also its vertices |
3443 | TopoDS_Iterator aItE(aE); |
3444 | for (; aItE.More(); aItE.Next()) { |
3445 | const TopoDS_Shape& aVE = aItE.Value(); |
3446 | if (aDMSF.Find(aVE).Extent() > 2) { |
3447 | break; |
3448 | } |
3449 | } |
3450 | // |
3451 | if (aItE.More()) { |
3452 | continue; |
3453 | } |
3454 | // |
3455 | // the edge is useless - look for other images |
3456 | const TopTools_ListOfShape *pLEOr = theOEOrigins.Seek(aE); |
3457 | if (!pLEOr) { |
3458 | continue; |
3459 | } |
3460 | // |
3461 | TopTools_ListIteratorOfListOfShape aItLEOr(*pLEOr); |
3462 | for (; aItLEOr.More(); aItLEOr.Next()) { |
3463 | const TopoDS_Shape& aEOr = aItLEOr.Value(); |
41aa3c3d |
3464 | // |
b443d536 |
3465 | const TopTools_ListOfShape& aLEIm = theOEImages.Find(aEOr); |
3466 | TopTools_ListIteratorOfListOfShape aItLEIm(aLEIm); |
3467 | for (; aItLEIm.More(); aItLEIm.Next()) { |
3468 | const TopoDS_Shape& aEIm = aItLEIm.Value(); |
3469 | // |
3470 | if (aMFence.Contains(aEIm)) { |
3471 | aMEAlone.Add(aEIm); |
3472 | } |
ecf4f17c |
3473 | } |
3474 | } |
41aa3c3d |
3475 | } |
3476 | } |
3477 | // |
3478 | // Get all invalidities from all faces to be used for avoiding |
3479 | // repeated usage of the common edges |
3480 | TopTools_MapOfShape aMAllInvs; |
3481 | aNbInv = theInvFaces.Extent(); |
3482 | for (k = 1; k <= aNbInv; ++k) { |
3483 | TopTools_ListIteratorOfListOfShape aIt(theInvFaces(k)); |
3484 | for (; aIt.More(); aIt.Next()) { |
3485 | TopExp_Explorer aExp(aIt.Value(), TopAbs_EDGE); |
3486 | for (; aExp.More(); aExp.Next()) { |
3487 | const TopoDS_Shape& aE = aExp.Current(); |
3488 | if (theInvEdges.Contains(aE) || aMEAlone.Contains(aE)) { |
3489 | aMAllInvs.Add(aE); |
3490 | TopoDS_Iterator aItV(aE); |
3491 | for (; aItV.More(); aItV.Next()) { |
3492 | aMAllInvs.Add(aItV.Value()); |
ecf4f17c |
3493 | } |
3494 | } |
3495 | } |
3496 | } |
3497 | } |
3498 | // |
3499 | // Bounding vertices of not trimmed edges |
3500 | TopTools_MapOfShape aMVBounds; |
41aa3c3d |
3501 | // |
3502 | TopTools_MapOfShape aMECheckExt; |
ecf4f17c |
3503 | // Save connections between not trimmed edge and its trimmed parts |
3504 | TopTools_DataMapOfShapeListOfShape aDMEETrim; |
3505 | // Splits of the new edges |
3506 | TopTools_DataMapOfShapeListOfShape aEImages; |
3507 | BRep_Builder aBB; |
3508 | // |
3509 | aNbInv = theInvFaces.Extent(); |
3510 | for (k = 1; k <= aNbInv; ++k) { |
3511 | const TopoDS_Shape& aFInv = theInvFaces.FindKey(k); |
3512 | Standard_Boolean bSelfRebAvoid = theFSelfRebAvoid.Contains(aFInv); |
3513 | const TopTools_ListOfShape& aLFInv = theInvFaces(k); |
3514 | // |
3515 | TopTools_ListOfShape aLCB; |
3516 | if (aLFInv.Extent() > 1) { |
3517 | // make compound of invalid faces |
3518 | TopoDS_Compound aCFInv; |
3519 | aBB.MakeCompound(aCFInv); |
3520 | // |
3521 | TopTools_ListIteratorOfListOfShape aIt(aLFInv); |
3522 | for (; aIt.More(); aIt.Next()) { |
3523 | const TopoDS_Shape& aFIm = aIt.Value(); |
3524 | aBB.Add(aCFInv, aFIm); |
3525 | } |
3526 | // |
3527 | // make connexity blocks |
3528 | BOPTools_AlgoTools::MakeConnexityBlocks(aCFInv, TopAbs_EDGE, TopAbs_FACE, aLCB); |
3529 | } |
3530 | else { |
3531 | aLCB = aLFInv; |
3532 | } |
3533 | // |
3534 | Standard_Boolean bArtificial = theArtInvFaces.IsBound(aFInv); |
3535 | TopTools_ListIteratorOfListOfShape aItLCB(aLCB); |
3536 | for (; aItLCB.More(); aItLCB.Next()) { |
3537 | const TopoDS_Shape& aCBInv = aItLCB.Value(); |
3538 | // |
3539 | TopTools_MapOfShape aMEFence; |
3540 | // |
3541 | TopoDS_Compound aCBE; |
3542 | aBB.MakeCompound(aCBE); |
3543 | // |
3544 | TopExp_Explorer aExp(aCBInv, TopAbs_EDGE); |
3545 | for (; aExp.More(); aExp.Next()) { |
3546 | const TopoDS_Shape& aE = aExp.Current(); |
3547 | if (theInvEdges.Contains(aE) || (bArtificial && aMEAlone.Contains(aE))) { |
3548 | if (aMEFence.Add(aE)) { |
3549 | aBB.Add(aCBE, aE); |
3550 | } |
3551 | } |
3552 | } |
3553 | // |
3554 | // make connexity blocks of edges |
3555 | TopTools_ListOfShape aLCBE; |
3556 | BOPTools_AlgoTools::MakeConnexityBlocks(aCBE, TopAbs_VERTEX, TopAbs_EDGE, aLCBE); |
3557 | // |
3558 | TopTools_ListIteratorOfListOfShape aItLCBE(aLCBE); |
3559 | for (; aItLCBE.More(); aItLCBE.Next()) { |
3560 | const TopoDS_Shape& aCBELoc = aItLCBE.Value(); |
3561 | // |
3562 | // map of edges and vertices of processing invalidity |
3563 | TopTools_IndexedMapOfShape aME; |
3564 | // map of vertices to trim the new edges |
3565 | TopTools_IndexedMapOfShape aMECV; |
3566 | TopExp::MapShapes(aCBELoc, TopAbs_EDGE, aME); |
3567 | aMECV = aME; |
3568 | TopExp::MapShapes(aCBELoc, TopAbs_VERTEX, aME); |
3569 | // |
3570 | // Using the map <aME> find chain of faces to be intersected; |
3571 | // |
3572 | // faces for intersection |
3573 | TopTools_IndexedMapOfShape aMFInt; |
3574 | // additional faces for intersection |
3575 | TopTools_IndexedMapOfShape aMFIntExt; |
3576 | // splits of faces for intersection |
3577 | TopTools_ListOfShape aLFInt; |
3578 | // faces to avoid intersection |
3579 | TopTools_IndexedMapOfShape aMFAvoid; |
3580 | // |
3581 | FindFacesForIntersection(aFInv, aME, theFImages, aDMSF, aMVInvAll, |
3582 | theArtInvFaces, bArtificial, theSSInterfs, aMFAvoid, aMFInt, aMFIntExt, aLFInt); |
3583 | if (aMFInt.Extent() < 3) { |
3584 | // nothing to intersect |
3585 | continue; |
3586 | } |
3587 | // |
3588 | // intersect the faces, but do not intersect the invalid ones |
3589 | // among each other (except for the artificially invalid faces) |
3590 | TopTools_IndexedMapOfShape aMEToInt; |
3591 | Standard_Integer aNb = aMFInt.Extent(); |
3592 | for (i = 1; i <= aNb; ++i) { |
3593 | const TopoDS_Face& aFi = TopoDS::Face(aMFInt(i)); |
3594 | if (bSelfRebAvoid && aFi.IsSame(aFInv)) { |
3595 | continue; |
3596 | } |
3597 | // |
3598 | const TopTools_ListOfShape& aLFImi = theFImages.FindFromKey(aFi); |
3599 | // |
3600 | TopTools_ListOfShape& aLFEi = aFLE.ChangeFromKey(aFi); |
3601 | // |
3602 | TopTools_ListOfShape& aLFDone = aMDone.ChangeFind(aFi); |
3603 | // |
3604 | for (j = i + 1; j <= aNb; ++j) { |
3605 | const TopoDS_Face& aFj = TopoDS::Face(aMFInt(j)); |
3606 | if (bSelfRebAvoid && aFj.IsSame(aFInv)) { |
3607 | continue; |
3608 | } |
3609 | // |
3610 | const TopTools_ListOfShape& aLFImj = theFImages.FindFromKey(aFj); |
3611 | // |
3612 | TopTools_ListOfShape& aLFEj = aFLE.ChangeFromKey(aFj); |
3613 | // |
3614 | // if there are some common edges between faces |
3615 | // we should use these edges and do not intersect again. |
3616 | TopTools_ListOfShape aLEC; |
3617 | FindCommonParts(aLFImi, aLFImj, aLEC); |
3618 | // |
3619 | if (aLEC.Extent()) { |
3620 | // no need to intersect if we have common edges between faces |
3621 | Standard_Boolean bForceUse = aMFIntExt.Contains(aFi) || aMFIntExt.Contains(aFj); |
3622 | ProcessCommonEdges(aLEC, theInvEdges, theValidEdges, aME, theETrimEInf, aMEInfETrim, |
41aa3c3d |
3623 | theOEOrigins, aMAllInvs, bForceUse, aMECV, aMECheckExt, aDMEETrim, aLFEi, aLFEj, aMEToInt); |
ecf4f17c |
3624 | continue; |
3625 | } |
3626 | // |
3627 | // check if both these faces are invalid and sharing edges |
3628 | if (theInvFaces.Contains(aFi) && theInvFaces.Contains(aFj) && |
3629 | !theArtInvFaces.IsBound(aFi) && !theArtInvFaces.IsBound(aFj)) { |
3630 | continue; |
3631 | } |
3632 | // |
3633 | // check if these two faces have already been treated |
3634 | aItLE.Initialize(aLFDone); |
3635 | for (; aItLE.More(); aItLE.Next()) { |
3636 | const TopoDS_Shape& aF = aItLE.Value(); |
3637 | if (aF.IsSame(aFj)) { |
3638 | break; |
3639 | } |
3640 | } |
3641 | // |
3642 | if (aItLE.More()) { |
3643 | // use intersection line obtained on the previous steps |
3644 | // plus, find new origins for these lines |
3645 | UpdateIntersectedFaces(aFInv, aFi, aFj, aLFInv, aLFImi, aLFImj, |
3646 | aLFEi, aLFEj, theEdgesOrigins, aMEToInt); |
3647 | continue; |
3648 | } |
3649 | // |
3650 | if (aMFAvoid.Contains(aFi) || aMFAvoid.Contains(aFj)) { |
3651 | continue; |
3652 | } |
3653 | // |
3654 | aLFDone.Append(aFj); |
3655 | aMDone.ChangeFind(aFj).Append(aFi); |
3656 | // |
3657 | IntersectFaces(aFInv, aFi, aFj, aLFInv, aLFImi, aLFImj, |
3658 | aLFEi, aLFEj, theEdgesOrigins, aMECV, aMEToInt); |
3659 | } |
3660 | } |
3661 | // |
3662 | // intersect and trim edges for this chain |
41aa3c3d |
3663 | IntersectAndTrimEdges(theFToRebuild, aMFInt, aMEToInt, aDMEETrim, aME, aMECV, |
3664 | aMVInv, aMVRInv, aMECheckExt, aMVBounds, aEImages); |
ecf4f17c |
3665 | } |
3666 | } |
3667 | } |
3668 | // |
3669 | // filter the obtained edges |
a8232603 |
3670 | UpdateValidEdges(theFImages, aFLE, aMVBounds, theSolids, theInvEdges, theInvertedEdges, aMEInvOnArt, |
41aa3c3d |
3671 | aMECheckExt, theEdgesToAvoid, theEdgesOrigins, theOEImages, theOEOrigins, |
ecf4f17c |
3672 | theVertsToAvoid, theETrimEInf, aEImages, aDMEETrim, theModifiedEdges, theAsDes); |
3673 | } |
3674 | |
3675 | //======================================================================= |
3676 | //function : PrepareFacesForIntersection |
3677 | //purpose : Preparation of the maps for analyzing intersections of the faces |
3678 | //======================================================================= |
3679 | void PrepareFacesForIntersection(const TopTools_IndexedDataMapOfShapeListOfShape& theFToRebuild, |
3680 | const TopTools_IndexedDataMapOfShapeListOfShape& theFImages, |
3681 | const TopTools_IndexedDataMapOfShapeListOfShape& theInvFaces, |
3682 | const TopTools_DataMapOfShapeShape& theArtInvFaces, |
3683 | const Standard_Boolean bLookVertToAvoid, |
3684 | TopTools_IndexedDataMapOfShapeListOfShape& theFLE, |
3685 | TopTools_DataMapOfShapeListOfShape& theMDone, |
3686 | TopTools_DataMapOfShapeListOfShape& theDMSF, |
3687 | TopTools_DataMapOfShapeListOfShape& theMEInfETrim, |
3688 | TopTools_DataMapOfShapeListOfShape& theDMVEFull, |
3689 | TopTools_DataMapOfShapeShape& theETrimEInf, |
3690 | TopTools_IndexedDataMapOfShapeListOfShape& theDMEFInv) |
3691 | { |
3692 | Standard_Integer i, aNb = theFToRebuild.Extent(); |
3693 | for (i = 1; i <= aNb; ++i) { |
3694 | const TopoDS_Shape& aF = theFToRebuild.FindKey(i); |
3695 | // |
3696 | TopTools_ListOfShape aLE; |
3697 | theFLE.Add(aF, aLE); |
3698 | theMDone.Bind(aF, aLE); |
3699 | // |
3700 | const TopTools_ListOfShape& aLFIm = theFImages.FindFromKey(aF); |
3701 | TopTools_ListIteratorOfListOfShape aItLF(aLFIm); |
3702 | for (; aItLF.More(); aItLF.Next()) { |
3703 | const TopoDS_Shape& aFIm = aItLF.Value(); |
3704 | TopExp_Explorer aExp(aFIm, TopAbs_EDGE); |
3705 | for (; aExp.More(); aExp.Next()) { |
3706 | const TopoDS_Shape& aE = aExp.Current(); |
3707 | // save connection to untrimmed face |
3708 | TopTools_ListOfShape *pLF = theDMSF.ChangeSeek(aE); |
3709 | if (!pLF) { |
3710 | pLF = theDMSF.Bound(aE, TopTools_ListOfShape()); |
3711 | } |
3712 | AppendToList(*pLF, aF); |
3713 | // |
3714 | // save connection to untrimmed edge |
3715 | const TopoDS_Shape& aEInf = theETrimEInf.Find(aE); |
3716 | TopTools_ListOfShape *pLETrim = theMEInfETrim.ChangeSeek(aEInf); |
3717 | if (!pLETrim) { |
3718 | pLETrim = theMEInfETrim.Bound(aEInf, TopTools_ListOfShape()); |
3719 | } |
3720 | AppendToList(*pLETrim, aE); |
3721 | // |
3722 | TopExp_Explorer aExpV(aE, TopAbs_VERTEX); |
3723 | for (; aExpV.More(); aExpV.Next()) { |
3724 | const TopoDS_Shape& aV = aExpV.Current(); |
3725 | // save connection to face |
3726 | TopTools_ListOfShape *pLFV = theDMSF.ChangeSeek(aV); |
3727 | if (!pLFV) { |
3728 | pLFV = theDMSF.Bound(aV, TopTools_ListOfShape()); |
3729 | } |
3730 | AppendToList(*pLFV, aF); |
3731 | // |
3732 | if (bLookVertToAvoid) { |
3733 | // save connection to edges |
3734 | TopTools_ListOfShape *pLEV = theDMVEFull.ChangeSeek(aV); |
3735 | if (!pLEV) { |
3736 | pLEV = theDMVEFull.Bound(aV, TopTools_ListOfShape()); |
3737 | } |
3738 | AppendToList(*pLEV, aE); |
3739 | } |
3740 | } |
3741 | } |
3742 | } |
3743 | // |
3744 | if (bLookVertToAvoid) { |
3745 | // get edges of invalid faces (from invalid splits only) |
3746 | const TopTools_ListOfShape *pLFInv = theInvFaces.Seek(aF); |
3747 | if (!pLFInv || theArtInvFaces.IsBound(aF)) { |
3748 | continue; |
3749 | } |
3750 | // |
3751 | aItLF.Initialize(*pLFInv); |
3752 | for (; aItLF.More(); aItLF.Next()) { |
3753 | const TopoDS_Shape& aFInv = aItLF.Value(); |
3754 | TopExp_Explorer aExp(aFInv, TopAbs_EDGE); |
3755 | for (; aExp.More(); aExp.Next()) { |
3756 | const TopoDS_Shape& aE = aExp.Current(); |
3757 | TopTools_ListOfShape *pLF = theDMEFInv.ChangeSeek(aE); |
3758 | if (!pLF) { |
3759 | pLF = &theDMEFInv(theDMEFInv.Add(aE, TopTools_ListOfShape())); |
3760 | } |
3761 | AppendToList(*pLF, aF); |
3762 | } |
3763 | } |
3764 | } |
3765 | } |
3766 | } |
3767 | |
3768 | //======================================================================= |
3769 | //function : FindVerticesToAvoid |
3770 | //purpose : Looking for the invalid vertices |
3771 | //======================================================================= |
3772 | void FindVerticesToAvoid(const TopTools_IndexedDataMapOfShapeListOfShape& theDMEFInv, |
3773 | const TopTools_IndexedMapOfShape& theInvEdges, |
3774 | const TopTools_IndexedMapOfShape& theValidEdges, |
3775 | TopTools_DataMapOfShapeListOfShape& theDMVEFull, |
3776 | TopTools_MapOfShape& theMVRInv) |
3777 | { |
3778 | TopTools_MapOfShape aMFence; |
3779 | Standard_Integer i, aNb = theDMEFInv.Extent(); |
3780 | for (i = 1; i <= aNb; ++i) { |
3781 | const TopTools_ListOfShape& aLFInv = theDMEFInv(i); |
3782 | if (aLFInv.Extent() == 1) { |
3783 | continue; |
3784 | } |
3785 | // |
3786 | const TopoDS_Shape& aE = theDMEFInv.FindKey(i); |
3787 | if (!theInvEdges.Contains(aE) || theValidEdges.Contains(aE)) { |
3788 | continue; |
3789 | } |
3790 | // |
3791 | TopExp_Explorer aExp(aE, TopAbs_VERTEX); |
3792 | for (; aExp.More(); aExp.Next()) { |
3793 | const TopoDS_Shape& aV = aExp.Current(); |
3794 | TopTools_ListOfShape *pLE = theDMVEFull.ChangeSeek(aV); |
3795 | if (!pLE) { |
3796 | theMVRInv.Add(aV); |
3797 | continue; |
3798 | } |
3799 | // |
3800 | TopTools_ListIteratorOfListOfShape aItLE(*pLE); |
3801 | for (; aItLE.More(); aItLE.Next()) { |
3802 | const TopoDS_Shape& aEV = aItLE.Value(); |
3803 | if (!theInvEdges.Contains(aEV) && !theDMEFInv.Contains(aEV)) { |
3804 | break; |
3805 | } |
3806 | } |
3807 | if (!aItLE.More()) { |
3808 | theMVRInv.Add(aV); |
3809 | } |
3810 | } |
3811 | } |
3812 | } |
3813 | |
3814 | //======================================================================= |
3815 | //function : FindFacesForIntersection |
3816 | //purpose : Looking for the faces around each invalidity for intersection |
3817 | //======================================================================= |
3818 | void FindFacesForIntersection(const TopoDS_Shape& theFInv, |
3819 | const TopTools_IndexedMapOfShape& theME, |
3820 | const TopTools_IndexedDataMapOfShapeListOfShape& theFImages, |
3821 | const TopTools_DataMapOfShapeListOfShape& theDMSF, |
3822 | const TopTools_MapOfShape& theMVInvAll, |
3823 | const TopTools_DataMapOfShapeShape& theArtInvFaces, |
3824 | const Standard_Boolean theArtCase, |
3825 | const TopTools_DataMapOfShapeListOfShape& theSSInterfs, |
3826 | TopTools_IndexedMapOfShape& theMFAvoid, |
3827 | TopTools_IndexedMapOfShape& theMFInt, |
3828 | TopTools_IndexedMapOfShape& theMFIntExt, |
3829 | TopTools_ListOfShape& theLFImInt) |
3830 | { |
3831 | Standard_Integer i, aNbE = theME.Extent(); |
3832 | // |
3833 | TopTools_IndexedMapOfShape aMShapes; |
3834 | // |
3835 | for (i = 1; i <= aNbE; ++i) { |
3836 | const TopoDS_Shape& aS = theME(i); |
3837 | if (!theDMSF.IsBound(aS)) { |
3838 | continue; |
3839 | } |
3840 | // |
3841 | // in artificial case we intersect the faces which are close to invalidity |
3842 | Standard_Boolean bAvoid = theArtCase ? |
3843 | ((aS.ShapeType() == TopAbs_VERTEX) && !theMVInvAll.Contains(aS)) : Standard_False; |
3844 | // |
3845 | const TopTools_ListOfShape& aLF = theDMSF.Find(aS); |
3846 | TopTools_ListIteratorOfListOfShape aItLF(aLF); |
3847 | for (; aItLF.More(); aItLF.Next()) { |
3848 | const TopoDS_Shape& aF = aItLF.Value(); |
3849 | if (theMFInt.Contains(aF)) { |
3850 | continue; |
3851 | } |
3852 | // |
3853 | if (bAvoid && theArtInvFaces.IsBound(aF)) { |
3854 | theMFAvoid.Add(aF); |
3855 | } |
3856 | // |
3857 | theMFInt.Add(aF); |
3858 | // |
3859 | Standard_Boolean bUse = !aF.IsSame(theFInv); |
3860 | // |
3861 | const TopTools_ListOfShape& aLFIm = theFImages.FindFromKey(aF); |
3862 | TopTools_ListIteratorOfListOfShape aItLFIm(aLFIm); |
3863 | for (; aItLFIm.More(); aItLFIm.Next()) { |
3864 | const TopoDS_Shape& aFIm = aItLFIm.Value(); |
3865 | theLFImInt.Append(aFIm); |
3866 | if (bUse) { |
3867 | TopExp::MapShapes(aFIm, TopAbs_EDGE, aMShapes); |
3868 | } |
3869 | } |
3870 | } |
3871 | } |
3872 | // |
3873 | if (theArtCase) { |
3874 | return; |
3875 | } |
3876 | // |
3877 | const TopTools_ListOfShape* pLFInv = theSSInterfs.Seek(theFInv); |
3878 | if (!pLFInv) { |
3879 | return; |
3880 | } |
3881 | // |
3882 | TopTools_MapOfShape aMF; |
3883 | TopTools_ListIteratorOfListOfShape aItLF(*pLFInv); |
3884 | for (; aItLF.More(); aItLF.Next()) { |
3885 | const TopoDS_Shape& aF = aItLF.Value(); |
3886 | aMF.Add(aF); |
3887 | } |
3888 | // |
3889 | // the faces should be unique in each place |
3890 | TopoDS_Compound aCF; |
3891 | BRep_Builder().MakeCompound(aCF); |
3892 | // |
3893 | TopTools_IndexedMapOfShape aMFToAdd; |
3894 | TopTools_DataMapOfShapeShape aDMFOr; |
3895 | // |
3896 | for (i = 1; i <= aNbE; ++i) { |
3897 | const TopoDS_Shape& aS = theME(i); |
3898 | const TopTools_ListOfShape* pLF = theSSInterfs.Seek(aS); |
3899 | if (!pLF) { |
3900 | continue; |
3901 | } |
3902 | // |
3903 | aItLF.Initialize(*pLF); |
3904 | for (; aItLF.More(); aItLF.Next()) { |
3905 | const TopoDS_Shape& aF = aItLF.Value(); |
3906 | if (theMFInt.Contains(aF) || aMFToAdd.Contains(aF) || !aMF.Contains(aF)) { |
3907 | continue; |
3908 | } |
3909 | // |
3910 | // check if the face has some connection to already added for intersection faces |
3911 | const TopTools_ListOfShape& aLFIm = theFImages.FindFromKey(aF); |
3912 | TopTools_ListIteratorOfListOfShape aItLFIm(aLFIm); |
3913 | for (; aItLFIm.More(); aItLFIm.Next()) { |
3914 | const TopoDS_Shape& aFIm = aItLFIm.Value(); |
3915 | TopExp_Explorer aExp(aFIm, TopAbs_EDGE); |
3916 | for (; aExp.More(); aExp.Next()) { |
3917 | if (aMShapes.Contains(aExp.Current())) { |
3918 | break; |
3919 | } |
3920 | } |
3921 | if (aExp.More()) { |
3922 | break; |
3923 | } |
3924 | } |
3925 | if (!aItLFIm.More()) { |
3926 | continue; |
3927 | } |
3928 | // |
3929 | aMFToAdd.Add(aF); |
3930 | aItLFIm.Initialize(aLFIm); |
3931 | for (; aItLFIm.More(); aItLFIm.Next()) { |
3932 | const TopoDS_Shape& aFIm = aItLFIm.Value(); |
3933 | aDMFOr.Bind(aFIm, aF); |
3934 | BRep_Builder().Add(aCF, aFIm); |
3935 | } |
3936 | } |
3937 | } |
3938 | // |
3939 | if (aMFToAdd.IsEmpty()) { |
3940 | return; |
3941 | } |
3942 | // |
3943 | TopTools_ListOfShape aLCB; |
3944 | BOPTools_AlgoTools::MakeConnexityBlocks(aCF, TopAbs_EDGE, TopAbs_FACE, aLCB); |
3945 | // |
3946 | if ((aLCB.Extent() == 1) && (aMFToAdd.Extent() > 1)) { |
3947 | return; |
3948 | } |
3949 | // |
3950 | TopTools_ListIteratorOfListOfShape aItLCB(aLCB); |
3951 | for (; aItLCB.More(); aItLCB.Next()) { |
3952 | const TopoDS_Shape& aCB = aItLCB.Value(); |
3953 | aMFToAdd.Clear(); |
3954 | TopExp_Explorer aExpF(aCB, TopAbs_FACE); |
3955 | for (; aExpF.More(); aExpF.Next()) { |
3956 | const TopoDS_Shape& aFIm = aExpF.Current(); |
3957 | aMFToAdd.Add(aDMFOr.Find(aFIm)); |
3958 | } |
3959 | // |
3960 | if (aMFToAdd.Extent() == 1) { |
3961 | const TopoDS_Shape& aF = aMFToAdd(1); |
3962 | // |
3963 | theMFInt.Add(aF); |
3964 | theMFIntExt.Add(aF); |
3965 | // |
3966 | const TopTools_ListOfShape& aLFIm = theFImages.FindFromKey(aF); |
3967 | TopTools_ListIteratorOfListOfShape aItLFIm(aLFIm); |
3968 | for (; aItLFIm.More(); aItLFIm.Next()) { |
3969 | const TopoDS_Shape& aFIm = aItLFIm.Value(); |
3970 | theLFImInt.Append(aFIm); |
3971 | } |
3972 | } |
3973 | } |
3974 | } |
3975 | |
3976 | //======================================================================= |
3977 | //function : ProcessCommonEdges |
3978 | //purpose : Analyzing the common edges between splits of offset faces |
3979 | //======================================================================= |
3980 | void ProcessCommonEdges(const TopTools_ListOfShape& theLEC, |
3981 | const TopTools_IndexedMapOfShape& theInvEdges, |
3982 | const TopTools_IndexedMapOfShape& theValidEdges, |
3983 | const TopTools_IndexedMapOfShape& theME, |
3984 | const TopTools_DataMapOfShapeShape& theETrimEInf, |
3985 | const TopTools_DataMapOfShapeListOfShape& theMEInfETrim, |
3986 | const TopTools_DataMapOfShapeListOfShape& theOEOrigins, |
41aa3c3d |
3987 | const TopTools_MapOfShape& theAllInvs, |
ecf4f17c |
3988 | const Standard_Boolean theForceUse, |
3989 | TopTools_IndexedMapOfShape& theMECV, |
41aa3c3d |
3990 | TopTools_MapOfShape& theMECheckExt, |
ecf4f17c |
3991 | TopTools_DataMapOfShapeListOfShape& theDMEETrim, |
3992 | TopTools_ListOfShape& theLFEi, |
3993 | TopTools_ListOfShape& theLFEj, |
3994 | TopTools_IndexedMapOfShape& theMEToInt) |
3995 | { |
3996 | TopTools_ListOfShape aLEC; |
3997 | // process common edges |
3998 | TopTools_ListIteratorOfListOfShape aItLE(theLEC); |
3999 | for (; aItLE.More(); aItLE.Next()) { |
4000 | const TopoDS_Shape& aEC = aItLE.Value(); |
4001 | // |
4002 | // check first if common edges are valid |
4003 | if (theInvEdges.Contains(aEC) && !theValidEdges.Contains(aEC)) { |
4004 | continue; |
4005 | } |
4006 | // |
4007 | // common edge should have connection to current invalidity |
4008 | if (theME.Contains(aEC)) { |
4009 | aLEC.Append(aEC); |
4010 | continue; |
4011 | } |
4012 | // |
4013 | TopoDS_Iterator aItV(aEC); |
4014 | for (; aItV.More(); aItV.Next()) { |
4015 | const TopoDS_Shape& aVE = aItV.Value(); |
4016 | if (theME.Contains(aVE)) { |
4017 | aLEC.Append(aEC); |
4018 | break; |
4019 | } |
4020 | } |
4021 | } |
4022 | // |
41aa3c3d |
4023 | Standard_Boolean bUseOnlyInf = aLEC.IsEmpty(); |
ecf4f17c |
4024 | if (bUseOnlyInf) { |
41aa3c3d |
4025 | if (theForceUse) { |
4026 | aLEC = theLEC; |
4027 | } |
4028 | else { |
4029 | aItLE.Initialize(theLEC); |
4030 | for (; aItLE.More(); aItLE.Next()) { |
4031 | const TopoDS_Shape& aEC = aItLE.Value(); |
b443d536 |
4032 | // check if all images of the origin of this edge |
4033 | // are not connected to any invalidity |
4034 | const TopoDS_Shape& aEInt = theETrimEInf.Find(aEC); |
4035 | const TopTools_ListOfShape& aLVE = theMEInfETrim.Find(aEInt); |
4036 | TopTools_ListIteratorOfListOfShape aItLVE(aLVE); |
4037 | for (; aItLVE.More(); aItLVE.Next()) { |
4038 | const TopoDS_Shape& aECx = aItLVE.Value(); |
4039 | if (theAllInvs.Contains(aECx) || theInvEdges.Contains(aECx)) { |
41aa3c3d |
4040 | return; |
4041 | } |
b443d536 |
4042 | // |
4043 | TopoDS_Iterator aItV(aECx); |
4044 | for (; aItV.More(); aItV.Next()) { |
4045 | if (theAllInvs.Contains(aItV.Value())) { |
4046 | return; |
4047 | } |
4048 | } |
41aa3c3d |
4049 | } |
41aa3c3d |
4050 | // use only one element |
4051 | if (aLEC.IsEmpty()) { |
4052 | aLEC.Append(aEC); |
4053 | } |
4054 | } |
4055 | } |
ecf4f17c |
4056 | } |
4057 | // |
4058 | aItLE.Initialize(aLEC); |
4059 | for (; aItLE.More(); aItLE.Next()) { |
4060 | const TopoDS_Shape& aEC = aItLE.Value(); |
4061 | // |
4062 | const TopoDS_Shape& aEInt = theETrimEInf.Find(aEC); |
4063 | if (!bUseOnlyInf) { |
4064 | // find the edges of the same original edge |
4065 | // and take their vertices as well |
4066 | const TopTools_ListOfShape& aLVE = theMEInfETrim.Find(aEInt); |
4067 | TopTools_ListIteratorOfListOfShape aItLVE(aLVE); |
4068 | for (; aItLVE.More(); aItLVE.Next()) { |
4069 | const TopoDS_Shape& aECx = aItLVE.Value(); |
4070 | // |
4071 | const TopTools_ListOfShape* pLEOr = theOEOrigins.Seek(aECx); |
4072 | if (!pLEOr || (pLEOr->Extent() == 1)) { |
4073 | TopExp::MapShapes(aECx, TopAbs_VERTEX, theMECV); |
4074 | } |
4075 | } |
4076 | // |
4077 | // bind unlimited edge to its trimmed part in face to update maps of |
4078 | // images and origins in the future |
4079 | TopTools_ListOfShape* pLTAdded = theDMEETrim.ChangeSeek(aEInt); |
4080 | if (!pLTAdded) { |
4081 | pLTAdded = theDMEETrim.Bound(aEInt, TopTools_ListOfShape()); |
4082 | } |
4083 | AppendToList(*pLTAdded, aEC); |
4084 | } |
41aa3c3d |
4085 | else if (!theForceUse) { |
4086 | theMECheckExt.Add(aEInt); |
4087 | } |
ecf4f17c |
4088 | // |
4089 | AppendToList(theLFEi, aEInt); |
4090 | AppendToList(theLFEj, aEInt); |
4091 | theMEToInt.Add(aEInt); |
4092 | } |
4093 | } |
4094 | |
4095 | //======================================================================= |
4096 | //function : UpdateIntersectedFaces |
4097 | //purpose : Updating the already interfered faces |
4098 | //======================================================================= |
4099 | void UpdateIntersectedFaces(const TopoDS_Shape& theFInv, |
4100 | const TopoDS_Shape& theFi, |
4101 | const TopoDS_Shape& theFj, |
4102 | const TopTools_ListOfShape& theLFInv, |
4103 | const TopTools_ListOfShape& theLFImi, |
4104 | const TopTools_ListOfShape& theLFImj, |
4105 | const TopTools_ListOfShape& theLFEi, |
4106 | const TopTools_ListOfShape& theLFEj, |
4107 | TopTools_DataMapOfShapeListOfShape& theEdgesOrigins, |
4108 | TopTools_IndexedMapOfShape& theMEToInt) |
4109 | { |
4110 | // Find common edges in these two lists |
4111 | TopTools_MapOfShape aMEi; |
4112 | TopTools_ListIteratorOfListOfShape aItLE(theLFEi); |
4113 | for (; aItLE.More(); aItLE.Next()) { |
4114 | const TopoDS_Shape& aE = aItLE.Value(); |
4115 | aMEi.Add(aE); |
4116 | } |
4117 | // |
4118 | // find origins |
4119 | TopTools_IndexedMapOfShape aMEToFindOrigins; |
4120 | TopTools_ListOfShape aLEToFindOrigins; |
4121 | if (!theFi.IsSame(theFInv)) { |
4122 | FindCommonParts(theLFImi, theLFInv, aLEToFindOrigins); |
4123 | } |
4124 | if (!theFj.IsSame(theFInv)) { |
4125 | FindCommonParts(theLFImj, theLFInv, aLEToFindOrigins); |
4126 | } |
4127 | // |
4128 | TopTools_ListOfShape aLEOrInit; |
4129 | aItLE.Initialize(aLEToFindOrigins); |
4130 | for (; aItLE.More(); aItLE.Next()) { |
4131 | const TopoDS_Shape& aEC = aItLE.Value(); |
4132 | aMEToFindOrigins.Add(aEC); |
4133 | } |
4134 | // |
4135 | FindOrigins(theLFImi, theLFImj, aMEToFindOrigins, theEdgesOrigins, aLEOrInit); |
4136 | // |
4137 | aItLE.Initialize(theLFEj); |
4138 | for (; aItLE.More(); aItLE.Next()) { |
4139 | const TopoDS_Shape& aE = aItLE.Value(); |
4140 | if (aMEi.Contains(aE)) { |
4141 | theMEToInt.Add(aE); |
4142 | if (aLEOrInit.Extent()) { |
4143 | if (theEdgesOrigins.IsBound(aE)) { |
4144 | TopTools_ListOfShape& aLEOr = theEdgesOrigins.ChangeFind(aE); |
4145 | TopTools_ListIteratorOfListOfShape aItLEOr(aLEOrInit); |
4146 | for (; aItLEOr.More(); aItLEOr.Next()) { |
4147 | const TopoDS_Shape& aEOr = aItLEOr.Value(); |
4148 | AppendToList(aLEOr, aEOr); |
4149 | } |
4150 | } |
4151 | else { |
4152 | theEdgesOrigins.Bind(aE, aLEOrInit); |
4153 | } |
4154 | } |
4155 | } |
4156 | } |
4157 | } |
4158 | |
4159 | //======================================================================= |
4160 | //function : IntersectFaces |
4161 | //purpose : Intersection of the pair of faces |
4162 | //======================================================================= |
4163 | void IntersectFaces(const TopoDS_Shape& theFInv, |
4164 | const TopoDS_Shape& theFi, |
4165 | const TopoDS_Shape& theFj, |
4166 | const TopTools_ListOfShape& theLFInv, |
4167 | const TopTools_ListOfShape& theLFImi, |
4168 | const TopTools_ListOfShape& theLFImj, |
4169 | TopTools_ListOfShape& theLFEi, |
4170 | TopTools_ListOfShape& theLFEj, |
4171 | TopTools_DataMapOfShapeListOfShape& theEdgesOrigins, |
4172 | TopTools_IndexedMapOfShape& theMECV, |
4173 | TopTools_IndexedMapOfShape& theMEToInt) |
4174 | { |
4175 | // intersect faces |
4176 | TopAbs_State aSide = TopAbs_OUT; |
4177 | TopTools_ListOfShape aLInt1, aLInt2; |
4178 | TopoDS_Edge aNullEdge; |
4179 | BRepOffset_Tool::Inter3D(TopoDS::Face(theFi), TopoDS::Face(theFj), aLInt1, aLInt2, aSide, aNullEdge); |
4180 | // |
4181 | if (aLInt1.IsEmpty()) { |
4182 | return; |
4183 | } |
4184 | // |
4185 | // find common vertices for trimming edges |
4186 | TopTools_ListOfShape aLCV; |
4187 | TopTools_ListIteratorOfListOfShape aItLE; |
4188 | FindCommonParts(theLFImi, theLFImj, aLCV, TopAbs_VERTEX); |
4189 | if (aLCV.Extent() > 1) { |
4190 | aItLE.Initialize(aLCV); |
4191 | for (; aItLE.More(); aItLE.Next()) { |
4192 | const TopoDS_Shape& aCV = aItLE.Value(); |
4193 | theMECV.Add(aCV); |
4194 | } |
4195 | } |
4196 | // |
4197 | // find origins |
4198 | TopTools_IndexedMapOfShape aMEToFindOrigins; |
4199 | TopTools_ListOfShape aLEToFindOrigins; |
4200 | if (!theFi.IsSame(theFInv)) { |
4201 | FindCommonParts(theLFImi, theLFInv, aLEToFindOrigins); |
4202 | } |
4203 | if (!theFj.IsSame(theFInv)) { |
4204 | FindCommonParts(theLFImj, theLFInv, aLEToFindOrigins); |
4205 | } |
4206 | TopTools_ListOfShape aLEOrInit; |
4207 | aItLE.Initialize(aLEToFindOrigins); |
4208 | for (; aItLE.More(); aItLE.Next()) { |
4209 | const TopoDS_Shape& aEC = aItLE.Value(); |
4210 | aMEToFindOrigins.Add(aEC); |
4211 | } |
4212 | // |
4213 | FindOrigins(theLFImi, theLFImj, aMEToFindOrigins, theEdgesOrigins, aLEOrInit); |
4214 | // |
4215 | aItLE.Initialize(aLInt1); |
4216 | for (; aItLE.More(); aItLE.Next()) { |
4217 | const TopoDS_Shape& aEInt = aItLE.Value(); |
4218 | theLFEi.Append(aEInt); |
4219 | theLFEj.Append(aEInt); |
4220 | // |
4221 | if (aLEOrInit.Extent()) { |
4222 | theEdgesOrigins.Bind(aEInt, aLEOrInit); |
4223 | } |
4224 | // |
4225 | theMEToInt.Add(aEInt); |
4226 | } |
4227 | } |
4228 | |
4229 | //======================================================================= |
4230 | //function : FindOrigins |
4231 | //purpose : Looking for the origin edges |
4232 | //======================================================================= |
4233 | void FindOrigins(const TopTools_ListOfShape& theLFIm1, |
4234 | const TopTools_ListOfShape& theLFIm2, |
4235 | const TopTools_IndexedMapOfShape& theME, |
4236 | const TopTools_DataMapOfShapeListOfShape& theOrigins, |
4237 | TopTools_ListOfShape& theLEOr) |
4238 | { |
4239 | Standard_Integer i; |
4240 | TopTools_MapOfShape aMFence; |
4241 | TopExp_Explorer aExp; |
4242 | TopTools_ListIteratorOfListOfShape aIt, aItLE; |
4243 | // |
4244 | for (i = 0; i < 2; ++i) { |
4245 | const TopTools_ListOfShape& aLF = !i ? theLFIm1 : theLFIm2; |
4246 | aIt.Initialize(aLF); |
4247 | for (; aIt.More(); aIt.Next()) { |
4248 | const TopoDS_Shape& aF = aIt.Value(); |
4249 | // |
4250 | aExp.Init(aF, TopAbs_EDGE); |
4251 | for (; aExp.More(); aExp.Next()) { |
4252 | const TopoDS_Shape& aE = aExp.Current(); |
4253 | // |
4254 | if (theME.Contains(aE) && theOrigins.IsBound(aE)) { |
4255 | const TopTools_ListOfShape& aLEOr = theOrigins.Find(aE); |
4256 | aItLE.Initialize(aLEOr); |
4257 | for (; aItLE.More(); aItLE.Next()) { |
4258 | const TopoDS_Shape& aEOr = aItLE.Value(); |
4259 | // |
4260 | if (aMFence.Add(aEOr) && (aEOr.ShapeType() == TopAbs_EDGE)) { |
4261 | theLEOr.Append(aEOr); |
4262 | } |
4263 | } // for (; aItLE.More(); aItLE.Next()) { |
4264 | } // if (theME.Contains(aE) && theOrigins.IsBound(aE)) { |
4265 | } // aExp.Init(aF, TopAbs_EDGE); |
4266 | } // for (; aIt.More(); aIt.Next()) { |
4267 | } // for (i = 0; i < 2; ++i) { |
4268 | } |
4269 | |
4270 | //======================================================================= |
4271 | //function : IntersectAndTrimEdges |
4272 | //purpose : Intersection of the new intersection edges among themselves |
4273 | //======================================================================= |
4274 | void IntersectAndTrimEdges(const TopTools_IndexedDataMapOfShapeListOfShape& theFToRebuild, |
4275 | const TopTools_IndexedMapOfShape& theMFInt, |
4276 | const TopTools_IndexedMapOfShape& theMEInt, |
4277 | const TopTools_DataMapOfShapeListOfShape& theDMEETrim, |
4278 | const TopTools_IndexedMapOfShape& theMSInv, |
4279 | const TopTools_IndexedMapOfShape& theMVE, |
4280 | const TopTools_MapOfShape& theVertsToAvoid, |
4281 | const TopTools_MapOfShape& theNewVertsToAvoid, |
41aa3c3d |
4282 | const TopTools_MapOfShape& theMECheckExt, |
ecf4f17c |
4283 | TopTools_MapOfShape& theMVBounds, |
4284 | TopTools_DataMapOfShapeListOfShape& theEImages) |
4285 | { |
4286 | Standard_Integer i, aNb = theMEInt.Extent(); |
4287 | if (!aNb) { |
4288 | return; |
4289 | } |
4290 | // |
4291 | BOPCol_ListOfShape aLArgs; |
4292 | TopTools_MapOfShape aMFence; |
4293 | TopTools_ListIteratorOfListOfShape aIt, aIt1; |
4294 | TopExp_Explorer aExp; |
4295 | // |
4296 | // get vertices from the splits of intersected faces. |
4297 | // vertices are taken from the edges close to invalidity |
4298 | // |
4299 | TopTools_IndexedDataMapOfShapeListOfShape aDMVE; |
4300 | aNb = theMFInt.Extent(); |
4301 | for (i = 1; i <= aNb; ++i) { |
4302 | const TopoDS_Shape& aF = theMFInt(i); |
4303 | const TopTools_ListOfShape& aLE = theFToRebuild.FindFromKey(aF); |
4304 | // |
4305 | aIt.Initialize(aLE); |
4306 | for (; aIt.More(); aIt.Next()) { |
4307 | const TopoDS_Shape& aE = aIt.Value(); |
4308 | TopExp::MapShapesAndAncestors(aE, TopAbs_VERTEX, TopAbs_EDGE, aDMVE); |
4309 | // |
4310 | aExp.Init(aE, TopAbs_VERTEX); |
4311 | for (; aExp.More(); aExp.Next()) { |
4312 | const TopoDS_Shape& aV1 = aExp.Current(); |
4313 | if (!theVertsToAvoid.Contains(aV1) && theMVE.Contains(aV1) && aMFence.Add(aV1)) { |
4314 | aLArgs.Append(aV1); |
4315 | } |
4316 | } |
4317 | } |
4318 | } |
4319 | // |
4320 | aNb = theMSInv.Extent(); |
4321 | for (i = 1; i <= aNb; ++i) { |
4322 | const TopoDS_Shape& aV = theMSInv(i); |
4323 | if (aV.ShapeType() != TopAbs_VERTEX) { |
4324 | continue; |
4325 | } |
4326 | // |
4327 | TopTools_ListOfShape *pLVE = aDMVE.ChangeSeek(aV); |
4328 | if (!pLVE) { |
4329 | continue; |
4330 | } |
4331 | // |
4332 | aIt.Initialize(*pLVE); |
4333 | for (; aIt.More(); aIt.Next()) { |
4334 | const TopoDS_Shape& aE = aIt.Value(); |
4335 | // |
4336 | aExp.Init(aE, TopAbs_VERTEX); |
4337 | for (; aExp.More(); aExp.Next()) { |
4338 | const TopoDS_Shape& aV1 = aExp.Current(); |
4339 | if (!theVertsToAvoid.Contains(aV1) && aMFence.Add(aV1)) { |
4340 | aLArgs.Append(aV1); |
4341 | } |
4342 | } |
4343 | } |
4344 | } |
4345 | // |
4346 | // bounding vertices of untrimmed edges |
4347 | TopTools_ListOfShape aLVBounds; |
4348 | // new intersection edges |
4349 | TopTools_ListOfShape aLENew; |
4350 | // get edges to intersect |
4351 | TopTools_ListOfShape aLEInt; |
41aa3c3d |
4352 | // Common intersection edges. Should be intersected separetely |
4353 | TopTools_ListOfShape aLCE; |
4354 | // |
ecf4f17c |
4355 | aNb = theMEInt.Extent(); |
4356 | for (i = 1; i <= aNb; ++i) { |
4357 | const TopoDS_Shape& aE = theMEInt(i); |
41aa3c3d |
4358 | if (theMECheckExt.Contains(aE)) { |
4359 | // avoid trimming of the intersection edges by additional common edges |
4360 | aLCE.Append(aE); |
ecf4f17c |
4361 | continue; |
4362 | } |
4363 | // |
4364 | if (!theDMEETrim.IsBound(aE)) { |
4365 | aLENew.Append(aE); |
4366 | } |
4367 | // |
4368 | aLEInt.Append(aE); |
4369 | aLArgs.Append(aE); |
4370 | // |
4371 | aExp.Init(aE, TopAbs_VERTEX); |
4372 | for (; aExp.More(); aExp.Next()) { |
4373 | const TopoDS_Shape& aV = aExp.Current(); |
4374 | aLVBounds.Append(aV); |
4375 | } |
4376 | } |
4377 | // |
4378 | // Intersect Edges |
4379 | BOPAlgo_Builder aGF; |
4380 | aGF.SetArguments(aLArgs); |
4381 | aGF.Perform(); |
4382 | if (aGF.ErrorStatus()) { |
4383 | return; |
4384 | } |
4385 | // |
4386 | // update vertices to avoid with SD vertices |
4387 | aIt.Initialize(aLVBounds); |
4388 | for (; aIt.More(); aIt.Next()) { |
4389 | const TopoDS_Shape& aV = aIt.Value(); |
4390 | const TopTools_ListOfShape& aLVIm = aGF.Modified(aV); |
4391 | if (aLVIm.IsEmpty()) { |
4392 | theMVBounds.Add(aV); |
4393 | } |
4394 | else { |
4395 | const TopoDS_Shape& aVIm = aLVIm.First(); |
4396 | theMVBounds.Add(aVIm); |
4397 | } |
4398 | } |
4399 | // |
4400 | // find invalid splits of edges |
4401 | TopTools_MapOfShape aMEInv; |
4402 | GetInvalidEdges(theNewVertsToAvoid, theMVBounds, aGF, aMEInv); |
4403 | // |
41aa3c3d |
4404 | BRep_Builder aBB; |
4405 | // get valid splits to intersect with the commons |
4406 | TopoDS_Compound aCEIm; |
4407 | aBB.MakeCompound(aCEIm); |
4408 | // |
ecf4f17c |
4409 | // remove the splits containing vertices from invalid edges |
4410 | aIt.Initialize(aLEInt); |
4411 | for (; aIt.More(); aIt.Next()) { |
4412 | const TopoDS_Shape& aE = aIt.Value(); |
4413 | // |
4414 | TopTools_ListOfShape aLEIm = aGF.Modified(aE); |
4415 | if (aLEIm.IsEmpty()) { |
4416 | continue; |
4417 | } |
4418 | // |
4419 | aIt1.Initialize(aLEIm); |
4420 | for (; aIt1.More(); ) { |
4421 | const TopoDS_Shape& aEIm = aIt1.Value(); |
4422 | // |
4423 | if (aMEInv.Contains(aEIm)) { |
4424 | aLEIm.Remove(aIt1); |
4425 | } |
4426 | else { |
41aa3c3d |
4427 | aBB.Add(aCEIm, aEIm); |
ecf4f17c |
4428 | aIt1.Next(); |
4429 | } |
4430 | } |
4431 | // |
4432 | if (aLEIm.Extent()) { |
41aa3c3d |
4433 | TopTools_ListOfShape* pLEIm = theEImages.ChangeSeek(aE); |
4434 | if (!pLEIm) { |
4435 | pLEIm = theEImages.Bound(aE, TopTools_ListOfShape()); |
ecf4f17c |
4436 | } |
41aa3c3d |
4437 | pLEIm->Append(aLEIm); |
4438 | } |
4439 | } |
4440 | // |
4441 | if (!aLCE.Extent()) { |
4442 | return; |
4443 | } |
4444 | // |
4445 | // trim common edges by other intersection edges |
4446 | BOPAlgo_Builder aGFCE; |
4447 | aGFCE.SetArguments(aLCE); |
4448 | aGFCE.AddArgument(aCEIm); |
4449 | aGFCE.Perform(); |
4450 | // |
4451 | if (aGFCE.ErrorStatus()) { |
4452 | return; |
4453 | } |
4454 | // |
4455 | const BOPDS_PDS& pDS = aGFCE.PDS(); |
4456 | TopTools_ListIteratorOfListOfShape aItLCE(aLCE); |
4457 | for (; aItLCE.More(); aItLCE.Next()) { |
4458 | const TopoDS_Shape& aE = aItLCE.Value(); |
4459 | TopTools_ListOfShape aLEIm = aGFCE.Modified(aE); |
4460 | if (aLEIm.IsEmpty()) { |
4461 | continue; |
4462 | } |
4463 | // |
4464 | // check if it's not coincide with some intersection edge |
4465 | BOPDS_ListIteratorOfListOfPaveBlock aItLPB(pDS->PaveBlocks(pDS->Index(aE))); |
4466 | for (; aItLPB.More(); aItLPB.Next()) { |
4467 | if (pDS->IsCommonBlock(aItLPB.Value())) { |
4468 | // find with what it is a common |
4469 | const BOPDS_ListOfPaveBlock& aLPBC = pDS->CommonBlock(aItLPB.Value())->PaveBlocks(); |
4470 | BOPDS_ListIteratorOfListOfPaveBlock aItLPBC(aLPBC); |
4471 | for (; aItLPBC.More(); aItLPBC.Next()) { |
4472 | const TopoDS_Shape& aEC = pDS->Shape(aItLPBC.Value()->OriginalEdge()); |
4473 | if (!theMECheckExt.Contains(aEC)) { |
4474 | break; |
4475 | } |
4476 | } |
4477 | if (aItLPBC.More()) { |
4478 | break; |
4479 | } |
ecf4f17c |
4480 | } |
4481 | } |
41aa3c3d |
4482 | if (aItLPB.More()) { |
4483 | // avoid creation of unnecessary splits from commons which |
4484 | // coincide with intersection edges |
4485 | continue; |
4486 | } |
4487 | // |
4488 | // save the images |
4489 | TopTools_ListOfShape* pLEIm = theEImages.ChangeSeek(aE); |
4490 | if (!pLEIm) { |
4491 | pLEIm = theEImages.Bound(aE, TopTools_ListOfShape()); |
4492 | } |
4493 | pLEIm->Append(aLEIm); |
4494 | // |
4495 | // save bounding vertices |
4496 | for (TopoDS_Iterator aItV(aE); aItV.More(); aItV.Next()) { |
4497 | const TopoDS_Shape& aV = aItV.Value(); |
4498 | const TopTools_ListOfShape& aLVIm = aGFCE.Modified(aV); |
4499 | theMVBounds.Add(aLVIm.IsEmpty() ? aV : aLVIm.First()); |
4500 | } |
ecf4f17c |
4501 | } |
4502 | } |
4503 | |
4504 | //======================================================================= |
4505 | //function : GetInvalidEdges |
4506 | //purpose : Looking for the invalid edges by intersecting with invalid vertices |
4507 | //======================================================================= |
4508 | void GetInvalidEdges(const TopTools_MapOfShape& theVertsToAvoid, |
4509 | const TopTools_MapOfShape& theMVBounds, |
4510 | BOPAlgo_Builder& theGF, |
4511 | TopTools_MapOfShape& theMEInv) |
4512 | { |
4513 | if (theVertsToAvoid.IsEmpty()) { |
4514 | return; |
4515 | } |
4516 | // |
4517 | TopTools_ListIteratorOfListOfShape aIt, aIt1; |
4518 | // get vertices created with intersection edges |
4519 | const TopoDS_Shape& aRes = theGF.Shape(); |
4520 | TopTools_IndexedDataMapOfShapeListOfShape aDMVE; |
4521 | TopExp::MapShapesAndAncestors(aRes, TopAbs_VERTEX, TopAbs_EDGE, aDMVE); |
4522 | // |
4523 | const BOPDS_PDS& pDS = theGF.PDS(); |
4524 | // |
4525 | // find invalid splits of edges |
4526 | // check if the vertex is invalid: |
4527 | // a. it may be the vertex SD with the vertices to avoid |
4528 | // b. or it may be the vertex which is created by the intersection |
4529 | // of only existing edges, i.e. no new intersection edges goes |
4530 | // through this vertex |
4531 | // |
4532 | TopTools_MapOfShape aMVInv; |
4533 | Standard_Integer i, aNb = aDMVE.Extent(); |
4534 | for (i = 1; i <= aNb; ++i) { |
4535 | const TopoDS_Vertex& aV = TopoDS::Vertex(aDMVE.FindKey(i)); |
4536 | if (theMVBounds.Contains(aV)) { |
4537 | continue; |
4538 | } |
4539 | // |
4540 | Standard_Integer nV = pDS->Index(aV); |
4541 | if ((nV >= 0) && !pDS->IsNewShape(nV)) { |
4542 | continue; |
4543 | } |
4544 | // |
4545 | TopTools_MapIteratorOfMapOfShape aItM(theVertsToAvoid); |
4546 | for (; aItM.More(); aItM.Next()) { |
4547 | const TopoDS_Vertex& aVInv = *(TopoDS_Vertex*)&aItM.Value(); |
4548 | Standard_Integer iFlag = BOPTools_AlgoTools::ComputeVV(aV, aVInv); |
4549 | if (!iFlag) { |
4550 | aMVInv.Add(aV); |
4551 | break; |
4552 | } |
4553 | } |
4554 | // |
4555 | if (aItM.More()) { |
4556 | const TopTools_ListOfShape& aLVE = aDMVE.FindFromKey(aV); |
4557 | aIt.Initialize(aLVE); |
4558 | for (; aIt.More(); aIt.Next()) { |
4559 | const TopoDS_Shape& aE = aIt.Value(); |
4560 | theMEInv.Add(aE); |
4561 | } |
4562 | } |
4563 | } |
4564 | } |
4565 | |
4566 | //======================================================================= |
4567 | //function : UpdateValidEdges |
4568 | //purpose : Making the new splits and updating the maps |
4569 | //======================================================================= |
41aa3c3d |
4570 | void UpdateValidEdges(const TopTools_IndexedDataMapOfShapeListOfShape& theFImages, |
ecf4f17c |
4571 | const TopTools_IndexedDataMapOfShapeListOfShape& theFLE, |
4572 | const TopTools_MapOfShape& theMVBounds, |
4573 | const TopoDS_Shape& theSolids, |
4574 | const TopTools_IndexedMapOfShape& theInvEdges, |
4575 | const TopTools_MapOfShape& theInvertedEdges, |
a8232603 |
4576 | const TopTools_MapOfShape& theMEInvOnArt, |
41aa3c3d |
4577 | TopTools_MapOfShape& theMECheckExt, |
ecf4f17c |
4578 | TopTools_IndexedMapOfShape& theEdgesToAvoid, |
4579 | TopTools_DataMapOfShapeListOfShape& theEdgesOrigins, |
4580 | TopTools_DataMapOfShapeListOfShape& theOEImages, |
4581 | TopTools_DataMapOfShapeListOfShape& theOEOrigins, |
4582 | TopTools_MapOfShape& theVertsToAvoid, |
4583 | TopTools_DataMapOfShapeShape& theETrimEInf, |
4584 | TopTools_DataMapOfShapeListOfShape& theEImages, |
4585 | TopTools_DataMapOfShapeListOfShape& theEETrim, |
4586 | TopTools_MapOfShape& theModifiedEdges, |
4587 | Handle(BRepAlgo_AsDes)& theAsDes) |
4588 | { |
4589 | // update images and origins of edges, plus update AsDes |
4590 | // |
4591 | // new edges |
4592 | TopTools_ListOfShape aLE; |
4593 | // back connection from edges to faces |
4594 | TopTools_DataMapOfShapeListOfShape aMELF; |
4595 | // |
b443d536 |
4596 | TopTools_MapOfShape aMETmp; |
ecf4f17c |
4597 | Standard_Integer i, aNb = theFLE.Extent(); |
4598 | for (i = 1; i <= aNb; ++i) { |
4599 | const TopoDS_Face& aF = TopoDS::Face(theFLE.FindKey(i)); |
4600 | // |
4601 | const TopTools_ListOfShape& aLEInt = theFLE(i); |
4602 | TopTools_ListIteratorOfListOfShape aItLE(aLEInt); |
4603 | for (; aItLE.More(); aItLE.Next()) { |
4604 | const TopoDS_Shape& aE = aItLE.Value(); |
b443d536 |
4605 | if ((theMECheckExt.Contains(aE) || aMETmp.Contains(aE)) && !theEImages.IsBound(aE)) { |
4606 | theMECheckExt.Remove(aE); |
4607 | aMETmp.Add(aE); |
4608 | continue; |
4609 | } |
ecf4f17c |
4610 | TopTools_ListOfShape* pLF = aMELF.ChangeSeek(aE); |
4611 | if (!pLF) { |
4612 | pLF = aMELF.Bound(aE, TopTools_ListOfShape()); |
4613 | aLE.Append(aE); |
4614 | } |
4615 | pLF->Append(aF); |
4616 | } |
4617 | } |
4618 | // |
4619 | if (aLE.IsEmpty()) { |
4620 | return; |
4621 | } |
4622 | // |
4623 | // bounding edges, that are going to be replaced |
4624 | TopTools_MapOfShape aMEB; |
4625 | // |
4626 | // new intersection edges |
4627 | TopTools_ListOfShape aLENew; |
4628 | TopTools_MapOfShape aMENew; |
4629 | // map of old vertices |
4630 | TopTools_MapOfShape aMVOld; |
4631 | // back connection to untrimmed edges |
4632 | TopTools_DataMapOfShapeListOfShape aDMEOr; |
4633 | // |
4634 | // trim the new intersection edges |
4635 | BOPCol_ListOfShape aLA; |
41aa3c3d |
4636 | TrimNewIntersectionEdges(aLE, theEETrim, theMVBounds, theMECheckExt, theEImages, |
4637 | aMEB, aMVOld, aLENew, aLA, aDMEOr, aMELF); |
ecf4f17c |
4638 | // |
4639 | if (aLA.IsEmpty()) { |
4640 | // update intersection edges |
4641 | UpdateNewIntersectionEdges(aLE, aMELF, theEImages, theInvEdges, theInvertedEdges, theEdgesOrigins, |
4642 | theOEImages, theOEOrigins, theETrimEInf, theEETrim, theModifiedEdges, theAsDes); |
4643 | return; |
4644 | } |
4645 | // |
4646 | TopoDS_Shape aSplits1; |
4647 | if (aLA.Extent() > 1) { |
4648 | // intersect the new splits among themselves to avoid self-intersections |
41aa3c3d |
4649 | IntersectEdges(aLA, aLE, aLENew, theMVBounds, theVertsToAvoid, theMECheckExt, |
4650 | theEImages, theModifiedEdges, aDMEOr, aMELF, aMENew, aSplits1); |
ecf4f17c |
4651 | } |
4652 | else { |
4653 | aSplits1 = aLA.First(); |
4654 | } |
4655 | // |
4656 | // filter the new splits with bounds |
4657 | TopoDS_Shape aFilterBounds; |
4658 | GetBounds(theFImages, aMEB, aFilterBounds); |
4659 | // |
4660 | // intersect splits and bounds and remove those splits which have pure E/E intersection |
4661 | TopTools_MapOfShape aMEInv; |
41aa3c3d |
4662 | GetInvalidEdgesByBounds(aSplits1, aFilterBounds, theFImages, theSolids, |
4663 | theInvEdges, aMVOld, aMENew, aDMEOr, aMELF, theEImages, |
a8232603 |
4664 | theMECheckExt, theMEInvOnArt, theVertsToAvoid, aMEInv); |
ecf4f17c |
4665 | // |
4666 | // get valid edges only |
4667 | TopoDS_Shape aSplits; |
4668 | if (aMEInv.Extent()) { |
4669 | // clear images from found invalid edges |
4670 | TopoDS_Compound aSp; |
4671 | BRep_Builder().MakeCompound(aSp); |
4672 | TopTools_MapOfShape aMFence; |
4673 | // |
4674 | TopTools_ListIteratorOfListOfShape aItLE(aLE); |
4675 | for (; aItLE.More(); aItLE.Next()) { |
4676 | const TopoDS_Shape& aE = aItLE.Value(); |
4677 | // |
4678 | TopTools_ListOfShape* pLEIm = theEImages.ChangeSeek(aE); |
4679 | if (!pLEIm) { |
4680 | continue; |
4681 | } |
4682 | // |
4683 | TopTools_ListIteratorOfListOfShape aItLEIm(*pLEIm); |
4684 | for (; aItLEIm.More();) { |
4685 | const TopoDS_Shape& aEIm = aItLEIm.Value(); |
4686 | if (aMEInv.Contains(aEIm)) { |
4687 | pLEIm->Remove(aItLEIm); |
4688 | } |
4689 | else { |
4690 | if (aMFence.Add(aEIm)) { |
4691 | BRep_Builder().Add(aSp, aEIm); |
4692 | } |
4693 | aItLEIm.Next(); |
4694 | } |
4695 | } |
4696 | // |
4697 | if (pLEIm->IsEmpty()) { |
4698 | theEImages.UnBind(aE); |
4699 | } |
4700 | } |
4701 | aSplits = aSp; |
4702 | } |
4703 | else { |
4704 | aSplits = aSplits1; |
4705 | } |
4706 | // |
4707 | // get bounds to update |
4708 | // we need to update the edges of all the affected faces |
4709 | TopTools_ListOfShape aLF; |
4710 | // prepare the vertices from new splits of edges |
4711 | TopTools_IndexedMapOfShape aMVSp; |
4712 | TopExp::MapShapes(aSplits, TopAbs_VERTEX, aMVSp); |
4713 | // |
4714 | Standard_Integer aNbF = theFImages.Extent(); |
4715 | for (i = 1; i <= aNbF; ++i) { |
4716 | const TopoDS_Shape& aF = theFImages.FindKey(i); |
4717 | if (theFLE.Contains(aF)) { |
4718 | aLF.Append(aF); |
4719 | continue; |
4720 | } |
4721 | // |
4722 | // check the splits of faces to have vertices from splits |
4723 | const TopTools_ListOfShape& aLFIm = theFImages(i); |
4724 | TopTools_ListIteratorOfListOfShape aItLFIm(aLFIm); |
4725 | for (; aItLFIm.More(); aItLFIm.Next()) { |
4726 | const TopoDS_Shape& aFIm = aItLFIm.Value(); |
4727 | // |
4728 | TopExp_Explorer aExpV(aFIm, TopAbs_VERTEX); |
4729 | for (; aExpV.More(); aExpV.Next()) { |
4730 | const TopoDS_Shape& aV = aExpV.Current(); |
4731 | if (aMVSp.Contains(aV)) { |
4732 | break; |
4733 | } |
4734 | } |
4735 | // |
4736 | if (aExpV.More()) { |
4737 | break; |
4738 | } |
4739 | } |
4740 | // |
4741 | if (aItLFIm.More()) { |
4742 | aLF.Append(aF); |
4743 | } |
4744 | } |
4745 | // |
4746 | // get bounds from splits of faces of aLF |
4747 | TopoDS_Shape aBounds; |
4748 | TopTools_ListOfShape aLAValid, aLABounds; |
4749 | GetBoundsToUpdate(aLF, theOEImages, theOEOrigins, aMEB, |
4750 | aLABounds, aLAValid, aBounds, theAsDes); |
4751 | // |
4752 | // intersect valid splits with bounds and update both |
4753 | BOPAlgo_Builder aGF; |
4754 | aGF.AddArgument(aSplits); |
4755 | aGF.AddArgument(aBounds); |
4756 | aGF.Perform(); |
4757 | // |
4758 | // update splits |
4759 | UpdateImages(aLE, theEImages, aGF, theModifiedEdges); |
4760 | // |
4761 | // update new intersection edges |
4762 | UpdateNewIntersectionEdges(aLE, aMELF, theEImages, theInvEdges, theInvertedEdges, theEdgesOrigins, |
4763 | theOEImages, theOEOrigins, theETrimEInf, theEETrim, theModifiedEdges, theAsDes); |
4764 | // |
4765 | // update bounds |
4766 | UpdateImages(aLAValid, theOEImages, aGF, theModifiedEdges); |
4767 | UpdateOrigins(aLABounds, theOEOrigins, aGF); |
4768 | UpdateOrigins(aLABounds, theEdgesOrigins, aGF); |
4769 | UpdateIntersectedEdges(aLABounds, theETrimEInf, aGF); |
4770 | // |
4771 | // update the edges to avoid with the splits |
4772 | TopTools_IndexedMapOfShape aNewEdges; |
4773 | const TopTools_ListOfShape* pSplitsIm = aGF.Images().Seek(aSplits); |
4774 | if (pSplitsIm) { |
4775 | TopTools_ListIteratorOfListOfShape aItSpIm(*pSplitsIm); |
4776 | for (; aItSpIm.More(); aItSpIm.Next()) { |
4777 | TopExp::MapShapes(aItSpIm.Value(), TopAbs_EDGE, aNewEdges); |
4778 | } |
4779 | } |
4780 | // |
4781 | Standard_Integer aNbE = theEdgesToAvoid.Extent(); |
4782 | for (i = 1; i <= aNbE; ++i) { |
4783 | const TopoDS_Shape& aE = theEdgesToAvoid(i); |
4784 | const TopTools_ListOfShape& aLEIm = aGF.Modified(aE); |
4785 | TopTools_ListIteratorOfListOfShape aItLEIm(aLEIm); |
4786 | for (; aItLEIm.More(); aItLEIm.Next()) { |
4787 | const TopoDS_Shape& aEIm = aItLEIm.Value(); |
4788 | if (!aNewEdges.Contains(aEIm)) { |
4789 | theEdgesToAvoid.Add(aItLEIm.Value()); |
4790 | } |
4791 | } |
4792 | } |
4793 | } |
4794 | |
4795 | //======================================================================= |
4796 | //function : TrimNewIntersectionEdges |
4797 | //purpose : |
4798 | //======================================================================= |
4799 | void TrimNewIntersectionEdges(const TopTools_ListOfShape& theLE, |
4800 | const TopTools_DataMapOfShapeListOfShape& theEETrim, |
4801 | const TopTools_MapOfShape& theMVBounds, |
41aa3c3d |
4802 | TopTools_MapOfShape& theMECheckExt, |
ecf4f17c |
4803 | TopTools_DataMapOfShapeListOfShape& theEImages, |
4804 | TopTools_MapOfShape& theMEB, |
4805 | TopTools_MapOfShape& theMVOld, |
4806 | TopTools_ListOfShape& theLENew, |
4807 | BOPCol_ListOfShape& theLA, |
41aa3c3d |
4808 | TopTools_DataMapOfShapeListOfShape& theDMEOr, |
4809 | TopTools_DataMapOfShapeListOfShape& theMELF) |
ecf4f17c |
4810 | { |
4811 | TopTools_ListIteratorOfListOfShape aIt, aIt1; |
4812 | aIt.Initialize(theLE); |
4813 | for (; aIt.More(); aIt.Next()) { |
4814 | const TopoDS_Shape& aE = aIt.Value(); |
4815 | // |
b443d536 |
4816 | Standard_Boolean bCheckExt = theMECheckExt.Remove(aE); |
4817 | // |
41aa3c3d |
4818 | Standard_Boolean bOld = theEETrim.IsBound(aE); |
4819 | if (bOld) { |
ecf4f17c |
4820 | const TopTools_ListOfShape& aLET = theEETrim.Find(aE); |
4821 | aIt1.Initialize(aLET); |
4822 | for (; aIt1.More(); aIt1.Next()) { |
4823 | const TopoDS_Shape& aET = aIt1.Value(); |
4824 | theMEB.Add(aET); |
4825 | TopExp_Explorer aExpV(aET, TopAbs_VERTEX); |
4826 | for (; aExpV.More(); aExpV.Next()) { |
4827 | const TopoDS_Shape& aV = aExpV.Current(); |
4828 | theMVOld.Add(aV); |
4829 | } |
4830 | } |
4831 | } |
4832 | // |
4833 | if (!theEImages.IsBound(aE)) { |
4834 | continue; |
4835 | } |
4836 | // |
4837 | TopTools_ListOfShape& aLEIm = theEImages.ChangeFind(aE); |
4838 | if (aLEIm.IsEmpty()) { |
4839 | theEImages.UnBind(aE); |
4840 | continue; |
4841 | } |
4842 | // |
4843 | TopoDS_Shape aCEIm; |
4844 | TopTools_MapOfShape aMEVBounds; |
4845 | // |
a8232603 |
4846 | if (aLEIm.Extent() > 1) { |
ecf4f17c |
4847 | TopTools_IndexedMapOfShape aMV; |
4848 | // fuse these parts |
4849 | BOPAlgo_Builder aGFE; |
4850 | TopTools_ListIteratorOfListOfShape aItLEIm(aLEIm); |
4851 | for (; aItLEIm.More(); aItLEIm.Next()) { |
4852 | const TopoDS_Shape& aEIm = aItLEIm.Value(); |
4853 | aGFE.AddArgument(aEIm); |
4854 | TopExp::MapShapes(aEIm, TopAbs_VERTEX, aMV); |
4855 | } |
4856 | // |
4857 | // add two bounding vertices of this edge to the operation |
4858 | TopoDS_Vertex aV1, aV2; |
4859 | TopExp::Vertices(TopoDS::Edge(aE), aV1, aV2); |
4860 | // |
4861 | aGFE.AddArgument(aV1); |
4862 | aGFE.AddArgument(aV2); |
4863 | aMV.Add(aV1); |
4864 | aMV.Add(aV2); |
4865 | // |
4866 | aGFE.Perform(); |
4867 | if (!aGFE.ErrorStatus()) { |
4868 | // get images of bounding vertices to remove splits containing them |
4869 | // in case some of the bounding edges has been interfered |
4870 | // during operation it is necessary to update their images as well |
4871 | Standard_Integer iV, aNbV = aMV.Extent(); |
4872 | for (iV = 1; iV <= aNbV; ++iV) { |
4873 | const TopoDS_Shape& aV = aMV(iV); |
4874 | if (theMVBounds.Contains(aV) || aV.IsSame(aV1) || aV.IsSame(aV2)) { |
4875 | const TopTools_ListOfShape& aLVIm = aGFE.Modified(aV); |
41aa3c3d |
4876 | aMEVBounds.Add(aLVIm.IsEmpty() ? aV : aLVIm.First()); |
ecf4f17c |
4877 | } |
4878 | } |
4879 | // |
4880 | aCEIm = aGFE.Shape(); |
4881 | } |
4882 | } |
4883 | else { |
4884 | aCEIm = aLEIm.First(); |
4885 | } |
4886 | // |
4887 | aLEIm.Clear(); |
4888 | // |
4889 | TopExp_Explorer aExp(aCEIm, TopAbs_EDGE); |
4890 | for (; aExp.More(); aExp.Next()) { |
4891 | const TopoDS_Shape& aEIm = aExp.Current(); |
4892 | // |
4893 | // check the split not to contain bounding vertices |
4894 | TopoDS_Iterator aItV(aEIm); |
4895 | for (; aItV.More(); aItV.Next()) { |
4896 | const TopoDS_Shape& aV = aItV.Value(); |
4897 | if (aMEVBounds.Contains(aV) || theMVBounds.Contains(aV)) { |
4898 | break; |
4899 | } |
4900 | } |
4901 | // |
4902 | if (!aItV.More()) { |
4903 | theLA.Append(aEIm); |
4904 | aLEIm.Append(aEIm); |
4905 | // |
4906 | theDMEOr.Bound(aEIm, TopTools_ListOfShape())->Append(aE); |
4907 | } |
4908 | } |
4909 | // |
4910 | if (aLEIm.IsEmpty()) { |
4911 | theEImages.UnBind(aE); |
4912 | } |
4913 | else { |
41aa3c3d |
4914 | const TopTools_ListOfShape& aLFE = theMELF.Find(aE); |
4915 | TopTools_ListIteratorOfListOfShape aItLEIm(aLEIm); |
4916 | for (; aItLEIm.More(); aItLEIm.Next()) { |
4917 | const TopoDS_Shape& aEIm = aItLEIm.Value(); |
4918 | TopTools_ListOfShape* pLFEIm = theMELF.ChangeSeek(aEIm); |
4919 | if (!pLFEIm) { |
4920 | pLFEIm = theMELF.Bound(aEIm, TopTools_ListOfShape()); |
4921 | } |
4922 | TopTools_ListIteratorOfListOfShape aItLF(aLFE); |
4923 | for (; aItLF.More(); aItLF.Next()) { |
4924 | AppendToList(*pLFEIm, aItLF.Value()); |
4925 | } |
4926 | // |
4927 | if (bCheckExt) { |
4928 | theMECheckExt.Add(aEIm); |
4929 | } |
4930 | else if (!bOld) { |
ecf4f17c |
4931 | theLENew.Append(aEIm); |
4932 | } |
4933 | } |
4934 | } |
4935 | } |
4936 | } |
4937 | |
4938 | //======================================================================= |
4939 | //function : IntersectEdges |
4940 | //purpose : Intersecting the trimmed edges to avoid self-intersections |
4941 | //======================================================================= |
4942 | void IntersectEdges(const BOPCol_ListOfShape& theLA, |
4943 | const TopTools_ListOfShape& theLE, |
4944 | const TopTools_ListOfShape& theLENew, |
4945 | const TopTools_MapOfShape& theMVBounds, |
4946 | const TopTools_MapOfShape& theVertsToAvoid, |
41aa3c3d |
4947 | TopTools_MapOfShape& theMECheckExt, |
ecf4f17c |
4948 | TopTools_DataMapOfShapeListOfShape& theEImages, |
4949 | TopTools_MapOfShape& theModifiedEdges, |
4950 | TopTools_DataMapOfShapeListOfShape& theDMEOr, |
41aa3c3d |
4951 | TopTools_DataMapOfShapeListOfShape& theMELF, |
ecf4f17c |
4952 | TopTools_MapOfShape& theMENew, |
4953 | TopoDS_Shape& theSplits) |
4954 | { |
4955 | BOPAlgo_Builder aGFA; |
4956 | aGFA.SetArguments(theLA); |
4957 | aGFA.Perform(); |
4958 | if (aGFA.ErrorStatus()) { |
4959 | // just copy input to the result |
4960 | TopoDS_Compound aSp; |
4961 | BRep_Builder aBB; |
4962 | aBB.MakeCompound(aSp); |
4963 | BOPCol_ListIteratorOfListOfShape anIt(theLA); |
4964 | for (; anIt.More(); anIt.Next()) { |
4965 | const TopoDS_Shape& aE = anIt.Value(); |
4966 | aBB.Add(aSp, aE); |
4967 | } |
4968 | theSplits = aSp; |
4969 | return; |
4970 | } |
4971 | // |
4972 | UpdateImages(theLE, theEImages, aGFA, theModifiedEdges); |
4973 | // |
4974 | // compound of valid splits |
4975 | theSplits = aGFA.Shape(); |
4976 | // |
4977 | // update new edges |
4978 | TopTools_ListIteratorOfListOfShape aIt, aIt1; |
4979 | aIt.Initialize(theLENew); |
4980 | for (; aIt.More(); aIt.Next()) { |
4981 | const TopoDS_Shape& aE = aIt.Value(); |
4982 | const TopTools_ListOfShape& aLEIm = aGFA.Modified(aE); |
4983 | if (aLEIm.Extent()) { |
4984 | aIt1.Initialize(aLEIm); |
4985 | for (; aIt1.More(); aIt1.Next()) { |
4986 | const TopoDS_Shape& aEIm = aIt1.Value(); |
4987 | theMENew.Add(aEIm); |
4988 | } |
4989 | } |
4990 | else { |
4991 | theMENew.Add(aE); |
4992 | } |
4993 | } |
4994 | // |
41aa3c3d |
4995 | // update edges after intersection for extended checking |
4996 | aIt.Initialize(theLA); |
4997 | for (; aIt.More(); aIt.Next()) { |
4998 | const TopoDS_Shape& aE = aIt.Value(); |
4999 | const TopTools_ListOfShape& aLEIm = aGFA.Modified(aE); |
5000 | if (aLEIm.IsEmpty()) { |
5001 | continue; |
5002 | } |
5003 | // |
5004 | if (theMECheckExt.Contains(aE)) { |
5005 | aIt1.Initialize(aLEIm); |
5006 | for (; aIt1.More(); aIt1.Next()) { |
5007 | theMECheckExt.Add(aIt1.Value()); |
5008 | } |
5009 | theMECheckExt.Remove(aE); |
5010 | } |
5011 | // |
5012 | const TopTools_ListOfShape& aLFE = theMELF.Find(aE); |
5013 | aIt1.Initialize(aLEIm); |
5014 | for (; aIt1.More(); aIt1.Next()) { |
5015 | const TopoDS_Shape& aEIm = aIt1.Value(); |
5016 | TopTools_ListOfShape* pLFEIm = theMELF.ChangeSeek(aEIm); |
5017 | if (!pLFEIm) { |
5018 | pLFEIm = theMELF.Bound(aEIm, TopTools_ListOfShape()); |
5019 | } |
5020 | TopTools_ListIteratorOfListOfShape aItLF(aLFE); |
5021 | for (; aItLF.More(); aItLF.Next()) { |
5022 | AppendToList(*pLFEIm, aItLF.Value()); |
5023 | } |
5024 | } |
5025 | } |
5026 | // |
ecf4f17c |
5027 | TopTools_MapOfShape aMEInv; |
5028 | GetInvalidEdges(theVertsToAvoid, theMVBounds, aGFA, aMEInv); |
5029 | if (aMEInv.Extent()) { |
5030 | // update shape |
5031 | TopoDS_Compound aSp; |
5032 | BRep_Builder aBB; |
5033 | aBB.MakeCompound(aSp); |
5034 | TopExp_Explorer aExp(theSplits, TopAbs_EDGE); |
5035 | for (; aExp.More(); aExp.Next()) { |
5036 | const TopoDS_Shape& aE = aExp.Current(); |
5037 | if (!aMEInv.Contains(aE)) { |
5038 | aBB.Add(aSp, aE); |
5039 | } |
5040 | } |
5041 | theSplits = aSp; |
5042 | } |
5043 | // |
5044 | UpdateOrigins(theLA, theDMEOr, aGFA); |
5045 | } |
5046 | |
5047 | //======================================================================= |
5048 | //function : GetBounds |
5049 | //purpose : Getting edges from the splits of offset faces |
5050 | //======================================================================= |
5051 | void GetBounds(const TopTools_IndexedDataMapOfShapeListOfShape& theFImages, |
5052 | const TopTools_MapOfShape& theMEB, |
5053 | TopoDS_Shape& theBounds) |
5054 | { |
5055 | // make compound of edges contained in the splits of faces |
5056 | TopoDS_Compound aBounds; |
5057 | BRep_Builder aBB; |
5058 | aBB.MakeCompound(aBounds); |
5059 | // |
5060 | TopTools_MapOfShape aMFence; |
5061 | // |
5062 | Standard_Integer i, aNb = theFImages.Extent(); |
5063 | for (i = 1; i <= aNb; ++i) { |
5064 | const TopTools_ListOfShape& aLFIm = theFImages(i); |
5065 | TopTools_ListIteratorOfListOfShape aIt(aLFIm); |
5066 | for (; aIt.More(); aIt.Next()) { |
5067 | const TopoDS_Shape& aFIm = aIt.Value(); |
5068 | // |
5069 | TopExp_Explorer aExpE(aFIm, TopAbs_EDGE); |
5070 | for (; aExpE.More(); aExpE.Next()) { |
5071 | const TopoDS_Shape& aEIm = aExpE.Current(); |
5072 | if (!theMEB.Contains(aEIm) && aMFence.Add(aEIm)) { |
5073 | aBB.Add(aBounds, aEIm); |
5074 | } |
5075 | } |
5076 | } |
5077 | } |
5078 | theBounds = aBounds; |
5079 | } |
5080 | |
5081 | //======================================================================= |
5082 | //function : GetBoundsToUpdate |
5083 | //purpose : Get bounding edges that should be updated |
5084 | //======================================================================= |
5085 | void GetBoundsToUpdate(const TopTools_ListOfShape& theLF, |
5086 | const TopTools_DataMapOfShapeListOfShape& theOEImages, |
5087 | const TopTools_DataMapOfShapeListOfShape& theOEOrigins, |
5088 | const TopTools_MapOfShape& theMEB, |
5089 | TopTools_ListOfShape& theLABounds, |
5090 | TopTools_ListOfShape& theLAValid, |
5091 | TopoDS_Shape& theBounds, |
5092 | Handle(BRepAlgo_AsDes)& theAsDes) |
5093 | { |
5094 | // get all edges |
5095 | TopoDS_Compound aBounds; |
5096 | BRep_Builder aBB; |
5097 | aBB.MakeCompound(aBounds); |
5098 | // |
5099 | TopTools_MapOfShape aMAValid, aMFence; |
5100 | // |
5101 | TopTools_ListIteratorOfListOfShape aItLF(theLF); |
5102 | for (; aItLF.More(); aItLF.Next()) { |
5103 | const TopoDS_Shape& aF = aItLF.Value(); |
5104 | // |
5105 | TopTools_IndexedMapOfShape aMDE; |
5106 | const TopTools_ListOfShape& aLFDes = theAsDes->Descendant(aF); |
5107 | TopTools_ListIteratorOfListOfShape aItLFDes(aLFDes); |
5108 | for (; aItLFDes.More(); aItLFDes.Next()) { |
5109 | const TopoDS_Shape& aED = aItLFDes.Value(); |
5110 | const TopTools_ListOfShape *pLEDIm = theOEImages.Seek(aED); |
5111 | if (!pLEDIm) { |
5112 | aMDE.Add(aED); |
5113 | continue; |
5114 | } |
5115 | // |
5116 | TopTools_ListIteratorOfListOfShape aItLEDIm(*pLEDIm); |
5117 | for (; aItLEDIm.More(); aItLEDIm.Next()) { |
5118 | const TopoDS_Shape& aEDIm = aItLEDIm.Value(); |
5119 | aMDE.Add(aEDIm); |
5120 | } |
5121 | } |
5122 | // |
5123 | Standard_Integer j, aNbE = aMDE.Extent(); |
5124 | for (j = 1; j <= aNbE; ++j) { |
5125 | const TopoDS_Edge& aEIm = TopoDS::Edge(aMDE(j)); |
5126 | // |
5127 | if (!theMEB.Contains(aEIm) && aMFence.Add(aEIm)) { |
5128 | aBB.Add(aBounds, aEIm); |
5129 | theLABounds.Append(aEIm); |
5130 | } |
5131 | // |
5132 | const TopTools_ListOfShape *pLO = theOEOrigins.Seek(aEIm); |
5133 | if (pLO) { |
5134 | TopTools_ListIteratorOfListOfShape aItLO(*pLO); |
5135 | for (; aItLO.More(); aItLO.Next()) { |
5136 | const TopoDS_Shape& aEO = aItLO.Value(); |
5137 | // |
5138 | if (aMAValid.Add(aEO)) { |
5139 | theLAValid.Append(aEO); |
5140 | } |
5141 | } |
5142 | } |
5143 | else { |
5144 | if (aMAValid.Add(aEIm)) { |
5145 | theLAValid.Append(aEIm); |
5146 | } |
5147 | } |
5148 | } |
5149 | } |
5150 | theBounds = aBounds; |
5151 | } |
5152 | |
5153 | //======================================================================= |
5154 | //function : GetInvalidEdgesByBounds |
5155 | //purpose : Filter new splits by intersection with bounds |
5156 | //======================================================================= |
5157 | void GetInvalidEdgesByBounds(const TopoDS_Shape& theSplits, |
5158 | const TopoDS_Shape& theBounds, |
ecf4f17c |
5159 | const TopTools_IndexedDataMapOfShapeListOfShape& theFImages, |
5160 | const TopoDS_Shape& theSolids, |
5161 | const TopTools_IndexedMapOfShape& theInvEdges, |
5162 | const TopTools_MapOfShape& theMVOld, |
5163 | const TopTools_MapOfShape& theMENew, |
5164 | const TopTools_DataMapOfShapeListOfShape& theDMEOr, |
41aa3c3d |
5165 | const TopTools_DataMapOfShapeListOfShape& theMELF, |
ecf4f17c |
5166 | const TopTools_DataMapOfShapeListOfShape& theEImages, |
41aa3c3d |
5167 | const TopTools_MapOfShape& theMECheckExt, |
a8232603 |
5168 | const TopTools_MapOfShape& theMEInvOnArt, |
ecf4f17c |
5169 | TopTools_MapOfShape& theVertsToAvoid, |
5170 | TopTools_MapOfShape& theMEInv) |
5171 | { |
a8232603 |
5172 | // map splits to check the vertices of edges |
5173 | TopTools_IndexedDataMapOfShapeListOfShape aDMVE; |
5174 | TopExp::MapShapesAndAncestors(theSplits, TopAbs_VERTEX, TopAbs_EDGE, aDMVE); |
5175 | // |
ecf4f17c |
5176 | BOPAlgo_Section aSec; |
5177 | aSec.AddArgument(theSplits); |
5178 | aSec.AddArgument(theBounds); |
5179 | // |
5180 | aSec.Perform(); |
5181 | // |
5182 | // invalid vertices |
5183 | TopTools_IndexedMapOfShape aMVInv; |
5184 | // vertices to check additionally by classification relatively to solid |
5185 | TopTools_MapOfShape aMVCheckAdd; |
5186 | // collect parts for removal |
5187 | const BOPDS_PDS& pDS = aSec.PDS(); |
5188 | // |
5189 | // check edge/edge intersections |
5190 | const BOPDS_VectorOfInterfEE& aEEs = pDS->InterfEE(); |
5191 | Standard_Integer i, aNb = aEEs.Extent(); |
5192 | for (i = 0; i < aNb; ++i) { |
5193 | const BOPDS_InterfEE& aEE = aEEs(i); |
ecf4f17c |
5194 | // |
5195 | const TopoDS_Shape& aE1 = pDS->Shape(aEE.Index1()); |
5196 | const TopoDS_Shape& aE2 = pDS->Shape(aEE.Index2()); |
5197 | // |
41aa3c3d |
5198 | if (!aEE.HasIndexNew()) { |
5199 | if (theMECheckExt.Contains(aE1) && (aEE.CommonPart().Type() == TopAbs_EDGE)) { |
5200 | theMEInv.Add(aE1); |
5201 | } |
5202 | continue; |
5203 | } |
5204 | // |
ecf4f17c |
5205 | if (theInvEdges.Contains(aE2)) { |
5206 | theMEInv.Add(aE1); |
5207 | } |
5208 | // |
a8232603 |
5209 | if (theMEInvOnArt.Contains(aE2)) { |
5210 | // avoid checking of the vertices of the split edge intersected by |
5211 | // the invalid edge from artificial face |
5212 | TopoDS_Vertex aV1, aV2; |
5213 | TopExp::Vertices(TopoDS::Edge(aE2), aV1, aV2); |
5214 | if (aDMVE.Contains(aV1) && aDMVE.Contains(aV2)) { |
5215 | continue; |
5216 | } |
5217 | } |
5218 | // |
41aa3c3d |
5219 | // add vertices of all images of the edge from splits for checking |
ecf4f17c |
5220 | const TopTools_ListOfShape& aLEOr = theDMEOr.Find(aE1); |
5221 | TopTools_ListIteratorOfListOfShape aItLEOr(aLEOr); |
5222 | for (; aItLEOr.More(); aItLEOr.Next()) { |
5223 | const TopoDS_Shape& aEOr = aItLEOr.Value(); |
5224 | // |
5225 | const TopTools_ListOfShape& aLEIm = theEImages.Find(aEOr); |
5226 | TopTools_ListIteratorOfListOfShape aItLEIm(aLEIm); |
5227 | for (; aItLEIm.More(); aItLEIm.Next()) { |
5228 | const TopoDS_Shape& aEIm = aItLEIm.Value(); |
5229 | // |
5230 | TopoDS_Iterator aItV(aEIm); |
5231 | for (; aItV.More(); aItV.Next()) { |
5232 | const TopoDS_Shape& aV = aItV.Value(); |
5233 | if (!theMVOld.Contains(aV)) { |
5234 | aMVInv.Add(aV); |
5235 | aMVCheckAdd.Add(aV); |
5236 | } |
5237 | } |
5238 | } |
5239 | } |
5240 | } |
5241 | // |
ecf4f17c |
5242 | // to avoid unnecessary filling of parts due to extra trim of the edges |
41aa3c3d |
5243 | // process Edge/Edge interferences of type EDGE, i.e. common blocks and check |
5244 | // not the bounding vertices of the edges, but check the edge itself |
5245 | // to be lying on some face |
ecf4f17c |
5246 | // |
5247 | // all common blocks are contained in the result of SECTION operation |
5248 | // between sets of edges |
5249 | const TopoDS_Shape& aSecR = aSec.Shape(); |
5250 | // |
5251 | TopTools_IndexedMapOfShape aMSSec; |
5252 | TopExp::MapShapes(aSecR, aMSSec); |
5253 | // |
5254 | const BOPCol_DataMapOfShapeListOfShape& anIm = aSec.Images(); |
45d0af05 |
5255 | for (TopExp_Explorer aExp(theSplits, TopAbs_EDGE); aExp.More(); aExp.Next()) |
5256 | { |
ecf4f17c |
5257 | const TopoDS_Shape& aE = aExp.Current(); |
5258 | if (aSec.IsDeleted(aE)) { |
5259 | // no common blocks for this edge |
5260 | continue; |
5261 | } |
5262 | // |
5263 | const BOPCol_ListOfShape* pLEIm = anIm.Seek(aE); |
5264 | if (!pLEIm) { |
5265 | // no splits, i.e. completely coincides with some edge from boundary |
5266 | continue; |
5267 | } |
5268 | // |
5269 | BOPCol_ListIteratorOfListOfShape aItLEIm(*pLEIm); |
5270 | for (; aItLEIm.More(); aItLEIm.Next()) { |
5271 | const TopoDS_Shape& aEIm = aItLEIm.Value(); |
5272 | if (!aMSSec.Contains(aEIm)) { |
5273 | // the edge included in section only partially. |
41aa3c3d |
5274 | // the part not included in section may be excessive |
ecf4f17c |
5275 | // |
5276 | // check vertices of this edge - if one of them is new |
5277 | // the edge might be removed |
5278 | TopoDS_Vertex aV1, aV2; |
5279 | TopExp::Vertices(TopoDS::Edge(aEIm), aV1, aV2); |
5280 | if (!theMVOld.Contains(aV1) || !theMVOld.Contains(aV2)) { |
41aa3c3d |
5281 | // add this edge for checking by making new vertex in the middle of the edge |
ecf4f17c |
5282 | TopoDS_Vertex aV; |
5283 | Standard_Real f, l; |
5284 | const Handle(Geom_Curve)& aC = BRep_Tool::Curve(TopoDS::Edge(aEIm), f, l); |
5285 | BRep_Builder().MakeVertex(aV, aC->Value((f+l)*0.5), Precision::Confusion()); |
41aa3c3d |
5286 | // and adding this vertex for checking |
5287 | aDMVE.ChangeFromIndex(aDMVE.Add(aV, TopTools_ListOfShape())).Append(aE); |
ecf4f17c |
5288 | aMVInv.Add(aV); |
5289 | break; |
5290 | } |
5291 | } |
5292 | } |
5293 | } |
5294 | // |
41aa3c3d |
5295 | // Add for check also the edges created from common between splits |
5296 | // of offset faces edges not connected to any invalidity. |
5297 | // These edges may also accidentally fill some part. |
5298 | TopTools_MapIteratorOfMapOfShape aItM(theMECheckExt); |
5299 | for (; aItM.More(); aItM.Next()) { |
5300 | const TopoDS_Shape& aE = aItM.Value(); |
5301 | // |
5302 | // make new vertex in the middle of the edge |
5303 | TopoDS_Vertex aV; |
5304 | Standard_Real f, l; |
5305 | const Handle(Geom_Curve)& aC = BRep_Tool::Curve(TopoDS::Edge(aE), f, l); |
5306 | BRep_Builder().MakeVertex(aV, aC->Value((f + l)*0.5), Precision::Confusion()); |
5307 | // add this vertex for checking |
5308 | aDMVE.ChangeFromIndex(aDMVE.Add(aV, TopTools_ListOfShape())).Append(aE); |
5309 | aMVInv.Add(aV); |
5310 | } |
5311 | // |
5312 | // add for check also the vertices connected only to new or old edges |
ecf4f17c |
5313 | aNb = aDMVE.Extent(); |
5314 | for (i = 1; i <= aNb; ++i) { |
5315 | const TopoDS_Shape& aV = aDMVE.FindKey(i); |
5316 | if (theMVOld.Contains(aV)) { |
5317 | continue; |
5318 | } |
5319 | // |
5320 | Standard_Boolean bNew = Standard_False, bOld = Standard_False; |
5321 | const TopTools_ListOfShape& aLEx = aDMVE(i); |
5322 | TopTools_ListIteratorOfListOfShape aIt(aLEx); |
5323 | for (; aIt.More(); aIt.Next()) { |
5324 | const TopoDS_Shape& aE = aIt.Value(); |
41aa3c3d |
5325 | if (theMECheckExt.Contains(aE)) { |
5326 | continue; |
5327 | } |
5328 | // |
ecf4f17c |
5329 | if (theMENew.Contains(aE)) { |
5330 | bNew = Standard_True; |
5331 | } |
5332 | else { |
5333 | bOld = Standard_True; |
5334 | } |
5335 | // |
5336 | if (bNew && bOld) { |
5337 | break; |
5338 | } |
5339 | } |
5340 | // |
5341 | if (!bNew || !bOld) { |
5342 | aMVInv.Add(aV); |
5343 | aMVCheckAdd.Remove(aV); |
5344 | } |
5345 | } |
5346 | // |
41aa3c3d |
5347 | // perform the checking |
ecf4f17c |
5348 | Handle(IntTools_Context) aCtx = new IntTools_Context; |
5349 | // filter vertices |
41aa3c3d |
5350 | Standard_Integer iv, aNbIV = aMVInv.Extent(); |
ecf4f17c |
5351 | for (iv = 1; iv <= aNbIV; ++iv) { |
5352 | const TopoDS_Vertex& aV = TopoDS::Vertex(aMVInv(iv)); |
41aa3c3d |
5353 | if (theMVOld.Contains(aV)) { |
5354 | continue; |
5355 | } |
5356 | // |
5357 | const TopTools_ListOfShape* pLEInv = aDMVE.Seek(aV); |
5358 | if (!pLEInv) { |
5359 | continue; |
5360 | } |
5361 | // find faces by the edges to check the vertex |
5362 | TopTools_IndexedMapOfShape aMF; |
5363 | TopTools_ListIteratorOfListOfShape aItLE(*pLEInv); |
5364 | for (; aItLE.More(); aItLE.Next()) { |
5365 | const TopoDS_Shape& aE = aItLE.Value(); |
5366 | const TopTools_ListOfShape& aLF = theMELF.Find(aE); |
5367 | TopTools_ListIteratorOfListOfShape aItLF(aLF); |
5368 | for (; aItLF.More(); aItLF.Next()) { |
5369 | aMF.Add(aItLF.Value()); |
5370 | } |
5371 | } |
5372 | // |
5373 | // check the vertex to belong to some split of the faces |
ecf4f17c |
5374 | Standard_Boolean bInvalid = Standard_True; |
5375 | // |
41aa3c3d |
5376 | Standard_Integer aNbF = aMF.Extent(); |
ecf4f17c |
5377 | for (i = 1; i <= aNbF && bInvalid; ++i) { |
41aa3c3d |
5378 | const TopoDS_Face& aF = TopoDS::Face(aMF(i)); |
ecf4f17c |
5379 | const TopTools_ListOfShape& aLFIm = theFImages.FindFromKey(aF); |
5380 | // |
5381 | TopTools_ListIteratorOfListOfShape aItLF(aLFIm); |
5382 | for (; aItLF.More() && bInvalid; aItLF.Next()) { |
5383 | const TopoDS_Face& aFIm = TopoDS::Face(aItLF.Value()); |
5384 | TopExp_Explorer aExp(aFIm, TopAbs_VERTEX); |
5385 | for (; aExp.More() && bInvalid; aExp.Next()) { |
5386 | const TopoDS_Shape& aVF = aExp.Current(); |
5387 | bInvalid = !aVF.IsSame(aV); |
5388 | } |
41aa3c3d |
5389 | } |
5390 | // |
5391 | if (bInvalid) { |
5392 | Standard_Real U, V, aTol; |
5393 | Standard_Integer iStatus = aCtx->ComputeVF(aV, aF, U, V, aTol); |
5394 | if (!iStatus) { |
5395 | // classify the point relatively faces |
5396 | gp_Pnt2d aP2d(U, V); |
5397 | aItLF.Initialize(aLFIm); |
5398 | for (; aItLF.More() && bInvalid; aItLF.Next()) { |
5399 | const TopoDS_Face& aFIm = TopoDS::Face(aItLF.Value()); |
5400 | bInvalid = !aCtx->IsPointInOnFace(aFIm, aP2d); |
5401 | } |
ecf4f17c |
5402 | } |
5403 | } |
5404 | } |
5405 | // |
5406 | if (bInvalid && aMVCheckAdd.Contains(aV)) { |
5407 | // the vertex is invalid for all faces |
5408 | // check the same vertex for the solids |
41aa3c3d |
5409 | const gp_Pnt& aP = BRep_Tool::Pnt(aV); |
5410 | Standard_Real aTolV = BRep_Tool::Tolerance(aV); |
5411 | // |
ecf4f17c |
5412 | TopExp_Explorer aExpS(theSolids, TopAbs_SOLID); |
5413 | for (; aExpS.More() && bInvalid; aExpS.Next()) { |
5414 | const TopoDS_Solid& aSol = TopoDS::Solid(aExpS.Current()); |
5415 | BRepClass3d_SolidClassifier& aSC = aCtx->SolidClassifier(aSol); |
5416 | aSC.Perform(aP, aTolV); |
5417 | bInvalid = (aSC.State() == TopAbs_OUT); |
5418 | } |
5419 | } |
5420 | // |
5421 | if (bInvalid) { |
5422 | theVertsToAvoid.Add(aV); |
41aa3c3d |
5423 | aItLE.Initialize(*pLEInv); |
5424 | for (; aItLE.More(); aItLE.Next()) { |
5425 | theMEInv.Add(aItLE.Value()); |
ecf4f17c |
5426 | } |
5427 | } |
5428 | } |
5429 | } |
5430 | |
5431 | //======================================================================= |
5432 | //function : UpdateNewIntersectionEdges |
5433 | //purpose : Updating the maps of images and origins of the offset edges |
5434 | //======================================================================= |
5435 | void UpdateNewIntersectionEdges(const TopTools_ListOfShape& theLE, |
5436 | const TopTools_DataMapOfShapeListOfShape& theMELF, |
5437 | const TopTools_DataMapOfShapeListOfShape& theEImages, |
5438 | const TopTools_IndexedMapOfShape& theInvEdges, |
5439 | const TopTools_MapOfShape& theInvertedEdges, |
5440 | TopTools_DataMapOfShapeListOfShape& theEdgesOrigins, |
5441 | TopTools_DataMapOfShapeListOfShape& theOEImages, |
5442 | TopTools_DataMapOfShapeListOfShape& theOEOrigins, |
5443 | TopTools_DataMapOfShapeShape& theETrimEInf, |
5444 | TopTools_DataMapOfShapeListOfShape& theEETrim, |
5445 | TopTools_MapOfShape& theModifiedEdges, |
5446 | Handle(BRepAlgo_AsDes)& theAsDes) |
5447 | { |
5448 | TopTools_ListOfShape aLEImEmpty; |
5449 | TopTools_ListIteratorOfListOfShape aIt, aIt1; |
5450 | // update global maps of images and origins with new splits |
5451 | aIt.Initialize(theLE); |
5452 | for (; aIt.More(); aIt.Next()) { |
5453 | const TopoDS_Shape& aE = aIt.Value(); |
5454 | // |
5455 | if (!theEImages.IsBound(aE)) { |
5456 | TopTools_ListOfShape* pLET = theEETrim.ChangeSeek(aE); |
5457 | if (!pLET) { |
5458 | continue; |
5459 | } |
5460 | // |
5461 | TopTools_ListIteratorOfListOfShape aItLET(*pLET); |
5462 | for (; aItLET.More();) { |
5463 | const TopoDS_Shape& aET = aItLET.Value(); |
5464 | if (!theInvEdges.Contains(aET) && !theInvertedEdges.Contains(aET)) { |
5465 | pLET->Remove(aItLET); |
5466 | } |
5467 | else { |
5468 | aItLET.Next(); |
5469 | } |
5470 | } |
5471 | // |
5472 | if (pLET->IsEmpty()) { |
5473 | continue; |
5474 | } |
5475 | } |
5476 | // new images |
5477 | const TopTools_ListOfShape& aLENew = |
5478 | theEImages.IsBound(aE) ? theEImages.Find(aE) : aLEImEmpty; |
5479 | // |
5480 | // save connection to untrimmed edge for the next steps |
5481 | aIt1.Initialize(aLENew); |
5482 | for (; aIt1.More(); aIt1.Next()) { |
5483 | const TopoDS_Shape& aET = aIt1.Value(); |
5484 | theETrimEInf.Bind(aET, aE); |
5485 | theModifiedEdges.Add(aET); |
5486 | } |
5487 | // |
5488 | // check if it is existing edge |
5489 | if (!theEETrim.IsBound(aE)) { |
5490 | const TopTools_ListOfShape& aLF = theMELF.Find(aE); |
5491 | // the edge is new |
5492 | // add this edge to AsDes |
5493 | aIt1.Initialize(aLF); |
5494 | for (; aIt1.More(); aIt1.Next()) { |
5495 | const TopoDS_Shape& aF = aIt1.Value(); |
5496 | theAsDes->Add(aF, aE); |
5497 | } |
5498 | // |
5499 | // add aE to the images |
5500 | theOEImages.Bind(aE, aLENew); |
5501 | theModifiedEdges.Add(aE); |
5502 | // |
5503 | // add to origins |
5504 | TopTools_ListIteratorOfListOfShape aItNew(aLENew); |
5505 | for (; aItNew.More(); aItNew.Next()) { |
5506 | const TopoDS_Shape& aENew = aItNew.Value(); |
5507 | if (theOEOrigins.IsBound(aENew)) { |
5508 | TopTools_ListOfShape& aEOrigins = theOEOrigins.ChangeFind(aENew); |
5509 | AppendToList(aEOrigins, aE); |
5510 | } |
5511 | else { |
5512 | TopTools_ListOfShape aEOrigins; |
5513 | aEOrigins.Append(aE); |
5514 | theOEOrigins.Bind(aENew, aEOrigins); |
5515 | } |
5516 | } |
5517 | // |
5518 | // update connection to initial origins |
5519 | if (theEdgesOrigins.IsBound(aE)) { |
5520 | const TopTools_ListOfShape& aLEOrInit = theEdgesOrigins.Find(aE); |
5521 | aIt1.Initialize(aLENew); |
5522 | for (; aIt1.More(); aIt1.Next()) { |
5523 | const TopoDS_Shape& aENew = aIt1.Value(); |
5524 | if (theEdgesOrigins.IsBound(aENew)) { |
5525 | TopTools_ListOfShape& aLENewOr = theEdgesOrigins.ChangeFind(aENew); |
5526 | TopTools_ListIteratorOfListOfShape aItOrInit(aLEOrInit); |
5527 | for (; aItOrInit.More(); aItOrInit.Next()) { |
5528 | const TopoDS_Shape& aEOr = aItOrInit.Value(); |
5529 | AppendToList(aLENewOr, aEOr); |
5530 | } |
5531 | } |
5532 | else { |
5533 | theEdgesOrigins.Bind(aENew, aLEOrInit); |
5534 | } |
5535 | } |
5536 | } |
5537 | // |
5538 | continue; |
5539 | } |
5540 | // |
5541 | // old images |
5542 | const TopTools_ListOfShape& aLEOld = theEETrim.Find(aE); |
5543 | // |
5544 | // list of initial origins |
5545 | TopTools_ListOfShape anInitOrigins; |
5546 | // |
5547 | // it is necessary to replace the old edges with new ones |
5548 | aIt1.Initialize(aLEOld); |
5549 | for (; aIt1.More(); aIt1.Next()) { |
5550 | const TopoDS_Shape& aEOld = aIt1.Value(); |
5551 | // |
5552 | if (theOEOrigins.IsBound(aEOld)) { |
5553 | // get its origins |
5554 | const TopTools_ListOfShape& aEOrigins = theOEOrigins.Find(aEOld); |
5555 | // |
5556 | TopTools_ListIteratorOfListOfShape aItOr(aEOrigins); |
5557 | for (; aItOr.More(); aItOr.Next()) { |
5558 | const TopoDS_Shape& aEOr = aItOr.Value(); |
5559 | // |
5560 | theModifiedEdges.Add(aEOr); |
5561 | // |
5562 | TopTools_ListOfShape& aEImages = theOEImages.ChangeFind(aEOr); |
5563 | // |
5564 | // remove old edge from images |
5565 | TopTools_ListIteratorOfListOfShape aItIm(aEImages); |
5566 | for (; aItIm.More(); ) { |
5567 | const TopoDS_Shape& aEIm = aItIm.Value(); |
5568 | if (aEIm.IsSame(aEOld)) { |
5569 | aEImages.Remove(aItIm); |
5570 | } |
5571 | else { |
5572 | aItIm.Next(); |
5573 | } |
5574 | } |
5575 | // |
5576 | // add new images |
5577 | TopTools_ListIteratorOfListOfShape aItNew(aLENew); |
5578 | for (; aItNew.More(); aItNew.Next()) { |
5579 | const TopoDS_Shape& aENew = aItNew.Value(); |
5580 | AppendToList(aEImages, aENew); |
5581 | if (theOEOrigins.IsBound(aENew)) { |
5582 | TopTools_ListOfShape& aENewOrigins = theOEOrigins.ChangeFind(aENew); |
5583 | AppendToList(aENewOrigins, aEOr); |
5584 | } |
5585 | else { |
5586 | TopTools_ListOfShape aENewOrigins; |
5587 | aENewOrigins.Append(aEOr); |
5588 | theOEOrigins.Bind(aENew, aENewOrigins); |
5589 | } |
5590 | } |
5591 | } |
5592 | } |
5593 | else { |
5594 | // add to images |
5595 | theOEImages.Bind(aEOld, aLENew); |
5596 | // |
5597 | theModifiedEdges.Add(aEOld); |
5598 | // |
5599 | // add to origins |
5600 | TopTools_ListIteratorOfListOfShape aItNew(aLENew); |
5601 | for (; aItNew.More(); aItNew.Next()) { |
5602 | const TopoDS_Shape& aENew = aItNew.Value(); |
5603 | if (theOEOrigins.IsBound(aENew)) { |
5604 | TopTools_ListOfShape& aEOrigins = theOEOrigins.ChangeFind(aENew); |
5605 | AppendToList(aEOrigins, aEOld); |
5606 | } |
5607 | else { |
5608 | TopTools_ListOfShape aEOrigins; |
5609 | aEOrigins.Append(aEOld); |
5610 | theOEOrigins.Bind(aENew, aEOrigins); |
5611 | } |
5612 | } |
5613 | } |
5614 | // |
5615 | // update connection to initial shape |
5616 | if (theEdgesOrigins.IsBound(aEOld)) { |
5617 | const TopTools_ListOfShape& aLEOrInit = theEdgesOrigins.Find(aEOld); |
5618 | TopTools_ListIteratorOfListOfShape aItEOrInit(aLEOrInit); |
5619 | for (; aItEOrInit.More(); aItEOrInit.Next()) { |
5620 | const TopoDS_Shape& aEOrInit = aItEOrInit.Value(); |
5621 | AppendToList(anInitOrigins, aEOrInit); |
5622 | } |
5623 | } |
5624 | } |
5625 | // |
5626 | if (anInitOrigins.Extent()) { |
5627 | TopTools_ListIteratorOfListOfShape aItNew(aLENew); |
5628 | for (; aItNew.More(); aItNew.Next()) { |
5629 | const TopoDS_Shape& aENew = aItNew.Value(); |
5630 | if (theEdgesOrigins.IsBound(aENew)) { |
5631 | TopTools_ListOfShape& aLENewOr = theEdgesOrigins.ChangeFind(aENew); |
5632 | TopTools_ListIteratorOfListOfShape aItOrInit(anInitOrigins); |
5633 | for (; aItOrInit.More(); aItOrInit.Next()) { |
5634 | const TopoDS_Shape& aEOr = aItOrInit.Value(); |
5635 | AppendToList(aLENewOr, aEOr); |
5636 | } |
5637 | } |
5638 | else { |
5639 | theEdgesOrigins.Bind(aENew, anInitOrigins); |
5640 | } |
5641 | } |
5642 | } |
5643 | } |
5644 | } |
5645 | |
5646 | //======================================================================= |
5647 | //function : FillHistory |
5648 | //purpose : Saving obtained results in history tools |
5649 | //======================================================================= |
5650 | void FillHistory(const TopTools_IndexedDataMapOfShapeListOfShape& theFImages, |
5651 | const TopTools_DataMapOfShapeListOfShape& theEImages, |
5652 | BRepAlgo_Image& theImage) |
5653 | { |
5654 | Standard_Integer i, aNb = theFImages.Extent(); |
5655 | if (!aNb) { |
5656 | return; |
5657 | } |
5658 | // |
5659 | BRep_Builder aBB; |
5660 | TopoDS_Compound aFaces; |
5661 | aBB.MakeCompound(aFaces); |
5662 | // |
5663 | // Fill history for faces |
5664 | for (i = 1; i <= aNb; ++i) { |
5665 | const TopoDS_Shape& aF = theFImages.FindKey(i); |
5666 | const TopTools_ListOfShape& aLFImages = theFImages(i); |
5667 | // |
5668 | if (aLFImages.Extent()) { |
5669 | if (theImage.HasImage(aF)) { |
5670 | theImage.Add(aF, aLFImages); |
5671 | } |
5672 | else { |
5673 | theImage.Bind(aF, aLFImages); |
5674 | } |
5675 | } |
5676 | // |
5677 | TopTools_ListIteratorOfListOfShape aItLF(aLFImages); |
5678 | for (; aItLF.More(); aItLF.Next()) { |
5679 | const TopoDS_Shape& aFIm = aItLF.Value(); |
5680 | aBB.Add(aFaces, aFIm); |
5681 | } |
5682 | } |
5683 | // |
5684 | // fill history for edges |
5685 | TopTools_IndexedMapOfShape aMFE; |
5686 | TopExp::MapShapes(aFaces, TopAbs_EDGE, aMFE); |
5687 | // |
5688 | TopTools_DataMapIteratorOfDataMapOfShapeListOfShape aItEIm(theEImages); |
5689 | for (; aItEIm.More(); aItEIm.Next()) { |
5690 | const TopoDS_Shape& aE = aItEIm.Key(); |
5691 | const TopTools_ListOfShape& aLEIm = aItEIm.Value(); |
5692 | // |
5693 | Standard_Boolean bHasImage = theImage.HasImage(aE); |
5694 | TopTools_ListIteratorOfListOfShape aItLE(aLEIm); |
5695 | for (; aItLE.More(); aItLE.Next()) { |
5696 | const TopoDS_Shape& aEIm = aItLE.Value(); |
5697 | if (aMFE.Contains(aEIm)) { |
5698 | if (bHasImage) { |
5699 | theImage.Add(aE, aEIm); |
5700 | } |
5701 | else { |
5702 | theImage.Bind(aE, aEIm); |
5703 | bHasImage = Standard_True; |
5704 | } |
5705 | } |
5706 | } |
5707 | } |
5708 | } |
5709 | |
5710 | //======================================================================= |
5711 | //function : ProcessMicroEdge |
5712 | //purpose : Checking if the edge is micro edge |
5713 | //======================================================================= |
5714 | Standard_Boolean ProcessMicroEdge(const TopoDS_Edge& theEdge, |
5715 | const Handle(IntTools_Context)& theCtx) |
5716 | { |
5717 | TopoDS_Vertex aV1, aV2; |
5718 | TopExp::Vertices(theEdge, aV1, aV2); |
5719 | if (aV1.IsNull() || aV2.IsNull()) { |
5720 | return Standard_False; |
5721 | } |
5722 | // |
5723 | Standard_Boolean bMicro = BOPTools_AlgoTools::IsMicroEdge(theEdge, theCtx); |
5724 | if (bMicro && BRepAdaptor_Curve(theEdge).GetType() == GeomAbs_Line) { |
5725 | Standard_Real aLen = BRep_Tool::Pnt(aV1).Distance(BRep_Tool::Pnt(aV2)); |
5726 | BRep_Builder().UpdateVertex(aV1, aLen / 2.); |
5727 | BRep_Builder().UpdateVertex(aV2, aLen / 2.); |
5728 | } |
5729 | // |
5730 | return bMicro; |
5731 | } |
5732 | |
5733 | //======================================================================= |
5734 | //function : UpdateOrigins |
5735 | //purpose : Updating origins |
5736 | //======================================================================= |
5737 | void UpdateOrigins(const TopTools_ListOfShape& theLA, |
5738 | TopTools_DataMapOfShapeListOfShape& theOrigins, |
5739 | BOPAlgo_Builder& theGF) |
5740 | { |
5741 | TopTools_ListIteratorOfListOfShape aItA(theLA); |
5742 | for (; aItA.More(); aItA.Next()) { |
5743 | const TopoDS_Shape& aS = aItA.Value(); |
5744 | // |
5745 | const TopTools_ListOfShape& aLSIm = theGF.Modified(aS); |
5746 | if (aLSIm.IsEmpty()) { |
5747 | continue; |
5748 | } |
5749 | // |
5750 | TopTools_ListOfShape aLSEmpt; |
5751 | TopTools_ListOfShape *pLS = theOrigins.ChangeSeek(aS); |
5752 | if (!pLS) { |
5753 | pLS = &aLSEmpt; |
5754 | pLS->Append(aS); |
5755 | } |
5756 | // |
5757 | TopTools_ListIteratorOfListOfShape aIt(aLSIm); |
5758 | for (; aIt.More(); aIt.Next()) { |
5759 | const TopoDS_Shape& aSIm = aIt.Value(); |
5760 | // |
5761 | TopTools_ListOfShape *pLSOr = theOrigins.ChangeSeek(aSIm); |
5762 | if (!pLSOr) { |
5763 | // just bind the origins |
5764 | theOrigins.Bind(aSIm, *pLS); |
5765 | } |
5766 | else { |
5767 | // merge two lists |
5768 | TopTools_ListIteratorOfListOfShape aIt1(*pLS); |
5769 | for (; aIt1.More(); aIt1.Next()) { |
5770 | const TopoDS_Shape& aS1 = aIt1.Value(); |
5771 | AppendToList(*pLSOr, aS1); |
5772 | } |
5773 | } |
5774 | } |
5775 | } |
5776 | } |
5777 | |
5778 | //======================================================================= |
5779 | //function : UpdateImages |
5780 | //purpose : Updating images of the shapes |
5781 | //======================================================================= |
5782 | void UpdateImages(const TopTools_ListOfShape& theLA, |
5783 | TopTools_DataMapOfShapeListOfShape& theImages, |
5784 | BOPAlgo_Builder& theGF, |
5785 | TopTools_MapOfShape& theModified) |
5786 | { |
5787 | TopTools_ListIteratorOfListOfShape aIt(theLA); |
5788 | for (; aIt.More(); aIt.Next()) { |
5789 | const TopoDS_Shape& aS = aIt.Value(); |
5790 | // |
5791 | TopTools_ListOfShape* pLSIm = theImages.ChangeSeek(aS); |
5792 | if (!pLSIm) { |
5793 | const TopTools_ListOfShape& aLSIm = theGF.Modified(aS); |
5794 | if (aLSIm.Extent()) { |
5795 | theImages.Bind(aS, aLSIm); |
5796 | theModified.Add(aS); |
5797 | } |
5798 | continue; |
5799 | } |
5800 | // |
5801 | TopTools_MapOfShape aMFence; |
5802 | TopTools_ListOfShape aLSImNew; |
5803 | // |
5804 | Standard_Boolean bModified = Standard_False; |
5805 | // |
5806 | // check modifications of the images |
5807 | TopTools_ListIteratorOfListOfShape aIt1(*pLSIm); |
5808 | for (; aIt1.More(); aIt1.Next()) { |
5809 | const TopoDS_Shape& aSIm = aIt1.Value(); |
5810 | const TopTools_ListOfShape& aLSIm1 = theGF.Modified(aSIm); |
5811 | if (aLSIm1.IsEmpty()) { |
5812 | if (aMFence.Add(aSIm)) { |
5813 | aLSImNew.Append(aSIm); |
5814 | } |
5815 | } |
5816 | else { |
5817 | TopTools_ListIteratorOfListOfShape aIt2(aLSIm1); |
5818 | for (; aIt2.More(); aIt2.Next()) { |
5819 | const TopoDS_Shape& aSImIm = aIt2.Value(); |
5820 | if (aMFence.Add(aSImIm)) { |
5821 | aLSImNew.Append(aSImIm); |
5822 | } |
5823 | } |
5824 | bModified = Standard_True; |
5825 | } |
5826 | } |
5827 | // |
5828 | if (bModified) { |
5829 | *pLSIm = aLSImNew; |
5830 | theModified.Add(aS); |
5831 | } |
5832 | } |
5833 | } |
5834 | |
5835 | //======================================================================= |
5836 | //function : UpdateIntersectedEdges |
5837 | //purpose : Saving connection from trimmed edges to not trimmed ones |
5838 | //======================================================================= |
5839 | void UpdateIntersectedEdges(const TopTools_ListOfShape& theLA, |
5840 | TopTools_DataMapOfShapeShape& theETrimEInf, |
5841 | BOPAlgo_Builder& theGF) |
5842 | { |
5843 | TopTools_ListIteratorOfListOfShape aItA(theLA); |
5844 | for (; aItA.More(); aItA.Next()) { |
5845 | const TopoDS_Shape& aS = aItA.Value(); |
5846 | // |
5847 | const TopoDS_Shape* pEInf = theETrimEInf.Seek(aS); |
5848 | if (!pEInf) { |
5849 | continue; |
5850 | } |
5851 | // |
5852 | const TopTools_ListOfShape& aLSIm = theGF.Modified(aS); |
5853 | if (aLSIm.IsEmpty()) { |
5854 | continue; |
5855 | } |
5856 | // |
5857 | TopTools_ListIteratorOfListOfShape aIt(aLSIm); |
5858 | for (; aIt.More(); aIt.Next()) { |
5859 | const TopoDS_Shape& aEIm = aIt.Value(); |
5860 | if (!theETrimEInf.IsBound(aEIm)) { |
5861 | theETrimEInf.Bind(aEIm, *pEInf); |
5862 | } |
5863 | } |
5864 | } |
5865 | } |
5866 | |
5867 | //======================================================================= |
5868 | //function : FindCommonParts |
5869 | //purpose : Looking for the parts of type <theType> contained in both lists |
5870 | //======================================================================= |
5871 | void FindCommonParts(const TopTools_ListOfShape& theLS1, |
5872 | const TopTools_ListOfShape& theLS2, |
5873 | TopTools_ListOfShape& theLSC, |
5874 | const TopAbs_ShapeEnum theType) |
5875 | { |
5876 | // map shapes in the first list |
5877 | TopTools_IndexedMapOfShape aMS1; |
5878 | TopTools_ListIteratorOfListOfShape aIt(theLS1); |
5879 | for (; aIt.More(); aIt.Next()) { |
5880 | const TopoDS_Shape& aS = aIt.Value(); |
5881 | TopExp::MapShapes(aS, theType, aMS1); |
5882 | } |
5883 | // |
5884 | if (aMS1.IsEmpty()) { |
5885 | return; |
5886 | } |
5887 | // |
5888 | TopTools_MapOfShape aMFence; |
5889 | // check for such shapes in the other list |
5890 | aIt.Initialize(theLS2); |
5891 | for (; aIt.More(); aIt.Next()) { |
5892 | const TopoDS_Shape& aS = aIt.Value(); |
5893 | // |
5894 | TopExp_Explorer aExp(aS, theType); |
5895 | for(; aExp.More(); aExp.Next()) { |
5896 | const TopoDS_Shape& aST = aExp.Current(); |
5897 | // |
5898 | if (aMS1.Contains(aST) && aMFence.Add(aST)) { |
5899 | theLSC.Append(aST); |
5900 | } |
5901 | } |
5902 | } |
5903 | } |
5904 | |
5905 | //======================================================================= |
5906 | //function : NbPoints |
5907 | //purpose : Defines number of sample points to get average direction of the edge |
5908 | //======================================================================= |
5909 | Standard_Integer NbPoints(const TopoDS_Edge& theEdge) |
5910 | { |
5911 | Standard_Integer aNbP; |
5912 | BRepAdaptor_Curve aBAC(theEdge); |
5913 | switch (aBAC.GetType()) { |
5914 | case GeomAbs_Line: |
5915 | aNbP = 1; |
5916 | break; |
5917 | default: |
5918 | aNbP = 11; |
5919 | } |
5920 | // |
5921 | return aNbP; |
5922 | } |
5923 | |
5924 | //======================================================================= |
5925 | //function : FindShape |
5926 | //purpose : Looking for the same sub-shape in the shape |
5927 | //======================================================================= |
5928 | Standard_Boolean FindShape(const TopoDS_Shape& theSWhat, |
5929 | const TopoDS_Shape& theSWhere, |
5930 | TopoDS_Shape& theRes) |
5931 | { |
5932 | Standard_Boolean bFound = Standard_False; |
5933 | TopAbs_ShapeEnum aType = theSWhat.ShapeType(); |
5934 | TopExp_Explorer aExp(theSWhere, aType); |
5935 | for (; aExp.More(); aExp.Next()) { |
5936 | const TopoDS_Shape& aS = aExp.Current(); |
5937 | if (aS.IsSame(theSWhat)) { |
5938 | theRes = aS; |
5939 | bFound = Standard_True; |
5940 | break; |
5941 | } |
5942 | } |
5943 | return bFound; |
5944 | } |
5945 | |
5946 | |
5947 | //======================================================================= |
5948 | //function : AppendToList |
5949 | //purpose : Add to a list only unique elements |
5950 | //======================================================================= |
5951 | void AppendToList(TopTools_ListOfShape& theList, |
5952 | const TopoDS_Shape& theShape) |
5953 | { |
5954 | TopTools_ListIteratorOfListOfShape aIt(theList); |
5955 | for (; aIt.More(); aIt.Next()) { |
5956 | const TopoDS_Shape& aS = aIt.Value(); |
5957 | if (aS.IsSame(theShape)) { |
5958 | return; |
5959 | } |
5960 | } |
5961 | theList.Append(theShape); |
5962 | } |