11using OpenSubdiv::Far::ConstPatchParamArray;
12using OpenSubdiv::Far::Index;
13using OpenSubdiv::Far::PatchParam;
14using OpenSubdiv::Far::PatchParamTable;
15using OpenSubdiv::Far::PatchTable;
27 for (
int i = 0;
i < 4; ++
i) {
44inline void PatchMap::assignRootNode(
QuadNode *node,
int index)
61 node->SetChild(quadrant, index,
true);
64 if (node->children[quadrant].isSet) {
65 return &_quadtree[node->children[quadrant].index];
68 int newChildNodeIndex = (int)_quadtree.size();
69 _quadtree.emplace_back();
70 node->SetChild(quadrant, newChildNodeIndex,
false);
71 return &_quadtree[newChildNodeIndex];
78 : _minPatchFace(-1), _maxPatchFace(-1), _maxDepth(0)
81 _patchesAreTriangular = patchTable.GetVaryingPatchDescriptor().GetNumControlVertices() == 3;
83 if (patchTable.GetNumPatchesTotal() > 0) {
84 initializeHandles(patchTable);
85 initializeQuadtree(patchTable);
89void PatchMap::initializeHandles(PatchTable
const &patchTable)
96 _minPatchFace = (int)patchTable.GetPatchParamTable()[0].GetFaceId();
97 _maxPatchFace = _minPatchFace;
99 int numArrays = patchTable.GetNumPatchArrays();
100 int numPatches = patchTable.GetNumPatchesTotal();
102 _handles.resize(numPatches);
104 for (
int pArray = 0, handleIndex = 0; pArray < numArrays; ++pArray) {
106 ConstPatchParamArray
params = patchTable.GetPatchParams(pArray);
108 int patchSize = patchTable.GetPatchArrayDescriptor(pArray).GetNumControlVertices();
110 for (Index j = 0; j < patchTable.GetNumPatches(pArray); ++j, ++handleIndex) {
112 Handle &h = _handles[handleIndex];
114 h.arrayIndex = pArray;
115 h.patchIndex = handleIndex;
116 h.vertIndex = j * patchSize;
118 int patchFaceId =
params[j].GetFaceId();
119 _minPatchFace = std::min(_minPatchFace, patchFaceId);
120 _maxPatchFace = std::max(_maxPatchFace, patchFaceId);
125void PatchMap::initializeQuadtree(PatchTable
const &patchTable)
132 int nPatchFaces = (_maxPatchFace - _minPatchFace) + 1;
134 int nHandles = int(_handles.size());
136 _quadtree.reserve(nPatchFaces + nHandles);
137 _quadtree.resize(nPatchFaces);
139 PatchParamTable
const &
params = patchTable.GetPatchParamTable();
141 for (
int handle = 0; handle < nHandles; ++handle) {
143 PatchParam
const ¶m =
params[handle];
145 int depth = param.GetDepth();
146 int rootDepth = param.NonQuadRoot();
148 _maxDepth = std::max(_maxDepth, depth);
150 QuadNode *node = &_quadtree[param.GetFaceId() - _minPatchFace];
152 if (depth == rootDepth) {
153 assignRootNode(node, handle);
157 if (!_patchesAreTriangular) {
159 int u = param.GetU();
160 int v = param.GetV();
162 for (
int j = rootDepth + 1; j <= depth; ++j) {
163 int uBit = (u >> (depth - j)) & 1;
164 int vBit = (
v >> (depth - j)) & 1;
166 int quadrant = (vBit << 1) | uBit;
168 node = assignLeafOrChildNode(node, (j == depth), quadrant, handle);
175 param.UnnormalizeTriangle(u,
v);
178 bool triRotated =
false;
180 for (
int j = rootDepth + 1; j <= depth; ++j, median *= 0.5) {
181 int quadrant = transformUVToTriQuadrant(median, u,
v, triRotated);
183 node = assignLeafOrChildNode(node, (j == depth), quadrant, handle);
189 QuadTree tmpTree = _quadtree;
190 _quadtree.swap(tmpTree);
ATTR_WARN_UNUSED_RESULT const BMVert * v
OpenSubdiv::Far::PatchTable::PatchHandle Handle
PatchMap(OpenSubdiv::Far::PatchTable const &patchTable)
Constructor.
#define assert(assertion)
void SetChildren(int index)
void SetChild(int quadrant, int index, bool isLeaf)