0024157: Parallelization of assembly part of BO
[occt.git] / src / StepToTopoDS / StepToTopoDS_TranslateEdge.cxx
1 // Created on: 1995-01-03
2 // Created by: Frederic MAUPAS
3 // Copyright (c) 1995-1999 Matra Datavision
4 // Copyright (c) 1999-2012 OPEN CASCADE SAS
5 //
6 // The content of this file is subject to the Open CASCADE Technology Public
7 // License Version 6.5 (the "License"). You may not use the content of this file
8 // except in compliance with the License. Please obtain a copy of the License
9 // at http://www.opencascade.org and read it completely before using this file.
10 //
11 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
12 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
13 //
14 // The Original Code and all software distributed under the License is
15 // distributed on an "AS IS" basis, without warranty of any kind, and the
16 // Initial Developer hereby disclaims all such warranties, including without
17 // limitation, any warranties of merchantability, fitness for a particular
18 // purpose or non-infringement. Please see the License for the specific terms
19 // and conditions governing the rights and limitations under the License.
20
21 //:o0 abv 16.02.99: POLYLINE allowed as 3d curve of edge
22 //gka,abv 05.04.99: S4136: improving tolerance management, eliminate BRepAPI::Precision()
23
24 #include <StepToTopoDS_TranslateEdge.ixx>
25
26 #include <StepToTopoDS.hxx>
27 #include <StepToTopoDS_TranslateVertex.hxx>
28 #include <StepToTopoDS_GeometricTool.hxx>
29 #include <StepToGeom_MakeCurve.hxx>
30
31 #include <TopoDS.hxx>
32 #include <TopoDS_Edge.hxx>
33 #include <BRep_Builder.hxx>
34 #include <BRep_Tool.hxx>
35 #include <BRepLib.hxx>
36 #include <BRepLib_MakeEdge.hxx>
37 #include <Geom_Curve.hxx>
38 #include <GeomAbs_Shape.hxx>
39
40 #include <Geom_Line.hxx>
41 #include <gp_Vec.hxx>
42 #include <gp_Dir.hxx>
43 #include <gp_Lin.hxx>
44
45 #include <ShapeAnalysis_Curve.hxx>
46 #include <ShapeConstruct_Curve.hxx>
47
48 #include <StepShape_EdgeCurve.hxx>
49 #include <StepShape_OrientedEdge.hxx>
50 #include <StepGeom_Curve.hxx>
51 //#include <StepGeom_Polyline.hxx>
52 #include <StepGeom_Pcurve.hxx>
53 #include <StepGeom_SurfaceCurve.hxx>
54 #include <Transfer_TransientProcess.hxx>
55 //#include <TransferBRep.hxx>
56
57 #include <GeomAdaptor_Curve.hxx>
58 #include <GCPnts_AbscissaPoint.hxx>
59 #include <Precision.hxx>
60
61 #include <StepToGeom_MakeCurve2d.hxx>
62 #include <StepRepr_DefinitionalRepresentation.hxx>
63 #include <UnitsMethods.hxx>
64
65 //:d8
66 #include <StepShape_VertexPoint.hxx>
67 #include <StepGeom_CartesianPoint.hxx>
68 #include <StepToGeom_MakeCartesianPoint.hxx>
69 #include <Geom_CartesianPoint.hxx>
70
71 // Used in I-DEAS-like STP processing (ssv; 15.11.2010)
72 #include <TCollection_HAsciiString.hxx>
73
74 //#define DEBUG
75
76
77 // ============================================================================
78 // Method  : DecodeMakeEdgeError
79 // Purpose : 
80 // ============================================================================
81
82 static void DecodeMakeEdgeError(const BRepLib_MakeEdge&   ME,
83                                 const Handle(Standard_Transient)& orig,
84                                 const Handle(Geom_Curve)& myCurve,
85                                 const TopoDS_Vertex&      V1,
86                                 const TopoDS_Vertex&      V2,
87                                 const Standard_Real&    /*U1*/,
88                                 const Standard_Real&    /*U2*/,
89                                 StepToTopoDS_Tool&   aTool,
90                                 const Handle(StepShape_TopologicalRepresentationItem)& /*tobind*/)
91 {
92   Handle(Transfer_TransientProcess) TP = aTool.TransientProcess();
93 //  if (!myCurve.IsNull() && !tobind.IsNull()) {
94 //    TransferBRep::SetShapeResult
95 //      (TP,tobind, MakeEdge(myCurve,V1,V2,U1,U2,BRepAPI::Precision()) );
96 //    aTool.Bind (tobind,E);  SURTOUT PAS : noter pour debug/erreur
97 //  }
98 #ifdef DEBUG
99   cout << "------------------------------------" << endl;
100   cout << "MakeEdge Error  : " << ME.Error()<<" - ";
101 #endif
102   switch(ME.Error())
103     {
104     case (BRepLib_EdgeDone): return;
105     case (BRepLib_PointProjectionFailed):
106       TP->AddFail(orig," Point Projection failed");
107       break;
108     case (BRepLib_ParameterOutOfRange):
109       TP->AddFail(orig," Parameter Out Of Range");
110       break;
111     case (BRepLib_DifferentPointsOnClosedCurve):
112       TP->AddFail(orig," Different Points on Closed Curve");
113       break;
114     case (BRepLib_PointWithInfiniteParameter):
115       TP->AddFail(orig," Point with infinite Parameter");
116       break;
117     case (BRepLib_DifferentsPointAndParameter):
118       if (!ShapeConstruct_Curve().AdjustCurve
119           (myCurve,BRep_Tool::Pnt(V1),BRep_Tool::Pnt(V2),Standard_True,Standard_True))
120         TP->AddFail(orig," Different Points and Parameters");
121        else TP->AddWarning(orig,"Different Points and Parameters, adjusted");
122       break;
123     case (BRepLib_LineThroughIdenticPoints):
124       TP->AddFail(orig," Line through identic Points");
125       break;
126     }
127 #ifdef DEBUG
128   cout << "Original Type   : " << orig->DynamicType() << endl;
129   cout << "3D Curve Type   : " << myCurve->DynamicType() << endl;
130   cout << "First Parameter : " << U1 << endl;
131   gp_Pnt p1 = BRep_Tool::Pnt(V1);
132 //  cout << "First Point     : ";
133   cout << "First Vertex    : "<<p1.X()<<"  "<<p1.Y()<<"  "<<p1.Z()<<"  ";
134   cout << "Distance Point - Vertex : ";
135   Standard_Real d1 = p1.Distance(myCurve->Value(U1)); 
136   cout << d1 << endl;
137   cout << "Last  Parameter : " << U2 << endl;
138   gp_Pnt p2 = BRep_Tool::Pnt(V2);
139 //  cout << "Last  Point     : ";
140   cout << "Last  Vertex    : "<<p2.X()<<"  "<<p2.Y()<<"  "<<p2.Z()<<"  ";
141   cout << "Distance Point - Vertex : ";
142   Standard_Real d2 = BRep_Tool::Pnt(V2).Distance(myCurve->Value(U2)); 
143   cout << d2 << endl;
144 #endif
145 }
146
147 // ============================================================================
148 // Method  : StepToTopoDS_TranslateEdge::StepToTopoDS_TranslateEdge
149 // Purpose : Empty Constructor
150 // ============================================================================
151
152 static Handle(Geom_Curve) MakeCurve
153   (const Handle(StepGeom_Curve)& C1, const Handle(Transfer_TransientProcess) TP)
154 {
155   Handle(Geom_Curve) C2 = Handle(Geom_Curve)::DownCast (TP->FindTransient(C1));
156   if (!C2.IsNull()) return C2;
157   if (StepToGeom_MakeCurve::Convert(C1,C2))
158     TP->BindTransient (C1,C2);
159   return C2;
160 }
161
162 static TopoDS_Edge  MakeEdge
163   (const Handle(Geom_Curve)& C3D,
164    const TopoDS_Vertex& V1, const TopoDS_Vertex& V2,
165    const Standard_Real U1, const Standard_Real U2) //, const Standard_Real preci)
166 {
167 //  fait son edge quoi qu il arrive
168   BRep_Builder B;
169   TopoDS_Edge E;
170   B.MakeEdge (E,C3D,Precision::Confusion());//preci);
171   B.Add (E,V1);  B.Add (E,V2);
172   B.UpdateVertex(V1, U1, E, 0.);//preci);
173   B.UpdateVertex(V2, U2, E, 0.);//preci);
174   return E;
175 }
176
177 StepToTopoDS_TranslateEdge::StepToTopoDS_TranslateEdge()
178 {
179   done = Standard_False;
180 }
181
182 // ============================================================================
183 // Method  : StepToTopoDS_TranslateEdge::StepToTopoDS_TranslateEdge()
184 // Purpose : Constructor with an Edge and a Tool
185 // ============================================================================
186
187 StepToTopoDS_TranslateEdge::StepToTopoDS_TranslateEdge(const Handle(StepShape_Edge)& E, 
188                                                        StepToTopoDS_Tool& T, 
189                                                        StepToTopoDS_NMTool& NMTool)
190 {
191   Init(E, T, NMTool);
192 }
193
194 // ============================================================================
195 // Method  : Init
196 // Purpose : Init with an Edge and a Tool.
197 //           This method builds an Edge With 2 Vertices and 2 Parameters.
198 //           The Edge is always build like FORWARD (BRepLib_MakeEdge)
199 // ============================================================================
200
201 void StepToTopoDS_TranslateEdge::Init(const Handle(StepShape_Edge)& aEdge, 
202                                       StepToTopoDS_Tool& aTool,
203                                       StepToTopoDS_NMTool& NMTool)
204 {
205   Handle(Transfer_TransientProcess) TP = aTool.TransientProcess();
206
207   Handle(StepShape_OrientedEdge) OE = 
208     Handle(StepShape_OrientedEdge)::DownCast(aEdge);
209   Handle(StepShape_Edge) wEdge = aEdge;
210   if ( ! OE.IsNull() ) wEdge = OE->EdgeElement();
211   Handle(StepShape_EdgeCurve) EC = Handle(StepShape_EdgeCurve)::DownCast(wEdge);
212   
213   if (aTool.IsBound(EC)) {
214     myResult = aTool.Find(EC);
215     if (BRep_Tool::Degenerated(TopoDS::Edge(myResult))) {
216       TP->AddWarning(EC,"Degenerated Edge in several faces : transferred for each face");
217     }
218     else {
219       myError  = StepToTopoDS_TranslateEdgeDone;
220       done     = Standard_True;
221 //      BRep_Builder B;
222 //:S4136      B.SameRange(TopoDS::Edge(myResult), Standard_False);    //:a5 abv 11 Feb 98
223 //:S4136      B.SameParameter(TopoDS::Edge(myResult), Standard_False);//:a5
224       return;
225     }
226   }
227
228   // [BEGIN] Proceed with non-manifold cases (ssv; 12.11.2010)
229   if ( NMTool.IsActive() && NMTool.IsBound(EC) ) {
230     TopoDS_Shape existingShape = NMTool.Find(EC);
231     // Reverse shape's orientation if needed
232     if ( !OE->Orientation() )
233       existingShape.Reverse();
234     myResult = existingShape;
235     myError = StepToTopoDS_TranslateEdgeDone;
236     done = Standard_True;
237     return;
238   }
239   // [END] Proceed with non-manifold cases (ssv; 12.11.2010)
240
241   // [BEGIN] Proceed with I-DEAS-like STP (ssv; 15.11.2010)
242   const Handle(TCollection_HAsciiString) anECName = EC->Name();
243   if ( NMTool.IsIDEASCase() && !anECName.IsNull() && !anECName->IsEmpty() &&
244        NMTool.IsBound(anECName->String()) ) {
245     TopoDS_Shape existingShape = NMTool.Find(anECName->String());
246     // Reverse shape's orientation if needed
247     if ( !OE->Orientation() )
248       existingShape.Reverse();
249     // Register Edge for final processing (I-DEAS case)
250     NMTool.RegisterNMEdge(existingShape);
251     myResult = existingShape;
252     myError = StepToTopoDS_TranslateEdgeDone;
253     done = Standard_True;
254     return;
255   }
256   // [END] Proceed with I-DEAS-like STP (ssv; 15.11.2010)
257
258   BRep_Builder B;
259
260 //  Standard_Real preci = BRepAPI::Precision();
261
262 //  Standard_Real precision = BRepAPI::Precision();
263
264   Handle(StepGeom_Curve) C = EC->EdgeGeometry();
265   TopoDS_Edge E;
266   Handle(StepShape_Vertex) Vstart, Vend;
267
268   // -----------------------------------------------------------
269   // Extract the start and end Vertices corresponding to FORWARD
270   // (following the geometrical sense)
271   // -----------------------------------------------------------
272
273 //  Standard_Boolean OrientedEdgeOrientation = OE->Orientation();
274   Standard_Boolean EdgeCurveSameSense      = EC->SameSense();
275   
276   if (EdgeCurveSameSense) {
277     Vstart = EC->EdgeStart();
278     Vend   = EC->EdgeEnd();
279   }
280   else {
281     Vend   = EC->EdgeStart();
282     Vstart = EC->EdgeEnd();
283   }
284
285   TopoDS_Vertex V1, V2;
286
287   StepToTopoDS_TranslateVertex myTranVertex1(Vstart, aTool, NMTool);
288   StepToTopoDS_TranslateVertex myTranVertex2(Vend, aTool, NMTool);
289
290   if (myTranVertex1.IsDone()) {
291     V1 = TopoDS::Vertex(myTranVertex1.Value());
292     V1.Orientation(TopAbs_FORWARD);
293   }
294   if (Vend == Vstart) {
295     V2 = V1;
296     V2.Orientation(TopAbs_REVERSED);
297   }
298   else if (myTranVertex2.IsDone()) {
299     V2 = TopoDS::Vertex(myTranVertex2.Value());
300     V2.Orientation(TopAbs_REVERSED);
301   }
302   done = Standard_True;
303   
304   // ----------------------------------------------------------
305   // --- The EdgeCurve Geometry is of StepGeom_Curve Type
306   // --- It can be : * a Pcurve : no 3D curve is constructed
307   // ---             * a Surface Curve, Intersection Curve
308   // ---               or a Seam Curve
309   // ---             * a 3D Curve
310   // ----------------------------------------------------------
311   
312   if ( C->IsKind(STANDARD_TYPE(StepGeom_Pcurve))) {
313     B.MakeEdge(E);
314 //:S4136    B.UpdateEdge (E,preci);
315     B.Add(E, V1);    // ?? en fin de TranslateEdgeLoop
316     B.Add(E, V2);
317   }
318   else if (C->IsKind(STANDARD_TYPE(StepGeom_SurfaceCurve)) ) {
319     // qui reprend les types SeamCurve et IntersectionCurve
320     // --- The Edge Geometry is a Surface Curve ---
321     // ---     (3d + 2 Pcurve Or Surface)       ---
322     Handle(StepGeom_SurfaceCurve) Sc =
323       Handle(StepGeom_SurfaceCurve)::DownCast(C);
324     Handle(StepGeom_Curve) C1 = Sc->Curve3d();
325 //    if (C1->IsKind(STANDARD_TYPE(StepGeom_Polyline))) {
326 //    B.MakeEdge(E);
327 //      B.UpdateEdge (E,preci);
328 //      B.Add(E, V1);    // ?? en fin de TranslateEdgeLoop
329 //      B.Add(E, V2);
330 //    }
331 //    else {
332       MakeFromCurve3D (C1,EC,Vend,Precision(), E,V1,V2 , aTool);
333 //    }
334   }
335 //  else if (C->IsKind(STANDARD_TYPE(StepGeom_Polyline))) {
336 //    B.MakeEdge(E);
337 //    B.UpdateEdge (E,preci);
338 //    B.Add(E, V1);    // ?? en fin de TranslateEdgeLoop
339 //    B.Add(E, V2);
340 //  }
341   else {
342     // --- The Edge Geometry is a Single 3d Curve ---
343     MakeFromCurve3D (C,EC,Vend,Precision(), E,V1,V2 , aTool);
344   }
345   // On force les flags SameRange et SameParameter a Standard_False
346   if (done) {
347 //:S4136    B.SameRange(E, Standard_False);
348 //:S4136    B.SameParameter(E, Standard_False);
349     aTool.Bind(EC,E);
350
351     // Bind Edge in NM tool (ssv; 15.11.2010)
352     if ( NMTool.IsActive() ) {
353       NMTool.Bind(EC, E);
354       if ( NMTool.IsIDEASCase() && !anECName.IsNull() && !anECName->IsEmpty() )
355         NMTool.Bind(anECName->String(), E);
356     }
357
358     myResult = E;
359     myError = StepToTopoDS_TranslateEdgeDone;
360   }
361 }
362
363
364 // ============================================================================
365 // Method  : MakeFromCurve3D
366 // Purpose : case of a Curve 3D (alone or in SurfaceCurve)
367 // ============================================================================
368
369 // auxiliary function
370 //:e6 abv 16 Apr 98: ProSTEP TR8, r0601_sy.stp, #14907
371 static void GetCartesianPoints ( const Handle(StepShape_EdgeCurve)& EC, 
372                                  gp_Pnt &P1, gp_Pnt &P2)
373 {
374   for ( Standard_Integer i=1; i<=2; i++ ) {
375     const Handle(StepShape_Vertex) V = ( (Standard_Boolean)(i==1) == EC->SameSense() ? EC->EdgeStart() : EC->EdgeEnd() );
376     const Handle(StepShape_VertexPoint) VP = Handle(StepShape_VertexPoint)::DownCast(V);
377     if ( VP.IsNull() ) continue;
378     const Handle(StepGeom_CartesianPoint) P = Handle(StepGeom_CartesianPoint)::DownCast(VP->VertexGeometry());
379     Handle(Geom_CartesianPoint) CP;
380     StepToGeom_MakeCartesianPoint::Convert(P,CP);
381         ( i==1 ? P1 : P2 ) = CP->Pnt();
382   }
383 }
384
385 void  StepToTopoDS_TranslateEdge::MakeFromCurve3D
386   (const Handle(StepGeom_Curve)& C3D, const Handle(StepShape_EdgeCurve)& EC,
387    const Handle(StepShape_Vertex)&  Vend,
388    const Standard_Real preci, TopoDS_Edge& E,
389    TopoDS_Vertex& V1, TopoDS_Vertex& V2,
390    StepToTopoDS_Tool&   aTool)
391 {
392   Handle(Transfer_TransientProcess) TP = aTool.TransientProcess();
393   Handle(Geom_Curve) C1 = MakeCurve(C3D,TP);
394   if (C1.IsNull()) {
395     TP->AddFail(C3D," Make Geom_Curve (3D) failed");
396     myError = StepToTopoDS_TranslateEdgeOther;
397     done = Standard_False;
398     return;
399   }
400     // -- Statistics -- -> No Warning message
401   aTool.AddContinuity (C1);
402   BRep_Builder B;
403   Standard_Real temp1,temp2, U1,U2;
404   gp_Pnt pproj;
405   gp_Pnt pv1 = BRep_Tool::Pnt(V1);
406   gp_Pnt pv2 = BRep_Tool::Pnt(V2);
407
408   //:e6 abv
409   gp_Pnt pnt1 = pv1, pnt2 = pv2;
410   if ( V1.IsSame ( V2 ) ) GetCartesianPoints ( EC, pnt1, pnt2 );
411   ShapeAnalysis_Curve sac;
412   temp1 = sac.Project (C1,pnt1,preci,pproj,U1,Standard_False);
413   temp2 = sac.Project (C1,pnt2,preci,pproj,U2,Standard_False);
414
415   if (!StepToTopoDS_GeometricTool::UpdateParam3d(C1, U1, U2, preci))
416     TP->AddWarning(C3D,"Update of 3D-Parameters has failed");
417
418   //:d5: instead of AdjustCurve above which is incorrect if U1 and U2 are not ends
419   gp_Pnt pU1 = C1->Value ( U1 ), pU2 = C1->Value ( U2 );
420   temp1 = pU1.Distance ( pv1 );
421   temp2 = pU2.Distance ( pv2 );
422   if ( temp1 > preci || temp2 > preci ) {
423     TP->AddWarning (C3D,"Poor result from projection vertex / curve 3d");
424   }
425   B.UpdateVertex ( V1, 1.000001*temp1 ); //:h6 abv 14 Jul 98: PRO8845 #2746: *=1.0001
426   B.UpdateVertex ( V2, 1.000001*temp2 ); //:h6
427   
428   BRepLib_MakeEdge ME(C1, V1, V2, U1, U2);
429   if (ME.IsDone()) {
430     E = ME.Edge();
431     B.Range ( E, U1, U2 ); // abv 14 Mar 00: trj3_pm1-ug.stp #91739, edge 2
432   }
433   else {
434     if (ME.Error() == BRepLib_DifferentPointsOnClosedCurve) {
435       // The Edge could be closed and trimmed by 2 Differents
436       // Vertices
437       if (C1->IsClosed()) {
438         // Attention : il faudra mettre a jour la topologie des
439         // vertex pour avoir des edges cul a cul ...... Good Luck!
440         aTool.Bind (Vend,V1);
441         TopoDS_Shape aLocalShape = V1.Reversed();
442         V2 = TopoDS::Vertex(aLocalShape);
443         ME.Init(C1, V1, V2, U1, U2);
444         if (ME.IsDone()) {
445           TP->AddWarning(EC, "Wrong topology corrected : Closed Edge with TWO different Vertices");
446           E = ME.Edge();
447         }
448         else {
449           DecodeMakeEdgeError(ME, C3D, C1, V1, V2, U1, U2, aTool, EC);
450           E = MakeEdge (C1,V1,V2,U1,U2);//preci
451           myError = StepToTopoDS_TranslateEdgeDone; // ????
452           done = Standard_True;
453           //            return;               
454         }
455       }
456       else {
457         // Then, this is should be coded as degenerated
458         // To be performed later !!!
459 //         DecodeMakeEdgeError(ME, C3D, C1, V1, V2, U1, U2, aTool, EC);
460         myError = StepToTopoDS_TranslateEdgeDone; // ????
461         //  Bon, on la fait cette petite edge, mais faudra repasser
462         //  pour l enlever ET FUSIONNER LES VERTEX, pour tout le shell !
463         //  courbe trop petite pour etre mise -> fait planter
464         done = Standard_True;
465         if (!V1.IsSame(V2)) {
466           TP->AddFail(EC, "This edge has null arc length");
467           gp_Pnt P1 = BRep_Tool::Pnt(V1);
468           gp_Pnt P2 = BRep_Tool::Pnt(V2);
469           gp_Vec avec (P1,P2);  gp_Dir adir (avec);  gp_Lin alin (P1,adir);
470           C1 = new Geom_Line (alin);
471           U1 = 0.;  U2 = P1.Distance(P2);
472           E = MakeEdge (C1,V1,V2,U1,U2);//,preci
473         } 
474         else {
475           TP->AddFail(EC,"NULL EDGE, SKIPPED");
476           myResult.Nullify();
477           return;         
478         }
479       }
480     }
481     else {
482       DecodeMakeEdgeError(ME, C3D, C1, V1, V2, U1, U2, aTool, EC);
483       E = MakeEdge (C1,V1,V2,U1,U2);//,preci
484       myError = StepToTopoDS_TranslateEdgeDone; // ????
485       done = Standard_True;
486     }
487   }
488 }
489
490
491 // ============================================================================
492 // Method  : MakePCurve
493 // Purpose : Computes an individual pcurve (i.e. curve 2d)
494 // ============================================================================
495 Handle(Geom2d_Curve)  StepToTopoDS_TranslateEdge::MakePCurve
496   (const Handle(StepGeom_Pcurve)& PCU, const Handle(Geom_Surface)& ConvSurf) const
497 {
498   Handle(Geom2d_Curve) C2d;
499   const Handle(StepRepr_DefinitionalRepresentation) DRI = PCU->ReferenceToCurve();
500   if( DRI.IsNull()) return C2d;
501   const Handle(StepGeom_Curve) StepCurve = Handle(StepGeom_Curve)::DownCast(DRI->ItemsValue(1));
502   if (StepToGeom_MakeCurve2d::Convert(StepCurve,C2d)) {
503     // -- if the surface is a RectangularTrimmedSurface, 
504     // -- send the BasisSurface.
505     C2d = UnitsMethods::DegreeToRadian(C2d, ConvSurf);
506   }
507   return C2d;
508 }
509
510
511 // ============================================================================
512 // Method  : Value
513 // Purpose : Returns the mapped edge
514 // ============================================================================
515
516 const TopoDS_Shape& StepToTopoDS_TranslateEdge::Value() const 
517 {
518   StdFail_NotDone_Raise_if(!done,"");
519   return myResult;
520 }
521
522 // ============================================================================
523 // Method  : Error
524 // Purpose : Returns the error code
525 // ============================================================================
526
527 StepToTopoDS_TranslateEdgeError StepToTopoDS_TranslateEdge::Error() const
528 {
529   return myError;
530 }