Added proper fractional weighting for semi-sharp FVar boundaries:

- semi-sharp edges interior to FVar regions now properly recognized
    - added clear() method to FVar tags and reworked their initialization
This commit is contained in:
barfowl 2014-10-13 12:17:25 -07:00
parent 5b7462286f
commit df23812759
3 changed files with 72 additions and 44 deletions

View File

@ -74,8 +74,9 @@ FVarLevel::resizeComponents() {
_faceVertValues.resize(_level.getNumFaceVerticesTotal()); _faceVertValues.resize(_level.getNumFaceVerticesTotal());
// Per-edge members: // Per-edge members:
_edgeTags.resize(_level.getNumEdges()); ETag edgeTagMatch;
std::memset(&_edgeTags[0], 0, _level.getNumEdges() * sizeof(ETag)); edgeTagMatch.clear();
_edgeTags.resize(_level.getNumEdges(), edgeTagMatch);
// Per-vertex members: // Per-vertex members:
_vertSiblingCounts.resize(_level.getNumVertices(), 0); _vertSiblingCounts.resize(_level.getNumVertices(), 0);
@ -140,11 +141,14 @@ FVarLevel::completeTopologyFromFaceValues() {
// values in cases where there are more than 2 values at a vertex, its unclear what the intent of // values in cases where there are more than 2 values at a vertex, its unclear what the intent of
// "propagate corners" is if more than 2 are present. // "propagate corners" is if more than 2 are present.
// //
bool sharpenAllIfMoreThan2 = (fvarOptions == Options::FVAR_LINEAR_CORNERS_PLUS1) || bool cornersPlus1 = (fvarOptions == Options::FVAR_LINEAR_CORNERS_PLUS1);
(fvarOptions == Options::FVAR_LINEAR_CORNERS_PLUS2); bool cornersPlus2 = (fvarOptions == Options::FVAR_LINEAR_CORNERS_PLUS2);
bool sharpenAllIfAnyCorner = (fvarOptions == Options::FVAR_LINEAR_CORNERS_PLUS2);
bool sharpenDarts = sharpenAllIfAnyCorner || !_hasSmoothBoundaries; bool considerEntireVertex = cornersPlus1 || cornersPlus2;
bool sharpenAllIfMoreThan2 = considerEntireVertex;
bool sharpenAllIfAnyCorner = cornersPlus2;
bool sharpenDarts = cornersPlus2 || !_hasSmoothBoundaries;
// //
// Its awkward and potentially inefficient to try and accomplish everything in one // Its awkward and potentially inefficient to try and accomplish everything in one
@ -172,13 +176,11 @@ FVarLevel::completeTopologyFromFaceValues() {
// //
// Still looking or opportunities to economize effort between the two passes... // Still looking or opportunities to economize effort between the two passes...
// //
ValueTag valueTagMatch(false); ValueTag valueTagMatch;
valueTagMatch._crease = false; valueTagMatch.clear();
valueTagMatch._semiSharp = false;
ValueTag valueTagMismatch(true); ValueTag valueTagMismatch = valueTagMatch;
valueTagMismatch._crease = false; valueTagMismatch._mismatch = true;
valueTagMismatch._semiSharp = false;
_vertValueTags.resize(_level.getNumVertices(), valueTagMatch); _vertValueTags.resize(_level.getNumVertices(), valueTagMatch);
_vertFaceSiblings.resize(_level.getNumVertexFacesTotal(), 0); _vertFaceSiblings.resize(_level.getNumVertexFacesTotal(), 0);
@ -223,7 +225,7 @@ FVarLevel::completeTopologyFromFaceValues() {
} else { } else {
// Tag the corresponding edge as discts: // Tag the corresponding edge as discts:
Index eIndex = vEdges[i]; Index eIndex = vEdges[i];
ETag& eTag = _edgeTags[eIndex]; ETag& eTag = _edgeTags[eIndex];
if (vInEdge[i] == 0) { if (vInEdge[i] == 0) {
eTag._disctsV0 = true; eTag._disctsV0 = true;
@ -317,11 +319,9 @@ FVarLevel::completeTopologyFromFaceValues() {
// vertex and to inspect local face-varying topology in more detail when necessary: // vertex and to inspect local face-varying topology in more detail when necessary:
// //
ValueTag valueTagCrease = valueTagMismatch; ValueTag valueTagCrease = valueTagMismatch;
valueTagCrease._crease = true; valueTagCrease._crease = true;
valueTagCrease._semiSharp = false;
ValueTag valueTagSemiSharp = valueTagMismatch; ValueTag valueTagSemiSharp = valueTagMismatch;
valueTagSemiSharp._crease = false;
valueTagSemiSharp._semiSharp = true; valueTagSemiSharp._semiSharp = true;
for (int vIndex = 0; vIndex < _level.getNumVertices(); ++vIndex) { for (int vIndex = 0; vIndex < _level.getNumVertices(); ++vIndex) {

View File

@ -91,7 +91,8 @@ public:
// //
struct ETag { struct ETag {
ETag() { } ETag() { }
ETag(bool mismatch) : _mismatch(mismatch) { }
void clear() { std::memset(this, 0, sizeof(ETag)); }
typedef unsigned char ETagSize; typedef unsigned char ETagSize;
@ -109,7 +110,8 @@ public:
// //
struct ValueTag { struct ValueTag {
ValueTag() { } ValueTag() { }
ValueTag(bool mismatch) : _mismatch(mismatch) { }
void clear() { std::memset(this, 0, sizeof(ValueTag)); }
typedef unsigned char ValueTagSize; typedef unsigned char ValueTagSize;

View File

@ -320,7 +320,9 @@ FVarRefinement::propagateEdgeTags() {
// - child edge for the matching end inherits tag // - child edge for the matching end inherits tag
// - child edge at the other end is doubly discts // - child edge at the other end is doubly discts
// //
FVarLevel::ETag eTagMatch(false); FVarLevel::ETag eTagMatch;
eTagMatch.clear();
eTagMatch._mismatch = false;
for (int eIndex = 0; eIndex < _refinement._childEdgeFromFaceCount; ++eIndex) { for (int eIndex = 0; eIndex < _refinement._childEdgeFromFaceCount; ++eIndex) {
_child->_edgeTags[eIndex] = eTagMatch; _child->_edgeTags[eIndex] = eTagMatch;
@ -350,7 +352,8 @@ FVarRefinement::propagateValueTags() {
// //
// Values from face-vertices -- all match: // Values from face-vertices -- all match:
// //
FVarLevel::ValueTag valTagMatch(false); FVarLevel::ValueTag valTagMatch;
valTagMatch.clear();
Index cVert = 0; Index cVert = 0;
for (cVert = 0; cVert < _refinement._childVertFromFaceCount; ++cVert) { for (cVert = 0; cVert < _refinement._childVertFromFaceCount; ++cVert) {
@ -361,13 +364,11 @@ FVarRefinement::propagateValueTags() {
// Values from edge-vertices -- for edges that are split, tag as mismatched and tag // Values from edge-vertices -- for edges that are split, tag as mismatched and tag
// as corner or crease depending on the presence of creases in the parent: // as corner or crease depending on the presence of creases in the parent:
// //
FVarLevel::ValueTag valTagMismatch(true); FVarLevel::ValueTag valTagMismatch = valTagMatch;
valTagMismatch._crease = false; valTagMismatch._mismatch = true;
valTagMismatch._semiSharp = false;
FVarLevel::ValueTag valTagCrease(true); FVarLevel::ValueTag valTagCrease = valTagMismatch;
valTagCrease._crease = true; valTagCrease._crease = true;
valTagCrease._semiSharp = false;
FVarLevel::ValueTag& valTagSplitEdge = _parent->_hasSmoothBoundaries ? valTagCrease : valTagMismatch; FVarLevel::ValueTag& valTagSplitEdge = _parent->_hasSmoothBoundaries ? valTagCrease : valTagMismatch;
@ -494,12 +495,14 @@ FVarRefinement::reclassifySemisharpValues() {
// their parent values -- we will be able to clear it in many simple cases but // their parent values -- we will be able to clear it in many simple cases but
// ultimately will need to inspect each value: // ultimately will need to inspect each value:
// //
FVarLevel::ValueTag valTagCrease(true); FVarLevel::ValueTag valTagCrease;
valTagCrease._crease = true; valTagCrease.clear();
valTagCrease._semiSharp = false; valTagCrease._mismatch = true;
valTagCrease._crease = true;
FVarLevel::ValueTag valTagSemiSharp(true); FVarLevel::ValueTag valTagSemiSharp;
valTagSemiSharp._crease = false; valTagSemiSharp.clear();
valTagSemiSharp._mismatch = true;
valTagSemiSharp._semiSharp = true; valTagSemiSharp._semiSharp = true;
Index cVert = _refinement._childVertFromFaceCount + _refinement._childVertFromEdgeCount; Index cVert = _refinement._childVertFromFaceCount + _refinement._childVertFromEdgeCount;
@ -559,31 +562,54 @@ FVarRefinement::reclassifySemisharpValues() {
} }
float float
FVarRefinement::getFractionalWeight(Index pVert, Sibling /* pSibling */, FVarRefinement::getFractionalWeight(Index pVert, Sibling pSibling,
Index cVert, Sibling /* cSibling */) const Index cVert, Sibling /* cSibling */) const
{ {
FVarLevel const& parentFVar = *_parent;
Level const& parent = *_refinement._parent;
Level const& child = *_refinement._child;
// Should only be called when the parent was semi-sharp but this child vertex // Should only be called when the parent was semi-sharp but this child vertex
// value (not necessarily the child vertex as a whole) is no longer semi-sharp: // value (not necessarily the child vertex as a whole) is no longer semi-sharp:
assert(_refinement._parent->_vertTags[pVert]._semiSharp); assert(parent._vertTags[pVert]._semiSharp);
assert(!child._vertTags[cVert]._incomplete);
float pVertSharpness = _refinement._parent->_vertSharpness[pVert];
float cVertSharpness = _refinement._child->_vertSharpness[cVert];
// //
// Need to identify sharpness values for edges within the spans for both the // Need to identify sharpness values for edges within the spans for both the
// parent and child... // parent and child...
// //
int numValueEdges = 0; // Consider gathering the complete parent and child sharpness vectors outside
float * pEdgeSharpness = 0; // this method and re-using them for each sibling, i.e. passing them to this
float * cEdgeSharpness = 0; // method somehow. We may also need them there for mask-related purposes...
//
IndexArray const pVertEdges = parent.getVertexEdges(pVert);
IndexArray const cVertEdges = child.getVertexEdges(cVert);
if (Sdc::Crease::IsSmooth(pVertSharpness)) { float * pEdgeSharpness = (float*) alloca(2 * pVertEdges.size() * sizeof(float));
printf("Warning -- FVarRefinement::getFractionalWeight() currently ignores edge sharpness...\n"); float * cEdgeSharpness = pEdgeSharpness + pVertEdges.size();
// Consider fully sharp until we gather and average the edge sharpness values...
return 1.0; int pValueIndex = parentFVar.getVertexValueIndex(pVert, pSibling);
LocalIndex const * pSiblingEnds = &parentFVar._vertValueCreaseEnds[2 * pValueIndex];
int interiorEdgeCount = 0;
if (pSiblingEnds[1] > pSiblingEnds[0]) {
for (int i = pSiblingEnds[0] + 1; i <= pSiblingEnds[1]; ++i, ++interiorEdgeCount) {
pEdgeSharpness[interiorEdgeCount] = parent._edgeSharpness[pVertEdges[i]];
cEdgeSharpness[interiorEdgeCount] = child._edgeSharpness[cVertEdges[i]];
}
} else if (pSiblingEnds[0] > pSiblingEnds[1]) {
for (int i = pSiblingEnds[0] + 1; i < pVertEdges.size(); ++i, ++interiorEdgeCount) {
pEdgeSharpness[interiorEdgeCount] = parent._edgeSharpness[pVertEdges[i]];
cEdgeSharpness[interiorEdgeCount] = child._edgeSharpness[cVertEdges[i]];
}
for (int i = 0; i <= pSiblingEnds[1]; ++i, ++interiorEdgeCount) {
pEdgeSharpness[interiorEdgeCount] = parent._edgeSharpness[pVertEdges[i]];
cEdgeSharpness[interiorEdgeCount] = child._edgeSharpness[cVertEdges[i]];
}
} }
return Sdc::Crease(_refinement._schemeOptions).ComputeFractionalWeightAtVertex( return Sdc::Crease(_refinement._schemeOptions).ComputeFractionalWeightAtVertex(
pVertSharpness, cVertSharpness, numValueEdges, pEdgeSharpness, cEdgeSharpness); parent._vertSharpness[pVert], child._vertSharpness[cVert],
interiorEdgeCount, pEdgeSharpness, cEdgeSharpness);
} }
} // end namespace Vtr } // end namespace Vtr