0024940: WOK: Cyclic dependency detected between: BOPInt IntTools
[occt.git] / src / BOPAlgo / BOPAlgo_BuilderFace.cxx
1 // Created by: Peter KURNEV
2 // Copyright (c) 2010-2012 OPEN CASCADE SAS
3 // Copyright (c) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE
4 // Copyright (c) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, CEDRAT,
5 //                         EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 //
7 //
8 // This file is part of Open CASCADE Technology software library.
9 //
10 // This library is free software; you can redistribute it and/or modify it under
11 // the terms of the GNU Lesser General Public License version 2.1 as published
12 // by the Free Software Foundation, with special exception defined in the file
13 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
14 // distribution for complete text of the license and disclaimer of any warranty.
15 //
16 // Alternatively, this file may be used under the terms of Open CASCADE
17 // commercial license or contractual agreement.
18
19 #include <BOPAlgo_BuilderFace.ixx>
20
21 #include <gp_Pnt2d.hxx>
22 #include <gp_Pln.hxx>
23 #include <gp_Vec.hxx>
24 #include <gp_Dir.hxx>
25 #include <gp_Pnt.hxx>
26
27 #include <Geom_Surface.hxx>
28
29 #include <TopAbs.hxx>
30 #include <TopLoc_Location.hxx>
31
32 #include <TopoDS_Iterator.hxx>
33 #include <TopoDS_Face.hxx>
34 #include <TopoDS_Shape.hxx>
35 #include <TopoDS_Wire.hxx>
36 #include <TopoDS_Edge.hxx>
37 #include <TopoDS_Vertex.hxx>
38
39 #include <BRep_Builder.hxx>
40 #include <BRep_Tool.hxx>
41 #include <BRepTools.hxx>
42
43 #include <TopExp.hxx>
44 #include <TopExp_Explorer.hxx>
45
46 #include <IntTools_FClass2d.hxx>
47 #include <IntTools_Context.hxx>
48
49 //
50 #include <BOPTools_AlgoTools.hxx>
51 #include <BOPTools_AlgoTools2D.hxx>
52 #include <BOPAlgo_WireEdgeSet.hxx>
53 //
54 #include <BOPCol_IndexedDataMapOfShapeListOfShape.hxx>
55 #include <BOPTools.hxx>
56 #include <BOPCol_ListOfShape.hxx>
57 #include <BOPAlgo_WireSplitter.hxx>
58 #include <BOPCol_DataMapOfShapeShape.hxx>
59 #include <BOPCol_DataMapOfShapeListOfShape.hxx>
60 #include <BOPCol_MapOfShape.hxx>
61
62
63 static
64   Standard_Boolean IsGrowthWire(const TopoDS_Shape& ,
65                                 const BOPCol_IndexedMapOfShape& );
66
67 static 
68   Standard_Boolean IsInside(const TopoDS_Shape& ,
69                             const TopoDS_Shape& ,
70                             Handle(IntTools_Context)& );
71 static
72   void MakeInternalWires(const BOPCol_MapOfShape& ,
73                          BOPCol_ListOfShape& );
74 static 
75   void GetWire(const TopoDS_Shape& , 
76         TopoDS_Shape& ); 
77 //
78 #include <NCollection_UBTreeFiller.hxx>
79 #include <BOPCol_Box2DBndTree.hxx>
80 #include <BRepTools.hxx>
81 #include <TColStd_MapIntegerHasher.hxx>
82 #include <NCollection_DataMap.hxx>
83 //
84 //=======================================================================
85 //class     : BOPAlgo_ShapeBox2D
86 //purpose   : Auxiliary class
87 //=======================================================================
88 class BOPAlgo_ShapeBox2D {
89  public:
90   BOPAlgo_ShapeBox2D() {
91     myIsHole=Standard_False;
92   };
93   //
94   ~BOPAlgo_ShapeBox2D() {
95   };
96   //
97   void SetShape(const TopoDS_Shape& aS) {
98     myShape=aS;
99   };
100   //
101   const TopoDS_Shape& Shape()const {
102     return myShape;
103   };
104   //
105   void SetBox2D(const Bnd_Box2d& aBox2D) {
106     myBox2D=aBox2D;
107   };
108   //
109   const Bnd_Box2d& Box2D()const {
110     return myBox2D;
111   };
112   //
113   void SetIsHole(const Standard_Boolean bFlag) {
114     myIsHole=bFlag;
115   };
116   //
117   Standard_Boolean IsHole()const {
118     return myIsHole;
119   };
120   //
121  protected:
122   Standard_Boolean myIsHole;
123   TopoDS_Shape myShape;
124   Bnd_Box2d myBox2D;
125 };
126 //
127 typedef NCollection_DataMap\
128   <Standard_Integer, BOPAlgo_ShapeBox2D, TColStd_MapIntegerHasher> \
129   BOPAlgo_DataMapOfIntegerShapeBox2D; 
130 //
131 typedef BOPAlgo_DataMapOfIntegerShapeBox2D::Iterator \
132   BOPAlgo_DataMapIteratorOfDataMapOfIntegerShapeBox2D; 
133 //
134 //
135 //=======================================================================
136 //function : 
137 //purpose  : 
138 //=======================================================================
139 BOPAlgo_BuilderFace::BOPAlgo_BuilderFace()
140 :
141   BOPAlgo_BuilderArea()
142 {
143   myOrientation=TopAbs_EXTERNAL;
144 }
145 //=======================================================================
146 //function : 
147 //purpose  : 
148 //=======================================================================
149 BOPAlgo_BuilderFace::BOPAlgo_BuilderFace
150   (const Handle(NCollection_BaseAllocator)& theAllocator)
151 :
152   BOPAlgo_BuilderArea(theAllocator)
153
154   myOrientation=TopAbs_EXTERNAL;
155 }
156 //=======================================================================
157 //function : ~
158 //purpose  : 
159 //=======================================================================
160   BOPAlgo_BuilderFace::~BOPAlgo_BuilderFace()
161 {
162 }
163 //=======================================================================
164 //function : SetFace
165 //purpose  : 
166 //=======================================================================
167 void BOPAlgo_BuilderFace::SetFace(const TopoDS_Face& theFace)
168 {
169   myOrientation=theFace.Orientation();
170   myFace=theFace;
171   myFace.Orientation(TopAbs_FORWARD);
172 }
173 //=======================================================================
174 //function : Orientation
175 //purpose  : 
176 //=======================================================================
177 TopAbs_Orientation BOPAlgo_BuilderFace::Orientation()const
178 {
179   return myOrientation;
180 }
181 //=======================================================================
182 //function : Face
183 //purpose  : 
184 //=======================================================================
185 const TopoDS_Face& BOPAlgo_BuilderFace::Face()const
186 {
187   return myFace;
188 }
189 //=======================================================================
190 //function : CheckData
191 //purpose  : 
192 //=======================================================================
193 void BOPAlgo_BuilderFace::CheckData()
194 {
195   myErrorStatus=0;
196   //
197   if (myFace.IsNull()) {
198     myErrorStatus=12;// Null face generix
199     return;
200   }
201   if (myContext.IsNull()) {
202     myContext = new IntTools_Context;
203   }
204 }
205 //=======================================================================
206 //function : Perform
207 //purpose  : 
208 //=======================================================================
209 void BOPAlgo_BuilderFace::Perform()
210 {
211   myErrorStatus=0;
212   //
213   CheckData();
214   if (myErrorStatus) {
215     return;
216   }
217   //
218   PerformShapesToAvoid();
219   if (myErrorStatus) {
220     return;
221   }
222   //
223   PerformLoops();
224   if (myErrorStatus) {
225     return;
226   }
227   //
228   PerformAreas();
229   if (myErrorStatus) {
230     return;
231   }
232   //
233   PerformInternalShapes();
234   if (myErrorStatus) {
235     return;
236   }
237 }
238 //=======================================================================
239 //function :PerformShapesToAvoid
240 //purpose  : 
241 //=======================================================================
242 void BOPAlgo_BuilderFace::PerformShapesToAvoid()
243 {
244   Standard_Boolean bFound;
245   Standard_Integer i, iCnt, aNbV, aNbE;
246   BOPCol_IndexedDataMapOfShapeListOfShape aMVE;
247   BOPCol_ListIteratorOfListOfShape aIt;
248   //
249   myShapesToAvoid.Clear();
250   //
251   iCnt=0;
252   for(;;) {
253     ++iCnt;
254     bFound=Standard_False;
255     //
256     // 1. MEF
257     aMVE.Clear();
258     aIt.Initialize (myShapes);
259     for (; aIt.More(); aIt.Next()) {
260       const TopoDS_Shape& aE=aIt.Value();
261       if (!myShapesToAvoid.Contains(aE)) {
262         BOPTools::MapShapesAndAncestors(aE, TopAbs_VERTEX, TopAbs_EDGE, aMVE);
263       }
264     }
265     aNbV=aMVE.Extent();
266     //
267     // 2. myEdgesToAvoid
268     for (i=1; i<=aNbV; ++i) {
269       const TopoDS_Vertex& aV=(*(TopoDS_Vertex *)(&aMVE.FindKey(i)));
270       //
271       BOPCol_ListOfShape& aLE=aMVE.ChangeFromKey(aV);
272       aNbE=aLE.Extent();
273       if (!aNbE) {
274         continue;
275       }
276       //
277       const TopoDS_Edge& aE1=(*(TopoDS_Edge *)(&aLE.First()));
278       if (aNbE==1) {
279         if (BRep_Tool::Degenerated(aE1)) {
280           continue;
281         }
282         if (aV.Orientation()==TopAbs_INTERNAL) {
283           continue;
284         }
285         bFound=Standard_True;
286         myShapesToAvoid.Add(aE1);
287       }
288       else if (aNbE==2) {
289         const TopoDS_Edge& aE2=(*(TopoDS_Edge *)(&aLE.Last()));
290         if (aE2.IsSame(aE1)) {
291           TopoDS_Vertex aV1x, aV2x;
292           //
293           TopExp::Vertices(aE1, aV1x, aV2x);
294           if (aV1x.IsSame(aV2x)) {
295             continue;
296           }
297           bFound=Standard_True;
298           myShapesToAvoid.Add(aE1);
299           myShapesToAvoid.Add(aE2);
300         }
301       }
302     }// for (i=1; i<=aNbE; ++i) {
303     //
304     if (!bFound) {
305       break;
306     }
307     //
308   }//while (1) 
309   //printf(" EdgesToAvoid=%d, iCnt=%d\n", EdgesToAvoid.Extent(), iCnt);
310 }  
311 //=======================================================================
312 //function : PerformLoops
313 //purpose  : 
314 //=======================================================================
315 void BOPAlgo_BuilderFace::PerformLoops()
316 {
317   myErrorStatus=0;
318   //
319   Standard_Boolean bFlag;
320   Standard_Integer iErr, aNbEA;
321   BOPCol_ListIteratorOfListOfShape aIt;
322   BOPCol_MapIteratorOfMapOfOrientedShape aItM;
323   BOPCol_IndexedDataMapOfShapeListOfShape aVEMap;
324   BOPCol_MapOfOrientedShape aMAdded;
325   TopoDS_Iterator aItW;
326   BRep_Builder aBB; 
327   BOPAlgo_WireEdgeSet aWES(myAllocator);
328   BOPAlgo_WireSplitter aWSp(myAllocator);
329   //
330   // 1. 
331   myLoops.Clear();
332   aWES.SetFace(myFace);
333   //
334   aIt.Initialize(myShapes);
335   for (; aIt.More(); aIt.Next()) {
336     const TopoDS_Shape& aE=aIt.Value();
337     if (!myShapesToAvoid.Contains(aE)) {
338       aWES.AddStartElement(aE);
339     }
340   }
341   //
342   aWSp.SetWES(aWES);
343   aWSp.SetRunParallel(myRunParallel);
344   aWSp.Perform();
345   iErr=aWSp.ErrorStatus();
346   if (iErr) {
347     return;
348   }
349   //
350   const BOPCol_ListOfShape& aLW=aWES.Shapes();
351   aIt.Initialize (aLW);
352   for (; aIt.More(); aIt.Next()) {
353     const TopoDS_Shape& aW=aIt.Value();
354     myLoops.Append(aW);
355   }
356   // Post Treatment
357   BOPCol_MapOfOrientedShape aMEP;
358   // 
359   // a. collect all edges that are in loops
360   aIt.Initialize (myLoops);
361   for (; aIt.More(); aIt.Next()) {
362     const TopoDS_Shape& aW=aIt.Value();
363     aItW.Initialize(aW);
364     for (; aItW.More(); aItW.Next()) {
365       const TopoDS_Shape& aE=aItW.Value();
366       aMEP.Add(aE);
367     }
368   }
369   // 
370   // b. collect all edges that are to avoid
371   aItM.Initialize(myShapesToAvoid);
372   for (; aItM.More(); aItM.Next()) {
373     const TopoDS_Shape& aE=aItM.Key();
374     aMEP.Add(aE);
375   }
376   //
377   // c. add all edges that are not processed to myShapesToAvoid
378   aIt.Initialize (myShapes);
379   for (; aIt.More(); aIt.Next()) {
380     const TopoDS_Shape& aE=aIt.Value();
381     if (!aMEP.Contains(aE)) {
382       myShapesToAvoid.Add(aE);
383     }
384   }
385   //
386   // 2. Internal Wires
387   myLoopsInternal.Clear();
388   //
389   aNbEA=myShapesToAvoid.Extent();
390   aItM.Initialize(myShapesToAvoid);
391   for (; aItM.More(); aItM.Next()) {
392     const TopoDS_Shape& aEE=aItM.Key();
393     BOPTools::MapShapesAndAncestors(aEE, 
394                                     TopAbs_VERTEX, 
395                                     TopAbs_EDGE, 
396                                     aVEMap);
397   }
398   //
399   bFlag=Standard_True;
400   aItM.Initialize(myShapesToAvoid);
401   for (; aItM.More()&&bFlag; aItM.Next()) {
402     const TopoDS_Shape& aEE=aItM.Key();
403     if (!aMAdded.Add(aEE)) {
404       continue;
405     }
406     //
407     // make new wire
408     TopoDS_Wire aW;
409     aBB.MakeWire(aW);
410     aBB.Add(aW, aEE);
411     //
412     aItW.Initialize(aW);
413     for (; aItW.More()&&bFlag; aItW.Next()) {
414       const TopoDS_Edge& aE=(*(TopoDS_Edge *)(&aItW.Value()));
415       //
416       TopoDS_Iterator aItE(aE);
417       for (; aItE.More()&&bFlag; aItE.Next()) {
418         const TopoDS_Vertex& aV = (*(TopoDS_Vertex *)(&aItE.Value()));
419         const BOPCol_ListOfShape& aLE=aVEMap.FindFromKey(aV);
420         aIt.Initialize(aLE);
421         for (; aIt.More()&&bFlag; aIt.Next()) { 
422           const TopoDS_Shape& aEx=aIt.Value();
423           if (aMAdded.Add(aEx)) {
424             aBB.Add(aW, aEx);
425             if(aMAdded.Extent()==aNbEA) {
426               bFlag=!bFlag;
427             }
428           }
429         }//for (; aIt.More(); aIt.Next()) { 
430       }//for (; aItE.More(); aItE.Next()) {
431     }//for (; aItW.More(); aItW.Next()) {
432     myLoopsInternal.Append(aW);
433   }//for (; aItM.More(); aItM.Next()) {
434 }
435 //
436
437 //=======================================================================
438 //function : PerformAreas
439 //purpose  : 
440 //=======================================================================
441 void BOPAlgo_BuilderFace::PerformAreas()
442 {
443   Standard_Boolean bIsGrowth, bIsHole;
444   Standard_Integer k,aNbHoles;
445   Standard_Real aTol;
446   TopLoc_Location aLoc;
447   Handle(Geom_Surface) aS;
448   BRep_Builder aBB;
449   TopoDS_Face aFace;
450   //
451   BOPCol_ListIteratorOfListOfInteger aItLI;
452   BOPCol_IndexedMapOfShape aMHE;
453   BOPCol_DataMapOfShapeShape aInOutMap;
454   BOPCol_DataMapIteratorOfDataMapOfShapeShape aItDMSS;
455   BOPCol_DataMapOfShapeListOfShape aMSH;
456   BOPCol_DataMapIteratorOfDataMapOfShapeListOfShape aItMSH;
457   BOPCol_ListIteratorOfListOfShape aIt1;
458   BOPAlgo_DataMapOfIntegerShapeBox2D aDMISB(100);
459   BOPAlgo_DataMapIteratorOfDataMapOfIntegerShapeBox2D aItDMISB;
460   //
461   BOPCol_Box2DBndTreeSelector aSelector;
462   BOPCol_Box2DBndTree aBBTree;
463   NCollection_UBTreeFiller <Standard_Integer, Bnd_Box2d> aTreeFiller(aBBTree);
464   //
465   myErrorStatus=0;
466   //
467   aTol=BRep_Tool::Tolerance(myFace);
468   aS=BRep_Tool::Surface(myFace, aLoc);
469   //
470   myAreas.Clear();
471   //
472   // 1. Growthes and Holes -> aDMISB: [Index/ShapeBox2D]
473   aIt1.Initialize(myLoops);
474   for (k=0 ; aIt1.More(); aIt1.Next(), ++k) {
475     Bnd_Box2d aBox2D;
476     //
477     const TopoDS_Shape& aWire=aIt1.Value();
478     //
479     aBB.MakeFace(aFace, aS, aLoc, aTol);
480     aBB.Add (aFace, aWire);
481     BRepTools::AddUVBounds(aFace, aBox2D);
482     //
483     bIsGrowth=IsGrowthWire(aWire, aMHE);
484     if (bIsGrowth) {
485       bIsHole=Standard_False;
486     }
487     else{
488       // check if a wire is a hole 
489       IntTools_FClass2d& aClsf=myContext->FClass2d(aFace);
490       aClsf.Init(aFace, aTol);
491       //
492       bIsHole=aClsf.IsHole();
493       if (bIsHole) {
494         BOPTools::MapShapes(aWire, TopAbs_EDGE, aMHE);
495           //
496           bIsHole=Standard_True;
497       }
498       else {
499         bIsHole=Standard_False;
500       }
501     }
502     //
503     BOPAlgo_ShapeBox2D aSB2D;
504     //
505     aSB2D.SetShape(aFace);
506     aSB2D.SetBox2D(aBox2D);
507     aSB2D.SetIsHole(bIsHole);
508     //
509     aDMISB.Bind(k, aSB2D);
510   }
511   //
512   // 2. Prepare TreeFiller
513   aItDMISB.Initialize(aDMISB);
514   for (; aItDMISB.More(); aItDMISB.Next()) {
515     k=aItDMISB.Key();
516     const BOPAlgo_ShapeBox2D& aSB2D=aItDMISB.Value();
517     //
518     bIsHole=aSB2D.IsHole();
519     if (bIsHole) {
520       const Bnd_Box2d& aBox2D=aSB2D.Box2D();
521       aTreeFiller.Add(k, aBox2D);
522     }
523   }
524   //
525   // 3. Shake TreeFiller
526   aTreeFiller.Fill();
527   //
528   // 4. Find outer growth shell that is most close 
529   //    to each hole shell
530   aItDMISB.Initialize(aDMISB);
531   for (; aItDMISB.More(); aItDMISB.Next()) {
532     k=aItDMISB.Key();
533     const BOPAlgo_ShapeBox2D& aSB2D=aItDMISB.Value();
534     bIsHole=aSB2D.IsHole();
535     if (bIsHole) {
536       continue;
537     }
538     //
539     const Bnd_Box2d& aBox2DF=aSB2D.Box2D();
540     const TopoDS_Shape aF=aSB2D.Shape();
541     //
542     aSelector.Clear();
543     aSelector.SetBox(aBox2DF);
544     //
545     aNbHoles=aBBTree.Select(aSelector);
546     //
547     const BOPCol_ListOfInteger& aLI=aSelector.Indices();
548     //
549     aItLI.Initialize(aLI);
550     for (; aItLI.More(); aItLI.Next()) {
551       k=aItLI.Value();
552       const BOPAlgo_ShapeBox2D& aSB2Dk=aDMISB.Find(k);
553       const TopoDS_Shape& aHole=aSB2Dk.Shape();
554       //
555       if (!IsInside(aHole, aF, myContext)){
556         continue;
557       }
558       //
559       if (aInOutMap.IsBound (aHole)){
560         const TopoDS_Shape& aF2=aInOutMap(aHole);
561         if (IsInside(aF, aF2, myContext)) {
562           aInOutMap.UnBind(aHole);
563           aInOutMap.Bind (aHole, aF);
564         }
565       }
566       else{
567         aInOutMap.Bind(aHole, aF);
568       }
569     }
570   }
571   //
572   // 5. Map [Face/Holes] -> aMSH 
573   aItDMSS.Initialize(aInOutMap);
574   for (; aItDMSS.More(); aItDMSS.Next()) {
575     const TopoDS_Shape& aHole=aItDMSS.Key();
576     const TopoDS_Shape& aF=aItDMSS.Value();
577     //
578     if (aMSH.IsBound(aF)) {
579       BOPCol_ListOfShape& aLH=aMSH.ChangeFind(aF);
580       aLH.Append(aHole);
581     }
582     else {
583       BOPCol_ListOfShape aLH;
584       aLH.Append(aHole);
585       aMSH.Bind(aF, aLH);
586     }
587   }
588   //
589   // 6. Add aHoles to Faces, 
590   aItMSH.Initialize(aMSH);
591   for (; aItMSH.More(); aItMSH.Next()) {
592     TopoDS_Face aF=(*(TopoDS_Face *)(&aItMSH.Key()));
593     //
594     const BOPCol_ListOfShape& aLH=aItMSH.Value();
595     aIt1.Initialize(aLH);
596     for (; aIt1.More(); aIt1.Next()) {
597       TopoDS_Shape aWHole;
598       //
599       const TopoDS_Shape& aFHole=aIt1.Value();
600       GetWire(aFHole, aWHole);
601       aBB.Add (aF, aWHole);
602     }
603     //
604     // update classifier 
605     aTol=BRep_Tool::Tolerance(aF);
606     IntTools_FClass2d& aClsf=myContext->FClass2d(aF);
607     aClsf.Init(aF, aTol);
608   }
609   //
610   // 7. Fill myAreas
611   //    NB:These aNewFaces are draft faces that 
612   //    do not contain any internal shapes
613   aItDMISB.Initialize(aDMISB);
614   for (; aItDMISB.More(); aItDMISB.Next()) {
615     const BOPAlgo_ShapeBox2D& aSB2D=aItDMISB.Value();
616     bIsHole=aSB2D.IsHole();
617     if (!bIsHole) {
618       const TopoDS_Shape aF=aSB2D.Shape();
619       myAreas.Append(aF);
620     }
621   }
622 }
623 //=======================================================================
624 //function : GetWire
625 //purpose  : 
626 //=======================================================================
627 void GetWire(const TopoDS_Shape& aF, TopoDS_Shape& aW) 
628 {
629   TopoDS_Shape aWx;
630   TopoDS_Iterator aIt;
631   //
632   aIt.Initialize(aF);
633   for (; aIt.More(); aIt.Next()) {
634     aW=aIt.Value();
635   }
636 }
637 //=======================================================================
638 //function : PerformInternalShapes
639 //purpose  : 
640 //=======================================================================
641 void BOPAlgo_BuilderFace::PerformInternalShapes()
642 {
643   myErrorStatus=0;
644   //
645   Standard_Integer aNbWI=myLoopsInternal.Extent();
646   if (!aNbWI) {// nothing to do
647     return;
648   }
649   // 
650   //Standard_Real aTol;
651   BRep_Builder aBB;
652   BOPCol_ListIteratorOfListOfShape aIt1, aIt2;
653   TopoDS_Iterator aIt; 
654   BOPCol_MapOfShape aME, aMEP;
655   BOPCol_MapIteratorOfMapOfShape aItME;
656   BOPCol_IndexedDataMapOfShapeListOfShape aMVE;
657   BOPCol_ListOfShape aLSI;
658   //
659   // 1. All internal edges
660   aIt1.Initialize(myLoopsInternal);
661   for (; aIt1.More(); aIt1.Next()) {
662     const TopoDS_Shape& aWire=aIt1.Value();
663     aIt.Initialize(aWire);
664     for (; aIt.More(); aIt.Next()) {
665       const TopoDS_Shape& aE=aIt.Value();
666       aME.Add(aE);
667     }
668   }
669   aNbWI=aME.Extent();
670   //
671   // 2 Process faces
672   aIt2.Initialize(myAreas);
673   for ( ; aIt2.More(); aIt2.Next()) {
674     TopoDS_Face& aF=(*(TopoDS_Face *)(&aIt2.Value()));
675     //
676     aMVE.Clear();
677     BOPTools::MapShapesAndAncestors(aF, TopAbs_VERTEX, TopAbs_EDGE, aMVE);
678     //
679     // 2.1 Separate faces to process aMEP
680     aMEP.Clear();
681     aItME.Initialize(aME);
682     for (; aItME.More(); aItME.Next()) {
683       const TopoDS_Edge& aE=(*(TopoDS_Edge *)(&aItME.Key()));
684       if (IsInside(aE, aF, myContext)) {
685         aMEP.Add(aE);
686       }
687     }
688     //
689     // 2.2 Make Internal Wires
690     aLSI.Clear();
691     MakeInternalWires(aMEP, aLSI);
692     //
693     // 2.3 Add them to aF
694     aIt1.Initialize(aLSI);
695     for (; aIt1.More(); aIt1.Next()) {
696       const TopoDS_Shape& aSI=aIt1.Value();
697       aBB.Add (aF, aSI);
698     }
699     //
700     // 2.4 Remove faces aMFP from aMF
701     aItME.Initialize(aMEP);
702     for (; aItME.More(); aItME.Next()) {
703       const TopoDS_Shape& aE=aItME.Key();
704       aME.Remove(aE);
705     }
706     //
707     aNbWI=aME.Extent();
708     if (!aNbWI) {
709       break;
710     }
711   } //for ( ; aIt2.More(); aIt2.Next()) {
712 }
713 //=======================================================================
714 //function : MakeInternalWires
715 //purpose  : 
716 //=======================================================================
717 void MakeInternalWires(const BOPCol_MapOfShape& theME,
718                        BOPCol_ListOfShape& theWires)
719 {
720   BOPCol_MapIteratorOfMapOfShape aItM;
721   BOPCol_MapOfShape aAddedMap;
722   BOPCol_ListIteratorOfListOfShape aItE;
723   BOPCol_IndexedDataMapOfShapeListOfShape aMVE;
724   BRep_Builder aBB;
725   //
726   aItM.Initialize(theME);
727   for (; aItM.More(); aItM.Next()) {
728     const TopoDS_Shape& aE=aItM.Key();
729     BOPTools::MapShapesAndAncestors(aE, TopAbs_VERTEX, TopAbs_EDGE, aMVE);
730   }
731   //
732   aItM.Initialize(theME);
733   for (; aItM.More(); aItM.Next()) {
734     TopoDS_Shape aEE=aItM.Key();
735     if (!aAddedMap.Add(aEE)) {
736       continue;
737     }
738     //
739     // make a new shell
740     TopoDS_Wire aW;
741     aBB.MakeWire(aW);    
742     aEE.Orientation(TopAbs_INTERNAL);
743     aBB.Add(aW, aEE);
744     //
745     TopoDS_Iterator aItAdded (aW);
746     for (; aItAdded.More(); aItAdded.Next()) {
747       const TopoDS_Shape& aE =aItAdded.Value();
748       //
749       TopExp_Explorer aExp(aE, TopAbs_VERTEX);
750       for (; aExp.More(); aExp.Next()) {
751         const TopoDS_Shape& aV =aExp.Current();
752         const BOPCol_ListOfShape& aLE=aMVE.FindFromKey(aV);
753         aItE.Initialize(aLE);
754         for (; aItE.More(); aItE.Next()) { 
755           TopoDS_Shape aEL=aItE.Value();
756           if (aAddedMap.Add(aEL)){
757             aEL.Orientation(TopAbs_INTERNAL);
758             aBB.Add(aW, aEL);
759           }
760         }
761       }
762     }
763     theWires.Append(aW);
764   }
765 }
766 //=======================================================================
767 //function : IsInside
768 //purpose  : 
769 //=======================================================================
770 Standard_Boolean IsInside(const TopoDS_Shape& theHole,
771                           const TopoDS_Shape& theF2,
772                           Handle(IntTools_Context)& theContext)
773 {
774   Standard_Boolean bRet;
775   Standard_Real aT, aU, aV;
776   
777   TopAbs_State aState;
778   TopExp_Explorer aExp;
779   BOPCol_IndexedMapOfShape aME2;
780   gp_Pnt2d aP2D;
781   //
782   bRet=Standard_False;
783   aState=TopAbs_UNKNOWN;
784   const TopoDS_Face& aF2=(*(TopoDS_Face *)(&theF2));
785   //
786   BOPTools::MapShapes(aF2, TopAbs_EDGE, aME2);//AA
787   //
788   aExp.Init(theHole, TopAbs_EDGE);
789   if (aExp.More()) {
790     const TopoDS_Edge& aE =(*(TopoDS_Edge *)(&aExp.Current()));
791     if (aME2.Contains(aE)) {
792       return bRet;
793     }
794     if (!BRep_Tool::Degenerated(aE)) {
795       //
796       aT=BOPTools_AlgoTools2D::IntermediatePoint(aE);
797       BOPTools_AlgoTools2D::PointOnSurface(aE, aF2, aT, aU, aV);
798       aP2D.SetCoord(aU, aV);
799       //
800       IntTools_FClass2d& aClsf=theContext->FClass2d(aF2);
801       aState=aClsf.Perform(aP2D);
802       bRet=(aState==TopAbs_IN);
803     }
804   }
805   //
806   return bRet;
807 }
808
809 //=======================================================================
810 //function : IsGrowthWire
811 //purpose  : 
812 //=======================================================================
813 Standard_Boolean IsGrowthWire(const TopoDS_Shape& theWire,
814                               const BOPCol_IndexedMapOfShape& theMHE)
815 {
816   Standard_Boolean bRet;
817   TopoDS_Iterator aIt;
818   // 
819   bRet=Standard_False;
820   if (theMHE.Extent()) {
821     aIt.Initialize(theWire);
822     for(; aIt.More(); aIt.Next()) {
823       const TopoDS_Shape& aE=aIt.Value();
824       if (theMHE.Contains(aE)) {
825         return !bRet;
826       }
827     }
828   }
829   return bRet;
830 }
831
832 //BRepTools::Write(aFF, "ff");
833 //
834 //  ErrorStatus :
835 // 11 - Null Context
836 // 12 - Null face generix