0024428: Implementation of LGPL license
[occt.git] / src / BRepLib / BRepLib_MakeEdge2d.cxx
CommitLineData
b311480e 1// Created on: 1995-01-04
2// Created by: Bruno DUMORTIER
3// Copyright (c) 1995-1999 Matra Datavision
973c2be1 4// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 5//
973c2be1 6// This file is part of Open CASCADE Technology software library.
b311480e 7//
973c2be1 8// This library is free software; you can redistribute it and / or modify it
9// under the terms of the GNU Lesser General Public 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.
b311480e 13//
973c2be1 14// Alternatively, this file may be used under the terms of Open CASCADE
15// commercial license or contractual agreement.
7fd59977 16
17#include <BRepLib_MakeEdge2d.ixx>
18
19#include <BRepLib.hxx>
20#include <BRep_Tool.hxx>
21#include <BRep_Builder.hxx>
22#include <TopoDS.hxx>
23#include <Geom_Plane.hxx>
24#include <Geom2d_Line.hxx>
25#include <Geom2d_Circle.hxx>
26#include <Geom2d_Ellipse.hxx>
27#include <Geom2d_Parabola.hxx>
28#include <Geom2d_Hyperbola.hxx>
29#include <Geom2d_TrimmedCurve.hxx>
30#include <Geom2dAdaptor_Curve.hxx>
31#include <Extrema_ExtPC2d.hxx>
32#include <gp.hxx>
33#include <ElCLib.hxx>
34#include <ElSLib.hxx>
35#include <Precision.hxx>
36
37
38//=======================================================================
39//function : Point
40//purpose : make a 3d point on the current plane
41//=======================================================================
42
43static gp_Pnt Point(const gp_Pnt2d& P)
44{
45 return BRepLib::Plane()->Value(P.X(),P.Y());
46}
47
48//=======================================================================
49//function : Project
50//purpose : project a vertex on the current plane
51//=======================================================================
52
53static gp_Pnt2d Project(const TopoDS_Vertex& Ve)
54{
55 gp_Pnt P = BRep_Tool::Pnt(Ve);
56 Standard_Real U,V;
57 ElSLib::Parameters(BRepLib::Plane()->Pln(),P,U,V);
58 return gp_Pnt2d(U,V);
59}
60
61//=======================================================================
62//function : Project
63//purpose : project a vertex on a curve
64//=======================================================================
65
66static Standard_Boolean Project(const Handle(Geom2d_Curve)& C,
67 const TopoDS_Vertex& V,
68 Standard_Real& p)
69{
70 gp_Pnt2d P = Project(V);
71 Geom2dAdaptor_Curve AC(C);
72 if (AC.GetType() == GeomAbs_Line) {
73 p = ElCLib::LineParameter(AC.Line().Position(),P);
74 }
75 else if (AC.GetType() == GeomAbs_Circle) {
76 p = ElCLib::CircleParameter(AC.Circle().Position(),P);
77 }
78 else {
79 Extrema_ExtPC2d extrema(P,AC);
80 if (extrema.IsDone()) {
81 Standard_Integer i,n = extrema.NbExt();
82
83 Standard_Real d2 = RealLast();
84 for (i = 1; i <= n; i++) {
85 //OCC16852:if (extrema.IsMin(i)) {
86 const Standard_Real dd2 = extrema.SquareDistance(i);
87 if (dd2 < d2) {
88 d2 = dd2;
89 p = extrema.Point(i).Parameter();
90 }
91 //OCC16852:}
92 }
93 }
94 else
95 return Standard_False;
96 }
97 return Standard_True;
98}
99
100//=======================================================================
101//function : BRepLib_MakeEdge2d
102//purpose :
103//=======================================================================
104
105BRepLib_MakeEdge2d::BRepLib_MakeEdge2d(const TopoDS_Vertex& V1,
106 const TopoDS_Vertex& V2)
107{
108 gp_Pnt2d P1 = Project(V1);
109 gp_Pnt2d P2 = Project(V2);
110 Standard_Real l = P1.Distance(P2);
111 if (l <= gp::Resolution()) {
112 myError = BRepLib_LineThroughIdenticPoints;
113 return;
114 }
115 gp_Lin2d L(P1,gp_Vec2d(P1,P2));
116 Handle(Geom2d_Line) GL = new Geom2d_Line(L);
117 Init(GL,V1,V2,0,l);
118}
119
120//=======================================================================
121//function : BRepLib_MakeEdge2d
122//purpose :
123//=======================================================================
124
125BRepLib_MakeEdge2d::BRepLib_MakeEdge2d(const gp_Pnt2d& P1,
126 const gp_Pnt2d& P2)
127{
128 Standard_Real l = P1.Distance(P2);
129 if (l <= gp::Resolution()) {
130 myError = BRepLib_LineThroughIdenticPoints;
131 return;
132 }
133 gp_Lin2d L(P1,gp_Vec2d(P1,P2));
134 Handle(Geom2d_Line) GL = new Geom2d_Line(L);
135 Init(GL,P1,P2,0,l);
136}
137
138
139//=======================================================================
140//function : BRepLib_MakeEdge2d
141//purpose :
142//=======================================================================
143
144BRepLib_MakeEdge2d::BRepLib_MakeEdge2d(const gp_Lin2d& L)
145{
146 Handle(Geom2d_Line) GL = new Geom2d_Line(L);
147 Init(GL);
148}
149
150//=======================================================================
151//function : BRepLib_MakeEdge2d
152//purpose :
153//=======================================================================
154
155BRepLib_MakeEdge2d::BRepLib_MakeEdge2d(const gp_Lin2d& L,
156 const Standard_Real p1,
157 const Standard_Real p2)
158{
159 Handle(Geom2d_Line) GL = new Geom2d_Line(L);
160 Init(GL,p1,p2);
161}
162
163//=======================================================================
164//function : BRepLib_MakeEdge2d
165//purpose :
166//=======================================================================
167
168BRepLib_MakeEdge2d::BRepLib_MakeEdge2d(const gp_Lin2d& L,
169 const gp_Pnt2d& P1,
170 const gp_Pnt2d& P2)
171{
172 Handle(Geom2d_Line) GL = new Geom2d_Line(L);
173 Init(GL,P1,P2);
174}
175
176//=======================================================================
177//function : BRepLib_MakeEdge2d
178//purpose :
179//=======================================================================
180
181BRepLib_MakeEdge2d::BRepLib_MakeEdge2d(const gp_Lin2d& L,
182 const TopoDS_Vertex& V1,
183 const TopoDS_Vertex& V2)
184{
185 Handle(Geom2d_Line) GL = new Geom2d_Line(L);
186 Init(GL,V1,V2);
187}
188
189//=======================================================================
190//function : BRepLib_MakeEdge2d
191//purpose :
192//=======================================================================
193
194BRepLib_MakeEdge2d::BRepLib_MakeEdge2d(const gp_Circ2d& C)
195{
196 Handle(Geom2d_Circle) GC = new Geom2d_Circle(C);
197 Init(GC);
198}
199
200//=======================================================================
201//function : BRepLib_MakeEdge2d
202//purpose :
203//=======================================================================
204
205BRepLib_MakeEdge2d::BRepLib_MakeEdge2d(const gp_Circ2d& C,
206 const Standard_Real p1,
207 const Standard_Real p2)
208{
209 Handle(Geom2d_Circle) GC = new Geom2d_Circle(C);
210 Init(GC,p1,p2);
211}
212
213//=======================================================================
214//function : BRepLib_MakeEdge2d
215//purpose :
216//=======================================================================
217
218BRepLib_MakeEdge2d::BRepLib_MakeEdge2d(const gp_Circ2d& C,
219 const gp_Pnt2d& P1,
220 const gp_Pnt2d& P2)
221{
222 Handle(Geom2d_Circle) GC = new Geom2d_Circle(C);
223 Init(GC,P1,P2);
224}
225
226//=======================================================================
227//function : BRepLib_MakeEdge2d
228//purpose :
229//=======================================================================
230
231BRepLib_MakeEdge2d::BRepLib_MakeEdge2d(const gp_Circ2d& C,
232 const TopoDS_Vertex& V1,
233 const TopoDS_Vertex& V2)
234{
235 Handle(Geom2d_Circle) GC = new Geom2d_Circle(C);
236 Init(GC,V1,V2);
237}
238
239//=======================================================================
240//function : BRepLib_MakeEdge2d
241//purpose :
242//=======================================================================
243
244BRepLib_MakeEdge2d::BRepLib_MakeEdge2d(const gp_Elips2d& E)
245{
246 Handle(Geom2d_Ellipse) GE = new Geom2d_Ellipse(E);
247 Init(GE);
248}
249
250//=======================================================================
251//function : BRepLib_MakeEdge2d
252//purpose :
253//=======================================================================
254
255BRepLib_MakeEdge2d::BRepLib_MakeEdge2d(const gp_Elips2d& E,
256 const Standard_Real p1,
257 const Standard_Real p2)
258{
259 Handle(Geom2d_Ellipse) GE = new Geom2d_Ellipse(E);
260 Init(GE,p1,p2);
261}
262
263//=======================================================================
264//function : BRepLib_MakeEdge2d
265//purpose :
266//=======================================================================
267
268BRepLib_MakeEdge2d::BRepLib_MakeEdge2d(const gp_Elips2d& E,
269 const gp_Pnt2d& P1,
270 const gp_Pnt2d& P2)
271{
272 Handle(Geom2d_Ellipse) GE = new Geom2d_Ellipse(E);
273 Init(GE,P1,P2);
274}
275
276//=======================================================================
277//function : BRepLib_MakeEdge2d
278//purpose :
279//=======================================================================
280
281BRepLib_MakeEdge2d::BRepLib_MakeEdge2d(const gp_Elips2d& E,
282 const TopoDS_Vertex& V1,
283 const TopoDS_Vertex& V2)
284{
285 Handle(Geom2d_Ellipse) GE = new Geom2d_Ellipse(E);
286 Init(GE,V1,V2);
287}
288
289//=======================================================================
290//function : BRepLib_MakeEdge2d
291//purpose :
292//=======================================================================
293
294BRepLib_MakeEdge2d::BRepLib_MakeEdge2d(const gp_Hypr2d& H)
295{
296 Handle(Geom2d_Hyperbola) GH = new Geom2d_Hyperbola(H);
297 Init(GH);
298}
299
300//=======================================================================
301//function : BRepLib_MakeEdge2d
302//purpose :
303//=======================================================================
304
305BRepLib_MakeEdge2d::BRepLib_MakeEdge2d(const gp_Hypr2d& H,
306 const Standard_Real p1,
307 const Standard_Real p2)
308{
309 Handle(Geom2d_Hyperbola) GH = new Geom2d_Hyperbola(H);
310 Init(GH,p1,p2);
311}
312
313//=======================================================================
314//function : BRepLib_MakeEdge2d
315//purpose :
316//=======================================================================
317
318BRepLib_MakeEdge2d::BRepLib_MakeEdge2d(const gp_Hypr2d& H,
319 const gp_Pnt2d& P1,
320 const gp_Pnt2d& P2)
321{
322 Handle(Geom2d_Hyperbola) GH = new Geom2d_Hyperbola(H);
323 Init(GH,P1,P2);
324}
325
326//=======================================================================
327//function : BRepLib_MakeEdge2d
328//purpose :
329//=======================================================================
330
331BRepLib_MakeEdge2d::BRepLib_MakeEdge2d(const gp_Hypr2d& H,
332 const TopoDS_Vertex& V1,
333 const TopoDS_Vertex& V2)
334{
335 Handle(Geom2d_Hyperbola) GH = new Geom2d_Hyperbola(H);
336 Init(GH,V1,V2);
337}
338
339//=======================================================================
340//function : BRepLib_MakeEdge2d
341//purpose :
342//=======================================================================
343
344BRepLib_MakeEdge2d::BRepLib_MakeEdge2d(const gp_Parab2d& P)
345{
346 Handle(Geom2d_Parabola) GP = new Geom2d_Parabola(P);
347 Init(GP);
348}
349
350//=======================================================================
351//function : BRepLib_MakeEdge2d
352//purpose :
353//=======================================================================
354
355BRepLib_MakeEdge2d::BRepLib_MakeEdge2d(const gp_Parab2d& P,
356 const Standard_Real p1,
357 const Standard_Real p2)
358{
359 Handle(Geom2d_Parabola) GP = new Geom2d_Parabola(P);
360 Init(GP,p1,p2);
361}
362
363//=======================================================================
364//function : BRepLib_MakeEdge2d
365//purpose :
366//=======================================================================
367
368BRepLib_MakeEdge2d::BRepLib_MakeEdge2d(const gp_Parab2d& P,
369 const gp_Pnt2d& P1,
370 const gp_Pnt2d& P2)
371{
372 Handle(Geom2d_Parabola) GP = new Geom2d_Parabola(P);
373 Init(GP,P1,P2);
374}
375
376//=======================================================================
377//function : BRepLib_MakeEdge2d
378//purpose :
379//=======================================================================
380
381BRepLib_MakeEdge2d::BRepLib_MakeEdge2d(const gp_Parab2d& P,
382 const TopoDS_Vertex& V1,
383 const TopoDS_Vertex& V2)
384{
385 Handle(Geom2d_Parabola) GP = new Geom2d_Parabola(P);
386 Init(GP,V1,V2);
387}
388
389//=======================================================================
390//function : BRepLib_MakeEdge2d
391//purpose :
392//=======================================================================
393
394BRepLib_MakeEdge2d::BRepLib_MakeEdge2d(const Handle(Geom2d_Curve)& L)
395{
396 Init(L);
397}
398
399//=======================================================================
400//function : BRepLib_MakeEdge2d
401//purpose :
402//=======================================================================
403
404BRepLib_MakeEdge2d::BRepLib_MakeEdge2d(const Handle(Geom2d_Curve)& L,
405 const Standard_Real p1,
406 const Standard_Real p2)
407{
408 Init(L,p1,p2);
409}
410
411//=======================================================================
412//function : BRepLib_MakeEdge2d
413//purpose :
414//=======================================================================
415
416BRepLib_MakeEdge2d::BRepLib_MakeEdge2d(const Handle(Geom2d_Curve)& L,
417 const gp_Pnt2d& P1,
418 const gp_Pnt2d& P2)
419{
420 Init(L,P1,P2);
421}
422
423//=======================================================================
424//function : BRepLib_MakeEdge2d
425//purpose :
426//=======================================================================
427
428BRepLib_MakeEdge2d::BRepLib_MakeEdge2d(const Handle(Geom2d_Curve)& L,
429 const TopoDS_Vertex& V1,
430 const TopoDS_Vertex& V2)
431{
432 Init(L,V1,V2);
433}
434
435//=======================================================================
436//function : BRepLib_MakeEdge2d
437//purpose :
438//=======================================================================
439
440BRepLib_MakeEdge2d::BRepLib_MakeEdge2d(const Handle(Geom2d_Curve)& L,
441 const gp_Pnt2d& P1,
442 const gp_Pnt2d& P2,
443 const Standard_Real p1,
444 const Standard_Real p2)
445{
446 Init(L,P1,P2,p1,p2);
447}
448
449//=======================================================================
450//function : BRepLib_MakeEdge2d
451//purpose :
452//=======================================================================
453
454BRepLib_MakeEdge2d::BRepLib_MakeEdge2d(const Handle(Geom2d_Curve)& L,
455 const TopoDS_Vertex& V1,
456 const TopoDS_Vertex& V2,
457 const Standard_Real p1,
458 const Standard_Real p2)
459{
460 Init(L,V1,V2,p1,p2);
461}
462
463//=======================================================================
464//function : Init
465//purpose :
466//=======================================================================
467
468void BRepLib_MakeEdge2d::Init(const Handle(Geom2d_Curve)& C)
469{
470 Init(C,C->FirstParameter(),C->LastParameter());
471}
472
473//=======================================================================
474//function : Init
475//purpose :
476//=======================================================================
477
478void BRepLib_MakeEdge2d::Init(const Handle(Geom2d_Curve)& C,
479 const Standard_Real p1,
480 const Standard_Real p2)
481{
482// BRep_Builder B;
483
484 TopoDS_Vertex V1,V2;
485 Init(C,V1,V2,p1,p2);
486}
487
488//=======================================================================
489//function : Init
490//purpose :
491//=======================================================================
492
493void BRepLib_MakeEdge2d::Init(const Handle(Geom2d_Curve)& C,
494 const gp_Pnt2d& P1,
495 const gp_Pnt2d& P2)
496{
497 BRep_Builder B;
498 TopoDS_Vertex V1,V2;
499 B.MakeVertex(V1,Point(P1),Precision::Confusion());
500 if (P1.Distance(P2) < Precision::Confusion())
501 V2 = V1;
502 else
503 B.MakeVertex(V2,Point(P2),Precision::Confusion());
504 Init(C,V1,V2);
505}
506
507//=======================================================================
508//function : Init
509//purpose :
510//=======================================================================
511
512void BRepLib_MakeEdge2d::Init(const Handle(Geom2d_Curve)& C,
513 const TopoDS_Vertex& V1,
514 const TopoDS_Vertex& V2)
515{
516 // try projecting the vertices on the curve
517
518 Standard_Real p1,p2;
519
520 if (V1.IsNull())
521 p1 = C->FirstParameter();
522 else
523 if (!Project(C,V1,p1)) {
524 myError = BRepLib_PointProjectionFailed;
525 return;
526 }
527 if (V2.IsNull())
528 p2 = C->LastParameter();
529 else
530 if (!Project(C,V2,p2)) {
531 myError = BRepLib_PointProjectionFailed;
532 return;
533 }
534
535 Init(C,V1,V2,p1,p2);
536}
537
538
539//=======================================================================
540//function : Init
541//purpose :
542//=======================================================================
543
544void BRepLib_MakeEdge2d::Init(const Handle(Geom2d_Curve)& C,
545 const gp_Pnt2d& P1,
546 const gp_Pnt2d& P2,
547 const Standard_Real p1,
548 const Standard_Real p2)
549{
550 BRep_Builder B;
551
552 TopoDS_Vertex V1,V2;
553 B.MakeVertex(V1,Point(P1),Precision::Confusion());
554 if (P1.Distance(P2) < Precision::Confusion())
555 V2 = V1;
556 else
557 B.MakeVertex(V2,Point(P2),Precision::Confusion());
558
559
560 Init(C,V1,V2,p1,p2);
561}
562
563
564//=======================================================================
565//function : Init
566//purpose : this one really makes the job ...
567//=======================================================================
568
569void BRepLib_MakeEdge2d::Init(const Handle(Geom2d_Curve)& CC,
570 const TopoDS_Vertex& VV1,
571 const TopoDS_Vertex& VV2,
572 const Standard_Real pp1,
573 const Standard_Real pp2)
574{
575 // kill trimmed curves
576 Handle(Geom2d_Curve) C = CC;
577 Handle(Geom2d_TrimmedCurve) CT = Handle(Geom2d_TrimmedCurve)::DownCast(C);
578 while (!CT.IsNull()) {
579 C = CT->BasisCurve();
580 CT = Handle(Geom2d_TrimmedCurve)::DownCast(C);
581 }
582
583 // check parameters
584 Standard_Real p1 = pp1;
585 Standard_Real p2 = pp2;
586 Standard_Real cf = C->FirstParameter();
587 Standard_Real cl = C->LastParameter();
588 Standard_Real epsilon = Precision::Confusion();
589 Standard_Boolean periodic = C->IsPeriodic();
590
591
592 TopoDS_Vertex V1,V2;
593 if (periodic) {
594 // adjust in period
595 ElCLib::AdjustPeriodic(cf,cl,epsilon,p1,p2);
596 V1 = VV1;
597 V2 = VV2;
598 }
599 else {
600 // reordonate
601 if (p1 < p2) {
602 V1 = VV1;
603 V2 = VV2;
604 }
605 else {
606 V2 = VV1;
607 V1 = VV2;
608 Standard_Real x = p1;
609 p1 = p2;
610 p2 = x;
611 }
612
613 // check range
614 if ((cf - p1 > epsilon) || (p2 - cl > epsilon)) {
615 myError = BRepLib_ParameterOutOfRange;
616 return;
617 }
618 }
619
620 // compute points on the curve
621 Standard_Boolean p1inf = Precision::IsNegativeInfinite(p1);
622 Standard_Boolean p2inf = Precision::IsPositiveInfinite(p2);
623 gp_Pnt2d P1,P2;
624 if (!p1inf) P1 = C->Value(p1);
625 if (!p2inf) P2 = C->Value(p2);
626
627 Standard_Real preci = Precision::Confusion();
628 BRep_Builder B;
629
630 // check for closed curve
631 Standard_Boolean closed = Standard_False;
632 if (!p1inf && !p2inf)
633 closed = (P1.Distance(P2) <= preci);
634
635 // check if the vertices are on the curve
636 if (closed) {
637 if (V1.IsNull() && V2.IsNull()) {
638 B.MakeVertex(V1,Point(P1),preci);
639 V2 = V1;
640 }
641 else if (V1.IsNull())
642 V1 = V2;
643 else if (V2.IsNull())
644 V2 = V1;
645 else {
646 if (!V1.IsSame(V2)) {
647 myError = BRepLib_DifferentPointsOnClosedCurve;
648 return;
649 }
650 else if (Point(P1).Distance(BRep_Tool::Pnt(V1)) > preci) {
651 myError = BRepLib_DifferentPointsOnClosedCurve;
652 return;
653 }
654 }
655 }
656
657 else { // not closed
658
659 if (p1inf) {
660 if (!V1.IsNull()) {
661 myError = BRepLib_PointWithInfiniteParameter;
662 return;
663 }
664 }
665 else {
666 gp_Pnt P = Point(P1);
667 if (V1.IsNull()) {
668 B.MakeVertex(V1,P,preci);
669 }
670#if 0
671 // desctivate control (RLE) for speed in sketcher
672 else if (P.Distance(BRep_Tool::Pnt(V1)) > preci) {
673 myError = BRepLib_DifferentsPointAndParameter;
674 return;
675 }
676#endif
677 }
678
679 if (p2inf) {
680 if (!V2.IsNull()) {
681 myError = BRepLib_PointWithInfiniteParameter;
682 return;
683 }
684 }
685 else {
686 gp_Pnt P = Point(P2);
687 if (V2.IsNull()) {
688 B.MakeVertex(V2,P,preci);
689 }
690#if 0
691 // desctivate control (RLE) for speed in sketcher
692 else if (P.Distance(BRep_Tool::Pnt(V2)) > preci){
693 myError = BRepLib_DifferentsPointAndParameter;
694 return;
695 }
696#endif
697 }
698 }
699
700 V1.Orientation(TopAbs_FORWARD);
701 V2.Orientation(TopAbs_REVERSED);
702 myVertex1 = V1;
703 myVertex2 = V2;
704
705 TopoDS_Edge& E = TopoDS::Edge(myShape);
706 B.MakeEdge(E);
707 B.UpdateEdge(E,C,BRepLib::Plane(),TopLoc_Location(),preci);
708 if (!V1.IsNull()) {
709 B.Add(E,V1);
710 }
711 if (!V2.IsNull()) {
712 B.Add(E,V2);
713 }
714 B.Range(E,p1,p2);
715 Done();
716}
717
718//=======================================================================
719//function : Error
720//purpose :
721//=======================================================================
722
723BRepLib_EdgeError BRepLib_MakeEdge2d::Error() const
724{
725 return myError;
726}
727
728//=======================================================================
729//function : Edge
730//purpose :
731//=======================================================================
732
733const TopoDS_Edge& BRepLib_MakeEdge2d::Edge()const
734{
735 return TopoDS::Edge(Shape());
736}
737
738
739//=======================================================================
740//function : Vertex1
741//purpose :
742//=======================================================================
743
744const TopoDS_Vertex& BRepLib_MakeEdge2d::Vertex1()const
745{
746 Check();
747 return myVertex1;
748}
749
750
751//=======================================================================
752//function : Vertex2
753//purpose :
754//=======================================================================
755
756const TopoDS_Vertex& BRepLib_MakeEdge2d::Vertex2()const
757{
758 Check();
759 return myVertex2;
760}
761
762
763
764//=======================================================================
765//function : operator
766//purpose :
767//=======================================================================
768
769BRepLib_MakeEdge2d::operator TopoDS_Edge() const
770{
771 return Edge();
772}