mirror of
https://github.com/PixarAnimationStudios/OpenSubdiv
synced 2024-11-27 05:50:05 +00:00
Minor code cleanup:
- removed Vtr::Sharpness typedef within Vtr - culled obsolete comments from Sdc headers
This commit is contained in:
parent
13e9136b63
commit
13f148aac8
@ -34,18 +34,18 @@ namespace OPENSUBDIV_VERSION {
|
||||
namespace Sdc {
|
||||
|
||||
///
|
||||
/// \brief Types, constants and utilities related to semi-sharp creasing -- whose implementation is
|
||||
/// independent of the subdivision scheme.
|
||||
/// \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.
|
||||
/// crease-related properties -- typically sharpness values and associated interpolation
|
||||
/// weights. An instance of 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.
|
||||
/// The Crease methods do not use topological neighborhoods as input. The methods here
|
||||
/// rely more on the sharpness values and less on the topology, so we choose to work directly
|
||||
/// with the sharpness values. We also follow the trend of using primitive arrays in the
|
||||
/// interface to encourage local gathering for re-use.
|
||||
///
|
||||
/// 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
|
||||
@ -60,13 +60,11 @@ namespace Sdc {
|
||||
///
|
||||
|
||||
class Crease {
|
||||
|
||||
public:
|
||||
|
||||
//@{
|
||||
/// Constants and related queries of sharpness values:
|
||||
///
|
||||
static float const SHARPNESS_SMOOTH; // = 0.0f, do we really need this?
|
||||
static float const SHARPNESS_SMOOTH; // = 0.0f, do we really need this?
|
||||
static float const SHARPNESS_INFINITE; // = 10.0f;
|
||||
|
||||
static bool IsSmooth(float sharpness) { return sharpness <= SHARPNESS_SMOOTH; }
|
||||
@ -78,7 +76,8 @@ public:
|
||||
///
|
||||
/// 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.
|
||||
/// useful to use bitwise operations to inspect collections of vertices (i.e. all of the
|
||||
/// vertices incident a particular face).
|
||||
///
|
||||
enum Rule {
|
||||
RULE_UNKNOWN = 0,
|
||||
@ -89,40 +88,34 @@ public:
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
Crease() : _options() { }
|
||||
Crease(Options const& options) : _options(options) { }
|
||||
~Crease() { }
|
||||
|
||||
//
|
||||
// Considering labeling the current/default/normal creasing method as "simple" in contrast
|
||||
// to all others that are "complex". The idea is that code can make certain assumptions
|
||||
// and take some "simple" action in some cases to avoid the higher costs of dealing with
|
||||
// more complex implementations.
|
||||
//
|
||||
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 adjusted before use. The following
|
||||
/// methods will adjust specific according to the options applied.
|
||||
/// or (in future) nonmanifold features -- sharpness values should be adjust before use.
|
||||
/// The following methods will adjust (by return) specific values 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;
|
||||
// For future consideration
|
||||
//float SharpenNonManifoldEdge(float edgeSharpness) const;
|
||||
//float SharpenNonManifoldVertex(float edgeSharpness) const;
|
||||
//@}
|
||||
|
||||
//@{
|
||||
/// Sharpness subdivision:
|
||||
/// The simple case for computing a subdivided sharpness value is as follows:
|
||||
/// The computation of a Uniform 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
|
||||
/// but for Chaikin (and potentially future non-uniform 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
|
||||
@ -155,7 +148,7 @@ public:
|
||||
int sharpEdgeCount) const;
|
||||
//@}
|
||||
|
||||
/// \brief Transitional weighting
|
||||
/// \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
|
||||
@ -166,19 +159,6 @@ public:
|
||||
/// 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,
|
||||
@ -197,14 +177,19 @@ private:
|
||||
Options _options;
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// Non-trivial inline declarations:
|
||||
// Inline declarations:
|
||||
//
|
||||
inline float
|
||||
Crease::SharpenBoundaryEdge(float edgeSharpness) const {
|
||||
Crease::SharpenBoundaryEdge(float /* edgeSharpness */) const {
|
||||
|
||||
return (_options.GetVtxBoundaryInterpolation() != Options::VTX_BOUNDARY_NONE) ?
|
||||
SHARPNESS_INFINITE : edgeSharpness;
|
||||
//
|
||||
// Despite the presence of the BOUNDARY_NONE option, boundary edges are always sharpened.
|
||||
// Much of the code relies on sharpess to indicate boundaries to avoid the more complex
|
||||
// topological inspection
|
||||
//
|
||||
return SHARPNESS_INFINITE;
|
||||
}
|
||||
|
||||
inline float
|
||||
|
@ -31,22 +31,6 @@ namespace OPENSUBDIV_VERSION {
|
||||
|
||||
namespace Sdc {
|
||||
|
||||
// BETA NOTES:
|
||||
// Several of these options are being reconsidered in light of the divergence of
|
||||
// OSD 3.0 from Hbr. In some cases the options can be expressed more clearly and free
|
||||
// of any RenderMan legacy for future use. Details are noted below:
|
||||
// "VtxBoundaryInterpolation"
|
||||
// - its effect is to sharpen edges/corners, but edges are always sharpened
|
||||
// - the "None" case serves no purpose (and would be discouraged)
|
||||
// "FVarLinearInterpolation":
|
||||
// - the new "corner only" mode will sharpen corners and NEVER sharpen smooth
|
||||
// boundaries, which we believe to be expected when sharping corners -- the
|
||||
// old "edge and corner" mode would sharpen boundaries under some situations
|
||||
// (e.g. more than three fvar values at a vertex)
|
||||
// "NonManifoldInterpolation":
|
||||
// - rules still need to be defined and implemented
|
||||
//
|
||||
|
||||
///
|
||||
/// \brief All supported options applying to subdivision scheme.
|
||||
///
|
||||
@ -63,6 +47,23 @@ namespace Sdc {
|
||||
/// scheme. Ideally it remains a set of bit-fields (essentially an int) and so
|
||||
/// remains light weight and easily passed down by value.
|
||||
///
|
||||
|
||||
//
|
||||
// BETA NOTES:
|
||||
// Several of these options are being reconsidered in light of the divergence of
|
||||
// OSD 3.0 from Hbr. In some cases the options can be expressed more clearly and free
|
||||
// of any RenderMan legacy for future use. Details are noted below:
|
||||
// "VtxBoundaryInterpolation"
|
||||
// - its effect is to sharpen edges/corners, but edges are always sharpened
|
||||
// - the "None" case serves no purpose (and would be discouraged)
|
||||
// "FVarLinearInterpolation":
|
||||
// - the new "corner only" mode will sharpen corners and NEVER sharpen smooth
|
||||
// boundaries, which we believe to be expected when sharping corners -- the
|
||||
// old "edge and corner" mode would sharpen boundaries under some situations
|
||||
// (e.g. more than three fvar values at a vertex)
|
||||
// "NonManifoldInterpolation":
|
||||
// - rules still need to be defined and implemented
|
||||
//
|
||||
class Options {
|
||||
public:
|
||||
enum VtxBoundaryInterpolation {
|
||||
|
@ -101,7 +101,7 @@ public:
|
||||
Crease::Rule childRule = Crease::RULE_UNKNOWN) const;
|
||||
|
||||
///
|
||||
/// ]brief Vertex-vertex masks
|
||||
/// \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
|
||||
|
@ -219,8 +219,8 @@ public:
|
||||
ConstLocalIndexArray getVertexEdgeLocalIndices(Index vertIndex) const;
|
||||
|
||||
// Replace these with access to sharpness buffers/arrays rather than elements:
|
||||
Sharpness getEdgeSharpness(Index edgeIndex) const;
|
||||
Sharpness getVertexSharpness(Index vertIndex) const;
|
||||
float getEdgeSharpness(Index edgeIndex) const;
|
||||
float getVertexSharpness(Index vertIndex) const;
|
||||
Sdc::Crease::Rule getVertexRule(Index vertIndex) const;
|
||||
|
||||
Index findEdge(Index v0Index, Index v1Index) const;
|
||||
@ -318,8 +318,8 @@ protected:
|
||||
LocalIndexArray getVertexEdgeLocalIndices(Index vertIndex);
|
||||
|
||||
// Replace these with access to sharpness buffers/arrays rather than elements:
|
||||
Sharpness& getEdgeSharpness(Index edgeIndex);
|
||||
Sharpness& getVertexSharpness(Index vertIndex);
|
||||
float& getEdgeSharpness(Index edgeIndex);
|
||||
float& getVertexSharpness(Index vertIndex);
|
||||
|
||||
// Create, destroy and populate face-varying channels:
|
||||
int createFVarChannel(int fvarValueCount, Sdc::Options const& options);
|
||||
@ -442,8 +442,8 @@ protected:
|
||||
std::vector<Index> _edgeFaceCountsAndOffsets; // 2 per edge
|
||||
std::vector<Index> _edgeFaceIndices; // varies with faces per edge
|
||||
|
||||
std::vector<Sharpness> _edgeSharpness; // 1 per edge
|
||||
std::vector<ETag> _edgeTags; // 1 per edge: manifold, boundary, etc.
|
||||
std::vector<float> _edgeSharpness; // 1 per edge
|
||||
std::vector<ETag> _edgeTags; // 1 per edge: manifold, boundary, etc.
|
||||
|
||||
// Per-vertex:
|
||||
std::vector<Index> _vertFaceCountsAndOffsets; // 2 per vertex
|
||||
@ -454,7 +454,7 @@ protected:
|
||||
std::vector<Index> _vertEdgeIndices; // varies with valence
|
||||
std::vector<LocalIndex> _vertEdgeLocalIndices; // varies with valence, 8-bit for now
|
||||
|
||||
std::vector<Sharpness> _vertSharpness; // 1 per vertex
|
||||
std::vector<float> _vertSharpness; // 1 per vertex
|
||||
std::vector<VTag> _vertTags; // 1 per vertex: manifold, Sdc::Rule, etc.
|
||||
|
||||
// Face-varying channels:
|
||||
@ -620,20 +620,20 @@ Level::trimEdgeFaces(Index edgeIndex, int count) {
|
||||
//
|
||||
// Access/modify sharpness values:
|
||||
//
|
||||
inline Sharpness
|
||||
inline float
|
||||
Level::getEdgeSharpness(Index edgeIndex) const {
|
||||
return _edgeSharpness[edgeIndex];
|
||||
}
|
||||
inline Sharpness&
|
||||
inline float&
|
||||
Level::getEdgeSharpness(Index edgeIndex) {
|
||||
return _edgeSharpness[edgeIndex];
|
||||
}
|
||||
|
||||
inline Sharpness
|
||||
inline float
|
||||
Level::getVertexSharpness(Index vertIndex) const {
|
||||
return _vertSharpness[vertIndex];
|
||||
}
|
||||
inline Sharpness&
|
||||
inline float&
|
||||
Level::getVertexSharpness(Index vertIndex) {
|
||||
return _vertSharpness[vertIndex];
|
||||
}
|
||||
|
@ -880,14 +880,14 @@ Refinement::subdivideEdgeSharpness() {
|
||||
Index cEdge = getFirstChildEdgeFromEdges();
|
||||
Index cEdgeEnd = cEdge + getNumChildEdgesFromEdges();
|
||||
for ( ; cEdge < cEdgeEnd; ++cEdge) {
|
||||
Sharpness& cSharpness = _child->_edgeSharpness[cEdge];
|
||||
float& cSharpness = _child->_edgeSharpness[cEdge];
|
||||
Level::ETag& cEdgeTag = _child->_edgeTags[cEdge];
|
||||
|
||||
if (cEdgeTag._infSharp) {
|
||||
cSharpness = Sdc::Crease::SHARPNESS_INFINITE;
|
||||
} else if (cEdgeTag._semiSharp) {
|
||||
Index pEdge = _childEdgeParentIndex[cEdge];
|
||||
Sharpness pSharpness = _parent->_edgeSharpness[pEdge];
|
||||
Index pEdge = _childEdgeParentIndex[cEdge];
|
||||
float pSharpness = _parent->_edgeSharpness[pEdge];
|
||||
|
||||
if (creasing.IsUniform()) {
|
||||
cSharpness = creasing.SubdivideUniformSharpness(pSharpness);
|
||||
@ -924,14 +924,14 @@ Refinement::subdivideVertexSharpness() {
|
||||
Index cVertEnd = cVertBegin + getNumChildVerticesFromVertices();
|
||||
|
||||
for (Index cVert = cVertBegin; cVert < cVertEnd; ++cVert) {
|
||||
Sharpness& cSharpness = _child->_vertSharpness[cVert];
|
||||
float& cSharpness = _child->_vertSharpness[cVert];
|
||||
Level::VTag& cVertTag = _child->_vertTags[cVert];
|
||||
|
||||
if (cVertTag._infSharp) {
|
||||
cSharpness = Sdc::Crease::SHARPNESS_INFINITE;
|
||||
} else if (cVertTag._semiSharp) {
|
||||
Index pVert = _childVertexParentIndex[cVert];
|
||||
Sharpness pSharpness = _parent->_vertSharpness[pVert];
|
||||
Index pVert = _childVertexParentIndex[cVert];
|
||||
float pSharpness = _parent->_vertSharpness[pVert];
|
||||
|
||||
cSharpness = creasing.SubdivideVertexSharpness(pSharpness);
|
||||
|
||||
|
@ -36,14 +36,9 @@ namespace OPENSUBDIV_VERSION {
|
||||
namespace Vtr {
|
||||
|
||||
//
|
||||
// A few types (and constants) are declared here while Vtr is being
|
||||
// developed. These tend to be used by more than one Vtr class, i.e.
|
||||
// both Level and Refinement and are often present in their
|
||||
// interfaces.
|
||||
// A few types (and constants) for use within Vtr and potentially by its
|
||||
// clients (appropriately exported and retyped)
|
||||
//
|
||||
// Is the sharpness overkill -- perhaps sdc should define this...
|
||||
//
|
||||
typedef float Sharpness;
|
||||
|
||||
//
|
||||
// Indices -- note we can't use sized integer types like uint32_t, etc. as use of
|
||||
@ -63,9 +58,10 @@ static const Index INDEX_INVALID = -1;
|
||||
inline bool IndexIsValid(Index index) { return (index != INDEX_INVALID); }
|
||||
|
||||
//
|
||||
// Note for aggregate types the use of "vector" wraps an std:;vector (typically a
|
||||
// member variable) and is fully resizable and owns its own storage, whereas "array"
|
||||
// is typically used in index a fixed subset of pre-allocated memory:
|
||||
// Note for aggregate types that the use of "vector" in the name indicates a class
|
||||
// that wraps an std:;vector (typically a member variable) which is fully resizable
|
||||
// and owns its own storage, whereas "array" indicates a fixed block of pre-allocated
|
||||
// memory:
|
||||
//
|
||||
typedef std::vector<Index> IndexVector;
|
||||
|
||||
@ -79,9 +75,7 @@ typedef ConstArray<LocalIndex> ConstLocalIndexArray;
|
||||
} // end namespace Vtr
|
||||
|
||||
} // end namespace OPENSUBDIV_VERSION
|
||||
|
||||
using namespace OPENSUBDIV_VERSION;
|
||||
|
||||
} // end namespace OpenSubdiv
|
||||
|
||||
#endif /* VTR_TYPES_H */
|
||||
|
Loading…
Reference in New Issue
Block a user