mirror of
https://github.com/PixarAnimationStudios/OpenSubdiv
synced 2024-11-08 13:30:04 +00:00
WIP doxyfication of Sdc
This commit is contained in:
parent
d02fce995b
commit
8d86a2c6bd
@ -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
|
||||
|
@ -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:
|
||||
//
|
||||
|
@ -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:
|
||||
//
|
||||
|
@ -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 {
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user