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