0028786: Refactoring of the Warning/Error reporting system of Boolean Operations...
[occt.git] / src / BRepFeat / BRepFeat_Builder.cxx
1 // Created on: 2012-06-01
2 // Created by: Eugeny MALTCHIKOV
3 // Copyright (c) 1999-2014 OPEN CASCADE SAS
4 //
5 // This file is part of Open CASCADE Technology software library.
6 //
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
12 //
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
15
16
17 #include <BOPAlgo_BuilderFace.hxx>
18 #include <BOPCol_DataMapOfShapeListOfShape.hxx>
19 #include <BOPDS_DS.hxx>
20 #include <BOPDS_FaceInfo.hxx>
21 #include <BOPDS_ListOfPave.hxx>
22 #include <BOPDS_ListOfPaveBlock.hxx>
23 #include <BOPDS_MapOfPaveBlock.hxx>
24 #include <BOPDS_Pave.hxx>
25 #include <BOPDS_ShapeInfo.hxx>
26 #include <BOPTools.hxx>
27 #include <BOPTools_AlgoTools.hxx>
28 #include <BOPTools_AlgoTools2D.hxx>
29 #include <BOPTools_AlgoTools3D.hxx>
30 #include <BOPTools_MapOfSet.hxx>
31 #include <BRep_Builder.hxx>
32 #include <BRep_Tool.hxx>
33 #include <BRepBndLib.hxx>
34 #include <BRepFeat_Builder.hxx>
35 #include <Geom_Curve.hxx>
36 #include <IntTools_Tools.hxx>
37 #include <Precision.hxx>
38 #include <TopExp_Explorer.hxx>
39 #include <TopoDS_Edge.hxx>
40 #include <TopoDS_Face.hxx>
41 #include <TopoDS_Shape.hxx>
42 #include <TopTools_ListIteratorOfListOfShape.hxx>
43
44 //=======================================================================
45 //function : 
46 //purpose  : 
47 //=======================================================================
48   BRepFeat_Builder::BRepFeat_Builder()
49 :
50   BOPAlgo_BOP()
51 {
52   Clear();
53 }
54
55 //=======================================================================
56 //function : ~
57 //purpose  : 
58 //=======================================================================
59   BRepFeat_Builder::~BRepFeat_Builder()
60 {
61 }
62
63 //=======================================================================
64 //function : Clear
65 //purpose  : 
66 //=======================================================================
67   void BRepFeat_Builder::Clear()
68 {
69   myShapes.Clear();
70   myRemoved.Clear();
71   BOPAlgo_BOP::Clear();
72 }
73
74 //=======================================================================
75 //function : Init
76 //purpose  : 
77 //=======================================================================
78   void BRepFeat_Builder::Init(const TopoDS_Shape& theShape)
79 {
80   Clear();
81   //
82   AddArgument(theShape);
83 }
84
85 //=======================================================================
86 //function : Init
87 //purpose  : 
88 //=======================================================================
89   void BRepFeat_Builder::Init(const TopoDS_Shape& theShape,
90                               const TopoDS_Shape& theTool)
91 {
92   Clear();
93   //
94   AddArgument(theShape);
95   AddTool(theTool);
96 }
97
98 //=======================================================================
99 //function : SetOperation
100 //purpose  : 
101 //=======================================================================
102   void BRepFeat_Builder::SetOperation(const Standard_Integer theFuse)
103 {
104   myFuse = theFuse;
105   myOperation = myFuse ? BOPAlgo_FUSE : BOPAlgo_CUT;
106 }
107
108 //=======================================================================
109 //function : SetOperation
110 //purpose  : 
111 //=======================================================================
112   void BRepFeat_Builder::SetOperation(const Standard_Integer theFuse,
113                                       const Standard_Boolean theFlag)
114 {
115   myFuse = theFuse;
116   if (!theFlag) {
117     myOperation = myFuse ? BOPAlgo_FUSE : BOPAlgo_CUT;
118   } else {  
119     myOperation = myFuse ? BOPAlgo_CUT21 : BOPAlgo_COMMON;
120   }
121 }
122
123 //=======================================================================
124 //function : PartsOfTool
125 //purpose  : 
126 //=======================================================================
127   void BRepFeat_Builder::PartsOfTool(TopTools_ListOfShape& aLT)
128 {
129   TopExp_Explorer aExp;
130   //
131   aLT.Clear();
132   aExp.Init(myShape, TopAbs_SOLID);
133   for (;aExp.More(); aExp.Next()) {
134     const TopoDS_Shape& aS = aExp.Current();
135     aLT.Append(aS);
136   }
137 }
138
139 //=======================================================================
140 //function : KeepPartsOfTool
141 //purpose  : 
142 //=======================================================================
143   void BRepFeat_Builder::KeepParts(const TopTools_ListOfShape& theIm)
144 {
145   TopTools_ListIteratorOfListOfShape aItT;
146   aItT.Initialize(theIm);
147   for (; aItT.More(); aItT.Next()) {
148     const TopoDS_Shape& aTIm=aItT.Value();
149     KeepPart(aTIm);
150   }
151 }
152
153 //=======================================================================
154 //function : KeepPart
155 //purpose  : 
156 //=======================================================================
157   void BRepFeat_Builder::KeepPart(const TopoDS_Shape& thePart)
158 {
159   TopoDS_Shape aF, aFOr;
160   TopExp_Explorer aExp;
161   //
162   BOPTools::MapShapes(thePart, myShapes);
163 }
164
165 //=======================================================================
166 //function : Prepare
167 //purpose  : 
168 //=======================================================================
169   void BRepFeat_Builder::Prepare()
170 {
171   GetReport()->Clear();
172   //
173   BRep_Builder aBB;
174   TopoDS_Compound aC;
175   aBB.MakeCompound(aC);
176   myShape=aC;
177   //
178   myFlagHistory=Standard_True;
179   //
180   FillRemoved();
181 }
182
183 //=======================================================================
184 //function : FillRemoved
185 //purpose  : 
186 //=======================================================================
187   void BRepFeat_Builder::FillRemoved()
188 {
189   TopExp_Explorer aExp;
190   //
191   const TopoDS_Shape& aArgs0=myArguments.First();
192   const TopoDS_Shape& aArgs1=myTools.First();
193   //
194   aExp.Init(aArgs0, TopAbs_SOLID);
195   for (; aExp.More(); aExp.Next()) {
196     const TopoDS_Shape& aS = aExp.Current();
197     myImages.UnBind(aS);
198   }
199   //
200   if (!myImages.IsBound(aArgs1)) {
201     return;
202   }
203   //
204   BOPCol_ListIteratorOfListOfShape aItIm;
205   //
206   BOPCol_ListOfShape& aLS = myImages.ChangeFind(aArgs1);
207   aItIm.Initialize(aLS);
208   for (; aItIm.More(); aItIm.Next()) {
209     const TopoDS_Shape& aS = aItIm.Value();
210     FillRemoved(aS, myRemoved);
211   }
212 }
213
214 //=======================================================================
215 //function : PerformResult
216 //purpose  : 
217 //=======================================================================
218   void BRepFeat_Builder::PerformResult()
219 {
220   myOperation = myFuse ? BOPAlgo_FUSE : BOPAlgo_CUT;
221   //
222   if (!myShapes.IsEmpty()) {
223     //
224     Prepare(); 
225     //
226     RebuildFaces();
227     //
228     FillImagesContainers(TopAbs_SHELL);
229     if (HasErrors()) {
230       return;
231     }
232     //
233     FillImagesSolids();
234     if (HasErrors()) {
235       return;
236     }
237     //
238     CheckSolidImages();
239     //
240     BuildResult(TopAbs_SOLID);
241     if (HasErrors()) {
242       return;
243     }
244     // 
245     FillImagesCompounds();
246     if (HasErrors()) {
247       return;
248     }
249     //
250     BuildResult(TopAbs_COMPOUND);
251     if (HasErrors()) {
252       return;
253     }
254   }
255   //
256   BuildShape();
257 }
258
259 //=======================================================================
260 //function : RebuildFaces
261 //purpose  : 
262 //=======================================================================
263   void BRepFeat_Builder::RebuildFaces()
264 {
265   Standard_Integer aNbS, i, iRank, nSp, j;
266   Standard_Boolean bIsClosed, bIsDegenerated, bToReverse,
267                    bRem, bIm, bFlagSD, bVInShapes;
268   TopAbs_Orientation anOriF, anOriE;
269   TopoDS_Face aFF, aFSD;
270   TopoDS_Edge aSp;
271   TopoDS_Shape aSx;
272   TopExp_Explorer aExp, aExpE;
273   BOPCol_MapOfShape aME, aMESplit;
274   BOPCol_ListIteratorOfListOfShape aItIm;
275   BOPDS_MapIteratorOfMapOfPaveBlock aItMPB;
276   BOPCol_MapIteratorOfMapOfShape aItM;
277   BOPTools_MapOfSet aMST;
278   BOPCol_ListOfShape aLE;
279   //
280   aItM.Initialize(myShapes);
281   for (; aItM.More(); aItM.Next()) {
282     const TopoDS_Shape& aS = aItM.Value();
283     if (aS.ShapeType() == TopAbs_FACE) {
284       BOPTools_Set aST;
285       aST.Add(aS, TopAbs_EDGE);
286       aMST.Add(aST);
287     }
288   }
289   //
290   aNbS=myDS->NbSourceShapes();
291   for (i=0; i<aNbS; ++i) {
292     const BOPDS_ShapeInfo& aSI=myDS->ShapeInfo(i);
293     //
294     iRank = myDS->Rank(i);
295     if (iRank == 1) {
296       const TopoDS_Shape& aS = aSI.Shape();
297       //
298       if (myImages.IsBound(aS)) {
299         BOPCol_ListOfShape& aLIm = myImages.ChangeFind(aS);
300         aItIm.Initialize(aLIm);
301         for (; aItIm.More(); ) {
302           const TopoDS_Shape& aSIm = aItIm.Value();
303           if (!myShapes.Contains(aSIm)) {
304             aLIm.Remove(aItIm);
305             continue;
306           }
307           aItIm.Next();
308         }
309       }
310       continue;
311     }
312     //
313     if (aSI.ShapeType()!=TopAbs_FACE) {
314       continue;
315     }
316     //
317     const BOPDS_FaceInfo& aFI=myDS->FaceInfo(i);
318     const TopoDS_Face& aF=(*(TopoDS_Face*)(&aSI.Shape()));
319     //
320     if (!myImages.IsBound(aF)) {
321       continue;
322     }
323     //
324     anOriF=aF.Orientation();
325     aFF=aF;
326     aFF.Orientation(TopAbs_FORWARD);
327
328     const BOPDS_IndexedMapOfPaveBlock& aMPBIn=aFI.PaveBlocksIn();
329     const BOPDS_IndexedMapOfPaveBlock& aMPBSc=aFI.PaveBlocksSc();
330
331     aLE.Clear();
332
333     //bounding edges
334     aExp.Init(aFF, TopAbs_EDGE);
335     for (; aExp.More(); aExp.Next()) {
336       const TopoDS_Edge& aE=(*(TopoDS_Edge*)(&aExp.Current()));
337       anOriE=aE.Orientation();
338       bIsDegenerated=BRep_Tool::Degenerated(aE);
339       bIsClosed=BRep_Tool::IsClosed(aE, aF);
340       if (myImages.IsBound(aE)) {
341         BOPCol_ListOfShape& aLEIm = myImages.ChangeFind(aE);
342         //
343         bRem = Standard_False;
344         bIm = Standard_False;
345         aME.Clear();
346         BOPCol_ListOfShape aLEImNew;
347         //
348         aItIm.Initialize(aLEIm);
349         for (; aItIm.More(); aItIm.Next()) {
350           const TopoDS_Shape& aS = aItIm.Value();
351
352           bVInShapes = Standard_False;
353           if (myShapes.Contains(aS)) {
354             bVInShapes = Standard_True;
355           } else {
356             aExpE.Init(aS, TopAbs_VERTEX);
357             for(;aExpE.More(); aExpE.Next()) {
358               const TopoDS_Shape& aV = aExpE.Current();
359               if (myShapes.Contains(aV)) {
360                 bVInShapes = Standard_True;
361                 break;
362               }
363             }
364           }
365           //
366           if (bVInShapes) {
367             bIm = Standard_True;
368             aLEImNew.Append(aS);
369           } else {
370             bRem = Standard_True;
371             aME.Add(aS);
372           }
373         }
374         //
375         if (!bIm) {
376           aLE.Append(aE);
377           continue;
378         }
379         //
380         if (bRem && bIm) {
381           if (aLEIm.Extent() == 2) {
382             aLE.Append(aE);
383             continue;
384           }
385           if (aMESplit.Add(aE)) {
386             RebuildEdge(aE, aFF, aME, aLEImNew);
387             aLEIm.Assign(aLEImNew);
388             if (aLEIm.Extent() == 1) {
389               aLE.Append(aE);
390               continue;
391             }
392           }
393         }
394         //
395         aItIm.Initialize(aLEIm);
396         for (; aItIm.More(); aItIm.Next()) {
397           aSp = *(TopoDS_Edge*)&aItIm.Value();
398
399           if (bIsDegenerated) {
400             aSp.Orientation(anOriE);
401             aLE.Append(aSp);
402             continue;
403           }
404           //
405           if (anOriE==TopAbs_INTERNAL) {
406             aSp.Orientation(TopAbs_FORWARD);
407             aLE.Append(aSp);
408             aSp.Orientation(TopAbs_REVERSED);
409             aLE.Append(aSp);
410             continue;
411           }
412           //
413           if (bIsClosed) {
414             if (!BRep_Tool::IsClosed(aSp, aFF)){
415               BOPTools_AlgoTools3D::DoSplitSEAMOnFace(aSp, aFF);
416             }
417             //
418             aSp.Orientation(TopAbs_FORWARD);
419             aLE.Append(aSp);
420             aSp.Orientation(TopAbs_REVERSED);
421             aLE.Append(aSp);
422             continue;
423           }// if (bIsClosed){
424           //
425           aSp.Orientation(anOriE);
426           bToReverse=BOPTools_AlgoTools::IsSplitToReverse(aSp, aE, myContext);
427           if (bToReverse) {
428             aSp.Reverse();
429           }
430           aLE.Append(aSp);
431         }
432       }
433       else {
434         aLE.Append(aE);
435       }
436     }
437
438     Standard_Integer aNbPBIn, aNbPBSc;
439     aNbPBIn = aMPBIn.Extent();
440     aNbPBSc = aMPBSc.Extent();
441     //
442     //in edges
443     for (j=1; j<=aNbPBIn; ++j) {
444       const Handle(BOPDS_PaveBlock)& aPB=aMPBIn(j);
445       nSp=aPB->Edge();
446       aSp=(*(TopoDS_Edge*)(&myDS->Shape(nSp)));
447       if (myRemoved.Contains(aSp)) {
448         continue;
449       }
450       //
451       aSp.Orientation(TopAbs_FORWARD);
452       aLE.Append(aSp);
453       aSp.Orientation(TopAbs_REVERSED);
454       aLE.Append(aSp);
455     }
456     //section edges
457     for (j=1; j<=aNbPBSc; ++j) {
458       const Handle(BOPDS_PaveBlock)& aPB=aMPBSc(j);
459       nSp=aPB->Edge();
460       aSp=(*(TopoDS_Edge*)(&myDS->Shape(nSp)));
461       if (myRemoved.Contains(aSp)) {
462         continue;
463       }
464       //
465       aSp.Orientation(TopAbs_FORWARD);
466       aLE.Append(aSp);
467       aSp.Orientation(TopAbs_REVERSED);
468       aLE.Append(aSp);
469     }
470     
471     //build new faces
472     BOPAlgo_BuilderFace aBF;
473     aBF.SetFace(aFF);
474     aBF.SetShapes(aLE);
475     
476     aBF.Perform();
477
478     BOPCol_ListOfShape& aLFIm = myImages.ChangeFind(aF);
479     aLFIm.Clear();
480
481     const BOPCol_ListOfShape& aLFR=aBF.Areas();
482     aItIm.Initialize(aLFR);
483     for (; aItIm.More(); aItIm.Next()) {
484       TopoDS_Shape& aFR=aItIm.ChangeValue();
485       //
486       BOPTools_Set aST;
487       aST.Add(aFR, TopAbs_EDGE);
488       bFlagSD=aMST.Contains(aST);
489       //
490       const BOPTools_Set& aSTx=aMST.Added(aST);
491       aSx=aSTx.Shape();
492       aSx.Orientation(anOriF);
493       aLFIm.Append(aSx);
494       //
495       BOPCol_ListOfShape* pLOr = myOrigins.ChangeSeek(aSx);
496       if (!pLOr) {
497         pLOr = myOrigins.Bound(aSx, BOPCol_ListOfShape());
498       }
499       pLOr->Append(aF);
500       //
501       if (bFlagSD) {
502         myShapesSD.Bind(aFR, aSx);
503       }
504     }
505     //
506     mySplits.Bind(aF, aLFIm); 
507     if (aLFIm.Extent() == 0) {
508       mySplits.UnBind(aF);
509       myImages.UnBind(aF);
510     }
511   }
512 }
513
514 //=======================================================================
515 //function : RebuildEdge
516 //purpose  : 
517 //=======================================================================
518   void BRepFeat_Builder::RebuildEdge(const TopoDS_Shape& theE,
519                                      const TopoDS_Face& theF,
520                                      const BOPCol_MapOfShape& aME,
521                                      BOPCol_ListOfShape& aLIm)
522 {
523   Standard_Integer nE, nSp, nV1, nV2, nE1, nV, nVx, nVSD;
524   Standard_Integer nV11, nV21;
525   Standard_Boolean bOld;
526   Standard_Real aT11, aT21;
527   Standard_Real aT1, aT2;
528   TopoDS_Edge aSp, aE;
529   BOPDS_ShapeInfo aSI;
530   TopoDS_Vertex aV1, aV2;
531   Handle(BOPDS_PaveBlock) aPBNew;
532   BOPCol_MapOfInteger aMI, aMAdd, aMV, aMVOr;
533   BOPDS_ListIteratorOfListOfPaveBlock aItPB;
534   BOPCol_ListIteratorOfListOfShape aIt;
535   BOPCol_ListIteratorOfListOfInteger aItLI;
536   BOPCol_MapIteratorOfMapOfShape aItM;
537   BOPDS_MapOfPaveBlock aMPB;
538   BOPDS_MapIteratorOfMapOfPaveBlock aItMPB;
539   //
540   aSI.SetShapeType(TopAbs_EDGE);
541
542   //1. collect origin vertices to aMV map.
543   nE = myDS->Index(theE);
544   const BOPDS_ShapeInfo& aSIE = myDS->ShapeInfo(nE);
545   const BOPCol_ListOfInteger& aLS = aSIE.SubShapes();
546   aItLI.Initialize(aLS);
547   for(; aItLI.More(); aItLI.Next()) {
548     nV = aItLI.Value();
549     nVx=nV;
550     if (myDS->HasShapeSD(nV, nVSD)) {
551       nVx=nVSD;
552     }
553     aMV.Add(nVx);
554     aMVOr.Add(nVx);
555   }
556   //
557   //2. collect vertices that should be removed to aMI map.
558   aPBNew = new BOPDS_PaveBlock;
559   BOPDS_ListOfPave& aLPExt = aPBNew->ChangeExtPaves();
560   BOPDS_ListOfPaveBlock& aLPB = myDS->ChangePaveBlocks(nE);
561   //
562   for (aItPB.Initialize(aLPB); aItPB.More(); aItPB.Next()) {
563     const Handle(BOPDS_PaveBlock)& aPB = aItPB.Value();
564     nE1 = aPB->Edge();
565     const TopoDS_Shape& aE1 = myDS->Shape(nE1);
566     //
567     if (aME.Contains(aE1)) {
568       aPB->Indices(nV1, nV2);
569       aMI.Add(nV1);
570       aMI.Add(nV2);
571     }
572     else {
573       aMPB.Add(aPB);
574     }
575   }
576   //3. collect vertices that split the source shape.
577   for (aItPB.Initialize(aLPB); aItPB.More(); aItPB.Next()) {
578     const Handle(BOPDS_PaveBlock)& aPB = aItPB.Value();
579     aPB->Indices(nV1, nV2);
580     //
581     if (!aMI.Contains(nV1)) {
582       aMV.Add(nV1);
583     }
584     if (!aMI.Contains(nV2)) {
585       aMV.Add(nV2);
586     }
587   }
588   //4. collect ext paves.
589   for (aItPB.Initialize(aLPB); aItPB.More(); aItPB.Next()) {
590     const Handle(BOPDS_PaveBlock)& aPB = aItPB.Value();
591     aPB->Indices(nV1, nV2);
592     //
593     if (aMV.Contains(nV1)) {
594       if (aMAdd.Add(nV1) || aMVOr.Contains(nV1)) {
595         aLPExt.Append(aPB->Pave1());
596       }
597     }
598     //
599     if (aMV.Contains(nV2)) {
600       if (aMAdd.Add(nV2) || aMVOr.Contains(nV2)) {
601         aLPExt.Append(aPB->Pave2());
602       }
603     }      
604   }
605
606   aE = (*(TopoDS_Edge *)(&theE));
607   aE.Orientation(TopAbs_FORWARD);
608   //
609   aLIm.Clear();
610   //
611   //5. split edge by new set of vertices.
612   aLPB.Clear();
613   aPBNew->SetOriginalEdge(nE);
614   aPBNew->Update(aLPB, Standard_False);
615   //
616   for (aItPB.Initialize(aLPB); aItPB.More(); aItPB.Next()) {
617     Handle(BOPDS_PaveBlock)& aPB = aItPB.ChangeValue();
618     const BOPDS_Pave& aPave1=aPB->Pave1();
619     aPave1.Contents(nV1, aT1);
620     //
621     const BOPDS_Pave& aPave2=aPB->Pave2();
622     aPave2.Contents(nV2, aT2);
623     //
624     aItMPB.Initialize(aMPB);
625     //check if it is the old pave block.
626     bOld = Standard_False;
627     for (; aItMPB.More(); aItMPB.Next()) {
628       const Handle(BOPDS_PaveBlock)& aPB1 = aItMPB.Value();
629       aPB1->Indices(nV11, nV21);
630       aPB1->Range(aT11, aT21);
631       if (nV1 == nV11 && nV2 == nV21 &&
632           aT1 == aT11 && aT2 == aT21) {
633         const TopoDS_Shape& aEIm = myDS->Shape(aPB1->Edge());
634         aLIm.Append(aEIm);
635         bOld = Standard_True;
636         break;
637       }
638     }
639     if (bOld) {
640       continue;
641     }
642     //
643     aV1=(*(TopoDS_Vertex *)(&myDS->Shape(nV1)));
644     aV1.Orientation(TopAbs_FORWARD); 
645     //
646     aV2=(*(TopoDS_Vertex *)(&myDS->Shape(nV2)));
647     aV2.Orientation(TopAbs_REVERSED); 
648     //
649     BOPTools_AlgoTools::MakeSplitEdge(aE, aV1, aT1, aV2, aT2, aSp);
650     BOPTools_AlgoTools2D::BuildPCurveForEdgeOnFace(aSp, theF, myContext);
651     //
652     aSI.SetShape(aSp);
653     //
654     Bnd_Box& aBox=aSI.ChangeBox();
655     BRepBndLib::Add(aSp, aBox);
656     //
657     nSp=myDS->Append(aSI);
658     //
659     aPB->SetEdge(nSp);
660     aLIm.Append(aSp);
661   }
662 }
663
664 //=======================================================================
665 //function : CheckSolidImages
666 //purpose  : 
667 //=======================================================================
668   void BRepFeat_Builder::CheckSolidImages()
669 {
670   BOPTools_MapOfSet aMST;
671   BOPCol_ListOfShape aLSImNew;
672   BOPCol_MapOfShape aMS;
673   BOPCol_ListIteratorOfListOfShape aIt;
674   TopExp_Explorer aExp, aExpF;
675   Standard_Boolean bFlagSD;
676   // 
677   const TopoDS_Shape& aArgs0=myArguments.First();
678   const TopoDS_Shape& aArgs1=myTools.First();
679   //
680   const BOPCol_ListOfShape& aLSIm = myImages.Find(aArgs1);
681   aIt.Initialize(aLSIm);
682   for(;aIt.More();aIt.Next()) {
683     const TopoDS_Shape& aSolIm = aIt.Value();
684     //
685     BOPTools_Set aST;
686     aST.Add(aSolIm, TopAbs_FACE);
687     aMST.Add(aST);
688   }
689   //
690   aExp.Init(aArgs0, TopAbs_SOLID);
691   for(; aExp.More(); aExp.Next()) {
692     const TopoDS_Shape& aSolid = aExp.Current();
693     if (myImages.IsBound(aSolid)) {
694       BOPCol_ListOfShape& aLSImSol = myImages.ChangeFind(aSolid);
695       aIt.Initialize(aLSImSol);
696       for(;aIt.More();aIt.Next()) {
697         const TopoDS_Shape& aSolIm = aIt.Value();
698         //
699         BOPTools_Set aST;
700         aST.Add(aSolIm, TopAbs_FACE);
701         bFlagSD=aMST.Contains(aST);
702         //
703         const BOPTools_Set& aSTx=aMST.Added(aST);
704         const TopoDS_Shape& aSx=aSTx.Shape();
705         aLSImNew.Append(aSx);
706         //
707         if (bFlagSD) {
708           myShapesSD.Bind(aSolIm, aSx);
709         }
710       }
711       aLSImSol.Assign(aLSImNew);
712     }
713   }
714 }
715
716 //=======================================================================
717 //function : MapShapes
718 //purpose  : 
719 //=======================================================================
720   void BRepFeat_Builder::FillRemoved(const TopoDS_Shape& S,  
721                                      BOPCol_MapOfShape& M)
722 {
723   if (myShapes.Contains(S)) {
724     return;
725   }
726   //
727   M.Add(S);
728   TopoDS_Iterator It(S);
729   while (It.More()) {
730     FillRemoved(It.Value(),M);
731     It.Next();
732   }
733 }
734
735 //=======================================================================
736 //function : FillIn3DParts
737 //purpose  : 
738 //=======================================================================
739   void BRepFeat_Builder::FillIn3DParts(BOPCol_DataMapOfShapeListOfShape& theInParts,
740                                        BOPCol_DataMapOfShapeShape& theDraftSolids,
741                                        const Handle(NCollection_BaseAllocator)& theAllocator)
742 {
743   GetReport()->Clear();
744   //
745   Standard_Boolean bIsIN, bHasImage;
746   Standard_Integer aNbS, i, j, aNbFP, aNbFPx, aNbFIN, aNbLIF, aNbEFP;
747   TopAbs_ShapeEnum aType;  
748   TopAbs_State aState;
749   TopoDS_Iterator aIt, aItF;
750   BRep_Builder aBB;
751   TopoDS_Solid aSolidSp; 
752   TopoDS_Face aFP;
753   BOPCol_ListIteratorOfListOfShape aItS, aItFP, aItEx;  
754   BOPCol_MapIteratorOfMapOfShape aItMS, aItMS1;
755   //
756   BOPCol_ListOfShape aLIF(theAllocator);
757   BOPCol_MapOfShape aMFDone(100, theAllocator);
758   BOPCol_MapOfShape aMSolids(100, theAllocator);
759   BOPCol_MapOfShape aMFaces(100, theAllocator);
760   BOPCol_MapOfShape aMFIN(100, theAllocator);
761   BOPCol_IndexedMapOfShape aMS(100, theAllocator);
762   BOPCol_IndexedDataMapOfShapeListOfShape aMEF(100, theAllocator);
763   //
764   theDraftSolids.Clear();
765   //
766   aNbS=myDS->NbSourceShapes();
767   for (i=0; i<aNbS; ++i) {
768     const BOPDS_ShapeInfo& aSI=myDS->ShapeInfo(i);
769     const TopoDS_Shape& aS=aSI.Shape();
770     //
771     aType=aSI.ShapeType();
772     switch(aType) {
773       case TopAbs_SOLID: {
774         aMSolids.Add(aS);
775         break;
776       }
777       //
778       case TopAbs_FACE: {
779         // all faces (originals or images)
780         if (myImages.IsBound(aS)) {
781           const BOPCol_ListOfShape& aLS=myImages.Find(aS);
782           aItS.Initialize(aLS);
783           for (; aItS.More(); aItS.Next()) {
784             const TopoDS_Shape& aFx=aItS.Value();
785             if (!myRemoved.Contains(aFx)) {
786               aMFaces.Add(aFx);
787             }
788           }
789         }
790         else {
791           if (!myRemoved.Contains(aS)) {
792             aMFaces.Add(aS);
793           }
794         }
795         break;
796       }
797       //
798       default:
799         break;
800     }
801   }
802   //
803   aItMS.Initialize(aMSolids);
804   for (; aItMS.More(); aItMS.Next()) {
805     const TopoDS_Solid& aSolid=(*(TopoDS_Solid*)(&aItMS.Value()));
806     //
807     aMFDone.Clear();
808     aMFIN.Clear();
809     aMEF.Clear();
810     //
811     aBB.MakeSolid(aSolidSp);
812     // 
813     // Draft solid and its pure internal faces => aSolidSp, aLIF
814     aLIF.Clear();
815     BuildDraftSolid(aSolid, aSolidSp, aLIF);
816     aNbLIF=aLIF.Extent();
817     //
818     // 1 all faces/edges from aSolid [ aMS ]
819     bHasImage=Standard_False;
820     aMS.Clear();
821     aIt.Initialize(aSolid);
822     for (; aIt.More(); aIt.Next()) {
823       const TopoDS_Shape& aShell=aIt.Value();
824       //
825       if (myImages.IsBound(aShell)) {
826         bHasImage=Standard_True;
827         //
828         const BOPCol_ListOfShape& aLS=myImages.Find(aShell);
829         aItS.Initialize(aLS);
830         for (; aItS.More(); aItS.Next()) {
831           const TopoDS_Shape& aSx=aItS.Value();
832           aMS.Add(aSx);
833           BOPTools::MapShapes(aSx, TopAbs_FACE, aMS);
834           BOPTools::MapShapes(aSx, TopAbs_EDGE, aMS);
835           BOPTools::MapShapesAndAncestors(aSx, TopAbs_EDGE, TopAbs_FACE, aMEF);
836         }
837       }
838       else {
839         //aMS.Add(aShell);
840         BOPTools::MapShapes(aShell, TopAbs_FACE, aMS);
841         BOPTools::MapShapesAndAncestors(aShell, TopAbs_EDGE, TopAbs_FACE, aMEF);
842       }
843     }
844     //
845     // 2 all faces that are not from aSolid [ aLFP1 ]
846     BOPCol_IndexedDataMapOfShapeListOfShape aMEFP(100, theAllocator);
847     BOPCol_ListOfShape aLFP1(theAllocator);
848     BOPCol_ListOfShape aLFP(theAllocator);
849     BOPCol_ListOfShape aLCBF(theAllocator);
850     BOPCol_ListOfShape aLFIN(theAllocator);
851     BOPCol_ListOfShape aLEx(theAllocator);
852     //
853     // for all non-solid faces build EF map [ aMEFP ]
854     aItMS1.Initialize(aMFaces);
855     for (; aItMS1.More(); aItMS1.Next()) {
856       const TopoDS_Shape& aFace=aItMS1.Value();
857       if (!aMS.Contains(aFace)) {
858         BOPTools::MapShapesAndAncestors(aFace, TopAbs_EDGE, TopAbs_FACE, aMEFP);
859       }
860     }
861     //
862     // among all faces from aMEFP select these that have same edges
863     // with the solid (i.e aMEF). These faces will be treated first 
864     // to prevent the usage of 3D classifier.
865     // The full list of faces to process is aLFP1. 
866     aNbEFP=aMEFP.Extent();
867     for (j=1; j<=aNbEFP; ++j) {
868       const TopoDS_Shape& aE=aMEFP.FindKey(j);
869       //
870       if (aMEF.Contains(aE)) { // !!
871         const BOPCol_ListOfShape& aLF=aMEFP(j);
872         aItFP.Initialize(aLF);
873         for (; aItFP.More(); aItFP.Next()) {
874           const TopoDS_Shape& aF=aItFP.Value();
875           if (aMFDone.Add(aF)) {
876             aLFP1.Append(aF);
877           }
878         }
879       }
880       else {
881         aLEx.Append(aE);
882       }
883     }
884     //
885     aItEx.Initialize(aLEx);
886     for (; aItEx.More(); aItEx.Next()) {
887       const TopoDS_Shape& aE=aItEx.Value();
888       const BOPCol_ListOfShape& aLF=aMEFP.FindFromKey(aE);
889       aItFP.Initialize(aLF);
890       for (; aItFP.More(); aItFP.Next()) {
891         const TopoDS_Shape& aF=aItFP.Value();
892         if (aMFDone.Add(aF)) {
893           //aLFP2.Append(aF);
894           aLFP1.Append(aF);
895         }
896       }
897     }
898     //
899     //==========
900     //
901     // 3 Process faces aLFP1
902     aMFDone.Clear();
903     aNbFP=aLFP1.Extent();
904     aItFP.Initialize(aLFP1);
905     for (; aItFP.More(); aItFP.Next()) {
906       const TopoDS_Shape& aSP=aItFP.Value();
907       if (!aMFDone.Add(aSP)) {
908         continue;
909       }
910       
911       //
912       // first face to process
913       aFP=(*(TopoDS_Face*)(&aSP));
914       bIsIN=BOPTools_AlgoTools::IsInternalFace(aFP, aSolidSp, aMEF, 1.e-14, myContext);
915       aState=(bIsIN) ? TopAbs_IN : TopAbs_OUT;
916       //
917       // collect faces to process [ aFP is the first ]
918       aLFP.Clear();
919       aLFP.Append(aFP);
920       aItS.Initialize(aLFP1);
921       for (; aItS.More(); aItS.Next()) {
922         const TopoDS_Shape& aSk=aItS.Value();
923         if (!aMFDone.Contains(aSk)) {
924           aLFP.Append(aSk);
925         }
926       }
927       //
928       // Connexity Block that spreads from aFP the Bound 
929       // or till the end of the block itself
930       aLCBF.Clear();
931       BOPTools_AlgoTools::MakeConnexityBlock(aLFP, aMS, aLCBF, theAllocator);
932       //
933       // fill states for the Connexity Block 
934       aItS.Initialize(aLCBF);
935       for (; aItS.More(); aItS.Next()) {
936         const TopoDS_Shape& aSx=aItS.Value();
937         aMFDone.Add(aSx);
938         if (aState==TopAbs_IN) {
939           aMFIN.Add(aSx);
940         }
941       }
942       //
943       aNbFPx=aMFDone.Extent();
944       if (aNbFPx==aNbFP) {
945         break;
946       }
947     }//for (; aItFP.More(); aItFP.Next())
948     //
949     // faces Inside aSolid
950     aLFIN.Clear();
951     aNbFIN=aMFIN.Extent();
952     if (aNbFIN || aNbLIF) {
953       aItMS1.Initialize(aMFIN);
954       for (; aItMS1.More(); aItMS1.Next()) {
955         const TopoDS_Shape& aFIn=aItMS1.Value();
956         aLFIN.Append(aFIn);
957       }
958       //
959       aItS.Initialize(aLIF);
960       for (; aItS.More(); aItS.Next()) {
961         const TopoDS_Shape& aFIN=aItS.Value();
962         aLFIN.Append(aFIN);
963       }
964       //
965       theInParts.Bind(aSolid, aLFIN);
966     }
967     if (aNbFIN || bHasImage) {
968       theDraftSolids.Bind(aSolid, aSolidSp);
969     }
970   }// for (; aItMS.More(); aItMS.Next()) {
971 }