// File: ChFiKPart_CompData_PlnCyl.gxx // Created: Thu Feb 3 15:03:17 1994 // Author: Isabelle GRIGNON // #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include //======================================================================= //function : MakeFillet //purpose : case cylinder/plane or plane/cylinder. //======================================================================= Standard_Boolean ChFiKPart_MakeFillet(TopOpeBRepDS_DataStructure& DStr, const Handle(ChFiDS_SurfData)& Data, const gp_Pln& Pln, const gp_Cylinder& Cyl, const Standard_Real fu, const Standard_Real lu, const TopAbs_Orientation Or1, const TopAbs_Orientation Or2, const Standard_Real Radius, const gp_Lin& Spine, const Standard_Real First, const TopAbs_Orientation Ofpl, const Standard_Boolean plandab) { //calculate the cylinder fillet. //plane deviated from radius gp_Ax3 AxPln = Pln.Position(); gp_Dir NorPln = AxPln.XDirection().Crossed(AxPln.YDirection()); gp_Dir NorF(NorPln); gp_Ax3 AxCyl = Cyl.Position(); if (Or1 == TopAbs_REVERSED) { NorF.Reverse(); } gp_Pln PlanOffset = Pln.Translated(Radius*gp_Vec(NorF)); // Parallel cylinder Standard_Real ROff = Cyl.Radius(); if ((Or2 == TopAbs_FORWARD && Cyl.Direct()) || (Or2 == TopAbs_REVERSED && !Cyl.Direct())) ROff+=Radius; else if (Radius < ROff) { ROff-=Radius; } else { #ifdef DEB cout<<"the fillet does not pass"< lu + tesp) UOnCyl = ElCLib::InPeriod(UOnCyl,fu,fu+2*PI); ElSLib::Parameters(Pln,OrFillet,UOnPln,VOnPln); gp_Vec XDir,OtherDir; XDir = NorF.Reversed(); OtherDir = gp_Dir(gp_Vec(OrFillet,ElSLib::Value(UOnCyl,VOnCyl,Cyl))); if (!plandab) { gp_Vec tmp = XDir; XDir = OtherDir; OtherDir = tmp; } gp_Ax3 AxFil (OrFillet,DirFillet,XDir); // construction YDir to go from face1 to face2. if ((XDir^OtherDir).Dot(DirFillet) < 0.) AxFil.YReverse(); Handle(Geom_CylindricalSurface) Fillet = new Geom_CylindricalSurface(AxFil,Radius); Data->ChangeSurf(ChFiKPart_IndexSurfaceInDS(Fillet,DStr)); // FaceInterferences are loaded with pcurves and curves 3D. // edge plane-Fillet gp_Pnt2d PPln2d(UOnPln,VOnPln); gp_Dir2d VPln2d(DirFillet.Dot(AxPln.XDirection()), DirFillet.Dot(AxPln.YDirection())); gp_Lin2d Lin2dPln(PPln2d,VPln2d); gp_Pnt POnPln = ElSLib::Value(UOnPln,VOnPln,Pln); gp_Lin C3d(POnPln,DirFillet); Standard_Real UOnFillet,V; ElSLib::CylinderParameters(AxFil,Radius,POnPln,UOnFillet,V); if(UOnFillet > PI) UOnFillet = 0.; gp_Lin2d LOnFillet(gp_Pnt2d(UOnFillet,V),gp::DY2d()); Handle(Geom_Line) L3d = new Geom_Line (C3d); Handle(Geom2d_Line) LFac = new Geom2d_Line(Lin2dPln); Handle(Geom2d_Line) LFil = new Geom2d_Line(LOnFillet); gp_Pnt P; gp_Vec deru,derv; ElSLib::CylinderD1(UOnFillet,V,AxFil,Radius,P,deru,derv); gp_Dir NorFil(deru.Crossed(derv)); Standard_Boolean toreverse = ( NorFil.Dot(NorPln) <= 0. ); // It is checked if the orientation of the cylinder is the same as of the plane. if (toreverse) {Data->ChangeOrientation() = TopAbs::Reverse(Ofpl);} else {Data->ChangeOrientation() = Ofpl;} TopAbs_Orientation trans; if ((toreverse && plandab) || (!toreverse && !plandab) ){ trans = TopAbs_REVERSED; } else { trans = TopAbs_FORWARD; } if (plandab) Data->ChangeInterferenceOnS1(). SetInterference(ChFiKPart_IndexCurveInDS(L3d,DStr), trans,LFac,LFil); else Data->ChangeInterferenceOnS2(). SetInterference(ChFiKPart_IndexCurveInDS(L3d,DStr), trans,LFac,LFil); // edge cylinder-Fillet. gp_Pnt2d PCyl2d(UOnCyl,VOnCyl); gp_Dir2d DPC = gp::DY2d(); if (DirFillet.Dot(AxCyl.Direction()) < 0.) DPC.Reverse(); gp_Lin2d Lin2dCyl(PCyl2d,DPC); gp_Pnt POnCyl = ElSLib::Value(UOnCyl,VOnCyl,Cyl); C3d = gp_Lin(POnCyl,DirFillet); ElSLib::CylinderParameters(AxFil,Radius,POnCyl,UOnFillet,V); if(UOnFillet > PI) UOnFillet = 0.; LOnFillet = gp_Lin2d(gp_Pnt2d(UOnFillet,V),gp::DY2d()); L3d = new Geom_Line (C3d); LFac = new Geom2d_Line(Lin2dCyl); LFil = new Geom2d_Line(LOnFillet); ElSLib::CylinderD1(UOnFillet,V,AxFil,Radius,P,deru,derv); NorFil= gp_Dir(deru.Crossed(derv)); ElSLib::CylinderD1(UOnCyl,VOnCyl,AxCyl,Cyl.Radius(),P,deru,derv); gp_Dir NorCyl(deru.Crossed(derv)); toreverse = ( NorFil.Dot(NorCyl) <= 0. ); if ((toreverse && plandab) || (!toreverse && !plandab) ){ trans = TopAbs_FORWARD; } else { trans = TopAbs_REVERSED; } if (plandab) Data->ChangeInterferenceOnS2(). SetInterference(ChFiKPart_IndexCurveInDS(L3d,DStr), trans,LFac,LFil); else Data->ChangeInterferenceOnS1(). SetInterference(ChFiKPart_IndexCurveInDS(L3d,DStr), trans,LFac,LFil); return Standard_True; } //======================================================================= //function : MakeFillet //purpose : case cylinder/plane or plane/cylinder. //======================================================================= Standard_Boolean ChFiKPart_MakeFillet(TopOpeBRepDS_DataStructure& DStr, const Handle(ChFiDS_SurfData)& Data, const gp_Pln& Pln, const gp_Cylinder& Cyl, const Standard_Real fu, const Standard_Real lu, const TopAbs_Orientation Or1, const TopAbs_Orientation Or2, const Standard_Real Radius, const gp_Circ& Spine, const Standard_Real First, const TopAbs_Orientation Ofpl, const Standard_Boolean plandab) { //calculation of the fillet (torus or sphere). Standard_Boolean c1sphere = Standard_False; gp_Ax3 PosPl = Pln.Position(); gp_Dir Dpnat = PosPl.XDirection().Crossed(PosPl.YDirection()); gp_Dir Dp = Dpnat; gp_Dir Df = Dp; if (Or1 == TopAbs_REVERSED) { Dp.Reverse(); } if (Ofpl == TopAbs_REVERSED) { Df.Reverse(); } gp_Pnt Or = Cyl.Location(); Standard_Real u,v; ElSLib::PlaneParameters(PosPl,Or,u,v); gp_Pnt2d c2dPln(u,v); ElSLib::PlaneD0(u,v,PosPl,Or); gp_Pnt cPln = Or; Or.SetCoord(Or.X()+Radius*Dp.X(), Or.Y()+Radius*Dp.Y(), Or.Z()+Radius*Dp.Z()); gp_Pnt PtSp; gp_Vec DSp; // Modification for the PtSp found at the wrong side of the sewing edge. gp_Pnt PtSp2; gp_Vec DSp2; Standard_Real acote = 1e-7; ElCLib::D1(First,Spine,PtSp,DSp); ElSLib::Parameters(Cyl,PtSp,u,v); if ((Abs(u)PI){ u = (2*PI)-u; PtSp = ElSLib::Value(u,v,Cyl); Standard_Real PR; PR = ElCLib::Parameter(Spine,PtSp); ElCLib::D1(PR,Spine,PtSp2,DSp); } } // end of modif gp_Dir Dx(gp_Vec(Or,PtSp)); Dx = Dp.Crossed(Dx.Crossed(Dp)); gp_Dir Dy(DSp); gp_Pnt PtCyl; gp_Vec Vu,Vv; ElSLib::D1(u,v,Cyl,PtCyl,Vu,Vv); gp_Dir Dc(Vu.Crossed(Vv)); if (Or2 == TopAbs_REVERSED) { Dc.Reverse(); } gp_Dir Dz = Dp; Standard_Real Rad,cylrad = Cyl.Radius(); Standard_Boolean dedans = (Dx.Dot(Dc) <= 0.); if(dedans){ if (!plandab){ Dz.Reverse(); } Rad = cylrad - Radius; if(Abs(Rad) <= Precision::Confusion()){ c1sphere = Standard_True; } else if(Rad < 0){ #ifdef DEB cout<<"the fillet can't pass"<ChangeSurf(ChFiKPart_IndexSurfaceInDS(gsph,DStr)); } else{ Handle(Geom_ToroidalSurface) gtor = new Geom_ToroidalSurface(FilAx3,Rad,Radius); Data->ChangeSurf(ChFiKPart_IndexSurfaceInDS(gtor,DStr)); } // It is checked if the orientation of the fillet is the same as of faces. gp_Pnt P,PP; gp_Vec deru,derv; P.SetCoord(cPln.X()+Rad*Dx.X(), cPln.Y()+Rad*Dx.Y(), cPln.Z()+Rad*Dx.Z()); u = 0.; if ((dedans && plandab) || (!dedans && !plandab)){ if (c1sphere) { v = - PI / 2; } else { v = 3 * PI / 2; } } else { v = PI / 2; } gp_Dir norFil; if(c1sphere){ ElSLib::SphereD1(u,v,FilAx3,cylrad,PP,deru,derv); norFil = FilAx3.XDirection().Crossed(FilAx3.YDirection()); if(v < 0.) norFil.Reverse(); } else{ ElSLib::TorusD1(u,v,FilAx3,Rad,Radius,PP,deru,derv); norFil = gp_Dir(deru.Crossed(derv)); } gp_Pnt2d p2dFil(0.,v); Standard_Boolean toreverse = ( norFil.Dot(Df) <= 0. ); if (toreverse) { Data->ChangeOrientation() = TopAbs_REVERSED; } else { Data->ChangeOrientation() = TopAbs_FORWARD; } // FaceInterferences are loaded with pcurves and curves 3d. // The plane face. Handle(Geom2d_Circle) GCirc2dPln; Handle(Geom_Circle) GCircPln; gp_Ax2 circAx2 = FilAx3.Ax2(); if(!c1sphere){ ElSLib::PlaneParameters(PosPl,P,u,v); gp_Pnt2d p2dPln(u,v); gp_Dir2d d2d(DSp.Dot(PosPl.XDirection()),DSp.Dot(PosPl.YDirection())); gp_Ax22d ax2dPln(c2dPln,gp_Dir2d(gp_Vec2d(c2dPln,p2dPln)),d2d); gp_Circ2d circ2dPln(ax2dPln,Rad); GCirc2dPln = new Geom2d_Circle(circ2dPln); circAx2.SetLocation(cPln); gp_Circ circPln(circAx2,Rad); GCircPln = new Geom_Circle(circPln); } else { ElSLib::PlaneParameters(PosPl,P,u,v); gp_Pnt2d p2dPln(u,v),pbid; if(plandab){ Data->Set2dPoints(p2dPln,p2dPln,pbid,pbid); } else { Data->Set2dPoints(pbid,pbid,p2dPln,p2dPln); } } gp_Lin2d lin2dFil(p2dFil,gp::DX2d()); Handle(Geom2d_Line) GLin2dFil1 = new Geom2d_Line(lin2dFil); toreverse = ( norFil.Dot(Dpnat) <= 0. ); TopAbs_Orientation trans; if ((toreverse && plandab) || (!toreverse && !plandab) ){ trans = TopAbs_FORWARD; } else { trans = TopAbs_REVERSED; } if(plandab){ Data->ChangeInterferenceOnS1(). SetInterference(ChFiKPart_IndexCurveInDS(GCircPln,DStr), trans,GCirc2dPln,GLin2dFil1); } else{ Data->ChangeInterferenceOnS2(). SetInterference(ChFiKPart_IndexCurveInDS(GCircPln,DStr), trans,GCirc2dPln,GLin2dFil1); } // The cylindrical face. P.SetCoord(Or.X()+cylrad*Dx.X(), Or.Y()+cylrad*Dx.Y(), Or.Z()+cylrad*Dx.Z()); u = 0.; if (dedans) { if (plandab && !c1sphere) { v = 2 * PI; } else { v = 0. ; } } else { v = PI; } p2dFil.SetCoord(u,v); if(c1sphere){ ElSLib::SphereD1(u,v,FilAx3,cylrad,PP,deru,derv); } else{ ElSLib::TorusD1(u,v,FilAx3,Rad,Radius,PP,deru,derv); } norFil = deru.Crossed(derv); lin2dFil.SetLocation(p2dFil); Handle(Geom2d_Line) GLin2dFil2 = new Geom2d_Line(lin2dFil); ElSLib::Parameters(Cyl,P,u,v); Standard_Real tol = Precision::PConfusion(); Standard_Boolean careaboutsens = 0; if(Abs(lu - fu - 2*PI) < tol) careaboutsens = 1; if(u >= fu - tol && u < fu) u = fu; if(u <= lu + tol && u > lu) u = lu; if(u < fu || u > lu) u = ChFiKPart_InPeriod(u,fu,fu + 2*PI,tol); ElSLib::D1(u,v,Cyl,PP,deru,derv); gp_Dir norcyl = deru.Crossed(derv); gp_Dir2d d2dCyl = gp::DX2d(); if( deru.Dot(Dy) < 0. ){ d2dCyl.Reverse(); if(careaboutsens && Abs(fu-u)ChangeInterferenceOnS2(). SetInterference(ChFiKPart_IndexCurveInDS(GCircCyl,DStr), trans,GLin2dCyl,GLin2dFil2); } else{ Data->ChangeInterferenceOnS1(). SetInterference(ChFiKPart_IndexCurveInDS(GCircCyl,DStr), trans,GLin2dCyl,GLin2dFil2); } return Standard_True; }