942b92b2cc029e54cae22c9364317d4011a78eeb
[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 <Bnd_Box.hxx>
23 #include <TopAbs_State.hxx>
24 //
25 #include <TopoDS.hxx>
26 #include <TopoDS_Iterator.hxx>
27 #include <TopoDS_Solid.hxx>
28 #include <TopoDS_Shape.hxx>
29 #include <TopoDS_Face.hxx>
30 #include <TopoDS_Edge.hxx>
31 #include <TopoDS_Solid.hxx>
32 #include <TopoDS_Shell.hxx>
33 #include <TopoDS_Compound.hxx>
34 //
35 #include <TopExp.hxx>
36 #include <TopExp_Explorer.hxx>
37 //
38 #include <BRep_Builder.hxx>
39 //
40 #include <BOPAlgo_Tools.hxx>
41 #include <BOPAlgo_BuilderSolid.hxx>
42 //
43 #include <IntTools_Context.hxx>
44 //
45 #include <BOPDS_DS.hxx>
46 #include <BOPDS_ShapeInfo.hxx>
47 //
48 #include <BOPTools_AlgoTools.hxx>
49 #include <BOPTools_MapOfSet.hxx>
50 #include <BOPTools_Set.hxx>
51 #include <BOPTools_Parallel.hxx>
52 //
53 #include <BOPAlgo_Tools.hxx>
54 #include <NCollection_Array1.hxx>
55 #include <NCollection_IncAllocator.hxx>
56 #include <NCollection_Vector.hxx>
57
58 #include <TopTools_IndexedMapOfShape.hxx>
59 #include <TopTools_MapOfShape.hxx>
60 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
61 #include <TopTools_IndexedDataMapOfShapeShape.hxx>
62 #include <TopTools_ListOfShape.hxx>
63
64 #include <algorithm>
65
66 static
67   void OwnInternalShapes(const TopoDS_Shape& ,
68                          TopTools_IndexedMapOfShape& );
69
70
71 //=======================================================================
72 //function : FillImagesSolids
73 //purpose  : 
74 //=======================================================================
75 void BOPAlgo_Builder::FillImagesSolids()
76 {
77   Standard_Boolean bHasSolids;
78   Standard_Integer i, aNbS;
79   //
80   bHasSolids=Standard_False;
81   aNbS=myDS->NbSourceShapes();
82   for (i=0; i<aNbS; ++i) {
83     const BOPDS_ShapeInfo& aSI=myDS->ShapeInfo(i);
84     if (aSI.ShapeType()==TopAbs_SOLID) {
85       bHasSolids=!bHasSolids;
86       break;
87     }
88   }
89   //
90   if (!bHasSolids) {
91     return;
92   }
93   // 
94   Handle(NCollection_BaseAllocator) aAlr;
95   //
96   aAlr=NCollection_BaseAllocator::CommonBaseAllocator();
97   //
98   TopTools_DataMapOfShapeListOfShape theInParts(100, aAlr);
99   TopTools_DataMapOfShapeShape theDraftSolids(100, aAlr);
100   //
101   FillIn3DParts(theInParts, theDraftSolids, aAlr); 
102   BuildSplitSolids(theInParts, theDraftSolids, aAlr);
103   FillInternalShapes();
104   //
105   theInParts.Clear();
106   theDraftSolids.Clear();
107 }
108 //=======================================================================
109 //function : FillIn3DParts
110 //purpose  : 
111 //=======================================================================
112 void BOPAlgo_Builder::FillIn3DParts
113   (TopTools_DataMapOfShapeListOfShape& theInParts,
114    TopTools_DataMapOfShapeShape& theDraftSolids,
115    const Handle(NCollection_BaseAllocator)& )
116 {
117   Handle(NCollection_BaseAllocator) anAlloc = new NCollection_IncAllocator;
118
119   // Find all faces that are IN solids
120
121   // Store boxes of the shapes into a map
122   TopTools_DataMapOfShapeBox aShapeBoxMap(1, anAlloc);
123
124   // Fence map
125   TopTools_MapOfShape aMFence(1, anAlloc);
126
127   // Get all faces
128   TopTools_ListOfShape aLFaces(anAlloc);
129
130   Standard_Integer i, aNbS = myDS->NbSourceShapes();
131   for (i = 0; i < aNbS; ++i)
132   {
133     const BOPDS_ShapeInfo& aSI = myDS->ShapeInfo(i);
134     if (aSI.ShapeType() != TopAbs_FACE)
135       continue;
136
137     const TopoDS_Shape& aS = aSI.Shape();
138     const TopTools_ListOfShape* pLSIm = myImages.Seek(aS);
139
140     if (pLSIm)
141     {
142       TopTools_ListIteratorOfListOfShape aItLSIm(*pLSIm);
143       for (; aItLSIm.More(); aItLSIm.Next())
144       {
145         const TopoDS_Shape& aSIm = aItLSIm.Value();
146         if (aMFence.Add(aSIm))
147           aLFaces.Append(aSIm);
148       }
149     }
150     else
151     {
152       aLFaces.Append(aS);
153       aShapeBoxMap.Bind(aS, aSI.Box());
154     }
155   }
156
157   BRep_Builder aBB;
158
159   // Get all solids
160   TopTools_ListOfShape aLSolids(anAlloc);
161   // Keep INTERNAL faces of the solids
162   TopTools_DataMapOfShapeListOfShape aSolidsIF(1, anAlloc);
163   // Draft solids
164   TopTools_IndexedDataMapOfShapeShape aDraftSolid(1, anAlloc);
165
166   for (i = 0; i < aNbS; ++i)
167   {
168     BOPDS_ShapeInfo& aSI = myDS->ChangeShapeInfo(i);
169     if (aSI.ShapeType() != TopAbs_SOLID)
170       continue;
171
172     const TopoDS_Shape& aS = aSI.Shape();
173     const TopoDS_Solid& aSolid = (*(TopoDS_Solid*)(&aS));
174     //
175     // Bounding box for the solid aS
176     Bnd_Box& aBoxS = aSI.ChangeBox();
177     if (aBoxS.IsVoid())
178       myDS->BuildBndBoxSolid(i, aBoxS, myCheckInverted);
179
180     // Build Draft Solid
181     TopTools_ListOfShape aLIF;
182     TopoDS_Solid aSD;
183     aBB.MakeSolid(aSD);
184     BuildDraftSolid(aSolid, aSD, aLIF);
185
186     aLSolids.Append(aSD);
187     aSolidsIF.Bind(aSD, aLIF);
188     aShapeBoxMap.Bind(aSD, aBoxS);
189     aDraftSolid.Add(aS, aSD);
190   }
191
192   // Perform classification of the faces
193   TopTools_IndexedDataMapOfShapeListOfShape anInParts;
194
195   BOPAlgo_Tools::ClassifyFaces(aLFaces, aLSolids, myRunParallel,
196                                myContext, anInParts, aShapeBoxMap, aSolidsIF);
197
198   // Analyze the results of classification
199   Standard_Integer aNbSol = aDraftSolid.Extent();
200   for (i = 1; i <= aNbSol; ++i)
201   {
202     const TopoDS_Solid& aSolid = TopoDS::Solid(aDraftSolid.FindKey(i));
203     const TopoDS_Solid& aSDraft = TopoDS::Solid(aDraftSolid(i));
204     const TopTools_ListOfShape& aLInFaces = anInParts.FindFromKey(aSDraft);
205     const TopTools_ListOfShape& aLInternal = aSolidsIF.Find(aSDraft);
206
207     Standard_Integer aNbIN = aLInFaces.Extent();
208
209     if (!aNbIN)
210     {
211       Standard_Boolean bHasImage = Standard_False;
212       // Check if the shells of the solid have image
213       for (TopoDS_Iterator it(aSolid); it.More() && !bHasImage; it.Next())
214         bHasImage = myImages.IsBound(it.Value());
215
216       if (!bHasImage)
217         // no need to split the solid
218         continue;
219     }
220
221     theDraftSolids.Bind(aSolid, aSDraft);
222
223     Standard_Integer aNbInt = aLInternal.Extent();
224     if (aNbInt || aNbIN)
225     {
226       // Combine the lists
227       TopTools_ListOfShape *pLIN  = theInParts.Bound(aSolid, TopTools_ListOfShape());
228
229       TopTools_ListIteratorOfListOfShape aItLS(aLInFaces);
230       for (; aItLS.More(); aItLS.Next())
231         pLIN->Append(aItLS.Value());
232
233       aItLS.Initialize(aLInternal);
234       for (; aItLS.More(); aItLS.Next())
235         pLIN->Append(aItLS.Value());
236     }
237   }
238 }
239 //=======================================================================
240 //function : BuildDraftSolid
241 //purpose  : 
242 //=======================================================================
243 void BOPAlgo_Builder::BuildDraftSolid(const TopoDS_Shape& theSolid,
244                                       TopoDS_Shape& theDraftSolid,
245                                       TopTools_ListOfShape& theLIF)
246 {
247   Standard_Boolean bToReverse;
248   Standard_Integer iFlag;
249   TopAbs_Orientation aOrF, aOrSh, aOrSd;
250   TopoDS_Iterator aIt1, aIt2;
251   TopoDS_Shell aShD;
252   TopoDS_Shape aFx;
253   BRep_Builder aBB;
254   TopTools_ListIteratorOfListOfShape aItS; 
255   //
256   aOrSd=theSolid.Orientation();
257   theDraftSolid.Orientation(aOrSd);
258   //
259   aIt1.Initialize(theSolid);
260   for (; aIt1.More(); aIt1.Next()) {
261     const TopoDS_Shape& aSh=aIt1.Value();
262     if(aSh.ShapeType()!=TopAbs_SHELL) {
263       continue; // mb internal edges,vertices
264     }
265     //
266     aOrSh=aSh.Orientation();
267     aBB.MakeShell(aShD);
268     aShD.Orientation(aOrSh);
269     iFlag=0;
270     //
271     aIt2.Initialize(aSh);
272     for (; aIt2.More(); aIt2.Next()) {
273       const TopoDS_Shape& aF=aIt2.Value();
274       aOrF=aF.Orientation();
275       //
276       if (myImages.IsBound(aF)) {
277         const TopTools_ListOfShape& aLSp=myImages.Find(aF);
278         aItS.Initialize(aLSp);
279         for (; aItS.More(); aItS.Next()) {
280           aFx=aItS.Value();
281           //
282           if (myShapesSD.IsBound(aFx)) {
283             //
284             if (aOrF==TopAbs_INTERNAL) {
285               aFx.Orientation(aOrF);
286               theLIF.Append(aFx);
287             }
288             else {
289               bToReverse=BOPTools_AlgoTools::IsSplitToReverseWithWarn
290                 (aFx, aF, myContext, myReport);
291               if (bToReverse) {
292                 aFx.Reverse();
293               }
294               //
295               iFlag=1;
296               aBB.Add(aShD, aFx);
297             }
298           }//if (myShapesSD.IsBound(aFx)) {
299           else {
300             aFx.Orientation(aOrF);
301             if (aOrF==TopAbs_INTERNAL) {
302               theLIF.Append(aFx);
303             }
304             else{
305               iFlag=1;
306               aBB.Add(aShD, aFx);
307             }
308           }
309         }
310       } // if (myImages.IsBound(aF)) { 
311       //
312       else {
313         if (aOrF==TopAbs_INTERNAL) {
314           theLIF.Append(aF);
315         }
316         else{
317           iFlag=1;
318           aBB.Add(aShD, aF);
319         }
320       }
321     } //for (; aIt2.More(); aIt2.Next()) {
322     //
323     if (iFlag) {
324       aShD.Closed (BRep_Tool::IsClosed (aShD));
325       aBB.Add(theDraftSolid, aShD);
326     }
327   } //for (; aIt1.More(); aIt1.Next()) {
328 }
329
330 //=======================================================================
331
332 //=======================================================================
333 //class : BOPAlgo_SplitSolid
334 //purpose  : Auxiliary class to extend the BOPAlgo_BuilderSolid with the solid to split
335 //=======================================================================
336 class BOPAlgo_SplitSolid : public BOPAlgo_BuilderSolid
337 {
338 public:
339   //! Sets the solid
340   void SetSolid(const TopoDS_Solid& theSolid) { mySolid = theSolid; }
341
342   //! Returns the solid
343   const TopoDS_Solid& Solid() const { return mySolid; }
344
345 private:
346   TopoDS_Solid mySolid; //!< Solid to split
347 };
348
349 // Vector of Solid Builders
350 typedef NCollection_Vector<BOPAlgo_SplitSolid> BOPAlgo_VectorOfBuilderSolid;
351 // Functors to split solids
352 typedef BOPTools_Functor<BOPAlgo_SplitSolid,
353                        BOPAlgo_VectorOfBuilderSolid> BOPAlgo_BuilderSolidFunctor;
354 //
355 typedef BOPTools_Cnt<BOPAlgo_BuilderSolidFunctor,
356                    BOPAlgo_VectorOfBuilderSolid> BOPAlgo_BuilderSolidCnt;
357 //=======================================================================
358
359 //=======================================================================
360 //function : BuildSplitSolids
361 //purpose  : 
362 //=======================================================================
363 void BOPAlgo_Builder::BuildSplitSolids
364   (TopTools_DataMapOfShapeListOfShape& theInParts,
365    TopTools_DataMapOfShapeShape& theDraftSolids,
366    const Handle(NCollection_BaseAllocator)&  )
367 {
368   Standard_Boolean bFlagSD;
369   Standard_Integer i, aNbS;
370   TopExp_Explorer aExp;
371   TopTools_ListIteratorOfListOfShape aIt;
372   //
373   Handle(NCollection_BaseAllocator) aAlr0;
374   aAlr0=NCollection_BaseAllocator::CommonBaseAllocator();
375   //
376   TopTools_ListOfShape aSFS(aAlr0), aLSEmpty(aAlr0);
377   TopTools_MapOfShape aMFence(100, aAlr0);
378   BOPTools_MapOfSet aMST(100, aAlr0);
379   BOPAlgo_VectorOfBuilderSolid aVBS;
380   //
381   // 0. Find same domain solids for non-interfered solids
382   aNbS=myDS->NbSourceShapes();
383   for (i=0; i<aNbS; ++i) {
384     const BOPDS_ShapeInfo& aSI=myDS->ShapeInfo(i);
385     //
386     if (aSI.ShapeType()!=TopAbs_SOLID) {
387       continue;
388     }
389     //
390     const TopoDS_Shape& aS=aSI.Shape();
391     if (!aMFence.Add(aS)) {
392       continue;
393     }
394     if(theDraftSolids.IsBound(aS)) {
395       continue;
396     }
397     //
398     BOPTools_Set aST;
399     //
400     aST.Add(aS, TopAbs_FACE);
401     aMST.Add(aST);
402     //
403   } //for (i=1; i<=aNbS; ++i) 
404   //
405   // Build temporary map of solids images to avoid rebuilding
406   // of the solids without internal faces
407   TopTools_IndexedDataMapOfShapeListOfShape aSolidsIm;
408   // 1. Build solids for interfered source solids
409   for (i = 0; i < aNbS; ++i) {
410     const BOPDS_ShapeInfo& aSI = myDS->ShapeInfo(i);
411     if (aSI.ShapeType() != TopAbs_SOLID)
412       continue;
413
414     const TopoDS_Shape& aS = aSI.Shape();
415     const TopoDS_Solid& aSolid=(*(TopoDS_Solid*)(&aS));
416     if (!theDraftSolids.IsBound(aS))
417       continue;
418
419     const TopoDS_Shape& aSD = theDraftSolids.Find(aS);
420     const TopTools_ListOfShape* pLFIN = theInParts.Seek(aS);
421     if (!pLFIN || pLFIN->IsEmpty())
422     {
423       aSolidsIm(aSolidsIm.Add(aS, TopTools_ListOfShape())).Append(aSD);
424       continue;
425     }
426
427     aSFS.Clear();
428     //
429     // 1.1 Fill Shell Faces Set
430     aExp.Init(aSD, TopAbs_FACE);
431     for (; aExp.More(); aExp.Next()) {
432       const TopoDS_Shape& aF = aExp.Current();
433       aSFS.Append(aF);
434     }
435     //
436     // 1.2 Fill internal faces
437     aIt.Initialize(*pLFIN);
438     for (; aIt.More(); aIt.Next()) {
439       TopoDS_Shape aF = aIt.Value();
440       //
441       aF.Orientation(TopAbs_FORWARD);
442       aSFS.Append(aF);
443       aF.Orientation(TopAbs_REVERSED);
444       aSFS.Append(aF);
445     }
446     //
447     // 1.3 Build new solids
448     BOPAlgo_SplitSolid& aBS=aVBS.Appended();
449     aBS.SetSolid(aSolid);
450     aBS.SetShapes(aSFS);
451     aBS.SetRunParallel(myRunParallel);
452     aBS.SetProgressIndicator(myProgressIndicator);
453   }//for (i=0; i<aNbS; ++i) {
454   //
455   Standard_Integer k, aNbBS;
456   //
457   aNbBS=aVBS.Length();
458   //
459   //===================================================
460   BOPAlgo_BuilderSolidCnt::Perform(myRunParallel, aVBS);
461   //===================================================
462   //
463   for (k = 0; k < aNbBS; ++k)
464   {
465     BOPAlgo_SplitSolid& aBS = aVBS(k);
466     aSolidsIm.Add(aBS.Solid(), aBS.Areas());
467     myReport->Merge(aBS.GetReport());
468   }
469   //
470   // Add new solids to images map
471   aNbBS = aSolidsIm.Extent();
472   for (k = 1; k <= aNbBS; ++k)
473   {
474     const TopoDS_Shape& aS = aSolidsIm.FindKey(k);
475     const TopTools_ListOfShape& aLSR = aSolidsIm(k);
476     //
477     if (!myImages.IsBound(aS)) {
478       TopTools_ListOfShape* pLSx = myImages.Bound(aS, TopTools_ListOfShape());
479       //
480       aIt.Initialize(aLSR);
481       for (; aIt.More(); aIt.Next()) {
482         BOPTools_Set aST;
483         //
484         const TopoDS_Shape& aSR=aIt.Value();
485         aST.Add(aSR, TopAbs_FACE);
486         //
487         bFlagSD=aMST.Contains(aST);
488         //
489         const BOPTools_Set& aSTx=aMST.Added(aST);
490         const TopoDS_Shape& aSx=aSTx.Shape();
491         pLSx->Append(aSx);
492         //
493         TopTools_ListOfShape* pLOr = myOrigins.ChangeSeek(aSx);
494         if (!pLOr) {
495           pLOr = myOrigins.Bound(aSx, TopTools_ListOfShape());
496         }
497         pLOr->Append(aS);
498         //
499         if (bFlagSD) {
500           myShapesSD.Bind(aSR, aSx);
501         }
502       }
503     }
504   }
505 }
506 //=======================================================================
507 //function :FillInternalShapes 
508 //purpose  : 
509 //=======================================================================
510 void BOPAlgo_Builder::FillInternalShapes()
511 {
512   Standard_Integer i, j,  aNbS, aNbSI, aNbSx;
513   TopAbs_ShapeEnum aType;
514   TopAbs_State aState; 
515   TopoDS_Iterator aItS;
516   BRep_Builder aBB;
517   TopTools_ListIteratorOfListOfShape aIt, aIt1;
518   //
519   Handle(NCollection_BaseAllocator) aAllocator;
520   //-----------------------------------------------------scope f
521   aAllocator=NCollection_BaseAllocator::CommonBaseAllocator();
522   //
523   TopTools_IndexedDataMapOfShapeListOfShape aMSx(100, aAllocator);
524   TopTools_IndexedMapOfShape aMx(100, aAllocator);
525   TopTools_IndexedMapOfShape aMSI(100, aAllocator);
526   TopTools_MapOfShape aMFence(100, aAllocator);
527   TopTools_MapOfShape aMSOr(100, aAllocator);
528   TopTools_ListOfShape aLSd(aAllocator);
529   TopTools_ListOfShape aLArgs(aAllocator);
530   TopTools_ListOfShape aLSC(aAllocator);
531   TopTools_ListOfShape aLSI(aAllocator);
532   //
533   // 1. Shapes to process
534   //
535   // 1.1 Shapes from pure arguments aMSI 
536   // 1.1.1 vertex, edge, wire
537   //
538   const TopTools_ListOfShape& aArguments=myDS->Arguments();
539   aIt.Initialize(aArguments);
540   for (; aIt.More(); aIt.Next()) {
541     const TopoDS_Shape& aS=aIt.Value();
542     BOPAlgo_Tools::TreatCompound(aS, aMFence, aLSC);
543   }
544   aIt.Initialize(aLSC);
545   for (; aIt.More(); aIt.Next()) {
546     const TopoDS_Shape& aS=aIt.Value();
547     aType=aS.ShapeType();
548     if (aType==TopAbs_WIRE) {
549       aItS.Initialize(aS);
550       for(; aItS.More(); aItS.Next()) {
551         const TopoDS_Shape& aE=aItS.Value();
552         if (aMFence.Add(aE)) {
553           aLArgs.Append(aE);
554         }
555       }
556     }
557     else if (aType==TopAbs_VERTEX || aType==TopAbs_EDGE){
558       aLArgs.Append(aS);
559     } 
560   }
561   aMFence.Clear();
562   //
563   aIt.Initialize(aLArgs);
564   for (; aIt.More(); aIt.Next()) {
565     const TopoDS_Shape& aS=aIt.Value();
566     aType=aS.ShapeType();
567     if (aType==TopAbs_VERTEX || 
568         aType==TopAbs_EDGE ||
569         aType==TopAbs_WIRE) {
570       if (aMFence.Add(aS)) {
571         if (myImages.IsBound(aS)) {
572           const TopTools_ListOfShape &aLSp=myImages.Find(aS);
573           aIt1.Initialize(aLSp);
574           for (; aIt1.More(); aIt1.Next()) {
575             const TopoDS_Shape& aSp=aIt1.Value();
576             aMSI.Add(aSp);
577           }
578         }
579         else {
580           aMSI.Add(aS);
581         }
582       }
583     }
584   }
585   
586   aNbSI=aMSI.Extent();
587   //
588   // 2. Internal vertices, edges from source solids
589   aMFence.Clear();
590   aLSd.Clear();
591   //
592   aNbS=myDS->NbSourceShapes();
593   for (i=0; i<aNbS; ++i) {
594     const BOPDS_ShapeInfo& aSI=myDS->ShapeInfo(i);
595     //
596     if (aSI.ShapeType()!=TopAbs_SOLID) {
597       continue;
598     }
599     //
600     UserBreak();
601     //
602     const TopoDS_Shape& aS=aSI.Shape();
603     //
604     aMx.Clear();
605     OwnInternalShapes(aS, aMx);
606     //
607     aNbSx=aMx.Extent();
608     for (j=1; j<=aNbSx; ++j) {
609       const TopoDS_Shape& aSi=aMx(j);
610       if (myImages.IsBound(aSi)) {
611         const TopTools_ListOfShape &aLSp=myImages.Find(aSi);
612         aIt1.Initialize(aLSp);
613         for (; aIt1.More(); aIt1.Next()) {
614           const TopoDS_Shape& aSp=aIt1.Value();
615           aMSI.Add(aSp);
616         }
617       }
618       else {
619         aMSI.Add(aSi);
620       }
621     }
622     //
623     // build aux map from splits of solids
624     if (myImages.IsBound(aS)) {
625       const TopTools_ListOfShape &aLSp=myImages.Find(aS);
626       aIt.Initialize(aLSp);
627       for (; aIt.More(); aIt.Next()) {
628         const TopoDS_Shape& aSp=aIt.Value();
629         if (aMFence.Add(aSp)) { 
630           TopExp::MapShapesAndAncestors(aSp, TopAbs_VERTEX, TopAbs_EDGE, aMSx);
631           TopExp::MapShapesAndAncestors(aSp, TopAbs_VERTEX, TopAbs_FACE, aMSx);
632           TopExp::MapShapesAndAncestors(aSp, TopAbs_EDGE  , TopAbs_FACE, aMSx);
633           aLSd.Append(aSp);
634         }
635       }
636     }
637     else {
638       if (aMFence.Add(aS)) {
639         TopExp::MapShapesAndAncestors(aS, TopAbs_VERTEX, TopAbs_EDGE, aMSx);
640         TopExp::MapShapesAndAncestors(aS, TopAbs_VERTEX, TopAbs_FACE, aMSx);
641         TopExp::MapShapesAndAncestors(aS, TopAbs_EDGE  , TopAbs_FACE, aMSx);
642         aLSd.Append(aS);
643         aMSOr.Add(aS); 
644       }
645     }
646   }// for (i=0; i<aNbS; ++i) {
647   //
648   // 3. Some shapes of aMSI can be already tied with faces of 
649   //    split solids
650   aNbSI = aMSI.Extent();
651   for (i = 1; i <= aNbSI; ++i) {
652     const TopoDS_Shape& aSI = aMSI(i);
653     if (aMSx.Contains(aSI)) {
654       const TopTools_ListOfShape &aLSx=aMSx.FindFromKey(aSI);
655       aNbSx = aLSx.Extent();
656       if (!aNbSx) {
657         aLSI.Append(aSI);
658       }
659     }
660     else {
661       aLSI.Append(aSI);
662     }
663   }
664   //
665   // 4. Just check it
666   aNbSI = aLSI.Extent();
667   if (!aNbSI) {
668     return;
669   }
670   //
671   // 5 Settle internal vertices and edges into solids
672   aMx.Clear();
673   aIt.Initialize(aLSd);
674   for (; aIt.More(); aIt.Next()) {
675     TopoDS_Solid aSd=TopoDS::Solid(aIt.Value());
676     //
677     aIt1.Initialize(aLSI);
678     for (; aIt1.More();) {
679       TopoDS_Shape aSI = aIt1.Value();
680       aSI.Orientation(TopAbs_INTERNAL);
681       //
682       aState=BOPTools_AlgoTools::ComputeStateByOnePoint
683         (aSI, aSd, 1.e-11, myContext);
684       //
685       if (aState != TopAbs_IN) {
686         aIt1.Next();
687         continue;
688       }
689       //
690       if (aMSOr.Contains(aSd)) {
691         // make new solid
692         TopoDS_Solid aSdx;
693         //
694         aBB.MakeSolid(aSdx);
695         aItS.Initialize(aSd);
696         for (; aItS.More(); aItS.Next()) {
697           const TopoDS_Shape& aSh=aItS.Value();
698           aBB.Add(aSdx, aSh);
699         }
700         //
701         aBB.Add(aSdx, aSI);
702         //
703         // no need to check for images of aSd as aMSOr contains only original solids
704         TopTools_ListOfShape* pLS = myImages.Bound(aSd, TopTools_ListOfShape());
705         pLS->Append(aSdx);
706         //
707         TopTools_ListOfShape* pLOr = myOrigins.Bound(aSdx, TopTools_ListOfShape());
708         pLOr->Append(aSd);
709         //
710         aMSOr.Remove(aSd);
711         aSd=aSdx;
712       }
713       else {
714         aBB.Add(aSd, aSI);
715       }
716       //
717       aLSI.Remove(aIt1);
718     }//for (; aIt1.More();) {
719   }//for (; aIt.More(); aIt.Next()) {
720   //
721   //-----------------------------------------------------scope t
722   aLArgs.Clear();
723   aLSd.Clear();
724   aMSOr.Clear();
725   aMFence.Clear();
726   aMSI.Clear();
727   aMx.Clear();
728   aMSx.Clear();
729 }
730 //=======================================================================
731 //function : OwnInternalShapes
732 //purpose  : 
733 //=======================================================================
734 void OwnInternalShapes(const TopoDS_Shape& theS,
735                        TopTools_IndexedMapOfShape& theMx)
736 {
737   TopoDS_Iterator aIt;
738   //
739   aIt.Initialize(theS);
740   for (; aIt.More(); aIt.Next()) {
741     const TopoDS_Shape& aSx=aIt.Value();
742     if (aSx.ShapeType()!=TopAbs_SHELL) {
743       theMx.Add(aSx);
744     }
745   }
746 }