32 #ifdef WITH_OPENSUBDIV
33 # include <opensubdiv/far/patchTable.h>
38 #ifdef WITH_OPENSUBDIV
44 struct PatchMapQuadNode {
46 void set_child(
int index)
48 for (
int i = 0; i < 4; i++) {
54 void set_child(
unsigned char quadrant,
int index,
bool is_leaf =
true)
63 template<
class T>
static int resolve_quadrant(
T &median,
T &u,
T &
v)
91 OpenSubdiv::Far::PatchTable *patch_table,
96 for (
int array = 0; array < table.
num_arrays; array++) {
97 Far::ConstPatchParamArray
params = patch_table->GetPatchParams(array);
99 for (
int j = 0; j < patch_table->GetNumPatches(array); j++) {
100 num_faces =
max(num_faces, (
int)
params[j].GetFaceId());
105 vector<PatchMapQuadNode> quadtree;
107 quadtree.resize(num_faces);
114 for (
int array = 0; array < table.
num_arrays; array++) {
115 Far::ConstPatchParamArray
params = patch_table->GetPatchParams(array);
117 for (
int i = 0; i < patch_table->GetNumPatches(array);
119 const Far::PatchParam ¶m =
params[i];
120 unsigned short depth = param.GetDepth();
122 PatchMapQuadNode *
node = &quadtree[
params[i].GetFaceId()];
124 if (depth == (param.NonQuadRoot() ? 1 : 0)) {
126 node->set_child(handle_index + offset);
130 int u = param.GetU();
131 int v = param.GetV();
132 int pdepth = param.NonQuadRoot() ? depth - 2 : depth - 1;
133 int half = 1 << pdepth;
135 for (
int j = 0; j < depth; j++) {
136 int delta =
half >> 1;
138 int quadrant = resolve_quadrant(
half, u,
v);
139 assert(quadrant >= 0);
146 node->set_child(quadrant, handle_index + offset,
true);
153 quadtree.push_back(PatchMapQuadNode());
155 int idx = (int)quadtree.size() - 1;
156 node->set_child(quadrant, idx * 4 + offset,
false);
158 node = &quadtree[idx];
163 node = &(quadtree[(idx - offset) / 4]);
179 for (
int i = 0; i < quadtree.size(); i++) {
180 for (
int j = 0; j < 4; j++) {
182 *(
data++) = quadtree[i].children[j];
204 #ifdef WITH_OPENSUBDIV
205 num_arrays = patch_table->GetNumPatchArrays();
207 for (
int i = 0; i < num_arrays; i++) {
208 int patches = patch_table->GetNumPatches(i);
209 int num_control = patch_table->GetPatchArrayDescriptor(i).GetNumControlVertices();
211 num_patches += patches;
212 num_indices += patches * num_control;
215 table.resize(total_size());
220 uint *param = index + num_indices;
223 uint current_param = 0;
225 for (
int i = 0; i < num_arrays; i++) {
226 *(array++) = patch_table->GetPatchArrayDescriptor(i).GetType();
227 *(array++) = patch_table->GetNumPatches(i);
228 *(array++) = (index -
data) + offset;
229 *(array++) = (param -
data) + offset;
231 Far::ConstIndexArray
indices = patch_table->GetPatchArrayVertices(i);
233 for (
int j = 0; j <
indices.size(); j++) {
237 const Far::PatchParamTable ¶m_table = patch_table->GetPatchParamTable();
239 int num_control = patch_table->GetPatchArrayDescriptor(i).GetNumControlVertices();
240 int patches = patch_table->GetNumPatches(i);
242 for (
int j = 0; j < patches; j++, current_param++) {
243 *(param++) = param_table[current_param].field0;
244 *(param++) = param_table[current_param].field1;
248 *(handle++) = j * num_control;
252 build_patch_map(*
this, patch_table, offset);
261 uint *src = table.data();
264 for (
int i = 0; i < num_arrays; i++) {
265 *(dest++) = *(src++);
266 *(dest++) = *(src++);
267 *(dest++) = *(src++) + doffset;
268 *(dest++) = *(src++) + doffset;
272 for (
int i = 0; i < num_indices; i++) {
273 *(dest++) = *(src++);
277 for (
int i = 0; i < num_patches; i++) {
278 *(dest++) = *(src++);
279 *(dest++) = *(src++);
283 for (
int i = 0; i < num_patches; i++) {
284 *(dest++) = *(src++) + doffset;
285 *(dest++) = *(src++) + doffset;
286 *(dest++) = *(src++);
290 for (
int i = 0; i < num_nodes; i++) {
291 *(dest++) = *(src++) + doffset;
ATTR_WARN_UNUSED_RESULT const BMVert * v
T * resize(size_t newsize)
#define CCL_NAMESPACE_END
#define PATCH_MAP_NODE_IS_SET
#define PATCH_MAP_NODE_IS_LEAF
#define PATCH_MAP_NODE_INDEX_MASK
void pack(Far::PatchTable *patch_table, int offset=0)
void copy_adjusting_offsets(uint *dest, int doffset)
#define PATCH_HANDLE_SIZE