All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
patchTables.h
Go to the documentation of this file.
1 //
2 // Copyright 2013 Pixar
3 //
4 // Licensed under the Apache License, Version 2.0 (the "Apache License")
5 // with the following modification; you may not use this file except in
6 // compliance with the Apache License and the following modification to it:
7 // Section 6. Trademarks. is deleted and replaced with:
8 //
9 // 6. Trademarks. This License does not grant permission to use the trade
10 // names, trademarks, service marks, or product names of the Licensor
11 // and its affiliates, except as required to comply with Section 4(c) of
12 // the License and to reproduce the content of the NOTICE file.
13 //
14 // You may obtain a copy of the Apache License at
15 //
16 // http://www.apache.org/licenses/LICENSE-2.0
17 //
18 // Unless required by applicable law or agreed to in writing, software
19 // distributed under the Apache License with the above modification is
20 // distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
21 // KIND, either express or implied. See the Apache License for the specific
22 // language governing permissions and limitations under the Apache License.
23 //
24 
25 #ifndef FAR_PATCH_TABLES_H
26 #define FAR_PATCH_TABLES_H
27 
28 #include "../version.h"
29 
30 #include "../far/patchParam.h"
31 #include "../far/types.h"
32 
33 #include <cstdlib>
34 #include <cassert>
35 #include <algorithm>
36 #include <vector>
37 #include <map>
38 
39 namespace OpenSubdiv {
40 namespace OPENSUBDIV_VERSION {
41 
42 namespace Far {
43 
49 class PatchTables {
50 
51 public:
52  typedef std::vector<unsigned int> PTable;
53  typedef std::vector<int> VertexValenceTable;
54  typedef std::vector<unsigned int> QuadOffsetTable;
55  typedef std::vector<PatchParam> PatchParamTable;
56 
57  enum Type {
58  NON_PATCH = 0,
59 
62 
65 
66  LOOP,
67 
73  };
74 
82  };
83 
102  class Descriptor {
103 
104  public:
107  _type(NON_PATCH), _pattern(NON_TRANSITION), _rotation(0) {}
108 
110  Descriptor(int type, int pattern, unsigned char rotation) :
111  _type(type), _pattern(pattern), _rotation(rotation) { }
112 
114  Descriptor( Descriptor const & d ) :
115  _type(d.GetType()), _pattern(d.GetPattern()), _rotation(d.GetRotation()) { }
116 
118  Type GetType() const {
119  return (Type)_type;
120  }
121 
124  return (TransitionPattern)_pattern;
125  }
126 
128  unsigned char GetRotation() const {
129  return (unsigned char)_rotation;
130  }
131 
134  static inline short GetNumControlVertices( Type t );
135 
136  static inline short GetNumFVarControlVertices( Type t );
137 
140  short GetNumControlVertices() const {
141  return GetNumControlVertices( this->GetType() );
142  }
143 
147  return GetNumFVarControlVertices( this->GetType() );
148  }
149 
151  static inline std::vector<Descriptor> const & GetAllValidDescriptors();
152 
154  inline bool operator < ( Descriptor const other ) const;
155 
157  inline bool operator == ( Descriptor const other ) const;
158 
188  class iterator;
189 
190  enum PrimType {
193  };
194 
199  static iterator begin(PrimType type);
200 
202  static iterator end();
203 
204  private:
205  friend class PatchTablesFactory;
206  friend class iterator;
207 
208  unsigned int _type:4;
209  unsigned int _pattern:3;
210  unsigned int _rotation:2;
211  };
212 
213 
214 
215 
217  class PatchArray {
218 
219  public:
236  PatchArray( Descriptor desc, unsigned int vertIndex, unsigned int patchIndex, unsigned int npatches, unsigned int quadOffsetIndex ) :
237  _desc(desc), _range(vertIndex, patchIndex, npatches, quadOffsetIndex) { }
238 
241  return _desc;
242  }
243 
245  struct ArrayRange {
246 
260  ArrayRange( unsigned int ivertIndex, unsigned int ipatchIndex, unsigned int inpatches, unsigned int iquadOffsetIndex ) :
261  vertIndex(ivertIndex), patchIndex(ipatchIndex), npatches(inpatches), quadOffsetIndex(iquadOffsetIndex) { }
262 
263  unsigned int vertIndex, // absolute index to the first control vertex of the first patch in the PTable
264  patchIndex, // absolute index of the first patch in the array
265  npatches, // number of patches in the array
266  quadOffsetIndex; // absolute index of the first quad offset entry
267  };
268 
270  ArrayRange const & GetArrayRange() const {
271  return _range;
272  }
273 
276  unsigned int GetVertIndex() const {
277  return _range.vertIndex;
278  }
279 
282  unsigned int GetPatchIndex() const {
283  return _range.patchIndex;
284  }
285 
287  unsigned int GetNumPatches() const {
288  return _range.npatches;
289  }
290 
292  unsigned int GetQuadOffsetIndex() const {
293  return _range.quadOffsetIndex;
294  }
295 
296  private:
297  friend class PatchTablesFactory;
298 
299  Descriptor _desc; // type of patches in the array
300 
301  ArrayRange _range; // index locators in the array
302  };
303 
304  typedef std::vector<PatchArray> PatchArrayVector;
305 
307  PTable const & GetPatchTable() const { return _patches; }
308 
310  PatchArray const * GetPatchArray( Descriptor desc ) const {
311  return const_cast<PatchTables *>(this)->findPatchArray( desc );
312  }
313 
316  return _patchArrays;
317  }
318 
327  PatchArray const * GetPatchArray(int level=0) const;
328 
344  unsigned int const * GetFaceVertices(int level=0) const;
345 
361  int GetNumFaces(int level=0) const;
362 
364  VertexValenceTable const & GetVertexValenceTable() const { return _vertexValenceTable; }
365 
367  QuadOffsetTable const & GetQuadOffsetTable() const { return _quadOffsetTable; }
368 
370  PatchParamTable const & GetPatchParamTable() const { return _paramTable; }
371 
373  static short GetRegularPatchRingsize() { return 16; }
374 
376  static short GetBoundaryPatchRingsize() { return 12; }
377 
379  static short GetCornerPatchRingsize() { return 9; }
380 
382  static short GetGregoryPatchRingsize() { return 4; }
383 
385  int GetNumPatches() const;
386 
388  int GetNumControlVertices() const;
389 
391  int GetMaxValence() const { return _maxValence; }
392 
394  bool IsFeatureAdaptive() const;
395 
397  int GetNumPtexFaces() const { return _numPtexFaces; }
398 
405 
406  public:
407 
409  int GetNumChannels() const {
410  return (int)_channels.size();
411  }
412 
417  std::vector<unsigned int> const & GetPatchVertices(int channel) const {
418  return _channels[channel].patchVertIndices;
419  }
420 
421  private:
422  friend class PatchTablesFactory;
423 
424  struct Channel {
425  friend class PatchTablesFactory;
426 
427  std::vector<unsigned int> patchVertIndices; // face-varying vertex indices
428  };
429 
430  std::vector<Channel> _channels; // face-varying primvar channels
431  };
432 
434  FVarPatchTables const * GetFVarPatchTables() const { return _fvarPatchTables; }
435 
452  PatchTables(PatchArrayVector const & patchArrays,
453  PTable const & patches,
454  VertexValenceTable const * vertexValences,
455  QuadOffsetTable const * quadOffsets,
456  PatchParamTable const * patchParams,
457  FVarPatchTables const * fvarPatchTables,
458  int maxValence);
459 
461  ~PatchTables() { delete _fvarPatchTables; }
462 
463 private:
464 
465  friend class PatchTablesFactory;
466 
467  // Returns the array of patches of type "desc", or NULL if there aren't any in the primitive
468  inline PatchArray * findPatchArray( Descriptor desc );
469 
470  // Private constructor
471  PatchTables( int maxvalence ) : _fvarPatchTables(0), _maxValence(maxvalence) { }
472 
473  PatchArrayVector _patchArrays; // Vector of descriptors for arrays of patches
474 
475  PTable _patches; // Indices of the control vertices of the patches
476 
477  VertexValenceTable _vertexValenceTable; // vertex valence table (for Gregory patches)
478 
479  QuadOffsetTable _quadOffsetTable; // quad offsets table (for Gregory patches)
480 
481  PatchParamTable _paramTable;
482 
483  FVarPatchTables const * _fvarPatchTables; // sparse face-varying patch table
484 
485  // highest vertex valence allowed in the mesh (used for Gregory
486  // vertexValance & quadOffset tables)
487  int _maxValence;
488 
489  // number of total ptex faces in quads or triangles(loop)
490  int _numPtexFaces;
491 
492 };
493 
496  public:
497 
499  iterator() : _pos(-1) {}
500 
502  iterator(Descriptor desc);
503 
506 
508  bool operator == ( iterator const & other ) const {
509  return (_pos==other._pos);
510  }
511 
513  bool operator != ( iterator const & other ) const {
514  return not (*this==other);
515  }
516 
518  Descriptor const * operator -> () const {
519  return getValue();
520  }
521 
523  Descriptor const & operator * () const {
524  return *getValue();
525  }
526 
527  private:
528  inline Descriptor const * getValue() const;
529 
530  int _pos;
531 };
532 
533 // Iterator constructor
535 
536  _pos = -1;
537  std::vector<Descriptor> const & descs =
539 
540  for (int i=0; i<(int)descs.size(); ++i) {
541  if (descs[i] == desc) {
542  _pos = i;
543  break;
544  }
545  }
546 }
547 
548 // Iteration increment operator
551 
552  if (++_pos>=(int)Descriptor::GetAllValidDescriptors().size()) {
553  _pos = -1;
554  }
555  return *this;
556 }
557 
558 inline PatchTables::Descriptor const *
559 PatchTables::Descriptor::iterator::getValue() const {
560 
561  static Descriptor _nonpatch;
562 
563  std::vector<Descriptor> const & descs =
565 
566  if (_pos>=0 and _pos<(int)descs.size()) {
567  return &descs[_pos];
568  }
569 
570  return &_nonpatch;
571 }
572 
573 inline std::vector<PatchTables::Descriptor> const &
575 
576  static std::vector<Descriptor> _descriptors;
577 
578  if (_descriptors.empty()) {
579  _descriptors.reserve(55);
580 
581  // non-patch primitives
582  for (int i=POINTS; i<=LOOP; ++i) {
583  _descriptors.push_back( Descriptor(i, NON_TRANSITION, 0) );
584  }
585 
586  // non-transition patches
587  for (int i=REGULAR; i<=GREGORY_BOUNDARY; ++i) {
588  _descriptors.push_back( Descriptor(i, NON_TRANSITION, 0) );
589  }
590 
591  // transition patches
592  for (int i=PATTERN0; i<=PATTERN4; ++i) {
593 
594  _descriptors.push_back( Descriptor(REGULAR, i, 0) );
595 
596  // 4 rotations for boundary & corner patches
597  for (int j=0; j<4; ++j) {
598  _descriptors.push_back( Descriptor(BOUNDARY, i, j) );
599  }
600 
601  for (int j=0; j<4; ++j) {
602  _descriptors.push_back( Descriptor(CORNER, i, j) );
603  }
604  }
605  }
606 
607  return _descriptors;
608 }
609 
610 // Returns an iterator to the first type of patch (REGULAR NON_TRANSITION ROT0)
613  switch (type) {
614  case ANY:
615  return iterator( Descriptor(POINTS, NON_TRANSITION, 0) );
617  return iterator( Descriptor(REGULAR, NON_TRANSITION, 0) );
618  default:
619  return iterator( Descriptor() );
620  }
621 }
622 
623 // Returns an iterator to the end of the list of patch types (NON_PATCH)
626  return iterator( Descriptor() );
627 }
628 
629 // Constructor
630 inline
632  PTable const & patches,
633  VertexValenceTable const * vertexValences,
634  QuadOffsetTable const * quadOffsets,
635  PatchParamTable const * patchParams,
636  FVarPatchTables const * fvarPatchTables,
637  int maxValence) :
638  _patchArrays(patchArrays),
639  _patches(patches),
640  _fvarPatchTables(fvarPatchTables),
641  _maxValence(maxValence),
642  _numPtexFaces(0) {
643 
644  // copy other tables if exist
645  if (vertexValences)
646  _vertexValenceTable = *vertexValences;
647  if (quadOffsets)
648  _quadOffsetTable = *quadOffsets;
649  if (patchParams)
650  _paramTable = *patchParams;
651 }
652 
653 inline bool
655 
656  // the vertex valence table is only used by Gregory patches, so the PatchTables
657  // contain feature adaptive patches if this is not empty.
658  if (not _vertexValenceTable.empty())
659  return true;
660 
661  PatchArrayVector const & parrays = GetPatchArrayVector();
662 
663  // otherwise, we have to check each patch array
664  for (int i=0; i<(int)parrays.size(); ++i) {
665 
666  if (parrays[i].GetDescriptor().GetType() >= REGULAR and
667  parrays[i].GetDescriptor().GetType() <= GREGORY_BOUNDARY)
668  return true;
669 
670  }
671  return false;
672 }
673 
674 // Returns the number of control vertices expected for a patch of this type
675 inline short
677  switch (type) {
679  case QUADS : return 4;
680  case GREGORY :
684  case TRIANGLES : return 3;
685  case LINES : return 2;
686  case POINTS : return 1;
687  default : return -1;
688  }
689 }
690 
691 // Returns the total number of control vertex indices in the tables
692 inline int
694 
695  int result=0;
696  for (int i=0; i<(int)_patchArrays.size(); ++i) {
697  result += _patchArrays[i].GetDescriptor().GetNumControlVertices() *
698  _patchArrays[i].GetNumPatches();
699  }
700 
701  return result;
702 }
703 
704 // Returns the number of face-varying control vertices expected for a patch of this type
705 inline short
707  switch (type) {
708  case REGULAR : // We only support bilinear interpolation for now,
709  case QUADS : // so all these patches only carry 4 CVs.
710  case GREGORY :
711  case GREGORY_BOUNDARY :
712  case BOUNDARY :
713  case CORNER : return 4;
714  case TRIANGLES : return 3;
715  case LINES : return 2;
716  case POINTS : return 1;
717  default : return -1;
718  }
719 }
720 
721 // Returns a pointer to the PatchArry of uniformly subdivided faces at 'level'
722 inline PatchTables::PatchArray const *
723 PatchTables::GetPatchArray(int level) const {
724 
725  if (IsFeatureAdaptive())
726  return NULL;
727 
728  PatchArrayVector const & parrays = GetPatchArrayVector();
729 
730  if (parrays.empty())
731  return NULL;
732 
733  if (level < 1) {
734  return &(*parrays.rbegin());
735  } else if ((level-1) < (int)parrays.size() ) {
736  return &parrays[level-1];
737  }
738 
739  return NULL;
740 }
741 
742 // Returns a pointer to the vertex indices of uniformly subdivided faces
743 inline unsigned int const *
745 
746  PatchArray const * parray = GetPatchArray(level);
747 
748  if (parray) {
749  return &GetPatchTable()[ parray->GetVertIndex() ];
750  }
751  return NULL;
752 }
753 
754 // Returns the number of faces in a uniformly subdivided mesh at a given level
755 inline int
756 PatchTables::GetNumFaces(int level) const {
757 
758  PatchArray const * parray = GetPatchArray(level);
759 
760  if (parray) {
761  return parray->GetNumPatches();
762  }
763  return -1;
764 }
765 
766 // Allows ordering of patches by type
767 inline bool
769  return _pattern < other._pattern or ((_pattern == other._pattern) and
770  (_type < other._type or ((_type == other._type) and
771  (_rotation < other._rotation))));
772 }
773 
774 // True if the descriptors are identical
775 inline bool
777  return _pattern == other._pattern and
778  _type == other._type and
779  _rotation == other._rotation;
780 }
781 
782 // Returns a pointer to the array of patches matching the descriptor
784 PatchTables::findPatchArray( PatchTables::Descriptor desc ) {
785 
786  for (int i=0; i<(int)_patchArrays.size(); ++i) {
787  if (_patchArrays[i].GetDescriptor()==desc)
788  return &_patchArrays[i];
789  }
790  return 0;
791 }
792 
793 // Returns the total number of patches stored in the tables
794 inline int
796  // there is one PatchParam record for each patch in the mesh
797  return (int)GetPatchParamTable().size();
798 }
799 
800 } // end namespace Far
801 
802 } // end namespace OPENSUBDIV_VERSION
803 using namespace OPENSUBDIV_VERSION;
804 
805 } // end namespace OpenSubdiv
806 
807 #endif /* FAR_PATCH_TABLES */
808 
unsigned char GetRotation() const
Returns the rotation of the patch (4 rotations)
Definition: patchTables.h:128
TransitionPattern GetPattern() const
Returns the transition pattern of the patch if any (5 types)
Definition: patchTables.h:123
PatchArray const * GetPatchArray(Descriptor desc) const
Returns a pointer to the array of patches matching the descriptor.
Definition: patchTables.h:310
Container for patch vertex indices tables.
Definition: patchTables.h:49
Describes the range of patches in a PatchArray.
Definition: patchTables.h:245
ArrayRange const & GetArrayRange() const
Returns a array range struct.
Definition: patchTables.h:270
int GetNumFaces(int level=0) const
Returns the number of faces in a uniformly subdivided mesh at a given level.
Definition: patchTables.h:756
PatchParamTable const & GetPatchParamTable() const
Returns a PatchParamTable for each type of patch.
Definition: patchTables.h:370
bool IsFeatureAdaptive() const
True if the patches are of feature adaptive types.
Definition: patchTables.h:654
static short GetRegularPatchRingsize()
Ringsize of Regular Patches in table.
Definition: patchTables.h:373
unsigned int GetVertIndex() const
Returns the index of the first control vertex of the first patch of this array in the global PTable...
Definition: patchTables.h:276
Descriptor(Descriptor const &d)
Copy Constructor.
Definition: patchTables.h:114
std::vector< unsigned int > const & GetPatchVertices(int channel) const
Returns the face-varying patches vertex indices.
Definition: patchTables.h:417
int GetNumPatches() const
Returns the total number of patches stored in the tables.
Definition: patchTables.h:795
Descriptor const * operator->() const
Dereferencing operator.
Definition: patchTables.h:518
static iterator begin(PrimType type)
Returns a patch type iterator.
Definition: patchTables.h:612
PatchArray(Descriptor desc, unsigned int vertIndex, unsigned int patchIndex, unsigned int npatches, unsigned int quadOffsetIndex)
Constructor.
Definition: patchTables.h:236
unsigned int const * GetFaceVertices(int level=0) const
Returns a pointer to the vertex indices of uniformly subdivided faces.
Definition: patchTables.h:744
Descriptor(int type, int pattern, unsigned char rotation)
Constructor.
Definition: patchTables.h:110
ArrayRange(unsigned int ivertIndex, unsigned int ipatchIndex, unsigned int inpatches, unsigned int iquadOffsetIndex)
Constructor.
Definition: patchTables.h:260
int GetNumChannels() const
Returns the number of face-varying primvar channels.
Definition: patchTables.h:409
short GetNumFVarControlVertices() const
Returns the number of control vertices expected for a patch of the type described.
Definition: patchTables.h:146
static short GetCornerPatchRingsize()
Ringsize of Boundary Patches in table.
Definition: patchTables.h:379
bool operator==(Descriptor const other) const
True if the descriptors are identical.
Definition: patchTables.h:776
std::vector< unsigned int > QuadOffsetTable
Definition: patchTables.h:54
static std::vector< Descriptor > const & GetAllValidDescriptors()
Returns a vector of all the legal patch descriptors.
Definition: patchTables.h:574
bool operator==(iterator const &other) const
True of the two descriptors are identical.
Definition: patchTables.h:508
Descriptor GetDescriptor() const
Returns a patch descriptor defining the type of patches in the array.
Definition: patchTables.h:240
int GetNumPtexFaces() const
Returns the total number of vertices in the mesh across across all depths.
Definition: patchTables.h:397
unsigned int GetPatchIndex() const
Returns the global index of the first patch in this array (Used to access param / fvar table data) ...
Definition: patchTables.h:282
bool operator<(Descriptor const other) const
Allows ordering of patches by type.
Definition: patchTables.h:768
unsigned int GetNumPatches() const
Returns the number of patches in the array.
Definition: patchTables.h:287
bool operator!=(iterator const &other) const
True if the two descriptors are different.
Definition: patchTables.h:513
PatchArrayVector const & GetPatchArrayVector() const
Returns all arrays of patches.
Definition: patchTables.h:315
unsigned int GetQuadOffsetIndex() const
Returns the index to the first entry in the QuadOffsetTable.
Definition: patchTables.h:292
Describes an array of patches of the same type.
Definition: patchTables.h:217
PatchTables(PatchArrayVector const &patchArrays, PTable const &patches, VertexValenceTable const *vertexValences, QuadOffsetTable const *quadOffsets, PatchParamTable const *patchParams, FVarPatchTables const *fvarPatchTables, int maxValence)
Public constructor.
Definition: patchTables.h:631
PTable const & GetPatchTable() const
Get the table of patch control vertices.
Definition: patchTables.h:307
VertexValenceTable const & GetVertexValenceTable() const
Returns a vertex valence table used by Gregory patches.
Definition: patchTables.h:364
QuadOffsetTable const & GetQuadOffsetTable() const
Returns a quad offsets table used by Gregory patches.
Definition: patchTables.h:367
static short GetBoundaryPatchRingsize()
Ringsize of Boundary Patches in table.
Definition: patchTables.h:376
int GetMaxValence() const
Returns max vertex valence.
Definition: patchTables.h:391
FVarPatchTables const * GetFVarPatchTables() const
Returns the face-varying patches.
Definition: patchTables.h:434
static short GetGregoryPatchRingsize()
Ringsize of Gregory (and Gregory Boundary) Patches in table.
Definition: patchTables.h:382
A specialized factory for feature adaptive PatchTables.
Descriptor const & operator*() const
Dereferencing operator.
Definition: patchTables.h:523
Type GetType() const
Returns the type of the patch.
Definition: patchTables.h:118
short GetNumControlVertices() const
Returns the number of control vertices expected for a patch of the type described.
Definition: patchTables.h:140
int GetNumControlVertices() const
Returns the total number of control vertex indices in the tables.
Definition: patchTables.h:693
static iterator end()
Returns an iterator to the end of the list of patch types (NON_PATCH)
Definition: patchTables.h:625