HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros 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_SharedPtr.h>
17 #include <UT/UT_StringArray.h>
18 #include <GU/GU_SubDivPacking.h>
19 #include "GT_Types.h"
20 #include "GT_Handles.h"
21 #include "GT_OSD3.h"
22 
23 class GU_Detail;
24 class GA_Range;
25 
26 #if 0
27 class GT_API GT_OSDDrawContext
28 {
29 public:
30  GT_OSDDrawContext(const Far::PatchTable &patchTables,
31  const GT_OSDTopology<OsdVertex> &topology,
32  const GT_OSDSubdivider<OsdVertex> &subdivider);
33  ~GT_OSDDrawContext();
34 
35  class PatchArrayDescriptor
36  {
37  public:
38  bool operator<(const PatchArrayDescriptor &other) const
39  {
40  if (myMaxValence == other.myMaxValence)
41  {
42  if (myType == other.myType)
43  {
44  if (myPattern == other.myPattern)
45  {
46  if (myRotation == other.myRotation)
47  {
48  if (mySubPatch == other.mySubPatch)
49  {
50  return false;
51  }
52 
53  return mySubPatch < other.mySubPatch;
54  }
55 
56  return myRotation < other.myRotation;
57  }
58 
59  return myPattern < other.myPattern;
60  }
61 
62  return myType < other.myType;
63  }
64 
65  return myMaxValence < other.myMaxValence;
66  }
67 
68  int myMaxValence;
69  int myType;
70  int myPattern;
71  int myRotation;
72  int mySubPatch;
73  };
74 
75  class PatchArray
76  {
77  public:
78  PatchArrayDescriptor myDescriptor;
79  int myPatchSize;
80  int myPatchCount;
81  exint myVertexOffset;
82  exint myQuadOffsetBase;
83  exint myPrimitiveIdBase;
84  };
85 
86  GT_AttributeListHandle myPointAttribs;
87  GT_AttributeListHandle myVertexAttribs;
88  const uint32 *myPatchTable;
89  exint myPatchCount;
90  const int32 *myValenceTable;
91  exint myValenceCount;
92  const uint32 *myQuadOffsetTable;
93  exint myQuadOffsetCount;
94  const FarPatchParam *myPatchParamTable;
95  exint myPatchParamCount;
96  UT_Array<PatchArray> myPatchArrays;
97  int myMaxValence;
98  int myPrimitiveMultiplier;
99 };
100 #endif
101 
102 /// Class to perform subdivision refinement using OpenSubdivision
104 {
105 public:
108 
110  using VtxBoundaryInterpolation = SdcOptions::VtxBoundaryInterpolation;
111  using FVarLinearInterpolation = SdcOptions::FVarLinearInterpolation;
113 
114  void dump() const;
115  void dump(UT_JSONWriter &w) const;
116 
117  /// @{
118  /// Option accessors
119  const GT_OSDOptions &options() const { return myOptions; }
120  void setOptions(const GT_OSDOptions &options)
121  {
122  clear();
123  myOptions = options;
124  }
125 
126  GT_Scheme scheme() const { return myOptions.scheme(); }
128  {
129  clear();
130  myOptions.setScheme(s);
131  }
132 
133  int levels() const { return myOptions.level(); }
134  void setLevels(int l)
135  {
136  clear();
137  myOptions.setLevel(l);
138  }
139  bool adaptive() const { return myOptions.adaptive(); }
140  void setAdaptive(bool v)
141  {
142  clear();
143  myOptions.setAdaptive(v);
144  }
145  bool removeHoles() const { return myOptions.removeHoles(); }
146  void setRemoveHoles(bool v)
147  {
148  clear();
149  myOptions.setRemoveHoles(v);
150  }
151 
152  bool doCreaseOverride() const
153  { return myOptions.enableCreaseOverride(); }
155  { return myOptions.creaseOverride(); }
156  void setCreaseOverride(bool yes, fpreal w)
157  { setCreaseOverride(yes ? w : -1); }
159  {
160  clear();
161  myOptions.setCreaseOverride(w);
162  }
163 
164  bool polySoup() const { return myPolySoup; }
165  void setPolySoup(bool v) { myPolySoup = v; }
166 
168  { return myOptions.vtxBoundaryInterpolation(); }
170  { return myOptions.fvarLinearInterpolation(); }
172  {
173  clear();
174  myOptions.setVtxBoundaryInterpolation(v);
175  }
177  {
178  clear();
179  myOptions.setFVarLinearInterpolation(v);
180  }
181  void setCreasingMethod(SdcOptions::CreasingMethod v)
182  {
183  clear();
184  myOptions.setCreasingMethod(v);
185  }
186  void setTriangleSubdivision(SdcOptions::TriangleSubdivision v)
187  {
188  clear();
189  myOptions.setTriangleSubdivision(v);
190  }
191  /// @}
192 
193  /// @{
194  /// Accessors for the limit surface evaluation options
196  { return myLimitOptions; }
198  { return myLimitOptions; }
199  /// @}
200 
201  /// Clear any topology, attributes or limit surface info
202  void clear();
203 
204  const UT_StringArray &errors() const { return myErrors; }
205  /// @}
206 
207  /// Refine the mesh to the given number of levels using a given subdivision
208  /// scheme. If the primitive is a subdivision mesh, the crease tags will
209  /// be used in refinement. If the supplied prim is not a subdivision
210  /// mesh, any required refinements will be performed automatically.
211  ///
212  /// If the method fails, a null pointer will be returned.
213  GT_PrimitiveHandle subdivide(const GT_PrimitiveHandle &mesh);
214 
215  /// Refine Houdini geometry
216  bool subdivide(GU_Detail &gdp, GA_Range *range=NULL);
217 
218  /// Set up mesh for limit surface evaluation. If successful, a subdivision
219  /// surface will be set up for evaluation. You can then do something like
220  /// @code
221  /// for (int i = 0; i < osd.limitCoarseFaceCount(); ++i)
222  /// {
223  /// int first = osd.limitFirstPatch(i);
224  /// int size = osd.limitPatchSize(i);
225  /// UT_ASSERT(first + size <= limit.patchCount());
226  /// for (int j = 0; j < size; ++j)
227  /// {
228  /// int patch_index = first + j;
229  /// float coord = .5;
230  /// // It's considerably more efficient to evaluate these in batch
231  /// osd.limitSurface("P", false, 1, &patch_index, &coord, &coord);
232  /// }
233  /// }
234  /// @endcode
235  bool setupLimitEval(const GT_PrimitiveHandle &mesh);
236 
237  /// Return the number of input faces. A cube would have 6 faces, a
238  /// tetrahedron would have 4 faces.
239  GT_Size limitCoarseFaceCount() const;
240 
241  /// Return the number of individual patches (ptex face ids). So, a cube
242  /// would have 6 patches, while a tetrahedron would have 12 patches (each
243  /// triangle generates 3 patches).
244  GT_Size limitPatchCount() const;
245 
246  /// Return the ptexture id for a given input face. For example, if the
247  /// input mesh is a tetrahedron, @c limitFirstPatch(2) would return 6.
248  /// This is also equivalent to the ptexture index of the first patch for a
249  /// given face.
250  GT_Size limitFirstPatch(GT_Size face_index) const;
251 
252  /// Return the number of subdivision patches for a given input face. For
253  /// example, if the input mesh is a tetrahedron, @c limitPTextureId(2)
254  /// would return 3.
255  GT_Size limitPatchSize(GT_Size face_index) const;
256 
257  /// Definition of an attribute id on the topolgy
258  AttribId limitFindAttribute(const char *name) const;
259 
260  /// Given a face on the coarse mesh and a u,v coordinate from an attribute,
261  /// look up the corresponding patch and interpolant. If the attribute is
262  /// invalid, then the uv's will be assumed to be the patch interpolants,
263  /// with the patch offset added to the u coordinate.
264  bool limitLookupPatch(GT_Size hou_face,
265  fpreal hou_u, fpreal hou_v,
266  GT_Size &osd_face,
267  fpreal &osd_u, fpreal &osd_v,
268  const AttribId &attrib) 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) const;
279 
280  /// Evaluate the limit surface for a given point/vertex attribute at the
281  /// coordinates specified.
282  GT_DataArrayHandle limitSurface(const char *attrib, bool vertex_attrib,
283  const GT_DataArrayHandle &faces,
284  const GT_DataArrayHandle &uvs) const;
285  GT_DataArrayHandle limitSurface(const char *attrib, bool vertex_attrib,
286  const GT_DataArrayHandle &faces,
287  const GT_DataArrayHandle &u,
288  const GT_DataArrayHandle &v) const;
289  /// Evaluate the limit surface for a given point/vertex attribute at the
290  /// coordinates specified. The @c face_indices array should have @c npts
291  /// entries. The @c uvs array should have @c uv_stride*npts entries. Only
292  /// the first 2 coordinates will be used (and represent the s/t coordinates
293  /// of the face).
294  GT_DataArrayHandle limitSurface(const char *attrib, bool vertex_attrib,
295  exint npts,
296  const int32 *face_indices,
297  const fpreal32 *u,
298  const fpreal32 *v,
299  int uv_stride = 1) const;
300 
301  /// @{
302  /// Evaluate the limit surface for a given point/vertex attribute at the
303  /// coordinates specified. The @c face_indices array should have @c npts
304  /// entries. The @c uvs array should have @c uv_stride*npts entries. Only
305  /// the first 2 coordinates will be used (and represent the s/t coordinates
306  /// of the face).
307  /// The data handles determine which properties are returned:
308  /// @c result - Attribute
309  /// @c result_du - Derivative of attribute in 'u'
310  /// @c result_dv - Derivative of attribute in 'v'
311  /// Passing 'NULL' for a handle disables evaluation of that property.
312  /// The size of the evaluated attribute is returned.
313  int limitSurface(GT_DataArrayHandle *result,
314  GT_DataArrayHandle *result_du,
315  GT_DataArrayHandle *result_dv,
316  const AttribId &attrib,
317  exint npts,
318  const int32 *face_indices,
319  const fpreal32 *u,
320  const fpreal32 *v,
321  int uv_stride = 1) const;
322  int limitSurface(GT_DataArrayHandle *result,
323  GT_DataArrayHandle *result_du,
324  GT_DataArrayHandle *result_dv,
325  const char *attrib, bool vertex_attrib,
326  exint npts,
327  const int32 *face_indices,
328  const fpreal32 *u,
329  const fpreal32 *v,
330  int uv_stride = 1) const;
331  /// @}
332 
333  /// Create the OSD data structures to represent a particular subdivision
334  /// mesh. The suppolied handle must refer to a GT_PrimSubdivisionMesh or
335  /// the functions will fail. This function can be called once followed
336  /// by ay number of calls to refine and/or extractSubdivisionMesh.
337  bool createTopology(const GT_PrimitiveHandle &mesh);
338 
339  /// Copies attribute data from the supplied mesh into the OSD data
340  /// structure, and performs the refinement. The topology of the supplied
341  /// mesh must match that of the mesh passed to the createTopology
342  /// function, which must be called before this one.
343  bool refine(const GT_PrimitiveHandle &mesh,
344  bool force_update = false);
345 
346  /// Returns a GT_PrimPolygonMesh that is the result of subdividing the
347  /// mesh passed to the refine function above.
348  GT_PrimitiveHandle extractSubdividedMesh(int level=-1);
349 
350 #if 0
351  /// Returns a GT_OSDDrawContext that can be used for adaptive rendering
352  /// of the subdivision surface in the viewport.
353  const GT_OSDDrawContext *getDrawContext();
354 
355  /// Build patches for render-controlled subdivision. The raw float
356  /// arrays provided by GT_OSDVertex will be ordered according to the
357  /// ptattribs and vtxattribs order.
358  void buildPatches(UT_Array<GT_OSDPatchHandle> &patches,
359  Scheme scheme,
360  const GU_Detail &gdp,
361  const GU_SubDivPacking &ptattribs,
362  const GU_SubDivPacking &vtxattribs,
363  GA_Range *range=NULL);
364 #endif
365 
366  /// @{
367  /// Error handling (used internally)
368  void addError(const char *msg) { myErrors.append(msg); }
369  void clearErrors() { myErrors.resize(0); }
370  /// @}
371 
372 private:
373  bool updateGeo(GU_Detail &gdp, GA_Range *range,
374  const GT_PrimitiveHandle &prim) const;
375 
376  GT_PrimitiveHandle getHull(const GT_PrimitiveHandle &prim,
377  bool triangulate_loop = true) const;
378 
379  UT_StringArray myErrors;
380  GT_OSDOptions myOptions;
381  GT_OSDPatchTableOptions myLimitOptions;
382  GT_OSDPatchTable myPatches;
383  UT_UniquePtr<GT_OSDTopology> myTopology;
384  UT_UniquePtr<GT_OSDAttributes> myAttributes;
386  GT_TransformHandle myPrimitiveTransform;
387  bool myPolySoup;
388 };
389 
390 #endif
VtxBoundaryInterpolation vtxBoundaryInterpolation() const
GT_OSDOptions::SdcOptions SdcOptions
bool polySoup() const
OpenSubdiv::Sdc::Options SdcOptions
Definition: GT_OSD3.h:38
GLenum GLint * range
Definition: glcorearb.h:1924
const GLdouble * v
Definition: glcorearb.h:836
std::pair< int, bool > AttribId
Definition: GT_OSD3.h:340
#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:119
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:65
bool doCreaseOverride() const
int64 exint
Definition: SYS_Types.h:109
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:28
GT_OSDAttributes::AttribId AttribId
double fpreal
Definition: SYS_Types.h:263
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:177
int64 GT_Size
Definition: GT_Types.h:109
void setFVarLinearInterpolation(FVarLinearInterpolation v)
float fpreal32
Definition: SYS_Types.h:184
void setRemoveHoles(bool v)
void setCreaseOverride(fpreal w)
Class to perform subdivision refinement using OpenSubdivision.
unsigned int uint32
Definition: SYS_Types.h:29
void setPolySoup(bool v)
Options for topology and refinement.
Definition: GT_OSD3.h:35