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  /// Evaluate the limit surface for a given point/vertex attribute at the
291  /// coordinates specified. The @c face_indices array should have @c npts
292  /// entries. The @c uvs array should have @c uv_stride*npts entries. Only
293  /// the first 2 coordinates will be used (and represent the s/t coordinates
294  /// of the face).
295  GT_DataArrayHandle limitSurface(const char *attrib, bool vertex_attrib,
296  exint npts,
297  const int32 *face_indices,
298  const fpreal32 *u,
299  const fpreal32 *v,
300  int uv_stride = 1) const;
301 
302  /// @{
303  /// Evaluate the limit surface for a given point/vertex attribute at the
304  /// coordinates specified. The @c face_indices array should have @c npts
305  /// entries. The @c uvs array should have @c uv_stride*npts entries. Only
306  /// the first 2 coordinates will be used (and represent the s/t coordinates
307  /// of the face).
308  /// The data handles determine which properties are returned:
309  /// @c result - Attribute
310  /// @c result_du - Derivative of attribute in 'u'
311  /// @c result_dv - Derivative of attribute in 'v'
312  /// Passing 'NULL' for a handle disables evaluation of that property.
313  /// The size of the evaluated attribute is returned.
314  int limitSurface(GT_DataArrayHandle *result,
315  GT_DataArrayHandle *result_du,
316  GT_DataArrayHandle *result_dv,
317  const AttribId &attrib,
318  exint npts,
319  const int32 *face_indices,
320  const fpreal32 *u,
321  const fpreal32 *v,
322  int uv_stride = 1) const;
323  int limitSurface(GT_DataArrayHandle *result,
324  GT_DataArrayHandle *result_du,
325  GT_DataArrayHandle *result_dv,
326  const char *attrib, bool vertex_attrib,
327  exint npts,
328  const int32 *face_indices,
329  const fpreal32 *u,
330  const fpreal32 *v,
331  int uv_stride = 1) const;
332  /// @}
333 
334  /// Create the OSD data structures to represent a particular subdivision
335  /// mesh. The suppolied handle must refer to a GT_PrimSubdivisionMesh or
336  /// the functions will fail. This function can be called once followed
337  /// by ay number of calls to refine and/or extractSubdivisionMesh.
338  bool createTopology(const GT_PrimitiveHandle &mesh);
339 
340  /// Copies attribute data from the supplied mesh into the OSD data
341  /// structure, and performs the refinement. The topology of the supplied
342  /// mesh must match that of the mesh passed to the createTopology
343  /// function, which must be called before this one.
344  bool refine(const GT_PrimitiveHandle &mesh,
345  bool force_update = false);
346 
347  /// Returns a GT_PrimPolygonMesh that is the result of subdividing the
348  /// mesh passed to the refine function above.
349  GT_PrimitiveHandle extractSubdividedMesh(int level=-1);
350 
351 #if 0
352  /// Returns a GT_OSDDrawContext that can be used for adaptive rendering
353  /// of the subdivision surface in the viewport.
354  const GT_OSDDrawContext *getDrawContext();
355 
356  /// Build patches for render-controlled subdivision. The raw float
357  /// arrays provided by GT_OSDVertex will be ordered according to the
358  /// ptattribs and vtxattribs order.
359  void buildPatches(UT_Array<GT_OSDPatchHandle> &patches,
360  Scheme scheme,
361  const GU_Detail &gdp,
362  const GU_SubDivPacking &ptattribs,
363  const GU_SubDivPacking &vtxattribs,
364  GA_Range *range=NULL);
365 #endif
366 
367  /// @{
368  /// Error handling (used internally)
369  void addError(const char *msg) { myErrors.append(msg); }
370  void clearErrors() { myErrors.clear(); }
371  /// @}
372 
373 private:
374  bool updateGeo(GU_Detail &gdp, GA_Range *range,
375  const GT_PrimitiveHandle &prim) const;
376 
377  GT_PrimitiveHandle getHull(const GT_PrimitiveHandle &prim,
378  bool triangulate_loop = true) const;
379 
380  UT_StringArray myErrors;
381  GT_OSDOptions myOptions;
382  GT_OSDPatchTableOptions myLimitOptions;
383  GT_OSDPatchTable myPatches;
384  UT_UniquePtr<GT_OSDTopology> myTopology;
385  UT_UniquePtr<GT_OSDAttributes> myAttributes;
387  GT_TransformHandle myPrimitiveTransform;
388  bool myPolySoup;
389 };
390 
391 #endif
VtxBoundaryInterpolation vtxBoundaryInterpolation() const
GT_OSDOptions::SdcOptions SdcOptions
bool polySoup() const
OpenSubdiv::Sdc::Options SdcOptions
Definition: GT_OSD3.h:40
GLenum GLint * range
Definition: glcorearb.h:1924
const GLdouble * v
Definition: glcorearb.h:836
std::pair< int, bool > AttribId
Definition: GT_OSD3.h:345
#define GT_API
Definition: GT_API.h:11
GLint level
Definition: glcorearb.h:107
const GT_OSDOptions & options() const
void addError(const char *msg)
Class which writes ASCII or binary JSON streams.
Definition: UT_JSONWriter.h:32
Options for setting up limit surface evaluation.
Definition: GT_OSD3.h:121
A range of elements in an index-map.
Definition: GA_Range.h:42
void setCreaseOverride(bool yes, fpreal w)
fpreal creaseOverride() const
GT_OSDPatchTableOptions & limitOptions()
GT_Scheme
Subdivision schemes.
Definition: GT_Types.h:68
bool doCreaseOverride() const
int64 exint
Definition: SYS_Types.h:116
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
GT_Scheme scheme() const
GLuint const GLchar * name
Definition: glcorearb.h:785
int int32
Definition: SYS_Types.h:35
GT_OSDAttributes::AttribId AttribId
double fpreal
Definition: SYS_Types.h:270
void setScheme(GT_Scheme s)
const UT_StringArray & errors() const
bool removeHoles() const
void setCreasingMethod(SdcOptions::CreasingMethod v)
SdcOptions::FVarLinearInterpolation FVarLinearInterpolation
const GT_OSDPatchTableOptions & limitOptions() const
void setOptions(const GT_OSDOptions &options)
GLubyte GLubyte GLubyte GLubyte w
Definition: glcorearb.h:856
void setTriangleSubdivision(SdcOptions::TriangleSubdivision v)
bool adaptive() const
Topology definition for opensubdiv classes.
Definition: GT_OSD3.h:181
int64 GT_Size
Definition: GT_Types.h:112
void setFVarLinearInterpolation(FVarLinearInterpolation v)
float fpreal32
Definition: SYS_Types.h:191
void setRemoveHoles(bool v)
void setCreaseOverride(fpreal w)
Class to perform subdivision refinement using OpenSubdivision.
unsigned int uint32
Definition: SYS_Types.h:36
void setPolySoup(bool v)
Options for topology and refinement.
Definition: GT_OSD3.h:37