[Bf-blender-cvs] [32ab0647a53] blender2.8: DRW: Implement Hair Weight drawing

Clément Foucault noreply at git.blender.org
Tue Nov 27 13:49:56 CET 2018


Commit: 32ab0647a53c16420993ca49563580cd48ac99af
Author: Clément Foucault
Date:   Tue Nov 27 13:49:00 2018 +0100
Branches: blender2.8
https://developer.blender.org/rB32ab0647a53c16420993ca49563580cd48ac99af

DRW: Implement Hair Weight drawing

Fixes T57931 Particle weight edit mode is not supported.

There is a bug that prevent refresh of the toolsettings on which is based
the weight / non-weight display selection (see T58086).

===================================================================

M	source/blender/draw/intern/draw_cache.c
M	source/blender/draw/intern/draw_cache.h
M	source/blender/draw/intern/draw_cache_impl.h
M	source/blender/draw/intern/draw_cache_impl_particles.c
M	source/blender/draw/modes/particle_mode.c
M	source/blender/draw/modes/shaders/particle_strand_vert.glsl

===================================================================

diff --git a/source/blender/draw/intern/draw_cache.c b/source/blender/draw/intern/draw_cache.c
index 8fe3ba5e5b3..ccb33b7b0fd 100644
--- a/source/blender/draw/intern/draw_cache.c
+++ b/source/blender/draw/intern/draw_cache.c
@@ -3465,9 +3465,10 @@ GPUBatch *DRW_cache_particles_get_dots(Object *object, ParticleSystem *psys)
 GPUBatch *DRW_cache_particles_get_edit_strands(
         Object *object,
         ParticleSystem *psys,
-        struct PTCacheEdit *edit)
+        struct PTCacheEdit *edit,
+        bool use_weight)
 {
-	return DRW_particles_batch_cache_get_edit_strands(object, psys, edit);
+	return DRW_particles_batch_cache_get_edit_strands(object, psys, edit, use_weight);
 }
 
 GPUBatch *DRW_cache_particles_get_edit_inner_points(
diff --git a/source/blender/draw/intern/draw_cache.h b/source/blender/draw/intern/draw_cache.h
index 207bc6ec5de..1eeef83c81e 100644
--- a/source/blender/draw/intern/draw_cache.h
+++ b/source/blender/draw/intern/draw_cache.h
@@ -200,7 +200,7 @@ struct GPUBatch *DRW_cache_particles_get_hair(
 struct GPUBatch *DRW_cache_particles_get_dots(
         struct Object *object, struct ParticleSystem *psys);
 struct GPUBatch *DRW_cache_particles_get_edit_strands(
-        struct Object *object, struct ParticleSystem *psys, struct PTCacheEdit *edit);
+        struct Object *object, struct ParticleSystem *psys, struct PTCacheEdit *edit, bool use_weight);
 struct GPUBatch *DRW_cache_particles_get_edit_inner_points(
         struct Object *object, struct ParticleSystem *psys, struct PTCacheEdit *edit);
 struct GPUBatch *DRW_cache_particles_get_edit_tip_points(
diff --git a/source/blender/draw/intern/draw_cache_impl.h b/source/blender/draw/intern/draw_cache_impl.h
index a9a6093529e..720d54ad011 100644
--- a/source/blender/draw/intern/draw_cache_impl.h
+++ b/source/blender/draw/intern/draw_cache_impl.h
@@ -212,7 +212,7 @@ struct GPUBatch *DRW_particles_batch_cache_get_hair(
 struct GPUBatch *DRW_particles_batch_cache_get_dots(
         struct Object *object, struct ParticleSystem *psys);
 struct GPUBatch *DRW_particles_batch_cache_get_edit_strands(
-        struct Object *object, struct ParticleSystem *psys, struct PTCacheEdit *edit);
+        struct Object *object, struct ParticleSystem *psys, struct PTCacheEdit *edit, bool use_weight);
 struct GPUBatch *DRW_particles_batch_cache_get_edit_inner_points(
         struct Object *object, struct ParticleSystem *psys, struct PTCacheEdit *edit);
 struct GPUBatch *DRW_particles_batch_cache_get_edit_tip_points(
diff --git a/source/blender/draw/intern/draw_cache_impl_particles.c b/source/blender/draw/intern/draw_cache_impl_particles.c
index c8185c2db60..5a5f0ea0b3a 100644
--- a/source/blender/draw/intern/draw_cache_impl_particles.c
+++ b/source/blender/draw/intern/draw_cache_impl_particles.c
@@ -93,6 +93,7 @@ typedef struct ParticleBatchCache {
 
 	/* Settings to determine if cache is invalid. */
 	bool is_dirty;
+	bool edit_is_weight;
 } ParticleBatchCache;
 
 /* GPUBatch cache management. */
@@ -692,8 +693,27 @@ static float particle_key_select_ratio(const PTCacheEdit *edit, int strand, floa
 	}
 }
 
+static float particle_key_weight(const ParticleData *particle, int strand, float t)
+{
+	const ParticleData *part = particle + strand;
+	const HairKey *hkeys = part->hair;
+	float edit_key_seg_t = 1.0f / (part->totkey - 1);
+	if (t == 1.0) {
+		return hkeys[part->totkey - 1].weight;
+	}
+	else {
+		float interp = t / edit_key_seg_t;
+		int index = (int)interp;
+		interp -= floorf(interp); /* Time between 2 edit key */
+		float s1 = hkeys[index].weight;
+		float s2 = hkeys[index+1].weight;
+		return s1 + interp * (s2 - s1);
+	}
+}
+
 static int particle_batch_cache_fill_segments_edit(
-        const PTCacheEdit *edit,
+        const PTCacheEdit *edit, /* NULL for weight data */
+        const ParticleData *particle, /* NULL for select data */
         ParticleCacheKey **path_cache,
         const int start_index,
         const int num_path_keys,
@@ -710,8 +730,15 @@ static int particle_batch_cache_fill_segments_edit(
 			EditStrandData *seg_data = (EditStrandData *)GPU_vertbuf_raw_step(attr_step);
 			copy_v3_v3(seg_data->pos, path[j].co);
 			float strand_t = (float)(j) / path->segments;
-			float selected = particle_key_select_ratio(edit, i, strand_t);
-			seg_data->color = (uchar)(0xFF * selected);
+			if (particle) {
+				float weight = particle_key_weight(particle, i, strand_t);
+				/* NaN or unclamped become 0xFF */
+				seg_data->color = (uchar)((weight <= 1.0f) ? 0xFE * weight : 0xFF);
+			}
+			else {
+				float selected = particle_key_select_ratio(edit, i, strand_t);
+				seg_data->color = (uchar)(0xFF * selected);
+			}
 			GPU_indexbuf_add_generic_vert(elb, curr_point);
 			curr_point++;
 		}
@@ -1436,14 +1463,17 @@ GPUBatch *DRW_particles_batch_cache_get_dots(Object *object, ParticleSystem *psy
 
 static void particle_batch_cache_ensure_edit_pos_and_seg(
         PTCacheEdit *edit,
-        ParticleSystem *UNUSED(psys),
+        ParticleSystem *psys,
         ModifierData *UNUSED(md),
-        ParticleHairCache *hair_cache)
+        ParticleHairCache *hair_cache,
+        bool use_weight)
 {
 	if (hair_cache->pos != NULL && hair_cache->indices != NULL) {
 		return;
 	}
 
+	ParticleData *particle = (use_weight) ? psys->particles : NULL;
+
 	GPU_VERTBUF_DISCARD_SAFE(hair_cache->pos);
 	GPU_INDEXBUF_DISCARD_SAFE(hair_cache->indices);
 
@@ -1464,7 +1494,7 @@ static void particle_batch_cache_ensure_edit_pos_and_seg(
 
 	if (edit != NULL && edit->pathcache != NULL) {
 		particle_batch_cache_fill_segments_edit(
-		        edit, edit->pathcache,
+		        edit, particle, edit->pathcache,
 		        0, edit->totcached,
 		        &elb, &data_step);
 	}
@@ -1477,19 +1507,25 @@ static void particle_batch_cache_ensure_edit_pos_and_seg(
 GPUBatch *DRW_particles_batch_cache_get_edit_strands(
         Object *object,
         ParticleSystem *psys,
-        PTCacheEdit *edit)
+        PTCacheEdit *edit,
+        bool use_weight)
 {
 	ParticleBatchCache *cache = particle_batch_cache_get(psys);
+	if (cache->edit_is_weight != use_weight) {
+		GPU_VERTBUF_DISCARD_SAFE(cache->edit_hair.pos);
+		GPU_BATCH_DISCARD_SAFE(cache->edit_hair.hairs);
+	}
 	if (cache->edit_hair.hairs != NULL) {
 		return cache->edit_hair.hairs;
 	}
 	drw_particle_update_ptcache_edit(object, psys, edit);
 	ensure_seg_pt_count(edit, psys, &cache->edit_hair);
-	particle_batch_cache_ensure_edit_pos_and_seg(edit, psys, NULL, &cache->edit_hair);
+	particle_batch_cache_ensure_edit_pos_and_seg(edit, psys, NULL, &cache->edit_hair, use_weight);
 	cache->edit_hair.hairs = GPU_batch_create(
 	        GPU_PRIM_LINE_STRIP,
 	        cache->edit_hair.pos,
 	        cache->edit_hair.indices);
+	cache->edit_is_weight = use_weight;
 	return cache->edit_hair.hairs;
 }
 
diff --git a/source/blender/draw/modes/particle_mode.c b/source/blender/draw/modes/particle_mode.c
index 9f0f18bf1d0..758218fe329 100644
--- a/source/blender/draw/modes/particle_mode.c
+++ b/source/blender/draw/modes/particle_mode.c
@@ -83,6 +83,7 @@ typedef struct PARTICLE_Data {
 
 static struct {
 	struct GPUShader *strands_shader;
+	struct GPUShader *strands_weight_shader;
 	struct GPUShader *points_shader;
 } e_data = {NULL}; /* Engine data */
 
@@ -104,6 +105,13 @@ static void particle_engine_init(void *UNUSED(vedata))
 		        datatoc_common_globals_lib_glsl,
 		        "");
 
+		e_data.strands_weight_shader = DRW_shader_create_with_lib(
+		        datatoc_particle_strand_vert_glsl,
+		        NULL,
+		        datatoc_particle_strand_frag_glsl,
+		        datatoc_common_globals_lib_glsl,
+		        "#define USE_WEIGHT");
+
 		e_data.points_shader = DRW_shader_create_with_lib(
 		        datatoc_particle_strand_vert_glsl,
 		        NULL,
@@ -117,6 +125,9 @@ static void particle_cache_init(void *vedata)
 {
 	PARTICLE_PassList *psl = ((PARTICLE_Data *)vedata)->psl;
 	PARTICLE_StorageList *stl = ((PARTICLE_Data *)vedata)->stl;
+	const DRWContextState *draw_ctx = DRW_context_state_get();
+	ParticleEditSettings *pset = PE_settings(draw_ctx->scene);
+	const bool use_weight = (pset->brushtype == PE_BRUSH_WEIGHT);
 
 	if (!stl->g_data) {
 		/* Alloc transient pointers */
@@ -131,12 +142,10 @@ static void particle_cache_init(void *vedata)
 	                                       DRW_STATE_WIRE |
 	                                       DRW_STATE_POINT));
 
-	stl->g_data->strands_group = DRW_shgroup_create(
-	        e_data.strands_shader, psl->psys_edit_pass);
-	stl->g_data->inner_points_group = DRW_shgroup_create(
-	        e_data.points_shader, psl->psys_edit_pass);
-	stl->g_data->tip_points_group = DRW_shgroup_create(
-	        e_data.points_shader, psl->psys_edit_pass);
+	GPUShader *strand_shader = (use_weight) ? e_data.strands_weight_shader : e_data.strands_shader;
+	stl->g_data->strands_group = DRW_shgroup_create(strand_shader, psl->psys_edit_pass);
+	stl->g_data->inner_points_group = DRW_shgroup_create(e_data.points_shader, psl->psys_edit_pass);
+	stl->g_data->tip_points_group = DRW_shgroup_create(e_data.points_shader, psl->psys_edit_pass);
 
 	DRW_shgroup_uniform_block(stl->g_data->strands_group, "globalsBlock", globals_ubo);
 	DRW_shgroup_uniform_block(stl->g_data->inner_points_group, "globalsBlock", globals_ubo);
@@ -151,9 +160,10 @@ static void particle_edit_cache_populate(void *vedata,
 	PARTICLE_StorageList *stl = ((PARTICLE_Data *)vedata)->stl;
 	const DRWContextState *draw_ctx = DRW_context_state_get();
 	ParticleEditSettings *pset = PE_settings(draw_ctx->scene);
+	const bool use_weight = (pset->brushtype == PE_BRUSH_WEIGHT);
 	{
 		struct GPUBatch *strands =
-		        DRW_cache_particles_get_edit_strands(object, psys, edit);
+		        DRW_cache_particles_get_edit_strands(object, psys, edit, use_weight);
 		DRW_shgroup_call_add(stl->g_data->strands_group, strands, NULL);
 	}
 	if (pset->selectmode == SCE_SELECT_POINT) {
@@ -229,6 +239,7 @@ static void particle_draw_scene(void *vedata)
 static void particle_engine_free(void)
 {
 	DRW_SHADER_FREE_SAFE(e_data.strands_shader);
+	DRW_SHADER_FREE_SAFE(e_data.strands_weight_shader);
 	DRW_SHADER_FREE_SAFE(e_data.points_shader);
 }
 
diff --git a/source/blender/draw/modes/shaders/particle_strand_vert.glsl b/source/

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list