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