27 array_utils::gather(mr.vert_positions, mr.corner_verts, corners_data);
28 extract_mesh_loose_edge_data(mr.vert_positions, mr.edges, mr.loose_edges, loose_edge_data);
29 array_utils::gather(mr.vert_positions, mr.loose_verts, loose_vert_data);
41 for (const int face_index : range) {
42 const BMFace &face = *BM_face_at_index(&const_cast<BMesh &>(bm), face_index);
43 const BMLoop *loop = BM_FACE_FIRST_LOOP(&face);
44 for ([[maybe_unused]] const int i : IndexRange(face.len)) {
45 const int index = BM_elem_index_get(loop);
46 corners_data[index] = bm_vert_co_get(mr, loop->v);
52 const Span<int> loose_edges = mr.loose_edges;
54 for (const int i : range) {
55 const BMEdge &edge = *BM_edge_at_index(&const_cast<BMesh &>(bm), loose_edges[i]);
56 loose_edge_data[i * 2 + 0] = bm_vert_co_get(mr, edge.v1);
57 loose_edge_data[i * 2 + 1] = bm_vert_co_get(mr, edge.v2);
61 const Span<int> loose_verts = mr.loose_verts;
62 threading::parallel_for(loose_verts.index_range(), 2048, [&](
const IndexRange range) {
63 for (const int i : range) {
64 const BMVert &vert = *BM_vert_at_index(&const_cast<BMesh &>(bm), loose_verts[i]);
65 loose_vert_data[i] = bm_vert_co_get(mr, &vert);
73 if (
format.attr_len == 0) {
91 if (
format.attr_len == 0) {
101 if (
format.attr_len == 0) {
111 char *
flag = &flags[i];
132 if (loose_verts.
is_empty() && loose_edges_num == 0) {
137 struct SubdivPosNorLoop {
146 const int resolution = subdiv_cache.
resolution;
153 SubdivPosNorLoop edge_data[2];
154 memset(edge_data, 0,
sizeof(SubdivPosNorLoop) * 2);
155 for (
const int i :
IndexRange(loose_edges_num)) {
156 const int edge_offset = loose_geom_start + i * verts_per_edge;
157 const Span<float3> positions = cached_positions.
slice(i * resolution, resolution);
158 for (
const int edge :
IndexRange(edges_per_edge)) {
162 (edge_offset + edge * 2) *
sizeof(SubdivPosNorLoop),
163 sizeof(SubdivPosNorLoop) * 2,
168 const int loose_verts_start = loose_geom_start + loose_edges_num * verts_per_edge;
171 SubdivPosNorLoop vert_data;
172 memset(&vert_data, 0,
sizeof(SubdivPosNorLoop));
174 copy_v3_v3(vert_data.pos, positions[loose_verts[i]]);
176 (loose_verts_start + i) *
sizeof(SubdivPosNorLoop),
177 sizeof(SubdivPosNorLoop),
203 char *flags = flags_buffer->
data<
char>().
data();
209 if (
format.attr_len == 0) {
222 const Mesh *coarse_mesh = subdiv_cache.
mesh;
228 src_custom_normals->
data<
float3>().copy_from(coarse_mesh->corner_normals());
235 subdiv_cache, *src_custom_normals, *dst_custom_normals,
GPU_COMP_F32, 3, 0);
255 subdiv_loop_subdiv_vert_index,
MINLINE uint divide_ceil_u(uint a, uint b)
MINLINE void copy_v3_v3(float r[3], const float a[3])
void GPU_vertbuf_init_build_on_device(blender::gpu::VertBuf &verts, const GPUVertFormat &format, uint v_len)
void GPU_vertbuf_use(blender::gpu::VertBuf *)
void GPU_vertbuf_tag_dirty(blender::gpu::VertBuf *verts)
#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_update_sub(blender::gpu::VertBuf *verts, uint start, uint len, const void *data)
void GPU_vertbuf_discard(blender::gpu::VertBuf *)
ATTR_WARN_UNUSED_RESULT BMesh * bm
constexpr MutableSpan slice(const int64_t start, const int64_t size) const
constexpr MutableSpan take_back(const int64_t n) const
constexpr int64_t size_in_bytes() const
constexpr MutableSpan take_front(const int64_t n) const
constexpr Span slice(int64_t start, int64_t size) const
constexpr int64_t size_in_bytes() const
constexpr int64_t size() const
constexpr IndexRange index_range() const
constexpr bool is_empty() const
int subdiv_verts_per_coarse_edge(const DRWSubdivCache &cache)
void extract_positions_subdiv(const DRWSubdivCache &subdiv_cache, const MeshRenderData &mr, gpu::VertBuf &vbo, gpu::VertBuf *orco_vbo)
int subdiv_edges_per_coarse_edge(const DRWSubdivCache &cache)
static void extract_positions_mesh(const MeshRenderData &mr, MutableSpan< float3 > vbo_data)
static void extract_positions_bm(const MeshRenderData &mr, MutableSpan< float3 > vbo_data)
static void extract_vertex_flags(const MeshRenderData &mr, char *flags)
static void extract_loose_positions_subdiv(const DRWSubdivCache &subdiv_cache, const MeshRenderData &mr, gpu::VertBuf &vbo)
void draw_subdiv_accumulate_normals(const DRWSubdivCache &cache, gpu::VertBuf *pos_nor, gpu::VertBuf *face_adjacency_offsets, gpu::VertBuf *face_adjacency_lists, gpu::VertBuf *vertex_loop_map, gpu::VertBuf *vert_normals)
void draw_subdiv_extract_pos_nor(const DRWSubdivCache &cache, gpu::VertBuf *flags_buffer, gpu::VertBuf *pos_nor, gpu::VertBuf *orco)
int subdiv_full_vbo_size(const MeshRenderData &mr, const DRWSubdivCache &cache)
static const GPUVertFormat & get_custom_normals_format()
void draw_subdiv_interp_custom_data(const DRWSubdivCache &cache, gpu::VertBuf &src_data, gpu::VertBuf &dst_data, int comp_type, int dimensions, int dst_offset)
void draw_subdiv_finalize_normals(const DRWSubdivCache &cache, gpu::VertBuf *vert_normals, gpu::VertBuf *subdiv_loop_subdiv_vert_index, gpu::VertBuf *pos_nor)
static const GPUVertFormat & get_normals_format()
gpu::VertBuf * draw_subdiv_build_origindex_buffer(int *vert_origindex, uint num_loops)
void extract_positions(const MeshRenderData &mr, gpu::VertBuf &vbo)
const GPUVertFormat & draw_subdiv_get_pos_nor_format()
void draw_subdiv_finalize_custom_normals(const DRWSubdivCache &cache, gpu::VertBuf *src_custom_normals, gpu::VertBuf *pos_nor)
void parallel_for(const IndexRange range, const int64_t grain_size, const Function &function, const TaskSizeHints &size_hints=detail::TaskSizeHints_Static(1))
void memory_bandwidth_bound_task(const int64_t approximate_bytes_touched, const Function &function)
Frequency::GEOMETRY nor[]
int * subdiv_loop_subdiv_vert_index
gpu::VertBuf * subdiv_vertex_face_adjacency_offsets
gpu::VertBuf * subdiv_vertex_face_adjacency
bool use_custom_loop_normals
Array< float3 > loose_edge_positions
VArraySpan< bool > hide_vert
const int * orig_index_vert
Span< float3 > vert_positions
VArraySpan< bool > select_vert
eMRExtractType extract_type