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