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();
124blender::OffsetIndices<int> Mesh::vert_to_face_map_offsets()
const
126 using namespace blender;
127 this->runtime->vert_to_face_offset_cache.ensure([&](
Array<int> &r_data) {
134blender::GroupedSpan<int> Mesh::vert_to_face_map()
const
136 using namespace blender;
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())
146 this->runtime->vert_to_corner_map_cache.data().as_span(),
153 return {offsets, this->runtime->vert_to_face_map_cache.
data()};
156blender::GroupedSpan<int> Mesh::vert_to_corner_map()
const
158 using namespace blender;
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()};
166const blender::bke::LooseVertCache &Mesh::loose_verts()
const
168 using namespace blender::bke;
169 this->runtime->loose_verts_cache.ensure([&](LooseVertCache &r_data) {
174 return this->runtime->loose_verts_cache.data();
177const blender::bke::LooseVertCache &Mesh::verts_no_face()
const
179 using namespace blender::bke;
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
193const blender::bke::LooseEdgeCache &Mesh::loose_edges()
const
195 using namespace blender::bke;
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
206 using namespace blender::bke;
207 this->runtime->loose_verts_cache.ensure([&](LooseVertCache &r_data) {
214void Mesh::tag_loose_edges_none()
const
216 using namespace blender::bke;
217 this->runtime->loose_edges_cache.ensure([&](LooseEdgeCache &r_data) {
224void Mesh::tag_overlapping_none()
226 using namespace blender::bke;
230namespace blender::bke {
242 this->
data.tag_dirty();
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();
280blender::Span<int> Mesh::corner_tri_faces()
const
282 using namespace blender;
283 this->runtime->corner_tri_faces_cache.ensure([&](blender::Array<int> &r_data) {
288 return this->runtime->corner_tri_faces_cache.data();
299 if (!
mesh->runtime->edit_data) {
300 mesh->runtime->edit_data = std::make_unique<blender::bke::EditMeshData>();
309 mesh->runtime->edit_data.reset();
317 mesh->runtime->subdiv_ccg.reset();
318 mesh->runtime->bounds_cache.tag_dirty();
319 mesh->runtime->vert_to_face_offset_cache.tag_dirty();
320 mesh->runtime->vert_to_face_map_cache.tag_dirty();
321 mesh->runtime->vert_to_corner_map_cache.tag_dirty();
322 mesh->runtime->corner_to_face_map_cache.tag_dirty();
323 mesh->runtime->vert_normals_cache.tag_dirty();
324 mesh->runtime->vert_normals_true_cache.tag_dirty();
325 mesh->runtime->face_normals_cache.tag_dirty();
326 mesh->runtime->face_normals_true_cache.tag_dirty();
327 mesh->runtime->corner_normals_cache.tag_dirty();
328 mesh->runtime->loose_edges_cache.tag_dirty();
329 mesh->runtime->loose_verts_cache.tag_dirty();
330 mesh->runtime->verts_no_face_cache.tag_dirty();
331 mesh->runtime->corner_tris_cache.data.tag_dirty();
332 mesh->runtime->corner_tri_faces_cache.tag_dirty();
333 mesh->runtime->shrinkwrap_boundary_cache.tag_dirty();
334 mesh->runtime->max_material_index.tag_dirty();
335 mesh->runtime->subsurf_face_dot_tags.clear_and_shrink();
336 mesh->runtime->subsurf_optimal_display_edges.clear_and_shrink();
337 mesh->runtime->spatial_groups.reset();
341void Mesh::tag_edges_split()
345 this->runtime->vert_normals_cache.tag_dirty();
346 this->runtime->corner_normals_cache.tag_dirty();
347 this->runtime->subdiv_ccg.reset();
348 this->runtime->vert_to_face_offset_cache.tag_dirty();
349 this->runtime->vert_to_face_map_cache.tag_dirty();
350 this->runtime->vert_to_corner_map_cache.tag_dirty();
351 if (this->runtime->loose_edges_cache.is_cached() &&
352 this->runtime->loose_edges_cache.data().count != 0)
354 this->runtime->loose_edges_cache.tag_dirty();
356 if (this->runtime->loose_verts_cache.is_cached() &&
357 this->runtime->loose_verts_cache.data().count != 0)
359 this->runtime->loose_verts_cache.tag_dirty();
361 if (this->runtime->verts_no_face_cache.is_cached() &&
362 this->runtime->verts_no_face_cache.data().count != 0)
364 this->runtime->verts_no_face_cache.tag_dirty();
366 this->runtime->subsurf_face_dot_tags.clear_and_shrink();
367 this->runtime->subsurf_optimal_display_edges.clear_and_shrink();
368 this->runtime->shrinkwrap_boundary_cache.tag_dirty();
371void Mesh::tag_sharpness_changed()
373 this->runtime->vert_normals_cache.tag_dirty();
374 this->runtime->face_normals_cache.tag_dirty();
375 this->runtime->corner_normals_cache.tag_dirty();
378void Mesh::tag_custom_normals_changed()
380 this->runtime->vert_normals_cache.tag_dirty();
381 this->runtime->face_normals_cache.tag_dirty();
382 this->runtime->corner_normals_cache.tag_dirty();
385void Mesh::tag_face_winding_changed()
387 this->runtime->vert_normals_cache.tag_dirty();
388 this->runtime->face_normals_cache.tag_dirty();
389 this->runtime->vert_normals_true_cache.tag_dirty();
390 this->runtime->face_normals_true_cache.tag_dirty();
391 this->runtime->corner_normals_cache.tag_dirty();
392 this->runtime->vert_to_corner_map_cache.tag_dirty();
393 this->runtime->shrinkwrap_boundary_cache.tag_dirty();
396void Mesh::tag_positions_changed()
398 this->runtime->vert_normals_cache.tag_dirty();
399 this->runtime->face_normals_cache.tag_dirty();
400 this->runtime->vert_normals_true_cache.tag_dirty();
401 this->runtime->face_normals_true_cache.tag_dirty();
402 this->runtime->corner_normals_cache.tag_dirty();
403 this->runtime->shrinkwrap_boundary_cache.tag_dirty();
404 this->tag_positions_changed_no_normals();
407void Mesh::tag_positions_changed_no_normals()
410 this->runtime->corner_tris_cache.tag_dirty();
411 this->runtime->bounds_cache.tag_dirty();
412 this->runtime->shrinkwrap_boundary_cache.tag_dirty();
415void Mesh::tag_positions_changed_uniformly()
419 this->runtime->bounds_cache.tag_dirty();
422void Mesh::tag_topology_changed()
427void Mesh::tag_visibility_changed()
429 this->runtime->bvh_cache_corner_tris_no_hidden.tag_dirty();
430 this->runtime->bvh_cache_loose_verts_no_hidden.tag_dirty();
431 this->runtime->bvh_cache_loose_edges_no_hidden.tag_dirty();
434void Mesh::tag_material_index_changed()
436 this->runtime->max_material_index.tag_dirty();
452 if (
mesh->runtime->batch_cache) {
458 Mesh *mesh_eval =
mesh->runtime->mesh_eval;
459 if (mesh_eval && mesh_eval->
runtime->batch_cache) {
478 const bool do_verbose =
true;
479 const bool do_fixes =
false;
481 bool is_valid =
true;
490 Span<int> face_offsets = mesh_eval->face_offsets();
491 Span<int> corner_verts = mesh_eval->corner_verts();
512 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_FLAG_UV_SELECT_SYNC_VALID
@ ME_NO_OVERLAPPING_TOPOLOGY
MutableSpan< T > as_mutable_span()
void reinitialize(const int64_t new_size)
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 gather(const GVArray &src, const IndexMask &indices, GMutableSpan dst, int64_t grain_size=4096)
void build_vert_to_face_indices(OffsetIndices< int > faces, Span< int > corner_verts, OffsetIndices< int > offsets, MutableSpan< int > face_indices)
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)
VecBase< float, 3 > float3
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
SharedCache< Array< int3 > > data