56 blender::Array<SurfacePoint> points = {};
65 blender::Vector<GridCoord> grid_coords = {};
67 float sharpness = 0.0f;
68 bool is_infinite_sharp =
false;
81 float sharpness = 0.0f;
86struct LinearGridElement {
92 blender::MutableSpan<LinearGridElement> elements = {};
103 blender::Array<LinearGrid> grids;
106 blender::Array<LinearGridElement> elements_storage;
112 const MultiresReshapeContext *reshape_context;
116 blender::Array<Vertex> vertices;
126 blender::Array<Edge> edges;
128 blender::Array<Corner>
corners;
131 blender::Array<int> face_offsets;
133 blender::OffsetIndices<int>
faces()
const
135 return blender::OffsetIndices<int>(face_offsets, blender::offset_indices::NoSortCheck());
141 LinearGrids linear_delta_grids;
144 blender::BitSpan loose_base_edges = {};
147 blender::bke::subdiv::Subdiv *reshape_subdiv =
nullptr;
157 blender::Array<SurfaceGrid> base_surface_grids;
167 MultiresReshapeSmoothContext(
const MultiresReshapeContext *reshape_context,
169 : reshape_context(reshape_context),
171 linear_delta_grids(),
172 smoothing_type(smoothing_type)
175 ~MultiresReshapeSmoothContext();
178MultiresReshapeSmoothContext::~MultiresReshapeSmoothContext()
180 if (this->reshape_subdiv ==
nullptr) {
192static void linear_grids_allocate(LinearGrids *linear_grids,
int num_grids,
int level)
195 const size_t grid_area = grid_size * grid_size;
196 const size_t num_grid_elements = num_grids * grid_area;
198 linear_grids->num_grids = num_grids;
199 linear_grids->level = level;
200 linear_grids->grid_size = grid_size;
202 linear_grids->grids.reinitialize(num_grids);
203 linear_grids->elements_storage.reinitialize(num_grid_elements);
205 for (
int i = 0;
i < num_grids; ++
i) {
206 const size_t element_offset = grid_area *
i;
207 linear_grids->grids[
i].elements = linear_grids->elements_storage.as_mutable_span().slice(
208 element_offset, grid_area);
212static LinearGridElement *linear_grid_element_get(LinearGrids *linear_grids,
218 const int grid_size = linear_grids->grid_size;
220 const int grid_x = lround(grid_coord->
u * (grid_size - 1));
221 const int grid_y = lround(grid_coord->
v * (grid_size - 1));
222 const int grid_element_index = grid_y * grid_size + grid_x;
224 LinearGrid *grid = &linear_grids->grids[grid_coord->
grid_index];
225 return &grid->elements[grid_element_index];
228static void linear_grid_element_init(LinearGridElement *linear_grid_element)
230 linear_grid_element->mask = 0.0f;
234static void linear_grid_element_sub(LinearGridElement *
result,
235 const LinearGridElement *a,
236 const LinearGridElement *
b)
238 result->mask = a->mask -
b->mask;
241static void linear_grid_element_interpolate(LinearGridElement *
result,
242 const LinearGridElement elements[4],
243 const float weights[4])
245 result->mask = elements[0].mask * weights[0] + elements[1].mask * weights[1] +
246 elements[2].mask * weights[2] + elements[3].mask * weights[3];
255static void base_surface_grids_allocate(MultiresReshapeSmoothContext *reshape_smooth_context)
259 const int num_grids = reshape_context->
num_grids;
261 const int grid_area = grid_size * grid_size;
263 reshape_smooth_context->base_surface_grids.reinitialize(num_grids);
265 for (
const int i : reshape_smooth_context->base_surface_grids.index_range()) {
266 reshape_smooth_context->base_surface_grids[
i].points.reinitialize(grid_area);
270static SurfacePoint *base_surface_grids_read(MultiresReshapeSmoothContext *reshape_smooth_context,
275 const int grid_index = grid_coord->
grid_index;
277 const int grid_x = lround(grid_coord->
u * (grid_size - 1));
278 const int grid_y = lround(grid_coord->
v * (grid_size - 1));
279 const int grid_element_index = grid_y * grid_size + grid_x;
281 SurfaceGrid *surface_grid = &reshape_smooth_context->base_surface_grids[grid_index];
282 return &surface_grid->points[grid_element_index];
285static void base_surface_grids_write(MultiresReshapeSmoothContext *reshape_smooth_context,
290 SurfacePoint *point = base_surface_grids_read(reshape_smooth_context, grid_coord);
292 point->tangent_matrix = tangent_matrix;
302static int get_face_grid_index(
const MultiresReshapeSmoothContext *reshape_smooth_context,
305 const Corner *first_corner = &reshape_smooth_context->geometry.corners[face.
start()];
306 const int grid_index = first_corner->grid_index;
309 for (
const int corner_index : face) {
310 const Corner *corner = &reshape_smooth_context->geometry.corners[corner_index];
318static std::optional<GridCoord> vertex_grid_coord_with_grid_index(
const Vertex *vertex,
319 const int grid_index)
321 for (
const int i : vertex->grid_coords.index_range()) {
322 if (vertex->grid_coords[
i].grid_index == grid_index) {
323 return vertex->grid_coords[
i];
331static std::array<std::optional<GridCoord>, 4> grid_coords_from_face_verts(
334 std::array<std::optional<GridCoord>, 4>
result;
337 const int grid_index = get_face_grid_index(reshape_smooth_context, face);
341 const int corner_index = face[
i];
342 Corner *corner = &reshape_smooth_context->geometry.corners[corner_index];
343 result[
i] = vertex_grid_coord_with_grid_index(
344 &reshape_smooth_context->geometry.vertices[corner->vert_index], grid_index);
354static float lerp_f(
float t,
float a,
float b)
356 return (a + t * (
b - a));
376 const float u01 = lerp_f(u, face_grid_coords[0]->u, face_grid_coords[1]->u);
377 const float u32 = lerp_f(u, face_grid_coords[3]->u, face_grid_coords[2]->u);
379 const float v03 = lerp_f(
v, face_grid_coords[0]->
v, face_grid_coords[3]->
v);
380 const float v12 = lerp_f(
v, face_grid_coords[1]->
v, face_grid_coords[2]->
v);
382 result.grid_index = face_grid_coords[0]->grid_index;
383 result.u = lerp_f(
v, u01, u32);
384 result.v = lerp_f(u, v03, v12);
389static void foreach_toplevel_grid_coord(
390 MultiresReshapeSmoothContext *reshape_smooth_context,
397 const int inner_grid_size = (1 << level_difference) + 1;
398 const float inner_grid_size_1_inv = 1.0f /
float(inner_grid_size - 1);
402 for (const int face_index : range) {
403 const blender::IndexRange face = faces[face_index];
404 std::array<std::optional<GridCoord>, 4> face_grid_coords = grid_coords_from_face_verts(
405 reshape_smooth_context, face);
407 for (int y = 0; y < inner_grid_size; ++y) {
408 const float ptex_v = float(y) * inner_grid_size_1_inv;
409 for (int x = 0; x < inner_grid_size; ++x) {
410 const float ptex_u = float(x) * inner_grid_size_1_inv;
412 PTexCoord ptex_coord;
413 ptex_coord.ptex_face_index = face_index;
414 ptex_coord.u = ptex_u;
415 ptex_coord.v = ptex_v;
417 const GridCoord grid_coord = interpolate_grid_coord(
418 blender::Span(face_grid_coords), ptex_u, ptex_v);
420 callback(&ptex_coord, &grid_coord);
441static bool is_crease_supported(
const MultiresReshapeSmoothContext *reshape_smooth_context)
443 return !
ELEM(reshape_smooth_context->smoothing_type,
450static float get_effective_crease(
const MultiresReshapeSmoothContext *reshape_smooth_context,
451 const int base_edge_index)
453 if (!is_crease_supported(reshape_smooth_context)) {
456 if (reshape_smooth_context->reshape_context->cd_edge_crease.is_empty()) {
459 return reshape_smooth_context->reshape_context->cd_edge_crease[base_edge_index];
462static float get_effective_crease_float(
const MultiresReshapeSmoothContext *reshape_smooth_context,
465 if (!is_crease_supported(reshape_smooth_context)) {
472 const int num_vertices,
478 MultiresReshapeSmoothContext *reshape_smooth_context =
479 static_cast<MultiresReshapeSmoothContext *
>(foreach_context->
user_data);
480 const int max_edges = reshape_smooth_context->smoothing_type ==
483 reshape_smooth_context->geometry.max_edges;
485 reshape_smooth_context->geometry.vertices.reinitialize(num_vertices);
487 reshape_smooth_context->geometry.max_edges = max_edges;
488 reshape_smooth_context->geometry.edges.reinitialize(max_edges);
490 reshape_smooth_context->geometry.corners.reinitialize(num_loops);
492 reshape_smooth_context->geometry.face_offsets.reinitialize(num_faces + 1);
493 reshape_smooth_context->geometry.face_offsets.last() = num_loops;
500 const int coarse_vertex_index,
501 const int subdiv_vertex_index)
503 MultiresReshapeSmoothContext *reshape_smooth_context =
504 static_cast<MultiresReshapeSmoothContext *
>(foreach_context->
user_data);
508 Vertex *vertex = &reshape_smooth_context->geometry.vertices[subdiv_vertex_index];
510 vertex->grid_coords.append(*grid_coord);
512 if (coarse_vertex_index == -1) {
522 if (crease == 0.0f) {
526 crease = get_effective_crease_float(reshape_smooth_context, crease);
533 const int coarse_vertex_index,
534 const int subdiv_vertex_index)
536 const MultiresReshapeSmoothContext *reshape_smooth_context =
537 static_cast<const MultiresReshapeSmoothContext *
>(foreach_context->
user_data);
544 const int num_corners = reshape_context->
base_faces[face_index].size();
546 const int corner = grid_coord.
grid_index - start_grid_index;
548 if (grid_coord.
u == 0.0f && grid_coord.
v == 0.0f) {
549 for (
int current_corner = 0; current_corner < num_corners; ++current_corner) {
550 GridCoord corner_grid_coord = grid_coord;
551 corner_grid_coord.
grid_index = start_grid_index + current_corner;
552 foreach_single_vertex(
553 foreach_context, &corner_grid_coord, coarse_vertex_index, subdiv_vertex_index);
558 foreach_single_vertex(foreach_context, &grid_coord, coarse_vertex_index, subdiv_vertex_index);
560 if (grid_coord.
u == 0.0f) {
562 prev_grid_coord.
grid_index = start_grid_index + ((corner + num_corners - 1) % num_corners);
563 prev_grid_coord.
u = grid_coord.
v;
564 prev_grid_coord.
v = 0.0f;
566 foreach_single_vertex(
567 foreach_context, &prev_grid_coord, coarse_vertex_index, subdiv_vertex_index);
570 if (grid_coord.
v == 0.0f) {
572 next_grid_coord.
grid_index = start_grid_index + ((corner + 1) % num_corners);
573 next_grid_coord.
u = 0.0f;
574 next_grid_coord.
v = grid_coord.
u;
576 foreach_single_vertex(
577 foreach_context, &next_grid_coord, coarse_vertex_index, subdiv_vertex_index);
583 const int ptex_face_index,
584 const float ptex_face_u,
585 const float ptex_face_v,
588 const int subdiv_vertex_index)
592 ptex_coord.
u = ptex_face_u;
593 ptex_coord.
v = ptex_face_v;
594 foreach_vertex(foreach_context, &ptex_coord, -1, subdiv_vertex_index);
597static void foreach_vertex_every_corner(
600 const int ptex_face_index,
601 const float ptex_face_u,
602 const float ptex_face_v,
603 const int coarse_vertex_index,
606 const int subdiv_vertex_index)
610 ptex_coord.
u = ptex_face_u;
611 ptex_coord.
v = ptex_face_v;
612 foreach_vertex(foreach_context, &ptex_coord, coarse_vertex_index, subdiv_vertex_index);
617 const int ptex_face_index,
618 const float ptex_face_u,
619 const float ptex_face_v,
623 const int subdiv_vertex_index)
627 ptex_coord.
u = ptex_face_u;
628 ptex_coord.
v = ptex_face_v;
629 foreach_vertex(foreach_context, &ptex_coord, -1, subdiv_vertex_index);
638 const int coarse_face_index,
639 const int coarse_corner,
640 const int subdiv_loop_index,
641 const int subdiv_vertex_index,
644 MultiresReshapeSmoothContext *reshape_smooth_context =
645 static_cast<MultiresReshapeSmoothContext *
>(foreach_context->
user_data);
650 Corner *corner = &reshape_smooth_context->geometry.corners[subdiv_loop_index];
651 corner->vert_index = subdiv_vertex_index;
654 corner->grid_index = first_grid_index + coarse_corner;
660 const int subdiv_face_index,
661 const int start_loop_index,
664 MultiresReshapeSmoothContext *reshape_smooth_context =
665 static_cast<MultiresReshapeSmoothContext *
>(foreach_context->
user_data);
669 reshape_smooth_context->geometry.face_offsets[subdiv_face_index] = start_loop_index;
672static void foreach_vertex_of_loose_edge(
677 const int vertex_index)
679 MultiresReshapeSmoothContext *reshape_smooth_context =
680 static_cast<MultiresReshapeSmoothContext *
>(foreach_context->
user_data);
681 Vertex *vertex = &reshape_smooth_context->geometry.vertices[vertex_index];
683 vertex->is_infinite_sharp = !vertex->grid_coords.is_empty();
686static void store_edge(MultiresReshapeSmoothContext *reshape_smooth_context,
696 Edge *edge = &reshape_smooth_context->geometry.edges[edge_index];
697 edge->v1 = subdiv_v1;
698 edge->v2 = subdiv_v2;
704 const int coarse_edge_index,
710 MultiresReshapeSmoothContext *reshape_smooth_context =
711 static_cast<MultiresReshapeSmoothContext *
>(foreach_context->
user_data);
715 store_edge(reshape_smooth_context, subdiv_v1, subdiv_v2, 1.0f);
725 if (!reshape_smooth_context->loose_base_edges.is_empty()) {
726 if (reshape_smooth_context->loose_base_edges[coarse_edge_index]) {
731 const float crease = get_effective_crease(reshape_smooth_context, coarse_edge_index);
732 if (crease == 0.0f) {
735 store_edge(reshape_smooth_context, subdiv_v1, subdiv_v2, crease);
738static void geometry_init_loose_information(MultiresReshapeSmoothContext *reshape_smooth_context)
744 reshape_smooth_context->loose_base_edges = loose_edges.
is_loose_bits;
746 int num_used_edges = 0;
751 const float crease = get_effective_crease(reshape_smooth_context, edge);
752 if (crease == 0.0f) {
758 const int resolution = get_reshape_level_resolution(reshape_context);
759 const int num_subdiv_vertices_per_base_edge = resolution - 2;
760 reshape_smooth_context->geometry.max_edges = num_used_edges *
761 (num_subdiv_vertices_per_base_edge + 1);
764static void geometry_create(MultiresReshapeSmoothContext *reshape_smooth_context)
773 foreach_context.
loop = foreach_loop;
774 foreach_context.
poly = foreach_poly;
776 foreach_context.
edge = foreach_edge;
777 foreach_context.
user_data = reshape_smooth_context;
779 geometry_init_loose_information(reshape_smooth_context);
782 mesh_settings.
resolution = get_reshape_level_resolution(reshape_context);
787 reshape_context->
subdiv, &foreach_context, &mesh_settings, reshape_context->
base_mesh);
804 const MultiresReshapeSmoothContext *reshape_smooth_context =
805 static_cast<const MultiresReshapeSmoothContext *
>(converter->
user_data);
816 const MultiresReshapeSmoothContext *reshape_smooth_context =
817 static_cast<const MultiresReshapeSmoothContext *
>(converter->
user_data);
832 const MultiresReshapeSmoothContext *reshape_smooth_context =
833 static_cast<const MultiresReshapeSmoothContext *
>(converter->
user_data);
835 return reshape_smooth_context->geometry.vertices.size();
842 const MultiresReshapeSmoothContext *reshape_smooth_context =
843 static_cast<const MultiresReshapeSmoothContext *
>(converter->
user_data);
849 const int corner_index = face[
i];
850 const Corner *corner = &reshape_smooth_context->geometry.corners[corner_index];
851 face_vertices[
i] = corner->vert_index;
857 const MultiresReshapeSmoothContext *reshape_smooth_context =
858 static_cast<const MultiresReshapeSmoothContext *
>(converter->
user_data);
859 return reshape_smooth_context->geometry.num_edges;
863 const int edge_index,
864 int edge_vertices[2])
866 const MultiresReshapeSmoothContext *reshape_smooth_context =
867 static_cast<const MultiresReshapeSmoothContext *
>(converter->
user_data);
870 const Edge *edge = &reshape_smooth_context->geometry.edges[edge_index];
871 edge_vertices[0] = edge->v1;
872 edge_vertices[1] = edge->v2;
877 const MultiresReshapeSmoothContext *reshape_smooth_context =
878 static_cast<const MultiresReshapeSmoothContext *
>(converter->
user_data);
881 const Edge *edge = &reshape_smooth_context->geometry.edges[edge_index];
882 return edge->sharpness;
887 const MultiresReshapeSmoothContext *reshape_smooth_context =
888 static_cast<const MultiresReshapeSmoothContext *
>(converter->
user_data);
891 const Vertex *vertex = &reshape_smooth_context->geometry.vertices[vertex_index];
892 return vertex->sharpness;
897 const MultiresReshapeSmoothContext *reshape_smooth_context =
898 static_cast<const MultiresReshapeSmoothContext *
>(converter->
user_data);
902 const Vertex *vertex = &reshape_smooth_context->geometry.vertices[vertex_index];
903 return vertex->is_infinite_sharp;
906static void converter_init(
const MultiresReshapeSmoothContext *reshape_smooth_context,
914 converter->
faces = reshape_smooth_context->geometry.faces();
942 converter->
user_data = (
void *)reshape_smooth_context;
946static void reshape_subdiv_create(MultiresReshapeSmoothContext *reshape_smooth_context)
952 converter_init(reshape_smooth_context, &converter);
955 settings, &converter);
961 &evaluator_settings);
963 reshape_smooth_context->reshape_subdiv = reshape_subdiv;
969using ReshapeSubdivCoarsePositionCb =
970 void(
const MultiresReshapeSmoothContext *reshape_smooth_context,
975static void reshape_subdiv_refine(
const MultiresReshapeSmoothContext *reshape_smooth_context,
976 ReshapeSubdivCoarsePositionCb coarse_position_cb)
982 const int num_vertices = reshape_smooth_context->geometry.vertices.size();
983 for (
int i = 0;
i < num_vertices; ++
i) {
984 const Vertex *vertex = &reshape_smooth_context->geometry.vertices[
i];
986 coarse_position_cb(reshape_smooth_context, vertex,
P);
994 if (vertex->grid_coords.is_empty()) {
1002 return &vertex->grid_coords[0];
1006static void reshape_subdiv_refine_orig_P(
1007 const MultiresReshapeSmoothContext *reshape_smooth_context,
1012 const GridCoord *grid_coord = reshape_subdiv_refine_vertex_grid_coord(vertex);
1015 if (grid_coord ==
nullptr) {
1023 reshape_context, grid_coord, limit_P, tangent_matrix);
1033static void reshape_subdiv_refine_orig(
const MultiresReshapeSmoothContext *reshape_smooth_context)
1035 reshape_subdiv_refine(reshape_smooth_context, reshape_subdiv_refine_orig_P);
1039static void reshape_subdiv_refine_final_P(
1040 const MultiresReshapeSmoothContext *reshape_smooth_context,
1045 const GridCoord *grid_coord = reshape_subdiv_refine_vertex_grid_coord(vertex);
1048 if (grid_coord ==
nullptr) {
1054 reshape_context, grid_coord);
1060static void reshape_subdiv_refine_final(
const MultiresReshapeSmoothContext *reshape_smooth_context)
1062 reshape_subdiv_refine(reshape_smooth_context, reshape_subdiv_refine_final_P);
1065static void reshape_subdiv_evaluate_limit_at_grid(
1066 const MultiresReshapeSmoothContext *reshape_smooth_context,
1088 reshape_context, face_index, corner, dPdu, dPdv, r_tangent_matrix);
1097static LinearGridElement linear_grid_element_orig_get(
1098 const MultiresReshapeSmoothContext *reshape_smooth_context,
const GridCoord *grid_coord)
1104 LinearGridElement linear_grid_element;
1105 linear_grid_element_init(&linear_grid_element);
1107 linear_grid_element.mask = orig_grid_element.
mask;
1109 return linear_grid_element;
1112static LinearGridElement linear_grid_element_final_get(
1113 const MultiresReshapeSmoothContext *reshape_smooth_context,
const GridCoord *grid_coord)
1117 reshape_context, grid_coord);
1119 LinearGridElement linear_grid_element;
1120 linear_grid_element_init(&linear_grid_element);
1122 if (final_grid_element.
mask !=
nullptr) {
1123 linear_grid_element.mask = *final_grid_element.
mask;
1126 return linear_grid_element;
1134static void linear_grid_element_delta_interpolate(
1135 const MultiresReshapeSmoothContext *reshape_smooth_context,
1137 LinearGridElement *
result)
1141 const int reshape_level = reshape_context->
reshape.
level;
1143 const int reshape_level_grid_size_1 = reshape_level_grid_size - 1;
1144 const float reshape_level_grid_size_1_inv = 1.0f /
float(reshape_level_grid_size_1);
1146 const float x_f = grid_coord->
u * reshape_level_grid_size_1;
1147 const float y_f = grid_coord->
v * reshape_level_grid_size_1;
1149 const int x_i = x_f;
1150 const int y_i = y_f;
1151 const int x_n_i = (x_i == reshape_level_grid_size - 1) ? (x_i) : (x_i + 1);
1152 const int y_n_i = (y_i == reshape_level_grid_size - 1) ? (y_i) : (y_i + 1);
1154 const int corners_int_coords[4][2] = {{x_i, y_i}, {x_n_i, y_i}, {x_n_i, y_n_i}, {x_i, y_n_i}};
1156 LinearGridElement corner_elements[4];
1157 for (
int i = 0;
i < 4; ++
i) {
1160 corner_grid_coord.
u = corners_int_coords[
i][0] * reshape_level_grid_size_1_inv;
1161 corner_grid_coord.
v = corners_int_coords[
i][1] * reshape_level_grid_size_1_inv;
1163 const LinearGridElement orig_element = linear_grid_element_orig_get(reshape_smooth_context,
1164 &corner_grid_coord);
1165 const LinearGridElement final_element = linear_grid_element_final_get(reshape_smooth_context,
1166 &corner_grid_coord);
1167 linear_grid_element_sub(&corner_elements[
i], &final_element, &orig_element);
1170 const float u = x_f - x_i;
1171 const float v = y_f - y_i;
1172 const float weights[4] = {(1.0f - u) * (1.0f -
v), u * (1.0f -
v), u *
v, (1.0f - u) *
v};
1174 linear_grid_element_interpolate(
result, corner_elements, weights);
1177static void evaluate_linear_delta_grids(MultiresReshapeSmoothContext *reshape_smooth_context)
1180 const int num_grids = reshape_context->
num_grids;
1181 const int top_level = reshape_context->
top.
level;
1183 linear_grids_allocate(&reshape_smooth_context->linear_delta_grids, num_grids, top_level);
1185 foreach_toplevel_grid_coord(reshape_smooth_context,
1187 LinearGridElement *linear_delta_element = linear_grid_element_get(
1188 &reshape_smooth_context->linear_delta_grids, grid_coord);
1190 linear_grid_element_delta_interpolate(
1191 reshape_smooth_context, grid_coord, linear_delta_element);
1195static void propagate_linear_data_delta(MultiresReshapeSmoothContext *reshape_smooth_context,
1201 LinearGridElement *linear_delta_element = linear_grid_element_get(
1202 &reshape_smooth_context->linear_delta_grids, grid_coord);
1207 if (final_grid_element->
mask !=
nullptr) {
1209 orig_grid_element.
mask + linear_delta_element->mask, 0.0f, 1.0f);
1219static void evaluate_base_surface_grids(MultiresReshapeSmoothContext *reshape_smooth_context)
1221 foreach_toplevel_grid_coord(
1222 reshape_smooth_context, [&](
const PTexCoord *ptex_coord,
const GridCoord *grid_coord) {
1225 reshape_subdiv_evaluate_limit_at_grid(
1226 reshape_smooth_context, ptex_coord, grid_coord, limit_P, tangent_matrix);
1228 base_surface_grids_write(reshape_smooth_context, grid_coord, limit_P, tangent_matrix);
1240static void evaluate_final_original_point(
1241 const MultiresReshapeSmoothContext *reshape_smooth_context,
1255 reshape_context, grid_coord, base_mesh_limit_P, base_mesh_tangent_matrix);
1259 base_mesh_tangent_matrix, orig_grid_element.
displacement);
1262 r_orig_final_P = base_mesh_limit_P + orig_displacement;
1265static void evaluate_higher_grid_positions_with_details(
1266 MultiresReshapeSmoothContext *reshape_smooth_context)
1269 foreach_toplevel_grid_coord(
1270 reshape_smooth_context, [&](
const PTexCoord *ptex_coord,
const GridCoord *grid_coord) {
1273 evaluate_final_original_point(reshape_smooth_context, grid_coord, orig_final_P);
1276 const SurfacePoint *orig_sculpt_point = base_surface_grids_read(reshape_smooth_context,
1280 const blender::float3 original_detail_delta = orig_final_P - orig_sculpt_point->P;
1285 orig_sculpt_point->tangent_matrix);
1287 original_sculpt_tangent_matrix_inv, original_detail_delta);
1292 reshape_subdiv_evaluate_limit_at_grid(
1293 reshape_smooth_context, ptex_coord, grid_coord, smooth_limit_P, smooth_tangent_matrix);
1297 smooth_tangent_matrix, original_detail_delta_tangent);
1303 reshape_context, grid_coord);
1305 *grid_element.
displacement = smooth_limit_P + smooth_delta;
1308 propagate_linear_data_delta(reshape_smooth_context, &grid_element, grid_coord);
1312static void evaluate_higher_grid_positions(MultiresReshapeSmoothContext *reshape_smooth_context)
1315 foreach_toplevel_grid_coord(
1316 reshape_smooth_context, [&](
const PTexCoord *ptex_coord,
const GridCoord *grid_coord) {
1320 reshape_context, grid_coord);
1329 propagate_linear_data_delta(reshape_smooth_context, &grid_element, grid_coord);
1344#ifdef WITH_OPENSUBDIV
1346 if (level_difference == 0) {
1354 MultiresReshapeSmoothContext reshape_smooth_context(reshape_context, smoothing_type);
1355 geometry_create(&reshape_smooth_context);
1356 evaluate_linear_delta_grids(&reshape_smooth_context);
1358 reshape_subdiv_create(&reshape_smooth_context);
1360 base_surface_grids_allocate(&reshape_smooth_context);
1361 reshape_subdiv_refine_orig(&reshape_smooth_context);
1362 evaluate_base_surface_grids(&reshape_smooth_context);
1364 reshape_subdiv_refine_final(&reshape_smooth_context);
1365 evaluate_higher_grid_positions_with_details(&reshape_smooth_context);
1374#ifdef WITH_OPENSUBDIV
1376 if (level_difference == 0) {
1381 MultiresReshapeSmoothContext reshape_smooth_context(reshape_context, mode);
1382 geometry_create(&reshape_smooth_context);
1383 evaluate_linear_delta_grids(&reshape_smooth_context);
1385 reshape_subdiv_create(&reshape_smooth_context);
1387 reshape_subdiv_refine_final(&reshape_smooth_context);
1388 evaluate_higher_grid_positions(&reshape_smooth_context);
CustomData interface, see also DNA_customdata_types.h.
MultiresSubdivideModeType
MINLINE float clamp_f(float value, float min, float max)
Read Guarded memory(de)allocation.
Provides wrapper around system-specific atomic primitives, and some extensions (faked-atomic operatio...
ATOMIC_INLINE size_t atomic_fetch_and_add_z(size_t *p, size_t x)
ATTR_WARN_UNUSED_RESULT const BMVert * v2
ATTR_WARN_UNUSED_RESULT const BMVert * v
constexpr bool is_empty() const
constexpr int64_t size() const
constexpr int64_t start() const
constexpr IndexRange index_range() const
void setCoarsePositions(const float *positions, const int start_vertex_index, const int num_vertices)
ccl_device_inline float2 mask(const MaskType mask, const float2 a)
int multires_reshape_grid_to_face_index(const MultiresReshapeContext *reshape_context, int grid_index)
ReshapeGridElement multires_reshape_grid_element_for_grid_coord(const MultiresReshapeContext *reshape_context, const GridCoord *grid_coord)
int multires_reshape_grid_to_corner(const MultiresReshapeContext *reshape_context, int grid_index)
ReshapeConstGridElement multires_reshape_orig_grid_element_for_grid_coord(const MultiresReshapeContext *reshape_context, const GridCoord *grid_coord)
GridCoord multires_reshape_ptex_coord_to_grid(const MultiresReshapeContext *reshape_context, const PTexCoord *ptex_coord)
void multires_reshape_tangent_matrix_for_corner(const MultiresReshapeContext *reshape_context, int face_index, int corner, const blender::float3 &dPdu, const blender::float3 &dPdv, blender::float3x3 &r_tangent_matrix)
void multires_reshape_evaluate_base_mesh_limit_at_grid(const MultiresReshapeContext *reshape_context, const GridCoord *grid_coord, blender::float3 &r_P, blender::float3x3 &r_tangent_matrix)
void multires_reshape_smooth_object_grids_with_details(const MultiresReshapeContext *reshape_context)
void multires_reshape_smooth_object_grids(const MultiresReshapeContext *reshape_context, const MultiresSubdivideModeType mode)
void free(Subdiv *subdiv)
BLI_INLINE float crease_to_sharpness(float crease)
float3 eval_limit_point(Subdiv *subdiv, int ptex_face_index, float u, float v)
int converter_fvar_linear_from_settings(const Settings *settings)
bool foreach_subdiv_geometry(Subdiv *subdiv, const ForeachContext *context, const ToMeshSettings *mesh_settings, const Mesh *coarse_mesh)
int converter_vtx_boundary_interpolation_from_settings(const Settings *settings)
bool eval_begin(Subdiv *subdiv, eSubdivEvaluatorType evaluator_type, OpenSubdiv_EvaluatorCache *evaluator_cache, const OpenSubdiv_EvaluatorSettings *settings)
BLI_INLINE int grid_size_from_level(int level)
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)
Subdiv * new_from_converter(const Settings *settings, OpenSubdiv_Converter *converter)
@ SUBDIV_EVALUATOR_TYPE_CPU
void converter_free(OpenSubdiv_Converter *converter)
std::array< VecBase< T, 3 >, 8 > corners(const Bounds< VecBase< T, 3 > > &bounds)
CartesianBasis invert(const CartesianBasis &basis)
VecBase< T, 3 > transform_direction(const MatBase< T, 3, 3 > &mat, const VecBase< T, 3 > &direction)
void parallel_for(const IndexRange range, const int64_t grain_size, const Function &function, const TaskSizeHints &size_hints=detail::TaskSizeHints_Static(1))
MatBase< float, 3, 3 > float3x3
VecBase< float, 3 > float3
OpenSubdiv_FVarLinearInterpolation
OpenSubdiv_VtxBoundaryInterpolation
struct MultiresReshapeContext::@114377305000353127144042327223234020156043120202 reshape
blender::bke::subdiv::Subdiv * subdiv
struct MultiresReshapeContext::@204160262355230072153262361266331214205042063262 top
blender::VArraySpan< float > cd_vertex_crease
blender::OffsetIndices< int > base_faces
blender::Array< int > face_start_grid_index
int(* getFaceCornerUVIndex)(const OpenSubdiv_Converter *converter, const int face_index, const int corner_index)
void(* freeUserData)(const OpenSubdiv_Converter *converter)
int(* getNumEdges)(const OpenSubdiv_Converter *converter)
void(* precalcUVLayer)(const OpenSubdiv_Converter *converter, const int layer_index)
float(* getEdgeSharpness)(const OpenSubdiv_Converter *converter, const int edge_index)
int(* getNumVertexFaces)(const OpenSubdiv_Converter *converter, const int vertex_index)
void(* getVertexFaces)(const OpenSubdiv_Converter *converter, const int vertex_index, int *vertex_faces)
void(* getVertexEdges)(const OpenSubdiv_Converter *converter, const int vertex_index, int *vertex_edges)
OpenSubdiv_FVarLinearInterpolation(* getFVarLinearInterpolation)(const OpenSubdiv_Converter *converter)
bool(* specifiesFullTopology)(const OpenSubdiv_Converter *converter)
int(* getNumUVCoordinates)(const OpenSubdiv_Converter *converter)
void(* getFaceVertices)(const OpenSubdiv_Converter *converter, const int face_index, int *face_vertices)
OpenSubdiv_VtxBoundaryInterpolation(* getVtxBoundaryInterpolation)(const OpenSubdiv_Converter *converter)
int(* getNumUVLayers)(const OpenSubdiv_Converter *converter)
int(* getNumEdgeFaces)(const OpenSubdiv_Converter *converter, const int edge_index)
blender::OffsetIndices< int > faces
bool(* isInfiniteSharpVertex)(const OpenSubdiv_Converter *converter, const int vertex_index)
float(* getVertexSharpness)(const OpenSubdiv_Converter *converter, const int vertex_index)
OpenSubdiv_SchemeType(* getSchemeType)(const OpenSubdiv_Converter *converter)
void(* getEdgeVertices)(const OpenSubdiv_Converter *converter, const int edge_index, int edge_vertices[2])
int(* getNumVertexEdges)(const OpenSubdiv_Converter *converter, const int vertex_index)
int(* getNumVertices)(const OpenSubdiv_Converter *converter)
void(* getFaceEdges)(const OpenSubdiv_Converter *converter, const int face_index, int *face_edges)
void(* finishUVLayer)(const OpenSubdiv_Converter *converter)
void(* getEdgeFaces)(const OpenSubdiv_Converter *converter, const int edge, int *edge_faces)
blender::opensubdiv::EvalOutputAPI * eval_output
blender::float3 displacement
blender::float3 * displacement
static MatBase identity()
blender::BitVector is_loose_bits
ForeachVertexFromEdgeCb vertex_every_edge
ForeachTopologyInformationCb topology_info
ForeachVertexOfLooseEdgeCb vertex_of_loose_edge
ForeachVertexFromCornerCb vertex_every_corner
ForeachVertexInnerCb vertex_inner
OpenSubdiv_Evaluator * evaluator