HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
GA_NUBBasis.h
Go to the documentation of this file.
1 /*
2  * PROPRIETARY INFORMATION. This software is proprietary to
3  * Side Effects Software Inc., and is not to be reproduced,
4  * transmitted, or disclosed in any way without written permission.
5  *
6  * NAME: GA_NUBBasis.h ( GA Library, C++)
7  *
8  * COMMENTS: Stores an array of knots for a NURBS patch
9  */
10 
11 #pragma once
12 
13 #ifndef __GA_NUBBasis__
14 #define __GA_NUBBasis__
15 
16 #include "GA_API.h"
17 #include "GA_Basis.h"
18 #include "GA_Defines.h"
19 #include "GA_KnotVector.h"
20 
21 #include <UT/UT_VectorTypes.h>
22 #include <SYS/SYS_Types.h>
23 
24 #include <iosfwd>
25 
26 
27 class UT_IStream;
28 
29 template<typename T> class UT_VectorT;
31 
32 
33 /// Knot scale factor for unclamping end interpolating curves/surfaces.
34 #define GA_NUB_UNCLAMP_SCALE 3.0
35 
36 
37 /// @brief NURBS basis classes which maintain knot vectors
38 ///
39 /// The GA_NUBBasis class maintains the knot vectors for NURBS.
40 /// The basis consists of:
41 /// -# The order of the basis (degree+1)
42 /// -# The knot vector (an array of doubles)
43 /// -# A flag for end interpolation
44 class GA_API GA_NUBBasis : public GA_Basis
45 {
46 public:
47  /// The default constructor will choose length/order based on the defaults
48  /// for the basis type.
49  /// default: order=4, length=8
50  GA_NUBBasis(int length=-1, int order=-1, bool end_interpolation=true);
51  GA_NUBBasis(fpreal start, fpreal step, int length, int order=-1, bool end_interpolation=true);
52  // This c-tor allows you to build the equivalent of a Bezier basis.
53  // To end up with a Bezier-like basis, set the multiplicity=ord-1.
54  // The end points will always have 'ord' multiplicity, so this is
55  // an end-interpolating basis. The multiplicity must be >= 1 and < ord.
56  GA_NUBBasis(int bkpoints, int multiplicity, int ord);
57  GA_NUBBasis(const GA_NUBBasis &src);
58 
59  /// Test to see if two bases are equal
60  bool isEqual(const GA_Basis &basis) const override;
61  bool operator==(const GA_NUBBasis &a) const;
62  bool operator!=(const GA_NUBBasis &a) const
63  { return !(*this == a); }
64 
65  /// Re-initializes the basis to default values
66  void reset() override;
67 
68  /// Return the type of the basis
69  GA_BASIS_TYPE getType() const override;
70 
71  /// Return the name of the basis
72  const char *getTypeName() const override;
73 
74  /// Return the dimension of the basis. For NURBS, this will be equivalent
75  /// to (getLength()-getOrder()).
76  int getDimension() const override;
77 
78  /// Return the end-interpolation flag
79  bool getEndInterpolation() const
80  { return myEndInterpolation; }
81 
82  /// Get the boundaries of the valid evaluation interval (as indices)
83  bool getValidInterval(int &a, int &b) const override;
84 
85  /// Return the index of the knot where the valid evaluation begins.
86  /// Typically, for a cubic spline, this index is 3 in the end-point
87  /// interpolating case and 1 otherwise. If u is completely outside
88  /// the valid knot sequence, this method returns -1.
89  ///
90  /// Equivalent to findStartOffset(u, uoffset).
91  int findValidStart(fpreal u, int uoffset = -1) const
92  { return findNURBSValidStart(u, uoffset); }
93 
94  /// Return the index in the knot vector such that knotVec[idx] <= k and
95  /// k < knotVec[idx+1]. If k is less than the first valid knot, return
96  /// -1, and if k is greater than the last valid knot, return the index
97  /// of the last valid knot (i.e. the dimension).
98  int findStart(fpreal k, int start_idx = 0) const
99  { return findNURBSStart(k, start_idx); }
100 
101  /// Evaluate on a specific domain interval, on which at least one
102  /// basis function is non-zero given domain point u.
103  void evalInterval(fpreal u, int offset, int deriv,
104  fpreal64 *vals) const override;
105  void evalInterval(fpreal u, int offset,
106  int deriv, fpreal32 *vals) const override;
107 
108  /// Evaluate all the derivatives of the basis from 0 to deriv (inclusive).
109  void evalDerivativeMatrix(fpreal u, int offset, int deriv,
110  fpreal64 bmatx[][GA_MAXORDER]) const override;
112  int offset, int deriv,
113  fpreal32 bmatx[][GA_MAXORDER]) const override;
114 
115  /// Return the first valid segment. Returns -1 on an error.
116  int findStartOffset(fpreal u, int uoffset) const override;
117 
118  /// Compute one basis function (ie. the one with the given index)
119  /// value at u.
120  fpreal computeBValue(int index, fpreal u) const override;
121 
122  /// Find out if two knot sequences are similar (ie if the knot spacings
123  /// are the same all over) and their knot count is the same.
124  bool isSimilar(const GA_NUBBasis &b) const;
125 
126  /// Return the number of breakpoints (ie. unique knots) in the knot
127  /// vector, in the valid interval.
128  int getBreakCount() const override;
129 
130  /// @{
131  /// Find the index of the last knot in the sequence that defines the given
132  /// breakpoint, or the breakpoint of the domain value. Returns -1 if not
133  /// found.
134  /// @note The search is done within the limits of the valid interval.
135  int findBreakpoint(int idx) const;
136  int findBreakpoint(fpreal t) const;
137  /// @}
138 
139  /// Given the index of a knot (kidx) and two bounds in the knot sequence
140  /// (a and b) find out the index of the breakpoint that the knot represents,
141  /// and possibly adjust kidx so that knot[kidx+1] > knot[kidx]. Return -1
142  /// if not found.
143  int knotToBreakpoint(int &kidx, int a, int b) const override;
144 
145  /// Compute an array of breakpoints (i.e. unique knots) in the valid
146  /// interval and return their number. The tolerance is used to
147  /// differentiate between close knots.
149  fpreal tol=theBasisTolerance) const override;
150 
151  /// Return the multiplicity of a domain point or -1 if outside the domain.
152  /// "uidx" is the index of the largest breakpoint <= u.
153  int getMultiplicity(fpreal u, int &uidx) const override;
154 
155  /// Return the expected multiplicity of the end knots (1 by default):
156  int getEndMultiplicity() const override;
157 
158  /// Change the multiplicity of the knot by inserting it "r" times WITHOUT
159  /// checking its current multiplicity. kidx is the index of a knot t such
160  /// that k >= t.
161  void refine(fpreal k, int kidx, int r, bool wrapped);
162 
163  /// Given a domain range in the valid interval, compute the range of CVs
164  /// that will be involved in the evaluation of the curve in that range.
165  /// Since the basis doesn't know about wrapping, the endcv index might
166  /// be higher than the spline's number of CVs.
167  void getCvRangeOfDomain(int ustartidx, int ustopidx,
168  int &start_cv, int &end_cv) const override;
169  void getCvRangeOfDomain(fpreal ustart, fpreal ustop,
170  int &start_cv, int &end_cv) const override;
171 
172  /// Given valid breakpoint index, compute the range of CVs that have a
173  /// non-zero influence at the knot of the breakpoint. Since the basis
174  /// doesn't know about wrapping, the endcv index might be higher than the
175  /// spline's number of CVs.
176  void getCvRangeOfBreakpoint(int bkp,
177  int &startcv, int &stopcv) const override;
178 
179  /// I/O functions for houdini9 format
180  bool saveH9(std::ostream &os, bool wrapped,
181  bool binary) const override;
182  bool loadH9(UT_IStream &is, int cvs, bool wrapped) override;
183 
184  /// Transitional method while we might need to import data from a GB_Basis.
185  /// Be careful calling this method as the order must be appropriate for the
186  /// number of knots.
187  /// TODO: Remove when no longer necessary.
188  bool import(int order, const UT_FloatArray &knots,
189  bool end_interpolation=true);
190 
191  /// Copy my data from the given source. If performing a compatible copy, we
192  /// only do the copy if if b has the same order and length as we do.
193  bool copyFrom(const GA_Basis &b, bool compatible=false) override;
194 
195  /// The validate() method will force the basis to be valid (if possible).
196  /// The adapt enum can be used to control the behaviour of this method.
197  bool validate(int adapt=GA_Basis::GA_BASIS_ADAPT_NONE) override;
198 
199  /// The checkValid() methods test to see whether th basis is valid given
200  /// a curve with
201  /// -# cvLen vertices
202  /// -# A basis length of bLen
203  /// -# Periodicity determined by doesWrap
204  bool checkValid(int cvLen, int bLen, bool doesWrap) const override;
205 
206  /// Compute the idx'th greville abscissa of the domain vector. Clamping
207  /// to the valid interval is optional and might not make any difference
208  /// for some spline types.
209  fpreal getGreville(int idx, bool clamp=true,
210  bool wrap=false) const override;
211 
212  /// Grow the length of the basis by one, and set the value of the new entry
213  /// to last knot+1. The method returns the index of the appended element.
214  int grow(bool wrapped=false) override;
215 
216  /// Shrink the basis by one. The basis should not shrink beyond a valid
217  /// length. Return the new length.
218  int shrink(bool wrapped=false) override;
219 
220  /// Insert a new knot as a result of a CV insertion at index cvIdx. The
221  /// knot index is cvIdx + 1, which is returned by growAt() if all goes OK.
222  /// -1 is returned upon failure.
223  /// (NURBS basis only)
224  int growAt(unsigned cvIdx, bool wrapped);
225 
226  /// Delete a knot as a result of a CV removal at index cvIdx. The knot
227  /// index is cvIdx + 1. The method returns the new length if successful,
228  /// and -1 otherwise.
229  int shrinkAt(unsigned cvIdx, bool wrapped);
230 
231  /// Attach another basis to us and grow our basis as a result. The bases
232  /// must have the same type and order.
233  /// If "overlap" is true, we overlap the beginning of b with
234  /// our end.
235  /// Spreading makes sense when you can have multiple knots in the basis, and
236  /// causes identical knots to be spread within range of the neighbouring
237  /// knots.
238  bool attach(const GA_Basis &b, bool overlap=true,
239  bool spread=false) override;
240 
241  /// Change the size of the basis (and maybe some of its values too) to
242  /// make it a valid basis for wrapped splines.
243  void setWrapping(bool wrap) override;
244 
245  /// Change end interpolation
246  void setEndInterpolation(bool value, bool modify_knots);
247 
248  /// Reverse the breakpoints in the basis.
249  void reverse(bool wrapped) override;
250 
251  /// Find index in the knot vector for the break point corresponding to k.
252  int findOffset(fpreal k, int startIdx=0) const override;
253 
254  /// Create a new basis containing the partial merging of bases a and b
255  /// If their order is different return -1. Otherwise return 0.
256  /// The resultant basis contains knots a0..a1 of basis a merged with
257  /// knots b0..b1 from basis b (after being mapped onto a0..a1)
258  /// If the aknot or bknot array is given, they are set with the
259  /// (appropriately mapped) knots values corresponding to the new insertions
260  bool mergePartial(const GA_NUBBasis &a, const GA_NUBBasis &b,
261  int a0, int a1, int b0, int b1,
262  GA_KnotVector *aknots = 0,
263  GA_KnotVector *bknots = 0);
264 
265  /// Rebuild the basis as a uniform sequence with a given step.
266  void rebuild(fpreal ustart=0, fpreal ustep=1) override;
267 
268  /// Make the basis uniform of just find out if it is uniform:
269  void makeUniform(fpreal ustep=1) override;
270 
271  /// Reparameterize the basis using the chord-length method, and clamp it
272  /// to the valid interval. The origin and length of the valid domain remains
273  /// unchanged.
274  void chord(UT_Vector4Array &cvs) override;
275 
276  /// Slide the knots found in the given range left or right by an amount at
277  /// most as large as the distance to the nearest knot outside the range.
278  /// The bias is a percentage value of the left-right distance, its default
279  /// value is 0.5 (i.e. don't change anything), and is clamped to [0,1].
280  bool slideRange(fpreal umin, fpreal umax,
281  fpreal ubias=0.5) override;
282 
283  /// Cycle the knots, optionally keeping the original span length and origin.
284  bool cycle(int amount, bool keepSpan);
285 
286  /// @{
287  /// Set up the knot vector with the given parameterization for the
288  /// approximiation.
289  void setKnotsByEqualSpacing(UT_Vector &param, bool wrapped=false);
290  void setKnotsByAveraging(UT_Vector &param, bool wrapped=false);
291  void setKnotsBySpreading(UT_Vector &param);
292  void setKnotsByBreakpoints(UT_Vector &param);
293  /// @}
294 
295  /// TODO: Public for GD_PrimNURBCurve use
296 
298  { setEndInterpolation(!myEndInterpolation, true); }
299  void makeNURBSPeriodic();
300 
301  // TODO: Public for IGES_EntityBSplineSurface use
302  void updateEndInterpolation();
303 
304  /// Return the amount of memory used
305  int64 getMemoryUsage(bool inclusive) const override
306  {
307  int64 mem = inclusive ? sizeof(*this) : 0;
308  mem += GA_Basis::getMemoryUsage(false);
309  return mem;
310  }
311 
312  /// Test whether the basis is a uniform basis.
313  bool isUniform() const;
314 
315 private:
316  void initialize(fpreal start, fpreal step,
317  int length, int order, bool interp);
318 
319  int findNURBSStart(fpreal k, int start=0) const;
320  int findNURBSValidStart(fpreal u, int off=-1) const;
321  void initializeNURBS(fpreal first, fpreal step);
322  void spreadNURBSKnots(int ai, int bi);
323 
324  // NUB basis interpolation end condition
325  bool myEndInterpolation;
326 };
327 
328 #endif
virtual int shrink(bool wrapped=false)=0
GLenum src
Definition: glew.h:2410
UT_VectorT< fpreal64 > UT_Vector
Definition: GA_NUBBasis.h:29
virtual void makeUniform(fpreal ustep=1)=0
Make the basis uniform of just find out if it is uniform:
virtual fpreal getGreville(int idx, bool clamp=true, bool wrap=false) const =0
int64 getMemoryUsage(bool inclusive) const override
Return the amount of memory used.
Definition: GA_NUBBasis.h:305
virtual int getMultiplicity(fpreal u, int &uidx) const =0
GLuint index
Definition: glew.h:1814
virtual int findOffset(fpreal k, int startIdx=0) const =0
Find index in the knot vector for the break point corresponding to k.
GLboolean GLboolean GLboolean GLboolean a
Definition: glew.h:9477
virtual int getBreakpoints(GA_KnotVector &a, fpreal tol=theBasisTolerance) const =0
const GLint * first
Definition: glew.h:1528
#define GA_MAXORDER
Definition: GA_Defines.h:17
virtual void evalInterval(fpreal u, int offset, int deriv, fpreal64 *vals) const =0
virtual fpreal computeBValue(int index, fpreal u) const =0
#define GA_API
Definition: GA_API.h:12
virtual bool slideRange(fpreal umin, fpreal umax, fpreal ubias=0.5)=0
float fpreal32
Definition: SYS_Types.h:200
GLfloat param
Definition: glew.h:1530
virtual int findStartOffset(fpreal u, int uoffset) const =0
virtual int getBreakCount() const =0
GLuint GLdouble GLdouble GLint GLint order
Definition: glew.h:3446
virtual void reset()=0
Re-initializes the basis to default values.
bool operator!=(const GA_NUBBasis &a) const
Definition: GA_NUBBasis.h:62
double fpreal64
Definition: SYS_Types.h:201
GLuint interp
Definition: glew.h:8277
virtual bool copyFrom(const GA_Basis &b, bool compatible=false)
virtual int grow(bool wrapped=false)=0
bool operator==(const BaseDimensions< T > &a, const BaseDimensions< Y > &b)
Definition: Dimensions.h:137
virtual bool checkValid(int cvLen, int bLen, bool doesWrap) const =0
virtual int knotToBreakpoint(int &kidx, int a, int b) const =0
GLenum clamp
Definition: glew.h:2166
const GLuint GLenum const void * binary
Definition: glew.h:3502
virtual GA_BASIS_TYPE getType() const =0
Return the type of the basis.
GLuint GLsizei GLsizei * length
Definition: glew.h:1825
Bezier or NURBS basis classes which maintain knot vectors.
Definition: GA_Basis.h:49
NURBS basis classes which maintain knot vectors.
Definition: GA_NUBBasis.h:44
long long int64
Definition: SYS_Types.h:116
virtual int64 getMemoryUsage(bool inclusive) const
Return the amount of memory used.
Definition: GA_Basis.h:379
virtual void setWrapping(bool wrap)=0
virtual int getDimension() const =0
virtual void rebuild(fpreal ustart=0, fpreal ustep=1)=0
Rebuild the basis as a uniform sequence with a given step.
OPENVDB_API void initialize()
Global registration of basic types.
Definition: logging.h:291
virtual bool validate(int adapt=GA_Basis::GA_BASIS_ADAPT_NONE)=0
virtual void chord(UT_Vector4Array &cvs)=0
GLuint start
Definition: glew.h:1253
virtual bool attach(const GA_Basis &b, bool overlap=true, bool spread=false)=0
GLdouble GLdouble GLdouble b
Definition: glew.h:9122
virtual bool loadH9(UT_IStream &is, int cvs, bool wrapped)=0
fpreal64 fpreal
Definition: SYS_Types.h:277
GA_BASIS_TYPE
Definition: GA_Basis.h:33
GLdouble GLdouble GLdouble r
Definition: glew.h:1406
void toggleEndInterpolation()
TODO: Public for GD_PrimNURBCurve use.
Definition: GA_NUBBasis.h:297
virtual bool saveH9(std::ostream &os, bool wrapped, bool binary) const =0
I/O functions for houdini9 format.
int findStart(fpreal k, int start_idx=0) const
Definition: GA_NUBBasis.h:98
virtual const char * getTypeName() const =0
Return the name of the basis.
virtual void reverse(bool wrapped)=0
Reverse the breakpoints in the basis.
bool getEndInterpolation() const
Return the end-interpolation flag.
Definition: GA_NUBBasis.h:79
GLsizei const GLfloat * value
Definition: glew.h:1849
GLdouble GLdouble t
Definition: glew.h:1398
virtual int getEndMultiplicity() const
Return the expected multiplicity of the end knots (1 by default):
virtual void getCvRangeOfDomain(int ustartidx, int ustopidx, int &start_cv, int &end_cv) const =0
virtual void getCvRangeOfBreakpoint(int bkp, int &startcv, int &stopcv) const =0
virtual bool getValidInterval(int &a, int &b) const =0
Get the boundaries of the valid evaluation interval (as indices)
virtual void evalDerivativeMatrix(fpreal u, int offset, int deriv, fpreal64 bmatx[][GA_MAXORDER]) const =0
Evaluate all the derivatives of the basis from 0 to deriv (inclusive).
virtual bool isEqual(const GA_Basis &basis) const =0
Compare to see whether the basis is equal.
GLintptr offset
Definition: glew.h:1682
int findValidStart(fpreal u, int uoffset=-1) const
Definition: GA_NUBBasis.h:91