[Bf-blender-cvs] [046bdb5] gsoc2016-improved_extrusion: Curves: Offset and Chamfer operator

João Araújo noreply at git.blender.org
Mon Aug 1 14:00:49 CEST 2016


Commit: 046bdb521682bfa426acdd5adc98dafd98d088b8
Author: João Araújo
Date:   Sun Jul 31 17:45:12 2016 +0100
Branches: gsoc2016-improved_extrusion
https://developer.blender.org/rB046bdb521682bfa426acdd5adc98dafd98d088b8

Curves: Offset and Chamfer operator

Commented out the mouse functionality. Code for handling keyboard input needs to be added. Once it is added, the invoke and modal functions are ready to go.

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

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

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

diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c
index bddf5b8..0cba6f3 100644
--- a/source/blender/editors/curve/editcurve.c
+++ b/source/blender/editors/curve/editcurve.c
@@ -7701,8 +7701,9 @@ void CURVE_OT_offset_curve(wmOperatorType *ot)
 	/* api callbacks */
 	ot->exec = offset_curve_exec;
 	ot->poll = ED_operator_editsurfcurve;
-	ot->modal = offset_curve_modal;
-	ot->invoke = offset_curve_invoke;
+	/* TODO: add code to offset_curve_modal to handle keyboard input */
+	//ot->modal = offset_curve_modal;
+	//ot->invoke = offset_curve_invoke;
 	
 	/* flags */
 	ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -7918,6 +7919,8 @@ static void chamfer_handle(BezTriple *bezt, BezTriple *r_new_bezt1, BezTriple *r
 	/* intersect the segments and get the control point for the first handle */
 	result = isect_line_line_v3(bezt->vec[0], bezt->vec[1], p1, p2, ip1, ip1);
 	copy_v3_v3(r_new_bezt1->vec[1], ip1);
+
+	r_new_bezt1->h1 = r_new_bezt2->h1 = r_new_bezt1->h2 = r_new_bezt2->h2 = bezt->h1;
 }
 
 static int curve_chamfer_exec(bContext *C, wmOperator *op)
@@ -7938,62 +7941,67 @@ static int curve_chamfer_exec(bContext *C, wmOperator *op)
 
 	/* check if handles are vector type! */
 	BezTriple *bezt = nu->bezt, *bezt1, *bezt2, *helper;
-	bezt1 = MEM_callocN(sizeof(BezTriple), "curve_chamfer1");
-	bezt2 = MEM_callocN(sizeof(BezTriple), "curve_chamfer2");
 	int selected_point = 0;
 	for (int i = 0; i < nu->pntsu; i++) {
+		bezt = &nu->bezt[i];
 		if (BEZT_ISSEL_ANY(bezt) && bezt->h1 == 2 && bezt->h2 == 2) {
+			bezt1 = MEM_callocN(sizeof(BezTriple), "curve_chamfer1");
+			bezt2 = MEM_callocN(sizeof(BezTriple), "curve_chamfer2");
 			chamfer_handle(bezt, bezt1, bezt2, angle, distance);
 			selected_point = i;
+			BKE_nurb_bezierPoints_add(nu, 1);
+
+			memcpy(&nu->bezt[selected_point + 1], &nu->bezt[selected_point], (nu->pntsu - selected_point - 1) * sizeof(BezTriple));
+			memcpy(&nu->bezt[selected_point], bezt1, sizeof(BezTriple));
+			memcpy(&nu->bezt[selected_point + 1], bezt2, sizeof(BezTriple));
+
+			MEM_freeN(bezt1);
+			MEM_freeN(bezt2);
+
+			/* set the handles for the first chamfered triple */
+			float v[3];
+			bezt1 = &nu->bezt[selected_point];
+			helper = &nu->bezt[selected_point - 1];
+			/* left handle */
+			sub_v3_v3v3(v, helper->vec[2], bezt1->vec[1]);
+			mul_v3_fl(v, 0.4 * len_v3(v));
+			copy_v3_v3(bezt1->vec[0], bezt1->vec[1]);
+			add_v3_v3(bezt1->vec[0], v);
+			/* right handle */
+			bezt2 = &nu->bezt[selected_point + 1];
+			sub_v3_v3v3(v, bezt2->vec[1], bezt1->vec[1]);
+			mul_v3_fl(v, 0.4 * len_v3(v));
+			copy_v3_v3(bezt1->vec[2], bezt1->vec[1]);
+			add_v3_v3(bezt1->vec[2], v);
+
+			/* second chamfered triple */
+			helper = &nu->bezt[selected_point + 2];
+			/* left handle */
+			sub_v3_v3v3(v, bezt1->vec[1], bezt2->vec[1]);
+			mul_v3_fl(v, 0.4 * len_v3(v));
+			copy_v3_v3(bezt2->vec[0], bezt2->vec[1]);
+			add_v3_v3(bezt2->vec[0], v);
+			/* right handle */
+			bezt2 = &nu->bezt[selected_point + 1];
+			sub_v3_v3v3(v, helper->vec[0], bezt2->vec[1]);
+			mul_v3_fl(v, 0.4 * len_v3(v));
+			copy_v3_v3(bezt2->vec[2], bezt2->vec[1]);
+			add_v3_v3(bezt2->vec[2], v);
 		}
-		bezt++;
 	}
 
-	BKE_nurb_bezierPoints_add(nu, 1);
-
-	memcpy(&nu->bezt[selected_point + 1], &nu->bezt[selected_point], (nu->pntsu - selected_point - 1) * sizeof(BezTriple));
-	memcpy(&nu->bezt[selected_point], bezt1, sizeof(BezTriple));
-	memcpy(&nu->bezt[selected_point + 1], bezt2, sizeof(BezTriple));
-
-	/* set the handles for the first chamfered triple */
-	float v[3];
-	bezt1 = &nu->bezt[selected_point];
-	helper = &nu->bezt[selected_point - 1];
-	/* left handle */
-	sub_v3_v3v3(v, helper->vec[2], bezt1->vec[1]);
-	mul_v3_fl(v, 0.4 * len_v3(v));
-	copy_v3_v3(bezt1->vec[0], bezt1->vec[1]);
-	add_v3_v3(bezt1->vec[0], v);
-	/* right handle */
-	bezt2 = &nu->bezt[selected_point + 1];
-	sub_v3_v3v3(v, bezt2->vec[1], bezt1->vec[1]);
-	mul_v3_fl(v, 0.4 * len_v3(v));
-	copy_v3_v3(bezt1->vec[2], bezt1->vec[1]);
-	add_v3_v3(bezt1->vec[2], v);
-
-	/* second chamfered triple */
-	helper = &nu->bezt[selected_point + 2];
-	/* left handle */
-	sub_v3_v3v3(v, bezt1->vec[1], bezt2->vec[1]);
-	mul_v3_fl(v, 0.4 * len_v3(v));
-	copy_v3_v3(bezt2->vec[0], bezt2->vec[1]);
-	add_v3_v3(bezt2->vec[0], v);
-	/* right handle */
-	bezt2 = &nu->bezt[selected_point + 1];
-	sub_v3_v3v3(v, helper->vec[0], bezt2->vec[1]);
-	mul_v3_fl(v, 0.4 * len_v3(v));
-	copy_v3_v3(bezt2->vec[2], bezt2->vec[1]);
-	add_v3_v3(bezt2->vec[2], v);
-
-	MEM_freeN(bezt1);
-	MEM_freeN(bezt2);
-
 	WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
 	DAG_id_tag_update(obedit->data, 0);
 
 	return OPERATOR_FINISHED;
 }
 
+typedef struct CD {
+	int *mouse;
+	int spline_id;
+	BezTriple *selected_points;
+} CD;
+
 static int curve_chamfer_modal(bContext *C, wmOperator *op, const wmEvent *event)
 {
 	Object *obedit = CTX_data_edit_object(C);
@@ -8001,46 +8009,94 @@ static int curve_chamfer_modal(bContext *C, wmOperator *op, const wmEvent *event
 	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];
+	Nurb *nu;
+	BezTriple *bezt, *bezt1, *bezt2, *helper, *original;
+	CD *cd = op->customdata;
+	int *init_mouse = cd->mouse;
 	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);
+	float distance = 1.0, angle = DEG2RAD(45.0f);
+	int spline_id = cd->spline_id;
 	nu = BLI_findlink(nubase, spline_id);
-	if (!nu) {
-		BKE_report(op->reports, RPT_ERROR, "One spline must be selected");
-		return OPERATOR_CANCELLED;
-	}
+	int selected = 0;
 
 	if (event->type == MOUSEMOVE) {
-		if (changed) {
-			new_nu = nubase->last;
-			BLI_poptail(nubase);
-			BKE_nurb_free(new_nu);
+		if (event->ctrl) {
+			/* do some whacky maths */
+			/* TODO: check the code for the rotate operator */
+			float dx = curr_mouse[0] - prev_mouse[0];
+			RNA_float_set(op->ptr, "angle", DEG2RAD(dx/10));
 		}
-		//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);
+		else {
+			float dy = curr_mouse[1] - prev_mouse[1];
+			RNA_float_set(op->ptr, "distance", dy/100);
+		}
+		angle = RNA_float_get(op->ptr, "angle");
 		distance = RNA_float_get(op->ptr, "distance");
-		new_nu = offset_curve(nu, nubase, distance);
-		BLI_addtail(nubase, new_nu);
-		init_mouse[2] = 1;
+		for (int i = 0; i < nu->pntsu; i++) {
+			bezt = &nu->bezt[i];
+			if (BEZT_ISSEL_ANY(bezt) && bezt->h1 == 2 && bezt->h2 == 2) {
+				selected += 1;
+				original = &cd->selected_points[selected - 1];
+				bezt1 = MEM_callocN(sizeof(BezTriple), "curve_chamfer_modal1");
+				BEZT_SEL_ALL(bezt1);
+				bezt2 = MEM_callocN(sizeof(BezTriple), "curve_chamfer_modal2");
+				chamfer_handle(original, bezt1, bezt2, angle, distance);
+
+				memcpy(bezt, bezt1, sizeof(BezTriple));
+				memcpy(&bezt[1], bezt2, sizeof(BezTriple));
+
+				MEM_freeN(bezt1);
+				MEM_freeN(bezt2);
+
+				/* set the handles for the first chamfered triple */
+				float v[3];
+				bezt1 = &nu->bezt[i];
+				helper = &nu->bezt[i - 1];
+				/* left handle */
+				sub_v3_v3v3(v, helper->vec[2], bezt1->vec[1]);
+				mul_v3_fl(v, 0.4 * len_v3(v));
+				copy_v3_v3(bezt1->vec[0], bezt1->vec[1]);
+				add_v3_v3(bezt1->vec[0], v);
+				/* right handle */
+				bezt2 = &nu->bezt[i + 1];
+				sub_v3_v3v3(v, bezt2->vec[1], bezt1->vec[1]);
+				mul_v3_fl(v, 0.4 * len_v3(v));
+				copy_v3_v3(bezt1->vec[2], bezt1->vec[1]);
+				add_v3_v3(bezt1->vec[2], v);
+
+				/* second chamfered triple */
+				helper = &nu->bezt[i + 2];
+				/* left handle */
+				sub_v3_v3v3(v, bezt1->vec[1], bezt2->vec[1]);
+				mul_v3_fl(v, 0.4 * len_v3(v));
+				copy_v3_v3(bezt2->vec[0], bezt2->vec[1]);
+				add_v3_v3(bezt2->vec[0], v);
+				/* right handle */
+				bezt2 = &nu->bezt[i + 1];
+				sub_v3_v3v3(v, helper->vec[0], bezt2->vec[1]);
+				mul_v3_fl(v, 0.4 * len_v3(v));
+				copy_v3_v3(bezt2->vec[2], bezt2->vec[1]);
+				add_v3_v3(bezt2->vec[2], v);
+			}
+		}
 	}
 	else if (event->type == LEFTMOUSE) {
-		//offset_curve_exec(C, op);
 		ED_area_headerprint(CTX_wm_area(C), NULL);
 		MEM_freeN(init_mouse);
+		MEM_freeN(cd->selected_points);
+		MEM_freeN(cd);
 		return OPERATOR_FINISHED;
 	}
 	else if (event->type == ESCKEY) {
 		ED_area_headerprint(CTX_wm_area(C), NULL);
 		MEM_freeN(init_mouse);
+		MEM_freeN(cd->selected_points);
+		MEM_freeN(cd);
 		return OPERATOR_CANCELLED;
 	}
 
-	ofs += BLI_snprintf(str + ofs, sizeof(str) - ofs, IFACE_("Offset distance: %.2f"), distance);
+	ofs += BLI_snprintf(str + ofs, sizeof(str) - ofs, IFACE_("Chamfer distance: %.2f (Ctrl)Chamfer Angle: %.2f"), distance, RAD2DEG(angle));
 	ED_area_headerprint(CTX_wm_area(C), str);
 
 	WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
@@ -8051,12 +8107,47 @@ static int curve_chamfer_modal(bContext *C, wmOperator *op, const wmEvent *event
 
 static int curve_chamfer_invoke(bContext *C, wmOperator *op, const wmEvent *event)
 {
-	int *mouse = MEM_callocN(3 * sizeof(int), "offset_curve_invoke");
+	CD *cd = MEM_callocN(sizeof(CD), __func__);
+	int *mouse = MEM_callocN(3 * sizeof(int), __func__);
 	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 */
+	cd->mouse = mouse;
 
-	op->customdata = mouse;
+	Object *obedit = CTX_data_edit_object(C);
+	ListBase *nubase = object_editcurve_get(obedit);
+	/* get selected spline */
+	int spline_id = get_selected_spline_id(nubase);
+	cd->spline_id = spline_id;
+	Nurb *nu = BLI_findlink(nubase, spline_id);
+	BezTriple *bezt = nu->bezt, *bezt1, *bezt2;
+	if (!nu) {
+		BKE_report(op->reports, RPT_ERROR, "One spline must be selected");
+		return OPERATOR_CANCELLED;
+	}
+	int selected = 0;
+	for (int i = 0; i < nu->pntsu; i++) {
+		bezt = &nu->bezt[i];
+		if (BEZT_ISSEL_ANY(bezt)) {
+			selected += 1;
+			cd->selected_points = MEM_reallocN(cd->selected_points, selected * sizeof(BezTriple));
+			memcpy(&cd->selected_points[selected - 1]

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list