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:
Diffstat (limited to 'source/blender/draw/intern/draw_cache_impl_volume.c')
-rw-r--r--source/blender/draw/intern/draw_cache_impl_volume.c88
1 files changed, 62 insertions, 26 deletions
diff --git a/source/blender/draw/intern/draw_cache_impl_volume.c b/source/blender/draw/intern/draw_cache_impl_volume.c
index 10b9623175c..1a9e40fb03b 100644
--- a/source/blender/draw/intern/draw_cache_impl_volume.c
+++ b/source/blender/draw/intern/draw_cache_impl_volume.c
@@ -42,6 +42,8 @@
#include "GPU_batch.h"
#include "GPU_texture.h"
+#include "DEG_depsgraph_query.h"
+
#include "DRW_render.h"
#include "draw_cache.h" /* own include */
@@ -62,6 +64,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 +137,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 +215,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)
@@ -238,39 +287,26 @@ static DRWVolumeGrid *volume_grid_cache_get(Volume *volume,
return cache_grid;
}
- /* Load grid tree into memory, if not loaded already. */
+ /* Remember if grid was loaded. If it was not, we want to unload it after the GPUTexture has been
+ * created. */
const bool was_loaded = BKE_volume_grid_is_loaded(grid);
- BKE_volume_grid_load(volume, grid);
-
- /* Compute dense voxel grid size. */
- int64_t dense_min[3], dense_max[3], resolution[3] = {0};
- if (BKE_volume_grid_dense_bounds(volume, grid, dense_min, dense_max)) {
- resolution[0] = dense_max[0] - dense_min[0];
- resolution[1] = dense_max[1] - dense_min[1];
- resolution[2] = dense_max[2] - dense_min[2];
- }
- size_t num_voxels = resolution[0] * resolution[1] * resolution[2];
- size_t elem_size = sizeof(float) * channels;
- /* Allocate and load voxels. */
- float *voxels = (num_voxels > 0) ? MEM_malloc_arrayN(num_voxels, elem_size, __func__) : NULL;
- if (voxels != NULL) {
- BKE_volume_grid_dense_voxels(volume, grid, dense_min, dense_max, voxels);
+ DenseFloatVolumeGrid dense_grid;
+ if (BKE_volume_grid_dense_floats(volume, grid, &dense_grid)) {
+ copy_m4_m4(cache_grid->texture_to_object, dense_grid.texture_to_object);
+ invert_m4_m4(cache_grid->object_to_texture, dense_grid.texture_to_object);
/* Create GPU texture. */
eGPUTextureFormat format = (channels == 3) ? GPU_RGB16F : GPU_R16F;
- cache_grid->texture = GPU_texture_create_3d(
- "volume_grid", UNPACK3(resolution), 1, format, voxels);
-
+ cache_grid->texture = GPU_texture_create_3d("volume_grid",
+ UNPACK3(dense_grid.resolution),
+ 1,
+ format,
+ GPU_DATA_FLOAT,
+ dense_grid.voxels);
GPU_texture_swizzle_set(cache_grid->texture, (channels == 3) ? "rgb1" : "rrr1");
GPU_texture_wrap_mode(cache_grid->texture, false, false);
-
- MEM_freeN(voxels);
-
- /* Compute transform matrices. */
- BKE_volume_grid_dense_transform_matrix(
- grid, dense_min, dense_max, cache_grid->texture_to_object);
- invert_m4_m4(cache_grid->object_to_texture, cache_grid->texture_to_object);
+ BKE_volume_dense_float_grid_clear(&dense_grid);
}
/* Free grid from memory if it wasn't previously loaded. */