0029948: Uninitialized variable in GeomEvaluator_OffsetSurface::CalculateD0(...)...
[occt.git] / src / GeomEvaluator / GeomEvaluator_SurfaceOfRevolution.cxx
1 // Created on: 2015-09-21
2 // Copyright (c) 2015 OPEN CASCADE SAS
3 //
4 // This file is part of Open CASCADE Technology software library.
5 //
6 // This library is free software; you can redistribute it and/or modify it under
7 // the terms of the GNU Lesser General Public License version 2.1 as published
8 // by the Free Software Foundation, with special exception defined in the file
9 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10 // distribution for complete text of the license and disclaimer of any warranty.
11 //
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
14
15 #include <GeomEvaluator_SurfaceOfRevolution.hxx>
16
17 #include <Adaptor3d_HCurve.hxx>
18 #include <gp_Trsf.hxx>
19
20 IMPLEMENT_STANDARD_RTTIEXT(GeomEvaluator_SurfaceOfRevolution,GeomEvaluator_Surface)
21
22 GeomEvaluator_SurfaceOfRevolution::GeomEvaluator_SurfaceOfRevolution(
23         const Handle(Geom_Curve)& theBase,
24         const gp_Dir& theRevolDir,
25         const gp_Pnt& theRevolLoc)
26   : GeomEvaluator_Surface(),
27     myBaseCurve(theBase),
28     myRotAxis(theRevolLoc, theRevolDir)
29 {
30 }
31
32 GeomEvaluator_SurfaceOfRevolution::GeomEvaluator_SurfaceOfRevolution(
33         const Handle(Adaptor3d_HCurve)& theBase,
34         const gp_Dir& theRevolDir,
35         const gp_Pnt& theRevolLoc)
36   : GeomEvaluator_Surface(),
37     myBaseAdaptor(theBase),
38     myRotAxis(theRevolLoc, theRevolDir)
39 {
40 }
41
42 void GeomEvaluator_SurfaceOfRevolution::D0(
43     const Standard_Real theU, const Standard_Real theV,
44     gp_Pnt& theValue) const
45 {
46   if (!myBaseAdaptor.IsNull())
47     myBaseAdaptor->D0(theV, theValue);
48   else
49     myBaseCurve->D0(theV, theValue);
50
51   gp_Trsf aRotation;
52   aRotation.SetRotation(myRotAxis, theU);
53   theValue.Transform(aRotation);
54 }
55
56 void GeomEvaluator_SurfaceOfRevolution::D1(
57     const Standard_Real theU, const Standard_Real theV,
58     gp_Pnt& theValue, gp_Vec& theD1U, gp_Vec& theD1V) const
59 {
60   if (!myBaseAdaptor.IsNull())
61     myBaseAdaptor->D1(theV, theValue, theD1V);
62   else
63     myBaseCurve->D1(theV, theValue, theD1V);
64
65   // vector from center of rotation to the point on rotated curve
66   gp_XYZ aCQ = theValue.XYZ() - myRotAxis.Location().XYZ();
67   theD1U = gp_Vec(myRotAxis.Direction().XYZ().Crossed(aCQ));
68   // If the point is placed on the axis of revolution then derivatives on U are undefined.
69   // Manually set them to zero.
70   if (theD1U.SquareMagnitude() < Precision::SquareConfusion())
71     theD1U.SetCoord(0.0, 0.0, 0.0);
72
73   gp_Trsf aRotation;
74   aRotation.SetRotation(myRotAxis, theU);
75   theValue.Transform(aRotation);
76   theD1U.Transform(aRotation);
77   theD1V.Transform(aRotation);
78 }
79
80 void GeomEvaluator_SurfaceOfRevolution::D2(
81     const Standard_Real theU, const Standard_Real theV,
82     gp_Pnt& theValue, gp_Vec& theD1U, gp_Vec& theD1V,
83     gp_Vec& theD2U, gp_Vec& theD2V, gp_Vec& theD2UV) const
84 {
85   if (!myBaseAdaptor.IsNull())
86     myBaseAdaptor->D2(theV, theValue, theD1V, theD2V);
87   else
88     myBaseCurve->D2(theV, theValue, theD1V, theD2V);
89
90   // vector from center of rotation to the point on rotated curve
91   gp_XYZ aCQ = theValue.XYZ() - myRotAxis.Location().XYZ();
92   const gp_XYZ& aDir = myRotAxis.Direction().XYZ();
93   theD1U = gp_Vec(aDir.Crossed(aCQ));
94   // If the point is placed on the axis of revolution then derivatives on U are undefined.
95   // Manually set them to zero.
96   if (theD1U.SquareMagnitude() < Precision::SquareConfusion())
97     theD1U.SetCoord(0.0, 0.0, 0.0);
98   theD2U = gp_Vec(aDir.Dot(aCQ) * aDir - aCQ);
99   theD2UV = gp_Vec(aDir.Crossed(theD1V.XYZ()));
100
101   gp_Trsf aRotation;
102   aRotation.SetRotation(myRotAxis, theU);
103   theValue.Transform(aRotation);
104   theD1U.Transform(aRotation);
105   theD1V.Transform(aRotation);
106   theD2U.Transform(aRotation);
107   theD2V.Transform(aRotation);
108   theD2UV.Transform(aRotation);
109 }
110
111 void GeomEvaluator_SurfaceOfRevolution::D3(
112     const Standard_Real theU, const Standard_Real theV,
113     gp_Pnt& theValue, gp_Vec& theD1U, gp_Vec& theD1V,
114     gp_Vec& theD2U, gp_Vec& theD2V, gp_Vec& theD2UV,
115     gp_Vec& theD3U, gp_Vec& theD3V, gp_Vec& theD3UUV, gp_Vec& theD3UVV) const
116 {
117   if (!myBaseAdaptor.IsNull())
118     myBaseAdaptor->D3(theV, theValue, theD1V, theD2V, theD3V);
119   else
120     myBaseCurve->D3(theV, theValue, theD1V, theD2V, theD3V);
121
122   // vector from center of rotation to the point on rotated curve
123   gp_XYZ aCQ = theValue.XYZ() - myRotAxis.Location().XYZ();
124   const gp_XYZ& aDir = myRotAxis.Direction().XYZ();
125   theD1U = gp_Vec(aDir.Crossed(aCQ));
126   // If the point is placed on the axis of revolution then derivatives on U are undefined.
127   // Manually set them to zero.
128   if (theD1U.SquareMagnitude() < Precision::SquareConfusion())
129     theD1U.SetCoord(0.0, 0.0, 0.0);
130   theD2U = gp_Vec(aDir.Dot(aCQ) * aDir - aCQ);
131   theD2UV = gp_Vec(aDir.Crossed(theD1V.XYZ()));
132   theD3U = -theD1U;
133   theD3UUV = gp_Vec(aDir.Dot(theD1V.XYZ()) * aDir - theD1V.XYZ());
134   theD3UVV = gp_Vec(aDir.Crossed(theD2V.XYZ()));
135
136   gp_Trsf aRotation;
137   aRotation.SetRotation(myRotAxis, theU);
138   theValue.Transform(aRotation);
139   theD1U.Transform(aRotation);
140   theD1V.Transform(aRotation);
141   theD2U.Transform(aRotation);
142   theD2V.Transform(aRotation);
143   theD2UV.Transform(aRotation);
144   theD3U.Transform(aRotation);
145   theD3V.Transform(aRotation);
146   theD3UUV.Transform(aRotation);
147   theD3UVV.Transform(aRotation);
148 }
149
150 gp_Vec GeomEvaluator_SurfaceOfRevolution::DN(
151     const Standard_Real theU, const Standard_Real theV,
152     const Standard_Integer theDerU, const Standard_Integer theDerV) const
153 {
154   Standard_RangeError_Raise_if(theDerU < 0, "GeomEvaluator_SurfaceOfRevolution::DN(): theDerU < 0");
155   Standard_RangeError_Raise_if(theDerV < 0, "GeomEvaluator_SurfaceOfRevolution::DN(): theDerV < 0");
156   Standard_RangeError_Raise_if(theDerU + theDerV < 1,
157       "GeomEvaluator_SurfaceOfRevolution::DN(): theDerU + theDerV < 1");
158
159   gp_Trsf aRotation;
160   aRotation.SetRotation(myRotAxis, theU);
161
162   gp_Pnt aP;
163   gp_Vec aDV;
164   gp_Vec aResult;
165   if (theDerU == 0)
166   {
167     if (!myBaseAdaptor.IsNull())
168       aResult = myBaseAdaptor->DN(theV, theDerV);
169     else
170       aResult = myBaseCurve->DN(theV, theDerV);
171   }
172   else
173   {
174     if (theDerV == 0)
175     {
176       if (!myBaseAdaptor.IsNull())
177         myBaseAdaptor->D0(theV, aP);
178       else
179         myBaseCurve->D0(theV, aP);
180       aDV = gp_Vec(aP.XYZ() - myRotAxis.Location().XYZ());
181     }
182     else
183     {
184       if (!myBaseAdaptor.IsNull())
185         aDV = myBaseAdaptor->DN(theV, theDerV);
186       else
187         aDV = myBaseCurve->DN(theV, theDerV);
188     }
189
190     const gp_XYZ& aDir = myRotAxis.Direction().XYZ();
191     if (theDerU % 4 == 1)
192       aResult = gp_Vec(aDir.Crossed(aDV.XYZ()));
193     else if (theDerU % 4 == 2)
194       aResult = gp_Vec(aDir.Dot(aDV.XYZ()) * aDir - aDV.XYZ());
195     else if (theDerU % 4 == 3)
196       aResult = gp_Vec(aDir.Crossed(aDV.XYZ())) * (-1.0);
197     else
198       aResult = gp_Vec(aDV.XYZ() - aDir.Dot(aDV.XYZ()) * aDir);
199   }
200
201   aResult.Transform(aRotation);
202   return aResult;
203 }
204