particle weight brush back (mostly the same as in 2.4x), needed to control long hairs...
authorCampbell Barton <ideasman42@gmail.com>
Thu, 14 Jan 2010 08:53:10 +0000 (08:53 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Thu, 14 Jan 2010 08:53:10 +0000 (08:53 +0000)
source/blender/blenkernel/intern/particle.c
source/blender/blenkernel/intern/particle_system.c
source/blender/editors/physics/particle_edit.c
source/blender/editors/space_view3d/drawobject.c
source/blender/makesdna/DNA_scene_types.h
source/blender/makesrna/intern/rna_sculpt_paint.c

index 715d3610b3183ebd1d4fe9d5884eb31f329f087b..9889fa9c7b313a0f31bdc2428591681e59aa700d 100644 (file)
@@ -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; i<totpart; i++, pa+=pa?1:0, point++){
@@ -3003,6 +3012,14 @@ void psys_cache_edit_paths(Scene *scene, Object *ob, PTCacheEdit *edit, float cf
                pind.bspline = psys ? (psys->part->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);
+                                       }
                                }
                        }
 
index 27e0c632a81a8cfbd3f8dccf11fff008d10b1844..acdab80bb37565e5b25cff693e5c328f51136332 100644 (file)
@@ -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++;
                        }
                }
index fc86971b8accad6957d493598e5f7c5c3ffe1653..f9c786b29b06e4aacb94d1087eb7acd55fddea0e 100644 (file)
@@ -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;
                        }
                }
index 8e269d980149dcd5babb843336085155826633ba..dd43c34c4dc1eefe820689d91607c78bf90e78e9 100644 (file)
@@ -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<totpoint; i++){
                path = cache[i];
index a55d13cf1606c24cd11dab576dd38255bbd6a172..85f75684d857f78533b81c8cd02534a74de0878e 100644 (file)
@@ -1137,6 +1137,7 @@ typedef enum SculptFlags {
 #define PE_BRUSH_PUFF          3
 #define PE_BRUSH_ADD           4
 #define PE_BRUSH_SMOOTH                5
+#define PE_BRUSH_WEIGHT                6
 
 /* this must equal ParticleEditSettings.brush array size */
 #define PE_TOT_BRUSH           6
index 5e5eb9d84ceb31d9fe0713dac8fbfd84d85202a8..5d81ec2c572fc71bb5cfe004fdbedfdd57af1dcb 100644 (file)
@@ -44,6 +44,7 @@ static EnumPropertyItem particle_edit_hair_brush_items[] = {
        {PE_BRUSH_LENGTH, "LENGTH", 0, "Length", "Make hairs longer or shorter."},
        {PE_BRUSH_PUFF, "PUFF", 0, "Puff", "Make hairs stand up."},
        {PE_BRUSH_CUT, "CUT", 0, "Cut", "Cut hairs."},
+       {PE_BRUSH_WEIGHT, "WEIGHT", 0, "Weight", "Weight hair particles."},
        {0, NULL, 0, NULL, NULL}};
 
 #ifdef RNA_RUNTIME