Blender  V3.3
extract_mesh_vbo_sculpt_data.cc
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2021 Blender Foundation. All rights reserved. */
3 
8 #include "MEM_guardedalloc.h"
9 
10 #include "BLI_string.h"
11 
12 #include "BKE_paint.h"
13 
14 #include "draw_subdivision.h"
15 #include "extract_mesh.hh"
16 
17 namespace blender::draw {
18 
19 /* ---------------------------------------------------------------------- */
24 {
25  static GPUVertFormat format = {0};
26  if (format.attr_len == 0) {
29  }
30  return &format;
31 }
32 
34  MeshBatchCache *UNUSED(cache),
35  void *buf,
36  void *UNUSED(tls_data))
37 {
38  GPUVertBuf *vbo = static_cast<GPUVertBuf *>(buf);
40 
41  CustomData *cd_ldata = (mr->extract_type == MR_EXTRACT_BMESH) ? &mr->bm->ldata : &mr->me->ldata;
42  CustomData *cd_vdata = (mr->extract_type == MR_EXTRACT_BMESH) ? &mr->bm->vdata : &mr->me->vdata;
43  CustomData *cd_pdata = (mr->extract_type == MR_EXTRACT_BMESH) ? &mr->bm->pdata : &mr->me->pdata;
44 
45  const float *cd_mask = (const float *)CustomData_get_layer(cd_vdata, CD_PAINT_MASK);
46  const int *cd_face_set = (const int *)CustomData_get_layer(cd_pdata, CD_SCULPT_FACE_SETS);
47 
50 
51  struct gpuSculptData {
52  uint8_t face_set_color[4];
53  float mask;
54  };
55 
56  gpuSculptData *vbo_data = (gpuSculptData *)GPU_vertbuf_get_data(vbo);
57  const MLoop *loops = (const MLoop *)CustomData_get_layer(cd_ldata, CD_MLOOP);
58 
59  if (mr->extract_type == MR_EXTRACT_BMESH) {
60  int cd_mask_ofs = CustomData_get_offset(cd_vdata, CD_PAINT_MASK);
61  int cd_face_set_ofs = CustomData_get_offset(cd_pdata, CD_SCULPT_FACE_SETS);
62  BMIter f_iter;
63  BMFace *efa;
64  BM_ITER_MESH (efa, &f_iter, mr->bm, BM_FACES_OF_MESH) {
65  BMLoop *l_iter, *l_first;
66  l_iter = l_first = BM_FACE_FIRST_LOOP(efa);
67  do {
68  float v_mask = 0.0f;
69  if (cd_mask) {
70  v_mask = BM_ELEM_CD_GET_FLOAT(l_iter->v, cd_mask_ofs);
71  }
72  vbo_data->mask = v_mask;
73  uchar face_set_color[4] = {UCHAR_MAX, UCHAR_MAX, UCHAR_MAX, UCHAR_MAX};
74  if (cd_face_set) {
75  const int face_set_id = BM_ELEM_CD_GET_INT(l_iter->f, cd_face_set_ofs);
76  if (face_set_id != mr->me->face_sets_color_default) {
78  face_set_id, mr->me->face_sets_color_seed, face_set_color);
79  }
80  }
81  copy_v3_v3_uchar(vbo_data->face_set_color, face_set_color);
82  vbo_data++;
83  } while ((l_iter = l_iter->next) != l_first);
84  }
85  }
86  else {
87  int mp_loop = 0;
88  for (int mp_index = 0; mp_index < mr->poly_len; mp_index++) {
89  const MPoly *p = &mr->mpoly[mp_index];
90  for (int l = 0; l < p->totloop; l++) {
91  float v_mask = 0.0f;
92  if (cd_mask) {
93  v_mask = cd_mask[loops[mp_loop].v];
94  }
95  vbo_data->mask = v_mask;
96 
97  uchar face_set_color[4] = {UCHAR_MAX, UCHAR_MAX, UCHAR_MAX, UCHAR_MAX};
98  if (cd_face_set) {
99  const int face_set_id = cd_face_set[mp_index];
100  /* Skip for the default color Face Set to render it white. */
101  if (face_set_id != mr->me->face_sets_color_default) {
103  face_set_id, mr->me->face_sets_color_seed, face_set_color);
104  }
105  }
106  copy_v3_v3_uchar(vbo_data->face_set_color, face_set_color);
107  mp_loop++;
108  vbo_data++;
109  }
110  }
111  }
112 }
113 
114 static void extract_sculpt_data_init_subdiv(const DRWSubdivCache *subdiv_cache,
115  const MeshRenderData *mr,
116  MeshBatchCache *UNUSED(cache),
117  void *buffer,
118  void *UNUSED(data))
119 {
120  GPUVertBuf *vbo = static_cast<GPUVertBuf *>(buffer);
121 
122  Mesh *coarse_mesh = mr->me;
123  CustomData *cd_vdata = &coarse_mesh->vdata;
124  CustomData *cd_pdata = &coarse_mesh->pdata;
125 
126  /* First, interpolate mask if available. */
127  GPUVertBuf *mask_vbo = nullptr;
128  GPUVertBuf *subdiv_mask_vbo = nullptr;
129  const float *cd_mask = (const float *)CustomData_get_layer(cd_vdata, CD_PAINT_MASK);
130 
131  if (cd_mask) {
132  GPUVertFormat mask_format = {0};
133  GPU_vertformat_attr_add(&mask_format, "msk", GPU_COMP_F32, 1, GPU_FETCH_FLOAT);
134 
135  mask_vbo = GPU_vertbuf_calloc();
136  GPU_vertbuf_init_with_format(mask_vbo, &mask_format);
137  GPU_vertbuf_data_alloc(mask_vbo, coarse_mesh->totloop);
138  float *v_mask = static_cast<float *>(GPU_vertbuf_get_data(mask_vbo));
139 
140  for (int i = 0; i < coarse_mesh->totpoly; i++) {
141  const MPoly *mpoly = &coarse_mesh->mpoly[i];
142 
143  for (int loop_index = mpoly->loopstart; loop_index < mpoly->loopstart + mpoly->totloop;
144  loop_index++) {
145  const MLoop *ml = &coarse_mesh->mloop[loop_index];
146  *v_mask++ = cd_mask[ml->v];
147  }
148  }
149 
150  subdiv_mask_vbo = GPU_vertbuf_calloc();
152  subdiv_mask_vbo, &mask_format, subdiv_cache->num_subdiv_loops);
153 
154  draw_subdiv_interp_custom_data(subdiv_cache, mask_vbo, subdiv_mask_vbo, 1, 0, false);
155  }
156 
157  /* Then, gather face sets. */
158  GPUVertFormat face_set_format = {0};
160 
161  GPUVertBuf *face_set_vbo = GPU_vertbuf_calloc();
162  GPU_vertbuf_init_with_format(face_set_vbo, &face_set_format);
163  GPU_vertbuf_data_alloc(face_set_vbo, subdiv_cache->num_subdiv_loops);
164 
165  struct gpuFaceSet {
166  uint8_t color[4];
167  };
168 
169  gpuFaceSet *face_sets = (gpuFaceSet *)GPU_vertbuf_get_data(face_set_vbo);
170  const int *cd_face_set = (const int *)CustomData_get_layer(cd_pdata, CD_SCULPT_FACE_SETS);
171 
174  int *subdiv_loop_poly_index = subdiv_cache->subdiv_loop_poly_index;
175 
176  for (uint i = 0; i < subdiv_cache->num_subdiv_loops; i++) {
177  const int mp_index = subdiv_loop_poly_index[i];
178 
179  uchar face_set_color[4] = {UCHAR_MAX, UCHAR_MAX, UCHAR_MAX, UCHAR_MAX};
180  if (cd_face_set) {
181  const int face_set_id = cd_face_set[mp_index];
182  /* Skip for the default color Face Set to render it white. */
183  if (face_set_id != coarse_mesh->face_sets_color_default) {
185  face_set_id, coarse_mesh->face_sets_color_seed, face_set_color);
186  }
187  }
188  copy_v3_v3_uchar(face_sets->color, face_set_color);
189  face_sets++;
190  }
191 
192  /* Finally, interleave mask and face sets. */
193  draw_subdiv_build_sculpt_data_buffer(subdiv_cache, subdiv_mask_vbo, face_set_vbo, vbo);
194 
195  if (mask_vbo) {
196  GPU_vertbuf_discard(mask_vbo);
197  GPU_vertbuf_discard(subdiv_mask_vbo);
198  }
199  GPU_vertbuf_discard(face_set_vbo);
200 }
201 
203 {
204  MeshExtract extractor = {nullptr};
205  extractor.init = extract_sculpt_data_init;
207  extractor.data_type = MR_DATA_NONE;
208  extractor.data_size = 0;
209  extractor.use_threading = false;
210  extractor.mesh_buffer_offset = offsetof(MeshBufferList, vbo.sculpt_data);
211  return extractor;
212 }
213 
216 } // namespace blender::draw
217 
void * CustomData_get_layer(const struct CustomData *data, int type)
int CustomData_get_offset(const struct CustomData *data, int type)
void BKE_paint_face_set_overlay_color_get(int face_set, int seed, uchar r_color[4])
Definition: paint.c:2336
MINLINE void copy_v3_v3_uchar(unsigned char r[3], const unsigned char a[3])
unsigned char uchar
Definition: BLI_sys_types.h:70
unsigned int uint
Definition: BLI_sys_types.h:67
#define UNUSED(x)
@ CD_PAINT_MASK
@ CD_SCULPT_FACE_SETS
void GPU_vertbuf_discard(GPUVertBuf *)
struct GPUVertBuf GPUVertBuf
GPUVertBuf * GPU_vertbuf_calloc(void)
void GPU_vertbuf_data_alloc(GPUVertBuf *, uint v_len)
#define GPU_vertbuf_init_with_format(verts, format)
void * GPU_vertbuf_get_data(const GPUVertBuf *verts)
void GPU_vertbuf_init_build_on_device(GPUVertBuf *verts, GPUVertFormat *format, uint v_len)
@ GPU_FETCH_FLOAT
@ GPU_FETCH_INT_TO_FLOAT_UNIT
uint GPU_vertformat_attr_add(GPUVertFormat *, const char *name, GPUVertCompType, uint comp_len, GPUVertFetchMode)
@ GPU_COMP_F32
@ GPU_COMP_U8
Read Guarded memory(de)allocation.
Group Output data from inside of a node group A color picker Mix two input colors RGB to Convert a color s luminance to a grayscale value Generate a normal vector and a dot product Bright Control the brightness and contrast of the input color Vector Map an input vectors to used to fine tune the interpolation of the input Camera Retrieve information about the camera and how it relates to the current shading point s position Clamp a value between a minimum and a maximum Vector Perform vector math operation Invert a color
#define BM_ELEM_CD_GET_FLOAT(ele, offset)
Definition: bmesh_class.h:553
#define BM_ELEM_CD_GET_INT(ele, offset)
Definition: bmesh_class.h:518
#define BM_FACE_FIRST_LOOP(p)
Definition: bmesh_class.h:622
#define BM_ITER_MESH(ele, iter, bm, itype)
@ BM_FACES_OF_MESH
ATTR_WARN_UNUSED_RESULT const BMLoop * l
@ MR_DATA_NONE
void draw_subdiv_build_sculpt_data_buffer(const DRWSubdivCache *cache, GPUVertBuf *mask_vbo, GPUVertBuf *face_set_vbo, GPUVertBuf *sculpt_data)
void draw_subdiv_interp_custom_data(const DRWSubdivCache *cache, GPUVertBuf *src_data, GPUVertBuf *dst_data, int dimensions, int dst_offset, bool compress_to_u16)
Extraction of Mesh data into VBO to feed to GPU.
@ MR_EXTRACT_BMESH
Definition: extract_mesh.hh:31
const MeshExtract extract_sculpt_data
ccl_global float * buffer
format
Definition: logImageCore.h:38
ccl_device_inline float4 mask(const int4 &mask, const float4 &a)
Definition: math_float4.h:513
static void extract_sculpt_data_init_subdiv(const DRWSubdivCache *subdiv_cache, const MeshRenderData *mr, MeshBatchCache *UNUSED(cache), void *buffer, void *UNUSED(data))
static void extract_sculpt_data_init(const MeshRenderData *mr, MeshBatchCache *UNUSED(cache), void *buf, void *UNUSED(tls_data))
constexpr MeshExtract create_extractor_sculpt_data()
static GPUVertFormat * get_sculpt_data_format()
unsigned char uint8_t
Definition: stdint.h:78
struct BMVert * v
Definition: bmesh_class.h:153
struct BMFace * f
Definition: bmesh_class.h:171
struct BMLoop * next
Definition: bmesh_class.h:233
CustomData vdata
Definition: bmesh_class.h:337
CustomData pdata
Definition: bmesh_class.h:337
CustomData ldata
Definition: bmesh_class.h:337
int * subdiv_loop_poly_index
unsigned int v
GPUVertBuf * sculpt_data
size_t mesh_buffer_offset
eMRDataType data_type
ExtractInitSubdivFn * init_subdiv
size_t data_size
bool use_threading
ExtractInitFn * init
eMRExtractType extract_type
Definition: extract_mesh.hh:37
const MPoly * mpoly
Definition: extract_mesh.hh:77
CustomData vdata
struct MLoop * mloop
CustomData pdata
int totpoly
int face_sets_color_seed
int face_sets_color_default
int totloop
struct MPoly * mpoly
CustomData ldata