Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/editors/curve/editcurve.c')
-rw-r--r--source/blender/editors/curve/editcurve.c611
1 files changed, 367 insertions, 244 deletions
diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c
index 99c64be5797..4aeeaa87269 100644
--- a/source/blender/editors/curve/editcurve.c
+++ b/source/blender/editors/curve/editcurve.c
@@ -643,25 +643,20 @@ static void keyData_switchDirectionNurb(Curve *cu, Nurb *nu)
static GHash *dupli_keyIndexHash(GHash *keyindex)
{
GHash *gh;
- GHashIterator *hashIter;
+ GHashIterator gh_iter;
gh = BLI_ghash_ptr_new_ex("dupli_keyIndex gh", BLI_ghash_size(keyindex));
- for (hashIter = BLI_ghashIterator_new(keyindex);
- BLI_ghashIterator_done(hashIter) == false;
- BLI_ghashIterator_step(hashIter))
- {
- void *cv = BLI_ghashIterator_getKey(hashIter);
- CVKeyIndex *index = BLI_ghashIterator_getValue(hashIter);
- CVKeyIndex *newIndex = MEM_callocN(sizeof(CVKeyIndex), "dupli_keyIndexHash index");
+ GHASH_ITER (gh_iter, keyindex) {
+ void *cv = BLI_ghashIterator_getKey(&gh_iter);
+ CVKeyIndex *index = BLI_ghashIterator_getValue(&gh_iter);
+ CVKeyIndex *newIndex = MEM_mallocN(sizeof(CVKeyIndex), "dupli_keyIndexHash index");
memcpy(newIndex, index, sizeof(CVKeyIndex));
BLI_ghash_insert(gh, cv, newIndex);
}
- BLI_ghashIterator_free(hashIter);
-
return gh;
}
@@ -999,7 +994,7 @@ static void fcurve_path_rename(AnimData *adt, const char *orig_rna_path, char *r
for (fcu = orig_curves->first; fcu; fcu = nextfcu) {
nextfcu = fcu->next;
- if (!strncmp(fcu->rna_path, orig_rna_path, len)) {
+ if (STREQLEN(fcu->rna_path, orig_rna_path, len)) {
char *spath, *suffix = fcu->rna_path + len;
nfcu = copy_fcurve(fcu);
spath = nfcu->rna_path;
@@ -1102,10 +1097,10 @@ static void curve_rename_fcurves(Curve *cu, ListBase *orig_curves)
for (fcu = orig_curves->first; fcu; fcu = next) {
next = fcu->next;
- if (!strncmp(fcu->rna_path, "splines", 7)) {
+ if (STREQLEN(fcu->rna_path, "splines", 7)) {
const char *ch = strchr(fcu->rna_path, '.');
- if (ch && (!strncmp(ch, ".bezier_points", 14) || !strncmp(ch, ".points", 7)))
+ if (ch && (STREQLEN(ch, ".bezier_points", 14) || STREQLEN(ch, ".points", 7)))
fcurve_remove(adt, orig_curves, fcu);
}
}
@@ -1129,7 +1124,7 @@ static void curve_rename_fcurves(Curve *cu, ListBase *orig_curves)
for (fcu = orig_curves->first; fcu; fcu = next) {
next = fcu->next;
- if (!strncmp(fcu->rna_path, "splines", 7)) fcurve_remove(adt, orig_curves, fcu);
+ if (STREQLEN(fcu->rna_path, "splines", 7)) fcurve_remove(adt, orig_curves, fcu);
else BLI_addtail(&curves, fcu);
}
@@ -2007,7 +2002,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;
@@ -2368,7 +2363,6 @@ static void adduplicateflagNurb(Object *obedit, ListBase *newnurb,
}
else {
/* knots done after duplicate as pntsu may change */
- nu->knotsu = nu->knotsv = NULL;
BKE_nurb_order_clamp_u(nu);
BKE_nurb_knot_calc_u(nu);
@@ -4889,285 +4883,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;
+
+ if (BEZSELECTED_HIDDENHANDLES(cu, bezt)) {
+ BezTriple *bezt_new;
+ BEZ_DESEL(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;
+ bezt_new = MEM_mallocN((nu->pntsu + 1) * sizeof(BezTriple), __func__);
+ ED_curve_beztcpy(editnurb, bezt_new + 1, bezt, nu->pntsu);
+ *bezt_new = *bezt;
- mul_v3_m4v3(newbp->vec, imat, location);
- newbp->vec[3] = 1.0;
- newnu->knotsu = newnu->knotsv = NULL;
- BKE_nurb_knot_calc_u(newnu);
+ MEM_freeN(nu->bezt);
+ nu->bezt = bezt_new;
- ok = 1;
- nu = newnu;
+ 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;
+
+ mid_v3_v3v3(center, minmax[0], minmax[1]);
+ sub_v3_v3v3(ofs, location, center);
- if (bp) {
- if (mode == 'e') {
- copy_v3_v3(newbp->vec, bp->vec);
+ 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)
@@ -5236,29 +5350,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;
@@ -5272,7 +5396,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 */
@@ -6543,7 +6667,6 @@ static int curve_delete_segments(Object *obedit, const bool split)
}
}
- nu->knotsu = nu->knotsv = NULL;
BKE_nurb_order_clamp_u(nu);
BKE_nurb_knot_calc_u(nu);
@@ -6640,7 +6763,7 @@ static int shade_smooth_exec(bContext *C, wmOperator *op)
Object *obedit = CTX_data_edit_object(C);
ListBase *editnurb = object_editcurve_get(obedit);
Nurb *nu;
- int clear = (strcmp(op->idname, "CURVE_OT_shade_flat") == 0);
+ int clear = (STREQ(op->idname, "CURVE_OT_shade_flat"));
if (obedit->type != OB_CURVE)
return OPERATOR_CANCELLED;