1 // File: ChFiKPart_CompData_PlnCyl.gxx
2 // Created: Thu Feb 3 15:03:17 1994
3 // Author: Isabelle GRIGNON
6 #include <ChFiKPart_ComputeData.jxx>
7 #include <Precision.hxx>
9 #include <gp_Pnt2d.hxx>
10 #include <gp_Dir2d.hxx>
11 #include <gp_Lin2d.hxx>
18 #include <gp_Circ.hxx>
20 #include <gp_Cylinder.hxx>
25 #include <Geom2d_Line.hxx>
26 #include <Geom2d_Circle.hxx>
27 #include <Geom_Line.hxx>
28 #include <Geom_Circle.hxx>
29 #include <Geom_ToroidalSurface.hxx>
30 #include <Geom_SphericalSurface.hxx>
31 #include <Geom_CylindricalSurface.hxx>
32 #include <IntAna_QuadQuadGeo.hxx>
34 #include <ChFiKPart_ComputeData_Fcts.hxx>
37 //=======================================================================
38 //function : MakeFillet
39 //purpose : case cylinder/plane or plane/cylinder.
40 //=======================================================================
42 Standard_Boolean ChFiKPart_MakeFillet(TopOpeBRepDS_DataStructure& DStr,
43 const Handle(ChFiDS_SurfData)& Data,
45 const gp_Cylinder& Cyl,
46 const Standard_Real fu,
47 const Standard_Real lu,
48 const TopAbs_Orientation Or1,
49 const TopAbs_Orientation Or2,
50 const Standard_Real Radius,
52 const Standard_Real First,
53 const TopAbs_Orientation Ofpl,
54 const Standard_Boolean plandab)
56 //calculate the cylinder fillet.
58 //plane deviated from radius
59 gp_Ax3 AxPln = Pln.Position();
60 gp_Dir NorPln = AxPln.XDirection().Crossed(AxPln.YDirection());
62 gp_Ax3 AxCyl = Cyl.Position();
64 if (Or1 == TopAbs_REVERSED) { NorF.Reverse(); }
65 gp_Pln PlanOffset = Pln.Translated(Radius*gp_Vec(NorF));
68 Standard_Real ROff = Cyl.Radius();
69 Standard_Boolean dedans = Standard_False;
71 if ((Or2 == TopAbs_FORWARD && Cyl.Direct()) ||
72 (Or2 == TopAbs_REVERSED && !Cyl.Direct()))
74 else if (Radius < ROff) {
75 ROff-=Radius;dedans = Standard_True;
79 cout<<"the fillet does not pass"<<endl;
81 return Standard_False;
83 // intersection of the parallel plane and of the parallel cylinder.
84 gp_Cylinder CylOffset(Cyl.Position(),ROff);
85 IntAna_QuadQuadGeo LInt(PlanOffset,CylOffset,
86 Precision::Angular(),Precision::Confusion());
87 gp_Pnt OrSpine = ElCLib::Value(First,Spine);
91 DirFillet = LInt.Line(1).Direction();
92 gp_Pnt P1 = ElCLib::Value(ElCLib::Parameter
93 (LInt.Line(1),OrSpine),LInt.Line(1));
94 if(LInt.NbSolutions() == 2){
95 gp_Pnt P2 = ElCLib::Value(ElCLib::Parameter
96 (LInt.Line(2),OrSpine),LInt.Line(2));
97 if (P1.SquareDistance(OrSpine) < P2.SquareDistance(OrSpine)) {
100 else { OrFillet = P2;}
102 else { OrFillet = P1;}
104 else {return Standard_False;}
106 // Construction fillet
107 if (DirFillet.Dot(Spine.Direction()) < 0.) {DirFillet.Reverse();}
109 Standard_Real UOnCyl,VOnCyl,UOnPln,VOnPln;
110 ElSLib::Parameters(Cyl,OrFillet,UOnCyl,VOnCyl);
111 Standard_Real tesp = Precision::Confusion();
112 if(UOnCyl < fu - tesp || UOnCyl > lu + tesp)
113 UOnCyl = ElCLib::InPeriod(UOnCyl,fu,fu+2*PI);
114 ElSLib::Parameters(Pln,OrFillet,UOnPln,VOnPln);
116 gp_Vec XDir,OtherDir;
117 XDir = NorF.Reversed();
118 OtherDir = gp_Dir(gp_Vec(OrFillet,ElSLib::Value(UOnCyl,VOnCyl,Cyl)));
125 gp_Ax3 AxFil (OrFillet,DirFillet,XDir);
126 // construction YDir to go from face1 to face2.
127 if ((XDir^OtherDir).Dot(DirFillet) < 0.)
130 Handle(Geom_CylindricalSurface)
131 Fillet = new Geom_CylindricalSurface(AxFil,Radius);
132 Data->ChangeSurf(ChFiKPart_IndexSurfaceInDS(Fillet,DStr));
134 // FaceInterferences are loaded with pcurves and curves 3D.
136 gp_Pnt2d PPln2d(UOnPln,VOnPln);
137 gp_Dir2d VPln2d(DirFillet.Dot(AxPln.XDirection()),
138 DirFillet.Dot(AxPln.YDirection()));
139 gp_Lin2d Lin2dPln(PPln2d,VPln2d);
140 gp_Pnt POnPln = ElSLib::Value(UOnPln,VOnPln,Pln);
141 gp_Lin C3d(POnPln,DirFillet);
142 Standard_Real UOnFillet,V;
143 ElSLib::CylinderParameters(AxFil,Radius,POnPln,UOnFillet,V);
144 if(UOnFillet > PI) UOnFillet = 0.;
145 gp_Lin2d LOnFillet(gp_Pnt2d(UOnFillet,V),gp::DY2d());
146 Handle(Geom_Line) L3d = new Geom_Line (C3d);
147 Handle(Geom2d_Line) LFac = new Geom2d_Line(Lin2dPln);
148 Handle(Geom2d_Line) LFil = new Geom2d_Line(LOnFillet);
151 ElSLib::CylinderD1(UOnFillet,V,AxFil,Radius,P,deru,derv);
152 gp_Dir NorFil(deru.Crossed(derv));
153 Standard_Boolean toreverse = ( NorFil.Dot(NorPln) <= 0. );
154 // It is checked if the orientation of the cylinder is the same as of the plane.
155 if (toreverse) {Data->ChangeOrientation() = TopAbs::Reverse(Ofpl);}
156 else {Data->ChangeOrientation() = Ofpl;}
158 TopAbs_Orientation trans;
159 if ((toreverse && plandab) || (!toreverse && !plandab) ){
160 trans = TopAbs_REVERSED;
163 trans = TopAbs_FORWARD;
166 Data->ChangeInterferenceOnS1().
167 SetInterference(ChFiKPart_IndexCurveInDS(L3d,DStr),
170 Data->ChangeInterferenceOnS2().
171 SetInterference(ChFiKPart_IndexCurveInDS(L3d,DStr),
174 // edge cylinder-Fillet.
175 gp_Pnt2d PCyl2d(UOnCyl,VOnCyl);
176 gp_Dir2d DPC = gp::DY2d();
177 if (DirFillet.Dot(AxCyl.Direction()) < 0.) DPC.Reverse();
178 gp_Lin2d Lin2dCyl(PCyl2d,DPC);
179 gp_Pnt POnCyl = ElSLib::Value(UOnCyl,VOnCyl,Cyl);
180 C3d = gp_Lin(POnCyl,DirFillet);
181 ElSLib::CylinderParameters(AxFil,Radius,POnCyl,UOnFillet,V);
182 if(UOnFillet > PI) UOnFillet = 0.;
183 LOnFillet = gp_Lin2d(gp_Pnt2d(UOnFillet,V),gp::DY2d());
184 L3d = new Geom_Line (C3d);
185 LFac = new Geom2d_Line(Lin2dCyl);
186 LFil = new Geom2d_Line(LOnFillet);
188 ElSLib::CylinderD1(UOnFillet,V,AxFil,Radius,P,deru,derv);
189 NorFil= gp_Dir(deru.Crossed(derv));
190 ElSLib::CylinderD1(UOnCyl,VOnCyl,AxCyl,Cyl.Radius(),P,deru,derv);
191 gp_Dir NorCyl(deru.Crossed(derv));
193 toreverse = ( NorFil.Dot(NorCyl) <= 0. );
194 if ((toreverse && plandab) || (!toreverse && !plandab) ){
195 trans = TopAbs_FORWARD;
198 trans = TopAbs_REVERSED;
201 Data->ChangeInterferenceOnS2().
202 SetInterference(ChFiKPart_IndexCurveInDS(L3d,DStr),
205 Data->ChangeInterferenceOnS1().
206 SetInterference(ChFiKPart_IndexCurveInDS(L3d,DStr),
208 return Standard_True;
211 //=======================================================================
212 //function : MakeFillet
213 //purpose : case cylinder/plane or plane/cylinder.
214 //=======================================================================
216 Standard_Boolean ChFiKPart_MakeFillet(TopOpeBRepDS_DataStructure& DStr,
217 const Handle(ChFiDS_SurfData)& Data,
219 const gp_Cylinder& Cyl,
220 const Standard_Real fu,
221 const Standard_Real lu,
222 const TopAbs_Orientation Or1,
223 const TopAbs_Orientation Or2,
224 const Standard_Real Radius,
225 const gp_Circ& Spine,
226 const Standard_Real First,
227 const TopAbs_Orientation Ofpl,
228 const Standard_Boolean plandab)
231 //calculation of the fillet (torus or sphere).
232 Standard_Boolean c1sphere = Standard_False;
233 gp_Ax3 PosPl = Pln.Position();
234 gp_Dir Dpnat = PosPl.XDirection().Crossed(PosPl.YDirection());
237 if (Or1 == TopAbs_REVERSED) { Dp.Reverse(); }
238 if (Ofpl == TopAbs_REVERSED) { Df.Reverse(); }
240 gp_Pnt Or = Cyl.Location();
242 ElSLib::PlaneParameters(PosPl,Or,u,v);
243 gp_Pnt2d c2dPln(u,v);
244 ElSLib::PlaneD0(u,v,PosPl,Or);
246 Or.SetCoord(Or.X()+Radius*Dp.X(),
247 Or.Y()+Radius*Dp.Y(),
248 Or.Z()+Radius*Dp.Z());
251 // Modification for the PtSp found at the wrong side of the sewing edge.
254 Standard_Real acote = 1e-7;
255 ElCLib::D1(First,Spine,PtSp,DSp);
256 ElSLib::Parameters(Cyl,PtSp,u,v);
257 if ((Abs(u)<acote) || (Abs(u-(2*PI))<acote)){
258 ElCLib::D1(First+0.2,Spine,PtSp2,DSp2);
260 ElSLib::Parameters(Cyl,PtSp2,u2,v2);
263 PtSp = ElSLib::Value(u,v,Cyl);
265 PR = ElCLib::Parameter(Spine,PtSp);
266 ElCLib::D1(PR,Spine,PtSp2,DSp);
270 gp_Dir Dx(gp_Vec(Or,PtSp));
271 Dx = Dp.Crossed(Dx.Crossed(Dp));
275 ElSLib::D1(u,v,Cyl,PtCyl,Vu,Vv);
276 gp_Dir Dc(Vu.Crossed(Vv));
277 if (Or2 == TopAbs_REVERSED) { Dc.Reverse(); }
279 Standard_Real Rad,cylrad = Cyl.Radius();
280 Standard_Boolean dedans = (Dx.Dot(Dc) <= 0.);
282 if (!plandab){ Dz.Reverse(); }
283 Rad = cylrad - Radius;
284 if(Abs(Rad) <= Precision::Confusion()){ c1sphere = Standard_True; }
287 cout<<"the fillet can't pass"<<endl;
289 return Standard_False;
293 if (plandab){ Dz.Reverse(); }
294 Rad = cylrad + Radius;
296 gp_Ax3 FilAx3(Or,Dz,Dx);
297 if (FilAx3.YDirection().Dot(Dy) <= 0.){ FilAx3.YReverse(); }
300 Handle(Geom_SphericalSurface)
301 gsph = new Geom_SphericalSurface(FilAx3,Radius);
302 Data->ChangeSurf(ChFiKPart_IndexSurfaceInDS(gsph,DStr));
305 Handle(Geom_ToroidalSurface)
306 gtor = new Geom_ToroidalSurface(FilAx3,Rad,Radius);
307 Data->ChangeSurf(ChFiKPart_IndexSurfaceInDS(gtor,DStr));
310 // It is checked if the orientation of the fillet is the same as of faces.
313 P.SetCoord(cPln.X()+Rad*Dx.X(),
315 cPln.Z()+Rad*Dx.Z());
317 if ((dedans && plandab) || (!dedans && !plandab)){
318 if (c1sphere) { v = - PI / 2; }
319 else { v = 3 * PI / 2; }
324 ElSLib::SphereD1(u,v,FilAx3,cylrad,PP,deru,derv);
325 norFil = FilAx3.XDirection().Crossed(FilAx3.YDirection());
326 if(v < 0.) norFil.Reverse();
329 ElSLib::TorusD1(u,v,FilAx3,Rad,Radius,PP,deru,derv);
330 norFil = gp_Dir(deru.Crossed(derv));
332 gp_Pnt2d p2dFil(0.,v);
333 Standard_Boolean toreverse = ( norFil.Dot(Df) <= 0. );
334 if (toreverse) { Data->ChangeOrientation() = TopAbs_REVERSED; }
335 else { Data->ChangeOrientation() = TopAbs_FORWARD; }
337 // FaceInterferences are loaded with pcurves and curves 3d.
340 Handle(Geom2d_Circle) GCirc2dPln;
341 Handle(Geom_Circle) GCircPln;
342 gp_Ax2 circAx2 = FilAx3.Ax2();
344 ElSLib::PlaneParameters(PosPl,P,u,v);
345 gp_Pnt2d p2dPln(u,v);
346 gp_Dir2d d2d(DSp.Dot(PosPl.XDirection()),DSp.Dot(PosPl.YDirection()));
347 gp_Ax22d ax2dPln(c2dPln,gp_Dir2d(gp_Vec2d(c2dPln,p2dPln)),d2d);
348 gp_Circ2d circ2dPln(ax2dPln,Rad);
349 GCirc2dPln = new Geom2d_Circle(circ2dPln);
350 circAx2.SetLocation(cPln);
351 gp_Circ circPln(circAx2,Rad);
352 GCircPln = new Geom_Circle(circPln);
355 ElSLib::PlaneParameters(PosPl,P,u,v);
356 gp_Pnt2d p2dPln(u,v),pbid;
358 Data->Set2dPoints(p2dPln,p2dPln,pbid,pbid);
361 Data->Set2dPoints(pbid,pbid,p2dPln,p2dPln);
364 gp_Lin2d lin2dFil(p2dFil,gp::DX2d());
365 Handle(Geom2d_Line) GLin2dFil1 = new Geom2d_Line(lin2dFil);
366 toreverse = ( norFil.Dot(Dpnat) <= 0. );
367 TopAbs_Orientation trans;
368 if ((toreverse && plandab) || (!toreverse && !plandab) ){
369 trans = TopAbs_FORWARD;
372 trans = TopAbs_REVERSED;
375 Data->ChangeInterferenceOnS1().
376 SetInterference(ChFiKPart_IndexCurveInDS(GCircPln,DStr),
377 trans,GCirc2dPln,GLin2dFil1);
380 Data->ChangeInterferenceOnS2().
381 SetInterference(ChFiKPart_IndexCurveInDS(GCircPln,DStr),
382 trans,GCirc2dPln,GLin2dFil1);
385 // The cylindrical face.
386 P.SetCoord(Or.X()+cylrad*Dx.X(),
387 Or.Y()+cylrad*Dx.Y(),
388 Or.Z()+cylrad*Dx.Z());
391 if (plandab && !c1sphere) { v = 2 * PI; }
395 p2dFil.SetCoord(u,v);
397 ElSLib::SphereD1(u,v,FilAx3,cylrad,PP,deru,derv);
400 ElSLib::TorusD1(u,v,FilAx3,Rad,Radius,PP,deru,derv);
402 norFil = deru.Crossed(derv);
403 lin2dFil.SetLocation(p2dFil);
404 Handle(Geom2d_Line) GLin2dFil2 = new Geom2d_Line(lin2dFil);
405 ElSLib::Parameters(Cyl,P,u,v);
406 Standard_Real tol = Precision::PConfusion();
407 Standard_Boolean careaboutsens = 0;
408 if(Abs(lu - fu - 2*PI) < tol) careaboutsens = 1;
409 if(u >= fu - tol && u < fu) u = fu;
410 if(u <= lu + tol && u > lu) u = lu;
411 if(u < fu || u > lu) u = ChFiKPart_InPeriod(u,fu,fu + 2*PI,tol);
412 ElSLib::D1(u,v,Cyl,PP,deru,derv);
413 gp_Dir norcyl = deru.Crossed(derv);
414 gp_Dir2d d2dCyl = gp::DX2d();
415 if( deru.Dot(Dy) < 0. ){
417 if(careaboutsens && Abs(fu-u)<tol) u = lu;
419 else if(careaboutsens && Abs(lu-u)<tol) u = fu;
420 gp_Pnt2d p2dCyl(u,v);
421 gp_Lin2d lin2dCyl(p2dCyl,d2dCyl);
422 Handle(Geom2d_Line) GLin2dCyl = new Geom2d_Line(lin2dCyl);
423 circAx2.SetLocation(Or);
424 gp_Circ circCyl(circAx2,cylrad);
425 Handle(Geom_Circle) GCircCyl = new Geom_Circle(circCyl);
426 toreverse = ( norFil.Dot(norcyl) <= 0. );
427 if ((toreverse && plandab) || (!toreverse && !plandab) ){
428 trans = TopAbs_REVERSED;
431 trans = TopAbs_FORWARD;
434 Data->ChangeInterferenceOnS2().
435 SetInterference(ChFiKPart_IndexCurveInDS(GCircCyl,DStr),
436 trans,GLin2dCyl,GLin2dFil2);
440 Data->ChangeInterferenceOnS1().
441 SetInterference(ChFiKPart_IndexCurveInDS(GCircCyl,DStr),
442 trans,GLin2dCyl,GLin2dFil2);
444 return Standard_True;