Page MenuHome

Pivot Center doesn't compute mirror elements
Open, Confirmed, MediumPublic

Description

System Information
Operating system: Darwin-17.2.0-x86_64-i386-64bit 64 Bits
Graphics card: NVIDIA GeForce GTX 1050 Ti OpenGL Engine NVIDIA Corporation 4.1 NVIDIA-10.27.6 378.10.10.10.20.109

Blender Version
Broken: version: 2.82 (sub 0), branch: master, commit date: 2019-10-16 09:29, hash: rBa3f7ae1b9682
Worked: (optional)

Short description of error
When you scale around the median point with x axis mirroring enabled, the result is not calculated from the median.

Exact steps for others to reproduce the error
see video.

Add circle mesh
turn on x axis mirroring (or any other axis)
scale around the median
It will give an unexpected result (unless you have topology mirror also enabled)

This does not work the same as 2.79 (excluding the extra axes of course)

Event Timeline

Jacques Lucke (JacquesLucke) lowered the priority of this task from Needs Triage by Developer to Confirmed, Medium.

I can confirm the issue. Looks like not all selected vertices are used to compute the median point.

Assigning to @Germano Cavalcante (mano-wii), because it might be caused by rB3bd4f229beb (haven't tested),

Germano Cavalcante (mano-wii) renamed this task from Mirror symmetry gives unexpected results to Pivot Center doesn't compute mirror elements.Oct 16 2019, 5:00 PM

Here a less invasive solution to fix this problem.
The idea is to change the TrasData->center of objects with mirror elements.
This changes the behavior of individual origins when the mirrored elements are also selected, but I don't consider it a regression. (The solution may also ignore this particular case).
Solution:

1diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h
2index ff2afbc0cd7..4b31931560c 100644
3--- a/source/blender/editors/transform/transform.h
4+++ b/source/blender/editors/transform/transform.h
5@@ -426,6 +426,7 @@ typedef struct TransDataMirror {
6 int sign_x : 2;
7 int sign_y : 2;
8 int sign_z : 2;
9+ uint flag : 2;
10 } TransDataMirror;
11
12 typedef struct MouseInput {
13@@ -825,6 +826,7 @@ enum {
14 /** #TransData.flag */
15 enum {
16 TD_SELECTED = 1 << 0,
17+ TD_NOCENTER = 1 << 1,
18 TD_NOACTION = 1 << 2,
19 TD_USEQUAT = 1 << 3,
20 TD_NOTCONNECTED = 1 << 4,
21@@ -832,7 +834,6 @@ enum {
22 TD_SINGLESIZE = 1 << 5,
23 /** Scale relative to individual element center */
24 TD_INDIVIDUAL_SCALE = 1 << 8,
25- TD_NOCENTER = 1 << 9,
26 /** #TransData.ext abused for particle key timing. */
27 TD_NO_EXT = 1 << 10,
28 /** don't transform this data */
29diff --git a/source/blender/editors/transform/transform_convert_mesh.c b/source/blender/editors/transform/transform_convert_mesh.c
30index f1928433491..c0451474281 100644
31--- a/source/blender/editors/transform/transform_convert_mesh.c
32+++ b/source/blender/editors/transform/transform_convert_mesh.c
33@@ -540,6 +540,7 @@ static TransDataMirror *editmesh_mirror_data_calc(BMEditMesh *em,
34 mirror_data_iter->sign_x = index[0] && index[0][i] == -2 ? -1 : 1;
35 mirror_data_iter->sign_y = index[1] && index[1][i] == -2 ? -1 : 1;
36 mirror_data_iter->sign_z = index[2] && index[2][i] == -2 ? -1 : 1;
37+ mirror_data_iter->flag = BM_elem_flag_test(eve, BM_ELEM_SELECT) ? TD_SELECTED : 0;
38 mirror_data_iter->extra = eve;
39
40 mirror_data_iter++;
41@@ -799,6 +800,9 @@ void createTransEditVerts(TransInfo *t)
42 }
43 }
44
45+ /* Used for mirror only. */
46+ uint tod_index = 0;
47+
48 BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, a) {
49 if (BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) {
50 continue;
51@@ -881,12 +885,40 @@ void createTransEditVerts(TransInfo *t)
52 if (tc->mirror.axis_z && fabsf(tob->loc[2]) < TRANSFORM_MAXDIST_MIRROR) {
53 tob->flag |= TD_MIRROR_EDGE_Z;
54 }
55+
56+ BM_elem_index_set(eve, tod_index);
57+ tod_index++;
58 }
59
60 tob++;
61 }
62 }
63
64+ if (tc->mirror.use_mirror_any) {
65+ bm->elem_index_dirty |= BM_VERT;
66+
67+ /* Change the center of `TransData` elements according to the mirrored elements.
68+ * This solves pivot center calculation problems. (See T70873) */
69+ TransDataMirror *mirror_data_iter = tc->mirror.data;
70+ for (int i = tc->mirror.data_len; i--; mirror_data_iter++) {
71+ if ((mirror_data_iter->flag & TD_SELECTED) == 0) {
72+ continue;
73+ }
74+ eve = (BMVert *)((char *)mirror_data_iter->loc_src - offsetof(BMVert, co));
75+ int tob_index = BM_elem_index_get(eve);
76+ tob = &tc->data[tob_index];
77+ if (mirror_data_iter->sign_x == -1) {
78+ tob->center[0] = 0.0f;
79+ }
80+ if (mirror_data_iter->sign_y == -1) {
81+ tob->center[1] = 0.0f;
82+ }
83+ if (mirror_data_iter->sign_z == -1) {
84+ tob->center[2] = 0.0f;
85+ }
86+ }
87+ }
88+
89 if (island_info) {
90 MEM_freeN(island_info);
91 MEM_freeN(island_vert_map);