HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
GT_UtilOpenSubdiv.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_UtilOpenSubdiv.h (GT Library, C++)
7  *
8  * COMMENTS:
9  */
10 
11 #ifndef __GT_UtilOpenSubdiv__
12 #define __GT_UtilOpenSubdiv__
13 
14 #include "GT_API.h"
15 #include <UT/UT_UniquePtr.h>
16 #include <UT/UT_StringArray.h>
17 #include <GU/GU_SubDivPacking.h>
18 #include "GT_Types.h"
19 #include "GT_Handles.h"
20 #include "GT_OSD3.h"
21 
22 class GU_Detail;
23 class GA_Range;
24 
25 #if 0
26 class GT_API GT_OSDDrawContext
27 {
28 public:
29  GT_OSDDrawContext(const Far::PatchTable &patchTables,
31  const GT_OSDSubdivider<OsdVertex> &subdivider);
32  ~GT_OSDDrawContext();
33 
34  class PatchArrayDescriptor
35  {
36  public:
37  bool operator<(const PatchArrayDescriptor &other) const
38  {
39  if (myMaxValence == other.myMaxValence)
40  {
41  if (myType == other.myType)
42  {
43  if (myPattern == other.myPattern)
44  {
45  if (myRotation == other.myRotation)
46  {
47  if (mySubPatch == other.mySubPatch)
48  {
49  return false;
50  }
51 
52  return mySubPatch < other.mySubPatch;
53  }
54 
55  return myRotation < other.myRotation;
56  }
57 
58  return myPattern < other.myPattern;
59  }
60 
61  return myType < other.myType;
62  }
63 
64  return myMaxValence < other.myMaxValence;
65  }
66 
67  int myMaxValence;
68  int myType;
69  int myPattern;
70  int myRotation;
71  int mySubPatch;
72  };
73 
74  class PatchArray
75  {
76  public:
77  PatchArrayDescriptor myDescriptor;
78  int myPatchSize;
79  int myPatchCount;
80  exint myVertexOffset;
81  exint myQuadOffsetBase;
82  exint myPrimitiveIdBase;
83  };
84 
85  GT_AttributeListHandle myPointAttribs;
86  GT_AttributeListHandle myVertexAttribs;
87  const uint32 *myPatchTable;
88  exint myPatchCount;
89  const int32 *myValenceTable;
90  exint myValenceCount;
91  const uint32 *myQuadOffsetTable;
92  exint myQuadOffsetCount;
93  const FarPatchParam *myPatchParamTable;
94  exint myPatchParamCount;
95  UT_Array<PatchArray> myPatchArrays;
96  int myMaxValence;
97  int myPrimitiveMultiplier;
98 };
99 #endif
100 
101 /// Class to perform subdivision refinement using OpenSubdivision
103 {
104 public:
107 
109  using VtxBoundaryInterpolation = SdcOptions::VtxBoundaryInterpolation;
110  using FVarLinearInterpolation = SdcOptions::FVarLinearInterpolation;
112 
113  void dump() const;
114  void dump(UT_JSONWriter &w) const;
115 
116  /// @{
117  /// Option accessors
118  const GT_OSDOptions &options() const { return myOptions; }
119  void setOptions(const GT_OSDOptions &options)
120  {
121  clear();
122  myOptions = options;
123  }
124 
125  GT_Scheme scheme() const { return myOptions.scheme(); }
127  {
128  clear();
129  myOptions.setScheme(s);
130  }
131 
132  int levels() const { return myOptions.level(); }
133  void setLevels(int l)
134  {
135  clear();
136  myOptions.setLevel(l);
137  }
138  bool adaptive() const { return myOptions.adaptive(); }
139  void setAdaptive(bool v)
140  {
141  clear();
142  myOptions.setAdaptive(v);
143  }
144  bool removeHoles() const { return myOptions.removeHoles(); }
145  void setRemoveHoles(bool v)
146  {
147  clear();
148  myOptions.setRemoveHoles(v);
149  }
150 
151  bool doCreaseOverride() const
152  { return myOptions.enableCreaseOverride(); }
154  { return myOptions.creaseOverride(); }
155  void setCreaseOverride(bool yes, fpreal w)
156  { setCreaseOverride(yes ? w : -1); }
158  {
159  clear();
160  myOptions.setCreaseOverride(w);
161  }
162 
163  bool polySoup() const { return myPolySoup; }
164  void setPolySoup(bool v) { myPolySoup = v; }
165 
167  { return myOptions.vtxBoundaryInterpolation(); }
169  { return myOptions.fvarLinearInterpolation(); }
171  {
172  clear();
173  myOptions.setVtxBoundaryInterpolation(v);
174  }
176  {
177  clear();
178  myOptions.setFVarLinearInterpolation(v);
179  }
180  void setCreasingMethod(SdcOptions::CreasingMethod v)
181  {
182  clear();
183  myOptions.setCreasingMethod(v);
184  }
185  void setTriangleSubdivision(SdcOptions::TriangleSubdivision v)
186  {
187  clear();
188  myOptions.setTriangleSubdivision(v);
189  }
190  /// @}
191 
192  /// @{
193  /// Accessors for the limit surface evaluation options
195  { return myLimitOptions; }
197  { return myLimitOptions; }
198  /// @}
199 
200  /// Clear any topology, attributes or limit surface info
201  void clear();
202 
203  const UT_StringArray &errors() const { return myErrors; }
204  /// @}
205 
206  /// Refine the mesh to the given number of levels using a given subdivision
207  /// scheme. If the primitive is a subdivision mesh, the crease tags will
208  /// be used in refinement. If the supplied prim is not a subdivision
209  /// mesh, any required refinements will be performed automatically.
210  ///
211  /// If the method fails, a null pointer will be returned.
212  GT_PrimitiveHandle subdivide(const GT_PrimitiveHandle &mesh);
213 
214  /// Refine Houdini geometry
215  bool subdivide(GU_Detail &gdp, GA_Range *range=NULL);
216 
217  /// Set up mesh for limit surface evaluation. If successful, a subdivision
218  /// surface will be set up for evaluation. You can then do something like
219  /// @code
220  /// for (int i = 0; i < osd.limitCoarseFaceCount(); ++i)
221  /// {
222  /// int first = osd.limitFirstPatch(i);
223  /// int size = osd.limitPatchSize(i);
224  /// UT_ASSERT(first + size <= limit.patchCount());
225  /// for (int j = 0; j < size; ++j)
226  /// {
227  /// int patch_index = first + j;
228  /// float coord = .5;
229  /// // It's considerably more efficient to evaluate these in batch
230  /// osd.limitSurface("P", false, 1, &patch_index, &coord, &coord);
231  /// }
232  /// }
233  /// @endcode
234  bool setupLimitEval(const GT_PrimitiveHandle &mesh);
235 
236  /// Return the number of input faces. A cube would have 6 faces, a
237  /// tetrahedron would have 4 faces.
238  GT_Size limitCoarseFaceCount() const;
239 
240  /// Return the number of individual patches (ptex face ids). So, a cube
241  /// would have 6 patches, while a tetrahedron would have 12 patches (each
242  /// triangle generates 3 patches).
243  GT_Size limitPatchCount() const;
244 
245  /// Return the ptexture id for a given input face. For example, if the
246  /// input mesh is a tetrahedron, @c limitFirstPatch(2) would return 6.
247  /// This is also equivalent to the ptexture index of the first patch for a
248  /// given face.
249  GT_Size limitFirstPatch(GT_Size face_index) const;
250 
251  /// Return the number of subdivision patches for a given input face. For
252  /// example, if the input mesh is a tetrahedron, @c limitPTextureId(2)
253  /// would return 3.
254  GT_Size limitPatchSize(GT_Size face_index) const;
255 
256  /// Definition of an attribute id on the topolgy
257  AttribId limitFindAttribute(const char *name) const;
258 
259  /// Given a face on the coarse mesh and a u,v coordinate from an attribute,
260  /// look up the corresponding patch and interpolant. If the attribute is
261  /// invalid, then the uv's will be assumed to be the patch interpolants,
262  /// with the patch offset added to the u coordinate.
263  bool limitLookupPatch(GT_Size hou_face,
264  fpreal hou_u, fpreal hou_v,
265  GT_Size &osd_face,
266  fpreal &osd_u, fpreal &osd_v,
267  const AttribId &attrib,
268  int seg = 0) const;
269  /// Given a patch on the subdivision mesh and a uv interpolant on the
270  /// patch, return the face on the coarse mesh and possibly the uv
271  /// attributes. If the topology attribute id is invalid, then the u/v
272  /// returned will be the uv interpolants on the patch, with the patch
273  /// offset added to the uv.
274  bool limitLookupFace(GT_Size osd_face,
275  fpreal osd_u, fpreal osd_v,
276  GT_Size &hou_prim,
277  fpreal &hou_u, fpreal &hou_v,
278  const AttribId &attrib,
279  int seg = 0) const;
280 
281  /// Evaluate the limit surface for a given point/vertex attribute at the
282  /// coordinates specified.
283  GT_DataArrayHandle limitSurface(const char *attrib, bool vertex_attrib,
284  const GT_DataArrayHandle &faces,
285  const GT_DataArrayHandle &uvs) const;
286  GT_DataArrayHandle limitSurface(const char *attrib, bool vertex_attrib,
287  const GT_DataArrayHandle &faces,
288  const GT_DataArrayHandle &u,
289  const GT_DataArrayHandle &v) const;
290 
291  /// Evaluate the limit surface for a given point/vertex attribute at the
292  /// coordinates specified with respect to the specified component. The
293  /// component is either the surface point (0), the first partial derivative
294  /// in the u-direction (1), or the first partial derivative in the
295  /// v-direction (2). The @c face_indices array should have @c npts entries.
296  /// The @c uvs array should have @c uv_stride*npts entries. Only the first
297  /// 2 coordinates will be used (and represent the s/t coordinates of the face).
298  GT_DataArrayHandle limitAt(const char *attrib, int component,
299  bool vertex_attrib,
300  exint npts,
301  const int32 *face_indices,
302  const fpreal32 *u,
303  const fpreal32 *v,
304  int uv_stride = 1) const;
305 
306  /// Evaluate the limit surface for a given point/vertex attribute at the
307  /// coordinates specified with respect to the surface, first partial
308  /// derivatives, and second partial derivatives.
309  void limitAll(GT_DataArrayHandle *result,
310  const char *attrib,
311  bool vertex_attrib,
312  exint npts,
313  const int32 *face_indices,
314  const fpreal32 *u,
315  const fpreal32 *v,
316  int uv_stride = 1) const;
317 
318  /// Evaluate the limit surface for a given point/vertex attribute at the
319  /// coordinates specified. The @c face_indices array should have @c npts
320  /// entries. The @c uvs array should have @c uv_stride*npts entries. Only
321  /// the first 2 coordinates will be used (and represent the s/t coordinates
322  /// of the face).
323  GT_DataArrayHandle limitSurface(const char *attrib, bool vertex_attrib,
324  exint npts,
325  const int32 *face_indices,
326  const fpreal32 *u,
327  const fpreal32 *v,
328  int uv_stride = 1) const;
329 
330  /// Evaluate the limit for a given point/vertex attribute at the
331  /// coordinates specified. The @c face_indices array should have @c npts
332  /// entries. The @c uvs array should have @c uv_stride*npts entries. Only
333  /// the first 2 coordinates will be used (and represent the s/t coordinates
334  /// of the face). The option argument specifies whether the resulting
335  /// attribute should be evaluatated with respect to the surface (option = 0),
336  /// the first partial in the u direction (option = 1), or the first partial
337  /// in the v direction (option = 2).
338  void limit(GT_DataArrayHandle &result,
339  const char *attrib,
340  bool vertex_attrib,
341  exint npts,
342  const int32 *face_indices,
343  const fpreal32 *u,
344  const fpreal32 *v,
345  int uv_stride = 1,
346  int option = 0) const;
347 
348  /// Evaluate the limit for a given point/vertex attribute at the
349  /// coordinates specified. The @c face_indices array should have @c npts
350  /// entries. The @c uvs array should have @c uv_stride*npts entries. Only
351  /// the first 2 coordinates will be used (and represent the s/t coordinates
352  /// of the face). The resulting attribute is evaluatated with respect to
353  /// the surface, first partial derivatives, and second partial derivatives.
354  void limit(GT_DataArrayHandle *result,
355  const char *attrib,
356  bool vertex_attrib,
357  exint npts,
358  const int32 *face_indices,
359  const fpreal32 *u,
360  const fpreal32 *v,
361  int uv_stride = 1) const;
362 
363  /// @{
364  /// Evaluate the limit surface for a given point/vertex attribute at the
365  /// coordinates specified. The @c face_indices array should have @c npts
366  /// entries. The @c uvs array should have @c uv_stride*npts entries. Only
367  /// the first 2 coordinates will be used (and represent the s/t coordinates
368  /// of the face).
369  /// The data handles determine which properties are returned:
370  /// @c result - Attribute
371  /// @c result_du - Derivative of attribute in 'u'
372  /// @c result_dv - Derivative of attribute in 'v'
373  /// Passing 'NULL' for a handle disables evaluation of that property.
374  /// The size of the evaluated attribute is returned.
375  int limitSurface(GT_DataArrayHandle *result,
376  GT_DataArrayHandle *result_du,
377  GT_DataArrayHandle *result_dv,
378  const AttribId &attrib,
379  exint npts,
380  const int32 *face_indices,
381  const fpreal32 *u,
382  const fpreal32 *v,
383  int uv_stride = 1) const;
384  int limitSurface(GT_DataArrayHandle *result,
385  GT_DataArrayHandle *result_du,
386  GT_DataArrayHandle *result_dv,
387  const char *attrib, bool vertex_attrib,
388  exint npts,
389  const int32 *face_indices,
390  const fpreal32 *u,
391  const fpreal32 *v,
392  int uv_stride = 1) const;
393  /// @}
394 
395  /// @{
396  /// Evaluate the limit surface for a given point/vertex attribute at the
397  /// coordinates specified. The @c face_indices array should have @c npts
398  /// entries. The @c uvs array should have @c uv_stride*npts entries. Only
399  /// the first 2 coordinates will be used (and represent the s/t coordinates
400  /// of the face).
401  /// All data handles are returned:
402  /// @c result - Attribute
403  /// @c result_du - Derivative of attribute in 'u'
404  /// @c result_dv - Derivative of attribute in 'v'
405  /// @c result_duu - Derivative of attribute in 'uu'
406  /// @c result_duv - Derivative of attribute in 'uv'
407  /// @c result_dvv - Derivative of attribute in 'vv'
408  int limitSurface(GT_DataArrayHandle *result,
409  GT_DataArrayHandle *result_du,
410  GT_DataArrayHandle *result_dv,
411  GT_DataArrayHandle *result_duu,
412  GT_DataArrayHandle *result_duv,
413  GT_DataArrayHandle *result_dvv,
414  const AttribId &attrib,
415  exint npts,
416  const int32 *face_indices,
417  const fpreal32 *u,
418  const fpreal32 *v,
419  int uv_stride = 1) const;
420  int limitSurface(GT_DataArrayHandle *result,
421  GT_DataArrayHandle *result_du,
422  GT_DataArrayHandle *result_dv,
423  GT_DataArrayHandle *result_duu,
424  GT_DataArrayHandle *result_duv,
425  GT_DataArrayHandle *result_dvv,
426  const char *attrib, bool vertex_attrib,
427  exint npts,
428  const int32 *face_indices,
429  const fpreal32 *u,
430  const fpreal32 *v,
431  int uv_stride = 1) const;
432  /// @}
433 
434  /// Create the OSD data structures to represent a particular subdivision
435  /// mesh. The suppolied handle must refer to a GT_PrimSubdivisionMesh or
436  /// the functions will fail. This function can be called once followed
437  /// by ay number of calls to refine and/or extractSubdivisionMesh.
438  bool createTopology(const GT_PrimitiveHandle &mesh);
439 
440  /// Copies attribute data from the supplied mesh into the OSD data
441  /// structure, and performs the refinement. The topology of the supplied
442  /// mesh must match that of the mesh passed to the createTopology
443  /// function, which must be called before this one.
444  bool refine(const GT_PrimitiveHandle &mesh,
445  bool force_update = false);
446 
447  /// Returns a GT_PrimPolygonMesh that is the result of subdividing the
448  /// mesh passed to the refine function above.
449  GT_PrimitiveHandle extractSubdividedMesh(int level=-1);
450 
451 #if 0
452  /// Returns a GT_OSDDrawContext that can be used for adaptive rendering
453  /// of the subdivision surface in the viewport.
454  const GT_OSDDrawContext *getDrawContext();
455 
456  /// Build patches for render-controlled subdivision. The raw float
457  /// arrays provided by GT_OSDVertex will be ordered according to the
458  /// ptattribs and vtxattribs order.
459  void buildPatches(UT_Array<GT_OSDPatchHandle> &patches,
460  Scheme scheme,
461  const GU_Detail &gdp,
462  const GU_SubDivPacking &ptattribs,
463  const GU_SubDivPacking &vtxattribs,
464  GA_Range *range=NULL);
465 #endif
466 
467  /// @{
468  /// Error handling (used internally)
469  void addError(const char *msg) { myErrors.append(msg); }
470  void clearErrors() { myErrors.clear(); }
471  /// @}
472 
473 private:
474  bool updateGeo(GU_Detail &gdp, GA_Range *range,
475  const GT_PrimitiveHandle &prim) const;
476 
477  GT_PrimitiveHandle getHull(const GT_PrimitiveHandle &prim,
478  bool triangulate_loop = true) const;
479 
480  UT_StringArray myErrors;
481  GT_OSDOptions myOptions;
482  GT_OSDPatchTableOptions myLimitOptions;
483  GT_OSDPatchTable myPatches;
484  UT_UniquePtr<GT_OSDTopology> myTopology;
485  UT_UniquePtr<GT_OSDAttributes> myAttributes;
487  GT_TransformHandle myPrimitiveTransform;
488  bool myPolySoup;
489 };
490 
491 #endif
VtxBoundaryInterpolation vtxBoundaryInterpolation() const
GT_OSDOptions::SdcOptions SdcOptions
bool polySoup() const
OpenSubdiv::Sdc::Options SdcOptions
Definition: GT_OSD3.h:42
int int32
Definition: SYS_Types.h:39
GLenum GLint * range
Definition: glcorearb.h:1925
const GLdouble * v
Definition: glcorearb.h:837
std::pair< int, bool > AttribId
Definition: GT_OSD3.h:351
#define GT_API
Definition: GT_API.h:13
int64 exint
Definition: SYS_Types.h:125
GLint level
Definition: glcorearb.h:108
GLdouble s
Definition: glad.h:3009
const GT_OSDOptions & options() const
void addError(const char *msg)
Class which writes ASCII or binary JSON streams.
Definition: UT_JSONWriter.h:37
**But if you need a result
Definition: thread.h:622
float fpreal32
Definition: SYS_Types.h:200
Options for setting up limit surface evaluation.
Definition: GT_OSD3.h:123
A range of elements in an index-map.
Definition: GA_Range.h:42
std::unique_ptr< T, Deleter > UT_UniquePtr
A smart pointer for unique ownership of dynamically allocated objects.
Definition: UT_UniquePtr.h:39
void setCreaseOverride(bool yes, fpreal w)
fpreal creaseOverride() const
GT_OSDPatchTableOptions & limitOptions()
GT_Scheme
Subdivision schemes.
Definition: GT_Types.h:81
bool doCreaseOverride() const
GT_API const UT_StringHolder topology
FVarLinearInterpolation fvarLinearInterpolation() const
void setAdaptive(bool v)
void setVtxBoundaryInterpolation(VtxBoundaryInterpolation v)
bool operator<(const GU_TetrahedronFacet &a, const GU_TetrahedronFacet &b)
SdcOptions::VtxBoundaryInterpolation VtxBoundaryInterpolation
GLuint const GLchar * name
Definition: glcorearb.h:786
GT_Scheme scheme() const
GT_OSDAttributes::AttribId AttribId
int64 GT_Size
Definition: GT_Types.h:128
fpreal64 fpreal
Definition: SYS_Types.h:278
void setScheme(GT_Scheme s)
const UT_StringArray & errors() const
bool removeHoles() const
void setCreasingMethod(SdcOptions::CreasingMethod v)
SdcOptions::FVarLinearInterpolation FVarLinearInterpolation
unsigned int uint32
Definition: SYS_Types.h:40
const GT_OSDPatchTableOptions & limitOptions() const
void setOptions(const GT_OSDOptions &options)
GLubyte GLubyte GLubyte GLubyte w
Definition: glcorearb.h:857
void setTriangleSubdivision(SdcOptions::TriangleSubdivision v)
bool adaptive() const
Topology definition for opensubdiv classes.
Definition: GT_OSD3.h:188
void setFVarLinearInterpolation(FVarLinearInterpolation v)
void setRemoveHoles(bool v)
void setCreaseOverride(fpreal w)
Class to perform subdivision refinement using OpenSubdivision.
void setPolySoup(bool v)
Options for topology and refinement.
Definition: GT_OSD3.h:39