0031687: Draw Harness, ViewerTest - extend command vrenderparams with option updating...
[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 <BOPDS_DS.hxx>
19 #include <BOPDS_FaceInfo.hxx>
20 #include <BOPDS_ListOfPave.hxx>
21 #include <BOPDS_ListOfPaveBlock.hxx>
22 #include <BOPDS_MapOfPaveBlock.hxx>
23 #include <BOPDS_Pave.hxx>
24 #include <BOPDS_ShapeInfo.hxx>
25 #include <BOPTools_AlgoTools.hxx>
26 #include <BOPTools_AlgoTools2D.hxx>
27 #include <BOPTools_AlgoTools3D.hxx>
28 #include <BOPTools_MapOfSet.hxx>
29 #include <BRep_Builder.hxx>
30 #include <BRep_Tool.hxx>
31 #include <BRepBndLib.hxx>
32 #include <BRepFeat_Builder.hxx>
33 #include <Geom_Curve.hxx>
34 #include <IntTools_Tools.hxx>
35 #include <Precision.hxx>
36 #include <TopExp.hxx>
37 #include <TopExp_Explorer.hxx>
38 #include <TopoDS_Edge.hxx>
39 #include <TopoDS_Face.hxx>
40 #include <TopoDS_Shape.hxx>
41 #include <TopTools_ListIteratorOfListOfShape.hxx>
42 #include <TopTools_DataMapOfShapeListOfShape.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   TopExp::MapShapes(thePart, myShapes);
163 }
164
165 //=======================================================================
166 //function : Prepare
167 //purpose  : 
168 //=======================================================================
169   void BRepFeat_Builder::Prepare()
170 {
171   GetReport()->Clear();
172   //
173   BRep_Builder aBB;
174   TopoDS_Compound aC;
175   aBB.MakeCompound(aC);
176   myShape=aC;
177   //
178   FillRemoved();
179 }
180
181 //=======================================================================
182 //function : FillRemoved
183 //purpose  : 
184 //=======================================================================
185   void BRepFeat_Builder::FillRemoved()
186 {
187   TopExp_Explorer aExp;
188   //
189   const TopoDS_Shape& aArgs0=myArguments.First();
190   const TopoDS_Shape& aArgs1=myTools.First();
191   //
192   aExp.Init(aArgs0, TopAbs_SOLID);
193   for (; aExp.More(); aExp.Next()) {
194     const TopoDS_Shape& aS = aExp.Current();
195     myImages.UnBind(aS);
196   }
197   //
198   if (!myImages.IsBound(aArgs1)) {
199     return;
200   }
201   //
202   TopTools_ListIteratorOfListOfShape aItIm;
203   //
204   TopTools_ListOfShape& aLS = myImages.ChangeFind(aArgs1);
205   aItIm.Initialize(aLS);
206   for (; aItIm.More(); aItIm.Next()) {
207     const TopoDS_Shape& aS = aItIm.Value();
208     FillRemoved(aS, myRemoved);
209   }
210 }
211
212 //=======================================================================
213 //function : PerformResult
214 //purpose  : 
215 //=======================================================================
216   void BRepFeat_Builder::PerformResult()
217 {
218   myOperation = myFuse ? BOPAlgo_FUSE : BOPAlgo_CUT;
219   //
220   if (!myShapes.IsEmpty()) {
221     //
222     Prepare(); 
223     //
224     RebuildFaces();
225     //
226     FillImagesContainers(TopAbs_SHELL);
227     if (HasErrors()) {
228       return;
229     }
230     //
231     FillImagesSolids();
232     if (HasErrors()) {
233       return;
234     }
235     //
236     CheckSolidImages();
237     //
238     BuildResult(TopAbs_SOLID);
239     if (HasErrors()) {
240       return;
241     }
242     // 
243     FillImagesCompounds();
244     if (HasErrors()) {
245       return;
246     }
247     //
248     BuildResult(TopAbs_COMPOUND);
249     if (HasErrors()) {
250       return;
251     }
252   }
253   //
254   BuildShape();
255 }
256
257 //=======================================================================
258 //function : RebuildFaces
259 //purpose  : 
260 //=======================================================================
261   void BRepFeat_Builder::RebuildFaces()
262 {
263   Standard_Integer aNbS, i, iRank, nSp, j;
264   Standard_Boolean bIsClosed, bIsDegenerated, bToReverse,
265                    bRem, bIm, bFlagSD, bVInShapes;
266   TopAbs_Orientation anOriF, anOriE;
267   TopoDS_Face aFF, aFSD;
268   TopoDS_Edge aSp;
269   TopoDS_Shape aSx;
270   TopExp_Explorer aExp, aExpE;
271   TopTools_MapOfShape aME, aMESplit;
272   TopTools_ListIteratorOfListOfShape aItIm;
273   BOPDS_MapIteratorOfMapOfPaveBlock aItMPB;
274   TopTools_MapIteratorOfMapOfShape aItM;
275   BOPTools_MapOfSet aMST;
276   TopTools_ListOfShape aLE;
277   //
278   aItM.Initialize(myShapes);
279   for (; aItM.More(); aItM.Next()) {
280     const TopoDS_Shape& aS = aItM.Value();
281     if (aS.ShapeType() == TopAbs_FACE) {
282       BOPTools_Set aST;
283       aST.Add(aS, TopAbs_EDGE);
284       aMST.Add(aST);
285     }
286   }
287   //
288   aNbS=myDS->NbSourceShapes();
289   for (i=0; i<aNbS; ++i) {
290     const BOPDS_ShapeInfo& aSI=myDS->ShapeInfo(i);
291     //
292     iRank = myDS->Rank(i);
293     if (iRank == 1) {
294       const TopoDS_Shape& aS = aSI.Shape();
295       //
296       if (myImages.IsBound(aS)) {
297         TopTools_ListOfShape& aLIm = myImages.ChangeFind(aS);
298         aItIm.Initialize(aLIm);
299         for (; aItIm.More(); ) {
300           const TopoDS_Shape& aSIm = aItIm.Value();
301           if (!myShapes.Contains(aSIm)) {
302             aLIm.Remove(aItIm);
303             continue;
304           }
305           aItIm.Next();
306         }
307       }
308       continue;
309     }
310     //
311     if (aSI.ShapeType()!=TopAbs_FACE) {
312       continue;
313     }
314     //
315     const BOPDS_FaceInfo& aFI=myDS->FaceInfo(i);
316     const TopoDS_Face& aF=(*(TopoDS_Face*)(&aSI.Shape()));
317     //
318     if (!myImages.IsBound(aF)) {
319       continue;
320     }
321     //
322     anOriF=aF.Orientation();
323     aFF=aF;
324     aFF.Orientation(TopAbs_FORWARD);
325
326     const BOPDS_IndexedMapOfPaveBlock& aMPBIn=aFI.PaveBlocksIn();
327     const BOPDS_IndexedMapOfPaveBlock& aMPBSc=aFI.PaveBlocksSc();
328
329     aLE.Clear();
330
331     //bounding edges
332     aExp.Init(aFF, TopAbs_EDGE);
333     for (; aExp.More(); aExp.Next()) {
334       const TopoDS_Edge& aE=(*(TopoDS_Edge*)(&aExp.Current()));
335       anOriE=aE.Orientation();
336       bIsDegenerated=BRep_Tool::Degenerated(aE);
337       bIsClosed=BRep_Tool::IsClosed(aE, aF);
338       if (myImages.IsBound(aE)) {
339         TopTools_ListOfShape& aLEIm = myImages.ChangeFind(aE);
340         //
341         bRem = Standard_False;
342         bIm = Standard_False;
343         aME.Clear();
344         TopTools_ListOfShape aLEImNew;
345         //
346         aItIm.Initialize(aLEIm);
347         for (; aItIm.More(); aItIm.Next()) {
348           const TopoDS_Shape& aS = aItIm.Value();
349
350           bVInShapes = Standard_False;
351           if (myShapes.Contains(aS)) {
352             bVInShapes = Standard_True;
353           } else {
354             aExpE.Init(aS, TopAbs_VERTEX);
355             for(;aExpE.More(); aExpE.Next()) {
356               const TopoDS_Shape& aV = aExpE.Current();
357               if (myShapes.Contains(aV)) {
358                 bVInShapes = Standard_True;
359                 break;
360               }
361             }
362           }
363           //
364           if (bVInShapes) {
365             bIm = Standard_True;
366             aLEImNew.Append(aS);
367           } else {
368             bRem = Standard_True;
369             aME.Add(aS);
370           }
371         }
372         //
373         if (!bIm) {
374           aLE.Append(aE);
375           continue;
376         }
377         //
378         if (bRem && bIm) {
379           if (aLEIm.Extent() == 2) {
380             aLE.Append(aE);
381             continue;
382           }
383           if (aMESplit.Add(aE)) {
384             RebuildEdge(aE, aFF, aME, aLEImNew);
385             aLEIm.Assign(aLEImNew);
386             if (aLEIm.Extent() == 1) {
387               aLE.Append(aE);
388               continue;
389             }
390           }
391         }
392         //
393         aItIm.Initialize(aLEIm);
394         for (; aItIm.More(); aItIm.Next()) {
395           aSp = *(TopoDS_Edge*)&aItIm.Value();
396
397           if (bIsDegenerated) {
398             aSp.Orientation(anOriE);
399             aLE.Append(aSp);
400             continue;
401           }
402           //
403           if (anOriE==TopAbs_INTERNAL) {
404             aSp.Orientation(TopAbs_FORWARD);
405             aLE.Append(aSp);
406             aSp.Orientation(TopAbs_REVERSED);
407             aLE.Append(aSp);
408             continue;
409           }
410           //
411           if (bIsClosed) {
412             if (!BRep_Tool::IsClosed(aSp, aFF)){
413               BOPTools_AlgoTools3D::DoSplitSEAMOnFace(aSp, aFF);
414             }
415             //
416             aSp.Orientation(TopAbs_FORWARD);
417             aLE.Append(aSp);
418             aSp.Orientation(TopAbs_REVERSED);
419             aLE.Append(aSp);
420             continue;
421           }// if (bIsClosed){
422           //
423           aSp.Orientation(anOriE);
424           bToReverse=BOPTools_AlgoTools::IsSplitToReverse(aSp, aE, myContext);
425           if (bToReverse) {
426             aSp.Reverse();
427           }
428           aLE.Append(aSp);
429         }
430       }
431       else {
432         aLE.Append(aE);
433       }
434     }
435
436     Standard_Integer aNbPBIn, aNbPBSc;
437     aNbPBIn = aMPBIn.Extent();
438     aNbPBSc = aMPBSc.Extent();
439     //
440     //in edges
441     for (j=1; j<=aNbPBIn; ++j) {
442       const Handle(BOPDS_PaveBlock)& aPB=aMPBIn(j);
443       nSp=aPB->Edge();
444       aSp=(*(TopoDS_Edge*)(&myDS->Shape(nSp)));
445       if (myRemoved.Contains(aSp)) {
446         continue;
447       }
448       //
449       aSp.Orientation(TopAbs_FORWARD);
450       aLE.Append(aSp);
451       aSp.Orientation(TopAbs_REVERSED);
452       aLE.Append(aSp);
453     }
454     //section edges
455     for (j=1; j<=aNbPBSc; ++j) {
456       const Handle(BOPDS_PaveBlock)& aPB=aMPBSc(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     
469     //build new faces
470     BOPAlgo_BuilderFace aBF;
471     aBF.SetFace(aFF);
472     aBF.SetShapes(aLE);
473     
474     aBF.Perform();
475
476     TopTools_ListOfShape& aLFIm = myImages.ChangeFind(aF);
477     aLFIm.Clear();
478
479     const TopTools_ListOfShape& aLFR=aBF.Areas();
480     aItIm.Initialize(aLFR);
481     for (; aItIm.More(); aItIm.Next()) {
482       TopoDS_Shape& aFR=aItIm.ChangeValue();
483       //
484       BOPTools_Set aST;
485       aST.Add(aFR, TopAbs_EDGE);
486       bFlagSD=aMST.Contains(aST);
487       //
488       const BOPTools_Set& aSTx=aMST.Added(aST);
489       aSx=aSTx.Shape();
490       aSx.Orientation(anOriF);
491       aLFIm.Append(aSx);
492       //
493       TopTools_ListOfShape* pLOr = myOrigins.ChangeSeek(aSx);
494       if (!pLOr) {
495         pLOr = myOrigins.Bound(aSx, TopTools_ListOfShape());
496       }
497       pLOr->Append(aF);
498       //
499       if (bFlagSD) {
500         myShapesSD.Bind(aFR, aSx);
501       }
502     }
503     //
504     if (aLFIm.Extent() == 0) {
505       myImages.UnBind(aF);
506     }
507   }
508 }
509
510 //=======================================================================
511 //function : RebuildEdge
512 //purpose  : 
513 //=======================================================================
514   void BRepFeat_Builder::RebuildEdge(const TopoDS_Shape& theE,
515                                      const TopoDS_Face& theF,
516                                      const TopTools_MapOfShape& aME,
517                                      TopTools_ListOfShape& aLIm)
518 {
519   Standard_Integer nE, nSp, nV1, nV2, nE1, nV, nVx, nVSD;
520   Standard_Integer nV11, nV21;
521   Standard_Boolean bOld;
522   Standard_Real aT11, aT21;
523   Standard_Real aT1, aT2;
524   TopoDS_Edge aSp, aE;
525   BOPDS_ShapeInfo aSI;
526   TopoDS_Vertex aV1, aV2;
527   Handle(BOPDS_PaveBlock) aPBNew;
528   TColStd_MapOfInteger aMI, aMAdd, aMV, aMVOr;
529   BOPDS_ListIteratorOfListOfPaveBlock aItPB;
530   TopTools_ListIteratorOfListOfShape aIt;
531   TColStd_ListIteratorOfListOfInteger aItLI;
532   TopTools_MapIteratorOfMapOfShape aItM;
533   BOPDS_MapOfPaveBlock aMPB;
534   BOPDS_MapIteratorOfMapOfPaveBlock aItMPB;
535   //
536   aSI.SetShapeType(TopAbs_EDGE);
537
538   //1. collect origin vertices to aMV map.
539   nE = myDS->Index(theE);
540   const BOPDS_ShapeInfo& aSIE = myDS->ShapeInfo(nE);
541   const TColStd_ListOfInteger& aLS = aSIE.SubShapes();
542   aItLI.Initialize(aLS);
543   for(; aItLI.More(); aItLI.Next()) {
544     nV = aItLI.Value();
545     nVx=nV;
546     if (myDS->HasShapeSD(nV, nVSD)) {
547       nVx=nVSD;
548     }
549     aMV.Add(nVx);
550     aMVOr.Add(nVx);
551   }
552   //
553   //2. collect vertices that should be removed to aMI map.
554   aPBNew = new BOPDS_PaveBlock;
555   BOPDS_ListOfPave& aLPExt = aPBNew->ChangeExtPaves();
556   BOPDS_ListOfPaveBlock& aLPB = myDS->ChangePaveBlocks(nE);
557   //
558   for (aItPB.Initialize(aLPB); aItPB.More(); aItPB.Next()) {
559     const Handle(BOPDS_PaveBlock)& aPB = aItPB.Value();
560     nE1 = aPB->Edge();
561     const TopoDS_Shape& aE1 = myDS->Shape(nE1);
562     //
563     if (aME.Contains(aE1)) {
564       aPB->Indices(nV1, nV2);
565       aMI.Add(nV1);
566       aMI.Add(nV2);
567     }
568     else {
569       aMPB.Add(aPB);
570     }
571   }
572   //3. collect vertices that split the source shape.
573   for (aItPB.Initialize(aLPB); aItPB.More(); aItPB.Next()) {
574     const Handle(BOPDS_PaveBlock)& aPB = aItPB.Value();
575     aPB->Indices(nV1, nV2);
576     //
577     if (!aMI.Contains(nV1)) {
578       aMV.Add(nV1);
579     }
580     if (!aMI.Contains(nV2)) {
581       aMV.Add(nV2);
582     }
583   }
584   //4. collect ext paves.
585   for (aItPB.Initialize(aLPB); aItPB.More(); aItPB.Next()) {
586     const Handle(BOPDS_PaveBlock)& aPB = aItPB.Value();
587     aPB->Indices(nV1, nV2);
588     //
589     if (aMV.Contains(nV1)) {
590       if (aMAdd.Add(nV1) || aMVOr.Contains(nV1)) {
591         aLPExt.Append(aPB->Pave1());
592       }
593     }
594     //
595     if (aMV.Contains(nV2)) {
596       if (aMAdd.Add(nV2) || aMVOr.Contains(nV2)) {
597         aLPExt.Append(aPB->Pave2());
598       }
599     }      
600   }
601
602   aE = (*(TopoDS_Edge *)(&theE));
603   aE.Orientation(TopAbs_FORWARD);
604   //
605   aLIm.Clear();
606   //
607   //5. split edge by new set of vertices.
608   aLPB.Clear();
609   aPBNew->SetOriginalEdge(nE);
610   aPBNew->Update(aLPB, Standard_False);
611   //
612   for (aItPB.Initialize(aLPB); aItPB.More(); aItPB.Next()) {
613     Handle(BOPDS_PaveBlock)& aPB = aItPB.ChangeValue();
614     const BOPDS_Pave& aPave1=aPB->Pave1();
615     aPave1.Contents(nV1, aT1);
616     //
617     const BOPDS_Pave& aPave2=aPB->Pave2();
618     aPave2.Contents(nV2, aT2);
619     //
620     aItMPB.Initialize(aMPB);
621     //check if it is the old pave block.
622     bOld = Standard_False;
623     for (; aItMPB.More(); aItMPB.Next()) {
624       const Handle(BOPDS_PaveBlock)& aPB1 = aItMPB.Value();
625       aPB1->Indices(nV11, nV21);
626       aPB1->Range(aT11, aT21);
627       if (nV1 == nV11 && nV2 == nV21 &&
628           aT1 == aT11 && aT2 == aT21) {
629         const TopoDS_Shape& aEIm = myDS->Shape(aPB1->Edge());
630         aLIm.Append(aEIm);
631         bOld = Standard_True;
632         break;
633       }
634     }
635     if (bOld) {
636       continue;
637     }
638     //
639     aV1=(*(TopoDS_Vertex *)(&myDS->Shape(nV1)));
640     aV1.Orientation(TopAbs_FORWARD); 
641     //
642     aV2=(*(TopoDS_Vertex *)(&myDS->Shape(nV2)));
643     aV2.Orientation(TopAbs_REVERSED); 
644     //
645     BOPTools_AlgoTools::MakeSplitEdge(aE, aV1, aT1, aV2, aT2, aSp);
646     BOPTools_AlgoTools2D::BuildPCurveForEdgeOnFace(aSp, theF, myContext);
647     //
648     aSI.SetShape(aSp);
649     //
650     Bnd_Box& aBox=aSI.ChangeBox();
651     BRepBndLib::Add(aSp, aBox);
652     //
653     nSp=myDS->Append(aSI);
654     //
655     aPB->SetEdge(nSp);
656     aLIm.Append(aSp);
657   }
658 }
659
660 //=======================================================================
661 //function : CheckSolidImages
662 //purpose  : 
663 //=======================================================================
664   void BRepFeat_Builder::CheckSolidImages()
665 {
666   BOPTools_MapOfSet aMST;
667   TopTools_ListOfShape aLSImNew;
668   TopTools_MapOfShape aMS;
669   TopTools_ListIteratorOfListOfShape aIt;
670   TopExp_Explorer aExp, aExpF;
671   Standard_Boolean bFlagSD;
672   // 
673   const TopoDS_Shape& aArgs0=myArguments.First();
674   const TopoDS_Shape& aArgs1=myTools.First();
675   //
676   const TopTools_ListOfShape& aLSIm = myImages.Find(aArgs1);
677   aIt.Initialize(aLSIm);
678   for(;aIt.More();aIt.Next()) {
679     const TopoDS_Shape& aSolIm = aIt.Value();
680     //
681     BOPTools_Set aST;
682     aST.Add(aSolIm, TopAbs_FACE);
683     aMST.Add(aST);
684   }
685   //
686   aExp.Init(aArgs0, TopAbs_SOLID);
687   for(; aExp.More(); aExp.Next()) {
688     const TopoDS_Shape& aSolid = aExp.Current();
689     if (myImages.IsBound(aSolid)) {
690       TopTools_ListOfShape& aLSImSol = myImages.ChangeFind(aSolid);
691       aIt.Initialize(aLSImSol);
692       for(;aIt.More();aIt.Next()) {
693         const TopoDS_Shape& aSolIm = aIt.Value();
694         //
695         BOPTools_Set aST;
696         aST.Add(aSolIm, TopAbs_FACE);
697         bFlagSD=aMST.Contains(aST);
698         //
699         const BOPTools_Set& aSTx=aMST.Added(aST);
700         const TopoDS_Shape& aSx=aSTx.Shape();
701         aLSImNew.Append(aSx);
702         //
703         if (bFlagSD) {
704           myShapesSD.Bind(aSolIm, aSx);
705         }
706       }
707       aLSImSol.Assign(aLSImNew);
708     }
709   }
710 }
711
712 //=======================================================================
713 //function : MapShapes
714 //purpose  : 
715 //=======================================================================
716   void BRepFeat_Builder::FillRemoved(const TopoDS_Shape& S,  
717                                      TopTools_MapOfShape& M)
718 {
719   if (myShapes.Contains(S)) {
720     return;
721   }
722   //
723   M.Add(S);
724   TopoDS_Iterator It(S);
725   while (It.More()) {
726     FillRemoved(It.Value(),M);
727     It.Next();
728   }
729 }
730
731 //=======================================================================
732 //function : FillIn3DParts
733 //purpose  : 
734 //=======================================================================
735   void BRepFeat_Builder::FillIn3DParts(TopTools_DataMapOfShapeShape& theDraftSolids)
736 {
737   GetReport()->Clear();
738
739   BOPAlgo_Builder::FillIn3DParts(theDraftSolids);
740
741   // Clear the IN parts of the solids from the removed faces
742   TopTools_DataMapOfShapeListOfShape::Iterator itM(myInParts);
743   for (; itM.More(); itM.Next())
744   {
745     TopTools_ListOfShape& aList = itM.ChangeValue();
746     TopTools_ListOfShape::Iterator itL(aList);
747     for (; itL.More();)
748     {
749       if (myRemoved.Contains(itL.Value()))
750         aList.Remove(itL);
751       else
752         itL.Next();
753     }
754   }
755 }