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