mirror of
https://github.com/PixarAnimationStudios/OpenSubdiv
synced 2024-11-15 08:20:08 +00:00
Add a function to Far::TopologyRefiner to gather ptex adjacency for a given face / quadrant pair
- also refactor Vtr::Array 'FindIndex' functions
This commit is contained in:
parent
19ed202965
commit
aacd43a09b
@ -110,7 +110,9 @@ TopologyRefiner::GetNumFVarValuesTotal(int channel) const {
|
||||
return sum;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Ptex information accessors
|
||||
//
|
||||
template <Sdc::Type SCHEME_TYPE> void
|
||||
computePtexIndices(Vtr::Level const & coarseLevel, std::vector<int> & ptexIndices) {
|
||||
int nfaces = coarseLevel.getNumFaces();
|
||||
@ -149,10 +151,135 @@ TopologyRefiner::GetPtexIndex(Index f) const {
|
||||
if (_ptexIndices.empty()) {
|
||||
initializePtexIndices();
|
||||
}
|
||||
if (f<((int)_ptexIndices.size()-1)) {
|
||||
assert(f<(int)_ptexIndices.size());
|
||||
return _ptexIndices[f];
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
// Returns the face adjacent to 'face' along edge 'edge'
|
||||
inline Index
|
||||
getAdjacentFace(Vtr::Level const & level, Index edge, Index face) {
|
||||
IndexArray adjFaces = level.getEdgeFaces(edge);
|
||||
if (adjFaces.size()!=2) {
|
||||
return -1;
|
||||
}
|
||||
return (adjFaces[0]==face) ? adjFaces[1] : adjFaces[0];
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TopologyRefiner::GetPtexAdjacency(int face, int quadrant,
|
||||
int adjFaces[4], int adjEdges[4]) const {
|
||||
|
||||
assert(GetSchemeType()==Sdc::TYPE_CATMARK);
|
||||
|
||||
if (_ptexIndices.empty()) {
|
||||
initializePtexIndices();
|
||||
}
|
||||
|
||||
Vtr::Level const & level = _levels[0];
|
||||
|
||||
IndexArray fedges = level.getFaceEdges(face);
|
||||
|
||||
if (fedges.size()==4) {
|
||||
|
||||
// Regular ptex quad face
|
||||
for (int i=0; i<4; ++i) {
|
||||
int edge = fedges[i];
|
||||
IndexArray efaces = level.getEdgeFaces(edge);
|
||||
Index adjface = getAdjacentFace(level, edge, face);
|
||||
if (adjface==-1) {
|
||||
adjFaces[i] = -1; // boundary or non-manifold
|
||||
adjEdges[i] = 0;
|
||||
} else {
|
||||
|
||||
IndexArray aedges = level.getFaceEdges(adjface);
|
||||
if (aedges.size()==4) {
|
||||
adjFaces[i] = _ptexIndices[adjface];
|
||||
adjEdges[i] = aedges.FindIndexIn4Tuple(edge);
|
||||
assert(adjEdges[i]!=-1);
|
||||
} else {
|
||||
// neighbor is a sub-face
|
||||
adjFaces[i] = _ptexIndices[adjface] +
|
||||
(aedges.FindIndex(edge)+1)%aedges.size();
|
||||
adjEdges[i] = 3;
|
||||
}
|
||||
assert(adjFaces[i]!=-1);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
// Ptex sub-face 'quadrant' (non-quad)
|
||||
//
|
||||
// Ptex adjacency pattern for non-quads:
|
||||
//
|
||||
// v2
|
||||
/* o
|
||||
// / \
|
||||
// / \
|
||||
// /0 3\
|
||||
// / \
|
||||
// o_ 1 2 _o
|
||||
// / -_ _- \
|
||||
// / 2 -o- 1 \
|
||||
// /3 | 0\
|
||||
// / 1|2 \
|
||||
// / 0 | 3 \
|
||||
// o----------o----------o
|
||||
// v0 v1
|
||||
*/
|
||||
assert(quadrant>=0 and quadrant<fedges.size());
|
||||
|
||||
int nextQuadrant = (quadrant+1) % fedges.size(),
|
||||
prevQuadrant = (quadrant+fedges.size()-1) % fedges.size();
|
||||
|
||||
{ // resolve neighbors within the sub-face (edges 1 & 2)
|
||||
adjFaces[1] = _ptexIndices[face] + nextQuadrant;
|
||||
adjEdges[1] = 2;
|
||||
|
||||
adjFaces[2] = _ptexIndices[face] + prevQuadrant;
|
||||
adjEdges[2] = 1;
|
||||
}
|
||||
|
||||
{ // resolve neighbor outisde the sub-face (edge 0)
|
||||
int edge0 = fedges[quadrant];
|
||||
Index adjface0 = getAdjacentFace(level, edge0, face);
|
||||
if (adjface0==-1) {
|
||||
adjFaces[0] = -1; // boundary or non-manifold
|
||||
adjEdges[0] = 0;
|
||||
} else {
|
||||
IndexArray afedges = level.getFaceEdges(adjface0);
|
||||
if (afedges.size()==4) {
|
||||
adjFaces[0] = _ptexIndices[adjface0];
|
||||
adjEdges[0] = afedges.FindIndexIn4Tuple(edge0);
|
||||
} else {
|
||||
int subedge = (afedges.FindIndex(edge0)+1)%afedges.size();
|
||||
adjFaces[0] = _ptexIndices[adjface0] + subedge;
|
||||
adjEdges[0] = 3;
|
||||
}
|
||||
assert(adjFaces[0]!=-1);
|
||||
}
|
||||
|
||||
// resolve neighbor outisde the sub-face (edge 3)
|
||||
int edge3 = fedges[prevQuadrant];
|
||||
Index adjface3 = getAdjacentFace(level, edge3, face);
|
||||
if (adjface3==-1) {
|
||||
adjFaces[3]=-1; // boundary or non-manifold
|
||||
adjEdges[3]=0;
|
||||
} else {
|
||||
IndexArray afedges = level.getFaceEdges(adjface3);
|
||||
if (afedges.size()==4) {
|
||||
adjFaces[3] = _ptexIndices[adjface3];
|
||||
adjEdges[3] = afedges.FindIndexIn4Tuple(edge3);
|
||||
} else {
|
||||
int subedge = afedges.FindIndex(edge3);
|
||||
adjFaces[3] = _ptexIndices[adjface3] + subedge;
|
||||
adjEdges[3] = 0;
|
||||
}
|
||||
assert(adjFaces[3]!=-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -377,6 +377,20 @@ public:
|
||||
/// \brief Returns the ptex face index given a coarse face 'f' or -1
|
||||
int GetPtexIndex(Index f) const;
|
||||
|
||||
/// \brief Returns ptex face adjacency information for a given coarse face
|
||||
///
|
||||
/// @param face coarse face index
|
||||
///
|
||||
/// @param quadrant quadrant index if 'face' is not a quad (the local ptex
|
||||
// sub-face index). Must be less than the number of face
|
||||
// vertices.
|
||||
///
|
||||
/// @param adjFaces ptex face indices of adjacent faces
|
||||
///
|
||||
/// @param adjFaces ptex edge indices of adjacent faces
|
||||
///
|
||||
void GetPtexAdjacency(int face, int quadrant,
|
||||
int adjFaces[4], int adjEdges[4]) const;
|
||||
|
||||
//
|
||||
// Debugging aides:
|
||||
@ -474,7 +488,7 @@ private:
|
||||
void initializePtexIndices() const;
|
||||
|
||||
private:
|
||||
// The following should be private but leaving it open while still early...
|
||||
|
||||
Sdc::Type _subdivType;
|
||||
Sdc::Options _subdivOptions;
|
||||
|
||||
|
@ -26,6 +26,8 @@
|
||||
|
||||
#include "../version.h"
|
||||
|
||||
#include <cassert>
|
||||
|
||||
namespace OpenSubdiv {
|
||||
namespace OPENSUBDIV_VERSION {
|
||||
|
||||
@ -78,6 +80,25 @@ public:
|
||||
iterator begin() { return _begin; }
|
||||
iterator end() { return _begin + _size; }
|
||||
|
||||
size_type FindIndexIn4Tuple(value_type value) const {
|
||||
assert(_size>=4);
|
||||
if (value == _begin[0]) return 0;
|
||||
if (value == _begin[1]) return 1;
|
||||
if (value == _begin[2]) return 2;
|
||||
if (value == _begin[3]) return 3;
|
||||
assert("FindIndexIn4Tuple() did not find expected value!" == 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
size_type FindIndex(value_type value) const {
|
||||
for (size_type i=0; i<size(); ++i) {
|
||||
if (value==_begin[i]) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
protected:
|
||||
value_type* _begin;
|
||||
size_type _size;
|
||||
|
@ -480,17 +480,6 @@ Level::getFaceCompositeVTag(IndexArray const& faceVerts) const {
|
||||
namespace {
|
||||
template <typename INT_TYPE>
|
||||
inline INT_TYPE fastMod4(INT_TYPE value) { return (value & 0x3); }
|
||||
|
||||
inline int
|
||||
fastFindIn4(Index value, IndexArray const& array) {
|
||||
|
||||
if (value == array[0]) return 0;
|
||||
if (value == array[1]) return 1;
|
||||
if (value == array[2]) return 2;
|
||||
if (value == array[3]) return 3;
|
||||
assert("fastFindIn4() did not find expected value!" == 0);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
@ -592,7 +581,7 @@ Level::gatherQuadRegularInteriorPatchVertices(
|
||||
IndexArray vFaces = level.getVertexFaces(v);
|
||||
LocalIndexArray vInFaces = level.getVertexFaceLocalIndices(v);
|
||||
|
||||
int thisFaceInVFaces = fastFindIn4(thisFace, vFaces);
|
||||
int thisFaceInVFaces = vFaces.FindIndexIn4Tuple(thisFace);
|
||||
int intFaceInVFaces = fastMod4(thisFaceInVFaces + 2);
|
||||
|
||||
Index intFace = vFaces[intFaceInVFaces];
|
||||
|
Loading…
Reference in New Issue
Block a user