0024002: Overall code and build procedure refactoring -- automatic
[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   myErrorStatus=0;
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 (myErrorStatus) {
230       return;
231     }
232     //
233     FillImagesSolids();
234     if (myErrorStatus) {
235       return;
236     }
237     //
238     CheckSolidImages();
239     //
240     BuildResult(TopAbs_SOLID);
241     if (myErrorStatus) {
242       return;
243     }
244     // 
245     FillImagesCompounds();
246     if (myErrorStatus) {
247       return;
248     }
249     //
250     BuildResult(TopAbs_COMPOUND);
251     if (myErrorStatus) {
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       myOrigins.Bind(aSx, aF);
495       //
496       if (bFlagSD) {
497         myShapesSD.Bind(aFR, aSx);
498       }
499     }
500     //
501     mySplits.Bind(aF, aLFIm); 
502     if (aLFIm.Extent() == 0) {
503       mySplits.UnBind(aF);
504       myImages.UnBind(aF);
505     }
506   }
507 }
508
509 //=======================================================================
510 //function : RebuildEdge
511 //purpose  : 
512 //=======================================================================
513   void BRepFeat_Builder::RebuildEdge(const TopoDS_Shape& theE,
514                                      const TopoDS_Face& theF,
515                                      const BOPCol_MapOfShape& aME,
516                                      BOPCol_ListOfShape& aLIm)
517 {
518   Standard_Integer nE, nSp, nV1, nV2, nE1, nV, nVx, nVSD;
519   Standard_Integer nV11, nV21;
520   Standard_Boolean bOld;
521   Standard_Real aT11, aT21;
522   Standard_Real aT1, aT2;
523   TopoDS_Edge aSp, aE;
524   BOPDS_ShapeInfo aSI;
525   TopoDS_Vertex aV1, aV2;
526   Handle(BOPDS_PaveBlock) aPBNew;
527   BOPCol_MapOfInteger aMI, aMAdd, aMV, aMVOr;
528   BOPDS_ListIteratorOfListOfPaveBlock aItPB;
529   BOPCol_ListIteratorOfListOfShape aIt;
530   BOPCol_ListIteratorOfListOfInteger aItLI;
531   BOPCol_MapIteratorOfMapOfShape aItM;
532   BOPDS_MapOfPaveBlock aMPB;
533   BOPDS_MapIteratorOfMapOfPaveBlock aItMPB;
534   //
535   aSI.SetShapeType(TopAbs_EDGE);
536
537   //1. collect origin vertices to aMV map.
538   nE = myDS->Index(theE);
539   const BOPDS_ShapeInfo& aSIE = myDS->ShapeInfo(nE);
540   const BOPCol_ListOfInteger& aLS = aSIE.SubShapes();
541   aItLI.Initialize(aLS);
542   for(; aItLI.More(); aItLI.Next()) {
543     nV = aItLI.Value();
544     nVx=nV;
545     if (myDS->HasShapeSD(nV, nVSD)) {
546       nVx=nVSD;
547     }
548     aMV.Add(nVx);
549     aMVOr.Add(nVx);
550   }
551   //
552   //2. collect vertices that should be removed to aMI map.
553   aPBNew = new BOPDS_PaveBlock;
554   BOPDS_ListOfPave& aLPExt = aPBNew->ChangeExtPaves();
555   BOPDS_ListOfPaveBlock& aLPB = myDS->ChangePaveBlocks(nE);
556   //
557   for (aItPB.Initialize(aLPB); aItPB.More(); aItPB.Next()) {
558     const Handle(BOPDS_PaveBlock)& aPB = aItPB.Value();
559     nE1 = aPB->Edge();
560     const TopoDS_Shape& aE1 = myDS->Shape(nE1);
561     //
562     if (aME.Contains(aE1)) {
563       aPB->Indices(nV1, nV2);
564       aMI.Add(nV1);
565       aMI.Add(nV2);
566     }
567     else {
568       aMPB.Add(aPB);
569     }
570   }
571   //3. collect vertices that split the source shape.
572   for (aItPB.Initialize(aLPB); aItPB.More(); aItPB.Next()) {
573     const Handle(BOPDS_PaveBlock)& aPB = aItPB.Value();
574     aPB->Indices(nV1, nV2);
575     //
576     if (!aMI.Contains(nV1)) {
577       aMV.Add(nV1);
578     }
579     if (!aMI.Contains(nV2)) {
580       aMV.Add(nV2);
581     }
582   }
583   //4. collect ext paves.
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 (aMV.Contains(nV1)) {
589       if (aMAdd.Add(nV1) || aMVOr.Contains(nV1)) {
590         aLPExt.Append(aPB->Pave1());
591       }
592     }
593     //
594     if (aMV.Contains(nV2)) {
595       if (aMAdd.Add(nV2) || aMVOr.Contains(nV2)) {
596         aLPExt.Append(aPB->Pave2());
597       }
598     }      
599   }
600
601   aE = (*(TopoDS_Edge *)(&theE));
602   aE.Orientation(TopAbs_FORWARD);
603   //
604   aLIm.Clear();
605   //
606   //5. split edge by new set of vertices.
607   aLPB.Clear();
608   aPBNew->SetOriginalEdge(nE);
609   aPBNew->Update(aLPB, Standard_False);
610   //
611   for (aItPB.Initialize(aLPB); aItPB.More(); aItPB.Next()) {
612     Handle(BOPDS_PaveBlock)& aPB = aItPB.ChangeValue();
613     const BOPDS_Pave& aPave1=aPB->Pave1();
614     aPave1.Contents(nV1, aT1);
615     //
616     const BOPDS_Pave& aPave2=aPB->Pave2();
617     aPave2.Contents(nV2, aT2);
618     //
619     aItMPB.Initialize(aMPB);
620     //check if it is the old pave block.
621     bOld = Standard_False;
622     for (; aItMPB.More(); aItMPB.Next()) {
623       const Handle(BOPDS_PaveBlock)& aPB1 = aItMPB.Value();
624       aPB1->Indices(nV11, nV21);
625       aPB1->Range(aT11, aT21);
626       if (nV1 == nV11 && nV2 == nV21 &&
627           aT1 == aT11 && aT2 == aT21) {
628         const TopoDS_Shape& aEIm = myDS->Shape(aPB1->Edge());
629         aLIm.Append(aEIm);
630         bOld = Standard_True;
631         break;
632       }
633     }
634     if (bOld) {
635       continue;
636     }
637     //
638     aV1=(*(TopoDS_Vertex *)(&myDS->Shape(nV1)));
639     aV1.Orientation(TopAbs_FORWARD); 
640     //
641     aV2=(*(TopoDS_Vertex *)(&myDS->Shape(nV2)));
642     aV2.Orientation(TopAbs_REVERSED); 
643     //
644     BOPTools_AlgoTools::MakeSplitEdge(aE, aV1, aT1, aV2, aT2, aSp);  
645     BOPTools_AlgoTools2D::BuildPCurveForEdgeOnFace(aSp, theF);
646     //
647     aSI.SetShape(aSp);
648     //
649     Bnd_Box& aBox=aSI.ChangeBox();
650     BRepBndLib::Add(aSp, aBox);
651     //
652     nSp=myDS->Append(aSI);
653     //
654     aPB->SetEdge(nSp);
655     aLIm.Append(aSp);
656   }
657 }
658
659 //=======================================================================
660 //function : CheckSolidImages
661 //purpose  : 
662 //=======================================================================
663   void BRepFeat_Builder::CheckSolidImages()
664 {
665   BOPTools_MapOfSet aMST;
666   BOPCol_ListOfShape aLSImNew;
667   BOPCol_MapOfShape aMS;
668   BOPCol_ListIteratorOfListOfShape aIt;
669   TopExp_Explorer aExp, aExpF;
670   Standard_Boolean bFlagSD;
671   // 
672   const TopoDS_Shape& aArgs0=myArguments.First();
673   const TopoDS_Shape& aArgs1=myTools.First();
674   //
675   const BOPCol_ListOfShape& aLSIm = myImages.Find(aArgs1);
676   aIt.Initialize(aLSIm);
677   for(;aIt.More();aIt.Next()) {
678     const TopoDS_Shape& aSolIm = aIt.Value();
679     //
680     BOPTools_Set aST;
681     aST.Add(aSolIm, TopAbs_FACE);
682     aMST.Add(aST);
683   }
684   //
685   aExp.Init(aArgs0, TopAbs_SOLID);
686   for(; aExp.More(); aExp.Next()) {
687     const TopoDS_Shape& aSolid = aExp.Current();
688     if (myImages.IsBound(aSolid)) {
689       BOPCol_ListOfShape& aLSImSol = myImages.ChangeFind(aSolid);
690       aIt.Initialize(aLSImSol);
691       for(;aIt.More();aIt.Next()) {
692         const TopoDS_Shape& aSolIm = aIt.Value();
693         //
694         BOPTools_Set aST;
695         aST.Add(aSolIm, TopAbs_FACE);
696         bFlagSD=aMST.Contains(aST);
697         //
698         const BOPTools_Set& aSTx=aMST.Added(aST);
699         const TopoDS_Shape& aSx=aSTx.Shape();
700         aLSImNew.Append(aSx);
701         //
702         if (bFlagSD) {
703           myShapesSD.Bind(aSolIm, aSx);
704         }
705       }
706       aLSImSol.Assign(aLSImNew);
707     }
708   }
709 }
710
711 //=======================================================================
712 //function : MapShapes
713 //purpose  : 
714 //=======================================================================
715   void BRepFeat_Builder::FillRemoved(const TopoDS_Shape& S,  
716                                      BOPCol_MapOfShape& M)
717 {
718   if (myShapes.Contains(S)) {
719     return;
720   }
721   //
722   M.Add(S);
723   TopoDS_Iterator It(S);
724   while (It.More()) {
725     FillRemoved(It.Value(),M);
726     It.Next();
727   }
728 }
729
730 //=======================================================================
731 //function : FillIn3DParts
732 //purpose  : 
733 //=======================================================================
734   void BRepFeat_Builder::FillIn3DParts(BOPCol_DataMapOfShapeListOfShape& theInParts,
735                                        BOPCol_DataMapOfShapeShape& theDraftSolids,
736                                        const Handle(NCollection_BaseAllocator)& theAllocator)
737 {
738   myErrorStatus=0;
739   //
740   Standard_Boolean bIsIN, bHasImage;
741   Standard_Integer aNbS, i, j, aNbFP, aNbFPx, aNbFIN, aNbLIF, aNbEFP;
742   TopAbs_ShapeEnum aType;  
743   TopAbs_State aState;
744   TopoDS_Iterator aIt, aItF;
745   BRep_Builder aBB;
746   TopoDS_Solid aSolidSp; 
747   TopoDS_Face aFP;
748   BOPCol_ListIteratorOfListOfShape aItS, aItFP, aItEx;  
749   BOPCol_MapIteratorOfMapOfShape aItMS, aItMS1;
750   //
751   BOPCol_ListOfShape aLIF(theAllocator);
752   BOPCol_MapOfShape aMFDone(100, theAllocator);
753   BOPCol_MapOfShape aMSolids(100, theAllocator);
754   BOPCol_MapOfShape aMFaces(100, theAllocator);
755   BOPCol_MapOfShape aMFIN(100, theAllocator);
756   BOPCol_IndexedMapOfShape aMS(100, theAllocator);
757   BOPCol_IndexedDataMapOfShapeListOfShape aMEF(100, theAllocator);
758   //
759   theDraftSolids.Clear();
760   //
761   aNbS=myDS->NbSourceShapes();
762   for (i=0; i<aNbS; ++i) {
763     const BOPDS_ShapeInfo& aSI=myDS->ShapeInfo(i);
764     const TopoDS_Shape& aS=aSI.Shape();
765     //
766     aType=aSI.ShapeType();
767     switch(aType) {
768       case TopAbs_SOLID: {
769         aMSolids.Add(aS);
770         break;
771       }
772       //
773       case TopAbs_FACE: {
774         // all faces (originals or images)
775         if (myImages.IsBound(aS)) {
776           const BOPCol_ListOfShape& aLS=myImages.Find(aS);
777           aItS.Initialize(aLS);
778           for (; aItS.More(); aItS.Next()) {
779             const TopoDS_Shape& aFx=aItS.Value();
780             if (!myRemoved.Contains(aFx)) {
781               aMFaces.Add(aFx);
782             }
783           }
784         }
785         else {
786           if (!myRemoved.Contains(aS)) {
787             aMFaces.Add(aS);
788           }
789         }
790         break;
791       }
792       //
793       default:
794         break;
795     }
796   }
797   //
798   aItMS.Initialize(aMSolids);
799   for (; aItMS.More(); aItMS.Next()) {
800     const TopoDS_Solid& aSolid=(*(TopoDS_Solid*)(&aItMS.Value()));
801     //
802     aMFDone.Clear();
803     aMFIN.Clear();
804     aMEF.Clear();
805     //
806     aBB.MakeSolid(aSolidSp);
807     // 
808     // Draft solid and its pure internal faces => aSolidSp, aLIF
809     aLIF.Clear();
810     BuildDraftSolid(aSolid, aSolidSp, aLIF);
811     aNbLIF=aLIF.Extent();
812     //
813     // 1 all faces/edges from aSolid [ aMS ]
814     bHasImage=Standard_False;
815     aMS.Clear();
816     aIt.Initialize(aSolid);
817     for (; aIt.More(); aIt.Next()) {
818       const TopoDS_Shape& aShell=aIt.Value();
819       //
820       if (myImages.IsBound(aShell)) {
821         bHasImage=Standard_True;
822         //
823         const BOPCol_ListOfShape& aLS=myImages.Find(aShell);
824         aItS.Initialize(aLS);
825         for (; aItS.More(); aItS.Next()) {
826           const TopoDS_Shape& aSx=aItS.Value();
827           aMS.Add(aSx);
828           BOPTools::MapShapes(aSx, TopAbs_FACE, aMS);
829           BOPTools::MapShapes(aSx, TopAbs_EDGE, aMS);
830           BOPTools::MapShapesAndAncestors(aSx, TopAbs_EDGE, TopAbs_FACE, aMEF);
831         }
832       }
833       else {
834         //aMS.Add(aShell);
835         BOPTools::MapShapes(aShell, TopAbs_FACE, aMS);
836         BOPTools::MapShapesAndAncestors(aShell, TopAbs_EDGE, TopAbs_FACE, aMEF);
837       }
838     }
839     //
840     // 2 all faces that are not from aSolid [ aLFP1 ]
841     BOPCol_IndexedDataMapOfShapeListOfShape aMEFP(100, theAllocator);
842     BOPCol_ListOfShape aLFP1(theAllocator);
843     BOPCol_ListOfShape aLFP(theAllocator);
844     BOPCol_ListOfShape aLCBF(theAllocator);
845     BOPCol_ListOfShape aLFIN(theAllocator);
846     BOPCol_ListOfShape aLEx(theAllocator);
847     //
848     // for all non-solid faces build EF map [ aMEFP ]
849     aItMS1.Initialize(aMFaces);
850     for (; aItMS1.More(); aItMS1.Next()) {
851       const TopoDS_Shape& aFace=aItMS1.Value();
852       if (!aMS.Contains(aFace)) {
853         BOPTools::MapShapesAndAncestors(aFace, TopAbs_EDGE, TopAbs_FACE, aMEFP);
854       }
855     }
856     //
857     // among all faces from aMEFP select these that have same edges
858     // with the solid (i.e aMEF). These faces will be treated first 
859     // to prevent the usage of 3D classifier.
860     // The full list of faces to process is aLFP1. 
861     aNbEFP=aMEFP.Extent();
862     for (j=1; j<=aNbEFP; ++j) {
863       const TopoDS_Shape& aE=aMEFP.FindKey(j);
864       //
865       if (aMEF.Contains(aE)) { // !!
866         const BOPCol_ListOfShape& aLF=aMEFP(j);
867         aItFP.Initialize(aLF);
868         for (; aItFP.More(); aItFP.Next()) {
869           const TopoDS_Shape& aF=aItFP.Value();
870           if (aMFDone.Add(aF)) {
871             aLFP1.Append(aF);
872           }
873         }
874       }
875       else {
876         aLEx.Append(aE);
877       }
878     }
879     //
880     aItEx.Initialize(aLEx);
881     for (; aItEx.More(); aItEx.Next()) {
882       const TopoDS_Shape& aE=aItEx.Value();
883       const BOPCol_ListOfShape& aLF=aMEFP.FindFromKey(aE);
884       aItFP.Initialize(aLF);
885       for (; aItFP.More(); aItFP.Next()) {
886         const TopoDS_Shape& aF=aItFP.Value();
887         if (aMFDone.Add(aF)) {
888           //aLFP2.Append(aF);
889           aLFP1.Append(aF);
890         }
891       }
892     }
893     //
894     //==========
895     //
896     // 3 Process faces aLFP1
897     aMFDone.Clear();
898     aNbFP=aLFP1.Extent();
899     aItFP.Initialize(aLFP1);
900     for (; aItFP.More(); aItFP.Next()) {
901       const TopoDS_Shape& aSP=aItFP.Value();
902       if (!aMFDone.Add(aSP)) {
903         continue;
904       }
905       
906       //
907       // first face to process
908       aFP=(*(TopoDS_Face*)(&aSP));
909       bIsIN=BOPTools_AlgoTools::IsInternalFace(aFP, aSolidSp, aMEF, 1.e-14, myContext);
910       aState=(bIsIN) ? TopAbs_IN : TopAbs_OUT;
911       //
912       // collect faces to process [ aFP is the first ]
913       aLFP.Clear();
914       aLFP.Append(aFP);
915       aItS.Initialize(aLFP1);
916       for (; aItS.More(); aItS.Next()) {
917         const TopoDS_Shape& aSk=aItS.Value();
918         if (!aMFDone.Contains(aSk)) {
919           aLFP.Append(aSk);
920         }
921       }
922       //
923       // Connexity Block that spreads from aFP the Bound 
924       // or till the end of the block itself
925       aLCBF.Clear();
926       BOPTools_AlgoTools::MakeConnexityBlock(aLFP, aMS, aLCBF, theAllocator);
927       //
928       // fill states for the Connexity Block 
929       aItS.Initialize(aLCBF);
930       for (; aItS.More(); aItS.Next()) {
931         const TopoDS_Shape& aSx=aItS.Value();
932         aMFDone.Add(aSx);
933         if (aState==TopAbs_IN) {
934           aMFIN.Add(aSx);
935         }
936       }
937       //
938       aNbFPx=aMFDone.Extent();
939       if (aNbFPx==aNbFP) {
940         break;
941       }
942     }//for (; aItFP.More(); aItFP.Next())
943     //
944     // faces Inside aSolid
945     aLFIN.Clear();
946     aNbFIN=aMFIN.Extent();
947     if (aNbFIN || aNbLIF) {
948       aItMS1.Initialize(aMFIN);
949       for (; aItMS1.More(); aItMS1.Next()) {
950         const TopoDS_Shape& aFIn=aItMS1.Value();
951         aLFIN.Append(aFIn);
952       }
953       //
954       aItS.Initialize(aLIF);
955       for (; aItS.More(); aItS.Next()) {
956         const TopoDS_Shape& aFIN=aItS.Value();
957         aLFIN.Append(aFIN);
958       }
959       //
960       theInParts.Bind(aSolid, aLFIN);
961     }
962     if (aNbFIN || bHasImage) {
963       theDraftSolids.Bind(aSolid, aSolidSp);
964     }
965   }// for (; aItMS.More(); aItMS.Next()) {
966 }