[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [59619] trunk/blender: patch [#36336] Split operator for curves and surfaces

Campbell Barton ideasman42 at gmail.com
Thu Aug 29 04:32:53 CEST 2013


Revision: 59619
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=59619
Author:   campbellbarton
Date:     2013-08-29 02:32:51 +0000 (Thu, 29 Aug 2013)
Log Message:
-----------
patch [#36336] Split operator for curves and surfaces
by Kevin Mackay (yakca)

The operator follows roughly the same behaviour as the split operator for a mesh (Ykey).

Modified Paths:
--------------
    trunk/blender/release/scripts/startup/bl_ui/space_view3d.py
    trunk/blender/source/blender/blenkernel/BKE_curve.h
    trunk/blender/source/blender/blenkernel/intern/curve.c
    trunk/blender/source/blender/editors/curve/curve_intern.h
    trunk/blender/source/blender/editors/curve/curve_ops.c
    trunk/blender/source/blender/editors/curve/editcurve.c
    trunk/blender/source/blender/editors/include/ED_curve.h

Modified: trunk/blender/release/scripts/startup/bl_ui/space_view3d.py
===================================================================
--- trunk/blender/release/scripts/startup/bl_ui/space_view3d.py	2013-08-29 01:08:00 UTC (rev 59618)
+++ trunk/blender/release/scripts/startup/bl_ui/space_view3d.py	2013-08-29 02:32:51 UTC (rev 59619)
@@ -2138,6 +2138,7 @@
 
     layout.operator("curve.extrude_move")
     layout.operator("curve.duplicate_move")
+    layout.operator("curve.split")
     layout.operator("curve.separate")
     layout.operator("curve.make_segment")
     layout.operator("curve.cyclic_toggle")

Modified: trunk/blender/source/blender/blenkernel/BKE_curve.h
===================================================================
--- trunk/blender/source/blender/blenkernel/BKE_curve.h	2013-08-29 01:08:00 UTC (rev 59618)
+++ trunk/blender/source/blender/blenkernel/BKE_curve.h	2013-08-29 02:32:51 UTC (rev 59619)
@@ -150,6 +150,7 @@
 void BKE_nurb_bezt_calc_plane(struct Nurb *nu, struct BezTriple *bezt, float r_plane[3]);
 
 void BKE_nurb_handle_calc(struct BezTriple *bezt, struct BezTriple *prev,  struct BezTriple *next, int mode);
+void BKE_nurb_handle_calc_simple(struct Nurb *nu, struct BezTriple *bezt);
 
 void BKE_nurb_handles_calc(struct Nurb *nu);
 void BKE_nurb_handles_autocalc(struct Nurb *nu, int flag);

Modified: trunk/blender/source/blender/blenkernel/intern/curve.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/curve.c	2013-08-29 01:08:00 UTC (rev 59618)
+++ trunk/blender/source/blender/blenkernel/intern/curve.c	2013-08-29 02:32:51 UTC (rev 59619)
@@ -3084,7 +3084,25 @@
 	calchandlesNurb_intern(nu, FALSE);
 }
 
+/* similar to BKE_nurb_handle_calc but for curves and
+ * figures out the previous and next for us */
+void BKE_nurb_handle_calc_simple(Nurb *nu, BezTriple *bezt)
+{
+	int index = (int)(bezt - nu->bezt);
+	BezTriple *prev, *next;
 
+	BLI_assert(ARRAY_HAS_ITEM(bezt, nu->bezt, nu->pntsu));
+
+	if (index == 0) {
+		prev = (nu->flag & CU_NURB_CYCLIC) ? &nu->bezt[nu->pntsu - 1] : NULL;
+	}
+	if (index == nu->pntsu - 1) {
+		next = (nu->flag & CU_NURB_CYCLIC) ? &nu->bezt[0] : NULL;
+	}
+
+	BKE_nurb_handle_calc(bezt, prev, next, 0);
+}
+
 void BKE_nurb_handles_test(Nurb *nu)
 {
 	/* use when something has changed with handles.

Modified: trunk/blender/source/blender/editors/curve/curve_intern.h
===================================================================
--- trunk/blender/source/blender/editors/curve/curve_intern.h	2013-08-29 01:08:00 UTC (rev 59618)
+++ trunk/blender/source/blender/editors/curve/curve_intern.h	2013-08-29 02:32:51 UTC (rev 59619)
@@ -76,6 +76,7 @@
 void CURVE_OT_reveal(struct wmOperatorType *ot);
 
 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);
 

Modified: trunk/blender/source/blender/editors/curve/curve_ops.c
===================================================================
--- trunk/blender/source/blender/editors/curve/curve_ops.c	2013-08-29 01:08:00 UTC (rev 59618)
+++ trunk/blender/source/blender/editors/curve/curve_ops.c	2013-08-29 02:32:51 UTC (rev 59619)
@@ -87,6 +87,7 @@
 	WM_operatortype_append(CURVE_OT_reveal);
 
 	WM_operatortype_append(CURVE_OT_separate);
+	WM_operatortype_append(CURVE_OT_split);
 	WM_operatortype_append(CURVE_OT_duplicate);
 	WM_operatortype_append(CURVE_OT_delete);
 
@@ -244,6 +245,7 @@
 	RNA_boolean_set(kmi->ptr, "deselect", TRUE);
 
 	WM_keymap_add_item(keymap, "CURVE_OT_separate", PKEY, KM_PRESS, 0, 0);
+	WM_keymap_add_item(keymap, "CURVE_OT_split", YKEY, KM_PRESS, 0, 0);
 	WM_keymap_add_item(keymap, "CURVE_OT_extrude_move", EKEY, KM_PRESS, 0, 0);
 	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);

Modified: trunk/blender/source/blender/editors/curve/editcurve.c
===================================================================
--- trunk/blender/source/blender/editors/curve/editcurve.c	2013-08-29 01:08:00 UTC (rev 59618)
+++ trunk/blender/source/blender/editors/curve/editcurve.c	2013-08-29 02:32:51 UTC (rev 59619)
@@ -108,10 +108,17 @@
 
 void selectend_nurb(Object *obedit, short selfirst, short doswap, short selstatus);
 static void select_adjacent_cp(ListBase *editnurb, short next, short cont, short selstatus);
+static void adduplicateflagNurb(Object *obedit, ListBase *newnurb, const short flag, const bool split);
+static int curve_delete_selected(Object *obedit, const int type, const bool split);
 
 /* still need to eradicate a few :( */
 #define CALLOC_STRUCT_N(x, y, name) (x *)MEM_callocN((y) * sizeof(x), name)
 
+enum {
+	CURVE_VERTEX = 0,
+	CURVE_SEGMENT,
+};
+
 static float nurbcircle[8][2] = {
 	{0.0, -1.0}, {-1.0, -1.0}, {-1.0, 0.0}, {-1.0,  1.0},
 	{0.0,  1.0}, { 1.0,  1.0}, { 1.0, 0.0}, { 1.0, -1.0}
@@ -1463,6 +1470,49 @@
 	ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
 }
 
+/******************** split operator ***********************/
+
+static int curve_split_exec(bContext *C, wmOperator *op)
+{
+	Object *obedit = CTX_data_edit_object(C);
+	ListBase *editnurb = object_editcurve_get(obedit);
+	ListBase newnurb = {NULL, NULL};
+
+	adduplicateflagNurb(obedit, &newnurb, SELECT, true);
+
+	if (newnurb.first != NULL) {
+		curve_delete_selected(obedit, CURVE_SEGMENT, true);
+		BLI_movelisttolist(editnurb, &newnurb);
+
+		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);
+	}
+	else {
+		BKE_report(op->reports, RPT_ERROR, "Cannot split current selection");
+		return OPERATOR_CANCELLED;
+	}
+
+	return OPERATOR_FINISHED;
+}
+
+void CURVE_OT_split(wmOperatorType *ot)
+{
+	/* identifiers */
+	ot->name = "Split";
+	ot->idname = "CURVE_OT_split";
+	ot->description = "Split off selected points from connected unselected points";
+
+	/* api callbacks */
+	ot->exec = curve_split_exec;
+	ot->poll = ED_operator_editcurve;
+
+	/* flags */
+	ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
 /* ******************* FLAGS ********************* */
 
 static short isNurbselUV(Nurb *nu, int *u, int *v, int flag)
@@ -1614,9 +1664,8 @@
 	}
 }
 
-static int deleteflagNurb(bContext *C, wmOperator *UNUSED(op), int flag)
+static int deleteflagNurb(Object *obedit, short flag)
 {
-	Object *obedit = CTX_data_edit_object(C);
 	Curve *cu = obedit->data;
 	ListBase *editnurb = object_editcurve_get(obedit);
 	Nurb *nu, *next;
@@ -1744,9 +1793,6 @@
 		nu = next;
 	}
 
-	if (ED_curve_updateAnimPaths(obedit->data))
-		WM_event_add_notifier(C, NC_OBJECT | ND_KEYS, obedit);
-
 	return OPERATOR_FINISHED;
 }
 
@@ -1869,41 +1915,55 @@
 	return ok;
 }
 
-static void adduplicateflagNurb(Object *obedit, short flag)
+static void adduplicateflagNurb(Object *obedit, ListBase *newnurb,
+                                const short flag, const bool split)
 {
 	ListBase *editnurb = object_editcurve_get(obedit);
-	Nurb *nu, *newnu;
+	Nurb *nu, *newnu, *startnu;
 	BezTriple *bezt, *bezt1;
 	BPoint *bp, *bp1;
 	Curve *cu = (Curve *)obedit->data;
-	int a, b, starta, enda, newu, newv;
+	int a, b, starta, enda, diffa, newu, newv;
 	char *usel;
 
 	cu->lastsel = NULL;
 
 	nu = editnurb->last;
 	while (nu) {
+		startnu = NULL;
 		if (nu->type == CU_BEZIER) {
 			bezt = nu->bezt;
 			for (a = 0; a < nu->pntsu; a++) {
 				enda = -1;
 				starta = a;
 				while ((bezt->f1 & flag) || (bezt->f2 & flag) || (bezt->f3 & flag)) {
-					select_beztriple(bezt, DESELECT, flag, HIDDEN);
+					if (!split) select_beztriple(bezt, DESELECT, flag, HIDDEN);
 					enda = a;
 					if (a >= nu->pntsu - 1) break;
 					a++;
 					bezt++;
 				}
 				if (enda >= starta) {
-					newnu = (Nurb *)MEM_mallocN(sizeof(Nurb), "adduplicateN");
-					memcpy(newnu, nu, sizeof(Nurb));
-					BLI_addtail(editnurb, newnu);
-					set_actNurb(obedit, newnu);
-					newnu->pntsu = enda - starta + 1;
-					newnu->bezt = (BezTriple *)MEM_mallocN((enda - starta + 1) * sizeof(BezTriple), "adduplicateN");
-					memcpy(newnu->bezt, &nu->bezt[starta], newnu->pntsu * sizeof(BezTriple));
+					diffa = enda - starta + 1;
 
+					if (startnu != NULL && enda == nu->pntsu - 1) {
+						/* end point of cyclic spline selected, so merge end points with start points */
+						bezt1 = (BezTriple *)MEM_mallocN((startnu->pntsu + diffa) * sizeof(BezTriple), "adduplicateN");
+						memcpy(bezt1, &nu->bezt[starta], diffa * sizeof(BezTriple));
+						memcpy(&bezt1[diffa], startnu->bezt, startnu->pntsu * sizeof(BezTriple));
+
+						MEM_freeN(startnu->bezt);
+						startnu->bezt = bezt1;
+						startnu->pntsu += diffa;
+						newnu = startnu;
+					}
+					else {
+						newnu = ED_curve_nurbcpy(nu, diffa);
+						BLI_addtail(newnurb, newnu);
+						set_actNurb(obedit, newnu);
+						memcpy(newnu->bezt, &nu->bezt[starta], newnu->pntsu * sizeof(BezTriple));
+					}
+
 					b = newnu->pntsu;
 					bezt1 = newnu->bezt;
 					while (b--) {
@@ -1914,6 +1974,7 @@
 					if (nu->flagu & CU_NURB_CYCLIC) {
 						if (starta != 0 || enda != nu->pntsu - 1) {
 							newnu->flagu &= ~CU_NURB_CYCLIC;
+							if (starta == 0) startnu = newnu;
 						}
 					}
 				}
@@ -1926,21 +1987,33 @@
 				enda = -1;
 				starta = a;
 				while (bp->f1 & flag) {
-					select_bpoint(bp, DESELECT, flag, HIDDEN);
+					if (!split) select_bpoint(bp, DESELECT, flag, HIDDEN);
 					enda = a;
 					if (a >= nu->pntsu - 1) break;
 					a++;
 					bp++;
 				}
 				if (enda >= starta) {
-					newnu = (Nurb *)MEM_mallocN(sizeof(Nurb), "adduplicateN3");
-					memcpy(newnu, nu, sizeof(Nurb));
-					set_actNurb(obedit, newnu);
-					BLI_addtail(editnurb, newnu);
-					newnu->pntsu = enda - starta + 1;
-					newnu->bp = (BPoint *)MEM_mallocN((enda - starta + 1) * sizeof(BPoint), "adduplicateN4");
-					memcpy(newnu->bp, &nu->bp[starta], newnu->pntsu * sizeof(BPoint));
+					diffa = enda - starta + 1;
 
+					if (startnu != NULL && enda == nu->pntsu - 1) {
+						/* end point of cyclic spline selected, so merge end points with start points */
+						bp1 = (BPoint *)MEM_mallocN((startnu->pntsu + diffa)  * sizeof(BPoint), "adduplicateN2");
+						memcpy(bp1, &nu->bp[starta], diffa * sizeof(BPoint));
+						memcpy(&bp1[diffa], startnu->bp, startnu->pntsu * sizeof(BPoint));
+
+						MEM_freeN(startnu->bp);
+						startnu->bp = bp1;

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list