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