mirror of
https://github.com/PixarAnimationStudios/OpenSubdiv
synced 2024-11-09 22:00:06 +00:00
Fix infinitely sharp edges isolation
- change topology refiner to check for edge sharpnesses when selecting faces for isolation - add face-aggregator for edge tags to Vtr::Level - fix logic in Far::PatchTablesFactory to correctly tag single-crease patches along infinitely sharp edges note : this fix is a bit of a cludge - barfowl confirms that the vertex crease tags (VTags) are intended to carry neighborhood information, which they currently do not. we will revisit this shortly and fix the tags, which will allow us to simplify the traversal logic when isolating topology features. fixes #369
This commit is contained in:
parent
5faa961bf6
commit
15b4135cfb
@ -48,6 +48,7 @@ static std::vector<ShapeDesc> g_defaultShapes;
|
||||
#include <shapes/catmark_cube_corner4.h>
|
||||
#include <shapes/catmark_cube_creases0.h>
|
||||
#include <shapes/catmark_cube_creases1.h>
|
||||
#include <shapes/catmark_cube_creases2.h>
|
||||
#include <shapes/catmark_cube.h>
|
||||
#include <shapes/catmark_dart_edgecorner.h>
|
||||
#include <shapes/catmark_dart_edgeonly.h>
|
||||
@ -110,6 +111,7 @@ static void initShapes() {
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_cube_corner4", catmark_cube_corner4, kCatmark ) );
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_cube_creases0", catmark_cube_creases0, kCatmark ) );
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_cube_creases1", catmark_cube_creases1, kCatmark ) );
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_cube_creases2", catmark_cube_creases2, kCatmark ) );
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_cube", catmark_cube, kCatmark ) );
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_dart_edgecorner", catmark_dart_edgecorner, kCatmark ) );
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_dart_edgeonly", catmark_dart_edgeonly, kCatmark ) );
|
||||
|
@ -1000,7 +1000,7 @@ PatchTablesFactory::identifyAdaptivePatches( TopologyRefiner const & refiner,
|
||||
assert(!compFaceVertTag._nonManifold);
|
||||
|
||||
patchTag._hasPatch = true;
|
||||
patchTag._isRegular = !compFaceVertTag._xordinary;
|
||||
patchTag._isRegular = not compFaceVertTag._xordinary;
|
||||
|
||||
int boundaryEdgeMask = 0;
|
||||
|
||||
@ -1008,17 +1008,22 @@ PatchTablesFactory::identifyAdaptivePatches( TopologyRefiner const & refiner,
|
||||
|
||||
// single crease patch optimization
|
||||
if (options.useSingleCreasePatch and
|
||||
!compFaceVertTag._xordinary and compFaceVertTag._semiSharp and not hasBoundaryVertex) {
|
||||
not compFaceVertTag._xordinary and not hasBoundaryVertex) {
|
||||
|
||||
float sharpness = 0;
|
||||
int rotation = 0;
|
||||
if (level->isSingleCreasePatch(faceIndex, &sharpness, &rotation)) {
|
||||
Vtr::ConstIndexArray fEdges = level->getFaceEdges(faceIndex);
|
||||
Vtr::Level::ETag compFaceETag = level->getFaceCompositeETag(fEdges);
|
||||
|
||||
// cap sharpness to the max isolation level
|
||||
float cappedSharpness = std::min(sharpness, (float)(options.maxIsolationLevel-i));
|
||||
if (cappedSharpness > 0) {
|
||||
patchTag._isSingleCrease = true;
|
||||
patchTag._boundaryIndex = (rotation + 2) % 4;
|
||||
if (compFaceETag._semiSharp or compFaceETag._infSharp) {
|
||||
float sharpness = 0;
|
||||
int rotation = 0;
|
||||
if (level->isSingleCreasePatch(faceIndex, &sharpness, &rotation)) {
|
||||
|
||||
// cap sharpness to the max isolation level
|
||||
float cappedSharpness = std::min(sharpness, (float)(options.maxIsolationLevel-i));
|
||||
if (cappedSharpness > 0) {
|
||||
patchTag._isSingleCrease = true;
|
||||
patchTag._boundaryIndex = (rotation + 2) % 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -433,7 +433,7 @@ TopologyRefiner::RefineAdaptive(int subdivLevel, bool fullTopology, bool useSing
|
||||
// This was originally written specific to the quad-centric Catmark scheme and was since
|
||||
// generalized to support Loop given the enhanced tagging of components based on the scheme.
|
||||
// Any further enhancements here, e.g. new approaches for dealing with infinitely sharp
|
||||
// creases, should be aware of the intended generality. Ultimately it may not be worth
|
||||
// creases, should be aware of the intended generality. Ultimately it may not be worth
|
||||
// trying to keep this general and we will be better off specializing it for each scheme.
|
||||
// The fact that this method is intimately tied to patch generation also begs for it to
|
||||
// become part of a class that encompasses both the feature adaptive tagging and the
|
||||
@ -448,11 +448,11 @@ TopologyRefiner::selectFeatureAdaptiveComponents(Vtr::SparseSelector& selector)
|
||||
bool considerSingleCreasePatch = _useSingleCreasePatch && (regularFaceSize == 4);
|
||||
|
||||
for (Vtr::Index face = 0; face < level.getNumFaces(); ++face) {
|
||||
|
||||
|
||||
if (level.isHole(face)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
Vtr::ConstIndexArray faceVerts = level.getFaceVertices(face);
|
||||
|
||||
//
|
||||
@ -482,32 +482,32 @@ TopologyRefiner::selectFeatureAdaptiveComponents(Vtr::SparseSelector& selector)
|
||||
// be necessary in some cases, particularly when we start trying to be clever about
|
||||
// minimizing refinement for inf-sharp creases, etc.):
|
||||
//
|
||||
Vtr::Level::VTag compFaceTag = level.getFaceCompositeVTag(faceVerts);
|
||||
if (compFaceTag._incomplete) {
|
||||
Vtr::Level::VTag compFaceVTag = level.getFaceCompositeVTag(faceVerts);
|
||||
if (compFaceVTag._incomplete) {
|
||||
continue;
|
||||
}
|
||||
|
||||
bool selectFace = false;
|
||||
if (compFaceTag._xordinary) {
|
||||
if (compFaceVTag._xordinary) {
|
||||
selectFace = true;
|
||||
} else if (compFaceTag._rule & Sdc::Crease::RULE_DART) {
|
||||
} else if (compFaceVTag._rule & Sdc::Crease::RULE_DART) {
|
||||
// Get this case out of the way before testing hard features
|
||||
selectFace = true;
|
||||
} else if (compFaceTag._nonManifold) {
|
||||
} else if (compFaceVTag._nonManifold) {
|
||||
// Warrants further inspection -- isolate for now
|
||||
// - will want to defer inf-sharp treatment to below
|
||||
selectFace = true;
|
||||
} else if (!(compFaceTag._rule & Sdc::Crease::RULE_SMOOTH)) {
|
||||
} else if (!(compFaceVTag._rule & Sdc::Crease::RULE_SMOOTH)) {
|
||||
// None of the vertices is Smooth, so we have all vertices either Crease or Corner,
|
||||
// though some may be regular patches, this currently warrants isolation as we only
|
||||
// support regular patches with one corner or one boundary.
|
||||
selectFace = true;
|
||||
} else if (compFaceTag._semiSharp) {
|
||||
} else if (compFaceVTag._semiSharp) {
|
||||
// if this is regular and the adjacent edges have same sharpness
|
||||
// and no vertex corner sharpness,
|
||||
// we can stop refinning and use single-crease patch.
|
||||
if (considerSingleCreasePatch) {
|
||||
selectFace = ! level.isSingleCreasePatch(face);
|
||||
selectFace = not level.isSingleCreasePatch(face);
|
||||
} else {
|
||||
selectFace = true;
|
||||
}
|
||||
@ -518,8 +518,26 @@ TopologyRefiner::selectFeatureAdaptiveComponents(Vtr::SparseSelector& selector)
|
||||
// that do warrant isolation -- needing further inspection.
|
||||
//
|
||||
// For now go with the boundary cases and don't isolate...
|
||||
selectFace = false;
|
||||
//selectFace = false;
|
||||
}
|
||||
|
||||
if (not selectFace) {
|
||||
// Infinitely sharp edges do not influence vertex flags, but they need to
|
||||
// isolated unless they can be treated as 'single-crease' cases.
|
||||
// XXXX manuelk this will probably have to be revisited once infinitely
|
||||
// sharp creases are handled correctly.
|
||||
Vtr::ConstIndexArray faceEdges = level.getFaceEdges(face);
|
||||
Vtr::Level::ETag compFaceETag = level.getFaceCompositeETag(faceEdges);
|
||||
if (compFaceETag._infSharp and not compFaceETag._boundary) {
|
||||
// XXXX manuelk we are testing an 'and' aggregate of flags for all
|
||||
// edges : this should be safe, because if the sharp edge is not
|
||||
// the edge on the boundary, this face would have been selected
|
||||
// with one of the previous tests
|
||||
selectFace = considerSingleCreasePatch ?
|
||||
not level.isSingleCreasePatch(face) : true;
|
||||
}
|
||||
}
|
||||
|
||||
if (selectFace) {
|
||||
selector.selectFace(face);
|
||||
}
|
||||
|
@ -553,7 +553,22 @@ Level::getFaceCompositeVTag(ConstIndexArray & faceVerts) const {
|
||||
}
|
||||
return compTag;
|
||||
}
|
||||
Level::ETag
|
||||
Level::getFaceCompositeETag(ConstIndexArray & faceEdges) const {
|
||||
|
||||
ETag compTag = _edgeTags[faceEdges[0]];
|
||||
|
||||
for (int i = 1; i < faceEdges.size(); ++i) {
|
||||
ETag const& edgeTag = _edgeTags[faceEdges[i]];
|
||||
|
||||
if (sizeof(ETag) == sizeof(unsigned char)) {
|
||||
combineTags<ETag, unsigned char>(compTag, edgeTag);
|
||||
} else {
|
||||
assert("ETag size is uint_8 -- need to adjust composite tag code..." == 0);
|
||||
}
|
||||
}
|
||||
return compTag;
|
||||
}
|
||||
|
||||
//
|
||||
// High-level topology gathering functions -- used mainly in patch construction. These
|
||||
|
@ -175,6 +175,8 @@ public:
|
||||
|
||||
VTag getFaceCompositeVTag(ConstIndexArray & faceVerts) const;
|
||||
|
||||
ETag getFaceCompositeETag(ConstIndexArray & faceEdges) const;
|
||||
|
||||
public:
|
||||
Level();
|
||||
~Level();
|
||||
|
94
regression/shapes/catmark_cube_creases2.h
Normal file
94
regression/shapes/catmark_cube_creases2.h
Normal file
@ -0,0 +1,94 @@
|
||||
//
|
||||
// Copyright 2013 Pixar
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "Apache License")
|
||||
// with the following modification; you may not use this file except in
|
||||
// compliance with the Apache License and the following modification to it:
|
||||
// Section 6. Trademarks. is deleted and replaced with:
|
||||
//
|
||||
// 6. Trademarks. This License does not grant permission to use the trade
|
||||
// names, trademarks, service marks, or product names of the Licensor
|
||||
// and its affiliates, except as required to comply with Section 4(c) of
|
||||
// the License and to reproduce the content of the NOTICE file.
|
||||
//
|
||||
// You may obtain a copy of the Apache License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the Apache License with the above modification is
|
||||
// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the Apache License for the specific
|
||||
// language governing permissions and limitations under the Apache License.
|
||||
//
|
||||
|
||||
static const std::string catmark_cube_creases2 =
|
||||
"# This file uses centimeters as units for non-parametric coordinates.\n"
|
||||
"\n"
|
||||
"v 0.000000 -1.414214 1.000000\n"
|
||||
"v 1.414214 0.000000 1.000000\n"
|
||||
"v -1.414214 0.000000 1.000000\n"
|
||||
"v 0.000000 1.414214 1.000000\n"
|
||||
"v -1.414214 0.000000 -1.000000\n"
|
||||
"v 0.000000 1.414214 -1.000000\n"
|
||||
"v 0.000000 -1.414214 -1.000000\n"
|
||||
"v 1.414214 0.000000 -1.000000\n"
|
||||
"vt 0.375000 0.000000\n"
|
||||
"vt 0.625000 0.000000\n"
|
||||
"vt 0.375000 0.250000\n"
|
||||
"vt 0.625000 0.250000\n"
|
||||
"vt 0.375000 0.500000\n"
|
||||
"vt 0.625000 0.500000\n"
|
||||
"vt 0.375000 0.750000\n"
|
||||
"vt 0.625000 0.750000\n"
|
||||
"vt 0.375000 1.000000\n"
|
||||
"vt 0.625000 1.000000\n"
|
||||
"vt 0.875000 0.000000\n"
|
||||
"vt 0.875000 0.250000\n"
|
||||
"vt 0.125000 0.000000\n"
|
||||
"vt 0.125000 0.250000\n"
|
||||
"vn 0.000000 0.000000 1.000000\n"
|
||||
"vn 0.000000 0.000000 1.000000\n"
|
||||
"vn 0.000000 0.000000 1.000000\n"
|
||||
"vn 0.000000 0.000000 1.000000\n"
|
||||
"vn -0.707107 0.707107 0.000000\n"
|
||||
"vn -0.707107 0.707107 0.000000\n"
|
||||
"vn -0.707107 0.707107 0.000000\n"
|
||||
"vn -0.707107 0.707107 0.000000\n"
|
||||
"vn 0.000000 0.000000 -1.000000\n"
|
||||
"vn 0.000000 0.000000 -1.000000\n"
|
||||
"vn 0.000000 0.000000 -1.000000\n"
|
||||
"vn 0.000000 0.000000 -1.000000\n"
|
||||
"vn 0.707107 -0.707107 0.000000\n"
|
||||
"vn 0.707107 -0.707107 0.000000\n"
|
||||
"vn 0.707107 -0.707107 0.000000\n"
|
||||
"vn 0.707107 -0.707107 0.000000\n"
|
||||
"vn 0.707107 0.707107 0.000000\n"
|
||||
"vn 0.707107 0.707107 0.000000\n"
|
||||
"vn 0.707107 0.707107 0.000000\n"
|
||||
"vn 0.707107 0.707107 0.000000\n"
|
||||
"vn -0.707107 -0.707107 0.000000\n"
|
||||
"vn -0.707107 -0.707107 0.000000\n"
|
||||
"vn -0.707107 -0.707107 0.000000\n"
|
||||
"vn -0.707107 -0.707107 0.000000\n"
|
||||
"s off\n"
|
||||
"f 1/1/1 2/2/2 4/4/3 3/3/4\n"
|
||||
"f 3/3/5 4/4/6 6/6/7 5/5/8\n"
|
||||
"f 5/5/9 6/6/10 8/8/11 7/7/12\n"
|
||||
"f 7/7/13 8/8/14 2/10/15 1/9/16\n"
|
||||
"f 2/2/17 8/11/18 6/12/19 4/4/20\n"
|
||||
"f 7/13/21 1/1/22 3/3/23 5/14/24\n"
|
||||
"t crease 2/1/0 0 1 10.0\n"
|
||||
"t crease 2/1/0 1 3 10.0\n"
|
||||
"t crease 2/1/0 3 2 10.0\n"
|
||||
"t crease 2/1/0 2 0 10.0\n"
|
||||
"t crease 2/1/0 4 5 10.0\n"
|
||||
"t crease 2/1/0 5 7 10.0\n"
|
||||
"t crease 2/1/0 7 6 10.0\n"
|
||||
"t crease 2/1/0 6 4 10.0\n"
|
||||
"t crease 2/1/0 0 6 10.0\n"
|
||||
"t crease 2/1/0 1 7 10.0\n"
|
||||
"t crease 2/1/0 2 4 10.0\n"
|
||||
"t crease 2/1/0 3 5 0.1\n"
|
||||
"t interpolateboundary 1/0/0 2\n"
|
||||
;
|
Loading…
Reference in New Issue
Block a user