7fd59977 |
1 | // File: ChFiKPart_CompData_PlnCon.cxx |
2 | // Created: Thu Feb 3 15:04:25 1994 |
3 | // Author: Isabelle GRIGNON |
4 | // <isg@zerox> |
5 | |
6 | #include <ChFiKPart_ComputeData.jxx> |
7 | #include <Precision.hxx> |
8 | #include <gp.hxx> |
9 | #include <gp_Pnt2d.hxx> |
10 | #include <gp_Dir2d.hxx> |
11 | #include <gp_Lin2d.hxx> |
12 | #include <gp_Pnt.hxx> |
13 | #include <gp_Dir.hxx> |
14 | #include <gp_Vec.hxx> |
15 | #include <gp_Lin.hxx> |
16 | #include <gp_Ax2.hxx> |
17 | #include <gp_Ax3.hxx> |
18 | #include <gp_Circ.hxx> |
19 | #include <gp_Pln.hxx> |
20 | #include <gp_Cone.hxx> |
21 | |
22 | #include <ElCLib.hxx> |
23 | #include <ElSLib.hxx> |
24 | |
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 | |
32 | #include <IntAna_QuadQuadGeo.hxx> |
33 | |
34 | #include <ChFiKPart_ComputeData_Fcts.hxx> |
35 | |
36 | //======================================================================= |
37 | //function : MakeFillet |
81bba717 |
38 | //purpose : case cone/plane or plane/cone. |
7fd59977 |
39 | //======================================================================= |
40 | |
41 | Standard_Boolean ChFiKPart_MakeFillet(TopOpeBRepDS_DataStructure& DStr, |
42 | const Handle(ChFiDS_SurfData)& Data, |
43 | const gp_Pln& Pln, |
44 | const gp_Cone& Con, |
45 | const Standard_Real fu, |
46 | const Standard_Real lu, |
47 | const TopAbs_Orientation Or1, |
48 | const TopAbs_Orientation Or2, |
49 | const Standard_Real Radius, |
50 | const gp_Circ& Spine, |
51 | const Standard_Real First, |
52 | const TopAbs_Orientation Ofpl, |
53 | const Standard_Boolean plandab) |
54 | { |
81bba717 |
55 | //calculate the fillet (torus or sphere). |
7fd59977 |
56 | Standard_Boolean c1sphere = Standard_False; |
57 | gp_Ax3 PosPl = Pln.Position(); |
58 | gp_Dir Dpnat = PosPl.XDirection().Crossed(PosPl.YDirection()); |
59 | gp_Dir Dp = Dpnat; |
60 | gp_Dir Df = Dp; |
61 | if (Or1 == TopAbs_REVERSED) { Dp.Reverse(); } |
62 | if (Ofpl == TopAbs_REVERSED) { Df.Reverse(); } |
63 | |
64 | gp_Pnt Or = Con.Location(); |
65 | Standard_Real u,v; |
66 | ElSLib::PlaneParameters(PosPl,Or,u,v); |
67 | gp_Pnt2d c2dPln(u,v); |
68 | ElSLib::PlaneD0(u,v,PosPl,Or); |
69 | gp_Pnt cPln = Or; |
70 | Or.SetCoord(Or.X()+Radius*Dp.X(), |
71 | Or.Y()+Radius*Dp.Y(), |
72 | Or.Z()+Radius*Dp.Z()); |
73 | |
74 | gp_Pnt PtSp; |
75 | gp_Vec DSp; |
76 | ElCLib::D1(First,Spine,PtSp,DSp); |
77 | IntAna_QuadQuadGeo CInt (Pln,Con,Precision::Angular(), |
78 | Precision::Confusion()); |
79 | gp_Pnt Pv; |
80 | if (CInt.IsDone()) { |
81bba717 |
81 | //The origin of the fillet is set at the start point on the |
82 | //guideline. |
7fd59977 |
83 | Pv = ElCLib::Value(ElCLib::Parameter(CInt.Circle(1),PtSp), |
84 | CInt.Circle(1)); |
85 | } |
86 | else { return Standard_False; } |
87 | gp_Dir Dx(gp_Vec(cPln,Pv)); |
88 | gp_Dir Dy(DSp); |
89 | ElSLib::Parameters(Con,Pv,u,v); |
90 | gp_Pnt PtCon; |
91 | gp_Vec Vu,Vv; |
92 | ElSLib::D1(u,v,Con,PtCon,Vu,Vv); |
93 | gp_Dir Dc(Vu.Crossed(Vv)); |
94 | if (Or2 == TopAbs_REVERSED) { Dc.Reverse(); } |
95 | gp_Dir Dz = Dp; |
96 | |
97 | gp_Pnt pp(Pv.X()+Dc.X(),Pv.Y()+Dc.Y(),Pv.Z()+Dc.Z()); |
98 | ElSLib::PlaneParameters(PosPl,pp,u,v); |
99 | ElSLib::PlaneD0(u,v,PosPl,pp); |
100 | gp_Dir ddp(gp_Vec(Pv,pp)); |
101 | ElSLib::Parameters(Con,Pv,u,v); |
102 | gp_Vec dcu,dcv; |
103 | ElSLib::D1(u,v,Con,pp,dcu,dcv); |
104 | gp_Dir ddc(dcv); |
105 | if(ddc.Dot(Dp) < 0.) ddc.Reverse(); |
106 | Standard_Real Ang = ddp.Angle(ddc); |
107 | Standard_Real Rabio = Radius/Tan(Ang/2); |
108 | Standard_Real Maxrad = cPln.Distance(Pv); |
109 | Standard_Real Rad; |
110 | Standard_Boolean dedans = Dx.Dot(Dc) <= 0. ; |
111 | if( dedans ){ |
112 | if (!plandab){ Dz.Reverse(); } |
113 | Rad = Maxrad - Rabio; |
114 | if(Abs(Rad) <= Precision::Confusion()){ c1sphere = Standard_True; } |
115 | else if(Rad < 0){ |
81bba717 |
116 | cout<<"the fillet does not pass"<<endl; |
7fd59977 |
117 | return Standard_False; |
118 | } |
119 | } |
120 | else { |
121 | if (plandab){ Dz.Reverse(); } |
122 | Rad = Maxrad + Rabio; |
123 | } |
124 | gp_Ax3 FilAx3(Or,Dz,Dx); |
125 | if (FilAx3.YDirection().Dot(Dy) <= 0.){ FilAx3.YReverse(); } |
126 | |
127 | if(c1sphere) { |
128 | Handle(Geom_SphericalSurface) |
129 | gsph = new Geom_SphericalSurface(FilAx3,Radius); |
130 | Data->ChangeSurf(ChFiKPart_IndexSurfaceInDS(gsph,DStr)); |
131 | } |
132 | else{ |
133 | Handle(Geom_ToroidalSurface) |
134 | gtor = new Geom_ToroidalSurface(FilAx3,Rad,Radius); |
135 | Data->ChangeSurf(ChFiKPart_IndexSurfaceInDS(gtor,DStr)); |
136 | } |
137 | |
81bba717 |
138 | // It is checked if the orientation of the fillet is the same |
139 | // as of the faces. |
7fd59977 |
140 | gp_Pnt P,PP; |
141 | gp_Vec deru,derv; |
142 | P.SetCoord(cPln.X()+Rad*Dx.X(), |
143 | cPln.Y()+Rad*Dx.Y(), |
144 | cPln.Z()+Rad*Dx.Z()); |
145 | if(c1sphere){ |
146 | ElSLib::SphereParameters(FilAx3,Rad,P,u,v); |
147 | ElSLib::SphereD1(u,v,FilAx3,Rad,PP,deru,derv); |
148 | } |
149 | else{ |
150 | ElSLib::TorusParameters(FilAx3,Rad,Radius,P,u,v); |
151 | ElSLib::TorusD1(u,v,FilAx3,Rad,Radius,PP,deru,derv); |
152 | if(!plandab && Ang < PI/2 && dedans) v = v + 2*PI; |
153 | } |
154 | gp_Pnt2d p2dFil(0.,v); |
155 | gp_Dir norFil(deru.Crossed(derv)); |
156 | Standard_Boolean toreverse = ( norFil.Dot(Df) <= 0. ); |
157 | if (toreverse) { Data->ChangeOrientation() = TopAbs_REVERSED; } |
158 | else { Data->ChangeOrientation() = TopAbs_FORWARD; } |
159 | |
81bba717 |
160 | // FaceInterferences are loaded with pcurves and curves 3d. |
7fd59977 |
161 | // --------------------------------------------------------------- |
162 | |
81bba717 |
163 | // The plane face. |
7fd59977 |
164 | // -------------- |
165 | |
166 | Handle(Geom2d_Circle) GCirc2dPln; |
167 | Handle(Geom_Circle) GCircPln; |
168 | gp_Ax2 circAx2 = FilAx3.Ax2(); |
169 | if(!c1sphere){ |
170 | ElSLib::PlaneParameters(PosPl,P,u,v); |
171 | gp_Pnt2d p2dPln(u,v); |
172 | gp_Dir2d d2d(DSp.Dot(PosPl.XDirection()),DSp.Dot(PosPl.YDirection())); |
173 | gp_Ax22d ax2dPln(c2dPln,gp_Dir2d(gp_Vec2d(c2dPln,p2dPln)),d2d); |
174 | gp_Circ2d circ2dPln(ax2dPln,Rad); |
175 | GCirc2dPln = new Geom2d_Circle(circ2dPln); |
176 | circAx2.SetLocation(cPln); |
177 | gp_Circ circPln(circAx2,Rad); |
178 | GCircPln = new Geom_Circle(circPln); |
179 | } |
180 | gp_Lin2d lin2dFil(p2dFil,gp::DX2d()); |
181 | Handle(Geom2d_Line) GLin2dFil1 = new Geom2d_Line(lin2dFil); |
182 | toreverse = ( norFil.Dot(Dpnat) <= 0. ); |
183 | TopAbs_Orientation trans; |
184 | if ((toreverse && plandab) || (!toreverse && !plandab) ){ |
185 | trans = TopAbs_FORWARD; |
186 | } |
187 | else { |
188 | trans = TopAbs_REVERSED; |
189 | } |
190 | if(plandab){ |
191 | Data->ChangeInterferenceOnS1(). |
192 | SetInterference(ChFiKPart_IndexCurveInDS(GCircPln,DStr), |
193 | trans,GCirc2dPln,GLin2dFil1); |
194 | } |
195 | else{ |
196 | Data->ChangeInterferenceOnS2(). |
197 | SetInterference(ChFiKPart_IndexCurveInDS(GCircPln,DStr), |
198 | trans,GCirc2dPln,GLin2dFil1); |
199 | } |
200 | |
81bba717 |
201 | // The conic face. |
7fd59977 |
202 | // ---------------- |
203 | |
204 | P.SetCoord(Pv.X()+Rabio*ddc.X(), |
205 | Pv.Y()+Rabio*ddc.Y(), |
206 | Pv.Z()+Rabio*ddc.Z()); |
207 | if(c1sphere){ |
208 | ElSLib::SphereParameters(FilAx3,Radius,P,u,v); |
209 | ElSLib::SphereD1(u,v,FilAx3,Radius,PP,deru,derv); |
210 | } |
211 | else{ |
212 | ElSLib::TorusParameters(FilAx3,Rad,Radius,P,u,v); |
213 | ElSLib::TorusD1(u,v,FilAx3,Rad,Radius,PP,deru,derv); |
214 | if(plandab && Ang < PI/2 && dedans) v = v + 2*PI; |
215 | } |
216 | norFil = deru.Crossed(derv); |
217 | p2dFil.SetCoord(0.,v); |
218 | lin2dFil.SetLocation(p2dFil); |
219 | Handle(Geom2d_Line) GLin2dFil2 = new Geom2d_Line(lin2dFil); |
220 | ElSLib::Parameters(Con,P,u,v); |
221 | Standard_Real tol = Precision::PConfusion(); |
222 | Standard_Boolean careaboutsens = 0; |
223 | if(Abs(lu - fu - 2*PI) < tol) careaboutsens = 1; |
224 | if(u >= fu - tol && u < fu) u = fu; |
225 | if(u <= lu + tol && u > lu) u = lu; |
226 | if(u < fu || u > lu) u = ElCLib::InPeriod(u,fu,fu + 2*PI); |
227 | ElSLib::D1(u,v,Con,PP,deru,derv); |
228 | gp_Dir norCon = deru.Crossed(derv); |
229 | gp_Dir2d d2dCon = gp::DX2d(); |
230 | if( deru.Dot(Dy) < 0. ){ |
231 | d2dCon.Reverse(); |
232 | if(careaboutsens && Abs(fu-u)<tol) u = lu; |
233 | } |
234 | else if(careaboutsens && Abs(lu-u)<tol) u = fu; |
235 | gp_Pnt2d p2dCon(u,v); |
236 | gp_Lin2d lin2dCon(p2dCon,d2dCon); |
237 | Handle(Geom2d_Line) GLin2dCon = new Geom2d_Line(lin2dCon); |
238 | Standard_Real scal = gp_Vec(Dp).Dot(gp_Vec(Pv,P)); |
239 | PP.SetCoord(cPln.X()+scal*Dp.X(), |
240 | cPln.Y()+scal*Dp.Y(), |
241 | cPln.Z()+scal*Dp.Z()); |
242 | circAx2.SetLocation(PP); |
243 | gp_Circ circCon(circAx2,P.Distance(PP)); |
244 | Handle(Geom_Circle) GCircCon = new Geom_Circle(circCon); |
245 | toreverse = ( norFil.Dot(norCon) <= 0. ); |
246 | if ((toreverse && plandab) || (!toreverse && !plandab) ){ |
247 | trans = TopAbs_REVERSED; |
248 | } |
249 | else { |
250 | trans = TopAbs_FORWARD; |
251 | } |
252 | if(plandab){ |
253 | Data->ChangeInterferenceOnS2(). |
254 | SetInterference(ChFiKPart_IndexCurveInDS(GCircCon,DStr), |
255 | trans,GLin2dCon,GLin2dFil2); |
256 | } |
257 | else{ |
258 | Data->ChangeInterferenceOnS1(). |
259 | SetInterference(ChFiKPart_IndexCurveInDS(GCircCon,DStr), |
260 | trans,GLin2dCon,GLin2dFil2); |
261 | } |
262 | return Standard_True; |
263 | } |