mirror of
https://github.com/PixarAnimationStudios/OpenSubdiv
synced 2024-11-15 08:20:08 +00:00
Revised Level::VTags for semi-sharpness and added corner tag:
- added new tag for sharp corner, now used in isolation - split single semi-sharp tag in two for vertex and edge sharpness - updated tag propagation and all tests of previous semi-sharp tag - added clear() methods for all tags and simplified initialization
This commit is contained in:
parent
3c88851cf6
commit
4ced1b1461
@ -523,7 +523,7 @@ TopologyRefiner::selectFeatureAdaptiveComponents(Vtr::SparseSelector& selector)
|
||||
// support regular patches with one corner or one boundary, i.e. with one or more
|
||||
// smooth interior vertices.
|
||||
selectFace = true;
|
||||
} else if (compFaceVTag._semiSharp) {
|
||||
} else if (compFaceVTag._semiSharp || compFaceVTag._semiSharpEdges) {
|
||||
// Any semi-sharp feature at or around the vertex warrants isolation -- unless we
|
||||
// optimize for the single-crease patch, i.e. only edge sharpness of a constant value
|
||||
// along the entire regular patch boundary (quickly exclude the Corner case first):
|
||||
@ -552,17 +552,25 @@ TopologyRefiner::selectFeatureAdaptiveComponents(Vtr::SparseSelector& selector)
|
||||
// boundary patch, so don't isolate.
|
||||
selectFace = false;
|
||||
} else {
|
||||
// This is the last case with at least one Corner (infinitely-sharp) vertex and one
|
||||
// Smooth (interior) vertex. Distinguish the regular corner case from others -- this
|
||||
// is where the _corner tag on the vertex would help but we still need ensure that no
|
||||
// vertex other than the corner is sharp, and so inspection of each is unavoidable...
|
||||
unsigned int boundaryCount = level._vertTags[faceVerts[0]]._boundary,
|
||||
infSharpCount = level._vertTags[faceVerts[0]]._infSharp;
|
||||
for (int i = 1; i < faceVerts.size(); ++i) {
|
||||
boundaryCount += level._vertTags[faceVerts[i]]._boundary;
|
||||
infSharpCount += level._vertTags[faceVerts[i]]._infSharp;
|
||||
// The last case with at least one Corner vertex and one Smooth (interior) vertex --
|
||||
// distinguish the regular corner case from others:
|
||||
if (not compFaceVTag._corner) {
|
||||
// We may consider interior sharp corners as regular in future, but for now we
|
||||
// only accept a topological corner for the regular corner case:
|
||||
selectFace = true;
|
||||
} else if (level.getDepth() > 0) {
|
||||
// A true corner at a subdivided level -- adjacent verts must be Crease and the
|
||||
// opposite Smooth so we must have a regular corner:
|
||||
selectFace = false;
|
||||
} else {
|
||||
// Make sure the adjacent boundary vertices were not sharpened, or equivalently,
|
||||
// that only one corner is sharp:
|
||||
unsigned int infSharpCount = level._vertTags[faceVerts[0]]._infSharp;
|
||||
for (int i = 1; i < faceVerts.size(); ++i) {
|
||||
infSharpCount += level._vertTags[faceVerts[i]]._infSharp;
|
||||
}
|
||||
selectFace = (infSharpCount != 1);
|
||||
}
|
||||
selectFace = (boundaryCount != 3) || (infSharpCount != 1);
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -175,8 +175,9 @@ TopologyRefinerFactoryBase::prepareComponentTagsAndSharpness(TopologyRefiner& re
|
||||
// Sharpen the vertex before using it in conjunction with incident edge
|
||||
// properties to determine the semi-sharp tag and rule:
|
||||
//
|
||||
bool isCorner = (vFaces.size() == 1) && (vEdges.size() == 2);
|
||||
if (isCorner && sharpenCornerVerts) {
|
||||
bool isTopologicalCorner = (vFaces.size() == 1) && (vEdges.size() == 2);
|
||||
bool isSharpenedCorner = isTopologicalCorner && sharpenCornerVerts;
|
||||
if (isSharpenedCorner) {
|
||||
vSharpness = Sdc::Crease::SHARPNESS_INFINITE;
|
||||
} else if (vTag._nonManifold && sharpenNonManFeatures) {
|
||||
// Don't sharpen the vertex if a non-manifold crease:
|
||||
@ -185,9 +186,9 @@ TopologyRefinerFactoryBase::prepareComponentTagsAndSharpness(TopologyRefiner& re
|
||||
}
|
||||
}
|
||||
|
||||
vTag._infSharp = Sdc::Crease::IsInfinite(vSharpness);
|
||||
|
||||
vTag._semiSharp = Sdc::Crease::IsSemiSharp(vSharpness) || (semiSharpEdgeCount > 0);
|
||||
vTag._infSharp = Sdc::Crease::IsInfinite(vSharpness);
|
||||
vTag._semiSharp = Sdc::Crease::IsSemiSharp(vSharpness);
|
||||
vTag._semiSharpEdges = (semiSharpEdgeCount > 0);
|
||||
|
||||
vTag._rule = (Vtr::Level::VTag::VTagSize)creasing.DetermineVertexVertexRule(vSharpness, sharpEdgeCount);
|
||||
|
||||
@ -196,8 +197,9 @@ TopologyRefinerFactoryBase::prepareComponentTagsAndSharpness(TopologyRefiner& re
|
||||
// tag is still being considered, but regardless, it depends on the Sdc::Scheme...
|
||||
//
|
||||
vTag._boundary = (vFaces.size() < vEdges.size());
|
||||
if (isCorner) {
|
||||
vTag._xordinary = !sharpenCornerVerts;
|
||||
vTag._corner = isSharpenedCorner;
|
||||
if (vTag._corner) {
|
||||
vTag._xordinary = false;
|
||||
} else if (vTag._boundary) {
|
||||
vTag._xordinary = (vFaces.size() != schemeRegularBoundaryValence);
|
||||
} else {
|
||||
|
@ -554,16 +554,20 @@ FVarRefinement::reclassifySemisharpValues() {
|
||||
if (_refinement._childVertexTag[cVert]._incomplete) continue;
|
||||
|
||||
// If the parent vertex wasn't semi-sharp, the child vertex and values can't be:
|
||||
Index pVert = _refinement.getChildVertexParentIndex(cVert);
|
||||
if (!_parentLevel._vertTags[pVert]._semiSharp) continue;
|
||||
Index pVert = _refinement.getChildVertexParentIndex(cVert);
|
||||
Level::VTag pVertTags = _parentLevel._vertTags[pVert];
|
||||
|
||||
if (!pVertTags._semiSharp && !pVertTags._semiSharpEdges) continue;
|
||||
|
||||
// If the child vertex is still sharp, all values remain unaffected:
|
||||
if (!Sdc::Crease::IsSmooth(_childLevel._vertSharpness[cVert])) continue;
|
||||
Level::VTag cVertTags = _childLevel._vertTags[cVert];
|
||||
|
||||
if (cVertTags._semiSharp || cVertTags._infSharp) continue;
|
||||
|
||||
// If the child is no longer semi-sharp, we can just clear those values marked
|
||||
// (i.e. make them creases, others may remain corners) and continue:
|
||||
//
|
||||
if (!_childLevel._vertTags[cVert]._semiSharp) {
|
||||
if (!cVertTags._semiSharp && !cVertTags._semiSharpEdges) {
|
||||
for (int j = 0; j < cValueTags.size(); ++j) {
|
||||
if (cValueTags[j]._semiSharp) {
|
||||
FVarLevel::ValueTag cValueTagOld = cValueTags[j];
|
||||
@ -626,11 +630,6 @@ float
|
||||
FVarRefinement::getFractionalWeight(Index pVert, LocalIndex pSibling,
|
||||
Index cVert, LocalIndex /* cSibling */) const {
|
||||
|
||||
// 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:
|
||||
assert(_parentLevel._vertTags[pVert]._semiSharp);
|
||||
assert(!_childLevel._vertTags[cVert]._incomplete);
|
||||
|
||||
//
|
||||
// Need to identify sharpness values for edges within the spans for both the
|
||||
// parent and child...
|
||||
|
@ -517,9 +517,11 @@ Level::print(const Refinement* pRefinement) const {
|
||||
printf(" vert %4d:", i);
|
||||
printf(" rule = %s", ruleString((Sdc::Crease::Rule)vTag._rule));
|
||||
printf(", boundary = %d", (int)vTag._boundary);
|
||||
printf(", corner = %d", (int)vTag._corner);
|
||||
printf(", xordinary = %d", (int)vTag._xordinary);
|
||||
printf(", semiSharp = %d", (int)vTag._semiSharp);
|
||||
printf(", infSharp = %d", (int)vTag._infSharp);
|
||||
printf(", semiSharp = %d", (int)vTag._semiSharp);
|
||||
printf(", semiSharpEdges = %d", (int)vTag._semiSharpEdges);
|
||||
printf("\n");
|
||||
}
|
||||
fflush(stdout);
|
||||
|
@ -135,17 +135,24 @@ public:
|
||||
// level.
|
||||
//
|
||||
struct VTag {
|
||||
typedef unsigned short VTagSize;
|
||||
|
||||
VTag() { }
|
||||
|
||||
VTagSize _nonManifold : 1; // fixed
|
||||
VTagSize _xordinary : 1; // fixed
|
||||
VTagSize _boundary : 1; // fixed
|
||||
VTagSize _infSharp : 1; // fixed
|
||||
VTagSize _semiSharp : 1; // variable
|
||||
VTagSize _rule : 4; // variable when _semiSharp
|
||||
VTagSize _incomplete : 1; // variable for sparse refinement
|
||||
// When cleared, the VTag ALMOST represents a smooth, regular, interior
|
||||
// vertex -- the Type enum requires a bit be explicitly set for Smooth,
|
||||
// so that must be done explicitly if desired on initialization.
|
||||
void clear() { std::memset(this, 0, sizeof(VTag)); }
|
||||
|
||||
typedef unsigned short VTagSize;
|
||||
|
||||
VTagSize _nonManifold : 1; // fixed
|
||||
VTagSize _xordinary : 1; // fixed
|
||||
VTagSize _boundary : 1; // fixed
|
||||
VTagSize _corner : 1; // fixed
|
||||
VTagSize _infSharp : 1; // fixed
|
||||
VTagSize _semiSharp : 1; // variable
|
||||
VTagSize _semiSharpEdges : 1; // variable
|
||||
VTagSize _rule : 4; // variable when _semiSharp
|
||||
VTagSize _incomplete : 1; // variable for sparse refinement
|
||||
|
||||
// On deck -- coming soon...
|
||||
//VTagSize _constSharp : 1; // variable when _semiSharp
|
||||
@ -153,20 +160,25 @@ public:
|
||||
//VTagSize _editsApplied : 1; // variable
|
||||
};
|
||||
struct ETag {
|
||||
typedef unsigned char ETagSize;
|
||||
|
||||
ETag() { }
|
||||
|
||||
// When cleared, the ETag represents a smooth, manifold, interior edge
|
||||
void clear() { std::memset(this, 0, sizeof(ETag)); }
|
||||
|
||||
typedef unsigned char ETagSize;
|
||||
|
||||
ETagSize _nonManifold : 1; // fixed
|
||||
ETagSize _boundary : 1; // fixed
|
||||
ETagSize _infSharp : 1; // fixed
|
||||
ETagSize _semiSharp : 1; // variable
|
||||
};
|
||||
struct FTag {
|
||||
typedef unsigned char FTagSize;
|
||||
|
||||
FTag() { }
|
||||
|
||||
void clear() { std::memset(this, 0, sizeof(FTag)); }
|
||||
|
||||
typedef unsigned char FTagSize;
|
||||
|
||||
FTagSize _hole : 1; // fixed
|
||||
|
||||
// On deck -- coming soon...
|
||||
|
@ -665,10 +665,7 @@ Refinement::populateEdgeTagsFromParentFaces() {
|
||||
// Tags for edges originating from faces are all constant:
|
||||
//
|
||||
Level::ETag eTag;
|
||||
eTag._nonManifold = 0;
|
||||
eTag._boundary = 0;
|
||||
eTag._infSharp = 0;
|
||||
eTag._semiSharp = 0;
|
||||
eTag.clear();
|
||||
|
||||
Index cEdge = getFirstChildEdgeFromFaces();
|
||||
Index cEdgeEnd = cEdge + getNumChildEdgesFromFaces();
|
||||
@ -717,13 +714,8 @@ Refinement::populateVertexTagsFromParentFaces() {
|
||||
if (getNumChildVerticesFromFaces() == 0) return;
|
||||
|
||||
Level::VTag vTag;
|
||||
vTag._nonManifold = 0;
|
||||
vTag._xordinary = 0;
|
||||
vTag._boundary = 0;
|
||||
vTag._infSharp = 0;
|
||||
vTag._semiSharp = 0;
|
||||
vTag._rule = Sdc::Crease::RULE_SMOOTH;
|
||||
vTag._incomplete = 0;
|
||||
vTag.clear();
|
||||
vTag._rule = Sdc::Crease::RULE_SMOOTH;
|
||||
|
||||
Index cVert = getFirstChildVertexFromFaces();
|
||||
Index cVertEnd = cVert + getNumChildVerticesFromFaces();
|
||||
@ -749,22 +741,25 @@ Refinement::populateVertexTagsFromParentEdges() {
|
||||
// Tags for vertices originating from edges are initialized according to the tags
|
||||
// of the parent edge:
|
||||
//
|
||||
Level::VTag vTag;
|
||||
vTag.clear();
|
||||
|
||||
for (Index pEdge = 0; pEdge < _parent->getNumEdges(); ++pEdge) {
|
||||
Index cVert = _edgeChildVertIndex[pEdge];
|
||||
if (!IndexIsValid(cVert)) continue;
|
||||
|
||||
// From the cleared local VTag, we just need to assign properties dependent
|
||||
// on the parent edge:
|
||||
Level::ETag const& pEdgeTag = _parent->_edgeTags[pEdge];
|
||||
Level::VTag& cVertTag = _child->_vertTags[cVert];
|
||||
|
||||
cVertTag._nonManifold = pEdgeTag._nonManifold;
|
||||
cVertTag._xordinary = false;
|
||||
cVertTag._boundary = pEdgeTag._boundary;
|
||||
cVertTag._infSharp = false;
|
||||
vTag._nonManifold = pEdgeTag._nonManifold;
|
||||
vTag._boundary = pEdgeTag._boundary;
|
||||
vTag._semiSharpEdges = pEdgeTag._semiSharp;
|
||||
|
||||
cVertTag._semiSharp = pEdgeTag._semiSharp;
|
||||
cVertTag._rule = (Level::VTag::VTagSize)((pEdgeTag._semiSharp || pEdgeTag._infSharp)
|
||||
vTag._rule = (Level::VTag::VTagSize)((pEdgeTag._semiSharp || pEdgeTag._infSharp)
|
||||
? Sdc::Crease::RULE_CREASE : Sdc::Crease::RULE_SMOOTH);
|
||||
cVertTag._incomplete = 0;
|
||||
|
||||
_child->_vertTags[cVert] = vTag;
|
||||
}
|
||||
}
|
||||
void
|
||||
@ -851,9 +846,13 @@ Refinement::subdivideSharpnessValues() {
|
||||
// process. So for now we apply a post-process to explicitly handle all
|
||||
// semi-sharp vertices.
|
||||
//
|
||||
|
||||
// These methods will update sharpness tags local to the edges and vertices:
|
||||
subdivideEdgeSharpness();
|
||||
subdivideVertexSharpness();
|
||||
|
||||
// This method uses local sharpness tags (set above) to update vertex tags that
|
||||
// reflect the neighborhood of the vertex (e.g. its rule):
|
||||
reclassifySemisharpVertices();
|
||||
}
|
||||
|
||||
@ -910,7 +909,9 @@ Refinement::subdivideEdgeSharpness() {
|
||||
cSharpness = creasing.SubdivideEdgeSharpnessAtVertex(pSharpness, pVertEdges.size(),
|
||||
pVertEdgeSharpness);
|
||||
}
|
||||
cEdgeTag._semiSharp = Sdc::Crease::IsSharp(cSharpness);
|
||||
if (not Sdc::Crease::IsSharp(cSharpness)) {
|
||||
cEdgeTag._semiSharp = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -942,11 +943,8 @@ Refinement::subdivideVertexSharpness() {
|
||||
float pSharpness = _parent->_vertSharpness[pVert];
|
||||
|
||||
cSharpness = creasing.SubdivideVertexSharpness(pSharpness);
|
||||
|
||||
if (!Sdc::Crease::IsSharp(cSharpness)) {
|
||||
// Need to visit edge neighborhood to determine if still semisharp...
|
||||
// cVertTag._infSharp = ...?
|
||||
// See the "reclassify" method below...
|
||||
if (not Sdc::Crease::IsSharp(cSharpness)) {
|
||||
cVertTag._semiSharp = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -969,7 +967,7 @@ Refinement::reclassifySemisharpVertices() {
|
||||
|
||||
for (Index cVert = vertFromEdgeBegin; cVert < vertFromEdgeEnd; ++cVert) {
|
||||
Level::VTag& cVertTag = _child->_vertTags[cVert];
|
||||
if (!cVertTag._semiSharp) continue;
|
||||
if (!cVertTag._semiSharpEdges) continue;
|
||||
|
||||
Index pEdge = _childVertexParentIndex[cVert];
|
||||
|
||||
@ -977,21 +975,21 @@ Refinement::reclassifySemisharpVertices() {
|
||||
|
||||
if (_childVertexTag[cVert]._incomplete) {
|
||||
// One child edge likely missing -- assume Crease if remaining edge semi-sharp:
|
||||
cVertTag._semiSharp = (IndexIsValid(cEdges[0]) && _child->_edgeTags[cEdges[0]]._semiSharp) ||
|
||||
(IndexIsValid(cEdges[1]) && _child->_edgeTags[cEdges[1]]._semiSharp);
|
||||
cVertTag._rule = (VTagSize)(cVertTag._semiSharp ? Sdc::Crease::RULE_CREASE : Sdc::Crease::RULE_SMOOTH);
|
||||
cVertTag._semiSharpEdges = (IndexIsValid(cEdges[0]) && _child->_edgeTags[cEdges[0]]._semiSharp) ||
|
||||
(IndexIsValid(cEdges[1]) && _child->_edgeTags[cEdges[1]]._semiSharp);
|
||||
cVertTag._rule = (VTagSize)(cVertTag._semiSharpEdges ? Sdc::Crease::RULE_CREASE : Sdc::Crease::RULE_SMOOTH);
|
||||
} else {
|
||||
int sharpEdgeCount = _child->_edgeTags[cEdges[0]]._semiSharp + _child->_edgeTags[cEdges[1]]._semiSharp;
|
||||
|
||||
cVertTag._semiSharp = (sharpEdgeCount > 0);
|
||||
cVertTag._rule = (VTagSize)(creasing.DetermineVertexVertexRule(0.0, sharpEdgeCount));
|
||||
cVertTag._semiSharpEdges = (sharpEdgeCount > 0);
|
||||
cVertTag._rule = (VTagSize)(creasing.DetermineVertexVertexRule(0.0, sharpEdgeCount));
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Inspect all vertices derived from vertices -- for those whose parent vertices were
|
||||
// semisharp, reset the semisharp tag and the associated Rule based on the neighborhood
|
||||
// of child edges around the child vertex.
|
||||
// semisharp (inherited in the child vert's tag), inspect and reset the semisharp tag
|
||||
// and the associated Rule (based on neighboring child edges around the child vertex).
|
||||
//
|
||||
// We should never find such a vertex "incomplete" in a sparse refinement as a parent
|
||||
// vertex is either selected or not, but never neighboring. So the only complication
|
||||
@ -1006,47 +1004,56 @@ Refinement::reclassifySemisharpVertices() {
|
||||
Index vertFromVertEnd = vertFromVertBegin + getNumChildVerticesFromVertices();
|
||||
|
||||
for (Index cVert = vertFromVertBegin; cVert < vertFromVertEnd; ++cVert) {
|
||||
Index pVert = _childVertexParentIndex[cVert];
|
||||
Level::VTag const& pVertTag = _parent->_vertTags[pVert];
|
||||
|
||||
// Skip if parent not semi-sharp:
|
||||
if (!pVertTag._semiSharp && !pVertTag._semiSharpEdges) continue;
|
||||
|
||||
//
|
||||
// We need to inspect the child neighborhood's sharpness when either semi-sharp
|
||||
// edges were present around the parent vertex, or the parent vertex sharpness
|
||||
// decayed:
|
||||
//
|
||||
Level::VTag& cVertTag = _child->_vertTags[cVert];
|
||||
if (!cVertTag._semiSharp) continue;
|
||||
|
||||
// If the vertex is still sharp, it remains the semisharp Corner its parent was...
|
||||
if (_child->_vertSharpness[cVert] > 0.0) continue;
|
||||
bool sharpVertexDecayed = pVertTag._semiSharp && !cVertTag._semiSharp;
|
||||
|
||||
//
|
||||
// See if we can use the vert-edges of the child vertex:
|
||||
//
|
||||
int sharpEdgeCount = 0;
|
||||
int semiSharpEdgeCount = 0;
|
||||
if (pVertTag._semiSharpEdges || sharpVertexDecayed) {
|
||||
int infSharpEdgeCount = 0;
|
||||
int semiSharpEdgeCount = 0;
|
||||
|
||||
bool cVertEdgesPresent = (_child->getNumVertexEdgesTotal() > 0);
|
||||
if (cVertEdgesPresent) {
|
||||
IndexArray const cEdges = _child->getVertexEdges(cVert);
|
||||
bool cVertEdgesPresent = (_child->getNumVertexEdgesTotal() > 0);
|
||||
if (cVertEdgesPresent) {
|
||||
IndexArray const cEdges = _child->getVertexEdges(cVert);
|
||||
|
||||
for (int i = 0; i < cEdges.size(); ++i) {
|
||||
Level::ETag cEdgeTag = _child->_edgeTags[cEdges[i]];
|
||||
for (int i = 0; i < cEdges.size(); ++i) {
|
||||
Level::ETag cEdgeTag = _child->_edgeTags[cEdges[i]];
|
||||
|
||||
sharpEdgeCount += cEdgeTag._semiSharp || cEdgeTag._infSharp;
|
||||
semiSharpEdgeCount += cEdgeTag._semiSharp;
|
||||
infSharpEdgeCount += cEdgeTag._infSharp;
|
||||
semiSharpEdgeCount += cEdgeTag._semiSharp;
|
||||
}
|
||||
} else {
|
||||
ConstIndexArray pEdges = _parent->getVertexEdges(pVert);
|
||||
ConstLocalIndexArray pVertInEdge = _parent->getVertexEdgeLocalIndices(pVert);
|
||||
|
||||
for (int i = 0; i < pEdges.size(); ++i) {
|
||||
ConstIndexArray cEdgePair = getEdgeChildEdges(pEdges[i]);
|
||||
|
||||
Index cEdge = cEdgePair[pVertInEdge[i]];
|
||||
Level::ETag cEdgeTag = _child->_edgeTags[cEdge];
|
||||
|
||||
infSharpEdgeCount += cEdgeTag._infSharp;
|
||||
semiSharpEdgeCount += cEdgeTag._semiSharp;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Index pVert = _childVertexParentIndex[cVert];
|
||||
cVertTag._semiSharpEdges = (semiSharpEdgeCount > 0);
|
||||
|
||||
ConstIndexArray pEdges = _parent->getVertexEdges(pVert);
|
||||
ConstLocalIndexArray pVertInEdge = _parent->getVertexEdgeLocalIndices(pVert);
|
||||
|
||||
for (int i = 0; i < pEdges.size(); ++i) {
|
||||
ConstIndexArray cEdgePair = getEdgeChildEdges(pEdges[i]);
|
||||
|
||||
Index cEdge = cEdgePair[pVertInEdge[i]];
|
||||
Level::ETag cEdgeTag = _child->_edgeTags[cEdge];
|
||||
|
||||
sharpEdgeCount += cEdgeTag._semiSharp || cEdgeTag._infSharp;
|
||||
semiSharpEdgeCount += cEdgeTag._semiSharp;
|
||||
if (!cVertTag._semiSharp && !cVertTag._infSharp) {
|
||||
cVertTag._rule = (VTagSize)(creasing.DetermineVertexVertexRule(0.0,
|
||||
infSharpEdgeCount + semiSharpEdgeCount));
|
||||
}
|
||||
}
|
||||
|
||||
cVertTag._semiSharp = (semiSharpEdgeCount > 0);
|
||||
cVertTag._rule = (VTagSize)(creasing.DetermineVertexVertexRule(0.0, sharpEdgeCount));
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user