Blender V5.0
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
8
9#include "BKE_attribute.hh"
10
11#include "extract_mesh.hh"
12
13namespace blender::draw {
14
16{
17 const Mesh &mesh = *mr.mesh;
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 const GPUVertFormat format = []() {
70 GPU_vertformat_attr_add(&format, "u", gpu::VertAttrType::SFLOAT_32_32);
73 return format;
74 }();
77 MutableSpan<float2> vbo_data = vbo->data<float2>();
78
80 extract_face_dots_uv_mesh(mr, vbo_data);
81 }
82 else {
83 extract_face_dots_uv_bm(mr, vbo_data);
84 }
85 return vbo;
86}
87
88} // 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
static blender::gpu::VertBuf * GPU_vertbuf_create_with_format(const GPUVertFormat &format)
void GPU_vertbuf_data_alloc(blender::gpu::VertBuf &verts, uint v_len)
void GPU_vertformat_alias_add(GPUVertFormat *, blender::StringRef alias)
uint GPU_vertformat_attr_add(GPUVertFormat *format, blender::StringRef name, blender::gpu::VertAttrType type)
BMesh * bm
AttributeSet attributes
constexpr T * data() const
Definition BLI_span.hh:539
void materialize(MutableSpan< T > r_span) const
GAttributeReader lookup(const StringRef attribute_id) const
Extraction of Mesh data into VBO to feed to GPU.
format
static char faces[256]
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)
gpu::VertBufPtr extract_face_dots_uv(const MeshRenderData &mr)
std::unique_ptr< gpu::VertBuf, gpu::VertBufDeleter > VertBufPtr
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:93
VecBase< float, 2 > float2
const char * name
MeshRuntimeHandle * runtime
CustomData corner_data
OffsetIndices< int > faces