HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
GT_PrimSubdivisionMesh.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: GT_PrimSubdivisionMesh.h ( GT Library, C++)
7  *
8  * COMMENTS:
9  */
10 
11 #ifndef __GT_PrimSubdivisionMesh__
12 #define __GT_PrimSubdivisionMesh__
13 
14 #include "GT_API.h"
15 #include "GT_PrimPolygonMesh.h"
16 #include <UT/UT_Array.h>
17 
18 /// A subdivision mesh primitive
19 ///
20 /// Subdivision meshes can have a list of arbitrary tags. Each tag can have
21 /// integer, real or string values. Tags that are used in refinement:
22 /// - int crease[]@n
23 /// A list of pairs of vertices defining edges
24 /// - real crease[]@n
25 /// The crease weights for each edge
26 /// - int corner[]@n
27 /// A list of corner vertices
28 /// - real corner[]@n
29 /// The crease weights for corner
30 /// - int interpolateboundary@n
31 /// Deprecated: Determines how point attributes are interpolated
32 /// - int facevaryinginterpolateboundary@n
33 /// Deprecated: Determines how vertex attributes are interpolated
34 /// - int osd_vtxboundaryinterpolation @n
35 /// Determines how point attributes are interpolated (values match the enum
36 /// in OpenSubdiv.
37 /// - int osd_fvarlinearinterpolation @n
38 /// Determines how vertex attributes are interpolated (values match the enum
39 /// in OpenSubdiv.
40 /// - int osd_creasingmethod @n
41 /// Determines the creasing rule (values match the enum in OpenSubdiv)
42 /// - int osd_trianglesubdivision @n
43 /// Determines triangle subdivision smoothing for Catmull-Clark subdivision
44 /// (values match the enum in OpenSubdiv)
46 {
47 public:
50  , myTags()
51  , myScheme(GT_CATMULL_CLARK)
52  {
53  }
54 
56  const GT_DataArrayHandle &vtx_indices,
57  const GT_AttributeListHandle &shared,
59  const GT_AttributeListHandle &uniform,
60  const GT_AttributeListHandle &detail,
62  GT_Size min_vertex_count=0,
63  GT_Size max_vertex_count=0)
64  : GT_PrimPolygonMesh(vtx_counts, vtx_indices,
65  shared, vertex, uniform, detail, indexing,
66  min_vertex_count, max_vertex_count)
67  , myTags()
68  , myScheme(GT_CATMULL_CLARK)
69  {
70  }
72  const GT_DataArrayHandle &vtx_indices,
73  const GT_AttributeListHandle &shared,
75  const GT_AttributeListHandle &uniform,
76  const GT_AttributeListHandle &detail)
77  : GT_PrimPolygonMesh(vtx_counts, vtx_indices,
78  shared, vertex, uniform, detail)
79  , myTags()
80  , myScheme(GT_CATMULL_CLARK)
81  {
82  }
83 
85  const GT_AttributeListHandle &shared,
87  const GT_AttributeListHandle &uniform,
88  const GT_AttributeListHandle &detail)
89  : GT_PrimPolygonMesh(mesh, shared, vertex, uniform, detail)
90  , myTags(mesh.myTags)
91  , myScheme(mesh.myScheme)
92  {
93  }
95  const GT_DataArrayHandle &vtx_index,
96  const GT_AttributeListHandle &shared)
97  : GT_PrimPolygonMesh(mesh, vtx_index, shared)
98  , myTags(mesh.myTags)
99  , myScheme(mesh.myScheme)
100  {
101  }
103  : GT_PrimPolygonMesh(mesh)
104  , myTags(mesh.myTags)
105  , myScheme(mesh.myScheme)
106  {
107  }
108  /// Construct from a GT_PrimPolygonMesh
110  : GT_PrimPolygonMesh(mesh)
111  , myTags()
112  , myScheme(scheme)
113  {
114  }
115 
116  /// Given a data array of either a string or integer value, look-up the
117  /// corresponding scheme. This can be used to interpret the "osd_scheme"
118  /// attribute.
119  static GT_Scheme lookupScheme(const GT_DataArrayHandle &scheme,
120  GT_Scheme defscheme = GT_CATMULL_CLARK);
121 
122  const char *className() const override
123  { return "GT_PrimSubdivisionMesh"; }
124  bool save(UT_JSONWriter &w) const override;
125  int getPrimitiveType() const override;
126  bool refine(GT_Refine &refiner,
127  const GT_RefineParms *parms) const override;
128  int64 getMemoryUsage() const override;
129 
130  void overrideAttributes(
131  const GT_AttributeListHandle &pt_attribs,
132  const GT_AttributeListHandle &vtx_attribs);
133  void clearOverrideAttributes();
134 
136  const UT_StringRef &P = GA_Names::P,
137  bool normalize = true) const;
138 
139  /// Subdivision tag
140  class GT_API Tag
141  {
142  public:
143  Tag()
144  : myName()
145  , myInt()
146  , myReal()
147  , myString()
148  {
149  }
150  Tag(const char *name)
151  : myName(name, true)
152  , myInt()
153  , myReal()
154  , myString()
155  {
156  }
157  Tag(const Tag &src)
158  : myName(src.myName, true)
159  , myInt(src.myInt)
160  , myReal(src.myReal)
161  , myString(src.myString)
162  {
163  }
164  Tag &operator=(const Tag &src)
165  {
166  if (this != &src)
167  {
168  myName.harden(src.myName);
169  myInt = src.myInt;
170  myReal = src.myReal;
171  myString = src.myString;
172  }
173  return *this;
174  }
175 
176  bool match(const char *name) const { return myName == name; }
177  bool valid() const { return myName.isstring(); }
179  {
180  int64 mem = sizeof(*this) + myName.getMemoryUsage();
181  for (exint i = 0; i < myInt.entries(); ++i)
182  mem += myInt(i)->getMemoryUsage();
183  for (exint i = 0; i < myReal.entries(); ++i)
184  mem += myReal(i)->getMemoryUsage();
185  for (exint i = 0; i < myString.entries(); ++i)
186  mem += myString(i)->getMemoryUsage();
187  return mem;
188  }
189 
190  void clear()
191  {
192  myInt.setCapacity(0);
193  myReal.setCapacity(0);
194  myString.setCapacity(0);
195  }
196  const char *name() const { return myName; }
197  exint intCount() const { return myInt.entries(); }
198  exint realCount() const { return myReal.entries(); }
199  exint stringCount() const { return myString.entries(); }
200 
202  { return myInt(i); }
204  { return myReal(i); }
206  { return myString(i); }
207 
208  void harden();
209 
211  { myInt.append(data); }
213  { myReal.append(data); }
215  { myString.append(data); }
216 
218  &getAllInt() const { return myInt; }
220  &getAllReal() const { return myReal; }
222  &getAllString() const { return myString; }
223 
224  private:
225  UT_String myName;
226  UT_Array<GT_DataArrayHandle> myInt; // Integer arrays
227  UT_Array<GT_DataArrayHandle> myReal; // Float arrays
228  UT_Array<GT_DataArrayHandle> myString; // String arrays
229  };
230 
232  {
233  public:
235  : myCurr(0)
236  , myTags(NULL)
237  {
238  }
240  : myCurr(s.myCurr)
241  , myTags(s.myTags)
242  {
243  }
244  bool operator==(const tag_iterator &tag) const
245  {
246  if (atEnd() && tag.atEnd())
247  return true;
248  if (atEnd() || tag.atEnd())
249  return false;
250  return myTags == tag.myTags && myCurr == tag.myCurr;
251  }
252  tag_iterator &operator++() { advance(); return *this; }
254  {
255  myCurr = src.myCurr;
256  myTags = src.myTags;
257  return *this;
258  }
260  { return (*myTags)(myCurr); }
262  { return tag(); }
263  int index() const { return myCurr; }
264 
265  bool atEnd() const
266  {
267  return !myTags || myCurr >= myTags->entries();
268  }
269  void advance() { myCurr++; }
270  void rewind() { myCurr = 0; }
271  private:
273  : myTags(&tags)
274  , myCurr(0)
275  {
276  }
278  int myCurr;
280  };
281 
282  /// Return a polygon mesh of the subdivision hull
284 
285  /// @{
286  /// get/set the subdivision scheme
287  GT_Scheme scheme() const { return myScheme; }
288  void setScheme(GT_Scheme s) { myScheme = s; }
289  /// @}
290 
291  /// @{
292  /// Add tags. If the @c replace tag is true, any existing tag will be
293  /// removed before the tag is added.
294  void appendTag(const Tag &src);
295  void appendIntTag(const char *name, const GT_DataArrayHandle &v,
296  bool replace=false);
297  void appendRealTag(const char *name, const GT_DataArrayHandle &v,
298  bool replace=false);
299  void appendStringTag(const char *name, const GT_DataArrayHandle &v,
300  bool replace=false);
301  /// @}
302  /// Find a tag by name
303  const Tag *findTag(const char *name) const
304  {
305  for (int i = 0; i < myTags.entries(); ++i)
306  {
307  if (myTags(i).match(name))
308  return &myTags(i);
309  }
310  return NULL;
311  }
312  /// Delete a tag
313  bool delTag(const char *name)
314  {
315  for (int i = 0; i < myTags.entries(); ++i)
316  {
317  if (myTags(i).match(name))
318  {
319  myTags.removeIndex(i);
320  return true;
321  }
322  }
323  return false;
324  }
325  /// Clear all tags
326  void clearTags()
327  {
328  myTags.setCapacity(0);
329  }
330 
331  /// @{
332  /// Tag iteration
333  tag_iterator beginTags() const { return tag_iterator(myTags); }
334  tag_iterator endTag() const { return tag_iterator(); }
335  /// @}
336 
337  /// Triangulate (for Loop subdivision)
339 
340 
341  /// Harden all attributes so there are no dangling dependencies
342  GT_PrimitiveHandle doHarden() const override;
344  { return new GT_PrimSubdivisionMesh(*this); }
345 
346  /// The virtual implementation of attribute merging
348  const UT_StringMMPattern *vertex,
349  const UT_StringMMPattern *point,
350  const UT_StringMMPattern *uniform,
351  const UT_StringMMPattern *detail
352  ) const override;
353 protected:
355  {
356  smesh->myTags = myTags;
357  smesh->myScheme = myScheme;
358  return smesh;
359  }
361  const GT_DataArrayHandle &vtx_indices,
362  const GT_AttributeListHandle &shared,
364  const GT_AttributeListHandle &uniform,
365  const GT_AttributeListHandle &detail,
367  GT_Size min_vertex_count=0,
368  GT_Size max_vertex_count=0) const override
369  {
370  auto smesh = new GT_PrimSubdivisionMesh(vtx_counts, vtx_indices,
371  shared, vertex, uniform, detail, indexing,
372  min_vertex_count, max_vertex_count);
373  return copySubd(smesh);
374  }
376  const GT_DataArrayHandle &vtx_indices,
377  const GT_AttributeListHandle &shared,
379  const GT_AttributeListHandle &uniform,
380  const GT_AttributeListHandle &detail) const override
381  {
382  auto smesh = new GT_PrimSubdivisionMesh(vtx_counts, vtx_indices,
383  shared, vertex, uniform, detail);
384  return copySubd(smesh);
385  }
388  const GT_AttributeListHandle &uniform,
389  const GT_AttributeListHandle &detail) const override
390  {
391  return new GT_PrimSubdivisionMesh(*this, shared, vertex, uniform, detail);
392  }
394  const GT_AttributeListHandle &shared) const override
395  {
396  return new GT_PrimSubdivisionMesh(*this, vtx_indices, shared);
397  }
398 
399 private:
400  void hardenTags();
401  Tag *findOrCreateTag(const char *name, bool replace)
402  {
403  for (int i = 0; i < myTags.entries(); ++i)
404  {
405  if (myTags(i).match(name))
406  {
407  if (replace)
408  myTags(i).clear();
409  return &myTags(i);
410  }
411  }
412  myTags.append(Tag(name));
413  return &myTags(myTags.entries()-1);
414  }
415 
416  UT_Array<Tag> myTags;
417  GT_Scheme myScheme;
418  GT_AttributeListHandle myStashedPoint;
419  GT_AttributeListHandle myStashedVertex;
420 };
421 
422 #endif
423 
tag_iterator endTag() const
SIM_API const UT_StringHolder vertex
A mesh of polygons.
const Tag * findTag(const char *name) const
GT_PrimitiveHandle triangulate() const
Triangulate (for Loop subdivision)
const GLdouble * v
Definition: glcorearb.h:837
void appendString(const GT_DataArrayHandle &data)
void appendRealTag(const char *name, const GT_DataArrayHandle &v, bool replace=false)
const UT_Array< GT_DataArrayHandle > & getAllReal() const
GT_IndexingMode
Definition: GT_Types.h:106
void appendStringTag(const char *name, const GT_DataArrayHandle &v, bool replace=false)
#define GT_API
Definition: GT_API.h:13
int64 exint
Definition: SYS_Types.h:125
bool delTag(const char *name)
Delete a tag.
GT_PrimSubdivisionMesh(const GT_PrimSubdivisionMesh &mesh, const GT_DataArrayHandle &vtx_index, const GT_AttributeListHandle &shared)
GLdouble s
Definition: glad.h:3009
Class which writes ASCII or binary JSON streams.
Definition: UT_JSONWriter.h:37
GA_API const UT_StringHolder P
tag_iterator beginTags() const
GT_PrimitiveHandle doSoftCopy() const override
bool operator==(const tag_iterator &tag) const
GT_PrimPolygonMesh * clone(const GT_DataArrayHandle &vtx_counts, const GT_DataArrayHandle &vtx_indices, const GT_AttributeListHandle &shared, const GT_AttributeListHandle &vertex, const GT_AttributeListHandle &uniform, const GT_AttributeListHandle &detail, GT_IndexingMode indexing=GT_INDEXING_QUICK, GT_Size min_vertex_count=0, GT_Size max_vertex_count=0) const override
int64 getMemoryUsage() const override
void appendTag(const Tag &src)
GT_PrimPolygonMesh * clone(const GT_DataArrayHandle &vtx_indices, const GT_AttributeListHandle &shared) const override
GT_PrimSubdivisionMesh(const GT_PrimSubdivisionMesh &mesh, const GT_AttributeListHandle &shared, const GT_AttributeListHandle &vertex, const GT_AttributeListHandle &uniform, const GT_AttributeListHandle &detail)
GT_Scheme
Subdivision schemes.
Definition: GT_Types.h:81
GT_PrimitiveHandle doAttributeMerge(const GT_Primitive &src, const UT_StringMMPattern *vertex, const UT_StringMMPattern *point, const UT_StringMMPattern *uniform, const UT_StringMMPattern *detail) const override
The virtual implementation of attribute merging.
GT_PrimPolygonMesh * createPointNormalsIfMissing(const UT_StringRef &P=GA_Names::P, bool normalize=true, bool *error=nullptr) const
Create point normals on a new mesh if no normals are found. If no point or vertex normals are found...
std::string OIIO_UTIL_API replace(string_view str, string_view pattern, string_view replacement, bool global=false)
const GT_DataArrayHandle & realArray(exint i=0) const
void clearTags()
Clear all tags.
void appendInt(const GT_DataArrayHandle &data)
GT_PrimSubdivisionMesh(const GT_PrimSubdivisionMesh &mesh)
const char * className() const override
long long int64
Definition: SYS_Types.h:116
const GT_PrimSubdivisionMesh::Tag & operator*() const
GT_PrimSubdivisionMesh(const GT_PrimPolygonMesh &mesh, GT_Scheme scheme)
Construct from a GT_PrimPolygonMesh.
GLuint const GLchar * name
Definition: glcorearb.h:786
const UT_Array< GT_DataArrayHandle > & getAllInt() const
The base class for all GT primitive types.
Definition: GT_Primitive.h:43
void appendIntTag(const char *name, const GT_DataArrayHandle &v, bool replace=false)
int getPrimitiveType() const override
Processes primitives generated by refinement process.
Definition: GT_Refine.h:20
GT_PrimitiveHandle refineToHull() const
Return a polygon mesh of the subdivision hull.
bool refine(GT_Refine &refiner, const GT_RefineParms *parms) const override
GT_PrimPolygonMesh * clone(const GT_AttributeListHandle &shared, const GT_AttributeListHandle &vertex, const GT_AttributeListHandle &uniform, const GT_AttributeListHandle &detail) const override
int64 GT_Size
Definition: GT_Types.h:128
bool match(const char *name) const
GT_PrimitiveHandle doHarden() const override
Harden all attributes so there are no dangling dependencies.
const UT_Array< GT_DataArrayHandle > & getAllString() const
GT_PrimSubdivisionMesh * copySubd(GT_PrimSubdivisionMesh *smesh) const
const GT_DataArrayHandle & intArray(exint i=0) const
GLubyte GLubyte GLubyte GLubyte w
Definition: glcorearb.h:857
const GT_DataArrayHandle & stringArray(exint i=0) const
const GT_PrimSubdivisionMesh::Tag & tag() const
bool save(UT_JSONWriter &w) const override
GT_PrimSubdivisionMesh(const GT_DataArrayHandle &vtx_counts, const GT_DataArrayHandle &vtx_indices, const GT_AttributeListHandle &shared, const GT_AttributeListHandle &vertex, const GT_AttributeListHandle &uniform, const GT_AttributeListHandle &detail, GT_IndexingMode indexing=GT_INDEXING_QUICK, GT_Size min_vertex_count=0, GT_Size max_vertex_count=0)
tag_iterator & operator=(const tag_iterator &src)
void appendReal(const GT_DataArrayHandle &data)
Definition: format.h:895
GT_PrimSubdivisionMesh(const GT_CountArray &vtx_counts, const GT_DataArrayHandle &vtx_indices, const GT_AttributeListHandle &shared, const GT_AttributeListHandle &vertex, const GT_AttributeListHandle &uniform, const GT_AttributeListHandle &detail)
constexpr T normalize(UT_FixedVector< T, D > &a) noexcept
GT_PrimPolygonMesh * clone(const GT_CountArray &vtx_counts, const GT_DataArrayHandle &vtx_indices, const GT_AttributeListHandle &shared, const GT_AttributeListHandle &vertex, const GT_AttributeListHandle &uniform, const GT_AttributeListHandle &detail) const override
GLenum src
Definition: glcorearb.h:1793