73 for (
const int i : indices_to_reset) {
83 const int indexed_elems_num,
88 r_bits.
resize(indexed_elems_num,
true);
100 if (!
mesh.
runtime->loose_edges_cache.is_cached() ||
mesh.loose_edges().count > 0) {
103 if (!
mesh.
runtime->loose_verts_cache.is_cached() ||
mesh.loose_verts().count > 0) {
117 this->runtime->corner_to_face_map_cache.ensure([&](
Array<int> &r_data) {
121 return this->runtime->corner_to_face_map_cache.data();
127 this->runtime->vert_to_face_offset_cache.ensure([&](
Array<int> &r_data) {
131 return OffsetIndices<int>(this->runtime->vert_to_face_offset_cache.data());
137 const OffsetIndices offsets = this->vert_to_face_map_offsets();
138 this->runtime->vert_to_face_map_cache.ensure([&](
Array<int> &r_data) {
140 if (this->runtime->vert_to_corner_map_cache.is_cached() &&
141 this->runtime->corner_to_face_map_cache.is_cached())
145 array_utils::gather(this->runtime->corner_to_face_map_cache.data().as_span(),
146 this->runtime->vert_to_corner_map_cache.data().as_span(),
147 r_data.as_mutable_span());
150 bke::mesh::build_vert_to_face_indices(this->faces(), this->corner_verts(), offsets, r_data);
153 return {offsets, this->runtime->vert_to_face_map_cache.data()};
159 const OffsetIndices offsets = this->vert_to_face_map_offsets();
160 this->runtime->vert_to_corner_map_cache.ensure([&](
Array<int> &r_data) {
163 return {offsets, this->runtime->vert_to_corner_map_cache.data()};
169 this->runtime->loose_verts_cache.ensure([&](
LooseVertCache &r_data) {
174 return this->runtime->loose_verts_cache.data();
180 this->runtime->verts_no_face_cache.ensure([&](
LooseVertCache &r_data) {
185 return this->runtime->verts_no_face_cache.data();
188bool Mesh::no_overlapping_topology()
const
196 this->runtime->loose_edges_cache.ensure([&](
LooseEdgeCache &r_data) {
197 const Span<int> edges = this->corner_edges();
201 return this->runtime->loose_edges_cache.data();
204void Mesh::tag_loose_verts_none()
const
207 this->runtime->loose_verts_cache.ensure([&](
LooseVertCache &r_data) {
214void Mesh::tag_loose_edges_none()
const
217 this->runtime->loose_edges_cache.ensure([&](
LooseEdgeCache &r_data) {
224void Mesh::tag_overlapping_none()
232void TrianglesCache::freeze()
235 this->dirty_while_frozen =
false;
238void TrianglesCache::unfreeze()
240 this->frozen =
false;
241 if (this->dirty_while_frozen) {
242 this->
data.tag_dirty();
244 this->dirty_while_frozen =
false;
247void TrianglesCache::tag_dirty()
250 this->dirty_while_frozen =
true;
253 this->
data.tag_dirty();
264 const Span<int> corner_verts = this->corner_verts();
273 positions,
faces, corner_verts, this->face_normals(), r_data);
277 return this->runtime->corner_tris_cache.data.data();
288 return this->runtime->corner_tri_faces_cache.data();
300 mesh->
runtime->edit_data = std::make_unique<blender::bke::EditMeshData>();
319 mesh->
runtime->vert_to_face_offset_cache.tag_dirty();
321 mesh->
runtime->vert_to_corner_map_cache.tag_dirty();
322 mesh->
runtime->corner_to_face_map_cache.tag_dirty();
324 mesh->
runtime->vert_normals_true_cache.tag_dirty();
326 mesh->
runtime->face_normals_true_cache.tag_dirty();
333 mesh->
runtime->shrinkwrap_boundary_cache.tag_dirty();
335 mesh->
runtime->subsurf_face_dot_tags.clear_and_shrink();
336 mesh->
runtime->subsurf_optimal_display_edges.clear_and_shrink();
337 mesh->
flag &= ~ME_NO_OVERLAPPING_TOPOLOGY;
340void Mesh::tag_edges_split()
344 this->runtime->vert_normals_cache.tag_dirty();
345 this->runtime->corner_normals_cache.tag_dirty();
346 this->runtime->subdiv_ccg.reset();
347 this->runtime->vert_to_face_offset_cache.tag_dirty();
348 this->runtime->vert_to_face_map_cache.tag_dirty();
349 this->runtime->vert_to_corner_map_cache.tag_dirty();
350 if (this->runtime->loose_edges_cache.is_cached() &&
351 this->runtime->loose_edges_cache.data().count != 0)
353 this->runtime->loose_edges_cache.tag_dirty();
355 if (this->runtime->loose_verts_cache.is_cached() &&
356 this->runtime->loose_verts_cache.data().count != 0)
358 this->runtime->loose_verts_cache.tag_dirty();
360 if (this->runtime->verts_no_face_cache.is_cached() &&
361 this->runtime->verts_no_face_cache.data().count != 0)
363 this->runtime->verts_no_face_cache.tag_dirty();
365 this->runtime->subsurf_face_dot_tags.clear_and_shrink();
366 this->runtime->subsurf_optimal_display_edges.clear_and_shrink();
367 this->runtime->shrinkwrap_boundary_cache.tag_dirty();
370void Mesh::tag_sharpness_changed()
372 this->runtime->vert_normals_cache.tag_dirty();
373 this->runtime->face_normals_cache.tag_dirty();
374 this->runtime->corner_normals_cache.tag_dirty();
377void Mesh::tag_custom_normals_changed()
379 this->runtime->vert_normals_cache.tag_dirty();
380 this->runtime->face_normals_cache.tag_dirty();
381 this->runtime->corner_normals_cache.tag_dirty();
384void Mesh::tag_face_winding_changed()
386 this->runtime->vert_normals_cache.tag_dirty();
387 this->runtime->face_normals_cache.tag_dirty();
388 this->runtime->vert_normals_true_cache.tag_dirty();
389 this->runtime->face_normals_true_cache.tag_dirty();
390 this->runtime->corner_normals_cache.tag_dirty();
391 this->runtime->vert_to_corner_map_cache.tag_dirty();
392 this->runtime->shrinkwrap_boundary_cache.tag_dirty();
395void Mesh::tag_positions_changed()
397 this->runtime->vert_normals_cache.tag_dirty();
398 this->runtime->face_normals_cache.tag_dirty();
399 this->runtime->vert_normals_true_cache.tag_dirty();
400 this->runtime->face_normals_true_cache.tag_dirty();
401 this->runtime->corner_normals_cache.tag_dirty();
402 this->runtime->shrinkwrap_boundary_cache.tag_dirty();
403 this->tag_positions_changed_no_normals();
406void Mesh::tag_positions_changed_no_normals()
409 this->runtime->corner_tris_cache.tag_dirty();
410 this->runtime->bounds_cache.tag_dirty();
411 this->runtime->shrinkwrap_boundary_cache.tag_dirty();
414void Mesh::tag_positions_changed_uniformly()
418 this->runtime->bounds_cache.tag_dirty();
421void Mesh::tag_topology_changed()
426void Mesh::tag_visibility_changed()
428 this->runtime->bvh_cache_corner_tris_no_hidden.tag_dirty();
429 this->runtime->bvh_cache_loose_verts_no_hidden.tag_dirty();
430 this->runtime->bvh_cache_loose_edges_no_hidden.tag_dirty();
433void Mesh::tag_material_index_changed()
435 this->runtime->max_material_index.tag_dirty();
458 if (mesh_eval && mesh_eval->
runtime->batch_cache) {
477 const bool do_verbose =
true;
478 const bool do_fixes =
false;
489 Span<int> face_offsets = mesh_eval->face_offsets();
490 Span<int> corner_verts = mesh_eval->corner_verts();
511 reinterpret_cast<float(*)[3]
>(positions.
data()),
CustomData interface, see also DNA_customdata_types.h.
void * CustomData_get_layer_for_write(CustomData *data, eCustomDataType type, int totelem)
void BKE_id_free(Main *bmain, void *idv)
void BKE_mesh_batch_cache_dirty_tag(Mesh *mesh, eMeshBatchDirtyMode mode)
void(* BKE_mesh_batch_cache_free_cb)(void *batch_cache)
bool BKE_mesh_validate_all_customdata(CustomData *vert_data, uint verts_num, CustomData *edge_data, uint edges_num, CustomData *corner_data, uint corners_num, CustomData *face_data, uint faces_num, bool check_meshmask, bool do_verbose, bool do_fixes, bool *r_change)
void(* BKE_mesh_batch_cache_dirty_tag_cb)(Mesh *mesh, eMeshBatchDirtyMode mode)
void BKE_mesh_batch_cache_free(void *batch_cache)
bool BKE_mesh_face_normals_are_dirty(const Mesh *mesh)
bool BKE_mesh_validate_arrays(Mesh *mesh, float(*vert_positions)[3], unsigned int verts_num, blender::int2 *edges, unsigned int edges_num, MFace *legacy_faces, unsigned int legacy_faces_num, const int *corner_verts, int *corner_edges, unsigned int corners_num, const int *face_offsets, unsigned int faces_num, MDeformVert *dverts, bool do_verbose, bool do_fixes, bool *r_change)
bool BKE_mesh_runtime_is_valid(Mesh *mesh_eval)
void BKE_mesh_runtime_ensure_edit_data(Mesh *mesh)
void BKE_mesh_runtime_clear_cache(Mesh *mesh)
void BKE_mesh_runtime_clear_geometry(Mesh *mesh)
int BKE_mesh_runtime_corner_tris_len(const Mesh *mesh)
MINLINE int poly_to_tri_count(int poly_count, int corner_count)
@ ME_NO_OVERLAPPING_TOPOLOGY
void reinitialize(const int64_t new_size)
constexpr int64_t size() const
constexpr T * data() const
Span< NewT > constexpr cast() const
constexpr const T * data() const
constexpr int64_t size() const
void resize(const int64_t new_size_in_bits, const bool value=false)
void corner_tris_calc(Span< float3 > vert_positions, OffsetIndices< int > faces, Span< int > corner_verts, MutableSpan< int3 > corner_tris)
Array< int > build_corner_to_face_map(OffsetIndices< int > faces)
Array< int > build_vert_to_corner_indices(Span< int > corner_verts, OffsetIndices< int > offsets)
void corner_tris_calc_with_normals(Span< float3 > vert_positions, OffsetIndices< int > faces, Span< int > corner_verts, Span< float3 > face_normals, MutableSpan< int3 > corner_tris)
void corner_tris_calc_face_indices(OffsetIndices< int > faces, MutableSpan< int > tri_faces)
static void try_tag_verts_no_face_none(const Mesh &mesh)
static void bit_vector_with_reset_bits_or_empty(const Span< int > indices_to_reset, const int indexed_elems_num, BitVector<> &r_bits, int &r_count)
static int reset_bits_and_count(MutableBitSpan bits, const Span< int > indices_to_reset)
static void free_bvh_caches(MeshRuntime &mesh_runtime)
static void free_batch_cache(MeshRuntime &mesh_runtime)
static void free_mesh_eval(MeshRuntime &mesh_runtime)
void build_reverse_offsets(Span< int > indices, MutableSpan< int > offsets)
MeshRuntimeHandle * runtime
blender::BitVector is_loose_bits
SharedCache< std::unique_ptr< BVHTree, BVHTreeDeleter > > bvh_cache_loose_verts
SharedCache< std::unique_ptr< BVHTree, BVHTreeDeleter > > bvh_cache_loose_edges_no_hidden
SharedCache< std::unique_ptr< BVHTree, BVHTreeDeleter > > bvh_cache_corner_tris
SharedCache< std::unique_ptr< BVHTree, BVHTreeDeleter > > bvh_cache_edges
SharedCache< std::unique_ptr< BVHTree, BVHTreeDeleter > > bvh_cache_verts
SharedCache< std::unique_ptr< BVHTree, BVHTreeDeleter > > bvh_cache_loose_verts_no_hidden
SharedCache< std::unique_ptr< BVHTree, BVHTreeDeleter > > bvh_cache_loose_edges
SharedCache< std::unique_ptr< BVHTree, BVHTreeDeleter > > bvh_cache_faces
SharedCache< std::unique_ptr< BVHTree, BVHTreeDeleter > > bvh_cache_corner_tris_no_hidden