0024275: Cppcheck warnings on uninitialized class members
[occt.git] / src / GeomFill / GeomFill_DiscreteTrihedron.cxx
1 // Created on: 2013-02-05
2 // Created by: Julia GERASIMOVA
3 // Copyright (c) 2001-2013 OPEN CASCADE SAS
4 //
5 // The content of this file is subject to the Open CASCADE Technology Public
6 // License Version 6.5 (the "License"). You may not use the content of this file
7 // except in compliance with the License. Please obtain a copy of the License
8 // at http://www.opencascade.org and read it completely before using this file.
9 //
10 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
11 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
12 //
13 // The Original Code and all software distributed under the License is
14 // distributed on an "AS IS" basis, without warranty of any kind, and the
15 // Initial Developer hereby disclaims all such warranties, including without
16 // limitation, any warranties of merchantability, fitness for a particular
17 // purpose or non-infringement. Please see the License for the specific terms
18 // and conditions governing the rights and limitations under the License.
19
20
21 #include <GeomFill_DiscreteTrihedron.ixx>
22 #include <GeomFill_DiscreteTrihedron.hxx>
23 #include <GeomFill_Frenet.hxx>
24 #include <GeomAbs_CurveType.hxx>
25 #include <Adaptor3d_HCurve.hxx>
26 #include <TColStd_Array1OfReal.hxx>
27 #include <TColStd_HSequenceOfReal.hxx>
28 #include <GeomFill_HSequenceOfAx2.hxx>
29
30
31 static const Standard_Real TolConf = Precision::Confusion();
32
33 //=======================================================================
34 //function : GeomFill_DiscreteTrihedron
35 //purpose  : Constructor
36 //=======================================================================
37
38 GeomFill_DiscreteTrihedron::GeomFill_DiscreteTrihedron() :
39     myUseFrenet(Standard_False)
40 {
41   myFrenet = new GeomFill_Frenet();
42   myKnots      = new TColStd_HSequenceOfReal();
43   myTrihedrons = new GeomFill_HSequenceOfAx2();
44 }
45
46 //=======================================================================
47 //function : Copy
48 //purpose  : 
49 //=======================================================================
50
51 Handle(GeomFill_TrihedronLaw) GeomFill_DiscreteTrihedron::Copy() const
52 {
53   Handle(GeomFill_DiscreteTrihedron) copy = new (GeomFill_DiscreteTrihedron)();
54   if (!myCurve.IsNull()) copy->SetCurve(myCurve);
55   return copy;
56 }
57
58 //=======================================================================
59 //function : SetCurve
60 //purpose  : 
61 //=======================================================================
62
63 void GeomFill_DiscreteTrihedron::SetCurve(const Handle(Adaptor3d_HCurve)& C) 
64 {
65   GeomFill_TrihedronLaw::SetCurve(C);
66   if (! C.IsNull()) {
67     GeomAbs_CurveType type;
68     type = C->GetType();
69     switch  (type) {
70     case GeomAbs_Circle:
71     case GeomAbs_Ellipse:
72     case GeomAbs_Hyperbola:
73     case GeomAbs_Parabola:
74     case GeomAbs_Line:
75       {
76         // No probleme
77         myUseFrenet = Standard_True;
78         myFrenet->SetCurve(C);
79         break;
80       }
81     default :
82       {
83         myUseFrenet = Standard_False;
84         // We have to fill <myKnots> and <myTrihedrons>
85         Init();
86         break;
87       }
88     }
89   }
90 }
91
92 //=======================================================================
93 //function : Init
94 //purpose  : 
95 //=======================================================================
96
97 void GeomFill_DiscreteTrihedron::Init()
98 {
99   Standard_Integer NbIntervals = myTrimmed->NbIntervals(GeomAbs_CN);
100   TColStd_Array1OfReal Knots(1, NbIntervals+1);
101   myTrimmed->Intervals(Knots, GeomAbs_CN);
102
103   //Standard_Real Tol = Precision::Confusion();
104   Standard_Integer NbSamples = 10;
105
106   Standard_Integer i, j;
107   for (i = 1; i <= NbIntervals; i++)
108   {
109     Standard_Real delta = (Knots(i+1) - Knots(i))/NbSamples;
110     for (j = 0; j < NbSamples; j++)
111     {
112       Standard_Real Param = Knots(i) + j*delta;
113       myKnots->Append(Param);
114     }
115   }
116   myKnots->Append(Knots(NbIntervals+1));
117   
118   
119   gp_Pnt Origin(0.,0.,0.), Pnt, SubPnt;
120   gp_Vec Tangent;
121   gp_Dir TangDir;
122   Standard_Real norm;
123   for (i = 1; i <= myKnots->Length(); i++)
124   {
125     Standard_Real Param = myKnots->Value(i);
126     myTrimmed->D1(Param, Pnt, Tangent);
127     norm = Tangent.Magnitude();
128     if (norm < TolConf)
129     {
130       Standard_Real subdelta = (myKnots->Value(i+1) - myKnots->Value(i))/NbSamples;
131       if (subdelta < Precision::PConfusion())
132         subdelta = myKnots->Value(i+1) - myKnots->Value(i);
133       SubPnt = myTrimmed->Value(Param + subdelta);
134       Tangent.SetXYZ(SubPnt.XYZ() - Pnt.XYZ());
135     }
136     //Tangent.Normalize();
137     TangDir = Tangent; //normalize;
138     Tangent = TangDir;
139     if (i == 1) //first point
140     {
141       gp_Ax2 FirstAxis(Origin, TangDir);
142       myTrihedrons->Append(FirstAxis);
143     }
144     else
145     {
146       gp_Ax2 LastAxis = myTrihedrons->Value(myTrihedrons->Length());
147       gp_Vec LastTangent = LastAxis.Direction();
148       gp_Vec AxisOfRotation = LastTangent ^ Tangent;
149       if (AxisOfRotation.Magnitude() <= gp::Resolution()) //tangents are equal or opposite
150       {
151         Standard_Real ScalarProduct = LastTangent * Tangent;
152         if (ScalarProduct > 0.) //tangents are equal
153           myTrihedrons->Append(LastAxis);
154         else //tangents are opposite
155         {
156           Standard_Real NewParam = (myKnots->Value(i-1) + myKnots->Value(i))/2.;
157           if (NewParam - myKnots->Value(i-1) < gp::Resolution())
158             Standard_ConstructionError::Raise("GeomFill_DiscreteTrihedron : impassable singularities on path curve");
159           myKnots->InsertBefore(i, NewParam);
160           i--;
161         }
162       }
163       else //good value of angle
164       {
165         Standard_Real theAngle = LastTangent.AngleWithRef(Tangent, AxisOfRotation);
166         gp_Ax1 theAxisOfRotation(Origin, AxisOfRotation);
167         gp_Ax2 NewAxis = LastAxis.Rotated(theAxisOfRotation, theAngle);
168         NewAxis.SetDirection(TangDir); //to prevent accumulation of floating computations error
169         myTrihedrons->Append(NewAxis);
170       }
171     }
172   }
173 }
174
175 //=======================================================================
176 //function : D0
177 //purpose  : 
178 //=======================================================================
179
180 Standard_Boolean GeomFill_DiscreteTrihedron::D0(const Standard_Real Param,
181                                                 gp_Vec& Tangent,
182                                                 gp_Vec& Normal,
183                                                 gp_Vec& BiNormal)
184 {
185   if (myUseFrenet)
186   {
187     myFrenet->D0(Param, Tangent, Normal, BiNormal);
188   }
189   else
190   {
191     //Locate <Param> in the sequence <myKnots>
192     Standard_Integer Index = -1;
193     Standard_Real TolPar = Precision::PConfusion();
194     //Standard_Real TolConf = Precision::Confusion();
195     Standard_Integer NbSamples = 10;
196     gp_Pnt Origin(0.,0.,0.);
197     
198     Standard_Integer i;
199     //gp_Ax2 PrevAxis;
200     //Standard_Real PrevParam;
201
202     Standard_Integer I1, I2;
203     I1 = 1;
204     I2 = myKnots->Length();
205     for (;;)
206     {
207       i = (I1 + I2)/2;
208       if (Param <= myKnots->Value(i))
209         I2 = i;
210       else
211         I1 = i;
212       if (I2 - I1 <= 1)
213         break;
214     }
215     Index = I1;
216     if (Abs(Param - myKnots->Value(I2)) < TolPar)
217       Index = I2;
218
219     Standard_Real PrevParam = myKnots->Value(Index);
220     gp_Ax2        PrevAxis  = myTrihedrons->Value(Index);
221     gp_Ax2 theAxis;
222     if (Abs(Param - PrevParam) < TolPar)
223       theAxis = PrevAxis;
224     else //<Param> is between knots
225     {
226       myTrimmed->D1(Param, myPoint, Tangent);
227       Standard_Real norm = Tangent.Magnitude();
228       if (norm < TolConf)
229       {
230         Standard_Real subdelta = (myKnots->Value(Index+1) - Param)/NbSamples;
231         if (subdelta < Precision::PConfusion())
232           subdelta = myKnots->Value(Index+1) - Param;
233         gp_Pnt SubPnt = myTrimmed->Value(Param + subdelta);
234         Tangent.SetXYZ(SubPnt.XYZ() - myPoint.XYZ());
235       }
236       //Tangent.Normalize();
237       gp_Dir TangDir(Tangent); //normalize;
238       Tangent = TangDir;
239       gp_Vec PrevTangent = PrevAxis.Direction();
240       gp_Vec AxisOfRotation = PrevTangent ^ Tangent;
241       if (AxisOfRotation.Magnitude() <= gp::Resolution()) //tangents are equal
242       {
243         //we assume that tangents can not be opposite
244         theAxis = PrevAxis;
245       }
246       else //good value of angle
247       {
248         Standard_Real theAngle = PrevTangent.AngleWithRef(Tangent, AxisOfRotation);
249         gp_Ax1 theAxisOfRotation(Origin, AxisOfRotation);
250         theAxis = PrevAxis.Rotated(theAxisOfRotation, theAngle);
251       }
252       theAxis.SetDirection(TangDir); //to prevent accumulation of floating computations error
253     } //end of else (Param is between knots)
254
255     Tangent  = theAxis.Direction();
256     Normal   = theAxis.XDirection();
257     BiNormal = theAxis.YDirection();
258   }
259   return Standard_True;
260 }
261
262 //=======================================================================
263 //function : D1
264 //purpose  : 
265 //=======================================================================
266
267 Standard_Boolean GeomFill_DiscreteTrihedron::D1(const Standard_Real Param,
268                                                 gp_Vec& Tangent,
269                                                 gp_Vec& DTangent,
270                                                 gp_Vec& Normal,
271                                                 gp_Vec& DNormal,
272                                                 gp_Vec& BiNormal,
273                                                 gp_Vec& DBiNormal) 
274 {
275   if (myUseFrenet)
276   {
277     myFrenet->D1(Param, Tangent, DTangent, Normal, DNormal, BiNormal, DBiNormal);
278   }
279   else
280   {
281     D0(Param, Tangent, Normal, BiNormal);
282
283     DTangent.SetCoord(0.,0.,0.);
284     DNormal.SetCoord(0.,0.,0.);
285     DBiNormal.SetCoord(0.,0.,0.);
286   }
287   return Standard_True;
288 }
289
290 //=======================================================================
291 //function : D2
292 //purpose  : 
293 //=======================================================================
294
295 Standard_Boolean GeomFill_DiscreteTrihedron::D2(const Standard_Real Param,
296                                                 gp_Vec& Tangent,
297                                                 gp_Vec& DTangent,
298                                                 gp_Vec& D2Tangent,
299                                                 gp_Vec& Normal,
300                                                 gp_Vec& DNormal,
301                                                 gp_Vec& D2Normal,
302                                                 gp_Vec& BiNormal,
303                                                 gp_Vec& DBiNormal,
304                                                 gp_Vec& D2BiNormal) 
305 {
306   if (myUseFrenet)
307   {
308     myFrenet->D2(Param, Tangent, DTangent, D2Tangent,
309                  Normal, DNormal, D2Normal,
310                  BiNormal, DBiNormal, D2BiNormal);
311   }
312   else
313   {
314     D0(Param, Tangent, Normal, BiNormal);
315     
316     DTangent.SetCoord(0.,0.,0.);
317     DNormal.SetCoord(0.,0.,0.);
318     DBiNormal.SetCoord(0.,0.,0.);
319     D2Tangent.SetCoord(0.,0.,0.);
320     D2Normal.SetCoord(0.,0.,0.);
321     D2BiNormal.SetCoord(0.,0.,0.);
322   }
323   return Standard_True;
324 }
325
326 //=======================================================================
327 //function : NbIntervals
328 //purpose  : 
329 //=======================================================================
330
331 Standard_Integer GeomFill_DiscreteTrihedron::NbIntervals(const GeomAbs_Shape) const
332 {
333   return (myTrimmed->NbIntervals(GeomAbs_CN));
334 }
335
336 //=======================================================================
337 //function : Intervals
338 //purpose  : 
339 //=======================================================================
340
341 void GeomFill_DiscreteTrihedron::Intervals(TColStd_Array1OfReal& T,
342                                            const GeomAbs_Shape) const
343 {
344   myTrimmed->Intervals(T, GeomAbs_CN);
345 }
346
347  void GeomFill_DiscreteTrihedron::GetAverageLaw(gp_Vec& ATangent,
348                                      gp_Vec& ANormal,
349                                      gp_Vec& ABiNormal) 
350 {
351   Standard_Integer Num = 20; //order of digitalization
352   gp_Vec T, N, BN;
353   ATangent = gp_Vec(0, 0, 0);
354   ANormal = gp_Vec(0, 0, 0);
355   ABiNormal = gp_Vec(0, 0, 0);
356   Standard_Real Step = (myTrimmed->LastParameter() - 
357                         myTrimmed->FirstParameter()) / Num;
358   Standard_Real Param;
359   for (Standard_Integer i = 0; i <= Num; i++) {
360     Param = myTrimmed->FirstParameter() + i*Step;
361     if (Param > myTrimmed->LastParameter()) Param = myTrimmed->LastParameter();
362     D0(Param, T, N, BN);
363     ATangent += T;
364     ANormal += N;
365     ABiNormal += BN;
366   }
367   ATangent /= Num + 1;
368   ANormal /= Num + 1;
369
370   ATangent.Normalize();
371   ABiNormal = ATangent.Crossed(ANormal).Normalized();
372   ANormal = ABiNormal.Crossed(ATangent);
373 }
374
375 //=======================================================================
376 //function : IsConstant
377 //purpose  : 
378 //=======================================================================
379
380  Standard_Boolean GeomFill_DiscreteTrihedron::IsConstant() const
381 {
382   return (myCurve->GetType() == GeomAbs_Line);
383 }
384
385 //=======================================================================
386 //function : IsOnlyBy3dCurve
387 //purpose  : 
388 //=======================================================================
389
390  Standard_Boolean GeomFill_DiscreteTrihedron::IsOnlyBy3dCurve() const
391 {
392   return Standard_True;
393 }