95 for (
int layer_index = 0; layer_index < ctx->
num_uv_layers; layer_index++) {
119 ctx->
orco =
static_cast<float (*)[3]
>(
159 const int ptex_of_face_index)
161 const int first_ptex_loop_index = coarse_face.
start() + ptex_of_face_index;
166 const int last_ptex_loop_index = coarse_face.
start() +
167 (ptex_of_face_index + coarse_face.
size() - 1) %
169 loops_of_ptex->
first_loop = first_ptex_loop_index;
170 loops_of_ptex->
last_loop = last_ptex_loop_index;
171 if (coarse_face.
size() == 4) {
216 if (coarse_face.
size() == 4) {
240 const float weight = 1.0f /
float(coarse_face.
size());
243 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()]};
334 if (coarse_face.
size() == 4) {
358 const float weight = 1.0f /
float(coarse_face.
size());
361 for (
int i = 0;
i < coarse_face.
size();
i++) {
379 if (coarse_face.
size() == 4) {
395 const float weights[2] = {0.5f, 0.5f};
396 const int base_loop_index = coarse_face.
start();
397 const int first_loop_index = loops_of_ptex.
first_loop;
398 const int second_loop_index = base_loop_index +
399 (first_loop_index - base_loop_index + 1) % coarse_face.
size();
400 const int first_indices[2] = {first_loop_index, second_loop_index};
452 const int ptex_face_index,
455 const int subdiv_vertex_index)
458 float vertex_data[6];
480 const int ptex_face_index,
483 const int subdiv_vertex_index)
510 const int num_vertices,
525 num_vertices, num_edges, num_faces, num_loops);
538 if (num_faces != 0) {
539 subdiv_mesh.face_offsets_for_write().last() = num_loops;
562 subdiv_mesh.
runtime->subsurf_face_dot_tags.clear();
563 subdiv_mesh.
runtime->subsurf_face_dot_tags.resize(num_vertices);
577 const int coarse_vertex_index,
578 const int subdiv_vertex_index)
589 const int subdiv_vertex_index,
594 const float weights[4] = {(1.0f - u) * (1.0f -
v), u * (1.0f -
v), u *
v, (1.0f - u) *
v};
600 subdiv_vertex_index);
607 const int ptex_face_index,
610 const int coarse_vertex_index,
611 const int subdiv_vertex_index)
616 float D[3] = {0.0f, 0.0f, 0.0f};
626 subdiv_position +=
D;
635 const int ptex_face_index,
639 const int subdiv_vertex_index)
644 float D[3] = {0.0f, 0.0f, 0.0f};
662 const int ptex_face_index,
665 const int subdiv_vertex_index)
673 const int ptex_face_index,
679 const int subdiv_vertex_index)
682 foreach_context, tls, ptex_face_index, u,
v, subdiv_vertex_index);
687 const int ptex_face_index,
693 const int subdiv_vertex_index)
696 foreach_context, tls, ptex_face_index, u,
v, subdiv_vertex_index);
701 const int ptex_face_index,
704 const int coarse_vertex_index,
707 const int subdiv_vertex_index)
712 ctx, ptex_face_index, u,
v, coarse_vertex_index, subdiv_vertex_index);
717 const int coarse_face_index,
718 const int coarse_corner)
748 const int ptex_face_index,
752 const int coarse_face_index,
753 const int coarse_corner,
754 const int subdiv_vertex_index)
767 if (coarse_face.
size() == 4) {
768 if (u == 0.5f &&
v == 0.5f) {
773 if (u == 1.0f &&
v == 1.0f) {
781 const int subdiv_vertex_index,
787 subdiv_mesh->
runtime->subsurf_face_dot_tags[subdiv_vertex_index].set();
793 const int ptex_face_index,
796 const int coarse_face_index,
797 const int coarse_corner,
798 const int subdiv_vertex_index)
819 const int subdiv_edge_index,
820 const int coarse_edge_index)
840 const int coarse_edge_index,
841 const int subdiv_edge_index,
859 const int subdiv_loop_index,
864 const float weights[4] = {(1.0f - u) * (1.0f -
v), u * (1.0f -
v), u *
v, (1.0f - u) *
v};
875 const int corner_index,
876 const int ptex_face_index,
884 for (
int layer_index = 0; layer_index < ctx->
num_uv_layers; layer_index++) {
886 subdiv, layer_index, ptex_face_index, u,
v, ctx->
uv_layers[layer_index][corner_index]);
892 const int coarse_face_index,
893 const int coarse_corner)
923 const int ptex_face_index,
927 const int coarse_face_index,
928 const int coarse_corner,
929 const int subdiv_loop_index,
930 const int subdiv_vertex_index,
931 const int subdiv_edge_index)
950 const int coarse_face_index,
951 const int subdiv_face_index,
952 const int start_loop_index,
973 const int coarse_vertex_index,
974 const int subdiv_vertex_index)
989 const auto neighbor_edge_if_single = [&](
const int vert) -> std::optional<int2> {
990 const Span<int> neighbors = vert_to_edge_map[vert];
991 if (neighbors.
size() != 2) {
994 return neighbors[0] == edge_index ? coarse_edges[neighbors[1]] : coarse_edges[neighbors[0]];
996 const int2 edge = coarse_edges[edge_index];
997 return {neighbor_edge_if_single(edge[0]), neighbor_edge_if_single(edge[1])};
1002 const int2 &coarse_edge,
1003 const std::array<std::optional<int2>, 2> &neighbors)
1005 std::array<float3, 4>
result;
1007 result[1] = coarse_positions[coarse_edge[0]];
1008 result[2] = coarse_positions[coarse_edge[1]];
1010 if (
const std::optional<int2> &other = neighbors[0]) {
1017 if (
const std::optional<int2> &other = neighbors[1]) {
1029 const int coarse_edge_index,
1030 const bool is_simple,
1033 const int2 edge = coarse_edges[coarse_edge_index];
1035 return math::interpolate(coarse_positions[edge[0]], coarse_positions[edge[1]], u);
1039 coarse_edges, vert_to_edge_map, coarse_edge_index);
1041 coarse_positions, edge, neighbors);
1048 const int2 &coarse_edge,
1050 const int subdiv_vertex_index)
1057 const float interpolation_weights[2] = {1.0f - u, u};
1058 const int coarse_vertex_indices[2] = {coarse_edge[0], coarse_edge[1]};
1061 coarse_vertex_indices,
1062 interpolation_weights,
1064 subdiv_vertex_index);
1072 const int coarse_edge_index,
1074 const int subdiv_vertex_index)
1082 if (!
ELEM(u, 0.0, 1.0)) {
1104 *foreach_context = {};
1147 subdiv_context.
settings = settings;
1154 if (coarse_mesh->loose_edges().count > 0) {
1169 foreach_context.
user_data = &subdiv_context;
1202 if (coarse_mesh->verts_no_face().count == 0) {
1203 result->tag_loose_verts_none();
1205 if (coarse_mesh->loose_edges().count == 0) {
1206 result->tag_loose_edges_none();
1208 result->tag_overlapping_none();
1210 if (
subdiv->settings.is_simple) {
1212 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_free(CustomData *data)
void CustomData_init_from(const CustomData *source, CustomData *dest, eCustomDataMask mask, int totelem)
void CustomData_interp(const CustomData *source, CustomData *dest, const int *src_indices, const float *weights, int count, int dest_index)
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])
#define CD_MASK_MULTIRES_GRIDS
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
constexpr void copy_from(Span< T > values) const
constexpr int64_t size() const
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 free(Subdiv *subdiv)
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)
float3 eval_final_point(Subdiv *subdiv, int ptex_face_index, float u, float v)
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)
@ SUBDIV_VTX_BOUNDARY_EDGE_ONLY
static void loop_interpolation_from_corner(const SubdivMeshContext *ctx, LoopsForInterpolation *loop_interpolation, const IndexRange coarse_face, const int corner)
bool eval_begin_from_mesh(Subdiv *subdiv, const Mesh *mesh, eSubdivEvaluatorType evaluator_type, Span< float3 > coarse_vert_positions={}, OpenSubdiv_EvaluatorCache *evaluator_cache=nullptr)
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)
float3 eval_limit_point(Subdiv *subdiv, int ptex_face_index, float u, float v)
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)
void calculate_limit_positions(Mesh *mesh, MutableSpan< float3 > limit_positions)
static bool subdiv_mesh_is_center_vertex(const IndexRange coarse_face, const float u, const float v)
@ SUBDIV_FVAR_LINEAR_INTERPOLATION_CORNERS_AND_JUNCTIONS
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)
void deform_coarse_vertices(Subdiv *subdiv, const Mesh *coarse_mesh, MutableSpan< float3 > vert_positions)
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)
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)
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)
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_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)
void eval_face_varying(Subdiv *subdiv, int face_varying_channel, int ptex_face_index, float u, float v, float2 &r_face_varying)
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)
void eval_vertex_data(Subdiv *subdiv, int ptex_face_index, float u, float v, float r_vertex_data[])
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
Subdiv * update_from_mesh(Subdiv *subdiv, const Settings *settings, const Mesh *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)
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
VtxBoundaryInterpolation vtx_boundary_interpolation
FVarLinearInterpolation fvar_linear_interpolation
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