Change edgeloop delete to use dissolve, fixes bug [#35738].
authorCampbell Barton <ideasman42@gmail.com>
Fri, 14 Jun 2013 03:04:36 +0000 (03:04 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Fri, 14 Jun 2013 03:04:36 +0000 (03:04 +0000)
Was using edge-slide & remove-doubles but this was error prone since remove doubles could fail in some cases or find doubles where it shouldn't (with very small scale objects).

This gives more predictable behavior when the edges of a loop wouldnt slide (in that case they would just drag over to one of the sides with no user control)
and multiple edge loops work better too. eg:
- http://www.graphicall.org/ftp/ideasman42/edge_loop_del_update.png

release/scripts/startup/bl_operators/wm.py
source/blender/editors/mesh/editmesh_tools.c
source/blender/editors/mesh/mesh_intern.h
source/blender/editors/mesh/mesh_ops.c

index 9cd9131ec4be454b0492db37fc88bab5e6d94d72..fd1f538efd33d0c80bd2bc045738d126ba5ecd69 100644 (file)
@@ -32,30 +32,6 @@ from rna_prop_ui import rna_idprop_ui_prop_get, rna_idprop_ui_prop_clear
 from bpy.app.translations import pgettext_tip as tip_
 
 
-class MESH_OT_delete_edgeloop(Operator):
-    """Delete an edge loop by merging the faces on each side """ \
-    """to a single face loop"""
-    bl_idname = "mesh.delete_edgeloop"
-    bl_label = "Delete Edge Loop"
-    bl_options = {'UNDO', 'REGISTER'}
-
-    @classmethod
-    def poll(cls, context):
-        return bpy.ops.transform.edge_slide.poll()
-
-    def execute(self, context):
-        mesh = context.object.data
-        use_mirror_x = mesh.use_mirror_x
-        mesh.use_mirror_x = False
-        if 'FINISHED' in bpy.ops.transform.edge_slide(value=1.0, correct_uv=True):
-            bpy.ops.mesh.select_more()
-            bpy.ops.mesh.remove_doubles()
-            ret = {'FINISHED'}
-        else:
-            ret = {'CANCELLED'}
-        mesh.use_mirror_x = use_mirror_x
-        return ret
-
 rna_path_prop = StringProperty(
         name="Context Attributes",
         description="RNA context string",
index fa29a1e2ea8786304261d5a36b197d63d81d18f7..3581902e29e5e010feed4e99ebc576a927679858 100644 (file)
@@ -3136,6 +3136,63 @@ void MESH_OT_dissolve_limited(wmOperatorType *ot)
                          "Delimit dissolve operation");
 }
 
+/* internally uses dissolve */
+static int edbm_delete_edgeloop_exec(bContext *C, wmOperator *op)
+{
+       Object *obedit = CTX_data_edit_object(C);
+       BMEditMesh *em = BKE_editmesh_from_object(obedit);
+
+       const bool use_face_split = RNA_boolean_get(op->ptr, "use_face_split");
+
+       /* deal with selection */
+       {
+               BMEdge *e;
+               BMIter iter;
+
+               BM_mesh_elem_hflag_disable_all(em->bm, BM_FACE, BM_ELEM_TAG, false);
+
+               BM_ITER_MESH (e, &iter, em->bm, BM_EDGES_OF_MESH) {
+                       if (BM_elem_flag_test(e, BM_ELEM_SELECT)) {
+                               BMLoop *l_iter = e->l;
+                               do {
+                                       BM_elem_flag_enable(l_iter->f, BM_ELEM_TAG);
+                               } while ((l_iter = l_iter->radial_next) != e->l);
+                       }
+               }
+       }
+
+       if (!EDBM_op_callf(em, op,
+                          "dissolve_edges edges=%he use_verts=%b use_face_split=%b",
+                          BM_ELEM_SELECT, true, use_face_split))
+       {
+               return OPERATOR_CANCELLED;
+       }
+
+       BM_mesh_elem_hflag_enable_test(em->bm, BM_FACE, BM_ELEM_SELECT, true, BM_ELEM_TAG);
+
+       EDBM_update_generic(em, true, true);
+
+       return OPERATOR_FINISHED;
+}
+
+void MESH_OT_delete_edgeloop(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name = "Delete Edge Loop";
+       ot->description = "Delete an edge loop by merging the faces on each side";
+       ot->idname = "MESH_OT_delete_edgeloop";
+
+       /* api callbacks */
+       ot->exec = edbm_delete_edgeloop_exec;
+       ot->poll = ED_operator_editmesh;
+
+       /* flags */
+       ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+       RNA_def_boolean(ot->srna, "use_face_split", true, "Face Split",
+                       "Split off face corners to maintain surrounding geometry");
+}
+
 static int edbm_split_exec(bContext *C, wmOperator *op)
 {
        Object *ob = CTX_data_edit_object(C);
index 2102ede2672b2be8cb3ee7fb566c641f3633f892..bc74f4a8bf554c042b5881e661043906f17c27ec 100644 (file)
@@ -202,6 +202,7 @@ void MESH_OT_dissolve_verts(struct wmOperatorType *ot);
 void MESH_OT_dissolve_edges(struct wmOperatorType *ot);
 void MESH_OT_dissolve_faces(struct wmOperatorType *ot);
 void MESH_OT_dissolve_limited(struct wmOperatorType *ot);
+void MESH_OT_delete_edgeloop(struct wmOperatorType *ot);
 void MESH_OT_edge_face_add(struct wmOperatorType *ot);
 void MESH_OT_duplicate(struct wmOperatorType *ot);
 void MESH_OT_merge(struct wmOperatorType *ot);
index 307377a8aa688430f2cadb24c35160d6ebadd58c..966d5ecb00e4377f36d83513c745c7d1e89b6346 100644 (file)
@@ -107,6 +107,7 @@ void ED_operatortypes_mesh(void)
        WM_operatortype_append(MESH_OT_dissolve_edges);
        WM_operatortype_append(MESH_OT_dissolve_faces);
        WM_operatortype_append(MESH_OT_dissolve_limited);
+       WM_operatortype_append(MESH_OT_delete_edgeloop);
        WM_operatortype_append(MESH_OT_faces_shade_smooth);
        WM_operatortype_append(MESH_OT_faces_shade_flat);
        WM_operatortype_append(MESH_OT_sort_elements);