HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
GA_PrimitiveList.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_PrimitiveList.h (GA Library, C++)
7  *
8  * COMMENTS: The list of a detail's primitives.
9  */
10 
11 #pragma once
12 
13 #ifndef __GA_PrimitiveList__
14 #define __GA_PrimitiveList__
15 
16 #define COMPRESSED_PRIM_LIST 1
17 
18 #include "GA_API.h"
19 #include "GA_OffsetList.h"
20 #include "GA_PageArray.h"
21 #include "GA_PrimitiveTracker.h"
22 #include "GA_PrimitiveTypeId.h"
23 #include "GA_Types.h"
24 #include <UT/UT_Array.h>
25 #if COMPRESSED_PRIM_LIST
26 #include <UT/UT_TaskExclusive.h>
27 #endif
28 #include <SYS/SYS_Inline.h>
29 
30 class GA_Defragment;
31 class GA_Detail;
32 struct GA_JSONUniformBlock;
33 class GA_LoadMap;
34 class GA_MergeMap;
35 class GA_PolyCounts;
36 class GA_Primitive;
38 class GA_SaveMap;
39 
40 class UT_StringRef;
41 class UT_JSONParser;
42 class UT_JSONValue;
43 class UT_JSONWriter;
44 class UT_MemoryCounter;
45 class UT_StringArray;
46 
47 /// @brief A list of primitives
48 ///
49 /// Primitives for a detail are stored in a primitive list. The list stores
50 /// pointers to primitive objects.
51 /// The list is ordered in the same order as the primitive attribute lists.
53 {
54 public:
55  GA_PrimitiveList(GA_Detail &detail);
56 
59  {
60  clear(true);
61  }
62 
64  const GA_Primitive *get(GA_Offset off) const
65  {
66  const GA_Primitive *const*prim_array = myList;
67 #if COMPRESSED_PRIM_LIST
68  if (!prim_array)
69  prim_array = hardenPrimitives();
70 #endif
71  UT_ASSERT_P(GAisValid(off) && off < GA_Offset(getMyListSize()));
72  return prim_array[off];
73  }
76  {
77  GA_Primitive *const*prim_array = myList;
78 #if COMPRESSED_PRIM_LIST
79  if (!prim_array)
80  prim_array = hardenPrimitives();
81 #endif
82  UT_ASSERT_P(GAisValid(off) && off < GA_Offset(getMyListSize()));
83  return prim_array[off];
84  }
85 
86  /// Returns a shallow copy of the vertex list of the primitive at the
87  /// specified primitive offset.
88  /// You must include GA_Primitive.h to use this.
90  GA_OffsetListRef getVertexList(GA_Offset primoff) const;
91 
92  /// Returns the number of vertices in the primitive at the specified
93  /// primitive offset.
94  /// You must include GA_Primitive.h to use this.
96  GA_Size getVertexCount(GA_Offset primoff) const;
97 
98  /// Returns the vertex offset in the primitive at the specified
99  /// primitive offset in vertex list position i.
100  /// If you're accessing all vertex offsets, it'll be faster to
101  /// call getVertexList() once and either read from that or
102  /// call forEach(fucntor) on it.
103  /// You must include GA_Primitive.h to use this.
105  GA_Offset getVertexOffset(GA_Offset primoff, GA_Size i) const;
106 
107  /// Returns the type ID of the primitive at the specified
108  /// primitive offset.
109  /// You must include GA_Primitive.h to use this.
111  int getTypeId(GA_Offset primoff) const;
112 
113  /// Returns the "closed" flag for polygon, NURBS curve, or Bezier curve
114  /// primitives, or false for other primitive types.
115  /// You must include GA_Primitive.h to use this.
117  bool getClosedFlag(GA_Offset primoff) const;
118 
119  /// Sets the "closed" flag for polygon primitives.
120  /// For NURBS curve or Bezier curve primitives, use GEO_Face::close()
121  /// or GEO_Face::open().
122  /// You must include GA_Primitive.h to use this.
124  void setClosedFlag(GA_Offset primoff, bool closed);
125 
126  /// Report on memory usage
127  int64 getMemoryUsage(bool inclusive) const;
128 
129  /// Count memory usage using a UT_MemoryCounter in order to count
130  /// shared memory correctly.
131  /// If inclusive is true, the size of this object is counted,
132  /// else only memory owned by this object is counted.
133  /// If this is pointed to by the calling object, inclusive should be true.
134  /// If this is contained in the calling object, inclusive should be false.
135  /// (Its memory was already counted in the size of the calling object.)
136  void countMemory(UT_MemoryCounter &counter, bool inclusive) const;
137 
138  /// Offset size of the list
140  {
141 #if COMPRESSED_PRIM_LIST
142  return GA_Offset(myList ? getMyListSize() : myVertexLists.size());
143 #else
144  return GA_Offset(getMyListSize());
145 #endif
146  }
147 
148  /// Set capacity of primitive offsets in the list
149  void adjustArraySize(GA_Offset size);
150  void clear(bool for_deletion);
151 
152  void stashAll();
153  void destroyStashed();
154 
155  /// Returns true iff the primitive list representation is as
156  /// separate allocations for each primitive, instead of using the
157  /// paged array format.
158  bool isFullRepresentation() const
159  {
160  return myList != nullptr;
161  }
162 
163  /// Returns true iff the specified vertex list page is constant.
165  {
166  return !myList && myVertexLists.isPageConstant(UT_PageNum(pagenum));
167  }
168 
169  void merge(GA_Detail &dgeo, const GA_MergeMap &map);
170 
171  /// NOTE: Since the primitive maps of dstgeo and srcgeo must have already
172  /// been made equal by the time this is called.
173  void replace(GA_Detail &dstgeo, const GA_Detail &srcgeo);
174 
175  /// Called by GA_Detail::defragment when defragmenting the primitive
176  /// index map.
177  /// NOTE: This bumps the primitive list data ID.
178  void defragment(const GA_Defragment &defrag);
179 
180  /// Called by GA_Detail::defragment when defragmenting the vertex
181  /// index map.
182  /// NOTE: This bumps the primitive list data ID.
183  void defragmentVertices(const GA_Defragment &defrag);
184 
185  /// Copy any modified caches from the GPU back to CPU cache.
186  void flushCEWriteCaches(const GA_PrimitiveFactory &f);
187 
188  /// Copy any modified caches from the GPU to CPU. Then delete the GPU
189  /// cache.
190  void flushCECaches(const GA_PrimitiveFactory &f);
191 
192  /// Save data to a JSON stream.
193  /// @section JSON-GA_PrimitiveList JSON Schema: GA_PrimitiveList
194  /// @code
195  /// {
196  /// "name" : "GA_PrimitiveList",
197  /// "description" : "An array of primitive objects",
198  /// "type" : "array",
199  /// "items" : { "$ref":"GA_Primitive" },
200  /// }
201  /// @endcode
202  /// @see @ref JSON_FileFormat, GA_Primitive
203  bool jsonSave(UT_JSONWriter &w, const GA_SaveMap &save) const;
204 
205  /// Load from a JSON stream
206  /// @see @ref JSON_FileFormat
207  bool jsonLoad(UT_JSONParser &p, GA_LoadMap &load, GA_Offset &load_end);
208 
209  /// Check to see whether the primitive list contains primitives of a given
210  /// type
212  { return myTracker.contains(type); }
213  /// Return the number of primitives of the given type
215  { return myTracker.count(type); }
216  /// Test whether the primitive list contains any primitives that have a
217  /// local transform.
218  bool hasLocalTransform(const GA_PrimitiveFactory &factory) const
219  { return myTracker.hasLocalTransform(factory); }
220  /// Return the primitives of the given type. Unlike the functions
221  /// above which use myTracker, this function requires iterating through
222  /// all primitives.
223  bool getPrimitivesOfType(const GA_PrimitiveTypeId &type,
224  UT_Array<const GA_Primitive *> &prims) const;
225 
226  /// Use this to mark primitives or their intrinsic data as dirty.
227  void bumpDataId();
229  { return myDataID; }
230 
232  { return myTracker; }
233 
234  /// Goes through the primitive list to confirm that it's in a consistent
235  /// state, returning true if it is, and false if it isn't.
236  /// This is only for debugging purposes.
237  bool validate(const GA_Detail &detail) const;
238 
239  // NOTE: These functor classes must be in the scope of GA_PrimitiveList
240  // so that it can access GA_Primitive::unstashImpl,
241  // GA_PrimitiveDefinition::getConstructor, and
242  // GA_PrimitiveDefinition::getBlockConstructor.
243  // They have to be public so that UTparallelReduce
244  // can be instantiated for GCC with it.
245  class ga_ParallelCreateForMerge;
246  class ga_ParallelCreatePagedForMerge;
247  class ga_ReplacePrimitiveBlockParallel;
248 
249 private:
250  void create(GA_Detail &detail,
251  const GA_PrimitiveDefinition &def,
253  bool check_stash);
254  void createBlock(GA_Detail &detail,
255  const GA_PrimitiveDefinition &def,
256  GA_Size nprimitives,
258  bool check_stash);
259  void initVertexLists(
260  GA_Offset prim_block_start,
261  GA_Offset vertex_block_start,
262  GA_Size nprimitives,
263  GA_Size nvertices_each,
264  bool closed = false);
265  void initVertexLists(
266  GA_Offset prim_block_start,
267  GA_Offset vertex_block_start,
268  const GA_PolyCounts &vertex_counts,
269  bool closed = false);
270 
271  /// To be called from GA_Detail::sortVertexMapByPrimitiveUse()
272  void sortVertexMapByPrimitiveUse(GA_IndexMap &vertex_map);
273 
274  /// @{
275  /// This class is non-copyable
277  const GA_PrimitiveList &operator=(const GA_PrimitiveList &);
278  /// @}
279 
280  bool loadPolyOrTetRun(
281  UT_JSONParser &p,
282  int runenum,
283  GA_Offset &primoff,
284  GA_Offset init_vtxoff,
285  GA_Detail &detail);
286  bool createLoadPrimitive(UT_JSONParser &p,
287  GA_LoadMap &load,
288  const UT_StringRef &type,
289  GA_Offset &load_offset,
290  const UT_StringArray *varying,
291  const GA_JSONUniformBlock &uniform);
292 
294  exint getMyListSize() const
295  {
296  return getMyPrimPtrSize(myList);
297  }
299  exint getMyStashedSize() const
300  {
301  return getMyPrimPtrSize(myStashedPrims);
302  }
304  static exint getMyPrimPtrSize(GA_Primitive**p)
305  {
306  UT_ASSERT_P(p);
307  return ((const exint*)p)[-1];
308  }
309  void reallocMyList(exint newsize);
311  void freeMyList();
312 
313 #if COMPRESSED_PRIM_LIST
314  GA_OffsetList *hardenVertexListPage(GA_PageNum pagenum);
315  void hardenAllVertexListPages();
316  void clearVertexLists();
317 #endif
318  void destroy(GA_Offset off);
319 
320 #if COMPRESSED_PRIM_LIST
321  GA_Primitive *const*hardenPrimitives() const;
322  /// This can be faster than hardenPrimitives, if we're calling from a
323  /// thread-unsafe function already.
324  GA_Primitive *const*hardenPrimitivesThreadUnsafe();
326  GA_Primitive *const*hardenPrimitivesImpl(bool parallel) const;
327  class HardenPrimitivesFunctor;
328 
329  void dump() const;
330 #endif
331 
332  friend class GA_Detail;
333 
334  /// This is nullptr when using myVertexLists and myPrimitiveTypes.
335  /// It has an exint indicating the size immediately before
336  /// where it points in memory.
337  mutable GA_Primitive **myList;
338 #if COMPRESSED_PRIM_LIST
339  GA_Detail &myDetail;
340  GA_PageArray<int,1,false,false> myPrimitiveTypes;
341  GA_PageArray<int64,2,false,false> myVertexLists;
342  mutable UT_TaskExclusive<HardenPrimitivesFunctor> myHardenExclusive;
343 #endif
344  GA_PrimitiveTracker myTracker;
345  GA_DataId myDataID;
346 
347  /// Array of temporarily stashed primitives.
348  /// This is only used to reduce overhead of freeing and
349  /// reallocating primitives if it's likely that the
350  /// detail is going to be rebuilt with the same primitive
351  /// types in the same order as the previous primitives.
352  /// It has an exint indicating the size immediately before
353  /// where it points in memory.
354  mutable GA_Primitive **myStashedPrims;
355 };
356 
357 #endif
A class to manage an ordered array which has fixed offset handles.
Definition: GA_IndexMap.h:63
Used to pass options and map offset values during saving.
Definition: GA_SaveMap.h:48
GA_DataId getDataId() const
const GA_PrimitiveTracker & getTracker() const
int64 GA_DataId
Definition: GA_Types.h:663
bool GAisValid(GA_Size v)
Definition: GA_Types.h:625
The merge map keeps track of information when merging details.
Definition: GA_MergeMap.h:53
exint UT_PageNum
Definition: UT_PageArray.h:40
JSON reader class which handles parsing of JSON or bJSON files.
Definition: UT_JSONParser.h:75
#define GA_API
Definition: GA_API.h:12
Class which writes ASCII or binary JSON streams.
Definition: UT_JSONWriter.h:32
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
GLsizeiptr size
Definition: glcorearb.h:663
GA_Size GA_Offset
Definition: GA_Types.h:617
GA_Size countType(const GA_PrimitiveTypeId &type) const
Return the number of primitives of the given type.
long long int64
Definition: SYS_Types.h:107
bool containsType(const GA_PrimitiveTypeId &type) const
GLfloat f
Definition: glcorearb.h:1925
SYS_FORCE_INLINE ~GA_PrimitiveList()
bool isVertexListPageConstant(GA_PageNum pagenum) const
Returns true iff the specified vertex list page is constant.
int64 exint
Definition: SYS_Types.h:116
Class which keeps counts of each type of primitive.
#define UT_ASSERT_P(ZZ)
Definition: UT_Assert.h:125
#define SYS_FORCE_INLINE
Definition: SYS_Inline.h:45
GLintptr offset
Definition: glcorearb.h:664
Options during loading.
Definition: GA_LoadMap.h:42
Defragmentation of IndexMaps.
Definition: GA_Defragment.h:45
A list of primitives.
GA_Size GA_PageNum
Definition: GA_Types.h:620
bool isFullRepresentation() const
bool hasLocalTransform(const GA_PrimitiveFactory &factory) const
Class to store JSON objects as C++ objects.
Definition: UT_JSONValue.h:75
GLint GLint GLsizei GLint GLenum GLenum type
Definition: glcorearb.h:107
Container class for all geometry.
Definition: GA_Detail.h:95
GA_Offset offsetSize() const
Offset size of the list.
GLubyte GLubyte GLubyte GLubyte w
Definition: glcorearb.h:856
Definition of a geometric primitive.