diff options
author | Sergey Sharybin <sergey.vfx@gmail.com> | 2016-07-22 15:46:13 +0300 |
---|---|---|
committer | Sergey Sharybin <sergey.vfx@gmail.com> | 2016-07-22 15:56:15 +0300 |
commit | 48c4b700dce0b326e1b905e133c0db1217a5cae0 (patch) | |
tree | d520f9d02eeaa7deb7774ed4dca84bdedd0d7914 /intern/opensubdiv/opensubdiv_capi.cc | |
parent | 98970f71fe95e6b842582f5b71f3081798a8f54a (diff) |
OpenSubdiv: Lay down fundamentals to support multiple UV maps
Diffstat (limited to 'intern/opensubdiv/opensubdiv_capi.cc')
-rw-r--r-- | intern/opensubdiv/opensubdiv_capi.cc | 78 |
1 files changed, 41 insertions, 37 deletions
diff --git a/intern/opensubdiv/opensubdiv_capi.cc b/intern/opensubdiv/opensubdiv_capi.cc index 9093fd87a44..ab904953c70 100644 --- a/intern/opensubdiv/opensubdiv_capi.cc +++ b/intern/opensubdiv/opensubdiv_capi.cc @@ -160,45 +160,49 @@ struct FVarVertex { static void interpolate_fvar_data(OpenSubdiv::Far::TopologyRefiner& refiner, const std::vector<float> uvs, std::vector<float> &fvar_data) { - /* TODO(sergey): Support all FVar channels. */ - const int channel = 0; /* TODO(sergey): Make it somehow more generic way. */ const int fvar_width = 2; - const int num_uvs = refiner.GetLevel(0).GetNumFVarValues(0) * 2; - int max_level = refiner.GetMaxLevel(), - num_values_max = refiner.GetLevel(max_level).GetNumFVarValues(channel), - num_values_total = refiner.GetNumFVarValuesTotal(channel); - if (num_values_total <= 0) { - return; - } - OpenSubdiv::Far::PrimvarRefiner primvar_refiner(refiner); - if (refiner.IsUniform()) { - /* For uniform we only keep the highest level of refinement. */ - fvar_data.resize(num_values_max * fvar_width); - std::vector<FVarVertex> buffer(num_values_total - num_values_max); - FVarVertex *src = &buffer[0]; - memcpy(src, &uvs[0], num_uvs * sizeof(float)); - /* Defer the last level to treat separately with its alternate - * destination. - */ - for (int level = 1; level < max_level; ++level) { - FVarVertex *dst = src + refiner.GetLevel(level-1).GetNumFVarValues(channel); - primvar_refiner.InterpolateFaceVarying(level, src, dst, channel); - src = dst; + const int max_level = refiner.GetMaxLevel(); + size_t fvar_data_offset = 0, values_offset = 0; + for (int channel = 0; channel < refiner.GetNumFVarChannels(); ++channel) { + const int num_values = refiner.GetLevel(0).GetNumFVarValues(0) * 2, + num_values_max = refiner.GetLevel(max_level).GetNumFVarValues(channel), + num_values_total = refiner.GetNumFVarValuesTotal(channel); + if (num_values_total <= 0) { + continue; + } + OpenSubdiv::Far::PrimvarRefiner primvar_refiner(refiner); + if (refiner.IsUniform()) { + /* For uniform we only keep the highest level of refinement. */ + fvar_data.resize(fvar_data.size() + num_values_max * fvar_width); + std::vector<FVarVertex> buffer(num_values_total - num_values_max); + FVarVertex *src = &buffer[0]; + memcpy(src, &uvs[values_offset], num_values * sizeof(float)); + /* Defer the last level to treat separately with its alternate + * destination. + */ + for (int level = 1; level < max_level; ++level) { + FVarVertex *dst = src + refiner.GetLevel(level-1).GetNumFVarValues(channel); + primvar_refiner.InterpolateFaceVarying(level, src, dst, channel); + src = dst; + } + FVarVertex *dst = reinterpret_cast<FVarVertex *>(&fvar_data[fvar_data_offset]); + primvar_refiner.InterpolateFaceVarying(max_level, src, dst, channel); + fvar_data_offset += num_values_max * fvar_width; + } else { + /* For adaptive we keep all levels. */ + fvar_data.resize(fvar_data.size() + num_values_total * fvar_width); + FVarVertex *src = reinterpret_cast<FVarVertex *>(&fvar_data[fvar_data_offset]); + memcpy(src, &uvs[values_offset], num_values * sizeof(float)); + for (int level = 1; level <= max_level; ++level) { + FVarVertex *dst = src + refiner.GetLevel(level-1).GetNumFVarValues(channel); + primvar_refiner.InterpolateFaceVarying(level, src, dst, channel); + src = dst; + } + fvar_data_offset += num_values_total * fvar_width; } - FVarVertex *dst = reinterpret_cast<FVarVertex *>(&fvar_data[0]); - primvar_refiner.InterpolateFaceVarying(max_level, src, dst, channel); - } else { - /* For adaptive we keep all levels. */ - fvar_data.resize(num_values_total * fvar_width); - FVarVertex *src = reinterpret_cast<FVarVertex *>(&fvar_data[0]); - memcpy(src, &uvs[0], num_uvs * sizeof(float)); - for (int level = 1; level <= max_level; ++level) { - FVarVertex *dst = src + refiner.GetLevel(level-1).GetNumFVarValues(channel); - primvar_refiner.InterpolateFaceVarying(level, src, dst, channel); - src = dst; - } - } + values_offset += num_values; + } } } // namespace @@ -275,7 +279,7 @@ struct OpenSubdiv_GLMesh *openSubdiv_createOsdGLMeshFromTopologyRefiner( if (refiner->GetNumFVarChannels() > 0) { std::vector<float> fvar_data; interpolate_fvar_data(*refiner, topology_refiner->uvs, fvar_data); - openSubdiv_osdGLAllocFVar(gl_mesh, &fvar_data[0]); + openSubdiv_osdGLAllocFVar(topology_refiner, gl_mesh, &fvar_data[0]); } else { gl_mesh->fvar_data = NULL; |