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.
17 #include <HLRBRep_Curve.ixx>
21 #include <Precision.hxx>
22 #include <ProjLib.hxx>
23 #include <TColgp_Array1OfPnt.hxx>
24 #include <HLRAlgo.hxx>
25 #include <HLRAlgo_Projector.hxx>
26 #include <HLRBRep_CLProps.hxx>
27 #include <Geom_BSplineCurve.hxx>
28 #include <Geom_BezierCurve.hxx>
30 //OCC155 // jfa 05.03.2002 // bad vectors projection
32 //=======================================================================
33 //function : HLRBRep_Curve
35 //=======================================================================
37 HLRBRep_Curve::HLRBRep_Curve ()
40 //=======================================================================
43 //=======================================================================
45 void HLRBRep_Curve::Curve (const TopoDS_Edge& E)
46 { myCurve.Initialize(E); }
48 //=======================================================================
49 //function : Parameter2d
51 //=======================================================================
54 HLRBRep_Curve::Parameter2d (const Standard_Real P3d) const
56 // Mathematical formula for lines
58 // myOF P3d (myOF myVX - myOZ myVX + myOX myVZ)
59 // Res -> --------------------------------------------
60 // (-myOF + myOZ) (-myOF + myOZ + P3d myVZ)
65 if (((HLRAlgo_Projector*) myProj)->Perspective()) {
66 const Standard_Real FmOZ = myOF - myOZ;
67 return myOF * P3d * (myVX * FmOZ + myOX * myVZ) / (FmOZ * (FmOZ - P3d * myVZ));
77 //=======================================================================
78 //function : Parameter3d
80 //=======================================================================
83 HLRBRep_Curve::Parameter3d (const Standard_Real P2d) const
85 // Mathematical formula for lines
89 // P3d -> -----------------------------------------------------
90 // (myOF - myOZ) (myOF myVX + P2d myVZ) + myOF myOX myVZ
92 if (myType == GeomAbs_Line) {
93 if (((HLRAlgo_Projector*) myProj)->Perspective()) {
94 const Standard_Real FmOZ = myOF - myOZ;
95 return P2d * FmOZ * FmOZ / (FmOZ * (myOF * myVX + P2d * myVZ) + myOF * myOX * myVZ);
97 return ((myVX <= gp::Resolution())? P2d : (P2d / myVX));
100 else if (myType == GeomAbs_Ellipse) {
107 //=======================================================================
110 //=======================================================================
112 Standard_Real HLRBRep_Curve::Update (const Standard_Address TotMin,
113 const Standard_Address TotMax)
115 GeomAbs_CurveType typ = HLRBRep_BCurveTool::GetType(myCurve);
116 myType = GeomAbs_OtherCurve;
125 if (!((HLRAlgo_Projector*) myProj)->Perspective()) {
126 gp_Dir D1 = HLRBRep_BCurveTool::Circle(myCurve).Axis().Direction();
127 D1.Transform(((HLRAlgo_Projector*) myProj)->Transformation());
128 if (D1.IsParallel(gp::DZ(),Precision::Angular()))
129 myType = GeomAbs_Circle;
130 else if (Abs(D1.Dot(gp::DZ())) < Precision::Angular()*10) //*10: The minor radius of ellipse should not be too small.
131 myType = GeomAbs_OtherCurve;
133 myType = GeomAbs_Ellipse;
134 // compute the angle offset
135 gp_Dir D3 = D1.Crossed(gp::DZ());
136 gp_Dir D2 = HLRBRep_BCurveTool::Circle(myCurve).XAxis().Direction();
137 D2.Transform(((HLRAlgo_Projector*) myProj)->Transformation());
138 myOX = D3.AngleWithRef(D2,D1);
143 case GeomAbs_Ellipse:
144 if (!((HLRAlgo_Projector*) myProj)->Perspective()) {
145 gp_Dir D1 = HLRBRep_BCurveTool::Ellipse(myCurve).Axis().Direction();
146 D1.Transform(((HLRAlgo_Projector*) myProj)->Transformation());
147 if (D1.IsParallel(gp::DZ(),Precision::Angular())) {
148 myOX = 0.; // no offset on the angle
149 myType = GeomAbs_Ellipse;
154 case GeomAbs_BezierCurve:
155 if (HLRBRep_BCurveTool::Degree(myCurve) == 1)
156 myType = GeomAbs_Line;
157 else if (!((HLRAlgo_Projector*) myProj)->Perspective())
161 case GeomAbs_BSplineCurve:
162 if (!((HLRAlgo_Projector*) myProj)->Perspective())
170 if (myType == GeomAbs_Line) {
171 // compute the values for a line
173 Standard_Real l3d = 1.; // length of the 3d bezier curve
174 if (HLRBRep_BCurveTool::GetType(myCurve) == GeomAbs_Line) {
175 L = HLRBRep_BCurveTool::Line(myCurve);
177 else { // bezier degree 1
180 HLRBRep_BCurveTool::D1(myCurve,0,PL,VL);
182 l3d = PL.Distance(HLRBRep_BCurveTool::Value(myCurve,1.));
184 gp_Pnt P = L.Location();
185 gp_Vec V = L.Direction();
186 P.Transform(((HLRAlgo_Projector*) myProj)->Transformation());
187 V.Transform(((HLRAlgo_Projector*) myProj)->Transformation());
188 if (((HLRAlgo_Projector*) myProj)->Perspective()) {
193 myVX = (VFX.X()*V.X()+VFX.Y()*V.Y()) * l3d;
194 Standard_Real l = - (VFX.X()*F.X() + VFX.Y()*F.Y());
195 F.SetCoord(F.X()+VFX.X()*l,F.Y()+VFX.Y()*l);
196 myOX = VFX.X()*(P.X()-F.X()) + VFX.Y()*(P.Y()-F.Y());
197 gp_Vec VFZ(-F.X(),-F.Y(),((HLRAlgo_Projector*) myProj)->Focus());
198 myOF = VFZ.Magnitude();
202 myOZ = VFZ * gp_Vec(P.X()-F.X(),P.Y()-F.Y(),P.Z());
204 else myVX = Sqrt(V.X() * V.X() + V.Y() * V.Y()) * l3d;
206 return(UpdateMinMax(TotMin,TotMax));
209 //=======================================================================
210 //function : UpdateMinMax
212 //=======================================================================
215 HLRBRep_Curve::UpdateMinMax (const Standard_Address TotMin,
216 const Standard_Address TotMax)
218 Standard_Real a = HLRBRep_BCurveTool::FirstParameter(myCurve);
219 Standard_Real b = HLRBRep_BCurveTool::LastParameter(myCurve);
220 Standard_Real x,y,z,tolMinMax = 0;
221 ((HLRAlgo_Projector*) myProj)->Project(Value3D(a),x,y,z);
222 HLRAlgo::UpdateMinMax(x,y,z,TotMin,TotMax);
224 if (myType != GeomAbs_Line) {
225 Standard_Integer nbPnt = 30;
227 Standard_Real step = (b-a)/(nbPnt+1);
228 Standard_Real xa,ya,za,xb =0.,yb =0.,zb =0.;
229 Standard_Real dx1,dy1,dz1,dd1;
230 Standard_Real dx2,dy2,dz2,dd2;
232 for (i = 1; i <= nbPnt; i++) {
234 xa = xb; ya = yb; za = zb;
235 xb = x ; yb = y ; zb = z ;
236 ((HLRAlgo_Projector*) myProj)->Project(Value3D(a),x,y,z);
237 HLRAlgo::UpdateMinMax(x,y,z,TotMin,TotMax);
239 dx1 = x - xa; dy1 = y - ya; dz1 = z - za;
240 dd1 = sqrt (dx1 * dx1 + dy1 * dy1 + dz1 * dz1);
242 dx2 = xb - xa; dy2 = yb - ya; dz2 = zb - za;
243 dd2 = sqrt (dx2 * dx2 + dy2 * dy2 + dz2 * dz2);
245 Standard_Real p = (dx1 * dx2 + dy1 * dy2 + dz1 * dz2) / (dd1 * dd2);
246 dx1 = xa + p * dx1 - xb;
247 dy1 = ya + p * dy1 - yb;
248 dz1 = za + p * dz1 - zb;
249 dd1 = sqrt (dx1 * dx1 + dy1 * dy1 + dz1 * dz1);
250 if (dd1 > tolMinMax) tolMinMax = dd1;
256 ((HLRAlgo_Projector*) myProj)->Project(Value3D(b),x,y,z);
257 HLRAlgo::UpdateMinMax(x,y,z,TotMin,TotMax);
261 //=======================================================================
264 //=======================================================================
266 Standard_Real HLRBRep_Curve::Z (const Standard_Real U) const
269 HLRBRep_BCurveTool::D0(myCurve,U,P3d);
270 P3d.Transform(((HLRAlgo_Projector*) myProj)->Transformation());
274 //=======================================================================
277 //=======================================================================
279 void HLRBRep_Curve::Tangent (const Standard_Boolean AtStart,
280 gp_Pnt2d& P, gp_Dir2d& D) const
282 Standard_Real U = AtStart? HLRBRep_BCurveTool::FirstParameter(myCurve) :
283 HLRBRep_BCurveTool::LastParameter (myCurve);
286 HLRBRep_CLProps CLP(2,Epsilon(1.));
287 const Standard_Address crv = (const Standard_Address)this;
290 StdFail_UndefinedDerivative_Raise_if
291 (!CLP.IsTangentDefined(), "HLRBRep_Curve::Tangent");
295 //=======================================================================
298 //=======================================================================
300 void HLRBRep_Curve::D0 (const Standard_Real U, gp_Pnt2d& P) const
303 HLRBRep_BCurveTool::D0(myCurve,U,P3d);
304 P3d.Transform(((HLRAlgo_Projector*) myProj)->Transformation());
305 if (((HLRAlgo_Projector*) myProj)->Perspective()) {
306 Standard_Real R = 1.-P3d.Z()/((HLRAlgo_Projector*) myProj)->Focus();
307 P.SetCoord(P3d.X()/R,P3d.Y()/R);
309 else P.SetCoord(P3d.X(),P3d.Y()); */
311 HLRBRep_BCurveTool::D0(myCurve,U,P3d);
312 ((HLRAlgo_Projector*) myProj)->Project(P3d,P);
315 //=======================================================================
318 //=======================================================================
320 void HLRBRep_Curve::D1 (const Standard_Real U,
321 gp_Pnt2d& P, gp_Vec2d& V) const
323 // Mathematical formula for lines
326 // D1 = -------- + -------------
328 // 1 - ---- f (1 - ----)
333 HLRBRep_BCurveTool::D1(myCurve,U,P3D,V13D);
334 P3D .Transform(((HLRAlgo_Projector*) myProj)->Transformation());
335 V13D.Transform(((HLRAlgo_Projector*) myProj)->Transformation());
336 if (((HLRAlgo_Projector*) myProj)->Perspective()) {
337 Standard_Real f = ((HLRAlgo_Projector*) myProj)->Focus();
338 Standard_Real R = 1. - P3D.Z()/f;
339 Standard_Real e = V13D.Z()/(f*R*R);
340 P.SetCoord(P3D .X()/R , P3D .Y()/R );
341 V.SetCoord(V13D.X()/R + P3D.X()*e, V13D.Y()/R + P3D.Y()*e);
344 P.SetCoord(P3D .X(),P3D .Y());
345 V.SetCoord(V13D.X(),V13D.Y());
349 HLRBRep_BCurveTool::D1(myCurve,U,P3D,V13D);
350 if (((HLRAlgo_Projector*) myProj)->Perspective()) {
351 Standard_Real f = ((HLRAlgo_Projector*) myProj)->Focus();
352 Standard_Real R = 1. - P3D.Z()/f;
353 Standard_Real e = V13D.Z()/(f*R*R);
354 P.SetCoord(P3D .X()/R , P3D .Y()/R );
355 V.SetCoord(V13D.X()/R + P3D.X()*e, V13D.Y()/R + P3D.Y()*e);
359 ((HLRAlgo_Projector*) myProj)->Project(P3D,V13D,P,V);
360 /* ((HLRAlgo_Projector*) myProj)->Project(P3D,P);
362 gp_Pnt uiui(V13D.X(),V13D.Y(),V13D.Z());
363 ((HLRAlgo_Projector*) myProj)->Project(uiui,opop);
364 V.SetCoord(opop.X(),opop.Y()); */
368 //=======================================================================
371 //=======================================================================
373 void HLRBRep_Curve::D2 (const Standard_Real U,
374 gp_Pnt2d& P, gp_Vec2d& V1, gp_Vec2d& V2) const
376 // Mathematical formula for lines
379 // 2 X'[t] Z'[t] 2 X[t] Z'[t] X''[t] X[t] Z''[t]
380 // D2 = ------------- + -------------- + -------- + -------------
381 // Z[t] 2 2 Z[t] 3 Z[t] Z[t] 2
382 // f (1 - ----) f (1 - ----) 1 - ---- f (1 - ----)
387 HLRBRep_BCurveTool::D2(myCurve,U,P3D,V13D,V23D);
388 P3D .Transform(((HLRAlgo_Projector*) myProj)->Transformation());
389 V13D.Transform(((HLRAlgo_Projector*) myProj)->Transformation());
390 V23D.Transform(((HLRAlgo_Projector*) myProj)->Transformation());
391 if (((HLRAlgo_Projector*) myProj)->Perspective()) {
392 Standard_Real f = ((HLRAlgo_Projector*) myProj)->Focus();
393 Standard_Real R = 1. - P3D.Z() / f;
394 Standard_Real q = f*R*R;
395 Standard_Real e = V13D.Z()/q;
396 Standard_Real c = e*V13D.Z()/(f*R);
397 P .SetCoord(P3D .X()/R , P3D .Y()/R );
398 V1.SetCoord(V13D.X()/R + P3D.X()*e, V13D.Y()/R + P3D.Y()*e);
399 V2.SetCoord(V23D.X()/R + 2*V13D.X()*e + P3D.X()*V23D.Z()/q + 2*P3D.X()*c,
400 V23D.Y()/R + 2*V13D.Y()*e + P3D.Y()*V23D.Z()/q + 2*P3D.Y()*c);
403 P .SetCoord(P3D .X(),P3D .Y());
404 V1.SetCoord(V13D.X(),V13D.Y());
405 V2.SetCoord(V23D.X(),V23D.Y());
409 //=======================================================================
412 //=======================================================================
414 void HLRBRep_Curve::D3 (const Standard_Real,
415 gp_Pnt2d&, gp_Vec2d&, gp_Vec2d&, gp_Vec2d&) const
419 //=======================================================================
422 //=======================================================================
424 gp_Vec2d HLRBRep_Curve::DN (const Standard_Real, const Standard_Integer) const
425 { return gp_Vec2d(); }
427 //=======================================================================
430 //=======================================================================
432 gp_Lin2d HLRBRep_Curve::Line () const
437 return gp_Lin2d(P,V);
440 //=======================================================================
443 //=======================================================================
445 gp_Circ2d HLRBRep_Curve::Circle () const
447 gp_Circ C = HLRBRep_BCurveTool::Circle(myCurve);
448 C.Transform(((HLRAlgo_Projector*) myProj)->Transformation());
449 return ProjLib::Project(gp_Pln(gp::XOY()),C);
452 //=======================================================================
455 //=======================================================================
457 gp_Elips2d HLRBRep_Curve::Ellipse () const
459 if (HLRBRep_BCurveTool::GetType(myCurve) == GeomAbs_Ellipse) {
460 gp_Elips E = HLRBRep_BCurveTool::Ellipse(myCurve);
461 E.Transform(((HLRAlgo_Projector*) myProj)->Transformation());
462 return ProjLib::Project(gp_Pln(gp::XOY()),E);
465 gp_Circ C = HLRBRep_BCurveTool::Circle(myCurve);
466 C.Transform(((HLRAlgo_Projector*) myProj)->Transformation());
467 const gp_Dir& D1 = C.Axis().Direction();
468 const gp_Dir& D3 = D1.Crossed(gp::DZ());
469 const gp_Dir& D2 = D1.Crossed(D3);
470 Standard_Real rap = sqrt( D2.X()*D2.X() + D2.Y()*D2.Y() );
471 gp_Dir2d d(D1.Y(),-D1.X());
472 gp_Pnt2d p(C.Location().X(),C.Location().Y());
473 gp_Elips2d El(gp_Ax2d(p,d),C.Radius(),C.Radius()*rap);
474 if ( D1.Z() < 0 ) El.Reverse();
478 //=======================================================================
479 //function : Hyperbola
481 //=======================================================================
483 gp_Hypr2d HLRBRep_Curve::Hyperbola () const
484 { return gp_Hypr2d(); }
486 //=======================================================================
487 //function : Parabola
489 //=======================================================================
490 gp_Parab2d HLRBRep_Curve::Parabola () const
491 { return gp_Parab2d(); }
493 //=======================================================================
496 //=======================================================================
498 void HLRBRep_Curve::Poles (TColgp_Array1OfPnt2d& TP) const
500 Standard_Integer i1 = TP.Lower();
501 Standard_Integer i2 = TP.Upper();
502 TColgp_Array1OfPnt TP3(i1,i2);
503 //-- HLRBRep_BCurveTool::Poles(myCurve,TP3);
504 if(HLRBRep_BCurveTool::GetType(myCurve) == GeomAbs_BSplineCurve) {
505 (HLRBRep_BCurveTool::BSpline(myCurve))->Poles(TP3);
508 (HLRBRep_BCurveTool::Bezier(myCurve))->Poles(TP3);
510 for (Standard_Integer i = i1; i <= i2; i++) {
511 ((HLRAlgo_Projector*) myProj)->Transform(TP3(i));
512 TP(i).SetCoord(TP3(i).X(),TP3(i).Y());
516 //=======================================================================
519 //=======================================================================
521 void HLRBRep_Curve::Poles (const Handle(Geom_BSplineCurve)& aCurve,
522 TColgp_Array1OfPnt2d& TP) const
524 Standard_Integer i1 = TP.Lower();
525 Standard_Integer i2 = TP.Upper();
526 TColgp_Array1OfPnt TP3(i1,i2);
527 //-- HLRBRep_BCurveTool::Poles(myCurve,TP3);
530 for (Standard_Integer i = i1; i <= i2; i++) {
531 ((HLRAlgo_Projector*) myProj)->Transform(TP3(i));
532 TP(i).SetCoord(TP3(i).X(),TP3(i).Y());
536 //=======================================================================
537 //function : PolesAndWeights
539 //=======================================================================
541 void HLRBRep_Curve::PolesAndWeights (TColgp_Array1OfPnt2d& TP,
542 TColStd_Array1OfReal& TW) const
544 Standard_Integer i1 = TP.Lower();
545 Standard_Integer i2 = TP.Upper();
546 TColgp_Array1OfPnt TP3(i1,i2);
547 //-- HLRBRep_BCurveTool::PolesAndWeights(myCurve,TP3,TW);
549 if(HLRBRep_BCurveTool::GetType(myCurve) == GeomAbs_BSplineCurve) {
550 Handle(Geom_BSplineCurve) HB = (HLRBRep_BCurveTool::BSpline(myCurve));
553 //-- (HLRBRep_BCurveTool::BSpline(myCurve))->PolesAndWeights(TP3,TW);
556 Handle(Geom_BezierCurve) HB = (HLRBRep_BCurveTool::Bezier(myCurve));
559 //-- (HLRBRep_BCurveTool::Bezier(myCurve))->PolesAndWeights(TP3,TW);
561 for (Standard_Integer i = i1; i <= i2; i++) {
562 ((HLRAlgo_Projector*) myProj)->Transform(TP3(i));
563 TP(i).SetCoord(TP3(i).X(),TP3(i).Y());
567 //=======================================================================
568 //function : PolesAndWeights
570 //=======================================================================
572 void HLRBRep_Curve::PolesAndWeights (const Handle(Geom_BSplineCurve)& aCurve,
573 TColgp_Array1OfPnt2d& TP,
574 TColStd_Array1OfReal& TW) const
576 Standard_Integer i1 = TP.Lower();
577 Standard_Integer i2 = TP.Upper();
578 TColgp_Array1OfPnt TP3(i1,i2);
579 //-- HLRBRep_BCurveTool::PolesAndWeights(myCurve,TP3,TW);
583 //-- (HLRBRep_BCurveTool::BSpline(myCurve))->PolesAndWeights(TP3,TW);
585 for (Standard_Integer i = i1; i <= i2; i++) {
586 ((HLRAlgo_Projector*) myProj)->Transform(TP3(i));
587 TP(i).SetCoord(TP3(i).X(),TP3(i).Y());
591 //=======================================================================
594 //=======================================================================
596 void HLRBRep_Curve::Knots (TColStd_Array1OfReal& kn) const
598 if(HLRBRep_BCurveTool::GetType(myCurve) == GeomAbs_BSplineCurve) {
599 Handle(Geom_BSplineCurve) HB = (HLRBRep_BCurveTool::BSpline(myCurve));
604 //=======================================================================
605 //function : Multiplicities
607 //=======================================================================
609 void HLRBRep_Curve::Multiplicities (TColStd_Array1OfInteger& mu) const
611 if(HLRBRep_BCurveTool::GetType(myCurve) == GeomAbs_BSplineCurve) {
612 Handle(Geom_BSplineCurve) HB = (HLRBRep_BCurveTool::BSpline(myCurve));
613 HB->Multiplicities(mu);