Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Sharybin <sergey.vfx@gmail.com>2016-07-22 15:46:13 +0300
committerSergey Sharybin <sergey.vfx@gmail.com>2016-07-22 15:56:15 +0300
commit48c4b700dce0b326e1b905e133c0db1217a5cae0 (patch)
treed520f9d02eeaa7deb7774ed4dca84bdedd0d7914 /intern/opensubdiv/opensubdiv_capi.cc
parent98970f71fe95e6b842582f5b71f3081798a8f54a (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.cc78
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;