HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
GA_MergeOptions.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_MergeOptions.h ( GA Library, C++)
7  *
8  * COMMENTS:
9  */
10 
11 #ifndef __GA_MergeOptions__
12 #define __GA_MergeOptions__
13 
14 #include "GA_API.h"
15 #include "GA_Range.h"
16 #include "GA_Types.h"
17 #include "GA_ReuseStrategy.h"
18 
19 #include <SYS/SYS_Math.h>
20 
21 
22 class GA_Detail;
24 class GA_Primitive;
25 
26 template <typename T> class UT_Array;
27 
28 
29 /// @brief Provide options when performing a merge operation.
30 ///
31 /// This class stores generic options which can be set/accessed when merging.
32 ///
33 /// Some common options are implemented using the @c IMPL_ENUM define.
34 ///
35 /// - TYPE = the name of the enum
36 /// - DEF = the default enum (used if no option is found)
37 /// - GENERAL = the name of the general option (i.e. "storagestrategy")
38 /// - VERTEX = speicific name for vertex attribs (i.e. "vertex:storagestrategy)
39 /// - POINT = specific name for point (i.e. "point:storagestrategy)
40 /// - PRIMITIVE = specifid name for primitive (i.e. "primitive:storagestrategy)
41 /// - GLOBAL = specific name for global (i.e. "global:storagestrategy)
42 ///
43 /// The methods provided are:
44 /// @code
45 /// TypeStrategy getTypeStrategy()
46 /// TypeStrategy getTypeStrategy(GA_AttributeOwner owner)
47 /// void setTypeStrategy(TypeStrategy value)
48 /// void setTypeStrategy(TypeStrategy value, GA_AttributeOwner owner)
49 ///
50 /// StorageStrategy getStorageStrategy()
51 /// StorageStrategy getStorageStrategy(GA_AttributeOwner owner)
52 /// void setStorageStrategy(StorageStrategy value)
53 /// void setStorageStrategy(StorageStrategy value, GA_AttributeOwner owner)
54 ///
55 /// TupleSizeStrategy getTupleSizeStrategy()
56 /// TupleSizeStrategy getTupleSizeStrategy(GA_AttributeOwner owner)
57 /// void setTupleSizeStrategy(TupleSizeStrategy value)
58 /// void setTupleSizeStrategy(TupleSizeStrategy value, GA_AttributeOwner owner)
59 ///
60 /// MergeStrategy getMergeStrategy()
61 /// MergeStrategy getMergeStrategy(GA_AttributeOwner owner)
62 /// void setMergeStrategy(MergeStrategy value)
63 /// void setMergeStrategy(MergeStrategy value, GA_AttributeOwner owner)
64 /// @endcode
65 ///
66 /// List of all well defined options:
67 /// - [point|vertex|primitive|global:]typestrategy @n
68 /// What to do when the attribute type on the source & destination of the
69 /// merge don't match.
70 /// - [point|vertex|primitive|global:]storagestrategy @n
71 /// What to do when the attribute storage on the source & destination of the
72 /// merge don't match.
73 /// - [point|vertex|primitive|global:]tuplesizestrategy @n
74 /// What to do when the attribute tuple size on the source & destination of
75 /// the merge don't match.
76 /// - [point|vertex|primitive|global:]mergestrategy @n
77 /// What approach should be taken when laying out data in the index maps
78 /// when merging data. Optimize for either space or speed.
79 /// - point|primitive:insert_at_head @n
80 /// Insert primitives/points at head of ordered list rather than appending
81 /// - point|primitive|vertex|edge|breakpoint:mergegroups
82 /// Whether to merge groups from source detail. Defaults to true.
83 /// - point|primitive|vertex|edge|breakpoint:mergeinternalgroups
84 /// Whether to merge internal groups from source detail. Defaults to true.
85 /// - point:mergeallpoints @n
86 /// When specifying a primitive group, by default only the points
87 /// referenced by the primitives will be merged. Setting this option will
88 /// cause @b all points to be merged.
89 /// - merge:threaded
90 /// Perform threaded merging of data
91 ///
93 {
94 public:
96 
97  /// The @c TypeStrategy is used to give a hint to the AIFMerge if it
98  /// encounters a type difference on the attributes. For example,
99  /// if the destination is a string attribute, but the source has a boolean
100  /// attribute, the attribute can either keep or change the destination to
101  /// match the source.
103  {
104  /// Only process exact matches on types
106  /// Keep destination unchanged if possible
108  /// Change destination attribute to match source
110 
111  TYPE_DEFAULT = TYPE_KEEP_DEST
112  };
113  /// For attributes which have storage, this enum gives a hint of what to do
114  /// if there's a mis-match on storage types.
116  {
117  /// Disallow mis-matched storage
119  /// Keep destination storage (casting source)
121  /// Change destination to match storage
123  /// Use storage with greatest precision
125 
126  STORAGE_DEFAULT = STORAGE_USE_BEST
127  };
128 
129  /// For attributes which have a tuple size, this enum gives a hint of what
130  /// to do if there's a mis-match on storage types.
132  {
133  /// Disallow mis-matched tuple sizes
135  /// Use the destination tuple size
137  /// Change destination to match source
139  /// Use the largest tuple size
141 
142  TUPLE_SIZE_DEFAULT = TUPLE_SIZE_USE_BEST
143  };
144 
145  /// The @c MergeStrategy is used to give a hint as to how the merge should
146  /// append data after the existing data or whether the source data should
147  /// be interleaved with the existing data.
148  /// The merge operation may change this "hint" for the actual operation.
150  {
151  /// The optimal mode will use simple heuristics to determine whether
152  /// elements should be appended or interleaved.
154  /// MERGE_COPY is very similar to MERGE_APPEND. However, this is done
155  /// when the original destination list has no elements allocated before
156  /// the merge (i.e. the merge acts as a copy).
158  /// All data is appended to the end of the existing destination data.
159  /// This offers attributes the opportunity to share data.
161  /// In this mode, the source data is merged and mixed in with the
162  /// destination data. This will result in the most compact storage,
163  /// but may result in non-shared data after the merge.
165 
166  MERGE_DEFAULT = MERGE_OPTIMAL
167  };
168 
169 #define IMPL_ENUM(TYPE, DEF) \
170  TYPE get##TYPE() const { \
171  if (my##TYPE[GA_ATTRIB_OWNER_N] >= 0) \
172  return my##TYPE[GA_ATTRIB_OWNER_N]; \
173  return DEF; \
174  } \
175  TYPE get##TYPE(GA_AttributeOwner owner) const { \
176  if (my##TYPE[owner] >= 0) return my##TYPE[owner]; \
177  return get##TYPE(); \
178  } \
179  void set##TYPE(TYPE v) { my##TYPE[GA_ATTRIB_OWNER_N] = v; } \
180  void set##TYPE(TYPE v, GA_AttributeOwner owner) { \
181  my##TYPE[owner] = v; \
182  }
183 
184  IMPL_ENUM(TypeStrategy, TYPE_DEFAULT)
185  IMPL_ENUM(StorageStrategy, STORAGE_DEFAULT)
186  IMPL_ENUM(TupleSizeStrategy, TUPLE_SIZE_DEFAULT)
187  IMPL_ENUM(MergeStrategy, MERGE_DEFAULT)
188 
189 #undef IMPL_ENUM
190 
192  {
193  switch (owner)
194  {
195  case GA_ATTRIB_POINT:
196  return getSourcePointRange();
197  case GA_ATTRIB_PRIMITIVE:
198  return getSourcePrimitiveRange();
199  default:
200  break;
201  }
202  return 0;
203  }
204 
205  /// @{
206  /// Set whether the merge should copy over group membership for the given
207  /// attribute type. By default, all groups are copied.
208  ///
209  /// Note that only a single type should be passed in (don't use bit-masks)
210  void setMergeGroups(GA_GroupType type, bool state)
211  { myGroupMerge[type] = state; }
212  void setAllMergeGroups(bool state)
213  {
214  for (int i = 0; i < GA_GROUP_N; ++i)
215  {
216  myGroupMerge[i] = state;
217  }
218  }
220  { return myGroupMerge[type]; }
222  { myInternalGroupMerge[type] = state; }
223  void setAllMergeInternalGroups(bool state)
224  {
225  for (int i = 0; i < GA_GROUP_N; ++i)
226  {
227  myInternalGroupMerge[i] = state;
228  }
229  }
231  { return myInternalGroupMerge[type]; }
232  /// @}
233 
234  /// @{
235  /// There are two iterators that can be specified in the options. This
236  /// allows the merge operation to operate on a subset of primitives &
237  /// points.
238  /// - If neither range is set, all source primitives, vertices and points
239  /// will be merged.
240  /// - If the primitive range is set, only the primitives in the range will
241  /// be merged. Only the points used by the primitives will be merged
242  /// unless the bool option: "point:mergeallpoints" is set.
243  /// - If the point range is set, no primitives will be merge, and only the
244  /// points in the range will be merged.
246  { return myPointRange.getRTI()
247  ? &myPointRange : (const GA_Range *)NULL; }
249  { return myPrimitiveRange.getRTI()
250  ? &myPrimitiveRange : (const GA_Range *)NULL; }
251 
253  { myPrimitiveRange = range; }
255  { myPointRange = range; }
256  /// @}
257 
258  /// @{
259  /// For backward compatibility with the GEO library, we provide a method to
260  /// control the "mapping" from source primitives to the newly
261  /// created merged primitives.
262  void setPrimitiveMap(UT_Array<GA_Primitive*> *prims);
264  { return myPrimitiveMap; }
265  /// @}
266 
267  /// @{
268  /// For backward compatibility with the GEO library, we provide a method to
269  /// control the "mapping" from source points to the newly created merged
270  /// points.
271  void setPointRedirect(GA_GBPointRedirectArray *map);
273  { return myPointRedirect; }
274  /// @}
275 
276  /// @{
277  /// Whether to perform threaded merging of attributes
278  /// Default: true
279  bool mergeThreaded() const { return myMergeThreaded; }
280  void setMergeThreaded(bool v) { myMergeThreaded = v; }
281  /// @}
282 
283  /// @{
284  /// When merging a range of primitives, check whether to merge @b all
285  /// points (or just the referenced points).
286  /// Default: false
287  bool mergeAllPoints() const { return myMergeAllPoints; }
288  void setMergeAllPoints(bool v) { myMergeAllPoints = v; }
289  /// @}
290 
291  /// @{
292  /// Whether to insert points at the head when merging.
293  /// Default: false
294  bool mergePointsAtHead() const { return myMergePointsAtHead; }
295  void setMergePointsAtHead(bool v) { myMergePointsAtHead = v; }
296  /// @}
297 
298  /// @{
299  /// Whether to insert primitives at the head when merging.
300  /// Default: false
301  bool mergePrimitivesAtHead() const { return myMergePrimitivesAtHead;}
302  void setMergePrimitivesAtHead(bool v) { myMergePrimitivesAtHead=v; }
303  /// @}
304 
305  /// @{
306  /// Merge the input detail multiple times.
307  GA_Size mergeCount() const { return myMergeCount; }
308  void setMergeCount(GA_Size nmerges)
309  {
310  myMergeCount = SYSmax(1, nmerges);
311  if (myMergeCount > 1)
312  myForceInterleaved = true;
313  }
314  /// @}
315 
316  /// @{
317  /// Whether the "copy" style of merging should force interleaving instead
318  /// of verbatim copying. This is often useful when merging multiple
319  /// different details.
320  bool forceInterleaved() const { return myForceInterleaved; }
321  void setForceInterleaved(bool v) { myForceInterleaved = v; }
322  /// @}
323 
324  /// @{
325  /// Strategy to use for attribute data ids during the merge, defaulting
326  /// to GA_DATA_ID_BUMP. GA_DATA_ID_CLONE is useful when copying a source
327  /// detail in order to perform a partial update without always blindly
328  /// invalidating any external caches tied to data ids. The data id must
329  /// be manually bumped when an attribute is later modified.
331  { return myAttributeDataIdStrategy; }
333  { myAttributeDataIdStrategy = s; }
334  /// @}
335 
336  /// @{
337  /// Strategy to use for handling point attributes and vertex attributes
338  /// of the same name, defaulting to override a previous point/vertex
339  /// attribute with the requested vertex/point attribute.
341  { return myReuseStrategy; }
343  { myReuseStrategy = reuse; }
344  /// }
345 
346 private:
347  TypeStrategy myTypeStrategy[GA_ATTRIB_OWNER_N + 1];
348  StorageStrategy myStorageStrategy[GA_ATTRIB_OWNER_N + 1];
349  TupleSizeStrategy myTupleSizeStrategy[GA_ATTRIB_OWNER_N + 1];
350  MergeStrategy myMergeStrategy[GA_ATTRIB_OWNER_N + 1];
351 
352  UT_Array<GA_Primitive*> *myPrimitiveMap;
353  GA_Range myPrimitiveRange;
354  GA_GBPointRedirectArray *myPointRedirect;
355  GA_Range myPointRange;
356  GA_Size myMergeCount;
357  GA_DataIdStrategy myAttributeDataIdStrategy;
358  GA_ReuseStrategy myReuseStrategy;
359  bool myGroupMerge[GA_GROUP_N];
360  bool myInternalGroupMerge[GA_GROUP_N];
361  bool myForceInterleaved;
362  bool myMergeThreaded;
363  bool myMergeAllPoints;
364  bool myMergePointsAtHead;
365  bool myMergePrimitivesAtHead;
366 };
367 
368 #endif
#define SYSmax(a, b)
Definition: SYS_Math.h:1365
void setMergePointsAtHead(bool v)
Only process exact matches on types.
UT_Array< GA_Primitive * > * getPrimitiveMap() const
Specify when and how to reuse an existing attribute.
GLenum GLint * range
Definition: glcorearb.h:1924
Disallow mis-matched storage.
GA_DataIdStrategy
Definition: GA_Types.h:186
void setMergeThreaded(bool v)
const GLdouble * v
Definition: glcorearb.h:836
const GA_Range * getSourcePrimitiveRange() const
void setMergeAllPoints(bool v)
void setSourcePointRange(const GA_Range &range)
void setMergePrimitivesAtHead(bool v)
#define GA_API
Definition: GA_API.h:12
void setMergeCount(GA_Size nmerges)
GA_DataIdStrategy getAttributeDataIdStrategy() const
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
Keep destination storage (casting source)
Use storage with greatest precision.
A range of elements in an index-map.
Definition: GA_Range.h:42
Change destination attribute to match source.
Class used to create a map of source points during merging.
void setReuseStrategy(const GA_ReuseStrategy &reuse)
}
const GA_ReuseStrategy & getReuseStrategy() const
Use the largest tuple size.
bool getMergeGroups(GA_GroupType type) const
bool mergePointsAtHead() const
GA_GBPointRedirectArray * getPointRedirect() const
bool mergeAllPoints() const
void setSourcePrimitiveRange(const GA_Range &range)
void setForceInterleaved(bool v)
#define IMPL_ENUM(TYPE, DEF)
const GA_Range * getSourceRange(GA_AttributeOwner owner)
const GA_Range * getSourcePointRange() const
const GA_RangeTypeInterface * getRTI() const
Accessor for RTI.
Definition: GA_Range.h:286
Use the destination tuple size.
bool mergeThreaded() const
bool mergePrimitivesAtHead() const
void setAttributeDataIdStrategy(GA_DataIdStrategy s)
GA_AttributeOwner
Definition: GA_Types.h:33
void setMergeGroups(GA_GroupType type, bool state)
bool forceInterleaved() const
void setMergeInternalGroups(GA_GroupType type, bool state)
GA_GroupType
An ordinal enum for the different types of groups in GA.
Definition: GA_Types.h:138
Disallow mis-matched tuple sizes.
Change destination to match source.
Keep destination unchanged if possible.
Change destination to match storage.
Provide options when performing a merge operation.
GLint GLint GLsizei GLint GLenum GLenum type
Definition: glcorearb.h:107
Container class for all geometry.
Definition: GA_Detail.h:96
bool getMergeInternalGroups(GA_GroupType type) const
void setAllMergeInternalGroups(bool state)
GA_Size mergeCount() const
void setAllMergeGroups(bool state)