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