a572861ae278981d136305ee63d179ea6a9e83ca
[occt.git] / src / BOPAlgo / BOPAlgo_Builder_3.cxx
1 // Created by: Peter KURNEV
2 // Copyright (c) 2010-2014 OPEN CASCADE SAS
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 //
7 // This file is part of Open CASCADE Technology software library.
8 //
9 // This library is free software; you can redistribute it and/or modify it under
10 // the terms of the GNU Lesser General Public License 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.
14 //
15 // Alternatively, this file may be used under the terms of Open CASCADE
16 // commercial license or contractual agreement.
17 //
18 #include <BOPAlgo_Builder.hxx>
19 //
20 #include <Precision.hxx>
21 //
22 #include <NCollection_UBTreeFiller.hxx>
23 //
24 #include <Bnd_Box.hxx>
25 #include <TopAbs_State.hxx>
26 //
27 #include <TopoDS.hxx>
28 #include <TopoDS_Iterator.hxx>
29 #include <TopoDS_Solid.hxx>
30 #include <TopoDS_Shape.hxx>
31 #include <TopoDS_Face.hxx>
32 #include <TopoDS_Edge.hxx>
33 #include <TopoDS_Solid.hxx>
34 #include <TopoDS_Iterator.hxx>
35 #include <TopoDS_Shell.hxx>
36 #include <TopoDS_Compound.hxx>
37 //
38 #include <TopExp.hxx>
39 #include <TopExp_Explorer.hxx>
40 //
41 #include <BRep_Builder.hxx>
42 #include <BRepTools.hxx>
43 #include <BRepClass3d_SolidClassifier.hxx>
44 #include <BRepBndLib.hxx>
45 //
46 #include <BOPCol_IndexedMapOfShape.hxx>
47 #include <BOPCol_MapOfShape.hxx>
48 #include <BOPCol_IndexedDataMapOfShapeListOfShape.hxx>
49 #include <BOPCol_ListOfShape.hxx>
50 #include <BOPCol_BoxBndTree.hxx>
51 #include <BOPCol_ListOfInteger.hxx>
52 #include <BOPCol_DataMapOfIntegerShape.hxx>
53 #include <BOPCol_NCVector.hxx>
54 #include <BOPCol_Parallel.hxx>
55 //
56 #include <IntTools_Context.hxx>
57 //
58 #include <BOPDS_DS.hxx>
59 #include <BOPDS_ShapeInfo.hxx>
60 //
61 #include <BOPTools.hxx>
62 #include <BOPTools_AlgoTools.hxx>
63 #include <BOPTools_MapOfSet.hxx>
64 #include <BOPTools_Set.hxx>
65 //
66 #include <BOPAlgo_BuilderSolid.hxx>
67 #include <NCollection_Array1.hxx>
68
69 #include <algorithm>
70 #include <BOPAlgo_Algo.hxx>
71
72 static
73   void OwnInternalShapes(const TopoDS_Shape& ,
74                          BOPCol_IndexedMapOfShape& );
75
76 static
77   void TreatCompound(const TopoDS_Shape& theS,
78                      BOPCol_MapOfShape& aMFence,
79                      BOPCol_ListOfShape& theLS);
80
81 //=======================================================================
82 // BOPAlgo_BuilderSolid
83 //
84 typedef BOPCol_NCVector
85   <BOPAlgo_BuilderSolid> BOPAlgo_VectorOfBuilderSolid;
86 //
87 typedef BOPCol_Functor 
88   <BOPAlgo_BuilderSolid,
89   BOPAlgo_VectorOfBuilderSolid> BOPAlgo_BuilderSolidFunctor;
90 //
91 typedef BOPCol_Cnt 
92   <BOPAlgo_BuilderSolidFunctor,
93   BOPAlgo_VectorOfBuilderSolid> BOPAlgo_BuilderSolidCnt;
94 //
95 //=======================================================================
96 // class:  BOPAlgo_ShapeBox
97 //
98 //=======================================================================
99 //class     : BOPAlgo_ShapeBox
100 //purpose   : Auxiliary class
101 //=======================================================================
102 class BOPAlgo_ShapeBox {
103  public:
104   BOPAlgo_ShapeBox() {
105   };
106   //
107   ~BOPAlgo_ShapeBox() {
108   };
109   //
110   void SetShape(const TopoDS_Shape& aS) {
111     myShape=aS;
112   };
113   //
114   const TopoDS_Shape& Shape()const {
115     return myShape;
116   };
117   //
118   void SetBox(const Bnd_Box& aBox) {
119     myBox=aBox;
120   };
121   //
122   const Bnd_Box& Box()const {
123     return myBox;
124   };
125   //
126  protected:
127   TopoDS_Shape myShape;
128   Bnd_Box myBox;
129 };
130 //
131 typedef BOPCol_NCVector<BOPAlgo_ShapeBox> BOPAlgo_VectorOfShapeBox;
132 //
133 //=======================================================================
134 // class:  BOPAlgo_FillIn3DParts
135 //
136 //=======================================================================
137 //class : BOPAlgo_FillIn3DParts
138 //purpose  : 
139 //=======================================================================
140 class BOPAlgo_FillIn3DParts : public BOPAlgo_Algo  {
141  public:
142   DEFINE_STANDARD_ALLOC
143   
144   BOPAlgo_FillIn3DParts(){
145     myHasImage=Standard_False;
146     myBBTree=NULL;
147     myVSB=NULL;
148   };
149   //
150   virtual ~BOPAlgo_FillIn3DParts(){
151   };
152   //
153   void SetSolid(const TopoDS_Solid& aS) {
154     mySolid=aS;
155   };
156   //
157   const TopoDS_Solid& Solid()const {
158     return mySolid;
159   };
160   //
161   void SetDraftSolid(const TopoDS_Solid& aS) {
162     myDraftSolid=aS;
163   };
164   //
165   const TopoDS_Solid& DraftSolid()const {
166     return myDraftSolid;
167   };
168   //
169   void SetHasImage(const Standard_Boolean bFlag) {
170     myHasImage=bFlag;
171   };
172   //
173   Standard_Boolean HasImage()const {
174     return myHasImage;
175   };
176   //
177   void SetBoxS(const Bnd_Box& aBox) {
178     myBoxS=aBox;
179   };
180   //
181   const Bnd_Box& BoxS()const {
182     return myBoxS;
183   };
184   //
185   void SetLIF(const BOPCol_ListOfShape& aLIF) {
186     myLIF=aLIF;
187   };
188   //
189   const BOPCol_ListOfShape& LIF()const {
190     return myLIF;
191   };
192   //
193   void SetBBTree(const BOPCol_BoxBndTree& aBBTree) {
194     myBBTree=(BOPCol_BoxBndTree*)&aBBTree;
195   };
196   //
197   void SetVSB(const BOPAlgo_VectorOfShapeBox& aVSB) {
198     myVSB=(BOPAlgo_VectorOfShapeBox*)&aVSB;
199   };
200   //
201   //
202   void SetContext(const Handle(IntTools_Context)& aContext) {
203     myContext=aContext;
204   }
205   //
206   const Handle(IntTools_Context)& Context()const {
207     return myContext;
208   }
209   //
210   virtual void Perform();
211   //
212   
213   //
214   const BOPCol_ListOfShape& LFIN()const {
215     return myLFIN;
216   };
217   
218  protected:
219   void MapEdgesAndFaces
220     (const TopoDS_Shape& ,
221      BOPCol_IndexedDataMapOfShapeListOfShape& ,
222      const Handle(NCollection_BaseAllocator)& );
223   
224   void MakeConnexityBlock 
225     (const TopoDS_Face& ,
226      const BOPCol_IndexedMapOfShape& ,
227      const BOPCol_IndexedDataMapOfShapeListOfShape& ,
228      BOPCol_MapOfShape& ,
229      BOPCol_ListOfShape& );
230   //
231  protected:
232   TopoDS_Solid mySolid;
233   TopoDS_Solid myDraftSolid;
234   Standard_Boolean myHasImage;
235   Bnd_Box myBoxS;
236   BOPCol_ListOfShape myLIF;
237   BOPCol_ListOfShape myLFIN;
238   //
239   BOPCol_BoxBndTree* myBBTree;
240   BOPAlgo_VectorOfShapeBox* myVSB;
241   //
242   TopoDS_Iterator myItF;
243   TopoDS_Iterator myItW;
244   
245   Handle(IntTools_Context) myContext;
246 };
247
248 //=======================================================================
249 //function : BOPAlgo_FillIn3DParts::Perform
250 //purpose  : 
251 //=======================================================================
252 void BOPAlgo_FillIn3DParts::Perform() 
253 {
254   Handle(NCollection_BaseAllocator) aAlr1;
255   BOPAlgo_Algo::UserBreak();
256   //  
257   Standard_Integer aNbFP, k, nFP, iIsIN;
258   Standard_Real aTolPC;
259   BOPCol_ListIteratorOfListOfInteger aItLI;
260   BOPCol_ListIteratorOfListOfShape aItLS;
261   BOPCol_BoxBndTreeSelector aSelector; 
262   //
263   aAlr1=
264     NCollection_BaseAllocator::CommonBaseAllocator();
265   //
266   BOPCol_ListOfShape aLCBF(aAlr1);
267   BOPCol_MapOfShape aMFDone(100, aAlr1);
268   BOPCol_IndexedMapOfShape aME(100, aAlr1);
269   BOPCol_IndexedMapOfShape aMF(100, aAlr1);
270   BOPCol_IndexedDataMapOfShapeListOfShape aMEFP(100, aAlr1);
271   BOPCol_IndexedDataMapOfShapeListOfShape aMEF(100, aAlr1);
272   //
273   aTolPC=Precision::Confusion();
274   myLFIN.Clear();
275   BOPAlgo_VectorOfShapeBox& aVSB=*myVSB;
276   //
277   // 1. aMEF - EF map for myDraftSolid
278   BOPTools::MapShapesAndAncestors(myDraftSolid, 
279                                   TopAbs_EDGE, 
280                                   TopAbs_FACE, 
281                                   aMEF); 
282   
283   //
284   // 2. Faces from myDraftSolid and its own internal faces => aMF 
285   BOPTools::MapShapes(myDraftSolid, TopAbs_FACE, aMF);
286   aItLS.Initialize(myLIF);
287   for (; aItLS.More(); aItLS.Next()) {
288     const TopoDS_Shape& aFI=aItLS.Value();
289     aMF.Add(aFI);
290   }
291   // aME - Edges from DraftSolid [i.e. edges to stop]
292   BOPTools::MapShapes(myDraftSolid, TopAbs_EDGE, aME);
293   //
294   // 3. Select boxes of faces that are not out of aBoxS
295   aSelector.Clear();
296   aSelector.SetBox(myBoxS);
297   //
298   aNbFP=myBBTree->Select(aSelector);
299   const BOPCol_ListOfInteger& aLIFPx=aSelector.Indices();
300   //
301   // 4. aIVec, aLIFP -  faces to process
302   BOPCol_ListOfInteger aLIFP(aAlr1); 
303   BOPCol_NCVector<Standard_Integer> aIVec(256, aAlr1);
304   //
305   k=0;
306   aItLI.Initialize(aLIFPx);
307   for (; aItLI.More(); aItLI.Next()) {
308     nFP=aItLI.Value();
309     const TopoDS_Shape& aFP=aVSB(nFP).Shape();
310     if (!aMF.Contains(aFP)) {
311       MapEdgesAndFaces(aFP, aMEFP, aAlr1);
312       aLIFP.Append(nFP);
313       aIVec.Append1()=nFP;
314       ++k;
315     }
316   }
317   aNbFP=k;
318   //
319   // sort indices
320   std::sort(aIVec.begin(), aIVec.end());
321   //
322   // 5. Collect faces that are IN mySolid [ myLFIN ]
323   for (k=0; k<aNbFP; ++k) {
324     nFP = aIVec(k);
325     const BOPAlgo_ShapeBox& aSBF=aVSB(nFP);
326     const TopoDS_Face& aFP=(*(TopoDS_Face*)&aSBF.Shape());
327     //
328     if (!aMFDone.Add(aFP)) {
329       continue;
330     }
331     //
332     iIsIN=BOPTools_AlgoTools::IsInternalFace
333       (aFP, myDraftSolid, aMEF, aTolPC, myContext);
334     //
335     // Make connexity blocks of faces, avoiding passing through the
336     // borders of the solid.
337     // It helps to reduce significantly the number of classified faces.
338     aLCBF.Clear();
339     MakeConnexityBlock(aFP, aME, aMEFP, aMFDone, aLCBF);
340     //
341     if (iIsIN) {
342       aItLS.Initialize(aLCBF);
343       for (; aItLS.More(); aItLS.Next())
344         myLFIN.Append(aItLS.Value());
345     }
346   } // for (k=0; k<aNbFP; ++k) {
347 }
348 //=======================================================================
349 // function: MapEdgesAndFaces
350 // purpose: 
351 //=======================================================================
352 void BOPAlgo_FillIn3DParts::MapEdgesAndFaces
353   (const TopoDS_Shape& aF,
354    BOPCol_IndexedDataMapOfShapeListOfShape& aMEF,
355    const Handle(NCollection_BaseAllocator)& theAllocator)
356 {
357   myItF.Initialize(aF);
358   for (; myItF.More(); myItF.Next()) {
359     const TopoDS_Shape& aW=myItF.Value();
360     if (aW.ShapeType()!=TopAbs_WIRE) {
361       continue;
362     }
363     //
364     myItW.Initialize(aW);
365     for (; myItW.More(); myItW.Next()) {
366       const TopoDS_Shape& aE=myItW.Value();
367       //
368       BOPCol_ListOfShape* pLF = aMEF.ChangeSeek(aE);
369       if (!pLF)
370         pLF = &aMEF(aMEF.Add(aE, BOPCol_ListOfShape(theAllocator)));
371       pLF->Append(aF);
372     }
373   }
374 }
375 //=======================================================================
376 // function: MakeConnexityBlock
377 // purpose: 
378 //=======================================================================
379 void BOPAlgo_FillIn3DParts::MakeConnexityBlock
380   (const TopoDS_Face& theFStart,
381    const BOPCol_IndexedMapOfShape& theMEAvoid,
382    const BOPCol_IndexedDataMapOfShapeListOfShape& theMEF,
383    BOPCol_MapOfShape& theMFDone,
384    BOPCol_ListOfShape& theLCB)
385 {
386   // Add start element
387   theLCB.Append(theFStart);
388
389   BOPCol_ListIteratorOfListOfShape aItCB(theLCB);
390   for (; aItCB.More(); aItCB.Next())
391   {
392     const TopoDS_Shape& aF = aItCB.Value();
393     myItF.Initialize(aF);
394     for (; myItF.More(); myItF.Next())
395     {
396       const TopoDS_Shape& aW = myItF.Value();
397       if (aW.ShapeType() != TopAbs_WIRE)
398         continue;
399
400       myItW.Initialize(aW);
401       for (; myItW.More(); myItW.Next())
402       {
403         const TopoDS_Shape& aE = myItW.Value();
404         if (theMEAvoid.Contains(aE))
405           continue;
406
407         const BOPCol_ListOfShape& aLF = theMEF.FindFromKey(aE);
408         BOPCol_ListIteratorOfListOfShape aItLF(aLF);
409         for (; aItLF.More(); aItLF.Next())
410         {
411           const TopoDS_Shape& aFx = aItLF.Value();
412           if (!aFx.IsSame(aF) && theMFDone.Add(aFx))
413             theLCB.Append(aFx);
414         }
415       }
416     }
417   }
418 }
419 //
420 typedef BOPCol_NCVector<BOPAlgo_FillIn3DParts> \
421   BOPAlgo_VectorOfFillIn3DParts;
422 //
423 typedef BOPCol_ContextFunctor 
424   <BOPAlgo_FillIn3DParts,
425   BOPAlgo_VectorOfFillIn3DParts,
426   Handle(IntTools_Context), 
427   IntTools_Context> BOPCol_FillIn3DPartsFunctor;
428 //
429 typedef BOPCol_ContextCnt 
430   <BOPCol_FillIn3DPartsFunctor,
431   BOPAlgo_VectorOfFillIn3DParts,
432   Handle(IntTools_Context)> BOPAlgo_FillIn3DPartsCnt;
433 //
434 //=======================================================================
435 // class:  BOPAlgo_Builder
436 //
437 //=======================================================================
438 //function : FillImagesSolids
439 //purpose  : 
440 //=======================================================================
441 void BOPAlgo_Builder::FillImagesSolids()
442 {
443   Standard_Boolean bHasSolids;
444   Standard_Integer i, aNbS;
445   //
446   bHasSolids=Standard_False;
447   aNbS=myDS->NbSourceShapes();
448   for (i=0; i<aNbS; ++i) {
449     const BOPDS_ShapeInfo& aSI=myDS->ShapeInfo(i);
450     if (aSI.ShapeType()==TopAbs_SOLID) {
451       bHasSolids=!bHasSolids;
452       break;
453     }
454   }
455   //
456   if (!bHasSolids) {
457     return;
458   }
459   // 
460   Handle(NCollection_BaseAllocator) aAlr;
461   //
462   aAlr=NCollection_BaseAllocator::CommonBaseAllocator();
463   //
464   BOPCol_DataMapOfShapeListOfShape theInParts(100, aAlr);
465   BOPCol_DataMapOfShapeShape theDraftSolids(100, aAlr);
466   //
467   FillIn3DParts(theInParts, theDraftSolids, aAlr); 
468   BuildSplitSolids(theInParts, theDraftSolids, aAlr);
469   FillInternalShapes();
470   //
471   theInParts.Clear();
472   theDraftSolids.Clear();
473 }
474 //=======================================================================
475 //function : FillIn3DParts
476 //purpose  : 
477 //=======================================================================
478 void BOPAlgo_Builder::FillIn3DParts
479   (BOPCol_DataMapOfShapeListOfShape& theInParts,
480    BOPCol_DataMapOfShapeShape& theDraftSolids,
481    const BOPCol_BaseAllocator& )
482 {
483   Standard_Boolean bHasImage;
484   Standard_Integer i, k, aNbS, aNbLIF, aNbFIN, aNbVSB, aNbVFIP;
485   Handle(NCollection_BaseAllocator) aAlr0;
486   TopoDS_Solid aSD;
487   TopoDS_Iterator aIt;
488   BRep_Builder aBB; 
489   //
490   BOPCol_ListIteratorOfListOfInteger aItLI, aItLI1;
491   BOPCol_ListIteratorOfListOfShape aItLS;
492   //
493   aAlr0=
494     NCollection_BaseAllocator::CommonBaseAllocator();
495   //
496   BOPCol_MapOfShape aMFence(100, aAlr0);
497   BOPAlgo_VectorOfShapeBox aVSB(256, aAlr0);
498   //
499   theDraftSolids.Clear();
500   //
501   // 1. aVSB vector Index/FaceBox 
502   aNbS=myDS->NbSourceShapes();
503   for (i=0; i<aNbS; ++i) {
504     const BOPDS_ShapeInfo& aSI=myDS->ShapeInfo(i);
505     if (aSI.ShapeType()!=TopAbs_FACE) {
506       continue;
507     }
508     //
509     const TopoDS_Shape& aS=aSI.Shape();
510     //
511     if (myImages.IsBound(aS)) {
512       const BOPCol_ListOfShape& aLS=myImages.Find(aS);
513       aItLS.Initialize(aLS);
514       for (; aItLS.More(); aItLS.Next()) {
515         const TopoDS_Shape& aSx=aItLS.Value();
516         if (!aMFence.Add(aSx)) {
517           continue;
518         }
519         Bnd_Box aBox;
520         BRepBndLib::Add(aSx, aBox);
521         aBox.SetGap(aBox.GetGap() + Precision::Confusion());
522         //
523         BOPAlgo_ShapeBox& aSB=aVSB.Append1();
524         aSB.SetShape(aSx);
525         aSB.SetBox(aBox);
526       }
527     }
528     else {
529       const Bnd_Box& aBox=aSI.Box();
530       //
531       BOPAlgo_ShapeBox& aSB=aVSB.Append1();
532       aSB.SetShape(aS);
533       aSB.SetBox(aBox);
534     }
535   }//for (i=0; i<aNbS; ++i) {
536   aMFence.Clear();
537   //
538   // 1.2. Prepare TreeFiller
539   BOPCol_BoxBndTree aBBTree;
540   NCollection_UBTreeFiller <Standard_Integer, Bnd_Box> 
541     aTreeFiller(aBBTree);
542   //
543   aNbVSB=aVSB.Extent();
544   for (k=0; k<aNbVSB; ++k) {
545     const BOPAlgo_ShapeBox& aSBk=aVSB(k);
546     const Bnd_Box& aBk=aSBk.Box();
547     //
548     aTreeFiller.Add(k, aBk);
549   }
550   //
551   // 1.3. Shake TreeFiller
552   aTreeFiller.Fill();
553   //
554   //---------------------------------------------
555   // 2. Solids
556   BOPAlgo_VectorOfFillIn3DParts aVFIP;
557   //
558   for (i=0; i<aNbS; ++i) {
559     BOPDS_ShapeInfo& aSI=myDS->ChangeShapeInfo(i);
560     if (aSI.ShapeType()!=TopAbs_SOLID) {
561       continue;
562     }
563     //
564     const TopoDS_Shape& aS=aSI.Shape();
565     const TopoDS_Solid& aSolid=(*(TopoDS_Solid*)(&aS));
566     //
567     // 2.0 Flag bHasImage
568     bHasImage=Standard_False;
569     aIt.Initialize(aS);
570     for (; aIt.More(); aIt.Next()) {
571       const TopoDS_Shape& aShell=aIt.Value();
572       bHasImage=myImages.IsBound(aShell);
573       if (bHasImage){
574         break;
575       }
576     }
577     //
578     // 2.1 Bounding box for the solid aS  [ aBoxS ]
579     Bnd_Box& aBoxS = aSI.ChangeBox();
580     if (aBoxS.IsVoid())
581       myDS->BuildBndBoxSolid(i, aBoxS, myCheckInverted);
582     //
583     // 2.2 Build Draft Solid [aSD]
584     BOPCol_ListOfShape aLIF;
585     //
586     aBB.MakeSolid(aSD);
587     BuildDraftSolid(aSolid, aSD, aLIF);
588     //
589     BOPAlgo_FillIn3DParts& aFIP=aVFIP.Append1();
590     //
591     aFIP.SetSolid(aSolid);
592     aFIP.SetDraftSolid(aSD);
593     aFIP.SetHasImage(bHasImage);
594     aFIP.SetBoxS(aBoxS);
595     aFIP.SetLIF(aLIF);
596     aFIP.SetBBTree(aBBTree);
597     aFIP.SetVSB(aVSB);
598   }//for (i=0; i<aNbS; ++i) {
599   //
600   aNbVFIP=aVFIP.Extent();
601   //================================================================
602   BOPAlgo_FillIn3DPartsCnt::Perform(myRunParallel, aVFIP, myContext);
603   //================================================================
604   for (k=0; k<aNbVFIP; ++k) {
605     BOPAlgo_FillIn3DParts& aFIP=aVFIP(k);
606     bHasImage=aFIP.HasImage();
607     const TopoDS_Solid& aSolid=aFIP.Solid();
608     const TopoDS_Solid& aSDraft =aFIP.DraftSolid();
609     const BOPCol_ListOfShape& aLFIN=aFIP.LFIN();
610     const BOPCol_ListOfShape& aLIF=aFIP.LIF();
611     //
612     aNbLIF=aLIF.Extent();
613     //
614     // Store the results in theInParts, theDraftSolids
615     BOPCol_ListOfShape aLFINx;
616     //
617     aNbFIN=aLFIN.Extent();
618     if (aNbFIN || aNbLIF) {
619       aItLS.Initialize(aLFIN);
620       for (; aItLS.More(); aItLS.Next()) {
621         const TopoDS_Shape& aFI=aItLS.Value();
622         aLFINx.Append(aFI);
623       }
624       aItLS.Initialize(aLIF);
625       for (; aItLS.More(); aItLS.Next()) {
626         const TopoDS_Shape& aFI=aItLS.Value();
627         aLFINx.Append(aFI);
628       }
629       theInParts.Bind(aSolid, aLFINx);
630     }
631     //
632     if (aNbFIN || bHasImage) {
633       theDraftSolids.Bind(aSolid, aSDraft);
634     }
635   }
636 }
637 //=======================================================================
638 //function : BuildDraftSolid
639 //purpose  : 
640 //=======================================================================
641 void BOPAlgo_Builder::BuildDraftSolid(const TopoDS_Shape& theSolid,
642                                       TopoDS_Shape& theDraftSolid,
643                                       BOPCol_ListOfShape& theLIF)
644 {
645   Standard_Boolean bToReverse;
646   Standard_Integer iFlag;
647   TopAbs_Orientation aOrF, aOrSh, aOrSd;
648   TopoDS_Iterator aIt1, aIt2;
649   TopoDS_Shell aShD;
650   TopoDS_Shape aFSDx, aFx;
651   BRep_Builder aBB;
652   BOPCol_ListIteratorOfListOfShape aItS; 
653   //
654   aOrSd=theSolid.Orientation();
655   theDraftSolid.Orientation(aOrSd);
656   //
657   aIt1.Initialize(theSolid);
658   for (; aIt1.More(); aIt1.Next()) {
659     const TopoDS_Shape& aSh=aIt1.Value();
660     if(aSh.ShapeType()!=TopAbs_SHELL) {
661       continue; // mb internal edges,vertices
662     }
663     //
664     aOrSh=aSh.Orientation();
665     aBB.MakeShell(aShD);
666     aShD.Orientation(aOrSh);
667     iFlag=0;
668     //
669     aIt2.Initialize(aSh);
670     for (; aIt2.More(); aIt2.Next()) {
671       const TopoDS_Shape& aF=aIt2.Value();
672       aOrF=aF.Orientation();
673       //
674       if (myImages.IsBound(aF)) {
675         const BOPCol_ListOfShape& aLSp=myImages.Find(aF);
676         aItS.Initialize(aLSp);
677         for (; aItS.More(); aItS.Next()) {
678           aFx=aItS.Value();
679           //
680           if (myShapesSD.IsBound(aFx)) {
681             aFSDx=myShapesSD.Find(aFx);
682             //
683             if (aOrF==TopAbs_INTERNAL) {
684               aFSDx.Orientation(aOrF);
685               theLIF.Append(aFSDx);
686             }
687             else {
688               bToReverse=BOPTools_AlgoTools::IsSplitToReverse
689                 (aFSDx, aF, myContext); 
690               if (bToReverse) {
691                 aFSDx.Reverse();
692               }
693               //
694               iFlag=1;
695               aBB.Add(aShD, aFSDx);
696             }
697           }//if (myShapesSD.IsBound(aFx)) {
698           else {
699             aFx.Orientation(aOrF);
700             if (aOrF==TopAbs_INTERNAL) {
701               theLIF.Append(aFx);
702             }
703             else{
704               iFlag=1;
705               aBB.Add(aShD, aFx);
706             }
707           }
708         }
709       } // if (myImages.IsBound(aF)) { 
710       //
711       else {
712         if (aOrF==TopAbs_INTERNAL) {
713           theLIF.Append(aF);
714         }
715         else{
716           iFlag=1;
717           aBB.Add(aShD, aF);
718         }
719       }
720     } //for (; aIt2.More(); aIt2.Next()) {
721     //
722     if (iFlag) {
723       aShD.Closed (BRep_Tool::IsClosed (aShD));
724       aBB.Add(theDraftSolid, aShD);
725     }
726   } //for (; aIt1.More(); aIt1.Next()) {
727 }
728 //=======================================================================
729 //function : BuildSplitSolids
730 //purpose  : 
731 //=======================================================================
732 void BOPAlgo_Builder::BuildSplitSolids
733   (BOPCol_DataMapOfShapeListOfShape& theInParts,
734    BOPCol_DataMapOfShapeShape& theDraftSolids,
735    const BOPCol_BaseAllocator&  )
736 {
737   Standard_Boolean bFlagSD;
738   Standard_Integer i, aNbS;
739   TopExp_Explorer aExp;
740   BOPCol_ListIteratorOfListOfShape aIt;
741   //
742   Handle(NCollection_BaseAllocator) aAlr0;
743   aAlr0=NCollection_BaseAllocator::CommonBaseAllocator();
744   //
745   BOPCol_ListOfShape aSFS(aAlr0), aLSEmpty(aAlr0);
746   BOPCol_MapOfShape aMFence(100, aAlr0);
747   BOPTools_MapOfSet aMST(100, aAlr0);
748   BOPAlgo_VectorOfBuilderSolid aVBS;
749   //
750   // 0. Find same domain solids for non-interferred solids
751   aNbS=myDS->NbSourceShapes();
752   for (i=0; i<aNbS; ++i) {
753     const BOPDS_ShapeInfo& aSI=myDS->ShapeInfo(i);
754     //
755     if (aSI.ShapeType()!=TopAbs_SOLID) {
756       continue;
757     }
758     //
759     const TopoDS_Shape& aS=aSI.Shape();
760     if (!aMFence.Add(aS)) {
761       continue;
762     }
763     if(theDraftSolids.IsBound(aS)) {
764       continue;
765     }
766     //
767     BOPTools_Set aST;
768     //
769     aST.Add(aS, TopAbs_FACE);
770     aMST.Add(aST);
771     //
772   } //for (i=1; i<=aNbS; ++i) 
773   //
774   // Build temporary map of solids images to avoid rebuilding
775   // of the solids without internal faces
776   BOPCol_IndexedDataMapOfShapeListOfShape aSolidsIm;
777   // 1. Build solids for interfered source solids
778   for (i = 0; i < aNbS; ++i) {
779     const BOPDS_ShapeInfo& aSI = myDS->ShapeInfo(i);
780     if (aSI.ShapeType() != TopAbs_SOLID)
781       continue;
782
783     const TopoDS_Shape& aS = aSI.Shape();
784     const TopoDS_Solid& aSolid=(*(TopoDS_Solid*)(&aS));
785     if (!theDraftSolids.IsBound(aS))
786       continue;
787
788     const TopoDS_Shape& aSD = theDraftSolids.Find(aS);
789     const BOPCol_ListOfShape* pLFIN = theInParts.Seek(aS);
790     if (!pLFIN)
791     {
792       aSolidsIm(aSolidsIm.Add(aS, BOPCol_ListOfShape())).Append(aSD);
793       continue;
794     }
795
796     aSFS.Clear();
797     //
798     // 1.1 Fill Shell Faces Set
799     aExp.Init(aSD, TopAbs_FACE);
800     for (; aExp.More(); aExp.Next()) {
801       const TopoDS_Shape& aF = aExp.Current();
802       aSFS.Append(aF);
803     }
804     //
805     // 1.2 Fill internal faces
806     aIt.Initialize(*pLFIN);
807     for (; aIt.More(); aIt.Next()) {
808       TopoDS_Shape aF = aIt.Value();
809       //
810       aF.Orientation(TopAbs_FORWARD);
811       aSFS.Append(aF);
812       aF.Orientation(TopAbs_REVERSED);
813       aSFS.Append(aF);
814     }
815     //
816     // 1.3 Build new solids
817     BOPAlgo_BuilderSolid& aBS=aVBS.Append1();
818     aBS.SetSolid(aSolid);
819     aBS.SetShapes(aSFS);
820     aBS.SetRunParallel(myRunParallel);
821     aBS.SetProgressIndicator(myProgressIndicator);
822   }//for (i=0; i<aNbS; ++i) {
823   //
824   Standard_Integer k, aNbBS;
825   //
826   aNbBS=aVBS.Extent();
827   //
828   //===================================================
829   BOPAlgo_BuilderSolidCnt::Perform(myRunParallel, aVBS);
830   //===================================================
831   //
832   for (k = 0; k < aNbBS; ++k)
833   {
834     BOPAlgo_BuilderSolid& aBS = aVBS(k);
835     aSolidsIm.Add(aBS.Solid(), aBS.Areas());
836   }
837   //
838   // Add new solids to images map
839   aNbBS = aSolidsIm.Extent();
840   for (k = 1; k <= aNbBS; ++k)
841   {
842     const TopoDS_Shape& aS = aSolidsIm.FindKey(k);
843     const BOPCol_ListOfShape& aLSR = aSolidsIm(k);
844     //
845     if (!myImages.IsBound(aS)) {
846       BOPCol_ListOfShape* pLSx = myImages.Bound(aS, BOPCol_ListOfShape());
847       //
848       aIt.Initialize(aLSR);
849       for (; aIt.More(); aIt.Next()) {
850         BOPTools_Set aST;
851         //
852         const TopoDS_Shape& aSR=aIt.Value();
853         aST.Add(aSR, TopAbs_FACE);
854         //
855         bFlagSD=aMST.Contains(aST);
856         //
857         const BOPTools_Set& aSTx=aMST.Added(aST);
858         const TopoDS_Shape& aSx=aSTx.Shape();
859         pLSx->Append(aSx);
860         //
861         BOPCol_ListOfShape* pLOr = myOrigins.ChangeSeek(aSx);
862         if (!pLOr) {
863           pLOr = myOrigins.Bound(aSx, BOPCol_ListOfShape());
864         }
865         pLOr->Append(aS);
866         //
867         if (bFlagSD) {
868           myShapesSD.Bind(aSR, aSx);
869         }
870       }
871     }
872   }
873 }
874 //=======================================================================
875 //function :FillInternalShapes 
876 //purpose  : 
877 //=======================================================================
878 void BOPAlgo_Builder::FillInternalShapes()
879 {
880   Standard_Integer i, j,  aNbS, aNbSI, aNbSx;
881   TopAbs_ShapeEnum aType;
882   TopAbs_State aState; 
883   TopoDS_Iterator aItS;
884   BRep_Builder aBB;
885   BOPCol_ListIteratorOfListOfShape aIt, aIt1;
886   //
887   Handle(NCollection_BaseAllocator) aAllocator;
888   //-----------------------------------------------------scope f
889   aAllocator=NCollection_BaseAllocator::CommonBaseAllocator();
890   //
891   BOPCol_IndexedDataMapOfShapeListOfShape aMSx(100, aAllocator);
892   BOPCol_IndexedMapOfShape aMx(100, aAllocator);
893   BOPCol_IndexedMapOfShape aMSI(100, aAllocator);
894   BOPCol_MapOfShape aMFence(100, aAllocator);
895   BOPCol_MapOfShape aMSOr(100, aAllocator);
896   BOPCol_ListOfShape aLSd(aAllocator);
897   BOPCol_ListOfShape aLArgs(aAllocator);
898   BOPCol_ListOfShape aLSC(aAllocator);
899   BOPCol_ListOfShape aLSI(aAllocator);
900   //
901   // 1. Shapes to process
902   //
903   // 1.1 Shapes from pure arguments aMSI 
904   // 1.1.1 vertex, edge, wire
905   //
906   const BOPCol_ListOfShape& aArguments=myDS->Arguments();
907   aIt.Initialize(aArguments);
908   for (; aIt.More(); aIt.Next()) {
909     const TopoDS_Shape& aS=aIt.Value();
910     TreatCompound(aS, aMFence, aLSC);
911   }
912   aIt.Initialize(aLSC);
913   for (; aIt.More(); aIt.Next()) {
914     const TopoDS_Shape& aS=aIt.Value();
915     aType=aS.ShapeType();
916     if (aType==TopAbs_WIRE) {
917       aItS.Initialize(aS);
918       for(; aItS.More(); aItS.Next()) {
919         const TopoDS_Shape& aE=aItS.Value();
920         if (aMFence.Add(aE)) {
921           aLArgs.Append(aE);
922         }
923       }
924     }
925     else if (aType==TopAbs_VERTEX || aType==TopAbs_EDGE){
926       aLArgs.Append(aS);
927     } 
928   }
929   aMFence.Clear();
930   //
931   aIt.Initialize(aLArgs);
932   for (; aIt.More(); aIt.Next()) {
933     const TopoDS_Shape& aS=aIt.Value();
934     aType=aS.ShapeType();
935     if (aType==TopAbs_VERTEX || 
936         aType==TopAbs_EDGE ||
937         aType==TopAbs_WIRE) {
938       if (aMFence.Add(aS)) {
939         if (myImages.IsBound(aS)) {
940           const BOPCol_ListOfShape &aLSp=myImages.Find(aS);
941           aIt1.Initialize(aLSp);
942           for (; aIt1.More(); aIt1.Next()) {
943             const TopoDS_Shape& aSp=aIt1.Value();
944             aMSI.Add(aSp);
945           }
946         }
947         else {
948           aMSI.Add(aS);
949         }
950       }
951     }
952   }
953   
954   aNbSI=aMSI.Extent();
955   //
956   // 2. Internal vertices, edges from source solids
957   aMFence.Clear();
958   aLSd.Clear();
959   //
960   aNbS=myDS->NbSourceShapes();
961   for (i=0; i<aNbS; ++i) {
962     const BOPDS_ShapeInfo& aSI=myDS->ShapeInfo(i);
963     //
964     if (aSI.ShapeType()!=TopAbs_SOLID) {
965       continue;
966     }
967     //
968     UserBreak();
969     //
970     const TopoDS_Shape& aS=aSI.Shape();
971     //
972     aMx.Clear();
973     OwnInternalShapes(aS, aMx);
974     //
975     aNbSx=aMx.Extent();
976     for (j=1; j<=aNbSx; ++j) {
977       const TopoDS_Shape& aSi=aMx(j);
978       if (myImages.IsBound(aSi)) {
979         const BOPCol_ListOfShape &aLSp=myImages.Find(aSi);
980         aIt1.Initialize(aLSp);
981         for (; aIt1.More(); aIt1.Next()) {
982           const TopoDS_Shape& aSp=aIt1.Value();
983           aMSI.Add(aSp);
984         }
985       }
986       else {
987         aMSI.Add(aSi);
988       }
989     }
990     //
991     // build aux map from splits of solids
992     if (myImages.IsBound(aS)) {
993       const BOPCol_ListOfShape &aLSp=myImages.Find(aS);
994       aIt.Initialize(aLSp);
995       for (; aIt.More(); aIt.Next()) {
996         const TopoDS_Shape& aSp=aIt.Value();
997         if (aMFence.Add(aSp)) { 
998           BOPTools::MapShapesAndAncestors(aSp, TopAbs_VERTEX, TopAbs_EDGE, aMSx);
999           BOPTools::MapShapesAndAncestors(aSp, TopAbs_VERTEX, TopAbs_FACE, aMSx);
1000           BOPTools::MapShapesAndAncestors(aSp, TopAbs_EDGE  , TopAbs_FACE, aMSx);
1001           aLSd.Append(aSp);
1002         }
1003       }
1004     }
1005     else {
1006       if (aMFence.Add(aS)) {
1007         BOPTools::MapShapesAndAncestors(aS, TopAbs_VERTEX, TopAbs_EDGE, aMSx);
1008         BOPTools::MapShapesAndAncestors(aS, TopAbs_VERTEX, TopAbs_FACE, aMSx);
1009         BOPTools::MapShapesAndAncestors(aS, TopAbs_EDGE  , TopAbs_FACE, aMSx);
1010         aLSd.Append(aS);
1011         aMSOr.Add(aS); 
1012       }
1013     }
1014   }// for (i=0; i<aNbS; ++i) {
1015   //
1016   // 3. Some shapes of aMSI can be already tied with faces of 
1017   //    split solids
1018   aNbSI = aMSI.Extent();
1019   for (i = 1; i <= aNbSI; ++i) {
1020     const TopoDS_Shape& aSI = aMSI(i);
1021     if (aMSx.Contains(aSI)) {
1022       const BOPCol_ListOfShape &aLSx=aMSx.FindFromKey(aSI);
1023       aNbSx = aLSx.Extent();
1024       if (!aNbSx) {
1025         aLSI.Append(aSI);
1026       }
1027     }
1028     else {
1029       aLSI.Append(aSI);
1030     }
1031   }
1032   //
1033   // 4. Just check it
1034   aNbSI = aLSI.Extent();
1035   if (!aNbSI) {
1036     return;
1037   }
1038   //
1039   // 5 Settle internal vertices and edges into solids
1040   aMx.Clear();
1041   aIt.Initialize(aLSd);
1042   for (; aIt.More(); aIt.Next()) {
1043     TopoDS_Solid aSd=TopoDS::Solid(aIt.Value());
1044     //
1045     aIt1.Initialize(aLSI);
1046     for (; aIt1.More();) {
1047       TopoDS_Shape aSI = aIt1.Value();
1048       aSI.Orientation(TopAbs_INTERNAL);
1049       //
1050       aState=BOPTools_AlgoTools::ComputeStateByOnePoint
1051         (aSI, aSd, 1.e-11, myContext);
1052       //
1053       if (aState != TopAbs_IN) {
1054         aIt1.Next();
1055         continue;
1056       }
1057       //
1058       if (aMSOr.Contains(aSd)) {
1059         // make new solid
1060         TopoDS_Solid aSdx;
1061         //
1062         aBB.MakeSolid(aSdx);
1063         aItS.Initialize(aSd);
1064         for (; aItS.More(); aItS.Next()) {
1065           const TopoDS_Shape& aSh=aItS.Value();
1066           aBB.Add(aSdx, aSh);
1067         }
1068         //
1069         aBB.Add(aSdx, aSI);
1070         //
1071         // no need to check for images of aSd as aMSOr contains only original solids
1072         BOPCol_ListOfShape* pLS = myImages.Bound(aSd, BOPCol_ListOfShape());
1073         pLS->Append(aSdx);
1074         //
1075         BOPCol_ListOfShape* pLOr = myOrigins.Bound(aSdx, BOPCol_ListOfShape());
1076         pLOr->Append(aSd);
1077         //
1078         aMSOr.Remove(aSd);
1079         aSd=aSdx;
1080       }
1081       else {
1082         aBB.Add(aSd, aSI);
1083       }
1084       //
1085       aLSI.Remove(aIt1);
1086     }//for (; aIt1.More();) {
1087   }//for (; aIt.More(); aIt.Next()) {
1088   //
1089   //-----------------------------------------------------scope t
1090   aLArgs.Clear();
1091   aLSd.Clear();
1092   aMSOr.Clear();
1093   aMFence.Clear();
1094   aMSI.Clear();
1095   aMx.Clear();
1096   aMSx.Clear();
1097 }
1098 //=======================================================================
1099 //function : OwnInternalShapes
1100 //purpose  : 
1101 //=======================================================================
1102 void OwnInternalShapes(const TopoDS_Shape& theS,
1103                        BOPCol_IndexedMapOfShape& theMx)
1104 {
1105   TopoDS_Iterator aIt;
1106   //
1107   aIt.Initialize(theS);
1108   for (; aIt.More(); aIt.Next()) {
1109     const TopoDS_Shape& aSx=aIt.Value();
1110     if (aSx.ShapeType()!=TopAbs_SHELL) {
1111       theMx.Add(aSx);
1112     }
1113   }
1114 }
1115 //=======================================================================
1116 //function : TreatCompound
1117 //purpose  : 
1118 //=======================================================================
1119 void TreatCompound(const TopoDS_Shape& theS,
1120                    BOPCol_MapOfShape& aMFence,
1121                    BOPCol_ListOfShape& theLS)
1122 {
1123   TopAbs_ShapeEnum aType;
1124   //
1125   aType = theS.ShapeType();
1126   if (aType != TopAbs_COMPOUND) {
1127     if (aMFence.Add(theS)) {
1128       theLS.Append(theS);
1129     }
1130     return;
1131   }
1132   //
1133   TopoDS_Iterator aIt;
1134   //
1135   aIt.Initialize(theS);
1136   for (; aIt.More(); aIt.Next()) {
1137     const TopoDS_Shape& aS = aIt.Value();
1138     TreatCompound(aS, aMFence, theLS);
1139   }
1140 }