e2a98a2fdc74d42919b89b20a3379f0ba37107ce
[occt.git] / src / StepToGeom / StepToGeom.cxx
1 // Created on: 1993-06-15
2 // Created by: Martine LANGLOIS
3 // Copyright (c) 1993-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17 #include <StepToGeom.hxx>
18
19 #include <BRep_Tool.hxx>
20 #include <BRepBuilderAPI_MakeFace.hxx>
21 #include <ElCLib.hxx>
22
23 #include <Geom_Axis1Placement.hxx>
24 #include <Geom_Axis2Placement.hxx>
25 #include <Geom_BoundedCurve.hxx>
26 #include <Geom_BoundedSurface.hxx>
27 #include <Geom_BSplineCurve.hxx>
28 #include <Geom_BSplineSurface.hxx>
29 #include <Geom_CartesianPoint.hxx>
30 #include <Geom_Circle.hxx>
31 #include <Geom_Conic.hxx>
32 #include <Geom_ConicalSurface.hxx>
33 #include <Geom_Curve.hxx>
34 #include <Geom_CylindricalSurface.hxx>
35 #include <Geom_Direction.hxx>
36 #include <Geom_ElementarySurface.hxx>
37 #include <Geom_Ellipse.hxx>
38 #include <Geom_Hyperbola.hxx>
39 #include <Geom_Line.hxx>
40 #include <Geom_OffsetCurve.hxx>
41 #include <Geom_OffsetSurface.hxx>
42 #include <Geom_Parabola.hxx>
43 #include <Geom_Plane.hxx>
44 #include <Geom_RectangularTrimmedSurface.hxx>
45 #include <Geom_SphericalSurface.hxx>
46 #include <Geom_Surface.hxx>
47 #include <Geom_SurfaceOfLinearExtrusion.hxx>
48 #include <Geom_SurfaceOfRevolution.hxx>
49 #include <Geom_SweptSurface.hxx>
50 #include <Geom_ToroidalSurface.hxx>
51 #include <Geom_TrimmedCurve.hxx>
52 #include <Geom_VectorWithMagnitude.hxx>
53
54 #include <Geom2d_AxisPlacement.hxx>
55 #include <Geom2d_BoundedCurve.hxx>
56 #include <Geom2d_BSplineCurve.hxx>
57 #include <Geom2d_CartesianPoint.hxx>
58 #include <Geom2d_Circle.hxx>
59 #include <Geom2d_Conic.hxx>
60 #include <Geom2d_Curve.hxx>
61 #include <Geom2d_Direction.hxx>
62 #include <Geom2d_Ellipse.hxx>
63 #include <Geom2d_Hyperbola.hxx>
64 #include <Geom2d_Line.hxx>
65 #include <Geom2d_Parabola.hxx>
66 #include <Geom2d_TrimmedCurve.hxx>
67 #include <Geom2d_VectorWithMagnitude.hxx>
68 #include <Geom2dConvert.hxx>
69
70 #include <gp_Trsf.hxx>
71 #include <gp_Trsf2d.hxx>
72 #include <gp_Lin.hxx>
73 #include <gp_Lin2d.hxx>
74
75 #include <ShapeAlgo.hxx>
76 #include <ShapeAlgo_AlgoContainer.hxx>
77 #include <ShapeAnalysis_Curve.hxx>
78
79 #include <StepGeom_Axis1Placement.hxx>
80 #include <StepGeom_Axis2Placement2d.hxx>
81 #include <StepGeom_Axis2Placement3d.hxx>
82 #include <StepGeom_BoundedCurve.hxx>
83 #include <StepGeom_BoundedSurface.hxx>
84 #include <StepGeom_BSplineCurve.hxx>
85 #include <StepGeom_CartesianPoint.hxx>
86 #include <StepGeom_Direction.hxx>
87
88 #include <Standard_ErrorHandler.hxx>
89 #include <Standard_Failure.hxx>
90
91 #include <StepGeom_BezierCurve.hxx>
92 #include <StepGeom_BezierSurface.hxx>
93 #include <StepGeom_BSplineSurface.hxx>
94 #include <StepGeom_BSplineCurveWithKnots.hxx>
95 #include <StepGeom_BSplineCurveWithKnotsAndRationalBSplineCurve.hxx>
96 #include <StepGeom_BSplineSurfaceWithKnots.hxx>
97 #include <StepGeom_BSplineSurfaceWithKnotsAndRationalBSplineSurface.hxx>
98 #include <StepGeom_Circle.hxx>
99 #include <StepGeom_Conic.hxx>
100 #include <StepGeom_ConicalSurface.hxx>
101 #include <StepGeom_Curve.hxx>
102 #include <StepGeom_CurveReplica.hxx>
103 #include <StepGeom_CylindricalSurface.hxx>
104 #include <StepGeom_ElementarySurface.hxx>
105 #include <StepGeom_Ellipse.hxx>
106 #include <StepGeom_Hyperbola.hxx>
107 #include <StepGeom_Line.hxx>
108 #include <StepGeom_OffsetCurve3d.hxx>
109 #include <StepGeom_OffsetSurface.hxx>
110 #include <StepGeom_Parabola.hxx>
111 #include <StepGeom_Plane.hxx>
112 #include <StepGeom_Polyline.hxx>
113 #include <StepGeom_QuasiUniformCurve.hxx>
114 #include <StepGeom_QuasiUniformCurveAndRationalBSplineCurve.hxx>
115 #include <StepGeom_QuasiUniformSurface.hxx>
116 #include <StepGeom_QuasiUniformSurfaceAndRationalBSplineSurface.hxx>
117 #include <StepGeom_RectangularTrimmedSurface.hxx>
118 #include <StepGeom_SphericalSurface.hxx>
119 #include <StepGeom_Surface.hxx>
120 #include <StepGeom_SurfaceCurve.hxx>
121 #include <StepGeom_SurfaceOfLinearExtrusion.hxx>
122 #include <StepGeom_SurfaceOfRevolution.hxx>
123 #include <StepGeom_SurfaceReplica.hxx>
124 #include <StepGeom_SweptSurface.hxx>
125 #include <StepGeom_ToroidalSurface.hxx>
126 #include <StepGeom_CartesianTransformationOperator2d.hxx>
127 #include <StepGeom_CartesianTransformationOperator3d.hxx>
128 #include <StepGeom_TrimmedCurve.hxx>
129 #include <StepGeom_UniformCurve.hxx>
130 #include <StepGeom_UniformCurveAndRationalBSplineCurve.hxx>
131 #include <StepGeom_UniformSurface.hxx>
132 #include <StepGeom_UniformSurfaceAndRationalBSplineSurface.hxx>
133 #include <StepGeom_Vector.hxx>
134
135 #include <TopoDS.hxx>
136 #include <TopoDS_Face.hxx>
137
138 #include <UnitsMethods.hxx>
139
140 //=============================================================================
141 // Creation d' un Ax1Placement de Geom a partir d' un axis1_placement de Step
142 //=============================================================================
143
144 Handle(Geom_Axis1Placement) StepToGeom::MakeAxis1Placement (const Handle(StepGeom_Axis1Placement)& SA)
145 {
146   Handle(Geom_CartesianPoint) P = MakeCartesianPoint (SA->Location());
147   if (! P.IsNull())
148   {
149     // sln 22.10.2001. CTS23496: If problems with creation of axis direction occur default direction is used
150     gp_Dir D(0.,0.,1.);
151     if (SA->HasAxis())
152     {
153       Handle(Geom_Direction) D1 = MakeDirection (SA->Axis());
154       if (! D1.IsNull())
155         D = D1->Dir();
156     }
157     return new Geom_Axis1Placement(P->Pnt(),D);
158   }
159   return 0;
160 }
161
162 //=============================================================================
163 // Creation d' un Axis2Placement de Geom a partir d' un axis2_placement_3d de Step
164 //=============================================================================
165
166 Handle(Geom_Axis2Placement) StepToGeom::MakeAxis2Placement (const Handle(StepGeom_Axis2Placement3d)& SA)
167 {
168   Handle(Geom_CartesianPoint) P = MakeCartesianPoint (SA->Location());
169   if (! P.IsNull())
170   {
171     const gp_Pnt Pgp = P->Pnt();
172
173     // sln 22.10.2001. CTS23496: If problems with creation of direction occur default direction is used (MakeLine(...) function)
174     gp_Dir Ngp(0.,0.,1.);
175     if (SA->HasAxis())
176     {
177       Handle(Geom_Direction) D = MakeDirection (SA->Axis());
178       if (! D.IsNull())
179         Ngp = D->Dir();
180     }
181
182     gp_Ax2 gpAx2;
183     Standard_Boolean isDefaultDirectionUsed = Standard_True;
184     if (SA->HasRefDirection())
185     {
186       Handle(Geom_Direction) D = MakeDirection (SA->RefDirection());
187       if (! D.IsNull())
188       {
189         const gp_Dir Vxgp = D->Dir();
190         if (!Ngp.IsParallel(Vxgp,Precision::Angular()))
191         {
192           gpAx2 = gp_Ax2(Pgp, Ngp, Vxgp);
193           isDefaultDirectionUsed = Standard_False;
194         }
195       }
196     }
197     if(isDefaultDirectionUsed)
198       gpAx2 = gp_Ax2(Pgp, Ngp);
199
200     return new Geom_Axis2Placement(gpAx2);
201   }
202   return 0;
203 }
204
205 //=============================================================================
206 // Creation d' un AxisPlacement de Geom2d a partir d' un axis2_placement_3d de Step
207 //=============================================================================
208
209 Handle(Geom2d_AxisPlacement) StepToGeom::MakeAxisPlacement (const Handle(StepGeom_Axis2Placement2d)& SA)
210 {
211   Handle(Geom2d_CartesianPoint) P = MakeCartesianPoint2d (SA->Location());
212   if (! P.IsNull())
213   {
214     // sln 23.10.2001. CTS23496: If problems with creation of direction occur default direction is used
215     gp_Dir2d Vxgp(1.,0.);
216     if (SA->HasRefDirection()) {
217       Handle(Geom2d_Direction) Vx = MakeDirection2d (SA->RefDirection());
218       if (! Vx.IsNull())
219         Vxgp = Vx->Dir2d();
220     }
221
222     return new Geom2d_AxisPlacement(P->Pnt2d(),Vxgp);
223   }
224   return 0;
225 }
226
227 //=============================================================================
228 // Creation d' une BoundedCurve de Geom a partir d' une BoundedCurve de Step
229 //=============================================================================
230
231 Handle(Geom_BoundedCurve) StepToGeom::MakeBoundedCurve (const Handle(StepGeom_BoundedCurve)& SC)
232 {
233   if (SC->IsKind(STANDARD_TYPE(StepGeom_BSplineCurveWithKnotsAndRationalBSplineCurve)))
234   {
235     return MakeBSplineCurve (Handle(StepGeom_BSplineCurveWithKnotsAndRationalBSplineCurve)::DownCast(SC));
236   }
237   if (SC->IsKind(STANDARD_TYPE(StepGeom_BSplineCurveWithKnots)))
238   {
239     return MakeBSplineCurve (Handle(StepGeom_BSplineCurveWithKnots)::DownCast(SC));
240   }
241   if (SC->IsKind(STANDARD_TYPE(StepGeom_TrimmedCurve)))
242   {
243     return MakeTrimmedCurve (Handle(StepGeom_TrimmedCurve)::DownCast(SC));
244   }
245
246   // STEP BezierCurve, UniformCurve and QuasiUniformCurve are transformed into
247   // STEP BSplineCurve before being mapped onto CAS.CADE/SF
248   if (SC->IsKind(STANDARD_TYPE(StepGeom_BezierCurve)))
249   {
250     const Handle(StepGeom_BezierCurve) BzC = Handle(StepGeom_BezierCurve)::DownCast(SC);
251     Standard_Integer aDegree = BzC->Degree();
252     if (aDegree < 1 || aDegree > Geom_BSplineCurve::MaxDegree())
253       return 0;
254     const Handle(StepGeom_BSplineCurveWithKnots) BSPL = new StepGeom_BSplineCurveWithKnots;
255     BSPL->SetDegree(aDegree);
256     BSPL->SetControlPointsList(BzC->ControlPointsList());
257     BSPL->SetCurveForm(BzC->CurveForm());
258     BSPL->SetClosedCurve(BzC->ClosedCurve());
259     BSPL->SetSelfIntersect(BzC->SelfIntersect());
260     // Compute Knots and KnotsMultiplicity
261     const Handle(TColStd_HArray1OfInteger) Kmult = new TColStd_HArray1OfInteger(1,2);
262     const Handle(TColStd_HArray1OfReal) Knots = new TColStd_HArray1OfReal(1,2);
263     Kmult->SetValue(1, BzC->Degree() + 1);
264     Kmult->SetValue(2, BzC->Degree() + 1);
265     Knots->SetValue(1, 0.);
266     Knots->SetValue(2, 1.);
267     BSPL->SetKnotMultiplicities(Kmult);
268     BSPL->SetKnots(Knots);
269
270     return MakeBSplineCurve (BSPL);
271   }
272
273   if (SC->IsKind(STANDARD_TYPE(StepGeom_UniformCurve)))
274   {
275     const Handle(StepGeom_UniformCurve) UC = Handle(StepGeom_UniformCurve)::DownCast(SC);
276     Standard_Integer aDegree = UC->Degree();
277     if (aDegree < 1 || aDegree > Geom_BSplineCurve::MaxDegree())
278       return 0;
279     const Handle(StepGeom_BSplineCurveWithKnots) BSPL = new StepGeom_BSplineCurveWithKnots;
280     BSPL->SetDegree(aDegree);
281     BSPL->SetControlPointsList(UC->ControlPointsList());
282     BSPL->SetCurveForm(UC->CurveForm());
283     BSPL->SetClosedCurve(UC->ClosedCurve());
284     BSPL->SetSelfIntersect(UC->SelfIntersect());
285
286     // Compute Knots and KnotsMultiplicity
287     const Standard_Integer nbK = BSPL->NbControlPointsList() + BSPL->Degree() + 1;
288     const Handle(TColStd_HArray1OfInteger) Kmult = new TColStd_HArray1OfInteger(1,nbK);
289     const Handle(TColStd_HArray1OfReal) Knots = new TColStd_HArray1OfReal(1,nbK);
290     for (Standard_Integer iUC = 1 ; iUC <= nbK ; iUC ++) {
291       Kmult->SetValue(iUC, 1);
292       Knots->SetValue(iUC, iUC - 1.);
293     }
294     BSPL->SetKnotMultiplicities(Kmult);
295     BSPL->SetKnots(Knots);
296
297     return MakeBSplineCurve (BSPL);
298   }
299
300   if (SC->IsKind(STANDARD_TYPE(StepGeom_QuasiUniformCurve)))
301   {
302     const Handle(StepGeom_QuasiUniformCurve) QUC =
303       Handle(StepGeom_QuasiUniformCurve)::DownCast(SC);
304     Standard_Integer aDegree = QUC->Degree();
305     if (aDegree < 1 || aDegree > Geom_BSplineCurve::MaxDegree())
306       return 0;
307     const Handle(StepGeom_BSplineCurveWithKnots) BSPL = new StepGeom_BSplineCurveWithKnots;
308     BSPL->SetDegree(aDegree);
309     BSPL->SetControlPointsList(QUC->ControlPointsList());
310     BSPL->SetCurveForm(QUC->CurveForm());
311     BSPL->SetClosedCurve(QUC->ClosedCurve());
312     BSPL->SetSelfIntersect(QUC->SelfIntersect());
313
314     // Compute Knots and KnotsMultiplicity
315     const Standard_Integer nbK = BSPL->NbControlPointsList() - BSPL->Degree() + 1;
316     const Handle(TColStd_HArray1OfInteger) Kmult = new TColStd_HArray1OfInteger(1,nbK);
317     const Handle(TColStd_HArray1OfReal) Knots = new TColStd_HArray1OfReal(1,nbK);
318     for (Standard_Integer iQUC = 1 ; iQUC <= nbK ; iQUC ++) {
319       Kmult->SetValue(iQUC, 1);
320       Knots->SetValue(iQUC, iQUC - 1.);
321     }
322     Kmult->SetValue(1, BSPL->Degree() + 1);
323     Kmult->SetValue(nbK, BSPL->Degree() + 1);
324     BSPL->SetKnotMultiplicities(Kmult);
325     BSPL->SetKnots(Knots);
326
327     return MakeBSplineCurve (BSPL);
328   }
329
330   if (SC->IsKind(STANDARD_TYPE(StepGeom_UniformCurveAndRationalBSplineCurve)))
331   {
332     const Handle(StepGeom_UniformCurveAndRationalBSplineCurve) RUC =
333       Handle(StepGeom_UniformCurveAndRationalBSplineCurve)::DownCast(SC);
334     Standard_Integer aDegree = RUC->Degree();
335     if (aDegree < 1 || aDegree > Geom_BSplineCurve::MaxDegree())
336       return 0;
337     const Handle(StepGeom_BSplineCurveWithKnotsAndRationalBSplineCurve) RBSPL =
338       new StepGeom_BSplineCurveWithKnotsAndRationalBSplineCurve;
339
340     // Compute Knots and KnotsMultiplicity
341     const Standard_Integer nbK = RUC->NbControlPointsList() + aDegree + 1;
342     const Handle(TColStd_HArray1OfInteger) Kmult = new TColStd_HArray1OfInteger(1,nbK);
343     const Handle(TColStd_HArray1OfReal) Knots = new TColStd_HArray1OfReal(1,nbK);
344     for (Standard_Integer iUC = 1 ; iUC <= nbK ; iUC ++) {
345       Kmult->SetValue(iUC, 1);
346       Knots->SetValue(iUC, iUC - 1.);
347     }
348
349     // Initialize the BSplineCurveWithKnotsAndRationalBSplineCurve
350     RBSPL->Init(RUC->Name(), aDegree, RUC->ControlPointsList(), RUC->CurveForm(),
351                 RUC->ClosedCurve(), RUC->SelfIntersect(), Kmult, Knots, StepGeom_ktUnspecified,
352                 RUC->WeightsData());
353
354     return MakeBSplineCurve (RBSPL);
355   }
356
357   if (SC->IsKind(STANDARD_TYPE(StepGeom_QuasiUniformCurveAndRationalBSplineCurve)))
358   {
359     const Handle(StepGeom_QuasiUniformCurveAndRationalBSplineCurve) RQUC =
360       Handle(StepGeom_QuasiUniformCurveAndRationalBSplineCurve)::DownCast(SC);
361     Standard_Integer aDegree = RQUC->Degree();
362     if (aDegree < 1 || aDegree > Geom_BSplineCurve::MaxDegree())
363       return 0;
364     const Handle(StepGeom_BSplineCurveWithKnotsAndRationalBSplineCurve) RBSPL =
365       new StepGeom_BSplineCurveWithKnotsAndRationalBSplineCurve;
366
367     // Compute Knots and KnotsMultiplicity
368     const Standard_Integer nbK = RQUC->NbControlPointsList() - aDegree + 1;
369     const Handle(TColStd_HArray1OfInteger) Kmult = new TColStd_HArray1OfInteger(1,nbK);
370     const Handle(TColStd_HArray1OfReal) Knots = new TColStd_HArray1OfReal(1,nbK);
371     for (Standard_Integer iRQUC = 1 ; iRQUC <= nbK ; iRQUC ++) {
372       Kmult->SetValue(iRQUC, 1);
373       Knots->SetValue(iRQUC, iRQUC - 1.);
374     }
375     Kmult->SetValue(1, aDegree + 1);
376     Kmult->SetValue(nbK, aDegree + 1);
377     // Initialize the BSplineCurveWithKnotsAndRationalBSplineCurve
378     RBSPL->Init(RQUC->Name(), aDegree, RQUC->ControlPointsList(), RQUC->CurveForm(),
379                 RQUC->ClosedCurve(), RQUC->SelfIntersect(), Kmult, Knots, StepGeom_ktUnspecified,
380                 RQUC->WeightsData());
381
382     return MakeBSplineCurve (RBSPL);
383   }
384
385   if (SC->IsKind(STANDARD_TYPE(StepGeom_Polyline)))
386   { //:n6 abv 15 Feb 99
387     return MakePolyline (Handle(StepGeom_Polyline)::DownCast (SC));
388   }
389
390   return 0;
391 }
392
393 //=============================================================================
394 // Creation d' une BoundedCurve de Geom a partir d' une BoundedCurve de Step
395 //=============================================================================
396
397 Handle(Geom2d_BoundedCurve) StepToGeom::MakeBoundedCurve2d (const Handle(StepGeom_BoundedCurve)& SC)
398 {
399   if (SC->IsKind(STANDARD_TYPE(StepGeom_BSplineCurveWithKnotsAndRationalBSplineCurve)))
400   {
401     return MakeBSplineCurve2d (Handle(StepGeom_BSplineCurveWithKnotsAndRationalBSplineCurve)::DownCast(SC));
402   }
403   if (SC->IsKind(STANDARD_TYPE(StepGeom_BSplineCurveWithKnots)))
404   {
405     return MakeBSplineCurve2d (Handle(StepGeom_BSplineCurveWithKnots)::DownCast(SC));
406   }
407   if (SC->IsKind(STANDARD_TYPE(StepGeom_TrimmedCurve)))
408   {
409     return MakeTrimmedCurve2d (Handle(StepGeom_TrimmedCurve)::DownCast(SC));
410   }
411   if (SC->IsKind(STANDARD_TYPE(StepGeom_Polyline)))
412   { //:n6 abv 15 Feb 99
413     return MakePolyline2d (Handle(StepGeom_Polyline)::DownCast(SC));
414   }
415   return Handle(Geom2d_BoundedCurve)();
416 }
417
418 //=============================================================================
419 // Creation d' une BoundedSurface de Geom a partir d' une BoundedSurface de Step
420 //=============================================================================
421
422 Handle(Geom_BoundedSurface) StepToGeom::MakeBoundedSurface (const Handle(StepGeom_BoundedSurface)& SS)
423 {
424   if (SS->IsKind(STANDARD_TYPE(StepGeom_BSplineSurfaceWithKnotsAndRationalBSplineSurface)))
425   {
426     return MakeBSplineSurface (Handle(StepGeom_BSplineSurfaceWithKnotsAndRationalBSplineSurface)::DownCast(SS));
427   }
428   if (SS->IsKind(STANDARD_TYPE(StepGeom_BSplineSurfaceWithKnots)))
429   {
430     return MakeBSplineSurface (Handle(StepGeom_BSplineSurfaceWithKnots)::DownCast(SS));
431   }
432   if (SS->IsKind(STANDARD_TYPE(StepGeom_RectangularTrimmedSurface)))
433   {
434     return MakeRectangularTrimmedSurface (Handle(StepGeom_RectangularTrimmedSurface)::DownCast(SS));
435   }
436
437   // STEP BezierSurface, UniformSurface and QuasiUniformSurface are transformed
438   // into STEP BSplineSurface before being mapped onto CAS.CADE/SF
439   if (SS->IsKind(STANDARD_TYPE(StepGeom_BezierSurface))) {
440     const Handle(StepGeom_BezierSurface) BzS = Handle(StepGeom_BezierSurface)::DownCast(SS);
441     const Handle(StepGeom_BSplineSurfaceWithKnots) BSPL = new StepGeom_BSplineSurfaceWithKnots;
442     BSPL->SetUDegree(BzS->UDegree());
443     BSPL->SetVDegree(BzS->VDegree());
444     BSPL->SetControlPointsList(BzS->ControlPointsList());
445     BSPL->SetSurfaceForm(BzS->SurfaceForm());
446     BSPL->SetUClosed(BzS->UClosed());
447     BSPL->SetVClosed(BzS->VClosed());
448     BSPL->SetSelfIntersect(BzS->SelfIntersect());
449
450     // Compute Knots and KnotsMultiplicity
451     const Handle(TColStd_HArray1OfInteger) UKmult = new TColStd_HArray1OfInteger(1,2);
452     const Handle(TColStd_HArray1OfInteger) VKmult = new TColStd_HArray1OfInteger(1,2);
453     const Handle(TColStd_HArray1OfReal) UKnots = new TColStd_HArray1OfReal(1,2);
454     const Handle(TColStd_HArray1OfReal) VKnots = new TColStd_HArray1OfReal(1,2);
455     UKmult->SetValue(1, BzS->UDegree() + 1);
456     UKmult->SetValue(2, BzS->UDegree() + 1);
457     VKmult->SetValue(1, BzS->VDegree() + 1);
458     VKmult->SetValue(2, BzS->VDegree() + 1);
459     UKnots->SetValue(1, 0.);
460     UKnots->SetValue(2, 1.);
461     VKnots->SetValue(1, 0.);
462     VKnots->SetValue(2, 1.);
463     BSPL->SetUMultiplicities(UKmult);
464     BSPL->SetVMultiplicities(VKmult);
465     BSPL->SetUKnots(UKnots);
466     BSPL->SetVKnots(VKnots);
467
468     return MakeBSplineSurface (BSPL);
469   }
470
471   if (SS->IsKind(STANDARD_TYPE(StepGeom_UniformSurface)))
472   {
473     const Handle(StepGeom_UniformSurface) US = Handle(StepGeom_UniformSurface)::DownCast(SS);
474     const Handle(StepGeom_BSplineSurfaceWithKnots) BSPL = new StepGeom_BSplineSurfaceWithKnots;
475     BSPL->SetUDegree(US->UDegree());
476     BSPL->SetVDegree(US->VDegree());
477     BSPL->SetControlPointsList(US->ControlPointsList());
478     BSPL->SetSurfaceForm(US->SurfaceForm());
479     BSPL->SetUClosed(US->UClosed());
480     BSPL->SetVClosed(US->VClosed());
481     BSPL->SetSelfIntersect(US->SelfIntersect());
482
483     // Compute Knots and KnotsMultiplicity for U Direction
484     const Standard_Integer nbKU = BSPL->NbControlPointsListI() + BSPL->UDegree() + 1;
485     const Handle(TColStd_HArray1OfInteger) UKmult = new TColStd_HArray1OfInteger(1,nbKU);
486     const Handle(TColStd_HArray1OfReal) UKnots = new TColStd_HArray1OfReal(1,nbKU);
487     for (Standard_Integer iU = 1 ; iU <= nbKU ; iU ++) {
488       UKmult->SetValue(iU, 1);
489       UKnots->SetValue(iU, iU - 1.);
490     }
491     BSPL->SetUMultiplicities(UKmult);
492     BSPL->SetUKnots(UKnots);
493
494     // Compute Knots and KnotsMultiplicity for V Direction
495     const Standard_Integer nbKV = BSPL->NbControlPointsListJ() + BSPL->VDegree() + 1;
496     const Handle(TColStd_HArray1OfInteger) VKmult = new TColStd_HArray1OfInteger(1,nbKV);
497     const Handle(TColStd_HArray1OfReal) VKnots = new TColStd_HArray1OfReal(1,nbKV);
498     for (Standard_Integer iV = 1 ; iV <= nbKV ; iV ++) {
499       VKmult->SetValue(iV, 1);
500       VKnots->SetValue(iV, iV - 1.);
501     }
502     BSPL->SetVMultiplicities(VKmult);
503     BSPL->SetVKnots(VKnots);
504
505     return MakeBSplineSurface (BSPL);
506   }
507
508   if (SS->IsKind(STANDARD_TYPE(StepGeom_QuasiUniformSurface)))
509   {
510     const Handle(StepGeom_QuasiUniformSurface) QUS =
511       Handle(StepGeom_QuasiUniformSurface)::DownCast(SS);
512     const Handle(StepGeom_BSplineSurfaceWithKnots) BSPL = new StepGeom_BSplineSurfaceWithKnots;
513     BSPL->SetUDegree(QUS->UDegree());
514     BSPL->SetVDegree(QUS->VDegree());
515     BSPL->SetControlPointsList(QUS->ControlPointsList());
516     BSPL->SetSurfaceForm(QUS->SurfaceForm());
517     BSPL->SetUClosed(QUS->UClosed());
518     BSPL->SetVClosed(QUS->VClosed());
519     BSPL->SetSelfIntersect(QUS->SelfIntersect());
520
521     // Compute Knots and KnotsMultiplicity for U Direction
522     const Standard_Integer nbKU = BSPL->NbControlPointsListI() - BSPL->UDegree() + 1;
523     const Handle(TColStd_HArray1OfInteger) UKmult = new TColStd_HArray1OfInteger(1,nbKU);
524     const Handle(TColStd_HArray1OfReal) UKnots = new TColStd_HArray1OfReal(1,nbKU);
525     for (Standard_Integer iU = 1 ; iU <= nbKU ; iU ++) {
526       UKmult->SetValue(iU, 1);
527       UKnots->SetValue(iU, iU - 1.);
528     }
529     UKmult->SetValue(1, BSPL->UDegree() + 1);
530     UKmult->SetValue(nbKU, BSPL->UDegree() + 1);
531     BSPL->SetUMultiplicities(UKmult);
532     BSPL->SetUKnots(UKnots);
533
534     // Compute Knots and KnotsMultiplicity for V Direction
535     const Standard_Integer nbKV = BSPL->NbControlPointsListJ() - BSPL->VDegree() + 1;
536     const Handle(TColStd_HArray1OfInteger) VKmult = new TColStd_HArray1OfInteger(1,nbKV);
537     const Handle(TColStd_HArray1OfReal) VKnots = new TColStd_HArray1OfReal(1,nbKV);
538     for (Standard_Integer iV = 1 ; iV <= nbKV ; iV ++) {
539       VKmult->SetValue(iV, 1);
540       VKnots->SetValue(iV, iV - 1.);
541     }
542     VKmult->SetValue(1, BSPL->VDegree() + 1);
543     VKmult->SetValue(nbKV, BSPL->VDegree() + 1);
544     BSPL->SetVMultiplicities(VKmult);
545     BSPL->SetVKnots(VKnots);
546
547     return MakeBSplineSurface (BSPL);
548   }
549
550   if (SS->IsKind(STANDARD_TYPE(StepGeom_UniformSurfaceAndRationalBSplineSurface)))
551   {
552     const Handle(StepGeom_UniformSurfaceAndRationalBSplineSurface) RUS =
553       Handle(StepGeom_UniformSurfaceAndRationalBSplineSurface)::DownCast(SS);
554     const Handle(StepGeom_BSplineSurfaceWithKnotsAndRationalBSplineSurface) RBSPL =
555       new StepGeom_BSplineSurfaceWithKnotsAndRationalBSplineSurface;
556
557     // Compute Knots and KnotsMultiplicity for U Direction
558     const Standard_Integer nbKU = RUS->NbControlPointsListI() + RUS->UDegree() + 1;
559     const Handle(TColStd_HArray1OfInteger) UKmult = new TColStd_HArray1OfInteger(1,nbKU);
560     const Handle(TColStd_HArray1OfReal) UKnots = new TColStd_HArray1OfReal(1,nbKU);
561     for (Standard_Integer iU = 1 ; iU <= nbKU ; iU ++) {
562       UKmult->SetValue(iU, 1);
563       UKnots->SetValue(iU, iU - 1.);
564     }
565
566     // Compute Knots and KnotsMultiplicity for V Direction
567     const Standard_Integer nbKV = RUS->NbControlPointsListJ() + RUS->VDegree() + 1;
568     const Handle(TColStd_HArray1OfInteger) VKmult = new TColStd_HArray1OfInteger(1,nbKV);
569     const Handle(TColStd_HArray1OfReal) VKnots = new TColStd_HArray1OfReal(1,nbKV);
570     for (Standard_Integer iV = 1 ; iV <= nbKV ; iV ++) {
571       VKmult->SetValue(iV, 1);
572       VKnots->SetValue(iV, iV - 1.);
573     }
574
575     // Initialize the BSplineSurfaceWithKnotsAndRationalBSplineSurface
576     RBSPL->Init(RUS->Name(), RUS->UDegree(), RUS->VDegree(),
577                 RUS->ControlPointsList(), RUS->SurfaceForm(),
578                 RUS->UClosed(), RUS->VClosed(), RUS->SelfIntersect(),
579                 UKmult, VKmult, UKnots, VKnots, StepGeom_ktUnspecified,
580                 RUS->WeightsData());
581
582     return MakeBSplineSurface (RBSPL);
583   }
584
585   if (SS->IsKind(STANDARD_TYPE(StepGeom_QuasiUniformSurfaceAndRationalBSplineSurface)))
586   {
587     const Handle(StepGeom_QuasiUniformSurfaceAndRationalBSplineSurface) RQUS =
588       Handle(StepGeom_QuasiUniformSurfaceAndRationalBSplineSurface)::DownCast(SS);
589     const Handle(StepGeom_BSplineSurfaceWithKnotsAndRationalBSplineSurface) RBSPL =
590       new StepGeom_BSplineSurfaceWithKnotsAndRationalBSplineSurface;
591
592     // Compute Knots and KnotsMultiplicity for U Direction
593     const Standard_Integer nbKU = RQUS->NbControlPointsListI() - RQUS->UDegree() + 1;
594     const Handle(TColStd_HArray1OfInteger) UKmult = new TColStd_HArray1OfInteger(1,nbKU);
595     const Handle(TColStd_HArray1OfReal) UKnots = new TColStd_HArray1OfReal(1,nbKU);
596     for (Standard_Integer iU = 1 ; iU <= nbKU ; iU ++) {
597       UKmult->SetValue(iU, 1);
598       UKnots->SetValue(iU, iU - 1.);
599     }
600     UKmult->SetValue(1, RQUS->UDegree() + 1);
601     UKmult->SetValue(nbKU, RQUS->UDegree() + 1);
602
603     // Compute Knots and KnotsMultiplicity for V Direction
604     const Standard_Integer nbKV = RQUS->NbControlPointsListJ() - RQUS->VDegree() + 1;
605     const Handle(TColStd_HArray1OfInteger) VKmult = new TColStd_HArray1OfInteger(1,nbKV);
606     const Handle(TColStd_HArray1OfReal) VKnots = new TColStd_HArray1OfReal(1,nbKV);
607     for (Standard_Integer iV = 1 ; iV <= nbKV ; iV ++) {
608       VKmult->SetValue(iV, 1);
609       VKnots->SetValue(iV, iV - 1.);
610     }
611     VKmult->SetValue(1, RQUS->VDegree() + 1);
612     VKmult->SetValue(nbKV, RQUS->VDegree() + 1);
613
614     // Initialize the BSplineSurfaceWithKnotsAndRationalBSplineSurface
615     RBSPL->Init(RQUS->Name(), RQUS->UDegree(), RQUS->VDegree(), RQUS->ControlPointsList(),
616                 RQUS->SurfaceForm(), RQUS->UClosed(), RQUS->VClosed(),
617                 RQUS->SelfIntersect(), UKmult, VKmult, UKnots, VKnots, StepGeom_ktUnspecified,
618                 RQUS->WeightsData());
619     return MakeBSplineSurface (RBSPL);
620   }
621
622   return 0;
623 }
624
625 //=============================================================================
626 // Creation d' une BSplineCurve de Geom a partir d' une BSplineCurve de Step
627 //=============================================================================
628
629 Handle(Geom_BSplineCurve) StepToGeom::MakeBSplineCurve (const Handle(StepGeom_BSplineCurve)& SC)
630 {
631 #define Array1OfPnt_gen                  TColgp_Array1OfPnt
632 #define Pnt_gen                          gp_Pnt
633 #define Pnt_fonc                         Pnt
634 #define CartesianPoint_gen               Handle(Geom_CartesianPoint)
635 #define MakeCartesianPoint_gen MakeCartesianPoint
636 #define BSplineCurve_gen                 Geom_BSplineCurve
637 #define BSplineCurve_retour              Handle(Geom_BSplineCurve)
638 #define MakeBSplineCurve_gen   MakeBSplineCurve
639 #include "StepToGeom_MakeBSplineCurve.pxx"
640 #undef Array1OfPnt_gen
641 #undef Pnt_gen
642 #undef Pnt_fonc
643 #undef CartesianPoint_gen
644 #undef MakeCartesianPoint_gen
645 #undef BSplineCurve_gen
646 #undef MakeBSplineCurve_gen
647 #undef BSplineCurve_retour
648 }
649
650 //=============================================================================
651 // Creation d' une BSplineCurve de Geom2d a partir d' une
652 // BSplineCurveWithKnotsAndRationalBSplineCurve de Step
653 //=============================================================================
654
655 Handle(Geom2d_BSplineCurve) StepToGeom::MakeBSplineCurve2d (const Handle(StepGeom_BSplineCurve)& SC)
656 {
657 #define Array1OfPnt_gen                  TColgp_Array1OfPnt2d
658 #define Pnt_gen                          gp_Pnt2d
659 #define CartesianPoint_gen               Handle(Geom2d_CartesianPoint)
660 #define MakeCartesianPoint_gen MakeCartesianPoint2d
661 #define Pnt_fonc                         Pnt2d
662 #define BSplineCurve_gen                 Geom2d_BSplineCurve
663 #define BSplineCurve_retour              Handle(Geom2d_BSplineCurve)
664 #define MakeBSplineCurve_gen   MakeBSplineCurve2d
665 #include "StepToGeom_MakeBSplineCurve.pxx"
666 #undef Array1OfPnt_gen
667 #undef Pnt_gen
668 #undef CartesianPoint_gen
669 #undef MakeCartesianPoint_gen
670 #undef Pnt_fonc
671 #undef BSplineCurve_gen
672 #undef MakeBSplineCurve_gen
673 #undef BSplineCurve_retour
674 }
675
676 //=============================================================================
677 // Creation d' une BSplineSurface de Geom a partir d' une
678 // BSplineSurface de Step
679 //=============================================================================
680
681 Handle(Geom_BSplineSurface) StepToGeom::MakeBSplineSurface (const Handle(StepGeom_BSplineSurface)& SS)
682 {
683   Standard_Integer                    i, j;
684   Handle(StepGeom_BSplineSurfaceWithKnots) BS;
685   Handle(StepGeom_BSplineSurfaceWithKnotsAndRationalBSplineSurface) BSR;
686
687   if (SS->
688       IsKind(STANDARD_TYPE(StepGeom_BSplineSurfaceWithKnotsAndRationalBSplineSurface))) {
689     BSR =
690       Handle(StepGeom_BSplineSurfaceWithKnotsAndRationalBSplineSurface)
691         ::DownCast(SS);
692     BS =
693       Handle(StepGeom_BSplineSurfaceWithKnots)
694         ::DownCast(BSR->BSplineSurfaceWithKnots());
695   }
696   else
697     BS = Handle(StepGeom_BSplineSurfaceWithKnots)::DownCast(SS);
698
699   const Standard_Integer UDeg = BS->UDegree();
700   const Standard_Integer VDeg = BS->VDegree();
701   const Standard_Integer NUPoles = BS->NbControlPointsListI();
702   const Standard_Integer NVPoles = BS->NbControlPointsListJ();
703   const Handle(StepGeom_HArray2OfCartesianPoint)& aControlPointsList = BS->ControlPointsList();
704   TColgp_Array2OfPnt Poles(1,NUPoles,1,NVPoles);
705   for (i=1; i<=NUPoles; i++) {
706     for (j=1; j<=NVPoles; j++) {
707       Handle(Geom_CartesianPoint) P = MakeCartesianPoint (aControlPointsList->Value(i,j));
708       if (! P.IsNull())
709         Poles.SetValue(i,j,P->Pnt());
710       else
711         return 0;
712     }
713   }
714   const Standard_Integer NUKnots = BS->NbUMultiplicities();
715   const Handle(TColStd_HArray1OfInteger)& aUMultiplicities = BS->UMultiplicities();
716   const Handle(TColStd_HArray1OfReal)& aUKnots = BS->UKnots();
717
718   // count number of unique uknots
719   Standard_Real lastKnot = RealFirst();
720   Standard_Integer NUKnotsUnique = 0;
721   for (i=1; i<=NUKnots; i++) {
722     if (aUKnots->Value(i) - lastKnot > Epsilon (Abs(lastKnot))) {
723       NUKnotsUnique++;
724       lastKnot = aUKnots->Value(i);
725     }
726   }
727
728   // set umultiplicities and uknots
729   TColStd_Array1OfInteger UMult(1,NUKnotsUnique);
730   TColStd_Array1OfReal KUn(1,NUKnotsUnique);
731   Standard_Integer pos = 1;
732   lastKnot = aUKnots->Value(1);
733   KUn.SetValue(1, aUKnots->Value(1));
734   UMult.SetValue(1, aUMultiplicities->Value(1));
735   for (i=2; i<=NUKnots; i++) {
736     if (aUKnots->Value(i) - lastKnot > Epsilon (Abs(lastKnot))) {
737       pos++;
738       KUn.SetValue(pos, aUKnots->Value(i));
739       UMult.SetValue(pos, aUMultiplicities->Value(i));
740       lastKnot = aUKnots->Value(i);
741     }
742     else {
743       // Knot not unique, increase multiplicity
744       Standard_Integer curMult = UMult.Value(pos);
745       UMult.SetValue(pos, curMult + aUMultiplicities->Value(i));
746     }
747   }
748   const Standard_Integer NVKnots = BS->NbVMultiplicities();
749   const Handle(TColStd_HArray1OfInteger)& aVMultiplicities = BS->VMultiplicities();
750   const Handle(TColStd_HArray1OfReal)& aVKnots = BS->VKnots();
751
752   // count number of unique vknots
753   lastKnot = RealFirst();
754   Standard_Integer NVKnotsUnique = 0;
755   for (i=1; i<=NVKnots; i++) {
756     if (aVKnots->Value(i) - lastKnot > Epsilon (Abs(lastKnot))) {
757       NVKnotsUnique++;
758       lastKnot = aVKnots->Value(i);
759     }
760   }
761
762   // set vmultiplicities and vknots
763   TColStd_Array1OfInteger VMult(1,NVKnotsUnique);
764   TColStd_Array1OfReal KVn(1,NVKnotsUnique);
765   pos = 1;
766   lastKnot = aVKnots->Value(1);
767   KVn.SetValue(1, aVKnots->Value(1));
768   VMult.SetValue(1, aVMultiplicities->Value(1));
769   for (i=2; i<=NVKnots; i++) {
770     if (aVKnots->Value(i) - lastKnot > Epsilon (Abs(lastKnot))) {
771       pos++;
772       KVn.SetValue(pos, aVKnots->Value(i));
773       VMult.SetValue(pos, aVMultiplicities->Value(i));
774       lastKnot = aVKnots->Value(i);
775     }
776     else {
777       // Knot not unique, increase multiplicity
778       Standard_Integer curMult = VMult.Value(pos);
779       VMult.SetValue(pos, curMult + aVMultiplicities->Value(i));
780     }
781   }
782
783   // --- Does the Surface Descriptor LOOKS like a U and/or V Periodic ---
784   // --- Descriptor ? ---
785
786   // --- U Periodic ? ---
787
788   Standard_Integer SumMult = 0;
789   for (i=1; i<=NUKnotsUnique; i++) {
790     SumMult += UMult.Value(i);
791   }
792
793   Standard_Boolean shouldBeUPeriodic = Standard_False;
794   if (SumMult == (NUPoles + UDeg + 1)) {
795     //shouldBeUPeriodic = Standard_False;
796   }
797   else if ((UMult.Value(1) ==
798             UMult.Value(NUKnotsUnique)) &&
799            ((SumMult - UMult.Value(1))== NUPoles)) {
800     shouldBeUPeriodic = Standard_True;
801   }
802
803   // --- V Periodic ? ---
804
805   SumMult = 0;
806   for (i=1; i<=NVKnotsUnique; i++) {
807     SumMult += VMult.Value(i);
808   }
809
810   Standard_Boolean shouldBeVPeriodic = Standard_False;
811   if (SumMult == (NVPoles + VDeg + 1)) {
812     //shouldBeVPeriodic = Standard_False;
813   }
814   else if ((VMult.Value(1) ==
815             VMult.Value(NVKnotsUnique)) &&
816            ((SumMult - VMult.Value(1)) == NVPoles)) {
817     shouldBeVPeriodic = Standard_True;
818   }
819
820   Handle(Geom_BSplineSurface) CS;
821   if (SS->IsKind(STANDARD_TYPE(StepGeom_BSplineSurfaceWithKnotsAndRationalBSplineSurface))) {
822     const Handle(TColStd_HArray2OfReal)& aWeight = BSR->WeightsData();
823     TColStd_Array2OfReal W(1,NUPoles,1,NVPoles);
824     for (i=1; i<=NUPoles; i++) {
825       for (j=1; j<=NVPoles; j++) {
826         W.SetValue(i,j,aWeight->Value(i,j));
827       }
828     }
829     CS = new Geom_BSplineSurface(Poles, W, KUn, KVn, UMult,
830                                  VMult, UDeg, VDeg,
831                                  shouldBeUPeriodic,
832                                  shouldBeVPeriodic);
833   }
834   else
835     CS = new Geom_BSplineSurface(Poles, KUn, KVn, UMult,
836                                  VMult, UDeg, VDeg,
837                                  shouldBeUPeriodic,
838                                  shouldBeVPeriodic);
839   return CS;
840 }
841
842 //=============================================================================
843 // Creation d' un CartesianPoint de Geom a partir d' un CartesianPoint de Step
844 //=============================================================================
845
846 Handle(Geom_CartesianPoint) StepToGeom::MakeCartesianPoint (const Handle(StepGeom_CartesianPoint)& SP)
847 {
848   if (SP->NbCoordinates() == 3)
849   {
850     const Standard_Real LF = UnitsMethods::LengthFactor();
851     const Standard_Real X = SP->CoordinatesValue(1) * LF;
852     const Standard_Real Y = SP->CoordinatesValue(2) * LF;
853     const Standard_Real Z = SP->CoordinatesValue(3) * LF;
854     return new Geom_CartesianPoint(X, Y, Z);
855   }
856   return 0;
857 }
858
859 //=============================================================================
860 // Creation d' un CartesianPoint de Geom2d a partir d' un CartesianPoint de
861 // Step
862 //=============================================================================
863
864 Handle(Geom2d_CartesianPoint) StepToGeom::MakeCartesianPoint2d (const Handle(StepGeom_CartesianPoint)& SP)
865 {
866   if (SP->NbCoordinates() == 2)
867   {
868     const Standard_Real X = SP->CoordinatesValue(1);
869     const Standard_Real Y = SP->CoordinatesValue(2);
870     return new Geom2d_CartesianPoint(X, Y);
871   }
872   return 0;
873 }
874
875 //=============================================================================
876 // Creation d' un Circle de Geom a partir d' un Circle de Step
877 //=============================================================================
878
879 Handle(Geom_Circle) StepToGeom::MakeCircle (const Handle(StepGeom_Circle)& SC)
880 {
881   const StepGeom_Axis2Placement AxisSelect = SC->Position();
882   if (AxisSelect.CaseNum(AxisSelect.Value()) == 2)
883   {
884     Handle(Geom_Axis2Placement) A =
885       MakeAxis2Placement (Handle(StepGeom_Axis2Placement3d)::DownCast(AxisSelect.Value()));
886     if (! A.IsNull())
887     {
888       return new Geom_Circle(A->Ax2(),SC->Radius() * UnitsMethods::LengthFactor());
889     }
890   }
891   return 0;
892 }
893
894 //=============================================================================
895 // Creation d' un Circle de Geom2d a partir d' un Circle de Step
896 //=============================================================================
897
898 Handle(Geom2d_Circle) StepToGeom::MakeCircle2d (const Handle(StepGeom_Circle)& SC)
899 {
900   const StepGeom_Axis2Placement AxisSelect = SC->Position();
901   if (AxisSelect.CaseNum(AxisSelect.Value()) == 1) {
902     Handle(Geom2d_AxisPlacement) A1 =
903       MakeAxisPlacement (Handle(StepGeom_Axis2Placement2d)::DownCast(AxisSelect.Value()));
904     if (! A1.IsNull())
905     {
906       return new Geom2d_Circle (A1->Ax2d(), SC->Radius());
907     }
908   }
909   return 0;
910 }
911
912 //=============================================================================
913 // Creation d' une Conic de Geom a partir d' une Conic de Step
914 //=============================================================================
915
916 Handle(Geom_Conic) StepToGeom::MakeConic (const Handle(StepGeom_Conic)& SC)
917 {
918   if (SC->IsKind(STANDARD_TYPE(StepGeom_Circle))) {
919     return MakeCircle (Handle(StepGeom_Circle)::DownCast(SC));
920   }
921   if (SC->IsKind(STANDARD_TYPE(StepGeom_Ellipse))) {
922     return MakeEllipse (Handle(StepGeom_Ellipse)::DownCast(SC));
923   }
924   if (SC->IsKind(STANDARD_TYPE(StepGeom_Hyperbola))) {
925     return MakeHyperbola (Handle(StepGeom_Hyperbola)::DownCast(SC));
926   }
927   if (SC->IsKind(STANDARD_TYPE(StepGeom_Parabola))) {
928     return MakeParabola (Handle(StepGeom_Parabola)::DownCast(SC));
929   }
930   // Attention : Other conic shall be implemented !
931   return 0;
932 }
933
934 //=============================================================================
935 // Creation d' une Conic de Geom2d a partir d' une Conic de Step
936 //=============================================================================
937
938 Handle(Geom2d_Conic) StepToGeom::MakeConic2d (const Handle(StepGeom_Conic)& SC)
939 {
940   if (SC->IsKind(STANDARD_TYPE(StepGeom_Circle))) {
941     return MakeCircle2d (Handle(StepGeom_Circle)::DownCast(SC));
942   }
943   if (SC->IsKind(STANDARD_TYPE(StepGeom_Ellipse))) {
944     return MakeEllipse2d (Handle(StepGeom_Ellipse)::DownCast(SC));
945   }
946   if (SC->IsKind(STANDARD_TYPE(StepGeom_Hyperbola))) {
947     return MakeHyperbola2d (Handle(StepGeom_Hyperbola)::DownCast(SC));
948   }
949   if (SC->IsKind(STANDARD_TYPE(StepGeom_Parabola))) {
950     return MakeParabola2d (Handle(StepGeom_Parabola)::DownCast(SC));
951   }
952   // Attention : Other conic shall be implemented !
953   return Handle(Geom2d_Conic)();
954 }
955
956 //=============================================================================
957 // Creation d' une ConicalSurface de Geom a partir d' une ConicalSurface de
958 // Step
959 //=============================================================================
960
961 Handle(Geom_ConicalSurface) StepToGeom::MakeConicalSurface (const Handle(StepGeom_ConicalSurface)& SS)
962 {
963   Handle(Geom_Axis2Placement) A = MakeAxis2Placement (SS->Position());
964   if (! A.IsNull())
965   {
966     const Standard_Real R = SS->Radius() * UnitsMethods::LengthFactor();
967     const Standard_Real Ang = SS->SemiAngle() * UnitsMethods::PlaneAngleFactor();
968     //#2(K3-3) rln 12/02/98 ProSTEP ct_turbine-A.stp entity #518, #3571 (gp::Resolution() is too little)
969     return new Geom_ConicalSurface(A->Ax2(), Max(Ang, Precision::Angular()), R);
970   }
971   return 0;
972 }
973
974 //=============================================================================
975 // Creation d' une Curve de Geom a partir d' une Curve de Step
976 //=============================================================================
977
978 Handle(Geom_Curve) StepToGeom::MakeCurve (const Handle(StepGeom_Curve)& SC)
979 {
980   if (SC.IsNull()){
981     return Handle(Geom_Curve)();
982   }
983   if (SC->IsKind(STANDARD_TYPE(StepGeom_Line))) {
984     return MakeLine (Handle(StepGeom_Line)::DownCast(SC));
985   }
986   if (SC->IsKind(STANDARD_TYPE(StepGeom_TrimmedCurve))) {
987     return MakeTrimmedCurve (Handle(StepGeom_TrimmedCurve)::DownCast(SC));
988   }
989   if (SC->IsKind(STANDARD_TYPE(StepGeom_Conic))) {
990     return MakeConic (Handle(StepGeom_Conic)::DownCast(SC));
991   }
992   if (SC->IsKind(STANDARD_TYPE(StepGeom_BoundedCurve))) {
993     return MakeBoundedCurve (Handle(StepGeom_BoundedCurve)::DownCast(SC));
994   }
995   if (SC->IsKind(STANDARD_TYPE(StepGeom_CurveReplica))) { //:n7 abv 16 Feb 99
996     const Handle(StepGeom_CurveReplica) CR = Handle(StepGeom_CurveReplica)::DownCast(SC);
997     const Handle(StepGeom_Curve) PC = CR->ParentCurve();
998     const Handle(StepGeom_CartesianTransformationOperator3d) T =
999       Handle(StepGeom_CartesianTransformationOperator3d)::DownCast(CR->Transformation());
1000     // protect against cyclic references and wrong type of cartop
1001     if ( !T.IsNull() && PC != SC )
1002     {
1003       Handle(Geom_Curve) C1 = MakeCurve (PC);
1004       if (! C1.IsNull())
1005       {
1006         gp_Trsf T1;
1007         if (MakeTransformation3d(T,T1))
1008         {
1009           C1->Transform ( T1 );
1010           return C1;
1011         }
1012       }
1013     }
1014   }
1015   else if (SC->IsKind(STANDARD_TYPE(StepGeom_OffsetCurve3d))) { //:o2 abv 17 Feb 99
1016     const Handle(StepGeom_OffsetCurve3d) OC = Handle(StepGeom_OffsetCurve3d)::DownCast(SC);
1017     const Handle(StepGeom_Curve) BC = OC->BasisCurve();
1018     if ( BC != SC ) { // protect against loop
1019       Handle(Geom_Curve) C1 = MakeCurve (BC);
1020       if (! C1.IsNull())
1021       {
1022         Handle(Geom_Direction) RD = MakeDirection(OC->RefDirection());
1023         if (! RD.IsNull())
1024         {
1025           return new Geom_OffsetCurve ( C1, -OC->Distance(), RD->Dir() );
1026         }
1027       }
1028     }
1029   }
1030   else if (SC->IsKind(STANDARD_TYPE(StepGeom_SurfaceCurve))) { //:o5 abv 17 Feb 99
1031     const Handle(StepGeom_SurfaceCurve) SurfC = Handle(StepGeom_SurfaceCurve)::DownCast(SC);
1032     return MakeCurve (SurfC->Curve3d());
1033   }
1034   return 0;
1035 }
1036
1037 //=============================================================================
1038 // Creation d' une Curve de Geom2d a partir d' une Curve de Step
1039 //=============================================================================
1040
1041 Handle(Geom2d_Curve) StepToGeom::MakeCurve2d (const Handle(StepGeom_Curve)& SC)
1042 {
1043   if (SC->IsKind(STANDARD_TYPE(StepGeom_Line))) {
1044     return MakeLine2d (Handle(StepGeom_Line)::DownCast(SC));
1045   }
1046   if (SC->IsKind(STANDARD_TYPE(StepGeom_Conic))) {
1047     return MakeConic2d (Handle(StepGeom_Conic)::DownCast(SC));
1048   }
1049   if (SC->IsKind(STANDARD_TYPE(StepGeom_BoundedCurve))) {
1050     return MakeBoundedCurve2d (Handle(StepGeom_BoundedCurve)::DownCast(SC));
1051   }
1052   if (SC->IsKind(STANDARD_TYPE(StepGeom_CurveReplica))) { //:n7 abv 16 Feb 99
1053     const Handle(StepGeom_CurveReplica) CR = Handle(StepGeom_CurveReplica)::DownCast(SC);
1054     const Handle(StepGeom_Curve) PC = CR->ParentCurve();
1055     const Handle(StepGeom_CartesianTransformationOperator2d) T =
1056       Handle(StepGeom_CartesianTransformationOperator2d)::DownCast(CR->Transformation());
1057     // protect against cyclic references and wrong type of cartop
1058     if ( !T.IsNull() && PC != SC )
1059     {
1060       Handle(Geom2d_Curve) C1 = MakeCurve2d (PC);
1061       if (! C1.IsNull())
1062       {
1063         gp_Trsf2d T1;
1064         if (MakeTransformation2d(T,T1))
1065         {
1066           C1->Transform ( T1 );
1067           return C1;
1068         }
1069       }
1070     }
1071   }
1072   return 0;
1073 }
1074
1075 //=============================================================================
1076 // Creation d' une CylindricalSurface de Geom a partir d' une
1077 // CylindricalSurface de Step
1078 //=============================================================================
1079
1080 Handle(Geom_CylindricalSurface) StepToGeom::MakeCylindricalSurface (const Handle(StepGeom_CylindricalSurface)& SS)
1081 {
1082   Handle(Geom_Axis2Placement) A = MakeAxis2Placement(SS->Position());
1083   if (! A.IsNull())
1084   {
1085     return new Geom_CylindricalSurface(A->Ax2(), SS->Radius() * UnitsMethods::LengthFactor());
1086   }
1087   return 0;
1088 }
1089
1090 //=============================================================================
1091 // Creation d' un Direction de Geom a partir d' un Direction de Step
1092 //=============================================================================
1093
1094 Handle(Geom_Direction) StepToGeom::MakeDirection (const Handle(StepGeom_Direction)& SD)
1095 {
1096   if (SD->NbDirectionRatios() >= 3)
1097   {
1098     const Standard_Real X = SD->DirectionRatiosValue(1);
1099     const Standard_Real Y = SD->DirectionRatiosValue(2);
1100     const Standard_Real Z = SD->DirectionRatiosValue(3);
1101     // sln 22.10.2001. CTS23496: Direction is not created if it has null magnitude
1102     if (gp_XYZ(X, Y, Z).SquareModulus() > gp::Resolution()*gp::Resolution())
1103     {
1104       return new Geom_Direction(X, Y, Z);
1105     }
1106   }
1107   return 0;
1108 }
1109
1110 //=============================================================================
1111 // Creation d' un Direction de Geom2d a partir d' un Direction de Step
1112 //=============================================================================
1113
1114 Handle(Geom2d_Direction) StepToGeom::MakeDirection2d (const Handle(StepGeom_Direction)& SD)
1115 {
1116   if (SD->NbDirectionRatios() >= 2)
1117   {
1118     const Standard_Real X = SD->DirectionRatiosValue(1);
1119     const Standard_Real Y = SD->DirectionRatiosValue(2);
1120     // sln 23.10.2001. CTS23496: Direction is not created if it has null magnitude
1121     if(gp_XY(X,Y).SquareModulus() > gp::Resolution()*gp::Resolution())
1122     {
1123       return  new Geom2d_Direction(X, Y);
1124     }
1125   }
1126   return 0;
1127 }
1128
1129 //=============================================================================
1130 // Creation d' une ElementarySurface de Geom a partir d' une
1131 // ElementarySurface de Step
1132 //=============================================================================
1133
1134 Handle(Geom_ElementarySurface) StepToGeom::MakeElementarySurface (const Handle(StepGeom_ElementarySurface)& SS)
1135 {
1136   if (SS->IsKind(STANDARD_TYPE(StepGeom_Plane))) {
1137     return MakePlane (Handle(StepGeom_Plane)::DownCast(SS));
1138   }
1139   if (SS->IsKind(STANDARD_TYPE(StepGeom_CylindricalSurface))) {
1140     return MakeCylindricalSurface (Handle(StepGeom_CylindricalSurface)::DownCast(SS));
1141   }
1142   if (SS->IsKind(STANDARD_TYPE(StepGeom_ConicalSurface))) {
1143     return MakeConicalSurface (Handle(StepGeom_ConicalSurface)::DownCast(SS));
1144   }
1145   if (SS->IsKind(STANDARD_TYPE(StepGeom_SphericalSurface))) {
1146     return MakeSphericalSurface (Handle(StepGeom_SphericalSurface)::DownCast(SS));
1147   }
1148   if (SS->IsKind(STANDARD_TYPE(StepGeom_ToroidalSurface))) {
1149     return MakeToroidalSurface (Handle(StepGeom_ToroidalSurface)::DownCast(SS));
1150   }
1151   return 0;
1152 }
1153
1154 //=============================================================================
1155 // Creation d' un Ellipse de Geom a partir d' un Ellipse de Step
1156 //=============================================================================
1157
1158 Handle(Geom_Ellipse) StepToGeom::MakeEllipse (const Handle(StepGeom_Ellipse)& SC)
1159 {
1160   const StepGeom_Axis2Placement AxisSelect = SC->Position();
1161   if (AxisSelect.CaseNum(AxisSelect.Value()) == 2) {
1162     Handle(Geom_Axis2Placement) A1 = MakeAxis2Placement (Handle(StepGeom_Axis2Placement3d)::DownCast(AxisSelect.Value()));
1163     if (! A1.IsNull())
1164     {
1165       gp_Ax2 A( A1->Ax2() );
1166       const Standard_Real LF = UnitsMethods::LengthFactor();
1167       const Standard_Real majorR = SC->SemiAxis1() * LF;
1168       const Standard_Real minorR = SC->SemiAxis2() * LF;
1169       if ( majorR - minorR >= 0. ) { //:o9 abv 19 Feb 99
1170         return new Geom_Ellipse(A, majorR, minorR);
1171       }
1172       //:o9 abv 19 Feb 99
1173       else {
1174         A.SetXDirection ( A.XDirection() ^ A.Direction() );
1175         return new Geom_Ellipse(A, minorR, majorR);
1176       }
1177     }
1178   }
1179   return 0;
1180 }
1181
1182 //=============================================================================
1183 // Creation d' un Ellipse de Geom2d a partir d' un Ellipse de Step
1184 //=============================================================================
1185
1186 Handle(Geom2d_Ellipse) StepToGeom::MakeEllipse2d (const Handle(StepGeom_Ellipse)& SC)
1187 {
1188   const StepGeom_Axis2Placement AxisSelect = SC->Position();
1189   if (AxisSelect.CaseNum(AxisSelect.Value()) == 1) {
1190     Handle(Geom2d_AxisPlacement) A1 = MakeAxisPlacement (Handle(StepGeom_Axis2Placement2d)::DownCast(AxisSelect.Value()));
1191     if (! A1.IsNull())
1192     {
1193       gp_Ax22d A( A1->Ax2d() );
1194       const Standard_Real majorR = SC->SemiAxis1();
1195       const Standard_Real minorR = SC->SemiAxis2();
1196       if ( majorR - minorR >= 0. ) { //:o9 abv 19 Feb 99: bm4_id_punch_b.stp #678: protection
1197         return new Geom2d_Ellipse(A, majorR, minorR);
1198       }
1199       else {
1200         const gp_Dir2d X = A.XDirection();
1201         A.SetXDirection ( gp_Dir2d ( X.X(), -X.Y() ) );
1202         return new Geom2d_Ellipse(A, minorR, majorR);
1203       }
1204     }
1205   }
1206   return 0;
1207 }
1208
1209 //=============================================================================
1210 // Creation d' un Hyperbola de Geom a partir d' un Hyperbola de Step
1211 //=============================================================================
1212
1213 Handle(Geom_Hyperbola) StepToGeom::MakeHyperbola (const Handle(StepGeom_Hyperbola)& SC)
1214 {
1215   const StepGeom_Axis2Placement AxisSelect = SC->Position();
1216   if (AxisSelect.CaseNum(AxisSelect.Value()) == 2)
1217   {
1218     Handle(Geom_Axis2Placement) A1 = MakeAxis2Placement (Handle(StepGeom_Axis2Placement3d)::DownCast(AxisSelect.Value()));
1219     if (! A1.IsNull())
1220     {
1221       const gp_Ax2 A( A1->Ax2() );
1222       const Standard_Real LF = UnitsMethods::LengthFactor();
1223       return new Geom_Hyperbola(A, SC->SemiAxis() * LF, SC->SemiImagAxis() * LF);
1224     }
1225   }
1226   return 0;
1227 }
1228
1229 //=============================================================================
1230 // Creation d' un Hyperbola de Geom2d a partir d' un Hyperbola de Step
1231 //=============================================================================
1232
1233 Handle(Geom2d_Hyperbola) StepToGeom::MakeHyperbola2d (const Handle(StepGeom_Hyperbola)& SC)
1234 {
1235   const StepGeom_Axis2Placement AxisSelect = SC->Position();
1236   if (AxisSelect.CaseNum(AxisSelect.Value()) == 1)
1237   {
1238     Handle(Geom2d_AxisPlacement) A1 = MakeAxisPlacement (Handle(StepGeom_Axis2Placement2d)::DownCast(AxisSelect.Value()));
1239     if (! A1.IsNull())
1240     {
1241       const gp_Ax22d A( A1->Ax2d() );
1242       return new Geom2d_Hyperbola(A, SC->SemiAxis(), SC->SemiImagAxis());
1243     }
1244   }
1245   return 0;
1246 }
1247
1248 //=============================================================================
1249 // Creation d' une Line de Geom a partir d' une Line de Step
1250 //=============================================================================
1251
1252 Handle(Geom_Line) StepToGeom::MakeLine (const Handle(StepGeom_Line)& SC)
1253 {
1254   Handle(Geom_CartesianPoint) P = MakeCartesianPoint(SC->Pnt());
1255   if (! P.IsNull())
1256   {
1257     // sln 22.10.2001. CTS23496: Line is not created if direction have not been succesfully created
1258     Handle(Geom_VectorWithMagnitude) D = MakeVectorWithMagnitude (SC->Dir());
1259     if (! D.IsNull())
1260     {
1261       if( D->Vec().SquareMagnitude() < Precision::Confusion() * Precision::Confusion())
1262         return 0;
1263       const gp_Dir V(D->Vec());
1264       return new Geom_Line(P->Pnt(), V);
1265     }
1266   }
1267   return 0;
1268 }
1269
1270 //=============================================================================
1271 // Creation d' une Line de Geom2d a partir d' une Line de Step
1272 //=============================================================================
1273
1274 Handle(Geom2d_Line) StepToGeom::MakeLine2d (const Handle(StepGeom_Line)& SC)
1275 {
1276   Handle(Geom2d_CartesianPoint) P = MakeCartesianPoint2d(SC->Pnt());
1277   if (! P.IsNull())
1278   {
1279     // sln 23.10.2001. CTS23496: Line is not created if direction have not been succesfully created
1280     Handle(Geom2d_VectorWithMagnitude) D = MakeVectorWithMagnitude2d (SC->Dir());
1281     if (! D.IsNull())
1282     {
1283       const gp_Dir2d D1(D->Vec2d());
1284       return new Geom2d_Line(P->Pnt2d(), D1);
1285     }
1286   }
1287   return 0;
1288 }
1289
1290 //=============================================================================
1291 // Creation d' un Parabola de Geom a partir d' un Parabola de Step
1292 //=============================================================================
1293
1294 Handle(Geom_Parabola) StepToGeom::MakeParabola (const Handle(StepGeom_Parabola)& SC)
1295 {
1296   const StepGeom_Axis2Placement AxisSelect = SC->Position();
1297   if (AxisSelect.CaseNum(AxisSelect.Value()) == 2)
1298   {
1299     Handle(Geom_Axis2Placement) A = MakeAxis2Placement (Handle(StepGeom_Axis2Placement3d)::DownCast(AxisSelect.Value()));
1300     if (! A.IsNull())
1301     {
1302       return new Geom_Parabola(A->Ax2(), SC->FocalDist() * UnitsMethods::LengthFactor());
1303     }
1304   }
1305   return 0;
1306 }
1307
1308 //=============================================================================
1309 // Creation d' un Parabola de Geom2d a partir d' un Parabola de Step
1310 //=============================================================================
1311
1312 Handle(Geom2d_Parabola) StepToGeom::MakeParabola2d (const Handle(StepGeom_Parabola)& SC)
1313 {
1314   const StepGeom_Axis2Placement AxisSelect = SC->Position();
1315   if (AxisSelect.CaseNum(AxisSelect.Value()) == 1) {
1316     Handle(Geom2d_AxisPlacement) A1 = MakeAxisPlacement (Handle(StepGeom_Axis2Placement2d)::DownCast(AxisSelect.Value()));
1317     if (! A1.IsNull())
1318     {
1319       const gp_Ax22d A( A1->Ax2d() );
1320       return new Geom2d_Parabola(A, SC->FocalDist());
1321     }
1322   }
1323   return 0;
1324 }
1325
1326 //=============================================================================
1327 // Creation d' un Plane de Geom a partir d' un plane de Step
1328 //=============================================================================
1329
1330 Handle(Geom_Plane) StepToGeom::MakePlane (const Handle(StepGeom_Plane)& SP)
1331 {
1332   Handle(Geom_Axis2Placement) A = MakeAxis2Placement (SP->Position());
1333   if (! A.IsNull())
1334   {
1335     return new Geom_Plane(A->Ax2());
1336   }
1337   return 0;
1338 }
1339
1340 //=======================================================================
1341 //function : MakePolyline
1342 //purpose  :
1343 //=======================================================================
1344
1345 Handle(Geom_BSplineCurve) StepToGeom::MakePolyline (const Handle(StepGeom_Polyline)& SPL)
1346 {
1347   if (SPL.IsNull())
1348     return Handle(Geom_BSplineCurve)();
1349
1350   const Standard_Integer nbp = SPL->NbPoints();
1351   if (nbp > 1)
1352   {
1353     TColgp_Array1OfPnt Poles ( 1, nbp );
1354     TColStd_Array1OfReal Knots ( 1, nbp );
1355     TColStd_Array1OfInteger Mults ( 1, nbp );
1356
1357     for ( Standard_Integer i=1; i <= nbp; i++ )
1358     {
1359       Handle(Geom_CartesianPoint) P = MakeCartesianPoint (SPL->PointsValue(i));
1360       if (! P.IsNull())
1361         Poles.SetValue ( i, P->Pnt() );
1362       else
1363         return 0;
1364       Knots.SetValue ( i, Standard_Real(i-1) );
1365       Mults.SetValue ( i, 1 );
1366     }
1367     Mults.SetValue ( 1, 2 );
1368     Mults.SetValue ( nbp, 2 );
1369
1370     return new Geom_BSplineCurve ( Poles, Knots, Mults, 1 );
1371   }
1372   return 0;
1373 }
1374
1375 //=======================================================================
1376 //function : MakePolyline2d
1377 //purpose  :
1378 //=======================================================================
1379
1380 Handle(Geom2d_BSplineCurve) StepToGeom::MakePolyline2d (const Handle(StepGeom_Polyline)& SPL)
1381 {
1382   if (SPL.IsNull())
1383     return Handle(Geom2d_BSplineCurve)();
1384
1385   const Standard_Integer nbp = SPL->NbPoints();
1386   if (nbp > 1)
1387   {
1388     TColgp_Array1OfPnt2d Poles ( 1, nbp );
1389     TColStd_Array1OfReal Knots ( 1, nbp );
1390     TColStd_Array1OfInteger Mults ( 1, nbp );
1391
1392     for ( Standard_Integer i=1; i <= nbp; i++ )
1393     {
1394     Handle(Geom2d_CartesianPoint) P = MakeCartesianPoint2d (SPL->PointsValue(i));
1395       if (! P.IsNull())
1396         Poles.SetValue ( i, P->Pnt2d() );
1397       else
1398         return 0;
1399       Knots.SetValue ( i, Standard_Real(i-1) );
1400       Mults.SetValue ( i, 1 );
1401     }
1402     Mults.SetValue ( 1, 2 );
1403     Mults.SetValue ( nbp, 2 );
1404
1405     return new Geom2d_BSplineCurve ( Poles, Knots, Mults, 1 );
1406   }
1407   return 0;
1408 }
1409
1410 //=============================================================================
1411 // Creation d' une RectangularTrimmedSurface de Geom a partir d' une
1412 // RectangularTrimmedSurface de Step
1413 //=============================================================================
1414
1415 Handle(Geom_RectangularTrimmedSurface) StepToGeom::MakeRectangularTrimmedSurface (const Handle(StepGeom_RectangularTrimmedSurface)& SS)
1416 {
1417   Handle(Geom_Surface) theBasis = MakeSurface (SS->BasisSurface());
1418   if (! theBasis.IsNull())
1419   {
1420     // -----------------------------------------
1421     // Modification of the Trimming Parameters ?
1422     // -----------------------------------------
1423
1424     Standard_Real uFact = 1.;
1425     Standard_Real vFact = 1.;
1426     const Standard_Real LengthFact  = UnitsMethods::LengthFactor();
1427     const Standard_Real AngleFact   = UnitsMethods::PlaneAngleFactor(); // abv 30.06.00 trj4_k1_geo-tc-214.stp #1477: PI/180.;
1428
1429     if (theBasis->IsKind(STANDARD_TYPE(Geom_SphericalSurface)) ||
1430         theBasis->IsKind(STANDARD_TYPE(Geom_ToroidalSurface))) {
1431       uFact = vFact = AngleFact;
1432     }
1433     else if (theBasis->IsKind(STANDARD_TYPE(Geom_CylindricalSurface))) {
1434       uFact = AngleFact;
1435       vFact = LengthFact;
1436     }
1437     else if ( theBasis->IsKind(STANDARD_TYPE(Geom_SurfaceOfRevolution))) {
1438       uFact = AngleFact;
1439     }
1440     else if (theBasis->IsKind(STANDARD_TYPE(Geom_ConicalSurface))) {
1441       const Handle(Geom_ConicalSurface) conicS = Handle(Geom_ConicalSurface)::DownCast(theBasis);
1442       uFact = AngleFact;
1443       vFact = LengthFact / Cos(conicS->SemiAngle());
1444     }
1445     else if (theBasis->IsKind(STANDARD_TYPE(Geom_Plane))) {
1446       uFact = vFact = LengthFact;
1447     }
1448
1449     const Standard_Real U1 = SS->U1() * uFact;
1450     const Standard_Real U2 = SS->U2() * uFact;
1451     const Standard_Real V1 = SS->V1() * vFact;
1452     const Standard_Real V2 = SS->V2() * vFact;
1453
1454     return new Geom_RectangularTrimmedSurface(theBasis, U1, U2, V1, V2, SS->Usense(), SS->Vsense());
1455   }
1456   return 0;
1457 }
1458
1459 //=============================================================================
1460 // Creation d' une SphericalSurface de Geom a partir d' une
1461 // SphericalSurface de Step
1462 //=============================================================================
1463
1464 Handle(Geom_SphericalSurface) StepToGeom::MakeSphericalSurface (const Handle(StepGeom_SphericalSurface)& SS)
1465 {
1466   Handle(Geom_Axis2Placement) A = MakeAxis2Placement (SS->Position());
1467   if (! A.IsNull())
1468   {
1469     return new Geom_SphericalSurface(A->Ax2(), SS->Radius() * UnitsMethods::LengthFactor());
1470   }
1471   return 0;
1472 }
1473
1474 //=============================================================================
1475 // Creation d' une Surface de Geom a partir d' une Surface de Step
1476 //=============================================================================
1477
1478 Handle(Geom_Surface) StepToGeom::MakeSurface (const Handle(StepGeom_Surface)& SS)
1479 {
1480    // sln 01.10.2001 BUC61003. If entry shell is NULL do nothing
1481   if(SS.IsNull()) {
1482     return Handle(Geom_Surface)();
1483   }
1484
1485   try {
1486     OCC_CATCH_SIGNALS
1487     if (SS->IsKind(STANDARD_TYPE(StepGeom_BoundedSurface))) {
1488       return MakeBoundedSurface (Handle(StepGeom_BoundedSurface)::DownCast(SS));
1489     }
1490     if (SS->IsKind(STANDARD_TYPE(StepGeom_ElementarySurface))) {
1491       const Handle(StepGeom_ElementarySurface) S1 = Handle(StepGeom_ElementarySurface)::DownCast(SS);
1492       if(S1->Position().IsNull())
1493         return Handle(Geom_Surface)();
1494
1495       return MakeElementarySurface (S1);
1496     }
1497     if (SS->IsKind(STANDARD_TYPE(StepGeom_SweptSurface))) {
1498       return MakeSweptSurface (Handle(StepGeom_SweptSurface)::DownCast(SS));
1499     }
1500     if (SS->IsKind(STANDARD_TYPE(StepGeom_OffsetSurface))) { //:d4 abv 12 Mar 98
1501       const Handle(StepGeom_OffsetSurface) OS = Handle(StepGeom_OffsetSurface)::DownCast(SS);
1502
1503       Handle(Geom_Surface) aBasisSurface = MakeSurface (OS->BasisSurface());
1504       if (! aBasisSurface.IsNull())
1505       {
1506         // sln 03.10.01. BUC61003. creation of  offset surface is corrected
1507         const Standard_Real anOffset = OS->Distance() * UnitsMethods::LengthFactor();
1508         if (aBasisSurface->Continuity() == GeomAbs_C0)
1509         {
1510           const BRepBuilderAPI_MakeFace aBFace(aBasisSurface, Precision::Confusion());
1511           if (aBFace.IsDone())
1512           {
1513             const TopoDS_Shape aResult = ShapeAlgo::AlgoContainer()->C0ShapeToC1Shape(aBFace.Face(), Abs(anOffset));
1514             if (aResult.ShapeType() == TopAbs_FACE)
1515             {
1516               aBasisSurface = BRep_Tool::Surface(TopoDS::Face(aResult));
1517             }
1518           }
1519         }
1520         if(aBasisSurface->Continuity() != GeomAbs_C0)
1521         {
1522           return new Geom_OffsetSurface ( aBasisSurface, anOffset );
1523         }
1524       }
1525     }
1526     else if (SS->IsKind(STANDARD_TYPE(StepGeom_SurfaceReplica))) { //:n7 abv 16 Feb 99
1527       const Handle(StepGeom_SurfaceReplica) SR = Handle(StepGeom_SurfaceReplica)::DownCast(SS);
1528       const Handle(StepGeom_Surface) PS = SR->ParentSurface();
1529       const Handle(StepGeom_CartesianTransformationOperator3d) T =
1530         Handle(StepGeom_CartesianTransformationOperator3d)::DownCast(SR->Transformation());
1531       // protect against cyclic references and wrong type of cartop
1532       if ( !T.IsNull() && PS != SS ) {
1533         Handle(Geom_Surface) S1 = MakeSurface (PS);
1534         if (! S1.IsNull())
1535         {
1536           gp_Trsf T1;
1537           if (MakeTransformation3d(T,T1))
1538           {
1539             S1->Transform ( T1 );
1540             return S1;
1541           }
1542         }
1543       }
1544     }
1545   }
1546   catch(Standard_Failure) {
1547 //   ShapeTool_DB ?
1548 #ifdef OCCT_DEBUG //:s5
1549     cout<<"Warning: MakeSurface: Exception:";
1550     Standard_Failure::Caught()->Print(cout); cout << endl;
1551 #endif
1552   }
1553   return 0;
1554 }
1555
1556 //=============================================================================
1557 // Creation d' une SurfaceOfLinearExtrusion de Geom a partir d' une
1558 // SurfaceOfLinearExtrusion de Step
1559 //=============================================================================
1560
1561 Handle(Geom_SurfaceOfLinearExtrusion) StepToGeom::MakeSurfaceOfLinearExtrusion (const Handle(StepGeom_SurfaceOfLinearExtrusion)& SS)
1562 {
1563   Handle(Geom_Curve) C = MakeCurve (SS->SweptCurve());
1564   if (! C.IsNull())
1565   {
1566     // sln 23.10.2001. CTS23496: Surface is not created if extrusion axis have not been succesfully created
1567     Handle(Geom_VectorWithMagnitude) V = MakeVectorWithMagnitude (SS->ExtrusionAxis());
1568     if (! V.IsNull())
1569     {
1570       const gp_Dir D(V->Vec());
1571       Handle(Geom_Line) aLine = Handle(Geom_Line)::DownCast(C);
1572       if (!aLine.IsNull() && aLine->Lin().Direction().IsParallel(D, Precision::Angular()))
1573         return Handle(Geom_SurfaceOfLinearExtrusion)();
1574       return new Geom_SurfaceOfLinearExtrusion(C,D);
1575     }
1576   }
1577   return 0;
1578 }
1579
1580 //=============================================================================
1581 // Creation d' une SurfaceOfRevolution de Geom a partir d' une
1582 // SurfaceOfRevolution de Step
1583 //=============================================================================
1584
1585 Handle(Geom_SurfaceOfRevolution) StepToGeom::MakeSurfaceOfRevolution (const Handle(StepGeom_SurfaceOfRevolution)& SS)
1586 {
1587   Handle(Geom_Curve) C = MakeCurve (SS->SweptCurve());
1588   if (! C.IsNull())
1589   {
1590     Handle(Geom_Axis1Placement) A1 = MakeAxis1Placement (SS->AxisPosition());
1591     if (! A1.IsNull())
1592     {
1593       const gp_Ax1 A( A1->Ax1() );
1594       //skl for OCC952 (one bad case revolution of circle)
1595       if ( C->IsKind(STANDARD_TYPE(Geom_Circle)) || C->IsKind(STANDARD_TYPE(Geom_Ellipse)) )
1596       {
1597         const Handle(Geom_Conic) conic = Handle(Geom_Conic)::DownCast(C);
1598         const gp_Pnt pc = conic->Location();
1599         const gp_Lin rl (A);
1600         if (rl.Distance(pc) < Precision::Confusion()) { //pc lies on A2
1601           const gp_Dir dirline = A.Direction();
1602           const gp_Dir norm = conic->Axis().Direction();
1603           const gp_Dir xAxis = conic->XAxis().Direction();
1604           //checking A2 lies on plane of circle
1605           if( dirline.IsNormal(norm,Precision::Angular()) && (dirline.IsParallel(xAxis,Precision::Angular()) || C->IsKind(STANDARD_TYPE(Geom_Circle)))) {
1606             //change parametrization for trimming
1607             gp_Ax2 axnew(pc,norm,dirline.Reversed());
1608             conic->SetPosition(axnew);
1609             C = new Geom_TrimmedCurve(conic, 0., M_PI);
1610           }
1611         }
1612       }
1613       return new Geom_SurfaceOfRevolution(C, A);
1614     }
1615   }
1616   return 0;
1617 }
1618
1619 //=============================================================================
1620 // Creation d' une SweptSurface de prostep a partir d' une
1621 // SweptSurface de Geom
1622 //=============================================================================
1623
1624 Handle(Geom_SweptSurface) StepToGeom::MakeSweptSurface (const Handle(StepGeom_SweptSurface)& SS)
1625 {
1626   if (SS->IsKind(STANDARD_TYPE(StepGeom_SurfaceOfLinearExtrusion))) {
1627     return MakeSurfaceOfLinearExtrusion (Handle(StepGeom_SurfaceOfLinearExtrusion)::DownCast(SS));
1628   }
1629   if (SS->IsKind(STANDARD_TYPE(StepGeom_SurfaceOfRevolution))) {
1630     return MakeSurfaceOfRevolution (Handle(StepGeom_SurfaceOfRevolution)::DownCast(SS));
1631   }
1632   return Handle(Geom_SweptSurface)();
1633 }
1634
1635 //=============================================================================
1636 // Creation d' une ToroidalSurface de Geom a partir d' une
1637 // ToroidalSurface de Step
1638 //=============================================================================
1639
1640 Handle(Geom_ToroidalSurface) StepToGeom::MakeToroidalSurface (const Handle(StepGeom_ToroidalSurface)& SS)
1641 {
1642   Handle(Geom_Axis2Placement) A = MakeAxis2Placement (SS->Position());
1643   if (! A.IsNull())
1644   {
1645     const Standard_Real LF = UnitsMethods::LengthFactor();
1646     return new Geom_ToroidalSurface(A->Ax2(), Abs(SS->MajorRadius() * LF), Abs(SS->MinorRadius() * LF));
1647   }
1648   return 0;
1649 }
1650
1651 //=======================================================================
1652 //function : MakeTransformation2d
1653 //purpose  :
1654 //=======================================================================
1655 Standard_Boolean StepToGeom::MakeTransformation2d (const Handle(StepGeom_CartesianTransformationOperator2d)& SCTO, gp_Trsf2d& CT)
1656 {
1657   //  NB : on ne s interesse ici qu au deplacement rigide
1658   Handle(Geom2d_CartesianPoint) CP = MakeCartesianPoint2d (SCTO->LocalOrigin());
1659   if (! CP.IsNull())
1660   {
1661     gp_Dir2d D1(1.,0.);
1662     // sln 23.10.2001. CTS23496: If problems with creation of direction occur default direction is used
1663     const Handle(StepGeom_Direction) A = SCTO->Axis1();
1664     if (!A.IsNull())
1665     {
1666       Handle(Geom2d_Direction) D = MakeDirection2d (A);
1667       if (! D.IsNull())
1668         D1 = D->Dir2d();
1669     }
1670     const gp_Ax2d result(CP->Pnt2d(),D1);
1671     CT.SetTransformation(result);
1672     CT = CT.Inverted();
1673     return Standard_True;
1674   }
1675   return Standard_False;
1676 }
1677
1678 //=======================================================================
1679 //function : MakeTransformation3d
1680 //purpose  :
1681 //=======================================================================
1682
1683 Standard_Boolean StepToGeom::MakeTransformation3d (const Handle(StepGeom_CartesianTransformationOperator3d)& SCTO, gp_Trsf& CT)
1684 {
1685   Handle(Geom_CartesianPoint) CP = MakeCartesianPoint (SCTO->LocalOrigin());
1686   if (! CP.IsNull())
1687   {
1688     const gp_Pnt Pgp = CP->Pnt();
1689
1690     // sln 23.10.2001. CTS23496: If problems with creation of direction occur default direction is used
1691     gp_Dir D1(1.,0.,0.);
1692     const Handle(StepGeom_Direction) A1 = SCTO->Axis1();
1693     if (!A1.IsNull()) {
1694       Handle(Geom_Direction) D = MakeDirection (A1);
1695       if (! D.IsNull())
1696         D1 = D->Dir();
1697     }
1698
1699     gp_Dir D2(0.,1.,0.);
1700     const Handle(StepGeom_Direction) A2 = SCTO->Axis2();
1701     if (!A2.IsNull()) {
1702       Handle(Geom_Direction) D = MakeDirection (A2);
1703       if (! D.IsNull())
1704         D2 = D->Dir();
1705     }
1706
1707     Standard_Boolean isDefaultDirectionUsed = Standard_True;
1708     gp_Dir D3;
1709     const Handle(StepGeom_Direction) A3 = SCTO->Axis3();
1710     if (!A3.IsNull()) {
1711       Handle(Geom_Direction) D = MakeDirection (A3);
1712       if (! D.IsNull())
1713       {
1714         D3 = D->Dir();
1715         isDefaultDirectionUsed = Standard_False;
1716       }
1717     }
1718     if(isDefaultDirectionUsed)
1719       D3 = D1.Crossed(D2);
1720
1721     const gp_Ax3 result(Pgp,D3,D1);
1722     CT.SetTransformation(result);
1723     CT = CT.Inverted(); //:n8 abv 16 Feb 99: tr8_as2_db.stp: reverse for accordance with LV tool
1724     return Standard_True;
1725   }
1726   return Standard_False;
1727 }
1728
1729 // ----------------------------------------------------------------
1730 // ExtractParameter
1731 // ----------------------------------------------------------------
1732 //:o6 abv 18 Feb 99: parameter Factor added
1733 //:p3 abv 23 Feb 99: parameter Shift added
1734 static Standard_Boolean  ExtractParameter
1735 (const Handle(Geom_Curve) &  aGeomCurve,
1736  const Handle(StepGeom_HArray1OfTrimmingSelect) & TS,
1737  const Standard_Integer nbSel,
1738  const Standard_Integer MasterRep,
1739  const Standard_Real Factor,
1740  const Standard_Real Shift,
1741  Standard_Real & aParam)
1742 {
1743   Handle(StepGeom_CartesianPoint) aPoint;
1744   Standard_Integer i;
1745 //:S4136  Standard_Real precBrep = BRepAPI::Precision();
1746   for ( i = 1 ; i <= nbSel ; i++) {
1747     StepGeom_TrimmingSelect theSel = TS->Value(i);
1748     if (MasterRep == 2 && theSel.CaseMember() > 0) {
1749       aParam = Shift + Factor * theSel.ParameterValue();
1750       return Standard_True;
1751     }
1752     else if (MasterRep == 1 && theSel.CaseNumber() > 0) {
1753       aPoint = theSel.CartesianPoint();
1754       Handle(Geom_CartesianPoint) theGeomPnt = StepToGeom::MakeCartesianPoint (aPoint);
1755       gp_Pnt thegpPnt = theGeomPnt->Pnt();
1756
1757       //:S4136: use advanced algorithm
1758       ShapeAnalysis_Curve sac;
1759       gp_Pnt p;
1760       sac.Project ( aGeomCurve, thegpPnt, Precision::Confusion(), p, aParam );
1761 /* //:S4136
1762       //Trim == natural boundary ?
1763       if(aGeomCurve->IsKind(STANDARD_TYPE(Geom_BoundedCurve))) {
1764         Standard_Real frstPar = aGeomCurve->FirstParameter();
1765         Standard_Real lstPar = aGeomCurve->LastParameter();
1766         gp_Pnt frstPnt = aGeomCurve->Value(frstPar);
1767         gp_Pnt lstPnt = aGeomCurve->Value(lstPar);
1768         if(frstPnt.IsEqual(thegpPnt,precBrep)) {
1769           aParam = frstPar;
1770           return Standard_True;
1771         }
1772         if(lstPnt.IsEqual(thegpPnt,precBrep)) {
1773           aParam = lstPar;
1774           return Standard_True;
1775         }
1776       }
1777       // Project Point On Curve
1778       GeomAPI_ProjectPointOnCurve PPOC(thegpPnt, aGeomCurve);
1779       if (PPOC.NbPoints() == 0) {
1780         return Standard_False;
1781       }
1782       aParam = PPOC.LowerDistanceParameter();
1783 */
1784       return Standard_True;
1785     }
1786   }
1787 // if the MasterRepresentation is unspecified:
1788 // if a ParameterValue exists, it is prefered
1789
1790   for ( i = 1 ; i <= nbSel ; i++) {
1791     StepGeom_TrimmingSelect theSel = TS->Value(i);
1792     if (theSel.CaseMember() > 0) {
1793       aParam = Shift + Factor * theSel.ParameterValue();
1794
1795       return Standard_True;
1796     }
1797   }
1798 // if no ParameterValue exists, it is created from the CartesianPointValue
1799
1800   for ( i = 1 ; i <= nbSel ; i++) {
1801     StepGeom_TrimmingSelect theSel = TS->Value(i);
1802     if (theSel.CaseNumber() > 0) {
1803       aPoint = theSel.CartesianPoint();
1804       Handle(Geom_CartesianPoint) theGeomPnt = StepToGeom::MakeCartesianPoint (aPoint);
1805       gp_Pnt thegpPnt = theGeomPnt->Pnt();
1806       // Project Point On Curve
1807       ShapeAnalysis_Curve sac;
1808       gp_Pnt p;
1809       sac.Project ( aGeomCurve, thegpPnt, Precision::Confusion(), p, aParam );
1810 /*
1811       GeomAPI_ProjectPointOnCurve PPOC(thegpPnt, aGeomCurve);
1812       if (PPOC.NbPoints() == 0) {
1813         return Standard_False;
1814       }
1815       aParam = PPOC.LowerDistanceParameter();
1816 */
1817       return Standard_True;
1818     }
1819   }
1820   return Standard_False;  // I suppose
1821 }
1822
1823
1824 //=============================================================================
1825 // Creation d' une Trimmed Curve de Geom a partir d' une Trimmed Curve de Step
1826 //=============================================================================
1827
1828 Handle(Geom_TrimmedCurve) StepToGeom::MakeTrimmedCurve (const Handle(StepGeom_TrimmedCurve)& SC)
1829 {
1830   const Handle(StepGeom_Curve) theSTEPCurve = SC->BasisCurve();
1831   Handle(Geom_Curve) theCurve = MakeCurve (theSTEPCurve);
1832   if (theCurve.IsNull())
1833     return Handle(Geom_TrimmedCurve)();
1834
1835   const Handle(StepGeom_HArray1OfTrimmingSelect)& theTrimSel1 = SC->Trim1();
1836   const Handle(StepGeom_HArray1OfTrimmingSelect)& theTrimSel2 = SC->Trim2();
1837   const Standard_Integer nbSel1 = SC->NbTrim1();
1838   const Standard_Integer nbSel2 = SC->NbTrim2();
1839
1840   Standard_Integer MasterRep;
1841   switch (SC->MasterRepresentation())
1842   {
1843     case StepGeom_tpCartesian: MasterRep = 1; break;
1844     case StepGeom_tpParameter: MasterRep = 2; break;
1845     default: MasterRep = 0;
1846   }
1847
1848   //gka 18.02.04 analysis for case when MasterRep = .Unspecified
1849   //and parameters are specified as CARTESIAN_POINT
1850   Standard_Boolean isPoint = Standard_False;
1851   if(MasterRep == 0 || (MasterRep == 2 && nbSel1 >1 && nbSel2 > 1)) {
1852     Standard_Integer ii;
1853     for(ii = 1; ii <= nbSel1; ii++)
1854     {
1855       if (!(theTrimSel1->Value(ii).CartesianPoint().IsNull()))
1856       {
1857         for(ii = 1; ii <= nbSel2; ii++)
1858         {
1859           if (!(theTrimSel2->Value(ii).CartesianPoint().IsNull()))
1860           {
1861             isPoint = Standard_True;
1862             break;
1863           }
1864         }
1865         break;
1866       }
1867     }
1868   }
1869
1870   //:o6 abv 18 Feb 99: computation of factor moved
1871   Standard_Real fact = 1., shift = 0.;
1872   if (theSTEPCurve->IsKind(STANDARD_TYPE(StepGeom_Line))) {
1873     const Handle(StepGeom_Line) theLine =
1874       Handle(StepGeom_Line)::DownCast(theSTEPCurve);
1875     fact = theLine->Dir()->Magnitude() * UnitsMethods::LengthFactor();
1876   }
1877   else if (theSTEPCurve->IsKind(STANDARD_TYPE(StepGeom_Circle)) ||
1878            theSTEPCurve->IsKind(STANDARD_TYPE(StepGeom_Ellipse))) {
1879 //    if (trim1 > 2.1*M_PI || trim2 > 2.1*M_PI) fact = M_PI / 180.;
1880     fact = UnitsMethods::PlaneAngleFactor();
1881     //:p3 abv 23 Feb 99: shift on pi/2 on ellipse with R1 < R2
1882     const Handle(StepGeom_Ellipse) ellipse = Handle(StepGeom_Ellipse)::DownCast(theSTEPCurve);
1883     if ( !ellipse.IsNull() && ellipse->SemiAxis1() - ellipse->SemiAxis2() < 0. )
1884       shift = 0.5 * M_PI;
1885
1886     // skl 04.02.2002 for OCC133: we can not make TrimmedCurve if
1887     // there is no X-direction in StepGeom_Axis2Placement3d
1888     const Handle(StepGeom_Conic) conic = Handle(StepGeom_Conic)::DownCast(theSTEPCurve);
1889     // CKY 6-FEB-2004 for Airbus-MedialAxis :
1890     // this restriction does not apply for trimming by POINTS
1891     if(!conic.IsNull() && MasterRep != 1) {
1892       const StepGeom_Axis2Placement a2p = conic->Position();
1893       if(a2p.CaseNum(a2p.Value())==2) {
1894         if( !a2p.Axis2Placement3d()->HasRefDirection() ) {
1895           ////gka 18.02.04 analysis for case when MasterRep = .Unspecified
1896           //and parameters are specified as CARTESIAN_POINT
1897           if(isPoint /*&& !MasterRep*/)
1898             MasterRep =1;
1899           else {
1900             if ( SC->SenseAgreement() )
1901               return new Geom_TrimmedCurve(theCurve, 0., 2.*M_PI, Standard_True);
1902             else
1903               return new Geom_TrimmedCurve(theCurve, 2.*M_PI, 0., Standard_False);
1904           }
1905         }
1906       }
1907     }
1908   }
1909
1910   Standard_Real trim1 = 0.;
1911   Standard_Real trim2 = 0.;
1912   Handle(StepGeom_CartesianPoint) TrimCP1, TrimCP2;
1913   const Standard_Boolean FoundParam1 = ExtractParameter(theCurve, theTrimSel1, nbSel1, MasterRep, fact, shift, trim1);
1914   const Standard_Boolean FoundParam2 = ExtractParameter(theCurve, theTrimSel2, nbSel2, MasterRep, fact, shift, trim2);
1915
1916   if (FoundParam1 && FoundParam2) {
1917     const Standard_Real cf = theCurve->FirstParameter();
1918     const Standard_Real cl = theCurve->LastParameter();
1919     //: abv 09.04.99: S4136: bm2_ug_t4-B.stp #70610: protect against OutOfRange
1920     if ( !theCurve->IsPeriodic() ) {
1921       if ( trim1 < cf ) trim1 = cf;
1922       else if ( trim1 > cl ) trim1 = cl;
1923       if ( trim2 < cf ) trim2 = cf;
1924       else if ( trim2 > cl ) trim2 = cl;
1925     }
1926     if (Abs(trim1 - trim2) < Precision::PConfusion()) {
1927       if (theCurve->IsPeriodic()) {
1928         ElCLib::AdjustPeriodic(cf,cl,Precision::PConfusion(),trim1,trim2);
1929       }
1930       else if (theCurve->IsClosed()) {
1931         if (Abs(trim1 - cf) < Precision::PConfusion()) {
1932           trim2 += cl;
1933         }
1934         else {
1935           trim1 -= cl;
1936         }
1937       }
1938       else {
1939         return 0;
1940       }
1941     }
1942 //  CKY 16-DEC-1997 : USA60035 le texte de Part42 parle de degres
1943 //    mais des systemes ecrivent en radians. Exploiter UnitsMethods
1944 //:o6    trim1 = trim1 * fact;
1945 //:o6    trim2 = trim2 * fact;
1946     if ( SC->SenseAgreement() )
1947       return new Geom_TrimmedCurve(theCurve, trim1, trim2, Standard_True);
1948     else //:abv 29.09.00 PRO20362: reverse parameters in case of reversed curve
1949       return new Geom_TrimmedCurve(theCurve, trim2, trim1, Standard_False);
1950   }
1951   return 0;
1952 }
1953
1954 //=============================================================================
1955 // Creation d'une Trimmed Curve de Geom2d a partir d' une Trimmed Curve de Step
1956 //=============================================================================
1957 // Shall be completed to treat trimming with points
1958
1959 Handle(Geom2d_BSplineCurve) StepToGeom::MakeTrimmedCurve2d (const Handle(StepGeom_TrimmedCurve)& SC)
1960 {
1961   const Handle(StepGeom_Curve) BasisCurve = SC->BasisCurve();
1962   Handle(Geom2d_Curve) theGeomBasis = MakeCurve2d (BasisCurve);
1963   if (theGeomBasis.IsNull())
1964     return Handle(Geom2d_BSplineCurve)();
1965
1966   if (theGeomBasis->IsKind(STANDARD_TYPE(Geom2d_BSplineCurve))) {
1967     return Handle(Geom2d_BSplineCurve)::DownCast(theGeomBasis);
1968   }
1969
1970   const Handle(StepGeom_HArray1OfTrimmingSelect)& theTrimSel1 = SC->Trim1();
1971   const Handle(StepGeom_HArray1OfTrimmingSelect)& theTrimSel2 = SC->Trim2();
1972   const Standard_Integer nbSel1 = SC->NbTrim1();
1973   const Standard_Integer nbSel2 = SC->NbTrim2();
1974   if ((nbSel1 == 1) && (nbSel2 == 1) &&
1975       (theTrimSel1->Value(1).CaseMember() > 0) &&
1976       (theTrimSel2->Value(1).CaseMember() > 0))
1977   {
1978     const Standard_Real u1 = theTrimSel1->Value(1).ParameterValue();
1979     const Standard_Real u2 = theTrimSel2->Value(1).ParameterValue();
1980     Standard_Real fact = 1., shift = 0.;
1981
1982     if (BasisCurve->IsKind(STANDARD_TYPE(StepGeom_Line))) {
1983       const Handle(StepGeom_Line) theLine = Handle(StepGeom_Line)::DownCast(BasisCurve);
1984       fact = theLine->Dir()->Magnitude();
1985     }
1986     else if (BasisCurve->IsKind(STANDARD_TYPE(StepGeom_Circle)) ||
1987              BasisCurve->IsKind(STANDARD_TYPE(StepGeom_Ellipse))) {
1988 //      if (u1 > 2.1*M_PI || u2 > 2.1*M_PI) fact = M_PI / 180.;
1989       fact = UnitsMethods::PlaneAngleFactor();
1990       //:p3 abv 23 Feb 99: shift on pi/2 on ellipse with R1 < R2
1991       const Handle(StepGeom_Ellipse) ellipse = Handle(StepGeom_Ellipse)::DownCast(BasisCurve);
1992       if ( !ellipse.IsNull() && ellipse->SemiAxis1() - ellipse->SemiAxis2() < 0. )
1993         shift = 0.5 * M_PI;
1994     }
1995     else if (BasisCurve->IsKind(STANDARD_TYPE(StepGeom_Parabola)) ||
1996              BasisCurve->IsKind(STANDARD_TYPE(StepGeom_Hyperbola))) {
1997       // LATER !!!
1998     }
1999 //    CKY 16-DEC-1997 : USA60035 le texte de Part42 parle de degres
2000 //      mais des systemes ecrivent en radians. Exploiter UnitsMethods
2001
2002     const Standard_Real newU1 = shift + u1 * fact;
2003     const Standard_Real newU2 = shift + u2 * fact;
2004
2005     const Handle(Geom2d_TrimmedCurve) theTrimmed =
2006       new Geom2d_TrimmedCurve(theGeomBasis, newU1, newU2, SC->SenseAgreement());
2007     return Geom2dConvert::CurveToBSplineCurve(theTrimmed);
2008   }
2009   return 0;
2010 }
2011
2012 //=============================================================================
2013 // Creation d' un VectorWithMagnitude de Geom a partir d' un Vector de Step
2014 //=============================================================================
2015
2016 Handle(Geom_VectorWithMagnitude) StepToGeom::MakeVectorWithMagnitude (const Handle(StepGeom_Vector)& SV)
2017 {
2018   // sln 22.10.2001. CTS23496: Vector is not created if direction have not been succesfully created
2019   Handle(Geom_Direction) D = MakeDirection (SV->Orientation());
2020   if (! D.IsNull())
2021   {
2022     const gp_Vec V(D->Dir().XYZ() * SV->Magnitude() * UnitsMethods::LengthFactor());
2023     return new Geom_VectorWithMagnitude(V);
2024   }
2025   return 0;
2026 }
2027
2028 //=============================================================================
2029 // Creation d' un VectorWithMagnitude de Geom2d a partir d' un Vector de Step
2030 //=============================================================================
2031
2032 Handle(Geom2d_VectorWithMagnitude) StepToGeom::MakeVectorWithMagnitude2d (const Handle(StepGeom_Vector)& SV)
2033 {
2034   // sln 23.10.2001. CTS23496: Vector is not created if direction have not been succesfully created (MakeVectorWithMagnitude2d(...) function)
2035   Handle(Geom2d_Direction) D = MakeDirection2d (SV->Orientation());
2036   if (! D.IsNull())
2037   {
2038     const gp_Vec2d V(D->Dir2d().XY() * SV->Magnitude());
2039     return new Geom2d_VectorWithMagnitude(V);
2040   }
2041   return 0;
2042 }