Minor internal cleanup of Far::TopologyRefinerFactory

This commit is contained in:
barfowl 2015-01-03 12:26:02 -08:00
parent be7c8fdfd1
commit 877b09d668
2 changed files with 68 additions and 87 deletions

View File

@ -41,25 +41,30 @@ TopologyRefinerFactoryBase::validateComponentTopologySizing(TopologyRefiner& ref
Vtr::Level& baseLevel = refiner.getBaseLevel();
//
// At minimum we require face-vertices (the total count of which can be determined
// from the offsets accumulated during sizing pass) and we need to resize members
// related to them to be populated during assignment:
//
int vCount = baseLevel.getNumVertices();
int eCount = baseLevel.getNumEdges();
int fCount = baseLevel.getNumFaces();
assert((vCount > 0) && (fCount > 0));
//
// This still needs a little work -- currently we are assuming all counts and offsets
// have been assigned, but eventually only the counts will be assigined (in arbitrary
// order) and we will need to accumulate the offsets to get the total sizes. That
// will require new methods on Vtr::Level -- we do not want direct member access here.
//
int fVertCount = 0;
for (int i = 0; i < fCount; ++i) {
fVertCount += baseLevel.getNumFaceVertices(i);
}
int fVertCount = baseLevel.getNumFaceVertices(fCount - 1) +
baseLevel.getOffsetOfFaceVertices(fCount - 1);
baseLevel.resizeFaceVertices(fVertCount);
assert(baseLevel.getNumFaceVerticesTotal() > 0);
//
// If edges were sized, all other topological relations must be sized with it, in
// which case we allocate those members to be populated. Otherwise, sizing of the
// other topology members is deferred until the face-vertices are assigned and the
// resulting relationships determined:
//
int eCount = baseLevel.getNumEdges();
if (eCount > 0) {
baseLevel.resizeFaceEdges(baseLevel.getNumFaceVerticesTotal());
baseLevel.resizeEdgeVertices();
@ -84,13 +89,13 @@ TopologyRefinerFactoryBase::validateFaceVaryingComponentTopologyAssignment(Topol
}
//
// This method combines the initialization of component tags with the sharpening of edges and
// vertices according to the given boundary interpolation rule in the Options. Since both
// This method combines the initialization of internal component tags with the sharpening of edges
// and vertices according to the given boundary interpolation rule in the Options. Since both
// involve traversing the edge and vertex lists and noting the presence of boundaries -- best
// to do both at once...
//
void
TopologyRefinerFactoryBase::applyComponentTagsAndBoundarySharpness(TopologyRefiner& refiner) {
TopologyRefinerFactoryBase::applyInternalTagsAndBoundarySharpness(TopologyRefiner& refiner) {
Vtr::Level& baseLevel = refiner.getBaseLevel();

View File

@ -105,8 +105,8 @@ public:
protected:
static void validateComponentTopologySizing(TopologyRefiner& refiner);
static void applyInternalTagsAndBoundarySharpness(TopologyRefiner& refiner);
static void validateFaceVaryingComponentTopologyAssignment(TopologyRefiner& refiner);
static void applyComponentTagsAndBoundarySharpness(TopologyRefiner& refiner);
};
@ -165,12 +165,6 @@ protected:
typedef Vtr::Level::TopologyError TopologyError;
static void reportInvalidTopology(TopologyError errCode, char const * msg, MESH const& mesh);
protected:
// Other protected details -- not to be specialized:
static void populateBaseLevel(TopologyRefiner& refiner, MESH const& mesh);
};
@ -181,75 +175,52 @@ template <class MESH>
TopologyRefiner*
TopologyRefinerFactory<MESH>::Create(Sdc::Type type, Sdc::Options options, MESH const& mesh) {
TopologyRefiner *refiner = new TopologyRefiner(type, options);
populateBaseLevel(*refiner, mesh);
return refiner;
}
template <class MESH>
void
TopologyRefinerFactory<MESH>::populateBaseLevel(TopologyRefiner& refiner, MESH const& mesh) {
TopologyRefiner & refiner = *(new TopologyRefiner(type, options));
//
// The following three methods may end up virtual:
// - resize the component counts and relation counts for individual components:
// - assign the topological relations for all components:
// - assign any sharpness values, hole tags, etc:
// Note that we can do some sanity checking (independent of the type MESH) between these
// to ensure that a client has done what is necessary at each stage.
// Construction of a specialized topology refiner involves four steps, each of which
// typically involves a method that is specialized for MESH followed by one that takes
// an action in response to it or in preparation for the next step.
//
// Required specialization for MESH:
//
// Sizing of the topology -- this is a required specialization for MESH. This defines
// an inventory of all components and their relations that is used to allocate buffers
// to be efficiently populated in the subsequent topology assignment step.
//
resizeComponentTopology(refiner, mesh);
validateComponentTopologySizing(refiner);
// Required specialization for MESH:
//
// Assignment of the topology -- this is a required specialization for MESH. If edges
// are specified, all other topological relations are expected to be defined for them.
// Otherwise edges and remaining topology will be completed from the face-vertices:
//
assignComponentTopology(refiner, mesh);
Vtr::Level& baseLevel = refiner.getBaseLevel();
//
// In the future we may want the ability to complete aspects of the topology that
// are incovenient for clients to specify, e.g. the local indices associated with
// some relations, orienting the vertex relations, etc. For the near term we'll be
// assuming only face-vertices have been specified and the absence of edges will
// trigger the construction of everything else:
//
bool completeMissingTopology = (refiner.getBaseLevel().getNumEdges() == 0);
if (completeMissingTopology) {
// Need to invoke some Vtr::Level method to "fill in" the missing topology...
baseLevel.completeTopologyFromFaceVertices();
if (refiner.getBaseLevel().getNumEdges() == 0) {
refiner.getBaseLevel().completeTopologyFromFaceVertices();
}
// XXXX manuelk TODO : client code should control this
bool applyValidation = false;
if (applyValidation) {
Vtr::Level::ValidationCallback callback =
reinterpret_cast<Vtr::Level::ValidationCallback>(reportInvalidTopology);
if (not baseLevel.validateTopology(callback, &mesh)) {
char msg[1024];
snprintf(msg, 1024, "Invalid topology detected in TopologyRefinerFactory (%s)\n",
completeMissingTopology ? "partially specified and completed" : "fully specified");
Warning(msg);
//baseLevel.print();
assert(false);
}
}
// Optional specialization for MESH:
//
// User assigned and internal tagging of components -- assignment of user tags is an
// optional specialization for MESH:
//
assignComponentTags(refiner, mesh);
// Finalize the translation of the mesh after its full specification above:
applyComponentTagsAndBoundarySharpness(refiner);
applyInternalTagsAndBoundarySharpness(refiner);
// Optional specialization for MESH:
//
// Defining channels of face-varying primvar data -- assignment of the FVar topology is
// an optional specialization for MESH:
//
assignFaceVaryingTopology(refiner, mesh);
validateFaceVaryingComponentTopologyAssignment(refiner);
return &refiner;
}
// XXXX manuelk MSVC specializes these templated functions which creates duplicated symbols
@ -305,14 +276,14 @@ TopologyRefinerFactory<MESH>::assignComponentTopology(TopologyRefiner& /* refine
// Once the topology tables have been allocated, the six required topological
// relations can be directly populated using the following methods:
//
// void IndexArray TopologyRefiner::baseFaceVertices(Index face)
// void IndexArray TopologyRefiner::baseFaceEdges(Index face)
// IndexArray TopologyRefiner::setBaseFaceVertices(Index face)
// IndexArray TopologyRefiner::setBaseFaceEdges(Index face)
//
// void IndexArray TopologyRefiner::baseEdgeVertices(Index edge)
// void IndexArray TopologyRefiner::baseEdgeFaces(Index edge)
// IndexArray TopologyRefiner::setBaseEdgeVertices(Index edge)
// IndexArray TopologyRefiner::setBaseEdgeFaces(Index edge)
//
// void IndexArray TopologyRefiner::baseVertexEdges(Index vertex)
// void IndexArray TopologyRefiner::baseVertexFaces(Index vertex)
// IndexArray TopologyRefiner::setBaseVertexEdges(Index vertex)
// IndexArray TopologyRefiner::setBaseVertexFaces(Index vertex)
//
// For the last two relations -- the faces and edges incident a vertex -- there are
// also "local indices" that must be specified (considering doing this internally),
@ -320,17 +291,22 @@ TopologyRefinerFactory<MESH>::assignComponentTopology(TopologyRefiner& /* refine
// within that face or edge, and so ranging from 0-3 for incident quads and 0-1 for
// incident edges. These are assigned through similarly retrieved arrays:
//
// LocalIndexArray TopologyRefiner::baseVertexFaceLocalIndices(Index vertex)
// LocalIndexArray TopologyRefiner::baseVertexEdgeLocalIndices(Index vertex)
// LocalIndexArray TopologyRefiner::setBaseVertexFaceLocalIndices(Index vertex)
// LocalIndexArray TopologyRefiner::setBaseVertexEdgeLocalIndices(Index vertex)
//
// As noted, we are considering determining these internally to avoid this complexity,
// but that will require iteration through the sets of vertex-faces and edges to find
// the location of the vertex within each. If that is known at the time the incident
// componets are assigned, they we can avoid that separate pass.
// All components are assumed to be locally manifold and ordering of components in
// the above relations is expected to be counter-clockwise.
//
// We also need to tag vertices as manifold or not here. Failure to do so explicitly
// will require the factory analyze the local neighborhood of each component, which
// is costly and often unnecessary.
// For non-manifold components, no ordering/orientation of incident components is
// assumed or required, but be sure to explicitly tag such components (vertices as
// edges) as non-manifold:
//
// void TopologyRefiner::setBaseEdgeNonManifold(Index edge, bool b);
//
// void TopologyRefiner::setBaseVertexNonManifold(Index vertex, bool b);
//
// Also consider using TopologyRefiner::ValidateTopology() when debugging to ensure
// that topolology has been completely and correctly specified.
//
}