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