Draw manager: Implement point selection modes for particle edit mode

This commit is contained in:
Sergey Sharybin
2018-05-09 14:59:29 +02:00
parent 5cea8bf435
commit 6f891e2b87
6 changed files with 153 additions and 46 deletions

View File

@@ -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)

View File

@@ -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 */

View File

@@ -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__ */

View File

@@ -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_points != NULL) {
return cache->edit_points;
if (cache->edit_inner_points != NULL) {
return cache->edit_inner_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;
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_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;
}

View File

@@ -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);
}
}

View File

@@ -1017,7 +1017,7 @@ static void view3d_main_region_listener(
}
static void view3d_main_region_message_subscribe(
const struct bContext *UNUSED(C),
const struct bContext *C,
struct WorkSpace *workspace, struct Scene *scene,
struct bScreen *UNUSED(screen), struct ScrArea *UNUSED(sa), struct ARegion *ar,
struct wmMsgBus *mbus)
@@ -1091,6 +1091,18 @@ static void view3d_main_region_message_subscribe(
WM_msg_subscribe_rna_anon_type(mbus, SceneDisplay, &msg_sub_value_region_tag_redraw);
ViewLayer *view_layer = CTX_data_view_layer(C);
Object *obact = OBACT(view_layer);
if (obact != NULL) {
switch (obact->mode) {
case OB_MODE_PARTICLE_EDIT:
WM_msg_subscribe_rna_anon_type(mbus, ParticleEdit, &msg_sub_value_region_tag_redraw);
break;
default:
break;
}
}
if (workspace->tool.spacetype == SPACE_VIEW3D) {
wmMsgSubscribeValue msg_sub_value_region_tag_refresh = {
.owner = ar,