38 switch (evaluator_type) {
63 if (
subdiv->topology_refiner ==
nullptr) {
68 if (
subdiv->evaluator ==
nullptr) {
70 opensubdiv_evaluator_from_subdiv_evaluator_type(evaluator_type);
73 subdiv->topology_refiner, opensubdiv_evaluator_type, evaluator_cache);
75 if (
subdiv->evaluator ==
nullptr) {
82 subdiv->evaluator->eval_output->setSettings(settings);
93static void set_coarse_positions(Subdiv *
subdiv,
98 if (verts_no_face.
count == 0) {
100 reinterpret_cast<const float *
>(positions.
data()), 0, positions.
size());
105 int used_vert_count = 0;
110 used_vert_positions[used_vert_count] = positions[vert];
114 reinterpret_cast<const float *
>(used_vert_positions.data()), 0, used_vert_positions.size());
118struct FaceVaryingDataFromUVContext {
119 opensubdiv::TopologyRefinerImpl *topology_refiner;
121 OffsetIndices<int>
faces;
122 const float (*uv_map)[2];
127static void set_face_varying_data_from_uv_task(
void *__restrict userdata,
128 const int face_index,
131 FaceVaryingDataFromUVContext *ctx =
static_cast<FaceVaryingDataFromUVContext *
>(userdata);
132 opensubdiv::TopologyRefinerImpl *topology_refiner = ctx->topology_refiner;
133 const int layer_index = ctx->layer_index;
134 const float (*mluv)[2] = &ctx->uv_map[ctx->faces[face_index].start()];
139 const OpenSubdiv::Vtr::ConstIndexArray uv_indices =
140 topology_refiner->base_level().GetFaceFVarValues(face_index, layer_index);
141 for (
int vertex_index = 0; vertex_index < uv_indices.size(); vertex_index++, mluv++) {
142 copy_v2_v2(ctx->buffer[uv_indices[vertex_index]], *mluv);
146static void set_face_varying_data_from_uv(
Subdiv *subdiv,
148 const float (*uv_map)[2],
149 const int layer_index)
151 opensubdiv::TopologyRefinerImpl *topology_refiner = subdiv->topology_refiner;
152 OpenSubdiv_Evaluator *evaluator = subdiv->evaluator;
153 const int num_faces = topology_refiner->base_level().GetNumFaces();
154 const float (*mluv)[2] = uv_map;
156 const int num_fvar_values = topology_refiner->base_level().GetNumFVarValues(layer_index);
160 FaceVaryingDataFromUVContext ctx;
161 ctx.topology_refiner = topology_refiner;
162 ctx.layer_index = layer_index;
165 ctx.faces = mesh->faces();
173 0, num_faces, &ctx, set_face_varying_data_from_uv_task, ¶llel_range_settings);
180static void set_vertex_data_from_orco(
Subdiv *subdiv,
const Mesh *mesh)
182 const float (*orco)[3] =
static_cast<const float (*)[3]
>(
184 const float (*cloth_orco)[3] =
static_cast<const float (*)[3]
>(
187 if (orco || cloth_orco) {
188 blender::opensubdiv::TopologyRefinerImpl *topology_refiner = subdiv->topology_refiner;
189 OpenSubdiv_Evaluator *evaluator = subdiv->evaluator;
190 const int num_verts = topology_refiner->
base_level().GetNumVertices();
192 if (orco && cloth_orco) {
194 for (
int i = 0;
i < num_verts;
i++) {
206 else if (cloth_orco) {
213static void get_mesh_evaluator_settings(OpenSubdiv_EvaluatorSettings *settings,
const Mesh *mesh)
227#ifdef WITH_OPENSUBDIV
229 get_mesh_evaluator_settings(&settings,
mesh);
244#ifdef WITH_OPENSUBDIV
245 if (
subdiv->evaluator ==
nullptr) {
251 set_coarse_positions(
subdiv,
252 coarse_vert_positions.
is_empty() ?
mesh->vert_positions() :
253 coarse_vert_positions,
254 mesh->verts_no_face());
258 for (
int layer_index = 0; layer_index < num_uv_layers; layer_index++) {
259 const float (*uv_map)[2] =
static_cast<const float (*)[2]
>(
261 set_face_varying_data_from_uv(
subdiv,
mesh, uv_map, layer_index);
267 subdiv->evaluator->eval_output->refine();
278 if (
subdiv->displacement_evaluator ==
nullptr) {
281 if (
subdiv->displacement_evaluator->initialize ==
nullptr) {
284 subdiv->displacement_evaluator->initialize(
subdiv->displacement_evaluator);
293#ifdef WITH_OPENSUBDIV
295 subdiv->evaluator->eval_output->evaluateLimit(ptex_face_index, u,
v, r_P,
nullptr,
nullptr);
299 return {0.0f, 0.0f, 0.0f};
304 const int ptex_face_index,
311#ifdef WITH_OPENSUBDIV
312 subdiv->evaluator->eval_output->evaluateLimit(ptex_face_index, u,
v, r_P, r_dPdu, r_dPdv);
326 subdiv->evaluator->eval_output->evaluateLimit(
327 ptex_face_index, u * 0.999f + 0.0005f,
v * 0.999f + 0.0005f, r_P, r_dPdu, r_dPdv);
335 const int ptex_face_index,
348 Subdiv *
subdiv,
const int ptex_face_index,
const float u,
const float v,
float r_vertex_data[])
350#ifdef WITH_OPENSUBDIV
351 subdiv->evaluator->eval_output->evaluateVertexData(ptex_face_index, u,
v, r_vertex_data);
358 const int face_varying_channel,
359 const int ptex_face_index,
364#ifdef WITH_OPENSUBDIV
365 subdiv->evaluator->eval_output->evaluateFaceVarying(
366 face_varying_channel, ptex_face_index, u,
v, r_face_varying);
373 const int ptex_face_index,
380 if (
subdiv->displacement_evaluator ==
nullptr) {
384 subdiv->displacement_evaluator->eval_displacement(
385 subdiv->displacement_evaluator, ptex_face_index, u,
v, dPdu, dPdv, r_D);
391 if (
subdiv->displacement_evaluator) {
CustomData interface, see also DNA_customdata_types.h.
const void * CustomData_get_layer_n(const CustomData *data, eCustomDataType type, int n)
const void * CustomData_get_layer(const CustomData *data, eCustomDataType type)
bool CustomData_has_layer(const CustomData *data, eCustomDataType type)
int CustomData_number_of_layers(const CustomData *data, eCustomDataType type)
#define BLI_assert_msg(a, msg)
MINLINE void copy_v2_v2(float r[2], const float a[2])
MINLINE void copy_v3_v3(float r[3], const float a[3])
struct TaskParallelTLS TaskParallelTLS
void BLI_task_parallel_range(int start, int stop, void *userdata, TaskParallelRangeFunc func, const TaskParallelSettings *settings)
BLI_INLINE void BLI_parallel_range_settings_defaults(TaskParallelSettings *settings)
struct TaskParallelSettings TaskParallelSettings
Read Guarded memory(de)allocation.
BMesh const char void * data
ATTR_WARN_UNUSED_RESULT const BMVert * v
constexpr const T * data() const
constexpr int64_t size() const
constexpr IndexRange index_range() const
constexpr bool is_empty() const
void setFaceVaryingData(const int face_varying_channel, const float *varying_data, const int start_vertex_index, const int num_vertices)
void setVertexData(const float *data, const int start_vertex_index, const int num_vertices)
void setCoarsePositions(const float *positions, const int start_vertex_index, const int num_vertices)
const OpenSubdiv::Far::TopologyLevel & base_level() const
OpenSubdiv_Evaluator * openSubdiv_createEvaluatorFromTopologyRefiner(blender::opensubdiv::TopologyRefinerImpl *topology_refiner, eOpenSubdivEvaluator evaluator_type, OpenSubdiv_EvaluatorCache *evaluator_cache_descr)
void * MEM_malloc_arrayN(size_t len, size_t size, const char *str)
void MEM_freeN(void *vmemh)
void eval_init_displacement(Subdiv *subdiv)
float3 eval_final_point(Subdiv *subdiv, int ptex_face_index, float u, float v)
bool eval_begin_from_mesh(Subdiv *subdiv, const Mesh *mesh, eSubdivEvaluatorType evaluator_type, Span< float3 > coarse_vert_positions={}, OpenSubdiv_EvaluatorCache *evaluator_cache=nullptr)
float3 eval_limit_point(Subdiv *subdiv, int ptex_face_index, float u, float v)
bool eval_begin(Subdiv *subdiv, eSubdivEvaluatorType evaluator_type, OpenSubdiv_EvaluatorCache *evaluator_cache, const OpenSubdiv_EvaluatorSettings *settings)
void eval_limit_point_and_normal(Subdiv *subdiv, int ptex_face_index, float u, float v, float3 &r_P, float3 &r_N)
void stats_reset(SubdivStats *stats, StatsValue value)
void eval_limit_point_and_derivatives(Subdiv *subdiv, int ptex_face_index, float u, float v, float3 &r_P, float3 &r_dPdu, float3 &r_dPdv)
void eval_displacement(Subdiv *subdiv, int ptex_face_index, float u, float v, const float3 &dPdu, const float3 &dPdv, float3 &r_D)
@ SUBDIV_EVALUATOR_TYPE_GPU
@ SUBDIV_EVALUATOR_TYPE_CPU
void stats_begin(SubdivStats *stats, StatsValue value)
void stats_end(SubdivStats *stats, StatsValue value)
bool eval_refine_from_mesh(Subdiv *subdiv, const Mesh *mesh, Span< float3 > coarse_vert_positions)
void eval_face_varying(Subdiv *subdiv, int face_varying_channel, int ptex_face_index, float u, float v, float2 &r_face_varying)
void eval_vertex_data(Subdiv *subdiv, int ptex_face_index, float u, float v, float r_vertex_data[])
@ SUBDIV_STATS_EVALUATOR_CREATE
@ SUBDIV_STATS_EVALUATOR_REFINE
AxisSigned cross(const AxisSigned a, const AxisSigned b)
MatBase< T, NumCol, NumRow > normalize(const MatBase< T, NumCol, NumRow > &a)
bool is_equal(const MatBase< T, NumCol, NumRow > &a, const MatBase< T, NumCol, NumRow > &b, const T epsilon=T(0))
VecBase< float, 2 > float2
VecBase< float, 3 > float3
@ OPENSUBDIV_EVALUATOR_GPU
@ OPENSUBDIV_EVALUATOR_CPU
blender::opensubdiv::EvalOutputAPI * eval_output
blender::BitVector is_loose_bits