65 return elem_id[v_index] == elem;
112 if (
bm->totface < 3) {
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;
343 for (
int i = 0;
i <
bm->totvert;
i++) {
344 if (!visited_verts[
i]) {
348 visited_verts[
i] =
true;
349 elem_id[
i] = current_id;
355 BMVert *current_v, *neighbor_v;
361 if (!visited_verts[neighbor_index]) {
362 visited_verts[neighbor_index] =
true;
363 elem_id[neighbor_index] = current_id;
402 "dissolve_verts verts=%hv use_face_split=%b use_boundary_tear=%b",
419 "dissolve_verts verts=%hv use_face_split=%b use_boundary_tear=%b",
451 bool valid_tag_found =
true;
460 for (
int id = 0;
id < tot_ids;
id++) {
463 valid_tag_found =
false;
470 if (valid_tag_found) {
475 return valid_tag_found;
485 if (edge ==
nullptr) {
486 (*r_next_vertex) =
v;
520 if (edge_x != test_edge) {
521 if (test_edge->
v1 != initial_vertex && test_edge->
v2 == initial_vertex) {
524 if (test_edge->
v2 != initial_vertex && test_edge->
v1 == initial_vertex) {
536 float (*face_grid)[3],
MDisps *mdisp,
int face_grid_size,
int orig_grid_size,
int loop)
542 const int grid_offset = orig_grid_size - 1;
543 origin[0] = grid_offset;
544 origin[1] = grid_offset;
581 for (
int y = 0;
y < orig_grid_size;
y++) {
582 for (
int x = 0;
x < orig_grid_size;
x++) {
583 const int remap_x = origin[1] + (step_x[1] *
x) + (step_y[1] *
y);
584 const int remap_y = origin[0] + (step_x[0] *
x) + (step_y[0] *
y);
586 const int final_index = remap_x + remap_y * face_grid_size;
597 float (*face_grid)[3],
602 const int grid_it = face_grid_size - 1;
603 for (
int y = 0;
y < face_grid_size;
y++) {
604 for (
int x = 0;
x < face_grid_size;
x++) {
605 const int remap_x = (grid_it * gunsub_x) +
x;
606 const int remap_y = (grid_it * gunsub_y) +
y;
608 const int remap_index_y = grid->
grid_size - remap_x - 1;
609 const int remap_index_x = grid->
grid_size - remap_y - 1;
610 const int grid_index = remap_index_x + (remap_index_y * grid->
grid_size);
629 Mesh *original_mesh = context->original_mesh;
639 for (
int i = 0;
i < face.
size();
i++) {
640 const int loop_index = face[
i];
641 if (corner_verts[loop_index] == corner_vertex_index) {
649 const int face_grid_size =
BKE_ccg_gridsize(context->num_original_levels + 1);
650 const int face_grid_area = face_grid_size * face_grid_size;
653 for (
int i = 0;
i < face.
size();
i++) {
654 const int loop_index = face[
i];
655 MDisps *mdisp = &context->original_mdisp[loop_index];
656 int quad_loop =
i - loop_offset;
660 if (quad_loop >= 4) {
679 const int remap_index_y = grid->
grid_size - 1 - grid_x;
680 const int remap_index_x = grid->
grid_size - 1 - grid_y;
682 const int grid_index = remap_index_x + (remap_index_y * grid->
grid_size);
706 size_t(unsubdiv_grid_size) *
size_t(unsubdiv_grid_size),
"grids coordinates");
712 initial_vertex = initial_edge_x->
v1;
715 initial_vertex = initial_edge_x->
v2;
723 edge_temp = initial_edge_x;
724 initial_edge_x = initial_edge_y;
725 initial_edge_y = edge_temp;
731 BMVert *current_vertex_x = initial_vertex;
732 BMEdge *edge_x = initial_edge_x;
734 BMVert *current_vertex_y = initial_vertex;
735 BMEdge *edge_y = initial_edge_y;
736 BMEdge *prev_edge_y = initial_edge_y;
738 BMFace *current_face = f1;
744 int grid_iteration_max_steps = grid_size;
745 if (context->num_original_levels > 0) {
746 grid_iteration_max_steps = grid_size - 1;
751 while (grid_y < grid_iteration_max_steps) {
753 grid_face = current_face;
755 while (grid_x < grid_iteration_max_steps) {
756 if (context->num_original_levels == 0) {
760 edge_x =
edge_step(current_vertex_x, edge_x, ¤t_vertex_x);
765 store_grid_data(context, grid, current_vertex_x, grid_face, grid_x, grid_y);
766 edge_x =
edge_step(current_vertex_x, edge_x, ¤t_vertex_x);
767 grid_face =
face_step(edge_x, grid_face);
774 edge_y =
edge_step(current_vertex_y, edge_y, ¤t_vertex_y);
775 current_vertex_x = current_vertex_y;
789 if (f != current_face) {
795 prev_edge_y = edge_y;
817 initial_vertex = initial_edge_x->
v1;
820 initial_vertex = initial_edge_x->
v2;
826 BMVert *current_vertex_x = initial_vertex;
827 BMEdge *edge_x = initial_edge_x;
829 BMVert *current_vertex_y = initial_vertex;
830 BMEdge *edge_y = initial_edge_y;
834 edge_x =
edge_step(current_vertex_x, edge_x, ¤t_vertex_x);
836 edge_x =
edge_step(current_vertex_x, edge_x, ¤t_vertex_x);
838 *r_corner_x = current_vertex_x;
841 edge_y =
edge_step(current_vertex_y, edge_y, ¤t_vertex_y);
843 edge_y =
edge_step(current_vertex_y, edge_y, ¤t_vertex_y);
845 *r_corner_y = current_vertex_y;
865static const char lname[] =
"l_remap_index";
866static const char vname[] =
"v_remap_index";
872 if (l_layer_index != -1) {
878 if (v_layer_index != -1) {
909 Mesh *original_mesh = context->original_mesh;
911 Mesh *base_mesh = context->base_mesh;
925 context->base_to_orig_vmap =
static_cast<const int *
>(
930 int vert_basemesh_index = context->base_to_orig_vmap[
i];
935 context->loop_to_face_map = original_mesh->corner_to_face_map();
950 const int v_first = corner_verts[face.
start()];
951 if ((loop == (face.
start() + (face.
size() - 1))) && v_first == v_x) {
955 int next_l_index = loop + 1;
956 if (next_l_index < face.
start() + face.
size()) {
957 const int v_next = corner_verts[next_l_index];
968 Mesh *original_mesh = context->original_mesh;
969 Mesh *base_mesh = context->base_mesh;
971 BMesh *bm_original_mesh = context->bm_original_mesh;
983 context->base_to_orig_vmap =
static_cast<const int *
>(
986 base_to_orig_vmap[
i] = context->base_to_orig_vmap[
i];
992 orig_to_base_vmap[
i] = -1;
996 const int orig_vertex_index = context->base_to_orig_vmap[
i];
997 orig_to_base_vmap[orig_vertex_index] =
i;
1005 BMIter iter, iter_a, iter_b;
1030 BMVert *corner_x, *corner_y;
1036 if (corner_x_index < 0 || corner_y_index < 0) {
1058 faces, corner_verts, base_mesh_face_index, base_mesh_loop_index, corner_x_index);
1076 context,
l->f,
l->e, !flip_grid, grid);
1093 if (context->bm_original_mesh !=
nullptr) {
1099 Mesh *original_mesh,
1102 context->original_mesh = original_mesh;
1103 context->num_new_levels = 0;
1104 context->num_total_levels = 0;
1105 context->num_original_levels = mmd->
totlvl;
1110 Mesh *original_mesh = context->original_mesh;
1117 context->num_new_levels = 0;
1118 int num_levels_left = context->max_new_levels;
1120 context->num_new_levels++;
1125 if (context->num_new_levels == 0) {
1132 context->num_total_levels = context->num_new_levels + context->num_original_levels;
1145 BM_mesh_bm_to_me(
nullptr, bm_base_mesh, context->base_mesh, &bm_to_me_params);
1159 for (
int i = 0;
i < context->num_grids;
i++) {
1160 if (context->base_mesh_grids[
i].grid_size > 0) {
1187 for (
int i = 0;
i < totloop;
i++) {
1190 if (mdisps[
i].disps) {
1194 for (
int j = 0; j < totdisp; j++) {
1195 if (context->base_mesh_grids[
i].grid_co) {
1196 copy_v3_v3(disps[j], context->base_mesh_grids[
i].grid_co[j]);
1202 mdisps[
i].
level = context->num_total_levels;
1210 bool switch_view_to_lower_level)
1212 Mesh *mesh =
static_cast<Mesh *
>(
object->data);
1252 Mesh *base_mesh =
static_cast<Mesh *
>(
object->data);
1260 if (switch_view_to_lower_level) {
1283 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)
bool CustomData_free_layer(CustomData *data, eCustomDataType type, int index)
int CustomData_get_named_layer_index(const CustomData *data, eCustomDataType type, blender::StringRef name)
int CustomData_get_offset_named(const CustomData *data, eCustomDataType type, blender::StringRef name)
void CustomData_free_layers(CustomData *data, eCustomDataType type)
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])
Object is a sort of wrapper for general info.
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)
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 *f_a, BMFace *f_b)
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
BPy_StructRNA * depsgraph
constexpr int64_t size() const
constexpr int64_t start() const
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)