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