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