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>2021-01-04 23:36:51 +0300
committerGermano Cavalcante <germano.costa@ig.com.br>2021-01-04 23:37:08 +0300
commit54ee4109143b6fdabf749d2fde183907469cfa3b (patch)
tree06bdc8456841ddce928c7ac3f9c8c42db4f46797 /source/blender/editors/transform/transform_convert_mesh.c
parent8c80299fc4493cac640ab4cd56b9bc34f606ee2c (diff)
Fix T84376: Skin Resize(Ctrl + A) does not work in Symmetry
Since the `TransData` converted from vertices is the same used for other transform modes (Move, Rotate, Resize), the logic used for mirroring focused only on the position of the vertices. The solution here is to create a specific `TansData` for `CD_MVERT_SKIN`.
Diffstat (limited to 'source/blender/editors/transform/transform_convert_mesh.c')
-rw-r--r--source/blender/editors/transform/transform_convert_mesh.c307
1 files changed, 163 insertions, 144 deletions
diff --git a/source/blender/editors/transform/transform_convert_mesh.c b/source/blender/editors/transform/transform_convert_mesh.c
index 5f41aaa8e50..b3bd6b31879 100644
--- a/source/blender/editors/transform/transform_convert_mesh.c
+++ b/source/blender/editors/transform/transform_convert_mesh.c
@@ -27,8 +27,6 @@
#include "MEM_guardedalloc.h"
#include "BLI_alloca.h"
-#include "BLI_bitmap.h"
-#include "BLI_ghash.h"
#include "BLI_linklist_stack.h"
#include "BLI_math.h"
#include "BLI_memarena.h"
@@ -45,12 +43,10 @@
#include "DEG_depsgraph_query.h"
#include "transform.h"
-#include "transform_mode.h"
+#include "transform_orientations.h"
#include "transform_snap.h"
-/* Own include. */
#include "transform_convert.h"
-#include "transform_orientations.h"
#define USE_FACE_SUBSTITUTE
@@ -59,18 +55,11 @@
*
* \{ */
-struct TransIslandData {
- float (*center)[3];
- float (*axismtx)[3][3];
- int island_tot;
- int *island_vert_map;
-};
-
-static void editmesh_islands_info_calc(BMEditMesh *em,
- const bool calc_single_islands,
- const bool calc_island_center,
- const bool calc_island_axismtx,
- struct TransIslandData *r_island_data)
+void transform_convert_mesh_islands_calc(struct BMEditMesh *em,
+ const bool calc_single_islands,
+ const bool calc_island_center,
+ const bool calc_island_axismtx,
+ struct TransIslandData *r_island_data)
{
BMesh *bm = em->bm;
char htype;
@@ -242,6 +231,19 @@ static void editmesh_islands_info_calc(BMEditMesh *em,
r_island_data->island_vert_map = vert_map;
}
+void transform_convert_mesh_islanddata_free(struct TransIslandData *island_data)
+{
+ if (island_data->center) {
+ MEM_freeN(island_data->center);
+ }
+ if (island_data->axismtx) {
+ MEM_freeN(island_data->axismtx);
+ }
+ if (island_data->island_vert_map) {
+ MEM_freeN(island_data->island_vert_map);
+ }
+}
+
/** \} */
/* -------------------------------------------------------------------- */
@@ -285,10 +287,10 @@ static bool bmesh_test_dist_add(BMVert *v,
* \param dists: Store the closest connected distance to selected vertices.
* \param index: Optionally store the original index we're measuring the distance to (can be NULL).
*/
-static void editmesh_set_connectivity_distance(BMesh *bm,
- const float mtx[3][3],
- float *dists,
- int *index)
+void transform_convert_mesh_connectivity_distance(struct BMesh *bm,
+ const float mtx[3][3],
+ float *dists,
+ int *index)
{
BLI_LINKSTACK_DECLARE(queue, BMVert *);
@@ -436,16 +438,6 @@ 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)) {
@@ -460,11 +452,11 @@ static bool is_in_quadrant_v3(const float co[3], const int quadrant[3], const fl
return true;
}
-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)
+void transform_convert_mesh_mirrordata_calc(struct BMEditMesh *em,
+ const bool use_select,
+ const bool use_topology,
+ const bool mirror_axis[3],
+ struct TransMirrorData *r_mirror_data)
{
struct MirrorDataVert *vert_map;
@@ -572,6 +564,119 @@ static void editmesh_mirror_data_calc(BMEditMesh *em,
r_mirror_data->mirror_elem_len = mirror_elem_len;
}
+void transform_convert_mesh_mirrordata_free(struct TransMirrorData *mirror_data)
+{
+ if (mirror_data->vert_map) {
+ MEM_freeN(mirror_data->vert_map);
+ }
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Crazy Space
+ *
+ * \{ */
+
+/* Detect CrazySpace [tm].
+ * Vertices with space affected by quats are marked with #BM_ELEM_TAG */
+void transform_convert_mesh_crazyspace_detect(TransInfo *t,
+ struct TransDataContainer *tc,
+ struct BMEditMesh *em,
+ struct TransMeshDataCrazySpace *r_crazyspace_data)
+{
+ float(*quats)[4] = NULL;
+ float(*defmats)[3][3] = NULL;
+ const int prop_mode = (t->flag & T_PROP_EDIT) ? (t->flag & T_PROP_EDIT_ALL) : 0;
+ 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));
+
+ /* Use evaluated state because we need b-bone cache. */
+ Scene *scene_eval = (Scene *)DEG_get_evaluated_id(t->depsgraph, &t->scene->id);
+ Object *obedit_eval = (Object *)DEG_get_evaluated_id(t->depsgraph, &tc->obedit->id);
+ BMEditMesh *em_eval = BKE_editmesh_from_object(obedit_eval);
+ /* check if we can use deform matrices for modifier from the
+ * start up to stack, they are more accurate than quats */
+ totleft = BKE_crazyspace_get_first_deform_matrices_editbmesh(
+ t->depsgraph, scene_eval, obedit_eval, em_eval, &defmats, &defcos);
+ }
+
+ /* If we still have more modifiers, also do crazy-space
+ * correction with \a quats, relative to the coordinates after
+ * the modifiers that support deform matrices \a defcos. */
+
+#if 0 /* TODO, fix crazy-space & extrude so it can be enabled for general use - campbell */
+ if ((totleft > 0) || (totleft == -1))
+#else
+ 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);
+ if (mappedcos) {
+ MEM_freeN(mappedcos);
+ }
+ }
+
+ if (defcos) {
+ MEM_freeN(defcos);
+ }
+ }
+ r_crazyspace_data->quats = quats;
+ r_crazyspace_data->defmats = defmats;
+}
+
+void transform_convert_mesh_crazyspace_transdata_set(const float mtx[3][3],
+ const float smtx[3][3],
+ const float defmat[3][3],
+ const float quat[4],
+ struct TransData *r_td)
+{
+ /* CrazySpace */
+ if (quat || defmat) {
+ float mat[3][3], qmat[3][3], imat[3][3];
+
+ /* Use both or either quat and defmat correction. */
+ if (quat) {
+ quat_to_mat3(qmat, quat);
+
+ if (defmat) {
+ mul_m3_series(mat, defmat, qmat, mtx);
+ }
+ else {
+ mul_m3_m3m3(mat, mtx, qmat);
+ }
+ }
+ else {
+ mul_m3_m3m3(mat, mtx, defmat);
+ }
+
+ invert_m3_m3(imat, mat);
+
+ copy_m3_m3(r_td->smtx, imat);
+ copy_m3_m3(r_td->mtx, mat);
+ }
+ else {
+ copy_m3_m3(r_td->smtx, smtx);
+ copy_m3_m3(r_td->mtx, mtx);
+ }
+}
+
+void transform_convert_mesh_crazyspace_free(struct TransMeshDataCrazySpace *r_crazyspace_data)
+{
+ if (r_crazyspace_data->quats) {
+ MEM_freeN(r_crazyspace_data->quats);
+ }
+ if (r_crazyspace_data->defmats) {
+ MEM_freeN(r_crazyspace_data->defmats);
+ }
+}
+
/** \} */
/* -------------------------------------------------------------------- */
@@ -643,19 +748,6 @@ static void VertsToTransData(TransInfo *t,
td->val = bweight;
td->ival = *bweight;
}
- else if (t->mode == TFM_SKIN_RESIZE) {
- MVertSkin *vs = CustomData_bmesh_get(&em->bm->vdata, eve->head.data, CD_MVERT_SKIN);
- if (vs) {
- /* skin node size */
- td->ext = tx;
- copy_v3_v3(tx->isize, vs->radius);
- tx->size = vs->radius;
- td->val = vs->radius;
- }
- else {
- td->flag |= TD_SKIP;
- }
- }
else if (t->mode == TFM_SHRINKFATTEN) {
td->ext = tx;
tx->isize[0] = BM_vert_calc_shell_factor_ex(eve, no, BM_ELEM_SELECT);
@@ -677,6 +769,7 @@ void createTransEditVerts(TransInfo *t)
struct TransIslandData island_data = {NULL};
struct TransMirrorData mirror_data = {NULL};
+ struct TransMeshDataCrazySpace crazyspace_data = {NULL};
/**
* Quick check if we can transform.
@@ -730,7 +823,7 @@ void createTransEditVerts(TransInfo *t)
* TODO(Germano): Extend the list to exclude other modes. */
const bool calc_island_axismtx = !ELEM(t->mode, TFM_SHRINKFATTEN);
- editmesh_islands_info_calc(
+ transform_convert_mesh_islands_calc(
em, calc_single_islands, calc_island_center, calc_island_axismtx, &island_data);
}
@@ -748,7 +841,7 @@ void createTransEditVerts(TransInfo *t)
if (is_island_center) {
dists_index = MEM_mallocN(bm->totvert * sizeof(int), __func__);
}
- editmesh_set_connectivity_distance(em->bm, mtx, dists, dists_index);
+ transform_convert_mesh_connectivity_distance(em->bm, mtx, dists, dists_index);
}
/* Create TransDataMirror. */
@@ -757,7 +850,8 @@ void createTransEditVerts(TransInfo *t)
bool use_select = (t->flag & T_PROP_EDIT) == 0;
const 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);
+ transform_convert_mesh_mirrordata_calc(
+ em, use_select, use_topology, mirror_axis, &mirror_data);
if (mirror_data.vert_map) {
tc->data_mirror_len = mirror_data.mirror_elem_len;
@@ -774,11 +868,14 @@ void createTransEditVerts(TransInfo *t)
}
}
+ /* Detect CrazySpace [tm]. */
+ transform_convert_mesh_crazyspace_detect(t, tc, em, &crazyspace_data);
+
/* 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)) {
+ if (t->mode == TFM_SHRINKFATTEN) {
/* warning, this is overkill, we only need 2 extra floats,
* but this stores loads of extra stuff, for TFM_SHRINKFATTEN its even more overkill
* since we may not use the 'alt' transform mode to maintain shell thickness,
@@ -787,49 +884,6 @@ void createTransEditVerts(TransInfo *t)
"TransObData ext");
}
- /* 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));
-
- /* Use evaluated state because we need b-bone cache. */
- Scene *scene_eval = (Scene *)DEG_get_evaluated_id(t->depsgraph, &t->scene->id);
- Object *obedit_eval = (Object *)DEG_get_evaluated_id(t->depsgraph, &tc->obedit->id);
- BMEditMesh *em_eval = BKE_editmesh_from_object(obedit_eval);
- /* check if we can use deform matrices for modifier from the
- * start up to stack, they are more accurate than quats */
- totleft = BKE_crazyspace_get_first_deform_matrices_editbmesh(
- t->depsgraph, scene_eval, obedit_eval, em_eval, &defmats, &defcos);
- }
-
- /* If we still have more modifiers, also do crazy-space
- * correction with \a quats, relative to the coordinates after
- * the modifiers that support deform matrices \a defcos. */
-
-#if 0 /* TODO, fix crazy-space & extrude so it can be enabled for general use - campbell */
- if ((totleft > 0) || (totleft == -1))
-#else
- 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);
- if (mappedcos) {
- MEM_freeN(mappedcos);
- }
- }
-
- if (defcos) {
- MEM_freeN(defcos);
- }
- }
-
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);
@@ -894,34 +948,14 @@ void createTransEditVerts(TransInfo *t)
}
/* CrazySpace */
- const bool use_quats = quats && BM_elem_flag_test(eve, BM_ELEM_TAG);
- if (use_quats || defmats) {
- float mat[3][3], qmat[3][3], imat[3][3];
-
- /* Use both or either quat and defmat correction. */
- if (use_quats) {
- quat_to_mat3(qmat, quats[BM_elem_index_get(eve)]);
-
- if (defmats) {
- mul_m3_series(mat, defmats[a], qmat, mtx);
- }
- else {
- mul_m3_m3m3(mat, mtx, qmat);
- }
- }
- else {
- mul_m3_m3m3(mat, mtx, defmats[a]);
- }
-
- invert_m3_m3(imat, mat);
-
- copy_m3_m3(tob->smtx, imat);
- copy_m3_m3(tob->mtx, mat);
- }
- else {
- copy_m3_m3(tob->smtx, smtx);
- copy_m3_m3(tob->mtx, mtx);
- }
+ transform_convert_mesh_crazyspace_transdata_set(
+ mtx,
+ smtx,
+ crazyspace_data.defmats ? crazyspace_data.defmats[a] : NULL,
+ crazyspace_data.quats && BM_elem_flag_test(eve, BM_ELEM_TAG) ?
+ crazyspace_data.quats[a] :
+ NULL,
+ tob);
if (tc->use_mirror_axis_any) {
if (tc->use_mirror_axis_x && fabsf(tob->loc[0]) < TRANSFORM_MAXDIST_MIRROR) {
@@ -939,24 +973,9 @@ void createTransEditVerts(TransInfo *t)
}
}
- if (island_data.center) {
- MEM_freeN(island_data.center);
- }
- if (island_data.axismtx) {
- MEM_freeN(island_data.axismtx);
- }
- 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);
- }
- if (defmats) {
- MEM_freeN(defmats);
- }
+ transform_convert_mesh_islanddata_free(&island_data);
+ transform_convert_mesh_mirrordata_free(&mirror_data);
+ transform_convert_mesh_crazyspace_free(&crazyspace_data);
if (dists) {
MEM_freeN(dists);
}
@@ -1523,7 +1542,7 @@ static void mesh_customdatacorrect_restore(struct TransInfo *t)
*
* \{ */
-static void transform_apply_to_mirror(TransInfo *t)
+static void mesh_apply_to_mirror(TransInfo *t)
{
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
if (tc->use_mirror_axis_any) {
@@ -1570,7 +1589,7 @@ void recalcData_mesh(TransInfo *t)
clipMirrorModifier(t);
if ((t->flag & T_NO_MIRROR) == 0 && (t->options & CTX_NO_MIRROR) == 0) {
- transform_apply_to_mirror(t);
+ mesh_apply_to_mirror(t);
}
mesh_customdatacorrect_apply(t, false);