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:
authorJanne Karhu <jhkarh@gmail.com>2011-06-21 15:15:37 +0400
committerJanne Karhu <jhkarh@gmail.com>2011-06-21 15:15:37 +0400
commit2145005e5e3d9618982b25047bf803a3433fe0a3 (patch)
tree287d48759f85ac2a162065ca671c9a4b84b6062a /source/blender/editors/physics
parenta50aa13faccec46df3a478c8de47925d4a5cfb5c (diff)
Fix for [#26939] Hair Combing intersects emitter when combed fast
* Hair combing now uses substeps to apply the combing when the mouse movement exceeds 0.2 of the brush radius. * This could make combing a bit slower on fast mouse movements, but the increase in combing quality is definitely worth it.
Diffstat (limited to 'source/blender/editors/physics')
-rw-r--r--source/blender/editors/physics/particle_edit.c236
1 files changed, 124 insertions, 112 deletions
diff --git a/source/blender/editors/physics/particle_edit.c b/source/blender/editors/physics/particle_edit.c
index 6155929243b..9124bdaf41c 100644
--- a/source/blender/editors/physics/particle_edit.c
+++ b/source/blender/editors/physics/particle_edit.c
@@ -3461,7 +3461,8 @@ static void brush_edit_apply(bContext *C, wmOperator *op, PointerRNA *itemptr)
ARegion *ar= CTX_wm_region(C);
float vec[3], mousef[2];
int mval[2];
- int flip, mouse[2], dx, dy, removed= 0, added=0, selected= 0;
+ int flip, mouse[2], removed= 0, added=0, selected= 0, tot_steps= 1, step= 1;
+ float dx, dy, dmax;
int lock_root = pset->flag & PE_LOCK_FIRST;
if(!PE_start_edit(edit))
@@ -3496,152 +3497,163 @@ static void brush_edit_apply(bContext *C, wmOperator *op, PointerRNA *itemptr)
view3d_operator_needs_opengl(C);
selected= (short)count_selected_keys(scene, edit);
- switch(pset->brushtype) {
- case PE_BRUSH_COMB:
- {
- float mval_f[2];
- data.mval= mval;
- data.rad= (float)brush->size;
+ dmax = MAX2(fabs(dx), fabs(dy));
+ tot_steps = dmax/(0.2f * brush->size) + 1;
- data.combfac= (brush->strength - 0.5f) * 2.0f;
- if(data.combfac < 0.0f)
- data.combfac= 1.0f - 9.0f * data.combfac;
- else
- data.combfac= 1.0f - data.combfac;
-
- invert_m4_m4(ob->imat, ob->obmat);
+ dx /= (float)tot_steps;
+ dy /= (float)tot_steps;
- mval_f[0]= dx;
- mval_f[1]= dy;
- ED_view3d_win_to_delta(ar, mval_f, vec);
- data.dvec= vec;
+ for(step = 1; step<=tot_steps; step++) {
+ mval[0] = bedit->lastmouse[0] + step*dx;
+ mval[1] = bedit->lastmouse[1] + step*dy;
- foreach_mouse_hit_key(&data, brush_comb, selected);
- break;
- }
- case PE_BRUSH_CUT:
- {
- if(edit->psys && edit->pathcache) {
+ switch(pset->brushtype) {
+ case PE_BRUSH_COMB:
+ {
+ float mval_f[2];
data.mval= mval;
data.rad= (float)brush->size;
- data.cutfac= brush->strength;
- if(selected)
- foreach_selected_point(&data, brush_cut);
+ data.combfac= (brush->strength - 0.5f) * 2.0f;
+ if(data.combfac < 0.0f)
+ data.combfac= 1.0f - 9.0f * data.combfac;
else
- foreach_point(&data, brush_cut);
+ data.combfac= 1.0f - data.combfac;
- removed= remove_tagged_particles(ob, edit->psys, pe_x_mirror(ob));
- if(pset->flag & PE_KEEP_LENGTHS)
- recalc_lengths(edit);
- }
- else
- removed= 0;
-
- break;
- }
- case PE_BRUSH_LENGTH:
- {
- data.mval= mval;
-
- data.rad= (float)brush->size;
- data.growfac= brush->strength / 50.0f;
+ invert_m4_m4(ob->imat, ob->obmat);
- if(brush->invert ^ flip)
- data.growfac= 1.0f - data.growfac;
- else
- data.growfac= 1.0f + data.growfac;
+ mval_f[0]= dx;
+ mval_f[1]= dy;
+ ED_view3d_win_to_delta(ar, mval_f, vec);
+ data.dvec= vec;
- foreach_mouse_hit_point(&data, brush_length, selected);
+ foreach_mouse_hit_key(&data, brush_comb, selected);
+ break;
+ }
+ case PE_BRUSH_CUT:
+ {
+ if(edit->psys && edit->pathcache) {
+ data.mval= mval;
+ data.rad= (float)brush->size;
+ data.cutfac= brush->strength;
+
+ if(selected)
+ foreach_selected_point(&data, brush_cut);
+ else
+ foreach_point(&data, brush_cut);
+
+ removed= remove_tagged_particles(ob, edit->psys, pe_x_mirror(ob));
+ if(pset->flag & PE_KEEP_LENGTHS)
+ recalc_lengths(edit);
+ }
+ else
+ removed= 0;
- if(pset->flag & PE_KEEP_LENGTHS)
- recalc_lengths(edit);
- break;
- }
- case PE_BRUSH_PUFF:
- {
- if(edit->psys) {
- data.dm= psmd->dm;
+ break;
+ }
+ case PE_BRUSH_LENGTH:
+ {
data.mval= mval;
+
data.rad= (float)brush->size;
- data.select= selected;
+ data.growfac= brush->strength / 50.0f;
- data.pufffac= (brush->strength - 0.5f) * 2.0f;
- if(data.pufffac < 0.0f)
- data.pufffac= 1.0f - 9.0f * data.pufffac;
+ if(brush->invert ^ flip)
+ data.growfac= 1.0f - data.growfac;
else
- data.pufffac= 1.0f - data.pufffac;
+ data.growfac= 1.0f + data.growfac;
- data.invert= (brush->invert ^ flip);
- invert_m4_m4(ob->imat, ob->obmat);
+ foreach_mouse_hit_point(&data, brush_length, selected);
- foreach_mouse_hit_point(&data, brush_puff, selected);
+ if(pset->flag & PE_KEEP_LENGTHS)
+ recalc_lengths(edit);
+ break;
}
- break;
- }
- case PE_BRUSH_ADD:
- {
- if(edit->psys && edit->psys->part->from==PART_FROM_FACE) {
- data.mval= mval;
+ case PE_BRUSH_PUFF:
+ {
+ if(edit->psys) {
+ data.dm= psmd->dm;
+ data.mval= mval;
+ data.rad= (float)brush->size;
+ data.select= selected;
+
+ data.pufffac= (brush->strength - 0.5f) * 2.0f;
+ if(data.pufffac < 0.0f)
+ data.pufffac= 1.0f - 9.0f * data.pufffac;
+ else
+ data.pufffac= 1.0f - data.pufffac;
+
+ data.invert= (brush->invert ^ flip);
+ invert_m4_m4(ob->imat, ob->obmat);
+
+ foreach_mouse_hit_point(&data, brush_puff, selected);
+ }
+ break;
+ }
+ case PE_BRUSH_ADD:
+ {
+ if(edit->psys && edit->psys->part->from==PART_FROM_FACE) {
+ data.mval= mval;
- added= brush_add(&data, brush->count);
+ added= brush_add(&data, brush->count);
- if(pset->flag & PE_KEEP_LENGTHS)
- recalc_lengths(edit);
+ if(pset->flag & PE_KEEP_LENGTHS)
+ recalc_lengths(edit);
+ }
+ else
+ added= 0;
+ break;
}
- else
- added= 0;
- break;
- }
- case PE_BRUSH_SMOOTH:
- {
- data.mval= mval;
- data.rad= (float)brush->size;
+ case PE_BRUSH_SMOOTH:
+ {
+ data.mval= mval;
+ data.rad= (float)brush->size;
+
+ data.vec[0]= data.vec[1]= data.vec[2]= 0.0f;
+ data.tot= 0;
- data.vec[0]= data.vec[1]= data.vec[2]= 0.0f;
- data.tot= 0;
+ data.smoothfac= brush->strength;
- data.smoothfac= brush->strength;
+ invert_m4_m4(ob->imat, ob->obmat);
- invert_m4_m4(ob->imat, ob->obmat);
+ foreach_mouse_hit_key(&data, brush_smooth_get, selected);
- foreach_mouse_hit_key(&data, brush_smooth_get, selected);
+ if(data.tot) {
+ mul_v3_fl(data.vec, 1.0f / (float)data.tot);
+ foreach_mouse_hit_key(&data, brush_smooth_do, selected);
+ }
- if(data.tot) {
- mul_v3_fl(data.vec, 1.0f / (float)data.tot);
- foreach_mouse_hit_key(&data, brush_smooth_do, selected);
+ break;
}
+ case PE_BRUSH_WEIGHT:
+ {
+ if(edit->psys) {
+ data.dm= psmd->dm;
+ data.mval= mval;
+ data.rad= (float)brush->size;
- break;
- }
- case PE_BRUSH_WEIGHT:
- {
- if(edit->psys) {
- data.dm= psmd->dm;
- data.mval= mval;
- data.rad= (float)brush->size;
+ data.weightfac = brush->strength; /* note that this will never be zero */
- data.weightfac = brush->strength; /* note that this will never be zero */
+ foreach_mouse_hit_key(&data, brush_weight, selected);
+ }
- foreach_mouse_hit_key(&data, brush_weight, selected);
+ break;
}
-
- break;
}
- }
- if((pset->flag & PE_KEEP_LENGTHS)==0)
- recalc_lengths(edit);
+ if((pset->flag & PE_KEEP_LENGTHS)==0)
+ recalc_lengths(edit);
- if(ELEM(pset->brushtype, PE_BRUSH_ADD, PE_BRUSH_CUT) && (added || removed)) {
- if(pset->brushtype == PE_BRUSH_ADD && pe_x_mirror(ob))
- PE_mirror_x(scene, ob, 1);
+ if(ELEM(pset->brushtype, PE_BRUSH_ADD, PE_BRUSH_CUT) && (added || removed)) {
+ if(pset->brushtype == PE_BRUSH_ADD && pe_x_mirror(ob))
+ PE_mirror_x(scene, ob, 1);
- update_world_cos(ob,edit);
- psys_free_path_cache(NULL, edit);
- DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
+ update_world_cos(ob,edit);
+ psys_free_path_cache(NULL, edit);
+ DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
+ }
+ else
+ PE_update_object(scene, ob, 1);
}
- else
- PE_update_object(scene, ob, 1);
WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_EDITED, ob);