mirror of
https://github.com/PixarAnimationStudios/OpenSubdiv
synced 2024-12-27 02:10:24 +00:00
Minor additions and revisions to TopologyRefiner interface:
- new Options for Refine() methods for base face and vertex ordering - removed ignored/unused "full topology" choice from AdaptiveOptions - added base face and vertex ordering logic to Refinement - addition of TopologyRefiner members for component counts and max valence - refactoring of Level additions to update all new member totals - addition of GetMaxValence() to TopologyRefiner - updated PatchTablesFactory to user new GetMaxValence() method - renaming of "Hole" methods for TopologyRefiner and Vtr::Level
This commit is contained in:
parent
9222c9e169
commit
898d68ae79
@ -1065,7 +1065,7 @@ PatchTablesFactory::createUniform(TopologyRefiner const & refiner, Options optio
|
|||||||
options.triangulateQuads &= (refiner.GetSchemeType()==Sdc::SCHEME_BILINEAR or
|
options.triangulateQuads &= (refiner.GetSchemeType()==Sdc::SCHEME_BILINEAR or
|
||||||
refiner.GetSchemeType()==Sdc::SCHEME_CATMARK);
|
refiner.GetSchemeType()==Sdc::SCHEME_CATMARK);
|
||||||
|
|
||||||
int maxvalence = refiner.getLevel(0).getMaxValence(),
|
int maxvalence = refiner.GetMaxValence(),
|
||||||
maxlevel = refiner.GetMaxLevel(),
|
maxlevel = refiner.GetMaxLevel(),
|
||||||
firstlevel = options.generateAllLevels ? 0 : maxlevel,
|
firstlevel = options.generateAllLevels ? 0 : maxlevel,
|
||||||
nlevels = maxlevel-firstlevel+1;
|
nlevels = maxlevel-firstlevel+1;
|
||||||
@ -1150,7 +1150,7 @@ PatchTablesFactory::createUniform(TopologyRefiner const & refiner, Options optio
|
|||||||
if (level>=firstlevel) {
|
if (level>=firstlevel) {
|
||||||
for (int face=0; face<nfaces; ++face) {
|
for (int face=0; face<nfaces; ++face) {
|
||||||
|
|
||||||
if (refiner.HasHoles() and refiner.IsHole(level, face)) {
|
if (refiner.HasHoles() and refiner.IsFaceHole(level, face)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1222,7 +1222,7 @@ PatchTablesFactory::createAdaptive(TopologyRefiner const & refiner, Options opti
|
|||||||
// Create the instance of the tables and allocate and initialize its members based on
|
// Create the instance of the tables and allocate and initialize its members based on
|
||||||
// the inventory of patches determined above:
|
// the inventory of patches determined above:
|
||||||
//
|
//
|
||||||
int maxValence = refiner.getLevel(0).getMaxValence();
|
int maxValence = refiner.GetMaxValence();
|
||||||
|
|
||||||
context.tables = new PatchTables(maxValence);
|
context.tables = new PatchTables(maxValence);
|
||||||
|
|
||||||
@ -1323,7 +1323,7 @@ PatchTablesFactory::identifyAdaptivePatches(AdaptiveContext & context) {
|
|||||||
patchTag.clear();
|
patchTag.clear();
|
||||||
patchTag._hasPatch = false;
|
patchTag._hasPatch = false;
|
||||||
|
|
||||||
if (level->isHole(faceIndex)) {
|
if (level->isFaceHole(faceIndex)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1613,7 +1613,7 @@ PatchTablesFactory::populateAdaptivePatches(AdaptiveContext & context) {
|
|||||||
|
|
||||||
assert(not context.RequiresLegacyGregoryPatches());
|
assert(not context.RequiresLegacyGregoryPatches());
|
||||||
|
|
||||||
int maxvalence = refiner.getLevel(0).getMaxValence(),
|
int maxvalence = refiner.GetMaxValence(),
|
||||||
npatches = context.patchInventory.GP;
|
npatches = context.patchInventory.GP;
|
||||||
|
|
||||||
gregoryStencilsFactory =
|
gregoryStencilsFactory =
|
||||||
@ -1646,7 +1646,7 @@ PatchTablesFactory::populateAdaptivePatches(AdaptiveContext & context) {
|
|||||||
|
|
||||||
for (int faceIndex = 0; faceIndex < level->getNumFaces(); ++faceIndex) {
|
for (int faceIndex = 0; faceIndex < level->getNumFaces(); ++faceIndex) {
|
||||||
|
|
||||||
if (level->isHole(faceIndex)) {
|
if (level->isFaceHole(faceIndex)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,8 +44,14 @@ TopologyRefiner::TopologyRefiner(Sdc::SchemeType schemeType, Sdc::Options scheme
|
|||||||
_subdivOptions(schemeOptions),
|
_subdivOptions(schemeOptions),
|
||||||
_isUniform(true),
|
_isUniform(true),
|
||||||
_hasHoles(false),
|
_hasHoles(false),
|
||||||
_useSingleCreasePatch(false),
|
_maxLevel(0),
|
||||||
_maxLevel(0) {
|
_uniformOptions(0),
|
||||||
|
_adaptiveOptions(0),
|
||||||
|
_totalVertices(0),
|
||||||
|
_totalEdges(0),
|
||||||
|
_totalFaces(0),
|
||||||
|
_totalFaceVertices(0),
|
||||||
|
_maxValence(0) {
|
||||||
|
|
||||||
// Need to revisit allocation scheme here -- want to use smart-ptrs for these
|
// Need to revisit allocation scheme here -- want to use smart-ptrs for these
|
||||||
// but will probably have to settle for explicit new/delete...
|
// but will probably have to settle for explicit new/delete...
|
||||||
@ -72,6 +78,7 @@ TopologyRefiner::Unrefine() {
|
|||||||
delete _levels[i];
|
delete _levels[i];
|
||||||
}
|
}
|
||||||
_levels.resize(1);
|
_levels.resize(1);
|
||||||
|
initializeInventory();
|
||||||
}
|
}
|
||||||
for (int i=0; i<(int)_refinements.size(); ++i) {
|
for (int i=0; i<(int)_refinements.size(); ++i) {
|
||||||
delete _refinements[i];
|
delete _refinements[i];
|
||||||
@ -80,42 +87,73 @@ TopologyRefiner::Unrefine() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Intializing and updating the component inventory:
|
||||||
|
//
|
||||||
|
void
|
||||||
|
TopologyRefiner::initializeInventory() {
|
||||||
|
|
||||||
|
if (_levels.size()) {
|
||||||
|
assert(_levels.size() == 1);
|
||||||
|
|
||||||
|
Vtr::Level const & baseLevel = *_levels[0];
|
||||||
|
|
||||||
|
_totalVertices = baseLevel.getNumVertices();
|
||||||
|
_totalEdges = baseLevel.getNumEdges();
|
||||||
|
_totalFaces = baseLevel.getNumFaces();
|
||||||
|
_totalFaceVertices = baseLevel.getNumFaceVerticesTotal();
|
||||||
|
|
||||||
|
_maxValence = baseLevel.getMaxValence();
|
||||||
|
} else {
|
||||||
|
_totalVertices = 0;
|
||||||
|
_totalEdges = 0;
|
||||||
|
_totalFaces = 0;
|
||||||
|
_totalFaceVertices = 0;
|
||||||
|
|
||||||
|
_maxValence = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
TopologyRefiner::updateInventory(Vtr::Level const & newLevel) {
|
||||||
|
|
||||||
|
_totalVertices += newLevel.getNumVertices();
|
||||||
|
_totalEdges += newLevel.getNumEdges();
|
||||||
|
_totalFaces += newLevel.getNumFaces();
|
||||||
|
_totalFaceVertices += newLevel.getNumFaceVerticesTotal();
|
||||||
|
|
||||||
|
_maxValence = std::max(_maxValence, newLevel.getMaxValence());
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
TopologyRefiner::appendLevel(Vtr::Level & newLevel) {
|
||||||
|
|
||||||
|
_levels.push_back(&newLevel);
|
||||||
|
|
||||||
|
updateInventory(newLevel);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
TopologyRefiner::appendRefinement(Vtr::Refinement & newRefinement) {
|
||||||
|
|
||||||
|
//
|
||||||
|
// There may be properties to transfer between refinements that cannot be passed on
|
||||||
|
// when refining between the parent and child since they exist "above" the parent:
|
||||||
|
//
|
||||||
|
bool applyBaseFace = (_isUniform && _uniformOptions.applyBaseFacePerFace) ||
|
||||||
|
(!_isUniform && _adaptiveOptions.applyBaseFacePerFace);
|
||||||
|
if (applyBaseFace) {
|
||||||
|
newRefinement.propagateBaseFace(_refinements.size() ? _refinements.back() : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
_refinements.push_back(&newRefinement);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Accessors to the topology information:
|
// Accessors to the topology information:
|
||||||
//
|
//
|
||||||
int
|
int
|
||||||
TopologyRefiner::GetNumVerticesTotal() const {
|
|
||||||
int sum = 0;
|
|
||||||
for (int i = 0; i < (int)_levels.size(); ++i) {
|
|
||||||
sum += _levels[i]->getNumVertices();
|
|
||||||
}
|
|
||||||
return sum;
|
|
||||||
}
|
|
||||||
int
|
|
||||||
TopologyRefiner::GetNumEdgesTotal() const {
|
|
||||||
int sum = 0;
|
|
||||||
for (int i = 0; i < (int)_levels.size(); ++i) {
|
|
||||||
sum += _levels[i]->getNumEdges();
|
|
||||||
}
|
|
||||||
return sum;
|
|
||||||
}
|
|
||||||
int
|
|
||||||
TopologyRefiner::GetNumFacesTotal() const {
|
|
||||||
int sum = 0;
|
|
||||||
for (int i = 0; i < (int)_levels.size(); ++i) {
|
|
||||||
sum += _levels[i]->getNumFaces();
|
|
||||||
}
|
|
||||||
return sum;
|
|
||||||
}
|
|
||||||
int
|
|
||||||
TopologyRefiner::GetNumFaceVerticesTotal() const {
|
|
||||||
int sum = 0;
|
|
||||||
for (int i = 0; i < (int)_levels.size(); ++i) {
|
|
||||||
sum += _levels[i]->getNumFaceVerticesTotal();
|
|
||||||
}
|
|
||||||
return sum;
|
|
||||||
}
|
|
||||||
int
|
|
||||||
TopologyRefiner::GetNumFVarValuesTotal(int channel) const {
|
TopologyRefiner::GetNumFVarValuesTotal(int channel) const {
|
||||||
int sum = 0;
|
int sum = 0;
|
||||||
for (int i = 0; i < (int)_levels.size(); ++i) {
|
for (int i = 0; i < (int)_levels.size(); ++i) {
|
||||||
@ -129,7 +167,7 @@ TopologyRefiner::GetNumHoles(int level) const {
|
|||||||
int sum = 0;
|
int sum = 0;
|
||||||
Vtr::Level const & lvl = getLevel(level);
|
Vtr::Level const & lvl = getLevel(level);
|
||||||
for (Index face = 0; face < lvl.getNumFaces(); ++face) {
|
for (Index face = 0; face < lvl.getNumFaces(); ++face) {
|
||||||
if (lvl.isHole(face)) {
|
if (lvl.isFaceHole(face)) {
|
||||||
++sum;
|
++sum;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -309,6 +347,8 @@ TopologyRefiner::RefineUniform(UniformOptions options) {
|
|||||||
//
|
//
|
||||||
// Allocate the stack of levels and the refinements between them:
|
// Allocate the stack of levels and the refinements between them:
|
||||||
//
|
//
|
||||||
|
_uniformOptions = options;
|
||||||
|
|
||||||
_isUniform = true;
|
_isUniform = true;
|
||||||
_maxLevel = options.refinementLevel;
|
_maxLevel = options.refinementLevel;
|
||||||
|
|
||||||
@ -318,10 +358,11 @@ TopologyRefiner::RefineUniform(UniformOptions options) {
|
|||||||
// Initialize refinement options for Vtr -- adjusting full-topology for the last level:
|
// Initialize refinement options for Vtr -- adjusting full-topology for the last level:
|
||||||
//
|
//
|
||||||
Vtr::Refinement::Options refineOptions;
|
Vtr::Refinement::Options refineOptions;
|
||||||
refineOptions._sparse = false;
|
refineOptions._sparse = false;
|
||||||
|
refineOptions._orderFaceVertsFirst = options.orderVerticesFromFacesFirst;
|
||||||
|
|
||||||
for (int i = 1; i <= (int)options.refinementLevel; ++i) {
|
for (int i = 1; i <= (int)options.refinementLevel; ++i) {
|
||||||
refineOptions._faceTopologyOnly =
|
refineOptions._minimalTopology =
|
||||||
options.fullTopologyInLastLevel ? false : (i == options.refinementLevel);
|
options.fullTopologyInLastLevel ? false : (i == options.refinementLevel);
|
||||||
|
|
||||||
Vtr::Level& parentLevel = getLevel(i-1);
|
Vtr::Level& parentLevel = getLevel(i-1);
|
||||||
@ -335,8 +376,8 @@ TopologyRefiner::RefineUniform(UniformOptions options) {
|
|||||||
}
|
}
|
||||||
refinement->refine(refineOptions);
|
refinement->refine(refineOptions);
|
||||||
|
|
||||||
_levels.push_back(&childLevel);
|
appendLevel(childLevel);
|
||||||
_refinements.push_back(refinement);
|
appendRefinement(*refinement);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -349,24 +390,24 @@ TopologyRefiner::RefineAdaptive(AdaptiveOptions options) {
|
|||||||
//
|
//
|
||||||
// Allocate the stack of levels and the refinements between them:
|
// Allocate the stack of levels and the refinements between them:
|
||||||
//
|
//
|
||||||
|
_adaptiveOptions = options;
|
||||||
|
|
||||||
_isUniform = false;
|
_isUniform = false;
|
||||||
_maxLevel = options.isolationLevel;
|
_maxLevel = options.isolationLevel;
|
||||||
_useSingleCreasePatch = options.useSingleCreasePatch;
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Initialize refinement options for Vtr:
|
// Initialize refinement options for Vtr -- full topology is always generated in
|
||||||
|
// the last level as expected usage is for patch retrieval:
|
||||||
//
|
//
|
||||||
Vtr::Refinement::Options refineOptions;
|
Vtr::Refinement::Options refineOptions;
|
||||||
|
|
||||||
refineOptions._sparse = true;
|
refineOptions._sparse = true;
|
||||||
refineOptions._faceTopologyOnly = not options.fullTopologyInLastLevel;
|
refineOptions._minimalTopology = false;
|
||||||
|
refineOptions._orderFaceVertsFirst = options.orderVerticesFromFacesFirst;
|
||||||
|
|
||||||
Sdc::Split splitType = (_subdivType == Sdc::SCHEME_LOOP) ? Sdc::SPLIT_TO_TRIS : Sdc::SPLIT_TO_QUADS;
|
Sdc::Split splitType = (_subdivType == Sdc::SCHEME_LOOP) ? Sdc::SPLIT_TO_TRIS : Sdc::SPLIT_TO_QUADS;
|
||||||
|
|
||||||
for (int i = 1; i <= (int)options.isolationLevel; ++i) {
|
for (int i = 1; i <= (int)options.isolationLevel; ++i) {
|
||||||
// Keeping full topology on for debugging -- may need to go back a level and "prune"
|
|
||||||
// its topology if we don't use the full depth
|
|
||||||
refineOptions._faceTopologyOnly = false;
|
|
||||||
|
|
||||||
Vtr::Level& parentLevel = getLevel(i-1);
|
Vtr::Level& parentLevel = getLevel(i-1);
|
||||||
Vtr::Level& childLevel = *(new Vtr::Level);
|
Vtr::Level& childLevel = *(new Vtr::Level);
|
||||||
@ -384,9 +425,6 @@ TopologyRefiner::RefineAdaptive(AdaptiveOptions options) {
|
|||||||
// maximum level and stop refinining any further. Otherwise, refine and append
|
// maximum level and stop refinining any further. Otherwise, refine and append
|
||||||
// the new refinement and child.
|
// the new refinement and child.
|
||||||
//
|
//
|
||||||
// Note that if we support the "full topology at last level" option properly,
|
|
||||||
// we should prune the previous level generated, as it is now the last...
|
|
||||||
//
|
|
||||||
Vtr::SparseSelector selector(*refinement);
|
Vtr::SparseSelector selector(*refinement);
|
||||||
|
|
||||||
selectFeatureAdaptiveComponents(selector);
|
selectFeatureAdaptiveComponents(selector);
|
||||||
@ -400,11 +438,8 @@ TopologyRefiner::RefineAdaptive(AdaptiveOptions options) {
|
|||||||
|
|
||||||
refinement->refine(refineOptions);
|
refinement->refine(refineOptions);
|
||||||
|
|
||||||
_levels.push_back(&childLevel);
|
appendLevel(childLevel);
|
||||||
_refinements.push_back(refinement);
|
appendRefinement(*refinement);
|
||||||
|
|
||||||
//childLevel.print(refinement);
|
|
||||||
//assert(childLevel.validateTopology());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -430,8 +465,8 @@ TopologyRefiner::selectFeatureAdaptiveComponents(Vtr::SparseSelector& selector)
|
|||||||
|
|
||||||
Vtr::Level const& level = selector.getRefinement().parent();
|
Vtr::Level const& level = selector.getRefinement().parent();
|
||||||
|
|
||||||
int regularFaceSize = selector.getRefinement()._regFaceSize;
|
int regularFaceSize = selector.getRefinement()._regFaceSize;
|
||||||
bool considerSingleCreasePatch = _useSingleCreasePatch && (regularFaceSize == 4);
|
bool considerSingleCreasePatch = _adaptiveOptions.useSingleCreasePatch && (regularFaceSize == 4);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Face-varying consideration when isolating features:
|
// Face-varying consideration when isolating features:
|
||||||
@ -464,7 +499,7 @@ TopologyRefiner::selectFeatureAdaptiveComponents(Vtr::SparseSelector& selector)
|
|||||||
//
|
//
|
||||||
for (Vtr::Index face = 0; face < level.getNumFaces(); ++face) {
|
for (Vtr::Index face = 0; face < level.getNumFaces(); ++face) {
|
||||||
|
|
||||||
if (level.isHole(face)) {
|
if (level.isFaceHole(face)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,22 +79,23 @@ public:
|
|||||||
/// \brief Returns the highest level of refinement
|
/// \brief Returns the highest level of refinement
|
||||||
int GetMaxLevel() const { return _maxLevel; }
|
int GetMaxLevel() const { return _maxLevel; }
|
||||||
|
|
||||||
|
/// \brief Returns the maximum vertex valence in all levels
|
||||||
|
int GetMaxValence() const { return _maxValence; }
|
||||||
|
|
||||||
/// \ brief Returns true if faces have been tagged as holes
|
/// \ brief Returns true if faces have been tagged as holes
|
||||||
bool HasHoles() const { return _hasHoles; }
|
bool HasHoles() const { return _hasHoles; }
|
||||||
|
|
||||||
// XXXX barfowl -- should cache these internally for trivial return)
|
|
||||||
|
|
||||||
/// \brief Returns the total number of vertices in all levels
|
/// \brief Returns the total number of vertices in all levels
|
||||||
int GetNumVerticesTotal() const;
|
int GetNumVerticesTotal() const { return _totalVertices; }
|
||||||
|
|
||||||
/// \brief Returns the total number of edges in all levels
|
/// \brief Returns the total number of edges in all levels
|
||||||
int GetNumEdgesTotal() const;
|
int GetNumEdgesTotal() const { return _totalEdges; }
|
||||||
|
|
||||||
/// \brief Returns the total number of edges in all levels
|
/// \brief Returns the total number of edges in all levels
|
||||||
int GetNumFacesTotal() const;
|
int GetNumFacesTotal() const { return _totalFaces; }
|
||||||
|
|
||||||
/// \brief Returns the total number of face vertices in all levels
|
/// \brief Returns the total number of face vertices in all levels
|
||||||
int GetNumFaceVerticesTotal() const;
|
int GetNumFaceVerticesTotal() const { return _totalFaceVertices; }
|
||||||
|
|
||||||
//@{
|
//@{
|
||||||
/// @name High-level refinement and related methods
|
/// @name High-level refinement and related methods
|
||||||
@ -109,11 +110,18 @@ public:
|
|||||||
|
|
||||||
UniformOptions(int level) :
|
UniformOptions(int level) :
|
||||||
refinementLevel(level),
|
refinementLevel(level),
|
||||||
|
applyBaseFacePerFace(false),
|
||||||
|
orderVerticesFromFacesFirst(false),
|
||||||
fullTopologyInLastLevel(false) { }
|
fullTopologyInLastLevel(false) { }
|
||||||
|
|
||||||
unsigned int refinementLevel:4, ///< Number of refinement iterations
|
unsigned int refinementLevel:4, ///< Number of refinement iterations
|
||||||
fullTopologyInLastLevel:1; ///< Skip secondary topological relationships
|
applyBaseFacePerFace:1, ///< For each refined face, record the index
|
||||||
///< at the highest level of refinement.
|
///< of the base face from which it originates
|
||||||
|
orderVerticesFromFacesFirst:1, ///< Order child vertices from faces first
|
||||||
|
///< instead of child vertices of vertices
|
||||||
|
fullTopologyInLastLevel:1; ///< Skip topological relationships in the last
|
||||||
|
///< level of refinement that are not needed for
|
||||||
|
///< interpolation (keep false if using limit).
|
||||||
};
|
};
|
||||||
|
|
||||||
/// \brief Refine the topology uniformly
|
/// \brief Refine the topology uniformly
|
||||||
@ -122,6 +130,9 @@ public:
|
|||||||
///
|
///
|
||||||
void RefineUniform(UniformOptions options);
|
void RefineUniform(UniformOptions options);
|
||||||
|
|
||||||
|
/// \brief Returns the options specified on refinement
|
||||||
|
UniformOptions GetUniformOptions() const { return _uniformOptions; }
|
||||||
|
|
||||||
//
|
//
|
||||||
// Adaptive refinement
|
// Adaptive refinement
|
||||||
//
|
//
|
||||||
@ -131,15 +142,18 @@ public:
|
|||||||
|
|
||||||
AdaptiveOptions(int level) :
|
AdaptiveOptions(int level) :
|
||||||
isolationLevel(level),
|
isolationLevel(level),
|
||||||
fullTopologyInLastLevel(false),
|
useSingleCreasePatch(false),
|
||||||
useSingleCreasePatch(false) { }
|
applyBaseFacePerFace(false),
|
||||||
|
orderVerticesFromFacesFirst(false) { }
|
||||||
|
|
||||||
unsigned int isolationLevel:4, ///< Number of iterations applied to isolate
|
unsigned int isolationLevel:4, ///< Number of iterations applied to isolate
|
||||||
///< extraordinary vertices and creases
|
///< extraordinary vertices and creases
|
||||||
fullTopologyInLastLevel:1, ///< Skip secondary topological relationships
|
useSingleCreasePatch:1, ///< Use 'single-crease' patch and stop
|
||||||
///< at the highest level of refinement.
|
///< isolation where applicable
|
||||||
useSingleCreasePatch:1; ///< Use 'single-crease' patch and stop
|
applyBaseFacePerFace:1, ///< For each refined face, record the index
|
||||||
///< isolation where applicable
|
///< of the base face from which it originates
|
||||||
|
orderVerticesFromFacesFirst:1; ///< Order child vertices from faces first
|
||||||
|
///< instead of child vertices of vertices
|
||||||
};
|
};
|
||||||
|
|
||||||
/// \brief Feature Adaptive topology refinement
|
/// \brief Feature Adaptive topology refinement
|
||||||
@ -148,6 +162,9 @@ public:
|
|||||||
///
|
///
|
||||||
void RefineAdaptive(AdaptiveOptions options);
|
void RefineAdaptive(AdaptiveOptions options);
|
||||||
|
|
||||||
|
/// \brief Returns the options specified on refinement
|
||||||
|
AdaptiveOptions GetAdaptiveOptions() const { return _adaptiveOptions; }
|
||||||
|
|
||||||
/// \brief Unrefine the topology (keep control cage)
|
/// \brief Unrefine the topology (keep control cage)
|
||||||
void Unrefine();
|
void Unrefine();
|
||||||
|
|
||||||
@ -336,8 +353,8 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// \brief Returns true if 'face' at 'level' is tagged as a hole
|
/// \brief Returns true if 'face' at 'level' is tagged as a hole
|
||||||
bool IsHole(int level, Index face) const {
|
bool IsFaceHole(int level, Index face) const {
|
||||||
return _levels[level]->isHole(face);
|
return _levels[level]->isFaceHole(face);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \brief Returns the vertices of an 'edge' at 'level' (2 of them)
|
/// \brief Returns the vertices of an 'edge' at 'level' (2 of them)
|
||||||
@ -415,7 +432,7 @@ public:
|
|||||||
|
|
||||||
//@{
|
//@{
|
||||||
/// @name Parent-to-child relationships,
|
/// @name Parent-to-child relationships,
|
||||||
/// Telationships between components in one level
|
/// Relationships between components in one level
|
||||||
/// and the next (entries may be invalid if sparse):
|
/// and the next (entries may be invalid if sparse):
|
||||||
///
|
///
|
||||||
|
|
||||||
@ -452,6 +469,23 @@ public:
|
|||||||
|
|
||||||
//@}
|
//@}
|
||||||
|
|
||||||
|
//@{
|
||||||
|
/// @name Child-to-parent or child-to-base relationships,
|
||||||
|
/// Relationships between components in one level and the
|
||||||
|
/// previous or base level (to be called with level > 0):
|
||||||
|
///
|
||||||
|
|
||||||
|
/// \brief Returns the parent face of face 'f' at 'level'
|
||||||
|
Index GetFaceParentFace(int level, Index f) const {
|
||||||
|
return _refinements[level-1]->getChildFaceParentFace(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \brief Returns the base face of face 'f' at 'level'
|
||||||
|
Index GetFaceBaseFace(int level, Index f) const {
|
||||||
|
return _refinements[level-1]->getChildFaceBaseFace(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
//@}
|
||||||
|
|
||||||
//@{
|
//@{
|
||||||
/// Ptex
|
/// Ptex
|
||||||
@ -535,7 +569,7 @@ protected:
|
|||||||
void setBaseEdgeSharpness(Index e, float s) { _levels[0]->getEdgeSharpness(e) = s; }
|
void setBaseEdgeSharpness(Index e, float s) { _levels[0]->getEdgeSharpness(e) = s; }
|
||||||
void setBaseVertexSharpness(Index v, float s) { _levels[0]->getVertexSharpness(v) = s; }
|
void setBaseVertexSharpness(Index v, float s) { _levels[0]->getVertexSharpness(v) = s; }
|
||||||
|
|
||||||
void setBaseFaceHole(Index f, bool b) { _levels[0]->setHole(f, b); _hasHoles |= b; }
|
void setBaseFaceHole(Index f, bool b) { _levels[0]->setFaceHole(f, b); _hasHoles |= b; }
|
||||||
|
|
||||||
// Optional methods for creating and assigning face-varying data channels:
|
// Optional methods for creating and assigning face-varying data channels:
|
||||||
int createBaseFVarChannel(int numValues);
|
int createBaseFVarChannel(int numValues);
|
||||||
@ -543,6 +577,9 @@ protected:
|
|||||||
|
|
||||||
IndexArray setBaseFVarFaceValues(Index face, int channel = 0);
|
IndexArray setBaseFVarFaceValues(Index face, int channel = 0);
|
||||||
|
|
||||||
|
void setBaseMaxValence(int valence) { _levels[0]->setMaxValence(valence); }
|
||||||
|
void initializeBaseInventory() { initializeInventory(); }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -579,6 +616,12 @@ private:
|
|||||||
|
|
||||||
void initializePtexIndices() const;
|
void initializePtexIndices() const;
|
||||||
|
|
||||||
|
void initializeInventory();
|
||||||
|
void updateInventory(Vtr::Level const & newLevel);
|
||||||
|
|
||||||
|
void appendLevel(Vtr::Level & newLevel);
|
||||||
|
void appendRefinement(Vtr::Refinement & newRefinement);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
Sdc::SchemeType _subdivType;
|
Sdc::SchemeType _subdivType;
|
||||||
@ -586,9 +629,19 @@ private:
|
|||||||
|
|
||||||
unsigned int _isUniform : 1,
|
unsigned int _isUniform : 1,
|
||||||
_hasHoles : 1,
|
_hasHoles : 1,
|
||||||
_useSingleCreasePatch : 1,
|
|
||||||
_maxLevel : 4;
|
_maxLevel : 4;
|
||||||
|
|
||||||
|
// Options assigned on refinement:
|
||||||
|
UniformOptions _uniformOptions;
|
||||||
|
AdaptiveOptions _adaptiveOptions;
|
||||||
|
|
||||||
|
// Cumulative properties of all levels:
|
||||||
|
int _totalVertices;
|
||||||
|
int _totalEdges;
|
||||||
|
int _totalFaces;
|
||||||
|
int _totalFaceVertices;
|
||||||
|
int _maxValence;
|
||||||
|
|
||||||
std::vector<Vtr::Level *> _levels;
|
std::vector<Vtr::Level *> _levels;
|
||||||
std::vector<Vtr::Refinement *> _refinements;
|
std::vector<Vtr::Refinement *> _refinements;
|
||||||
|
|
||||||
|
@ -115,6 +115,13 @@ TopologyRefinerFactoryBase::prepareComponentTopologyAssignment(TopologyRefiner&
|
|||||||
Warning(msg);
|
Warning(msg);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
if (baseLevel.getMaxValence() == 0) {
|
||||||
|
char msg[1024];
|
||||||
|
snprintf(msg, 1024, "Invalid topology detected : maximum valence not assigned.");
|
||||||
|
Warning(msg);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fullValidation) {
|
if (fullValidation) {
|
||||||
@ -128,6 +135,9 @@ TopologyRefinerFactoryBase::prepareComponentTopologyAssignment(TopologyRefiner&
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Now that we have a valid base level, initialize the Refiner's component inventory:
|
||||||
|
refiner.initializeBaseInventory();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -275,29 +275,17 @@ FVarRefinement::populateChildValues() {
|
|||||||
//
|
//
|
||||||
// Be sure to match the same vertex ordering as Refinement, i.e. face-vertices
|
// Be sure to match the same vertex ordering as Refinement, i.e. face-vertices
|
||||||
// first vs vertex-vertices first, etc. A few optimizations within the use of
|
// first vs vertex-vertices first, etc. A few optimizations within the use of
|
||||||
// face-varying data take advantage of this assumption.
|
// face-varying data take advantage of this assumption, and it just makes sense
|
||||||
//
|
// to be consistent (e.g. if there is a 1-to-1 correspondence between vertices
|
||||||
// Right now there are only two orderings under consideration, and its unclear
|
// and their FVar-values, their children will correspond).
|
||||||
// whether only one will be supported or both. Until that's determined, assert
|
|
||||||
// the conditions we expect for these two.
|
|
||||||
//
|
//
|
||||||
_childFVar._valueCount = 0;
|
_childFVar._valueCount = 0;
|
||||||
|
|
||||||
if (_refinement.getFirstChildVertexFromVertices() > 0) {
|
if (_refinement._faceVertsFirst) {
|
||||||
assert((_refinement.getFirstChildVertexFromFaces() <=
|
|
||||||
_refinement.getFirstChildVertexFromEdges()) &&
|
|
||||||
(_refinement.getFirstChildVertexFromEdges() <
|
|
||||||
_refinement.getFirstChildVertexFromVertices()));
|
|
||||||
|
|
||||||
populateChildValuesFromFaceVertices();
|
populateChildValuesFromFaceVertices();
|
||||||
populateChildValuesFromEdgeVertices();
|
populateChildValuesFromEdgeVertices();
|
||||||
populateChildValuesFromVertexVertices();
|
populateChildValuesFromVertexVertices();
|
||||||
} else {
|
} else {
|
||||||
assert((_refinement.getFirstChildVertexFromVertices() <
|
|
||||||
_refinement.getFirstChildVertexFromFaces()) &&
|
|
||||||
(_refinement.getFirstChildVertexFromFaces() <=
|
|
||||||
_refinement.getFirstChildVertexFromEdges()));
|
|
||||||
|
|
||||||
populateChildValuesFromVertexVertices();
|
populateChildValuesFromVertexVertices();
|
||||||
populateChildValuesFromFaceVertices();
|
populateChildValuesFromFaceVertices();
|
||||||
populateChildValuesFromEdgeVertices();
|
populateChildValuesFromEdgeVertices();
|
||||||
|
@ -241,8 +241,8 @@ public:
|
|||||||
Index findEdge(Index v0Index, Index v1Index) const;
|
Index findEdge(Index v0Index, Index v1Index) const;
|
||||||
|
|
||||||
// Holes
|
// Holes
|
||||||
void setHole(Index faceIndex, bool b);
|
void setFaceHole(Index faceIndex, bool b);
|
||||||
bool isHole(Index faceIndex) const;
|
bool isFaceHole(Index faceIndex) const;
|
||||||
|
|
||||||
// Face-varying
|
// Face-varying
|
||||||
Sdc::Options getFVarOptions(int channel = 0) const;
|
Sdc::Options getFVarOptions(int channel = 0) const;
|
||||||
@ -351,6 +351,8 @@ protected:
|
|||||||
void resizeVertexFaces(int numVertexFacesTotal);
|
void resizeVertexFaces(int numVertexFacesTotal);
|
||||||
void resizeVertexEdges(int numVertexEdgesTotal);
|
void resizeVertexEdges(int numVertexEdgesTotal);
|
||||||
|
|
||||||
|
void setMaxValence(int maxValence);
|
||||||
|
|
||||||
// Modifiers to populate the relations for each component:
|
// Modifiers to populate the relations for each component:
|
||||||
IndexArray getFaceVertices(Index faceIndex);
|
IndexArray getFaceVertices(Index faceIndex);
|
||||||
IndexArray getFaceEdges(Index faceIndex);
|
IndexArray getFaceEdges(Index faceIndex);
|
||||||
@ -447,11 +449,14 @@ protected:
|
|||||||
int _edgeCount;
|
int _edgeCount;
|
||||||
int _vertCount;
|
int _vertCount;
|
||||||
|
|
||||||
// TBD - "depth" is clearly useful in both the topological splitting and the
|
// The "depth" member is clearly useful in both the topological splitting and the
|
||||||
// stencil queries so could be valuable in both. As face-vert valence becomes
|
// stencil queries, but arguably it ties the Level to a hierarchy which counters
|
||||||
// constant there is no need to store face-vert and face-edge counts so it has
|
// the idea if it being independent.
|
||||||
// value in Level, though perhaps specified as something other than "depth"
|
|
||||||
int _depth;
|
int _depth;
|
||||||
|
|
||||||
|
// Maxima to help clients manage sizing of data buffers. Given "max valence",
|
||||||
|
// the "max edge faces" is strictly redundant as it will always be less, but
|
||||||
|
// since it will typically be so much less (i.e. 2) it is kept for now.
|
||||||
int _maxEdgeFaces;
|
int _maxEdgeFaces;
|
||||||
int _maxValence;
|
int _maxValence;
|
||||||
|
|
||||||
@ -619,6 +624,11 @@ Level::trimVertexEdges(Index vertIndex, int count) {
|
|||||||
_vertEdgeCountsAndOffsets[vertIndex*2] = count;
|
_vertEdgeCountsAndOffsets[vertIndex*2] = count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void
|
||||||
|
Level::setMaxValence(int valence) {
|
||||||
|
_maxValence = valence;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Access/modify the vertices indicent a given edge:
|
// Access/modify the vertices indicent a given edge:
|
||||||
//
|
//
|
||||||
@ -700,11 +710,11 @@ Level::getVertexRule(Index vertIndex) const {
|
|||||||
// Access/modify hole tag:
|
// Access/modify hole tag:
|
||||||
//
|
//
|
||||||
inline void
|
inline void
|
||||||
Level::setHole(Index faceIndex, bool b) {
|
Level::setFaceHole(Index faceIndex, bool b) {
|
||||||
_faceTags[faceIndex]._hole = b;
|
_faceTags[faceIndex]._hole = b;
|
||||||
}
|
}
|
||||||
inline bool
|
inline bool
|
||||||
Level::isHole(Index faceIndex) const {
|
Level::isFaceHole(Index faceIndex) const {
|
||||||
return _faceTags[faceIndex]._hole;
|
return _faceTags[faceIndex]._hole;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -966,10 +966,9 @@ QuadRefinement::markSparseFaceChildren() {
|
|||||||
int marked = false;
|
int marked = false;
|
||||||
|
|
||||||
for (int i = 0; i < fVerts.size(); ++i) {
|
for (int i = 0; i < fVerts.size(); ++i) {
|
||||||
// NOTE - the mod 4 here will not work for N-gons (and want to avoid % anyway)
|
|
||||||
int iPrev = (i+3) % 4;
|
|
||||||
|
|
||||||
if (_parentVertexTag[fVerts[i]]._selected) {
|
if (_parentVertexTag[fVerts[i]]._selected) {
|
||||||
|
int iPrev = i ? (i - 1) : (fVerts.size() - 1);
|
||||||
|
|
||||||
markSparseIndexNeighbor(fChildFaces[i]);
|
markSparseIndexNeighbor(fChildFaces[i]);
|
||||||
|
|
||||||
markSparseIndexNeighbor(fChildEdges[i]);
|
markSparseIndexNeighbor(fChildEdges[i]);
|
||||||
|
@ -49,6 +49,8 @@ Refinement::Refinement(Level const & parent, Level & child, Sdc::Options const&
|
|||||||
_child(&child),
|
_child(&child),
|
||||||
_options(options),
|
_options(options),
|
||||||
_regFaceSize(-1),
|
_regFaceSize(-1),
|
||||||
|
_uniform(false),
|
||||||
|
_faceVertsFirst(false),
|
||||||
_childFaceFromFaceCount(0),
|
_childFaceFromFaceCount(0),
|
||||||
_childEdgeFromFaceCount(0),
|
_childEdgeFromFaceCount(0),
|
||||||
_childEdgeFromEdgeCount(0),
|
_childEdgeFromEdgeCount(0),
|
||||||
@ -116,7 +118,8 @@ Refinement::refine(Options refineOptions) {
|
|||||||
// This will become redundant when/if assigned on construction:
|
// This will become redundant when/if assigned on construction:
|
||||||
assert(_parent && _child);
|
assert(_parent && _child);
|
||||||
|
|
||||||
_uniform = !refineOptions._sparse;
|
_uniform = !refineOptions._sparse;
|
||||||
|
_faceVertsFirst = refineOptions._faceVertsFirst;
|
||||||
|
|
||||||
// We may soon have an option here to suppress refinement of FVar channels...
|
// We may soon have an option here to suppress refinement of FVar channels...
|
||||||
bool refineOptions_ignoreFVarChannels = false;
|
bool refineOptions_ignoreFVarChannels = false;
|
||||||
@ -140,7 +143,7 @@ Refinement::refine(Options refineOptions) {
|
|||||||
// (though we do require the vertex-face relation for refining FVar channels):
|
// (though we do require the vertex-face relation for refining FVar channels):
|
||||||
//
|
//
|
||||||
Relations relationsToPopulate;
|
Relations relationsToPopulate;
|
||||||
if (refineOptions._faceTopologyOnly) {
|
if (refineOptions._minimalTopology) {
|
||||||
relationsToPopulate.setAll(false);
|
relationsToPopulate.setAll(false);
|
||||||
relationsToPopulate._faceVertices = true;
|
relationsToPopulate._faceVertices = true;
|
||||||
} else {
|
} else {
|
||||||
@ -222,18 +225,12 @@ void
|
|||||||
Refinement::populateParentChildIndices() {
|
Refinement::populateParentChildIndices() {
|
||||||
|
|
||||||
//
|
//
|
||||||
// Two vertex orderings are under consideration -- the original mode orders
|
// Two vertex orderings are currently supported -- ordering vertices refined
|
||||||
// vertices originating from faces first (historically these were relied upon
|
// from vertices first, or those refined from faces first. Its possible this
|
||||||
// to compute the rest of the vertices) while ordering vertices from vertices
|
// may be extended to more possibilities. Once the ordering is defined here,
|
||||||
// first is being considered (advantageous as it preserves the index of a parent
|
// other than analogous initialization in FVarRefinement, the treatment of
|
||||||
// vertex at all subsequent levels).
|
// vertices in blocks based on origin should make the rest of the code
|
||||||
//
|
// invariant to ordering changes.
|
||||||
// Other than defining the same ordering for refinement face-varying channels
|
|
||||||
// (which can be inferred from settings here) the rest of the code should be
|
|
||||||
// invariant to vertex ordering.
|
|
||||||
//
|
|
||||||
bool faceVertsFirst = false;
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// These two blocks now differ only in the utility function that assigns the
|
// These two blocks now differ only in the utility function that assigns the
|
||||||
// sequential values to the index vectors -- so parameterization/simplification
|
// sequential values to the index vectors -- so parameterization/simplification
|
||||||
@ -252,7 +249,7 @@ Refinement::populateParentChildIndices() {
|
|||||||
_childEdgeFromEdgeCount = sequenceFullIndexVector(_edgeChildEdgeIndices, _firstChildEdgeFromEdge);
|
_childEdgeFromEdgeCount = sequenceFullIndexVector(_edgeChildEdgeIndices, _firstChildEdgeFromEdge);
|
||||||
|
|
||||||
// child vertices:
|
// child vertices:
|
||||||
if (faceVertsFirst) {
|
if (_faceVertsFirst) {
|
||||||
_firstChildVertFromFace = 0;
|
_firstChildVertFromFace = 0;
|
||||||
_childVertFromFaceCount = sequenceFullIndexVector(_faceChildVertIndex, _firstChildVertFromFace);
|
_childVertFromFaceCount = sequenceFullIndexVector(_faceChildVertIndex, _firstChildVertFromFace);
|
||||||
|
|
||||||
@ -284,7 +281,7 @@ Refinement::populateParentChildIndices() {
|
|||||||
_childEdgeFromEdgeCount = sequenceSparseIndexVector(_edgeChildEdgeIndices, _firstChildEdgeFromEdge);
|
_childEdgeFromEdgeCount = sequenceSparseIndexVector(_edgeChildEdgeIndices, _firstChildEdgeFromEdge);
|
||||||
|
|
||||||
// child vertices:
|
// child vertices:
|
||||||
if (faceVertsFirst) {
|
if (_faceVertsFirst) {
|
||||||
_firstChildVertFromFace = 0;
|
_firstChildVertFromFace = 0;
|
||||||
_childVertFromFaceCount = sequenceSparseIndexVector(_faceChildVertIndex, _firstChildVertFromFace);
|
_childVertFromFaceCount = sequenceSparseIndexVector(_faceChildVertIndex, _firstChildVertFromFace);
|
||||||
|
|
||||||
@ -1081,6 +1078,25 @@ Refinement::subdivideFVarChannels() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Methods to inherit properties between refinements in a hierarchy:
|
||||||
|
//
|
||||||
|
void
|
||||||
|
Refinement::propagateBaseFace(Refinement const * grandParent) {
|
||||||
|
|
||||||
|
_childFaceBaseFaceIndex.resize(_child->_faceCount);
|
||||||
|
|
||||||
|
if (grandParent == 0) {
|
||||||
|
_childFaceBaseFaceIndex = _childFaceParentIndex;
|
||||||
|
} else {
|
||||||
|
IndexVector & childBaseFace = _childFaceBaseFaceIndex;
|
||||||
|
IndexVector const & parentBaseFace = grandParent->_childFaceBaseFaceIndex;
|
||||||
|
|
||||||
|
for (Index cFace = 0; cFace < _child->_faceCount; ++cFace) {
|
||||||
|
childBaseFace[cFace] = parentBaseFace[_childFaceParentIndex[cFace]];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Marking of sparse child components -- including those selected and those neighboring...
|
// Marking of sparse child components -- including those selected and those neighboring...
|
||||||
|
@ -82,40 +82,36 @@ public:
|
|||||||
Level& child() { return *_child; }
|
Level& child() { return *_child; }
|
||||||
|
|
||||||
//
|
//
|
||||||
// Options associated with the actual refinement operation, which are going to get
|
// Options associated with the actual refinement operation, which may end up
|
||||||
// quite involved to ensure that the refinement of data that is not of interest can
|
// quite involved if we want to allow for the refinement of data that is not
|
||||||
// be suppressed. For now we have:
|
// of interest to be suppressed. For now we have:
|
||||||
//
|
//
|
||||||
// "sparse": the alternative to uniform refinement, which requires that
|
// "sparse": the alternative to uniform refinement, which requires that
|
||||||
// components be previously selected/marked to be included.
|
// components be previously selected/marked to be included.
|
||||||
//
|
//
|
||||||
// "face topology only": this is one that may get broken down into a finer
|
// "minimal topology": this is one that may get broken down into a finer
|
||||||
// set of options. It suppresses "full topology" in the child level
|
// set of options. It suppresses "full topology" in the child level
|
||||||
// and only generates what is necessary to define the list of faces.
|
// and only generates what is minimally necessary for interpolation --
|
||||||
// This is only one of the six possible topological relations that
|
// which requires at least the face-vertices for faces, but also the
|
||||||
// can be generated -- we may eventually want a flag for each.
|
// vertex-faces for any face-varying channels present. So it will
|
||||||
|
// generate one or two of the six possible topological relations.
|
||||||
//
|
//
|
||||||
// "compute masks": this is intended to be temporary, along with the data
|
// These are strictly controlled right now, e.g. for sparse refinement, we
|
||||||
// members associated with it -- it will trigger the computation and
|
// currently enforce full topology at the finest level to allow for subsequent
|
||||||
// storage of mask weights for all child vertices. This is naively
|
// patch construction.
|
||||||
// stored at this point and exists only for reference.
|
|
||||||
//
|
|
||||||
// Its still up for debate as to how finely these should be controlled, e.g.
|
|
||||||
// for sparse refinement, we likely want full topology at the finest level to
|
|
||||||
// allow for subsequent patch construction...
|
|
||||||
//
|
//
|
||||||
struct Options {
|
struct Options {
|
||||||
Options() : _sparse(0),
|
Options() : _sparse(false),
|
||||||
_faceTopologyOnly(0)
|
_faceVertsFirst(false),
|
||||||
|
_minimalTopology(false)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
unsigned int _sparse : 1;
|
unsigned int _sparse : 1;
|
||||||
unsigned int _faceTopologyOnly : 1;
|
unsigned int _faceVertsFirst : 1;
|
||||||
|
unsigned int _minimalTopology : 1;
|
||||||
|
|
||||||
// Currently under consideration:
|
// Still under consideration:
|
||||||
//unsigned int _childToParentMap : 1;
|
//unsigned int _childToParentMap : 1;
|
||||||
//unsigned int _ancestorFacePerFace : 1;
|
|
||||||
//unsigned int _computeMasks : 1;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void refine(Options options = Options());
|
void refine(Options options = Options());
|
||||||
@ -156,6 +152,9 @@ public:
|
|||||||
|
|
||||||
Index getChildVertexParentIndex(Index v) const { return _childVertexParentIndex[v]; }
|
Index getChildVertexParentIndex(Index v) const { return _childVertexParentIndex[v]; }
|
||||||
|
|
||||||
|
// Child-to-"ancestor" relationships:
|
||||||
|
Index getChildFaceBaseFace(Index f) const { return _childFaceBaseFaceIndex[f]; }
|
||||||
|
|
||||||
//
|
//
|
||||||
// Non-public methods:
|
// Non-public methods:
|
||||||
//
|
//
|
||||||
@ -263,6 +262,8 @@ protected:
|
|||||||
void populateVertexTagsFromParentEdges();
|
void populateVertexTagsFromParentEdges();
|
||||||
void populateVertexTagsFromParentVertices();
|
void populateVertexTagsFromParentVertices();
|
||||||
|
|
||||||
|
void propagateBaseFace(Refinement const * previousRefinement);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Methods (and types) involved in subdividing the topology -- though not
|
// Methods (and types) involved in subdividing the topology -- though not
|
||||||
// fully exploited, any subset of the 6 relations can be generated:
|
// fully exploited, any subset of the 6 relations can be generated:
|
||||||
@ -326,6 +327,7 @@ protected:
|
|||||||
|
|
||||||
// Determined by the refinement options:
|
// Determined by the refinement options:
|
||||||
bool _uniform;
|
bool _uniform;
|
||||||
|
bool _faceVertsFirst;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Inventory and ordering of the types of child components:
|
// Inventory and ordering of the types of child components:
|
||||||
@ -391,6 +393,11 @@ protected:
|
|||||||
// Refinement data for face-varying channels present in the Levels being refined:
|
// Refinement data for face-varying channels present in the Levels being refined:
|
||||||
//
|
//
|
||||||
std::vector<FVarRefinement*> _fvarChannels;
|
std::vector<FVarRefinement*> _fvarChannels;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Child-to-base/ancestor mappings:
|
||||||
|
//
|
||||||
|
IndexVector _childFaceBaseFaceIndex;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline ConstIndexArray
|
inline ConstIndexArray
|
||||||
|
Loading…
Reference in New Issue
Block a user