Blender  V3.3
draw_cache_impl_metaball.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2017 Blender Foundation. All rights reserved. */
3 
10 #include "MEM_guardedalloc.h"
11 
12 #include "BLI_math_base.h"
13 #include "BLI_utildefines.h"
14 
15 #include "DNA_meta_types.h"
16 #include "DNA_object_types.h"
17 
18 #include "BKE_curve.h"
19 #include "BKE_mball.h"
20 
21 #include "GPU_batch.h"
22 
23 #include "DRW_render.h"
24 #include "draw_cache_impl.h" /* own include */
25 
26 static void metaball_batch_cache_clear(MetaBall *mb);
27 
28 /* -------------------------------------------------------------------- */
32 typedef struct MetaBallBatchCache {
35 
36  int mat_len;
37 
38  /* Shared */
40 
41  /* Wireframe */
42  struct {
43  GPUBatch *batch;
45 
46  /* Edge detection */
49 
50  /* settings to determine if cache is invalid */
51  bool is_dirty;
52 
53  /* Valid only if edge_detection is up to date. */
56 
57 /* GPUBatch cache management. */
58 
60 {
61  MetaBallBatchCache *cache = mb->batch_cache;
62 
63  if (cache == NULL) {
64  return false;
65  }
66 
67  return cache->is_dirty == false;
68 }
69 
71 {
72  MetaBallBatchCache *cache = mb->batch_cache;
73 
74  if (!cache) {
75  cache = mb->batch_cache = MEM_mallocN(sizeof(*cache), __func__);
76  }
77  cache->batch = NULL;
78  cache->mat_len = 0;
79  cache->shaded_triangles = NULL;
80  cache->is_dirty = false;
81  cache->pos_nor_in_order = NULL;
82  cache->face_wire.batch = NULL;
83  cache->edge_detection = NULL;
84  cache->edges_adj_lines = NULL;
85  cache->is_manifold = false;
86 }
87 
89 {
90  if (!metaball_batch_cache_valid(mb)) {
93  }
94 }
95 
97 {
98  return mb->batch_cache;
99 }
100 
102 {
103  MetaBallBatchCache *cache = mb->batch_cache;
104  if (cache == NULL) {
105  return;
106  }
107  switch (mode) {
109  cache->is_dirty = true;
110  break;
111  default:
112  BLI_assert(0);
113  }
114 }
115 
117 {
118  MetaBallBatchCache *cache = mb->batch_cache;
119  if (!cache) {
120  return;
121  }
122 
128  /* NOTE: shaded_triangles[0] is already freed by `cache->batch`. */
130  cache->mat_len = 0;
131  cache->is_manifold = false;
132 }
133 
135 {
138 }
139 
141  MetaBallBatchCache *cache,
142  const struct Scene *scene)
143 {
144  if (cache->pos_nor_in_order == NULL) {
145  ListBase *lb = &ob->runtime.curve_cache->disp;
148  }
149  return cache->pos_nor_in_order;
150 }
151 
153 {
154  if (cache->edges_adj_lines == NULL) {
155  ListBase *lb = &ob->runtime.curve_cache->disp;
158  lb, cache->edges_adj_lines, &cache->is_manifold);
159  }
160  return cache->edges_adj_lines;
161 }
162 
165 /* -------------------------------------------------------------------- */
170 {
171  if (!BKE_mball_is_basis(ob)) {
172  return NULL;
173  }
174 
175  MetaBall *mb = ob->data;
177  const DRWContextState *draw_ctx = DRW_context_state_get();
178  const struct Scene *scene = draw_ctx->scene;
179 
180  if (cache->batch == NULL) {
181  ListBase *lb = &ob->runtime.curve_cache->disp;
186  ibo,
188  }
189 
190  return cache->batch;
191 }
192 
194  MetaBall *mb,
195  struct GPUMaterial **UNUSED(gpumat_array),
196  uint gpumat_array_len)
197 {
198  if (!BKE_mball_is_basis(ob)) {
199  return NULL;
200  }
201 
202  BLI_assert(gpumat_array_len == DRW_metaball_material_count_get(mb));
203 
205  if (cache->shaded_triangles == NULL) {
206  cache->mat_len = gpumat_array_len;
207  cache->shaded_triangles = MEM_callocN(sizeof(*cache->shaded_triangles) * cache->mat_len,
208  __func__);
210  for (int i = 1; i < cache->mat_len; i++) {
211  cache->shaded_triangles[i] = NULL;
212  }
213  }
214  return cache->shaded_triangles;
215 }
216 
218 {
219  if (!BKE_mball_is_basis(ob)) {
220  return NULL;
221  }
222 
223  MetaBall *mb = ob->data;
225  const DRWContextState *draw_ctx = DRW_context_state_get();
226  const struct Scene *scene = draw_ctx->scene;
227 
228  if (cache->face_wire.batch == NULL) {
229  ListBase *lb = &ob->runtime.curve_cache->disp;
230 
231  GPUVertBuf *vbo_wiredata = GPU_vertbuf_calloc();
232  DRW_displist_vertbuf_create_wiredata(lb, vbo_wiredata);
233 
236 
240  ibo,
242 
243  GPU_batch_vertbuf_add_ex(cache->face_wire.batch, vbo_wiredata, true);
244  }
245 
246  return cache->face_wire.batch;
247 }
248 
250  bool *r_is_manifold)
251 {
252  if (!BKE_mball_is_basis(ob)) {
253  return NULL;
254  }
255 
256  MetaBall *mb = ob->data;
258  const DRWContextState *draw_ctx = DRW_context_state_get();
259  const struct Scene *scene = draw_ctx->scene;
260 
261  if (cache->edge_detection == NULL) {
266  }
267 
268  if (r_is_manifold) {
269  *r_is_manifold = cache->is_manifold;
270  }
271 
272  return cache->edge_detection;
273 }
274 
276 {
277  if (!BKE_mball_is_basis(ob)) {
278  return NULL;
279  }
280 
281  MetaBall *mb = ob->data;
283  const DRWContextState *draw_ctx = DRW_context_state_get();
284  const struct Scene *scene = draw_ctx->scene;
285 
286  return mball_batch_cache_get_pos_and_normals(ob, cache, scene);
287 }
288 
290 {
291  return max_ii(1, mb->totcol);
292 }
293 
@ BKE_MBALL_BATCH_DIRTY_ALL
Definition: BKE_mball.h:118
bool BKE_mball_is_basis(const struct Object *ob)
#define BLI_assert(a)
Definition: BLI_assert.h:46
MINLINE int max_ii(int a, int b)
unsigned int uint
Definition: BLI_sys_types.h:67
#define UNUSED(x)
Object is a sort of wrapper for general info.
GPUBatch
Definition: GPU_batch.h:78
#define GPU_batch_create(prim, verts, elem)
Definition: GPU_batch.h:95
int GPU_batch_vertbuf_add_ex(GPUBatch *, GPUVertBuf *, bool own_vbo)
Definition: gpu_batch.cc:171
#define GPU_BATCH_DISCARD_SAFE(batch)
Definition: GPU_batch.h:216
GPUBatch * GPU_batch_create_ex(GPUPrimType prim, GPUVertBuf *vert, GPUIndexBuf *elem, eGPUBatchFlag owns_flag)
Definition: gpu_batch.cc:43
@ GPU_BATCH_OWNS_INDEX
Definition: GPU_batch.h:39
struct GPUIndexBuf GPUIndexBuf
#define GPU_INDEXBUF_DISCARD_SAFE(elem)
GPUIndexBuf * GPU_indexbuf_calloc(void)
@ GPU_PRIM_LINES
Definition: GPU_primitive.h:20
@ GPU_PRIM_LINES_ADJ
Definition: GPU_primitive.h:29
@ GPU_PRIM_TRIS
Definition: GPU_primitive.h:21
struct GPUVertBuf GPUVertBuf
GPUVertBuf * GPU_vertbuf_calloc(void)
#define GPU_VERTBUF_DISCARD_SAFE(verts)
Read Guarded memory(de)allocation.
#define MEM_SAFE_FREE(v)
Scene scene
void DRW_displist_indexbuf_create_edges_adjacency_lines(struct ListBase *lb, struct GPUIndexBuf *ibo, bool *r_is_manifold)
void DRW_displist_vertbuf_create_wiredata(struct ListBase *lb, struct GPUVertBuf *vbo)
void DRW_displist_indexbuf_create_triangles_in_order(struct ListBase *lb, struct GPUIndexBuf *ibo)
void DRW_displist_indexbuf_create_lines_in_order(struct ListBase *lb, struct GPUIndexBuf *ibo)
void DRW_displist_vertbuf_create_pos_and_nor(struct ListBase *lb, struct GPUVertBuf *vbo, const struct Scene *scene)
static GPUIndexBuf * mball_batch_cache_get_edges_adj_lines(Object *ob, MetaBallBatchCache *cache)
void DRW_mball_batch_cache_free(MetaBall *mb)
void DRW_mball_batch_cache_validate(MetaBall *mb)
GPUBatch * DRW_metaball_batch_cache_get_triangles_with_normals(Object *ob)
static GPUVertBuf * mball_batch_cache_get_pos_and_normals(Object *ob, MetaBallBatchCache *cache, const struct Scene *scene)
struct MetaBallBatchCache MetaBallBatchCache
GPUBatch * DRW_metaball_batch_cache_get_wireframes_face(Object *ob)
static void metaball_batch_cache_clear(MetaBall *mb)
GPUBatch ** DRW_metaball_batch_cache_get_surface_shaded(Object *ob, MetaBall *mb, struct GPUMaterial **UNUSED(gpumat_array), uint gpumat_array_len)
static bool metaball_batch_cache_valid(MetaBall *mb)
struct GPUVertBuf * DRW_mball_batch_cache_pos_vertbuf_get(Object *ob)
static void metaball_batch_cache_init(MetaBall *mb)
void DRW_mball_batch_cache_dirty_tag(MetaBall *mb, int mode)
static MetaBallBatchCache * metaball_batch_cache_get(MetaBall *mb)
int DRW_metaball_material_count_get(MetaBall *mb)
struct GPUBatch * DRW_metaball_batch_cache_get_edge_detection(struct Object *ob, bool *r_is_manifold)
const DRWContextState * DRW_context_state_get(void)
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:31
void *(* MEM_mallocN)(size_t len, const char *str)
Definition: mallocn.c:33
ListBase disp
Definition: BKE_curve.h:33
struct Scene * scene
Definition: DRW_render.h:979
struct MetaBallBatchCache::@290 face_wire
void * batch_cache
short totcol
struct CurveCache * curve_cache
Object_Runtime runtime
void * data