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