0026377: Passing Handle objects as arguments to functions as non-const reference...
[occt.git] / src / IGESToBRep / IGESToBRep_BasicCurve.cxx
1 // Copyright (c) 1999-2014 OPEN CASCADE SAS
2 //
3 // This file is part of Open CASCADE Technology software library.
4 //
5 // This library is free software; you can redistribute it and/or modify it under
6 // the terms of the GNU Lesser General Public License version 2.1 as published
7 // by the Free Software Foundation, with special exception defined in the file
8 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
9 // distribution for complete text of the license and disclaimer of any warranty.
10 //
11 // Alternatively, this file may be used under the terms of Open CASCADE
12 // commercial license or contractual agreement.
13
14 //=======================================================================
15 //modified: 
16 // 21.02.2002 skl
17 // 21.12.98 rln, gka S4054
18 //:k5 abv 25 Dec 98: PRO8803 1901: extending method of fixing Multi > Degree
19 // 28.12.98 dce S3767 New messaging system
20 //#61 rln 05.01.99
21 //#60 rln 29.12.98 PRO17015
22 //:l3 abv 11.01.99: CATIA01.igs: using less values for checking short lines
23 //%11 pdn 12.01.98 CTS22023 correcting used tolerances
24 //sln 29.12.2001 OCC90 : Method checkBSplineCurve and varification before creation of bspline curves were added
25 //=======================================================================
26
27 #include <ElCLib.hxx>
28 #include <Geom2d_BSplineCurve.hxx>
29 #include <Geom2d_Circle.hxx>
30 #include <Geom2d_Curve.hxx>
31 #include <Geom2d_Ellipse.hxx>
32 #include <Geom2d_Hyperbola.hxx>
33 #include <Geom2d_Line.hxx>
34 #include <Geom2d_Parabola.hxx>
35 #include <Geom2d_TrimmedCurve.hxx>
36 #include <Geom_BSplineCurve.hxx>
37 #include <Geom_Circle.hxx>
38 #include <Geom_Curve.hxx>
39 #include <Geom_Ellipse.hxx>
40 #include <Geom_Hyperbola.hxx>
41 #include <Geom_Line.hxx>
42 #include <Geom_Parabola.hxx>
43 #include <Geom_Transformation.hxx>
44 #include <Geom_TrimmedCurve.hxx>
45 #include <gp_Ax2.hxx>
46 #include <gp_Ax2d.hxx>
47 #include <gp_Dir.hxx>
48 #include <gp_Dir2d.hxx>
49 #include <gp_GTrsf.hxx>
50 #include <gp_Hypr.hxx>
51 #include <gp_Pnt.hxx>
52 #include <gp_Pnt2d.hxx>
53 #include <gp_Trsf.hxx>
54 #include <gp_XY.hxx>
55 #include <gp_XYZ.hxx>
56 #include <IGESConvGeom.hxx>
57 #include <IGESData_IGESEntity.hxx>
58 #include <IGESData_ToolLocation.hxx>
59 #include <IGESGeom_BSplineCurve.hxx>
60 #include <IGESGeom_CircularArc.hxx>
61 #include <IGESGeom_ConicArc.hxx>
62 #include <IGESGeom_CopiousData.hxx>
63 #include <IGESGeom_Line.hxx>
64 #include <IGESGeom_Point.hxx>
65 #include <IGESGeom_SplineCurve.hxx>
66 #include <IGESGeom_TransformationMatrix.hxx>
67 #include <IGESToBRep.hxx>
68 #include <IGESToBRep_BasicCurve.hxx>
69 #include <IGESToBRep_CurveAndSurface.hxx>
70 #include <Interface_Macros.hxx>
71 #include <Message_Msg.hxx>
72 #include <Precision.hxx>
73 #include <ShapeConstruct_Curve.hxx>
74 #include <Standard_ErrorHandler.hxx>
75 #include <Standard_Failure.hxx>
76 #include <TColGeom_SequenceOfCurve.hxx>
77 #include <TColgp_Array1OfPnt2d.hxx>
78 #include <TColgp_HArray1OfPnt.hxx>
79 #include <TColgp_HArray1OfPnt2d.hxx>
80 #include <TColgp_HArray2OfPnt.hxx>
81 #include <TColStd_Array1OfInteger.hxx>
82 #include <TColStd_Array1OfReal.hxx>
83 #include <TColStd_HArray1OfInteger.hxx>
84 #include <TColStd_HArray1OfReal.hxx>
85 #include <TColStd_SequenceOfInteger.hxx>
86
87 //:36
88 // S3767
89 //=======================================================================
90 //function : CheckBSplineCurve
91 //purpose  : Check coincidede knots Check whether knots are in ascending 
92 //           order and difference between vaues of weights more than 1000. 
93 //           Send corresponding messages. The function returns Standard_False 
94 //           if curve can not be created, Standard_True otherwise.
95 //=======================================================================
96 static Standard_Boolean checkBSplineCurve(IGESToBRep_BasicCurve*               theCurve,
97                                           const Handle(IGESGeom_BSplineCurve)& theBSplineCurve,
98                                           TColStd_Array1OfReal&                CKnots,
99                                           const TColStd_Array1OfReal&          CWeights)
100 {
101   // check whether difference between vaues of weights more than 1000.
102   if(!theBSplineCurve->IsPolynomial()) {
103     Standard_Real aMinValue = CWeights.Value(CWeights.Lower());
104     Standard_Real aMaxValue = CWeights.Value(CWeights.Lower());
105     for(Standard_Integer i = CWeights.Lower()+1; i<= CWeights.Upper(); i++) {
106       if(CWeights.Value(i) < aMinValue) aMinValue = CWeights.Value(i);
107       if(CWeights.Value(i) > aMaxValue) aMaxValue = CWeights.Value(i);    
108     }
109     if(aMaxValue - aMinValue > 1000) {
110       Message_Msg msg1374("IGES_1374"); // WARNING - Difference between weights is too big.
111       theCurve->SendWarning(theBSplineCurve, msg1374);
112     }
113   }
114  
115   Standard_Boolean aResult = Standard_True;
116   
117   //check whether knots are in ascending order.
118   for (Standard_Integer i = CKnots.Lower(); i < CKnots.Upper(); i++) 
119     if(CKnots.Value (i+1) < CKnots.Value (i)) { 
120       Message_Msg msg1373("IGES_1373"); // FAIL - Knots are not in ascending order 
121       theCurve->SendFail(theBSplineCurve, msg1373);
122       aResult = Standard_False;
123     }
124   //Fix coincided knots
125   if(aResult) ShapeConstruct_Curve::FixKnots(CKnots);
126   
127   return aResult;
128
129 }
130
131
132
133 //=======================================================================
134 //function : IGESToBRep_BasicCurve
135 //purpose  : 
136 //=======================================================================
137 IGESToBRep_BasicCurve::IGESToBRep_BasicCurve()
138      :IGESToBRep_CurveAndSurface()
139 {  
140   SetModeTransfer(Standard_False);
141 }
142
143
144 //=======================================================================
145 //function : IGESToBRep_BasicCurve
146 //purpose  : 
147 //=======================================================================
148 IGESToBRep_BasicCurve::IGESToBRep_BasicCurve
149   (const IGESToBRep_CurveAndSurface& CS)
150      :IGESToBRep_CurveAndSurface(CS)
151 {  
152 }
153
154
155 //=======================================================================
156 //function : IGESToBRep_BasicCurve
157 //purpose  : 
158 //=======================================================================
159 IGESToBRep_BasicCurve::IGESToBRep_BasicCurve
160   (const Standard_Real    eps,
161    const Standard_Real    epsCoeff,
162    const Standard_Real    epsGeom,
163    const Standard_Boolean mode,
164    const Standard_Boolean modeapprox,
165    const Standard_Boolean optimized)
166      :IGESToBRep_CurveAndSurface(eps, epsCoeff, epsGeom, mode, 
167                                  modeapprox,optimized)
168 {  
169 }
170
171
172 //=======================================================================
173 //function : TransferBasicCurve
174 //purpose  : 
175 //=======================================================================
176
177 Handle(Geom_Curve) IGESToBRep_BasicCurve::TransferBasicCurve
178        (const Handle(IGESData_IGESEntity)& start)
179
180   Handle(Geom_Curve) res;
181   if (start.IsNull()) {
182     Message_Msg msg1005("IGES_1005");
183     SendFail(start, msg1005);
184     return res;
185   }
186   try { //:36 by abv 11.12.97: Geom_BSplineCurve fails if somw weights are <=0
187     OCC_CATCH_SIGNALS
188     //S4054
189     if (start->IsKind(STANDARD_TYPE(IGESGeom_BSplineCurve))) {
190       DeclareAndCast(IGESGeom_BSplineCurve, st126, start);
191       res = TransferBSplineCurve(st126);
192     }
193     else if (start->IsKind(STANDARD_TYPE(IGESGeom_Line))) {
194       DeclareAndCast(IGESGeom_Line, st110, start);
195       res = TransferLine(st110);
196     }
197     else if (start->IsKind(STANDARD_TYPE(IGESGeom_CircularArc))) {
198       DeclareAndCast(IGESGeom_CircularArc, st100, start);
199       res = TransferCircularArc(st100);
200     }
201     else if (start->IsKind(STANDARD_TYPE(IGESGeom_ConicArc))) {
202       DeclareAndCast(IGESGeom_ConicArc, st104, start);
203       res = TransferConicArc(st104);
204     }
205     else if (start->IsKind(STANDARD_TYPE(IGESGeom_CopiousData))) {
206       DeclareAndCast(IGESGeom_CopiousData, st106, start);
207       res = TransferCopiousData(st106);
208     }
209     else if (start->IsKind(STANDARD_TYPE(IGESGeom_SplineCurve))) {
210       DeclareAndCast(IGESGeom_SplineCurve, st112, start);
211       res = TransferSplineCurve(st112);
212     }
213     else {
214       // AddFail(start, "The IGESEntity is not a basic curve.");
215       // This case can not occur
216       return res;
217     }
218
219   } //:36
220   catch(Standard_Failure) {
221 #ifdef OCCT_DEBUG
222     cout << "\n** Exception in IGESToBRep_BasicCurve::TransferBasicCurve : "; 
223     Standard_Failure::Caught()->Print(cout);
224 #endif
225   }
226   if (res.IsNull()) {
227     // AddFail(start, "The IGESEntity cannot be transfered.");
228     // The more specific function have ever add a fail message for this entity
229   }
230   else
231     res->Scale(gp_Pnt(0,0,0),GetUnitFactor());
232   return res;
233 }
234
235 //=======================================================================
236 //function : Transfer2dBasicCurve
237 //purpose  : 
238 //=======================================================================
239
240 Handle(Geom2d_Curve) IGESToBRep_BasicCurve::Transfer2dBasicCurve
241        (const Handle(IGESData_IGESEntity)& start)
242
243   Handle(Geom2d_Curve) res;
244   if (start.IsNull()) {
245     Message_Msg msg1005("IGES_1005");
246     SendFail(start, msg1005);
247     return res;
248   }
249   try { //:h8 abv 15 Jul 98: BUC60291 43693: Bspline Multiplicity > Degree+1 -> exception
250     OCC_CATCH_SIGNALS
251     
252     //S4054
253     if (start->IsKind(STANDARD_TYPE(IGESGeom_BSplineCurve))) {
254       DeclareAndCast(IGESGeom_BSplineCurve, st126, start);
255       res = Transfer2dBSplineCurve(st126);
256     }
257     else if (start->IsKind(STANDARD_TYPE(IGESGeom_Line))) {
258       DeclareAndCast(IGESGeom_Line, st110, start);
259       res = Transfer2dLine(st110);
260     }
261     else if (start->IsKind(STANDARD_TYPE(IGESGeom_CircularArc))) {
262       DeclareAndCast(IGESGeom_CircularArc, st100, start);
263       res = Transfer2dCircularArc(st100);
264     }
265     else if (start->IsKind(STANDARD_TYPE(IGESGeom_ConicArc))) {
266       DeclareAndCast(IGESGeom_ConicArc, st104, start);
267       res = Transfer2dConicArc(st104);
268     }
269     else if (start->IsKind(STANDARD_TYPE(IGESGeom_CopiousData))) {
270       DeclareAndCast(IGESGeom_CopiousData, st106, start);
271       res = Transfer2dCopiousData(st106);
272     }
273     else if (start->IsKind(STANDARD_TYPE(IGESGeom_SplineCurve))) {
274       DeclareAndCast(IGESGeom_SplineCurve, st112, start);
275       res = Transfer2dSplineCurve(st112);
276     }
277      else {
278       // AddFail(start, "The IGESEntity is not a basic curve.");
279       // This case can not occur
280       return res;
281     }
282   } //:h8
283   catch(Standard_Failure) {
284 #ifdef OCCT_DEBUG
285     cout << "\n** Exception in IGESToBRep_BasicCurve::Transfer2dBasicCurve : "; 
286     Standard_Failure::Caught()->Print(cout);
287 #endif
288   }
289   return res;
290 }
291
292
293
294 //=======================================================================
295 //function : TransferConicArc
296 //purpose  : 
297 //=======================================================================
298 //
299 // A,B,C,D,E,F are the coefficients recorded in IGES. a,b,c,d,e,f are used to 
300 // simplify the equations of convertion. They are already used in Euclid. 
301
302 Handle(Geom_Curve) IGESToBRep_BasicCurve::TransferConicArc
303        (const Handle(IGESGeom_ConicArc)& st)
304
305   Handle(Geom_Curve) res;
306   if (st.IsNull()) {
307     Message_Msg msg1005("IGES_1005");
308     SendFail(st, msg1005);
309     return res;
310   }
311   // If the Conic is closed, the start and end points will be ignored.
312   if (!st->ComputedFormNumber()) {
313     Message_Msg msg1155("IGES_1155");
314     SendFail(st, msg1155);
315 //    AddFail(st, "Coefficients do not define correctly a conic.");
316     return res;
317   }
318   
319   // Conic = ax2+bxy+cy2+dx+ey+f=0 in the plane z=ZT.
320   Standard_Real a,b,c,d,e,f,ZT; 
321   st->Equation(a, b, c, d, e, f);
322
323   ZT = st->ZPlane();
324
325   gp_Pnt        center, startPoint, endPoint;
326   gp_Dir        mainAxis ,normAxis;
327   Standard_Real minorRadius, majorRadius;
328   
329   if (!GetModeTransfer() && st->HasTransf()) {
330
331     st->TransformedDefinition(center ,mainAxis, minorRadius, majorRadius);
332     normAxis = st->TransformedAxis();                            
333
334     startPoint = st->TransformedStartPoint();
335     endPoint   = st->TransformedEndPoint();
336   }
337   else {
338     st->Definition(center ,mainAxis, minorRadius, majorRadius);
339     normAxis = st->Axis();                            
340
341     startPoint.SetCoord(st->StartPoint().X(), st->StartPoint().Y(), ZT);
342     endPoint.SetCoord  (st->EndPoint().X()  , st->EndPoint().Y()  , ZT);
343   }
344   gp_Ax2 frame(center, normAxis, mainAxis);
345   Standard_Real t1 =0.0, t2 =0.0;
346   if (st->IsFromEllipse()) {
347
348     //#60 rln 29.12.98 PRO17015 reading back face#67: ellipse with big radii produces
349     //small coefficients
350     //The dimensions should be also obliged:
351     //[a]=[b]=[c]=L^-2
352     //if ( (Abs(a-c) <= GetEpsGeom()) && (Abs(b) < GetEpsCoeff()))
353     Standard_Real eps2 = Precision::PConfusion() * Precision::PConfusion();
354     if ( (Abs(a-c) <= eps2) && (Abs(b) < eps2)) {
355     
356 //                          =================
357 //                          ==  Circle 3D  ==
358 //                          =================
359
360       res = new Geom_Circle(frame, minorRadius);
361       
362       if (!st->IsClosed()) {
363
364         gp_Circ circ(frame, minorRadius);
365
366         t1 = ElCLib::Parameter(circ, startPoint);
367         t2 = ElCLib::Parameter(circ, endPoint);
368         if (t1 > t2 && (t1 - t2) > Precision::Confusion()) t2 += 2.*M_PI;
369         if (Abs(t1 - t2) <= Precision::Confusion())  { // t1 = t2
370           Message_Msg msg1160("IGES_1160");
371           SendWarning(st, msg1160);      
372         }
373         else
374           res = new Geom_TrimmedCurve(res, t1, t2);
375       }
376       return res;
377     }
378     else { 
379       // This is a no circular ellipse which will be computed with 
380       // the hyperbola at the end of this member.
381     }
382   }
383   else if (st->IsFromParabola()) {
384     
385     //                         ===================
386     //                         ==  Parabola 3D  ==
387     //                         ===================
388     
389     Standard_Real focal = minorRadius;
390     // PTV 26.03.2002
391     focal = focal/2.;
392     gp_Parab parab(frame, focal);
393     
394     res = new Geom_Parabola(frame, focal);
395     
396     t1 = ElCLib::Parameter(parab, startPoint);
397     t2 = ElCLib::Parameter(parab, endPoint);
398     if (Abs(t1 - t2) <= Precision::Confusion()) { // t1 = t2
399       Message_Msg msg1160("IGES_1160");
400       SendWarning(st, msg1160);      
401       //AddWarning(st, "The trim of the parabola is not correct.");
402     }
403     else 
404       // if t1 > t2, the course of the curve is going to be reversed.
405       res = new Geom_TrimmedCurve(res, t1, t2);
406     
407     return res;
408   }
409   
410   // Same computing for the ellipse and the hyperbola.
411   
412   //              =============================================
413   //              ==  Hyperbola or a no circular Ellipse 3D. ==
414   //              =============================================
415   
416   
417   if (st->IsFromEllipse()) {
418     res = new Geom_Ellipse(frame, majorRadius, minorRadius);
419     
420     if (!st->IsClosed()) {
421       gp_Elips  elips(frame, majorRadius, minorRadius);
422       
423       t1 = ElCLib::Parameter(elips, startPoint);
424       t2 = ElCLib::Parameter(elips, endPoint);
425       if (t2 < t1 && (t1 -t2) > Precision::Confusion()) t2 += 2.*M_PI;
426       if (Abs(t1 - t2) <= Precision::Confusion()) { // t1 = t2   
427         Message_Msg msg1160("IGES_1160");
428         SendWarning(st, msg1160);  
429         //AddWarning(st, "The trim of the ellipse is not correct, the result will be a ellipse.");
430       }
431       else
432         res = new Geom_TrimmedCurve(res, t1, t2);
433     }
434   }
435   else {
436       
437     gp_Hypr hpr(frame, majorRadius, minorRadius);
438     
439     t1 = ElCLib::Parameter(hpr, startPoint);
440     t2 = ElCLib::Parameter(hpr, endPoint);
441       
442     res = new Geom_Hyperbola(frame, majorRadius, minorRadius);
443     
444     //pdn taking PConfusion for parameters.
445     if (Abs(t1 - t2) <= Precision::PConfusion()) { // t1 = t2   
446         Message_Msg msg1160("IGES_1160");
447         SendWarning(st, msg1160);  
448       }
449     else if (t1 > t2)
450       res = new Geom_TrimmedCurve(res, t2, t1); // inversion des parametres.
451     else
452       res = new Geom_TrimmedCurve(res, t1, t2); 
453   }
454
455   return res;
456 }
457
458
459 //=======================================================================
460 //function : Transfer2dConicArc
461 //purpose  : Transfer 2d of a ConicArc to be used as a boundary of a Face
462 //=======================================================================
463
464 Handle(Geom2d_Curve) IGESToBRep_BasicCurve::Transfer2dConicArc
465        (const Handle(IGESGeom_ConicArc)& st)
466
467   Handle(Geom2d_Curve) res;
468   if (st.IsNull()) {
469     Message_Msg msg1005("IGES_1005");
470     SendFail(st, msg1005);
471     return res;
472   }
473
474  if (!st->ComputedFormNumber()) {
475     Message_Msg msg1155("IGES_1155");
476     SendFail(st, msg1155);
477     return res;
478   }
479
480   Standard_Real a,b,c,d,e,f;                          
481   // Conic = ax2+bxy+cy2+dx+ey+f=0.
482   st->Equation(a, b, c, d, e, f);
483
484   gp_Pnt        center3d;
485   gp_Dir        mainAxis3d;
486   gp_Pnt2d      startPoint, endPoint;
487   Standard_Real minorRadius, majorRadius;
488   
489   SetEpsilon(1.E-03);
490   if (!st->TransformedAxis().IsParallel /*#45 rln 23.11.98 IsEqual*/(st->Axis(), GetEpsilon())) {
491     SetModeTransfer(Standard_True); 
492     // Only not to use Trsf.
493     // the normal axis is not parallel with Z axis.
494     SendWarning(st, "The Trsf is not compatible with a transfer2d, it will not applied.");
495   } 
496
497   if (!GetModeTransfer() && st->HasTransf()) {
498
499     st->TransformedDefinition(center3d, 
500                               mainAxis3d, 
501                               minorRadius, 
502                               majorRadius);
503     startPoint.SetCoord(st->TransformedStartPoint().X(),
504                         st->TransformedStartPoint().Y());
505     endPoint.SetCoord(st->TransformedEndPoint().X(),
506                       st->TransformedEndPoint().Y());
507   }
508   else {
509     st->Definition(center3d, mainAxis3d, minorRadius, majorRadius);
510     startPoint = st->StartPoint();
511     endPoint   = st->EndPoint();
512   }
513   
514   gp_Pnt2d center(center3d.X(), center3d.Y());
515   gp_Dir2d mainAxis(mainAxis3d.X(), mainAxis3d.Y());
516   gp_Ax2d  frame(center, mainAxis);
517   Standard_Real t1 =0.0, t2=0.0;
518   if (st->IsFromEllipse()) {
519
520     //#60 rln 29.12.98 PRO17015
521     //if ( (Abs(a-c) <= GetEpsGeom()) && (Abs(b) < GetEpsCoeff()))
522     Standard_Real eps2 = Precision::PConfusion() * Precision::PConfusion();
523     if ( (Abs(a-c) <= eps2) && (Abs(b) < eps2)) {
524
525       //                          =================
526       //                          ==  Circle 2D  ==
527       //                          =================
528       
529       res = new Geom2d_Circle(frame, minorRadius);
530       //#45 rln 23.11.98
531       if (st->TransformedAxis().IsOpposite (st->Axis(), GetEpsilon()))
532         res->Reverse();
533       
534       if (!st->IsClosed()) {
535
536         gp_Circ2d circ = Handle(Geom2d_Circle)::DownCast(res)->Circ2d();//#45 rln (frame, minorRadius);
537         
538         t1 = ElCLib::Parameter(circ, startPoint);
539         t2 = ElCLib::Parameter(circ, endPoint);
540         
541         if (t2 < t1 && (t1 -t2) > Precision::PConfusion()) t2 += 2.*M_PI;
542         if (Abs(t1 - t2) <= Precision::PConfusion()) { // t1 = t2
543           Message_Msg msg1160("IGES_1160");
544           SendWarning(st, msg1160); 
545         }
546         else 
547           res = new Geom2d_TrimmedCurve(res, t1, t2);
548       }
549       return res; 
550     }
551     else { 
552       // This is a no circular ellipse, it will be computed with the hyperbola.
553     }
554   }  
555   else if (st->IsFromParabola()) {
556     
557     //                         ===================
558     //                         ==  Parabola 2D  ==
559     //                         ===================
560     
561     Standard_Real focal = minorRadius;
562     // PTV 26.03.2002
563     focal = focal/2.;
564     res = new Geom2d_Parabola(frame, focal);
565     //#45 rln 23.11.98
566     if (st->TransformedAxis().IsOpposite (st->Axis(), GetEpsilon()))
567       res->Reverse();
568     
569     gp_Parab2d parab = Handle(Geom2d_Parabola)::DownCast(res)->Parab2d();//#45 rln (frame, focal);
570     
571     t1  = ElCLib::Parameter(parab, startPoint);
572     t2  = ElCLib::Parameter(parab, endPoint);
573     if (Abs(t1 - t2) <= Precision::PConfusion())  { // t1 = t2   
574         Message_Msg msg1160("IGES_1160");
575         SendWarning(st, msg1160);  
576       }  
577     else if (t1 > t2)
578       res = new Geom2d_TrimmedCurve(res, t2, t1); // inversion des parametres.
579     else 
580       res = new Geom2d_TrimmedCurve(res, t1, t2);
581     return res;                      
582   }
583     
584   /* Same computing for the ellipse2d and the hyperbola2d. */
585   
586   //              ============================================
587   //              ==  Hyperbola or a no circular Ellipse 2D ==
588   //              ============================================
589     
590   if (st->IsFromEllipse()) {
591
592     res = new Geom2d_Ellipse(frame, majorRadius, minorRadius);
593     //#45 rln 23.11.98
594     if (st->TransformedAxis().IsOpposite (st->Axis(), GetEpsilon()))
595       res->Reverse();
596
597     if (!st->IsClosed()) {
598
599       gp_Elips2d elips = Handle(Geom2d_Ellipse)::DownCast(res)->Elips2d();//#45 rln (frame, majorRadius, minorRadius);
600       
601       t1  = ElCLib::Parameter(elips, startPoint);
602       t2  = ElCLib::Parameter(elips, endPoint);
603       if (t2 < t1 && (t1 - t2) > Precision::PConfusion()) t2 += 2.*M_PI;
604       if (Abs(t1 - t2) <= Precision::PConfusion())  { // t1 = t2   
605         Message_Msg msg1160("IGES_1160");
606         SendWarning(st, msg1160);  
607       }
608       else   
609         res = new Geom2d_TrimmedCurve(res, t1, t2);
610     }
611   }
612   else {
613
614     res = new Geom2d_Hyperbola(frame, majorRadius, minorRadius);
615     //#45 rln 23.11.98
616     if (st->TransformedAxis().IsOpposite (st->Axis(), GetEpsilon()))
617       res->Reverse();
618
619     gp_Hypr2d hpr = Handle(Geom2d_Hyperbola)::DownCast(res)->Hypr2d();//#45 rln (frame, majorRadius, minorRadius);
620    
621     t1 = ElCLib::Parameter(hpr, startPoint);
622     t2 = ElCLib::Parameter(hpr, endPoint);
623     
624     if (Abs(t1 - t2) <= Precision::PConfusion())   { // t1 = t2   
625         Message_Msg msg1160("IGES_1160");
626         SendWarning(st, msg1160);  
627       }
628     else if (t1 > t2)
629       res = new Geom2d_TrimmedCurve(res, t2, t1); // inversion des parametres.
630     else   
631       res = new Geom2d_TrimmedCurve(res, t1, t2);
632   }
633
634   return res;
635 }
636
637
638 //=======================================================================
639 //function : TransferCircularArc
640 //purpose  : 
641 //=======================================================================
642
643 Handle(Geom_Curve) IGESToBRep_BasicCurve::TransferCircularArc
644        (const Handle(IGESGeom_CircularArc)& st)
645
646   Handle(Geom_Curve) res;
647   if (st.IsNull()) {
648     Message_Msg msg1005("IGES_1005");
649     SendFail(st,msg1005);
650     return res;
651   }
652
653   gp_Dir tNormAxis, tMainAxis;
654   gp_Ax2 frame;
655   gp_Pnt startPoint, endPoint;
656
657   if (!GetModeTransfer() && st->HasTransf()) {
658
659     tNormAxis = st->TransformedAxis();
660
661     gp_GTrsf loc = st->Location();
662     loc.SetTranslationPart (gp_XYZ(0.,0.,0.));
663     gp_XYZ mainAxis(1., 0., 0.); 
664     loc.Transforms(mainAxis);
665     tMainAxis = gp_Dir(mainAxis);
666
667     startPoint = st->TransformedStartPoint();
668     endPoint   = st->TransformedEndPoint();
669     
670     frame = gp_Ax2(st->TransformedCenter(), tNormAxis, tMainAxis);
671   }
672   else {
673     tNormAxis  = st->Axis();
674     tMainAxis.SetCoord(1., 0., 0.);
675
676     Standard_Real ZT    = st->ZPlane();
677     startPoint.SetCoord(st->StartPoint().X(), st->StartPoint().Y(), ZT);
678     endPoint.SetCoord  (st->EndPoint().X()  , st->EndPoint().Y()  , ZT);
679     gp_Pnt centerPoint (st->Center().X()    , st->Center().Y()    , ZT);
680
681     frame = gp_Ax2(centerPoint, tNormAxis, tMainAxis);
682   }
683   
684   res = new Geom_Circle(frame, st->Radius());
685   
686   gp_Circ   circ(frame, st->Radius());
687   
688   Standard_Real t1 =0.0, t2 =0.0;
689  
690   t1 = ElCLib::Parameter(circ, startPoint);
691   t2 = ElCLib::Parameter(circ, endPoint);
692
693   if ( st->IsClosed() && t1>=GetEpsGeom()) t2 = t1 + 2.*M_PI;
694   if (!st->IsClosed() && fabs(t1 - t2) <=Precision::PConfusion()) {    
695     // micro-arc
696     // cky 27 Aout 1996 : t2-t1 vaut distance(start,end)/rayon
697     t2 = t1 + startPoint.Distance(endPoint)/st->Radius();
698   }
699   if (!st->IsClosed() || t1>=GetEpsGeom()) {
700     if (t2 < t1) t2 += 2.*M_PI;
701     res = new Geom_TrimmedCurve(res, t1, t2);
702   }
703
704   return res;      
705 }
706
707 //=======================================================================
708 //function : Transfer2dCircularArc
709 //purpose  : 
710 //=======================================================================
711
712 Handle(Geom2d_Curve) IGESToBRep_BasicCurve::Transfer2dCircularArc
713        (const Handle(IGESGeom_CircularArc)& st) 
714
715   Handle(Geom2d_Curve) res;     
716   if (st.IsNull()) {
717     Message_Msg msg1005("IGES_1005");
718     SendFail(st,msg1005);
719     return res;
720   }
721
722   gp_XYZ center(st->Center().X(), st->Center().Y(), 0.);
723   gp_XYZ mainAxis(1., 0., 0.); 
724
725   SetEpsilon(1.E-03);
726   if (!st->TransformedAxis().IsParallel /*#45 rln 23.11.98 IsEqual*/(st->Axis(), GetEpsilon())) {
727     SetModeTransfer(Standard_True);          // Only not to use Trsf
728     Message_Msg msg1165("IGES_1165");
729     SendWarning(st, msg1165); //"The Trsf is not compatible with a transfer2d, it will not applied."
730   }
731
732   if (!GetModeTransfer() && st->HasTransf()) {
733     gp_GTrsf loc = st->Location();
734     loc.Transforms(center);
735     loc.SetTranslationPart (gp_XYZ(0.,0.,0.));
736     loc.Transforms(mainAxis);
737   }
738   gp_Pnt2d tCenter(center.X(), center.Y());
739   gp_Dir2d tMainAxis(mainAxis.X(), mainAxis.Y());
740   gp_Ax2d  frame(tCenter, tMainAxis);
741   
742   res = new Geom2d_Circle(frame, st->Radius());
743   
744   gp_Pnt2d startPoint, endPoint;
745    if (!GetModeTransfer() && st->HasTransf()) {
746     startPoint.SetCoord(st->TransformedStartPoint().X(),
747                         st->TransformedStartPoint().Y());
748     endPoint.SetCoord(st->TransformedEndPoint().X(),
749                       st->TransformedEndPoint().Y());
750     //#45 rln 23.11.98
751     if (st->TransformedAxis().IsOpposite (st->Axis(), GetEpsilon()))
752       res->Reverse();
753   }
754   else {
755     startPoint = st->StartPoint();
756     endPoint   = st->EndPoint();
757   }
758
759   gp_Circ2d circ = Handle(Geom2d_Circle)::DownCast(res)->Circ2d();//#45 rln (frame, st->Radius());
760   
761   Standard_Real t1 =0.0, t2 =0.0;
762   
763   t1 = ElCLib::Parameter(circ, startPoint);
764   t2 = ElCLib::Parameter(circ, endPoint);
765     
766   if ( st->IsClosed() && t1>=GetEpsGeom()) t2 = t1 + 2.*M_PI;
767   if (!st->IsClosed() && fabs(t1 -t2) <= Precision::PConfusion()) { 
768     // micro-arc
769     // cky 27 Aout 1996 : t2-t1 vaut distance(start,end)/rayon
770     t2 = t1 + startPoint.Distance(endPoint)/st->Radius();
771   }
772   if (!st->IsClosed() || t1>= GetEpsGeom()) {
773     if (t2 < t1) t2 += 2.*M_PI;
774     res     = new Geom2d_TrimmedCurve(res, t1, t2);
775   }
776   return res;
777 }
778
779
780
781 //=======================================================================
782 //function : TransferSplineCurve
783 //purpose  : 
784 //=======================================================================
785
786 Handle(Geom_BSplineCurve) IGESToBRep_BasicCurve::TransferSplineCurve
787        (const Handle(IGESGeom_SplineCurve)& st)
788
789   Handle(Geom_BSplineCurve) resconv;
790   if (st.IsNull()) {
791     Message_Msg msg1005("IGES_1005");
792     SendFail(st,msg1005);
793     return resconv;
794   }
795   
796   Standard_Real epscoef = GetEpsCoeff();
797   Standard_Real epsgeom = GetEpsGeom();
798
799   Standard_Integer result = IGESConvGeom::SplineCurveFromIGES(st, epscoef, epsgeom, resconv);
800   
801   switch (result) {
802   case 5 : {
803     Message_Msg msg246("XSTEP_246");
804     SendFail(st, msg246);
805     // less than on segment (no result produced)
806     return resconv;
807   }
808   case 4 : {
809     Message_Msg msg1170("IGES_1170");
810     SendFail(st, msg1170);
811     // Polynomial equation is not correct ( no result produced
812     return resconv;}
813   case 3 :{
814     Message_Msg msg1175("IGES_1175");
815     SendFail(st, msg1175);
816     // Error during creation of control points ( no result produced)
817     return resconv;}
818   case 2 :{
819     Message_Msg msg1180("IGES_1180");
820    SendFail(st, msg1180);
821     //SplineType not processed (allowed : max 3) (no result produced)
822     return resconv;}
823   default :
824     break;
825   }
826
827   //  Checking C2 and C1 continuity :
828   //  ===============================
829   IGESConvGeom::IncreaseCurveContinuity (resconv, Min(Precision::Confusion(),epsgeom), GetContinuity());
830   return resconv;
831 }
832
833
834
835 //=======================================================================
836 //function : Transfer2dSplineCurve
837 //purpose  : 
838 //=======================================================================
839
840 Handle(Geom2d_BSplineCurve) IGESToBRep_BasicCurve::Transfer2dSplineCurve
841        (const Handle(IGESGeom_SplineCurve)& st)
842
843   Handle(Geom2d_BSplineCurve) res;
844   if (st.IsNull()) {
845     Message_Msg msg1005("IGES_1005");
846     SendFail(st, msg1005);
847     return res;
848   }
849
850   // 3d transfer First 
851   // =================
852   // The same Presision as in BSpline 2d is used
853   Standard_Real epsGeom = GetEpsGeom();
854   SetEpsGeom(Precision::PConfusion());
855   Handle(Geom_BSplineCurve) res3d = TransferSplineCurve(st);
856   SetEpsGeom(epsGeom);
857   if (res3d.IsNull()) 
858     return res;        // The transfer was not over the top.
859
860  
861   // 2d 
862   // ==
863   Standard_Integer nbPoles = res3d->NbPoles();
864   Standard_Integer nbKnots = res3d->NbKnots();
865  
866   TColgp_Array1OfPnt2d    bspoles2d(1, nbPoles);
867   TColStd_Array1OfReal    knots(1, nbKnots);
868   TColStd_Array1OfInteger multi(1, nbKnots);
869
870   res3d->Knots(knots);
871   res3d->Multiplicities(multi);
872
873   for (Standard_Integer i = bspoles2d.Lower(); i <= bspoles2d.Upper(); i++) 
874     bspoles2d.SetValue(i, gp_Pnt2d(res3d->Pole(i).X(), res3d->Pole(i).Y()));
875   
876   res = new Geom2d_BSplineCurve (bspoles2d, knots, multi, res3d->Degree());
877   return res;
878 }
879
880 //=======================================================================
881 //function : TransferBSplineCurve
882 //purpose  : 
883 //=======================================================================
884
885 Handle(Geom_Curve) IGESToBRep_BasicCurve::TransferBSplineCurve
886        (const Handle(IGESGeom_BSplineCurve)&  start)
887      
888
889   Handle(Geom_BSplineCurve)  BSplineRes;
890   Handle(Geom_Curve) res;
891   
892   if (start.IsNull()) {
893     Message_Msg msg1005("IGES_1005");
894     SendFail(start,msg1005);
895     return res;
896   }
897
898   Standard_Integer  Degree = start->Degree();
899
900   if (Degree<=0 || Degree>Geom_BSplineCurve::MaxDegree()) { 
901     Message_Msg msg1190("IGES_1190");
902     SendFail(start, msg1190);
903     // Improper degree either lower or equal to 0 or upper to MaxDegree
904       return res;
905   }
906   
907   
908   //  Filling poles array :
909   //  =====================
910   
911   Standard_Integer  NbPoles = start->NbPoles();
912   Standard_Integer  newNbPoles = NbPoles;
913   
914   if (NbPoles<2) {
915     Message_Msg msg1195("IGES_1195");
916     SendFail(start, msg1195);
917     // Transfer aborted for a BSpline Curve : Number of poles lower than 2
918     return res;
919   }
920
921   TColgp_Array1OfPnt   Pole(1,NbPoles);
922   Standard_Integer     PoleIndex = Pole.Lower();
923   Standard_Integer     i; //szv#4:S4163:12Mar99 j unused
924
925   if (!GetModeTransfer() && start->HasTransf()) 
926     for (i=0; i<=start->UpperIndex(); i++) 
927       Pole.SetValue(PoleIndex++, start->TransformedPole(i));
928   else
929     for (i=0; i<=start->UpperIndex(); i++) 
930       Pole.SetValue(PoleIndex++, start->Pole(i));
931   
932   
933   //  Filling knots & multiplicities arraies :
934   //  ========================================
935   
936   Standard_Integer          NbKnots = start->NbKnots();
937   TColStd_Array1OfReal      TempKnot(1,NbKnots);
938   TColStd_Array1OfInteger   TempMult(1,NbKnots); 
939   TempMult.Init(1);
940   Standard_Integer          KnotIndex = TempKnot.Lower();
941
942   TempKnot.SetValue(KnotIndex, start->Knot(-Degree));
943   
944   //  If several identical IGES knots are encountered, corresponding 
945   //  multiplicity is increased
946   //  ==============================================================
947
948   for (i=1-Degree; i<NbKnots-Degree; i++) {
949
950     Standard_Real Knot1 = start->Knot(i);
951     Standard_Real Knot2 = start->Knot(i-1);
952 //    Standard_Real ek    =  Epsilon(Knot1);
953
954     if (Abs(Knot1 - Knot2) <= Epsilon(Knot1))
955       TempMult.SetValue(KnotIndex, TempMult.Value(KnotIndex)+1);
956     else 
957       TempKnot.SetValue(++KnotIndex, Knot1);
958   }
959   
960
961   //  Final knots & multiplicities arraies are dimensionned so as to be fully 
962   //  filled
963   //  =======================================================================
964   
965   TColStd_Array1OfReal        Knot(1,KnotIndex);
966   TColStd_Array1OfInteger     Mult(1,KnotIndex);
967
968   Standard_Integer SumOfMult=0;
969   
970   TColStd_SequenceOfInteger SeqIndex;
971   Standard_Integer DelIndex;
972   Standard_Integer OldSumOfMult = 0;
973   for (i=1; i <= KnotIndex; i++) { //:k5 abv 25 Dec 98: cycle modified
974     Standard_Integer aMult = TempMult.Value(i);
975     Standard_Integer maxMult = ( i==1 || i == KnotIndex ? Degree + 1 : Degree );
976     if (aMult > maxMult) {
977     Message_Msg msg1200("IGES_1200");//#61 rln 05.01.99
978     const Standard_CString vide ("");
979     msg1200.Arg(vide);
980     msg1200.Arg(vide);
981     msg1200.Arg(vide);
982     SendWarning(start, msg1200);//Multiplicity > Degree (or Degree+1 at end); corrected
983       for ( DelIndex = OldSumOfMult + 1; aMult > maxMult; DelIndex++, aMult-- ) {
984         newNbPoles--;
985         SeqIndex.Append(DelIndex);
986       }
987     }
988     OldSumOfMult += TempMult.Value(i); 
989     Knot.SetValue(i, TempKnot.Value(i));
990     Mult.SetValue(i, aMult);
991     SumOfMult += aMult;
992   }
993
994   // Mise a jour du tableau des poles lors de la correction de la multiplicite
995   TColgp_Array1OfPnt Poles(1,newNbPoles);
996   TColStd_SequenceOfInteger PoleInd;
997
998   if ( newNbPoles < NbPoles) {
999     for (i=1; i<=NbPoles; i++) PoleInd.Append(i);
1000     Standard_Integer Offset = 0;
1001     for (Standard_Integer itab = 1; itab <= SeqIndex.Length(); itab++) {
1002       DelIndex = SeqIndex.Value(itab) - Offset;
1003       PoleInd.Remove(DelIndex);
1004       Offset++;
1005     }
1006     Standard_Integer nbseq = PoleInd.Length();
1007     if ( nbseq == newNbPoles) {
1008       Standard_Integer indj = 1;
1009       for ( i=1; i<= newNbPoles; i++) {
1010         Poles.SetValue(i, Pole.Value(PoleInd.Value(indj++)));
1011       }
1012     }
1013   }
1014
1015   else {
1016     for ( i=1; i<= newNbPoles; i++) {
1017       Poles.SetValue (i, Pole.Value(i));
1018     }
1019   }
1020     
1021
1022   if (! (SumOfMult  ==  newNbPoles + Degree + 1)) {
1023     Message_Msg msg1210("IGES_1210");
1024     const Standard_CString vide ("");
1025     msg1210.Arg(vide);
1026     msg1210.Arg(vide);
1027     SendWarning(start, msg1210);
1028     //Sum of multiplicities not equal to the sum : Count of poles + Degree + 1
1029   }
1030   
1031   //  Output BSpline curve with the array of pole weights if any :
1032   //  ============================================================
1033   
1034   TColStd_Array1OfReal Weight(1,newNbPoles);
1035
1036   if (start->IsPolynomial()) {
1037 //:5    BSplineC = new Geom_BSplineCurve(Poles, Knot, Mult, Degree);  
1038   }
1039   else {
1040     TColStd_Array1OfReal  PoleWeight(1,NbPoles);
1041     Standard_Boolean      polynomial               = Standard_True;
1042     Standard_Real         WeightReference          = start->Weight(0);
1043     Standard_Integer      WeightIndex              = PoleWeight.Lower();
1044     
1045     for (i=0; i <= start->UpperIndex(); i++) {
1046       polynomial = Abs(start->Weight(i) - WeightReference) <= 
1047         Epsilon(WeightReference) && polynomial;
1048       //:39 by abv 15.12.97
1049       Standard_Real weight = start->Weight(i);
1050       if ( weight < Precision::PConfusion() ) {
1051         Message_Msg msg1215("IGES_1215");
1052         SendFail(start, msg1215);
1053         // Some weights are not positive
1054         return res;
1055       }
1056       PoleWeight.SetValue(WeightIndex++, weight);
1057 //:39      PoleWeight.SetValue(WeightIndex++, start->Weight(i));
1058     }
1059     if (polynomial) {
1060       Message_Msg msg1220("IGES_1220");
1061       msg1220.Arg("curve");
1062       SendWarning(start, msg1220);
1063       // Rational curve is polynomial
1064     }
1065     // Mise a jour du tableau des Weight lors de la correction de la multiplicite
1066     if ( newNbPoles < NbPoles) {
1067       Standard_Integer indj = 1;
1068       for ( i=1; i<= newNbPoles; i++) {
1069         Weight.SetValue(i, PoleWeight.Value(PoleInd.Value(indj++)));
1070       }
1071     }
1072     else {
1073       for ( i=1; i<= newNbPoles; i++) {
1074         Weight.SetValue (i, PoleWeight.Value(i));
1075       }
1076     }
1077 //:5    BSplineC = new Geom_BSplineCurve(Poles, Weight, Knot, Mult, Degree); 
1078   }
1079   
1080   //sln 29.12.2001 OCC90 : If curve can not be created do nothing
1081   if(!checkBSplineCurve(this, start, Knot, Weight)) return BSplineRes;
1082
1083   {
1084     try {
1085       OCC_CATCH_SIGNALS
1086       if (start->IsPolynomial()) 
1087         BSplineRes = new Geom_BSplineCurve(Poles, Knot, Mult, Degree);  
1088       else 
1089         BSplineRes = new Geom_BSplineCurve(Poles, Weight, Knot, Mult, Degree); 
1090     }
1091     catch(Standard_Failure) {
1092 #ifdef OCCT_DEBUG
1093       cout << "\n** Exception in IGESToBRep_BasicCurve::TransferBSplineCurve during creation of Geom_BSplineCurve : "; 
1094       Standard_Failure::Caught()->Print(cout);
1095 #endif
1096     }
1097   }
1098   
1099   Standard_Real First = BSplineRes->FirstParameter();
1100   Standard_Real Last  = BSplineRes->LastParameter();
1101   Standard_Real Udeb = start->UMin();
1102   Standard_Real Ufin = start->UMax();
1103   //%11 pdn 12.01.98 CTS22023 
1104   //if ( (Udeb-First) > Precision::PConfusion() || (Last-Ufin) > Precision::PConfusion() )
1105   //  BSplineRes->Segment(Udeb, Ufin);
1106   //res = BSplineRes;
1107
1108 //  IGESConvGeom::IncreaseCurveContinuity (BSplineRes,Min(Precision::Confusion(),GetEpsGeom()), GetContinuity());
1109   
1110   // skl 21.02.2002 (exception in OCC133 and for file
1111   //                 "/dn04/OS/USINOR/UIdev/src/IsoLim/dat/igs/ps1002-v5.igs")
1112   Handle(Geom_BSplineCurve) BSplineRes2 = BSplineRes;
1113   if (((Udeb-First)>-Precision::PConfusion() &&
1114        (Last-Ufin)>-Precision::PConfusion()) && Udeb<=Ufin ) {
1115     try {
1116       OCC_CATCH_SIGNALS
1117       if (Abs(Ufin-Udeb) > Precision::PConfusion())
1118         BSplineRes->Segment(Udeb, Ufin);
1119       res = BSplineRes;
1120     }
1121     catch (Standard_Failure) {
1122       Handle(Geom_TrimmedCurve) gtc = new Geom_TrimmedCurve(BSplineRes2,Udeb,Ufin);
1123       res = gtc;
1124     }
1125   }
1126   else
1127     res = BSplineRes;
1128
1129   return res;
1130 }
1131
1132
1133
1134 //=======================================================================
1135 //function : Transfer2dBSplineCurve
1136 //purpose  : 
1137 //=======================================================================
1138
1139 Handle(Geom2d_Curve)  IGESToBRep_BasicCurve::Transfer2dBSplineCurve
1140        (const Handle(IGESGeom_BSplineCurve)& start)
1141
1142   Handle(Geom2d_Curve)  res;
1143   if (start.IsNull()) {
1144     Message_Msg msg1005("IGES_1005");
1145     SendFail(start, msg1005);
1146     return res;
1147   }
1148
1149   Handle(Geom2d_BSplineCurve)  BSplineC;
1150   Handle(Geom_BSplineCurve)  Bspline;
1151   Standard_Boolean IsTrimmed = Standard_False;
1152   Standard_Real Deb=0., Fin=0.;
1153
1154   //  3d transfer first :
1155   //  ===================
1156 //  Standard_Real epsGeom = GetEpsGeom();
1157 //  SetEpsGeom(Precision::PConfusion());
1158   Handle(Geom_Curve)  res3d = TransferBSplineCurve(start);
1159 //  SetEpsGeom(epsGeom);
1160   if (res3d.IsNull()) {
1161     return res;
1162   }
1163   
1164              
1165   if (res3d->IsKind(STANDARD_TYPE(Geom_TrimmedCurve))) {
1166     DeclareAndCast(Geom_TrimmedCurve, TrimC, res3d);
1167     Handle(Geom_Curve) BasicCurve = TrimC->BasisCurve();
1168     Deb = TrimC->FirstParameter();
1169     Fin = TrimC->LastParameter();
1170     IsTrimmed = Standard_True;
1171     if (BasicCurve->IsKind(STANDARD_TYPE(Geom_BSplineCurve))) {
1172       DeclareAndCast(Geom_BSplineCurve, BSpline, BasicCurve);
1173       Bspline = BSpline;
1174     }
1175     else {
1176       return res;
1177     }
1178   }
1179   else if (res3d->IsKind(STANDARD_TYPE(Geom_BSplineCurve))) {
1180     DeclareAndCast(Geom_BSplineCurve, BSpline, res3d);
1181     Bspline = BSpline;
1182   }
1183
1184
1185   //  Creating 2d poles :
1186   //  ===================
1187
1188   Standard_Integer       NbPoles  =  Bspline->NbPoles();
1189   TColgp_Array1OfPnt2d   Pole(1,NbPoles);
1190
1191   for (Standard_Integer i=1; i<=NbPoles; i++){
1192     gp_Pnt2d aPole2d(Bspline->Pole(i).X(),Bspline->Pole(i).Y());
1193     Pole.SetValue(i,aPole2d);
1194   }
1195
1196   //  Knots and multiplicities are the same :
1197   //  =======================================
1198
1199   Standard_Integer  NbKnots = Bspline->NbKnots();
1200
1201   TColStd_Array1OfReal Knot(1,NbKnots);
1202   Bspline->Knots(Knot);
1203
1204   TColStd_Array1OfInteger Mult(1,NbKnots);
1205   Bspline->Multiplicities(Mult);
1206
1207   Standard_Integer  Degree = Bspline->Degree();
1208
1209   if (Bspline->IsRational()) {
1210     TColStd_Array1OfReal  Weight(1,NbPoles);
1211     Bspline->Weights(Weight);
1212     BSplineC = new Geom2d_BSplineCurve(Pole, Weight, Knot, Mult, Degree);
1213   }
1214   else BSplineC = new Geom2d_BSplineCurve(Pole, Knot, Mult, Degree);
1215   
1216   res = BSplineC;
1217
1218   // cas ou la Bspline est trimmee.
1219   if (IsTrimmed) {
1220     Handle(Geom2d_TrimmedCurve) TC = new Geom2d_TrimmedCurve
1221       (BSplineC, Deb, Fin, Standard_True);
1222     res = TC;
1223   }
1224   
1225   return res;
1226 }
1227
1228
1229
1230 //=======================================================================
1231 //function : TransferLine
1232 //purpose  : 
1233 //=======================================================================
1234
1235 Handle(Geom_Curve)  IGESToBRep_BasicCurve::TransferLine
1236        (const Handle(IGESGeom_Line)& start)
1237
1238   Handle(Geom_Curve)  res;
1239   if (start.IsNull()) {
1240     Message_Msg msg1005("IGES_1005");
1241     SendFail(start, msg1005);
1242     return res;
1243   }
1244
1245   gp_Pnt Ps,Pe;
1246   
1247   if (!GetModeTransfer() && start->HasTransf()) { 
1248     Ps = start->TransformedStartPoint();
1249     Pe = start->TransformedEndPoint();
1250   }
1251   else {
1252     Ps = start->StartPoint();
1253     Pe = start->EndPoint();
1254   }
1255
1256   // modif du 15/10/97  : test moins severe
1257   // beaucoup de points confondus a GetEpsGeom()*GetUnitFactor()
1258   if (!Ps.IsEqual(Pe,Precision::Confusion())) { //:l3 abv 11 Jan 99: GetEpsGeom()*GetUnitFactor()/10.)) {
1259     gp_Lin line(Ps, gp_Dir(gp_Vec(Ps,Pe)));
1260     Standard_Real t1 = ElCLib::Parameter(line, Ps);
1261     Standard_Real t2 = ElCLib::Parameter(line, Pe);
1262     Handle(Geom_Line)  Gline = new Geom_Line(line);
1263     if (Precision::IsNegativeInfinite(t1)) t1 = -Precision::Infinite();
1264     if (Precision::IsPositiveInfinite(t2)) t2 = Precision::Infinite();
1265     res = new Geom_TrimmedCurve(Gline, t1, t2);
1266   }
1267   else {
1268     Message_Msg msg1225("IGES_1225");
1269     SendFail(start, msg1225);
1270     // StartPoint and EndPoint of the line are the same Point
1271   }
1272
1273   return res;
1274 }
1275
1276
1277
1278 //=======================================================================
1279 //function : Transfer2dLine
1280 //purpose  : 
1281 //=======================================================================
1282
1283 Handle(Geom2d_Curve)  IGESToBRep_BasicCurve::Transfer2dLine
1284        (const Handle(IGESGeom_Line)& start)
1285
1286   Handle(Geom2d_Curve) res;
1287   if (start.IsNull()) {
1288     Message_Msg msg1005("IGES_1005");
1289     SendFail(start, msg1005);
1290     return res;
1291   }
1292
1293   gp_Pnt2d beg, end;
1294   
1295   if (!GetModeTransfer() && start->HasTransf()) {
1296     beg.SetCoord(start->TransformedStartPoint().X(),
1297                  start->TransformedStartPoint().Y());
1298     end.SetCoord(start->TransformedEndPoint().X(),
1299                  start->TransformedEndPoint().Y());
1300   }
1301   else {
1302     beg.SetCoord(start->StartPoint().X(),
1303                  start->StartPoint().Y());
1304     end.SetCoord(start->EndPoint().X(), 
1305                  start->EndPoint().Y());
1306   }
1307
1308   if (!beg.IsEqual(end,Precision::PConfusion())) { //:l3 abv 11 Jan 99: GetEpsCoeff())) {
1309     gp_Lin2d line2d(beg, gp_Dir2d(gp_Vec2d(beg,end)));
1310     Standard_Real t1 = ElCLib::Parameter(line2d, beg);
1311     Standard_Real t2 = ElCLib::Parameter(line2d, end);
1312     Handle(Geom2d_Line) Gline2d = new Geom2d_Line(line2d);
1313     if (Precision::IsNegativeInfinite(t1)) t1 = -Precision::Infinite();
1314     if (Precision::IsPositiveInfinite(t2)) t2 = Precision::Infinite();
1315     res = new Geom2d_TrimmedCurve(Gline2d, t1, t2);
1316   }
1317   //added by rln 18/12/97 CSR# CTS18544 entity 25168 and 31273
1318   //generating fail the same as above
1319   else { 
1320     Message_Msg msg1225("IGES_1225");
1321     SendFail(start, msg1225); // StartPoint and EndPoint of the 2d line are the same Point
1322   }
1323   return res;
1324 }
1325
1326
1327
1328 //=======================================================================
1329 //function : TransferTransformation
1330 //purpose  : 
1331 //=======================================================================
1332
1333 Handle(Geom_Transformation)  IGESToBRep_BasicCurve::TransferTransformation
1334        (const Handle(IGESGeom_TransformationMatrix)& start)
1335      
1336
1337   Handle(Geom_Transformation) res;
1338   if (start.IsNull()) {
1339     Message_Msg msg1005("IGES_1005");
1340     SendFail(start, msg1005);
1341     return res;
1342   }
1343   gp_Trsf resultat;
1344   SetEpsilon(1.E-05);  
1345   if ( IGESData_ToolLocation::ConvertLocation
1346       (GetEpsilon(),start->Value(),resultat) )
1347     res = new Geom_Transformation(resultat);
1348   else {
1349     Message_Msg msg1036("IGES_1036");
1350     SendFail(start, msg1036); // Transformation : not a similarity
1351   } 
1352   return res;
1353 }
1354
1355
1356
1357
1358 //=======================================================================
1359 //function : TransferCopiousData
1360 //purpose  : 
1361 //=======================================================================
1362
1363 Handle(Geom_BSplineCurve)  IGESToBRep_BasicCurve::TransferCopiousData
1364        (const Handle(IGESGeom_CopiousData)& start)
1365      
1366
1367   Handle(Geom_BSplineCurve)  res;
1368   if (start.IsNull()) {
1369     Message_Msg msg1005("IGES_1005");
1370     SendFail(start, msg1005);
1371     return res;
1372   }
1373   
1374   Standard_Integer  FormNb = start->FormNumber();
1375   if (!(FormNb==11 || FormNb==12 || FormNb==63)) {
1376     Message_Msg msg1240("IGES_1240");
1377     SendWarning( start, msg1240);
1378     // "Copious Data : Form number is different from 11, 12 or 63 so the vector treatement is skipped");
1379   }
1380
1381   Standard_Integer  NbPoints = start->NbPoints();
1382   if (NbPoints < 2) {
1383     Message_Msg msg1195("IGES_1195");
1384     SendFail(start, msg1195);  // Count of points lower than 2
1385     return res;
1386   }
1387
1388   //  Filling array of poles :
1389   //  ========================
1390
1391   TColgp_Array1OfPnt  TempPole(1,NbPoints);
1392   Standard_Integer    TempIndex = TempPole.Lower();
1393   
1394   if (!GetModeTransfer() && start->HasTransf()) {
1395     TempPole.SetValue(TempIndex,start->TransformedPoint(1));
1396   }
1397   else {
1398     TempPole.SetValue(TempIndex,start->Point(1));
1399   }    
1400   
1401   TempIndex++;
1402   Standard_Integer i;// svv Jan 10 2000 : porting on DEC
1403   for (i=2; i <= NbPoints; i++) {
1404     gp_Pnt  aPole;
1405     if (!GetModeTransfer() && start->HasTransf()) 
1406       aPole = start->TransformedPoint(i);
1407     else 
1408       aPole = start->Point(i);
1409     // #2 pdn 7 May 1998 BUC50028 
1410     //  delete GetUnitFactor()
1411     //   if (!aPole.IsEqual(TempPole(TempIndex-1),GetEpsGeom()))
1412     //S4054: some filter must be kept UKI60556 entity 7 (two equal points)
1413     if (!aPole.IsEqual(TempPole(TempIndex-1), gp::Resolution()))
1414       TempPole.SetValue(TempIndex++,aPole);
1415   }
1416
1417   NbPoints = TempIndex - TempPole.Lower();
1418
1419   // #1 pdn 7 May 1998  BUC50028 entity 6307
1420   if ( NbPoints == 1) {
1421     Message_Msg msg1235("IGES_1235");
1422     SendFail(start, msg1235);
1423     // The curve degenerates to a point");
1424     return res;
1425   }
1426   TColgp_Array1OfPnt  Pole(1,NbPoints);
1427
1428   TempIndex = TempPole.Lower();
1429   for (i=Pole.Lower(); i<=Pole.Upper(); i++)  
1430     Pole.SetValue(i,TempPole.Value(TempIndex++));
1431
1432   
1433   //  Filling array of knots :
1434   //  ========================
1435   
1436   TColStd_Array1OfReal  Knot(1,NbPoints);
1437   
1438   Knot.SetValue(Knot.Lower(),0.0);
1439
1440   for (i=Knot.Lower()+1; i <= Knot.Upper(); i++) {
1441     gp_Pnt  Pole1    =  Pole.Value(i);
1442     gp_Pnt  Pole2    =  Pole.Value(i-1);
1443     Standard_Real    KnotDist =  Pole1.Distance(Pole2);
1444     Knot.SetValue(i, Knot.Value(i-1)+KnotDist);
1445   }
1446   
1447   Standard_Integer  Degree = 1;
1448
1449   TColStd_Array1OfInteger  Mult(1, NbPoints);
1450   Mult.Init(Degree);
1451   Mult.SetValue(Mult.Lower(),Degree+1);
1452   Mult.SetValue(Mult.Upper(),Degree+1);
1453
1454   res = new Geom_BSplineCurve(Pole, Knot, Mult, Degree);
1455   
1456   IGESConvGeom::IncreaseCurveContinuity (res, Max(GetEpsGeom()/10.,Precision::Confusion()), GetContinuity());
1457   return res;
1458 }
1459
1460
1461 //                    ================================
1462 //                    ==  TRANSFER 2D Copious data  ==
1463 //                    ================================
1464
1465 Handle(Geom2d_BSplineCurve) IGESToBRep_BasicCurve::Transfer2dCopiousData(const Handle(IGESGeom_CopiousData)& start)
1466
1467   Handle(Geom2d_BSplineCurve)  res;
1468   if (start.IsNull()) {
1469     Message_Msg msg1005("IGES_1005");
1470     SendFail(start, msg1005);
1471     return res;
1472   }
1473   
1474   Standard_Integer  FormNb = start->FormNumber();
1475   if (!(FormNb==11 || FormNb==12 || FormNb==63)) {
1476     Message_Msg msg1240("IGES_1240");
1477     SendWarning( start, msg1240);
1478     // "Copious Data : Form number is different from 11, 12 or 63 so the vector treatement is skipped");
1479   }
1480   
1481   Standard_Integer  NbPoints = start->NbPoints();
1482   if (NbPoints < 2) {
1483     Message_Msg msg1195("IGES_1195");
1484     SendFail(start, msg1195);  // Count of points lower than 2
1485     return res;
1486   }
1487   
1488   //  Filling array of poles :
1489   //  ========================
1490   
1491   TColgp_Array1OfPnt2d  TempPole(1,NbPoints);
1492   Standard_Integer      TempIndex = TempPole.Lower();
1493   
1494   if (!GetModeTransfer() && start->HasTransf()) 
1495     TempPole.SetValue(TempIndex,gp_Pnt2d(start->TransformedPoint(1).X(),
1496                                          start->TransformedPoint(1).Y()));
1497   else 
1498     TempPole.SetValue(TempIndex,gp_Pnt2d(start->Point(1).X(),
1499                                          start->Point(1).Y()));
1500   
1501   
1502   TempIndex++;
1503   Standard_Integer i;//svv Jan 10 2000 : porting on DEC
1504   for  (i=2; i <= NbPoints; i++) {
1505     gp_Pnt2d  aPole;
1506     if (!GetModeTransfer() && start->HasTransf()) 
1507       aPole = gp_Pnt2d(start->TransformedPoint(i).X(),
1508                        start->TransformedPoint(i).Y());
1509     else 
1510       aPole = gp_Pnt2d(start->Point(i).X(),
1511                        start->Point(i).Y());
1512     //    if (!aPole.IsEqual(TempPole(TempIndex-1), GetEpsCoeff())) //modified by rln 16/12/97 CSR# PRO11641 entity 46GetEpsGeom()*GetUnitFactor()
1513     //S4054: some filter must be kept UKI60556 entity 7 (two equal points)
1514     if (!aPole.IsEqual(TempPole(TempIndex-1), gp::Resolution()))
1515       TempPole.SetValue(TempIndex++,aPole);
1516   }
1517
1518   NbPoints = TempIndex - TempPole.Lower();
1519   //added by rln on 26/12/97 to avoid exception when creating Bspline from one point
1520   if (NbPoints == 1) {
1521     Message_Msg msg1235("IGES_1235");
1522     SendFail(start, msg1235);
1523     // The curve degenerates to a point");
1524     return res;
1525   }
1526   TColgp_Array1OfPnt2d  Pole(1,NbPoints);
1527
1528   TempIndex = TempPole.Lower();
1529   for (i=Pole.Lower(); i<=Pole.Upper(); i++)  
1530     Pole.SetValue(i,TempPole.Value(TempIndex++));
1531
1532
1533   //  Filling array of knots :
1534   //  ========================
1535
1536   TColStd_Array1OfReal  Knot(1,NbPoints);
1537   
1538   Knot.SetValue(Knot.Lower(),0.0);
1539
1540   for (i=Knot.Lower()+1; i <= Knot.Upper(); i++) {
1541     gp_Pnt2d  Pole1    =  Pole.Value(i);
1542     gp_Pnt2d  Pole2    =  Pole.Value(i-1);
1543     Standard_Real      KnotDist =  Pole1.Distance(Pole2);
1544     Knot.SetValue(i, Knot.Value(i-1)+KnotDist);
1545   }
1546   
1547   const Standard_Integer  Degree = 1;
1548
1549   TColStd_Array1OfInteger  Mult(1, NbPoints);
1550   Mult.Init(Degree);
1551   Mult.SetValue(Mult.Lower(),Degree+1);
1552   Mult.SetValue(Mult.Upper(),Degree+1);
1553   
1554   res = new Geom2d_BSplineCurve(Pole, Knot, Mult, Degree);
1555   
1556   Standard_Real epsGeom = GetEpsGeom();
1557   Standard_Real anUVResolution = GetUVResolution();
1558   
1559   IGESConvGeom::IncreaseCurveContinuity (res, Max(Precision::Confusion(),epsGeom*anUVResolution), GetContinuity());
1560   return res;
1561 }