HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
GA_Detail.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_Detail.h ( GA Library, C++)
7  *
8  * COMMENTS:
9  */
10 
11 #pragma once
12 
13 #ifndef __GA_Detail__
14 #define __GA_Detail__
15 
16 #include "GA_API.h"
17 #include "GA_ATITopology.h"
18 #include "GA_AttributeRef.h"
19 #include "GA_AttributeSet.h"
20 #include "GA_Defaults.h"
21 #include "GA_EdgeGroup.h"
22 #include "GA_EdgeGroupTable.h"
23 #include "GA_ElementGroup.h"
24 #include "GA_ElementGroupOrder.h"
25 #include "GA_ElementGroupTable.h"
26 #include "GA_Handle.h"
27 #include "GA_IndexMap.h"
28 #include "GA_IntrinsicManager.h"
29 #include "GA_OffsetList.h"
30 #include "GA_PrimitiveFactory.h"
31 #include "GA_PrimitiveList.h"
32 #include "GA_PrimitiveTypeMask.h"
33 #include "GA_Range.h"
34 #include "GA_Topology.h"
35 #include "GA_Types.h"
36 
37 #include <UT/UT_Assert.h>
38 #include <UT/UT_BoundingBox.h>
39 #include <UT/UT_BoundingRect.h>
40 #include <UT/UT_Vector2.h>
41 #include <UT/UT_Vector3.h>
42 #include <UT/UT_Vector4.h>
43 
44 #include <SYS/SYS_Compiler.h>
45 #include <SYS/SYS_Inline.h>
46 #include <SYS/SYS_Types.h>
47 
48 #include <iosfwd>
49 
50 class UT_IStream;
51 class UT_JSONParser;
52 class UT_JSONWriter;
53 class UT_MemoryCounter;
54 class UT_Options;
55 class UT_String;
56 class UT_StringArray;
57 class UT_StringHolder;
58 class UT_StringRef;
59 class UT_WorkBuffer;
60 template <typename T> class UT_Array;
61 
62 class GA_ATINumeric;
65 class GA_Attribute;
66 class GA_AttributeDict;
67 class GA_AttributeFilter;
70 class GA_AttributeType;
71 class GA_Group;
72 class GA_GroupTable;
73 class GA_IntrinsicEval;
74 class GA_IO;
75 class GA_LoadMap;
76 class GA_LoadOptions;
77 class GA_MergeMap;
78 class GA_MergeOptions;
79 class GA_PolyCounts;
80 class GA_Primitive;
81 class GA_PrimitiveTypeId;
83 class GA_SaveOptions;
84 class GA_Stat;
85 class ga_TailInitializeTable;
86 
87 namespace GA_FileFormatH9 { class PrimTypeXlate; }
88 
89 /// @brief Container class for all geometry.
90 ///
91 /// All Houdini geometry is stored in a GA_Detail class. The detail stores
92 /// lists of attributes (GA_Attribute) which are maintained in GA_AttributeSet
93 /// collections. The attribute set contains 4 separate classes of attribute
94 /// based on the GA_AttributeOwner enum.
96 {
97 public:
98  /// @param Pstorage determines the precision of the @b P attribute.
99  /// @param isprimary determines the default value of the @b P attribute.
100  /// true yields (0,0,0) as the default, and false yields (0,0,1),
101  /// for use by GD_Detail, where the z component is actually the
102  /// point weight for NURBS/Bezier trim/profile curves.
103  /// P will have typeinfo "hpoint" if secondary, and "point" if primary.
104  /// @param full_topology indicates whether the detail should maintain
105  /// additional attributes which make it easy to lookup
106  /// - Primitives using a shared point
107  /// - The primitive containing a unique point (vertex)
108  /// - The list of vertices referencing a shared point
109  /// @see typedef::GA_Storage.
111  bool isprimary=true,
112  bool full_topology=true);
113  /// Destructor
114  virtual ~GA_Detail();
115 
116  exint getUniqueId() const { return myUniqueId; }
117 
118  /// Re-initialize:
119  /// - Clears all attributes
120  /// - Clears all geometry elements (points, primitives, vertices, etc.)
121  /// - Clears all groups
122  /// NOTE: Does *NOT* clear caches like the primitive stash or selections,
123  /// though it does clear the attribute instance matrix. It has
124  /// to keep the stash, because it's used by stashAll().
125  /// Use clearAndDestroy() to clear everything.
126  void clear() { clearData(false); }
127 
128  /// Returns true if the detail is empty. This is not just
129  /// having zero points/primitives, but also only having trivial
130  /// attributes.
131  bool isEmpty() const;
132 
133  /// These two functions should be used instead of the more
134  /// destructive clearAndDestroy() when it it likely the
135  /// geometry it relatively stable between operations
136  /// @{
137  void stashAll()
138  {
139  clearCaches();
140 
141  getPrimitiveList().stashAll();
142 
143  // We have to clear the primitive index map before calling the virtual
144  // clearAndDestroy() to prevent primitive iterators from ending up in
145  // a bad state with expected entries missing from the primitive list.
146  getIndexMap(GA_ATTRIB_PRIMITIVE).clear(/*clear_capacity*/ true);
147 
148  // Increment the meta-cache count, since it did so before, in case
149  // anything is relying on it being incremented here.
150  incrementMetaCacheCount();
151 
152  // remove the rest
153  clear();
154  }
156  {
157  getPrimitiveList().destroyStashed();
158  }
159  ///@}
160 
161  // -------------- P attribute ----------------------------
162  /// Convenience method to access the @b P attribute
163  GA_Attribute *getP() { return myP; }
164  const GA_Attribute *getP() const { return myP; }
165 
166  /// The ptoff passed is the point offset. @see vertexPoint()
168  {
169  UT_Vector3 v3 = myHandlePV3.get(ptoff);
170  return UT_Vector2(v3.x(), v3.y());
171  }
172  /// The ptoff passed is the point offset. @see vertexPoint()
174  getPos3(GA_Offset ptoff) const
175  {
176  return myHandlePV3.get(ptoff);
177  }
178  /// Get an array of all positions from the given point range.
179  /// The template parameter T is must be one of: fpreal, fpreal32, or
180  /// fpreal64.
181  template <typename T>
183  const GA_Range &ptrange,
184  UT_Array< UT_Vector3T<T> > &positions) const
185  {
186  return getAttributeAsArray(getP(), ptrange, positions);
187  }
188  /// Get an array of all positions from the given point range.
189  /// The template parameter T is must be one of: fpreal, fpreal32, or
190  /// fpreal64.
191  template <typename T>
193  const GA_Range &ptrange,
194  const UT_Array< UT_Vector3T<T> > &positions)
195  {
196  return setAttributeFromArray(getP(), ptrange, positions);
197  }
198 
199  /// Set @b P from a UT_Vector2
200  void setPos2(GA_Offset ptoff, const UT_Vector2 &P)
201  {
202  UT_Vector3 v3 = UT_Vector3(P.x(), P.y(), myHandlePV3.get(ptoff).z());
203  myHandlePV3.set(ptoff, v3);
204  }
205  /// Set @b P from a UT_Vector3
207  void setPos3(GA_Offset ptoff, const UT_Vector3 &P)
208  {
209  myHandlePV3.set(ptoff, P);
210  }
211  /// Set @b P given the x, y, z components.
214  {
215  myHandlePV3.set(ptoff, UT_Vector3(x,y,z));
216  }
217 
218  /// Apply a translation to the specified point index. @see vertexPoint()
219  /// Effectively setPos3(offset, getPos3(offset) + delta)
221  void translatePoint(GA_Offset ptoff, const UT_Vector3 &delta)
222  {
223  myHandlePV3.add(ptoff, delta);
224  }
225 
226  //
227  // Functions for handling Pw: specific to rational NURBS and Bezier
228  // curves and surfaces! DO NOT USE unless you actually need to adjust the
229  // point weights!
230  //
231 
232  /// Get the homogeneous coordinate for a point
233  fpreal getPw(GA_Offset ptoff) const;
234  /// Set the homogeneous coordinate for a point
235  void setPw(GA_Offset ptoff, fpreal w);
236  /// NOTE: This will usually return nullptr, because very
237  /// few things actually set the homogenous coordinate
238  /// to anything other than 1.0, in which case, the
239  /// attribute won't be created.
240  /// @{
242  {
243  return myPw;
244  }
246  {
247  return myPw;
248  }
249  /// @}
250 
251  /// The ptoff passed is the point offset. @see vertexPoint()
253  {
254  return UT_Vector4(getPos3(ptoff), getPw(ptoff));
255  }
256 
257  /// Set @b P from a UT_Vector4
258  void setPos4(GA_Offset ptoff, const UT_Vector4 &P)
259  {
260  setPos3(ptoff, UT_Vector3(P));
261  setPw(ptoff, P.w());
262  }
263  /// Set @b P given the x, y, z, w components.
265  fpreal z, fpreal w)
266  {
267  setPos3(ptoff, UT_Vector3(x, y, z));
268  setPw(ptoff, w);
269  }
270 
271  //
272  // -------------- Element Interface ----------------------
273  //
274 
275  /// Append a new point, returning its new data offset
278  { return appendPointBlock(1); }
279  /// Append new points, returning the first offset of the contiguous block
282  { return myPointMap.addElementBlock(npoints); }
283  /// Return the number of points
286  { return myPointMap.indexSize(); }
287  /// This will be an exclusive, possibly loose, upper bound when iterating
288  /// over point offsets.
289  /// Every point offset in this detail will be strictly less than this.
290  /// @note (getNumPoints() <= getNumPointOffsets()) is always true.
293  { return myPointMap.offsetSize(); }
294  /// Given a point's index (in append order), return its data offset
297  { return myPointMap.offsetFromIndex(index); }
298  /// Given a point's data offset, return its index
301  { return myPointMap.indexFromOffset(offset); }
302  /// Reorder a point. The index of the point at the given data offset
303  /// will be changed to the new order (provided that the ordered position is
304  /// in a valid range).
305  /// @return The new index of the point, or -1 if there was an error
306  GA_Index reorderPoint(GA_Offset ptoff, GA_Index new_order);
307 
308  /// Append a primitive by GA_PrimitiveTypeId
309  GA_Primitive *appendPrimitive(const GA_PrimitiveTypeId &type);
310  /// Append a primitive by type name string
311  GA_Primitive *appendPrimitive(const UT_StringRef &type);
312  /// Append a contiguous block of primitives by GA_PrimitiveTypeId
313  GA_Offset appendPrimitiveBlock(const GA_PrimitiveTypeId &type,
314  GA_Size nprimitives);
315 
316  /// Append a contiguous block of primitives and a contiguous
317  /// block of vertices, with each primitive having nvertices_each vertices,
318  /// though the vertices will be unwired, so the caller is responsible
319  /// for wiring the vertices to points.
320  /// Make absolutely sure you know what you're doing if you call this!
321  /// It's used by GEO_PrimPoly::buildBlock() and GEO_PrimTetrahedron::
322  /// buildBlock().
323  /// The return value is the start offset of the primitive block,
324  /// and vertex_block_start is filled with the start offset of the
325  /// vertex block.
326  GA_Offset appendPrimitivesAndVertices(
327  const GA_PrimitiveTypeId &type,
328  GA_Size nprimitives,
329  GA_Size nvertices_each,
330  GA_Offset &vertex_block_start,
331  bool closed_flag = false);
332 
333  /// Append a contiguous block of primitives and a contiguous
334  /// block of vertices, with vertex_counts being a run-length encoded
335  /// array indicating the number of vertices in each primitive,
336  /// though the vertices will be unwired, so the caller is responsible
337  /// for wiring the vertices to points.
338  /// Make absolutely sure you know what you're doing if you call this!
339  /// It's used by GEO_PrimPoly::buildBlock() and GEO_PrimTetrahedron::
340  /// buildBlock().
341  /// The return value is the start offset of the primitive block,
342  /// and vertex_block_start is filled with the start offset of the
343  /// vertex block.
344  GA_Offset appendPrimitivesAndVertices(
345  const GA_PrimitiveTypeId &type,
346  const GA_PolyCounts &vertex_counts,
347  GA_Offset &vertex_block_start,
348  bool closed_flag = false);
349 
350  /// Return the number of primitives
353  { return myPrimitiveMap.indexSize(); }
354  /// This will be an exclusive, possibly loose, upper bound when iterating
355  /// over primitive offsets.
356  /// Every primitive offset in this detail will be strictly less than this.
357  /// @note (getNumPrimitives() <= getNumPrimitiveOffsets()) is always true.
360  { return myPrimitiveMap.offsetSize(); }
361  /// Given a primitive's index (in append order), return its data offset
364  { return myPrimitiveMap.offsetFromIndex(index); }
365  /// Given a primitive's data offset, return its index
368  { return myPrimitiveMap.indexFromOffset(offset); }
369 
370  /// Get the primitive by offset
371  /// @{
374  { return myPrimitiveList.get(prim_off); }
376  const GA_Primitive *getPrimitive(GA_Offset prim_off) const
377  { return myPrimitiveList.get(prim_off); }
378  /// @}
379 
380  /// Get the primitive by index
381  /// @{
383  { return myPrimitiveList.get(primitiveOffset(prim_idx)); }
385  { return myPrimitiveList.get(primitiveOffset(prim_idx)); }
386  /// @}
387 
388  /// Returns a shallow copy of the vertex list of the primitive at the
389  /// specified primitive offset.
390  /// You must include GA_Primitive.h to use this.
392  GA_OffsetListRef getPrimitiveVertexList(GA_Offset primoff) const;
393 
394  /// Returns the number of vertices in the primitive at the specified
395  /// primitive offset.
396  /// You must include GA_Primitive.h to use this.
398  GA_Size getPrimitiveVertexCount(GA_Offset primoff) const;
399 
400  /// Returns the vertex offset in the primitive at the specified
401  /// primitive offset in vertex list position i.
402  /// If you're accessing all vertex offsets, it'll be faster to
403  /// call getVertexList() once and either read from that or
404  /// call forEach(fucntor) on it.
405  /// You must include GA_Primitive.h to use this.
407  GA_Offset getPrimitiveVertexOffset(GA_Offset primoff, GA_Size i) const;
408 
409  /// Returns the type ID of the primitive at the specified
410  /// primitive offset.
411  /// You must include GA_Primitive.h to use this.
413  int getPrimitiveTypeId(GA_Offset primoff) const;
414 
415  /// Returns the "closed" flag for polygon, NURBS curve, or Bezier curve
416  /// primitives, or false for other primitive types.
417  /// You must include GA_Primitive.h to use this.
419  bool getPrimitiveClosedFlag(GA_Offset primoff) const;
420 
421  /// Sets the "closed" flag for polygon primitives.
422  /// For NURBS curve or Bezier curve primitives, use GEO_Face::close()
423  /// or GEO_Face::open().
424  /// You must include GA_Primitive.h to use this.
426  void setPrimitiveClosedFlag(GA_Offset primoff, bool closed);
427 
428 
429  /// Reorder a primitive. The index of the primitive at the given data
430  /// offset will be changed to the new order (provided that the ordered
431  /// position is in a valid range).
432  /// @return The new index of the primitive, or -1 if there was an error
433  GA_Index reorderPrimitive(GA_Offset offset, GA_Index new_order);
434 
435  /// Swap the order of the two specified primitive data offsets.
436  bool swapPrimitiveOrder(GA_Offset offset1,
437  GA_Offset offset2);
438 
439  /// Append a vertex (for the entire detail)
441  GA_Offset appendVertex() { return appendVertexBlock(1); }
442  /// Append new vertices, returning the first offset of the contiguous block
445  { return myVertexMap.addElementBlock(nvertices); }
446  /// Return the number verticies in the entire detail
449  { return myVertexMap.indexSize(); }
450  /// This will be an exclusive, possibly loose, upper bound when iterating
451  /// over vertex offsets.
452  /// Every vertex offset in this detail will be strictly less than this.
453  /// @note (getNumVertices() <= getNumVertexOffsets()) is always true.
456  { return myVertexMap.offsetSize(); }
457  /// Given a vertex's index (in append order), return its data offset
460  { return myVertexMap.offsetFromIndex(index); }
461  /// Given a vertex's data offset, return its index
464  { return myVertexMap.indexFromOffset(offset); }
465 
466  /// @private @see GA_WorkVertexBuffer
467  GA_Offset appendTemporaryPoint();
468  /// @private @see GA_WorkVertexBuffer
469  GA_Offset appendTemporaryVertex();
470 
471  /// Given a vertex, return the point it references
474  {
475  UT_ASSERT_P(!myVertexMap.isOffsetVacant(vertex));
476  return myTopology.getPointRef()->getLink(vertex);
477  }
478  /// Given a vertex, return primitive it references
479  /// Returns -1 if no topology attributes exist.
482  {
483  UT_ASSERT_P(!myVertexMap.isOffsetVacant(vertex));
484  const GA_ATITopology *pref = myTopology.getPrimitiveRef();
485  UT_ASSERT_P(pref);
486  return pref->getLink(vertex);
487  }
488 
489  /// Given a point, returns *a* vertex that it references.
490  /// More than one vertex may refer to a single point, and it is
491  /// quite possible that no vertices refer to the point.
492  /// GA_INVALID_OFFSET is returned if no vertices match.
493  /// See getVerticesReferencingPoint() for methods to get all the points.
496  {
497  UT_ASSERT_P(!myPointMap.isOffsetVacant(point));
498  const GA_ATITopology *ref = myTopology.getVertexRef();
499  UT_ASSERT_P(ref);
500  return ref->getLink(point);
501  }
502 
503  /// Given a vertex, returns the next one that shares the same
504  /// point as this vertex. GA_INVALID_OFFSET if no further
505  /// vertices match
508  {
509  UT_ASSERT_P(!myVertexMap.isOffsetVacant(vtx));
510  const GA_ATITopology *ref = myTopology.getVertexNextRef();
511  UT_ASSERT_P(ref);
512  return ref->getLink(vtx);
513  }
514 
515  /// Given a vertex, returns the previous one that shares the same
516  /// point as this vertex. GA_INVALID_OFFSET if no further
517  /// vertices match
520  {
521  UT_ASSERT_P(!myVertexMap.isOffsetVacant(vtx));
522  const GA_ATITopology *ref = myTopology.getVertexPrevRef();
523  UT_ASSERT_P(ref);
524  return ref->getLink(vtx);
525  }
526 
527  /// Given a point and primitive, find the corresponding vertex. Note that
528  /// this is O(N) on the number of vertices which share the point. If the
529  /// primitive offset is -1, then the "first" vertex which references the
530  /// point will be returned. The order of the "first" vertex is arbitrary,
531  /// though it will likely be the same for each call.
532  ///
533  /// Returns -1 if no topology attributes exist.
534  GA_Offset getVertexReferencingPoint(GA_Offset ptoff,
535  GA_Offset primoff = GA_INVALID_OFFSET) const;
536 
537  /// Given a point offset, return a list of all vertices which reference it.
538  /// NOTE: The vertex offsets might be in ANY order, and may even be
539  /// different from run to run, so DO NOT rely on the order!
540  GA_Size getVerticesReferencingPoint(
541  GA_OffsetArray &vertices,
542  GA_Offset point_offset) const;
543  /// Given a point offset, return a list of all primitives which reference it.
544  /// The primitive offsets will be in ascending order and have no duplicates,
545  /// so you can do:
546  /// detail.getPrimitivesReferencingPoint(prims0, p0off);
547  /// detail.getPrimitivesReferencingPoint(prims1, p1off);
548  /// prims0.sortedIntersection(prims1);
549  /// to quickly get a list of primitives that contain both p0off and p1off,
550  /// (not necessarily as an edge, but this can be used as a first pass check.)
551  GA_Size getPrimitivesReferencingPoint(
552  GA_OffsetArray &primitives,
553  GA_Offset point_offset) const;
554 
555  /// Returns false if any point is shared, ie, more than one vertex
556  /// points to the same point. This being true means each point
557  /// has at most one vertex and belongs to at most one primitive.
558  /// Note that points can belong to zero vertices and zero primitives
559  /// still. Requires topology.
560  bool hasNoSharedPoints() const;
561 
562  /// When destroying points, there are three different modes when dealing
563  /// with primitives that reference the points. These modes cause different
564  /// behaviours when notifying primitives about point deletion. The
565  /// behaviour is determined by the result of @c
566  /// primitive->dereferencePoint() or @c primitive->dereferencePoints().
567  /// - GA_LEAVE_PRIMITIVES @n
568  /// Primitive is destroyed if it returns GA_DEREFERENCE_DESTROY.
569  /// Point will @b not be destroyed if prim returns GA_DEREFERENCE_FAIL.
570  /// - GA_DESTROY_DEGENERATE @n
571  /// Primitive is destroyed if it returns GA_DEREFERENCE_DEGENERATE or
572  /// GA_DEREFERENCE_DESTROY. Point is not destroyed if prim returns
573  /// GA_DEREFERENCE_FAIL.
574  /// - GA_DESTROY_DEGENERATE_INCOMPATIBLE @n
575  /// Primitive is destroyed if it returns GA_DEREFERENCE_DEGENERATE,
576  /// GA_DEREFERENCE_DESTROY, or GA_DEREFERENCE_FAIL. The point will
577  /// always be destroyed.
579  {
583  };
584 
585  /// @{
586  /// Destroy the given point. This may leave dangling vertex references if
587  /// there is no full topology.
588  ///
589  /// If the @c guarantee_no_vertex_references flag is true, the operation
590  /// will be more efficient, but you must truly guarantee that there are no
591  /// vertices referring to the point.
592  bool destroyPointOffset(GA_Offset ptoff,
593  GA_DestroyPointMode mode=GA_LEAVE_PRIMITIVES,
594  bool guarantee_no_vertex_references=false);
595  bool destroyPointIndex(GA_Index index,
596  GA_DestroyPointMode mode=GA_LEAVE_PRIMITIVES,
597  bool guarantee_no_vertex_references=false);
598  /// @}
599  /// Destroy the given vertex
600  bool destroyVertexOffset(GA_Offset offset);
601  /// Destroy the given primitive. Optionally destroy any referenced points
602  /// that will no longer be in use after this operation. Note that this
603  /// option requires full topology.
604  virtual bool destroyPrimitiveOffset(GA_Offset offset,
605  bool and_points = false);
606  bool destroyPrimitiveIndex(GA_Index index,
607  bool and_points = false);
608  bool destroyPrimitive(GA_Primitive &prim,
609  bool and_points = false);
610 
611  /// Destroy the given primitives. Optionally destroy any referenced points
612  /// that will no longer be in use after this operation. Note that this
613  /// option requires full topology.
614  virtual GA_Size destroyPrimitiveOffsets(const GA_Range &it,
615  bool and_points = false);
617  bool and_points = false)
618  { return destroyPrimitiveOffsets(it, and_points); }
619  GA_Size destroyDegeneratePrimitives(const GA_Range &it,
620  bool and_points = false);
621  GA_Size destroyDegeneratePrimitives(const GA_PrimitiveGroup *prims=0, bool and_points = false);
622 
623 
624  /// Destroy unused points. If ptgrp is given, then only within the group
626  {
627  return destroyUnusedPoints(getPointRange(ptgrp));
628  }
629  /// @{
630  /// Destroy unused points in given point range
631  GA_Size destroyUnusedPoints(const GA_Range &point_range);
633  GA_DestroyPointMode mode=GA_LEAVE_PRIMITIVES,
634  bool guarantee_no_vertex_references=false)
635  {
636  return destroyElements(range, mode,
637  guarantee_no_vertex_references);
638  }
640  GA_DestroyPointMode mode=GA_LEAVE_PRIMITIVES,
641  bool guarantee_no_vertex_references=false)
642  {
643  return destroyPointOffsets(range, mode,
644  guarantee_no_vertex_references);
645  }
646  /// @}
647 
648 
650  { return destroyElements(range); }
652  { return destroyVertexOffsets(range); }
653 
654  /// Returns whether a point is referenced by any vertices
655  /// This may be a slow operation if there is no topology allocated
656  bool isPointUsed(GA_Offset point) const;
657  /// Returns if a point is referenced. Fails catastrophically
658  /// if you do not have full topology.
659  bool isPointUsedFast(GA_Offset point) const
660  {
661  return GAisValid(pointVertex(point));
662  }
663 
664  /// Returns true if there are any unused points.
665  /// If the offset list is given, it is set to all of the found
666  /// unused points.
667  bool findUnusedPoints(GA_OffsetList *unused=nullptr) const;
668 
669  // -------------- Index Maps -----------------------------
670  const GA_IndexMap &getIndexMap(GA_AttributeOwner owner) const;
672  {
673  return const_cast<GA_IndexMap &>(
674  static_cast<const GA_Detail *>(this)
675  ->getIndexMap(owner));
676  }
677  const GA_IndexMap &getPointMap() const { return myPointMap; }
678  const GA_IndexMap &getVertexMap() const { return myVertexMap; }
679  const GA_IndexMap &getPrimitiveMap() const { return myPrimitiveMap; }
680  const GA_IndexMap &getGlobalMap() const { return myGlobalMap; }
681 
682  /// This is a helpful class for getting the ranges of elements
683  /// created after such an OffsetMarker is declared. For example,
684  ///
685  /// GA_Detail::OffsetMarker marker(*gdp);
686  /// ... // Some code that creates points, vertices, or primitives
687  /// for (GA_Iterator it(marker.pointRange()); !it.atEnd(); ++it)
688  /// ... // Do something to each created point
689  /// for (GA_Iterator it(marker.vertexRange()); !it.atEnd(); ++it)
690  /// ... // Do something to each created vertex
691  /// for (GA_Iterator it(marker.primitiveRange()); !it.atEnd(); ++it)
692  /// ... // Do something to each created primitive
693  ///
694  /// NOTE: The code doing the creating can't delete elements from
695  /// the detail before adding any new elements.
697  {
698  public:
699  OffsetMarker(const GA_Detail &detail)
700  : myPointMarker(detail.getPointMap())
701  , myVertexMarker(detail.getVertexMap())
702  , myPrimitiveMarker(detail.getPrimitiveMap())
703  {}
705  { return myPointMarker.getRange(); }
707  { return myVertexMarker.getRange(); }
709  { return myPrimitiveMarker.getRange(); }
711  { return myPointMarker.getBegin(); }
713  { return myVertexMarker.getBegin(); }
715  { return myPrimitiveMarker.getBegin(); }
717  { return myPointMarker.getEnd(); }
719  { return myVertexMarker.getEnd(); }
721  { return myPrimitiveMarker.getEnd(); }
722  private:
723  const GA_IndexMap::Marker myPointMarker;
724  const GA_IndexMap::Marker myVertexMarker;
725  const GA_IndexMap::Marker myPrimitiveMarker;
726  };
727 
729  { return myPrimitiveList; }
731  { return myPrimitiveList; }
732  GA_AttributeSet &getAttributes() { return myAttributes; }
733  const GA_AttributeSet &getAttributes() const{ return myAttributes; }
734  GA_Topology &getTopology() { return myTopology; }
735  const GA_Topology &getTopology() const { return myTopology; }
736  bool checkValidTopology() const;
737  void createTopologyAttributes();
738  void clearTopologyAttributes();
739 
740  /// This bumps all data IDs in this detail, including
741  /// point, vertex, primitive, and detail attribute data IDs,
742  /// the primitive list data ID, and edge group data IDs.
743  void bumpAllDataIds();
744 
745  /// Call this to bump the appropriate topology data IDs when
746  /// vertices have been rewired to different points.
747  ///
748  /// If vertices have been added or removed, or if they've been
749  /// "stolen" by a different primitive,
750  /// just call bumpDataIdsForAddOrRemove(____,true,____) instead.
751  /// If points have been added or removed, but vertices have
752  /// only been rewired, call bumpDataIdsForAddOrRemove(true,false,false)
753  /// in addition to this.
754  void bumpDataIdsForRewire();
755 
756  /// Call this to bump the appropriate data IDs when points, vertices,
757  /// or primitives have been added or removed. If you're not 100%
758  /// sure whether an element type has been added or removed,
759  /// it's better to err on the side of safety and pass true for it.
760  void bumpDataIdsForAddOrRemove(
761  bool added_or_removed_points,
762  bool added_or_removed_vertices,
763  bool added_or_removed_primitives);
764 
765  /// @{
766  /// Get access to the attributes for one element type
767  GA_AttributeOwner getAttributeOwner(const GA_AttributeDict &dict) const;
769  { return myAttributes.getDict(owner); }
770  /// @}
771 
772  /// Defragment index maps
773  /// NOTE: To make sure that it actually defragments when there is even just
774  /// one hole, you must pass a UT_Options with a "removeholes"
775  /// bool option set to true.
776  /// NOTE: If any defragmenting occurs, this bumps data IDs for everything
777  /// that is modified.
778  bool defragment(GA_AttributeOwner owner,
779  const UT_Options *options = nullptr);
780  /// Defragment everything.
781  /// NOTE: To make sure that it actually defragments when there is even just
782  /// one hole, you must pass a UT_Options with a "removeholes"
783  /// bool option set to true.
784  /// NOTE: If any defragmenting occurs, this bumps data IDs for everything
785  /// that is modified.
786  bool defragment(const UT_Options *options = nullptr);
787 
788  /// Optimized layout of vertex index map. This sorts the vertex index map
789  /// by the primitive order use. The map will be defragmented after this
790  /// function is called.
791  void sortVertexMapByPrimitiveUse();
792 
793  // -------------- Attributes ----------------------------
794 
795  /// @{
796  /// createAttribute is very general purpose method, requiring
797  /// some knowledge about ATIs, etc. Unless you are creating
798  /// your own user-defined attributes, it would likely be better
799  /// to use something at the GEO_Detail level, like addFloatTuple.
801  GA_AttributeScope scope,
802  const UT_StringHolder &name,
803  const UT_Options *create_args,
804  const GA_AttributeOptions *attribute_options,
805  const UT_StringRef &attribtype)
806  {
807  return myAttributes.createAttribute(
808  owner, scope, name, create_args,
809  attribute_options, attribtype);
810  }
812  const UT_StringHolder &name,
813  const UT_Options *create_args,
814  const GA_AttributeOptions *attribute_options,
815  const UT_StringRef &attribtype)
816  {
817  return myAttributes.createAttribute(
818  owner, name, create_args,
819  attribute_options, attribtype);
820  }
821  /// @}
822 
823  /// This will create detached attributes. They will have the
824  /// right number of elements at the moment of creation, but
825  /// will not update with changes to the detail. The caller
826  /// is responsible for invoking delete on them as well.
827  /// These attributes will have no name.
828  /// @{
831  GA_AttributeOwner owner,
833  int tuple_size,
834  const GA_Defaults &defaults=GA_Defaults(0.0f),
835  const GA_AttributeOptions *attribute_options = nullptr) const
836  {
837  return myAttributes.createDetachedTupleAttribute(
838  owner, storage, tuple_size,
839  defaults, attribute_options);
840  }
843  GA_AttributeOwner owner,
844  const UT_StringRef &attribtype,
845  const UT_Options *create_args = nullptr,
846  const GA_AttributeOptions *attribute_options = nullptr) const
847  {
848  return myAttributes.createDetachedAttribute(
849  owner, attribtype, create_args,
850  attribute_options);
851  }
854  GA_AttributeOwner owner,
855  const GA_AttributeType &attribtype,
856  const UT_Options *create_args = nullptr,
857  const GA_AttributeOptions *attribute_options = nullptr) const
858  {
859  return myAttributes.createDetachedAttribute(
860  owner, attribtype, create_args,
861  attribute_options);
862  }
863  /// @}
864 
867  GA_AttributeScope scope,
868  const UT_StringRef &name)
869  {
870  return myAttributes.destroyAttribute(owner,
871  scope, name);
872  }
875  const UT_StringRef &name)
876  {
877  return myAttributes.destroyAttribute(owner, name);
878  }
881  GA_AttributeScope scope,
882  const UT_StringRef &fromName,
883  const UT_StringHolder &toName)
884  {
885  return myAttributes.renameAttribute(owner, scope,
886  fromName, toName);
887  }
888 
889  // Convenience attribute methods
891  GA_AttributeScope scope,
892  const UT_StringHolder &name,
893  GA_Storage storage,
894  int tuple_size,
895  const GA_Defaults &defaults = GA_Defaults(0.0f),
896  const UT_Options *create_args = nullptr,
897  const GA_AttributeOptions *attribute_options = nullptr)
898  {
899  return myAttributes.createTupleAttribute(
900  owner, scope, name, storage,
901  tuple_size, defaults,
902  create_args,
903  attribute_options);
904  }
906  const UT_StringHolder &name,
907  GA_Storage storage,
908  int tuple_size,
909  const GA_Defaults &defaults = GA_Defaults(0.0f),
910  const UT_Options *create_args = nullptr,
911  const GA_AttributeOptions *attribute_options = nullptr)
912  {
913  return myAttributes.createTupleAttribute(
914  owner, name, storage,
915  tuple_size, defaults,
916  create_args,
917  attribute_options);
918  }
920  GA_AttributeScope scope,
921  const UT_StringHolder &name,
922  const UT_Options *create_args=nullptr,
923  const GA_AttributeOptions *attribute_options=nullptr)
924  {
925  return myAttributes.createStringAttribute(
926  owner, scope, name, 1,
927  create_args,
928  attribute_options);
929  }
931  const UT_StringHolder &name,
932  const UT_Options *create_args=nullptr,
933  const GA_AttributeOptions *attribute_options=nullptr)
934  {
935  return myAttributes.createStringAttribute(
936  owner, name, 1, create_args,
937  attribute_options);
938  }
939 
940  /// Find an existing attribute, returning a read-only reference.
941  ///
944  const UT_StringRef &name,
945  const GA_AttributeOwner search_order[],
946  int search_size) const
947  {
948  return myAttributes.findAttribute(
949  scope, name, search_order,
950  search_size);
951  }
954  const GA_AttributeOwner search_order[],
955  int search_size) const
956  {
957  return myAttributes.findAttribute(
958  name, search_order, search_size);
959  }
962  GA_AttributeScope scope,
963  const UT_StringRef &name) const
964  { return findAttribute(scope, name, &owner, 1); }
967  const UT_StringRef &name) const
968  { return findAttribute(name, &owner, 1); }
971  const UT_StringRef &name) const
972  { return findAttribute(GA_ATTRIB_POINT, s, name); }
974  const GA_Attribute *findPointAttribute(const UT_StringRef &name) const
975  { return findAttribute(GA_ATTRIB_POINT, name); }
978  const UT_StringRef &name) const
979  { return findAttribute(GA_ATTRIB_VERTEX,s, name); }
982  { return findAttribute(GA_ATTRIB_VERTEX, name); }
985  const UT_StringRef &name) const
986  {return findAttribute(GA_ATTRIB_PRIMITIVE,s,name);}
989  {return findAttribute(GA_ATTRIB_PRIMITIVE, name);}
992  const UT_StringRef &name) const
993  { return findAttribute(GA_ATTRIB_GLOBAL,s, name); }
996  { return findAttribute(GA_ATTRIB_GLOBAL, name); }
997 
998  /// Find an existing attribute, returning a read-write reference.
999  ///
1002  const UT_StringRef &name,
1003  const GA_AttributeOwner search_order[],
1004  int search_size)
1005  {
1006  return myAttributes.findAttribute(
1007  scope, name, search_order,
1008  search_size);
1009  }
1012  const GA_AttributeOwner search_order[],
1013  int search_size)
1014  {
1015  return myAttributes.findAttribute(
1016  name, search_order, search_size);
1017  }
1020  GA_AttributeScope scope,
1021  const UT_StringRef &name)
1022  { return findAttribute(scope, name, &owner, 1); }
1025  const UT_StringRef &name)
1026  { return findAttribute(name, &owner, 1); }
1029  const UT_StringRef &name)
1030  { return findAttribute(GA_ATTRIB_POINT, s, name); }
1033  { return findAttribute(GA_ATTRIB_POINT, name); }
1036  const UT_StringRef &name)
1037  { return findAttribute(GA_ATTRIB_VERTEX,s, name); }
1040  { return findAttribute(GA_ATTRIB_VERTEX, name); }
1043  const UT_StringRef &name)
1044  {return findAttribute(GA_ATTRIB_PRIMITIVE,s,name);}
1047  {return findAttribute(GA_ATTRIB_PRIMITIVE, name);}
1050  const UT_StringRef &name)
1051  { return findAttribute(GA_ATTRIB_GLOBAL,s, name); }
1054  { return findAttribute(GA_ATTRIB_GLOBAL, name); }
1055 
1056  /// Get/set all the point attribute data from/to a contiguous array
1057  // @{
1058 
1059  /// Valid types for T are:
1060  /// int32, int64, fpreal32, fpreal64,
1061  /// UT_Vector2T<S>, UT_Vector3T<S>, UT_Vector4T<S>,
1062  /// UT_QuaternionT<S>, UT_Matrix3T<S>, UT_Matrix4T<S>
1063  /// where S is one of: fpreal, fpreal32, fpreal64,
1064  /// For the UT_Vector classes, S can also be one of: int, int32, int64
1065  template <typename T>
1066  bool getAttributeAsArray(
1067  const GA_Attribute *atr,
1068  const GA_Range &range,
1069  UT_Array<T> &result) const;
1070 
1071  /// Valid types for T are:
1072  /// int32, int64, fpreal32, fpreal64,
1073  /// UT_Vector2T<S>, UT_Vector3T<S>, UT_Vector4T<S>,
1074  /// UT_QuaternionT<S>, UT_Matrix3T<S>, UT_Matrix4T<S>
1075  /// where S is one of: fpreal, fpreal32, fpreal64,
1076  /// For the UT_Vector classes, S can also be one of: int, int32, int64
1077  template <typename T>
1078  bool setAttributeFromArray(
1079  GA_Attribute *atr,
1080  const GA_Range &range,
1081  const UT_Array<T> &src);
1082  // @}
1083 
1084  // -------------- Groups ---------------------------------
1085  GA_ElementGroup *createElementGroup(GA_AttributeOwner owner,
1086  const UT_StringHolder &name,
1087  bool ordered=false);
1088  GA_ElementGroup *createInternalElementGroup(GA_AttributeOwner owner,
1089  bool ordered=false);
1090  GA_ElementGroup *findElementGroup(GA_AttributeOwner owner,
1091  const UT_StringRef &name);
1092  const GA_ElementGroup *findElementGroup(GA_AttributeOwner owner,
1093  const UT_StringRef &name) const;
1094 
1095  // Only accepts GA_ATTRIB_POINT,GA_ATTRIB_VERTEX,GA_ATTRIB_PRIMITIVE
1096  const GA_ElementGroupTable &
1097  getElementGroupTable(GA_AttributeOwner owner) const;
1100  {
1101  return const_cast<GA_ElementGroupTable &>(
1102  static_cast<const GA_Detail *>(this)
1103  ->getElementGroupTable(owner));
1104  }
1105 
1106  // Gets any group table.
1107  GA_GroupTable *getGroupTable(GA_GroupType group_type);
1108  const GA_GroupTable *getGroupTable(GA_GroupType group_type) const;
1109 
1110  /// @{
1111  /// Access point, primitive, vertex, or edge group tables
1113  { return myPointGroups; }
1115  { return myPointGroups; }
1117  { return myPrimitiveGroups; }
1119  { return myPrimitiveGroups; }
1121  { return myVertexGroups; }
1123  { return myVertexGroups; }
1125  { return myEdgeGroups; }
1127  { return myEdgeGroups; }
1128  /// @}
1129 
1130  template <GA_AttributeOwner OWNER>
1134  bool ordered=false)
1135  {
1137  createElementGroup(OWNER, name, ordered));
1138  }
1139 
1140  template <GA_AttributeOwner OWNER>
1143  createInternalElementGroup(bool ordered=false)
1144  {
1146  createInternalElementGroup(OWNER,ordered));
1147  }
1148 
1149  template <GA_AttributeOwner OWNER>
1153  {
1155  findElementGroup(OWNER, name));
1156  }
1157  template <GA_AttributeOwner OWNER>
1160  findElementGroup(const UT_StringRef &name) const
1161  {
1163  findElementGroup(OWNER, name));
1164  }
1165 
1166  void getElementGroupList(GA_AttributeOwner owner,
1167  UT_Array<const GA_ElementGroup *> &list) const;
1168  void getElementGroupList(GA_AttributeOwner owner,
1172  const UT_StringRef &name)
1173  { return getElementGroupTable(owner).destroy(name); }
1176  const char *name)
1177  { return getElementGroupTable(owner).destroy(name); }
1178  bool destroyElementGroup(GA_ElementGroup *group);
1179  bool destroyGroup(GA_Group *group);
1180 
1181  // Convenience group methods
1183  const GA_PointGroup *findPointGroup(const UT_StringRef &name) const
1184  { return findElementGroup<GA_ATTRIB_POINT>(name); }
1186  const GA_VertexGroup *findVertexGroup(const UT_StringRef &name) const
1187  { return findElementGroup<GA_ATTRIB_VERTEX>(name); }
1190  { return findElementGroup<GA_ATTRIB_PRIMITIVE>(name); }
1191 
1194  { return findElementGroup<GA_ATTRIB_POINT>(name); }
1197  { return findElementGroup<GA_ATTRIB_VERTEX>(name); }
1200  { return findElementGroup<GA_ATTRIB_PRIMITIVE>(name); }
1201 
1202  GA_EdgeGroup *createEdgeGroup(const UT_StringHolder &name);
1203  GA_EdgeGroup *createInternalEdgeGroup();
1204  const GA_EdgeGroup *findEdgeGroup(const UT_StringRef &name) const;
1205  GA_EdgeGroup *findEdgeGroup(const UT_StringRef &name);
1206  void getEdgeGroupList(
1207  UT_Array<const GA_EdgeGroup *> &list) const;
1208  void getEdgeGroupList(
1209  UT_Array<GA_EdgeGroup *> &list);
1211  bool destroyEdgeGroup(const UT_StringRef &name)
1212  { return myEdgeGroups.destroy(name); }
1215  { return g ? myEdgeGroups.destroy(g) : false; }
1216 
1217  // Utility group functions
1218  GA_Size destroyEmptyGroups(GA_AttributeOwner owner);
1219  GA_Size destroyAllEmptyGroups();
1220 
1221  /// Creates a non-internal group with the specified name,
1222  /// owned by this detail.
1223  /// @{
1225  {
1226  return static_cast<GA_PointGroup *>(pointGroups().newGroup(name));
1227  }
1229  {
1230  return static_cast<GA_VertexGroup *>(vertexGroups().newGroup(name));
1231  }
1233  {
1234  return static_cast<GA_PrimitiveGroup *>(primitiveGroups().newGroup(name));
1235  }
1237  {
1238  return static_cast<GA_EdgeGroup *>(edgeGroups().newGroup(name));
1239  }
1240  /// @}
1241 
1242  /// Creates an internal group with a unique name,
1243  /// owned by this detail.
1244  /// Be sure to call GA_Detail::destroyGroup (or destroyElementGroup)
1245  /// with this group to clean it up.
1246  /// @{
1248  {
1249  return static_cast<GA_PointGroup *>(pointGroups().newInternalGroup());
1250  }
1252  {
1253  return static_cast<GA_VertexGroup *>(vertexGroups().newInternalGroup());
1254  }
1256  {
1257  return static_cast<GA_PrimitiveGroup *>(primitiveGroups().newInternalGroup());
1258  }
1260  {
1261  return static_cast<GA_EdgeGroup *>(edgeGroups().newInternalGroup());
1262  }
1263  /// @}
1264 
1265  /// Creates a detached group with no name, owned by the caller.
1266  /// Be sure to do "delete group;" to clean it up.
1267  /// NOTE: The detail knows nothing about any detached groups that
1268  /// are created.
1269  /// @{
1271  {
1272  return new GA_PointGroup(*this);
1273  }
1275  {
1276  return new GA_PrimitiveGroup(*this);
1277  }
1279  {
1280  return new GA_VertexGroup(*this);
1281  }
1283  {
1284  return new GA_EdgeGroup(*this);
1285  }
1286  /// @}
1287 
1288  /// TODO: Deprecate internal groups with user-specified names.
1289  /// @{
1290  GA_PointGroup *newPointGroup(const UT_StringHolder &name, bool internal)
1291  {
1292  return static_cast<GA_PointGroup *>(pointGroups().newGroup(name, internal));
1293  }
1295  {
1296  return static_cast<GA_PrimitiveGroup *>(primitiveGroups().newGroup(name, internal));
1297  }
1298  GA_VertexGroup *newVertexGroup(const UT_StringHolder &name, bool internal)
1299  {
1300  return static_cast<GA_VertexGroup *>(vertexGroups().newGroup(name, internal));
1301  }
1302  GA_EdgeGroup *newEdgeGroup(const UT_StringHolder &name, bool internal)
1303  {
1304  return static_cast<GA_EdgeGroup *>(edgeGroups().newGroup(name, internal));
1305  }
1306  /// @}
1307 
1308  // -------------- Intrinsics ------------------------
1309  /// Register global intrinsics.
1310  /// Each subclass should have registration which looks like: @code
1311  /// SubClass::registerIntrinsics(GA_PrimitiveFactory &factory)
1312  /// {
1313  /// GA_LocalIntrinsicMap map(factory.getDetailIntrinsics());
1314  /// BaseClass::registerIntrinsics(factory);
1315  /// map.addAttribute(...);
1316  /// map.addAttribute(...);
1317  /// }
1318  /// @endcode
1320  registerIntrinsics(GA_PrimitiveFactory &factory);
1321 
1322  /// Get the intrinsic manager for global/detail intrinsics.
1323  ///
1324  /// At the current time, these include:
1325  /// - "string globaltokens[]" @n List of all global/detail intrinsics
1326  /// - "string primitivetokens[]" @n List of all primitive intrinsics
1327  /// - "int vertexcount" @n Number of vertices in the detail
1328  /// - "int pointcount" @n Number of points in the detail
1329  /// - "int primitivecount" @n Number of primitives in the detail
1331  { return myPrimitiveFactory.getDetailIntrinsics(); }
1332 
1333  /// @{
1334  /// Query properties of the @b global/detail intrinsic
1335  /// Note that the tuple size calls the virtual method since the tuple size
1336  /// may be dynamic (i.e. basis knot vector)
1337  GA_LocalIntrinsic findIntrinsic(const char *nm) const
1338  { return getIntrinsicManager().getLocalHandle(nm); }
1340  { return getIntrinsicManager().getLocalHandle(h); }
1342  { return getIntrinsicManager().getGlobalHandle(h); }
1343 
1345  { return getIntrinsicManager().getName(h); }
1346  GA_Size getIntrinsicTupleSize(GA_LocalIntrinsic h) const;
1348  { return getIntrinsicManager().getStorage(h); }
1350  { return getIntrinsicManager().getReadOnly(h); }
1352  { return getIntrinsicManager().getOptions(h); }
1353  /// @}
1354 
1355  /// @{
1356  /// Get the value of a global/detail intrinsic.
1357  /// These methods return the number of items retrieved.
1358  GA_Size getIntrinsic(GA_LocalIntrinsic h, UT_String &val) const;
1359  GA_Size getIntrinsic(GA_LocalIntrinsic h, UT_StringArray &val) const;
1360  GA_Size getIntrinsic(GA_LocalIntrinsic h, int64 *v, GA_Size size) const;
1361  GA_Size getIntrinsic(GA_LocalIntrinsic h, fpreal64 *v, GA_Size sz) const;
1362  /// @}
1363 
1364  /// @{
1365  /// Get the value of a global/detail intrinsic.
1366  /// Returns false if not the right type or not found.
1367  /// Always will clear out the provided value.
1368  bool getIntrinsic(GA_LocalIntrinsic h, float &v) const;
1369  bool getIntrinsic(GA_LocalIntrinsic h, int &v) const;
1370  bool getIntrinsic(GA_LocalIntrinsic h, UT_Vector2 &v) const;
1371  bool getIntrinsic(GA_LocalIntrinsic h, UT_Vector3 &v) const;
1372  bool getIntrinsic(GA_LocalIntrinsic h, UT_Vector4 &v) const;
1373  bool getIntrinsic(GA_LocalIntrinsic h, UT_Matrix2 &v) const;
1374  bool getIntrinsic(GA_LocalIntrinsic h, UT_Matrix3 &v) const;
1375  bool getIntrinsic(GA_LocalIntrinsic h, UT_Matrix4 &v) const;
1376 
1377  /// @}
1378 
1379  /// @{
1380  /// Set intrinsic. This will fail if the intrinsic is read-only.
1381  /// These methods return the number of items set.
1382  GA_Size setIntrinsic(GA_LocalIntrinsic h, const char *value);
1383  GA_Size setIntrinsic(GA_LocalIntrinsic h, const UT_StringArray &value);
1384  GA_Size setIntrinsic(GA_LocalIntrinsic h, const char **val, GA_Size s);
1385  GA_Size setIntrinsic(GA_LocalIntrinsic h, const int64 val);
1386  GA_Size setIntrinsic(GA_LocalIntrinsic h, const fpreal64 val);
1387  GA_Size setIntrinsic(GA_LocalIntrinsic h, const int64 *val, GA_Size sz);
1388  GA_Size setIntrinsic(GA_LocalIntrinsic h, const fpreal64 *v, GA_Size sz);
1389  /// @}
1390 
1391  /// Calls functor on every active point offset.
1392  /// This is easiest to use with C++ lambdas, e.g.:
1393  /// detail.forEachPoint([&vec,&detail](GA_Offset ptoff) {
1394  /// vec += detail.getPos3(ptoff);
1395  /// });
1396  template<typename FUNCTOR>
1398  void forEachPoint(FUNCTOR &&functor) const
1399  {
1400  myPointMap.forEachOffset(functor);
1401  }
1402 
1403  /// Calls functor on every point offset in a group.
1404  /// This is easiest to use with C++ lambdas, e.g.:
1405  /// detail.forEachPoint(group, [&vec,&detail](GA_Offset ptoff) {
1406  /// vec += detail.getPos3(ptoff);
1407  /// });
1408  template<typename FUNCTOR>
1410  void forEachPoint(const GA_PointGroup *group, FUNCTOR &&functor) const
1411  {
1412  forEachOffset(functor, myPointMap, group);
1413  }
1414 
1415  /// Calls functor on every point offset in a group, (or not in a group
1416  /// if complement is true).
1417  template<typename FUNCTOR>
1419  void forEachPoint(const GA_PointGroup *group, bool complement, FUNCTOR &&functor) const
1420  {
1421  forEachOffset(functor, myPointMap, group, complement);
1422  }
1423 
1424  /// Like forEachPoint, except taking a functor that
1425  /// returns true to continue, and false to break.
1426  /// @{
1427  template<typename FUNCTOR>
1429  void forEachPointBreak(FUNCTOR &&functor) const
1430  {
1431  myPointMap.forEachOffsetBreak(functor);
1432  }
1433  template<typename FUNCTOR>
1435  void forEachPointBreak(const GA_PointGroup *group, FUNCTOR &&functor) const
1436  {
1437  forEachOffset(functor, myPointMap, group);
1438  }
1439  template<typename FUNCTOR>
1441  void forEachPointBreak(const GA_PointGroup *group, bool complement, FUNCTOR &&functor) const
1442  {
1443  forEachOffset(functor, myPointMap, group, complement);
1444  }
1445  /// @}
1446 
1447  /// Calls functor on every active primitive offset.
1448  /// This is easiest to use with C++ lambdas, e.g.:
1449  /// detail.forEachPrimitive([&tris,&detail](GA_Offset primoff) {
1450  /// if (detail.getPrimitiveMap().getTypeId(primoff) != GA_PRIMPOLY)
1451  /// return;
1452  /// GA_OffsetListRef vertices = detail.getPrimitiveMap().getVertexList(primoff);
1453  /// if (vertices.size() == 3 && vertices.getExtraFlag())
1454  /// tris.addOffset(primoff);
1455  /// });
1456  template<typename FUNCTOR>
1458  void forEachPrimitive(FUNCTOR &&functor) const
1459  {
1460  myPrimitiveMap.forEachOffset(functor);
1461  }
1462 
1463  /// Calls functor on every primitive offset in a group.
1464  /// This is easiest to use with C++ lambdas, e.g.:
1465  /// detail.forEachPrimitive(group, [&tris,&detail](GA_Offset primoff) {
1466  /// if (detail.getPrimitiveMap().getTypeId(primoff) != GA_PRIMPOLY)
1467  /// return;
1468  /// GA_OffsetListRef vertices = detail.getPrimitiveMap().getVertexList(primoff);
1469  /// if (vertices.size() == 3 && vertices.getExtraFlag())
1470  /// tris.addOffset(primoff);
1471  /// });
1472  template<typename FUNCTOR>
1474  void forEachPrimitive(const GA_PrimitiveGroup *group, FUNCTOR &&functor) const
1475  {
1476  forEachOffset(functor, myPrimitiveMap, group);
1477  }
1478 
1479  /// Calls functor on every primitive offset in a group, (or not in a group
1480  /// if complement is true).
1481  template<typename FUNCTOR>
1483  void forEachPrimitive(const GA_PrimitiveGroup *group, bool complement, FUNCTOR &&functor) const
1484  {
1485  forEachOffset(functor, myPrimitiveMap, group, complement);
1486  }
1487 
1488  /// Like forEachPrimitive, except taking a functor that
1489  /// returns true to continue, and false to break.
1490  /// @{
1491  template<typename FUNCTOR>
1493  void forEachPrimitiveBreak(FUNCTOR &&functor) const
1494  {
1495  myPrimitiveMap.forEachOffsetBreak(functor);
1496  }
1497  template<typename FUNCTOR>
1499  void forEachPrimitiveBreak(const GA_PrimitiveGroup *group, FUNCTOR &&functor) const
1500  {
1501  forEachOffsetBreak(functor, myPrimitiveMap, group);
1502  }
1503  template<typename FUNCTOR>
1505  void forEachPrimitiveBreak(const GA_PrimitiveGroup *group, bool complement, FUNCTOR &&functor) const
1506  {
1507  forEachOffsetBreak(functor, myPrimitiveMap, group, complement);
1508  }
1509  /// @}
1510 
1511  template<typename FUNCTOR>
1512  static void forEachOffset(FUNCTOR &&functor, const GA_IndexMap &index_map, const GA_ElementGroup *group = nullptr, bool complement = false)
1513  {
1514  // Fall back to regular case if no group.
1515  if (!group)
1516  {
1517  if (!complement)
1518  index_map.forEachOffset(functor);
1519  return;
1520  }
1521 
1522  // Group order is only relevant if not complemented.
1523  if (!complement)
1524  {
1525  const GA_ElementGroupOrder *order = group->getOrdered();
1526  if (order)
1527  {
1528  for (GA_ElementGroupOrderIndex i(0), n(order->entries()); i != n; ++i)
1529  {
1530  GA_Offset off = order->getElement(i);
1531  functor(off);
1532  }
1533  return;
1534  }
1535  }
1536 
1537  // We have a group, treated as unordered.
1538  const GA_Offset veryend = index_map.offsetSize();
1539  GA_Offset off(0);
1540  while (true)
1541  {
1542  bool value;
1543  GA_Size span_size;
1544  group->getConstantSpan(off, veryend, span_size, value);
1545  if (span_size == 0)
1546  break;
1547  if (value == complement)
1548  {
1549  off += span_size;
1550  continue;
1551  }
1552  const GA_Offset span_end = off+span_size;
1553  while (true)
1554  {
1555  off = index_map.findActiveOffset(off, span_end);
1556  GA_Offset end = index_map.findInactiveOffset(off, span_end);
1557  if (off == end)
1558  break;
1559  do
1560  {
1561  functor(off);
1562  ++off;
1563  } while (off != end);
1564  }
1565  }
1566  }
1567 
1568  template<typename FUNCTOR>
1569  static void forEachOffsetBreak(FUNCTOR &&functor, const GA_IndexMap &index_map, const GA_ElementGroup *group = nullptr, bool complement = false)
1570  {
1571  // Fall back to regular case if no group.
1572  if (!group)
1573  {
1574  if (!complement)
1575  index_map.forEachOffsetBreak(functor);
1576  return;
1577  }
1578 
1579  // Group order is only relevant if not complemented.
1580  if (!complement)
1581  {
1582  const GA_ElementGroupOrder *order = group->getOrdered();
1583  if (order)
1584  {
1585  for (GA_ElementGroupOrderIndex i(0), n(order->entries()); i != n; ++i)
1586  {
1587  GA_Offset off = order->getElement(i);
1588  if (!functor(off))
1589  return;
1590  }
1591  return;
1592  }
1593  }
1594 
1595  // We have a group, treated as unordered.
1596  const GA_Offset veryend = index_map.offsetSize();
1597  GA_Offset off(0);
1598  while (true)
1599  {
1600  bool value;
1601  GA_Size span_size;
1602  group->getConstantSpan(off, veryend, span_size, value);
1603  if (span_size == 0)
1604  break;
1605  if (value == complement)
1606  {
1607  off += span_size;
1608  continue;
1609  }
1610  const GA_Offset span_end = off+span_size;
1611  while (true)
1612  {
1613  off = index_map.findActiveOffset(off, span_end);
1614  GA_Offset end = index_map.findInactiveOffset(off, span_end);
1615  if (off == end)
1616  break;
1617  do
1618  {
1619  if (!functor(off))
1620  return;
1621  ++off;
1622  } while (off != end);
1623  }
1624  }
1625  }
1626 
1627  // -------------- Range Accessors --------------------------
1628  /// Get a range of all points in the detail
1629  GA_Range getPointRange(const GA_PointGroup *group = 0) const
1630  { return GA_Range(getPointMap(), group); }
1631  /// Get a range of all primitives in the detail
1633  { return GA_Range(getPrimitiveMap(), group); }
1634 
1635  /// Get ordered point range from base_ptnum to end_ptnum, or the end
1637  GA_Index begin_ptnum,
1638  GA_Index end_ptnum = GA_INVALID_INDEX) const
1639  {
1640  GA_Range::ordered ordered;
1641  if (!GAisValid(end_ptnum))
1642  end_ptnum = GA_Index(getNumPoints());
1643  return GA_Range(getPointMap(), begin_ptnum, end_ptnum,
1644  ordered);
1645  }
1646  /// Get ordered primitive range from base_prim to end_prim, or the end
1648  GA_Index begin_prim,
1649  GA_Index end_prim = GA_INVALID_INDEX) const
1650  {
1651  GA_Range::ordered ordered;
1652  if (!GAisValid(end_prim))
1653  end_prim = GA_Index(getNumPrimitives());
1654  return GA_Range(getPrimitiveMap(),
1655  begin_prim, end_prim, ordered);
1656  }
1657 
1658  /// Get a range of all vertices in the detail
1659  GA_Range getVertexRange(const GA_VertexGroup *group = 0) const
1660  { return GA_Range(getVertexMap(), group); }
1661  /// Get a range representing the global (detail) data
1663  { return GA_Range(getGlobalMap()); }
1664 
1665  // -------------- Common Operations ------------------------
1666  /// Compute memory usage (includes all shared memory)
1667  virtual int64 getMemoryUsage(bool inclusive) const;
1668 
1669  /// Count memory usage using a UT_MemoryCounter in order to count
1670  /// shared memory correctly.
1671  /// If inclusive is true, the size of this object is counted,
1672  /// else only memory owned by this object is counted.
1673  /// If this is pointed to by the calling object, inclusive should be true.
1674  /// If this is contained in the calling object, inclusive should be false.
1675  /// (Its memory was already counted in the size of the calling object.)
1676  virtual void countMemory(UT_MemoryCounter &counter, bool inclusive) const;
1677 
1678  // Computing the bounding box. Depending on the element being iterated,
1679  // either the point or primitive bounding box will be computed. When a
1680  // P attribute argument is not present, the detail's position attribute
1681  // is used.
1682  bool enlargeBoundingBox(UT_BoundingRect &box,
1683  const GA_Range &range) const;
1684  bool enlargeBoundingBox(UT_BoundingRect &box,
1685  const GA_Range &range,
1686  const GA_Attribute *P) const;
1687  bool enlargeBoundingBox(UT_BoundingBox &box,
1688  const GA_Range &range) const;
1689  bool enlargeBoundingBox(UT_BoundingBox &box,
1690  const GA_Range &range,
1691  const GA_Attribute *P) const;
1692 
1693  /// Compute the bounding box quickly by:
1694  /// - Computing the point bounding box of "P"
1695  /// - Computing the maximum extents of all primitives
1696  /// This requires a single pass through the P attribute along with a single
1697  /// pass through primitives.
1698  void computeQuickBounds(UT_BoundingBox &box) const;
1699 
1700  /// Compute the bounding box quickly by:
1701  /// - Computing the point bounding box of "P"
1702  /// - Computing the maximum extents of all primitives
1703  /// - Count the number of each type of primitive in the detail
1704  /// This requires a single pass through the P attribute along with a single
1705  /// pass through primitives.
1706  /// The @c counts buffer will be filled with the count of each primitive
1707  /// type in the detail. The count_buf_size should be set to
1708  /// @c getPrimitiveFactory().getPrimTypeCount();
1709  void computeQuickBounds(UT_BoundingBox &box,
1710  GA_Size counts[], GA_Size count_buf_size) const;
1711 
1712  /// Create a new detail that has all the same attributes, groups, etc. but
1713  /// has no elements.
1714  /// Subclasses should look at: cloneCopyGroupsAndAttributes()
1715  virtual GA_Detail *cloneEmptyDetail(bool clone_attributes) const = 0;
1716 
1717  /// Copy groups and attribute definitions from the source detail.
1718  ///
1719  /// The caller should ensure that all attributes are cleared before calling
1720  /// this method (i.e. call clear())
1721  void cloneCopyGroupsAndAttributes(const GA_Detail &src,
1722  bool copydetailattribs = false);
1723 
1724  /// Copy all attribute values from srcoff to destoff for
1725  /// attributes accepted by filter. If no filter is specified,
1726  /// all public attributes and non-internal groups are copied.
1727  ///
1728  /// NOTE: If you're copying multiple offsets, it's *much* faster to do:
1729  /// For each attribute, copy data for all offsets;
1730  /// rather than:
1731  /// For each offset, copy data in all attributes.
1732  /// These functions are only for if the former is too awkward
1733  /// to do in some case.
1734  /// @{
1735  void copyAttributes(
1736  GA_AttributeOwner owner,
1737  GA_Offset destoff,
1738  GA_Offset srcoff,
1739  const GA_AttributeFilter *filter = nullptr);
1740  void copyAttributes(
1741  GA_AttributeOwner owner,
1742  GA_Offset destoff,
1743  const GA_Detail &srcdetail,
1744  GA_Offset srcoff,
1745  const GA_AttributeFilter *filter = nullptr);
1746  /// @}
1747 
1748  /// Copy all attribute values from srcptoff to destptoff for point
1749  /// attributes accepted by filter. If no filter is specified,
1750  /// all public attributes and non-internal groups are copied.
1753  GA_Offset destptoff,
1754  GA_Offset srcptoff,
1755  const GA_AttributeFilter *filter = nullptr)
1756  {
1757  copyAttributes(GA_ATTRIB_POINT, destptoff, srcptoff, filter);
1758  }
1759 
1760  /// Copy all attribute values from srcvtxoff to destvtxoff for vertex
1761  /// attributes accepted by filter. If no filter is specified,
1762  /// all public attributes and non-internal groups are copied.
1763  /// If ref_point_dont_copy is true, the point of srcvtxoff is
1764  /// referenced by destvtxoff, otherwise point attributes are also
1765  /// copied.
1766  /// NOTE: If you only want to copy vertex attributes, and not the
1767  /// point, call copyAttributes(GA_ATTRIB_VERTEX, ...)
1769  GA_Offset destvtxoff,
1770  GA_Offset srcvtxoff,
1771  bool ref_point_dont_copy,
1772  const GA_AttributeFilter *filter = nullptr)
1773  {
1774  GA_Offset srcptoff = vertexPoint(srcvtxoff);
1775  if (ref_point_dont_copy)
1776  myTopology.wireVertexPoint(destvtxoff, srcptoff);
1777  else
1778  copyPoint(vertexPoint(destvtxoff), srcptoff, filter);
1779  copyAttributes(GA_ATTRIB_VERTEX, destvtxoff, srcvtxoff, filter);
1780  }
1781 
1782  /// Merge the source detail into this detail (using default options)
1783  void baseMerge(const GA_Detail &src);
1784  /// Merge the source detail into this detail with options
1785  void baseMerge(const GA_Detail &src,
1786  GA_MergeOptions &options);
1787 
1788  /// Fast version of merge for the common case of completely replacing
1789  /// all of this detail with the source detail, using data IDs to avoid
1790  /// copying things that are the same. This does not copy private
1791  /// scope attributes (except topology) or internal groups.
1792  /// When skip is given, all processing of attributes matching the filter
1793  /// will be skipped. The result is that skipped attributes may or may not
1794  /// exist afterwards, and they also won't be initialized in any expected
1795  /// way. The assumption is that the caller will fully handle creation,
1796  /// initialization, or deletion of skipped attributes.
1797  void replaceWith(const GA_Detail &src,
1798  GA_AttributeFilter *skip = nullptr);
1799 
1800  /// Fast version of merge for the case of completely replacing all of this
1801  /// detail with the points from the source detail, using data IDs to avoid
1802  /// copying things that are the same. This does not copy private
1803  /// scope attributes (except topology) or internal groups.
1804  /// It will act as if replaceWith was called and then all primitives
1805  /// were deleted, so vertex/primitive attributes will be transferred,
1806  /// but there will be no vertices or primitives.
1807  /// When skip is given, all processing of attributes matching the filter
1808  /// will be skipped. The result is that skipped attributes may or may not
1809  /// exist afterwards, and they also won't be initialized in any expected
1810  /// way. The assumption is that the caller will fully handle creation,
1811  /// initialization, or deletion of skipped attributes.
1812  void replaceWithPoints(const GA_Detail &src,
1813  GA_AttributeFilter *skip = nullptr);
1814 
1815  /// This clears any caches that subclasses of GA_Detail may have, so that
1816  /// replacing the content of the detail doesn't cause crashes.
1817  /// NOTE: You may or may not also have to call refreshCachedHandles later
1818  /// if P or Pw might be replaced or change storage.
1819  virtual void clearCaches()
1820  {
1821  clearInstanceMatrix();
1822  getPrimitiveList().destroyStashed();
1823  }
1824 
1825  /// Merge global attributes (using default options)
1826  void mergeGlobalAttributes(const GA_Detail &src);
1827  /// Merge source global attributes using options
1828  void mergeGlobalAttributes(const GA_Detail &src,
1829  GA_MergeOptions &options);
1830 
1831  /// Clone any missing attributes from the source detail, skipping P, any
1832  /// topology, and any group attributes.
1833  void cloneMissingAttributes(const GA_Detail &src,
1834  GA_AttributeOwner owner,
1835  const GA_AttributeFilter &filter);
1836  /// Clone any missing groups from the source detail.
1837  void cloneMissingGroups(const GA_Detail &src,
1838  GA_AttributeOwner owner,
1839  const GA_AttributeFilter &filter);
1840 
1841  // -------------- Stream I/O METHODS ------------------------
1842  /// Register an IO file format
1843  bool registerIO(GA_IO *io) const
1844  { return myPrimitiveFactory.registerIO(io); }
1845 
1846  /// Find an IO class. If no name is specified, the "default" IO class will
1847  /// be returned (the one specified by HOUDINI_GEOMETRY_FORMAT).
1848  const GA_IO *findIO(const char *name = nullptr) const
1849  { return myPrimitiveFactory.findIO(name); }
1850 
1851  /// Get a list of all the IO names registered. Returns the number of names
1852  /// in the array.
1853  void getIONames(UT_StringArray &names) const
1854  { return myPrimitiveFactory.getIONames(names); }
1855 
1856  /// This class is used to return the status from I/O operations on a
1857  /// GA_Detail.
1858  class IOStatus
1859  {
1860  public:
1861  IOStatus(bool success=false)
1862  : mySuccess(success)
1863  {}
1865  : mySuccess(src.mySuccess)
1866  {}
1868 
1870  {
1871  if (this != &src)
1872  mySuccess = src.mySuccess;
1873  return *this;
1874  }
1875 
1876  /// Return a boolean for success or failure.
1877  /// true means success
1878  bool success() const { return mySuccess; }
1879 
1880  /// bool operator
1881  SYS_SAFE_BOOL operator bool() const { return mySuccess; }
1882 
1883  /// For backward compatibility in older code, you can query the status
1884  /// as an integer, 0 for success, less than zero for failure.
1885  int gbstatus() const { return mySuccess ? 0 : -1; }
1886 
1887  private:
1888  bool mySuccess;
1889  };
1890 
1891  /// Save to a given filename. An extension of .gz will enable zlib
1892  /// compression (for JSON format only)
1893  /// Options include:
1894  /// - string geo:format @n Use the IO format specified by the string
1895  /// See also the options for the stream save
1896  IOStatus save(const char *filename,
1897  const GA_SaveOptions *options,
1898  UT_StringArray *errors = 0) const;
1899 
1900  /// Save to an existing ostream. JSON format will check the options for:
1901  /// - bool geo:gzip @n Enable gzip compression for JSON (false)
1902  /// - bool geo:saveinfo @n Output optional "info" section [true]
1903  /// - string info:software - Software
1904  /// - string info:artist - Artist
1905  /// - string info:hostname - Hostname comment
1906  /// - string info:comment - Arbitrary Comment
1907  /// - any info:token - Saved in the "info" section
1908  /// - bool group:saveinternal @n Save "internal" groups (debugging)
1909  IOStatus save(std::ostream &os, bool binary,
1910  const GA_SaveOptions *options,
1911  UT_StringArray *errors = 0) const;
1912  /// @{
1913  /// Save in "hclassic" format.
1914  IOStatus saveClassic(const char *, const GA_SaveOptions *) const;
1915  IOStatus saveClassic(std::ostream &os, bool, const GA_SaveOptions *) const;
1916  /// @}
1917 
1918  /// @section JSON-GA_Detail JSON Schema: GA_Detail
1919  ///
1920  /// The JSON schema for a detail can be broken down into 5 major sections
1921  /// - Header: The global information about the detail
1922  /// - References: Topological references
1923  /// - Attributes: Attribute data for elements
1924  /// - Primitives: List of primitives in the detail
1925  /// - Groups: Groups
1926  ///
1927  /// @code
1928  /// {
1929  /// "name" : "GA_Detail-Header",
1930  /// "description" : "Storage for an entire geometry object",
1931  /// "type" : "orderedmap",
1932  /// "properties": {
1933  /// // Header section
1934  /// "file_version": {
1935  /// "type" : "string",
1936  /// "description" : "File Version",
1937  /// "optional" : true,
1938  /// },
1939  /// "info": {
1940  /// "type" : "object",
1941  /// "description" :
1942  /// "Optional tags including:
1943  /// 'software' : Software used to create geometry,
1944  /// 'artist' : Artist name,
1945  /// 'hostname' : Computer name,
1946  /// 'comment' : Arbitrary comment
1947  /// etc.",
1948  /// "optional" : true,
1949  /// }
1950  /// "pointcount": {
1951  /// "type" : "integer",
1952  /// "description" : "The number of points in the geometry",
1953  /// },
1954  /// "vertexcount": {
1955  /// "type" : "integer",
1956  /// "description" : "The number of vertices in the geometry",
1957  /// },
1958  /// "primitivecount": {
1959  /// "type" : "integer",
1960  /// "description" : "The number of primitives in the geometry",
1961  /// },
1962  ///
1963  /// // Topology section
1964  /// "topology" : {
1965  /// "type" : "orderedmap",
1966  /// "description" : "Topological information",
1967  /// "properties" : {
1968  /// "pointref" : {
1969  /// "type" : [{ "$ref" : "GA_ATITopology" }],
1970  /// "description" :
1971  /// "An list of points referenced by each
1972  /// vertex. The array of 'vertexcount' items
1973  /// must contain integer values in the range of
1974  /// (0,pointcount-1)"
1975  /// }
1976  /// }
1977  /// },
1978  ///
1979  /// // Attributes section
1980  /// "attributes": {
1981  /// "type" : { "$ref" : "GA_AttributeSet" } ,
1982  /// "description" : "Vertex attributes",
1983  /// }
1984  ///
1985  /// // Primitives section
1986  /// "primitives": {
1987  /// "type" : { "$ref" : "GA_PrimitiveList" } ,
1988  /// "description" : "An array of primitives",
1989  /// }
1990  ///
1991  /// // Groups section
1992  /// "pointgroups": {
1993  /// "type" : { "$ref" : "GA_GroupTable" },
1994  /// "description" : "The list of point groups",
1995  /// "optional" : true,
1996  /// },
1997  /// "primitivegroups": {
1998  /// "type" : { "$ref" : "GA_GroupTable" },
1999  /// "description" : "The list of primitive groups",
2000  /// "optional" : true,
2001  /// },
2002  /// "vertexgroups": {
2003  /// "type" : { "$ref" : "GA_GroupTable" },
2004  /// "description" : "The list of vertex groups",
2005  /// "optional" : true,
2006  /// },
2007  /// "edgegroups": {
2008  /// "type" : { "$ref" : "GA_GroupTable" },
2009  /// "description" : "The list of edge groups",
2010  /// "optional" : true,
2011  /// },
2012  /// },
2013  /// }
2014  /// @endcode
2015  /// @see @ref JSON_FileFormat
2016  /// @note This method uses <tt>findIO(GA_IOTable::getJSONToken())</tt> and
2017  /// uses a dynamic cast to GA_IOJSON to actually do the writing.
2018  IOStatus save(UT_JSONWriter &w, const GA_SaveOptions *opts=0) const;
2019 
2020  /// Load a geometry file
2021  IOStatus load(const char *filename,
2022  const GA_LoadOptions *opts=0,
2023  UT_StringArray *errors=0);
2024 
2025  /// Load a geometry file given a UT_IStream.
2026  IOStatus load(UT_IStream &is,
2027  const GA_LoadOptions *opts=0,
2028  UT_StringArray *errors=0);
2029 
2030  /// Load geometry from a JSON stream.
2031  /// @note This method uses <tt>findIO(GA_IOTable::getJSONToken())</tt> and
2032  /// uses a dynamic cast to GA_IOJSON to actually do the loading.
2033  IOStatus load(UT_JSONParser &p,
2034  const GA_LoadOptions *opts=0,
2035  UT_StringArray *errors=0);
2036 
2037  /// @{
2038  /// Stat a disk file rather than loading the entire geometry.
2039  /// (see @ref GA_STAT_LEVEL)
2040  /// The method cannot be static since the primitive factory is required.
2041  /// The primitive factory stores the IO table for the geometry.
2042  ///
2043  /// When performing a stat on a disk file, if the format supports it, only
2044  /// the header of the file is loaded. This means that the full
2045  /// information for the geometry isn't available. Thus, this will give
2046  /// you different information than if you run stat() on geometry that's
2047  /// fully loaded into memory.
2048  ///
2049  /// If you inspect a .geo file, you can see the information that's
2050  /// available. For example, you can get the "primcount_summary" using the
2051  /// GA_Stat::getInfoOptions() method.
2052  IOStatus statFile(const char *filename, GA_Stat &stat,
2053  uint level=0xffff,
2054  const GA_LoadOptions *opts=nullptr) const;
2055  IOStatus stat(UT_JSONParser &p, GA_Stat &stat, uint level) const;
2056  /// @}
2057 
2058  /// Private methods
2059  /// @private
2060  void batchDeletion(GA_AttributeOwner owner);
2061  /// @private
2062  void adjustArraySize(GA_AttributeOwner owner, GA_Offset size);
2063  /// @private
2064  void constructElementBlock(GA_AttributeOwner owner, GA_Offset offset, GA_Offset nelements)
2065  { myAttributes.constructElementBlock(owner, offset, nelements); }
2066  /// @private
2067  void destructElement(GA_AttributeOwner owner, GA_Offset offset)
2068  { myAttributes.destructElement(owner, offset); }
2069 
2070  /// @private mergeGrowArrays() is called during the merging process
2071  /// @b prior to the actual addition of new elements to the detail.
2072  /// At this point, attribute arrays are grown to store the incoming data
2073  void mergeGrowArrays(GA_MergeMap &map, GA_AttributeOwner owner);
2074 
2075  /// Get information about the detail.
2076  /// @param stat @n - Information about detail
2077  /// @param level @n - Mask of information to retrieve
2078  /// (see @ref GA_STAT_LEVEL)
2079  /// Note that since this method queries the geometry that's fully loaded
2080  /// into memory, you will get different information than the @c statFile()
2081  /// method.
2082  bool stat(GA_Stat &stat, uint level=0xffff) const;
2083 
2084  /// Fill out only the attribute information on the stat
2085  void statAttributes(GA_Stat &stat, uint level=0xffff) const;
2086  /// Fill out only the group information on the stat
2087  void statGroups(GA_Stat &stat, uint level=0xffff) const;
2088  /// Fill out only the volume information.
2089  virtual void statVolumes(GA_Stat &stat, uint level=0xffff) const;
2090 
2091  /// Debugging output of detail
2092  static int64 printMemory(UT_WorkBuffer &buffer,
2093  bool include_total=true,
2094  int indent=3,
2095  const char *title="Geometry Memory Tracking");
2096 
2097  /// @{
2098  /// Utility casting functions used by GA_GBMacros.h to maintain (source
2099  /// code) type compatibility with the old implementations that used the
2100  /// derived GD/GEO_PrimList objects.
2101  ///
2102  /// The first argument is used solely to infer the templatized type.
2103  /// Derived classes (GD_Detail/GEO_Detail) should contain embedded
2104  /// GB_MACRO_PRIM_TYPE typedef to specify
2105  /// the proper derived type to use for the cast.
2106  template <typename T> static inline const typename T::GB_MACRO_PRIM_TYPE *
2107  GB_MACRO_CAST(const T *, const GA_Primitive *prim)
2108  { return static_cast<const typename T::GB_MACRO_PRIM_TYPE *>(prim);}
2109  template <typename T> static inline typename T::GB_MACRO_PRIM_TYPE *
2110  GB_MACRO_CAST(const T *, GA_Primitive *prim)
2111  { return static_cast<typename T::GB_MACRO_PRIM_TYPE *>(prim); }
2112  /// @}
2113 
2115 
2116  /// @{
2117  /// @private
2118  /// Methods used by GEO primitives to save/load vertex references
2119  bool loadVertexPointReferenceH9(UT_IStream &is,
2120  GA_Offset &point_offset);
2121  bool saveVertexPointReferenceH9(std::ostream &os,
2122  int binary, GA_Offset vertex_offset) const;
2123 
2124  static bool loadAttribDataH9(UT_IStream &is, GA_Offset offset,
2126  static bool saveAttribDataH9(std::ostream &os, int binary,
2127  GA_Offset offset,
2129  char delim_ch = '(');
2130  /// Convenience methods for saving/loading both a vertex's point reference
2131  /// and its attribute values in a Houdini9 compatible style. Note that the
2132  /// load wires the vertex to the loaded point.
2133  bool loadVertexH9(UT_IStream &is, GA_Offset vertex_offset,
2134  const UT_Array<GA_AttribLoadDataH9> &vtx_l);
2135  bool saveVertexH9(std::ostream &os, int binary,
2136  GA_Offset vertex_offset,
2137  const UT_Array<GA_AttribSaveDataH9> &vtx_l)
2138  const;
2139  /// @}
2140 
2141  /// Provide access to the factory. This allows users to query information
2142  /// about factories.
2144  { return myPrimitiveFactory; }
2145 
2146  /// Refreshes handles cached in the detail. This method must be called
2147  /// after changing the storage of the P attribute.
2148  virtual void refreshCachedHandles();
2149  /// Refreshes the cached myP attribute.
2150  void refreshCachedAttributes();
2151 
2152  /// @{
2153  /// Add/Remove an attribute to the tail-initialization list.
2154  ///
2155  /// When attributes grow in size, they usually initialize their values to
2156  /// the default value. However, some attributes may not adhere to this
2157  /// rule, or due to space optimizations, may have the values set to
2158  /// non-default values. In this case, they should be added to the
2159  /// tail-initialization list. When new elements are appended to the
2160  /// detail, they will be told to re-initialize the new element. Otherwise,
2161  /// the detail will assume that the element values are at their default
2162  /// value.
2163  ///
2164  /// When removing, the method will return @c true if the attribute was a
2165  /// tail initializer.
2166  ///
2167  /// @note These methods are thread-safe
2168  /// @note DO NOT CALL THESE: Use the GA_Attribute::setTailInitialization
2169  /// instead.
2170  void addTailInitializer(GA_Attribute *attrib);
2171  bool removeTailInitializer(GA_Attribute *attrib);
2172  /// @}
2173 
2174  /// Tell all tail initialization attributes to initialize the given offset
2175  /// @note This method is not thread-safe
2178  {
2179  if (myTailInitializers)
2180  doConstructTailInitializers(owner, start, size);
2181  }
2182 
2184  { return myPrimitiveList.containsType(type); }
2186  { return myPrimitiveList.countType(type); }
2188  { return myPrimitiveList.
2189  hasLocalTransform(myPrimitiveFactory); }
2191  UT_Array<const GA_Primitive *> &prims) const
2192  { return myPrimitiveList.getPrimitivesOfType(type, prims); }
2193 
2194  // ------------- Primitive Type Masks ----------------------
2195 
2196  /// Returns a primitive typemask that represents all known primitive type
2197  /// by the primitive factory that is associated with this detail.
2198  GA_PrimitiveTypeMask getPrimitiveTypeMaskAll() const;
2199 
2200  /// Returns the primitive typemask that represents all primitives in this
2201  /// detail.
2202  GA_PrimitiveTypeMask getPrimitiveTypeMask(
2203  const GA_PrimitiveGroup *group = 0) const;
2204 
2205 
2206  /// Return cached attribute instance matrix pointer
2207  const GA_AttributeInstanceMatrix &getInstanceMatrix() const;
2208 
2209  /// Clear the attribute instance matrix pointer. This is called
2210  /// automatically when point attributes are added or deleted.
2211  void clearInstanceMatrix();
2212 
2213  /// This function is entirely here so that GA has a way to check if a
2214  /// GA_Detail is a GEO_Detail (true) or GD_Detail (false).
2215  bool isPrimary() const
2216  {
2217  return myPrimitiveFactory.isForPrimaryDetail();
2218  }
2219 
2220  /// All GPU buffers that have been written to will be copied back
2221  /// to the CPU & marked clean.
2222  void flushCEWriteCaches();
2223 
2224  /// Flush all GPU-backed CE attributes, clearing them from this
2225  /// geometry.
2226  void flushCECaches();
2227 
2228  /// Copy changed/non transforming attribute values from inputgeo
2229  /// owner specifies the attribute class to act upon
2230  /// This is used by SOP_Deform/SOP_AttribVop to speed up the duplication of input gdp.
2231  void copyChangedNonTransforming(const GA_Detail *inputgeo, GA_AttributeOwner owner);
2232 
2233  static const int64 INVALID_CACHE_COUNT = -1;
2234 
2235  void incrementMetaCacheCount() { myMetaCacheCount++; }
2236  int64 getMetaCacheCount() const { return myMetaCacheCount; }
2237 
2238  /// @{
2239  /// @private
2240  class GA_API MantraGeometry
2241  {
2242  public:
2243  MantraGeometry() {}
2244  virtual ~MantraGeometry() {}
2245  virtual void refreshCachedHandles();
2246  };
2247  MantraGeometry *mantraGeometry()
2248  { return myMantraGeometry; }
2249  const MantraGeometry *mantraGeometry() const
2250  { return myMantraGeometry; }
2251  void setMantraGeometry(MantraGeometry *m)
2252  { myMantraGeometry = m; }
2253  /// @}
2254 
2255 protected:
2256  void doConstructTailInitializers(GA_AttributeOwner owner,
2257  GA_Offset start, GA_Offset size);
2258 
2259  bool loadPrimitivesH9(UT_IStream &is, int count,
2260  const GA_FileFormatH9::PrimTypeXlate &type_map,
2261  const UT_Array<GA_AttribLoadDataH9> &prim_attribs,
2262  const UT_Array<GA_AttribLoadDataH9> &vtx_attribs);
2263  bool savePrimitivesH9(std::ostream &os, int binary,
2264  const UT_Array<const GA_Primitive *> &list,
2265  const GA_FileFormatH9::PrimTypeXlate &type_map,
2266  const UT_Array<GA_AttribSaveDataH9> &prim_attribs,
2267  const UT_Array<GA_AttribSaveDataH9> &vx_attribs) const;
2268 
2269  /// @{
2270  /// Virtual implementation of intrinsic attributes. See GA_IntrinsicEval
2271  /// for further details.
2272  virtual GA_Size localIntrinsicTupleSize(GA_IntrinsicEval &eval) const;
2273  virtual GA_Size localGetIntrinsicS(GA_IntrinsicEval &eval,
2274  UT_String &value) const;
2275  virtual GA_Size localGetIntrinsicSA(GA_IntrinsicEval &eval,
2276  UT_StringArray &value) const;
2277  virtual GA_Size localGetIntrinsicI(GA_IntrinsicEval &eval,
2278  int64 *value, GA_Size size) const;
2279  virtual GA_Size localGetIntrinsicF(GA_IntrinsicEval &eval,
2280  fpreal64 *value, GA_Size size) const;
2281  virtual GA_Size localSetIntrinsicS(GA_IntrinsicEval &eval,
2282  const char *value);
2283  virtual GA_Size localSetIntrinsicSA(GA_IntrinsicEval &eval,
2284  const UT_StringArray &value);
2285  virtual GA_Size localSetIntrinsicSS(GA_IntrinsicEval &eval,
2286  const char **value, GA_Size size);
2287  virtual GA_Size localSetIntrinsicI(GA_IntrinsicEval &eval,
2288  const int64 *value, GA_Size size);
2289  virtual GA_Size localSetIntrinsicF(GA_IntrinsicEval &eval,
2290  const fpreal64 *value, GA_Size size);
2291  /// @}
2292 
2293  // Methods used by GEO when loading old style geometry files.
2294  static void finishLoadH9(
2295  const UT_Array<GA_AttribLoadDataH9> &attribs
2296  );
2297 
2298  friend class GA_AttributeSet;
2299  /// This is here just so that GA_AttributeSet::jsonSave() can call
2300  /// GEOcomputeNormals()
2301  virtual void privateComputeNormal(
2302  const GA_RWHandleV3 &normalattrib,
2303  const GA_Group *group,
2304  const float cuspangledegrees,
2305  const int method) const
2306  {}
2307  /// This is here so that GA_AttributeSet::jsonLoad() can call it
2308  /// after loading attributes, since VDB primitive loading tries to
2309  /// write to P, and we might as well have it correctly split up
2310  /// before anything might read/write it.
2311  void splitAnyFloat4P();
2312 
2313 private:
2314  void init(GA_Storage Pstore, bool isprimary, bool full_topology);
2315 
2316  GA_Offset newPrimitiveOffset();
2317 
2318  void clearData(bool for_deletion);
2319 
2320  /// Destroy elements. When destroying points, if the
2321  /// guarantee_no_vertex_point_references is true, we don't bother
2322  /// dereferencing the points (which speeds up the operation).
2323  GA_Size destroyElements(const GA_Range &range,
2324  GA_DestroyPointMode mode=GA_LEAVE_PRIMITIVES,
2325  bool guarantee_no_vertex_point_references=false);
2326 
2327  // Try to make primitives de-reference the point
2328  bool dereferencePoint(GA_Offset point,
2329  GA_DestroyPointMode mode=GA_LEAVE_PRIMITIVES);
2330  // Try to make primitives de-reference a range of points. A return value
2331  // of true means that all points in the range are no longer referenced by
2332  // primitives, while a return value of false means that some points in the
2333  // range continue to be referenced. This method may allocate a membership
2334  // query object, in which case, the caller is responsible for deleting it.
2335  bool dereferencePoints(const GA_Range &point_range,
2336  const GA_RangeMemberQuery *&point_range_query,
2337  GA_DestroyPointMode mode=GA_LEAVE_PRIMITIVES);
2338 
2339 
2340  /// Called by GA_IO during loading of optimized formats
2341  bool setLoadCounts(GA_Size npoint, GA_Size nvertex, GA_Size nprim,
2342  GA_LoadMap &load);
2343 
2344  friend class GA_IO;
2345  friend class GA_PrimitiveList;
2346 
2347  GA_PrimitiveFactory &myPrimitiveFactory;
2348  GA_IndexMap myPointMap;
2349  GA_IndexMap myVertexMap;
2350  GA_IndexMap myPrimitiveMap;
2351  GA_IndexMap myGlobalMap; // Always has a single entry
2352  GA_PrimitiveList myPrimitiveList;
2353  GA_AttributeSet myAttributes;
2354  GA_Topology myTopology;
2355  GA_Attribute *myP;
2356  GA_RWHandleV3 myHandlePV3;
2357  GA_Attribute *myPw;
2358  ga_TailInitializeTable *myTailInitializers;
2359  MantraGeometry *myMantraGeometry;
2360  mutable GA_AttributeInstanceMatrix *myInstanceMatrix;
2361  GA_PointGroupTable myPointGroups;
2362  GA_VertexGroupTable myVertexGroups;
2363  GA_PrimitiveGroupTable myPrimitiveGroups;
2364  GA_EdgeGroupTable myEdgeGroups;
2365  exint myUniqueId;
2366 
2367 
2368  /// Checking this meta cache count and the unique ID of the
2369  /// detail is sufficient to determine whether this detail
2370  /// has been modified since it was last examined, so long as it's
2371  /// not currently being used in a cook. Any cook only needs to
2372  /// increment the meta cache count once, and only if the detail
2373  /// is actually modified, (e.g. don't need to inc if instancing).
2374  ///
2375  /// NOTE: Do not rely on the detail pointer to check for modification,
2376  /// since a different detail could happen to be allocated
2377  /// at the same address in memory.
2378  int64 myMetaCacheCount;
2379 };
2380 
2381 #endif
UT_Vector2 getPos2(GA_Offset ptoff) const
The ptoff passed is the point offset.
Definition: GA_Detail.h:167
virtual void clearCaches()
Definition: GA_Detail.h:1819
void stashAll()
Definition: GA_Detail.h:137
A class to manage an ordered array which has fixed offset handles.
Definition: GA_IndexMap.h:63
GA_PointGroup * newDetachedPointGroup() const
Definition: GA_Detail.h:1270
SYS_FORCE_INLINE void forEachPrimitiveBreak(const GA_PrimitiveGroup *group, FUNCTOR &&functor) const
Definition: GA_Detail.h:1499
SYS_FORCE_INLINE void setPos3(GA_Offset ptoff, const UT_Vector3 &P)
Set P from a UT_Vector3.
Definition: GA_Detail.h:207
GA_PointGroupTable & pointGroups()
Definition: GA_Detail.h:1112
bool isPointUsedFast(GA_Offset point) const
Definition: GA_Detail.h:659
SYS_FORCE_INLINE const GA_PrimitiveGroup * findPrimitiveGroup(const UT_StringRef &name) const
Definition: GA_Detail.h:1189
Definition of a geometry attribute.
Definition: GA_Attribute.h:190
GA_Range primitiveRange() const
Definition: GA_Detail.h:708
const UT_Options * getIntrinsicOptions(GA_LocalIntrinsic h) const
Definition: GA_Detail.h:1351
void incrementMetaCacheCount()
Definition: GA_Detail.h:2235
bool containsLocalTransformPrimitive() const
Definition: GA_Detail.h:2187
GT_API const UT_StringHolder filename
GA_Range getPrimitiveRangeSlice(GA_Index begin_prim, GA_Index end_prim=GA_INVALID_INDEX) const
Get ordered primitive range from base_prim to end_prim, or the end.
Definition: GA_Detail.h:1647
SYS_FORCE_INLINE const GA_Attribute * findGlobalAttribute(GA_AttributeScope s, const UT_StringRef &name) const
Definition: GA_Detail.h:991
const GA_VertexGroupTable & vertexGroups() const
Definition: GA_Detail.h:1122
SYS_FORCE_INLINE GA_Primitive * getPrimitive(GA_Offset prim_off)
Definition: GA_Detail.h:373
SYS_FORCE_INLINE void copyPoint(GA_Offset destptoff, GA_Offset srcptoff, const GA_AttributeFilter *filter=nullptr)
Definition: GA_Detail.h:1752
GA_Attribute * createAttribute(GA_AttributeOwner owner, const UT_StringHolder &name, const UT_Options *create_args, const GA_AttributeOptions *attribute_options, const UT_StringRef &attribtype)
Definition: GA_Detail.h:811
bool setLoadCounts(GA_Detail &gdp, GA_Size npoints, GA_Size nvertex, GA_Size nprimitive, GA_LoadMap &loadmap) const
GLenum GLint * range
Definition: glcorearb.h:1924
SYS_FORCE_INLINE const GA_Attribute * findVertexAttribute(const UT_StringRef &name) const
Definition: GA_Detail.h:981
GA_Primitive GB_MACRO_PRIM_TYPE
Definition: GA_Detail.h:2114
GA_Primitive * getPrimitiveByIndex(GA_Index prim_idx)
Definition: GA_Detail.h:382
GA_Range getVertexRange(const GA_VertexGroup *group=0) const
Get a range of all vertices in the detail.
Definition: GA_Detail.h:1659
int gbstatus() const
Definition: GA_Detail.h:1885
SYS_FORCE_INLINE void forEachPointBreak(const GA_PointGroup *group, bool complement, FUNCTOR &&functor) const
Definition: GA_Detail.h:1441
void getIONames(UT_StringArray &names) const
Definition: GA_Detail.h:1853
const GA_IndexMap & getPrimitiveMap() const
Definition: GA_Detail.h:679
SYS_FORCE_INLINE GA_Attribute * findGlobalAttribute(const UT_StringRef &name)
Definition: GA_Detail.h:1053
static T::GB_MACRO_PRIM_TYPE * GB_MACRO_CAST(const T *, GA_Primitive *prim)
Definition: GA_Detail.h:2110
GA_Size destroyVertexOffsets(const GA_Range &range)
Definition: GA_Detail.h:649
GA_PointGroup * newInternalPointGroup()
Definition: GA_Detail.h:1247
void constructTailInitializers(GA_AttributeOwner owner, GA_Offset start, GA_Offset size=GA_Offset(1))
Definition: GA_Detail.h:2176
Class which stores the default values for a GA_Attribute.
Definition: GA_Defaults.h:35
UT_Vector2T< float > UT_Vector2
const GA_IO * findIO(const char *name=nullptr) const
Definition: GA_Detail.h:1848
SYS_FORCE_INLINE const GA_Attribute * findVertexAttribute(GA_AttributeScope s, const UT_StringRef &name) const
Definition: GA_Detail.h:977
GA_StorageClass
Definition: GA_Types.h:68
void skip(T &in, int n)
Definition: ImfXdr.h:885
const GLdouble * v
Definition: glcorearb.h:836
UT_Vector4 getPos4(GA_Offset ptoff) const
The ptoff passed is the point offset.
Definition: GA_Detail.h:252
GLuint start
Definition: glcorearb.h:474
GA_IndexMap & getIndexMap(GA_AttributeOwner owner)
Definition: GA_Detail.h:671
bool GAisValid(GA_Size v)
Definition: GA_Types.h:625
OffsetMarker(const GA_Detail &detail)
Definition: GA_Detail.h:699
SYS_FORCE_INLINE void setPos3(GA_Offset ptoff, fpreal x, fpreal y, fpreal z)
Set P given the x, y, z components.
Definition: GA_Detail.h:213
GA_EdgeGroup * newEdgeGroup(const UT_StringHolder &name, bool internal)
Definition: GA_Detail.h:1302
void setMantraGeometry(MantraGeometry *m)
Definition: GA_Detail.h:2251
const GLuint GLenum const void * binary
Definition: glcorearb.h:1923
UT_Vector3T< float > UT_Vector3
GA_VertexGroup * newInternalVertexGroup()
Definition: GA_Detail.h:1251
const GA_IndexMap & getGlobalMap() const
Definition: GA_Detail.h:680
GLdouble GLdouble GLdouble z
Definition: glcorearb.h:847
GLboolean GLboolean g
Definition: glcorearb.h:1221
const MantraGeometry * mantraGeometry() const
Definition: GA_Detail.h:2249
The merge map keeps track of information when merging details.
Definition: GA_MergeMap.h:53
GLint level
Definition: glcorearb.h:107
GA_Attribute * getP()
Convenience method to access the P attribute.
Definition: GA_Detail.h:163
const GA_Primitive * getPrimitiveByIndex(GA_Index prim_idx) const
Definition: GA_Detail.h:384
GA_Range pointRange() const
Definition: GA_Detail.h:704
T & x(void)
Definition: UT_Vector2.h:285
GA_StorageClass getIntrinsicStorage(GA_LocalIntrinsic h) const
Definition: GA_Detail.h:1347
const GA_Attribute * getP() const
Definition: GA_Detail.h:164
SYS_FORCE_INLINE const GA_Attribute * findAttribute(GA_AttributeOwner owner, GA_AttributeScope scope, const UT_StringRef &name) const
Definition: GA_Detail.h:961
SYS_FORCE_INLINE GA_Attribute * findAttribute(GA_AttributeOwner owner, const UT_StringRef &name)
Definition: GA_Detail.h:1024
SYS_FORCE_INLINE GA_ElementGroupTableT< OWNER >::GROUP_TYPE * createElementGroup(const UT_StringHolder &name, bool ordered=false)
Definition: GA_Detail.h:1133
JSON reader class which handles parsing of JSON or bJSON files.
Definition: UT_JSONParser.h:75
SYS_FORCE_INLINE const GA_Attribute * findGlobalAttribute(const UT_StringRef &name) const
Definition: GA_Detail.h:995
SYS_FORCE_INLINE GA_Attribute * findPointAttribute(GA_AttributeScope s, const UT_StringRef &name)
Definition: GA_Detail.h:1028
Class used to map H9 geometry files to a form used by GA.
Definition: GA_AIFFileH9.h:317
Manager to keep track of global handle to name mappings.
GLint y
Definition: glcorearb.h:102
#define GA_API
Definition: GA_API.h:12
SYS_FORCE_INLINE void forEachOffset(FUNCTOR &&functor) const
Calls functor on every active offset in this index map.
Definition: GA_IndexMap.h:493
Class which writes ASCII or binary JSON streams.
Definition: UT_JSONWriter.h:32
GA_Range vertexRange() const
Definition: GA_Detail.h:706
Abstract base class for a range membership query object.
GA_PrimitiveGroup * newInternalPrimitiveGroup()
Definition: GA_Detail.h:1255
GA_EdgeGroupTable & edgeGroups()
Definition: GA_Detail.h:1124
IOStatus & operator=(const IOStatus &src)
Definition: GA_Detail.h:1869
SYS_FORCE_INLINE GA_Attribute * createDetachedAttribute(GA_AttributeOwner owner, const UT_StringRef &attribtype, const UT_Options *create_args=nullptr, const GA_AttributeOptions *attribute_options=nullptr) const
Definition: GA_Detail.h:842
SYS_FORCE_INLINE UT_Vector3 getPos3(GA_Offset ptoff) const
The ptoff passed is the point offset.
Definition: GA_Detail.h:174
static const T::GB_MACRO_PRIM_TYPE * GB_MACRO_CAST(const T *, const GA_Primitive *prim)
Definition: GA_Detail.h:2107
SYS_FORCE_INLINE T & x(void)
Definition: UT_Vector3.h:498
GA_PointGroup * newPointGroup(const UT_StringHolder &name)
Definition: GA_Detail.h:1224
GLfloat GLfloat GLfloat GLfloat v3
Definition: glcorearb.h:818
SYS_FORCE_INLINE const GA_ElementGroupTableT< OWNER >::GROUP_TYPE * findElementGroup(const UT_StringRef &name) const
Definition: GA_Detail.h:1160
SYS_FORCE_INLINE void forEachPointBreak(const GA_PointGroup *group, FUNCTOR &&functor) const
Definition: GA_Detail.h:1435
SYS_FORCE_INLINE GA_PrimitiveGroup * findPrimitiveGroup(const UT_StringRef &name)
Definition: GA_Detail.h:1199
GA_Offset pointBegin() const
Definition: GA_Detail.h:710
SYS_FORCE_INLINE GA_Attribute * findPrimitiveAttribute(GA_AttributeScope s, const UT_StringRef &name)
Definition: GA_Detail.h:1042
SYS_FORCE_INLINE GA_Attribute * createDetachedAttribute(GA_AttributeOwner owner, const GA_AttributeType &attribtype, const UT_Options *create_args=nullptr, const GA_AttributeOptions *attribute_options=nullptr) const
Definition: GA_Detail.h:853
GLuint buffer
Definition: glcorearb.h:659
png_uint_32 i
Definition: png.h:2877
exint GA_Size
Defines the bit width for index and offset types in GA.
Definition: GA_Types.h:211
bool setPos3FromArray(const GA_Range &ptrange, const UT_Array< UT_Vector3T< T > > &positions)
Definition: GA_Detail.h:192
GA_DestroyPointMode
Definition: GA_Detail.h:578
GLsizeiptr size
Definition: glcorearb.h:663
GA_Size destroyPrimitives(const GA_Range &it, bool and_points=false)
Definition: GA_Detail.h:616
SYS_FORCE_INLINE GA_Offset vertexToPrevVertex(GA_Offset vtx) const
Definition: GA_Detail.h:519
#define GA_INVALID_OFFSET
Definition: GA_Types.h:654
GA_Size countPrimitiveType(const GA_PrimitiveTypeId &type) const
Definition: GA_Detail.h:2185
SYS_FORCE_INLINE GA_Offset findActiveOffset(GA_Offset start, GA_Offset end) const
Definition: GA_IndexMap.h:477
A range of elements in an index-map.
Definition: GA_Range.h:42
GA_PrimitiveGroup * newPrimitiveGroup(const UT_StringHolder &name)
Definition: GA_Detail.h:1232
int GA_GlobalIntrinsic
Definition: GA_Types.h:671
A string map of attributes to ease backward compatibility In the GB/GEO/GU library code would often p...
SYS_FORCE_INLINE const GA_Attribute * findPointAttribute(const UT_StringRef &name) const
Definition: GA_Detail.h:974
SYS_FORCE_INLINE GA_VertexGroup * findVertexGroup(const UT_StringRef &name)
Definition: GA_Detail.h:1196
GA_Size GA_Offset
Definition: GA_Types.h:617
GA_VertexGroup * newVertexGroup(const UT_StringHolder &name, bool internal)
Definition: GA_Detail.h:1298
SYS_FORCE_INLINE void forEachPrimitiveBreak(FUNCTOR &&functor) const
Definition: GA_Detail.h:1493
long long int64
Definition: SYS_Types.h:107
int GA_LocalIntrinsic
Definition: GA_Types.h:670
GA_EdgeGroup * newInternalEdgeGroup()
Definition: GA_Detail.h:1259
GA_VertexGroupTable & vertexGroups()
Definition: GA_Detail.h:1120
GA_AttributeScope
Definition: GA_Types.h:121
SYS_FORCE_INLINE const GA_Attribute * findAttribute(GA_AttributeOwner owner, const UT_StringRef &name) const
Definition: GA_Detail.h:966
GLdouble n
Definition: glcorearb.h:2007
GLfloat f
Definition: glcorearb.h:1925
MantraGeometry * mantraGeometry()
Definition: GA_Detail.h:2247
SYS_FORCE_INLINE GA_Index primitiveIndex(GA_Offset offset) const
Given a primitive's data offset, return its index.
Definition: GA_Detail.h:367
void setPos4(GA_Offset ptoff, fpreal x, fpreal y, fpreal z, fpreal w)
Set P given the x, y, z, w components.
Definition: GA_Detail.h:264
UT_Vector4T< float > UT_Vector4
GA_Range getPointRange(const GA_PointGroup *group=0) const
Get a range of all points in the detail.
Definition: GA_Detail.h:1629
const GA_IndexMap & getPointMap() const
Definition: GA_Detail.h:677
GA_Offset primitiveEnd() const
Definition: GA_Detail.h:720
const GA_Topology & getTopology() const
Definition: GA_Detail.h:735
GA_Range getGlobalRange() const
Get a range representing the global (detail) data.
Definition: GA_Detail.h:1662
const GA_AttributeSet & getAttributes() const
Definition: GA_Detail.h:733
static void forEachOffsetBreak(FUNCTOR &&functor, const GA_IndexMap &index_map, const GA_ElementGroup *group=nullptr, bool complement=false)
Definition: GA_Detail.h:1569
GA_PointGroup * newPointGroup(const UT_StringHolder &name, bool internal)
Definition: GA_Detail.h:1290
GA_Offset pointEnd() const
Definition: GA_Detail.h:716
ElementType< OWNER, true >::Class GROUP_TYPE
SYS_FORCE_INLINE const GA_Primitive * getPrimitive(GA_Offset prim_off) const
Definition: GA_Detail.h:376
GA_Size GA_ElementGroupOrderIndex
Class used to keep track of inheritance of intrinsic attribute evaluation.
GLint ref
Definition: glcorearb.h:123
#define SYS_SAFE_BOOL
Definition: SYS_Compiler.h:62
SYS_FORCE_INLINE GA_Offset appendPointBlock(GA_Size npoints)
Append new points, returning the first offset of the contiguous block.
Definition: GA_Detail.h:281
SYS_FORCE_INLINE void forEachPoint(FUNCTOR &&functor) const
Definition: GA_Detail.h:1398
SYS_FORCE_INLINE bool destroyElementGroup(GA_AttributeOwner owner, const UT_StringRef &name)
Definition: GA_Detail.h:1171
int64 exint
Definition: SYS_Types.h:116
GA_EdgeGroup * newEdgeGroup(const UT_StringHolder &name)
Definition: GA_Detail.h:1236
#define UT_ASSERT_P(ZZ)
Definition: UT_Assert.h:125
bool registerIO(GA_IO *io) const
Register an IO file format.
Definition: GA_Detail.h:1843
SYS_FORCE_INLINE const GA_PointGroup * findPointGroup(const UT_StringRef &name) const
Definition: GA_Detail.h:1183
SYS_FORCE_INLINE void forEachPrimitive(FUNCTOR &&functor) const
Definition: GA_Detail.h:1458
GA_PrimitiveGroup * newDetachedPrimitiveGroup() const
Definition: GA_Detail.h:1274
double fpreal64
Definition: SYS_Types.h:192
SYS_FORCE_INLINE GA_Offset appendVertex()
Append a vertex (for the entire detail)
Definition: GA_Detail.h:441
const GA_EdgeGroupTable & edgeGroups() const
Definition: GA_Detail.h:1126
GLuint GLuint end
Definition: glcorearb.h:474
int method
Definition: png.h:1924
#define SYS_FORCE_INLINE
Definition: SYS_Inline.h:45
bool success() const
Definition: GA_Detail.h:1878
GA_Size destroyUnusedPoints(const GA_PointGroup *ptgrp=0)
Destroy unused points. If ptgrp is given, then only within the group.
Definition: GA_Detail.h:625
GLintptr offset
Definition: glcorearb.h:664
SYS_FORCE_INLINE GA_Offset appendPoint()
Append a new point, returning its new data offset.
Definition: GA_Detail.h:277
GA_AttributeSet & getAttributes()
Definition: GA_Detail.h:732
bool getIntrinsicReadOnly(GA_LocalIntrinsic h) const
Definition: GA_Detail.h:1349
SYS_FORCE_INLINE void translatePoint(GA_Offset ptoff, const UT_Vector3 &delta)
Definition: GA_Detail.h:221
GA_Attribute * createStringAttribute(GA_AttributeOwner owner, GA_AttributeScope scope, const UT_StringHolder &name, const UT_Options *create_args=nullptr, const GA_AttributeOptions *attribute_options=nullptr)
Definition: GA_Detail.h:919
SYS_FORCE_INLINE GA_Attribute * findPrimitiveAttribute(const UT_StringRef &name)
Definition: GA_Detail.h:1046
SYS_FORCE_INLINE GA_Offset pointVertex(GA_Offset point) const
Definition: GA_Detail.h:495
SYS_FORCE_INLINE GA_Offset findInactiveOffset(GA_Offset start, GA_Offset end) const
Definition: GA_IndexMap.h:471
SYS_FORCE_INLINE GA_Attribute * findPointAttribute(const UT_StringRef &name)
Definition: GA_Detail.h:1032
IOStatus(const IOStatus &src)
Definition: GA_Detail.h:1864
const GA_PointGroupTable & pointGroups() const
Definition: GA_Detail.h:1114
SYS_FORCE_INLINE GA_Offset getNumPointOffsets() const
Definition: GA_Detail.h:292
SYS_FORCE_INLINE GA_Attribute * findAttribute(const UT_StringRef &name, const GA_AttributeOwner search_order[], int search_size)
Definition: GA_Detail.h:1011
GA_EdgeGroup * newDetachedEdgeGroup() const
Definition: GA_Detail.h:1282
SYS_FORCE_INLINE GA_Index vertexIndex(GA_Offset offset) const
Given a vertex's data offset, return its index.
Definition: GA_Detail.h:463
Options during loading.
Definition: GA_LoadMap.h:42
SYS_FORCE_INLINE GA_Offset getNumVertexOffsets() const
Definition: GA_Detail.h:455
SYS_FORCE_INLINE GA_ElementGroupTableT< OWNER >::GROUP_TYPE * findElementGroup(const UT_StringRef &name)
Definition: GA_Detail.h:1152
SYS_FORCE_INLINE GA_Attribute * findAttribute(GA_AttributeScope scope, const UT_StringRef &name, const GA_AttributeOwner search_order[], int search_size)
Definition: GA_Detail.h:1001
const GA_IndexMap & getVertexMap() const
Definition: GA_Detail.h:678
SYS_FORCE_INLINE GA_Offset vertexPoint(GA_Offset vertex) const
Given a vertex, return the point it references.
Definition: GA_Detail.h:473
SYS_FORCE_INLINE GA_Attribute * findGlobalAttribute(GA_AttributeScope s, const UT_StringRef &name)
Definition: GA_Detail.h:1049
GA_Range getPointRangeSlice(GA_Index begin_ptnum, GA_Index end_ptnum=GA_INVALID_INDEX) const
Get ordered point range from base_ptnum to end_ptnum, or the end.
Definition: GA_Detail.h:1636
SYS_FORCE_INLINE GA_PointGroup * findPointGroup(const UT_StringRef &name)
Definition: GA_Detail.h:1193
GLuint const GLchar * name
Definition: glcorearb.h:785
SYS_FORCE_INLINE const GA_Attribute * findAttribute(GA_AttributeScope scope, const UT_StringRef &name, const GA_AttributeOwner search_order[], int search_size) const
Definition: GA_Detail.h:943
SYS_FORCE_INLINE bool destroyEdgeGroup(const UT_StringRef &name)
Definition: GA_Detail.h:1211
GA_Size GA_Index
Define the strictness of GA_Offset/GA_Index.
Definition: GA_Types.h:611
GA_PrimitiveList & getPrimitiveList()
Definition: GA_Detail.h:730
SYS_FORCE_INLINE bool destroyEdgeGroup(GA_EdgeGroup *g)
Definition: GA_Detail.h:1214
SYS_FORCE_INLINE const GA_Attribute * findPrimitiveAttribute(const UT_StringRef &name) const
Definition: GA_Detail.h:988
unsigned int uint
Definition: SYS_Types.h:40
GA_GlobalIntrinsic findGlobalIntrinsic(GA_LocalIntrinsic h) const
Definition: GA_Detail.h:1341
GLint GLsizei count
Definition: glcorearb.h:404
SYS_FORCE_INLINE GA_Offset vertexToNextVertex(GA_Offset vtx) const
Definition: GA_Detail.h:507
exint getUniqueId() const
Definition: GA_Detail.h:116
GA_Topology & getTopology()
Definition: GA_Detail.h:734
SYS_FORCE_INLINE void forEachPoint(const GA_PointGroup *group, FUNCTOR &&functor) const
Definition: GA_Detail.h:1410
GA_Offset getElement(GA_ElementGroupOrderIndex i) const
Will return -1 if the i'th entry is a mixed entry.
A list of primitives.
GLenum mode
Definition: glcorearb.h:98
SYS_FORCE_INLINE void forEachPrimitiveBreak(const GA_PrimitiveGroup *group, bool complement, FUNCTOR &&functor) const
Definition: GA_Detail.h:1505
SYS_FORCE_INLINE const GA_Attribute * findPrimitiveAttribute(GA_AttributeScope s, const UT_StringRef &name) const
Definition: GA_Detail.h:984
GA_LocalIntrinsic findIntrinsic(const char *nm) const
Definition: GA_Detail.h:1337
GA_Size destroyPointOffsets(const GA_Range &range, GA_DestroyPointMode mode=GA_LEAVE_PRIMITIVES, bool guarantee_no_vertex_references=false)
Definition: GA_Detail.h:632
GA_Attribute * createTupleAttribute(GA_AttributeOwner owner, const UT_StringHolder &name, GA_Storage storage, int tuple_size, const GA_Defaults &defaults=GA_Defaults(0.0f), const UT_Options *create_args=nullptr, const GA_AttributeOptions *attribute_options=nullptr)
Definition: GA_Detail.h:905
SYS_FORCE_INLINE GA_Index pointIndex(GA_Offset offset) const
Given a point's data offset, return its index.
Definition: GA_Detail.h:300
SYS_FORCE_INLINE GA_ElementGroupTable & getElementGroupTable(GA_AttributeOwner owner)
Definition: GA_Detail.h:1099
SYS_FORCE_INLINE GA_Size getNumVertices() const
Return the number verticies in the entire detail.
Definition: GA_Detail.h:448
GA_Size entries() const
Return the total number of entries, mixed or not.
GLfloat GLfloat GLfloat GLfloat h
Definition: glcorearb.h:2001
SYS_FORCE_INLINE GA_Offset vertexPrimitive(GA_Offset vertex) const
Definition: GA_Detail.h:481
static const GROUP_TYPE * castGroup(const GA_ElementGroup *group)
SYS_FORCE_INLINE T & y(void)
Definition: UT_Vector3.h:500
GA_Offset vertexEnd() const
Definition: GA_Detail.h:718
GLsizei const GLfloat * value
Definition: glcorearb.h:823
GA_VertexGroup * newDetachedVertexGroup() const
Definition: GA_Detail.h:1278
GA_AttributeOwner
Definition: GA_Types.h:33
double fpreal
Definition: SYS_Types.h:270
A map of string to various well defined value types.
Definition: UT_Options.h:42
Class to return information about a GA_Detail.
Definition: GA_Stat.h:50
GA_LocalIntrinsic findIntrinsic(GA_GlobalIntrinsic h) const
Definition: GA_Detail.h:1339
void clear()
Definition: GA_Detail.h:126
GA_Offset vertexBegin() const
Definition: GA_Detail.h:712
SYS_FORCE_INLINE GA_Offset getNumPrimitiveOffsets() const
Definition: GA_Detail.h:359
void copyVertex(GA_Offset destvtxoff, GA_Offset srcvtxoff, bool ref_point_dont_copy, const GA_AttributeFilter *filter=nullptr)
Definition: GA_Detail.h:1768
SYS_FORCE_INLINE GA_Offset primitiveOffset(GA_Index index) const
Given a primitive's index (in append order), return its data offset.
Definition: GA_Detail.h:363
SYS_FORCE_INLINE GA_ElementGroupTableT< OWNER >::GROUP_TYPE * createInternalElementGroup(bool ordered=false)
Definition: GA_Detail.h:1143
SYS_FORCE_INLINE bool destroyAttribute(GA_AttributeOwner owner, const UT_StringRef &name)
Definition: GA_Detail.h:874
GA_GroupType
An ordinal enum for the different types of groups in GA.
Definition: GA_Types.h:138
GLuint index
Definition: glcorearb.h:785
bool containsPrimitiveType(const GA_PrimitiveTypeId &type) const
Definition: GA_Detail.h:2183
SYS_FORCE_INLINE GA_Size getNumPrimitives() const
Return the number of primitives.
Definition: GA_Detail.h:352
SYS_FORCE_INLINE void forEachPoint(const GA_PointGroup *group, bool complement, FUNCTOR &&functor) const
Definition: GA_Detail.h:1419
GLint GLenum GLint x
Definition: glcorearb.h:408
Class used to map the GA attribute into a form for H9 geometry files.
Definition: GA_AIFFileH9.h:261
Compute an instance transform given a set of attributes.
GLuint GLfloat * val
Definition: glcorearb.h:1607
GA_PrimitiveGroup * newPrimitiveGroup(const UT_StringHolder &name, bool internal)
Definition: GA_Detail.h:1294
int64 getMetaCacheCount() const
Definition: GA_Detail.h:2236
SYS_FORCE_INLINE bool renameAttribute(GA_AttributeOwner owner, GA_AttributeScope scope, const UT_StringRef &fromName, const UT_StringHolder &toName)
Definition: GA_Detail.h:880
SYS_FORCE_INLINE void forEachPointBreak(FUNCTOR &&functor) const
Definition: GA_Detail.h:1429
const GA_PrimitiveList & getPrimitiveList() const
Definition: GA_Detail.h:728
const GA_Attribute * getPwAttribute() const
Definition: GA_Detail.h:241
Provide options when performing a merge operation.
IOStatus(bool success=false)
Definition: GA_Detail.h:1861
#define GA_INVALID_INDEX
Definition: GA_Types.h:653
GLint GLint GLsizei GLint GLenum GLenum type
Definition: glcorearb.h:107
GA_Size destroyPoints(const GA_Range &range, GA_DestroyPointMode mode=GA_LEAVE_PRIMITIVES, bool guarantee_no_vertex_references=false)
Definition: GA_Detail.h:639
SYS_FORCE_INLINE GA_Attribute * findAttribute(GA_AttributeOwner owner, GA_AttributeScope scope, const UT_StringRef &name)
Definition: GA_Detail.h:1019
bool getPos3AsArray(const GA_Range &ptrange, UT_Array< UT_Vector3T< T > > &positions) const
Definition: GA_Detail.h:182
void destroyStashed()
Definition: GA_Detail.h:155
SYS_FORCE_INLINE void forEachPrimitive(const GA_PrimitiveGroup *group, bool complement, FUNCTOR &&functor) const
Definition: GA_Detail.h:1483
getOption("OpenEXR.storage") storage
Definition: HDK_Image.dox:276
GA_PrimitiveGroupTable & primitiveGroups()
Definition: GA_Detail.h:1116
Container class for all geometry.
Definition: GA_Detail.h:95
bool isPrimary() const
Definition: GA_Detail.h:2215
T & y(void)
Definition: UT_Vector2.h:287
GLubyte GLubyte GLubyte GLubyte w
Definition: glcorearb.h:856
GA_Size destroyVertices(const GA_Range &range)
Definition: GA_Detail.h:651
SYS_FORCE_INLINE bool destroyAttribute(GA_AttributeOwner owner, GA_AttributeScope scope, const UT_StringRef &name)
Definition: GA_Detail.h:866
SYS_FORCE_INLINE void forEachPrimitive(const GA_PrimitiveGroup *group, FUNCTOR &&functor) const
Definition: GA_Detail.h:1474
SYS_FORCE_INLINE GA_Attribute * findVertexAttribute(GA_AttributeScope s, const UT_StringRef &name)
Definition: GA_Detail.h:1035
virtual void privateComputeNormal(const GA_RWHandleV3 &normalattrib, const GA_Group *group, const float cuspangledegrees, const int method) const
Definition: GA_Detail.h:2301
const GA_AttributeDict & getAttributeDict(GA_AttributeOwner owner) const
Definition: GA_Detail.h:768
SYS_FORCE_INLINE GA_Offset vertexOffset(GA_Index index) const
Given a vertex's index (in append order), return its data offset.
Definition: GA_Detail.h:459
const GA_PrimitiveGroupTable & primitiveGroups() const
Definition: GA_Detail.h:1118
GA_VertexGroup * newVertexGroup(const UT_StringHolder &name)
Definition: GA_Detail.h:1228
SYS_FORCE_INLINE const GA_Attribute * findAttribute(const UT_StringRef &name, const GA_AttributeOwner search_order[], int search_size) const
Definition: GA_Detail.h:953
T & w(void)
Definition: UT_Vector4.h:381
SYS_FORCE_INLINE const GA_Attribute * findPointAttribute(GA_AttributeScope s, const UT_StringRef &name) const
Definition: GA_Detail.h:970
GA_Range getPrimitiveRange(const GA_PrimitiveGroup *group=0) const
Get a range of all primitives in the detail.
Definition: GA_Detail.h:1632
SYS_FORCE_INLINE const GA_VertexGroup * findVertexGroup(const UT_StringRef &name) const
Definition: GA_Detail.h:1186
void setPos2(GA_Offset ptoff, const UT_Vector2 &P)
Set P from a UT_Vector2.
Definition: GA_Detail.h:200
Class to specify options for loading geometry.
SYS_FORCE_INLINE bool destroyElementGroup(GA_AttributeOwner owner, const char *name)
Definition: GA_Detail.h:1175
static void forEachOffset(FUNCTOR &&functor, const GA_IndexMap &index_map, const GA_ElementGroup *group=nullptr, bool complement=false)
Definition: GA_Detail.h:1512
SYS_FORCE_INLINE void forEachOffsetBreak(FUNCTOR &&functor) const
Definition: GA_IndexMap.h:526
SYS_FORCE_INLINE GA_Offset pointOffset(GA_Index index) const
Given a point's index (in append order), return its data offset.
Definition: GA_Detail.h:296
bool getPrimitivesOfType(const GA_PrimitiveTypeId &type, UT_Array< const GA_Primitive * > &prims) const
Definition: GA_Detail.h:2190
GA_Storage
Definition: GA_Types.h:48
void setPos4(GA_Offset ptoff, const UT_Vector4 &P)
Set P from a UT_Vector4.
Definition: GA_Detail.h:258
const GA_PrimitiveFactory & getPrimitiveFactory() const
Definition: GA_Detail.h:2143
SYS_FORCE_INLINE GA_Attribute * findVertexAttribute(const UT_StringRef &name)
Definition: GA_Detail.h:1039
GA_Attribute * createTupleAttribute(GA_AttributeOwner owner, GA_AttributeScope scope, const UT_StringHolder &name, GA_Storage storage, int tuple_size, const GA_Defaults &defaults=GA_Defaults(0.0f), const UT_Options *create_args=nullptr, const GA_AttributeOptions *attribute_options=nullptr)
Definition: GA_Detail.h:890
GA_Attribute * getPwAttribute()
Definition: GA_Detail.h:245
GA_Attribute * createAttribute(GA_AttributeOwner owner, GA_AttributeScope scope, const UT_StringHolder &name, const UT_Options *create_args, const GA_AttributeOptions *attribute_options, const UT_StringRef &attribtype)
Definition: GA_Detail.h:800
const GA_IntrinsicManager & getIntrinsicManager() const
Definition: GA_Detail.h:1330
SYS_FORCE_INLINE GA_Offset offsetSize() const
Definition: GA_IndexMap.h:97
SYS_FORCE_INLINE GA_ATINumeric * createDetachedTupleAttribute(GA_AttributeOwner owner, GA_Storage storage, int tuple_size, const GA_Defaults &defaults=GA_Defaults(0.0f), const GA_AttributeOptions *attribute_options=nullptr) const
Definition: GA_Detail.h:830
const char * getIntrinsicName(GA_LocalIntrinsic h) const
Definition: GA_Detail.h:1344
SYS_FORCE_INLINE GA_Offset appendVertexBlock(GA_Size nvertices)
Append new vertices, returning the first offset of the contiguous block.
Definition: GA_Detail.h:444
GA_Offset primitiveBegin() const
Definition: GA_Detail.h:714
GA_Attribute * createStringAttribute(GA_AttributeOwner owner, const UT_StringHolder &name, const UT_Options *create_args=nullptr, const GA_AttributeOptions *attribute_options=nullptr)
Definition: GA_Detail.h:930
SYS_FORCE_INLINE GA_Size getNumPoints() const
Return the number of points.
Definition: GA_Detail.h:285
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
Definition: glcorearb.h:1296
GLenum src
Definition: glcorearb.h:1792