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