[Bf-blender-cvs] [8708e50] gsoc2016-improved_extrusion: Curves: Offset operator

João Araújo noreply at git.blender.org
Mon Aug 8 00:11:35 CEST 2016


Commit: 8708e50bedab319b7a95fa9ea3783a07a48730a1
Author: João Araújo
Date:   Sun Aug 7 22:31:50 2016 +0100
Branches: gsoc2016-improved_extrusion
https://developer.blender.org/rB8708e50bedab319b7a95fa9ea3783a07a48730a1

Curves: Offset operator

Fully implemented the modal operator for the offset tool. Also fixed a few bugs.There is still a bug when calculating the correct offset direction. If the distance is sufficiently high, or if the curve is too tight on a few places, the reverse_offset function returns true even though that is not what we want. Passing in a different BezTriple offset by a precision distance (such as 10e-5) should fix it, though attempts at this have proved unsuccessful.

Regarding editmesh_bevel.c, fixed a trailing whitespace that I found by chance.

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

M	source/blender/editors/curve/editcurve.c
M	source/blender/editors/mesh/editmesh_bevel.c

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

diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c
index 59bb34f..9a4a15a 100644
--- a/source/blender/editors/curve/editcurve.c
+++ b/source/blender/editors/curve/editcurve.c
@@ -69,6 +69,7 @@
 #include "ED_util.h"
 #include "ED_view3d.h"
 #include "ED_curve.h"
+#include "ED_numinput.h"
 
 #include "curve_intern.h"
 
@@ -6765,7 +6766,7 @@ static int sel_point_id(Nurb *nu)
 	return -1; /* This line should never be reached, but well... warnings*/
 }
 
-typedef struct XShape{
+typedef struct XShape {
 	struct XShape *next, *prev;
 	float *intersections;
 	int order;
@@ -6965,8 +6966,6 @@ static float ratio_to_segment(float *x, float *p1, float *p2, float *p3, float *
 	return 0;
 }
 
-
-
 static void split_segment(float t, float *p1, float *p2, float *p3, float *p4,
 							   float *r_s1, float *r_s2)
 {
@@ -7530,7 +7529,7 @@ static bool reverse_offset(BezTriple *offset1, BezTriple *offset2, ListBase *nur
 
 static Nurb *offset_curve(Nurb *nu, ListBase *nubase, float distance)
 {
-	BezTriple *bezt = nu->bezt, *new_bezt;
+	BezTriple *bezt = nu->bezt, *new_bezt, *copy_bezt = MEM_callocN(sizeof(BezTriple), __func__);
 	Nurb *new_nu = BKE_nurb_duplicate(nu);
 	new_bezt = new_nu->bezt;
 	/* offset the first handle */
@@ -7549,11 +7548,10 @@ static Nurb *offset_curve(Nurb *nu, ListBase *nubase, float distance)
 	copy_v3_v3(co, bezt->vec[2]);
 	add_v3_v3(co, v2);
 	int result = isect_line_line_v3(new_bezt->vec[1], new_bezt->vec[2], bezt->vec[2], co, v1, v2);
-	if (result == 1) {
+	if (result != 0) {
 		copy_v3_v3(new_bezt->vec[2], v1);
 	}
 
-
 	/* offset all the handles between the first and the last */
 	bezt++;
 	new_bezt++;
@@ -7569,7 +7567,9 @@ static Nurb *offset_curve(Nurb *nu, ListBase *nubase, float distance)
 		get_handles_offset_vec(bezt[0].vec[1], bezt[0].vec[2], bezt[1].vec[0], v2);
 		copy_v3_v3(co, bezt->vec[2]);
 		add_v3_v3(co, v2);
-		if (reverse_offset(new_bezt - 1, new_bezt, nubase)) { /* we got the wrong direction. Fix that */
+		if (reverse_offset(new_bezt - 1, new_bezt, nubase)) { /* we got the wrong direction. Fix that
+															   * further spline intersections due to the offset
+															   * distance are sometiomes taken into account. TODO: Fix that */
 			mul_v3_fl(v1, -2);
 			add_v3_v3(new_bezt->vec[0], v1);
 			add_v3_v3(new_bezt->vec[1], v1);
@@ -7577,7 +7577,7 @@ static Nurb *offset_curve(Nurb *nu, ListBase *nubase, float distance)
 			//swap_v3_v3(new_bezt->vec[0], new_bezt->vec[2]);
 		}
 		result = isect_line_line_v3(new_bezt->vec[1], new_bezt->vec[2], bezt->vec[2], co, v1, v2);
-		if (result == 1) {
+		if (result != 0) {
 			copy_v3_v3(new_bezt->vec[2], v1);
 		}
 		/* left handle */
@@ -7585,7 +7585,7 @@ static Nurb *offset_curve(Nurb *nu, ListBase *nubase, float distance)
 		copy_v3_v3(co, bezt->vec[0]);
 		add_v3_v3(co, v2);
 		result = isect_line_line_v3(new_bezt->vec[0], new_bezt->vec[1], bezt->vec[0], co, v1, v2);
-		if (result == 1) {
+		if (result != 0) {
 			copy_v3_v3(new_bezt->vec[0], v1);
 		}
 		bezt++;
@@ -7609,13 +7609,14 @@ static Nurb *offset_curve(Nurb *nu, ListBase *nubase, float distance)
 		//swap_v3_v3(new_bezt->vec[0], new_bezt->vec[2]);
 	}
 	result = isect_line_line_v3(new_bezt->vec[0], new_bezt->vec[1], bezt->vec[0], co, v1, v2);
-	if (result == 1) {
+	if (result != 0) {
 		copy_v3_v3(new_bezt->vec[0], v1);
 	}
 
 	MEM_freeN(v1);
 	MEM_freeN(v2);
 	MEM_freeN(co);
+	MEM_freeN(copy_bezt);
 
 	return new_nu;
 }
@@ -7623,8 +7624,8 @@ static Nurb *offset_curve(Nurb *nu, ListBase *nubase, float distance)
 static int offset_curve_exec(bContext *C, wmOperator *op)
 {
 	Object *obedit = CTX_data_edit_object(C);
-	ListBase *nubase = object_editcurve_get(obedit);
-	Nurb *nu, *new_nu;
+	ListBase *nubase = object_editcurve_get(obedit), dummy = {NULL};
+	Nurb *nu, *new_nu, *copy_nu;
 	float distance = RNA_float_get(op->ptr, "distance");
 
 	/* get selected spline */
@@ -7635,7 +7636,10 @@ static int offset_curve_exec(bContext *C, wmOperator *op)
 		return OPERATOR_CANCELLED;
 	}
 
-	new_nu = offset_curve(nu, nubase, distance);
+	copy_nu = BKE_nurb_duplicate(nu);
+	BLI_addtail(&dummy, copy_nu);
+	new_nu = offset_curve(nu, &dummy, distance);
+	BKE_nurb_free(copy_nu);
 
 	BKE_nurb_handles_calc(new_nu);
 	BLI_addtail(nubase, new_nu);
@@ -7646,50 +7650,98 @@ static int offset_curve_exec(bContext *C, wmOperator *op)
 	return OPERATOR_FINISHED;
 }
 
+typedef struct OffsetData {
+	NumInput num_input[4];
+	float mcenter[2];
+	int value_mode;
+	int spline_id;
+	bool changed;
+} OffsetData;
+
 static int offset_curve_modal(bContext *C, wmOperator *op, const wmEvent *event)
 {
 	Object *obedit = CTX_data_edit_object(C);
 	ED_area_tag_redraw(CTX_wm_area(C));
+	float curr_mouse[2] = {event->mval[0], event->mval[1]};
+	OffsetData *opdata = op->customdata;
 	char str[UI_MAX_DRAW_STR];
 	size_t ofs = 0;
 	ListBase *nubase = object_editcurve_get(obedit);
 	Nurb *nu, *new_nu;
-	int *init_mouse = op->customdata, changed = init_mouse[2];
-	float curr_mouse[2] = {event->x, event->y};
-	float prev_mouse[2] = {init_mouse[0], init_mouse[1]};
-	float distance = 1.0;
-	int spline_id = get_selected_spline_id(nubase);
-	nu = BLI_findlink(nubase, spline_id);
+	float distance = RNA_float_get(op->ptr, "distance");
+	nu = BLI_findlink(nubase, opdata->spline_id);
 	if (!nu) {
 		BKE_report(op->reports, RPT_ERROR, "One spline must be selected");
 		return OPERATOR_CANCELLED;
 	}
 
-	if (event->type == MOUSEMOVE) {
-		if (changed) {
+	const bool has_numinput = hasNumInput(&opdata->num_input[opdata->value_mode]);
+
+	/* Modal numinput active, try to handle numeric inputs first... */
+	if (event->val == KM_PRESS && has_numinput && handleNumInput(C, &opdata->num_input[opdata->value_mode], event)) {
+		if (opdata->changed) {
 			new_nu = nubase->last;
 			BLI_poptail(nubase);
 			BKE_nurb_free(new_nu);
 		}
-		//float d = len_v2v2(prev_mouse, curr_mouse);
-		float dy = curr_mouse[1] - prev_mouse[1];
-		//RNA_float_set(op->ptr, "distance", d/1000);
-		RNA_float_set(op->ptr, "distance", dy/100);
+		RNA_float_set(op->ptr, "distance", opdata->num_input->val[0]);
 		distance = RNA_float_get(op->ptr, "distance");
 		new_nu = offset_curve(nu, nubase, distance);
 		BLI_addtail(nubase, new_nu);
-		init_mouse[2] = 1;
+		opdata->changed = 1;
 	}
-	else if (event->type == LEFTMOUSE) {
-		//offset_curve_exec(C, op);
-		ED_area_headerprint(CTX_wm_area(C), NULL);
-		MEM_freeN(init_mouse);
-		return OPERATOR_FINISHED;
-	}
-	else if (event->type == ESCKEY) {
-		ED_area_headerprint(CTX_wm_area(C), NULL);
-		MEM_freeN(init_mouse);
-		return OPERATOR_CANCELLED;
+	else {
+		bool handled = false;
+		switch (event->type) {
+			case ESCKEY:
+			case RIGHTMOUSE:
+				if (opdata->changed) {
+					new_nu = nubase->last;
+					BLI_poptail(nubase);
+					BKE_nurb_free(new_nu);
+				}
+				MEM_freeN(opdata);
+				ED_area_headerprint(CTX_wm_area(C), NULL);
+				WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
+				DAG_id_tag_update(obedit->data, 0);
+				return OPERATOR_CANCELLED;
+			case RETKEY:
+			case LEFTMOUSE:
+				MEM_freeN(opdata);
+				ED_area_headerprint(CTX_wm_area(C), NULL);
+				WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
+				DAG_id_tag_update(obedit->data, 0);
+				return OPERATOR_FINISHED;
+			case MOUSEMOVE:
+				if (!has_numinput) {
+					if (opdata->changed) {
+						new_nu = nubase->last;
+						BLI_poptail(nubase);
+						BKE_nurb_free(new_nu);
+					}
+					float d = opdata->mcenter[1] - curr_mouse[1];
+					RNA_float_set(op->ptr, "distance", -d/100);
+					distance = RNA_float_get(op->ptr, "distance");
+					new_nu = offset_curve(nu, nubase, distance);
+					BLI_addtail(nubase, new_nu);
+					handled = true;
+					opdata->changed = 1;
+				}
+				break;
+		}
+		/* Modal numinput inactive, try to handle numeric inputs last... */
+		if (!handled && event->val == KM_PRESS && handleNumInput(C, &opdata->num_input[opdata->value_mode], event)) {
+			if (opdata->changed) {
+				new_nu = nubase->last;
+				BLI_poptail(nubase);
+				BKE_nurb_free(new_nu);
+			}
+			RNA_float_set(op->ptr, "distance", opdata->num_input->val[0]);
+			distance = RNA_float_get(op->ptr, "distance");
+			new_nu = offset_curve(nu, nubase, distance);
+			BLI_addtail(nubase, new_nu);
+			opdata->changed = 1;
+		}
 	}
 
 	ofs += BLI_snprintf(str + ofs, sizeof(str) - ofs, IFACE_("Offset distance: %.2f"), distance);
@@ -7701,14 +7753,23 @@ static int offset_curve_modal(bContext *C, wmOperator *op, const wmEvent *event)
 	return OPERATOR_RUNNING_MODAL;
 }
 
-static int offset_curve_invoke(bContext *C, wmOperator *op, const wmEvent *event)
+static int offset_curve_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
 {
-	int *mouse = MEM_callocN(3 * sizeof(int), "offset_curve_invoke");
-	mouse[0] = event->x;
-	mouse[1] = event->y;
-	mouse[2] = 0; /* this is a flag to check if the operator is currently running or if it has just been called */
+	OffsetData *customdata = MEM_callocN(sizeof(OffsetData), "offset_curve_invoke1");
+	Object *obedit = CTX_data_active_object(C);
+	ListBase *nubase = object_editcurve_get(obedit);
+	float center_3d[3];
 
-	op->customdata = mouse;
+	RNA_float_set(op->ptr, "distance", 1.0f);
+
+	op->customdata = customdata;
+	customdata->value_mode = 0;
+	customdata->changed = 0;
+	customdata->spline_id = get_selected_spline_id(nubase);
+	for (int i = 0; i < 4; i++) {
+		initNumInput(&customdata->num_input[i]);
+	}
+	calculateTransformCenter(C, V3D_AROUND_CENTER_MEAN, center_3d, customdata->mcenter);
 
 	/* add modal handler */
 	WM_event_add_modal_handler(C, op);
@@ -7727,9 +7788,8 @@ void CURVE_OT_offset_curve(wmOperatorType *ot)
 	/* api callbacks */
 	ot->exec = offset_curve_exec;
 	ot->poll = ED_operator_editsurfcurve;
-	/* TODO: add code to offset_curve_modal to handle keyboard input */
-	//ot->modal = offset_curve_modal;
-	//ot->invoke = offset_curve_invoke;
+	ot->modal = offset_curve_modal;
+	ot->invoke = offset_curve_invoke;
 	
 	/* flags */
 	ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
diff --git a/source/blender/editors/mesh/editmesh_bevel.c b/source/blender/editors/mesh/editmesh_bevel.c
index 302ca40..2633714 100644
--- a/source/blender/editors/mesh/editmesh_bevel.c
++

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list