7d9828b7a94e0bf02111d32f7c4e7de006577c2f
[occt.git] / src / BRepLib / BRepLib_MakeEdge.cxx
1 // File:        BRepLib_MakeEdge.cxx
2 // Created:     Fri Jul 23 15:51:46 1993
3 // Author:      Remi LEQUETTE
4 //              <rle@nonox>
5 // Modified:    Wed Oct 23 09:17:47 1996
6 // Author:      Joelle CHAUVET
7 //              <jct@sgi38>
8 //              check ponctuallity (PRO4896)
9
10 #include <BRepLib_MakeEdge.ixx>
11 #include <BRepLib.hxx>
12 #include <BRep_Tool.hxx>
13 #include <BRep_Builder.hxx>
14 #include <TopoDS.hxx>
15 #include <Geom_Line.hxx>
16 #include <Geom_Circle.hxx>
17 #include <Geom_Ellipse.hxx>
18 #include <Geom_Parabola.hxx>
19 #include <Geom_Hyperbola.hxx>
20 #include <Geom_TrimmedCurve.hxx>
21 #include <Geom2d_TrimmedCurve.hxx>
22 #include <GeomAdaptor_Curve.hxx>
23 #include <Geom2dAdaptor_HCurve.hxx>
24 #include <GeomAdaptor_HSurface.hxx>
25 #include <Adaptor3d_CurveOnSurface.hxx>
26 #include <Extrema_ExtPC.hxx>
27 #include <gp.hxx>
28 #include <ElCLib.hxx>
29 #include <Precision.hxx>
30
31
32 //=======================================================================
33 //function : Project
34 //purpose  : project a vertex on a curve
35 //=======================================================================
36
37 static Standard_Boolean Project(const Handle(Geom_Curve)& C,
38                                 const TopoDS_Vertex& V,
39                                 Standard_Real& p)
40 {
41   Standard_Real Eps2 = BRep_Tool::Tolerance(V);
42   Eps2 *= Eps2;
43   
44   gp_Pnt P = BRep_Tool::Pnt(V);
45   GeomAdaptor_Curve GAC(C);
46   
47   // Afin de faire les extremas, on verifie les distances en bout
48   Standard_Real D1,D2;
49   gp_Pnt P1,P2;
50   P1 = GAC.Value(GAC.FirstParameter());
51   P2 = GAC.Value(GAC.LastParameter());
52   D1 = P1.SquareDistance(P);
53   D2 = P2.SquareDistance(P);
54   if ( (D1 < D2) && (D1 <= Eps2) ) {
55     p = GAC.FirstParameter();
56     return Standard_True;
57   }
58   else if ( (D2 < D1) && (D2 <= Eps2) ) {
59     p = GAC.LastParameter();
60     return Standard_True;
61   }
62
63   // Sinon, on calcule les extremas.
64
65   Extrema_ExtPC extrema(P,GAC);
66   if (extrema.IsDone()) {
67     Standard_Integer i, index = 0, n = extrema.NbExt();
68     Standard_Real Dist2 = RealLast(), dist2min;
69
70     for (i = 1; i <= n; i++) {
71       dist2min = extrema.SquareDistance(i);
72       if (dist2min < Dist2) {
73         index = i;
74         Dist2 = dist2min;
75       }
76     }
77
78     if (index != 0) {
79       if (Dist2 <= Eps2) {
80         p = (extrema.Point(index)).Parameter();
81         return Standard_True;
82       }
83     }
84   }
85   return Standard_False;
86 }
87
88
89 //=======================================================================
90 //function : Project
91 //purpose  : project a vertex on a curve on surface
92 //=======================================================================
93
94 static Standard_Boolean Project(const Handle(Geom2d_Curve)& C,
95                                 const Handle(Geom_Surface)& S,
96                                 const TopoDS_Vertex& V,
97                                 Standard_Real& p)
98 {
99   gp_Pnt P = BRep_Tool::Pnt(V);
100   Standard_Real Eps2 = BRep_Tool::Tolerance(V);
101   Eps2 *= Eps2;
102   
103   static Handle(Geom2dAdaptor_HCurve) HG2AHC;
104   if ( HG2AHC.IsNull() ) HG2AHC = new Geom2dAdaptor_HCurve();
105   HG2AHC->Set(C);
106   static Handle(GeomAdaptor_HSurface) HGAHS;
107   if ( HGAHS.IsNull() ) HGAHS = new GeomAdaptor_HSurface();
108   HGAHS->Set(S);
109   Adaptor3d_CurveOnSurface ACOS(HG2AHC,HGAHS);
110
111   Standard_Real D1,D2;
112   gp_Pnt P1,P2;
113   P1 = ACOS.Value(ACOS.FirstParameter());
114   P2 = ACOS.Value(ACOS.LastParameter());
115   D1 = P1.SquareDistance(P);
116   D2 = P2.SquareDistance(P);
117   if ( (D1 < D2) && (D1 <= Eps2) ) {
118     p = ACOS.FirstParameter();
119     return Standard_True;
120   }
121   else if ( (D2 < D1) && (D2 <= Eps2) ) {
122     p = ACOS.LastParameter();
123     return Standard_True;
124   }
125   
126   
127   Extrema_ExtPC extrema(P,ACOS);
128   
129   if (extrema.IsDone()) {
130     Standard_Integer i, index = 0, n = extrema.NbExt();
131     Standard_Real Dist2 = RealLast(), dist2min;
132     
133     for (i = 1; i <= n; i++) {
134       dist2min = extrema.SquareDistance(i);
135       if (dist2min < Dist2) {
136         index = i;
137         Dist2 = dist2min;
138       }
139     }
140     
141     if (index != 0) {
142       Extrema_POnCurv POC = extrema.Point(index);
143       if (P.SquareDistance(POC.Value()) <= Precision::Confusion() * Precision::Confusion()) {
144         p = POC.Parameter();
145         return Standard_True;
146       }
147     }
148   }
149   return Standard_False;
150 }
151
152 //=======================================================================
153 //function : BRepLib_MakeEdge
154 //purpose  : 
155 //=======================================================================
156
157 BRepLib_MakeEdge::BRepLib_MakeEdge()
158 {}
159
160 //=======================================================================
161 //function : BRepLib_MakeEdge
162 //purpose  : 
163 //=======================================================================
164
165 BRepLib_MakeEdge::BRepLib_MakeEdge(const TopoDS_Vertex& V1, 
166                                    const TopoDS_Vertex& V2)
167 {
168   gp_Pnt P1 = BRep_Tool::Pnt(V1);
169   gp_Pnt P2 = BRep_Tool::Pnt(V2);
170   Standard_Real l = P1.Distance(P2);
171   if (l <= gp::Resolution()) {
172     myError = BRepLib_LineThroughIdenticPoints;
173     return;
174   }
175   gp_Lin L(P1,gp_Vec(P1,P2));
176   Handle(Geom_Line) GL = new Geom_Line(L);
177   Init(GL,V1,V2,0,l);
178 }
179
180
181 //=======================================================================
182 //function : BRepLib_MakeEdge
183 //purpose  : 
184 //=======================================================================
185
186 BRepLib_MakeEdge::BRepLib_MakeEdge(const gp_Pnt& P1, 
187                                    const gp_Pnt& P2)
188 {
189   Standard_Real l = P1.Distance(P2);
190   if (l <= gp::Resolution()) {
191     myError = BRepLib_LineThroughIdenticPoints;
192     return;
193   }
194   gp_Lin L(P1,gp_Vec(P1,P2));
195   Handle(Geom_Line) GL = new Geom_Line(L);
196   Init(GL,P1,P2,0,l);
197 }
198
199
200 //=======================================================================
201 //function : BRepLib_MakeEdge
202 //purpose  : 
203 //=======================================================================
204
205 BRepLib_MakeEdge::BRepLib_MakeEdge(const gp_Lin& L)
206 {
207   Handle(Geom_Line) GL = new Geom_Line(L);
208   Init(GL);
209 }
210
211
212 //=======================================================================
213 //function : BRepLib_MakeEdge
214 //purpose  : 
215 //=======================================================================
216
217 BRepLib_MakeEdge::BRepLib_MakeEdge(const gp_Lin& L, 
218                                    const Standard_Real p1, 
219                                    const Standard_Real p2)
220 {
221   Handle(Geom_Line) GL = new Geom_Line(L);
222   Init(GL,p1,p2);
223 }
224
225
226 //=======================================================================
227 //function : BRepLib_MakeEdge
228 //purpose  : 
229 //=======================================================================
230
231 BRepLib_MakeEdge::BRepLib_MakeEdge(const gp_Lin& L, 
232                                    const gp_Pnt& P1, 
233                                    const gp_Pnt& P2)
234 {
235   Handle(Geom_Line) GL = new Geom_Line(L);
236   Init(GL,P1,P2);
237 }
238
239
240 //=======================================================================
241 //function : BRepLib_MakeEdge
242 //purpose  : 
243 //=======================================================================
244
245 BRepLib_MakeEdge::BRepLib_MakeEdge(const gp_Lin& L, 
246                                    const TopoDS_Vertex& V1, 
247                                    const TopoDS_Vertex& V2)
248 {
249   Handle(Geom_Line) GL = new Geom_Line(L);
250   Init(GL,V1,V2);
251 }
252
253
254 //=======================================================================
255 //function : BRepLib_MakeEdge
256 //purpose  : 
257 //=======================================================================
258
259 BRepLib_MakeEdge::BRepLib_MakeEdge(const gp_Circ& C) 
260 {
261   Handle(Geom_Circle) GC = new Geom_Circle(C);
262   Init(GC);
263 }
264
265
266 //=======================================================================
267 //function : BRepLib_MakeEdge
268 //purpose  : 
269 //=======================================================================
270
271 BRepLib_MakeEdge::BRepLib_MakeEdge(const gp_Circ& C,
272                                    const Standard_Real p1,
273                                    const Standard_Real p2)
274 {
275   Handle(Geom_Circle) GC = new Geom_Circle(C);
276   Init(GC,p1,p2);
277 }
278
279
280 //=======================================================================
281 //function : BRepLib_MakeEdge
282 //purpose  : 
283 //=======================================================================
284
285 BRepLib_MakeEdge::BRepLib_MakeEdge(const gp_Circ& C,
286                                    const gp_Pnt& P1,
287                                    const gp_Pnt& P2)
288 {
289   Handle(Geom_Circle) GC = new Geom_Circle(C);
290   Init(GC,P1,P2);
291 }
292
293
294 //=======================================================================
295 //function : BRepLib_MakeEdge
296 //purpose  : 
297 //=======================================================================
298
299 BRepLib_MakeEdge::BRepLib_MakeEdge(const gp_Circ& C,
300                                    const TopoDS_Vertex& V1,
301                                    const TopoDS_Vertex& V2)
302 {
303   Handle(Geom_Circle) GC = new Geom_Circle(C);
304   Init(GC,V1,V2);
305 }
306
307
308 //=======================================================================
309 //function : BRepLib_MakeEdge
310 //purpose  : 
311 //=======================================================================
312
313 BRepLib_MakeEdge::BRepLib_MakeEdge(const gp_Elips& E) 
314 {
315   Handle(Geom_Ellipse) GE = new Geom_Ellipse(E);
316   Init(GE);
317 }
318
319
320 //=======================================================================
321 //function : BRepLib_MakeEdge
322 //purpose  : 
323 //=======================================================================
324
325 BRepLib_MakeEdge::BRepLib_MakeEdge(const gp_Elips& E,
326                                    const Standard_Real p1,
327                                    const Standard_Real p2)
328 {
329   Handle(Geom_Ellipse) GE = new Geom_Ellipse(E);
330   Init(GE,p1,p2);
331 }
332
333
334 //=======================================================================
335 //function : BRepLib_MakeEdge
336 //purpose  : 
337 //=======================================================================
338
339 BRepLib_MakeEdge::BRepLib_MakeEdge(const gp_Elips& E,
340                                    const gp_Pnt& P1,
341                                    const gp_Pnt& P2)
342 {
343   Handle(Geom_Ellipse) GE = new Geom_Ellipse(E);
344   Init(GE,P1,P2);
345 }
346
347
348 //=======================================================================
349 //function : BRepLib_MakeEdge
350 //purpose  : 
351 //=======================================================================
352
353 BRepLib_MakeEdge::BRepLib_MakeEdge(const gp_Elips& E,
354                                    const TopoDS_Vertex& V1,
355                                    const TopoDS_Vertex& V2)
356 {
357   Handle(Geom_Ellipse) GE = new Geom_Ellipse(E);
358   Init(GE,V1,V2);
359 }
360
361
362 //=======================================================================
363 //function : BRepLib_MakeEdge
364 //purpose  : 
365 //=======================================================================
366
367 BRepLib_MakeEdge::BRepLib_MakeEdge(const gp_Hypr& H)
368 {
369   Handle(Geom_Hyperbola) GH = new Geom_Hyperbola(H);
370   Init(GH);
371 }
372
373
374 //=======================================================================
375 //function : BRepLib_MakeEdge
376 //purpose  : 
377 //=======================================================================
378
379 BRepLib_MakeEdge::BRepLib_MakeEdge(const gp_Hypr& H,
380                                    const Standard_Real p1,
381                                    const Standard_Real p2)
382 {
383   Handle(Geom_Hyperbola) GH = new Geom_Hyperbola(H);
384   Init(GH,p1,p2);
385 }
386
387
388 //=======================================================================
389 //function : BRepLib_MakeEdge
390 //purpose  : 
391 //=======================================================================
392
393 BRepLib_MakeEdge::BRepLib_MakeEdge(const gp_Hypr& H,
394                                    const gp_Pnt& P1,
395                                    const gp_Pnt& P2)
396 {
397   Handle(Geom_Hyperbola) GH = new Geom_Hyperbola(H);
398   Init(GH,P1,P2);
399 }
400
401
402 //=======================================================================
403 //function : BRepLib_MakeEdge
404 //purpose  : 
405 //=======================================================================
406
407 BRepLib_MakeEdge::BRepLib_MakeEdge(const gp_Hypr& H,
408                                    const TopoDS_Vertex& V1,
409                                    const TopoDS_Vertex& V2)
410 {
411   Handle(Geom_Hyperbola) GH = new Geom_Hyperbola(H);
412   Init(GH,V1,V2);
413 }
414
415
416 //=======================================================================
417 //function : BRepLib_MakeEdge
418 //purpose  : 
419 //=======================================================================
420
421 BRepLib_MakeEdge::BRepLib_MakeEdge(const gp_Parab& P)
422 {
423   Handle(Geom_Parabola) GP = new Geom_Parabola(P);
424   Init(GP);
425 }
426
427
428 //=======================================================================
429 //function : BRepLib_MakeEdge
430 //purpose  : 
431 //=======================================================================
432
433 BRepLib_MakeEdge::BRepLib_MakeEdge(const gp_Parab& P,
434                                    const Standard_Real p1,
435                                    const Standard_Real p2)
436 {
437   Handle(Geom_Parabola) GP = new Geom_Parabola(P);
438   Init(GP,p1,p2);
439 }
440
441
442 //=======================================================================
443 //function : BRepLib_MakeEdge
444 //purpose  : 
445 //=======================================================================
446
447 BRepLib_MakeEdge::BRepLib_MakeEdge(const gp_Parab& P,
448                                    const gp_Pnt& P1,
449                                    const gp_Pnt& P2)
450 {
451   Handle(Geom_Parabola) GP = new Geom_Parabola(P);
452   Init(GP,P1,P2);
453 }
454
455
456 //=======================================================================
457 //function : BRepLib_MakeEdge
458 //purpose  : 
459 //=======================================================================
460
461 BRepLib_MakeEdge::BRepLib_MakeEdge(const gp_Parab& P,
462                                    const TopoDS_Vertex& V1,
463                                    const TopoDS_Vertex& V2)
464 {
465   Handle(Geom_Parabola) GP = new Geom_Parabola(P);
466   Init(GP,V1,V2);
467 }
468
469
470 //=======================================================================
471 //function : BRepLib_MakeEdge
472 //purpose  : 
473 //=======================================================================
474
475 BRepLib_MakeEdge::BRepLib_MakeEdge(const Handle(Geom_Curve)& L)
476 {
477   Init(L);
478 }
479
480
481 //=======================================================================
482 //function : BRepLib_MakeEdge
483 //purpose  : 
484 //=======================================================================
485
486 BRepLib_MakeEdge::BRepLib_MakeEdge(const Handle(Geom_Curve)& L,
487                                    const Standard_Real p1,
488                                    const Standard_Real p2)
489 {
490   Init(L,p1,p2);
491 }
492
493
494 //=======================================================================
495 //function : BRepLib_MakeEdge
496 //purpose  : 
497 //=======================================================================
498
499 BRepLib_MakeEdge::BRepLib_MakeEdge(const Handle(Geom_Curve)& L,
500                                    const gp_Pnt& P1,
501                                    const gp_Pnt& P2)
502 {
503   Init(L,P1,P2);
504 }
505
506 //=======================================================================
507 //function : BRepLib_MakeEdge
508 //purpose  : 
509 //=======================================================================
510
511 BRepLib_MakeEdge::BRepLib_MakeEdge(const Handle(Geom_Curve)& L,
512                                    const TopoDS_Vertex& V1,
513                                    const TopoDS_Vertex& V2)
514 {
515   Init(L,V1,V2);
516 }
517
518
519 //=======================================================================
520 //function : BRepLib_MakeEdge
521 //purpose  : 
522 //=======================================================================
523
524 BRepLib_MakeEdge::BRepLib_MakeEdge(const Handle(Geom_Curve)& L,
525                                    const gp_Pnt& P1,
526                                    const gp_Pnt& P2,
527                                    const Standard_Real p1,
528                                    const Standard_Real p2)
529 {
530   Init(L,P1,P2,p1,p2);
531 }
532
533
534 //=======================================================================
535 //function : BRepLib_MakeEdge
536 //purpose  : 
537 //=======================================================================
538
539 BRepLib_MakeEdge::BRepLib_MakeEdge(const Handle(Geom_Curve)& L,
540                                    const TopoDS_Vertex& V1,
541                                    const TopoDS_Vertex& V2,
542                                    const Standard_Real p1,
543                                    const Standard_Real p2)
544 {
545   Init(L,V1,V2,p1,p2);
546 }
547
548
549
550 //=======================================================================
551 //function : BRepLib_MakeEdge
552 //purpose  : 
553 //=======================================================================
554
555 BRepLib_MakeEdge::BRepLib_MakeEdge(const Handle(Geom2d_Curve)& L,
556                                    const Handle(Geom_Surface)& S)
557 {
558   Init(L,S);
559 }
560
561
562 //=======================================================================
563 //function : BRepLib_MakeEdge
564 //purpose  : 
565 //=======================================================================
566
567 BRepLib_MakeEdge::BRepLib_MakeEdge(const Handle(Geom2d_Curve)& L,
568                                    const Handle(Geom_Surface)& S,
569                                    const Standard_Real p1,
570                                    const Standard_Real p2)
571 {
572   Init(L,S,p1,p2);
573 }
574
575
576 //=======================================================================
577 //function : BRepLib_MakeEdge
578 //purpose  : 
579 //=======================================================================
580
581 BRepLib_MakeEdge::BRepLib_MakeEdge(const Handle(Geom2d_Curve)& L,
582                                    const Handle(Geom_Surface)& S,
583                                    const gp_Pnt& P1,
584                                    const gp_Pnt& P2)
585 {
586   Init(L,S,P1,P2);
587 }
588
589 //=======================================================================
590 //function : BRepLib_MakeEdge
591 //purpose  : 
592 //=======================================================================
593
594 BRepLib_MakeEdge::BRepLib_MakeEdge(const Handle(Geom2d_Curve)& L,
595                                    const Handle(Geom_Surface)& S,
596                                    const TopoDS_Vertex& V1,
597                                    const TopoDS_Vertex& V2)
598 {
599   Init(L,S,V1,V2);
600 }
601
602
603 //=======================================================================
604 //function : BRepLib_MakeEdge
605 //purpose  : 
606 //=======================================================================
607
608 BRepLib_MakeEdge::BRepLib_MakeEdge(const Handle(Geom2d_Curve)& L,
609                                    const Handle(Geom_Surface)& S,
610                                    const gp_Pnt& P1,
611                                    const gp_Pnt& P2,
612                                    const Standard_Real p1,
613                                    const Standard_Real p2)
614 {
615   Init(L,S,P1,P2,p1,p2);
616 }
617
618
619 //=======================================================================
620 //function : BRepLib_MakeEdge
621 //purpose  : 
622 //=======================================================================
623
624 BRepLib_MakeEdge::BRepLib_MakeEdge(const Handle(Geom2d_Curve)& L,
625                                    const Handle(Geom_Surface)& S,
626                                    const TopoDS_Vertex& V1,
627                                    const TopoDS_Vertex& V2,
628                                    const Standard_Real p1,
629                                    const Standard_Real p2)
630 {
631   Init(L,S,V1,V2,p1,p2);
632 }
633
634
635 //=======================================================================
636 //function : Init
637 //purpose  : 
638 //=======================================================================
639
640 void  BRepLib_MakeEdge::Init(const Handle(Geom_Curve)& C)
641 {
642   Init(C,C->FirstParameter(),C->LastParameter());
643 }
644
645
646 //=======================================================================
647 //function : Init
648 //purpose  : 
649 //=======================================================================
650
651 void  BRepLib_MakeEdge::Init(const Handle(Geom_Curve)& C,
652                              const Standard_Real p1,
653                              const Standard_Real p2)
654 {
655 //  BRep_Builder B;
656
657   TopoDS_Vertex V1,V2;
658   Init(C,V1,V2,p1,p2);
659 }
660
661
662 //=======================================================================
663 //function : Init
664 //purpose  : 
665 //=======================================================================
666
667 void  BRepLib_MakeEdge::Init(const Handle(Geom_Curve)& C,
668                              const gp_Pnt& P1,
669                              const gp_Pnt& P2)
670 {
671   Standard_Real Tol = BRepLib::Precision();
672
673   BRep_Builder B;
674   TopoDS_Vertex V1,V2;
675   B.MakeVertex(V1,P1,Tol);
676   if (P1.Distance(P2) < Tol)
677     V2 = V1;
678   else
679     B.MakeVertex(V2,P2,Tol);
680   
681   Init(C,V1,V2);
682 }
683
684
685 //=======================================================================
686 //function : Init
687 //purpose  : 
688 //=======================================================================
689
690 void  BRepLib_MakeEdge::Init(const Handle(Geom_Curve)& C,
691                              const TopoDS_Vertex& V1,
692                              const TopoDS_Vertex& V2)
693 {
694   // try projecting the vertices on the curve
695
696   Standard_Real p1,p2;
697   
698   if (V1.IsNull())
699     p1 = C->FirstParameter();
700   else
701     if (!Project(C,V1,p1)) {
702       myError = BRepLib_PointProjectionFailed;
703       return;
704     }
705   if (V2.IsNull())
706     p2 = C->LastParameter();
707   else
708     if (!Project(C,V2,p2))  {
709       myError = BRepLib_PointProjectionFailed;
710       return;
711     }
712   
713   Init(C,V1,V2,p1,p2);
714 }
715
716
717 //=======================================================================
718 //function : Init
719 //purpose  : 
720 //=======================================================================
721
722 void  BRepLib_MakeEdge::Init(const Handle(Geom_Curve)& C,
723                              const gp_Pnt& P1,
724                              const gp_Pnt& P2,
725                              const Standard_Real p1,
726                              const Standard_Real p2)
727 {
728   Standard_Real Tol = BRepLib::Precision();
729   BRep_Builder B;
730
731   TopoDS_Vertex V1,V2;
732   B.MakeVertex(V1,P1,Tol);
733   if (P1.Distance(P2) < Tol)
734     V2 = V1;
735   else
736     B.MakeVertex(V2,P2,Tol);
737   
738   Init(C,V1,V2,p1,p2);
739 }
740
741
742 //=======================================================================
743 //function : Init
744 //purpose  : this one really makes the job ...
745 //=======================================================================
746
747 void  BRepLib_MakeEdge::Init(const Handle(Geom_Curve)& CC,
748                              const TopoDS_Vertex& VV1,
749                              const TopoDS_Vertex& VV2,
750                              const Standard_Real pp1,
751                              const Standard_Real pp2)
752 {
753   // kill trimmed curves
754   Handle(Geom_Curve) C = CC;
755   Handle(Geom_TrimmedCurve) CT = Handle(Geom_TrimmedCurve)::DownCast(C);
756   while (!CT.IsNull()) {
757     C = CT->BasisCurve();
758     CT = Handle(Geom_TrimmedCurve)::DownCast(C);
759   }
760
761   // check parameters
762   Standard_Real p1 = pp1;
763   Standard_Real p2 = pp2;
764   Standard_Real cf = C->FirstParameter();
765   Standard_Real cl = C->LastParameter();
766   Standard_Real epsilon = Precision::Confusion();
767   Standard_Boolean periodic = C->IsPeriodic();
768
769
770   TopoDS_Vertex V1,V2;
771   if (periodic) {
772     // adjust in period
773     ElCLib::AdjustPeriodic(cf,cl,epsilon,p1,p2);
774     V1 = VV1;
775     V2 = VV2;
776   }
777   else {
778     // reordonate
779     if (p1 < p2) {
780       V1 = VV1;
781       V2 = VV2;
782     }
783     else {
784       V2 = VV1;
785       V1 = VV2;
786       Standard_Real x = p1;
787       p1 = p2;
788       p2 = x;
789     }
790
791     // check range
792     if ((cf - p1 > epsilon) || (p2 - cl > epsilon)) {
793       myError = BRepLib_ParameterOutOfRange;
794       return;
795     }
796
797     // check ponctuallity
798     if ((p2-p1) <= gp::Resolution()) {
799       myError = BRepLib_LineThroughIdenticPoints;
800       return;
801     }
802   }
803   
804   // compute points on the curve
805   Standard_Boolean p1inf = Precision::IsNegativeInfinite(p1);
806   Standard_Boolean p2inf = Precision::IsPositiveInfinite(p2);
807   gp_Pnt P1,P2;
808   if (!p1inf) P1 = C->Value(p1);
809   if (!p2inf) P2 = C->Value(p2);
810
811   Standard_Real preci = BRepLib::Precision();
812   BRep_Builder B;
813
814   // check for closed curve
815   Standard_Boolean closed = Standard_False;
816   if (!p1inf && !p2inf)
817     closed = (P1.Distance(P2) <= preci);
818
819   // check if the vertices are on the curve
820   if (closed) {
821     if (V1.IsNull() && V2.IsNull()) {
822       B.MakeVertex(V1,P1,preci);
823       V2 = V1;
824     }
825     else if (V1.IsNull())
826       V1 = V2;
827     else if (V2.IsNull())
828       V2 = V1;
829     else {
830       if (!V1.IsSame(V2)) {
831         myError = BRepLib_DifferentPointsOnClosedCurve;
832         return;
833       }
834       else if (P1.Distance(BRep_Tool::Pnt(V1)) > 
835                Max(preci,BRep_Tool::Tolerance(V1))) {
836         myError = BRepLib_DifferentPointsOnClosedCurve;
837         return;
838       }
839     }
840   }
841
842   else {    // not closed
843
844     if (p1inf) {
845       if (!V1.IsNull()) {
846         myError = BRepLib_PointWithInfiniteParameter;
847         return;
848       }
849     }
850     else {
851       if (V1.IsNull()) {
852         B.MakeVertex(V1,P1,preci);
853       }
854       else if (P1.Distance(BRep_Tool::Pnt(V1)) >
855                Max(preci,BRep_Tool::Tolerance(V1))) {
856         myError = BRepLib_DifferentsPointAndParameter;
857         return;
858       }
859     }
860     
861     if (p2inf) {
862       if (!V2.IsNull()) {
863         myError = BRepLib_PointWithInfiniteParameter;
864         return;
865       }
866     }
867     else {
868       if (V2.IsNull()) {
869         B.MakeVertex(V2,P2,preci);
870       }
871       else if (P2.Distance(BRep_Tool::Pnt(V2)) >
872                Max(preci,BRep_Tool::Tolerance(V2))){
873         myError = BRepLib_DifferentsPointAndParameter;
874         return;
875       }
876     }
877   }
878
879   V1.Orientation(TopAbs_FORWARD);
880   V2.Orientation(TopAbs_REVERSED);
881   myVertex1 = V1;
882   myVertex2 = V2;
883
884   TopoDS_Edge& E = TopoDS::Edge(myShape);
885   B.MakeEdge(E,C,preci);
886   if (!V1.IsNull()) {
887     B.Add(E,V1);
888   }
889   if (!V2.IsNull()) {
890     B.Add(E,V2);
891   }
892   B.Range(E,p1,p2);
893
894   myError = BRepLib_EdgeDone;
895   Done();
896 }
897
898 //=======================================================================
899 //function : Init
900 //purpose  : 
901 //=======================================================================
902
903 void  BRepLib_MakeEdge::Init(const Handle(Geom2d_Curve)& C,
904                              const Handle(Geom_Surface)& S)
905 {
906   Init(C,S,C->FirstParameter(),C->LastParameter());
907 }
908
909
910 //=======================================================================
911 //function : Init
912 //purpose  : 
913 //=======================================================================
914
915 void  BRepLib_MakeEdge::Init(const Handle(Geom2d_Curve)& C,
916                              const Handle(Geom_Surface)& S,
917                              const Standard_Real p1,
918                              const Standard_Real p2)
919 {
920 //  BRep_Builder B;
921
922   TopoDS_Vertex V1,V2;
923   Init(C,S,V1,V2,p1,p2);
924 }
925
926
927 //=======================================================================
928 //function : Init
929 //purpose  : 
930 //=======================================================================
931
932 void  BRepLib_MakeEdge::Init(const Handle(Geom2d_Curve)& C,
933                              const Handle(Geom_Surface)& S,
934                              const gp_Pnt& P1,
935                              const gp_Pnt& P2)
936 {
937   Standard_Real Tol = BRepLib::Precision();
938   
939   BRep_Builder B;
940   TopoDS_Vertex V1,V2;
941   B.MakeVertex(V1,P1,Tol);
942   if (P1.Distance(P2) < Tol)
943     V2 = V1;
944   else
945     B.MakeVertex(V2,P2,Tol);
946   
947   Init(C,S,V1,V2);
948 }
949
950
951 //=======================================================================
952 //function : Init
953 //purpose  : 
954 //=======================================================================
955
956 void  BRepLib_MakeEdge::Init(const Handle(Geom2d_Curve)& C,
957                              const Handle(Geom_Surface)& S,
958                              const TopoDS_Vertex& V1,
959                              const TopoDS_Vertex& V2)
960 {
961   // try projecting the vertices on the curve
962
963   Standard_Real p1,p2;
964   
965   if (V1.IsNull())
966     p1 = C->FirstParameter();
967   else
968     if (!Project(C,S,V1,p1)) {
969       myError = BRepLib_PointProjectionFailed;
970       return;
971     }
972   if (V2.IsNull())
973     p2 = C->LastParameter();
974   else
975     if (!Project(C,S,V2,p2))  {
976       myError = BRepLib_PointProjectionFailed;
977       return;
978     }
979   
980   Init(C,S,V1,V2,p1,p2);
981 }
982
983
984 //=======================================================================
985 //function : Init
986 //purpose  : 
987 //=======================================================================
988
989 void  BRepLib_MakeEdge::Init(const Handle(Geom2d_Curve)& C,
990                              const Handle(Geom_Surface)& S,
991                              const gp_Pnt& P1,
992                              const gp_Pnt& P2,
993                              const Standard_Real p1,
994                              const Standard_Real p2)
995 {
996   Standard_Real Tol = BRepLib::Precision();
997   BRep_Builder B;
998
999   TopoDS_Vertex V1,V2;
1000   B.MakeVertex(V1,P1,Tol);
1001   if (P1.Distance(P2) < Tol)
1002     V2 = V1;
1003   else
1004     B.MakeVertex( V2, P2, Tol);
1005   
1006   Init(C,S,V1,V2,p1,p2);
1007 }
1008
1009
1010 //=======================================================================
1011 //function : Init
1012 //purpose  : this one really makes the job ...
1013 //=======================================================================
1014
1015 void  BRepLib_MakeEdge::Init(const Handle(Geom2d_Curve)& CC,
1016                              const Handle(Geom_Surface)& S,
1017                              const TopoDS_Vertex& VV1,
1018                              const TopoDS_Vertex& VV2,
1019                              const Standard_Real pp1,
1020                              const Standard_Real pp2)
1021 {
1022   // kill trimmed curves
1023   Handle(Geom2d_Curve) C = CC;
1024   Handle(Geom2d_TrimmedCurve) CT = Handle(Geom2d_TrimmedCurve)::DownCast(C);
1025   while (!CT.IsNull()) {
1026     C = CT->BasisCurve();
1027     CT = Handle(Geom2d_TrimmedCurve)::DownCast(C);
1028   }
1029
1030   // check parameters
1031   Standard_Real p1 = pp1;
1032   Standard_Real p2 = pp2;
1033   Standard_Real cf = C->FirstParameter();
1034   Standard_Real cl = C->LastParameter();
1035   Standard_Real epsilon = Precision::Confusion();
1036   Standard_Boolean periodic = C->IsPeriodic();
1037
1038
1039   TopoDS_Vertex V1,V2;
1040   Standard_Boolean reverse = Standard_False;
1041
1042   if (periodic) {
1043     // adjust in period
1044     ElCLib::AdjustPeriodic(cf,cl,epsilon,p1,p2);
1045     V1 = VV1;
1046     V2 = VV2;
1047   }
1048   else {
1049     // reordonate
1050     if (p1 < p2) {
1051       V1 = VV1;
1052       V2 = VV2;
1053     }
1054     else {
1055       V2 = VV1;
1056       V1 = VV2;
1057       Standard_Real x = p1;
1058       p1 = p2;
1059       p2 = x;
1060       reverse = Standard_True;
1061     }
1062
1063     // check range
1064     if ((cf - p1 > epsilon) || (p2 - cl > epsilon)) {
1065       myError = BRepLib_ParameterOutOfRange;
1066       return;
1067     }
1068   }
1069   
1070   // compute points on the curve
1071   Standard_Boolean p1inf = Precision::IsNegativeInfinite(p1);
1072   Standard_Boolean p2inf = Precision::IsPositiveInfinite(p2);
1073   gp_Pnt P1,P2;
1074   gp_Pnt2d P2d1,P2d2;
1075   if (!p1inf) {
1076     P2d1 = C->Value(p1);
1077     P1   = S->Value(P2d1.X(),P2d1.Y());
1078   }
1079   if (!p2inf) {
1080     P2d2 = C->Value(p2);
1081     P2   = S->Value(P2d2.X(),P2d2.Y());
1082   }
1083
1084   Standard_Real preci = BRepLib::Precision();
1085   BRep_Builder B;
1086
1087   // check for closed curve
1088   Standard_Boolean closed = Standard_False;
1089   if (!p1inf && !p2inf)
1090     closed = (P1.Distance(P2) <= preci);
1091
1092   // check if the vertices are on the curve
1093   if (closed) {
1094     if (V1.IsNull() && V2.IsNull()) {
1095       B.MakeVertex(V1,P1,preci);
1096       V2 = V1;
1097     }
1098     else if (V1.IsNull())
1099       V1 = V2;
1100     else if (V2.IsNull())
1101       V2 = V1;
1102     else {
1103       if (!V1.IsSame(V2)) {
1104         myError = BRepLib_DifferentPointsOnClosedCurve;
1105         return;
1106       }
1107       else if (P1.Distance(BRep_Tool::Pnt(V1)) > 
1108                Max(preci,BRep_Tool::Tolerance(V1))) {
1109         myError = BRepLib_DifferentPointsOnClosedCurve;
1110         return;
1111       }
1112     }
1113   }
1114
1115   else {    // not closed
1116
1117     if (p1inf) {
1118       if (!V1.IsNull()) {
1119         myError = BRepLib_PointWithInfiniteParameter;
1120         return;
1121       }
1122     }
1123     else {
1124       if (V1.IsNull()) {
1125         B.MakeVertex(V1,P1,preci);
1126       }
1127       else if (P1.Distance(BRep_Tool::Pnt(V1)) >
1128                Max(preci,BRep_Tool::Tolerance(V1))) {
1129         myError = BRepLib_DifferentsPointAndParameter;
1130         return;
1131       }
1132     }
1133     
1134     if (p2inf) {
1135       if (!V2.IsNull()) {
1136         myError = BRepLib_PointWithInfiniteParameter;
1137         return;
1138       }
1139     }
1140     else {
1141       if (V2.IsNull()) {
1142         B.MakeVertex(V2,P2,preci);
1143       }
1144       else if (P2.Distance(BRep_Tool::Pnt(V2)) >
1145                Max(preci,BRep_Tool::Tolerance(V2))){
1146         myError = BRepLib_DifferentsPointAndParameter;
1147         return;
1148       }
1149     }
1150   }
1151
1152   V1.Orientation(TopAbs_FORWARD);
1153   V2.Orientation(TopAbs_REVERSED);
1154   myVertex1 = V1;
1155   myVertex2 = V2;
1156
1157   TopoDS_Edge& E = TopoDS::Edge(myShape);
1158   B.MakeEdge(E);
1159   B.UpdateEdge(E,C,S,TopLoc_Location(),preci);
1160
1161   if (!V1.IsNull()) {
1162     B.Add(E,V1);
1163   }
1164   if (!V2.IsNull()) {
1165     B.Add(E,V2);
1166   }
1167   B.Range(E,p1,p2);
1168
1169   if (reverse)
1170     E.Orientation(TopAbs_REVERSED);
1171
1172   myError = BRepLib_EdgeDone;
1173   Done();
1174 }
1175
1176 //=======================================================================
1177 //function : Error
1178 //purpose  : 
1179 //=======================================================================
1180
1181 BRepLib_EdgeError BRepLib_MakeEdge::Error() const
1182 {
1183   return myError;
1184 }
1185
1186 //=======================================================================
1187 //function : Edge
1188 //purpose  : 
1189 //=======================================================================
1190
1191 const TopoDS_Edge&  BRepLib_MakeEdge::Edge()const 
1192 {
1193   return TopoDS::Edge(Shape());
1194 }
1195
1196
1197 //=======================================================================
1198 //function : Vertex1
1199 //purpose  : 
1200 //=======================================================================
1201
1202 const TopoDS_Vertex&  BRepLib_MakeEdge::Vertex1()const 
1203 {
1204   Check();
1205   return myVertex1;
1206 }
1207
1208
1209 //=======================================================================
1210 //function : Vertex2
1211 //purpose  : 
1212 //=======================================================================
1213
1214 const TopoDS_Vertex&  BRepLib_MakeEdge::Vertex2()const 
1215 {
1216   Check();
1217   return myVertex2;
1218 }
1219
1220
1221
1222 //=======================================================================
1223 //function : operator
1224 //purpose  : 
1225 //=======================================================================
1226
1227 BRepLib_MakeEdge::operator TopoDS_Edge() const
1228 {
1229   return Edge();
1230 }