0024428: Implementation of LGPL license
[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
7 // under the terms of the GNU Lesser General Public 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 <TopTools_IndexedMapOfShape.hxx>
18 #include <TopExp.hxx>
19 #include <TopExp_Explorer.hxx>
20
21 #include <TopoDS.hxx>
22 #include <TopoDS_Edge.hxx>
23 #include <TopoDS_Vertex.hxx>
24 #include <TopoDS_Face.hxx>
25
26 #include <TopLoc_Location.hxx>
27
28 #include <BRep_TVertex.hxx>
29 #include <BRep_TEdge.hxx>
30 #include <BRep_TFace.hxx>
31 #include <BRep_Tool.hxx>
32 #include <BRep_GCurve.hxx>
33 #include <BRep_ListIteratorOfListOfPointRepresentation.hxx>
34 #include <BRep_ListIteratorOfListOfCurveRepresentation.hxx>
35 #include <BRep_CurveRepresentation.hxx>
36 #include <BRep_PointRepresentation.hxx>
37
38 #include <Geom_Curve.hxx>
39 #include <Geom_Surface.hxx>
40 #include <Geom_Plane.hxx>
41 #include <Geom_TrimmedCurve.hxx>
42
43 #include <GeomAdaptor_Curve.hxx>
44 #include <GeomAdaptor_HCurve.hxx>
45 #include <GeomAdaptor_HSurface.hxx>
46
47 #include <Geom2d_Curve.hxx>
48
49 #include <Geom2dAdaptor_HCurve.hxx>
50 #include <Geom_RectangularTrimmedSurface.hxx>
51 #include <Geom2dAdaptor.hxx>
52 #include <GeomProjLib.hxx>
53
54 #include <ProjLib_ProjectedCurve.hxx>
55 #include <Extrema_LocateExtPC.hxx>
56
57 #include <gp_Pnt.hxx>
58
59 #include <Adaptor3d_HCurve.hxx>
60 #include <Adaptor3d_CurveOnSurface.hxx>
61 #include <Adaptor3d_HCurveOnSurface.hxx>
62 //
63 #include <BRepAdaptor_Surface.hxx>
64 #include <TopoDS_Iterator.hxx>
65 #include <TopoDS_Wire.hxx>
66 #include <TopoDS.hxx>
67 #include <BRepTools_WireExplorer.hxx>
68 #include <gp_Pnt2d.hxx>
69 #include <BRep_Tool.hxx>
70 #include <BRep_Tool.hxx>
71 #include <BRep_Builder.hxx>
72 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
73 #include <TopTools_ListOfShape.hxx>
74 #include <TopTools_ListIteratorOfListOfShape.hxx>
75 #include <Geom2d_Curve.hxx>
76 #include <GeomAdaptor_Surface.hxx>
77 #include <Geom2dAdaptor_Curve.hxx>
78 #include <IntRes2d_Domain.hxx>
79 #include <Geom2dInt_GInter.hxx>
80 #include <IntRes2d_IntersectionPoint.hxx>
81
82 static 
83   void CheckEdge (const TopoDS_Edge& E,
84                   const Standard_Real aMaxTol);
85 static 
86   void CorrectEdgeTolerance (const TopoDS_Edge& myShape,
87                              const TopoDS_Face& S,
88                              const Standard_Real aMaxTol);
89 static 
90   Standard_Boolean Validate(const Adaptor3d_Curve& CRef,
91                             const Adaptor3d_Curve& Other,
92                             const Standard_Real Tol,
93                             const Standard_Boolean SameParameter,
94                             Standard_Real& aNewTolerance);
95
96 static
97   void CorrectVertexTolerance(const TopoDS_Edge& aE);
98
99 static
100   void CorrectWires(const TopoDS_Face& aF);
101
102 static 
103   Standard_Real IntersectCurves2d(const gp_Pnt& aPV,
104                                   const TopoDS_Face& aF,
105                                   const TopoDS_Edge& aE1,
106                                   const TopoDS_Edge& aE2);
107
108 static
109   void UpdateEdges(const TopoDS_Face& aF);
110
111 static
112   void UpdateVertices(const TopoDS_Edge& aE);
113
114 //=======================================================================
115 // Function : CorrectTolerances
116 // purpose : 
117 //=======================================================================
118   void BOPTools_AlgoTools::CorrectTolerances(const TopoDS_Shape& aShape,
119                                              const Standard_Real aMaxTol)
120 {
121   BOPTools_AlgoTools::CorrectPointOnCurve(aShape, aMaxTol);
122   BOPTools_AlgoTools::CorrectCurveOnSurface(aShape, aMaxTol);
123 }
124
125 //=======================================================================
126 // Function : CorrectPointOnCurve
127 // purpose : 
128 //=======================================================================
129   void BOPTools_AlgoTools::CorrectPointOnCurve(const TopoDS_Shape& S,
130                                                const Standard_Real aMaxTol)
131 {
132   Standard_Integer i, aNb;
133   TopTools_IndexedMapOfShape Edges;
134   TopExp::MapShapes (S, TopAbs_EDGE, Edges);
135   aNb=Edges.Extent();
136   for (i=1; i<=aNb; i++) {
137     const TopoDS_Edge& E= TopoDS::Edge(Edges(i));
138     CheckEdge(E, aMaxTol);
139   }     
140 }
141
142 //=======================================================================
143 // Function : CorrectCurveOnSurface
144 // purpose : 
145 //=======================================================================
146   void BOPTools_AlgoTools::CorrectCurveOnSurface(const TopoDS_Shape& S,
147                                                  const Standard_Real aMaxTol)
148 {
149   Standard_Integer i, aNbFaces, j, aNbEdges;
150   TopTools_IndexedMapOfShape Faces;
151   TopExp::MapShapes (S, TopAbs_FACE, Faces);
152   
153   aNbFaces=Faces.Extent();
154   for (i=1; i<=aNbFaces; i++) {
155     const TopoDS_Face& F= TopoDS::Face(Faces(i));
156     //
157     CorrectWires(F);
158     //
159     TopTools_IndexedMapOfShape Edges;
160     TopExp::MapShapes (F, TopAbs_EDGE, Edges);
161     aNbEdges=Edges.Extent();
162     for (j=1; j<=aNbEdges; j++) {
163       const TopoDS_Edge& E= TopoDS::Edge(Edges(j));
164       CorrectEdgeTolerance (E, F, aMaxTol);
165     }
166   }
167 }
168 //=======================================================================
169 // Function : CorrectWires
170 // purpose : 
171 //=======================================================================
172 void CorrectWires(const TopoDS_Face& aFx)
173 {
174   Standard_Integer i, aNbV;
175   Standard_Real aTol, aTol2, aD2, aD2max, aT1, aT2, aT, aTol2d; 
176   gp_Pnt aP, aPV;
177   gp_Pnt2d aP2D;
178   TopoDS_Face aF;
179   BRep_Builder aBB;
180   TopTools_IndexedDataMapOfShapeListOfShape aMVE;
181   TopTools_ListIteratorOfListOfShape aIt, aIt1;
182   //
183   aF=aFx;
184   aF.Orientation(TopAbs_FORWARD);
185   aTol2d = Precision::Confusion();
186   const Handle(Geom_Surface)& aS=BRep_Tool::Surface(aFx);
187   //
188   TopExp::MapShapesAndAncestors(aF, TopAbs_VERTEX, TopAbs_EDGE, aMVE);
189   aNbV=aMVE.Extent();
190   for (i=1; i<=aNbV; ++i) {
191     const TopoDS_Vertex& aV=TopoDS::Vertex(aMVE.FindKey(i));
192     aPV=BRep_Tool::Pnt(aV);
193     aTol=BRep_Tool::Tolerance(aV);
194     aTol2=aTol*aTol;
195     //
196     aD2max=-1.;
197     const TopTools_ListOfShape& aLE=aMVE.FindFromIndex(i);
198     aIt.Initialize(aLE);
199     for (; aIt.More(); aIt.Next()) {
200       const TopoDS_Edge& aE=*(TopoDS_Edge*)(&aIt.Value());
201       aT=BRep_Tool::Parameter(aV, aE);
202       const Handle(Geom2d_Curve)& aC2D=BRep_Tool::CurveOnSurface(aE, aF, aT1, aT2);
203       aC2D->D0(aT, aP2D);
204       aS->D0(aP2D.X(), aP2D.Y(), aP);
205       aD2=aPV.SquareDistance(aP);
206       if (aD2>aD2max) {
207         aD2max=aD2;
208       }
209       //check self interference
210       if (aNbV == 2) {
211         continue;
212       }
213       aIt1 = aIt;
214       aIt1.Next();
215       for (; aIt1.More(); aIt1.Next()) {
216         const TopoDS_Edge& aE1=*(TopoDS_Edge*)(&aIt1.Value());
217         //do not perform check for edges that have two common vertices
218         {
219           TopoDS_Vertex aV11, aV12, aV21, aV22;
220           TopExp::Vertices(aE, aV11, aV12);
221           TopExp::Vertices(aE1, aV21, aV22);
222           if ((aV11.IsSame(aV21) && aV12.IsSame(aV22)) ||
223               (aV12.IsSame(aV21) && aV11.IsSame(aV22))) {
224             continue;
225           }
226         }
227         aD2 = IntersectCurves2d(aPV, aF, aE, aE1);
228         if (aD2>aD2max) {
229           aD2max=aD2;
230         }
231       }
232     }
233     if (aD2max>aTol2) {
234       aTol=sqrt(aD2max);
235       aBB.UpdateVertex(aV, aTol);
236     }
237   }
238 }
239 //=======================================================================
240 // Function : IntersectCurves2d
241 // purpose  : Intersect 2d curves of edges
242 //=======================================================================
243 Standard_Real IntersectCurves2d(const gp_Pnt& aPV,
244                                 const TopoDS_Face& aF,
245                                 const TopoDS_Edge& aE1,
246                                 const TopoDS_Edge& aE2)
247 {
248   const Handle(Geom_Surface)& aS=BRep_Tool::Surface(aF);
249   GeomAdaptor_Surface aGAS (aS);
250   if (aGAS.IsUPeriodic() || aGAS.IsVPeriodic()) {
251     return 0;
252   }
253   //
254   Standard_Real aDist, aD, aT11, aT12, aT21, aT22, aTol2d;
255   Standard_Integer j, aNbPnt;
256   Geom2dInt_GInter aInter;
257   gp_Pnt aP;
258   gp_Pnt2d aP2D;
259   //
260   aDist = 0.;
261   aTol2d = Precision::Confusion();
262   //
263   const Handle(Geom2d_Curve)& aC2D1=BRep_Tool::CurveOnSurface(aE1, aF, aT11, aT12);
264   const Handle(Geom2d_Curve)& aC2D2=BRep_Tool::CurveOnSurface(aE2, aF, aT21, aT22);
265   //
266   Geom2dAdaptor_Curve aGAC1(aC2D1), aGAC2(aC2D2);
267   IntRes2d_Domain aDom1(aC2D1->Value(aT11), aT11, aTol2d, aC2D1->Value(aT12), aT12, aTol2d),
268                   aDom2(aC2D2->Value(aT21), aT21, aTol2d, aC2D2->Value(aT22), aT22, aTol2d);
269   //
270   aInter.Perform(aGAC1, aDom1, aGAC2, aDom2, aTol2d, aTol2d);
271   if (aInter.IsDone()) {
272     if (aInter.NbSegments()) {
273       return aDist;
274     }
275     aNbPnt = aInter.NbPoints();
276     if (aNbPnt) {
277       aDist = Precision::Infinite();
278       for (j = 1; j <= aNbPnt; ++j) {
279         aP2D = aInter.Point(j).Value();
280         aS->D0(aP2D.X(), aP2D.Y(), aP);
281         aD=aPV.SquareDistance(aP);
282         if (aD < aDist) {
283           aDist = aD;
284         }
285       }
286     }
287   }
288   return aDist;
289 }
290
291 //=======================================================================
292 // Function : CorrectEdgeTolerance
293 // purpose :  Correct tolerances for Edge 
294 //=======================================================================
295 void CorrectEdgeTolerance (const TopoDS_Edge& myShape, 
296                            const TopoDS_Face& S,
297                            const Standard_Real aMaxTol)
298 {
299   // 
300   // 1. Minimum of conditions to Perform
301   Handle (BRep_CurveRepresentation) myCref;
302   Handle (Adaptor3d_HCurve) myHCurve;
303
304   myCref.Nullify();
305
306   Handle(BRep_TEdge)& TEx = *((Handle(BRep_TEdge)*)&myShape.TShape());
307   BRep_ListIteratorOfListOfCurveRepresentation itcrx(TEx->Curves());
308   Standard_Boolean Degenerated, SameParameterx, SameRangex;
309
310   Standard_Integer unique = 0;
311
312   Degenerated    = TEx->Degenerated();
313   SameParameterx = TEx->SameParameter();
314   SameRangex     = TEx->SameRange();
315   
316   if (!SameRangex && SameParameterx) {
317     return;
318   }
319
320   Handle(Geom_Curve) C3d;
321   while (itcrx.More()) {
322     const Handle(BRep_CurveRepresentation)& cr = itcrx.Value();
323     if (cr->IsCurve3D()) {
324       unique++;
325       if (myCref.IsNull() && !cr->Curve3D().IsNull()) {
326         myCref = cr;
327       }
328     }
329     itcrx.Next();
330   }
331   
332   if (unique==0) {
333     return;//...No3DCurve
334   }
335   if (unique>1) {
336     return;//...Multiple3DCurve;
337   }
338
339   if (myCref.IsNull() && !Degenerated) {
340     itcrx.Initialize(TEx->Curves());
341     while (itcrx.More()) {
342       const Handle(BRep_CurveRepresentation)& cr = itcrx.Value();
343       if (cr->IsCurveOnSurface()) {
344         myCref = cr;
345         break;
346       }
347       itcrx.Next();
348     }
349   }
350   
351   else if (!myCref.IsNull() && Degenerated){
352     return ;//...InvalidDegeneratedFlag;
353   }
354   
355   if (!myCref.IsNull()) {
356     const Handle(BRep_GCurve)& GCref = *((Handle(BRep_GCurve)*)&myCref);
357     Standard_Real First,Last;
358     GCref->Range(First,Last);
359     if (Last<=First) {
360       myCref.Nullify();
361       return ;//InvalidRange;
362     }
363     
364     else {
365       if (myCref->IsCurve3D()) {
366         Handle(Geom_Curve) C3dx = Handle(Geom_Curve)::DownCast
367           (myCref->Curve3D()->Transformed (myCref->Location().Transformation()));
368         GeomAdaptor_Curve GAC3d(C3dx, First, Last);
369         myHCurve = new GeomAdaptor_HCurve(GAC3d);
370       }
371       else { // curve on surface
372         Handle(Geom_Surface) Sref = myCref->Surface();
373         Sref = Handle(Geom_Surface)::DownCast(Sref->Transformed(myCref->Location().Transformation()));
374         const  Handle(Geom2d_Curve)& PCref = myCref->PCurve();
375         Handle(GeomAdaptor_HSurface) GAHSref = new GeomAdaptor_HSurface(Sref);
376         Handle(Geom2dAdaptor_HCurve) GHPCref = new Geom2dAdaptor_HCurve(PCref, First, Last);
377         Adaptor3d_CurveOnSurface ACSref(GHPCref,GAHSref);
378         myHCurve = new Adaptor3d_HCurveOnSurface(ACSref);
379       }
380     }
381   }
382
383   //=============================================== 
384   // 2. Tolerances in InContext
385   {
386     if (myCref.IsNull()) 
387       return;
388     Standard_Boolean ok=Standard_True;;
389
390     Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*)&myShape.TShape());
391     Standard_Real Tol = BRep_Tool::Tolerance(TopoDS::Edge(myShape));
392     Standard_Real aNewTol=Tol;
393
394     Standard_Boolean SameParameter = TE->SameParameter();
395     Standard_Boolean SameRange = TE->SameRange();
396     Standard_Real First = myHCurve->FirstParameter();
397     Standard_Real Last  = myHCurve->LastParameter();
398     Standard_Real Delta =1.e-12;
399
400     Handle(BRep_TFace)& TF = *((Handle(BRep_TFace)*) &S.TShape());
401     const TopLoc_Location& Floc = S.Location();
402     const TopLoc_Location& TFloc = TF->Location();
403     const Handle(Geom_Surface)& Su = TF->Surface();
404     TopLoc_Location L = (Floc * TFloc).Predivided(myShape.Location());
405     Standard_Boolean pcurvefound = Standard_False;
406
407     BRep_ListIteratorOfListOfCurveRepresentation itcr(TE->Curves());
408     while (itcr.More()) {
409       const Handle(BRep_CurveRepresentation)& cr = itcr.Value();
410       if (cr != myCref && cr->IsCurveOnSurface(Su,L)) {
411         pcurvefound = Standard_True;
412         const Handle(BRep_GCurve)& GC = *((Handle(BRep_GCurve)*)&cr);
413         Standard_Real f,l;
414         GC->Range(f,l);
415         if (SameRange && (f != First || l != Last)) {
416           return ;//BRepCheck_InvalidSameRangeFlag;
417         }
418         
419         Handle(Geom_Surface) Sb = cr->Surface();
420         Sb = Handle(Geom_Surface)::DownCast (Su->Transformed(L.Transformation()));
421         Handle(Geom2d_Curve) PC = cr->PCurve();
422         Handle(GeomAdaptor_HSurface) GAHS = new GeomAdaptor_HSurface(Sb);
423         Handle(Geom2dAdaptor_HCurve) GHPC = new Geom2dAdaptor_HCurve(PC,f,l);
424         Adaptor3d_CurveOnSurface ACS(GHPC,GAHS);
425         ok = Validate(myHCurve->Curve(), ACS, Tol, SameParameter, aNewTol);
426         if (ok) {
427           if (cr->IsCurveOnClosedSurface()) {
428             //return ;// BRepCheck::Add(lst,BRepCheck_InvalidCurveOnClosedSurface);
429           }
430           else {
431             //return;//BRepCheck::Add(lst,BRepCheck_InvalidCurveOnSurface);
432           }
433           if (SameParameter) {
434             //return;//BRepCheck::Add(lst,BRepCheck_InvalidSameParameterFlag);
435           }
436           //
437           if (aNewTol<aMaxTol) {
438             TE->UpdateTolerance(aNewTol+Delta); 
439             //
440             CorrectVertexTolerance(myShape);
441           }
442         }
443         
444         if (cr->IsCurveOnClosedSurface()) {
445           //checkclosed = Standard_True;
446           GHPC->ChangeCurve2d().Load(cr->PCurve2(),f,l); // same bounds
447           ACS.Load(GAHS); // sans doute inutile
448           ACS.Load(GHPC); // meme remarque...
449           ok = Validate(myHCurve->Curve(),ACS,Tol,SameParameter, aNewTol);
450           if (ok) {
451             //return;//BRepCheck::Add(lst,BRepCheck_InvalidCurveOnClosedSurface);
452             if (SameParameter) {
453               //return;//BRepCheck::Add(lst,BRepCheck_InvalidSameParameterFlag);
454             }
455             if (aNewTol<aMaxTol) {
456               TE->UpdateTolerance(aNewTol+Delta);
457               CorrectVertexTolerance(myShape);
458             } 
459           }
460         }
461       }
462       itcr.Next();
463     }
464     
465     if (!pcurvefound) {
466       Handle(Geom_Plane) P;
467       Handle(Standard_Type) styp = Su->DynamicType();
468       if (styp == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
469         P = Handle(Geom_Plane)::DownCast(Handle(Geom_RectangularTrimmedSurface)::
470                                          DownCast(Su)->BasisSurface());
471       }
472       else {
473         P = Handle(Geom_Plane)::DownCast(Su);
474       }
475       if (P.IsNull()) { // not a plane
476         return;//BRepCheck::Add(lst,BRepCheck_NoCurveOnSurface);
477       }
478       
479       else {// on fait la projection a la volee, comme BRep_Tool
480         P = Handle(Geom_Plane)::DownCast(P->Transformed(L.Transformation()));
481         //on projette Cref sur ce plan
482         Handle(GeomAdaptor_HSurface) GAHS = new GeomAdaptor_HSurface(P);
483         
484         // Dub - Normalement myHCurve est une GeomAdaptor_HCurve
485         GeomAdaptor_Curve& Gac = Handle(GeomAdaptor_HCurve)::DownCast(myHCurve)->ChangeCurve();
486         Handle(Geom_Curve) C3dx = Gac.Curve();
487         Handle(Geom_Curve) ProjOnPlane = GeomProjLib::ProjectOnPlane
488           (new Geom_TrimmedCurve(C3dx,First,Last), P, P->Position().Direction(), Standard_True);
489         
490         Handle(GeomAdaptor_HCurve) aHCurve = new GeomAdaptor_HCurve(ProjOnPlane);
491         
492         ProjLib_ProjectedCurve proj(GAHS,aHCurve);
493         Handle(Geom2d_Curve) PC = Geom2dAdaptor::MakeCurve(proj);
494         Handle(Geom2dAdaptor_HCurve) GHPC = 
495           new Geom2dAdaptor_HCurve(PC, myHCurve->FirstParameter(), myHCurve->LastParameter());
496         
497         Adaptor3d_CurveOnSurface ACS(GHPC,GAHS);
498         
499         Standard_Boolean okx = Validate(myHCurve->Curve(),ACS,
500                                         Tol,Standard_True, aNewTol); // voir dub...
501         if (okx) {
502           //return;//BRepCheck::Add(lst,BRepCheck_InvalidCurveOnSurface);
503           if (aNewTol<aMaxTol) {
504             TE->UpdateTolerance(aNewTol+Delta);
505             CorrectVertexTolerance(myShape);
506           }
507         }
508       }
509       
510     }//end of if (!pcurvefound) {
511   } // end of  2. Tolerances in InContext
512
513 }
514
515 //=======================================================================
516 // Function : CorrectShapeTolerances
517 // purpose : 
518 //=======================================================================
519   void BOPTools_AlgoTools::CorrectShapeTolerances(const TopoDS_Shape& aShape)
520 {
521   TopExp_Explorer aExp;
522   Standard_Integer aDim;
523   //
524   aDim=Dimension(aShape);
525   if (aDim == 1) {
526     aExp.Init(aShape, TopAbs_EDGE);
527     for (; aExp.More(); aExp.Next()) {
528       const TopoDS_Edge& aE = *(TopoDS_Edge*)&aExp.Current();
529       UpdateVertices(aE);
530     }
531   } else {
532     aExp.Init(aShape, TopAbs_FACE);
533     for (; aExp.More(); aExp.Next()) {
534       const TopoDS_Face& aF = *(TopoDS_Face*)&aExp.Current();
535       UpdateEdges(aF);
536     }
537   }
538 }
539
540 //=======================================================================
541 //function : CorrectVertexTolerance
542 //purpose  : 
543 //=======================================================================
544 void CorrectVertexTolerance(const TopoDS_Edge& aE)
545 {
546   Standard_Integer k, aNbV;
547   Standard_Real aTolE, aTolV;
548   TopTools_IndexedMapOfShape aVMap;
549   
550   aTolE=BRep_Tool::Tolerance(aE);
551   
552   TopExp::MapShapes(aE, TopAbs_VERTEX, aVMap);
553   aNbV=aVMap.Extent();
554   for (k=1; k<=aNbV; ++k) {
555     const TopoDS_Vertex& aV=TopoDS::Vertex(aVMap(k));
556     aTolV=BRep_Tool::Tolerance(aV);
557     if (aTolV<aTolE) {
558       Handle(BRep_TVertex)& aTV = *((Handle(BRep_TVertex)*)&aV.TShape());
559       aTV->UpdateTolerance(aTolE);
560     }
561   }
562 }
563
564 #define NCONTROL 23
565 //=======================================================================
566 //function : Validate
567 //purpose  : 
568 //=======================================================================
569 Standard_Boolean Validate(const Adaptor3d_Curve& CRef,
570                           const Adaptor3d_Curve& Other,
571                           const Standard_Real Tol,
572                           const Standard_Boolean SameParameter,
573                           Standard_Real& aNewTolerance)
574 {
575   Standard_Real First, Last, MaxDistance, aD, Tol2;
576
577   First = CRef.FirstParameter();
578   Last  = CRef.LastParameter();
579   MaxDistance = 0.;
580   Tol2 = Tol*Tol;
581
582   Standard_Integer i, aNC1=NCONTROL-1;
583
584   Standard_Boolean aFlag=Standard_False;
585   Standard_Boolean proj = (!SameParameter || 
586                            First != Other.FirstParameter() ||
587                            Last  != Other.LastParameter());
588   //
589   // 1. 
590   if (!proj) {
591     for (i = 0; i < NCONTROL; i++) {
592       Standard_Real prm = ((aNC1-i)*First + i*Last)/aNC1;
593       gp_Pnt pref   = CRef.Value(prm);
594       gp_Pnt pother = Other.Value(prm);
595       
596       aD=pref.SquareDistance(pother);
597
598       if (aD > Tol2) {
599         if (aD>MaxDistance) {
600           MaxDistance=aD;
601         }
602         aFlag=Standard_True;
603       }
604     }
605
606     if (aFlag) {
607       aNewTolerance=sqrt(MaxDistance);
608     }
609     return aFlag;
610   }
611   
612   //
613   // 2.
614   else {
615     Extrema_LocateExtPC refd,otherd;
616     Standard_Real OFirst, OLast;
617     OFirst = Other.FirstParameter();
618     OLast  = Other.LastParameter();
619     
620     gp_Pnt pd  = CRef.Value(First);
621     gp_Pnt pdo = Other.Value(OFirst);
622     
623     aD = pd.SquareDistance(pdo);
624     if (aD > Tol2) {
625       if (aD>MaxDistance) {
626         MaxDistance=aD;
627       }
628       aFlag=Standard_True;
629     }
630
631     pd  = CRef.Value(Last);
632     pdo = Other.Value(OLast);
633     aD = pd.SquareDistance(pdo);
634     if (aD > Tol2 && aD > MaxDistance) {
635       MaxDistance=aD;
636       aFlag=Standard_True;
637     }
638
639     refd.Initialize(CRef, First, Last, CRef.Resolution(Tol));
640     otherd.Initialize(Other, OFirst, OLast, Other.Resolution(Tol));
641     
642     for (i = 2; i< aNC1; i++) {
643       Standard_Real rprm = ((aNC1-i)*First + i*Last)/aNC1;
644       gp_Pnt pref = CRef.Value(rprm);
645
646       Standard_Real oprm = ((aNC1-i)*OFirst + i*OLast)/aNC1;
647       gp_Pnt pother = Other.Value(oprm);
648
649       refd.Perform(pother,rprm);
650       if (!refd.IsDone() || refd.SquareDistance() > Tol2) {
651         if (refd.IsDone()) {
652           aD=refd.SquareDistance();
653           if (aD > Tol2 && aD>MaxDistance) {
654             aFlag=Standard_True;
655             MaxDistance=aD;
656           }
657         }
658       }
659
660       otherd.Perform(pref,oprm);
661       if (!otherd.IsDone() || otherd.SquareDistance() > Tol2) {
662         
663         if (otherd.IsDone()) {
664           aD=otherd.SquareDistance();
665           if (aD > Tol2 && aD>MaxDistance) {
666             aFlag=Standard_True;
667             MaxDistance=aD;
668           }
669         }
670       }
671     }
672   }
673   
674   aD=sqrt (MaxDistance);
675   aNewTolerance=aD;
676
677   return aFlag;
678   
679 }
680
681 //=======================================================================
682 // Function : CheckEdge
683 // purpose :  Correct tolerances for Vertices on Edge 
684 //=======================================================================
685 void CheckEdge (const TopoDS_Edge& Ed, const Standard_Real aMaxTol)
686 {
687   TopoDS_Edge E=Ed;
688   E.Orientation(TopAbs_FORWARD);
689
690   gp_Pnt Controlp;
691   
692   TopExp_Explorer aVExp;
693   aVExp.Init(E, TopAbs_VERTEX);
694   for (; aVExp.More(); aVExp.Next()) {
695     TopoDS_Vertex aVertex= TopoDS::Vertex(aVExp.Current());
696
697     Handle(BRep_TVertex)& TV = *((Handle(BRep_TVertex)*) &aVertex.TShape());
698     const gp_Pnt& prep = TV->Pnt();
699
700     Standard_Real Tol, aD2, aNewTolerance, dd;
701
702     Tol =BRep_Tool::Tolerance(aVertex);
703     Tol = Max(Tol, BRep_Tool::Tolerance(E));
704     dd=0.1*Tol;
705     Tol*=Tol;
706
707     const TopLoc_Location& Eloc = E.Location();
708     BRep_ListIteratorOfListOfPointRepresentation itpr;
709     
710     Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*)&E.TShape());
711     BRep_ListIteratorOfListOfCurveRepresentation itcr(TE->Curves());
712     while (itcr.More()) {
713       const Handle(BRep_CurveRepresentation)& cr = itcr.Value();
714       const TopLoc_Location& loc = cr->Location();
715       TopLoc_Location L = (Eloc * loc).Predivided(aVertex.Location());
716       
717       if (cr->IsCurve3D()) {
718         const Handle(Geom_Curve)& C = cr->Curve3D();
719         if (!C.IsNull()) {
720           itpr.Initialize(TV->Points());
721           while (itpr.More()) {
722             const Handle(BRep_PointRepresentation)& pr = itpr.Value();
723             if (pr->IsPointOnCurve(C,L)) {
724               Controlp = C->Value(pr->Parameter());
725               Controlp.Transform(L.Transformation());
726               aD2=prep.SquareDistance(Controlp);
727               if (aD2 > Tol) {
728                 aNewTolerance=sqrt(aD2)+dd;
729                 if (aNewTolerance<aMaxTol)
730                   TV->UpdateTolerance(aNewTolerance);
731               }
732             }
733             itpr.Next();
734           }
735           
736           TopAbs_Orientation orv = aVertex.Orientation();
737           if (orv == TopAbs_FORWARD || orv == TopAbs_REVERSED) {
738             const Handle(BRep_GCurve)& GC = *((Handle(BRep_GCurve)*)&cr);
739             
740             if (orv==TopAbs_FORWARD)
741               Controlp = C->Value(GC->First());
742             else 
743               Controlp = C->Value(GC->Last());
744             
745             Controlp.Transform(L.Transformation());
746             aD2=prep.SquareDistance(Controlp);
747             
748             if (aD2 > Tol) {
749               aNewTolerance=sqrt(aD2)+dd;
750               if (aNewTolerance<aMaxTol)
751                 TV->UpdateTolerance(aNewTolerance);
752             }
753           }
754         }
755       }
756       itcr.Next();
757     }
758   }
759 }
760
761 //=======================================================================
762 // Function : UpdateVertices
763 // purpose : 
764 //=======================================================================
765   void UpdateVertices(const TopoDS_Edge& aE)
766 {
767   Standard_Real aTolE, aTolV;
768   TopoDS_Iterator aItE;
769   BRep_Builder aBB;
770   //
771   aTolE = BRep_Tool::Tolerance(aE);
772   aItE.Initialize(aE);
773   for (; aItE.More(); aItE.Next()) {
774     const TopoDS_Vertex& aV = *(TopoDS_Vertex*)&aItE.Value();
775     aTolV = BRep_Tool::Tolerance(aV);
776     if (aTolV < aTolE) {
777       aBB.UpdateVertex(aV, aTolE);
778     }
779   }
780 }
781 //=======================================================================
782 // Function : UpdateEdges
783 // purpose : 
784 //=======================================================================
785   void UpdateEdges(const TopoDS_Face& aF)
786 {
787   Standard_Real aTolF, aTolE, aTolV;
788   TopoDS_Iterator aItF, aItW, aItE;
789   BRep_Builder aBB;
790   //
791   aTolE = aTolF = BRep_Tool::Tolerance(aF);
792   aItF.Initialize(aF);
793   for (; aItF.More(); aItF.Next()) {
794     const TopoDS_Shape& aS = aItF.Value();
795     if (aS.ShapeType()==TopAbs_WIRE) {
796       aItW.Initialize(aS);
797       for (; aItW.More(); aItW.Next()) {
798         const TopoDS_Edge& aE = *(TopoDS_Edge*)&aItW.Value();
799         aTolE = BRep_Tool::Tolerance(aE);
800         if (aTolE < aTolF) {
801           aBB.UpdateEdge(aE, aTolF);
802           aTolE = aTolF;
803         }
804         UpdateVertices(aE);
805       }
806     }
807     else {
808       const TopoDS_Vertex& aV = *(TopoDS_Vertex*)&aItF.Value();
809       aTolV = BRep_Tool::Tolerance(aV);
810       if (aTolV < aTolE) {
811         aBB.UpdateVertex(aV, aTolF);
812       }
813     }
814   }
815 }