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