diff options
author | Sergey Sharybin <sergey.vfx@gmail.com> | 2018-05-09 15:59:29 +0300 |
---|---|---|
committer | Sergey Sharybin <sergey.vfx@gmail.com> | 2018-05-09 16:00:29 +0300 |
commit | 6f891e2b87fa44714ce66c7aff1b402603f48ff9 (patch) | |
tree | 9d038678a4e60fad9b766ed4120f7e3cad6ec0cd /source/blender/draw | |
parent | 5cea8bf4355dbe9d0ad5170d123b15e9babfa51a (diff) |
Draw manager: Implement point selection modes for particle edit mode
Diffstat (limited to 'source/blender/draw')
-rw-r--r-- | source/blender/draw/intern/draw_cache.c | 9 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_cache.h | 3 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_cache_impl.h | 3 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_cache_impl_particles.c | 147 | ||||
-rw-r--r-- | source/blender/draw/modes/particle_mode.c | 25 |
5 files changed, 141 insertions, 46 deletions
diff --git a/source/blender/draw/intern/draw_cache.c b/source/blender/draw/intern/draw_cache.c index 95193bebaea..38ec9cff7f4 100644 --- a/source/blender/draw/intern/draw_cache.c +++ b/source/blender/draw/intern/draw_cache.c @@ -2891,9 +2891,14 @@ Gwn_Batch *DRW_cache_particles_get_edit_strands(struct PTCacheEdit *edit) return DRW_particles_batch_cache_get_edit_strands(edit); } -Gwn_Batch *DRW_cache_particles_get_edit_points(struct PTCacheEdit *edit) +Gwn_Batch *DRW_cache_particles_get_edit_inner_points(struct PTCacheEdit *edit) { - return DRW_particles_batch_cache_get_edit_points(edit); + return DRW_particles_batch_cache_get_edit_inner_points(edit); +} + +Gwn_Batch *DRW_cache_particles_get_edit_tip_points(struct PTCacheEdit *edit) +{ + return DRW_particles_batch_cache_get_edit_tip_points(edit); } Gwn_Batch *DRW_cache_particles_get_prim(int type) diff --git a/source/blender/draw/intern/draw_cache.h b/source/blender/draw/intern/draw_cache.h index e726e25431f..66db405786d 100644 --- a/source/blender/draw/intern/draw_cache.h +++ b/source/blender/draw/intern/draw_cache.h @@ -170,7 +170,8 @@ struct Gwn_Batch *DRW_cache_lattice_vert_overlay_get(struct Object *ob); struct Gwn_Batch *DRW_cache_particles_get_hair(struct ParticleSystem *psys, struct ModifierData *md); struct Gwn_Batch *DRW_cache_particles_get_dots(struct Object *object, struct ParticleSystem *psys); struct Gwn_Batch *DRW_cache_particles_get_edit_strands(struct PTCacheEdit *edit); -struct Gwn_Batch *DRW_cache_particles_get_edit_points(struct PTCacheEdit *edit); +struct Gwn_Batch *DRW_cache_particles_get_edit_inner_points(struct PTCacheEdit *edit); +struct Gwn_Batch *DRW_cache_particles_get_edit_tip_points(struct PTCacheEdit *edit); struct Gwn_Batch *DRW_cache_particles_get_prim(int type); /* Metaball */ diff --git a/source/blender/draw/intern/draw_cache_impl.h b/source/blender/draw/intern/draw_cache_impl.h index 84c7825c6f9..4e3c56eb427 100644 --- a/source/blender/draw/intern/draw_cache_impl.h +++ b/source/blender/draw/intern/draw_cache_impl.h @@ -126,6 +126,7 @@ void DRW_mesh_cache_sculpt_coords_ensure(struct Mesh *me); struct Gwn_Batch *DRW_particles_batch_cache_get_hair(struct ParticleSystem *psys, struct ModifierData *md); struct Gwn_Batch *DRW_particles_batch_cache_get_dots(struct Object *object, struct ParticleSystem *psys); struct Gwn_Batch *DRW_particles_batch_cache_get_edit_strands(struct PTCacheEdit *edit); -struct Gwn_Batch *DRW_particles_batch_cache_get_edit_points(struct PTCacheEdit *edit); +struct Gwn_Batch *DRW_particles_batch_cache_get_edit_inner_points(struct PTCacheEdit *edit); +struct Gwn_Batch *DRW_particles_batch_cache_get_edit_tip_points(struct PTCacheEdit *edit); #endif /* __DRAW_CACHE_IMPL_H__ */ diff --git a/source/blender/draw/intern/draw_cache_impl_particles.c b/source/blender/draw/intern/draw_cache_impl_particles.c index 065628f3f68..0bf2ea4f26c 100644 --- a/source/blender/draw/intern/draw_cache_impl_particles.c +++ b/source/blender/draw/intern/draw_cache_impl_particles.c @@ -70,9 +70,13 @@ typedef struct ParticleBatchCache { int point_count; /* Control points when in edit mode. */ - Gwn_VertBuf *edit_pos; - Gwn_Batch *edit_points; - int edit_point_count; + Gwn_VertBuf *edit_inner_pos; + Gwn_Batch *edit_inner_points; + int edit_inner_point_count; + + Gwn_VertBuf *edit_tip_pos; + Gwn_Batch *edit_tip_points; + int edit_tip_point_count; /* Settings to determine if cache is invalid. */ bool is_dirty; @@ -153,8 +157,10 @@ static void particle_batch_cache_clear(ParticleSystem *psys) GWN_VERTBUF_DISCARD_SAFE(cache->pos); GWN_INDEXBUF_DISCARD_SAFE(cache->indices); - GWN_BATCH_DISCARD_SAFE(cache->edit_points); - GWN_VERTBUF_DISCARD_SAFE(cache->edit_pos); + GWN_BATCH_DISCARD_SAFE(cache->edit_inner_points); + GWN_VERTBUF_DISCARD_SAFE(cache->edit_inner_pos); + GWN_BATCH_DISCARD_SAFE(cache->edit_tip_points); + GWN_VERTBUF_DISCARD_SAFE(cache->edit_tip_pos); } void DRW_particle_batch_cache_free(ParticleSystem *psys) @@ -600,30 +606,42 @@ Gwn_Batch *DRW_particles_batch_cache_get_edit_strands(PTCacheEdit *edit) return cache->hairs; } -static void ensure_edit_points_count(const PTCacheEdit *edit, - ParticleBatchCache *cache) +static void ensure_edit_inner_points_count(const PTCacheEdit *edit, + ParticleBatchCache *cache) { - if (cache->edit_pos != NULL) { + if (cache->edit_inner_pos != NULL) { return; } - cache->edit_point_count = 0; + cache->edit_inner_point_count = 0; for (int point_index = 0; point_index < edit->totpoint; point_index++) { const PTCacheEditPoint *point = &edit->points[point_index]; - cache->edit_point_count += point->totkey; + BLI_assert(point->totkey >= 1); + cache->edit_inner_point_count += (point->totkey - 1); } } -static void particle_batch_cache_ensure_edit_pos(PTCacheEdit *edit, - ParticleBatchCache *cache) +static void edit_colors_get(PTCacheEdit *edit, + float selected_color[4], + float normal_color[4]) { - if (cache->edit_pos != NULL) { + rgb_uchar_to_float(selected_color, edit->sel_col); + rgb_uchar_to_float(normal_color, edit->nosel_col); + selected_color[3] = 1.0f; + normal_color[3] = 1.0f; +} + +static void particle_batch_cache_ensure_edit_inner_pos( + PTCacheEdit *edit, + ParticleBatchCache *cache) +{ + if (cache->edit_inner_pos != NULL) { return; } static Gwn_VertFormat format = { 0 }; static unsigned pos_id, color_id; - GWN_VERTBUF_DISCARD_SAFE(cache->edit_pos); + GWN_VERTBUF_DISCARD_SAFE(cache->edit_inner_pos); if (format.attrib_ct == 0) { /* initialize vertex format */ @@ -631,43 +649,102 @@ static void particle_batch_cache_ensure_edit_pos(PTCacheEdit *edit, color_id = GWN_vertformat_attr_add(&format, "color", GWN_COMP_F32, 4, GWN_FETCH_FLOAT); } - cache->edit_pos = GWN_vertbuf_create_with_format(&format); - GWN_vertbuf_data_alloc(cache->edit_pos, cache->edit_point_count); + cache->edit_inner_pos = GWN_vertbuf_create_with_format(&format); + GWN_vertbuf_data_alloc(cache->edit_inner_pos, cache->edit_inner_point_count); - /* Convert theme colors from uchar[3] to float[4]. */ - float selected_color[4] = {0.0f, 0.0f, 0.0f, 1.0f}; - float normal_color[4] = {0.0f, 0.0f, 0.0f, 1.0f}; - rgb_uchar_to_float(selected_color, edit->sel_col); - rgb_uchar_to_float(normal_color, edit->nosel_col); + float selected_color[4], normal_color[4]; + edit_colors_get(edit, selected_color, normal_color); int global_key_index = 0; for (int point_index = 0; point_index < edit->totpoint; point_index++) { const PTCacheEditPoint *point = &edit->points[point_index]; - for (int key_index = 0; key_index < point->totkey; key_index++) { + for (int key_index = 0; key_index < point->totkey - 1; key_index++) { PTCacheEditKey *key = &point->keys[key_index]; - GWN_vertbuf_attr_set(cache->edit_pos, pos_id, global_key_index, key->world_co); + GWN_vertbuf_attr_set(cache->edit_inner_pos, pos_id, global_key_index, key->world_co); if (key->flag & PEK_SELECT) { - GWN_vertbuf_attr_set(cache->edit_pos, color_id, global_key_index, selected_color); + GWN_vertbuf_attr_set(cache->edit_inner_pos, color_id, global_key_index, selected_color); } else { - GWN_vertbuf_attr_set(cache->edit_pos, color_id, global_key_index, normal_color); + GWN_vertbuf_attr_set(cache->edit_inner_pos, color_id, global_key_index, normal_color); } global_key_index++; } } } -Gwn_Batch *DRW_particles_batch_cache_get_edit_points(PTCacheEdit *edit) +Gwn_Batch *DRW_particles_batch_cache_get_edit_inner_points(PTCacheEdit *edit) +{ + ParticleSystem *psys = edit->psys; + ParticleBatchCache *cache = particle_batch_cache_get(psys); + if (cache->edit_inner_points != NULL) { + return cache->edit_inner_points; + } + ensure_edit_inner_points_count(edit, cache); + particle_batch_cache_ensure_edit_inner_pos(edit, cache); + cache->edit_inner_points = GWN_batch_create(GWN_PRIM_POINTS, + cache->edit_inner_pos, + NULL); + return cache->edit_inner_points; +} + +static void ensure_edit_tip_points_count(const PTCacheEdit *edit, + ParticleBatchCache *cache) +{ + if (cache->edit_tip_pos != NULL) { + return; + } + cache->edit_tip_point_count = edit->totpoint; +} + +static void particle_batch_cache_ensure_edit_tip_pos( + PTCacheEdit *edit, + ParticleBatchCache *cache) +{ + if (cache->edit_tip_pos != NULL) { + return; + } + + static Gwn_VertFormat format = { 0 }; + static unsigned pos_id, color_id; + + GWN_VERTBUF_DISCARD_SAFE(cache->edit_tip_pos); + + if (format.attrib_ct == 0) { + /* initialize vertex format */ + pos_id = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); + color_id = GWN_vertformat_attr_add(&format, "color", GWN_COMP_F32, 4, GWN_FETCH_FLOAT); + } + + cache->edit_tip_pos = GWN_vertbuf_create_with_format(&format); + GWN_vertbuf_data_alloc(cache->edit_tip_pos, cache->edit_tip_point_count); + + float selected_color[4], normal_color[4]; + edit_colors_get(edit, selected_color, normal_color); + + for (int point_index = 0; point_index < edit->totpoint; point_index++) { + const PTCacheEditPoint *point = &edit->points[point_index]; + PTCacheEditKey *key = &point->keys[point->totkey - 1]; + GWN_vertbuf_attr_set(cache->edit_tip_pos, pos_id, point_index, key->world_co); + if (key->flag & PEK_SELECT) { + GWN_vertbuf_attr_set(cache->edit_tip_pos, color_id, point_index, selected_color); + } + else { + GWN_vertbuf_attr_set(cache->edit_tip_pos, color_id, point_index, normal_color); + } + } +} + +Gwn_Batch *DRW_particles_batch_cache_get_edit_tip_points(PTCacheEdit *edit) { ParticleSystem *psys = edit->psys; ParticleBatchCache *cache = particle_batch_cache_get(psys); - if (cache->edit_points != NULL) { - return cache->edit_points; - } - ensure_edit_points_count(edit, cache); - particle_batch_cache_ensure_edit_pos(edit, cache); - cache->edit_points = GWN_batch_create(GWN_PRIM_POINTS, - cache->edit_pos, - NULL); - return cache->edit_points; + if (cache->edit_tip_points != NULL) { + return cache->edit_tip_points; + } + ensure_edit_tip_points_count(edit, cache); + particle_batch_cache_ensure_edit_tip_pos(edit, cache); + cache->edit_tip_points = GWN_batch_create(GWN_PRIM_POINTS, + cache->edit_tip_pos, + NULL); + return cache->edit_tip_points; } diff --git a/source/blender/draw/modes/particle_mode.c b/source/blender/draw/modes/particle_mode.c index 52d72da0151..91d00589449 100644 --- a/source/blender/draw/modes/particle_mode.c +++ b/source/blender/draw/modes/particle_mode.c @@ -85,7 +85,8 @@ static struct { typedef struct PARTICLE_PrivateData { DRWShadingGroup *strands_group; - DRWShadingGroup *points_group; + DRWShadingGroup *inner_points_group; + DRWShadingGroup *tip_points_group; } PARTICLE_PrivateData; /* Transient data */ /* *********** FUNCTIONS *********** */ @@ -125,25 +126,35 @@ static void particle_cache_init(void *vedata) stl->g_data->strands_group = DRW_shgroup_create( e_data.strands_shader, psl->psys_edit_pass); - stl->g_data->points_group = DRW_shgroup_create( + 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); static float size = 5.0f; - DRW_shgroup_uniform_float(stl->g_data->points_group, "size", &size, 1); static float outline_width = 1.0f; - DRW_shgroup_uniform_float(stl->g_data->points_group, "outlineWidth", &outline_width, 1); + DRW_shgroup_uniform_float(stl->g_data->inner_points_group, "size", &size, 1); + DRW_shgroup_uniform_float(stl->g_data->inner_points_group, "outlineWidth", &outline_width, 1); + DRW_shgroup_uniform_float(stl->g_data->tip_points_group, "size", &size, 1); + DRW_shgroup_uniform_float(stl->g_data->tip_points_group, "outlineWidth", &outline_width, 1); } static void particle_edit_cache_populate(void *vedata, PTCacheEdit *edit) { PARTICLE_StorageList *stl = ((PARTICLE_Data *)vedata)->stl; + const DRWContextState *draw_ctx = DRW_context_state_get(); + ParticleEditSettings *pset= PE_settings(draw_ctx->scene); { struct Gwn_Batch *strands = DRW_cache_particles_get_edit_strands(edit); DRW_shgroup_call_add(stl->g_data->strands_group, strands, NULL); } - { - struct Gwn_Batch *points = DRW_cache_particles_get_edit_points(edit); - DRW_shgroup_call_add(stl->g_data->points_group, points, NULL); + if (pset->selectmode == SCE_SELECT_POINT) { + struct Gwn_Batch *points = DRW_cache_particles_get_edit_inner_points(edit); + DRW_shgroup_call_add(stl->g_data->inner_points_group, points, NULL); + } + if (ELEM(pset->selectmode, SCE_SELECT_POINT, SCE_SELECT_END)) { + struct Gwn_Batch *points = DRW_cache_particles_get_edit_tip_points(edit); + DRW_shgroup_call_add(stl->g_data->tip_points_group, points, NULL); } } |