[Bf-blender-cvs] [143f6c4] master: Curve: new dissolve tool

Campbell Barton noreply at git.blender.org
Mon May 2 10:46:18 CEST 2016


Commit: 143f6c4bb24a88f76fe9823d6ad461896f3a76af
Author: Campbell Barton
Date:   Mon May 2 18:11:09 2016 +1000
Branches: master
https://developer.blender.org/rB143f6c4bb24a88f76fe9823d6ad461896f3a76af

Curve: new dissolve tool

removes vertices, re-fitting the surrounding handles.

===================================================================

M	release/scripts/startup/bl_ui/space_view3d.py
M	source/blender/editors/curve/curve_intern.h
M	source/blender/editors/curve/curve_ops.c
M	source/blender/editors/curve/editcurve.c

===================================================================

diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py
index 374bc98..b4525d4 100644
--- a/release/scripts/startup/bl_ui/space_view3d.py
+++ b/release/scripts/startup/bl_ui/space_view3d.py
@@ -2633,7 +2633,7 @@ def draw_curve(self, context):
     layout.operator("curve.separate")
     layout.operator("curve.make_segment")
     layout.operator("curve.cyclic_toggle")
-    layout.operator("curve.delete", text="Delete...")
+    layout.menu("VIEW3D_MT_edit_curve_delete")
 
     layout.separator()
 
@@ -2704,6 +2704,19 @@ class VIEW3D_MT_edit_curve_specials(Menu):
         layout.operator("curve.smooth_tilt")
 
 
+class VIEW3D_MT_edit_curve_delete(Menu):
+    bl_label = "Delete"
+
+    def draw(self, context):
+        layout = self.layout
+
+        layout.operator_enum("curve.delete", "type")
+
+        layout.separator()
+
+        layout.operator("curve.dissolve_verts")
+
+
 class VIEW3D_MT_edit_curve_showhide(ShowHideMenu, Menu):
     _operator_name = "curve"
 
diff --git a/source/blender/editors/curve/curve_intern.h b/source/blender/editors/curve/curve_intern.h
index d63616e..856573f 100644
--- a/source/blender/editors/curve/curve_intern.h
+++ b/source/blender/editors/curve/curve_intern.h
@@ -102,6 +102,7 @@ void CURVE_OT_separate(struct wmOperatorType *ot);
 void CURVE_OT_split(struct wmOperatorType *ot);
 void CURVE_OT_duplicate(struct wmOperatorType *ot);
 void CURVE_OT_delete(struct wmOperatorType *ot);
+void CURVE_OT_dissolve_verts(struct wmOperatorType *ot);
 
 void CURVE_OT_spline_type_set(struct wmOperatorType *ot);
 void CURVE_OT_radius_set(struct wmOperatorType *ot);
diff --git a/source/blender/editors/curve/curve_ops.c b/source/blender/editors/curve/curve_ops.c
index d1994c8..fce6425 100644
--- a/source/blender/editors/curve/curve_ops.c
+++ b/source/blender/editors/curve/curve_ops.c
@@ -87,6 +87,7 @@ void ED_operatortypes_curve(void)
 	WM_operatortype_append(CURVE_OT_split);
 	WM_operatortype_append(CURVE_OT_duplicate);
 	WM_operatortype_append(CURVE_OT_delete);
+	WM_operatortype_append(CURVE_OT_dissolve_verts);
 
 	WM_operatortype_append(CURVE_OT_spline_type_set);
 	WM_operatortype_append(CURVE_OT_radius_set);
@@ -262,8 +263,12 @@ void ED_keymap_curve(wmKeyConfig *keyconf)
 	WM_keymap_add_item(keymap, "CURVE_OT_duplicate_move", DKEY, KM_PRESS, KM_SHIFT, 0);
 	WM_keymap_add_item(keymap, "CURVE_OT_make_segment", FKEY, KM_PRESS, 0, 0);
 	WM_keymap_add_item(keymap, "CURVE_OT_cyclic_toggle", CKEY, KM_PRESS, KM_ALT, 0);
-	WM_keymap_add_item(keymap, "CURVE_OT_delete", XKEY, KM_PRESS, 0, 0);
-	WM_keymap_add_item(keymap, "CURVE_OT_delete", DELKEY, KM_PRESS, 0, 0);
+
+	WM_keymap_add_menu(keymap, "VIEW3D_MT_edit_curve_delete", XKEY, KM_PRESS, 0, 0);
+	WM_keymap_add_menu(keymap, "VIEW3D_MT_edit_curve_delete", DELKEY, KM_PRESS, 0, 0);
+
+	WM_keymap_add_item(keymap, "CURVE_OT_dissolve_verts", XKEY, KM_PRESS, KM_CTRL, 0);
+	WM_keymap_add_item(keymap, "CURVE_OT_dissolve_verts", DELKEY, KM_PRESS, KM_CTRL, 0);
 
 	WM_keymap_add_item(keymap, "CURVE_OT_tilt_clear", TKEY, KM_PRESS, KM_ALT, 0);
 	WM_keymap_add_item(keymap, "TRANSFORM_OT_tilt", TKEY, KM_PRESS, KM_CTRL, 0);
diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c
index 395da2c..354530d 100644
--- a/source/blender/editors/curve/editcurve.c
+++ b/source/blender/editors/curve/editcurve.c
@@ -36,6 +36,7 @@
 
 #include "MEM_guardedalloc.h"
 
+#include "BLI_array_utils.h"
 #include "BLI_blenlib.h"
 #include "BLI_math.h"
 #include "BLI_ghash.h"
@@ -70,6 +71,8 @@
 
 #include "curve_intern.h"
 
+#include "curve_fit_nd.h"
+
 #include "UI_interface.h"
 #include "UI_resources.h"
 
@@ -5776,6 +5779,108 @@ void CURVE_OT_delete(wmOperatorType *ot)
 	ot->prop = prop;
 }
 
+static bool test_bezt_is_sel_any(const void *bezt_v, void *user_data)
+{
+	Curve *cu = user_data;
+	const BezTriple *bezt = bezt_v;
+	return BEZT_ISSEL_ANY_HIDDENHANDLES(cu, bezt);
+}
+
+static int curve_dissolve_exec(bContext *C, wmOperator *UNUSED(op))
+{
+	Object *obedit = CTX_data_edit_object(C);
+	Curve *cu = (Curve *)obedit->data;
+
+	{
+		ListBase *editnurb = object_editcurve_get(obedit);
+		Nurb *nu;
+
+		for (nu = editnurb->first; nu; nu = nu->next) {
+			if ((nu->type == CU_BEZIER) && (nu->pntsu > 2)) {
+				unsigned int span_step[2] = {nu->pntsu, nu->pntsu};
+				unsigned int span_len;
+
+				while (BLI_array_iter_span(
+				           nu->bezt, nu->pntsu,
+				           (nu->flagu & CU_NURB_CYCLIC) != 0, false,
+				           test_bezt_is_sel_any, cu,
+				           span_step, &span_len))
+				{
+					BezTriple *bezt_prev = &nu->bezt[mod_i(span_step[0] - 1, nu->pntsu)];
+					BezTriple *bezt_next = &nu->bezt[mod_i(span_step[1] + 1, nu->pntsu)];
+
+					int i_span_edge_len = span_len + 1;
+					const unsigned int dims = 3;
+
+					const unsigned int points_len = ((cu->resolu - 1) * i_span_edge_len) + 1;
+					float *points = MEM_mallocN(points_len * dims * sizeof(float), __func__);
+					float *points_stride = points;
+					const int points_stride_len = (cu->resolu - 1);
+
+					for (int segment = 0; segment < i_span_edge_len; segment++) {
+						BezTriple *bezt_a = &nu->bezt[mod_i((span_step[0] + segment) - 1, nu->pntsu)];
+						BezTriple *bezt_b = &nu->bezt[mod_i((span_step[0] + segment),     nu->pntsu)];
+
+						for (int axis = 0; axis < dims; axis++) {
+							BKE_curve_forward_diff_bezier(
+									bezt_a->vec[1][axis], bezt_a->vec[2][axis],
+									bezt_b->vec[0][axis], bezt_b->vec[1][axis],
+									points_stride + axis, points_stride_len, dims * sizeof(float));
+						}
+
+						points_stride += dims * points_stride_len;
+					}
+
+					BLI_assert(points_stride + dims == points + (points_len * dims));
+
+					float tan_l[3], tan_r[3], error_sq_dummy;
+
+					sub_v3_v3v3(tan_l, bezt_prev->vec[1], bezt_prev->vec[2]);
+					normalize_v3(tan_l);
+					sub_v3_v3v3(tan_r, bezt_next->vec[0], bezt_next->vec[1]);
+					normalize_v3(tan_r);
+
+					curve_fit_cubic_to_points_single_fl(
+					        points, points_len, dims, FLT_EPSILON,
+					        tan_l, tan_r,
+					        bezt_prev->vec[2], bezt_next->vec[0],
+					        &error_sq_dummy);
+
+					MEM_freeN(points);
+				}
+			}
+		}
+	}
+
+	ed_curve_delete_selected(obedit);
+
+	{
+		cu->actnu = cu->actvert = CU_ACT_NONE;
+
+		if (ED_curve_updateAnimPaths(obedit->data)) WM_event_add_notifier(C, NC_OBJECT | ND_KEYS, obedit);
+
+		WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
+		DAG_id_tag_update(obedit->data, 0);
+	}
+
+	return OPERATOR_FINISHED;
+}
+
+void CURVE_OT_dissolve_verts(wmOperatorType *ot)
+{
+	/* identifiers */
+	ot->name = "Dissolve Vertices";
+	ot->description = "Delete selected control points, correcting surrounding handles";
+	ot->idname = "CURVE_OT_dissolve_verts";
+
+	/* api callbacks */
+	ot->exec = curve_dissolve_exec;
+	ot->poll = ED_operator_editcurve;
+
+	/* flags */
+	ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
 /********************** shade smooth/flat operator *********************/
 
 static int shade_smooth_exec(bContext *C, wmOperator *op)




More information about the Bf-blender-cvs mailing list