HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
GEO_PrimNURBSurf.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: Geometry Library (C++)
7  *
8  * COMMENTS:
9  * This class implements a non-uniform B-Spline surface defined by
10  * a set of knots, basis functions, and CVs.
11  *
12  */
13 
14 #ifndef __GEO_PrimNURBSurf_h__
15 #define __GEO_PrimNURBSurf_h__
16 
17 #include "GEO_API.h"
18 #include "GEO_TPSurf.h"
19 #include "GEO_PrimType.h"
20 
21 class GA_Detail;
22 class GA_NUBBasis;
23 
25 {
26 protected:
27  /// NOTE: The constructor should only be called from subclass
28  /// constructors.
30  : GEO_TPSurf(d, offset)
31  {}
32 
33  /// NOTE: The destructor should only be called from subclass
34  /// destructors.
35  /// Please read the comments on the parent class destructor.
36  ~GEO_PrimNURBSurf() override {}
37 
38 public:
39  // Given a domain value (u,v), store all the basis derivatives
40  // (from 0 to du and from 0 to dv inclusive) into ubmatx and vbmatx
41  // respectively. Return the min indices of the CVs needed
42  // for the linear combination. The indices may exceed the number of
43  // vertices if the surface is wrapped, so remember to use modulus (%).
45  float u, float v,
46  float ubmatx[][GA_MAXORDER],
47  float vbmatx[][GA_MAXORDER],
48  int &rowoffset, int &coloffset,
49  unsigned du=0, unsigned dv=0,
50  int uoffset=-1, int voffset=-1) const override;
51 
52  // Evaluate the basis at the given point in the domain and also return
53  // the index of the first CV to linearly combine the basis with. The CV
54  // indices may exceed the number of vertices if the surface is wrapped,
55  // so remember to use modulus (%).
56  int evaluateBasis(
57  float u, float v,
58  float *ubvals, float *vbvals,
59  int &rowoffset, int &coloffset,
60  unsigned du=0, unsigned dv=0,
61  int uoffset=-1, int voffset=-1) const override;
62  int evaluateUBasis(
63  float u, float *ubvals, int &coloffset,
64  unsigned du=0, int uoffset=-1) const override;
65  int evaluateVBasis(
66  float v, float *vbvals, int &rowoffset,
67  unsigned dv=0, int voffset=-1) const override;
68 
69  // Compute the location of the breakpoint. Return 0 if OK, else -1.
70  int evaluateBreakpoint(int uidx, int vidx,
71  UT_Vector4 &pos,
72  int du=0, int dv=0) const override;
73 
74  // Given a CV index figure out the min/max indicies of the knots between
75  // which the curve needs to be re-evaluated if the CV changes. If not
76  // given a valid CV index, the method returns -1. Otherwise it returns 0.
77  int domainRangeOfCV(int i, int j, int &minuk,int &maxuk,
78  int &minvk,int &maxvk) const override;
79 
80  // Given a CV index figure out the min/max breakpoints which are
81  // affected if the CV changes. If not given a valid CV index, the
82  // method returns -1. Otherwise it returns 0. Also returns -1 if
83  // no breakpoints are affected.
84  // NOTE: use % breakCount since maxbkp may be >= breakCount
85  int breakpointRangeOfCV(int i, int j, int &minbkpu,
86  int &maxbkpu, int &minbkpv,
87  int &maxbkpv) const override;
88 
89  // Reparameterize the surface by changing its basis. All the knots up to
90  // and including the first valid knot remain unchanged. This type of
91  // reparameterization is generally NOT shape preserving:
92  void reparameterizeU(GA_ParameterizationType ptype) override;
93  void reparameterizeV(GA_ParameterizationType ptype) override;
94 
95  // Change the multiplicity of the knot by inserting it "r" times after
96  // checking its current multiplicity. The maximum valid r for a knot is
97  // equal to the degree of the basis (ie order-1). Return -1 if k is outside
98  // the valid interval or greater than the number of CVs. Otherwise, return
99  // the index of the inserted knot.
100 
101  int refineU(float k, GA_AttributeRefMap &hl,
102  int r=1) override;
103  int refineU(float k, int r=1) override;
104 
105  int refineV(float k, GA_AttributeRefMap &hl,
106  int r=1) override;
107  int refineV(float k, int r=1) override;
108 
109  // To gain access to the GEO_AttributeHandleList versions of refine()
110  using GEO_Hull::refineU;
111  using GEO_Hull::refineV;
112  // Warp the nurb at u,v by the given delta. Change 1 or 4 Cvs and possibly
113  // insert a knot once or more as well. If a knot is inserted or we happen
114  // to land exactly on a knot, we change only one CV. The bias makes sense
115  // only when changing 4 CVs, and will be ignored altogether if < 0.
116  // We return the CV index in warpU/V and 0 in warp() if OK; -1 otherwise.
117  int warpU(float u, const UT_Vector3 &delta,
118  GA_AttributeRefMap &map,
119  float sharpness = 0.0f,
120  float bias = -1.0f) override;
121  int warpV(float v, const UT_Vector3 &delta,
122  GA_AttributeRefMap &map,
123  float sharpness = 0.0f,
124  float bias = -1.0f) override;
125  int warp(float u, float v, const UT_Vector3 &delta,
126  GA_AttributeRefMap &map,
127  float usharpness = 0.f, float vsharpness = 0.f,
128  float ubias = -1.0f, float vbias = -1.0f) override;
129 
130  // Set the wrap or open flag, and make sure the basis knot vectors are
131  // consistent with the change. These functions are virtual by inheritance.
132  void wrapU(int rounded = 1, int preserveShape = 0) override;
133  void openU(int preserveShape = 0, int = 0) override;
134  void wrapV(int rounded = 1, int preserveShape = 0) override;
135  void openV(int preserveShape = 0, int = 0) override;
136 
137  int unrollU(int append_pts = 1) override;
138  int unrollV(int append_pts = 1) override;
139 
140  // Check if the basis interpolates the endpoints, or change the flag.
141  bool interpolatesEndsU() const;
142  void toggleEndConditionU();
143  bool interpolatesEndsV() const;
144  void toggleEndConditionV();
145 
146  // Insert or remove rows and columns. The insertion returns the index if
147  // successful. The deletion methods return 0 if ok. If failure, return -1.
148  int insertRow(unsigned int beforeWhich,
149  bool appendPts=true) override;
150  int insertCol(unsigned int beforeWhich,
151  bool appendPts=true) override;
152  int deleteRow(unsigned int which) override;
153  int deleteCol(unsigned int which) override;
154 
155  // If the surface is wrapped in U and/or V, explicitly add the wrapped
156  // vertex (or vertices) and open the surface in the direction(s)
157  // it's wrapped in.
158  void fixSeamsU() override;
159  void fixSeamsV() override;
160 
161  // Find the valid min and max u and v indices of the bases:
162  int uMinValidIndex() const override;
163  int uMaxValidIndex() const override;
164  int vMinValidIndex() const override;
165  int vMaxValidIndex() const override;
166 
167  // Raise the number of CVs to match the newcount. The shape of the curve
168  // (especially if parametric) should NOT change. Return 0 upon success
169  // and -1 otherwise. start and stop define which indices to examine
170  // if newcount is negative it is taken as a relative value.
171  int loftU(int newcount, int start=-1, int stop=-1) override;
172  int loftV(int newcount, int start=-1, int stop=-1) override;
173 
174  // Merge a bunch of NURB surfaces together. The surfaces are assumed to
175  // be all NURBS, all of the same order and characteristics such as
176  // non/end-interp, open/wrapped.
177  static int mergeGroupU(GEO_Detail *gdp, GA_PrimitiveGroup *nurbs);
178  static int mergeGroupV(GEO_Detail *gdp, GA_PrimitiveGroup *nurbs);
179 
180  // Shift the array of vertices by an offset and wrap around.
181  // Cycle a subrange if the curve is closed and cycle the basis
182  // accordingly. The offset can be either negative or positive.
183  // Optionally remap the new basis to the original length and origin
184  int cycleU(int amount, int keepSpan = 1) override;
185  int cycleV(int amount, int keepSpan = 1) override;
186 
187  // Remove the interior knot at kidx once in udir if possible, where mult is
188  // the multiplicity of the knot, and U/V[kidx] != U/V[kidx+1].
189  // If multiplicity mult is not given, the procedure will compute it.
190  // The tol specifies the tolerance of distance between the knot removable
191  // position and its actual position. To force knot removal, set tol = -1.0F.
192  // The deletegroup is used to gather unused cv geo points to be deleted.
193  // (It is more efficient to delete points in a group.)
194  // Output: 1 if the knot got removed, else 0.
195  // Note: During the process of knot removal, interior cvs geo points
196  // may changed and/or deleted.
197  int unrefine(int udir, int kidx,
198  GA_AttributeRefMap &hlist,
199  int mult=0, float tol=1e-4F,
200  GA_PointGroup *delgroup=0);
201  int unrefine (int udir, int kidx, int mult=0,
202  float tol=1e-4F,GA_PointGroup *delgroup=0);
203 
204  // Get error bound for removing of a knot once.
205  float getKnotRemovalBound(int uDir, int curveIdx,
206  int knotIdx, int mult=0) const;
207 
208  // If this surface is open and non-end-interpolating, insert knots such that
209  // it becomes end-interpolating without changing its shape. Return 0 if
210  // successful and -1 othewise.
211  // If the delPoints group is passed in, the points to be deleted will be
212  // added to the group. Otherwise, the points will be deleted from the gdp.
213  int clampU(GA_PointGroup *delPoints = 0);
214  int clampV(GA_PointGroup *delPoints = 0);
215  void unclampU();
216  void unclampV();
217 
218  bool isClampedU() const override;
219  bool isClampedV() const override;
220 
221  // Translate the CVs such that the given breakpoint change positions by
222  // the given delta. Return -1 if something goes wrong, 0 if translation
223  // was successful.
224  // NOTE: Cannot contain any duplicates. If the surface is wrapped,
225  // the first and last breakpoint are considered the same.
226  int translateBreakpoints(const UT_IntArray &uindices,
227  const UT_IntArray &vindices,
228  const UT_Vector3 &delta,
229  int fixbkpts = 1,
230  GA_PointGroup *ptgroup=NULL,
231  GEO_Delta *geodelta = 0) override;
232 
233  int transformBreakpoints(const UT_IntArray &uindices,
234  const UT_IntArray &vindices,
235  const UT_Matrix4 &matx,
236  int fixbkpts = 1,
237  GA_PointGroup *ptgroup=NULL,
238  GEO_Delta *geodelta = 0) override;
239 
240  // Append another hull to us in one of two ways: blend the two endpoints
241  // or connect them straight or rounded. The bias ranges from 0 to 1 and is
242  // relevant only to blending. The tolerance for blending: if 0, the two
243  // endpoints will merge into one point with a discontinuity; if less than
244  // 1, we insert knots into the hulls to minimize the affected areas; if 1,
245  // no refinement is done. For the non-blend case, the tolerance will
246  // generate a span whose shape goes from round to straight; 0 tolerance
247  // means straight connection. If unrefine is on, we'll try to reduce the
248  // complexity of the hull if we're connecting rounded. We return 0 if OK
249  // and -1 if error. Both hulls must be open and have the same order.
250  int attachU(const GEO_Hull &hull, int blend = 1,
251  float bias = 0.5f, float tolerance = 1.0f,
252  int unrefine = 1,
253  GA_PointGroup *ptgroup=0) override;
254  int attachV(const GEO_Hull &hull, int blend = 1,
255  float bias = 0.5f, float tolerance = 1.0f,
256  int unrefine = 1,
257  GA_PointGroup *ptgroup=0) override;
258 
259  // If [ustart,ustop] and [vstart,vstop] are in the valid interval, return
260  // the part of the surface delimited by those values in a new primitive.
261  // Return 0 if a problem is encountered.
262  GEO_TPSurf *extract(float ustart, float ustop,
263  float vstart, float vstop) const override;
264 
265  // Reverse the roles of rows and columns
266  void transpose() override;
267 
268  const GA_PrimitiveJSON *getJSON() const override;
269 
270 protected:
272  { return GEO_TPSurf::buildFamilyMask(); }
273 
274  /// All subclasses should call this method to register the curve intrinsics.
275  /// @see GA_IntrinsicManager
278  { return GEO_TPSurf::registerIntrinsics(defn); }
279 
280  // Get a new basis of a type that matches our type:
281  GA_Basis *newBasis() const override;
282 
283  // Reverse rows (V) or columns (U). Reversing in either direction will
284  // flip the normal.
285  void reverseU() override;
286  void reverseV() override;
287 
288 
289  // Parameter correction by Newton iteration.
290  void correctParam(const UT_Vector4 &p,
291  float &u, float &v,
292  float distTol=1e-10F, float angTol=1e-2F,
293  int maxIter=50) const;
294 
295  // Protected methods to translate/transform selected breakpoints and
296  // perform an interpolation.
297  virtual int translateBkptsFixed(const UT_IntArray &uindices,
298  const UT_IntArray &vindices,
299  const UT_Vector3 &delta,
300  GA_PointGroup *ptgroup=NULL,
301  GEO_Delta *geodelta = 0);
302  virtual int transformBkptsFixed(const UT_IntArray &uindices,
303  const UT_IntArray &vindices,
304  const UT_Matrix4 &matx,
305  GA_PointGroup *ptgroup=NULL,
306  GEO_Delta *geodelta = 0);
307 
308  // Methods to translate/transform selected breakpoints which do not
309  // perform an interpolation.
310  virtual int translateBkptsNonFixed(const UT_IntArray &uindices,
311  const UT_IntArray &vindices,
312  const UT_Vector3 &delta,
313  GA_PointGroup *ptgroup=NULL,
314  GEO_Delta *geodelta = 0);
315  virtual int transformBkptsNonFixed(const UT_IntArray &uindices,
316  const UT_IntArray &vindices,
317  const UT_Matrix4 &matx,
318  GA_PointGroup *ptgroup=NULL,
319  GEO_Delta *geodelta = 0);
320 
321  // Given a parameter in the domain, insert as many CVs as necessary to
322  // create a discontinuity at the corresponding point on the curve.The shape
323  // of the curve should NOT change. Return u's index upon success and -1
324  // otherwise.
325  int subdivideURefMap(float u,
326  GA_AttributeRefMap &map) override;
327  int subdivideUFloat(float u) override;
328 
329  int subdivideVRefMap(float u,
330  GA_AttributeRefMap &map) override;
331  int subdivideVFloat(float u) override;
332 
333  int unrefineURefMap(int kidx,
334  GA_AttributeRefMap &hlist,
335  int mult=0, float tol=1e-4F,
336  GA_PointGroup *delgroup=0) override;
337  int unrefineUFloat(int kidx, int mult=0, float tol=1e-4F,
338  GA_PointGroup *delgroup=0) override;
339 
340  int unrefineVRefMap(int kidx,
341  GA_AttributeRefMap &hlist,
342  int mult=0, float tol=1e-4F,
343  GA_PointGroup *delgroup=0) override;
344  int unrefineVFloat(int kidx, int mult=0, float tol=1e-4F,
345  GA_PointGroup *delgroup=0) override;
346 
347  // Increase the order. Return 0 if successful, -1 otherwise (eg.
348  // order cannot be increased because it's >= MAXORDER).
349  int raiseOrderURefMap(int neworder,
350  GA_AttributeRefMap &h) override;
351  int raiseOrderUInt(int neworder) override;
352  int raiseOrderVRefMap(int neworder,
353  GA_AttributeRefMap &h) override;
354  int raiseOrderVInt(int neworder) override;
355 
356 private:
357  int xformBreakpoints(const UT_IntArray &uindices,
358  const UT_IntArray &vindices,
359  const UT_Vector3Array &trans,
360  GA_PointGroup *ptgroup=NULL,
361  GEO_Delta *geodelta = 0);
362 
363  // Merge the given basis into ours and refine the surface accordingly.
364  // It is assumed that both bases have the same order and that "basis"
365  // contains all our knots plus possibly others. Also, it is assumed that
366  // "basis" has been GA_Basis::map()-ed onto our knot interval. The
367  // method returns 0 if OK and -1 if problems.
368  // Finally, it is assumed that the basis has no knots of higher
369  // multiplicity than degree. This is not checked for here, so one
370  // must ensure the resulting basis is of proper length.
371  int mergeU(const GA_NUBBasis &basis);
372  int mergeV(const GA_NUBBasis &basis);
373 
374  // Return the multiplicity of knot k, cycling the curve first and/or
375  // unsharing the wrapped points if necessary.
376 
377  int alignKnotU(float k, int &kidx,
378  int &cycFix, int &interpFix);
379  int alignKnotV(float k, int &kidx,
380  int &cycFix, int &interpFix);
381 
382  void unAlignKnotU(int &kidx, int cycFix, int interpFix);
383  void unAlignKnotV(int &kidx, int cycFix, int interpFix);
384 
385 };
386 
387 #endif
virtual int loftV(int newcount, int start=-1, int stop=-1)=0
static GA_PrimitiveFamilyMask buildFamilyMask()
virtual int insertRow(unsigned int beforeWhich, bool appendPts=true)
virtual int refineU(float k, GA_AttributeRefMap &hlist, int i=1)
virtual GA_Basis * newBasis() const =0
virtual int unrollU(int append_pts=1)
virtual void fixSeamsU()
virtual void fixSeamsV()
virtual int raiseOrderVInt(int neworder)=0
virtual void openU(int preserveShape=0, int safe=0)
virtual int evaluateBreakpoint(int uidx, int vidx, UT_Vector4 &pos, int du=0, int dv=0) const =0
GEO_PrimNURBSurf(GA_Detail *d, GA_Offset offset=GA_INVALID_OFFSET)
const GLdouble * v
Definition: glcorearb.h:837
virtual int evaluateBasisDerivs(float u, float v, float ubmatx[][GA_MAXORDER], float vbmatx[][GA_MAXORDER], int &rowoffset, int &coloffset, unsigned du=0, unsigned dv=0, int uoffset=-1, int voffset=-1) const =0
GLuint start
Definition: glcorearb.h:475
virtual int warp(float u, float v, const UT_Vector3 &delta, GA_AttributeRefMap &map, float usharpness=0.0f, float vsharpness=0.f, float ubias=-1.0f, float vbias=-1.0f)=0
#define GA_MAXORDER
Definition: GA_Defines.h:17
virtual int deleteCol(unsigned int which)
virtual int warpU(float u, const UT_Vector3 &delta, GA_AttributeRefMap &map, float sharpness=0.0f, float bias=-1.0f)=0
virtual void wrapU(int rounded=1, int preserveShape=0)
virtual int unrefineUFloat(int kidx, int mult=0, float tol=1e-4F, GA_PointGroup *delgroup=0)
virtual int subdivideVRefMap(float u, GA_AttributeRefMap &map)
virtual int raiseOrderUInt(int neworder)=0
virtual int refineV(float k, GA_AttributeRefMap &hlist, int i=1)
void reverseV() override
virtual int subdivideURefMap(float u, GA_AttributeRefMap &map)
virtual int cycleV(int amount, int=1)
virtual int domainRangeOfCV(int i, int j, int &minuk, int &maxuk, int &minvk, int &maxvk) const =0
GA_PrimitiveFamilyMask
#define GA_INVALID_OFFSET
Definition: GA_Types.h:678
virtual bool isClampedU() const
virtual int insertCol(unsigned int beforeWhich, bool appendPts=true)
virtual int warpV(float v, const UT_Vector3 &delta, GA_AttributeRefMap &map, float sharpness=0.0f, float bias=-1.0f)=0
GA_ParameterizationType
Definition: GA_Types.h:196
virtual int vMaxValidIndex() const
static GA_IntrinsicManager::Registrar registerIntrinsics(GA_PrimitiveDefinition &defn)
GA_Size GA_Offset
Definition: GA_Types.h:641
vint4 blend(const vint4 &a, const vint4 &b, const vbool4 &mask)
Definition: simd.h:4784
virtual int unrefineVRefMap(int kidx, GA_AttributeRefMap &h, int mult=0, float tol=1e-4f, GA_PointGroup *delgroup=0)
GLfloat f
Definition: glcorearb.h:1926
GLintptr offset
Definition: glcorearb.h:665
virtual int breakpointRangeOfCV(int i, int j, int &minbkpu, int &maxbkpu, int &minbkpv, int &maxbkpv) const =0
int attachV(const GEO_Hull &hull, int blend=1, float bias=0.5f, float tolerance=1.0f, int unrefine=1, GA_PointGroup *ptgroup=0) override
GA_API const UT_StringHolder trans
virtual int cycleU(int amount, int=1)
virtual int evaluateUBasis(float u, float *ubvals, int &coloffset, unsigned du=0, int uoffset=-1) const =0
virtual const GA_PrimitiveJSON * getJSON() const =0
virtual void openV(int preserveShape=0, int safe=0)
Provide a JSON interface to a primitive.
#define GEO_API
Definition: GEO_API.h:14
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
virtual void reparameterizeV(GA_ParameterizationType ptype)=0
A handle to simplify manipulation of multiple attributes.
~GEO_PrimNURBSurf() override
virtual int evaluateBasis(float u, float v, float *ubvals, float *vbvals, int &rowoffset, int &coloffset, unsigned du=0, unsigned dv=0, int uoffset=-1, int voffset=-1) const =0
virtual int subdivideVFloat(float u)
void reverseU() override
virtual void reparameterizeU(GA_ParameterizationType ptype)=0
virtual int subdivideUFloat(float u)
virtual GEO_TPSurf * extract(float ustart, float ustop, float vstart, float vstop) const =0
GLint j
Definition: glad.h:2733
GLfloat GLfloat GLfloat GLfloat h
Definition: glcorearb.h:2002
virtual void wrapV(int rounded=1, int preserveShape=0)
virtual int translateBreakpoints(const UT_IntArray &uindices, const UT_IntArray &vindices, const UT_Vector3 &delta, int fixbkpts=1, GA_PointGroup *ptgroup=NULL, GEO_Delta *geodelta=0)=0
virtual int vMinValidIndex() const
int attachU(const GEO_Hull &hull, int blend=1, float bias=0.5f, float tolerance=1.0f, int unrefine=1, GA_PointGroup *ptgroup=0) override
virtual int unrefineVFloat(int kidx, int mult=0, float tol=1e-4F, GA_PointGroup *delgroup=0)
virtual int loftU(int newcount, int start=-1, int stop=-1)=0
virtual void transpose()
virtual int uMaxValidIndex() const
virtual int uMinValidIndex() const
virtual int evaluateVBasis(float v, float *vbvals, int &rowoffset, unsigned dv=0, int voffset=-1) const =0
Container class for all geometry.
Definition: GA_Detail.h:96
Definition of a geometric primitive.
GLboolean r
Definition: glcorearb.h:1222
virtual int unrefineURefMap(int kidx, GA_AttributeRefMap &h, int mult=0, float tol=1e-4f, GA_PointGroup *delgroup=0)
virtual int deleteRow(unsigned int which)
virtual bool isClampedV() const
static GA_IntrinsicManager::Registrar registerIntrinsics(GA_PrimitiveDefinition &defn)
static GA_PrimitiveFamilyMask buildFamilyMask()
Definition: GEO_TPSurf.h:651
virtual int raiseOrderVRefMap(int neworder, GA_AttributeRefMap &map)=0
virtual int raiseOrderURefMap(int neworder, GA_AttributeRefMap &map)=0
virtual int transformBreakpoints(const UT_IntArray &uindices, const UT_IntArray &vindices, const UT_Matrix4 &matx, int fixbkpts=1, GA_PointGroup *ptgroup=NULL, GEO_Delta *geodelta=0)=0
virtual int unrollV(int append_pts=1)