// File: Contap_SurfProps.gxx // Created: Fri Feb 24 15:37:28 1995 // Author: Jacques GOUSSARD // #include //======================================================================= //function : Normale //purpose : //======================================================================= void Contap_SurfProps::Normale(const TheSurface& S, const Standard_Real U, const Standard_Real V, gp_Pnt& P, gp_Vec& Norm) { GeomAbs_SurfaceType typS = TheSurfaceTool::GetType(S); switch (typS) { case GeomAbs_Plane: { gp_Pln pl(TheSurfaceTool::Plane(S)); Norm = pl.Axis().Direction(); P = ElSLib::Value(U,V,pl); if (!pl.Direct()) { Norm.Reverse(); } } break; case GeomAbs_Sphere: { gp_Sphere sp(TheSurfaceTool::Sphere(S)); P = ElSLib::Value(U,V,sp); Norm = gp_Vec(sp.Location(),P); if (sp.Direct()) { Norm.Divide(sp.Radius()); } else { Norm.Divide(-sp.Radius()); } } break; case GeomAbs_Cylinder: { gp_Cylinder cy(TheSurfaceTool::Cylinder(S)); P = ElSLib::Value(U,V,cy); Norm.SetLinearForm(Cos(U),cy.XAxis().Direction(), Sin(U),cy.YAxis().Direction()); if (!cy.Direct()) { Norm.Reverse(); } } break; case GeomAbs_Cone: { gp_Cone co(TheSurfaceTool::Cone(S)); P = ElSLib::Value(U,V,co); Standard_Real Angle = co.SemiAngle(); Standard_Real Sina = sin(Angle); Standard_Real Cosa = cos(Angle); Standard_Real Rad = co.RefRadius(); Standard_Real Vcalc = V; if (Abs(V*Sina + Rad) <= 1e-12) { // on est a l`apex /* Standard_Real Vfi = TheSurfaceTool::FirstVParameter(S); if (Vfi < -Rad/Sina) { // partie valide pour V < Vapex Vcalc = V - 1; } else { Vcalc = V + 1.; } */ Norm.SetCoord(0,0,0); return; } if (Rad + Vcalc*Sina < 0.) { Norm.SetLinearForm(Sina, co.Axis().Direction(), Cosa*cos(U),co.XAxis().Direction(), Cosa*sin(U),co.YAxis().Direction()); } else { Norm.SetLinearForm(-Sina, co.Axis().Direction(), Cosa*cos(U),co.XAxis().Direction(), Cosa*sin(U),co.YAxis().Direction()); } if (!co.Direct()) { Norm.Reverse(); } } break; default: { gp_Vec d1u,d1v; TheSurfaceTool::D1(S,U,V,P,d1u,d1v); Norm = d1u.Crossed(d1v); } break; } } //======================================================================= //function : DerivAndNorm //purpose : //======================================================================= void Contap_SurfProps::DerivAndNorm(const TheSurface& S, const Standard_Real U, const Standard_Real V, gp_Pnt& P, gp_Vec& d1u, gp_Vec& d1v, gp_Vec& Norm) { GeomAbs_SurfaceType typS = TheSurfaceTool::GetType(S); switch (typS) { case GeomAbs_Plane: { gp_Pln pl(TheSurfaceTool::Plane(S)); Norm = pl.Axis().Direction(); ElSLib::D1(U,V,pl,P,d1u,d1v); if (!pl.Direct()) { Norm.Reverse(); } } break; case GeomAbs_Sphere: { gp_Sphere sp(TheSurfaceTool::Sphere(S)); ElSLib::D1(U,V,sp,P,d1u,d1v); Norm = gp_Vec(sp.Location(),P); if (sp.Direct()) { Norm.Divide(sp.Radius()); } else { Norm.Divide(-sp.Radius()); } } break; case GeomAbs_Cylinder: { gp_Cylinder cy(TheSurfaceTool::Cylinder(S)); ElSLib::D1(U,V,cy,P,d1u,d1v); Norm.SetLinearForm(Cos(U),cy.XAxis().Direction(), Sin(U),cy.YAxis().Direction()); if (!cy.Direct()) { Norm.Reverse(); } } break; case GeomAbs_Cone: { gp_Cone co(TheSurfaceTool::Cone(S)); ElSLib::D1(U,V,co,P,d1u,d1v); Standard_Real Angle = co.SemiAngle(); Standard_Real Sina = Sin(Angle); Standard_Real Cosa = Cos(Angle); Standard_Real Rad = co.RefRadius(); Standard_Real Vcalc = V; if (Abs(V*Sina + Rad) <= RealEpsilon()) { // on est a l`apex Standard_Real Vfi = TheSurfaceTool::FirstVParameter(S); if (Vfi < -Rad/Sina) { // partie valide pour V < Vapex Vcalc = V - 1; } else { Vcalc = V + 1.; } } if (Rad + Vcalc*Sina < 0.) { Norm.SetLinearForm(Sina, co.Axis().Direction(), Cosa*Cos(U),co.XAxis().Direction(), Cosa*Sin(U),co.YAxis().Direction()); } else { Norm.SetLinearForm(-Sina, co.Axis().Direction(), Cosa*Cos(U),co.XAxis().Direction(), Cosa*Sin(U),co.YAxis().Direction()); } if (!co.Direct()) { Norm.Reverse(); } } break; default: { TheSurfaceTool::D1(S,U,V,P,d1u,d1v); Norm = d1u.Crossed(d1v); } break; } } //======================================================================= //function : NormAndDn //purpose : //======================================================================= void Contap_SurfProps::NormAndDn(const TheSurface& S, const Standard_Real U, const Standard_Real V, gp_Pnt& P, gp_Vec& Norm, gp_Vec& Dnu, gp_Vec& Dnv) { GeomAbs_SurfaceType typS = TheSurfaceTool::GetType(S); switch (typS) { case GeomAbs_Plane: { gp_Pln pl(TheSurfaceTool::Plane(S)); P = ElSLib::Value(U,V,pl); Norm = pl.Axis().Direction(); if (!pl.Direct()) { Norm.Reverse(); } Dnu = Dnv = gp_Vec(0.,0.,0.); } break; case GeomAbs_Sphere: { gp_Sphere sp(TheSurfaceTool::Sphere(S)); ElSLib::D1(U,V,sp,P,Dnu,Dnv); Norm = gp_Vec(sp.Location(),P); Standard_Real Rad = sp.Radius(); if (!sp.Direct()) { Rad = -Rad; } Norm.Divide(Rad); Dnu.Divide(Rad); Dnv.Divide(Rad); } break; case GeomAbs_Cylinder: { gp_Cylinder cy(TheSurfaceTool::Cylinder(S)); P = ElSLib::Value(U,V,cy); Norm.SetLinearForm(Cos(U),cy.XAxis().Direction(), Sin(U),cy.YAxis().Direction()); Dnu.SetLinearForm(-Sin(U),cy.XAxis().Direction(), Cos(U),cy.YAxis().Direction()); if (!cy.Direct()) { Norm.Reverse(); Dnu.Reverse(); } Dnv = gp_Vec(0.,0.,0.); } break; case GeomAbs_Cone: { gp_Cone co(TheSurfaceTool::Cone(S)); P = ElSLib::Value(U,V,co); Standard_Real Angle = co.SemiAngle(); Standard_Real Sina = Sin(Angle); Standard_Real Cosa = Cos(Angle); Standard_Real Rad = co.RefRadius(); Standard_Real Vcalc = V; if (Abs(V*Sina + Rad) <= RealEpsilon()) { // on est a l`apex Standard_Real Vfi = TheSurfaceTool::FirstVParameter(S); if (Vfi < -Rad/Sina) { // partie valide pour V < Vapex Vcalc = V - 1; } else { Vcalc = V + 1.; } } if (Rad + Vcalc*Sina < 0.) { Norm.SetLinearForm(Sina, co.Axis().Direction(), Cosa*Cos(U),co.XAxis().Direction(), Cosa*Sin(U),co.YAxis().Direction()); } else { Norm.SetLinearForm(-Sina, co.Axis().Direction(), Cosa*Cos(U),co.XAxis().Direction(), Cosa*Sin(U),co.YAxis().Direction()); } Dnu.SetLinearForm(-Cosa*Sin(U),co.XAxis().Direction(), Cosa*Cos(U),co.YAxis().Direction()); if (!co.Direct()) { Norm.Reverse(); Dnu.Reverse(); } Dnv = gp_Vec(0.,0.,0.); } break; default: { gp_Vec d1u,d1v,d2u,d2v,d2uv; TheSurfaceTool::D2(S,U,V,P,d1u,d1v,d2u,d2v,d2uv); Norm = d1u.Crossed(d1v); Dnu = d2u.Crossed(d1v) + d1u.Crossed(d2uv); Dnv = d2uv.Crossed(d1v) + d1u.Crossed(d2v); } break; } }