0031642: Visualization - crash in Graphic3d_Structure::SetVisual() on redisplaying...
[occt.git] / src / UnitsMethods / UnitsMethods.cxx
CommitLineData
973c2be1 1// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 2//
973c2be1 3// This file is part of Open CASCADE Technology software library.
b311480e 4//
d5f74e42 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
973c2be1 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.
b311480e 10//
973c2be1 11// Alternatively, this file may be used under the terms of Open CASCADE
12// commercial license or contractual agreement.
b311480e 13
7fd59977 14
42cf5bc1 15#include <Geom2d_BoundedCurve.hxx>
7fd59977 16#include <Geom2d_BSplineCurve.hxx>
17#include <Geom2d_Circle.hxx>
42cf5bc1 18#include <Geom2d_Conic.hxx>
7fd59977 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>
42cf5bc1 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>
7fd59977 32#include <gp.hxx>
42cf5bc1 33#include <gp_Dir2d.hxx>
7fd59977 34#include <gp_GTrsf2d.hxx>
7fd59977 35#include <gp_Pnt2d.hxx>
42cf5bc1 36#include <gp_Trsf2d.hxx>
37#include <UnitsMethods.hxx>
7fd59977 38
39static Standard_Real theLengthFactor = 1.;
40static Standard_Real thePlaneAngleFactor = 1.;
41static Standard_Real theSolidAngleFactor = 1.;
42static Standard_Boolean set3d = Standard_True;
43
44static Standard_Real FactRD = 1.;
45static Standard_Real FactDR = 1.;
46
47static Standard_Real theCasCadeLengthUnit = 1.; // abv 28 Feb 00
48
49// ============================================================================
50// Method :
51// Purpose:
52// ============================================================================
53
54void UnitsMethods::InitializeFactors(const Standard_Real LengthFactor, const Standard_Real PlaneAngleFactor, const Standard_Real SolidAngleFactor)
55{
56 theLengthFactor = LengthFactor;
57 thePlaneAngleFactor = PlaneAngleFactor;
58 theSolidAngleFactor = SolidAngleFactor;
59 FactRD = 1./PlaneAngleFactor;
60 FactDR = PlaneAngleFactor;
61}
62
63// ============================================================================
64// Method :
65// Purpose:
66// ============================================================================
67
68Standard_Real UnitsMethods ::LengthFactor()
69{
70 return theLengthFactor;
71}
72
73// ============================================================================
74// Method :
75// Purpose:
76// ============================================================================
77
78Standard_Real UnitsMethods::PlaneAngleFactor()
79{
80 return thePlaneAngleFactor;
81}
82
83// ============================================================================
84// Method :
85// Purpose:
86// ============================================================================
87
88Standard_Real UnitsMethods::SolidAngleFactor()
89{
90 return theSolidAngleFactor;
91}
92
93// ============================================================================
94// Method :
95// Purpose:
96// ============================================================================
97
98void UnitsMethods::Set3dConversion(const Standard_Boolean B)
99{
100 set3d = B;
101}
102
103// ============================================================================
104// Method :
105// Purpose:
106// ============================================================================
107
108Standard_Boolean UnitsMethods::Convert3d()
109{
110 return set3d;
111}
112
113
114// ============================================================================
115// Method :
116// Purpose:
117// ============================================================================
118
119Handle(Geom2d_Curve) UnitsMethods::RadianToDegree
120 (const Handle(Geom2d_Curve) & theCurve2d,
121 const Handle(Geom_Surface) & theSurf)
122{
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
128
129 gp_Pnt2d Pt1;
130 gp_XY pXY;
131 gp_GTrsf2d tMatu , tMatv;
132
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;
139 }
140 else if (theSurf->IsKind(STANDARD_TYPE(Geom_CylindricalSurface))) {
141 uFact = AngleFact;
142 vFact = LengthFact;
143 }
144 else if ( theSurf->IsKind(STANDARD_TYPE(Geom_SurfaceOfRevolution))) {
145 uFact = AngleFact;
146 }
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();
151 uFact = AngleFact;
152 vFact = LengthFact * Cos(semAng);
153 }
154 else if (theSurf->IsKind(STANDARD_TYPE(Geom_Plane))) {
155 uFact = vFact = LengthFact;
72ae9895
RL
156 if (aCurve2d->IsKind(STANDARD_TYPE(Geom2d_Circle)) ||
157 aCurve2d->IsKind(STANDARD_TYPE(Geom2d_Ellipse))) {
158 gp_Trsf2d aT;
159 aT.SetScale (gp::Origin2d(), LengthFact);
160 aCurve2d->Transform (aT);
161 return aCurve2d;
7fd59977 162 }
163 }
164 else {
165// debug
04232180 166// std::cout <<"UnitsMethods: SurfType = "<< aSurface->DynamicType();
7fd59977 167 return aCurve2d;
168 }
169
170 if (aCurve2d->IsKind(STANDARD_TYPE(Geom2d_Line))) {
171 Handle(Geom2d_Line) aLine2d = Handle(Geom2d_Line)::DownCast(aCurve2d);
172
173 gp_Pnt2d myLoc = aLine2d->Location();
174 gp_Dir2d myDir = aLine2d->Direction();
175
176 gp_Pnt2d myNewLoc;
177 myNewLoc.SetCoord(myLoc.X()*uFact, myLoc.Y()*vFact);
178
179 gp_Dir2d myNewDir;
180 myNewDir.SetCoord(myDir.X()*uFact, myDir.Y()*vFact);
181
182 Handle(Geom2d_Line) myNewLine2d = Handle(Geom2d_Line)::DownCast(aLine2d->Copy());
183 myNewLine2d->SetLocation(myNewLoc);
184 myNewLine2d->SetDirection(myNewDir);
185
186 return myNewLine2d;
187 }
188 else if (aCurve2d->IsKind(STANDARD_TYPE(Geom2d_Conic))) {
72ae9895
RL
189 if (aCurve2d->IsKind(STANDARD_TYPE(Geom2d_Circle)) ||
190 aCurve2d->IsKind(STANDARD_TYPE(Geom2d_Ellipse))) {
7fd59977 191 Handle(Geom2d_BSplineCurve) aBSpline2d =
72ae9895 192 Geom2dConvert::CurveToBSplineCurve(aCurve2d);
7fd59977 193 aCurve2d = aBSpline2d;
194 }
7fd59977 195 else if (aCurve2d->IsKind(STANDARD_TYPE(Geom2d_Parabola))) {
0797d9d3 196#ifdef OCCT_DEBUG
04232180 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;
7fd59977 199#endif
200 }
201 else if (aCurve2d->IsKind(STANDARD_TYPE(Geom2d_Hyperbola))) {
0797d9d3 202#ifdef OCCT_DEBUG
04232180 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;
7fd59977 205#endif
206 }
207
208 }
209
210 // Compute affinity
211 tMatu.SetAffinity(gp::OY2d(), uFact);
212 tMatv.SetAffinity(gp::OX2d(), vFact);
213
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);
225 Pt1.SetXY(pXY);
226 myNewBSpline2d->SetPole(i, Pt1);
227 }
228 return myNewBSpline2d;
229 }
230 else {
0797d9d3 231#ifdef OCCT_DEBUG
04232180 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;
7fd59977 234#endif
235 }
236 }
237 return aCurve2d;
238}
239
240//=============================================================================
241// DegreeToRadian: 1. Change definition of the pcurves according to Length
242// Factor
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//=============================================================================
248
249Handle(Geom2d_Curve) UnitsMethods::DegreeToRadian
250 (const Handle(Geom2d_Curve) & thePcurve,
251 const Handle(Geom_Surface) & aSurface)
252{
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
258
259 gp_Pnt2d Pt1;
260 gp_XY pXY;
261 gp_GTrsf2d tMatu , tMatv;
262
263 // What to change ??
264
265 if (aSurface->IsKind(STANDARD_TYPE(Geom_SphericalSurface)) ||
266 aSurface->IsKind(STANDARD_TYPE(Geom_ToroidalSurface))) {
267 uFact = vFact = AngleFact;
268 }
269 else if (aSurface->IsKind(STANDARD_TYPE(Geom_CylindricalSurface))) {
270 uFact = AngleFact;
271 vFact = LengthFact;
272 }
273 else if ( aSurface->IsKind(STANDARD_TYPE(Geom_SurfaceOfRevolution))) {
274 uFact = AngleFact;
275 }
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();
280 uFact = AngleFact;
281 vFact = LengthFact / Cos(semAng);
282 }
283 else if (aSurface->IsKind(STANDARD_TYPE(Geom_Plane))) {
284 uFact = vFact = LengthFact;
72ae9895
RL
285 if (aPcurve->IsKind(STANDARD_TYPE(Geom2d_Circle)) ||
286 aPcurve->IsKind(STANDARD_TYPE(Geom2d_Ellipse))) {
287 gp_Trsf2d aT;
288 aT.SetScale (gp::Origin2d(), LengthFact);
289 aPcurve->Transform (aT);
290 return aPcurve;
7fd59977 291 }
292 }
293 else {
294// debug
04232180 295// std::cout <<"UnitsMethods: SurfType = "<< aSurface->DynamicType();
7fd59977 296 return aPcurve;
297 }
298
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;
305 }
306 else if (aPcurve->IsKind(STANDARD_TYPE(Geom2d_Parabola))) {
0797d9d3 307#ifdef OCCT_DEBUG
04232180 308 std::cout << "PCURVE of Parabola type" << std::endl;
309 std::cout << "Parameters Not Yet transformed according to LenghtUnit" << std::endl;
7fd59977 310#endif
311 return aPcurve;
312 }
313 else if (aPcurve->IsKind(STANDARD_TYPE(Geom2d_Hyperbola))) {
0797d9d3 314#ifdef OCCT_DEBUG
04232180 315 std::cout << "PCURVE of Hyperbola type" << std::endl;
316 std::cout << "Parameters Not Yet transformed according to LenghtUnit" << std::endl;
7fd59977 317#endif
318 return aPcurve;
319 }
320 }
321
322 // Compute affinity
323
324 tMatu.SetAffinity(gp::OY2d(), uFact);
325 tMatv.SetAffinity(gp::OX2d(), vFact);
326
327 if (aPcurve->IsKind(STANDARD_TYPE(Geom2d_Line))) {
328 Handle(Geom2d_Line) aLine2d = Handle(Geom2d_Line)::DownCast(aPcurve);
329
330 gp_Pnt2d myLoc = aLine2d->Location();
331 gp_Dir2d myDir = aLine2d->Direction();
332
333 gp_Pnt2d myNewLoc;
334 myNewLoc.SetCoord(myLoc.X()*uFact, myLoc.Y()*vFact);
335
336 gp_Dir2d myNewDir;
337 myNewDir.SetCoord(myDir.X()*uFact, myDir.Y()*vFact);
338
339 aLine2d->SetLocation(myNewLoc);
340 aLine2d->SetDirection(myNewDir);
341
342 aPcurve = aLine2d;
343 }
344 else if (aPcurve->IsKind(STANDARD_TYPE(Geom2d_BSplineCurve))) {
345 Handle(Geom2d_BSplineCurve) aBSpline2d =
346 Handle(Geom2d_BSplineCurve)::DownCast(aPcurve);
347
348// transform the Poles of the BSplineCurve according to AngleFact and LengthFact
349
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);
355 Pt1.SetXY(pXY);
356 aBSpline2d->SetPole(i, Pt1);
357 }
358 aPcurve = aBSpline2d;
359 }
360 else {
0797d9d3 361#ifdef OCCT_DEBUG
04232180 362 std::cout << "DegreeToRadian : Type " << aPcurve->DynamicType();
363 std::cout << " not yet implemented" << std::endl;
7fd59977 364#endif
365 }
366 return aPcurve;
367}
368
369// ============================================================================
370// Method :
371// Purpose:
372// ============================================================================
373
374Handle(Geom2d_Curve) UnitsMethods::MirrorPCurve
375(const Handle(Geom2d_Curve) & C2d)
376{
377 Handle(Geom2d_Curve) theMirrored =
378 Handle(Geom2d_Curve)::DownCast(C2d->Copy());
379
380 gp_Trsf2d T;
381 gp_Pnt2d Loc(0.,0.);
382 gp_Dir2d Dir(1.,0.);
383 gp_Ax2d ax2(Loc, Dir);
384 T.SetMirror(ax2);
385 theMirrored->Transform(T);
386 return theMirrored;
387}
388
389//=======================================================================
390//function : GetCasCadeLengthUnit
391//purpose :
392//=======================================================================
393
394Standard_Real UnitsMethods::GetCasCadeLengthUnit ()
395{
396 return theCasCadeLengthUnit;
397}
398
399//=======================================================================
400//function : SetCasCadeLengthUnit
401//purpose :
402//=======================================================================
403
404void UnitsMethods::SetCasCadeLengthUnit (const Standard_Integer unit)
405{
406 theCasCadeLengthUnit = UnitsMethods::GetLengthFactorValue ( unit );
407}
408
409//=======================================================================
410//function : GetLengthFactorValue
411//purpose :
412//=======================================================================
413
414Standard_Real UnitsMethods::GetLengthFactorValue (const Standard_Integer par)
415{
416 switch ( par ) {
59336f5c 417 case 1 : return 25.4; // inch
418 case 2 : return 1.; // millimeter
7fd59977 419
59336f5c 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
7fd59977 428 default : return 1.;
429 }
430}
431