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 OPENSUBDIV3_FAR_PATCH_TABLE_H
26 #define OPENSUBDIV3_FAR_PATCH_TABLE_H
27 
28 #include "../version.h"
29 
30 #include "../far/patchDescriptor.h"
31 #include "../far/patchParam.h"
32 #include "../far/stencilTable.h"
33 
34 #include "../sdc/options.h"
35 
36 #include <vector>
37 
38 namespace OpenSubdiv {
39 namespace OPENSUBDIV_VERSION {
40 
41 namespace Far {
42 
43 /// \brief Container for arrays of parametric patches
44 ///
45 /// PatchTable contains topology and parametric information about the patches
46 /// generated by the Refinement process. Patches in the table are sorted into
47 /// arrays based on their PatchDescriptor Type.
48 ///
49 /// Note : PatchTable can be accessed either using a PatchHandle or a
50 ///        combination of array and patch indices.
51 ///
52 /// XXXX manuelk we should add a PatchIterator that can dereference into
53 ///              a PatchHandle for fast linear traversal of the table
54 ///
55 class PatchTable {
56 
57 public:
58 
59     /// \brief Handle that can be used as unique patch identifier within PatchTable
60     class PatchHandle {
61     // XXXX manuelk members will eventually be made private
62     public:
63 
64         friend class PatchTable;
65         friend class PatchMap;
66 
67         Index arrayIndex, // Array index of the patch
68               patchIndex, // Absolute Index of the patch
69               vertIndex;  // Relative offset to the first CV of the patch in array
70     };
71 
72 public:
73 
74     /// \brief Copy constructor
75     PatchTable(PatchTable const & src);
76 
77     /// \brief Destructor
78     ~PatchTable();
79 
80     /// \brief True if the patches are of feature adaptive types
81     bool IsFeatureAdaptive() const;
82 
83     /// \brief Returns the total number of control vertex indices in the table
GetNumControlVerticesTotal()84     int GetNumControlVerticesTotal() const {
85         return (int)_patchVerts.size();
86     }
87 
88     /// \brief Returns the total number of patches stored in the table
89     int GetNumPatchesTotal() const;
90 
91     /// \brief Returns max vertex valence
GetMaxValence()92     int GetMaxValence() const { return _maxValence; }
93 
94     /// \brief Returns the total number of ptex faces in the mesh
GetNumPtexFaces()95     int GetNumPtexFaces() const { return _numPtexFaces; }
96 
97 
98     //@{
99     ///  @name Individual patches
100     ///
101     /// \anchor individual_patches
102     ///
103     /// \brief Accessors for individual patches
104     ///
105 
106     /// \brief Returns the PatchDescriptor for the patch identified by \p handle
107     PatchDescriptor GetPatchDescriptor(PatchHandle const & handle) const;
108 
109     /// \brief Returns the control vertex indices for the patch identified by \p handle
110     ConstIndexArray GetPatchVertices(PatchHandle const & handle) const;
111 
112     /// \brief Returns a PatchParam for the patch identified by \p handle
113     PatchParam GetPatchParam(PatchHandle const & handle) const;
114 
115     /// \brief Returns the control vertex indices for \p patch in \p array
116     ConstIndexArray GetPatchVertices(int array, int patch) const;
117 
118     /// \brief Returns the PatchParam for \p patch in \p array
119     PatchParam GetPatchParam(int array, int patch) const;
120     //@}
121 
122 
123     //@{
124     ///  @name Arrays of patches
125     ///
126     /// \anchor arrays_of_patches
127     ///
128     /// \brief Accessors for arrays of patches of the same type
129     ///
130 
131     /// \brief Returns the number of patch arrays in the table
132     int GetNumPatchArrays() const;
133 
134     /// \brief Returns the number of patches in \p array
135     int GetNumPatches(int array) const;
136 
137     /// \brief Returns the number of control vertices in \p array
138     int GetNumControlVertices(int array) const;
139 
140     /// \brief Returns the PatchDescriptor for the patches in \p array
141     PatchDescriptor GetPatchArrayDescriptor(int array) const;
142 
143     /// \brief Returns the control vertex indices for the patches in \p array
144     ConstIndexArray GetPatchArrayVertices(int array) const;
145 
146     /// \brief Returns the PatchParams for the patches in \p array
147     ConstPatchParamArray const GetPatchParams(int array) const;
148     //@}
149 
150 
151     //@{
152     ///  @name Change of basis patches
153     ///
154     /// \anchor change_of_basis_patches
155     ///
156     /// \brief Accessors for change of basis patches
157     ///
158     ///
159 
160     /// \brief Returns the number of local vertex points.
161     int GetNumLocalPoints() const;
162 
163     /// \brief Returns the stencil table to compute local point vertex values
164     StencilTable const *GetLocalPointStencilTable() const;
165 
166     /// \brief Returns the stencil table to compute local point vertex values
167     template <typename REAL>
168     StencilTableReal<REAL> const *GetLocalPointStencilTable() const;
169 
170     /// \brief Tests if the precision of the stencil table to compute local point
171     /// vertex values matches the given floating point type \<REAL\>.
172     template <typename REAL> bool LocalPointStencilPrecisionMatchesType() const;
173 
174     /// \brief Updates local point vertex values.
175     ///
176     /// @param src       Buffer with primvar data for the base and refined
177     ///                  vertex values
178     ///
179     /// @param dst       Destination buffer for the computed local point
180     ///                  vertex values
181     ///
182     /// For more flexibility computing local vertex points, retrieval of
183     /// the local point stencil table and use of its public methods is
184     /// recommended or often required.
185     ///
186     template <class T> void
187     ComputeLocalPointValues(T const *src, T *dst) const;
188 
189 
190     /// \brief Returns the number of local varying points.
191     int GetNumLocalPointsVarying() const;
192 
193     /// \brief Returns the stencil table to compute local point varying values
194     StencilTable const *GetLocalPointVaryingStencilTable() const;
195 
196     /// \brief Returns the stencil table to compute local point varying values
197     template <typename REAL>
198     StencilTableReal<REAL> const *GetLocalPointVaryingStencilTable() const;
199 
200     /// \brief Tests if the precision of the stencil table to compute local point
201     /// varying values matches the given floating point type \<REAL\>.
202     template <typename REAL> bool LocalPointVaryingStencilPrecisionMatchesType() const;
203 
204     /// \brief Updates local point varying values.
205     ///
206     /// @param src       Buffer with primvar data for the base and refined
207     ///                  varying values
208     ///
209     /// @param dst       Destination buffer for the computed local point
210     ///                  varying values
211     ///
212     /// For more flexibility computing local varying points, retrieval of
213     /// the local point varying stencil table and use of its public methods
214     /// is recommended or often required.
215     ///
216     template <class T> void
217     ComputeLocalPointValuesVarying(T const *src, T *dst) const;
218 
219 
220     /// \brief Returns the number of local face-varying points for \p channel
221     int GetNumLocalPointsFaceVarying(int channel = 0) const;
222 
223     /// \brief Returns the stencil table to compute local point face-varying values
224     StencilTable const *GetLocalPointFaceVaryingStencilTable(int channel = 0) const;
225 
226     /// \brief Returns the stencil table to compute local point face-varying values
227     template <typename REAL>
228     StencilTableReal<REAL> const * GetLocalPointFaceVaryingStencilTable(int channel = 0) const;
229 
230     /// \brief Tests if the precision of the stencil table to compute local point
231     /// face-varying values matches the given floating point type \<REAL\>.
232     template <typename REAL> bool LocalPointFaceVaryingStencilPrecisionMatchesType() const;
233 
234     /// \brief Updates local point face-varying values.
235     ///
236     /// @param src       Buffer with primvar data for the base and refined
237     ///                  face-varying values
238     ///
239     /// @param dst       Destination buffer for the computed local point
240     ///                  face-varying values
241     ///
242     /// @param channel   face-varying channel
243     ///
244     /// For more flexibility computing local face-varying points, retrieval
245     /// of the local point face-varying stencil table and use of its public
246     /// methods is recommended or often required.
247     ///
248     template <class T> void
249     ComputeLocalPointValuesFaceVarying(T const *src, T *dst, int channel = 0) const;
250     //@}
251 
252 
253     //@{
254     ///  @name Legacy gregory patch evaluation buffers
255 
256     /// \brief Accessors for the gregory patch evaluation buffers.
257     ///        These methods will be deprecated.
258     ///
259     typedef Vtr::ConstArray<unsigned int> ConstQuadOffsetsArray;
260 
261     /// \brief Returns the 'QuadOffsets' for the Gregory patch identified by \p handle
262     ConstQuadOffsetsArray GetPatchQuadOffsets(PatchHandle const & handle) const;
263 
264     typedef std::vector<Index> VertexValenceTable;
265 
266     /// \brief Returns the 'VertexValences' table (vertex neighborhoods table)
GetVertexValenceTable()267     VertexValenceTable const & GetVertexValenceTable() const {
268         return _vertexValenceTable;
269     }
270     //@}
271 
272 
273     //@{
274     ///  @name Single-crease patches
275     ///
276     /// \anchor single_crease_patches
277     ///
278     /// \brief Accessors for single-crease patch edge sharpness
279     ///
280 
281     /// \brief Returns the crease sharpness for the patch identified by \p handle
282     ///        if it is a single-crease patch, or 0.0f
283     float GetSingleCreasePatchSharpnessValue(PatchHandle const & handle) const;
284 
285     /// \brief Returns the crease sharpness for the \p patch in \p array
286     ///        if it is a single-crease patch, or 0.0f
287     float GetSingleCreasePatchSharpnessValue(int array, int patch) const;
288     //@}
289 
290 
291     //@{
292     ///  @name Varying data
293     ///
294     /// \anchor varying_data
295     ///
296     /// \brief Accessors for varying data
297     ///
298 
299     /// \brief Returns the varying patch descriptor
300     PatchDescriptor GetVaryingPatchDescriptor() const;
301 
302     /// \brief Returns the varying vertex indices for a given patch
303     ConstIndexArray GetPatchVaryingVertices(PatchHandle const & handle) const;
304 
305     /// \brief Returns the varying vertex indices for a given patch
306     ConstIndexArray GetPatchVaryingVertices(int array, int patch) const;
307 
308     /// \brief Returns the varying vertex indices for the patches in \p array
309     ConstIndexArray GetPatchArrayVaryingVertices(int array) const;
310 
311     /// \brief Returns an array of varying vertex indices for the patches.
312     ConstIndexArray GetVaryingVertices() const;
313     //@}
314 
315 
316     //@{
317     ///  @name Face-varying channels
318     ///
319     /// \anchor face_varying_channels
320     ///
321     /// \brief Accessors for face-varying channels
322     ///
323 
324     /// \brief Returns the number of face-varying channels
325     int GetNumFVarChannels() const;
326 
327     /// \brief Returns the regular patch descriptor for \p channel
328     PatchDescriptor GetFVarPatchDescriptorRegular(int channel = 0) const;
329 
330     /// \brief Returns the irregular patch descriptor for \p channel
331     PatchDescriptor GetFVarPatchDescriptorIrregular(int channel = 0) const;
332 
333     /// \brief Returns the default/irregular patch descriptor for \p channel
334     PatchDescriptor GetFVarPatchDescriptor(int channel = 0) const;
335 
336     /// \brief Returns the value indices for a given patch in \p channel
337     ConstIndexArray GetPatchFVarValues(PatchHandle const & handle, int channel = 0) const;
338 
339     /// \brief Returns the value indices for a given patch in \p channel
340     ConstIndexArray GetPatchFVarValues(int array, int patch, int channel = 0) const;
341 
342     /// \brief Returns the value indices for the patches in \p array in \p channel
343     ConstIndexArray GetPatchArrayFVarValues(int array, int channel = 0) const;
344 
345     /// \brief Returns an array of value indices for the patches in \p channel
346     ConstIndexArray GetFVarValues(int channel = 0) const;
347 
348     /// \brief Returns the stride between patches in the value index array of \p channel
349     int GetFVarValueStride(int channel = 0) const;
350 
351     /// \brief Returns the value indices for a given patch in \p channel
352     PatchParam GetPatchFVarPatchParam(PatchHandle const & handle, int channel = 0) const;
353 
354     /// \brief Returns the face-varying params for a given patch \p channel
355     PatchParam GetPatchFVarPatchParam(int array, int patch, int channel = 0) const;
356 
357     /// \brief Returns the face-varying for a given patch in \p array in \p channel
358     ConstPatchParamArray GetPatchArrayFVarPatchParams(int array, int channel = 0) const;
359 
360     /// \brief Returns an array of face-varying patch param for \p channel
361     ConstPatchParamArray GetFVarPatchParams(int channel = 0) const;
362 
363     /// \brief Deprecated @see PatchTable#GetFVarPatchDescriptor
364     Sdc::Options::FVarLinearInterpolation GetFVarChannelLinearInterpolation(int channel = 0) const;
365     //@}
366 
367 
368     //@{
369     ///  @name Direct accessors
370     ///
371     /// \warning These direct accessors are left for convenience, but they are
372     ///          likely going to be deprecated in future releases
373     ///
374 
375     typedef std::vector<Index> PatchVertsTable;
376 
377     /// \brief Get the table of patch control vertices
GetPatchControlVerticesTable()378     PatchVertsTable const & GetPatchControlVerticesTable() const { return _patchVerts; }
379 
380     /// \brief Returns the PatchParamTable (PatchParams order matches patch array sorting)
GetPatchParamTable()381     PatchParamTable const & GetPatchParamTable() const { return _paramTable; }
382 
383     /// \brief Returns a sharpness index table for each patch (if exists)
GetSharpnessIndexTable()384     std::vector<Index> const &GetSharpnessIndexTable() const { return _sharpnessIndices; }
385 
386     /// \brief Returns sharpness values table
GetSharpnessValues()387     std::vector<float> const &GetSharpnessValues() const { return _sharpnessValues; }
388 
389     typedef std::vector<unsigned int> QuadOffsetsTable;
390 
391     /// \brief Returns the quad-offsets table
GetQuadOffsetsTable()392     QuadOffsetsTable const & GetQuadOffsetsTable() const {
393         return _quadOffsetsTable;
394     }
395     //@}
396 
397     /// debug helper
398     void print() const;
399 
400 public:
401 
402     //@{
403     ///  @name Evaluation methods
404     ///
405 
406     /// \brief Evaluate basis functions for position and derivatives at a
407     /// given (u,v) parametric location of a patch.
408     ///
409     /// @param handle  A patch handle identifying the sub-patch containing the
410     ///                (u,v) location
411     ///
412     /// @param u       Patch coordinate (in base face normalized space)
413     ///
414     /// @param v       Patch coordinate (in base face normalized space)
415     ///
416     /// @param wP      Weights (evaluated basis functions) for the position
417     ///
418     /// @param wDu     Weights (evaluated basis functions) for derivative wrt u
419     ///
420     /// @param wDv     Weights (evaluated basis functions) for derivative wrt v
421     ///
422     /// @param wDuu    Weights (evaluated basis functions) for 2nd derivative wrt u
423     ///
424     /// @param wDuv    Weights (evaluated basis functions) for 2nd derivative wrt u and v
425     ///
426     /// @param wDvv    Weights (evaluated basis functions) for 2nd derivative wrt v
427     ///
428     template <typename REAL>
429     void EvaluateBasis(PatchHandle const & handle, REAL u, REAL v,
430         REAL wP[], REAL wDu[] = 0, REAL wDv[] = 0,
431         REAL wDuu[] = 0, REAL wDuv[] = 0, REAL wDvv[] = 0) const;
432 
433     /// \brief  An overloaded version to assist template parameter resolution
434     /// when explicitly declaring unused array arguments as 0.
435     void EvaluateBasis(PatchHandle const & handle, float u, float v,
436         float wP[], float wDu[] = 0, float wDv[] = 0,
437         float wDuu[] = 0, float wDuv[] = 0, float wDvv[] = 0) const;
438 
439     /// \brief  An overloaded version to assist template parameter resolution
440     /// when explicitly declaring unused array arguments as 0.
441     void EvaluateBasis(PatchHandle const & handle, double u, double v,
442         double wP[], double wDu[] = 0, double wDv[] = 0,
443         double wDuu[] = 0, double wDuv[] = 0, double wDvv[] = 0) const;
444 
445     /// \brief Evaluate basis functions for a varying value and
446     /// derivatives at a given (u,v) parametric location of a patch.
447     ///
448     /// @param handle  A patch handle identifying the sub-patch containing the
449     ///                (u,v) location
450     ///
451     /// @param u       Patch coordinate (in base face normalized space)
452     ///
453     /// @param v       Patch coordinate (in base face normalized space)
454     ///
455     /// @param wP      Weights (evaluated basis functions) for the position
456     ///
457     /// @param wDu     Weights (evaluated basis functions) for derivative wrt u
458     ///
459     /// @param wDv     Weights (evaluated basis functions) for derivative wrt v
460     ///
461     /// @param wDuu    Weights (evaluated basis functions) for 2nd derivative wrt u
462     ///
463     /// @param wDuv    Weights (evaluated basis functions) for 2nd derivative wrt u and v
464     ///
465     /// @param wDvv    Weights (evaluated basis functions) for 2nd derivative wrt v
466     ///
467     template <typename REAL>
468     void EvaluateBasisVarying(PatchHandle const & handle, REAL u, REAL v,
469         REAL wP[], REAL wDu[] = 0, REAL wDv[] = 0,
470         REAL wDuu[] = 0, REAL wDuv[] = 0, REAL wDvv[] = 0) const;
471 
472     /// \brief  An overloaded version to assist template parameter resolution
473     /// when explicitly declaring unused array arguments as 0.
474     void EvaluateBasisVarying(PatchHandle const & handle, float u, float v,
475         float wP[], float wDu[] = 0, float wDv[] = 0,
476         float wDuu[] = 0, float wDuv[] = 0, float wDvv[] = 0) const;
477 
478     /// \brief  An overloaded version to assist template parameter resolution
479     /// when explicitly declaring unused array arguments as 0.
480     void EvaluateBasisVarying(PatchHandle const & handle, double u, double v,
481         double wP[], double wDu[] = 0, double wDv[] = 0,
482         double wDuu[] = 0, double wDuv[] = 0, double wDvv[] = 0) const;
483 
484     /// \brief Evaluate basis functions for a face-varying value and
485     /// derivatives at a given (u,v) parametric location of a patch.
486     ///
487     /// @param handle  A patch handle identifying the sub-patch containing the
488     ///                (u,v) location
489     ///
490     /// @param u       Patch coordinate (in base face normalized space)
491     ///
492     /// @param v       Patch coordinate (in base face normalized space)
493     ///
494     /// @param wP      Weights (evaluated basis functions) for the position
495     ///
496     /// @param wDu     Weights (evaluated basis functions) for derivative wrt u
497     ///
498     /// @param wDv     Weights (evaluated basis functions) for derivative wrt v
499     ///
500     /// @param wDuu    Weights (evaluated basis functions) for 2nd derivative wrt u
501     ///
502     /// @param wDuv    Weights (evaluated basis functions) for 2nd derivative wrt u and v
503     ///
504     /// @param wDvv    Weights (evaluated basis functions) for 2nd derivative wrt v
505     ///
506     /// @param channel face-varying channel
507     ///
508     template <typename REAL>
509     void EvaluateBasisFaceVarying(PatchHandle const & handle, REAL u, REAL v,
510         REAL wP[], REAL wDu[] = 0, REAL wDv[] = 0,
511         REAL wDuu[] = 0, REAL wDuv[] = 0, REAL wDvv[] = 0,
512         int channel = 0) const;
513 
514     /// \brief  An overloaded version to assist template parameter resolution
515     /// when explicitly declaring unused array arguments as 0.
516     void EvaluateBasisFaceVarying(PatchHandle const & handle, float u, float v,
517         float wP[], float wDu[] = 0, float wDv[] = 0,
518         float wDuu[] = 0, float wDuv[] = 0, float wDvv[] = 0,
519         int channel = 0) const;
520 
521     /// \brief  An overloaded version to assist template parameter resolution
522     /// when explicitly declaring unused array arguments as 0.
523     void EvaluateBasisFaceVarying(PatchHandle const & handle, double u, double v,
524         double wP[], double wDu[] = 0, double wDv[] = 0,
525         double wDuu[] = 0, double wDuv[] = 0, double wDvv[] = 0,
526         int channel = 0) const;
527     //@}
528 
529 protected:
530 
531     friend class PatchTableBuilder;
532 
533     // Factory constructor
534     PatchTable(int maxvalence);
535 
536     Index getPatchIndex(int array, int patch) const;
537 
538     PatchParamArray getPatchParams(int arrayIndex);
539 
540     Index * getSharpnessIndices(Index arrayIndex);
541     float * getSharpnessValues(Index arrayIndex);
542 
543 private:
544 
545     //
546     // Patch arrays
547     //
548 
549     struct PatchArray;
550     typedef std::vector<PatchArray> PatchArrayVector;
551 
552     PatchArray & getPatchArray(Index arrayIndex);
553     PatchArray const & getPatchArray(Index arrayIndex) const;
554 
555     void reservePatchArrays(int numPatchArrays);
556     void pushPatchArray(PatchDescriptor desc, int npatches,
557         Index * vidx, Index * pidx, Index * qoidx=0);
558 
559     IndexArray getPatchArrayVertices(int arrayIndex);
560 
561     Index findPatchArray(PatchDescriptor desc);
562 
563 
564     //
565     // Varying patch arrays
566     //
567     IndexArray getPatchArrayVaryingVertices(int arrayIndex);
568 
569     void allocateVaryingVertices(
570         PatchDescriptor desc, int numPatches);
571     void populateVaryingVertices();
572 
573     //
574     // Face-varying patch channels
575     //
576 
577     struct FVarPatchChannel;
578     typedef std::vector<FVarPatchChannel> FVarPatchChannelVector;
579 
580     FVarPatchChannel & getFVarPatchChannel(int channel);
581     FVarPatchChannel const & getFVarPatchChannel(int channel) const;
582 
583     void allocateFVarPatchChannels(int numChannels);
584     void allocateFVarPatchChannelValues(
585         PatchDescriptor regDesc, PatchDescriptor irregDesc,
586         int numPatches, int channel);
587 
588     // deprecated
589     void setFVarPatchChannelLinearInterpolation(
590         Sdc::Options::FVarLinearInterpolation interpolation, int channel);
591 
592     IndexArray getFVarValues(int channel);
593     ConstIndexArray getPatchFVarValues(int patch, int channel) const;
594 
595     PatchParamArray getFVarPatchParams(int channel);
596     PatchParam getPatchFVarPatchParam(int patch, int channel) const;
597 
598 private:
599     //
600     //  Simple private class to hold stencil table pointers of varying precision,
601     //  where the discriminant of the precision is external.
602     //
603     //  NOTE that this is a simple pointer container and NOT a smart pointer that
604     //  manages the ownership of the object referred to by it.
605     //
606     class StencilTablePtr {
607     private:
608         typedef StencilTableReal<float>  float_type;
609         typedef StencilTableReal<double> double_type;
610 
611         union {
612             float_type  * _fPtr;
613             double_type * _dPtr;
614         };
615 
616     public:
StencilTablePtr()617         StencilTablePtr()                  { _fPtr = 0; }
StencilTablePtr(float_type * ptr)618         StencilTablePtr(float_type  * ptr) { _fPtr = ptr; }
StencilTablePtr(double_type * ptr)619         StencilTablePtr(double_type * ptr) { _dPtr = ptr; }
620 
621         operator bool() const { return _fPtr != 0; }
622 
Set()623         void Set()                  { _fPtr = 0; }
Set(float_type * ptr)624         void Set(float_type  * ptr) { _fPtr = ptr; }
Set(double_type * ptr)625         void Set(double_type * ptr) { _dPtr = ptr; }
626 
627         template <typename REAL> StencilTableReal<REAL> * Get() const;
628     };
629 
630 private:
631 
632     //
633     // Topology
634     //
635 
636     int _maxValence,   // highest vertex valence found in the mesh
637         _numPtexFaces; // total number of ptex faces
638 
639     PatchArrayVector     _patchArrays;  // Vector of descriptors for arrays of patches
640 
641     std::vector<Index>   _patchVerts;   // Indices of the control vertices of the patches
642 
643     PatchParamTable      _paramTable;   // PatchParam bitfields (one per patch)
644 
645     //
646     // Extraordinary vertex closed-form evaluation / endcap basis conversion
647     //
648     // XXXtakahito: these data will probably be replaced with mask coefficient or something
649     //              SchemeWorker populates.
650     //
651     QuadOffsetsTable     _quadOffsetsTable;   // Quad offsets (for Gregory patches)
652     VertexValenceTable   _vertexValenceTable; // Vertex valence table (for Gregory patches)
653 
654     StencilTablePtr _localPointStencils;        // local point conversion stencils
655     StencilTablePtr _localPointVaryingStencils; // local point varying stencils
656 
657     //
658     // Varying data
659     //
660     PatchDescriptor _varyingDesc;
661 
662     std::vector<Index>   _varyingVerts;
663 
664     //
665     // Face-varying data
666     //
667     FVarPatchChannelVector _fvarChannels;
668 
669     std::vector<StencilTablePtr> _localPointFaceVaryingStencils;
670 
671     //
672     // 'single-crease' patch sharpness tables
673     //
674     std::vector<Index>   _sharpnessIndices; // Indices of single-crease sharpness (one per patch)
675     std::vector<float>   _sharpnessValues;  // Sharpness values.
676 
677     //
678     //  Construction history -- relevant to at least one public query:
679     //
680     unsigned int _isUniformLinear : 1;
681 
682     //
683     //  Precision -- only applies to local-point stencil tables
684     //
685     unsigned int _vertexPrecisionIsDouble      : 1;
686     unsigned int _varyingPrecisionIsDouble     : 1;
687     unsigned int _faceVaryingPrecisionIsDouble : 1;
688 };
689 
690 
691 //
692 //  Template specializations for float/double -- to be defined before used:
693 //
694 template <> inline StencilTableReal<float> *
695 PatchTable::StencilTablePtr::Get<float>() const { return _fPtr; }
696 
697 template <> inline StencilTableReal<double> *
698 PatchTable::StencilTablePtr::Get<double>() const { return _dPtr; }
699 
700 template <> inline bool
701 PatchTable::LocalPointStencilPrecisionMatchesType<float>() const {
702     return !_vertexPrecisionIsDouble;
703 }
704 template <> inline bool
705 PatchTable::LocalPointVaryingStencilPrecisionMatchesType<float>() const {
706     return !_varyingPrecisionIsDouble;
707 }
708 template <> inline bool
709 PatchTable::LocalPointFaceVaryingStencilPrecisionMatchesType<float>() const {
710     return !_faceVaryingPrecisionIsDouble;
711 }
712 
713 template <> inline bool
714 PatchTable::LocalPointStencilPrecisionMatchesType<double>() const {
715     return _vertexPrecisionIsDouble;
716 }
717 template <> inline bool
718 PatchTable::LocalPointVaryingStencilPrecisionMatchesType<double>() const {
719     return _varyingPrecisionIsDouble;
720 }
721 template <> inline bool
722 PatchTable::LocalPointFaceVaryingStencilPrecisionMatchesType<double>() const {
723     return _faceVaryingPrecisionIsDouble;
724 }
725 
726 //
727 //  StencilTable access -- backward compatible and generic:
728 //
729 inline StencilTable const *
GetLocalPointStencilTable()730 PatchTable::GetLocalPointStencilTable() const {
731     assert(LocalPointStencilPrecisionMatchesType<float>());
732     return static_cast<StencilTable const *>(_localPointStencils.Get<float>());
733 }
734 inline StencilTable const *
GetLocalPointVaryingStencilTable()735 PatchTable::GetLocalPointVaryingStencilTable() const {
736     assert(LocalPointVaryingStencilPrecisionMatchesType<float>());
737     return static_cast<StencilTable const *>(
738             _localPointVaryingStencils.Get<float>());
739 }
740 inline StencilTable const *
GetLocalPointFaceVaryingStencilTable(int channel)741 PatchTable::GetLocalPointFaceVaryingStencilTable(int channel) const {
742     assert(LocalPointFaceVaryingStencilPrecisionMatchesType<float>());
743     if (channel >= 0 && channel < (int)_localPointFaceVaryingStencils.size()) {
744         return static_cast<StencilTable const *>(
745                 _localPointFaceVaryingStencils[channel].Get<float>());
746     }
747     return NULL;
748 }
749 
750 template <typename REAL>
751 inline StencilTableReal<REAL> const *
GetLocalPointStencilTable()752 PatchTable::GetLocalPointStencilTable() const {
753     assert(LocalPointStencilPrecisionMatchesType<REAL>());
754     return _localPointStencils.Get<REAL>();
755 }
756 template <typename REAL>
757 inline StencilTableReal<REAL> const *
GetLocalPointVaryingStencilTable()758 PatchTable::GetLocalPointVaryingStencilTable() const {
759     assert(LocalPointVaryingStencilPrecisionMatchesType<REAL>());
760     return _localPointVaryingStencils.Get<REAL>();
761 }
762 template <typename REAL>
763 inline StencilTableReal<REAL> const *
GetLocalPointFaceVaryingStencilTable(int channel)764 PatchTable::GetLocalPointFaceVaryingStencilTable(int channel) const {
765     assert(LocalPointFaceVaryingStencilPrecisionMatchesType<REAL>());
766     if (channel >= 0 && channel < (int)_localPointFaceVaryingStencils.size()) {
767         return _localPointFaceVaryingStencils[channel].Get<REAL>();
768     }
769     return NULL;
770 }
771 
772 
773 //
774 //  Computation of local point values:
775 //
776 template <class T>
777 inline void
ComputeLocalPointValues(T const * src,T * dst)778 PatchTable::ComputeLocalPointValues(T const *src, T *dst) const {
779     assert(LocalPointStencilPrecisionMatchesType<float>());
780     if (_localPointStencils) {
781         _localPointStencils.Get<float>()->UpdateValues(src, dst);
782     }
783 }
784 
785 template <class T>
786 inline void
ComputeLocalPointValuesVarying(T const * src,T * dst)787 PatchTable::ComputeLocalPointValuesVarying(T const *src, T *dst) const {
788     assert(LocalPointVaryingStencilPrecisionMatchesType<float>());
789     if (_localPointVaryingStencils) {
790         _localPointVaryingStencils.Get<float>()->UpdateValues(src, dst);
791     }
792 }
793 
794 template <class T>
795 inline void
ComputeLocalPointValuesFaceVarying(T const * src,T * dst,int channel)796 PatchTable::ComputeLocalPointValuesFaceVarying(T const *src, T *dst, int channel) const {
797     assert(LocalPointFaceVaryingStencilPrecisionMatchesType<float>());
798     if (channel >= 0 && channel < (int)_localPointFaceVaryingStencils.size()) {
799         if (_localPointFaceVaryingStencils[channel]) {
800             _localPointFaceVaryingStencils[channel].Get<float>()->UpdateValues(src, dst);
801         }
802     }
803 }
804 
805 
806 //
807 //  Basis evaluation overloads
808 //
809 inline void
EvaluateBasis(PatchHandle const & handle,float u,float v,float wP[],float wDu[],float wDv[],float wDuu[],float wDuv[],float wDvv[])810 PatchTable::EvaluateBasis(PatchHandle const & handle, float u, float v,
811     float wP[], float wDu[], float wDv[],
812     float wDuu[], float wDuv[], float wDvv[]) const {
813 
814     EvaluateBasis<float>(handle, u, v, wP, wDu, wDv, wDuu, wDuv, wDvv);
815 }
816 inline void
EvaluateBasis(PatchHandle const & handle,double u,double v,double wP[],double wDu[],double wDv[],double wDuu[],double wDuv[],double wDvv[])817 PatchTable::EvaluateBasis(PatchHandle const & handle, double u, double v,
818     double wP[], double wDu[], double wDv[],
819     double wDuu[], double wDuv[], double wDvv[]) const {
820 
821     EvaluateBasis<double>(handle, u, v, wP, wDu, wDv, wDuu, wDuv, wDvv);
822 }
823 
824 inline void
EvaluateBasisVarying(PatchHandle const & handle,float u,float v,float wP[],float wDu[],float wDv[],float wDuu[],float wDuv[],float wDvv[])825 PatchTable::EvaluateBasisVarying(PatchHandle const & handle, float u, float v,
826     float wP[], float wDu[], float wDv[],
827     float wDuu[], float wDuv[], float wDvv[]) const {
828 
829     EvaluateBasisVarying<float>(handle, u, v, wP, wDu, wDv, wDuu, wDuv, wDvv);
830 }
831 inline void
EvaluateBasisVarying(PatchHandle const & handle,double u,double v,double wP[],double wDu[],double wDv[],double wDuu[],double wDuv[],double wDvv[])832 PatchTable::EvaluateBasisVarying(PatchHandle const & handle, double u, double v,
833     double wP[], double wDu[], double wDv[],
834     double wDuu[], double wDuv[], double wDvv[]) const {
835 
836     EvaluateBasisVarying<double>(handle, u, v, wP, wDu, wDv, wDuu, wDuv, wDvv);
837 }
838 
839 inline void
EvaluateBasisFaceVarying(PatchHandle const & handle,float u,float v,float wP[],float wDu[],float wDv[],float wDuu[],float wDuv[],float wDvv[],int channel)840 PatchTable::EvaluateBasisFaceVarying(PatchHandle const & handle, float u, float v,
841     float wP[], float wDu[], float wDv[],
842     float wDuu[], float wDuv[], float wDvv[], int channel) const {
843 
844     EvaluateBasisFaceVarying<float>(handle, u, v, wP, wDu, wDv, wDuu, wDuv, wDvv, channel);
845 }
846 inline void
EvaluateBasisFaceVarying(PatchHandle const & handle,double u,double v,double wP[],double wDu[],double wDv[],double wDuu[],double wDuv[],double wDvv[],int channel)847 PatchTable::EvaluateBasisFaceVarying(PatchHandle const & handle, double u, double v,
848     double wP[], double wDu[], double wDv[],
849     double wDuu[], double wDuv[], double wDvv[], int channel) const {
850 
851     EvaluateBasisFaceVarying<double>(handle, u, v, wP, wDu, wDv, wDuu, wDuv, wDvv, channel);
852 }
853 
854 } // end namespace Far
855 
856 } // end namespace OPENSUBDIV_VERSION
857 using namespace OPENSUBDIV_VERSION;
858 
859 } // end namespace OpenSubdiv
860 
861 #endif /* OPENSUBDIV3_FAR_PATCH_TABLE */
862