0025410: Tool for extended check of validity of the curve on the surface
[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 <BOPCol_NCVector.hxx>
81 #include <BOPCol_TBB.hxx>
82
83 static 
84   void CheckEdge (const TopoDS_Edge& E,
85                   const Standard_Real aMaxTol);
86 static 
87   void CorrectEdgeTolerance (const TopoDS_Edge& myShape,
88                              const TopoDS_Face& S,
89                              const Standard_Real aMaxTol);
90 static 
91   Standard_Boolean Validate(const Adaptor3d_Curve& CRef,
92                             const Adaptor3d_Curve& Other,
93                             const Standard_Real Tol,
94                             const Standard_Boolean SameParameter,
95                             Standard_Real& aNewTolerance);
96
97 static
98   void CorrectVertexTolerance(const TopoDS_Edge& aE);
99
100 static
101   void CorrectWires(const TopoDS_Face& aF);
102
103
104
105 static
106   void UpdateEdges(const TopoDS_Face& aF);
107
108 static 
109   Standard_Real IntersectCurves2d(const gp_Pnt& aPV,
110                                   const TopoDS_Face& aF,
111                                   const Handle(Geom_Surface)& aS,
112                                   const TopoDS_Edge& aE1,
113                                   const TopoDS_Edge& aE2);
114
115
116
117 //=======================================================================
118 //class    : BOPTools_CPC
119 //purpose  : 
120 //=======================================================================
121 class BOPTools_CPC {
122  public:
123   BOPTools_CPC()
124     : myMaxTol(1.e-7) {
125   }
126   //
127   ~BOPTools_CPC() {
128   }
129   //
130   void SetEdge(const TopoDS_Edge& aE) {
131     myEdge=aE;
132   }
133   //
134   const TopoDS_Edge& Edge()const {
135     return myEdge;
136   }
137   //
138   void SetMaxTol(const Standard_Real aMaxTol) {
139     myMaxTol=aMaxTol;
140   }
141   //
142   Standard_Real MaxTol()const {
143     return myMaxTol;
144   }
145   //
146   void Perform() {
147     CheckEdge(myEdge, myMaxTol);
148   }
149   
150  protected:
151   Standard_Real myMaxTol;
152   TopoDS_Edge myEdge;
153 };
154 //
155 //=======================================================================
156 typedef BOPCol_NCVector<BOPTools_CPC> BOPTools_VectorOfCPC; 
157 //
158 typedef BOPCol_TBBFunctor 
159   <BOPTools_CPC,
160   BOPTools_VectorOfCPC> BOPTools_CPCFunctor;
161 //
162 typedef BOPCol_TBBCnt 
163   <BOPTools_CPCFunctor,
164   BOPTools_VectorOfCPC> BOPTools_CPCCnt;
165 //
166 //=======================================================================
167 //class    : BOPTools_CWT
168 //purpose  : 
169 //=======================================================================
170 class BOPTools_CWT {
171  public:
172   BOPTools_CWT() {
173   }
174   //
175   ~BOPTools_CWT() {
176   }
177   //
178   void SetFace(const TopoDS_Face& aF) {
179     myFace=aF;
180   }
181   //
182   void Perform() {
183     CorrectWires(myFace);
184   }
185   //
186  protected:
187   TopoDS_Face myFace;
188 };
189 //=======================================================================
190 typedef BOPCol_NCVector<BOPTools_CWT> BOPTools_VectorOfCWT; 
191 //
192 typedef BOPCol_TBBFunctor 
193   <BOPTools_CWT,
194   BOPTools_VectorOfCWT> BOPTools_CWTFunctor;
195 //
196 typedef BOPCol_TBBCnt 
197   <BOPTools_CWTFunctor,
198   BOPTools_VectorOfCWT> BOPTools_CWTCnt;
199 //
200 //=======================================================================
201 //class    : BOPTools_CDT
202 //purpose  : 
203 //=======================================================================
204 class BOPTools_CDT {
205  public:
206   BOPTools_CDT() 
207     : myMaxTol(1.e-7) {
208   }
209   //
210   ~BOPTools_CDT() {
211   }
212   //
213   void SetEdge(const TopoDS_Edge& aE) {
214     myEdge=aE;
215   }
216   //
217   void SetFace(const TopoDS_Face& aF) {
218     myFace=aF;
219   }
220   //
221   void SetMaxTol(const Standard_Real aMaxTol) {
222     myMaxTol=aMaxTol;
223   }
224   //
225   void Perform() {
226     CorrectEdgeTolerance (myEdge, myFace, myMaxTol);
227   }
228   //
229  protected:
230   Standard_Real myMaxTol;
231   TopoDS_Edge myEdge;
232   TopoDS_Face myFace;
233 };
234 //=======================================================================
235 typedef BOPCol_NCVector<BOPTools_CDT> BOPTools_VectorOfCDT; 
236 //
237 typedef BOPCol_TBBFunctor 
238   <BOPTools_CDT,
239   BOPTools_VectorOfCDT> BOPTools_CDTFunctor;
240 //
241 typedef BOPCol_TBBCnt 
242   <BOPTools_CDTFunctor,
243   BOPTools_VectorOfCDT> BOPTools_CDTCnt;
244 //
245 //=======================================================================
246 //class    : BOPTools_CVT
247 //purpose  : 
248 //=======================================================================
249 class BOPTools_CVT {
250  public:
251   BOPTools_CVT() {
252   }
253   //
254   ~BOPTools_CVT() {
255   }
256   //
257   void SetEdge(const TopoDS_Edge& aE) {
258     myEdge=aE;
259   }
260   //
261   void Perform() {
262     CorrectVertexTolerance(myEdge);
263   }
264   //
265  protected:
266   TopoDS_Edge myEdge;
267 };
268 //
269 //=======================================================================
270 typedef BOPCol_NCVector<BOPTools_CVT> BOPTools_VectorOfCVT; 
271 //
272 typedef BOPCol_TBBFunctor 
273   <BOPTools_CVT,
274   BOPTools_VectorOfCVT> BOPTools_CVTFunctor;
275 //
276 typedef BOPCol_TBBCnt 
277   <BOPTools_CVTFunctor,
278   BOPTools_VectorOfCVT> BOPTools_CVTCnt;
279 //
280 //=======================================================================
281 //class    : BOPTools_CET
282 //purpose  : 
283 //=======================================================================
284 class BOPTools_CET {
285  public:
286   BOPTools_CET() {
287   }
288   //
289   ~BOPTools_CET() {
290   }
291   //
292   void SetFace(const TopoDS_Face& aF) {
293     myFace=aF;
294   }
295   //
296   void Perform() {
297     UpdateEdges(myFace);
298   }
299   //
300  protected:
301   TopoDS_Face myFace;
302 };
303 //=======================================================================
304 typedef BOPCol_NCVector<BOPTools_CET> BOPTools_VectorOfCET; 
305 //
306 typedef BOPCol_TBBFunctor 
307   <BOPTools_CET,
308   BOPTools_VectorOfCET> BOPTools_CETFunctor;
309 //
310 typedef BOPCol_TBBCnt 
311   <BOPTools_CETFunctor,
312   BOPTools_VectorOfCET> BOPTools_CETCnt;
313 //
314 //
315 //=======================================================================
316 //class    : BOPTools_CheckCurveOnSurface
317 //purpose  : it is used to check the curve on the surface
318 //=======================================================================
319 #include <math_GlobOptMin.hxx>
320 #include <math_MultipleVarFunctionWithHessian.hxx>
321 #include <math_Matrix.hxx>
322 #include <Geom2d_TrimmedCurve.hxx>
323
324 class BOPTools_CheckCurveOnSurface : 
325   public math_MultipleVarFunctionWithHessian
326 {
327  public:
328   BOPTools_CheckCurveOnSurface(BOPTools_CheckCurveOnSurface&);
329   BOPTools_CheckCurveOnSurface(const Handle(Geom_Curve)& theC3D,
330                               const Handle(Geom2d_Curve)& theC2D,
331                               const Handle(Geom_Surface)& theSurf)
332     :
333       my3DCurve(theC3D),
334       my2DCurve(theC2D),
335       mySurf(theSurf)
336   {
337   }
338   //
339   virtual Standard_Integer NbVariables() const {
340     return 1;
341   }
342   //
343   virtual Standard_Boolean Value(const math_Vector& theX,
344                                  Standard_Real& theFVal) {
345     try {
346       const Standard_Real aPar = theX(1);
347       gp_Pnt aP1, aP2;
348       gp_Pnt2d aP2d;
349       my3DCurve->D0(aPar, aP1);
350       my2DCurve->D0(aPar, aP2d);
351       mySurf->D0(aP2d.X(), aP2d.Y(), aP2);
352       //
353       theFVal = -1.0*aP1.SquareDistance(aP2);
354     }
355     catch(...) {
356       return Standard_False;
357     }
358     //
359     return Standard_True;
360   }
361   //
362   virtual Standard_Integer GetStateNumber() {
363     return 0;
364   }
365   //
366   virtual Standard_Boolean Gradient(const math_Vector& theX,
367                                     math_Vector& theGrad) {
368     try {
369       const Standard_Real aPar = theX(1);
370       
371       gp_Pnt aP1, aP2;
372       gp_Vec aDC3D, aDSU, aDSV;
373       gp_Pnt2d aP2d;
374       gp_Vec2d aDC2D;
375       
376       my3DCurve->D1(aPar, aP1, aDC3D);
377       my2DCurve->D1(aPar, aP2d, aDC2D);
378       mySurf->D1(aP2d.X(), aP2d.Y(), aP2, aDSU, aDSV);
379       
380       aP1.SetXYZ(aP1.XYZ() - aP2.XYZ());
381       aP2.SetXYZ(aDC3D.XYZ() - aDC2D.X()*aDSU.XYZ() - aDC2D.Y()*aDSV.XYZ());
382       
383       theGrad(1) = -2.0*aP1.XYZ().Dot(aP2.XYZ());
384     }
385     catch(...) {
386       return Standard_False;
387     }
388     
389     return Standard_True;
390   }
391   //   
392   virtual Standard_Boolean Values(const math_Vector& theX,
393                                   Standard_Real& theVal,
394                                   math_Vector& theGrad) {
395     if(!Value(theX, theVal))
396       return Standard_False;
397     
398     if(!Gradient(theX, theGrad))
399       return Standard_False;
400     
401     return Standard_True;
402   }
403   //
404   virtual Standard_Boolean Values(const math_Vector& theX,
405                                   Standard_Real& theVal,
406                                   math_Vector& theGrad,
407                                   math_Matrix& theHessian) {
408     if(!Value(theX, theVal))
409       return Standard_False;
410     
411     if(!Gradient(theX, theGrad))
412       return Standard_False;
413     
414     theHessian(1,1) = theGrad(1);
415     
416     return Standard_True;
417   }
418   //
419  private:
420   Handle(Geom_Curve) my3DCurve;
421   Handle(Geom2d_Curve) my2DCurve;
422   Handle(Geom_Surface) mySurf;
423 };
424 //=======================================================================
425 //
426 //=======================================================================
427 // Function : CorrectTolerances
428 // purpose : 
429 //=======================================================================
430 void BOPTools_AlgoTools::CorrectTolerances
431   (const TopoDS_Shape& aShape,
432    const Standard_Real aMaxTol,
433    const Standard_Boolean bRunParallel)
434 {
435   BOPTools_AlgoTools::CorrectPointOnCurve(aShape, aMaxTol, bRunParallel);
436   BOPTools_AlgoTools::CorrectCurveOnSurface(aShape, aMaxTol, bRunParallel);
437 }
438 //
439 //=======================================================================
440 // Function : CorrectPointOnCurve
441 // purpose : 
442 //=======================================================================
443 void BOPTools_AlgoTools::CorrectPointOnCurve
444   (const TopoDS_Shape& aS,
445    const Standard_Real aMaxTol,
446    const Standard_Boolean bRunParallel)
447 {
448   TopExp_Explorer aExp;
449   BOPTools_VectorOfCPC aVCPC;
450   //
451   aExp.Init(aS, TopAbs_EDGE);
452   for(; aExp.More();  aExp.Next()) {
453     const TopoDS_Edge& aE=*((TopoDS_Edge*)&aExp.Current());
454     BOPTools_CPC& aCPC=aVCPC.Append1();
455     aCPC.SetEdge(aE);
456     aCPC.SetMaxTol(aMaxTol);
457   }
458   //
459   //======================================================
460   BOPTools_CPCCnt::Perform(bRunParallel, aVCPC);
461   //======================================================
462 }
463 //=======================================================================
464 // Function : CorrectCurveOnSurface
465 // purpose : 
466 //=======================================================================
467 void BOPTools_AlgoTools::CorrectCurveOnSurface
468   (const TopoDS_Shape& aS,
469    const Standard_Real aMaxTol,
470    const Standard_Boolean bRunParallel)
471 {
472   TopExp_Explorer aExpF, aExpE;
473   BOPTools_VectorOfCWT aVCWT;
474   BOPTools_VectorOfCDT aVCDT;
475   //
476   aExpF.Init(aS, TopAbs_FACE);
477   for (; aExpF.More(); aExpF.Next()) {
478     const TopoDS_Face& aF=*((TopoDS_Face*)&aExpF.Current());
479     //
480     BOPTools_CWT& aCWT=aVCWT.Append1();
481     aCWT.SetFace(aF);
482     //
483     aExpE.Init(aF, TopAbs_EDGE);
484     for (; aExpE.More(); aExpE.Next()) {
485       const TopoDS_Edge& aE=*((TopoDS_Edge*)&aExpE.Current());
486       //
487       BOPTools_CDT& aCDT=aVCDT.Append1();
488       aCDT.SetEdge(aE);
489       aCDT.SetFace(aF);
490       aCDT.SetMaxTol(aMaxTol);
491     }
492   }
493   //
494   //======================================================
495   BOPTools_CWTCnt::Perform(bRunParallel, aVCWT);
496   //======================================================
497   BOPTools_CDTCnt::Perform(bRunParallel, aVCDT);
498   //======================================================
499 }
500 //=======================================================================
501 // Function : CorrectShapeTolerances
502 // purpose : 
503 //=======================================================================
504 void BOPTools_AlgoTools::CorrectShapeTolerances
505   (const TopoDS_Shape& aShape,
506    const Standard_Boolean bRunParallel)
507
508   TopExp_Explorer aExp;
509   BOPTools_VectorOfCVT aVCVT;
510   BOPTools_VectorOfCET aVCET;
511   //
512   aExp.Init(aShape, TopAbs_EDGE);
513   for (; aExp.More(); aExp.Next()) {
514     const TopoDS_Edge& aE = *(TopoDS_Edge*)&aExp.Current();
515     BOPTools_CVT& aCVT=aVCVT.Append1();
516     aCVT.SetEdge(aE);
517   }
518   //
519   //======================================================
520   BOPTools_CVTCnt::Perform(bRunParallel, aVCVT);
521   //======================================================
522   //
523   aExp.Init(aShape, TopAbs_FACE);
524   for (; aExp.More(); aExp.Next()) {
525     const TopoDS_Face& aF = *(TopoDS_Face*)&aExp.Current();
526     BOPTools_CET& aCET=aVCET.Append1();
527     aCET.SetFace(aF);
528   }
529   //
530   //======================================================
531   BOPTools_CETCnt::Perform(bRunParallel, aVCET);
532   //======================================================
533 }
534 //
535 //=======================================================================
536 // Function : CheckEdge
537 // purpose :  Correct tolerances for Vertices on Edge 
538 //=======================================================================
539 void CheckEdge (const TopoDS_Edge& Ed, 
540                 const Standard_Real aMaxTol)
541 {
542   Standard_Real aTolE, aTol, aD2, aNewTolerance, dd;
543   gp_Pnt aPC;
544   TopLoc_Location L;
545   TopoDS_Edge aE;
546   TopoDS_Vertex aV;
547   TopoDS_Iterator aItS;
548   //
549   TopAbs_Orientation aOrV;
550   BRep_ListIteratorOfListOfPointRepresentation aItPR;
551   BRep_ListIteratorOfListOfCurveRepresentation aItCR;
552   //
553   aE=Ed;
554   aE.Orientation(TopAbs_FORWARD);
555   aTolE=BRep_Tool::Tolerance(aE);
556   //
557   Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*)&aE.TShape());
558   //
559   aItS.Initialize(aE);
560   for (; aItS.More(); aItS.Next()) {
561     aV= TopoDS::Vertex(aItS.Value());
562     //
563     Handle(BRep_TVertex)& TV=*((Handle(BRep_TVertex)*)&aV.TShape());
564     const gp_Pnt& aPV = TV->Pnt();
565     //
566     aTol=BRep_Tool::Tolerance(aV);
567     aTol=Max(aTol, aTolE);
568     dd=0.1*aTol;
569     aTol*=aTol;
570     //
571     const TopLoc_Location& Eloc = aE.Location();
572     //
573     aItCR.Initialize(TE->Curves());
574     while (aItCR.More()) {
575       const Handle(BRep_CurveRepresentation)& aCR = aItCR.Value();
576       const TopLoc_Location& loc = aCR->Location();
577       L = (Eloc * loc).Predivided(aV.Location());
578       //
579       if (aCR->IsCurve3D()) {
580         const Handle(Geom_Curve)& aC = aCR->Curve3D();
581         if (!aC.IsNull()) {
582           aItPR.Initialize(TV->Points());
583           while (aItPR.More()) {
584             const Handle(BRep_PointRepresentation)& aPR=aItPR.Value();
585             if (aPR->IsPointOnCurve(aC, L)) {
586               aPC = aC->Value(aPR->Parameter());
587               aPC.Transform(L.Transformation());
588               aD2=aPV.SquareDistance(aPC);
589               if (aD2 > aTol) {
590                 aNewTolerance=sqrt(aD2)+dd;
591                 if (aNewTolerance<aMaxTol)
592                   TV->UpdateTolerance(aNewTolerance);
593               }
594             }
595             aItPR.Next();
596           }
597           //
598           aOrV=aV.Orientation();
599           if (aOrV==TopAbs_FORWARD || aOrV==TopAbs_REVERSED) {
600             const Handle(BRep_GCurve)& aGC=*((Handle(BRep_GCurve)*)&aCR);
601             
602             if (aOrV==TopAbs_FORWARD) {
603               aPC=aC->Value(aGC->First());
604             }
605             else {
606               aPC=aC->Value(aGC->Last());
607             }
608             aPC.Transform(L.Transformation());
609             //
610             aD2=aPV.SquareDistance(aPC);
611             if (aD2 > aTol) {
612               aNewTolerance=sqrt(aD2)+dd;
613               if (aNewTolerance<aMaxTol) 
614                 TV->UpdateTolerance(aNewTolerance);
615             }
616           }
617         }
618       }
619       aItCR.Next();
620     }//  while (itcr.More()) {  
621   } // for (; aVExp.More(); aVExp.Next()) {
622 }
623 //=======================================================================
624 // Function : CorrectWires
625 // purpose : 
626 //=======================================================================
627 void CorrectWires(const TopoDS_Face& aFx)
628 {
629   Standard_Boolean bIsPeriodic; 
630   Standard_Integer i, aNbV;
631   Standard_Real aTol, aTol2, aD2, aD2max, aT1, aT2, aT;
632   gp_Pnt aP, aPV;
633   gp_Pnt2d aP2D;
634   TopoDS_Face aF;
635   TopoDS_Vertex aV11, aV12, aV21, aV22;;
636   TopTools_IndexedDataMapOfShapeListOfShape aMVE;
637   TopTools_ListIteratorOfListOfShape aIt, aIt1;
638   //
639   aF=aFx;
640   aF.Orientation(TopAbs_FORWARD);
641   const Handle(Geom_Surface)& aS=BRep_Tool::Surface(aFx);
642   GeomAdaptor_Surface aGAS (aS);
643   //
644   bIsPeriodic=(aGAS.IsUPeriodic() || aGAS.IsVPeriodic()); 
645   //
646   TopExp::MapShapesAndAncestors(aF, 
647                                 TopAbs_VERTEX, 
648                                 TopAbs_EDGE, 
649                                 aMVE);
650   aNbV=aMVE.Extent();
651   for (i=1; i<=aNbV; ++i) {
652     const TopoDS_Vertex& aV=*((TopoDS_Vertex*)&aMVE.FindKey(i));
653     aPV=BRep_Tool::Pnt(aV);
654     aTol=BRep_Tool::Tolerance(aV);
655     aTol2=aTol*aTol;
656     //
657     aD2max=-1.;
658     const TopTools_ListOfShape& aLE=aMVE.FindFromIndex(i);
659     aIt.Initialize(aLE);
660     for (; aIt.More(); aIt.Next()) {
661       const TopoDS_Edge& aE=*(TopoDS_Edge*)(&aIt.Value());
662       const Handle(Geom2d_Curve)& aC2D=
663         BRep_Tool::CurveOnSurface(aE, aF, aT1, aT2);
664       aT=BRep_Tool::Parameter(aV, aE);
665       //
666       aC2D->D0(aT, aP2D);
667       aS->D0(aP2D.X(), aP2D.Y(), aP);
668       aD2=aPV.SquareDistance(aP);
669       if (aD2>aD2max) {
670         aD2max=aD2;
671       }
672       //check self interference
673       if (aNbV==2) {
674         continue;
675       }
676       //
677       if (bIsPeriodic) {
678         continue;
679       }
680       //
681       TopExp::Vertices(aE, aV11, aV12);
682       //
683       aIt1 = aIt;
684       aIt1.Next();
685       for (; aIt1.More(); aIt1.Next()) {
686         const TopoDS_Edge& aE1=*(TopoDS_Edge*)(&aIt1.Value());
687         //
688         //do not perform check for edges that have two common vertices
689         TopExp::Vertices(aE1, aV21, aV22);
690         if ((aV11.IsSame(aV21) && aV12.IsSame(aV22)) ||
691             (aV12.IsSame(aV21) && aV11.IsSame(aV22))) {
692           continue;
693         }
694         //
695         aD2=IntersectCurves2d(aPV, aF, aS, aE, aE1);
696         if (aD2>aD2max) {
697           aD2max=aD2;
698         }
699       }// for (; aIt1.More(); aIt1.Next()) {
700     }// for (; aIt.More(); aIt.Next()) {
701     if (aD2max>aTol2) {
702       BRep_Builder aBB;
703       //
704       aTol=sqrt(aD2max);
705       aBB.UpdateVertex(aV, aTol);
706     }
707   }// for (i=1; i<=aNbV; ++i) {
708 }
709 //=======================================================================
710 // Function : IntersectCurves2d
711 // purpose  : Intersect 2d curves of edges
712 //=======================================================================
713 Standard_Real IntersectCurves2d(const gp_Pnt& aPV,
714                                 const TopoDS_Face& aF,
715                                 const Handle(Geom_Surface)& aS,
716                                 const TopoDS_Edge& aE1,
717                                 const TopoDS_Edge& aE2)
718 {
719   Standard_Real aDist, aD, aT11, aT12, aT21, aT22, aTol2d;
720   Standard_Integer j, aNbPnt;
721   Geom2dInt_GInter aInter;
722   gp_Pnt aP;
723   gp_Pnt2d aP2D;
724   //
725   aDist = 0.;
726   aTol2d = Precision::Confusion();
727   //
728   const Handle(Geom2d_Curve)& aC2D1=
729     BRep_Tool::CurveOnSurface(aE1, aF, aT11, aT12);
730   const Handle(Geom2d_Curve)& aC2D2=
731     BRep_Tool::CurveOnSurface(aE2, aF, aT21, aT22);
732   //
733   Geom2dAdaptor_Curve aGAC1(aC2D1), aGAC2(aC2D2);
734   IntRes2d_Domain aDom1(aC2D1->Value(aT11), aT11, aTol2d, 
735                         aC2D1->Value(aT12), aT12, aTol2d);
736   IntRes2d_Domain aDom2(aC2D2->Value(aT21), aT21, aTol2d, 
737                         aC2D2->Value(aT22), aT22, aTol2d);
738   //
739   aInter.Perform(aGAC1, aDom1, aGAC2, aDom2, aTol2d, aTol2d);
740   if (aInter.IsDone()) {
741     if (aInter.NbSegments()) {
742       return aDist;
743     }
744     aNbPnt = aInter.NbPoints();
745     if (aNbPnt) {
746       aDist = Precision::Infinite();
747       for (j = 1; j <= aNbPnt; ++j) {
748         aP2D = aInter.Point(j).Value();
749         aS->D0(aP2D.X(), aP2D.Y(), aP);
750         aD=aPV.SquareDistance(aP);
751         if (aD < aDist) {
752           aDist = aD;
753         }
754       }
755     }
756   }
757   return aDist;
758 }
759 //=======================================================================
760 // Function : CorrectEdgeTolerance
761 // purpose :  Correct tolerances for Edge 
762 //=======================================================================
763 void CorrectEdgeTolerance (const TopoDS_Edge& myShape, 
764                            const TopoDS_Face& S,
765                            const Standard_Real aMaxTol)
766 {
767   // 
768   // 1. Minimum of conditions to Perform
769   Handle (BRep_CurveRepresentation) myCref;
770   Handle (Adaptor3d_HCurve) myHCurve;
771
772   myCref.Nullify();
773
774   Handle(BRep_TEdge)& TEx = *((Handle(BRep_TEdge)*)&myShape.TShape());
775   BRep_ListIteratorOfListOfCurveRepresentation itcrx(TEx->Curves());
776   Standard_Boolean Degenerated, SameParameterx, SameRangex;
777
778   Standard_Integer unique = 0;
779
780   Degenerated    = TEx->Degenerated();
781   SameParameterx = TEx->SameParameter();
782   SameRangex     = TEx->SameRange();
783   
784   if (!SameRangex && SameParameterx) {
785     return;
786   }
787
788   Handle(Geom_Curve) C3d;
789   while (itcrx.More()) {
790     const Handle(BRep_CurveRepresentation)& cr = itcrx.Value();
791     if (cr->IsCurve3D()) {
792       unique++;
793       if (myCref.IsNull() && !cr->Curve3D().IsNull()) {
794         myCref = cr;
795       }
796     }
797     itcrx.Next();
798   }
799   
800   if (unique==0) {
801     return;//...No3DCurve
802   }
803   if (unique>1) {
804     return;//...Multiple3DCurve;
805   }
806
807   if (myCref.IsNull() && !Degenerated) {
808     itcrx.Initialize(TEx->Curves());
809     while (itcrx.More()) {
810       const Handle(BRep_CurveRepresentation)& cr = itcrx.Value();
811       if (cr->IsCurveOnSurface()) {
812         myCref = cr;
813         break;
814       }
815       itcrx.Next();
816     }
817   }
818   
819   else if (!myCref.IsNull() && Degenerated){
820     return ;//...InvalidDegeneratedFlag;
821   }
822   
823   if (!myCref.IsNull()) {
824     const Handle(BRep_GCurve)& GCref = 
825       *((Handle(BRep_GCurve)*)&myCref);
826     Standard_Real First,Last;
827     GCref->Range(First,Last);
828     if (Last<=First) {
829       myCref.Nullify();
830       return ;//InvalidRange;
831     }
832     
833     else {
834       if (myCref->IsCurve3D()) {
835         Handle(Geom_Curve) C3dx = Handle(Geom_Curve)::DownCast
836           (myCref->Curve3D()->Transformed 
837            (myCref->Location().Transformation()));
838         GeomAdaptor_Curve GAC3d(C3dx, First, Last);
839         myHCurve = new GeomAdaptor_HCurve(GAC3d);
840       }
841       else { // curve on surface
842         Handle(Geom_Surface) Sref = myCref->Surface();
843         Sref = Handle(Geom_Surface)::
844           DownCast(Sref->Transformed(myCref->Location().Transformation()));
845         const  Handle(Geom2d_Curve)& PCref = myCref->PCurve();
846         Handle(GeomAdaptor_HSurface) GAHSref = 
847           new GeomAdaptor_HSurface(Sref);
848         Handle(Geom2dAdaptor_HCurve) GHPCref = 
849           new Geom2dAdaptor_HCurve(PCref, First, Last);
850         Adaptor3d_CurveOnSurface ACSref(GHPCref,GAHSref);
851         myHCurve = new Adaptor3d_HCurveOnSurface(ACSref);
852       }
853     }
854   }
855
856   //=============================================== 
857   // 2. Tolerances in InContext
858   {
859     if (myCref.IsNull()) 
860       return;
861     Standard_Boolean ok=Standard_True;;
862
863     Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*)&myShape.TShape());
864     Standard_Real Tol = BRep_Tool::Tolerance(TopoDS::Edge(myShape));
865     Standard_Real aNewTol=Tol;
866
867     Standard_Boolean SameParameter = TE->SameParameter();
868     Standard_Boolean SameRange = TE->SameRange();
869     Standard_Real First = myHCurve->FirstParameter();
870     Standard_Real Last  = myHCurve->LastParameter();
871     Standard_Real Delta =1.e-12;
872
873     Handle(BRep_TFace)& TF = *((Handle(BRep_TFace)*) &S.TShape());
874     const TopLoc_Location& Floc = S.Location();
875     const TopLoc_Location& TFloc = TF->Location();
876     const Handle(Geom_Surface)& Su = TF->Surface();
877     TopLoc_Location L = (Floc * TFloc).Predivided(myShape.Location());
878     Standard_Boolean pcurvefound = Standard_False;
879
880     BRep_ListIteratorOfListOfCurveRepresentation itcr(TE->Curves());
881     while (itcr.More()) {
882       const Handle(BRep_CurveRepresentation)& cr = itcr.Value();
883       if (cr != myCref && cr->IsCurveOnSurface(Su,L)) {
884         pcurvefound = Standard_True;
885         const Handle(BRep_GCurve)& GC = *((Handle(BRep_GCurve)*)&cr);
886         Standard_Real f,l;
887         GC->Range(f,l);
888         if (SameRange && (f != First || l != Last)) {
889           return ;//BRepCheck_InvalidSameRangeFlag;
890         }
891  
892         Handle(Geom_Surface) Sb = cr->Surface();
893         Sb = Handle(Geom_Surface)::
894           DownCast (Su->Transformed(L.Transformation()));
895         Handle(Geom2d_Curve) PC = cr->PCurve();
896         Handle(GeomAdaptor_HSurface) GAHS = 
897           new GeomAdaptor_HSurface(Sb);
898         Handle(Geom2dAdaptor_HCurve) GHPC = 
899           new Geom2dAdaptor_HCurve(PC,f,l);
900         Adaptor3d_CurveOnSurface ACS(GHPC,GAHS);
901         ok = Validate(myHCurve->Curve(), ACS, 
902                       Tol, SameParameter, aNewTol);
903         if (ok) {
904           if (aNewTol<aMaxTol) {
905             TE->UpdateTolerance(aNewTol+Delta); 
906             //
907             CorrectVertexTolerance(myShape);
908           }
909         }
910         
911         if (cr->IsCurveOnClosedSurface()) {
912           //checkclosed = Standard_True;
913           GHPC->ChangeCurve2d().Load(cr->PCurve2(),f,l); // same bounds
914           ACS.Load(GAHS); // sans doute inutile
915           ACS.Load(GHPC); // meme remarque...
916           ok = Validate(myHCurve->Curve(),ACS,Tol,SameParameter, aNewTol);
917           if (ok) {
918             if (aNewTol<aMaxTol) {
919               TE->UpdateTolerance(aNewTol+Delta);
920               CorrectVertexTolerance(myShape);
921             } 
922           }
923         }
924       }
925       itcr.Next();
926     }
927     
928     if (!pcurvefound) {
929       Handle(Geom_Plane) P;
930       Handle(Standard_Type) styp = Su->DynamicType();
931       if (styp == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
932         P = Handle(Geom_Plane)::
933           DownCast(Handle(Geom_RectangularTrimmedSurface)::
934                    DownCast(Su)->BasisSurface());
935       }
936       else {
937         P = Handle(Geom_Plane)::DownCast(Su);
938       }
939       if (P.IsNull()) { // not a plane
940         return;
941       }
942       
943       else {// on fait la projection a la volee, comme BRep_Tool
944         P = Handle(Geom_Plane)::
945           DownCast(P->Transformed(L.Transformation()));
946         //on projette Cref sur ce plan
947         Handle(GeomAdaptor_HSurface) GAHS = new GeomAdaptor_HSurface(P);
948         
949         // Dub - Normalement myHCurve est une GeomAdaptor_HCurve
950         GeomAdaptor_Curve& Gac = 
951           Handle(GeomAdaptor_HCurve)::DownCast(myHCurve)->ChangeCurve();
952         Handle(Geom_Curve) C3dx = Gac.Curve();
953         Handle(Geom_Curve) ProjOnPlane = 
954           GeomProjLib::ProjectOnPlane(new Geom_TrimmedCurve(C3dx,First,Last), 
955                                        P, 
956                                        P->Position().Direction(), 
957                                        Standard_True);
958         
959         Handle(GeomAdaptor_HCurve) aHCurve = 
960           new GeomAdaptor_HCurve(ProjOnPlane);
961         
962         ProjLib_ProjectedCurve proj(GAHS,aHCurve);
963         Handle(Geom2d_Curve) PC = Geom2dAdaptor::MakeCurve(proj);
964         Handle(Geom2dAdaptor_HCurve) GHPC = 
965           new Geom2dAdaptor_HCurve(PC, 
966                                    myHCurve->FirstParameter(), 
967                                    myHCurve->LastParameter());
968         
969         Adaptor3d_CurveOnSurface ACS(GHPC,GAHS);
970         
971         Standard_Boolean okx = Validate(myHCurve->Curve(),ACS,
972                                         Tol,Standard_True, aNewTol); 
973         if (okx) {
974           if (aNewTol<aMaxTol) {
975             TE->UpdateTolerance(aNewTol+Delta);
976             CorrectVertexTolerance(myShape);
977           }
978         }
979       }
980     }//end of if (!pcurvefound) {
981   } // end of  2. Tolerances in InContext
982 }
983 //=======================================================================
984 //function : CorrectVertexTolerance
985 //purpose  : 
986 //=======================================================================
987 void CorrectVertexTolerance(const TopoDS_Edge& aE)
988 {
989   Standard_Real aTolE, aTolV;
990   TopoDS_Iterator aIt;
991   //
992   aTolE=BRep_Tool::Tolerance(aE);
993   aIt.Initialize(aE);
994   for(; aIt.More(); aIt.Next()) {
995     const TopoDS_Vertex& aV=*((TopoDS_Vertex*)&aIt.Value());
996     aTolV=BRep_Tool::Tolerance(aV);
997     if (aTolV<aTolE) {
998       Handle(BRep_TVertex)& aTV= *((Handle(BRep_TVertex)*)&aV.TShape());
999       aTV->UpdateTolerance(aTolE);
1000     }
1001   }
1002 }
1003 //=======================================================================
1004 //function : Validate
1005 //purpose  : 
1006 //=======================================================================
1007 Standard_Boolean Validate(const Adaptor3d_Curve& CRef,
1008                           const Adaptor3d_Curve& Other,
1009                           const Standard_Real Tol,
1010                           const Standard_Boolean SameParameter,
1011                           Standard_Real& aNewTolerance)
1012 {
1013   Standard_Real First, Last, MaxDistance, aD, Tol2;
1014
1015   First = CRef.FirstParameter();
1016   Last  = CRef.LastParameter();
1017   MaxDistance = 0.;
1018   Tol2 = Tol*Tol;
1019   //
1020   Standard_Integer NCONTROL=23;
1021   Standard_Integer i, aNC1=NCONTROL-1;
1022
1023   Standard_Boolean aFlag=Standard_False;
1024   Standard_Boolean proj = (!SameParameter || 
1025                            First != Other.FirstParameter() ||
1026                            Last  != Other.LastParameter());
1027   //
1028   // 1. 
1029   if (!proj) {
1030     for (i = 0; i < NCONTROL; i++) {
1031       Standard_Real prm = ((aNC1-i)*First + i*Last)/aNC1;
1032       gp_Pnt pref   = CRef.Value(prm);
1033       gp_Pnt pother = Other.Value(prm);
1034       
1035       aD=pref.SquareDistance(pother);
1036
1037       if (aD > Tol2) {
1038         if (aD>MaxDistance) {
1039           MaxDistance=aD;
1040         }
1041         aFlag=Standard_True;
1042       }
1043     }
1044
1045     if (aFlag) {
1046       aNewTolerance=sqrt(MaxDistance);
1047     }
1048     return aFlag;
1049   }
1050   
1051   //
1052   // 2.
1053   else {
1054     Extrema_LocateExtPC refd,otherd;
1055     Standard_Real OFirst, OLast;
1056     OFirst = Other.FirstParameter();
1057     OLast  = Other.LastParameter();
1058     
1059     gp_Pnt pd  = CRef.Value(First);
1060     gp_Pnt pdo = Other.Value(OFirst);
1061     
1062     aD = pd.SquareDistance(pdo);
1063     if (aD > Tol2) {
1064       if (aD>MaxDistance) {
1065         MaxDistance=aD;
1066       }
1067       aFlag=Standard_True;
1068     }
1069
1070     pd  = CRef.Value(Last);
1071     pdo = Other.Value(OLast);
1072     aD = pd.SquareDistance(pdo);
1073     if (aD > Tol2 && aD > MaxDistance) {
1074       MaxDistance=aD;
1075       aFlag=Standard_True;
1076     }
1077
1078     refd.Initialize(CRef, First, Last, CRef.Resolution(Tol));
1079     otherd.Initialize(Other, OFirst, OLast, Other.Resolution(Tol));
1080     
1081     for (i = 2; i< aNC1; i++) {
1082       Standard_Real rprm = ((aNC1-i)*First + i*Last)/aNC1;
1083       gp_Pnt pref = CRef.Value(rprm);
1084
1085       Standard_Real oprm = ((aNC1-i)*OFirst + i*OLast)/aNC1;
1086       gp_Pnt pother = Other.Value(oprm);
1087
1088       refd.Perform(pother,rprm);
1089       if (!refd.IsDone() || refd.SquareDistance() > Tol2) {
1090         if (refd.IsDone()) {
1091           aD=refd.SquareDistance();
1092           if (aD > Tol2 && aD>MaxDistance) {
1093             aFlag=Standard_True;
1094             MaxDistance=aD;
1095           }
1096         }
1097       }
1098
1099       otherd.Perform(pref,oprm);
1100       if (!otherd.IsDone() || otherd.SquareDistance() > Tol2) {
1101         
1102         if (otherd.IsDone()) {
1103           aD=otherd.SquareDistance();
1104           if (aD > Tol2 && aD>MaxDistance) {
1105             aFlag=Standard_True;
1106             MaxDistance=aD;
1107           }
1108         }
1109       }
1110     }
1111   }
1112   
1113   aD=sqrt (MaxDistance);
1114   aNewTolerance=aD;
1115   return aFlag;
1116 }
1117 //=======================================================================
1118 // Function : UpdateEdges
1119 // purpose : 
1120 //=======================================================================
1121 void UpdateEdges(const TopoDS_Face& aF)
1122 {
1123   Standard_Real aTolF, aTolE, aTolV;
1124   TopoDS_Iterator aItF, aItW, aItE;
1125   BRep_Builder aBB;
1126   //
1127   aTolE=aTolF= BRep_Tool::Tolerance(aF);
1128   aItF.Initialize(aF);
1129   for (; aItF.More(); aItF.Next()) {
1130     const TopoDS_Shape& aS = aItF.Value();
1131     if (aS.ShapeType()==TopAbs_WIRE) {
1132       aItW.Initialize(aS);
1133       for (; aItW.More(); aItW.Next()) {
1134         const TopoDS_Edge& aE=*((TopoDS_Edge*)&aItW.Value());
1135         aTolE = BRep_Tool::Tolerance(aE);
1136         if (aTolE < aTolF) {
1137           aBB.UpdateEdge(aE, aTolF);
1138           aTolE = aTolF;
1139         }
1140         //UpdateVertices(aE);
1141       }
1142     }
1143     else {
1144       const TopoDS_Vertex& aV=*(TopoDS_Vertex*)&aItF.Value();
1145       aTolV = BRep_Tool::Tolerance(aV);
1146       if (aTolV < aTolE) {
1147         aBB.UpdateVertex(aV, aTolF);
1148       }
1149     }
1150   }
1151 }
1152 //=======================================================================
1153 // Function : MinComputing
1154 // purpose : 
1155 //=======================================================================
1156 static Standard_Boolean MinComputing( BOPTools_CheckCurveOnSurface& theFunction,
1157                                       const Standard_Real theFirst,
1158                                       const Standard_Real theLast,
1159                                       const Standard_Real theEpsilon, //1.0e-3
1160                                       Standard_Real & theBestValue,
1161                                       Standard_Real & theBestParameter)
1162 {
1163   //Standard_Real aPrevValue = theBestValue;
1164   const Standard_Real aStepMin = 1.0e-2;
1165   math_Vector aFirstV(1, 1), aLastV(1, 1), anOutputParam(1, 1);
1166   aFirstV(1) = theFirst;
1167   aLastV(1) = theLast;
1168
1169   math_GlobOptMin aFinder(&theFunction, aFirstV, aLastV);
1170   aFinder.SetTol(aStepMin, theEpsilon);
1171   aFinder.Perform();
1172
1173   const Standard_Integer aNbExtr = aFinder.NbExtrema();
1174   for(Standard_Integer i = 1; i <= aNbExtr; i++)
1175   {
1176     Standard_Real aValue = 0.0;
1177     aFinder.Points(i, anOutputParam);
1178     theFunction.Value(anOutputParam, aValue);
1179     
1180     if(aValue < theBestValue)
1181     {
1182       theBestValue = aValue;
1183       theBestParameter = anOutputParam(1);
1184     }
1185   }
1186
1187   return Standard_True;
1188 }
1189
1190 //=======================================================================
1191 // Function : ComputeTolerance
1192 // purpose : 
1193 //=======================================================================
1194 Standard_Boolean BOPTools_AlgoTools::
1195           ComputeTolerance( const Handle(Geom_Curve)& theCurve3D,
1196                             const Handle(Geom2d_Curve)& theCurve2D,
1197                             const Handle(Geom_Surface)& theSurf,
1198                             Standard_Real& theMaxDist,
1199                             Standard_Real& theMaxPar)
1200 {
1201   if (theCurve3D.IsNull() ||
1202       theCurve2D.IsNull() ||
1203       theSurf.IsNull()) {
1204     return Standard_False;
1205   }
1206
1207   const Standard_Real anEpsilonRange = 1.0e-3, aMinDelta = 1.0e-5;
1208
1209   //
1210   try {
1211     Standard_Real aFirst = theCurve3D->FirstParameter(),
1212                   aLast = theCurve3D->LastParameter();
1213
1214     BOPTools_CheckCurveOnSurface aFunc(theCurve3D, theCurve2D, theSurf);
1215     //
1216     math_Vector anOutputParam(1, 1);
1217     anOutputParam(1) = theMaxPar = aFirst;
1218     //
1219     theMaxDist = 0.;
1220     MinComputing(aFunc, aFirst, aLast, anEpsilonRange, theMaxDist, theMaxPar);
1221
1222     Standard_Integer aNbIteration = 100;
1223     Standard_Boolean aStatus = Standard_True;
1224     while((aNbIteration-- >= 0) && aStatus)
1225     {
1226       Standard_Real aValue = theMaxDist, aParam = theMaxPar;
1227       Standard_Real aBP = theMaxPar - aMinDelta;
1228       MinComputing(aFunc, aFirst, aBP, anEpsilonRange, theMaxDist, theMaxPar);
1229
1230       if(theMaxDist < aValue)
1231       {
1232         aLast = aBP;
1233         aStatus = Standard_True;
1234       }
1235       else 
1236       {
1237         theMaxDist = aValue;
1238         theMaxPar = aParam;
1239         aStatus = Standard_False;
1240       }
1241
1242       if(!aStatus)
1243       {
1244         aBP = theMaxPar + aMinDelta;
1245         MinComputing(aFunc, aBP, aLast, 1.0e-3, theMaxDist, theMaxPar);
1246
1247         if(theMaxDist < aValue)
1248         {
1249           aFirst = aBP;
1250           aStatus = Standard_True;
1251         }
1252         else
1253         {
1254           theMaxDist = aValue;
1255           theMaxPar = aParam;
1256           aStatus = Standard_False;
1257         }
1258       }
1259     }
1260
1261     theMaxDist = sqrt(Abs(theMaxDist));
1262   }
1263   catch (...) {
1264     return Standard_False;
1265   }
1266   //
1267   return Standard_True;
1268 }
1269
1270 //=======================================================================
1271 // Function : ComputeTolerance
1272 // purpose : 
1273 //=======================================================================
1274 Standard_Boolean BOPTools_AlgoTools::ComputeTolerance
1275   (const TopoDS_Face& theFace,
1276    const TopoDS_Edge& theEdge,
1277    Standard_Real& theMaxDist,
1278    Standard_Real& theParameter)
1279 {
1280   Standard_Boolean bRet;
1281   Standard_Real aT, aD, aFirst, aLast;
1282   TopLoc_Location aLocC, aLocS;
1283   //
1284   theMaxDist = 0.;
1285   theParameter = 0.;
1286   bRet = Standard_False;
1287   //
1288   const Handle(BRep_TEdge)& aTE = *((Handle(BRep_TEdge)*)&theEdge.TShape());
1289   //The edge is considered to be same range and not degenerated
1290   if ((!aTE->SameRange() && aTE->SameParameter()) ||
1291       aTE->Degenerated()) {
1292     return bRet;
1293   }
1294   //
1295   Handle(Geom_Curve) aC = Handle(Geom_Curve)::
1296     DownCast(BRep_Tool::Curve(theEdge, aLocC, aFirst, aLast)->Copy());
1297   aC = new Geom_TrimmedCurve(aC, aFirst, aLast);
1298   aC->Transform(aLocC.Transformation());
1299   //
1300   const Handle(Geom_Surface)& aSurfF = BRep_Tool::Surface(theFace, aLocS);
1301   const Handle(Geom_Surface)& aSurf = Handle(Geom_Surface)::
1302     DownCast(aSurfF->Copy()->Transformed(aLocS.Transformation()));
1303   //
1304   Standard_Boolean isPCurveFound = Standard_False;
1305   BRep_ListIteratorOfListOfCurveRepresentation itcr(aTE->Curves());
1306   for (; itcr.More(); itcr.Next()) {
1307     const Handle(BRep_CurveRepresentation)& cr = itcr.Value();
1308     if (!(cr->IsCurveOnSurface(aSurfF, aLocS.Predivided(theEdge.Location())))) {
1309       continue;
1310     }
1311     isPCurveFound = Standard_True;
1312     //
1313     Handle(Geom2d_Curve) aC2d = Handle(Geom2d_Curve)::
1314       DownCast(cr->PCurve()->Copy());
1315     aC2d = new Geom2d_TrimmedCurve(aC2d, aFirst, aLast);
1316       //
1317     if(BOPTools_AlgoTools::ComputeTolerance
1318        (aC, aC2d, aSurf, aD, aT)) {
1319       bRet = Standard_True;
1320       if (aD > theMaxDist) {
1321         theMaxDist = aD;
1322         theParameter = aT;
1323       }
1324     }
1325     //
1326     if (cr->IsCurveOnClosedSurface()) {
1327       Handle(Geom2d_Curve) aC2d = Handle(Geom2d_Curve)::
1328         DownCast(cr->PCurve2()->Copy());
1329       aC2d = new Geom2d_TrimmedCurve(aC2d, aFirst, aLast);
1330       //
1331       if(BOPTools_AlgoTools::ComputeTolerance
1332          (aC, aC2d, aSurf, aD, aT)) {
1333         bRet = Standard_True;
1334         if (aD > theMaxDist) {
1335           theMaxDist = aD;
1336           theParameter = aT;
1337         }
1338       }
1339     }
1340   }
1341   //
1342   if (isPCurveFound) {
1343     return bRet;
1344   }
1345   //
1346   Handle(Geom_Plane) aPlane;
1347   Handle(Standard_Type) dtyp = aSurf->DynamicType();
1348   //
1349   if (dtyp == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
1350     aPlane = Handle(Geom_Plane)::
1351       DownCast(Handle(Geom_RectangularTrimmedSurface)::
1352                DownCast(aSurf)->BasisSurface()->Copy());
1353   }
1354   else {
1355     aPlane = Handle(Geom_Plane)::DownCast(aSurf->Copy());
1356   }
1357   //
1358   if (aPlane.IsNull()) { // not a plane
1359     return bRet;
1360   }
1361   //
1362   aPlane = Handle(Geom_Plane)::DownCast(aPlane);//
1363   //
1364   Handle(GeomAdaptor_HSurface) GAHS = new GeomAdaptor_HSurface(aPlane);
1365   Handle(Geom_Curve) ProjOnPlane = 
1366     GeomProjLib::ProjectOnPlane (new Geom_TrimmedCurve(aC, aFirst, aLast), 
1367                                  aPlane, aPlane->Position().Direction(), 
1368                                  Standard_True);
1369   Handle(GeomAdaptor_HCurve) aHCurve = new GeomAdaptor_HCurve(ProjOnPlane);
1370   //
1371   ProjLib_ProjectedCurve proj(GAHS,aHCurve);
1372   Handle(Geom2d_Curve) aC2d = Geom2dAdaptor::MakeCurve(proj);
1373   aC2d = new Geom2d_TrimmedCurve(aC2d, aFirst, aLast);
1374   //
1375   if(BOPTools_AlgoTools::ComputeTolerance
1376      (aC, aC2d, aPlane, aD, aT)) {
1377     bRet = Standard_True;
1378     if (aD > theMaxDist) {
1379       theMaxDist = aD;
1380       theParameter = aT;
1381     }
1382   }
1383   //
1384   return bRet;
1385 }