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