0023024: Update headers of OCCT files
[occt.git] / src / BOP / BOP_FaceBuilder.cxx
1 // Created by: Mister Open CAS.CADE
2 // Copyright (c) 1999-2012 OPEN CASCADE SAS
3 //
4 // The content of this file is subject to the Open CASCADE Technology Public
5 // License Version 6.5 (the "License"). You may not use the content of this file
6 // except in compliance with the License. Please obtain a copy of the License
7 // at http://www.opencascade.org and read it completely before using this file.
8 //
9 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
10 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
11 //
12 // The Original Code and all software distributed under the License is
13 // distributed on an "AS IS" basis, without warranty of any kind, and the
14 // Initial Developer hereby disclaims all such warranties, including without
15 // limitation, any warranties of merchantability, fitness for a particular
16 // purpose or non-infringement. Please see the License for the specific terms
17 // and conditions governing the rights and limitations under the License.
18
19
20 #include <BOP_FaceBuilder.ixx>
21
22 #include <Geom2d_Curve.hxx>
23 #include <Geom_Surface.hxx>
24 #include <Geom_Curve.hxx>
25
26 #include <BRep_Builder.hxx>
27 #include <BRep_Tool.hxx>
28 #include <BRepAdaptor_Surface.hxx>
29
30 #include <TopAbs_Orientation.hxx>
31
32 #include <TopLoc_Location.hxx>
33
34 #include <TopTools_IndexedMapOfShape.hxx>
35 #include <TopTools_IndexedMapOfOrientedShape.hxx>
36 #include <TopTools_ListOfShape.hxx>
37 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
38 #include <TopTools_ListIteratorOfListOfShape.hxx>
39
40 #include <TopoDS.hxx>
41 #include <TopoDS_Face.hxx>
42 #include <TopoDS_Edge.hxx>
43 #include <TopoDS_Vertex.hxx>
44
45 #include <TopExp.hxx>
46
47 #include <IntTools_Tools.hxx>
48 #include <IntTools_FClass2d.hxx>
49 #include <IntTools_Context.hxx>
50
51 #include <BOP_WireEdgeClassifier.hxx>
52 #include <BOP_Loop.hxx>
53 #include <BOP_BlockBuilder.hxx>
54 #include <BOP_LoopSet.hxx>
55 #include <BOP_WESCorrector.hxx>
56 #include <BOPTools_Tools2D.hxx>
57 #include <BOPTools_Tools3D.hxx>
58
59 #include <BOP_ListOfConnexityBlock.hxx>
60 #include <BOP_BuilderTools.hxx>
61 #include <BOP_ListIteratorOfListOfConnexityBlock.hxx>
62 #include <BOP_ConnexityBlock.hxx>
63
64 //modified by NIZNHY-PKV Wed Feb 29 10:04:56 2012t
65 #include <TopTools_DataMapOfShapeShape.hxx>
66 #include <TopTools_DataMapOfShapeListOfShape.hxx>
67 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
68 #include <BRepAdaptor_Curve2d.hxx>
69 #include <Geom2dInt_Geom2dCurveTool.hxx>
70
71 static
72   Standard_Boolean IsGrowthWire(const TopoDS_Shape& theWire,
73                                 const TopTools_IndexedMapOfShape& theMHE);
74 static
75   Standard_Boolean IsHole(const TopoDS_Shape& aW,
76                           const TopoDS_Shape& aFace);
77 static
78   Standard_Boolean IsInside(const TopoDS_Shape& theHole,
79                             const TopoDS_Shape& theF2,
80                             const Handle(IntTools_Context)& theContext);
81 //modified by NIZNHY-PKV Wed Feb 29 10:05:21 2012t
82 static 
83   void DoTopologicalVerification(TopoDS_Face& F);
84
85 //=======================================================================
86 //function : BOP_FaceBuilder
87 //purpose  : 
88 //=======================================================================
89 BOP_FaceBuilder::BOP_FaceBuilder():
90   myTreatment(0),
91 //  myManifoldFlag(Standard_True),
92   myTreatSDScales(0)
93 {
94 }
95 //=======================================================================
96 //function : SetContext
97 //purpose  : 
98 //=======================================================================
99 void BOP_FaceBuilder::SetContext(const Handle(IntTools_Context)& aCtx)
100 {
101   myContext=aCtx;
102 }
103 //=======================================================================
104 //function : Context
105 //purpose  : 
106 //=======================================================================
107 const Handle(IntTools_Context)& BOP_FaceBuilder::Context()const
108 {
109   return myContext;
110 }
111 //=======================================================================
112 //function : SetTreatment
113 //purpose  : 
114 //=======================================================================
115 void BOP_FaceBuilder::SetTreatment(const Standard_Integer aTreatment)
116 {
117   myTreatment=aTreatment;
118 }
119 //=======================================================================
120 //function : Treatment
121 //purpose  : 
122 //=======================================================================
123 Standard_Integer BOP_FaceBuilder::Treatment()const 
124 {
125   return myTreatment;
126 }
127 //=======================================================================
128 //function : SetTreatSDScales
129 //purpose  : 
130 //=======================================================================
131 void BOP_FaceBuilder::SetTreatSDScales(const Standard_Integer aTreatment)
132 {
133   myTreatSDScales=aTreatment;
134 }
135 //=======================================================================
136 //function : TreatSDScales
137 //purpose  : 
138 //=======================================================================
139 Standard_Integer BOP_FaceBuilder::TreatSDScales()const 
140 {
141   return myTreatSDScales;
142 }
143 //=======================================================================
144 //function : WES
145 //purpose  : 
146 //=======================================================================
147 const BOP_WireEdgeSet& BOP_FaceBuilder::WES() const
148 {
149   return *myWES;
150 }
151 //=======================================================================
152 //function : NewFaces
153 //purpose  : 
154 //=======================================================================
155 const TopTools_ListOfShape& BOP_FaceBuilder::NewFaces() const
156 {
157   return myNewFaces;
158 }
159 //=======================================================================
160 //function : Do
161 //purpose  : 
162 //=======================================================================
163 void BOP_FaceBuilder::Do(const BOP_WireEdgeSet& aWES,
164                          const Standard_Boolean bForceClass) 
165 {
166   myFace=aWES.Face();
167   myWES=(BOP_WireEdgeSet*) &aWES;
168   //
169   //modified by NIZNHY-PKV Wed Feb 29 10:57:31 2012f
170   if (myContext.IsNull()) {
171     myContext=new IntTools_Context;
172   }
173   //modified by NIZNHY-PKV Wed Feb 29 10:57:34 2012t
174   //
175   BOP_WESCorrector aWESCor;
176   aWESCor.SetWES(aWES);
177   aWESCor.Do();
178   BOP_WireEdgeSet& aNewWES=aWESCor.NewWES();
179   //
180   //modified by NIZNHY-PKV Wed Feb 29 09:28:06 2012f
181   /*
182   //Make Loops. Only Loops are allowed after WESCorrector 
183   MakeLoops(aNewWES);
184   //
185   BOP_BlockBuilder& aBB = myBlockBuilder;
186   BOP_WireEdgeClassifier WEC(myFace, aBB);
187   BOP_LoopSet& LS = myLoopSet;
188   //
189   myFaceAreaBuilder.InitFaceAreaBuilder(LS, WEC, bForceClass);
190
191   BuildNewFaces();
192   */
193   
194   PerformAreas(aNewWES);
195   //modified by NIZNHY-PKV Wed Feb 29 09:28:08 2012t
196   
197   if (myTreatment==0) {
198     DoInternalEdges(); 
199   }
200   if (myTreatSDScales) {
201     SDScales();
202   }
203
204   // do topological verification
205   TopTools_ListIteratorOfListOfShape anIt;
206   anIt.Initialize(myNewFaces);
207   for(anIt.Initialize(myNewFaces); anIt.More(); anIt.Next()) {
208     TopoDS_Face& aF = TopoDS::Face(anIt.Value());
209     DoTopologicalVerification(aF);
210   }
211 }
212 //=======================================================================
213 //function : DoInternalEdges
214 //purpose  : 
215 //=======================================================================
216 void BOP_FaceBuilder::DoInternalEdges()
217 {
218   Standard_Integer i, aNbE, aNbSE, aNb, aNbF;
219   TopTools_IndexedDataMapOfShapeListOfShape aDifferenceMap, aFLEMap;
220   TopTools_IndexedMapOfOrientedShape aStartElementsMap, anEdgesMap;
221   TopTools_IndexedMapOfShape anInternalEdges;
222   //
223   const TopTools_ListOfShape& aStartElements=myWES->StartElements();
224
225   TopTools_ListIteratorOfListOfShape anIt(aStartElements);
226   for (; anIt.More(); anIt.Next()) {
227     const TopoDS_Shape& aE=anIt.Value();
228     aStartElementsMap.Add(aE);
229   }
230
231   anIt.Initialize(myNewFaces);
232   for (; anIt.More(); anIt.Next()) {
233     const TopoDS_Shape& aF=anIt.Value();
234     TopExp_Explorer anExp (aF, TopAbs_EDGE);
235     for (; anExp.More(); anExp.Next()) {
236       const TopoDS_Shape& aE=anExp.Current();
237       anEdgesMap.Add(aE);
238     }   
239   }
240   aNbSE=aStartElementsMap.Extent();
241   aNbE=anEdgesMap.Extent();
242
243   if (aNbE==aNbSE) {
244     return;
245   }
246
247   for (i=1; i<=aNbSE; i++) {
248     const TopoDS_Shape& aE=aStartElementsMap(i);
249     if (!anEdgesMap.Contains(aE)) {
250       if (!aDifferenceMap.Contains(aE)) {
251         TopTools_ListOfShape aLEx;
252         aLEx.Append(aE);
253         aDifferenceMap.Add(aE, aLEx);
254       }
255       else {
256         TopTools_ListOfShape& aLEx=aDifferenceMap.ChangeFromKey(aE);
257         aLEx.Append(aE);
258       }
259     }
260   }
261
262   aNbE=aDifferenceMap.Extent();
263   if(!aNbE) {
264     return;
265   }
266
267   for (i=1; i<=aNbE; i++) {
268     const TopoDS_Shape& aE=aDifferenceMap.FindKey(i);
269     const TopTools_ListOfShape& aLE=aDifferenceMap(i);
270     aNb=aLE.Extent();
271     if (aNb==2) {
272       const TopoDS_Edge& anEdge=TopoDS::Edge(aE);
273       if (!BRep_Tool::IsClosed(anEdge, myFace)) {
274         anInternalEdges.Add(aE);
275       }
276     }
277     //
278     if (aNb==1) {
279       const TopoDS_Edge& anEdge=TopoDS::Edge(aE);
280       if (anEdge.Orientation()==TopAbs_INTERNAL) {
281         anInternalEdges.Add(aE);
282       }
283     }
284     //
285   }
286   
287   aNbE=anInternalEdges.Extent();
288   if(!aNbE) {
289     return;
290   }
291
292   aFLEMap.Clear();
293
294   for (i=1; i<=aNbE; i++) {
295     const TopoDS_Edge& aEx=TopoDS::Edge(anInternalEdges(i));
296     TopoDS_Edge aE=aEx;
297
298     Standard_Real aT, aT1, aT2, aToler;
299     Standard_Boolean bHasCurveOnSurface, bIsPointInOnFace;
300     Handle(Geom2d_Curve)aC2D;
301
302     bHasCurveOnSurface=
303       BOPTools_Tools2D::HasCurveOnSurface(aE, myFace, aC2D, aT1, aT2, aToler);
304
305     if (bHasCurveOnSurface) {
306       aT=BOPTools_Tools2D::IntermediatePoint(aT1, aT2);
307       gp_Pnt2d aP2D;
308       aC2D->D0(aT, aP2D);
309       //
310       anIt.Initialize(myNewFaces);
311       
312       for (; anIt.More(); anIt.Next()) {
313         TopoDS_Face& aF=TopoDS::Face(anIt.Value());
314         //
315         //modified by NIZNHY-PKV Wed Feb 29 10:59:40 2012f
316         //IntTools_Context aCtx;
317         //bIsPointInOnFace=aCtx.IsPointInOnFace(aF, aP2D);
318         bIsPointInOnFace=myContext->IsPointInOnFace(aF, aP2D);
319         //modified by NIZNHY-PKV Wed Feb 29 10:59:43 2012t
320         //
321         if (bIsPointInOnFace) {
322           //
323           if (!aFLEMap.Contains(aF)) {
324             TopTools_ListOfShape aLE;
325             aLE.Append(aEx);
326             aFLEMap.Add(aF, aLE);
327           }
328           else {
329             TopTools_ListOfShape& aLE=aFLEMap.ChangeFromKey(aF);
330             aLE.Append(aEx);
331           }
332           break;
333         }
334       } //for (; anIt.More(); anIt.Next()) 
335     }// if (bHasCurveOnSurface)
336   } // for (i=1; i<=aNbE; i++)
337   //
338   // Make Wires from Internal Edges and Add the Wires to the faces
339   aNbF=aFLEMap.Extent();
340   BRep_Builder aBB;
341   for (i=1; i<=aNbF; i++) {
342     const TopoDS_Face& aF=TopoDS::Face(aFLEMap.FindKey(i));
343     TopoDS_Face* pF=(TopoDS_Face*)&aF;
344
345     const TopTools_ListOfShape& aLE=aFLEMap(i);
346     //
347     BOP_ListOfConnexityBlock aLConBlks;
348
349     BOP_BuilderTools::MakeConnexityBlocks(aLE, TopAbs_EDGE, aLConBlks);
350
351     BOP_ListIteratorOfListOfConnexityBlock aConBlkIt(aLConBlks);
352     for (; aConBlkIt.More(); aConBlkIt.Next()) {
353       BOP_ConnexityBlock& aConnexityBlock=aConBlkIt.Value();
354       const TopTools_ListOfShape& aLECB=aConnexityBlock.Shapes();
355       
356       aNbE=aLECB.Extent();
357       if (aNbE) {
358         TopoDS_Wire aW;
359         aBB.MakeWire(aW);
360
361         anIt.Initialize(aLECB);
362         for (; anIt.More(); anIt.Next()) {
363           TopoDS_Edge& aE=TopoDS::Edge(anIt.Value());
364           aE.Orientation(TopAbs_INTERNAL);
365           aBB.Add(aW, aE);
366         }
367         
368         aBB.Add(*pF, aW);
369       }
370     }
371     //
372   }
373 }
374 //=======================================================================
375 // function: TreatSDScales 
376 // purpose :  
377 //=======================================================================
378 void BOP_FaceBuilder::SDScales()
379 {
380   
381   Standard_Integer iNegativeFlag, aNbFR, i, aNbEFOpen, iCnt;
382   
383   TopTools_ListOfShape aLFR;
384   TopTools_ListIteratorOfListOfShape anIt, anItFR;
385   TopTools_IndexedMapOfShape aMFR;
386   //
387   iCnt=myNewFaces.Extent();
388   if (iCnt<2){
389     return;
390   }
391   //
392   // 1. Collect all faces with negative (infinite) area 
393   anIt.Initialize(myNewFaces);
394   for (i=1; anIt.More(); anIt.Next(), ++i) {
395     const TopoDS_Face& aF=TopoDS::Face(anIt.Value());
396     
397     iNegativeFlag=myNegatives(i);
398     if (iNegativeFlag) {
399       aLFR.Append(aF);
400     }
401   }
402   //
403   aNbFR=aLFR.Extent();
404   //
405   if (!aNbFR) {
406     return;
407   }
408   //
409   //
410   BOP_ListOfConnexityBlock aLCB;
411   BOP_ListIteratorOfListOfConnexityBlock aLCBIt;
412   //
413   BOP_BuilderTools::MakeConnexityBlocks (myNewFaces, TopAbs_FACE, aLCB);
414   //
415   anItFR.Initialize(aLFR);
416   for (; anItFR.More(); anItFR.Next()) {
417     const TopoDS_Face& aFR=TopoDS::Face(anItFR.Value());
418     //
419     iCnt=1;
420     TopTools_IndexedMapOfShape aMEFOpen;
421     BOP_ConnexityBlock* pCBR=NULL;
422     //
423     TopExp::MapShapes(aFR, TopAbs_EDGE, aMEFOpen);
424     aNbEFOpen=aMEFOpen.Extent();
425     //
426     // Look for ConnexityBlock to which aFR belongs to (pCBR)
427     aLCBIt.Initialize(aLCB);
428     for (; aLCBIt.More() && iCnt; aLCBIt.Next()) {
429       const BOP_ConnexityBlock& aCB=aLCBIt.Value();
430     
431       const TopTools_ListOfShape& aLCF=aCB.Shapes();
432       anIt.Initialize(aLCF);
433       for (; anIt.More() && iCnt; anIt.Next()) {
434         const TopoDS_Face& aF=TopoDS::Face(anIt.Value());
435         TopTools_IndexedMapOfShape aMECB;
436         TopExp::MapShapes(aF, TopAbs_EDGE, aMECB);
437         
438         for (i=1; i<=aNbEFOpen; ++i) {
439           const TopoDS_Shape& aEFOpen= aMEFOpen(i);
440           if (aMECB.Contains(aEFOpen)) {
441             iCnt=0;
442             pCBR=(BOP_ConnexityBlock*) &aCB;
443             break;
444           }
445         }
446       }
447     }
448     //
449     if (iCnt) {
450       // it is strange
451       continue;
452     }
453     //
454     // Collect Faces to remove in the map aMFR
455     const TopTools_ListOfShape& aLCR=pCBR->Shapes();
456     anIt.Initialize(aLCR);
457     for (; anIt.More(); anIt.Next()) {
458       const TopoDS_Face& aF=TopoDS::Face(anIt.Value());
459       aMFR.Add(aF);
460     }
461   } // for (; anItFR.More(); anItFR.Next())
462   //
463   //
464   iCnt=aMFR.Extent();
465   if (!iCnt) {
466     // Nothing to remove
467     return;
468   }
469   //
470   TopTools_ListOfShape aLFOut;
471   anIt.Initialize(myNewFaces);
472   for (; anIt.More(); anIt.Next()) {
473     const TopoDS_Face& aF=TopoDS::Face(anIt.Value());
474     if (!aMFR.Contains(aF)) {
475       aLFOut.Append(aF);
476     }
477   }
478   //
479   myNewFaces.Clear();
480   anIt.Initialize(aLFOut);
481   for (; anIt.More(); anIt.Next()) {
482     const TopoDS_Face& aF=TopoDS::Face(anIt.Value());
483     myNewFaces.Append(aF);
484   }
485 }
486 //modified by NIZNHY-PKV Wed Feb 29 08:57:52 2012f
487 //=======================================================================
488 //function : PerformAreas
489 //purpose  : 
490 //=======================================================================
491 void BOP_FaceBuilder::PerformAreas(BOP_WireEdgeSet& aWES)
492 {
493   Standard_Boolean bIsGrowth, bIsHole;
494   Standard_Real aTol;
495   TopTools_ListOfShape aNewFaces, aHoleWires, aLoops; 
496   TopoDS_Shape anInfinitePointShape;
497   TopTools_DataMapOfShapeShape aInOutMap;
498   TopTools_DataMapOfShapeListOfShape aMSH;
499   TopTools_DataMapIteratorOfDataMapOfShapeListOfShape aItMSH;
500   TopTools_ListIteratorOfListOfShape aIt1, aIt2;
501   TopTools_IndexedMapOfShape aMHE;
502   BRep_Builder aBB;
503   Handle(Geom_Surface) aS;
504   TopLoc_Location aLoc;
505   //
506   aTol=BRep_Tool::Tolerance(myFace);
507   aS=BRep_Tool::Surface(myFace, aLoc);
508   //
509   myNewFaces.Clear();
510   //
511   for(aWES.InitShapes();  aWES.MoreShapes(); aWES.NextShape()) {
512     const TopoDS_Shape& aW=aWES.Shape();
513     aLoops.Append(aW);
514   }
515   //
516   //  Draft faces [aNewFaces]
517   aIt1.Initialize(aLoops);
518   for ( ; aIt1.More(); aIt1.Next()) {
519     const TopoDS_Shape& aWire=aIt1.Value();
520     //
521     bIsGrowth=IsGrowthWire(aWire, aMHE);
522     if (bIsGrowth) {
523       // make a growth face from a wire
524       TopoDS_Face aFace;
525       aBB.MakeFace(aFace, aS, aLoc, aTol);
526       aBB.Add (aFace, aWire);
527       //
528       aNewFaces.Append (aFace);
529     }
530     else{
531       // check if a wire is a hole 
532       bIsHole=IsHole(aWire, myFace);
533       //XX
534       if (bIsHole) {
535         aHoleWires.Append(aWire);
536         TopExp::MapShapes(aWire, TopAbs_EDGE, aMHE);
537       }
538       else {
539         // make a growth face from a wire
540         TopoDS_Face aFace;
541         aBB.MakeFace(aFace, aS, aLoc, aTol);
542         aBB.Add (aFace, aWire);
543         //
544         aNewFaces.Append (aFace);
545       }
546     }
547   }
548   //
549   // 2. Find outer growth shell that is most close to each hole shell
550   aIt2.Initialize(aHoleWires);
551   for (; aIt2.More(); aIt2.Next()) {
552     const TopoDS_Shape& aHole = aIt2.Value();
553     //
554     aIt1.Initialize(aNewFaces);
555     for ( ; aIt1.More(); aIt1.Next()) {
556       const TopoDS_Shape& aF=aIt1.Value();
557       //
558       if (!IsInside(aHole, aF, myContext)){
559         continue;
560       }
561       //
562       if ( aInOutMap.IsBound (aHole)){
563         const TopoDS_Shape& aF2=aInOutMap(aHole);
564         if (IsInside(aF, aF2, myContext)) {
565           aInOutMap.UnBind(aHole);
566           aInOutMap.Bind (aHole, aF);
567         }
568       }
569       else{
570         aInOutMap.Bind (aHole, aF);
571       }
572     }
573     //
574     // Add aHole to a map Face/ListOfHoles [aMSH]
575     if (aInOutMap.IsBound(aHole)){
576       const TopoDS_Shape& aF=aInOutMap(aHole);
577       if (aMSH.IsBound(aF)) {
578         TopTools_ListOfShape& aLH=aMSH.ChangeFind(aF);
579         aLH.Append(aHole);
580       }
581       else {
582         TopTools_ListOfShape aLH;
583         aLH.Append(aHole);
584         aMSH.Bind(aF, aLH);
585       }
586     }
587   }// for (; aIt2.More(); aIt2.Next())
588   //
589   // 3. 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 TopTools_ListOfShape& aLH=aItMSH.Value();
595     aIt2.Initialize(aLH);
596     for (; aIt2.More(); aIt2.Next()) {
597       const TopoDS_Shape& aHole = aIt2.Value();
598       aBB.Add (aF, aHole);
599     }
600     //
601     // update classifier 
602     aTol=BRep_Tool::Tolerance(aF);
603     IntTools_FClass2d& aClsf=myContext->FClass2d(aF);
604     aClsf.Init(aF, aTol);
605   }
606   //
607   // These aNewFaces are draft faces that 
608   // do not contain any internal shapes
609   //
610   Standard_Boolean bIsValidIn2D, bNegativeFlag;
611   Standard_Integer iNegativeFlag;
612   //
613   myNewFaces.Clear();
614   myNegatives.Clear();
615   //
616   aIt1.Initialize(aNewFaces);
617   for ( ; aIt1.More(); aIt1.Next()) {
618     const TopoDS_Face& aFx=TopoDS::Face(aIt1.Value());
619     bIsValidIn2D=BOPTools_Tools3D::IsValidArea (aFx, bNegativeFlag);
620     if(bIsValidIn2D) {
621       myNewFaces.Append (aFx);
622       iNegativeFlag=(Standard_Integer)bNegativeFlag;
623       myNegatives.Append(iNegativeFlag);
624     }
625   }
626   //
627 }
628 //=======================================================================
629 //function : IsGrowthWire
630 //purpose  : 
631 //=======================================================================
632 Standard_Boolean IsGrowthWire(const TopoDS_Shape& theWire,
633                               const TopTools_IndexedMapOfShape& theMHE)
634 {
635   Standard_Boolean bRet;
636   TopoDS_Iterator aIt;
637   // 
638   bRet=Standard_False;
639   if (theMHE.Extent()) {
640     aIt.Initialize(theWire);
641     for(; aIt.More(); aIt.Next()) {
642       const TopoDS_Shape& aE=aIt.Value();
643       if (theMHE.Contains(aE)) {
644         return !bRet;
645       }
646     }
647   }
648   return bRet;
649 }
650 //=======================================================================
651 //function : IsHole
652 //purpose  : 
653 //=======================================================================
654 Standard_Boolean IsHole(const TopoDS_Shape& aW,
655                         const TopoDS_Shape& aFace)
656 {
657   Standard_Boolean bIsHole;
658   Standard_Real aTolF;
659   TopoDS_Shape aFE;
660   TopoDS_Face aFF;
661   BRep_Builder aBB;
662   IntTools_FClass2d aFClass2d;
663   //
664   aFE=aFace.EmptyCopied();
665   aFF=TopoDS::Face(aFE);
666   aFF.Orientation(TopAbs_FORWARD);
667   aBB.Add(aFF, aW);
668   //
669   aTolF=BRep_Tool::Tolerance(aFF);
670   //
671   aFClass2d.Init(aFF, aTolF);
672   //
673   bIsHole=aFClass2d.IsHole();
674   //
675   return bIsHole;
676 }
677 //=======================================================================
678 //function : IsInside
679 //purpose  : 
680 //=======================================================================
681 Standard_Boolean IsInside(const TopoDS_Shape& theHole,
682                           const TopoDS_Shape& theF2,
683                           const Handle(IntTools_Context)& theContext)
684 {
685   Standard_Boolean bRet;
686   Standard_Real aT, aU, aV;
687   
688   TopAbs_State aState;
689   TopExp_Explorer aExp;
690   TopTools_IndexedMapOfShape aME2;
691   gp_Pnt2d aP2D;
692   //
693   bRet=Standard_False;
694   aState=TopAbs_UNKNOWN;
695   const TopoDS_Face& aF2=TopoDS::Face(theF2);
696   //
697   TopExp::MapShapes(aF2, TopAbs_EDGE, aME2);
698   //
699   aExp.Init(theHole, TopAbs_EDGE);
700   if (aExp.More()) {
701     const TopoDS_Edge& aE = TopoDS::Edge(aExp.Current());
702     if (aME2.Contains(aE)) {
703       return bRet;
704     }
705     //
706     aT=BOPTools_Tools2D::IntermediatePoint(aE);
707     BOPTools_Tools2D::PointOnSurface(aE, aF2, aT, aU, aV);
708     aP2D.SetCoord(aU, aV);
709     //
710     IntTools_FClass2d& aClsf=theContext->FClass2d(aF2);
711     aState=aClsf.Perform(aP2D);
712     bRet=(aState==TopAbs_IN);
713   }
714   //
715   return bRet;
716 }
717 //modified by NIZNHY-PKV Wed Feb 29 08:57:55 2012t
718
719 //=======================================================================
720 //function : DoTopologicalVerification
721 //purpose  : 
722 //=======================================================================
723 void DoTopologicalVerification(TopoDS_Face& F)
724 {
725   TopTools_IndexedDataMapOfShapeListOfShape mapVE;
726   mapVE.Clear();
727   TopExp::MapShapesAndAncestors(F,TopAbs_VERTEX,TopAbs_EDGE,mapVE);
728
729   Standard_Real pF1 = 0., pL1 = 0., pF2 = 0., pL2 = 0.;
730   Standard_Integer nbKeys = mapVE.Extent(), iKey = 0;
731
732   for( iKey = 1; iKey <= nbKeys; iKey++ ) {
733     const TopoDS_Vertex& iV = TopoDS::Vertex(mapVE.FindKey(iKey));
734     if( iV.IsNull() ) continue;
735
736     Standard_Real TolV = BRep_Tool::Tolerance(iV);
737
738     const TopTools_ListOfShape& iLE = mapVE.FindFromIndex(iKey);
739     Standard_Integer nbE = iLE.Extent();
740     if( nbE != 2 ) break;
741
742     const TopoDS_Edge& iE1 = TopoDS::Edge(iLE.First());
743     const TopoDS_Edge& iE2 = TopoDS::Edge(iLE.Last());
744
745     if(BRep_Tool::Degenerated(iE1) || BRep_Tool::Degenerated(iE2) ) continue;
746
747     Standard_Real iPE1 = BRep_Tool::Parameter(iV,iE1);
748     Standard_Real iPE2 = BRep_Tool::Parameter(iV,iE2);
749         
750     Handle(Geom_Curve) aC3D1 = BRep_Tool::Curve(iE1,pF1,pL1);
751     Handle(Geom_Curve) aC3D2 = BRep_Tool::Curve(iE2,pF2,pL2);
752     if( aC3D1.IsNull() || aC3D2.IsNull() ) break;
753
754     Standard_Boolean is1F = (fabs(iPE1-pF1) < fabs(iPE1-pL1));
755     Standard_Boolean is2F = (fabs(iPE2-pF2) < fabs(iPE2-pL2));
756     
757     Standard_Real useP1 = iPE1;
758     if( is1F ) {
759       if( fabs(iPE1-pF1) > 1.e-7 ) useP1 = pF1;
760     }
761     else {
762       if( fabs(iPE1-pL1) > 1.e-7 ) useP1 = pL1;
763     }
764
765     Standard_Real useP2 = iPE2;
766     if( is2F ) {
767       if( fabs(iPE2-pF2) > 1.e-7 ) useP2 = pF2;
768     }
769     else {
770       if( fabs(iPE2-pL2) > 1.e-7 ) useP2 = pL2;
771     }
772
773     gp_Pnt aPnt1 = aC3D1->Value(useP1);
774     gp_Pnt aPnt2 = aC3D2->Value(useP2);
775     gp_Pnt aPntV = BRep_Tool::Pnt(iV);
776
777     Standard_Real distV1 = aPntV.Distance(aPnt1);
778     Standard_Real distV2 = aPntV.Distance(aPnt2);
779
780     // update vertex tolerance checking 3D curves
781     if( distV1 > TolV || distV2 > TolV ) {
782       Standard_Real distMax = Max(distV1,distV2);
783       Standard_Real delta = fabs(distMax-TolV);
784       Standard_Real newTol = TolV + delta + 2.e-7;
785       TopoDS_Vertex & aV = (TopoDS_Vertex &) iV;
786       BRep_Builder bb;
787       bb.UpdateVertex(aV,newTol);
788       TolV = newTol;
789     }
790
791     gp_Pnt2d aPnt2dF, aPnt2dL;
792     BRep_Tool::UVPoints(iE1,F,aPnt2dF, aPnt2dL);
793     gp_Pnt2d aPnt2dE1 = (is1F) ? aPnt2dF : aPnt2dL;
794     BRep_Tool::UVPoints(iE2,F,aPnt2dF, aPnt2dL);
795     gp_Pnt2d aPnt2dE2 = (is2F) ? aPnt2dF : aPnt2dL;
796
797     BRepAdaptor_Surface aFSurf (F,Standard_False);
798     aPnt1 = aFSurf.Value(aPnt2dE1.X(), aPnt2dE1.Y());
799     aPnt2 = aFSurf.Value(aPnt2dE2.X(), aPnt2dE2.Y());
800     distV1 = aPntV.Distance(aPnt1);
801     distV2 = aPntV.Distance(aPnt2);
802
803     // update vertex tolerance checking 3D points on surface
804     if( distV1 > TolV || distV2 > TolV ) {
805       Standard_Real distMax = Max(distV1,distV2);
806       Standard_Real delta = fabs(distMax-TolV);
807       Standard_Real newTol = TolV + delta + 2.e-7;
808       TopoDS_Vertex & aV = (TopoDS_Vertex &) iV;
809       BRep_Builder bb;
810       bb.UpdateVertex(aV,newTol);
811       TolV = newTol;
812     }
813   }
814 }
815 //modified by NIZNHY-PKV Wed Feb 29 10:07:16 2012f
816 /*
817 //=======================================================================
818 //function : MakeLoops
819 //purpose  : 
820 //=======================================================================
821   void BOP_FaceBuilder::MakeLoops(BOP_WireEdgeSet& SS)
822 {
823   //BOP_BlockBuilder& BB = myBlockBuilder;
824   BOP_ListOfLoop& LL = myLoopSet.ChangeListOfLoop();
825   
826   // Build blocks on elements of SS [ Ready to remove this invocation]
827   // make list of loop (LL) of the LoopSet
828   // - on shapes of the ShapeSet (SS)
829   // - on blocks of the BlockBuilder (BB)
830   //
831   // Add shapes of SS as shape loops
832   LL.Clear();
833   for(SS.InitShapes();SS.MoreShapes();SS.NextShape()) {
834     const TopoDS_Shape& S = SS.Shape();
835     Handle(BOP_Loop) ShapeLoop = new BOP_Loop(S);
836     LL.Append(ShapeLoop);
837   }
838 }
839 */
840 /*
841 //=======================================================================
842 //function : BuildNewFaces
843 //purpose  : 
844 //=======================================================================
845   void BOP_FaceBuilder::BuildNewFaces() 
846 {
847   Standard_Integer nF, nW, nE;
848   Standard_Real    aTol;
849   TopLoc_Location aLoc;
850   TopoDS_Face newFace;
851   TopoDS_Wire newWire;
852   BRep_Builder aBB;
853   Standard_Boolean bValidWire, bValidFace;
854   
855   Handle(Geom_Surface) aSurface=BRep_Tool::Surface(myFace, aLoc);
856   aTol=BRep_Tool::Tolerance(myFace);
857
858   myNewFaces.Clear();
859   myNegatives.Clear();
860
861   nF=InitFace();
862   for (; MoreFace(); NextFace()) {
863     bValidFace=Standard_False;
864     aBB.MakeFace (newFace, aSurface, aLoc, aTol);
865
866     nW=InitWire();
867     for (; MoreWire(); NextWire()) {
868       if (IsOldWire()) {
869         newWire=TopoDS::Wire(OldWire());
870       }
871       else {
872         aBB.MakeWire(newWire);
873         nE=InitEdge();
874         for (; MoreEdge(); NextEdge()) {
875           const TopoDS_Edge& newEdge=Edge();
876           aBB.Add(newWire, newEdge);
877         }
878       }
879       
880       bValidWire=BOPTools_Tools3D::IsConvexWire(newWire);
881       if (bValidWire) {
882         bValidFace=Standard_True;
883         aBB.Add(newFace, newWire);
884       }
885
886       else {
887         if (!myManifoldFlag && myTreatment==1) {
888           myNewFaces.Append (newWire);
889         }
890       }
891     } // end of for (; MoreWire(); NextWire())
892     
893     if (bValidFace) {
894       
895       Standard_Boolean bIsValidIn2D, bNegativeFlag;
896       Standard_Integer iNegativeFlag;
897
898       bIsValidIn2D=BOPTools_Tools3D::IsValidArea (newFace, bNegativeFlag);
899       if(bIsValidIn2D) {
900         myNewFaces.Append (newFace);
901         iNegativeFlag=(Standard_Integer)bNegativeFlag;
902         myNegatives.Append(iNegativeFlag);
903       }
904     }
905   }
906 }
907 */
908 /*
909 //=======================================================================
910 //function : InitFace
911 //purpose  : 
912 //=======================================================================
913   Standard_Integer BOP_FaceBuilder::InitFace()
914 {
915   Standard_Integer n = myFaceAreaBuilder.InitArea();
916   return n;
917 }
918 //=======================================================================
919 //function : MoreFace
920 //purpose  : 
921 //=======================================================================
922   Standard_Boolean BOP_FaceBuilder::MoreFace() const
923 {
924   Standard_Boolean b = myFaceAreaBuilder.MoreArea();
925   return b;
926 }
927 //=======================================================================
928 //function : NextFace
929 //purpose  : 
930 //=======================================================================
931   void BOP_FaceBuilder::NextFace()
932 {
933   myFaceAreaBuilder.NextArea();
934 }
935
936 //=======================================================================
937 //function : InitWire
938 //purpose  : 
939 //=======================================================================
940   Standard_Integer BOP_FaceBuilder::InitWire()
941 {
942   Standard_Integer n = myFaceAreaBuilder.InitLoop();
943   return n;
944 }
945 //=======================================================================
946 //function : MoreWire
947 //purpose  : 
948 //=======================================================================
949   Standard_Boolean BOP_FaceBuilder::MoreWire() const
950 {
951   Standard_Boolean b = myFaceAreaBuilder.MoreLoop();
952   return b;
953 }
954 //=======================================================================
955 //function : NextWire
956 //purpose  : 
957 //=======================================================================
958   void BOP_FaceBuilder::NextWire()
959 {
960   myFaceAreaBuilder.NextLoop();
961 }
962 //=======================================================================
963 //function : IsOldWire
964 //purpose  : 
965 //=======================================================================
966   Standard_Boolean BOP_FaceBuilder::IsOldWire() const
967 {
968   const Handle(BOP_Loop)& L = myFaceAreaBuilder.Loop();
969   Standard_Boolean b = L->IsShape();
970   return b;
971 }
972 //=======================================================================
973 //function : OldWire
974 //purpose  : 
975 //=======================================================================
976   const TopoDS_Shape& BOP_FaceBuilder::OldWire() const
977 {
978   const Handle(BOP_Loop)& L = myFaceAreaBuilder.Loop();
979   const TopoDS_Shape& B = L->Shape();
980   return B;
981 }
982 //=======================================================================
983 //function : Wire
984 //purpose  : 
985 //=======================================================================
986   const TopoDS_Wire& BOP_FaceBuilder::Wire() const
987 {
988   return TopoDS::Wire(OldWire());
989 }
990 */
991 /*
992 //=======================================================================
993 //function : InitEdge
994 //purpose  : 
995 //=======================================================================
996   Standard_Integer BOP_FaceBuilder::InitEdge()
997 {
998   const Handle(BOP_Loop)& L = myFaceAreaBuilder.Loop();
999   if ( L->IsShape() ){
1000     Standard_DomainError::Raise("BOP_FaceBuilder:InitEdge");
1001   }
1002   else {
1003     myBlockIterator = L->BlockIterator();
1004     myBlockIterator.Initialize();
1005     FindNextValidElement();
1006   }
1007   Standard_Integer n = myBlockIterator.Extent();
1008   return n;
1009 }
1010 //=======================================================================
1011 //function : FindNextValidElement
1012 //purpose  : 
1013 //=======================================================================
1014   void BOP_FaceBuilder::FindNextValidElement()
1015 {
1016   // prerequisites : myBlockIterator.Initialize
1017   Standard_Boolean found = Standard_False;
1018
1019   while ( myBlockIterator.More()) {
1020     const Standard_Integer i = myBlockIterator.Value();
1021     found = myBlockBuilder.ElementIsValid(i);
1022     if (found) break;
1023     else myBlockIterator.Next();
1024   }
1025 }
1026 //=======================================================================
1027 //function : MoreEdge
1028 //purpose  : 
1029 //=======================================================================
1030   Standard_Boolean BOP_FaceBuilder::MoreEdge() const
1031 {
1032   Standard_Boolean b = myBlockIterator.More();
1033   return b;
1034 }
1035 //=======================================================================
1036 //function : NextEdge
1037 //purpose  : 
1038 //=======================================================================
1039   void BOP_FaceBuilder::NextEdge()
1040 {
1041   myBlockIterator.Next();
1042   FindNextValidElement();
1043 }
1044 //=======================================================================
1045 //function : Edge
1046 //purpose  : 
1047 //=======================================================================
1048   const TopoDS_Edge& BOP_FaceBuilder::Edge() const
1049 {
1050   if (!myBlockIterator.More()) {
1051     Standard_Failure::Raise("OutOfRange");
1052   }
1053   
1054   Standard_Integer i = myBlockIterator.Value();
1055   
1056   Standard_Boolean isvalid = myBlockBuilder.ElementIsValid(i);
1057  
1058   if (!isvalid) {
1059     Standard_Failure::Raise("Edge not Valid");
1060   }
1061
1062   const TopoDS_Shape& E = myBlockBuilder.Element(i);
1063   const TopoDS_Edge& anEdge = TopoDS::Edge(E);
1064   
1065   return anEdge;
1066 }
1067 */
1068 /*
1069 //=======================================================================
1070 //function : SetManifoldFlag
1071 //purpose  : 
1072 //=======================================================================
1073   void BOP_FaceBuilder::SetManifoldFlag(const Standard_Boolean aManifoldFlag)
1074 {
1075   myManifoldFlag=aManifoldFlag;
1076 }
1077 //=======================================================================
1078 //function : ManifoldFlag
1079 //purpose  : 
1080 //=======================================================================
1081   Standard_Boolean BOP_FaceBuilder::ManifoldFlag()const
1082 {
1083   return myManifoldFlag;
1084 }
1085 */
1086 //modified by NIZNHY-PKV Wed Feb 29 10:07:05 2012t