OpenSubdiv

Types, constants and utilities related to semisharp creasing – whose implementation is independent of the subdivision scheme. More...
#include <crease.h>
Public Types  
enum  Rule { RULE_UNKNOWN = 0 , RULE_SMOOTH = (1 << 0) , RULE_DART = (1 << 1) , RULE_CREASE = (1 << 2) , RULE_CORNER = (1 << 3) } 
Public Member Functions  
Crease ()  
Crease (Options const &options)  
~Crease ()  
bool  IsUniform () const 
float  SharpenBoundaryEdge (float edgeSharpness) const 
float  SharpenBoundaryVertex (float edgeSharpness) const 
float  SubdivideUniformSharpness (float vertexOrEdgeSharpness) const 
float  SubdivideVertexSharpness (float vertexSharpness) const 
float  SubdivideEdgeSharpnessAtVertex (float edgeSharpness, int incidentEdgeCountAtEndVertex, float const *edgeSharpnessAroundEndVertex) const 
void  SubdivideEdgeSharpnessesAroundVertex (int incidentEdgeCountAtVertex, float const *incidentEdgeSharpnessAroundVertex, float *childEdgesSharpnessAroundVertex) const 
Rule  DetermineVertexVertexRule (float vertexSharpness, int incidentEdgeCount, float const *incidentEdgeSharpness) const 
Rule  DetermineVertexVertexRule (float vertexSharpness, int sharpEdgeCount) const 
float  ComputeFractionalWeightAtVertex (float vertexSharpness, float childVertexSharpness, int incidentEdgeCount, float const *incidentEdgeSharpness, float const *childEdgesSharpness) 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.  
void  GetSharpEdgePairOfCrease (float const *incidentEdgeSharpness, int incidentEdgeCount, int sharpEdgePair[2]) const 
Static Public Member Functions  
static bool  IsSmooth (float sharpness) 
static bool  IsSharp (float sharpness) 
static bool  IsInfinite (float sharpness) 
static bool  IsSemiSharp (float sharpness) 
Static Public Attributes  
static float const  SHARPNESS_SMOOTH 
static float const  SHARPNESS_INFINITE 
Protected Member Functions  
float  decrementSharpness (float sharpness) const 
Types, constants and utilities related to semisharp creasing – whose implementation is independent of the subdivision scheme.
Crease is intended to be a lightweight, trivially constructed class that computes creaserelated 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.
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 reuse.
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 occasionally 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 reuse is a worthwhile consideration.
enum Rule 
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 use bitwise operations to inspect collections of vertices (i.e. all of the vertices incident a particular face).
Enumerator  

RULE_UNKNOWN  
RULE_SMOOTH  
RULE_DART  
RULE_CREASE  
RULE_CORNER 
float ComputeFractionalWeightAtVertex  (  float  vertexSharpness, 
float  childVertexSharpness,  
int  incidentEdgeCount,  
float const *  incidentEdgeSharpness,  
float const *  childEdgesSharpness  
)  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.

inlineprotected 
Rule DetermineVertexVertexRule  (  float  vertexSharpness, 
int  incidentEdgeCount,  
float const *  incidentEdgeSharpness  
)  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 DetermineVertexVertexRule  (  float  vertexSharpness, 
int  sharpEdgeCount  
)  const 

inline 

inline 
Optional sharp features: Since options treat certain topological features as infinitely sharp – boundaries or (in future) nonmanifold features – sharpness values should be adjusted before use. The following methods will adjust (by return) specific values according to the options applied.

inline 
float SubdivideEdgeSharpnessAtVertex  (  float  edgeSharpness, 
int  incidentEdgeCountAtEndVertex,  
float const *  edgeSharpnessAroundEndVertex  
)  const 
void SubdivideEdgeSharpnessesAroundVertex  (  int  incidentEdgeCountAtVertex, 
float const *  incidentEdgeSharpnessAroundVertex,  
float *  childEdgesSharpnessAroundVertex  
)  const 

inline 
Sharpness subdivision: The computation of a Uniform subdivided sharpness value is as follows:

inline 

static 