1 // Created on: 2015-09-21
2 // Copyright (c) 2015 OPEN CASCADE SAS
4 // This file is part of Open CASCADE Technology software library.
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.
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
15 #include <GeomEvaluator_SurfaceOfRevolution.hxx>
17 #include <Adaptor3d_HCurve.hxx>
18 #include <gp_Trsf.hxx>
20 GeomEvaluator_SurfaceOfRevolution::GeomEvaluator_SurfaceOfRevolution(
21 const Handle(Geom_Curve)& theBase,
22 const gp_Dir& theRevolDir,
23 const gp_Pnt& theRevolLoc)
24 : GeomEvaluator_Surface(),
26 myRotAxis(theRevolLoc, theRevolDir)
30 GeomEvaluator_SurfaceOfRevolution::GeomEvaluator_SurfaceOfRevolution(
31 const Handle(Adaptor3d_HCurve)& theBase,
32 const gp_Dir& theRevolDir,
33 const gp_Pnt& theRevolLoc)
34 : GeomEvaluator_Surface(),
35 myBaseAdaptor(theBase),
36 myRotAxis(theRevolLoc, theRevolDir)
40 void GeomEvaluator_SurfaceOfRevolution::D0(
41 const Standard_Real theU, const Standard_Real theV,
42 gp_Pnt& theValue) const
44 if (!myBaseAdaptor.IsNull())
45 myBaseAdaptor->D0(theV, theValue);
47 myBaseCurve->D0(theV, theValue);
50 aRotation.SetRotation(myRotAxis, theU);
51 theValue.Transform(aRotation);
54 void GeomEvaluator_SurfaceOfRevolution::D1(
55 const Standard_Real theU, const Standard_Real theV,
56 gp_Pnt& theValue, gp_Vec& theD1U, gp_Vec& theD1V) const
58 if (!myBaseAdaptor.IsNull())
59 myBaseAdaptor->D1(theV, theValue, theD1V);
61 myBaseCurve->D1(theV, theValue, theD1V);
63 // vector from center of rotation to the point on rotated curve
64 gp_XYZ aCQ = theValue.XYZ() - myRotAxis.Location().XYZ();
65 theD1U = gp_Vec(myRotAxis.Direction().XYZ().Crossed(aCQ));
66 // If the point is placed on the axis of revolution then derivatives on U are undefined.
67 // Manually set them to zero.
68 if (theD1U.SquareMagnitude() < Precision::SquareConfusion())
69 theD1U.SetCoord(0.0, 0.0, 0.0);
72 aRotation.SetRotation(myRotAxis, theU);
73 theValue.Transform(aRotation);
74 theD1U.Transform(aRotation);
75 theD1V.Transform(aRotation);
78 void GeomEvaluator_SurfaceOfRevolution::D2(
79 const Standard_Real theU, const Standard_Real theV,
80 gp_Pnt& theValue, gp_Vec& theD1U, gp_Vec& theD1V,
81 gp_Vec& theD2U, gp_Vec& theD2V, gp_Vec& theD2UV) const
83 if (!myBaseAdaptor.IsNull())
84 myBaseAdaptor->D2(theV, theValue, theD1V, theD2V);
86 myBaseCurve->D2(theV, theValue, theD1V, theD2V);
88 // vector from center of rotation to the point on rotated curve
89 gp_XYZ aCQ = theValue.XYZ() - myRotAxis.Location().XYZ();
90 const gp_XYZ& aDir = myRotAxis.Direction().XYZ();
91 theD1U = gp_Vec(aDir.Crossed(aCQ));
92 // If the point is placed on the axis of revolution then derivatives on U are undefined.
93 // Manually set them to zero.
94 if (theD1U.SquareMagnitude() < Precision::SquareConfusion())
95 theD1U.SetCoord(0.0, 0.0, 0.0);
96 theD2U = gp_Vec(aDir.Dot(aCQ) * aDir - aCQ);
97 theD2UV = gp_Vec(aDir.Crossed(theD1V.XYZ()));
100 aRotation.SetRotation(myRotAxis, theU);
101 theValue.Transform(aRotation);
102 theD1U.Transform(aRotation);
103 theD1V.Transform(aRotation);
104 theD2U.Transform(aRotation);
105 theD2V.Transform(aRotation);
106 theD2UV.Transform(aRotation);
109 void GeomEvaluator_SurfaceOfRevolution::D3(
110 const Standard_Real theU, const Standard_Real theV,
111 gp_Pnt& theValue, gp_Vec& theD1U, gp_Vec& theD1V,
112 gp_Vec& theD2U, gp_Vec& theD2V, gp_Vec& theD2UV,
113 gp_Vec& theD3U, gp_Vec& theD3V, gp_Vec& theD3UUV, gp_Vec& theD3UVV) const
115 if (!myBaseAdaptor.IsNull())
116 myBaseAdaptor->D3(theV, theValue, theD1V, theD2V, theD3V);
118 myBaseCurve->D3(theV, theValue, theD1V, theD2V, theD3V);
120 // vector from center of rotation to the point on rotated curve
121 gp_XYZ aCQ = theValue.XYZ() - myRotAxis.Location().XYZ();
122 const gp_XYZ& aDir = myRotAxis.Direction().XYZ();
123 theD1U = gp_Vec(aDir.Crossed(aCQ));
124 // If the point is placed on the axis of revolution then derivatives on U are undefined.
125 // Manually set them to zero.
126 if (theD1U.SquareMagnitude() < Precision::SquareConfusion())
127 theD1U.SetCoord(0.0, 0.0, 0.0);
128 theD2U = gp_Vec(aDir.Dot(aCQ) * aDir - aCQ);
129 theD2UV = gp_Vec(aDir.Crossed(theD1V.XYZ()));
131 theD3UUV = gp_Vec(aDir.Dot(theD1V.XYZ()) * aDir - theD1V.XYZ());
132 theD3UVV = gp_Vec(aDir.Crossed(theD2V.XYZ()));
135 aRotation.SetRotation(myRotAxis, theU);
136 theValue.Transform(aRotation);
137 theD1U.Transform(aRotation);
138 theD1V.Transform(aRotation);
139 theD2U.Transform(aRotation);
140 theD2V.Transform(aRotation);
141 theD2UV.Transform(aRotation);
142 theD3U.Transform(aRotation);
143 theD3V.Transform(aRotation);
144 theD3UUV.Transform(aRotation);
145 theD3UVV.Transform(aRotation);
148 gp_Vec GeomEvaluator_SurfaceOfRevolution::DN(
149 const Standard_Real theU, const Standard_Real theV,
150 const Standard_Integer theDerU, const Standard_Integer theDerV) const
152 Standard_RangeError_Raise_if(theDerU < 0, "GeomEvaluator_SurfaceOfRevolution::DN(): theDerU < 0");
153 Standard_RangeError_Raise_if(theDerV < 0, "GeomEvaluator_SurfaceOfRevolution::DN(): theDerV < 0");
154 Standard_RangeError_Raise_if(theDerU + theDerV < 1,
155 "GeomEvaluator_SurfaceOfRevolution::DN(): theDerU + theDerV < 1");
158 aRotation.SetRotation(myRotAxis, theU);
165 if (!myBaseAdaptor.IsNull())
166 aResult = myBaseAdaptor->DN(theV, theDerV);
168 aResult = myBaseCurve->DN(theV, theDerV);
174 if (!myBaseAdaptor.IsNull())
175 myBaseAdaptor->D0(theV, aP);
177 myBaseCurve->D0(theV, aP);
178 aDV = gp_Vec(aP.XYZ() - myRotAxis.Location().XYZ());
182 if (!myBaseAdaptor.IsNull())
183 aDV = myBaseAdaptor->DN(theV, theDerV);
185 aDV = myBaseCurve->DN(theV, theDerV);
188 const gp_XYZ& aDir = myRotAxis.Direction().XYZ();
189 if (theDerU % 4 == 1)
190 aResult = gp_Vec(aDir.Crossed(aDV.XYZ()));
191 else if (theDerU % 4 == 2)
192 aResult = gp_Vec(aDir.Dot(aDV.XYZ()) * aDir - aDV.XYZ());
193 else if (theDerU % 4 == 3)
194 aResult = gp_Vec(aDir.Crossed(aDV.XYZ())) * (-1.0);
196 aResult = gp_Vec(aDV.XYZ() - aDir.Dot(aDV.XYZ()) * aDir);
199 aResult.Transform(aRotation);