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