0022623: Use of uninitialized variables in HLRBRep_Curve::UpdateMinMax in debug mode
[occt.git] / src / HLRBRep / HLRBRep_Curve.cxx
1 // File:      HLRBRep_Curve.cxx
2 // Created:   Fri Mar 13 11:08:32 1992
3 // Author:    Christophe MARION
4 // Copyright: OPEN CASCADE 2000
5
6 #include <HLRBRep_Curve.ixx>
7 #include <gp.hxx>
8 #include <gp_Ax3.hxx>
9 #include <gp_Pln.hxx>
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>
20
21 //OCC155 // jfa 05.03.2002 // bad vectors projection
22
23 //=======================================================================
24 //function : HLRBRep_Curve
25 //purpose  : 
26 //=======================================================================
27
28 HLRBRep_Curve::HLRBRep_Curve ()
29 {}
30
31 //=======================================================================
32 //function : Curve
33 //purpose  : 
34 //=======================================================================
35
36 void HLRBRep_Curve::Curve (const TopoDS_Edge& E)
37 { myCurve.Initialize(E); }
38
39 //=======================================================================
40 //function : Parameter2d
41 //purpose  : 
42 //=======================================================================
43
44 Standard_Real 
45 HLRBRep_Curve::Parameter2d (const Standard_Real P3d) const
46 {
47   // Mathematical formula for lines
48
49   //        myOF P3d (myOF myVX - myOZ myVX + myOX myVZ)
50   // Res -> --------------------------------------------
51   //        (-myOF + myOZ) (-myOF + myOZ + P3d myVZ)
52
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));
57     }
58     return P3d * myVX;
59   }
60
61   else if (myType == GeomAbs_Ellipse) {
62     return P3d + myOX;
63   }
64
65   return P3d;
66 }
67
68 //=======================================================================
69 //function : Parameter3d
70 //purpose  : 
71 //=======================================================================
72
73 Standard_Real
74 HLRBRep_Curve::Parameter3d (const Standard_Real P2d) const
75 {
76   // Mathematical formula for lines
77
78   //                                 2   
79   //                   (-myOF + myOZ)  P2d
80   // P3d -> -----------------------------------------------------
81   //        (myOF - myOZ) (myOF myVX + P2d myVZ) + myOF myOX myVZ
82
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);
87     }
88     return P2d / myVX;
89   }
90
91   else if (myType == GeomAbs_Ellipse) {
92     return P2d - myOX;
93   }
94
95   return P2d;
96 }
97
98 //=======================================================================
99 //function : Update
100 //purpose  : 
101 //=======================================================================
102
103 Standard_Real  HLRBRep_Curve::Update (const Standard_Address TotMin,
104                                       const Standard_Address TotMax)
105 {
106   GeomAbs_CurveType typ = HLRBRep_BCurveTool::GetType(myCurve);
107   myType = GeomAbs_OtherCurve;
108
109   switch (typ) {
110
111   case GeomAbs_Line:
112     myType = typ;
113     break;
114
115   case GeomAbs_Circle:
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;
123       else {
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);
130       }
131     }
132     break;
133
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;
141       }
142     }
143     break;
144
145   case GeomAbs_BezierCurve:
146     if (HLRBRep_BCurveTool::Degree(myCurve) == 1)
147       myType = GeomAbs_Line;
148     else if (!((HLRAlgo_Projector*) myProj)->Perspective())
149       myType = typ;
150     break;
151
152   case GeomAbs_BSplineCurve:
153     if (!((HLRAlgo_Projector*) myProj)->Perspective())
154       myType = typ;
155     break;
156
157   default:
158     break;
159   }
160
161   if (myType == GeomAbs_Line) {
162     // compute the values for a line
163     gp_Lin L;
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);
167     }
168     else {  // bezier degree 1
169       gp_Pnt PL;
170       gp_Vec VL;
171       HLRBRep_BCurveTool::D1(myCurve,0,PL,VL);
172       L = gp_Lin(PL,VL);
173       l3d = PL.Distance(HLRBRep_BCurveTool::Value(myCurve,1.));
174     }
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()) {
180       gp_Pnt2d F;
181       gp_Vec2d VFX;
182       D1(0.,F,VFX);
183       VFX.Normalize();
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();
190       VFZ /= myOF;
191       myVZ = VFZ * V;
192       myVZ *= l3d;
193       myOZ = VFZ * gp_Vec(P.X()-F.X(),P.Y()-F.Y(),P.Z());
194     }
195     else myVX = Sqrt(V.X() * V.X() + V.Y() * V.Y()) * l3d;
196   }
197   return(UpdateMinMax(TotMin,TotMax));
198 }
199
200 //=======================================================================
201 //function : UpdateMinMax
202 //purpose  : 
203 //=======================================================================
204
205 Standard_Real 
206 HLRBRep_Curve::UpdateMinMax (const Standard_Address TotMin,
207                              const Standard_Address TotMax)
208 {
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);
214
215   if (myType != GeomAbs_Line) {
216     Standard_Integer nbPnt = 30;
217     Standard_Integer i;
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;
222
223     for (i = 1; i <= nbPnt; i++) {
224       a += step;
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);
229       if (i >= 2) {
230         dx1 = x - xa; dy1 = y - ya; dz1 = z - za;
231         dd1 = sqrt (dx1 * dx1 + dy1 * dy1 + dz1 * dz1);
232         if (dd1 > 0) {
233           dx2 = xb - xa; dy2 = yb - ya; dz2 = zb - za;
234           dd2 = sqrt (dx2 * dx2 + dy2 * dy2 + dz2 * dz2);
235           if (dd2 > 0) {
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;
242           }
243         }
244       }
245     }
246   }
247   ((HLRAlgo_Projector*) myProj)->Project(Value3D(b),x,y,z);
248   HLRAlgo::UpdateMinMax(x,y,z,TotMin,TotMax);
249   return tolMinMax;
250 }
251
252 //=======================================================================
253 //function : Z
254 //purpose  : 
255 //=======================================================================
256
257 Standard_Real HLRBRep_Curve::Z (const Standard_Real U) const 
258 {
259   gp_Pnt P3d;
260   HLRBRep_BCurveTool::D0(myCurve,U,P3d);
261   P3d.Transform(((HLRAlgo_Projector*) myProj)->Transformation());
262   return P3d.Z();
263 }
264
265 //=======================================================================
266 //function : Tangent
267 //purpose  : 
268 //=======================================================================
269
270 void HLRBRep_Curve::Tangent (const Standard_Boolean AtStart,
271                              gp_Pnt2d& P, gp_Dir2d& D) const
272 {
273   Standard_Real U = AtStart? HLRBRep_BCurveTool::FirstParameter(myCurve) :
274                              HLRBRep_BCurveTool::LastParameter (myCurve);
275
276   D0(U,P);
277   HLRBRep_CLProps CLP(2,Epsilon(1.));
278   const Standard_Address crv = (const Standard_Address)this;
279   CLP.SetCurve(crv);
280   CLP.SetParameter(U);
281   StdFail_UndefinedDerivative_Raise_if
282     (!CLP.IsTangentDefined(), "HLRBRep_Curve::Tangent");
283   CLP.Tangent(D); 
284 }
285
286 //=======================================================================
287 //function : D0
288 //purpose  : 
289 //=======================================================================
290
291 void HLRBRep_Curve::D0 (const Standard_Real U, gp_Pnt2d& P) const
292 {
293   /* gp_Pnt P3d;
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);
299   }
300   else P.SetCoord(P3d.X(),P3d.Y()); */
301   gp_Pnt P3d;
302   HLRBRep_BCurveTool::D0(myCurve,U,P3d); 
303   ((HLRAlgo_Projector*) myProj)->Project(P3d,P);
304 }
305
306 //=======================================================================
307 //function : D1
308 //purpose  : 
309 //=======================================================================
310
311 void HLRBRep_Curve::D1 (const Standard_Real U,
312                         gp_Pnt2d& P, gp_Vec2d& V) const
313 {
314   // Mathematical formula for lines
315
316   //        X'[t]      X[t] Z'[t]                                     
317   // D1 =  -------- + -------------                                   
318   //           Z[t]          Z[t] 2                                   
319   //       1 - ----   f (1 - ----)                                    
320   //            f             f                                       
321
322   /* gp_Pnt P3D;
323   gp_Vec V13D;
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);
333   }
334   else {
335     P.SetCoord(P3D .X(),P3D .Y());
336     V.SetCoord(V13D.X(),V13D.Y());
337   } */
338   gp_Pnt P3D;
339   gp_Vec V13D;
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);
347   }
348   else {
349     //OCC155
350     ((HLRAlgo_Projector*) myProj)->Project(P3D,V13D,P,V);
351     /* ((HLRAlgo_Projector*) myProj)->Project(P3D,P);
352     gp_Pnt2d opop;
353     gp_Pnt uiui(V13D.X(),V13D.Y(),V13D.Z());
354     ((HLRAlgo_Projector*) myProj)->Project(uiui,opop);
355     V.SetCoord(opop.X(),opop.Y()); */
356   }
357 }
358
359 //=======================================================================
360 //function : D2
361 //purpose  : 
362 //=======================================================================
363
364 void HLRBRep_Curve::D2 (const Standard_Real U,
365                         gp_Pnt2d& P, gp_Vec2d& V1, gp_Vec2d& V2) const
366 {
367   // Mathematical formula for lines
368   
369   //                                   2
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 - ----)   
374   //               f                f            f             f      
375
376   gp_Pnt P3D;
377   gp_Vec V13D,V23D;
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);
392   }
393   else {
394     P .SetCoord(P3D .X(),P3D .Y());
395     V1.SetCoord(V13D.X(),V13D.Y());
396     V2.SetCoord(V23D.X(),V23D.Y());
397   }
398 }
399
400 //=======================================================================
401 //function : D3
402 //purpose  : 
403 //=======================================================================
404
405 void HLRBRep_Curve::D3 (const Standard_Real,
406                         gp_Pnt2d&, gp_Vec2d&, gp_Vec2d&, gp_Vec2d&) const
407 {
408 }
409
410 //=======================================================================
411 //function : DN
412 //purpose  : 
413 //=======================================================================
414
415 gp_Vec2d HLRBRep_Curve::DN (const Standard_Real, const Standard_Integer) const
416 { return gp_Vec2d(); }
417
418 //=======================================================================
419 //function : Line
420 //purpose  : 
421 //=======================================================================
422
423 gp_Lin2d HLRBRep_Curve::Line () const
424 {
425   gp_Pnt2d P;
426   gp_Vec2d V;
427   D1(0.,P,V);
428   return gp_Lin2d(P,V);
429 }
430
431 //=======================================================================
432 //function : Circle
433 //purpose  : 
434 //=======================================================================
435
436 gp_Circ2d HLRBRep_Curve::Circle () const
437 {
438   gp_Circ C = HLRBRep_BCurveTool::Circle(myCurve);
439   C.Transform(((HLRAlgo_Projector*) myProj)->Transformation());
440   return ProjLib::Project(gp_Pln(gp::XOY()),C);
441 }
442
443 //=======================================================================
444 //function : Ellipse
445 //purpose  : 
446 //=======================================================================
447
448 gp_Elips2d HLRBRep_Curve::Ellipse () const
449 {
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);
454   }
455   // this is a circle
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();
466   return El;
467 }
468
469 //=======================================================================
470 //function : Hyperbola
471 //purpose  : 
472 //=======================================================================
473
474 gp_Hypr2d HLRBRep_Curve::Hyperbola () const
475 { return gp_Hypr2d(); }
476
477 //=======================================================================
478 //function : Parabola
479 //purpose  : 
480 //=======================================================================
481 gp_Parab2d HLRBRep_Curve::Parabola () const
482 { return gp_Parab2d(); }
483
484 //=======================================================================
485 //function : Poles
486 //purpose  : 
487 //=======================================================================
488
489 void  HLRBRep_Curve::Poles (TColgp_Array1OfPnt2d& TP) const
490 {
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);
497   }
498   else { 
499     (HLRBRep_BCurveTool::Bezier(myCurve))->Poles(TP3);
500   }
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());
504   }
505 }
506
507 //=======================================================================
508 //function : PolesAndWeights
509 //purpose  : 
510 //=======================================================================
511
512 void  HLRBRep_Curve::PolesAndWeights (TColgp_Array1OfPnt2d& TP,
513                                                TColStd_Array1OfReal& TW) const
514 {
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);
519   
520   if(HLRBRep_BCurveTool::GetType(myCurve) == GeomAbs_BSplineCurve) {
521     Handle(Geom_BSplineCurve) HB = (HLRBRep_BCurveTool::BSpline(myCurve));
522     HB->Poles(TP3);
523     HB->Weights(TW);  
524     //-- (HLRBRep_BCurveTool::BSpline(myCurve))->PolesAndWeights(TP3,TW);
525   }
526   else { 
527     Handle(Geom_BezierCurve) HB = (HLRBRep_BCurveTool::Bezier(myCurve));
528     HB->Poles(TP3);
529     HB->Weights(TW);
530     //-- (HLRBRep_BCurveTool::Bezier(myCurve))->PolesAndWeights(TP3,TW);
531   }
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());
535   }
536 }
537
538 //=======================================================================
539 //function : Knots
540 //purpose  : 
541 //=======================================================================
542
543 void  HLRBRep_Curve::Knots (TColStd_Array1OfReal& kn) const
544 {
545   if(HLRBRep_BCurveTool::GetType(myCurve) == GeomAbs_BSplineCurve) {
546     Handle(Geom_BSplineCurve) HB = (HLRBRep_BCurveTool::BSpline(myCurve));
547     HB->Knots(kn);
548   }
549 }
550
551 //=======================================================================
552 //function : Multiplicities
553 //purpose  : 
554 //=======================================================================
555
556 void  HLRBRep_Curve::Multiplicities (TColStd_Array1OfInteger& mu) const
557 {
558   if(HLRBRep_BCurveTool::GetType(myCurve) == GeomAbs_BSplineCurve) {
559     Handle(Geom_BSplineCurve) HB = (HLRBRep_BCurveTool::BSpline(myCurve));
560     HB->Multiplicities(mu);
561   }
562 }