55 const bool no_loose_vert_hint = mesh.
runtime->loose_verts_cache.is_cached() &&
56 mesh.runtime->loose_verts_cache.data().count == 0;
57 const bool no_loose_edge_hint = mesh.runtime->loose_edges_cache.is_cached() &&
58 mesh.runtime->loose_edges_cache.data().count == 0;
60 mesh.edges_num > 4096 && !no_loose_vert_hint && !no_loose_edge_hint,
62 const bke::LooseEdgeCache &loose_edges = mesh.loose_edges();
63 if (loose_edges.count > 0) {
64 cache.loose_geom.edges.reinitialize(loose_edges.count);
65 extract_set_bits(loose_edges.is_loose_bits, cache.loose_geom.edges);
70 if (loose_verts.
count > 0) {
71 cache.loose_geom.verts.reinitialize(loose_verts.
count);
87 if (vert->
e ==
nullptr) {
88 loose_verts[
count] = i;
110 if (edge->l ==
nullptr) {
111 loose_edges[
count] = i;
170 Array<int> &tri_counts = all_tri_counts.local();
171 const short last_index = tri_counts.size() - 1;
172 for (const int i : range) {
173 const BMFace &face = *BM_face_at_index(&const_cast<BMesh &>(bm), i);
174 if (!BM_elem_flag_test(&face, BM_ELEM_HIDDEN)) {
175 const short mat = std::clamp<short>(face.mat_nr, 0, last_index);
176 tri_counts[mat] += face.len - 2;
190 all_tri_counts.local().
first() = threading::parallel_reduce(
195 for (const int face : range) {
196 if (!hide_poly[face]) {
197 count += bke::mesh::face_triangles_num(faces[face].size());
210 threading::parallel_for(material_indices.index_range(), 1024, [&](
const IndexRange range) {
211 Array<int> &tri_counts = all_tri_counts.local();
212 const int last_index = tri_counts.size() - 1;
213 if (!hide_poly.is_empty()) {
214 for (const int i : range) {
216 const int mat = std::clamp(material_indices[i], 0, last_index);
217 tri_counts[mat] += bke::mesh::face_triangles_num(faces[i].size());
222 for (const int i : range) {
223 const int mat = std::clamp(material_indices[i], 0, last_index);
224 tri_counts[mat] += bke::mesh::face_triangles_num(faces[i].size());
243 Array<int> &tris_num_by_material = all_tri_counts.local();
244 for (
const Array<int> &counts : all_tri_counts) {
245 if (&counts != &tris_num_by_material) {
246 for (
const int i : tris_num_by_material.
index_range()) {
247 tris_num_by_material[i] += counts[i];
251 return std::move(tris_num_by_material);
260 face_tri_offsets.
fill(-1);
271 const int mat = std::clamp(
int(face->mat_nr), 0, mat_last);
272 face_tri_offsets[i] = material_tri_starts[mat];
273 material_tri_starts[mat] += face->len - 2;
276 return face_tri_offsets;
281 const int used_materials = std::count_if(
284 [&](
const int i) { return material_tri_starts[i].size() > 0; });
285 return used_materials == 1;
301 face_tri_offsets.
fill(-1);
304 if (single_material) {
306 for (
const int face : faces.index_range()) {
307 if (hide_poly[face]) {
310 face_tri_offsets[face] = offset;
311 offset += bke::mesh::face_triangles_num(faces[face].
size());
313 return face_tri_offsets;
318 for (
const int face : faces.index_range()) {
319 if (!hide_poly.
is_empty() && hide_poly[face]) {
322 const int mat = std::clamp(material_indices[face], 0, mat_last);
323 face_tri_offsets[face] = material_tri_starts[mat];
324 material_tri_starts[mat] += bke::mesh::face_triangles_num(faces[face].
size());
327 return face_tri_offsets;
337 material_tri_starts.
as_mutable_span().drop_back(1).copy_from(tris_num_by_material);
338 offset_indices::accumulate_counts_to_offsets(material_tri_starts);
368 if (mesh.runtime->edit_mesh !=
nullptr) {
370 return *editmesh_eval_final;
379 switch (mesh.runtime->wrapper_type) {
382 return mesh.corner_data;
385 return mesh.runtime->edit_mesh->bm->ldata;
390 return mesh.corner_data;
395 switch (mesh.runtime->wrapper_type) {
398 return mesh.face_data;
401 return mesh.runtime->edit_mesh->bm->pdata;
406 return mesh.face_data;
411 switch (mesh.runtime->wrapper_type) {
414 return mesh.edge_data;
417 return mesh.runtime->edit_mesh->bm->edata;
422 return mesh.edge_data;
427 switch (mesh.runtime->wrapper_type) {
430 return mesh.vert_data;
433 return mesh.runtime->edit_mesh->bm->vdata;
438 return mesh.vert_data;
458 return bke::MeshNormalDomain::Point;
462 return bke::MeshNormalDomain::Corner;
469 if (face_mix == array_utils::BooleanMix::AllTrue) {
470 return bke::MeshNormalDomain::Face;
477 if (edge_mix == array_utils::BooleanMix::AllTrue) {
478 return bke::MeshNormalDomain::Face;
481 if (edge_mix == array_utils::BooleanMix::AllFalse &&
482 face_mix == array_utils::BooleanMix::AllFalse)
484 return bke::MeshNormalDomain::Point;
487 return bke::MeshNormalDomain::Corner;
533 const bool is_editmode,
534 const bool is_paint_mode,
535 const bool edit_mode_active,
538 const bool do_uvedit,
542 std::unique_ptr<MeshRenderData> mr = std::make_unique<MeshRenderData>();
543 mr->toolsettings = ts;
546 mr->object_to_world = object_to_world;
548 mr->use_hide = use_hide;
554 BLI_assert(editmesh_eval_cage && editmesh_eval_final);
555 mr->bm = mesh.runtime->edit_mesh->bm;
556 mr->edit_bmesh = mesh.runtime->edit_mesh.get();
557 mr->mesh = (do_final) ? editmesh_eval_final : editmesh_eval_cage;
558 mr->edit_data = edit_mode_active ? mr->mesh->runtime->edit_data.get() :
nullptr;
561 mr->hide_unmapped_edges = !do_final || editmesh_eval_final == editmesh_eval_cage;
564 if (!emd->vert_positions.is_empty()) {
565 mr->bm_vert_coords = mr->edit_data->vert_positions;
595 if ((edit_mode_active && mr->mesh->runtime->is_original_bmesh &&
597 (do_uvedit && !do_final))
605 if (edit_mode_active && do_final) {
606 mr->orig_index_vert =
static_cast<const int *
>(
608 mr->orig_index_edge =
static_cast<const int *
>(
610 mr->orig_index_face =
static_cast<const int *
>(
614 mr->orig_index_vert =
nullptr;
615 mr->orig_index_edge =
nullptr;
616 mr->orig_index_face =
nullptr;
622 mr->edit_bmesh =
nullptr;
624 mr->hide_unmapped_edges =
false;
626 if (is_paint_mode && mr->mesh) {
627 mr->orig_index_vert =
static_cast<const int *
>(
629 mr->orig_index_edge =
static_cast<const int *
>(
631 mr->orig_index_face =
static_cast<const int *
>(
635 mr->orig_index_vert =
nullptr;
636 mr->orig_index_edge =
nullptr;
637 mr->orig_index_face =
nullptr;
643 mr->verts_num = mr->mesh->verts_num;
644 mr->edges_num = mr->mesh->edges_num;
645 mr->faces_num = mr->mesh->faces_num;
646 mr->corners_num = mr->mesh->corners_num;
649 mr->vert_positions = mr->mesh->vert_positions();
650 mr->edges = mr->mesh->edges();
651 mr->faces = mr->mesh->faces();
652 mr->corner_verts = mr->mesh->corner_verts();
653 mr->corner_edges = mr->mesh->corner_edges();
655 mr->orig_index_vert =
static_cast<const int *
>(
657 mr->orig_index_edge =
static_cast<const int *
>(
659 mr->orig_index_face =
static_cast<const int *
>(
662 mr->normals_domain = mr->mesh->normals_domain();
666 mr->material_indices = *attributes.lookup<
int>(
"material_index", bke::AttrDomain::Face);
668 if (edit_mode_active || is_paint_mode) {
670 mr->hide_vert = *attributes.lookup<
bool>(
".hide_vert", bke::AttrDomain::Point);
671 mr->hide_edge = *attributes.lookup<
bool>(
".hide_edge", bke::AttrDomain::Edge);
672 mr->hide_poly = *attributes.lookup<
bool>(
".hide_poly", bke::AttrDomain::Face);
675 mr->select_vert = *attributes.lookup<
bool>(
".select_vert", bke::AttrDomain::Point);
676 mr->select_edge = *attributes.lookup<
bool>(
".select_edge", bke::AttrDomain::Edge);
677 mr->select_poly = *attributes.lookup<
bool>(
".select_poly", bke::AttrDomain::Face);
680 mr->sharp_faces = *attributes.lookup<
bool>(
"sharp_face", bke::AttrDomain::Face);
int CustomData_get_offset(const CustomData *data, eCustomDataType type)
const void * CustomData_get_layer(const CustomData *data, eCustomDataType type)
int CustomData_get_offset_named(const CustomData *data, eCustomDataType type, blender::StringRef name)
bool CustomData_has_layer(const CustomData *data, eCustomDataType type)
blender::Span< blender::float3 > BKE_editmesh_cache_ensure_vert_normals(BMEditMesh &em, blender::bke::EditMeshData &emd)
blender::Span< blender::float3 > BKE_editmesh_cache_ensure_face_normals(BMEditMesh &em, blender::bke::EditMeshData &emd)
General operations, lookup, etc. for blender objects.
const Mesh * BKE_object_get_editmesh_eval_cage(const Object *object)
const Mesh * BKE_object_get_editmesh_eval_final(const Object *object)
MINLINE int poly_to_tri_count(int poly_count, int corner_count)
BMFace * EDBM_uv_active_face_get(BMEditMesh *em, bool sloppy, bool selected)
Read Guarded memory(de)allocation.
#define BM_elem_flag_test(ele, hflag)
#define BM_ITER_MESH_INDEX(ele, iter, bm, itype, indexvar)
ATTR_WARN_UNUSED_RESULT BMesh * bm
BMVert * BM_mesh_active_vert_get(BMesh *bm)
BMEdge * BM_mesh_active_edge_get(BMesh *bm)
BMFace * BM_mesh_active_face_get(BMesh *bm, const bool is_sloppy, const bool is_selected)
void BM_mesh_elem_table_ensure(BMesh *bm, const char htype)
void BM_mesh_elem_index_ensure(BMesh *bm, const char htype)
void BM_loops_calc_normal_vcos(BMesh *bm, const Span< float3 > vcos, const Span< float3 > vnos, const Span< float3 > fnos, const bool use_split_normals, MutableSpan< float3 > r_lnos, MLoopNorSpaceArray *r_lnors_spacearr, short(*clnors_data)[2], const int cd_loop_clnors_offset, const bool do_rebuild)
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Span< T > as_span() const
MutableSpan< T > as_mutable_span()
const T & last(const int64_t n=0) const
IndexRange index_range() const
void fill(const T &value) const
void reinitialize(const int64_t new_size)
constexpr Iterator end() const
constexpr Iterator begin() const
constexpr Span< T > as_span() const
constexpr const T & first() const
constexpr bool is_empty() const
IndexRange index_range() const
IndexRange index_range() const
draw_view push_constant(Type::INT, "radiance_src") .push_constant(Type capture_info_buf storage_buf(1, Qualifier::READ, "ObjectBounds", "bounds_buf[]") .push_constant(Type draw_view int
const CustomData & mesh_cd_ldata_get_from_mesh(const Mesh &mesh)
static Array< int > calc_face_tri_starts_bmesh(const MeshRenderData &mr, MutableSpan< int > material_tri_starts)
void mesh_render_data_update_face_normals(MeshRenderData &mr)
static Array< int > mesh_render_data_mat_tri_len_build(const MeshRenderData &mr)
static bool mesh_is_single_material(const OffsetIndices< int > material_tri_starts)
static void mesh_render_data_loose_verts_bm(const MeshRenderData &mr, MeshBufferCache &cache, BMesh &bm)
const CustomData & mesh_cd_edata_get_from_mesh(const Mesh &mesh)
static void mesh_render_data_loose_geom_ensure(const MeshRenderData &mr, MeshBufferCache &cache)
static bke::MeshNormalDomain bmesh_normals_domain(BMesh *bm)
static void accumululate_material_counts_mesh(const MeshRenderData &mr, threading::EnumerableThreadSpecific< Array< int > > &all_tri_counts)
int mesh_render_mat_len_get(const Object &object, const Mesh &mesh)
static void accumululate_material_counts_bm(const BMesh &bm, threading::EnumerableThreadSpecific< Array< int > > &all_tri_counts)
static void retrieve_active_attribute_names(MeshRenderData &mr, const Object &object, const Mesh &mesh)
static std::optional< Array< int > > calc_face_tri_starts_mesh(const MeshRenderData &mr, MutableSpan< int > material_tri_starts)
const Mesh & editmesh_final_or_this(const Object &object, const Mesh &mesh)
static void mesh_render_data_loose_geom_mesh(const MeshRenderData &mr, MeshBufferCache &cache)
std::unique_ptr< MeshRenderData > mesh_render_data_create(Object &object, Mesh &mesh, const bool is_editmode, const bool is_paint_mode, const bool edit_mode_active, const float4x4 &object_to_world, const bool do_final, const bool do_uvedit, const bool use_hide, const ToolSettings *ts)
void mesh_render_data_update_corner_normals(MeshRenderData &mr)
const SortedFaceData & mesh_render_data_faces_sorted_ensure(const MeshRenderData &mr, MeshBufferCache &cache)
const CustomData & mesh_cd_vdata_get_from_mesh(const Mesh &mesh)
void mesh_render_data_update_loose_geom(MeshRenderData &mr, MeshBufferCache &cache)
static void mesh_render_data_loose_geom_build(const MeshRenderData &mr, MeshBufferCache &cache)
static void extract_set_bits(const BitSpan bits, MutableSpan< int > indices)
static SortedFaceData mesh_render_data_faces_sorted_build(const MeshRenderData &mr)
static void mesh_render_data_loose_edges_bm(const MeshRenderData &mr, MeshBufferCache &cache, BMesh &bm)
static bool bm_face_is_sharp(const BMFace *const &face)
static bool bm_edge_is_sharp(const BMEdge *const &edge)
const CustomData & mesh_cd_pdata_get_from_mesh(const Mesh &mesh)
void parallel_invoke(Functions &&...functions)
MeshRuntimeHandle * runtime
char * default_color_attribute
char * active_color_attribute
blender::BitVector is_loose_bits
MeshExtractLooseGeom loose_geom
SortedFaceData face_sorted
const char * default_color_name
Span< float3 > bm_vert_coords
Span< float3 > bm_vert_normals
const char * active_color_name
eMRExtractType extract_type
Span< float3 > bm_face_normals
Span< float3 > face_normals
Span< float3 > corner_normals
VArraySpan< int > material_indices
VArraySpan< bool > hide_poly
OffsetIndices< int > faces
Array< float3 > bm_loop_normals
std::optional< Array< int > > face_tri_offsets
Array< int > tris_num_by_material