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