0026838: Using GeomEvaluators for calculation of values of curves
[occt.git] / src / GeomEvaluator / GeomEvaluator_SurfaceOfRevolution.cxx
CommitLineData
6b84c3f7 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
20GeomEvaluator_SurfaceOfRevolution::GeomEvaluator_SurfaceOfRevolution(
21 const Handle(Geom_Curve)& theBase,
22 const gp_Dir& theRevolDir,
23 const gp_Pnt& theRevolLoc)
24 : GeomEvaluator_Surface(),
25 myBaseCurve(theBase),
26 myRotAxis(theRevolLoc, theRevolDir)
27{
28}
29
30GeomEvaluator_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)
37{
38}
39
40void GeomEvaluator_SurfaceOfRevolution::D0(
41 const Standard_Real theU, const Standard_Real theV,
42 gp_Pnt& theValue) const
43{
44 if (!myBaseAdaptor.IsNull())
45 myBaseAdaptor->D0(theV, theValue);
46 else
47 myBaseCurve->D0(theV, theValue);
48
49 gp_Trsf aRotation;
50 aRotation.SetRotation(myRotAxis, theU);
51 theValue.Transform(aRotation);
52}
53
54void GeomEvaluator_SurfaceOfRevolution::D1(
55 const Standard_Real theU, const Standard_Real theV,
56 gp_Pnt& theValue, gp_Vec& theD1U, gp_Vec& theD1V) const
57{
58 if (!myBaseAdaptor.IsNull())
59 myBaseAdaptor->D1(theV, theValue, theD1V);
60 else
61 myBaseCurve->D1(theV, theValue, theD1V);
62
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);
70
71 gp_Trsf aRotation;
72 aRotation.SetRotation(myRotAxis, theU);
73 theValue.Transform(aRotation);
74 theD1U.Transform(aRotation);
75 theD1V.Transform(aRotation);
76}
77
78void 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
82{
83 if (!myBaseAdaptor.IsNull())
84 myBaseAdaptor->D2(theV, theValue, theD1V, theD2V);
85 else
86 myBaseCurve->D2(theV, theValue, theD1V, theD2V);
87
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()));
98
99 gp_Trsf aRotation;
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);
107}
108
109void 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
114{
115 if (!myBaseAdaptor.IsNull())
116 myBaseAdaptor->D3(theV, theValue, theD1V, theD2V, theD3V);
117 else
118 myBaseCurve->D3(theV, theValue, theD1V, theD2V, theD3V);
119
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()));
130 theD3U = -theD1U;
131 theD3UUV = gp_Vec(aDir.Dot(theD1V.XYZ()) * aDir - theD1V.XYZ());
132 theD3UVV = gp_Vec(aDir.Crossed(theD2V.XYZ()));
133
134 gp_Trsf aRotation;
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);
146}
147
148gp_Vec GeomEvaluator_SurfaceOfRevolution::DN(
149 const Standard_Real theU, const Standard_Real theV,
150 const Standard_Integer theDerU, const Standard_Integer theDerV) const
151{
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");
156
157 gp_Trsf aRotation;
158 aRotation.SetRotation(myRotAxis, theU);
159
160 gp_Pnt aP;
161 gp_Vec aDV;
162 gp_Vec aResult;
163 if (theDerU == 0)
164 {
165 if (!myBaseAdaptor.IsNull())
166 aResult = myBaseAdaptor->DN(theV, theDerV);
167 else
168 aResult = myBaseCurve->DN(theV, theDerV);
169 }
170 else
171 {
172 if (theDerV == 0)
173 {
174 if (!myBaseAdaptor.IsNull())
175 myBaseAdaptor->D0(theV, aP);
176 else
177 myBaseCurve->D0(theV, aP);
178 aDV = gp_Vec(aP.XYZ() - myRotAxis.Location().XYZ());
179 }
180 else
181 {
182 if (!myBaseAdaptor.IsNull())
183 aDV = myBaseAdaptor->DN(theV, theDerV);
184 else
185 aDV = myBaseCurve->DN(theV, theDerV);
186 }
187
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);
195 else
196 aResult = gp_Vec(aDV.XYZ() - aDir.Dot(aDV.XYZ()) * aDir);
197 }
198
199 aResult.Transform(aRotation);
200 return aResult;
201}
202