Fix T57852: Mesh X Mirror option not working
D3869 by @lichtwerk w/ own edits
This commit is contained in:
parent
9c7adcfd8b
commit
65b82e09d9
Notes:
blender-bot
2023-02-14 08:38:11 +01:00
Referenced by issue #57852, Edit Mesh: X-Mirror/Topology Mirror not working
|
@ -2171,7 +2171,7 @@ void saveTransform(bContext *C, TransInfo *t, wmOperator *op)
|
|||
}
|
||||
|
||||
if ((prop = RNA_struct_find_property(op->ptr, "mirror"))) {
|
||||
RNA_property_boolean_set(op->ptr, prop, (t->flag & T_MIRROR) != 0);
|
||||
RNA_property_boolean_set(op->ptr, prop, (t->flag & T_NO_MIRROR) == 0);
|
||||
}
|
||||
|
||||
if ((prop = RNA_struct_find_property(op->ptr, "constraint_axis"))) {
|
||||
|
@ -5980,7 +5980,7 @@ static void slide_origdata_create_data_vert(
|
|||
}
|
||||
|
||||
static void slide_origdata_create_data(
|
||||
TransInfo *t, TransDataContainer *tc, SlideOrigData *sod,
|
||||
TransDataContainer *tc, SlideOrigData *sod,
|
||||
TransDataGenericSlideVert *sv_array, unsigned int v_stride, unsigned int v_num)
|
||||
{
|
||||
if (sod->use_origfaces) {
|
||||
|
@ -6015,7 +6015,7 @@ static void slide_origdata_create_data(
|
|||
slide_origdata_create_data_vert(bm, sod, sv);
|
||||
}
|
||||
|
||||
if (t->flag & T_MIRROR) {
|
||||
if (tc->mirror.axis_flag) {
|
||||
TransData *td = tc->data;
|
||||
TransDataGenericSlideVert *sv_mirror;
|
||||
|
||||
|
@ -6995,7 +6995,7 @@ static bool createEdgeSlideVerts_double_side(TransInfo *t, TransDataContainer *t
|
|||
/* create copies of faces for customdata projection */
|
||||
bmesh_edit_begin(bm, BMO_OPTYPE_FLAG_UNTAN_MULTIRES);
|
||||
slide_origdata_init_data(tc, &sld->orig_data);
|
||||
slide_origdata_create_data(t, tc, &sld->orig_data, (TransDataGenericSlideVert *)sld->sv, sizeof(*sld->sv), sld->totsv);
|
||||
slide_origdata_create_data(tc, &sld->orig_data, (TransDataGenericSlideVert *)sld->sv, sizeof(*sld->sv), sld->totsv);
|
||||
|
||||
if (rv3d) {
|
||||
calcEdgeSlide_even(t, tc, sld, mval);
|
||||
|
@ -7190,7 +7190,7 @@ static bool createEdgeSlideVerts_single_side(TransInfo *t, TransDataContainer *t
|
|||
/* create copies of faces for customdata projection */
|
||||
bmesh_edit_begin(bm, BMO_OPTYPE_FLAG_UNTAN_MULTIRES);
|
||||
slide_origdata_init_data(tc, &sld->orig_data);
|
||||
slide_origdata_create_data(t, tc, &sld->orig_data, (TransDataGenericSlideVert *)sld->sv, sizeof(*sld->sv), sld->totsv);
|
||||
slide_origdata_create_data(tc, &sld->orig_data, (TransDataGenericSlideVert *)sld->sv, sizeof(*sld->sv), sld->totsv);
|
||||
|
||||
if (rv3d) {
|
||||
calcEdgeSlide_even(t, tc, sld, mval);
|
||||
|
@ -7806,7 +7806,7 @@ static bool createVertSlideVerts(TransInfo *t, TransDataContainer *tc)
|
|||
|
||||
bmesh_edit_begin(bm, BMO_OPTYPE_FLAG_UNTAN_MULTIRES);
|
||||
slide_origdata_init_data(tc, &sld->orig_data);
|
||||
slide_origdata_create_data(t, tc, &sld->orig_data, (TransDataGenericSlideVert *)sld->sv, sizeof(*sld->sv), sld->totsv);
|
||||
slide_origdata_create_data(tc, &sld->orig_data, (TransDataGenericSlideVert *)sld->sv, sizeof(*sld->sv), sld->totsv);
|
||||
|
||||
sld->em = em;
|
||||
|
||||
|
|
|
@ -514,6 +514,16 @@ typedef struct TransDataContainer {
|
|||
/** Center of transformation (in local-space), Calculated from #TransInfo.center_global. */
|
||||
float center_local[3];
|
||||
|
||||
/**
|
||||
* Mirror option
|
||||
*/
|
||||
struct {
|
||||
/* Currently for mesh X mirror only. */
|
||||
int axis_flag;
|
||||
/** Set to -1.0f or 1.0 when use_mirror is set. */
|
||||
float sign;
|
||||
} mirror;
|
||||
|
||||
TransCustomDataContainer custom;
|
||||
} TransDataContainer;
|
||||
|
||||
|
@ -618,8 +628,6 @@ typedef struct TransInfo {
|
|||
|
||||
short prop_mode;
|
||||
|
||||
short mirror;
|
||||
|
||||
float values[4];
|
||||
/** Offset applied ontop of modal input. */
|
||||
float values_modal_offset[4];
|
||||
|
@ -710,7 +718,8 @@ enum {
|
|||
/** Auto-ik is on. */
|
||||
T_AUTOIK = 1 << 18,
|
||||
|
||||
T_MIRROR = 1 << 19,
|
||||
/** Don't use mirror even if the data-block option is set. */
|
||||
T_NO_MIRROR = 1 << 19,
|
||||
|
||||
T_AUTOVALUES = 1 << 20,
|
||||
|
||||
|
|
|
@ -2676,12 +2676,9 @@ static void createTransEditVerts(TransInfo *t)
|
|||
* Optional, allocate if needed. */
|
||||
int *dists_index = NULL;
|
||||
|
||||
if (t->flag & T_MIRROR) {
|
||||
/* TODO(campbell): xform: We need support for many mirror objects at once! */
|
||||
if (tc->is_active) {
|
||||
EDBM_verts_mirror_cache_begin(em, 0, false, (t->flag & T_PROP_EDIT) == 0, use_topology);
|
||||
mirror = 1;
|
||||
}
|
||||
if (tc->mirror.axis_flag) {
|
||||
EDBM_verts_mirror_cache_begin(em, 0, false, (t->flag & T_PROP_EDIT) == 0, use_topology);
|
||||
mirror = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2791,7 +2788,7 @@ static void createTransEditVerts(TransInfo *t)
|
|||
BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
|
||||
if (BM_elem_flag_test(eve, BM_ELEM_SELECT) && eve->co[0] != 0.0f) {
|
||||
if (eve->co[0] < 0.0f) {
|
||||
t->mirror = -1;
|
||||
tc->mirror.sign = -1.0f;
|
||||
mirror = -1;
|
||||
}
|
||||
break;
|
||||
|
@ -2895,7 +2892,7 @@ cleanup:
|
|||
if (dists_index)
|
||||
MEM_freeN(dists_index);
|
||||
|
||||
if (t->flag & T_MIRROR) {
|
||||
if (tc->mirror.axis_flag) {
|
||||
EDBM_verts_mirror_cache_end(em);
|
||||
}
|
||||
}
|
||||
|
@ -6381,7 +6378,7 @@ static void special_aftertrans_update__mesh(bContext *UNUSED(C), TransInfo *t)
|
|||
char hflag;
|
||||
bool has_face_sel = (bm->totfacesel != 0);
|
||||
|
||||
if (t->flag & T_MIRROR) {
|
||||
if (tc->mirror.axis_flag) {
|
||||
TransData *td;
|
||||
int i;
|
||||
|
||||
|
|
|
@ -237,27 +237,29 @@ static void clipMirrorModifier(TransInfo *t)
|
|||
static void editbmesh_apply_to_mirror(TransInfo *t)
|
||||
{
|
||||
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
|
||||
TransData *td = tc->data;
|
||||
BMVert *eve;
|
||||
int i;
|
||||
if (tc->mirror.axis_flag) {
|
||||
TransData *td = tc->data;
|
||||
BMVert *eve;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < tc->data_len; i++, td++) {
|
||||
if (td->flag & TD_NOACTION)
|
||||
break;
|
||||
if (td->loc == NULL)
|
||||
break;
|
||||
if (td->flag & TD_SKIP)
|
||||
continue;
|
||||
for (i = 0; i < tc->data_len; i++, td++) {
|
||||
if (td->flag & TD_NOACTION)
|
||||
break;
|
||||
if (td->loc == NULL)
|
||||
break;
|
||||
if (td->flag & TD_SKIP)
|
||||
continue;
|
||||
|
||||
eve = td->extra;
|
||||
if (eve) {
|
||||
eve->co[0] = -td->loc[0];
|
||||
eve->co[1] = td->loc[1];
|
||||
eve->co[2] = td->loc[2];
|
||||
}
|
||||
eve = td->extra;
|
||||
if (eve) {
|
||||
eve->co[0] = -td->loc[0];
|
||||
eve->co[1] = td->loc[1];
|
||||
eve->co[2] = td->loc[2];
|
||||
}
|
||||
|
||||
if (td->flag & TD_MIRROR_EDGE) {
|
||||
td->loc[0] = 0;
|
||||
if (td->flag & TD_MIRROR_EDGE) {
|
||||
td->loc[0] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -812,8 +814,11 @@ static void recalcData_objects(TransInfo *t)
|
|||
applyProject(t);
|
||||
clipMirrorModifier(t);
|
||||
}
|
||||
if ((t->options & CTX_NO_MIRROR) == 0 && (t->flag & T_MIRROR))
|
||||
if ((t->flag & T_NO_MIRROR) == 0 &&
|
||||
(t->options & CTX_NO_MIRROR) == 0)
|
||||
{
|
||||
editbmesh_apply_to_mirror(t);
|
||||
}
|
||||
|
||||
if (t->mode == TFM_EDGE_SLIDE) {
|
||||
projectEdgeSlideData(t, false);
|
||||
|
@ -1227,6 +1232,12 @@ void initTransDataContainers_FromObjectData(TransInfo *t, Object *obact, Object
|
|||
|
||||
for (int i = 0; i < objects_len; i++) {
|
||||
TransDataContainer *tc = &t->data_container[i];
|
||||
/* TODO, multiple axes. */
|
||||
tc->mirror.axis_flag = (
|
||||
((t->flag & T_NO_MIRROR) == 0) &&
|
||||
((t->options & CTX_NO_MIRROR) == 0) &&
|
||||
(((Mesh *)objects[i]->data)->editflag & ME_EDIT_MIRROR_X) != 0);
|
||||
|
||||
if (object_mode & OB_MODE_EDIT) {
|
||||
tc->obedit = objects[i];
|
||||
/* Check needed for UV's */
|
||||
|
@ -1548,18 +1559,16 @@ void initTransInfo(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve
|
|||
if (op && ((prop = RNA_struct_find_property(op->ptr, "mirror")) &&
|
||||
RNA_property_is_set(op->ptr, prop)))
|
||||
{
|
||||
if (RNA_property_boolean_get(op->ptr, prop)) {
|
||||
t->flag |= T_MIRROR;
|
||||
t->mirror = 1;
|
||||
if (!RNA_property_boolean_get(op->ptr, prop)) {
|
||||
t->flag |= T_NO_MIRROR;
|
||||
}
|
||||
}
|
||||
// Need stuff to take it from edit mesh or whatnot here
|
||||
else if (t->spacetype == SPACE_VIEW3D) {
|
||||
/* TODO(campbell): xform, get mirror from each object. */
|
||||
if (t->obedit_type == OB_MESH && (((Mesh *)OBACT(t->view_layer)->data)->editflag & ME_EDIT_MIRROR_X)) {
|
||||
t->flag |= T_MIRROR;
|
||||
t->mirror = 1;
|
||||
}
|
||||
else if ((t->spacetype == SPACE_VIEW3D) && (t->obedit_type == OB_MESH)) {
|
||||
/* pass */
|
||||
}
|
||||
else {
|
||||
/* Avoid mirroring for unsupported contexts. */
|
||||
t->options |= CTX_NO_MIRROR;
|
||||
}
|
||||
|
||||
/* setting PET flag only if property exist in operator. Otherwise, assume it's not supported */
|
||||
|
@ -2168,7 +2177,7 @@ void calculatePropRatio(TransInfo *t)
|
|||
if (td->flag & TD_SELECTED) {
|
||||
td->factor = 1.0f;
|
||||
}
|
||||
else if (t->flag & T_MIRROR && td->loc[0] * t->mirror < -0.00001f) {
|
||||
else if (tc->mirror.axis_flag && (td->loc[0] * tc->mirror.sign) < -0.00001f) {
|
||||
td->flag |= TD_SKIP;
|
||||
td->factor = 0.0f;
|
||||
restoreElement(td);
|
||||
|
|
Loading…
Reference in New Issue