97 for (
int layer_index = 0; layer_index < ctx->
num_uv_layers; layer_index++) {
121 ctx->
orco =
static_cast<float(*)[3]
>(
162 const int ptex_of_face_index)
164 const int first_ptex_loop_index = coarse_face.
start() + ptex_of_face_index;
169 const int last_ptex_loop_index = coarse_face.
start() +
170 (ptex_of_face_index + coarse_face.
size() - 1) %
172 loops_of_ptex->
first_loop = first_ptex_loop_index;
173 loops_of_ptex->
last_loop = last_ptex_loop_index;
174 if (coarse_face.
size() == 4) {
219 if (coarse_face.
size() == 4) {
243 const float weight = 1.0f /
float(coarse_face.
size());
246 for (
int i = 0; i < coarse_face.
size(); i++) {
265 if (coarse_face.
size() == 4) {
283 const float weights[2] = {0.5f, 0.5f};
284 const int first_loop_index = loops_of_ptex.
first_loop;
285 const int last_loop_index = loops_of_ptex.
last_loop;
286 const int first_indices[2] = {
289 (first_loop_index - coarse_face.
start() + 1) %
290 coarse_face.
size()]};
348 if (coarse_face.
size() == 4) {
372 const float weight = 1.0f /
float(coarse_face.
size());
375 for (
int i = 0; i < coarse_face.
size(); i++) {
377 indices[i] = coarse_face.
start() + i;
394 if (coarse_face.
size() == 4) {
410 const float weights[2] = {0.5f, 0.5f};
411 const int base_loop_index = coarse_face.
start();
412 const int first_loop_index = loops_of_ptex.
first_loop;
413 const int second_loop_index = base_loop_index +
414 (first_loop_index - base_loop_index + 1) % coarse_face.
size();
415 const int first_indices[2] = {first_loop_index, second_loop_index};
477 const int ptex_face_index,
480 const int subdiv_vertex_index)
483 float vertex_data[6];
505 const int ptex_face_index,
508 const int subdiv_vertex_index)
512 float dummy_P[3], dPdu[3], dPdv[3], D[3];
532 const int num_vertices,
541 mask.
lmask &= ~CD_MASK_MULTIRES_GRIDS;
547 num_vertices, num_edges, num_faces, num_loops);
560 if (num_faces != 0) {
561 subdiv_mesh.face_offsets_for_write().last() = num_loops;
588 subdiv_mesh.
runtime->subsurf_face_dot_tags.clear();
589 subdiv_mesh.
runtime->subsurf_face_dot_tags.resize(num_vertices);
603 const int coarse_vertex_index,
604 const int subdiv_vertex_index)
615 const int subdiv_vertex_index,
620 const float weights[4] = {(1.0f - u) * (1.0f -
v), u * (1.0f -
v), u *
v, (1.0f - u) *
v};
627 subdiv_vertex_index);
634 const int ptex_face_index,
637 const int coarse_vertex_index,
638 const int subdiv_vertex_index)
643 float D[3] = {0.0f, 0.0f, 0.0f};
653 subdiv_position +=
D;
662 const int ptex_face_index,
666 const int subdiv_vertex_index)
671 float D[3] = {0.0f, 0.0f, 0.0f};
689 const int ptex_face_index,
692 const int subdiv_vertex_index)
700 const int ptex_face_index,
706 const int subdiv_vertex_index)
709 foreach_context, tls, ptex_face_index, u,
v, subdiv_vertex_index);
714 const int ptex_face_index,
720 const int subdiv_vertex_index)
723 foreach_context, tls, ptex_face_index, u,
v, subdiv_vertex_index);
728 const int ptex_face_index,
731 const int coarse_vertex_index,
734 const int subdiv_vertex_index)
739 ctx, ptex_face_index, u,
v, coarse_vertex_index, subdiv_vertex_index);
744 const int coarse_face_index,
745 const int coarse_corner)
775 const int ptex_face_index,
779 const int coarse_face_index,
780 const int coarse_corner,
781 const int subdiv_vertex_index)
794 if (coarse_face.
size() == 4) {
795 if (u == 0.5f &&
v == 0.5f) {
800 if (u == 1.0f &&
v == 1.0f) {
808 const int subdiv_vertex_index,
814 subdiv_mesh->
runtime->subsurf_face_dot_tags[subdiv_vertex_index].set();
820 const int ptex_face_index,
823 const int coarse_face_index,
824 const int coarse_corner,
825 const int subdiv_vertex_index)
847 const int subdiv_edge_index,
848 const int coarse_edge_index)
868 const int coarse_edge_index,
869 const int subdiv_edge_index,
887 const int subdiv_loop_index,
892 const float weights[4] = {(1.0f - u) * (1.0f -
v), u * (1.0f -
v), u *
v, (1.0f - u) *
v};
904 const int corner_index,
905 const int ptex_face_index,
913 for (
int layer_index = 0; layer_index < ctx->
num_uv_layers; layer_index++) {
915 subdiv, layer_index, ptex_face_index, u,
v, ctx->
uv_layers[layer_index][corner_index]);
921 const int coarse_face_index,
922 const int coarse_corner)
952 const int ptex_face_index,
956 const int coarse_face_index,
957 const int coarse_corner,
958 const int subdiv_loop_index,
959 const int subdiv_vertex_index,
960 const int subdiv_edge_index)
979 const int coarse_face_index,
980 const int subdiv_face_index,
981 const int start_loop_index,
1002 const int coarse_vertex_index,
1003 const int subdiv_vertex_index)
1018 const auto neighbor_edge_if_single = [&](
const int vert) -> std::optional<int2> {
1019 const Span<int> neighbors = vert_to_edge_map[vert];
1020 if (neighbors.
size() != 2) {
1021 return std::nullopt;
1023 return neighbors[0] == edge_index ? coarse_edges[neighbors[1]] : coarse_edges[neighbors[0]];
1025 const int2 edge = coarse_edges[edge_index];
1026 return {neighbor_edge_if_single(edge[0]), neighbor_edge_if_single(edge[1])};
1031 const int2 &coarse_edge,
1032 const std::array<std::optional<int2>, 2> &neighbors)
1034 std::array<float3, 4>
result;
1036 result[1] = coarse_positions[coarse_edge[0]];
1037 result[2] = coarse_positions[coarse_edge[1]];
1039 if (
const std::optional<int2> &other = neighbors[0]) {
1043 result[0] = result[1] * 2.0f - result[2];
1046 if (
const std::optional<int2> &other = neighbors[1]) {
1050 result[3] = result[2] * 2.0f - result[1];
1058 const int coarse_edge_index,
1059 const bool is_simple,
1062 const int2 edge = coarse_edges[coarse_edge_index];
1064 return math::interpolate(coarse_positions[edge[0]], coarse_positions[edge[1]], u);
1068 coarse_edges, vert_to_edge_map, coarse_edge_index);
1070 coarse_positions, edge, neighbors);
1077 const int2 &coarse_edge,
1079 const int subdiv_vertex_index)
1086 const float interpolation_weights[2] = {1.0f - u, u};
1087 const int coarse_vertex_indices[2] = {coarse_edge[0], coarse_edge[1]};
1090 coarse_vertex_indices,
1091 interpolation_weights,
1094 subdiv_vertex_index);
1102 const int coarse_edge_index,
1104 const int subdiv_vertex_index)
1112 if (!
ELEM(u, 0.0, 1.0)) {
1134 memset(foreach_context, 0,
sizeof(*foreach_context));
1178 subdiv_context.
settings = settings;
1180 subdiv_context.coarse_mesh = coarse_mesh;
1181 subdiv_context.coarse_positions = coarse_mesh->vert_positions();
1182 subdiv_context.coarse_edges = coarse_mesh->edges();
1183 subdiv_context.coarse_faces = coarse_mesh->faces();
1184 subdiv_context.coarse_corner_verts = coarse_mesh->corner_verts();
1185 if (coarse_mesh->loose_edges().count > 0) {
1187 subdiv_context.coarse_edges,
1189 subdiv_context.vert_to_edge_offsets,
1190 subdiv_context.vert_to_edge_indices);
1193 subdiv_context.subdiv = subdiv;
1200 foreach_context.
user_data = &subdiv_context;
1205 Mesh *result = subdiv_context.subdiv_mesh;
1209 subdiv_context.subdiv_corner_verts,
1210 result->corners_num,
1213 subdiv_context.subdiv_corner_verts =
nullptr;
1216 subdiv_context.subdiv_corner_edges,
1217 result->corners_num,
1220 subdiv_context.subdiv_corner_edges =
nullptr;
1228 if (!subdiv_context.subdiv_display_edges.is_empty()) {
1229 result->runtime->subsurf_optimal_display_edges =
BitVector<>(
1230 subdiv_context.subdiv_display_edges);
1233 if (coarse_mesh->verts_no_face().count == 0) {
1234 result->tag_loose_verts_none();
1236 if (coarse_mesh->loose_edges().count == 0) {
1237 result->tag_loose_edges_none();
1239 result->tag_overlapping_none();
1243 result->runtime->bounds_cache = coarse_mesh->
runtime->bounds_cache;
CustomData interface, see also DNA_customdata_types.h.
const CustomData_MeshMasks CD_MASK_EVERYTHING
bool CustomData_free_layer_named(CustomData *data, blender::StringRef name, const int totelem)
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_init_from(const CustomData *source, CustomData *dest, eCustomDataMask mask, int totelem)
void CustomData_free(CustomData *data, 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)
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], int 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
draw_view in_light_buf[] float
void *(* MEM_malloc_arrayN)(size_t len, size_t size, const char *str)
void *(* MEM_calloc_arrayN)(size_t len, size_t size, const char *str)
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)
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
Displacement * displacement_evaluator
const CustomData * vertex_data
bool vertex_data_storage_allocated
CustomData vertex_data_storage