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