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