Fix T57852: Mesh X Mirror option not working
authorCampbell Barton <ideasman42@gmail.com>
Mon, 14 Jan 2019 03:59:18 +0000 (14:59 +1100)
committerCampbell Barton <ideasman42@gmail.com>
Mon, 14 Jan 2019 04:14:39 +0000 (15:14 +1100)
D3869 by @lichtwerk w/ own edits

source/blender/editors/transform/transform.c
source/blender/editors/transform/transform.h
source/blender/editors/transform/transform_conversions.c
source/blender/editors/transform/transform_generics.c

index 055e974..c70bfc6 100644 (file)
@@ -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;
 
index 115c063..530c03d 100644 (file)
@@ -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,
 
index 6e4386a..cf911a9 100644 (file)
@@ -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;
 
index 8ae2373..5f7d3ec 100644 (file)
@@ -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;
-
-                       eve = td->extra;
-                       if (eve) {
-                               eve->co[0] = -td->loc[0];
-                               eve->co[1] = td->loc[1];
-                               eve->co[2] = td->loc[2];
-                       }
+                       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;
 
-                       if (td->flag & TD_MIRROR_EDGE) {
-                               td->loc[0] = 0;
+                               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;
+                               }
                        }
                }
        }
@@ -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);