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  /// @{
833  /// Get access to the attributes for one element type
834  GA_AttributeOwner getAttributeOwner(const GA_AttributeDict &dict) const;
836  { return myAttributes.getDict(owner); }
837  /// @}
838 
839  /// Defragment index maps
840  /// NOTE: To make sure that it actually defragments when there is even just
841  /// one hole, you must pass a UT_Options with a "removeholes"
842  /// bool option set to true.
843  /// NOTE: If any defragmenting occurs, this bumps data IDs for everything
844  /// that is modified.
845  bool defragment(GA_AttributeOwner owner,
846  const UT_Options *options = nullptr);
847  /// Defragment everything.
848  /// NOTE: To make sure that it actually defragments when there is even just
849  /// one hole, you must pass a UT_Options with a "removeholes"
850  /// bool option set to true.
851  /// NOTE: If any defragmenting occurs, this bumps data IDs for everything
852  /// that is modified.
853  bool defragment(const UT_Options *options = nullptr);
854 
855  /// Optimized layout of vertex index map. This sorts the vertex index map
856  /// by the primitive order use. The map will be defragmented after this
857  /// function is called.
858  void sortVertexMapByPrimitiveUse();
859 
860  // -------------- Attributes ----------------------------
861 
862  /// @{
863  /// createAttribute is very general purpose method, requiring
864  /// some knowledge about ATIs, etc. Unless you are creating
865  /// your own user-defined attributes, it would likely be better
866  /// to use something at the GEO_Detail level, like addFloatTuple.
868  GA_AttributeScope scope,
869  const UT_StringHolder &name,
870  const UT_Options *create_args,
871  const GA_AttributeOptions *attribute_options,
872  const UT_StringRef &attribtype)
873  {
874  return myAttributes.createAttribute(
875  owner, scope, name, create_args,
876  attribute_options, attribtype);
877  }
879  const UT_StringHolder &name,
880  const UT_Options *create_args,
881  const GA_AttributeOptions *attribute_options,
882  const UT_StringRef &attribtype)
883  {
884  return myAttributes.createAttribute(
885  owner, name, create_args,
886  attribute_options, attribtype);
887  }
888  /// @}
889 
890  /// This will create detached attributes. They will have the right number
891  /// of elements at the moment of creation, but will not update with changes
892  /// to the detail. These attributes will have no name.
893  /// @{
896  GA_AttributeOwner owner,
898  int tuple_size,
899  const GA_Defaults &defaults=GA_Defaults(0.0f),
900  const GA_AttributeOptions *attribute_options = nullptr) const
901  {
902  return myAttributes.createDetachedTupleAttribute(
903  owner, storage, tuple_size,
904  defaults, attribute_options);
905  }
906 
909  GA_AttributeOwner owner,
910  const UT_StringRef &attribtype,
911  const UT_Options *create_args = nullptr,
912  const GA_AttributeOptions *attribute_options = nullptr) const
913  {
914  return myAttributes.createDetachedAttribute(
915  owner, attribtype, create_args,
916  attribute_options);
917  }
918 
921  GA_AttributeOwner owner,
922  const GA_AttributeType &attribtype,
923  const UT_Options *create_args = nullptr,
924  const GA_AttributeOptions *attribute_options = nullptr) const
925  {
926  return myAttributes.createDetachedAttribute(
927  owner, attribtype, create_args,
928  attribute_options);
929  }
930  /// @}
931 
934  GA_AttributeScope scope,
935  const UT_StringRef &name)
936  {
937  return myAttributes.destroyAttribute(owner,
938  scope, name);
939  }
942  const UT_StringRef &name)
943  {
944  return myAttributes.destroyAttribute(owner, name);
945  }
948  GA_AttributeScope scope,
949  const UT_StringRef &from_name,
950  const UT_StringHolder &to_name)
951  {
952  return myAttributes.renameAttribute(owner, scope,
953  from_name, to_name);
954  }
955 
956  // Convenience attribute methods
958  GA_AttributeScope scope,
959  const UT_StringHolder &name,
960  GA_Storage storage,
961  int tuple_size,
962  const GA_Defaults &defaults = GA_Defaults(0.0f),
963  const UT_Options *create_args = nullptr,
964  const GA_AttributeOptions *attribute_options = nullptr)
965  {
966  return myAttributes.createTupleAttribute(
967  owner, scope, name, storage,
968  tuple_size, defaults,
969  create_args,
970  attribute_options);
971  }
973  const UT_StringHolder &name,
974  GA_Storage storage,
975  int tuple_size,
976  const GA_Defaults &defaults = GA_Defaults(0.0f),
977  const UT_Options *create_args = nullptr,
978  const GA_AttributeOptions *attribute_options = nullptr)
979  {
980  return myAttributes.createTupleAttribute(
981  owner, name, storage,
982  tuple_size, defaults,
983  create_args,
984  attribute_options);
985  }
987  GA_AttributeScope scope,
988  const UT_StringHolder &name,
989  const UT_Options *create_args=nullptr,
990  const GA_AttributeOptions *attribute_options=nullptr)
991  {
992  return myAttributes.createStringAttribute(
993  owner, scope, name, 1,
994  create_args,
995  attribute_options);
996  }
998  const UT_StringHolder &name,
999  const UT_Options *create_args=nullptr,
1000  const GA_AttributeOptions *attribute_options=nullptr)
1001  {
1002  return myAttributes.createStringAttribute(
1003  owner, name, 1, create_args,
1004  attribute_options);
1005  }
1006 
1007  /// Find an existing attribute, returning a read-only reference.
1008  ///
1011  const UT_StringRef &name,
1012  const GA_AttributeOwner search_order[],
1013  int search_size) const
1014  {
1015  return myAttributes.findAttribute(
1016  scope, name, search_order,
1017  search_size);
1018  }
1021  const GA_AttributeOwner search_order[],
1022  int search_size) const
1023  {
1024  return myAttributes.findAttribute(
1025  name, search_order, search_size);
1026  }
1029  GA_AttributeScope scope,
1030  const UT_StringRef &name) const
1031  { return findAttribute(scope, name, &owner, 1); }
1034  const UT_StringRef &name) const
1035  { return findAttribute(name, &owner, 1); }
1038  const UT_StringRef &name) const
1039  { return findAttribute(GA_ATTRIB_POINT, s, name); }
1042  { return findAttribute(GA_ATTRIB_POINT, name); }
1045  const UT_StringRef &name) const
1046  { return findAttribute(GA_ATTRIB_VERTEX,s, name); }
1049  { return findAttribute(GA_ATTRIB_VERTEX, name); }
1052  const UT_StringRef &name) const
1053  {return findAttribute(GA_ATTRIB_PRIMITIVE,s,name);}
1056  {return findAttribute(GA_ATTRIB_PRIMITIVE, name);}
1059  const UT_StringRef &name) const
1060  { return findAttribute(GA_ATTRIB_GLOBAL,s, name); }
1063  { return findAttribute(GA_ATTRIB_GLOBAL, name); }
1064 
1065  /// Find an existing attribute, returning a read-write reference.
1066  ///
1069  const UT_StringRef &name,
1070  const GA_AttributeOwner search_order[],
1071  int search_size)
1072  {
1073  return myAttributes.findAttribute(
1074  scope, name, search_order,
1075  search_size);
1076  }
1079  const GA_AttributeOwner search_order[],
1080  int search_size)
1081  {
1082  return myAttributes.findAttribute(
1083  name, search_order, search_size);
1084  }
1087  GA_AttributeScope scope,
1088  const UT_StringRef &name)
1089  { return findAttribute(scope, name, &owner, 1); }
1092  const UT_StringRef &name)
1093  { return findAttribute(name, &owner, 1); }
1096  const UT_StringRef &name)
1097  { return findAttribute(GA_ATTRIB_POINT, s, name); }
1100  { return findAttribute(GA_ATTRIB_POINT, name); }
1103  const UT_StringRef &name)
1104  { return findAttribute(GA_ATTRIB_VERTEX,s, name); }
1107  { return findAttribute(GA_ATTRIB_VERTEX, name); }
1110  const UT_StringRef &name)
1111  {return findAttribute(GA_ATTRIB_PRIMITIVE,s,name);}
1114  {return findAttribute(GA_ATTRIB_PRIMITIVE, name);}
1117  const UT_StringRef &name)
1118  { return findAttribute(GA_ATTRIB_GLOBAL,s, name); }
1121  { return findAttribute(GA_ATTRIB_GLOBAL, name); }
1122 
1123  /// Get/set all the point attribute data from/to a contiguous array
1124  // @{
1125 
1126  /// Valid types for T are:
1127  /// int32, int64, fpreal32, fpreal64,
1128  /// UT_Vector2T<S>, UT_Vector3T<S>, UT_Vector4T<S>,
1129  /// UT_QuaternionT<S>, UT_Matrix3T<S>, UT_Matrix4T<S>
1130  /// where S is one of: fpreal, fpreal32, fpreal64,
1131  /// For the UT_Vector classes, S can also be one of: int, int32, int64
1132  template <typename T>
1133  bool getAttributeAsArray(
1134  const GA_Attribute *atr,
1135  const GA_Range &range,
1136  UT_Array<T> &result) const;
1137 
1138  /// Valid types for T are:
1139  /// int32, int64, fpreal32, fpreal64,
1140  /// UT_Vector2T<S>, UT_Vector3T<S>, UT_Vector4T<S>,
1141  /// UT_QuaternionT<S>, UT_Matrix3T<S>, UT_Matrix4T<S>
1142  /// where S is one of: fpreal, fpreal32, fpreal64,
1143  /// For the UT_Vector classes, S can also be one of: int, int32, int64
1144  template <typename T>
1145  bool setAttributeFromArray(
1146  GA_Attribute *atr,
1147  const GA_Range &range,
1148  const UT_Array<T> &src);
1149  // @}
1150 
1151  // -------------- Groups ---------------------------------
1152  GA_ElementGroup *createElementGroup(GA_AttributeOwner owner,
1153  const UT_StringHolder &name,
1154  bool ordered=false);
1155  GA_ElementGroup *createInternalElementGroup(GA_AttributeOwner owner,
1156  bool ordered=false);
1157  GA_ElementGroup *findElementGroup(GA_AttributeOwner owner,
1158  const UT_StringRef &name);
1159  const GA_ElementGroup *findElementGroup(GA_AttributeOwner owner,
1160  const UT_StringRef &name) const;
1161 
1162  // Only accepts GA_ATTRIB_POINT,GA_ATTRIB_VERTEX,GA_ATTRIB_PRIMITIVE
1163  const GA_ElementGroupTable &
1164  getElementGroupTable(GA_AttributeOwner owner) const;
1167  {
1168  return const_cast<GA_ElementGroupTable &>(
1169  static_cast<const GA_Detail *>(this)
1170  ->getElementGroupTable(owner));
1171  }
1172 
1173  // Gets any group table.
1174  GA_GroupTable *getGroupTable(GA_GroupType group_type);
1175  const GA_GroupTable *getGroupTable(GA_GroupType group_type) const;
1176 
1177  /// @{
1178  /// Access point, primitive, vertex, or edge group tables
1180  { return myPointGroups; }
1182  { return myPointGroups; }
1184  { return myPrimitiveGroups; }
1186  { return myPrimitiveGroups; }
1188  { return myVertexGroups; }
1190  { return myVertexGroups; }
1192  { return myEdgeGroups; }
1194  { return myEdgeGroups; }
1195  /// @}
1196 
1197  template <GA_AttributeOwner OWNER>
1201  bool ordered=false)
1202  {
1204  createElementGroup(OWNER, name, ordered));
1205  }
1206 
1207  template <GA_AttributeOwner OWNER>
1210  createInternalElementGroup(bool ordered=false)
1211  {
1213  createInternalElementGroup(OWNER,ordered));
1214  }
1215 
1216  template <GA_AttributeOwner OWNER>
1220  {
1222  findElementGroup(OWNER, name));
1223  }
1224  template <GA_AttributeOwner OWNER>
1227  findElementGroup(const UT_StringRef &name) const
1228  {
1230  findElementGroup(OWNER, name));
1231  }
1232 
1233  void getElementGroupList(GA_AttributeOwner owner,
1234  UT_Array<const GA_ElementGroup *> &list) const;
1235  void getElementGroupList(GA_AttributeOwner owner,
1239  const UT_StringRef &name)
1240  { return getElementGroupTable(owner).destroy(name); }
1243  const char *name)
1244  { return getElementGroupTable(owner).destroy(name); }
1245  bool destroyElementGroup(GA_ElementGroup *group);
1246  bool destroyGroup(GA_Group *group);
1247 
1248  // Convenience group methods
1250  const GA_PointGroup *findPointGroup(const UT_StringRef &name) const
1251  { return findElementGroup<GA_ATTRIB_POINT>(name); }
1253  const GA_VertexGroup *findVertexGroup(const UT_StringRef &name) const
1254  { return findElementGroup<GA_ATTRIB_VERTEX>(name); }
1257  { return findElementGroup<GA_ATTRIB_PRIMITIVE>(name); }
1258 
1261  { return findElementGroup<GA_ATTRIB_POINT>(name); }
1264  { return findElementGroup<GA_ATTRIB_VERTEX>(name); }
1267  { return findElementGroup<GA_ATTRIB_PRIMITIVE>(name); }
1268 
1269  GA_EdgeGroup *createEdgeGroup(const UT_StringHolder &name);
1270  GA_EdgeGroup *createInternalEdgeGroup();
1271  const GA_EdgeGroup *findEdgeGroup(const UT_StringRef &name) const;
1272  GA_EdgeGroup *findEdgeGroup(const UT_StringRef &name);
1273  void getEdgeGroupList(
1274  UT_Array<const GA_EdgeGroup *> &list) const;
1275  void getEdgeGroupList(
1276  UT_Array<GA_EdgeGroup *> &list);
1278  bool destroyEdgeGroup(const UT_StringRef &name)
1279  { return myEdgeGroups.destroy(name); }
1282  { return g ? myEdgeGroups.destroy(g) : false; }
1283 
1284  // Utility group functions
1285  GA_Size destroyEmptyGroups(GA_AttributeOwner owner);
1286  GA_Size destroyAllEmptyGroups();
1287 
1288  /// Creates a non-internal group with the specified name,
1289  /// owned by this detail.
1290  /// @{
1292  {
1293  return static_cast<GA_PointGroup *>(pointGroups().newGroup(name));
1294  }
1296  {
1297  return static_cast<GA_VertexGroup *>(vertexGroups().newGroup(name));
1298  }
1300  {
1301  return static_cast<GA_PrimitiveGroup *>(primitiveGroups().newGroup(name));
1302  }
1304  {
1305  return static_cast<GA_EdgeGroup *>(edgeGroups().newGroup(name));
1306  }
1307  /// @}
1308 
1309  /// Creates an internal group with a unique name,
1310  /// owned by this detail.
1311  /// Be sure to call GA_Detail::destroyGroup (or destroyElementGroup)
1312  /// with this group to clean it up.
1313  /// @{
1315  {
1316  return static_cast<GA_PointGroup *>(pointGroups().newInternalGroup());
1317  }
1319  {
1320  return static_cast<GA_VertexGroup *>(vertexGroups().newInternalGroup());
1321  }
1323  {
1324  return static_cast<GA_PrimitiveGroup *>(primitiveGroups().newInternalGroup());
1325  }
1327  {
1328  return static_cast<GA_EdgeGroup *>(edgeGroups().newInternalGroup());
1329  }
1330  /// @}
1331 
1332  /// Creates a detached group with no name, owned by the caller.
1333  /// NOTE: The detail knows nothing about any detached groups that
1334  /// are created so these become invalid if the detail is modified.
1335  /// @{
1336  /// Be sure to do "delete group;" to clean it up.
1337  SYS_DEPRECATED_REPLACE(20.0, "createDetachedPointGroup")
1338  GA_PointGroup *newDetachedPointGroup() const
1339  {
1340  return new GA_PointGroup(*this);
1341  }
1342  /// Be sure to do "delete group;" to clean it up.
1343  SYS_DEPRECATED_REPLACE(20.0, "createDetachedPrimitiveGroup")
1344  GA_PrimitiveGroup *newDetachedPrimitiveGroup() const
1345  {
1346  return new GA_PrimitiveGroup(*this);
1347  }
1348  /// Be sure to do "delete group;" to clean it up.
1349  SYS_DEPRECATED_REPLACE(20.0, "createDetachedVertexGroup")
1350  GA_VertexGroup *newDetachedVertexGroup() const
1351  {
1352  return new GA_VertexGroup(*this);
1353  }
1354  /// Be sure to do "delete group;" to clean it up.
1355  SYS_DEPRECATED_REPLACE(20.0, "createDetachedEdgeGroup")
1356  GA_EdgeGroup *newDetachedEdgeGroup() const
1357  {
1358  return new GA_EdgeGroup(*this);
1359  }
1360 
1362  {
1363  return UTmakeUnique<GA_PointGroup>(*this);
1364  }
1366  {
1367  return UTmakeUnique<GA_PrimitiveGroup>(*this);
1368  }
1370  {
1371  return UTmakeUnique<GA_VertexGroup>(*this);
1372  }
1374  {
1375  return UTmakeUnique<GA_EdgeGroup>(*this);
1376  }
1377  /// @}
1378 
1379  /// TODO: Deprecate internal groups with user-specified names.
1380  /// @{
1381  GA_PointGroup *newPointGroup(const UT_StringHolder &name, bool internal)
1382  {
1383  return static_cast<GA_PointGroup *>(pointGroups().newGroup(name, internal));
1384  }
1386  {
1387  return static_cast<GA_PrimitiveGroup *>(primitiveGroups().newGroup(name, internal));
1388  }
1389  GA_VertexGroup *newVertexGroup(const UT_StringHolder &name, bool internal)
1390  {
1391  return static_cast<GA_VertexGroup *>(vertexGroups().newGroup(name, internal));
1392  }
1393  GA_EdgeGroup *newEdgeGroup(const UT_StringHolder &name, bool internal)
1394  {
1395  return static_cast<GA_EdgeGroup *>(edgeGroups().newGroup(name, internal));
1396  }
1397  /// @}
1398 
1399  // -------------- Intrinsics ------------------------
1400  /// Register global intrinsics.
1401  /// Each subclass should have registration which looks like: @code
1402  /// SubClass::registerIntrinsics(GA_PrimitiveFactory &factory)
1403  /// {
1404  /// GA_LocalIntrinsicMap map(factory.getDetailIntrinsics());
1405  /// BaseClass::registerIntrinsics(factory);
1406  /// map.addAttribute(...);
1407  /// map.addAttribute(...);
1408  /// }
1409  /// @endcode
1411  registerIntrinsics(GA_PrimitiveFactory &factory);
1412 
1413  /// Get the intrinsic manager for global/detail intrinsics.
1414  ///
1415  /// At the current time, these include:
1416  /// - "string globaltokens[]" @n List of all global/detail intrinsics
1417  /// - "string primitivetokens[]" @n List of all primitive intrinsics
1418  /// - "int vertexcount" @n Number of vertices in the detail
1419  /// - "int pointcount" @n Number of points in the detail
1420  /// - "int primitivecount" @n Number of primitives in the detail
1422  { return myPrimitiveFactory.getDetailIntrinsics(); }
1423 
1424  /// @{
1425  /// Query properties of the @b global/detail intrinsic
1426  /// Note that the tuple size calls the virtual method since the tuple size
1427  /// may be dynamic (i.e. basis knot vector). This also means that to know
1428  /// whether a single component tuple should collapse to a scalar value, you
1429  /// need to call the getIntrinsicCollapseSingletons method.
1431  { return getIntrinsicManager().getLocalHandle(nm); }
1433  { return getIntrinsicManager().getLocalHandle(h); }
1435  { return getIntrinsicManager().getGlobalHandle(h); }
1436 
1438  { return getIntrinsicManager().getName(h); }
1439  GA_Size getIntrinsicTupleSize(GA_LocalIntrinsic h) const;
1441  GA_LocalIntrinsic h) const
1442  { return getIntrinsicManager().getCollapseSingletons(h); }
1444  { return getIntrinsicManager().getStorage(h); }
1446  { return getIntrinsicManager().getReadOnly(h); }
1448  { return getIntrinsicManager().getOptions(h); }
1449  /// @}
1450 
1451  /// @{
1452  /// Get the value of a global/detail intrinsic.
1453  /// These methods return the number of items retrieved.
1454  GA_Size getIntrinsic(GA_LocalIntrinsic h, UT_String &val) const;
1455  GA_Size getIntrinsic(GA_LocalIntrinsic h, UT_StringArray &val) const;
1456  GA_Size getIntrinsic(GA_LocalIntrinsic h, UT_OptionsHolder &val) const;
1458  GA_Size getIntrinsic(GA_LocalIntrinsic h, int64 *v, GA_Size size) const;
1459  GA_Size getIntrinsic(GA_LocalIntrinsic h, fpreal64 *v, GA_Size sz) const;
1460  /// @}
1461 
1462  /// @{
1463  /// Get the value of a global/detail intrinsic.
1464  /// Returns false if not the right type or not found.
1465  /// Always will clear out the provided value.
1466  bool getIntrinsic(GA_LocalIntrinsic h, float &v) const;
1467  bool getIntrinsic(GA_LocalIntrinsic h, int &v) const;
1468  bool getIntrinsic(GA_LocalIntrinsic h, UT_Vector2 &v) const;
1469  bool getIntrinsic(GA_LocalIntrinsic h, UT_Vector3 &v) const;
1470  bool getIntrinsic(GA_LocalIntrinsic h, UT_Vector4 &v) const;
1471  bool getIntrinsic(GA_LocalIntrinsic h, UT_Matrix2 &v) const;
1472  bool getIntrinsic(GA_LocalIntrinsic h, UT_Matrix3 &v) const;
1473  bool getIntrinsic(GA_LocalIntrinsic h, UT_Matrix4 &v) const;
1474  bool getIntrinsic(GA_LocalIntrinsic h, double &v) const;
1475  bool getIntrinsic(GA_LocalIntrinsic h, int64 &v) const;
1476  bool getIntrinsic(GA_LocalIntrinsic h, UT_Vector2D &v) const;
1477  bool getIntrinsic(GA_LocalIntrinsic h, UT_Vector3D &v) const;
1478  bool getIntrinsic(GA_LocalIntrinsic h, UT_Vector4D &v) const;
1479  bool getIntrinsic(GA_LocalIntrinsic h, UT_Matrix2D &v) const;
1480  bool getIntrinsic(GA_LocalIntrinsic h, UT_Matrix3D &v) const;
1481  bool getIntrinsic(GA_LocalIntrinsic h, UT_Matrix4D &v) const;
1482 
1483  /// @}
1484 
1485  /// @{
1486  /// Set intrinsic. This will fail if the intrinsic is read-only.
1487  /// These methods return the number of items set.
1488  GA_Size setIntrinsic(GA_LocalIntrinsic h, const char *value);
1489  GA_Size setIntrinsic(GA_LocalIntrinsic h, const UT_StringArray &value);
1490  GA_Size setIntrinsic(GA_LocalIntrinsic h, const char **val, GA_Size s);
1491  GA_Size setIntrinsic(GA_LocalIntrinsic h, const UT_OptionsHolder &val);
1493  GA_Size setIntrinsic(GA_LocalIntrinsic h, const UT_OptionsHolder *val, GA_Size s);
1494  GA_Size setIntrinsic(GA_LocalIntrinsic h, const int64 val);
1495  GA_Size setIntrinsic(GA_LocalIntrinsic h, const fpreal64 val);
1496  GA_Size setIntrinsic(GA_LocalIntrinsic h, const int64 *val, GA_Size sz);
1497  GA_Size setIntrinsic(GA_LocalIntrinsic h, const fpreal64 *v, GA_Size sz);
1498  /// @}
1499 
1500  /// Calls functor on every active point offset.
1501  /// This is easiest to use with C++ lambdas, e.g.:
1502  /// detail.forEachPoint([&vec,&detail](GA_Offset ptoff) {
1503  /// vec += detail.getPos3(ptoff);
1504  /// });
1505  template<typename FUNCTOR>
1507  void forEachPoint(FUNCTOR &&functor) const
1508  {
1509  myPointMap.forEachOffset(functor);
1510  }
1511 
1512  /// Calls functor on every point offset in a group.
1513  /// This is easiest to use with C++ lambdas, e.g.:
1514  /// detail.forEachPoint(group, [&vec,&detail](GA_Offset ptoff) {
1515  /// vec += detail.getPos3(ptoff);
1516  /// });
1517  template<typename FUNCTOR>
1519  void forEachPoint(const GA_PointGroup *group, FUNCTOR &&functor) const
1520  {
1521  forEachOffset(functor, myPointMap, group);
1522  }
1523 
1524  /// Calls functor on every point offset in a group, (or not in a group
1525  /// if complement is true).
1526  template<typename FUNCTOR>
1528  void forEachPoint(const GA_PointGroup *group, bool complement, FUNCTOR &&functor) const
1529  {
1530  forEachOffset(functor, myPointMap, group, complement);
1531  }
1532 
1533  /// Like forEachPoint, except taking a functor that
1534  /// returns true to continue, and false to break.
1535  /// @{
1536  template<typename FUNCTOR>
1538  void forEachPointBreak(FUNCTOR &&functor) const
1539  {
1540  myPointMap.forEachOffsetBreak(functor);
1541  }
1542  template<typename FUNCTOR>
1544  void forEachPointBreak(const GA_PointGroup *group, FUNCTOR &&functor) const
1545  {
1546  forEachOffset(functor, myPointMap, group);
1547  }
1548  template<typename FUNCTOR>
1550  void forEachPointBreak(const GA_PointGroup *group, bool complement, FUNCTOR &&functor) const
1551  {
1552  forEachOffset(functor, myPointMap, group, complement);
1553  }
1554  /// @}
1555 
1556  /// Calls functor on every active primitive offset.
1557  /// This is easiest to use with C++ lambdas, e.g.:
1558  /// detail.forEachPrimitive([&tris,&detail](GA_Offset primoff) {
1559  /// if (detail.getPrimitiveMap().getTypeId(primoff) != GA_PRIMPOLY)
1560  /// return;
1561  /// GA_OffsetListRef vertices = detail.getPrimitiveMap().getVertexList(primoff);
1562  /// if (vertices.size() == 3 && vertices.getExtraFlag())
1563  /// tris.addOffset(primoff);
1564  /// });
1565  template<typename FUNCTOR>
1567  void forEachPrimitive(FUNCTOR &&functor) const
1568  {
1569  myPrimitiveMap.forEachOffset(functor);
1570  }
1571 
1572  /// Calls functor on every primitive offset in a group.
1573  /// This is easiest to use with C++ lambdas, e.g.:
1574  /// detail.forEachPrimitive(group, [&tris,&detail](GA_Offset primoff) {
1575  /// if (detail.getPrimitiveMap().getTypeId(primoff) != GA_PRIMPOLY)
1576  /// return;
1577  /// GA_OffsetListRef vertices = detail.getPrimitiveMap().getVertexList(primoff);
1578  /// if (vertices.size() == 3 && vertices.getExtraFlag())
1579  /// tris.addOffset(primoff);
1580  /// });
1581  template<typename FUNCTOR>
1583  void forEachPrimitive(const GA_PrimitiveGroup *group, FUNCTOR &&functor) const
1584  {
1585  forEachOffset(functor, myPrimitiveMap, group);
1586  }
1587 
1588  /// Calls functor on every primitive offset in a group, (or not in a group
1589  /// if complement is true).
1590  template<typename FUNCTOR>
1592  void forEachPrimitive(const GA_PrimitiveGroup *group, bool complement, FUNCTOR &&functor) const
1593  {
1594  forEachOffset(functor, myPrimitiveMap, group, complement);
1595  }
1596 
1597  /// Like forEachPrimitive, except taking a functor that
1598  /// returns true to continue, and false to break.
1599  /// @{
1600  template<typename FUNCTOR>
1602  void forEachPrimitiveBreak(FUNCTOR &&functor) const
1603  {
1604  myPrimitiveMap.forEachOffsetBreak(functor);
1605  }
1606  template<typename FUNCTOR>
1608  void forEachPrimitiveBreak(const GA_PrimitiveGroup *group, FUNCTOR &&functor) const
1609  {
1610  forEachOffsetBreak(functor, myPrimitiveMap, group);
1611  }
1612  template<typename FUNCTOR>
1614  void forEachPrimitiveBreak(const GA_PrimitiveGroup *group, bool complement, FUNCTOR &&functor) const
1615  {
1616  forEachOffsetBreak(functor, myPrimitiveMap, group, complement);
1617  }
1618  /// @}
1619 
1620  template<typename FUNCTOR>
1621  static void forEachOffset(FUNCTOR &&functor, const GA_IndexMap &index_map, const GA_ElementGroup *group = nullptr, bool complement = false)
1622  {
1623  // Fall back to regular case if no group.
1624  if (!group)
1625  {
1626  if (!complement)
1627  index_map.forEachOffset(functor);
1628  return;
1629  }
1630 
1631  // Group order is only relevant if not complemented.
1632  if (!complement)
1633  {
1634  const GA_ElementGroupOrder *order = group->getOrdered();
1635  if (order)
1636  {
1637  for (GA_ElementGroupOrderIndex i(0), n(order->entries()); i != n; ++i)
1638  {
1639  GA_Offset off = order->getElement(i);
1640  functor(off);
1641  }
1642  return;
1643  }
1644  }
1645 
1646  // We have a group, treated as unordered.
1647  const GA_Offset veryend = index_map.offsetSize();
1648  GA_Offset off(0);
1649  while (true)
1650  {
1651  bool value;
1652  GA_Size span_size;
1653  group->getConstantSpan(off, veryend, span_size, value);
1654  if (span_size == 0)
1655  break;
1656  if (value == complement)
1657  {
1658  off += span_size;
1659  continue;
1660  }
1661  const GA_Offset span_end = off+span_size;
1662  while (true)
1663  {
1664  off = index_map.findActiveOffset(off, span_end);
1665  GA_Offset end = index_map.findInactiveOffset(off, span_end);
1666  if (off == end)
1667  break;
1668  do
1669  {
1670  functor(off);
1671  ++off;
1672  } while (off != end);
1673  }
1674  }
1675  }
1676 
1677  template<typename FUNCTOR>
1678  static void forEachOffsetBreak(FUNCTOR &&functor, const GA_IndexMap &index_map, const GA_ElementGroup *group = nullptr, bool complement = false)
1679  {
1680  // Fall back to regular case if no group.
1681  if (!group)
1682  {
1683  if (!complement)
1684  index_map.forEachOffsetBreak(functor);
1685  return;
1686  }
1687 
1688  // Group order is only relevant if not complemented.
1689  if (!complement)
1690  {
1691  const GA_ElementGroupOrder *order = group->getOrdered();
1692  if (order)
1693  {
1694  for (GA_ElementGroupOrderIndex i(0), n(order->entries()); i != n; ++i)
1695  {
1696  GA_Offset off = order->getElement(i);
1697  if (!functor(off))
1698  return;
1699  }
1700  return;
1701  }
1702  }
1703 
1704  // We have a group, treated as unordered.
1705  const GA_Offset veryend = index_map.offsetSize();
1706  GA_Offset off(0);
1707  while (true)
1708  {
1709  bool value;
1710  GA_Size span_size;
1711  group->getConstantSpan(off, veryend, span_size, value);
1712  if (span_size == 0)
1713  break;
1714  if (value == complement)
1715  {
1716  off += span_size;
1717  continue;
1718  }
1719  const GA_Offset span_end = off+span_size;
1720  while (true)
1721  {
1722  off = index_map.findActiveOffset(off, span_end);
1723  GA_Offset end = index_map.findInactiveOffset(off, span_end);
1724  if (off == end)
1725  break;
1726  do
1727  {
1728  if (!functor(off))
1729  return;
1730  ++off;
1731  } while (off != end);
1732  }
1733  }
1734  }
1735 
1736  // -------------- Range Accessors --------------------------
1737  /// Get a range of all points in the detail
1738  GA_Range getPointRange(const GA_PointGroup *group = 0) const
1739  { return GA_Range(getPointMap(), group); }
1740  /// Get a range of all primitives in the detail
1742  { return GA_Range(getPrimitiveMap(), group); }
1743 
1744  /// Get ordered point range from base_ptnum to end_ptnum, or the end
1746  GA_Index begin_ptnum,
1747  GA_Index end_ptnum = GA_INVALID_INDEX) const
1748  {
1749  GA_Range::ordered ordered;
1750  if (!GAisValid(end_ptnum))
1751  end_ptnum = GA_Index(getNumPoints());
1752  return GA_Range(getPointMap(), begin_ptnum, end_ptnum,
1753  ordered);
1754  }
1755  /// Get ordered primitive range from base_prim to end_prim, or the end
1757  GA_Index begin_prim,
1758  GA_Index end_prim = GA_INVALID_INDEX) const
1759  {
1760  GA_Range::ordered ordered;
1761  if (!GAisValid(end_prim))
1762  end_prim = GA_Index(getNumPrimitives());
1763  return GA_Range(getPrimitiveMap(),
1764  begin_prim, end_prim, ordered);
1765  }
1766 
1767  /// Get a range of all vertices in the detail
1768  GA_Range getVertexRange(const GA_VertexGroup *group = 0) const
1769  { return GA_Range(getVertexMap(), group); }
1770  /// Get a range representing the global (detail) data
1772  { return GA_Range(getGlobalMap()); }
1773 
1774  // -------------- Common Operations ------------------------
1775  /// Compute memory usage (includes all shared memory)
1776  virtual int64 getMemoryUsage(bool inclusive) const;
1777 
1778  /// Count memory usage using a UT_MemoryCounter in order to count
1779  /// shared memory correctly.
1780  /// If inclusive is true, the size of this object is counted,
1781  /// else only memory owned by this object is counted.
1782  /// If this is pointed to by the calling object, inclusive should be true.
1783  /// If this is contained in the calling object, inclusive should be false.
1784  /// (Its memory was already counted in the size of the calling object.)
1785  virtual void countMemory(UT_MemoryCounter &counter, bool inclusive) const;
1786 
1787  // Computing the bounding box. Depending on the element being iterated,
1788  // either the point or primitive bounding box will be computed. When a
1789  // P attribute argument is not present, the detail's position attribute
1790  // is used.
1791  bool enlargeBoundingBox(UT_BoundingRect &box,
1792  const GA_Range &range) const;
1793  bool enlargeBoundingBox(UT_BoundingRect &box,
1794  const GA_Range &range,
1795  const GA_Attribute *P) const;
1796  bool enlargeBoundingBox(UT_BoundingBox &box,
1797  const GA_Range &range) const;
1798  bool enlargeBoundingBox(UT_BoundingBox &box,
1799  const GA_Range &range,
1800  const GA_Attribute *P) const;
1801 
1802  /// Compute the bounding box quickly by:
1803  /// - Computing the point bounding box of "P"
1804  /// - Computing the maximum extents of all primitives
1805  /// This requires a single pass through the P attribute along with a single
1806  /// pass through primitives.
1807  void computeQuickBounds(UT_BoundingBox &box) const;
1808 
1809  /// Compute the bounding box quickly by:
1810  /// - Computing the point bounding box of "P"
1811  /// - Computing the maximum extents of all primitives
1812  /// - Count the number of each type of primitive in the detail
1813  /// This requires a single pass through the P attribute along with a single
1814  /// pass through primitives.
1815  /// The @c counts buffer will be filled with the count of each primitive
1816  /// type in the detail. The count_buf_size should be set to
1817  /// @c getPrimitiveFactory().getPrimTypeCount();
1818  void computeQuickBounds(UT_BoundingBox &box,
1819  GA_Size counts[], GA_Size count_buf_size) const;
1820 
1821  /// Create a new detail that has all the same attributes, groups, etc. but
1822  /// has no elements.
1823  /// Subclasses should look at: cloneCopyGroupsAndAttributes()
1824  virtual GA_Detail *cloneEmptyDetail(bool clone_attributes) const = 0;
1825 
1826  /// Copy groups and attribute definitions from the source detail.
1827  ///
1828  /// The caller should ensure that all attributes are cleared before calling
1829  /// this method (i.e. call clear())
1830  void cloneCopyGroupsAndAttributes(const GA_Detail &src,
1831  bool copydetailattribs = false);
1832 
1833  /// Copy all attribute values from srcoff to destoff for
1834  /// attributes accepted by filter. If no filter is specified,
1835  /// all public attributes and non-internal groups are copied.
1836  ///
1837  /// NOTE: If you're copying multiple offsets, it's *much* faster to do:
1838  /// For each attribute, copy data for all offsets;
1839  /// rather than:
1840  /// For each offset, copy data in all attributes.
1841  /// These functions are only for if the former is too awkward
1842  /// to do in some case.
1843  /// @{
1844  void copyAttributes(
1845  GA_AttributeOwner owner,
1846  GA_Offset destoff,
1847  GA_Offset srcoff,
1848  const GA_AttributeFilter *filter = nullptr);
1849  void copyAttributes(
1850  GA_AttributeOwner owner,
1851  GA_Offset destoff,
1852  const GA_Detail &srcdetail,
1853  GA_Offset srcoff,
1854  const GA_AttributeFilter *filter = nullptr);
1855  /// @}
1856 
1857  /// Copy all attribute values from srcptoff to destptoff for point
1858  /// attributes accepted by filter. If no filter is specified,
1859  /// all public attributes and non-internal groups are copied.
1862  GA_Offset destptoff,
1863  GA_Offset srcptoff,
1864  const GA_AttributeFilter *filter = nullptr)
1865  {
1866  copyAttributes(GA_ATTRIB_POINT, destptoff, srcptoff, filter);
1867  }
1868 
1869  /// Copy all attribute values from srcvtxoff to destvtxoff for vertex
1870  /// attributes accepted by filter. If no filter is specified,
1871  /// all public attributes and non-internal groups are copied.
1872  /// If ref_point_dont_copy is true, the point of srcvtxoff is
1873  /// referenced by destvtxoff, otherwise point attributes are also
1874  /// copied.
1875  /// NOTE: If you only want to copy vertex attributes, and not the
1876  /// point, call copyAttributes(GA_ATTRIB_VERTEX, ...)
1878  GA_Offset destvtxoff,
1879  GA_Offset srcvtxoff,
1880  bool ref_point_dont_copy,
1881  const GA_AttributeFilter *filter = nullptr)
1882  {
1883  GA_Offset srcptoff = vertexPoint(srcvtxoff);
1884  if (ref_point_dont_copy)
1885  setVertexPoint(destvtxoff, srcptoff);
1886  else
1887  copyPoint(vertexPoint(destvtxoff), srcptoff, filter);
1888  copyAttributes(GA_ATTRIB_VERTEX, destvtxoff, srcvtxoff, filter);
1889  }
1890 
1891  /// Merge the source detail into this detail (using default options)
1892  void baseMerge(const GA_Detail &src);
1893  /// Merge the source detail into this detail with options
1894  void baseMerge(const GA_Detail &src,
1895  GA_MergeOptions &options);
1896 
1897  /// Fast version of merge for the common case of completely replacing
1898  /// all of this detail with the source detail, using data IDs to avoid
1899  /// copying things that are the same. This does not copy private
1900  /// scope attributes (except topology) or internal groups.
1901  /// When skip is given, all processing of attributes matching the filter
1902  /// will be skipped. The result is that skipped attributes may or may not
1903  /// exist afterwards, and they also won't be initialized in any expected
1904  /// way. The assumption is that the caller will fully handle creation,
1905  /// initialization, or deletion of skipped attributes.
1906  /// If 'full_copy is true, internal groups and private attribute are also
1907  /// considered.'
1908  void replaceWith(const GA_Detail &src,
1909  const GA_AttributeFilter *skip = nullptr,
1910  bool full_copy = false);
1911 
1912  /// Fast version of merge for the case of completely replacing all of this
1913  /// detail with the points from the source detail, using data IDs to avoid
1914  /// copying things that are the same. This does not copy private
1915  /// scope attributes (except topology) or internal groups.
1916  /// It will act as if replaceWith was called and then all primitives
1917  /// were deleted, so vertex/primitive attributes will be transferred,
1918  /// but there will be no vertices or primitives.
1919  /// When skip is given, all processing of attributes matching the filter
1920  /// will be skipped. The result is that skipped attributes may or may not
1921  /// exist afterwards, and they also won't be initialized in any expected
1922  /// way. The assumption is that the caller will fully handle creation,
1923  /// initialization, or deletion of skipped attributes.
1924  void replaceWithPoints(const GA_Detail &src,
1925  const GA_AttributeFilter *skip = nullptr);
1926 
1927  /// This clears any caches that subclasses of GA_Detail may have, so that
1928  /// replacing the content of the detail doesn't cause crashes.
1929  /// NOTE: You may or may not also have to call refreshCachedHandles later
1930  /// if P or Pw might be replaced or change storage.
1931  virtual void clearCaches()
1932  {
1933  clearInstanceMatrix();
1934  getPrimitiveList().destroyStashed();
1935  }
1936 
1937  /// Merge global attributes (using default options)
1938  void mergeGlobalAttributes(const GA_Detail &src);
1939  /// Merge source global attributes using options
1940  void mergeGlobalAttributes(const GA_Detail &src,
1941  GA_MergeOptions &options);
1942 
1943  /// Clone any missing attributes from the source detail, skipping P, any
1944  /// topology, and any group attributes.
1945  void cloneMissingAttributes(const GA_Detail &src,
1946  GA_AttributeOwner owner,
1947  const GA_AttributeFilter &filter);
1948  /// Clone any missing groups from the source detail.
1949  void cloneMissingGroups(const GA_Detail &src,
1950  GA_AttributeOwner owner,
1951  const GA_AttributeFilter &filter);
1952 
1953  // -------------- Stream I/O METHODS ------------------------
1954  /// Register an IO file format
1955  bool registerIO(GA_IO *io) const
1956  { return myPrimitiveFactory.registerIO(io); }
1957 
1958  /// Find an IO class. If no name is specified, the "default" IO class will
1959  /// be returned (the one specified by HOUDINI_GEOMETRY_FORMAT).
1960  const GA_IO *findIO(const char *name = nullptr) const
1961  { return myPrimitiveFactory.findIO(name); }
1962 
1963  /// Get a list of all the IO names registered. Returns the number of names
1964  /// in the array.
1965  void getIONames(UT_StringArray &names) const
1966  { return myPrimitiveFactory.getIONames(names); }
1967 
1968  /// This class is used to return the status from I/O operations on a
1969  /// GA_Detail.
1970  class IOStatus
1971  {
1972  public:
1973  IOStatus(bool success=false)
1974  : mySuccess(success)
1975  {}
1977  : mySuccess(src.mySuccess)
1978  {}
1980 
1982  {
1983  if (this != &src)
1984  mySuccess = src.mySuccess;
1985  return *this;
1986  }
1987 
1988  /// Return a boolean for success or failure.
1989  /// true means success
1990  bool success() const { return mySuccess; }
1991 
1992  /// bool operator
1993  SYS_SAFE_BOOL operator bool() const { return mySuccess; }
1994 
1995  /// For backward compatibility in older code, you can query the status
1996  /// as an integer, 0 for success, less than zero for failure.
1997  int gbstatus() const { return mySuccess ? 0 : -1; }
1998 
1999  private:
2000  bool mySuccess;
2001  };
2002 
2003  /// Save to a given filename. An extension of .gz will enable zlib
2004  /// compression (for JSON format only)
2005  /// Options include:
2006  /// - string geo:format @n Use the IO format specified by the string
2007  /// See also the options for the stream save
2008  IOStatus save(const char *filename,
2009  const GA_SaveOptions *options,
2010  UT_StringArray *errors = 0) const;
2011 
2012  /// Save to an existing ostream. JSON format will check the options for:
2013  /// - bool geo:gzip @n Enable gzip compression for JSON (false)
2014  /// - bool geo:saveinfo @n Output optional "info" section [true]
2015  /// - string info:software - Software
2016  /// - string info:artist - Artist
2017  /// - string info:hostname - Hostname comment
2018  /// - string info:comment - Arbitrary Comment
2019  /// - any info:token - Saved in the "info" section
2020  /// - bool group:saveinternal @n Save "internal" groups (debugging)
2021  IOStatus save(std::ostream &os, bool binary,
2022  const GA_SaveOptions *options,
2023  UT_StringArray *errors = 0) const;
2024  /// @{
2025  /// Save in "hclassic" format.
2026  IOStatus saveClassic(const char *, const GA_SaveOptions *) const;
2027  IOStatus saveClassic(std::ostream &os, bool, const GA_SaveOptions *) const;
2028  /// @}
2029 
2030  /// @section JSON-GA_Detail JSON Schema: GA_Detail
2031  ///
2032  /// The JSON schema for a detail can be broken down into 5 major sections
2033  /// - Header: The global information about the detail
2034  /// - References: Topological references
2035  /// - Attributes: Attribute data for elements
2036  /// - Primitives: List of primitives in the detail
2037  /// - Groups: Groups
2038  ///
2039  /// @code
2040  /// {
2041  /// "name" : "GA_Detail-Header",
2042  /// "description" : "Storage for an entire geometry object",
2043  /// "type" : "orderedmap",
2044  /// "properties": {
2045  /// // Header section
2046  /// "file_version": {
2047  /// "type" : "string",
2048  /// "description" : "File Version",
2049  /// "optional" : true,
2050  /// },
2051  /// "info": {
2052  /// "type" : "object",
2053  /// "description" :
2054  /// "Optional tags including:
2055  /// 'software' : Software used to create geometry,
2056  /// 'artist' : Artist name,
2057  /// 'hostname' : Computer name,
2058  /// 'comment' : Arbitrary comment
2059  /// etc.",
2060  /// "optional" : true,
2061  /// }
2062  /// "pointcount": {
2063  /// "type" : "integer",
2064  /// "description" : "The number of points in the geometry",
2065  /// },
2066  /// "vertexcount": {
2067  /// "type" : "integer",
2068  /// "description" : "The number of vertices in the geometry",
2069  /// },
2070  /// "primitivecount": {
2071  /// "type" : "integer",
2072  /// "description" : "The number of primitives in the geometry",
2073  /// },
2074  ///
2075  /// // Topology section
2076  /// "topology" : {
2077  /// "type" : "orderedmap",
2078  /// "description" : "Topological information",
2079  /// "properties" : {
2080  /// "pointref" : {
2081  /// "type" : [{ "$ref" : "GA_ATITopology" }],
2082  /// "description" :
2083  /// "An list of points referenced by each
2084  /// vertex. The array of 'vertexcount' items
2085  /// must contain integer values in the range of
2086  /// (0,pointcount-1)"
2087  /// }
2088  /// }
2089  /// },
2090  ///
2091  /// // Attributes section
2092  /// "attributes": {
2093  /// "type" : { "$ref" : "GA_AttributeSet" } ,
2094  /// "description" : "Vertex attributes",
2095  /// }
2096  ///
2097  /// // Primitives section
2098  /// "primitives": {
2099  /// "type" : { "$ref" : "GA_PrimitiveList" } ,
2100  /// "description" : "An array of primitives",
2101  /// }
2102  ///
2103  /// // Groups section
2104  /// "pointgroups": {
2105  /// "type" : { "$ref" : "GA_GroupTable" },
2106  /// "description" : "The list of point groups",
2107  /// "optional" : true,
2108  /// },
2109  /// "primitivegroups": {
2110  /// "type" : { "$ref" : "GA_GroupTable" },
2111  /// "description" : "The list of primitive groups",
2112  /// "optional" : true,
2113  /// },
2114  /// "vertexgroups": {
2115  /// "type" : { "$ref" : "GA_GroupTable" },
2116  /// "description" : "The list of vertex groups",
2117  /// "optional" : true,
2118  /// },
2119  /// "edgegroups": {
2120  /// "type" : { "$ref" : "GA_GroupTable" },
2121  /// "description" : "The list of edge groups",
2122  /// "optional" : true,
2123  /// },
2124  /// },
2125  /// }
2126  /// @endcode
2127  /// @see @ref JSON_FileFormat
2128  /// @note This method uses <tt>findIO(GA_IOTable::getJSONToken())</tt> and
2129  /// uses a dynamic cast to GA_IOJSON to actually do the writing.
2130  IOStatus save(UT_JSONWriter &w, const GA_SaveOptions *opts=0) const;
2131 
2132  /// Load a geometry file
2133  IOStatus load(const char *filename,
2134  const GA_LoadOptions *opts=0,
2135  UT_StringArray *errors=0);
2136 
2137  /// Load a geometry file given a UT_IStream.
2138  IOStatus load(UT_IStream &is,
2139  const GA_LoadOptions *opts=0,
2140  UT_StringArray *errors=0);
2141 
2142  /// Load geometry from a JSON stream.
2143  /// @note This method uses <tt>findIO(GA_IOTable::getJSONToken())</tt> and
2144  /// uses a dynamic cast to GA_IOJSON to actually do the loading.
2145  IOStatus load(UT_JSONParser &p,
2146  const GA_LoadOptions *opts=0,
2147  UT_StringArray *errors=0);
2148 
2149  /// @{
2150  /// Stat a disk file rather than loading the entire geometry.
2151  /// (see @ref GA_STAT_LEVEL)
2152  /// The method cannot be static since the primitive factory is required.
2153  /// The primitive factory stores the IO table for the geometry.
2154  ///
2155  /// When performing a stat on a disk file, if the format supports it, only
2156  /// the header of the file is loaded. This means that the full
2157  /// information for the geometry isn't available. Thus, this will give
2158  /// you different information than if you run stat() on geometry that's
2159  /// fully loaded into memory.
2160  ///
2161  /// If you inspect a .geo file, you can see the information that's
2162  /// available. For example, you can get the "primcount_summary" using the
2163  /// GA_Stat::getInfoOptions() method.
2164  IOStatus statFile(const char *filename, GA_Stat &stat,
2165  uint level=0xffff,
2166  const GA_LoadOptions *opts=nullptr) const;
2167  IOStatus stat(UT_JSONParser &p, GA_Stat &stat, uint level) const;
2168  /// @}
2169 
2170  /// Private methods
2171  /// @private
2172  void batchDeletion(GA_AttributeOwner owner);
2173  /// @private
2174  void adjustArraySize(GA_AttributeOwner owner, GA_Offset size);
2175  /// @private
2176  void constructElementBlock(GA_AttributeOwner owner, GA_Offset offset, GA_Offset nelements)
2177  { myAttributes.constructElementBlock(owner, offset, nelements); }
2178  /// @private
2179  void destructElement(GA_AttributeOwner owner, GA_Offset offset)
2180  { myAttributes.destructElement(owner, offset); }
2181 
2182  /// @private mergeGrowArrays() is called during the merging process
2183  /// @b prior to the actual addition of new elements to the detail.
2184  /// At this point, attribute arrays are grown to store the incoming data
2185  void mergeGrowArrays(GA_MergeMap &map, GA_AttributeOwner owner);
2186 
2187  /// Get information about the detail.
2188  /// @param stat @n - Information about detail
2189  /// @param level @n - Mask of information to retrieve
2190  /// (see @ref GA_STAT_LEVEL)
2191  /// Note that since this method queries the geometry that's fully loaded
2192  /// into memory, you will get different information than the @c statFile()
2193  /// method.
2194  bool stat(GA_Stat &stat, uint level=0xffff) const;
2195 
2196  /// Fill out only the attribute information on the stat
2197  void statAttributes(GA_Stat &stat, uint level=0xffff) const;
2198  /// Fill out only the group information on the stat
2199  void statGroups(GA_Stat &stat, uint level=0xffff) const;
2200  /// Fill out only the volume information.
2201  virtual void statVolumes(GA_Stat &stat, uint level=0xffff) const;
2202 
2203  /// Debugging output of detail
2204  static int64 printMemory(UT_WorkBuffer &buffer,
2205  bool include_total=true,
2206  int indent=3,
2207  const char *title="Geometry Memory Tracking");
2208 
2209  /// @{
2210  /// Utility casting functions used by GA_GBMacros.h to maintain (source
2211  /// code) type compatibility with the old implementations that used the
2212  /// derived GD/GEO_PrimList objects.
2213  ///
2214  /// The first argument is used solely to infer the templatized type.
2215  /// Derived classes (GD_Detail/GEO_Detail) should contain embedded
2216  /// GB_MACRO_PRIM_TYPE typedef to specify
2217  /// the proper derived type to use for the cast.
2218  template <typename T> static inline const typename T::GB_MACRO_PRIM_TYPE *
2219  GB_MACRO_CAST(const T *, const GA_Primitive *prim)
2220  { return static_cast<const typename T::GB_MACRO_PRIM_TYPE *>(prim);}
2221  template <typename T> static inline typename T::GB_MACRO_PRIM_TYPE *
2222  GB_MACRO_CAST(const T *, GA_Primitive *prim)
2223  { return static_cast<typename T::GB_MACRO_PRIM_TYPE *>(prim); }
2224  /// @}
2225 
2227 
2228  /// @{
2229  /// @private
2230  /// Methods used by GEO primitives to save/load vertex references
2231  bool loadVertexPointReferenceH9(UT_IStream &is,
2232  GA_Offset &point_offset);
2233  bool saveVertexPointReferenceH9(std::ostream &os,
2234  int binary, GA_Offset vertex_offset) const;
2235 
2236  static bool loadAttribDataH9(UT_IStream &is, GA_Offset offset,
2238  static bool saveAttribDataH9(std::ostream &os, int binary,
2239  GA_Offset offset,
2241  char delim_ch = '(');
2242  /// Convenience methods for saving/loading both a vertex's point reference
2243  /// and its attribute values in a Houdini9 compatible style. Note that the
2244  /// load wires the vertex to the loaded point.
2245  bool loadVertexH9(UT_IStream &is, GA_Offset vertex_offset,
2246  const UT_Array<GA_AttribLoadDataH9> &vtx_l);
2247  bool saveVertexH9(std::ostream &os, int binary,
2248  GA_Offset vertex_offset,
2249  const UT_Array<GA_AttribSaveDataH9> &vtx_l)
2250  const;
2251  /// @}
2252 
2253  /// Provide access to the factory. This allows users to query information
2254  /// about factories.
2256  { return myPrimitiveFactory; }
2257 
2258  /// Refreshes handles cached in the detail. This method must be called
2259  /// after changing the storage of the P attribute.
2260  virtual void refreshCachedHandles();
2261  /// Refreshes the cached myP attribute.
2262  void refreshCachedAttributes();
2263 
2264  /// @{
2265  /// Add/Remove an attribute to the tail-initialization list.
2266  ///
2267  /// When attributes grow in size, they usually initialize their values to
2268  /// the default value. However, some attributes may not adhere to this
2269  /// rule, or due to space optimizations, may have the values set to
2270  /// non-default values. In this case, they should be added to the
2271  /// tail-initialization list. When new elements are appended to the
2272  /// detail, they will be told to re-initialize the new element. Otherwise,
2273  /// the detail will assume that the element values are at their default
2274  /// value.
2275  ///
2276  /// When removing, the method will return @c true if the attribute was a
2277  /// tail initializer.
2278  ///
2279  /// @note These methods are thread-safe
2280  /// @note DO NOT CALL THESE: Use the GA_Attribute::setTailInitialization
2281  /// instead.
2282  void addTailInitializer(GA_Attribute *attrib);
2283  bool removeTailInitializer(GA_Attribute *attrib);
2284  /// @}
2285 
2286  /// Tell all tail initialization attributes to initialize the given offset
2287  /// @note This method is not thread-safe
2290  {
2291  if (myTailInitializers)
2292  doConstructTailInitializers(owner, start, size);
2293  }
2294 
2296  { return myPrimitiveList.containsType(type); }
2298  { return myPrimitiveList.containsOnlyTypes(type); }
2300  { return myPrimitiveList.countType(type); }
2302  { return myPrimitiveList.countTypeFamily(family); }
2304  { return myPrimitiveList.
2305  hasLocalTransform(myPrimitiveFactory); }
2307  UT_Array<const GA_Primitive *> &prims) const
2308  { return myPrimitiveList.getPrimitivesOfType(type, prims); }
2309 
2310  // ------------- Primitive Type Masks ----------------------
2311 
2312  /// Returns a primitive typemask that represents all known primitive type
2313  /// by the primitive factory that is associated with this detail.
2314  GA_PrimitiveTypeMask getPrimitiveTypeMaskAll() const;
2315 
2316  /// Returns the primitive typemask that represents all primitives in this
2317  /// detail.
2318  GA_PrimitiveTypeMask getPrimitiveTypeMask(
2319  const GA_PrimitiveGroup *group = 0) const;
2320 
2321 
2322  /// Return cached attribute instance matrix pointer
2323  const GA_AttributeInstanceMatrix &getInstanceMatrix() const;
2324 
2325  /// Clear the attribute instance matrix pointer. This is called
2326  /// automatically when point attributes are added or deleted.
2327  void clearInstanceMatrix();
2328 
2329  /// This function is entirely here so that GA has a way to check if a
2330  /// GA_Detail is a GEO_Detail (true) or GD_Detail (false).
2331  bool isPrimary() const
2332  {
2333  return myPrimitiveFactory.isForPrimaryDetail();
2334  }
2335 
2336  /// Builds & acquires GPU backed buffers for topology attributes.
2337  GA_CEAttribute *getTopologyCEAttribute(
2338  GA_Topology::TopologyCE topotype,
2339  GA_StorageClass storage,
2341  int &tuplesize,
2342  bool isarray,
2343  bool read, bool write);
2344 
2345  /// Builds a new CEAttribute for the given topology. This is not
2346  /// cached internally anywhere, nor does it use any existing cache.
2347  virtual UT_UniquePtr<GA_CEAttribute> buildTopologyCEAttribute(
2348  GA_Topology::TopologyCE topotype,
2349  GA_StorageClass storage,
2351  int &tuplesize,
2352  bool isarray,
2353  bool read, bool write) const;
2354 
2355  /// All GPU buffers that have been written to will be copied back
2356  /// to the CPU & marked clean.
2357  void flushCEWriteCaches();
2358 
2359  /// Flush all GPU-backed CE attributes, clearing them from this
2360  /// geometry.
2361  void flushCECaches();
2362 
2363  /// Steal all GPU-backed CE buffers from the source detail,
2364  /// including attributes, VDBs, and volumes. NOTE: this is
2365  /// only safe to call immediately after flushing the source
2366  /// detail's write cache with flushCEWriteCache, then calling
2367  /// replaceWith.
2368  void stealCEBuffers(const GA_Detail &srcdetail);
2369 
2370  /// Copy changed/non transforming attribute values from inputgeo
2371  /// owner specifies the attribute class to act upon
2372  /// This is used by SOP_Deform/SOP_AttribVop to speed up the duplication of input gdp.
2373  void copyChangedNonTransforming(const GA_Detail *inputgeo, GA_AttributeOwner owner);
2374 
2375  static const int64 INVALID_CACHE_COUNT = -1;
2376 
2377  void incrementMetaCacheCount() { myMetaCacheCount++; }
2378  int64 getMetaCacheCount() const { return myMetaCacheCount; }
2379 
2380  /// The preferred precision for both computation and creation of
2381  /// attributes. Default precision is 32bit.
2382  GA_Precision getPreferredPrecision() const;
2383  /// Override the preferred precision. Currently will accept
2384  /// 32 and 64bit.
2385  void setPreferredPrecision(GA_Precision prec);
2386 
2387  /// @{
2388  /// @private
2389  class GA_API MantraGeometry
2390  {
2391  public:
2392  MantraGeometry() {}
2393  virtual ~MantraGeometry() {}
2394  virtual void refreshCachedHandles();
2395  };
2396  MantraGeometry *mantraGeometry()
2397  { return myMantraGeometry; }
2398  const MantraGeometry *mantraGeometry() const
2399  { return myMantraGeometry; }
2400  void setMantraGeometry(MantraGeometry *m)
2401  { myMantraGeometry = m; }
2402  /// @}
2403 
2404 protected:
2405  void doConstructTailInitializers(GA_AttributeOwner owner,
2406  GA_Offset start, GA_Offset size);
2407 
2408  bool loadPrimitivesH9(UT_IStream &is, int count,
2409  const GA_FileFormatH9::PrimTypeXlate &type_map,
2410  const UT_Array<GA_AttribLoadDataH9> &prim_attribs,
2411  const UT_Array<GA_AttribLoadDataH9> &vtx_attribs);
2412  bool savePrimitivesH9(std::ostream &os, int binary,
2413  const UT_Array<const GA_Primitive *> &list,
2414  const GA_FileFormatH9::PrimTypeXlate &type_map,
2415  const UT_Array<GA_AttribSaveDataH9> &prim_attribs,
2416  const UT_Array<GA_AttribSaveDataH9> &vx_attribs) const;
2417 
2418  /// @{
2419  /// Virtual implementation of intrinsic attributes. See GA_IntrinsicEval
2420  /// for further details.
2421  virtual GA_Size localIntrinsicTupleSize(GA_IntrinsicEval &eval) const;
2422  virtual GA_Size localGetIntrinsicS(GA_IntrinsicEval &eval,
2423  UT_String &value) const;
2424  virtual GA_Size localGetIntrinsicSA(GA_IntrinsicEval &eval,
2425  UT_StringArray &value) const;
2426  virtual GA_Size localGetIntrinsicD(GA_IntrinsicEval &eval,
2427  UT_OptionsHolder &value) const;
2428  virtual GA_Size localGetIntrinsicDA(GA_IntrinsicEval &eval,
2430  virtual GA_Size localGetIntrinsicI(GA_IntrinsicEval &eval,
2431  int64 *value, GA_Size size) const;
2432  virtual GA_Size localGetIntrinsicF(GA_IntrinsicEval &eval,
2433  fpreal64 *value, GA_Size size) const;
2434  virtual GA_Size localSetIntrinsicS(GA_IntrinsicEval &eval,
2435  const char *value);
2436  virtual GA_Size localSetIntrinsicSA(GA_IntrinsicEval &eval,
2437  const UT_StringArray &value);
2438  virtual GA_Size localSetIntrinsicSS(GA_IntrinsicEval &eval,
2439  const char **value, GA_Size size);
2440  virtual GA_Size localSetIntrinsicDA(GA_IntrinsicEval &eval,
2442  virtual GA_Size localSetIntrinsicDS(GA_IntrinsicEval &eval,
2444  virtual GA_Size localSetIntrinsicI(GA_IntrinsicEval &eval,
2445  const int64 *value, GA_Size size);
2446  virtual GA_Size localSetIntrinsicF(GA_IntrinsicEval &eval,
2447  const fpreal64 *value, GA_Size size);
2448  /// @}
2449 
2450  // Methods used by GEO when loading old style geometry files.
2451  static void finishLoadH9(
2452  const UT_Array<GA_AttribLoadDataH9> &attribs
2453  );
2454 
2455  friend class GA_AttributeSet;
2456  /// This is here just so that GA_AttributeSet::jsonSave() can call
2457  /// GEOcomputeNormals()
2458  virtual void privateComputeNormal(
2459  const GA_RWHandleV3 &normalattrib,
2460  const GA_Group *group,
2461  const float cuspangledegrees,
2462  const int method) const
2463  {}
2464  /// This is here so that GA_AttributeSet::jsonLoad() can call it
2465  /// after loading attributes, since VDB primitive loading tries to
2466  /// write to P, and we might as well have it correctly split up
2467  /// before anything might read/write it.
2468  void splitAnyFloat4P();
2469 
2470  // Allow derived classes to modify myUniqueId and myMetaCacheCount
2471  // Don't make public, as this shouldn't be used in normal cooking.
2472  // Used by GU_Detail::cloneForCache() to make separated details act
2473  // as the same detail.
2474  void setUniqueId(exint i) { myUniqueId = i; }
2475  void setMetaCacheCount(int64 i) { myMetaCacheCount=i; }
2476 
2477 private:
2478  void init(GA_Storage Pstore, bool isprimary, bool full_topology);
2479 
2480  GA_Offset newPrimitiveOffset();
2481 
2482  void clearData(bool for_deletion);
2483 
2484  /// Destroy elements. When destroying points, if the
2485  /// guarantee_no_vertex_point_references is true, we don't bother
2486  /// dereferencing the points (which speeds up the operation).
2487  GA_Size destroyElements(const GA_Range &range,
2488  GA_DestroyPointMode mode=GA_LEAVE_PRIMITIVES,
2489  bool guarantee_no_vertex_point_references=false);
2490 
2491  // Try to make primitives de-reference the point
2492  bool dereferencePoint(GA_Offset point,
2493  GA_DestroyPointMode mode=GA_LEAVE_PRIMITIVES);
2494  // Try to make primitives de-reference a range of points. A return value
2495  // of true means that all points in the range are no longer referenced by
2496  // primitives, while a return value of false means that some points in the
2497  // range continue to be referenced. This method may allocate a membership
2498  // query object, in which case, the caller is responsible for deleting it.
2499  bool dereferencePoints(const GA_Range &point_range,
2500  const GA_RangeMemberQuery *&point_range_query,
2501  GA_DestroyPointMode mode=GA_LEAVE_PRIMITIVES);
2502 
2503 
2504  /// Called by GA_IO during loading of optimized formats
2505  bool setLoadCounts(GA_Size npoint, GA_Size nvertex, GA_Size nprim,
2506  GA_LoadMap &load);
2507 
2508  friend class GA_IO;
2509  friend class GA_PrimitiveList;
2510 
2511  GA_PrimitiveFactory &myPrimitiveFactory;
2512  GA_IndexMap myPointMap;
2513  GA_IndexMap myVertexMap;
2514  GA_IndexMap myPrimitiveMap;
2515  GA_IndexMap myGlobalMap; // Always has a single entry
2516  GA_PrimitiveList myPrimitiveList;
2517  GA_AttributeSet myAttributes;
2518  GA_Topology myTopology;
2519  GA_Attribute *myP;
2520  /// The pre-binding of position is as float, but we rely on the
2521  /// AlmostMatch binding allowing us to query double directly.
2522  GA_RWHandleV3 myHandlePV3;
2523  GA_Attribute *myPw;
2524  ga_TailInitializeTable *myTailInitializers;
2525  MantraGeometry *myMantraGeometry;
2526  mutable GA_AttributeInstanceMatrix *myInstanceMatrix;
2527  GA_PointGroupTable myPointGroups;
2528  GA_VertexGroupTable myVertexGroups;
2529  GA_PrimitiveGroupTable myPrimitiveGroups;
2530  GA_EdgeGroupTable myEdgeGroups;
2531  exint myUniqueId;
2532 
2533 
2534  /// Checking this meta cache count and the unique ID of the
2535  /// detail is sufficient to determine whether this detail
2536  /// has been modified since it was last examined, so long as it's
2537  /// not currently being used in a cook. Any cook only needs to
2538  /// increment the meta cache count once, and only if the detail
2539  /// is actually modified, (e.g. don't need to inc if instancing).
2540  ///
2541  /// NOTE: Do not rely on the detail pointer to check for modification,
2542  /// since a different detail could happen to be allocated
2543  /// at the same address in memory.
2544  int64 myMetaCacheCount;
2545 };
2546 
2547 #endif
SIM_API const UT_StringHolder vertex
GA_Size countPrimitiveTypeFamily(GA_PrimitiveFamilyMask family) const
Definition: GA_Detail.h:2301
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:1931
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:1608
GA_PointGroupTable & pointGroups()
Definition: GA_Detail.h:1179
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:1256
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:1447
void incrementMetaCacheCount()
Definition: GA_Detail.h:2377
bool containsLocalTransformPrimitive() const
Definition: GA_Detail.h:2303
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:1756
SYS_FORCE_INLINE const GA_Attribute * findGlobalAttribute(GA_AttributeScope s, const UT_StringRef &name) const
Definition: GA_Detail.h:1058
const GA_VertexGroupTable & vertexGroups() const
Definition: GA_Detail.h:1189
SYS_FORCE_INLINE GA_Primitive * getPrimitive(GA_Offset prim_off)
Definition: GA_Detail.h:429
GA_PrimitiveGroupUPtr createDetachedPrimitiveGroup() const
Definition: GA_Detail.h:1365
SYS_FORCE_INLINE void copyPoint(GA_Offset destptoff, GA_Offset srcptoff, const GA_AttributeFilter *filter=nullptr)
Definition: GA_Detail.h:1861
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:878
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:1048
GLenum GLint * range
Definition: glcorearb.h:1925
GA_Primitive GB_MACRO_PRIM_TYPE
Definition: GA_Detail.h:2226
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:908
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:1768
int gbstatus() const
Definition: GA_Detail.h:1997
SYS_FORCE_INLINE void forEachPointBreak(const GA_PointGroup *group, bool complement, FUNCTOR &&functor) const
Definition: GA_Detail.h:1550
void getIONames(UT_StringArray &names) const
Definition: GA_Detail.h:1965
const GA_IndexMap & getPrimitiveMap() const
Definition: GA_Detail.h:746
SYS_FORCE_INLINE GA_Attribute * findGlobalAttribute(const UT_StringRef &name)
Definition: GA_Detail.h:1120
static T::GB_MACRO_PRIM_TYPE * GB_MACRO_CAST(const T *, GA_Primitive *prim)
Definition: GA_Detail.h:2222
GA_Size destroyVertexOffsets(const GA_Range &range)
Definition: GA_Detail.h:713
GA_PointGroup * newInternalPointGroup()
Definition: GA_Detail.h:1314
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:2288
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:1960
SYS_FORCE_INLINE const GA_Attribute * findVertexAttribute(GA_AttributeScope s, const UT_StringRef &name) const
Definition: GA_Detail.h:1044
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:1393
void setMantraGeometry(MantraGeometry *m)
Definition: GA_Detail.h:2400
const GLuint GLenum const void * binary
Definition: glcorearb.h:1924
UT_Vector3T< float > UT_Vector3
GA_VertexGroup * newInternalVertexGroup()
Definition: GA_Detail.h:1318
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:2398
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:1443
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:1028
SYS_FORCE_INLINE GA_Attribute * findAttribute(GA_AttributeOwner owner, const UT_StringRef &name)
Definition: GA_Detail.h:1091
SYS_FORCE_INLINE GA_ElementGroupTableT< OWNER >::GROUP_TYPE * createElementGroup(const UT_StringHolder &name, bool ordered=false)
Definition: GA_Detail.h:1200
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:1062
SYS_FORCE_INLINE GA_Attribute * findPointAttribute(GA_AttributeScope s, const UT_StringRef &name)
Definition: GA_Detail.h:1095
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:1322
GA_EdgeGroupTable & edgeGroups()
Definition: GA_Detail.h:1191
IOStatus & operator=(const IOStatus &src)
Definition: GA_Detail.h:1981
**But if you need a result
Definition: thread.h:613
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:2475
static const T::GB_MACRO_PRIM_TYPE * GB_MACRO_CAST(const T *, const GA_Primitive *prim)
Definition: GA_Detail.h:2219
GA_PointGroup * newPointGroup(const UT_StringHolder &name)
Definition: GA_Detail.h:1291
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:1227
SYS_FORCE_INLINE void forEachPointBreak(const GA_PointGroup *group, FUNCTOR &&functor) const
Definition: GA_Detail.h:1544
SYS_FORCE_INLINE GA_PrimitiveGroup * findPrimitiveGroup(const UT_StringRef &name)
Definition: GA_Detail.h:1266
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:1109
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
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
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:2299
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:1299
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:1440
double fpreal64
Definition: SYS_Types.h:201
SYS_FORCE_INLINE const GA_Attribute * findPointAttribute(const UT_StringRef &name) const
Definition: GA_Detail.h:1041
SYS_FORCE_INLINE GA_VertexGroup * findVertexGroup(const UT_StringRef &name)
Definition: GA_Detail.h:1263
#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:1389
GA_PointGroupUPtr createDetachedPointGroup() const
Definition: GA_Detail.h:1361
SYS_FORCE_INLINE void forEachPrimitiveBreak(FUNCTOR &&functor) const
Definition: GA_Detail.h:1602
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:1326
GA_VertexGroupTable & vertexGroups()
Definition: GA_Detail.h:1187
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:1033
GLdouble n
Definition: glcorearb.h:2008
GLfloat f
Definition: glcorearb.h:1926
MantraGeometry * mantraGeometry()
Definition: GA_Detail.h:2396
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:1738
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
Definition: core.h:760
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:1771
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:1678
GA_PointGroup * newPointGroup(const UT_StringHolder &name, bool internal)
Definition: GA_Detail.h:1381
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:1507
SYS_FORCE_INLINE bool destroyElementGroup(GA_AttributeOwner owner, const UT_StringRef &name)
Definition: GA_Detail.h:1238
GA_EdgeGroup * newEdgeGroup(const UT_StringHolder &name)
Definition: GA_Detail.h:1303
#define UT_ASSERT_P(ZZ)
Definition: UT_Assert.h:155
GA_EdgeGroupUPtr createDetachedEdgeGroup() const
Definition: GA_Detail.h:1373
bool registerIO(GA_IO *io) const
Register an IO file format.
Definition: GA_Detail.h:1955
SYS_FORCE_INLINE const GA_PointGroup * findPointGroup(const UT_StringRef &name) const
Definition: GA_Detail.h:1250
SYS_FORCE_INLINE void forEachPrimitive(FUNCTOR &&functor) const
Definition: GA_Detail.h:1567
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:1193
GLuint GLuint end
Definition: glcorearb.h:475
#define SYS_FORCE_INLINE
Definition: SYS_Inline.h:45
bool success() const
Definition: GA_Detail.h:1990
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:1445
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:986
SYS_FORCE_INLINE GA_Attribute * findPrimitiveAttribute(const UT_StringRef &name)
Definition: GA_Detail.h:1113
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:2474
SYS_FORCE_INLINE GA_Attribute * findPointAttribute(const UT_StringRef &name)
Definition: GA_Detail.h:1099
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:895
IOStatus(const IOStatus &src)
Definition: GA_Detail.h:1976
const GA_PointGroupTable & pointGroups() const
Definition: GA_Detail.h:1181
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:1078
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:1219
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:1068
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:1116
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:1745
SYS_FORCE_INLINE GA_PointGroup * findPointGroup(const UT_StringRef &name)
Definition: GA_Detail.h:1260
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:1010
SYS_FORCE_INLINE bool destroyEdgeGroup(const UT_StringRef &name)
Definition: GA_Detail.h:1278
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:1281
SYS_FORCE_INLINE const GA_Attribute * findPrimitiveAttribute(const UT_StringRef &name) const
Definition: GA_Detail.h:1055
GA_GlobalIntrinsic findGlobalIntrinsic(GA_LocalIntrinsic h) const
Definition: GA_Detail.h:1434
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:930
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:1519
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:1614
SYS_FORCE_INLINE const GA_Attribute * findPrimitiveAttribute(GA_AttributeScope s, const UT_StringRef &name) const
Definition: GA_Detail.h:1051
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:972
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:1369
SYS_FORCE_INLINE GA_ElementGroupTable & getElementGroupTable(GA_AttributeOwner owner)
Definition: GA_Detail.h:1166
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:1432
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:920
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:1877
fpreal64 fpreal
Definition: SYS_Types.h:277
SYS_FORCE_INLINE GA_Offset primitiveOffset(GA_Index index) const
Given a primitive's index (in append order), return its data offset.
Definition: GA_Detail.h:419
SYS_FORCE_INLINE GA_ElementGroupTableT< OWNER >::GROUP_TYPE * createInternalElementGroup(bool ordered=false)
Definition: GA_Detail.h:1210
SYS_FORCE_INLINE bool destroyAttribute(GA_AttributeOwner owner, const UT_StringRef &name)
Definition: GA_Detail.h:941
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:2295
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:1528
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:1385
int64 getMetaCacheCount() const
Definition: GA_Detail.h:2378
SYS_FORCE_INLINE void forEachPointBreak(FUNCTOR &&functor) const
Definition: GA_Detail.h:1538
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:947
Provide options when performing a merge operation.
IOStatus(bool success=false)
Definition: GA_Detail.h:1973
#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:1086
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:1592
GA_PrimitiveGroupTable & primitiveGroups()
Definition: GA_Detail.h:1183
Container class for all geometry.
Definition: GA_Detail.h:96
bool isPrimary() const
Definition: GA_Detail.h:2331
GLubyte GLubyte GLubyte GLubyte w
Definition: glcorearb.h:857
Definition: core.h:1131
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:933
SYS_FORCE_INLINE void forEachPrimitive(const GA_PrimitiveGroup *group, FUNCTOR &&functor) const
Definition: GA_Detail.h:1583
SYS_FORCE_INLINE GA_Attribute * findVertexAttribute(GA_AttributeScope s, const UT_StringRef &name)
Definition: GA_Detail.h:1102
UT_UniquePtr< GA_PointGroup > GA_PointGroupUPtr
GA_LocalIntrinsic findIntrinsic(const UT_StringRef &nm) const
Definition: GA_Detail.h:1430
virtual void privateComputeNormal(const GA_RWHandleV3 &normalattrib, const GA_Group *group, const float cuspangledegrees, const int method) const
Definition: GA_Detail.h:2458
const GA_AttributeDict & getAttributeDict(GA_AttributeOwner owner) const
Definition: GA_Detail.h:835
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:1185
UT_Vector4T< fpreal64 > UT_Vector4D
GA_VertexGroup * newVertexGroup(const UT_StringHolder &name)
Definition: GA_Detail.h:1295
SYS_FORCE_INLINE const GA_Attribute * findAttribute(const UT_StringRef &name, const GA_AttributeOwner search_order[], int search_size) const
Definition: GA_Detail.h:1020
SYS_FORCE_INLINE const GA_Attribute * findPointAttribute(GA_AttributeScope s, const UT_StringRef &name) const
Definition: GA_Detail.h:1037
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:1741
SYS_FORCE_INLINE const GA_VertexGroup * findVertexGroup(const UT_StringRef &name) const
Definition: GA_Detail.h:1253
void setPos2(GA_Offset ptoff, const UT_Vector2 &pos)
Set P from a UT_Vector2.
Definition: GA_Detail.h:225
type
Definition: core.h:1059
Class to specify options for loading geometry.
SYS_FORCE_INLINE bool destroyElementGroup(GA_AttributeOwner owner, const char *name)
Definition: GA_Detail.h:1242
static void forEachOffset(FUNCTOR &&functor, const GA_IndexMap &index_map, const GA_ElementGroup *group=nullptr, bool complement=false)
Definition: GA_Detail.h:1621
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:2306
GA_Storage
Definition: GA_Types.h:51
UT_UniquePtr< GA_ATINumeric > GA_ATINumericUPtr
const GA_PrimitiveFactory & getPrimitiveFactory() const
Definition: GA_Detail.h:2255
SYS_FORCE_INLINE GA_Attribute * findVertexAttribute(const UT_StringRef &name)
Definition: GA_Detail.h:1106
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:957
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:2297
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:867
const GA_IntrinsicManager & getIntrinsicManager() const
Definition: GA_Detail.h:1421
SYS_FORCE_INLINE GA_Offset offsetSize() const
Definition: GA_IndexMap.h:97
const char * getIntrinsicName(GA_LocalIntrinsic h) const
Definition: GA_Detail.h:1437
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:997
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