WIP doxyfication of Sdc

This commit is contained in:
manuelk 2014-12-22 11:29:15 -08:00
parent d02fce995b
commit 8d86a2c6bd
4 changed files with 155 additions and 154 deletions

View File

@ -1224,7 +1224,7 @@ GENERATE_TREEVIEW = YES
# documentation. Note that a value of 0 will completely suppress the enum
# values from appearing in the overview section.
ENUM_VALUES_PER_LINE = 4
ENUM_VALUES_PER_LINE = 1
# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be
# used to set the initial width (in pixels) of the frame in which the tree

View File

@ -33,37 +33,39 @@ namespace OPENSUBDIV_VERSION {
namespace Sdc {
//
// Types, constants and utilities related to semi-sharp creasing -- whose implementation is
// independent of the subdivision scheme.
//
// Crease is intended to be a light-weight, trivially constructed class that computes
// crease-related properties. An instance of an Crease is defined with a set of options
// that include current and future variations that will impact computations involving
// sharpness values.
//
// We do not to use Neighborhoods here as input. Since their sharpness values are potentially
// not specified (and gathered on demand), and the methods here rely more on the sharpness
// values and less on the topology, we choose to work directly with the sharpness values for
// more flexibility. We also follow the trend of using primitive arrays in the interface.
//
// Note on the need for and use of sharpness values:
// In general, mask queries rely on the sharpness values. The common case of a smooth
// vertex, when known, avoids the need to inspect them, but unless the rules are well understood,
// users will be expected to provided them -- particularly when they expect the mask queries
// to do all of the work (just determining if a vertex is smooth will require inspection of
// incident edge sharpness).
// Mask queries will occassionally require the subdivided sharpness values around the
// child vertex. So users will be expected to either provide them up front when known, or to be
// gathered on demand. Any implementation of subdivision with creasing cannot avoid subdividing
// the sharpness values first, so keeping them available for re-use is a worthwhile consideration.
//
///
/// \brief Types, constants and utilities related to semi-sharp creasing -- whose implementation is
/// independent of the subdivision scheme.
///
/// Crease is intended to be a light-weight, trivially constructed class that computes
/// crease-related properties. An instance of an Crease is defined with a set of options
/// that include current and future variations that will impact computations involving
/// sharpness values.
///
/// We do not to use Neighborhoods here as input. Since their sharpness values are potentially
/// not specified (and gathered on demand), and the methods here rely more on the sharpness
/// values and less on the topology, we choose to work directly with the sharpness values for
/// more flexibility. We also follow the trend of using primitive arrays in the interface.
///
/// Note on the need for and use of sharpness values:
/// In general, mask queries rely on the sharpness values. The common case of a smooth
/// vertex, when known, avoids the need to inspect them, but unless the rules are well understood,
/// users will be expected to provided them -- particularly when they expect the mask queries
/// to do all of the work (just determining if a vertex is smooth will require inspection of
/// incident edge sharpness).
/// Mask queries will occassionally require the subdivided sharpness values around the
/// child vertex. So users will be expected to either provide them up front when known, or to be
/// gathered on demand. Any implementation of subdivision with creasing cannot avoid subdividing
/// the sharpness values first, so keeping them available for re-use is a worthwhile consideration.
///
class Crease {
public:
//
// Constants and related queries of sharpness values:
//
//@{
/// Constants and related queries of sharpness values:
///
static float const SHARPNESS_SMOOTH; // = 0.0f, do we really need this?
static float const SHARPNESS_INFINITE; // = 10.0f;
@ -71,12 +73,13 @@ public:
static bool IsSharp(float sharpness) { return sharpness > SHARPNESS_SMOOTH; }
static bool IsInfinite(float sharpness) { return sharpness >= SHARPNESS_INFINITE; }
static bool IsSemiSharp(float sharpness) { return (SHARPNESS_SMOOTH < sharpness) && (sharpness < SHARPNESS_INFINITE); }
//@}
//
// Enum for the types of subdivision rules applied based on sharpness values (note these
// correspond to Hbr's vertex "mask"). The values are assigned to bit positions as it is
// useful to OR the corners of faces to quickly inspect its applicable rules.
//
///
/// Enum for the types of subdivision rules applied based on sharpness values (note these
/// correspond to Hbr's vertex "mask"). The values are assigned to bit positions as it is
/// useful to OR the corners of faces to quickly inspect its applicable rules.
///
enum Rule {
RULE_UNKNOWN = 0,
RULE_SMOOTH = (1 << 0),
@ -86,6 +89,7 @@ public:
};
public:
Crease() : _options() { }
Crease(Options const& options) : _options(options) { }
~Crease() { }
@ -98,30 +102,32 @@ public:
//
bool IsUniform() const { return _options.GetCreasingMethod() == Options::CREASE_UNIFORM; }
//
// Optional sharp features:
// Since options treat certain topological features as infinitely sharp -- boundaries
// or nonmanifold features -- sharpness values should be adjust before use. The following
// methods will adjust specific according to the options applied.
//
//@{
///
/// Optional sharp features:
/// Since options treat certain topological features as infinitely sharp -- boundaries
/// or nonmanifold features -- sharpness values should be adjusted before use. The following
/// methods will adjust specific according to the options applied.
///
float SharpenBoundaryEdge(float edgeSharpness) const;
float SharpenBoundaryVertex(float edgeSharpness) const;
float SharpenNonManifoldEdge(float edgeSharpness) const;
float SharpenNonManifoldVertex(float edgeSharpness) const;
//@}
//
// Sharpness subdivision:
// The simple case for computing a subdivided sharpness value is as follows:
// - Smooth edges or verts stay Smooth
// - Sharp edges or verts stay Sharp
// - semi-sharp edges or verts are decremented by 1.0
// but for Chaikin (and potentially future creasing schemes that improve upon it) the
// computation is more involved. In the case of edges in particular, the sharpness of a
// child edge is determined by the sharpness in the neighborhood of the end vertex
// corresponding to the child. For this reason, an alternative to subdividing sharpness
// that computes all child edges around a vertex is given.
//
//@{
/// Sharpness subdivision:
/// The simple case for computing a subdivided sharpness value is as follows:
/// - Smooth edges or verts stay Smooth
/// - Sharp edges or verts stay Sharp
/// - semi-sharp edges or verts are decremented by 1.0
/// but for Chaikin (and potentially future creasing schemes that improve upon it) the
/// computation is more involved. In the case of edges in particular, the sharpness of a
/// child edge is determined by the sharpness in the neighborhood of the end vertex
/// corresponding to the child. For this reason, an alternative to subdividing sharpness
/// that computes all child edges around a vertex is given.
///
float SubdivideUniformSharpness(float vertexOrEdgeSharpness) const;
float SubdivideVertexSharpness(float vertexSharpness) const;
@ -133,45 +139,46 @@ public:
void SubdivideEdgeSharpnessesAroundVertex(int incidentEdgeCountAtVertex,
float const* incidentEdgeSharpnessAroundVertex,
float* childEdgesSharpnessAroundVertex) const;
//@}
//
// Rule determination:
// Mask queries do not require the Rule to be known, it can be determined from
// the information provided, but it is generally more efficient when the Rule is known
// and provided. In particular, the Smooth case dominates and is known to be applicable
// based on the origin of the vertex without inspection of sharpness.
//
//@{
/// Rule determination:
/// Mask queries do not require the Rule to be known, it can be determined from
/// the information provided, but it is generally more efficient when the Rule is known
/// and provided. In particular, the Smooth case dominates and is known to be applicable
/// based on the origin of the vertex without inspection of sharpness.
///
Rule DetermineVertexVertexRule(float vertexSharpness,
int incidentEdgeCount,
float const* incidentEdgeSharpness) const;
Rule DetermineVertexVertexRule(float vertexSharpness,
int sharpEdgeCount) const;
//@}
//
// Transitional weighting:
// When the rules applicable to a parent vertex and its child differ, one or more
// sharpness values has "decayed" to zero. Both rules are then applicable and blended
// by a weight between 0 and 1 that reflects the transition. Most often this will be
// a single sharpness value that decays from within the interval [0,1] to zero -- and
// the weight to apply is exactly that sharpness value -- but more than one may decay,
// and values > 1 may also decay to 0 in a single step while others within [0,1] may
// remain > 0.
// So to properly determine a transitional weight, sharpness values for both the
// parent and child must be inspected, combined and clamped accordingly.
//
// Open questions:
// - does this method need to be public, or can it reside within the mask
// query classes? (though it would be the same for anything non-linear, so
// may be worth making a protected method somewhere)
// - does this need further consideration at an edge-vertex?
// - no, the edge-vertex case is far more trivial: one non-zero sharpness
// for the edge that decays to zero for one or both child edges -- the
// transitional weight is simply the edge sharpness (clamped to 1)
// ? why pass only the parent vertex sharpness...
// - because it is so trivial to compute the child vertex sharpness?
// - may be better off passing both parent and child for both vertex and edge
// just to be clear here.
//
/// \brief Transitional weighting
/// When the rules applicable to a parent vertex and its child differ, one or more
/// sharpness values has "decayed" to zero. Both rules are then applicable and blended
/// by a weight between 0 and 1 that reflects the transition. Most often this will be
/// a single sharpness value that decays from within the interval [0,1] to zero -- and
/// the weight to apply is exactly that sharpness value -- but more than one may decay,
/// and values > 1 may also decay to 0 in a single step while others within [0,1] may
/// remain > 0.
/// So to properly determine a transitional weight, sharpness values for both the
/// parent and child must be inspected, combined and clamped accordingly.
///
/// Open questions:
/// - does this method need to be public, or can it reside within the mask
/// query classes? (though it would be the same for anything non-linear, so
/// may be worth making a protected method somewhere)
/// - does this need further consideration at an edge-vertex?
/// - no, the edge-vertex case is far more trivial: one non-zero sharpness
/// for the edge that decays to zero for one or both child edges -- the
/// transitional weight is simply the edge sharpness (clamped to 1)
/// ? why pass only the parent vertex sharpness...
/// - because it is so trivial to compute the child vertex sharpness?
/// - may be better off passing both parent and child for both vertex and edge
/// just to be clear here.
///
float ComputeFractionalWeightAtVertex(float vertexSharpness,
float childVertexSharpness,
int incidentEdgeCount,
@ -190,8 +197,6 @@ private:
Options _options;
};
// XXXX manuelk non-manifold is not implemented yet - return infintely sharp as default for now
//
// Non-trivial inline declarations:
//

View File

@ -74,55 +74,55 @@ public:
Options GetOptions() const { return _options; }
void SetOptions(const Options& newOptions) { _options = newOptions; }
//
// Face-vertex masks - trivial for all current schemes:
//
///
/// \brief Face-vertex masks - trivial for all current schemes
///
template <typename FACE, typename MASK>
void ComputeFaceVertexMask(FACE const& faceNeighborhood, MASK& faceVertexMask) const;
//
// Edge-vertex masks:
// If known, the Rule for the edge and/or the derived vertex can be specified to
// accelerate the computation (though the Rule for the parent is trivially determined).
// In particular, knowing the child rule can avoid the need to subdivide the sharpness
// of the edge to see if it is a transitional crease that warrants fractional blending.
//
// Whether to use the "Rules" in this interface is really debatable -- the parent Rule
// is really based on the edge and its sharpness, while the child Rule is technically
// based on the neighborhood of the child vertex, but it can be deduced from the two
// child edges' sharpness. So the Crease methods used to compute these rules differ
// from those for the vertex-vertex mask. Perhaps a simple pair of new methods for
// Crease should be added specific to the edge-vertex case, i.e. one that takes a
// single sharpness (for the parent rule) and one that takes a pair (for the child).
//
///
/// \brief Edge-vertex masks
/// If known, the Rule for the edge and/or the derived vertex can be specified to
/// accelerate the computation (though the Rule for the parent is trivially determined).
/// In particular, knowing the child rule can avoid the need to subdivide the sharpness
/// of the edge to see if it is a transitional crease that warrants fractional blending.
///
/// Whether to use the "Rules" in this interface is really debatable -- the parent Rule
/// is really based on the edge and its sharpness, while the child Rule is technically
/// based on the neighborhood of the child vertex, but it can be deduced from the two
/// child edges' sharpness. So the Crease methods used to compute these rules differ
/// from those for the vertex-vertex mask. Perhaps a simple pair of new methods for
/// Crease should be added specific to the edge-vertex case, i.e. one that takes a
/// single sharpness (for the parent rule) and one that takes a pair (for the child).
///
template <typename EDGE, typename MASK>
void ComputeEdgeVertexMask(EDGE const& edgeNeighborhood, MASK& edgeVertexMask,
Crease::Rule parentRule = Crease::RULE_UNKNOWN,
Crease::Rule childRule = Crease::RULE_UNKNOWN) const;
//
// Vertex-vertex masks:
// If known, a single Rule or pair of Rules can be specified (indicating a crease
// transition) to accelerate the computation. Either no Rules, the first, or both should
// be specified. Specification of only the first Rule implies it to be true for both
// (wish the compiler would allow such default value specification), i.e. no transition.
// The case of knowing the parent Rule but deferring determination of the child Rule to
// this method is not supported.
//
///
/// ]brief Vertex-vertex masks
/// If known, a single Rule or pair of Rules can be specified (indicating a crease
/// transition) to accelerate the computation. Either no Rules, the first, or both should
/// be specified. Specification of only the first Rule implies it to be true for both
/// (wish the compiler would allow such default value specification), i.e. no transition.
/// The case of knowing the parent Rule but deferring determination of the child Rule to
/// this method is not supported.
///
template <typename VERTEX, typename MASK>
void ComputeVertexVertexMask(VERTEX const& vertexNeighborhood, MASK& vertexVertexMask,
Crease::Rule parentRule = Crease::RULE_UNKNOWN,
Crease::Rule childRule = Crease::RULE_UNKNOWN) const;
//
// IN PROGRESS -- NOT YET FULLY FUNCTIONAL...
//
// Masks for limit points and tangents -- note that these require the vertex be
// suitably isolated such that its limit is well-defined.
//
// These are stubs that are still being completed. The position masks are now
// supported but tangent masks need work.
//
///
/// \brief IN PROGRESS -- NOT YET FULLY FUNCTIONAL...
///
/// Masks for limit points and tangents -- note that these require the vertex be
/// suitably isolated such that its limit is well-defined.
///
/// These are stubs that are still being completed. The position masks are now
/// supported but tangent masks need work.
///
template <typename VERTEX, typename MASK>
void ComputeVertexLimitMask(VERTEX const& vertexNeighborhood, MASK& positionMask) const;
@ -131,11 +131,11 @@ public:
MASK& tangent1Mask,
MASK& tangent2Mask) const;
protected:
//
// Supporting internal methods -- optionally implemented, depending on specialization:
//
//
// Subdivision/refinement masks -- two for edge-vertices and three for vertex-vertices:
//
template <typename EDGE, typename MASK>
@ -167,6 +167,7 @@ private:
Options _options;
protected:
//
// Internal implementation support:
//

View File

@ -31,17 +31,9 @@ namespace OPENSUBDIV_VERSION {
namespace Sdc {
//
// Enumerated type for all subdivisions schemes supported by OpenSubdiv:
//
// Questions:
// In general, scoping of enumeration names is an issue given the lack of nested
// namespaces. Originally I gave all other types a qualifying prefix to avoid conflicts
// but these names didn't seem to warrant it, but I added one later.
//
// Note there is a similar Scheme enum in FarSubdivisionTables that includes UNKNOWN=0
// along with the same three constants.
//
///
/// \brief Enumerated type for all subdivisions schemes supported by OpenSubdiv
///
enum Type {
TYPE_BILINEAR,
TYPE_CATMARK,
@ -49,29 +41,32 @@ enum Type {
};
//
// Traits associated with all types -- these are specialized and instantiated for
// each of the supported types.
//
// Traits do not vary with the topology or any options applied to the scheme. They
// are intended to help construct more general queries about a subdivision scheme
// in a context where its details may be less well understood. They serve little
// purpose in code specialized to the particular scheme, i.e. in code already
// specialized for Catmark, the values for these traits for the Catmark scheme are
// typically known and their usage well understood.
//
// Question:
// Do we really need/want these TypeTraits, or will static methods on another
// class specialized for the type suffice, i.e. Scheme<SCHEME_TYPE>?
// If yes, there will be little in here other than Sdc::Type, which we may want
// to merge into <sdc/options.h>.
//
///
/// \brief Enumerated type for all face splitting scheme
///
enum Split {
SPLIT_TO_QUADS, // used by Catmark and Bilinear
SPLIT_TO_TRIS, // used by Loop
SPLIT_HYBRID // not currently used (potential future extension)
SPLIT_TO_QUADS, ///< Used by Catmark and Bilinear
SPLIT_TO_TRIS, ///< Used by Loop
SPLIT_HYBRID ///< Not currently used (potential future extension)
};
///
/// \brief Traits associated with all types. These are specialized and instantiated for
/// each of the supported types.
///
/// Traits do not vary with the topology or any options applied to the scheme. They
/// are intended to help construct more general queries about a subdivision scheme
/// in a context where its details may be less well understood. They serve little
/// purpose in code specialized to the particular scheme, i.e. in code already
/// specialized for Catmark, the values for these traits for the Catmark scheme are
/// typically known and their usage well understood.
///
// Question:
// Do we really need/want these TypeTraits, or will static methods on another
// class specialized for the type suffice, i.e. Scheme<SCHEME_TYPE>?
// If yes, there will be little in here other than Sdc::Type, which we may want
// to merge into <sdc/options.h>.
//
template <Type SCHEME_TYPE>
struct TypeTraits {