// Created on: 1994-02-09 // Created by: Jean Yves LEBEY // Copyright (c) 1994-1999 Matra Datavision // Copyright (c) 1999-2014 OPEN CASCADE SAS // // This file is part of Open CASCADE Technology software library. // // This library is free software; you can redistribute it and/or modify it under // the terms of the GNU Lesser General Public License version 2.1 as published // by the Free Software Foundation, with special exception defined in the file // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT // distribution for complete text of the license and disclaimer of any warranty. // // Alternatively, this file may be used under the terms of Open CASCADE // commercial license or contractual agreement. #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include //======================================================================= //function : Tolerance //purpose : //======================================================================= Standard_Real TopOpeBRepTool_ShapeTool::Tolerance(const TopoDS_Shape& S) { if ( S.IsNull() ) return 0. ; Standard_Real tol=0; switch (S.ShapeType()) { case TopAbs_FACE : tol = BRep_Tool::Tolerance(TopoDS::Face(S)); break; case TopAbs_EDGE : tol = BRep_Tool::Tolerance(TopoDS::Edge(S)); break; case TopAbs_VERTEX : tol = BRep_Tool::Tolerance(TopoDS::Vertex(S)); break; default : Standard_ProgramError::Raise ("TopOpeBRepTool_ShapeTool : Shape has no tolerance"); break; } return tol; } //======================================================================= //function : Pnt //purpose : //======================================================================= gp_Pnt TopOpeBRepTool_ShapeTool::Pnt(const TopoDS_Shape& S) { if ( S.ShapeType() != TopAbs_VERTEX ) { Standard_ProgramError::Raise("TopOpeBRepTool_ShapeTool::Pnt"); return gp_Pnt(); } return BRep_Tool::Pnt(TopoDS::Vertex(S)); } #include #include //======================================================================= //function : BASISCURVE //purpose : //======================================================================= Handle(Geom_Curve) TopOpeBRepTool_ShapeTool::BASISCURVE(const Handle(Geom_Curve)& C) { Handle(Standard_Type) T = C->DynamicType(); if ( T == STANDARD_TYPE(Geom_OffsetCurve) ) return BASISCURVE(Handle(Geom_OffsetCurve)::DownCast(C)->BasisCurve()); else if ( T == STANDARD_TYPE(Geom_TrimmedCurve) ) return BASISCURVE(Handle(Geom_TrimmedCurve)::DownCast(C)->BasisCurve()); else return C; } Handle(Geom_Curve) TopOpeBRepTool_ShapeTool::BASISCURVE(const TopoDS_Edge& E) { Standard_Real f, l; Handle(Geom_Curve) C = BRep_Tool::Curve(E, f, l); if ( C.IsNull() ) return C; return BASISCURVE(C); } #include #include #include #include //======================================================================= //function : BASISSURFACE //purpose : //======================================================================= Handle(Geom_Surface) TopOpeBRepTool_ShapeTool::BASISSURFACE(const Handle(Geom_Surface)& S) { Handle(Standard_Type) T = S->DynamicType(); if ( T == STANDARD_TYPE(Geom_OffsetSurface) ) return BASISSURFACE(Handle(Geom_OffsetSurface)::DownCast(S)->BasisSurface()); else if ( T == STANDARD_TYPE(Geom_RectangularTrimmedSurface) ) return BASISSURFACE(Handle(Geom_RectangularTrimmedSurface)::DownCast(S)->BasisSurface()); else return S; } Handle(Geom_Surface) TopOpeBRepTool_ShapeTool::BASISSURFACE(const TopoDS_Face& F) { TopLoc_Location L;Handle(Geom_Surface) S = BRep_Tool::Surface(F,L); return BASISSURFACE(S); } //======================================================================= //function : UVBOUNDS //purpose : //======================================================================= void TopOpeBRepTool_ShapeTool::UVBOUNDS (const Handle(Geom_Surface)& S, Standard_Boolean& UPeriodic, Standard_Boolean& VPeriodic, Standard_Real& Umin, Standard_Real& Umax, Standard_Real& Vmin, Standard_Real& Vmax) { const Handle(Geom_Surface) BS = BASISSURFACE(S); Handle(Standard_Type) T = BS->DynamicType(); if ( T == STANDARD_TYPE(Geom_SurfaceOfRevolution) ) { Handle(Geom_SurfaceOfRevolution) SR = Handle(Geom_SurfaceOfRevolution)::DownCast(BS); Handle(Geom_Curve) C = BASISCURVE(SR->BasisCurve()); if (C->IsPeriodic()) { UPeriodic = Standard_False; VPeriodic = Standard_True; Vmin = C->FirstParameter(); Vmax = C->LastParameter(); } } else if ( T == STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion) ) { Handle(Geom_SurfaceOfLinearExtrusion) SE = Handle(Geom_SurfaceOfLinearExtrusion)::DownCast(BS); Handle(Geom_Curve) C = BASISCURVE(SE->BasisCurve()); if (C->IsPeriodic()) { UPeriodic = Standard_True; Umin = C->FirstParameter(); Umax = C->LastParameter(); VPeriodic = Standard_False; } } else { UPeriodic = BS->IsUPeriodic(); VPeriodic = BS->IsVPeriodic(); BS->Bounds(Umin,Umax,Vmin,Vmax); } } void TopOpeBRepTool_ShapeTool::UVBOUNDS (const TopoDS_Face& F, Standard_Boolean& UPeriodic, Standard_Boolean& VPeriodic, Standard_Real& Umin, Standard_Real& Umax, Standard_Real& Vmin, Standard_Real& Vmax) { TopLoc_Location L;Handle(Geom_Surface) S = BRep_Tool::Surface(F,L); UVBOUNDS(S, UPeriodic, VPeriodic, Umin, Umax, Vmin, Vmax); } //======================================================================= //function : AdjustOnPeriodic //purpose : //======================================================================= void TopOpeBRepTool_ShapeTool::AdjustOnPeriodic(const TopoDS_Shape& F, Standard_Real& u, Standard_Real& v) { TopoDS_Face FF = TopoDS::Face(F); TopLoc_Location Loc; const Handle(Geom_Surface) Surf = BRep_Tool::Surface(FF,Loc); // Standard_Real Ufirst,Ulast,Vfirst,Vlast; Standard_Boolean isUperio,isVperio; isUperio = Surf->IsUPeriodic(); isVperio = Surf->IsVPeriodic(); // exit if surface supporting F is not periodic on U or V if (!isUperio && !isVperio) return; Standard_Real UFfirst,UFlast,VFfirst,VFlast; BRepTools::UVBounds(FF,UFfirst,UFlast,VFfirst,VFlast); Standard_Real tol = Precision::PConfusion(); if (isUperio) { Standard_Real Uperiod = Surf->UPeriod(); // Standard_Real ubid = UFfirst; // ElCLib::AdjustPeriodic(UFfirst,UFfirst + Uperiod,tol,ubid,u); if (Abs(u - UFfirst-Uperiod) > tol) u = ElCLib::InPeriod(u,UFfirst,UFfirst + Uperiod); } if (isVperio) { Standard_Real Vperiod = Surf->VPeriod(); // Standard_Real vbid = VFfirst; // ElCLib::AdjustPeriodic(VFfirst,VFfirst + Vperiod,tol,vbid,v); if (Abs(v - VFfirst-Vperiod) > tol) v = ElCLib::InPeriod(v,VFfirst,VFfirst + Vperiod); } } //======================================================================= //function : Closed //purpose : //======================================================================= Standard_Boolean TopOpeBRepTool_ShapeTool::Closed(const TopoDS_Shape& S1, const TopoDS_Shape& S2) { const TopoDS_Edge& E = TopoDS::Edge(S1); const TopoDS_Face& F = TopoDS::Face(S2); Standard_Boolean brepclosed = BRep_Tool::IsClosed(E,F); if ( brepclosed ) { Standard_Integer n = 0; for ( TopExp_Explorer x(F,TopAbs_EDGE); x.More(); x.Next() ) if ( x.Current().IsSame(E) ) n++; if ( n < 2 ) return Standard_False; else return Standard_True; } return Standard_False; } #ifdef OCCT_DEBUG extern Standard_Boolean TopOpeBRepTool_GettraceVC(); extern Standard_Boolean TopOpeBRepTool_GettraceNYI(); #endif inline Standard_Boolean PARINBOUNDS(const Standard_Real par, const Standard_Real first, const Standard_Real last, const Standard_Real tol) { Standard_Boolean b = ( ((first+tol) <= par) && (par <= (last-tol)) ); return b; } inline Standard_Boolean PARONBOUND(const Standard_Real par, const Standard_Real bound, const Standard_Real tol) { Standard_Boolean b = ( ((bound-tol) <= par) && (par <= (bound+tol)) ); return b; } Standard_Real ADJUST(const Standard_Real par, const Standard_Real first, const Standard_Real last, const Standard_Real tol) { Standard_Real period = last - first, periopar = par; if (PARINBOUNDS(par,first,last,tol)) { periopar = par + period; } else if (PARONBOUND(par,first,tol)) { periopar = par + period; } else if (PARONBOUND(par,last,tol)) { periopar = par - period; } return periopar; } //======================================================================= //function : PeriodizeParameter //purpose : //======================================================================= Standard_Real TopOpeBRepTool_ShapeTool::PeriodizeParameter (const Standard_Real par, const TopoDS_Shape& EE, const TopoDS_Shape& FF) { Standard_Real periopar = par; if ( ! TopOpeBRepTool_ShapeTool::Closed(EE,FF) ) return periopar; TopoDS_Edge E = TopoDS::Edge(EE); TopoDS_Face F = TopoDS::Face(FF); TopLoc_Location Loc; const Handle(Geom_Surface) Surf = BRep_Tool::Surface(F,Loc); Standard_Boolean isUperio = Surf->IsUPeriodic(); Standard_Boolean isVperio = Surf->IsVPeriodic(); if (!isUperio && !isVperio) return periopar; Standard_Real Ufirst,Ulast,Vfirst,Vlast; Surf->Bounds(Ufirst,Ulast,Vfirst,Vlast); Standard_Real first,last,tolpc; const Handle(Geom2d_Curve) PC = FC2D_CurveOnSurface(E,F,first,last,tolpc); if (PC.IsNull()) Standard_ProgramError::Raise("ShapeTool::PeriodizeParameter : no 2d curve"); Handle(Standard_Type) TheType = PC->DynamicType(); if (TheType == STANDARD_TYPE(Geom2d_Line)) { Handle(Geom2d_Line) HL (Handle(Geom2d_Line)::DownCast (PC)); const gp_Dir2d& D = HL->Direction(); Standard_Real tol = Precision::Angular(); Standard_Boolean isoU = Standard_False, isoV = Standard_False; if (D.IsParallel(gp_Dir2d(0.,1.),tol)) isoU = Standard_True; else if (D.IsParallel(gp_Dir2d(1.,0.),tol)) isoV = Standard_True; if (isoU) { periopar = ADJUST(par,Ufirst,Ulast,tol); } else if (isoV) { periopar = ADJUST(par,Vfirst,Vlast,tol); } #ifdef OCCT_DEBUG if (TopOpeBRepTool_GettraceVC()) { cout<<"TopOpeBRepTool_ShapeTool PC on edge is "; if (isoU) cout<<"isoU f,l "< "< 0.); } else if (ST1 == GeomAbs_Cylinder && ST2 == GeomAbs_Cylinder) { // On peut projeter n'importe quel point. // prenons donc l'origine Standard_Real u1 = 0.; Standard_Real v1 = 0.; gp_Pnt p1; gp_Vec d1u,d1v; S1.D1(u1,v1,p1,d1u,d1v); gp_Vec n1 = d1u.Crossed(d1v); Handle(Geom_Surface) HS2 = S2.Surface().Surface(); HS2 = Handle(Geom_Surface)::DownCast(HS2->Transformed(S2.Trsf())); gp_Pnt2d p22d; Standard_Real dp2; Standard_Boolean ok = FUN_tool_projPonS(p1,HS2,p22d,dp2); if ( !ok ) return so; // NYI : raise Standard_Real u2 = p22d.X(); Standard_Real v2 = p22d.Y(); gp_Pnt p2; gp_Vec d2u,d2v; S2.D1(u2,v2,p2,d2u,d2v); gp_Vec n2 = d2u.Crossed(d2v); Standard_Real d = n1.Dot(n2); so = (d > 0.); } else { // prendre u1,v1 et projeter sur 2 pour calcul des normales // au meme point 3d. #ifdef OCCT_DEBUG if (TopOpeBRepTool_GettraceNYI()) { cout<<"TopOpeBRepTool_ShapeTool::SurfacesSameOriented surfaces non traitees : NYI"; cout< 0.); } else { // prendre p1 et projeter sur 2 pour calcul des normales // au meme point 3d. #ifdef OCCT_DEBUG if (TopOpeBRepTool_GettraceNYI()) { cout<<"TopOpeBRepTool_ShapeTool::CurvesSameOriented non lineaires : NYI"; cout< tolm ) BL.Normal(N); return tol; } //======================================================================= //function : EdgeData //purpose : //======================================================================= Standard_Real TopOpeBRepTool_ShapeTool::EdgeData (const TopoDS_Shape& E, const Standard_Real P, gp_Dir& T, gp_Dir& N, Standard_Real& C) { BRepAdaptor_Curve BAC(TopoDS::Edge(E)); Standard_Real d = EdgeData(BAC,P,T,N,C); return d; } //======================================================================= //function : Resolution3dU //purpose : //======================================================================= Standard_Real TopOpeBRepTool_ShapeTool::Resolution3dU(const Handle(Geom_Surface)& SU, const Standard_Real Tol2d) { GeomAdaptor_Surface GAS(SU); Standard_Real r3dunit = 0.00001; // petite valeur (1.0 -> RangeError sur un tore) Standard_Real ru = GAS.UResolution(r3dunit); Standard_Real r3du = r3dunit*(Tol2d/ru); return r3du; } //======================================================================= //function : Resolution3dV //purpose : //======================================================================= Standard_Real TopOpeBRepTool_ShapeTool::Resolution3dV(const Handle(Geom_Surface)& SU, const Standard_Real Tol2d) { GeomAdaptor_Surface GAS(SU); Standard_Real r3dunit = 0.00001; // petite valeur (1.0 -> RangeError sur un tore) Standard_Real rv = GAS.VResolution(r3dunit); Standard_Real r3dv = r3dunit*(Tol2d/rv); return r3dv; } //======================================================================= //function : Resolution3d //purpose : //======================================================================= Standard_Real TopOpeBRepTool_ShapeTool::Resolution3d(const Handle(Geom_Surface)& SU, const Standard_Real Tol2d) { Standard_Real ru = Resolution3dU(SU,Tol2d); Standard_Real rv = Resolution3dV(SU,Tol2d); Standard_Real r = Max(ru,rv); return r; } //======================================================================= //function : Resolution3d //purpose : //======================================================================= Standard_Real TopOpeBRepTool_ShapeTool::Resolution3d(const TopoDS_Face& F, const Standard_Real Tol2d) { TopLoc_Location L; const Handle(Geom_Surface)& SU = BRep_Tool::Surface(F,L); Standard_Real r = Resolution3d(SU,Tol2d); return r; }