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