85d19aa80abc8279bcae48365c7489dd931fa111
[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 aMSolids(100, theAllocator);
112   BOPCol_IndexedMapOfShape aMFaces(100, theAllocator);
113   BOPCol_IndexedMapOfShape aMFIN(100, theAllocator);
114   BOPCol_IndexedMapOfShape aMS(100, theAllocator);
115   BOPCol_IndexedDataMapOfShapeListOfShape aMEF(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     const TopoDS_Solid& aSolid=(*(TopoDS_Solid*)(&aMSolids(i)));
157     //
158     aMFDone.Clear();
159     aMFIN.Clear();
160     aMEF.Clear();
161     //
162     aBB.MakeSolid(aSolidSp);
163     // 
164     // Draft solid and its pure internal faces => aSolidSp, aLIF
165     aLIF.Clear();
166     BuildDraftSolid(aSolid, aSolidSp, aLIF);
167     aNbLIF=aLIF.Extent();
168     //
169     // 1 all faces/edges from aSolid [ aMS ]
170     bHasImage=Standard_False;
171     aMS.Clear();
172     aIt.Initialize(aSolid);
173     for (; aIt.More(); aIt.Next()) {
174       const TopoDS_Shape& aShell=aIt.Value();
175       //
176       if (myImages.IsBound(aShell)) {
177         bHasImage=Standard_True;
178         //
179         const BOPCol_ListOfShape& aLS=myImages.Find(aShell);
180         aItS.Initialize(aLS);
181         for (; aItS.More(); aItS.Next()) {
182           const TopoDS_Shape& aSx=aItS.Value();
183           aMS.Add(aSx);
184           BOPTools::MapShapes(aSx, TopAbs_FACE, aMS);
185           BOPTools::MapShapes(aSx, TopAbs_EDGE, aMS);
186           BOPTools::MapShapesAndAncestors(aSx, TopAbs_EDGE, TopAbs_FACE, aMEF);
187         }
188       }
189       else {
190         //aMS.Add(aShell);
191         BOPTools::MapShapes(aShell, TopAbs_FACE, aMS);
192         BOPTools::MapShapesAndAncestors(aShell, TopAbs_EDGE, TopAbs_FACE, aMEF);
193       }
194     }
195     //
196     // 2 all faces that are not from aSolid [ aLFP1 ]
197     BOPCol_IndexedDataMapOfShapeListOfShape aMEFP(100, theAllocator);
198     BOPCol_ListOfShape aLFP1(theAllocator);
199     BOPCol_ListOfShape aLFP(theAllocator);
200     BOPCol_ListOfShape aLCBF(theAllocator);
201     BOPCol_ListOfShape aLFIN(theAllocator);
202     BOPCol_ListOfShape aLEx(theAllocator);
203     //
204     // for all non-solid faces build EF map [ aMEFP ]
205     for (j=1; j<=aNbFaces; ++j) {
206       const TopoDS_Shape& aFace=aMFaces(j);
207       if (!aMS.Contains(aFace)) {
208         BOPTools::MapShapesAndAncestors(aFace, TopAbs_EDGE, TopAbs_FACE, aMEFP);
209       }
210     }
211     //
212     // among all faces from aMEFP select these that have same edges
213     // with the solid (i.e aMEF). These faces will be treated first 
214     // to prevent the usage of 3D classifier.
215     // The full list of faces to process is aLFP1. 
216     aNbEFP=aMEFP.Extent();
217     for (j=1; j<=aNbEFP; ++j) {
218       const TopoDS_Shape& aE=aMEFP.FindKey(j);
219       //
220       if (aMEF.Contains(aE)) { // !!
221         const BOPCol_ListOfShape& aLF=aMEFP(j);
222         aItFP.Initialize(aLF);
223         for (; aItFP.More(); aItFP.Next()) {
224           const TopoDS_Shape& aF=aItFP.Value();
225           if (aMFDone.Add(aF)) {
226             aLFP1.Append(aF);
227           }
228         }
229       }
230       else {
231         aLEx.Append(aE);
232       }
233     }
234     //
235     aItEx.Initialize(aLEx);
236     for (; aItEx.More(); aItEx.Next()) {
237       const TopoDS_Shape& aE=aItEx.Value();
238       const BOPCol_ListOfShape& aLF=aMEFP.FindFromKey(aE);
239       aItFP.Initialize(aLF);
240       for (; aItFP.More(); aItFP.Next()) {
241         const TopoDS_Shape& aF=aItFP.Value();
242         if (aMFDone.Add(aF)) {
243           //aLFP2.Append(aF);
244           aLFP1.Append(aF);
245         }
246       }
247     }
248     //
249     //==========
250     //
251     // 3 Process faces aLFP1
252     aMFDone.Clear();
253     aNbFP=aLFP1.Extent();
254     aItFP.Initialize(aLFP1);
255     for (; aItFP.More(); aItFP.Next()) {
256       const TopoDS_Shape& aSP=aItFP.Value();
257       if (!aMFDone.Add(aSP)) {
258         continue;
259       }
260       
261       //
262       // first face to process
263       aFP=(*(TopoDS_Face*)(&aSP));
264       bIsIN=BOPTools_AlgoTools::IsInternalFace(aFP, aSolidSp, aMEF, 1.e-14, myContext);
265       aState=(bIsIN) ? TopAbs_IN : TopAbs_OUT;
266       //
267       // collect faces to process [ aFP is the first ]
268       aLFP.Clear();
269       aLFP.Append(aFP);
270       aItS.Initialize(aLFP1);
271       for (; aItS.More(); aItS.Next()) {
272         const TopoDS_Shape& aSk=aItS.Value();
273         if (!aMFDone.Contains(aSk)) {
274           aLFP.Append(aSk);
275         }
276       }
277       //
278       // Connexity Block that spreads from aFP the Bound 
279       // or till the end of the block itself
280       aLCBF.Clear();
281       BOPTools_AlgoTools::MakeConnexityBlock(aLFP, aMS, aLCBF, theAllocator);
282       //
283       // fill states for the Connexity Block 
284       aItS.Initialize(aLCBF);
285       for (; aItS.More(); aItS.Next()) {
286         const TopoDS_Shape& aSx=aItS.Value();
287         aMFDone.Add(aSx);
288         if (aState==TopAbs_IN) {
289           aMFIN.Add(aSx);
290         }
291       }
292       //
293       aNbFPx=aMFDone.Extent();
294       if (aNbFPx==aNbFP) {
295         break;
296       }
297     }//for (; aItFP.More(); aItFP.Next())
298     //
299     // faces Inside aSolid
300     aLFIN.Clear();
301     aNbFIN=aMFIN.Extent();
302     if (aNbFIN || aNbLIF) {
303       for (j=1; j<=aNbFIN; ++j) {
304         const TopoDS_Shape& aFIn=aMFIN(j);
305         aLFIN.Append(aFIn);
306       }
307       //
308       aItS.Initialize(aLIF);
309       for (; aItS.More(); aItS.Next()) {
310         const TopoDS_Shape& aFIN=aItS.Value();
311         aLFIN.Append(aFIN);
312       }
313       //
314       theInParts.Bind(aSolid, aLFIN);
315     }
316     if (aNbFIN || bHasImage) {
317       theDraftSolids.Bind(aSolid, aSolidSp);
318     }
319   }// for (; aItMS.More(); aItMS.Next()) {
320 }
321 //=======================================================================
322 //function : BuildDraftSolid
323 //purpose  : 
324 //=======================================================================
325   void BOPAlgo_Builder::BuildDraftSolid(const TopoDS_Shape& theSolid,
326                                         TopoDS_Shape& theDraftSolid,
327                                         BOPCol_ListOfShape& theLIF)
328 {
329   myErrorStatus=0;
330   //
331   Standard_Boolean bToReverse;
332   Standard_Integer iFlag;
333   TopAbs_Orientation aOrF, aOrSh, aOrSd;
334   TopoDS_Iterator aIt1, aIt2;
335   TopoDS_Shell aShD;
336   TopoDS_Shape aFSDx, aFx;
337   BRep_Builder aBB;
338   BOPCol_ListIteratorOfListOfShape aItS;        
339   //
340   aOrSd=theSolid.Orientation();
341   theDraftSolid.Orientation(aOrSd);
342   //
343   aIt1.Initialize(theSolid);
344   for (; aIt1.More(); aIt1.Next()) {
345     const TopoDS_Shape& aSh=aIt1.Value();
346     if(aSh.ShapeType()!=TopAbs_SHELL) {
347       continue; // mb internal edges,vertices
348     }
349     //
350     aOrSh=aSh.Orientation();
351     aBB.MakeShell(aShD);
352     aShD.Orientation(aOrSh);
353     iFlag=0;
354     //
355     aIt2.Initialize(aSh);
356     for (; aIt2.More(); aIt2.Next()) {
357       const TopoDS_Shape& aF=aIt2.Value();
358       aOrF=aF.Orientation();
359       //
360       if (myImages.IsBound(aF)) {
361         const BOPCol_ListOfShape& aLSp=myImages.Find(aF);
362         aItS.Initialize(aLSp);
363         for (; aItS.More(); aItS.Next()) {
364           aFx=aItS.Value();
365           //
366           if (myShapesSD.IsBound(aFx)) {
367             aFSDx=myShapesSD.Find(aFx);
368             //
369             if (aOrF==TopAbs_INTERNAL) {
370               aFSDx.Orientation(aOrF);
371               theLIF.Append(aFSDx);
372             }
373             else {
374               bToReverse=BOPTools_AlgoTools::IsSplitToReverse(aFSDx, aF, myContext); 
375               if (bToReverse) {
376                 aFSDx.Reverse();
377               }
378               //
379               iFlag=1;
380               aBB.Add(aShD, aFSDx);
381             }
382           }//if (myShapesSD.IsBound(aFx)) {
383           else {
384             aFx.Orientation(aOrF);
385             if (aOrF==TopAbs_INTERNAL) {
386               theLIF.Append(aFx);
387             }
388             else{
389               iFlag=1;
390               aBB.Add(aShD, aFx);
391             }
392           }
393         }
394       } // if (myImages.IsBound(aF)) { 
395       //
396       else {
397         if (aOrF==TopAbs_INTERNAL) {
398           theLIF.Append(aF);
399         }
400         else{
401           iFlag=1;
402           aBB.Add(aShD, aF);
403         }
404       }
405     } //for (; aIt2.More(); aIt2.Next()) {
406     //
407     if (iFlag) {
408       aBB.Add(theDraftSolid, aShD);
409     }
410   } //for (; aIt1.More(); aIt1.Next()) {
411 }
412 //=======================================================================
413 //function : BuildSplitSolids
414 //purpose  : 
415 //=======================================================================
416   void BOPAlgo_Builder::BuildSplitSolids(BOPCol_DataMapOfShapeListOfShape& theInParts,
417                                          BOPCol_DataMapOfShapeShape& theDraftSolids,
418                                          const Handle(NCollection_BaseAllocator)& theAllocator)
419 {
420   myErrorStatus=0;
421   //
422   Standard_Boolean bFlagSD;
423   Standard_Integer i, aNbS, iErr, aNbSFS;
424   TopExp_Explorer aExp;
425   BOPCol_ListIteratorOfListOfShape aIt;
426   BOPCol_DataMapIteratorOfDataMapOfShapeShape aIt1;
427   //
428   BOPCol_ListOfShape aSFS(theAllocator), aLSEmpty(theAllocator);
429   BOPCol_MapOfShape aMFence(100, theAllocator);
430   BOPTools_MapOfSet aMST(100, theAllocator);
431   //
432   // 0. Find same domain solids for non-interferred solids
433   aNbS=myDS->NbSourceShapes();
434   for (i=0; i<aNbS; ++i) {
435     const BOPDS_ShapeInfo& aSI=myDS->ShapeInfo(i);
436     //
437     if (aSI.ShapeType()!=TopAbs_SOLID) {
438       continue;
439     }
440     //
441     const TopoDS_Shape& aS=aSI.Shape();
442     if (!aMFence.Add(aS)) {
443       continue;
444     }
445     if(theDraftSolids.IsBound(aS)) {
446       continue;
447     }
448     //
449     BOPTools_Set aST;
450     //
451     aST.Add(aS, TopAbs_FACE);
452     aMST.Add(aST);
453     //
454   } //for (i=1; i<=aNbS; ++i) 
455   //
456   // 1. Build solids for interferred source solids
457   for (i=0; i<aNbS; ++i) {
458     const BOPDS_ShapeInfo& aSI=myDS->ShapeInfo(i);
459     //
460     if (aSI.ShapeType()!=TopAbs_SOLID) {
461       continue;
462     }
463     //
464     const TopoDS_Shape& aS=aSI.Shape();
465     if(!theDraftSolids.IsBound(aS)) {
466       continue;
467     }
468     const TopoDS_Shape& aSD=theDraftSolids.Find(aS);
469     const BOPCol_ListOfShape& aLFIN=
470       (theInParts.IsBound(aS)) ? theInParts.Find(aS) : aLSEmpty;
471     //
472     // 1.1 Fill Shell Faces Set
473     aSFS.Clear();
474     aExp.Init(aSD, TopAbs_FACE);
475     for (; aExp.More(); aExp.Next()) {
476       const TopoDS_Shape& aF=aExp.Current();
477       aSFS.Append(aF);
478     }
479     //
480     aIt.Initialize(aLFIN);
481     for (; aIt.More(); aIt.Next()) {
482       TopoDS_Shape aF=aIt.Value();
483       //
484       aF.Orientation(TopAbs_FORWARD);
485       aSFS.Append(aF);
486       aF.Orientation(TopAbs_REVERSED);
487       aSFS.Append(aF);
488     }
489     //
490     aNbSFS=aSFS.Extent();
491     //DEB f
492     // <-A
493     //DEB t
494     //
495     // 1.3 Build new solids
496     BOPAlgo_BuilderSolid aSB(theAllocator);
497     //
498     //aSB.SetContext(myContext);
499     aSB.SetShapes(aSFS);
500     aSB.Perform();
501     iErr=aSB.ErrorStatus();
502     if (iErr) {
503       myErrorStatus=30; // SolidBuilder failed
504       return;
505     }
506     //
507     const BOPCol_ListOfShape& aLSR=aSB.Areas();
508     //
509     // 1.4 Collect resulting solids and theirs set of faces. 
510     //     Update Images.
511     if (!myImages.IsBound(aS)) {
512       BOPCol_ListOfShape aLSx;
513       //
514       myImages.Bind(aS, aLSx);
515       BOPCol_ListOfShape& aLSIm=myImages.ChangeFind(aS);
516       //
517       aIt.Initialize(aLSR);
518       for (; aIt.More(); aIt.Next()) {
519         BOPTools_Set aST;
520         //
521         const TopoDS_Shape& aSR=aIt.Value();
522         aST.Add(aSR, TopAbs_FACE);
523         //
524         bFlagSD=aMST.Contains(aST);
525         //
526         const BOPTools_Set& aSTx=aMST.Added(aST);
527         const TopoDS_Shape& aSx=aSTx.Shape();
528         aLSIm.Append(aSx);
529         //
530         if (bFlagSD) {
531           myShapesSD.Bind(aSR, aSx);
532         }
533       }
534     }
535   } // for (; aIt1.More(); aIt1.Next()) {
536 }
537
538 //=======================================================================
539 //function :FillInternalShapes 
540 //purpose  : 
541 //=======================================================================
542   void BOPAlgo_Builder::FillInternalShapes()
543 {
544   myErrorStatus=0;
545   //
546   Standard_Integer i, j,  aNbS, aNbSI, aNbSx, aNbSd;
547   TopAbs_ShapeEnum aType;
548   TopAbs_State aState; 
549   TopoDS_Iterator aItS;
550   BRep_Builder aBB;
551   BOPCol_MapIteratorOfMapOfShape aItM;
552   BOPCol_ListIteratorOfListOfShape aIt, aIt1;
553   //
554   Handle(NCollection_IncAllocator) aAllocator;
555   //-----------------------------------------------------scope f
556   aAllocator=new NCollection_IncAllocator();
557   //
558   BOPCol_IndexedDataMapOfShapeListOfShape aMSx(100, aAllocator);
559   BOPCol_IndexedMapOfShape aMx(100, aAllocator);
560   BOPCol_MapOfShape aMSI(100, aAllocator);
561   BOPCol_MapOfShape aMFence(100, aAllocator);
562   BOPCol_MapOfShape aMSOr(100, aAllocator);
563   BOPCol_ListOfShape aLSd(aAllocator);
564   BOPCol_ListOfShape aLArgs(aAllocator);
565   //
566   // 1. Shapes to process
567   //
568   // 1.1 Shapes from pure arguments aMSI 
569   // 1.1.1 vertex, edge, wire
570   //
571   aIt.Initialize(myArguments);
572   for (; aIt.More(); aIt.Next()) {
573     const TopoDS_Shape& aS=aIt.Value();
574     if (!aMFence.Add(aS)) {
575       continue;
576     }
577     //
578     aType=aS.ShapeType();
579     if (aType==TopAbs_WIRE) {
580       aItS.Initialize(aS);
581       for(; aItS.More(); aItS.Next()) {
582         const TopoDS_Shape& aE=aItS.Value();
583         if (aMFence.Add(aE)) {
584           aLArgs.Append(aE);
585         }
586       }
587     }
588     else if (aType==TopAbs_VERTEX || aType==TopAbs_EDGE){
589       aLArgs.Append(aS);
590     } 
591   }
592   aMFence.Clear();
593   //
594   aIt.Initialize(aLArgs);
595   for (; aIt.More(); aIt.Next()) {
596     const TopoDS_Shape& aS=aIt.Value();
597     aType=aS.ShapeType();
598     if (aType==TopAbs_VERTEX || aType==TopAbs_EDGE ||aType==TopAbs_WIRE) {
599       if (aMFence.Add(aS)) {
600         if (myImages.IsBound(aS)) {
601           const BOPCol_ListOfShape &aLSp=myImages.Find(aS);
602           aIt1.Initialize(aLSp);
603           for (; aIt1.More(); aIt1.Next()) {
604             const TopoDS_Shape& aSp=aIt1.Value();
605             aMSI.Add(aSp);
606           }
607         }
608         else {
609           aMSI.Add(aS);
610         }
611       }
612     }
613   }
614   
615   aNbSI=aMSI.Extent();
616   //
617   // 2. Internal vertices, edges from source solids
618   aMFence.Clear();
619   aLSd.Clear();
620   //
621   aNbS=myDS->NbSourceShapes();
622   for (i=0; i<aNbS; ++i) {
623     const BOPDS_ShapeInfo& aSI=myDS->ShapeInfo(i);
624     //
625     if (aSI.ShapeType()!=TopAbs_SOLID) {
626       continue;
627     }
628     //
629     const TopoDS_Shape& aS=aSI.Shape();
630     //
631     aMx.Clear();
632     OwnInternalShapes(aS, aMx);
633     //
634     aNbSx=aMx.Extent();
635     for (j=1; j<=aNbSx; ++j) {
636       const TopoDS_Shape& aSi=aMx(j);
637       if (myImages.IsBound(aSi)) {
638         const BOPCol_ListOfShape &aLSp=myImages.Find(aSi);
639         aIt1.Initialize(aLSp);
640         for (; aIt1.More(); aIt1.Next()) {
641           const TopoDS_Shape& aSp=aIt1.Value();
642           aMSI.Add(aSp);
643         }
644       }
645       else {
646         aMSI.Add(aSi);
647       }
648     }
649     //
650     // build aux map from splits of solids
651     if (myImages.IsBound(aS)) {
652       const BOPCol_ListOfShape &aLSp=myImages.Find(aS);
653       aIt.Initialize(aLSp);
654       for (; aIt.More(); aIt.Next()) {
655         const TopoDS_Shape& aSp=aIt.Value();
656         if (aMFence.Add(aSp)) { 
657           BOPTools::MapShapesAndAncestors(aSp, TopAbs_VERTEX, TopAbs_EDGE, aMSx);
658           BOPTools::MapShapesAndAncestors(aSp, TopAbs_VERTEX, TopAbs_FACE, aMSx);
659           BOPTools::MapShapesAndAncestors(aSp, TopAbs_EDGE  , TopAbs_FACE, aMSx);
660           aLSd.Append(aSp);
661         }
662       }
663     }
664     else {
665       if (aMFence.Add(aS)) {
666         BOPTools::MapShapesAndAncestors(aS, TopAbs_VERTEX, TopAbs_EDGE, aMSx);
667         BOPTools::MapShapesAndAncestors(aS, TopAbs_VERTEX, TopAbs_FACE, aMSx);
668         BOPTools::MapShapesAndAncestors(aS, TopAbs_EDGE  , TopAbs_FACE, aMSx);
669         aLSd.Append(aS);
670         aMSOr.Add(aS); 
671       }
672     }
673   }// for (i=0; i<aNbS; ++i) {
674   //
675   aNbSd=aLSd.Extent();
676   //
677   // 3. Some shapes of aMSI can be already tied with faces of 
678   //    split solids
679   aItM.Initialize(aMSI); 
680   for (; aItM.More(); aItM.Next()) {
681     const TopoDS_Shape& aSI=aItM.Key();
682     if (aMSx.Contains(aSI)) {
683       const BOPCol_ListOfShape &aLSx=aMSx.FindFromKey(aSI);
684       aNbSx=aLSx.Extent();
685       if (aNbSx) {
686         aMSI.Remove(aSI);
687       }
688     }
689   }
690   //
691   // 4. Just check it
692   aNbSI=aMSI.Extent();
693   if (!aNbSI) {
694     return;
695   }
696   //
697   // 5 Settle internal vertices and edges into solids
698   aMx.Clear();
699   aIt.Initialize(aLSd);
700   for (; aIt.More(); aIt.Next()) {
701     TopoDS_Solid aSd=TopoDS::Solid(aIt.Value());
702     //
703     aItM.Initialize(aMSI); 
704     for (; aItM.More(); aItM.Next()) {
705       TopoDS_Shape aSI=aItM.Key();
706       aSI.Orientation(TopAbs_INTERNAL);
707       //
708       aState=BOPTools_AlgoTools::ComputeStateByOnePoint(aSI, aSd, 1.e-11, myContext);
709       if (aState==TopAbs_IN) {
710         //
711         if(aMSOr.Contains(aSd)) {
712           //
713           TopoDS_Solid aSdx;
714           //
715           aBB.MakeSolid(aSdx);
716           aItS.Initialize(aSd);
717           for (; aItS.More(); aItS.Next()) {
718             const TopoDS_Shape& aSh=aItS.Value();
719             aBB.Add(aSdx, aSh);
720           }
721           //
722           aBB.Add(aSdx, aSI);
723           //
724           if (myImages.IsBound(aSdx)) {
725             BOPCol_ListOfShape& aLS=myImages.ChangeFind(aSdx);
726             aLS.Append(aSdx);
727           } 
728           else {
729             BOPCol_ListOfShape aLS;
730             aLS.Append(aSdx);
731             myImages.Bind(aSd, aLS);
732           }
733           //
734           aMSOr.Remove(aSd);
735           aSd=aSdx;
736         }
737         else {
738           aBB.Add(aSd, aSI);
739         }
740         //
741         aMSI.Remove(aSI);
742       } //if (aState==TopAbs_IN) {
743     }// for (; aItM.More(); aItM.Next()) {
744   }//for (; aIt1.More(); aIt1.Next()) {
745   //
746   //-----------------------------------------------------scope t
747   aLArgs.Clear();
748   aLSd.Clear();
749   aMSOr.Clear();
750   aMFence.Clear();
751   aMSI.Clear();
752   aMx.Clear();
753   aMSx.Clear();
754 }
755 //=======================================================================
756 //function : OwnInternalShapes
757 //purpose  : 
758 //=======================================================================
759   void OwnInternalShapes(const TopoDS_Shape& theS,
760                          BOPCol_IndexedMapOfShape& theMx)
761 {
762   TopoDS_Iterator aIt;
763   //
764   aIt.Initialize(theS);
765   for (; aIt.More(); aIt.Next()) {
766     const TopoDS_Shape& aSx=aIt.Value();
767     if (aSx.ShapeType()!=TopAbs_SHELL) {
768       theMx.Add(aSx);
769     }
770   }
771 }
772 //
773 // ErrorStatus
774 // 30 - SolidBuilder failed
775 // A
776 /*
777     {
778       TopoDS_Compound aCx;
779       BRep_Builder aBBx;
780       BOPCol_ListIteratorOfListOfShape aItx;
781       //
782       aBBx.MakeCompound(aCx);
783       aItx.Initialize(aSFS1);
784       for (; aItx.More(); aItx.Next()) {
785       const TopoDS_Shape& aFx=aItx.Value();
786       aBBx.Add(aCx, aFx);
787       }
788       BRepTools::Write(aCx, "cxso");
789       int a=0;
790     }
791     */