[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [37693] trunk/blender/source/blender/ editors/physics/particle_edit.c: Fix for [#26939] Hair Combing intersects emitter when combed fast

Janne Karhu jhkarh at gmail.com
Tue Jun 21 13:15:37 CEST 2011


Revision: 37693
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=37693
Author:   jhk
Date:     2011-06-21 11:15:37 +0000 (Tue, 21 Jun 2011)
Log Message:
-----------
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.

Modified Paths:
--------------
    trunk/blender/source/blender/editors/physics/particle_edit.c

Modified: trunk/blender/source/blender/editors/physics/particle_edit.c
===================================================================
--- trunk/blender/source/blender/editors/physics/particle_edit.c	2011-06-21 08:09:42 UTC (rev 37692)
+++ trunk/blender/source/blender/editors/physics/particle_edit.c	2011-06-21 11:15:37 UTC (rev 37693)
@@ -3461,7 +3461,8 @@
 	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 @@
 		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;
+		dx /= (float)tot_steps;
+		dy /= (float)tot_steps;
 
-				invert_m4_m4(ob->imat, ob->obmat);
+		for(step = 1; step<=tot_steps; step++) {
+			mval[0] = bedit->lastmouse[0] + step*dx;
+			mval[1] = bedit->lastmouse[1] + step*dy;
 
-				mval_f[0]= dx;
-				mval_f[1]= dy;
-				ED_view3d_win_to_delta(ar, mval_f, vec);
-				data.dvec= vec;
-
-				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);
+					invert_m4_m4(ob->imat, ob->obmat);
+
+					mval_f[0]= dx;
+					mval_f[1]= dy;
+					ED_view3d_win_to_delta(ar, mval_f, vec);
+					data.dvec= vec;
+
+					foreach_mouse_hit_key(&data, brush_comb, selected);
+					break;
 				}
-				else
-					removed= 0;
+				case PE_BRUSH_CUT:
+				{
+					if(edit->psys && edit->pathcache) {
+						data.mval= mval;
+						data.rad= (float)brush->size;
+						data.cutfac= brush->strength;
 
-				break;
-			}
-			case PE_BRUSH_LENGTH:
-			{
-				data.mval= mval;
-				
-				data.rad= (float)brush->size;
-				data.growfac= brush->strength / 50.0f;
+						if(selected)
+							foreach_selected_point(&data, brush_cut);
+						else
+							foreach_point(&data, brush_cut);
 
-				if(brush->invert ^ flip)
-					data.growfac= 1.0f - data.growfac;
-				else
-					data.growfac= 1.0f + data.growfac;
+						removed= remove_tagged_particles(ob, edit->psys, pe_x_mirror(ob));
+						if(pset->flag & PE_KEEP_LENGTHS)
+							recalc_lengths(edit);
+					}
+					else
+						removed= 0;
 
-				foreach_mouse_hit_point(&data, brush_length, selected);
-
-				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);
-				}
-				break;
-			}
-			case PE_BRUSH_ADD:
-			{
-				if(edit->psys && edit->psys->part->from==PART_FROM_FACE) {
-					data.mval= mval;
-
-					added= brush_add(&data, brush->count);
-
 					if(pset->flag & PE_KEEP_LENGTHS)
 						recalc_lengths(edit);
+					break;
 				}
-				else
-					added= 0;
-				break;
-			}
-			case PE_BRUSH_SMOOTH:
-			{
-				data.mval= mval;
-				data.rad= (float)brush->size;
+				case PE_BRUSH_PUFF:
+				{
+					if(edit->psys) {
+						data.dm= psmd->dm;
+						data.mval= mval;
+						data.rad= (float)brush->size;
+						data.select= selected;
 
-				data.vec[0]= data.vec[1]= data.vec[2]= 0.0f;
-				data.tot= 0;
+						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.smoothfac= brush->strength;
+						data.invert= (brush->invert ^ flip);
+						invert_m4_m4(ob->imat, ob->obmat);
 
-				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;
 
-				foreach_mouse_hit_key(&data, brush_smooth_get, selected);
+						added= brush_add(&data, brush->count);
 
-				if(data.tot) {
-					mul_v3_fl(data.vec, 1.0f / (float)data.tot);
-					foreach_mouse_hit_key(&data, brush_smooth_do, selected);
+						if(pset->flag & PE_KEEP_LENGTHS)
+							recalc_lengths(edit);
+					}
+					else
+						added= 0;
+					break;
 				}
-
-				break;
-			}
-			case PE_BRUSH_WEIGHT:
-			{
-				if(edit->psys) {
-					data.dm= psmd->dm;
+				case PE_BRUSH_SMOOTH:
+				{
 					data.mval= mval;
 					data.rad= (float)brush->size;
 
-					data.weightfac = brush->strength; /* note that this will never be zero */
+					data.vec[0]= data.vec[1]= data.vec[2]= 0.0f;
+					data.tot= 0;
 
-					foreach_mouse_hit_key(&data, brush_weight, selected);
+					data.smoothfac= brush->strength;
+
+					invert_m4_m4(ob->imat, ob->obmat);
+
+					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);
+					}
+
+					break;
 				}
+				case PE_BRUSH_WEIGHT:
+				{
+					if(edit->psys) {
+						data.dm= psmd->dm;
+						data.mval= mval;
+						data.rad= (float)brush->size;
 
-				break;
+						data.weightfac = brush->strength; /* note that this will never be zero */
+
+						foreach_mouse_hit_key(&data, brush_weight, selected);
+					}
+
+					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);
 		




More information about the Bf-blender-cvs mailing list