[Bf-blender-cvs] [2548ca3] gsoc2016-improved_extrusion: Curves: Extend tool/ Trim tool

João Araújo noreply at git.blender.org
Sun Jun 26 00:29:07 CEST 2016


Commit: 2548ca35e2b1ed32d00eff801cde5433d9b3d4bf
Author: João Araújo
Date:   Sat Jun 25 23:27:33 2016 +0100
Branches: gsoc2016-improved_extrusion
https://developer.blender.org/rB2548ca35e2b1ed32d00eff801cde5433d9b3d4bf

Curves: Extend tool/ Trim tool

Extend tool: fixed a few bugs, as described by dphantom in
http://blenderartists.org/forum/showthread.php?397450-GSoC-2016-Improvements-to-Bezier-Curves&p=3066750&viewfull=1#post3066750

Trim tool: Implemented spline_X_shape (helper function)

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

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

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

diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c
index 4dd4c6e..5eb5c0c 100644
--- a/source/blender/editors/curve/editcurve.c
+++ b/source/blender/editors/curve/editcurve.c
@@ -6310,53 +6310,63 @@ void CURVE_OT_match_texture_space(wmOperatorType *ot)
 
 static ListBase *get_selected_splines(ListBase *nubase, int *r_number_splines, bool return_cyclic)
 {
-	/* receives a list with all splines in a "curve" object
+	/* receives a list with all Bezier splines in a "curve" object
 	 * returns the first spline of a linked list with all the selected splines,
 	 * along with the number of selected splines
 	 * if "return_cyclic" is false, it ignores cyclic splines */
 
 	Nurb *nu, *nu_copy;
 	BezTriple *bezt;
-	ListBase spline_list = {NULL, NULL};
+	ListBase *spline_list = (ListBase *)MEM_callocN(sizeof(ListBase), "get_selected_splines1");
 	int handles;
 
-	for(nu=nubase->first; nu; nu = nu->next) {
+	for(nu=nubase->first; nu; nu = nu->next)
+	{
 		handles = nu->pntsu;
 		bezt = nu->bezt;
-		while (handles--) { /* cycle through all the handles. see if any is selected */
-			if (BEZT_ISSEL_ANY(bezt) && (!nu->flagu || return_cyclic)) { /* this expression was deduced using truth tables */
+		while (handles--)
+		{ /* cycle through all the handles. see if any is selected */
+			if (BEZT_ISSEL_ANY(bezt) && (!nu->flagu || return_cyclic))
+			{ /* this expression was deduced using truth tables */
 				*r_number_splines += 1;
 				nu_copy = BKE_nurb_duplicate(nu);
 				nu_copy->next = NULL;
 				nu_copy->prev = NULL;
-				BLI_addtail(&spline_list, nu_copy);
+				BLI_addtail(spline_list, nu_copy);
 				break;
 			}
 			bezt++;
 		}
 	}
-	return &spline_list;
+	return spline_list;
 }
 
-static void get_selected_handles(Nurb* nu, BezTriple **r_handle_list)
+static ListBase *get_selected_handles(Nurb* nu, int *r_num_sel_handles)
 {
 	/* Takes in the first element of a linked list of nurbs
-	 * and returns an array with the BezTriple of the selected handles. */
+	 * and returns a ListBase with the BezTriple of the selected handles. */
 	BezTriple *bezt;
-	int i = 0, a;
+	LinkData *link;
+	ListBase *sel_handles = (ListBase *)MEM_callocN(sizeof(ListBase), "get_selected_handles1");
+	int a;
 
+	*r_num_sel_handles = 0;
 	while (nu) {
 		a = nu->pntsu;
 		bezt = nu->bezt;
 		while (a--) {
 			if (BEZT_ISSEL_ANY(bezt)) {
-				r_handle_list[i] = bezt;
-				i++;
+				link = MEM_callocN(sizeof(LinkData), "get_selected_handles2");
+				link->data = bezt;
+				BLI_addtail(sel_handles, link);
+				*r_num_sel_handles = *r_num_sel_handles + 1;
 			}
 			bezt++;
 		}
 		nu = nu->next;
 	}
+
+	return sel_handles;
 }
 
 static void get_selected_endpoints(Nurb* nu, BezTriple **r_handle_list)
@@ -6525,7 +6535,7 @@ static ListBase *get_intersections(float *p1, float *p2, ListBase *nubase)
 				p4[0] = coord_array[(i + 1) * dims];
 				p4[1] = coord_array[(i + 1) * dims + 1];
 				result = isect_seg_seg_v2_point(p2, p1, p3, p4, vi);
-				if (result == 1 && len_v2v2(vi, p1) > PRECISION && len_v2v2(vi, p2) > PRECISION) {
+				if (result == 1 && len_v2v2(vi, p1) > PRECISION) {
 					intersection = MEM_callocN(sizeof(LinkData), "get_intersections4");
 					intersection->data = vi;
 					BLI_addtail(il, intersection);
@@ -6548,6 +6558,15 @@ static int extend_curve_exec(bContext *C, wmOperator *op)
 	int n_selected_splines = 0, result = 0, a = 0;
 	float p1[3], p2[3], p1_handle[3], bound_box[4], p1_extend[2];
 
+	for (nu = nubase->first; nu; nu = nu->next)
+	{
+		if (!(nu->type & CU_BEZIER))
+		{
+			BKE_report(op->reports, RPT_ERROR, "Only Bezier curves can be extended");
+			return OPERATOR_CANCELLED;
+		}
+	}
+
 	spline_list = get_selected_splines(nubase, &n_selected_splines, false);
 
 	/* the user can only select one or two splines */
@@ -6684,437 +6703,157 @@ void CURVE_OT_extend_curve(wmOperatorType *ot)
 
 /******************** Trim curve operator ********************/
 
-/*import bpy
-from mathutils import Vector
-from mathutils.geometry import intersect_line_line_2d, intersect_line_line, interpolate_bezier
-
-
-PRECISION = 1.0e-5
-
-
-def active_spline_id(shape_ob):
-    '''
-    returns integer of active spline
-    '''
-    return [i for i,s in enumerate(shape_ob.data.splines) if s == shape_ob.data.splines.active][0]
-
-
-def sel_point_id(spline_ob):
-    '''
-    > spline_ob:     bezier spline object
-    < returns integer of selected points
-    '''
-    return [i for i,bp in enumerate(spline_ob.bezier_points) if bp.select_control_point]
-
-
-def interpolate_all_segments(spline_ob):
-    '''
-    > spline_ob:     bezier spline object
-    < returns interpolated splinepoints
-    '''
-    point_range = len(spline_ob.bezier_points)
-    pl = []
-
-    for i in range (0, point_range-1+spline_ob.use_cyclic_u):
-        if len(pl) > 0:
-            pl.pop()
-        seg = (interpolate_bezier(spline_ob.bezier_points[i%point_range].co,
-                                  spline_ob.bezier_points[i%point_range].handle_right,
-                                  spline_ob.bezier_points[(i+1)%point_range].handle_left,
-                                  spline_ob.bezier_points[(i+1)%point_range].co,
-                                  spline_ob.resolution_u+1))
-        pl += seg
-    return pl
-
-
-def interpolate_spline(spline_ob):
-    '''
-    > spline_ob:     bezier spline object
-    < returns segments as lists of vectors
-    '''
-    point_range = len(spline_ob.bezier_points)
-    segments = []
-
-    for i in range (0, point_range-1+spline_ob.use_cyclic_u):
-        segments.append(interpolate_bezier(spline_ob.bezier_points[i%point_range].co,
-                                           spline_ob.bezier_points[i%point_range].handle_right,
-                                           spline_ob.bezier_points[(i+1)%point_range].handle_left,
-                                           spline_ob.bezier_points[(i+1)%point_range].co,
-                                           spline_ob.resolution_u+1))
-    return segments
-
-
-def linear_spline_list(shape_ob):
-    '''
-    > shape_ob:     bezier shape object
-    < returns list of linear interpolated splinepoints
-    '''
-    return [interpolate_spline(spl) for spl in shape_ob.data.splines]
+static int get_selected_spline_id(ListBase *nubase)
+{
+	/* receives a list with all splines in a "curve" object
+	 * returns the number of the first selected spline */
 
+	Nurb *nu;
+	BezTriple *bezt;
+	int handles, i = 0;
 
+	for(nu=nubase->first; nu; nu = nu->next) {
+		handles = nu->pntsu;
+		bezt = nu->bezt;
+		while (handles--) { /* cycle through all the handles. see if any is selected */
+			if (BEZT_ISSEL_ANY(bezt)) {
+				return i;
+			}
+			bezt++;
+		}
+		i++;
+	}
+	return -1;
+}
 
+typedef struct XShape{
+	struct XShape *next, *prev;
+	float *intersections;
+	int order;
+	float distance;
+} XShape;
 
+static int XShape_cmp(const void *xs1, const void *xs2)
+{
+	XShape *x1 = (XShape *)xs1, *x2 = (XShape *)xs2;
+	return x1->distance > x2->distance ? 1 : 0;
+}
 
-def is_between(x, a, b):
-    '''
-    > x, a, b = point
-    < True if x lies between a and b
-    '''
-    cross = (x[1] - a[1]) * (b[0] - a[0]) - (x[0] - a[0]) * (b[1] - a[1])
-    if abs(cross) > PRECISION: return False
-    dot = (x[0] - a[0]) * (b[0] - a[0]) + (x[1] - a[1])*(b[1] - a[1])
-    if dot < 0 : return False
-    squaredlengthba = (b[0] - a[0])*(b[0] - a[0]) + (b[1] - a[1])*(b[1] - a[1])
-    if dot > squaredlengthba: return False
-
-    return True
+static ListBase *spline_X_shape(Object *obedit, int selected_spline)
+{
+	ListBase *nubase, *shape_list, *all_segments;
+	Nurb *nu;
+	const float PRECISION = 1e-05;
 
+	nubase = object_editcurve_get(obedit);
+	shape_list = linear_spline_list(nubase);
+	nu = BLI_findlink(nubase, selected_spline);
+	all_segments = interpolate_all_segments(nu);
+
+	/* check for self intersections */
+	ListBase *intersections;
+	XShape *xshape;
+	LinkData *segment, *spline;
+	float *coord_array, *full_coord_array, *vi, helper[3], *segment_coord_array;
+	int i = 0, a = 0, j = 0, k = 0;
+	intersections = (ListBase *)MEM_callocN(sizeof(ListBase), "splineXshape2");
+	full_coord_array = (float *)MEM_callocN(3 * (nu->pntsu * nu->resolu - 1) * sizeof(float), "splineXshape3");
+
+	/* get the full coord_array for nu */
+	float *original_first_coord_array;
+	original_first_coord_array = (float *)MEM_callocN(3 * (nu->resolu + 1) * sizeof(float), "splineXshape7");
+	original_first_coord_array = ((LinkData *)all_segments->first)->data;
+	for (segment = all_segments->first; segment; segment = segment->next) {
+		coord_array = segment->data;
+		for (i = 0; i < 3 * (nu->resolu); i++) {
+			full_coord_array[(a * 3 * (nu->resolu)) + i] = coord_array[i];
+		}
+		a++;
+	}
+	/* last point */
+	for (i = 0; i < 3; i++) {
+		full_coord_array[a * 3 * (nu->resolu) + i] = coord_array[3 * (nu->resolu) + i];
+	}
+
+	int sl_length = 0, result = 0;
+	for (i = 0; i < nu->resolu * (nu->pntsu - 1); i++) {
+		for (j = i + 2; j < nu->resolu * (nu->pntsu - 1); j++) {
+			vi = (float *)MEM_callocN(3 * sizeof(float), "splineXshape4");
+			result = isect_seg_seg_v2_point(&full_coord_array[i * 3], &full_coord_array[(i + 1) * 3],
+											&full_coord_array[j * 3], &full_coord_array[(j + 1) * 3], vi);
+			if (result == 1) {
+				xshape = (XShape *)MEM_callocN(sizeof(XShape), "splineXshape1");
+				xshape->intersections = vi;
+				xshape->order = i / nu->resolu;
+				copy_v3_v3(helper, vi);
+				sub_v3_v3(helper, &full_coord_array[i * 3]);
+				xshape->distance = sl_length + len_v3(helper);
+				BLI_addtail(intersections, xshape);
+			}
+		}
+		copy_v3_v3(helper, &full_coord_array[(i + 1) * 3]);
+		sub_v3_v3(helper, &full_coord_array[i * 3]);
+		sl_length += len_v3(helper);
+	}
+
+	/* check all other intersections with active spline */
+	sl_length = 0;
+	float l1, l2, l3, l4;
+	l1 = l2 = l3 = l4 = 0;
+	for (i = 0; i < nu->resolu * (nu->pntsu - 1); i++) {
+		j = 0;
+		for (spline = shape_list->first; spline; spline = spline->next, j++) {
+			k = 0;
+			for (segment = ((ListBase *)spline->data)->first; segment; segment = segment->next, k++) {
+				segment_coord_array = segment->data;
+				if (!(memcmp(original_first_coord_array, segment_c

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list