Blender V4.3
extract_mesh_vbo_edituv_stretch_area.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
10
11#include "MEM_guardedalloc.h"
12
13#include "BKE_attribute.hh"
14#include "BKE_mesh.hh"
15
16#include "extract_mesh.hh"
17
18#include "draw_subdivision.hh"
19
20namespace blender::draw {
21
22BLI_INLINE float area_ratio_get(float area, float uvarea)
23{
24 if (area >= FLT_EPSILON && uvarea >= FLT_EPSILON) {
25 return uvarea / area;
26 }
27 return 0.0f;
28}
29
30BLI_INLINE float area_ratio_to_stretch(float ratio, float tot_ratio)
31{
32 ratio *= tot_ratio;
33 return (ratio > 1.0f) ? (1.0f / ratio) : ratio;
34}
35
36struct AreaInfo {
37 float tot_area = 0.0f;
38 float tot_uv_area = 0.0f;
39};
41{
43 const BMesh &bm = *mr.bm;
44 const int uv_offset = CustomData_get_offset(&bm.ldata, CD_PROP_FLOAT2);
47 1024,
48 AreaInfo{},
49 [&](const IndexRange range, AreaInfo info) {
50 for (const int face_index : range) {
51 const BMFace &face = *BM_face_at_index(&const_cast<BMesh &>(bm), face_index);
52 const float area = BM_face_calc_area(&face);
53 const float uvarea = BM_face_calc_area_uv(&face, uv_offset);
54 info.tot_area += area;
55 info.tot_uv_area += uvarea;
56 r_area_ratio[face_index] = area_ratio_get(area, uvarea);
57 }
58 return info;
59 },
60 [](const AreaInfo &a, const AreaInfo &b) {
61 return AreaInfo{a.tot_area + b.tot_area, a.tot_uv_area + b.tot_uv_area};
62 });
63 }
64
65 const Span<float3> positions = mr.vert_positions;
66 const OffsetIndices<int> faces = mr.faces;
67 const Span<int> corner_verts = mr.corner_verts;
68 const Mesh &mesh = *mr.mesh;
69 const bke::AttributeAccessor attributes = mesh.attributes();
70 const StringRef name = CustomData_get_active_layer_name(&mesh.corner_data, CD_PROP_FLOAT2);
71 const VArraySpan uv_map = *attributes.lookup<float2>(name, bke::AttrDomain::Corner);
72
74 faces.index_range(),
75 1024,
76 AreaInfo{},
77 [&](const IndexRange range, AreaInfo info) {
78 for (const int face_index : range) {
79 const IndexRange face = faces[face_index];
80 const float area = bke::mesh::face_area_calc(positions, corner_verts.slice(face));
81 float uvarea = area_poly_v2(reinterpret_cast<const float(*)[2]>(&uv_map[face.start()]),
82 face.size());
83 info.tot_area += area;
84 info.tot_uv_area += uvarea;
85 r_area_ratio[face_index] = area_ratio_get(area, uvarea);
86 }
87 return info;
88 },
89 [](const AreaInfo &a, const AreaInfo &b) {
90 return AreaInfo{a.tot_area + b.tot_area, a.tot_uv_area + b.tot_uv_area};
91 });
92}
93
95 gpu::VertBuf &vbo,
96 float &tot_area,
97 float &tot_uv_area)
98{
99 Array<float> area_ratio(mr.faces_num);
100 const AreaInfo info = compute_area_ratio(mr, area_ratio);
101 tot_area = info.tot_area;
102 tot_uv_area = info.tot_uv_area;
103
104 static GPUVertFormat format = {0};
105 if (format.attr_len == 0) {
107 }
110 MutableSpan<float> vbo_data = vbo.data<float>();
111
112 const int64_t bytes = area_ratio.as_span().size_in_bytes() + vbo_data.size_in_bytes();
113 threading::memory_bandwidth_bound_task(bytes, [&]() {
114 if (mr.extract_type == MR_EXTRACT_BMESH) {
115 const BMesh &bm = *mr.bm;
116 threading::parallel_for(IndexRange(bm.totface), 2048, [&](const IndexRange range) {
117 for (const int face_index : range) {
118 const BMFace &face = *BM_face_at_index(&const_cast<BMesh &>(bm), face_index);
119 const IndexRange face_range(BM_elem_index_get(BM_FACE_FIRST_LOOP(&face)), face.len);
120 vbo_data.slice(face_range).fill(area_ratio[face_index]);
121 }
122 });
123 }
124 else {
126 const OffsetIndices<int> faces = mr.faces;
127 threading::parallel_for(faces.index_range(), 2048, [&](const IndexRange range) {
128 for (const int face : range) {
129 vbo_data.slice(faces[face]).fill(area_ratio[face]);
130 }
131 });
132 }
133 });
134}
135
137 const DRWSubdivCache &subdiv_cache,
138 gpu::VertBuf &vbo,
139 float &tot_area,
140 float &tot_uv_area)
141{
142 static GPUVertFormat format = {0};
143 if (format.attr_len == 0) {
145 }
147
148 gpu::VertBuf *coarse_vbo = GPU_vertbuf_calloc();
150 GPU_vertbuf_data_alloc(*coarse_vbo, mr.faces_num);
151 MutableSpan coarse_vbo_data = coarse_vbo->data<float>();
152 const AreaInfo info = compute_area_ratio(mr, coarse_vbo_data);
153 tot_area = info.tot_area;
154 tot_uv_area = info.tot_uv_area;
155
157 draw_subdiv_build_edituv_stretch_area_buffer(subdiv_cache, coarse_vbo, &vbo);
158
159 GPU_vertbuf_discard(coarse_vbo);
160}
161
162} // namespace blender::draw
int CustomData_get_offset(const CustomData *data, eCustomDataType type)
const char * CustomData_get_active_layer_name(const CustomData *data, eCustomDataType type)
#define BLI_assert(a)
Definition BLI_assert.h:50
#define BLI_INLINE
@ CD_PROP_FLOAT2
void GPU_vertbuf_init_build_on_device(blender::gpu::VertBuf &verts, const GPUVertFormat &format, uint v_len)
#define GPU_vertbuf_init_with_format(verts, format)
blender::gpu::VertBuf * GPU_vertbuf_calloc()
void GPU_vertbuf_data_alloc(blender::gpu::VertBuf &verts, uint v_len)
void GPU_vertbuf_discard(blender::gpu::VertBuf *)
@ GPU_FETCH_FLOAT
uint GPU_vertformat_attr_add(GPUVertFormat *, const char *name, GPUVertCompType, uint comp_len, GPUVertFetchMode)
@ GPU_COMP_F32
Read Guarded memory(de)allocation.
ATTR_WARN_UNUSED_RESULT BMesh * bm
Span< T > as_span() const
Definition BLI_array.hh:232
constexpr int64_t size_in_bytes() const
Definition BLI_span.hh:502
MutableSpan< T > data()
local_group_size(16, 16) .push_constant(Type b
Extraction of Mesh data into VBO to feed to GPU.
format
void extract_edituv_stretch_area_subdiv(const MeshRenderData &mr, const DRWSubdivCache &subdiv_cache, gpu::VertBuf &vbo, float &tot_area, float &tot_uv_area)
BLI_INLINE float area_ratio_to_stretch(float ratio, float tot_ratio)
void draw_subdiv_build_edituv_stretch_area_buffer(const DRWSubdivCache &cache, gpu::VertBuf *coarse_data, gpu::VertBuf *subdiv_data)
static AreaInfo compute_area_ratio(const MeshRenderData &mr, MutableSpan< float > r_area_ratio)
BLI_INLINE float area_ratio_get(float area, float uvarea)
void extract_edituv_stretch_area(const MeshRenderData &mr, gpu::VertBuf &vbo, float &tot_area, float &tot_uv_area)
Value parallel_reduce(IndexRange range, int64_t grain_size, const Value &identity, const Function &function, const Reduction &reduction)
Definition BLI_task.hh:153
__int64 int64_t
Definition stdint.h:89
CustomData ldata
int totface
OffsetIndices< int > faces