[Bf-blender-cvs] [5d403a6] gsoc2016-improved_extrusion: Merge remote-tracking branch 'origin/master' into gsoc2016-improved_extrusion

João Araújo noreply at git.blender.org
Sat Jul 30 21:59:28 CEST 2016


Commit: 5d403a6dc3376932967398ac0f8a103e08badbee
Author: João Araújo
Date:   Sat Jul 30 15:41:24 2016 +0100
Branches: gsoc2016-improved_extrusion
https://developer.blender.org/rB5d403a6dc3376932967398ac0f8a103e08badbee

Merge remote-tracking branch 'origin/master' into gsoc2016-improved_extrusion

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



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

diff --cc source/blender/editors/curve/editcurve.c
index 482ba72,e40dde2..571bf01
--- a/source/blender/editors/curve/editcurve.c
+++ b/source/blender/editors/curve/editcurve.c
@@@ -6302,1567 -6302,3 +6302,1567 @@@ void CURVE_OT_match_texture_space(wmOpe
  	/* flags */
  	ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
  }
 +
 +
 +
 +/******************** Extend curve operator ********************/
 +
 +static void get_selected_splines(ListBase* spline_list, ListBase *nubase, int *r_number_splines, bool return_cyclic)
 +{
 +	/* 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;
 +	int handles;
 +
 +	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 & CU_NURB_CYCLIC) || 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);
 +				break;
 +			}
 +			bezt++;
 +		}
 +	}
 +}
 +
 +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 a ListBase with the BezTriple of the selected handles. */
 +	BezTriple *bezt;
 +	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)) {
 +				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)
 +{
 +	/* Takes in a nurb and returns an array with the selected endpoints BezTriple */
 +	BezTriple *first_bezt, *last_bezt;
 +	int a;
 +	r_handle_list[0] = r_handle_list[1] = NULL;
 +
 +	a = nu->pntsu - 1;
 +	first_bezt = last_bezt = nu->bezt;
 +
 +	while (a--) {
 +		last_bezt++;
 +	}
 +
 +	if (BEZT_ISSEL_ANY(first_bezt) && BEZT_ISSEL_ANY(last_bezt))
 +	{
 +		r_handle_list[0] = first_bezt;
 +		r_handle_list[1] = last_bezt;
 +	}
 +	else if (BEZT_ISSEL_ANY(first_bezt))
 +	{
 +		r_handle_list[0] = first_bezt;
 +		r_handle_list[1] = NULL;
 +	}
 +	else if (BEZT_ISSEL_ANY(last_bezt))
 +	{
 +		r_handle_list[0] = NULL;
 +		r_handle_list[1] = last_bezt;
 +	}
 +}
 +
 +static void get_nurb_shape_bounds(Object *obedit, float r_bound_box[4])
 +{
 +	/* returns the coordinates of the XY-bounding box of obedit */
 +	r_bound_box[0] = obedit->bb->vec[0][0]; /* min X */
 +	r_bound_box[1] = obedit->bb->vec[4][0]; /* max X */
 +	r_bound_box[2] = obedit->bb->vec[0][1]; /* min Y */
 +	r_bound_box[3] = obedit->bb->vec[3][1]; /* max Y */
 +}
 +
 +static void get_max_extent_2d(float p1[2], float p2[2], float bb[4], float r_result[2])
 +{
 +	/* TODO: Find out what this actually does */
 +	if (fabsf(p1[0]-p2[0])) {
 +		if (p1[0] < p2[0]) {
 +			r_result[0] = bb[0];
 +			r_result[1] = (p2[1]-p1[1])/(p2[0]-p1[0])*(bb[0]-p1[0])+p1[1];
 +		}
 +		else {
 +			r_result[0] = bb[1];
 +			r_result[1] = (p2[1]-p1[1])/(p2[0]-p1[0])*(bb[1]-p1[0])+p1[1];
 +		}
 +	}
 +	else {
 +		if (p1[1] < p2[1]) {
 +			r_result[0] = (p2[0]-p1[0])/(p2[1]-p1[1])*(bb[2]-p1[1])+p1[0];
 +			r_result[1] = bb[2];
 +		}
 +		else {
 +			r_result[0] = (p2[0]-p1[0])/(p2[1]-p1[1])*(bb[3]-p1[1])+p1[0];
 +			r_result[1] = bb[3];
 +		}
 +	}
 +}
 +
 +static void nearest_point(float p[2], ListBase *p_list, float r_near[2], int *r_result)
 +{
 +	LinkData *link;
 +	int p_list_size = BLI_listbase_count(p_list);
 +	*r_result = 1;
 +	/* return the point from p_list nearer to p */
 +	if (p_list_size == 0) {
 +		r_near = NULL;
 +		*r_result = 0;
 +	}
 +	else if (p_list_size == 1) {
 +		link = p_list->first;
 +		copy_v2_v2(r_near, link->data);
 +	}
 +	else {
 +		int pos = 0, i = 0;
 +		float distance = len_v2v2(p, ((LinkData *)p_list->first)->data), smallest_distance = distance;
 +		for (link = p_list->first; link; link = link->next) {
 +			distance = len_v2v2(p, link->data);
 +			if (distance <= smallest_distance) {
 +				distance = smallest_distance;
 +				copy_v2_v2(r_near, link->data);
 +				pos = i;
 +			}
 +			i++;
 +		}
 +	}
 +}
 +
 +static ListBase *interpolate_all_segments(Nurb *nu)
 +{
 +	/* return a listbase with all the points in the Bezier curve. Each element
 +	 * of the ListBase is a segment between two handles.
 +	 * If the cuve only has two handles, the final result is only on list
 +	 * Otherwise, there is an overlap between the last element of a list and
 +	 * the first of the next one */
 +	int i = 0, dims = 3;
 +	float *coord_array;
 +	ListBase *pl = (ListBase *)MEM_callocN(sizeof(ListBase), "interpolate_all_segments1");
 +	LinkData *link;
 +
 +	/* number of BezTriples */
 +	int bezier_points = nu->pntsu;
 +
 +	while (i < bezier_points-1+nu->flagu) {
 +		coord_array = MEM_callocN(dims * (nu->resolu + 1) * sizeof(float), "interpolate_all_segments2");
 +		link = MEM_callocN(sizeof(LinkData), "interpolate_all_segments3");
 +		link->data = coord_array;
 +		for (int j = 0; j < dims; j++) {
 +			BKE_curve_forward_diff_bezier(nu->bezt[i%bezier_points].vec[1][j],
 +										  nu->bezt[i%bezier_points].vec[2][j],
 +										  nu->bezt[(i+1)%bezier_points].vec[0][j],
 +										  nu->bezt[(i+1)%bezier_points].vec[1][j],
 +										  coord_array + j, nu->resolu, sizeof(float) * dims);
 +		}
 +		BLI_addtail(pl, link);
 +		i++;
 +	}
 +
 +	return pl;
 +}
 +
 +static void linear_spline_list(ListBase *nubase, ListBase *spline_list)
 +{
 +	/* return a list with all the points of a curve object */
 +	LinkData *link;
 +	Nurb *nu;
 +
 +	for (nu=nubase->first; nu; nu=nu->next) {
 +		link = MEM_callocN(sizeof(LinkData), "linearspllist1");
 +		link->data = interpolate_all_segments(nu);
 +		BLI_addtail(spline_list, link);
 +	}
 +}
 +
 +static void get_intersections(ListBase* il, float *p1, float *p2, ListBase *nubase)
 +{
 +	/* return a list with all the intersection points of the segment p1p2 with the curve object */
 +	ListBase spline_list = {NULL}, *points_list;
 +	LinkData *intersection, *link, *spl;
 +	float *coord_array, *vi, p3[2], p4[2];
 +	Nurb *nu = nubase->first;
 +	int dims = 3, result;
 +	const float PRECISION = 1e-05;
 +
 +	linear_spline_list(nubase, &spline_list);		/* all the points in a curve object */
 +	for (spl=spline_list.first; spl; spl=spl->next) { /* selecting the points of a given spline */
 +		points_list = spl->data;        /* output of interpolate_all_segments */
 +		for (link = points_list->first; link; link=link->next) {
 +			coord_array = (float *)link->data;
 +			for (int i = 0; i < nu->resolu; i++) {
 +				vi = (float *) MEM_callocN(3 * sizeof(float), "get_intersections2");
 +				p3[0] = coord_array[i * dims];
 +				p3[1] = coord_array[i * dims + 1];
 +				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) {
 +					/* a hit, lets add it. */
 +					intersection = MEM_callocN(sizeof(LinkData), "get_intersections4");
 +					intersection->data = vi;
 +					BLI_addtail(il, intersection);
 +				}
 +				else {
 +					/* not going to add, so free the memory we reserved, not used. */
 +					MEM_freeN(vi);
 +				}
 +			}
 +			MEM_freeN(link->data);   /* commenting either does not free the memory */
 +			MEM_freeN(coord_array);  /* running both gives an error, but seems to free the memory */
 +		}
 +		BLI_freelistN(spl->data);
 +		BLI_freelistN(points_list);
 +		MEM_freeN(points_list);
 +	}
 +	BLI_freelistN(&spline_list);
 +	MEM_freeN(&spline_list);
 +}
 +
 +static int extend_curve_exec(bContext *C, wmOperator *op)
 +{
 +	Object *obedit = CTX_data_edit_object(C);
 +	Nurb *first_spline, *second_spline;
 +	Curve *cu = obedit->data;
 +	Nurb *nu;
 +	EditNurb *editnurb = cu->editnurb;
 +	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;
 +	float p1[3], p2[3] = {0.0, 0.0, 0.0}, 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;
 +		}
 +	}
 +
 +	get_selected_splines(&spline_list, nubase, &n_selected_splines, false);
 +
 +	/* the user can only select one or two splines */
 +	if ((n_selected_splines == 0 || n_selected_splines > 2)) {
 +		BKE_report(op->reports, RPT_ERROR, "Cannot extend current selection");
 +		return OPERATOR_CANCELLED;
 +	}
 +
 +	first_spline = (Nurb *)spline_list.first;
 +	second_spline = (Nurb *)spline_list.last;
 +
 +	if (n_selected_splines == 1) { /* one spline selected */
 +		selected_endpoints = MEM_callocN(2 * sizeof(BezTriple*), "extendcurve1");
 +		get_selected_endpoints(first_spline, selected_endpoints);
 +
 +		if (selected_endpoints[0] && selected_endpoints[1]) { /* both endpoints are selected */
 +			result = isect_line_line_v3(selected_endpoints[0]->vec[1], selected_endpoints[0]->vec[0],
 +										selected_endpoints[1]->vec[1], selected_endpoints[1]->vec[2],
 +										p1, p2); /* result serves to check the existence of the intersection;
 +												  * the intersection point is on variables p1 and p2 */
 +		}
 +		else if (selected_endpoints[0] || selected_endpoints[1]) { /* only one endpoint selected */
 +			if (selected_endpoints[0])
 +			{
 +				copy_v3_v3(p1, selected_endpoints[0]->vec[1]);
 +				copy_v3_v3(p1_handle

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list