// Created on: 1995-05-19 // Created by: Flore Lantheaume // Copyright (c) 1995-1999 Matra Datavision // Copyright (c) 1999-2012 OPEN CASCADE SAS // // The content of this file is subject to the Open CASCADE Technology Public // License Version 6.5 (the "License"). You may not use the content of this file // except in compliance with the License. Please obtain a copy of the License // at http://www.opencascade.org and read it completely before using this file. // // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France. // // The Original Code and all software distributed under the License is // distributed on an "AS IS" basis, without warranty of any kind, and the // Initial Developer hereby disclaims all such warranties, including without // limitation, any warranties of merchantability, fitness for a particular // purpose or non-infringement. Please see the License for the specific terms // and conditions governing the rights and limitations under the License. #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include //pour tester #include //======================================================================= //function : MakeChamfer //purpose : Compute the chamfer in the particular case Plane/Cylinder // or Cylinder/Plane // Compute the SurfData of the chamfer build on the // between the plane and the cylinder , with the // distances on and on . // and are the orientations of and // and this of the face carried by . // is the start point on the // is equal to True if the plane is the surface S1 // and are the first and last u parameters of the // cylinder //out : True if the chanfer has been computed // False else //======================================================================= Standard_Boolean ChFiKPart_MakeChamfer(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 Dis1, const Standard_Real Dis2, const gp_Circ& Spine, const Standard_Real First, const TopAbs_Orientation Ofpl, const Standard_Boolean plandab) { // compute the chamfer surface(cone) // compute the normals to the plane surface & to the plane face gp_Ax3 PosPl = Pln.Position(); gp_Dir Dpl = PosPl.XDirection().Crossed(PosPl.YDirection()); gp_Dir norf = Dpl; if ( Ofpl == TopAbs_REVERSED) norf.Reverse(); if (Or1 == TopAbs_REVERSED) Dpl.Reverse(); // compute the origin Or of the cone gp_Pnt Or = Cyl.Location(); Standard_Real u,v; ElSLib::PlaneParameters(PosPl,Or,u,v); gp_Pnt2d pt2dPln(u,v); ElSLib::PlaneD0(u,v,PosPl,Or); gp_Pnt PtPl = Or; // projection of the cylinder origin //on the plane gp_Pnt PtSp;//start 3d point on the Spine gp_Vec DSp; //tangent vector to the spine on PtSp ElCLib::D1(First,Spine,PtSp,DSp); gp_Dir Dx(gp_Vec(Or,PtSp)); gp_Dir Dy(DSp); ElSLib::Parameters(Cyl,PtSp,u,v); gp_Pnt PtCyl;//point on the cylinder and on the Spine gp_Vec Vu,Vv; ElSLib::D1(u,v,Cyl,PtCyl,Vu,Vv); gp_Dir Dcyl(Vu.Crossed(Vv));//normal to the cylinder in PtSp if (Or2 == TopAbs_REVERSED) Dcyl.Reverse(); Standard_Boolean dedans = ( Dcyl.Dot(Dx) <= 0.); Standard_Boolean pointu = Standard_False; Standard_Real ConRad, Rad, SemiAngl ; Or.SetCoord(Or.X()+Dis2*Dpl.X(), Or.Y()+Dis2*Dpl.Y(), Or.Z()+Dis2*Dpl.Z()); // variables used to compute the semiangle of the cone gp_Dir Vec1(Or.X()-PtPl.X(), Or.Y()-PtPl.Y(), Or.Z()-PtPl.Z()); gp_Pnt Pt(Or.X()+Dis1*PosPl.XDirection().X(), Or.Y()+Dis1*PosPl.XDirection().Y(), Or.Z()+Dis1*PosPl.XDirection().Z()); gp_Dir Vec2( Pt.X()-PtPl.X(), Pt.Y()-PtPl.Y(), Pt.Z()-PtPl.Z()); // compute the parameters of the conical surface if (dedans) { Rad = Cyl.Radius()- Dis1; if ( Abs(Rad) <= Precision::Confusion() ) pointu = Standard_True; if(Rad < 0 ) { cout<<"the chamfer can't pass"<VReverse();// be carefull : the SemiAngle was changed ConAx3 = gcon->Position(); SemiAngl = gcon->SemiAngle(); } // changes due to the fact we have reversed the V direction of // parametrization if (ConAx3.YDirection().Dot(DSp) <= 0.) { ConAx3.YReverse(); gcon->SetPosition(ConAx3); } Data->ChangeSurf(ChFiKPart_IndexSurfaceInDS(gcon,DStr)); // compute the chamfer's orientation according to the orientation // of the faces //search the normal to the cone gp_Vec deru, derv; ElSLib::ConeD1(0.,0.,ConAx3,ConRad,SemiAngl,Pt,deru,derv); gp_Dir norCon(deru.Crossed(derv)); Standard_Boolean toreverse = ( norCon.Dot(norf) <= 0.); if (toreverse) { Data->ChangeOrientation() = TopAbs_REVERSED; } else { Data->ChangeOrientation() = TopAbs_FORWARD; } //we load of the faceInterference with the pcurves and // the 3d curves // Case of the plane face // NB: in the case 'pointu', no pcurve on the plane surface // and no intersection plane-chamfer are needed Handle(Geom2d_Circle) GCir2dPln; Handle(Geom_Circle) GCirPln; gp_Ax2 CirAx2 = ConAx3.Ax2(); CirAx2.SetLocation(PtPl); if (!pointu) { // intersection plane-chamfer gp_Circ CirPln(CirAx2,Rad); GCirPln = new Geom_Circle(CirPln); //pcurve on the plane ElSLib::PlaneParameters(PosPl,Pt ,u,v); gp_Pnt2d p2dPln(u,v); gp_Dir2d d2d(DSp.Dot(PosPl.XDirection()),DSp.Dot(PosPl.YDirection())); gp_Ax22d ax2dPln(pt2dPln, gp_Dir2d(gp_Vec2d(pt2dPln,p2dPln)),d2d); gp_Circ2d cir2dPln(ax2dPln,Rad); GCir2dPln = new Geom2d_Circle(cir2dPln); } //pcurve on the chamfer gp_Pnt2d p2dch; if (plandab) v= -sqrt(Dis1*Dis1+Dis2*Dis2); else v = sqrt(Dis1*Dis1+Dis2*Dis2); p2dch.SetCoord(0.,v); ElSLib::ConeD1(0.,v,ConAx3,ConRad,SemiAngl,Pt,deru,derv); gp_Lin2d lin2dch(p2dch,gp::DX2d()); Handle(Geom2d_Line) GLin2dCh1 = new Geom2d_Line(lin2dch); //orientation TopAbs_Orientation trans; gp_Dir norpl = PosPl.XDirection().Crossed(PosPl.YDirection()); toreverse = ( norCon.Dot(norpl) <= 0. ); if ((toreverse && plandab) || (!toreverse && !plandab)){ trans = TopAbs_FORWARD; } else { trans = TopAbs_REVERSED; } if(plandab){ Data->ChangeInterferenceOnS1(). SetInterference(ChFiKPart_IndexCurveInDS(GCirPln,DStr), trans,GCir2dPln,GLin2dCh1); } else{ Data->ChangeInterferenceOnS2(). SetInterference(ChFiKPart_IndexCurveInDS(GCirPln,DStr), trans,GCir2dPln,GLin2dCh1); } // Case of the cylindrical face //intersection cylinder-chamfer CirAx2.SetLocation(Or); gp_Circ CirCyl(CirAx2,ConRad); Handle(Geom_Circle) GCirCyl = new Geom_Circle(CirCyl); //pcurve on the chamfer p2dch.SetCoord(0.,0.); ElSLib::ConeD1(0.,0.,ConAx3,ConRad,SemiAngl,Pt,deru,derv); lin2dch.SetLocation(p2dch); Handle(Geom2d_Line) GLin2dCh2 = new Geom2d_Line(lin2dch); //pcurve on the cylinder norCon.SetXYZ (deru.Crossed(derv).XYZ()); Pt.SetCoord(Or.X()+ConRad*Dx.X(), Or.Y()+ConRad*Dx.Y(), Or.Z()+ConRad*Dx.Z()); ElSLib::Parameters(Cyl,Pt ,u,v); Standard_Real tol = Precision::PConfusion(); Standard_Boolean careaboutsens = 0; if(Abs(lu - fu - 2*M_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*M_PI,tol); ElSLib::D1(u,v,Cyl,Pt,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(GCirCyl,DStr), trans,GLin2dCyl,GLin2dCh2); } else{ Data->ChangeInterferenceOnS1(). SetInterference(ChFiKPart_IndexCurveInDS(GCirCyl,DStr), trans,GLin2dCyl,GLin2dCh2); } return Standard_True; } //======================================================================= //function : MakeChamfer //purpose : case cylinder/plane or plane/cylinder. //======================================================================= Standard_Boolean ChFiKPart_MakeChamfer(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 Dis1, const Standard_Real Dis2, const gp_Lin& Spine, const Standard_Real First, const TopAbs_Orientation Ofpl, const Standard_Boolean plandab) { // calculation of the fillet plane. // or1 and or2 permit to determine in which of four sides created by // intersection of 2 surfaces we are // _|_ Ofpl is orientation of the plane face allowing // |4 to determine the side of the material Standard_Real dis1=Dis1, dis2=Dis2; if (!plandab){ dis1 = Dis2; dis2 = Dis1;} gp_Pnt OrSpine = ElCLib::Value(First,Spine); gp_Pnt POnCyl, POnPln, OrCyl; gp_Dir XDir = Spine.Direction(); gp_Ax3 AxPln = Pln.Position(); gp_Dir NorPln = AxPln.XDirection().Crossed(AxPln.YDirection()); gp_Dir NorF(NorPln); if (Or1 == TopAbs_REVERSED) {NorF.Reverse();} gp_Ax3 AxCyl = Cyl.Position(); // OrCyl is the point on axis of cylinder in the plane normal to the // axis containing OrSpine gp_Pnt Loc = AxCyl.Location(); gp_Vec LocSp(Loc, OrSpine); gp_XYZ temp = AxCyl.Direction().XYZ(); temp = temp.Multiplied(LocSp.XYZ().Multiplied(temp) ); OrCyl.SetXYZ( (Loc.XYZ()).Added(temp) ); // gp_XYZ temp = AxCyl.Direction().XYZ(); // temp = temp.Multiplied( OrSpine.XYZ().Multiplied(temp) ); // OrCyl.SetXYZ( (AxCyl.Location().XYZ()).Added(temp) ); //construction of POnPln gp_Vec VecTranslPln,tmp; tmp = gp_Vec(OrSpine,OrCyl); if ((Or2 == TopAbs_FORWARD && Cyl.Direct()) || (Or2 == TopAbs_REVERSED && !Cyl.Direct())) {tmp.Reverse();} VecTranslPln = gp_Vec( XDir.Crossed(NorPln) ); if( VecTranslPln.Dot(tmp) <= 0. ) {VecTranslPln.Reverse();} VecTranslPln.Multiply(dis1); POnPln.SetXYZ( (OrSpine.XYZ()).Added(VecTranslPln.XYZ()) ); //construction of POnCyl Standard_Real alpha = ( 2*ASin(dis2*0.5/Cyl.Radius()) ); // gp_Vec VecTranslCyl; // VecTranslCyl = gp_Vec(OrSpine,OrCyl); // if ( ( XDir.Crossed(gp_Dir(VecTranslCyl)) ).Dot(NorF) <=0. ) // {VecTranslCyl.Rotate(gp_Ax1(OrSpine,XDir),alpha);} // else // {VecTranslCyl.Rotate(gp_Ax1(OrSpine,XDir.Reversed()),alpha);} // POnCyl.SetXYZ( OrCyl.XYZ().Added(VecTranslCyl.XYZ()) ); gp_Vec VecCylTransl = gp_Vec(OrCyl,OrSpine); if ( ( XDir.Crossed(gp_Dir(VecCylTransl)) ).Dot(NorF) > 0.) { VecCylTransl.Rotate(gp_Ax1(OrCyl,XDir),alpha); } else { VecCylTransl.Rotate(gp_Ax1(OrCyl,XDir.Reversed()),alpha);} POnCyl.SetXYZ( OrCyl.XYZ().Added(VecCylTransl.XYZ()) ); //construction of chamfer Standard_Real UOnCyl,VOnCyl,UOnPln,VOnPln; ElSLib::Parameters(Cyl,POnCyl,UOnCyl,VOnCyl); POnCyl = ElSLib::CylinderValue(UOnCyl,VOnCyl,AxCyl,Cyl.Radius()); ElSLib::Parameters(Pln,POnPln,UOnPln,VOnPln); POnPln = ElSLib::PlaneValue(UOnPln,VOnPln,AxPln); //construction of YDir to go to face1 from face2. gp_Vec YDir(POnPln,POnCyl); if (!plandab){ YDir.Reverse(); } gp_Ax3 AxCh(POnPln,XDir.Crossed(YDir),XDir); Handle(Geom_Plane) Chamfer = new Geom_Plane(AxCh); Data->ChangeSurf(ChFiKPart_IndexSurfaceInDS(Chamfer,DStr)); // FaceInterferences are loaded with pcurves and curves 3d. //----------- edge plane-Chamfer gp_Pnt2d PPln2d(UOnPln,VOnPln); gp_Dir2d VPln2d(XDir.Dot(AxPln.XDirection()), XDir.Dot(AxPln.YDirection())); gp_Lin2d Lin2dPln(PPln2d,VPln2d); POnPln = ElSLib::Value(UOnPln,VOnPln,Pln); gp_Lin C3d(POnPln,XDir); Standard_Real U,VOnChamfer; ElSLib::PlaneParameters(AxCh,POnPln,U,VOnChamfer); gp_Lin2d LOnChamfer(gp_Pnt2d(U,VOnChamfer),gp::DX2d()); Handle(Geom_Line) L3d = new Geom_Line (C3d); Handle(Geom2d_Line) LFac = new Geom2d_Line(Lin2dPln); Handle(Geom2d_Line) LFil = new Geom2d_Line(LOnChamfer); gp_Dir NorFil=AxCh.Direction(); Standard_Boolean toreverse = ( NorFil.Dot(NorPln) <= 0. ); gp_Dir DirPlnCyl(gp_Vec(POnPln, POnCyl)); gp_Dir DirSPln(gp_Vec(OrSpine, POnPln)); Standard_Boolean PosChamfPln = DirPlnCyl.Dot(DirSPln) > 0; if (PosChamfPln ) toreverse = !toreverse; // It is checked if the orientation of the Chamfer is the same as of the plane if (toreverse) {Data->ChangeOrientation() = TopAbs::Reverse(Ofpl);} else {Data->ChangeOrientation() = Ofpl;} TopAbs_Orientation trans = TopAbs_FORWARD; if ((!plandab && toreverse) || (plandab && !toreverse)) {trans=TopAbs_REVERSED;} //trans permits to determine the "material" side on S1(2) limited by L3d 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-Chamfer gp_Pnt2d PCyl2d(UOnCyl,VOnCyl); gp_Dir2d VCyl2d=gp::DY2d(); if ( XDir.Dot(AxCyl.Direction())<0 ) {VCyl2d.Reverse();} gp_Lin2d Lin2dCyl(PCyl2d,VCyl2d); POnCyl = ElSLib::Value(UOnCyl,VOnCyl,Cyl); C3d = gp_Lin(POnCyl,XDir); ElSLib::PlaneParameters(AxCh,POnCyl,U,VOnChamfer); LOnChamfer = gp_Lin2d(gp_Pnt2d(U,VOnChamfer),gp::DX2d()); L3d = new Geom_Line (C3d); LFac = new Geom2d_Line(Lin2dCyl); LFil = new Geom2d_Line(LOnChamfer); gp_Vec deru,derv; ElSLib::CylinderD1(UOnCyl,VOnCyl,AxCyl,Cyl.Radius(),POnCyl,deru,derv); gp_Dir NorCyl(deru.Crossed(derv)); toreverse = ( NorFil.Dot(NorCyl) <= 0. ); gp_Dir DirSCyl(gp_Vec(OrSpine, POnCyl)); Standard_Boolean PosChamfCyl = DirPlnCyl.Dot(DirSCyl) < 0; if (PosChamfCyl) toreverse = !toreverse; trans = TopAbs_REVERSED; if ((!plandab && toreverse) || (plandab && !toreverse)) {trans=TopAbs_FORWARD;} 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; }