Blender V5.0
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
8
9#include "BLI_math_geom.h"
11
12#include "BKE_attribute.hh"
13#include "BKE_mesh.hh"
14
15#include "extract_mesh.hh"
16
17#include "draw_subdivision.hh"
18
19namespace blender::draw {
20
21BLI_INLINE float area_ratio_get(float area, float uvarea)
22{
23 if (area >= FLT_EPSILON && uvarea >= FLT_EPSILON) {
24 return uvarea / area;
25 }
26 return 0.0f;
27}
28
29BLI_INLINE float area_ratio_to_stretch(float ratio, float tot_ratio)
30{
31 ratio *= tot_ratio;
32 return (ratio > 1.0f) ? (1.0f / ratio) : ratio;
33}
34
35struct AreaInfo {
36 float tot_area = 0.0f;
37 float tot_uv_area = 0.0f;
38};
40{
42 const BMesh &bm = *mr.bm;
43 const int uv_offset = CustomData_get_offset(&bm.ldata, CD_PROP_FLOAT2);
45 IndexRange(bm.totface),
46 1024,
47 AreaInfo{},
48 [&](const IndexRange range, AreaInfo info) {
49 for (const int face_index : range) {
50 const BMFace &face = *BM_face_at_index(&const_cast<BMesh &>(bm), face_index);
51 const float area = BM_face_calc_area(&face);
52 const float uvarea = BM_face_calc_area_uv(&face, uv_offset);
53 info.tot_area += area;
54 info.tot_uv_area += uvarea;
55 r_area_ratio[face_index] = area_ratio_get(area, uvarea);
56 }
57 return info;
58 },
59 [](const AreaInfo &a, const AreaInfo &b) {
60 return AreaInfo{a.tot_area + b.tot_area, a.tot_uv_area + b.tot_uv_area};
61 });
62 }
63
64 const Span<float3> positions = mr.vert_positions;
65 const OffsetIndices<int> faces = mr.faces;
66 const Span<int> corner_verts = mr.corner_verts;
67 const Mesh &mesh = *mr.mesh;
68 const bke::AttributeAccessor attributes = mesh.attributes();
70 const VArraySpan uv_map = *attributes.lookup<float2>(name, bke::AttrDomain::Corner);
71
73 faces.index_range(),
74 1024,
75 AreaInfo{},
76 [&](const IndexRange range, AreaInfo info) {
77 for (const int face_index : range) {
78 const IndexRange face = faces[face_index];
79 const float area = bke::mesh::face_area_calc(positions, corner_verts.slice(face));
80 float uvarea = area_poly_v2(reinterpret_cast<const float (*)[2]>(&uv_map[face.start()]),
81 face.size());
82 info.tot_area += area;
83 info.tot_uv_area += uvarea;
84 r_area_ratio[face_index] = area_ratio_get(area, uvarea);
85 }
86 return info;
87 },
88 [](const AreaInfo &a, const AreaInfo &b) {
89 return AreaInfo{a.tot_area + b.tot_area, a.tot_uv_area + b.tot_uv_area};
90 });
91}
92
94 float &tot_area,
95 float &tot_uv_area)
96{
97 Array<float> area_ratio(mr.faces_num);
98 const AreaInfo info = compute_area_ratio(mr, area_ratio);
99 tot_area = info.tot_area;
100 tot_uv_area = info.tot_uv_area;
101
103 gpu::VertAttrType::SFLOAT_32);
106 MutableSpan<float> vbo_data = vbo->data<float>();
107
108 const int64_t bytes = area_ratio.as_span().size_in_bytes() + vbo_data.size_in_bytes();
111 const BMesh &bm = *mr.bm;
112 threading::parallel_for(IndexRange(bm.totface), 2048, [&](const IndexRange range) {
113 for (const int face_index : range) {
114 const BMFace &face = *BM_face_at_index(&const_cast<BMesh &>(bm), face_index);
115 const IndexRange face_range(BM_elem_index_get(BM_FACE_FIRST_LOOP(&face)), face.len);
116 vbo_data.slice(face_range).fill(area_ratio[face_index]);
117 }
118 });
119 }
120 else {
122 const OffsetIndices<int> faces = mr.faces;
123 threading::parallel_for(faces.index_range(), 2048, [&](const IndexRange range) {
124 for (const int face : range) {
125 vbo_data.slice(faces[face]).fill(area_ratio[face]);
126 }
127 });
128 }
129 });
130 return vbo;
131}
132
134 const DRWSubdivCache &subdiv_cache,
135 float &tot_area,
136 float &tot_uv_area)
137{
139 gpu::VertAttrType::SFLOAT_32);
142
143 gpu::VertBuf *coarse_vbo = GPU_vertbuf_calloc();
145 GPU_vertbuf_data_alloc(*coarse_vbo, mr.faces_num);
146 MutableSpan coarse_vbo_data = coarse_vbo->data<float>();
147 const AreaInfo info = compute_area_ratio(mr, coarse_vbo_data);
148 tot_area = info.tot_area;
149 tot_uv_area = info.tot_uv_area;
150
151 draw_subdiv_build_edituv_stretch_area_buffer(subdiv_cache, coarse_vbo, vbo.get());
152
153 GPU_vertbuf_discard(coarse_vbo);
154 return vbo;
155}
156
157} // 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:46
#define BLI_INLINE
@ CD_PROP_FLOAT2
blender::gpu::VertBuf * GPU_vertbuf_create_on_device(const GPUVertFormat &format, uint v_len)
static blender::gpu::VertBuf * GPU_vertbuf_create_with_format(const GPUVertFormat &format)
#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 *)
GPUVertFormat GPU_vertformat_from_attribute(blender::StringRef name, blender::gpu::VertAttrType type)
BMesh * bm
long long int int64_t
AttributeSet attributes
Span< T > as_span() const
Definition BLI_array.hh:243
constexpr T * data() const
Definition BLI_span.hh:539
constexpr int64_t size_in_bytes() const
Definition BLI_span.hh:501
GAttributeReader lookup(const StringRef attribute_id) const
MutableSpan< T > data()
Extraction of Mesh data into VBO to feed to GPU.
format
static char faces[256]
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)
gpu::VertBufPtr extract_edituv_stretch_area(const MeshRenderData &mr, float &tot_area, float &tot_uv_area)
static AreaInfo compute_area_ratio(const MeshRenderData &mr, MutableSpan< float > r_area_ratio)
gpu::VertBufPtr extract_edituv_stretch_area_subdiv(const MeshRenderData &mr, const DRWSubdivCache &subdiv_cache, float &tot_area, float &tot_uv_area)
BLI_INLINE float area_ratio_get(float area, float uvarea)
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
void memory_bandwidth_bound_task(const int64_t approximate_bytes_touched, const Function &function)
Definition BLI_task.hh:265
Value parallel_reduce(IndexRange range, int64_t grain_size, const Value &identity, const Function &function, const Reduction &reduction)
Definition BLI_task.hh:151
VecBase< float, 2 > float2
const char * name
CustomData corner_data
OffsetIndices< int > faces