HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
GT_OSD3.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_OSD3.h (GT Library, C++)
7  *
8  * COMMENTS:
9  */
10 
11 #ifndef __GT_OSD3__
12 #define __GT_OSD3__
13 
14 #if defined(WIN32)
15  // MSVC does not provide readable alternatives to operators by default
16  // (i.e. && => 'and') so we have to include this header since OpenSubdiv
17  // makes use of some of the alternatives such as 'not', 'and' and 'or'.
18  #include <iso646.h>
19 #endif
20 
21 #include "GT_API.h"
22 #include "GT_Types.h"
23 #include "GT_PrimPolygonMesh.h"
24 #include <SYS/SYS_Hash.h>
25 #include <UT/UT_UniquePtr.h>
26 #include <opensubdiv/far/ptexIndices.h>
27 #include <opensubdiv/far/primvarRefiner.h>
28 #include <opensubdiv/far/patchTableFactory.h>
29 #include <opensubdiv/far/patchMap.h>
30 #include <opensubdiv/bfr/surface.h>
31 
32 class UT_JSONWriter;
33 
34 /// @file
35 /// This file contains code to support OpenSubdiv 3.x for the GT library
36 /// The code in here is primarily used in GT_UtilOpenSubdiv
37 
38 /// Options for topology and refinement
40 {
41 public:
42  using SdcOptions = OpenSubdiv::Sdc::Options;
43  using VtxBoundaryInterpolation = SdcOptions::VtxBoundaryInterpolation;
44  using FVarLinearInterpolation = SdcOptions::FVarLinearInterpolation;
45  using CreasingMethod = SdcOptions::CreasingMethod;
46  using TriangleSubdivision = SdcOptions::TriangleSubdivision;
47 
49  int level = 2,
50  bool adaptive = false,
51  fpreal crease_override = -1,
52  bool remove_holes = true)
53  : myOptions()
54  , myScheme(scheme)
55  , myCreaseOverride(crease_override)
56  , myLevel(level)
57  , myAdaptive(adaptive)
58  , myRemoveHoles(remove_holes)
59  {
60  // Set default behaviour
61  setVtxBoundaryInterpolation(SdcOptions::VTX_BOUNDARY_EDGE_AND_CORNER);
62  setFVarLinearInterpolation(SdcOptions::FVAR_LINEAR_BOUNDARIES);
63  }
64 
65  const SdcOptions &options() const { return myOptions; }
66  void setOptions(const SdcOptions &o) { myOptions = o; }
67 
68  SYS_HashType hash() const;
69  bool isEqual(const GT_OSDOptions &opts) const;
70  bool operator==(const GT_OSDOptions &s) const
71  { return isEqual(s); }
72  bool operator!=(const GT_OSDOptions &s) const
73  { return !isEqual(s); }
74 
75  // Access this object as it were an OpenSubdiv::Sdc::Options
76  SdcOptions &operator->() { return myOptions; }
77  const SdcOptions &operator->() const { return myOptions; }
78  SdcOptions &operator*() { return myOptions; }
79  const SdcOptions &operator*() const { return myOptions; }
80 
81  GT_Scheme scheme() const { return myScheme; }
82  void setScheme(GT_Scheme t) { myScheme = t; }
83 
84  int level() const { return myLevel; }
85  void setLevel(int l) { myLevel = l; }
86 
87  bool adaptive() const { return myAdaptive; }
88  void setAdaptive(bool b) { myAdaptive = b; }
89 
90  bool removeHoles() const { return myRemoveHoles; }
91  void setRemoveHoles(bool v) { myRemoveHoles = v; }
92 
93  bool enableCreaseOverride() const { return myCreaseOverride >= 0; }
94  fpreal creaseOverride() const { return myCreaseOverride; }
95  void setCreaseOverride(fpreal value=-1) { myCreaseOverride = value; }
96 
97 #define GETSET(TYPE, GET) \
98  TYPE GET() const { return myOptions.Get##TYPE(); } \
99  void set##TYPE(TYPE v) { myOptions.Set##TYPE(v); }
100 
101  /// @{
102  /// Simple wrappers on the SdcOptions
103  GETSET(VtxBoundaryInterpolation, vtxBoundaryInterpolation);
104  GETSET(FVarLinearInterpolation, fvarLinearInterpolation);
105  GETSET(CreasingMethod, creasingMethod);
106  GETSET(TriangleSubdivision, triangleSubdivision);
107  /// @}
108 #undef GETSET
109 
110  void dump() const;
111  void dump(UT_JSONWriter &w) const;
112 
113 private:
114  SdcOptions myOptions;
115  GT_Scheme myScheme;
116  fpreal myCreaseOverride;
117  int myLevel;
118  bool myAdaptive;
119  bool myRemoveHoles;
120 };
121 
122 /// Options for setting up limit surface evaluation.
124 {
125 public:
126  using FactoryOptions = OpenSubdiv::Far::PatchTableFactory::Options;
127 
129  : myOptions()
130  {
131  }
132 
133  bool isEqual(const GT_OSDPatchTableOptions &o) const;
134  bool operator==(const GT_OSDPatchTableOptions &o) const
135  { return isEqual(o); }
136  bool operator!=(const GT_OSDPatchTableOptions &o) const
137  { return !isEqual(o); }
138  void dump() const;
139  void dump(UT_JSONWriter &w) const;
140 
141  FactoryOptions &operator*() { return myOptions; }
142  const FactoryOptions &operator*() const { return myOptions; }
143 
145  { return (FactoryOptions::EndCapType)myOptions.endCapType; }
146  bool generateAllLevels() const
147  { return myOptions.generateAllLevels; }
148  bool triangulateQuads() const
149  { return myOptions.triangulateQuads; }
150  bool useSingleCreasePatch() const
151  { return myOptions.useSingleCreasePatch; }
152  int maxIsolationLevel() const
153  { return myOptions.maxIsolationLevel; }
155  { return myOptions.shareEndCapPatchPoints; }
156  bool generateFVarTables() const
157  { return myOptions.generateFVarTables; }
158  int numFVarChannels() const
159  { return myOptions.numFVarChannels; }
160  const int *fvarChannelIndices() const
161  { return myOptions.fvarChannelIndices; }
162 
164  { myOptions.endCapType = (FactoryOptions::EndCapType)t; }
166  { myOptions.generateAllLevels = v; }
168  { myOptions.triangulateQuads = v; }
170  { myOptions.useSingleCreasePatch = v; }
172  { myOptions.maxIsolationLevel = v; }
174  { myOptions.shareEndCapPatchPoints = v; }
176  { myOptions.generateFVarTables = v; }
178  { myOptions.numFVarChannels = n; }
180  { myOptions.fvarChannelIndices = indices; }
182  { myOptions.generateFVarLegacyLinearPatches = b; }
183 private:
184  FactoryOptions myOptions;
185 };
186 
187 /// Topology definition for opensubdiv classes
189 {
190 public:
191  using TopologyRefiner = OpenSubdiv::Far::TopologyRefiner;
192  using LevelInfo = OpenSubdiv::Far::TopologyLevel;
193 
194  GT_OSDTopology();
195  ~GT_OSDTopology();
196 
197  /// @{
198  /// Debug - dump the topology out
199  void dump() const;
200  void dump(UT_JSONWriter &w) const;
201  /// @}
202 
203  bool isEqual(const GT_OSDTopology &src) const;
204  bool operator==(const GT_OSDTopology &o) const { return isEqual(o); }
205 
206  static SYS_HashType hash(const GT_PrimPolygonMesh &mesh,
207  const GT_OSDOptions &options);
208  static SYS_HashType areEqual(const GT_PrimPolygonMesh &a,
209  const GT_PrimPolygonMesh &b);
210 
211  /// Create the topology for the given polygonal hull and options. Note
212  /// that if the mesh is a GT_PrimSubdivisionMesh, crease weights will be
213  /// picked up from the tags on the primitive.
214  bool create(const GT_PrimPolygonMesh &mesh,
215  const GT_OSDOptions &options);
216 
217  /// Number of levels in refinement (note this is the max level + 1)
219  { return myRefiner->GetNumLevels(); }
220 
221  /// Access to the level information for a given refinement level
222  /// This returns the number of vertices, face-varying vertices, faces, etc.
223  /// for each level. Level 0 is the "coarse" mesh.
224  /// - GetNumVertices() - Number of shared points (i.e. Houdini points)
225  /// - GetNumFaces() - Number of faces
226  /// - GetNumEdges() - Number of edges
227  /// - GetNumFaceVertices() - Number of face varying (i.e. Houdini vertices)
228  const LevelInfo &levelInfo(int level) const
229  { return myRefiner->GetLevel(level); }
230  const LevelInfo &lastLevel() const
231  { return levelInfo(myRefiner->GetNumLevels()-1); }
232 
233 
234  /// @{
235  /// Return specific information about the coarse mesh (i.e. level 0)
237  { return levelInfo(0).GetNumFaces(); }
239  { return levelInfo(0).GetNumVertices(); }
241  { return levelInfo(0).GetNumFaceVertices(); }
242  GT_Size coarseVertexCount(GT_Size face_index) const;
243  /// @}
244 
245  /// Access to the refiner
246  const TopologyRefiner *refiner() const { return myRefiner; }
247 
248  /// Test whether this has been built for adaptive refinement
249  bool adaptive() const { return myAdaptive; }
250 
251  /// Create a polygon mesh for a given level
252  GT_PrimitiveHandle createMesh(int level,
253  const GT_AttributeListHandle &point,
255  const GT_AttributeListHandle &uniform,
256  const GT_AttributeListHandle &detail,
257  const GT_FaceSetMapPtr &fsets=GT_FaceSetMapPtr()) const;
258 private:
259  TopologyRefiner *myRefiner;
260  bool myAdaptive;
261  bool myRemoveHoles;
262 };
263 
264 // Interface to create and look through a patch table
266 {
267 public:
268  using TopologyRefiner = OpenSubdiv::Far::TopologyRefiner;
269  using PatchTable = OpenSubdiv::Far::PatchTable;
270  using PatchTableFactory = OpenSubdiv::Far::PatchTableFactory;
271  using PatchDescriptor = OpenSubdiv::Far::PatchDescriptor;
272  using ConstIndexArray = OpenSubdiv::Far::ConstIndexArray;
273  using PatchParam = OpenSubdiv::Far::PatchParam;
275  using PtexIndices = OpenSubdiv::Far::PtexIndices;
276  using Handle = PatchTable::PatchHandle;
277 
279 
280  bool create(const GT_OSDTopology &top,
281  bool createPtexMap=false,
282  bool legacy_linear=true,
283  ConstIndexArray selectedfaces=ConstIndexArray());
284 
285  bool isEqual(const GT_OSDPatchTable &p) const;
286  bool operator==(const GT_OSDPatchTable &o) const
287  { return isEqual(o); }
288  void dump() const;
289  void dump(UT_JSONWriter &w )const;
290 
291  // Array level queries
292  int arrayCount() const;
293  int arrayPatchCount(int arr) const;
294  int numLocalPoints() const;
295  int numLocalPointsVarying() const;
296  ConstIndexArray vertexArray(int arr) const;
297  ConstIndexArray varyingVertexArray(int arr) const;
298  PatchDescriptor arrayPatchDesc(int arr) const;
299  template<typename T>
300  void computeLocalPoints(const T *src, T *dest) const
301  {
302  if (myTable)
303  myTable->ComputeLocalPointValues(src, dest);
304  }
305  template<typename T>
306  void computeLocalFVPoints(const T *src, T *dest) const
307  {
308  if (myTable)
309  myTable->ComputeLocalPointValuesFaceVarying(src, dest);
310  }
311 
312  // Patch level queries
313  PatchParam patchParam(int arr, int pat) const;
314  ConstIndexArray patchVertices(const Handle &patch) const;
315  ConstIndexArray patchFVValues(const Handle &patch) const;
316  void evaluateBasis(const Handle &patch, float u, float v,
317  float *w, float *du, float *dv) const;
318  void evaluateBasisFV(const Handle &patch, float u, float v,
319  float *w, float *du, float *dv) const;
320 
321  // For ptex queries
322  int numPtexFaces() const;
323  const int *getPtexMap() const { return myPtexMap.array(); };
324  const UT_Array<int> &getPtexArray() const { return myPtexMap; };
325 
326  PatchTable *getTable() const { return myTable.get(); };
327  bool initialized() const { return myTable != nullptr; };
328 
329 private:
330  UT_UniquePtr<PatchTable> myTable;
331  GT_OSDPatchTableOptions myOptions;
332  UT_Array<int> myPtexMap;
333 };
334 
335 /// Storage arrays for vertex data for opensubdiv classes
337 {
338 public:
339  /// Identifier for an attribute. The first item is the index in the
340  /// attribute list, the second is whether it's a vertex or a point
341  /// attribute.
342  using AttribId = std::pair<int, bool>;
343 
345  ~GT_OSDAttributes();
346 
347  void dump() const;
348  void dump(UT_JSONWriter &w )const;
349 
350  exint getMemoryUsage() const;
351 
352  bool create(const GT_OSDTopology &topology,
353  const GT_PrimPolygonMesh &mesh,
354  const GT_OSDPatchTable *table=nullptr);
355 
356  bool update(const GT_OSDTopology &topology,
357  const GT_PrimPolygonMesh &mesh,
358  bool skip_equality_check = false);
359 
360  /// Extract a subdivided mesh for the given topology level
361  GT_PrimitiveHandle extractMesh(const GT_OSDTopology &topology,
362  bool harden,
363  int level = -1);
364 
365  /// Extract the shared/point attributes for a mesh at the given refinement
366  /// level. If @c harden is @c false, the attributes lists will point to
367  /// the temporary buffers (which are over-sized). Passing @c true to @c
368  /// harden will copy out the temporary data into compact arrays.
369  GT_AttributeListHandle extractShared(const GT_OSDTopology &top,
370  int level_index,
371  bool harden) const;
372  /// Extract the vertex/face-varying attributes for a mesh at the given
373  /// refinement level. See @c extractShared for help on @c harden
374  GT_AttributeListHandle extractVertex(const GT_OSDTopology &top,
375  int level_index,
376  bool harden) const;
377  /// Extract the primitive/face attributes for a mesh at the given
378  /// refinement level.
379  GT_AttributeListHandle extractUniform(const GT_OSDTopology &top,
380  int level_index,
381  bool harden) const;
382 
383  /// Extract a face map set for a mesh at the given refinement level
384  GT_FaceSetMapPtr extractFaceSets(const GT_OSDTopology &top,
385  int level_index) const;
386 
387  /// Extract a mapping from fine faces at a given refinement level to
388  /// its corresponding coarse face
389  GT_DataArrayHandle extractFaceMap(const GT_OSDTopology &top,
390  int level_index) const;
391 
392  /// @{
393  /// Find an attribute
394  AttribId findAttribute(const char *name) const;
395  AttribId findAttribute(const char *name, bool vertex_attrib) const;
396  /// @}
397 
398  /// Return the size of a given attribute
399  int tupleSize(const AttribId &attrib) const;
400 
401  /// Extract attributes on the coarse mesh
402  bool coarseValues(const AttribId &attrib,
403  const GT_Size *vertices,
404  GT_Size nvtx,
406  int seg) const;
407 
409  {
410  public:
412  : myAttribs(nullptr)
413  , myArrays(nullptr)
414  , mySizes(nullptr)
415  , myStorage(nullptr)
416  , myPointers(nullptr)
417  , mySize(0)
418  , myReadOnly(true)
419  {
420  }
422  {
423  clear();
424  }
425 
426  exint getMemoryUsage() const;
427 
428  int findAttrib(const char *name) const
429  {
430  return myAttribs ? myAttribs->getIndex(name) : -1;
431  }
432 
433  void init(const GT_AttributeListHandle &list, GT_Size size);
434  bool update(const GT_AttributeListHandle &list,
435  bool skip_equality_check = false);
436 
437  void clear()
438  {
439  mySize = 0;
440  delete [] myArrays;
441  delete [] myStorage;
442  delete [] myPointers;
443  delete [] mySizes;
444  myArrays = nullptr;
445  myStorage = nullptr;
446  myPointers = nullptr;
447  mySizes = nullptr;
448  }
449 
450  /// Extract the attributes for a given level. Note that the array
451  /// returned makes reference to the arrays including the temporary
452  /// vertices. Passing @c harden==true will cause the arrays to be
453  /// duplicated (more memory, but more compact)
454  GT_AttributeListHandle extractLevel(const GT_OSDTopology &topology,
455  int level,
456  bool harden,
457  bool fvar) const;
458 
459  /// Raw access to the attributes
460  const GT_AttributeListHandle &attribList() const { return myAttribs;}
461 
462  /// Access a specific data array in the attributes
463  const GT_DataArrayHandle &attribArray(int attrib) const
464  { return myAttribs->get(attrib); }
465 
466  exint size() const { return mySize; }
467  bool readOnly() const { return myReadOnly; }
468  GT_Size attribSize(int attrib) const { return mySizes[attrib]; }
469  bool attribValid(int attrib) const
470  { return myPointers[attrib] != nullptr; }
471  GT_Storage attribStorage(int attrib) const
472  { return myStorage[attrib]; }
473  GT_Type attribType(int attrib) const
474  { return myType[attrib]; }
475  int motionSegments() const { return mySegments; }
476 
477  template <typename T>
478  T *attribData(int attrib, GT_Size index, int seg)
479  {
480  UT_ASSERT(myPointers[attrib + mySize * seg]);
481  UT_ASSERT(!myReadOnly);
482  // Here, we cast away the const, but we know that this is not
483  // read-only
484  auto data = (T *)myPointers[attrib + mySize * seg];
485  return data + index*mySizes[attrib];
486  }
487  template <typename T>
488  const T *attribData(int attrib, GT_Size index, int seg) const
489  {
490  UT_ASSERT(myPointers[attrib + mySize * seg]);
491  auto data = (const T *)myPointers[attrib + mySize * seg];
492  return data + index*mySizes[attrib];
493  }
494  void dump() const;
495  void dump(UT_JSONWriter &w) const;
496  private:
497  GT_AttributeListHandle myAttribs;
498  GT_DataArrayHandle *myArrays;
499  GT_Size *mySizes;
500  GT_Storage *myStorage;
501  GT_Type *myType;
502  const void **myPointers;
503  GT_Size mySize;
504  int mySegments;
505  bool myReadOnly;
506  };
507 
509  {
510  public:
512  : myStorage(nullptr)
513  , myIndex(-1)
514  , myMaxWeight(0)
515  {
516  }
518  {
519  myStorage = &storage;
520  myIndex = index;
521  myMaxWeight = 0;
522  }
523 
524  /// Methods required for OpenSubdiv
525  const VertexStorage *storage() const { return myStorage; }
526  GT_Size index() const { return myIndex; }
527 
528  template <typename T>
529  const T *attribData(int attrib, int seg) const
530  {
531  // Make sure to call the const method on myStorage
532  return static_cast<const VertexStorage *>(myStorage)->attribData<T>(
533  attrib, myIndex, seg);
534  }
535 
536  // TODO: Templatize?
537  void extract(int attrib_idx, fpreal32 *data, int size,
538  int seg) const;
539 
540  void Clear();
541  void AddWithWeight(const Vertex &src, float weight);
542  void dump() const;
543  void dump(UT_JSONWriter &w) const;
544  private:
545  VertexStorage *myStorage;
546  GT_Size myIndex;
547  float myMaxWeight;
548  };
549 
551  { return myCoarseStorage; }
553  { return myCoarseFVStorage; }
554 
556  { return myVertices; }
557 
559  { return myFVertices; }
560 
561 #if 0
562  /// Given a face on the coarse mesh, a u/v coordinate from an attribute,
563  /// look up the corresponding patch and interpolant. If the attribute is
564  /// invalid, the uv's will be assumed to be the face interpolants using the
565  /// scheme where (0,0) maps to the first vertex, (1,0) maps to nvtx-1, (0,
566  /// 1) maps to vertex 2, (1,1) maps to nvtx-2 and the remaining vertices
567  /// are fit linearly between (0, 1) and (1,1).
568  bool lookupPatch(const GT_OSDTopology &topology,
569  GT_Size coarse_id, fpreal coarse_u, fpreal coarse_v,
570  GT_Size &patch_id, fpreal &patch_u, fpreal &patch_v,
571  const AttribId &attrib) const;
572 
573  /// Inverse of @c lookupPatch. Given a patch, lookup the coarse id and
574  /// interpolants.
575  bool lookupFace(GT_Size patch_id, fpreal patch_u, fpreal patch_v,
576  GT_Size &coarse_id, fpreal &coarse_u, fpreal &coarse_v,
577  const AttribId &attrib) const;
578 #endif
579 
580  const VertexStorage &coarseStorage() const { return myCoarseStorage; }
581  const VertexStorage &fineStorage() const { return myFineStorage; }
582  const VertexStorage &coarseFVStorage() const { return myCoarseFVStorage; }
583  const VertexStorage &fineFVStorage() const { return myFineFVStorage; }
584 
585  /// Return a pointer to the index-th entry in the given attribute array.
586  /// If the index exceeds or equals the number of coarse vertices
587  /// (myFineOffset), then the data is located in the fine attribute
588  /// array. The first element of the fine attribute array has index
589  /// equal to myFineOffset, so we do pointer arithmetic to shift the
590  /// array by myFineOffset entries.
591  template <typename T>
592  const T *getData(int attrib, int index, int seg) const
593  {
594  if (index < myFineOffset)
595  {
596  return myCoarseStorage.attribData<T>(attrib, index, seg);
597  }
598  else
599  {
600  int offset = index - myFineOffset;
601  return myFineStorage.attribData<T>(attrib, offset, seg);
602  }
603  }
604 
605  /// Same idea as with getData, but with face varying data
606  template <typename T>
607  const T *getDataFV(int attrib, int index, int seg) const
608  {
609  if (index < myFineFVOffset)
610  {
611  return myCoarseFVStorage.attribData<T>(attrib, index, seg);
612  }
613  else
614  {
615  int offset = index - myFineFVOffset;
616  return myFineFVStorage.attribData<T>(attrib, offset, seg);
617  }
618  }
619 
620  int fineOffset() const { return myFineOffset; }
621  int fineFVOffset() const { return myFineFVOffset; }
622 
623 private:
624  // Perform interpolation
625  void interpolateData(const GT_OSDTopology &topology);
626 
627  GT_AttributeListHandle myUniform;
628  GT_AttributeListHandle myDetail;
629  GT_FaceSetMapPtr myFaceSets;
630  VertexStorage myCoarseStorage;
631  VertexStorage myFineStorage;
632  VertexStorage myCoarseFVStorage; // Face vertex coarse storage
633  VertexStorage myFineFVStorage; // Face vertex refined storage
634  UT_Array<Vertex> myVertices;
635  UT_Array<Vertex> myFVertices; // Face vertices
636  exint myFineOffset;
637  exint myFineFVOffset;
638 };
639 
640 /// Minimal interface to Bfr (base-face representation)
642 {
643 public:
644  using Surface = OpenSubdiv::Bfr::Surface<fpreal32>;
645 
648 
649  /// Minimum. The actual usage may be far greater.
650  exint getMemoryUsage() const;
651 
652  /// @{
653  /// Calculate patch points for all surfaces to pass to evaluate functions.
654  /// Input attrdata must be of float typpe. Returns GT_DANumeric of same
655  /// type. It's up to the caller to store and manage the returned data for
656  /// reuse. May return nullptr if invalid (eg surfaces don't exist or the
657  /// input attrdata is unsupported type)
659  const GT_DataArrayHandle &attrdata) const
660  {
661  return doPreparePatchPoints<false>(attrdata);
662  }
663 
665  const GT_DataArrayHandle &attrdata) const
666  {
667  return doPreparePatchPoints<true>(attrdata);
668  }
669  /// @}
670 
671  /// @{
672  /// Evaluate attribute and its derivs at specified coordinate.
673  /// T must be a float type (accepts 64-bit but beware that it'll be
674  /// interpolated in 32-bit). The tuple count in result array must match the
675  /// tuple count in patchpoints. du and dv may be nullptr if not needed.
676  template <typename T>
677  void evaluate(T *result, T *du, T *dv,
678  int ptexid, float u, float v,
679  const GT_DataArrayHandle &patchpoints) const
680  {
681  doEvaluate<T, false>(result, du, dv, ptexid, u, v, patchpoints);
682  }
683 
684  template <typename T>
685  void evaluateFV(T *result, T *du, T *dv,
686  int ptexid, float u, float v,
687  const GT_DataArrayHandle &patchpoints) const
688  {
689  doEvaluate<T, true>(result, du, dv, ptexid, u, v, patchpoints);
690  }
691  /// @}
692 
693  /// Get Ptex to base face mapping
694  const int *getPtexMap() const { return myPtexToFaceMap.array(); };
695 
696 private:
697  // Get base mesh face id and quadrant given ptex id
698  void decodePtex(int &faceid, int &subface, int ptexid) const;
699 
700  template <bool FVAR>
701  exint totalPatchPointsCount() const;
702 
703  template <bool FVAR>
704  GT_DataArrayHandle doPreparePatchPoints(
705  const GT_DataArrayHandle &attrdata) const;
706 
707  template <typename T, bool FVAR>
708  void doEvaluate(T *result, T *du, T *dv,
709  int ptexid, float u, float v,
710  const GT_DataArrayHandle &patchpoints) const;
711 
712  UT_Array<Surface> mySurfaces;
713  UT_Array<GT_Offset> myPatchOffsets;
714  UT_Array<Surface> myFVSurfaces;
715  UT_Array<GT_Offset> myFVPatchOffsets;
716  UT_Array<int> myPtexToFaceMap;
717 };
718 
719 /// Interface to perform limit surface evaluation.
721 {
722 public:
723  using TopologyRefiner = OpenSubdiv::Far::TopologyRefiner;
724  using PtexIndices = OpenSubdiv::Far::PtexIndices;
725  using PatchTable = OpenSubdiv::Far::PatchTable;
726  using PatchMap = OpenSubdiv::Far::PatchMap;
727  using PatchTableFactory = OpenSubdiv::Far::PatchTableFactory;
731 
733  const GT_OSDPatchTableOptions &options,
734  const GT_OSDPatchTable &patchTable,
735  const GT_PrimPolygonMesh &mesh);
737 
738  void dump() const;
739  void dump(UT_JSONWriter &w) const;
740 
741  /// Return the number of patches
742  int ptexFaceCount() const;
743 
744  /// Return the first ptex patch associated with the given coarse face
745  int ptexFromFace(GT_Size face_index) const;
746  /// @{
747  /// Return the number of ptex patches for the given coarse face
748  int numPtexPatches(const TopologyRefiner &refiner,
749  GT_Size face_index) const;
751  GT_Size face_index) const
752  { return numPtexPatches(*top.refiner(), face_index); }
753  /// @}
754 
755  /// Return the coarse face associated with the given ptex id
756  GT_Size faceFromPtex(int ptex_id, int &offset) const;
757 
758  /// @{
759  /// Query the points/vertices for a face in the coarse mesh
760  bool coarsePoints(const GT_OSDTopology &topology,
761  GT_Size coarse_face_index,
762  GT_Size *vertices,
763  GT_Size buffer_size) const;
764  bool coarseVertices(const GT_OSDTopology &topology,
765  GT_Size coarse_face_index,
766  GT_Size *vertices,
767  GT_Size buffer_size) const;
768  /// @}
769 
770  /// Evaluate the limit surface (and derivatives) at a given coordinates.
771  /// The @c faces array should have @c npts entries. The @c u and @c v
772  /// arrays should have also have @c npts entries. Each @c u and @c v
773  /// coordinate will be offset by @c uv_stride entries. So, if you have
774  /// uv's that are interleaved (i.e. [u0 v0 u1 v1 u2 v2 ...]), you can
775  /// offset the @c v pointer and set the stride to 2.
776  ///
777  /// Passing a @c nullptr for any of the results will disable evaluation of
778  /// that property.
779  ///
780  /// The method returns the tuple size of the attribute evaluated.
781  int limitSurface(GT_DataArrayHandle *result,
782  GT_DataArrayHandle *result_du,
783  GT_DataArrayHandle *result_dv,
784  const GT_OSDAttributes &alist,
785  const AttribId &attrib,
786  int npts,
787  const int32 *faces,
788  const fpreal32 *u,
789  const fpreal32 *v,
790  int uv_stride = 1,
791  int seg = 0) const;
792 
793  /// Evaluation of face-varying attributes on the limit surface
794  int limitSurfaceFVar(const GT_OSDTopology &topology,
796  GT_DataArrayHandle *result_du,
797  GT_DataArrayHandle *result_dv,
798  const GT_OSDAttributes &alist,
799  const AttribId &attrib,
800  int npts,
801  const int32 *faces,
802  const fpreal32 *u,
803  const fpreal32 *v,
804  int uv_stride = 1,
805  int seg = 0) const;
806 
807 private:
808  // Maps coarse face -> ptex
809  UT_UniquePtr<PtexIndices> myPtexIndices;
810  // Holds all patches and also a map for ptex -> face
811  const GT_OSDPatchTable &myPatches;
812  // Maps (coarse face + (u,v)) -> sub patch
813  UT_UniquePtr<PatchMap> myPatchMap;
814  //VertexStorage myStorage;
815  GT_CountArray myFaceOffsets;
816 };
817 
818 #endif
const UT_Array< int > & getPtexArray() const
Definition: GT_OSD3.h:324
SIM_API const UT_StringHolder vertex
OpenSubdiv::Far::ConstIndexArray ConstIndexArray
Definition: GT_OSD3.h:272
OpenSubdiv::Far::TopologyRefiner TopologyRefiner
Definition: GT_OSD3.h:723
GT_Storage
Definition: GT_Types.h:19
OpenSubdiv::Far::PatchTableFactory PatchTableFactory
Definition: GT_OSD3.h:270
const int * fvarChannelIndices() const
Definition: GT_OSD3.h:160
FactoryOptions & operator*()
Definition: GT_OSD3.h:141
GLsizei GLenum const void * indices
Definition: glcorearb.h:406
OpenSubdiv::Sdc::Options SdcOptions
Definition: GT_OSD3.h:42
int int32
Definition: SYS_Types.h:39
GT_Storage attribStorage(int attrib) const
Definition: GT_OSD3.h:471
GT_DataArrayHandle preparePatchPoints(const GT_DataArrayHandle &attrdata) const
Definition: GT_OSD3.h:658
OpenSubdiv::Far::PtexIndices PtexIndices
Definition: GT_OSD3.h:275
void computeLocalPoints(const T *src, T *dest) const
Definition: GT_OSD3.h:300
int numPtexPatches(const GT_OSDTopology &top, GT_Size face_index) const
Definition: GT_OSD3.h:750
GT_DataArrayHandle preparePatchPointsFV(const GT_DataArrayHandle &attrdata) const
Definition: GT_OSD3.h:664
OpenSubdiv::Far::PatchDescriptor::Type PatchType
Definition: GT_OSD3.h:274
A mesh of polygons.
void evaluate(T *result, T *du, T *dv, int ptexid, float u, float v, const GT_DataArrayHandle &patchpoints) const
Definition: GT_OSD3.h:677
const LevelInfo & lastLevel() const
Definition: GT_OSD3.h:230
void computeLocalFVPoints(const T *src, T *dest) const
Definition: GT_OSD3.h:306
bool operator!=(const GT_OSDPatchTableOptions &o) const
Definition: GT_OSD3.h:136
SdcOptions & operator->()
Definition: GT_OSD3.h:76
GT_OSDAttributes::AttribId AttribId
Definition: GT_OSD3.h:728
getFileOption("OpenEXR:storage") storage
Definition: HDK_Image.dox:276
const SdcOptions & operator*() const
Definition: GT_OSD3.h:79
const GLdouble * v
Definition: glcorearb.h:837
void setRemoveHoles(bool v)
Definition: GT_OSD3.h:91
void evaluateFV(T *result, T *du, T *dv, int ptexid, float u, float v, const GT_DataArrayHandle &patchpoints) const
Definition: GT_OSD3.h:685
GLsizei const GLfloat * value
Definition: glcorearb.h:824
int fineOffset() const
Definition: GT_OSD3.h:620
std::pair< int, bool > AttribId
Definition: GT_OSD3.h:342
const VertexStorage & coarseFVStorage() const
Definition: GT_OSD3.h:582
GT_Size index() const
Definition: GT_OSD3.h:526
bool adaptive() const
Definition: GT_OSD3.h:87
OpenSubdiv::Far::PatchDescriptor PatchDescriptor
Definition: GT_OSD3.h:271
#define GT_API
Definition: GT_API.h:13
int64 exint
Definition: SYS_Types.h:125
bool operator==(const GT_OSDPatchTableOptions &o) const
Definition: GT_OSD3.h:134
GLint level
Definition: glcorearb.h:108
GT_Type
Definition: GT_Types.h:36
void setMaxIsolationLevel(int v)
Definition: GT_OSD3.h:171
GLboolean GLboolean GLboolean GLboolean a
Definition: glcorearb.h:1222
const VertexStorage & fineFVStorage() const
Definition: GT_OSD3.h:583
GLdouble s
Definition: glad.h:3009
std::size_t SYS_HashType
Define the type for hash values.
Definition: SYS_Hash.h:19
Storage arrays for vertex data for opensubdiv classes.
Definition: GT_OSD3.h:336
int maxIsolationLevel() const
Definition: GT_OSD3.h:152
void setCreaseOverride(fpreal value=-1)
Definition: GT_OSD3.h:95
SdcOptions::VtxBoundaryInterpolation VtxBoundaryInterpolation
Definition: GT_OSD3.h:43
Class which writes ASCII or binary JSON streams.
Definition: UT_JSONWriter.h:37
const T * attribData(int attrib, GT_Size index, int seg) const
Definition: GT_OSD3.h:488
**But if you need a result
Definition: thread.h:613
void init(VertexStorage &storage, GT_Size index)
Definition: GT_OSD3.h:517
OpenSubdiv::Far::PatchTableFactory PatchTableFactory
Definition: GT_OSD3.h:727
void setFVarChannelIndices(const int *indices)
Definition: GT_OSD3.h:179
float fpreal32
Definition: SYS_Types.h:200
void setGenerateAllLevels(bool v)
Definition: GT_OSD3.h:165
SdcOptions::FVarLinearInterpolation FVarLinearInterpolation
Definition: GT_OSD3.h:44
Options for setting up limit surface evaluation.
Definition: GT_OSD3.h:123
std::unique_ptr< T, Deleter > UT_UniquePtr
A smart pointer for unique ownership of dynamically allocated objects.
Definition: UT_UniquePtr.h:39
bool useSingleCreasePatch() const
Definition: GT_OSD3.h:150
fpreal creaseOverride() const
Definition: GT_OSD3.h:94
FactoryOptions::EndCapType endCapType() const
Definition: GT_OSD3.h:144
SdcOptions::CreasingMethod CreasingMethod
Definition: GT_OSD3.h:45
OIIO_FORCEINLINE bool extract(const vbool4 &a)
Definition: simd.h:3426
void setEndCapType(FactoryOptions::EndCapType t)
Definition: GT_OSD3.h:163
void setOptions(const SdcOptions &o)
Definition: GT_OSD3.h:66
const FactoryOptions & operator*() const
Definition: GT_OSD3.h:142
GT_Size attribSize(int attrib) const
Definition: GT_OSD3.h:468
int numFVarChannels() const
Definition: GT_OSD3.h:158
GLdouble n
Definition: glcorearb.h:2008
const T * getDataFV(int attrib, int index, int seg) const
Same idea as with getData, but with face varying data.
Definition: GT_OSD3.h:607
GT_Size coarseVertexCount() const
Definition: GT_OSD3.h:240
GLintptr offset
Definition: glcorearb.h:665
bool attribValid(int attrib) const
Definition: GT_OSD3.h:469
GT_Type attribType(int attrib) const
Definition: GT_OSD3.h:473
const SdcOptions & options() const
Definition: GT_OSD3.h:65
GT_Scheme
Subdivision schemes.
Definition: GT_Types.h:81
void setNumFVarChannels(int n)
Definition: GT_OSD3.h:177
void setLegacyLinearPatches(bool b)
Definition: GT_OSD3.h:181
bool operator==(const GT_OSDTopology &o) const
Definition: GT_OSD3.h:204
PatchTable::PatchHandle Handle
Definition: GT_OSD3.h:276
const GT_AttributeListHandle & attribList() const
Raw access to the attributes.
Definition: GT_OSD3.h:460
OpenSubdiv::Far::PatchTableFactory::Options FactoryOptions
Definition: GT_OSD3.h:126
GT_API const UT_StringHolder topology
bool operator!=(const GT_OSDOptions &s) const
Definition: GT_OSD3.h:72
const VertexStorage & coarseStorage() const
Definition: GT_OSD3.h:580
bool shareEndCapPatchPoints() const
Definition: GT_OSD3.h:154
exint levelCount() const
Number of levels in refinement (note this is the max level + 1)
Definition: GT_OSD3.h:218
bool enableCreaseOverride() const
Definition: GT_OSD3.h:93
void setScheme(GT_Scheme t)
Definition: GT_OSD3.h:82
const int * getPtexMap() const
Definition: GT_OSD3.h:323
GT_Size coarsePointCount() const
Definition: GT_OSD3.h:238
int findAttrib(const char *name) const
Definition: GT_OSD3.h:428
const T * getData(int attrib, int index, int seg) const
Definition: GT_OSD3.h:592
T * attribData(int attrib, GT_Size index, int seg)
Definition: GT_OSD3.h:478
GLuint const GLchar * name
Definition: glcorearb.h:786
int level() const
Definition: GT_OSD3.h:84
bool generateAllLevels() const
Definition: GT_OSD3.h:146
GLboolean GLboolean GLboolean b
Definition: glcorearb.h:1222
GT_ElementSetMapPtr GT_FaceSetMapPtr
Aliases for backwards compatibility. In the past, only face sets were supported.
Definition: GT_FaceSetMap.h:18
void setTriangulateQuads(bool v)
Definition: GT_OSD3.h:167
GLenum GLenum GLsizei void * table
Definition: glad.h:5129
bool generateFVarTables() const
Definition: GT_OSD3.h:156
OpenSubdiv::Far::TopologyLevel LevelInfo
Definition: GT_OSD3.h:192
GLdouble t
Definition: glad.h:2397
GT_Size coarseFaceCount() const
Definition: GT_OSD3.h:236
const TopologyRefiner * refiner() const
Access to the refiner.
Definition: GT_OSD3.h:246
int fineFVOffset() const
Definition: GT_OSD3.h:621
OpenSubdiv::Far::PatchMap PatchMap
Definition: GT_OSD3.h:726
Minimal interface to Bfr (base-face representation)
Definition: GT_OSD3.h:641
OpenSubdiv::Far::TopologyRefiner TopologyRefiner
Definition: GT_OSD3.h:191
OpenSubdiv::Far::PtexIndices PtexIndices
Definition: GT_OSD3.h:724
int64 GT_Size
Definition: GT_Types.h:128
const T * attribData(int attrib, int seg) const
Definition: GT_OSD3.h:529
GLsizeiptr size
Definition: glcorearb.h:664
bool operator==(const GT_OSDPatchTable &o) const
Definition: GT_OSD3.h:286
PatchTable * getTable() const
Definition: GT_OSD3.h:326
const GT_DataArrayHandle & attribArray(int attrib) const
Access a specific data array in the attributes.
Definition: GT_OSD3.h:463
bool removeHoles() const
Definition: GT_OSD3.h:90
OpenSubdiv::Far::PatchTable PatchTable
Definition: GT_OSD3.h:725
OpenSubdiv::Far::PatchTable PatchTable
Definition: GT_OSD3.h:269
GLenum GLsizei GLsizei GLint * values
Definition: glcorearb.h:1602
SdcOptions & operator*()
Definition: GT_OSD3.h:78
const VertexStorage & fineStorage() const
Definition: GT_OSD3.h:581
const int * getPtexMap() const
Get Ptex to base face mapping.
Definition: GT_OSD3.h:694
fpreal64 fpreal
Definition: SYS_Types.h:277
const UT_Array< Vertex > & vertexArray() const
Definition: GT_OSD3.h:555
GLuint index
Definition: glcorearb.h:786
void setGenerateFVarTables(bool v)
Definition: GT_OSD3.h:175
const LevelInfo & levelInfo(int level) const
Definition: GT_OSD3.h:228
GT_OSDOptions(GT_Scheme scheme=GT_CATMULL_CLARK, int level=2, bool adaptive=false, fpreal crease_override=-1, bool remove_holes=true)
Definition: GT_OSD3.h:48
const VertexStorage & coarseVertex() const
Definition: GT_OSD3.h:550
OpenSubdiv::Far::PatchParam PatchParam
Definition: GT_OSD3.h:273
void setShareEndCapPatchPoints(bool v)
Definition: GT_OSD3.h:173
GLdouble GLdouble GLdouble top
Definition: glad.h:2817
void setLevel(int l)
Definition: GT_OSD3.h:85
void setAdaptive(bool b)
Definition: GT_OSD3.h:88
#define GETSET(TYPE, GET)
Definition: GT_OSD3.h:97
GLubyte GLubyte GLubyte GLubyte w
Definition: glcorearb.h:857
#define UT_ASSERT(ZZ)
Definition: UT_Assert.h:156
Definition: core.h:1131
bool initialized() const
Definition: GT_OSD3.h:327
OpenSubdiv::Far::TopologyRefiner TopologyRefiner
Definition: GT_OSD3.h:268
Topology definition for opensubdiv classes.
Definition: GT_OSD3.h:188
OpenSubdiv::Bfr::Surface< fpreal32 > Surface
Definition: GT_OSD3.h:644
bool triangulateQuads() const
Definition: GT_OSD3.h:148
bool operator==(const GT_OSDOptions &s) const
Definition: GT_OSD3.h:70
GT_Scheme scheme() const
Definition: GT_OSD3.h:81
SdcOptions::TriangleSubdivision TriangleSubdivision
Definition: GT_OSD3.h:46
const SdcOptions & operator->() const
Definition: GT_OSD3.h:77
const UT_Array< Vertex > & facevaryingArray() const
Definition: GT_OSD3.h:558
void setUseSingleCreasePatch(bool v)
Definition: GT_OSD3.h:169
Definition: format.h:895
bool adaptive() const
Test whether this has been built for adaptive refinement.
Definition: GT_OSD3.h:249
const VertexStorage * storage() const
Methods required for OpenSubdiv.
Definition: GT_OSD3.h:525
Interface to perform limit surface evaluation.
Definition: GT_OSD3.h:720
void * Handle
Definition: plugin.h:27
const VertexStorage & coarseFaceVarying() const
Definition: GT_OSD3.h:552
GLenum src
Definition: glcorearb.h:1793
Options for topology and refinement.
Definition: GT_OSD3.h:39