10efe77184fdd6e46fa05fb712ec0ea0b2441624
[occt.git] / src / BOPTools / BOPTools_AlgoTools_1.cxx
1 // Created by: Peter KURNEV
2 // Copyright (c) 1999-2014 OPEN CASCADE SAS
3 //
4 // This file is part of Open CASCADE Technology software library.
5 //
6 // This library is free software; you can redistribute it and/or modify it under
7 // the terms of the GNU Lesser General Public License version 2.1 as published
8 // by the Free Software Foundation, with special exception defined in the file
9 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10 // distribution for complete text of the license and disclaimer of any warranty.
11 //
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
14
15 #include <BOPTools_AlgoTools.ixx>
16 //
17 #include <gp_Pnt.hxx>
18 #include <gp_Pnt2d.hxx>
19 //
20 #include <Adaptor3d_HCurve.hxx>
21 #include <Adaptor3d_CurveOnSurface.hxx>
22 #include <Adaptor3d_HCurveOnSurface.hxx>
23 //
24 #include <Geom_Curve.hxx>
25 #include <Geom_Surface.hxx>
26 #include <Geom_Plane.hxx>
27 #include <Geom_TrimmedCurve.hxx>
28 #include <Geom_RectangularTrimmedSurface.hxx>
29 //
30 #include <GeomAdaptor_Surface.hxx>
31 #include <GeomAdaptor_Curve.hxx>
32 #include <GeomAdaptor_HCurve.hxx>
33 #include <GeomAdaptor_HSurface.hxx>
34 //
35 #include <Geom2d_Curve.hxx>
36 #include <Geom2dInt_GInter.hxx>
37 #include <Geom2dAdaptor_Curve.hxx>
38 #include <Geom2dAdaptor_HCurve.hxx>
39 #include <Geom2dAdaptor.hxx>
40 //
41 #include <GeomProjLib.hxx>
42 //
43 #include <ProjLib_ProjectedCurve.hxx>
44 #include <Extrema_LocateExtPC.hxx>
45 //
46 #include <IntRes2d_Domain.hxx>
47 #include <IntRes2d_IntersectionPoint.hxx>
48 //
49 #include <TopLoc_Location.hxx>
50 //
51 #include <TopoDS.hxx>
52 #include <TopoDS_Edge.hxx>
53 #include <TopoDS_Vertex.hxx>
54 #include <TopoDS_Face.hxx>
55 #include <TopoDS_Iterator.hxx>
56 #include <TopoDS_Wire.hxx>
57 //
58 #include <BRep_TVertex.hxx>
59 #include <BRep_TEdge.hxx>
60 #include <BRep_TFace.hxx>
61 #include <BRep_Tool.hxx>
62 #include <BRep_GCurve.hxx>
63 #include <BRep_ListIteratorOfListOfPointRepresentation.hxx>
64 #include <BRep_ListIteratorOfListOfCurveRepresentation.hxx>
65 #include <BRep_CurveRepresentation.hxx>
66 #include <BRep_PointRepresentation.hxx>
67 #include <BRep_Builder.hxx>
68 //
69 #include <BRepAdaptor_Surface.hxx>
70 //
71 #include <BRepTools_WireExplorer.hxx>
72 //
73 #include <TopExp.hxx>
74 #include <TopExp_Explorer.hxx>
75 #include <TopTools_IndexedMapOfShape.hxx>
76 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
77 #include <TopTools_ListOfShape.hxx>
78 #include <TopTools_ListIteratorOfListOfShape.hxx>
79 //
80 #include <IntTools_Tools.hxx>
81 //
82 #include <BOPCol_NCVector.hxx>
83 #include <BOPCol_Parallel.hxx>
84 #include <BRepLib_CheckCurveOnSurface.hxx>
85
86 static 
87   void CheckEdge (const TopoDS_Edge& E,
88                   const Standard_Real aMaxTol);
89 static 
90   void CorrectEdgeTolerance (const TopoDS_Edge& myShape,
91                              const TopoDS_Face& S,
92                              const Standard_Real aMaxTol);
93 static 
94   Standard_Boolean Validate(const Adaptor3d_Curve& CRef,
95                             const Adaptor3d_Curve& Other,
96                             const Standard_Real Tol,
97                             const Standard_Boolean SameParameter,
98                             Standard_Real& aNewTolerance);
99
100 static
101   void CorrectVertexTolerance(const TopoDS_Edge& aE);
102
103 static
104   void CorrectWires(const TopoDS_Face& aF);
105
106
107
108 static
109   void UpdateEdges(const TopoDS_Face& aF);
110
111 static 
112   Standard_Real IntersectCurves2d(const gp_Pnt& aPV,
113                                   const TopoDS_Face& aF,
114                                   const GeomAdaptor_Surface& aS,
115                                   const TopoDS_Edge& aE1,
116                                   const TopoDS_Edge& aE2);
117
118
119
120 //=======================================================================
121 //class    : BOPTools_CPC
122 //purpose  : 
123 //=======================================================================
124 class BOPTools_CPC {
125  public:
126   BOPTools_CPC()
127     : myMaxTol(1.e-7) {
128   }
129   //
130   ~BOPTools_CPC() {
131   }
132   //
133   void SetEdge(const TopoDS_Edge& aE) {
134     myEdge=aE;
135   }
136   //
137   const TopoDS_Edge& Edge()const {
138     return myEdge;
139   }
140   //
141   void SetMaxTol(const Standard_Real aMaxTol) {
142     myMaxTol=aMaxTol;
143   }
144   //
145   Standard_Real MaxTol()const {
146     return myMaxTol;
147   }
148   //
149   void Perform() {
150     CheckEdge(myEdge, myMaxTol);
151   }
152   
153  protected:
154   Standard_Real myMaxTol;
155   TopoDS_Edge myEdge;
156 };
157 //
158 //=======================================================================
159 typedef BOPCol_NCVector<BOPTools_CPC> BOPTools_VectorOfCPC; 
160 //
161 typedef BOPCol_Functor 
162   <BOPTools_CPC,
163   BOPTools_VectorOfCPC> BOPTools_CPCFunctor;
164 //
165 typedef BOPCol_Cnt 
166   <BOPTools_CPCFunctor,
167   BOPTools_VectorOfCPC> BOPTools_CPCCnt;
168 //
169 //=======================================================================
170 //class    : BOPTools_CWT
171 //purpose  : 
172 //=======================================================================
173 class BOPTools_CWT {
174  public:
175   BOPTools_CWT() {
176   }
177   //
178   ~BOPTools_CWT() {
179   }
180   //
181   void SetFace(const TopoDS_Face& aF) {
182     myFace=aF;
183   }
184   //
185   void Perform() {
186     CorrectWires(myFace);
187   }
188   //
189  protected:
190   TopoDS_Face myFace;
191 };
192 //=======================================================================
193 typedef BOPCol_NCVector<BOPTools_CWT> BOPTools_VectorOfCWT; 
194 //
195 typedef BOPCol_Functor 
196   <BOPTools_CWT,
197   BOPTools_VectorOfCWT> BOPTools_CWTFunctor;
198 //
199 typedef BOPCol_Cnt 
200   <BOPTools_CWTFunctor,
201   BOPTools_VectorOfCWT> BOPTools_CWTCnt;
202 //
203 //=======================================================================
204 //class    : BOPTools_CDT
205 //purpose  : 
206 //=======================================================================
207 class BOPTools_CDT {
208  public:
209   BOPTools_CDT() 
210     : myMaxTol(1.e-7) {
211   }
212   //
213   ~BOPTools_CDT() {
214   }
215   //
216   void SetEdge(const TopoDS_Edge& aE) {
217     myEdge=aE;
218   }
219   //
220   void SetFace(const TopoDS_Face& aF) {
221     myFace=aF;
222   }
223   //
224   void SetMaxTol(const Standard_Real aMaxTol) {
225     myMaxTol=aMaxTol;
226   }
227   //
228   void Perform() {
229     CorrectEdgeTolerance (myEdge, myFace, myMaxTol);
230   }
231   //
232  protected:
233   Standard_Real myMaxTol;
234   TopoDS_Edge myEdge;
235   TopoDS_Face myFace;
236 };
237 //=======================================================================
238 typedef BOPCol_NCVector<BOPTools_CDT> BOPTools_VectorOfCDT; 
239 //
240 typedef BOPCol_Functor 
241   <BOPTools_CDT,
242   BOPTools_VectorOfCDT> BOPTools_CDTFunctor;
243 //
244 typedef BOPCol_Cnt 
245   <BOPTools_CDTFunctor,
246   BOPTools_VectorOfCDT> BOPTools_CDTCnt;
247 //
248 //=======================================================================
249 //class    : BOPTools_CVT
250 //purpose  : 
251 //=======================================================================
252 class BOPTools_CVT {
253  public:
254   BOPTools_CVT() {
255   }
256   //
257   ~BOPTools_CVT() {
258   }
259   //
260   void SetEdge(const TopoDS_Edge& aE) {
261     myEdge=aE;
262   }
263   //
264   void Perform() {
265     CorrectVertexTolerance(myEdge);
266   }
267   //
268  protected:
269   TopoDS_Edge myEdge;
270 };
271 //
272 //=======================================================================
273 typedef BOPCol_NCVector<BOPTools_CVT> BOPTools_VectorOfCVT; 
274 //
275 typedef BOPCol_Functor 
276   <BOPTools_CVT,
277   BOPTools_VectorOfCVT> BOPTools_CVTFunctor;
278 //
279 typedef BOPCol_Cnt 
280   <BOPTools_CVTFunctor,
281   BOPTools_VectorOfCVT> BOPTools_CVTCnt;
282 //
283 //=======================================================================
284 //class    : BOPTools_CET
285 //purpose  : 
286 //=======================================================================
287 class BOPTools_CET {
288  public:
289   BOPTools_CET() {
290   }
291   //
292   ~BOPTools_CET() {
293   }
294   //
295   void SetFace(const TopoDS_Face& aF) {
296     myFace=aF;
297   }
298   //
299   void Perform() {
300     UpdateEdges(myFace);
301   }
302   //
303  protected:
304   TopoDS_Face myFace;
305 };
306 //=======================================================================
307 typedef BOPCol_NCVector<BOPTools_CET> BOPTools_VectorOfCET; 
308 //
309 typedef BOPCol_Functor 
310   <BOPTools_CET,
311   BOPTools_VectorOfCET> BOPTools_CETFunctor;
312 //
313 typedef BOPCol_Cnt 
314   <BOPTools_CETFunctor,
315   BOPTools_VectorOfCET> BOPTools_CETCnt;
316 //
317 //
318 //=======================================================================
319   //
320 //=======================================================================
321 // Function : CorrectTolerances
322 // purpose : 
323 //=======================================================================
324 void BOPTools_AlgoTools::CorrectTolerances
325   (const TopoDS_Shape& aShape,
326    const Standard_Real aMaxTol,
327    const Standard_Boolean bRunParallel)
328 {
329   BOPTools_AlgoTools::CorrectPointOnCurve(aShape, aMaxTol, bRunParallel);
330   BOPTools_AlgoTools::CorrectCurveOnSurface(aShape, aMaxTol, bRunParallel);
331 }
332 //
333 //=======================================================================
334 // Function : CorrectPointOnCurve
335 // purpose : 
336 //=======================================================================
337 void BOPTools_AlgoTools::CorrectPointOnCurve
338   (const TopoDS_Shape& aS,
339    const Standard_Real aMaxTol,
340    const Standard_Boolean bRunParallel)
341 {
342   TopExp_Explorer aExp;
343   BOPTools_VectorOfCPC aVCPC;
344   //
345   aExp.Init(aS, TopAbs_EDGE);
346   for(; aExp.More();  aExp.Next()) {
347     const TopoDS_Edge& aE=*((TopoDS_Edge*)&aExp.Current());
348     BOPTools_CPC& aCPC=aVCPC.Append1();
349     aCPC.SetEdge(aE);
350     aCPC.SetMaxTol(aMaxTol);
351   }
352   //
353   //======================================================
354   BOPTools_CPCCnt::Perform(bRunParallel, aVCPC);
355   //======================================================
356 }
357 //=======================================================================
358 // Function : CorrectCurveOnSurface
359 // purpose : 
360 //=======================================================================
361 void BOPTools_AlgoTools::CorrectCurveOnSurface
362   (const TopoDS_Shape& aS,
363    const Standard_Real aMaxTol,
364    const Standard_Boolean bRunParallel)
365 {
366   TopExp_Explorer aExpF, aExpE;
367   BOPTools_VectorOfCWT aVCWT;
368   BOPTools_VectorOfCDT aVCDT;
369   //
370   aExpF.Init(aS, TopAbs_FACE);
371   for (; aExpF.More(); aExpF.Next()) {
372     const TopoDS_Face& aF=*((TopoDS_Face*)&aExpF.Current());
373     //
374     BOPTools_CWT& aCWT=aVCWT.Append1();
375     aCWT.SetFace(aF);
376     //
377     aExpE.Init(aF, TopAbs_EDGE);
378     for (; aExpE.More(); aExpE.Next()) {
379       const TopoDS_Edge& aE=*((TopoDS_Edge*)&aExpE.Current());
380       //
381       BOPTools_CDT& aCDT=aVCDT.Append1();
382       aCDT.SetEdge(aE);
383       aCDT.SetFace(aF);
384       aCDT.SetMaxTol(aMaxTol);
385     }
386   }
387   //
388   //======================================================
389   BOPTools_CWTCnt::Perform(bRunParallel, aVCWT);
390   //======================================================
391   BOPTools_CDTCnt::Perform(bRunParallel, aVCDT);
392   //======================================================
393 }
394 //=======================================================================
395 // Function : CorrectShapeTolerances
396 // purpose : 
397 //=======================================================================
398 void BOPTools_AlgoTools::CorrectShapeTolerances
399   (const TopoDS_Shape& aShape,
400    const Standard_Boolean bRunParallel)
401
402   TopExp_Explorer aExp;
403   BOPTools_VectorOfCVT aVCVT;
404   BOPTools_VectorOfCET aVCET;
405   //
406   aExp.Init(aShape, TopAbs_EDGE);
407   for (; aExp.More(); aExp.Next()) {
408     const TopoDS_Edge& aE = *(TopoDS_Edge*)&aExp.Current();
409     BOPTools_CVT& aCVT=aVCVT.Append1();
410     aCVT.SetEdge(aE);
411   }
412   //
413   //======================================================
414   BOPTools_CVTCnt::Perform(bRunParallel, aVCVT);
415   //======================================================
416   //
417   aExp.Init(aShape, TopAbs_FACE);
418   for (; aExp.More(); aExp.Next()) {
419     const TopoDS_Face& aF = *(TopoDS_Face*)&aExp.Current();
420     BOPTools_CET& aCET=aVCET.Append1();
421     aCET.SetFace(aF);
422   }
423   //
424   //======================================================
425   BOPTools_CETCnt::Perform(bRunParallel, aVCET);
426   //======================================================
427 }
428 //
429 //=======================================================================
430 // Function : CheckEdge
431 // purpose :  Correct tolerances for Vertices on Edge 
432 //=======================================================================
433 void CheckEdge (const TopoDS_Edge& Ed, 
434                 const Standard_Real aMaxTol)
435 {
436   Standard_Real aTolE, aTol, aD2, aNewTolerance, dd;
437   gp_Pnt aPC;
438   TopLoc_Location L;
439   TopoDS_Edge aE;
440   TopoDS_Vertex aV;
441   TopoDS_Iterator aItS;
442   //
443   TopAbs_Orientation aOrV;
444   BRep_ListIteratorOfListOfPointRepresentation aItPR;
445   BRep_ListIteratorOfListOfCurveRepresentation aItCR;
446   //
447   aE=Ed;
448   aE.Orientation(TopAbs_FORWARD);
449   aTolE=BRep_Tool::Tolerance(aE);
450   //
451   Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*)&aE.TShape());
452   //
453   aItS.Initialize(aE);
454   for (; aItS.More(); aItS.Next()) {
455     aV= TopoDS::Vertex(aItS.Value());
456     //
457     Handle(BRep_TVertex)& TV=*((Handle(BRep_TVertex)*)&aV.TShape());
458     const gp_Pnt& aPV = TV->Pnt();
459     //
460     aTol=BRep_Tool::Tolerance(aV);
461     aTol=Max(aTol, aTolE);
462     dd=0.1*aTol;
463     aTol*=aTol;
464     //
465     const TopLoc_Location& Eloc = aE.Location();
466     //
467     aItCR.Initialize(TE->Curves());
468     while (aItCR.More()) {
469       const Handle(BRep_CurveRepresentation)& aCR = aItCR.Value();
470       const TopLoc_Location& loc = aCR->Location();
471       L = (Eloc * loc).Predivided(aV.Location());
472       //
473       if (aCR->IsCurve3D()) {
474         const Handle(Geom_Curve)& aC = aCR->Curve3D();
475         if (!aC.IsNull()) {
476           aItPR.Initialize(TV->Points());
477           while (aItPR.More()) {
478             const Handle(BRep_PointRepresentation)& aPR=aItPR.Value();
479             if (aPR->IsPointOnCurve(aC, L)) {
480               aPC = aC->Value(aPR->Parameter());
481               aPC.Transform(L.Transformation());
482               aD2=aPV.SquareDistance(aPC);
483               if (aD2 > aTol) {
484                 aNewTolerance=sqrt(aD2)+dd;
485                 if (aNewTolerance<aMaxTol)
486                   TV->UpdateTolerance(aNewTolerance);
487               }
488             }
489             aItPR.Next();
490           }
491           //
492           aOrV=aV.Orientation();
493           if (aOrV==TopAbs_FORWARD || aOrV==TopAbs_REVERSED) {
494             const Handle(BRep_GCurve)& aGC=*((Handle(BRep_GCurve)*)&aCR);
495             
496             if (aOrV==TopAbs_FORWARD) {
497               aPC=aC->Value(aGC->First());
498             }
499             else {
500               aPC=aC->Value(aGC->Last());
501             }
502             aPC.Transform(L.Transformation());
503             //
504             aD2=aPV.SquareDistance(aPC);
505             if (aD2 > aTol) {
506               aNewTolerance=sqrt(aD2)+dd;
507               if (aNewTolerance<aMaxTol) 
508                 TV->UpdateTolerance(aNewTolerance);
509             }
510           }
511         }
512       }
513       aItCR.Next();
514     }//  while (itcr.More()) {  
515   } // for (; aVExp.More(); aVExp.Next()) {
516 }
517 //=======================================================================
518 // Function : CorrectWires
519 // purpose : 
520 //=======================================================================
521 void CorrectWires(const TopoDS_Face& aFx)
522 {
523   Standard_Boolean bIsPeriodic; 
524   Standard_Integer i, aNbV;
525   Standard_Real aTol, aTol2, aD2, aD2max, aT1, aT2, aT;
526   gp_Pnt aP, aPV;
527   gp_Pnt2d aP2D;
528   TopoDS_Face aF;
529   TopoDS_Vertex aV11, aV12, aV21, aV22;;
530   TopTools_IndexedDataMapOfShapeListOfShape aMVE;
531   TopTools_ListIteratorOfListOfShape aIt, aIt1;
532   //
533   aF=aFx;
534   aF.Orientation(TopAbs_FORWARD);
535   const Handle(Geom_Surface)& aS=BRep_Tool::Surface(aFx);
536   GeomAdaptor_Surface aGAS (aS);
537   //
538   bIsPeriodic=(aGAS.IsUPeriodic() || aGAS.IsVPeriodic()); 
539   //
540   TopExp::MapShapesAndAncestors(aF, 
541                                 TopAbs_VERTEX, 
542                                 TopAbs_EDGE, 
543                                 aMVE);
544   aNbV=aMVE.Extent();
545   for (i=1; i<=aNbV; ++i) {
546     const TopoDS_Vertex& aV=*((TopoDS_Vertex*)&aMVE.FindKey(i));
547     aPV=BRep_Tool::Pnt(aV);
548     aTol=BRep_Tool::Tolerance(aV);
549     aTol2=aTol*aTol;
550     //
551     aD2max=-1.;
552     const TopTools_ListOfShape& aLE=aMVE.FindFromIndex(i);
553     aIt.Initialize(aLE);
554     for (; aIt.More(); aIt.Next()) {
555       const TopoDS_Edge& aE=*(TopoDS_Edge*)(&aIt.Value());
556       const Handle(Geom2d_Curve)& aC2D=
557         BRep_Tool::CurveOnSurface(aE, aF, aT1, aT2);
558       aT=BRep_Tool::Parameter(aV, aE);
559       //
560       aC2D->D0(aT, aP2D);
561       aGAS.D0(aP2D.X(), aP2D.Y(), aP);
562       aD2=aPV.SquareDistance(aP);
563       if (aD2>aD2max) {
564         aD2max=aD2;
565       }
566       //check self interference
567       if (aNbV==2) {
568         continue;
569       }
570       //
571       if (bIsPeriodic) {
572         continue;
573       }
574       //
575       TopExp::Vertices(aE, aV11, aV12);
576       //
577       aIt1 = aIt;
578       aIt1.Next();
579       for (; aIt1.More(); aIt1.Next()) {
580         const TopoDS_Edge& aE1=*(TopoDS_Edge*)(&aIt1.Value());
581         //
582         //do not perform check for edges that have two common vertices
583         TopExp::Vertices(aE1, aV21, aV22);
584         if ((aV11.IsSame(aV21) && aV12.IsSame(aV22)) ||
585             (aV12.IsSame(aV21) && aV11.IsSame(aV22))) {
586           continue;
587         }
588         //
589         aD2=IntersectCurves2d(aPV, aF, aGAS, aE, aE1);
590         if (aD2>aD2max) {
591           aD2max=aD2;
592         }
593       }// for (; aIt1.More(); aIt1.Next()) {
594     }// for (; aIt.More(); aIt.Next()) {
595     if (aD2max>aTol2) {
596       BRep_Builder aBB;
597       //
598       aTol=sqrt(aD2max);
599       aBB.UpdateVertex(aV, aTol);
600     }
601   }// for (i=1; i<=aNbV; ++i) {
602 }
603 //=======================================================================
604 // Function : IntersectCurves2d
605 // purpose  : Intersect 2d curves of edges
606 //=======================================================================
607 Standard_Real IntersectCurves2d(const gp_Pnt& aPV,
608                                 const TopoDS_Face& aF,
609                                 const GeomAdaptor_Surface& aGAS,
610                                 const TopoDS_Edge& aE1,
611                                 const TopoDS_Edge& aE2)
612 {
613   Standard_Real aDist, aD, aT11, aT12, aT21, aT22, aTol2d, aT1, aT2;
614   Standard_Integer j, aNbPnt;
615   Geom2dInt_GInter aInter;
616   gp_Pnt aP;
617   gp_Pnt2d aP2D;
618   //
619   aDist = 0.;
620   aTol2d = 1.e-10;//Precision::Confusion();
621   //
622   const Handle(Geom2d_Curve)& aC2D1=
623     BRep_Tool::CurveOnSurface(aE1, aF, aT11, aT12);
624   const Handle(Geom2d_Curve)& aC2D2=
625     BRep_Tool::CurveOnSurface(aE2, aF, aT21, aT22);
626   //
627   Geom2dAdaptor_Curve aGAC1(aC2D1), aGAC2(aC2D2);
628   IntRes2d_Domain aDom1(aC2D1->Value(aT11), aT11, aTol2d, 
629                         aC2D1->Value(aT12), aT12, aTol2d);
630   IntRes2d_Domain aDom2(aC2D2->Value(aT21), aT21, aTol2d, 
631                         aC2D2->Value(aT22), aT22, aTol2d);
632   //
633   aInter.Perform(aGAC1, aDom1, aGAC2, aDom2, aTol2d, aTol2d);
634   if (aInter.IsDone()) {
635     if (aInter.NbSegments()) {
636       return aDist;
637     }
638     aNbPnt = aInter.NbPoints();
639     if (aNbPnt) {
640       aDist = -Precision::Infinite();
641       for (j = 1; j <= aNbPnt; ++j) {
642         const IntRes2d_IntersectionPoint& aPoint = aInter.Point(j);
643         //
644         aT1 = aPoint.ParamOnFirst();
645         aT2 = aPoint.ParamOnSecond();
646         //
647         if ((aT1 < aT11 || aT1 > aT12) ||
648             (aT2 < aT21 || aT2 > aT22)) {
649           continue;
650         }          
651         //
652         aP2D = aPoint.Value();
653         aGAS.D0(aP2D.X(), aP2D.Y(), aP);
654         aD=aPV.SquareDistance(aP);
655         if (aD > aDist) {
656           aDist = 1.01 * aD;
657         }
658       }
659     }
660   }
661   return aDist;
662 }
663 //=======================================================================
664 // Function : CorrectEdgeTolerance
665 // purpose :  Correct tolerances for Edge 
666 //=======================================================================
667 void CorrectEdgeTolerance (const TopoDS_Edge& myShape, 
668                            const TopoDS_Face& S,
669                            const Standard_Real aMaxTol)
670 {
671   // 
672   // 1. Minimum of conditions to Perform
673   Handle (BRep_CurveRepresentation) myCref;
674   Handle (Adaptor3d_HCurve) myHCurve;
675
676   myCref.Nullify();
677
678   Handle(BRep_TEdge)& TEx = *((Handle(BRep_TEdge)*)&myShape.TShape());
679   BRep_ListIteratorOfListOfCurveRepresentation itcrx(TEx->Curves());
680   Standard_Boolean Degenerated, SameParameterx, SameRangex;
681
682   Standard_Integer unique = 0;
683
684   Degenerated    = TEx->Degenerated();
685   SameParameterx = TEx->SameParameter();
686   SameRangex     = TEx->SameRange();
687   
688   if (!SameRangex && SameParameterx) {
689     return;
690   }
691
692   Handle(Geom_Curve) C3d;
693   while (itcrx.More()) {
694     const Handle(BRep_CurveRepresentation)& cr = itcrx.Value();
695     if (cr->IsCurve3D()) {
696       unique++;
697       if (myCref.IsNull() && !cr->Curve3D().IsNull()) {
698         myCref = cr;
699       }
700     }
701     itcrx.Next();
702   }
703   
704   if (unique==0) {
705     return;//...No3DCurve
706   }
707   if (unique>1) {
708     return;//...Multiple3DCurve;
709   }
710
711   if (myCref.IsNull() && !Degenerated) {
712     itcrx.Initialize(TEx->Curves());
713     while (itcrx.More()) {
714       const Handle(BRep_CurveRepresentation)& cr = itcrx.Value();
715       if (cr->IsCurveOnSurface()) {
716         myCref = cr;
717         break;
718       }
719       itcrx.Next();
720     }
721   }
722   
723   else if (!myCref.IsNull() && Degenerated){
724     return ;//...InvalidDegeneratedFlag;
725   }
726   
727   if (!myCref.IsNull()) {
728     const Handle(BRep_GCurve)& GCref = 
729       *((Handle(BRep_GCurve)*)&myCref);
730     Standard_Real First,Last;
731     GCref->Range(First,Last);
732     if (Last<=First) {
733       myCref.Nullify();
734       return ;//InvalidRange;
735     }
736     
737     else {
738       if (myCref->IsCurve3D()) {
739         Handle(Geom_Curve) C3dx = Handle(Geom_Curve)::DownCast
740           (myCref->Curve3D()->Transformed 
741            (myCref->Location().Transformation()));
742         GeomAdaptor_Curve GAC3d(C3dx, First, Last);
743         myHCurve = new GeomAdaptor_HCurve(GAC3d);
744       }
745       else { // curve on surface
746         Handle(Geom_Surface) Sref = myCref->Surface();
747         Sref = Handle(Geom_Surface)::
748           DownCast(Sref->Transformed(myCref->Location().Transformation()));
749         const  Handle(Geom2d_Curve)& PCref = myCref->PCurve();
750         Handle(GeomAdaptor_HSurface) GAHSref = 
751           new GeomAdaptor_HSurface(Sref);
752         Handle(Geom2dAdaptor_HCurve) GHPCref = 
753           new Geom2dAdaptor_HCurve(PCref, First, Last);
754         Adaptor3d_CurveOnSurface ACSref(GHPCref,GAHSref);
755         myHCurve = new Adaptor3d_HCurveOnSurface(ACSref);
756       }
757     }
758   }
759
760   //=============================================== 
761   // 2. Tolerances in InContext
762   {
763     if (myCref.IsNull()) 
764       return;
765     Standard_Boolean ok=Standard_True;;
766
767     Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*)&myShape.TShape());
768     Standard_Real Tol = BRep_Tool::Tolerance(TopoDS::Edge(myShape));
769     Standard_Real aNewTol=Tol;
770
771     Standard_Boolean SameParameter = TE->SameParameter();
772     Standard_Boolean SameRange = TE->SameRange();
773     Standard_Real First = myHCurve->FirstParameter();
774     Standard_Real Last  = myHCurve->LastParameter();
775     Standard_Real Delta =1.e-12;
776
777     Handle(BRep_TFace)& TF = *((Handle(BRep_TFace)*) &S.TShape());
778     const TopLoc_Location& Floc = S.Location();
779     const TopLoc_Location& TFloc = TF->Location();
780     const Handle(Geom_Surface)& Su = TF->Surface();
781     TopLoc_Location L = (Floc * TFloc).Predivided(myShape.Location());
782     Standard_Boolean pcurvefound = Standard_False;
783
784     BRep_ListIteratorOfListOfCurveRepresentation itcr(TE->Curves());
785     while (itcr.More()) {
786       const Handle(BRep_CurveRepresentation)& cr = itcr.Value();
787       if (cr != myCref && cr->IsCurveOnSurface(Su,L)) {
788         pcurvefound = Standard_True;
789         const Handle(BRep_GCurve)& GC = *((Handle(BRep_GCurve)*)&cr);
790         Standard_Real f,l;
791         GC->Range(f,l);
792         if (SameRange && (f != First || l != Last)) {
793           return ;//BRepCheck_InvalidSameRangeFlag;
794         }
795  
796         Handle(Geom_Surface) Sb = cr->Surface();
797         Sb = Handle(Geom_Surface)::
798           DownCast (Su->Transformed(L.Transformation()));
799         Handle(Geom2d_Curve) PC = cr->PCurve();
800         Handle(GeomAdaptor_HSurface) GAHS = 
801           new GeomAdaptor_HSurface(Sb);
802         Handle(Geom2dAdaptor_HCurve) GHPC = 
803           new Geom2dAdaptor_HCurve(PC,f,l);
804         Adaptor3d_CurveOnSurface ACS(GHPC,GAHS);
805         ok = Validate(myHCurve->Curve(), ACS, 
806                       Tol, SameParameter, aNewTol);
807         if (ok) {
808           if (aNewTol<aMaxTol) {
809             TE->UpdateTolerance(aNewTol+Delta); 
810             //
811             CorrectVertexTolerance(myShape);
812           }
813         }
814         
815         if (cr->IsCurveOnClosedSurface()) {
816           //checkclosed = Standard_True;
817           GHPC->ChangeCurve2d().Load(cr->PCurve2(),f,l); // same bounds
818           ACS.Load(GAHS); // sans doute inutile
819           ACS.Load(GHPC); // meme remarque...
820           ok = Validate(myHCurve->Curve(),ACS,Tol,SameParameter, aNewTol);
821           if (ok) {
822             if (aNewTol<aMaxTol) {
823               TE->UpdateTolerance(aNewTol+Delta);
824               CorrectVertexTolerance(myShape);
825             } 
826           }
827         }
828       }
829       itcr.Next();
830     }
831     
832     if (!pcurvefound) {
833       Handle(Geom_Plane) P;
834       Handle(Standard_Type) styp = Su->DynamicType();
835       if (styp == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
836         P = Handle(Geom_Plane)::
837           DownCast(Handle(Geom_RectangularTrimmedSurface)::
838                    DownCast(Su)->BasisSurface());
839       }
840       else {
841         P = Handle(Geom_Plane)::DownCast(Su);
842       }
843       if (P.IsNull()) { // not a plane
844         return;
845       }
846       
847       else {// on fait la projection a la volee, comme BRep_Tool
848         P = Handle(Geom_Plane)::
849           DownCast(P->Transformed(L.Transformation()));
850         //on projette Cref sur ce plan
851         Handle(GeomAdaptor_HSurface) GAHS = new GeomAdaptor_HSurface(P);
852         
853         // Dub - Normalement myHCurve est une GeomAdaptor_HCurve
854         GeomAdaptor_Curve& Gac = 
855           Handle(GeomAdaptor_HCurve)::DownCast(myHCurve)->ChangeCurve();
856         Handle(Geom_Curve) C3dx = Gac.Curve();
857         Handle(Geom_Curve) ProjOnPlane = 
858           GeomProjLib::ProjectOnPlane(new Geom_TrimmedCurve(C3dx,First,Last), 
859                                        P, 
860                                        P->Position().Direction(), 
861                                        Standard_True);
862         
863         Handle(GeomAdaptor_HCurve) aHCurve = 
864           new GeomAdaptor_HCurve(ProjOnPlane);
865         
866         ProjLib_ProjectedCurve proj(GAHS,aHCurve);
867         Handle(Geom2d_Curve) PC = Geom2dAdaptor::MakeCurve(proj);
868         Handle(Geom2dAdaptor_HCurve) GHPC = 
869           new Geom2dAdaptor_HCurve(PC, 
870                                    myHCurve->FirstParameter(), 
871                                    myHCurve->LastParameter());
872         
873         Adaptor3d_CurveOnSurface ACS(GHPC,GAHS);
874         
875         Standard_Boolean okx = Validate(myHCurve->Curve(),ACS,
876                                         Tol,Standard_True, aNewTol); 
877         if (okx) {
878           if (aNewTol<aMaxTol) {
879             TE->UpdateTolerance(aNewTol+Delta);
880             CorrectVertexTolerance(myShape);
881           }
882         }
883       }
884     }//end of if (!pcurvefound) {
885   } // end of  2. Tolerances in InContext
886 }
887 //=======================================================================
888 //function : CorrectVertexTolerance
889 //purpose  : 
890 //=======================================================================
891 void CorrectVertexTolerance(const TopoDS_Edge& aE)
892 {
893   Standard_Real aTolE, aTolV;
894   TopoDS_Iterator aIt;
895   //
896   aTolE=BRep_Tool::Tolerance(aE);
897   aIt.Initialize(aE);
898   for(; aIt.More(); aIt.Next()) {
899     const TopoDS_Vertex& aV=*((TopoDS_Vertex*)&aIt.Value());
900     aTolV=BRep_Tool::Tolerance(aV);
901     if (aTolV<aTolE) {
902       Handle(BRep_TVertex)& aTV= *((Handle(BRep_TVertex)*)&aV.TShape());
903       aTV->UpdateTolerance(aTolE);
904     }
905   }
906 }
907 //=======================================================================
908 //function : Validate
909 //purpose  : 
910 //=======================================================================
911 Standard_Boolean Validate(const Adaptor3d_Curve& CRef,
912                           const Adaptor3d_Curve& Other,
913                           const Standard_Real Tol,
914                           const Standard_Boolean SameParameter,
915                           Standard_Real& aNewTolerance)
916 {
917   Standard_Real First, Last, MaxDistance, aD, Tol2;
918
919   First = CRef.FirstParameter();
920   Last  = CRef.LastParameter();
921   MaxDistance = 0.;
922   Tol2 = Tol*Tol;
923   //
924   Standard_Integer NCONTROL=23;
925   Standard_Integer i, aNC1=NCONTROL-1;
926
927   Standard_Boolean aFlag=Standard_False;
928   Standard_Boolean proj = (!SameParameter || 
929                            First != Other.FirstParameter() ||
930                            Last  != Other.LastParameter());
931   //
932   // 1. 
933   if (!proj) {
934     for (i = 0; i < NCONTROL; i++) {
935       Standard_Real prm = ((aNC1-i)*First + i*Last)/aNC1;
936       gp_Pnt pref   = CRef.Value(prm);
937       gp_Pnt pother = Other.Value(prm);
938       
939       aD=pref.SquareDistance(pother);
940
941       if (aD > Tol2) {
942         if (aD>MaxDistance) {
943           MaxDistance=aD;
944         }
945         aFlag=Standard_True;
946       }
947     }
948
949     if (aFlag) {
950       aNewTolerance=sqrt(MaxDistance);
951     }
952     return aFlag;
953   }
954   
955   //
956   // 2.
957   else {
958     Extrema_LocateExtPC refd,otherd;
959     Standard_Real OFirst, OLast;
960     OFirst = Other.FirstParameter();
961     OLast  = Other.LastParameter();
962     
963     gp_Pnt pd  = CRef.Value(First);
964     gp_Pnt pdo = Other.Value(OFirst);
965     
966     aD = pd.SquareDistance(pdo);
967     if (aD > Tol2) {
968       if (aD>MaxDistance) {
969         MaxDistance=aD;
970       }
971       aFlag=Standard_True;
972     }
973
974     pd  = CRef.Value(Last);
975     pdo = Other.Value(OLast);
976     aD = pd.SquareDistance(pdo);
977     if (aD > Tol2 && aD > MaxDistance) {
978       MaxDistance=aD;
979       aFlag=Standard_True;
980     }
981
982     refd.Initialize(CRef, First, Last, CRef.Resolution(Tol));
983     otherd.Initialize(Other, OFirst, OLast, Other.Resolution(Tol));
984     
985     for (i = 2; i< aNC1; i++) {
986       Standard_Real rprm = ((aNC1-i)*First + i*Last)/aNC1;
987       gp_Pnt pref = CRef.Value(rprm);
988
989       Standard_Real oprm = ((aNC1-i)*OFirst + i*OLast)/aNC1;
990       gp_Pnt pother = Other.Value(oprm);
991
992       refd.Perform(pother,rprm);
993       if (!refd.IsDone() || refd.SquareDistance() > Tol2) {
994         if (refd.IsDone()) {
995           aD=refd.SquareDistance();
996           if (aD > Tol2 && aD>MaxDistance) {
997             aFlag=Standard_True;
998             MaxDistance=aD;
999           }
1000         }
1001       }
1002
1003       otherd.Perform(pref,oprm);
1004       if (!otherd.IsDone() || otherd.SquareDistance() > Tol2) {
1005         
1006         if (otherd.IsDone()) {
1007           aD=otherd.SquareDistance();
1008           if (aD > Tol2 && aD>MaxDistance) {
1009             aFlag=Standard_True;
1010             MaxDistance=aD;
1011           }
1012         }
1013       }
1014     }
1015   }
1016   
1017   aD=sqrt (MaxDistance);
1018   aNewTolerance=aD;
1019   return aFlag;
1020 }
1021 //=======================================================================
1022 // Function : UpdateEdges
1023 // purpose : 
1024 //=======================================================================
1025 void UpdateEdges(const TopoDS_Face& aF)
1026 {
1027   Standard_Real aTolF, aTolE, aTolV;
1028   TopoDS_Iterator aItF, aItW, aItE;
1029   BRep_Builder aBB;
1030   //
1031   aTolE=aTolF= BRep_Tool::Tolerance(aF);
1032   aItF.Initialize(aF);
1033   for (; aItF.More(); aItF.Next()) {
1034     const TopoDS_Shape& aS = aItF.Value();
1035     if (aS.ShapeType()==TopAbs_WIRE) {
1036       aItW.Initialize(aS);
1037       for (; aItW.More(); aItW.Next()) {
1038         const TopoDS_Edge& aE=*((TopoDS_Edge*)&aItW.Value());
1039         aTolE = BRep_Tool::Tolerance(aE);
1040         if (aTolE < aTolF) {
1041           aBB.UpdateEdge(aE, aTolF);
1042           aTolE = aTolF;
1043         }
1044         //UpdateVertices(aE);
1045       }
1046     }
1047     else {
1048       const TopoDS_Vertex& aV=*(TopoDS_Vertex*)&aItF.Value();
1049       aTolV = BRep_Tool::Tolerance(aV);
1050       if (aTolV < aTolE) {
1051         aBB.UpdateVertex(aV, aTolF);
1052       }
1053     }
1054   }
1055 }
1056 //=======================================================================
1057 // Function : ComputeTolerance
1058 // purpose : 
1059 //=======================================================================
1060 Standard_Boolean BOPTools_AlgoTools::ComputeTolerance
1061   (const TopoDS_Face& theFace,
1062    const TopoDS_Edge& theEdge,
1063    Standard_Real& theMaxDist,
1064    Standard_Real& theMaxPar)
1065 {
1066   BRepLib_CheckCurveOnSurface aCS;
1067   //
1068   aCS.Init(theEdge, theFace);
1069   aCS.Perform();
1070   if (!aCS.IsDone()) {
1071     return Standard_False;
1072   }
1073   //
1074   theMaxDist = aCS.MaxDistance();
1075   theMaxPar  = aCS.MaxParameter();
1076     //
1077   return Standard_True;
1078 }