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