1 // File: TopOpeBRepTool_ShapeTool.cxx
2 // Created: Wed Feb 9 16:24:57 1994
3 // Author: Jean Yves LEBEY
6 #include <TopOpeBRepTool_ShapeTool.ixx>
8 #include <BRep_Tool.hxx>
12 #include <Geom_Surface.hxx>
13 #include <TopLoc_Location.hxx>
14 #include <Precision.hxx>
15 #include <Standard_ProgramError.hxx>
16 #include <Geom2d_Curve.hxx>
17 #include <Geom_Curve.hxx>
18 #include <TopoDS_Edge.hxx>
19 #include <TopoDS_Face.hxx>
21 #include <gp_Dir2d.hxx>
22 #include <Geom2d_Line.hxx>
23 #include <BRepTools.hxx>
24 #include <TopExp_Explorer.hxx>
25 #include <BRepLProp_CLProps.hxx>
26 #include <GeomAdaptor_Surface.hxx>
27 #include <TopOpeBRepTool_EXPORT.hxx>
28 #include <TopOpeBRepTool_2d.hxx>
30 //=======================================================================
31 //function : Tolerance
33 //=======================================================================
35 Standard_Real TopOpeBRepTool_ShapeTool::Tolerance(const TopoDS_Shape& S)
37 if ( S.IsNull() ) return 0. ;
39 switch (S.ShapeType()) {
40 case TopAbs_FACE : tol = BRep_Tool::Tolerance(TopoDS::Face(S)); break;
41 case TopAbs_EDGE : tol = BRep_Tool::Tolerance(TopoDS::Edge(S)); break;
42 case TopAbs_VERTEX : tol = BRep_Tool::Tolerance(TopoDS::Vertex(S)); break;
43 default : Standard_ProgramError::Raise
44 ("TopOpeBRepTool_ShapeTool : Shape has no tolerance"); break;
50 //=======================================================================
53 //=======================================================================
55 gp_Pnt TopOpeBRepTool_ShapeTool::Pnt(const TopoDS_Shape& S)
57 if ( S.ShapeType() != TopAbs_VERTEX ) {
58 Standard_ProgramError::Raise("TopOpeBRepTool_ShapeTool::Pnt");
61 return BRep_Tool::Pnt(TopoDS::Vertex(S));
65 #include <Geom_OffsetCurve.hxx>
66 #include <Geom_TrimmedCurve.hxx>
68 //=======================================================================
69 //function : BASISCURVE
71 //=======================================================================
72 Handle(Geom_Curve) TopOpeBRepTool_ShapeTool::BASISCURVE(const Handle(Geom_Curve)& C)
74 Handle(Standard_Type) T = C->DynamicType();
75 if ( T == STANDARD_TYPE(Geom_OffsetCurve) )
76 return BASISCURVE(Handle(Geom_OffsetCurve)::DownCast(C)->BasisCurve());
77 else if ( T == STANDARD_TYPE(Geom_TrimmedCurve) )
78 return BASISCURVE(Handle(Geom_TrimmedCurve)::DownCast(C)->BasisCurve());
82 Handle(Geom_Curve) TopOpeBRepTool_ShapeTool::BASISCURVE(const TopoDS_Edge& E)
85 Handle(Geom_Curve) C = BRep_Tool::Curve(E, f, l);
86 if ( C.IsNull() ) return C;
90 #include <Geom_OffsetSurface.hxx>
91 #include <Geom_RectangularTrimmedSurface.hxx>
92 #include <Geom_SurfaceOfRevolution.hxx>
93 #include <Geom_SurfaceOfLinearExtrusion.hxx>
96 //=======================================================================
97 //function : BASISSURFACE
99 //=======================================================================
100 Handle(Geom_Surface) TopOpeBRepTool_ShapeTool::BASISSURFACE(const Handle(Geom_Surface)& S)
102 Handle(Standard_Type) T = S->DynamicType();
103 if ( T == STANDARD_TYPE(Geom_OffsetSurface) )
104 return BASISSURFACE(Handle(Geom_OffsetSurface)::DownCast(S)->BasisSurface());
105 else if ( T == STANDARD_TYPE(Geom_RectangularTrimmedSurface) )
106 return BASISSURFACE(Handle(Geom_RectangularTrimmedSurface)::DownCast(S)->BasisSurface());
110 Handle(Geom_Surface) TopOpeBRepTool_ShapeTool::BASISSURFACE(const TopoDS_Face& F)
112 TopLoc_Location L;Handle(Geom_Surface) S = BRep_Tool::Surface(F,L);
113 return BASISSURFACE(S);
116 //=======================================================================
117 //function : UVBOUNDS
119 //=======================================================================
120 void TopOpeBRepTool_ShapeTool::UVBOUNDS
121 (const Handle(Geom_Surface)& S,
122 Standard_Boolean& UPeriodic,
123 Standard_Boolean& VPeriodic,
124 Standard_Real& Umin, Standard_Real& Umax,
125 Standard_Real& Vmin, Standard_Real& Vmax)
127 const Handle(Geom_Surface) BS = BASISSURFACE(S);
128 Handle(Standard_Type) T = BS->DynamicType();
130 if ( T == STANDARD_TYPE(Geom_SurfaceOfRevolution) ) {
131 Handle(Geom_SurfaceOfRevolution)
132 SR = Handle(Geom_SurfaceOfRevolution)::DownCast(BS);
133 Handle(Geom_Curve) C = BASISCURVE(SR->BasisCurve());
134 if (C->IsPeriodic()) {
135 UPeriodic = Standard_False;
136 VPeriodic = Standard_True;
137 Vmin = C->FirstParameter(); Vmax = C->LastParameter();
140 else if ( T == STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion) ) {
141 Handle(Geom_SurfaceOfLinearExtrusion)
142 SE = Handle(Geom_SurfaceOfLinearExtrusion)::DownCast(BS);
143 Handle(Geom_Curve) C = BASISCURVE(SE->BasisCurve());
144 if (C->IsPeriodic()) {
145 UPeriodic = Standard_True;
146 Umin = C->FirstParameter(); Umax = C->LastParameter();
147 VPeriodic = Standard_False;
151 UPeriodic = BS->IsUPeriodic();
152 VPeriodic = BS->IsVPeriodic();
153 BS->Bounds(Umin,Umax,Vmin,Vmax);
157 void TopOpeBRepTool_ShapeTool::UVBOUNDS
158 (const TopoDS_Face& F,
159 Standard_Boolean& UPeriodic, Standard_Boolean& VPeriodic,
160 Standard_Real& Umin, Standard_Real& Umax,
161 Standard_Real& Vmin, Standard_Real& Vmax)
163 TopLoc_Location L;Handle(Geom_Surface) S = BRep_Tool::Surface(F,L);
164 UVBOUNDS(S, UPeriodic, VPeriodic, Umin, Umax, Vmin, Vmax);
167 //=======================================================================
168 //function : AdjustOnPeriodic
170 //=======================================================================
172 void TopOpeBRepTool_ShapeTool::AdjustOnPeriodic(const TopoDS_Shape& F,
176 TopoDS_Face FF = TopoDS::Face(F);
178 const Handle(Geom_Surface) Surf = BRep_Tool::Surface(FF,Loc);
180 // Standard_Real Ufirst,Ulast,Vfirst,Vlast;
181 Standard_Boolean isUperio,isVperio;
182 isUperio = Surf->IsUPeriodic();
183 isVperio = Surf->IsVPeriodic();
185 // exit if surface supporting F is not periodic on U or V
186 if (!isUperio && !isVperio) return;
188 Standard_Real UFfirst,UFlast,VFfirst,VFlast;
189 BRepTools::UVBounds(FF,UFfirst,UFlast,VFfirst,VFlast);
191 Standard_Real tol = Precision::PConfusion();
194 Standard_Real Uperiod = Surf->UPeriod();
196 Standard_Real ubid = UFfirst;
198 // ElCLib::AdjustPeriodic(UFfirst,UFfirst + Uperiod,tol,ubid,u);
199 if (Abs(u - UFfirst-Uperiod) > tol)
200 u = ElCLib::InPeriod(u,UFfirst,UFfirst + Uperiod);
203 Standard_Real Vperiod = Surf->VPeriod();
205 Standard_Real vbid = VFfirst;
207 // ElCLib::AdjustPeriodic(VFfirst,VFfirst + Vperiod,tol,vbid,v);
208 if (Abs(v - VFfirst-Vperiod) > tol)
209 v = ElCLib::InPeriod(v,VFfirst,VFfirst + Vperiod);
214 //=======================================================================
217 //=======================================================================
219 Standard_Boolean TopOpeBRepTool_ShapeTool::Closed(const TopoDS_Shape& S1,
220 const TopoDS_Shape& S2)
222 const TopoDS_Edge& E = TopoDS::Edge(S1);
223 const TopoDS_Face& F = TopoDS::Face(S2);
224 Standard_Boolean brepclosed = BRep_Tool::IsClosed(E,F);
226 Standard_Integer n = 0;
227 for ( TopExp_Explorer x(F,TopAbs_EDGE); x.More(); x.Next() )
228 if ( x.Current().IsSame(E) ) n++;
229 if ( n < 2 ) return Standard_False;
230 else return Standard_True;
232 return Standard_False;
237 Standard_IMPORT Standard_Boolean TopOpeBRepTool_GettraceVC();
238 Standard_IMPORT Standard_Boolean TopOpeBRepTool_GettraceNYI();
242 inline Standard_Boolean PARINBOUNDS(const Standard_Real par,
243 const Standard_Real first,
244 const Standard_Real last,
245 const Standard_Real tol)
247 Standard_Boolean b = ( ((first+tol) <= par) && (par <= (last-tol)) );
251 inline Standard_Boolean PARONBOUND(const Standard_Real par,
252 const Standard_Real bound,
253 const Standard_Real tol)
255 Standard_Boolean b = ( ((bound-tol) <= par) && (par <= (bound+tol)) );
260 Standard_Real ADJUST(const Standard_Real par,
261 const Standard_Real first,
262 const Standard_Real last,
263 const Standard_Real tol)
265 Standard_Real period = last - first, periopar = par;
267 if (PARINBOUNDS(par,first,last,tol)) {
268 periopar = par + period;
270 else if (PARONBOUND(par,first,tol)) {
271 periopar = par + period;
273 else if (PARONBOUND(par,last,tol)) {
274 periopar = par - period;
280 //=======================================================================
281 //function : PeriodizeParameter
283 //=======================================================================
285 Standard_Real TopOpeBRepTool_ShapeTool::PeriodizeParameter
286 (const Standard_Real par,
287 const TopoDS_Shape& EE,
288 const TopoDS_Shape& FF)
290 Standard_Real periopar = par;
291 if ( ! TopOpeBRepTool_ShapeTool::Closed(EE,FF) ) return periopar;
293 TopoDS_Edge E = TopoDS::Edge(EE);
294 TopoDS_Face F = TopoDS::Face(FF);
297 const Handle(Geom_Surface) Surf = BRep_Tool::Surface(F,Loc);
298 Standard_Boolean isUperio = Surf->IsUPeriodic();
299 Standard_Boolean isVperio = Surf->IsVPeriodic();
300 if (!isUperio && !isVperio) return periopar;
302 Standard_Real Ufirst,Ulast,Vfirst,Vlast;
303 Surf->Bounds(Ufirst,Ulast,Vfirst,Vlast);
304 Standard_Real Uperiod = 0., Vperiod = 0.;
305 if (isUperio) Uperiod = Ulast - Ufirst;
306 if (isVperio) Vperiod = Vlast - Vfirst;
308 Standard_Real first,last,tolpc;
309 const Handle(Geom2d_Curve) PC = FC2D_CurveOnSurface(E,F,first,last,tolpc);
310 if (PC.IsNull()) Standard_ProgramError::Raise("ShapeTool::PeriodizeParameter : no 2d curve");
312 Handle(Standard_Type) TheType = PC->DynamicType();
313 if (TheType == STANDARD_TYPE(Geom2d_Line)) {
315 const Handle(Geom2d_Line)& HL = *((Handle(Geom2d_Line)*)&PC);
316 const gp_Dir2d& D = HL->Direction();
318 Standard_Real tol = Precision::Angular();
319 Standard_Boolean isoU = Standard_False, isoV = Standard_False;
320 if (D.IsParallel(gp_Dir2d(0.,1.),tol)) isoU = Standard_True;
321 else if (D.IsParallel(gp_Dir2d(1.,0.),tol)) isoV = Standard_True;
323 periopar = ADJUST(par,Ufirst,Ulast,tol);
326 periopar = ADJUST(par,Vfirst,Vlast,tol);
330 if (TopOpeBRepTool_GettraceVC()) {
331 cout<<"TopOpeBRepTool_ShapeTool PC on edge is ";
332 if (isoU) cout<<"isoU f,l "<<Ufirst<<" "<<Ulast<<endl;
333 else if (isoV) cout<<"isoV f,l "<<Vfirst<<" "<<Vlast<<endl;
334 else cout<<"not isoU, not isoV"<<endl;
335 cout<<"par = "<<par<<" --> "<<periopar<<endl;
346 //=======================================================================
347 //function : ShapesSameOriented
349 //=======================================================================
351 Standard_Boolean TopOpeBRepTool_ShapeTool::ShapesSameOriented
352 (const TopoDS_Shape& S1, const TopoDS_Shape& S2)
354 Standard_Boolean so = Standard_True;
356 Standard_Boolean sam = S1.IsSame(S2);
358 const TopAbs_Orientation o1 = S1.Orientation();
359 const TopAbs_Orientation o2 = S2.Orientation();
360 if ((o1 == TopAbs_FORWARD || o1 == TopAbs_REVERSED) &&
361 (o2 == TopAbs_FORWARD || o2 == TopAbs_REVERSED)) {
367 TopAbs_ShapeEnum t1 = S1.ShapeType(), t2 = S2.ShapeType();
368 if ( (t1 == TopAbs_SOLID) && (t2 == TopAbs_SOLID) ) {
371 else if ( (t1 == TopAbs_FACE) && (t2 == TopAbs_FACE) ) {
372 so = FacesSameOriented(S1,S2);
374 else if ( (t1 == TopAbs_EDGE) && (t2 == TopAbs_EDGE) ) {
375 so = EdgesSameOriented(S1,S2);
377 else if ( (t1 == TopAbs_VERTEX) && (t2 == TopAbs_VERTEX) ) {
378 TopAbs_Orientation o1 = S1.Orientation();
379 TopAbs_Orientation o2 = S2.Orientation();
380 if (o1==TopAbs_EXTERNAL||o1==TopAbs_INTERNAL||o2==TopAbs_EXTERNAL||o2==TopAbs_INTERNAL)
389 //=======================================================================
390 //function : SurfacesSameOriented
392 //=======================================================================
394 Standard_Boolean TopOpeBRepTool_ShapeTool::SurfacesSameOriented
395 (const BRepAdaptor_Surface& S1,const BRepAdaptor_Surface& Sref)
397 const BRepAdaptor_Surface& S2 = Sref;
398 GeomAbs_SurfaceType ST1 = S1.GetType();
399 GeomAbs_SurfaceType ST2 = S2.GetType();
401 Standard_Boolean so = Standard_True;
403 if (ST1 == GeomAbs_Plane && ST2 == GeomAbs_Plane) {
405 Standard_Real u1 = S1.FirstUParameter();
406 Standard_Real v1 = S1.FirstVParameter();
407 gp_Pnt p1; gp_Vec d1u,d1v; S1.D1(u1,v1,p1,d1u,d1v);
408 gp_Vec n1 = d1u.Crossed(d1v);
410 Standard_Real u2 = S2.FirstUParameter();
411 Standard_Real v2 = S2.FirstVParameter();
412 gp_Pnt p2; gp_Vec d2u,d2v; S2.D1(u2,v2,p2,d2u,d2v);
413 gp_Vec n2 = d2u.Crossed(d2v);
415 Standard_Real d = n1.Dot(n2);
418 else if (ST1 == GeomAbs_Cylinder && ST2 == GeomAbs_Cylinder) {
420 // On peut projeter n'importe quel point.
421 // prenons donc l'origine
422 Standard_Real u1 = 0.;
423 Standard_Real v1 = 0.;
424 gp_Pnt p1; gp_Vec d1u,d1v; S1.D1(u1,v1,p1,d1u,d1v);
425 gp_Vec n1 = d1u.Crossed(d1v);
427 Handle(Geom_Surface) HS2 = S2.Surface().Surface();
428 HS2 = Handle(Geom_Surface)::DownCast(HS2->Transformed(S2.Trsf()));
429 gp_Pnt2d p22d; Standard_Real dp2;
430 Standard_Boolean ok = FUN_tool_projPonS(p1,HS2,p22d,dp2);
431 if ( !ok ) return so; // NYI : raise
433 Standard_Real u2 = p22d.X();
434 Standard_Real v2 = p22d.Y();
435 gp_Pnt p2; gp_Vec d2u,d2v; S2.D1(u2,v2,p2,d2u,d2v);
436 gp_Vec n2 = d2u.Crossed(d2v);
438 Standard_Real d = n1.Dot(n2);
442 // prendre u1,v1 et projeter sur 2 pour calcul des normales
445 if (TopOpeBRepTool_GettraceNYI()) {
446 cout<<"TopOpeBRepTool_ShapeTool::SurfacesSameOriented surfaces non traitees : NYI";
456 //=======================================================================
457 //function : FacesSameOriented
459 //=======================================================================
461 Standard_Boolean TopOpeBRepTool_ShapeTool::FacesSameOriented
462 (const TopoDS_Shape& S1, const TopoDS_Shape& Sref)
464 const TopoDS_Shape& S2 = Sref;
465 const TopoDS_Face& F1 = TopoDS::Face(S1);
466 const TopoDS_Face& F2 = TopoDS::Face(S2);
467 TopAbs_Orientation o1 = F1.Orientation();
468 TopAbs_Orientation o2 = F2.Orientation();
469 if ( o1 == TopAbs_EXTERNAL || o1 == TopAbs_INTERNAL ||
470 o2 == TopAbs_EXTERNAL || o2 == TopAbs_INTERNAL ) {
471 return Standard_True;
474 Standard_Boolean computerestriction = Standard_False;
475 BRepAdaptor_Surface BAS1(F1,computerestriction);
476 BRepAdaptor_Surface BAS2(F2,computerestriction);
477 Standard_Boolean so = F1.IsSame(F2) || SurfacesSameOriented(BAS1,BAS2);
478 Standard_Boolean b = so;
479 if ( o1 != o2 ) b = !so;
484 //=======================================================================
485 //function : CurvesSameOriented
487 //=======================================================================
489 Standard_Boolean TopOpeBRepTool_ShapeTool::CurvesSameOriented
490 (const BRepAdaptor_Curve& C1, const BRepAdaptor_Curve& Cref)
492 const BRepAdaptor_Curve& C2 = Cref;
493 GeomAbs_CurveType CT1 = C1.GetType();
494 GeomAbs_CurveType CT2 = C2.GetType();
495 Standard_Boolean so = Standard_True;
497 if (CT1 == GeomAbs_Line && CT2 == GeomAbs_Line) {
498 Standard_Real p1 = C1.FirstParameter();
499 gp_Dir t1,n1; Standard_Real c1; EdgeData(C1,p1,t1,n1,c1);
500 Standard_Real p2 = C2.FirstParameter();
501 gp_Dir t2,n2; Standard_Real c2; EdgeData(C2,p2,t2,n2,c2);
502 Standard_Real d = t1.Dot(t2);
506 // prendre p1 et projeter sur 2 pour calcul des normales
509 if (TopOpeBRepTool_GettraceNYI()) {
510 cout<<"TopOpeBRepTool_ShapeTool::CurvesSameOriented non lineaires : NYI";
519 //=======================================================================
520 //function : EdgesSameOriented
522 //=======================================================================
524 Standard_Boolean TopOpeBRepTool_ShapeTool::EdgesSameOriented
525 (const TopoDS_Shape& S1, const TopoDS_Shape& Sref)
527 const TopoDS_Shape& S2 = Sref;
528 const TopoDS_Edge& E1 = TopoDS::Edge(S1);
529 const TopoDS_Edge& E2 = TopoDS::Edge(S2);
530 TopAbs_Orientation o1 = E1.Orientation();
531 TopAbs_Orientation o2 = E2.Orientation();
532 if ( o1 == TopAbs_EXTERNAL || o1 == TopAbs_INTERNAL ||
533 o2 == TopAbs_EXTERNAL || o2 == TopAbs_INTERNAL ) {
534 return Standard_True;
536 BRepAdaptor_Curve BAC1(E1);
537 BRepAdaptor_Curve BAC2(E2);
538 Standard_Boolean so = CurvesSameOriented(BAC1,BAC2);
539 Standard_Boolean b = so;
540 if ( o1 != o2 ) b = !so;
545 //=======================================================================
546 //function : EdgeData
548 //=======================================================================
550 Standard_Real TopOpeBRepTool_ShapeTool::EdgeData
551 (const BRepAdaptor_Curve& BAC, const Standard_Real P,
552 gp_Dir& T, gp_Dir& N, Standard_Real& C)
555 Standard_Real tol = Precision::Angular();
557 BRepLProp_CLProps BL(BAC,P,2,tol);
561 // xpu150399 cto900R4
562 Standard_Real tol1 = Epsilon(0.), tol2 = RealLast();
563 Standard_Real tolm = Max(tol,Max(tol1,tol2));
565 if ( Abs(C) > tolm ) BL.Normal(N);
570 //=======================================================================
571 //function : EdgeData
573 //=======================================================================
575 Standard_Real TopOpeBRepTool_ShapeTool::EdgeData
576 (const TopoDS_Shape& E, const Standard_Real P,
577 gp_Dir& T, gp_Dir& N, Standard_Real& C)
579 BRepAdaptor_Curve BAC(TopoDS::Edge(E));
580 Standard_Real d = EdgeData(BAC,P,T,N,C);
585 //=======================================================================
586 //function : Resolution3dU
588 //=======================================================================
590 Standard_Real TopOpeBRepTool_ShapeTool::Resolution3dU(const Handle(Geom_Surface)& SU,
591 const Standard_Real Tol2d)
593 GeomAdaptor_Surface GAS(SU);
594 Standard_Real r3dunit = 0.00001; // petite valeur (1.0 -> RangeError sur un tore)
595 Standard_Real ru = GAS.UResolution(r3dunit);
596 Standard_Real r3du = r3dunit*(Tol2d/ru);
601 //=======================================================================
602 //function : Resolution3dV
604 //=======================================================================
606 Standard_Real TopOpeBRepTool_ShapeTool::Resolution3dV(const Handle(Geom_Surface)& SU,
607 const Standard_Real Tol2d)
609 GeomAdaptor_Surface GAS(SU);
610 Standard_Real r3dunit = 0.00001; // petite valeur (1.0 -> RangeError sur un tore)
611 Standard_Real rv = GAS.VResolution(r3dunit);
612 Standard_Real r3dv = r3dunit*(Tol2d/rv);
617 //=======================================================================
618 //function : Resolution3d
620 //=======================================================================
622 Standard_Real TopOpeBRepTool_ShapeTool::Resolution3d(const Handle(Geom_Surface)& SU,
623 const Standard_Real Tol2d)
625 Standard_Real ru = Resolution3dU(SU,Tol2d);
626 Standard_Real rv = Resolution3dV(SU,Tol2d);
627 Standard_Real r = Max(ru,rv);
632 //=======================================================================
633 //function : Resolution3d
635 //=======================================================================
637 Standard_Real TopOpeBRepTool_ShapeTool::Resolution3d(const TopoDS_Face& F,
638 const Standard_Real Tol2d)
640 TopLoc_Location L; const Handle(Geom_Surface)& SU = BRep_Tool::Surface(F,L);
641 Standard_Real r = Resolution3d(SU,Tol2d);