Blender  V3.3
extract_mesh_vbo_lnor.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 "extract_mesh.hh"
9 
10 #include "draw_subdivision.h"
11 
12 namespace blender::draw {
13 
14 /* ---------------------------------------------------------------------- */
18 static void extract_lnor_init(const MeshRenderData *mr,
19  MeshBatchCache *UNUSED(cache),
20  void *buf,
21  void *tls_data)
22 {
23  GPUVertBuf *vbo = static_cast<GPUVertBuf *>(buf);
24  static GPUVertFormat format = {0};
25  if (format.attr_len == 0) {
28  }
31 
32  *(GPUPackedNormal **)tls_data = static_cast<GPUPackedNormal *>(GPU_vertbuf_get_data(vbo));
33 }
34 
36  const BMFace *f,
37  const int UNUSED(f_index),
38  void *data)
39 {
40  BMLoop *l_iter, *l_first;
41  l_iter = l_first = BM_FACE_FIRST_LOOP(f);
42  do {
43  const int l_index = BM_elem_index_get(l_iter);
44  if (mr->loop_normals) {
45  (*(GPUPackedNormal **)data)[l_index] = GPU_normal_convert_i10_v3(mr->loop_normals[l_index]);
46  }
47  else {
50  bm_vert_no_get(mr, l_iter->v));
51  }
52  else {
54  }
55  }
56  (*(GPUPackedNormal **)data)[l_index].w = BM_elem_flag_test(f, BM_ELEM_HIDDEN) ? -1 : 0;
57  } while ((l_iter = l_iter->next) != l_first);
58 }
59 
61  const MPoly *mp,
62  const int mp_index,
63  void *data)
64 {
65  const MLoop *mloop = mr->mloop;
66  const int ml_index_end = mp->loopstart + mp->totloop;
67  for (int ml_index = mp->loopstart; ml_index < ml_index_end; ml_index += 1) {
68  const MLoop *ml = &mloop[ml_index];
69  GPUPackedNormal *lnor_data = &(*(GPUPackedNormal **)data)[ml_index];
70  if (mr->loop_normals) {
71  *lnor_data = GPU_normal_convert_i10_v3(mr->loop_normals[ml_index]);
72  }
73  else if (mp->flag & ME_SMOOTH) {
74  *lnor_data = GPU_normal_convert_i10_v3(mr->vert_normals[ml->v]);
75  }
76  else {
77  *lnor_data = GPU_normal_convert_i10_v3(mr->poly_normals[mp_index]);
78  }
79 
80  /* Flag for paint mode overlay.
81  * Only use MR_EXTRACT_MAPPED in edit mode where it is used to display the edge-normals.
82  * In paint mode it will use the un-mapped data to draw the wire-frame. */
83  if (mp->flag & ME_HIDE || (mr->edit_bmesh && mr->extract_type == MR_EXTRACT_MAPPED &&
84  (mr->v_origindex) && mr->v_origindex[ml->v] == ORIGINDEX_NONE)) {
85  lnor_data->w = -1;
86  }
87  else if (mp->flag & ME_FACE_SEL) {
88  lnor_data->w = 1;
89  }
90  else {
91  lnor_data->w = 0;
92  }
93  }
94 }
95 
97 {
98  static GPUVertFormat format = {0};
99  if (format.attr_len == 0) {
102  }
103  return &format;
104 }
105 
106 static void extract_lnor_init_subdiv(const DRWSubdivCache *subdiv_cache,
107  const MeshRenderData *UNUSED(mr),
108  MeshBatchCache *cache,
109  void *buffer,
110  void *UNUSED(data))
111 {
112  GPUVertBuf *vbo = static_cast<GPUVertBuf *>(buffer);
113  GPUVertBuf *pos_nor = cache->final.buff.vbo.pos_nor;
114  BLI_assert(pos_nor);
116  draw_subdiv_build_lnor_buffer(subdiv_cache, pos_nor, vbo);
117 }
118 
120 {
121  MeshExtract extractor = {nullptr};
122  extractor.init = extract_lnor_init;
126  extractor.data_type = MR_DATA_LOOP_NOR;
127  extractor.data_size = sizeof(GPUPackedNormal *);
128  extractor.use_threading = true;
129  extractor.mesh_buffer_offset = offsetof(MeshBufferList, vbo.lnor);
130  return extractor;
131 }
132 
135 /* ---------------------------------------------------------------------- */
139 struct gpuHQNor {
140  short x, y, z, w;
141 };
142 
143 static void extract_lnor_hq_init(const MeshRenderData *mr,
144  MeshBatchCache *UNUSED(cache),
145  void *buf,
146  void *tls_data)
147 {
148  GPUVertBuf *vbo = static_cast<GPUVertBuf *>(buf);
149  static GPUVertFormat format = {0};
150  if (format.attr_len == 0) {
153  }
156 
157  *(gpuHQNor **)tls_data = static_cast<gpuHQNor *>(GPU_vertbuf_get_data(vbo));
158 }
159 
161  const BMFace *f,
162  const int UNUSED(f_index),
163  void *data)
164 {
165  BMLoop *l_iter, *l_first;
166  l_iter = l_first = BM_FACE_FIRST_LOOP(f);
167  do {
168  const int l_index = BM_elem_index_get(l_iter);
169  if (mr->loop_normals) {
170  normal_float_to_short_v3(&(*(gpuHQNor **)data)[l_index].x, mr->loop_normals[l_index]);
171  }
172  else {
174  normal_float_to_short_v3(&(*(gpuHQNor **)data)[l_index].x, bm_vert_no_get(mr, l_iter->v));
175  }
176  else {
177  normal_float_to_short_v3(&(*(gpuHQNor **)data)[l_index].x, bm_face_no_get(mr, f));
178  }
179  }
180  } while ((l_iter = l_iter->next) != l_first);
181 }
182 
184  const MPoly *mp,
185  const int mp_index,
186  void *data)
187 {
188  const MLoop *mloop = mr->mloop;
189  const int ml_index_end = mp->loopstart + mp->totloop;
190  for (int ml_index = mp->loopstart; ml_index < ml_index_end; ml_index += 1) {
191  const MLoop *ml = &mloop[ml_index];
192  gpuHQNor *lnor_data = &(*(gpuHQNor **)data)[ml_index];
193  if (mr->loop_normals) {
194  normal_float_to_short_v3(&lnor_data->x, mr->loop_normals[ml_index]);
195  }
196  else if (mp->flag & ME_SMOOTH) {
197  normal_float_to_short_v3(&lnor_data->x, mr->vert_normals[ml->v]);
198  }
199  else {
200  normal_float_to_short_v3(&lnor_data->x, mr->poly_normals[mp_index]);
201  }
202 
203  /* Flag for paint mode overlay.
204  * Only use #MR_EXTRACT_MAPPED in edit mode where it is used to display the edge-normals.
205  * In paint mode it will use the un-mapped data to draw the wire-frame. */
206  if (mp->flag & ME_HIDE || (mr->edit_bmesh && mr->extract_type == MR_EXTRACT_MAPPED &&
207  (mr->v_origindex) && mr->v_origindex[ml->v] == ORIGINDEX_NONE)) {
208  lnor_data->w = -1;
209  }
210  else if (mp->flag & ME_FACE_SEL) {
211  lnor_data->w = 1;
212  }
213  else {
214  lnor_data->w = 0;
215  }
216  }
217 }
218 
220 {
221  MeshExtract extractor = {nullptr};
222  extractor.init = extract_lnor_hq_init;
226  extractor.data_type = MR_DATA_LOOP_NOR;
227  extractor.data_size = sizeof(gpuHQNor *);
228  extractor.use_threading = true;
229  extractor.mesh_buffer_offset = offsetof(MeshBufferList, vbo.lnor);
230  return extractor;
231 }
232 
235 } // namespace blender::draw
236 
#define ORIGINDEX_NONE
#define BLI_assert(a)
Definition: BLI_assert.h:46
MINLINE void normal_float_to_short_v3(short r[3], const float n[3])
#define UNUSED(x)
@ ME_HIDE
@ ME_SMOOTH
@ ME_FACE_SEL
struct GPUVertBuf GPUVertBuf
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)
BLI_INLINE GPUPackedNormal GPU_normal_convert_i10_v3(const float data[3])
void GPU_vertformat_alias_add(GPUVertFormat *, const char *alias)
@ GPU_COMP_I10
@ GPU_COMP_F32
@ GPU_COMP_I16
#define BM_FACE_FIRST_LOOP(p)
Definition: bmesh_class.h:622
@ BM_ELEM_HIDDEN
Definition: bmesh_class.h:472
@ BM_ELEM_SMOOTH
Definition: bmesh_class.h:477
#define BM_elem_index_get(ele)
Definition: bmesh_inline.h:110
#define BM_elem_flag_test(ele, hflag)
Definition: bmesh_inline.h:12
@ MR_DATA_LOOP_NOR
void draw_subdiv_build_lnor_buffer(const DRWSubdivCache *cache, GPUVertBuf *pos_nor, GPUVertBuf *lnor)
Extraction of Mesh data into VBO to feed to GPU.
BLI_INLINE const float * bm_face_no_get(const MeshRenderData *mr, const BMFace *efa)
@ MR_EXTRACT_MAPPED
Definition: extract_mesh.hh:32
BLI_INLINE const float * bm_vert_no_get(const MeshRenderData *mr, const BMVert *eve)
const MeshExtract extract_lnor
const MeshExtract extract_lnor_hq
ccl_global float * buffer
format
Definition: logImageCore.h:38
constexpr MeshExtract create_extractor_lnor_hq()
static void extract_lnor_hq_iter_poly_bm(const MeshRenderData *mr, const BMFace *f, const int UNUSED(f_index), void *data)
static void extract_lnor_init_subdiv(const DRWSubdivCache *subdiv_cache, const MeshRenderData *UNUSED(mr), MeshBatchCache *cache, void *buffer, void *UNUSED(data))
static void extract_lnor_iter_poly_bm(const MeshRenderData *mr, const BMFace *f, const int UNUSED(f_index), void *data)
static void extract_lnor_iter_poly_mesh(const MeshRenderData *mr, const MPoly *mp, const int mp_index, void *data)
constexpr MeshExtract create_extractor_lnor()
static void extract_lnor_init(const MeshRenderData *mr, MeshBatchCache *UNUSED(cache), void *buf, void *tls_data)
static void extract_lnor_hq_iter_poly_mesh(const MeshRenderData *mr, const MPoly *mp, const int mp_index, void *data)
static void extract_lnor_hq_init(const MeshRenderData *mr, MeshBatchCache *UNUSED(cache), void *buf, void *tls_data)
static GPUVertFormat * get_subdiv_lnor_format()
struct BMVert * v
Definition: bmesh_class.h:153
struct BMLoop * next
Definition: bmesh_class.h:233
unsigned int v
MeshBufferCache final
MeshBufferList buff
GPUVertBuf * pos_nor
struct MeshBufferList::@272 vbo
size_t mesh_buffer_offset
eMRDataType data_type
ExtractInitSubdivFn * init_subdiv
size_t data_size
ExtractPolyBMeshFn * iter_poly_bm
ExtractPolyMeshFn * iter_poly_mesh
bool use_threading
ExtractInitFn * init
eMRExtractType extract_type
Definition: extract_mesh.hh:37
const float(* poly_normals)[3]
Definition: extract_mesh.hh:85
const MLoop * mloop
Definition: extract_mesh.hh:76
const int * v_origindex
Definition: extract_mesh.hh:66
const float(* vert_normals)[3]
Definition: extract_mesh.hh:84
float(* loop_normals)[3]
Definition: extract_mesh.hh:86
BMEditMesh * edit_bmesh
Definition: extract_mesh.hh:55