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