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:
authorJacques Lucke <jacques@blender.org>2020-09-29 13:39:41 +0300
committerJacques Lucke <jacques@blender.org>2020-09-29 13:39:41 +0300
commite12767a0352a9e113892b4a07c6c8446d3ff361f (patch)
tree9fe48bb33bda0256e1421f34714bc22668d7b06e /source/blender/draw
parent6374644fd11797806ab2e92341e5e7d32e94067b (diff)
Volumes: support selection and outlines in viewport
Previously, one could only select a volume object in the outliner or by clicking on the object origin. This patch allows you to click on the actual volume. Furthermore, the generated (invisible) mesh that is used for selection is also used to draw an outline for the volume object now. Reviewers: brecht Differential Revision: https://developer.blender.org/D9022
Diffstat (limited to 'source/blender/draw')
-rw-r--r--source/blender/draw/CMakeLists.txt1
-rw-r--r--source/blender/draw/engines/overlay/overlay_engine.c6
-rw-r--r--source/blender/draw/engines/overlay/overlay_outline.c16
-rw-r--r--source/blender/draw/engines/overlay/overlay_private.h6
-rw-r--r--source/blender/draw/engines/overlay/overlay_volume.c67
-rw-r--r--source/blender/draw/intern/draw_cache.c6
-rw-r--r--source/blender/draw/intern/draw_cache.h1
-rw-r--r--source/blender/draw/intern/draw_cache_impl.h1
-rw-r--r--source/blender/draw/intern/draw_cache_impl_volume.c47
9 files changed, 151 insertions, 0 deletions
diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt
index 11aea544c65..4e72e89ae99 100644
--- a/source/blender/draw/CMakeLists.txt
+++ b/source/blender/draw/CMakeLists.txt
@@ -146,6 +146,7 @@ set(SRC
engines/overlay/overlay_particle.c
engines/overlay/overlay_sculpt.c
engines/overlay/overlay_shader.c
+ engines/overlay/overlay_volume.c
engines/overlay/overlay_wireframe.c
DRW_engine.h
diff --git a/source/blender/draw/engines/overlay/overlay_engine.c b/source/blender/draw/engines/overlay/overlay_engine.c
index fb235a1ff57..5a87af7238e 100644
--- a/source/blender/draw/engines/overlay/overlay_engine.c
+++ b/source/blender/draw/engines/overlay/overlay_engine.c
@@ -207,6 +207,7 @@ static void OVERLAY_cache_init(void *vedata)
OVERLAY_outline_cache_init(vedata);
OVERLAY_particle_cache_init(vedata);
OVERLAY_wireframe_cache_init(vedata);
+ OVERLAY_volume_cache_init(vedata);
}
BLI_INLINE OVERLAY_DupliData *OVERLAY_duplidata_get(Object *ob, void *vedata, bool *do_init)
@@ -355,6 +356,10 @@ static void OVERLAY_cache_populate(void *vedata, Object *ob)
OVERLAY_pose_cache_populate(vedata, ob);
}
+ if (ob->type == OB_VOLUME) {
+ OVERLAY_volume_cache_populate(vedata, ob);
+ }
+
if (in_edit_mode && !pd->hide_overlays) {
switch (ob->type) {
case OB_MESH:
@@ -551,6 +556,7 @@ static void OVERLAY_draw_scene(void *vedata)
OVERLAY_particle_draw(vedata);
OVERLAY_metaball_draw(vedata);
OVERLAY_gpencil_draw(vedata);
+ OVERLAY_volume_draw(vedata);
OVERLAY_extra_draw(vedata);
if (DRW_state_is_fbo()) {
diff --git a/source/blender/draw/engines/overlay/overlay_outline.c b/source/blender/draw/engines/overlay/overlay_outline.c
index e904066248f..f1467ff9794 100644
--- a/source/blender/draw/engines/overlay/overlay_outline.c
+++ b/source/blender/draw/engines/overlay/overlay_outline.c
@@ -272,6 +272,17 @@ static void OVERLAY_outline_gpencil(OVERLAY_PrivateData *pd, Object *ob)
pd->cfra);
}
+static void OVERLAY_outline_volume(OVERLAY_PrivateData *pd, Object *ob)
+{
+ struct GPUBatch *geom = DRW_cache_volume_selection_surface_get(ob);
+ if (geom == NULL) {
+ return;
+ }
+
+ DRWShadingGroup *shgroup = pd->outlines_grp;
+ DRW_shgroup_call(shgroup, geom, ob);
+}
+
void OVERLAY_outline_cache_populate(OVERLAY_Data *vedata,
Object *ob,
OVERLAY_DupliData *dupli,
@@ -293,6 +304,11 @@ void OVERLAY_outline_cache_populate(OVERLAY_Data *vedata,
return;
}
+ if (ob->type == OB_VOLUME) {
+ OVERLAY_outline_volume(pd, ob);
+ return;
+ }
+
if (ob->type == OB_POINTCLOUD && pd->wireframe_mode) {
/* Looks bad in this case. Could be relaxed if we draw a
* wireframe of some sort in the future. */
diff --git a/source/blender/draw/engines/overlay/overlay_private.h b/source/blender/draw/engines/overlay/overlay_private.h
index 2cf2ca34801..ada2c2c8d1f 100644
--- a/source/blender/draw/engines/overlay/overlay_private.h
+++ b/source/blender/draw/engines/overlay/overlay_private.h
@@ -119,6 +119,7 @@ typedef struct OVERLAY_PassList {
DRWPass *particle_ps;
DRWPass *pointcloud_ps;
DRWPass *sculpt_mask_ps;
+ DRWPass *volume_ps;
DRWPass *wireframe_ps;
DRWPass *wireframe_xray_ps;
DRWPass *xray_fade_ps;
@@ -285,6 +286,7 @@ typedef struct OVERLAY_PrivateData {
DRWShadingGroup *particle_shapes_grp;
DRWShadingGroup *pointcloud_dots_grp;
DRWShadingGroup *sculpt_mask_grp;
+ DRWShadingGroup *volume_selection_surface_grp;
DRWShadingGroup *wires_grp[2][2]; /* With and without coloring. */
DRWShadingGroup *wires_all_grp[2][2]; /* With and without coloring. */
DRWShadingGroup *wires_hair_grp[2][2]; /* With and without coloring. */
@@ -511,6 +513,10 @@ void OVERLAY_edit_text_cache_init(OVERLAY_Data *vedata);
void OVERLAY_edit_text_cache_populate(OVERLAY_Data *vedata, Object *ob);
void OVERLAY_edit_text_draw(OVERLAY_Data *vedata);
+void OVERLAY_volume_cache_init(OVERLAY_Data *vedata);
+void OVERLAY_volume_cache_populate(OVERLAY_Data *vedata, Object *ob);
+void OVERLAY_volume_draw(OVERLAY_Data *vedata);
+
void OVERLAY_edit_mesh_init(OVERLAY_Data *vedata);
void OVERLAY_edit_mesh_cache_init(OVERLAY_Data *vedata);
void OVERLAY_edit_mesh_cache_populate(OVERLAY_Data *vedata, Object *ob);
diff --git a/source/blender/draw/engines/overlay/overlay_volume.c b/source/blender/draw/engines/overlay/overlay_volume.c
new file mode 100644
index 00000000000..ffa664c90d5
--- /dev/null
+++ b/source/blender/draw/engines/overlay/overlay_volume.c
@@ -0,0 +1,67 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/** \file
+ * \ingroup draw_engine
+ */
+
+#include "DNA_volume_types.h"
+
+#include "DRW_render.h"
+#include "GPU_shader.h"
+
+#include "overlay_private.h"
+
+void OVERLAY_volume_cache_init(OVERLAY_Data *vedata)
+{
+ OVERLAY_PassList *psl = vedata->psl;
+ OVERLAY_PrivateData *pd = vedata->stl->pd;
+ const bool is_select = DRW_state_is_select();
+
+ if (is_select) {
+ DRWState state = DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL;
+ DRW_PASS_CREATE(psl->volume_ps, state | pd->clipping_state);
+ GPUShader *sh = OVERLAY_shader_depth_only();
+ DRWShadingGroup *grp = DRW_shgroup_create(sh, psl->volume_ps);
+ pd->volume_selection_surface_grp = grp;
+ DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
+ }
+}
+
+void OVERLAY_volume_cache_populate(OVERLAY_Data *vedata, Object *ob)
+{
+ OVERLAY_PrivateData *pd = vedata->stl->pd;
+ const bool is_select = DRW_state_is_select();
+
+ if (is_select) {
+ struct GPUBatch *geom = DRW_cache_volume_selection_surface_get(ob);
+ if (geom != NULL) {
+ DRW_shgroup_call(pd->volume_selection_surface_grp, geom, ob);
+ }
+ }
+}
+
+void OVERLAY_volume_draw(OVERLAY_Data *vedata)
+{
+ OVERLAY_PassList *psl = vedata->psl;
+ OVERLAY_FramebufferList *fbl = vedata->fbl;
+
+ if (DRW_state_is_fbo()) {
+ GPU_framebuffer_bind(fbl->overlay_default_fb);
+ }
+
+ DRW_draw_pass(psl->volume_ps);
+}
diff --git a/source/blender/draw/intern/draw_cache.c b/source/blender/draw/intern/draw_cache.c
index 0fbc9e2ed82..52e7e91a995 100644
--- a/source/blender/draw/intern/draw_cache.c
+++ b/source/blender/draw/intern/draw_cache.c
@@ -3279,6 +3279,12 @@ GPUBatch *DRW_cache_volume_face_wireframe_get(Object *ob)
return DRW_volume_batch_cache_get_wireframes_face(ob->data);
}
+GPUBatch *DRW_cache_volume_selection_surface_get(Object *ob)
+{
+ BLI_assert(ob->type == OB_VOLUME);
+ return DRW_volume_batch_cache_get_selection_surface(ob->data);
+}
+
/** \} */
/* -------------------------------------------------------------------- */
diff --git a/source/blender/draw/intern/draw_cache.h b/source/blender/draw/intern/draw_cache.h
index 7164a477d8a..5da9f4b7964 100644
--- a/source/blender/draw/intern/draw_cache.h
+++ b/source/blender/draw/intern/draw_cache.h
@@ -236,6 +236,7 @@ typedef struct DRWVolumeGrid {
DRWVolumeGrid *DRW_volume_batch_cache_get_grid(struct Volume *volume, struct VolumeGrid *grid);
struct GPUBatch *DRW_cache_volume_face_wireframe_get(struct Object *ob);
+struct GPUBatch *DRW_cache_volume_selection_surface_get(struct Object *ob);
/* GPencil */
struct GPUBatch *DRW_cache_gpencil_strokes_get(struct Object *ob, int cfra);
diff --git a/source/blender/draw/intern/draw_cache_impl.h b/source/blender/draw/intern/draw_cache_impl.h
index 9e7a2e2916c..e5cc18f6e09 100644
--- a/source/blender/draw/intern/draw_cache_impl.h
+++ b/source/blender/draw/intern/draw_cache_impl.h
@@ -152,6 +152,7 @@ struct GPUBatch **DRW_cache_pointcloud_surface_shaded_get(struct Object *ob,
int DRW_volume_material_count_get(struct Volume *volume);
struct GPUBatch *DRW_volume_batch_cache_get_wireframes_face(struct Volume *volume);
+struct GPUBatch *DRW_volume_batch_cache_get_selection_surface(struct Volume *volume);
/* Mesh */
void DRW_mesh_batch_cache_create_requested(struct TaskGraph *task_graph,
diff --git a/source/blender/draw/intern/draw_cache_impl_volume.c b/source/blender/draw/intern/draw_cache_impl_volume.c
index e39c4976e38..7b03070e32b 100644
--- a/source/blender/draw/intern/draw_cache_impl_volume.c
+++ b/source/blender/draw/intern/draw_cache_impl_volume.c
@@ -62,6 +62,9 @@ typedef struct VolumeBatchCache {
GPUBatch *batch;
} face_wire;
+ /* Surface for selection */
+ GPUBatch *selection_surface;
+
/* settings to determine if cache is invalid */
bool is_dirty;
} VolumeBatchCache;
@@ -132,6 +135,7 @@ static void volume_batch_cache_clear(Volume *volume)
GPU_VERTBUF_DISCARD_SAFE(cache->face_wire.pos_nor_in_order);
GPU_BATCH_DISCARD_SAFE(cache->face_wire.batch);
+ GPU_BATCH_DISCARD_SAFE(cache->selection_surface);
}
void DRW_volume_batch_cache_free(Volume *volume)
@@ -209,6 +213,49 @@ GPUBatch *DRW_volume_batch_cache_get_wireframes_face(Volume *volume)
return cache->face_wire.batch;
}
+static void drw_volume_selection_surface_cb(
+ void *userdata, float (*verts)[3], int (*tris)[3], int totvert, int tottris)
+{
+ Volume *volume = userdata;
+ VolumeBatchCache *cache = volume->batch_cache;
+
+ static GPUVertFormat format = {0};
+ static uint pos_id;
+ if (format.attr_len == 0) {
+ pos_id = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
+ }
+
+ /* Create vertex buffer. */
+ GPUVertBuf *vbo_surface = GPU_vertbuf_create_with_format(&format);
+ GPU_vertbuf_data_alloc(vbo_surface, totvert);
+ GPU_vertbuf_attr_fill(vbo_surface, pos_id, verts);
+
+ /* Create index buffer. */
+ GPUIndexBufBuilder elb;
+ GPU_indexbuf_init(&elb, GPU_PRIM_TRIS, tottris, totvert);
+ for (int i = 0; i < tottris; i++) {
+ GPU_indexbuf_add_tri_verts(&elb, UNPACK3(tris[i]));
+ }
+ GPUIndexBuf *ibo_surface = GPU_indexbuf_build(&elb);
+
+ cache->selection_surface = GPU_batch_create_ex(
+ GPU_PRIM_TRIS, vbo_surface, ibo_surface, GPU_BATCH_OWNS_VBO | GPU_BATCH_OWNS_INDEX);
+}
+
+GPUBatch *DRW_volume_batch_cache_get_selection_surface(Volume *volume)
+{
+ VolumeBatchCache *cache = volume_batch_cache_get(volume);
+ if (cache->selection_surface == NULL) {
+ VolumeGrid *volume_grid = BKE_volume_grid_active_get(volume);
+ if (volume_grid == NULL) {
+ return NULL;
+ }
+ BKE_volume_grid_selection_surface(
+ volume, volume_grid, drw_volume_selection_surface_cb, volume);
+ }
+ return cache->selection_surface;
+}
+
static DRWVolumeGrid *volume_grid_cache_get(Volume *volume,
VolumeGrid *grid,
VolumeBatchCache *cache)