From c1f2fd0a464c62e01e78f3b8f544219fa087ffc2 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 14 Jan 2010 08:53:10 +0000 Subject: particle weight brush back (mostly the same as in 2.4x), needed to control long hairs movement. --- source/blender/blenkernel/intern/particle.c | 69 ++++++++++++++++------ source/blender/blenkernel/intern/particle_system.c | 6 +- source/blender/editors/physics/particle_edit.c | 40 +++++++++++-- source/blender/editors/space_view3d/drawobject.c | 6 ++ source/blender/makesdna/DNA_scene_types.h | 1 + source/blender/makesrna/intern/rna_sculpt_paint.c | 1 + 6 files changed, 94 insertions(+), 29 deletions(-) (limited to 'source') diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c index 715d3610b31..9889fa9c7b3 100644 --- a/source/blender/blenkernel/intern/particle.c +++ b/source/blender/blenkernel/intern/particle.c @@ -2983,12 +2983,21 @@ void psys_cache_edit_paths(Scene *scene, Object *ob, PTCacheEdit *edit, float cf frs_sec = (psys || edit->pid.flag & PTCACHE_VEL_PER_SEC) ? 25.0f : 1.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; + if(pset->brushtype == PE_BRUSH_WEIGHT){ + /* use weight painting colors now... */ +#if 0 + sel_col[0] = sel_col[1] = sel_col[2] = 1.0f; + nosel_col[0] = nosel_col[1] = nosel_col[2] = 0.0f; +#endif + } + else{ + 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; + } /*---first main loop: create all actual particles' paths---*/ for(i=0; ipart->flag & PART_HAIR_BSPLINE) : 0; pind.dm = NULL; + + /* should init_particle_interpolation set this ? */ + if(pset->brushtype==PE_BRUSH_WEIGHT){ + pind.hkey[0] = pa->hair; + pind.hkey[1] = pa->hair + 1; + } + + memset(cache[i], 0, sizeof(*cache[i])*(steps+1)); cache[i]->steps = steps; @@ -3035,6 +3052,12 @@ void psys_cache_edit_paths(Scene *scene, Object *ob, PTCacheEdit *edit, float cf do_particle_interpolation(psys, i, pa, t, frs_sec, &pind, &result); + /* should init_particle_interpolation set this ? */ + if(pset->brushtype==PE_BRUSH_WEIGHT){ + pind.hkey[0] = pind.hkey[1]; + pind.hkey[1]++; + } + /* non-hair points are allready in global space */ if(psys && !(psys->flag & PSYS_GLOBAL_HAIR)) { mul_m4_v3(hairmat, result.co); @@ -3091,22 +3114,30 @@ void psys_cache_edit_paths(Scene *scene, Object *ob, PTCacheEdit *edit, float cf ca->vel[1] = 1.0f; /* selection coloring in edit mode */ - if((ekey + (pind.ekey[0] - point->keys))->flag & PEK_SELECT){ - if((ekey + (pind.ekey[1] - point->keys))->flag & PEK_SELECT){ - VECCOPY(ca->col, sel_col); - } - else{ - keytime = (t - (*pind.ekey[0]->time))/((*pind.ekey[1]->time) - (*pind.ekey[0]->time)); - interp_v3_v3v3(ca->col, sel_col, nosel_col, keytime); - } + if(pset->brushtype==PE_BRUSH_WEIGHT){ + if(k==steps) + weight_to_rgb(pind.hkey[0]->weight, ca->col, ca->col+1, ca->col+2); + else + weight_to_rgb((1.0f - keytime) * pind.hkey[0]->weight + keytime * pind.hkey[1]->weight, ca->col, ca->col+1, ca->col+2); } - else{ - if((ekey + (pind.ekey[1] - point->keys))->flag & PEK_SELECT){ - keytime = (t - (*pind.ekey[0]->time))/((*pind.ekey[1]->time) - (*pind.ekey[0]->time)); - interp_v3_v3v3(ca->col, nosel_col, sel_col, keytime); + else { + if((ekey + (pind.ekey[0] - point->keys))->flag & PEK_SELECT){ + if((ekey + (pind.ekey[1] - point->keys))->flag & PEK_SELECT){ + VECCOPY(ca->col, sel_col); + } + else{ + keytime = (t - (*pind.ekey[0]->time))/((*pind.ekey[1]->time) - (*pind.ekey[0]->time)); + interp_v3_v3v3(ca->col, sel_col, nosel_col, keytime); + } } else{ - VECCOPY(ca->col, nosel_col); + if((ekey + (pind.ekey[1] - point->keys))->flag & PEK_SELECT){ + keytime = (t - (*pind.ekey[0]->time))/((*pind.ekey[1]->time) - (*pind.ekey[0]->time)); + interp_v3_v3v3(ca->col, nosel_col, sel_col, keytime); + } + else{ + VECCOPY(ca->col, nosel_col); + } } } diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c index 27e0c632a81..acdab80bb37 100644 --- a/source/blender/blenkernel/intern/particle_system.c +++ b/source/blender/blenkernel/intern/particle_system.c @@ -3071,10 +3071,8 @@ static void do_hair_dynamics(ParticleSimulationData *sim) dvert->dw = MEM_callocN (sizeof(MDeformWeight), "deformWeight"); dvert->totweight = 1; } - - /* no special reason for the 0.5 */ - /* just seems like a nice value from experiments */ - dvert->dw->weight = k ? 0.5f : 1.0f; + /* roots should be 1.0, the rest can be anything from 0.0 to 1.0 */ + dvert->dw->weight = key->weight; dvert++; } } diff --git a/source/blender/editors/physics/particle_edit.c b/source/blender/editors/physics/particle_edit.c index fc86971b8ac..f9c786b29b0 100644 --- a/source/blender/editors/physics/particle_edit.c +++ b/source/blender/editors/physics/particle_edit.c @@ -2844,7 +2844,6 @@ static void brush_puff(PEData *data, int point_index) PTCacheEditPoint *point = edit->points + point_index; KEY_K; float mat[4][4], imat[4][4]; - float obmat[4][4], obimat[4][4]; float lastco[3], rootco[3] = {0.0f, 0.0f, 0.0f}, co[3], nor[3], kco[3], dco[3], ofs[3] = {0.0f, 0.0f, 0.0f}, fac=0.0f, length=0.0f; int puff_volume = 0; @@ -2865,22 +2864,19 @@ static void brush_puff(PEData *data, int point_index) unit_m4(imat); } - copy_m4_m4(obmat, data->ob->obmat); - invert_m4_m4(obimat, obmat); - LOOP_KEYS { if(k==0) { /* find root coordinate and normal on emitter */ VECCOPY(co, key->co); mul_m4_v3(mat, co); - mul_v3_m4v3(kco, obimat, co); /* use 'kco' as the object space version of worldspace 'co' */ + mul_v3_m4v3(kco, data->ob->imat, co); /* use 'kco' as the object space version of worldspace 'co', ob->imat is set before calling */ point_index= BLI_kdtree_find_nearest(edit->emitter_field, kco, NULL, NULL); if(point_index == -1) return; VECCOPY(rootco, co); copy_v3_v3(nor, &edit->emitter_cosnos[point_index*6+3]); - mul_mat3_m4_v3(obmat, nor); /* normal into worldspace */ + mul_mat3_m4_v3(data->ob->obmat, nor); /* normal into worldspace */ normalize_v3(nor); length= 0.0f; @@ -2949,6 +2945,21 @@ static void brush_puff(PEData *data, int point_index) point->flag |= PEP_EDIT_RECALC; } + +static void brush_weight(PEData *data, float mat[][4], float imat[][4], int point_index, int key_index, PTCacheEditKey *key) +{ + /* roots have full weight allways */ + if(key_index) { + PTCacheEdit *edit = data->edit; + ParticleSystem *psys = edit->psys; + + ParticleData *pa= psys->particles + point_index; + pa->hair[key_index].weight = data->weightfac; + + (data->edit->points + point_index)->flag |= PEP_EDIT_RECALC; + } +} + static void brush_smooth_get(PEData *data, float mat[][4], float imat[][4], int point_index, int key_index, PTCacheEditKey *key) { if(key_index) { @@ -3394,6 +3405,23 @@ static void brush_edit_apply(bContext *C, wmOperator *op, PointerRNA *itemptr) foreach_mouse_hit_key(&data, brush_smooth_do, selected); } + break; + } + case PE_BRUSH_WEIGHT: + { + PEData data; + PE_set_view3d_data(C, &data); + + if(edit->psys) { + data.dm= psmd->dm; + data.mval= mval; + data.rad= (float)brush->size; + + data.weightfac = (float)(brush->strength / 100.0f); /* note that this will never be zero */ + + foreach_mouse_hit_key(&data, brush_weight, selected); + } + break; } } diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index 8e269d98014..dd43c34c4dc 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -3812,6 +3812,12 @@ static void draw_ptcache_edit(Scene *scene, View3D *v3d, RegionView3D *rv3d, Obj glEnable(GL_COLOR_MATERIAL); glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE); + if(pset->brushtype == PE_BRUSH_WEIGHT) { + glLineWidth(2.0f); + glDisable(GL_LIGHTING); + /* TODO, nice color blending */ + } + cache=edit->pathcache; for(i=0; i