1 // File: HLRBRep_Curve.cxx
2 // Created: Fri Mar 13 11:08:32 1992
3 // Author: Christophe MARION
4 // Copyright: OPEN CASCADE 2000
6 #include <HLRBRep_Curve.ixx>
10 #include <Precision.hxx>
11 #include <ProjLib.hxx>
12 #include <TColgp_Array1OfPnt.hxx>
13 #include <HLRAlgo.hxx>
14 #include <HLRAlgo_Projector.hxx>
15 #include <HLRBRep_CLProps.hxx>
16 #include <Geom_BSplineCurve.hxx>
17 #include <Geom_BezierCurve.hxx>
18 #include <Handle_Geom_BSplineCurve.hxx>
19 #include <Handle_Geom_BezierCurve.hxx>
21 //OCC155 // jfa 05.03.2002 // bad vectors projection
23 //=======================================================================
24 //function : HLRBRep_Curve
26 //=======================================================================
28 HLRBRep_Curve::HLRBRep_Curve ()
31 //=======================================================================
34 //=======================================================================
36 void HLRBRep_Curve::Curve (const TopoDS_Edge& E)
37 { myCurve.Initialize(E); }
39 //=======================================================================
40 //function : Parameter2d
42 //=======================================================================
45 HLRBRep_Curve::Parameter2d (const Standard_Real P3d) const
47 // Mathematical formula for lines
49 // myOF P3d (myOF myVX - myOZ myVX + myOX myVZ)
50 // Res -> --------------------------------------------
51 // (-myOF + myOZ) (-myOF + myOZ + P3d myVZ)
53 if (myType == GeomAbs_Line) {
54 if (((HLRAlgo_Projector*) myProj)->Perspective()) {
55 const Standard_Real FmOZ = myOF - myOZ;
56 return myOF * P3d * (myVX * FmOZ + myOX * myVZ) / (FmOZ * (FmOZ - P3d * myVZ));
61 else if (myType == GeomAbs_Ellipse) {
68 //=======================================================================
69 //function : Parameter3d
71 //=======================================================================
74 HLRBRep_Curve::Parameter3d (const Standard_Real P2d) const
76 // Mathematical formula for lines
80 // P3d -> -----------------------------------------------------
81 // (myOF - myOZ) (myOF myVX + P2d myVZ) + myOF myOX myVZ
83 if (myType == GeomAbs_Line) {
84 if (((HLRAlgo_Projector*) myProj)->Perspective()) {
85 const Standard_Real FmOZ = myOF - myOZ;
86 return P2d * FmOZ * FmOZ / (FmOZ * (myOF * myVX + P2d * myVZ) + myOF * myOX * myVZ);
91 else if (myType == GeomAbs_Ellipse) {
98 //=======================================================================
101 //=======================================================================
103 Standard_Real HLRBRep_Curve::Update (const Standard_Address TotMin,
104 const Standard_Address TotMax)
106 GeomAbs_CurveType typ = HLRBRep_BCurveTool::GetType(myCurve);
107 myType = GeomAbs_OtherCurve;
116 if (!((HLRAlgo_Projector*) myProj)->Perspective()) {
117 gp_Dir D1 = HLRBRep_BCurveTool::Circle(myCurve).Axis().Direction();
118 D1.Transform(((HLRAlgo_Projector*) myProj)->Transformation());
119 if (D1.IsParallel(gp::DZ(),Precision::Angular()))
120 myType = GeomAbs_Circle;
121 else if (Abs(D1.Dot(gp::DZ())) < Precision::Angular()*10) //*10: The minor radius of ellipse should not be too small.
122 myType = GeomAbs_OtherCurve;
124 myType = GeomAbs_Ellipse;
125 // compute the angle offset
126 gp_Dir D3 = D1.Crossed(gp::DZ());
127 gp_Dir D2 = HLRBRep_BCurveTool::Circle(myCurve).XAxis().Direction();
128 D2.Transform(((HLRAlgo_Projector*) myProj)->Transformation());
129 myOX = D3.AngleWithRef(D2,D1);
134 case GeomAbs_Ellipse:
135 if (!((HLRAlgo_Projector*) myProj)->Perspective()) {
136 gp_Dir D1 = HLRBRep_BCurveTool::Ellipse(myCurve).Axis().Direction();
137 D1.Transform(((HLRAlgo_Projector*) myProj)->Transformation());
138 if (D1.IsParallel(gp::DZ(),Precision::Angular())) {
139 myOX = 0.; // no offset on the angle
140 myType = GeomAbs_Ellipse;
145 case GeomAbs_BezierCurve:
146 if (HLRBRep_BCurveTool::Degree(myCurve) == 1)
147 myType = GeomAbs_Line;
148 else if (!((HLRAlgo_Projector*) myProj)->Perspective())
152 case GeomAbs_BSplineCurve:
153 if (!((HLRAlgo_Projector*) myProj)->Perspective())
161 if (myType == GeomAbs_Line) {
162 // compute the values for a line
164 Standard_Real l3d = 1.; // length of the 3d bezier curve
165 if (HLRBRep_BCurveTool::GetType(myCurve) == GeomAbs_Line) {
166 L = HLRBRep_BCurveTool::Line(myCurve);
168 else { // bezier degree 1
171 HLRBRep_BCurveTool::D1(myCurve,0,PL,VL);
173 l3d = PL.Distance(HLRBRep_BCurveTool::Value(myCurve,1.));
175 gp_Pnt P = L.Location();
176 gp_Vec V = L.Direction();
177 P.Transform(((HLRAlgo_Projector*) myProj)->Transformation());
178 V.Transform(((HLRAlgo_Projector*) myProj)->Transformation());
179 if (((HLRAlgo_Projector*) myProj)->Perspective()) {
184 myVX = (VFX.X()*V.X()+VFX.Y()*V.Y()) * l3d;
185 Standard_Real l = - (VFX.X()*F.X() + VFX.Y()*F.Y());
186 F.SetCoord(F.X()+VFX.X()*l,F.Y()+VFX.Y()*l);
187 myOX = VFX.X()*(P.X()-F.X()) + VFX.Y()*(P.Y()-F.Y());
188 gp_Vec VFZ(-F.X(),-F.Y(),((HLRAlgo_Projector*) myProj)->Focus());
189 myOF = VFZ.Magnitude();
193 myOZ = VFZ * gp_Vec(P.X()-F.X(),P.Y()-F.Y(),P.Z());
195 else myVX = Sqrt(V.X() * V.X() + V.Y() * V.Y()) * l3d;
197 return(UpdateMinMax(TotMin,TotMax));
200 //=======================================================================
201 //function : UpdateMinMax
203 //=======================================================================
206 HLRBRep_Curve::UpdateMinMax (const Standard_Address TotMin,
207 const Standard_Address TotMax)
209 Standard_Real a = HLRBRep_BCurveTool::FirstParameter(myCurve);
210 Standard_Real b = HLRBRep_BCurveTool::LastParameter(myCurve);
211 Standard_Real x,y,z,tolMinMax = 0;
212 ((HLRAlgo_Projector*) myProj)->Project(Value3D(a),x,y,z);
213 HLRAlgo::UpdateMinMax(x,y,z,TotMin,TotMax);
215 if (myType != GeomAbs_Line) {
216 Standard_Integer nbPnt = 30;
218 Standard_Real step = (b-a)/(nbPnt+1);
219 Standard_Real xa,ya,za,xb =0.,yb =0.,zb =0.;
220 Standard_Real dx1,dy1,dz1,dd1;
221 Standard_Real dx2,dy2,dz2,dd2;
223 for (i = 1; i <= nbPnt; i++) {
225 xa = xb; ya = yb; za = zb;
226 xb = x ; yb = y ; zb = z ;
227 ((HLRAlgo_Projector*) myProj)->Project(Value3D(a),x,y,z);
228 HLRAlgo::UpdateMinMax(x,y,z,TotMin,TotMax);
230 dx1 = x - xa; dy1 = y - ya; dz1 = z - za;
231 dd1 = sqrt (dx1 * dx1 + dy1 * dy1 + dz1 * dz1);
233 dx2 = xb - xa; dy2 = yb - ya; dz2 = zb - za;
234 dd2 = sqrt (dx2 * dx2 + dy2 * dy2 + dz2 * dz2);
236 Standard_Real p = (dx1 * dx2 + dy1 * dy2 + dz1 * dz2) / (dd1 * dd2);
237 dx1 = xa + p * dx1 - xb;
238 dy1 = ya + p * dy1 - yb;
239 dz1 = za + p * dz1 - zb;
240 dd1 = sqrt (dx1 * dx1 + dy1 * dy1 + dz1 * dz1);
241 if (dd1 > tolMinMax) tolMinMax = dd1;
247 ((HLRAlgo_Projector*) myProj)->Project(Value3D(b),x,y,z);
248 HLRAlgo::UpdateMinMax(x,y,z,TotMin,TotMax);
252 //=======================================================================
255 //=======================================================================
257 Standard_Real HLRBRep_Curve::Z (const Standard_Real U) const
260 HLRBRep_BCurveTool::D0(myCurve,U,P3d);
261 P3d.Transform(((HLRAlgo_Projector*) myProj)->Transformation());
265 //=======================================================================
268 //=======================================================================
270 void HLRBRep_Curve::Tangent (const Standard_Boolean AtStart,
271 gp_Pnt2d& P, gp_Dir2d& D) const
273 Standard_Real U = AtStart? HLRBRep_BCurveTool::FirstParameter(myCurve) :
274 HLRBRep_BCurveTool::LastParameter (myCurve);
277 HLRBRep_CLProps CLP(2,Epsilon(1.));
278 const Standard_Address crv = (const Standard_Address)this;
281 StdFail_UndefinedDerivative_Raise_if
282 (!CLP.IsTangentDefined(), "HLRBRep_Curve::Tangent");
286 //=======================================================================
289 //=======================================================================
291 void HLRBRep_Curve::D0 (const Standard_Real U, gp_Pnt2d& P) const
294 HLRBRep_BCurveTool::D0(myCurve,U,P3d);
295 P3d.Transform(((HLRAlgo_Projector*) myProj)->Transformation());
296 if (((HLRAlgo_Projector*) myProj)->Perspective()) {
297 Standard_Real R = 1.-P3d.Z()/((HLRAlgo_Projector*) myProj)->Focus();
298 P.SetCoord(P3d.X()/R,P3d.Y()/R);
300 else P.SetCoord(P3d.X(),P3d.Y()); */
302 HLRBRep_BCurveTool::D0(myCurve,U,P3d);
303 ((HLRAlgo_Projector*) myProj)->Project(P3d,P);
306 //=======================================================================
309 //=======================================================================
311 void HLRBRep_Curve::D1 (const Standard_Real U,
312 gp_Pnt2d& P, gp_Vec2d& V) const
314 // Mathematical formula for lines
317 // D1 = -------- + -------------
319 // 1 - ---- f (1 - ----)
324 HLRBRep_BCurveTool::D1(myCurve,U,P3D,V13D);
325 P3D .Transform(((HLRAlgo_Projector*) myProj)->Transformation());
326 V13D.Transform(((HLRAlgo_Projector*) myProj)->Transformation());
327 if (((HLRAlgo_Projector*) myProj)->Perspective()) {
328 Standard_Real f = ((HLRAlgo_Projector*) myProj)->Focus();
329 Standard_Real R = 1. - P3D.Z()/f;
330 Standard_Real e = V13D.Z()/(f*R*R);
331 P.SetCoord(P3D .X()/R , P3D .Y()/R );
332 V.SetCoord(V13D.X()/R + P3D.X()*e, V13D.Y()/R + P3D.Y()*e);
335 P.SetCoord(P3D .X(),P3D .Y());
336 V.SetCoord(V13D.X(),V13D.Y());
340 HLRBRep_BCurveTool::D1(myCurve,U,P3D,V13D);
341 if (((HLRAlgo_Projector*) myProj)->Perspective()) {
342 Standard_Real f = ((HLRAlgo_Projector*) myProj)->Focus();
343 Standard_Real R = 1. - P3D.Z()/f;
344 Standard_Real e = V13D.Z()/(f*R*R);
345 P.SetCoord(P3D .X()/R , P3D .Y()/R );
346 V.SetCoord(V13D.X()/R + P3D.X()*e, V13D.Y()/R + P3D.Y()*e);
350 ((HLRAlgo_Projector*) myProj)->Project(P3D,V13D,P,V);
351 /* ((HLRAlgo_Projector*) myProj)->Project(P3D,P);
353 gp_Pnt uiui(V13D.X(),V13D.Y(),V13D.Z());
354 ((HLRAlgo_Projector*) myProj)->Project(uiui,opop);
355 V.SetCoord(opop.X(),opop.Y()); */
359 //=======================================================================
362 //=======================================================================
364 void HLRBRep_Curve::D2 (const Standard_Real U,
365 gp_Pnt2d& P, gp_Vec2d& V1, gp_Vec2d& V2) const
367 // Mathematical formula for lines
370 // 2 X'[t] Z'[t] 2 X[t] Z'[t] X''[t] X[t] Z''[t]
371 // D2 = ------------- + -------------- + -------- + -------------
372 // Z[t] 2 2 Z[t] 3 Z[t] Z[t] 2
373 // f (1 - ----) f (1 - ----) 1 - ---- f (1 - ----)
378 HLRBRep_BCurveTool::D2(myCurve,U,P3D,V13D,V23D);
379 P3D .Transform(((HLRAlgo_Projector*) myProj)->Transformation());
380 V13D.Transform(((HLRAlgo_Projector*) myProj)->Transformation());
381 V23D.Transform(((HLRAlgo_Projector*) myProj)->Transformation());
382 if (((HLRAlgo_Projector*) myProj)->Perspective()) {
383 Standard_Real f = ((HLRAlgo_Projector*) myProj)->Focus();
384 Standard_Real R = 1. - P3D.Z() / f;
385 Standard_Real q = f*R*R;
386 Standard_Real e = V13D.Z()/q;
387 Standard_Real c = e*V13D.Z()/(f*R);
388 P .SetCoord(P3D .X()/R , P3D .Y()/R );
389 V1.SetCoord(V13D.X()/R + P3D.X()*e, V13D.Y()/R + P3D.Y()*e);
390 V2.SetCoord(V23D.X()/R + 2*V13D.X()*e + P3D.X()*V23D.Z()/q + 2*P3D.X()*c,
391 V23D.Y()/R + 2*V13D.Y()*e + P3D.Y()*V23D.Z()/q + 2*P3D.Y()*c);
394 P .SetCoord(P3D .X(),P3D .Y());
395 V1.SetCoord(V13D.X(),V13D.Y());
396 V2.SetCoord(V23D.X(),V23D.Y());
400 //=======================================================================
403 //=======================================================================
405 void HLRBRep_Curve::D3 (const Standard_Real,
406 gp_Pnt2d&, gp_Vec2d&, gp_Vec2d&, gp_Vec2d&) const
410 //=======================================================================
413 //=======================================================================
415 gp_Vec2d HLRBRep_Curve::DN (const Standard_Real, const Standard_Integer) const
416 { return gp_Vec2d(); }
418 //=======================================================================
421 //=======================================================================
423 gp_Lin2d HLRBRep_Curve::Line () const
428 return gp_Lin2d(P,V);
431 //=======================================================================
434 //=======================================================================
436 gp_Circ2d HLRBRep_Curve::Circle () const
438 gp_Circ C = HLRBRep_BCurveTool::Circle(myCurve);
439 C.Transform(((HLRAlgo_Projector*) myProj)->Transformation());
440 return ProjLib::Project(gp_Pln(gp::XOY()),C);
443 //=======================================================================
446 //=======================================================================
448 gp_Elips2d HLRBRep_Curve::Ellipse () const
450 if (HLRBRep_BCurveTool::GetType(myCurve) == GeomAbs_Ellipse) {
451 gp_Elips E = HLRBRep_BCurveTool::Ellipse(myCurve);
452 E.Transform(((HLRAlgo_Projector*) myProj)->Transformation());
453 return ProjLib::Project(gp_Pln(gp::XOY()),E);
456 gp_Circ C = HLRBRep_BCurveTool::Circle(myCurve);
457 C.Transform(((HLRAlgo_Projector*) myProj)->Transformation());
458 const gp_Dir& D1 = C.Axis().Direction();
459 const gp_Dir& D3 = D1.Crossed(gp::DZ());
460 const gp_Dir& D2 = D1.Crossed(D3);
461 Standard_Real rap = sqrt( D2.X()*D2.X() + D2.Y()*D2.Y() );
462 gp_Dir2d d(D1.Y(),-D1.X());
463 gp_Pnt2d p(C.Location().X(),C.Location().Y());
464 gp_Elips2d El(gp_Ax2d(p,d),C.Radius(),C.Radius()*rap);
465 if ( D1.Z() < 0 ) El.Reverse();
469 //=======================================================================
470 //function : Hyperbola
472 //=======================================================================
474 gp_Hypr2d HLRBRep_Curve::Hyperbola () const
475 { return gp_Hypr2d(); }
477 //=======================================================================
478 //function : Parabola
480 //=======================================================================
481 gp_Parab2d HLRBRep_Curve::Parabola () const
482 { return gp_Parab2d(); }
484 //=======================================================================
487 //=======================================================================
489 void HLRBRep_Curve::Poles (TColgp_Array1OfPnt2d& TP) const
491 Standard_Integer i1 = TP.Lower();
492 Standard_Integer i2 = TP.Upper();
493 TColgp_Array1OfPnt TP3(i1,i2);
494 //-- HLRBRep_BCurveTool::Poles(myCurve,TP3);
495 if(HLRBRep_BCurveTool::GetType(myCurve) == GeomAbs_BSplineCurve) {
496 (HLRBRep_BCurveTool::BSpline(myCurve))->Poles(TP3);
499 (HLRBRep_BCurveTool::Bezier(myCurve))->Poles(TP3);
501 for (Standard_Integer i = i1; i <= i2; i++) {
502 ((HLRAlgo_Projector*) myProj)->Transform(TP3(i));
503 TP(i).SetCoord(TP3(i).X(),TP3(i).Y());
507 //=======================================================================
508 //function : PolesAndWeights
510 //=======================================================================
512 void HLRBRep_Curve::PolesAndWeights (TColgp_Array1OfPnt2d& TP,
513 TColStd_Array1OfReal& TW) const
515 Standard_Integer i1 = TP.Lower();
516 Standard_Integer i2 = TP.Upper();
517 TColgp_Array1OfPnt TP3(i1,i2);
518 //-- HLRBRep_BCurveTool::PolesAndWeights(myCurve,TP3,TW);
520 if(HLRBRep_BCurveTool::GetType(myCurve) == GeomAbs_BSplineCurve) {
521 Handle(Geom_BSplineCurve) HB = (HLRBRep_BCurveTool::BSpline(myCurve));
524 //-- (HLRBRep_BCurveTool::BSpline(myCurve))->PolesAndWeights(TP3,TW);
527 Handle(Geom_BezierCurve) HB = (HLRBRep_BCurveTool::Bezier(myCurve));
530 //-- (HLRBRep_BCurveTool::Bezier(myCurve))->PolesAndWeights(TP3,TW);
532 for (Standard_Integer i = i1; i <= i2; i++) {
533 ((HLRAlgo_Projector*) myProj)->Transform(TP3(i));
534 TP(i).SetCoord(TP3(i).X(),TP3(i).Y());
538 //=======================================================================
541 //=======================================================================
543 void HLRBRep_Curve::Knots (TColStd_Array1OfReal& kn) const
545 if(HLRBRep_BCurveTool::GetType(myCurve) == GeomAbs_BSplineCurve) {
546 Handle(Geom_BSplineCurve) HB = (HLRBRep_BCurveTool::BSpline(myCurve));
551 //=======================================================================
552 //function : Multiplicities
554 //=======================================================================
556 void HLRBRep_Curve::Multiplicities (TColStd_Array1OfInteger& mu) const
558 if(HLRBRep_BCurveTool::GetType(myCurve) == GeomAbs_BSplineCurve) {
559 Handle(Geom_BSplineCurve) HB = (HLRBRep_BCurveTool::BSpline(myCurve));
560 HB->Multiplicities(mu);