diff options
author | Campbell Barton <ideasman42@gmail.com> | 2015-01-26 12:55:41 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2015-01-26 13:08:43 +0300 |
commit | 027361c898b343a9c89182ebc15c1737e60946fc (patch) | |
tree | 7c974b999b9b8fcd1a527f3db9a5bfadfae5932d /source | |
parent | 9415976d1785cd615f7585d3e4343a5474b8fe2e (diff) |
Fix T41834: Ctrl+LMB, Extrude Curves 2+ splines
Extrude and Ctrl+LMB now support multiple selected vertices.
Also maintain active vertices.
D964 by Tyler Sliwkanich with own modifications
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/blenkernel/BKE_curve.h | 1 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/curve.c | 29 | ||||
-rw-r--r-- | source/blender/editors/curve/editcurve.c | 584 |
3 files changed, 374 insertions, 240 deletions
diff --git a/source/blender/blenkernel/BKE_curve.h b/source/blender/blenkernel/BKE_curve.h index 13a1468aee8..60cbf8b302e 100644 --- a/source/blender/blenkernel/BKE_curve.h +++ b/source/blender/blenkernel/BKE_curve.h @@ -176,6 +176,7 @@ void BKE_nurb_bezt_calc_plane(struct Nurb *nu, struct BezTriple *bezt, float r_p void BKE_nurb_handle_calc(struct BezTriple *bezt, struct BezTriple *prev, struct BezTriple *next, const bool is_fcurve); void BKE_nurb_handle_calc_simple(struct Nurb *nu, struct BezTriple *bezt); +void BKE_nurb_handle_calc_simple_auto(struct Nurb *nu, struct BezTriple *bezt); void BKE_nurb_handles_calc(struct Nurb *nu); void BKE_nurb_handles_autocalc(struct Nurb *nu, int flag); diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c index f1e9f2b19d7..51330f27fea 100644 --- a/source/blender/blenkernel/intern/curve.c +++ b/source/blender/blenkernel/intern/curve.c @@ -3351,6 +3351,21 @@ void BKE_nurb_handle_calc_simple(Nurb *nu, BezTriple *bezt) } } +void BKE_nurb_handle_calc_simple_auto(Nurb *nu, BezTriple *bezt) +{ + if (nu->pntsu > 1) { + const char h1_back = bezt->h1, h2_back = bezt->h2; + + bezt->h1 = bezt->h2 = HD_AUTO; + + /* Override handle types to HD_AUTO and recalculate */ + BKE_nurb_handle_calc_simple(nu, bezt); + + bezt->h1 = h1_back; + bezt->h2 = h2_back; + } +} + /** * Use when something has changed handle positions. * @@ -3608,24 +3623,12 @@ void BKE_nurbList_handles_recalculate(ListBase *editnurb, const bool calc_length if (h1_select || h2_select) { - /* Override handle types to HD_AUTO and recalculate */ - - char h1_back, h2_back; float co1_back[3], co2_back[3]; - h1_back = bezt->h1; - h2_back = bezt->h2; - - bezt->h1 = HD_AUTO; - bezt->h2 = HD_AUTO; - copy_v3_v3(co1_back, bezt->vec[0]); copy_v3_v3(co2_back, bezt->vec[2]); - BKE_nurb_handle_calc_simple(nu, bezt); - - bezt->h1 = h1_back; - bezt->h2 = h2_back; + BKE_nurb_handle_calc_simple_auto(nu, bezt); if (h1_select) { if (!calc_length) { diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c index 25dedee4630..f17c46252c4 100644 --- a/source/blender/editors/curve/editcurve.c +++ b/source/blender/editors/curve/editcurve.c @@ -2007,7 +2007,7 @@ static void ed_curve_delete_selected(Object *obedit) } /* only for OB_SURF */ -bool ed_editnurb_extrude_flag(EditNurb *editnurb, short flag) +bool ed_editnurb_extrude_flag(EditNurb *editnurb, const short flag) { Nurb *nu; BPoint *bp, *bpn, *newbp; @@ -4888,285 +4888,405 @@ void CURVE_OT_spin(wmOperatorType *ot) RNA_def_float_vector(ot->srna, "axis", 3, NULL, -FLT_MAX, FLT_MAX, "Axis", "Axis in global view space", -1.0f, 1.0f); } -/***************** add vertex operator **********************/ +/***************** extrude vertex operator **********************/ -static int addvert_Nurb(bContext *C, short mode, float location[3]) +static bool ed_editcurve_extrude(Curve *cu, EditNurb *editnurb) { - Object *obedit = CTX_data_edit_object(C); - Curve *cu = (Curve *)obedit->data; - EditNurb *editnurb = cu->editnurb; - Nurb *nu, *newnu = NULL; - BezTriple *bezt, *newbezt = NULL; - BPoint *bp, *newbp = NULL; - float imat[4][4], temp[3]; - bool ok = false; - BezTriple *bezt_recalc[3] = {NULL}; + Nurb *nu = NULL; + Nurb *nu_last = NULL; - invert_m4_m4(imat, obedit->obmat); + bool changed = false; - findselectedNurbvert(&editnurb->nurbs, &nu, &bezt, &bp); - - if ((nu == NULL) || (nu->type == CU_BEZIER && bezt == NULL) || (nu->type != CU_BEZIER && bp == NULL)) { - if (mode != 'e') { - if (cu->actnu != CU_ACT_NONE) - nu = BLI_findlink(&editnurb->nurbs, cu->actnu); - - if (!nu || nu->type == CU_BEZIER) { - newbezt = (BezTriple *)MEM_callocN(sizeof(BezTriple), "addvert_Nurb"); - newbezt->radius = 1; - newbezt->alfa = 0; - BEZ_SEL(newbezt); - newbezt->h2 = newbezt->h1 = HD_AUTO; - - newnu = (Nurb *)MEM_callocN(sizeof(Nurb), "addvert_Nurb newnu"); - if (!nu) { - /* no selected segment -- create new one which is BEZIER type - * type couldn't be determined from Curve bt could be changed - * in the future, so shouldn't make much headache */ - newnu->type = CU_BEZIER; - newnu->resolu = cu->resolu; - newnu->flag |= CU_SMOOTH; - } - else { - memcpy(newnu, nu, sizeof(Nurb)); - } + Nurb *cu_actnu; + union { + BezTriple *bezt; + BPoint *bp; + void *p; + } cu_actvert; - BLI_addtail(&editnurb->nurbs, newnu); - newnu->bezt = newbezt; - newnu->pntsu = 1; + BKE_curve_nurb_vert_active_get(cu, &cu_actnu, &cu_actvert.p); + BKE_curve_nurb_vert_active_set(cu, NULL, NULL); - temp[0] = 1; - temp[1] = 0; - temp[2] = 0; + /* first pass (endpoints) */ + for (nu = editnurb->nurbs.first; nu; nu = nu->next) { - copy_v3_v3(newbezt->vec[1], location); - sub_v3_v3v3(newbezt->vec[0], newbezt->vec[1], temp); - add_v3_v3v3(newbezt->vec[2], newbezt->vec[1], temp); + if ((nu->flagu & CU_NURB_CYCLIC) && (nu->pntsu > 1)) { + continue; + } - mul_m4_v3(imat, newbezt->vec[0]); - mul_m4_v3(imat, newbezt->vec[1]); - mul_m4_v3(imat, newbezt->vec[2]); + if (nu->type == CU_BEZIER) { - ok = 1; - nu = newnu; - } - else if (nu->pntsv == 1) { - newbp = (BPoint *)MEM_callocN(sizeof(BPoint), "addvert_Nurb5"); - newbp->radius = 1; - newbp->alfa = 0; - newbp->f1 |= SELECT; + /* Check to see if the first bezier point is selected */ + if (nu->pntsu > 0 && nu->bezt != NULL) { + BezTriple *nu_bezt_old = nu->bezt; + BezTriple *bezt = nu->bezt; - newnu = (Nurb *)MEM_mallocN(sizeof(Nurb), "addvert_Nurb newnu"); - memcpy(newnu, nu, sizeof(Nurb)); - BLI_addtail(&editnurb->nurbs, newnu); - newnu->bp = newbp; - newnu->orderu = 2; - newnu->pntsu = 1; + if (BEZSELECTED_HIDDENHANDLES(cu, bezt)) { + BezTriple *bezt_new; + BEZ_DESEL(bezt); - mul_v3_m4v3(newbp->vec, imat, location); - newbp->vec[3] = 1.0; + bezt_new = MEM_mallocN((nu->pntsu + 1) * sizeof(BezTriple), __func__); + ED_curve_beztcpy(editnurb, bezt_new + 1, bezt, nu->pntsu); + *bezt_new = *bezt; - newnu->knotsu = newnu->knotsv = NULL; - BKE_nurb_knot_calc_u(newnu); - ok = 1; - nu = newnu; + MEM_freeN(nu->bezt); + nu->bezt = bezt_new; + + nu->pntsu += 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) + 1]; + BKE_curve_nurb_vert_active_set(cu, nu, cu_actvert.bezt); + } + + BEZ_SEL(bezt_new); + changed = true; + } } + /* Check to see if the last bezier point is selected */ + if (nu->pntsu > 1) { + BezTriple *nu_bezt_old = nu->bezt; + BezTriple *bezt = &nu->bezt[nu->pntsu - 1]; + + if (BEZSELECTED_HIDDENHANDLES(cu, bezt)) { + BezTriple *bezt_new; + BEZ_DESEL(bezt); + + bezt_new = MEM_mallocN((nu->pntsu + 1) * sizeof(BezTriple), __func__); + ED_curve_beztcpy(editnurb, bezt_new, nu->bezt, nu->pntsu); + bezt_new[nu->pntsu] = *bezt; + + MEM_freeN(nu->bezt); + nu->bezt = bezt_new; + + bezt_new += nu->pntsu; + nu->pntsu += 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); + } + + BEZ_SEL(bezt_new); + changed = true; + } + } } + else { - if (!ok) - return OPERATOR_CANCELLED; - } + /* Check to see if the first bpoint is selected */ + if (nu->pntsu > 0 && nu->bp != NULL) { + BPoint *nu_bp_old = nu->bp; + BPoint *bp = nu->bp; - if (!ok && nu->type == CU_BEZIER) { - /* which bezpoint? */ - if (bezt == &nu->bezt[nu->pntsu - 1]) { /* last */ - BEZ_DESEL(bezt); - newbezt = (BezTriple *)MEM_callocN((nu->pntsu + 1) * sizeof(BezTriple), "addvert_Nurb"); - ED_curve_beztcpy(editnurb, newbezt, nu->bezt, nu->pntsu); - newbezt[nu->pntsu] = *bezt; - copy_v3_v3(temp, bezt->vec[1]); - MEM_freeN(nu->bezt); - nu->bezt = newbezt; - newbezt += nu->pntsu; - BEZ_SEL(newbezt); - newbezt->h1 = newbezt->h2; - bezt = &nu->bezt[nu->pntsu - 1]; - ok = 1; + if (bp->f1 & SELECT) { + BPoint *bp_new; + bp->f1 &= ~SELECT; - if (nu->pntsu > 1) { - bezt_recalc[1] = newbezt; - bezt_recalc[0] = newbezt - 1; - } - } - else if (bezt == nu->bezt) { /* first */ - BEZ_DESEL(bezt); - newbezt = (BezTriple *)MEM_callocN((nu->pntsu + 1) * sizeof(BezTriple), "addvert_Nurb"); - ED_curve_beztcpy(editnurb, newbezt + 1, bezt, nu->pntsu); - *newbezt = *bezt; - BEZ_SEL(newbezt); - newbezt->h2 = newbezt->h1; - copy_v3_v3(temp, bezt->vec[1]); - MEM_freeN(nu->bezt); - nu->bezt = newbezt; - bezt = newbezt + 1; - ok = 1; + bp_new = MEM_mallocN((nu->pntsu + 1) * sizeof(BPoint), __func__); + ED_curve_bpcpy(editnurb, bp_new + 1, bp, nu->pntsu); + *bp_new = *bp; + + MEM_freeN(nu->bp); + nu->bp = bp_new; + + nu->pntsu += 1; + BKE_nurb_knot_calc_u(nu); + if (ARRAY_HAS_ITEM(cu_actvert.bp, nu_bp_old, nu->pntsu - 1)) { + cu_actvert.bp = (cu_actvert.bp == bp) ? + bp_new : &nu->bp[(cu_actvert.bp - nu_bp_old) + 1]; + BKE_curve_nurb_vert_active_set(cu, nu, cu_actvert.bp); + } + + bp_new->f1 |= SELECT; + changed = true; + } + } + + /* Check to see if the last bpoint is selected */ if (nu->pntsu > 1) { - bezt_recalc[1] = newbezt; - bezt_recalc[2] = newbezt + 1; + BPoint *nu_bp_old = nu->bp; + BPoint *bp = &nu->bp[nu->pntsu - 1]; + + if (bp->f1 & SELECT) { + BPoint *bp_new; + bp->f1 &= ~SELECT; + + bp_new = MEM_mallocN((nu->pntsu + 1) * sizeof(BPoint), __func__); + ED_curve_bpcpy(editnurb, bp_new, nu->bp, nu->pntsu); + bp_new[nu->pntsu] = *bp; + + MEM_freeN(nu->bp); + nu->bp = bp_new; + + bp_new += nu->pntsu; + nu->pntsu += 1; + + if (ARRAY_HAS_ITEM(cu_actvert.bp, nu_bp_old, nu->pntsu - 1)) { + cu_actvert.bp = (cu_actvert.bp == bp) ? + bp_new : &nu->bp[cu_actvert.bp - nu_bp_old]; + BKE_curve_nurb_vert_active_set(cu, nu, cu_actvert.bp); + } + + BKE_nurb_knot_calc_u(nu); + + bp_new->f1 |= SELECT; + changed = true; + } } } - else if (mode != 'e') { - BEZ_DESEL(bezt); - newbezt = (BezTriple *)MEM_callocN(sizeof(BezTriple), "addvert_Nurb"); - *newbezt = *bezt; - BEZ_SEL(newbezt); - newbezt->h2 = newbezt->h1; - copy_v3_v3(temp, bezt->vec[1]); + } - newnu = (Nurb *)MEM_mallocN(sizeof(Nurb), "addvert_Nurb newnu"); - memcpy(newnu, nu, sizeof(Nurb)); - BLI_addtail(&editnurb->nurbs, newnu); - newnu->bezt = newbezt; - newnu->pntsu = 1; + /* second pass (interior points) */ + nu_last = editnurb->nurbs.last; + for (nu = editnurb->nurbs.first; (nu != nu_last->next); nu = nu->next) { + int i, i_end; - nu = newnu; - bezt = newbezt; - ok = 1; + if ((nu->flagu & CU_NURB_CYCLIC) && (nu->pntsu > 1)) { + /* all points are interior */ + i = 0; + i_end = nu->pntsu; } else { - bezt = NULL; + /* skip endpoints */ + i = 1; + i_end = nu->pntsu - 1; } - if (bezt) { - if (!newnu) nu->pntsu++; + if (nu->type == CU_BEZIER) { + BezTriple *bezt; - if (mode == 'e') { - copy_v3_v3(newbezt->vec[0], bezt->vec[0]); - copy_v3_v3(newbezt->vec[1], bezt->vec[1]); - copy_v3_v3(newbezt->vec[2], bezt->vec[2]); - } - else { - mul_v3_m4v3(newbezt->vec[1], imat, location); - sub_v3_v3v3(temp, newbezt->vec[1], temp); + for (bezt = &nu->bezt[i]; i < i_end; i++, bezt++) { + if (BEZSELECTED_HIDDENHANDLES(cu, bezt)) { + Nurb *nurb_new; + BezTriple *bezt_new; + + BEZ_DESEL(bezt); + nurb_new = BKE_nurb_copy(nu, 1, 1); + nurb_new->flagu &= ~CU_NURB_CYCLIC; + BLI_addtail(&editnurb->nurbs, nurb_new); + bezt_new = nurb_new->bezt; + ED_curve_beztcpy(editnurb, bezt_new, bezt, 1); + BEZ_SEL(bezt_new); + + if (cu_actvert.bezt == bezt || cu_actnu == NULL) { + BKE_curve_nurb_vert_active_set(cu, nurb_new, bezt_new); + } - if (bezt_recalc[1]) { - const char h1 = bezt_recalc[1]->h1, h2 = bezt_recalc[1]->h2; - bezt_recalc[1]->h1 = bezt_recalc[1]->h2 = HD_AUTO; - BKE_nurb_handle_calc(bezt_recalc[1], bezt_recalc[0], bezt_recalc[2], 0); - bezt_recalc[1]->h1 = h1; - bezt_recalc[1]->h2 = h2; - } - else { - add_v3_v3v3(newbezt->vec[0], bezt->vec[0], temp); - add_v3_v3v3(newbezt->vec[2], bezt->vec[2], temp); + changed = true; } - + } + } + else { + BPoint *bp; + + for (bp = &nu->bp[i]; i < i_end; i++, bp++) { + if (bp->f1 & SELECT) { + Nurb *nurb_new; + BPoint *bp_new; + + bp->f1 &= ~SELECT; + nurb_new = BKE_nurb_copy(nu, 1, 1); + nurb_new->flagu &= ~CU_NURB_CYCLIC; + BLI_addtail(&editnurb->nurbs, nurb_new); + bp_new = nurb_new->bp; + ED_curve_bpcpy(editnurb, bp_new, bp, 1); + bp_new->f1 |= SELECT; + + if (cu_actvert.bp == bp || cu_actnu == NULL) { + BKE_curve_nurb_vert_active_set(cu, nurb_new, bp_new); + } - if (newnu) BKE_nurb_handles_calc(newnu); - else BKE_nurb_handles_calc(nu); + changed = true; + } } } } - else if (!ok && nu->pntsv == 1) { - /* which b-point? */ - if (bp == &nu->bp[nu->pntsu - 1]) { /* last */ - bp->f1 = 0; - newbp = (BPoint *)MEM_callocN((nu->pntsu + 1) * sizeof(BPoint), "addvert_Nurb4"); - ED_curve_bpcpy(editnurb, newbp, nu->bp, nu->pntsu); - newbp[nu->pntsu] = *bp; - MEM_freeN(nu->bp); - nu->bp = newbp; - newbp += nu->pntsu; - newbp->f1 |= SELECT; - bp = newbp - 1; - ok = 1; - } - else if (bp == nu->bp) { /* first */ - bp->f1 = 0; - newbp = (BPoint *)MEM_callocN((nu->pntsu + 1) * sizeof(BPoint), "addvert_Nurb3"); - ED_curve_bpcpy(editnurb, newbp + 1, bp, nu->pntsu); - *newbp = *bp; - newbp->f1 |= SELECT; - MEM_freeN(nu->bp); - nu->bp = newbp; - bp = newbp + 1; - ok = 1; - } - else if (mode != 'e') { - bp->f1 = 0; - newbp = (BPoint *)MEM_callocN(sizeof(BPoint), "addvert_Nurb5"); - *newbp = *bp; - newbp->f1 |= SELECT; - newnu = (Nurb *)MEM_mallocN(sizeof(Nurb), "addvert_Nurb newnu"); - memcpy(newnu, nu, sizeof(Nurb)); - BLI_addtail(&editnurb->nurbs, newnu); - newnu->bp = newbp; - newnu->orderu = 2; - newnu->pntsu = 1; - newnu->knotsu = newnu->knotsv = NULL; + if (changed == false) { + BKE_curve_nurb_vert_active_set(cu, cu_actnu, cu_actvert.p); + } - nu = newnu; - bp = newbp; - ok = 1; + return changed; +} + +/***************** add vertex operator **********************/ + +static int ed_editcurve_addvert(Curve *cu, EditNurb *editnurb, const float location[3]) +{ + Nurb *nu; + + float minmax[2][3]; + float temp[3]; + bool nu_has_select = false; + + bool changed = false; + + INIT_MINMAX(minmax[0], minmax[1]); + + for (nu = editnurb->nurbs.first; nu; nu = nu->next) { + int i; + if (nu->type == CU_BEZIER) { + BezTriple *bezt; + + for (i = 0, bezt = nu->bezt; i < nu->pntsu; i++, bezt++) { + if (BEZSELECTED_HIDDENHANDLES(cu, bezt)) { + minmax_v3v3_v3(UNPACK2(minmax), bezt->vec[1]); + nu_has_select = true; + } + } } else { - bp = NULL; + BPoint *bp; + + for (i = 0, bp = nu->bp; i < nu->pntsu; i++, bp++) { + if (bp->f1 & SELECT) { + minmax_v3v3_v3(UNPACK2(minmax), bp->vec); + nu_has_select = true; + } + } } + } + + if (nu_has_select && ed_editcurve_extrude(cu, editnurb)) { + float ofs[3], center[3]; + int i; - if (bp) { - if (mode == 'e') { - copy_v3_v3(newbp->vec, bp->vec); + mid_v3_v3v3(center, minmax[0], minmax[1]); + sub_v3_v3v3(ofs, location, center); + + if ((cu->flag & CU_3D) == 0) { + ofs[2] = 0.0f; + } + + for (nu = editnurb->nurbs.first; nu; nu = nu->next) { + if (nu->type == CU_BEZIER) { + BezTriple *bezt; + for (i = 0, bezt = nu->bezt; i < nu->pntsu; i++, bezt++) { + if (BEZSELECTED_HIDDENHANDLES(cu, bezt)) { + add_v3_v3(bezt->vec[0], ofs); + add_v3_v3(bezt->vec[1], ofs); + add_v3_v3(bezt->vec[2], ofs); + + if (((nu->flagu & CU_NURB_CYCLIC) == 0) && + (i == 0 || i == nu->pntsu - 1)) + { + BKE_nurb_handle_calc_simple_auto(nu, bezt); + } + } + } } else { - mul_v3_m4v3(newbp->vec, imat, location); - newbp->vec[3] = 1.0; + BPoint *bp; - if (!newnu && nu->orderu < 4 && nu->orderu <= nu->pntsu) - nu->orderu++; + for (i = 0, bp = nu->bp; i < nu->pntsu; i++, bp++) { + if (bp->f1 & SELECT) { + add_v3_v3(bp->vec, ofs); + } + } } + } + changed = true; + } + else { + /* nothing selected: create a new curve */ + nu = BKE_curve_nurb_active_get(cu); - if (!newnu) { - nu->pntsu++; - BKE_nurb_knot_calc_u(nu); + if (!nu || nu->type == CU_BEZIER) { + Nurb *nurb_new; + BezTriple *bezt_new; + + if (nu) { + nurb_new = BKE_nurb_copy(nu, 1, 1); } else { - BKE_nurb_knot_calc_u(newnu); + nurb_new = MEM_callocN(sizeof(Nurb), "BLI_editcurve_addvert new_bezt_nurb 2"); + nurb_new->type = CU_BEZIER; + nurb_new->resolu = cu->resolu; + nurb_new->orderu = 4; + nurb_new->flag |= CU_SMOOTH; + BKE_nurb_bezierPoints_add(nurb_new, 1); } - } - } + BLI_addtail(&editnurb->nurbs, nurb_new); - if (ok) { - if (nu->bezt) { - BKE_curve_nurb_vert_active_set(cu, nu, newbezt); + bezt_new = nurb_new->bezt; + + BEZ_SEL(bezt_new); + + bezt_new->h1 = HD_AUTO; + bezt_new->h2 = HD_AUTO; + + temp[0] = 1.0f; + temp[1] = 0.0f; + temp[2] = 0.0f; + + copy_v3_v3(bezt_new->vec[1], location); + sub_v3_v3v3(bezt_new->vec[0], bezt_new->vec[1], temp); + add_v3_v3v3(bezt_new->vec[2], bezt_new->vec[1], temp); + + changed = true; } else { - BKE_curve_nurb_vert_active_set(cu, nu, newbp); - } + Nurb *nurb_new; + BPoint *bp_new; - BKE_nurb_test2D(nu); + { + nurb_new = MEM_callocN(sizeof(Nurb), __func__); + nurb_new->type = CU_POLY; + nurb_new->resolu = cu->resolu; + nurb_new->flag |= CU_SMOOTH; + nurb_new->orderu = 4; + BKE_nurb_points_add(nurb_new, 1); + } + BLI_addtail(&editnurb->nurbs, nurb_new); - if (ED_curve_updateAnimPaths(obedit->data)) - WM_event_add_notifier(C, NC_OBJECT | ND_KEYS, obedit); + bp_new = nurb_new->bp; - WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data); - DAG_id_tag_update(obedit->data, 0); + bp_new->f1 |= SELECT; - return OPERATOR_FINISHED; + copy_v3_v3(bp_new->vec, location); + bp_new->vec[3] = 1.0f; + + BKE_nurb_knot_calc_u(nurb_new); + + changed = true; + } } - return OPERATOR_CANCELLED; + return changed; } static int add_vertex_exec(bContext *C, wmOperator *op) { + Object *obedit = CTX_data_edit_object(C); + Curve *cu = obedit->data; + EditNurb *editnurb = cu->editnurb; float location[3]; + float imat[4][4]; RNA_float_get_array(op->ptr, "location", location); - return addvert_Nurb(C, 0, location); + + invert_m4_m4(imat, obedit->obmat); + mul_m4_v3(imat, location); + + if (ed_editcurve_addvert(cu, editnurb, location)) { + if (ED_curve_updateAnimPaths(obedit->data)) { + WM_event_add_notifier(C, NC_OBJECT | ND_KEYS, obedit); + } + + WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data); + DAG_id_tag_update(obedit->data, 0); + + return OPERATOR_FINISHED; + } + else { + return OPERATOR_CANCELLED; + } } static int add_vertex_invoke(bContext *C, wmOperator *op, const wmEvent *event) @@ -5235,29 +5355,39 @@ void CURVE_OT_vertex_add(wmOperatorType *ot) /***************** extrude operator **********************/ -static int extrude_exec(bContext *C, wmOperator *UNUSED(op)) +static int curve_extrude_exec(bContext *C, wmOperator *UNUSED(op)) { Object *obedit = CTX_data_edit_object(C); Curve *cu = obedit->data; EditNurb *editnurb = cu->editnurb; - Nurb *nu; + bool changed = false; + bool as_curve = false; /* first test: curve? */ - for (nu = editnurb->nurbs.first; nu; nu = nu->next) - if (nu->pntsv == 1 && isNurbsel_count(cu, nu) == 1) - break; + if (obedit->type != OB_CURVE) { + Nurb *nu; + for (nu = editnurb->nurbs.first; nu; nu = nu->next) { + if (nu->pntsv == 1 && isNurbsel_count(cu, nu) == 1) { + as_curve = true; + break; + } + } + } - if (obedit->type == OB_CURVE || nu) { - addvert_Nurb(C, 'e', NULL); + if (obedit->type == OB_CURVE || as_curve) { + changed = ed_editcurve_extrude(cu, editnurb); } else { - if (ed_editnurb_extrude_flag(editnurb, SELECT)) { - if (ED_curve_updateAnimPaths(obedit->data)) - WM_event_add_notifier(C, NC_OBJECT | ND_KEYS, obedit); + changed = ed_editnurb_extrude_flag(editnurb, SELECT); + } - WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data); - DAG_id_tag_update(obedit->data, 0); + if (changed) { + if (ED_curve_updateAnimPaths(obedit->data)) { + WM_event_add_notifier(C, NC_OBJECT | ND_KEYS, obedit); } + + WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data); + DAG_id_tag_update(obedit->data, 0); } return OPERATOR_FINISHED; @@ -5271,7 +5401,7 @@ void CURVE_OT_extrude(wmOperatorType *ot) ot->idname = "CURVE_OT_extrude"; /* api callbacks */ - ot->exec = extrude_exec; + ot->exec = curve_extrude_exec; ot->poll = ED_operator_editsurfcurve; /* flags */ |