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.c219
1 files changed, 190 insertions, 29 deletions
diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c
index f7dab0c0935..9df611b3216 100644
--- a/source/blender/editors/curve/editcurve.c
+++ b/source/blender/editors/curve/editcurve.c
@@ -49,6 +49,7 @@
#include "BKE_fcurve.h"
#include "BKE_global.h"
#include "BKE_key.h"
+#include "BKE_library.h"
#include "BKE_main.h"
#include "BKE_report.h"
#include "BKE_animsys.h"
@@ -1177,7 +1178,7 @@ static void remap_hooks_and_vertex_parents(Object *obedit)
}
/* load editNurb in object */
-void load_editNurb(Object *obedit)
+void ED_curve_editnurb_load(Object *obedit)
{
ListBase *editnurb = object_editcurve_get(obedit);
@@ -1209,7 +1210,7 @@ void load_editNurb(Object *obedit)
}
/* make copy in cu->editnurb */
-void make_editNurb(Object *obedit)
+void ED_curve_editnurb_make(Object *obedit)
{
Curve *cu = (Curve *)obedit->data;
EditNurb *editnurb = cu->editnurb;
@@ -1252,7 +1253,7 @@ void make_editNurb(Object *obedit)
}
}
-void free_editNurb(Object *obedit)
+void ED_curve_editnurb_free(Object *obedit)
{
Curve *cu = obedit->data;
@@ -1298,10 +1299,10 @@ static int separate_exec(bContext *C, wmOperator *op)
newob = newbase->object;
newcu = newob->data = BKE_curve_copy(oldcu);
newcu->editnurb = NULL;
- oldcu->id.us--; /* because new curve is a copy: reduce user count */
+ id_us_min(&oldcu->id); /* because new curve is a copy: reduce user count */
/* 3. put new object in editmode, clear it and set separated nurbs */
- make_editNurb(newob);
+ ED_curve_editnurb_make(newob);
newedit = newcu->editnurb;
BKE_nurbList_free(&newedit->nurbs);
BKE_curve_editNurb_keyIndex_free(newedit);
@@ -1309,8 +1310,8 @@ static int separate_exec(bContext *C, wmOperator *op)
BLI_movelisttolist(&newedit->nurbs, &newnurb);
/* 4. put old object out of editmode and delete separated geometry */
- load_editNurb(newob);
- free_editNurb(newob);
+ ED_curve_editnurb_load(newob);
+ ED_curve_editnurb_free(newob);
curve_delete_segments(oldob, true);
DAG_id_tag_update(&oldob->id, OB_RECALC_DATA); /* this is the original one */
@@ -1351,7 +1352,11 @@ static int curve_split_exec(bContext *C, wmOperator *op)
adduplicateflagNurb(obedit, &newnurb, SELECT, true);
if (BLI_listbase_is_empty(&newnurb) == false) {
+ Curve *cu = obedit->data;
+ const int len_orig = BLI_listbase_count(editnurb);
+
curve_delete_segments(obedit, true);
+ cu->actnu -= len_orig - BLI_listbase_count(editnurb);
BLI_movelisttolist(editnurb, &newnurb);
if (ED_curve_updateAnimPaths(obedit->data))
@@ -1385,7 +1390,9 @@ void CURVE_OT_split(wmOperatorType *ot)
/* ******************* FLAGS ********************* */
-static short isNurbselUV(Nurb *nu, int *u, int *v, int flag)
+static bool isNurbselUV(
+ const Nurb *nu, int flag,
+ int *r_u, int *r_v)
{
/* return (u != -1): 1 row in u-direction selected. U has value between 0-pntsv
* return (v != -1): 1 column in v-direction selected. V has value between 0-pntsu
@@ -1393,7 +1400,7 @@ static short isNurbselUV(Nurb *nu, int *u, int *v, int flag)
BPoint *bp;
int a, b, sel;
- *u = *v = -1;
+ *r_u = *r_v = -1;
bp = nu->bp;
for (b = 0; b < nu->pntsv; b++) {
@@ -1402,7 +1409,7 @@ static short isNurbselUV(Nurb *nu, int *u, int *v, int flag)
if (bp->f1 & flag) sel++;
}
if (sel == nu->pntsu) {
- if (*u == -1) *u = b;
+ if (*r_u == -1) *r_u = b;
else return 0;
}
else if (sel > 1) {
@@ -1417,7 +1424,7 @@ static short isNurbselUV(Nurb *nu, int *u, int *v, int flag)
if (bp->f1 & flag) sel++;
}
if (sel == nu->pntsv) {
- if (*v == -1) *v = a;
+ if (*r_v == -1) *r_v = a;
else return 0;
}
else if (sel > 1) {
@@ -1425,8 +1432,8 @@ static short isNurbselUV(Nurb *nu, int *u, int *v, int flag)
}
}
- if (*u == -1 && *v > -1) return 1;
- if (*v == -1 && *u > -1) return 1;
+ if (*r_u == -1 && *r_v > -1) return 1;
+ if (*r_v == -1 && *r_u > -1) return 1;
return 0;
}
@@ -1846,7 +1853,7 @@ bool ed_editnurb_extrude_flag(EditNurb *editnurb, const short flag)
else {
/* which row or column is selected */
- if (isNurbselUV(nu, &u, &v, flag)) {
+ if (isNurbselUV(nu, flag, &u, &v)) {
/* deselect all */
bp = nu->bp;
@@ -1918,18 +1925,30 @@ bool ed_editnurb_extrude_flag(EditNurb *editnurb, const short flag)
return ok;
}
+static bool calc_duplicate_actvert(
+ const ListBase *editnurb, const ListBase *newnurb, Curve *cu,
+ int start, int end, int vert)
+{
+ if ((start <= cu->actvert) && (end > cu->actvert)) {
+ cu->actvert = vert;
+ cu->actnu = BLI_listbase_count(editnurb) + BLI_listbase_count(newnurb);
+ return true;
+ }
+ return false;
+}
+
static void adduplicateflagNurb(Object *obedit, ListBase *newnurb,
const short flag, const bool split)
{
ListBase *editnurb = object_editcurve_get(obedit);
- Nurb *nu = editnurb->last, *newnu;
+ Nurb *nu, *newnu;
BezTriple *bezt, *bezt1;
BPoint *bp, *bp1, *bp2, *bp3;
Curve *cu = (Curve *)obedit->data;
- int a, b, c, starta, enda, diffa, cyclicu, cyclicv, newu, newv;
+ int a, b, c, starta, enda, diffa, cyclicu, cyclicv, newu, newv, i;
char *usel;
- while (nu) {
+ for (i = 0, nu = editnurb->first; nu; i++, nu = nu->next) {
cyclicu = cyclicv = 0;
if (nu->type == CU_BEZIER) {
for (a = 0, bezt = nu->bezt; a < nu->pntsu; a++, bezt++) {
@@ -1950,12 +1969,21 @@ static void adduplicateflagNurb(Object *obedit, ListBase *newnurb,
}
else {
if (enda == nu->pntsu - 1) newu += cyclicu;
+ if (i == cu->actnu) {
+ calc_duplicate_actvert(
+ editnurb, newnurb, cu,
+ starta, starta + diffa, cu->actvert - starta);
+ }
newnu = BKE_nurb_copy(nu, newu, 1);
- BLI_addtail(newnurb, newnu);
memcpy(newnu->bezt, &nu->bezt[starta], diffa * sizeof(BezTriple));
if (newu != diffa) {
memcpy(&newnu->bezt[diffa], nu->bezt, cyclicu * sizeof(BezTriple));
+ if (i == cu->actnu) {
+ calc_duplicate_actvert(
+ editnurb, newnurb, cu,
+ 0, cyclicu, newu - cyclicu + cu->actvert);
+ }
cyclicu = 0;
}
@@ -1964,19 +1992,28 @@ static void adduplicateflagNurb(Object *obedit, ListBase *newnurb,
for (b = 0, bezt1 = newnu->bezt; b < newnu->pntsu; b++, bezt1++) {
select_beztriple(bezt1, SELECT, flag, HIDDEN);
}
+
+ BLI_addtail(newnurb, newnu);
}
}
}
if (cyclicu != 0) {
+ if (i == cu->actnu) {
+ calc_duplicate_actvert(
+ editnurb, newnurb, cu,
+ 0, cyclicu, cu->actvert);
+ }
+
newnu = BKE_nurb_copy(nu, cyclicu, 1);
- BLI_addtail(newnurb, newnu);
memcpy(newnu->bezt, nu->bezt, cyclicu * sizeof(BezTriple));
newnu->flagu &= ~CU_NURB_CYCLIC;
for (b = 0, bezt1 = newnu->bezt; b < newnu->pntsu; b++, bezt1++) {
select_beztriple(bezt1, SELECT, flag, HIDDEN);
}
+
+ BLI_addtail(newnurb, newnu);
}
}
else if (nu->pntsv == 1) { /* because UV Nurb has a different method for dupli */
@@ -1998,12 +2035,21 @@ static void adduplicateflagNurb(Object *obedit, ListBase *newnurb,
}
else {
if (enda == nu->pntsu - 1) newu += cyclicu;
+ if (i == cu->actnu) {
+ calc_duplicate_actvert(
+ editnurb, newnurb, cu,
+ starta, starta + diffa, cu->actvert - starta);
+ }
newnu = BKE_nurb_copy(nu, newu, 1);
- BLI_addtail(newnurb, newnu);
memcpy(newnu->bp, &nu->bp[starta], diffa * sizeof(BPoint));
if (newu != diffa) {
memcpy(&newnu->bp[diffa], nu->bp, cyclicu * sizeof(BPoint));
+ if (i == cu->actnu) {
+ calc_duplicate_actvert(
+ editnurb, newnurb, cu,
+ 0, cyclicu, newu - cyclicu + cu->actvert);
+ }
cyclicu = 0;
}
@@ -2012,19 +2058,28 @@ static void adduplicateflagNurb(Object *obedit, ListBase *newnurb,
for (b = 0, bp1 = newnu->bp; b < newnu->pntsu; b++, bp1++) {
select_bpoint(bp1, SELECT, flag, HIDDEN);
}
+
+ BLI_addtail(newnurb, newnu);
}
}
}
if (cyclicu != 0) {
+ if (i == cu->actnu) {
+ calc_duplicate_actvert(
+ editnurb, newnurb, cu,
+ 0, cyclicu, cu->actvert);
+ }
+
newnu = BKE_nurb_copy(nu, cyclicu, 1);
- BLI_addtail(newnurb, newnu);
memcpy(newnu->bp, nu->bp, cyclicu * sizeof(BPoint));
newnu->flagu &= ~CU_NURB_CYCLIC;
for (b = 0, bp1 = newnu->bp; b < newnu->pntsu; b++, bp1++) {
select_bpoint(bp1, SELECT, flag, HIDDEN);
}
+
+ BLI_addtail(newnurb, newnu);
}
}
else {
@@ -2100,6 +2155,28 @@ static void adduplicateflagNurb(Object *obedit, ListBase *newnurb,
memcpy(&newnu->bp[b * newnu->pntsu], &nu->bp[b * nu->pntsu + a], newu * sizeof(BPoint));
memcpy(&newnu->bp[b * newnu->pntsu + newu], &nu->bp[b * nu->pntsu], cyclicu * sizeof(BPoint));
}
+
+ if (cu->actnu == i) {
+ for (b = 0, diffa = 0; b < newv; b++, diffa += nu->pntsu - newu) {
+ starta = b * nu->pntsu + a;
+ if (calc_duplicate_actvert(
+ editnurb, newnurb, cu,
+ cu->actvert, starta,
+ cu->actvert % nu->pntsu + newu + b * newnu->pntsu))
+ {
+ /* actvert in cyclicu selection */
+ break;
+ }
+ else if (calc_duplicate_actvert(
+ editnurb, newnurb, cu,
+ starta, starta + newu,
+ cu->actvert - starta + b * newnu->pntsu))
+ {
+ /* actvert in 'current' iteration selection */
+ break;
+ }
+ }
+ }
cyclicu = cyclicv = 0;
}
else if ((a / nu->pntsu) + newv == nu->pntsv && cyclicv != 0) {
@@ -2107,6 +2184,14 @@ static void adduplicateflagNurb(Object *obedit, ListBase *newnurb,
newnu = BKE_nurb_copy(nu, newu, newv + cyclicv);
memcpy(newnu->bp, &nu->bp[a], newu * newv * sizeof(BPoint));
memcpy(&newnu->bp[newu * newv], nu->bp, newu * cyclicv * sizeof(BPoint));
+
+ /* check for actvert in cylicv selection */
+ if (cu->actnu == i) {
+ calc_duplicate_actvert(
+ editnurb, newnurb, cu,
+ cu->actvert, a,
+ (newu * newv) + cu->actvert);
+ }
cyclicu = cyclicv = 0;
}
else {
@@ -2115,6 +2200,20 @@ static void adduplicateflagNurb(Object *obedit, ListBase *newnurb,
memcpy(&newnu->bp[b * newu], &nu->bp[b * nu->pntsu + a], newu * sizeof(BPoint));
}
}
+
+ /* general case if not handled by cyclicu or cyclicv */
+ if (cu->actnu == i) {
+ for (b = 0, diffa = 0; b < newv; b++, diffa += nu->pntsu - newu) {
+ starta = b * nu->pntsu + a;
+ if (calc_duplicate_actvert(
+ editnurb, newnurb, cu,
+ starta, starta + newu,
+ cu->actvert - (a / nu->pntsu * nu->pntsu + diffa + (starta % nu->pntsu))))
+ {
+ break;
+ }
+ }
+ }
BLI_addtail(newnurb, newnu);
if (newu != nu->pntsu) newnu->flagu &= ~CU_NURB_CYCLIC;
@@ -2131,6 +2230,20 @@ static void adduplicateflagNurb(Object *obedit, ListBase *newnurb,
for (b = 0; b < newv; b++) {
memcpy(&newnu->bp[b * newu], &nu->bp[b * nu->pntsu], newu * sizeof(BPoint));
}
+
+ /* check for actvert in the unused cyclicuv selection */
+ if (cu->actnu == i) {
+ for (b = 0, diffa = 0; b < newv; b++, diffa += nu->pntsu - newu) {
+ starta = b * nu->pntsu;
+ if (calc_duplicate_actvert(
+ editnurb, newnurb, cu,
+ starta, starta + newu,
+ cu->actvert - (diffa + (starta % nu->pntsu))))
+ {
+ break;
+ }
+ }
+ }
BLI_addtail(newnurb, newnu);
if (newu != nu->pntsu) newnu->flagu &= ~CU_NURB_CYCLIC;
@@ -2144,12 +2257,9 @@ static void adduplicateflagNurb(Object *obedit, ListBase *newnurb,
}
}
}
- nu = nu->prev;
}
if (BLI_listbase_is_empty(newnurb) == false) {
- cu->actnu = cu->actvert = CU_ACT_NONE;
-
for (nu = newnurb->first; nu; nu = nu->next) {
if (nu->type == CU_BEZIER) {
if (split) {
@@ -4163,7 +4273,7 @@ void CURVE_OT_make_segment(wmOperatorType *ot)
/***************** pick select from 3d view **********************/
-bool mouse_nurb(bContext *C, const int mval[2], bool extend, bool deselect, bool toggle)
+bool ED_curve_editnurb_select_pick(bContext *C, const int mval[2], bool extend, bool deselect, bool toggle)
{
Object *obedit = CTX_data_edit_object(C);
Curve *cu = obedit->data;
@@ -4659,7 +4769,7 @@ static bool ed_editcurve_extrude(Curve *cu, EditNurb *editnurb)
/***************** add vertex operator **********************/
-static int ed_editcurve_addvert(Curve *cu, EditNurb *editnurb, const float location[3])
+static int ed_editcurve_addvert(Curve *cu, EditNurb *editnurb, const float location_init[3])
{
Nurb *nu;
@@ -4700,7 +4810,7 @@ static int ed_editcurve_addvert(Curve *cu, EditNurb *editnurb, const float locat
int i;
mid_v3_v3v3(center, minmax[0], minmax[1]);
- sub_v3_v3v3(ofs, location, center);
+ sub_v3_v3v3(ofs, location_init, center);
if ((cu->flag & CU_3D) == 0) {
ofs[2] = 0.0f;
@@ -4722,6 +4832,8 @@ static int ed_editcurve_addvert(Curve *cu, EditNurb *editnurb, const float locat
}
}
}
+
+ BKE_nurb_handles_calc(nu);
}
else {
BPoint *bp;
@@ -4736,6 +4848,14 @@ static int ed_editcurve_addvert(Curve *cu, EditNurb *editnurb, const float locat
changed = true;
}
else {
+ float location[3];
+
+ copy_v3_v3(location, location_init);
+
+ if ((cu->flag & CU_3D) == 0) {
+ location[2] = 0.0f;
+ }
+
/* nothing selected: create a new curve */
nu = BKE_curve_nurb_active_get(cu);
@@ -4753,6 +4873,10 @@ static int ed_editcurve_addvert(Curve *cu, EditNurb *editnurb, const float locat
nurb_new->orderu = 4;
nurb_new->flag |= CU_SMOOTH;
BKE_nurb_bezierPoints_add(nurb_new, 1);
+
+ if ((cu->flag & CU_3D) == 0) {
+ nurb_new->flag |= CU_2D;
+ }
}
BLI_addtail(&editnurb->nurbs, nurb_new);
@@ -4784,6 +4908,10 @@ static int ed_editcurve_addvert(Curve *cu, EditNurb *editnurb, const float locat
nurb_new->flag |= CU_SMOOTH;
nurb_new->orderu = 4;
BKE_nurb_points_add(nurb_new, 1);
+
+ if ((cu->flag & CU_3D) == 0) {
+ nurb_new->flag |= CU_2D;
+ }
}
BLI_addtail(&editnurb->nurbs, nurb_new);
@@ -4867,7 +4995,40 @@ static int add_vertex_invoke(bContext *C, wmOperator *op, const wmEvent *event)
const float mval[2] = {UNPACK2(event->mval)};
float no_dummy[3];
float dist_px_dummy;
- snapObjectsContext(C, mval, &dist_px_dummy, location, no_dummy, SNAP_NOT_OBEDIT);
+ snapObjectsContext(
+ C, mval, SNAP_NOT_OBEDIT,
+ location, no_dummy, &dist_px_dummy);
+ }
+
+ if ((cu->flag & CU_3D) == 0) {
+ const float eps = 1e-6f;
+
+ /* get the view vector to 'location' */
+ float view_dir[3];
+ ED_view3d_global_to_vector(vc.rv3d, location, view_dir);
+
+ /* get the plane */
+ float plane[4];
+ /* only normalize to avoid precision errors */
+ normalize_v3_v3(plane, vc.obedit->obmat[2]);
+ plane[3] = -dot_v3v3(plane, vc.obedit->obmat[3]);
+
+ if (fabsf(dot_v3v3(view_dir, plane)) < eps) {
+ /* can't project on an aligned plane. */
+ }
+ else {
+ float lambda;
+ if (isect_ray_plane_v3(location, view_dir, plane, &lambda, false)) {
+ /* check if we're behind the viewport */
+ float location_test[3];
+ madd_v3_v3v3fl(location_test, location, view_dir, lambda);
+ if ((vc.rv3d->is_persp == false) ||
+ (mul_project_m4_v3_zfac(vc.rv3d->persmat, location_test) > 0.0f))
+ {
+ copy_v3_v3(location, location_test);
+ }
+ }
+ }
}
RNA_float_set_array(op->ptr, "location", location);
@@ -4953,7 +5114,7 @@ void CURVE_OT_extrude(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* to give to transform */
- RNA_def_enum(ot->srna, "mode", transform_mode_types, TFM_TRANSLATION, "Mode", "");
+ RNA_def_enum(ot->srna, "mode", rna_enum_transform_mode_types, TFM_TRANSLATION, "Mode", "");
}
/***************** make cyclic operator **********************/