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