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