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