tornavis/source/blender/blenkernel/BKE_mesh_types.hh

224 lines
7.8 KiB
C++

/* SPDX-FileCopyrightText: 2020 Blender Authors
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#pragma once
/** \file
* \ingroup bke
*/
#include <memory>
#include <mutex>
#include "BLI_array.hh"
#include "BLI_bit_vector.hh"
#include "BLI_bounds_types.hh"
#include "BLI_implicit_sharing.hh"
#include "BLI_math_vector_types.hh"
#include "BLI_shared_cache.hh"
#include "BLI_vector.hh"
#include "DNA_customdata_types.h"
struct BMEditMesh;
struct BVHCache;
struct Mesh;
class ShrinkwrapBoundaryData;
struct SubdivCCG;
struct SubsurfRuntimeData;
namespace blender::bke {
struct EditMeshData;
}
namespace blender::bke::bake {
struct BakeMaterialsList;
}
/** #MeshRuntime.wrapper_type */
enum eMeshWrapperType {
/** Use mesh data (#Mesh.vert_positions(), #Mesh.medge, #Mesh.corner_verts(), #Mesh.faces()). */
ME_WRAPPER_TYPE_MDATA = 0,
/** Use edit-mesh data (#Mesh.edit_mesh, #MeshRuntime.edit_data). */
ME_WRAPPER_TYPE_BMESH = 1,
/** Use subdivision mesh data (#MeshRuntime.mesh_eval). */
ME_WRAPPER_TYPE_SUBD = 2,
};
namespace blender::bke {
/**
* The complexity requirement of attribute domains needed to process normals.
* See #Mesh::normals_domain().
*/
enum class MeshNormalDomain : int8_t {
/**
* The mesh is completely flat shaded; either all faces or edges are sharp.
* Only #Mesh::face_normals() is necessary. This case is generally the best
* for performance, since no mixing is necessary and multithreading is simple.
*/
Face = 0,
/**
* The mesh is completely smooth shaded; there are no sharp face or edges. Only
* #Mesh::vert_normals() is necessary. Calculating face normals is still necessary though,
* since they have to be mixed to become vertex normals.
*/
Point = 1,
/**
* The mesh has mixed smooth and sharp shading. In order to split the normals on each side of
* sharp edges, they need to be processed per-face-corner. Normals can be retrieved with
* #Mesh::corner_normals().
*/
Corner = 2,
};
struct LooseGeomCache {
/**
* A bitmap set to true for each "loose" element.
* Allocated only if there is at least one loose element.
*/
blender::BitVector<> is_loose_bits;
/**
* The number of loose elements. If zero, the #is_loose_bits shouldn't be accessed.
* If less than zero, the cache has been accessed in an invalid way
* (i.e. directly instead of through a Mesh API function).
*/
int count = -1;
};
/**
* Cache of a mesh's loose edges, accessed with #Mesh::loose_edges(). *
*/
struct LooseEdgeCache : public LooseGeomCache {};
/**
* Cache of a mesh's loose vertices or vertices not used by faces.
*/
struct LooseVertCache : public LooseGeomCache {};
struct MeshRuntime {
/* Evaluated mesh for objects which do not have effective modifiers.
* This mesh is used as a result of modifier stack evaluation.
* Since modifier stack evaluation is threaded on object level we need some synchronization. */
Mesh *mesh_eval = nullptr;
std::mutex eval_mutex;
/** Needed to ensure some thread-safety during render data pre-processing. */
std::mutex render_mutex;
/** Implicit sharing user count for #Mesh::face_offset_indices. */
const ImplicitSharingInfo *face_offsets_sharing_info = nullptr;
/**
* Storage of the edit mode mesh. If it exists, it generally has the most up-to-date
* information about the mesh.
* \note When the object is available, the preferred access method is #BKE_editmesh_from_object.
*/
BMEditMesh *edit_mesh = nullptr;
/**
* A cache of bounds shared between data-blocks with unchanged positions. When changing positions
* affect the bounds, the cache is "un-shared" with other geometries. See #SharedCache comments.
*/
SharedCache<Bounds<float3>> bounds_cache;
/**
* Lazily initialized SoA data from the #edit_mesh field in #Mesh. Used when the mesh is a BMesh
* wrapper (#ME_WRAPPER_TYPE_BMESH).
*/
std::unique_ptr<EditMeshData> edit_data;
/**
* Data used to efficiently draw the mesh in the viewport, especially useful when
* the same mesh is used in many objects or instances. See `draw_cache_impl_mesh.cc`.
*/
void *batch_cache = nullptr;
/** Cache for derived triangulation of the mesh, accessed with #Mesh::corner_tris(). */
SharedCache<Array<int3>> corner_tris_cache;
/** Cache for triangle to original face index map, accessed with #Mesh::corner_tri_faces(). */
SharedCache<Array<int>> corner_tri_faces_cache;
/** Cache for BVH trees generated for the mesh. Defined in 'BKE_bvhutil.c' */
BVHCache *bvh_cache = nullptr;
/** Needed in case we need to lazily initialize the mesh. */
CustomData_MeshMasks cd_mask_extra = {};
/**
* Grids representation for multi-resolution sculpting. When this is set, the mesh will be empty,
* since it is conceptually replaced with the limited data stored in the grids.
*/
std::unique_ptr<SubdivCCG> subdiv_ccg;
int subdiv_ccg_tot_level = 0;
/** Set by modifier stack if only deformed from original. */
bool deformed_only = false;
/**
* Copied from edit-mesh (hint, draw with edit-mesh data when true).
*
* Modifiers that edit the mesh data in-place must set this to false
* (most #ModifierTypeType::NonGeometrical modifiers). Otherwise the edit-mesh
* data will be used for drawing, missing changes from modifiers. See #79517.
*/
bool is_original_bmesh = false;
/** #eMeshWrapperType and others. */
eMeshWrapperType wrapper_type = ME_WRAPPER_TYPE_MDATA;
/**
* Settings for lazily evaluating the subdivision on the CPU if needed. These are
* set in the modifier when GPU subdivision can be performed, and owned by the by
* the modifier in the object.
*/
SubsurfRuntimeData *subsurf_runtime_data = nullptr;
/** Lazily computed vertex normals (#Mesh::vert_normals()). */
SharedCache<Vector<float3>> vert_normals_cache;
/** Lazily computed face normals (#Mesh::face_normals()). */
SharedCache<Vector<float3>> face_normals_cache;
/** Lazily computed face corner normals (#Mesh::corner_normals()). */
SharedCache<Vector<float3>> corner_normals_cache;
/**
* Cache of offsets for vert to face/corner maps. The same offsets array is used to group
* indices for both the vertex to face and vertex to corner maps.
*/
SharedCache<Array<int>> vert_to_face_offset_cache;
/** Cache of indices for vert to face map. */
SharedCache<Array<int>> vert_to_face_map_cache;
/** Cache of indices for vert to corner map. */
SharedCache<Array<int>> vert_to_corner_map_cache;
/** Cache of face indices for each face corner. */
SharedCache<Array<int>> corner_to_face_map_cache;
/** Cache of data about edges not used by faces. See #Mesh::loose_edges(). */
SharedCache<LooseEdgeCache> loose_edges_cache;
/** Cache of data about vertices not used by edges. See #Mesh::loose_verts(). */
SharedCache<LooseVertCache> loose_verts_cache;
/** Cache of data about vertices not used by faces. See #Mesh::verts_no_face(). */
SharedCache<LooseVertCache> verts_no_face_cache;
/** Cache of non-manifold boundary data for shrinkwrap target Project. */
SharedCache<ShrinkwrapBoundaryData> shrinkwrap_boundary_cache;
/**
* A bit vector the size of the number of vertices, set to true for the center vertices of
* subdivided faces. The values are set by the subdivision surface modifier and used by
* drawing code instead of face center face dots. Otherwise this will be empty.
*/
BitVector<> subsurf_face_dot_tags;
/**
* A bit vector the size of the number of edges, set to true for edges that should be drawn in
* the viewport. Created by the "Optimal Display" feature of the subdivision surface modifier.
* Otherwise it will be empty.
*/
BitVector<> subsurf_optimal_display_edges;
/** Stores weak references to material data blocks. */
std::unique_ptr<bake::BakeMaterialsList> bake_materials;
MeshRuntime();
~MeshRuntime();
};
} // namespace blender::bke