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