4e57c75e |
1 | // Created by: Peter KURNEV |
973c2be1 |
2 | // Copyright (c) 2010-2014 OPEN CASCADE SAS |
4e57c75e |
3 | // Copyright (c) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE |
4 | // Copyright (c) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, CEDRAT, |
5 | // EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS |
6 | // |
973c2be1 |
7 | // This file is part of Open CASCADE Technology software library. |
4e57c75e |
8 | // |
973c2be1 |
9 | // This library is free software; you can redistribute it and / or modify it |
10 | // under the terms of the GNU Lesser General Public version 2.1 as published |
11 | // by the Free Software Foundation, with special exception defined in the file |
12 | // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT |
13 | // distribution for complete text of the license and disclaimer of any warranty. |
4e57c75e |
14 | // |
973c2be1 |
15 | // Alternatively, this file may be used under the terms of Open CASCADE |
16 | // commercial license or contractual agreement. |
4e57c75e |
17 | |
18 | #include <BOPAlgo_Builder.hxx> |
19 | |
20 | #include <NCollection_IncAllocator.hxx> |
21 | |
22 | #include <TopAbs_State.hxx> |
23 | |
24 | #include <TopoDS.hxx> |
25 | #include <TopoDS_Iterator.hxx> |
26 | #include <TopoDS_Solid.hxx> |
27 | #include <TopoDS_Shape.hxx> |
28 | #include <TopoDS_Face.hxx> |
744511c8 |
29 | #include <TopoDS_Edge.hxx> |
4e57c75e |
30 | #include <TopoDS_Solid.hxx> |
31 | #include <TopoDS_Iterator.hxx> |
32 | #include <TopoDS_Shell.hxx> |
33 | #include <TopoDS_Compound.hxx> |
34 | |
35 | #include <TopExp.hxx> |
36 | #include <TopExp_Explorer.hxx> |
37 | |
38 | #include <BRep_Builder.hxx> |
39 | #include <BRepTools.hxx> |
40 | #include <BRepClass3d_SolidClassifier.hxx> |
41 | // |
42 | #include <BOPCol_IndexedMapOfShape.hxx> |
43 | #include <BOPCol_MapOfShape.hxx> |
44 | #include <BOPCol_IndexedDataMapOfShapeListOfShape.hxx> |
45 | #include <BOPCol_ListOfShape.hxx> |
46 | // |
47 | #include <BOPDS_DS.hxx> |
48 | #include <BOPDS_ShapeInfo.hxx> |
49 | // |
50 | #include <BOPTools.hxx> |
51 | #include <BOPTools_AlgoTools.hxx> |
52 | // |
53 | #include <BOPTools_MapOfSet.hxx> |
54 | #include <BOPTools_Set.hxx> |
55 | // |
56 | #include <BOPAlgo_BuilderSolid.hxx> |
57 | |
744511c8 |
58 | #include <BOPCol_DataMapOfIntegerShape.hxx> |
59 | #include <Bnd_Box.hxx> |
60 | #include <BRepBndLib.hxx> |
61 | |
62 | #include <NCollection_UBTreeFiller.hxx> |
63 | #include <BOPDS_BoxBndTree.hxx> |
64 | #include <BOPCol_ListOfInteger.hxx> |
65 | #include <BOPInt_Context.hxx> |
66 | |
67 | |
68 | static |
69 | Standard_Boolean IsClosedShell(const TopoDS_Shell& aSh); |
4e57c75e |
70 | |
71 | static |
72 | void OwnInternalShapes(const TopoDS_Shape& , |
73 | BOPCol_IndexedMapOfShape& ); |
74 | |
c884a268 |
75 | static |
76 | void TreatCompound(const TopoDS_Shape& theS, |
77 | BOPCol_MapOfShape& aMFence, |
78 | BOPCol_ListOfShape& theLS); |
79 | |
744511c8 |
80 | //======================================================================= |
81 | //class : BOPAlgo_ShapeBox |
82 | //purpose : Auxiliary class |
83 | //======================================================================= |
84 | class BOPAlgo_ShapeBox { |
85 | public: |
86 | BOPAlgo_ShapeBox() { |
87 | }; |
88 | // |
89 | ~BOPAlgo_ShapeBox() { |
90 | }; |
91 | // |
92 | void SetShape(const TopoDS_Shape& aS) { |
93 | myShape=aS; |
94 | }; |
95 | // |
96 | const TopoDS_Shape& Shape()const { |
97 | return myShape; |
98 | }; |
99 | // |
100 | void SetBox(const Bnd_Box& aBox) { |
101 | myBox=aBox; |
102 | }; |
103 | // |
104 | const Bnd_Box& Box()const { |
105 | return myBox; |
106 | }; |
107 | // |
108 | protected: |
109 | TopoDS_Shape myShape; |
110 | Bnd_Box myBox; |
111 | }; |
112 | // |
113 | typedef NCollection_DataMap\ |
114 | <Standard_Integer, BOPAlgo_ShapeBox, TColStd_MapIntegerHasher> \ |
115 | BOPAlgo_DataMapOfIntegerShapeBox; |
116 | // |
117 | typedef BOPAlgo_DataMapOfIntegerShapeBox::Iterator \ |
118 | BOPAlgo_DataMapIteratorOfDataMapOfIntegerShapeBox; |
119 | // |
120 | |
4e57c75e |
121 | //======================================================================= |
122 | //function : FillImagesSolids |
123 | //purpose : |
124 | //======================================================================= |
744511c8 |
125 | void BOPAlgo_Builder::FillImagesSolids() |
4e57c75e |
126 | { |
744511c8 |
127 | Standard_Boolean bHasSolids; |
128 | Standard_Integer i, aNbS; |
129 | // |
4e57c75e |
130 | myErrorStatus=0; |
131 | // |
744511c8 |
132 | bHasSolids=Standard_False; |
133 | aNbS=myDS->NbSourceShapes(); |
134 | for (i=0; i<aNbS; ++i) { |
135 | const BOPDS_ShapeInfo& aSI=myDS->ShapeInfo(i); |
136 | if (aSI.ShapeType()==TopAbs_SOLID) { |
137 | bHasSolids=!bHasSolids; |
138 | break; |
139 | } |
140 | } |
141 | // |
142 | if (!bHasSolids) { |
143 | return; |
144 | } |
145 | // |
146 | Handle(NCollection_IncAllocator) aAlr; |
4e57c75e |
147 | // |
744511c8 |
148 | aAlr=new NCollection_IncAllocator(); |
4e57c75e |
149 | // |
744511c8 |
150 | BOPCol_DataMapOfShapeListOfShape theInParts(100, aAlr); |
151 | BOPCol_DataMapOfShapeShape theDraftSolids(100, aAlr); |
152 | // |
153 | FillIn3DParts(theInParts, theDraftSolids, aAlr); |
154 | BuildSplitSolids(theInParts, theDraftSolids, aAlr); |
4e57c75e |
155 | FillInternalShapes(); |
156 | // |
157 | theInParts.Clear(); |
158 | theDraftSolids.Clear(); |
4e57c75e |
159 | } |
160 | //======================================================================= |
161 | //function : FillIn3DParts |
162 | //purpose : |
163 | //======================================================================= |
744511c8 |
164 | void BOPAlgo_Builder::FillIn3DParts(BOPCol_DataMapOfShapeListOfShape& theInParts, |
165 | BOPCol_DataMapOfShapeShape& theDraftSolids, |
166 | const BOPCol_BaseAllocator& ) |
4e57c75e |
167 | { |
744511c8 |
168 | Standard_Boolean bHasImage; |
169 | Standard_Integer i, k, aNbS, aNbLIF, nFP, aNbFP, aNbFIN, iIsIN; |
170 | TopoDS_Solid aSD; |
171 | TopoDS_Iterator aIt; |
172 | BRep_Builder aBB; |
173 | BOPCol_ListIteratorOfListOfInteger aItLI, aItLI1; |
174 | BOPCol_ListIteratorOfListOfShape aItLS; |
175 | BOPAlgo_ShapeBox aSB; |
176 | Handle(NCollection_IncAllocator) aAlr0; |
4e57c75e |
177 | // |
744511c8 |
178 | aAlr0=new NCollection_IncAllocator(); |
179 | BOPAlgo_DataMapOfIntegerShapeBox aDMISB(100, aAlr0); |
180 | BOPAlgo_DataMapIteratorOfDataMapOfIntegerShapeBox aItDMISB; |
4e57c75e |
181 | // |
744511c8 |
182 | myErrorStatus=0; |
4e57c75e |
183 | theDraftSolids.Clear(); |
184 | // |
744511c8 |
185 | // 1. aDMISB map Index/FaceBox |
186 | k=0; |
4e57c75e |
187 | aNbS=myDS->NbSourceShapes(); |
188 | for (i=0; i<aNbS; ++i) { |
189 | const BOPDS_ShapeInfo& aSI=myDS->ShapeInfo(i); |
744511c8 |
190 | if (aSI.ShapeType()!=TopAbs_FACE) { |
191 | continue; |
192 | } |
193 | // |
4e57c75e |
194 | const TopoDS_Shape& aS=aSI.Shape(); |
195 | // |
744511c8 |
196 | if (myImages.IsBound(aS)) { |
197 | const BOPCol_ListOfShape& aLS=myImages.Find(aS); |
198 | aItLS.Initialize(aLS); |
199 | for (; aItLS.More(); aItLS.Next()) { |
200 | const TopoDS_Shape& aSx=aItLS.Value(); |
201 | // |
202 | Bnd_Box aBox; |
203 | BRepBndLib::Add(aSx, aBox); |
204 | // |
205 | aSB.SetShape(aSx); |
206 | aSB.SetBox(aBox); |
207 | // |
208 | aDMISB.Bind(k, aSB); |
209 | ++k; |
4e57c75e |
210 | } |
744511c8 |
211 | } |
212 | else { |
213 | const Bnd_Box& aBox=aSI.Box(); |
4e57c75e |
214 | // |
744511c8 |
215 | aSB.SetShape(aS); |
216 | aSB.SetBox(aBox); |
4e57c75e |
217 | // |
744511c8 |
218 | aDMISB.Bind(k, aSB); |
219 | ++k; |
4e57c75e |
220 | } |
744511c8 |
221 | }//for (i=0; i<aNbS; ++i) { |
4e57c75e |
222 | // |
744511c8 |
223 | // 2. Solids |
224 | for (i=0; i<aNbS; ++i) { |
225 | const BOPDS_ShapeInfo& aSI=myDS->ShapeInfo(i); |
226 | if (aSI.ShapeType()!=TopAbs_SOLID) { |
227 | continue; |
228 | } |
229 | // |
230 | //--------------------------------------------- |
231 | Handle(NCollection_IncAllocator) aAlr1; |
72e88cf7 |
232 | // |
744511c8 |
233 | aAlr1=new NCollection_IncAllocator(); |
4e57c75e |
234 | // |
744511c8 |
235 | BOPCol_ListOfShape aLFIN(aAlr1); |
236 | BOPCol_ListOfShape aLIF(aAlr1); |
237 | BOPCol_IndexedMapOfShape aMF(100, aAlr1); |
238 | BOPCol_IndexedDataMapOfShapeListOfShape aMEF(100, aAlr1); |
4e57c75e |
239 | // |
744511c8 |
240 | BOPDS_BoxBndTreeSelector aSelector; |
241 | BOPDS_BoxBndTree aBBTree; |
242 | NCollection_UBTreeFiller <Standard_Integer, Bnd_Box> aTreeFiller(aBBTree); |
243 | Bnd_Box aBoxS; |
72e88cf7 |
244 | // |
744511c8 |
245 | const TopoDS_Shape& aS=aSI.Shape(); |
246 | const TopoDS_Solid& aSolid=(*(TopoDS_Solid*)(&aS)); |
4e57c75e |
247 | // |
744511c8 |
248 | // 2.0 Flag bHasImage |
4e57c75e |
249 | bHasImage=Standard_False; |
744511c8 |
250 | aIt.Initialize(aS); |
4e57c75e |
251 | for (; aIt.More(); aIt.Next()) { |
252 | const TopoDS_Shape& aShell=aIt.Value(); |
744511c8 |
253 | bHasImage=myImages.IsBound(aShell); |
254 | if (bHasImage){ |
255 | break; |
4e57c75e |
256 | } |
257 | } |
258 | // |
744511c8 |
259 | // 2.1 Compute Bnd_Box for the solid aS [ aBoxS ] |
260 | BuildBndBox(i, aBoxS); |
261 | //----- |
4e57c75e |
262 | // |
744511c8 |
263 | // 2.2 Build Draft Solid [aSD] |
264 | aBB.MakeSolid(aSD); |
4e57c75e |
265 | // |
744511c8 |
266 | BuildDraftSolid(aSolid, aSD, aLIF); |
267 | aNbLIF=aLIF.Extent(); |
268 | // |
269 | BOPTools::MapShapesAndAncestors(aSD, TopAbs_EDGE, TopAbs_FACE, aMEF); |
270 | // |
271 | // 2.3 Faces from aSD and own internal faces => aMF |
272 | BOPTools::MapShapes(aSD, TopAbs_FACE, aMF); |
273 | // |
274 | aItLS.Initialize(aLIF); |
275 | for (; aItLS.More(); aItLS.Next()) { |
276 | const TopoDS_Shape& aFI=aItLS.Value(); |
277 | aMF.Add(aFI); |
4e57c75e |
278 | } |
279 | // |
744511c8 |
280 | // 2.4. Prepare TreeFiller |
281 | aItDMISB.Initialize(aDMISB); |
282 | for (; aItDMISB.More(); aItDMISB.Next()) { |
283 | k=aItDMISB.Key(); |
284 | const BOPAlgo_ShapeBox& aSBk=aItDMISB.Value(); |
285 | const TopoDS_Shape& aFk=aSBk.Shape(); |
286 | if (aMF.Contains(aFk)) { |
287 | continue; |
4e57c75e |
288 | } |
744511c8 |
289 | // |
290 | const Bnd_Box& aBk=aSBk.Box(); |
291 | // |
292 | aTreeFiller.Add(k, aBk); |
4e57c75e |
293 | } |
294 | // |
744511c8 |
295 | // 2.5. Shake TreeFiller |
296 | aTreeFiller.Fill(); |
297 | // |
298 | // 2.6. Select boxes of faces that are not out of aBoxS |
299 | aSelector.Clear(); |
300 | aSelector.SetBox(aBoxS); |
301 | // |
302 | aNbFP=aBBTree.Select(aSelector); |
4e57c75e |
303 | // |
744511c8 |
304 | const BOPCol_ListOfInteger& aLIFP=aSelector.Indices(); |
305 | // |
306 | // 2.7. Collect faces that are IN aSolid [ aLFIN ] |
307 | BOPCol_ListOfShape aLFP(aAlr1); |
308 | BOPCol_ListOfShape aLCBF(aAlr1); |
309 | BOPCol_MapOfShape aMFDone(100, aAlr1); |
310 | BOPCol_IndexedMapOfShape aME(100, aAlr1); |
311 | // |
312 | BOPTools::MapShapes(aSD, TopAbs_EDGE, aME); |
313 | // |
314 | aItLI.Initialize(aLIFP); |
315 | for (; aItLI.More(); aItLI.Next()) { |
316 | nFP=aItLI.Value(); |
317 | const BOPAlgo_ShapeBox& aSBF=aDMISB.Find(nFP); |
318 | const TopoDS_Face& aFP=(*(TopoDS_Face*)&aSBF.Shape()); |
319 | if (aMFDone.Contains(aFP)) { |
320 | continue; |
4e57c75e |
321 | } |
4e57c75e |
322 | // |
744511c8 |
323 | aMFDone.Add(aFP); |
324 | // |
325 | iIsIN=BOPTools_AlgoTools::IsInternalFace(aFP, aSD, aMEF, 1.e-14, myContext); |
4e57c75e |
326 | // |
4e57c75e |
327 | aLFP.Clear(); |
328 | aLFP.Append(aFP); |
744511c8 |
329 | // |
330 | aItLI1.Initialize(aLIFP); |
331 | for (; aItLI1.More(); aItLI1.Next()) { |
332 | const TopoDS_Shape& aFx=aDMISB.Find(aItLI1.Value()).Shape(); |
333 | if (!aMFDone.Contains(aFx)) { |
334 | aLFP.Append(aFx); |
335 | } |
4e57c75e |
336 | } |
337 | // |
4e57c75e |
338 | aLCBF.Clear(); |
744511c8 |
339 | //---------------------------------------- |
72e88cf7 |
340 | { |
744511c8 |
341 | Handle(NCollection_IncAllocator) aAlr2; |
342 | aAlr2=new NCollection_IncAllocator(); |
72e88cf7 |
343 | // |
744511c8 |
344 | BOPTools_AlgoTools::MakeConnexityBlock(aLFP, aME, aLCBF, aAlr2); |
72e88cf7 |
345 | } |
744511c8 |
346 | //---------------------------------------- |
347 | aItLS.Initialize(aLCBF); |
348 | for (; aItLS.More(); aItLS.Next()) { |
349 | const TopoDS_Shape& aFx=aItLS.Value(); |
350 | aMFDone.Add(aFx); |
351 | if (iIsIN) { |
352 | aLFIN.Append(aFx); |
4e57c75e |
353 | } |
354 | } |
744511c8 |
355 | }// for (; aItLI.More(); aItLI.Next()) { |
4e57c75e |
356 | // |
744511c8 |
357 | // 2.8. Store the results in theInParts, theDraftSolids |
358 | aNbFIN=aLFIN.Extent(); |
4e57c75e |
359 | if (aNbFIN || aNbLIF) { |
744511c8 |
360 | aItLS.Initialize(aLIF); |
361 | for (; aItLS.More(); aItLS.Next()) { |
362 | const TopoDS_Shape& aFI=aItLS.Value(); |
363 | aLFIN.Append(aFI); |
4e57c75e |
364 | } |
4e57c75e |
365 | theInParts.Bind(aSolid, aLFIN); |
366 | } |
744511c8 |
367 | // |
4e57c75e |
368 | if (aNbFIN || bHasImage) { |
744511c8 |
369 | theDraftSolids.Bind(aSolid, aSD); |
4e57c75e |
370 | } |
744511c8 |
371 | //--------------------------------------------- |
372 | }// for (i=0; i<aNbS; ++i) { |
4e57c75e |
373 | } |
744511c8 |
374 | |
4e57c75e |
375 | //======================================================================= |
376 | //function : BuildDraftSolid |
377 | //purpose : |
378 | //======================================================================= |
744511c8 |
379 | void BOPAlgo_Builder::BuildDraftSolid(const TopoDS_Shape& theSolid, |
380 | TopoDS_Shape& theDraftSolid, |
381 | BOPCol_ListOfShape& theLIF) |
4e57c75e |
382 | { |
383 | myErrorStatus=0; |
384 | // |
385 | Standard_Boolean bToReverse; |
386 | Standard_Integer iFlag; |
387 | TopAbs_Orientation aOrF, aOrSh, aOrSd; |
388 | TopoDS_Iterator aIt1, aIt2; |
389 | TopoDS_Shell aShD; |
390 | TopoDS_Shape aFSDx, aFx; |
391 | BRep_Builder aBB; |
392 | BOPCol_ListIteratorOfListOfShape aItS; |
393 | // |
394 | aOrSd=theSolid.Orientation(); |
395 | theDraftSolid.Orientation(aOrSd); |
396 | // |
397 | aIt1.Initialize(theSolid); |
398 | for (; aIt1.More(); aIt1.Next()) { |
399 | const TopoDS_Shape& aSh=aIt1.Value(); |
400 | if(aSh.ShapeType()!=TopAbs_SHELL) { |
401 | continue; // mb internal edges,vertices |
402 | } |
403 | // |
404 | aOrSh=aSh.Orientation(); |
405 | aBB.MakeShell(aShD); |
406 | aShD.Orientation(aOrSh); |
407 | iFlag=0; |
408 | // |
409 | aIt2.Initialize(aSh); |
410 | for (; aIt2.More(); aIt2.Next()) { |
411 | const TopoDS_Shape& aF=aIt2.Value(); |
412 | aOrF=aF.Orientation(); |
413 | // |
414 | if (myImages.IsBound(aF)) { |
415 | const BOPCol_ListOfShape& aLSp=myImages.Find(aF); |
416 | aItS.Initialize(aLSp); |
417 | for (; aItS.More(); aItS.Next()) { |
418 | aFx=aItS.Value(); |
419 | // |
420 | if (myShapesSD.IsBound(aFx)) { |
421 | aFSDx=myShapesSD.Find(aFx); |
422 | // |
423 | if (aOrF==TopAbs_INTERNAL) { |
424 | aFSDx.Orientation(aOrF); |
425 | theLIF.Append(aFSDx); |
426 | } |
427 | else { |
428 | bToReverse=BOPTools_AlgoTools::IsSplitToReverse(aFSDx, aF, myContext); |
429 | if (bToReverse) { |
430 | aFSDx.Reverse(); |
431 | } |
432 | // |
433 | iFlag=1; |
434 | aBB.Add(aShD, aFSDx); |
435 | } |
436 | }//if (myShapesSD.IsBound(aFx)) { |
437 | else { |
438 | aFx.Orientation(aOrF); |
439 | if (aOrF==TopAbs_INTERNAL) { |
440 | theLIF.Append(aFx); |
441 | } |
442 | else{ |
443 | iFlag=1; |
444 | aBB.Add(aShD, aFx); |
445 | } |
446 | } |
447 | } |
448 | } // if (myImages.IsBound(aF)) { |
449 | // |
450 | else { |
451 | if (aOrF==TopAbs_INTERNAL) { |
452 | theLIF.Append(aF); |
453 | } |
454 | else{ |
455 | iFlag=1; |
456 | aBB.Add(aShD, aF); |
457 | } |
458 | } |
459 | } //for (; aIt2.More(); aIt2.Next()) { |
460 | // |
461 | if (iFlag) { |
462 | aBB.Add(theDraftSolid, aShD); |
463 | } |
464 | } //for (; aIt1.More(); aIt1.Next()) { |
465 | } |
466 | //======================================================================= |
467 | //function : BuildSplitSolids |
468 | //purpose : |
469 | //======================================================================= |
744511c8 |
470 | void BOPAlgo_Builder::BuildSplitSolids(BOPCol_DataMapOfShapeListOfShape& theInParts, |
471 | BOPCol_DataMapOfShapeShape& theDraftSolids, |
472 | const BOPCol_BaseAllocator& ) |
4e57c75e |
473 | { |
474 | myErrorStatus=0; |
475 | // |
476 | Standard_Boolean bFlagSD; |
477 | Standard_Integer i, aNbS, iErr, aNbSFS; |
478 | TopExp_Explorer aExp; |
479 | BOPCol_ListIteratorOfListOfShape aIt; |
480 | BOPCol_DataMapIteratorOfDataMapOfShapeShape aIt1; |
481 | // |
744511c8 |
482 | Handle(NCollection_IncAllocator) aAlr0; |
483 | aAlr0=new NCollection_IncAllocator(); |
484 | // |
485 | BOPCol_ListOfShape aSFS(aAlr0), aLSEmpty(aAlr0); |
486 | BOPCol_MapOfShape aMFence(100, aAlr0); |
487 | BOPTools_MapOfSet aMST(100, aAlr0); |
4e57c75e |
488 | // |
489 | // 0. Find same domain solids for non-interferred solids |
490 | aNbS=myDS->NbSourceShapes(); |
491 | for (i=0; i<aNbS; ++i) { |
492 | const BOPDS_ShapeInfo& aSI=myDS->ShapeInfo(i); |
493 | // |
494 | if (aSI.ShapeType()!=TopAbs_SOLID) { |
495 | continue; |
496 | } |
497 | // |
498 | const TopoDS_Shape& aS=aSI.Shape(); |
499 | if (!aMFence.Add(aS)) { |
500 | continue; |
501 | } |
502 | if(theDraftSolids.IsBound(aS)) { |
503 | continue; |
504 | } |
505 | // |
506 | BOPTools_Set aST; |
507 | // |
508 | aST.Add(aS, TopAbs_FACE); |
509 | aMST.Add(aST); |
510 | // |
511 | } //for (i=1; i<=aNbS; ++i) |
512 | // |
513 | // 1. Build solids for interferred source solids |
514 | for (i=0; i<aNbS; ++i) { |
515 | const BOPDS_ShapeInfo& aSI=myDS->ShapeInfo(i); |
516 | // |
517 | if (aSI.ShapeType()!=TopAbs_SOLID) { |
518 | continue; |
519 | } |
520 | // |
521 | const TopoDS_Shape& aS=aSI.Shape(); |
522 | if(!theDraftSolids.IsBound(aS)) { |
523 | continue; |
524 | } |
525 | const TopoDS_Shape& aSD=theDraftSolids.Find(aS); |
526 | const BOPCol_ListOfShape& aLFIN= |
527 | (theInParts.IsBound(aS)) ? theInParts.Find(aS) : aLSEmpty; |
528 | // |
529 | // 1.1 Fill Shell Faces Set |
530 | aSFS.Clear(); |
531 | aExp.Init(aSD, TopAbs_FACE); |
532 | for (; aExp.More(); aExp.Next()) { |
533 | const TopoDS_Shape& aF=aExp.Current(); |
534 | aSFS.Append(aF); |
535 | } |
536 | // |
537 | aIt.Initialize(aLFIN); |
538 | for (; aIt.More(); aIt.Next()) { |
539 | TopoDS_Shape aF=aIt.Value(); |
540 | // |
541 | aF.Orientation(TopAbs_FORWARD); |
542 | aSFS.Append(aF); |
543 | aF.Orientation(TopAbs_REVERSED); |
544 | aSFS.Append(aF); |
545 | } |
546 | // |
547 | aNbSFS=aSFS.Extent(); |
4e57c75e |
548 | // |
744511c8 |
549 | // 1.3 Build new solids |
550 | Handle(NCollection_IncAllocator) aAlr1; |
551 | aAlr1=new NCollection_IncAllocator(); |
552 | // |
553 | BOPAlgo_BuilderSolid aSB(aAlr1); |
4e57c75e |
554 | // |
555 | //aSB.SetContext(myContext); |
556 | aSB.SetShapes(aSFS); |
557 | aSB.Perform(); |
558 | iErr=aSB.ErrorStatus(); |
559 | if (iErr) { |
560 | myErrorStatus=30; // SolidBuilder failed |
561 | return; |
562 | } |
563 | // |
564 | const BOPCol_ListOfShape& aLSR=aSB.Areas(); |
565 | // |
566 | // 1.4 Collect resulting solids and theirs set of faces. |
567 | // Update Images. |
568 | if (!myImages.IsBound(aS)) { |
569 | BOPCol_ListOfShape aLSx; |
570 | // |
571 | myImages.Bind(aS, aLSx); |
572 | BOPCol_ListOfShape& aLSIm=myImages.ChangeFind(aS); |
573 | // |
574 | aIt.Initialize(aLSR); |
575 | for (; aIt.More(); aIt.Next()) { |
576 | BOPTools_Set aST; |
577 | // |
578 | const TopoDS_Shape& aSR=aIt.Value(); |
579 | aST.Add(aSR, TopAbs_FACE); |
580 | // |
581 | bFlagSD=aMST.Contains(aST); |
582 | // |
583 | const BOPTools_Set& aSTx=aMST.Added(aST); |
584 | const TopoDS_Shape& aSx=aSTx.Shape(); |
585 | aLSIm.Append(aSx); |
586 | // |
587 | if (bFlagSD) { |
588 | myShapesSD.Bind(aSR, aSx); |
589 | } |
590 | } |
591 | } |
744511c8 |
592 | }// for (i=0; i<aNbS; ++i) { |
4e57c75e |
593 | } |
594 | |
595 | //======================================================================= |
596 | //function :FillInternalShapes |
597 | //purpose : |
598 | //======================================================================= |
744511c8 |
599 | void BOPAlgo_Builder::FillInternalShapes() |
4e57c75e |
600 | { |
601 | myErrorStatus=0; |
602 | // |
603 | Standard_Integer i, j, aNbS, aNbSI, aNbSx, aNbSd; |
604 | TopAbs_ShapeEnum aType; |
605 | TopAbs_State aState; |
606 | TopoDS_Iterator aItS; |
607 | BRep_Builder aBB; |
608 | BOPCol_MapIteratorOfMapOfShape aItM; |
609 | BOPCol_ListIteratorOfListOfShape aIt, aIt1; |
610 | // |
611 | Handle(NCollection_IncAllocator) aAllocator; |
612 | //-----------------------------------------------------scope f |
613 | aAllocator=new NCollection_IncAllocator(); |
614 | // |
615 | BOPCol_IndexedDataMapOfShapeListOfShape aMSx(100, aAllocator); |
616 | BOPCol_IndexedMapOfShape aMx(100, aAllocator); |
617 | BOPCol_MapOfShape aMSI(100, aAllocator); |
618 | BOPCol_MapOfShape aMFence(100, aAllocator); |
619 | BOPCol_MapOfShape aMSOr(100, aAllocator); |
620 | BOPCol_ListOfShape aLSd(aAllocator); |
621 | BOPCol_ListOfShape aLArgs(aAllocator); |
c884a268 |
622 | BOPCol_ListOfShape aLSC(aAllocator); |
4e57c75e |
623 | // |
624 | // 1. Shapes to process |
625 | // |
626 | // 1.1 Shapes from pure arguments aMSI |
627 | // 1.1.1 vertex, edge, wire |
628 | // |
629 | aIt.Initialize(myArguments); |
630 | for (; aIt.More(); aIt.Next()) { |
631 | const TopoDS_Shape& aS=aIt.Value(); |
c884a268 |
632 | TreatCompound(aS, aMFence, aLSC); |
633 | } |
634 | aIt.Initialize(aLSC); |
635 | for (; aIt.More(); aIt.Next()) { |
636 | const TopoDS_Shape& aS=aIt.Value(); |
4e57c75e |
637 | aType=aS.ShapeType(); |
638 | if (aType==TopAbs_WIRE) { |
639 | aItS.Initialize(aS); |
640 | for(; aItS.More(); aItS.Next()) { |
641 | const TopoDS_Shape& aE=aItS.Value(); |
642 | if (aMFence.Add(aE)) { |
643 | aLArgs.Append(aE); |
644 | } |
645 | } |
646 | } |
647 | else if (aType==TopAbs_VERTEX || aType==TopAbs_EDGE){ |
648 | aLArgs.Append(aS); |
649 | } |
650 | } |
651 | aMFence.Clear(); |
652 | // |
653 | aIt.Initialize(aLArgs); |
654 | for (; aIt.More(); aIt.Next()) { |
655 | const TopoDS_Shape& aS=aIt.Value(); |
656 | aType=aS.ShapeType(); |
657 | if (aType==TopAbs_VERTEX || aType==TopAbs_EDGE ||aType==TopAbs_WIRE) { |
658 | if (aMFence.Add(aS)) { |
659 | if (myImages.IsBound(aS)) { |
660 | const BOPCol_ListOfShape &aLSp=myImages.Find(aS); |
661 | aIt1.Initialize(aLSp); |
662 | for (; aIt1.More(); aIt1.Next()) { |
663 | const TopoDS_Shape& aSp=aIt1.Value(); |
664 | aMSI.Add(aSp); |
665 | } |
666 | } |
667 | else { |
668 | aMSI.Add(aS); |
669 | } |
670 | } |
671 | } |
672 | } |
673 | |
674 | aNbSI=aMSI.Extent(); |
675 | // |
676 | // 2. Internal vertices, edges from source solids |
677 | aMFence.Clear(); |
678 | aLSd.Clear(); |
679 | // |
680 | aNbS=myDS->NbSourceShapes(); |
681 | for (i=0; i<aNbS; ++i) { |
682 | const BOPDS_ShapeInfo& aSI=myDS->ShapeInfo(i); |
683 | // |
684 | if (aSI.ShapeType()!=TopAbs_SOLID) { |
685 | continue; |
686 | } |
687 | // |
688 | const TopoDS_Shape& aS=aSI.Shape(); |
689 | // |
690 | aMx.Clear(); |
691 | OwnInternalShapes(aS, aMx); |
692 | // |
693 | aNbSx=aMx.Extent(); |
694 | for (j=1; j<=aNbSx; ++j) { |
695 | const TopoDS_Shape& aSi=aMx(j); |
696 | if (myImages.IsBound(aSi)) { |
697 | const BOPCol_ListOfShape &aLSp=myImages.Find(aSi); |
698 | aIt1.Initialize(aLSp); |
699 | for (; aIt1.More(); aIt1.Next()) { |
700 | const TopoDS_Shape& aSp=aIt1.Value(); |
701 | aMSI.Add(aSp); |
702 | } |
703 | } |
704 | else { |
705 | aMSI.Add(aSi); |
706 | } |
707 | } |
708 | // |
709 | // build aux map from splits of solids |
710 | if (myImages.IsBound(aS)) { |
711 | const BOPCol_ListOfShape &aLSp=myImages.Find(aS); |
712 | aIt.Initialize(aLSp); |
713 | for (; aIt.More(); aIt.Next()) { |
714 | const TopoDS_Shape& aSp=aIt.Value(); |
715 | if (aMFence.Add(aSp)) { |
716 | BOPTools::MapShapesAndAncestors(aSp, TopAbs_VERTEX, TopAbs_EDGE, aMSx); |
717 | BOPTools::MapShapesAndAncestors(aSp, TopAbs_VERTEX, TopAbs_FACE, aMSx); |
718 | BOPTools::MapShapesAndAncestors(aSp, TopAbs_EDGE , TopAbs_FACE, aMSx); |
719 | aLSd.Append(aSp); |
720 | } |
721 | } |
722 | } |
723 | else { |
724 | if (aMFence.Add(aS)) { |
725 | BOPTools::MapShapesAndAncestors(aS, TopAbs_VERTEX, TopAbs_EDGE, aMSx); |
726 | BOPTools::MapShapesAndAncestors(aS, TopAbs_VERTEX, TopAbs_FACE, aMSx); |
727 | BOPTools::MapShapesAndAncestors(aS, TopAbs_EDGE , TopAbs_FACE, aMSx); |
728 | aLSd.Append(aS); |
729 | aMSOr.Add(aS); |
730 | } |
731 | } |
732 | }// for (i=0; i<aNbS; ++i) { |
733 | // |
734 | aNbSd=aLSd.Extent(); |
735 | // |
736 | // 3. Some shapes of aMSI can be already tied with faces of |
737 | // split solids |
738 | aItM.Initialize(aMSI); |
739 | for (; aItM.More(); aItM.Next()) { |
740 | const TopoDS_Shape& aSI=aItM.Key(); |
741 | if (aMSx.Contains(aSI)) { |
742 | const BOPCol_ListOfShape &aLSx=aMSx.FindFromKey(aSI); |
743 | aNbSx=aLSx.Extent(); |
744 | if (aNbSx) { |
745 | aMSI.Remove(aSI); |
746 | } |
747 | } |
748 | } |
749 | // |
750 | // 4. Just check it |
751 | aNbSI=aMSI.Extent(); |
752 | if (!aNbSI) { |
753 | return; |
754 | } |
755 | // |
756 | // 5 Settle internal vertices and edges into solids |
757 | aMx.Clear(); |
758 | aIt.Initialize(aLSd); |
759 | for (; aIt.More(); aIt.Next()) { |
760 | TopoDS_Solid aSd=TopoDS::Solid(aIt.Value()); |
761 | // |
762 | aItM.Initialize(aMSI); |
763 | for (; aItM.More(); aItM.Next()) { |
764 | TopoDS_Shape aSI=aItM.Key(); |
765 | aSI.Orientation(TopAbs_INTERNAL); |
766 | // |
767 | aState=BOPTools_AlgoTools::ComputeStateByOnePoint(aSI, aSd, 1.e-11, myContext); |
768 | if (aState==TopAbs_IN) { |
769 | // |
770 | if(aMSOr.Contains(aSd)) { |
771 | // |
772 | TopoDS_Solid aSdx; |
773 | // |
774 | aBB.MakeSolid(aSdx); |
775 | aItS.Initialize(aSd); |
776 | for (; aItS.More(); aItS.Next()) { |
777 | const TopoDS_Shape& aSh=aItS.Value(); |
778 | aBB.Add(aSdx, aSh); |
779 | } |
780 | // |
781 | aBB.Add(aSdx, aSI); |
782 | // |
783 | if (myImages.IsBound(aSdx)) { |
784 | BOPCol_ListOfShape& aLS=myImages.ChangeFind(aSdx); |
785 | aLS.Append(aSdx); |
786 | } |
787 | else { |
788 | BOPCol_ListOfShape aLS; |
789 | aLS.Append(aSdx); |
790 | myImages.Bind(aSd, aLS); |
791 | } |
792 | // |
793 | aMSOr.Remove(aSd); |
794 | aSd=aSdx; |
795 | } |
796 | else { |
797 | aBB.Add(aSd, aSI); |
798 | } |
799 | // |
800 | aMSI.Remove(aSI); |
801 | } //if (aState==TopAbs_IN) { |
802 | }// for (; aItM.More(); aItM.Next()) { |
803 | }//for (; aIt1.More(); aIt1.Next()) { |
804 | // |
805 | //-----------------------------------------------------scope t |
806 | aLArgs.Clear(); |
807 | aLSd.Clear(); |
808 | aMSOr.Clear(); |
809 | aMFence.Clear(); |
810 | aMSI.Clear(); |
811 | aMx.Clear(); |
812 | aMSx.Clear(); |
813 | } |
814 | //======================================================================= |
744511c8 |
815 | //function : BuildBndBox |
816 | //purpose : |
817 | //======================================================================= |
818 | void BOPAlgo_Builder::BuildBndBox(const Standard_Integer theIndex, |
819 | Bnd_Box& aBoxS) |
820 | { |
821 | Standard_Boolean bIsOpenBox; |
822 | Standard_Integer nSh, nFc; |
823 | Standard_Real aTolS, aTolFc; |
824 | TopAbs_State aState; |
825 | BOPCol_ListIteratorOfListOfInteger aItLI, aItLI1; |
826 | // |
827 | const BOPDS_ShapeInfo& aSI=myDS->ShapeInfo(theIndex); |
828 | const TopoDS_Shape& aS=aSI.Shape(); |
829 | const TopoDS_Solid& aSolid=(*(TopoDS_Solid*)(&aS)); |
830 | // |
831 | bIsOpenBox=Standard_False; |
832 | // |
833 | aTolS=0.; |
834 | const BOPCol_ListOfInteger& aLISh=aSI.SubShapes(); |
835 | aItLI.Initialize(aLISh); |
836 | for (; aItLI.More(); aItLI.Next()) { |
837 | nSh=aItLI.Value(); |
838 | const BOPDS_ShapeInfo& aSISh=myDS->ShapeInfo(nSh); |
839 | if (aSISh.ShapeType()!=TopAbs_SHELL) { |
840 | continue; |
841 | } |
842 | // |
843 | const BOPCol_ListOfInteger& aLIFc=aSISh.SubShapes(); |
844 | aItLI1.Initialize(aLIFc); |
845 | for (; aItLI1.More(); aItLI1.Next()) { |
846 | nFc=aItLI1.Value(); |
847 | const BOPDS_ShapeInfo& aSIFc=myDS->ShapeInfo(nFc); |
848 | if (aSIFc.ShapeType()!=TopAbs_FACE) { |
849 | continue; |
850 | } |
851 | // |
852 | const Bnd_Box& aBFc=aSIFc.Box(); |
853 | aBoxS.Add(aBFc); |
854 | // |
855 | if (!bIsOpenBox) { |
856 | bIsOpenBox=(aBFc.IsOpenXmin() || aBFc.IsOpenXmax() || |
857 | aBFc.IsOpenYmin() || aBFc.IsOpenYmax() || |
858 | aBFc.IsOpenZmin() || aBFc.IsOpenZmax()); |
859 | if (bIsOpenBox) { |
860 | break; |
861 | } |
862 | } |
863 | // |
864 | const TopoDS_Face& aFc=*((TopoDS_Face*)&aSIFc.Shape()); |
865 | aTolFc=BRep_Tool::Tolerance(aFc); |
866 | if (aTolFc>aTolS) { |
867 | aTolS=aTolFc; |
868 | } |
869 | }//for (; aItLI1.More(); aItLI1.Next()) { |
870 | if (bIsOpenBox) { |
871 | break; |
872 | } |
873 | // |
874 | const TopoDS_Shell& aSh=*((TopoDS_Shell*)&aSISh.Shape()); |
875 | bIsOpenBox=IsClosedShell(aSh); |
876 | if (bIsOpenBox) { |
877 | break; |
878 | } |
879 | }//for (; aItLI.More(); aItLI.Next()) { |
880 | // |
881 | if (bIsOpenBox) { |
882 | aBoxS.SetWhole(); |
883 | } |
884 | else { |
885 | BRepClass3d_SolidClassifier& aSC=myContext->SolidClassifier(aSolid); |
886 | aSC.PerformInfinitePoint(aTolS); |
887 | aState=aSC.State(); |
888 | if (aState==TopAbs_IN) { |
889 | aBoxS.SetWhole(); |
890 | } |
891 | } |
892 | } |
893 | //======================================================================= |
4e57c75e |
894 | //function : OwnInternalShapes |
895 | //purpose : |
896 | //======================================================================= |
897 | void OwnInternalShapes(const TopoDS_Shape& theS, |
898 | BOPCol_IndexedMapOfShape& theMx) |
899 | { |
900 | TopoDS_Iterator aIt; |
901 | // |
902 | aIt.Initialize(theS); |
903 | for (; aIt.More(); aIt.Next()) { |
904 | const TopoDS_Shape& aSx=aIt.Value(); |
905 | if (aSx.ShapeType()!=TopAbs_SHELL) { |
906 | theMx.Add(aSx); |
907 | } |
908 | } |
909 | } |
744511c8 |
910 | //======================================================================= |
911 | //function : IsClosedShell |
912 | //purpose : |
913 | //======================================================================= |
914 | Standard_Boolean IsClosedShell(const TopoDS_Shell& aSh) |
915 | { |
916 | Standard_Boolean bRet; |
917 | Standard_Integer i, aNbE, aNbF; |
918 | TopAbs_Orientation aOrF; |
919 | BOPCol_IndexedDataMapOfShapeListOfShape aMEF; |
920 | BOPCol_ListIteratorOfListOfShape aItLS; |
921 | // |
922 | bRet=Standard_False; |
923 | // |
924 | BOPTools::MapShapesAndAncestors(aSh, TopAbs_EDGE, TopAbs_FACE, aMEF); |
925 | // |
926 | aNbE=aMEF.Extent(); |
927 | for (i=1; i<=aNbE; ++i) { |
928 | const TopoDS_Edge& aE=*((TopoDS_Edge*)&aMEF.FindKey(i)); |
929 | if (BRep_Tool::Degenerated(aE)) { |
930 | continue; |
931 | } |
932 | // |
933 | aNbF=0; |
934 | const BOPCol_ListOfShape& aLF=aMEF(i); |
935 | aItLS.Initialize(aLF); |
936 | for (; aItLS.More(); aItLS.Next()) { |
937 | const TopoDS_Shape& aF=aItLS.Value(); |
938 | aOrF=aF.Orientation(); |
939 | if (aOrF==TopAbs_INTERNAL || aOrF==TopAbs_EXTERNAL) { |
940 | continue; |
941 | } |
942 | ++aNbF; |
943 | } |
944 | // |
945 | if (aNbF==1) { |
946 | bRet=!bRet; // True |
947 | break; |
948 | } |
949 | } |
950 | // |
951 | return bRet; |
952 | } |
c884a268 |
953 | //======================================================================= |
954 | //function : TreatCompound |
955 | //purpose : |
956 | //======================================================================= |
957 | void TreatCompound(const TopoDS_Shape& theS, |
958 | BOPCol_MapOfShape& aMFence, |
959 | BOPCol_ListOfShape& theLS) |
960 | { |
961 | TopAbs_ShapeEnum aType; |
962 | // |
963 | aType = theS.ShapeType(); |
964 | if (aType != TopAbs_COMPOUND) { |
965 | if (aMFence.Add(theS)) { |
966 | theLS.Append(theS); |
967 | } |
968 | return; |
969 | } |
970 | // |
971 | TopoDS_Iterator aIt; |
972 | // |
973 | aIt.Initialize(theS); |
974 | for (; aIt.More(); aIt.Next()) { |
975 | const TopoDS_Shape& aS = aIt.Value(); |
976 | TreatCompound(aS, aMFence, theLS); |
977 | } |
978 | } |
744511c8 |
979 | |
4e57c75e |
980 | // |
981 | // ErrorStatus |
982 | // 30 - SolidBuilder failed |
983 | // A |