1 // Copyright (c) 1999-2014 OPEN CASCADE SAS
3 // This file is part of Open CASCADE Technology software library.
5 // This library is free software; you can redistribute it and/or modify it under
6 // the terms of the GNU Lesser General Public License version 2.1 as published
7 // by the Free Software Foundation, with special exception defined in the file
8 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
9 // distribution for complete text of the license and disclaimer of any warranty.
11 // Alternatively, this file may be used under the terms of Open CASCADE
12 // commercial license or contractual agreement.
14 #include <UnitsMethods.ixx>
16 #include <Geom_Plane.hxx>
17 #include <Geom_Surface.hxx>
18 #include <Geom_ConicalSurface.hxx>
19 #include <Geom_CylindricalSurface.hxx>
20 #include <Geom_SphericalSurface.hxx>
21 #include <Geom_ToroidalSurface.hxx>
22 #include <Geom_SurfaceOfRevolution.hxx>
23 #include <Geom2dConvert.hxx>
24 #include <Geom2d_BSplineCurve.hxx>
25 #include <Geom2d_Circle.hxx>
26 #include <Geom2d_Curve.hxx>
27 #include <Geom2d_Ellipse.hxx>
28 #include <Geom2d_Hyperbola.hxx>
29 #include <Geom2d_Line.hxx>
30 #include <Geom2d_Parabola.hxx>
32 #include <gp_GTrsf2d.hxx>
33 #include <gp_Trsf2d.hxx>
34 #include <gp_Pnt2d.hxx>
35 #include <gp_Dir2d.hxx>
37 static Standard_Real theLengthFactor = 1.;
38 static Standard_Real thePlaneAngleFactor = 1.;
39 static Standard_Real theSolidAngleFactor = 1.;
40 static Standard_Boolean set3d = Standard_True;
42 static Standard_Real FactRD = 1.;
43 static Standard_Real FactDR = 1.;
45 static Standard_Real theCasCadeLengthUnit = 1.; // abv 28 Feb 00
47 // ============================================================================
50 // ============================================================================
52 void UnitsMethods::InitializeFactors(const Standard_Real LengthFactor, const Standard_Real PlaneAngleFactor, const Standard_Real SolidAngleFactor)
54 theLengthFactor = LengthFactor;
55 thePlaneAngleFactor = PlaneAngleFactor;
56 theSolidAngleFactor = SolidAngleFactor;
57 FactRD = 1./PlaneAngleFactor;
58 FactDR = PlaneAngleFactor;
61 // ============================================================================
64 // ============================================================================
66 Standard_Real UnitsMethods ::LengthFactor()
68 return theLengthFactor;
71 // ============================================================================
74 // ============================================================================
76 Standard_Real UnitsMethods::PlaneAngleFactor()
78 return thePlaneAngleFactor;
81 // ============================================================================
84 // ============================================================================
86 Standard_Real UnitsMethods::SolidAngleFactor()
88 return theSolidAngleFactor;
91 // ============================================================================
94 // ============================================================================
96 void UnitsMethods::Set3dConversion(const Standard_Boolean B)
101 // ============================================================================
104 // ============================================================================
106 Standard_Boolean UnitsMethods::Convert3d()
112 // ============================================================================
115 // ============================================================================
117 Handle(Geom2d_Curve) UnitsMethods::RadianToDegree
118 (const Handle(Geom2d_Curve) & theCurve2d,
119 const Handle(Geom_Surface) & theSurf)
121 Handle(Geom2d_Curve) aCurve2d = Handle(Geom2d_Curve)::DownCast(theCurve2d->Copy());
122 Standard_Real uFact = 1.;
123 Standard_Real vFact = 1.;
124 Standard_Real LengthFact = 1. / UnitsMethods::LengthFactor();
125 Standard_Real AngleFact = FactRD; // 180./PI; pilotable
129 gp_GTrsf2d tMatu , tMatv;
131 // theSurf is a CylindricalSurface or a ConicalSurface or
132 // a ToroidalSurface or a SphericalSurface or
133 // a SurfaceOfRevolution
134 if (theSurf->IsKind(STANDARD_TYPE(Geom_SphericalSurface)) ||
135 theSurf->IsKind(STANDARD_TYPE(Geom_ToroidalSurface))) {
136 uFact = vFact = AngleFact;
138 else if (theSurf->IsKind(STANDARD_TYPE(Geom_CylindricalSurface))) {
142 else if ( theSurf->IsKind(STANDARD_TYPE(Geom_SurfaceOfRevolution))) {
145 else if (theSurf->IsKind(STANDARD_TYPE(Geom_ConicalSurface))) {
146 Handle(Geom_ConicalSurface) conicS =
147 Handle(Geom_ConicalSurface)::DownCast(theSurf);
148 Standard_Real semAng = conicS->SemiAngle();
150 vFact = LengthFact * Cos(semAng);
152 else if (theSurf->IsKind(STANDARD_TYPE(Geom_Plane))) {
153 uFact = vFact = LengthFact;
154 if (aCurve2d->IsKind(STANDARD_TYPE(Geom2d_Circle)) ||
155 aCurve2d->IsKind(STANDARD_TYPE(Geom2d_Ellipse))) {
157 aT.SetScale (gp::Origin2d(), LengthFact);
158 aCurve2d->Transform (aT);
164 // cout <<"UnitsMethods: SurfType = "<< aSurface->DynamicType();
168 if (aCurve2d->IsKind(STANDARD_TYPE(Geom2d_Line))) {
169 Handle(Geom2d_Line) aLine2d = Handle(Geom2d_Line)::DownCast(aCurve2d);
171 gp_Pnt2d myLoc = aLine2d->Location();
172 gp_Dir2d myDir = aLine2d->Direction();
175 myNewLoc.SetCoord(myLoc.X()*uFact, myLoc.Y()*vFact);
178 myNewDir.SetCoord(myDir.X()*uFact, myDir.Y()*vFact);
180 Handle(Geom2d_Line) myNewLine2d = Handle(Geom2d_Line)::DownCast(aLine2d->Copy());
181 myNewLine2d->SetLocation(myNewLoc);
182 myNewLine2d->SetDirection(myNewDir);
186 else if (aCurve2d->IsKind(STANDARD_TYPE(Geom2d_Conic))) {
187 if (aCurve2d->IsKind(STANDARD_TYPE(Geom2d_Circle)) ||
188 aCurve2d->IsKind(STANDARD_TYPE(Geom2d_Ellipse))) {
189 Handle(Geom2d_BSplineCurve) aBSpline2d =
190 Geom2dConvert::CurveToBSplineCurve(aCurve2d);
191 aCurve2d = aBSpline2d;
193 else if (aCurve2d->IsKind(STANDARD_TYPE(Geom2d_Parabola))) {
195 cout << "PCURVE of Parabola type in U or V Periodic Surface" << endl;
196 cout << "Parameters Not transformed to Degree" << endl;
199 else if (aCurve2d->IsKind(STANDARD_TYPE(Geom2d_Hyperbola))) {
201 cout << "PCURVE of Hyperbola type in U or V Periodic Surface" << endl;
202 cout << "Parameters Not transformed to Degree" << endl;
209 tMatu.SetAffinity(gp::OY2d(), uFact);
210 tMatv.SetAffinity(gp::OX2d(), vFact);
212 if (aCurve2d->IsKind(STANDARD_TYPE(Geom2d_BoundedCurve))) {
213 if (aCurve2d->IsKind(STANDARD_TYPE(Geom2d_BSplineCurve))) {
214 Handle(Geom2d_BSplineCurve) aBSpline2d =
215 Handle(Geom2d_BSplineCurve)::DownCast(aCurve2d);
216 Handle(Geom2d_BSplineCurve) myNewBSpline2d =
217 Handle(Geom2d_BSplineCurve)::DownCast(aBSpline2d->Copy());
218 Standard_Integer nbPol = aBSpline2d->NbPoles();
219 for (Standard_Integer i = 1; i<=nbPol ; i++) {
220 pXY = aBSpline2d->Pole(i).XY();
221 tMatu.Transforms(pXY);
222 tMatv.Transforms(pXY);
224 myNewBSpline2d->SetPole(i, Pt1);
226 return myNewBSpline2d;
230 cout << "PCURVE of Other Types of Bounded Curve in U or V Periodic Surface" << endl;
231 cout << "Parameters Not transformed to Degree" << endl;
238 //=============================================================================
239 // DegreeToRadian: 1. Change definition of the pcurves according to Length
241 // 2. STEP cylinder, torus, cone and sphere are parametrized
242 // from 0 to 360 degree
243 // Then pcurves parameter have to be transformed
244 // from DEGREE to RADIAN
245 //=============================================================================
247 Handle(Geom2d_Curve) UnitsMethods::DegreeToRadian
248 (const Handle(Geom2d_Curve) & thePcurve,
249 const Handle(Geom_Surface) & aSurface)
251 Handle(Geom2d_Curve) aPcurve = Handle(Geom2d_Curve)::DownCast(thePcurve->Copy());
252 Standard_Real uFact = 1.;
253 Standard_Real vFact = 1.;
254 Standard_Real LengthFact = UnitsMethods::LengthFactor();
255 Standard_Real AngleFact = FactDR; // PI/180.; pilotable
259 gp_GTrsf2d tMatu , tMatv;
263 if (aSurface->IsKind(STANDARD_TYPE(Geom_SphericalSurface)) ||
264 aSurface->IsKind(STANDARD_TYPE(Geom_ToroidalSurface))) {
265 uFact = vFact = AngleFact;
267 else if (aSurface->IsKind(STANDARD_TYPE(Geom_CylindricalSurface))) {
271 else if ( aSurface->IsKind(STANDARD_TYPE(Geom_SurfaceOfRevolution))) {
274 else if (aSurface->IsKind(STANDARD_TYPE(Geom_ConicalSurface))) {
275 Handle(Geom_ConicalSurface) conicS =
276 Handle(Geom_ConicalSurface)::DownCast(aSurface);
277 Standard_Real semAng = conicS->SemiAngle();
279 vFact = LengthFact / Cos(semAng);
281 else if (aSurface->IsKind(STANDARD_TYPE(Geom_Plane))) {
282 uFact = vFact = LengthFact;
283 if (aPcurve->IsKind(STANDARD_TYPE(Geom2d_Circle)) ||
284 aPcurve->IsKind(STANDARD_TYPE(Geom2d_Ellipse))) {
286 aT.SetScale (gp::Origin2d(), LengthFact);
287 aPcurve->Transform (aT);
293 // cout <<"UnitsMethods: SurfType = "<< aSurface->DynamicType();
297 if (aPcurve->IsKind(STANDARD_TYPE(Geom2d_Conic))) {
298 if (aPcurve->IsKind(STANDARD_TYPE(Geom2d_Circle)) ||
299 aPcurve->IsKind(STANDARD_TYPE(Geom2d_Ellipse))) {
300 Handle(Geom2d_BSplineCurve) aBSpline2d =
301 Geom2dConvert::CurveToBSplineCurve(aPcurve);
302 aPcurve = aBSpline2d;
304 else if (aPcurve->IsKind(STANDARD_TYPE(Geom2d_Parabola))) {
306 cout << "PCURVE of Parabola type" << endl;
307 cout << "Parameters Not Yet transformed according to LenghtUnit" << endl;
311 else if (aPcurve->IsKind(STANDARD_TYPE(Geom2d_Hyperbola))) {
313 cout << "PCURVE of Hyperbola type" << endl;
314 cout << "Parameters Not Yet transformed according to LenghtUnit" << endl;
322 tMatu.SetAffinity(gp::OY2d(), uFact);
323 tMatv.SetAffinity(gp::OX2d(), vFact);
325 if (aPcurve->IsKind(STANDARD_TYPE(Geom2d_Line))) {
326 Handle(Geom2d_Line) aLine2d = Handle(Geom2d_Line)::DownCast(aPcurve);
328 gp_Pnt2d myLoc = aLine2d->Location();
329 gp_Dir2d myDir = aLine2d->Direction();
332 myNewLoc.SetCoord(myLoc.X()*uFact, myLoc.Y()*vFact);
335 myNewDir.SetCoord(myDir.X()*uFact, myDir.Y()*vFact);
337 aLine2d->SetLocation(myNewLoc);
338 aLine2d->SetDirection(myNewDir);
342 else if (aPcurve->IsKind(STANDARD_TYPE(Geom2d_BSplineCurve))) {
343 Handle(Geom2d_BSplineCurve) aBSpline2d =
344 Handle(Geom2d_BSplineCurve)::DownCast(aPcurve);
346 // transform the Poles of the BSplineCurve according to AngleFact and LengthFact
348 Standard_Integer nbPol = aBSpline2d->NbPoles();
349 for (Standard_Integer i = 1; i<=nbPol ; i++) {
350 pXY = aBSpline2d->Pole(i).XY();
351 tMatu.Transforms(pXY);
352 tMatv.Transforms(pXY);
354 aBSpline2d->SetPole(i, Pt1);
356 aPcurve = aBSpline2d;
360 cout << "DegreeToRadian : Type " << aPcurve->DynamicType();
361 cout << " not yet implemented" << endl;
367 // ============================================================================
370 // ============================================================================
372 Handle(Geom2d_Curve) UnitsMethods::MirrorPCurve
373 (const Handle(Geom2d_Curve) & C2d)
375 Handle(Geom2d_Curve) theMirrored =
376 Handle(Geom2d_Curve)::DownCast(C2d->Copy());
381 gp_Ax2d ax2(Loc, Dir);
383 theMirrored->Transform(T);
387 //=======================================================================
388 //function : GetCasCadeLengthUnit
390 //=======================================================================
392 Standard_Real UnitsMethods::GetCasCadeLengthUnit ()
394 return theCasCadeLengthUnit;
397 //=======================================================================
398 //function : SetCasCadeLengthUnit
400 //=======================================================================
402 void UnitsMethods::SetCasCadeLengthUnit (const Standard_Integer unit)
404 theCasCadeLengthUnit = UnitsMethods::GetLengthFactorValue ( unit );
407 //=======================================================================
408 //function : GetLengthFactorValue
410 //=======================================================================
412 Standard_Real UnitsMethods::GetLengthFactorValue (const Standard_Integer par)
415 case 1 : return 25.4;
418 case 4 : return 304.8;
419 case 5 : return 1609270.;
420 case 6 : return 1000.;
421 case 7 : return 1000000.;
422 case 8 : return 0.0254;
423 case 9 : return 0.001;
424 case 10 : return 10.;
425 case 11 : return 0.0000254;