1/****************************************************************************************
2
3 Copyright (C) 2015 Autodesk, Inc.
4 All rights reserved.
5
6 Use of this software is subject to the terms of the Autodesk license agreement
7 provided at the time of installation or download, or which otherwise accompanies
8 this software in either electronic or hard copy form.
9
10****************************************************************************************/
11
12//! \file fbxnurbscurve.h
13#ifndef _FBXSDK_SCENE_GEOMETRY_NURBS_CURVE_H_
14#define _FBXSDK_SCENE_GEOMETRY_NURBS_CURVE_H_
15
16#include <fbxsdk/fbxsdk_def.h>
17
18#include <fbxsdk/scene/geometry/fbxgeometry.h>
19#include <fbxsdk/scene/geometry/fbxline.h>
20
21#include <fbxsdk/fbxsdk_nsbegin.h>
22
23/**
24 A Non-Uniform Rational B-Spline (NURBS) curve is a type of parametric geometry. A NURBS
25 curve is defined by the order, form, knot vector and control points.
26
27 Let M be the order of the curve.
28 Let N be the number of control points of the curve.
29
30 The form of the curve can be open, closed or periodic. A curve with end points
31 that do not meet is defined as an open curve. The number of knots in an open curve
32 is defined as N+(M+1).
33
34 A closed curve simply has its last control point equal to its first control point.
35 Note that this does not imply tangent continuity at the end point. The curve may
36 have a kink at this point. In FBX the last control point is not specified by the user
37 in the InitControlPoints() method. For example, if there are to be 10 control points in
38 total, and the curve is to be closed, than only 9 control points need to be passed
39 into the InitControlPoints() method. The last control point is implied to be equal
40 to the first control point. Thus N represents the number of unique CVs.
41
42 A periodic curve has its last M control points equal to its first M control points.
43 A periodic curve is tangent continuous at the ends. Similar to a closed curve,
44 when creating a periodic curve, only the unique control points need to be set. For
45 example a periodic curve of order 3 with 10 control points requires only 7 CVs to
46 be specified in the InitControlPoints() method. The last 3 CVs, which are the same as
47 the first 3, are not included.
48
49 The calculation of the number of knots in closed and periodic curves is more complex.
50 Since we have excluded one CV in N in a closed curve, the number of knots is N+(M+1)+1.
51 Similarly, we excluded M CVs in periodic curves so the number of knots is N+(M+1)+M.
52
53 Note that FBX stores one extra knot at the beginning and and end of the knot vector,
54 compared to some other graphics applications such as Maya. The two knots are not
55 used in calculation, but they are included so that no data is lost when converting
56 from file formats that do store the extra knots.
57
58 * \nosubgrouping
59 */
60class FBXSDK_DLL FbxNurbsCurve : public FbxGeometry
61{
62 FBXSDK_OBJECT_DECLARE(FbxNurbsCurve,FbxGeometry);
63
64public:
65 //! Returns the EType::eNurbsCurve node attribute type.
66 virtual FbxNodeAttribute::EType GetAttributeType() const;
67
68 /** \enum EDimension The dimension of the CVs.
69 * - \e e2D The CVs are two dimensional points.
70 * - \e e3D The CVs are three dimensional points.
71 */
72 enum EDimension
73 {
74 e2D = 2,
75 e3D
76 };
77
78 /** \enum EType The curve's form.
79 * - \e eOpen
80 * - \e eClosed
81 * - \e ePeriodic
82 */
83 enum EType
84 {
85 eOpen,
86 eClosed,
87 ePeriodic
88 };
89
90 /** Allocates memory space for the control points array as well as for the knot
91 * vector.
92 * \param pCount Number of control points.
93 * \param pVType NURBS type.
94 * \remarks This function should always be called after FbxNurbsCurve::SetOrder().
95 */
96 void InitControlPoints( int pCount, EType pVType );
97
98 /** Returns the knot vector.
99 * \return Pointer to the knots array.
100 */
101 inline double* GetKnotVector() const { return mKnotVector; }
102
103 /** Returns the number of elements in the knot vector.
104 * \return The number of knots.
105 */
106 int GetKnotCount() const;
107
108 /** Sets the order of the curve.
109 * \param pOrder The curve order.
110 * \remarks The curve order must be set before InitControlPoints() is called.
111 */
112 inline void SetOrder( int pOrder ) { mOrder = pOrder; }
113
114 /** Returns the NURBS curve order.
115 * \return The NURBS curve order.
116 */
117 inline int GetOrder() const { return mOrder; }
118
119 /** Sets the step of the curve.
120 * \param pStep The curve step.
121 * \remarks To tessellate curve, it denotes the evaluation frequency between two neighbor knots.
122 */
123 inline void SetStep( int pStep ) { mStep = pStep; }
124
125 /** Returns the NURBS curve step.
126 * \return The NURBS curve step.
127 * \remarks To tessellate curve, it denotes the evaluation frequency between two neighbor knots.
128 */
129 inline int GetStep() const { return mStep; }
130
131 /** Sets the dimension of the CVs.
132 * For 3D curves: control point = ( x, y, z, w ), where w is the weight.
133 * For 2D curves: control point = ( x, y, 0, w ), where the z component is unused, and w is the weight.
134 * \param pDimension The control points dimension(3D or 2D).
135 */
136 inline void SetDimension( EDimension pDimension ) { mDimension = pDimension; }
137
138 /** Returns the control points dimension.
139 * \return The curve dimension.
140 */
141 inline EDimension GetDimension() const { return mDimension; }
142
143 /** Determines if the curve is rational or not.
144 * \return \c True if the curve is rational, return \c false if not.
145 */
146 bool IsRational();
147
148 /** Calculates the number of curve spans with the following:
149 * Where
150 * S = Number of spans
151 * N = Number of CVs
152 * M = Order of the curve
153 *
154 * S = N - M + 1;
155 *
156 * In this calculation N includes the duplicate CVs for closed and periodic curves.
157 *
158 * \return The number of curve spans if the curve has been initialized, returns -1 if the curve has not been initialized.
159 */
160 int GetSpanCount() const;
161
162 /** Returns NURBS type.
163 * \return NURBS type identifier.
164 */
165 inline EType GetType() const { return mNurbsType; }
166
167 /** Checks if the curve is a poly line. (A poly line is a
168 * linear NURBS curve )
169 *
170 * \return \c True if curve is a poly line, return \c false if it is not a poly line.
171 */
172 inline bool IsPolyline() const { return ( GetOrder() == 2 ); }
173
174 /** This function determines if this NURBS curve is a Bezier curve.
175 * Bezier curves are a special case of NURBS curve.
176 * \return \c True if curve is a Bezier curve. If it is not a Bezier curve return \c false.
177 */
178 bool IsBezier() const;
179
180 /** Evaluate the point on the curve. Save the result as a point array. Meanwhile, return the length of the point array.
181 * \param pPointArray Save the evaluate result as a point array.
182 * \param pStep The evaluation frequency between two neighbor knots. Its default value is 16, which is same as Maya.
183 * \return The length of the point array.
184 */
185 int TessellateCurve(FbxArray<FbxVector4>& pPointArray, int pStep = 16);
186
187 /** Evaluate the point on the curve. Per the evaluation result, create a FbxLine and return the pointer to the line.
188 * \param pStep The evaluation frequency between two neighbor knots. Its default value is 16, which is same as Maya.
189 * \return A line to hold the tessellate points.
190 */
191 FbxLine* TessellateCurve(int pStep = 16);
192
193/*****************************************************************************************************************************
194** WARNING! Anything beyond these lines is for internal use, may not be documented and is subject to change without notice! **
195*****************************************************************************************************************************/
196#ifndef DOXYGEN_SHOULD_SKIP_THIS
197 virtual FbxObject& Copy(const FbxObject& pObject);
198
199 bool FullMultiplicity() const;
200
201 // Error identifiers, these are only used internally.
202 enum EErrorCode
203 {
204 eNurbsCurveTypeUnknown,
205 eWeightTooSmall,
206 eKnotVectorError,
207 eWrongNumberOfControlPoint,
208 eErrorCount
209 };
210
211 bool mIsRational;
212
213 virtual void SetControlPointAt(const FbxVector4 &pCtrlPoint , int pIndex) { ParentClass::SetControlPointAt(pCtrlPoint, pIndex); }
214 virtual void InitControlPoints(int pCount) { ParentClass::InitControlPoints(pCount); }
215
216protected:
217 virtual void Construct(const FbxObject* pFrom);
218 virtual void Destruct(bool pRecursive);
219
220 void Reset();
221
222private:
223 double* mKnotVector;
224 EType mNurbsType;
225 int mOrder;
226 EDimension mDimension;
227 int mStep;
228#endif /* !DOXYGEN_SHOULD_SKIP_THIS *****************************************************************************************/
229};
230
231#include <fbxsdk/fbxsdk_nsend.h>
232
233#endif /* _FBXSDK_SCENE_GEOMETRY_NURBS_CURVE_H_ */
234