mirror of
https://github.com/PixarAnimationStudios/OpenSubdiv
synced 2024-12-27 18:30:21 +00:00
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:
parent
5b7462286f
commit
df23812759
@ -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) {
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user