0026377: Passing Handle objects as arguments to functions as non-const reference...
[occt.git] / src / IGESToBRep / IGESToBRep_TopoCurve.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 //purpose  : Members to transfert any IGES Curves into TopoDS_Shape
16 //=======================================================================
17 // modif mjm du 23/09/97 : appel a ShapeTool en remplacement a PCurveLib
18 // 21.12.98 rln, gka S4054
19 //%11 12.01.99 pdn CTS22023 reversing direction when reading offset curves
20 //:q5 abv 19.03.99 unnecessary includes removed
21 //%14 03.03.99 pdn USA60022 do not insert lacking edge before fix missing seam
22 // pdn 10.03.99 S4135 Creating vertices using minimal tolerance.
23 //S4181 pdn 17.04.99 Inplementing of reading IGES elementary surfaces. Transform
24 //pcurves using gp_Trsf2d that depends on type of pair (IGES surface, resulting 
25 //CAS.CADE surface)
26 //szv#9:PRO19565:04Oct99 missing location for standalone vertices corrected
27
28 #include <BRep_Builder.hxx>
29 #include <BRep_Tool.hxx>
30 #include <BRepBuilderAPI_MakeEdge.hxx>
31 #include <BRepLib_MakeFace.hxx>
32 #include <BRepTools.hxx>
33 #include <Geom2d_BSplineCurve.hxx>
34 #include <Geom2d_Curve.hxx>
35 #include <Geom2d_OffsetCurve.hxx>
36 #include <Geom2d_TrimmedCurve.hxx>
37 #include <Geom_BSplineCurve.hxx>
38 #include <Geom_Curve.hxx>
39 #include <Geom_OffsetCurve.hxx>
40 #include <Geom_Plane.hxx>
41 #include <Geom_Surface.hxx>
42 #include <Geom_TrimmedCurve.hxx>
43 #include <gp.hxx>
44 #include <gp_Dir.hxx>
45 #include <gp_GTrsf.hxx>
46 #include <gp_Pnt.hxx>
47 #include <gp_Pnt2d.hxx>
48 #include <gp_Trsf2d.hxx>
49 #include <gp_XY.hxx>
50 #include <IGESData_HArray1OfIGESEntity.hxx>
51 #include <IGESData_IGESEntity.hxx>
52 #include <IGESData_IGESModel.hxx>
53 #include <IGESData_ToolLocation.hxx>
54 #include <IGESGeom_Boundary.hxx>
55 #include <IGESGeom_CircularArc.hxx>
56 #include <IGESGeom_CompositeCurve.hxx>
57 #include <IGESGeom_CurveOnSurface.hxx>
58 #include <IGESGeom_OffsetCurve.hxx>
59 #include <IGESGeom_Point.hxx>
60 #include <IGESGeom_SplineCurve.hxx>
61 #include <IGESToBRep.hxx>
62 #include <IGESToBRep_AlgoContainer.hxx>
63 #include <IGESToBRep_BasicCurve.hxx>
64 #include <IGESToBRep_BasicSurface.hxx>
65 #include <IGESToBRep_CurveAndSurface.hxx>
66 #include <IGESToBRep_IGESBoundary.hxx>
67 #include <IGESToBRep_ToolContainer.hxx>
68 #include <IGESToBRep_TopoCurve.hxx>
69 #include <IGESToBRep_TopoSurface.hxx>
70 #include <Interface_Macros.hxx>
71 #include <Message_Msg.hxx>
72 #include <Precision.hxx>
73 #include <ShapeAlgo.hxx>
74 #include <ShapeAlgo_AlgoContainer.hxx>
75 #include <ShapeBuild_Edge.hxx>
76 #include <ShapeExtend_WireData.hxx>
77 #include <ShapeFix_Wire.hxx>
78 #include <Standard_ErrorHandler.hxx>
79 #include <Standard_Failure.hxx>
80 #include <TColGeom2d_HSequenceOfBoundedCurve.hxx>
81 #include <TColGeom_HSequenceOfBoundedCurve.hxx>
82 #include <TColgp_Array1OfPnt.hxx>
83 #include <TColgp_Array1OfPnt2d.hxx>
84 #include <TCollection_HAsciiString.hxx>
85 #include <TopAbs.hxx>
86 #include <TopLoc_Location.hxx>
87 #include <TopoDS.hxx>
88 #include <TopoDS_Edge.hxx>
89 #include <TopoDS_Face.hxx>
90 #include <TopoDS_Iterator.hxx>
91 #include <TopoDS_Shape.hxx>
92 #include <TopoDS_Vertex.hxx>
93 #include <TopoDS_Wire.hxx>
94
95 #include <stdio.h>
96 //added by rln 32/12/97
97 //#include <TColStd_Array1OfInteger.hxx>
98 //#include <TColStd_Array1OfReal.hxx>
99 //#include <TColStd_HSequenceOfTransient.hxx>
100 //=======================================================================
101 //function : IGESToBRep_TopoCurve
102 //purpose  : 
103 //=======================================================================
104 IGESToBRep_TopoCurve::IGESToBRep_TopoCurve()
105 :IGESToBRep_CurveAndSurface()
106 {  
107 }
108
109
110 //=======================================================================
111 //function : IGESToBRep_TopoCurve
112 //purpose  : 
113 //=======================================================================
114
115 IGESToBRep_TopoCurve::IGESToBRep_TopoCurve (const IGESToBRep_TopoCurve& other)
116      :IGESToBRep_CurveAndSurface (other)
117 {  
118   TheCurves.Assign(other.TheCurves);
119   TheCurves2d.Assign(other.TheCurves2d);
120 }
121
122
123 //=======================================================================
124 //function : IGESToBRep_TopoCurve
125 //purpose  : 
126 //=======================================================================
127
128 IGESToBRep_TopoCurve::IGESToBRep_TopoCurve
129   (const IGESToBRep_CurveAndSurface& CS)
130      :IGESToBRep_CurveAndSurface(CS)
131 {  
132 }
133
134
135 //=======================================================================
136 //function : IGESToBRep_TopoCurve
137 //purpose  : 
138 //=======================================================================
139
140 IGESToBRep_TopoCurve::IGESToBRep_TopoCurve
141   (const Standard_Real    eps,
142    const Standard_Real    epsCoeff,
143    const Standard_Real    epsGeom,
144    const Standard_Boolean mode,
145    const Standard_Boolean modeapprox,
146    const Standard_Boolean optimized)
147 :IGESToBRep_CurveAndSurface(eps, epsCoeff, epsGeom, mode, modeapprox, 
148                             optimized)
149 {  
150 }
151
152
153 //=======================================================================
154 //function : TransferPoint
155 //purpose  : 
156 //=======================================================================
157
158 TopoDS_Vertex  IGESToBRep_TopoCurve::TransferPoint
159        (const Handle(IGESGeom_Point)& start)
160      
161 {
162   TopoDS_Vertex  V1;
163   if (start.IsNull()) {
164     Message_Msg Msg1005("IGES_1005");
165     SendFail(start, Msg1005); //"Point Transfer Error : Null IGESEntity"
166     //AddFail(start, "Point Transfer Error : Null IGESEntity");
167     return  V1;
168   }
169
170   BRep_Builder B;
171   gp_Pnt point;
172   
173   if (!GetModeTransfer() && start->HasTransf())
174     point = start->TransformedValue();
175   else
176     point = start->Value();
177
178   point.Scale(gp_Pnt(0,0,0),GetUnitFactor());
179   B.MakeVertex(V1, point, Precision::Confusion());//S4135: GetEpsGeom()*GetUnitFactor()
180
181   //szv#9:PRO19565:04Oct99
182   if (GetModeTransfer() && start->HasTransf()) {
183     gp_Trsf T;
184     SetEpsilon(1.E-04);
185     if (IGESData_ToolLocation::ConvertLocation
186         (GetEpsilon(),start->CompoundLocation(),T,GetUnitFactor())) { 
187       TopLoc_Location L(T);
188       V1.Move(L);
189     }
190   }
191   
192   return V1;
193 }
194
195 //=======================================================================
196 //function : Transfer2dPoint
197 //purpose  : 
198 //=======================================================================
199
200 TopoDS_Vertex  IGESToBRep_TopoCurve::Transfer2dPoint
201        (const Handle(IGESGeom_Point)& start)
202      
203 {
204   TopoDS_Vertex V1;
205   if (start.IsNull()) {
206      Message_Msg Msg1005("IGES_1005");//"2D Point Transfer Error : Null IGESEntity"
207      SendFail(start, Msg1005);
208    // AddFail(start, "2D Point Transfer Error : Null IGESEntity");
209     return  V1;
210   }
211
212   BRep_Builder B;
213   gp_Pnt point;
214   
215   if (!GetModeTransfer() && start->HasTransf())
216     point = gp_Pnt(start->TransformedValue().X(), 
217                    start->TransformedValue().Y(),
218                    0.);
219   else
220     point = gp_Pnt(start->Value().X(), 
221                    start->Value().Y(),
222                    0.);  
223
224   B.MakeVertex(V1, point, Precision::Confusion());//S4135: GetEpsCoeff()
225   return V1;
226 }
227
228 //=======================================================================
229 //function : TransferCompositeCurveGeneral
230 //purpose  : General transfer for both 2d and 3d cases
231 //=======================================================================
232
233 //:13 by abv 13 Nov 97: common part of two methods (see below)
234 TopoDS_Shape  IGESToBRep_TopoCurve::TransferCompositeCurveGeneral(const Handle(IGESGeom_CompositeCurve)& start, 
235                                                                   const Standard_Boolean is2d,
236                                                                   const TopoDS_Face& face,
237                                                                   const gp_Trsf2d& trans,
238                                                                   const Standard_Real uFact)
239
240 {
241   TopoDS_Shape  res;
242
243   if (start.IsNull()) {
244     Message_Msg Msg1005("IGES_1005"); //"CompositeCurve Transfer Error : Null IGESEntity"
245     SendFail(start, Msg1005);
246     // AddFail(start, "CompositeCurve Transfer Error : Null IGESEntity");
247     return  res;
248   }
249
250   Standard_Real precision = GetEpsGeom() * GetUnitFactor(), maxtol = GetMaxTol();
251   
252   Handle(ShapeExtend_WireData) sewd = new ShapeExtend_WireData();
253   Handle(ShapeAnalysis_Wire) saw = new ShapeAnalysis_Wire;
254   saw->Load (sewd);
255   saw->SetPrecision (precision);
256   
257   for (Standard_Integer i=1; i<= start->NbCurves(); i++) {
258
259     Handle(IGESData_IGESEntity)  IgesEnt = start->Curve(i);
260     //added by rln 26/12/97 CSR# UKI60028 entity 3117
261     if (i > 1 && IgesEnt == start->Curve (i-1)) {
262 //      char mess[80];
263       Message_Msg Msg1045("IGES_1045"); //"The entities of the CompositeCurve are the same: %d & %d"
264       Msg1045.Arg(i);
265       SendWarning(start,Msg1045);
266       //sprintf (mess, "The entities of the CompositeCurve are the same: %d & %d", i-1, i);
267       //AddWarning (start, mess);
268       continue;
269     }
270     if (IgesEnt.IsNull()) {
271       Message_Msg Msg1040("IGES_1040");//"Curve%dd is a null object : number %d"
272       Msg1040.Arg(i); 
273       SendFail(start,Msg1040);
274       return res;
275     }
276     
277     if (is2d && (IgesEnt->IsKind(STANDARD_TYPE(IGESGeom_Boundary)) ||
278                  IgesEnt->IsKind(STANDARD_TYPE(IGESGeom_CurveOnSurface)) ) ) {
279       //AddWarning(start, "Entity cannot be built from a boundary.");
280       Message_Msg Msg1040("IGES_1040");//"Entity cannot be built from a boundary."
281       Msg1040.Arg(i); 
282       SendFail(start,Msg1040);
283       return res;
284     }
285     else if (IGESToBRep::IsTopoCurve(IgesEnt)) {
286       TopoDS_Shape shape; //:13 = TransferTopoCurve(IgesEnt);
287       if ( is2d ) shape = Transfer2dTopoCurve ( IgesEnt, face, trans, uFact ); //:13
288       else        shape = TransferTopoCurve   ( IgesEnt ); //:13
289       if (!shape.IsNull()){
290         if (shape.ShapeType() == TopAbs_VERTEX) continue;
291
292         Handle(ShapeExtend_WireData) nextsewd = new ShapeExtend_WireData;
293         nextsewd->Add (shape);
294         Standard_Real distmin;
295         Standard_Boolean revsewd, revnextsewd;
296         Standard_Boolean isConnected = ShapeAlgo::AlgoContainer()->ConnectNextWire (saw, nextsewd, maxtol, distmin,
297                                                                                     revsewd, revnextsewd);
298         if (isConnected) {
299           if (revsewd) {
300             Message_Msg Msg1051("IGES_1051");   //"All curvAll curves %dd before rank %d have been to be reversed."
301             Msg1051.Arg((is2d ? 2 : 3));
302             Msg1051.Arg(i);
303             SendWarning(start,Msg1051);
304           }
305           if (revnextsewd) {
306             Message_Msg Msg1050("IGES_1050");   //"Curve %dd needs to be reversed : %d"
307             Msg1050.Arg((is2d ? 2 : 3));
308             Msg1050.Arg(i);
309             SendWarning(start,Msg1050);
310             
311             //  sprintf(mess, "Curve %dd needs to be reversed : %d", ( is2d ? 2 : 3 ), i);//:13
312           //  AddWarning(start, mess);
313           }
314           if (distmin > precision) {
315             Message_Msg Msg1055("IGES_1055");   
316             Msg1055.Arg((is2d ? 2 : 3));
317             Msg1055.Arg(i);
318             SendWarning(start,Msg1055);
319           }
320         }
321         else {
322           Message_Msg Msg1060("IGES_1060");   //"Curves %dd are too much disconnected : %d & %d"
323           Msg1060.Arg((is2d ? 2 : 3));
324           Msg1060.Arg(i);
325           SendFail(start,Msg1060);
326           return res;
327         }
328       }
329     }
330   }
331
332   Handle(ShapeFix_Wire) sfw = new ShapeFix_Wire;
333   sfw->Load (sewd);
334   sfw->ClosedWireMode() = Standard_False;//closing of face boundaries will be later
335   sfw->FixConnected (maxtol);
336   sfw->FixConnected (1, precision);//10.12.98 CTS18953 entity 14 (Plane+CompositeCurve)
337   res = sewd->Wire();
338   
339   SetShapeResult (start, res);
340   return  res;
341 }
342
343 //=======================================================================
344 //function : TransferCompositeCurve
345 //purpose  : Implementation for 3d case
346 //=======================================================================
347
348 TopoDS_Shape  IGESToBRep_TopoCurve::TransferCompositeCurve
349   (const Handle(IGESGeom_CompositeCurve)&  start)
350
351 {
352   TopoDS_Shape res;
353   TopoDS_Face f;
354   gp_Trsf trans;
355   res = TransferCompositeCurveGeneral ( start, Standard_False, f, trans, 1.);
356
357   if ( ! res.IsNull() && start->HasTransf()) {
358     gp_Trsf  T;
359     SetEpsilon(1.E-04);
360     if (IGESData_ToolLocation::ConvertLocation
361         (GetEpsilon(),start->CompoundLocation(),T,GetUnitFactor())) { 
362       TopLoc_Location  L(T);
363       res.Move(L);
364     }
365     else {
366       Message_Msg Msg1035("IGES_1035");
367       SendWarning(start,Msg1035);
368     }
369       //  AddWarning(start, "Transformation skipped (not a similarity)");
370   }
371   return res;
372 }
373
374 //=======================================================================
375 //function : Transfer2dCompositeCurve
376 //purpose  : Implementation for 2d case
377 //=======================================================================
378
379 TopoDS_Shape  IGESToBRep_TopoCurve::Transfer2dCompositeCurve
380        (const Handle(IGESGeom_CompositeCurve)&  start,
381         const TopoDS_Face&          face,
382         const gp_Trsf2d& trans,
383         const Standard_Real uFact)
384      
385 {
386   TopoDS_Shape res;
387   res = TransferCompositeCurveGeneral ( start, Standard_True, face, trans, uFact);
388   // Message occur if needed in TransferCompositeCurveGeneral
389   //if (start->HasTransf()) {
390   //  Message_Msg Msg1036("IGES_1036"); //"The Trsf cannot be applied to the entity."
391   //  SendWarning(start,Msg1036);
392   // AddWarning(start, "The Trsf cannot be applied to the entity.");
393   //}
394   return  res;
395 }
396
397 //=======================================================================
398 //function : TransferCurveOnSurface
399 //purpose  : 
400 //=======================================================================
401
402 TopoDS_Shape  IGESToBRep_TopoCurve::TransferCurveOnSurface
403   (const Handle(IGESGeom_CurveOnSurface)& start)
404 {
405   TopoDS_Shape  res;
406   
407   if (start.IsNull()) {
408     Message_Msg Msg1005("IGES_1005");
409     SendFail(start,Msg1005);
410     //  AddFail(start, "CurveOnSurface Transfer Error : Null IGESEntity");
411     return  res;
412   }
413
414   TopoDS_Face  face;
415   Handle (IGESData_IGESEntity) igesSurface = start->Surface();
416   if (igesSurface.IsNull() || !IGESToBRep::IsTopoSurface(igesSurface)) {
417     Message_Msg Msg131("XSTEP_131");  //"BasicSurface Transfer Error : Null IGESEntity"
418     SendFail(start,Msg131);
419     //AddFail(start, "BasicSurface Transfer Error : Null IGESEntity");
420     return res;
421   }
422   TopAbs_ShapeEnum shapeEnum;
423   IGESToBRep_TopoSurface TS(*this);
424   gp_Trsf2d trans;
425   Standard_Real uFact;
426   TopoDS_Shape myshape = TS.ParamSurface (igesSurface, trans, uFact);
427
428   if (!myshape.IsNull()) {
429     shapeEnum = myshape.ShapeType();
430     switch (shapeEnum) {
431     case TopAbs_FACE :
432       {
433         face = TopoDS::Face(myshape);
434         break;
435       }
436     case TopAbs_SHELL :
437       {
438         TopoDS_Iterator IT(myshape);
439         Standard_Integer nbfaces = 0;
440         for (; IT.More(); IT.Next()) {
441           nbfaces++;
442           face = TopoDS::Face(IT.Value());
443         }
444         //szv#4:S4163:12Mar99 optimized
445         if (nbfaces != 1) {
446           if (!start->Curve3D().IsNull()) {
447             if (IGESToBRep::IsTopoCurve(start->Curve3D())) {
448               TopoDS_Shape  Sh = TransferTopoCurve(start->Curve3D());
449               if (!Sh.IsNull()) {
450                 Message_Msg Msg1062("IGES_1062");
451      //CurveOnSurface on Composite Surface case not implemented : 3D representation returned.
452                 SendWarning(start,Msg1062);
453                 res = Sh;
454               }
455             }
456           }
457           else {
458             Message_Msg Msg1061("IGES_1061"); 
459             Msg1061.Arg("CurveOnSurface");
460             SendFail(start,Msg1061);
461           }
462           return res;
463         }
464       }
465       break;
466     default:
467       {
468         if (!start->Curve3D().IsNull()) {
469           if (IGESToBRep::IsTopoCurve(start->Curve3D())) {
470             TopoDS_Shape  Sh = TransferTopoCurve(start->Curve3D());
471             if (!Sh.IsNull()) {
472               Message_Msg Msg1062("IGES_1062"); //"Basis Surface Error : 3dCurve returned"
473               SendWarning(start,Msg1062);
474               //   AddWarning(start,"Basis Surface Error : 3dCurve returned");
475               res = Sh;
476             }
477           }
478         }
479         else {
480           Message_Msg Msg1061("IGES_1061"); 
481           Msg1061.Arg("CurveOnSurface");
482           SendFail(start,Msg1061);
483         }
484         //  AddFail(start, "Basis Surface Error.");
485         return res;
486       }
487     }
488   }
489
490   face.EmptyCopy();
491   res = TransferCurveOnFace (face, start, trans, uFact, Standard_True);
492   return res;
493 }
494
495
496 //=======================================================================
497 //function : TransferCurveOnFace
498 //purpose  : 
499 //=======================================================================
500
501 TopoDS_Shape IGESToBRep_TopoCurve::TransferCurveOnFace(TopoDS_Face&  face, 
502                                                        const Handle(IGESGeom_CurveOnSurface)& start,
503                                                        const gp_Trsf2d& trans,
504                                                        const Standard_Real uFact,
505                                                        const Standard_Boolean isCurveOnSurf)
506 {
507   TopoDS_Shape  res;
508   if (start.IsNull()) {
509     Message_Msg Msg1005("IGES_1005"); //"CurveOnFace Transfer Error : Null IGESEntity"
510     SendFail(start,Msg1005);
511     return res;
512   }
513   
514   Standard_Boolean okCurve = Standard_True, okCurve3d = Standard_True, okCurve2d = Standard_True;
515   Standard_Integer filepreference = 0;
516   if      (start->PreferenceMode() == 1) filepreference = 2;
517   else if (start->PreferenceMode() == 2) filepreference = 3;
518   Handle(IGESData_HArray1OfIGESEntity) Curves2d = new IGESData_HArray1OfIGESEntity (1, 1);
519   Curves2d->SetValue (1, start->CurveUV());
520   
521   Handle(IGESToBRep_IGESBoundary) IB = IGESToBRep::AlgoContainer()->ToolContainer()->IGESBoundary();
522   IB->Init (*this, start, face, trans, uFact, filepreference);
523   Standard_Boolean Result = IB->Transfer (okCurve, okCurve3d, okCurve2d,
524                                           start->Curve3D(), Standard_False,
525                                           Curves2d, 1);
526   IB->Check(Result, !isCurveOnSurf, okCurve3d, okCurve2d);
527   Handle(ShapeExtend_WireData) sewd = IB->WireData();
528   if (sewd->NbEdges() == 0) {
529       Message_Msg Msg1095("IGES_1095");//"Both 2d and 3d representations are invalid"
530       SendFail(start,Msg1095);
531     return res;
532   }
533   
534   //%14 pdn 03.03.99
535   //IB.Fix (sewd, Standard_True, !isCurveOnSurf, Standard_False, Standard_False, Standard_False);
536   TopoDS_Wire mywire = sewd->Wire();
537
538   if (start->HasTransf()) {
539     gp_Trsf  T;
540     SetEpsilon(1.E-04);
541     if (IGESData_ToolLocation::ConvertLocation
542         (GetEpsilon(),start->CompoundLocation(),T)) {
543       TopLoc_Location L(T);
544       mywire.Move(L);
545     }
546     else {
547       Message_Msg Msg1035("IGES_1035"); //"Transformation skipped (not a similarity)"
548       SendWarning(start,Msg1035);
549     }
550   }
551
552   BRepLib_MakeFace MF(face);
553   MF.Add(mywire);
554   face = MF.Face();
555   SetShapeResult (start, mywire);
556   return mywire;
557 }
558
559
560 //=======================================================================
561 //function : TransferOffsetCurve
562 //purpose  : 
563 //=======================================================================
564
565 TopoDS_Shape  IGESToBRep_TopoCurve::TransferOffsetCurve
566   (const Handle(IGESGeom_OffsetCurve)&  start)
567
568 {
569   TopoDS_Shape  res;
570
571   if (start.IsNull()) {
572     Message_Msg Msg1005("IGES_1005"); //"Offset Curve Transfer Error : Null IGESEntity"
573     SendFail(start, Msg1005);
574     //AddFail(start, "OffsetCurve Transfer Error : Null IGESEntity");
575     return  res;
576   }
577   if (start->OffsetType() != 1) {
578     Message_Msg Msg1100("IGES_1100"); //"Offset distance flag different from 1 not treated"
579     SendFail(start,Msg1100);
580     //AddFail(start, "Offset distance flag different from 1 not treated");
581     return  res;
582   }
583
584   Standard_Real    Offset = start->FirstOffsetDistance();
585   gp_Dir  NrmDir;
586   if (start->HasTransf()) 
587     NrmDir = start->TransformedNormalVector();
588   else
589     NrmDir = start->NormalVector();
590   //%11 pdn 12.01.99 CTS22023
591   NrmDir.Reverse();
592
593   Handle(IGESData_IGESEntity)  BaseCrv = start->BaseCurve();
594
595   while (BaseCrv->IsKind(STANDARD_TYPE(IGESGeom_OffsetCurve))) {
596     DeclareAndCast(IGESGeom_OffsetCurve, OffCrv, BaseCrv);
597     if (OffCrv->OffsetType() != 1) {
598        Message_Msg Msg1100("IGES_1100"); //"Offset distance flag different from 1 not treated"
599        SendFail(start,Msg1100);
600        return  res;
601     }
602     BaseCrv = OffCrv->BaseCurve();
603     Offset  = Offset + OffCrv->FirstOffsetDistance();
604   }
605
606
607   if (!IGESToBRep::IsTopoCurve(BaseCrv)) {
608    Message_Msg Msg110("XSTEP_110");
609    SendFail(start,Msg110);
610    return res;
611  }
612   
613   Handle(Geom_Curve)  Crv;
614   Handle(Geom_OffsetCurve)  OffCrv;
615   
616   IGESToBRep_TopoCurve  TC(*this);
617   TopoDS_Shape  Sh = TC.TransferTopoCurve(BaseCrv);
618   
619   if (Sh.IsNull() || ! ((Sh.ShapeType() == TopAbs_EDGE) || (Sh.ShapeType() == TopAbs_WIRE)) ) {
620     Message_Msg Msg1156("IGES_1156");
621     Handle(TCollection_HAsciiString) label = GetModel()->StringLabel(BaseCrv);
622     Msg1156.Arg("basis curve");
623     Msg1156.Arg(label);
624     SendFail(start,Msg1156);
625     //AddFail(start, "Edge or wire expected from TransferTopoCurve");
626     return res;
627   }
628
629   if (Sh.ShapeType() == TopAbs_EDGE) {
630     TopLoc_Location  aLoc;  
631     Standard_Real  a, b;
632     Crv = BRep_Tool::Curve(TopoDS::Edge(Sh), aLoc, a, b);
633     OffCrv = new Geom_OffsetCurve(Crv,Offset,NrmDir);
634     BRepBuilderAPI_MakeEdge  ME(OffCrv,start->StartParameter(),start->EndParameter());
635     if (!ME.IsDone()) {
636       
637       Message_Msg Msg1005("IGES_1005"); //"Edge construction error"
638       SendFail(start,Msg1005);
639       //AddFail(start, "Edge construction error");
640       return  res;
641     }
642     TopoDS_Edge  anEdge = ME.Edge();  
643     anEdge.Move(aLoc);
644     res = anEdge;
645   }
646     
647   else if (Sh.ShapeType() == TopAbs_WIRE) {
648     Handle(ShapeExtend_WireData) sewd = new ShapeExtend_WireData;
649     TopoDS_Wire      aWire  = TopoDS::Wire(Sh);
650     Standard_Boolean begin  = Standard_True;
651     Standard_Real    length = 0.0;
652     Standard_Real    staPar = start->StartParameter();
653     Standard_Real    endPar = start->EndParameter();
654       
655     for (TopoDS_Iterator Iter(aWire); Iter.More(); Iter.Next()) {
656       TopoDS_Edge     anEdge = TopoDS::Edge(Iter.Value());
657       TopLoc_Location aLoc;  
658       Standard_Real   first, last;
659       Crv = BRep_Tool::Curve(anEdge, aLoc, first, last);
660       if ((length + last - first) <= staPar) continue;
661       if (length >= endPar) {
662         if (begin) {
663            Message_Msg Msg1105("IGES_1105"); //"Cannot build a ruled surface from these curves."
664            SendFail(start,Msg1105);
665           //AddFail(start, "Cannot build a ruled surface from these curves.");
666           return  res;
667         }
668         break;
669       }
670       OffCrv = new Geom_OffsetCurve(Crv,Offset,NrmDir);
671       BRepBuilderAPI_MakeEdge  ME(OffCrv, staPar - length, endPar - length);
672         
673       if (!ME.IsDone()) {
674          Message_Msg Msg1005("IGES_1005"); //"Edge construction error"
675          SendFail(start,Msg1005);
676         //AddFail(start, "Edge construction error");
677         return  res;
678       }
679       TopoDS_Edge  anotherEdge = ME.Edge();  
680       anotherEdge.Move(aLoc);
681       begin   = Standard_False;
682       length += last - first;
683       sewd->Add (anotherEdge);
684     }
685     Handle(ShapeFix_Wire) sfw = new ShapeFix_Wire;
686     sfw->Load (sewd);
687     //pdn S4135 10.03.99
688     //sfw.FixConnected (GetEpsGeom() * GetUnitFactor());
689     sfw->FixConnected ();
690     res = sfw->Wire();
691   }
692   
693   if (start->HasTransf()) {
694     gp_Trsf T;
695     SetEpsilon(1.E-04);
696     if (IGESData_ToolLocation::ConvertLocation
697         (GetEpsilon(),start->CompoundLocation(),T,GetUnitFactor())) { 
698       TopLoc_Location L(T);
699       res.Move(L);
700     }
701     else {
702       Message_Msg Msg1035("IGES_1035");
703       SendWarning(start,Msg1035);
704     }
705       //AddWarning(start, "Transformation skipped (not a similarity)");
706   }
707
708   return  res;
709 }
710
711
712
713
714 //=======================================================================
715 //function : Transfer2dOffsetCurve
716 //purpose  : 
717 //=======================================================================
718
719 TopoDS_Shape  IGESToBRep_TopoCurve::Transfer2dOffsetCurve
720   (const Handle(IGESGeom_OffsetCurve)&  start,
721         const TopoDS_Face&          face,
722         const gp_Trsf2d& trans,
723         const Standard_Real uFact)
724
725 {
726   TopoDS_Shape  res;
727   if (start.IsNull()) {
728     Message_Msg Msg1005("IGES_1005"); //"Offset Curve Transfer Error : Null IGESEntity"
729     SendFail(start, Msg1005);
730     //AddFail(start, "2D OffsetCurve Transfer Error : Null IGESEntity");
731     return  res;
732   }
733
734   if (start->OffsetType() != 1) {
735     Message_Msg Msg1100("IGES_1100"); //"Offset distance flag different from 1 not treated"
736     SendFail(start,Msg1100);
737   }
738    // AddWarning(start, "Offset distance flag different from 1 not properly treated");
739
740   Standard_Real                Offset = start->FirstOffsetDistance();
741   Handle(IGESData_IGESEntity)  BaseCrv = start->BaseCurve();
742   Handle(Geom2d_Curve)         Crv;
743   Handle(Geom2d_OffsetCurve)   OffCrv;
744
745
746   if (IGESToBRep::IsTopoCurve(BaseCrv)) {
747     IGESToBRep_TopoCurve  TC(*this);
748     TC.SetModeTransfer(Standard_False);
749     TopoDS_Shape  Sh = TC.Transfer2dTopoCurve(BaseCrv, face, trans, uFact);
750     if (Sh.IsNull() || !( (Sh.ShapeType()==TopAbs_EDGE) ||(Sh.ShapeType()==TopAbs_WIRE)) ) {
751       Message_Msg Msg1156("IGES_1156"); //"Edge or wire expected from TransferTopoCurve"
752       Handle(TCollection_HAsciiString) label = GetModel()->StringLabel(BaseCrv);
753       Msg1156.Arg("2D basis curve");
754       Msg1156.Arg(label);
755       SendFail(start,Msg1156);
756       return  res;
757     }
758     
759     if (Sh.ShapeType()==TopAbs_EDGE) {
760       Handle(Geom_Surface)  Srf;
761       TopLoc_Location aLoc; 
762       Standard_Real  a, b;
763       BRep_Tool::CurveOnSurface(TopoDS::Edge(Sh), Crv, Srf, aLoc, a, b);
764       OffCrv = new Geom2d_OffsetCurve(Crv,Offset * uFact);
765       TopoDS_Edge  anEdge;
766       ShapeBuild_Edge().MakeEdge (anEdge, OffCrv, face, start->StartParameter(), start->EndParameter());
767       if (anEdge.IsNull()/*!ME.IsDone()*/) {
768         Message_Msg Msg1005("IGES_1005"); //"Edge construction error"
769         SendFail(start,Msg1005);
770         return  res;
771       }
772       res = anEdge;
773     }
774     else if (Sh.ShapeType()==TopAbs_WIRE) {
775       TopoDS_Wire  aWire = TopoDS::Wire(Sh);
776       Handle(ShapeExtend_WireData) sewd = new ShapeExtend_WireData;
777       for (TopoDS_Iterator Iter(aWire); Iter.More(); Iter.Next()) {
778         TopoDS_Edge  anEdge = TopoDS::Edge(Iter.Value());
779         Handle(Geom_Surface)  Srf;
780         TopLoc_Location  aLoc;  
781         Standard_Real  a, b;
782         BRep_Tool::CurveOnSurface(anEdge, Crv, Srf, aLoc, a, b);
783         OffCrv = new Geom2d_OffsetCurve(Crv,Offset * uFact); 
784         TopoDS_Edge  anotherEdge;
785         ShapeBuild_Edge().MakeEdge (anotherEdge, OffCrv, face, start->StartParameter(), start->EndParameter());
786         if (anotherEdge.IsNull()/*!ME.IsDone()*/) {
787           Message_Msg Msg1005("IGES_1005"); //"Edge construction error"
788           SendFail(start,Msg1005);
789           return  res;
790         }
791         sewd->Add (anotherEdge);
792       }
793       Handle(ShapeFix_Wire) sfw = new ShapeFix_Wire;
794       sfw->Load (sewd);
795       //pdn 10.03.99
796       //sfw.FixConnected (GetEpsGeom() * GetUnitFactor());
797       sfw->FixConnected ();
798       res = sfw->Wire();
799     }
800   }
801   return  res;
802 }
803
804
805 //=======================================================================
806 //function : TransferTopoCurve
807 //purpose  : 
808 //=======================================================================
809
810 TopoDS_Shape  IGESToBRep_TopoCurve::TransferTopoCurve
811 (const Handle(IGESData_IGESEntity)&  start)
812 {
813   TopoDS_Shape  res;
814   
815   if (start.IsNull()) {
816     Message_Msg Msg1005("IGES_1005"); //"TopoCurve Transfer Error : Null IGESEntity"
817     SendFail(start, Msg1005);
818     //AddFail(start, "TopoCurve Transfer Error : Null IGESEntity");
819     return  res;
820   }
821   //S4054
822   if (IGESToBRep::IsBasicCurve(start)) {
823     res = TransferTopoBasicCurve(start);
824   }
825   else if (start->IsKind(STANDARD_TYPE(IGESGeom_CompositeCurve))) {
826     DeclareAndCast(IGESGeom_CompositeCurve, st102, start);
827     res = TransferCompositeCurve(st102);
828   }
829   else if (start->IsKind(STANDARD_TYPE(IGESGeom_CurveOnSurface))) {
830     DeclareAndCast(IGESGeom_CurveOnSurface, st142, start);
831     res = TransferCurveOnSurface(st142);
832   }
833   else if (start->IsKind(STANDARD_TYPE(IGESGeom_Boundary))) {
834     DeclareAndCast(IGESGeom_Boundary, st141, start);
835     res = TransferBoundary(st141);
836   }
837   else if (start->IsKind(STANDARD_TYPE(IGESGeom_Point))) {
838     DeclareAndCast(IGESGeom_Point, st116, start);
839     res = TransferPoint(st116);
840   }
841   else if (start->IsKind(STANDARD_TYPE(IGESGeom_OffsetCurve))) {
842     DeclareAndCast(IGESGeom_OffsetCurve, st130, start);
843     res = TransferOffsetCurve(st130);
844   }
845   else {
846     // This message can not occur.
847     //"Improper type provided to TransferTopoCurve"
848   }  
849   return  res;
850 }
851
852
853 //=======================================================================
854 //function : Transfer2dTopoCurve
855 //purpose  : 
856 //=======================================================================
857
858 TopoDS_Shape  IGESToBRep_TopoCurve::Transfer2dTopoCurve(const Handle(IGESData_IGESEntity)& start,
859                                                         const TopoDS_Face& face,
860                                                         const gp_Trsf2d& trans,
861                                                         const Standard_Real uFact)
862 {
863   TopoDS_Shape  res;
864
865   if (start.IsNull()) {
866     Message_Msg Msg1005("IGES_1005"); //"2d TopoCurve Transfer Error : Null IGESEntity"
867     SendFail(start, Msg1005);
868     //    AddFail(start, "2D TopoCurve Transfer Error : Null IGESEntity");
869     return  res;
870   }
871   //S4054
872   if (IGESToBRep::IsBasicCurve(start)) 
873     res = Transfer2dTopoBasicCurve(start, face, trans, uFact);
874
875   else if (start->IsKind(STANDARD_TYPE(IGESGeom_CompositeCurve))) {
876     DeclareAndCast(IGESGeom_CompositeCurve, st102, start);
877     res = Transfer2dCompositeCurve(st102, face, trans, uFact);
878   }
879   else if (start->IsKind(STANDARD_TYPE(IGESGeom_Point))) {
880     DeclareAndCast(IGESGeom_Point, st116, start);
881     res = Transfer2dPoint(st116);
882   }
883   else if (start->IsKind(STANDARD_TYPE(IGESGeom_OffsetCurve))) {
884     DeclareAndCast(IGESGeom_OffsetCurve, st130, start);
885     res = Transfer2dOffsetCurve(st130, face, trans, uFact);
886   }
887   return  res;
888 }
889
890
891 //=======================================================================
892 //function : TransferTopoBasicCurve
893 //purpose  : 
894 //=======================================================================
895
896 TopoDS_Shape  IGESToBRep_TopoCurve::TransferTopoBasicCurve
897   (const Handle(IGESData_IGESEntity)&  start)
898 {
899   TopoDS_Shape myshape;
900   TopoDS_Edge myedge;
901 //  TopoDS_Vertex V1,V2;
902
903   if (start.IsNull()) {
904     Message_Msg Msg1005("IGES_1005"); //"TopoBasicCurve Transfer Error : Null IGESEntity"
905     SendFail(start, Msg1005);
906     //AddFail(start, "TopoBasicCurve Transfer Error : Null IGESEntity");
907     return  myshape;
908   }
909
910   IGESToBRep_BasicCurve BC(*this);
911   // 14.05.2009 skl for OCC21131
912   BC.SetModeTransfer(Standard_False);
913   Handle(Geom_Curve) C = BC.TransferBasicCurve(start);
914
915   if (C.IsNull()) {
916     // A message has been thrown in TransferBasicCurve
917     return myshape;
918   }
919
920
921 // si la courbe est une BSpline de degre 1, et si l`utilisateur
922 // le souhaite, on approxime
923   TheCurves.Clear();
924   if ((C->IsKind(STANDARD_TYPE(Geom_BSplineCurve)))&& GetModeApprox()) {
925         Handle(Geom_BSplineCurve) BSplineC = Handle(Geom_BSplineCurve)::DownCast(C);
926     if (BSplineC->Degree() == 1) 
927       ApproxBSplineCurve(BSplineC);
928     else
929       TheCurves.Append(C);
930   }
931   else
932     TheCurves.Append(C);
933
934       
935   // Si la courbe est une BSpline, il ne faut pas qu`elle soit C0.
936   // sinon inutilisable dans les algos de topologie ...
937   // on construit un wire avec des morceaux de courbes C1.
938   Standard_Integer nbcurves = NbCurves();
939   if ( nbcurves == 0 ) {
940     Message_Msg Msg1156("IGES_1156"); //"TopoBasicCurve Transfer Error : Null Entity"
941     Handle(TCollection_HAsciiString) label = GetModel()->StringLabel(start);
942     Msg1156.Arg("Geom_Curve");
943     Msg1156.Arg(label);
944     SendFail(start,Msg1156);
945     return  myshape;
946   }
947
948 //  Standard_Real epsgeom = GetEpsGeom()*GetUnitFactor();
949   Handle(ShapeExtend_WireData) sewd = new ShapeExtend_WireData;
950   
951   for (Standard_Integer icurve = 1; icurve <= nbcurves; icurve++) {
952     Handle(Geom_Curve) mycurve = Curve(icurve);
953     if ((mycurve->IsKind(STANDARD_TYPE(Geom_BSplineCurve))) 
954         && (mycurve->Continuity() < GeomAbs_C1)
955         && GetContinuity() >= 1) {
956       Handle(Geom_BSplineCurve) BSplineC = 
957         Handle(Geom_BSplineCurve)::DownCast(mycurve);
958
959       Handle(TColGeom_HSequenceOfBoundedCurve) seqBS;
960       ShapeAlgo::AlgoContainer()->C0BSplineToSequenceOfC1BSplineCurve (BSplineC, seqBS);
961       Standard_Integer NbC0 = seqBS->Length();
962       for (Standard_Integer i = 1; i <= NbC0; i++) {
963         BRepBuilderAPI_MakeEdge ME (seqBS->Value (i));
964         if (!ME.IsDone()) {
965           Message_Msg Msg1005("IGES_1005");
966           SendFail(start,Msg1005);
967           //  AddFail(start, "Edge construction error");
968           return myshape;
969         }
970         myedge = ME.Edge();
971         sewd->Add (myedge);
972       }
973     }
974     else {
975       Standard_Real a = mycurve->FirstParameter(), b = mycurve->LastParameter();
976       if (mycurve->IsKind(STANDARD_TYPE(Geom_TrimmedCurve))) {
977         Handle(Geom_TrimmedCurve) tmp = Handle(Geom_TrimmedCurve)::DownCast (mycurve);
978         mycurve = tmp->BasisCurve();
979       }
980       BRepBuilderAPI_MakeEdge ME (mycurve, a, b);
981       if (!ME.IsDone() || (Precision::IsInfinite(a) || Precision::IsInfinite(b))) {
982         Message_Msg Msg1005("IGES_1005");
983         SendFail(start,Msg1005);
984         //AddFail(start, "Edge construction error");
985         return  myshape;
986       }
987       myedge = ME.Edge();
988       sewd->Add (myedge);
989     } 
990   }
991   
992   Handle(ShapeFix_Wire) sfw = new ShapeFix_Wire;
993   sfw->Load (sewd);
994   //pdn 10.03.99 S4135 Using mintol
995   //sfw.FixConnected (epsgeom);
996   sfw->FixConnected ();
997   myshape = sewd->Wire();
998   
999   //S4054 PRO11414-1.igs entities 56, 80 (self-intersection is hidden only when
1000   //tolerance of vertices is resolution of IGES file)
1001 //  ShapeAnalysis::FindBounds (myshape, V1, V2);
1002 //  BRep_Builder B;
1003 //  B.UpdateVertex (V1, epsgeom);
1004 //  B.UpdateVertex (V2, epsgeom);
1005   // 14.05.2009 skl for OCC21131
1006   // 15.03.2011 emv for OCC22294 begin
1007   Standard_Boolean bIsNeedTransf = start->IsKind(STANDARD_TYPE(IGESGeom_SplineCurve));
1008   if (start->HasTransf() && bIsNeedTransf) {
1009     gp_Trsf  T;
1010     SetEpsilon(1.E-04);
1011     if (IGESData_ToolLocation::ConvertLocation
1012        (GetEpsilon(),start->CompoundLocation(),T, GetUnitFactor())) { 
1013       TopLoc_Location L(T);
1014       myshape.Move(L);
1015     }
1016     else {
1017       Message_Msg Msg1035("IGES_1035");
1018       SendWarning(start,Msg1035);
1019     }
1020     //AddWarning(start, "Transformation skipped (not a similarity)");
1021   }
1022   //15.03.2011 emv for OCC22294 end
1023
1024   // debug mjm du 26/07/96 en attendant developpement meilleur
1025   // sur traitement des Wire et non des Edge dans les programmes appelant
1026   
1027   if (sewd->NbEdges() != 1) {
1028     //S4054    TheBadCase = Standard_True; //:27
1029     Message_Msg Msg1120("IGES_1120");// "Wire not always implemented."
1030     SendWarning(start,Msg1120);
1031     //    AddWarning(start, "Wire not always implemented.");
1032     return myshape;
1033   }
1034   else 
1035     myedge = TopoDS::Edge (TopoDS_Iterator (myshape).Value());
1036
1037   //added by rln 23/12/97 CSR# UKI60155 entity 208 (CircularArc)
1038   //if Starting and Terminating point are the same this can be caused by either error in the file
1039   //(curve with null length) or normal situation (period 2*PI). It is better to look at
1040   // 2d representation
1041   if (start->IsKind(STANDARD_TYPE(IGESGeom_CircularArc)) &&
1042       Handle(IGESGeom_CircularArc)::DownCast (start)->IsClosed())
1043     TheBadCase = Standard_True;
1044
1045   return myedge;
1046 }
1047
1048
1049 //=======================================================================
1050 //function : Transfer2dTopoBasicCurve
1051 //purpose  : 
1052 //=======================================================================
1053
1054 TopoDS_Shape  IGESToBRep_TopoCurve::Transfer2dTopoBasicCurve
1055   (const Handle(IGESData_IGESEntity)& start,
1056                 const TopoDS_Face&    face,
1057                 const gp_Trsf2d&    trans,
1058                 const Standard_Real uFact)
1059 {
1060   TopoDS_Edge  edge, myedge;
1061   TopoDS_Shape myshape;
1062
1063   if (start.IsNull()) {
1064     Message_Msg Msg1005("IGES_1005"); //"2D TopoBasicCurve Transfer Error : Null IGESEntity"
1065     SendFail(start, Msg1005);
1066     //    AddFail(start, "2D TopoBasicCurve Transfer Error : Null IGESEntity");
1067     return  edge;
1068   }
1069   
1070   TopLoc_Location L;
1071   Handle(Geom_Surface) mysurf = BRep_Tool::Surface(face, L);
1072
1073   IGESToBRep_BasicCurve  BC(*this);
1074   BC.SetModeTransfer(Standard_False);
1075                                 // The Trsf must be applied to the Curve2d.
1076
1077   Handle(Geom2d_Curve)  C2d = BC.Transfer2dBasicCurve(start);
1078   if (C2d.IsNull()) {
1079     // A message has been thrown in Transfer2dBasicCurve
1080     //AddFail(start, "Conversion error");
1081     return edge;
1082   }
1083
1084  
1085 // si la courbe est une BSpline de degre 1, on approxime
1086   TheCurves2d.Clear();
1087   if ((C2d->IsKind(STANDARD_TYPE(Geom2d_BSplineCurve)))&& GetModeApprox()){
1088     Handle(Geom2d_BSplineCurve) BSplineC2d = 
1089       Handle(Geom2d_BSplineCurve)::DownCast(C2d);
1090     if (BSplineC2d->Degree() == 1) 
1091       Approx2dBSplineCurve(BSplineC2d);
1092     else
1093       TheCurves2d.Append(C2d);
1094   }
1095   else
1096     TheCurves2d.Append(C2d);
1097
1098
1099   // Si la courbe est une BSpline, il ne faut pas qu`elle soit C0.
1100   // on construit un wire avec des morceaux de courbes C1.
1101   Standard_Integer nbcurves = NbCurves2d();
1102   if ( nbcurves == 0 ) {
1103     Message_Msg Msg1156("IGES_1156"); //"2dTopoBasicCurve Transfer Error : Null Entity"
1104     Handle(TCollection_HAsciiString) label = GetModel()->StringLabel(start);
1105     Msg1156.Arg("Geom2d_Curve");
1106     Msg1156.Arg(label);
1107     SendFail(start,Msg1156);
1108     //AddFail(start, "2dTopoBasicCurve Transfer Error : Null Entity");
1109     return  myshape;
1110   }
1111
1112 //  Standard_Real epsgeom = GetEpsGeom()*GetUnitFactor();
1113   //S4054 Standard_Real epscoeff = GetEpsCoeff();
1114   Handle(ShapeExtend_WireData) sewd = new ShapeExtend_WireData;
1115
1116   for (Standard_Integer icurve = 1; icurve <= nbcurves; icurve++) {
1117     Handle(Geom2d_Curve) mycurve2d = Curve2d(icurve);
1118     //S4054 November 98 Transformation of pcurve in a single place
1119     //(taken from Compute2d3d and Compute2d)
1120 /*    if (isrev) {
1121       //#30 rln 19.10.98 transformation of pcurves for IGES Surface of Revolution
1122       mycurve2d ->Translate (gp_Vec2d (0, -2 * M_PI));
1123       mycurve2d->Mirror (gp::OX2d());
1124       mycurve2d->Mirror (gp_Ax2d (gp::Origin2d(), gp_Dir2d (1.,1.)));
1125       
1126       gp_Trsf2d TR;
1127       TR.SetTranslation (gp_Pnt2d (0.,0.),gp_Pnt2d (-paramu,0.));
1128       mycurve2d->Transform (TR);
1129     }
1130     if (paramv != 0.) {
1131       gp_Trsf2d TR;
1132       TR.SetTranslation (gp_Pnt2d (0.,0.), gp_Pnt2d (0.,paramv));
1133       mycurve2d->Transform (TR);
1134     }*/
1135        
1136     if(trans.Form()!=gp_Identity)
1137       mycurve2d->Transform (trans);
1138     
1139     gp_Trsf2d ntrsf;
1140     if(mysurf->IsKind(STANDARD_TYPE(Geom_Plane))) 
1141       ntrsf.SetScale(gp_Pnt2d(0,0),GetUnitFactor());
1142     
1143     Standard_Real a = mycurve2d->FirstParameter(), b =  mycurve2d->LastParameter();
1144     ShapeBuild_Edge sbe;
1145     mycurve2d = sbe.TransformPCurve (mycurve2d, ntrsf, uFact, a, b);
1146     
1147     if ((mycurve2d->IsKind(STANDARD_TYPE(Geom2d_BSplineCurve))) 
1148         && (mycurve2d->Continuity() < GeomAbs_C1)
1149         && GetContinuity() >= 1) {
1150       Handle(Geom2d_BSplineCurve) BSplineC2d = 
1151         Handle(Geom2d_BSplineCurve)::DownCast(mycurve2d);
1152
1153       Handle(TColGeom2d_HSequenceOfBoundedCurve) seqBS;
1154       ShapeAlgo::AlgoContainer()->C0BSplineToSequenceOfC1BSplineCurve (BSplineC2d, seqBS);
1155       Standard_Integer NbC0 = seqBS->Length();
1156       for (Standard_Integer i = 1; i <= NbC0; i++) {
1157         ShapeBuild_Edge().MakeEdge (myedge, seqBS->Value (i), face);
1158 //      BRepBuilderAPI_MakeEdge ME (seqBS->Value (i), mysurf);
1159         if (myedge.IsNull()/*!ME.IsDone()*/) {
1160           Message_Msg Msg1005("IGES_1005"); //"Edge construction error"
1161           SendFail(start,Msg1005);
1162           //AddFail(start, "Edge construction error");
1163           return myshape;
1164         }
1165 //      myedge = ME.Edge();
1166 //      ShapeBuild_Edge().RemovePCurve (myedge, mysurf);
1167 //      B.UpdateEdge (myedge, seqBS->Value (i), face, 0);
1168         sewd->Add (myedge);
1169       }
1170     }
1171     else {
1172       if (mycurve2d->IsKind(STANDARD_TYPE(Geom2d_TrimmedCurve))) {
1173         Handle(Geom2d_TrimmedCurve) tmp = Handle(Geom2d_TrimmedCurve)::DownCast (mycurve2d);
1174         mycurve2d = tmp->BasisCurve();
1175       }
1176       ShapeBuild_Edge().MakeEdge (myedge, mycurve2d, face, a, b);
1177 //      BRepBuilderAPI_MakeEdge ME (mycurve2d, mysurf);
1178       if (myedge.IsNull()/*!ME.IsDone()*/) {
1179         Message_Msg Msg1005("IGES_1005"); //"Edge construction error"
1180         SendFail(start,Msg1005);
1181         return myshape;
1182       }
1183       //      myedge = ME.Edge();
1184       //      ShapeBuild_Edge().RemovePCurve (myedge, mysurf);
1185       //      B.UpdateEdge (myedge, mycurve2d, face, 0);
1186       sewd->Add (myedge);
1187     }
1188   }
1189   
1190   Handle(ShapeFix_Wire) sfw = new ShapeFix_Wire;
1191   sfw->Load (sewd);
1192   //pdn 10.03.99 S4135
1193   //sfw.FixConnected (epsgeom);
1194   sfw->FixConnected ();
1195   myshape = sewd->Wire();
1196
1197 //  TopoDS_Vertex V1,V2;
1198 //  ShapeAnalysis::FindBounds (myshape, V1, V2);
1199 //  B.UpdateVertex (V1, epsgeom);
1200 //  B.UpdateVertex (V2, epsgeom);
1201
1202   // debug mjm du 26/07/96 en attendant developpement meilleur
1203   // sur traitement des Wire et non des Edge dans les programmes appelant
1204
1205   if (sewd->NbEdges() != 1) {
1206     //S4054 TheBadCase = Standard_True; //:27
1207     Message_Msg Msg1120("IGES_1120");// "Wire not always implemented."
1208     SendWarning(start,Msg1120);
1209 //    AddWarning(start, "Wire not always implemented.");
1210     return myshape;
1211   }
1212
1213   //the same modifications as in TransferBasicCurve()
1214   if (start->IsKind(STANDARD_TYPE(IGESGeom_CircularArc)) &&
1215       Handle(IGESGeom_CircularArc)::DownCast (start)->IsClosed())
1216     TheBadCase = Standard_True;
1217
1218   return myedge;
1219 }
1220
1221
1222 //=======================================================================
1223 //function : TransferBoundary
1224 //purpose  : 
1225 //=======================================================================
1226
1227 TopoDS_Shape  IGESToBRep_TopoCurve::TransferBoundary
1228   (const Handle(IGESGeom_Boundary)& start)
1229 {  
1230   TopoDS_Shape  res;
1231   if (start.IsNull()) {
1232     Message_Msg Msg1005("IGES_1005"); //"Boundary Transfer Error : Null IGESEntity"
1233     SendFail(start, Msg1005);
1234     //AddFail(start, "Boundary Transfer Error : Null IGESEntity");
1235     return  res;
1236   }
1237
1238   if (start->BoundaryType()==0) {
1239     Message_Msg Msg1125("IGES_1125"); //"Model space representation not implemented"
1240     SendFail(start,Msg1125);
1241     //AddFail(start, "Model space representation not implemented");
1242     return res;
1243   }
1244
1245   //  Transfer of the unbounded surface
1246   //  =================================
1247
1248   Handle (IGESData_IGESEntity) igesSurface = start->Surface();
1249   if (igesSurface.IsNull() || !IGESToBRep::IsTopoSurface(igesSurface) ) {
1250     Message_Msg Msg124("XSTEP_124"); //"BasicSurface Transfer Error : Null IGESEntity"
1251     SendFail(start,Msg124);
1252     //    AddFail(start, "BasicSurface Transfer Error : Null IGESEntity");
1253     return res;
1254   }
1255  
1256   TopoDS_Face  face;
1257   TopAbs_ShapeEnum shapeEnum;
1258   IGESToBRep_TopoSurface TS(*this);
1259   gp_Trsf2d trans;
1260   Standard_Real uFact;
1261   TopoDS_Shape myshape = TS.ParamSurface(igesSurface, trans, uFact);
1262
1263   if (!myshape.IsNull()) {
1264     shapeEnum = myshape.ShapeType();
1265     switch (shapeEnum) {
1266     case TopAbs_FACE :
1267       {
1268         face = TopoDS::Face(myshape);
1269         break;
1270       }
1271     case TopAbs_SHELL :
1272       {
1273         TopoDS_Iterator IT(myshape);
1274         Standard_Integer nbfaces = 0;
1275         for (; IT.More(); IT.Next()) {
1276           nbfaces++;
1277           face = TopoDS::Face(IT.Value());
1278         }
1279         //szv#4:S4163:12Mar99 optimized
1280         if (nbfaces != 1) {
1281            Message_Msg Msg1061("IGES_1061"); //"Not Implemented Trimmed Composite Surface."
1282             SendFail(start,Msg1061);
1283           //AddFail(start,"Not Implemented Trimmed Composite Surface.");
1284           return res;
1285         }
1286       }
1287       break;
1288     default:
1289       {
1290         Message_Msg Msg1156("IGES_1156"); //"Basis Surface Error." ?? Msg1066
1291         Handle(TCollection_HAsciiString) label = GetModel()->StringLabel(igesSurface);
1292         Msg1156.Arg("basic surface");
1293         Msg1156.Arg(label);
1294         SendFail(start,Msg1156);
1295         //      AddFail(start, "Basis Surface Error.");
1296         return res;
1297       }
1298     }
1299   }
1300
1301   face.EmptyCopy();
1302   res = TransferBoundaryOnFace(face, start, trans, uFact);
1303   return res;
1304 }
1305
1306
1307
1308 //=======================================================================
1309 //function : TransferBoundaryOnFace
1310 //purpose  : 
1311 //=======================================================================
1312
1313 TopoDS_Shape IGESToBRep_TopoCurve::TransferBoundaryOnFace(TopoDS_Face&  face, 
1314                                                           const Handle(IGESGeom_Boundary)& start, 
1315                                                           const gp_Trsf2d& trans,
1316                                                           const Standard_Real uFact)
1317 {
1318   TopoDS_Shape  res;  
1319   if (start.IsNull()) {
1320     Message_Msg Msg1005("IGES_1005"); //"BoundaryOnFace Transfer Error : Null IGESEntity"
1321     SendFail(start,Msg1005);
1322     return res;
1323   }
1324
1325   Standard_Boolean okCurve = Standard_True, okCurve3d = Standard_True, okCurve2d = Standard_True;
1326   Standard_Integer filepreference = 0;
1327   if      (start->PreferenceType() == 2) filepreference = 2;
1328   else if (start->PreferenceType() == 1) filepreference = 3;
1329   Standard_Boolean Result = Standard_True;
1330
1331   Handle(IGESToBRep_IGESBoundary) IB = IGESToBRep::AlgoContainer()->ToolContainer()->IGESBoundary();
1332   IB->Init (*this, start, face, trans, uFact, filepreference);
1333   for (Standard_Integer i = 1; i <= start->NbModelSpaceCurves(); i++) {
1334     Handle(IGESData_HArray1OfIGESEntity) Curves2d;
1335     if (start->NbParameterCurves(i) == 0 && start->BoundaryType() == 1) {
1336       Message_Msg Msg1135("IGES_1135");  
1337       Msg1135.Arg(2); 
1338       Msg1135.Arg(3); 
1339       SendWarning(start,Msg1135);
1340     } 
1341     else
1342       Curves2d = start->ParameterCurves(i);
1343     Result = Result & IB->Transfer (okCurve, okCurve3d, okCurve2d,
1344                                     start->ModelSpaceCurve(i), start->Sense(i) == 2,
1345                                     Curves2d, i);
1346   }
1347   IB->Check(Result, Standard_True, okCurve3d, okCurve2d);
1348   Handle(ShapeExtend_WireData) sewd = IB->WireData();
1349   if (sewd->NbEdges() == 0) {
1350      Message_Msg Msg1095("IGES_1095");//"Both 2d and 3d representations are invalid"
1351      SendFail(start,Msg1095);
1352     return res;
1353   }
1354
1355   //#20 rln 14/05/98 buc40130 entity 16977
1356   //first wire should be outer, all other are inner
1357   //%14 pdn 03.03.99
1358   // IB.Fix (sewd, Standard_True, Standard_True, Standard_False, Standard_False, Standard_False);
1359   TopoDS_Wire mywire = sewd->Wire();
1360
1361   if (start->HasTransf()) {
1362     gp_Trsf T;
1363     SetEpsilon(1.E-04);
1364     if (IGESData_ToolLocation::ConvertLocation
1365         (GetEpsilon(), start->CompoundLocation(),T)) { 
1366       TopLoc_Location L(T);
1367       mywire.Move(L);
1368     }
1369     else {
1370       Message_Msg Msg1035("IGES_1035"); //"Transformation skipped (not a similarity)"
1371       SendWarning(start,Msg1035);
1372     }
1373   }
1374   BRep_Builder B;
1375   B.Add(face,mywire);
1376   SetShapeResult (start, mywire);
1377   return mywire;
1378 }
1379
1380 //=======================================================================
1381 //function : ApproxBSplineCurve
1382 //purpose  : 
1383 //=======================================================================
1384
1385 void IGESToBRep_TopoCurve::ApproxBSplineCurve
1386        (const Handle(Geom_BSplineCurve)& start)
1387          
1388 {
1389   ShapeAlgo::AlgoContainer()->ApproxBSplineCurve (start, TheCurves);
1390 }
1391
1392
1393 //=======================================================================
1394 //function : NbCurves
1395 //purpose  : Returns the count of produced Curves
1396 //=======================================================================
1397 Standard_Integer  IGESToBRep_TopoCurve::NbCurves () const
1398 {
1399   return TheCurves.Length();
1400 }
1401
1402
1403 //=======================================================================
1404 //function : Curve
1405 //purpose  : Returns a Curvee given its rank
1406 //=======================================================================
1407 Handle(Geom_Curve)  IGESToBRep_TopoCurve::Curve (const Standard_Integer num) const
1408 {
1409   Handle(Geom_Curve) res;
1410   if (num > 0 && num <= TheCurves.Length()) res = TheCurves.Value(num);
1411   return res;
1412 }
1413
1414
1415 //=======================================================================
1416 //function : Approx2dBSplineCurve
1417 //purpose  : 
1418 //=======================================================================
1419
1420 void IGESToBRep_TopoCurve::Approx2dBSplineCurve
1421        (const Handle(Geom2d_BSplineCurve)& start)
1422          
1423 {
1424   ShapeAlgo::AlgoContainer()->ApproxBSplineCurve (start, TheCurves2d);
1425 }
1426
1427
1428 //=======================================================================
1429 //function : NbCurves2d
1430 //purpose  : Returns the count of produced Curves
1431 //=======================================================================
1432 Standard_Integer  IGESToBRep_TopoCurve::NbCurves2d () const
1433 {
1434   return TheCurves2d.Length();
1435 }
1436
1437
1438 //=======================================================================
1439 //function : Curve2d
1440 //purpose  : Returns a Curve given its rank
1441 //=======================================================================
1442 Handle(Geom2d_Curve)  IGESToBRep_TopoCurve::Curve2d (const Standard_Integer num) const
1443 {
1444   Handle(Geom2d_Curve) res;
1445   if (num > 0 && num <= TheCurves2d.Length()) res = TheCurves2d.Value(num);
1446   return res;
1447 }
1448
1449 //=======================================================================
1450 //function : SetBadCase
1451 //purpose  : 
1452 //=======================================================================
1453
1454  void IGESToBRep_TopoCurve::SetBadCase (const Standard_Boolean value)
1455 {
1456   TheBadCase = value;
1457 }
1458
1459 //=======================================================================
1460 //function : BadCase
1461 //purpose  : 
1462 //=======================================================================
1463
1464  Standard_Boolean IGESToBRep_TopoCurve::BadCase () const
1465 {
1466   return TheBadCase;
1467 }