0030145: Modeling Algorithms - Boolean Operations on open solids
[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 // Functors to split solids
345 typedef BOPTools_Functor<BOPAlgo_SplitSolid,
346                        BOPAlgo_VectorOfBuilderSolid> BOPAlgo_BuilderSolidFunctor;
347 //
348 typedef BOPTools_Cnt<BOPAlgo_BuilderSolidFunctor,
349                    BOPAlgo_VectorOfBuilderSolid> BOPAlgo_BuilderSolidCnt;
350 //=======================================================================
351
352 //=======================================================================
353 //function : BuildSplitSolids
354 //purpose  : 
355 //=======================================================================
356 void BOPAlgo_Builder::BuildSplitSolids(TopTools_DataMapOfShapeShape& theDraftSolids)
357 {
358   Standard_Boolean bFlagSD;
359   Standard_Integer i, aNbS;
360   TopExp_Explorer aExp;
361   TopTools_ListIteratorOfListOfShape aIt;
362   //
363   Handle(NCollection_BaseAllocator) aAlr0;
364   aAlr0=NCollection_BaseAllocator::CommonBaseAllocator();
365   //
366   TopTools_ListOfShape aSFS(aAlr0), aLSEmpty(aAlr0);
367   TopTools_MapOfShape aMFence(100, aAlr0);
368   BOPTools_MapOfSet aMST(100, aAlr0);
369   BOPAlgo_VectorOfBuilderSolid aVBS;
370   //
371   // 0. Find same domain solids for non-interfered solids
372   aNbS=myDS->NbSourceShapes();
373   for (i=0; i<aNbS; ++i) {
374     const BOPDS_ShapeInfo& aSI=myDS->ShapeInfo(i);
375     //
376     if (aSI.ShapeType()!=TopAbs_SOLID) {
377       continue;
378     }
379     //
380     const TopoDS_Shape& aS=aSI.Shape();
381     if (!aMFence.Add(aS)) {
382       continue;
383     }
384     if(theDraftSolids.IsBound(aS)) {
385       continue;
386     }
387     //
388     BOPTools_Set aST;
389     //
390     aST.Add(aS, TopAbs_FACE);
391     aMST.Add(aST);
392     //
393   } //for (i=1; i<=aNbS; ++i) 
394   //
395   // Build temporary map of solids images to avoid rebuilding
396   // of the solids without internal faces
397   TopTools_IndexedDataMapOfShapeListOfShape aSolidsIm;
398   // 1. Build solids for interfered source solids
399   for (i = 0; i < aNbS; ++i) {
400     const BOPDS_ShapeInfo& aSI = myDS->ShapeInfo(i);
401     if (aSI.ShapeType() != TopAbs_SOLID)
402       continue;
403
404     const TopoDS_Shape& aS = aSI.Shape();
405     const TopoDS_Solid& aSolid=(*(TopoDS_Solid*)(&aS));
406     if (!theDraftSolids.IsBound(aS))
407       continue;
408
409     const TopoDS_Shape& aSD = theDraftSolids.Find(aS);
410     const TopTools_ListOfShape* pLFIN = myInParts.Seek(aS);
411     if (!pLFIN || pLFIN->IsEmpty())
412     {
413       aSolidsIm(aSolidsIm.Add(aS, TopTools_ListOfShape())).Append(aSD);
414       continue;
415     }
416
417     aSFS.Clear();
418     //
419     // 1.1 Fill Shell Faces Set
420     aExp.Init(aSD, TopAbs_FACE);
421     for (; aExp.More(); aExp.Next()) {
422       const TopoDS_Shape& aF = aExp.Current();
423       aSFS.Append(aF);
424     }
425     //
426     // 1.2 Fill internal faces
427     aIt.Initialize(*pLFIN);
428     for (; aIt.More(); aIt.Next()) {
429       TopoDS_Shape aF = aIt.Value();
430       //
431       aF.Orientation(TopAbs_FORWARD);
432       aSFS.Append(aF);
433       aF.Orientation(TopAbs_REVERSED);
434       aSFS.Append(aF);
435     }
436     //
437     // 1.3 Build new solids
438     BOPAlgo_SplitSolid& aBS=aVBS.Appended();
439     aBS.SetSolid(aSolid);
440     aBS.SetShapes(aSFS);
441     aBS.SetRunParallel(myRunParallel);
442     aBS.SetProgressIndicator(myProgressIndicator);
443   }//for (i=0; i<aNbS; ++i) {
444   //
445   Standard_Integer k, aNbBS;
446   //
447   aNbBS=aVBS.Length();
448   //
449   //===================================================
450   BOPAlgo_BuilderSolidCnt::Perform(myRunParallel, aVBS);
451   //===================================================
452   //
453   for (k = 0; k < aNbBS; ++k)
454   {
455     BOPAlgo_SplitSolid& aBS = aVBS(k);
456     aSolidsIm.Add(aBS.Solid(), aBS.Areas());
457
458     // Merge BuilderSolid's report into main report,
459     // assigning the solid with the warnings/errors which
460     // have been generated for it.
461     // Convert all errors of BuilderSolid into warnings for main report.
462     const Handle(Message_Report)& aBSReport = aBS.GetReport();
463     Message_Gravity anAlertTypes[2] = { Message_Warning, Message_Fail };
464     for (Standard_Integer iGravity = 0; iGravity < 2; iGravity++)
465     {
466       const Message_ListOfAlert& anLAlerts = aBSReport->GetAlerts(anAlertTypes[iGravity]);
467       for (Message_ListOfAlert::Iterator itA(anLAlerts); itA.More(); itA.Next())
468       {
469         Handle(Message_Alert) anAlert = itA.Value();
470
471         Handle(TopoDS_AlertWithShape) anAlertWithShape = Handle(TopoDS_AlertWithShape)::DownCast(itA.Value());
472         if (!anAlertWithShape.IsNull())
473         {
474           TopoDS_Shape aWarnShape;
475           BRep_Builder().MakeCompound(TopoDS::Compound(aWarnShape));
476           BRep_Builder().Add(aWarnShape, aBS.Solid());
477           BRep_Builder().Add(aWarnShape, anAlertWithShape->GetShape());
478
479           anAlertWithShape->SetShape(aWarnShape);
480           AddWarning(anAlertWithShape);
481         }
482         else
483           AddWarning(anAlert);
484       }
485     }
486   }
487   //
488   // Add new solids to images map
489   aNbBS = aSolidsIm.Extent();
490   for (k = 1; k <= aNbBS; ++k)
491   {
492     const TopoDS_Shape& aS = aSolidsIm.FindKey(k);
493     const TopTools_ListOfShape& aLSR = aSolidsIm(k);
494     //
495     if (!myImages.IsBound(aS)) {
496       TopTools_ListOfShape* pLSx = myImages.Bound(aS, TopTools_ListOfShape());
497       //
498       aIt.Initialize(aLSR);
499       for (; aIt.More(); aIt.Next()) {
500         BOPTools_Set aST;
501         //
502         const TopoDS_Shape& aSR=aIt.Value();
503         aST.Add(aSR, TopAbs_FACE);
504         //
505         bFlagSD=aMST.Contains(aST);
506         //
507         const BOPTools_Set& aSTx=aMST.Added(aST);
508         const TopoDS_Shape& aSx=aSTx.Shape();
509         pLSx->Append(aSx);
510         //
511         TopTools_ListOfShape* pLOr = myOrigins.ChangeSeek(aSx);
512         if (!pLOr) {
513           pLOr = myOrigins.Bound(aSx, TopTools_ListOfShape());
514         }
515         pLOr->Append(aS);
516         //
517         if (bFlagSD) {
518           myShapesSD.Bind(aSR, aSx);
519         }
520       }
521     }
522   }
523 }
524 //=======================================================================
525 //function :FillInternalShapes 
526 //purpose  : 
527 //=======================================================================
528 void BOPAlgo_Builder::FillInternalShapes()
529 {
530   Standard_Integer i, j,  aNbS, aNbSI, aNbSx;
531   TopAbs_ShapeEnum aType;
532   TopAbs_State aState; 
533   TopoDS_Iterator aItS;
534   BRep_Builder aBB;
535   TopTools_ListIteratorOfListOfShape aIt, aIt1;
536   //
537   Handle(NCollection_BaseAllocator) aAllocator;
538   //-----------------------------------------------------scope f
539   aAllocator=NCollection_BaseAllocator::CommonBaseAllocator();
540   //
541   TopTools_IndexedDataMapOfShapeListOfShape aMSx(100, aAllocator);
542   TopTools_IndexedMapOfShape aMx(100, aAllocator);
543   TopTools_IndexedMapOfShape aMSI(100, aAllocator);
544   TopTools_MapOfShape aMFence(100, aAllocator);
545   TopTools_MapOfShape aMSOr(100, aAllocator);
546   TopTools_ListOfShape aLSd(aAllocator);
547   TopTools_ListOfShape aLArgs(aAllocator);
548   TopTools_ListOfShape aLSC(aAllocator);
549   TopTools_ListOfShape aLSI(aAllocator);
550   //
551   // 1. Shapes to process
552   //
553   // 1.1 Shapes from pure arguments aMSI 
554   // 1.1.1 vertex, edge, wire
555   //
556   const TopTools_ListOfShape& aArguments=myDS->Arguments();
557   aIt.Initialize(aArguments);
558   for (; aIt.More(); aIt.Next()) {
559     const TopoDS_Shape& aS=aIt.Value();
560     BOPAlgo_Tools::TreatCompound(aS, aMFence, aLSC);
561   }
562   aIt.Initialize(aLSC);
563   for (; aIt.More(); aIt.Next()) {
564     const TopoDS_Shape& aS=aIt.Value();
565     aType=aS.ShapeType();
566     if (aType==TopAbs_WIRE) {
567       aItS.Initialize(aS);
568       for(; aItS.More(); aItS.Next()) {
569         const TopoDS_Shape& aE=aItS.Value();
570         if (aMFence.Add(aE)) {
571           aLArgs.Append(aE);
572         }
573       }
574     }
575     else if (aType==TopAbs_VERTEX || aType==TopAbs_EDGE){
576       aLArgs.Append(aS);
577     } 
578   }
579   aMFence.Clear();
580   //
581   aIt.Initialize(aLArgs);
582   for (; aIt.More(); aIt.Next()) {
583     const TopoDS_Shape& aS=aIt.Value();
584     aType=aS.ShapeType();
585     if (aType==TopAbs_VERTEX || 
586         aType==TopAbs_EDGE ||
587         aType==TopAbs_WIRE) {
588       if (aMFence.Add(aS)) {
589         if (myImages.IsBound(aS)) {
590           const TopTools_ListOfShape &aLSp=myImages.Find(aS);
591           aIt1.Initialize(aLSp);
592           for (; aIt1.More(); aIt1.Next()) {
593             const TopoDS_Shape& aSp=aIt1.Value();
594             aMSI.Add(aSp);
595           }
596         }
597         else {
598           aMSI.Add(aS);
599         }
600       }
601     }
602   }
603   
604   aNbSI=aMSI.Extent();
605   //
606   // 2. Internal vertices, edges from source solids
607   aMFence.Clear();
608   aLSd.Clear();
609   //
610   aNbS=myDS->NbSourceShapes();
611   for (i=0; i<aNbS; ++i) {
612     const BOPDS_ShapeInfo& aSI=myDS->ShapeInfo(i);
613     //
614     if (aSI.ShapeType()!=TopAbs_SOLID) {
615       continue;
616     }
617     //
618     UserBreak();
619     //
620     const TopoDS_Shape& aS=aSI.Shape();
621     //
622     aMx.Clear();
623     OwnInternalShapes(aS, aMx);
624     //
625     aNbSx=aMx.Extent();
626     for (j=1; j<=aNbSx; ++j) {
627       const TopoDS_Shape& aSi=aMx(j);
628       if (myImages.IsBound(aSi)) {
629         const TopTools_ListOfShape &aLSp=myImages.Find(aSi);
630         aIt1.Initialize(aLSp);
631         for (; aIt1.More(); aIt1.Next()) {
632           const TopoDS_Shape& aSp=aIt1.Value();
633           aMSI.Add(aSp);
634         }
635       }
636       else {
637         aMSI.Add(aSi);
638       }
639     }
640     //
641     // build aux map from splits of solids
642     if (myImages.IsBound(aS)) {
643       const TopTools_ListOfShape &aLSp=myImages.Find(aS);
644       aIt.Initialize(aLSp);
645       for (; aIt.More(); aIt.Next()) {
646         const TopoDS_Shape& aSp=aIt.Value();
647         if (aMFence.Add(aSp)) { 
648           TopExp::MapShapesAndAncestors(aSp, TopAbs_VERTEX, TopAbs_EDGE, aMSx);
649           TopExp::MapShapesAndAncestors(aSp, TopAbs_VERTEX, TopAbs_FACE, aMSx);
650           TopExp::MapShapesAndAncestors(aSp, TopAbs_EDGE  , TopAbs_FACE, aMSx);
651           aLSd.Append(aSp);
652         }
653       }
654     }
655     else {
656       if (aMFence.Add(aS)) {
657         TopExp::MapShapesAndAncestors(aS, TopAbs_VERTEX, TopAbs_EDGE, aMSx);
658         TopExp::MapShapesAndAncestors(aS, TopAbs_VERTEX, TopAbs_FACE, aMSx);
659         TopExp::MapShapesAndAncestors(aS, TopAbs_EDGE  , TopAbs_FACE, aMSx);
660         aLSd.Append(aS);
661         aMSOr.Add(aS); 
662       }
663     }
664   }// for (i=0; i<aNbS; ++i) {
665   //
666   // 3. Some shapes of aMSI can be already tied with faces of 
667   //    split solids
668   aNbSI = aMSI.Extent();
669   for (i = 1; i <= aNbSI; ++i) {
670     const TopoDS_Shape& aSI = aMSI(i);
671     if (aMSx.Contains(aSI)) {
672       const TopTools_ListOfShape &aLSx=aMSx.FindFromKey(aSI);
673       aNbSx = aLSx.Extent();
674       if (!aNbSx) {
675         aLSI.Append(aSI);
676       }
677     }
678     else {
679       aLSI.Append(aSI);
680     }
681   }
682   //
683   // 4. Just check it
684   aNbSI = aLSI.Extent();
685   if (!aNbSI) {
686     return;
687   }
688   //
689   // 5 Settle internal vertices and edges into solids
690   aMx.Clear();
691   aIt.Initialize(aLSd);
692   for (; aIt.More(); aIt.Next()) {
693     TopoDS_Solid aSd=TopoDS::Solid(aIt.Value());
694     //
695     aIt1.Initialize(aLSI);
696     for (; aIt1.More();) {
697       TopoDS_Shape aSI = aIt1.Value();
698       aSI.Orientation(TopAbs_INTERNAL);
699       //
700       aState=BOPTools_AlgoTools::ComputeStateByOnePoint
701         (aSI, aSd, 1.e-11, myContext);
702       //
703       if (aState != TopAbs_IN) {
704         aIt1.Next();
705         continue;
706       }
707       //
708       if (aMSOr.Contains(aSd)) {
709         // make new solid
710         TopoDS_Solid aSdx;
711         //
712         aBB.MakeSolid(aSdx);
713         aItS.Initialize(aSd);
714         for (; aItS.More(); aItS.Next()) {
715           const TopoDS_Shape& aSh=aItS.Value();
716           aBB.Add(aSdx, aSh);
717         }
718         //
719         aBB.Add(aSdx, aSI);
720         //
721         // no need to check for images of aSd as aMSOr contains only original solids
722         TopTools_ListOfShape* pLS = myImages.Bound(aSd, TopTools_ListOfShape());
723         pLS->Append(aSdx);
724         //
725         TopTools_ListOfShape* pLOr = myOrigins.Bound(aSdx, TopTools_ListOfShape());
726         pLOr->Append(aSd);
727         //
728         aMSOr.Remove(aSd);
729         aSd=aSdx;
730       }
731       else {
732         aBB.Add(aSd, aSI);
733       }
734       //
735       aLSI.Remove(aIt1);
736     }//for (; aIt1.More();) {
737   }//for (; aIt.More(); aIt.Next()) {
738   //
739   //-----------------------------------------------------scope t
740   aLArgs.Clear();
741   aLSd.Clear();
742   aMSOr.Clear();
743   aMFence.Clear();
744   aMSI.Clear();
745   aMx.Clear();
746   aMSx.Clear();
747 }
748 //=======================================================================
749 //function : OwnInternalShapes
750 //purpose  : 
751 //=======================================================================
752 void OwnInternalShapes(const TopoDS_Shape& theS,
753                        TopTools_IndexedMapOfShape& theMx)
754 {
755   TopoDS_Iterator aIt;
756   //
757   aIt.Initialize(theS);
758   for (; aIt.More(); aIt.Next()) {
759     const TopoDS_Shape& aSx=aIt.Value();
760     if (aSx.ShapeType()!=TopAbs_SHELL) {
761       theMx.Add(aSx);
762     }
763   }
764 }