mirror of
https://github.com/PixarAnimationStudios/OpenSubdiv
synced 2024-11-23 20:20:09 +00:00
Fix Far::LimitStencilTableFactory issues with uniform refinement:
- corrected stencil estimates according to the interpolation mode - removed the added error checking for the tables provided - use uniform vertex patches when varying interpolation specified
This commit is contained in:
parent
27bc5c5495
commit
9219b0fb00
@ -436,16 +436,19 @@ LimitStencilTableFactoryReal<REAL>::Create(TopologyRefiner const & refiner,
|
|||||||
int fvarChannel = options.fvarChannel;
|
int fvarChannel = options.fvarChannel;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Quick sanity checks for given PatchTable and/or StencilTables -- more to
|
// Quick sanity checks for given PatchTable and/or StencilTables:
|
||||||
// come once a PatchTable is built and the number of local points known:
|
|
||||||
//
|
//
|
||||||
int nRefinedStencils = 0;
|
int nRefinedStencils = 0;
|
||||||
if (uniform) {
|
if (uniform) {
|
||||||
nRefinedStencils = refiner.GetLevel(maxlevel).GetNumVertices();
|
// Uniform stencils must include at least the last level points:
|
||||||
} else if (!interpolateFaceVarying) {
|
nRefinedStencils = interpolateFaceVarying
|
||||||
nRefinedStencils = refiner.GetNumVerticesTotal();
|
? refiner.GetLevel(maxlevel).GetNumFVarValues(fvarChannel)
|
||||||
|
: refiner.GetLevel(maxlevel).GetNumVertices();
|
||||||
} else {
|
} else {
|
||||||
nRefinedStencils = refiner.GetNumFVarValuesTotal(fvarChannel);
|
// Adaptive stencils must include at least all refined points:
|
||||||
|
nRefinedStencils = interpolateFaceVarying
|
||||||
|
? refiner.GetNumFVarValuesTotal(fvarChannel)
|
||||||
|
: refiner.GetNumVerticesTotal();
|
||||||
}
|
}
|
||||||
if (cvStencilsIn && (cvStencilsIn->GetNumStencils() < nRefinedStencils)) {
|
if (cvStencilsIn && (cvStencilsIn->GetNumStencils() < nRefinedStencils)) {
|
||||||
// Too few stencils in given StencilTable
|
// Too few stencils in given StencilTable
|
||||||
@ -474,7 +477,6 @@ LimitStencilTableFactoryReal<REAL>::Create(TopologyRefiner const & refiner,
|
|||||||
stencilTableOptions.fvarChannel = options.fvarChannel;
|
stencilTableOptions.fvarChannel = options.fvarChannel;
|
||||||
|
|
||||||
cvstencils = StencilTableFactoryReal<REAL>::Create(refiner, stencilTableOptions);
|
cvstencils = StencilTableFactoryReal<REAL>::Create(refiner, stencilTableOptions);
|
||||||
assert(cvstencils->GetNumStencils() == nRefinedStencils);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If an appropriate PatchTable was given, use it, otherwise, create a new one
|
// If an appropriate PatchTable was given, use it, otherwise, create a new one
|
||||||
@ -487,9 +489,11 @@ LimitStencilTableFactoryReal<REAL>::Create(TopologyRefiner const & refiner,
|
|||||||
//
|
//
|
||||||
PatchTableFactory::Options patchTableOptions;
|
PatchTableFactory::Options patchTableOptions;
|
||||||
patchTableOptions.SetPatchPrecision<REAL>();
|
patchTableOptions.SetPatchPrecision<REAL>();
|
||||||
|
patchTableOptions.includeBaseLevelIndices = true;
|
||||||
patchTableOptions.generateVaryingTables = interpolateVarying;
|
patchTableOptions.generateVaryingTables = interpolateVarying;
|
||||||
patchTableOptions.generateFVarTables = interpolateFaceVarying;
|
patchTableOptions.generateFVarTables = interpolateFaceVarying;
|
||||||
if (interpolateFaceVarying) {
|
if (interpolateFaceVarying) {
|
||||||
|
patchTableOptions.includeFVarBaseLevelIndices = true;
|
||||||
patchTableOptions.numFVarChannels = 1;
|
patchTableOptions.numFVarChannels = 1;
|
||||||
patchTableOptions.fvarChannelIndices = &fvarChannel;
|
patchTableOptions.fvarChannelIndices = &fvarChannel;
|
||||||
patchTableOptions.generateFVarLegacyLinearPatches = uniform ||
|
patchTableOptions.generateFVarLegacyLinearPatches = uniform ||
|
||||||
@ -523,15 +527,6 @@ LimitStencilTableFactoryReal<REAL>::Create(TopologyRefiner const & refiner,
|
|||||||
refiner, refinedstencils, localstencils);
|
refiner, refinedstencils, localstencils);
|
||||||
}
|
}
|
||||||
if (!cvStencilsIn) delete refinedstencils;
|
if (!cvStencilsIn) delete refinedstencils;
|
||||||
} else if (cvStencilsIn) {
|
|
||||||
int nLocalStencils = localstencils ? localstencils->GetNumStencils() : 0;
|
|
||||||
if (cvstencils->GetNumStencils() != (nRefinedStencils + nLocalStencils)) {
|
|
||||||
// Stencil count mismatch with PatchTable and given StencilTable
|
|
||||||
// (previously undetected and subject to crashing)
|
|
||||||
|
|
||||||
if (!patchTableIn) delete patchtable;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(patchtable && cvstencils);
|
assert(patchtable && cvstencils);
|
||||||
@ -542,14 +537,24 @@ LimitStencilTableFactoryReal<REAL>::Create(TopologyRefiner const & refiner,
|
|||||||
//
|
//
|
||||||
// Generate limit stencils for locations
|
// Generate limit stencils for locations
|
||||||
//
|
//
|
||||||
StencilBuilder<REAL> builder(!interpolateFaceVarying
|
int nControlVertices = interpolateFaceVarying
|
||||||
? refiner.GetLevel(0).GetNumVertices()
|
? refiner.GetLevel(0).GetNumFVarValues(fvarChannel)
|
||||||
: refiner.GetLevel(0).GetNumFVarValues(fvarChannel),
|
: refiner.GetLevel(0).GetNumVertices();
|
||||||
|
|
||||||
|
StencilBuilder<REAL> builder(nControlVertices,
|
||||||
/*genControlVerts*/ false,
|
/*genControlVerts*/ false,
|
||||||
/*compactWeights*/ true);
|
/*compactWeights*/ true);
|
||||||
typename StencilBuilder<REAL>::Index origin(&builder, 0);
|
typename StencilBuilder<REAL>::Index origin(&builder, 0);
|
||||||
typename StencilBuilder<REAL>::Index dst = origin;
|
typename StencilBuilder<REAL>::Index dst = origin;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Generally use the patches corresponding to the interpolation mode, but Uniform
|
||||||
|
// PatchTables do not have varying patches -- use the equivalent linear vertex
|
||||||
|
// patches in this case:
|
||||||
|
//
|
||||||
|
bool useVertexPatches = interpolateVertex || (interpolateVarying && uniform);
|
||||||
|
bool useFVarPatches = interpolateFaceVarying;
|
||||||
|
|
||||||
REAL wP[20], wDs[20], wDt[20], wDss[20], wDst[20], wDtt[20];
|
REAL wP[20], wDs[20], wDt[20], wDss[20], wDst[20], wDtt[20];
|
||||||
|
|
||||||
for (size_t i=0; i<locationArrays.size(); ++i) {
|
for (size_t i=0; i<locationArrays.size(); ++i) {
|
||||||
@ -564,9 +569,9 @@ LimitStencilTableFactoryReal<REAL>::Create(TopologyRefiner const & refiner,
|
|||||||
patchmap.FindPatch(array.ptexIdx, s, t);
|
patchmap.FindPatch(array.ptexIdx, s, t);
|
||||||
if (handle) {
|
if (handle) {
|
||||||
ConstIndexArray cvs;
|
ConstIndexArray cvs;
|
||||||
if (interpolateVertex) {
|
if (useVertexPatches) {
|
||||||
cvs = patchtable->GetPatchVertices(*handle);
|
cvs = patchtable->GetPatchVertices(*handle);
|
||||||
} else if (interpolateFaceVarying) {
|
} else if (useFVarPatches) {
|
||||||
cvs = patchtable->GetPatchFVarValues(*handle, fvarChannel);
|
cvs = patchtable->GetPatchFVarValues(*handle, fvarChannel);
|
||||||
} else {
|
} else {
|
||||||
cvs = patchtable->GetPatchVaryingVertices(*handle);
|
cvs = patchtable->GetPatchVaryingVertices(*handle);
|
||||||
@ -576,10 +581,10 @@ LimitStencilTableFactoryReal<REAL>::Create(TopologyRefiner const & refiner,
|
|||||||
dst = origin[numLimitStencils];
|
dst = origin[numLimitStencils];
|
||||||
|
|
||||||
if (options.generate2ndDerivatives) {
|
if (options.generate2ndDerivatives) {
|
||||||
if (interpolateVertex) {
|
if (useVertexPatches) {
|
||||||
patchtable->EvaluateBasis<REAL>(
|
patchtable->EvaluateBasis<REAL>(
|
||||||
*handle, s, t, wP, wDs, wDt, wDss, wDst, wDtt);
|
*handle, s, t, wP, wDs, wDt, wDss, wDst, wDtt);
|
||||||
} else if (interpolateFaceVarying) {
|
} else if (useFVarPatches) {
|
||||||
patchtable->EvaluateBasisFaceVarying<REAL>(
|
patchtable->EvaluateBasisFaceVarying<REAL>(
|
||||||
*handle, s, t, wP, wDs, wDt, wDss, wDst, wDtt, fvarChannel);
|
*handle, s, t, wP, wDs, wDt, wDss, wDst, wDtt, fvarChannel);
|
||||||
} else {
|
} else {
|
||||||
@ -592,10 +597,10 @@ LimitStencilTableFactoryReal<REAL>::Create(TopologyRefiner const & refiner,
|
|||||||
dst.AddWithWeight(src[cvs[k]], wP[k], wDs[k], wDt[k], wDss[k], wDst[k], wDtt[k]);
|
dst.AddWithWeight(src[cvs[k]], wP[k], wDs[k], wDt[k], wDss[k], wDst[k], wDtt[k]);
|
||||||
}
|
}
|
||||||
} else if (options.generate1stDerivatives) {
|
} else if (options.generate1stDerivatives) {
|
||||||
if (interpolateVertex) {
|
if (useVertexPatches) {
|
||||||
patchtable->EvaluateBasis<REAL>(
|
patchtable->EvaluateBasis<REAL>(
|
||||||
*handle, s, t, wP, wDs, wDt);
|
*handle, s, t, wP, wDs, wDt);
|
||||||
} else if (interpolateFaceVarying) {
|
} else if (useFVarPatches) {
|
||||||
patchtable->EvaluateBasisFaceVarying<REAL>(
|
patchtable->EvaluateBasisFaceVarying<REAL>(
|
||||||
*handle, s, t, wP, wDs, wDt, 0, 0, 0, fvarChannel);
|
*handle, s, t, wP, wDs, wDt, 0, 0, 0, fvarChannel);
|
||||||
} else {
|
} else {
|
||||||
@ -608,10 +613,10 @@ LimitStencilTableFactoryReal<REAL>::Create(TopologyRefiner const & refiner,
|
|||||||
dst.AddWithWeight(src[cvs[k]], wP[k], wDs[k], wDt[k]);
|
dst.AddWithWeight(src[cvs[k]], wP[k], wDs[k], wDt[k]);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (interpolateVertex) {
|
if (useVertexPatches) {
|
||||||
patchtable->EvaluateBasis<REAL>(
|
patchtable->EvaluateBasis<REAL>(
|
||||||
*handle, s, t, wP);
|
*handle, s, t, wP);
|
||||||
} else if (interpolateFaceVarying) {
|
} else if (useFVarPatches) {
|
||||||
patchtable->EvaluateBasisFaceVarying<REAL>(
|
patchtable->EvaluateBasisFaceVarying<REAL>(
|
||||||
*handle, s, t, wP, 0, 0, 0, 0, 0, fvarChannel);
|
*handle, s, t, wP, 0, 0, 0, 0, 0, fvarChannel);
|
||||||
} else {
|
} else {
|
||||||
@ -642,7 +647,7 @@ LimitStencilTableFactoryReal<REAL>::Create(TopologyRefiner const & refiner,
|
|||||||
// Copy the proto-stencils into the limit stencil table
|
// Copy the proto-stencils into the limit stencil table
|
||||||
//
|
//
|
||||||
LimitStencilTableReal<REAL> * result = new LimitStencilTableReal<REAL>(
|
LimitStencilTableReal<REAL> * result = new LimitStencilTableReal<REAL>(
|
||||||
refiner.GetLevel(0).GetNumVertices(),
|
nControlVertices,
|
||||||
builder.GetStencilOffsets(),
|
builder.GetStencilOffsets(),
|
||||||
builder.GetStencilSizes(),
|
builder.GetStencilSizes(),
|
||||||
builder.GetStencilSources(),
|
builder.GetStencilSources(),
|
||||||
|
Loading…
Reference in New Issue
Block a user