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
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`.
-rw-r--r--source/blender/editors/transform/CMakeLists.txt1
-rw-r--r--source/blender/editors/transform/transform_convert.c17
-rw-r--r--source/blender/editors/transform/transform_convert.h56
-rw-r--r--source/blender/editors/transform/transform_convert_mesh.c307
-rw-r--r--source/blender/editors/transform/transform_convert_mesh_skin.c296
-rw-r--r--source/blender/editors/transform/transform_convert_mesh_uv.c2
-rw-r--r--source/blender/editors/transform/transform_mode_skin_resize.c4
7 files changed, 533 insertions, 150 deletions
diff --git a/source/blender/editors/transform/CMakeLists.txt b/source/blender/editors/transform/CMakeLists.txt
index a2eb68a1b71..faed8abb202 100644
--- a/source/blender/editors/transform/CMakeLists.txt
+++ b/source/blender/editors/transform/CMakeLists.txt
@@ -50,6 +50,7 @@ set(SRC
transform_convert_mball.c
transform_convert_mesh.c
transform_convert_mesh_edge.c
+ transform_convert_mesh_skin.c
transform_convert_mesh_uv.c
transform_convert_nla.c
transform_convert_node.c
diff --git a/source/blender/editors/transform/transform_convert.c b/source/blender/editors/transform/transform_convert.c
index dd35d67e1fa..fb365da6b43 100644
--- a/source/blender/editors/transform/transform_convert.c
+++ b/source/blender/editors/transform/transform_convert.c
@@ -1078,7 +1078,12 @@ void createTransData(bContext *C, TransInfo *t)
initTransDataContainers_FromObjectData(t, ob, NULL, 0);
if (t->obedit_type == OB_MESH) {
- convert_type = TC_MESH_VERTS;
+ if (t->mode == TFM_SKIN_RESIZE) {
+ convert_type = TC_MESH_SKIN;
+ }
+ else {
+ convert_type = TC_MESH_VERTS;
+ }
}
else if (ELEM(t->obedit_type, OB_CURVE, OB_SURF)) {
convert_type = TC_CURVE_VERTS;
@@ -1202,6 +1207,9 @@ void createTransData(bContext *C, TransInfo *t)
case TC_MESH_EDGES:
createTransEdge(t);
break;
+ case TC_MESH_SKIN:
+ createTransMeshSkin(t);
+ break;
case TC_MESH_UV:
createTransUVs(C, t);
break;
@@ -1273,9 +1281,9 @@ void createTransData(bContext *C, TransInfo *t)
if (ELEM(convert_type, TC_ACTION_DATA, TC_GRAPH_EDIT_DATA)) {
/* Distance has already been set. */
}
- else if (convert_type == TC_MESH_VERTS) {
+ else if (ELEM(convert_type, TC_MESH_VERTS, TC_MESH_SKIN)) {
if (t->flag & T_PROP_CONNECTED) {
- /* Already calculated by editmesh_set_connectivity_distance. */
+ /* Already calculated by transform_convert_mesh_connectivity_distance. */
}
else {
set_prop_dist(t, false);
@@ -1536,6 +1544,9 @@ void recalcData(TransInfo *t)
case TC_MESH_EDGES:
recalcData_mesh(t);
break;
+ case TC_MESH_SKIN:
+ recalcData_mesh_skin(t);
+ break;
case TC_MESH_UV:
recalcData_uv(t);
break;
diff --git a/source/blender/editors/transform/transform_convert.h b/source/blender/editors/transform/transform_convert.h
index 59fcd016020..be4322b42e2 100644
--- a/source/blender/editors/transform/transform_convert.h
+++ b/source/blender/editors/transform/transform_convert.h
@@ -25,6 +25,8 @@
#pragma once
struct BezTriple;
+struct BMEditMesh;
+struct BMesh;
struct FCurve;
struct ListBase;
struct Object;
@@ -65,6 +67,7 @@ typedef enum eTransConvertType {
TC_MBALL_VERTS,
TC_MESH_VERTS,
TC_MESH_EDGES,
+ TC_MESH_SKIN,
TC_MESH_UV,
TC_NLA_DATA,
TC_NODE_DATA,
@@ -136,6 +139,55 @@ void special_aftertrans_update__mask(bContext *C, TransInfo *t);
void createTransMBallVerts(TransInfo *t);
/* transform_convert_mesh.c */
+struct TransIslandData {
+ float (*center)[3];
+ float (*axismtx)[3][3];
+ int island_tot;
+ int *island_vert_map;
+};
+
+struct MirrorDataVert {
+ int index;
+ int flag;
+};
+
+struct TransMirrorData {
+ struct MirrorDataVert *vert_map;
+ int mirror_elem_len;
+};
+
+struct TransMeshDataCrazySpace {
+ float (*quats)[4];
+ float (*defmats)[3][3];
+};
+
+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);
+void transform_convert_mesh_islanddata_free(struct TransIslandData *island_data);
+void transform_convert_mesh_connectivity_distance(struct BMesh *bm,
+ const float mtx[3][3],
+ float *dists,
+ int *index);
+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);
+void transform_convert_mesh_mirrordata_free(struct TransMirrorData *mirror_data);
+void transform_convert_mesh_crazyspace_detect(TransInfo *t,
+ struct TransDataContainer *tc,
+ struct BMEditMesh *em,
+ struct TransMeshDataCrazySpace *r_crazyspace_data);
+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);
+void transform_convert_mesh_crazyspace_free(struct TransMeshDataCrazySpace *r_crazyspace_data);
+
void createTransEditVerts(TransInfo *t);
void recalcData_mesh(TransInfo *t);
void special_aftertrans_update__mesh(bContext *C, TransInfo *t);
@@ -143,6 +195,10 @@ void special_aftertrans_update__mesh(bContext *C, TransInfo *t);
/* transform_convert_mesh_edge.c */
void createTransEdge(TransInfo *t);
+/* transform_convert_mesh_skin.c */
+void createTransMeshSkin(TransInfo *t);
+void recalcData_mesh_skin(TransInfo *t);
+
/* transform_convert_mesh_uv.c */
void createTransUVs(bContext *C, TransInfo *t);
void recalcData_uv(TransInfo *t);
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);
diff --git a/source/blender/editors/transform/transform_convert_mesh_skin.c b/source/blender/editors/transform/transform_convert_mesh_skin.c
new file mode 100644
index 00000000000..78f9380f383
--- /dev/null
+++ b/source/blender/editors/transform/transform_convert_mesh_skin.c
@@ -0,0 +1,296 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ */
+
+/** \file
+ * \ingroup edtransform
+ */
+
+#include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_math.h"
+
+#include "BKE_context.h"
+#include "BKE_crazyspace.h"
+#include "BKE_editmesh.h"
+#include "BKE_modifier.h"
+#include "BKE_scene.h"
+
+#include "ED_mesh.h"
+
+#include "DEG_depsgraph_query.h"
+
+#include "transform.h"
+#include "transform_orientations.h"
+
+#include "transform_convert.h"
+
+/* -------------------------------------------------------------------- */
+/** \name Edit Mesh #CD_MVERT_SKIN Transform Creation
+ *
+ * \{ */
+
+static void mesh_skin_transdata_create(TransInfo *t,
+ TransDataBasic *td,
+ BMEditMesh *em,
+ BMVert *eve,
+ const struct TransIslandData *island_data,
+ const int island_index)
+{
+ BLI_assert(BM_elem_flag_test(eve, BM_ELEM_HIDDEN) == 0);
+ MVertSkin *vs = CustomData_bmesh_get(&em->bm->vdata, eve->head.data, CD_MVERT_SKIN);
+ if (vs) {
+ copy_v3_v3(td->iloc, vs->radius);
+ td->loc = vs->radius;
+ }
+ else {
+ td->flag |= TD_SKIP;
+ }
+
+ td->flag = 0;
+
+ if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) {
+ td->flag |= TD_SELECTED;
+ }
+
+ td->extra = eve;
+}
+
+void createTransMeshSkin(TransInfo *t)
+{
+ BLI_assert(t->mode == TFM_SKIN_RESIZE);
+ FOREACH_TRANS_DATA_CONTAINER (t, tc) {
+ BMEditMesh *em = BKE_editmesh_from_object(tc->obedit);
+ Mesh *me = tc->obedit->data;
+ BMesh *bm = em->bm;
+ BMVert *eve;
+ BMIter iter;
+ 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;
+
+ struct TransIslandData island_data = {NULL};
+ struct TransMirrorData mirror_data = {NULL};
+ struct TransMeshDataCrazySpace crazyspace_data = {NULL};
+
+ /**
+ * Quick check if we can transform.
+ *
+ * \note ignore modes here, even in edge/face modes,
+ * transform data is created by selected vertices.
+ */
+
+ /* Support other objects using PET to adjust these, unless connected is enabled. */
+ if ((!prop_mode || (prop_mode & T_PROP_CONNECTED)) && (bm->totvertsel == 0)) {
+ continue;
+ }
+
+ int data_len = 0;
+ if (prop_mode) {
+ BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
+ if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) {
+ data_len++;
+ }
+ }
+ }
+ else {
+ data_len = bm->totvertsel;
+ }
+
+ if (data_len == 0) {
+ continue;
+ }
+
+ const bool is_island_center = (t->around == V3D_AROUND_LOCAL_ORIGINS);
+ 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 = false;
+ const bool calc_island_axismtx = false;
+
+ transform_convert_mesh_islands_calc(
+ em, calc_single_islands, calc_island_center, calc_island_axismtx, &island_data);
+ }
+
+ 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);
+
+ /* 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__);
+ }
+ transform_convert_mesh_connectivity_distance(em->bm, mtx, dists, dists_index);
+ }
+
+ /* 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;
+ const bool mirror_axis[3] = {
+ tc->use_mirror_axis_x, tc->use_mirror_axis_y, tc->use_mirror_axis_z};
+ 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;
+ 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--;
+ }
+ }
+ }
+ }
+ }
+
+ /* 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)");
+
+ TransData *td = tc->data;
+ TransDataMirror *td_mirror = tc->data_mirror;
+ BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, a) {
+ if (BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) {
+ continue;
+ }
+
+ int island_index = -1;
+ if (island_data.island_vert_map) {
+ const int connected_index = (dists_index && dists_index[a] != -1) ? dists_index[a] : a;
+ island_index = island_data.island_vert_map[connected_index];
+ }
+
+ if (mirror_data.vert_map && mirror_data.vert_map[a].index != -1) {
+ mesh_skin_transdata_create(
+ t, (TransDataBasic *)td_mirror, em, eve, &island_data, island_index);
+
+ int elem_index = mirror_data.vert_map[a].index;
+ BMVert *v_src = BM_vert_at_index(bm, elem_index);
+ MVertSkin *vs = CustomData_bmesh_get(&em->bm->vdata, v_src->head.data, CD_MVERT_SKIN);
+
+ td_mirror->flag |= mirror_data.vert_map[a].flag;
+ td_mirror->loc_src = vs->radius;
+ td_mirror++;
+ }
+ else if (prop_mode || BM_elem_flag_test(eve, BM_ELEM_SELECT)) {
+ mesh_skin_transdata_create(t, (TransDataBasic *)td, em, eve, &island_data, island_index);
+
+ if (t->around == V3D_AROUND_LOCAL_ORIGINS) {
+ createSpaceNormal(td->axismtx, eve->no);
+ }
+ else {
+ /* Setting normals */
+ copy_v3_v3(td->axismtx[2], eve->no);
+ td->axismtx[0][0] = td->axismtx[0][1] = td->axismtx[0][2] = td->axismtx[1][0] =
+ td->axismtx[1][1] = td->axismtx[1][2] = 0.0f;
+ }
+
+ if (prop_mode) {
+ if (prop_mode & T_PROP_CONNECTED) {
+ td->dist = dists[a];
+ }
+ else {
+ td->flag |= TD_NOTCONNECTED;
+ td->dist = FLT_MAX;
+ }
+ }
+
+ /* CrazySpace */
+ 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,
+ td);
+
+ td++;
+ }
+ }
+
+ 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);
+ }
+ if (dists_index) {
+ MEM_freeN(dists_index);
+ }
+ }
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Recalc Mesh Data
+ *
+ * \{ */
+
+static void mesh_skin_apply_to_mirror(TransInfo *t)
+{
+ FOREACH_TRANS_DATA_CONTAINER (t, tc) {
+ if (tc->use_mirror_axis_any) {
+ TransDataMirror *td_mirror = tc->data_mirror;
+ for (int i = 0; i < tc->data_mirror_len; i++, td_mirror++) {
+ copy_v3_v3(td_mirror->loc, td_mirror->loc_src);
+ }
+ }
+ }
+}
+
+void recalcData_mesh_skin(TransInfo *t)
+{
+ bool is_canceling = t->state == TRANS_CANCEL;
+ /* mirror modifier clipping? */
+ if (!is_canceling) {
+ if ((t->flag & T_NO_MIRROR) == 0 && (t->options & CTX_NO_MIRROR) == 0) {
+ mesh_skin_apply_to_mirror(t);
+ }
+ }
+
+ FOREACH_TRANS_DATA_CONTAINER (t, tc) {
+ DEG_id_tag_update(tc->obedit->data, 0); /* sets recalc flags */
+ BMEditMesh *em = BKE_editmesh_from_object(tc->obedit);
+ EDBM_mesh_normals_update(em);
+ BKE_editmesh_looptri_calc(em);
+ }
+}
+/** \} */
diff --git a/source/blender/editors/transform/transform_convert_mesh_uv.c b/source/blender/editors/transform/transform_convert_mesh_uv.c
index b54c45e2ab2..52394009d28 100644
--- a/source/blender/editors/transform/transform_convert_mesh_uv.c
+++ b/source/blender/editors/transform/transform_convert_mesh_uv.c
@@ -92,7 +92,7 @@ static void UVsToTransData(const float aspect[2],
*/
static void uv_set_connectivity_distance(BMesh *bm, float *dists, const float aspect[2])
{
- /* Mostly copied from #editmesh_set_connectivity_distance. */
+ /* Mostly copied from #transform_convert_mesh_connectivity_distance. */
BLI_LINKSTACK_DECLARE(queue, BMLoop *);
/* Any BM_ELEM_TAG'd loop is added to 'queue_next', this makes sure that we don't add things
diff --git a/source/blender/editors/transform/transform_mode_skin_resize.c b/source/blender/editors/transform/transform_mode_skin_resize.c
index b4c919cbb86..8beacb844b9 100644
--- a/source/blender/editors/transform/transform_mode_skin_resize.c
+++ b/source/blender/editors/transform/transform_mode_skin_resize.c
@@ -88,8 +88,8 @@ static void applySkinResize(TransInfo *t, const int UNUSED(mval[2]))
}
mat3_to_size(fsize, tmat);
- td->val[0] = td->ext->isize[0] * (1 + (fsize[0] - 1) * td->factor);
- td->val[1] = td->ext->isize[1] * (1 + (fsize[1] - 1) * td->factor);
+ td->loc[0] = td->iloc[0] * (1 + (fsize[0] - 1) * td->factor);
+ td->loc[1] = td->iloc[1] * (1 + (fsize[1] - 1) * td->factor);
}
}