42 using namespace draw::pbvh;
43 if (
const CustomRequest *request_type = std::get_if<CustomRequest>(&value)) {
46 const GenericRequest &attr = std::get<GenericRequest>(value);
80 attributes(mesh.attributes())
90 struct AttributeData {
105 void tag_dirty(
const IndexMask &node_mask);
160 const IndexMask &nodes_to_update)
override;
164 const IndexMask &nodes_to_update)
override;
193void DrawCacheImpl::AttributeData::tag_dirty(
const IndexMask &node_mask)
196 node_mask.
set_bits(this->dirty_nodes);
202 data->tag_dirty(node_mask);
205 data->tag_dirty(node_mask);
212 node_mask.
set_bits(dirty_topology_);
225 data->tag_dirty(node_mask);
232 data->tag_dirty(node_mask);
238 for (
const auto &[data_request, data] : attribute_vbos_.
items()) {
239 if (
const GenericRequest *request = std::get_if<GenericRequest>(&data_request)) {
240 if (request->name == attribute_name) {
241 data.tag_dirty(node_mask);
250 ptr = std::make_unique<DrawCacheImpl>();
282 if (
format.attr_len == 0) {
291 if (
format.attr_len == 0) {
300 if (
format.attr_len == 0) {
309 if (
format.attr_len == 0) {
321 bool is_render, is_active;
322 const char *prefix =
"a";
342 if (
const CustomRequest *request_type = std::get_if<CustomRequest>(&request)) {
343 switch (*request_type) {
364 if (std::holds_alternative<CustomRequest>(request)) {
372 bool type_supported =
false;
374 using T = decltype(dummy);
375 using Converter = AttributeConverter<T>;
376 using VBOType = typename Converter::VBOType;
377 if constexpr (!std::is_void_v<VBOType>) {
378 type_supported = true;
381 return type_supported;
388 return short4(result.x, result.y, result.z, 0);
399 using VBOType =
typename Converter::VBOType;
400 VBOType *data = vbo.
data<VBOType>().
data();
401 for (
const int face : face_indices) {
402 for (
const int vert : corner_verts.
slice(faces[face])) {
403 *data = Converter::convert(attribute[vert]);
416 using VBOType =
typename Converter::VBOType;
418 VBOType *data = vbo.
data<VBOType>().
data();
419 for (
const int face : face_indices) {
420 const int face_size = faces[face].size();
421 std::fill_n(data, face_size, Converter::convert(attribute[face]));
433 using VBOType =
typename Converter::VBOType;
435 VBOType *data = vbo.
data<VBOType>().
data();
436 for (
const int face : face_indices) {
437 for (
const int corner : faces[face]) {
438 *data = Converter::convert(attribute[corner]);
456 return *
static_cast<const T *
>(
POINTER_OFFSET(face.head.data, offset));
463 using VBOType =
typename Converter::VBOType;
464 VBOType *data = vbo.
data<VBOType>().
data();
470 const BMLoop *
l = face->l_first;
484 using VBOType =
typename Converter::VBOType;
485 VBOType *data = vbo.
data<VBOType>().
data();
502 using VBOType =
typename Converter::VBOType;
503 VBOType *data = vbo.
data<VBOType>().
data();
509 const BMLoop *
l = face->l_first;
550 return std::count_if(faces.begin(), faces.end(), [&](
const BMFace *face) {
551 return !BM_elem_flag_test_bool(face, BM_ELEM_HIDDEN);
560 free_ibos(lines_ibos_, lines_ibos_.index_range());
561 free_ibos(lines_ibos_coarse_, lines_ibos_coarse_.index_range());
562 free_ibos(tris_ibos_, tris_ibos_.index_range());
563 free_ibos(tris_ibos_coarse_, tris_ibos_coarse_.index_range());
564 for (DrawCacheImpl::AttributeData &data : attribute_vbos_.
values()) {
565 free_vbos(data.vbos, data.vbos.index_range());
575void DrawCacheImpl::free_nodes_with_changed_topology(
const bke::pbvh::Tree &pbvh)
589 free_ibos(lines_ibos_coarse_, nodes_to_free);
591 free_ibos(tris_ibos_coarse_, nodes_to_free);
597 for (AttributeData &data : attribute_vbos_.values()) {
604 for (MutableSpan<gpu::Batch *> batches : tris_batches_.values()) {
619 for (
const int face : face_indices) {
620 if (!sharp_faces.
is_empty() && sharp_faces[face]) {
621 const int face_size = faces[face].size();
626 for (
const int vert : corner_verts.
slice(faces[face])) {
640 float *data = vbo.
data<
float>().
data();
641 for (
const int face : face_indices) {
642 for (
const int vert : corner_verts.
slice(faces[face])) {
651 const int color_default,
652 const int color_seed,
657 for (
const int face : face_indices) {
658 const int id = face_sets[face];
660 uchar4 fset_color(UCHAR_MAX);
661 if (
id != color_default) {
666 fset_color[0] = fset_color[1] = fset_color[2] = UCHAR_MAX;
669 const int face_size = faces[face].size();
670 std::fill_n(data, face_size, fset_color);
677 const GSpan attribute,
683 using T = decltype(dummy);
684 if constexpr (!std::is_void_v<typename AttributeConverter<T>::VBOType>) {
685 const Span<T> src = attribute.typed<T>();
687 case bke::AttrDomain::Point:
688 extract_data_vert_mesh<T>(faces, corner_verts, src, face_indices, vert_buf);
690 case bke::AttrDomain::Face:
691 extract_data_face_mesh<T>(faces, src, face_indices, vert_buf);
693 case bke::AttrDomain::Corner:
694 extract_data_corner_mesh<T>(faces, src, face_indices, vert_buf);
697 BLI_assert_unreachable();
705 const bool use_flat_layout,
710 if (use_flat_layout) {
711 const int grid_size_1 = key.
grid_size - 1;
712 for (
const int grid : grids) {
714 for (
int y = 0; y < grid_size_1; y++) {
715 for (
int x = 0; x < grid_size_1; x++) {
729 for (
const int grid : grids) {
731 std::copy_n(grid_positions.
data(), grid_positions.
size(), data);
732 data += grid_positions.
size();
742 const bool use_flat_layout,
748 if (use_flat_layout) {
749 const int grid_size_1 = key.
grid_size - 1;
750 for (
const int grid : grids) {
753 if (!sharp_faces.
is_empty() && sharp_faces[grid_to_face_map[grid]]) {
754 for (
int y = 0; y < grid_size_1; y++) {
755 for (
int x = 0; x < grid_size_1; x++) {
768 for (
int y = 0; y < grid_size_1; y++) {
769 for (
int x = 0; x < grid_size_1; x++) {
782 for (
const int grid : grids) {
793 const bool use_flat_layout,
797 float *data = vert_buf.
data<
float>().
data();
798 if (use_flat_layout) {
799 const int grid_size_1 = key.
grid_size - 1;
800 for (
const int grid : grids) {
802 for (
int y = 0; y < grid_size_1; y++) {
803 for (
int x = 0; x < grid_size_1; x++) {
817 for (
const int grid : grids) {
819 std::copy_n(grid_masks.
data(), grid_masks.
size(), data);
820 data += grid_masks.
size();
828 const int color_default,
829 const int color_seed,
830 const bool use_flat_layout,
839 const int fset = face_sets[grid_to_face_map[grid_indices[i]]];
840 if (fset != color_default) {
844 std::fill_n(data, verts_per_grid, color);
845 data += verts_per_grid;
862 if (
const CustomRequest *request_type = std::get_if<CustomRequest>(&request)) {
863 switch (*request_type) {
867 key, subdiv_ccg.positions, use_flat_layout[i], nodes[i].grids(), *vbos[i]);
872 const Span<int> grid_to_face_map = subdiv_ccg.grid_to_face_map;
874 const VArraySpan sharp_faces = *attributes.lookup<
bool>(
"sharp_face",
878 subdiv_ccg.positions,
891 if (!masks.is_empty()) {
898 [&](
const int i) { vbos[i]->
data<
float>().fill(0.0f); });
905 const Span<int> grid_to_face_map = subdiv_ccg.grid_to_face_map;
907 if (
const VArray<int> face_sets = *attributes.lookup<
int>(
".sculpt_face_set",
934 using T =
decltype(dummy);
936 using VBOType =
typename Converter::VBOType;
937 if constexpr (!std::is_void_v<VBOType>) {
953 const Mesh &mesh = *
static_cast<const Mesh *
>(
object.data);
955 const Span<int> corner_verts = mesh.corner_verts();
957 if (
const CustomRequest *request_type = std::get_if<CustomRequest>(&request)) {
958 switch (*request_type) {
963 faces, corner_verts, vert_positions, nodes[i].
faces(), *vbos[i]);
971 const VArraySpan sharp_faces = *attributes.lookup<
bool>(
"sharp_face",
987 if (!mask.is_empty()) {
994 [&](
const int i) { vbos[i]->
data<
float>().fill(0.0f); });
1006 faces, face_sets, face_set_default, face_set_seed, nodes[i].
faces(), *vbos[i]);
1023 const GVArraySpan attribute = *attributes.lookup_or_default(name, domain, data_type);
1037 const BMLoop *
l = face->l_first;
1055 const BMLoop *
l = face->l_first;
1071 const int cd_offset,
1074 float *data = vbo.
data<
float>().
data();
1079 const BMLoop *
l = face->l_first;
1090 const int color_default,
1091 const int color_seed,
1102 if (fset != color_default) {
1105 std::fill_n(data, 3, color);
1117 using T =
decltype(dummy);
1118 if constexpr (!std::is_void_v<typename AttributeConverter<T>::VBOType>) {
1146 if (
const CustomRequest *request_type = std::get_if<CustomRequest>(&request)) {
1147 switch (*request_type) {
1165 if (cd_offset != -1) {
1175 [&](
const int i) { vbos[i]->
data<
float>().fill(0.0f); });
1184 if (cd_offset != -1) {
1223 int corners_count = 0;
1224 for (
const int face : face_indices) {
1225 if (!hide_poly.
is_empty() && hide_poly[face]) {
1228 corners_count += faces[face].size();
1235 int node_corner_offset = 0;
1237 for (
const int face_index : face_indices) {
1238 const int face_size = faces[face_index].size();
1239 if (!hide_poly.
is_empty() && hide_poly[face_index]) {
1240 node_corner_offset += face_size;
1244 const int next = (i == face_size - 1) ? 0 : i + 1;
1245 data[line_index] =
uint2(i,
next) + node_corner_offset;
1249 node_corner_offset += face_size;
1258 const int visible_faces_num)
1288 const uint grid_vert_len = gridsize * gridsize;
1289 for (
int i = 0; i < totgrid; i++, offset += grid_vert_len) {
1293 grid_hidden[grid_indices[i]];
1295 for (
int y = 0; y < gridsize - skip; y += skip) {
1296 for (
int x = 0; x < gridsize - skip; x += skip) {
1324 for (
int i = 0; i < totgrid; i++, offset += grid_vert_len) {
1326 grid_hidden[grid_indices[i]];
1329 for (
int y = 0; y < gridsize - skip; y += skip) {
1330 for (
int x = 0; x < gridsize - skip; x += skip) {
1336 v0 = (y * (gridsize - 1) + x) * 4;
1339 v1 = (y * (gridsize - 1) + x + skip - 1) * 4;
1340 v2 = ((y + skip - 1) * (gridsize - 1) + x + skip - 1) * 4;
1341 v3 = ((y + skip - 1) * (gridsize - 1) +
x) * 4;
1364 int display_gridsize,
1372 const uint grid_vert_len = gridsize * gridsize;
1373 for (
int i = 0; i < totgrid; i++, offset += grid_vert_len) {
1375 bool grid_visible =
false;
1378 grid_hidden[grid_indices[i]];
1380 for (
int y = 0; y < gridsize - skip; y += skip) {
1381 for (
int x = 0; x < gridsize - skip; x += skip) {
1395 if (y / skip + 2 == display_gridsize) {
1398 grid_visible =
true;
1409 int display_gridsize,
1419 for (
int i = 0; i < totgrid; i++, offset += grid_vert_len) {
1420 bool grid_visible =
false;
1422 grid_hidden[grid_indices[i]];
1425 for (
int y = 0; y < gridsize - skip; y += skip) {
1426 for (
int x = 0; x < gridsize - skip; x += skip) {
1432 v0 = (y * (gridsize - 1) + x) * 4;
1435 v1 = (y * (gridsize - 1) + x + skip - 1) * 4;
1436 v2 = ((y + skip - 1) * (gridsize - 1) + x + skip - 1) * 4;
1437 v3 = ((y + skip - 1) * (gridsize - 1) +
x) * 4;
1455 if (y / skip + 2 == display_gridsize) {
1458 grid_visible =
true;
1472 switch (pbvh.
type()) {
1475 const Mesh &mesh = *
static_cast<const Mesh *
>(
object.data);
1477 const VArray material_indices = *attributes.lookup<
int>(
"material_index",
1479 if (!material_indices) {
1484 for (const int i : range) {
1485 const Span<int> face_indices = nodes[i].faces();
1486 if (face_indices.is_empty()) {
1489 node_materials[i] = material_indices[face_indices.first()];
1492 return node_materials;
1498 const VArray material_indices = *attributes.lookup<
int>(
"material_index",
1500 if (!material_indices) {
1507 for (const int i : range) {
1508 const Span<int> grids = nodes[i].grids();
1509 if (grids.is_empty()) {
1512 node_materials[i] = material_indices[grid_faces[grids.first()]];
1515 return node_materials;
1527 switch (pbvh.
type()) {
1540 const SubdivCCG &subdiv_ccg = *
object.sculpt->subdiv_ccg;
1546 for (const int i : range) {
1547 const Span<int> grids = nodes[i].grids();
1548 if (grids.is_empty()) {
1551 use_flat_layout[i] = std::any_of(grids.begin(), grids.end(), [&](const int grid) {
1552 return sharp_faces[grid_to_face_map[grid]];
1570 const Span<int> face_indices = node.faces();
1576 for (
const int face : face_indices) {
1577 if (hide_poly[face]) {
1589 int node_corner_offset = 0;
1590 for (
const int face_index : face_indices) {
1592 if (!hide_poly.
is_empty() && hide_poly[face_index]) {
1593 node_corner_offset += face.
size();
1598 const int corner = tri[i];
1599 const int index_in_face = corner - face.first();
1600 data[tri_index][i] = node_corner_offset + index_in_face;
1604 node_corner_offset += face.size();
1614 const bool do_coarse,
1616 const bool use_flat_layout)
1619 int display_gridsize = gridsize;
1620 int totgrid = grid_indices.
size();
1623 const int display_level = do_coarse ? 0 : key.
level;
1625 if (display_level < key.
level) {
1626 display_gridsize = (1 << display_level) + 1;
1627 skip = 1 << (key.
level - display_level - 1);
1633 grid_hidden, grid_indices, key.
grid_size, display_gridsize);
1637 if (use_flat_layout) {
1649 const bool do_coarse,
1651 const bool use_flat_layout)
1654 int display_gridsize = gridsize;
1655 int totgrid = grid_indices.
size();
1658 const int display_level = do_coarse ? 0 : key.
level;
1660 if (display_level < key.
level) {
1661 display_gridsize = (1 << display_level) + 1;
1662 skip = 1 << (key.
level - display_level - 1);
1667 &elb,
GPU_PRIM_LINES, 2 * totgrid * display_gridsize * (display_gridsize - 1), INT_MAX);
1669 if (use_flat_layout) {
1671 grid_indices, display_gridsize, grid_hidden, gridsize, skip, totgrid, elb);
1675 grid_indices, display_gridsize, grid_hidden, gridsize, skip, totgrid, elb);
1682 const OrigMeshData &orig_mesh_data,
1692 node_mask,
GrainSize(8196), memory, [&](
const int i) {
return !ibos[i]; });
1694 switch (pbvh.
type()) {
1697 const Mesh &mesh = *
static_cast<const Mesh *
>(
object.data);
1707 const Span<bke::pbvh::GridsNode> nodes = pbvh.
nodes<bke::pbvh::GridsNode>();
1708 nodes_to_calculate.
foreach_index(GrainSize(1), [&](
const int i) {
1709 const SubdivCCG &subdiv_ccg = *
object.sculpt->subdiv_ccg;
1712 key, subdiv_ccg.
grid_hidden, coarse, nodes[i].grids(), use_flat_layout_[i]);
1717 const Span<bke::pbvh::BMeshNode> nodes = pbvh.
nodes<bke::pbvh::BMeshNode>();
1718 nodes_to_calculate.
foreach_index(GrainSize(1), [&](
const int i) {
1720 &
const_cast<bke::pbvh::BMeshNode &
>(nodes[i]));
1731BitSpan DrawCacheImpl::ensure_use_flat_layout(
const Object &
object,
1732 const OrigMeshData &orig_mesh_data)
1735 if (use_flat_layout_.
size() != pbvh.nodes_num()) {
1738 return use_flat_layout_;
1758 const BitSpan use_flat_layout,
1771 const int verts_per_grid = use_flat_layout[i] ?
square_i(key.
grid_size - 1) * 4 :
1773 const int verts_num = nodes[i].grids().size() * verts_per_grid;
1804 const OrigMeshData &orig_mesh_data,
1813 Vector<gpu::VertBuf *> &vbos = data.vbos;
1814 vbos.resize(pbvh.nodes_num(),
nullptr);
1822 IndexMaskMemory memory;
1824 node_mask, GrainSize(8196), memory, [&](
const int i) {
return !vbos[i]; });
1826 node_mask.
slice_content(data.dirty_nodes.index_range()), data.dirty_nodes, memory);
1831 switch (pbvh.type()) {
1839 fill_vbos_grids(
object, orig_mesh_data, use_flat_layout_, mask, attr, vbos);
1851 dirty_mask.foreach_index_optimized<
int>([&](
const int i) { data.dirty_nodes[i].reset(); });
1858Span<gpu::IndexBuf *> DrawCacheImpl::ensure_tri_indices(
const Object &
object,
1859 const OrigMeshData &orig_mesh_data,
1860 const IndexMask &node_mask,
1864 switch (pbvh.type()) {
1866 const Span<bke::pbvh::MeshNode> nodes = pbvh.nodes<bke::pbvh::MeshNode>();
1868 Vector<gpu::IndexBuf *> &ibos = tris_ibos_;
1869 ibos.resize(nodes.size(),
nullptr);
1874 IndexMaskMemory memory;
1876 node_mask, GrainSize(8196), memory, [&](
const int i) {
return !ibos[i]; });
1878 const Mesh &mesh = *
static_cast<const Mesh *
>(
object.data);
1879 const OffsetIndices<int> faces = mesh.faces();
1880 const Span<int3> corner_tris = mesh.corner_tris();
1881 const bke::AttributeAccessor attributes = orig_mesh_data.
attributes;
1883 nodes_to_calculate.foreach_index(GrainSize(1), [&](
const int i) {
1896 const Span<bke::pbvh::GridsNode> nodes = pbvh.nodes<bke::pbvh::GridsNode>();
1898 Vector<gpu::IndexBuf *> &ibos = coarse ? tris_ibos_coarse_ : tris_ibos_;
1899 ibos.resize(nodes.size(),
nullptr);
1904 IndexMaskMemory memory;
1906 node_mask, GrainSize(8196), memory, [&](
const int i) {
return !ibos[i]; });
1908 const SubdivCCG &subdiv_ccg = *
object.sculpt->subdiv_ccg;
1911 nodes_to_calculate.foreach_index(GrainSize(1), [&](
const int i) {
1913 key, subdiv_ccg.grid_hidden, coarse, nodes[i].grids(), use_flat_layout_[i]);
1932 this->ensure_use_flat_layout(
object, orig_mesh_data);
1933 this->free_nodes_with_changed_topology(pbvh);
1939 this->ensure_attribute_data(
object, orig_mesh_data, attr, nodes_to_update);
1976 this->ensure_use_flat_layout(
object, orig_mesh_data);
1977 this->free_nodes_with_changed_topology(pbvh);
2007 return material_indices_;
int CCG_grid_xy_to_index(const int grid_size, const int x, const int y)
CustomData interface, see also DNA_customdata_types.h.
int CustomData_get_offset_named(const CustomData *data, eCustomDataType type, blender::StringRef name)
const char * CustomData_get_render_layer_name(const CustomData *data, eCustomDataType type)
const char * CustomData_get_active_layer_name(const CustomData *data, eCustomDataType type)
#define CD_TYPE_AS_MASK(_type)
void BKE_paint_face_set_overlay_color_get(int face_set, int seed, uchar r_color[4])
bool paint_is_grid_face_hidden(blender::BoundedBitSpan grid_hidden, int gridsize, int x, int y)
A BVH for high poly meshes.
const blender::Set< BMFace *, 0 > & BKE_pbvh_bmesh_node_faces(blender::bke::pbvh::BMeshNode *node)
CCGKey BKE_subdiv_ccg_key_top_level(const SubdivCCG &subdiv_ccg)
#define BLI_assert_unreachable()
MINLINE int square_i(int a)
MINLINE unsigned int square_uint(unsigned int a)
float normal_quad_v3(float n[3], const float v1[3], const float v2[3], const float v3[3], const float v4[3])
MINLINE int poly_to_tri_count(int poly_count, int corner_count)
MINLINE void normal_float_to_short_v3(short out[3], const float in[3])
#define POINTER_OFFSET(v, ofs)
Object * DEG_get_original_object(Object *object)
#define CD_MASK_COLOR_ALL
Object is a sort of wrapper for general info.
void DRW_cdlayer_attr_aliases_add(GPUVertFormat *format, const char *base_name, int data_type, const char *layer_name, bool is_active_render, bool is_active_layer)
#define GPU_batch_create(primitive_type, vertex_buf, index_buf)
int GPU_batch_vertbuf_add(blender::gpu::Batch *batch, blender::gpu::VertBuf *vertex_buf, bool own_vbo)
#define GPU_BATCH_DISCARD_SAFE(batch)
void GPU_indexbuf_build_in_place_ex(GPUIndexBufBuilder *builder, uint index_min, uint index_max, bool uses_restart_indices, blender::gpu::IndexBuf *elem)
blender::MutableSpan< uint32_t > GPU_indexbuf_get_data(GPUIndexBufBuilder *)
#define GPU_INDEXBUF_DISCARD_SAFE(elem)
void GPU_indexbuf_init(GPUIndexBufBuilder *, GPUPrimType, uint prim_len, uint vertex_len)
blender::gpu::IndexBuf * GPU_indexbuf_calloc()
blender::gpu::IndexBuf * GPU_indexbuf_build(GPUIndexBufBuilder *)
void GPU_indexbuf_add_line_verts(GPUIndexBufBuilder *, uint v1, uint v2)
void GPU_indexbuf_add_tri_verts(GPUIndexBufBuilder *, uint v1, uint v2, uint v3)
#define GPU_vertbuf_create_with_format(format)
void GPU_vertbuf_use(blender::gpu::VertBuf *)
#define GPU_VERTBUF_DISCARD_SAFE(verts)
void GPU_vertbuf_data_alloc(blender::gpu::VertBuf &verts, uint v_len)
#define BM_elem_flag_test(ele, hflag)
ATTR_WARN_UNUSED_RESULT BMesh * bm
ATTR_WARN_UNUSED_RESULT const BMVert * v2
ATTR_WARN_UNUSED_RESULT const BMLoop * l
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
constexpr int64_t size() const
const Value * lookup_ptr(const Key &key) const
Value & lookup_or_add_default(const Key &key)
const Value & lookup(const Key &key) const
ValueIterator values() const
ItemIterator items() const
constexpr MutableSpan< NewT > cast() const
constexpr T * data() const
constexpr IndexRange index_range() const
constexpr Span slice(int64_t start, int64_t size) const
constexpr const T * data() const
constexpr int64_t size() const
constexpr IndexRange index_range() const
constexpr bool is_empty() const
void append(const T &value)
IndexRange index_range() const
void resize(const int64_t new_size)
void resize(const int64_t new_size_in_bits, const bool value=false)
GAttributeReader lookup(const StringRef attribute_id) const
Span< NodeT > nodes() const
void tag_visibility_changed(const IndexMask &node_mask) override
void tag_positions_changed(const IndexMask &node_mask) override
virtual ~DrawCacheImpl() override
Span< int > ensure_material_indices(const Object &object) override
void tag_attribute_changed(const IndexMask &node_mask, StringRef attribute_name) override
Span< gpu::Batch * > ensure_tris_batches(const Object &object, const ViewportRequest &request, const IndexMask &nodes_to_update) override
void tag_masks_changed(const IndexMask &node_mask) override
void tag_topology_changed(const IndexMask &node_mask) override
void tag_face_sets_changed(const IndexMask &node_mask) override
Span< gpu::Batch * > ensure_lines_batches(const Object &object, const ViewportRequest &request, const IndexMask &nodes_to_update) override
static IndexMask from_predicate(const IndexMask &universe, GrainSize grain_size, IndexMaskMemory &memory, Fn &&predicate)
IndexMask slice_content(IndexRange range) const
static IndexMask from_bits(BitSpan bits, IndexMaskMemory &memory)
static IndexMask from_union(const IndexMask &mask_a, const IndexMask &mask_b, IndexMaskMemory &memory)
static IndexMask from_intersection(const IndexMask &mask_a, const IndexMask &mask_b, IndexMaskMemory &memory)
int64_t min_array_size() const
void set_bits(MutableBitSpan r_bits, int64_t offset=0) const
void foreach_index(Fn &&fn) const
void convert_to_static_type(const CPPType &cpp_type, const Func &func)
IndexRange grid_range(const int grid_area, const int grid)
int face_triangles_num(const int face_size)
IndexRange face_triangles_range(OffsetIndices< int > faces, int face_i)
pbvh::Tree * pbvh_get(Object &object)
Span< float3 > vert_normals_eval_from_eval(const Object &object_eval)
Span< float3 > vert_positions_eval_from_eval(const Object &object_eval)
int count_grid_quads(const BitGroupVector<> &grid_visibility, Span< int > grid_indices, int gridsize, int display_gridsize)
Span< float3 > face_normals_eval_from_eval(const Object &object_eval)
void extract_data_vert_mesh(const OffsetIndices< int > faces, const Span< int > corner_verts, const Span< T > attribute, const Span< int > face_indices, gpu::VertBuf &vbo)
static BLI_NOINLINE void ensure_vbos_allocated_bmesh(const Object &object, const GPUVertFormat &format, const IndexMask &node_mask, const MutableSpan< gpu::VertBuf * > vbos)
static void create_tri_index_grids(const Span< int > grid_indices, const BitGroupVector<> &grid_hidden, const int gridsize, const int skip, const int totgrid, GPUIndexBufBuilder &elb)
static BLI_NOINLINE void ensure_vbos_allocated_grids(const Object &object, const GPUVertFormat &format, const BitSpan use_flat_layout, const IndexMask &node_mask, const MutableSpan< gpu::VertBuf * > vbos)
void extract_data_corner_mesh(const OffsetIndices< int > faces, const Span< T > attribute, const Span< int > face_indices, gpu::VertBuf &vbo)
static gpu::IndexBuf * create_index_bmesh(const Set< BMFace *, 0 > &faces, const int visible_faces_num)
static const CustomData * get_cdata(const BMesh &bm, const bke::AttrDomain domain)
static void fill_vbo_face_set_grids(const CCGKey &key, const Span< int > grid_to_face_map, const Span< int > face_sets, const int color_default, const int color_seed, const bool use_flat_layout, const Span< int > grid_indices, gpu::VertBuf &vert_buf)
static int count_visible_tris_bmesh(const Set< BMFace *, 0 > &faces)
const T & bmesh_cd_loop_get(const BMLoop &loop, const int offset)
static void fill_vbo_position_grids(const CCGKey &key, const Span< float3 > positions, const bool use_flat_layout, const Span< int > grids, gpu::VertBuf &vert_buf)
static BitVector calc_use_flat_layout(const Object &object, const OrigMeshData &orig_mesh_data)
static const GPUVertFormat & normal_format()
static const GPUVertFormat & face_set_format()
static void fill_vbo_normal_grids(const CCGKey &key, const Span< float3 > positions, const Span< float3 > normals, const Span< int > grid_to_face_map, const Span< bool > sharp_faces, const bool use_flat_layout, const Span< int > grids, gpu::VertBuf &vert_buf)
DrawCache & ensure_draw_data(std::unique_ptr< bke::pbvh::DrawCache > &ptr)
static const GPUVertFormat & position_format()
static void create_lines_index_grids(const Span< int > grid_indices, int display_gridsize, const BitGroupVector<> &grid_hidden, const int gridsize, const int skip, const int totgrid, GPUIndexBufBuilder &elb_lines)
static GPUVertFormat attribute_format(const OrigMeshData &orig_mesh_data, const StringRefNull name, const eCustomDataType data_type)
static void create_tri_index_grids_flat_layout(const Span< int > grid_indices, const BitGroupVector<> &grid_hidden, const int gridsize, const int skip, const int totgrid, GPUIndexBufBuilder &elb)
static void fill_vbo_face_set_mesh(const OffsetIndices< int > faces, const Span< int > face_sets, const int color_default, const int color_seed, const Span< int > face_indices, gpu::VertBuf &vert_buf)
static GPUVertFormat format_for_request(const OrigMeshData &orig_mesh_data, const AttributeRequest &request)
T fallback_value_for_fill()
const T & bmesh_cd_face_get(const BMFace &face, const int offset)
static gpu::IndexBuf * create_tri_index_mesh(const OffsetIndices< int > faces, const Span< int3 > corner_tris, const Span< bool > hide_poly, const bke::pbvh::MeshNode &node)
static BLI_NOINLINE void flush_vbo_data(const Span< gpu::VertBuf * > vbos, const IndexMask &node_mask)
static void fill_vbo_attribute_mesh(const OffsetIndices< int > faces, const Span< int > corner_verts, const GSpan attribute, const bke::AttrDomain domain, const Span< int > face_indices, gpu::VertBuf &vert_buf)
static BLI_NOINLINE void ensure_vbos_allocated_mesh(const Object &object, const GPUVertFormat &format, const IndexMask &node_mask, const MutableSpan< gpu::VertBuf * > vbos)
static void fill_vbo_normal_mesh(const OffsetIndices< int > faces, const Span< int > corner_verts, const Span< bool > sharp_faces, const Span< float3 > vert_normals, const Span< float3 > face_normals, const Span< int > face_indices, gpu::VertBuf &vert_buf)
void extract_data_face_bmesh(const Set< BMFace *, 0 > &faces, const int cd_offset, gpu::VertBuf &vbo)
static Array< int > calc_material_indices(const Object &object, const OrigMeshData &orig_mesh_data)
short4 normal_float_to_short(const float3 &value)
static void fill_vbo_normal_bmesh(const Set< BMFace *, 0 > &faces, gpu::VertBuf &vbo)
static void fill_vbo_position_bmesh(const Set< BMFace *, 0 > &faces, gpu::VertBuf &vbo)
static void fill_vbo_mask_mesh(const OffsetIndices< int > faces, const Span< int > corner_verts, const Span< float > mask, const Span< int > face_indices, gpu::VertBuf &vbo)
static BLI_NOINLINE void free_batches(const MutableSpan< gpu::Batch * > batches, const IndexMask &node_mask)
static bool pbvh_attr_supported(const AttributeRequest &request)
static void fill_vbo_mask_bmesh(const Set< BMFace *, 0 > &faces, const int cd_offset, gpu::VertBuf &vbo)
void extract_data_vert_bmesh(const Set< BMFace *, 0 > &faces, const int cd_offset, gpu::VertBuf &vbo)
static void fill_vbo_face_set_bmesh(const Set< BMFace *, 0 > &faces, const int color_default, const int color_seed, const int offset, gpu::VertBuf &vbo)
void extract_data_face_mesh(const OffsetIndices< int > faces, const Span< T > attribute, const Span< int > face_indices, gpu::VertBuf &vbo)
static gpu::IndexBuf * create_index_faces(const OffsetIndices< int > faces, const Span< bool > hide_poly, const Span< int > face_indices)
static BLI_NOINLINE void free_ibos(const MutableSpan< gpu::IndexBuf * > ibos, const IndexMask &node_mask)
static void fill_vbo_mask_grids(const CCGKey &key, const Span< float > masks, const bool use_flat_layout, const Span< int > grids, gpu::VertBuf &vert_buf)
void extract_data_corner_bmesh(const Set< BMFace *, 0 > &faces, const int cd_offset, gpu::VertBuf &vbo)
static BLI_NOINLINE void free_vbos(const MutableSpan< gpu::VertBuf * > vbos, const IndexMask &node_mask)
static void create_lines_index_grids_flat_layout(const Span< int > grid_indices, int display_gridsize, const BitGroupVector<> &grid_hidden, const int gridsize, const int skip, const int totgrid, GPUIndexBufBuilder &elb_lines)
static void fill_vbo_attribute_bmesh(const Set< BMFace *, 0 > &faces, const eCustomDataType data_type, const bke::AttrDomain domain, const int offset, gpu::VertBuf &vbo)
static void fill_vbos_mesh(const Object &object, const OrigMeshData &orig_mesh_data, const IndexMask &node_mask, const AttributeRequest &request, const MutableSpan< gpu::VertBuf * > vbos)
static void fill_vbos_bmesh(const Object &object, const OrigMeshData &orig_mesh_data, const IndexMask &node_mask, const AttributeRequest &request, const MutableSpan< gpu::VertBuf * > vbos)
static void fill_vbos_grids(const Object &object, const OrigMeshData &orig_mesh_data, const BitSpan use_flat_layout, const IndexMask &node_mask, const AttributeRequest &request, const MutableSpan< gpu::VertBuf * > vbos)
const T & bmesh_cd_vert_get(const BMVert &vert, const int offset)
static const GPUVertFormat & mask_format()
std::variant< CustomRequest, GenericRequest > AttributeRequest
GPUVertFormat init_format_for_attribute(const eCustomDataType data_type, const StringRefNull vbo_name)
void parallel_for(const IndexRange range, const int64_t grain_size, const Function &function, const TaskSizeHints &size_hints=detail::TaskSizeHints_Static(1))
VecBase< uint32_t, 2 > uint2
blender::VecBase< int16_t, 4 > short4
blender::VecBase< uint8_t, 4 > uchar4
uint64_t get_default_hash(const T &v)
ColorSceneLinear4f< eAlpha::Premultiplied > ColorGeometry4f
unsigned __int64 uint64_t
blender::BitGroupVector grid_hidden
blender::Span< int > grid_to_face_map
uint64_t operator()(const draw::pbvh::AttributeRequest &value) const
OrigMeshData(const Mesh &mesh)
bke::AttributeAccessor attributes
Vector< AttributeRequest > attributes