0024255: Regressions in test cases on OCCT vc9 win64 Release
[occt.git] / src / BRepMAT2d / BRepMAT2d_Explorer.cxx
1 // Created on: 1994-10-04
2 // Created by: Yves FRICAUD
3 // Copyright (c) 1994-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
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
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.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17 #include <BRepMAT2d_Explorer.ixx>
18 #include <MAT2d_SequenceOfSequenceOfCurve.hxx>
19 #include <TColGeom2d_SequenceOfCurve.hxx>
20 #include <TopoDS_Wire.hxx>
21 #include <BRepTools_WireExplorer.hxx>
22 #include <TopLoc_Location.hxx>
23 #include <Geom_Curve.hxx>
24 #include <Geom_TrimmedCurve.hxx>  
25 #include <Geom2d_TrimmedCurve.hxx>
26 #include <GeomAPI.hxx>
27 #include <BRep_Tool.hxx>
28 #include <gp.hxx>
29 #include <gp_Pln.hxx>
30 #include <TopExp_Explorer.hxx>
31 #include <TopAbs.hxx>
32 #include <TopoDS.hxx>
33
34 #include <Precision.hxx>
35 #include <Geom2d_BSplineCurve.hxx>
36 #include <Geom2dConvert.hxx>
37 #include <BRepBuilderAPI_MakeFace.hxx>
38 #include <TopExp.hxx>
39 #include <BRep_Builder.hxx>
40 #include <BRepLib.hxx>
41 #include <TopTools_IndexedDataMapOfShapeShape.hxx>
42 #include <GeomAbs_CurveType.hxx>
43 #include <Geom2d_Circle.hxx>
44 #include <Geom2d_Line.hxx>
45 #include <Geom2d_Ellipse.hxx>
46 #include <Geom2d_Parabola.hxx>
47 #include <Geom2d_Hyperbola.hxx>
48 #include <Geom2d_BezierCurve.hxx>
49 #include <GCE2d_MakeArcOfCircle.hxx>
50 #include <GCE2d_MakeSegment.hxx> 
51 //
52 //  Modified by Sergey KHROMOV - Thu Dec  5 10:38:14 2002 Begin
53 static TopoDS_Edge MakeEdge(const Handle(Geom2d_Curve) &theCurve,
54   const TopoDS_Face          &theFace,
55   const TopoDS_Vertex        &theVFirst,
56   const TopoDS_Vertex        &theVLast);
57 //  Modified by Sergey KHROMOV - Thu Dec  5 10:38:16 2002 End
58 //
59 static GeomAbs_CurveType GetCurveType(const Handle(Geom2d_Curve)& theC2d);
60 static void AdjustCurveEnd(Handle(Geom2d_BoundedCurve)& theC2d, const gp_Pnt2d theP,
61                            const Standard_Boolean isFirst);
62 //
63 //=======================================================================
64 //function : BRepMAT2d_Explorer
65 //purpose  : 
66 //=======================================================================
67
68 BRepMAT2d_Explorer::BRepMAT2d_Explorer()
69 {
70   Clear();
71 }
72
73 //=======================================================================
74 //function : BRepMAT2d_Explorer
75 //purpose  : 
76 //=======================================================================
77
78 BRepMAT2d_Explorer::BRepMAT2d_Explorer(const TopoDS_Face& aFace)
79 {
80   Perform (aFace);
81 }
82
83 //=======================================================================
84 //function : Perform
85 //purpose  : 
86 //=======================================================================
87
88 void BRepMAT2d_Explorer::Perform(const TopoDS_Face& aFace)
89 {
90   Clear();
91   myShape        = aFace;
92   TopoDS_Face  F = TopoDS::Face(aFace);
93   F.Orientation(TopAbs_FORWARD);
94   TopExp_Explorer Exp (F,TopAbs_WIRE);
95   //  Modified by Sergey KHROMOV - Tue Nov 26 16:10:37 2002 Begin
96   Handle(Geom_Surface) aSurf = BRep_Tool::Surface(F);
97   TopoDS_Face          aNewF = BRepBuilderAPI_MakeFace(aSurf, Precision::Confusion());
98
99   while (Exp.More()) {
100     Add (TopoDS::Wire (Exp.Current()),F, aNewF);
101     Exp.Next();
102   }
103
104   BRepLib::BuildCurves3d(aNewF);
105
106   myModifShapes.Add(aFace, aNewF);
107   //   CheckConnection();
108   //  Modified by Sergey KHROMOV - Tue Nov 26 16:10:38 2002 End
109 }
110
111 //=======================================================================
112 //function : Add
113 //purpose  : 
114 //=======================================================================
115
116 void BRepMAT2d_Explorer::Add(const TopoDS_Wire& Spine,
117   const TopoDS_Face& aFace,
118   TopoDS_Face& aNewFace)
119 {  
120   //  Modified by Sergey KHROMOV - Tue Nov 26 14:25:46 2002 Begin
121   // This method is totally rewroted to include check
122   // of connection and creation of a new spine.
123   NewContour();
124   myIsClosed(currentContour) = (Spine.Closed()) ? Standard_True : Standard_False;
125
126   //  Modified by skv - Wed Jun 23 12:23:01 2004 Integration Begin
127   //  Taking into account side of bisecting loci construction.
128   //   TopoDS_Wire                         aWFwd = TopoDS::Wire(Spine.Oriented(TopAbs_FORWARD));
129   //   BRepTools_WireExplorer              anExp(aWFwd, aFace);
130   BRepTools_WireExplorer              anExp(Spine, aFace);
131   //  Modified by skv - Wed Jun 23 12:23:02 2004 Integration End
132   TopTools_IndexedDataMapOfShapeShape anOldNewE;
133
134   if (!anExp.More())
135     return;
136
137   TopoDS_Edge                 aFirstEdge = anExp.Current();
138   TopoDS_Edge                 aPrevEdge = aFirstEdge;
139   Standard_Real               UFirst,ULast, aD;
140   Handle(Geom2d_Curve)        C2d;
141   Handle(Geom2d_TrimmedCurve) CT2d;
142   Handle(Geom2d_TrimmedCurve) aFirstCurve;
143   gp_Pnt2d                    aPFirst;
144   gp_Pnt2d                    aPLast;
145   gp_Pnt2d                    aPCurFirst;
146   //  Modified by skv - Mon Jul 11 19:00:25 2005 Integration Begin
147   //  Set the confusion tolerance in accordance with the further algo
148   //   Standard_Real               aTolConf   = Precision::Confusion();
149   Standard_Real               aTolConf   = 1.e-8;
150   //  Modified by skv - Mon Jul 11 19:00:25 2005 Integration End
151   Standard_Boolean            isModif    = Standard_False;
152
153   // Treatment of the first edge of a wire.
154   anOldNewE.Add(aFirstEdge, aFirstEdge);
155   C2d  = BRep_Tool::CurveOnSurface (aFirstEdge, aFace, UFirst, ULast);
156   CT2d = new Geom2d_TrimmedCurve(C2d,UFirst,ULast);
157
158   if (aFirstEdge.Orientation() == TopAbs_REVERSED)
159     CT2d->Reverse();
160
161   aPFirst = CT2d->Value(CT2d->FirstParameter());
162   aPLast  = CT2d->Value(CT2d->LastParameter());
163
164   Add(CT2d);
165   aFirstCurve = CT2d;
166   anExp.Next();
167
168   // Treatment of the next edges:
169   for (; anExp.More(); anExp.Next()) {
170     TopoDS_Edge  anEdge = anExp.Current();
171
172     anOldNewE.Add(anEdge, anEdge);
173     C2d  = BRep_Tool::CurveOnSurface (anEdge, aFace, UFirst, ULast);
174     CT2d = new Geom2d_TrimmedCurve(C2d,UFirst,ULast);
175
176     if (anEdge.Orientation() == TopAbs_REVERSED)
177       CT2d->Reverse();
178
179     aPCurFirst = CT2d->Value(CT2d->FirstParameter());
180     //
181     aD=aPLast.Distance(aPCurFirst);
182     if (aD > aTolConf) {
183       // There are two ways how to fill holes:
184       //     First,  to create a line between these two points.
185       //     Second, create a BSpline curve and to add the last point of the previous
186       //             curve as the first pole of the current one. Second method which
187       //             is worse was performed before and leaved here. Otherwise too much
188       //             code should be rewritten.
189       isModif = Standard_True;
190       //
191       Standard_Integer aNbC = theCurves.Value(currentContour).Length();
192       Handle(Geom2d_BoundedCurve) CPrev = 
193         Handle(Geom2d_BoundedCurve)::DownCast(theCurves.ChangeValue(currentContour).ChangeValue(aNbC));
194       //
195       GeomAbs_CurveType TCPrev = GetCurveType(CPrev);
196       GeomAbs_CurveType TCCurr = GetCurveType(CT2d);
197       //
198       if(TCCurr <= TCPrev)
199       {
200         AdjustCurveEnd(CT2d, aPLast, Standard_True);
201         // Creation of new edge.
202         TopoDS_Edge aNewEdge;
203         TopoDS_Vertex aVf = TopExp::FirstVertex(anEdge);
204         TopoDS_Vertex aVl = TopExp::LastVertex(anEdge);
205
206         if (anEdge.Orientation() == TopAbs_FORWARD)
207           aNewEdge = MakeEdge(CT2d, aNewFace, aVf, aVl);
208         else 
209           aNewEdge = MakeEdge(CT2d->Reversed(), aNewFace, aVf, aVl);
210
211         aNewEdge.Orientation(anEdge.Orientation());
212
213         anOldNewE.ChangeFromKey(anEdge) = aNewEdge;
214       }
215       else
216       {
217         gp_Pnt2d aP = CT2d->Value(CT2d->FirstParameter());
218         AdjustCurveEnd(CPrev, aP, Standard_False);
219         theCurves.ChangeValue(currentContour).ChangeValue(aNbC) = CPrev;
220         //Change previous edge
221         TopoDS_Edge aNewEdge;
222         TopoDS_Vertex aVf = TopExp::FirstVertex(aPrevEdge);
223         TopoDS_Vertex aVl = TopExp::LastVertex(aPrevEdge);
224
225         if (aPrevEdge.Orientation() == TopAbs_FORWARD)
226           aNewEdge = MakeEdge(CPrev, aNewFace, aVf, aVl);
227         else 
228           aNewEdge = MakeEdge(CPrev->Reversed(), aNewFace, aVf, aVl);
229
230         aNewEdge.Orientation(aPrevEdge.Orientation());
231
232         anOldNewE.ChangeFromKey(aPrevEdge) = aNewEdge;
233         
234       }
235
236     }
237
238     aPLast = CT2d->Value(CT2d->LastParameter());
239     Add(CT2d);
240     aPrevEdge = anEdge;
241   }
242
243   // Check of the distance between the first and the last point of wire
244   // if the wire is closed.
245   if (myIsClosed(currentContour) && aPLast.Distance(aPFirst) > aTolConf) {
246     isModif = Standard_True;
247
248       //
249     Standard_Integer aNbC = theCurves.Value(currentContour).Length();
250     Handle(Geom2d_BoundedCurve) CPrev = 
251         Handle(Geom2d_BoundedCurve)::DownCast(theCurves.ChangeValue(currentContour).ChangeValue(aNbC));
252       //
253     GeomAbs_CurveType TCPrev = GetCurveType(CPrev);
254     GeomAbs_CurveType TCCurr = GetCurveType(aFirstCurve);
255     //
256     if(TCCurr <= TCPrev)
257     {
258       AdjustCurveEnd(aFirstCurve, aPLast, Standard_True);
259       theCurves.ChangeValue(currentContour).ChangeValue(1) = aFirstCurve;
260       // Creation of new edge.
261       TopoDS_Edge aNewEdge;
262       TopoDS_Vertex aVf = TopExp::FirstVertex(aFirstEdge);
263       TopoDS_Vertex aVl = TopExp::LastVertex(aFirstEdge);
264
265       if (aFirstEdge.Orientation() == TopAbs_FORWARD)
266         aNewEdge = MakeEdge(aFirstCurve, aNewFace, aVf, aVl);
267       else 
268         aNewEdge = MakeEdge(aFirstCurve->Reversed(), aNewFace, aVf, aVl);
269
270       aNewEdge.Orientation(aFirstEdge.Orientation());
271
272       anOldNewE.ChangeFromKey(aFirstEdge) = aNewEdge;
273     }
274     else
275     {
276       gp_Pnt2d aP = aFirstCurve->Value(aFirstCurve->FirstParameter());
277       AdjustCurveEnd(CPrev, aP, Standard_False);
278       theCurves.ChangeValue(currentContour).ChangeValue(aNbC) = CPrev;
279       //Change previous edge
280       TopoDS_Edge aNewEdge;
281       TopoDS_Vertex aVf = TopExp::FirstVertex(aPrevEdge);
282       TopoDS_Vertex aVl = TopExp::LastVertex(aPrevEdge);
283
284       if (aPrevEdge.Orientation() == TopAbs_FORWARD)
285         aNewEdge = MakeEdge(CPrev, aNewFace, aVf, aVl);
286       else 
287         aNewEdge = MakeEdge(CPrev->Reversed(), aNewFace, aVf, aVl);
288
289       aNewEdge.Orientation(aPrevEdge.Orientation());
290
291       anOldNewE.ChangeFromKey(aPrevEdge) = aNewEdge;
292
293     }
294
295   }
296
297   TopoDS_Wire  aNewWire;
298   BRep_Builder aBuilder;
299
300   if (isModif) {
301     Standard_Integer i;
302     Standard_Integer aNbEdges = anOldNewE.Extent();
303
304     aBuilder.MakeWire(aNewWire);
305
306     for (i = 1; i <= aNbEdges; i++) {
307       const TopoDS_Shape &aKey     = anOldNewE.FindKey(i);
308       const TopoDS_Shape &aNewEdge = anOldNewE.FindFromIndex(i);
309
310       aBuilder.Add(aNewWire, aNewEdge);
311       myModifShapes.Add(aKey, aNewEdge);
312     }
313
314     if (myIsClosed(currentContour))
315       aNewWire.Closed(Standard_True);
316
317     //  Modified by skv - Fri Nov 12 17:22:12 2004 Integration Begin
318     //  The orientation of wire is already taken into account.
319     //    aNewWire.Orientation(Spine.Orientation());
320     //  Modified by skv - Fri Nov 12 17:22:12 2004 Integration End
321     myModifShapes.Add(Spine, aNewWire);
322   } else
323     aNewWire = Spine;
324
325   aBuilder.Add(aNewFace, aNewWire);
326   //  Modified by Sergey KHROMOV - Tue Nov 26 14:25:53 2002 End
327 }
328
329 //=======================================================================
330 //function : CheckConnection
331 //purpose  : 
332 //=======================================================================
333
334 //  Modified by Sergey KHROMOV - Tue Nov 26 17:21:44 2002 Begin
335 // void BRepMAT2d_Explorer::CheckConnection()
336 // {
337 //   for (Standard_Integer i = 1; i <= theCurves.Length(); i++)
338 //     for (Standard_Integer j = 2; j <= theCurves(i).Length(); j++)
339 //       {
340 //      gp_Pnt2d P1 = theCurves(i)(j-1)->Value( theCurves(i)(j-1)->LastParameter() );
341 //      gp_Pnt2d P2 = theCurves(i)(j)->Value( theCurves(i)(j)->FirstParameter() );
342 //      if (P1.Distance( P2 ) > Precision::Confusion())
343 //        {
344 //          Handle( Geom2d_BSplineCurve ) BCurve;
345 //          if (theCurves(i)(j)->DynamicType() != STANDARD_TYPE(Geom2d_BSplineCurve))
346 //            BCurve = Geom2dConvert::CurveToBSplineCurve( theCurves(i)(j) );
347 //          else
348 //            BCurve = Handle( Geom2d_BSplineCurve )::DownCast( theCurves(i)(j) );
349 //          BCurve->SetPole( 1, P1 );
350 //          theCurves(i)(j) = new Geom2d_TrimmedCurve( BCurve, BCurve->FirstParameter(), BCurve->LastParameter() );
351 //        }
352 //       }
353 // }
354 //  Modified by Sergey KHROMOV - Tue Nov 26 17:21:29 2002 End
355
356 //=======================================================================
357 //function : Clear
358 //purpose  : 
359 //=======================================================================
360
361 void BRepMAT2d_Explorer::Clear()
362 {  
363   theCurves.Clear() ;
364   currentContour = 0;
365   //  Modified by Sergey KHROMOV - Wed Mar  6 16:07:55 2002 Begin
366   myIsClosed.Clear();
367   myModifShapes.Clear();
368   //  Modified by Sergey KHROMOV - Wed Mar  6 16:07:55 2002 End
369 }
370
371
372 //=======================================================================
373 //function : NewContour
374 //purpose  : 
375 //=======================================================================
376
377 void BRepMAT2d_Explorer::NewContour()
378 {  
379   TColGeom2d_SequenceOfCurve Contour;
380   theCurves.Append(Contour);
381   //  Modified by Sergey KHROMOV - Wed Mar  6 16:12:05 2002 Begin
382   myIsClosed.Append(Standard_False);
383   //  Modified by Sergey KHROMOV - Wed Mar  6 16:12:05 2002 End
384   currentContour ++ ;
385 }
386
387
388 //=======================================================================
389 //function : Add
390 //purpose  : 
391 //=======================================================================
392
393 void BRepMAT2d_Explorer::Add(const Handle(Geom2d_Curve)& aCurve)
394 {  
395   theCurves.ChangeValue(currentContour).Append(aCurve);
396 }
397
398 //=======================================================================
399 //function : NumberOfContours
400 //purpose  : 
401 //=======================================================================
402
403 Standard_Integer BRepMAT2d_Explorer::NumberOfContours() const 
404 {  
405   return theCurves.Length() ;
406 }
407
408
409 //=======================================================================
410 //function : NumberOfCurves
411 //purpose  : 
412 //=======================================================================
413
414 Standard_Integer BRepMAT2d_Explorer::NumberOfCurves
415   (const Standard_Integer IndexContour)
416   const 
417 {  
418   return theCurves.Value(IndexContour).Length();
419 }
420
421
422 //=======================================================================
423 //function : Init
424 //purpose  : 
425 //=======================================================================
426
427 void BRepMAT2d_Explorer::Init(const Standard_Integer IndexContour)
428 {  
429   currentContour = IndexContour;
430   current        = 1;
431 }
432
433
434 //=======================================================================
435 //function : More
436 //purpose  : 
437 //=======================================================================
438
439 Standard_Boolean BRepMAT2d_Explorer::More() const 
440 {  
441   return (current <= NumberOfCurves(currentContour));
442 }
443
444
445 //=======================================================================
446 //function : Next
447 //purpose  : 
448 //=======================================================================
449
450 void BRepMAT2d_Explorer::Next()
451
452   current++;
453 }
454
455
456 //=======================================================================
457 //function : Value
458 //purpose  : 
459 //=======================================================================
460
461 Handle(Geom2d_Curve) BRepMAT2d_Explorer::Value() const 
462 {  
463   return theCurves.Value(currentContour).Value(current);
464 }
465
466 //=======================================================================
467 //function : Shape
468 //purpose  : 
469 //=======================================================================
470
471 TopoDS_Shape BRepMAT2d_Explorer::Shape() const
472 {
473   return myShape;
474 }
475
476
477 //=======================================================================
478 //function : Contour
479 //purpose  : 
480 //=======================================================================
481
482 const TColGeom2d_SequenceOfCurve& BRepMAT2d_Explorer::Contour
483   (const Standard_Integer IC)
484   const
485 {
486   return theCurves.Value(IC);
487 }
488
489
490 //  Modified by Sergey KHROMOV - Wed Mar  6 17:40:07 2002 Begin
491 //=======================================================================
492 //function : IsModified
493 //purpose  : 
494 //=======================================================================
495
496 Standard_Boolean BRepMAT2d_Explorer::IsModified
497   (const TopoDS_Shape &aShape) const
498 {
499   if (myModifShapes.Contains(aShape)) {
500     const TopoDS_Shape     &aNewShape = myModifShapes.FindFromKey(aShape);
501     const Standard_Boolean  isSame    = aNewShape.IsSame(aShape);
502
503     return !isSame;
504   }
505
506   return Standard_False;
507 }
508
509 //=======================================================================
510 //function : ModifiedShape
511 //purpose  : 
512 //=======================================================================
513
514 TopoDS_Shape BRepMAT2d_Explorer::ModifiedShape
515   (const TopoDS_Shape &aShape) const
516 {
517   if (myModifShapes.Contains(aShape)) {
518     const TopoDS_Shape &aNewShape = myModifShapes.FindFromKey(aShape);
519
520     return aNewShape;
521   }
522
523   return aShape;
524 }
525
526 //=======================================================================
527 //function : GetIsClosed
528 //purpose  : 
529 //=======================================================================
530
531 const TColStd_SequenceOfBoolean &BRepMAT2d_Explorer::GetIsClosed() const
532 {
533   return myIsClosed;
534 }
535
536 //=======================================================================
537 //function : MakeEdge
538 //purpose  : Creation of an edge by 2d curve, face and two vertices.
539 //=======================================================================
540
541 TopoDS_Edge MakeEdge(const Handle(Geom2d_Curve) &theCurve,
542   const TopoDS_Face          &theFace,
543   const TopoDS_Vertex        &theVFirst,
544   const TopoDS_Vertex        &theVLast)
545 {
546   TopoDS_Edge   aNewEdge;
547   BRep_Builder  aBuilder;
548   Standard_Real aTol  = Precision::Confusion();
549   Standard_Real aFPar = theCurve->FirstParameter();
550   Standard_Real aLPar = theCurve->LastParameter();
551
552   aBuilder.MakeEdge(aNewEdge);
553   aBuilder.UpdateEdge(aNewEdge, theCurve, theFace, aTol);
554   aBuilder.Add(aNewEdge, theVFirst.Oriented(TopAbs_FORWARD));
555   aBuilder.Add(aNewEdge, theVLast.Oriented(TopAbs_REVERSED));
556   aBuilder.Range(aNewEdge, aFPar, aLPar);
557
558   return aNewEdge;
559 }
560 //  Modified by Sergey KHROMOV - Wed Mar  6 17:40:14 2002 End
561 //
562 //=======================================================================
563 //function : GetCurveType
564 //purpose  : Get curve type.
565 //=======================================================================
566
567 GeomAbs_CurveType GetCurveType(const Handle(Geom2d_Curve)& theC2d)
568 {
569   GeomAbs_CurveType aTypeCurve = GeomAbs_OtherCurve;
570   Handle(Standard_Type) TheType = theC2d->DynamicType();
571   if ( TheType == STANDARD_TYPE(Geom2d_TrimmedCurve)) {
572     TheType = (*((Handle(Geom2d_TrimmedCurve)*)&theC2d))->BasisCurve()->DynamicType();
573   }
574
575   if ( TheType ==  STANDARD_TYPE(Geom2d_Circle)) {
576     aTypeCurve = GeomAbs_Circle;
577   }
578   else if ( TheType ==STANDARD_TYPE(Geom2d_Line)) {
579     aTypeCurve = GeomAbs_Line;
580   }
581   else if ( TheType == STANDARD_TYPE(Geom2d_Ellipse)) {
582     aTypeCurve = GeomAbs_Ellipse;
583   }
584   else if ( TheType == STANDARD_TYPE(Geom2d_Parabola)) {
585     aTypeCurve = GeomAbs_Parabola;
586   }
587   else if ( TheType == STANDARD_TYPE(Geom2d_Hyperbola)) {
588     aTypeCurve = GeomAbs_Hyperbola;
589   }
590   else if ( TheType == STANDARD_TYPE(Geom2d_BezierCurve)) {
591     aTypeCurve = GeomAbs_BezierCurve;
592   }
593   else if ( TheType == STANDARD_TYPE(Geom2d_BSplineCurve)) {
594     aTypeCurve = GeomAbs_BSplineCurve;
595   }
596   else {
597     aTypeCurve = GeomAbs_OtherCurve;
598   }
599   return aTypeCurve;    
600 }
601 //=======================================================================
602 //function : AdjustCurveEnd
603 //purpose  : 
604 //=======================================================================
605 void AdjustCurveEnd(Handle(Geom2d_BoundedCurve)& theC2d, const gp_Pnt2d theP,
606                            const Standard_Boolean isFirst)
607 {
608   GeomAbs_CurveType aType = GetCurveType(theC2d);
609   if(aType == GeomAbs_Line)
610   {
611     //create new line
612     if(isFirst)
613     {
614       gp_Pnt2d aP = theC2d->Value(theC2d->LastParameter());
615       theC2d = GCE2d_MakeSegment(theP, aP);
616     }
617     else
618     {
619       gp_Pnt2d aP = theC2d->Value(theC2d->FirstParameter());
620       theC2d = GCE2d_MakeSegment(aP, theP);
621     }
622   }
623   else
624   {
625     //Convert to BSpline and adjust first pole
626     Handle(Geom2d_BSplineCurve) BCurve = 
627       Geom2dConvert::CurveToBSplineCurve(theC2d, Convert_QuasiAngular);
628     if(isFirst)
629     {
630       BCurve->SetPole(1, theP);
631       theC2d = new Geom2d_TrimmedCurve(BCurve, BCurve->FirstParameter(),
632                                                BCurve->LastParameter());
633     }
634     else
635     {
636       BCurve->SetPole(BCurve->NbPoles(), theP);
637       theC2d = new Geom2d_TrimmedCurve(BCurve, BCurve->FirstParameter(),
638                                                BCurve->LastParameter());
639     }
640   }
641
642 }