[Bf-blender-cvs] [5b31c6a] gsoc2016-improved_extrusion: Curves: fillet and chamfer operator

João Araújo noreply at git.blender.org
Wed Aug 17 23:27:36 CEST 2016


Commit: 5b31c6abc99b87bd25f4c2a729d1df80433bd97e
Author: João Araújo
Date:   Wed Aug 17 22:24:23 2016 +0100
Branches: gsoc2016-improved_extrusion
https://developer.blender.org/rB5b31c6abc99b87bd25f4c2a729d1df80433bd97e

Curves: fillet and chamfer operator

The modal operators for the fillet and chamfer operators are now 90% complete.
On the chamfer operator, an option is needed to handle angle numinput. It would also be nice to have some sort of circular input for the angle (currently it is linked to the x variation of the cursor position).
For fillet, there is some kind of bug that corrupts curve data.

Due to the above mentioned reasons, modal operators are still commented.

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

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

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

diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c
index 0a5cbbb..c183409 100644
--- a/source/blender/editors/curve/editcurve.c
+++ b/source/blender/editors/curve/editcurve.c
@@ -8211,6 +8211,8 @@ static int curve_chamfer_exec(bContext *C, wmOperator *op)
 		}
 	}
 
+	BKE_nurb_handles_calc(nu);
+
 	WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
 	DAG_id_tag_update(obedit->data, 0);
 
@@ -8218,8 +8220,7 @@ static int curve_chamfer_exec(bContext *C, wmOperator *op)
 }
 
 typedef struct CD {
-	int *mouse;
-	int spline_id;
+	OffsetData *data;
 	BezTriple *selected_points;
 } CD;
 
@@ -8235,26 +8236,23 @@ static int curve_chamfer_modal(bContext *C, wmOperator *op, const wmEvent *event
 	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};
+	OffsetData *opdata = cd->data;
+	float *init_mouse = cd->data->mcenter;
+	int curr_mouse[2] = {event->mval[0], event->mval[1]};
 	float prev_mouse[2] = {init_mouse[0], init_mouse[1]};
-	float distance = 1.0, angle = DEG2RAD(45.0f);
-	int spline_id = cd->spline_id;
+	float distance = RNA_float_get(op->ptr, "distance");
+	float angle = RNA_float_get(op->ptr, "angle");
+	int spline_id = cd->data->spline_id;
 	nu = BLI_findlink(nubase, spline_id);
 	int selected = 0;
 
-	if (event->type == MOUSEMOVE) {
-		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));
-		}
-		else {
-			float dy = curr_mouse[1] - prev_mouse[1];
-			RNA_float_set(op->ptr, "distance", dy/100);
-		}
-		angle = RNA_float_get(op->ptr, "angle");
+	/* handle events */
+	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)) {
+		/* TODO: numinput for angle (handleNumInput returns false when event->ctrl )*/
+		RNA_float_set(op->ptr, "distance", opdata->num_input->val[0]);
 		distance = RNA_float_get(op->ptr, "distance");
 		for (int i = 0; i < nu->pntsu; i++) {
 			bezt = &nu->bezt[i];
@@ -8262,9 +8260,9 @@ static int curve_chamfer_modal(bContext *C, wmOperator *op, const wmEvent *event
 				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);
+				BEZT_SEL_ALL(bezt1);
 
 				ED_curve_beztcpy(editnurb, bezt, bezt1, 1);
 				ED_curve_beztcpy(editnurb, &bezt[1], bezt2, 1);
@@ -8304,21 +8302,152 @@ static int curve_chamfer_modal(bContext *C, wmOperator *op, const wmEvent *event
 			}
 		}
 	}
-	else if (event->type == LEFTMOUSE) {
-		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;
+	else {
+		bool handled = false;
+		switch (event->type) {
+			case ESCKEY:
+			case RIGHTMOUSE:
+				MEM_freeN(opdata);
+				MEM_freeN(cd->selected_points);
+				MEM_freeN(cd);
+				BKE_nurb_handles_calc(nu);
+				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);
+				MEM_freeN(cd->selected_points);
+				MEM_freeN(cd);
+				BKE_nurb_handles_calc(nu);
+				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 (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));
+					}
+					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");
+					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");
+							bezt2 = MEM_callocN(sizeof(BezTriple), "curve_chamfer_modal2");
+							chamfer_handle(original, bezt1, bezt2, angle, distance);
+							BEZT_SEL_ALL(bezt1);
+
+							ED_curve_beztcpy(editnurb, bezt, bezt1, 1);
+							ED_curve_beztcpy(editnurb, &bezt[1], bezt2, 1);
+
+							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);
+						}
+					}
+					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)) {
+			RNA_float_set(op->ptr, "distance", opdata->num_input->val[0]);
+			distance = RNA_float_get(op->ptr, "distance");
+			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");
+					bezt2 = MEM_callocN(sizeof(BezTriple), "curve_chamfer_modal2");
+					chamfer_handle(original, bezt1, bezt2, angle, distance);
+					BEZT_SEL_ALL(bezt1);
+
+					ED_curve_beztcpy(editnurb, bezt, bezt1, 1);
+					ED_curve_beztcpy(editnurb, &bezt[1], bezt2, 1);
+
+					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);
+				}
+			}
+			opdata->changed = 1;
+		}
 	}
 
+	BKE_nurb_handles_calc(nu);
+
 	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);
 
@@ -8328,13 +8457,12 @@ static int curve_chamfer_modal(bContext *C, wmOperator *op, const wmEvent *event
 	return OPERATOR_RUNNING_MODAL;
 }
 
-static int curve_chamfer_invoke(bContext *C, wmOperator *op, const wmEvent *event)
+static int curve_chamfer_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
 {
-	CD *cd = MEM_callocN(sizeof(CD), __func__);
-	int *mouse = MEM_callocN(3 * sizeof(int), __func__);
-	mouse[0] = event->x;
-	mouse[1] = event->y;
-	cd->mouse = mouse;
+	CD *cd = MEM_callocN(sizeof(CD), "curve_chamfer_invoke1");
+	cd->data = MEM_callocN(sizeof(OffsetData), "curve_chamfer_invoke2");
+	float center_3d[3];
+	calculateTransformCenter(C, V3D_AROUND_CENTER_MEAN, center_3d, cd->data->mcenter);
 
 	Object *obedit = CTX_data_edit_object(C);
 	Curve *cu = obedit->data;
@@ -8342,7 +8470,7 @@ static int curve_chamfer_invoke(bContext *C, wmOperator *op, const wmEvent *even
 	ListBase *nubase = object_editcurve_get(obedit);
 	/* get selected spline */
 	int spline_id = get_selected_spline_id(nubase);
-	cd->spline_id = spline_id;
+	cd->data->spline_id = spline_id;
 	Nurb *nu = BLI_findlink(nubase, spline_id);
 	BezTriple *bezt = nu->bezt, *bezt1, *bezt2;
 	if (!nu) {
@@ -8359,9 +8487,9 @@ static int curve_chamfer_invoke(bContext *C, wmOperator *op, const wmEvent *even
 			BKE_nurb_bezierPoints_add(nu, 1);
 			bezt = &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(bez

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list