1 // Created on: 1992-03-13
2 // Created by: Christophe MARION
3 // Copyright (c) 1992-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
18 #include <BRepAdaptor_Curve.hxx>
19 #include <Geom_BezierCurve.hxx>
20 #include <Geom_BSplineCurve.hxx>
23 #include <gp_Circ2d.hxx>
24 #include <gp_Dir2d.hxx>
25 #include <gp_Elips2d.hxx>
26 #include <gp_Hypr2d.hxx>
27 #include <gp_Lin2d.hxx>
28 #include <gp_Parab2d.hxx>
31 #include <gp_Pnt2d.hxx>
33 #include <gp_Vec2d.hxx>
34 #include <HLRAlgo.hxx>
35 #include <HLRAlgo_Projector.hxx>
36 #include <HLRBRep_CLProps.hxx>
37 #include <HLRBRep_Curve.hxx>
38 #include <Precision.hxx>
39 #include <ProjLib.hxx>
40 #include <Standard_DomainError.hxx>
41 #include <Standard_NoSuchObject.hxx>
42 #include <Standard_OutOfRange.hxx>
43 #include <StdFail_UndefinedDerivative.hxx>
44 #include <TColgp_Array1OfPnt.hxx>
45 #include <TopoDS_Edge.hxx>
47 //OCC155 // jfa 05.03.2002 // bad vectors projection
48 //=======================================================================
49 //function : HLRBRep_Curve
51 //=======================================================================
52 HLRBRep_Curve::HLRBRep_Curve ()
55 //=======================================================================
58 //=======================================================================
60 void HLRBRep_Curve::Curve (const TopoDS_Edge& E)
61 { myCurve.Initialize(E); }
63 //=======================================================================
64 //function : Parameter2d
66 //=======================================================================
69 HLRBRep_Curve::Parameter2d (const Standard_Real P3d) const
71 // Mathematical formula for lines
73 // myOF P3d (myOF myVX - myOZ myVX + myOX myVZ)
74 // Res -> --------------------------------------------
75 // (-myOF + myOZ) (-myOF + myOZ + P3d myVZ)
80 if (((HLRAlgo_Projector*) myProj)->Perspective()) {
81 const Standard_Real FmOZ = myOF - myOZ;
82 return myOF * P3d * (myVX * FmOZ + myOX * myVZ) / (FmOZ * (FmOZ - P3d * myVZ));
89 default: // implemented to avoid gcc compiler warnings
95 //=======================================================================
96 //function : Parameter3d
98 //=======================================================================
101 HLRBRep_Curve::Parameter3d (const Standard_Real P2d) const
103 // Mathematical formula for lines
106 // (-myOF + myOZ) P2d
107 // P3d -> -----------------------------------------------------
108 // (myOF - myOZ) (myOF myVX + P2d myVZ) + myOF myOX myVZ
110 if (myType == GeomAbs_Line) {
111 if (((HLRAlgo_Projector*) myProj)->Perspective()) {
112 const Standard_Real FmOZ = myOF - myOZ;
113 return P2d * FmOZ * FmOZ / (FmOZ * (myOF * myVX + P2d * myVZ) + myOF * myOX * myVZ);
115 return ((myVX <= gp::Resolution())? P2d : (P2d / myVX));
118 else if (myType == GeomAbs_Ellipse) {
125 //=======================================================================
128 //=======================================================================
130 Standard_Real HLRBRep_Curve::Update (const Standard_Address TotMin,
131 const Standard_Address TotMax)
133 GeomAbs_CurveType typ = HLRBRep_BCurveTool::GetType(myCurve);
134 myType = GeomAbs_OtherCurve;
143 if (!((HLRAlgo_Projector*) myProj)->Perspective()) {
144 gp_Dir D1 = HLRBRep_BCurveTool::Circle(myCurve).Axis().Direction();
145 D1.Transform(((HLRAlgo_Projector*) myProj)->Transformation());
146 if (D1.IsParallel(gp::DZ(),Precision::Angular()))
147 myType = GeomAbs_Circle;
148 else if (Abs(D1.Dot(gp::DZ())) < Precision::Angular()*10) //*10: The minor radius of ellipse should not be too small.
149 myType = GeomAbs_OtherCurve;
151 myType = GeomAbs_Ellipse;
152 // compute the angle offset
153 gp_Dir D3 = D1.Crossed(gp::DZ());
154 gp_Dir D2 = HLRBRep_BCurveTool::Circle(myCurve).XAxis().Direction();
155 D2.Transform(((HLRAlgo_Projector*) myProj)->Transformation());
156 myOX = D3.AngleWithRef(D2,D1);
161 case GeomAbs_Ellipse:
162 if (!((HLRAlgo_Projector*) myProj)->Perspective()) {
163 gp_Dir D1 = HLRBRep_BCurveTool::Ellipse(myCurve).Axis().Direction();
164 D1.Transform(((HLRAlgo_Projector*) myProj)->Transformation());
165 if (D1.IsParallel(gp::DZ(),Precision::Angular())) {
166 myOX = 0.; // no offset on the angle
167 myType = GeomAbs_Ellipse;
172 case GeomAbs_BezierCurve:
173 if (HLRBRep_BCurveTool::Degree(myCurve) == 1)
174 myType = GeomAbs_Line;
175 else if (!((HLRAlgo_Projector*) myProj)->Perspective())
179 case GeomAbs_BSplineCurve:
180 if (!((HLRAlgo_Projector*) myProj)->Perspective())
188 if (myType == GeomAbs_Line) {
189 // compute the values for a line
191 Standard_Real l3d = 1.; // length of the 3d bezier curve
192 if (HLRBRep_BCurveTool::GetType(myCurve) == GeomAbs_Line) {
193 L = HLRBRep_BCurveTool::Line(myCurve);
195 else { // bezier degree 1
198 HLRBRep_BCurveTool::D1(myCurve,0,PL,VL);
200 l3d = PL.Distance(HLRBRep_BCurveTool::Value(myCurve,1.));
202 gp_Pnt P = L.Location();
203 gp_Vec V = L.Direction();
204 P.Transform(((HLRAlgo_Projector*) myProj)->Transformation());
205 V.Transform(((HLRAlgo_Projector*) myProj)->Transformation());
206 if (((HLRAlgo_Projector*) myProj)->Perspective()) {
211 myVX = (VFX.X()*V.X()+VFX.Y()*V.Y()) * l3d;
212 Standard_Real l = - (VFX.X()*F.X() + VFX.Y()*F.Y());
213 F.SetCoord(F.X()+VFX.X()*l,F.Y()+VFX.Y()*l);
214 myOX = VFX.X()*(P.X()-F.X()) + VFX.Y()*(P.Y()-F.Y());
215 gp_Vec VFZ(-F.X(),-F.Y(),((HLRAlgo_Projector*) myProj)->Focus());
216 myOF = VFZ.Magnitude();
220 myOZ = VFZ * gp_Vec(P.X()-F.X(),P.Y()-F.Y(),P.Z());
222 else myVX = Sqrt(V.X() * V.X() + V.Y() * V.Y()) * l3d;
224 return(UpdateMinMax(TotMin,TotMax));
227 //=======================================================================
228 //function : UpdateMinMax
230 //=======================================================================
233 HLRBRep_Curve::UpdateMinMax (const Standard_Address TotMin,
234 const Standard_Address TotMax)
236 Standard_Real a = HLRBRep_BCurveTool::FirstParameter(myCurve);
237 Standard_Real b = HLRBRep_BCurveTool::LastParameter(myCurve);
238 Standard_Real x,y,z,tolMinMax = 0;
239 ((HLRAlgo_Projector*) myProj)->Project(Value3D(a),x,y,z);
240 HLRAlgo::UpdateMinMax(x,y,z,TotMin,TotMax);
242 if (myType != GeomAbs_Line) {
243 Standard_Integer nbPnt = 30;
245 Standard_Real step = (b-a)/(nbPnt+1);
246 Standard_Real xa,ya,za,xb =0.,yb =0.,zb =0.;
247 Standard_Real dx1,dy1,dz1,dd1;
248 Standard_Real dx2,dy2,dz2,dd2;
250 for (i = 1; i <= nbPnt; i++) {
252 xa = xb; ya = yb; za = zb;
253 xb = x ; yb = y ; zb = z ;
254 ((HLRAlgo_Projector*) myProj)->Project(Value3D(a),x,y,z);
255 HLRAlgo::UpdateMinMax(x,y,z,TotMin,TotMax);
257 dx1 = x - xa; dy1 = y - ya; dz1 = z - za;
258 dd1 = sqrt (dx1 * dx1 + dy1 * dy1 + dz1 * dz1);
260 dx2 = xb - xa; dy2 = yb - ya; dz2 = zb - za;
261 dd2 = sqrt (dx2 * dx2 + dy2 * dy2 + dz2 * dz2);
263 Standard_Real p = (dx1 * dx2 + dy1 * dy2 + dz1 * dz2) / (dd1 * dd2);
264 dx1 = xa + p * dx1 - xb;
265 dy1 = ya + p * dy1 - yb;
266 dz1 = za + p * dz1 - zb;
267 dd1 = sqrt (dx1 * dx1 + dy1 * dy1 + dz1 * dz1);
268 if (dd1 > tolMinMax) tolMinMax = dd1;
274 ((HLRAlgo_Projector*) myProj)->Project(Value3D(b),x,y,z);
275 HLRAlgo::UpdateMinMax(x,y,z,TotMin,TotMax);
279 //=======================================================================
282 //=======================================================================
284 Standard_Real HLRBRep_Curve::Z (const Standard_Real U) const
287 HLRBRep_BCurveTool::D0(myCurve,U,P3d);
288 P3d.Transform(((HLRAlgo_Projector*) myProj)->Transformation());
292 //=======================================================================
295 //=======================================================================
297 void HLRBRep_Curve::Tangent (const Standard_Boolean AtStart,
298 gp_Pnt2d& P, gp_Dir2d& D) const
300 Standard_Real U = AtStart? HLRBRep_BCurveTool::FirstParameter(myCurve) :
301 HLRBRep_BCurveTool::LastParameter (myCurve);
304 HLRBRep_CLProps CLP(2,Epsilon(1.));
305 const Standard_Address crv = (const Standard_Address)this;
308 StdFail_UndefinedDerivative_Raise_if
309 (!CLP.IsTangentDefined(), "HLRBRep_Curve::Tangent");
313 //=======================================================================
316 //=======================================================================
318 void HLRBRep_Curve::D0 (const Standard_Real U, gp_Pnt2d& P) const
321 HLRBRep_BCurveTool::D0(myCurve,U,P3d);
322 P3d.Transform(((HLRAlgo_Projector*) myProj)->Transformation());
323 if (((HLRAlgo_Projector*) myProj)->Perspective()) {
324 Standard_Real R = 1.-P3d.Z()/((HLRAlgo_Projector*) myProj)->Focus();
325 P.SetCoord(P3d.X()/R,P3d.Y()/R);
327 else P.SetCoord(P3d.X(),P3d.Y()); */
329 HLRBRep_BCurveTool::D0(myCurve,U,P3d);
330 ((HLRAlgo_Projector*) myProj)->Project(P3d,P);
333 //=======================================================================
336 //=======================================================================
338 void HLRBRep_Curve::D1 (const Standard_Real U,
339 gp_Pnt2d& P, gp_Vec2d& V) const
341 // Mathematical formula for lines
344 // D1 = -------- + -------------
346 // 1 - ---- f (1 - ----)
351 HLRBRep_BCurveTool::D1(myCurve,U,P3D,V13D);
352 P3D .Transform(((HLRAlgo_Projector*) myProj)->Transformation());
353 V13D.Transform(((HLRAlgo_Projector*) myProj)->Transformation());
354 if (((HLRAlgo_Projector*) myProj)->Perspective()) {
355 Standard_Real f = ((HLRAlgo_Projector*) myProj)->Focus();
356 Standard_Real R = 1. - P3D.Z()/f;
357 Standard_Real e = V13D.Z()/(f*R*R);
358 P.SetCoord(P3D .X()/R , P3D .Y()/R );
359 V.SetCoord(V13D.X()/R + P3D.X()*e, V13D.Y()/R + P3D.Y()*e);
362 P.SetCoord(P3D .X(),P3D .Y());
363 V.SetCoord(V13D.X(),V13D.Y());
367 HLRBRep_BCurveTool::D1(myCurve,U,P3D,V13D);
368 if (((HLRAlgo_Projector*) myProj)->Perspective()) {
369 Standard_Real f = ((HLRAlgo_Projector*) myProj)->Focus();
370 Standard_Real R = 1. - P3D.Z()/f;
371 Standard_Real e = V13D.Z()/(f*R*R);
372 P.SetCoord(P3D .X()/R , P3D .Y()/R );
373 V.SetCoord(V13D.X()/R + P3D.X()*e, V13D.Y()/R + P3D.Y()*e);
377 ((HLRAlgo_Projector*) myProj)->Project(P3D,V13D,P,V);
378 /* ((HLRAlgo_Projector*) myProj)->Project(P3D,P);
380 gp_Pnt uiui(V13D.X(),V13D.Y(),V13D.Z());
381 ((HLRAlgo_Projector*) myProj)->Project(uiui,opop);
382 V.SetCoord(opop.X(),opop.Y()); */
386 //=======================================================================
389 //=======================================================================
391 void HLRBRep_Curve::D2 (const Standard_Real U,
392 gp_Pnt2d& P, gp_Vec2d& V1, gp_Vec2d& V2) const
394 // Mathematical formula for lines
397 // 2 X'[t] Z'[t] 2 X[t] Z'[t] X''[t] X[t] Z''[t]
398 // D2 = ------------- + -------------- + -------- + -------------
399 // Z[t] 2 2 Z[t] 3 Z[t] Z[t] 2
400 // f (1 - ----) f (1 - ----) 1 - ---- f (1 - ----)
405 HLRBRep_BCurveTool::D2(myCurve,U,P3D,V13D,V23D);
406 P3D .Transform(((HLRAlgo_Projector*) myProj)->Transformation());
407 V13D.Transform(((HLRAlgo_Projector*) myProj)->Transformation());
408 V23D.Transform(((HLRAlgo_Projector*) myProj)->Transformation());
409 if (((HLRAlgo_Projector*) myProj)->Perspective()) {
410 Standard_Real f = ((HLRAlgo_Projector*) myProj)->Focus();
411 Standard_Real R = 1. - P3D.Z() / f;
412 Standard_Real q = f*R*R;
413 Standard_Real e = V13D.Z()/q;
414 Standard_Real c = e*V13D.Z()/(f*R);
415 P .SetCoord(P3D .X()/R , P3D .Y()/R );
416 V1.SetCoord(V13D.X()/R + P3D.X()*e, V13D.Y()/R + P3D.Y()*e);
417 V2.SetCoord(V23D.X()/R + 2*V13D.X()*e + P3D.X()*V23D.Z()/q + 2*P3D.X()*c,
418 V23D.Y()/R + 2*V13D.Y()*e + P3D.Y()*V23D.Z()/q + 2*P3D.Y()*c);
421 P .SetCoord(P3D .X(),P3D .Y());
422 V1.SetCoord(V13D.X(),V13D.Y());
423 V2.SetCoord(V23D.X(),V23D.Y());
427 //=======================================================================
430 //=======================================================================
432 void HLRBRep_Curve::D3 (const Standard_Real,
433 gp_Pnt2d&, gp_Vec2d&, gp_Vec2d&, gp_Vec2d&) const
437 //=======================================================================
440 //=======================================================================
442 gp_Vec2d HLRBRep_Curve::DN (const Standard_Real, const Standard_Integer) const
443 { return gp_Vec2d(); }
445 //=======================================================================
448 //=======================================================================
450 gp_Lin2d HLRBRep_Curve::Line () const
455 return gp_Lin2d(P,V);
458 //=======================================================================
461 //=======================================================================
463 gp_Circ2d HLRBRep_Curve::Circle () const
465 gp_Circ C = HLRBRep_BCurveTool::Circle(myCurve);
466 C.Transform(((HLRAlgo_Projector*) myProj)->Transformation());
467 return ProjLib::Project(gp_Pln(gp::XOY()),C);
470 //=======================================================================
473 //=======================================================================
475 gp_Elips2d HLRBRep_Curve::Ellipse () const
477 if (HLRBRep_BCurveTool::GetType(myCurve) == GeomAbs_Ellipse) {
478 gp_Elips E = HLRBRep_BCurveTool::Ellipse(myCurve);
479 E.Transform(((HLRAlgo_Projector*) myProj)->Transformation());
480 return ProjLib::Project(gp_Pln(gp::XOY()),E);
483 gp_Circ C = HLRBRep_BCurveTool::Circle(myCurve);
484 C.Transform(((HLRAlgo_Projector*) myProj)->Transformation());
485 const gp_Dir& D1 = C.Axis().Direction();
486 const gp_Dir& D3 = D1.Crossed(gp::DZ());
487 const gp_Dir& D2 = D1.Crossed(D3);
488 Standard_Real rap = sqrt( D2.X()*D2.X() + D2.Y()*D2.Y() );
489 gp_Dir2d d(D1.Y(),-D1.X());
490 gp_Pnt2d p(C.Location().X(),C.Location().Y());
491 gp_Elips2d El(gp_Ax2d(p,d),C.Radius(),C.Radius()*rap);
492 if ( D1.Z() < 0 ) El.Reverse();
496 //=======================================================================
497 //function : Hyperbola
499 //=======================================================================
501 gp_Hypr2d HLRBRep_Curve::Hyperbola () const
502 { return gp_Hypr2d(); }
504 //=======================================================================
505 //function : Parabola
507 //=======================================================================
508 gp_Parab2d HLRBRep_Curve::Parabola () const
509 { return gp_Parab2d(); }
511 //=======================================================================
514 //=======================================================================
516 void HLRBRep_Curve::Poles (TColgp_Array1OfPnt2d& TP) const
518 Standard_Integer i1 = TP.Lower();
519 Standard_Integer i2 = TP.Upper();
520 TColgp_Array1OfPnt TP3(i1,i2);
521 //-- HLRBRep_BCurveTool::Poles(myCurve,TP3);
522 if(HLRBRep_BCurveTool::GetType(myCurve) == GeomAbs_BSplineCurve) {
523 (HLRBRep_BCurveTool::BSpline(myCurve))->Poles(TP3);
526 (HLRBRep_BCurveTool::Bezier(myCurve))->Poles(TP3);
528 for (Standard_Integer i = i1; i <= i2; i++) {
529 ((HLRAlgo_Projector*) myProj)->Transform(TP3(i));
530 TP(i).SetCoord(TP3(i).X(),TP3(i).Y());
534 //=======================================================================
537 //=======================================================================
539 void HLRBRep_Curve::Poles (const Handle(Geom_BSplineCurve)& aCurve,
540 TColgp_Array1OfPnt2d& TP) const
542 Standard_Integer i1 = TP.Lower();
543 Standard_Integer i2 = TP.Upper();
544 TColgp_Array1OfPnt TP3(i1,i2);
545 //-- HLRBRep_BCurveTool::Poles(myCurve,TP3);
548 for (Standard_Integer i = i1; i <= i2; i++) {
549 ((HLRAlgo_Projector*) myProj)->Transform(TP3(i));
550 TP(i).SetCoord(TP3(i).X(),TP3(i).Y());
554 //=======================================================================
555 //function : PolesAndWeights
557 //=======================================================================
559 void HLRBRep_Curve::PolesAndWeights (TColgp_Array1OfPnt2d& TP,
560 TColStd_Array1OfReal& TW) const
562 Standard_Integer i1 = TP.Lower();
563 Standard_Integer i2 = TP.Upper();
564 TColgp_Array1OfPnt TP3(i1,i2);
565 //-- HLRBRep_BCurveTool::PolesAndWeights(myCurve,TP3,TW);
567 if(HLRBRep_BCurveTool::GetType(myCurve) == GeomAbs_BSplineCurve) {
568 Handle(Geom_BSplineCurve) HB = (HLRBRep_BCurveTool::BSpline(myCurve));
571 //-- (HLRBRep_BCurveTool::BSpline(myCurve))->PolesAndWeights(TP3,TW);
574 Handle(Geom_BezierCurve) HB = (HLRBRep_BCurveTool::Bezier(myCurve));
577 //-- (HLRBRep_BCurveTool::Bezier(myCurve))->PolesAndWeights(TP3,TW);
579 for (Standard_Integer i = i1; i <= i2; i++) {
580 ((HLRAlgo_Projector*) myProj)->Transform(TP3(i));
581 TP(i).SetCoord(TP3(i).X(),TP3(i).Y());
585 //=======================================================================
586 //function : PolesAndWeights
588 //=======================================================================
590 void HLRBRep_Curve::PolesAndWeights (const Handle(Geom_BSplineCurve)& aCurve,
591 TColgp_Array1OfPnt2d& TP,
592 TColStd_Array1OfReal& TW) const
594 Standard_Integer i1 = TP.Lower();
595 Standard_Integer i2 = TP.Upper();
596 TColgp_Array1OfPnt TP3(i1,i2);
597 //-- HLRBRep_BCurveTool::PolesAndWeights(myCurve,TP3,TW);
601 //-- (HLRBRep_BCurveTool::BSpline(myCurve))->PolesAndWeights(TP3,TW);
603 for (Standard_Integer i = i1; i <= i2; i++) {
604 ((HLRAlgo_Projector*) myProj)->Transform(TP3(i));
605 TP(i).SetCoord(TP3(i).X(),TP3(i).Y());
609 //=======================================================================
612 //=======================================================================
614 void HLRBRep_Curve::Knots (TColStd_Array1OfReal& kn) const
616 if(HLRBRep_BCurveTool::GetType(myCurve) == GeomAbs_BSplineCurve) {
617 Handle(Geom_BSplineCurve) HB = (HLRBRep_BCurveTool::BSpline(myCurve));
622 //=======================================================================
623 //function : Multiplicities
625 //=======================================================================
627 void HLRBRep_Curve::Multiplicities (TColStd_Array1OfInteger& mu) const
629 if(HLRBRep_BCurveTool::GetType(myCurve) == GeomAbs_BSplineCurve) {
630 Handle(Geom_BSplineCurve) HB = (HLRBRep_BCurveTool::BSpline(myCurve));
631 HB->Multiplicities(mu);