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>2018-08-01 19:31:05 +0300
committerSergey Sharybin <sergey.vfx@gmail.com>2018-08-01 19:43:03 +0300
commit86270b60dbeab29b4dc7dd9b596bcf0d533639d0 (patch)
tree925fc9160014a5e8ed30b2d044cd51aefb41ce50
parent5b3b0ed54f20fedcd4d5324c17f3d5ea39f6274f (diff)
Subsurf: Evaluate all UV layers
Before that it was only first UV layer which was properly evaluated, the rest were ignored. Now all layers are being properly handled.
-rw-r--r--intern/opensubdiv/internal/opensubdiv_evaluator.cc12
-rw-r--r--intern/opensubdiv/internal/opensubdiv_evaluator_internal.cc291
-rw-r--r--intern/opensubdiv/internal/opensubdiv_evaluator_internal.h9
-rw-r--r--intern/opensubdiv/internal/opensubdiv_util.h5
-rw-r--r--intern/opensubdiv/opensubdiv_evaluator_capi.h3
-rw-r--r--source/blender/blenkernel/BKE_subdiv.h1
-rw-r--r--source/blender/blenkernel/intern/subdiv_converter_mesh.c2
-rw-r--r--source/blender/blenkernel/intern/subdiv_eval.c16
-rw-r--r--source/blender/blenkernel/intern/subdiv_mesh.c8
9 files changed, 225 insertions, 122 deletions
diff --git a/intern/opensubdiv/internal/opensubdiv_evaluator.cc b/intern/opensubdiv/internal/opensubdiv_evaluator.cc
index 29d42a903ba..49b8626448b 100644
--- a/intern/opensubdiv/internal/opensubdiv_evaluator.cc
+++ b/intern/opensubdiv/internal/opensubdiv_evaluator.cc
@@ -42,9 +42,11 @@ void setVaryingData(OpenSubdiv_Evaluator* evaluator,
}
void setFaceVaryingData(OpenSubdiv_Evaluator* evaluator,
+ const int face_varying_channel,
const float* face_varying_data,
const int start_vertex_index, const int num_vertices) {
- evaluator->internal->eval_output->setFaceVaryingData(face_varying_data,
+ evaluator->internal->eval_output->setFaceVaryingData(face_varying_channel,
+ face_varying_data,
start_vertex_index,
num_vertices);
}
@@ -78,12 +80,14 @@ void setVaryingDataFromBuffer(OpenSubdiv_Evaluator* evaluator,
}
void setFaceVaryingDataFromBuffer(OpenSubdiv_Evaluator* evaluator,
+ const int face_varying_channel,
const void* buffer,
const int start_offset,
const int stride,
const int start_vertex_index,
const int num_vertices) {
evaluator->internal->eval_output->setFaceVaryingDataFromBuffer(
+ face_varying_channel,
buffer,
start_offset,
stride,
@@ -114,12 +118,12 @@ void evaluateVarying(OpenSubdiv_Evaluator* evaluator,
}
void evaluateFaceVarying(OpenSubdiv_Evaluator* evaluator,
+ const int face_varying_channel,
const int ptex_face_index,
float face_u, float face_v,
float face_varying[2]) {
- evaluator->internal->eval_output->evaluateFaceVarying(ptex_face_index,
- face_u, face_v,
- face_varying);
+ evaluator->internal->eval_output->evaluateFaceVarying(
+ face_varying_channel, ptex_face_index, face_u, face_v, face_varying);
}
void assignFunctionPointers(OpenSubdiv_Evaluator* evaluator) {
diff --git a/intern/opensubdiv/internal/opensubdiv_evaluator_internal.cc b/intern/opensubdiv/internal/opensubdiv_evaluator_internal.cc
index d593518405f..31e68492587 100644
--- a/intern/opensubdiv/internal/opensubdiv_evaluator_internal.cc
+++ b/intern/opensubdiv/internal/opensubdiv_evaluator_internal.cc
@@ -39,6 +39,7 @@
#include "MEM_guardedalloc.h"
#include "internal/opensubdiv_topology_refiner_internal.h"
+#include "internal/opensubdiv_util.h"
#include "opensubdiv_topology_refiner_capi.h"
using OpenSubdiv::Osd::BufferDescriptor;
@@ -147,6 +148,106 @@ class StackAllocatedBuffer {
float data_[element_size * num_vertices];
};
+template <typename EVAL_VERTEX_BUFFER,
+ typename STENCIL_TABLE,
+ typename PATCH_TABLE,
+ typename EVALUATOR,
+ typename DEVICE_CONTEXT = void>
+class FaceVaryingVolatileEval {
+ public:
+ typedef OpenSubdiv::Osd::EvaluatorCacheT<EVALUATOR> EvaluatorCache;
+
+ FaceVaryingVolatileEval(int face_varying_channel,
+ const StencilTable* face_varying_stencils,
+ int face_varying_width,
+ PATCH_TABLE* patch_table,
+ EvaluatorCache* evaluator_cache = NULL,
+ DEVICE_CONTEXT* device_context = NULL)
+ : face_varying_channel_(face_varying_channel),
+ src_face_varying_desc_(0, face_varying_width, face_varying_width),
+ patch_table_(patch_table),
+ evaluator_cache_(evaluator_cache),
+ device_context_(device_context) {
+ using OpenSubdiv::Osd::convertToCompatibleStencilTable;
+ num_coarse_face_varying_vertices_ =
+ face_varying_stencils->GetNumControlVertices();
+ const int num_total_face_varying_vertices =
+ face_varying_stencils->GetNumControlVertices() +
+ face_varying_stencils->GetNumStencils();
+ src_face_varying_data_ =
+ EVAL_VERTEX_BUFFER::Create(2,
+ num_total_face_varying_vertices,
+ device_context);
+ face_varying_stencils_ = convertToCompatibleStencilTable<STENCIL_TABLE>(
+ face_varying_stencils, device_context_);
+ }
+
+ ~FaceVaryingVolatileEval() {
+ delete src_face_varying_data_;
+ delete face_varying_stencils_;
+ }
+
+ void updateData(const float* src, int start_vertex, int num_vertices) {
+ src_face_varying_data_->UpdateData(src,
+ start_vertex,
+ num_vertices,
+ device_context_);
+ }
+
+ void refine() {
+ BufferDescriptor dst_face_varying_desc = src_face_varying_desc_;
+ dst_face_varying_desc.offset += num_coarse_face_varying_vertices_ *
+ src_face_varying_desc_.stride;
+ const EVALUATOR* eval_instance = OpenSubdiv::Osd::GetEvaluator<EVALUATOR>(
+ evaluator_cache_,
+ src_face_varying_desc_,
+ dst_face_varying_desc,
+ device_context_);
+ EVALUATOR::EvalStencils(src_face_varying_data_, src_face_varying_desc_,
+ src_face_varying_data_, dst_face_varying_desc,
+ face_varying_stencils_,
+ eval_instance,
+ device_context_);
+ }
+
+ void evalPatch(const PatchCoord& patch_coord, float face_varying[2]) {
+ StackAllocatedBuffer<2, 1> face_varying_data;
+ BufferDescriptor face_varying_desc(0, 2, 2);
+ SinglePatchCoordBuffer patch_coord_buffer(patch_coord);
+ const EVALUATOR* eval_instance =
+ OpenSubdiv::Osd::GetEvaluator<EVALUATOR>(evaluator_cache_,
+ src_face_varying_desc_,
+ face_varying_desc,
+ device_context_);
+ EVALUATOR::EvalPatchesFaceVarying(
+ src_face_varying_data_, src_face_varying_desc_,
+ &face_varying_data, face_varying_desc,
+ patch_coord_buffer.GetNumVertices(),
+ &patch_coord_buffer,
+ patch_table_,
+ face_varying_channel_,
+ eval_instance,
+ device_context_);
+ const float* refined_face_varying = face_varying_data.BindCpuBuffer();
+ memcpy(face_varying, refined_face_varying, sizeof(float) * 2);
+ }
+
+ protected:
+ int face_varying_channel_;
+
+ BufferDescriptor src_face_varying_desc_;
+
+ int num_coarse_face_varying_vertices_;
+ EVAL_VERTEX_BUFFER* src_face_varying_data_;
+ const STENCIL_TABLE* face_varying_stencils_;
+
+ // NOTE: We reference this, do not own it.
+ PATCH_TABLE* patch_table_;
+
+ EvaluatorCache* evaluator_cache_;
+ DEVICE_CONTEXT* device_context_;
+};
+
// Volatile evaluator which can be used from threads.
//
// TODO(sergey): Make it possible to evaluate coordinates in chunks.
@@ -162,19 +263,22 @@ template <typename SRC_VERTEX_BUFFER,
class VolatileEvalOutput {
public:
typedef OpenSubdiv::Osd::EvaluatorCacheT<EVALUATOR> EvaluatorCache;
-
- VolatileEvalOutput(const StencilTable* vertex_stencils,
- const StencilTable* varying_stencils,
- const StencilTable* face_varying_stencils,
- const int face_varying_channel,
- const int face_varying_width,
- const PatchTable* patch_table,
- EvaluatorCache* evaluator_cache = NULL,
- DEVICE_CONTEXT* device_context = NULL)
+ typedef FaceVaryingVolatileEval<EVAL_VERTEX_BUFFER,
+ STENCIL_TABLE,
+ PATCH_TABLE,
+ EVALUATOR,
+ DEVICE_CONTEXT> FaceVaryingEval;
+
+ VolatileEvalOutput(
+ const StencilTable* vertex_stencils,
+ const StencilTable* varying_stencils,
+ const vector<const StencilTable*>& all_face_varying_stencils,
+ const int face_varying_width,
+ const PatchTable* patch_table,
+ EvaluatorCache* evaluator_cache = NULL,
+ DEVICE_CONTEXT* device_context = NULL)
: src_desc_(0, 3, 3),
src_varying_desc_(0, 3, 3),
- src_face_varying_desc_(0, face_varying_width, face_varying_width),
- face_varying_channel_(face_varying_channel),
face_varying_width_(face_varying_width),
evaluator_cache_(evaluator_cache),
device_context_(device_context) {
@@ -193,33 +297,31 @@ class VolatileEvalOutput {
vertex_stencils, device_context_);
varying_stencils_ = convertToCompatibleStencilTable<STENCIL_TABLE>(
varying_stencils, device_context_);
- if (face_varying_stencils != NULL) {
- num_coarse_face_varying_vertices_ =
- face_varying_stencils->GetNumControlVertices();
- const int num_total_face_varying_vertices =
- face_varying_stencils->GetNumControlVertices() +
- face_varying_stencils->GetNumStencils();
- src_face_varying_data_ =
- EVAL_VERTEX_BUFFER::Create(2,
- num_total_face_varying_vertices,
- device_context_);
- face_varying_stencils_ = convertToCompatibleStencilTable<STENCIL_TABLE>(
- face_varying_stencils, device_context_);
- } else {
- num_coarse_face_varying_vertices_ = 0;
- src_face_varying_data_ = NULL;
- face_varying_stencils_ = NULL;
+ // Create evaluators for every face varying channel.
+ face_varying_evaluators.reserve(all_face_varying_stencils.size());
+ int face_varying_channel = 0;
+ foreach (const StencilTable* face_varying_stencils,
+ all_face_varying_stencils) {
+ face_varying_evaluators.push_back(
+ new FaceVaryingEval(face_varying_channel,
+ face_varying_stencils,
+ face_varying_width,
+ patch_table_,
+ evaluator_cache_,
+ device_context_));
+ ++face_varying_channel;
}
}
~VolatileEvalOutput() {
delete src_data_;
delete src_varying_data_;
- delete src_face_varying_data_;
delete patch_table_;
delete vertex_stencils_;
delete varying_stencils_;
- delete face_varying_stencils_;
+ foreach (FaceVaryingEval* face_varying_evaluator, face_varying_evaluators) {
+ delete face_varying_evaluator;
+ }
}
// TODO(sergey): Implement binding API.
@@ -235,13 +337,14 @@ class VolatileEvalOutput {
device_context_);
}
- void updateFaceVaryingData(const float* src,
+ void updateFaceVaryingData(const int face_varying_channel,
+ const float* src,
int start_vertex,
int num_vertices) {
- src_face_varying_data_->UpdateData(src,
- start_vertex,
- num_vertices,
- device_context_);
+ assert(face_varying_channel >= 0);
+ assert(face_varying_channel < face_varying_evaluators.size());
+ face_varying_evaluators[face_varying_channel]->updateData(
+ src, start_vertex, num_vertices);
}
bool hasVaryingData() const {
@@ -251,7 +354,7 @@ class VolatileEvalOutput {
}
bool hasFaceVaryingData() const {
- return face_varying_stencils_ != NULL;
+ return face_varying_evaluators.size() != 0;
}
void refine() {
@@ -285,19 +388,10 @@ class VolatileEvalOutput {
}
// Evaluate face-varying data.
if (hasFaceVaryingData()) {
- BufferDescriptor dst_face_varying_desc = src_face_varying_desc_;
- dst_face_varying_desc.offset += num_coarse_face_varying_vertices_ *
- src_face_varying_desc_.stride;
- eval_instance = OpenSubdiv::Osd::GetEvaluator<EVALUATOR>(
- evaluator_cache_,
- src_face_varying_desc_,
- dst_face_varying_desc,
- device_context_);
- EVALUATOR::EvalStencils(src_face_varying_data_, src_face_varying_desc_,
- src_face_varying_data_, dst_face_varying_desc,
- face_varying_stencils_,
- eval_instance,
- device_context_);
+ foreach (FaceVaryingEval* face_varying_evaluator,
+ face_varying_evaluators) {
+ face_varying_evaluator->refine();
+ }
}
}
@@ -384,47 +478,30 @@ class VolatileEvalOutput {
memcpy(varying, refined_varying, sizeof(float) * 3);
}
- void evalPatchFaceVarying(const PatchCoord& patch_coord,
+ void evalPatchFaceVarying(const int face_varying_channel,
+ const PatchCoord& patch_coord,
float face_varying[2]) {
- StackAllocatedBuffer<2, 1> face_varying_data;
- BufferDescriptor face_varying_desc(0, 2, 2);
- SinglePatchCoordBuffer patch_coord_buffer(patch_coord);
- const EVALUATOR* eval_instance =
- OpenSubdiv::Osd::GetEvaluator<EVALUATOR>(evaluator_cache_,
- src_face_varying_desc_,
- face_varying_desc,
- device_context_);
- EVALUATOR::EvalPatchesFaceVarying(
- src_face_varying_data_, src_face_varying_desc_,
- &face_varying_data, face_varying_desc,
- patch_coord_buffer.GetNumVertices(),
- &patch_coord_buffer,
- patch_table_,
- face_varying_channel_,
- eval_instance,
- device_context_);
- const float* refined_face_varying = face_varying_data.BindCpuBuffer();
- memcpy(face_varying, refined_face_varying, sizeof(float) * 2);
+ assert(face_varying_channel >= 0);
+ assert(face_varying_channel < face_varying_evaluators.size());
+ face_varying_evaluators[face_varying_channel]->evalPatch(
+ patch_coord, face_varying);
}
private:
SRC_VERTEX_BUFFER* src_data_;
SRC_VERTEX_BUFFER* src_varying_data_;
- EVAL_VERTEX_BUFFER* src_face_varying_data_;
PatchCoordBuffer* patch_coords_;
PATCH_TABLE* patch_table_;
BufferDescriptor src_desc_;
BufferDescriptor src_varying_desc_;
- BufferDescriptor src_face_varying_desc_;
int num_coarse_vertices_;
- int face_varying_channel_;
- int face_varying_width_;
- int num_coarse_face_varying_vertices_;
const STENCIL_TABLE* vertex_stencils_;
const STENCIL_TABLE* varying_stencils_;
- const STENCIL_TABLE* face_varying_stencils_;
+
+ int face_varying_width_;
+ vector<FaceVaryingEval*> face_varying_evaluators;
EvaluatorCache* evaluator_cache_;
DEVICE_CONTEXT* device_context_;
@@ -442,8 +519,7 @@ class CpuEvalOutput : public VolatileEvalOutput<CpuVertexBuffer,
public:
CpuEvalOutput(const StencilTable* vertex_stencils,
const StencilTable* varying_stencils,
- const StencilTable* face_varying_stencils,
- const int face_varying_channel,
+ const vector<const StencilTable*>& all_face_varying_stencils,
const int face_varying_width,
const PatchTable* patch_table,
EvaluatorCache* evaluator_cache = NULL)
@@ -453,8 +529,7 @@ class CpuEvalOutput : public VolatileEvalOutput<CpuVertexBuffer,
CpuPatchTable,
CpuEvaluator> (vertex_stencils,
varying_stencils,
- face_varying_stencils,
- face_varying_channel,
+ all_face_varying_stencils,
face_varying_width,
patch_table,
evaluator_cache) {
@@ -490,11 +565,13 @@ void CpuEvalOutputAPI::setVaryingData(const float* varying_data,
num_vertices);
}
-void CpuEvalOutputAPI::setFaceVaryingData(const float* face_varying_data,
+void CpuEvalOutputAPI::setFaceVaryingData(const int face_varying_channel,
+ const float* face_varying_data,
const int start_vertex_index,
const int num_vertices) {
// TODO(sergey): Add sanity check on indices.
- implementation_->updateFaceVaryingData(face_varying_data,
+ implementation_->updateFaceVaryingData(face_varying_channel,
+ face_varying_data,
start_vertex_index,
num_vertices);
}
@@ -535,6 +612,7 @@ void CpuEvalOutputAPI::setVaryingDataFromBuffer(
}
void CpuEvalOutputAPI::setFaceVaryingDataFromBuffer(
+ const int face_varying_channel,
const void* buffer,
const int start_offset,
const int stride,
@@ -546,6 +624,7 @@ void CpuEvalOutputAPI::setFaceVaryingDataFromBuffer(
for (int i = 0; i < num_vertices; ++i) {
const int current_vertex_index = start_vertex_index + i;
implementation_->updateFaceVaryingData(
+ face_varying_channel,
reinterpret_cast<const float*>(current_buffer),
current_vertex_index, 1);
current_buffer += stride;
@@ -585,7 +664,8 @@ void CpuEvalOutputAPI::evaluateVarying(const int ptex_face_index,
implementation_->evalPatchVarying(patch_coord, varying);
}
-void CpuEvalOutputAPI::evaluateFaceVarying(const int ptex_face_index,
+void CpuEvalOutputAPI::evaluateFaceVarying(const int face_varying_channel,
+ const int ptex_face_index,
float face_u, float face_v,
float face_varying[2]) {
assert(face_u >= 0.0f);
@@ -595,7 +675,8 @@ void CpuEvalOutputAPI::evaluateFaceVarying(const int ptex_face_index,
const PatchTable::PatchHandle* handle =
patch_map_->FindPatch(ptex_face_index, face_u, face_v);
PatchCoord patch_coord(*handle, face_u, face_v);
- implementation_->evalPatchFaceVarying(patch_coord, face_varying);
+ implementation_->evalPatchFaceVarying(
+ face_varying_channel, patch_coord, face_varying);
}
} // namespace opensubdiv_capi
@@ -614,6 +695,7 @@ OpenSubdiv_EvaluatorInternal::~OpenSubdiv_EvaluatorInternal() {
OpenSubdiv_EvaluatorInternal* openSubdiv_createEvaluatorInternal(
OpenSubdiv_TopologyRefiner* topology_refiner) {
+ using opensubdiv_capi::vector;
TopologyRefiner* refiner = topology_refiner->internal->osd_topology_refiner;
if (refiner == NULL) {
// Happens on bad topology.
@@ -621,8 +703,8 @@ OpenSubdiv_EvaluatorInternal* openSubdiv_createEvaluatorInternal(
}
// TODO(sergey): Base this on actual topology.
// const bool bas_varying_data = false;
- const bool has_face_varying_data =
- (refiner->GetNumFVarChannels() != 0);
+ const int num_face_varying_channels = refiner->GetNumFVarChannels();
+ const bool has_face_varying_data = (num_face_varying_channels != 0);
const int level = topology_refiner->getSubdivisionLevel(topology_refiner);
// TODO(sergey): Query from topology refiner.
const bool is_adaptive = topology_refiner->getIsAdaptive(topology_refiner);
@@ -659,19 +741,20 @@ OpenSubdiv_EvaluatorInternal* openSubdiv_createEvaluatorInternal(
varying_stencils =
StencilTableFactory::Create(*refiner, varying_stencil_options);
// Face warying stencil.
- const StencilTable* face_varying_stencils = NULL;
+vector<const StencilTable*> all_face_varying_stencils;
#ifdef OPENSUBDIV_HAS_FVAR_EVALUATION
- if (has_face_varying_data) {
+ all_face_varying_stencils.reserve(num_face_varying_channels);
+ for (int face_varying_channel = 0;
+ face_varying_channel < num_face_varying_channels;
+ ++face_varying_channel) {
StencilTableFactory::Options face_varying_stencil_options;
face_varying_stencil_options.generateOffsets = true;
face_varying_stencil_options.generateIntermediateLevels = is_adaptive;
face_varying_stencil_options.interpolationMode =
StencilTableFactory::INTERPOLATE_FACE_VARYING;
- // TODO(sergey): Make it configurable which face varying channel is being
- // interpolated.
- face_varying_stencil_options.fvarChannel = 0;
- face_varying_stencils =
- StencilTableFactory::Create(*refiner, face_varying_stencil_options);
+ face_varying_stencil_options.fvarChannel = face_varying_channel;
+ all_face_varying_stencils.push_back(
+ StencilTableFactory::Create(*refiner, face_varying_stencil_options));
}
#endif
// Generate bi-cubic patch table for the limit surface.
@@ -705,16 +788,20 @@ OpenSubdiv_EvaluatorInternal* openSubdiv_createEvaluatorInternal(
varying_stencils = table;
}
#ifdef OPENSUBDIV_HAS_FVAR_EVALUATION
- const StencilTable* local_point_face_varying_stencil_table =
- patch_table->GetLocalPointFaceVaryingStencilTable();
- if (local_point_face_varying_stencil_table != NULL) {
+ for (int face_varying_channel = 0;
+ face_varying_channel < num_face_varying_channels;
+ ++face_varying_channel) {
const StencilTable* table =
StencilTableFactory::AppendLocalPointStencilTableFaceVarying(
*refiner,
- face_varying_stencils,
- local_point_face_varying_stencil_table);
- delete face_varying_stencils;
- face_varying_stencils = table;
+ all_face_varying_stencils[face_varying_channel],
+ patch_table->GetLocalPointFaceVaryingStencilTable(
+ face_varying_channel),
+ face_varying_channel);
+ if (table != NULL) {
+ delete all_face_varying_stencils[face_varying_channel];
+ all_face_varying_stencils[face_varying_channel] = table;
+ }
}
#endif
// Create OpenSubdiv's CPU side evaluator.
@@ -722,8 +809,8 @@ OpenSubdiv_EvaluatorInternal* openSubdiv_createEvaluatorInternal(
opensubdiv_capi::CpuEvalOutput* eval_output =
new opensubdiv_capi::CpuEvalOutput(vertex_stencils,
varying_stencils,
- face_varying_stencils,
- 0, 2,
+ all_face_varying_stencils,
+ 2,
patch_table);
OpenSubdiv::Far::PatchMap* patch_map = new PatchMap(*patch_table);
// Wrap everything we need into an object which we control from our side.
@@ -736,7 +823,9 @@ OpenSubdiv_EvaluatorInternal* openSubdiv_createEvaluatorInternal(
// TOOD(sergey): Look into whether we've got duplicated stencils arrays.
delete vertex_stencils;
delete varying_stencils;
- delete face_varying_stencils;
+ foreach (const StencilTable* table, all_face_varying_stencils) {
+ delete table;
+ }
return evaluator_descr;
}
diff --git a/intern/opensubdiv/internal/opensubdiv_evaluator_internal.h b/intern/opensubdiv/internal/opensubdiv_evaluator_internal.h
index cc69db6abc6..7d9178f38dc 100644
--- a/intern/opensubdiv/internal/opensubdiv_evaluator_internal.h
+++ b/intern/opensubdiv/internal/opensubdiv_evaluator_internal.h
@@ -57,7 +57,8 @@ class CpuEvalOutputAPI {
//
// TODO(sergey): Find a better name for vertex here. It is not the vertex of
// geometry, but a vertex of UV map.
- void setFaceVaryingData(const float* varying_data,
+ void setFaceVaryingData(const int face_varying_channel,
+ const float* varying_data,
const int start_vertex_index, const int num_vertices);
// Set coarse vertex position from a continuous memory buffer where
@@ -82,7 +83,8 @@ class CpuEvalOutputAPI {
//
// TODO(sergey): Find a better name for vertex here. It is not the vertex of
// geometry, but a vertex of UV map.
- void setFaceVaryingDataFromBuffer(const void* buffer,
+ void setFaceVaryingDataFromBuffer(const int face_varying_channel,
+ const void* buffer,
const int start_offset,
const int stride,
const int start_vertex_index,
@@ -104,7 +106,8 @@ class CpuEvalOutputAPI {
// Evaluate facee-varying data at a given bilinear coordinate of given
// ptex face.
- void evaluateFaceVarying(const int ptes_face_index,
+ void evaluateFaceVarying(const int face_varying_channel,
+ const int ptes_face_index,
float face_u, float face_v,
float face_varying[2]);
diff --git a/intern/opensubdiv/internal/opensubdiv_util.h b/intern/opensubdiv/internal/opensubdiv_util.h
index 6ed19b37e33..db55504215d 100644
--- a/intern/opensubdiv/internal/opensubdiv_util.h
+++ b/intern/opensubdiv/internal/opensubdiv_util.h
@@ -25,6 +25,11 @@
namespace opensubdiv_capi {
+using std::string;
+using std::vector;
+
+#define foreach(x, y) for(x : y)
+
#define STRINGIFY_ARG(x) "" #x
#define STRINGIFY_APPEND(a, b) "" a #b
#define STRINGIFY(x) STRINGIFY_APPEND("", x)
diff --git a/intern/opensubdiv/opensubdiv_evaluator_capi.h b/intern/opensubdiv/opensubdiv_evaluator_capi.h
index 07a55cfd349..eda5d614635 100644
--- a/intern/opensubdiv/opensubdiv_evaluator_capi.h
+++ b/intern/opensubdiv/opensubdiv_evaluator_capi.h
@@ -41,6 +41,7 @@ typedef struct OpenSubdiv_Evaluator {
// TODO(sergey): Find a better name for vertex here. It is not the vertex of
// geometry, but a vertex of UV map.
void (*setFaceVaryingData)(struct OpenSubdiv_Evaluator* evaluator,
+ const int face_varying_channel,
const float* face_varying_data,
const int start_vertex_index,
const int num_vertices);
@@ -70,6 +71,7 @@ typedef struct OpenSubdiv_Evaluator {
// TODO(sergey): Find a better name for vertex here. It is not the vertex of
// geometry, but a vertex of UV map.
void (*setFaceVaryingDataFromBuffer)(struct OpenSubdiv_Evaluator* evaluator,
+ const int face_varying_channel,
const void* buffer,
const int start_offset,
const int stride,
@@ -95,6 +97,7 @@ typedef struct OpenSubdiv_Evaluator {
// Evaluate face-varying data at a given bilinear coordinate of given
// ptex face.
void (*evaluateFaceVarying)(struct OpenSubdiv_Evaluator* evaluator,
+ const int face_varying_channel,
const int ptex_face_index,
float face_u, float face_v,
float face_varying[2]);
diff --git a/source/blender/blenkernel/BKE_subdiv.h b/source/blender/blenkernel/BKE_subdiv.h
index ad829946db8..cd1e3adbc21 100644
--- a/source/blender/blenkernel/BKE_subdiv.h
+++ b/source/blender/blenkernel/BKE_subdiv.h
@@ -158,6 +158,7 @@ void BKE_subdiv_eval_limit_point_and_short_normal(
void BKE_subdiv_eval_face_varying(
Subdiv *subdiv,
+ const int face_varying_channel,
const int ptex_face_index,
const float u, const float v,
float varying[2]);
diff --git a/source/blender/blenkernel/intern/subdiv_converter_mesh.c b/source/blender/blenkernel/intern/subdiv_converter_mesh.c
index b1e3be6c799..963f403e8d3 100644
--- a/source/blender/blenkernel/intern/subdiv_converter_mesh.c
+++ b/source/blender/blenkernel/intern/subdiv_converter_mesh.c
@@ -157,7 +157,7 @@ static float get_edge_sharpness(const OpenSubdiv_Converter *converter,
storage->manifold_edge_index_reverse[manifold_edge_index];
const MEdge *medge = storage->mesh->medge;
const float edge_crease = (float)medge[edge_index].crease / 255.0f;
- return edge_crease * storage->settings.level;
+ return edge_crease * storage->settings.level * 10;
}
diff --git a/source/blender/blenkernel/intern/subdiv_eval.c b/source/blender/blenkernel/intern/subdiv_eval.c
index 0f928331724..fa9488f15b6 100644
--- a/source/blender/blenkernel/intern/subdiv_eval.c
+++ b/source/blender/blenkernel/intern/subdiv_eval.c
@@ -122,10 +122,11 @@ static void set_face_varying_data_from_uv(Subdiv *subdiv,
vertex_index < num_face_vertices;
vertex_index++, mluv++)
{
- evaluator->setFaceVaryingData(evaluator,
- mluv->uv,
- uv_indicies[vertex_index],
- 1);
+ evaluator->setFaceVaryingData(evaluator,
+ layer_index,
+ mluv->uv,
+ uv_indicies[vertex_index],
+ 1);
}
}
}
@@ -147,11 +148,6 @@ void BKE_subdiv_eval_update_from_mesh(Subdiv *subdiv, const Mesh *mesh)
const MLoopUV *mloopuv = CustomData_get_layer_n(
&mesh->ldata, CD_MLOOPUV, layer_index);
set_face_varying_data_from_uv(subdiv, mloopuv, layer_index);
- /* NOTE: Currently evaluator can only handle single face varying layer.
- * This is a limitation of C-API and some underlying helper classes from
- * our side which will get fixed.
- */
- break;
}
/* Update evaluator to the new coarse geometry. */
BKE_subdiv_stats_begin(&subdiv->stats, SUBDIV_STATS_EVALUATOR_REFINE);
@@ -223,12 +219,14 @@ void BKE_subdiv_eval_limit_point_and_short_normal(
void BKE_subdiv_eval_face_varying(
Subdiv *subdiv,
+ const int face_varying_channel,
const int ptex_face_index,
const float u, const float v,
float face_varying[2])
{
#ifdef WITH_OPENSUBDIV
subdiv->evaluator->evaluateFaceVarying(subdiv->evaluator,
+ face_varying_channel,
ptex_face_index,
u, v,
face_varying);
diff --git a/source/blender/blenkernel/intern/subdiv_mesh.c b/source/blender/blenkernel/intern/subdiv_mesh.c
index befd2b9847c..a58dbdcff84 100644
--- a/source/blender/blenkernel/intern/subdiv_mesh.c
+++ b/source/blender/blenkernel/intern/subdiv_mesh.c
@@ -1509,25 +1509,25 @@ static void subdiv_eval_uv_layer(SubdivMeshContext *ctx,
for (int layer_index = 0; layer_index < ctx->num_uv_layers; layer_index++) {
MLoopUV *subdiv_loopuv = &ctx->uv_layers[layer_index][mloop_index];
BKE_subdiv_eval_face_varying(subdiv,
+ layer_index,
ptex_face_index,
u, v,
subdiv_loopuv[0].uv);
BKE_subdiv_eval_face_varying(subdiv,
+ layer_index,
ptex_face_index,
u + du, v,
subdiv_loopuv[1].uv);
BKE_subdiv_eval_face_varying(subdiv,
+ layer_index,
ptex_face_index,
u + du, v + dv,
subdiv_loopuv[2].uv);
BKE_subdiv_eval_face_varying(subdiv,
+ layer_index,
ptex_face_index,
u, v + dv,
subdiv_loopuv[3].uv);
- /* TODO(sergey): Currently evaluator only has single UV layer, so can
- * not evaluate more than that. Need to be solved.
- */
- break;
}
}