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(
131 Standard_Real TotMin[16], Standard_Real TotMax[16])
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 //=======================================================================
232 Standard_Real HLRBRep_Curve::UpdateMinMax(
233 Standard_Real TotMin[16], Standard_Real TotMax[16])
235 Standard_Real a = HLRBRep_BCurveTool::FirstParameter(myCurve);
236 Standard_Real b = HLRBRep_BCurveTool::LastParameter(myCurve);
237 Standard_Real x,y,z,tolMinMax = 0;
238 ((HLRAlgo_Projector*) myProj)->Project(Value3D(a),x,y,z);
239 HLRAlgo::UpdateMinMax(x,y,z,TotMin,TotMax);
241 if (myType != GeomAbs_Line) {
242 Standard_Integer nbPnt = 30;
244 Standard_Real step = (b-a)/(nbPnt+1);
245 Standard_Real xa,ya,za,xb =0.,yb =0.,zb =0.;
246 Standard_Real dx1,dy1,dz1,dd1;
247 Standard_Real dx2,dy2,dz2,dd2;
249 for (i = 1; i <= nbPnt; i++) {
251 xa = xb; ya = yb; za = zb;
252 xb = x ; yb = y ; zb = z ;
253 ((HLRAlgo_Projector*) myProj)->Project(Value3D(a),x,y,z);
254 HLRAlgo::UpdateMinMax(x,y,z,TotMin,TotMax);
256 dx1 = x - xa; dy1 = y - ya; dz1 = z - za;
257 dd1 = sqrt (dx1 * dx1 + dy1 * dy1 + dz1 * dz1);
259 dx2 = xb - xa; dy2 = yb - ya; dz2 = zb - za;
260 dd2 = sqrt (dx2 * dx2 + dy2 * dy2 + dz2 * dz2);
262 Standard_Real p = (dx1 * dx2 + dy1 * dy2 + dz1 * dz2) / (dd1 * dd2);
263 dx1 = xa + p * dx1 - xb;
264 dy1 = ya + p * dy1 - yb;
265 dz1 = za + p * dz1 - zb;
266 dd1 = sqrt (dx1 * dx1 + dy1 * dy1 + dz1 * dz1);
267 if (dd1 > tolMinMax) tolMinMax = dd1;
273 ((HLRAlgo_Projector*) myProj)->Project(Value3D(b),x,y,z);
274 HLRAlgo::UpdateMinMax(x,y,z,TotMin,TotMax);
278 //=======================================================================
281 //=======================================================================
283 Standard_Real HLRBRep_Curve::Z (const Standard_Real U) const
286 HLRBRep_BCurveTool::D0(myCurve,U,P3d);
287 P3d.Transform(((HLRAlgo_Projector*) myProj)->Transformation());
291 //=======================================================================
294 //=======================================================================
296 void HLRBRep_Curve::Tangent (const Standard_Boolean AtStart,
297 gp_Pnt2d& P, gp_Dir2d& D) const
299 Standard_Real U = AtStart? HLRBRep_BCurveTool::FirstParameter(myCurve) :
300 HLRBRep_BCurveTool::LastParameter (myCurve);
303 HLRBRep_CLProps CLP(2,Epsilon(1.));
304 const HLRBRep_Curve* aCurve = this;
305 CLP.SetCurve(aCurve);
307 StdFail_UndefinedDerivative_Raise_if
308 (!CLP.IsTangentDefined(), "HLRBRep_Curve::Tangent");
312 //=======================================================================
315 //=======================================================================
317 void HLRBRep_Curve::D0 (const Standard_Real U, gp_Pnt2d& P) const
320 HLRBRep_BCurveTool::D0(myCurve,U,P3d);
321 P3d.Transform(((HLRAlgo_Projector*) myProj)->Transformation());
322 if (((HLRAlgo_Projector*) myProj)->Perspective()) {
323 Standard_Real R = 1.-P3d.Z()/((HLRAlgo_Projector*) myProj)->Focus();
324 P.SetCoord(P3d.X()/R,P3d.Y()/R);
326 else P.SetCoord(P3d.X(),P3d.Y()); */
328 HLRBRep_BCurveTool::D0(myCurve,U,P3d);
329 ((HLRAlgo_Projector*) myProj)->Project(P3d,P);
332 //=======================================================================
335 //=======================================================================
337 void HLRBRep_Curve::D1 (const Standard_Real U,
338 gp_Pnt2d& P, gp_Vec2d& V) const
340 // Mathematical formula for lines
343 // D1 = -------- + -------------
345 // 1 - ---- f (1 - ----)
350 HLRBRep_BCurveTool::D1(myCurve,U,P3D,V13D);
351 if (myProj->Perspective())
353 P3D .Transform(myProj->Transformation());
354 V13D.Transform(myProj->Transformation());
356 Standard_Real f = myProj->Focus();
357 Standard_Real R = 1. - P3D.Z()/f;
358 Standard_Real e = V13D.Z()/(f*R*R);
359 P.SetCoord(P3D .X()/R , P3D .Y()/R );
360 V.SetCoord(V13D.X()/R + P3D.X()*e, V13D.Y()/R + P3D.Y()*e);
364 myProj->Project(P3D,V13D,P,V);
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(myProj->Transformation());
389 V13D.Transform(myProj->Transformation());
390 V23D.Transform(myProj->Transformation());
391 if (myProj->Perspective())
393 Standard_Real f = myProj->Focus();
394 Standard_Real R = 1. - P3D.Z() / f;
395 Standard_Real q = f*R*R;
396 Standard_Real e = V13D.Z()/q;
397 Standard_Real c = e*V13D.Z()/(f*R);
398 P .SetCoord(P3D .X()/R , P3D .Y()/R );
399 V1.SetCoord(V13D.X()/R + P3D.X()*e, V13D.Y()/R + P3D.Y()*e);
400 V2.SetCoord(V23D.X()/R + 2*V13D.X()*e + P3D.X()*V23D.Z()/q + 2*P3D.X()*c,
401 V23D.Y()/R + 2*V13D.Y()*e + P3D.Y()*V23D.Z()/q + 2*P3D.Y()*c);
404 P .SetCoord(P3D .X(),P3D .Y());
405 V1.SetCoord(V13D.X(),V13D.Y());
406 V2.SetCoord(V23D.X(),V23D.Y());
410 //=======================================================================
413 //=======================================================================
415 void HLRBRep_Curve::D3 (const Standard_Real,
416 gp_Pnt2d&, gp_Vec2d&, gp_Vec2d&, gp_Vec2d&) const
420 //=======================================================================
423 //=======================================================================
425 gp_Vec2d HLRBRep_Curve::DN (const Standard_Real, const Standard_Integer) const
426 { return gp_Vec2d(); }
428 //=======================================================================
431 //=======================================================================
433 gp_Lin2d HLRBRep_Curve::Line () const
438 return gp_Lin2d(P,V);
441 //=======================================================================
444 //=======================================================================
446 gp_Circ2d HLRBRep_Curve::Circle () const
448 gp_Circ C = HLRBRep_BCurveTool::Circle(myCurve);
449 C.Transform(myProj->Transformation());
450 return ProjLib::Project(gp_Pln(gp::XOY()),C);
453 //=======================================================================
456 //=======================================================================
458 gp_Elips2d HLRBRep_Curve::Ellipse () const
460 if (HLRBRep_BCurveTool::GetType(myCurve) == GeomAbs_Ellipse) {
461 gp_Elips E = HLRBRep_BCurveTool::Ellipse(myCurve);
462 E.Transform(myProj->Transformation());
463 return ProjLib::Project(gp_Pln(gp::XOY()),E);
466 gp_Circ C = HLRBRep_BCurveTool::Circle(myCurve);
467 C.Transform(myProj->Transformation());
468 const gp_Dir& D1 = C.Axis().Direction();
469 const gp_Dir& D3 = D1.Crossed(gp::DZ());
470 const gp_Dir& D2 = D1.Crossed(D3);
471 Standard_Real rap = sqrt( D2.X()*D2.X() + D2.Y()*D2.Y() );
472 gp_Dir2d d(D1.Y(),-D1.X());
473 gp_Pnt2d p(C.Location().X(),C.Location().Y());
474 gp_Elips2d El(gp_Ax2d(p,d),C.Radius(),C.Radius()*rap);
475 if ( D1.Z() < 0 ) El.Reverse();
479 //=======================================================================
480 //function : Hyperbola
482 //=======================================================================
484 gp_Hypr2d HLRBRep_Curve::Hyperbola () const
485 { return gp_Hypr2d(); }
487 //=======================================================================
488 //function : Parabola
490 //=======================================================================
491 gp_Parab2d HLRBRep_Curve::Parabola () const
492 { return gp_Parab2d(); }
494 //=======================================================================
497 //=======================================================================
499 void HLRBRep_Curve::Poles (TColgp_Array1OfPnt2d& TP) const
501 Standard_Integer i1 = TP.Lower();
502 Standard_Integer i2 = TP.Upper();
503 TColgp_Array1OfPnt TP3(i1,i2);
504 //-- HLRBRep_BCurveTool::Poles(myCurve,TP3);
505 if(HLRBRep_BCurveTool::GetType(myCurve) == GeomAbs_BSplineCurve) {
506 (HLRBRep_BCurveTool::BSpline(myCurve))->Poles(TP3);
509 (HLRBRep_BCurveTool::Bezier(myCurve))->Poles(TP3);
511 for (Standard_Integer i = i1; i <= i2; i++) {
512 myProj->Transform(TP3(i));
513 TP(i).SetCoord(TP3(i).X(),TP3(i).Y());
517 //=======================================================================
520 //=======================================================================
522 void HLRBRep_Curve::Poles (const Handle(Geom_BSplineCurve)& aCurve,
523 TColgp_Array1OfPnt2d& TP) const
525 Standard_Integer i1 = TP.Lower();
526 Standard_Integer i2 = TP.Upper();
527 TColgp_Array1OfPnt TP3(i1,i2);
528 //-- HLRBRep_BCurveTool::Poles(myCurve,TP3);
531 for (Standard_Integer i = i1; i <= i2; i++) {
532 ((HLRAlgo_Projector*) myProj)->Transform(TP3(i));
533 TP(i).SetCoord(TP3(i).X(),TP3(i).Y());
537 //=======================================================================
538 //function : PolesAndWeights
540 //=======================================================================
542 void HLRBRep_Curve::PolesAndWeights (TColgp_Array1OfPnt2d& TP,
543 TColStd_Array1OfReal& TW) const
545 Standard_Integer i1 = TP.Lower();
546 Standard_Integer i2 = TP.Upper();
547 TColgp_Array1OfPnt TP3(i1,i2);
548 //-- HLRBRep_BCurveTool::PolesAndWeights(myCurve,TP3,TW);
550 if(HLRBRep_BCurveTool::GetType(myCurve) == GeomAbs_BSplineCurve) {
551 Handle(Geom_BSplineCurve) HB = (HLRBRep_BCurveTool::BSpline(myCurve));
554 //-- (HLRBRep_BCurveTool::BSpline(myCurve))->PolesAndWeights(TP3,TW);
557 Handle(Geom_BezierCurve) HB = (HLRBRep_BCurveTool::Bezier(myCurve));
560 //-- (HLRBRep_BCurveTool::Bezier(myCurve))->PolesAndWeights(TP3,TW);
562 for (Standard_Integer i = i1; i <= i2; i++) {
563 ((HLRAlgo_Projector*) myProj)->Transform(TP3(i));
564 TP(i).SetCoord(TP3(i).X(),TP3(i).Y());
568 //=======================================================================
569 //function : PolesAndWeights
571 //=======================================================================
573 void HLRBRep_Curve::PolesAndWeights (const Handle(Geom_BSplineCurve)& aCurve,
574 TColgp_Array1OfPnt2d& TP,
575 TColStd_Array1OfReal& TW) const
577 Standard_Integer i1 = TP.Lower();
578 Standard_Integer i2 = TP.Upper();
579 TColgp_Array1OfPnt TP3(i1,i2);
580 //-- HLRBRep_BCurveTool::PolesAndWeights(myCurve,TP3,TW);
584 //-- (HLRBRep_BCurveTool::BSpline(myCurve))->PolesAndWeights(TP3,TW);
586 for (Standard_Integer i = i1; i <= i2; i++) {
587 ((HLRAlgo_Projector*) myProj)->Transform(TP3(i));
588 TP(i).SetCoord(TP3(i).X(),TP3(i).Y());
592 //=======================================================================
595 //=======================================================================
597 void HLRBRep_Curve::Knots (TColStd_Array1OfReal& kn) const
599 if(HLRBRep_BCurveTool::GetType(myCurve) == GeomAbs_BSplineCurve) {
600 Handle(Geom_BSplineCurve) HB = (HLRBRep_BCurveTool::BSpline(myCurve));
605 //=======================================================================
606 //function : Multiplicities
608 //=======================================================================
610 void HLRBRep_Curve::Multiplicities (TColStd_Array1OfInteger& mu) const
612 if(HLRBRep_BCurveTool::GetType(myCurve) == GeomAbs_BSplineCurve) {
613 Handle(Geom_BSplineCurve) HB = (HLRBRep_BCurveTool::BSpline(myCurve));
614 HB->Multiplicities(mu);