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