[Bf-blender-cvs] [4daf1c1] gsoc2016-improved_extrusion: Curve: Concluded the implementation of the Extend operator
João Araújo
noreply at git.blender.org
Sun Jun 19 15:00:03 CEST 2016
Commit: 4daf1c17e4aaf5be9f46c6ca3cf52c4631ef6207
Author: João Araújo
Date: Sun Jun 19 13:59:14 2016 +0100
Branches: gsoc2016-improved_extrusion
https://developer.blender.org/rB4daf1c17e4aaf5be9f46c6ca3cf52c4631ef6207
Curve: Concluded the implementation of the Extend operator
This commit contains the full implementation of the Extend operator, plus helper functions.
===================================================================
M source/blender/editors/curve/editcurve.c
===================================================================
diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c
index 8050305..a96b188 100644
--- a/source/blender/editors/curve/editcurve.c
+++ b/source/blender/editors/curve/editcurve.c
@@ -6364,6 +6364,7 @@ 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;
@@ -6372,15 +6373,18 @@ static void get_selected_endpoints(Nurb* nu, BezTriple **r_handle_list)
last_bezt++;
}
- if (BEZT_ISSEL_ANY(first_bezt) && BEZT_ISSEL_ANY(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)) {
+ 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)) {
+ else if (BEZT_ISSEL_ANY(last_bezt))
+ {
r_handle_list[0] = NULL;
r_handle_list[1] = last_bezt;
}
@@ -6420,27 +6424,32 @@ static void get_max_extent_2d(float p1[2], float p2[2], float bb[4], float r_res
}
}
-static void nearest_point(float p[2], float **p_list, int p_list_size, float r_near[2])
+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) {
- copy_v2_v2(r_near, p_list[0]);
+ link = p_list->first;
+ copy_v2_v2(r_near, link->data);
}
else {
- int pos = 0, i = 1;
- float distance = len_v2v2(p, p_list[0]), smallest_distance = distance;
- while (i < p_list_size) {
- distance = len_v2v2(p, p_list[i]);
- if (distance < smallest_distance) {
+ 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++;
}
- copy_v2_v2(r_near, p_list[pos]);
}
}
@@ -6453,7 +6462,7 @@ static ListBase *interpolate_all_segments(Nurb *nu)
* the first of the next one */
int i = 0, dims = 3;
float *coord_array;
- ListBase pl = {NULL,NULL};
+ ListBase *pl = (ListBase *)MEM_callocN(sizeof(ListBase), "interpolate_all_segments1");
LinkData *link;
/* number of BezTriples */
@@ -6470,35 +6479,36 @@ static ListBase *interpolate_all_segments(Nurb *nu)
nu->bezt[(i+1)%bezier_points].vec[1][j],
coord_array + j, nu->resolu - 1, sizeof(float) * dims);
}
- BLI_addtail(&pl, link);
+ BLI_addtail(pl, link);
i++;
}
- return &pl;
+ return pl;
}
static ListBase *linear_spline_list(ListBase *nubase)
{
/* return a list with all the points of a curve object */
- ListBase spline_list = {NULL, NULL};
+ ListBase *spline_list = (ListBase *)MEM_callocN(sizeof(ListBase), "linearspllist1");
LinkData *link;
Nurb *nu;
for (nu=nubase->first; nu; nu=nu->next) {
- link = MEM_callocN(sizeof(LinkData), "linearspllist1");
+ link = MEM_callocN(sizeof(LinkData), "linearspllist2");
link->data = interpolate_all_segments(nu);
- BLI_addtail(&spline_list, link);
+ BLI_addtail(spline_list, link);
}
- return &spline_list;
+ return spline_list;
}
static ListBase *get_intersections(float *p1, float *p2, ListBase *nubase)
{
/* return a list with all the intersection points of the segment p1p2 with the curve object */
- ListBase il = {NULL, NULL}, *spline_list, *points_list;
+ ListBase *spline_list, *points_list;
+ ListBase *il = (ListBase *)MEM_callocN(sizeof(ListBase), "get_intersections1");;
LinkData *intersection, *link, *spl;
- float *coord_array, vi[2], p3[2], p4[2];
+ float *coord_array, *vi, p3[2], p4[2];
Nurb *nu = nubase->first;
int dims = 3, result;
const float PRECISION = 1e-05;
@@ -6509,33 +6519,38 @@ static ListBase *get_intersections(float *p1, float *p2, ListBase *nubase)
for (link = points_list->first; link; link=link->next) {
coord_array = (float *)link->data;
for (int i = 0; i < nu->resolu - 1; 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) {
- intersection = MEM_callocN(sizeof(LinkData), "getintersections1");
+ intersection = MEM_callocN(sizeof(LinkData), "get_intersections4");
intersection->data = vi;
- BLI_addtail(&il, intersection);
+ BLI_addtail(il, intersection);
}
}
}
}
- return &il;
+ return il;
}
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 *nubase = object_editcurve_get(obedit), *spline_list, *intersections_list;
- BezTriple **selected_endpoints = NULL;
- int n_selected_splines = 0, result;
+ 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], p1_handle[3], bound_box[4], p1_extend[2];
spline_list = get_selected_splines(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;
@@ -6554,21 +6569,100 @@ static int extend_curve_exec(bContext *C, wmOperator *op)
p1, p2); /* result serves to check the existence of the intersection;
* the intersection point is on variables p1 and p2 */
}
- else { /* only one endpoint selected */
- if (selected_endpoints[0]) {
+ 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, selected_endpoints[0]->vec[2]);
}
- else {
+ else if (selected_endpoints[1])
+ {
copy_v3_v3(p1, selected_endpoints[1]->vec[1]);
copy_v3_v3(p1_handle, selected_endpoints[1]->vec[0]);
}
get_nurb_shape_bounds(obedit, bound_box);
get_max_extent_2d(p1, p1_handle, bound_box, p1_extend);
intersections_list = get_intersections(p1, p1_extend, nubase);
- /* nearest_point(p1, get_intersections(p1, p1_extend, nubase), 0, p2); */
+ nearest_point(p1, intersections_list, p2, &result);
}
}
+ else if (n_selected_splines == 2) { /* two endpoints selected on two different splines */
+ first_selected_endpoints = MEM_callocN(2 * sizeof(BezTriple), "extendcurve1");
+ get_selected_endpoints(first_spline, first_selected_endpoints);
+ second_selected_endpoints = MEM_callocN(2 * sizeof(BezTriple), "extendcurve1");
+ get_selected_endpoints(second_spline, second_selected_endpoints);
+
+ float p1_first[3], p1_second[3], p1_first_handle[3], p1_second_handle[3];
+
+ if (first_selected_endpoints[0]) {
+ copy_v3_v3(p1_first, first_selected_endpoints[0]->vec[1]);
+ copy_v3_v3(p1_first_handle, first_selected_endpoints[0]->vec[2]);
+ }
+ else {
+ copy_v3_v3(p1_first, first_selected_endpoints[1]->vec[1]);
+ copy_v3_v3(p1_first_handle, first_selected_endpoints[1]->vec[0]);
+ }
+
+ if (second_selected_endpoints[0]) {
+ copy_v3_v3(p1_second, second_selected_endpoints[0]->vec[1]);
+ copy_v3_v3(p1_second_handle, second_selected_endpoints[0]->vec[2]);
+ }
+ else {
+ copy_v3_v3(p1_second, second_selected_endpoints[1]->vec[1]);
+ copy_v3_v3(p1_second_handle, second_selected_endpoints[1]->vec[0]);
+ }
+
+ result = isect_line_line_v3(p1_first_handle, p1_first,
+ p1_second_handle, p1_second,
+ p1, p2); /* result serves to check the existence of the intersection;
+ * the intersection point is on variables p1 and p2 */
+ }
+
+ if (result != 1)
+ {
+ BKE_report(op->reports, RPT_ERROR, "No intersection found");
+ return OPERATOR_CANCELLED;
+ }
+ else
+ {
+ if (n_selected_splines == 1) {
+ 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)) {
+ copy_v3_v3(nu->bezt[0].vec[1], p2);
+ copy_v3_v3(nu->bezt[nu->pntsu - 1].vec[1], p2);
+ }
+ }
+ BKE_nurbList_handles_set(nubase, 1);
+ }
+ else { /* only one endpoint selected */
+ BKE_nurbList_handles_set(nubase, 5);
+ ed_editcurve_addvert(cu, editnurb, 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++;
+ }
+ }
+ BKE_nurbList_handles_set(nubase, 1);
+ }
+ }
+
+ WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
+ DAG_id_tag_update(obedit->data, 0);
return OPERATOR_FINISHED;
}
More information about the Bf-blender-cvs
mailing list