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