52 const bool no_loose_vert_hint = mesh.
runtime->loose_verts_cache.is_cached() &&
53 mesh.
runtime->loose_verts_cache.data().count == 0;
54 const bool no_loose_edge_hint = mesh.
runtime->loose_edges_cache.is_cached() &&
55 mesh.
runtime->loose_edges_cache.data().count == 0;
57 mesh.
edges_num > 4096 && !no_loose_vert_hint && !no_loose_edge_hint,
59 const bke::LooseEdgeCache &loose_edges = mesh.loose_edges();
60 if (loose_edges.count > 0) {
61 cache.loose_geom.edges.reinitialize(loose_edges.count);
62 extract_set_bits(loose_edges.is_loose_bits, cache.loose_geom.edges);
67 if (loose_verts.
count > 0) {
68 cache.loose_geom.verts.reinitialize(loose_verts.
count);
84 if (vert->
e ==
nullptr) {
107 if (edge->
l ==
nullptr) {
165 Array<int> &tri_counts = all_tri_counts.local();
166 const short last_index = tri_counts.size() - 1;
167 for (const int i : range) {
168 const BMFace &face = *BM_face_at_index(&const_cast<BMesh &>(bm), i);
169 if (!BM_elem_flag_test(&face, BM_ELEM_HIDDEN)) {
170 const short mat = std::clamp<short>(face.mat_nr, 0, last_index);
171 tri_counts[mat] += face.len - 2;
190 for (const int face : range) {
191 if (!hide_poly[face]) {
192 count += bke::mesh::face_triangles_num(faces[face].size());
206 Array<int> &tri_counts = all_tri_counts.local();
207 const int last_index = tri_counts.size() - 1;
208 if (!hide_poly.is_empty()) {
209 for (const int i : range) {
211 const int mat = std::clamp(material_indices[i], 0, last_index);
212 tri_counts[mat] += bke::mesh::face_triangles_num(faces[i].size());
217 for (const int i : range) {
218 const int mat = std::clamp(material_indices[i], 0, last_index);
219 tri_counts[mat] += bke::mesh::face_triangles_num(faces[i].size());
238 Array<int> &tris_num_by_material = all_tri_counts.local();
239 for (
const Array<int> &counts : all_tri_counts) {
240 if (&counts != &tris_num_by_material) {
241 for (
const int i : tris_num_by_material.
index_range()) {
242 tris_num_by_material[
i] += counts[
i];
246 return std::move(tris_num_by_material);
255 face_tri_offsets.
fill(-1);
266 const int mat = std::clamp(
int(face->
mat_nr), 0, mat_last);
267 face_tri_offsets[
i] = material_tri_starts[mat];
268 material_tri_starts[mat] += face->
len - 2;
271 return face_tri_offsets;
276 const int used_materials = std::count_if(
279 [&](
const int i) { return material_tri_starts[i].size() > 0; });
280 return used_materials == 1;
296 face_tri_offsets.
fill(-1);
299 if (single_material) {
301 for (
const int face :
faces.index_range()) {
302 if (hide_poly[face]) {
305 face_tri_offsets[face] = offset;
308 return face_tri_offsets;
313 for (
const int face :
faces.index_range()) {
314 if (!hide_poly.
is_empty() && hide_poly[face]) {
317 const int mat = std::clamp(material_indices[face], 0, mat_last);
318 face_tri_offsets[face] = material_tri_starts[mat];
322 return face_tri_offsets;
332 material_tri_starts.
as_mutable_span().drop_back(1).copy_from(tris_num_by_material);
363 switch (mesh.
runtime->wrapper_type) {
369 return mesh.
runtime->edit_mesh->bm->ldata;
379 switch (mesh.
runtime->wrapper_type) {
385 return mesh.
runtime->edit_mesh->bm->pdata;
395 switch (mesh.
runtime->wrapper_type) {
401 return mesh.
runtime->edit_mesh->bm->edata;
411 switch (mesh.
runtime->wrapper_type) {
417 return mesh.
runtime->edit_mesh->bm->vdata;
441 if (
bm->totface == 0) {
536 const bool is_editmode,
537 const bool is_paint_mode,
539 const bool do_uvedit,
550 if (editmesh_orig && editmesh_orig->
runtime->edit_mesh) {
553 mr.
bm = editmesh_orig->
runtime->edit_mesh->bm;
555 mr.
mesh = (do_final) ? &mesh : eval_cage;
569 if (!emd->vert_positions.is_empty()) {
606 (do_uvedit && !do_final))
614 if (is_editmode && do_final) {
635 if (is_paint_mode && mr.
mesh) {
676 if (is_editmode || is_paint_mode) {
const void * CustomData_get_layer(const CustomData *data, eCustomDataType type)
bool CustomData_has_layer_named(const CustomData *data, eCustomDataType type, blender::StringRef name)
int CustomData_get_offset_named(const CustomData *data, eCustomDataType type, blender::StringRef name)
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 materials.
int BKE_object_material_used_with_fallback_eval(const Object &ob)
General operations, lookup, etc. for blender objects.
const Mesh * BKE_object_get_pre_modified_mesh(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)
#define BM_elem_flag_test(ele, hflag)
#define BM_ITER_MESH_INDEX(ele, iter, bm, itype, indexvar)
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)
constexpr bool is_empty() const
static VArray from_derived_span(Span< StructT > values)
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
constexpr Iterator end() const
constexpr Iterator begin() const
constexpr Span< T > as_span() const
constexpr bool is_empty() const
GAttributeReader lookup(const StringRef attribute_id) const
IndexRange index_range() const
const Mesh * DRW_object_get_editmesh_cage_for_drawing(const Object &object)
BooleanMix booleans_mix_calc(const VArray< bool > &varray, IndexRange range_to_check)
int face_triangles_num(const int face_size)
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)
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)
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)
MeshRenderData mesh_render_data_create(Object &object, Mesh &mesh, const bool is_editmode, const bool is_paint_mode, const bool do_final, const bool do_uvedit, const bool use_hide, const ToolSettings *ts)
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)
OffsetIndices< int > accumulate_counts_to_offsets(MutableSpan< int > counts_to_offsets, int start_offset=0)
void parallel_invoke(Functions &&...functions)
void parallel_for(const IndexRange range, const int64_t grain_size, const Function &function, const TaskSizeHints &size_hints=detail::TaskSizeHints_Static(1))
Value parallel_reduce(IndexRange range, int64_t grain_size, const Value &identity, const Function &function, const Reduction &reduction)
MeshRuntimeHandle * runtime
char * default_color_attribute
char * active_color_attribute
Array< float3 > vert_positions
blender::BitVector is_loose_bits
MeshExtractLooseGeom loose_geom
SortedFaceData face_sorted
VArraySpan< bool > hide_vert
const char * default_color_name
Span< float3 > bm_vert_coords
VArraySpan< bool > hide_edge
Span< float3 > bm_vert_normals
bke::EditMeshData * edit_data
const int * orig_index_vert
const ToolSettings * toolsettings
Span< float3 > vert_positions
MeshExtractType extract_type
const int * orig_index_face
VArraySpan< bool > select_vert
VArraySpan< bool > sharp_faces
const char * active_color_name
int bm_free_normal_offset_face
VArraySpan< bool > select_poly
VArraySpan< bool > select_edge
Span< float3 > bm_face_normals
Span< float3 > face_normals
int bm_free_normal_offset_corner
const int * orig_index_edge
Span< float3 > corner_normals
VArraySpan< int > material_indices
VArraySpan< bool > hide_poly
OffsetIndices< int > faces
bke::MeshNormalDomain normals_domain
int bm_free_normal_offset_vert
Array< float3 > bm_loop_normals
std::optional< Array< int > > face_tri_offsets
Array< int > tris_num_by_material