[Bf-blender-cvs] [ea311fc] gsoc2016-improved_extrusion: Curves: Batch extend operator
João Araújo
noreply at git.blender.org
Sat Jul 30 00:31:51 CEST 2016
Commit: ea311fc39429031286f4e9d4ae31fb74710e4853
Author: João Araújo
Date: Fri Jul 29 23:30:10 2016 +0100
Branches: gsoc2016-improved_extrusion
https://developer.blender.org/rBea311fc39429031286f4e9d4ae31fb74710e4853
Curves: Batch extend operator
Concluded the implementation of the Batch extend operator.
Though some code was reused from the Extend operator, the main algorithm is different.
===================================================================
M source/blender/editors/curve/editcurve.c
===================================================================
diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c
index 32b011c..6eaffeb 100644
--- a/source/blender/editors/curve/editcurve.c
+++ b/source/blender/editors/curve/editcurve.c
@@ -6583,7 +6583,7 @@ static int extend_curve_exec(bContext *C, wmOperator *op)
second_spline = (Nurb *)spline_list.last;
if (n_selected_splines == 1) { /* one spline selected */
- selected_endpoints = MEM_callocN(2 * sizeof(BezTriple), "extendcurve1");
+ 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 */
@@ -7691,53 +7691,139 @@ 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])
+{
+ 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(obedit, 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);
+ }
+}
+
+static void add_bezt(Nurb *nu, float *p, int position, Curve *cu)
+{
+ /* this function is a weaker version of the ed_editnurb_addvert function */
+ Nurb *cu_actnu;
+ union {
+ BezTriple *bezt;
+ void *p;
+ } cu_actvert;
+
+ EditNurb *editnurb = cu->editnurb;
+ BKE_curve_nurb_vert_active_get(cu, &cu_actnu, &cu_actvert.p);
+ BKE_curve_nurb_vert_active_set(cu, NULL, NULL);
+
+ BezTriple *bezt_new, *bezt = nu->bezt;
+
+ bezt_new = MEM_mallocN((nu->pntsu + 1) * sizeof(BezTriple), __func__);
+ BezTriple *nu_bezt_old = nu->bezt;
+ if (position == 0) {
+ ED_curve_beztcpy(editnurb, bezt_new + 1, bezt, nu->pntsu);
+ *bezt_new = *bezt;
+ }
+ else if (position == 1) {
+ ED_curve_beztcpy(editnurb, bezt_new, bezt, nu->pntsu);
+ bezt_new[nu->pntsu]= *bezt;
+ }
+
+ MEM_freeN(nu->bezt);
+ nu->bezt = bezt_new;
+
+ nu->pntsu += 1;
+
+ if (position == 0) {
+ if (ARRAY_HAS_ITEM(cu_actvert.bezt, nu_bezt_old, nu->pntsu - 1)) {
+ cu_actvert.bezt = (cu_actvert.bezt == bezt) ?
+ bezt_new : &nu->bezt[(cu_actvert.bezt - nu_bezt_old) + 1];
+ BKE_curve_nurb_vert_active_set(cu, nu, cu_actvert.bezt);
+ }
+ }
+ else if (position == 1) {
+ if (ARRAY_HAS_ITEM(cu_actvert.bezt, nu_bezt_old, nu->pntsu - 1)) {
+ cu_actvert.bezt = (cu_actvert.bezt == bezt) ?
+ bezt_new : &nu->bezt[cu_actvert.bezt - nu_bezt_old];
+ BKE_curve_nurb_vert_active_set(cu, nu, cu_actvert.bezt);
+ }
+ }
+
+ if (position == 0) {
+ copy_v3_v3(nu->bezt->vec[1], p);
+ BEZT_SEL_ALL(nu->bezt);
+ }
+ else if (position == 1) {
+ copy_v3_v3(nu->bezt[nu->pntsu - 1].vec[1], p);
+ BEZT_SEL_ALL(&nu->bezt[nu->pntsu - 1]);
+ }
+
+ BKE_nurb_handles_calc(nu);
+}
+
static int batch_extend_exec(bContext *C, wmOperator *op)
{
Object *obedit = CTX_data_edit_object(C);
ListBase *nubase = object_editcurve_get(obedit);
Nurb *nu;
+ Curve *cu = obedit->data;
+ EditNurb *editnurb = cu->editnurb;
BezTriple *bezt, **selected_triples, **selected_endpoints = NULL;
+ ListBase first_extend = {NULL}, last_extend = {NULL};
+ LinkData *link;
/* at most, both endpoints can be selected for all splines */
selected_triples = MEM_callocN(2 * BLI_listbase_count(nubase) * sizeof(BezTriple *), "batch_extend1");
- /* make a list with all the selected endpoints */
- int i = 0;
+ /* fill in the lists with all the selected endpoints */
for (nu = nubase->first; nu; nu = nu->next) {
bezt = nu->bezt;
if (BEZT_ISSEL_ANY(bezt)) { /* first endpoint */
- selected_triples[i] = bezt;
- i++;
+ BEZT_DESEL_ALL(bezt);
+ link = MEM_callocN(sizeof(Nurb *), "batch_extend2");
+ link->data = nu;
+ BLI_addtail(&first_extend, link);
}
bezt = &nu->bezt[nu->pntsu - 1];
if (BEZT_ISSEL_ANY(bezt)) { /* last endpoint */
- selected_triples[i] = bezt;
- i++;
+ BEZT_DESEL_ALL(bezt);
+ link = MEM_callocN(sizeof(Nurb *), "batch_extend2");
+ link->data = nu;
+ BLI_addtail(&last_extend, link);
}
}
- if (i < 2 * BLI_listbase_count(nubase)) {
- selected_endpoints = MEM_callocN(i * sizeof(BezTriple *), "batch_extend2");
- memcpy(selected_endpoints, selected_triples, i * sizeof(BezTriple*));
- }
- else {
- selected_endpoints = selected_triples;
- }
-
- /* unselect them all */
- WM_operator_name_call(C, "CURVE_OT_select_all", WM_OP_EXEC_DEFAULT, op->ptr);
-
- /* for each on the list, select and extend them */
- for (int j = 0; j < i; j++) {
- bezt = selected_endpoints[j];
- BEZT_SEL_ALL(bezt);
- extend_curve_exec(C, op);
- /* deselect all vertices again */
- WM_operator_name_call(C, "CURVE_OT_select_all", WM_OP_EXEC_DEFAULT, op->ptr);
+ float p2[3];
+ for (LinkData *l = first_extend.first; l; l = l->next) {
+ nu = l->data;
+ bezt = nu->bezt;
+ extend_vertex(0, nu, nubase, obedit, p2);
+ BKE_nurbList_handles_set(nubase, 5);
+ p2[2] = bezt->vec[1][2];
+ add_bezt(nu, p2, 0, cu);
+ BKE_nurbList_handles_set(nubase, 1);
+ }
+ for (LinkData *l = last_extend.first; l; l = l->next) {
+ nu = l->data;
+ bezt = nu->bezt;
+ extend_vertex(1, nu, nubase, obedit, p2);
+ BKE_nurbList_handles_set(nubase, 5);
+ p2[2] = bezt->vec[1][2];
+ add_bezt(nu, p2, 1, cu);
+ BKE_nurbList_handles_set(nubase, 1);
}
- MEM_freeN(selected_triples);
- MEM_freeN(selected_endpoints);
-
WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
DAG_id_tag_update(obedit->data, 0);
More information about the Bf-blender-cvs
mailing list