[Bf-blender-cvs] [88da231] gsoc2016-improved_extrusion: Curves: Extend, Batch Extend and Offset operators

João Araújo noreply at git.blender.org
Fri Aug 12 23:48:51 CEST 2016


Commit: 88da231cc6ee35c9ecc884156dd67bf817c7a12d
Author: João Araújo
Date:   Fri Aug 12 17:05:17 2016 +0100
Branches: gsoc2016-improved_extrusion
https://developer.blender.org/rB88da231cc6ee35c9ecc884156dd67bf817c7a12d

Curves: Extend, Batch Extend and Offset operators

Fixed a bug in the Extend operator. Refactored the Extend operator. Refactored the Batch Extend operator to make use of the existing Extend operator.

Started working on a fix for collinear handles on the offset operator. Current changes are ineffective.

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

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

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

diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c
index b66f39f..9edc91f 100644
--- a/source/blender/editors/curve/editcurve.c
+++ b/source/blender/editors/curve/editcurve.c
@@ -6457,7 +6457,7 @@ static void nearest_point(float p[2], ListBase *p_list, float r_near[2], int *r_
 		for (link = p_list->first; link; link = link->next) {
 			distance = len_v2v2(p, link->data);
 			if (distance <= smallest_distance) {
-				distance = smallest_distance;
+				smallest_distance = distance;
 				copy_v2_v2(r_near, link->data);
 				pos = i;
 			}
@@ -6575,8 +6575,8 @@ static int extend_curve_exec(bContext *C, wmOperator *op)
 	ListBase spline_list = {NULL};
 	ListBase intersections_list = {NULL};
 	ListBase *nubase = object_editcurve_get(obedit);
-	BezTriple **selected_endpoints = NULL, **first_selected_endpoints = NULL, **second_selected_endpoints = NULL, *bezt;
-	int n_selected_splines = 0, result = 0, a = 0;
+	BezTriple **selected_endpoints = NULL, **first_selected_endpoints = NULL, **second_selected_endpoints = NULL;
+	int n_selected_splines = 0, result = 0;
 	float p1[3], p2[3] = {0.0, 0.0, 0.0}, p1_handle[3], bound_box[4], p1_extend[2];
 
 	get_selected_bezier_splines(&spline_list, nubase, &n_selected_splines, false);
@@ -6655,9 +6655,13 @@ static int extend_curve_exec(bContext *C, wmOperator *op)
 			if (selected_endpoints[0] && selected_endpoints[1])
 			{ /* both endpoints selected */
 				BKE_nurbList_handles_set(nubase, 5);
-				ed_editcurve_addvert(cu, editnurb, p2);
 				for (nu = nubase->first; nu; nu = nu->next) {
 					if (BEZT_ISSEL_ANY_HIDDENHANDLES(cu, nu->bezt)) {
+						BKE_nurb_bezierPoints_add(nu, 2);
+						ED_curve_beztcpy(editnurb, &nu->bezt[1], &nu->bezt[0], nu->pntsu - 2);
+						ED_curve_beztcpy(editnurb, &nu->bezt[nu->pntsu - 1], &nu->bezt[nu->pntsu - 2], 1);
+						BEZT_DESEL_ALL(&nu->bezt[1]);
+						BEZT_DESEL_ALL(&nu->bezt[nu->pntsu - 2]);
 						copy_v3_v3(nu->bezt[0].vec[1], p2);
 						copy_v3_v3(nu->bezt[nu->pntsu - 1].vec[1], p2);
 					}
@@ -6667,21 +6671,35 @@ static int extend_curve_exec(bContext *C, wmOperator *op)
 			else { /* only one endpoint selected */
 				BKE_nurbList_handles_set(nubase, 5);
 				p2[2] = (selected_endpoints[0] ? selected_endpoints[0] : selected_endpoints[1])->vec[1][2];
-				ed_editcurve_addvert(cu, editnurb, p2);
+				for (nu = nubase->first; nu; nu = nu->next) {
+					if (BEZT_ISSEL_ANY(nu->bezt)) { /* first handle selected */
+						BKE_nurb_bezierPoints_add(nu, 1);
+						ED_curve_beztcpy(editnurb, &nu->bezt[1], &nu->bezt[0], nu->pntsu - 1);
+						BEZT_DESEL_ALL(&nu->bezt[1]);
+						copy_v3_v3(nu->bezt[0].vec[1], p2);					}
+					else if (BEZT_ISSEL_ANY(&nu->bezt[nu->pntsu - 1])) { /* last handle selected */
+						BKE_nurb_bezierPoints_add(nu, 1);
+						ED_curve_beztcpy(editnurb, &nu->bezt[nu->pntsu - 1], &nu->bezt[nu->pntsu - 2], 1);
+						BEZT_DESEL_ALL(&nu->bezt[nu->pntsu - 2]);
+						copy_v3_v3(nu->bezt[nu->pntsu - 1].vec[1], p2);
+					}
+				}
 				BKE_nurbList_handles_set(nubase, 1);
 			}
 		}
 		else if (n_selected_splines == 2) {
 			BKE_nurbList_handles_set(nubase, 5);
-			ed_editcurve_addvert(cu, editnurb, p2);
 			for (nu = nubase->first; nu; nu = nu->next) {
-				a = nu->pntsu;
-				bezt = nu->bezt;
-				while (a--) {
-					if (BEZT_ISSEL_ANY_HIDDENHANDLES(cu, bezt)) {
-						copy_v3_v3(bezt->vec[1], p2);
-					}
-					bezt++;
+				if (BEZT_ISSEL_ANY(nu->bezt)) { /* first handle selected */
+					BKE_nurb_bezierPoints_add(nu, 1);
+					ED_curve_beztcpy(editnurb, &nu->bezt[1], &nu->bezt[0], nu->pntsu - 1);
+					BEZT_DESEL_ALL(&nu->bezt[1]);
+					copy_v3_v3(nu->bezt[0].vec[1], p2);					}
+				else if (BEZT_ISSEL_ANY(&nu->bezt[nu->pntsu - 1])) { /* last handle selected */
+					BKE_nurb_bezierPoints_add(nu, 1);
+					ED_curve_beztcpy(editnurb, &nu->bezt[nu->pntsu - 1], &nu->bezt[nu->pntsu - 2], 1);
+					BEZT_DESEL_ALL(&nu->bezt[nu->pntsu - 2]);
+					copy_v3_v3(nu->bezt[nu->pntsu - 1].vec[1], p2);
 				}
 			}
 			BKE_nurbList_handles_set(nubase, 1);
@@ -7408,11 +7426,11 @@ void CURVE_OT_trim_curve(wmOperatorType *ot)
 
 /******************** Offset curve operator ********************/
 
-static void get_offset_vecs(BezTriple *bezt1, BezTriple *bezt2, float *r_v1, float *r_v2)
+static int get_offset_vecs(BezTriple *bezt1, BezTriple *bezt2, float *r_v1, float *r_v2)
 {
 	/* TODO: when bezt1 and bezt2 are collinear, things go wrong. Extending and the offseting exposes
 	 * 		 the problem */
-	int dims = 3;
+	int dims = 3, ret = 1;
 	float *coord_array, *vx, *vy, *helper;
 	coord_array = MEM_callocN(dims * (12 + 1) * sizeof(float), "get_offset_vecs1");
 	vx = MEM_callocN(dims * sizeof(float), "get_offset_vecs2");
@@ -7439,6 +7457,11 @@ static void get_offset_vecs(BezTriple *bezt1, BezTriple *bezt2, float *r_v1, flo
 	plane_from_point_normal_v3(plane_a, bezt1->vec[1], vx);
 	plane_from_point_normal_v3(plane_b, bezt1->vec[1], plane_b_no);
 
+	if (!(plane_a[0] && plane_a[1] && plane_a[2] && plane_a[3]) || !(plane_b[0] && plane_b[1] && plane_b[2] && plane_b[3])) {
+		/* handles are collinear */
+		ret = 0;
+	}
+
 	if (isect_plane_plane_v3(plane_a, plane_b,
 							 isect_co, isect_no))
 	{
@@ -7452,6 +7475,11 @@ static void get_offset_vecs(BezTriple *bezt1, BezTriple *bezt2, float *r_v1, flo
 	plane_from_point_normal_v3(plane_a, bezt2->vec[1], vy);
 	plane_from_point_normal_v3(plane_b, bezt2->vec[1], plane_b_no);
 
+	if (!(plane_a[0] && plane_a[1] && plane_a[2] && plane_a[3]) || !(plane_b[0] && plane_b[1] && plane_b[2] && plane_b[3])) {
+		/* handles are collinear */
+		ret = 0;
+	}
+
 	if (isect_plane_plane_v3(plane_a, plane_b,
 							 isect_co, isect_no))
 	{
@@ -7463,6 +7491,8 @@ static void get_offset_vecs(BezTriple *bezt1, BezTriple *bezt2, float *r_v1, flo
 	MEM_freeN(vx);
 	MEM_freeN(vy);
 	MEM_freeN(helper);
+
+	return ret;
 }
 
 static void get_handles_offset_vec(float *p1, float *p2, float *p3, float *r_v1)
@@ -7531,18 +7561,32 @@ static bool reverse_offset(BezTriple *offset1, BezTriple *offset2, ListBase *nur
 	return ret;
 }
 
+static void populate_control_bezt(BezTriple *bezt1, BezTriple *bezt2, float *v)
+{
+	memcpy(bezt1, bezt2, sizeof(BezTriple));
+	add_v3_v3(bezt1->vec[0], v);
+	add_v3_v3(bezt1->vec[1], v);
+	add_v3_v3(bezt1->vec[2], v);
+}
+
 static Nurb *offset_curve(Nurb *nu, ListBase *nubase, float distance)
 {
-	BezTriple *bezt = nu->bezt, *new_bezt, *copy_bezt = MEM_callocN(sizeof(BezTriple), __func__);
+	BezTriple *bezt = nu->bezt, *new_bezt;
+	BezTriple *copy_bezt1 = MEM_callocN(sizeof(BezTriple), __func__), *copy_bezt2 = MEM_callocN(sizeof(BezTriple), __func__);
 	Nurb *new_nu = BKE_nurb_duplicate(nu);
 	new_bezt = new_nu->bezt;
+	int res;
 	/* offset the first handle */
 	/* control point */
-	float *v1, *v2, *co;
+	float *v0, *v1, *v2, *co;
+	v0 = MEM_callocN(3 * sizeof(float), "offset_curve_exec0");
 	v1 = MEM_callocN(3 * sizeof(float), "offset_curve_exec1");
 	v2 = MEM_callocN(3 * sizeof(float), "offset_curve_exec2");
 	co = MEM_callocN(3 * sizeof(float), "offset_curve_exec3");
-	get_offset_vecs(bezt, bezt + 1, v1, v2);
+	res = get_offset_vecs(bezt, bezt + 1, v1, v2);
+	copy_v3_v3(v0, v1);
+	mul_v3_fl(v0, 1.0e-1);
+	populate_control_bezt(copy_bezt1, bezt, v0);
 	mul_v3_fl(v1, distance);
 	add_v3_v3(new_bezt->vec[0], v1);
 	add_v3_v3(new_bezt->vec[1], v1);
@@ -7562,7 +7606,10 @@ static Nurb *offset_curve(Nurb *nu, ListBase *nubase, float distance)
 	for (int i = 1; i < nu->pntsu - 1; i++)
 	{
 		/* control point */
-		get_offset_vecs(bezt, bezt + 1, v1, v2);
+		res = get_offset_vecs(bezt, bezt + 1, v1, v2);
+		copy_v3_v3(v0, v1);
+		mul_v3_fl(v0, 1.0e-1);
+		populate_control_bezt(copy_bezt2, bezt, v0);
 		mul_v3_fl(v1, distance);
 		add_v3_v3(new_bezt->vec[0], v1);
 		add_v3_v3(new_bezt->vec[1], v1);
@@ -7574,12 +7621,14 @@ static Nurb *offset_curve(Nurb *nu, ListBase *nubase, float distance)
 		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 */
+		/* if (reverse_offset(copy_bezt1, copy_bezt2, nubase)) { */
 			mul_v3_fl(v1, -2);
 			add_v3_v3(new_bezt->vec[0], v1);
 			add_v3_v3(new_bezt->vec[1], v1);
 			add_v3_v3(new_bezt->vec[2], v1);
 			//swap_v3_v3(new_bezt->vec[0], new_bezt->vec[2]);
 		}
+		memcpy(copy_bezt1, new_bezt, sizeof(BezTriple));
 		result = isect_line_line_v3(new_bezt->vec[1], new_bezt->vec[2], bezt->vec[2], co, v1, v2);
 		if (result != 0) {
 			copy_v3_v3(new_bezt->vec[2], v1);
@@ -7599,6 +7648,9 @@ static Nurb *offset_curve(Nurb *nu, ListBase *nubase, float distance)
 	/* offset the last handle */
 	get_offset_vecs(bezt - 1, bezt, v1, v2);
 	get_handles_offset_vec(bezt[-1].vec[2], bezt->vec[0], bezt->vec[1], v1);
+	copy_v3_v3(v0, v1);
+	mul_v3_fl(v0, 1.0e-1);
+	populate_control_bezt(copy_bezt2, bezt, v0);
 	mul_v3_fl(v2, distance);
 	add_v3_v3(new_bezt->vec[0], v2);
 	add_v3_v3(new_bezt->vec[1], v2);
@@ -7617,10 +7669,12 @@ static Nurb *offset_curve(Nurb *nu, ListBase *nubase, float distance)
 		copy_v3_v3(new_bezt->vec[0], v1);
 	}
 
+	MEM_freeN(v0);
 	MEM_freeN(v1);
 	MEM_freeN(v2);
 	MEM_freeN(co);
-	MEM_freeN(copy_bezt);
+	MEM_freeN(copy_bezt1);
+	MEM_freeN(copy_bezt2);
 
 	return new_nu;
 }
@@ -7805,96 +7859,6 @@ void CURVE_OT_offset_curve(wmOperatorType *ot)
 
 /******************** Batch Extend operator ********************/
 
-static void extend_vertex(int i, Nurb *nu, ListBase *nubase, Object *obedit, float r_p2[3])
-{
-	Curve *cu = obedit->data;
-	float p1[3], p1_handle[3], bound_box[4], p1_extend[3], p2[3];
-	int result = 0;
-	ListBase il = {NULL};
-
-	if (i == 0) { /* extend first handle */
-		copy_v3_v3(p1, nu->bezt->vec[1]);
-		copy_v3_v3(p1_handle, nu->bezt->vec[2]);
-	}
-	if (i == 1) { /* extend last handle */
-		copy_v3_v3(p1, nu->bezt[nu->pntsu - 1].vec[1]);
-		copy_v3_v3(p1_handle, nu->bezt[nu->pntsu - 1].vec[0]);
-	}
-
-	get_nurb_shape_bounds(cu, bound_box);
-	get_max_extent_2d(p1, p1_handle, bound_box, p1_extend);
-	get_intersections(&il, p1, p1_extend, nubase);
-	nearest_point(p1, &il, p2, &result);
-	if (result == 1) {
-		copy_v3_v3(r_p2, p2);
-	}
-
-	for (LinkD

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list