0024107: BRepAlgo::ConcatenateWireC0 method doesn't work on a translated wire
[occt.git] / src / BRepAlgo / BRepAlgo.cxx
1 // Created on: 1997-03-10
2 // Created by: Stagiaire Francois DUMONT
3 // Copyright (c) 1997-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
22
23 #include <BRepAlgo.ixx>
24 #include <BRepTools_WireExplorer.hxx>
25 #include <BRep_Tool.hxx>
26 #include <BRepLib_MakeEdge.hxx>
27 #include <BRepLib_MakeWire.hxx>
28 #include <gp_Pnt.hxx>
29 #include <GeomConvert.hxx>
30 #include <GeomLProp.hxx>
31 #include <Geom_TrimmedCurve.hxx>
32 #include <Precision.hxx>
33 #include <Standard_ConstructionError.hxx>
34 #include <TColGeom_Array1OfBSplineCurve.hxx>
35 #include <TColGeom_HArray1OfBSplineCurve.hxx>
36 #include <TColStd_Array1OfReal.hxx>
37 #include <TColStd_Array1OfBoolean.hxx>
38 #include <TopoDS_Edge.hxx>
39 #include <TopoDS_Vertex.hxx>
40 #include <TopLoc_Location.hxx>
41 #include <TopExp.hxx>
42
43 #include <TColGeom_SequenceOfCurve.hxx>
44 #include <TopTools_SequenceOfShape.hxx>
45 #include <TColStd_SequenceOfReal.hxx>
46 #include <TColStd_SequenceOfBoolean.hxx>
47 #include <GeomAbs_CurveType.hxx>
48 #include <BRepAdaptor_Curve.hxx>
49 #include <ElCLib.hxx>
50 #include <BRepLib.hxx>
51 #include <TopoDS.hxx>
52 #include <ShapeFix_Shape.hxx>
53 #include <GeomConvert_CompCurveToBSplineCurve.hxx>
54
55 //Temporary
56 #//include <DrawTrSurf.hxx>
57
58
59 //=======================================================================
60 //function : ConcatenateWire
61 //purpose  : 
62 //=======================================================================
63
64 TopoDS_Wire  BRepAlgo::ConcatenateWire(const TopoDS_Wire& W,
65                                        const GeomAbs_Shape Option,
66                                        const Standard_Real TolAngular) 
67 {
68
69
70   Standard_Integer        nb_curve,                         //number of curves in the Wire
71                           index;
72   BRepTools_WireExplorer  WExp(W) ;
73   TopoDS_Edge             edge;
74   TopLoc_Location         L ;
75   Standard_Real           First=0.,Last=0.,                       //extremal values for the curve
76                           First0 =0.,
77                           toler =0.,
78                           tolleft,tolright;                 //Vertex tolerances
79   TopoDS_Vertex           Vfirst,Vlast;                     //Vertex of the Wire
80   gp_Pnt                  Pfirst,Plast;            //, Pint;  corresponding points
81
82   BRepLib_MakeWire        MakeResult;                       
83   Standard_Real           closed_tolerance =0.0;
84   Standard_Boolean        closed_flag = Standard_False ;
85   
86   nb_curve = 0;
87   
88   while ( WExp.More()){                                     //computation of the curve number
89     nb_curve++ ;
90     WExp.Next();
91   }
92   
93   if (nb_curve > 1) {
94     TColGeom_Array1OfBSplineCurve tab(0,nb_curve-1);          //array of the wire's curve
95     TColStd_Array1OfReal tabtolvertex(0,nb_curve-2);          //array of the tolerance's vertex
96     
97     WExp.Init(W);
98     
99     for (index=0 ;index<nb_curve; index++){                   //main loop
100       edge = WExp.Current() ;
101       Handle(Geom_Curve) aCurve = BRep_Tool::Curve(edge, L, First, Last);
102       Handle(Geom_TrimmedCurve) aTrCurve = new Geom_TrimmedCurve(aCurve, First, Last);
103       tab(index) = GeomConvert::CurveToBSplineCurve(aTrCurve); //storage in a array 
104       tab(index)->Transform(L.Transformation());
105       GeomConvert::C0BSplineToC1BSplineCurve(tab(index),Precision::Confusion());
106       
107       if (index >= 1){                                         //continuity test loop
108         if (edge.Orientation()==TopAbs_REVERSED)
109           tab(index)->Reverse();
110         tolleft=BRep_Tool::Tolerance(TopExp::LastVertex(edge));
111         tolright=BRep_Tool::Tolerance(TopExp::FirstVertex(edge));
112         tabtolvertex(index-1)=Max(tolleft,tolright);
113       }
114       
115       if(index==0){                                           //storage of the first edge features
116         First0=First;
117         if(edge.Orientation()==TopAbs_REVERSED){             //(usefull for the closed wire) 
118           Vfirst=TopExp::LastVertex(edge);
119           tab(index)->Reverse();
120         }
121         else
122           Vfirst=TopExp::FirstVertex(edge);
123       }
124       
125       if(index==nb_curve-1){                                  //storage of the last edge features
126         if(edge.Orientation()==TopAbs_REVERSED)
127           Vlast=TopExp::FirstVertex(edge);
128         else
129           Vlast=TopExp::LastVertex(edge);
130       }
131       WExp.Next() ; 
132     }
133   
134     if (BRep_Tool::Tolerance(Vfirst)>BRep_Tool::Tolerance(Vlast)) //computation of the closing tolerance
135       toler=BRep_Tool::Tolerance(Vfirst);
136     else
137       toler=BRep_Tool::Tolerance(Vlast);
138     
139     Pfirst=BRep_Tool::Pnt(Vfirst);
140     Plast=BRep_Tool::Pnt(Vlast); 
141     
142     if ((Pfirst.Distance(Plast)<=toler)&&                   //C0 continuity test at the closing point
143         (GeomLProp::Continuity(tab(nb_curve-1),tab(0),Last,First0,
144                                Standard_True,Standard_True, 
145                                toler, TolAngular)>=GeomAbs_G1)) 
146       {
147         closed_tolerance =toler;                                        //if ClosedG1!=0 it will be True and
148         closed_flag = Standard_True ;
149       }                                                        //with the toler value
150     Handle(TColGeom_HArray1OfBSplineCurve)  concatcurve;     //array of the concatenated curves
151     Handle(TColStd_HArray1OfInteger)        ArrayOfIndices;  //array of the remining Vertex
152     if (Option==GeomAbs_G1)
153       GeomConvert::ConcatG1(tab,
154                             tabtolvertex,
155                             concatcurve,
156                             closed_flag,
157                             closed_tolerance) ;    //G1 concatenation
158     else
159       GeomConvert::ConcatC1(tab,
160                             tabtolvertex,
161                             ArrayOfIndices,
162                             concatcurve,
163                             closed_flag,
164                             closed_tolerance);   //C1 concatenation
165     
166     for (index=0;index<=(concatcurve->Length()-1);index++){    //building of the resulting Wire
167       BRepLib_MakeEdge EdgeBuilder(concatcurve->Value(index));
168       edge = EdgeBuilder.Edge();
169       MakeResult.Add(edge);
170     } 
171
172   }
173   else {
174     TColGeom_Array1OfBSplineCurve tab(0,0);          //array of the wire's curve
175     TColStd_Array1OfReal tabtolvertex(0,0);          //array of the tolerance's vertex 
176     WExp.Init(W);
177     
178     edge = WExp.Current() ;
179     tab(0)  = GeomConvert::CurveToBSplineCurve(new      //storage in a array 
180                                                      Geom_TrimmedCurve(BRep_Tool::Curve(edge,L,First,Last),First,Last));
181     tab(0)->Transform(L.Transformation());
182     GeomConvert::C0BSplineToC1BSplineCurve(tab(0),Precision::Confusion());
183     if (edge.Orientation()==TopAbs_REVERSED)
184           tab(0)->Reverse();
185     tolleft=BRep_Tool::Tolerance(TopExp::LastVertex(edge));
186     tolright=BRep_Tool::Tolerance(TopExp::FirstVertex(edge));
187     tabtolvertex(0)=Max(tolleft,tolright);
188     if(edge.Orientation()==TopAbs_REVERSED){             //(usefull for the closed wire) 
189           Vfirst=TopExp::LastVertex(edge);
190           Vlast=TopExp::FirstVertex(edge);
191     }
192     else {
193       
194       Vfirst=TopExp::FirstVertex(edge);
195       Vlast = TopExp::LastVertex(edge) ;
196     }
197     Pfirst=BRep_Tool::Pnt(Vfirst);
198     Plast=BRep_Tool::Pnt(Vlast); 
199     if ((Pfirst.Distance(Plast)<=toler)&&                   //C0 continuity test at the closing point
200         (GeomLProp::Continuity(tab(0),tab(0),Last,First,
201                                Standard_True,Standard_True,
202                                toler, TolAngular)>=GeomAbs_G1)) 
203       {
204         closed_tolerance =toler;                                        //if ClosedG1!=0 it will be True and
205         closed_flag = Standard_True ;
206       }                                                        //with the toler value
207     Handle(TColGeom_HArray1OfBSplineCurve)  concatcurve;     //array of the concatenated curves
208     Handle(TColStd_HArray1OfInteger)        ArrayOfIndices;  //array of the remining Vertex
209     if (Option==GeomAbs_G1)
210       GeomConvert::ConcatG1(tab,
211                             tabtolvertex,
212                             concatcurve,
213                             closed_flag,
214                             closed_tolerance) ;    //G1 concatenation
215     else
216       GeomConvert::ConcatC1(tab,
217                             tabtolvertex,
218                             ArrayOfIndices,
219                             concatcurve,
220                             closed_flag,
221                             closed_tolerance);   //C1 concatenation
222     
223     for (index=0;index<=(concatcurve->Length()-1);index++){    //building of the resulting Wire
224       BRepLib_MakeEdge EdgeBuilder(concatcurve->Value(index));
225       edge = EdgeBuilder.Edge();
226       MakeResult.Add(edge);
227     } 
228   }
229   return MakeResult.Wire() ;  
230   
231 }
232
233 //=======================================================================
234 //function : ConcatenateWireC0
235 //purpose  : 
236 //=======================================================================
237
238 TopoDS_Edge  BRepAlgo::ConcatenateWireC0(const TopoDS_Wire& aWire)
239 {
240   Standard_Real LinTol = Precision::Confusion();
241   Standard_Real AngTol = Precision::Angular();
242
243   TopoDS_Edge ResEdge;
244
245   TopoDS_Wire theWire = aWire;
246   BRepLib::BuildCurves3d(theWire);
247   Handle(ShapeFix_Shape) Fixer = new ShapeFix_Shape(theWire);
248   Fixer->SetPrecision(LinTol);
249   Fixer->SetMaxTolerance(LinTol);
250   Fixer->Perform();
251   theWire = TopoDS::Wire(Fixer->Shape());
252
253   TColGeom_SequenceOfCurve CurveSeq;
254   TColStd_SequenceOfReal FparSeq;
255   TColStd_SequenceOfReal LparSeq;
256   TColStd_SequenceOfReal TolSeq;
257   TColStd_SequenceOfBoolean IsFwdSeq;
258   GeomAbs_CurveType CurType = GeomAbs_OtherCurve;
259   TopoDS_Vertex FirstVertex, LastVertex;
260
261   BRepTools_WireExplorer wexp(theWire);
262
263   for (; wexp.More(); wexp.Next()) {
264     TopoDS_Edge anEdge = wexp.Current();
265     Standard_Real fpar, lpar;
266     Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anEdge, fpar, lpar);
267
268     if (aCurve.IsNull())
269       continue;
270
271     GeomAdaptor_Curve  aGACurve(aCurve);
272     GeomAbs_CurveType  aType       = aGACurve.GetType();
273     Handle(Geom_Curve) aBasisCurve = aGACurve.Curve();
274     Standard_Boolean   isFwd       = (wexp.Orientation() != TopAbs_REVERSED);
275
276     if (aBasisCurve->IsPeriodic()) {
277       ElCLib::AdjustPeriodic
278         (aBasisCurve->FirstParameter(), aBasisCurve->LastParameter(),
279         Precision::PConfusion(), fpar, lpar);
280
281
282
283     }
284
285     if (CurveSeq.IsEmpty()) {
286       CurveSeq.Append(aCurve);
287       FparSeq.Append(fpar);
288       LparSeq.Append(lpar);
289       IsFwdSeq.Append(isFwd);
290       CurType     = aType;
291       FirstVertex = wexp.CurrentVertex();
292     } else {
293       Standard_Boolean isSameCurve = Standard_False;
294       Standard_Real NewFpar, NewLpar;
295       GeomAdaptor_Curve GAprevcurve(CurveSeq.Last());
296
297       if (aCurve == CurveSeq.Last()) {
298         NewFpar = fpar;
299         NewLpar = lpar;
300         isSameCurve = Standard_True;
301       } else if (aType == CurType &&
302                  aType != GeomAbs_BezierCurve &&
303                  aType != GeomAbs_BSplineCurve &&
304                  aType != GeomAbs_OtherCurve) {
305         switch (aType) {
306         case GeomAbs_Line:
307         {
308           gp_Lin aLine    = aGACurve.Line();
309           gp_Lin PrevLine = GAprevcurve.Line(); 
310
311           if (aLine.Contains(PrevLine.Location(), LinTol) &&
312               aLine.Direction().IsParallel(PrevLine.Direction(), AngTol)) {
313             gp_Pnt P1 = ElCLib::Value(fpar, aLine);
314             gp_Pnt P2 = ElCLib::Value(lpar, aLine);
315
316             NewFpar = ElCLib::Parameter(PrevLine, P1);
317             NewLpar = ElCLib::Parameter(PrevLine, P2);
318             isSameCurve = Standard_True;
319           }
320           break;
321         }
322         case GeomAbs_Circle:
323         {
324           gp_Circ aCircle    = aGACurve.Circle();
325           gp_Circ PrevCircle = GAprevcurve.Circle();
326
327           if (aCircle.Location().Distance(PrevCircle.Location()) <= LinTol &&
328               Abs(aCircle.Radius() - PrevCircle.Radius()) <= LinTol &&
329               aCircle.Axis().IsParallel(PrevCircle.Axis(), AngTol)) {
330             gp_Pnt P1 = ElCLib::Value(fpar, aCircle);
331             gp_Pnt P2 = ElCLib::Value(lpar, aCircle);
332
333             NewFpar = ElCLib::Parameter(PrevCircle, P1);
334             NewLpar = ElCLib::Parameter(PrevCircle, P2);
335             isSameCurve = Standard_True;
336           }
337           break;
338         }
339         case GeomAbs_Ellipse:
340         {
341           gp_Elips anEllipse   = aGACurve.Ellipse();
342           gp_Elips PrevEllipse = GAprevcurve.Ellipse();
343
344           if (anEllipse.Focus1().Distance(PrevEllipse.Focus1()) <= LinTol &&
345               anEllipse.Focus2().Distance(PrevEllipse.Focus2()) <= LinTol &&
346               Abs(anEllipse.MajorRadius() - PrevEllipse.MajorRadius()) <= LinTol &&
347               Abs(anEllipse.MinorRadius() - PrevEllipse.MinorRadius()) <= LinTol &&
348               anEllipse.Axis().IsParallel(PrevEllipse.Axis(), AngTol)) {
349             gp_Pnt P1 = ElCLib::Value(fpar, anEllipse);
350             gp_Pnt P2 = ElCLib::Value(lpar, anEllipse);
351
352             NewFpar = ElCLib::Parameter(PrevEllipse, P1);
353             NewLpar = ElCLib::Parameter(PrevEllipse, P2);
354             isSameCurve = Standard_True;
355           }
356           break;
357         }
358         case GeomAbs_Hyperbola:
359         {
360           gp_Hypr aHypr    = aGACurve.Hyperbola();
361           gp_Hypr PrevHypr = GAprevcurve.Hyperbola();
362
363           if (aHypr.Focus1().Distance(PrevHypr.Focus1()) <= LinTol &&
364               aHypr.Focus2().Distance(PrevHypr.Focus2()) <= LinTol &&
365               Abs(aHypr.MajorRadius() - PrevHypr.MajorRadius()) <= LinTol &&
366               Abs(aHypr.MinorRadius() - PrevHypr.MinorRadius()) <= LinTol &&
367               aHypr.Axis().IsParallel(PrevHypr.Axis(), AngTol)) {
368             gp_Pnt P1 = ElCLib::Value(fpar, aHypr);
369             gp_Pnt P2 = ElCLib::Value(lpar, aHypr);
370
371             NewFpar = ElCLib::Parameter(PrevHypr, P1);
372             NewLpar = ElCLib::Parameter(PrevHypr, P2);
373             isSameCurve = Standard_True;
374           }
375           break;
376         }
377         case GeomAbs_Parabola:
378         {
379           gp_Parab aParab    = aGACurve.Parabola();
380           gp_Parab PrevParab = GAprevcurve.Parabola();
381
382           if (aParab.Location().Distance(PrevParab.Location()) <= LinTol &&
383               aParab.Focus().Distance(PrevParab.Focus()) <= LinTol &&
384               Abs(aParab.Focal() - PrevParab.Focal()) <= LinTol &&
385               aParab.Axis().IsParallel(PrevParab.Axis(), AngTol)) {
386             gp_Pnt P1 = ElCLib::Value(fpar, aParab);
387             gp_Pnt P2 = ElCLib::Value(lpar, aParab);
388
389             NewFpar = ElCLib::Parameter(PrevParab, P1);
390             NewLpar = ElCLib::Parameter(PrevParab, P2);
391             isSameCurve = Standard_True;
392           }
393           break;
394         }
395         default:
396           break;
397         } //end of switch
398       } //end of else
399
400       if (isSameCurve) {
401         const Standard_Boolean isSameDir = (isFwd == IsFwdSeq.Last());
402
403         if (aBasisCurve->IsPeriodic()) {
404           // Treat periodic curves.
405           const Standard_Real aPeriod = aBasisCurve->Period();
406
407           if (isSameDir) {
408             // Check if first parameter is greater then the last one.
409             while (NewFpar > NewLpar) {
410               NewFpar -= aPeriod;
411             }
412           } else { // !isSameDir
413             // Check if last parameter is greater then the first one.
414             while (NewLpar > NewFpar) {
415               NewLpar -= aPeriod;
416             }
417
418             // Change parameters
419             const Standard_Real aTmpPar = NewLpar;
420
421             NewLpar = NewFpar;
422             NewFpar = aTmpPar;
423           }
424
425           // Udjust parameters on periodic curves.
426           if (IsFwdSeq.Last()) {
427             // The current curve should be after the previous one.
428             ElCLib::AdjustPeriodic(LparSeq.Last(), LparSeq.Last() + aPeriod,
429               Precision::PConfusion(), NewFpar, NewLpar);
430           } else {
431             // The current curve should be before the previous one.
432             ElCLib::AdjustPeriodic(FparSeq.Last() - aPeriod, FparSeq.Last(),
433               Precision::PConfusion(), NewFpar, NewLpar);
434           }
435         } else if (!isSameDir) {
436           // Not periodic curves. Opposite dirs.
437           const Standard_Real aTmpPar = NewLpar;
438
439           NewLpar = NewFpar;
440           NewFpar = aTmpPar;
441         }
442
443         if (IsFwdSeq.Last()) {
444           // Update last parameter 
445           LparSeq(LparSeq.Length()) = NewLpar;
446         } else {
447           // Update first parameter 
448           FparSeq(FparSeq.Length()) = NewFpar;
449         }
450       } else {
451         // Add new curve.
452         CurveSeq.Append(aCurve);
453         FparSeq.Append(fpar);
454         LparSeq.Append(lpar);
455         IsFwdSeq.Append(isFwd);
456         TolSeq.Append(BRep_Tool::Tolerance(wexp.CurrentVertex()));
457         CurType = aType;
458       }
459     }
460   }
461
462   LastVertex = wexp.CurrentVertex();
463   TolSeq.Append(BRep_Tool::Tolerance(LastVertex));
464
465   Standard_Boolean isReverse = Standard_False;
466
467   if (!IsFwdSeq.IsEmpty()) {
468     isReverse = !IsFwdSeq(1);
469   }
470
471   TopoDS_Vertex FirstVtx_final = (isReverse)? LastVertex : FirstVertex;
472   FirstVtx_final.Orientation(TopAbs_FORWARD);
473   TopoDS_Vertex LastVtx_final = (isReverse)? FirstVertex : LastVertex;
474   LastVtx_final.Orientation(TopAbs_REVERSED);
475   
476   if (CurveSeq.IsEmpty())
477     return ResEdge;
478
479   Standard_Integer nb_curve = CurveSeq.Length();   //number of curves
480   TColGeom_Array1OfBSplineCurve tab(0,nb_curve-1);                    //array of the curves
481   TColStd_Array1OfReal tabtolvertex(0,nb_curve-1); //(0,nb_curve-2);  //array of the tolerances
482
483   Standard_Integer i;
484
485   if (nb_curve > 1)
486     {
487       for (i = 1; i <= nb_curve; i++)
488         {
489           if (CurveSeq(i)->IsInstance(STANDARD_TYPE(Geom_TrimmedCurve)))
490             CurveSeq(i) = (*((Handle(Geom_TrimmedCurve)*)&(CurveSeq(i))))->BasisCurve();
491           
492           Handle(Geom_TrimmedCurve) aTrCurve = new Geom_TrimmedCurve(CurveSeq(i), FparSeq(i), LparSeq(i));
493           tab(i-1) = GeomConvert::CurveToBSplineCurve(aTrCurve);
494           GeomConvert::C0BSplineToC1BSplineCurve(tab(i-1), Precision::Confusion());
495
496           if (!IsFwdSeq(i)) {
497             tab(i-1)->Reverse();
498           }
499           
500           //Temporary
501           //char* name = new char[100];
502           //sprintf(name, "c%d", i);
503           //DrawTrSurf::Set(name, tab(i-1));
504           
505           if (i > 1)
506             tabtolvertex(i-2) = TolSeq(i-1) * 5.;
507         }
508       tabtolvertex(nb_curve-1) = TolSeq(TolSeq.Length()) * 5.;
509       
510       Standard_Boolean closed_flag = Standard_False;
511       Standard_Real closed_tolerance = 0.;
512       if (FirstVertex.IsSame(LastVertex) &&
513           GeomLProp::Continuity(tab(0), tab(nb_curve-1),
514                                 tab(0)->FirstParameter(),
515                                 tab(nb_curve-1)->LastParameter(),
516                                 Standard_False, Standard_False, LinTol, AngTol) >= GeomAbs_G1)
517         {
518           closed_flag = Standard_True ;
519           closed_tolerance = BRep_Tool::Tolerance(FirstVertex);
520         }
521       
522       Handle(TColGeom_HArray1OfBSplineCurve)  concatcurve;     //array of the concatenated curves
523       Handle(TColStd_HArray1OfInteger)        ArrayOfIndices;  //array of the remining Vertex
524       GeomConvert::ConcatC1(tab,
525                             tabtolvertex,
526                             ArrayOfIndices,
527                             concatcurve,
528                             closed_flag,
529                             closed_tolerance);   //C1 concatenation
530
531       if (concatcurve->Length() > 1)
532         {
533           Standard_Real MaxTolVer = LinTol;
534           for (i = 1; i <= TolSeq.Length(); i++)
535             if (TolSeq(i) > MaxTolVer)
536               MaxTolVer = TolSeq(i);
537           MaxTolVer *= 5.;
538           
539           GeomConvert_CompCurveToBSplineCurve Concat(concatcurve->Value(concatcurve->Lower()));
540           
541           for (i = concatcurve->Lower()+1; i <= concatcurve->Upper(); i++)
542             Concat.Add( concatcurve->Value(i), MaxTolVer, Standard_True );
543           
544           concatcurve->SetValue(concatcurve->Lower(), Concat.BSplineCurve());
545         }
546
547       ResEdge = BRepLib_MakeEdge(concatcurve->Value(concatcurve->Lower()),
548                                  FirstVtx_final, LastVtx_final,
549                                  concatcurve->Value(concatcurve->Lower())->FirstParameter(),
550                                  concatcurve->Value(concatcurve->Lower())->LastParameter());
551     }
552   else
553     {
554       if (CurveSeq(1)->IsInstance(STANDARD_TYPE(Geom_TrimmedCurve)))
555         CurveSeq(1) = (*((Handle(Geom_TrimmedCurve)*)&(CurveSeq(1))))->BasisCurve();
556
557       Handle(Geom_Curve) aCopyCurve =
558           Handle(Geom_Curve)::DownCast(CurveSeq(1)->Copy());
559
560       ResEdge = BRepLib_MakeEdge(aCopyCurve,
561                                  FirstVtx_final, LastVtx_final,
562                                  FparSeq(1), LparSeq(1));
563     }
564
565   if (isReverse)
566     ResEdge.Reverse();
567   
568   return ResEdge;
569 }