Merge pull request #587 from davidgyu/fvarSmoothPatchPostpone

Prepare to defer face-varying bicubic patches
This commit is contained in:
Takahito Tejima 2015-06-03 12:33:05 -07:00
commit ef55c48123
6 changed files with 75 additions and 17 deletions

View File

@ -400,7 +400,9 @@ createFVarPatchNumbers(OpenSubdiv::Far::PatchTable const & patchTable,
g_font->Print3D(fvarBuffer[cvs[i]].GetPos(), buf, 2);
}
#ifdef FAR_FVAR_SMOOTH_PATCH
g_currentFVarPatchType = patchTable.GetFVarPatchType(handle, channel);
#endif
}
}

View File

@ -457,7 +457,8 @@ GLMesh::InitializeFVar(Options options, TopologyRefiner const & refiner,
// default to solid color
float const * color=0;
static float quadColor[3] = { 1.0f, 1.0f, 0.0f };
float const * color = quadColor;
// wireframe indices
int * basisedges = (int *)alloca(2*nedgesperpatch*sizeof(int)),
@ -480,10 +481,11 @@ GLMesh::InitializeFVar(Options options, TopologyRefiner const & refiner,
*ptr++ = tessFactor * (tessFactor-1) + i+1;
}
OpenSubdiv::Far::PatchTable::PatchHandle handle;
for (int patch=0, offset=0; patch<npatches; ++patch) {
#ifdef FAR_FVAR_SMOOTH_PATCH
if (options.edgeColorMode==EDGECOLOR_BY_PATCHTYPE) {
OpenSubdiv::Far::PatchTable::PatchHandle handle;
handle.patchIndex = patch;
OpenSubdiv::Far::PatchDescriptor::Type type =
@ -493,10 +495,10 @@ GLMesh::InitializeFVar(Options options, TopologyRefiner const & refiner,
color = getAdaptivePatchColor(
OpenSubdiv::Far::PatchDescriptor(type));
} else {
static float quadColor[3] = { 1.0f, 1.0f, 0.0f };
color = quadColor;
}
}
#endif
assert(color);
for (int edge=0; edge<nedgesperpatch; ++edge) {

View File

@ -128,13 +128,10 @@ PatchTable::reservePatchArrays(int numPatchArrays) {
//
// - Face-varying channels can have a different interpolation modes
//
// - Unlike "vertex" PatchTable, there are no "transition" patterns required
// - Unlike "vertex" patches, there are no transition masks required
// for face-varying patches.
//
// - No transition patterns means vertex indices of face-varying patches can
// be pre-rotated in the factory, so we do not store patch rotation
//
// - Face-varying patches still special variants for boundary and corner cases
// - Face-varying patches still require boundary edge masks.
//
// - currently most patches with sharp boundaries but smooth interiors have
// to be isolated to level 10 : we need a special type of bicubic patch
@ -178,6 +175,7 @@ PatchTable::allocateFVarPatchChannelValues(
int numPatches, int numVerticesTotal, int channel) {
FVarPatchChannel & c = getFVarPatchChannel(channel);
#ifdef FAR_FVAR_SMOOTH_PATCH
if (c.interpolation==Sdc::Options::FVAR_LINEAR_ALL) {
// Allocate bi-linear channels (allows uniform topology to be populated
// in a single traversal)
@ -192,6 +190,12 @@ PatchTable::allocateFVarPatchChannelValues(
c.patchesType = PatchDescriptor::NON_PATCH;
c.patchTypes.resize(numPatches);
}
#else
(void)numPatches; // not used
// Allocate bi-linear channels (allows uniform topology to be populated
// in a single traversal)
c.patchValues.resize(numVerticesTotal);
#endif
}
void
PatchTable::setFVarPatchChannelLinearInterpolation(
@ -199,6 +203,7 @@ PatchTable::setFVarPatchChannelLinearInterpolation(
FVarPatchChannel & c = getFVarPatchChannel(channel);
c.interpolation = interpolation;
}
#ifdef FAR_FVAR_SMOOTH_PATCH
void
PatchTable::setFVarPatchChannelPatchesType(
PatchDescriptor::Type type, int channel) {
@ -246,6 +251,7 @@ PatchTable::setBicubicFVarPatchChannelValues(
dstValues += nv;
}
}
#endif
//
// PatchTable
@ -434,6 +440,7 @@ PatchTable::GetFVarChannelLinearInterpolation(int channel) const {
FVarPatchChannel const & c = getFVarPatchChannel(channel);
return c.interpolation;
}
#ifdef FAR_FVAR_SMOOTH_PATCH
Vtr::Array<PatchDescriptor::Type>
PatchTable::getFVarPatchTypes(int channel) {
FVarPatchChannel & c = getFVarPatchChannel(channel);
@ -450,6 +457,7 @@ PatchTable::GetFVarPatchTypes(int channel) const {
(int)c.patchTypes.size());
}
}
#endif
ConstIndexArray
PatchTable::GetFVarValues(int channel) const {
FVarPatchChannel const & c = getFVarPatchChannel(channel);
@ -460,6 +468,7 @@ PatchTable::getFVarValues(int channel) {
FVarPatchChannel & c = getFVarPatchChannel(channel);
return IndexArray(&c.patchValues[0], (int)c.patchValues.size());
}
#ifdef FAR_FVAR_SMOOTH_PATCH
PatchDescriptor::Type
PatchTable::getFVarPatchType(int patch, int channel) const {
FVarPatchChannel const & c = getFVarPatchChannel(channel);
@ -481,6 +490,7 @@ PatchDescriptor::Type
PatchTable::GetFVarPatchType(int arrayIndex, int patchIndex, int channel) const {
return getFVarPatchType(getPatchIndex(arrayIndex, patchIndex), channel);
}
#endif
ConstIndexArray
PatchTable::getPatchFVarValues(int patch, int channel) const {

View File

@ -41,6 +41,12 @@ namespace OPENSUBDIV_VERSION {
namespace Far {
// XXXdyu We're going to postpone support for smooth interpolation of
// face-varying patches until after the version 3.0 release. We've cordoned
// off the related code with the following macro and will restore this
// code after we cut the release.
#undef FAR_FVAR_SMOOTH_PATCH
/// \brief Container for arrays of parametric patches
///
/// PatchTable contain topology and parametric information about the patches
@ -239,6 +245,7 @@ public:
Sdc::Options::FVarLinearInterpolation GetFVarChannelLinearInterpolation(int channel = 0) const;
#ifdef FAR_FVAR_SMOOTH_PATCH
/// \brief Returns a descriptor for a given patch in a channel
PatchDescriptor::Type GetFVarPatchType(PatchHandle const & handle, int channel = 0) const;
@ -247,6 +254,7 @@ public:
/// \brief Returns an array of descriptors for the patches in a channel
Vtr::ConstArray<PatchDescriptor::Type> GetFVarPatchTypes(int channel = 0) const;
#endif
/// \brief Returns the value indices for a given patch in a channel
@ -372,7 +380,9 @@ private:
void setFVarPatchChannelLinearInterpolation(
Sdc::Options::FVarLinearInterpolation interpolation, int channel = 0);
#ifdef FAR_FVAR_SMOOTH_PATCH
void setFVarPatchChannelPatchesType(PatchDescriptor::Type type, int channel = 0);
#endif
PatchDescriptor::Type getFVarPatchType(int patch, int channel = 0) const;
Vtr::Array<PatchDescriptor::Type> getFVarPatchTypes(int channel = 0);
@ -380,7 +390,9 @@ private:
IndexArray getFVarValues(int channel = 0);
ConstIndexArray getPatchFVarValues(int patch, int channel = 0) const;
void setBicubicFVarPatchChannelValues(int patchSize, std::vector<Index> const & values, int channel = 0);
#ifdef FAR_FVAR_SMOOTH_PATCH
void setBicubicFVarPatchChannelValues(int patchSize, std::vector<Index> const & values, int channel =0);
#endif
private:

View File

@ -264,10 +264,10 @@ public:
_channelIndices[_currentChannel] : _currentChannel;
}
int pos() { return _currentChannel; }
int begin() { return 0; }
int end() { return _numChannels; }
int size() { return _numChannels; }
int pos() const { return _currentChannel; }
int begin() const { return 0; }
int end() const { return _numChannels; }
int size() const { return _numChannels; }
private:
int _numChannels, // total number of channels
@ -322,6 +322,7 @@ public:
// by client-code
FVarChannelCursor fvarChannelCursor;
#ifdef FAR_FVAR_SMOOTH_PATCH
// Allocate temporary space to store face-varying values : because we do
// not know yet the types of each patch, we pre-emptively allocate
// non-sparse arrays for each channel. Patches are assumed to have a maximum
@ -339,6 +340,7 @@ public:
// populated (in the correct sorted order), we copy them in the final sparse
// vectors and generate offsets.
std::vector<std::vector<Index> > fvarPatchValues;
#endif
};
// Constructor
@ -347,9 +349,12 @@ PatchTableFactory::AdaptiveContext::AdaptiveContext(
refiner(ref), options(opts), table(0),
fvarChannelCursor(ref, opts) {
#ifdef FAR_FVAR_SMOOTH_PATCH
fvarPatchValues.resize(fvarChannelCursor.size());
#endif
}
#ifdef FAR_FVAR_SMOOTH_PATCH
void
PatchTableFactory::AdaptiveContext::AllocateFVarPatchValues(int npatches) {
@ -366,10 +371,11 @@ PatchTableFactory::AdaptiveContext::AllocateFVarPatchValues(int npatches) {
}
}
}
#endif
bool
PatchTableFactory::AdaptiveContext::RequiresFVarPatches() const {
return not fvarPatchValues.empty();
return (fvarChannelCursor.size() > 0);
}
//
@ -424,6 +430,7 @@ PatchTableFactory::allocateFVarChannels(TopologyRefiner const & refiner,
table->setFVarPatchChannelLinearInterpolation(interpolation, fvc.pos());
int nverts = 0;
#ifdef FAR_FVAR_SMOOTH_PATCH
if (interpolation==Sdc::Options::FVAR_LINEAR_ALL) {
PatchDescriptor::Type type = options.triangulateQuads ?
@ -435,6 +442,13 @@ PatchTableFactory::allocateFVarChannels(TopologyRefiner const & refiner,
npatches * PatchDescriptor::GetNumFVarControlVertices(type);
}
#else
PatchDescriptor::Type type = options.triangulateQuads ?
PatchDescriptor::TRIANGLES : PatchDescriptor::QUADS;
nverts =
npatches * PatchDescriptor::GetNumFVarControlVertices(type);
#endif
table->allocateFVarPatchChannelValues(npatches, nverts, fvc.pos());
}
}
@ -445,6 +459,10 @@ int
PatchTableFactory::gatherFVarData(AdaptiveContext & context, int level,
Index faceIndex, Index levelFaceOffset, int rotation,
Index const * levelFVarVertOffsets, Index fofss, Index ** fptrs) {
#ifndef FAR_FVAR_SMOOTH_PATCH
(void)levelFaceOffset; // not used
(void)fofss; // not used
#endif
if (not context.RequiresFVarPatches()) {
return 0;
@ -452,12 +470,14 @@ PatchTableFactory::gatherFVarData(AdaptiveContext & context, int level,
TopologyRefiner const & refiner = context.refiner;
#ifdef FAR_FVAR_SMOOTH_PATCH
PatchTable * table = context.table;
assert((levelFaceOffset + faceIndex)<(int)context.patchTags.size());
PatchFaceTag & vertexPatchTag = context.patchTags[levelFaceOffset + faceIndex];
Index patchVerts[context.fvarPatchSize];
#endif
// Iterate over valid FVar channels (if any)
FVarChannelCursor & fvc = context.fvarChannelCursor;
@ -466,6 +486,7 @@ PatchTableFactory::gatherFVarData(AdaptiveContext & context, int level,
Vtr::internal::Level const & vtxLevel = refiner.getLevel(level);
Vtr::internal::FVarLevel const & fvarLevel = vtxLevel.getFVarLevel(*fvc);
#ifdef FAR_FVAR_SMOOTH_PATCH
if (refiner.GetFVarLinearInterpolation(*fvc)!=Sdc::Options::FVAR_LINEAR_ALL) {
//
@ -629,7 +650,9 @@ PatchTableFactory::gatherFVarData(AdaptiveContext & context, int level,
offsetAndPermuteIndices(patchVerts, nverts, levelFVarVertOffsets[fvc.pos()],
permutation, &context.fvarPatchValues[fvc.pos()][fofss*context.fvarPatchSize]);
} else {
} else
#endif
{
//
// Bi-linear patches
@ -643,6 +666,7 @@ PatchTableFactory::gatherFVarData(AdaptiveContext & context, int level,
levelFVarVertOffsets[fvc.pos()] + fvarValues[(vert+rotation)%4];
}
fptrs[fvc.pos()]+=fvarValues.size();
}
}
return 1;
@ -949,11 +973,13 @@ PatchTableFactory::createAdaptive(TopologyRefiner const & refiner, Options optio
allocateFVarChannels(refiner, options, npatches, context.table);
#ifdef FAR_FVAR_SMOOTH_PATCH
// Reserve temporary non-sparse storage for non-linear fvar channels.
// FVar Values for these channels are copied into the final
// FVarPatchChannel after the second traversal happens within the call to
// populateAdaptivePatches()
context.AllocateFVarPatchValues(npatches);
#endif
}
//
@ -1500,6 +1526,7 @@ PatchTableFactory::populateAdaptivePatches(
break;
}
#ifdef FAR_FVAR_SMOOTH_PATCH
if (context.RequiresFVarPatches()) {
// Compress & copy FVar values from context into FVarPatchChannel
// sparse array, generate offsets
@ -1515,6 +1542,7 @@ PatchTableFactory::populateAdaptivePatches(
}
}
}
#endif
}
} // end namespace Far

View File

@ -94,7 +94,9 @@ public:
endCapType(ENDCAP_GREGORY_BASIS),
shareEndCapPatchPoints(true),
generateFVarTables(false),
#ifdef FAR_FVAR_SMOOTH_PATCH
useFVarQuadEndCaps(true), // XXXX change to false when FVar Gregory is ready
#endif
numFVarChannels(-1),
fvarChannelIndices(0)
{ }
@ -116,8 +118,10 @@ public:
///< currently only work with GregoryBasis.
// face-varying
generateFVarTables : 1, ///< Generate face-varying patch tables
useFVarQuadEndCaps : 1; ///< Use bilinear quads as end-caps around extraordinary vertices
generateFVarTables : 1;///< Generate face-varying patch tables
#ifdef FAR_FVAR_SMOOTH_PATCH
unsigned int useFVarQuadEndCaps : 1; ///< Use bilinear quads as end-caps around extraordinary vertices
#endif
int numFVarChannels; ///< Number of channel indices and interpolation modes passed
int const * fvarChannelIndices; ///< List containing the indices of the channels selected for the factory