72 for (
const int i : indices_to_reset) {
82 const int indexed_elems_num,
87 r_bits.
resize(indexed_elems_num,
true);
99 if (!mesh.runtime->loose_edges_cache.is_cached() || mesh.loose_edges().count > 0) {
102 if (!mesh.runtime->loose_verts_cache.is_cached() || mesh.loose_verts().count > 0) {
105 mesh.runtime->verts_no_face_cache.ensure([&](
LooseVertCache &r_data) {
116 this->runtime->corner_to_face_map_cache.ensure([&](
Array<int> &r_data) {
117 const OffsetIndices faces = this->
faces();
120 return this->runtime->corner_to_face_map_cache.data();
126 this->runtime->vert_to_face_offset_cache.ensure([&](
Array<int> &r_data) {
130 return OffsetIndices<int>(this->runtime->vert_to_face_offset_cache.data());
136 const OffsetIndices offsets = this->vert_to_face_map_offsets();
137 this->runtime->vert_to_face_map_cache.ensure([&](
Array<int> &r_data) {
139 if (this->runtime->vert_to_corner_map_cache.is_cached() &&
140 this->runtime->corner_to_face_map_cache.is_cached())
144 array_utils::gather(this->runtime->corner_to_face_map_cache.data().as_span(),
145 this->runtime->vert_to_corner_map_cache.data().as_span(),
146 r_data.as_mutable_span());
149 bke::mesh::build_vert_to_face_indices(this->faces(), this->corner_verts(), offsets, r_data);
152 return {offsets, this->runtime->vert_to_face_map_cache.data()};
158 const OffsetIndices offsets = this->vert_to_face_map_offsets();
159 this->runtime->vert_to_corner_map_cache.ensure([&](
Array<int> &r_data) {
162 return {offsets, this->runtime->vert_to_corner_map_cache.data()};
168 this->runtime->loose_verts_cache.ensure([&](
LooseVertCache &r_data) {
173 return this->runtime->loose_verts_cache.data();
179 this->runtime->verts_no_face_cache.ensure([&](
LooseVertCache &r_data) {
184 return this->runtime->verts_no_face_cache.data();
187bool Mesh::no_overlapping_topology()
const
195 this->runtime->loose_edges_cache.ensure([&](
LooseEdgeCache &r_data) {
196 const Span<int> edges = this->corner_edges();
200 return this->runtime->loose_edges_cache.data();
203void Mesh::tag_loose_verts_none()
const
206 this->runtime->loose_verts_cache.ensure([&](
LooseVertCache &r_data) {
213void Mesh::tag_loose_edges_none()
const
216 this->runtime->loose_edges_cache.ensure([&](
LooseEdgeCache &r_data) {
223void Mesh::tag_overlapping_none()
231void TrianglesCache::freeze()
234 this->dirty_while_frozen =
false;
237void TrianglesCache::unfreeze()
239 this->frozen =
false;
240 if (this->dirty_while_frozen) {
241 this->data.tag_dirty();
243 this->dirty_while_frozen =
false;
246void TrianglesCache::tag_dirty()
249 this->dirty_while_frozen =
true;
252 this->data.tag_dirty();
263 const Span<int> corner_verts = this->corner_verts();
272 positions, faces, corner_verts, this->face_normals(), r_data);
276 return this->runtime->corner_tris_cache.data.data();
283 const OffsetIndices faces = this->
faces();
287 return this->runtime->corner_tri_faces_cache.data();
298 if (!mesh->runtime->edit_data) {
299 mesh->runtime->edit_data = std::make_unique<blender::bke::EditMeshData>();
306 free_mesh_eval(*mesh->runtime);
307 free_batch_cache(*mesh->runtime);
308 mesh->runtime->edit_data.reset();
315 free_bvh_cache(*mesh->runtime);
316 mesh->runtime->subdiv_ccg.reset();
317 mesh->runtime->bounds_cache.tag_dirty();
318 mesh->runtime->vert_to_face_offset_cache.tag_dirty();
319 mesh->runtime->vert_to_face_map_cache.tag_dirty();
320 mesh->runtime->vert_to_corner_map_cache.tag_dirty();
321 mesh->runtime->corner_to_face_map_cache.tag_dirty();
322 mesh->runtime->vert_normals_cache.tag_dirty();
323 mesh->runtime->face_normals_cache.tag_dirty();
324 mesh->runtime->corner_normals_cache.tag_dirty();
325 mesh->runtime->loose_edges_cache.tag_dirty();
326 mesh->runtime->loose_verts_cache.tag_dirty();
327 mesh->runtime->verts_no_face_cache.tag_dirty();
328 mesh->runtime->corner_tris_cache.data.tag_dirty();
329 mesh->runtime->corner_tri_faces_cache.tag_dirty();
330 mesh->runtime->shrinkwrap_boundary_cache.tag_dirty();
331 mesh->runtime->subsurf_face_dot_tags.clear_and_shrink();
332 mesh->runtime->subsurf_optimal_display_edges.clear_and_shrink();
333 mesh->flag &= ~ME_NO_OVERLAPPING_TOPOLOGY;
336void Mesh::tag_edges_split()
340 this->runtime->vert_normals_cache.tag_dirty();
341 this->runtime->subdiv_ccg.reset();
342 this->runtime->vert_to_face_offset_cache.tag_dirty();
343 this->runtime->vert_to_face_map_cache.tag_dirty();
344 this->runtime->vert_to_corner_map_cache.tag_dirty();
345 if (this->runtime->loose_edges_cache.is_cached() &&
346 this->runtime->loose_edges_cache.data().count != 0)
348 this->runtime->loose_edges_cache.tag_dirty();
350 if (this->runtime->loose_verts_cache.is_cached() &&
351 this->runtime->loose_verts_cache.data().count != 0)
353 this->runtime->loose_verts_cache.tag_dirty();
355 if (this->runtime->verts_no_face_cache.is_cached() &&
356 this->runtime->verts_no_face_cache.data().count != 0)
358 this->runtime->verts_no_face_cache.tag_dirty();
360 this->runtime->subsurf_face_dot_tags.clear_and_shrink();
361 this->runtime->subsurf_optimal_display_edges.clear_and_shrink();
362 this->runtime->shrinkwrap_boundary_cache.tag_dirty();
365void Mesh::tag_sharpness_changed()
367 this->runtime->corner_normals_cache.tag_dirty();
370void Mesh::tag_custom_normals_changed()
372 this->runtime->corner_normals_cache.tag_dirty();
375void Mesh::tag_face_winding_changed()
377 this->runtime->vert_normals_cache.tag_dirty();
378 this->runtime->face_normals_cache.tag_dirty();
379 this->runtime->corner_normals_cache.tag_dirty();
380 this->runtime->vert_to_corner_map_cache.tag_dirty();
381 this->runtime->shrinkwrap_boundary_cache.tag_dirty();
384void Mesh::tag_positions_changed()
386 this->runtime->vert_normals_cache.tag_dirty();
387 this->runtime->face_normals_cache.tag_dirty();
388 this->runtime->corner_normals_cache.tag_dirty();
389 this->runtime->shrinkwrap_boundary_cache.tag_dirty();
390 this->tag_positions_changed_no_normals();
393void Mesh::tag_positions_changed_no_normals()
396 this->runtime->corner_tris_cache.tag_dirty();
397 this->runtime->bounds_cache.tag_dirty();
398 this->runtime->shrinkwrap_boundary_cache.tag_dirty();
401void Mesh::tag_positions_changed_uniformly()
405 this->runtime->bounds_cache.tag_dirty();
408void Mesh::tag_topology_changed()
426 if (mesh->runtime->batch_cache) {
445 const bool do_verbose =
true;
446 const bool do_fixes =
false;
457 Span<int> face_offsets = mesh_eval->face_offsets();
458 Span<int> corner_verts = mesh_eval->corner_verts();
479 reinterpret_cast<float(*)[3]
>(positions.data()),
void bvhcache_free(BVHCache *bvh_cache)
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
Read Guarded memory(de)allocation.
void reinitialize(const int64_t new_size)
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_batch_cache(MeshRuntime &mesh_runtime)
static void free_mesh_eval(MeshRuntime &mesh_runtime)
static void free_bvh_cache(MeshRuntime &mesh_runtime)
void build_reverse_offsets(Span< int > indices, MutableSpan< int > offsets)
blender::BitVector is_loose_bits