Salome HOME
Update from BR_V5_DEV 13Feb2009
[modules/geom.git] / src / GEOMAlgo / GEOMAlgo_BuilderFace.cxx
1 //  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 //  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 //  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 //  This library is free software; you can redistribute it and/or
7 //  modify it under the terms of the GNU Lesser General Public
8 //  License as published by the Free Software Foundation; either
9 //  version 2.1 of the License.
10 //
11 //  This library is distributed in the hope that it will be useful,
12 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
13 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 //  Lesser General Public License for more details.
15 //
16 //  You should have received a copy of the GNU Lesser General Public
17 //  License along with this library; if not, write to the Free Software
18 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 //  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22 // File:        GEOMAlgo_BuilderFace.cxx
23 // Created:     
24 // Author:      Peter KURNEV
25 //
26 #include <GEOMAlgo_BuilderFace.ixx>
27
28 #include <gp_Pnt2d.hxx>
29 #include <gp_Pln.hxx>
30 #include <gp_Vec.hxx>
31 #include <gp_Dir.hxx>
32 #include <gp_Pnt.hxx>
33
34 #include <Geom_Surface.hxx>
35
36 #include <TopAbs.hxx>
37 #include <TopLoc_Location.hxx>
38
39 #include <TopoDS_Iterator.hxx>
40 #include <TopoDS_Face.hxx>
41 #include <TopoDS.hxx>
42 #include <TopoDS_Shape.hxx>
43 #include <TopoDS_Wire.hxx>
44 #include <TopoDS_Edge.hxx>
45 #include <TopoDS_Vertex.hxx>
46
47 #include <BRep_Builder.hxx>
48 #include <BRep_Tool.hxx>
49 #include <BRepTools.hxx>
50
51 #include <TopExp.hxx>
52 #include <TopExp_Explorer.hxx>
53
54 #include <TopTools_MapOfShape.hxx>
55 #include <TopTools_MapIteratorOfMapOfShape.hxx>
56 #include <TopTools_MapOfOrientedShape.hxx>
57 #include <TopTools_MapIteratorOfMapOfOrientedShape.hxx>
58 #include <TopTools_ListOfShape.hxx>
59 #include <TopTools_ListIteratorOfListOfShape.hxx>
60 #include <TopTools_DataMapOfShapeShape.hxx>
61 #include <TopTools_IndexedMapOfShape.hxx>
62 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
63 #include <TopTools_DataMapOfShapeListOfShape.hxx>
64 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
65
66 #include <IntTools_FClass2d.hxx>
67 #include <IntTools_Context.hxx>
68
69 #include <BOPTools_Tools2D.hxx>
70 #include <BOP_WireEdgeSet.hxx>
71 #include <BOP_WESCorrector.hxx>
72
73 #include <NMTTools_ListOfCoupleOfShape.hxx>
74 #include <NMTTools_CoupleOfShape.hxx>
75 #include <NMTTools_ListIteratorOfListOfCoupleOfShape.hxx>
76
77 #include <GEOMAlgo_Tools3D.hxx>
78 #include <GEOMAlgo_BuilderTools.hxx>
79 #include <GEOMAlgo_WireEdgeSet.hxx>
80 #include <GEOMAlgo_WESCorrector.hxx>
81
82 //
83 static
84   Standard_Boolean IsGrowthWire(const TopoDS_Shape& ,
85
86                                 const TopTools_IndexedMapOfShape& );
87
88 static 
89   Standard_Boolean IsInside(const TopoDS_Shape& ,
90                             const TopoDS_Shape& ,
91                             IntTools_PContext& );
92 static
93   void MakeInternalWires(const TopTools_MapOfShape& ,
94                          TopTools_ListOfShape& );
95
96 //=======================================================================
97 //function : 
98 //purpose  : 
99 //=======================================================================
100   GEOMAlgo_BuilderFace::GEOMAlgo_BuilderFace()
101 :
102   GEOMAlgo_BuilderArea()
103 {
104 }
105 //=======================================================================
106 //function : ~
107 //purpose  : 
108 //=======================================================================
109   GEOMAlgo_BuilderFace::~GEOMAlgo_BuilderFace()
110 {
111 }
112 //=======================================================================
113 //function : SetFace
114 //purpose  : 
115 //=======================================================================
116   void GEOMAlgo_BuilderFace::SetFace(const TopoDS_Face& theFace)
117 {
118   myFace=theFace;
119 }
120 //=======================================================================
121 //function : Face
122 //purpose  : 
123 //=======================================================================
124   const TopoDS_Face& GEOMAlgo_BuilderFace::Face()const
125 {
126   return myFace;
127 }
128 //=======================================================================
129 //function : Perform
130 //purpose  : 
131 //=======================================================================
132   void GEOMAlgo_BuilderFace::Perform()
133 {
134   myErrorStatus=0;
135   //
136   if (myContext==NULL) {
137     myErrorStatus=11;// Null Context
138     return;
139   }
140   //
141   if (myFace.IsNull()) {
142     myErrorStatus=12;// Null face generix
143     return;
144   }
145   //
146   PerformShapesToAvoid();
147   if (myErrorStatus) {
148     return;
149   }
150   //
151   PerformLoops();
152   if (myErrorStatus) {
153     return;
154   }
155   //
156   PerformAreas();
157   if (myErrorStatus) {
158     return;
159   }
160   //
161   PerformInternalShapes();
162   if (myErrorStatus) {
163     return;
164   }
165 }
166 //=======================================================================
167 //function :PerformShapesToAvoid
168 //purpose  : 
169 //=======================================================================
170   void GEOMAlgo_BuilderFace::PerformShapesToAvoid()
171 {
172   Standard_Boolean bFound;
173   Standard_Integer i, iCnt, aNbV, aNbE;
174   TopTools_IndexedDataMapOfShapeListOfShape aMVE;
175   TopTools_ListIteratorOfListOfShape aIt;
176   //
177   myShapesToAvoid.Clear();
178   //
179   iCnt=0;
180   while (1) {
181     ++iCnt;
182     bFound=Standard_False;
183     //
184     // 1. MEF
185     aMVE.Clear();
186     aIt.Initialize (myShapes);
187     for (; aIt.More(); aIt.Next()) {
188       const TopoDS_Shape& aE=aIt.Value();
189       if (!myShapesToAvoid.Contains(aE)) {
190         TopExp::MapShapesAndAncestors(aE, TopAbs_VERTEX, TopAbs_EDGE, aMVE);
191       }
192       else {
193         int a=0;
194       }
195     }
196     aNbV=aMVE.Extent();
197     //
198     // 2. myEdgesToAvoid
199     for (i=1; i<=aNbV; ++i) {
200       const TopoDS_Vertex& aV=TopoDS::Vertex(aMVE.FindKey(i));
201       //
202       TopTools_ListOfShape& aLE=aMVE.ChangeFromKey(aV);
203       aNbE=aLE.Extent();
204       if (!aNbE) {
205         continue;
206       }
207       //
208       const TopoDS_Edge& aE1=TopoDS::Edge(aLE.First());
209       if (aNbE==1) {
210         if (BRep_Tool::Degenerated(aE1)) {
211           continue;
212         }
213         if (aV.Orientation()==TopAbs_INTERNAL) {
214           continue;
215         }
216         bFound=Standard_True;
217         myShapesToAvoid.Add(aE1);
218       }
219       else if (aNbE==2) {
220         const TopoDS_Edge& aE2=TopoDS::Edge(aLE.Last());
221         if (aE2.IsSame(aE1)) {
222           TopoDS_Vertex aV1x, aV2x;
223           //
224           TopExp::Vertices(aE1, aV1x, aV2x);
225           if (aV1x.IsSame(aV2x)) {
226             continue;
227           }
228           bFound=Standard_True;
229           myShapesToAvoid.Add(aE1);
230           myShapesToAvoid.Add(aE2);
231         }
232       }
233     }// for (i=1; i<=aNbE; ++i) {
234     //
235     if (!bFound) {
236       break;
237     }
238     //
239   }//while (1) 
240   //printf(" EdgesToAvoid=%d, iCnt=%d\n", EdgesToAvoid.Extent(), iCnt);
241 }  
242 //=======================================================================
243 //function : PerformLoops
244 //purpose  : 
245 //=======================================================================
246   void GEOMAlgo_BuilderFace::PerformLoops()
247 {
248   myErrorStatus=0;
249   //
250   Standard_Boolean bFlag;
251   Standard_Integer aNbEA;
252   TopTools_ListIteratorOfListOfShape aIt;
253   TopTools_MapIteratorOfMapOfOrientedShape aItM;
254   TopTools_IndexedDataMapOfShapeListOfShape aVEMap;
255   TopTools_MapOfOrientedShape aMAdded;
256   TopoDS_Iterator aItW;
257   BRep_Builder aBB; 
258   GEOMAlgo_WireEdgeSet aWES;
259   GEOMAlgo_WESCorrector aWESCor;
260   //
261   // 1. Usual Wires 
262   myLoops.Clear();
263   aWES.SetFace(myFace);
264   //
265   aIt.Initialize (myShapes);
266   for (; aIt.More(); aIt.Next()) {
267     const TopoDS_Shape& aE=aIt.Value();
268     if (!myShapesToAvoid.Contains(aE)) {
269       aWES.AddStartElement(aE);
270     }
271   }
272   //
273   aWESCor.SetWES(aWES);
274   aWESCor.Perform();
275   //
276   GEOMAlgo_WireEdgeSet& aWESN=aWESCor.NewWES();
277   const TopTools_ListOfShape& aLW=aWESN.Shapes();
278   //
279   aIt.Initialize (aLW);
280   for (; aIt.More(); aIt.Next()) {
281     const TopoDS_Shape& aW=aIt.Value();
282     myLoops.Append(aW);
283   }
284   //modified by NIZNHY-PKV Tue Aug  5 15:09:29 2008f
285   // Post Treatment
286   TopTools_MapOfOrientedShape aMEP;
287   // 
288   // a. collect all edges that are in loops
289   aIt.Initialize (myLoops);
290   for (; aIt.More(); aIt.Next()) {
291     const TopoDS_Shape& aW=aIt.Value();
292     aItW.Initialize(aW);
293     for (; aItW.More(); aItW.Next()) {
294       const TopoDS_Shape& aE=aItW.Value();
295       aMEP.Add(aE);
296     }
297   }
298   // 
299   // b. collect all edges that are to avoid
300   aItM.Initialize(myShapesToAvoid);
301   for (; aItM.More(); aItM.Next()) {
302     const TopoDS_Shape& aE=aItM.Key();
303     aMEP.Add(aE);
304   }
305   //
306   // c. add all edges that are not processed to myShapesToAvoid
307   aIt.Initialize (myShapes);
308   for (; aIt.More(); aIt.Next()) {
309     const TopoDS_Shape& aE=aIt.Value();
310     if (!aMEP.Contains(aE)) {
311       myShapesToAvoid.Add(aE);
312     }
313   }
314   //modified by NIZNHY-PKV Tue Aug  5 15:09:35 2008t
315   //
316   // 2. Internal Wires
317   myLoopsInternal.Clear();
318   //
319   aNbEA=myShapesToAvoid.Extent();
320   aItM.Initialize(myShapesToAvoid);
321   for (; aItM.More(); aItM.Next()) {
322     const TopoDS_Shape& aEE=aItM.Key();
323     TopExp::MapShapesAndAncestors(aEE, TopAbs_VERTEX, TopAbs_EDGE, aVEMap);
324   }
325   //
326   bFlag=Standard_True;
327   aItM.Initialize(myShapesToAvoid);
328   for (; aItM.More()&&bFlag; aItM.Next()) {
329     const TopoDS_Shape& aEE=aItM.Key();
330     if (!aMAdded.Add(aEE)) {
331       continue;
332     }
333     //
334     // make new wire
335     TopoDS_Wire aW;
336     aBB.MakeWire(aW);
337     aBB.Add(aW, aEE);
338     //
339     aItW.Initialize(aW);
340     for (; aItW.More()&&bFlag; aItW.Next()) {
341       const TopoDS_Edge& aE=TopoDS::Edge(aItW.Value());
342       //
343       TopoDS_Iterator aItE(aE);
344       for (; aItE.More()&&bFlag; aItE.Next()) {
345         const TopoDS_Vertex& aV = TopoDS::Vertex(aItE.Value());
346         const TopTools_ListOfShape& aLE=aVEMap.FindFromKey(aV);
347         aIt.Initialize(aLE);
348         for (; aIt.More()&&bFlag; aIt.Next()) { 
349           const TopoDS_Shape& aEx=aIt.Value();
350           if (aMAdded.Add(aEx)) {
351             aBB.Add(aW, aEx);
352             if(aMAdded.Extent()==aNbEA) {
353               bFlag=!bFlag;
354             }
355           }
356         }//for (; aIt.More(); aIt.Next()) { 
357       }//for (; aItE.More(); aItE.Next()) {
358     }//for (; aItW.More(); aItW.Next()) {
359     myLoopsInternal.Append(aW);
360   }//for (; aItM.More(); aItM.Next()) {
361 }
362 //=======================================================================
363 //function : PerformAreas
364 //purpose  : 
365 //=======================================================================
366   void GEOMAlgo_BuilderFace::PerformAreas()
367 {
368   myErrorStatus=0;
369   //
370   Standard_Boolean bIsGrowth, bIsHole;
371   Standard_Real aTol;
372   TopTools_ListOfShape aNewFaces, aHoleWires; 
373   TopoDS_Shape anInfinitePointShape;
374   TopTools_DataMapOfShapeShape aInOutMap;
375   TopTools_DataMapOfShapeListOfShape aMSH;
376   TopTools_DataMapIteratorOfDataMapOfShapeListOfShape aItMSH;
377   TopTools_ListIteratorOfListOfShape aIt1, aIt2;
378   TopTools_IndexedMapOfShape aMHE;
379   BRep_Builder aBB;
380   Handle(Geom_Surface) aS;
381   TopLoc_Location aLoc;
382   //
383   aTol=BRep_Tool::Tolerance(myFace);
384   aS=BRep_Tool::Surface(myFace, aLoc);
385   //
386   myAreas.Clear();
387   //
388   //  Draft faces [aNewFaces]
389   aIt1.Initialize(myLoops);
390   for ( ; aIt1.More(); aIt1.Next()) {
391     const TopoDS_Shape& aWire=aIt1.Value();
392     //
393     bIsGrowth=IsGrowthWire(aWire, aMHE);
394     if (bIsGrowth) {
395       // make a growth face from a wire
396       TopoDS_Face aFace;
397       aBB.MakeFace(aFace, aS, aLoc, aTol);
398       aBB.Add (aFace, aWire);
399       //
400       aNewFaces.Append (aFace);
401     }
402     else{
403       // check if a wire is a hole 
404       //XX
405       //bIsHole=IsHole(aWire, myFace, myContext);
406       bIsHole=GEOMAlgo_BuilderTools::IsHole(aWire, myFace);
407       //XX
408       if (bIsHole) {
409         aHoleWires.Append(aWire);
410         TopExp::MapShapes(aWire, TopAbs_EDGE, aMHE);
411       }
412       else {
413         // make a growth face from a wire
414         TopoDS_Face aFace;
415         aBB.MakeFace(aFace, aS, aLoc, aTol);
416         aBB.Add (aFace, aWire);
417         //
418         aNewFaces.Append (aFace);
419       }
420     }
421   }
422   //
423   // 2. Find outer growth shell that is most close to each hole shell
424   aIt2.Initialize(aHoleWires);
425   for (; aIt2.More(); aIt2.Next()) {
426     const TopoDS_Shape& aHole = aIt2.Value();
427     //
428     aIt1.Initialize(aNewFaces);
429     for ( ; aIt1.More(); aIt1.Next()) {
430       const TopoDS_Shape& aF=aIt1.Value();
431       //
432       if (!IsInside(aHole, aF, myContext)){
433         continue;
434       }
435       //
436       if ( aInOutMap.IsBound (aHole)){
437         const TopoDS_Shape& aF2=aInOutMap(aHole);
438         if (IsInside(aF, aF2, myContext)) {
439           aInOutMap.UnBind(aHole);
440           aInOutMap.Bind (aHole, aF);
441         }
442       }
443       else{
444         aInOutMap.Bind (aHole, aF);
445       }
446     }
447     //
448     // Add aHole to a map Face/ListOfHoles [aMSH]
449     if (aInOutMap.IsBound(aHole)){
450       const TopoDS_Shape& aF=aInOutMap(aHole);
451       if (aMSH.IsBound(aF)) {
452         TopTools_ListOfShape& aLH=aMSH.ChangeFind(aF);
453         aLH.Append(aHole);
454       }
455       else {
456         TopTools_ListOfShape aLH;
457         aLH.Append(aHole);
458         aMSH.Bind(aF, aLH);
459       }
460     }
461   }// for (; aIt2.More(); aIt2.Next())
462   //
463   // 3. Add aHoles to Faces
464   aItMSH.Initialize(aMSH);
465   for (; aItMSH.More(); aItMSH.Next()) {
466     TopoDS_Face aF=TopoDS::Face(aItMSH.Key());
467     //
468     const TopTools_ListOfShape& aLH=aItMSH.Value();
469     aIt2.Initialize(aLH);
470     for (; aIt2.More(); aIt2.Next()) {
471       const TopoDS_Shape& aHole = aIt2.Value();
472       aBB.Add (aF, aHole);
473     }
474     //
475     // update classifier 
476     aTol=BRep_Tool::Tolerance(aF);
477     IntTools_FClass2d& aClsf=myContext->FClass2d(aF);
478     aClsf.Init(aF, aTol);
479   }
480   //
481   // These aNewFaces are draft faces that 
482   // do not contain any internal shapes
483   //
484   myAreas.Append(aNewFaces);
485 }
486 //=======================================================================
487 //function : PerformInternalShapes
488 //purpose  : 
489 //=======================================================================
490   void GEOMAlgo_BuilderFace::PerformInternalShapes()
491 {
492   myErrorStatus=0;
493   //
494   Standard_Integer aNbWI=myLoopsInternal.Extent();
495   if (!aNbWI) {// nothing to do
496     return;
497   }
498   // 
499   //Standard_Real aTol;
500   BRep_Builder aBB;
501   TopTools_ListIteratorOfListOfShape aIt1, aIt2;
502   TopoDS_Iterator aIt; 
503   TopTools_MapOfShape aME, aMEP;
504   TopTools_MapIteratorOfMapOfShape aItME;
505   TopTools_IndexedDataMapOfShapeListOfShape aMVE;
506   TopTools_ListOfShape aLSI;
507   //
508   // 1. All internal edges
509   aIt1.Initialize(myLoopsInternal);
510   for (; aIt1.More(); aIt1.Next()) {
511     const TopoDS_Shape& aWire=aIt1.Value();
512     aIt.Initialize(aWire);
513     for (; aIt.More(); aIt.Next()) {
514       const TopoDS_Shape& aE=aIt.Value();
515       aME.Add(aE);
516     }
517   }
518   aNbWI=aME.Extent();
519   //
520   // 2 Process faces
521   aIt2.Initialize(myAreas);
522   for ( ; aIt2.More(); aIt2.Next()) {
523     TopoDS_Face& aF=TopoDS::Face(aIt2.Value());
524     //
525     aMVE.Clear();
526     TopExp::MapShapesAndAncestors(aF, TopAbs_VERTEX, TopAbs_EDGE, aMVE);
527     //
528     // 2.1 Separate faces to process aMEP
529     aMEP.Clear();
530     aItME.Initialize(aME);
531     for (; aItME.More(); aItME.Next()) {
532       const TopoDS_Edge& aE=TopoDS::Edge(aItME.Key());
533       if (IsInside(aE, aF, myContext)) {
534         aMEP.Add(aE);
535       }
536     }
537     //
538     // 2.2 Make Internal Wires
539     aLSI.Clear();
540     MakeInternalWires(aMEP, aLSI);
541     //
542     // 2.3 Add them to aF
543     aIt1.Initialize(aLSI);
544     for (; aIt1.More(); aIt1.Next()) {
545       const TopoDS_Shape& aSI=aIt1.Value();
546       aBB.Add (aF, aSI);
547     }
548     //
549     // 2.4 Remove faces aMFP from aMF
550     aItME.Initialize(aMEP);
551     for (; aItME.More(); aItME.Next()) {
552       const TopoDS_Shape& aE=aItME.Key();
553       aME.Remove(aE);
554     }
555     //
556     aNbWI=aME.Extent();
557     if (!aNbWI) {
558       break;
559     }
560   } //for ( ; aIt2.More(); aIt2.Next()) {
561 }
562 //=======================================================================
563 //function : MakeInternalWires
564 //purpose  : 
565 //=======================================================================
566 void MakeInternalWires(const TopTools_MapOfShape& theME,
567                        TopTools_ListOfShape& theWires)
568 {
569   TopTools_MapIteratorOfMapOfShape aItM;
570   TopTools_MapOfShape aAddedMap;
571   TopTools_ListIteratorOfListOfShape aItE;
572   TopTools_IndexedDataMapOfShapeListOfShape aMVE;
573   BRep_Builder aBB;
574   //
575   aItM.Initialize(theME);
576   for (; aItM.More(); aItM.Next()) {
577     const TopoDS_Shape& aE=aItM.Key();
578     TopExp::MapShapesAndAncestors(aE, TopAbs_VERTEX, TopAbs_EDGE, aMVE);
579   }
580   //
581   aItM.Initialize(theME);
582   for (; aItM.More(); aItM.Next()) {
583     TopoDS_Shape aEE=aItM.Key();
584     if (!aAddedMap.Add(aEE)) {
585       continue;
586     }
587     //
588     // make a new shell
589     TopoDS_Wire aW;
590     aBB.MakeWire(aW);    
591     aEE.Orientation(TopAbs_INTERNAL);
592     aBB.Add(aW, aEE);
593     //
594     TopoDS_Iterator aItAdded (aW);
595     for (; aItAdded.More(); aItAdded.Next()) {
596       const TopoDS_Shape& aE =aItAdded.Value();
597       //
598       TopExp_Explorer aExp(aE, TopAbs_VERTEX);
599       for (; aExp.More(); aExp.Next()) {
600         const TopoDS_Shape& aV =aExp.Current();
601         const TopTools_ListOfShape& aLE=aMVE.FindFromKey(aV);
602         aItE.Initialize(aLE);
603         for (; aItE.More(); aItE.Next()) { 
604           TopoDS_Shape aEL=aItE.Value();
605           if (aAddedMap.Add(aEL)){
606             aEL.Orientation(TopAbs_INTERNAL);
607             aBB.Add(aW, aEL);
608           }
609         }
610       }
611     }
612     theWires.Append(aW);
613   }
614 }
615 //=======================================================================
616 //function : IsInside
617 //purpose  : 
618 //=======================================================================
619 Standard_Boolean IsInside(const TopoDS_Shape& theHole,
620                           const TopoDS_Shape& theF2,
621                           IntTools_PContext& theContext)
622 {
623   Standard_Boolean bRet;
624   Standard_Real aT, aU, aV;
625   
626   TopAbs_State aState;
627   TopExp_Explorer aExp;
628   TopTools_IndexedMapOfShape aME2;
629   gp_Pnt2d aP2D;
630   //
631   bRet=Standard_False;
632   aState=TopAbs_UNKNOWN;
633   const TopoDS_Face& aF2=TopoDS::Face(theF2);
634   //
635   TopExp::MapShapes(aF2, TopAbs_EDGE, aME2);
636   //
637   aExp.Init(theHole, TopAbs_EDGE);
638   if (aExp.More()) {
639     const TopoDS_Edge& aE = TopoDS::Edge(aExp.Current());
640     if (aME2.Contains(aE)) {
641       return bRet;
642     }
643     //
644     aT=BOPTools_Tools2D::IntermediatePoint(aE);
645     BOPTools_Tools2D::PointOnSurface(aE, aF2, aT, aU, aV);
646     aP2D.SetCoord(aU, aV);
647     //
648     IntTools_FClass2d& aClsf=theContext->FClass2d(aF2);
649     aState=aClsf.Perform(aP2D);
650     bRet=(aState==TopAbs_IN);
651   }
652   //
653   return bRet;
654 }
655
656 //=======================================================================
657 //function : IsGrowthWire
658 //purpose  : 
659 //=======================================================================
660 Standard_Boolean IsGrowthWire(const TopoDS_Shape& theWire,
661                               const TopTools_IndexedMapOfShape& theMHE)
662 {
663   Standard_Boolean bRet;
664   TopoDS_Iterator aIt;
665   // 
666   bRet=Standard_False;
667   if (theMHE.Extent()) {
668     aIt.Initialize(theWire);
669     for(; aIt.More(); aIt.Next()) {
670       const TopoDS_Shape& aE=aIt.Value();
671       if (theMHE.Contains(aE)) {
672         return !bRet;
673       }
674     }
675   }
676   return bRet;
677 }
678
679 //BRepTools::Write(aFF, "ff");
680 //
681 //  ErrorStatus :
682 // 11 - Null Context
683 // 12 - Null face generix
684
685 /*
686 //=======================================================================
687 //function : IsInside
688 //purpose  : 
689 //=======================================================================
690 Standard_Boolean IsInside(const TopoDS_Shape& theHole,
691                           const TopoDS_Shape& theF2,
692                           IntTools_PContext& theContext)
693 {
694   Standard_Real aT, aU, aV;
695   TopExp_Explorer aExp;
696   TopAbs_State aState=TopAbs_UNKNOWN;
697   gp_Pnt2d aP2D;
698   //
699   const TopoDS_Face& aF2=TopoDS::Face(theF2);
700   //
701   aExp.Init(theHole, TopAbs_EDGE);
702   if (aExp.More()){
703     const TopoDS_Edge& aE = TopoDS::Edge(aExp.Current());
704     aT=BOPTools_Tools2D::IntermediatePoint(aE);
705     BOPTools_Tools2D::PointOnSurface(aE, aF2, aT, aU, aV);
706     aP2D.SetCoord(aU, aV);
707     //
708     IntTools_FClass2d& aClsf=theContext->FClass2d(aF2);
709     aState=aClsf.Perform(aP2D);
710   }
711   return (aState==TopAbs_IN);
712 }
713 */