b311480e |
1 | // Created on: 1995-05-30 |
2 | // Created by: Stagiaire Flore Lantheaume |
3 | // Copyright (c) 1995-1999 Matra Datavision |
4 | // Copyright (c) 1999-2012 OPEN CASCADE SAS |
5 | // |
6 | // The content of this file is subject to the Open CASCADE Technology Public |
7 | // License Version 6.5 (the "License"). You may not use the content of this file |
8 | // except in compliance with the License. Please obtain a copy of the License |
9 | // at http://www.opencascade.org and read it completely before using this file. |
10 | // |
11 | // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its |
12 | // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France. |
13 | // |
14 | // The Original Code and all software distributed under the License is |
15 | // distributed on an "AS IS" basis, without warranty of any kind, and the |
16 | // Initial Developer hereby disclaims all such warranties, including without |
17 | // limitation, any warranties of merchantability, fitness for a particular |
18 | // purpose or non-infringement. Please see the License for the specific terms |
19 | // and conditions governing the rights and limitations under the License. |
20 | |
7fd59977 |
21 | |
22 | |
23 | #include <ChFiKPart_ComputeData.jxx> |
24 | #include <Precision.hxx> |
25 | #include <gp.hxx> |
26 | #include <gp_Pnt2d.hxx> |
27 | #include <gp_Dir2d.hxx> |
28 | #include <gp_Lin2d.hxx> |
29 | |
30 | #include <gp_Dir.hxx> |
31 | #include <gp_Pnt.hxx> |
32 | #include <gp_Ax2.hxx> |
33 | #include <gp_Ax3.hxx> |
34 | #include <gp_Vec.hxx> |
35 | #include <gp_Circ.hxx> |
36 | |
37 | #include <ElCLib.hxx> |
38 | #include <ElSLib.hxx> |
39 | |
40 | #include <Geom2d_Line.hxx> |
41 | #include <Geom2d_Circle.hxx> |
42 | #include <Geom_Circle.hxx> |
43 | #include <Geom_ConicalSurface.hxx> |
44 | |
45 | #include <ChFiKPart_ComputeData_Fcts.hxx> |
46 | |
47 | #include <ChFiKPart_ComputeData_ChAsymPlnCon.hxx> |
48 | |
49 | //======================================================================= |
50 | //function : MakeChamfer |
51 | //purpose : Compute the chamfer in the particular case Plane/Cone or |
52 | // Cylinder/Plane |
53 | // Compute the SurfData <Data> of the chamfer build on the <Spine> |
54 | // between the plane <Pln> and the cone <Con>, with the |
55 | // distances <Dis1> on <Pln> and <Dis2> on <Con>. |
56 | // <Or1> and <Or2> are the orientations of <Pln> and <Con> |
57 | // and <Ofpl> this of the face carried by <Pln>. |
58 | // <First> is the start point on the <Spine> |
59 | // <Plandab> is equal to True if the plane is the surface S1 |
60 | // <fu> and <lu> are the first and last u parameters of the |
61 | // cone |
62 | //out : True if the chanfer has been computed |
63 | // False else |
64 | //======================================================================= |
65 | |
66 | Standard_Boolean ChFiKPart_MakeChamfer(TopOpeBRepDS_DataStructure& DStr, |
67 | const Handle(ChFiDS_SurfData)& Data, |
68 | const gp_Pln& Pln, |
69 | const gp_Cone& Con, |
70 | const Standard_Real fu, |
71 | const Standard_Real lu, |
72 | const TopAbs_Orientation Or1, |
73 | const TopAbs_Orientation Or2, |
74 | const Standard_Real Dis1, |
75 | const Standard_Real Dis2, |
76 | const gp_Circ& Spine, |
77 | const Standard_Real First, |
78 | const TopAbs_Orientation Ofpl, |
79 | const Standard_Boolean plandab) |
80 | { |
81 | |
82 | Standard_Real angcon = Con.SemiAngle(); |
83 | Standard_Real sincon =Abs(Sin(angcon)); |
84 | Standard_Real angle; |
85 | Standard_Boolean IsResol; |
86 | |
87 | gp_Ax3 PosPl = Pln.Position(); |
88 | gp_Dir Dpl = PosPl.XDirection().Crossed(PosPl.YDirection()); |
89 | if ( Or1 == TopAbs_REVERSED ) Dpl.Reverse(); |
90 | |
91 | // compute the origin of the conical chamfer PtPl |
92 | gp_Pnt Or = Con.Location(); |
93 | Standard_Real u,v; |
94 | ElSLib::PlaneParameters(PosPl,Or,u,v); |
95 | #ifdef DEB |
96 | gp_Pnt2d pt2dPln(u,v); |
97 | #endif |
98 | ElSLib::PlaneD0(u,v,PosPl,Or); |
99 | |
100 | gp_Pnt PtSp; |
101 | gp_Vec DSp; |
102 | ElCLib::D1(First,Spine,PtSp,DSp); |
103 | #ifdef DEB |
104 | gp_Dir Dx(gp_Vec(Or,PtSp)); |
105 | #endif |
106 | //compute the normal to the cone in PtSp |
107 | gp_Vec deru,derv; |
108 | gp_Pnt PtCon; |
109 | ElSLib::Parameters(Con,PtSp,u,v); |
110 | ElSLib::D1(u,v,Con,PtCon ,deru,derv); |
111 | gp_Dir Dcon( deru.Crossed(derv) ); |
112 | if ( Or2 == TopAbs_REVERSED ) Dcon.Reverse(); |
113 | |
114 | Standard_Boolean ouvert = ( Dpl.Dot(Dcon) >= 0.); |
115 | |
116 | if (!ouvert) { |
117 | if (Abs(Dis1 - Dis2 * sincon) > Precision::Confusion()) { |
118 | Standard_Real abscos = Abs(Dis2 - Dis1 * sincon); |
119 | angle = ATan((Dis1 * Cos(angcon)) / abscos); |
120 | } |
121 | else { |
122 | angle = angcon; |
123 | } |
124 | } |
125 | else { |
126 | angle = ATan((Dis1 * Cos(angcon)) / (Dis2 + Dis1 * sincon)); |
127 | } |
128 | |
129 | Standard_Boolean DisOnP = Standard_False; |
130 | |
131 | IsResol = ChFiKPart_MakeChAsym(DStr, Data, Pln, Con, fu, lu, Or1, Or2, |
132 | Dis2, angle, Spine, First, Ofpl, plandab, DisOnP); |
133 | |
134 | return IsResol; |
135 | |
136 | } |
137 | |
138 | /* |
139 | // Compute the chamfer surface(cone) |
140 | gp_Ax3 PosPl = Pln.Position(); |
141 | gp_Dir Dpl = PosPl.XDirection().Crossed(PosPl.YDirection()); |
142 | gp_Dir norf = Dpl; |
143 | if (Ofpl == TopAbs_REVERSED ) norf.Reverse(); |
144 | if ( Or1 == TopAbs_REVERSED ) Dpl.Reverse(); |
145 | |
146 | // compute the origin of the conical chamfer PtPl |
147 | gp_Pnt Or = Con.Location(); |
148 | Standard_Real u,v; |
149 | ElSLib::PlaneParameters(PosPl,Or,u,v); |
150 | gp_Pnt2d pt2dPln(u,v); |
151 | ElSLib::PlaneD0(u,v,PosPl,Or); |
152 | gp_Pnt PtPl = Or; |
153 | |
154 | gp_Pnt PtSp; |
155 | gp_Vec DSp; |
156 | ElCLib::D1(First,Spine,PtSp,DSp); |
157 | gp_Dir Dx(gp_Vec(PtPl,PtSp)); |
158 | |
159 | //compute the normal to the cone in PtSp |
160 | gp_Vec deru,derv; |
161 | gp_Pnt PtCon; |
162 | ElSLib::Parameters(Con,PtSp,u,v); |
163 | ElSLib::D1(u,v,Con,PtCon ,deru,derv); |
164 | gp_Dir Dcon( deru.Crossed(derv) ); |
165 | if ( Or2 == TopAbs_REVERSED ) Dcon.Reverse(); |
166 | |
167 | Standard_Boolean dedans = ( Dx.Dot(Dcon) <= 0.); |
168 | Standard_Boolean ouvert = ( Dpl.Dot(Dcon) >= 0.); |
169 | |
170 | // variables used to compute the semiangle of the chamfer |
171 | Standard_Real angle = Con.SemiAngle(); |
172 | Standard_Real move = Dis2 * Cos(angle); |
173 | Or.SetCoord( Or.X()+ move*Dpl.X(), |
174 | Or.Y()+ move*Dpl.Y(), |
175 | Or.Z()+ move*Dpl.Z()); |
176 | |
177 | gp_Dir Vec1(Or.X()-PtPl.X(), Or.Y()-PtPl.Y(), Or.Z()-PtPl.Z()); |
178 | Standard_Real Dis; |
179 | if (ouvert) |
180 | Dis = Dis1 + Dis2*Abs(Sin(angle)); |
181 | else |
182 | Dis = Dis1 - Dis2*Abs(Sin(angle)); |
183 | |
184 | gp_Pnt Pt(Or.X()+Dis*PosPl.XDirection().X(), |
185 | Or.Y()+Dis*PosPl.XDirection().Y(), |
186 | Or.Z()+Dis*PosPl.XDirection().Z()); |
187 | gp_Dir Vec2( Pt.X()-PtPl.X(), Pt.Y()-PtPl.Y(), Pt.Z()-PtPl.Z()); |
188 | |
189 | // compute the parameters of the conical chamfer |
190 | Standard_Real ChamfRad,SemiAngl; |
191 | Standard_Boolean pointu = Standard_False; |
192 | |
193 | if (dedans) { |
194 | ChamfRad = Spine.Radius() - Dis1; |
195 | if ( Abs(ChamfRad)<=Precision::Confusion() ) pointu = Standard_True; |
196 | if( ChamfRad < 0 ) { |
197 | #ifdef DEB |
198 | cout<<"le chanfrein ne passe pas"<<endl; |
199 | #endif |
200 | return Standard_False; |
201 | } |
202 | } |
203 | else { |
204 | ChamfRad = Spine.Radius() + Dis1; |
205 | gp_Dir Dplr = Dpl.Reversed(); |
206 | Dpl = Dplr; |
207 | } |
208 | |
209 | gp_Ax3 ChamfAx3(PtPl,Dpl,Dx); |
210 | SemiAngl = Vec1.Angle(Vec2); |
211 | |
212 | Handle (Geom_ConicalSurface) |
213 | gcon = new Geom_ConicalSurface( ChamfAx3, SemiAngl, ChamfRad ); |
214 | |
215 | // changes due to the fact the parameters of the chamfer must go increasing |
216 | // from surface S1 to surface S2 |
217 | if ( (dedans && !plandab) || (!dedans && plandab) ) { |
218 | gcon->VReverse();// be carefull : the SemiAngle was changed |
219 | ChamfAx3 = gcon->Position(); |
220 | SemiAngl = gcon->SemiAngle(); |
221 | } |
222 | |
223 | // changes due to the fact we have reversed the V direction of |
224 | // parametrization |
225 | if (ChamfAx3.YDirection().Dot(DSp) <= 0.) { |
226 | ChamfAx3.YReverse(); |
227 | gcon->SetPosition(ChamfAx3); |
228 | } |
229 | |
230 | Data->ChangeSurf(ChFiKPart_IndexSurfaceInDS(gcon,DStr)); |
231 | |
232 | |
233 | //compute the chamfer's orientation according to the orientation |
234 | // of the faces |
235 | |
236 | //search the normal to the conical chamfer |
237 | gp_Pnt P; |
238 | u=0.; |
239 | if (plandab) |
240 | v = sqrt(Dis*Dis + move*move); |
241 | else |
242 | v = - sqrt(Dis*Dis + move*move); |
243 | ElSLib::ConeD1(u,v,ChamfAx3,ChamfRad,SemiAngl,P,deru,derv); |
244 | gp_Dir norchamf(deru.Crossed(derv)); |
245 | |
246 | Standard_Boolean toreverse = (norf.Dot(norchamf)<= 0.); |
247 | |
248 | if (toreverse) |
249 | Data->ChangeOrientation() = TopAbs_REVERSED; |
250 | else |
251 | Data->ChangeOrientation() = TopAbs_FORWARD; |
252 | |
253 | |
254 | //we load the faceInterference with the pcurves and |
255 | // the 3d curves |
256 | |
257 | // Case of the plane face |
258 | // NB: in the case 'pointu', no pcurve on the plane surface |
259 | // and no intersection plane-chamfer are needed |
260 | |
261 | // intersection plane-chamfer |
262 | Handle(Geom_Circle) GCirPln; |
263 | Handle(Geom2d_Circle) GCir2dPln; |
264 | gp_Ax2 CirAx2 = ChamfAx3.Ax2(); |
265 | CirAx2.SetLocation(PtPl); |
266 | |
267 | if (!pointu) { |
268 | Pt.SetCoord(PtPl.X()+ChamfRad*Dx.X(), |
269 | PtPl.Y()+ChamfRad*Dx.Y(), |
270 | PtPl.Z()+ChamfRad*Dx.Z()); |
271 | gp_Circ CirPln(CirAx2,ChamfRad); |
272 | GCirPln = new Geom_Circle(CirPln); |
273 | |
274 | //pcurve on the plane |
275 | ElSLib::PlaneParameters(PosPl,Pt ,u,v); |
276 | gp_Pnt2d p2dPln(u,v); |
277 | gp_Dir2d d2d(DSp.Dot(PosPl.XDirection()),DSp.Dot(PosPl.YDirection())); |
278 | gp_Ax22d ax2dPln(pt2dPln, gp_Dir2d(gp_Vec2d(pt2dPln,p2dPln)),d2d); |
279 | gp_Circ2d cir2dPln(ax2dPln,ChamfRad); |
280 | GCir2dPln = new Geom2d_Circle(cir2dPln); |
281 | } |
282 | |
283 | //pcurve on chamfer |
284 | gp_Pnt2d p2dch; |
285 | p2dch.SetCoord(0.,0.); |
286 | ElSLib::ConeD1(0.,0.,ChamfAx3,ChamfRad,SemiAngl,Pt,deru,derv); |
287 | gp_Lin2d lin2dch(p2dch,gp::DX2d()); |
288 | Handle(Geom2d_Line) GLin2dCh1 = new Geom2d_Line(lin2dch); |
289 | |
290 | //orientation |
291 | TopAbs_Orientation trans; |
292 | gp_Dir norpl = PosPl.XDirection().Crossed(PosPl.YDirection()); |
293 | if (!pointu) |
294 | norchamf.SetXYZ (deru.Crossed(derv).XYZ()); |
295 | toreverse = ( norchamf.Dot(norpl) <= 0. ); |
296 | if ((toreverse && plandab) || (!toreverse && !plandab)){ |
297 | trans = TopAbs_FORWARD; |
298 | } |
299 | else { |
300 | trans = TopAbs_REVERSED; |
301 | } |
302 | |
303 | if(plandab){ |
304 | Data->ChangeInterferenceOnS1(). |
305 | SetInterference(ChFiKPart_IndexCurveInDS(GCirPln,DStr), |
306 | trans,GCir2dPln,GLin2dCh1); |
307 | } |
308 | else{ |
309 | Data->ChangeInterferenceOnS2(). |
310 | SetInterference(ChFiKPart_IndexCurveInDS(GCirPln,DStr), |
311 | trans,GCir2dPln,GLin2dCh1); |
312 | } |
313 | |
314 | |
315 | // Case of the conical face |
316 | |
317 | //intersection cone-chamfer |
318 | Standard_Real Rad; |
319 | if (dedans) |
320 | Rad = ChamfRad + Dis; |
321 | else |
322 | Rad = ChamfRad - Dis; |
323 | |
324 | CirAx2.SetLocation(Or); |
325 | gp_Circ CirCon(CirAx2, Rad); |
326 | Handle(Geom_Circle) GCirCon = new Geom_Circle(CirCon); |
327 | |
328 | //pcurve on chamfer |
329 | if (plandab) |
330 | v = sqrt(Dis*Dis + move*move); |
331 | else |
332 | v = - sqrt(Dis*Dis + move*move); |
333 | p2dch.SetCoord(0.,v); |
334 | ElSLib::ConeD1(0.,v,ChamfAx3,ChamfRad,SemiAngl,Pt,deru,derv); |
335 | lin2dch.SetLocation(p2dch); |
336 | Handle(Geom2d_Line) GLin2dCh2 = new Geom2d_Line(lin2dch); |
337 | |
338 | //pcurve on cone |
339 | norchamf.SetXYZ (deru.Crossed(derv).XYZ()); |
340 | |
341 | Pt.SetCoord(Or.X()+Rad*Dx.X(), |
342 | Or.Y()+Rad*Dx.Y(), |
343 | Or.Z()+Rad*Dx.Z()); |
344 | ElSLib::Parameters(Con,Pt ,u,v); |
345 | Standard_Real tol = Precision::PConfusion(); |
c6541a0c |
346 | if(u >= 2*M_PI - tol && u <= 2*M_PI) u = 0.; |
7fd59977 |
347 | if(u >= fu - tol && u < fu) u = fu; |
348 | if(u <= lu + tol && u > lu) u = lu; |
c6541a0c |
349 | if(u < fu || u > lu) u = ElCLib::InPeriod(u,fu,fu + 2*M_PI); |
7fd59977 |
350 | ElSLib::D1(u,v,Con,Pt,deru,derv); |
351 | gp_Pnt2d p2dCon(u,v); |
352 | gp_Dir2d d2dCon; |
353 | if ( deru.Dot(DSp)<=0. ) |
354 | d2dCon = - gp::DX2d(); |
355 | else |
356 | d2dCon = gp::DX2d(); |
357 | gp_Lin2d lin2dCon(p2dCon,d2dCon); |
358 | Handle(Geom2d_Line) GLin2dCon = new Geom2d_Line(lin2dCon); |
359 | |
360 | //orientation |
361 | gp_Dir norcon = deru.Crossed(derv); |
362 | toreverse = ( norchamf.Dot(norcon) <= 0. ); |
363 | if ((toreverse && plandab) || (!toreverse && !plandab) ) { |
364 | trans = TopAbs_REVERSED; |
365 | } |
366 | else { |
367 | trans = TopAbs_FORWARD; |
368 | } |
369 | |
370 | if(plandab){ |
371 | Data->ChangeInterferenceOnS2(). |
372 | SetInterference(ChFiKPart_IndexCurveInDS(GCirCon,DStr), |
373 | trans,GLin2dCon,GLin2dCh2); |
374 | } |
375 | else{ |
376 | Data->ChangeInterferenceOnS1(). |
377 | SetInterference(ChFiKPart_IndexCurveInDS(GCirCon,DStr), |
378 | trans,GLin2dCon,GLin2dCh2); |
379 | } |
380 | |
381 | |
382 | return Standard_True; |
383 | } |
384 | |
385 | */ |
386 | |
387 | |
388 | |
389 | |
390 | |
391 | |