Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGermano Cavalcante <germano.costa@ig.com.br>2020-06-21 17:40:08 +0300
committerGermano Cavalcante <germano.costa@ig.com.br>2020-06-22 13:54:36 +0300
commitba97da21acf2391544a2e58e4f3c7c4249feb839 (patch)
treea20b9c41268f106e09cf18d4da9059c4dd656beb /source/blender/editors/transform/transform_convert_mesh.c
parentd6e07a7cd342f69c93c58cacc61eb6990bfbd444 (diff)
Transform: Simplify and rearrange mirror code
No real functional changes.
Diffstat (limited to 'source/blender/editors/transform/transform_convert_mesh.c')
-rw-r--r--source/blender/editors/transform/transform_convert_mesh.c319
1 files changed, 143 insertions, 176 deletions
diff --git a/source/blender/editors/transform/transform_convert_mesh.c b/source/blender/editors/transform/transform_convert_mesh.c
index dd2b269ba7e..0f181a52810 100644
--- a/source/blender/editors/transform/transform_convert_mesh.c
+++ b/source/blender/editors/transform/transform_convert_mesh.c
@@ -50,9 +50,6 @@
/* Own include. */
#include "transform_convert.h"
-/* Used for both mirror epsilon and TD_MIRROR_EDGE_ */
-#define TRANSFORM_MAXDIST_MIRROR 0.00002f
-
/* -------------------------------------------------------------------- */
/** \name Island Creation
*
@@ -432,6 +429,19 @@ static void editmesh_set_connectivity_distance(BMesh *bm,
*
* \{ */
+/* Used for both mirror epsilon and TD_MIRROR_EDGE_ */
+#define TRANSFORM_MAXDIST_MIRROR 0.00002f
+
+struct MirrorDataVert {
+ int index;
+ int flag;
+};
+
+struct TransMirrorData {
+ struct MirrorDataVert *vert_map;
+ int mirror_elem_len;
+};
+
static bool is_in_quadrant_v3(const float co[3], const int quadrant[3], const float epsilon)
{
if (quadrant[0] && ((co[0] * quadrant[0]) < -epsilon)) {
@@ -446,163 +456,109 @@ static bool is_in_quadrant_v3(const float co[3], const int quadrant[3], const fl
return true;
}
-static TransDataMirror *editmesh_mirror_data_calc(BMEditMesh *em,
- bool use_select,
- const bool use_topology,
- const bool mirror_axis[3],
- int *r_mirror_data_len,
- BLI_bitmap **r_mirror_bitmap)
+static void editmesh_mirror_data_calc(BMEditMesh *em,
+ const bool use_select,
+ const bool use_topology,
+ const bool mirror_axis[3],
+ struct TransMirrorData *r_mirror_data)
{
- BMesh *bm = em->bm;
- int *index[3] = {NULL};
- int i;
-
- bool test_selected_only = use_select && (mirror_axis[0] + mirror_axis[1] + mirror_axis[2]) == 1;
- for (i = 0; i < 3; i++) {
- if (mirror_axis[i]) {
- index[i] = MEM_mallocN(bm->totvert * sizeof(int), __func__);
- EDBM_verts_mirror_cache_begin_ex(
- em, i, false, test_selected_only, use_topology, TRANSFORM_MAXDIST_MIRROR, index[i]);
- }
- }
+ struct MirrorDataVert *vert_map;
+ BMesh *bm = em->bm;
BMVert *eve;
BMIter iter;
+ int i, flag, totvert = bm->totvert;
- int quadrant[3];
- {
- float select_sum[3] = {0};
- BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
- if (BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) {
- continue;
- }
- if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) {
- add_v3_v3(select_sum, eve->co);
- }
- }
-
- for (i = 0; i < 3; i++) {
- if (mirror_axis[i]) {
- quadrant[i] = select_sum[i] >= 0.0f ? 1 : -1;
- }
- else {
- quadrant[i] = 0;
- }
- }
- }
+ vert_map = MEM_mallocN(totvert * sizeof(*vert_map), __func__);
- /* Tag only elements that will be transformed within the quadrant. */
+ float select_sum[3] = {0};
BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, i) {
+ vert_map[i] = (struct MirrorDataVert){-1, 0};
if (BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) {
continue;
}
- if ((!use_select || BM_elem_flag_test(eve, BM_ELEM_SELECT)) &&
- is_in_quadrant_v3(eve->co, quadrant, TRANSFORM_MAXDIST_MIRROR)) {
- BM_elem_flag_enable(eve, BM_ELEM_TAG);
- BM_elem_index_set(eve, i);
+ if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) {
+ add_v3_v3(select_sum, eve->co);
+ }
+ }
+
+ /* Tag only elements that will be transformed within the quadrant. */
+ int quadrant[3];
+ for (int a = 0; a < 3; a++) {
+ if (mirror_axis[a]) {
+ quadrant[a] = select_sum[a] >= 0.0f ? 1 : -1;
}
else {
- BM_elem_flag_disable(eve, BM_ELEM_TAG);
- BM_elem_index_set(eve, -1);
+ quadrant[a] = 0;
}
}
+ uint mirror_elem_len = 0;
+ int *index[3] = {NULL, NULL, NULL};
+ bool test_selected_only = use_select && (mirror_axis[0] + mirror_axis[1] + mirror_axis[2]) == 1;
for (int a = 0; a < 3; a++) {
- int *index_iter = index[a];
- if (index_iter == NULL) {
+ if (!mirror_axis[a]) {
continue;
}
+
+ index[a] = MEM_mallocN(totvert * sizeof(*index[a]), __func__);
+ EDBM_verts_mirror_cache_begin_ex(
+ em, a, false, test_selected_only, use_topology, TRANSFORM_MAXDIST_MIRROR, index[a]);
+
+ flag = TD_MIRROR_X << a;
BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, i) {
+ int i_mirr = index[a][i];
+ if (i_mirr < 0) {
+ continue;
+ }
if (BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) {
continue;
}
- if (test_selected_only && !BM_elem_flag_test(eve, BM_ELEM_SELECT)) {
+ if (use_select && !BM_elem_flag_test(eve, BM_ELEM_SELECT)) {
continue;
}
- int elem_index = BM_elem_index_get(eve);
- if (elem_index != -1) {
- int i_mirr = index_iter[i];
- if (i_mirr >= 0) {
- BMVert *vmir = BM_vert_at_index(bm, i_mirr);
- BM_elem_index_set(vmir, elem_index);
-
- /* The slot of this element in the index array no longer needs to be read.
- * Use to set the mirror sign. */
- if (index[0] && a > 0) {
- index[0][i_mirr] = index[0][i];
- }
- if (index[1] && a > 1) {
- index[1][i_mirr] = index[1][i];
- }
- /* Use -2 to differ from -1, but both can work. */
- index_iter[i_mirr] = -2;
- }
+ if (!is_in_quadrant_v3(eve->co, quadrant, TRANSFORM_MAXDIST_MIRROR)) {
+ continue;
}
- }
- }
- /* Count mirror elements. */
- uint mirror_elem_len = 0;
- BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, i) {
- if (BM_elem_flag_test(eve, BM_ELEM_HIDDEN | BM_ELEM_TAG)) {
- /* Not a mirror element. */
- BM_elem_index_set(eve, -1);
- continue;
- }
- int elem_index = BM_elem_index_get(eve);
- if (elem_index != -1) {
+ vert_map[i_mirr] = (struct MirrorDataVert){i, flag};
mirror_elem_len++;
}
}
- TransDataMirror *td_mirror_iter, *td_mirror = NULL;
- if (mirror_elem_len != 0) {
- td_mirror = MEM_mallocN(mirror_elem_len * sizeof(*td_mirror), __func__);
- td_mirror_iter = &td_mirror[0];
-
- *r_mirror_bitmap = BLI_BITMAP_NEW(bm->totvert, __func__);
-
- BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, i) {
- int elem_index = BM_elem_index_get(eve);
- if (elem_index != -1) {
- BMVert *v_src = BM_vert_at_index(bm, elem_index);
+ if (mirror_elem_len) {
+ for (int a = 0; a < 3; a++) {
+ if (!mirror_axis[a]) {
+ continue;
+ }
- int flag = 0;
- if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) {
- flag |= TD_SELECTED;
- }
- if (index[0] && index[0][i] == -2) {
- flag |= TD_MIRROR_X;
+ flag = TD_MIRROR_X << a;
+ for (i = 0; i < totvert; i++) {
+ int i_mirr = index[a][i];
+ if (i_mirr < 0) {
+ continue;
}
- if (index[1] && index[1][i] == -2) {
- flag |= TD_MIRROR_Y;
- }
- if (index[2] && index[2][i] == -2) {
- flag |= TD_MIRROR_Z;
+ if (vert_map[i].index != -1 && !(vert_map[i].flag & flag)) {
+ if (vert_map[i_mirr].index == -1) {
+ mirror_elem_len++;
+ }
+ vert_map[i_mirr].index = vert_map[i].index;
+ vert_map[i_mirr].flag |= vert_map[i].flag | flag;
}
-
- td_mirror_iter->extra = eve;
- td_mirror_iter->loc = eve->co;
- copy_v3_v3(td_mirror_iter->iloc, eve->co);
- td_mirror_iter->flag = flag;
- td_mirror_iter->loc_src = v_src->co;
- /** `center` will be set in the main createTransEditVerts loop.
- * copy_v3_v3(td_mirror_iter->center, eve->co); */
-
- td_mirror_iter++;
-
- BLI_BITMAP_ENABLE(*r_mirror_bitmap, i);
}
}
}
+ else {
+ MEM_freeN(vert_map);
+ vert_map = NULL;
+ }
MEM_SAFE_FREE(index[0]);
MEM_SAFE_FREE(index[1]);
MEM_SAFE_FREE(index[2]);
- bm->elem_index_dirty |= BM_VERT;
- *r_mirror_data_len = mirror_elem_len;
- return td_mirror;
+ r_mirror_data->vert_map = vert_map;
+ r_mirror_data->mirror_elem_len = mirror_elem_len;
}
/** \} */
@@ -704,14 +660,12 @@ void createTransEditVerts(TransInfo *t)
BMesh *bm = em->bm;
BMVert *eve;
BMIter iter;
- float(*mappedcos)[3] = NULL, (*quats)[4] = NULL;
- float mtx[3][3], smtx[3][3], (*defmats)[3][3] = NULL, (*defcos)[3] = NULL;
- float *dists = NULL;
+ float mtx[3][3], smtx[3][3];
int a;
const int prop_mode = (t->flag & T_PROP_EDIT) ? (t->flag & T_PROP_EDIT_ALL) : 0;
- int cd_vert_bweight_offset = -1;
struct TransIslandData island_data = {NULL};
+ struct TransMirrorData mirror_data = {NULL};
/**
* Quick check if we can transform.
@@ -753,46 +707,63 @@ void createTransEditVerts(TransInfo *t)
/* Even for translation this is needed because of island-orientation, see: T51651. */
const bool is_island_center = (t->around == V3D_AROUND_LOCAL_ORIGINS) || is_snap_rotate;
+ if (is_island_center) {
+ /* In this specific case, near-by vertices will need to know
+ * the island of the nearest connected vertex. */
+ const bool calc_single_islands = ((prop_mode & T_PROP_CONNECTED) &&
+ (t->around == V3D_AROUND_LOCAL_ORIGINS) &&
+ (em->selectmode & SCE_SELECT_VERTEX));
- /* Original index of our connected vertex when connected distances are calculated.
- * Optional, allocate if needed. */
- int *dists_index = NULL;
-
- BLI_bitmap *mirror_bitmap = NULL;
+ const bool calc_island_center = !is_snap_rotate;
+ /* The island axismtx is only necessary in some modes.
+ * TODO(Germano): Extend the list to exclude other modes. */
+ const bool calc_island_axismtx = !ELEM(t->mode, TFM_SHRINKFATTEN);
- if (t->mode == TFM_BWEIGHT) {
- BM_mesh_cd_flag_ensure(bm, BKE_mesh_from_object(tc->obedit), ME_CDFLAG_VERT_BWEIGHT);
- cd_vert_bweight_offset = CustomData_get_offset(&bm->vdata, CD_BWEIGHT);
+ editmesh_islands_info_calc(
+ em, calc_single_islands, calc_island_center, calc_island_axismtx, &island_data);
}
- if (tc->use_mirror_axis_any) {
- bool use_topology = (me->editflag & ME_EDIT_MIRROR_TOPO) != 0;
- bool use_select = (t->flag & T_PROP_EDIT) == 0;
- bool mirror_axis[3] = {tc->use_mirror_axis_x, tc->use_mirror_axis_y, tc->use_mirror_axis_z};
- tc->data_mirror = editmesh_mirror_data_calc(
- em, use_select, use_topology, mirror_axis, &tc->data_mirror_len, &mirror_bitmap);
- }
+ copy_m3_m4(mtx, tc->obedit->obmat);
+ /* we use a pseudo-inverse so that when one of the axes is scaled to 0,
+ * matrix inversion still works and we can still moving along the other */
+ pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON);
- /* allocating scratch arrays */
+ /* Original index of our connected vertex when connected distances are calculated.
+ * Optional, allocate if needed. */
+ int *dists_index = NULL;
+ float *dists = NULL;
if (prop_mode & T_PROP_CONNECTED) {
dists = MEM_mallocN(bm->totvert * sizeof(float), __func__);
if (is_island_center) {
dists_index = MEM_mallocN(bm->totvert * sizeof(int), __func__);
}
+ editmesh_set_connectivity_distance(em->bm, mtx, dists, dists_index);
}
- if (mirror_bitmap) {
- BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, a) {
- if (prop_mode || BM_elem_flag_test(eve, BM_ELEM_SELECT)) {
- if (BLI_BITMAP_TEST(mirror_bitmap, a)) {
- data_len--;
+ /* Create TransDataMirror. */
+ if (tc->use_mirror_axis_any) {
+ bool use_topology = (me->editflag & ME_EDIT_MIRROR_TOPO) != 0;
+ bool use_select = (t->flag & T_PROP_EDIT) == 0;
+ bool mirror_axis[3] = {tc->use_mirror_axis_x, tc->use_mirror_axis_y, tc->use_mirror_axis_z};
+ editmesh_mirror_data_calc(em, use_select, use_topology, mirror_axis, &mirror_data);
+
+ if (mirror_data.vert_map) {
+ tc->data_mirror_len = mirror_data.mirror_elem_len;
+ tc->data_mirror = MEM_mallocN(mirror_data.mirror_elem_len * sizeof(*tc->data_mirror),
+ __func__);
+
+ BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, a) {
+ if (prop_mode || BM_elem_flag_test(eve, BM_ELEM_SELECT)) {
+ if (mirror_data.vert_map[a].index != -1) {
+ data_len--;
+ }
}
}
}
}
- BLI_assert(data_len != 0);
-
+ /* Create TransData. */
+ BLI_assert(data_len >= 1);
tc->data_len = data_len;
tc->data = MEM_callocN(data_len * sizeof(TransData), "TransObData(Mesh EditMode)");
if (ELEM(t->mode, TFM_SKIN_RESIZE, TFM_SHRINKFATTEN)) {
@@ -804,34 +775,11 @@ void createTransEditVerts(TransInfo *t)
"TransObData ext");
}
- copy_m3_m4(mtx, tc->obedit->obmat);
- /* we use a pseudo-inverse so that when one of the axes is scaled to 0,
- * matrix inversion still works and we can still moving along the other */
- pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON);
-
- if (prop_mode & T_PROP_CONNECTED) {
- editmesh_set_connectivity_distance(em->bm, mtx, dists, dists_index);
- }
-
- if (is_island_center) {
- /* In this specific case, near-by vertices will need to know
- * the island of the nearest connected vertex. */
- const bool calc_single_islands = ((prop_mode & T_PROP_CONNECTED) &&
- (t->around == V3D_AROUND_LOCAL_ORIGINS) &&
- (em->selectmode & SCE_SELECT_VERTEX));
-
- const bool calc_island_center = !is_snap_rotate;
-
- /* The island axismtx is only necessary in some modes.
- * TODO(Germano): Extend the list to exclude other modes. */
- const bool calc_island_axismtx = !ELEM(t->mode, TFM_SHRINKFATTEN);
-
- editmesh_islands_info_calc(
- em, calc_single_islands, calc_island_center, calc_island_axismtx, &island_data);
- }
-
/* detect CrazySpace [tm] */
+ float(*quats)[4] = NULL;
+ float(*defmats)[3][3] = NULL;
if (BKE_modifiers_get_cage_index(t->scene, tc->obedit, NULL, 1) != -1) {
+ float(*defcos)[3] = NULL;
int totleft = -1;
if (BKE_modifiers_is_correctable_deformed(t->scene, tc->obedit)) {
BKE_scene_graph_evaluated_ensure(t->depsgraph, CTX_data_main(t->context));
@@ -856,6 +804,7 @@ void createTransEditVerts(TransInfo *t)
if (totleft > 0)
#endif
{
+ float(*mappedcos)[3] = NULL;
mappedcos = BKE_crazyspace_get_mapped_editverts(t->depsgraph, tc->obedit);
quats = MEM_mallocN(em->bm->totvert * sizeof(*quats), "crazy quats");
BKE_crazyspace_set_quats_editmesh(em, defcos, mappedcos, quats, !prop_mode);
@@ -869,6 +818,12 @@ void createTransEditVerts(TransInfo *t)
}
}
+ int cd_vert_bweight_offset = -1;
+ if (t->mode == TFM_BWEIGHT) {
+ BM_mesh_cd_flag_ensure(bm, BKE_mesh_from_object(tc->obedit), ME_CDFLAG_VERT_BWEIGHT);
+ cd_vert_bweight_offset = CustomData_get_offset(&bm->vdata, CD_BWEIGHT);
+ }
+
TransData *tob = tc->data;
TransDataMirror *td_mirror = tc->data_mirror;
BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, a) {
@@ -882,7 +837,19 @@ void createTransEditVerts(TransInfo *t)
island_index = island_data.island_vert_map[connected_index];
}
- if (mirror_bitmap && BLI_BITMAP_TEST(mirror_bitmap, a)) {
+ if (mirror_data.vert_map && mirror_data.vert_map[a].index != -1) {
+ int elem_index = mirror_data.vert_map[a].index;
+ BMVert *v_src = BM_vert_at_index(bm, elem_index);
+
+ if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) {
+ mirror_data.vert_map[a].flag |= TD_SELECTED;
+ }
+
+ td_mirror->extra = eve;
+ td_mirror->loc = eve->co;
+ copy_v3_v3(td_mirror->iloc, eve->co);
+ td_mirror->flag = mirror_data.vert_map[a].flag;
+ td_mirror->loc_src = v_src->co;
transdata_center_get(&island_data, island_index, td_mirror->iloc, td_mirror->center);
td_mirror++;
@@ -970,6 +937,9 @@ void createTransEditVerts(TransInfo *t)
if (island_data.island_vert_map) {
MEM_freeN(island_data.island_vert_map);
}
+ if (mirror_data.vert_map) {
+ MEM_freeN(mirror_data.vert_map);
+ }
if (quats) {
MEM_freeN(quats);
}
@@ -982,9 +952,6 @@ void createTransEditVerts(TransInfo *t)
if (dists_index) {
MEM_freeN(dists_index);
}
- if (mirror_bitmap) {
- MEM_freeN(mirror_bitmap);
- }
}
}