Highlight last selected point in curve/surface edit mode.

Curve->lastselbp field was renamed to Curve->lastsel and now not last
either BPoint or BezTriple is storing here. It's not easy to determine
type of selected point, but operator which depends on such point reviews
the full nurbs, so this shouldn't be a problem.

Made changes to curve undo stuff to restore last selected point on undo/redo.

Added new theme color for curve last selected point.
This commit is contained in:
2010-04-30 04:48:40 +00:00
parent 53dbc1efdf
commit 16e7ed28be
10 changed files with 194 additions and 71 deletions

View File

@@ -612,6 +612,7 @@ class USERPREF_PT_theme(bpy.types.Panel):
col.prop(v3d, "handle_sel_vect")
col.prop(v3d, "handle_sel_align")
col.prop(v3d, "act_spline")
col.prop(v3d, "lastsel_point")
col = split.column()
col.prop(v3d, "vertex")

View File

@@ -2754,7 +2754,7 @@ static void direct_link_curve(FileData *fd, Curve *cu)
cu->bev.first=cu->bev.last= NULL;
cu->disp.first=cu->disp.last= NULL;
cu->editnurb= NULL;
cu->lastselbp= NULL;
cu->lastsel= NULL;
cu->path= NULL;
cu->editfont= NULL;

View File

@@ -75,6 +75,12 @@
#include "RNA_access.h"
#include "RNA_define.h"
/* Undo stuff */
typedef struct {
ListBase nubase;
void *lastsel;
} UndoCurve;
void selectend_nurb(Object *obedit, short selfirst, short doswap, short selstatus);
static void select_adjacent_cp(ListBase *editnurb, short next, short cont, short selstatus);
@@ -324,7 +330,7 @@ void make_editNurb(Object *obedit)
editnurb= cu->editnurb= MEM_callocN(sizeof(ListBase), "editnurb");
nu= cu->nurb.first;
cu->lastselbp= NULL; /* for select row */
cu->lastsel= NULL; /* for select row */
while(nu) {
newnu= duplicateNurb(nu);
@@ -389,6 +395,8 @@ void CU_select_swap(Object *obedit)
BezTriple *bezt;
int a;
cu->lastsel= NULL;
for(nu= editnurb->first; nu; nu= nu->next) {
if(nu->type == CU_BEZIER) {
bezt= nu->bezt;
@@ -654,7 +662,7 @@ static int deleteflagNurb(bContext *C, wmOperator *op, int flag)
if(obedit && obedit->type==OB_SURF);
else return OPERATOR_CANCELLED;
cu->lastselbp= NULL;
cu->lastsel= NULL;
nu= editnurb->first;
while(nu) {
@@ -887,9 +895,12 @@ static void adduplicateflagNurb(Object *obedit, short flag)
Nurb *nu, *newnu;
BezTriple *bezt, *bezt1;
BPoint *bp, *bp1;
Curve *cu= (Curve*)obedit->data;
int a, b, starta, enda, newu, newv;
char *usel;
cu->lastsel= NULL;
nu= editnurb->last;
while(nu) {
if(nu->type == CU_BEZIER) {
@@ -1499,11 +1510,15 @@ void selectend_nurb(Object *obedit, short selfirst, short doswap, short selstatu
Nurb *nu;
BPoint *bp;
BezTriple *bezt;
Curve *cu;
int a;
short sel;
if(obedit==0) return;
cu= (Curve*)obedit->data;
cu->lastsel= NULL;
for(nu= editnurb->first; nu; nu= nu->next) {
sel= 0;
if(nu->type == CU_BEZIER) {
@@ -1819,6 +1834,8 @@ static int select_inverse_exec(bContext *C, wmOperator *op)
BezTriple *bezt;
int a;
cu->lastsel= NULL;
for(nu= editnurb->first; nu; nu= nu->next) {
if(nu->type == CU_BEZIER) {
bezt= nu->bezt;
@@ -3183,12 +3200,18 @@ int mouse_nurb(bContext *C, short mval[2], int extend)
if(bezt) {
if(hand==1) select_beztriple(bezt, SELECT, 1, HIDDEN);
else if(hand==0) bezt->f1|= SELECT;
else bezt->f3|= SELECT;
if(hand==1) {
select_beztriple(bezt, SELECT, 1, HIDDEN);
cu->lastsel= bezt;
} else {
if(hand==0) bezt->f1|= SELECT;
else bezt->f3|= SELECT;
cu->lastsel= NULL;
}
}
else {
cu->lastselbp= bp;
cu->lastsel= bp;
select_bpoint(bp, SELECT, 1, HIDDEN);
}
@@ -3196,8 +3219,13 @@ int mouse_nurb(bContext *C, short mval[2], int extend)
else {
if(bezt) {
if(hand==1) {
if(bezt->f2 & SELECT) select_beztriple(bezt, DESELECT, 1, HIDDEN);
else select_beztriple(bezt, SELECT, 1, HIDDEN);
if(bezt->f2 & SELECT) {
select_beztriple(bezt, DESELECT, 1, HIDDEN);
if (bezt == cu->lastsel) cu->lastsel = NULL;
} else {
select_beztriple(bezt, SELECT, 1, HIDDEN);
cu->lastsel= bezt;
}
} else if(hand==0) {
bezt->f1 ^= SELECT;
} else {
@@ -3205,10 +3233,12 @@ int mouse_nurb(bContext *C, short mval[2], int extend)
}
}
else {
if(bp->f1 & SELECT) select_bpoint(bp, DESELECT, 1, HIDDEN);
else {
if(bp->f1 & SELECT) {
select_bpoint(bp, DESELECT, 1, HIDDEN);
if (cu->lastsel == bp) cu->lastsel = NULL;
} else {
select_bpoint(bp, SELECT, 1, HIDDEN);
cu->lastselbp= bp;
cu->lastsel= bp;
}
}
@@ -3813,7 +3843,7 @@ static int select_row_exec(bContext *C, wmOperator *op)
if(editnurb->first==0)
return OPERATOR_CANCELLED;
if(cu->lastselbp==NULL)
if(cu->lastsel==NULL)
return OPERATOR_CANCELLED;
/* find the correct nurb and toggle with u of v */
@@ -3821,7 +3851,7 @@ static int select_row_exec(bContext *C, wmOperator *op)
bp= nu->bp;
for(v=0; v<nu->pntsv; v++) {
for(u=0; u<nu->pntsu; u++, bp++) {
if(bp==cu->lastselbp) {
if(bp==cu->lastsel) {
if(bp->f1 & SELECT) {
ok= 1;
break;
@@ -3832,11 +3862,11 @@ static int select_row_exec(bContext *C, wmOperator *op)
}
if(ok) {
if(last==cu->lastselbp) {
if(last==cu->lastsel) {
direction= 1-direction;
setflagsNurb(editnurb, 0);
}
last= cu->lastselbp;
last= cu->lastsel;
bp= nu->bp;
for(a=0; a<nu->pntsv; a++) {
@@ -5190,49 +5220,87 @@ void CURVE_OT_tilt_clear(wmOperatorType *ot)
/****************** undo for curves ****************/
static void undoCurve_to_editCurve(void *lbu, void *lbe)
static void *undo_check_lastsel(void *lastsel, Nurb *nu, Nurb *newnu)
{
ListBase *lb= lbu;
ListBase *editnurb= lbe;
Nurb *nu, *newnu;
freeNurblist(editnurb);
/* copy */
for(nu= lb->first; nu; nu= nu->next) {
newnu= duplicateNurb(nu);
BLI_addtail(editnurb, newnu);
if (nu->bezt) {
BezTriple *lastbezt= (BezTriple*)lastsel;
if (lastbezt >= nu->bezt && lastbezt < nu->bezt + nu->pntsu) {
return newnu->bezt + (lastbezt - nu->bezt);
}
} else {
BPoint *lastbp= (BPoint*)lastsel;
if (lastbp >= nu->bp && lastbp < nu->bp + nu->pntsu*nu->pntsv) {
return newnu->bp + (lastbp - nu->bp);
}
}
return NULL;
}
static void *editCurve_to_undoCurve(void *lbe)
static void undoCurve_to_editCurve(void *ucu, void *cue)
{
ListBase *editnurb= lbe;
ListBase *lb;
Curve *cu= cue;
UndoCurve *undoCurve= ucu;
ListBase *undobase= &undoCurve->nubase;
ListBase *editbase= cu->editnurb;
Nurb *nu, *newnu;
void *lastsel= NULL;
freeNurblist(editbase);
lb= MEM_callocN(sizeof(ListBase), "listbase undo");
/* copy */
for(nu= editnurb->first; nu; nu= nu->next) {
for(nu= undobase->first; nu; nu= nu->next) {
newnu= duplicateNurb(nu);
BLI_addtail(lb, newnu);
if (lastsel == NULL) {
lastsel= undo_check_lastsel(undoCurve->lastsel, nu, newnu);
}
BLI_addtail(editbase, newnu);
}
return lb;
cu->lastsel= lastsel;
}
static void free_undoCurve(void *lbv)
static void *editCurve_to_undoCurve(void *cue)
{
ListBase *lb= lbv;
freeNurblist(lb);
MEM_freeN(lb);
Curve *cu= cue;
ListBase *nubase= cu->editnurb;
UndoCurve *undoCurve;
Nurb *nu, *newnu;
void *lastsel= NULL;
undoCurve= MEM_callocN(sizeof(UndoCurve), "undoCurve");
/* copy */
for(nu= nubase->first; nu; nu= nu->next) {
newnu= duplicateNurb(nu);
if (lastsel == NULL) {
lastsel= undo_check_lastsel(cu->lastsel, nu, newnu);
}
BLI_addtail(&undoCurve->nubase, newnu);
}
undoCurve->lastsel= lastsel;
return undoCurve;
}
static void free_undoCurve(void *ucv)
{
UndoCurve *undoCurve= ucv;
freeNurblist(&undoCurve->nubase);
MEM_freeN(undoCurve);
}
static void *get_data(bContext *C)
{
Object *obedit= CTX_data_edit_object(C);
return curve_get_editcurve(obedit);
return obedit->data;
}
/* and this is all the undo system needs to know */

View File

@@ -180,6 +180,7 @@ enum {
TH_HANDLE_SEL_ALIGN,
TH_ACTIVE_SPLINE,
TH_LASTSEL_POINT,
TH_SYNTAX_B,
TH_SYNTAX_V,

View File

@@ -309,6 +309,8 @@ char *UI_ThemeGetColorPtr(bTheme *btheme, int spacetype, int colorid)
cp= ts->nurb_sel_vline; break;
case TH_ACTIVE_SPLINE:
cp= ts->act_spline; break;
case TH_LASTSEL_POINT:
cp= ts->lastsel_point; break;
case TH_HANDLE_FREE:
cp= ts->handle_free; break;
case TH_HANDLE_AUTO:
@@ -530,6 +532,7 @@ void ui_theme_init_default(void)
SETCOL(btheme->tv3d.handle_sel_align, 0xf0, 0x90, 0xa0, 255);
SETCOL(btheme->tv3d.act_spline, 0xdb, 0x25, 0x12, 255);
SETCOL(btheme->tv3d.lastsel_point, 0xff, 0xff, 0xff, 255);
SETCOL(btheme->tv3d.bone_solid, 200, 200, 200, 255);
SETCOL(btheme->tv3d.bone_pose, 80, 200, 255, 80); // alpha 80 is not meant editable, used for wire+action draw
@@ -1451,7 +1454,15 @@ void init_userdef_do_versions(void)
SETCOLF(btheme->tv3d.edge_crease, 0.8, 0, 0.6, 1.0);
}
}
if (G.main->versionfile <= 252) {
bTheme *btheme;
/* init new curve colors */
for(btheme= U.themes.first; btheme; btheme= btheme->next) {
if (btheme->tv3d.lastsel_point[3] == 0)
SETCOL(btheme->tv3d.lastsel_point, 0xff, 0xff, 0xff, 255);
}
}
/* GL Texture Garbage Collection (variable abused above!) */
if (U.textimeout == 0) {

View File

@@ -4405,17 +4405,19 @@ static void tekenhandlesN_active(Nurb *nu)
glLineWidth(1);
}
static void tekenvertsN(Nurb *nu, short sel, short hide_handles)
static void tekenvertsN(Nurb *nu, short sel, short hide_handles, void *lastsel)
{
BezTriple *bezt;
BPoint *bp;
float size;
int a;
int a, color;
if(nu->hide) return;
if(sel) UI_ThemeColor(TH_VERTEX_SELECT);
else UI_ThemeColor(TH_VERTEX);
if(sel) color= TH_VERTEX_SELECT;
else color= TH_VERTEX;
UI_ThemeColor(color);
size= UI_GetThemeValuef(TH_VERTEX_SIZE);
glPointSize(size);
@@ -4428,7 +4430,17 @@ static void tekenvertsN(Nurb *nu, short sel, short hide_handles)
a= nu->pntsu;
while(a--) {
if(bezt->hide==0) {
if (hide_handles) {
if (bezt == lastsel) {
UI_ThemeColor(TH_LASTSEL_POINT);
bglVertex3fv(bezt->vec[1]);
if (!hide_handles) {
bglVertex3fv(bezt->vec[0]);
bglVertex3fv(bezt->vec[2]);
}
UI_ThemeColor(color);
} else if (hide_handles) {
if((bezt->f2 & SELECT)==sel) bglVertex3fv(bezt->vec[1]);
} else {
if((bezt->f1 & SELECT)==sel) bglVertex3fv(bezt->vec[0]);
@@ -4444,7 +4456,13 @@ static void tekenvertsN(Nurb *nu, short sel, short hide_handles)
a= nu->pntsu*nu->pntsv;
while(a--) {
if(bp->hide==0) {
if((bp->f1 & SELECT)==sel) bglVertex3fv(bp->vec);
if (bp == lastsel) {
UI_ThemeColor(TH_LASTSEL_POINT);
bglVertex3fv(bp->vec);
UI_ThemeColor(color);
} else {
if((bp->f1 & SELECT)==sel) bglVertex3fv(bp->vec);
}
}
bp++;
}
@@ -4669,7 +4687,7 @@ static void drawnurb(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base,
for(nu=nurb; nu; nu=nu->next) {
if(nu->type == CU_BEZIER && (cu->drawflag & CU_HIDE_HANDLES)==0)
tekenhandlesN(nu, 1, hide_handles);
tekenvertsN(nu, 0, hide_handles);
tekenvertsN(nu, 0, hide_handles, NULL);
}
if(v3d->zbuf) glEnable(GL_DEPTH_TEST);
@@ -4712,7 +4730,7 @@ static void drawnurb(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base,
if(v3d->zbuf) glDisable(GL_DEPTH_TEST);
for(nu=nurb; nu; nu=nu->next) {
tekenvertsN(nu, 1, hide_handles);
tekenvertsN(nu, 1, hide_handles, cu->lastsel);
}
if(v3d->zbuf) glEnable(GL_DEPTH_TEST);

View File

@@ -554,14 +554,15 @@ static void do_lasso_select_mesh_uv(short mcords[][2], short moves, short select
static void do_lasso_select_curve__doSelect(void *userData, Nurb *nu, BPoint *bp, BezTriple *bezt, int beztindex, int x, int y)
{
struct { ViewContext vc; short (*mcords)[2]; short moves; short select; } *data = userData;
struct { ViewContext *vc; short (*mcords)[2]; short moves; short select; } *data = userData;
Object *obedit= data->vc->obedit;
Curve *cu= (Curve*)obedit->data;
if (lasso_inside(data->mcords, data->moves, x, y)) {
if (bp) {
bp->f1 = data->select?(bp->f1|SELECT):(bp->f1&~SELECT);
if (bp == cu->lastsel && !(bp->f1 & 1)) cu->lastsel = NULL;
} else {
Curve *cu= data->vc.obedit->data;
if (cu->drawflag & CU_HIDE_HANDLES) {
/* can only be beztindex==0 here since handles are hidden */
bezt->f1 = bezt->f2 = bezt->f3 = data->select?(bezt->f2|SELECT):(bezt->f2&~SELECT);
@@ -574,16 +575,18 @@ static void do_lasso_select_curve__doSelect(void *userData, Nurb *nu, BPoint *bp
bezt->f3 = data->select?(bezt->f3|SELECT):(bezt->f3&~SELECT);
}
}
if (bezt == cu->lastsel && !(bezt->f2 & 1)) cu->lastsel = NULL;
}
}
}
static void do_lasso_select_curve(ViewContext *vc, short mcords[][2], short moves, short select)
{
struct { ViewContext vc; short (*mcords)[2]; short moves; short select; } data;
struct { ViewContext *vc; short (*mcords)[2]; short moves; short select; } data;
/* set vc->editnurb */
data.vc = *vc;
data.vc = vc;
data.mcords = mcords;
data.moves = moves;
data.select = select;
@@ -1274,14 +1277,15 @@ int edge_inside_circle(short centx, short centy, short rad, short x1, short y1,
static void do_nurbs_box_select__doSelect(void *userData, Nurb *nu, BPoint *bp, BezTriple *bezt, int beztindex, int x, int y)
{
struct { ViewContext vc; rcti *rect; int select; } *data = userData;
struct { ViewContext *vc; rcti *rect; int select; } *data = userData;
Object *obedit= data->vc->obedit;
Curve *cu= (Curve*)obedit->data;
if (BLI_in_rcti(data->rect, x, y)) {
if (bp) {
bp->f1 = data->select?(bp->f1|SELECT):(bp->f1&~SELECT);
if (bp == cu->lastsel && !(bp->f1 & 1)) cu->lastsel = NULL;
} else {
Curve *cu= data->vc.obedit->data;
if (cu->drawflag & CU_HIDE_HANDLES) {
/* can only be beztindex==0 here since handles are hidden */
bezt->f1 = bezt->f2 = bezt->f3 = data->select?(bezt->f2|SELECT):(bezt->f2&~SELECT);
@@ -1294,14 +1298,16 @@ static void do_nurbs_box_select__doSelect(void *userData, Nurb *nu, BPoint *bp,
bezt->f3 = data->select?(bezt->f3|SELECT):(bezt->f3&~SELECT);
}
}
if (bezt == cu->lastsel && !(bezt->f2 & 1)) cu->lastsel = NULL;
}
}
}
static void do_nurbs_box_select(ViewContext *vc, rcti *rect, int select, int extend)
{
struct { ViewContext vc; rcti *rect; int select; } data;
struct { ViewContext *vc; rcti *rect; int select; } data;
data.vc = *vc;
data.vc = vc;
data.rect = rect;
data.select = select;
@@ -1871,18 +1877,29 @@ static void nurbscurve_circle_doSelect(void *userData, Nurb *nu, BPoint *bp, Bez
struct {ViewContext *vc; short select, mval[2]; float radius; } *data = userData;
int mx = x - data->mval[0], my = y - data->mval[1];
float r = sqrt(mx*mx + my*my);
Object *obedit= data->vc->obedit;
Curve *cu= (Curve*)obedit->data;
if (r<=data->radius) {
if (bp) {
bp->f1 = data->select?(bp->f1|SELECT):(bp->f1&~SELECT);
if (bp == cu->lastsel && !(bp->f1 & 1)) cu->lastsel = NULL;
} else {
if (beztindex==0) {
bezt->f1 = data->select?(bezt->f1|SELECT):(bezt->f1&~SELECT);
} else if (beztindex==1) {
bezt->f2 = data->select?(bezt->f2|SELECT):(bezt->f2&~SELECT);
if (cu->drawflag & CU_HIDE_HANDLES) {
/* can only be beztindex==0 here since handles are hidden */
bezt->f1 = bezt->f2 = bezt->f3 = data->select?(bezt->f2|SELECT):(bezt->f2&~SELECT);
} else {
bezt->f3 = data->select?(bezt->f3|SELECT):(bezt->f3&~SELECT);
if (beztindex==0) {
bezt->f1 = data->select?(bezt->f1|SELECT):(bezt->f1&~SELECT);
} else if (beztindex==1) {
bezt->f2 = data->select?(bezt->f2|SELECT):(bezt->f2&~SELECT);
} else {
bezt->f3 = data->select?(bezt->f3|SELECT):(bezt->f3&~SELECT);
}
}
if (bezt == cu->lastsel && !(bezt->f2 & 1)) cu->lastsel = NULL;
}
}
}
@@ -1896,6 +1913,7 @@ static void nurbscurve_circle_select(ViewContext *vc, int selecting, short *mval
data.mval[0] = mval[0];
data.mval[1] = mval[1];
data.radius = rad;
data.vc = vc;
ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* for foreach's screen/vert projection */
nurbs_foreachScreenVert(vc, nurbscurve_circle_doSelect, &data);

View File

@@ -189,8 +189,8 @@ typedef struct Curve {
/* edit, index in nurb list */
int actnu;
/* edit, last selected bpoint */
BPoint *lastselbp;
/* edit, last selected point */
void *lastsel;
/* font part */
short len, lines, pos, spacemode;

View File

@@ -201,7 +201,7 @@ typedef struct ThemeSpace {
char strip[4], strip_select[4];
char cframe[4];
char nurb_uline[4], nurb_vline[4];
char act_spline[4], nurb_sel_uline[4], nurb_sel_vline[4];
char act_spline[4], nurb_sel_uline[4], nurb_sel_vline[4], lastsel_point[4];
char handle_free[4], handle_auto[4], handle_vect[4], handle_align[4];
char handle_sel_free[4], handle_sel_auto[4], handle_sel_vect[4], handle_sel_align[4];
char ds_channel[4], ds_subchannel[4]; // dopesheet
@@ -223,7 +223,7 @@ typedef struct ThemeSpace {
char handle_vertex_select[4];
char handle_vertex_size;
char hpad[3];
char hpad[7];
char preview_back[4];

View File

@@ -791,6 +791,12 @@ static void rna_def_userdef_theme_spaces_curves(StructRNA *srna, short incl_nurb
RNA_def_property_array(prop, 3);
RNA_def_property_ui_text(prop, "Align handle selected color", "");
RNA_def_property_update(prop, 0, "rna_userdef_update");
prop= RNA_def_property(srna, "lastsel_point", PROP_FLOAT, PROP_COLOR);
RNA_def_property_float_sdna(prop, NULL, "lastsel_point");
RNA_def_property_array(prop, 3);
RNA_def_property_ui_text(prop, "Last selected point", "");
RNA_def_property_update(prop, 0, "rna_userdef_update");
}
static void rna_def_userdef_theme_space_view3d(BlenderRNA *brna)