37 switch (evaluator_type) {
62 if (
subdiv->topology_refiner ==
nullptr) {
67 if (
subdiv->evaluator ==
nullptr) {
69 opensubdiv_evaluator_from_subdiv_evaluator_type(evaluator_type);
72 subdiv->topology_refiner, opensubdiv_evaluator_type, evaluator_cache);
74 if (
subdiv->evaluator ==
nullptr) {
81 subdiv->evaluator->eval_output->setSettings(settings);
92static void set_coarse_positions(Subdiv *
subdiv,
97 if (verts_no_face.
count == 0) {
99 reinterpret_cast<const float *
>(positions.
data()), 0, positions.
size());
104 int used_vert_count = 0;
109 used_vert_positions[used_vert_count] = positions[vert];
113 reinterpret_cast<const float *
>(used_vert_positions.data()), 0, used_vert_positions.size());
117struct FaceVaryingDataFromUVContext {
118 opensubdiv::TopologyRefinerImpl *topology_refiner;
120 OffsetIndices<int>
faces;
121 const float (*mloopuv)[2];
126static void set_face_varying_data_from_uv_task(
void *__restrict userdata,
127 const int face_index,
130 FaceVaryingDataFromUVContext *ctx =
static_cast<FaceVaryingDataFromUVContext *
>(userdata);
131 opensubdiv::TopologyRefinerImpl *topology_refiner = ctx->topology_refiner;
132 const int layer_index = ctx->layer_index;
133 const float(*mluv)[2] = &ctx->mloopuv[ctx->faces[face_index].start()];
138 const OpenSubdiv::Vtr::ConstIndexArray uv_indices =
139 topology_refiner->base_level().GetFaceFVarValues(face_index, layer_index);
140 for (
int vertex_index = 0; vertex_index < uv_indices.size(); vertex_index++, mluv++) {
141 copy_v2_v2(ctx->buffer[uv_indices[vertex_index]], *mluv);
145static void set_face_varying_data_from_uv(
Subdiv *subdiv,
147 const float (*mloopuv)[2],
148 const int layer_index)
150 opensubdiv::TopologyRefinerImpl *topology_refiner = subdiv->topology_refiner;
151 OpenSubdiv_Evaluator *evaluator = subdiv->evaluator;
152 const int num_faces = topology_refiner->base_level().GetNumFaces();
153 const float(*mluv)[2] = mloopuv;
155 const int num_fvar_values = topology_refiner->base_level().GetNumFVarValues(layer_index);
159 FaceVaryingDataFromUVContext ctx;
160 ctx.topology_refiner = topology_refiner;
161 ctx.layer_index = layer_index;
164 ctx.faces = mesh->faces();
172 0, num_faces, &ctx, set_face_varying_data_from_uv_task, ¶llel_range_settings);
179static void set_vertex_data_from_orco(
Subdiv *subdiv,
const Mesh *mesh)
181 const float(*orco)[3] =
static_cast<const float(*)[3]
>(
183 const float(*cloth_orco)[3] =
static_cast<const float(*)[3]
>(
186 if (orco || cloth_orco) {
187 blender::opensubdiv::TopologyRefinerImpl *topology_refiner = subdiv->topology_refiner;
188 OpenSubdiv_Evaluator *evaluator = subdiv->evaluator;
189 const int num_verts = topology_refiner->
base_level().GetNumVertices();
191 if (orco && cloth_orco) {
193 for (
int i = 0;
i < num_verts;
i++) {
205 else if (cloth_orco) {
212static void get_mesh_evaluator_settings(OpenSubdiv_EvaluatorSettings *settings,
const Mesh *mesh)
226#ifdef WITH_OPENSUBDIV
228 get_mesh_evaluator_settings(&settings,
mesh);
243#ifdef WITH_OPENSUBDIV
244 if (
subdiv->evaluator ==
nullptr) {
250 set_coarse_positions(
subdiv,
251 coarse_vert_positions.
is_empty() ?
mesh->vert_positions() :
252 coarse_vert_positions,
253 mesh->verts_no_face());
257 for (
int layer_index = 0; layer_index < num_uv_layers; layer_index++) {
258 const float(*mloopuv)[2] =
static_cast<const float(*)[2]
>(
260 set_face_varying_data_from_uv(
subdiv,
mesh, mloopuv, layer_index);
266 subdiv->evaluator->eval_output->refine();
277 if (
subdiv->displacement_evaluator ==
nullptr) {
280 if (
subdiv->displacement_evaluator->initialize ==
nullptr) {
283 subdiv->displacement_evaluator->initialize(
subdiv->displacement_evaluator);
291 Subdiv *
subdiv,
const int ptex_face_index,
const float u,
const float v,
float r_P[3])
297 const int ptex_face_index,
304#ifdef WITH_OPENSUBDIV
305 subdiv->evaluator->eval_output->evaluateLimit(ptex_face_index, u,
v, r_P, r_dPdu, r_dPdv);
318 if (r_dPdu !=
nullptr && r_dPdv !=
nullptr) {
320 subdiv->evaluator->eval_output->evaluateLimit(
321 ptex_face_index, u * 0.999f + 0.0005f,
v * 0.999f + 0.0005f, r_P, r_dPdu, r_dPdv);
330 const int ptex_face_index,
336 float dPdu[3], dPdv[3];
343 Subdiv *
subdiv,
const int ptex_face_index,
const float u,
const float v,
float r_vertex_data[])
345#ifdef WITH_OPENSUBDIV
346 subdiv->evaluator->eval_output->evaluateVertexData(ptex_face_index, u,
v, r_vertex_data);
353 const int face_varying_channel,
354 const int ptex_face_index,
357 float r_face_varying[2])
359#ifdef WITH_OPENSUBDIV
360 subdiv->evaluator->eval_output->evaluateFaceVarying(
361 face_varying_channel, ptex_face_index, u,
v, r_face_varying);
368 const int ptex_face_index,
375 if (
subdiv->displacement_evaluator ==
nullptr) {
379 subdiv->displacement_evaluator->eval_displacement(
380 subdiv->displacement_evaluator, ptex_face_index, u,
v, dPdu, dPdv, r_D);
384 Subdiv *
subdiv,
const int ptex_face_index,
const float u,
const float v,
float r_P[3])
386 if (
subdiv->displacement_evaluator) {
387 float dPdu[3], dPdv[3],
D[3];
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 bool equals_v3v3(const float v1[3], const float v2[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void copy_v2_v2(float r[2], const float a[2])
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE void cross_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE bool is_zero_v3(const float v[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void zero_v3(float r[3])
MINLINE void add_v3_v3(float r[3], const float a[3])
MINLINE float normalize_v3(float n[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)
void eval_vertex_data(Subdiv *subdiv, const int ptex_face_index, const float u, const float v, float r_vertex_data[])
bool eval_begin_from_mesh(Subdiv *subdiv, const Mesh *mesh, Span< float3 > coarse_vert_positions, eSubdivEvaluatorType evaluator_type, OpenSubdiv_EvaluatorCache *evaluator_cache)
void eval_limit_point(Subdiv *subdiv, int ptex_face_index, float u, float v, float r_P[3])
void eval_displacement(Subdiv *subdiv, int ptex_face_index, float u, float v, const float dPdu[3], const float dPdv[3], float r_D[3])
void eval_limit_point_and_derivatives(Subdiv *subdiv, int ptex_face_index, float u, float v, float r_P[3], float r_dPdu[3], float r_dPdv[3])
void eval_limit_point_and_normal(Subdiv *subdiv, int ptex_face_index, float u, float v, float r_P[3], float r_N[3])
bool eval_begin(Subdiv *subdiv, eSubdivEvaluatorType evaluator_type, OpenSubdiv_EvaluatorCache *evaluator_cache, const OpenSubdiv_EvaluatorSettings *settings)
void eval_face_varying(Subdiv *subdiv, int face_varying_channel, int ptex_face_index, float u, float v, float r_face_varying[2])
void stats_reset(SubdivStats *stats, StatsValue value)
@ 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)
@ SUBDIV_STATS_EVALUATOR_CREATE
@ SUBDIV_STATS_EVALUATOR_REFINE
void eval_final_point(Subdiv *subdiv, int ptex_face_index, float u, float v, float r_P[3])
@ OPENSUBDIV_EVALUATOR_GPU
@ OPENSUBDIV_EVALUATOR_CPU
blender::opensubdiv::EvalOutputAPI * eval_output
blender::BitVector is_loose_bits