Add Chromium-only Blender WebEngine parity work
This commit is contained in:
382
blender-5.2.0/extern/opensubdiv-source/opensubdiv/bfr/faceVertex.h
vendored
Normal file
382
blender-5.2.0/extern/opensubdiv-source/opensubdiv/bfr/faceVertex.h
vendored
Normal file
@@ -0,0 +1,382 @@
|
||||
//
|
||||
// Copyright 2021 Pixar
|
||||
//
|
||||
// Licensed under the terms set forth in the LICENSE.txt file available at
|
||||
// https://opensubdiv.org/license.
|
||||
//
|
||||
|
||||
#ifndef OPENSUBDIV3_BFR_FACE_VERTEX_H
|
||||
#define OPENSUBDIV3_BFR_FACE_VERTEX_H
|
||||
|
||||
#include "../version.h"
|
||||
|
||||
#include "../bfr/vertexTag.h"
|
||||
#include "../bfr/vertexDescriptor.h"
|
||||
#include "../bfr/faceVertexSubset.h"
|
||||
#include "../bfr/surfaceData.h"
|
||||
#include "../sdc/crease.h"
|
||||
|
||||
#include <cassert>
|
||||
|
||||
namespace OpenSubdiv {
|
||||
namespace OPENSUBDIV_VERSION {
|
||||
|
||||
namespace Bfr {
|
||||
|
||||
//
|
||||
// The FaceVertex class is the primary internal class for gathering all
|
||||
// topological information around the corner of a face. As such, it
|
||||
// wraps an instance of the public VertexDescriptor class populated by the
|
||||
// Factory subclasses. It extends an instance of VertexDescriptor with
|
||||
// additional topological information and methods to make it more widely
|
||||
// available and useful to internal classes.
|
||||
//
|
||||
// One fundamental extension of FaceVertex is that it includes the
|
||||
// location of the face in the ring of incident faces around the vertex.
|
||||
// VertexDescriptor alone simply specifies the neighborhood of the
|
||||
// vertex, but the FaceVertex provides context relative to the face for
|
||||
// which all of this information is being gathered.
|
||||
//
|
||||
// Several instances of FaceVertex (one for each corner of a face)
|
||||
// are necessary to fully define the limit surface for a face, but in
|
||||
// many cases, only a subset of the FaceVertex's incident faces will
|
||||
// actually contribute to the surface. A companion class for defining
|
||||
// that subset is defined elsewhere.
|
||||
//
|
||||
class FaceVertex {
|
||||
public:
|
||||
typedef internal::SurfaceData::Index Index;
|
||||
|
||||
public:
|
||||
FaceVertex() { }
|
||||
~FaceVertex() { }
|
||||
|
||||
// Methods supporting construction/initialization (subclass required
|
||||
// to populate VertexDescriptor between Initialize and Finalize):
|
||||
void Initialize(int faceSize, int regFaceSize);
|
||||
void Finalize(int faceInVertex);
|
||||
|
||||
VertexDescriptor & GetVertexDescriptor() { return _vDesc; }
|
||||
|
||||
void ConnectUnOrderedFaces(Index const faceVertexIndices[]);
|
||||
|
||||
public:
|
||||
// Methods to initialize and find subsets:
|
||||
typedef FaceVertexSubset Subset;
|
||||
|
||||
int GetVertexSubset(Subset * subset) const;
|
||||
|
||||
int FindFaceVaryingSubset(Subset * fvarSubset,
|
||||
Index const fvarIndices[],
|
||||
Subset const & vtxSubset) const;
|
||||
|
||||
// Methods to control sharpness of the corner in a subset:
|
||||
void SharpenSubset(Subset * subset) const;
|
||||
void SharpenSubset(Subset * subset, float sharpness) const;
|
||||
void UnSharpenSubset(Subset * subset) const;
|
||||
|
||||
public:
|
||||
//
|
||||
// Public methods to query simple properties:
|
||||
//
|
||||
VertexTag GetTag() const { return _tag; }
|
||||
|
||||
int GetFace() const { return _faceInRing; }
|
||||
|
||||
int GetNumFaces() const { return _vDesc._numFaces; }
|
||||
int GetNumFaceVertices() const { return _numFaceVerts; }
|
||||
|
||||
bool HasCommonFaceSize() const { return (_commonFaceSize > 0); }
|
||||
int GetCommonFaceSize() const { return _commonFaceSize; }
|
||||
|
||||
public:
|
||||
//
|
||||
// Public methods to inspect incident faces and connected neighbors:
|
||||
//
|
||||
int GetFaceSize(int face) const;
|
||||
|
||||
// Get neighbors of a specific face (return -1 if unconnected):
|
||||
int GetFaceNext( int face) const;
|
||||
int GetFacePrevious(int face) const;
|
||||
|
||||
// Find faces relative to this face (require a known safe step size):
|
||||
int GetFaceAfter (int stepForwardFromCornerFace) const;
|
||||
int GetFaceBefore(int stepBackwardFromCornerFace) const;
|
||||
|
||||
// Get first and last faces of a subset:
|
||||
int GetFaceFirst(Subset const & subset) const;
|
||||
int GetFaceLast( Subset const & subset) const;
|
||||
|
||||
public:
|
||||
//
|
||||
// Public methods to access indices assigned to incident faces:
|
||||
//
|
||||
int GetFaceIndexOffset(int face) const;
|
||||
|
||||
Index GetFaceIndexAtCorner(Index const indices[]) const;
|
||||
|
||||
Index GetFaceIndexAtCorner(int face, Index const indices[]) const;
|
||||
Index GetFaceIndexTrailing(int face, Index const indices[]) const;
|
||||
Index GetFaceIndexLeading( int face, Index const indices[]) const;
|
||||
|
||||
bool FaceIndicesMatchAtCorner( int f1, int f2, Index const indices[])const;
|
||||
bool FaceIndicesMatchAtEdgeEnd( int f1, int f2, Index const indices[])const;
|
||||
bool FaceIndicesMatchAcrossEdge(int f1, int f2, Index const indices[])const;
|
||||
|
||||
public:
|
||||
//
|
||||
// Public methods for sharpness of the vertex or its incident edges:
|
||||
//
|
||||
float GetVertexSharpness() const;
|
||||
|
||||
float GetFaceEdgeSharpness(int faceEdge) const;
|
||||
float GetFaceEdgeSharpness(int face, bool trailingEdge) const;
|
||||
|
||||
bool IsFaceEdgeSharp( int face, bool trailingEdge) const;
|
||||
bool IsFaceEdgeInfSharp( int face, bool trailingEdge) const;
|
||||
bool IsFaceEdgeSemiSharp(int face, bool trailingEdge) const;
|
||||
|
||||
bool HasImplicitVertexSharpness() const;
|
||||
float GetImplicitVertexSharpness() const;
|
||||
|
||||
private:
|
||||
// Internal convenience methods:
|
||||
bool isOrdered() const { return _tag.IsOrdered(); }
|
||||
bool isUnOrdered() const { return _tag.IsUnOrdered(); }
|
||||
bool isBoundary() const { return _tag.IsBoundary(); }
|
||||
bool isInterior() const { return _tag.IsInterior(); }
|
||||
bool isManifold() const { return _tag.IsManifold(); }
|
||||
|
||||
int getConnectedFaceNext(int face) const;
|
||||
int getConnectedFacePrev(int face) const;
|
||||
|
||||
private:
|
||||
// Internal methods for assembling and managing subsets:
|
||||
int initCompleteSubset(Subset * subset) const;
|
||||
|
||||
int findConnectedSubsetExtent(Subset * subset) const;
|
||||
|
||||
int findFVarSubsetExtent(Subset const & vtxSubset,
|
||||
Subset * fvarSubset,
|
||||
Index const fvarIndices[]) const;
|
||||
|
||||
void adjustSubsetTags(Subset * subset,
|
||||
Subset const * superset = 0) const;
|
||||
|
||||
bool subsetHasInfSharpEdges( Subset const & subset) const;
|
||||
bool subsetHasSemiSharpEdges(Subset const & subset) const;
|
||||
bool subsetHasIrregularFaces(Subset const & subset) const;
|
||||
|
||||
private:
|
||||
// Internal methods to connect a set of unordered faces (given their
|
||||
// associated face-vertex indices) and assess the resulting topology:
|
||||
struct Edge;
|
||||
|
||||
int createUnOrderedEdges(Edge edges[],
|
||||
short faceEdgeIndices[],
|
||||
Index const faceVertIndices[]) const;
|
||||
|
||||
void markDuplicateEdges(Edge edges[],
|
||||
short const faceEdgeIndices[],
|
||||
Index const faceVertIndices[]) const;
|
||||
|
||||
void assignUnOrderedFaceNeighbors(Edge const edges[],
|
||||
short const faceEdgeIndices[]);
|
||||
|
||||
bool testNonManifoldCrease(Edge const edges[], int numEdges,
|
||||
Index const faceVertIndices[]) const;
|
||||
|
||||
void finalizeUnOrderedTags(Edge const edges[], int numEdges,
|
||||
Index const faceVertIndices[]);
|
||||
|
||||
// Ordered counterpart to the above method for finalizing tags
|
||||
void finalizeOrderedTags();
|
||||
|
||||
private:
|
||||
typedef Vtr::internal::StackBuffer<short,16,true> ShortBuffer;
|
||||
|
||||
// Private members:
|
||||
VertexDescriptor _vDesc;
|
||||
VertexTag _tag;
|
||||
|
||||
short _faceInRing;
|
||||
short _commonFaceSize;
|
||||
|
||||
unsigned char _regFaceSize;
|
||||
unsigned char _isExpInfSharp : 1;
|
||||
unsigned char _isExpSemiSharp : 1;
|
||||
unsigned char _isImpInfSharp : 1;
|
||||
unsigned char _isImpSemiSharp : 1;
|
||||
|
||||
int _numFaceVerts;
|
||||
|
||||
ShortBuffer _faceEdgeNeighbors;
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// Inline methods for inspecting/traversing incident faces of the vertex:
|
||||
//
|
||||
inline int
|
||||
FaceVertex::GetFaceSize(int face) const {
|
||||
return _commonFaceSize ? _commonFaceSize :
|
||||
(_vDesc._faceSizeOffsets[face+1] - _vDesc._faceSizeOffsets[face]);
|
||||
}
|
||||
|
||||
inline int
|
||||
FaceVertex::getConnectedFaceNext(int face) const {
|
||||
return _faceEdgeNeighbors[2*face + 1];
|
||||
}
|
||||
inline int
|
||||
FaceVertex::getConnectedFacePrev(int face) const {
|
||||
return _faceEdgeNeighbors[2*face];
|
||||
}
|
||||
|
||||
inline int
|
||||
FaceVertex::GetFaceNext(int face) const {
|
||||
if (isUnOrdered()) {
|
||||
return getConnectedFaceNext(face);
|
||||
} else if (face < (_vDesc._numFaces - 1)) {
|
||||
return face + 1;
|
||||
} else {
|
||||
return isBoundary() ? -1 : 0;
|
||||
}
|
||||
}
|
||||
inline int
|
||||
FaceVertex::GetFacePrevious(int face) const {
|
||||
if (isUnOrdered()) {
|
||||
return getConnectedFacePrev(face);
|
||||
} else if (face) {
|
||||
return face - 1;
|
||||
} else {
|
||||
return isBoundary() ? -1 : (_vDesc._numFaces - 1);
|
||||
}
|
||||
}
|
||||
|
||||
inline int
|
||||
FaceVertex::GetFaceAfter(int step) const {
|
||||
assert(step >= 0);
|
||||
if (isOrdered()) {
|
||||
return (_faceInRing + step) % _vDesc._numFaces;
|
||||
} else if (step == 1) {
|
||||
return getConnectedFaceNext(_faceInRing);
|
||||
} else if (step == 2) {
|
||||
return getConnectedFaceNext(getConnectedFaceNext(_faceInRing));
|
||||
} else {
|
||||
int face = _faceInRing;
|
||||
for ( ; step > 0; --step) {
|
||||
face = getConnectedFaceNext(face);
|
||||
}
|
||||
return face;
|
||||
}
|
||||
}
|
||||
inline int
|
||||
FaceVertex::GetFaceBefore(int step) const {
|
||||
assert(step >= 0);
|
||||
if (isOrdered()) {
|
||||
return (_faceInRing - step + _vDesc._numFaces) % _vDesc._numFaces;
|
||||
} else if (step == 1) {
|
||||
return getConnectedFacePrev(_faceInRing);
|
||||
} else if (step == 2) {
|
||||
return getConnectedFacePrev(getConnectedFacePrev(_faceInRing));
|
||||
} else {
|
||||
int face = _faceInRing;
|
||||
for ( ; step > 0; --step) {
|
||||
face = getConnectedFacePrev(face);
|
||||
}
|
||||
return face;
|
||||
}
|
||||
}
|
||||
|
||||
inline int
|
||||
FaceVertex::GetFaceFirst(Subset const & subset) const {
|
||||
return GetFaceBefore(subset._numFacesBefore);
|
||||
}
|
||||
inline int
|
||||
FaceVertex::GetFaceLast(Subset const & subset) const {
|
||||
return GetFaceAfter(subset._numFacesAfter);
|
||||
}
|
||||
|
||||
//
|
||||
// Inline methods for accessing indices associated with incident faces:
|
||||
//
|
||||
inline int
|
||||
FaceVertex::GetFaceIndexOffset(int face) const {
|
||||
return _commonFaceSize ? (face * _commonFaceSize) :
|
||||
_vDesc._faceSizeOffsets[face];
|
||||
}
|
||||
|
||||
inline FaceVertex::Index
|
||||
FaceVertex::GetFaceIndexAtCorner(Index const indices[]) const {
|
||||
return indices[GetFaceIndexOffset(_faceInRing)];
|
||||
}
|
||||
inline FaceVertex::Index
|
||||
FaceVertex::GetFaceIndexAtCorner(int face, Index const indices[]) const {
|
||||
return indices[GetFaceIndexOffset(face)];
|
||||
}
|
||||
inline FaceVertex::Index
|
||||
FaceVertex::GetFaceIndexLeading(int face, Index const indices[]) const {
|
||||
return indices[GetFaceIndexOffset(face) + 1];
|
||||
}
|
||||
inline FaceVertex::Index
|
||||
FaceVertex::GetFaceIndexTrailing(int face, Index const indices[]) const {
|
||||
// It is safe to use "face+1" here for the last face:
|
||||
return indices[GetFaceIndexOffset(face+1) - 1];
|
||||
}
|
||||
|
||||
inline bool
|
||||
FaceVertex::FaceIndicesMatchAtCorner(int facePrev, int faceNext,
|
||||
Index const indices[]) const {
|
||||
return GetFaceIndexAtCorner(facePrev, indices) ==
|
||||
GetFaceIndexAtCorner(faceNext, indices);
|
||||
}
|
||||
inline bool
|
||||
FaceVertex::FaceIndicesMatchAtEdgeEnd(int facePrev, int faceNext,
|
||||
Index const indices[]) const {
|
||||
return GetFaceIndexTrailing(facePrev, indices) ==
|
||||
GetFaceIndexLeading(faceNext, indices);
|
||||
}
|
||||
inline bool
|
||||
FaceVertex::FaceIndicesMatchAcrossEdge(int facePrev, int faceNext,
|
||||
Index const indices[]) const {
|
||||
return FaceIndicesMatchAtCorner (facePrev, faceNext, indices) &&
|
||||
FaceIndicesMatchAtEdgeEnd(facePrev, faceNext, indices);
|
||||
}
|
||||
|
||||
//
|
||||
// Inline methods for accessing vertex and edge sharpness:
|
||||
//
|
||||
inline float
|
||||
FaceVertex::GetVertexSharpness() const {
|
||||
return _vDesc._vertSharpness;
|
||||
}
|
||||
|
||||
inline float
|
||||
FaceVertex::GetFaceEdgeSharpness(int faceEdge) const {
|
||||
return _vDesc._faceEdgeSharpness[faceEdge];
|
||||
}
|
||||
inline float
|
||||
FaceVertex::GetFaceEdgeSharpness(int face, bool trailing) const {
|
||||
return _vDesc._faceEdgeSharpness[face*2 + trailing];
|
||||
}
|
||||
|
||||
inline bool
|
||||
FaceVertex::IsFaceEdgeSharp(int face, bool trailing) const {
|
||||
return Sdc::Crease::IsSharp(_vDesc._faceEdgeSharpness[face*2+trailing]);
|
||||
}
|
||||
inline bool
|
||||
FaceVertex::IsFaceEdgeInfSharp(int face, bool trailing) const {
|
||||
return Sdc::Crease::IsInfinite(_vDesc._faceEdgeSharpness[face*2+trailing]);
|
||||
}
|
||||
inline bool
|
||||
FaceVertex::IsFaceEdgeSemiSharp(int face, bool trailing) const {
|
||||
return Sdc::Crease::IsSemiSharp(_vDesc._faceEdgeSharpness[face*2+trailing]);
|
||||
}
|
||||
|
||||
} // end namespace Bfr
|
||||
|
||||
} // end namespace OPENSUBDIV_VERSION
|
||||
using namespace OPENSUBDIV_VERSION;
|
||||
} // end namespace OpenSubdiv
|
||||
|
||||
#endif /* OPENSUBDIV3_BFR_FACE_VERTEX_H */
|
||||
Reference in New Issue
Block a user