0027104: DownCast() cannot return null for mismatched handle
[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 = BSR->BSplineSurfaceWithKnots();
693   }
694   else
695     BS = Handle(StepGeom_BSplineSurfaceWithKnots)::DownCast(SS);
696
697   const Standard_Integer UDeg = BS->UDegree();
698   const Standard_Integer VDeg = BS->VDegree();
699   const Standard_Integer NUPoles = BS->NbControlPointsListI();
700   const Standard_Integer NVPoles = BS->NbControlPointsListJ();
701   const Handle(StepGeom_HArray2OfCartesianPoint)& aControlPointsList = BS->ControlPointsList();
702   TColgp_Array2OfPnt Poles(1,NUPoles,1,NVPoles);
703   for (i=1; i<=NUPoles; i++) {
704     for (j=1; j<=NVPoles; j++) {
705       Handle(Geom_CartesianPoint) P = MakeCartesianPoint (aControlPointsList->Value(i,j));
706       if (! P.IsNull())
707         Poles.SetValue(i,j,P->Pnt());
708       else
709         return 0;
710     }
711   }
712   const Standard_Integer NUKnots = BS->NbUMultiplicities();
713   const Handle(TColStd_HArray1OfInteger)& aUMultiplicities = BS->UMultiplicities();
714   const Handle(TColStd_HArray1OfReal)& aUKnots = BS->UKnots();
715
716   // count number of unique uknots
717   Standard_Real lastKnot = RealFirst();
718   Standard_Integer NUKnotsUnique = 0;
719   for (i=1; i<=NUKnots; i++) {
720     if (aUKnots->Value(i) - lastKnot > Epsilon (Abs(lastKnot))) {
721       NUKnotsUnique++;
722       lastKnot = aUKnots->Value(i);
723     }
724   }
725
726   // set umultiplicities and uknots
727   TColStd_Array1OfInteger UMult(1,NUKnotsUnique);
728   TColStd_Array1OfReal KUn(1,NUKnotsUnique);
729   Standard_Integer pos = 1;
730   lastKnot = aUKnots->Value(1);
731   KUn.SetValue(1, aUKnots->Value(1));
732   UMult.SetValue(1, aUMultiplicities->Value(1));
733   for (i=2; i<=NUKnots; i++) {
734     if (aUKnots->Value(i) - lastKnot > Epsilon (Abs(lastKnot))) {
735       pos++;
736       KUn.SetValue(pos, aUKnots->Value(i));
737       UMult.SetValue(pos, aUMultiplicities->Value(i));
738       lastKnot = aUKnots->Value(i);
739     }
740     else {
741       // Knot not unique, increase multiplicity
742       Standard_Integer curMult = UMult.Value(pos);
743       UMult.SetValue(pos, curMult + aUMultiplicities->Value(i));
744     }
745   }
746   const Standard_Integer NVKnots = BS->NbVMultiplicities();
747   const Handle(TColStd_HArray1OfInteger)& aVMultiplicities = BS->VMultiplicities();
748   const Handle(TColStd_HArray1OfReal)& aVKnots = BS->VKnots();
749
750   // count number of unique vknots
751   lastKnot = RealFirst();
752   Standard_Integer NVKnotsUnique = 0;
753   for (i=1; i<=NVKnots; i++) {
754     if (aVKnots->Value(i) - lastKnot > Epsilon (Abs(lastKnot))) {
755       NVKnotsUnique++;
756       lastKnot = aVKnots->Value(i);
757     }
758   }
759
760   // set vmultiplicities and vknots
761   TColStd_Array1OfInteger VMult(1,NVKnotsUnique);
762   TColStd_Array1OfReal KVn(1,NVKnotsUnique);
763   pos = 1;
764   lastKnot = aVKnots->Value(1);
765   KVn.SetValue(1, aVKnots->Value(1));
766   VMult.SetValue(1, aVMultiplicities->Value(1));
767   for (i=2; i<=NVKnots; i++) {
768     if (aVKnots->Value(i) - lastKnot > Epsilon (Abs(lastKnot))) {
769       pos++;
770       KVn.SetValue(pos, aVKnots->Value(i));
771       VMult.SetValue(pos, aVMultiplicities->Value(i));
772       lastKnot = aVKnots->Value(i);
773     }
774     else {
775       // Knot not unique, increase multiplicity
776       Standard_Integer curMult = VMult.Value(pos);
777       VMult.SetValue(pos, curMult + aVMultiplicities->Value(i));
778     }
779   }
780
781   // --- Does the Surface Descriptor LOOKS like a U and/or V Periodic ---
782   // --- Descriptor ? ---
783
784   // --- U Periodic ? ---
785
786   Standard_Integer SumMult = 0;
787   for (i=1; i<=NUKnotsUnique; i++) {
788     SumMult += UMult.Value(i);
789   }
790
791   Standard_Boolean shouldBeUPeriodic = Standard_False;
792   if (SumMult == (NUPoles + UDeg + 1)) {
793     //shouldBeUPeriodic = Standard_False;
794   }
795   else if ((UMult.Value(1) ==
796             UMult.Value(NUKnotsUnique)) &&
797            ((SumMult - UMult.Value(1))== NUPoles)) {
798     shouldBeUPeriodic = Standard_True;
799   }
800
801   // --- V Periodic ? ---
802
803   SumMult = 0;
804   for (i=1; i<=NVKnotsUnique; i++) {
805     SumMult += VMult.Value(i);
806   }
807
808   Standard_Boolean shouldBeVPeriodic = Standard_False;
809   if (SumMult == (NVPoles + VDeg + 1)) {
810     //shouldBeVPeriodic = Standard_False;
811   }
812   else if ((VMult.Value(1) ==
813             VMult.Value(NVKnotsUnique)) &&
814            ((SumMult - VMult.Value(1)) == NVPoles)) {
815     shouldBeVPeriodic = Standard_True;
816   }
817
818   Handle(Geom_BSplineSurface) CS;
819   if (SS->IsKind(STANDARD_TYPE(StepGeom_BSplineSurfaceWithKnotsAndRationalBSplineSurface))) {
820     const Handle(TColStd_HArray2OfReal)& aWeight = BSR->WeightsData();
821     TColStd_Array2OfReal W(1,NUPoles,1,NVPoles);
822     for (i=1; i<=NUPoles; i++) {
823       for (j=1; j<=NVPoles; j++) {
824         W.SetValue(i,j,aWeight->Value(i,j));
825       }
826     }
827     CS = new Geom_BSplineSurface(Poles, W, KUn, KVn, UMult,
828                                  VMult, UDeg, VDeg,
829                                  shouldBeUPeriodic,
830                                  shouldBeVPeriodic);
831   }
832   else
833     CS = new Geom_BSplineSurface(Poles, KUn, KVn, UMult,
834                                  VMult, UDeg, VDeg,
835                                  shouldBeUPeriodic,
836                                  shouldBeVPeriodic);
837   return CS;
838 }
839
840 //=============================================================================
841 // Creation d' un CartesianPoint de Geom a partir d' un CartesianPoint de Step
842 //=============================================================================
843
844 Handle(Geom_CartesianPoint) StepToGeom::MakeCartesianPoint (const Handle(StepGeom_CartesianPoint)& SP)
845 {
846   if (SP->NbCoordinates() == 3)
847   {
848     const Standard_Real LF = UnitsMethods::LengthFactor();
849     const Standard_Real X = SP->CoordinatesValue(1) * LF;
850     const Standard_Real Y = SP->CoordinatesValue(2) * LF;
851     const Standard_Real Z = SP->CoordinatesValue(3) * LF;
852     return new Geom_CartesianPoint(X, Y, Z);
853   }
854   return 0;
855 }
856
857 //=============================================================================
858 // Creation d' un CartesianPoint de Geom2d a partir d' un CartesianPoint de
859 // Step
860 //=============================================================================
861
862 Handle(Geom2d_CartesianPoint) StepToGeom::MakeCartesianPoint2d (const Handle(StepGeom_CartesianPoint)& SP)
863 {
864   if (SP->NbCoordinates() == 2)
865   {
866     const Standard_Real X = SP->CoordinatesValue(1);
867     const Standard_Real Y = SP->CoordinatesValue(2);
868     return new Geom2d_CartesianPoint(X, Y);
869   }
870   return 0;
871 }
872
873 //=============================================================================
874 // Creation d' un Circle de Geom a partir d' un Circle de Step
875 //=============================================================================
876
877 Handle(Geom_Circle) StepToGeom::MakeCircle (const Handle(StepGeom_Circle)& SC)
878 {
879   const StepGeom_Axis2Placement AxisSelect = SC->Position();
880   if (AxisSelect.CaseNum(AxisSelect.Value()) == 2)
881   {
882     Handle(Geom_Axis2Placement) A =
883       MakeAxis2Placement (Handle(StepGeom_Axis2Placement3d)::DownCast(AxisSelect.Value()));
884     if (! A.IsNull())
885     {
886       return new Geom_Circle(A->Ax2(),SC->Radius() * UnitsMethods::LengthFactor());
887     }
888   }
889   return 0;
890 }
891
892 //=============================================================================
893 // Creation d' un Circle de Geom2d a partir d' un Circle de Step
894 //=============================================================================
895
896 Handle(Geom2d_Circle) StepToGeom::MakeCircle2d (const Handle(StepGeom_Circle)& SC)
897 {
898   const StepGeom_Axis2Placement AxisSelect = SC->Position();
899   if (AxisSelect.CaseNum(AxisSelect.Value()) == 1) {
900     Handle(Geom2d_AxisPlacement) A1 =
901       MakeAxisPlacement (Handle(StepGeom_Axis2Placement2d)::DownCast(AxisSelect.Value()));
902     if (! A1.IsNull())
903     {
904       return new Geom2d_Circle (A1->Ax2d(), SC->Radius());
905     }
906   }
907   return 0;
908 }
909
910 //=============================================================================
911 // Creation d' une Conic de Geom a partir d' une Conic de Step
912 //=============================================================================
913
914 Handle(Geom_Conic) StepToGeom::MakeConic (const Handle(StepGeom_Conic)& SC)
915 {
916   if (SC->IsKind(STANDARD_TYPE(StepGeom_Circle))) {
917     return MakeCircle (Handle(StepGeom_Circle)::DownCast(SC));
918   }
919   if (SC->IsKind(STANDARD_TYPE(StepGeom_Ellipse))) {
920     return MakeEllipse (Handle(StepGeom_Ellipse)::DownCast(SC));
921   }
922   if (SC->IsKind(STANDARD_TYPE(StepGeom_Hyperbola))) {
923     return MakeHyperbola (Handle(StepGeom_Hyperbola)::DownCast(SC));
924   }
925   if (SC->IsKind(STANDARD_TYPE(StepGeom_Parabola))) {
926     return MakeParabola (Handle(StepGeom_Parabola)::DownCast(SC));
927   }
928   // Attention : Other conic shall be implemented !
929   return 0;
930 }
931
932 //=============================================================================
933 // Creation d' une Conic de Geom2d a partir d' une Conic de Step
934 //=============================================================================
935
936 Handle(Geom2d_Conic) StepToGeom::MakeConic2d (const Handle(StepGeom_Conic)& SC)
937 {
938   if (SC->IsKind(STANDARD_TYPE(StepGeom_Circle))) {
939     return MakeCircle2d (Handle(StepGeom_Circle)::DownCast(SC));
940   }
941   if (SC->IsKind(STANDARD_TYPE(StepGeom_Ellipse))) {
942     return MakeEllipse2d (Handle(StepGeom_Ellipse)::DownCast(SC));
943   }
944   if (SC->IsKind(STANDARD_TYPE(StepGeom_Hyperbola))) {
945     return MakeHyperbola2d (Handle(StepGeom_Hyperbola)::DownCast(SC));
946   }
947   if (SC->IsKind(STANDARD_TYPE(StepGeom_Parabola))) {
948     return MakeParabola2d (Handle(StepGeom_Parabola)::DownCast(SC));
949   }
950   // Attention : Other conic shall be implemented !
951   return Handle(Geom2d_Conic)();
952 }
953
954 //=============================================================================
955 // Creation d' une ConicalSurface de Geom a partir d' une ConicalSurface de
956 // Step
957 //=============================================================================
958
959 Handle(Geom_ConicalSurface) StepToGeom::MakeConicalSurface (const Handle(StepGeom_ConicalSurface)& SS)
960 {
961   Handle(Geom_Axis2Placement) A = MakeAxis2Placement (SS->Position());
962   if (! A.IsNull())
963   {
964     const Standard_Real R = SS->Radius() * UnitsMethods::LengthFactor();
965     const Standard_Real Ang = SS->SemiAngle() * UnitsMethods::PlaneAngleFactor();
966     //#2(K3-3) rln 12/02/98 ProSTEP ct_turbine-A.stp entity #518, #3571 (gp::Resolution() is too little)
967     return new Geom_ConicalSurface(A->Ax2(), Max(Ang, Precision::Angular()), R);
968   }
969   return 0;
970 }
971
972 //=============================================================================
973 // Creation d' une Curve de Geom a partir d' une Curve de Step
974 //=============================================================================
975
976 Handle(Geom_Curve) StepToGeom::MakeCurve (const Handle(StepGeom_Curve)& SC)
977 {
978   if (SC.IsNull()){
979     return Handle(Geom_Curve)();
980   }
981   if (SC->IsKind(STANDARD_TYPE(StepGeom_Line))) {
982     return MakeLine (Handle(StepGeom_Line)::DownCast(SC));
983   }
984   if (SC->IsKind(STANDARD_TYPE(StepGeom_TrimmedCurve))) {
985     return MakeTrimmedCurve (Handle(StepGeom_TrimmedCurve)::DownCast(SC));
986   }
987   if (SC->IsKind(STANDARD_TYPE(StepGeom_Conic))) {
988     return MakeConic (Handle(StepGeom_Conic)::DownCast(SC));
989   }
990   if (SC->IsKind(STANDARD_TYPE(StepGeom_BoundedCurve))) {
991     return MakeBoundedCurve (Handle(StepGeom_BoundedCurve)::DownCast(SC));
992   }
993   if (SC->IsKind(STANDARD_TYPE(StepGeom_CurveReplica))) { //:n7 abv 16 Feb 99
994     const Handle(StepGeom_CurveReplica) CR = Handle(StepGeom_CurveReplica)::DownCast(SC);
995     const Handle(StepGeom_Curve) PC = CR->ParentCurve();
996     const Handle(StepGeom_CartesianTransformationOperator3d) T =
997       Handle(StepGeom_CartesianTransformationOperator3d)::DownCast(CR->Transformation());
998     // protect against cyclic references and wrong type of cartop
999     if ( !T.IsNull() && PC != SC )
1000     {
1001       Handle(Geom_Curve) C1 = MakeCurve (PC);
1002       if (! C1.IsNull())
1003       {
1004         gp_Trsf T1;
1005         if (MakeTransformation3d(T,T1))
1006         {
1007           C1->Transform ( T1 );
1008           return C1;
1009         }
1010       }
1011     }
1012   }
1013   else if (SC->IsKind(STANDARD_TYPE(StepGeom_OffsetCurve3d))) { //:o2 abv 17 Feb 99
1014     const Handle(StepGeom_OffsetCurve3d) OC = Handle(StepGeom_OffsetCurve3d)::DownCast(SC);
1015     const Handle(StepGeom_Curve) BC = OC->BasisCurve();
1016     if ( BC != SC ) { // protect against loop
1017       Handle(Geom_Curve) C1 = MakeCurve (BC);
1018       if (! C1.IsNull())
1019       {
1020         Handle(Geom_Direction) RD = MakeDirection(OC->RefDirection());
1021         if (! RD.IsNull())
1022         {
1023           return new Geom_OffsetCurve ( C1, -OC->Distance(), RD->Dir() );
1024         }
1025       }
1026     }
1027   }
1028   else if (SC->IsKind(STANDARD_TYPE(StepGeom_SurfaceCurve))) { //:o5 abv 17 Feb 99
1029     const Handle(StepGeom_SurfaceCurve) SurfC = Handle(StepGeom_SurfaceCurve)::DownCast(SC);
1030     return MakeCurve (SurfC->Curve3d());
1031   }
1032   return 0;
1033 }
1034
1035 //=============================================================================
1036 // Creation d' une Curve de Geom2d a partir d' une Curve de Step
1037 //=============================================================================
1038
1039 Handle(Geom2d_Curve) StepToGeom::MakeCurve2d (const Handle(StepGeom_Curve)& SC)
1040 {
1041   if (SC->IsKind(STANDARD_TYPE(StepGeom_Line))) {
1042     return MakeLine2d (Handle(StepGeom_Line)::DownCast(SC));
1043   }
1044   if (SC->IsKind(STANDARD_TYPE(StepGeom_Conic))) {
1045     return MakeConic2d (Handle(StepGeom_Conic)::DownCast(SC));
1046   }
1047   if (SC->IsKind(STANDARD_TYPE(StepGeom_BoundedCurve))) {
1048     return MakeBoundedCurve2d (Handle(StepGeom_BoundedCurve)::DownCast(SC));
1049   }
1050   if (SC->IsKind(STANDARD_TYPE(StepGeom_CurveReplica))) { //:n7 abv 16 Feb 99
1051     const Handle(StepGeom_CurveReplica) CR = Handle(StepGeom_CurveReplica)::DownCast(SC);
1052     const Handle(StepGeom_Curve) PC = CR->ParentCurve();
1053     const Handle(StepGeom_CartesianTransformationOperator2d) T =
1054       Handle(StepGeom_CartesianTransformationOperator2d)::DownCast(CR->Transformation());
1055     // protect against cyclic references and wrong type of cartop
1056     if ( !T.IsNull() && PC != SC )
1057     {
1058       Handle(Geom2d_Curve) C1 = MakeCurve2d (PC);
1059       if (! C1.IsNull())
1060       {
1061         gp_Trsf2d T1;
1062         if (MakeTransformation2d(T,T1))
1063         {
1064           C1->Transform ( T1 );
1065           return C1;
1066         }
1067       }
1068     }
1069   }
1070   return 0;
1071 }
1072
1073 //=============================================================================
1074 // Creation d' une CylindricalSurface de Geom a partir d' une
1075 // CylindricalSurface de Step
1076 //=============================================================================
1077
1078 Handle(Geom_CylindricalSurface) StepToGeom::MakeCylindricalSurface (const Handle(StepGeom_CylindricalSurface)& SS)
1079 {
1080   Handle(Geom_Axis2Placement) A = MakeAxis2Placement(SS->Position());
1081   if (! A.IsNull())
1082   {
1083     return new Geom_CylindricalSurface(A->Ax2(), SS->Radius() * UnitsMethods::LengthFactor());
1084   }
1085   return 0;
1086 }
1087
1088 //=============================================================================
1089 // Creation d' un Direction de Geom a partir d' un Direction de Step
1090 //=============================================================================
1091
1092 Handle(Geom_Direction) StepToGeom::MakeDirection (const Handle(StepGeom_Direction)& SD)
1093 {
1094   if (SD->NbDirectionRatios() >= 3)
1095   {
1096     const Standard_Real X = SD->DirectionRatiosValue(1);
1097     const Standard_Real Y = SD->DirectionRatiosValue(2);
1098     const Standard_Real Z = SD->DirectionRatiosValue(3);
1099     // sln 22.10.2001. CTS23496: Direction is not created if it has null magnitude
1100     if (gp_XYZ(X, Y, Z).SquareModulus() > gp::Resolution()*gp::Resolution())
1101     {
1102       return new Geom_Direction(X, Y, Z);
1103     }
1104   }
1105   return 0;
1106 }
1107
1108 //=============================================================================
1109 // Creation d' un Direction de Geom2d a partir d' un Direction de Step
1110 //=============================================================================
1111
1112 Handle(Geom2d_Direction) StepToGeom::MakeDirection2d (const Handle(StepGeom_Direction)& SD)
1113 {
1114   if (SD->NbDirectionRatios() >= 2)
1115   {
1116     const Standard_Real X = SD->DirectionRatiosValue(1);
1117     const Standard_Real Y = SD->DirectionRatiosValue(2);
1118     // sln 23.10.2001. CTS23496: Direction is not created if it has null magnitude
1119     if(gp_XY(X,Y).SquareModulus() > gp::Resolution()*gp::Resolution())
1120     {
1121       return  new Geom2d_Direction(X, Y);
1122     }
1123   }
1124   return 0;
1125 }
1126
1127 //=============================================================================
1128 // Creation d' une ElementarySurface de Geom a partir d' une
1129 // ElementarySurface de Step
1130 //=============================================================================
1131
1132 Handle(Geom_ElementarySurface) StepToGeom::MakeElementarySurface (const Handle(StepGeom_ElementarySurface)& SS)
1133 {
1134   if (SS->IsKind(STANDARD_TYPE(StepGeom_Plane))) {
1135     return MakePlane (Handle(StepGeom_Plane)::DownCast(SS));
1136   }
1137   if (SS->IsKind(STANDARD_TYPE(StepGeom_CylindricalSurface))) {
1138     return MakeCylindricalSurface (Handle(StepGeom_CylindricalSurface)::DownCast(SS));
1139   }
1140   if (SS->IsKind(STANDARD_TYPE(StepGeom_ConicalSurface))) {
1141     return MakeConicalSurface (Handle(StepGeom_ConicalSurface)::DownCast(SS));
1142   }
1143   if (SS->IsKind(STANDARD_TYPE(StepGeom_SphericalSurface))) {
1144     return MakeSphericalSurface (Handle(StepGeom_SphericalSurface)::DownCast(SS));
1145   }
1146   if (SS->IsKind(STANDARD_TYPE(StepGeom_ToroidalSurface))) {
1147     return MakeToroidalSurface (Handle(StepGeom_ToroidalSurface)::DownCast(SS));
1148   }
1149   return 0;
1150 }
1151
1152 //=============================================================================
1153 // Creation d' un Ellipse de Geom a partir d' un Ellipse de Step
1154 //=============================================================================
1155
1156 Handle(Geom_Ellipse) StepToGeom::MakeEllipse (const Handle(StepGeom_Ellipse)& SC)
1157 {
1158   const StepGeom_Axis2Placement AxisSelect = SC->Position();
1159   if (AxisSelect.CaseNum(AxisSelect.Value()) == 2) {
1160     Handle(Geom_Axis2Placement) A1 = MakeAxis2Placement (Handle(StepGeom_Axis2Placement3d)::DownCast(AxisSelect.Value()));
1161     if (! A1.IsNull())
1162     {
1163       gp_Ax2 A( A1->Ax2() );
1164       const Standard_Real LF = UnitsMethods::LengthFactor();
1165       const Standard_Real majorR = SC->SemiAxis1() * LF;
1166       const Standard_Real minorR = SC->SemiAxis2() * LF;
1167       if ( majorR - minorR >= 0. ) { //:o9 abv 19 Feb 99
1168         return new Geom_Ellipse(A, majorR, minorR);
1169       }
1170       //:o9 abv 19 Feb 99
1171       else {
1172         A.SetXDirection ( A.XDirection() ^ A.Direction() );
1173         return new Geom_Ellipse(A, minorR, majorR);
1174       }
1175     }
1176   }
1177   return 0;
1178 }
1179
1180 //=============================================================================
1181 // Creation d' un Ellipse de Geom2d a partir d' un Ellipse de Step
1182 //=============================================================================
1183
1184 Handle(Geom2d_Ellipse) StepToGeom::MakeEllipse2d (const Handle(StepGeom_Ellipse)& SC)
1185 {
1186   const StepGeom_Axis2Placement AxisSelect = SC->Position();
1187   if (AxisSelect.CaseNum(AxisSelect.Value()) == 1) {
1188     Handle(Geom2d_AxisPlacement) A1 = MakeAxisPlacement (Handle(StepGeom_Axis2Placement2d)::DownCast(AxisSelect.Value()));
1189     if (! A1.IsNull())
1190     {
1191       gp_Ax22d A( A1->Ax2d() );
1192       const Standard_Real majorR = SC->SemiAxis1();
1193       const Standard_Real minorR = SC->SemiAxis2();
1194       if ( majorR - minorR >= 0. ) { //:o9 abv 19 Feb 99: bm4_id_punch_b.stp #678: protection
1195         return new Geom2d_Ellipse(A, majorR, minorR);
1196       }
1197       else {
1198         const gp_Dir2d X = A.XDirection();
1199         A.SetXDirection ( gp_Dir2d ( X.X(), -X.Y() ) );
1200         return new Geom2d_Ellipse(A, minorR, majorR);
1201       }
1202     }
1203   }
1204   return 0;
1205 }
1206
1207 //=============================================================================
1208 // Creation d' un Hyperbola de Geom a partir d' un Hyperbola de Step
1209 //=============================================================================
1210
1211 Handle(Geom_Hyperbola) StepToGeom::MakeHyperbola (const Handle(StepGeom_Hyperbola)& SC)
1212 {
1213   const StepGeom_Axis2Placement AxisSelect = SC->Position();
1214   if (AxisSelect.CaseNum(AxisSelect.Value()) == 2)
1215   {
1216     Handle(Geom_Axis2Placement) A1 = MakeAxis2Placement (Handle(StepGeom_Axis2Placement3d)::DownCast(AxisSelect.Value()));
1217     if (! A1.IsNull())
1218     {
1219       const gp_Ax2 A( A1->Ax2() );
1220       const Standard_Real LF = UnitsMethods::LengthFactor();
1221       return new Geom_Hyperbola(A, SC->SemiAxis() * LF, SC->SemiImagAxis() * LF);
1222     }
1223   }
1224   return 0;
1225 }
1226
1227 //=============================================================================
1228 // Creation d' un Hyperbola de Geom2d a partir d' un Hyperbola de Step
1229 //=============================================================================
1230
1231 Handle(Geom2d_Hyperbola) StepToGeom::MakeHyperbola2d (const Handle(StepGeom_Hyperbola)& SC)
1232 {
1233   const StepGeom_Axis2Placement AxisSelect = SC->Position();
1234   if (AxisSelect.CaseNum(AxisSelect.Value()) == 1)
1235   {
1236     Handle(Geom2d_AxisPlacement) A1 = MakeAxisPlacement (Handle(StepGeom_Axis2Placement2d)::DownCast(AxisSelect.Value()));
1237     if (! A1.IsNull())
1238     {
1239       const gp_Ax22d A( A1->Ax2d() );
1240       return new Geom2d_Hyperbola(A, SC->SemiAxis(), SC->SemiImagAxis());
1241     }
1242   }
1243   return 0;
1244 }
1245
1246 //=============================================================================
1247 // Creation d' une Line de Geom a partir d' une Line de Step
1248 //=============================================================================
1249
1250 Handle(Geom_Line) StepToGeom::MakeLine (const Handle(StepGeom_Line)& SC)
1251 {
1252   Handle(Geom_CartesianPoint) P = MakeCartesianPoint(SC->Pnt());
1253   if (! P.IsNull())
1254   {
1255     // sln 22.10.2001. CTS23496: Line is not created if direction have not been succesfully created
1256     Handle(Geom_VectorWithMagnitude) D = MakeVectorWithMagnitude (SC->Dir());
1257     if (! D.IsNull())
1258     {
1259       if( D->Vec().SquareMagnitude() < Precision::Confusion() * Precision::Confusion())
1260         return 0;
1261       const gp_Dir V(D->Vec());
1262       return new Geom_Line(P->Pnt(), V);
1263     }
1264   }
1265   return 0;
1266 }
1267
1268 //=============================================================================
1269 // Creation d' une Line de Geom2d a partir d' une Line de Step
1270 //=============================================================================
1271
1272 Handle(Geom2d_Line) StepToGeom::MakeLine2d (const Handle(StepGeom_Line)& SC)
1273 {
1274   Handle(Geom2d_CartesianPoint) P = MakeCartesianPoint2d(SC->Pnt());
1275   if (! P.IsNull())
1276   {
1277     // sln 23.10.2001. CTS23496: Line is not created if direction have not been succesfully created
1278     Handle(Geom2d_VectorWithMagnitude) D = MakeVectorWithMagnitude2d (SC->Dir());
1279     if (! D.IsNull())
1280     {
1281       const gp_Dir2d D1(D->Vec2d());
1282       return new Geom2d_Line(P->Pnt2d(), D1);
1283     }
1284   }
1285   return 0;
1286 }
1287
1288 //=============================================================================
1289 // Creation d' un Parabola de Geom a partir d' un Parabola de Step
1290 //=============================================================================
1291
1292 Handle(Geom_Parabola) StepToGeom::MakeParabola (const Handle(StepGeom_Parabola)& SC)
1293 {
1294   const StepGeom_Axis2Placement AxisSelect = SC->Position();
1295   if (AxisSelect.CaseNum(AxisSelect.Value()) == 2)
1296   {
1297     Handle(Geom_Axis2Placement) A = MakeAxis2Placement (Handle(StepGeom_Axis2Placement3d)::DownCast(AxisSelect.Value()));
1298     if (! A.IsNull())
1299     {
1300       return new Geom_Parabola(A->Ax2(), SC->FocalDist() * UnitsMethods::LengthFactor());
1301     }
1302   }
1303   return 0;
1304 }
1305
1306 //=============================================================================
1307 // Creation d' un Parabola de Geom2d a partir d' un Parabola de Step
1308 //=============================================================================
1309
1310 Handle(Geom2d_Parabola) StepToGeom::MakeParabola2d (const Handle(StepGeom_Parabola)& SC)
1311 {
1312   const StepGeom_Axis2Placement AxisSelect = SC->Position();
1313   if (AxisSelect.CaseNum(AxisSelect.Value()) == 1) {
1314     Handle(Geom2d_AxisPlacement) A1 = MakeAxisPlacement (Handle(StepGeom_Axis2Placement2d)::DownCast(AxisSelect.Value()));
1315     if (! A1.IsNull())
1316     {
1317       const gp_Ax22d A( A1->Ax2d() );
1318       return new Geom2d_Parabola(A, SC->FocalDist());
1319     }
1320   }
1321   return 0;
1322 }
1323
1324 //=============================================================================
1325 // Creation d' un Plane de Geom a partir d' un plane de Step
1326 //=============================================================================
1327
1328 Handle(Geom_Plane) StepToGeom::MakePlane (const Handle(StepGeom_Plane)& SP)
1329 {
1330   Handle(Geom_Axis2Placement) A = MakeAxis2Placement (SP->Position());
1331   if (! A.IsNull())
1332   {
1333     return new Geom_Plane(A->Ax2());
1334   }
1335   return 0;
1336 }
1337
1338 //=======================================================================
1339 //function : MakePolyline
1340 //purpose  :
1341 //=======================================================================
1342
1343 Handle(Geom_BSplineCurve) StepToGeom::MakePolyline (const Handle(StepGeom_Polyline)& SPL)
1344 {
1345   if (SPL.IsNull())
1346     return Handle(Geom_BSplineCurve)();
1347
1348   const Standard_Integer nbp = SPL->NbPoints();
1349   if (nbp > 1)
1350   {
1351     TColgp_Array1OfPnt Poles ( 1, nbp );
1352     TColStd_Array1OfReal Knots ( 1, nbp );
1353     TColStd_Array1OfInteger Mults ( 1, nbp );
1354
1355     for ( Standard_Integer i=1; i <= nbp; i++ )
1356     {
1357       Handle(Geom_CartesianPoint) P = MakeCartesianPoint (SPL->PointsValue(i));
1358       if (! P.IsNull())
1359         Poles.SetValue ( i, P->Pnt() );
1360       else
1361         return 0;
1362       Knots.SetValue ( i, Standard_Real(i-1) );
1363       Mults.SetValue ( i, 1 );
1364     }
1365     Mults.SetValue ( 1, 2 );
1366     Mults.SetValue ( nbp, 2 );
1367
1368     return new Geom_BSplineCurve ( Poles, Knots, Mults, 1 );
1369   }
1370   return 0;
1371 }
1372
1373 //=======================================================================
1374 //function : MakePolyline2d
1375 //purpose  :
1376 //=======================================================================
1377
1378 Handle(Geom2d_BSplineCurve) StepToGeom::MakePolyline2d (const Handle(StepGeom_Polyline)& SPL)
1379 {
1380   if (SPL.IsNull())
1381     return Handle(Geom2d_BSplineCurve)();
1382
1383   const Standard_Integer nbp = SPL->NbPoints();
1384   if (nbp > 1)
1385   {
1386     TColgp_Array1OfPnt2d Poles ( 1, nbp );
1387     TColStd_Array1OfReal Knots ( 1, nbp );
1388     TColStd_Array1OfInteger Mults ( 1, nbp );
1389
1390     for ( Standard_Integer i=1; i <= nbp; i++ )
1391     {
1392     Handle(Geom2d_CartesianPoint) P = MakeCartesianPoint2d (SPL->PointsValue(i));
1393       if (! P.IsNull())
1394         Poles.SetValue ( i, P->Pnt2d() );
1395       else
1396         return 0;
1397       Knots.SetValue ( i, Standard_Real(i-1) );
1398       Mults.SetValue ( i, 1 );
1399     }
1400     Mults.SetValue ( 1, 2 );
1401     Mults.SetValue ( nbp, 2 );
1402
1403     return new Geom2d_BSplineCurve ( Poles, Knots, Mults, 1 );
1404   }
1405   return 0;
1406 }
1407
1408 //=============================================================================
1409 // Creation d' une RectangularTrimmedSurface de Geom a partir d' une
1410 // RectangularTrimmedSurface de Step
1411 //=============================================================================
1412
1413 Handle(Geom_RectangularTrimmedSurface) StepToGeom::MakeRectangularTrimmedSurface (const Handle(StepGeom_RectangularTrimmedSurface)& SS)
1414 {
1415   Handle(Geom_Surface) theBasis = MakeSurface (SS->BasisSurface());
1416   if (! theBasis.IsNull())
1417   {
1418     // -----------------------------------------
1419     // Modification of the Trimming Parameters ?
1420     // -----------------------------------------
1421
1422     Standard_Real uFact = 1.;
1423     Standard_Real vFact = 1.;
1424     const Standard_Real LengthFact  = UnitsMethods::LengthFactor();
1425     const Standard_Real AngleFact   = UnitsMethods::PlaneAngleFactor(); // abv 30.06.00 trj4_k1_geo-tc-214.stp #1477: PI/180.;
1426
1427     if (theBasis->IsKind(STANDARD_TYPE(Geom_SphericalSurface)) ||
1428         theBasis->IsKind(STANDARD_TYPE(Geom_ToroidalSurface))) {
1429       uFact = vFact = AngleFact;
1430     }
1431     else if (theBasis->IsKind(STANDARD_TYPE(Geom_CylindricalSurface))) {
1432       uFact = AngleFact;
1433       vFact = LengthFact;
1434     }
1435     else if ( theBasis->IsKind(STANDARD_TYPE(Geom_SurfaceOfRevolution))) {
1436       uFact = AngleFact;
1437     }
1438     else if (theBasis->IsKind(STANDARD_TYPE(Geom_ConicalSurface))) {
1439       const Handle(Geom_ConicalSurface) conicS = Handle(Geom_ConicalSurface)::DownCast(theBasis);
1440       uFact = AngleFact;
1441       vFact = LengthFact / Cos(conicS->SemiAngle());
1442     }
1443     else if (theBasis->IsKind(STANDARD_TYPE(Geom_Plane))) {
1444       uFact = vFact = LengthFact;
1445     }
1446
1447     const Standard_Real U1 = SS->U1() * uFact;
1448     const Standard_Real U2 = SS->U2() * uFact;
1449     const Standard_Real V1 = SS->V1() * vFact;
1450     const Standard_Real V2 = SS->V2() * vFact;
1451
1452     return new Geom_RectangularTrimmedSurface(theBasis, U1, U2, V1, V2, SS->Usense(), SS->Vsense());
1453   }
1454   return 0;
1455 }
1456
1457 //=============================================================================
1458 // Creation d' une SphericalSurface de Geom a partir d' une
1459 // SphericalSurface de Step
1460 //=============================================================================
1461
1462 Handle(Geom_SphericalSurface) StepToGeom::MakeSphericalSurface (const Handle(StepGeom_SphericalSurface)& SS)
1463 {
1464   Handle(Geom_Axis2Placement) A = MakeAxis2Placement (SS->Position());
1465   if (! A.IsNull())
1466   {
1467     return new Geom_SphericalSurface(A->Ax2(), SS->Radius() * UnitsMethods::LengthFactor());
1468   }
1469   return 0;
1470 }
1471
1472 //=============================================================================
1473 // Creation d' une Surface de Geom a partir d' une Surface de Step
1474 //=============================================================================
1475
1476 Handle(Geom_Surface) StepToGeom::MakeSurface (const Handle(StepGeom_Surface)& SS)
1477 {
1478    // sln 01.10.2001 BUC61003. If entry shell is NULL do nothing
1479   if(SS.IsNull()) {
1480     return Handle(Geom_Surface)();
1481   }
1482
1483   try {
1484     OCC_CATCH_SIGNALS
1485     if (SS->IsKind(STANDARD_TYPE(StepGeom_BoundedSurface))) {
1486       return MakeBoundedSurface (Handle(StepGeom_BoundedSurface)::DownCast(SS));
1487     }
1488     if (SS->IsKind(STANDARD_TYPE(StepGeom_ElementarySurface))) {
1489       const Handle(StepGeom_ElementarySurface) S1 = Handle(StepGeom_ElementarySurface)::DownCast(SS);
1490       if(S1->Position().IsNull())
1491         return Handle(Geom_Surface)();
1492
1493       return MakeElementarySurface (S1);
1494     }
1495     if (SS->IsKind(STANDARD_TYPE(StepGeom_SweptSurface))) {
1496       return MakeSweptSurface (Handle(StepGeom_SweptSurface)::DownCast(SS));
1497     }
1498     if (SS->IsKind(STANDARD_TYPE(StepGeom_OffsetSurface))) { //:d4 abv 12 Mar 98
1499       const Handle(StepGeom_OffsetSurface) OS = Handle(StepGeom_OffsetSurface)::DownCast(SS);
1500
1501       Handle(Geom_Surface) aBasisSurface = MakeSurface (OS->BasisSurface());
1502       if (! aBasisSurface.IsNull())
1503       {
1504         // sln 03.10.01. BUC61003. creation of  offset surface is corrected
1505         const Standard_Real anOffset = OS->Distance() * UnitsMethods::LengthFactor();
1506         if (aBasisSurface->Continuity() == GeomAbs_C0)
1507         {
1508           const BRepBuilderAPI_MakeFace aBFace(aBasisSurface, Precision::Confusion());
1509           if (aBFace.IsDone())
1510           {
1511             const TopoDS_Shape aResult = ShapeAlgo::AlgoContainer()->C0ShapeToC1Shape(aBFace.Face(), Abs(anOffset));
1512             if (aResult.ShapeType() == TopAbs_FACE)
1513             {
1514               aBasisSurface = BRep_Tool::Surface(TopoDS::Face(aResult));
1515             }
1516           }
1517         }
1518         if(aBasisSurface->Continuity() != GeomAbs_C0)
1519         {
1520           return new Geom_OffsetSurface ( aBasisSurface, anOffset );
1521         }
1522       }
1523     }
1524     else if (SS->IsKind(STANDARD_TYPE(StepGeom_SurfaceReplica))) { //:n7 abv 16 Feb 99
1525       const Handle(StepGeom_SurfaceReplica) SR = Handle(StepGeom_SurfaceReplica)::DownCast(SS);
1526       const Handle(StepGeom_Surface) PS = SR->ParentSurface();
1527       const Handle(StepGeom_CartesianTransformationOperator3d) T = SR->Transformation();
1528       // protect against cyclic references and wrong type of cartop
1529       if ( !T.IsNull() && PS != SS ) {
1530         Handle(Geom_Surface) S1 = MakeSurface (PS);
1531         if (! S1.IsNull())
1532         {
1533           gp_Trsf T1;
1534           if (MakeTransformation3d(T,T1))
1535           {
1536             S1->Transform ( T1 );
1537             return S1;
1538           }
1539         }
1540       }
1541     }
1542   }
1543   catch(Standard_Failure) {
1544 //   ShapeTool_DB ?
1545 #ifdef OCCT_DEBUG //:s5
1546     cout<<"Warning: MakeSurface: Exception:";
1547     Standard_Failure::Caught()->Print(cout); cout << endl;
1548 #endif
1549   }
1550   return 0;
1551 }
1552
1553 //=============================================================================
1554 // Creation d' une SurfaceOfLinearExtrusion de Geom a partir d' une
1555 // SurfaceOfLinearExtrusion de Step
1556 //=============================================================================
1557
1558 Handle(Geom_SurfaceOfLinearExtrusion) StepToGeom::MakeSurfaceOfLinearExtrusion (const Handle(StepGeom_SurfaceOfLinearExtrusion)& SS)
1559 {
1560   Handle(Geom_Curve) C = MakeCurve (SS->SweptCurve());
1561   if (! C.IsNull())
1562   {
1563     // sln 23.10.2001. CTS23496: Surface is not created if extrusion axis have not been succesfully created
1564     Handle(Geom_VectorWithMagnitude) V = MakeVectorWithMagnitude (SS->ExtrusionAxis());
1565     if (! V.IsNull())
1566     {
1567       const gp_Dir D(V->Vec());
1568       Handle(Geom_Line) aLine = Handle(Geom_Line)::DownCast(C);
1569       if (!aLine.IsNull() && aLine->Lin().Direction().IsParallel(D, Precision::Angular()))
1570         return Handle(Geom_SurfaceOfLinearExtrusion)();
1571       return new Geom_SurfaceOfLinearExtrusion(C,D);
1572     }
1573   }
1574   return 0;
1575 }
1576
1577 //=============================================================================
1578 // Creation d' une SurfaceOfRevolution de Geom a partir d' une
1579 // SurfaceOfRevolution de Step
1580 //=============================================================================
1581
1582 Handle(Geom_SurfaceOfRevolution) StepToGeom::MakeSurfaceOfRevolution (const Handle(StepGeom_SurfaceOfRevolution)& SS)
1583 {
1584   Handle(Geom_Curve) C = MakeCurve (SS->SweptCurve());
1585   if (! C.IsNull())
1586   {
1587     Handle(Geom_Axis1Placement) A1 = MakeAxis1Placement (SS->AxisPosition());
1588     if (! A1.IsNull())
1589     {
1590       const gp_Ax1 A( A1->Ax1() );
1591       //skl for OCC952 (one bad case revolution of circle)
1592       if ( C->IsKind(STANDARD_TYPE(Geom_Circle)) || C->IsKind(STANDARD_TYPE(Geom_Ellipse)) )
1593       {
1594         const Handle(Geom_Conic) conic = Handle(Geom_Conic)::DownCast(C);
1595         const gp_Pnt pc = conic->Location();
1596         const gp_Lin rl (A);
1597         if (rl.Distance(pc) < Precision::Confusion()) { //pc lies on A2
1598           const gp_Dir dirline = A.Direction();
1599           const gp_Dir norm = conic->Axis().Direction();
1600           const gp_Dir xAxis = conic->XAxis().Direction();
1601           //checking A2 lies on plane of circle
1602           if( dirline.IsNormal(norm,Precision::Angular()) && (dirline.IsParallel(xAxis,Precision::Angular()) || C->IsKind(STANDARD_TYPE(Geom_Circle)))) {
1603             //change parametrization for trimming
1604             gp_Ax2 axnew(pc,norm,dirline.Reversed());
1605             conic->SetPosition(axnew);
1606             C = new Geom_TrimmedCurve(conic, 0., M_PI);
1607           }
1608         }
1609       }
1610       return new Geom_SurfaceOfRevolution(C, A);
1611     }
1612   }
1613   return 0;
1614 }
1615
1616 //=============================================================================
1617 // Creation d' une SweptSurface de prostep a partir d' une
1618 // SweptSurface de Geom
1619 //=============================================================================
1620
1621 Handle(Geom_SweptSurface) StepToGeom::MakeSweptSurface (const Handle(StepGeom_SweptSurface)& SS)
1622 {
1623   if (SS->IsKind(STANDARD_TYPE(StepGeom_SurfaceOfLinearExtrusion))) {
1624     return MakeSurfaceOfLinearExtrusion (Handle(StepGeom_SurfaceOfLinearExtrusion)::DownCast(SS));
1625   }
1626   if (SS->IsKind(STANDARD_TYPE(StepGeom_SurfaceOfRevolution))) {
1627     return MakeSurfaceOfRevolution (Handle(StepGeom_SurfaceOfRevolution)::DownCast(SS));
1628   }
1629   return Handle(Geom_SweptSurface)();
1630 }
1631
1632 //=============================================================================
1633 // Creation d' une ToroidalSurface de Geom a partir d' une
1634 // ToroidalSurface de Step
1635 //=============================================================================
1636
1637 Handle(Geom_ToroidalSurface) StepToGeom::MakeToroidalSurface (const Handle(StepGeom_ToroidalSurface)& SS)
1638 {
1639   Handle(Geom_Axis2Placement) A = MakeAxis2Placement (SS->Position());
1640   if (! A.IsNull())
1641   {
1642     const Standard_Real LF = UnitsMethods::LengthFactor();
1643     return new Geom_ToroidalSurface(A->Ax2(), Abs(SS->MajorRadius() * LF), Abs(SS->MinorRadius() * LF));
1644   }
1645   return 0;
1646 }
1647
1648 //=======================================================================
1649 //function : MakeTransformation2d
1650 //purpose  :
1651 //=======================================================================
1652 Standard_Boolean StepToGeom::MakeTransformation2d (const Handle(StepGeom_CartesianTransformationOperator2d)& SCTO, gp_Trsf2d& CT)
1653 {
1654   //  NB : on ne s interesse ici qu au deplacement rigide
1655   Handle(Geom2d_CartesianPoint) CP = MakeCartesianPoint2d (SCTO->LocalOrigin());
1656   if (! CP.IsNull())
1657   {
1658     gp_Dir2d D1(1.,0.);
1659     // sln 23.10.2001. CTS23496: If problems with creation of direction occur default direction is used
1660     const Handle(StepGeom_Direction) A = SCTO->Axis1();
1661     if (!A.IsNull())
1662     {
1663       Handle(Geom2d_Direction) D = MakeDirection2d (A);
1664       if (! D.IsNull())
1665         D1 = D->Dir2d();
1666     }
1667     const gp_Ax2d result(CP->Pnt2d(),D1);
1668     CT.SetTransformation(result);
1669     CT = CT.Inverted();
1670     return Standard_True;
1671   }
1672   return Standard_False;
1673 }
1674
1675 //=======================================================================
1676 //function : MakeTransformation3d
1677 //purpose  :
1678 //=======================================================================
1679
1680 Standard_Boolean StepToGeom::MakeTransformation3d (const Handle(StepGeom_CartesianTransformationOperator3d)& SCTO, gp_Trsf& CT)
1681 {
1682   Handle(Geom_CartesianPoint) CP = MakeCartesianPoint (SCTO->LocalOrigin());
1683   if (! CP.IsNull())
1684   {
1685     const gp_Pnt Pgp = CP->Pnt();
1686
1687     // sln 23.10.2001. CTS23496: If problems with creation of direction occur default direction is used
1688     gp_Dir D1(1.,0.,0.);
1689     const Handle(StepGeom_Direction) A1 = SCTO->Axis1();
1690     if (!A1.IsNull()) {
1691       Handle(Geom_Direction) D = MakeDirection (A1);
1692       if (! D.IsNull())
1693         D1 = D->Dir();
1694     }
1695
1696     gp_Dir D2(0.,1.,0.);
1697     const Handle(StepGeom_Direction) A2 = SCTO->Axis2();
1698     if (!A2.IsNull()) {
1699       Handle(Geom_Direction) D = MakeDirection (A2);
1700       if (! D.IsNull())
1701         D2 = D->Dir();
1702     }
1703
1704     Standard_Boolean isDefaultDirectionUsed = Standard_True;
1705     gp_Dir D3;
1706     const Handle(StepGeom_Direction) A3 = SCTO->Axis3();
1707     if (!A3.IsNull()) {
1708       Handle(Geom_Direction) D = MakeDirection (A3);
1709       if (! D.IsNull())
1710       {
1711         D3 = D->Dir();
1712         isDefaultDirectionUsed = Standard_False;
1713       }
1714     }
1715     if(isDefaultDirectionUsed)
1716       D3 = D1.Crossed(D2);
1717
1718     const gp_Ax3 result(Pgp,D3,D1);
1719     CT.SetTransformation(result);
1720     CT = CT.Inverted(); //:n8 abv 16 Feb 99: tr8_as2_db.stp: reverse for accordance with LV tool
1721     return Standard_True;
1722   }
1723   return Standard_False;
1724 }
1725
1726 // ----------------------------------------------------------------
1727 // ExtractParameter
1728 // ----------------------------------------------------------------
1729 //:o6 abv 18 Feb 99: parameter Factor added
1730 //:p3 abv 23 Feb 99: parameter Shift added
1731 static Standard_Boolean  ExtractParameter
1732 (const Handle(Geom_Curve) &  aGeomCurve,
1733  const Handle(StepGeom_HArray1OfTrimmingSelect) & TS,
1734  const Standard_Integer nbSel,
1735  const Standard_Integer MasterRep,
1736  const Standard_Real Factor,
1737  const Standard_Real Shift,
1738  Standard_Real & aParam)
1739 {
1740   Handle(StepGeom_CartesianPoint) aPoint;
1741   Standard_Integer i;
1742 //:S4136  Standard_Real precBrep = BRepAPI::Precision();
1743   for ( i = 1 ; i <= nbSel ; i++) {
1744     StepGeom_TrimmingSelect theSel = TS->Value(i);
1745     if (MasterRep == 2 && theSel.CaseMember() > 0) {
1746       aParam = Shift + Factor * theSel.ParameterValue();
1747       return Standard_True;
1748     }
1749     else if (MasterRep == 1 && theSel.CaseNumber() > 0) {
1750       aPoint = theSel.CartesianPoint();
1751       Handle(Geom_CartesianPoint) theGeomPnt = StepToGeom::MakeCartesianPoint (aPoint);
1752       gp_Pnt thegpPnt = theGeomPnt->Pnt();
1753
1754       //:S4136: use advanced algorithm
1755       ShapeAnalysis_Curve sac;
1756       gp_Pnt p;
1757       sac.Project ( aGeomCurve, thegpPnt, Precision::Confusion(), p, aParam );
1758 /* //:S4136
1759       //Trim == natural boundary ?
1760       if(aGeomCurve->IsKind(STANDARD_TYPE(Geom_BoundedCurve))) {
1761         Standard_Real frstPar = aGeomCurve->FirstParameter();
1762         Standard_Real lstPar = aGeomCurve->LastParameter();
1763         gp_Pnt frstPnt = aGeomCurve->Value(frstPar);
1764         gp_Pnt lstPnt = aGeomCurve->Value(lstPar);
1765         if(frstPnt.IsEqual(thegpPnt,precBrep)) {
1766           aParam = frstPar;
1767           return Standard_True;
1768         }
1769         if(lstPnt.IsEqual(thegpPnt,precBrep)) {
1770           aParam = lstPar;
1771           return Standard_True;
1772         }
1773       }
1774       // Project Point On Curve
1775       GeomAPI_ProjectPointOnCurve PPOC(thegpPnt, aGeomCurve);
1776       if (PPOC.NbPoints() == 0) {
1777         return Standard_False;
1778       }
1779       aParam = PPOC.LowerDistanceParameter();
1780 */
1781       return Standard_True;
1782     }
1783   }
1784 // if the MasterRepresentation is unspecified:
1785 // if a ParameterValue exists, it is prefered
1786
1787   for ( i = 1 ; i <= nbSel ; i++) {
1788     StepGeom_TrimmingSelect theSel = TS->Value(i);
1789     if (theSel.CaseMember() > 0) {
1790       aParam = Shift + Factor * theSel.ParameterValue();
1791
1792       return Standard_True;
1793     }
1794   }
1795 // if no ParameterValue exists, it is created from the CartesianPointValue
1796
1797   for ( i = 1 ; i <= nbSel ; i++) {
1798     StepGeom_TrimmingSelect theSel = TS->Value(i);
1799     if (theSel.CaseNumber() > 0) {
1800       aPoint = theSel.CartesianPoint();
1801       Handle(Geom_CartesianPoint) theGeomPnt = StepToGeom::MakeCartesianPoint (aPoint);
1802       gp_Pnt thegpPnt = theGeomPnt->Pnt();
1803       // Project Point On Curve
1804       ShapeAnalysis_Curve sac;
1805       gp_Pnt p;
1806       sac.Project ( aGeomCurve, thegpPnt, Precision::Confusion(), p, aParam );
1807 /*
1808       GeomAPI_ProjectPointOnCurve PPOC(thegpPnt, aGeomCurve);
1809       if (PPOC.NbPoints() == 0) {
1810         return Standard_False;
1811       }
1812       aParam = PPOC.LowerDistanceParameter();
1813 */
1814       return Standard_True;
1815     }
1816   }
1817   return Standard_False;  // I suppose
1818 }
1819
1820
1821 //=============================================================================
1822 // Creation d' une Trimmed Curve de Geom a partir d' une Trimmed Curve de Step
1823 //=============================================================================
1824
1825 Handle(Geom_TrimmedCurve) StepToGeom::MakeTrimmedCurve (const Handle(StepGeom_TrimmedCurve)& SC)
1826 {
1827   const Handle(StepGeom_Curve) theSTEPCurve = SC->BasisCurve();
1828   Handle(Geom_Curve) theCurve = MakeCurve (theSTEPCurve);
1829   if (theCurve.IsNull())
1830     return Handle(Geom_TrimmedCurve)();
1831
1832   const Handle(StepGeom_HArray1OfTrimmingSelect)& theTrimSel1 = SC->Trim1();
1833   const Handle(StepGeom_HArray1OfTrimmingSelect)& theTrimSel2 = SC->Trim2();
1834   const Standard_Integer nbSel1 = SC->NbTrim1();
1835   const Standard_Integer nbSel2 = SC->NbTrim2();
1836
1837   Standard_Integer MasterRep;
1838   switch (SC->MasterRepresentation())
1839   {
1840     case StepGeom_tpCartesian: MasterRep = 1; break;
1841     case StepGeom_tpParameter: MasterRep = 2; break;
1842     default: MasterRep = 0;
1843   }
1844
1845   //gka 18.02.04 analysis for case when MasterRep = .Unspecified
1846   //and parameters are specified as CARTESIAN_POINT
1847   Standard_Boolean isPoint = Standard_False;
1848   if(MasterRep == 0 || (MasterRep == 2 && nbSel1 >1 && nbSel2 > 1)) {
1849     Standard_Integer ii;
1850     for(ii = 1; ii <= nbSel1; ii++)
1851     {
1852       if (!(theTrimSel1->Value(ii).CartesianPoint().IsNull()))
1853       {
1854         for(ii = 1; ii <= nbSel2; ii++)
1855         {
1856           if (!(theTrimSel2->Value(ii).CartesianPoint().IsNull()))
1857           {
1858             isPoint = Standard_True;
1859             break;
1860           }
1861         }
1862         break;
1863       }
1864     }
1865   }
1866
1867   //:o6 abv 18 Feb 99: computation of factor moved
1868   Standard_Real fact = 1., shift = 0.;
1869   if (theSTEPCurve->IsKind(STANDARD_TYPE(StepGeom_Line))) {
1870     const Handle(StepGeom_Line) theLine =
1871       Handle(StepGeom_Line)::DownCast(theSTEPCurve);
1872     fact = theLine->Dir()->Magnitude() * UnitsMethods::LengthFactor();
1873   }
1874   else if (theSTEPCurve->IsKind(STANDARD_TYPE(StepGeom_Circle)) ||
1875            theSTEPCurve->IsKind(STANDARD_TYPE(StepGeom_Ellipse))) {
1876 //    if (trim1 > 2.1*M_PI || trim2 > 2.1*M_PI) fact = M_PI / 180.;
1877     fact = UnitsMethods::PlaneAngleFactor();
1878     //:p3 abv 23 Feb 99: shift on pi/2 on ellipse with R1 < R2
1879     const Handle(StepGeom_Ellipse) ellipse = Handle(StepGeom_Ellipse)::DownCast(theSTEPCurve);
1880     if ( !ellipse.IsNull() && ellipse->SemiAxis1() - ellipse->SemiAxis2() < 0. )
1881       shift = 0.5 * M_PI;
1882
1883     // skl 04.02.2002 for OCC133: we can not make TrimmedCurve if
1884     // there is no X-direction in StepGeom_Axis2Placement3d
1885     const Handle(StepGeom_Conic) conic = Handle(StepGeom_Conic)::DownCast(theSTEPCurve);
1886     // CKY 6-FEB-2004 for Airbus-MedialAxis :
1887     // this restriction does not apply for trimming by POINTS
1888     if(!conic.IsNull() && MasterRep != 1) {
1889       const StepGeom_Axis2Placement a2p = conic->Position();
1890       if(a2p.CaseNum(a2p.Value())==2) {
1891         if( !a2p.Axis2Placement3d()->HasRefDirection() ) {
1892           ////gka 18.02.04 analysis for case when MasterRep = .Unspecified
1893           //and parameters are specified as CARTESIAN_POINT
1894           if(isPoint /*&& !MasterRep*/)
1895             MasterRep =1;
1896           else {
1897             if ( SC->SenseAgreement() )
1898               return new Geom_TrimmedCurve(theCurve, 0., 2.*M_PI, Standard_True);
1899             else
1900               return new Geom_TrimmedCurve(theCurve, 2.*M_PI, 0., Standard_False);
1901           }
1902         }
1903       }
1904     }
1905   }
1906
1907   Standard_Real trim1 = 0.;
1908   Standard_Real trim2 = 0.;
1909   Handle(StepGeom_CartesianPoint) TrimCP1, TrimCP2;
1910   const Standard_Boolean FoundParam1 = ExtractParameter(theCurve, theTrimSel1, nbSel1, MasterRep, fact, shift, trim1);
1911   const Standard_Boolean FoundParam2 = ExtractParameter(theCurve, theTrimSel2, nbSel2, MasterRep, fact, shift, trim2);
1912
1913   if (FoundParam1 && FoundParam2) {
1914     const Standard_Real cf = theCurve->FirstParameter();
1915     const Standard_Real cl = theCurve->LastParameter();
1916     //: abv 09.04.99: S4136: bm2_ug_t4-B.stp #70610: protect against OutOfRange
1917     if ( !theCurve->IsPeriodic() ) {
1918       if ( trim1 < cf ) trim1 = cf;
1919       else if ( trim1 > cl ) trim1 = cl;
1920       if ( trim2 < cf ) trim2 = cf;
1921       else if ( trim2 > cl ) trim2 = cl;
1922     }
1923     if (Abs(trim1 - trim2) < Precision::PConfusion()) {
1924       if (theCurve->IsPeriodic()) {
1925         ElCLib::AdjustPeriodic(cf,cl,Precision::PConfusion(),trim1,trim2);
1926       }
1927       else if (theCurve->IsClosed()) {
1928         if (Abs(trim1 - cf) < Precision::PConfusion()) {
1929           trim2 += cl;
1930         }
1931         else {
1932           trim1 -= cl;
1933         }
1934       }
1935       else {
1936         return 0;
1937       }
1938     }
1939 //  CKY 16-DEC-1997 : USA60035 le texte de Part42 parle de degres
1940 //    mais des systemes ecrivent en radians. Exploiter UnitsMethods
1941 //:o6    trim1 = trim1 * fact;
1942 //:o6    trim2 = trim2 * fact;
1943     if ( SC->SenseAgreement() )
1944       return new Geom_TrimmedCurve(theCurve, trim1, trim2, Standard_True);
1945     else //:abv 29.09.00 PRO20362: reverse parameters in case of reversed curve
1946       return new Geom_TrimmedCurve(theCurve, trim2, trim1, Standard_False);
1947   }
1948   return 0;
1949 }
1950
1951 //=============================================================================
1952 // Creation d'une Trimmed Curve de Geom2d a partir d' une Trimmed Curve de Step
1953 //=============================================================================
1954 // Shall be completed to treat trimming with points
1955
1956 Handle(Geom2d_BSplineCurve) StepToGeom::MakeTrimmedCurve2d (const Handle(StepGeom_TrimmedCurve)& SC)
1957 {
1958   const Handle(StepGeom_Curve) BasisCurve = SC->BasisCurve();
1959   Handle(Geom2d_Curve) theGeomBasis = MakeCurve2d (BasisCurve);
1960   if (theGeomBasis.IsNull())
1961     return Handle(Geom2d_BSplineCurve)();
1962
1963   if (theGeomBasis->IsKind(STANDARD_TYPE(Geom2d_BSplineCurve))) {
1964     return Handle(Geom2d_BSplineCurve)::DownCast(theGeomBasis);
1965   }
1966
1967   const Handle(StepGeom_HArray1OfTrimmingSelect)& theTrimSel1 = SC->Trim1();
1968   const Handle(StepGeom_HArray1OfTrimmingSelect)& theTrimSel2 = SC->Trim2();
1969   const Standard_Integer nbSel1 = SC->NbTrim1();
1970   const Standard_Integer nbSel2 = SC->NbTrim2();
1971   if ((nbSel1 == 1) && (nbSel2 == 1) &&
1972       (theTrimSel1->Value(1).CaseMember() > 0) &&
1973       (theTrimSel2->Value(1).CaseMember() > 0))
1974   {
1975     const Standard_Real u1 = theTrimSel1->Value(1).ParameterValue();
1976     const Standard_Real u2 = theTrimSel2->Value(1).ParameterValue();
1977     Standard_Real fact = 1., shift = 0.;
1978
1979     if (BasisCurve->IsKind(STANDARD_TYPE(StepGeom_Line))) {
1980       const Handle(StepGeom_Line) theLine = Handle(StepGeom_Line)::DownCast(BasisCurve);
1981       fact = theLine->Dir()->Magnitude();
1982     }
1983     else if (BasisCurve->IsKind(STANDARD_TYPE(StepGeom_Circle)) ||
1984              BasisCurve->IsKind(STANDARD_TYPE(StepGeom_Ellipse))) {
1985 //      if (u1 > 2.1*M_PI || u2 > 2.1*M_PI) fact = M_PI / 180.;
1986       fact = UnitsMethods::PlaneAngleFactor();
1987       //:p3 abv 23 Feb 99: shift on pi/2 on ellipse with R1 < R2
1988       const Handle(StepGeom_Ellipse) ellipse = Handle(StepGeom_Ellipse)::DownCast(BasisCurve);
1989       if ( !ellipse.IsNull() && ellipse->SemiAxis1() - ellipse->SemiAxis2() < 0. )
1990         shift = 0.5 * M_PI;
1991     }
1992     else if (BasisCurve->IsKind(STANDARD_TYPE(StepGeom_Parabola)) ||
1993              BasisCurve->IsKind(STANDARD_TYPE(StepGeom_Hyperbola))) {
1994       // LATER !!!
1995     }
1996 //    CKY 16-DEC-1997 : USA60035 le texte de Part42 parle de degres
1997 //      mais des systemes ecrivent en radians. Exploiter UnitsMethods
1998
1999     const Standard_Real newU1 = shift + u1 * fact;
2000     const Standard_Real newU2 = shift + u2 * fact;
2001
2002     const Handle(Geom2d_TrimmedCurve) theTrimmed =
2003       new Geom2d_TrimmedCurve(theGeomBasis, newU1, newU2, SC->SenseAgreement());
2004     return Geom2dConvert::CurveToBSplineCurve(theTrimmed);
2005   }
2006   return 0;
2007 }
2008
2009 //=============================================================================
2010 // Creation d' un VectorWithMagnitude de Geom a partir d' un Vector de Step
2011 //=============================================================================
2012
2013 Handle(Geom_VectorWithMagnitude) StepToGeom::MakeVectorWithMagnitude (const Handle(StepGeom_Vector)& SV)
2014 {
2015   // sln 22.10.2001. CTS23496: Vector is not created if direction have not been succesfully created
2016   Handle(Geom_Direction) D = MakeDirection (SV->Orientation());
2017   if (! D.IsNull())
2018   {
2019     const gp_Vec V(D->Dir().XYZ() * SV->Magnitude() * UnitsMethods::LengthFactor());
2020     return new Geom_VectorWithMagnitude(V);
2021   }
2022   return 0;
2023 }
2024
2025 //=============================================================================
2026 // Creation d' un VectorWithMagnitude de Geom2d a partir d' un Vector de Step
2027 //=============================================================================
2028
2029 Handle(Geom2d_VectorWithMagnitude) StepToGeom::MakeVectorWithMagnitude2d (const Handle(StepGeom_Vector)& SV)
2030 {
2031   // sln 23.10.2001. CTS23496: Vector is not created if direction have not been succesfully created (MakeVectorWithMagnitude2d(...) function)
2032   Handle(Geom2d_Direction) D = MakeDirection2d (SV->Orientation());
2033   if (! D.IsNull())
2034   {
2035     const gp_Vec2d V(D->Dir2d().XY() * SV->Magnitude());
2036     return new Geom2d_VectorWithMagnitude(V);
2037   }
2038   return 0;
2039 }