diff options
Diffstat (limited to 'intern/cycles/subd/subd_patch_table.cpp')
-rw-r--r-- | intern/cycles/subd/subd_patch_table.cpp | 424 |
1 files changed, 212 insertions, 212 deletions
diff --git a/intern/cycles/subd/subd_patch_table.cpp b/intern/cycles/subd/subd_patch_table.cpp index f9671ee144d..4e873375725 100644 --- a/intern/cycles/subd/subd_patch_table.cpp +++ b/intern/cycles/subd/subd_patch_table.cpp @@ -30,7 +30,7 @@ #include "util/util_math.h" #ifdef WITH_OPENSUBDIV -#include <opensubdiv/far/patchTable.h> +# include <opensubdiv/far/patchTable.h> #endif CCL_NAMESPACE_BEGIN @@ -42,144 +42,146 @@ using namespace OpenSubdiv; /* functions for building patch maps */ struct PatchMapQuadNode { - /* sets all the children to point to the patch of index */ - void set_child(int index) - { - for(int i = 0; i < 4; i++) { - children[i] = index | PATCH_MAP_NODE_IS_SET | PATCH_MAP_NODE_IS_LEAF; - } - } - - /* sets the child in quadrant to point to the node or patch of the given index */ - void set_child(unsigned char quadrant, int index, bool is_leaf=true) - { - assert(quadrant < 4); - children[quadrant] = index | PATCH_MAP_NODE_IS_SET | (is_leaf ? PATCH_MAP_NODE_IS_LEAF : 0); - } - - uint children[4]; + /* sets all the children to point to the patch of index */ + void set_child(int index) + { + for (int i = 0; i < 4; i++) { + children[i] = index | PATCH_MAP_NODE_IS_SET | PATCH_MAP_NODE_IS_LEAF; + } + } + + /* sets the child in quadrant to point to the node or patch of the given index */ + void set_child(unsigned char quadrant, int index, bool is_leaf = true) + { + assert(quadrant < 4); + children[quadrant] = index | PATCH_MAP_NODE_IS_SET | (is_leaf ? PATCH_MAP_NODE_IS_LEAF : 0); + } + + uint children[4]; }; -template<class T> -static int resolve_quadrant(T& median, T& u, T& v) +template<class T> static int resolve_quadrant(T &median, T &u, T &v) { - int quadrant = -1; - - if(u < median) { - if(v < median) { - quadrant = 0; - } - else { - quadrant = 1; - v -= median; - } - } - else { - if(v < median) { - quadrant = 3; - } - else { - quadrant = 2; - v -= median; - } - u -= median; - } - - return quadrant; + int quadrant = -1; + + if (u < median) { + if (v < median) { + quadrant = 0; + } + else { + quadrant = 1; + v -= median; + } + } + else { + if (v < median) { + quadrant = 3; + } + else { + quadrant = 2; + v -= median; + } + u -= median; + } + + return quadrant; } -static void build_patch_map(PackedPatchTable& table, OpenSubdiv::Far::PatchTable* patch_table, int offset) +static void build_patch_map(PackedPatchTable &table, + OpenSubdiv::Far::PatchTable *patch_table, + int offset) { - int num_faces = 0; - - for(int array = 0; array < table.num_arrays; array++) { - Far::ConstPatchParamArray params = patch_table->GetPatchParams(array); - - for(int j = 0; j < patch_table->GetNumPatches(array); j++) { - num_faces = max(num_faces, (int)params[j].GetFaceId()); - } - } - num_faces++; - - vector<PatchMapQuadNode> quadtree; - quadtree.reserve(num_faces + table.num_patches); - quadtree.resize(num_faces); - - /* adjust offsets to make indices relative to the table */ - int handle_index = -(table.num_patches * PATCH_HANDLE_SIZE); - offset += table.total_size(); - - /* populate the quadtree from the FarPatchArrays sub-patches */ - for(int array = 0; array < table.num_arrays; array++) { - Far::ConstPatchParamArray params = patch_table->GetPatchParams(array); - - for(int i = 0; i < patch_table->GetNumPatches(array); i++, handle_index += PATCH_HANDLE_SIZE) { - const Far::PatchParam& param = params[i]; - unsigned short depth = param.GetDepth(); - - PatchMapQuadNode* node = &quadtree[params[i].GetFaceId()]; - - if(depth == (param.NonQuadRoot() ? 1 : 0)) { - /* special case : regular BSpline face w/ no sub-patches */ - node->set_child(handle_index + offset); - continue; - } - - int u = param.GetU(); - int v = param.GetV(); - int pdepth = param.NonQuadRoot() ? depth-2 : depth-1; - int half = 1 << pdepth; - - for(int j = 0; j < depth; j++) { - int delta = half >> 1; - - int quadrant = resolve_quadrant(half, u, v); - assert(quadrant >= 0); - - half = delta; - - if(j == pdepth) { - /* we have reached the depth of the sub-patch : add a leaf */ - assert(!(node->children[quadrant] & PATCH_MAP_NODE_IS_SET)); - node->set_child(quadrant, handle_index + offset, true); - break; - } - else { - /* travel down the child node of the corresponding quadrant */ - if(!(node->children[quadrant] & PATCH_MAP_NODE_IS_SET)) { - /* create a new branch in the quadrant */ - quadtree.push_back(PatchMapQuadNode()); - - int idx = (int)quadtree.size() - 1; - node->set_child(quadrant, idx*4 + offset, false); - - node = &quadtree[idx]; - } - else { - /* travel down an existing branch */ - uint idx = node->children[quadrant] & PATCH_MAP_NODE_INDEX_MASK; - node = &(quadtree[(idx - offset)/4]); - } - } - } - } - } - - /* copy into table */ - assert(table.table.size() == table.total_size()); - uint map_offset = table.total_size(); - - table.num_nodes = quadtree.size() * 4; - table.table.resize(table.total_size()); - - uint* data = &table.table[map_offset]; - - for(int i = 0; i < quadtree.size(); i++) { - for(int j = 0; j < 4; j++) { - assert(quadtree[i].children[j] & PATCH_MAP_NODE_IS_SET); - *(data++) = quadtree[i].children[j]; - } - } + int num_faces = 0; + + for (int array = 0; array < table.num_arrays; array++) { + Far::ConstPatchParamArray params = patch_table->GetPatchParams(array); + + for (int j = 0; j < patch_table->GetNumPatches(array); j++) { + num_faces = max(num_faces, (int)params[j].GetFaceId()); + } + } + num_faces++; + + vector<PatchMapQuadNode> quadtree; + quadtree.reserve(num_faces + table.num_patches); + quadtree.resize(num_faces); + + /* adjust offsets to make indices relative to the table */ + int handle_index = -(table.num_patches * PATCH_HANDLE_SIZE); + offset += table.total_size(); + + /* populate the quadtree from the FarPatchArrays sub-patches */ + for (int array = 0; array < table.num_arrays; array++) { + Far::ConstPatchParamArray params = patch_table->GetPatchParams(array); + + for (int i = 0; i < patch_table->GetNumPatches(array); + i++, handle_index += PATCH_HANDLE_SIZE) { + const Far::PatchParam ¶m = params[i]; + unsigned short depth = param.GetDepth(); + + PatchMapQuadNode *node = &quadtree[params[i].GetFaceId()]; + + if (depth == (param.NonQuadRoot() ? 1 : 0)) { + /* special case : regular BSpline face w/ no sub-patches */ + node->set_child(handle_index + offset); + continue; + } + + int u = param.GetU(); + int v = param.GetV(); + int pdepth = param.NonQuadRoot() ? depth - 2 : depth - 1; + int half = 1 << pdepth; + + for (int j = 0; j < depth; j++) { + int delta = half >> 1; + + int quadrant = resolve_quadrant(half, u, v); + assert(quadrant >= 0); + + half = delta; + + if (j == pdepth) { + /* we have reached the depth of the sub-patch : add a leaf */ + assert(!(node->children[quadrant] & PATCH_MAP_NODE_IS_SET)); + node->set_child(quadrant, handle_index + offset, true); + break; + } + else { + /* travel down the child node of the corresponding quadrant */ + if (!(node->children[quadrant] & PATCH_MAP_NODE_IS_SET)) { + /* create a new branch in the quadrant */ + quadtree.push_back(PatchMapQuadNode()); + + int idx = (int)quadtree.size() - 1; + node->set_child(quadrant, idx * 4 + offset, false); + + node = &quadtree[idx]; + } + else { + /* travel down an existing branch */ + uint idx = node->children[quadrant] & PATCH_MAP_NODE_INDEX_MASK; + node = &(quadtree[(idx - offset) / 4]); + } + } + } + } + } + + /* copy into table */ + assert(table.table.size() == table.total_size()); + uint map_offset = table.total_size(); + + table.num_nodes = quadtree.size() * 4; + table.table.resize(table.total_size()); + + uint *data = &table.table[map_offset]; + + for (int i = 0; i < quadtree.size(); i++) { + for (int j = 0; j < 4; j++) { + assert(quadtree[i].children[j] & PATCH_MAP_NODE_IS_SET); + *(data++) = quadtree[i].children[j]; + } + } } #endif @@ -188,108 +190,106 @@ static void build_patch_map(PackedPatchTable& table, OpenSubdiv::Far::PatchTable size_t PackedPatchTable::total_size() { - return num_arrays * PATCH_ARRAY_SIZE + - num_indices + - num_patches * (PATCH_PARAM_SIZE + PATCH_HANDLE_SIZE) + - num_nodes * PATCH_NODE_SIZE; + return num_arrays * PATCH_ARRAY_SIZE + num_indices + + num_patches * (PATCH_PARAM_SIZE + PATCH_HANDLE_SIZE) + num_nodes * PATCH_NODE_SIZE; } -void PackedPatchTable::pack(Far::PatchTable* patch_table, int offset) +void PackedPatchTable::pack(Far::PatchTable *patch_table, int offset) { - num_arrays = 0; - num_patches = 0; - num_indices = 0; - num_nodes = 0; + num_arrays = 0; + num_patches = 0; + num_indices = 0; + num_nodes = 0; #ifdef WITH_OPENSUBDIV - num_arrays = patch_table->GetNumPatchArrays(); + num_arrays = patch_table->GetNumPatchArrays(); - for(int i = 0; i < num_arrays; i++) { - int patches = patch_table->GetNumPatches(i); - int num_control = patch_table->GetPatchArrayDescriptor(i).GetNumControlVertices(); + for (int i = 0; i < num_arrays; i++) { + int patches = patch_table->GetNumPatches(i); + int num_control = patch_table->GetPatchArrayDescriptor(i).GetNumControlVertices(); - num_patches += patches; - num_indices += patches * num_control; - } + num_patches += patches; + num_indices += patches * num_control; + } - table.resize(total_size()); - uint* data = table.data(); + table.resize(total_size()); + uint *data = table.data(); - uint* array = data; - uint* index = array + num_arrays * PATCH_ARRAY_SIZE; - uint* param = index + num_indices; - uint* handle = param + num_patches * PATCH_PARAM_SIZE; + uint *array = data; + uint *index = array + num_arrays * PATCH_ARRAY_SIZE; + uint *param = index + num_indices; + uint *handle = param + num_patches * PATCH_PARAM_SIZE; - uint current_param = 0; + uint current_param = 0; - for(int i = 0; i < num_arrays; i++) { - *(array++) = patch_table->GetPatchArrayDescriptor(i).GetType(); - *(array++) = patch_table->GetNumPatches(i); - *(array++) = (index - data) + offset; - *(array++) = (param - data) + offset; + for (int i = 0; i < num_arrays; i++) { + *(array++) = patch_table->GetPatchArrayDescriptor(i).GetType(); + *(array++) = patch_table->GetNumPatches(i); + *(array++) = (index - data) + offset; + *(array++) = (param - data) + offset; - Far::ConstIndexArray indices = patch_table->GetPatchArrayVertices(i); + Far::ConstIndexArray indices = patch_table->GetPatchArrayVertices(i); - for(int j = 0; j < indices.size(); j++) { - *(index++) = indices[j]; - } + for (int j = 0; j < indices.size(); j++) { + *(index++) = indices[j]; + } - const Far::PatchParamTable& param_table = patch_table->GetPatchParamTable(); + const Far::PatchParamTable ¶m_table = patch_table->GetPatchParamTable(); - int num_control = patch_table->GetPatchArrayDescriptor(i).GetNumControlVertices(); - int patches = patch_table->GetNumPatches(i); + int num_control = patch_table->GetPatchArrayDescriptor(i).GetNumControlVertices(); + int patches = patch_table->GetNumPatches(i); - for(int j = 0; j < patches; j++, current_param++) { - *(param++) = param_table[current_param].field0; - *(param++) = param_table[current_param].field1; + for (int j = 0; j < patches; j++, current_param++) { + *(param++) = param_table[current_param].field0; + *(param++) = param_table[current_param].field1; - *(handle++) = (array - data) - PATCH_ARRAY_SIZE + offset; - *(handle++) = (param - data) - PATCH_PARAM_SIZE + offset; - *(handle++) = j * num_control; - } - } + *(handle++) = (array - data) - PATCH_ARRAY_SIZE + offset; + *(handle++) = (param - data) - PATCH_PARAM_SIZE + offset; + *(handle++) = j * num_control; + } + } - build_patch_map(*this, patch_table, offset); + build_patch_map(*this, patch_table, offset); #else - (void) patch_table; - (void) offset; + (void)patch_table; + (void)offset; #endif } -void PackedPatchTable::copy_adjusting_offsets(uint* dest, int doffset) +void PackedPatchTable::copy_adjusting_offsets(uint *dest, int doffset) { - uint* src = table.data(); - - /* arrays */ - for(int i = 0; i < num_arrays; i++) { - *(dest++) = *(src++); - *(dest++) = *(src++); - *(dest++) = *(src++) + doffset; - *(dest++) = *(src++) + doffset; - } - - /* indices */ - for(int i = 0; i < num_indices; i++) { - *(dest++) = *(src++); - } - - /* params */ - for(int i = 0; i < num_patches; i++) { - *(dest++) = *(src++); - *(dest++) = *(src++); - } - - /* handles */ - for(int i = 0; i < num_patches; i++) { - *(dest++) = *(src++) + doffset; - *(dest++) = *(src++) + doffset; - *(dest++) = *(src++); - } - - /* nodes */ - for(int i = 0; i < num_nodes; i++) { - *(dest++) = *(src++) + doffset; - } + uint *src = table.data(); + + /* arrays */ + for (int i = 0; i < num_arrays; i++) { + *(dest++) = *(src++); + *(dest++) = *(src++); + *(dest++) = *(src++) + doffset; + *(dest++) = *(src++) + doffset; + } + + /* indices */ + for (int i = 0; i < num_indices; i++) { + *(dest++) = *(src++); + } + + /* params */ + for (int i = 0; i < num_patches; i++) { + *(dest++) = *(src++); + *(dest++) = *(src++); + } + + /* handles */ + for (int i = 0; i < num_patches; i++) { + *(dest++) = *(src++) + doffset; + *(dest++) = *(src++) + doffset; + *(dest++) = *(src++); + } + + /* nodes */ + for (int i = 0; i < num_nodes; i++) { + *(dest++) = *(src++) + doffset; + } } CCL_NAMESPACE_END |