65 return elem_id[v_index] == elem;
166 visited_verts[neighbor_vertex_index].set();
200 if (!visited_verts[neighbor_vertex_index] && neighbor_v != diagonal_v &&
204 visited_verts[neighbor_vertex_index].set(
true);
230 BMIter iter, iter_a, iter_b;
251 bool any_tagged =
false;
279 if (initial_vertex_pole !=
nullptr) {
286 BMFace *f, *init_face =
nullptr;
296 if (init_face !=
nullptr) {
305 bool valid_tag_found =
false;
318 valid_tag_found =
true;
333 return valid_tag_found;
341 bool *visited_verts =
static_cast<bool *
>(
345 if (!visited_verts[i]) {
349 visited_verts[i] =
true;
350 elem_id[i] = current_id;
356 BMVert *current_v, *neighbor_v;
362 if (!visited_verts[neighbor_index]) {
363 visited_verts[neighbor_index] =
true;
364 elem_id[neighbor_index] = current_id;
403 "dissolve_verts verts=%hv use_face_split=%b use_boundary_tear=%b",
420 "dissolve_verts verts=%hv use_face_split=%b use_boundary_tear=%b",
452 bool valid_tag_found =
true;
461 for (
int id = 0;
id < tot_ids;
id++) {
464 valid_tag_found =
false;
471 if (valid_tag_found) {
476 return valid_tag_found;
486 if (edge ==
nullptr) {
487 (*r_next_vertex) =
v;
521 if (edge_x != test_edge) {
522 if (test_edge->
v1 != initial_vertex && test_edge->
v2 == initial_vertex) {
525 if (test_edge->
v2 != initial_vertex && test_edge->
v1 == initial_vertex) {
537 float (*face_grid)[3],
MDisps *mdisp,
int face_grid_size,
int orig_grid_size,
int loop)
543 const int grid_offset = orig_grid_size - 1;
544 origin[0] = grid_offset;
545 origin[1] = grid_offset;
582 for (
int y = 0; y < orig_grid_size; y++) {
583 for (
int x = 0; x < orig_grid_size; x++) {
584 const int remap_x = origin[1] + (step_x[1] *
x) + (step_y[1] * y);
585 const int remap_y = origin[0] + (step_x[0] *
x) + (step_y[0] * y);
587 const int final_index = remap_x + remap_y * face_grid_size;
588 copy_v3_v3(face_grid[final_index], mdisp->
disps[x + y * orig_grid_size]);
598 float (*face_grid)[3],
603 const int grid_it = face_grid_size - 1;
604 for (
int y = 0; y < face_grid_size; y++) {
605 for (
int x = 0; x < face_grid_size; x++) {
606 const int remap_x = (grid_it * gunsub_x) + x;
607 const int remap_y = (grid_it * gunsub_y) + y;
609 const int remap_index_y = grid->grid_size - remap_x - 1;
610 const int remap_index_x = grid->grid_size - remap_y - 1;
611 const int grid_index = remap_index_x + (remap_index_y * grid->grid_size);
612 copy_v3_v3(grid->grid_co[grid_index], face_grid[x + y * face_grid_size]);
630 Mesh *original_mesh = context->original_mesh;
640 for (
int i = 0; i < face.size(); i++) {
641 const int loop_index = face[i];
642 if (corner_verts[loop_index] == corner_vertex_index) {
650 const int face_grid_size =
BKE_ccg_gridsize(context->num_original_levels + 1);
651 const int face_grid_area = face_grid_size * face_grid_size;
652 float(*face_grid)[3] =
static_cast<float(*)[3]
>(
655 for (
int i = 0; i < face.size(); i++) {
656 const int loop_index = face[i];
657 MDisps *mdisp = &context->original_mdisp[loop_index];
658 int quad_loop = i - loop_offset;
662 if (quad_loop >= 4) {
681 const int remap_index_y = grid->grid_size - 1 - grid_x;
682 const int remap_index_x = grid->grid_size - 1 - grid_y;
684 const int grid_index = remap_index_x + (remap_index_y * grid->grid_size);
704 const int unsubdiv_grid_size = grid->grid_size =
BKE_ccg_gridsize(context->num_total_levels);
706 grid->grid_size = unsubdiv_grid_size;
708 unsubdiv_grid_size * unsubdiv_grid_size,
sizeof(
float[3]),
"grids coordinates"));
714 initial_vertex = initial_edge_x->
v1;
717 initial_vertex = initial_edge_x->
v2;
725 edge_temp = initial_edge_x;
726 initial_edge_x = initial_edge_y;
727 initial_edge_y = edge_temp;
733 BMVert *current_vertex_x = initial_vertex;
734 BMEdge *edge_x = initial_edge_x;
736 BMVert *current_vertex_y = initial_vertex;
737 BMEdge *edge_y = initial_edge_y;
738 BMEdge *prev_edge_y = initial_edge_y;
740 BMFace *current_face = f1;
746 int grid_iteration_max_steps = grid_size;
747 if (context->num_original_levels > 0) {
748 grid_iteration_max_steps = grid_size - 1;
753 while (grid_y < grid_iteration_max_steps) {
755 grid_face = current_face;
757 while (grid_x < grid_iteration_max_steps) {
758 if (context->num_original_levels == 0) {
762 edge_x =
edge_step(current_vertex_x, edge_x, ¤t_vertex_x);
767 store_grid_data(context, grid, current_vertex_x, grid_face, grid_x, grid_y);
768 edge_x =
edge_step(current_vertex_x, edge_x, ¤t_vertex_x);
769 grid_face =
face_step(edge_x, grid_face);
776 edge_y =
edge_step(current_vertex_y, edge_y, ¤t_vertex_y);
777 current_vertex_x = current_vertex_y;
791 if (f != current_face) {
797 prev_edge_y = edge_y;
819 initial_vertex = initial_edge_x->
v1;
822 initial_vertex = initial_edge_x->
v2;
828 BMVert *current_vertex_x = initial_vertex;
829 BMEdge *edge_x = initial_edge_x;
831 BMVert *current_vertex_y = initial_vertex;
832 BMEdge *edge_y = initial_edge_y;
836 edge_x =
edge_step(current_vertex_x, edge_x, ¤t_vertex_x);
838 edge_x =
edge_step(current_vertex_x, edge_x, ¤t_vertex_x);
840 *r_corner_x = current_vertex_x;
843 edge_y =
edge_step(current_vertex_y, edge_y, ¤t_vertex_y);
845 edge_y =
edge_step(current_vertex_y, edge_y, ¤t_vertex_y);
847 *r_corner_y = current_vertex_y;
860 bm_from_me_params.calc_vert_normal =
true;
867static const char lname[] =
"l_remap_index";
868static const char vname[] =
"v_remap_index";
874 if (l_layer_index != -1) {
880 if (v_layer_index != -1) {
900 for (
int i = 0; i < mesh->corners_num; i++) {
903 for (
int i = 0; i < mesh->verts_num; i++) {
911 Mesh *original_mesh = context->original_mesh;
913 Mesh *base_mesh = context->base_mesh;
927 context->base_to_orig_vmap =
static_cast<const int *
>(
931 for (
int i = 0; i < base_mesh->
verts_num; i++) {
932 int vert_basemesh_index = context->base_to_orig_vmap[i];
937 context->loop_to_face_map = original_mesh->corner_to_face_map();
952 const int v_first = corner_verts[face.start()];
953 if ((loop == (face.start() + (face.size() - 1))) && v_first == v_x) {
957 int next_l_index = loop + 1;
958 if (next_l_index < face.start() + face.size()) {
959 const int v_next = corner_verts[next_l_index];
970 Mesh *original_mesh = context->original_mesh;
971 Mesh *base_mesh = context->base_mesh;
973 BMesh *bm_original_mesh = context->bm_original_mesh;
982 int *orig_to_base_vmap =
static_cast<int *
>(
984 int *base_to_orig_vmap =
static_cast<int *
>(
987 context->base_to_orig_vmap =
static_cast<const int *
>(
989 for (
int i = 0; i < base_mesh->
verts_num; i++) {
990 base_to_orig_vmap[i] = context->base_to_orig_vmap[i];
995 for (
int i = 0; i < original_mesh->
verts_num; i++) {
996 orig_to_base_vmap[i] = -1;
999 for (
int i = 0; i < base_mesh->
verts_num; i++) {
1000 const int orig_vertex_index = context->base_to_orig_vmap[i];
1001 orig_to_base_vmap[orig_vertex_index] = i;
1009 BMIter iter, iter_a, iter_b;
1034 BMVert *corner_x, *corner_y;
1040 if (corner_x_index < 0 || corner_y_index < 0) {
1062 faces, corner_verts, base_mesh_face_index, base_mesh_loop_index, corner_x_index);
1066 if (
UNLIKELY(grid->grid_co !=
nullptr)) {
1080 context,
l->
f,
l->
e, !flip_grid, grid);
1097 if (context->bm_original_mesh !=
nullptr) {
1103 Mesh *original_mesh,
1106 context->original_mesh = original_mesh;
1107 context->num_new_levels = 0;
1108 context->num_total_levels = 0;
1109 context->num_original_levels = mmd->
totlvl;
1114 Mesh *original_mesh = context->original_mesh;
1121 context->num_new_levels = 0;
1122 int num_levels_left = context->max_new_levels;
1124 context->num_new_levels++;
1129 if (context->num_new_levels == 0) {
1136 context->num_total_levels = context->num_new_levels + context->num_original_levels;
1149 BM_mesh_bm_to_me(
nullptr, bm_base_mesh, context->base_mesh, &bm_to_me_params);
1163 for (
int i = 0; i < context->num_grids; i++) {
1164 if (context->base_mesh_grids[i].grid_size > 0) {
1191 for (
int i = 0; i < totloop; i++) {
1192 float(*disps)[3] =
static_cast<float(*)[3]
>(
1195 if (mdisps[i].disps) {
1199 for (
int j = 0; j < totdisp; j++) {
1200 if (context->base_mesh_grids[i].grid_co) {
1201 copy_v3_v3(disps[j], context->base_mesh_grids[i].grid_co[j]);
1205 mdisps[i].
disps = disps;
1207 mdisps[i].
level = context->num_total_levels;
1215 bool switch_view_to_lower_level)
1217 Mesh *mesh =
static_cast<Mesh *
>(
object->data);
1234 unsubdiv_context.original_mdisp = reshape_context.mdisps;
1238 unsubdiv_context.max_new_levels = rebuild_limit;
1257 Mesh *base_mesh =
static_cast<Mesh *
>(
object->data);
1263 mmd->
totlvl = char(unsubdiv_context.num_total_levels);
1265 if (switch_view_to_lower_level) {
1271 mmd->
lvl = char(mmd->
lvl + unsubdiv_context.num_new_levels);
1285 const int rebuild_subdvis = unsubdiv_context.num_new_levels;
1288 return rebuild_subdvis;
CustomData interface, see also DNA_customdata_types.h.
const void * CustomData_get_layer_named(const CustomData *data, eCustomDataType type, blender::StringRef name)
void * CustomData_add_layer_named(CustomData *data, eCustomDataType type, eCDAllocType alloctype, int totelem, blender::StringRef name)
int CustomData_get_named_layer_index(const CustomData *data, eCustomDataType type, blender::StringRef name)
bool CustomData_free_layer(CustomData *data, eCustomDataType type, int totelem, int index)
int CustomData_get_offset_named(const CustomData *data, eCustomDataType type, blender::StringRef name)
void CustomData_free_layers(CustomData *data, eCustomDataType type, int totelem)
bool CustomData_has_layer(const CustomData *data, eCustomDataType type)
void * CustomData_add_layer(CustomData *data, eCustomDataType type, eCDAllocType alloctype, int totelem)
Mesh * BKE_mesh_new_nomain_from_template(const Mesh *me_src, int verts_num, int edges_num, int faces_num, int corners_num)
void BKE_mesh_nomain_to_mesh(Mesh *mesh_src, Mesh *mesh_dst, Object *ob)
void multires_force_sculpt_rebuild(Object *object)
int BKE_ccg_gridsize(int level)
#define BLI_assert_msg(a, msg)
void BLI_gsqueue_free(GSQueue *queue)
void BLI_gsqueue_push(GSQueue *queue, const void *item)
void BLI_gsqueue_pop(GSQueue *queue, void *r_item)
GSQueue * BLI_gsqueue_new(size_t elem_size)
bool BLI_gsqueue_is_empty(const GSQueue *queue)
int pow_i(int base, int exp)
MINLINE void copy_v3_v3(float r[3], const float a[3])
Read Guarded memory(de)allocation.
#define BM_ELEM_CD_GET_INT(ele, offset)
#define BM_elem_index_get(ele)
#define BM_elem_flag_set(ele, hflag, val)
#define BM_elem_flag_test(ele, hflag)
#define BM_ITER_ELEM(ele, iter, data, itype)
#define BM_ITER_MESH(ele, iter, bm, itype)
ATTR_WARN_UNUSED_RESULT BMesh * bm
void BM_mesh_elem_hflag_enable_all(BMesh *bm, const char htype, const char hflag, const bool respecthide)
void BM_mesh_elem_hflag_disable_all(BMesh *bm, const char htype, const char hflag, const bool respecthide)
void BM_mesh_free(BMesh *bm)
BMesh Free Mesh.
void BM_mesh_elem_table_ensure(BMesh *bm, const char htype)
void BM_mesh_elem_table_init(BMesh *bm, const char htype)
BMesh * BM_mesh_create(const BMAllocTemplate *allocsize, const BMeshCreateParams *params)
BMesh Make Mesh.
BLI_INLINE BMVert * BM_vert_at_index(BMesh *bm, const int index)
#define BMALLOC_TEMPLATE_FROM_ME(...)
void BM_mesh_bm_from_me(BMesh *bm, const Mesh *mesh, const BMeshFromMeshParams *params)
void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *mesh, const BMeshToMeshParams *params)
bool BMO_op_callf(BMesh *bm, int flag, const char *fmt,...)
#define BMO_FLAG_DEFAULTS
bool BM_vert_is_wire(const BMVert *v)
bool BM_edge_share_quad_check(BMEdge *e1, BMEdge *e2)
bool BM_edge_in_face(const BMEdge *e, const BMFace *f)
bool BM_face_share_edge_check(BMFace *f1, BMFace *f2)
BMEdge * BM_edge_exists(BMVert *v_a, BMVert *v_b)
bool BM_vert_in_face(BMVert *v, BMFace *f)
bool BM_vert_is_boundary(const BMVert *v)
#define BM_vert_edge_count_is_equal(v, n)
BLI_INLINE BMVert * BM_edge_other_vert(BMEdge *e, const BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
#define BM_vert_edge_count_is_over(v, n)
ATTR_WARN_UNUSED_RESULT const BMLoop * l
ATTR_WARN_UNUSED_RESULT const BMVert * v
const Depsgraph * depsgraph
draw_view in_light_buf[] float
void *(* MEM_calloc_arrayN)(size_t len, size_t size, const char *str)
void MEM_freeN(void *vmemh)
void multires_reshape_assign_final_coords_from_mdisps(const MultiresReshapeContext *reshape_context)
bool multires_reshape_context_create_from_object(MultiresReshapeContext *reshape_context, Depsgraph *depsgraph, Object *object, MultiresModifierData *mmd)
void multires_reshape_context_free(MultiresReshapeContext *reshape_context)
void multires_reshape_store_original_grids(MultiresReshapeContext *reshape_context)
void multires_reshape_object_grids_to_tangent_displacement(const MultiresReshapeContext *reshape_context)
bool multires_reshape_context_create_from_base_mesh(MultiresReshapeContext *reshape_context, Depsgraph *depsgraph, Object *object, MultiresModifierData *mmd)
static BMFace * face_step(BMEdge *edge, BMFace *f)
static bool unsubdivide_tag_disconnected_mesh_element(BMesh *bm, int *elem_id, int elem)
static void store_vertex_data(MultiresUnsubdivideGrid *grid, BMVert *v, int grid_x, int grid_y)
static void write_loop_in_face_grid(float(*face_grid)[3], MDisps *mdisp, int face_grid_size, int orig_grid_size, int loop)
static bool is_vertex_in_id(BMVert *v, const int *elem_id, int elem)
static void multires_create_grids_in_unsubdivided_base_mesh(MultiresUnsubdivideContext *context, Mesh *base_mesh)
static bool multires_unsubdivide_single_level(BMesh *bm)
static void multires_unsubdivide_prepare_original_bmesh_for_extract(MultiresUnsubdivideContext *context)
static BMEdge * edge_step(BMVert *v, BMEdge *edge, BMVert **r_next_vertex)
static void multires_unsubdivide_private_extract_data_free(MultiresUnsubdivideContext *context)
static BMVert * unsubdivide_find_any_pole(BMesh *bm, int *elem_id, int elem)
static bool is_vertex_pole_three(BMVert *v)
static void multires_unsubdivide_add_original_index_datalayers(Mesh *mesh)
bool multires_unsubdivide_to_basemesh(MultiresUnsubdivideContext *context)
static void unsubdivide_face_center_vertex_tag(BMesh *bm, BMVert *initial_vertex)
static bool is_vertex_pole(BMVert *v)
static int unsubdivide_init_elem_ids(BMesh *bm, int *elem_id)
static void store_grid_data(MultiresUnsubdivideContext *context, MultiresUnsubdivideGrid *grid, BMVert *v, BMFace *f, int grid_x, int grid_y)
static const char lname[]
static bool unsubdivide_is_center_vertex_tag_valid(BMesh *bm, int *elem_id, int elem)
static bool unsubdivide_is_all_quads(BMesh *bm)
void multires_unsubdivide_context_init(MultiresUnsubdivideContext *context, Mesh *original_mesh, MultiresModifierData *mmd)
static bool multires_unsubdivide_flip_grid_x_axis(const blender::OffsetIndices< int > faces, const blender::Span< int > corner_verts, int face_index, int loop, int v_x)
static void multires_unsubdivide_get_grid_corners_on_base_mesh(BMFace *f1, BMEdge *e1, BMVert **r_corner_x, BMVert **r_corner_y)
static void unsubdivide_build_base_mesh_from_tags(BMesh *bm)
static void multires_unsubdivide_free_original_datalayers(Mesh *mesh)
static bool is_vertex_diagonal(BMVert *from_v, BMVert *to_v)
static BMEdge * get_initial_edge_y(BMFace *f, BMEdge *edge_x, BMVert *initial_vertex)
static void multires_unsubdivide_extract_grids(MultiresUnsubdivideContext *context)
static void multires_unsubdivide_extract_single_grid_from_face_edge(MultiresUnsubdivideContext *context, BMFace *f1, BMEdge *e1, bool flip_grid, MultiresUnsubdivideGrid *grid)
static const char vname[]
int multiresModifier_rebuild_subdiv(Depsgraph *depsgraph, Object *object, MultiresModifierData *mmd, int rebuild_limit, bool switch_view_to_lower_level)
static void write_face_grid_in_unsubdivide_grid(MultiresUnsubdivideGrid *grid, float(*face_grid)[3], int face_grid_size, int gunsub_x, int gunsub_y)
void multires_unsubdivide_context_free(MultiresUnsubdivideContext *context)
static BMesh * get_bmesh_from_mesh(Mesh *mesh)