Blender V4.3
extract_mesh_vbo_fdots_uv.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2021 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
9#include "BKE_attribute.hh"
10
11#include "extract_mesh.hh"
12
13namespace blender::draw {
14
16{
17 const Mesh &mesh = *mr.mesh;
18 const StringRef name = CustomData_get_active_layer_name(&mesh.corner_data, CD_PROP_FLOAT2);
19 const bke::AttributeAccessor attributes = mesh.attributes();
20 if (mr.use_subsurf_fdots) {
21 const BitSpan facedot_tags = mesh.runtime->subsurf_face_dot_tags;
22 const OffsetIndices faces = mr.faces;
23 const Span<int> corner_verts = mr.corner_verts;
24 const VArraySpan uv_map = *attributes.lookup<float2>(name, bke::AttrDomain::Corner);
25 threading::parallel_for(faces.index_range(), 4096, [&](const IndexRange range) {
26 for (const int face_index : range) {
27 const IndexRange face = faces[face_index];
28 const auto corner = std::find_if(face.begin(), face.end(), [&](const int corner) {
29 return facedot_tags[corner_verts[corner]].test();
30 });
31 if (corner == face.end()) {
32 vbo_data[face_index] = float2(0);
33 }
34 else {
35 vbo_data[face_index] = uv_map[*corner];
36 }
37 }
38 });
39 }
40 else {
41 /* Use the attribute API to average the attribute on the face domain. */
42 const VArray uv_map = *attributes.lookup<float2>(name, bke::AttrDomain::Face);
43 uv_map.materialize(vbo_data);
44 }
45}
46
48{
49 const BMesh &bm = *mr.bm;
50 const int offset = CustomData_get_offset(&bm.ldata, CD_PROP_FLOAT2);
51
52 threading::parallel_for(IndexRange(bm.totface), 2048, [&](const IndexRange range) {
53 for (const int face_index : range) {
54 const BMFace &face = *BM_face_at_index(&const_cast<BMesh &>(bm), face_index);
55 const BMLoop *loop = BM_FACE_FIRST_LOOP(&face);
56 vbo_data[face_index] = float2(0);
57 for ([[maybe_unused]] const int i : IndexRange(face.len)) {
58 vbo_data[face_index] += *BM_ELEM_CD_GET_FLOAT2_P(loop, offset);
59 loop = loop->next;
60 }
61 vbo_data[face_index] /= face.len;
62 }
63 });
64}
65
67{
68 static GPUVertFormat format = {0};
69 if (format.attr_len == 0) {
73 }
76 MutableSpan<float2> vbo_data = vbo.data<float2>();
77
78 if (mr.extract_type == MR_EXTRACT_MESH) {
79 extract_face_dots_uv_mesh(mr, vbo_data);
80 }
81 else {
82 extract_face_dots_uv_bm(mr, vbo_data);
83 }
84}
85
86} // namespace blender::draw
int CustomData_get_offset(const CustomData *data, eCustomDataType type)
const char * CustomData_get_active_layer_name(const CustomData *data, eCustomDataType type)
@ CD_PROP_FLOAT2
#define GPU_vertbuf_init_with_format(verts, format)
void GPU_vertbuf_data_alloc(blender::gpu::VertBuf &verts, uint v_len)
@ GPU_FETCH_FLOAT
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_F32
ATTR_WARN_UNUSED_RESULT BMesh * bm
void materialize(MutableSpan< T > r_span) const
MutableSpan< T > data()
Extraction of Mesh data into VBO to feed to GPU.
format
void extract_face_dots_uv(const MeshRenderData &mr, gpu::VertBuf &vbo)
static void extract_face_dots_uv_mesh(const MeshRenderData &mr, MutableSpan< float2 > vbo_data)
static void extract_face_dots_uv_bm(const MeshRenderData &mr, MutableSpan< float2 > vbo_data)
void parallel_for(const IndexRange range, const int64_t grain_size, const Function &function, const TaskSizeHints &size_hints=detail::TaskSizeHints_Static(1))
Definition BLI_task.hh:95
CustomData ldata
int totface
OffsetIndices< int > faces