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