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