Blender  V3.3
extract_mesh_vbo_edituv_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 "extract_mesh.hh"
9 
10 #include "draw_cache_impl.h"
11 
12 #include "draw_subdivision.h"
13 
14 namespace blender::draw {
15 
16 /* ---------------------------------------------------------------------- */
22  int cd_ofs;
23 };
24 
26  GPUVertBuf *vbo,
28  uint loop_len)
29 {
30  static GPUVertFormat format = {0};
31  if (format.attr_len == 0) {
32  /* WARNING: Adjust #EditLoopData struct accordingly. */
35  }
36 
38  GPU_vertbuf_data_alloc(vbo, loop_len);
39 
40  CustomData *cd_ldata = (mr->extract_type == MR_EXTRACT_BMESH) ? &mr->bm->ldata : &mr->me->ldata;
41  data->vbo_data = (EditLoopData *)GPU_vertbuf_get_data(vbo);
42  data->cd_ofs = CustomData_get_offset(cd_ldata, CD_MLOOPUV);
43 }
44 
46  MeshBatchCache *UNUSED(cache),
47  void *buf,
48  void *tls_data)
49 {
50  GPUVertBuf *vbo = static_cast<GPUVertBuf *>(buf);
53 }
54 
56  const BMFace *f,
57  const int UNUSED(f_index),
58  void *_data)
59 {
60  BMLoop *l_iter, *l_first;
61  l_iter = l_first = BM_FACE_FIRST_LOOP(f);
62  do {
63  const int l_index = BM_elem_index_get(l_iter);
65  EditLoopData *eldata = &data->vbo_data[l_index];
66  memset(eldata, 0x0, sizeof(*eldata));
67  mesh_render_data_loop_flag(mr, l_iter, data->cd_ofs, eldata);
68  mesh_render_data_face_flag(mr, f, data->cd_ofs, eldata);
69  mesh_render_data_loop_edge_flag(mr, l_iter, data->cd_ofs, eldata);
70  } while ((l_iter = l_iter->next) != l_first);
71 }
72 
74  const MPoly *mp,
75  const int mp_index,
76  void *_data)
77 {
79  const MLoop *mloop = mr->mloop;
80  const int ml_index_end = mp->loopstart + mp->totloop;
81  for (int ml_index = mp->loopstart; ml_index < ml_index_end; ml_index += 1) {
82  const MLoop *ml = &mloop[ml_index];
83 
84  EditLoopData *eldata = &data->vbo_data[ml_index];
85  memset(eldata, 0x0, sizeof(*eldata));
86  BMFace *efa = bm_original_face_get(mr, mp_index);
87  if (efa) {
88  BMEdge *eed = bm_original_edge_get(mr, ml->e);
89  BMVert *eve = bm_original_vert_get(mr, ml->v);
90  if (eed && eve) {
91  /* Loop on an edge endpoint. */
92  BMLoop *l = BM_face_edge_share_loop(efa, eed);
93  mesh_render_data_loop_flag(mr, l, data->cd_ofs, eldata);
94  mesh_render_data_loop_edge_flag(mr, l, data->cd_ofs, eldata);
95  }
96  else {
97  if (eed == nullptr) {
98  /* Find if the loop's vert is not part of an edit edge.
99  * For this, we check if the previous loop was on an edge. */
100  const int ml_index_last = mp->loopstart + mp->totloop - 1;
101  const int l_prev = (ml_index == mp->loopstart) ? ml_index_last : (ml_index - 1);
102  const MLoop *ml_prev = &mr->mloop[l_prev];
103  eed = bm_original_edge_get(mr, ml_prev->e);
104  }
105  if (eed) {
106  /* Mapped points on an edge between two edit verts. */
107  BMLoop *l = BM_face_edge_share_loop(efa, eed);
108  mesh_render_data_loop_edge_flag(mr, l, data->cd_ofs, eldata);
109  }
110  }
111  }
112  }
113 }
114 
115 static void extract_edituv_data_init_subdiv(const DRWSubdivCache *subdiv_cache,
116  const MeshRenderData *mr,
117  MeshBatchCache *UNUSED(cache),
118  void *buf,
119  void *tls_data)
120 {
121  GPUVertBuf *vbo = static_cast<GPUVertBuf *>(buf);
123  extract_edituv_data_init_common(mr, vbo, data, subdiv_cache->num_subdiv_loops);
124 }
125 
126 static void extract_edituv_data_iter_subdiv_bm(const DRWSubdivCache *subdiv_cache,
127  const MeshRenderData *mr,
128  void *_data,
129  uint subdiv_quad_index,
130  const BMFace *coarse_quad)
131 {
133  int *subdiv_loop_vert_index = (int *)GPU_vertbuf_get_data(subdiv_cache->verts_orig_index);
134  int *subdiv_loop_edge_index = (int *)GPU_vertbuf_get_data(subdiv_cache->edges_orig_index);
135 
136  uint start_loop_idx = subdiv_quad_index * 4;
137  uint end_loop_idx = (subdiv_quad_index + 1) * 4;
138  for (uint i = start_loop_idx; i < end_loop_idx; i++) {
139  const int vert_origindex = subdiv_loop_vert_index[i];
140  int edge_origindex = subdiv_loop_edge_index[i];
141 
142  EditLoopData *edit_loop_data = &data->vbo_data[i];
143  memset(edit_loop_data, 0, sizeof(EditLoopData));
144 
145  if (vert_origindex != -1 && edge_origindex != -1) {
146  BMEdge *eed = BM_edge_at_index(mr->bm, edge_origindex);
147  /* Loop on an edge endpoint. */
148  BMLoop *l = BM_face_edge_share_loop(const_cast<BMFace *>(coarse_quad), eed);
149  mesh_render_data_loop_flag(mr, l, data->cd_ofs, edit_loop_data);
150  mesh_render_data_loop_edge_flag(mr, l, data->cd_ofs, edit_loop_data);
151  }
152  else {
153  if (edge_origindex == -1) {
154  /* Find if the loop's vert is not part of an edit edge.
155  * For this, we check if the previous loop was on an edge. */
156  const uint loop_index_last = (i == start_loop_idx) ? end_loop_idx - 1 : i - 1;
157  edge_origindex = subdiv_loop_edge_index[loop_index_last];
158  }
159  if (edge_origindex != -1) {
160  /* Mapped points on an edge between two edit verts. */
161  BMEdge *eed = BM_edge_at_index(mr->bm, edge_origindex);
162  BMLoop *l = BM_face_edge_share_loop(const_cast<BMFace *>(coarse_quad), eed);
163  mesh_render_data_loop_edge_flag(mr, l, data->cd_ofs, edit_loop_data);
164  }
165  }
166 
167  mesh_render_data_face_flag(mr, coarse_quad, data->cd_ofs, edit_loop_data);
168  }
169 }
170 
171 static void extract_edituv_data_iter_subdiv_mesh(const DRWSubdivCache *subdiv_cache,
172  const MeshRenderData *mr,
173  void *_data,
174  uint subdiv_quad_index,
175  const MPoly *coarse_quad)
176 {
177  const int coarse_quad_index = static_cast<int>(coarse_quad - mr->mpoly);
178  BMFace *coarse_quad_bm = bm_original_face_get(mr, coarse_quad_index);
179  extract_edituv_data_iter_subdiv_bm(subdiv_cache, mr, _data, subdiv_quad_index, coarse_quad_bm);
180 }
181 
183 {
184  MeshExtract extractor = {nullptr};
185  extractor.init = extract_edituv_data_init;
191  extractor.data_type = MR_DATA_NONE;
192  extractor.data_size = sizeof(MeshExtract_EditUVData_Data);
193  extractor.use_threading = true;
194  extractor.mesh_buffer_offset = offsetof(MeshBufferList, vbo.edituv_data);
195  return extractor;
196 }
197 
200 } // namespace blender::draw
201 
int CustomData_get_offset(const struct CustomData *data, int type)
unsigned int uint
Definition: BLI_sys_types.h:67
#define UNUSED(x)
@ CD_MLOOPUV
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)
@ GPU_FETCH_INT
uint GPU_vertformat_attr_add(GPUVertFormat *, const char *name, GPUVertCompType, uint comp_len, GPUVertFetchMode)
void GPU_vertformat_alias_add(GPUVertFormat *, const char *alias)
@ GPU_COMP_U8
#define BM_FACE_FIRST_LOOP(p)
Definition: bmesh_class.h:622
#define BM_elem_index_get(ele)
Definition: bmesh_inline.h:110
BLI_INLINE BMEdge * BM_edge_at_index(BMesh *bm, const int index)
Definition: bmesh_mesh.h:109
BMLoop * BM_face_edge_share_loop(BMFace *f, BMEdge *e)
Return the Loop Shared by Face and Edge.
Definition: bmesh_query.c:1115
ATTR_WARN_UNUSED_RESULT const BMLoop * l
@ MR_DATA_NONE
void mesh_render_data_loop_flag(const MeshRenderData *mr, BMLoop *l, const int cd_ofs, EditLoopData *eattr)
void mesh_render_data_loop_edge_flag(const MeshRenderData *mr, BMLoop *l, const int cd_ofs, EditLoopData *eattr)
void mesh_render_data_face_flag(const MeshRenderData *mr, const BMFace *efa, const int cd_ofs, EditLoopData *eattr)
Definition: extract_mesh.cc:92
Extraction of Mesh data into VBO to feed to GPU.
BLI_INLINE BMFace * bm_original_face_get(const MeshRenderData *mr, int idx)
BLI_INLINE BMEdge * bm_original_edge_get(const MeshRenderData *mr, int idx)
BLI_INLINE BMVert * bm_original_vert_get(const MeshRenderData *mr, int idx)
@ MR_EXTRACT_BMESH
Definition: extract_mesh.hh:31
const MeshExtract extract_edituv_data
format
Definition: logImageCore.h:38
static void extract_edituv_data_init_common(const MeshRenderData *mr, GPUVertBuf *vbo, MeshExtract_EditUVData_Data *data, uint loop_len)
static void extract_edituv_data_iter_subdiv_bm(const DRWSubdivCache *subdiv_cache, const MeshRenderData *mr, void *_data, uint subdiv_quad_index, const BMFace *coarse_quad)
static void extract_edituv_data_iter_subdiv_mesh(const DRWSubdivCache *subdiv_cache, const MeshRenderData *mr, void *_data, uint subdiv_quad_index, const MPoly *coarse_quad)
static void extract_edituv_data_init_subdiv(const DRWSubdivCache *subdiv_cache, const MeshRenderData *mr, MeshBatchCache *UNUSED(cache), void *buf, void *tls_data)
static void extract_edituv_data_init(const MeshRenderData *mr, MeshBatchCache *UNUSED(cache), void *buf, void *tls_data)
static void extract_edituv_data_iter_poly_mesh(const MeshRenderData *mr, const MPoly *mp, const int mp_index, void *_data)
constexpr MeshExtract create_extractor_edituv_data()
static void extract_edituv_data_iter_poly_bm(const MeshRenderData *mr, const BMFace *f, const int UNUSED(f_index), void *_data)
struct BMLoop * next
Definition: bmesh_class.h:233
CustomData ldata
Definition: bmesh_class.h:337
struct GPUVertBuf * edges_orig_index
struct GPUVertBuf * verts_orig_index
unsigned int e
unsigned int v
GPUVertBuf * edituv_data
ExtractIterSubdivBMeshFn * iter_subdiv_bm
size_t mesh_buffer_offset
eMRDataType data_type
ExtractIterSubdivMeshFn * iter_subdiv_mesh
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 MLoop * mloop
Definition: extract_mesh.hh:76
const MPoly * mpoly
Definition: extract_mesh.hh:77
CustomData ldata