1 // Created on: 1995-05-30
2 // Created by: Stagiaire Flore Lantheaume
3 // Copyright (c) 1995-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
18 #include <Adaptor3d_HSurface.hxx>
19 #include <ChFiDS_Spine.hxx>
20 #include <ChFiDS_SurfData.hxx>
21 #include <ChFiKPart_ComputeData.hxx>
22 #include <ChFiKPart_ComputeData_ChAsymPlnCon.hxx>
23 #include <ChFiKPart_ComputeData_Fcts.hxx>
26 #include <Geom2d_Circle.hxx>
27 #include <Geom2d_Line.hxx>
28 #include <Geom_Circle.hxx>
29 #include <Geom_ConicalSurface.hxx>
33 #include <gp_Circ.hxx>
35 #include <gp_Dir2d.hxx>
36 #include <gp_Lin2d.hxx>
38 #include <gp_Pnt2d.hxx>
40 #include <Precision.hxx>
41 #include <TopOpeBRepDS_DataStructure.hxx>
43 //=======================================================================
44 //function : MakeChamfer
45 //purpose : Compute the chamfer in the particular case Plane/Cone or
47 // Compute the SurfData <Data> of the chamfer build on the <Spine>
48 // between the plane <Pln> and the cone <Con>, with the
49 // distances <Dis1> on <Pln> and <Dis2> on <Con>.
50 // <Or1> and <Or2> are the orientations of <Pln> and <Con>
51 // and <Ofpl> this of the face carried by <Pln>.
52 // <First> is the start point on the <Spine>
53 // <Plandab> is equal to True if the plane is the surface S1
54 // <fu> and <lu> are the first and last u parameters of the
56 //out : True if the chanfer has been computed
58 //=======================================================================
59 Standard_Boolean ChFiKPart_MakeChamfer(TopOpeBRepDS_DataStructure& DStr,
60 const Handle(ChFiDS_SurfData)& Data,
61 const ChFiDS_ChamfMode theMode,
64 const Standard_Real fu,
65 const Standard_Real lu,
66 const TopAbs_Orientation Or1,
67 const TopAbs_Orientation Or2,
68 const Standard_Real theDis1,
69 const Standard_Real theDis2,
71 const Standard_Real First,
72 const TopAbs_Orientation Ofpl,
73 const Standard_Boolean plandab)
76 Standard_Real angcon = Con.SemiAngle();
78 Standard_Real Dis1 = theDis1, Dis2 = theDis2;
79 Standard_Real Alpha = M_PI/2 - angcon;
80 Standard_Real CosHalfAlpha = Cos(Alpha/2);
81 if (theMode == ChFiDS_ConstThroatChamfer)
82 Dis1 = Dis2 = theDis1 / CosHalfAlpha;
83 else if (theMode == ChFiDS_ConstThroatWithPenetrationChamfer)
85 Standard_Real aDis1 = Min(theDis1, theDis2);
86 Standard_Real aDis2 = Max(theDis1, theDis2);
87 Standard_Real dis1dis1 = aDis1*aDis1, dis2dis2 = aDis2*aDis2;
88 Standard_Real SinAlpha = Sin(Alpha);
89 Standard_Real CosAlpha = Cos(Alpha);
90 Standard_Real CotanAlpha = CosAlpha/SinAlpha;
91 Dis1 = sqrt(dis2dis2 - dis1dis1) - aDis1*CotanAlpha;
92 Standard_Real CosBeta = sqrt(1-dis1dis1/dis2dis2)*CosAlpha + aDis1/aDis2*SinAlpha;
93 Standard_Real FullDist1 = aDis2/CosBeta;
94 Dis2 = FullDist1 - aDis1/SinAlpha;
97 Standard_Real sincon =Abs(Sin(angcon));
99 Standard_Boolean IsResol;
101 gp_Ax3 PosPl = Pln.Position();
102 gp_Dir Dpl = PosPl.XDirection().Crossed(PosPl.YDirection());
103 if ( Or1 == TopAbs_REVERSED ) Dpl.Reverse();
105 // compute the origin of the conical chamfer PtPl
106 gp_Pnt Or = Con.Location();
108 ElSLib::PlaneParameters(PosPl,Or,u,v);
110 gp_Pnt2d pt2dPln(u,v);
112 ElSLib::PlaneD0(u,v,PosPl,Or);
116 ElCLib::D1(First,Spine,PtSp,DSp);
118 gp_Dir Dx(gp_Vec(Or,PtSp));
120 //compute the normal to the cone in PtSp
123 ElSLib::Parameters(Con,PtSp,u,v);
124 ElSLib::D1(u,v,Con,PtCon ,deru,derv);
125 gp_Dir Dcon( deru.Crossed(derv) );
126 if ( Or2 == TopAbs_REVERSED ) Dcon.Reverse();
128 Standard_Boolean ouvert = ( Dpl.Dot(Dcon) >= 0.);
131 if (Abs(Dis1 - Dis2 * sincon) > Precision::Confusion()) {
132 Standard_Real abscos = Abs(Dis2 - Dis1 * sincon);
133 angle = ATan((Dis1 * Cos(angcon)) / abscos);
140 angle = ATan((Dis1 * Cos(angcon)) / (Dis2 + Dis1 * sincon));
143 Standard_Boolean DisOnP = Standard_False;
145 IsResol = ChFiKPart_MakeChAsym(DStr, Data, Pln, Con, fu, lu, Or1, Or2,
146 Dis2, angle, Spine, First, Ofpl, plandab, DisOnP);
153 // Compute the chamfer surface(cone)
154 gp_Ax3 PosPl = Pln.Position();
155 gp_Dir Dpl = PosPl.XDirection().Crossed(PosPl.YDirection());
157 if (Ofpl == TopAbs_REVERSED ) norf.Reverse();
158 if ( Or1 == TopAbs_REVERSED ) Dpl.Reverse();
160 // compute the origin of the conical chamfer PtPl
161 gp_Pnt Or = Con.Location();
163 ElSLib::PlaneParameters(PosPl,Or,u,v);
164 gp_Pnt2d pt2dPln(u,v);
165 ElSLib::PlaneD0(u,v,PosPl,Or);
170 ElCLib::D1(First,Spine,PtSp,DSp);
171 gp_Dir Dx(gp_Vec(PtPl,PtSp));
173 //compute the normal to the cone in PtSp
176 ElSLib::Parameters(Con,PtSp,u,v);
177 ElSLib::D1(u,v,Con,PtCon ,deru,derv);
178 gp_Dir Dcon( deru.Crossed(derv) );
179 if ( Or2 == TopAbs_REVERSED ) Dcon.Reverse();
181 Standard_Boolean dedans = ( Dx.Dot(Dcon) <= 0.);
182 Standard_Boolean ouvert = ( Dpl.Dot(Dcon) >= 0.);
184 // variables used to compute the semiangle of the chamfer
185 Standard_Real angle = Con.SemiAngle();
186 Standard_Real move = Dis2 * Cos(angle);
187 Or.SetCoord( Or.X()+ move*Dpl.X(),
188 Or.Y()+ move*Dpl.Y(),
189 Or.Z()+ move*Dpl.Z());
191 gp_Dir Vec1(Or.X()-PtPl.X(), Or.Y()-PtPl.Y(), Or.Z()-PtPl.Z());
194 Dis = Dis1 + Dis2*Abs(Sin(angle));
196 Dis = Dis1 - Dis2*Abs(Sin(angle));
198 gp_Pnt Pt(Or.X()+Dis*PosPl.XDirection().X(),
199 Or.Y()+Dis*PosPl.XDirection().Y(),
200 Or.Z()+Dis*PosPl.XDirection().Z());
201 gp_Dir Vec2( Pt.X()-PtPl.X(), Pt.Y()-PtPl.Y(), Pt.Z()-PtPl.Z());
203 // compute the parameters of the conical chamfer
204 Standard_Real ChamfRad,SemiAngl;
205 Standard_Boolean pointu = Standard_False;
208 ChamfRad = Spine.Radius() - Dis1;
209 if ( Abs(ChamfRad)<=Precision::Confusion() ) pointu = Standard_True;
212 std::cout<<"le chanfrein ne passe pas"<<std::endl;
214 return Standard_False;
218 ChamfRad = Spine.Radius() + Dis1;
219 gp_Dir Dplr = Dpl.Reversed();
223 gp_Ax3 ChamfAx3(PtPl,Dpl,Dx);
224 SemiAngl = Vec1.Angle(Vec2);
226 Handle (Geom_ConicalSurface)
227 gcon = new Geom_ConicalSurface( ChamfAx3, SemiAngl, ChamfRad );
229 // changes due to the fact the parameters of the chamfer must go increasing
230 // from surface S1 to surface S2
231 if ( (dedans && !plandab) || (!dedans && plandab) ) {
232 gcon->VReverse();// be carefull : the SemiAngle was changed
233 ChamfAx3 = gcon->Position();
234 SemiAngl = gcon->SemiAngle();
237 // changes due to the fact we have reversed the V direction of
239 if (ChamfAx3.YDirection().Dot(DSp) <= 0.) {
241 gcon->SetPosition(ChamfAx3);
244 Data->ChangeSurf(ChFiKPart_IndexSurfaceInDS(gcon,DStr));
247 //compute the chamfer's orientation according to the orientation
250 //search the normal to the conical chamfer
254 v = sqrt(Dis*Dis + move*move);
256 v = - sqrt(Dis*Dis + move*move);
257 ElSLib::ConeD1(u,v,ChamfAx3,ChamfRad,SemiAngl,P,deru,derv);
258 gp_Dir norchamf(deru.Crossed(derv));
260 Standard_Boolean toreverse = (norf.Dot(norchamf)<= 0.);
263 Data->ChangeOrientation() = TopAbs_REVERSED;
265 Data->ChangeOrientation() = TopAbs_FORWARD;
268 //we load the faceInterference with the pcurves and
271 // Case of the plane face
272 // NB: in the case 'pointu', no pcurve on the plane surface
273 // and no intersection plane-chamfer are needed
275 // intersection plane-chamfer
276 Handle(Geom_Circle) GCirPln;
277 Handle(Geom2d_Circle) GCir2dPln;
278 gp_Ax2 CirAx2 = ChamfAx3.Ax2();
279 CirAx2.SetLocation(PtPl);
282 Pt.SetCoord(PtPl.X()+ChamfRad*Dx.X(),
283 PtPl.Y()+ChamfRad*Dx.Y(),
284 PtPl.Z()+ChamfRad*Dx.Z());
285 gp_Circ CirPln(CirAx2,ChamfRad);
286 GCirPln = new Geom_Circle(CirPln);
288 //pcurve on the plane
289 ElSLib::PlaneParameters(PosPl,Pt ,u,v);
290 gp_Pnt2d p2dPln(u,v);
291 gp_Dir2d d2d(DSp.Dot(PosPl.XDirection()),DSp.Dot(PosPl.YDirection()));
292 gp_Ax22d ax2dPln(pt2dPln, gp_Dir2d(gp_Vec2d(pt2dPln,p2dPln)),d2d);
293 gp_Circ2d cir2dPln(ax2dPln,ChamfRad);
294 GCir2dPln = new Geom2d_Circle(cir2dPln);
299 p2dch.SetCoord(0.,0.);
300 ElSLib::ConeD1(0.,0.,ChamfAx3,ChamfRad,SemiAngl,Pt,deru,derv);
301 gp_Lin2d lin2dch(p2dch,gp::DX2d());
302 Handle(Geom2d_Line) GLin2dCh1 = new Geom2d_Line(lin2dch);
305 TopAbs_Orientation trans;
306 gp_Dir norpl = PosPl.XDirection().Crossed(PosPl.YDirection());
308 norchamf.SetXYZ (deru.Crossed(derv).XYZ());
309 toreverse = ( norchamf.Dot(norpl) <= 0. );
310 if ((toreverse && plandab) || (!toreverse && !plandab)){
311 trans = TopAbs_FORWARD;
314 trans = TopAbs_REVERSED;
318 Data->ChangeInterferenceOnS1().
319 SetInterference(ChFiKPart_IndexCurveInDS(GCirPln,DStr),
320 trans,GCir2dPln,GLin2dCh1);
323 Data->ChangeInterferenceOnS2().
324 SetInterference(ChFiKPart_IndexCurveInDS(GCirPln,DStr),
325 trans,GCir2dPln,GLin2dCh1);
329 // Case of the conical face
331 //intersection cone-chamfer
334 Rad = ChamfRad + Dis;
336 Rad = ChamfRad - Dis;
338 CirAx2.SetLocation(Or);
339 gp_Circ CirCon(CirAx2, Rad);
340 Handle(Geom_Circle) GCirCon = new Geom_Circle(CirCon);
344 v = sqrt(Dis*Dis + move*move);
346 v = - sqrt(Dis*Dis + move*move);
347 p2dch.SetCoord(0.,v);
348 ElSLib::ConeD1(0.,v,ChamfAx3,ChamfRad,SemiAngl,Pt,deru,derv);
349 lin2dch.SetLocation(p2dch);
350 Handle(Geom2d_Line) GLin2dCh2 = new Geom2d_Line(lin2dch);
353 norchamf.SetXYZ (deru.Crossed(derv).XYZ());
355 Pt.SetCoord(Or.X()+Rad*Dx.X(),
358 ElSLib::Parameters(Con,Pt ,u,v);
359 Standard_Real tol = Precision::PConfusion();
360 if(u >= 2*M_PI - tol && u <= 2*M_PI) u = 0.;
361 if(u >= fu - tol && u < fu) u = fu;
362 if(u <= lu + tol && u > lu) u = lu;
363 if(u < fu || u > lu) u = ElCLib::InPeriod(u,fu,fu + 2*M_PI);
364 ElSLib::D1(u,v,Con,Pt,deru,derv);
365 gp_Pnt2d p2dCon(u,v);
367 if ( deru.Dot(DSp)<=0. )
368 d2dCon = - gp::DX2d();
371 gp_Lin2d lin2dCon(p2dCon,d2dCon);
372 Handle(Geom2d_Line) GLin2dCon = new Geom2d_Line(lin2dCon);
375 gp_Dir norcon = deru.Crossed(derv);
376 toreverse = ( norchamf.Dot(norcon) <= 0. );
377 if ((toreverse && plandab) || (!toreverse && !plandab) ) {
378 trans = TopAbs_REVERSED;
381 trans = TopAbs_FORWARD;
385 Data->ChangeInterferenceOnS2().
386 SetInterference(ChFiKPart_IndexCurveInDS(GCirCon,DStr),
387 trans,GLin2dCon,GLin2dCh2);
390 Data->ChangeInterferenceOnS1().
391 SetInterference(ChFiKPart_IndexCurveInDS(GCirCon,DStr),
392 trans,GLin2dCon,GLin2dCh2);
396 return Standard_True;