0024098: Exception Standard_OutOfMemory raised during topological operation.
[occt.git] / src / BOPAlgo / BOPAlgo_Builder_3.cxx
1 // Created by: Peter KURNEV
2 // Copyright (c) 2010-2012 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 // The content of this file is subject to the Open CASCADE Technology Public
8 // License Version 6.5 (the "License"). You may not use the content of this file
9 // except in compliance with the License. Please obtain a copy of the License
10 // at http://www.opencascade.org and read it completely before using this file.
11 //
12 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
13 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
14 //
15 // The Original Code and all software distributed under the License is
16 // distributed on an "AS IS" basis, without warranty of any kind, and the
17 // Initial Developer hereby disclaims all such warranties, including without
18 // limitation, any warranties of merchantability, fitness for a particular
19 // purpose or non-infringement. Please see the License for the specific terms
20 // and conditions governing the rights and limitations under the License.
21
22 #include <BOPAlgo_Builder.hxx>
23
24 #include <NCollection_IncAllocator.hxx>
25
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_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 //
45 #include <BOPCol_IndexedMapOfShape.hxx>
46 #include <BOPCol_MapOfShape.hxx>
47 #include <BOPCol_IndexedDataMapOfShapeListOfShape.hxx>
48 #include <BOPCol_ListOfShape.hxx>
49 //
50 #include <BOPDS_DS.hxx>
51 #include <BOPDS_ShapeInfo.hxx>
52 //
53 #include <BOPTools.hxx>
54 #include <BOPTools_AlgoTools.hxx>
55 //
56 #include <BOPTools_MapOfSet.hxx>
57 #include <BOPTools_Set.hxx>
58 //
59 #include <BOPAlgo_BuilderSolid.hxx>
60
61
62 static
63   void OwnInternalShapes(const TopoDS_Shape& ,
64                          BOPCol_IndexedMapOfShape& );
65
66 //=======================================================================
67 //function : FillImagesSolids
68 //purpose  : 
69 //=======================================================================
70   void BOPAlgo_Builder::FillImagesSolids()
71 {
72   myErrorStatus=0;
73   //
74   Handle(NCollection_IncAllocator) aAllocator;
75   //-----------------------------------------------------scope_1 f
76   aAllocator=new NCollection_IncAllocator();
77   //
78   BOPCol_DataMapOfShapeListOfShape theInParts(100, aAllocator);
79   BOPCol_DataMapOfShapeShape theDraftSolids(100, aAllocator);
80   //
81   FillIn3DParts(theInParts, theDraftSolids, aAllocator);
82   BuildSplitSolids(theInParts, theDraftSolids, aAllocator);
83   FillInternalShapes();
84   //
85   theInParts.Clear();
86   theDraftSolids.Clear();
87   //-----------------------------------------------------scope_1 t
88 }
89 //=======================================================================
90 //function : FillIn3DParts
91 //purpose  : 
92 //=======================================================================
93   void BOPAlgo_Builder::FillIn3DParts(BOPCol_DataMapOfShapeListOfShape& theInParts,
94                                       BOPCol_DataMapOfShapeShape& theDraftSolids,
95                                       const Handle(NCollection_BaseAllocator)& theAllocator)
96 {
97   myErrorStatus=0;
98   //
99   Standard_Boolean bIsIN, bHasImage;
100   Standard_Integer aNbS, aNbSolids, i, j, aNbFaces, aNbFP, aNbFPx, aNbFIN, aNbLIF, aNbEFP;
101   TopAbs_ShapeEnum aType;  
102   TopAbs_State aState;
103   TopoDS_Iterator aIt, aItF;
104   BRep_Builder aBB;
105   TopoDS_Solid aSolidSp; 
106   TopoDS_Face aFP;
107   BOPCol_ListIteratorOfListOfShape aItS, aItFP, aItEx;  
108   //
109   //BOPCol_ListOfShape aLIF(theAllocator);
110   //BOPCol_MapOfShape aMFDone(100, theAllocator);
111   //BOPCol_IndexedMapOfShape aMFIN(100, theAllocator);
112   //BOPCol_IndexedDataMapOfShapeListOfShape aMEF(100, theAllocator);
113   //BOPCol_IndexedMapOfShape aMS(100, theAllocator);
114   BOPCol_IndexedMapOfShape aMSolids(100, theAllocator);
115   BOPCol_IndexedMapOfShape aMFaces(100, theAllocator);
116   //
117   theDraftSolids.Clear();
118   //
119   aNbS=myDS->NbSourceShapes();
120   for (i=0; i<aNbS; ++i) {
121     const BOPDS_ShapeInfo& aSI=myDS->ShapeInfo(i);
122     const TopoDS_Shape& aS=aSI.Shape();
123     //
124     aType=aSI.ShapeType();
125     switch(aType) {
126       case TopAbs_SOLID: {
127         aMSolids.Add(aS);
128         break;
129       }
130       //
131       case TopAbs_FACE: {
132         // all faces (originals or images)
133         if (myImages.IsBound(aS)) {
134           const BOPCol_ListOfShape& aLS=myImages.Find(aS);
135           aItS.Initialize(aLS);
136           for (; aItS.More(); aItS.Next()) {
137             const TopoDS_Shape& aFx=aItS.Value();
138             aMFaces.Add(aFx);
139           }
140         }
141         else {
142           aMFaces.Add(aS);
143         }
144         break;
145       }
146       //
147       default:
148         break;
149     }
150   }
151   //
152   aNbFaces=aMFaces.Extent();
153   aNbSolids=aMSolids.Extent();
154   //
155   for (i=1; i<=aNbSolids; ++i) {
156     Handle(NCollection_IncAllocator) aAllocator1;
157     aAllocator1=new NCollection_IncAllocator();
158     //
159     BOPCol_MapOfShape aMFDone(100, aAllocator1);
160     BOPCol_IndexedMapOfShape aMFIN(100, aAllocator1);
161     BOPCol_IndexedDataMapOfShapeListOfShape aMEF(100, aAllocator1);
162     BOPCol_ListOfShape aLIF(aAllocator1);
163     BOPCol_IndexedMapOfShape aMS(100, aAllocator1);
164     //
165     aMFDone.Clear();
166     aMFIN.Clear();
167     aMEF.Clear();
168     //
169     const TopoDS_Solid& aSolid=(*(TopoDS_Solid*)(&aMSolids(i)));
170     //
171     aBB.MakeSolid(aSolidSp);
172     // 
173     // Draft solid and its pure internal faces => aSolidSp, aLIF
174     aLIF.Clear();
175     BuildDraftSolid(aSolid, aSolidSp, aLIF);
176     aNbLIF=aLIF.Extent();
177     //
178     // 1 all faces/edges from aSolid [ aMS ]
179     bHasImage=Standard_False;
180     aMS.Clear();
181     aIt.Initialize(aSolid);
182     for (; aIt.More(); aIt.Next()) {
183       const TopoDS_Shape& aShell=aIt.Value();
184       //
185       if (myImages.IsBound(aShell)) {
186         bHasImage=Standard_True;
187         //
188         const BOPCol_ListOfShape& aLS=myImages.Find(aShell);
189         aItS.Initialize(aLS);
190         for (; aItS.More(); aItS.Next()) {
191           const TopoDS_Shape& aSx=aItS.Value();
192           aMS.Add(aSx);
193           BOPTools::MapShapes(aSx, TopAbs_FACE, aMS);
194           BOPTools::MapShapes(aSx, TopAbs_EDGE, aMS);
195           BOPTools::MapShapesAndAncestors(aSx, TopAbs_EDGE, TopAbs_FACE, aMEF);
196         }
197       }
198       else {
199         //aMS.Add(aShell);
200         BOPTools::MapShapes(aShell, TopAbs_FACE, aMS);
201         BOPTools::MapShapesAndAncestors(aShell, TopAbs_EDGE, TopAbs_FACE, aMEF);
202       }
203     }
204     //
205     // 2 all faces that are not from aSolid [ aLFP1 ]
206     BOPCol_IndexedDataMapOfShapeListOfShape aMEFP(100, aAllocator1);
207     BOPCol_ListOfShape aLFP1(aAllocator1);
208     BOPCol_ListOfShape aLFP(aAllocator1);
209     BOPCol_ListOfShape aLCBF(aAllocator1);
210     BOPCol_ListOfShape aLFIN(aAllocator1);
211     BOPCol_ListOfShape aLEx(aAllocator1);
212     //
213     // for all non-solid faces build EF map [ aMEFP ]
214     for (j=1; j<=aNbFaces; ++j) {
215       const TopoDS_Shape& aFace=aMFaces(j);
216       if (!aMS.Contains(aFace)) {
217         BOPTools::MapShapesAndAncestors(aFace, TopAbs_EDGE, TopAbs_FACE, aMEFP);
218       }
219     }
220     //
221     // among all faces from aMEFP select these that have same edges
222     // with the solid (i.e aMEF). These faces will be treated first 
223     // to prevent the usage of 3D classifier.
224     // The full list of faces to process is aLFP1. 
225     aNbEFP=aMEFP.Extent();
226     for (j=1; j<=aNbEFP; ++j) {
227       const TopoDS_Shape& aE=aMEFP.FindKey(j);
228       //
229       if (aMEF.Contains(aE)) { // !!
230         const BOPCol_ListOfShape& aLF=aMEFP(j);
231         aItFP.Initialize(aLF);
232         for (; aItFP.More(); aItFP.Next()) {
233           const TopoDS_Shape& aF=aItFP.Value();
234           if (aMFDone.Add(aF)) {
235             aLFP1.Append(aF);
236           }
237         }
238       }
239       else {
240         aLEx.Append(aE);
241       }
242     }
243     //
244     aItEx.Initialize(aLEx);
245     for (; aItEx.More(); aItEx.Next()) {
246       const TopoDS_Shape& aE=aItEx.Value();
247       const BOPCol_ListOfShape& aLF=aMEFP.FindFromKey(aE);
248       aItFP.Initialize(aLF);
249       for (; aItFP.More(); aItFP.Next()) {
250         const TopoDS_Shape& aF=aItFP.Value();
251         if (aMFDone.Add(aF)) {
252           //aLFP2.Append(aF);
253           aLFP1.Append(aF);
254         }
255       }
256     }
257     //
258     //==========
259     //
260     // 3 Process faces aLFP1
261     aMFDone.Clear();
262     aNbFP=aLFP1.Extent();
263     aItFP.Initialize(aLFP1);
264     for (; aItFP.More(); aItFP.Next()) {
265       const TopoDS_Shape& aSP=aItFP.Value();
266       if (!aMFDone.Add(aSP)) {
267         continue;
268       }
269       
270       //
271       // first face to process
272       aFP=(*(TopoDS_Face*)(&aSP));
273       bIsIN=BOPTools_AlgoTools::IsInternalFace(aFP, aSolidSp, aMEF, 1.e-14, myContext);
274       aState=(bIsIN) ? TopAbs_IN : TopAbs_OUT;
275       //
276       // collect faces to process [ aFP is the first ]
277       aLFP.Clear();
278       aLFP.Append(aFP);
279       aItS.Initialize(aLFP1);
280       for (; aItS.More(); aItS.Next()) {
281         const TopoDS_Shape& aSk=aItS.Value();
282         if (!aMFDone.Contains(aSk)) {
283           aLFP.Append(aSk);
284         }
285       }
286       //
287       // Connexity Block that spreads from aFP the Bound 
288       // or till the end of the block itself
289       aLCBF.Clear();
290       {
291         Handle(NCollection_IncAllocator) aAllocator;
292         aAllocator=new NCollection_IncAllocator();
293         //
294         BOPTools_AlgoTools::MakeConnexityBlock(aLFP, aMS, aLCBF, aAllocator);
295         //
296       }
297       //
298       //
299       // fill states for the Connexity Block 
300       aItS.Initialize(aLCBF);
301       for (; aItS.More(); aItS.Next()) {
302         const TopoDS_Shape& aSx=aItS.Value();
303         aMFDone.Add(aSx);
304         if (aState==TopAbs_IN) {
305           aMFIN.Add(aSx);
306         }
307       }
308       //
309       aNbFPx=aMFDone.Extent();
310       if (aNbFPx==aNbFP) {
311         break;
312       }
313     }//for (; aItFP.More(); aItFP.Next())
314     //
315     // faces Inside aSolid
316     aLFIN.Clear();
317     aNbFIN=aMFIN.Extent();
318     if (aNbFIN || aNbLIF) {
319       for (j=1; j<=aNbFIN; ++j) {
320         const TopoDS_Shape& aFIn=aMFIN(j);
321         aLFIN.Append(aFIn);
322       }
323       //
324       aItS.Initialize(aLIF);
325       for (; aItS.More(); aItS.Next()) {
326         const TopoDS_Shape& aFIN=aItS.Value();
327         aLFIN.Append(aFIN);
328       }
329       //
330       theInParts.Bind(aSolid, aLFIN);
331     }
332     if (aNbFIN || bHasImage) {
333       theDraftSolids.Bind(aSolid, aSolidSp);
334     }
335   }//for (i=1; i<=aNbSolids; ++i) {
336 }
337 //=======================================================================
338 //function : BuildDraftSolid
339 //purpose  : 
340 //=======================================================================
341   void BOPAlgo_Builder::BuildDraftSolid(const TopoDS_Shape& theSolid,
342                                         TopoDS_Shape& theDraftSolid,
343                                         BOPCol_ListOfShape& theLIF)
344 {
345   myErrorStatus=0;
346   //
347   Standard_Boolean bToReverse;
348   Standard_Integer iFlag;
349   TopAbs_Orientation aOrF, aOrSh, aOrSd;
350   TopoDS_Iterator aIt1, aIt2;
351   TopoDS_Shell aShD;
352   TopoDS_Shape aFSDx, aFx;
353   BRep_Builder aBB;
354   BOPCol_ListIteratorOfListOfShape aItS;        
355   //
356   aOrSd=theSolid.Orientation();
357   theDraftSolid.Orientation(aOrSd);
358   //
359   aIt1.Initialize(theSolid);
360   for (; aIt1.More(); aIt1.Next()) {
361     const TopoDS_Shape& aSh=aIt1.Value();
362     if(aSh.ShapeType()!=TopAbs_SHELL) {
363       continue; // mb internal edges,vertices
364     }
365     //
366     aOrSh=aSh.Orientation();
367     aBB.MakeShell(aShD);
368     aShD.Orientation(aOrSh);
369     iFlag=0;
370     //
371     aIt2.Initialize(aSh);
372     for (; aIt2.More(); aIt2.Next()) {
373       const TopoDS_Shape& aF=aIt2.Value();
374       aOrF=aF.Orientation();
375       //
376       if (myImages.IsBound(aF)) {
377         const BOPCol_ListOfShape& aLSp=myImages.Find(aF);
378         aItS.Initialize(aLSp);
379         for (; aItS.More(); aItS.Next()) {
380           aFx=aItS.Value();
381           //
382           if (myShapesSD.IsBound(aFx)) {
383             aFSDx=myShapesSD.Find(aFx);
384             //
385             if (aOrF==TopAbs_INTERNAL) {
386               aFSDx.Orientation(aOrF);
387               theLIF.Append(aFSDx);
388             }
389             else {
390               bToReverse=BOPTools_AlgoTools::IsSplitToReverse(aFSDx, aF, myContext); 
391               if (bToReverse) {
392                 aFSDx.Reverse();
393               }
394               //
395               iFlag=1;
396               aBB.Add(aShD, aFSDx);
397             }
398           }//if (myShapesSD.IsBound(aFx)) {
399           else {
400             aFx.Orientation(aOrF);
401             if (aOrF==TopAbs_INTERNAL) {
402               theLIF.Append(aFx);
403             }
404             else{
405               iFlag=1;
406               aBB.Add(aShD, aFx);
407             }
408           }
409         }
410       } // if (myImages.IsBound(aF)) { 
411       //
412       else {
413         if (aOrF==TopAbs_INTERNAL) {
414           theLIF.Append(aF);
415         }
416         else{
417           iFlag=1;
418           aBB.Add(aShD, aF);
419         }
420       }
421     } //for (; aIt2.More(); aIt2.Next()) {
422     //
423     if (iFlag) {
424       aBB.Add(theDraftSolid, aShD);
425     }
426   } //for (; aIt1.More(); aIt1.Next()) {
427 }
428 //=======================================================================
429 //function : BuildSplitSolids
430 //purpose  : 
431 //=======================================================================
432   void BOPAlgo_Builder::BuildSplitSolids(BOPCol_DataMapOfShapeListOfShape& theInParts,
433                                          BOPCol_DataMapOfShapeShape& theDraftSolids,
434                                          const Handle(NCollection_BaseAllocator)& theAllocator)
435 {
436   myErrorStatus=0;
437   //
438   Standard_Boolean bFlagSD;
439   Standard_Integer i, aNbS, iErr, aNbSFS;
440   TopExp_Explorer aExp;
441   BOPCol_ListIteratorOfListOfShape aIt;
442   BOPCol_DataMapIteratorOfDataMapOfShapeShape aIt1;
443   //
444   BOPCol_ListOfShape aSFS(theAllocator), aLSEmpty(theAllocator);
445   BOPCol_MapOfShape aMFence(100, theAllocator);
446   BOPTools_MapOfSet aMST(100, theAllocator);
447   //
448   // 0. Find same domain solids for non-interferred solids
449   aNbS=myDS->NbSourceShapes();
450   for (i=0; i<aNbS; ++i) {
451     const BOPDS_ShapeInfo& aSI=myDS->ShapeInfo(i);
452     //
453     if (aSI.ShapeType()!=TopAbs_SOLID) {
454       continue;
455     }
456     //
457     const TopoDS_Shape& aS=aSI.Shape();
458     if (!aMFence.Add(aS)) {
459       continue;
460     }
461     if(theDraftSolids.IsBound(aS)) {
462       continue;
463     }
464     //
465     BOPTools_Set aST;
466     //
467     aST.Add(aS, TopAbs_FACE);
468     aMST.Add(aST);
469     //
470   } //for (i=1; i<=aNbS; ++i) 
471   //
472   // 1. Build solids for interferred source solids
473   for (i=0; i<aNbS; ++i) {
474     const BOPDS_ShapeInfo& aSI=myDS->ShapeInfo(i);
475     //
476     if (aSI.ShapeType()!=TopAbs_SOLID) {
477       continue;
478     }
479     //
480     const TopoDS_Shape& aS=aSI.Shape();
481     if(!theDraftSolids.IsBound(aS)) {
482       continue;
483     }
484     const TopoDS_Shape& aSD=theDraftSolids.Find(aS);
485     const BOPCol_ListOfShape& aLFIN=
486       (theInParts.IsBound(aS)) ? theInParts.Find(aS) : aLSEmpty;
487     //
488     // 1.1 Fill Shell Faces Set
489     aSFS.Clear();
490     aExp.Init(aSD, TopAbs_FACE);
491     for (; aExp.More(); aExp.Next()) {
492       const TopoDS_Shape& aF=aExp.Current();
493       aSFS.Append(aF);
494     }
495     //
496     aIt.Initialize(aLFIN);
497     for (; aIt.More(); aIt.Next()) {
498       TopoDS_Shape aF=aIt.Value();
499       //
500       aF.Orientation(TopAbs_FORWARD);
501       aSFS.Append(aF);
502       aF.Orientation(TopAbs_REVERSED);
503       aSFS.Append(aF);
504     }
505     //
506     aNbSFS=aSFS.Extent();
507     //DEB f
508     // <-A
509     //DEB t
510     //
511     // 1.3 Build new solids
512     BOPAlgo_BuilderSolid aSB(theAllocator);
513     //
514     //aSB.SetContext(myContext);
515     aSB.SetShapes(aSFS);
516     aSB.Perform();
517     iErr=aSB.ErrorStatus();
518     if (iErr) {
519       myErrorStatus=30; // SolidBuilder failed
520       return;
521     }
522     //
523     const BOPCol_ListOfShape& aLSR=aSB.Areas();
524     //
525     // 1.4 Collect resulting solids and theirs set of faces. 
526     //     Update Images.
527     if (!myImages.IsBound(aS)) {
528       BOPCol_ListOfShape aLSx;
529       //
530       myImages.Bind(aS, aLSx);
531       BOPCol_ListOfShape& aLSIm=myImages.ChangeFind(aS);
532       //
533       aIt.Initialize(aLSR);
534       for (; aIt.More(); aIt.Next()) {
535         BOPTools_Set aST;
536         //
537         const TopoDS_Shape& aSR=aIt.Value();
538         aST.Add(aSR, TopAbs_FACE);
539         //
540         bFlagSD=aMST.Contains(aST);
541         //
542         const BOPTools_Set& aSTx=aMST.Added(aST);
543         const TopoDS_Shape& aSx=aSTx.Shape();
544         aLSIm.Append(aSx);
545         //
546         if (bFlagSD) {
547           myShapesSD.Bind(aSR, aSx);
548         }
549       }
550     }
551   } // for (; aIt1.More(); aIt1.Next()) {
552 }
553
554 //=======================================================================
555 //function :FillInternalShapes 
556 //purpose  : 
557 //=======================================================================
558   void BOPAlgo_Builder::FillInternalShapes()
559 {
560   myErrorStatus=0;
561   //
562   Standard_Integer i, j,  aNbS, aNbSI, aNbSx, aNbSd;
563   TopAbs_ShapeEnum aType;
564   TopAbs_State aState; 
565   TopoDS_Iterator aItS;
566   BRep_Builder aBB;
567   BOPCol_MapIteratorOfMapOfShape aItM;
568   BOPCol_ListIteratorOfListOfShape aIt, aIt1;
569   //
570   Handle(NCollection_IncAllocator) aAllocator;
571   //-----------------------------------------------------scope f
572   aAllocator=new NCollection_IncAllocator();
573   //
574   BOPCol_IndexedDataMapOfShapeListOfShape aMSx(100, aAllocator);
575   BOPCol_IndexedMapOfShape aMx(100, aAllocator);
576   BOPCol_MapOfShape aMSI(100, aAllocator);
577   BOPCol_MapOfShape aMFence(100, aAllocator);
578   BOPCol_MapOfShape aMSOr(100, aAllocator);
579   BOPCol_ListOfShape aLSd(aAllocator);
580   BOPCol_ListOfShape aLArgs(aAllocator);
581   //
582   // 1. Shapes to process
583   //
584   // 1.1 Shapes from pure arguments aMSI 
585   // 1.1.1 vertex, edge, wire
586   //
587   aIt.Initialize(myArguments);
588   for (; aIt.More(); aIt.Next()) {
589     const TopoDS_Shape& aS=aIt.Value();
590     if (!aMFence.Add(aS)) {
591       continue;
592     }
593     //
594     aType=aS.ShapeType();
595     if (aType==TopAbs_WIRE) {
596       aItS.Initialize(aS);
597       for(; aItS.More(); aItS.Next()) {
598         const TopoDS_Shape& aE=aItS.Value();
599         if (aMFence.Add(aE)) {
600           aLArgs.Append(aE);
601         }
602       }
603     }
604     else if (aType==TopAbs_VERTEX || aType==TopAbs_EDGE){
605       aLArgs.Append(aS);
606     } 
607   }
608   aMFence.Clear();
609   //
610   aIt.Initialize(aLArgs);
611   for (; aIt.More(); aIt.Next()) {
612     const TopoDS_Shape& aS=aIt.Value();
613     aType=aS.ShapeType();
614     if (aType==TopAbs_VERTEX || aType==TopAbs_EDGE ||aType==TopAbs_WIRE) {
615       if (aMFence.Add(aS)) {
616         if (myImages.IsBound(aS)) {
617           const BOPCol_ListOfShape &aLSp=myImages.Find(aS);
618           aIt1.Initialize(aLSp);
619           for (; aIt1.More(); aIt1.Next()) {
620             const TopoDS_Shape& aSp=aIt1.Value();
621             aMSI.Add(aSp);
622           }
623         }
624         else {
625           aMSI.Add(aS);
626         }
627       }
628     }
629   }
630   
631   aNbSI=aMSI.Extent();
632   //
633   // 2. Internal vertices, edges from source solids
634   aMFence.Clear();
635   aLSd.Clear();
636   //
637   aNbS=myDS->NbSourceShapes();
638   for (i=0; i<aNbS; ++i) {
639     const BOPDS_ShapeInfo& aSI=myDS->ShapeInfo(i);
640     //
641     if (aSI.ShapeType()!=TopAbs_SOLID) {
642       continue;
643     }
644     //
645     const TopoDS_Shape& aS=aSI.Shape();
646     //
647     aMx.Clear();
648     OwnInternalShapes(aS, aMx);
649     //
650     aNbSx=aMx.Extent();
651     for (j=1; j<=aNbSx; ++j) {
652       const TopoDS_Shape& aSi=aMx(j);
653       if (myImages.IsBound(aSi)) {
654         const BOPCol_ListOfShape &aLSp=myImages.Find(aSi);
655         aIt1.Initialize(aLSp);
656         for (; aIt1.More(); aIt1.Next()) {
657           const TopoDS_Shape& aSp=aIt1.Value();
658           aMSI.Add(aSp);
659         }
660       }
661       else {
662         aMSI.Add(aSi);
663       }
664     }
665     //
666     // build aux map from splits of solids
667     if (myImages.IsBound(aS)) {
668       const BOPCol_ListOfShape &aLSp=myImages.Find(aS);
669       aIt.Initialize(aLSp);
670       for (; aIt.More(); aIt.Next()) {
671         const TopoDS_Shape& aSp=aIt.Value();
672         if (aMFence.Add(aSp)) { 
673           BOPTools::MapShapesAndAncestors(aSp, TopAbs_VERTEX, TopAbs_EDGE, aMSx);
674           BOPTools::MapShapesAndAncestors(aSp, TopAbs_VERTEX, TopAbs_FACE, aMSx);
675           BOPTools::MapShapesAndAncestors(aSp, TopAbs_EDGE  , TopAbs_FACE, aMSx);
676           aLSd.Append(aSp);
677         }
678       }
679     }
680     else {
681       if (aMFence.Add(aS)) {
682         BOPTools::MapShapesAndAncestors(aS, TopAbs_VERTEX, TopAbs_EDGE, aMSx);
683         BOPTools::MapShapesAndAncestors(aS, TopAbs_VERTEX, TopAbs_FACE, aMSx);
684         BOPTools::MapShapesAndAncestors(aS, TopAbs_EDGE  , TopAbs_FACE, aMSx);
685         aLSd.Append(aS);
686         aMSOr.Add(aS); 
687       }
688     }
689   }// for (i=0; i<aNbS; ++i) {
690   //
691   aNbSd=aLSd.Extent();
692   //
693   // 3. Some shapes of aMSI can be already tied with faces of 
694   //    split solids
695   aItM.Initialize(aMSI); 
696   for (; aItM.More(); aItM.Next()) {
697     const TopoDS_Shape& aSI=aItM.Key();
698     if (aMSx.Contains(aSI)) {
699       const BOPCol_ListOfShape &aLSx=aMSx.FindFromKey(aSI);
700       aNbSx=aLSx.Extent();
701       if (aNbSx) {
702         aMSI.Remove(aSI);
703       }
704     }
705   }
706   //
707   // 4. Just check it
708   aNbSI=aMSI.Extent();
709   if (!aNbSI) {
710     return;
711   }
712   //
713   // 5 Settle internal vertices and edges into solids
714   aMx.Clear();
715   aIt.Initialize(aLSd);
716   for (; aIt.More(); aIt.Next()) {
717     TopoDS_Solid aSd=TopoDS::Solid(aIt.Value());
718     //
719     aItM.Initialize(aMSI); 
720     for (; aItM.More(); aItM.Next()) {
721       TopoDS_Shape aSI=aItM.Key();
722       aSI.Orientation(TopAbs_INTERNAL);
723       //
724       aState=BOPTools_AlgoTools::ComputeStateByOnePoint(aSI, aSd, 1.e-11, myContext);
725       if (aState==TopAbs_IN) {
726         //
727         if(aMSOr.Contains(aSd)) {
728           //
729           TopoDS_Solid aSdx;
730           //
731           aBB.MakeSolid(aSdx);
732           aItS.Initialize(aSd);
733           for (; aItS.More(); aItS.Next()) {
734             const TopoDS_Shape& aSh=aItS.Value();
735             aBB.Add(aSdx, aSh);
736           }
737           //
738           aBB.Add(aSdx, aSI);
739           //
740           if (myImages.IsBound(aSdx)) {
741             BOPCol_ListOfShape& aLS=myImages.ChangeFind(aSdx);
742             aLS.Append(aSdx);
743           } 
744           else {
745             BOPCol_ListOfShape aLS;
746             aLS.Append(aSdx);
747             myImages.Bind(aSd, aLS);
748           }
749           //
750           aMSOr.Remove(aSd);
751           aSd=aSdx;
752         }
753         else {
754           aBB.Add(aSd, aSI);
755         }
756         //
757         aMSI.Remove(aSI);
758       } //if (aState==TopAbs_IN) {
759     }// for (; aItM.More(); aItM.Next()) {
760   }//for (; aIt1.More(); aIt1.Next()) {
761   //
762   //-----------------------------------------------------scope t
763   aLArgs.Clear();
764   aLSd.Clear();
765   aMSOr.Clear();
766   aMFence.Clear();
767   aMSI.Clear();
768   aMx.Clear();
769   aMSx.Clear();
770 }
771 //=======================================================================
772 //function : OwnInternalShapes
773 //purpose  : 
774 //=======================================================================
775   void OwnInternalShapes(const TopoDS_Shape& theS,
776                          BOPCol_IndexedMapOfShape& theMx)
777 {
778   TopoDS_Iterator aIt;
779   //
780   aIt.Initialize(theS);
781   for (; aIt.More(); aIt.Next()) {
782     const TopoDS_Shape& aSx=aIt.Value();
783     if (aSx.ShapeType()!=TopAbs_SHELL) {
784       theMx.Add(aSx);
785     }
786   }
787 }
788 //
789 // ErrorStatus
790 // 30 - SolidBuilder failed
791 // A
792 /*
793     {
794       TopoDS_Compound aCx;
795       BRep_Builder aBBx;
796       BOPCol_ListIteratorOfListOfShape aItx;
797       //
798       aBBx.MakeCompound(aCx);
799       aItx.Initialize(aSFS1);
800       for (; aItx.More(); aItx.Next()) {
801       const TopoDS_Shape& aFx=aItx.Value();
802       aBBx.Add(aCx, aFx);
803       }
804       BRepTools::Write(aCx, "cxso");
805       int a=0;
806     }
807     */