2.5: Particle edit mode more functional now. Transform, brush

editing, paint cursor, radial control, mouse/border/circle/lasso
select, mirroring, bad level calls fixed, etc.
This commit is contained in:
2009-02-25 19:29:58 +00:00
parent c3078c94fb
commit 9ac7c8e91a
16 changed files with 537 additions and 427 deletions

View File

@@ -139,15 +139,20 @@ typedef struct ParticleUndo {
char name[64];
} ParticleUndo;
typedef struct ParticleEdit{
typedef struct ParticleEdit {
ListBase undo;
struct ParticleUndo *curundo;
struct KDTree *emitter_field;
ParticleEditKey **keys;
int totkeys;
int *mirror_cache;
struct KDTree *emitter_field;
float *emitter_cosnos;
int totkeys;
char sel_col[3];
char nosel_col[3];
} ParticleEdit;
typedef struct ParticleThreadContext {
@@ -244,6 +249,7 @@ void psys_find_parents(struct Object *ob, struct ParticleSystemModifierData *psm
void psys_cache_paths(struct Scene *scene, struct Object *ob, struct ParticleSystem *psys, float cfra, int editupdate);
void psys_cache_child_paths(struct Scene *scene, struct Object *ob, struct ParticleSystem *psys, float cfra, int editupdate);
void psys_update_world_cos(struct Object *ob, struct ParticleSystem *psys);
int do_guide(struct Scene *scene, struct ParticleKey *state, int pa_num, float time, struct ListBase *lb);
float psys_get_size(struct Object *ob, struct Material *ma, struct ParticleSystemModifierData *psmd, struct IpoCurve *icu_size, struct ParticleSystem *psys, struct ParticleSettings *part, struct ParticleData *pa, float *vg_size);
float psys_get_timestep(struct ParticleSettings *part);

View File

@@ -391,7 +391,8 @@ void psys_free(Object *ob, ParticleSystem * psys)
free_keyed_keys(psys);
//XXX PE_free_particle_edit(psys);
if(psys->edit && psys->free_edit)
psys->free_edit(psys);
if(psys->particles){
MEM_freeN(psys->particles);
@@ -2338,7 +2339,6 @@ void psys_cache_paths(Scene *scene, Object *ob, ParticleSystem *psys, float cfra
int k,i;
int steps = (int)pow(2.0, (double)psys->part->draw_step);
int totpart = psys->totpart;
char nosel[4], sel[4];
float sel_col[3];
float nosel_col[3];
float length, vec[3];
@@ -2350,25 +2350,25 @@ void psys_cache_paths(Scene *scene, Object *ob, ParticleSystem *psys, float cfra
if((psys->flag & PSYS_HAIR_DONE)==0 && (psys->flag & PSYS_KEYED)==0)
return;
if(psys->renderdata)
if(psys->renderdata) {
steps = (int)pow(2.0, (double)psys->part->ren_step);
else if(psys_in_edit_mode(scene, psys)){
}
else if(psys_in_edit_mode(scene, psys)) {
edit=psys->edit;
//timed = edit->draw_timed;
//XXX PE_get_colors(sel,nosel);
if(pset->brushtype == PE_BRUSH_WEIGHT){
if(pset->brushtype == PE_BRUSH_WEIGHT) {
sel_col[0] = sel_col[1] = sel_col[2] = 1.0f;
nosel_col[0] = nosel_col[1] = nosel_col[2] = 0.0f;
}
else{
sel_col[0] = (float)sel[0] / 255.0f;
sel_col[1] = (float)sel[1] / 255.0f;
sel_col[2] = (float)sel[2] / 255.0f;
nosel_col[0] = (float)nosel[0] / 255.0f;
nosel_col[1] = (float)nosel[1] / 255.0f;
nosel_col[2] = (float)nosel[2] / 255.0f;
sel_col[0] = (float)edit->sel_col[0] / 255.0f;
sel_col[1] = (float)edit->sel_col[1] / 255.0f;
sel_col[2] = (float)edit->sel_col[2] / 255.0f;
nosel_col[0] = (float)edit->nosel_col[0] / 255.0f;
nosel_col[1] = (float)edit->nosel_col[1] / 255.0f;
nosel_col[2] = (float)edit->nosel_col[2] / 255.0f;
}
}

View File

@@ -4174,6 +4174,30 @@ static void psys_update_path_cache(Scene *scene, Object *ob, ParticleSystemModif
psys_free_path_cache(psys);
}
/* calculate and store key locations in world coordinates */
void psys_update_world_cos(Object *ob, ParticleSystem *psys)
{
ParticleSystemModifierData *psmd= psys_get_modifier(ob, psys);
ParticleData *pa;
ParticleEditKey *key;
int i, k, totpart;
float hairmat[4][4];
if(psys==0 || psys->edit==0)
return;
totpart= psys->totpart;
for(i=0, pa=psys->particles; i<totpart; i++, pa++) {
psys_mat_hair_to_global(ob, psmd->dm, psys->part->from, pa, hairmat);
for(k=0, key=psys->edit->keys[i]; k<pa->totkey; k++, key++) {
VECCOPY(key->world_co,key->co);
Mat4MulVecfl(hairmat, key->world_co);
}
}
}
static void hair_step(Scene *scene, Object *ob, ParticleSystemModifierData *psmd, ParticleSystem *psys, float cfra)
{
ParticleSettings *part = psys->part;
@@ -4200,7 +4224,7 @@ static void hair_step(Scene *scene, Object *ob, ParticleSystemModifierData *psmd
precalc_effectors(scene, ob,psys,psmd,cfra);
if(psys_in_edit_mode(scene, psys))
; //XXX PE_recalc_world_cos(ob, psys);
psys_update_world_cos(ob, psys);
psys_update_path_cache(scene, ob,psmd,psys,cfra);
}

View File

@@ -2941,6 +2941,7 @@ static void direct_link_particlesystems(FileData *fd, ListBase *particles)
}
psys->edit = 0;
psys->free_edit = NULL;
psys->pathcache = 0;
psys->childcache = 0;
psys->pathcachebufs.first = psys->pathcachebufs.last = 0;
@@ -3852,6 +3853,9 @@ static void direct_link_scene(FileData *fd, Scene *sce)
sce->toolsettings->vpaint= newdataadr(fd, sce->toolsettings->vpaint);
sce->toolsettings->wpaint= newdataadr(fd, sce->toolsettings->wpaint);
sce->toolsettings->sculpt= newdataadr(fd, sce->toolsettings->sculpt);
sce->toolsettings->imapaint.paintcursor= NULL;
sce->toolsettings->particle.paintcursor= NULL;
if(sce->toolsettings->sculpt)
sce->toolsettings->sculpt->session= MEM_callocN(sizeof(SculptSession), "reload sculpt session");
}

View File

@@ -71,9 +71,10 @@ struct CustomData;
/* meshtools.c */
intptr_t mesh_octree_table(Object *ob, struct EditMesh *em, float *co, char mode);
struct EditVert *editmesh_get_x_mirror_vert(Object *ob, struct EditMesh *em, float *co);
int mesh_get_x_mirror_vert(Object *ob, int index);
intptr_t mesh_octree_table(struct Object *ob, struct EditMesh *em, float *co, char mode);
struct EditVert *editmesh_get_x_mirror_vert(struct Object *ob, struct EditMesh *em, float *co);
int mesh_get_x_mirror_vert(struct Object *ob, int index);
int *mesh_get_x_mirror_faces(struct Object *ob, struct EditMesh *em);
/* mesh_ops.c */
void ED_operatortypes_mesh(void);

View File

@@ -30,19 +30,15 @@
#ifndef ED_PARTICLE_H
#define ED_PARTICLE_H
struct bContext;
struct Object;
struct ParticleSystem;
struct ParticleEditSettings;
struct ParticleSystem;
struct RadialControl;
struct ViewContext;
struct rcti;
struct wmWindowManager;
/* particle edit mode */
void PE_set_particle_edit(struct Scene *scene);
void PE_create_particle_edit(struct Scene *scene, struct Object *ob, struct ParticleSystem *psys);
void PE_free_particle_edit(struct ParticleSystem *psys);
void PE_change_act(void *ob_v, void *act_v);
void PE_change_act_psys(struct Scene *scene, struct Object *ob, struct ParticleSystem *psys);
int PE_can_edit(struct ParticleSystem *psys);
@@ -51,38 +47,17 @@ int PE_can_edit(struct ParticleSystem *psys);
struct ParticleSystem *PE_get_current(struct Scene *scene, struct Object *ob);
short PE_get_current_num(struct Object *ob);
int PE_minmax(struct Scene *scene, float *min, float *max);
void PE_get_colors(char sel[4], char nosel[4]);
struct ParticleEditSettings *PE_settings(Scene *scene);
struct RadialControl **PE_radialcontrol(void);
/* update calls */
void PE_hide_keys_time(struct Scene *scene, struct ParticleSystem *psys, float cfra);
void PE_update_object(struct Scene *scene, struct Object *ob, int useflag);
void PE_update_selection(struct Scene *scene, struct Object *ob, int useflag);
void PE_recalc_world_cos(struct Object *ob, struct ParticleSystem *psys);
/* selection tools */
void PE_select_root(void);
void PE_select_tip(void);
void PE_deselectall(void);
void PE_select_linked(void);
void PE_select_less(void);
void PE_select_more(void);
void PE_mouse_particles(void);
void PE_border_select(struct ViewContext *vc, struct rcti *rect, int select);
void PE_circle_select(struct ViewContext *vc, int selecting, short *mval, float rad);
void PE_lasso_select(struct ViewContext *vc, short mcords[][2], short moves, short select);
/* tools */
void PE_hide(int mode);
void PE_rekey(void);
void PE_subdivide(Object *ob);
int PE_brush_particles(void);
void PE_remove_doubles(void);
void PE_selectbrush_menu(Scene *scene);
void PE_remove_doubles(void);
void PE_radialcontrol_start(const int mode);
int PE_mouse_particles(struct bContext *C, short *mval, int extend);
int PE_border_select(struct bContext *C, struct rcti *rect, int select);
int PE_circle_select(struct bContext *C, int selecting, short *mval, float rad);
int PE_lasso_select(struct bContext *C, short mcords[][2], short moves, short select);
/* undo */
void PE_undo_push(Scene *scene, char *str);

View File

@@ -127,6 +127,8 @@ void view3d_get_transformation(struct ViewContext *vc, struct Object *ob, struct
/* XXX should move to arithb.c */
int edge_inside_circle(short centx, short centy, short rad, short x1, short y1, short x2, short y2);
int lasso_inside(short mcords[][2], short moves, short sx, short sy);
int lasso_inside_edge(short mcords[][2], short moves, int x0, int y0, int x1, int y1);
/* modes */
void ED_view3d_exit_paint_modes(struct bContext *C);

File diff suppressed because it is too large Load Diff

View File

@@ -5136,7 +5136,8 @@ void PAINT_OT_texture_paint_toggle(wmOperatorType *ot)
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
}
/* ************ texture paint radial control *************/
/************* texture paint radial control *************/
static int texture_paint_radial_control_invoke(bContext *C, wmOperator *op, wmEvent *event)
{
ToolSettings *ts = CTX_data_scene(C)->toolsettings;
@@ -5178,3 +5179,4 @@ void PAINT_OT_texture_paint_radial_control(wmOperatorType *ot)
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
}

View File

@@ -1890,7 +1890,6 @@ static int vpaint_invoke(bContext *C, wmOperator *op, wmEvent *event)
void PAINT_OT_vertex_paint(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Vertex Paint";
ot->idname= "PAINT_OT_vertex_paint";
@@ -1903,6 +1902,5 @@ void PAINT_OT_vertex_paint(wmOperatorType *ot)
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
}

View File

@@ -1082,6 +1082,7 @@ void backdrawview3d(Scene *scene, ARegion *ar, View3D *v3d)
if(G.f & G_VERTEXPAINT || G.f & G_WEIGHTPAINT);
else if((G.f & G_TEXTUREPAINT) && scene->toolsettings && (scene->toolsettings->imapaint.flag & IMAGEPAINT_PROJECT_DISABLE));
else if((G.f & G_PARTICLEEDIT) && v3d->drawtype>OB_WIRE && (v3d->flag & V3D_ZBUF_SELECT));
else if(scene->obedit && v3d->drawtype>OB_WIRE && (v3d->flag & V3D_ZBUF_SELECT));
else {
v3d->flag &= ~V3D_NEEDBACKBUFDRAW;
@@ -2090,6 +2091,12 @@ void view3d_main_area_draw(const bContext *C, ARegion *ar)
v3d->flag |= V3D_NEEDBACKBUFDRAW;
// XXX addafterqueue(ar->win, BACKBUFDRAW, 1);
}
if((G.f & G_PARTICLEEDIT) && v3d->drawtype>OB_WIRE && (v3d->flag & V3D_ZBUF_SELECT)) {
v3d->flag |= V3D_NEEDBACKBUFDRAW;
// XXX addafterqueue(ar->win, BACKBUFDRAW, 1);
}
// test for backbuf select
if(scene->obedit && v3d->drawtype>OB_WIRE && (v3d->flag & V3D_ZBUF_SELECT)) {

View File

@@ -689,7 +689,7 @@ static void do_lasso_select_node(short mcords[][2], short moves, short select)
}
#endif
void view3d_lasso_select(ViewContext *vc, short mcords[][2], short moves, short select)
void view3d_lasso_select(bContext *C, ViewContext *vc, short mcords[][2], short moves, short select)
{
if(vc->obedit==NULL) {
if(FACESEL_PAINT_TEST)
@@ -697,7 +697,7 @@ void view3d_lasso_select(ViewContext *vc, short mcords[][2], short moves, short
else if(G.f & (G_VERTEXPAINT|G_TEXTUREPAINT|G_WEIGHTPAINT))
;
else if(G.f & G_PARTICLEEDIT)
PE_lasso_select(vc, mcords, moves, select);
PE_lasso_select(C, mcords, moves, select);
else
do_lasso_select_objects(vc, mcords, moves, select);
}
@@ -747,7 +747,7 @@ static int view3d_lasso_select_exec(bContext *C, wmOperator *op)
view3d_set_viewcontext(C, &vc);
select= RNA_enum_is_equal(op->ptr, "type", "SELECT");
view3d_lasso_select(&vc, mcords, i, select);
view3d_lasso_select(C, &vc, mcords, i, select);
return OPERATOR_FINISHED;
}
@@ -1349,8 +1349,7 @@ static int view3d_borderselect_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
else if(obedit==NULL && (G.f & G_PARTICLEEDIT)) {
PE_border_select(&vc, &rect, (val==LEFTMOUSE));
return OPERATOR_FINISHED;
return PE_border_select(C, &rect, (val==LEFTMOUSE));
}
if(obedit) {
@@ -1580,6 +1579,8 @@ static int view3d_select_invoke(bContext *C, wmOperator *op, wmEvent *event)
mouse_nurb(C, event->mval, extend);
}
else if(G.f & G_PARTICLEEDIT)
PE_mouse_particles(C, event->mval, extend);
else
mouse_select(C, event->mval, extend, 0);
@@ -1799,7 +1800,7 @@ static int view3d_circle_select_exec(bContext *C, wmOperator *op)
if(CTX_data_edit_object(C))
obedit_circle_select(&vc, selecting, mval, (float)radius);
else
PE_circle_select(&vc, selecting, mval, (float)radius);
return PE_circle_select(C, selecting, mval, (float)radius);
}
else {
Base *base;

View File

@@ -1601,13 +1601,11 @@ static void createTransLatticeVerts(bContext *C, TransInfo *t)
/* ******************* particle edit **************** */
static void createTransParticleVerts(bContext *C, TransInfo *t)
{
// TRANSFORM_FIX_ME
#if 0
TransData *td = NULL;
TransDataExtension *tx;
Base *base = BASACT;
Object *ob = OBACT;
ParticleSystem *psys = PE_get_current(ob);
Base *base = CTX_data_active_base(C);
Object *ob = CTX_data_active_object(C);
ParticleSystem *psys = PE_get_current(t->scene, ob);
ParticleSystemModifierData *psmd = NULL;
ParticleEditSettings *pset = PE_settings(t->scene);
ParticleData *pa = NULL;
@@ -1715,15 +1713,13 @@ static void createTransParticleVerts(bContext *C, TransInfo *t)
if (propmode && head != tail)
calc_distanceCurveVerts(head, tail - 1);
}
#endif
}
void flushTransParticles(TransInfo *t)
{
#if 0 // TRANSFORM_FIX_ME
Scene *scene = t->scene;
Object *ob = OBACT;
ParticleSystem *psys = PE_get_current(ob);
ParticleSystem *psys = PE_get_current(scene, ob);
ParticleSystemModifierData *psmd;
ParticleData *pa;
ParticleEditKey *key;
@@ -1755,7 +1751,6 @@ void flushTransParticles(TransInfo *t)
}
PE_update_object(scene, OBACT, 1);
#endif
}
/* ********************* mesh ****************** */
@@ -4630,11 +4625,9 @@ void special_aftertrans_update(TransInfo *t)
// allqueue(REDRAWBUTSEDIT, 0);
}
#if 0 // TRANSFORM_FIX_ME
else if(G.f & G_PARTICLEEDIT) {
;
}
#endif
else {
/* Objects */
// XXX ideally, this would go through context iterators, but we don't have context iterator access here,
@@ -4999,8 +4992,7 @@ void createTransData(bContext *C, TransInfo *t)
}
CTX_DATA_END;
}
#if 0 // TRANSFORM_FIX_ME
else if (G.f & G_PARTICLEEDIT && PE_can_edit(PE_get_current(ob))) {
else if (G.f & G_PARTICLEEDIT && PE_can_edit(PE_get_current(scene, ob))) {
createTransParticleVerts(C, t);
if(t->data && t->flag & T_PROP_EDIT) {
@@ -5011,7 +5003,6 @@ void createTransData(bContext *C, TransInfo *t)
t->flag |= T_POINTS;
}
#endif
else {
View3D *v3d = t->view;
RegionView3D *rv3d = t->ar->regiondata;

View File

@@ -405,16 +405,18 @@ int calc_manipulator_stats(ScrArea *sa)
ParticleEditKey *ek;
int k;
if(psys->edit){
for(a=0; a<psys->totpart; a++,pa++){
if(psys->edit) {
for(a=0; a<psys->totpart; a++,pa++) {
if(pa->flag & PARS_HIDE) continue;
for(k=0, ek=psys->edit->keys[a]; k<pa->totkey; k++,ek++){
if(ek->flag & PEK_SELECT){
for(k=0, ek=psys->edit->keys[a]; k<pa->totkey; k++, ek++) {
if(ek->flag & PEK_SELECT) {
calc_tw_center(ek->world_co);
totsel++;
}
}
}
/* selection center */
if(totsel)
VecMulf(G.scene->twcent, 1.0f/(float)totsel); // centroid!

View File

@@ -179,7 +179,8 @@ typedef struct ParticleSystem{ /* note, make sure all (runtime) are NULL's in
ParticleData *particles; /* (parent) particles */
ChildParticle *child; /* child particles */
struct ParticleEdit *edit; /* particle editmode (runtime) */
struct ParticleEdit *edit; /* particle editmode (runtime) */
void (*free_edit)(struct ParticleSystem *sys); /* free callback */
struct ParticleCacheKey **pathcache; /* path cache (runtime) */
struct ParticleCacheKey **childcache; /* child cache (runtime) */

View File

@@ -370,6 +370,7 @@ typedef struct ParticleEditSettings {
short brushtype;
ParticleBrushData brush[7]; /* 7 = PE_TOT_BRUSH */
void *paintcursor; /* runtime */
float emitterdist;
int draw_timed;