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.
15 #include <Geom2d_BoundedCurve.hxx>
16 #include <Geom2d_BSplineCurve.hxx>
17 #include <Geom2d_Circle.hxx>
18 #include <Geom2d_Conic.hxx>
19 #include <Geom2d_Curve.hxx>
20 #include <Geom2d_Ellipse.hxx>
21 #include <Geom2d_Hyperbola.hxx>
22 #include <Geom2d_Line.hxx>
23 #include <Geom2d_Parabola.hxx>
24 #include <Geom2dConvert.hxx>
25 #include <Geom_ConicalSurface.hxx>
26 #include <Geom_CylindricalSurface.hxx>
27 #include <Geom_Plane.hxx>
28 #include <Geom_SphericalSurface.hxx>
29 #include <Geom_Surface.hxx>
30 #include <Geom_SurfaceOfRevolution.hxx>
31 #include <Geom_ToroidalSurface.hxx>
33 #include <gp_Dir2d.hxx>
34 #include <gp_GTrsf2d.hxx>
35 #include <gp_Pnt2d.hxx>
36 #include <gp_Trsf2d.hxx>
37 #include <UnitsMethods.hxx>
39 static Standard_Real theLengthFactor = 1.;
40 static Standard_Real thePlaneAngleFactor = 1.;
41 static Standard_Real theSolidAngleFactor = 1.;
42 static Standard_Boolean set3d = Standard_True;
44 static Standard_Real FactRD = 1.;
45 static Standard_Real FactDR = 1.;
47 static Standard_Real theCasCadeLengthUnit = 1.; // abv 28 Feb 00
49 // ============================================================================
52 // ============================================================================
54 void UnitsMethods::InitializeFactors(const Standard_Real LengthFactor, const Standard_Real PlaneAngleFactor, const Standard_Real SolidAngleFactor)
56 theLengthFactor = LengthFactor;
57 thePlaneAngleFactor = PlaneAngleFactor;
58 theSolidAngleFactor = SolidAngleFactor;
59 FactRD = 1./PlaneAngleFactor;
60 FactDR = PlaneAngleFactor;
63 // ============================================================================
66 // ============================================================================
68 Standard_Real UnitsMethods ::LengthFactor()
70 return theLengthFactor;
73 // ============================================================================
76 // ============================================================================
78 Standard_Real UnitsMethods::PlaneAngleFactor()
80 return thePlaneAngleFactor;
83 // ============================================================================
86 // ============================================================================
88 Standard_Real UnitsMethods::SolidAngleFactor()
90 return theSolidAngleFactor;
93 // ============================================================================
96 // ============================================================================
98 void UnitsMethods::Set3dConversion(const Standard_Boolean B)
103 // ============================================================================
106 // ============================================================================
108 Standard_Boolean UnitsMethods::Convert3d()
114 // ============================================================================
117 // ============================================================================
119 Handle(Geom2d_Curve) UnitsMethods::RadianToDegree
120 (const Handle(Geom2d_Curve) & theCurve2d,
121 const Handle(Geom_Surface) & theSurf)
123 Handle(Geom2d_Curve) aCurve2d = Handle(Geom2d_Curve)::DownCast(theCurve2d->Copy());
124 Standard_Real uFact = 1.;
125 Standard_Real vFact = 1.;
126 Standard_Real LengthFact = 1. / UnitsMethods::LengthFactor();
127 Standard_Real AngleFact = FactRD; // 180./PI; pilotable
131 gp_GTrsf2d tMatu , tMatv;
133 // theSurf is a CylindricalSurface or a ConicalSurface or
134 // a ToroidalSurface or a SphericalSurface or
135 // a SurfaceOfRevolution
136 if (theSurf->IsKind(STANDARD_TYPE(Geom_SphericalSurface)) ||
137 theSurf->IsKind(STANDARD_TYPE(Geom_ToroidalSurface))) {
138 uFact = vFact = AngleFact;
140 else if (theSurf->IsKind(STANDARD_TYPE(Geom_CylindricalSurface))) {
144 else if ( theSurf->IsKind(STANDARD_TYPE(Geom_SurfaceOfRevolution))) {
147 else if (theSurf->IsKind(STANDARD_TYPE(Geom_ConicalSurface))) {
148 Handle(Geom_ConicalSurface) conicS =
149 Handle(Geom_ConicalSurface)::DownCast(theSurf);
150 Standard_Real semAng = conicS->SemiAngle();
152 vFact = LengthFact * Cos(semAng);
154 else if (theSurf->IsKind(STANDARD_TYPE(Geom_Plane))) {
155 uFact = vFact = LengthFact;
156 if (aCurve2d->IsKind(STANDARD_TYPE(Geom2d_Circle)) ||
157 aCurve2d->IsKind(STANDARD_TYPE(Geom2d_Ellipse))) {
159 aT.SetScale (gp::Origin2d(), LengthFact);
160 aCurve2d->Transform (aT);
166 // std::cout <<"UnitsMethods: SurfType = "<< aSurface->DynamicType();
170 if (aCurve2d->IsKind(STANDARD_TYPE(Geom2d_Line))) {
171 Handle(Geom2d_Line) aLine2d = Handle(Geom2d_Line)::DownCast(aCurve2d);
173 gp_Pnt2d myLoc = aLine2d->Location();
174 gp_Dir2d myDir = aLine2d->Direction();
177 myNewLoc.SetCoord(myLoc.X()*uFact, myLoc.Y()*vFact);
180 myNewDir.SetCoord(myDir.X()*uFact, myDir.Y()*vFact);
182 Handle(Geom2d_Line) myNewLine2d = Handle(Geom2d_Line)::DownCast(aLine2d->Copy());
183 myNewLine2d->SetLocation(myNewLoc);
184 myNewLine2d->SetDirection(myNewDir);
188 else if (aCurve2d->IsKind(STANDARD_TYPE(Geom2d_Conic))) {
189 if (aCurve2d->IsKind(STANDARD_TYPE(Geom2d_Circle)) ||
190 aCurve2d->IsKind(STANDARD_TYPE(Geom2d_Ellipse))) {
191 Handle(Geom2d_BSplineCurve) aBSpline2d =
192 Geom2dConvert::CurveToBSplineCurve(aCurve2d);
193 aCurve2d = aBSpline2d;
195 else if (aCurve2d->IsKind(STANDARD_TYPE(Geom2d_Parabola))) {
197 std::cout << "PCURVE of Parabola type in U or V Periodic Surface" << std::endl;
198 std::cout << "Parameters Not transformed to Degree" << std::endl;
201 else if (aCurve2d->IsKind(STANDARD_TYPE(Geom2d_Hyperbola))) {
203 std::cout << "PCURVE of Hyperbola type in U or V Periodic Surface" << std::endl;
204 std::cout << "Parameters Not transformed to Degree" << std::endl;
211 tMatu.SetAffinity(gp::OY2d(), uFact);
212 tMatv.SetAffinity(gp::OX2d(), vFact);
214 if (aCurve2d->IsKind(STANDARD_TYPE(Geom2d_BoundedCurve))) {
215 if (aCurve2d->IsKind(STANDARD_TYPE(Geom2d_BSplineCurve))) {
216 Handle(Geom2d_BSplineCurve) aBSpline2d =
217 Handle(Geom2d_BSplineCurve)::DownCast(aCurve2d);
218 Handle(Geom2d_BSplineCurve) myNewBSpline2d =
219 Handle(Geom2d_BSplineCurve)::DownCast(aBSpline2d->Copy());
220 Standard_Integer nbPol = aBSpline2d->NbPoles();
221 for (Standard_Integer i = 1; i<=nbPol ; i++) {
222 pXY = aBSpline2d->Pole(i).XY();
223 tMatu.Transforms(pXY);
224 tMatv.Transforms(pXY);
226 myNewBSpline2d->SetPole(i, Pt1);
228 return myNewBSpline2d;
232 std::cout << "PCURVE of Other Types of Bounded Curve in U or V Periodic Surface" << std::endl;
233 std::cout << "Parameters Not transformed to Degree" << std::endl;
240 //=============================================================================
241 // DegreeToRadian: 1. Change definition of the pcurves according to Length
243 // 2. STEP cylinder, torus, cone and sphere are parametrized
244 // from 0 to 360 degree
245 // Then pcurves parameter have to be transformed
246 // from DEGREE to RADIAN
247 //=============================================================================
249 Handle(Geom2d_Curve) UnitsMethods::DegreeToRadian
250 (const Handle(Geom2d_Curve) & thePcurve,
251 const Handle(Geom_Surface) & aSurface)
253 Handle(Geom2d_Curve) aPcurve = Handle(Geom2d_Curve)::DownCast(thePcurve->Copy());
254 Standard_Real uFact = 1.;
255 Standard_Real vFact = 1.;
256 Standard_Real LengthFact = UnitsMethods::LengthFactor();
257 Standard_Real AngleFact = FactDR; // PI/180.; pilotable
261 gp_GTrsf2d tMatu , tMatv;
265 if (aSurface->IsKind(STANDARD_TYPE(Geom_SphericalSurface)) ||
266 aSurface->IsKind(STANDARD_TYPE(Geom_ToroidalSurface))) {
267 uFact = vFact = AngleFact;
269 else if (aSurface->IsKind(STANDARD_TYPE(Geom_CylindricalSurface))) {
273 else if ( aSurface->IsKind(STANDARD_TYPE(Geom_SurfaceOfRevolution))) {
276 else if (aSurface->IsKind(STANDARD_TYPE(Geom_ConicalSurface))) {
277 Handle(Geom_ConicalSurface) conicS =
278 Handle(Geom_ConicalSurface)::DownCast(aSurface);
279 Standard_Real semAng = conicS->SemiAngle();
281 vFact = LengthFact / Cos(semAng);
283 else if (aSurface->IsKind(STANDARD_TYPE(Geom_Plane))) {
284 uFact = vFact = LengthFact;
285 if (aPcurve->IsKind(STANDARD_TYPE(Geom2d_Circle)) ||
286 aPcurve->IsKind(STANDARD_TYPE(Geom2d_Ellipse))) {
288 aT.SetScale (gp::Origin2d(), LengthFact);
289 aPcurve->Transform (aT);
295 // std::cout <<"UnitsMethods: SurfType = "<< aSurface->DynamicType();
299 if (aPcurve->IsKind(STANDARD_TYPE(Geom2d_Conic))) {
300 if (aPcurve->IsKind(STANDARD_TYPE(Geom2d_Circle)) ||
301 aPcurve->IsKind(STANDARD_TYPE(Geom2d_Ellipse))) {
302 Handle(Geom2d_BSplineCurve) aBSpline2d =
303 Geom2dConvert::CurveToBSplineCurve(aPcurve);
304 aPcurve = aBSpline2d;
306 else if (aPcurve->IsKind(STANDARD_TYPE(Geom2d_Parabola))) {
308 std::cout << "PCURVE of Parabola type" << std::endl;
309 std::cout << "Parameters Not Yet transformed according to LenghtUnit" << std::endl;
313 else if (aPcurve->IsKind(STANDARD_TYPE(Geom2d_Hyperbola))) {
315 std::cout << "PCURVE of Hyperbola type" << std::endl;
316 std::cout << "Parameters Not Yet transformed according to LenghtUnit" << std::endl;
324 tMatu.SetAffinity(gp::OY2d(), uFact);
325 tMatv.SetAffinity(gp::OX2d(), vFact);
327 if (aPcurve->IsKind(STANDARD_TYPE(Geom2d_Line))) {
328 Handle(Geom2d_Line) aLine2d = Handle(Geom2d_Line)::DownCast(aPcurve);
330 gp_Pnt2d myLoc = aLine2d->Location();
331 gp_Dir2d myDir = aLine2d->Direction();
334 myNewLoc.SetCoord(myLoc.X()*uFact, myLoc.Y()*vFact);
337 myNewDir.SetCoord(myDir.X()*uFact, myDir.Y()*vFact);
339 aLine2d->SetLocation(myNewLoc);
340 aLine2d->SetDirection(myNewDir);
344 else if (aPcurve->IsKind(STANDARD_TYPE(Geom2d_BSplineCurve))) {
345 Handle(Geom2d_BSplineCurve) aBSpline2d =
346 Handle(Geom2d_BSplineCurve)::DownCast(aPcurve);
348 // transform the Poles of the BSplineCurve according to AngleFact and LengthFact
350 Standard_Integer nbPol = aBSpline2d->NbPoles();
351 for (Standard_Integer i = 1; i<=nbPol ; i++) {
352 pXY = aBSpline2d->Pole(i).XY();
353 tMatu.Transforms(pXY);
354 tMatv.Transforms(pXY);
356 aBSpline2d->SetPole(i, Pt1);
358 aPcurve = aBSpline2d;
362 std::cout << "DegreeToRadian : Type " << aPcurve->DynamicType();
363 std::cout << " not yet implemented" << std::endl;
369 // ============================================================================
372 // ============================================================================
374 Handle(Geom2d_Curve) UnitsMethods::MirrorPCurve
375 (const Handle(Geom2d_Curve) & C2d)
377 Handle(Geom2d_Curve) theMirrored =
378 Handle(Geom2d_Curve)::DownCast(C2d->Copy());
383 gp_Ax2d ax2(Loc, Dir);
385 theMirrored->Transform(T);
389 //=======================================================================
390 //function : GetCasCadeLengthUnit
392 //=======================================================================
394 Standard_Real UnitsMethods::GetCasCadeLengthUnit ()
396 return theCasCadeLengthUnit;
399 //=======================================================================
400 //function : SetCasCadeLengthUnit
402 //=======================================================================
404 void UnitsMethods::SetCasCadeLengthUnit (const Standard_Integer unit)
406 theCasCadeLengthUnit = UnitsMethods::GetLengthFactorValue ( unit );
409 //=======================================================================
410 //function : GetLengthFactorValue
412 //=======================================================================
414 Standard_Real UnitsMethods::GetLengthFactorValue (const Standard_Integer par)
417 case 1 : return 25.4; // inch
418 case 2 : return 1.; // millimeter
420 case 4 : return 304.8; // foot
421 case 5 : return 1609344.; // mile
422 case 6 : return 1000.; // meter
423 case 7 : return 1000000.; // kilometer
424 case 8 : return 0.0254; // mil (0.001 inch)
425 case 9 : return 0.001; // micron
426 case 10 : return 10.; // centimeter
427 case 11 : return 0.0000254; // microinch