HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
GEO_Hull.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 is used as a base class for all patch types supported.
10  * The vertex list management is handled by this class, however, all
11  * other function should be handled by the subclass.
12  * The insertRow and insertCol are meant to be virtual since it
13  * may be possible for the patch type to insert a row or column
14  * without distorting the shape of the patch (as in NURBs or MESH)
15  *
16  */
17 
18 #pragma once
19 
20 #ifndef __GEO_Hull_H__
21 #define __GEO_Hull_H__
22 
23 #include "GEO_API.h"
24 #include "GEO_Primitive.h"
25 #include "GEO_SurfaceType.h"
26 #include "GEO_Vertex.h"
27 #include <GA/GA_OffsetMatrix.h>
28 #include <UT/UT_Assert.h>
29 #include <UT/UT_RefMatrix.h>
30 #include <UT/UT_Vector3.h>
31 #include <iosfwd>
32 
33 class UT_BitArray;
34 class GA_Detail;
35 class GA_EdgeGroup;
36 class UT_JSONWriter;
37 class UT_JSONParser;
38 class GA_SaveMap;
39 class GA_LoadMap;
40 
41 template<typename T, bool B> class GA_EdgeT;
43 
45 {
46 public:
48  {
49  wrapu = 0;
50  wrapv = 0;
51  }
52  bool wrapu:1;
53  bool wrapv:1;
54  bool loadBinary( UT_IStream &is );
55  int saveBinary( std::ostream &os ) const;
56 };
57 
59 {
60 public:
62  {
63  wrapu = 0; wrapv = 0;
64  dupTop = 0; dupLeft = 0;
65  dupBottom = 0; dupRight = 0;
66  breakThread = 0; breakBridge = 0;
67  recurse = 1;
68  }
69 
70  unsigned wrapu:1,
71  wrapv:1,
72  dupTop:1,
73  dupLeft:1,
74  dupBottom:1,
75  dupRight:1,
76  breakThread:1,
77  breakBridge:1,
78  recurse:1;
79 };
80 
82 {
83 public:
84  GEO_SubHullPart() { h_edge = v_edge = d_edge = flags = 0; }
85 
86  int h_edge;
87  int v_edge;
88  int d_edge;
89  int flags;
90  // `flags' is used as follows:
91  // Bit 0 - horizontal edge is used to break into a subhull
92  // Bit 1 - vertical edge " "
93  // Bit 2 - diagonal edge " "
94 
95  bool operator==(const GEO_SubHullPart &p) const
96  { return( (h_edge==p.h_edge) &&
97  (v_edge==p.v_edge) &&
98  (d_edge==p.d_edge) &&
99  (flags ==p.flags ) );
100  }
101  bool operator!=(const GEO_SubHullPart &p) const
102  { return !(*this == p); }
103 };
104 
106 {
107 public:
108  GEO_SubHull() : mat() {}
109 
111  int v_rows, v_cols;
112  int h_rows, h_cols;
113  int d_rows, d_cols;
114 };
115 
117 {
118 protected:
119  /// NOTE: The constructor should only be called from subclass
120  /// constructors.
122  : GEO_Primitive(d, offset)
124  , myRows(0)
125  , myCols(0)
126 #endif
127  {}
128 
129 #if !GA_PRIMITIVE_VERTEXLIST
130  /// NOTE: The destructor should only be called from subclass
131  /// destructors.
132  virtual ~GEO_Hull();
133 #endif
134 
135 public:
136  bool saveVertexArray(UT_JSONWriter &w,
137  const GA_SaveMap &save) const;
138  bool loadVertexArray(UT_JSONParser &p,
139  const GA_LoadMap &load);
140 
141  // Compute the location of the breakpoint. Return 0 if OK, else -1.
142  virtual int evaluateBreakpoint(int uidx, int vidx,
143  UT_Vector4 &pos,
144  int du=0, int dv=0) const = 0;
145 
146  // Evaluate one point (when du=dv=0), or the du-th dv-th derivative.
147  // Returns true if successful, and false otherwise.
148  bool evaluateIndex(fpreal u, fpreal v, GA_Offset result_vtx,
149  GA_AttributeRefMap &hlist,
150  unsigned du, unsigned dv) const
151  { return evaluateIndexRefMap(u, v, result_vtx, hlist, du, dv); }
152  int evaluateIndex(float iu, float iv, UT_Vector4 &pos,
153  unsigned du=0, unsigned dv=0) const
154  { return evaluateIndexV4(iu, iv, pos, du, dv); }
155 
156  virtual void computeInteriorPointWeights(
157  UT_Array<GA_Offset> &vtxlist, UT_Array<float> &weightlist,
158  fpreal u, fpreal v, fpreal w) const override;
159 
160  void normal(NormalComp &output) const override;
161 
162  // Evaluate the normal using unit u and v coordinates (i.e. in [0,1]).
163  // The normal is not normalized. The method does NOT fail if the point
164  // attribute is missing. We return 0 if OK and -1 if error.
165  int evaluateNormalVector(UT_Vector3 &nml, float u,
166  float v = 0, float w = 0) const override;
167 
168  // Evaluate the normal at real (u,v). The method does not fail if there
169  // is no point attribute, it instead just returns the face normal.
170  // Return 0 if successful, and -1 otherwise.
171  virtual int evaluateNormal(float u,float v, UT_Vector3 &nml) const;
172  virtual int normalIndex(float iu, float iv, UT_Vector3 &nml) const;
173 
174  virtual int uMinValidIndex() const;
175  virtual int uMaxValidIndex() const;
176  virtual int vMinValidIndex() const;
177  virtual int vMaxValidIndex() const;
178 
179  bool saveH9(std::ostream &os, bool binary,
180  const UT_Array<GA_AttribSaveDataH9> &prim_attribs,
181  const UT_Array<GA_AttribSaveDataH9> &vtx_attribs) const override;
182  bool loadH9(UT_IStream &is,
183  const UT_Array<GA_AttribLoadDataH9> &prim_attribs,
184  const UT_Array<GA_AttribLoadDataH9> &vtx_attribs) override;
185  int getBBox(UT_BoundingBox *bbox) const override;
186  void addToBSphere(UT_BoundingSphere *bsphere) const override;
187  UT_Vector3 baryCenter() const override;
188  UT_Vector3 computeNormal() const override;
189  void copyPrimitive(const GEO_Primitive *src) override;
190  GEO_Primitive *copy(int preserve_shared_pts = 0) const override;
191 
192  virtual void copySubclassData(const GA_Primitive *source) override;
193 
194 #if !GA_PRIMITIVE_VERTEXLIST
195  void addPointRefToGroup(GA_PointGroup &grp) const override;
196 #endif
197 
198  // Reverse rows (V) and/or columns (U):
199  void reverse () override;
200  virtual void reverseU();
201  virtual void reverseV();
202 
203  // Shift the array of vertices by an offset and wrap around. The offset
204  // can be either negative or positive. Cycles in complete rows/cols
205  virtual int cycleU(int amount, int = 1);
206  virtual int cycleV(int amount, int = 1);
207 
208  // All current rows and columns will be reinitialized
209  int setRowCol(int r, int c);
210  virtual int insertRow(unsigned int beforeWhich, bool appendPts=true);
211  int appendRow(bool appendPts=true)
212  {
213 #if GA_PRIMITIVE_VERTEXLIST
214  return insertRow(myRows, appendPts);
215 #else
216  return insertRow(myVertexMatx.getRows(), appendPts);
217 #endif
218  }
219  virtual int insertCol(unsigned int beforeWhich, bool appendPts=true);
220  int appendCol(bool appendPts=true)
221  {
222 #if GA_PRIMITIVE_VERTEXLIST
223  return insertCol(myCols, appendPts);
224 #else
225  return insertCol(myVertexMatx.getCols(), appendPts);
226 #endif
227  }
228 
229  virtual int deleteRow(unsigned int which);
230  virtual int deleteCol(unsigned int which);
231 
232  // Take the whole set of points into consideration when applying the
233  // point removal operation to this primitive. The method returns 0 if
234  // successful, -1 if it failed because it would have become degenerate,
235  // and -2 if it failed because it would have had to remove the primitive
236  // altogether.
237  int detachPoints (GA_PointGroup &grp) override;
238 
239  /// Before a point is deleted, all primitives using the point will be
240  /// notified. The method should return "false" if it's impossible to
241  /// delete the point. Otherwise, the vertices should be removed.
242  GA_DereferenceStatus dereferencePoint(
243  GA_Offset point, bool dry_run=false) override;
244  GA_DereferenceStatus dereferencePoints(
245  const GA_RangeMemberQuery &pt_q, bool dry_run=false) override;
246 
247  // Given a parameter in the domain, insert as many CVs as necessary to
248  // create a discontinuity at the corresponding point on the curve.The shape
249  // of the curve should NOT change. Return u's index upon success and -1
250  // otherwise.
251  int subdivideU(float u, GA_AttributeRefMap &map)
252  { return subdivideURefMap(u, map); }
253  int subdivideU(float u)
254  { return subdivideUFloat(u); }
255  int subdivideV(float u, GA_AttributeRefMap &map)
256  { return subdivideVRefMap(u, map); }
257  int subdivideV(float u)
258  { return subdivideVFloat(u); }
259 
260  virtual void subdivide(int numdivs, GA_PointGroup *ptgroup=0);
261 
262  // Warp the hull at u,v by the given delta. Change 1 or 4 Cvs and possibly
263  // insert a knot once or more as well. If a knot is inserted or we happen
264  // to land exactly on a knot, we change only one CV. The bias makes sense
265  // only when changing 4 CVs, and will be ignored altogether if < 0.
266  // We return the CV index in warpU/V and 0 in warp() if OK; -1 otherwise.
267  virtual int warpU(float u, const UT_Vector3 &delta,
268  GA_AttributeRefMap &map,
269  float sharpness = 0.0f, float bias = -1.0f) = 0;
270  virtual int warpV(float v, const UT_Vector3 &delta,
271  GA_AttributeRefMap &map,
272  float sharpness = 0.0f, float bias = -1.0f) = 0;
273  virtual int warp (float u, float v, const UT_Vector3 &delta,
274  GA_AttributeRefMap &map,
275  float usharpness = 0.0f, float vsharpness = 0.f,
276  float ubias = -1.0f, float vbias = -1.0f) = 0;
277 
278 
279  // Warp the hull along its normal at u,v. We warp u if the flag is 0,
280  // warp v if flag is 1, and warp both if flag is 2.
281  // We return 0 if OK, or -1 if there's an error.
282  int warpAlongNormal (float u, float v, float distance,
283  GA_AttributeRefMap &map,
284  float usharpness, float vsharpness,
285  float ubias, float vbias,
286  int u_v_both);
287 
288  // Append another hull to us in one of two ways: blend the two endpoints
289  // or connect them straight or rounded. The bias ranges from 0 to 1 and is
290  // relevant only to blending. The tolerance for blending: if 0, the two
291  // endpoints will merge into one point with a discontinuity; if less than
292  // 1, we insert knots into the hulls to minimize the affected areas; if 1,
293  // no refinement is done. For the non-blend case, the tolerance will
294  // generate a span whose shape goes from round to straight; 0 tolerance
295  // means straight connection. If unrefine is on, we'll try to reduce the
296  // complexity of the hull if we're connecting rounded. We return 0 if OK
297  // and -1 if error. Both hulls must be open and have the same order.
298  virtual int attachU(const GEO_Hull &hull, int blend = 1,
299  float bias = 0.5f, float tolerance = 1.0f,
300  int unrefine=1, GA_PointGroup *ptgroup=0) = 0;
301  virtual int attachV(const GEO_Hull &hull, int blend = 1,
302  float bias = 0.5f, float tolerance = 1.0f,
303  int unrefine=1, GA_PointGroup *ptgroup=0) = 0;
304 
305  // Change the multiplicity of the domain value by inserting it after
306  // checking its current multiplicity. Return -1 if invalid, otherwise
307  // return the index of the inserted knot
308 
309  virtual int refineU(float k,
310  GA_AttributeRefMap &hlist,
311  int i=1);
312 
313  virtual int refineU ( float k, int i=1);
314  virtual int refineV(float k,
315  GA_AttributeRefMap &hlist,
316  int i=1);
317  virtual int refineV ( float k, int i=1);
318 
319  // Refine numdivs times in each span.
321  int numdivs=1)
322  { spanRefineURefMap(map, numdivs); }
323  void spanRefineU( int numdivs=1)
324  { spanRefineUInt(numdivs); }
326  int numdivs=1)
327  { spanRefineVRefMap(map, numdivs); }
328  void spanRefineV( int numdivs=1)
329  { spanRefineVInt(numdivs); }
330 
331  // Remove rows and or columns based on a curvature tolerance. Return 1 of
332  // something was removed, else 0.
334  int mult=0, float tol=1e-4f,
335  GA_PointGroup *delgroup=0)
336  { return unrefineURefMap(kidx, h, mult,
337  tol, delgroup); }
338  int unrefineU(int kidx, int mult = 0,
339  float tol = 1e-4F,
340  GA_PointGroup *delgroup = 0)
341  { return unrefineUFloat(kidx, mult, tol,
342  delgroup); }
344  int mult=0, float tol=1e-4f,
345  GA_PointGroup *delgroup=0)
346  { return unrefineVRefMap(kidx, h, mult,
347  tol, delgroup); }
348  int unrefineV(int kidx, int mult = 0,
349  float tol = 1e-4F,
350  GA_PointGroup *delgroup = 0)
351  { return unrefineVFloat(kidx, mult, tol,
352  delgroup); }
353 
354  // If the hull is wrapped in U and/or V, explicitly add the wrapped vertex
355  // and open the hull in the direction(s) it's wrapped in.
356  virtual void fixSeamsU(void);
357  virtual void fixSeamsV(void);
358 
359  /// Apply row-column texture. If ptattrib is true, we deal with
360  /// points, else with vertices. Returns false iff problems.
361  bool rowColTexture(const GA_RWHandleV3 &txth, bool ptattrib);
362 
365 #if GA_PRIMITIVE_VERTEXLIST
366  { return myRows; }
367 #else
368  { return (int)myVertexMatx.getRows(); }
369 #endif
372 #if GA_PRIMITIVE_VERTEXLIST
373  { return myCols; }
374 #else
375  { return (int)myVertexMatx.getCols(); }
376 #endif
377 
378  /// This should only be used for initializing member data after
379  /// creating a hull primitive via appendPrimitive
380  /// and initializing its vertex list.
381  /// To initialize GEO_TPSurf primitives, also call setUBasis and setVBasis
382  /// with the appropriate type of basis.
383  ///
384  /// NOTE: rows corresponds with v, and cols corresponds with u
386  void initHullData(int rows, int cols, bool wrapv, bool wrapu)
387  {
388  UT_ASSERT(myRows == 0 && myCols == 0);
389  UT_ASSERT(rows*exint(cols) == getVertexCount());
390  myRows = rows;
391  myCols = cols;
392  flags.wrapv = wrapv;
393  flags.wrapu = wrapu;
394  }
395 
396  // Subscript operators. The const version does not check the boundaries.
397  // For safer but slower use, call getVertex() and setVertex().
399  SYS_DEPRECATED_HDK(13.0)
400  const GEO_Vertex operator()(unsigned int r, unsigned int c) const
401  { return getVertexElement(r, c); }
402  SYS_DEPRECATED_HDK(13.0)
403  GEO_Vertex operator()(unsigned int r, unsigned int c)
404  { return getVertexElement(r, c); }
405 
407  SYS_DEPRECATED_HDK(13.0)
408  const GEO_Vertex getVertexElement(unsigned int r, unsigned int c) const;
409 
410 #if GA_PRIMITIVE_VERTEXLIST
412 #endif
413 
414  SYS_FORCE_INLINE GA_Offset getVertexOffset(unsigned int r, unsigned int c) const
415  {
416  UT_ASSERT_P(r < getNumRows() && c < getNumCols());
417  if (r >= getNumRows() || c >= getNumCols())
418  return GA_INVALID_OFFSET;
419 #if GA_PRIMITIVE_VERTEXLIST
420  return getVertexOffset(r*exint(myCols) + c);
421 #else
422  return myVertexMatx(r, c);
423 #endif
424  }
425  SYS_FORCE_INLINE GA_Index getVertexIndex(unsigned int r, unsigned int c) const
426  {
427  GA_Offset vtxoff = getVertexOffset(r, c);
428  return GAisValid(vtxoff) ? getDetail().vertexIndex(vtxoff)
430  }
431  SYS_FORCE_INLINE GA_Offset getPointOffset(unsigned int r, unsigned int c) const
432  {
433  if (r >= getNumRows() || c >= getNumCols())
434  {
435  UT_ASSERT(!"Invalid offset");
436  return GA_INVALID_OFFSET;
437  }
438 
439  return vertexPoint(r, c);
440  }
441  SYS_FORCE_INLINE GA_Index getPointIndex(unsigned int r, unsigned int c) const
442  {
443  GA_Offset ptoff = getPointOffset(r, c);
444  return GAisValid(ptoff) ? getDetail().pointIndex(ptoff)
446  }
447  SYS_FORCE_INLINE UT_Vector3 getPos3(unsigned int r, unsigned int c) const
448  { return getDetail().getPos3(getPointOffset(r, c)); }
449  SYS_FORCE_INLINE void setPos3(unsigned int r, unsigned int c, const UT_Vector3 &pos) const
450  { getDetail().setPos3(getPointOffset(r, c), pos); }
451  SYS_FORCE_INLINE UT_Vector4 getPos4(unsigned int r, unsigned int c) const
452  { return getDetail().getPos4(getPointOffset(r, c)); }
453  SYS_FORCE_INLINE void setPos4(unsigned int r, unsigned int c, const UT_Vector4 &pos) const
454  { getDetail().setPos4(getPointOffset(r, c), pos); }
455  SYS_FORCE_INLINE void setPointOffset(unsigned int r, unsigned int c, GA_Offset ptoff) const
457 
459  {
460  return exint(getNumRows()) * exint(getNumCols());
461  }
462  void setVertexPoint(unsigned int r, unsigned int c, GA_Offset pt)
463  {
464  if (r >= getNumRows() || c >= getNumCols())
465  return;
466 
467  setPointOffset(r, c, pt);
468  }
469 
470 #if !GA_PRIMITIVE_VERTEXLIST
471  void beginVertex(const_iterator &i) const override;
472  void nextVertex(const_iterator &i) const override;
473 #endif
474 
475  GEO_SurfaceType getSurfaceType() const { return surfaceType; }
476  void setSurfaceType(GEO_SurfaceType t) { surfaceType = t; }
477 
478  /// @{
479  /// Get or set the surface type by name token
480  const char *getSurfaceTypeName() const;
481  bool setSurfaceTypeName(const char *name);
482  /// @}
483 
484  bool isWrappedU() const { return flags.wrapu; }
485  bool isWrappedV() const { return flags.wrapv; }
486 
487  /// @{
488  /// Convenience method to set wrapping based on intrinsic properties
489  bool setWrapU(bool dowrap);
490  bool setWrapV(bool dowrap);
491  /// @}
492 
493  virtual void wrapU(int rounded = 1, int preserveShape = 0);
494  virtual void openU(int preserveShape = 0, int safe = 0);
495  virtual void wrapV(int rounded = 1, int preserveShape = 0);
496  virtual void openV(int preserveShape = 0, int safe = 0);
497 
498  virtual bool isClampedU() const;
499  virtual bool isClampedV() const;
500 
501  // Assuming the hull is closed in u/v, "unroll" it so that the CVs that are
502  // shared to form a wrapped surface are made unique. Also, the hull becomes
503  // open. The base class method only flips the open flag. If the face is
504  // not closed, the method returns -1. Otherwise it returns 0.
505  virtual int unrollU(int append_pts = 1);
506  virtual int unrollV(int append_pts = 1);
507 
508  bool hasEdge(const GA_Edge &edge) const override;
509 
510  // Check degenerate condition by testing face area in u and v
511  bool isDegenerate() const override;
512 
513 #if !GA_PRIMITIVE_VERTEXLIST
514  bool vertexApply(bool (*apply)(GA_Offset vtx, void *),
515  void *data = nullptr) const override;
516 #endif
517 
518  void iterateEdges(GA_IterateEdgesFunc apply_func) const override;
519  void iterateEdgesByVertex(GA_IterateEdgesByVertexFunc apply_func) const override;
520 
521 #if !GA_PRIMITIVE_VERTEXLIST
522  GA_Size getVertexCount() const override;
523  GA_Offset getVertexOffset(GA_Size index) const override;
524 #endif
525 
526  /// return the index of a vertex within our vertex list
527 #if GA_PRIMITIVE_VERTEXLIST
528  GA_Size findVertex(GA_Offset vtx) const { return myVertexList.find(vtx); }
529 #else
530  GA_Size findVertex(GA_Offset vtx) const { return myVertexMatx.find(vtx); }
531 #endif
532 
533  // Have we been deactivated and stashed?
534  virtual void stashed(bool beingstashed,
535  GA_Offset offset = GA_INVALID_OFFSET) override;
536 
537  // Raise the number of CVs to match the newcount. The shape of the face
538  // (especially if parametric) should NOT change. Return 0 upon success
539  // and -1 otherwise. start and stop define which indices to examine
540  // if newcount is negative it is taken as a relative value.
541  virtual int loftU(int newcount, int start=-1, int stop=-1) = 0;
542  virtual int loftV(int newcount, int start=-1, int stop=-1) = 0;
543 
544 
545  // Convert the real domain values of the primitive to unit values to be
546  // used in the common evaluation methods:
547  void realToUnitPair(float ureal, float vreal,
548  float &uunit, float &vunit) const override;
549  // and vice versa
550  void unitToRealPair(float uunit, float vunit,
551  float &ureal, float &vreal) const override;
552 
553  // Go from a normalized domain ([0,1]) to the real domain or vice versa.
554  // In the base class (i.e. here) the real domain ranges from 0 to
555  // vertexcount - 1 + isWrapped() for u and v respectively.
556  virtual void unitToRealDomain(float u_unit, float v_unit,
557  float &u_real, float &v_real) const;
558  virtual void realToUnitDomain(float u_real, float v_real,
559  float &u_unit, float &v_unit) const;
560 
561  // Calculate the real domains for n consecutive operations on the domain
562  // given n normalized domains and the operation
563 
564  virtual void unitToRealSequenceU(float *uunit, float *ureal,
565  int ulen) const;
566  virtual void unitToRealSequenceV(float *vunit, float *vreal,
567  int vlen) const;
568 
569  // Finds the vertex#'s of the end points of an edge.
570  // returns 0 if it fails (the edge is not on the hull) , 1 if it succeeds
571  virtual int findEdgePoints(const GA_Edge &edge,
572  int *pr0, int *pc0,
573  int *pr1, int *pc1) const;
574 
575  virtual int findEdgePoints(GA_Offset a, GA_Offset b,
576  int *pr0, int *pc0,
577  int *pr1, int *pc1) const;
578 
579  // This method fills the horizontal and vertical edge matrices
580  // based on the input linked list. An element of the matrix is
581  // non-zero if one of the selected edges exists on that spot on the
582  // hull, and zero otherwise. It returns 0 if no edges are on the hull,
583  // and 1 if at least one edge matches.
584  int makeEdgeMatrix(const GA_EdgeGroup &edges,
585  GEO_SubHull &subhull);
586 
587  // Append n points equally spaced between the 1st and last vertex.
588  void sampleEndsU(int n);
589  void sampleEndsV(int n);
590 
591  // Return the bounds of the valid evaluation interval in domain space:
592  // For meshes this refers to cv indices.
593  virtual void validURange(float &ua, float &ub) const;
594  virtual void validVRange(float &va, float &vb) const;
595  virtual void validUInterval(int &a, int &b) const;
596  virtual void validVInterval(int &a, int &b) const;
597 
598  // Find enclosing integral values(c1, c2) which validly enclose c
599  // and return the distance to c1
600  float getIndices(float c, int &c1, int &c2,
601  int maxIndex, int wrap) const;
602 
603  // Reverse the roles of rows and columns
604  virtual void transpose();
605 
606  // Return the surrounding values of the real-space u,v parameters.
607  // Returns 1 if succesful, 0 if out-of-range.
608  int parametricBBox(float u, float v,
609  float *u0, float *u1,
610  float *v0, float *v1) override;
611 
612  // Find distance in parameter space, aware of wrapping.
613  float uvDist(float u1, float v1, float u2, float v2) const override;
614 
615  virtual void weights(unsigned short onOff);
616 
617  fpreal calcVolume(const UT_Vector3 &refpt) const override;
618  fpreal calcArea() const override;
619  fpreal calcPerimeter() const override;
620 
621  static const inline UT_Vector3 quadNormal(
622  const UT_Vector3 &p1, const UT_Vector3 &p2,
623  const UT_Vector3 &p3, const UT_Vector3 &p4)
624  {
625  UT_Vector3 nml(0, 0, 0);
626  nml.normal(p1, p2);
627  nml.normal(p2, p3);
628  nml.normal(p3, p4);
629  nml.normal(p4, p1);
630 
631  nml.normalize();
632  return nml;
633  }
634 
635  /// This is a wrapper for a single quad of a GEO_Hull, so that
636  /// it can be treated like a GEO_PrimPoly in a template.
637  class Poly {
638  public:
639  Poly(const GEO_Hull &hull, const exint row, const exint col)
640  : myHull(hull)
641  , myRow(row)
642  , myCol(col)
643  , myRowP1((row+1 == hull.getNumRows()) ? 0 : (row+1))
644  , myColP1((col+1 == hull.getNumCols()) ? 0 : (col+1))
645  {}
647  { return 4; }
649  { return myHull.getVertexOffset((i >= 2) ? myRowP1 : myRow, (i==1 || i==2) ? myColP1 : myCol); }
651  { return myHull.getPointOffset((i >= 2) ? myRowP1 : myRow, (i==1 || i==2) ? myColP1 : myCol); }
653  { return myHull.getPos3((i >= 2) ? myRowP1 : myRow, (i==1 || i==2) ? myColP1 : myCol); }
655  { return true; }
656  float calcArea() const
657  {
658  UT_Vector3 p[4];
659  for (GA_Size i = 0; i < getFastVertexCount(); ++i)
660  p[i] = getPos3(i);
661  float area = cross(p[0]-p[1],p[2]-p[1]).length()
662  + cross(p[0]-p[3],p[2]-p[3]).length();
663  area *= 0.5f;
664  return area;
665  }
666  private:
667  const GEO_Hull &myHull;
668  const exint myRow;
669  const exint myRowP1;
670  const exint myCol;
671  const exint myColP1;
672  };
673 
674 protected:
675 #if !GA_PRIMITIVE_VERTEXLIST
676  void clearForDeletion() override;
677 #endif
678 
679  void cycleOffsetListRows(int shift);
680  void cycleOffsetListCols(int shift);
681 
683  { return GEO_FAMILY_HULL; }
684 
685  // Declare intrinsic attribute functions
686  GA_DECLARE_INTRINSICS(override);
687 
688  // The following three methods are used by removeEdges to
689  // remove all possible selected edges from a hull.
690 
691  // This computes where the hull needs to be split, recursing downwards
692  // if necessary. It calls getSubHull to split the hulls. Returns 1 if
693  // the hull needs to be deleted as a result of breaking.
694  int breakHull(GEO_SubHull &subhull,
695  int top, int left, int bottom, int right,
696  GEO_SubHullFlags break_flags);
697 
698  // This figures out which edges were actually used in the edge deletion.
699  // It returns 1 if all the selected edges were used, 0 if some were not
700  int checkUsedEdges(UT_BitArray *remove_edges,
701  const GEO_SubHull &subhull);
702 
703  // Implemented in GU. Gets a part of this hull, creating a new one
704  // if break_flags.recurse is set.
705  virtual GEO_Hull *getSubHull(int top, int left, int bottom, int right,
706  GEO_SubHullFlags break_flags) = 0;
707 
708  // Speacial save and load methods for the sub-classes:
709  virtual bool savePrivateH9(std::ostream &os, bool binary) const = 0;
710  virtual bool loadPrivateH9(UT_IStream &is) = 0;
711  virtual bool saveExtraH9 (std::ostream &os, bool binary) const = 0;
712  virtual bool loadExtraH9 (UT_IStream &is) = 0;
713 
714  // Check the validity of the data. Meant to be called especially at loading
715  // time. The method returns 1 if OK and 0 if trouble.
716  virtual bool validate(void) const = 0;
717 
718  // Clip or wrap c to find enclosing integral values(c1, c2)
719  // and return the distance to c1
720  float getLRIndex(float c, int &c1, int &c2,
721  int minIndex, int maxIndex, int wrap) const;
722 
723  /// @warning vertexPoint() doesn't check the bounds. Use with caution.
725  {
726  UT_ASSERT_P(r < getNumRows() && c < getNumCols());
727 #if GA_PRIMITIVE_VERTEXLIST
728  return getDetail().vertexPoint(getVertexOffset(r*exint(myCols) + c));
729 #else
730  return getDetail().vertexPoint(myVertexMatx(r,c));
731 #endif
732  }
733 
734 #if !GA_PRIMITIVE_VERTEXLIST
735  /// Defragmentation
736  void swapVertexOffsets(const GA_Defragment &defrag) override;
737 #endif
738 
739 #if GA_PRIMITIVE_VERTEXLIST
741  GA_Size matrixIndex(int r, int c) const
742  {
743  UT_ASSERT_P(r < getNumRows() && c < getNumCols());
744  return r*exint(myCols) + c;
745  }
746 
747  int myRows;
748  int myCols;
749 #else
751 #endif
754 
755  bool evaluateBaryCenterRefMap(GA_Offset result_vertex,
756  GA_AttributeRefMap &map) const override;
757 
758  // Evaluate one point (when du=dv=0), or the du-th dv-th derivative.
759  // Return 0 if successful, and -1 otherwise.
760  virtual bool evaluateIndexRefMap(fpreal u, fpreal v, GA_Offset result_vtx,
761  GA_AttributeRefMap &hlist,
762  unsigned du, unsigned dv) const;
763  virtual int evaluateIndexV4(float iu, float iv, UT_Vector4 &pos,
764  unsigned du=0, unsigned dv=0) const;
765 
766  virtual int subdivideURefMap(float u, GA_AttributeRefMap &map);
767  virtual int subdivideUFloat(float u);
768  virtual int subdivideVRefMap(float u, GA_AttributeRefMap &map);
769  virtual int subdivideVFloat(float u);
770 
771  // Refine numdivs times in each span.
772  virtual void spanRefineURefMap(GA_AttributeRefMap &map,
773  int numdivs=1) = 0;
774  virtual void spanRefineUInt( int numdivs=1) = 0;
775  virtual void spanRefineVRefMap(GA_AttributeRefMap &map,
776  int numdivs=1) = 0;
777  virtual void spanRefineVInt( int numdivs=1) = 0;
778 
779  virtual int unrefineURefMap(int kidx, GA_AttributeRefMap &h,
780  int mult=0, float tol=1e-4f,
781  GA_PointGroup *delgroup=0);
782  virtual int unrefineUFloat(int kidx, int mult = 0,
783  float tol = 1e-4F,
784  GA_PointGroup *delgroup = 0);
785  virtual int unrefineVRefMap(int kidx, GA_AttributeRefMap &h,
786  int mult=0, float tol=1e-4f,
787  GA_PointGroup *delgroup=0);
788  virtual int unrefineVFloat(int kidx, int mult = 0,
789  float tol = 1e-4F,
790  GA_PointGroup *delgroup = 0);
791 
792 #if !GA_PRIMITIVE_VERTEXLIST
793  /// Report approximate memory usage for myVertexMatx (exclusive)
794  int64 getBaseMemoryUsage() const;
795 
796  // This is called by the subclasses to count the
797  // memory used by myVertexMatx (exclusive)
799 #endif
800 
801 private:
802  friend std::ostream &operator<<(std::ostream &os, const GEO_Hull &d)
803  {
804  d.saveH9(os, 0,
807  return os;
808  }
809  void increaseDensityInRows(GA_AttributeRefMap &m,
810  int numdivs, GA_PointGroup *pgp);
811  void increaseDensityInCols(GA_AttributeRefMap &m,
812  int numdivs, GA_PointGroup *pgp);
814 };
816 #endif
bool isWrappedU() const
Definition: GEO_Hull.h:484
SYS_FORCE_INLINE void setPos3(unsigned int r, unsigned int c, const UT_Vector3 &pos) const
Definition: GEO_Hull.h:449
GLbyte * weights
Definition: glew.h:7551
ImageBuf OIIO_API warp(const ImageBuf &src, const Imath::M33f &M, string_view filtername=string_view(), float filterwidth=0.0f, bool recompute_roi=false, ImageBuf::WrapMode wrap=ImageBuf::WrapDefault, ROI roi={}, int nthreads=0)
SYS_FORCE_INLINE void setPos3(GA_Offset ptoff, const UT_Vector3 &P)
Set P from a UT_Vector3.
Definition: GA_Detail.h:207
virtual GEO_Primitive * copy(int preserve_shared_pts=0) const
bool findEdgePoints(GA_Offset ptoff0, GA_Offset ptoff1, GA_Size &vtx0, GA_Size &vtx1) const
static const UT_Vector3 quadNormal(const UT_Vector3 &p1, const UT_Vector3 &p2, const UT_Vector3 &p3, const UT_Vector3 &p4)
Definition: GEO_Hull.h:621
void spanRefineU(GA_AttributeRefMap &map, int numdivs=1)
Definition: GEO_Hull.h:320
SYS_FORCE_INLINE GA_Offset getPointOffset(GA_Size i) const
Definition: GA_Primitive.h:246
virtual UT_Vector3 baryCenter() const
GLenum src
Definition: glew.h:2410
SYS_FORCE_INLINE GA_Detail & getDetail() const
Definition: GA_Primitive.h:133
virtual void copyPrimitive(const GEO_Primitive *src)=0
SYS_FORCE_INLINE GA_Index getVertexIndex(unsigned int r, unsigned int c) const
Definition: GEO_Hull.h:425
bool isWrappedV() const
Definition: GEO_Hull.h:485
virtual void clearForDeletion()
Definition: GA_Primitive.h:641
GLuint const GLchar * name
Definition: glew.h:1814
Used to pass options and map offset values during saving.
Definition: GA_SaveMap.h:48
void spanRefineU(int numdivs=1)
Definition: GEO_Hull.h:323
SYS_FORCE_INLINE GA_Size getVertexCount() const
Return the number of vertices used by this primitive.
Definition: GA_Primitive.h:224
int unrefineU(int kidx, GA_AttributeRefMap &h, int mult=0, float tol=1e-4f, GA_PointGroup *delgroup=0)
Definition: GEO_Hull.h:333
GA_OffsetMatrix myVertexMatx
Definition: GEO_Hull.h:750
GEO_Vertex getVertexElement(GA_Size i) const
virtual void computeInteriorPointWeights(UT_Array< GA_Offset > &vtxlist, UT_Array< float > &weightlist, fpreal u, fpreal v, fpreal w) const
GLuint index
Definition: glew.h:1814
GLuint GLdouble u1
Definition: glew.h:3446
GLint left
Definition: glew.h:8008
#define SYS_DEPRECATED_PUSH_DISABLE()
UT_Vector4 getPos4(GA_Offset ptoff) const
The ptoff passed is the point offset.
Definition: GA_Detail.h:252
#define SYS_DEPRECATED_POP_DISABLE()
virtual void copySubclassData(const GA_Primitive *source)
Definition: GA_Primitive.h:476
bool GAisValid(GA_Size v)
Definition: GA_Types.h:645
SYS_FORCE_INLINE GA_Size getFastVertexCount() const
Definition: GEO_Hull.h:458
int unrefineU(int kidx, int mult=0, float tol=1e-4F, GA_PointGroup *delgroup=0)
Definition: GEO_Hull.h:338
GLboolean GLboolean GLboolean GLboolean a
Definition: glew.h:9477
GLenum GLsizei GLsizei GLsizei GLsizei GLbitfield flags
Definition: glew.h:2864
static GA_PrimitiveFamilyMask buildFamilyMask()
Definition: GEO_Hull.h:682
SYS_FORCE_INLINE GA_Size getFastVertexCount() const
Definition: GEO_Hull.h:646
GEO_SurfaceType surfaceType
Definition: GEO_Hull.h:753
SYS_FORCE_INLINE void setPointOffset(GA_Size i, GA_Offset ptoff)
Definition: GA_Primitive.h:252
SYS_FORCE_INLINE GA_Offset getVertexOffset(unsigned int r, unsigned int c) const
Definition: GEO_Hull.h:414
SYS_FORCE_INLINE GA_Index getPointIndex(unsigned int r, unsigned int c) const
Definition: GEO_Hull.h:441
SYS_FORCE_INLINE void initHullData(int rows, int cols, bool wrapv, bool wrapu)
Definition: GEO_Hull.h:386
int appendCol(bool appendPts=true)
Definition: GEO_Hull.h:220
GLsizei GLsizei GLchar * source
Definition: glew.h:1832
int h_rows
Definition: GEO_Hull.h:112
virtual GA_DereferenceStatus dereferencePoint(GA_Offset point, bool dry_run=false)=0
JSON reader class which handles parsing of JSON or bJSON files.
Definition: UT_JSONParser.h:75
#define GA_DECLARE_INTRINSICS(OVERRIDE)
Definition: GA_Primitive.h:80
SYS_FORCE_INLINE GA_Offset getPointOffset(unsigned int r, unsigned int c) const
Definition: GEO_Hull.h:431
const GLdouble * m
Definition: glew.h:9124
Class which writes ASCII or binary JSON streams.
Definition: UT_JSONWriter.h:32
SYS_FORCE_INLINE void setPos4(unsigned int r, unsigned int c, const UT_Vector4 &pos) const
Definition: GEO_Hull.h:453
Abstract base class for a range membership query object.
const GLdouble * v
Definition: glew.h:1391
SYS_FORCE_INLINE UT_Vector3 getPos3(GA_Offset ptoff) const
The ptoff passed is the point offset.
Definition: GA_Detail.h:174
SYS_FORCE_INLINE bool isClosed() const
Definition: GEO_Hull.h:654
int unrefineV(int kidx, int mult=0, float tol=1e-4F, GA_PointGroup *delgroup=0)
Definition: GEO_Hull.h:348
virtual int parametricBBox(float u, float v, float *u0, float *u1, float *v0, float *v1)
float calcArea() const
Definition: GEO_Hull.h:656
4D Vector class.
Definition: UT_Vector4.h:163
virtual void realToUnitPair(float ureal, float vreal, float &uunit, float &vunit) const
#define GEO_FAMILY_HULL
Definition: GEO_PrimType.h:74
virtual void swapVertexOffsets(const GA_Defragment &defrag)
exint GA_Size
Defines the bit width for index and offset types in GA.
Definition: GA_Types.h:231
SYS_FORCE_INLINE int64 getBaseMemoryUsage() const
Report approximate memory usage for myVertexList for subclasses.
Definition: GA_Primitive.h:796
SYS_FORCE_INLINE GA_Offset getPointOffset(GA_Size i) const
Definition: GEO_Hull.h:650
virtual bool loadH9(UT_IStream &is, const UT_Array< GA_AttribLoadDataH9 > &prim_attribs, const UT_Array< GA_AttribLoadDataH9 > &vtx_attribs)
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
virtual UT_Vector3 computeNormal() const =0
Return a normal vector for the primitive.
#define GA_INVALID_OFFSET
Definition: GA_Types.h:674
virtual void normal(NormalComp &output) const =0
bool evaluateIndex(fpreal u, fpreal v, GA_Offset result_vtx, GA_AttributeRefMap &hlist, unsigned du, unsigned dv) const
Definition: GEO_Hull.h:148
GEO_SurfaceType getSurfaceType() const
Definition: GEO_Hull.h:475
virtual bool isDegenerate() const =0
Is the primitive degenerate.
GA_Size GA_Offset
Definition: GA_Types.h:637
vint4 blend(const vint4 &a, const vint4 &b, const vbool4 &mask)
Definition: simd.h:4648
long long int64
Definition: SYS_Types.h:111
Poly(const GEO_Hull &hull, const exint row, const exint col)
Definition: GEO_Hull.h:639
GLint GLint bottom
Definition: glew.h:8008
GLfloat GLfloat GLfloat v2
Definition: glew.h:1856
void wireVertexPoint(GA_Offset vtx, GA_Offset pt)
int v_rows
Definition: GEO_Hull.h:111
GLclampf f
Definition: glew.h:3499
int subdivideU(float u)
Definition: GEO_Hull.h:253
SIM_DerScalar length() const
friend std::ostream & operator<<(std::ostream &os, const GEO_Hull &d)
Definition: GEO_Hull.h:802
virtual fpreal calcArea() const
int64 exint
Definition: SYS_Types.h:120
GLint GLenum GLsizei GLint GLsizei const void * data
Definition: glew.h:1379
#define UT_ASSERT_P(ZZ)
Definition: UT_Assert.h:134
const GLuint GLenum const void * binary
Definition: glew.h:3502
int evaluateIndex(float iu, float iv, UT_Vector4 &pos, unsigned du=0, unsigned dv=0) const
Definition: GEO_Hull.h:152
GLfloat GLfloat GLfloat top
Definition: glew.h:15186
SYS_FORCE_INLINE int getNumRows() const
Definition: GEO_Hull.h:364
#define SYS_FORCE_INLINE
Definition: SYS_Inline.h:45
GLubyte GLubyte GLubyte GLubyte w
Definition: glew.h:1890
bool operator==(const GEO_SubHullPart &p) const
Definition: GEO_Hull.h:95
GLsizei n
Definition: glew.h:4040
const GLfloat * c
Definition: glew.h:16296
GLsizei GLsizei GLfloat distance
Definition: glew.h:13640
int appendRow(bool appendPts=true)
Definition: GEO_Hull.h:211
#define GEO_API
Definition: GEO_API.h:14
std::function< bool(const GA_Edge &edge)> GA_IterateEdgesFunc
Definition: GA_Primitive.h:73
void setVertexPoint(unsigned int r, unsigned int c, GA_Offset pt)
Definition: GEO_Hull.h:462
virtual void reverse()=0
Reverse the order of vertices.
A handle to simplify manipulation of multiple attributes.
virtual void iterateEdges(GA_IterateEdgesFunc apply_func) const
Definition: GA_Primitive.h:339
SYS_FORCE_INLINE GA_Index vertexIndex(GA_Offset offset) const
Given a vertex's data offset, return its index.
Definition: GA_Detail.h:470
Options during loading.
Definition: GA_LoadMap.h:42
virtual int getBBox(UT_BoundingBox *bbox) const =0
virtual float uvDist(float u1, float v1, float u2, float v2) const
Defragmentation of IndexMaps.
Definition: GA_Defragment.h:45
SYS_FORCE_INLINE GA_Offset vertexPoint(GA_Offset vertex) const
Given a vertex, return the point it references.
Definition: GA_Detail.h:480
void addPointRefToGroup(GA_PointGroup &grp) const
GLfloat GLfloat GLfloat GLfloat h
Definition: glew.h:8011
GLfloat bias
Definition: glew.h:10274
#define SYS_DEPRECATED_HDK(__V__)
GLfloat right
Definition: glew.h:15186
std::function< bool(GA_Size, GA_Size)> GA_IterateEdgesByVertexFunc
Definition: GA_Primitive.h:74
bool operator!=(const GEO_SubHullPart &p) const
Definition: GEO_Hull.h:101
GA_Size GA_Index
Define the strictness of GA_Offset/GA_Index.
Definition: GA_Types.h:631
virtual fpreal calcPerimeter() const
virtual GA_DereferenceStatus dereferencePoints(const GA_RangeMemberQuery &pt_q, bool dry_run=false)=0
virtual bool saveH9(std::ostream &os, bool binary, const UT_Array< GA_AttribSaveDataH9 > &prim_attribs, const UT_Array< GA_AttribSaveDataH9 > &vtx_attribs) const
void spanRefineV(int numdivs=1)
Definition: GEO_Hull.h:328
GLuint start
Definition: glew.h:1253
GA_Topology & getTopology()
Definition: GA_Detail.h:741
virtual bool evaluateBaryCenterRefMap(GA_Offset result_vtx, GA_AttributeRefMap &map) const
SYS_FORCE_INLINE GA_Index pointIndex(GA_Offset offset) const
Given a point's data offset, return its index.
Definition: GA_Detail.h:300
GLdouble GLdouble GLdouble b
Definition: glew.h:9122
GLfloat GLfloat p
Definition: glew.h:16321
virtual bool vertexApply(bool(*apply)(GA_Offset vtx, void *), void *data=0) const
double fpreal
Definition: SYS_Types.h:276
int subdivideU(float u, GA_AttributeRefMap &map)
Definition: GEO_Hull.h:251
void spanRefineV(GA_AttributeRefMap &map, int numdivs=1)
Definition: GEO_Hull.h:325
virtual int detachPoints(GA_PointGroup &grp)=0
SYS_FORCE_INLINE GA_Offset vertexPoint(GA_Size r, GA_Size c) const
Definition: GEO_Hull.h:724
GLuint counter
Definition: glew.h:2740
static const UT_Array< GA_AttribSaveDataH9 > & theEmptySaveAttribs
Convience objects to pass as arguments to saveH9()/loadH9().
virtual bool hasEdge(const GA_Edge &edge) const
Method to determine if a primitive has an edge (undirected).
int d_rows
Definition: GEO_Hull.h:113
virtual void unitToRealPair(float uunit, float vunit, float &ureal, float &vreal) const
SYS_FORCE_INLINE UT_Vector3 getPos3(unsigned int r, unsigned int c) const
Definition: GEO_Hull.h:447
GLdouble GLdouble GLdouble r
Definition: glew.h:1406
virtual fpreal calcVolume(const UT_Vector3 &) const
virtual int evaluateNormalVector(UT_Vector3 &nml, float u, float v=0, float w=0) const
SYS_FORCE_INLINE GA_Offset getVertexOffset(GA_Size primvertexnum) const
Definition: GA_Primitive.h:232
GLfloat v0
Definition: glew.h:1848
#define GA_INVALID_INDEX
Definition: GA_Types.h:673
#define GA_PRIMITIVE_VERTEXLIST
Definition: GA_Primitive.h:16
SYS_FORCE_INLINE Storage::MathFloat normalize()
virtual void addToBSphere(UT_BoundingSphere *bsphere) const
SYS_FORCE_INLINE void setPointOffset(unsigned int r, unsigned int c, GA_Offset ptoff) const
Definition: GEO_Hull.h:455
GEO_SurfaceType
GLuint GLdouble GLdouble u2
Definition: glew.h:3446
SYS_FORCE_INLINE UT_Vector3 getPos3(GA_Size i) const
Definition: GEO_Hull.h:652
Container class for all geometry.
Definition: GA_Detail.h:95
#define UT_ASSERT(ZZ)
Definition: UT_Assert.h:135
if(rank==1) return rank
SYS_FORCE_INLINE int getNumCols() const
Definition: GEO_Hull.h:371
int unrefineV(int kidx, GA_AttributeRefMap &h, int mult=0, float tol=1e-4f, GA_PointGroup *delgroup=0)
Definition: GEO_Hull.h:343
#define const
Definition: zconf.h:214
SYS_FORCE_INLINE void normal(const UT_Vector3T< T > &va, const UT_Vector3T< T > &vb)
Definition: UT_Vector3.h:383
GLenum GLenum void * row
Definition: glew.h:4965
void countBaseMemory(UT_MemoryCounter &counter) const
UT_RefMatrix< GEO_SubHullPart > mat
Definition: GEO_Hull.h:110
SIM_DerVector3 cross(const SIM_DerVector3 &lhs, const SIM_DerVector3 &rhs)
GLdouble GLdouble t
Definition: glew.h:1398
GLfloat GLfloat v1
Definition: glew.h:1852
virtual void iterateEdgesByVertex(GA_IterateEdgesByVertexFunc apply_func) const
Definition: GA_Primitive.h:349
void setPos4(GA_Offset ptoff, const UT_Vector4 &P)
Set P from a UT_Vector4.
Definition: GA_Detail.h:258
GA_Size findVertex(GA_Offset vtx) const
return the index of a vertex within our vertex list
Definition: GEO_Hull.h:530
SYS_FORCE_INLINE UT_Vector4 getPos4(unsigned int r, unsigned int c) const
Definition: GEO_Hull.h:451
GEO_Hull(GA_Detail *d, GA_Offset offset=GA_INVALID_OFFSET)
Definition: GEO_Hull.h:121
virtual void stashed(bool beingstashed, GA_Offset offset=GA_INVALID_OFFSET)
int subdivideV(float u)
Definition: GEO_Hull.h:257
int subdivideV(float u, GA_AttributeRefMap &map)
Definition: GEO_Hull.h:255
GA_API const UT_StringHolder area
GEO_HullFlags flags
Definition: GEO_Hull.h:752
void setSurfaceType(GEO_SurfaceType t)
Definition: GEO_Hull.h:476
SYS_FORCE_INLINE GA_Offset getFastVertexOffset(GA_Size i) const
Definition: GEO_Hull.h:648
GLsizei GLboolean transpose
Definition: glew.h:1864
GLintptr offset
Definition: glew.h:1682