HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
GEO_TPSurf.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 handles tensor product (TP) surfaces of arbitrary degree.
10  * The Hull class maintains the hull for the surface.
11  *
12  *
13  */
14 
15 #ifndef __GEO_TPSurf_h__
16 #define __GEO_TPSurf_h__
17 
18 #include "GEO_API.h"
19 #include <UT/UT_BoundingRect.h>
20 #include <UT/UT_RefMatrix.h>
21 #include <UT/UT_IntArray.h>
22 #include <UT/UT_Interval.h>
23 #include <UT/UT_Matrix.h>
24 #include <GA/GA_Basis.h>
25 #include <GA/GA_GenericHandle.h>
26 #include "GEO_Hull.h"
27 #include "GEO_PrimType.h"
28 
29 class GU_IsectCurveSet;
30 class GEO_Curve;
31 class GEO_Delta;
32 class GEO_Face;
33 class GEO_Greville;
34 class GEO_PasteSurf;
35 class GEO_Profiles;
37 class GA_Detail;
38 template<bool isconst> class GA_PwHandle;
41 class UT_MemoryCounter;
42 
43 class GEO_API GEO_TPSurf : public GEO_Hull
44 {
45 protected:
46  /// NOTE: The constructor should only be called from subclass
47  /// constructors.
48  // You can optionally specify the number of rows and columns.
50  : GEO_Hull(d, offset)
51  , myUBasis(NULL)
52  , myVBasis(NULL)
53  , theProfiles(NULL)
54  , thePasteSurf(NULL)
55  {}
56 
57  /// NOTE: The destructor should only be called from subclass
58  /// destructors.
59  // It assumes it is OK to delete the bases, so make sure you always
60  // set the bases with objects allocated from the heap.
61  virtual ~GEO_TPSurf();
62 
63 public:
64  // Return any dependent details (GEO_Profiles)
65  virtual unsigned getNumSecondaryDetails() const;
66  virtual const GA_Detail *getSecondaryDetail(GA_Index i) const;
68 
69  // Overwrite this surface with the data from src. Virtual by inheritance.
70  virtual void copyPrimitive( const GEO_Primitive *src);
71  virtual GEO_Primitive *copy(int preserve_shared_pts = 0) const;
72 
73  virtual void copyUnwiredForMerge(const GA_Primitive *src,
74  const GA_MergeMap &map);
75 
76  virtual void clearForDeletion();
77 
78  // Merge tpsurf's profiles into ours. Skin invisible ones if you want.
79  void mergeProfiles(const GEO_TPSurf &tpsurf,
80  int onlyvisible = 0);
81 
82 
83  // Evaluate one point (when du=dv=0), or the du-th dv-th derivative.
84  // Return 0 if successful, and -1 otherwise.
85  bool evaluate(fpreal u, fpreal v, GA_Offset result_vtx,
86  GA_AttributeRefMap &hlist,
87  unsigned du=0, unsigned dv=0,
88  int uoffset=-1, int voffset=-1) const;
89  int evaluateHomogeneous(float u, float v, UT_Vector4 &pos,
90  unsigned du=0, unsigned dv=0,
91  int uoffset=-1, int voffset=-1) const;
92  int evaluate(float u, float v, UT_Vector4 &pos,
93  unsigned du=0, unsigned dv=0,
94  int uoffset=-1, int voffset=-1) const;
95  virtual void computeInteriorPointWeights(
96  UT_Array<GA_Offset> &vtxlist,
97  UT_Array<float> &weightlist,
98  fpreal u, fpreal v, fpreal w) const;
99 
100  template <typename T>
101  bool evaluateHomogeneous(fpreal u, fpreal v,
102  const GA_ROGenericHandleVertex<T> &h, T &pos,
103  unsigned du=0, unsigned dv=0,
104  int uoffset=-1, int voffset=-1) const;
105 
106  // Given a domain value (u,v), store all the basis derivatives
107  // (from 0 to du and from 0 to dv inclusive) into ubmatx and vbmatx
108  // respectively. Return the min indices of the CVs needed
109  // for the linear combination. The indices may exceed the number of
110  // vertices if the surface is wrapped, so remember to use modulus (%).
111  virtual int evaluateBasisDerivs(float u, float v,
112  float ubmatx[][GA_MAXORDER],
113  float vbmatx[][GA_MAXORDER],
114  int &rowoffset, int &coloffset,
115  unsigned du=0, unsigned dv=0,
116  int uoffset=-1, int voffset=-1) const = 0;
117 
118  // Evaluate the basis at the given point in the domain and also return
119  // the index of the first CV to linearly combine the basis with. The CV
120  // indices may exceed the number of vertices if the surface is wrapped,
121  // so remember to use modulus (%).
122  virtual int evaluateBasis(float u, float v, float *ubvals,
123  float *vbvals, int &rowoffset,
124  int &coloffset,
125  unsigned du=0, unsigned dv=0,
126  int uoffset=-1, int voffset=-1) const = 0;
127  virtual int evaluateUBasis(float u, float *ubvals, int &coloffset,
128  unsigned du=0, int uoffset=-1) const = 0;
129  virtual int evaluateVBasis(float v, float *vbvals, int &rowoffset,
130  unsigned dv=0, int voffset=-1) const = 0;
131 
132  // Return the value of the i'th u/vbasis at parameter u or v, or both.
133  // This method handles both rational an non-rational surfaces. You need
134  // to specify the row and column index only if the surface is rational,
135  // so that we know whose weights to use.
136  float computeUBValue(float u, int uoff) const;
137  float computeVBValue(float v, int voff) const;
138  float computeBValue (float u,float v,int uoff,int voff)const;
139 
140  // Fill in parameter values that interpolate breakpoints. The start
141  // and stop indices are breakpoint indices. lod specifies the number
142  // of isoparms to insert between breakpoints in each dimension.
143  void fillBreakParameters(UT_FloatArray &uvals,
144  UT_FloatArray &vvals,
145  int ustartidx, int ustopidx,
146  int vstartidx, int vstopidx,
147  int ulod, int vlod) const;
148 
149  // Evaluate the surface for the given parameter arrays. The provided
150  // result array should provide storage for
151  // uvals.entries()*vvals.entries() values.
152  bool evaluateMesh(const UT_FloatArray &uvals,
153  const UT_FloatArray &vvals,
154  UT_Vector4 *pos,
155  bool transpose = false,
156  unsigned du = 0, unsigned dv = 0) const;
157  bool evaluateMesh(const UT_FloatArray &uvals,
158  const UT_FloatArray &vvals,
159  GEO_WorkVertexArray &verts,
161  bool transpose = false,
162  unsigned du = 0, unsigned dv = 0) const;
163  bool evaluateMesh(const UT_FloatArray &uvals,
164  const UT_FloatArray &vvals,
165  GA_WorkVertexBuffer &verts,
166  GA_AttributeRefMap &map,
167  bool transpose = false,
168  unsigned du = 0, unsigned dv = 0) const;
169 
170  // Explicit instantiations are provided for float, UT_Vector3,
171  // UT_Vector4, UT_Matrix3, UT_Matrix4, GA_Offset
172  template <typename T>
173  bool evaluateMesh(const UT_FloatArray &uvals,
174  const UT_FloatArray &vvals,
176  T *pos,
177  bool transpose = false,
178  unsigned du = 0, unsigned dv = 0) const;
179 
180  // Compute the CVs of the U or V isoparametric curve running through
181  // the given parametric value. The number of resulting CVs equals the
182  // number or rows (if v = const.) or cols (if u = const.) respectively.
183  // We return 0 if successful and -1 otherwise. Use these methods to
184  // extract isoparms.
185  int computeUConstCVs(float u, GEO_Face *results,
186  const GA_AttributeRefMap &map,
187  int uoffset=-1) const;
188 
189  int computeUConstCVs(float u, UT_Vector4 *cvs,
190  int uoffset=-1) const;
191 
192  int computeVConstCVs(float v, GEO_Face *results,
193  const GA_AttributeRefMap &map,
194  int voffset=-1) const;
195  int computeVConstCVs(float v, UT_Vector4 *cvs,
196  int voffset=-1) const;
197 
198  // Create a profile curve (curve on surface) at the given isopam value:
199  // Return 0 if successful and -1 otherwise. growtip is a value by which
200  // we grow the tips of the iso line. It's useful to have it non-zero
201  // when trimming.
202  int createUConstProfile(float u, float growtip = 0.0f);
203  int createVConstProfile(float v, float growtip = 0.0f);
204 
205  // Map the given value, defined in our domain, to a value in a chord/arc
206  // length domain computed from our columns (u) or rows (v). Return -1 if
207  // failed and 0 if successful. u and v must live in the valid interval.
208  // Compute the chord-length parameterized basis in U or V for a given
209  // location in our valid interval. Return 0 if OK and -1 otherwise. ubasis
210  // and vbasis will be resized inside these methods if necessary.
211  int chordUBasis(float v, GA_Basis &ub, int voff=-1) const;
212  int chordVBasis(float u, GA_Basis &vb, int uoff=-1) const;
213 
214  // Evaluate the unit normal at (u,v) or at basis indices (iu,iv).
215  // Return 0 if successful, and -1 otherwise.
216  virtual int evaluateNormal(float u,float v, UT_Vector3 &nml) const;
217  virtual int normalIndex(float iu, float iv, UT_Vector3 &nml) const;
218 
219  // Evaluate the curvature at (u,v).
220  // Return 0 if successful, and -1 otherwise.
221  int curvature(float u, float v, float &curv) const;
222 
223  // Evaluate the arc length of the surface within a range. If the
224  // values are invalid, return -1. divs means divisions per span.
225  float arcLength(float u0, float v0, float u1, float v1,
226  int divs = 10) const;
227 
228  // Given a CV index figure out the min/max indicies of the knots between
229  // which the curve needs to be re-evaluated if the CV changes. If not
230  // given a valid CV index, the method returns -1. Otherwise it returns 0.
231  virtual int domainRangeOfCV(int i, int j, int &minuk,int &maxuk,
232  int &minvk,int &maxvk) const=0;
233 
234  // Given a CV index figure out the min/max breakpoints which are
235  // affected if the CV changes. If not given a valid CV index, the
236  // method returns -1. Otherwise it returns 0. Also returns -1 if
237  // no breakpoints are affected.
238  // NOTE: use % breakCount since maxbkp may be >= breakCount
239  virtual int breakpointRangeOfCV(int i, int j, int &minbkpu,
240  int &maxbkpu, int &minbkpv,
241  int &maxbkpv) const = 0;
242 
243  // Reparameterize the surface by changing its basis. This type of
244  // reparameterization is generally NOT shape preserving:
245  virtual void reparameterizeU(GA_ParameterizationType ptype) = 0;
246  virtual void reparameterizeV(GA_ParameterizationType ptype) = 0;
247 
248  // Reverse rows (V) or columns (U). Reversing in either direction will
249  // flip the normal.
250  virtual void reverseU(void);
251  virtual void reverseV(void);
252 
253  // Remap the basis and possibly the profiles too. The origin and length
254  // apply to the whole length of the basis, not just to the valid interval.
255  void mapUBasis(float orig, float len);
256  void mapVBasis(float orig, float len);
257 
258  // Return the bounds of the valid evaluation interval in domain space:
259  // For meshes this refers to cv indices.
260  virtual void validURange(float &ua, float &ub) const;
261  virtual void validVRange(float &va, float &vb) const;
262  virtual void validUInterval(int &a, int &b) const;
263  virtual void validVInterval(int &a, int &b) const;
264 
265  /// Compute the texture coordinates either uniformly of chord length.
266  /// If ptattrib is true we deal with points, else with vertices.
267  /// Returns false iff problems.
268  bool uniformTexture (const GA_RWHandleV3 &txth, bool ptattrib);
269  bool grevilleTexture(const GA_RWHandleV3 &txth, bool ptattrib);
270  bool chordLenTexture(const GA_RWHandleV3 &txth, bool ptattrib);
271 
272  // Compute the UV anc CV images of each Greville point.
273  // resize is expensive: try to avoid it if possible.
274  // Returns true if success
275  bool buildGrevilles(UT_RefMatrix<GEO_Greville> &dest) const;
276 
277  // Compute the _approximate_ first order derivative at
278  // greville[uIdx,vIdx]. None of these methods checks the boundary
279  // conditions on the two indices, so be careful.
280  // They return true iff successful.
281  bool duApprox(const UT_RefMatrix<GEO_Greville> &grevilles,
282  int uIdx, int vIdx, UT_Vector3 &du,
283  int normalize=1, float precision=0.008F) const;
284  bool dvApprox(const UT_RefMatrix<GEO_Greville> &grevilles,
285  int uIdx, int vIdx, UT_Vector3 &du,
286  int normalize=1, float precision=0.008F) const;
287 
288  // Set the coordinates of cv[r,c].
289  // The method returns 0 if OK and -1 if the indices are wrong.
290  int setCV(unsigned r, unsigned c, const UT_Vector4 &v);
291 
292  // Take the weights into consideration or don't. If you do, the surface
293  // becomes a rational, and possibly different algorithms apply. If 'onOff'
294  // is true, this function first checks if any two weights are different
295  // before setting the rational flag to TRUE; if they are all the same,
296  // the surface is set to non-rational (=> faster evaluation). weights()
297  // calls normalizeWeights() to bring the weights to standard form.
298  // Weights that are <= 0 are bumped up to FLT_EPSILON.
299  void weights(unsigned short onOff);
300 
301  // Set the weight of cv[r,c] to w. If the indices are out of bounds, it
302  // returns -1; otherwise it returns 0. Weights that are <= 0 are bumped
303  // up to FLT_EPSILON.
304  int setWeight(unsigned int r, unsigned int c, float w);
305 
306  // Get the weight of cv[r,c]. Return -1 if indices are wrong.
307  float getWeight(unsigned int r, unsigned int c) const;
308 
309  // Find out whether the surface is currently computed as a rational:
310  int isRational() const;
311 
312  // Go from a normalized domain ([0,1]) to the real domain or vice versa.
313  // We look only at the valid interval.
314  virtual void unitToRealDomain(float u_unit, float v_unit,
315  float &u_real, float &v_real) const;
316  virtual void realToUnitDomain(float u_real, float v_real,
317  float &u_unit, float &v_unit) const;
318 
319  // Calculate the real domains for n consecutive operations on the domain
320  // given n normalized domains and the operation
321  virtual void unitToRealSequenceU(float *uunit, float *ureal,
322  int ulen) const;
323 
324  virtual void unitToRealSequenceV(float *vunit, float *vreal,
325  int vlen) const;
326 
327  // Normalize the weights of the control mesh so that edge weights are 1,
328  // and all weights are >= 0 (those that are <= 0 are bumped up to
329  // FLT_EPSILON).
330  void normalizeWeights();
331 
332  // Normalize the domain and optionally shift it to a new origin. Use the
333  // given length if greater than 0.
334  void normalizeDomain(float len = 0.F,float *newuorigin = 0,
335  float *newvorigin = 0);
336 
337  // This function will refine the area bounded by "rect" to have divisions
338  // at least the size of "tol". "rect" passes in the boundary of the
339  // surface that contains the curve to be deformed, and it passes out the
340  // boundary that was actually defined (the latter is slightly bigger).
341  // It returns (via reference parameters uunits, vunits, udivs, vdivs) the
342  // float arrays and the size of the float array. Please delete the
343  // array pointed to by uunits and vunits after use. It also returns an
344  // array of original breakpoints (via uunrefineranges and vunrefineranges)
345  // where all the original breakpoints with some newly inserted nodes between
346  // them are returned.
347  void refineRange(const UT_BoundingRect &rect, float tol,
348  float *&uunits, float *&vunits,
349  int &udivs, int &vdivs,
350  UT_FloatArray &uunrefineranges,
351  UT_FloatArray &vunrefineranges);
352 
353  // Refine an area around the boundary of the surface, called the "belt".
354  void refineBelt(float ubwidth = 0.4F, float vbwidth = 0.4F,
355  int ubdivs = 2, int vbdivs = 2);
356 
357  // Set or query the U and V bases respectively. The "set" functions
358  // overwrite the current basis pointer, so use with care; they return
359  // -1 if the bases are invalid.
361  {
362  if (ub && ub->checkValid((int)getNumCols(), (int)isWrappedU()))
363  {
364  delete myUBasis; myUBasis = ub;
365  return 0;
366  }
367  else return -1;
368  }
370  {
371  if (vb && vb->checkValid((int)getNumRows(), (int)isWrappedV()))
372  {
373  delete myVBasis; myVBasis = vb;
374  return 0;
375  }
376  else return -1;
377  }
378  GA_Basis* getUBasis(void) const { return myUBasis; }
379  GA_Basis* getVBasis(void) const { return myVBasis; }
380 
381  // Query the order of the u and respectively v bases.
382  unsigned getUOrder(void) const { return (unsigned)myUBasis->getOrder(); }
383  unsigned getVOrder(void) const { return (unsigned)myVBasis->getOrder(); }
384 
385  // Query the dimension of the u and respectively v bases.
386  unsigned getUDim(void) const { return (unsigned)myUBasis->getDimension(); }
387  unsigned getVDim(void) const { return (unsigned)myVBasis->getDimension(); }
388 
389  // Gets the current U and V grevilles of the surface
390  // User Beware: If the surface is subsequently changed, i.e. if the basis
391  // changed, refined, etc., the results from this method
392  // will be useless.
393  void getUGrevilles(UT_FloatArray &ugrevilles) const;
394  void getVGrevilles(UT_FloatArray &vgrevilles) const;
395 
396  // Inherited from the base class: just checks the validity of the bases.
397  virtual bool isDegenerate(void) const;
398 
399  // Get the bounding box for a specific range of u and v
400  virtual void getRangeBBox(const UT_Interval &u,
401  const UT_Interval &v,
402  UT_BoundingBox &bbox,
403  const GA_PwHandleRO &h) const = 0;
404 
405  // Dehomogenize data (with attributes):
406  static void dehomogenizeData(GA_Offset *vertices,
407  GA_AttributeRefMap &hlist,
408  int count);
409  static void dehomogenizeData(UT_Vector4 *pos, int count);
410 
411  // Increase the order. Return 0 if successful, -1 otherwise (eg.
412  // order cannot be increased because it's >= MAXORDER).
413  int raiseOrderU (int neworder)
414  { return raiseOrderUInt(neworder); }
415  int raiseOrderV (int neworder)
416  { return raiseOrderVInt(neworder); }
417  int raiseOrderU(int neworder,
418  GA_AttributeRefMap &map)
419  { return raiseOrderURefMap(neworder, map); }
420  int raiseOrderV(int neworder,
421  GA_AttributeRefMap &map)
422  { return raiseOrderVRefMap(neworder, map); }
423 
424 
425  // Translate the CVs such that the given breakpoint change positions by
426  // the given delta. Return -1 if something goes wrong, 0 if translation
427  // was successful.
428  // NOTE: Cannot contain any duplicates. If the surface is wrapped,
429  // the first and last breakpoint are considered the same.
430  virtual int translateBreakpoints(const UT_IntArray &uindices,
431  const UT_IntArray &vindices,
432  const UT_Vector3 &delta,
433  int fixbkpts = 1,
434  GA_PointGroup *ptgroup=NULL,
435  GEO_Delta *geodelta = 0) = 0;
436 
437  virtual int transformBreakpoints(const UT_IntArray &uindices,
438  const UT_IntArray &vindices,
439  const UT_Matrix4 &matx,
440  int fixbkpts = 1,
441  GA_PointGroup *ptgroup=NULL,
442  GEO_Delta *geodelta = 0) = 0;
443 
444  // Append another hull to us in one of two ways: blend the two endpoints
445  // or connect them straight or rounded. The bias ranges from 0 to 1 and is
446  // relevant only to blending. The tolerance for blending: if 0, the two
447  // endpoints will merge into one point with a discontinuity; if less than
448  // 1, we insert knots into the hulls to minimize the affected areas; if 1,
449  // no refinement is done. For the non-blend case, the tolerance will
450  // generate a span whose shape goes from round to straight; 0 tolerance
451  // means straight connection. If unrefine is on, we'll try to reduce the
452  // complexity of the hull if we're connecting rounded. We return 0 if OK
453  // and -1 if error. Both hulls must be open and have the same order.
454  virtual int attachU(const GEO_Hull &hull, int blend = 1,
455  float bias = 0.5f, float tolerance = 1.0f,
456  int unrefine = 1, GA_PointGroup *ptgroup=0);
457  virtual int attachV(const GEO_Hull &hull, int blend = 1,
458  float bias = 0.5f, float tolerance = 1.0f,
459  int unrefine = 1, GA_PointGroup *ptgroup=0);
460 
461  // If [ustart,ustop] and [vstart,vstop] are in the valid interval, return
462  // the part of the surface delimited by those values in a new primitive.
463  // Return 0 if a problem is encountered.
464  virtual GEO_TPSurf *extract(float ustart, float ustop,
465  float vstart, float vstop) const = 0;
466 
467  // Derived from the base class. Here we just want to preserve our basis.
468  virtual void subdivide(int numdivs, GA_PointGroup *ptgroup=0);
469 
470  // Return the surrounding values of the real-space u,v parameters.
471  // Returns 1 if succesful, 0 if out-of-range.
472  virtual int parametricBBox(float u, float v,
473  float *u0, float *u1,
474  float *v0, float *v1);
475 
476  // Find out if the surface has any profiles in its domain:
477  int hasProfiles(void) const;
478 
479  // Get the profiles detail. Create the detail if not there if the create
480  // option is true.
481  GEO_Profiles *profiles(int create = 1);
482  GEO_Profiles *profiles(void) const { return theProfiles; }
483 
484  // find out if the surface is pasted:
485  int isPasted(void) const { return thePasteSurf != 0; }
486 
487  // Get or set the pasted image of this surface:
488  GEO_PasteSurf *pastedSurface(void) const { return thePasteSurf; }
489  void pastedSurface(GEO_PasteSurf *p) { thePasteSurf = p; }
490 
491  // Update the displacement of the CV(s) whose point is ptoff if the
492  // surface is pasted. This method wil not update the pasted dependents
493  // unless you want it to. Return 1 of found and 0 otherwise.
494  int updateDisplacement(GA_Offset ptoff,
495  int updatekids = 1);
496 
497  virtual void isolate(void);
498 
499  /// Stash (deactivate) or unstash (reactivate) the primitive.
500  virtual void stashed(bool beingstashed,
502 
503  /// @{
504  /// Method to load/save basis values.
505  bool jsonSaveUBasis(UT_JSONWriter &w) const;
506  bool jsonSaveUBasis(UT_JSONValue &v) const;
507  bool jsonSaveVBasis(UT_JSONWriter &w) const;
508  bool jsonSaveVBasis(UT_JSONValue &v) const;
509  bool jsonLoadUBasis(UT_JSONParser &p);
510  bool jsonLoadUBasis(UT_JSONParser &p, const UT_JSONValue &v);
511  bool jsonLoadVBasis(UT_JSONParser &p);
512  bool jsonLoadVBasis(UT_JSONParser &p, const UT_JSONValue &v);
513  /// @}
514 
515  // Constraint based manipulation.
516  // If the parameterization and derivative constraints do not change and
517  // the curve's basis and order don't change, then the system only needs to
518  // be solved once. The solution can then be applied multiple times,
519  // with different changes at the given parameters.
520 
521  // Return 0 if the resulting system is overdetermined (or otherwise
522  // unsolvable).
523  // 1 if ok.
524  int solveConstraints(const UT_Vector &uparam,
525  const UT_Vector &vparam,
526  const UT_IntArray &udervs,
527  const UT_IntArray &vdervs,
528  UT_MatrixF &soln,
529  UT_IntArray &cv_idx);
530 
531  // Return 0 if the given data is invalid (incorrect dimensions or indices).
532  // 1 if ok.
533  // The changes matrix is an n x 3 matrix, with each of the columns
534  // corresponding to the x, y, and z coordinates.
535  // If the surface is rational, the changes matrix will be modified.
536  int applyConstraints(UT_MatrixF &changes,
537  const UT_Vector &uparam,
538  const UT_Vector &vparam,
539  const UT_IntArray &udervs,
540  const UT_IntArray &vdervs,
541  const UT_IntArray &cv_index,
542  const UT_MatrixF &soln);
543 
544  // Return 0 if the resulting system is overdetermined.
545  // 1 if ok.
546  // Only call this method when the solution cannot be reused.
547  // If the surface is rational, the changes matrix will be modified.
548  int solveAndApplyConstraints(const UT_Vector &uparam,
549  const UT_Vector &vparam,
550  const UT_IntArray &udervs,
551  const UT_IntArray &vdervs,
552  UT_MatrixF &changes);
553 
554  /// Elevate the curve to the given order. Return 0 if OK and -1 otherwise.
555  int elevateOrderU(int order);
556  int elevateOrderV(int order);
557 
558  virtual int intersectSurf(GEO_TPSurf &surf2,
559  GU_IsectCurveSet &curveset,
560  float worldtol = 1e-4F,
561  float domaintol = 1e-2F,
562  int steps = 100,
563  bool docompact = true) = 0;
564  virtual int doesIntersect(const GEO_Primitive &prim,
565  float worldtol = 1e-4F, int nontrivial = 0) const = 0;
566 
567  /// This is more powerful than convertNew. It always returns a NEW
568  /// object, so free it when you're done with it. It may return a mesh,
569  /// a NURB surface or a Bezier surface depending on the type.
570  virtual GEO_Hull *reconfigure(unsigned type, int orderu, int orderv,
571  bool openu, bool openv,
572  bool endsu, bool endsv) const = 0;
573 
574  /// Construct a curve that has our characteristics in u or v. The
575  /// CVs of the new curve are not set.
576  /// @{
577  virtual GEO_Curve *buildRowCurve(bool appendPoints,
578  GEO_Detail *parent) const = 0;
579  virtual GEO_Curve *buildColCurve(bool appendPoints,
580  GEO_Detail *parent) const = 0;
581  /// @}
582 
583  /// Cut a wedge of the primitive given a domain range
584  /// ind1 and ind2 are indices to the refined values
585  /// They are updated if negative on input, else used as is.
586  /// If keep is zero the curve is only refined and the indices
587  /// updated.
588  virtual GEO_TPSurf *cutU(float u1, float u2, int &ind1, int &ind2,
589  int keep) = 0;
590 
591  virtual GEO_TPSurf *cutV(float v1, float v2, int &ind1, int &ind2,
592  int keep) = 0;
593 
594  /// Open the primitive at the given domain value
595  virtual void openAtU(float u) = 0;
596  virtual void openAtV(float v) = 0;
597 
598  /// Puts the position of the breakpoint at (uidx, vidx) in p
599  /// Returns 1 if uidx and vidx are both valid, 0 otherwise.
600  bool interpretBreakpoint(int uidx, int vidx, UT_Vector3 &p) const;
601 
602  /// Compute the CVs of the U or V isoparametric curve running through
603  /// the given parametric value. The number of resulting CVs equals the
604  /// number or rows (if v = const.) or cols (if u = const.) respectively.
605  /// We return the extracted curve if successful and 0 otherwise.
606  /// @{
607  GEO_Curve *extractUIsoparm(float u, int uoffset=-1)
608  { return extractUIsoparm(u, uoffset, getParent()); }
609  GEO_Curve *extractUIsoparm(float u, int uoffset,
610  GEO_Detail *parent) const;
612  int uoffset=-1)
613  { return extractUIsoparm(u, map, uoffset, getParent()); }
614  GEO_Curve *extractUIsoparm(float u, const GA_AttributeRefMap &map,
615  int uoffset, GEO_Detail *parent) const;
616  GEO_Curve *extractVIsoparm(float v, int voffset=-1)
617  { return extractVIsoparm(v, voffset, getParent()); }
618  GEO_Curve *extractVIsoparm(float v, int voffset,
619  GEO_Detail *parent) const;
621  int voffset=-1)
622  { return extractUIsoparm(v, map, voffset, getParent()); }
623  GEO_Curve *extractVIsoparm(float v, const GA_AttributeRefMap &map,
624  int voffset, GEO_Detail *parent) const;
625  /// @}
626 
627  /// remove a single curve in the domain of the hull
628  /// @{
629  GEO_Curve *extractU(float unitu)
630  { return extractU(unitu, getParent()); }
631  GEO_Curve *extractU(float unitu, GEO_Detail *parent) const;
632  GEO_Curve *extractV(float unitv)
633  { return extractV(unitv, getParent()); }
634  GEO_Curve *extractV(float unitv, GEO_Detail *parent) const;
635  /// @}
636 
637 protected:
638  // The bases in each parametric direction. Not const because we want
639  // to be able to (re)set them at initialization time or elsewhere.
640  // They must be set with objects allocated from the heap so that we can
641  // delete them when calling this class's destructor.
644 
645  // PROTECTED METHODS:
647  {
648  return static_cast<GA_PrimitiveFamilyMask>(
651  );
652  }
653 
654  // Declare intrinsic attribute functions
656 
657  // Load and save functions redefined from the parent class.
658  virtual bool savePrivateH9(std::ostream &os, bool binary) const;
659  virtual bool saveExtraH9 (std::ostream &, bool binary) const;
660  virtual bool loadPrivateH9(UT_IStream &is);
661  virtual bool loadExtraH9 (UT_IStream &);
662 
663  // Check the validity of the data. Meant to be called especially at loading
664  // time. The method returns 1 if OK and 0 if trouble.
665  virtual bool validate(void) const;
666 
667  // Used by the derived classes in their attach() methods.
668  void mergeAttachProfilesU(const GEO_TPSurf &tpsurf);
669  void mergeAttachProfilesV(const GEO_TPSurf &tpsurf);
670 
671  // Compute an evalution stepsize that is surely valid.
672  float stepSize(float start, float stop, int count) const
673  {
674  return (count > 0) ? ((stop - start)/(float)count)
675  : 0.0F;
676  }
677 
678  // Get a new basis of a type that matches our type:
679  virtual GA_Basis *newBasis(void) const = 0;
680 
681  // Evaluate the position or the derivative at domain point (u,v), where
682  // u and v MUST be in [0,1]. "v" and "dv" will be ignored when dealing
683  // with one-dimensional types such as circles and polygons. Return 0 if
684  // OK and -1 otherwise.
685  virtual bool evaluatePointRefMap( GA_Offset result_vtx,
686  GA_AttributeRefMap &hlist,
687  fpreal u, fpreal v, uint du, uint dv) const;
688  virtual int evaluatePointV4( UT_Vector4 &pos, float u, float v = 0,
689  unsigned du=0, unsigned dv=0) const;
690 
691  // Evaluate one point (when du=dv=0), or the du-th dv-th derivative.
692  // Return 0 if successful, and -1 otherwise.
693  // The difference between this method and evaluate() is that this one
694  // treats u and v as values between 2 knot indices, while evaluate()
695  // sees them as actual domain values.
696  virtual bool evaluateIndexRefMap(fpreal u, fpreal v, GA_Offset result_vtx,
697  GA_AttributeRefMap &hlist,
698  unsigned du, unsigned dv) const;
699  virtual int evaluateIndexV4(float iu, float iv, UT_Vector4 &pos,
700  unsigned du=0, unsigned dv=0) const;
701 
702  // Refine for all spans with specified number of divisions per span.
703  virtual void spanRefineURefMap(GA_AttributeRefMap &map, int ndivs=1);
704  virtual void spanRefineUInt(int numdivs=1);
705  virtual void spanRefineVRefMap(GA_AttributeRefMap &map, int ndivs=1);
706  virtual void spanRefineVInt(int numdivs=1);
707 
708  virtual int raiseOrderUInt (int neworder) = 0;
709  virtual int raiseOrderVInt (int neworder) = 0;
710  virtual int raiseOrderURefMap(int neworder,
711  GA_AttributeRefMap &map) = 0;
712  virtual int raiseOrderVRefMap(int neworder,
713  GA_AttributeRefMap &map) = 0;
714 
715  /// Report approximate memory usage for myUBasis, myVBasis,
716  /// theProfiles, since the subclasses don't have access to some.
717  int64 getBaseMemoryUsage() const;
718 
719  // This is called by the subclasses to count the
720  // memory used by myUBasis, myVBasis, theProfiles
721  void countBaseMemory(UT_MemoryCounter &counter) const;
722 
723 private:
724  // Method to copy the basis of the source to me
725  void copyBasisAndProfiles(const GEO_TPSurf *src);
726 
727  // Detail of (trimming) profiles:
728  GEO_Profiles *theProfiles;
729 
730  // The pasted image:
731  GEO_PasteSurf *thePasteSurf;
732 
733  friend std::ostream &operator<<(std::ostream &os, const GEO_TPSurf &d)
734  {
735  d.saveH9(os, 0,
738  return os;
739  }
740 };
741 
742 #endif
bool isWrappedU() const
Definition: GEO_Hull.h:467
void copyUnwiredForMerge(const GA_Primitive *src, const GA_MergeMap &map) override
virtual void realToUnitDomain(float u_real, float v_real, float &u_unit, float &v_unit) const
int setUBasis(GA_Basis *ub)
Definition: GEO_TPSurf.h:360
bool isWrappedV() const
Definition: GEO_Hull.h:468
int raiseOrderV(int neworder, GA_AttributeRefMap &map)
Definition: GEO_TPSurf.h:420
int isPasted(void) const
Definition: GEO_TPSurf.h:485
int setVBasis(GA_Basis *vb)
Definition: GEO_TPSurf.h:369
GEO_Primitive * copy(int preserve_shared_pts=0) const override
#define GEO_FAMILY_TPSURF
Definition: GEO_PrimType.h:75
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)=0
virtual void validVRange(float &va, float &vb) const
unsigned getUOrder(void) const
Definition: GEO_TPSurf.h:382
virtual void subdivide(int numdivs, GA_PointGroup *ptgroup=0)
const GLdouble * v
Definition: glcorearb.h:836
GEO_Profiles * profiles(void) const
Definition: GEO_TPSurf.h:482
GLuint start
Definition: glcorearb.h:474
virtual bool evaluateIndexRefMap(fpreal u, fpreal v, GA_Offset result_vtx, GA_AttributeRefMap &hlist, unsigned du, unsigned dv) const
int raiseOrderU(int neworder)
Definition: GEO_TPSurf.h:413
const GLuint GLenum const void * binary
Definition: glcorearb.h:1923
virtual int evaluateNormal(float u, float v, UT_Vector3 &nml) const
virtual void validVInterval(int &a, int &b) const
GEO_Curve * extractU(float unitu)
Definition: GEO_TPSurf.h:629
static GA_PrimitiveFamilyMask buildFamilyMask()
Definition: GEO_Hull.h:665
The merge map keeps track of information when merging details.
Definition: GA_MergeMap.h:53
virtual void validUInterval(int &a, int &b) const
GLboolean GLboolean GLboolean GLboolean a
Definition: glcorearb.h:1221
unsigned getUDim(void) const
Definition: GEO_TPSurf.h:386
#define GA_MAXORDER
Definition: GA_Defines.h:17
JSON reader class which handles parsing of JSON or bJSON files.
Definition: UT_JSONParser.h:75
SYS_FORCE_INLINE GEO_Detail * getParent() const
Class which writes ASCII or binary JSON streams.
Definition: UT_JSONWriter.h:32
virtual void unitToRealSequenceU(float *uunit, float *ureal, int ulen) const
#define GA_NO_OVERRIDE
Definition: GA_Primitive.h:76
GLfloat GLfloat GLfloat v2
Definition: glcorearb.h:817
3D Vector class.
png_uint_32 i
Definition: png.h:2877
virtual void spanRefineURefMap(GA_AttributeRefMap &map, int numdivs=1)=0
GA_PrimitiveFamilyMask
bool saveH9(std::ostream &os, bool binary, const UT_Array< GA_AttribSaveDataH9 > &prim_attribs, const UT_Array< GA_AttribSaveDataH9 > &vtx_attribs) const override
#define GA_INVALID_OFFSET
Definition: GA_Types.h:654
GA_Basis * myVBasis
Definition: GEO_TPSurf.h:643
GA_ParameterizationType
Definition: GA_Types.h:173
GA_PwHandle< true > GA_PwHandleRO
Definition: GEO_TPSurf.h:38
int divs(int x, int y)
Definition: ImathFun.h:180
GA_Size GA_Offset
Definition: GA_Types.h:617
virtual void unitToRealSequenceV(float *vunit, float *vreal, int vlen) const
GLsizei GLboolean transpose
Definition: glcorearb.h:831
long long int64
Definition: SYS_Types.h:107
virtual void validURange(float &ua, float &ub) const
GLfloat f
Definition: glcorearb.h:1925
unsigned getVOrder(void) const
Definition: GEO_TPSurf.h:383
GEO_PasteSurf * pastedSurface(void) const
Definition: GEO_TPSurf.h:488
virtual bool checkValid(int cvLen, int bLen, bool doesWrap) const =0
virtual int normalIndex(float iu, float iv, UT_Vector3 &nml) const
virtual void reverseU()
GA_Basis * getVBasis(void) const
Definition: GEO_TPSurf.h:379
virtual void unitToRealDomain(float u_unit, float v_unit, float &u_real, float &v_real) const
int64 getBaseMemoryUsage() const
Report approximate memory usage for myVertexMatx (exclusive)
GLintptr offset
Definition: glcorearb.h:664
#define GEO_API
Definition: GEO_API.h:10
Bezier or NURBS basis classes which maintain knot vectors.
Definition: GA_Basis.h:49
A handle to simplify manipulation of multiple attributes.
GEO_Curve * extractVIsoparm(float v, const GA_AttributeRefMap &map, int voffset=-1)
Definition: GEO_TPSurf.h:620
virtual void weights(unsigned short onOff)
bool isDegenerate() const override
Is the primitive degenerate.
GridType::Ptr normalize(const GridType &grid, bool threaded, InterruptT *interrupt)
Normalize the vectors of the given vector-valued grid.
GLboolean GLboolean GLboolean b
Definition: glcorearb.h:1221
GA_Size GA_Index
Define the strictness of GA_Offset/GA_Index.
Definition: GA_Types.h:611
unsigned int uint
Definition: SYS_Types.h:40
GLint GLsizei count
Definition: glcorearb.h:404
GA_DECLARE_INTRINSICS(override)
GLfloat v0
Definition: glcorearb.h:815
GEO_Curve * extractV(float unitv)
Definition: GEO_TPSurf.h:632
GLenum GLint GLint * precision
Definition: glcorearb.h:1924
int parametricBBox(float u, float v, float *u0, float *u1, float *v0, float *v1) override
GLfloat GLfloat GLfloat GLfloat h
Definition: glcorearb.h:2001
double fpreal
Definition: SYS_Types.h:270
virtual void spanRefineUInt(int numdivs=1)=0
unsigned getVDim(void) const
Definition: GEO_TPSurf.h:387
int raiseOrderV(int neworder)
Definition: GEO_TPSurf.h:415
static const UT_Array< GA_AttribSaveDataH9 > & theEmptySaveAttribs
Convience objects to pass as arguments to saveH9()/loadH9().
virtual bool loadExtraH9(UT_IStream &is)=0
GEO_Curve * extractVIsoparm(float v, int voffset=-1)
Definition: GEO_TPSurf.h:616
void copyPrimitive(const GEO_Primitive *src) override
virtual void reverseV()
int raiseOrderU(int neworder, GA_AttributeRefMap &map)
Definition: GEO_TPSurf.h:417
virtual int evaluateIndexV4(float iu, float iv, UT_Vector4 &pos, unsigned du=0, unsigned dv=0) const
GLfloat GLfloat v1
Definition: glcorearb.h:816
GEO_Curve * extractUIsoparm(float u, const GA_AttributeRefMap &map, int uoffset=-1)
Definition: GEO_TPSurf.h:611
GA_Basis * myUBasis
Definition: GEO_TPSurf.h:642
Class to store JSON objects as C++ objects.
Definition: UT_JSONValue.h:75
virtual bool evaluatePointRefMap(GA_Offset result_vtx, GA_AttributeRefMap &map, fpreal u, fpreal v=0, uint du=0, uint dv=0) const =0
GLint GLint GLsizei GLint GLenum GLenum type
Definition: glcorearb.h:107
virtual bool loadPrivateH9(UT_IStream &is)=0
Container class for all geometry.
Definition: GA_Detail.h:95
friend std::ostream & operator<<(std::ostream &os, const GEO_TPSurf &d)
Definition: GEO_TPSurf.h:733
virtual void spanRefineVRefMap(GA_AttributeRefMap &map, int numdivs=1)=0
GLubyte GLubyte GLubyte GLubyte w
Definition: glcorearb.h:856
Specialization of GA_ROGenericHandle for GA_ATTRIB_VERTEX offsets.
void countBaseMemory(UT_MemoryCounter &counter) const
float stepSize(float start, float stop, int count) const
Definition: GEO_TPSurf.h:672
virtual void computeInteriorPointWeights(UT_Array< GA_Offset > &vtxlist, UT_Array< float > &weightlist, fpreal u, fpreal v, fpreal w) const override
GEO_Curve * extractUIsoparm(float u, int uoffset=-1)
Definition: GEO_TPSurf.h:607
GLboolean r
Definition: glcorearb.h:1221
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)=0
GA_Basis * getUBasis(void) const
Definition: GEO_TPSurf.h:378
static GA_PrimitiveFamilyMask buildFamilyMask()
Definition: GEO_TPSurf.h:646
virtual bool saveExtraH9(std::ostream &os, bool binary) const =0
virtual unsigned getNumSecondaryDetails() const
A primitive may support any number of secondary details.
virtual bool savePrivateH9(std::ostream &os, bool binary) const =0
virtual void spanRefineVInt(int numdivs=1)=0
virtual void isolate()
Method to isolate a pasted surface.
virtual int evaluatePointV4(UT_Vector4 &pos, float u, float v=0, unsigned du=0, unsigned dv=0) const
void pastedSurface(GEO_PasteSurf *p)
Definition: GEO_TPSurf.h:489
virtual bool validate(void) const =0
void clearForDeletion() override
int keep
Definition: png.h:2568
virtual void stashed(bool beingstashed, GA_Offset offset=GA_INVALID_OFFSET) override
GEO_TPSurf(GA_Detail *d, GA_Offset offset=GA_INVALID_OFFSET)
Definition: GEO_TPSurf.h:49
virtual const GA_Detail * getSecondaryDetail(GA_Index i) const
GLenum src
Definition: glcorearb.h:1792