mirror of
https://github.com/PixarAnimationStudios/OpenSubdiv
synced 2024-11-15 00:11:07 +00:00
Merge pull request #587 from davidgyu/fvarSmoothPatchPostpone
Prepare to defer face-varying bicubic patches
This commit is contained in:
commit
ef55c48123
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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 {
|
||||
|
||||
|
@ -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:
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user