HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
GA_Primitive.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: GA_Primitive.h (GA Library, C++)
7  *
8  * COMMENTS: Interface for primitives.
9  */
10 
11 #pragma once
12 
13 #ifndef __GA_Primitive__
14 #define __GA_Primitive__
15 
16 #define GA_PRIMITIVE_VERTEXLIST 1
17 
18 #include "GA_API.h"
19 #include "GA_Detail.h"
20 #include "GA_IntrinsicManager.h"
21 #include "GA_OffsetList.h"
22 #include "GA_PrimCompat.h"
23 #include "GA_PrimitiveDefinition.h"
24 #include "GA_PrimitiveFamilyMask.h"
25 #include "GA_PrimitiveTypeId.h"
26 #include "GA_SharedDataHandle.h"
27 #include "GA_SharedLoadData.h"
28 #include "GA_Range.h"
29 #include "GA_Topology.h"
30 #include "GA_Types.h"
31 
32 #include <UT/UT_BoundingBox.h>
33 #include <UT/UT_BoundingRect.h>
34 #include <UT/UT_NonCopyable.h>
35 #include <UT/UT_VectorTypes.h>
36 #include <SYS/SYS_Inline.h>
37 #include <SYS/SYS_Types.h>
38 
39 #include <functional>
40 #include <iosfwd>
41 #include <stddef.h>
42 
45 class GA_Attribute;
46 class GA_Defragment;
47 class GA_Detail;
48 class GA_IntrinsicEval;
49 class GA_MergeMap;
50 class GA_PrimitiveJSON;
51 class GA_PrimitiveList;
53 class GA_GeometryIndex;
54 
55 class UT_BoundingSphere;
56 class UT_IStream;
57 class UT_MemoryCounter;
58 class UT_Options;
59 class UT_String;
60 class UT_StringArray;
61 template <typename T> class UT_Array;
62 
63 template<typename T, bool B> class GA_EdgeT;
65 
66 
67 class GA_Primitive;
68 typedef void (* GA_EdgeApplyFunc)(const GA_Primitive &prim,
69  GA_Offset pt_a, GA_Offset pt_b, void *data);
70 typedef void (* GA_EdgeApplyIndexFunc)(const GA_Primitive &prim,
71  GA_Size v1, GA_Size v2, void *data);
72 
73 using GA_IterateEdgesFunc = std::function<bool(const GA_Edge &edge)>;
74 using GA_IterateEdgesByVertexFunc = std::function<bool(GA_Size, GA_Size)>;
75 
76 #define GA_NO_OVERRIDE
77 
78 /// Declare intrinsic callback functions in header file. See
79 /// GA_IntrinsicMacros.h for macros to help implement intrinsics.
80 #define GA_DECLARE_INTRINSICS(OVERRIDE) \
81  static GA_IntrinsicManager::Registrar \
82  registerIntrinsics(GA_PrimitiveDefinition &); \
83  virtual GA_Size localIntrinsicTupleSize(const GA_IntrinsicEval &) const \
84  OVERRIDE; \
85  virtual GA_Size localGetIntrinsicI(const GA_IntrinsicEval &, \
86  int64 *, GA_Size) const OVERRIDE; \
87  virtual GA_Size localGetIntrinsicF(const GA_IntrinsicEval &, \
88  fpreal64 *, GA_Size) const OVERRIDE; \
89  virtual GA_Size localGetIntrinsicS(const GA_IntrinsicEval &, \
90  UT_String &) const OVERRIDE; \
91  virtual GA_Size localGetIntrinsicSA(const GA_IntrinsicEval &, \
92  UT_StringArray &) const OVERRIDE; \
93  virtual GA_Size localSetIntrinsicI(const GA_IntrinsicEval &, \
94  const int64 *, GA_Size) OVERRIDE; \
95  virtual GA_Size localSetIntrinsicF(const GA_IntrinsicEval &, \
96  const fpreal64 *, GA_Size) OVERRIDE; \
97  virtual GA_Size localSetIntrinsicSS(const GA_IntrinsicEval &, \
98  const char **, GA_Size) OVERRIDE; \
99  virtual GA_Size localSetIntrinsicSA(const GA_IntrinsicEval &, \
100  const UT_StringArray &) OVERRIDE;
101 
103 {
104 protected:
105  /// NOTE: The constructor should only be called from subclass
106  /// constructors.
109  : myDetail(&detail)
110  , myOffset(offset)
111  {}
112 
113 public:
114  /// NOTE: The destructor should only be called from subclass
115  /// destructors; only GA_PrimitiveList should be calling
116  /// delete on GA_Primitive pointers.
117  virtual ~GA_Primitive()
118  {
119  // The detail should have already deleted the vertices, and
120  // myVertexList is automatically cleaned up in its destructor.
121  }
122 
123  virtual const GA_PrimitiveDefinition &getTypeDef() const = 0;
124 
125  const char *getTypeName() const
126  { return getTypeDef().getToken(); }
127 
128  /// Gets the detail containing this primitive.
129  ///
130  /// FIXME: This should return a const detail, and a non-const version should
131  /// return a non-const detail.
134  { return *myDetail; }
135 
136  /// Gets the offset of this primitive in the detail containing it.
139  { return myOffset; }
140 
141  /// Gets the index of this primitive in the detail containing it.
144  { return myDetail->primitiveIndex(myOffset); }
145 
146  /// Gets the index map for primitives in the detail containing this primitive.
148  const GA_IndexMap &getIndexMap() const
149  { return myDetail->getPrimitiveMap(); }
150 
151  SYS_DEPRECATED_HDK(13.0)
152  GA_Index getNum() const
153  { return getMapIndex(); }
154 
155  /// For defragmentation, we need to update the offset
156  void swapOffsetValue(const GA_Defragment &defrag);
157 
158  /// Returns true if the primitive is part of a 3D geometry detail
159  /// (GEO_Detail), and false if it is part of a 2D geometry detail
160  /// (GD_Detail) for trim/projection curves.
161  bool isPrimary() const
162  { return myDetail->isPrimary(); }
163 
164  // FIXME: Switch this back to SYS_FORCE_INLINE when Microsoft fixes
165  // Visual Studio bug report ID 2154929.
166  // It seems to be fixed in Update 3, so I updated the define,
167  // but we haven't switched our builds over yet from Update 1.
170  { return getTypeDef().getId(); }
172  { return getTypeDef().getFamilyMask(); }
173  bool isFamily(unsigned family_mask) const
174  { return ((getFamilyMask() & family_mask) != 0); }
175 
176  /// Whether the primitive has a transform associated with it
177  bool hasLocalTransform() const
178  { return getTypeDef().hasLocalTransform(); }
179  /// Return the local transform matrix for the primitive. Some primitives
180  /// don't store transforms (see @c hasLocalTransform()). The default
181  /// behaviour is to make the transform an identity.
182  virtual void getLocalTransform(UT_Matrix3D &matrix) const;
183 
184  /// Return the local transform matrix for the primitive, but with the
185  /// translates specified by the position of the first vertex of the
186  /// primitive. This only includes the local transform and the translate
187  /// due to the point position.
188  virtual void getLocalTransform4(UT_Matrix4D &matrix) const;
189 
190  /// Set the local transform. The default implementation does nothing.
191  virtual void setLocalTransform(const UT_Matrix3D &matrix);
192 
193  /// @deprecated This method is only for transitional backward compatibility
194  /// for the HDK and will be removed in a future release.
195  /// TODO: Should be pure virtual here, overwritten at GEO_Primitive.
197  { return primCompatMaskFromTypeId(getTypeId().get()); }
198 
199  /// Report approximate memory usage, including sizeof(*this) and
200  /// any shared memory.
201  virtual int64 getMemoryUsage() const
202  {
203  return sizeof(*this) + getBaseMemoryUsage();
204  }
205 
206  /// Count memory usage using a UT_MemoryCounter in order to count
207  /// shared memory correctly.
208  /// NOTE: This should always include sizeof(*this).
209  virtual void countMemory(UT_MemoryCounter &counter) const;
210 
211  /// @{
212  /// This method is called when the vertex index map is being defragmented.
213  /// Since the defragmentation process moves vertex offsets, primitives need
214  /// to update their references with the new values. @code
215  /// new_vtx_offset = defrag.mapOffset(new_vtx_offset);
216  /// myOffsetList.swapOffsetValues(defrag);
217  /// myOffsetMatrix.swapOffsetValues(defrag);
218  /// @endcode
219  virtual void swapVertexOffsets(const GA_Defragment &defrag);
220  /// @}
221 
222  /// Return the number of vertices used by this primitive
225  {
226  return myVertexList.size();
227  }
228 
229  /// Given an vertex number (into the primitive's vertex list), return the
230  /// vertex offset.
232  GA_Offset getVertexOffset(GA_Size primvertexnum) const
233  {
234  UT_ASSERT_P(primvertexnum >= 0 && primvertexnum < myVertexList.size());
235  return myVertexList.get(primvertexnum);
236  }
238  GA_Index getVertexIndex(GA_Size primvertexnum) const
239  {
240  return getDetail().vertexIndex(getVertexOffset(primvertexnum));
241  }
242 
243  /// Given a vertex number (into the primitive's vertex list), return the
244  /// point offset.
247  { return getDetail().vertexPoint(getVertexOffset(i)); }
248 
249  /// Given a vertex number (into the primitive's vertex list), set the
250  /// corresponding point offset.
253  {
254  getDetail().getTopology().wireVertexPoint(getVertexOffset(i), ptoff);
255  }
256 
257  /// Given a vertex number (into the primitive's vertex list), return its
258  /// point index number.
261  { return getDetail().pointIndex(getPointOffset(i)); }
262 
263  /// Given a vertex number (into the primitive's vertex list), return its
264  /// point's position.
267  { return getDetail().getPos3(getPointOffset(i)); }
268 
269  /// Given a vertex number (into the primitive's vertex list),
270  /// move the point to the specified position.
272  void setPos3(GA_Size i, const UT_Vector3 &pos) const
273  { getDetail().setPos3(getPointOffset(i), pos); }
274 
275  /// Given a vertex number (into the primitive's vertex list), return its
276  /// point's position.
279  { return getDetail().getPos4(getPointOffset(i)); }
280 
281  /// Given a vertex number (into the primitive's vertex list),
282  /// move the point to the specified position.
284  void setPos4(GA_Size i, const UT_Vector4 &pos) const
285  { getDetail().setPos4(getPointOffset(i), pos); }
286 
287  /// Get a range of all the vertices accessed by the primitive
288  GA_Range getVertexRange(bool harden=false) const
289  {
290  return GA_Range(getDetail(), getMapOffset(),
292  harden);
293  }
294  /// Get a range of all the points accessed by the primitive. Note, the
295  /// range may visit points multiple times.
296  GA_Range getPointRange(bool harden=false) const
297  {
298  return GA_Range(getDetail(), getMapOffset(),
300  harden);
301  }
302 
303  /// Return whether a point is referenced by a primitive. This simply
304  /// iterates over the vertices, checking if any vertices reference the
305  /// point.
306  bool isPointUsed(GA_Offset ptoff) const
307  {
308  GA_Size nvtx = getVertexCount();
309  for (GA_Size i = 0; i < nvtx; ++i)
310  {
311  if (getPointOffset(i) == ptoff)
312  return true;
313  }
314  return false;
315  }
316 
317  /// Add all points referenced by the primitive to the given group. This
318  /// defaults to iterating over the vertices and adding their referenced
319  /// points.
320  void addPointRefToGroup(GA_PointGroup &grp) const;
321 
322  /// Method to determine if a primitive has an edge (undirected).
323  virtual bool hasEdge(const GA_Edge &edge) const;
324 
325 
326  /// Calls apply for each directed edge in this primitive
327  /// @deprecated Use @c iterateEdges instead.
328  SYS_DEPRECATED_HDK_REPLACE(16.0, iterateEdges)
329  void edgeApply(GA_EdgeApplyFunc apply, void *data = nullptr) const;
330 
331  /// Calls apply for each directed edge in this primitive
332  /// @deprecated Use @c iterateEdgesByVertex instead.
333  SYS_DEPRECATED_HDK_REPLACE(16.0, iterateEdgesByVertex)
334  void edgeApplyIndex(GA_EdgeApplyIndexFunc apply, void *data = nullptr) const;
335 
336  /// Calls @c apply_func for each directed edge on the primitive.
337  /// If the @c apply_func function returns @c false, then the
338  /// traversal will be stopped.
339  virtual void iterateEdges(GA_IterateEdgesFunc apply_func) const
340  {
341  // Default implementation does nothing.
342  // Re-implemented by relevant primitives.
343  }
344 
345  /// Calls @c apply_func for each directed edge on the primitive,
346  /// passing in the @c GA_Size primitive vertex index for each point on the
347  /// edge. If the @c apply_func function returns @c false, then the
348  /// traversal will be stopped.
349  virtual void iterateEdgesByVertex(GA_IterateEdgesByVertexFunc apply_func) const
350  {
351  // Default implementation does nothing.
352  // Re-implemented by relevant primitives.
353  }
354 
355  /// Calls edgeApplyIndex to find the vertices within this primitive,
356  /// corresponding with the first undirected edge between ptoff0 and ptoff1.
357  /// If the edge is not in this primitive, vtx0 and vtx1 will not be
358  /// written-to, and the function will return false.
359  /// When written, vtx0->vtx1 will always be the direction the edge
360  /// appears in this primitive, which may be *opposite* ptoff0->ptoff1.
361  bool findEdgePoints(GA_Offset ptoff0, GA_Offset ptoff1,
362  GA_Size &vtx0, GA_Size &vtx1) const;
363 
364  /// The return status of @c dereferencePoint()
365  /// - GA_DEREFERENCE_FAIL @n
366  /// The primitive cannot detach itself from the points and thus the
367  /// points cannot be deleted. It's possible that the primitive may be
368  /// destroyed in this case if the user specified this behaviour (see
369  /// GA_Detail::GA_DestroyPointMode).
370  /// - GA_DEREFERENCE_OK @n
371  /// The primitive has detached the points and is still valid.
372  /// - GA_DEREFERENCE_DEGENERATE @n
373  /// The primitive has detached the points but is now degenerate.
374  /// - GA_DEREFERENCE_DESTROY @n
375  /// The primitive has detached the points and should now be destroyed.
377  {
382  };
383  /// Before points are deleted, all primitives referencing the points will
384  /// be notified using @c dereferencePoint or @c dereferencePoints. These
385  /// methods should return the appropriate DeferefenceStatus.
386  /// @example
387  /// A quadric primitive will return
388  /// - GA_DEREFERENCE_OK @n
389  /// If it's point is not in the point group
390  /// - GA_DEREFERENCE_DESTROY @n
391  /// If it destroyed its vertex
392  /// A hull primitive will return
393  /// - GA_DEREFERENCE_OK @n
394  /// If a full row or column was dereferenced
395  /// - GA_DEREFERENCE_DEGENERATE @n
396  /// If a full row/column was dereferenced, leaving a degenerate
397  /// primitive.
398  /// - GA_DEREFERENCE_FAIL @n
399  /// If a single point from within the hull cannot be dereferenced
400  /// The @c dry_run parameter will prevent the point from actually being
401  /// detached.
402  virtual GA_DereferenceStatus dereferencePoint(GA_Offset point,
403  bool dry_run=false) = 0;
404  virtual GA_DereferenceStatus dereferencePoints(
405  const GA_RangeMemberQuery &pt_q,
406  bool dry_run=false) = 0;
407 
408  /// @{
409  /// Enlarge a bounding box by the bounding box of the primitive. A
410  /// return value of false indicates an error in the operation, most
411  /// likely an invalid P. By default, these methods simply enlarge the
412  /// bounding box based on the vertices.
413  virtual bool enlargeBoundingBox(UT_BoundingRect &b,
414  const GA_Attribute *P) const;
415  virtual bool enlargeBoundingBox(UT_BoundingBox &b,
416  const GA_Attribute *P) const;
417  /// @}
418  /// Enlarge a bounding sphere to encompass the primitive. A return value
419  /// of false indicates an error in the operation, most likely an invalid
420  /// P. By default, this method simply enlarges the bounding box based on
421  /// the vertices.
422  virtual bool enlargeBoundingSphere(UT_BoundingSphere &b,
423  const GA_Attribute *P) const;
424 
425  /// Enlarge a point bounding box for implicit primitive bounds. If a
426  /// primitive (such as a sphere) has a bounding box larger than its point
427  /// hull, then it should implement this method. Otherwise, it can rely on
428  /// the default behaviour.
429  virtual void enlargePointBounds(UT_BoundingBox &box) const;
430 
431  /// Is the primitive degenerate
432  virtual bool isDegenerate() const = 0;
433 
434  /// Copy the specified primitive as part of the merge. The source
435  /// primitive will be of the same type.
436  ///
437  /// Since the vertex offsets will change for the merged geometry, the map
438  /// should be used to lookup the new vertex offsets. For example
439  /// @code
440  /// map.mapDestFromSource( GA_ATTRIB_VERTEX, source_vertex );
441  /// @endcode
442  ///
443  /// @see GA_MergeMap
444  virtual void copyUnwiredForMerge(
445  const GA_Primitive *src, const GA_MergeMap &map);
446 
447  /// This method returns the JSON interface for saving/loading the primitive
448  /// If the method returns a NULL pointer, then the primitive will @b not
449  /// be saved to geometry files (and thus cannot be loaded).
450  virtual const GA_PrimitiveJSON *getJSON() const = 0;
451 
452  /// Some primitives can have common/shared data between different
453  /// instances of the primitives. This method is invoked during the save
454  /// process to save data. The method requires you to save two objects
455  /// sequentially (the data is stored in a list) for each shared key:
456  /// - The primitive typedef name. This is used at load time to find the
457  /// definition which knows how to load the data.
458  /// - The data required to represent the shared object. This is
459  /// typically a list or map containing the type of data, the key value
460  /// (used for loading) and the actual object data.
461  ///
462  /// If there are multiple shared data pointers, the array can continue with name/value pairs.
463  ///
464  /// For example, you might have something like: @code
465  /// const char *key = makeKeyForSharedPtr(ptr);
466  /// bool ok = true;
467  /// if (!save.hasSavedSharedData(key))
468  /// {
469  /// save.setSavedSharedData(key); // Flag this data as saved
470  /// ok = ok && w.jsonStringToken(getTypeName());
471  /// ok = ok && w.jsonBeginArray();
472  /// ok = ok && w.jsonStringToken("datatype");
473  /// ok = ok && w.jsonStringToken(key);
474  /// ok = ok && saveSharedData(ptr);
475  /// ok = ok && w.jsonEndArray();
476  /// }
477  /// return ok;
478  /// @endcode
479  /// Then in the primitive JSON, you'd likely want to have two fields, one
480  /// for the shared data pointer, the other for an expanded version of the
481  /// data. The @c shouldSaveField() method would be something like: @code
482  /// if (index == SHARED_DATA_KEY)
483  /// return save.hasSavedSharedData(key);
484  /// if (index == EXPANDED_DATA_KEY)
485  /// return !save.hasSavedSharedData(key);
486  /// @endcode
487  ///
488  /// Then the saveField() method of the primitive JSON would look something
489  /// like: @code
490  /// switch (index)
491  /// {
492  /// case SHARED_DATA_KEY:
493  /// UT_ASSERT(save.hasSaveSharedData(key));
494  /// return w.jsonString(key);
495  /// case EXPANDED_DATA_KEY:
496  /// UT_ASSERT(!save.hasSaveSharedData(key));
497  /// return saveSharedData(ptr);
498  /// }
499  /// @endcode
500  ///
501  /// During the loading process, you can just get the shared data from the
502  /// load map. @code
503  /// MySharedDataContainer *data;
504  /// data = load.sharedLoadDataAs<MySharedDataContainer>(key);
505  /// if (data)
506  /// setSharedPointer(data->getSharedData();
507  /// else
508  /// return false;
509  /// @endcode
510  virtual bool saveSharedLoadData(UT_JSONWriter &w, GA_SaveMap &save, GA_GeometryIndex* geometryIndex) const;
511 
512 
513  virtual bool registerSharedLoadData(int load_data_type, GA_SharedDataHandlePtr item);
514 
515  virtual bool loadH9(UT_IStream &is,
516  const UT_Array<GA_AttribLoadDataH9> &prim_attribs,
517  const UT_Array<GA_AttribLoadDataH9> &vtx_attribs);
518  virtual bool saveH9(std::ostream &os, bool binary,
519  const UT_Array<GA_AttribSaveDataH9> &prim_attribs,
520  const UT_Array<GA_AttribSaveDataH9> &vtx_attribs)
521  const;
522 
523  // ------------ Intrinsic interface ------------
524  /// Get the intrinsic manager for primitive intrinsics.
525  /// All primitives have at least the following intrinsics:
526  /// - "string typename" @n The type name of the primitive
527  /// - "int typeid" @n The type id (may change per run)
528  /// - "int vertexcount" @n The number of vertices in the primitive
530  { return getTypeDef().getIntrinsicManager(); }
531 
532  /// @{
533  /// Query properties of the primitive intrinsic.
534  /// Note that the tuple size calls the virtual method since the tuple size
535  /// may be dynamic (i.e. basis knot vector)
536  GA_LocalIntrinsic findIntrinsic(const char *nm) const
537  { return getIntrinsicManager().getLocalHandle(nm); }
539  { return getIntrinsicManager().getLocalHandle(h); }
541  { return getIntrinsicManager().getGlobalHandle(h); }
542 
544  { return getIntrinsicManager().getName(h); }
545  GA_Size getIntrinsicTupleSize(GA_LocalIntrinsic h) const;
547  { return getIntrinsicManager().getStorage(h); }
549  { return getIntrinsicManager().getReadOnly(h); }
551  { return getIntrinsicManager().getOptions(h); }
552  /// @}
553 
554  /// @{
555  /// Get the value of a primitive intrinsic.
556  /// These methods return the number of items retrieved.
557  GA_Size getIntrinsic(GA_LocalIntrinsic h, UT_String &val) const;
558  GA_Size getIntrinsic(GA_LocalIntrinsic h, UT_StringArray &val) const;
559  GA_Size getIntrinsic(GA_LocalIntrinsic h, int64 *v, GA_Size size) const;
560  GA_Size getIntrinsic(GA_LocalIntrinsic h, fpreal64 *v, GA_Size sz) const;
561  /// @}
562 
563  /// @{
564  /// Get the value of a primitive intrinsic.
565  /// Returns false if not the right type or not found.
566  /// Always will clear out the provided value.
567  bool getIntrinsic(GA_LocalIntrinsic h, float &v) const;
568  bool getIntrinsic(GA_LocalIntrinsic h, int &v) const;
569  bool getIntrinsic(GA_LocalIntrinsic h, UT_Vector2 &v) const;
570  bool getIntrinsic(GA_LocalIntrinsic h, UT_Vector3 &v) const;
571  bool getIntrinsic(GA_LocalIntrinsic h, UT_Vector4 &v) const;
572  bool getIntrinsic(GA_LocalIntrinsic h, UT_Matrix2 &v) const;
573  bool getIntrinsic(GA_LocalIntrinsic h, UT_Matrix3 &v) const;
574  bool getIntrinsic(GA_LocalIntrinsic h, UT_Matrix4 &v) const;
575 
576  /// @}
577 
578  /// @{
579  /// Set intrinsic attributes. This will fail if the intrinsic is read-only.
580  /// These methods return the number of items set.
581  GA_Size setIntrinsic(GA_LocalIntrinsic h, const char *value);
582  GA_Size setIntrinsic(GA_LocalIntrinsic h, const UT_StringArray &value);
583  GA_Size setIntrinsic(GA_LocalIntrinsic h, const char **val, GA_Size s);
584  GA_Size setIntrinsic(GA_LocalIntrinsic h, const int64 val);
585  GA_Size setIntrinsic(GA_LocalIntrinsic h, const fpreal64 val);
586  GA_Size setIntrinsic(GA_LocalIntrinsic h, const int64 *val, GA_Size sz);
587  GA_Size setIntrinsic(GA_LocalIntrinsic h, const fpreal64 *v, GA_Size sz);
588  /// @}
589 
590  /// Private interface
591  /// The clearForDeletion() method is called just prior to the detail being
592  /// cleared out. This allows the primitive to simplify its data structures,
593  /// knowing that topology doesn't need to be maintained (i.e. unwiring all
594  /// vertices);
595  virtual void clearForDeletion() {}
596 
597  /// Return the next and previous vertex on the "boundary" of the primitive
598  /// (as understood by the primitive) relative to a given vertex. These are
599  /// needed to maintain half-edge topology attributes.
600  /// They must be implemented for primitives that realize a notion of a
601  /// boundary composed of one or more closed cycles of vertices if we want
602  /// to be able to use hedges to quickly move from such a primitive to
603  /// another sharing an edge with it. A GA_INVALID_OFFSET for prev_vtx or
604  /// next_vtx means that either the primitive doesn't care about hedges,
605  /// the input vertex is not a boundary vertex in the primitive (or not a
606  /// vertex at all), or vtx is at an end of a boundary (e.g. open polys).
608  GA_Offset &prev_vtx,
609  GA_Offset &next_vtx) const
610  { prev_vtx = next_vtx = GA_INVALID_OFFSET; }
611 
612  /// Primitives that implement getAdjacentBoundaryVertices must respond true
613  /// to supportsHedge().
614  virtual bool supportsHedge() const
615  { return false; }
616 
617  /// Release the given vertex. This is equivalent to deleting a vertex
618  /// without modifying its topology attributes. In other words, the primitive
619  /// doesn't use the vertex anymore, but the vertex stays wired to the
620  /// primitive and to the point it was wired to. The intended use is with
621  /// stealVertex methods, so that the same vertex can be aquired by another
622  /// primitive, thus maintaining its offset number and attributes The return
623  /// value is the vertex offset (same as input) if successful and
624  /// GA_INVALID_OFFSET otherwise.
626  { return GA_INVALID_OFFSET; }
627 
628 
629  /// Backward compatible methods for GD library
630  /// Determine whether the primitive is visisble on the interval of the
631  /// parent surface. Partial visiblity should return true as well.
632  /// @return
633  /// - @c 0: Not visible on parent surface
634  /// - @c 1: Full visibility (@b default)
635  /// - @c 2: Partial visibility
636  virtual int isVisible() const;
637 
638  /// A primitive may support any number of secondary details.
639  virtual unsigned getNumSecondaryDetails() const;
640  virtual const GA_Detail *getSecondaryDetail(GA_Index i) const;
641  virtual GA_Detail *getSecondaryDetail(GA_Index i);
642 
643  GA_Index getNumSecondary(GA_Index detail) const;
644  const GA_Primitive *getSecondaryByIndex(GA_Index detail, GA_Index i) const;
645  GA_Primitive *getSecondaryByIndex(GA_Index detail, GA_Index i);
646  const GA_Primitive *getSecondaryByOffset(GA_Index detail,
647  GA_Offset o) const;
648  GA_Primitive *getSecondaryByOffset(GA_Index detail, GA_Offset o);
649 
650  /// @{
651  /// Primitives must provide these methods
652  virtual void reverse() = 0;
653  /// @}
654 
655  /// @{
656  /// Measure the primitive.
657  virtual fpreal calcVolume(const UT_Vector3 &refpt) const
658  { return 0; }
659  virtual fpreal calcArea() const { return 0; }
660  virtual fpreal calcPerimeter() const { return 0; }
661  /// @}
662 
663  /// A trivial vertex list is a uniform ascending list, so
664  /// getFastVertexOffset(i) == getFastVertexOffset(0) + i
666  bool isVertexListTrivial() const { return myVertexList.isTrivial(); }
667  /// A trivial point list is doubly-trivial:
668  /// getPointOffset(i) == getPointOffset(0) + i
669  /// This requires testing every point so is slower than isVertexListTrivial.
670  bool isPointListTrivial() const;
671 
672  /// Calls a functor (e.g. a lambda) for each vertex offset in this
673  /// primitive, in the order they occur in the vertex list.
674  /// This is optimized to only check triviality once.
675  template<typename FUNCTOR>
677  void forEachVertex(FUNCTOR &&functor) const
678  {
679  myVertexList.forEach(functor);
680  }
681 
682  /// Calls a functor (e.g. a lambda) for each point offset in this
683  /// primitive, in the order they occur in the vertex list.
684  /// This is optimized to only check triviality once and only look up
685  /// the vertex-to-point topology attribute once.
686  template<typename FUNCTOR>
688  void forEachPoint(FUNCTOR &&functor) const
689  {
690  const GA_ATITopology *vtx_to_pt = myDetail->getTopology().getPointRef();
691  myVertexList.forEach([vtx_to_pt,&functor](GA_Offset vtx){
692  functor(vtx_to_pt->getLink(vtx));
693  });
694  }
695 
696  bool vertexApply(bool(*apply)(GA_Offset vtx, void *),
697  void *data = nullptr) const
698  {
699  for (GA_Size i = 0, n = getVertexCount(); i < n; ++i)
700  {
701  if (apply(getVertexOffset(i), data))
702  return true;
703  }
704  return false;
705  }
706 
707  /// Stash (deactivate) or unstash (reactivate) the primitive.
708  ///
709  /// Stashing a primitive will set its offset to that specified, typically
710  /// GA_INVALID_OFFSET. Primitives are only stashed as part of clearing a
711  /// detail, so there is no need to explicitly deallocate vertices. It is
712  /// safe to delete a stashed primitive.
713  ///
714  /// Unstashing a primitive will re-register that primitive with its parent
715  /// detail at the specified offset (or a new offset if GA_INVALID_OFFSET).
716  virtual void stashed(bool beingstashed,
718 
719  /// Copy any modified caches from the GPU back to CPU cache.
720  virtual void flushCEWriteCaches() {}
721 
722  /// Copy any modified caches from the GPU to CPU. Then delete the GPU
723  /// cache.
724  virtual void flushCECaches() {}
725 
726  static SYS_FORCE_INLINE
729  {
731  if (type_id < GA_PrimCompat::TypeMaskBits)
732  m = (GA_PrimCompat::value_type)1 << type_id;
733  return GA_PrimCompat::TypeMask(m);
734  }
735 
736 protected:
737  void setNumVertices(GA_Size nvertices);
738 
739  /// allocateVertex() will call wireVertex() if the point given is not -1
740  GA_Offset allocateVertex(GA_Offset point=GA_INVALID_OFFSET);
741  void destroyVertex(GA_Offset vertex);
742  void wireVertex(GA_Offset vertex, GA_Offset point);
743 
744  /// Create the topological binding between preallocated vertex and
745  /// primitive.
746  void registerVertex(GA_Offset vertex);
747 
748  /// Report approximate memory usage for myVertexList for subclasses.
751  {
752  return myVertexList.getMemoryUsage(false);
753  }
754 
755  /// This is called by the subclasses to count the
756  /// memory used by myVertexList
757  void countBaseMemory(UT_MemoryCounter &counter) const;
758 
759  /// This is the implementation of this level of copyUnwiredForMerge,
760  /// and enables GA_PrimitiveList to set the vertex list without a
761  /// source primitive.
762  void copyVertexListForMerge(
763  const GA_OffsetListRef &src_vertices, const GA_MergeMap &map);
764 
765  /// @{
766  /// Implementation of intrinsic attributes. See GA_IntrinsicEval
767  /// for further details. See GA_IntrinsicMacros.h for implementation of
768  /// intrinsics.
769  /// @note When implementing support for string intrinsic attributes, please
770  /// ensure to implement for @b all methods (localGetIntrinsicS,
771  /// localGetIntrinsicSA for reading and localSetIntrinsicSA,
772  /// localSetIntrinsicSS for writing). You should do this even if the
773  /// string tuple size is 1.
775  /// @}
776 
777 private:
778 
780  void unstashImpl(GA_Offset offset)
781  {
782  UT_ASSERT_P(myVertexList.size() == 0);
783  myOffset = offset;
784  }
785 
786  friend class GA_PrimitiveList;
787 
788  GA_Detail *myDetail;
789  GA_Offset myOffset;
790 protected:
792 };
793 
797 {
798  return myPrimitiveList.getVertexList(primoff);
799 }
800 
802 GA_Size
804 {
805  return myPrimitiveList.getVertexCount(primoff);
806 }
807 
809 GA_Offset
811 {
812  return myPrimitiveList.getVertexOffset(primoff, i);
813 }
814 
816 int
818 {
819  return myPrimitiveList.getTypeId(primoff);
820 }
821 
823 bool
825 {
826  return myPrimitiveList.getClosedFlag(primoff);
827 }
828 
830 void
832 {
833  myPrimitiveList.setClosedFlag(primoff, closed);
834 }
835 
836 #if COMPRESSED_PRIM_LIST
840 {
841  UT_ASSERT_P(!myDetail.getPrimitiveMap().isOffsetVacant(primoff));
842  const GA_Primitive *const*prim_array = myList;
843  if (!prim_array)
844  {
845  GA_PageNum pagenum = GAgetPageNum(primoff);
846  GA_PageOff pageoff = GAgetPageOff(primoff);
847  auto p = myVertexLists.getPageData(pagenum);
848  UT_ASSERT_COMPILETIME(2*sizeof(*p) == sizeof(GA_OffsetListRef));
849  auto po = reinterpret_cast<const GA_OffsetListRef*>(p);
850  if (myVertexLists.isPageConstant(pagenum))
851  {
852  exint size = po->size();
853  return GA_OffsetListRef(po->trivialStart() + size*pageoff, size, po->getExtraFlag());
854  }
855  else
856  {
857  return po[pageoff];
858  }
859  }
860  else
861  {
862  UT_ASSERT_P(GAisValid(primoff) && primoff < GA_Offset(getMyListSize()));
863  return GA_OffsetListRef(prim_array[primoff]->myVertexList);
864  }
865 }
866 
868 GA_Size
870 {
871  UT_ASSERT_P(!myDetail.getPrimitiveMap().isOffsetVacant(primoff));
872  const GA_Primitive *const*prim_array = myList;
873  if (!prim_array)
874  {
875  GA_PageNum pagenum = GAgetPageNum(primoff);
876  UT_ASSERT_COMPILETIME(2*sizeof(int64) == sizeof(GA_OffsetList));
877  auto p = reinterpret_cast<const GA_OffsetList*>(myVertexLists.getPageData(pagenum));
878  if (!myVertexLists.isPageConstant(pagenum))
879  {
880  p += GAgetPageOff(primoff);
881  }
882  return p->size();
883  }
884  else
885  {
886  UT_ASSERT_P(GAisValid(primoff) && primoff < GA_Offset(getMyListSize()));
887  return prim_array[primoff]->getVertexCount();
888  }
889 }
890 
892 GA_Offset
894 {
895  UT_ASSERT_P(!myDetail.getPrimitiveMap().isOffsetVacant(primoff));
896  const GA_Primitive *const*prim_array = myList;
897  if (!prim_array)
898  {
899  GA_PageNum pagenum = GAgetPageNum(primoff);
900  GA_PageOff pageoff = GAgetPageOff(primoff);
901  UT_ASSERT_COMPILETIME(2*sizeof(int64) == sizeof(GA_OffsetList));
902  auto p = reinterpret_cast<const GA_OffsetList*>(myVertexLists.getPageData(pagenum));
903  if (!myVertexLists.isPageConstant(pagenum))
904  {
905  return p[pageoff].get(i);
906  }
907  return p->trivialStart() + p->size()*pageoff + i;
908  }
909  else
910  {
911  UT_ASSERT_P(GAisValid(primoff) && primoff < GA_Offset(getMyListSize()));
912  return prim_array[primoff]->getVertexOffset(i);
913  }
914 }
915 
917 int
919 {
920  UT_ASSERT_P(!myDetail.getPrimitiveMap().isOffsetVacant(primoff));
921  const GA_Primitive *const*prim_array = myList;
922  if (!prim_array)
923  {
924  return myPrimitiveTypes.get(primoff);
925  }
926  else
927  {
928  UT_ASSERT_P(GAisValid(primoff) && primoff < GA_Offset(getMyListSize()));
929  return prim_array[primoff]->getTypeId().get();
930  }
931 }
932 
934 bool
936 {
937  UT_ASSERT_P(!myDetail.getPrimitiveMap().isOffsetVacant(primoff));
938  const GA_Primitive *const*prim_array = myList;
939  if (!prim_array)
940  {
941  GA_PageNum pagenum = GAgetPageNum(primoff);
942  auto p = myVertexLists.getPageData(pagenum);
943  if (!myVertexLists.isPageConstant(pagenum))
944  {
945  p += 2*GAgetPageOff(primoff);
946  }
947  UT_ASSERT_COMPILETIME(2*sizeof(*p) == sizeof(GA_OffsetList));
948  return reinterpret_cast<const GA_OffsetList*>(p)->getExtraFlag();
949  }
950  else
951  {
952  UT_ASSERT_P(GAisValid(primoff) && primoff < GA_Offset(getMyListSize()));
953  return prim_array[primoff]->myVertexList.getExtraFlag();
954  }
955 }
956 
958 void
960 {
961  UT_ASSERT_P(!myDetail.getPrimitiveMap().isOffsetVacant(primoff));
962  GA_Primitive *const*prim_array = myList;
963  if (!prim_array)
964  {
965  GA_PageNum pagenum = GAgetPageNum(primoff);
966  auto p = hardenVertexListPage(pagenum);
967  GA_PageOff pageoff = GAgetPageOff(primoff);
968  return p[pageoff].setExtraFlag(closed);
969  }
970  else
971  {
972  UT_ASSERT_P(GAisValid(primoff) && primoff < GA_Offset(getMyListSize()));
973  return prim_array[primoff]->myVertexList.setExtraFlag(closed);
974  }
975 }
976 #else
980 {
981  return GA_OffsetListRef(myList[off]->myVertexList);
982 }
983 
985 GA_Size
987 {
988  return myList[off]->getVertexCount();
989 }
990 
992 GA_Offset
994 {
995  return myList[primoff]->getVertexOffset(i);
996 }
997 
999 int
1001 {
1002  return myList[off]->getTypeId().get();
1003 }
1004 
1006 void
1008 {
1009  list = myList[off]->myVertexList;
1010 }
1011 
1013 bool
1015 {
1016  return myList[off]->myVertexList.getExtraFlag();
1017 }
1018 
1020 void
1021 GA_PrimitiveList::setClosedFlag(GA_Offset primoff, bool closed)
1022 {
1023  return myList[primoff]->myVertexList.setExtraFlag(closed);
1024 }
1025 #endif
1026 
1027 #endif
virtual void flushCEWriteCaches()
Copy any modified caches from the GPU back to CPU cache.
Definition: GA_Primitive.h:720
A class to manage an ordered array which has fixed offset handles.
Definition: GA_IndexMap.h:63
virtual void flushCECaches()
Definition: GA_Primitive.h:724
SYS_FORCE_INLINE const GA_IndexMap & getIndexMap() const
Gets the index map for primitives in the detail containing this primitive.
Definition: GA_Primitive.h:148
SYS_FORCE_INLINE bool isPageConstant(UT_PageNum pagenum) const
Returns true iff the specified page is constant-compressed.
Definition of a geometry attribute.
Definition: GA_Attribute.h:190
SYS_FORCE_INLINE GA_Offset getPrimitiveVertexOffset(GA_Offset primoff, GA_Size i) const
Definition: GA_Primitive.h:810
SYS_FORCE_INLINE GA_Offset getPointOffset(GA_Size i) const
Definition: GA_Primitive.h:246
SYS_FORCE_INLINE void setClosedFlag(GA_Offset primoff, bool closed)
Definition: GA_Primitive.h:959
GA_LocalIntrinsic findIntrinsic(const char *nm) const
Definition: GA_Primitive.h:536
SYS_FORCE_INLINE GA_Detail & getDetail() const
Definition: GA_Primitive.h:133
virtual void clearForDeletion()
Definition: GA_Primitive.h:595
Used to pass options and map offset values during saving.
Definition: GA_SaveMap.h:48
const GA_IndexMap & getPrimitiveMap() const
Definition: GA_Detail.h:679
SYS_FORCE_INLINE GA_Size getVertexCount() const
Return the number of vertices used by this primitive.
Definition: GA_Primitive.h:224
GA_Size GA_PageOff
Definition: GA_Types.h:621
virtual fpreal calcPerimeter() const
Definition: GA_Primitive.h:660
SYS_FORCE_INLINE GA_Offset getLink(GA_Offset ai) const
SYS_FORCE_INLINE int getPrimitiveTypeId(GA_Offset primoff) const
Definition: GA_Primitive.h:817
SYS_FORCE_INLINE GA_Index getVertexIndex(GA_Size primvertexnum) const
Definition: GA_Primitive.h:238
bool hasLocalTransform() const
Whether the primitive has a transform associated with it.
Definition: GA_Primitive.h:177
GA_StorageClass
Definition: GA_Types.h:68
bool getIntrinsicReadOnly(GA_LocalIntrinsic h) const
Definition: GA_Primitive.h:548
const GLdouble * v
Definition: glcorearb.h:836
GA_LocalIntrinsic findIntrinsic(GA_GlobalIntrinsic h) const
Definition: GA_Primitive.h:538
bool GAisValid(GA_Size v)
Definition: GA_Types.h:625
typedef void(APIENTRYP PFNGLCULLFACEPROC)(GLenum mode)
#define SYS_DEPRECATED_HDK_REPLACE(__V__, __R__)
const GLuint GLenum const void * binary
Definition: glcorearb.h:1923
bool isOffsetVacant(GA_Offset offset) const
SYS_FORCE_INLINE bool getExtraFlag() const
GA_PrimitiveFamilyMask getFamilyMask() const
Definition: GA_Primitive.h:171
virtual ~GA_Primitive()
Definition: GA_Primitive.h:117
The merge map keeps track of information when merging details.
Definition: GA_MergeMap.h:53
SYS_FORCE_INLINE void setPointOffset(GA_Size i, GA_Offset ptoff)
Definition: GA_Primitive.h:252
SYS_FORCE_INLINE DEST_DATA_T get(IDX_T i, exint component=0) const
Definition: UT_PageArray.h:491
SYS_FORCE_INLINE const GA_PrimitiveTypeId & getTypeId() const
Definition: GA_Primitive.h:169
Class used to map H9 geometry files to a form used by GA.
Definition: GA_AIFFileH9.h:317
#define GA_DECLARE_INTRINSICS(OVERRIDE)
Definition: GA_Primitive.h:80
Manager to keep track of global handle to name mappings.
#define GA_API
Definition: GA_API.h:12
Class which writes ASCII or binary JSON streams.
Definition: UT_JSONWriter.h:32
Abstract base class for a range membership query object.
#define GA_NO_OVERRIDE
Definition: GA_Primitive.h:76
GLfloat GLfloat GLfloat v2
Definition: glcorearb.h:817
GA_ListTypeRef< GA_Size, GA_Offset > GA_OffsetListRef
virtual int64 getMemoryUsage() const
Definition: GA_Primitive.h:201
UT_SharedPtr< GA_SharedDataHandle > GA_SharedDataHandlePtr
png_uint_32 i
Definition: png.h:2877
uint64 value_type
Definition: GA_PrimCompat.h:29
exint GA_Size
Defines the bit width for index and offset types in GA.
Definition: GA_Types.h:211
SYS_FORCE_INLINE int64 getBaseMemoryUsage() const
Report approximate memory usage for myVertexList for subclasses.
Definition: GA_Primitive.h:750
GA_PageOff GAgetPageOff(GA_Offset v)
Definition: GA_Types.h:636
bool isFamily(unsigned family_mask) const
Definition: GA_Primitive.h:173
GA_PrimitiveFamilyMask
SYS_FORCE_INLINE bool getPrimitiveClosedFlag(GA_Offset primoff) const
Definition: GA_Primitive.h:824
GLsizeiptr size
Definition: glcorearb.h:663
#define GA_INVALID_OFFSET
Definition: GA_Types.h:654
GA_OffsetList myVertexList
Definition: GA_Primitive.h:791
A range of elements in an index-map.
Definition: GA_Range.h:42
int GA_GlobalIntrinsic
Definition: GA_Types.h:671
SYS_FORCE_INLINE GA_Size getVertexCount(GA_Offset primoff) const
Definition: GA_Primitive.h:869
GA_Size GA_Offset
Definition: GA_Types.h:617
long long int64
Definition: SYS_Types.h:107
int GA_LocalIntrinsic
Definition: GA_Types.h:670
const GA_IntrinsicManager & getIntrinsicManager() const
Definition: GA_Primitive.h:529
SYS_FORCE_INLINE UT_Vector3 getPos3(GA_Size i) const
Definition: GA_Primitive.h:266
GLdouble n
Definition: glcorearb.h:2007
Class used to keep track of inheritance of intrinsic attribute evaluation.
SYS_FORCE_INLINE GA_OffsetListRef getVertexList(GA_Offset primoff) const
Definition: GA_Primitive.h:839
int64 exint
Definition: SYS_Types.h:116
virtual GA_PrimCompat::TypeMask getPrimitiveId() const
Definition: GA_Primitive.h:196
#define UT_ASSERT_P(ZZ)
Definition: UT_Assert.h:125
GA_Range getPointRange(bool harden=false) const
Definition: GA_Primitive.h:296
double fpreal64
Definition: SYS_Types.h:192
SYS_FORCE_INLINE GA_OffsetListRef getPrimitiveVertexList(GA_Offset primoff) const
Definition: GA_Primitive.h:796
#define SYS_FORCE_INLINE
Definition: SYS_Inline.h:45
GA_GlobalIntrinsic findGlobalIntrinsic(GA_LocalIntrinsic h) const
Definition: GA_Primitive.h:540
GLintptr offset
Definition: glcorearb.h:664
Provide a JSON interface to a primitive.
SYS_FORCE_INLINE void forEachPoint(FUNCTOR &&functor) const
Definition: GA_Primitive.h:688
virtual fpreal calcArea() const
Definition: GA_Primitive.h:659
SYS_FORCE_INLINE bool isVertexListTrivial() const
Definition: GA_Primitive.h:666
SYS_FORCE_INLINE UT_Vector4 getPos4(GA_Size i) const
Definition: GA_Primitive.h:278
std::function< bool(const GA_Edge &edge)> GA_IterateEdgesFunc
Definition: GA_Primitive.h:73
virtual bool supportsHedge() const
Definition: GA_Primitive.h:614
SYS_FORCE_INLINE int get() const
Defragmentation of IndexMaps.
Definition: GA_Defragment.h:45
GLboolean * data
Definition: glcorearb.h:130
#define SYS_DEPRECATED_HDK(__V__)
std::function< bool(GA_Size, GA_Size)> GA_IterateEdgesByVertexFunc
Definition: GA_Primitive.h:74
GLboolean GLboolean GLboolean b
Definition: glcorearb.h:1221
GA_Size GA_Index
Define the strictness of GA_Offset/GA_Index.
Definition: GA_Types.h:611
const NotVoidType * getPageData(UT_PageNum pagenum) const
SYS_FORCE_INLINE GA_Index getPointIndex(GA_Size i) const
Definition: GA_Primitive.h:260
SYS_FORCE_INLINE void setPos3(GA_Size i, const UT_Vector3 &pos) const
Definition: GA_Primitive.h:272
const char * getIntrinsicName(GA_LocalIntrinsic h) const
Definition: GA_Primitive.h:543
SYS_FORCE_INLINE bool getClosedFlag(GA_Offset primoff) const
Definition: GA_Primitive.h:935
A list of primitives.
bool vertexApply(bool(*apply)(GA_Offset vtx, void *), void *data=nullptr) const
Definition: GA_Primitive.h:696
SYS_FORCE_INLINE void setPos4(GA_Size i, const UT_Vector4 &pos) const
Definition: GA_Primitive.h:284
GLfloat GLfloat GLfloat GLfloat h
Definition: glcorearb.h:2001
GLsizei const GLfloat * value
Definition: glcorearb.h:823
double fpreal
Definition: SYS_Types.h:270
bool isPointUsed(GA_Offset ptoff) const
Definition: GA_Primitive.h:306
A map of string to various well defined value types.
Definition: UT_Options.h:42
SYS_FORCE_INLINE GA_Index getMapIndex() const
Gets the index of this primitive in the detail containing it.
Definition: GA_Primitive.h:143
const UT_Options * getIntrinsicOptions(GA_LocalIntrinsic h) const
Definition: GA_Primitive.h:550
virtual fpreal calcVolume(const UT_Vector3 &refpt) const
Definition: GA_Primitive.h:657
GA_StorageClass getIntrinsicStorage(GA_LocalIntrinsic h) const
Definition: GA_Primitive.h:546
virtual void getAdjacentBoundaryVertices(GA_Offset vtx, GA_Offset &prev_vtx, GA_Offset &next_vtx) const
Definition: GA_Primitive.h:607
SYS_FORCE_INLINE void setExtraFlag(bool v)
SYS_FORCE_INLINE void forEachVertex(FUNCTOR &&functor) const
Definition: GA_Primitive.h:677
GA_Size GA_PageNum
Definition: GA_Types.h:620
SYS_FORCE_INLINE GA_Offset getMapOffset() const
Gets the offset of this primitive in the detail containing it.
Definition: GA_Primitive.h:138
Class used to map the GA attribute into a form for H9 geometry files.
Definition: GA_AIFFileH9.h:261
GLfloat GLfloat v1
Definition: glcorearb.h:816
GLuint GLfloat * val
Definition: glcorearb.h:1607
void(* GA_EdgeApplyFunc)(const GA_Primitive &prim, GA_Offset pt_a, GA_Offset pt_b, void *data)
Definition: GA_Primitive.h:68
SYS_FORCE_INLINE GA_Offset getVertexOffset(GA_Size primvertexnum) const
Definition: GA_Primitive.h:232
SYS_FORCE_INLINE void setPrimitiveClosedFlag(GA_Offset primoff, bool closed)
Definition: GA_Primitive.h:831
SYS_FORCE_INLINE ToType get(FromType index) const
Get the the value at the index.
Container class for all geometry.
Definition: GA_Detail.h:95
GLubyte GLubyte GLubyte GLubyte w
Definition: glcorearb.h:856
SYS_FORCE_INLINE GA_Size getPrimitiveVertexCount(GA_Offset primoff) const
Definition: GA_Primitive.h:803
Definition of a geometric primitive.
#define const
Definition: zconf.h:214
bool isPrimary() const
Definition: GA_Primitive.h:161
const char * getTypeName() const
Definition: GA_Primitive.h:125
GA_Range getVertexRange(bool harden=false) const
Get a range of all the vertices accessed by the primitive.
Definition: GA_Primitive.h:288
UT_ASSERT_COMPILETIME(BRAY_EVENT_MAXFLAGS<=32)
SYS_FORCE_INLINE GA_Primitive(GA_Detail &detail, GA_Offset offset=GA_INVALID_OFFSET)
Definition: GA_Primitive.h:108
void(* GA_EdgeApplyIndexFunc)(const GA_Primitive &prim, GA_Size v1, GA_Size v2, void *data)
Definition: GA_Primitive.h:70
virtual GA_Offset releaseVertex(GA_Offset vtx)
Definition: GA_Primitive.h:625
virtual void iterateEdgesByVertex(GA_IterateEdgesByVertexFunc apply_func) const
Definition: GA_Primitive.h:349
SYS_FORCE_INLINE int getTypeId(GA_Offset primoff) const
Definition: GA_Primitive.h:918
GA_PageNum GAgetPageNum(GA_Offset v)
Definition: GA_Types.h:632
SYS_FORCE_INLINE FromType size() const
Returns the number of used elements in the list (always <= capacity())
static SYS_FORCE_INLINE GA_PrimCompat::TypeMask primCompatMaskFromTypeId(int type_id)
Definition: GA_Primitive.h:728
GLenum src
Definition: glcorearb.h:1792
SYS_FORCE_INLINE GA_Offset getVertexOffset(GA_Offset primoff, GA_Size i) const
Definition: GA_Primitive.h:893