94 for (
int layer_index = 0; layer_index < ctx->
num_uv_layers; layer_index++) {
118 ctx->
orco =
static_cast<float(*)[3]
>(
158 const int ptex_of_face_index)
160 const int first_ptex_loop_index = coarse_face.
start() + ptex_of_face_index;
165 const int last_ptex_loop_index = coarse_face.
start() +
166 (ptex_of_face_index + coarse_face.
size() - 1) %
168 loops_of_ptex->
first_loop = first_ptex_loop_index;
169 loops_of_ptex->
last_loop = last_ptex_loop_index;
170 if (coarse_face.
size() == 4) {
215 if (coarse_face.
size() == 4) {
239 const float weight = 1.0f / float(coarse_face.
size());
242 for (
int i = 0;
i < coarse_face.
size();
i++) {
261 if (coarse_face.
size() == 4) {
279 const float weights[2] = {0.5f, 0.5f};
280 const int first_loop_index = loops_of_ptex.
first_loop;
281 const int last_loop_index = loops_of_ptex.
last_loop;
282 const int first_indices[2] = {
285 (first_loop_index - coarse_face.
start() + 1) %
286 coarse_face.
size()]};
344 if (coarse_face.
size() == 4) {
368 const float weight = 1.0f / float(coarse_face.
size());
371 for (
int i = 0;
i < coarse_face.
size();
i++) {
390 if (coarse_face.
size() == 4) {
406 const float weights[2] = {0.5f, 0.5f};
407 const int base_loop_index = coarse_face.
start();
408 const int first_loop_index = loops_of_ptex.
first_loop;
409 const int second_loop_index = base_loop_index +
410 (first_loop_index - base_loop_index + 1) % coarse_face.
size();
411 const int first_indices[2] = {first_loop_index, second_loop_index};
473 const int ptex_face_index,
476 const int subdiv_vertex_index)
479 float vertex_data[6];
501 const int ptex_face_index,
504 const int subdiv_vertex_index)
508 float dummy_P[3], dPdu[3], dPdv[3],
D[3];
528 const int num_vertices,
543 num_vertices, num_edges, num_faces, num_loops);
556 if (num_faces != 0) {
557 subdiv_mesh.face_offsets_for_write().last() = num_loops;
580 subdiv_mesh.
runtime->subsurf_face_dot_tags.clear();
581 subdiv_mesh.
runtime->subsurf_face_dot_tags.resize(num_vertices);
595 const int coarse_vertex_index,
596 const int subdiv_vertex_index)
607 const int subdiv_vertex_index,
612 const float weights[4] = {(1.0f - u) * (1.0f -
v), u * (1.0f -
v), u *
v, (1.0f - u) *
v};
619 subdiv_vertex_index);
626 const int ptex_face_index,
629 const int coarse_vertex_index,
630 const int subdiv_vertex_index)
635 float D[3] = {0.0f, 0.0f, 0.0f};
645 subdiv_position +=
D;
654 const int ptex_face_index,
658 const int subdiv_vertex_index)
663 float D[3] = {0.0f, 0.0f, 0.0f};
681 const int ptex_face_index,
684 const int subdiv_vertex_index)
692 const int ptex_face_index,
698 const int subdiv_vertex_index)
701 foreach_context, tls, ptex_face_index, u,
v, subdiv_vertex_index);
706 const int ptex_face_index,
712 const int subdiv_vertex_index)
715 foreach_context, tls, ptex_face_index, u,
v, subdiv_vertex_index);
720 const int ptex_face_index,
723 const int coarse_vertex_index,
726 const int subdiv_vertex_index)
731 ctx, ptex_face_index, u,
v, coarse_vertex_index, subdiv_vertex_index);
736 const int coarse_face_index,
737 const int coarse_corner)
767 const int ptex_face_index,
771 const int coarse_face_index,
772 const int coarse_corner,
773 const int subdiv_vertex_index)
786 if (coarse_face.
size() == 4) {
787 if (u == 0.5f &&
v == 0.5f) {
792 if (u == 1.0f &&
v == 1.0f) {
800 const int subdiv_vertex_index,
806 subdiv_mesh->
runtime->subsurf_face_dot_tags[subdiv_vertex_index].set();
812 const int ptex_face_index,
815 const int coarse_face_index,
816 const int coarse_corner,
817 const int subdiv_vertex_index)
839 const int subdiv_edge_index,
840 const int coarse_edge_index)
860 const int coarse_edge_index,
861 const int subdiv_edge_index,
879 const int subdiv_loop_index,
884 const float weights[4] = {(1.0f - u) * (1.0f -
v), u * (1.0f -
v), u *
v, (1.0f - u) *
v};
896 const int corner_index,
897 const int ptex_face_index,
905 for (
int layer_index = 0; layer_index < ctx->
num_uv_layers; layer_index++) {
907 subdiv, layer_index, ptex_face_index, u,
v, ctx->
uv_layers[layer_index][corner_index]);
913 const int coarse_face_index,
914 const int coarse_corner)
944 const int ptex_face_index,
948 const int coarse_face_index,
949 const int coarse_corner,
950 const int subdiv_loop_index,
951 const int subdiv_vertex_index,
952 const int subdiv_edge_index)
971 const int coarse_face_index,
972 const int subdiv_face_index,
973 const int start_loop_index,
994 const int coarse_vertex_index,
995 const int subdiv_vertex_index)
1010 const auto neighbor_edge_if_single = [&](
const int vert) -> std::optional<int2> {
1011 const Span<int> neighbors = vert_to_edge_map[vert];
1012 if (neighbors.
size() != 2) {
1013 return std::nullopt;
1015 return neighbors[0] == edge_index ? coarse_edges[neighbors[1]] : coarse_edges[neighbors[0]];
1017 const int2 edge = coarse_edges[edge_index];
1018 return {neighbor_edge_if_single(edge[0]), neighbor_edge_if_single(edge[1])};
1023 const int2 &coarse_edge,
1024 const std::array<std::optional<int2>, 2> &neighbors)
1026 std::array<float3, 4>
result;
1028 result[1] = coarse_positions[coarse_edge[0]];
1029 result[2] = coarse_positions[coarse_edge[1]];
1031 if (
const std::optional<int2> &other = neighbors[0]) {
1038 if (
const std::optional<int2> &other = neighbors[1]) {
1050 const int coarse_edge_index,
1051 const bool is_simple,
1054 const int2 edge = coarse_edges[coarse_edge_index];
1056 return math::interpolate(coarse_positions[edge[0]], coarse_positions[edge[1]], u);
1060 coarse_edges, vert_to_edge_map, coarse_edge_index);
1062 coarse_positions, edge, neighbors);
1069 const int2 &coarse_edge,
1071 const int subdiv_vertex_index)
1078 const float interpolation_weights[2] = {1.0f - u, u};
1079 const int coarse_vertex_indices[2] = {coarse_edge[0], coarse_edge[1]};
1082 coarse_vertex_indices,
1083 interpolation_weights,
1086 subdiv_vertex_index);
1094 const int coarse_edge_index,
1096 const int subdiv_vertex_index)
1104 if (!
ELEM(u, 0.0, 1.0)) {
1126 memset(foreach_context, 0,
sizeof(*foreach_context));
1170 subdiv_context.
settings = settings;
1177 if (coarse_mesh->loose_edges().count > 0) {
1192 foreach_context.
user_data = &subdiv_context;
1225 if (coarse_mesh->verts_no_face().count == 0) {
1226 result->tag_loose_verts_none();
1228 if (coarse_mesh->loose_edges().count == 0) {
1229 result->tag_loose_edges_none();
1231 result->tag_overlapping_none();
1233 if (
subdiv->settings.is_simple) {
1235 result->runtime->bounds_cache = coarse_mesh->
runtime->bounds_cache;
CustomData interface, see also DNA_customdata_types.h.
const CustomData_MeshMasks CD_MASK_EVERYTHING
void CustomData_interp(const CustomData *source, CustomData *dest, const int *src_indices, const float *weights, const float *sub_weights, int count, int dest_index)
void CustomData_free(CustomData *data)
void CustomData_init_from(const CustomData *source, CustomData *dest, eCustomDataMask mask, int totelem)
void CustomData_init_layout_from(const CustomData *source, CustomData *dest, eCustomDataMask mask, eCDAllocType alloctype, int totelem)
void * CustomData_get_layer_for_write(CustomData *data, eCustomDataType type, int totelem)
void CustomData_free_elem(CustomData *data, int index, int count)
void CustomData_copy_data(const CustomData *source, CustomData *dest, int source_index, int dest_index, int count)
const void * CustomData_add_layer_named_with_data(CustomData *data, eCustomDataType type, void *layer_data, int totelem, blender::StringRef name, const blender::ImplicitSharingInfo *sharing_info)
int CustomData_number_of_layers(const CustomData *data, eCustomDataType type)
bool CustomData_free_layer_named(CustomData *data, blender::StringRef name)
void * CustomData_get_layer_n_for_write(CustomData *data, eCustomDataType type, int n, int totelem)
void key_curve_position_weights(float t, float data[4], KeyInterpolationType type)
void BKE_mesh_copy_parameters_for_eval(Mesh *me_dst, const Mesh *me_src)
MINLINE void mul_v3_fl(float r[3], float f)
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE void add_v3_v3(float r[3], const float a[3])
Read Guarded memory(de)allocation.
ATTR_WARN_UNUSED_RESULT const BMVert * v
constexpr int64_t size() const
constexpr int64_t start() const
constexpr int64_t size() const
#define CD_MASK_MULTIRES_GRIDS
void * MEM_calloc_arrayN(size_t len, size_t size, const char *str)
void * MEM_malloc_arrayN(size_t len, size_t size, const char *str)
ccl_device_inline float2 mask(const MaskType mask, const float2 a)
T mix4(const float4 &weights, const T &v0, const T &v1, const T &v2, const T &v3)
int edge_other_vert(const int2 edge, const int vert)
GroupedSpan< int > build_vert_to_edge_map(Span< int2 > edges, int verts_num, Array< int > &r_offsets, Array< int > &r_indices)
void eval_vertex_data(Subdiv *subdiv, const int ptex_face_index, const float u, const float v, float r_vertex_data[])
static void subdiv_mesh_ensure_loop_interpolation(SubdivMeshContext *ctx, SubdivMeshTLS *tls, const int coarse_face_index, const int coarse_corner)
static void subdiv_mesh_ensure_vertex_interpolation(SubdivMeshContext *ctx, SubdivMeshTLS *tls, const int coarse_face_index, const int coarse_corner)
static void vertex_interpolation_init(const SubdivMeshContext *ctx, VerticesForInterpolation *vertex_interpolation, const IndexRange coarse_face)
static void subdiv_mesh_ctx_cache_uv_layers(SubdivMeshContext *ctx)
static void loop_interpolation_from_corner(const SubdivMeshContext *ctx, LoopsForInterpolation *loop_interpolation, const IndexRange coarse_face, const int corner)
static void loop_interpolation_init(const SubdivMeshContext *ctx, LoopsForInterpolation *loop_interpolation, const IndexRange coarse_face)
static void subdiv_mesh_vertex_loose(const ForeachContext *foreach_context, void *, const int coarse_vertex_index, const int subdiv_vertex_index)
float3 mesh_interpolate_position_on_edge(Span< float3 > coarse_positions, Span< int2 > coarse_edges, GroupedSpan< int > vert_to_edge_map, int coarse_edge_index, bool is_simple, float u)
static void evaluate_vertex_and_apply_displacement_copy(const SubdivMeshContext *ctx, const int ptex_face_index, const float u, const float v, const int coarse_vertex_index, const int subdiv_vertex_index)
bool foreach_subdiv_geometry(Subdiv *subdiv, const ForeachContext *context, const ToMeshSettings *mesh_settings, const Mesh *coarse_mesh)
static void subdiv_mesh_vertex_displacement_every_corner(const ForeachContext *foreach_context, void *tls, const int ptex_face_index, const float u, const float v, const int, const int, const int, const int subdiv_vertex_index)
static void subdiv_vertex_data_copy(const SubdivMeshContext *ctx, const int coarse_vertex_index, const int subdiv_vertex_index)
static void subdiv_mesh_vertex_inner(const ForeachContext *foreach_context, void *tls_v, const int ptex_face_index, const float u, const float v, const int coarse_face_index, const int coarse_corner, const int subdiv_vertex_index)
static void subdiv_mesh_vertex_of_loose_edge_interpolate(SubdivMeshContext *ctx, const int2 &coarse_edge, const float u, const int subdiv_vertex_index)
static bool subdiv_mesh_is_center_vertex(const IndexRange coarse_face, const float u, const float v)
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_face_varying(Subdiv *subdiv, int face_varying_channel, int ptex_face_index, float u, float v, float r_face_varying[2])
static void subdiv_mesh_edge(const ForeachContext *foreach_context, void *, const int coarse_edge_index, const int subdiv_edge_index, const bool, const int subdiv_v1, const int subdiv_v2)
static void subdiv_mesh_vertex_edge(const ForeachContext *foreach_context, void *tls_v, const int ptex_face_index, const float u, const float v, const int, const int coarse_face_index, const int coarse_corner, const int subdiv_vertex_index)
static void loops_of_ptex_get(LoopsOfPtex *loops_of_ptex, const IndexRange coarse_face, const int ptex_of_face_index)
static void vertex_interpolation_from_corner(const SubdivMeshContext *ctx, VerticesForInterpolation *vertex_interpolation, const IndexRange coarse_face, const int corner)
static void vertex_interpolation_end(VerticesForInterpolation *vertex_interpolation)
static void subdiv_mesh_tag_center_vertex(const IndexRange coarse_face, const int subdiv_vertex_index, const float u, const float v, Mesh *subdiv_mesh)
static void subdiv_eval_uv_layer(SubdivMeshContext *ctx, const int corner_index, const int ptex_face_index, const float u, const float v)
static void subdiv_mesh_vertex_displacement_every_edge(const ForeachContext *foreach_context, void *tls, const int ptex_face_index, const float u, const float v, const int, const int, const int, const int subdiv_vertex_index)
static void setup_foreach_callbacks(const SubdivDeformContext *subdiv_context, ForeachContext *foreach_context)
static void subdiv_mesh_prepare_accumulator(SubdivDeformContext *ctx, int num_vertices)
static void subdiv_mesh_vertex_displacement_every_corner_or_edge(const ForeachContext *foreach_context, void *, const int ptex_face_index, const float u, const float v, const int subdiv_vertex_index)
@ SUBDIV_EVALUATOR_TYPE_CPU
static std::array< std::optional< int2 >, 2 > find_edge_neighbors(const Span< int2 > coarse_edges, const GroupedSpan< int > vert_to_edge_map, const int edge_index)
static void subdiv_mesh_tls_free(void *tls_v)
void stats_begin(SubdivStats *stats, StatsValue value)
static void subdiv_mesh_vertex_of_loose_edge(const ForeachContext *foreach_context, void *, const int coarse_edge_index, const float u, const int subdiv_vertex_index)
void stats_end(SubdivStats *stats, StatsValue value)
static void subdiv_mesh_vertex_corner(const ForeachContext *foreach_context, void *, const int ptex_face_index, const float u, const float v, const int coarse_vertex_index, const int, const int, const int)
static void subdiv_mesh_loop(const ForeachContext *foreach_context, void *tls_v, const int ptex_face_index, const float u, const float v, const int, const int coarse_face_index, const int coarse_corner, const int subdiv_loop_index, const int subdiv_vertex_index, const int subdiv_edge_index)
Mesh * subdiv_to_mesh(Subdiv *subdiv, const ToMeshSettings *settings, const Mesh *coarse_mesh)
static void subdiv_accumulate_vertex_displacement(SubdivDeformContext *ctx, const int ptex_face_index, const float u, const float v, int vertex_index)
static std::array< float3, 4 > find_loose_edge_interpolation_positions(const Span< float3 > coarse_positions, const int2 &coarse_edge, const std::array< std::optional< int2 >, 2 > &neighbors)
static void subdiv_vertex_orco_evaluate(const SubdivMeshContext *ctx, const int ptex_face_index, const float u, const float v, const int subdiv_vertex_index)
static bool subdiv_mesh_topology_info(const ForeachContext *foreach_context, const int, const int, const int, const int, const int *)
static void loop_interpolation_end(LoopsForInterpolation *loop_interpolation)
@ SUBDIV_STATS_SUBDIV_TO_MESH_GEOMETRY
@ SUBDIV_STATS_SUBDIV_TO_MESH
static void subdiv_mesh_ctx_cache_custom_data_layers(SubdivMeshContext *ctx)
static void subdiv_mesh_face(const ForeachContext *foreach_context, void *, const int coarse_face_index, const int subdiv_face_index, const int start_loop_index, const int)
static void subdiv_interpolate_corner_data(const SubdivMeshContext *ctx, const int subdiv_loop_index, const LoopsForInterpolation *loop_interpolation, const float u, const float v)
static void subdiv_mesh_context_free(SubdivDeformContext *ctx)
static void evaluate_vertex_and_apply_displacement_interpolate(const SubdivMeshContext *ctx, const int ptex_face_index, const float u, const float v, VerticesForInterpolation *vertex_interpolation, const int subdiv_vertex_index)
void eval_final_point(Subdiv *subdiv, int ptex_face_index, float u, float v, float r_P[3])
static void subdiv_vertex_data_interpolate(const SubdivMeshContext *ctx, const int subdiv_vertex_index, const VerticesForInterpolation *vertex_interpolation, const float u, const float v)
static void subdiv_copy_edge_data(SubdivMeshContext *ctx, const int subdiv_edge_index, const int coarse_edge_index)
Mesh * mesh_new_no_attributes(int verts_num, int edges_num, int faces_num, int corners_num)
T interpolate(const T &a, const T &b, const FactorT &t)
VecBase< float, 4 > float4
VecBase< int32_t, 2 > int2
VecBase< float, 2 > float2
VecBase< float, 3 > float3
MeshRuntimeHandle * runtime
void(* user_data_tls_free)(void *tls)
ForeachVertexFromEdgeCb vertex_every_edge
ForeachVertexFromCornerCb vertex_corner
ForeachTopologyInformationCb topology_info
ForeachVertexOfLooseEdgeCb vertex_of_loose_edge
ForeachVertexFromCornerCb vertex_every_corner
ForeachLooseCb vertex_loose
ForeachVertexInnerCb vertex_inner
ForeachVertexFromEdgeCb vertex_edge
size_t user_data_tls_size
const CustomData * corner_data
bool corner_data_storage_allocated
CustomData corner_data_storage
CustomData coarse_corner_data_interp
MutableSpan< int > subdiv_face_offsets
int * accumulated_counters
Array< int > vert_to_edge_indices
Array< int > vert_to_edge_offsets
GroupedSpan< int > vert_to_edge_map
Span< int2 > coarse_edges
Span< float3 > coarse_positions
const ToMeshSettings * settings
int * subdiv_corner_verts
float2 * uv_layers[MAX_MTFACE]
MutableSpan< int2 > subdiv_edges
OffsetIndices< int > coarse_faces
Array< bool > subdiv_display_edges
MutableSpan< float3 > subdiv_positions
int * subdiv_corner_edges
Span< int > coarse_corner_verts
int vertex_interpolation_coarse_corner
int loop_interpolation_coarse_corner
bool loop_interpolation_initialized
bool vertex_interpolation_initialized
int vertex_interpolation_coarse_face_index
LoopsForInterpolation loop_interpolation
VerticesForInterpolation vertex_interpolation
int loop_interpolation_coarse_face_index
const CustomData * vertex_data
bool vertex_data_storage_allocated
CustomData vertex_data_storage