25 #ifndef FAR_PATCH_MAP_H
26 #define FAR_PATCH_MAP_H
28 #include "../version.h"
30 #include "../far/patchTables.h"
34 namespace OpenSubdiv {
35 namespace OPENSUBDIV_VERSION {
81 inline void initialize(
PatchTables const & patchTables );
92 void SetChild(
int patchIdx);
95 void SetChild(
unsigned char quadrant,
int child,
bool isLeaf=
true);
100 typedef std::vector<QuadNode> QuadTree;
103 static QuadNode * addChild( QuadTree & quadtree, QuadNode * parent,
int quadrant );
120 template <
class T>
static int resolveQuadrant(T & median, T & u, T & v);
122 std::vector<Handle> _handles;
123 std::vector<QuadNode> _quadtree;
129 initialize( patchTables );
134 PatchMap::QuadNode::SetChild(
int patchIdx) {
135 for (
int i=0; i<4; ++i) {
136 children[i].isSet=
true;
137 children[i].isLeaf=
true;
138 children[i].idx=patchIdx;
144 PatchMap::QuadNode::SetChild(
unsigned char quadrant,
int idx,
bool isLeaf) {
146 children[quadrant].isSet =
true;
147 children[quadrant].isLeaf = isLeaf;
148 children[quadrant].idx = idx;
152 inline PatchMap::QuadNode *
153 PatchMap::addChild( QuadTree & quadtree, QuadNode * parent,
int quadrant ) {
154 quadtree.push_back(QuadNode());
155 int idx = (int)quadtree.size()-1;
156 parent->SetChild(quadrant, idx,
false);
157 return &(quadtree[idx]);
162 template <
class T>
int
163 PatchMap::resolveQuadrant(T & median, T & u, T & v) {
186 inline PatchMap::Handle
const *
189 if (faceid>=(
int)_quadtree.size())
192 assert( (u>=0.0f) and (u<=1.0f) and (v>=0.0f) and (v<=1.0f) );
194 QuadNode
const * node = &_quadtree[faceid];
199 for (
int depth=0; depth<0xFF; ++depth) {
201 float delta = half * 0.5f;
203 int quadrant = resolveQuadrant( half, u, v );
207 if (not node->children[quadrant].isSet)
210 if (node->children[quadrant].isLeaf) {
211 return &_handles[node->children[quadrant].idx];
213 node = &_quadtree[node->children[quadrant].idx];
225 PatchMap::initialize(
PatchTables const & patchTables ) {
239 _handles.resize(npatches);
240 for (
int arrayIdx=0, current=0; arrayIdx<(int)patchArrays.size(); ++arrayIdx) {
250 Handle & h = _handles[current];
252 h.patchArrayIdx = arrayIdx;
253 h.patchIdx = (
unsigned int)current;
254 h.vertexOffset = j * ringsize;
256 nfaces = std::max(nfaces, (
int)param.
faceIndex);
264 std::vector<QuadNode> quadtree;
267 quadtree.reserve( nfaces + npatches );
270 quadtree.resize(nfaces);
273 for (
int i=0, handleIdx=0; i<(int)patchArrays.size(); ++i) {
275 PatchTables::PatchArray
const & parray = patchArrays[i];
277 for (
unsigned int j=0; j < parray.GetNumPatches(); ++j, ++handleIdx) {
279 PatchParam
const & param = paramTable[parray.GetPatchIndex()+j];
281 PatchParam::BitField bits = param.
bitField;
283 unsigned char depth = bits.
GetDepth();
285 QuadNode * node = &quadtree[ param.faceIndex ];
287 if (depth==(bits.NonQuadRoot() ? 1 : 0)) {
289 node->SetChild( handleIdx );
295 pdepth = bits.NonQuadRoot() ? depth-2 : depth-1,
298 for (
unsigned char k=0; k<depth; ++k) {
300 int delta = half >> 1;
302 int quadrant = resolveQuadrant(half, u, v);
309 assert( not node->children[quadrant].isSet );
310 node->SetChild(quadrant, handleIdx,
true);
314 if (not node->children[quadrant].isSet) {
316 node = addChild(quadtree, node, quadrant);
319 node = &(quadtree[ node->children[quadrant].idx ]);
327 _quadtree = quadtree;
333 using namespace OPENSUBDIV_VERSION;
unsigned char GetDepth() const
Returns the level of subdivision of the patch.
Container for patch vertex indices tables.
std::vector< PatchParam > PatchParamTable
PatchParamTable const & GetPatchParamTable() const
Returns a PatchParamTable for each type of patch.
Handle that can be used as unique patch identifier within PatchTables.
unsigned int patchArrayIdx
int GetNumPatches() const
Returns the total number of patches stored in the tables.
static short GetNumControlVertices(Type t)
Returns the number of control vertices expected for a patch of the type described.
Handle const * FindPatch(int faceid, float u, float v) const
Returns a handle to the sub-patch of the face at the given (u,v). Note : the faceid corresponds to qu...
Local patch parameterization descriptor.
PatchMap(PatchTables const &patchTables)
Constructor.
unsigned int vertexOffset
Descriptor GetDescriptor() const
Returns a patch descriptor defining the type of patches in the array.
unsigned int GetPatchIndex() const
Returns the global index of the first patch in this array (Used to access param / fvar table data) ...
unsigned int GetNumPatches() const
Returns the number of patches in the array.
An quadtree-based map connecting coarse faces to their sub-patches.
PatchArrayVector const & GetPatchArrayVector() const
Returns all arrays of patches.
Describes an array of patches of the same type.
std::vector< PatchArray > PatchArrayVector
struct OpenSubdiv::OPENSUBDIV_VERSION::Far::PatchParam::BitField bitField