Merge pull request #824 from davidgyu/patch_table_api

Updated PatchTable for Varying and Face-Varying
This commit is contained in:
Takahito Tejima 2016-07-20 11:40:24 -07:00 committed by GitHub
commit 1e625e690e
3 changed files with 326 additions and 78 deletions

View File

@ -63,11 +63,21 @@ PatchTable::PatchTable(PatchTable const & src) :
_localPointVaryingStencils =
new StencilTable(*src._localPointVaryingStencils);
}
if (! src._localPointFaceVaryingStencils.empty()) {
_localPointFaceVaryingStencils.resize(src._localPointFaceVaryingStencils.size());
for (int fvc=0; fvc<(int)_localPointFaceVaryingStencils.size(); ++fvc) {
_localPointFaceVaryingStencils[fvc] =
new StencilTable(*src._localPointFaceVaryingStencils[fvc]);
}
}
}
PatchTable::~PatchTable() {
delete _localPointStencils;
delete _localPointVaryingStencils;
for (int fvc=0; fvc<(int)_localPointFaceVaryingStencils.size(); ++fvc) {
delete _localPointFaceVaryingStencils[fvc];
}
}
//
@ -86,7 +96,7 @@ struct PatchTable::PatchArray {
int numPatches; // number of patches in the array
Index vertIndex, // index to the first control vertex
patchIndex, // index of the first patch in the array
patchIndex, // absolute index of the first patch in the array
quadOffsetIndex; // index of the first quad offset entry
};
@ -140,30 +150,28 @@ PatchTable::reservePatchArrays(int numPatchArrays) {
//
struct PatchTable::FVarPatchChannel {
// Channel interpolation mode
Sdc::Options::FVarLinearInterpolation interpolation;
// Patch type
//
// Note : in bilinear interpolation modes, all patches are of the same type,
// so we only need a single type (patchesType). In bi-cubic modes, each
// patch requires its own type (patchTypes).
PatchDescriptor::Type patchesType;
std::vector<PatchDescriptor::Type> patchTypes;
PatchDescriptor desc;
// Patch points values
std::vector<Index> patchValuesOffsets; // offset to the first value of each patch
std::vector<Index> patchValues; // point values for each patch
std::vector<Index> patchValues;
};
void
PatchTable::allocateVaryingVertices(
PatchDescriptor desc, int numPatches) {
_varyingDesc = desc;
_varyingVerts.resize(numPatches*desc.GetNumControlVertices());
}
inline PatchTable::FVarPatchChannel &
PatchTable::getFVarPatchChannel(int channel) {
assert(channel<(int)_fvarChannels.size());
assert(channel>=0 && channel<(int)_fvarChannels.size());
return _fvarChannels[channel];
}
inline PatchTable::FVarPatchChannel const &
PatchTable::getFVarPatchChannel(int channel) const {
assert(channel<(int)_fvarChannels.size());
assert(channel>=0 && channel<(int)_fvarChannels.size());
return _fvarChannels[channel];
}
void
@ -172,13 +180,10 @@ PatchTable::allocateFVarPatchChannels(int numChannels) {
}
void
PatchTable::allocateFVarPatchChannelValues(
int numPatches, int numVerticesTotal, int channel) {
PatchDescriptor desc, int numPatches, int channel) {
FVarPatchChannel & c = getFVarPatchChannel(channel);
(void)numPatches; // not used
// Allocate bi-linear channels (allows uniform topology to be populated
// in a single traversal)
c.patchValues.resize(numVerticesTotal);
c.desc = desc;
c.patchValues.resize(numPatches*desc.GetNumControlVertices());
}
void
PatchTable::setFVarPatchChannelLinearInterpolation(
@ -343,6 +348,18 @@ int
PatchTable::GetNumLocalPoints() const {
return _localPointStencils ? _localPointStencils->GetNumStencils() : 0;
}
int
PatchTable::GetNumLocalPointsVarying() const {
return _localPointVaryingStencils ? _localPointVaryingStencils->GetNumStencils() : 0;
}
int
PatchTable::GetNumLocalPointsFaceVarying(int channel) const {
if (channel>=0 && channel<(int)_localPointFaceVaryingStencils.size() &&
_localPointFaceVaryingStencils[channel]) {
return _localPointFaceVaryingStencils[channel]->GetNumStencils();
}
return 0;
}
PatchTable::ConstQuadOffsetsArray
PatchTable::GetPatchQuadOffsets(PatchHandle const & handle) const {
@ -365,6 +382,39 @@ PatchTable::IsFeatureAdaptive() const {
return false;
}
ConstIndexArray
PatchTable::GetPatchVaryingVertices(PatchHandle const & handle) const {
int numVaryingCVs = _varyingDesc.GetNumControlVertices();
Index start = handle.patchIndex * numVaryingCVs;
return ConstIndexArray(&_varyingVerts[start], numVaryingCVs);
}
ConstIndexArray
PatchTable::GetPatchVaryingVertices(int array, int patch) const {
PatchArray const & pa = getPatchArray(array);
int numVaryingCVs = _varyingDesc.GetNumControlVertices();
Index start = (pa.patchIndex + patch) * numVaryingCVs;
return ConstIndexArray(&_varyingVerts[start], numVaryingCVs);
}
ConstIndexArray
PatchTable::GetPatchArrayVaryingVertices(int array) const {
PatchArray const & pa = getPatchArray(array);
int numVaryingCVs = _varyingDesc.GetNumControlVertices();
Index start = pa.patchIndex * numVaryingCVs;
Index count = pa.numPatches * numVaryingCVs;
return ConstIndexArray(&_varyingVerts[start], count);
}
ConstIndexArray
PatchTable::GetVaryingVertices() const {
return ConstIndexArray(&_varyingVerts[0], (int)_varyingVerts.size());
}
IndexArray
PatchTable::getPatchArrayVaryingVertices(int arrayIndex) {
PatchArray const & pa = getPatchArray(arrayIndex);
int numVaryingCVs = _varyingDesc.GetNumControlVertices();
Index start = pa.patchIndex * numVaryingCVs;
return IndexArray(&_varyingVerts[start], pa.numPatches * numVaryingCVs);
}
int
PatchTable::GetNumFVarChannels() const {
return (int)_fvarChannels.size();
@ -374,6 +424,11 @@ PatchTable::GetFVarChannelLinearInterpolation(int channel) const {
FVarPatchChannel const & c = getFVarPatchChannel(channel);
return c.interpolation;
}
PatchDescriptor
PatchTable::GetFVarChannelPatchDescriptor(int channel) const {
FVarPatchChannel const & c = getFVarPatchChannel(channel);
return c.desc;
}
ConstIndexArray
PatchTable::GetFVarValues(int channel) const {
FVarPatchChannel const & c = getFVarPatchChannel(channel);
@ -386,18 +441,9 @@ PatchTable::getFVarValues(int channel) {
}
ConstIndexArray
PatchTable::getPatchFVarValues(int patch, int channel) const {
FVarPatchChannel const & c = getFVarPatchChannel(channel);
if (c.patchValuesOffsets.empty()) {
int ncvs = PatchDescriptor::GetNumFVarControlVertices(c.patchesType);
return ConstIndexArray(&c.patchValues[patch * ncvs], ncvs);
} else {
assert(patch<(int)c.patchValuesOffsets.size() &&
patch<(int)c.patchTypes.size());
return ConstIndexArray(&c.patchValues[c.patchValuesOffsets[patch]],
PatchDescriptor::GetNumFVarControlVertices(c.patchTypes[patch]));
}
int ncvs = c.desc.GetNumControlVertices();
return ConstIndexArray(&c.patchValues[patch * ncvs], ncvs);
}
ConstIndexArray
PatchTable::GetPatchFVarValues(PatchHandle const & handle, int channel) const {
@ -407,6 +453,15 @@ ConstIndexArray
PatchTable::GetPatchFVarValues(int arrayIndex, int patchIndex, int channel) const {
return getPatchFVarValues(getPatchIndex(arrayIndex, patchIndex), channel);
}
ConstIndexArray
PatchTable::GetPatchArrayFVarValues(int array, int channel) const {
PatchArray const & pa = getPatchArray(array);
FVarPatchChannel const & c = getFVarPatchChannel(channel);
int ncvs = c.desc.GetNumControlVertices();
int start = pa.patchIndex * ncvs;
int count = pa.numPatches * ncvs;
return ConstIndexArray(&c.patchValues[start], count);
}
void
PatchTable::print() const {
@ -420,11 +475,13 @@ PatchTable::print() const {
}
//
// Evaluate basis functions for position and first derivatives at (s,t):
// Evaluate basis functions for vertex and derivatives at (s,t):
//
void
PatchTable::EvaluateBasis(PatchHandle const & handle, float s, float t,
float wP[], float wDs[], float wDt[], float wDss[], float wDst[], float wDtt[]) const {
PatchTable::EvaluateBasis(
PatchHandle const & handle, float s, float t,
float wP[], float wDs[], float wDt[],
float wDss[], float wDst[], float wDtt[]) const {
PatchDescriptor::Type patchType = GetPatchArrayDescriptor(handle.arrayIndex).GetType();
PatchParam const & param = _paramTable[handle.patchIndex];
@ -440,6 +497,45 @@ PatchTable::EvaluateBasis(PatchHandle const & handle, float s, float t,
}
}
//
// Evaluate basis functions for varying and derivatives at (s,t):
//
void
PatchTable::EvaluateBasisVarying(
PatchHandle const & handle, float s, float t,
float wP[], float wDs[], float wDt[],
float wDss[], float wDst[], float wDtt[]) const {
PatchParam const & param = _paramTable[handle.patchIndex];
internal::GetBilinearWeights(param, s, t, wP, wDs, wDt, wDss, wDst, wDtt);
}
//
// Evaluate basis functions for face-varying and derivatives at (s,t):
//
void
PatchTable::EvaluateBasisFaceVarying(
PatchHandle const & handle, float s, float t,
float wP[], float wDs[], float wDt[],
float wDss[], float wDst[], float wDtt[],
int channel) const {
PatchDescriptor::Type patchType = GetFVarChannelPatchDescriptor(channel).GetType();
PatchParam param = _paramTable[handle.patchIndex];
// XXXdyu need fvar boundary parameterization
if (patchType == PatchDescriptor::REGULAR) {
internal::GetBSplineWeights(param, s, t, wP, wDs, wDt, wDss, wDst, wDtt);
} else if (patchType == PatchDescriptor::GREGORY_BASIS) {
internal::GetGregoryWeights(param, s, t, wP, wDs, wDt, wDss, wDst, wDtt);
} else if (patchType == PatchDescriptor::QUADS) {
internal::GetBilinearWeights(param, s, t, wP, wDs, wDt, wDss, wDst, wDtt);
} else {
assert(0);
}
}
} // end namespace Far

View File

@ -33,7 +33,6 @@
#include "../sdc/options.h"
#include <cstdlib>
#include <vector>
namespace OpenSubdiv {
@ -104,19 +103,19 @@ public:
/// \brief Accessors for individual patches
///
/// \brief Returns the PatchDescriptor for the patches in array 'array'
/// \brief Returns the PatchDescriptor for the patch identified by \p handle
PatchDescriptor GetPatchDescriptor(PatchHandle const & handle) const;
/// \brief Returns the control vertex indices for the patch identified by 'handle'
/// \brief Returns the control vertex indices for the patch identified by \p handle
ConstIndexArray GetPatchVertices(PatchHandle const & handle) const;
/// \brief Returns a PatchParam for the patch identified by 'handle'
/// \brief Returns a PatchParam for the patch identified by \p handle
PatchParam GetPatchParam(PatchHandle const & handle) const;
/// \brief Returns the control vertex indices for the patch 'patch' in array 'array'
/// \brief Returns the control vertex indices for \p patch in \p array
ConstIndexArray GetPatchVertices(int array, int patch) const;
/// \brief Returns the PatchParam for the patch 'patch' in array 'array'
/// \brief Returns the PatchParam for \p patch in \p array
PatchParam GetPatchParam(int array, int patch) const;
//@}
@ -132,56 +131,94 @@ public:
/// \brief Returns the number of patch arrays in the table
int GetNumPatchArrays() const;
/// \brief Returns the number of patches in patch array 'array'
/// \brief Returns the number of patches in \p array
int GetNumPatches(int array) const;
/// \brief Returns the number of control vertices in patch array 'array'
/// \brief Returns the number of control vertices in \p array
int GetNumControlVertices(int array) const;
/// \brief Returns the PatchDescriptor for the patches in array 'array'
/// \brief Returns the PatchDescriptor for the patches in \p array
PatchDescriptor GetPatchArrayDescriptor(int array) const;
/// \brief Returns the control vertex indices for the patches in array 'array'
/// \brief Returns the control vertex indices for the patches in \p array
ConstIndexArray GetPatchArrayVertices(int array) const;
/// \brief Returns the PatchParams for the patches in array 'array'
/// \brief Returns the PatchParams for the patches in \p array
ConstPatchParamArray const GetPatchParams(int array) const;
//@}
//@{
/// @name change of basis patches
/// @name Change of basis patches
///
/// \anchor change_of_basis_patches
///
/// \brief Accessors for change of basis patch points
/// \brief Accessors for change of basis patches
///
///
/// \brief Returns the number of points of the change of basis patches.
/// \brief Returns the number of local vertex points.
int GetNumLocalPoints() const;
/// \brief Updates local point values based on the refined values
/// \brief Updates local point vertex values.
///
/// @param src Buffer with primvar data for the control vertices
/// and refined vertices
/// @param src Buffer with primvar data for the coarse vertex values
/// and refined vertex values
///
/// @param dst Destination buffer for the computed local points
/// @param dst Destination buffer for the computed local point
/// vertex values
///
///
template <class T> void
ComputeLocalPointValues(T const *src, T *dst) const;
/// \brief Returns the stencil table to get change of basis patch points.
/// \brief Returns the stencil table to compute local point vertex values
StencilTable const *GetLocalPointStencilTable() const {
return _localPointStencils;
}
/// \brief Returns the varying stencil table for the change of basis patch
/// points.
/// \brief Returns the number of local varying points.
int GetNumLocalPointsVarying() const;
/// \brief Updates local point varying values.
///
/// @param src Buffer with primvar data for the coarse varying values
/// and refined varying values
///
/// @param dst Destination buffer for the computed local point
/// varying values
///
///
template <class T> void
ComputeLocalPointValuesVarying(T const *src, T *dst) const;
/// \brief Returns the stencil table to compute local point varying values
StencilTable const *GetLocalPointVaryingStencilTable() const {
return _localPointVaryingStencils;
}
/// \brief Returns the number of local face-varying points for \p channel
int GetNumLocalPointsFaceVarying(int channel = 0) const;
/// \brief Updates local point face-varying values.
///
/// @param src Buffer with primvar data for the coarse face-varying
/// values and refined face-varying values
///
/// @param dst Destination buffer for the computed local point
/// face-varying values
///
///
template <class T> void
ComputeLocalPointValuesFaceVarying(T const *src, T *dst, int channel = 0) const;
/// \brief Returns the stencil table to compute local point face-varying values
StencilTable const *GetLocalPointFaceVaryingStencilTable(int channel = 0) const {
if (channel >= 0 && channel < (int)_localPointFaceVaryingStencils.size()) {
return _localPointFaceVaryingStencils[channel];
}
return NULL;
}
//@}
@ -193,7 +230,7 @@ public:
///
typedef Vtr::ConstArray<unsigned int> ConstQuadOffsetsArray;
/// \brief Returns the 'QuadOffsets' for the Gregory patch identified by 'handle'
/// \brief Returns the 'QuadOffsets' for the Gregory patch identified by \p handle
ConstQuadOffsetsArray GetPatchQuadOffsets(PatchHandle const & handle) const;
typedef std::vector<Index> VertexValenceTable;
@ -213,16 +250,38 @@ public:
/// \brief Accessors for single-crease patch edge sharpness
///
/// \brief Returns the crease sharpness for the patch identified by 'handle'
/// \brief Returns the crease sharpness for the patch identified by \p handle
/// if it is a single-crease patch, or 0.0f
float GetSingleCreasePatchSharpnessValue(PatchHandle const & handle) const;
/// \brief Returns the crease sharpness for the patch 'patch' in array 'array'
/// \brief Returns the crease sharpness for the \p patch in \p array
/// if it is a single-crease patch, or 0.0f
float GetSingleCreasePatchSharpnessValue(int array, int patch) const;
//@}
//@{
/// @name Varying data
///
/// \anchor varying_data
///
/// \brief Accessors for varying data
///
/// \brief Returns the varying vertex indices for a given patch
ConstIndexArray GetPatchVaryingVertices(PatchHandle const & handle) const;
/// \brief Returns the varying vertex indices for a given patch
ConstIndexArray GetPatchVaryingVertices(int array, int patch) const;
/// \brief Returns the varying vertex indices for the patches in \p array
ConstIndexArray GetPatchArrayVaryingVertices(int array) const;
/// \brief Returns an array of varying vertex indices for the patches.
ConstIndexArray GetVaryingVertices() const;
//@}
//@{
/// @name Face-varying channels
///
@ -234,19 +293,23 @@ public:
/// \brief Returns the number of face-varying channels
int GetNumFVarChannels() const;
/// \brief Returns the interpolation mode for a given channel
/// \brief Deprecated Returns the interpolation mode for \p channel
Sdc::Options::FVarLinearInterpolation GetFVarChannelLinearInterpolation(int channel = 0) const;
/// \brief Returns the patch descriptor for \p channel
PatchDescriptor GetFVarChannelPatchDescriptor(int channel = 0) const;
/// \brief Returns the value indices for a given patch in a channel
/// \brief Returns the value indices for a given patch in \p channel
ConstIndexArray GetPatchFVarValues(PatchHandle const & handle, int channel = 0) const;
/// \brief Returns the value indices for a given patch in a channel
/// \brief Returns the value indices for a given patch in \p channel
ConstIndexArray GetPatchFVarValues(int array, int patch, int channel = 0) const;
/// \brief Returns the value indices for the patches in \p array in \p channel
ConstIndexArray GetPatchArrayFVarValues(int array, int channel = 0) const;
/// \brief Returns an array of value indices for the patches in a channel
/// \brief Returns an array of value indices for the patches in \p channel
ConstIndexArray GetFVarValues(int channel = 0) const;
//@}
@ -289,7 +352,7 @@ public:
/// @name Evaluation methods
///
/// \brief Evaluate basis functions for position and first derivatives at a
/// \brief Evaluate basis functions for position and derivatives at a
/// given (s,t) parametric location of a patch.
///
/// @param handle A patch handle indentifying the sub-patch containing the
@ -305,9 +368,70 @@ public:
///
/// @param wDt Weights (evaluated basis functions) for derivative wrt t
///
/// @param wDss Weights (evaluated basis functions) for derivative wrt ss
///
/// @param wDst Weights (evaluated basis functions) for derivative wrt st
///
/// @param wDtt Weights (evaluated basis functions) for derivative wrt tt
///
void EvaluateBasis(PatchHandle const & handle, float s, float t,
float wP[], float wDs[] = 0, float wDt[] = 0, float wDss[] = 0, float wDst[] = 0, float wDtt[] = 0) const;
float wP[], float wDs[] = 0, float wDt[] = 0,
float wDss[] = 0, float wDst[] = 0, float wDtt[] = 0) const;
/// \brief Evaluate basis functions for a varying value and
/// derivatives at a given (s,t) parametric location of a patch.
///
/// @param handle A patch handle indentifying the sub-patch containing the
/// (s,t) location
///
/// @param s Patch coordinate (in coarse face normalized space)
///
/// @param t Patch coordinate (in coarse face normalized space)
///
/// @param wP Weights (evaluated basis functions) for the position
///
/// @param wDs Weights (evaluated basis functions) for derivative wrt s
///
/// @param wDt Weights (evaluated basis functions) for derivative wrt t
///
/// @param wDss Weights (evaluated basis functions) for derivative wrt ss
///
/// @param wDst Weights (evaluated basis functions) for derivative wrt st
///
/// @param wDtt Weights (evaluated basis functions) for derivative wrt tt
///
void EvaluateBasisVarying(PatchHandle const & handle, float s, float t,
float wP[], float wDs[] = 0, float wDt[] = 0,
float wDss[] = 0, float wDst[] = 0, float wDtt[] = 0) const;
/// \brief Evaluate basis functions for a face-varying value and
/// derivatives at a given (s,t) parametric location of a patch.
///
/// @param handle A patch handle indentifying the sub-patch containing the
/// (s,t) location
///
/// @param s Patch coordinate (in coarse face normalized space)
///
/// @param t Patch coordinate (in coarse face normalized space)
///
/// @param wP Weights (evaluated basis functions) for the position
///
/// @param wDs Weights (evaluated basis functions) for derivative wrt s
///
/// @param wDt Weights (evaluated basis functions) for derivative wrt t
///
/// @param wDss Weights (evaluated basis functions) for derivative wrt ss
///
/// @param wDst Weights (evaluated basis functions) for derivative wrt st
///
/// @param wDtt Weights (evaluated basis functions) for derivative wrt tt
///
/// @param channel face-varying channel
///
void EvaluateBasisFaceVarying(PatchHandle const & handle, float s, float t,
float wP[], float wDs[] = 0, float wDt[] = 0,
float wDss[] = 0, float wDst[] = 0, float wDtt[] = 0,
int channel = 0) const;
//@}
protected:
@ -346,7 +470,15 @@ private:
//
// FVar patch channels
// Varying patch arrays
//
IndexArray getPatchArrayVaryingVertices(int arrayIndex);
void allocateVaryingVertices(
PatchDescriptor desc, int numPatches);
//
// Face-varying patch channels
//
struct FVarPatchChannel;
@ -357,19 +489,15 @@ private:
void allocateFVarPatchChannels(int numChannels);
void allocateFVarPatchChannelValues(
int numPatches, int numVerticesTotal, int channel);
PatchDescriptor desc, int numPatches, int channel);
// deprecated
void setFVarPatchChannelLinearInterpolation(
Sdc::Options::FVarLinearInterpolation interpolation, int channel);
PatchDescriptor::Type getFVarPatchType(int patch, int channel) const;
Vtr::Array<PatchDescriptor::Type> getFVarPatchTypes(int channel);
IndexArray getFVarValues(int channel);
ConstIndexArray getPatchFVarValues(int patch, int channel) const;
private:
//
@ -396,12 +524,22 @@ private:
StencilTable const * _localPointStencils; // endcap basis conversion stencils
StencilTable const * _localPointVaryingStencils; // endcap varying stencils (for convenience)
//
// Varying data
//
PatchDescriptor _varyingDesc;
std::vector<Index> _varyingVerts;
//
// Face-varying data
//
FVarPatchChannelVector _fvarChannels;
std::vector<StencilTable const *> _localPointFaceVaryingStencils;
//
// 'single-crease' patch sharpness tables
//
@ -418,6 +556,24 @@ PatchTable::ComputeLocalPointValues(T const *src, T *dst) const {
}
}
template <class T>
inline void
PatchTable::ComputeLocalPointValuesVarying(T const *src, T *dst) const {
if (_localPointVaryingStencils) {
_localPointVaryingStencils->UpdateValues(src, dst);
}
}
template <class T>
inline void
PatchTable::ComputeLocalPointValuesFaceVarying(T const *src, T *dst, int channel) const {
if (channel >= 0 && channel < (int)_localPointFaceVaryingStencils.size()) {
if (_localPointFaceVaryingStencils[channel]) {
_localPointFaceVaryingStencils[channel]->UpdateValues(src, dst);
}
}
}
} // end namespace Far

View File

@ -389,15 +389,11 @@ PatchTableFactory::allocateFVarChannels(TopologyRefiner const & refiner,
table->setFVarPatchChannelLinearInterpolation(interpolation, fvc.pos());
int nverts = 0;
PatchDescriptor::Type type = options.triangulateQuads ?
PatchDescriptor::TRIANGLES : PatchDescriptor::QUADS;
nverts =
npatches * PatchDescriptor::GetNumFVarControlVertices(type);
table->allocateFVarPatchChannelValues(npatches, nverts, fvc.pos());
table->allocateFVarPatchChannelValues(
PatchDescriptor(type), npatches, fvc.pos());
}
}