0024157: Parallelization of assembly part of BO
[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 // Function : CorrectTolerances
316 // purpose : 
317 //=======================================================================
318 void BOPTools_AlgoTools::CorrectTolerances
319   (const TopoDS_Shape& aShape,
320    const Standard_Real aMaxTol,
321    const Standard_Boolean bRunParallel)
322 {
323   BOPTools_AlgoTools::CorrectPointOnCurve(aShape, aMaxTol, bRunParallel);
324   BOPTools_AlgoTools::CorrectCurveOnSurface(aShape, aMaxTol, bRunParallel);
325 }
326 //
327 //=======================================================================
328 // Function : CorrectPointOnCurve
329 // purpose : 
330 //=======================================================================
331 void BOPTools_AlgoTools::CorrectPointOnCurve
332   (const TopoDS_Shape& aS,
333    const Standard_Real aMaxTol,
334    const Standard_Boolean bRunParallel)
335 {
336   TopExp_Explorer aExp;
337   BOPTools_VectorOfCPC aVCPC;
338   //
339   aExp.Init(aS, TopAbs_EDGE);
340   for(; aExp.More();  aExp.Next()) {
341     const TopoDS_Edge& aE=*((TopoDS_Edge*)&aExp.Current());
342     BOPTools_CPC& aCPC=aVCPC.Append1();
343     aCPC.SetEdge(aE);
344     aCPC.SetMaxTol(aMaxTol);
345   }
346   //
347   //======================================================
348   BOPTools_CPCCnt::Perform(bRunParallel, aVCPC);
349   //======================================================
350 }
351 //=======================================================================
352 // Function : CorrectCurveOnSurface
353 // purpose : 
354 //=======================================================================
355 void BOPTools_AlgoTools::CorrectCurveOnSurface
356   (const TopoDS_Shape& aS,
357    const Standard_Real aMaxTol,
358    const Standard_Boolean bRunParallel)
359 {
360   TopExp_Explorer aExpF, aExpE;
361   BOPTools_VectorOfCWT aVCWT;
362   BOPTools_VectorOfCDT aVCDT;
363   //
364   aExpF.Init(aS, TopAbs_FACE);
365   for (; aExpF.More(); aExpF.Next()) {
366     const TopoDS_Face& aF=*((TopoDS_Face*)&aExpF.Current());
367     //
368     BOPTools_CWT& aCWT=aVCWT.Append1();
369     aCWT.SetFace(aF);
370     //
371     aExpE.Init(aF, TopAbs_EDGE);
372     for (; aExpE.More(); aExpE.Next()) {
373       const TopoDS_Edge& aE=*((TopoDS_Edge*)&aExpE.Current());
374       //
375       BOPTools_CDT& aCDT=aVCDT.Append1();
376       aCDT.SetEdge(aE);
377       aCDT.SetFace(aF);
378       aCDT.SetMaxTol(aMaxTol);
379     }
380   }
381   //
382   //======================================================
383   BOPTools_CWTCnt::Perform(bRunParallel, aVCWT);
384   //======================================================
385   BOPTools_CDTCnt::Perform(bRunParallel, aVCDT);
386   //======================================================
387 }
388 //=======================================================================
389 // Function : CorrectShapeTolerances
390 // purpose : 
391 //=======================================================================
392 void BOPTools_AlgoTools::CorrectShapeTolerances
393   (const TopoDS_Shape& aShape,
394    const Standard_Boolean bRunParallel)
395
396   TopExp_Explorer aExp;
397   BOPTools_VectorOfCVT aVCVT;
398   BOPTools_VectorOfCET aVCET;
399   //
400   aExp.Init(aShape, TopAbs_EDGE);
401   for (; aExp.More(); aExp.Next()) {
402     const TopoDS_Edge& aE = *(TopoDS_Edge*)&aExp.Current();
403     BOPTools_CVT& aCVT=aVCVT.Append1();
404     aCVT.SetEdge(aE);
405   }
406   //
407   //======================================================
408   BOPTools_CVTCnt::Perform(bRunParallel, aVCVT);
409   //======================================================
410   //
411   aExp.Init(aShape, TopAbs_FACE);
412   for (; aExp.More(); aExp.Next()) {
413     const TopoDS_Face& aF = *(TopoDS_Face*)&aExp.Current();
414     BOPTools_CET& aCET=aVCET.Append1();
415     aCET.SetFace(aF);
416   }
417   //
418   //======================================================
419   BOPTools_CETCnt::Perform(bRunParallel, aVCET);
420   //======================================================
421 }
422 //
423 //=======================================================================
424 // Function : CheckEdge
425 // purpose :  Correct tolerances for Vertices on Edge 
426 //=======================================================================
427 void CheckEdge (const TopoDS_Edge& Ed, 
428                 const Standard_Real aMaxTol)
429 {
430   Standard_Real aTolE, aTol, aD2, aNewTolerance, dd;
431   gp_Pnt aPC;
432   TopLoc_Location L;
433   TopoDS_Edge aE;
434   TopoDS_Vertex aV;
435   TopoDS_Iterator aItS;
436   //
437   TopAbs_Orientation aOrV;
438   BRep_ListIteratorOfListOfPointRepresentation aItPR;
439   BRep_ListIteratorOfListOfCurveRepresentation aItCR;
440   //
441   aE=Ed;
442   aE.Orientation(TopAbs_FORWARD);
443   aTolE=BRep_Tool::Tolerance(aE);
444   //
445   Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*)&aE.TShape());
446   //
447   aItS.Initialize(aE);
448   for (; aItS.More(); aItS.Next()) {
449     aV= TopoDS::Vertex(aItS.Value());
450     //
451     Handle(BRep_TVertex)& TV=*((Handle(BRep_TVertex)*)&aV.TShape());
452     const gp_Pnt& aPV = TV->Pnt();
453     //
454     aTol=BRep_Tool::Tolerance(aV);
455     aTol=Max(aTol, aTolE);
456     dd=0.1*aTol;
457     aTol*=aTol;
458     //
459     const TopLoc_Location& Eloc = aE.Location();
460     //
461     aItCR.Initialize(TE->Curves());
462     while (aItCR.More()) {
463       const Handle(BRep_CurveRepresentation)& aCR = aItCR.Value();
464       const TopLoc_Location& loc = aCR->Location();
465       L = (Eloc * loc).Predivided(aV.Location());
466       //
467       if (aCR->IsCurve3D()) {
468         const Handle(Geom_Curve)& aC = aCR->Curve3D();
469         if (!aC.IsNull()) {
470           aItPR.Initialize(TV->Points());
471           while (aItPR.More()) {
472             const Handle(BRep_PointRepresentation)& aPR=aItPR.Value();
473             if (aPR->IsPointOnCurve(aC, L)) {
474               aPC = aC->Value(aPR->Parameter());
475               aPC.Transform(L.Transformation());
476               aD2=aPV.SquareDistance(aPC);
477               if (aD2 > aTol) {
478                 aNewTolerance=sqrt(aD2)+dd;
479                 if (aNewTolerance<aMaxTol)
480                   TV->UpdateTolerance(aNewTolerance);
481               }
482             }
483             aItPR.Next();
484           }
485           //
486           aOrV=aV.Orientation();
487           if (aOrV==TopAbs_FORWARD || aOrV==TopAbs_REVERSED) {
488             const Handle(BRep_GCurve)& aGC=*((Handle(BRep_GCurve)*)&aCR);
489             
490             if (aOrV==TopAbs_FORWARD) {
491               aPC=aC->Value(aGC->First());
492             }
493             else {
494               aPC=aC->Value(aGC->Last());
495             }
496             aPC.Transform(L.Transformation());
497             //
498             aD2=aPV.SquareDistance(aPC);
499             if (aD2 > aTol) {
500               aNewTolerance=sqrt(aD2)+dd;
501               if (aNewTolerance<aMaxTol) 
502                 TV->UpdateTolerance(aNewTolerance);
503             }
504           }
505         }
506       }
507       aItCR.Next();
508     }//  while (itcr.More()) {  
509   } // for (; aVExp.More(); aVExp.Next()) {
510 }
511 //=======================================================================
512 // Function : CorrectWires
513 // purpose : 
514 //=======================================================================
515 void CorrectWires(const TopoDS_Face& aFx)
516 {
517   Standard_Boolean bIsPeriodic; 
518   Standard_Integer i, aNbV;
519   Standard_Real aTol, aTol2, aD2, aD2max, aT1, aT2, aT;
520   gp_Pnt aP, aPV;
521   gp_Pnt2d aP2D;
522   TopoDS_Face aF;
523   TopoDS_Vertex aV11, aV12, aV21, aV22;;
524   TopTools_IndexedDataMapOfShapeListOfShape aMVE;
525   TopTools_ListIteratorOfListOfShape aIt, aIt1;
526   //
527   aF=aFx;
528   aF.Orientation(TopAbs_FORWARD);
529   const Handle(Geom_Surface)& aS=BRep_Tool::Surface(aFx);
530   GeomAdaptor_Surface aGAS (aS);
531   //
532   bIsPeriodic=(aGAS.IsUPeriodic() || aGAS.IsVPeriodic()); 
533   //
534   TopExp::MapShapesAndAncestors(aF, 
535                                 TopAbs_VERTEX, 
536                                 TopAbs_EDGE, 
537                                 aMVE);
538   aNbV=aMVE.Extent();
539   for (i=1; i<=aNbV; ++i) {
540     const TopoDS_Vertex& aV=*((TopoDS_Vertex*)&aMVE.FindKey(i));
541     aPV=BRep_Tool::Pnt(aV);
542     aTol=BRep_Tool::Tolerance(aV);
543     aTol2=aTol*aTol;
544     //
545     aD2max=-1.;
546     const TopTools_ListOfShape& aLE=aMVE.FindFromIndex(i);
547     aIt.Initialize(aLE);
548     for (; aIt.More(); aIt.Next()) {
549       const TopoDS_Edge& aE=*(TopoDS_Edge*)(&aIt.Value());
550       const Handle(Geom2d_Curve)& aC2D=
551         BRep_Tool::CurveOnSurface(aE, aF, aT1, aT2);
552       aT=BRep_Tool::Parameter(aV, aE);
553       //
554       aC2D->D0(aT, aP2D);
555       aS->D0(aP2D.X(), aP2D.Y(), aP);
556       aD2=aPV.SquareDistance(aP);
557       if (aD2>aD2max) {
558         aD2max=aD2;
559       }
560       //check self interference
561       if (aNbV==2) {
562         continue;
563       }
564       //
565       if (bIsPeriodic) {
566         continue;
567       }
568       //
569       TopExp::Vertices(aE, aV11, aV12);
570       //
571       aIt1 = aIt;
572       aIt1.Next();
573       for (; aIt1.More(); aIt1.Next()) {
574         const TopoDS_Edge& aE1=*(TopoDS_Edge*)(&aIt1.Value());
575         //
576         //do not perform check for edges that have two common vertices
577         TopExp::Vertices(aE1, aV21, aV22);
578         if ((aV11.IsSame(aV21) && aV12.IsSame(aV22)) ||
579             (aV12.IsSame(aV21) && aV11.IsSame(aV22))) {
580           continue;
581         }
582         //
583         aD2=IntersectCurves2d(aPV, aF, aS, aE, aE1);
584         if (aD2>aD2max) {
585           aD2max=aD2;
586         }
587       }// for (; aIt1.More(); aIt1.Next()) {
588     }// for (; aIt.More(); aIt.Next()) {
589     if (aD2max>aTol2) {
590       BRep_Builder aBB;
591       //
592       aTol=sqrt(aD2max);
593       aBB.UpdateVertex(aV, aTol);
594     }
595   }// for (i=1; i<=aNbV; ++i) {
596 }
597 //=======================================================================
598 // Function : IntersectCurves2d
599 // purpose  : Intersect 2d curves of edges
600 //=======================================================================
601 Standard_Real IntersectCurves2d(const gp_Pnt& aPV,
602                                 const TopoDS_Face& aF,
603                                 const Handle(Geom_Surface)& aS,
604                                 const TopoDS_Edge& aE1,
605                                 const TopoDS_Edge& aE2)
606 {
607   Standard_Real aDist, aD, aT11, aT12, aT21, aT22, aTol2d;
608   Standard_Integer j, aNbPnt;
609   Geom2dInt_GInter aInter;
610   gp_Pnt aP;
611   gp_Pnt2d aP2D;
612   //
613   aDist = 0.;
614   aTol2d = Precision::Confusion();
615   //
616   const Handle(Geom2d_Curve)& aC2D1=
617     BRep_Tool::CurveOnSurface(aE1, aF, aT11, aT12);
618   const Handle(Geom2d_Curve)& aC2D2=
619     BRep_Tool::CurveOnSurface(aE2, aF, aT21, aT22);
620   //
621   Geom2dAdaptor_Curve aGAC1(aC2D1), aGAC2(aC2D2);
622   IntRes2d_Domain aDom1(aC2D1->Value(aT11), aT11, aTol2d, 
623                         aC2D1->Value(aT12), aT12, aTol2d);
624   IntRes2d_Domain aDom2(aC2D2->Value(aT21), aT21, aTol2d, 
625                         aC2D2->Value(aT22), aT22, aTol2d);
626   //
627   aInter.Perform(aGAC1, aDom1, aGAC2, aDom2, aTol2d, aTol2d);
628   if (aInter.IsDone()) {
629     if (aInter.NbSegments()) {
630       return aDist;
631     }
632     aNbPnt = aInter.NbPoints();
633     if (aNbPnt) {
634       aDist = Precision::Infinite();
635       for (j = 1; j <= aNbPnt; ++j) {
636         aP2D = aInter.Point(j).Value();
637         aS->D0(aP2D.X(), aP2D.Y(), aP);
638         aD=aPV.SquareDistance(aP);
639         if (aD < aDist) {
640           aDist = aD;
641         }
642       }
643     }
644   }
645   return aDist;
646 }
647 //=======================================================================
648 // Function : CorrectEdgeTolerance
649 // purpose :  Correct tolerances for Edge 
650 //=======================================================================
651 void CorrectEdgeTolerance (const TopoDS_Edge& myShape, 
652                            const TopoDS_Face& S,
653                            const Standard_Real aMaxTol)
654 {
655   // 
656   // 1. Minimum of conditions to Perform
657   Handle (BRep_CurveRepresentation) myCref;
658   Handle (Adaptor3d_HCurve) myHCurve;
659
660   myCref.Nullify();
661
662   Handle(BRep_TEdge)& TEx = *((Handle(BRep_TEdge)*)&myShape.TShape());
663   BRep_ListIteratorOfListOfCurveRepresentation itcrx(TEx->Curves());
664   Standard_Boolean Degenerated, SameParameterx, SameRangex;
665
666   Standard_Integer unique = 0;
667
668   Degenerated    = TEx->Degenerated();
669   SameParameterx = TEx->SameParameter();
670   SameRangex     = TEx->SameRange();
671   
672   if (!SameRangex && SameParameterx) {
673     return;
674   }
675
676   Handle(Geom_Curve) C3d;
677   while (itcrx.More()) {
678     const Handle(BRep_CurveRepresentation)& cr = itcrx.Value();
679     if (cr->IsCurve3D()) {
680       unique++;
681       if (myCref.IsNull() && !cr->Curve3D().IsNull()) {
682         myCref = cr;
683       }
684     }
685     itcrx.Next();
686   }
687   
688   if (unique==0) {
689     return;//...No3DCurve
690   }
691   if (unique>1) {
692     return;//...Multiple3DCurve;
693   }
694
695   if (myCref.IsNull() && !Degenerated) {
696     itcrx.Initialize(TEx->Curves());
697     while (itcrx.More()) {
698       const Handle(BRep_CurveRepresentation)& cr = itcrx.Value();
699       if (cr->IsCurveOnSurface()) {
700         myCref = cr;
701         break;
702       }
703       itcrx.Next();
704     }
705   }
706   
707   else if (!myCref.IsNull() && Degenerated){
708     return ;//...InvalidDegeneratedFlag;
709   }
710   
711   if (!myCref.IsNull()) {
712     const Handle(BRep_GCurve)& GCref = 
713       *((Handle(BRep_GCurve)*)&myCref);
714     Standard_Real First,Last;
715     GCref->Range(First,Last);
716     if (Last<=First) {
717       myCref.Nullify();
718       return ;//InvalidRange;
719     }
720     
721     else {
722       if (myCref->IsCurve3D()) {
723         Handle(Geom_Curve) C3dx = Handle(Geom_Curve)::DownCast
724           (myCref->Curve3D()->Transformed 
725            (myCref->Location().Transformation()));
726         GeomAdaptor_Curve GAC3d(C3dx, First, Last);
727         myHCurve = new GeomAdaptor_HCurve(GAC3d);
728       }
729       else { // curve on surface
730         Handle(Geom_Surface) Sref = myCref->Surface();
731         Sref = Handle(Geom_Surface)::
732           DownCast(Sref->Transformed(myCref->Location().Transformation()));
733         const  Handle(Geom2d_Curve)& PCref = myCref->PCurve();
734         Handle(GeomAdaptor_HSurface) GAHSref = 
735           new GeomAdaptor_HSurface(Sref);
736         Handle(Geom2dAdaptor_HCurve) GHPCref = 
737           new Geom2dAdaptor_HCurve(PCref, First, Last);
738         Adaptor3d_CurveOnSurface ACSref(GHPCref,GAHSref);
739         myHCurve = new Adaptor3d_HCurveOnSurface(ACSref);
740       }
741     }
742   }
743
744   //=============================================== 
745   // 2. Tolerances in InContext
746   {
747     if (myCref.IsNull()) 
748       return;
749     Standard_Boolean ok=Standard_True;;
750
751     Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*)&myShape.TShape());
752     Standard_Real Tol = BRep_Tool::Tolerance(TopoDS::Edge(myShape));
753     Standard_Real aNewTol=Tol;
754
755     Standard_Boolean SameParameter = TE->SameParameter();
756     Standard_Boolean SameRange = TE->SameRange();
757     Standard_Real First = myHCurve->FirstParameter();
758     Standard_Real Last  = myHCurve->LastParameter();
759     Standard_Real Delta =1.e-12;
760
761     Handle(BRep_TFace)& TF = *((Handle(BRep_TFace)*) &S.TShape());
762     const TopLoc_Location& Floc = S.Location();
763     const TopLoc_Location& TFloc = TF->Location();
764     const Handle(Geom_Surface)& Su = TF->Surface();
765     TopLoc_Location L = (Floc * TFloc).Predivided(myShape.Location());
766     Standard_Boolean pcurvefound = Standard_False;
767
768     BRep_ListIteratorOfListOfCurveRepresentation itcr(TE->Curves());
769     while (itcr.More()) {
770       const Handle(BRep_CurveRepresentation)& cr = itcr.Value();
771       if (cr != myCref && cr->IsCurveOnSurface(Su,L)) {
772         pcurvefound = Standard_True;
773         const Handle(BRep_GCurve)& GC = *((Handle(BRep_GCurve)*)&cr);
774         Standard_Real f,l;
775         GC->Range(f,l);
776         if (SameRange && (f != First || l != Last)) {
777           return ;//BRepCheck_InvalidSameRangeFlag;
778         }
779  
780         Handle(Geom_Surface) Sb = cr->Surface();
781         Sb = Handle(Geom_Surface)::
782           DownCast (Su->Transformed(L.Transformation()));
783         Handle(Geom2d_Curve) PC = cr->PCurve();
784         Handle(GeomAdaptor_HSurface) GAHS = 
785           new GeomAdaptor_HSurface(Sb);
786         Handle(Geom2dAdaptor_HCurve) GHPC = 
787           new Geom2dAdaptor_HCurve(PC,f,l);
788         Adaptor3d_CurveOnSurface ACS(GHPC,GAHS);
789         ok = Validate(myHCurve->Curve(), ACS, 
790                       Tol, SameParameter, aNewTol);
791         if (ok) {
792           if (aNewTol<aMaxTol) {
793             TE->UpdateTolerance(aNewTol+Delta); 
794             //
795             CorrectVertexTolerance(myShape);
796           }
797         }
798         
799         if (cr->IsCurveOnClosedSurface()) {
800           //checkclosed = Standard_True;
801           GHPC->ChangeCurve2d().Load(cr->PCurve2(),f,l); // same bounds
802           ACS.Load(GAHS); // sans doute inutile
803           ACS.Load(GHPC); // meme remarque...
804           ok = Validate(myHCurve->Curve(),ACS,Tol,SameParameter, aNewTol);
805           if (ok) {
806             if (aNewTol<aMaxTol) {
807               TE->UpdateTolerance(aNewTol+Delta);
808               CorrectVertexTolerance(myShape);
809             } 
810           }
811         }
812       }
813       itcr.Next();
814     }
815     
816     if (!pcurvefound) {
817       Handle(Geom_Plane) P;
818       Handle(Standard_Type) styp = Su->DynamicType();
819       if (styp == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
820         P = Handle(Geom_Plane)::
821           DownCast(Handle(Geom_RectangularTrimmedSurface)::
822                    DownCast(Su)->BasisSurface());
823       }
824       else {
825         P = Handle(Geom_Plane)::DownCast(Su);
826       }
827       if (P.IsNull()) { // not a plane
828         return;
829       }
830       
831       else {// on fait la projection a la volee, comme BRep_Tool
832         P = Handle(Geom_Plane)::
833           DownCast(P->Transformed(L.Transformation()));
834         //on projette Cref sur ce plan
835         Handle(GeomAdaptor_HSurface) GAHS = new GeomAdaptor_HSurface(P);
836         
837         // Dub - Normalement myHCurve est une GeomAdaptor_HCurve
838         GeomAdaptor_Curve& Gac = 
839           Handle(GeomAdaptor_HCurve)::DownCast(myHCurve)->ChangeCurve();
840         Handle(Geom_Curve) C3dx = Gac.Curve();
841         Handle(Geom_Curve) ProjOnPlane = 
842           GeomProjLib::ProjectOnPlane(new Geom_TrimmedCurve(C3dx,First,Last), 
843                                        P, 
844                                        P->Position().Direction(), 
845                                        Standard_True);
846         
847         Handle(GeomAdaptor_HCurve) aHCurve = 
848           new GeomAdaptor_HCurve(ProjOnPlane);
849         
850         ProjLib_ProjectedCurve proj(GAHS,aHCurve);
851         Handle(Geom2d_Curve) PC = Geom2dAdaptor::MakeCurve(proj);
852         Handle(Geom2dAdaptor_HCurve) GHPC = 
853           new Geom2dAdaptor_HCurve(PC, 
854                                    myHCurve->FirstParameter(), 
855                                    myHCurve->LastParameter());
856         
857         Adaptor3d_CurveOnSurface ACS(GHPC,GAHS);
858         
859         Standard_Boolean okx = Validate(myHCurve->Curve(),ACS,
860                                         Tol,Standard_True, aNewTol); 
861         if (okx) {
862           if (aNewTol<aMaxTol) {
863             TE->UpdateTolerance(aNewTol+Delta);
864             CorrectVertexTolerance(myShape);
865           }
866         }
867       }
868     }//end of if (!pcurvefound) {
869   } // end of  2. Tolerances in InContext
870 }
871 //=======================================================================
872 //function : CorrectVertexTolerance
873 //purpose  : 
874 //=======================================================================
875 void CorrectVertexTolerance(const TopoDS_Edge& aE)
876 {
877   Standard_Real aTolE, aTolV;
878   TopoDS_Iterator aIt;
879   //
880   aTolE=BRep_Tool::Tolerance(aE);
881   aIt.Initialize(aE);
882   for(; aIt.More(); aIt.Next()) {
883     const TopoDS_Vertex& aV=*((TopoDS_Vertex*)&aIt.Value());
884     aTolV=BRep_Tool::Tolerance(aV);
885     if (aTolV<aTolE) {
886       Handle(BRep_TVertex)& aTV= *((Handle(BRep_TVertex)*)&aV.TShape());
887       aTV->UpdateTolerance(aTolE);
888     }
889   }
890 }
891 //=======================================================================
892 //function : Validate
893 //purpose  : 
894 //=======================================================================
895 Standard_Boolean Validate(const Adaptor3d_Curve& CRef,
896                           const Adaptor3d_Curve& Other,
897                           const Standard_Real Tol,
898                           const Standard_Boolean SameParameter,
899                           Standard_Real& aNewTolerance)
900 {
901   Standard_Real First, Last, MaxDistance, aD, Tol2;
902
903   First = CRef.FirstParameter();
904   Last  = CRef.LastParameter();
905   MaxDistance = 0.;
906   Tol2 = Tol*Tol;
907   //
908   Standard_Integer NCONTROL=23;
909   Standard_Integer i, aNC1=NCONTROL-1;
910
911   Standard_Boolean aFlag=Standard_False;
912   Standard_Boolean proj = (!SameParameter || 
913                            First != Other.FirstParameter() ||
914                            Last  != Other.LastParameter());
915   //
916   // 1. 
917   if (!proj) {
918     for (i = 0; i < NCONTROL; i++) {
919       Standard_Real prm = ((aNC1-i)*First + i*Last)/aNC1;
920       gp_Pnt pref   = CRef.Value(prm);
921       gp_Pnt pother = Other.Value(prm);
922       
923       aD=pref.SquareDistance(pother);
924
925       if (aD > Tol2) {
926         if (aD>MaxDistance) {
927           MaxDistance=aD;
928         }
929         aFlag=Standard_True;
930       }
931     }
932
933     if (aFlag) {
934       aNewTolerance=sqrt(MaxDistance);
935     }
936     return aFlag;
937   }
938   
939   //
940   // 2.
941   else {
942     Extrema_LocateExtPC refd,otherd;
943     Standard_Real OFirst, OLast;
944     OFirst = Other.FirstParameter();
945     OLast  = Other.LastParameter();
946     
947     gp_Pnt pd  = CRef.Value(First);
948     gp_Pnt pdo = Other.Value(OFirst);
949     
950     aD = pd.SquareDistance(pdo);
951     if (aD > Tol2) {
952       if (aD>MaxDistance) {
953         MaxDistance=aD;
954       }
955       aFlag=Standard_True;
956     }
957
958     pd  = CRef.Value(Last);
959     pdo = Other.Value(OLast);
960     aD = pd.SquareDistance(pdo);
961     if (aD > Tol2 && aD > MaxDistance) {
962       MaxDistance=aD;
963       aFlag=Standard_True;
964     }
965
966     refd.Initialize(CRef, First, Last, CRef.Resolution(Tol));
967     otherd.Initialize(Other, OFirst, OLast, Other.Resolution(Tol));
968     
969     for (i = 2; i< aNC1; i++) {
970       Standard_Real rprm = ((aNC1-i)*First + i*Last)/aNC1;
971       gp_Pnt pref = CRef.Value(rprm);
972
973       Standard_Real oprm = ((aNC1-i)*OFirst + i*OLast)/aNC1;
974       gp_Pnt pother = Other.Value(oprm);
975
976       refd.Perform(pother,rprm);
977       if (!refd.IsDone() || refd.SquareDistance() > Tol2) {
978         if (refd.IsDone()) {
979           aD=refd.SquareDistance();
980           if (aD > Tol2 && aD>MaxDistance) {
981             aFlag=Standard_True;
982             MaxDistance=aD;
983           }
984         }
985       }
986
987       otherd.Perform(pref,oprm);
988       if (!otherd.IsDone() || otherd.SquareDistance() > Tol2) {
989         
990         if (otherd.IsDone()) {
991           aD=otherd.SquareDistance();
992           if (aD > Tol2 && aD>MaxDistance) {
993             aFlag=Standard_True;
994             MaxDistance=aD;
995           }
996         }
997       }
998     }
999   }
1000   
1001   aD=sqrt (MaxDistance);
1002   aNewTolerance=aD;
1003   return aFlag;
1004 }
1005 //=======================================================================
1006 // Function : UpdateEdges
1007 // purpose : 
1008 //=======================================================================
1009 void UpdateEdges(const TopoDS_Face& aF)
1010 {
1011   Standard_Real aTolF, aTolE, aTolV;
1012   TopoDS_Iterator aItF, aItW, aItE;
1013   BRep_Builder aBB;
1014   //
1015   aTolE=aTolF= BRep_Tool::Tolerance(aF);
1016   aItF.Initialize(aF);
1017   for (; aItF.More(); aItF.Next()) {
1018     const TopoDS_Shape& aS = aItF.Value();
1019     if (aS.ShapeType()==TopAbs_WIRE) {
1020       aItW.Initialize(aS);
1021       for (; aItW.More(); aItW.Next()) {
1022         const TopoDS_Edge& aE=*((TopoDS_Edge*)&aItW.Value());
1023         aTolE = BRep_Tool::Tolerance(aE);
1024         if (aTolE < aTolF) {
1025           aBB.UpdateEdge(aE, aTolF);
1026           aTolE = aTolF;
1027         }
1028         //UpdateVertices(aE);
1029       }
1030     }
1031     else {
1032       const TopoDS_Vertex& aV=*(TopoDS_Vertex*)&aItF.Value();
1033       aTolV = BRep_Tool::Tolerance(aV);
1034       if (aTolV < aTolE) {
1035         aBB.UpdateVertex(aV, aTolF);
1036       }
1037     }
1038   }
1039 }