Merging r59182 through r59257 from trunk into soc-2013-depsgraph_mt
[blender.git] / source / blender / bmesh / operators / bmo_inset.c
index f799d589b3c02e73b5ea2c810f656d05337b2893..731b895a6b5221d69261854c6fb43cd15f2f462c 100644 (file)
@@ -76,6 +76,7 @@ void bmo_inset_individual_exec(BMesh *bm, BMOperator *op)
        const float thickness = BMO_slot_float_get(op->slots_in, "thickness");
        const float depth = BMO_slot_float_get(op->slots_in, "depth");
        const bool use_even_offset = BMO_slot_bool_get(op->slots_in, "use_even_offset");
+       const bool use_relative_offset = BMO_slot_bool_get(op->slots_in, "use_relative_offset");
        const bool use_interpolate = BMO_slot_bool_get(op->slots_in, "use_interpolate");
 
        /* Only tag faces in slot */
@@ -83,7 +84,7 @@ void bmo_inset_individual_exec(BMesh *bm, BMOperator *op)
 
        BMO_slot_buffer_hflag_enable(bm, op->slots_in, "faces", BM_FACE, BM_ELEM_TAG, false);
 
-       BMO_ITER(f, &oiter, op->slots_in, "faces", BM_FACE) {
+       BMO_ITER (f, &oiter, op->slots_in, "faces", BM_FACE) {
                BMFace *f_new_inner;
                BMLoop *l_iter, *l_first;
                BMLoop *l_iter_inner = NULL;
@@ -146,6 +147,10 @@ void bmo_inset_individual_exec(BMesh *bm, BMOperator *op)
                        }
 
                        /* Modify vertices and their normals */
+                       if (use_relative_offset) {
+                               mul_v3_fl(tvec, (BM_edge_calc_length(l_iter->e) + BM_edge_calc_length(l_iter->prev->e)) / 2.0f);
+                       }
+
                        madd_v3_v3fl(v_new_co, tvec, thickness);
 
                        /* Set normal, add depth and write new vertex position*/
@@ -272,6 +277,8 @@ static void bm_interp_face_store(InterpFace *iface, BMesh *bm, BMFace *f, MemAre
        void *axis_mat     = iface->axis_mat;
        int i;
 
+       BLI_assert(BM_face_is_normal_valid(f));
+
        axis_dominant_v3_to_m3(axis_mat, f->no);
 
        iface->f = f;
@@ -450,7 +457,7 @@ void bmo_inset_region_exec(BMesh *bm, BMOperator *op)
 
 
                /* run the separate arg */
-               bmesh_edge_separate(bm, es->e_old, es->l);
+               bmesh_edge_separate(bm, es->e_old, es->l, false);
 
                /* calc edge-split info */
                es->e_new = es->l->e;
@@ -472,13 +479,22 @@ void bmo_inset_region_exec(BMesh *bm, BMOperator *op)
 
                /* initialize interpolation vars */
                /* this could go in its own loop,
-                * only use the 'es->l->f' so we don't store loops for faces which have no mixed selection */
+                * only use the 'es->l->f' so we don't store loops for faces which have no mixed selection
+                *
+                * note: faces on the other side of the inset will be interpolated too since this is hard to
+                * detect, just allow it even though it will cause some redundant interpolation */
                if (use_interpolate) {
-                       const int j = BM_elem_index_get((f = es->l->f));
-                       if (iface_array[j] == NULL) {
-                               InterpFace *iface = BLI_memarena_alloc(interp_arena, sizeof(*iface));
-                               bm_interp_face_store(iface, bm, f, interp_arena);
-                               iface_array[j] = iface;
+                       BMIter viter;
+                       BM_ITER_ELEM (v, &viter, es->l->e, BM_VERTS_OF_EDGE) {
+                               BMIter fiter;
+                               BM_ITER_ELEM (f, &fiter, v, BM_FACES_OF_VERT) {
+                                       const int j = BM_elem_index_get(f);
+                                       if (iface_array[j] == NULL) {
+                                               InterpFace *iface = BLI_memarena_alloc(interp_arena, sizeof(*iface));
+                                               bm_interp_face_store(iface, bm, f, interp_arena);
+                                               iface_array[j] = iface;
+                                       }
+                               }
                        }
                }
                /* done interpolation */
@@ -519,7 +535,7 @@ void bmo_inset_region_exec(BMesh *bm, BMOperator *op)
                                /* disable touching twice, this _will_ happen if the flags not disabled */
                                BM_elem_flag_disable(v, BM_ELEM_TAG);
 
-                               bmesh_vert_separate(bm, v, &vout, &r_vout_len);
+                               bmesh_vert_separate(bm, v, &vout, &r_vout_len, false);
                                v = NULL; /* don't use again */
 
                                /* in some cases the edge doesn't split off */
@@ -780,7 +796,7 @@ void bmo_inset_region_exec(BMesh *bm, BMOperator *op)
 #if 0
                /* don't use this because face boundaries have no adjacent loops and won't be filled in.
                 * instead copy from the opposite side with the code below */
-               BM_face_copy_shared(bm, f);
+               BM_face_copy_shared(bm, f, NULL, NULL);
 #else
                {
                        /* 2 inner loops on the edge between the new face and the original */