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 
259  /// Build and return ptex to faceid mapping
260  UT_IntArray ptexToFaceMap() const;
261 
262 private:
263  TopologyRefiner *myRefiner;
264  bool myAdaptive;
265  bool myRemoveHoles;
266 };
267 
268 // Interface to create and look through a patch table
270 {
271 public:
272  using TopologyRefiner = OpenSubdiv::Far::TopologyRefiner;
273  using PatchTable = OpenSubdiv::Far::PatchTable;
274  using PatchTableFactory = OpenSubdiv::Far::PatchTableFactory;
275  using PatchDescriptor = OpenSubdiv::Far::PatchDescriptor;
276  using ConstIndexArray = OpenSubdiv::Far::ConstIndexArray;
277  using PatchParam = OpenSubdiv::Far::PatchParam;
279  using PtexIndices = OpenSubdiv::Far::PtexIndices;
280  using Handle = PatchTable::PatchHandle;
281 
283 
284  bool create(const GT_OSDTopology &top,
285  bool createPtexMap=false,
286  bool legacy_linear=true,
287  ConstIndexArray selectedfaces=ConstIndexArray());
288 
289  bool isEqual(const GT_OSDPatchTable &p) const;
290  bool operator==(const GT_OSDPatchTable &o) const
291  { return isEqual(o); }
292  void dump() const;
293  void dump(UT_JSONWriter &w )const;
294 
295  // Array level queries
296  int arrayCount() const;
297  int arrayPatchCount(int arr) const;
298  int numLocalPoints() const;
299  int numLocalPointsVarying() const;
300  ConstIndexArray vertexArray(int arr) const;
301  ConstIndexArray varyingVertexArray(int arr) const;
302  PatchDescriptor arrayPatchDesc(int arr) const;
303  template<typename T>
304  void computeLocalPoints(const T *src, T *dest) const
305  {
306  if (myTable)
307  myTable->ComputeLocalPointValues(src, dest);
308  }
309  template<typename T>
310  void computeLocalFVPoints(const T *src, T *dest) const
311  {
312  if (myTable)
313  myTable->ComputeLocalPointValuesFaceVarying(src, dest);
314  }
315 
316  // Patch level queries
317  PatchParam patchParam(int arr, int pat) const;
318  ConstIndexArray patchVertices(const Handle &patch) const;
319  ConstIndexArray patchFVValues(const Handle &patch) const;
320  void evaluateBasis(const Handle &patch, float u, float v,
321  float *w, float *du, float *dv) const;
322  void evaluateBasis(const Handle &patch, float u, float v,
323  float *w, float *du, float *dv,
324  float *duu, float *duv, float *dvv) const;
325  void evaluateBasisFV(const Handle &patch, float u, float v,
326  float *w, float *du, float *dv) const;
327  void evaluateBasisFV(const Handle &patch, float u, float v,
328  float *w, float *du, float *dv,
329  float *duu, float *duv, float *dvv) const;
330  // For ptex queries
331  int numPtexFaces() const;
332  const int *getPtexMap() const { return myPtexMap.array(); };
333  const UT_Array<int> &getPtexArray() const { return myPtexMap; };
334 
335  PatchTable *getTable() const { return myTable.get(); };
336  bool initialized() const { return myTable != nullptr; };
337 
338 private:
339  UT_UniquePtr<PatchTable> myTable;
340  GT_OSDPatchTableOptions myOptions;
341  UT_Array<int> myPtexMap;
342 };
343 
344 /// Storage arrays for vertex data for opensubdiv classes
346 {
347 public:
348  /// Identifier for an attribute. The first item is the index in the
349  /// attribute list, the second is whether it's a vertex or a point
350  /// attribute.
351  using AttribId = std::pair<int, bool>;
352 
354  ~GT_OSDAttributes();
355 
356  void dump() const;
357  void dump(UT_JSONWriter &w )const;
358 
359  exint getMemoryUsage() const;
360 
361  bool create(const GT_OSDTopology &topology,
362  const GT_PrimPolygonMesh &mesh,
363  const GT_OSDPatchTable *table=nullptr);
364 
365  bool update(const GT_OSDTopology &topology,
366  const GT_PrimPolygonMesh &mesh,
367  bool skip_equality_check = false);
368 
369  /// Extract a subdivided mesh for the given topology level
370  GT_PrimitiveHandle extractMesh(const GT_OSDTopology &topology,
371  bool harden,
372  int level = -1);
373 
374  /// Extract the shared/point attributes for a mesh at the given refinement
375  /// level. If @c harden is @c false, the attributes lists will point to
376  /// the temporary buffers (which are over-sized). Passing @c true to @c
377  /// harden will copy out the temporary data into compact arrays.
378  GT_AttributeListHandle extractShared(const GT_OSDTopology &top,
379  int level_index,
380  bool harden) const;
381  /// Extract the vertex/face-varying attributes for a mesh at the given
382  /// refinement level. See @c extractShared for help on @c harden
383  GT_AttributeListHandle extractVertex(const GT_OSDTopology &top,
384  int level_index,
385  bool harden) const;
386  /// Extract the primitive/face attributes for a mesh at the given
387  /// refinement level.
388  GT_AttributeListHandle extractUniform(const GT_OSDTopology &top,
389  int level_index,
390  bool harden) const;
391 
392  /// Extract a face map set for a mesh at the given refinement level
393  GT_FaceSetMapPtr extractFaceSets(const GT_OSDTopology &top,
394  int level_index) const;
395 
396  /// Extract a mapping from fine faces at a given refinement level to
397  /// its corresponding coarse face
398  GT_DataArrayHandle extractFaceMap(const GT_OSDTopology &top,
399  int level_index) const;
400 
401  /// @{
402  /// Find an attribute
403  AttribId findAttribute(const char *name) const;
404  AttribId findAttribute(const char *name, bool vertex_attrib) const;
405  /// @}
406 
407  /// Return the size of a given attribute
408  int tupleSize(const AttribId &attrib) const;
409 
410  /// Extract attributes on the coarse mesh
411  bool coarseValues(const AttribId &attrib,
412  const GT_Size *vertices,
413  GT_Size nvtx,
415  int seg) const;
416 
418  {
419  public:
421  : myAttribs(nullptr)
422  , myArrays(nullptr)
423  , mySizes(nullptr)
424  , myStorage(nullptr)
425  , myPointers(nullptr)
426  , mySize(0)
427  , myReadOnly(true)
428  {
429  }
431  {
432  clear();
433  }
434 
435  exint getMemoryUsage() const;
436 
437  int findAttrib(const char *name) const
438  {
439  return myAttribs ? myAttribs->getIndex(name) : -1;
440  }
441 
442  void init(const GT_AttributeListHandle &list, GT_Size size);
443  bool update(const GT_AttributeListHandle &list,
444  bool skip_equality_check = false);
445 
446  void clear()
447  {
448  mySize = 0;
449  delete [] myArrays;
450  delete [] myStorage;
451  delete [] myPointers;
452  delete [] mySizes;
453  myArrays = nullptr;
454  myStorage = nullptr;
455  myPointers = nullptr;
456  mySizes = nullptr;
457  }
458 
459  /// Extract the attributes for a given level. Note that the array
460  /// returned makes reference to the arrays including the temporary
461  /// vertices. Passing @c harden==true will cause the arrays to be
462  /// duplicated (more memory, but more compact)
463  GT_AttributeListHandle extractLevel(const GT_OSDTopology &topology,
464  int level,
465  bool harden,
466  bool fvar) const;
467 
468  /// Raw access to the attributes
469  const GT_AttributeListHandle &attribList() const { return myAttribs;}
470 
471  /// Access a specific data array in the attributes
472  const GT_DataArrayHandle &attribArray(int attrib) const
473  { return myAttribs->get(attrib); }
474 
475  exint size() const { return mySize; }
476  bool readOnly() const { return myReadOnly; }
477  GT_Size attribSize(int attrib) const { return mySizes[attrib]; }
478  bool attribValid(int attrib) const
479  { return myPointers[attrib] != nullptr; }
480  GT_Storage attribStorage(int attrib) const
481  { return myStorage[attrib]; }
482  GT_Type attribType(int attrib) const
483  { return myType[attrib]; }
484  int motionSegments() const { return mySegments; }
485 
486  template <typename T>
487  T *attribData(int attrib, GT_Size index, int seg)
488  {
489  UT_ASSERT(myPointers[attrib + mySize * seg]);
490  UT_ASSERT(!myReadOnly);
491  // Here, we cast away the const, but we know that this is not
492  // read-only
493  auto data = (T *)myPointers[attrib + mySize * seg];
494  return data + index*mySizes[attrib];
495  }
496  template <typename T>
497  const T *attribData(int attrib, GT_Size index, int seg) const
498  {
499  UT_ASSERT(myPointers[attrib + mySize * seg]);
500  auto data = (const T *)myPointers[attrib + mySize * seg];
501  return data + index*mySizes[attrib];
502  }
503  void dump() const;
504  void dump(UT_JSONWriter &w) const;
505  private:
506  GT_AttributeListHandle myAttribs;
507  GT_DataArrayHandle *myArrays;
508  GT_Size *mySizes;
509  GT_Storage *myStorage;
510  GT_Type *myType;
511  const void **myPointers;
512  GT_Size mySize;
513  int mySegments;
514  bool myReadOnly;
515  };
516 
518  {
519  public:
521  : myStorage(nullptr)
522  , myIndex(-1)
523  , myMaxWeight(0)
524  {
525  }
527  {
528  myStorage = &storage;
529  myIndex = index;
530  myMaxWeight = 0;
531  }
532 
533  /// Methods required for OpenSubdiv
534  const VertexStorage *storage() const { return myStorage; }
535  GT_Size index() const { return myIndex; }
536 
537  template <typename T>
538  const T *attribData(int attrib, int seg) const
539  {
540  // Make sure to call the const method on myStorage
541  return static_cast<const VertexStorage *>(myStorage)->attribData<T>(
542  attrib, myIndex, seg);
543  }
544 
545  // TODO: Templatize?
546  void extract(int attrib_idx, fpreal32 *data, int size,
547  int seg) const;
548 
549  void Clear();
550  void AddWithWeight(const Vertex &src, float weight);
551  void dump() const;
552  void dump(UT_JSONWriter &w) const;
553  private:
554  VertexStorage *myStorage;
555  GT_Size myIndex;
556  float myMaxWeight;
557  };
558 
560  { return myCoarseStorage; }
562  { return myCoarseFVStorage; }
563 
565  { return myVertices; }
566 
568  { return myFVertices; }
569 
570 #if 0
571  /// Given a face on the coarse mesh, a u/v coordinate from an attribute,
572  /// look up the corresponding patch and interpolant. If the attribute is
573  /// invalid, the uv's will be assumed to be the face interpolants using the
574  /// scheme where (0,0) maps to the first vertex, (1,0) maps to nvtx-1, (0,
575  /// 1) maps to vertex 2, (1,1) maps to nvtx-2 and the remaining vertices
576  /// are fit linearly between (0, 1) and (1,1).
577  bool lookupPatch(const GT_OSDTopology &topology,
578  GT_Size coarse_id, fpreal coarse_u, fpreal coarse_v,
579  GT_Size &patch_id, fpreal &patch_u, fpreal &patch_v,
580  const AttribId &attrib) const;
581 
582  /// Inverse of @c lookupPatch. Given a patch, lookup the coarse id and
583  /// interpolants.
584  bool lookupFace(GT_Size patch_id, fpreal patch_u, fpreal patch_v,
585  GT_Size &coarse_id, fpreal &coarse_u, fpreal &coarse_v,
586  const AttribId &attrib) const;
587 #endif
588 
589  const VertexStorage &coarseStorage() const { return myCoarseStorage; }
590  const VertexStorage &fineStorage() const { return myFineStorage; }
591  const VertexStorage &coarseFVStorage() const { return myCoarseFVStorage; }
592  const VertexStorage &fineFVStorage() const { return myFineFVStorage; }
593 
594  /// Return a pointer to the index-th entry in the given attribute array.
595  /// If the index exceeds or equals the number of coarse vertices
596  /// (myFineOffset), then the data is located in the fine attribute
597  /// array. The first element of the fine attribute array has index
598  /// equal to myFineOffset, so we do pointer arithmetic to shift the
599  /// array by myFineOffset entries.
600  template <typename T>
601  const T *getData(int attrib, int index, int seg) const
602  {
603  if (index < myFineOffset)
604  {
605  return myCoarseStorage.attribData<T>(attrib, index, seg);
606  }
607  else
608  {
609  int offset = index - myFineOffset;
610  return myFineStorage.attribData<T>(attrib, offset, seg);
611  }
612  }
613 
614  /// Same idea as with getData, but with face varying data
615  template <typename T>
616  const T *getDataFV(int attrib, int index, int seg) const
617  {
618  if (index < myFineFVOffset)
619  {
620  return myCoarseFVStorage.attribData<T>(attrib, index, seg);
621  }
622  else
623  {
624  int offset = index - myFineFVOffset;
625  return myFineFVStorage.attribData<T>(attrib, offset, seg);
626  }
627  }
628 
629  int fineOffset() const { return myFineOffset; }
630  int fineFVOffset() const { return myFineFVOffset; }
631 
632 private:
633  // Perform interpolation
634  void interpolateData(const GT_OSDTopology &topology);
635 
636  GT_AttributeListHandle myUniform;
637  GT_AttributeListHandle myDetail;
638  GT_FaceSetMapPtr myFaceSets;
639  VertexStorage myCoarseStorage;
640  VertexStorage myFineStorage;
641  VertexStorage myCoarseFVStorage; // Face vertex coarse storage
642  VertexStorage myFineFVStorage; // Face vertex refined storage
643  UT_Array<Vertex> myVertices;
644  UT_Array<Vertex> myFVertices; // Face vertices
645  exint myFineOffset;
646  exint myFineFVOffset;
647 };
648 
649 /// Minimal interface to Bfr (base-face representation)
651 {
652 public:
653  using Surface = OpenSubdiv::Bfr::Surface<fpreal32>;
654 
657 
658  /// Minimum. The actual usage may be far greater.
659  exint getMemoryUsage() const;
660 
661  /// @{
662  /// Calculate patch points for all surfaces to pass to evaluate functions.
663  /// Input attrdata must be of float type. Returns GT_DANumeric of same
664  /// type. It's up to the caller to store and manage the returned data for
665  /// reuse. May return nullptr if invalid (eg surfaces don't exist or the
666  /// input attrdata is unsupported type)
668  const GT_DataArrayHandle &attrdata) const
669  {
670  return doPreparePatchPoints<false>(attrdata);
671  }
672 
674  const GT_DataArrayHandle &attrdata) const
675  {
676  return doPreparePatchPoints<true>(attrdata);
677  }
678  /// @}
679 
680  /// @{
681  /// Evaluate attribute and its derivs at specified coordinate.
682  /// T must be a float type (accepts 64-bit but beware that it'll be
683  /// interpolated in 32-bit). The tuple count in result array must match the
684  /// tuple count in patchpoints. du and dv may be nullptr if not needed.
685  template <typename T>
686  void evaluate(T *result, T *du, T *dv,
687  int ptexid, float u, float v,
688  const GT_DataArrayHandle &patchpoints) const
689  {
690  doEvaluate<T, false>(result, du, dv, ptexid, u, v, patchpoints);
691  }
692 
693  template <typename T>
694  void evaluateFV(T *result, T *du, T *dv,
695  int ptexid, float u, float v,
696  const GT_DataArrayHandle &patchpoints) const
697  {
698  doEvaluate<T, true>(result, du, dv, ptexid, u, v, patchpoints);
699  }
700  /// @}
701 
702  /// Get Ptex to base face mapping
703  const int *getPtexMap() const { return myPtexToFaceMap.array(); };
704 
705 private:
706  // Get base mesh face id and quadrant given ptex id
707  void decodePtex(int &faceid, int &subface, int ptexid) const;
708 
709  template <bool FVAR>
710  exint totalPatchPointsCount() const;
711 
712  template <bool FVAR>
713  GT_DataArrayHandle doPreparePatchPoints(
714  const GT_DataArrayHandle &attrdata) const;
715 
716  template <typename T, bool FVAR>
717  void doEvaluate(T *result, T *du, T *dv,
718  int ptexid, float u, float v,
719  const GT_DataArrayHandle &patchpoints) const;
720 
721  UT_Array<Surface> mySurfaces;
722  UT_Array<GT_Offset> myPatchOffsets;
723  UT_Array<Surface> myFVSurfaces;
724  UT_Array<GT_Offset> myFVPatchOffsets;
725  UT_Array<int> myPtexToFaceMap;
726 };
727 
728 /// Minimal interface to Bfr (base-face representation) for individual face
730 {
731 public:
732  /// GT_OSDBfrSurface builder
734  {
735  public:
737  ~Factory();
738  GT_OSDBfrSurface build(int faceid);
739 
740  private:
741  class InternalData;
742  UT_UniquePtr<InternalData> myInternalData;
743  };
744  static Factory &getFactory();
745 
746  /// @{
747  /// Calculate patch points to pass to evaluate functions.
748  /// Input attrdata must be of float type. Returns GT_DANumeric of same
749  /// type. Using fpreal32 storage is highly recommended for performance
750  /// reasons. It's up to the caller to store and manage the returned data
751  /// for reuse. May return nullptr if unknown data type.
753  const GT_DataArrayHandle &attrdata) const
754  {
755  return doPreparePatchPoints<false>(attrdata);
756  }
757 
759  const GT_DataArrayHandle &attrdata) const
760  {
761  return doPreparePatchPoints<true>(attrdata);
762  }
763  /// @}
764 
765  /// @{
766  /// Evaluate attribute and its derivs at specified coordinate.
767  /// subface index can be obtained by counting digits to subtract from
768  /// ptexid until it maps to a different face (using ptex->face mapping from
769  /// GT_OSDTopology). T must be a float type (accepts 64-bit but beware that
770  /// it'll be interpolated in 32-bit). The tuple count in result array must
771  /// match the tuple count in patchpoints. du and dv may be nullptr if not
772  /// needed.
773  template <typename T>
774  void evaluate(T *result, T *du, T *dv,
775  int subface, float u, float v,
776  const GT_DataArrayHandle &patchpoints) const
777  {
778  doEvaluate<T, false>(result, du, dv, subface, u, v, patchpoints);
779  }
780 
781  template <typename T>
782  void evaluateFV(T *result, T *du, T *dv,
783  int subface, float u, float v,
784  const GT_DataArrayHandle &patchpoints) const
785  {
786  doEvaluate<T, true>(result, du, dv, subface, u, v, patchpoints);
787  }
788  /// @}
789 
790 private:
791  template <bool FVAR>
792  GT_DataArrayHandle doPreparePatchPoints(
793  const GT_DataArrayHandle &attrdata) const;
794 
795  template <typename T, bool FVAR>
796  void doEvaluate(T *result, T *du, T *dv,
797  int subface, float u, float v,
798  const GT_DataArrayHandle &patchpoints) const;
799 
800  using Surface = OpenSubdiv::Bfr::Surface<fpreal32>;
801  Surface mySurface;
802  Surface myFVSurface;
803 };
804 
805 /// Interface to perform limit surface evaluation.
807 {
808 public:
809  using TopologyRefiner = OpenSubdiv::Far::TopologyRefiner;
810  using PtexIndices = OpenSubdiv::Far::PtexIndices;
811  using PatchTable = OpenSubdiv::Far::PatchTable;
812  using PatchMap = OpenSubdiv::Far::PatchMap;
813  using PatchTableFactory = OpenSubdiv::Far::PatchTableFactory;
817 
819  const GT_OSDPatchTableOptions &options,
820  const GT_OSDPatchTable &patchTable,
821  const GT_PrimPolygonMesh &mesh);
823 
824  void dump() const;
825  void dump(UT_JSONWriter &w) const;
826 
827  /// Return the number of patches
828  int ptexFaceCount() const;
829 
830  /// Return the first ptex patch associated with the given coarse face
831  int ptexFromFace(GT_Size face_index) const;
832  /// @{
833  /// Return the number of ptex patches for the given coarse face
834  int numPtexPatches(const TopologyRefiner &refiner,
835  GT_Size face_index) const;
837  GT_Size face_index) const
838  { return numPtexPatches(*top.refiner(), face_index); }
839  /// @}
840 
841  /// Return the coarse face associated with the given ptex id
842  GT_Size faceFromPtex(int ptex_id, int &offset) const;
843 
844  /// @{
845  /// Query the points/vertices for a face in the coarse mesh
846  bool coarsePoints(const GT_OSDTopology &topology,
847  GT_Size coarse_face_index,
848  GT_Size *vertices,
849  GT_Size buffer_size) const;
850  bool coarseVertices(const GT_OSDTopology &topology,
851  GT_Size coarse_face_index,
852  GT_Size *vertices,
853  GT_Size buffer_size) const;
854  /// @}
855 
856  /// Evaluate the limit surface (and derivatives) at a given coordinates.
857  /// The @c faces array should have @c npts entries. The @c u and @c v
858  /// arrays should have also have @c npts entries. Each @c u and @c v
859  /// coordinate will be offset by @c uv_stride entries. So, if you have
860  /// uv's that are interleaved (i.e. [u0 v0 u1 v1 u2 v2 ...]), you can
861  /// offset the @c v pointer and set the stride to 2.
862  ///
863  /// Passing a @c nullptr for any of the results will disable evaluation of
864  /// that property.
865  ///
866  /// The method returns the tuple size of the attribute evaluated.
867  int limitSurface(GT_DataArrayHandle *result,
868  GT_DataArrayHandle *result_du,
869  GT_DataArrayHandle *result_dv,
870  const GT_OSDAttributes &alist,
871  const AttribId &attrib,
872  int npts,
873  const int32 *faces,
874  const fpreal32 *u,
875  const fpreal32 *v,
876  int uv_stride = 1,
877  int seg = 0) const;
878 
879  /// Evaluation of face-varying attributes on the limit surface
880  int limitSurfaceFVar(const GT_OSDTopology &topology,
882  GT_DataArrayHandle *result_du,
883  GT_DataArrayHandle *result_dv,
884  const GT_OSDAttributes &alist,
885  const AttribId &attrib,
886  int npts,
887  const int32 *faces,
888  const fpreal32 *u,
889  const fpreal32 *v,
890  int uv_stride = 1,
891  int seg = 0) const;
892 
893  /// Evaluate the limit surface (and derivatives) at the given coordinates.
894  /// The @c faces array should have @c npts entries. The @c u and @c v
895  /// arrays should have also have @c npts entries. Each @c u and @c v
896  /// coordinate will be offset by @c uv_stride entries. So, if you have
897  /// uv's that are interleaved (i.e. [u0 v0 u1 v1 u2 v2 ...]), you can
898  /// offset the @c v pointer and set the stride to 2.
899  ///
900  /// All pointers are required in this version.
901  ///
902  /// The method returns the tuple size of the attribute evaluated.
903  int limitSurface(GT_DataArrayHandle *result,
904  GT_DataArrayHandle *result_du,
905  GT_DataArrayHandle *result_dv,
906  GT_DataArrayHandle *result_duu,
907  GT_DataArrayHandle *result_duv,
908  GT_DataArrayHandle *result_dvv,
909  const GT_OSDAttributes &alist,
910  const AttribId &attrib,
911  int npts,
912  const int32 *faces,
913  const fpreal32 *u,
914  const fpreal32 *v,
915  int uv_stride = 1,
916  int seg = 0) const;
917 
918  /// Evaluation of face-varying attributes on the limit surface
919  int limitSurfaceFVar(const GT_OSDTopology &topology,
921  GT_DataArrayHandle *result_du,
922  GT_DataArrayHandle *result_dv,
923  GT_DataArrayHandle *result_duu,
924  GT_DataArrayHandle *result_duv,
925  GT_DataArrayHandle *result_dvv,
926  const GT_OSDAttributes &alist,
927  const AttribId &attrib,
928  int npts,
929  const int32 *faces,
930  const fpreal32 *u,
931  const fpreal32 *v,
932  int uv_stride = 1,
933  int seg = 0) const;
934 
935 private:
936  // Maps coarse face -> ptex
937  UT_UniquePtr<PtexIndices> myPtexIndices;
938  // Holds all patches and also a map for ptex -> face
939  const GT_OSDPatchTable &myPatches;
940  // Maps (coarse face + (u,v)) -> sub patch
941  UT_UniquePtr<PatchMap> myPatchMap;
942  //VertexStorage myStorage;
943  GT_CountArray myFaceOffsets;
944 };
945 
946 #endif
const UT_Array< int > & getPtexArray() const
Definition: GT_OSD3.h:333
SIM_API const UT_StringHolder vertex
OpenSubdiv::Far::ConstIndexArray ConstIndexArray
Definition: GT_OSD3.h:276
OpenSubdiv::Far::TopologyRefiner TopologyRefiner
Definition: GT_OSD3.h:809
GT_Storage
Definition: GT_Types.h:19
OpenSubdiv::Far::PatchTableFactory PatchTableFactory
Definition: GT_OSD3.h:274
GT_DataArrayHandle preparePatchPoints(const GT_DataArrayHandle &attrdata) const
Definition: GT_OSD3.h:752
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:480
GT_DataArrayHandle preparePatchPoints(const GT_DataArrayHandle &attrdata) const
Definition: GT_OSD3.h:667
OpenSubdiv::Far::PtexIndices PtexIndices
Definition: GT_OSD3.h:279
void computeLocalPoints(const T *src, T *dest) const
Definition: GT_OSD3.h:304
int numPtexPatches(const GT_OSDTopology &top, GT_Size face_index) const
Definition: GT_OSD3.h:836
GT_DataArrayHandle preparePatchPointsFV(const GT_DataArrayHandle &attrdata) const
Definition: GT_OSD3.h:673
OpenSubdiv::Far::PatchDescriptor::Type PatchType
Definition: GT_OSD3.h:278
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:686
const LevelInfo & lastLevel() const
Definition: GT_OSD3.h:230
void computeLocalFVPoints(const T *src, T *dest) const
Definition: GT_OSD3.h:310
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:814
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:694
GLsizei const GLfloat * value
Definition: glcorearb.h:824
int fineOffset() const
Definition: GT_OSD3.h:629
std::pair< int, bool > AttribId
Definition: GT_OSD3.h:351
const VertexStorage & coarseFVStorage() const
Definition: GT_OSD3.h:591
GT_Size index() const
Definition: GT_OSD3.h:535
bool adaptive() const
Definition: GT_OSD3.h:87
OpenSubdiv::Far::PatchDescriptor PatchDescriptor
Definition: GT_OSD3.h:275
#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:592
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:345
int maxIsolationLevel() const
Definition: GT_OSD3.h:152
void setCreaseOverride(fpreal value=-1)
Definition: GT_OSD3.h:95
void evaluate(T *result, T *du, T *dv, int subface, float u, float v, const GT_DataArrayHandle &patchpoints) const
Definition: GT_OSD3.h:774
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:497
**But if you need a result
Definition: thread.h:622
void init(VertexStorage &storage, GT_Size index)
Definition: GT_OSD3.h:526
OpenSubdiv::Far::PatchTableFactory PatchTableFactory
Definition: GT_OSD3.h:813
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:3542
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:477
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:616
GT_Size coarseVertexCount() const
Definition: GT_OSD3.h:240
GLintptr offset
Definition: glcorearb.h:665
bool attribValid(int attrib) const
Definition: GT_OSD3.h:478
GT_Type attribType(int attrib) const
Definition: GT_OSD3.h:482
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:280
const GT_AttributeListHandle & attribList() const
Raw access to the attributes.
Definition: GT_OSD3.h:469
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:589
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:332
GT_Size coarsePointCount() const
Definition: GT_OSD3.h:238
int findAttrib(const char *name) const
Definition: GT_OSD3.h:437
const T * getData(int attrib, int index, int seg) const
Definition: GT_OSD3.h:601
T * attribData(int attrib, GT_Size index, int seg)
Definition: GT_OSD3.h:487
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
Minimal interface to Bfr (base-face representation) for individual face.
Definition: GT_OSD3.h:729
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:630
OpenSubdiv::Far::PatchMap PatchMap
Definition: GT_OSD3.h:812
Minimal interface to Bfr (base-face representation)
Definition: GT_OSD3.h:650
OpenSubdiv::Far::TopologyRefiner TopologyRefiner
Definition: GT_OSD3.h:191
OpenSubdiv::Far::PtexIndices PtexIndices
Definition: GT_OSD3.h:810
int64 GT_Size
Definition: GT_Types.h:128
const T * attribData(int attrib, int seg) const
Definition: GT_OSD3.h:538
GLsizeiptr size
Definition: glcorearb.h:664
GT_OSDBfrSurface builder.
Definition: GT_OSD3.h:733
bool operator==(const GT_OSDPatchTable &o) const
Definition: GT_OSD3.h:290
PatchTable * getTable() const
Definition: GT_OSD3.h:335
const GT_DataArrayHandle & attribArray(int attrib) const
Access a specific data array in the attributes.
Definition: GT_OSD3.h:472
bool removeHoles() const
Definition: GT_OSD3.h:90
OpenSubdiv::Far::PatchTable PatchTable
Definition: GT_OSD3.h:811
OpenSubdiv::Far::PatchTable PatchTable
Definition: GT_OSD3.h:273
GLenum GLsizei GLsizei GLint * values
Definition: glcorearb.h:1602
SdcOptions & operator*()
Definition: GT_OSD3.h:78
const VertexStorage & fineStorage() const
Definition: GT_OSD3.h:590
const int * getPtexMap() const
Get Ptex to base face mapping.
Definition: GT_OSD3.h:703
fpreal64 fpreal
Definition: SYS_Types.h:278
const UT_Array< Vertex > & vertexArray() const
Definition: GT_OSD3.h:564
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:559
OpenSubdiv::Far::PatchParam PatchParam
Definition: GT_OSD3.h:277
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
bool initialized() const
Definition: GT_OSD3.h:336
GT_DataArrayHandle preparePatchPointsFV(const GT_DataArrayHandle &attrdata) const
Definition: GT_OSD3.h:758
OpenSubdiv::Far::TopologyRefiner TopologyRefiner
Definition: GT_OSD3.h:272
Topology definition for opensubdiv classes.
Definition: GT_OSD3.h:188
OpenSubdiv::Bfr::Surface< fpreal32 > Surface
Definition: GT_OSD3.h:653
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:567
void setUseSingleCreasePatch(bool v)
Definition: GT_OSD3.h:169
Definition: format.h:1821
bool adaptive() const
Test whether this has been built for adaptive refinement.
Definition: GT_OSD3.h:249
void evaluateFV(T *result, T *du, T *dv, int subface, float u, float v, const GT_DataArrayHandle &patchpoints) const
Definition: GT_OSD3.h:782
const VertexStorage * storage() const
Methods required for OpenSubdiv.
Definition: GT_OSD3.h:534
Interface to perform limit surface evaluation.
Definition: GT_OSD3.h:806
void * Handle
Definition: plugin.h:27
const VertexStorage & coarseFaceVarying() const
Definition: GT_OSD3.h:561
GLenum src
Definition: glcorearb.h:1793
Options for topology and refinement.
Definition: GT_OSD3.h:39