0026937: Eliminate NO_CXX_EXCEPTION macro support
[occt.git] / src / TopOpeBRepTool / TopOpeBRepTool_ShapeTool.cxx
1 // Created on: 1994-02-09
2 // Created by: Jean Yves LEBEY
3 // Copyright (c) 1994-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17
18 #include <BRep_Tool.hxx>
19 #include <BRepAdaptor_Curve.hxx>
20 #include <BRepAdaptor_Surface.hxx>
21 #include <BRepLProp_CLProps.hxx>
22 #include <BRepTools.hxx>
23 #include <ElCLib.hxx>
24 #include <Geom2d_Curve.hxx>
25 #include <Geom2d_Line.hxx>
26 #include <Geom_Curve.hxx>
27 #include <Geom_Surface.hxx>
28 #include <GeomAdaptor_Surface.hxx>
29 #include <gp_Dir.hxx>
30 #include <gp_Dir2d.hxx>
31 #include <gp_Pnt.hxx>
32 #include <Precision.hxx>
33 #include <Standard_ProgramError.hxx>
34 #include <TopAbs.hxx>
35 #include <TopExp_Explorer.hxx>
36 #include <TopLoc_Location.hxx>
37 #include <TopoDS.hxx>
38 #include <TopoDS_Edge.hxx>
39 #include <TopoDS_Face.hxx>
40 #include <TopoDS_Shape.hxx>
41 #include <TopOpeBRepTool_2d.hxx>
42 #include <TopOpeBRepTool_EXPORT.hxx>
43 #include <TopOpeBRepTool_ShapeTool.hxx>
44
45 //=======================================================================
46 //function : Tolerance
47 //purpose  : 
48 //=======================================================================
49 Standard_Real TopOpeBRepTool_ShapeTool::Tolerance(const TopoDS_Shape& S)
50 {
51   if ( S.IsNull() ) return 0. ;
52   Standard_Real tol=0;
53   switch (S.ShapeType()) {
54     case TopAbs_FACE   : tol = BRep_Tool::Tolerance(TopoDS::Face(S)); break;
55     case TopAbs_EDGE   : tol = BRep_Tool::Tolerance(TopoDS::Edge(S)); break;
56     case TopAbs_VERTEX : tol = BRep_Tool::Tolerance(TopoDS::Vertex(S)); break;
57     default : throw Standard_ProgramError("TopOpeBRepTool_ShapeTool : Shape has no tolerance"); break;
58   }
59   return tol;
60 }
61
62
63 //=======================================================================
64 //function : Pnt
65 //purpose  : 
66 //=======================================================================
67
68 gp_Pnt TopOpeBRepTool_ShapeTool::Pnt(const TopoDS_Shape& S)
69 {
70   if ( S.ShapeType() != TopAbs_VERTEX ) {
71     throw Standard_ProgramError("TopOpeBRepTool_ShapeTool::Pnt");
72   }
73   return BRep_Tool::Pnt(TopoDS::Vertex(S));
74 }
75
76
77 #include <Geom_OffsetCurve.hxx>
78 #include <Geom_TrimmedCurve.hxx>
79
80 //=======================================================================
81 //function : BASISCURVE
82 //purpose  : 
83 //=======================================================================
84 Handle(Geom_Curve) TopOpeBRepTool_ShapeTool::BASISCURVE(const Handle(Geom_Curve)& C)
85 {
86   Handle(Standard_Type) T = C->DynamicType();
87   if      ( T == STANDARD_TYPE(Geom_OffsetCurve) ) 
88     return BASISCURVE(Handle(Geom_OffsetCurve)::DownCast(C)->BasisCurve());
89   else if ( T == STANDARD_TYPE(Geom_TrimmedCurve) )
90     return BASISCURVE(Handle(Geom_TrimmedCurve)::DownCast(C)->BasisCurve());
91   else return C;
92 }
93
94 Handle(Geom_Curve) TopOpeBRepTool_ShapeTool::BASISCURVE(const TopoDS_Edge& E)
95 {
96   Standard_Real f, l;
97   Handle(Geom_Curve) C = BRep_Tool::Curve(E, f, l);
98   if ( C.IsNull() ) return C;
99   return BASISCURVE(C);
100 }
101
102 #include <Geom_OffsetSurface.hxx>
103 #include <Geom_RectangularTrimmedSurface.hxx>
104 #include <Geom_SurfaceOfRevolution.hxx>
105 #include <Geom_SurfaceOfLinearExtrusion.hxx>
106
107
108 //=======================================================================
109 //function : BASISSURFACE
110 //purpose  : 
111 //=======================================================================
112 Handle(Geom_Surface) TopOpeBRepTool_ShapeTool::BASISSURFACE(const Handle(Geom_Surface)& S)
113 {
114   Handle(Standard_Type) T = S->DynamicType();
115   if      ( T == STANDARD_TYPE(Geom_OffsetSurface) ) 
116     return BASISSURFACE(Handle(Geom_OffsetSurface)::DownCast(S)->BasisSurface());
117   else if ( T == STANDARD_TYPE(Geom_RectangularTrimmedSurface) )
118     return BASISSURFACE(Handle(Geom_RectangularTrimmedSurface)::DownCast(S)->BasisSurface());
119   else return S;
120 }
121
122 Handle(Geom_Surface) TopOpeBRepTool_ShapeTool::BASISSURFACE(const TopoDS_Face& F)
123 {
124   TopLoc_Location L;Handle(Geom_Surface) S = BRep_Tool::Surface(F,L);
125   return BASISSURFACE(S);
126 }
127
128 //=======================================================================
129 //function : UVBOUNDS
130 //purpose  : 
131 //=======================================================================
132 void TopOpeBRepTool_ShapeTool::UVBOUNDS
133 (const Handle(Geom_Surface)& S,
134  Standard_Boolean& UPeriodic,
135  Standard_Boolean& VPeriodic,
136  Standard_Real& Umin, Standard_Real& Umax,
137  Standard_Real& Vmin, Standard_Real& Vmax)
138 {
139   const Handle(Geom_Surface) BS = BASISSURFACE(S);
140   Handle(Standard_Type) T = BS->DynamicType();
141
142   if      ( T == STANDARD_TYPE(Geom_SurfaceOfRevolution) ) {
143     Handle(Geom_SurfaceOfRevolution) 
144       SR = Handle(Geom_SurfaceOfRevolution)::DownCast(BS);
145     Handle(Geom_Curve) C = BASISCURVE(SR->BasisCurve());
146     if (C->IsPeriodic()) {
147       UPeriodic = Standard_False; 
148       VPeriodic = Standard_True; 
149       Vmin = C->FirstParameter(); Vmax = C->LastParameter();
150     }
151   }
152   else if ( T == STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion) ) {
153     Handle(Geom_SurfaceOfLinearExtrusion)
154       SE = Handle(Geom_SurfaceOfLinearExtrusion)::DownCast(BS);
155     Handle(Geom_Curve) C = BASISCURVE(SE->BasisCurve());
156     if (C->IsPeriodic()) {
157       UPeriodic = Standard_True; 
158       Umin = C->FirstParameter(); Umax = C->LastParameter();
159       VPeriodic = Standard_False;
160     }
161   }
162   else { 
163     UPeriodic = BS->IsUPeriodic();
164     VPeriodic = BS->IsVPeriodic();
165     BS->Bounds(Umin,Umax,Vmin,Vmax);
166   }
167 }
168
169 void TopOpeBRepTool_ShapeTool::UVBOUNDS
170 (const TopoDS_Face& F,
171  Standard_Boolean& UPeriodic, Standard_Boolean& VPeriodic,
172  Standard_Real& Umin, Standard_Real& Umax,
173  Standard_Real& Vmin, Standard_Real& Vmax)
174 {
175   TopLoc_Location L;Handle(Geom_Surface) S = BRep_Tool::Surface(F,L);
176   UVBOUNDS(S, UPeriodic, VPeriodic, Umin, Umax, Vmin, Vmax);
177 }
178
179 //=======================================================================
180 //function : AdjustOnPeriodic
181 //purpose  : 
182 //=======================================================================
183
184 void TopOpeBRepTool_ShapeTool::AdjustOnPeriodic(const TopoDS_Shape& F,
185                                                 Standard_Real& u,
186                                                 Standard_Real& v)
187 {
188   TopoDS_Face FF = TopoDS::Face(F);
189   TopLoc_Location Loc;
190   const Handle(Geom_Surface) Surf = BRep_Tool::Surface(FF,Loc);
191   
192 //  Standard_Real Ufirst,Ulast,Vfirst,Vlast;
193   Standard_Boolean isUperio,isVperio;
194   isUperio = Surf->IsUPeriodic();
195   isVperio = Surf->IsVPeriodic();
196
197   // exit if surface supporting F is not periodic on U or V
198   if (!isUperio && !isVperio) return;
199
200   Standard_Real UFfirst,UFlast,VFfirst,VFlast;
201   BRepTools::UVBounds(FF,UFfirst,UFlast,VFfirst,VFlast);
202
203   Standard_Real tol = Precision::PConfusion();
204
205   if (isUperio) {
206     Standard_Real Uperiod = Surf->UPeriod();
207
208 //    Standard_Real ubid = UFfirst;
209
210 //    ElCLib::AdjustPeriodic(UFfirst,UFfirst + Uperiod,tol,ubid,u);
211     if (Abs(u - UFfirst-Uperiod) > tol)
212       u = ElCLib::InPeriod(u,UFfirst,UFfirst + Uperiod);
213   }
214   if (isVperio) {
215     Standard_Real Vperiod = Surf->VPeriod();
216
217 //    Standard_Real vbid = VFfirst;
218
219 //    ElCLib::AdjustPeriodic(VFfirst,VFfirst + Vperiod,tol,vbid,v);
220     if (Abs(v - VFfirst-Vperiod) > tol)
221       v = ElCLib::InPeriod(v,VFfirst,VFfirst + Vperiod);
222   }
223 }
224
225
226 //=======================================================================
227 //function : Closed
228 //purpose  : 
229 //=======================================================================
230
231 Standard_Boolean TopOpeBRepTool_ShapeTool::Closed(const TopoDS_Shape& S1, 
232                                                   const TopoDS_Shape& S2)
233 {
234   const TopoDS_Edge& E = TopoDS::Edge(S1);
235   const TopoDS_Face& F = TopoDS::Face(S2);
236   Standard_Boolean brepclosed = BRep_Tool::IsClosed(E,F);
237   if ( brepclosed ) {
238     Standard_Integer n = 0;
239     for ( TopExp_Explorer x(F,TopAbs_EDGE); x.More(); x.Next() ) 
240       if ( x.Current().IsSame(E) ) n++;
241     if ( n < 2 ) return Standard_False;
242     else return Standard_True;
243   }
244   return Standard_False;
245 }
246
247
248 #ifdef OCCT_DEBUG
249 extern Standard_Boolean TopOpeBRepTool_GettraceVC();
250 extern Standard_Boolean TopOpeBRepTool_GettraceNYI();
251 #endif
252
253
254 inline Standard_Boolean PARINBOUNDS(const Standard_Real par,
255                                     const Standard_Real first,
256                                     const Standard_Real last,
257                                     const Standard_Real tol)
258 {
259   Standard_Boolean b = ( ((first+tol) <= par) && (par <= (last-tol)) );
260   return b;
261 }
262
263 inline Standard_Boolean PARONBOUND(const Standard_Real par,
264                                    const Standard_Real bound,
265                                    const Standard_Real tol)
266 {
267   Standard_Boolean b = ( ((bound-tol) <= par) && (par <= (bound+tol)) );
268   return b;
269 }
270
271
272 Standard_Real ADJUST(const Standard_Real par,
273                      const Standard_Real first,
274                      const Standard_Real last,
275                      const Standard_Real tol)
276 {
277   Standard_Real period = last - first, periopar = par;
278
279   if      (PARINBOUNDS(par,first,last,tol)) {
280     periopar = par + period;
281   }
282   else if (PARONBOUND(par,first,tol)) {
283     periopar = par + period;
284   }
285   else if (PARONBOUND(par,last,tol)) {
286     periopar = par - period;
287   }
288   return periopar;
289 }
290
291
292 //=======================================================================
293 //function : PeriodizeParameter
294 //purpose  : 
295 //=======================================================================
296
297 Standard_Real TopOpeBRepTool_ShapeTool::PeriodizeParameter
298   (const Standard_Real par,
299    const TopoDS_Shape& EE,
300    const TopoDS_Shape& FF)
301 {
302   Standard_Real periopar = par;
303   if ( ! TopOpeBRepTool_ShapeTool::Closed(EE,FF) ) return periopar;
304
305   TopoDS_Edge E = TopoDS::Edge(EE);
306   TopoDS_Face F = TopoDS::Face(FF);
307
308   TopLoc_Location Loc;
309   const Handle(Geom_Surface) Surf = BRep_Tool::Surface(F,Loc);
310   Standard_Boolean isUperio = Surf->IsUPeriodic();
311   Standard_Boolean isVperio = Surf->IsVPeriodic();
312   if (!isUperio && !isVperio) return periopar;
313
314   Standard_Real Ufirst,Ulast,Vfirst,Vlast;
315   Surf->Bounds(Ufirst,Ulast,Vfirst,Vlast);
316
317   Standard_Real first,last,tolpc;
318   const Handle(Geom2d_Curve) PC = FC2D_CurveOnSurface(E,F,first,last,tolpc);
319   if (PC.IsNull()) throw Standard_ProgramError("ShapeTool::PeriodizeParameter : no 2d curve");
320
321   Handle(Standard_Type) TheType = PC->DynamicType();
322   if (TheType == STANDARD_TYPE(Geom2d_Line)) {
323
324     Handle(Geom2d_Line) HL (Handle(Geom2d_Line)::DownCast (PC));
325     const gp_Dir2d&  D = HL->Direction();
326
327     Standard_Real    tol = Precision::Angular();
328     Standard_Boolean isoU = Standard_False, isoV = Standard_False;
329     if      (D.IsParallel(gp_Dir2d(0.,1.),tol)) isoU = Standard_True;
330     else if (D.IsParallel(gp_Dir2d(1.,0.),tol)) isoV = Standard_True;
331     if      (isoU) {
332       periopar = ADJUST(par,Ufirst,Ulast,tol);
333     }
334     else if (isoV) {
335       periopar = ADJUST(par,Vfirst,Vlast,tol);
336     }
337
338 #ifdef OCCT_DEBUG
339     if (TopOpeBRepTool_GettraceVC()) {
340       cout<<"TopOpeBRepTool_ShapeTool PC on edge is ";
341       if      (isoU) cout<<"isoU f,l "<<Ufirst<<" "<<Ulast<<endl;
342       else if (isoV) cout<<"isoV f,l "<<Vfirst<<" "<<Vlast<<endl;
343       else           cout<<"not isoU, not isoV"<<endl;
344       cout<<"par = "<<par<<" --> "<<periopar<<endl;
345     }
346 #endif
347
348   }
349   // NYI : BSpline ... 
350
351   return periopar;
352 }
353
354
355 //=======================================================================
356 //function : ShapesSameOriented
357 //purpose  : 
358 //=======================================================================
359
360 Standard_Boolean TopOpeBRepTool_ShapeTool::ShapesSameOriented
361 (const TopoDS_Shape& S1, const TopoDS_Shape& S2)
362 {
363   Standard_Boolean so = Standard_True;
364
365   Standard_Boolean sam = S1.IsSame(S2);
366   if (sam) {
367     const TopAbs_Orientation o1 = S1.Orientation();
368     const TopAbs_Orientation o2 = S2.Orientation();
369     if ((o1 == TopAbs_FORWARD || o1 == TopAbs_REVERSED) &&
370         (o2 == TopAbs_FORWARD || o2 == TopAbs_REVERSED)) {
371       so = (o1 == o2);
372       return so;
373     }
374   }
375
376   TopAbs_ShapeEnum t1 = S1.ShapeType(), t2 = S2.ShapeType();
377   if      ( (t1 == TopAbs_SOLID) && (t2 == TopAbs_SOLID) ) {
378     so = Standard_True;
379   }
380   else if ( (t1 == TopAbs_FACE) && (t2 == TopAbs_FACE) )  {
381     so = FacesSameOriented(S1,S2);
382   }
383   else if ( (t1 == TopAbs_EDGE) && (t2 == TopAbs_EDGE) )  {
384     so = EdgesSameOriented(S1,S2);
385   }
386   else if ( (t1 == TopAbs_VERTEX) && (t2 == TopAbs_VERTEX) ) {
387     TopAbs_Orientation o1 = S1.Orientation();
388     TopAbs_Orientation o2 = S2.Orientation();
389     if (o1==TopAbs_EXTERNAL||o1==TopAbs_INTERNAL||o2==TopAbs_EXTERNAL||o2==TopAbs_INTERNAL)
390       so = Standard_True;
391     else 
392       so = ( o1 == o2 );
393   }
394
395   return so;
396 }
397
398 //=======================================================================
399 //function : SurfacesSameOriented
400 //purpose  : 
401 //=======================================================================
402
403 Standard_Boolean TopOpeBRepTool_ShapeTool::SurfacesSameOriented
404 (const BRepAdaptor_Surface& S1,const BRepAdaptor_Surface& Sref)
405 {
406   const BRepAdaptor_Surface& S2 = Sref;
407   GeomAbs_SurfaceType ST1 = S1.GetType();
408   GeomAbs_SurfaceType ST2 = S2.GetType();
409
410   Standard_Boolean so = Standard_True;
411
412   if (ST1 == GeomAbs_Plane && ST2 == GeomAbs_Plane) { 
413
414     Standard_Real u1 = S1.FirstUParameter();
415     Standard_Real v1 = S1.FirstVParameter();
416     gp_Pnt p1; gp_Vec d1u,d1v; S1.D1(u1,v1,p1,d1u,d1v); 
417     gp_Vec n1 = d1u.Crossed(d1v);
418     
419     Standard_Real u2 = S2.FirstUParameter();
420     Standard_Real v2 = S2.FirstVParameter();
421     gp_Pnt p2; gp_Vec d2u,d2v; S2.D1(u2,v2,p2,d2u,d2v); 
422     gp_Vec n2 = d2u.Crossed(d2v);
423     
424     Standard_Real d = n1.Dot(n2);
425     so = (d > 0.);
426   }
427   else if (ST1 == GeomAbs_Cylinder && ST2 == GeomAbs_Cylinder) { 
428
429     // On peut projeter n'importe quel point.
430     // prenons donc l'origine
431     Standard_Real u1 = 0.;
432     Standard_Real v1 = 0.;
433     gp_Pnt p1; gp_Vec d1u,d1v; S1.D1(u1,v1,p1,d1u,d1v); 
434     gp_Vec n1 = d1u.Crossed(d1v);
435
436     Handle(Geom_Surface) HS2 = S2.Surface().Surface();
437     HS2 = Handle(Geom_Surface)::DownCast(HS2->Transformed(S2.Trsf()));
438     gp_Pnt2d p22d; Standard_Real dp2;
439     Standard_Boolean ok = FUN_tool_projPonS(p1,HS2,p22d,dp2);
440     if ( !ok ) return so; // NYI : raise
441     
442     Standard_Real u2 = p22d.X();
443     Standard_Real v2 = p22d.Y();
444     gp_Pnt p2; gp_Vec d2u,d2v; S2.D1(u2,v2,p2,d2u,d2v); 
445     gp_Vec n2 = d2u.Crossed(d2v);
446     
447     Standard_Real d = n1.Dot(n2);
448     so = (d > 0.);
449   }
450   else { 
451     // prendre u1,v1 et projeter sur 2 pour calcul des normales
452     // au meme point 3d.
453 #ifdef OCCT_DEBUG
454     if (TopOpeBRepTool_GettraceNYI()) {
455       cout<<"TopOpeBRepTool_ShapeTool::SurfacesSameOriented surfaces non traitees : NYI";
456       cout<<endl;
457     }
458 #endif
459   }
460
461   return so;
462 }
463
464
465 //=======================================================================
466 //function : FacesSameOriented
467 //purpose  : 
468 //=======================================================================
469
470 Standard_Boolean TopOpeBRepTool_ShapeTool::FacesSameOriented
471 (const TopoDS_Shape& S1, const TopoDS_Shape& Sref)
472 {
473   const TopoDS_Shape& S2 = Sref;
474   const TopoDS_Face& F1 = TopoDS::Face(S1);
475   const TopoDS_Face& F2 = TopoDS::Face(S2);
476   TopAbs_Orientation o1 = F1.Orientation();
477   TopAbs_Orientation o2 = F2.Orientation();
478   if ( o1 == TopAbs_EXTERNAL || o1 == TopAbs_INTERNAL ||
479        o2 == TopAbs_EXTERNAL || o2 == TopAbs_INTERNAL ) {
480     return Standard_True;
481   }
482
483   Standard_Boolean computerestriction = Standard_False;
484   BRepAdaptor_Surface BAS1(F1,computerestriction);
485   BRepAdaptor_Surface BAS2(F2,computerestriction);
486   Standard_Boolean so = F1.IsSame(F2) || SurfacesSameOriented(BAS1,BAS2);
487   Standard_Boolean b = so;
488   if ( o1 != o2 ) b = !so; 
489   return b;
490 }
491
492
493 //=======================================================================
494 //function : CurvesSameOriented
495 //purpose  : 
496 //=======================================================================
497
498 Standard_Boolean TopOpeBRepTool_ShapeTool::CurvesSameOriented
499 (const BRepAdaptor_Curve& C1, const BRepAdaptor_Curve& Cref)
500 {
501   const BRepAdaptor_Curve& C2 = Cref;
502   GeomAbs_CurveType CT1 = C1.GetType();
503   GeomAbs_CurveType CT2 = C2.GetType();
504   Standard_Boolean so = Standard_True;
505
506   if (CT1 == GeomAbs_Line && CT2 == GeomAbs_Line) { 
507     Standard_Real p1 = C1.FirstParameter();
508     gp_Dir t1,n1; Standard_Real c1; EdgeData(C1,p1,t1,n1,c1);
509     Standard_Real p2 = C2.FirstParameter();
510     gp_Dir t2,n2; Standard_Real c2; EdgeData(C2,p2,t2,n2,c2);
511     Standard_Real d = t1.Dot(t2);
512     so = (d > 0.);
513   }
514   else { 
515     // prendre p1 et projeter sur 2 pour calcul des normales
516     // au meme point 3d.
517 #ifdef OCCT_DEBUG
518     if (TopOpeBRepTool_GettraceNYI()) { 
519       cout<<"TopOpeBRepTool_ShapeTool::CurvesSameOriented non lineaires : NYI";
520       cout<<endl;
521     }
522 #endif
523   }
524
525   return so;
526 }
527
528 //=======================================================================
529 //function : EdgesSameOriented
530 //purpose  : 
531 //=======================================================================
532
533 Standard_Boolean TopOpeBRepTool_ShapeTool::EdgesSameOriented
534 (const TopoDS_Shape& S1, const TopoDS_Shape& Sref)
535 {
536   const TopoDS_Shape& S2 = Sref;
537   const TopoDS_Edge& E1 = TopoDS::Edge(S1);
538   const TopoDS_Edge& E2 = TopoDS::Edge(S2);
539   TopAbs_Orientation o1 = E1.Orientation();
540   TopAbs_Orientation o2 = E2.Orientation();
541   if ( o1 == TopAbs_EXTERNAL || o1 == TopAbs_INTERNAL ||
542        o2 == TopAbs_EXTERNAL || o2 == TopAbs_INTERNAL ) {
543     return Standard_True;
544   }
545   BRepAdaptor_Curve BAC1(E1);
546   BRepAdaptor_Curve BAC2(E2);
547   Standard_Boolean so = CurvesSameOriented(BAC1,BAC2);
548   Standard_Boolean b = so;
549   if ( o1 != o2 ) b = !so;
550   return b;
551 }
552
553
554 //=======================================================================
555 //function : EdgeData
556 //purpose  : 
557 //=======================================================================
558
559 Standard_Real TopOpeBRepTool_ShapeTool::EdgeData
560 (const BRepAdaptor_Curve& BAC, const Standard_Real P, 
561  gp_Dir& T, gp_Dir& N, Standard_Real& C)
562      
563 {
564   Standard_Real tol = Precision::Angular();
565
566   BRepLProp_CLProps BL(BAC,P,2,tol);
567   BL.Tangent(T);
568   C = BL.Curvature();
569
570   // xpu150399 cto900R4
571   Standard_Real tol1 = Epsilon(0.), tol2 = RealLast();
572   Standard_Real tolm = Max(tol,Max(tol1,tol2));
573
574   if ( Abs(C) > tolm ) BL.Normal(N);
575   return tol;
576 }
577
578
579 //=======================================================================
580 //function : EdgeData
581 //purpose  : 
582 //=======================================================================
583
584 Standard_Real TopOpeBRepTool_ShapeTool::EdgeData
585 (const TopoDS_Shape& E, const Standard_Real P, 
586  gp_Dir& T, gp_Dir& N, Standard_Real& C)
587 {
588   BRepAdaptor_Curve BAC(TopoDS::Edge(E));
589   Standard_Real d = EdgeData(BAC,P,T,N,C);
590   return d;
591 }
592
593
594 //=======================================================================
595 //function : Resolution3dU
596 //purpose  : 
597 //=======================================================================
598
599 Standard_Real TopOpeBRepTool_ShapeTool::Resolution3dU(const Handle(Geom_Surface)& SU,
600                                                       const Standard_Real Tol2d)
601 {
602   GeomAdaptor_Surface GAS(SU);
603   Standard_Real r3dunit = 0.00001;  // petite valeur (1.0 -> RangeError sur un tore)
604   Standard_Real ru = GAS.UResolution(r3dunit);
605   Standard_Real r3du = r3dunit*(Tol2d/ru);
606   return r3du;
607 }
608
609
610 //=======================================================================
611 //function : Resolution3dV
612 //purpose  : 
613 //=======================================================================
614
615 Standard_Real TopOpeBRepTool_ShapeTool::Resolution3dV(const Handle(Geom_Surface)& SU,
616                                                       const Standard_Real Tol2d)
617 {
618   GeomAdaptor_Surface GAS(SU);
619   Standard_Real r3dunit = 0.00001; // petite valeur (1.0 -> RangeError sur un tore)
620   Standard_Real rv = GAS.VResolution(r3dunit);
621   Standard_Real r3dv = r3dunit*(Tol2d/rv);
622   return r3dv;
623 }
624
625
626 //=======================================================================
627 //function : Resolution3d
628 //purpose  : 
629 //=======================================================================
630
631 Standard_Real TopOpeBRepTool_ShapeTool::Resolution3d(const Handle(Geom_Surface)& SU,
632                                                      const Standard_Real Tol2d)
633 {
634   Standard_Real ru = Resolution3dU(SU,Tol2d);
635   Standard_Real rv = Resolution3dV(SU,Tol2d);
636   Standard_Real r = Max(ru,rv);
637   return r;
638 }
639
640
641 //=======================================================================
642 //function : Resolution3d
643 //purpose  : 
644 //=======================================================================
645
646 Standard_Real TopOpeBRepTool_ShapeTool::Resolution3d(const TopoDS_Face& F,
647                                                      const Standard_Real Tol2d)
648 {
649   TopLoc_Location L; const Handle(Geom_Surface)& SU = BRep_Tool::Surface(F,L);
650   Standard_Real r = Resolution3d(SU,Tol2d);
651   return r;
652 }