Rewrite the "mesh is valid" and "validate mesh" functions to be more agnostic of the custom data storage system, align with the changes to topology storage in the last 5 years, be much clearer overall, more reusable. Each check is implemented as a separate pass over the remaining valid geometry in the mesh, producing an IndexMask of the invalid elements it finds. At the cost of some extra iteration over mesh elements, this should make each requirement clearer and make it easier to optimize and reuse each check if needed. The code is roughly twice as fast as it was before. I measured 92ms instead of 200ms for a 1 million vertex cube on a Ryzen 7950X. There's a bit of low hanging fruit for further optimization too. There are now automated tests just for the validation code as well. For now they are very basic but they could be extended in the future. Some non-obvious points: - The new face offsets storage (replacing `MPoly`) upholds more invariants by itself. Previously faces could easily overlap or leave corners unreferenced. That doesn't really happen anymore, but bad offset values are a more "global" problem. - The validation code for the old "MFace" storage was removed. It is just rebuilt when it's needed at runtime anyway, so there isn't much point in validating it. - The versioning code for 2.90.1 was calling the mesh validation code to fix an issue where the extrude manifold tool could generate bad faces. Unfortunately keeping that would mean being unable to remove the old code, so now there's a warning to open and save the file in a previous version instead. - One of the main goals of the new code is better const correctness, and working better with implicit sharing. The code now only requests mutable copies of the mesh data if it has to change. Part of #122398 Pull Request: https://projects.blender.org/blender/blender/pulls/148063
86 lines
3.2 KiB
C++
86 lines
3.2 KiB
C++
/* SPDX-FileCopyrightText: 2001-2002 NaN Holding BV. All rights reserved.
|
|
*
|
|
* SPDX-License-Identifier: GPL-2.0-or-later */
|
|
#pragma once
|
|
|
|
/** \file
|
|
* \ingroup bke
|
|
*
|
|
* This file contains access functions for the Mesh.runtime struct.
|
|
*/
|
|
|
|
#include "BLI_math_vector_types.hh"
|
|
#include "BLI_span.hh"
|
|
|
|
struct BMEditMesh;
|
|
struct CustomData_MeshMasks;
|
|
struct Depsgraph;
|
|
struct KeyBlock;
|
|
struct ModifierData;
|
|
struct Mesh;
|
|
struct Object;
|
|
struct Scene;
|
|
|
|
/** Return the number of derived triangles (corner_tris). */
|
|
int BKE_mesh_runtime_corner_tris_len(const Mesh *mesh);
|
|
|
|
void BKE_mesh_runtime_ensure_edit_data(Mesh *mesh);
|
|
|
|
/**
|
|
* Clear and free any derived caches associated with the mesh geometry data. Examples include BVH
|
|
* caches, normals, triangulation, etc. This should be called when replacing a mesh's geometry
|
|
* directly or making other large changes to topology. It does not need to be called on new meshes.
|
|
*
|
|
* For "smaller" changes to meshes like updating positions, consider calling a more specific update
|
|
* function like #Mesh::tag_positions_changed().
|
|
*/
|
|
void BKE_mesh_runtime_clear_geometry(Mesh *mesh);
|
|
|
|
/**
|
|
* Similar to #BKE_mesh_runtime_clear_geometry, but subtly different in that it also clears
|
|
* data-block level features like evaluated data-blocks and edit mode data. They will be
|
|
* functionally the same in most cases, but prefer this function if unsure, since it clears
|
|
* more data.
|
|
*/
|
|
void BKE_mesh_runtime_clear_cache(Mesh *mesh);
|
|
|
|
namespace blender::bke {
|
|
|
|
void mesh_get_mapped_verts_coords(Mesh *mesh_eval, MutableSpan<float3> r_cos);
|
|
|
|
Mesh *editbmesh_get_eval_cage(Depsgraph *depsgraph,
|
|
const Scene *scene,
|
|
Object *obedit,
|
|
BMEditMesh *em,
|
|
const CustomData_MeshMasks *dataMask);
|
|
Mesh *editbmesh_get_eval_cage_from_orig(Depsgraph *depsgraph,
|
|
const Scene *scene,
|
|
Object *obedit,
|
|
const CustomData_MeshMasks *dataMask);
|
|
|
|
bool editbmesh_modifier_is_enabled(const Scene *scene,
|
|
const Object *ob,
|
|
ModifierData *md,
|
|
bool has_prev_mesh);
|
|
|
|
Mesh *mesh_get_eval_deform(Depsgraph *depsgraph,
|
|
const Scene *scene,
|
|
Object *ob,
|
|
const CustomData_MeshMasks *dataMask);
|
|
|
|
Mesh *mesh_create_eval_final(Depsgraph *depsgraph,
|
|
const Scene *scene,
|
|
Object *ob,
|
|
const CustomData_MeshMasks *dataMask);
|
|
|
|
Mesh *mesh_create_eval_no_deform(Depsgraph *depsgraph,
|
|
const Scene *scene,
|
|
Object *ob,
|
|
const CustomData_MeshMasks *dataMask);
|
|
Mesh *mesh_create_eval_no_deform_render(Depsgraph *depsgraph,
|
|
const Scene *scene,
|
|
Object *ob,
|
|
const CustomData_MeshMasks *dataMask);
|
|
|
|
} // namespace blender::bke
|