b311480e |
1 | // Copyright (c) 1999-2012 OPEN CASCADE SAS |
2 | // |
3 | // The content of this file is subject to the Open CASCADE Technology Public |
4 | // License Version 6.5 (the "License"). You may not use the content of this file |
5 | // except in compliance with the License. Please obtain a copy of the License |
6 | // at http://www.opencascade.org and read it completely before using this file. |
7 | // |
8 | // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its |
9 | // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France. |
10 | // |
11 | // The Original Code and all software distributed under the License is |
12 | // distributed on an "AS IS" basis, without warranty of any kind, and the |
13 | // Initial Developer hereby disclaims all such warranties, including without |
14 | // limitation, any warranties of merchantability, fitness for a particular |
15 | // purpose or non-infringement. Please see the License for the specific terms |
16 | // and conditions governing the rights and limitations under the License. |
17 | |
7fd59977 |
18 | #include <UnitsMethods.ixx> |
19 | |
20 | #include <Geom_Plane.hxx> |
21 | #include <Geom_Surface.hxx> |
22 | #include <Geom_ConicalSurface.hxx> |
23 | #include <Geom_CylindricalSurface.hxx> |
24 | #include <Geom_SphericalSurface.hxx> |
25 | #include <Geom_ToroidalSurface.hxx> |
26 | #include <Geom_SurfaceOfRevolution.hxx> |
27 | #include <Geom2dConvert.hxx> |
28 | #include <Geom2d_BSplineCurve.hxx> |
29 | #include <Geom2d_Circle.hxx> |
30 | #include <Geom2d_Curve.hxx> |
31 | #include <Geom2d_Ellipse.hxx> |
32 | #include <Geom2d_Hyperbola.hxx> |
33 | #include <Geom2d_Line.hxx> |
34 | #include <Geom2d_Parabola.hxx> |
35 | #include <gp.hxx> |
36 | #include <gp_GTrsf2d.hxx> |
37 | #include <gp_Trsf2d.hxx> |
38 | #include <gp_Pnt2d.hxx> |
39 | #include <gp_Dir2d.hxx> |
40 | |
41 | static Standard_Real theLengthFactor = 1.; |
42 | static Standard_Real thePlaneAngleFactor = 1.; |
43 | static Standard_Real theSolidAngleFactor = 1.; |
44 | static Standard_Boolean set3d = Standard_True; |
45 | |
46 | static Standard_Real FactRD = 1.; |
47 | static Standard_Real FactDR = 1.; |
48 | |
49 | static Standard_Real theCasCadeLengthUnit = 1.; // abv 28 Feb 00 |
50 | |
51 | // ============================================================================ |
52 | // Method : |
53 | // Purpose: |
54 | // ============================================================================ |
55 | |
56 | void UnitsMethods::InitializeFactors(const Standard_Real LengthFactor, const Standard_Real PlaneAngleFactor, const Standard_Real SolidAngleFactor) |
57 | { |
58 | theLengthFactor = LengthFactor; |
59 | thePlaneAngleFactor = PlaneAngleFactor; |
60 | theSolidAngleFactor = SolidAngleFactor; |
61 | FactRD = 1./PlaneAngleFactor; |
62 | FactDR = PlaneAngleFactor; |
63 | } |
64 | |
65 | // ============================================================================ |
66 | // Method : |
67 | // Purpose: |
68 | // ============================================================================ |
69 | |
70 | Standard_Real UnitsMethods ::LengthFactor() |
71 | { |
72 | return theLengthFactor; |
73 | } |
74 | |
75 | // ============================================================================ |
76 | // Method : |
77 | // Purpose: |
78 | // ============================================================================ |
79 | |
80 | Standard_Real UnitsMethods::PlaneAngleFactor() |
81 | { |
82 | return thePlaneAngleFactor; |
83 | } |
84 | |
85 | // ============================================================================ |
86 | // Method : |
87 | // Purpose: |
88 | // ============================================================================ |
89 | |
90 | Standard_Real UnitsMethods::SolidAngleFactor() |
91 | { |
92 | return theSolidAngleFactor; |
93 | } |
94 | |
95 | // ============================================================================ |
96 | // Method : |
97 | // Purpose: |
98 | // ============================================================================ |
99 | |
100 | void UnitsMethods::Set3dConversion(const Standard_Boolean B) |
101 | { |
102 | set3d = B; |
103 | } |
104 | |
105 | // ============================================================================ |
106 | // Method : |
107 | // Purpose: |
108 | // ============================================================================ |
109 | |
110 | Standard_Boolean UnitsMethods::Convert3d() |
111 | { |
112 | return set3d; |
113 | } |
114 | |
115 | |
116 | // ============================================================================ |
117 | // Method : |
118 | // Purpose: |
119 | // ============================================================================ |
120 | |
121 | Handle(Geom2d_Curve) UnitsMethods::RadianToDegree |
122 | (const Handle(Geom2d_Curve) & theCurve2d, |
123 | const Handle(Geom_Surface) & theSurf) |
124 | { |
125 | Handle(Geom2d_Curve) aCurve2d = Handle(Geom2d_Curve)::DownCast(theCurve2d->Copy()); |
126 | Standard_Real uFact = 1.; |
127 | Standard_Real vFact = 1.; |
128 | Standard_Real LengthFact = 1. / UnitsMethods::LengthFactor(); |
129 | Standard_Real AngleFact = FactRD; // 180./PI; pilotable |
130 | |
131 | gp_Pnt2d Pt1; |
132 | gp_XY pXY; |
133 | gp_GTrsf2d tMatu , tMatv; |
134 | |
135 | // theSurf is a CylindricalSurface or a ConicalSurface or |
136 | // a ToroidalSurface or a SphericalSurface or |
137 | // a SurfaceOfRevolution |
138 | if (theSurf->IsKind(STANDARD_TYPE(Geom_SphericalSurface)) || |
139 | theSurf->IsKind(STANDARD_TYPE(Geom_ToroidalSurface))) { |
140 | uFact = vFact = AngleFact; |
141 | } |
142 | else if (theSurf->IsKind(STANDARD_TYPE(Geom_CylindricalSurface))) { |
143 | uFact = AngleFact; |
144 | vFact = LengthFact; |
145 | } |
146 | else if ( theSurf->IsKind(STANDARD_TYPE(Geom_SurfaceOfRevolution))) { |
147 | uFact = AngleFact; |
148 | } |
149 | else if (theSurf->IsKind(STANDARD_TYPE(Geom_ConicalSurface))) { |
150 | Handle(Geom_ConicalSurface) conicS = |
151 | Handle(Geom_ConicalSurface)::DownCast(theSurf); |
152 | Standard_Real semAng = conicS->SemiAngle(); |
153 | uFact = AngleFact; |
154 | vFact = LengthFact * Cos(semAng); |
155 | } |
156 | else if (theSurf->IsKind(STANDARD_TYPE(Geom_Plane))) { |
157 | uFact = vFact = LengthFact; |
158 | if (aCurve2d->IsKind(STANDARD_TYPE(Geom2d_Circle))) { |
159 | Handle(Geom2d_Circle) newCircle = |
160 | Handle(Geom2d_Circle)::DownCast(aCurve2d); |
161 | gp_Pnt2d Loc = newCircle->Location(); |
162 | Loc.SetX(Loc.X()*LengthFact); |
163 | Loc.SetY(Loc.Y()*LengthFact); |
164 | newCircle->SetRadius(newCircle->Radius()*LengthFact); |
165 | return newCircle; |
166 | } |
167 | else if (aCurve2d->IsKind(STANDARD_TYPE(Geom2d_Ellipse))) { |
168 | Handle(Geom2d_Ellipse) newEllipse = |
169 | Handle(Geom2d_Ellipse)::DownCast(aCurve2d); |
170 | gp_Pnt2d Loc = newEllipse->Location(); |
171 | Loc.SetX(Loc.X()*LengthFact); |
172 | Loc.SetY(Loc.Y()*LengthFact); |
173 | newEllipse->SetMajorRadius(newEllipse->MajorRadius()*LengthFact); |
174 | newEllipse->SetMinorRadius(newEllipse->MinorRadius()*LengthFact); |
175 | return newEllipse; |
176 | } |
177 | } |
178 | else { |
179 | // debug |
180 | // cout <<"UnitsMethods: SurfType = "<< aSurface->DynamicType(); |
181 | return aCurve2d; |
182 | } |
183 | |
184 | if (aCurve2d->IsKind(STANDARD_TYPE(Geom2d_Line))) { |
185 | Handle(Geom2d_Line) aLine2d = Handle(Geom2d_Line)::DownCast(aCurve2d); |
186 | |
187 | gp_Pnt2d myLoc = aLine2d->Location(); |
188 | gp_Dir2d myDir = aLine2d->Direction(); |
189 | |
190 | gp_Pnt2d myNewLoc; |
191 | myNewLoc.SetCoord(myLoc.X()*uFact, myLoc.Y()*vFact); |
192 | |
193 | gp_Dir2d myNewDir; |
194 | myNewDir.SetCoord(myDir.X()*uFact, myDir.Y()*vFact); |
195 | |
196 | Handle(Geom2d_Line) myNewLine2d = Handle(Geom2d_Line)::DownCast(aLine2d->Copy()); |
197 | myNewLine2d->SetLocation(myNewLoc); |
198 | myNewLine2d->SetDirection(myNewDir); |
199 | |
200 | return myNewLine2d; |
201 | } |
202 | else if (aCurve2d->IsKind(STANDARD_TYPE(Geom2d_Conic))) { |
203 | if (aCurve2d->IsKind(STANDARD_TYPE(Geom2d_Circle))) { |
204 | Handle(Geom2d_Circle) aCirc2d = |
205 | Handle(Geom2d_Circle)::DownCast(aCurve2d); |
206 | Handle(Geom2d_BSplineCurve) aBSpline2d = |
207 | Geom2dConvert::CurveToBSplineCurve(aCirc2d); |
208 | aCurve2d = aBSpline2d; |
209 | } |
210 | else if (aCurve2d->IsKind(STANDARD_TYPE(Geom2d_Ellipse))) { |
211 | Handle(Geom2d_Ellipse) aHel2d = |
212 | Handle(Geom2d_Ellipse)::DownCast(aCurve2d); |
213 | Handle(Geom2d_BSplineCurve) aBSpline2d = |
214 | Geom2dConvert::CurveToBSplineCurve(aHel2d); |
215 | aCurve2d = aBSpline2d; |
216 | } |
217 | else if (aCurve2d->IsKind(STANDARD_TYPE(Geom2d_Parabola))) { |
218 | #ifdef DEBUG |
219 | cout << "PCURVE of Parabola type in U or V Periodic Surface" << endl; |
220 | cout << "Parameters Not transformed to Degree" << endl; |
221 | #endif |
222 | } |
223 | else if (aCurve2d->IsKind(STANDARD_TYPE(Geom2d_Hyperbola))) { |
224 | #ifdef DEBUG |
225 | cout << "PCURVE of Hyperbola type in U or V Periodic Surface" << endl; |
226 | cout << "Parameters Not transformed to Degree" << endl; |
227 | #endif |
228 | } |
229 | |
230 | } |
231 | |
232 | // Compute affinity |
233 | tMatu.SetAffinity(gp::OY2d(), uFact); |
234 | tMatv.SetAffinity(gp::OX2d(), vFact); |
235 | |
236 | if (aCurve2d->IsKind(STANDARD_TYPE(Geom2d_BoundedCurve))) { |
237 | if (aCurve2d->IsKind(STANDARD_TYPE(Geom2d_BSplineCurve))) { |
238 | Handle(Geom2d_BSplineCurve) aBSpline2d = |
239 | Handle(Geom2d_BSplineCurve)::DownCast(aCurve2d); |
240 | Handle(Geom2d_BSplineCurve) myNewBSpline2d = |
241 | Handle(Geom2d_BSplineCurve)::DownCast(aBSpline2d->Copy()); |
242 | Standard_Integer nbPol = aBSpline2d->NbPoles(); |
243 | for (Standard_Integer i = 1; i<=nbPol ; i++) { |
244 | pXY = aBSpline2d->Pole(i).XY(); |
245 | tMatu.Transforms(pXY); |
246 | tMatv.Transforms(pXY); |
247 | Pt1.SetXY(pXY); |
248 | myNewBSpline2d->SetPole(i, Pt1); |
249 | } |
250 | return myNewBSpline2d; |
251 | } |
252 | else { |
253 | #ifdef DEBUG |
254 | cout << "PCURVE of Other Types of Bounded Curve in U or V Periodic Surface" << endl; |
255 | cout << "Parameters Not transformed to Degree" << endl; |
256 | #endif |
257 | } |
258 | } |
259 | return aCurve2d; |
260 | } |
261 | |
262 | //============================================================================= |
263 | // DegreeToRadian: 1. Change definition of the pcurves according to Length |
264 | // Factor |
265 | // 2. STEP cylinder, torus, cone and sphere are parametrized |
266 | // from 0 to 360 degree |
267 | // Then pcurves parameter have to be transformed |
268 | // from DEGREE to RADIAN |
269 | //============================================================================= |
270 | |
271 | Handle(Geom2d_Curve) UnitsMethods::DegreeToRadian |
272 | (const Handle(Geom2d_Curve) & thePcurve, |
273 | const Handle(Geom_Surface) & aSurface) |
274 | { |
275 | Handle(Geom2d_Curve) aPcurve = Handle(Geom2d_Curve)::DownCast(thePcurve->Copy()); |
276 | Standard_Real uFact = 1.; |
277 | Standard_Real vFact = 1.; |
278 | Standard_Real LengthFact = UnitsMethods::LengthFactor(); |
279 | Standard_Real AngleFact = FactDR; // PI/180.; pilotable |
280 | |
281 | gp_Pnt2d Pt1; |
282 | gp_XY pXY; |
283 | gp_GTrsf2d tMatu , tMatv; |
284 | |
285 | // What to change ?? |
286 | |
287 | if (aSurface->IsKind(STANDARD_TYPE(Geom_SphericalSurface)) || |
288 | aSurface->IsKind(STANDARD_TYPE(Geom_ToroidalSurface))) { |
289 | uFact = vFact = AngleFact; |
290 | } |
291 | else if (aSurface->IsKind(STANDARD_TYPE(Geom_CylindricalSurface))) { |
292 | uFact = AngleFact; |
293 | vFact = LengthFact; |
294 | } |
295 | else if ( aSurface->IsKind(STANDARD_TYPE(Geom_SurfaceOfRevolution))) { |
296 | uFact = AngleFact; |
297 | } |
298 | else if (aSurface->IsKind(STANDARD_TYPE(Geom_ConicalSurface))) { |
299 | Handle(Geom_ConicalSurface) conicS = |
300 | Handle(Geom_ConicalSurface)::DownCast(aSurface); |
301 | Standard_Real semAng = conicS->SemiAngle(); |
302 | uFact = AngleFact; |
303 | vFact = LengthFact / Cos(semAng); |
304 | } |
305 | else if (aSurface->IsKind(STANDARD_TYPE(Geom_Plane))) { |
306 | uFact = vFact = LengthFact; |
307 | if (aPcurve->IsKind(STANDARD_TYPE(Geom2d_Circle))) { |
308 | Handle(Geom2d_Circle) newCircle = |
309 | Handle(Geom2d_Circle)::DownCast(aPcurve); |
310 | gp_Pnt2d Loc = newCircle->Location(); |
311 | Loc.SetX(Loc.X()*LengthFact); |
312 | Loc.SetY(Loc.Y()*LengthFact); |
313 | newCircle->SetRadius(newCircle->Radius()*LengthFact); |
314 | return newCircle; |
315 | } |
316 | else if (aPcurve->IsKind(STANDARD_TYPE(Geom2d_Ellipse))) { |
317 | Handle(Geom2d_Ellipse) newEllipse = |
318 | Handle(Geom2d_Ellipse)::DownCast(aPcurve); |
319 | gp_Pnt2d Loc = newEllipse->Location(); |
320 | Loc.SetX(Loc.X()*LengthFact); |
321 | Loc.SetY(Loc.Y()*LengthFact); |
322 | newEllipse->SetMajorRadius(newEllipse->MajorRadius()*LengthFact); |
323 | newEllipse->SetMinorRadius(newEllipse->MinorRadius()*LengthFact); |
324 | return newEllipse; |
325 | } |
326 | } |
327 | else { |
328 | // debug |
329 | // cout <<"UnitsMethods: SurfType = "<< aSurface->DynamicType(); |
330 | return aPcurve; |
331 | } |
332 | |
333 | if (aPcurve->IsKind(STANDARD_TYPE(Geom2d_Conic))) { |
334 | if (aPcurve->IsKind(STANDARD_TYPE(Geom2d_Circle)) || |
335 | aPcurve->IsKind(STANDARD_TYPE(Geom2d_Ellipse))) { |
336 | Handle(Geom2d_BSplineCurve) aBSpline2d = |
337 | Geom2dConvert::CurveToBSplineCurve(aPcurve); |
338 | aPcurve = aBSpline2d; |
339 | } |
340 | else if (aPcurve->IsKind(STANDARD_TYPE(Geom2d_Parabola))) { |
341 | #ifdef DEBUG |
342 | cout << "PCURVE of Parabola type" << endl; |
343 | cout << "Parameters Not Yet transformed according to LenghtUnit" << endl; |
344 | #endif |
345 | return aPcurve; |
346 | } |
347 | else if (aPcurve->IsKind(STANDARD_TYPE(Geom2d_Hyperbola))) { |
348 | #ifdef DEBUG |
349 | cout << "PCURVE of Hyperbola type" << endl; |
350 | cout << "Parameters Not Yet transformed according to LenghtUnit" << endl; |
351 | #endif |
352 | return aPcurve; |
353 | } |
354 | } |
355 | |
356 | // Compute affinity |
357 | |
358 | tMatu.SetAffinity(gp::OY2d(), uFact); |
359 | tMatv.SetAffinity(gp::OX2d(), vFact); |
360 | |
361 | if (aPcurve->IsKind(STANDARD_TYPE(Geom2d_Line))) { |
362 | Handle(Geom2d_Line) aLine2d = Handle(Geom2d_Line)::DownCast(aPcurve); |
363 | |
364 | gp_Pnt2d myLoc = aLine2d->Location(); |
365 | gp_Dir2d myDir = aLine2d->Direction(); |
366 | |
367 | gp_Pnt2d myNewLoc; |
368 | myNewLoc.SetCoord(myLoc.X()*uFact, myLoc.Y()*vFact); |
369 | |
370 | gp_Dir2d myNewDir; |
371 | myNewDir.SetCoord(myDir.X()*uFact, myDir.Y()*vFact); |
372 | |
373 | aLine2d->SetLocation(myNewLoc); |
374 | aLine2d->SetDirection(myNewDir); |
375 | |
376 | aPcurve = aLine2d; |
377 | } |
378 | else if (aPcurve->IsKind(STANDARD_TYPE(Geom2d_BSplineCurve))) { |
379 | Handle(Geom2d_BSplineCurve) aBSpline2d = |
380 | Handle(Geom2d_BSplineCurve)::DownCast(aPcurve); |
381 | |
382 | // transform the Poles of the BSplineCurve according to AngleFact and LengthFact |
383 | |
384 | Standard_Integer nbPol = aBSpline2d->NbPoles(); |
385 | for (Standard_Integer i = 1; i<=nbPol ; i++) { |
386 | pXY = aBSpline2d->Pole(i).XY(); |
387 | tMatu.Transforms(pXY); |
388 | tMatv.Transforms(pXY); |
389 | Pt1.SetXY(pXY); |
390 | aBSpline2d->SetPole(i, Pt1); |
391 | } |
392 | aPcurve = aBSpline2d; |
393 | } |
394 | else { |
395 | #ifdef DEBUG |
396 | cout << "DegreeToRadian : Type " << aPcurve->DynamicType(); |
397 | cout << " not yet implemented" << endl; |
398 | #endif |
399 | } |
400 | return aPcurve; |
401 | } |
402 | |
403 | // ============================================================================ |
404 | // Method : |
405 | // Purpose: |
406 | // ============================================================================ |
407 | |
408 | Handle(Geom2d_Curve) UnitsMethods::MirrorPCurve |
409 | (const Handle(Geom2d_Curve) & C2d) |
410 | { |
411 | Handle(Geom2d_Curve) theMirrored = |
412 | Handle(Geom2d_Curve)::DownCast(C2d->Copy()); |
413 | |
414 | gp_Trsf2d T; |
415 | gp_Pnt2d Loc(0.,0.); |
416 | gp_Dir2d Dir(1.,0.); |
417 | gp_Ax2d ax2(Loc, Dir); |
418 | T.SetMirror(ax2); |
419 | theMirrored->Transform(T); |
420 | return theMirrored; |
421 | } |
422 | |
423 | //======================================================================= |
424 | //function : GetCasCadeLengthUnit |
425 | //purpose : |
426 | //======================================================================= |
427 | |
428 | Standard_Real UnitsMethods::GetCasCadeLengthUnit () |
429 | { |
430 | return theCasCadeLengthUnit; |
431 | } |
432 | |
433 | //======================================================================= |
434 | //function : SetCasCadeLengthUnit |
435 | //purpose : |
436 | //======================================================================= |
437 | |
438 | void UnitsMethods::SetCasCadeLengthUnit (const Standard_Integer unit) |
439 | { |
440 | theCasCadeLengthUnit = UnitsMethods::GetLengthFactorValue ( unit ); |
441 | } |
442 | |
443 | //======================================================================= |
444 | //function : GetLengthFactorValue |
445 | //purpose : |
446 | //======================================================================= |
447 | |
448 | Standard_Real UnitsMethods::GetLengthFactorValue (const Standard_Integer par) |
449 | { |
450 | switch ( par ) { |
451 | case 1 : return 25.4; |
452 | case 2 : return 1.; |
453 | |
454 | case 4 : return 304.8; |
455 | case 5 : return 1609270.; |
456 | case 6 : return 1000.; |
457 | case 7 : return 1000000.; |
458 | case 8 : return 0.0254; |
459 | case 9 : return 0.001; |
460 | case 10 : return 10.; |
461 | case 11 : return 0.0000254; |
462 | default : return 1.; |
463 | } |
464 | } |
465 | |