Mesh: Move runtime data out of DNA
This commit replaces the `Mesh_Runtime` struct embedded in `Mesh` with `blender::bke::MeshRuntime`. This has quite a few benefits: - It's possible to use C++ types like `std::mutex`, `Array`, `BitVector`, etc. more easily - Meshes saved in files are slightly smaller - Copying and writing meshes is a bit more obvious without clearing of runtime data, etc. The first is by far the most important. It will allows us to avoid a bunch of manual memory management boilerplate that is error-prone and annoying. It should also simplify future CoW improvements for runtime data. This patch doesn't change anything besides changing `mesh.runtime.data` to `mesh.runtime->data`. The cleanups above will happen separately. Differential Revision: https://developer.blender.org/D16180
This commit is contained in:
parent
b3e6a2888a
commit
c34c6d3e25
|
@ -11,15 +11,25 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
struct BMEditMesh;
|
||||
struct EditMeshData;
|
||||
|
||||
void BKE_editmesh_cache_ensure_poly_normals(struct BMEditMesh *em, struct EditMeshData *emd);
|
||||
void BKE_editmesh_cache_ensure_vert_normals(struct BMEditMesh *em, struct EditMeshData *emd);
|
||||
typedef struct EditMeshData {
|
||||
/** when set, \a vertexNos, polyNos are lazy initialized */
|
||||
const float (*vertexCos)[3];
|
||||
|
||||
void BKE_editmesh_cache_ensure_poly_centers(struct BMEditMesh *em, struct EditMeshData *emd);
|
||||
/** lazy initialize (when \a vertexCos is set) */
|
||||
float const (*vertexNos)[3];
|
||||
float const (*polyNos)[3];
|
||||
/** also lazy init but don't depend on \a vertexCos */
|
||||
const float (*polyCos)[3];
|
||||
} EditMeshData;
|
||||
|
||||
void BKE_editmesh_cache_ensure_poly_normals(struct BMEditMesh *em, EditMeshData *emd);
|
||||
void BKE_editmesh_cache_ensure_vert_normals(struct BMEditMesh *em, EditMeshData *emd);
|
||||
|
||||
void BKE_editmesh_cache_ensure_poly_centers(struct BMEditMesh *em, EditMeshData *emd);
|
||||
|
||||
bool BKE_editmesh_cache_calc_minmax(struct BMEditMesh *em,
|
||||
struct EditMeshData *emd,
|
||||
EditMeshData *emd,
|
||||
float min[3],
|
||||
float max[3]);
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
*/
|
||||
|
||||
//#include "BKE_customdata.h" /* for eCustomDataMask */
|
||||
#include "BKE_mesh_types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
@ -25,22 +26,11 @@ struct Mesh;
|
|||
struct Object;
|
||||
struct Scene;
|
||||
|
||||
/**
|
||||
* \brief Initialize the runtime of the given mesh.
|
||||
*
|
||||
* Function expects that the runtime is already cleared.
|
||||
*/
|
||||
void BKE_mesh_runtime_init_data(struct Mesh *mesh);
|
||||
/**
|
||||
* \brief Free all data (and mutexes) inside the runtime of the given mesh.
|
||||
*/
|
||||
void BKE_mesh_runtime_free_data(struct Mesh *mesh);
|
||||
/**
|
||||
* Clear all pointers which we don't want to be shared on copying the datablock.
|
||||
* However, keep all the flags which defines what the mesh is (for example, that
|
||||
* it's deformed only, or that its custom data layers are out of date.)
|
||||
*/
|
||||
void BKE_mesh_runtime_reset_on_copy(struct Mesh *mesh, int flag);
|
||||
|
||||
int BKE_mesh_runtime_looptri_len(const struct Mesh *mesh);
|
||||
void BKE_mesh_runtime_looptri_recalc(struct Mesh *mesh);
|
||||
/**
|
||||
|
@ -66,6 +56,11 @@ void BKE_mesh_runtime_verttri_from_looptri(struct MVertTri *r_verttri,
|
|||
const struct MLoopTri *looptri,
|
||||
int looptri_num);
|
||||
|
||||
/** \note Only used for access in C. */
|
||||
bool BKE_mesh_is_deformed_only(const struct Mesh *mesh);
|
||||
/** \note Only used for access in C. */
|
||||
eMeshWrapperType BKE_mesh_wrapper_type(const struct Mesh *mesh);
|
||||
|
||||
/* NOTE: the functions below are defined in DerivedMesh.cc, and are intended to be moved
|
||||
* to a more suitable location when that file is removed.
|
||||
* They should also be renamed to use conventions from BKE, not old DerivedMesh.cc.
|
||||
|
|
|
@ -1,11 +1,33 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
* Copyright 2020 Blender Foundation. All rights reserved. */
|
||||
|
||||
#pragma once
|
||||
|
||||
/** \file
|
||||
* \ingroup bke
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
# include "BLI_span.hh"
|
||||
|
||||
# include "DNA_customdata_types.h"
|
||||
|
||||
# include "MEM_guardedalloc.h"
|
||||
|
||||
struct BVHCache;
|
||||
struct EditMeshData;
|
||||
struct MLoopTri;
|
||||
struct ShrinkwrapBoundaryData;
|
||||
struct SubdivCCG;
|
||||
struct SubsurfRuntimeData;
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum eMeshBatchDirtyMode {
|
||||
BKE_MESH_BATCH_DIRTY_ALL = 0,
|
||||
BKE_MESH_BATCH_DIRTY_SELECT,
|
||||
|
@ -14,3 +36,125 @@ typedef enum eMeshBatchDirtyMode {
|
|||
BKE_MESH_BATCH_DIRTY_UVEDIT_ALL,
|
||||
BKE_MESH_BATCH_DIRTY_UVEDIT_SELECT,
|
||||
} eMeshBatchDirtyMode;
|
||||
|
||||
/** #MeshRuntime.wrapper_type */
|
||||
typedef enum eMeshWrapperType {
|
||||
/** Use mesh data (#Mesh.mvert, #Mesh.medge, #Mesh.mloop, #Mesh.mpoly). */
|
||||
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,
|
||||
} eMeshWrapperType;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
namespace blender::bke {
|
||||
|
||||
/**
|
||||
* \warning Typical access is done via #Mesh::looptris().
|
||||
*/
|
||||
struct MLoopTri_Store {
|
||||
/* WARNING! swapping between array (ready-to-be-used data) and array_wip
|
||||
* (where data is actually computed)
|
||||
* shall always be protected by same lock as one used for looptris computing. */
|
||||
MLoopTri *array = nullptr;
|
||||
MLoopTri *array_wip = nullptr;
|
||||
int len = 0;
|
||||
int len_alloc = 0;
|
||||
};
|
||||
|
||||
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;
|
||||
void *eval_mutex = nullptr;
|
||||
|
||||
/* A separate mutex is needed for normal calculation, because sometimes
|
||||
* the normals are needed while #eval_mutex is already locked. */
|
||||
void *normals_mutex = nullptr;
|
||||
|
||||
/** Needed to ensure some thread-safety during render data pre-processing. */
|
||||
void *render_mutex = nullptr;
|
||||
|
||||
/** Lazily initialized SoA data from the #edit_mesh field in #Mesh. */
|
||||
EditMeshData *edit_data = nullptr;
|
||||
|
||||
/**
|
||||
* 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. */
|
||||
MLoopTri_Store looptris;
|
||||
|
||||
/** Cache for BVH trees generated for the mesh. Defined in 'BKE_bvhutil.c' */
|
||||
BVHCache *bvh_cache = nullptr;
|
||||
|
||||
/** Cache of non-manifold boundary data for Shrinkwrap Target Project. */
|
||||
ShrinkwrapBoundaryData *shrinkwrap_data = nullptr;
|
||||
|
||||
/** Needed in case we need to lazily initialize the mesh. */
|
||||
CustomData_MeshMasks cd_mask_extra = {};
|
||||
|
||||
SubdivCCG *subdiv_ccg = nullptr;
|
||||
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 #eModifierTypeType_NonGeometrical modifiers). Otherwise the edit-mesh
|
||||
* data will be used for drawing, missing changes from modifiers. See T79517.
|
||||
*/
|
||||
bool is_original_bmesh = false;
|
||||
|
||||
/** #eMeshWrapperType and others. */
|
||||
eMeshWrapperType wrapper_type = ME_WRAPPER_TYPE_MDATA;
|
||||
/**
|
||||
* A type mask from wrapper_type,
|
||||
* in case there are differences in finalizing logic between types.
|
||||
*/
|
||||
eMeshWrapperType wrapper_type_finalize = 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;
|
||||
|
||||
/**
|
||||
* Caches for lazily computed vertex and polygon normals. These are stored here rather than in
|
||||
* #CustomData because they can be calculated on a const mesh, and adding custom data layers on a
|
||||
* const mesh is not thread-safe.
|
||||
*/
|
||||
bool vert_normals_dirty = false;
|
||||
bool poly_normals_dirty = false;
|
||||
float (*vert_normals)[3] = nullptr;
|
||||
float (*poly_normals)[3] = nullptr;
|
||||
|
||||
/**
|
||||
* A #BLI_bitmap containing tags for the center vertices of subdivided polygons, set by the
|
||||
* subdivision surface modifier and used by drawing code instead of polygon center face dots.
|
||||
*/
|
||||
uint32_t *subsurf_face_dot_tags = nullptr;
|
||||
|
||||
MeshRuntime();
|
||||
/** \warning This does not free all data currently. See #BKE_mesh_runtime_free_data. */
|
||||
~MeshRuntime();
|
||||
|
||||
MEM_CXX_CLASS_ALLOC_FUNCS("MeshRuntime")
|
||||
};
|
||||
|
||||
} // namespace blender::bke
|
||||
|
||||
#endif
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#include "BKE_colorband.h"
|
||||
#include "BKE_deform.h"
|
||||
#include "BKE_editmesh.h"
|
||||
#include "BKE_editmesh_cache.h"
|
||||
#include "BKE_geometry_set.hh"
|
||||
#include "BKE_geometry_set_instances.hh"
|
||||
#include "BKE_key.h"
|
||||
|
@ -537,7 +538,7 @@ static void mesh_calc_modifier_final_normals(const Mesh *mesh_input,
|
|||
(final_datamask->lmask & CD_MASK_NORMAL) != 0);
|
||||
|
||||
/* Needed as `final_datamask` is not preserved outside modifier stack evaluation. */
|
||||
SubsurfRuntimeData *subsurf_runtime_data = mesh_final->runtime.subsurf_runtime_data;
|
||||
SubsurfRuntimeData *subsurf_runtime_data = mesh_final->runtime->subsurf_runtime_data;
|
||||
if (subsurf_runtime_data) {
|
||||
subsurf_runtime_data->calc_loop_normals = calc_loop_normals;
|
||||
}
|
||||
|
@ -585,11 +586,12 @@ static void mesh_calc_finalize(const Mesh *mesh_input, Mesh *mesh_eval)
|
|||
void BKE_mesh_wrapper_deferred_finalize_mdata(Mesh *me_eval,
|
||||
const CustomData_MeshMasks *cd_mask_finalize)
|
||||
{
|
||||
if (me_eval->runtime.wrapper_type_finalize & (1 << ME_WRAPPER_TYPE_BMESH)) {
|
||||
if (me_eval->runtime->wrapper_type_finalize & (1 << ME_WRAPPER_TYPE_BMESH)) {
|
||||
editbmesh_calc_modifier_final_normals(me_eval, cd_mask_finalize);
|
||||
me_eval->runtime.wrapper_type_finalize &= ~(1 << ME_WRAPPER_TYPE_BMESH);
|
||||
me_eval->runtime->wrapper_type_finalize = eMeshWrapperType(
|
||||
me_eval->runtime->wrapper_type_finalize & ~(1 << ME_WRAPPER_TYPE_BMESH));
|
||||
}
|
||||
BLI_assert(me_eval->runtime.wrapper_type_finalize == 0);
|
||||
BLI_assert(me_eval->runtime->wrapper_type_finalize == 0);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1052,7 +1054,7 @@ static void mesh_calc_modifiers(struct Depsgraph *depsgraph,
|
|||
append_mask.lmask |= CD_MASK_PREVIEW_MLOOPCOL;
|
||||
}
|
||||
|
||||
mesh_final->runtime.deformed_only = false;
|
||||
mesh_final->runtime->deformed_only = false;
|
||||
}
|
||||
|
||||
isPrevDeform = (mti->type == eModifierTypeType_OnlyDeform);
|
||||
|
@ -1119,7 +1121,7 @@ static void mesh_calc_modifiers(struct Depsgraph *depsgraph,
|
|||
mesh_calc_finalize(mesh_input, mesh_final);
|
||||
}
|
||||
else {
|
||||
Mesh_Runtime *runtime = &mesh_input->runtime;
|
||||
blender::bke::MeshRuntime *runtime = mesh_input->runtime;
|
||||
if (runtime->mesh_eval == nullptr) {
|
||||
BLI_assert(runtime->eval_mutex != nullptr);
|
||||
BLI_mutex_lock((ThreadMutex *)runtime->eval_mutex);
|
||||
|
@ -1207,7 +1209,7 @@ static void editbmesh_calc_modifier_final_normals(Mesh *mesh_final,
|
|||
const bool calc_loop_normals = ((mesh_final->flag & ME_AUTOSMOOTH) != 0 ||
|
||||
(final_datamask->lmask & CD_MASK_NORMAL) != 0);
|
||||
|
||||
SubsurfRuntimeData *subsurf_runtime_data = mesh_final->runtime.subsurf_runtime_data;
|
||||
SubsurfRuntimeData *subsurf_runtime_data = mesh_final->runtime->subsurf_runtime_data;
|
||||
if (subsurf_runtime_data) {
|
||||
subsurf_runtime_data->calc_loop_normals = calc_loop_normals;
|
||||
}
|
||||
|
@ -1234,9 +1236,10 @@ static void editbmesh_calc_modifier_final_normals(Mesh *mesh_final,
|
|||
static void editbmesh_calc_modifier_final_normals_or_defer(
|
||||
Mesh *mesh_final, const CustomData_MeshMasks *final_datamask)
|
||||
{
|
||||
if (mesh_final->runtime.wrapper_type != ME_WRAPPER_TYPE_MDATA) {
|
||||
if (mesh_final->runtime->wrapper_type != ME_WRAPPER_TYPE_MDATA) {
|
||||
/* Generated at draw time. */
|
||||
mesh_final->runtime.wrapper_type_finalize = (1 << mesh_final->runtime.wrapper_type);
|
||||
mesh_final->runtime->wrapper_type_finalize = eMeshWrapperType(
|
||||
1 << mesh_final->runtime->wrapper_type);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1450,7 +1453,7 @@ static void editbmesh_calc_modifiers(struct Depsgraph *depsgraph,
|
|||
deformed_verts = nullptr;
|
||||
}
|
||||
}
|
||||
mesh_final->runtime.deformed_only = false;
|
||||
mesh_final->runtime->deformed_only = false;
|
||||
}
|
||||
|
||||
if (r_cage && i == cageIndex) {
|
||||
|
@ -1469,7 +1472,8 @@ static void editbmesh_calc_modifiers(struct Depsgraph *depsgraph,
|
|||
if (!BKE_mesh_runtime_ensure_edit_data(me_orig)) {
|
||||
BKE_mesh_runtime_reset_edit_data(me_orig);
|
||||
}
|
||||
me_orig->runtime.edit_data->vertexCos = (const float(*)[3])MEM_dupallocN(deformed_verts);
|
||||
me_orig->runtime->edit_data->vertexCos = (const float(*)[3])MEM_dupallocN(
|
||||
deformed_verts);
|
||||
}
|
||||
mesh_cage = BKE_mesh_wrapper_from_editmesh_with_coords(
|
||||
em_input,
|
||||
|
@ -1583,7 +1587,7 @@ static void mesh_build_data(struct Depsgraph *depsgraph,
|
|||
* object's runtime: this could cause access freed data on depsgraph destruction (mesh who owns
|
||||
* the final result might be freed prior to object). */
|
||||
Mesh *mesh = (Mesh *)ob->data;
|
||||
const bool is_mesh_eval_owned = (mesh_eval != mesh->runtime.mesh_eval);
|
||||
const bool is_mesh_eval_owned = (mesh_eval != mesh->runtime->mesh_eval);
|
||||
BKE_object_eval_assign_data(ob, &mesh_eval->id, is_mesh_eval_owned);
|
||||
|
||||
/* Add the final mesh as a non-owning component to the geometry set. */
|
||||
|
@ -1643,7 +1647,7 @@ static void editbmesh_build_data(struct Depsgraph *depsgraph,
|
|||
}
|
||||
}
|
||||
|
||||
const bool is_mesh_eval_owned = (me_final != mesh->runtime.mesh_eval);
|
||||
const bool is_mesh_eval_owned = (me_final != mesh->runtime->mesh_eval);
|
||||
BKE_object_eval_assign_data(obedit, &me_final->id, is_mesh_eval_owned);
|
||||
|
||||
obedit->runtime.editmesh_eval_cage = me_cage;
|
||||
|
@ -1914,7 +1918,7 @@ static void make_vertexcos__mapFunc(void *userData,
|
|||
|
||||
void mesh_get_mapped_verts_coords(Mesh *me_eval, float (*r_cos)[3], const int totcos)
|
||||
{
|
||||
if (me_eval->runtime.deformed_only == false) {
|
||||
if (me_eval->runtime->deformed_only == false) {
|
||||
MappedUserData userData;
|
||||
memset(r_cos, 0, sizeof(*r_cos) * totcos);
|
||||
userData.vertexcos = r_cos;
|
||||
|
|
|
@ -1222,8 +1222,8 @@ BVHTree *BKE_bvhtree_from_mesh_get(struct BVHTreeFromMesh *data,
|
|||
const BVHCacheType bvh_cache_type,
|
||||
const int tree_type)
|
||||
{
|
||||
BVHCache **bvh_cache_p = (BVHCache **)&mesh->runtime.bvh_cache;
|
||||
ThreadMutex *mesh_eval_mutex = (ThreadMutex *)mesh->runtime.eval_mutex;
|
||||
BVHCache **bvh_cache_p = (BVHCache **)&mesh->runtime->bvh_cache;
|
||||
ThreadMutex *mesh_eval_mutex = (ThreadMutex *)mesh->runtime->eval_mutex;
|
||||
|
||||
const MLoopTri *looptri = nullptr;
|
||||
int looptri_len = 0;
|
||||
|
|
|
@ -826,7 +826,7 @@ static void cloth_from_mesh(ClothModifierData *clmd, const Object *ob, Mesh *mes
|
|||
const MLoop *mloop = BKE_mesh_loops(mesh);
|
||||
const MLoopTri *looptri = BKE_mesh_runtime_looptri_ensure(mesh);
|
||||
const uint mvert_num = mesh->totvert;
|
||||
const uint looptri_num = mesh->runtime.looptris.len;
|
||||
const uint looptri_num = BKE_mesh_runtime_looptri_len(mesh);
|
||||
|
||||
/* Allocate our vertices. */
|
||||
clmd->clothObject->mvert_num = mvert_num;
|
||||
|
|
|
@ -240,12 +240,12 @@ const float (*BKE_editmesh_vert_coords_when_deformed(Depsgraph *depsgraph,
|
|||
Object *object_eval = DEG_get_evaluated_object(depsgraph, ob);
|
||||
Mesh *editmesh_eval_final = BKE_object_get_editmesh_eval_final(object_eval);
|
||||
|
||||
if ((me->runtime.edit_data != nullptr) && (me->runtime.edit_data->vertexCos != nullptr)) {
|
||||
if ((me->runtime->edit_data != nullptr) && (me->runtime->edit_data->vertexCos != nullptr)) {
|
||||
/* Deformed, and we have deformed coords already. */
|
||||
coords = me->runtime.edit_data->vertexCos;
|
||||
coords = me->runtime->edit_data->vertexCos;
|
||||
}
|
||||
else if ((editmesh_eval_final != nullptr) &&
|
||||
(editmesh_eval_final->runtime.wrapper_type == ME_WRAPPER_TYPE_BMESH)) {
|
||||
(editmesh_eval_final->runtime->wrapper_type == ME_WRAPPER_TYPE_BMESH)) {
|
||||
/* If this is an edit-mesh type, leave nullptr as we can use the vertex coords. */
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -1498,7 +1498,7 @@ Mesh *BKE_mball_polygonize(Depsgraph *depsgraph, Scene *scene, Object *ob)
|
|||
for (int i = 0; i < mesh->totvert; i++) {
|
||||
normalize_v3(process.no[i]);
|
||||
}
|
||||
mesh->runtime.vert_normals = process.no;
|
||||
mesh->runtime->vert_normals = process.no;
|
||||
BKE_mesh_vertex_normals_clear_dirty(mesh);
|
||||
|
||||
mesh->totloop = loop_offset;
|
||||
|
|
|
@ -89,7 +89,7 @@ static void mesh_init_data(ID *id)
|
|||
CustomData_reset(&mesh->pdata);
|
||||
CustomData_reset(&mesh->ldata);
|
||||
|
||||
BKE_mesh_runtime_init_data(mesh);
|
||||
mesh->runtime = new blender::bke::MeshRuntime();
|
||||
|
||||
/* A newly created mesh does not have normals, so tag them dirty. This will be cleared
|
||||
* by #BKE_mesh_vertex_normals_clear_dirty or #BKE_mesh_poly_normals_ensure. */
|
||||
|
@ -103,14 +103,19 @@ static void mesh_copy_data(Main *bmain, ID *id_dst, const ID *id_src, const int
|
|||
Mesh *mesh_dst = (Mesh *)id_dst;
|
||||
const Mesh *mesh_src = (const Mesh *)id_src;
|
||||
|
||||
BKE_mesh_runtime_reset_on_copy(mesh_dst, flag);
|
||||
mesh_dst->runtime = new blender::bke::MeshRuntime();
|
||||
mesh_dst->runtime->deformed_only = mesh_src->runtime->deformed_only;
|
||||
mesh_dst->runtime->wrapper_type = mesh_src->runtime->wrapper_type;
|
||||
mesh_dst->runtime->wrapper_type_finalize = mesh_src->runtime->wrapper_type_finalize;
|
||||
mesh_dst->runtime->subsurf_runtime_data = mesh_src->runtime->subsurf_runtime_data;
|
||||
mesh_dst->runtime->cd_mask_extra = mesh_src->runtime->cd_mask_extra;
|
||||
/* Copy face dot tags, since meshes may be duplicated after a subsurf modifier
|
||||
* or node, but we still need to be able to draw face center vertices. */
|
||||
mesh_dst->runtime.subsurf_face_dot_tags = static_cast<uint32_t *>(
|
||||
MEM_dupallocN(mesh_src->runtime.subsurf_face_dot_tags));
|
||||
mesh_dst->runtime->subsurf_face_dot_tags = static_cast<uint32_t *>(
|
||||
MEM_dupallocN(mesh_src->runtime->subsurf_face_dot_tags));
|
||||
if ((mesh_src->id.tag & LIB_TAG_NO_MAIN) == 0) {
|
||||
/* This is a direct copy of a main mesh, so for now it has the same topology. */
|
||||
mesh_dst->runtime.deformed_only = true;
|
||||
mesh_dst->runtime->deformed_only = true;
|
||||
}
|
||||
/* This option is set for run-time meshes that have been copied from the current objects mode.
|
||||
* Currently this is used for edit-mesh although it could be used for sculpt or other
|
||||
|
@ -121,7 +126,7 @@ static void mesh_copy_data(Main *bmain, ID *id_dst, const ID *id_src, const int
|
|||
*
|
||||
* While this could be the callers responsibility, keep here since it's
|
||||
* highly unlikely we want to create a duplicate and not use it for drawing. */
|
||||
mesh_dst->runtime.is_original_bmesh = false;
|
||||
mesh_dst->runtime->is_original_bmesh = false;
|
||||
|
||||
/* Only do tessface if we have no polys. */
|
||||
const bool do_tessface = ((mesh_src->totface != 0) && (mesh_src->totpoly == 0));
|
||||
|
@ -194,6 +199,8 @@ static void mesh_free_data(ID *id)
|
|||
BKE_mesh_runtime_free_data(mesh);
|
||||
mesh_clear_geometry(mesh);
|
||||
MEM_SAFE_FREE(mesh->mat);
|
||||
|
||||
delete mesh->runtime;
|
||||
}
|
||||
|
||||
static void mesh_foreach_id(ID *id, LibraryForeachIDData *data)
|
||||
|
@ -229,7 +236,7 @@ static void mesh_blend_write(BlendWriter *writer, ID *id, const void *id_address
|
|||
mesh->mface = nullptr;
|
||||
mesh->totface = 0;
|
||||
memset(&mesh->fdata, 0, sizeof(mesh->fdata));
|
||||
mesh->runtime = blender::dna::shallow_zero_initialize();
|
||||
mesh->runtime = nullptr;
|
||||
|
||||
/* Do not store actual geometry data in case this is a library override ID. */
|
||||
if (ID_IS_OVERRIDE_LIBRARY(mesh) && !is_undo) {
|
||||
|
@ -339,8 +346,7 @@ static void mesh_blend_read_data(BlendDataReader *reader, ID *id)
|
|||
mesh->texflag &= ~ME_AUTOSPACE_EVALUATED;
|
||||
mesh->edit_mesh = nullptr;
|
||||
|
||||
mesh->runtime = blender::dna::shallow_zero_initialize();
|
||||
BKE_mesh_runtime_init_data(mesh);
|
||||
mesh->runtime = new blender::bke::MeshRuntime();
|
||||
|
||||
/* happens with old files */
|
||||
if (mesh->mselect == nullptr) {
|
||||
|
@ -1137,7 +1143,7 @@ static void ensure_orig_index_layer(CustomData &data, const int size)
|
|||
|
||||
void BKE_mesh_ensure_default_orig_index_customdata(Mesh *mesh)
|
||||
{
|
||||
BLI_assert(mesh->runtime.wrapper_type == ME_WRAPPER_TYPE_MDATA);
|
||||
BLI_assert(mesh->runtime->wrapper_type == ME_WRAPPER_TYPE_MDATA);
|
||||
BKE_mesh_ensure_default_orig_index_customdata_no_check(mesh);
|
||||
}
|
||||
|
||||
|
@ -2106,8 +2112,8 @@ void BKE_mesh_split_faces(Mesh *mesh, bool free_loop_normals)
|
|||
}
|
||||
|
||||
/* Update normals manually to avoid recalculation after this operation. */
|
||||
mesh->runtime.vert_normals = (float(*)[3])MEM_reallocN(mesh->runtime.vert_normals,
|
||||
sizeof(float[3]) * mesh->totvert);
|
||||
mesh->runtime->vert_normals = (float(*)[3])MEM_reallocN(mesh->runtime->vert_normals,
|
||||
sizeof(float[3]) * mesh->totvert);
|
||||
|
||||
/* Perform actual split of vertices and edges. */
|
||||
split_faces_split_new_verts(mesh, new_verts, num_new_verts);
|
||||
|
@ -2141,10 +2147,10 @@ void BKE_mesh_eval_geometry(Depsgraph *depsgraph, Mesh *mesh)
|
|||
/* We are here because something did change in the mesh. This means we can not trust the existing
|
||||
* evaluated mesh, and we don't know what parts of the mesh did change. So we simply delete the
|
||||
* evaluated mesh and let objects to re-create it with updated settings. */
|
||||
if (mesh->runtime.mesh_eval != nullptr) {
|
||||
mesh->runtime.mesh_eval->edit_mesh = nullptr;
|
||||
BKE_id_free(nullptr, mesh->runtime.mesh_eval);
|
||||
mesh->runtime.mesh_eval = nullptr;
|
||||
if (mesh->runtime->mesh_eval != nullptr) {
|
||||
mesh->runtime->mesh_eval->edit_mesh = nullptr;
|
||||
BKE_id_free(nullptr, mesh->runtime->mesh_eval);
|
||||
mesh->runtime->mesh_eval = nullptr;
|
||||
}
|
||||
if (DEG_is_active(depsgraph)) {
|
||||
Mesh *mesh_orig = (Mesh *)DEG_get_original_id(&mesh->id);
|
||||
|
|
|
@ -903,7 +903,7 @@ static Mesh *mesh_new_from_mesh(Object *object, Mesh *mesh)
|
|||
{
|
||||
/* While we could copy this into the new mesh,
|
||||
* add the data to 'mesh' so future calls to this function don't need to re-convert the data. */
|
||||
if (mesh->runtime.wrapper_type == ME_WRAPPER_TYPE_BMESH) {
|
||||
if (mesh->runtime->wrapper_type == ME_WRAPPER_TYPE_BMESH) {
|
||||
BKE_mesh_wrapper_ensure_mdata(mesh);
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -41,9 +41,9 @@ char *BKE_mesh_debug_info(const Mesh *me)
|
|||
BLI_dynstr_appendf(dynstr, " 'totface': %d,\n", me->totface);
|
||||
BLI_dynstr_appendf(dynstr, " 'totpoly': %d,\n", me->totpoly);
|
||||
|
||||
BLI_dynstr_appendf(dynstr, " 'runtime.deformed_only': %d,\n", me->runtime.deformed_only);
|
||||
BLI_dynstr_appendf(dynstr, " 'runtime.deformed_only': %d,\n", me->runtime->deformed_only);
|
||||
BLI_dynstr_appendf(
|
||||
dynstr, " 'runtime.is_original_bmesh': %d,\n", me->runtime.is_original_bmesh);
|
||||
dynstr, " 'runtime->is_original_bmesh': %d,\n", me->runtime->is_original_bmesh);
|
||||
|
||||
BLI_dynstr_append(dynstr, " 'vert_layers': (\n");
|
||||
CustomData_debug_info_from_layers(&me->vdata, indent8, dynstr);
|
||||
|
|
|
@ -36,18 +36,18 @@ void BKE_mesh_foreach_mapped_vert(
|
|||
void *userData,
|
||||
MeshForeachFlag flag)
|
||||
{
|
||||
if (mesh->edit_mesh != nullptr && mesh->runtime.edit_data != nullptr) {
|
||||
if (mesh->edit_mesh != nullptr && mesh->runtime->edit_data != nullptr) {
|
||||
BMEditMesh *em = mesh->edit_mesh;
|
||||
BMesh *bm = em->bm;
|
||||
BMIter iter;
|
||||
BMVert *eve;
|
||||
int i;
|
||||
if (mesh->runtime.edit_data->vertexCos != nullptr) {
|
||||
const float(*vertexCos)[3] = mesh->runtime.edit_data->vertexCos;
|
||||
if (mesh->runtime->edit_data->vertexCos != nullptr) {
|
||||
const float(*vertexCos)[3] = mesh->runtime->edit_data->vertexCos;
|
||||
const float(*vertexNos)[3];
|
||||
if (flag & MESH_FOREACH_USE_NORMAL) {
|
||||
BKE_editmesh_cache_ensure_vert_normals(em, mesh->runtime.edit_data);
|
||||
vertexNos = mesh->runtime.edit_data->vertexNos;
|
||||
BKE_editmesh_cache_ensure_vert_normals(em, mesh->runtime->edit_data);
|
||||
vertexNos = mesh->runtime->edit_data->vertexNos;
|
||||
}
|
||||
else {
|
||||
vertexNos = nullptr;
|
||||
|
@ -96,14 +96,14 @@ void BKE_mesh_foreach_mapped_edge(
|
|||
void (*func)(void *userData, int index, const float v0co[3], const float v1co[3]),
|
||||
void *userData)
|
||||
{
|
||||
if (mesh->edit_mesh != nullptr && mesh->runtime.edit_data) {
|
||||
if (mesh->edit_mesh != nullptr && mesh->runtime->edit_data) {
|
||||
BMEditMesh *em = mesh->edit_mesh;
|
||||
BMesh *bm = em->bm;
|
||||
BMIter iter;
|
||||
BMEdge *eed;
|
||||
int i;
|
||||
if (mesh->runtime.edit_data->vertexCos != nullptr) {
|
||||
const float(*vertexCos)[3] = mesh->runtime.edit_data->vertexCos;
|
||||
if (mesh->runtime->edit_data->vertexCos != nullptr) {
|
||||
const float(*vertexCos)[3] = mesh->runtime->edit_data->vertexCos;
|
||||
BM_mesh_elem_index_ensure(bm, BM_VERT);
|
||||
|
||||
BM_ITER_MESH_INDEX (eed, &iter, bm, BM_EDGES_OF_MESH, i) {
|
||||
|
@ -154,13 +154,13 @@ void BKE_mesh_foreach_mapped_loop(Mesh *mesh,
|
|||
/* We can't use `dm->getLoopDataLayout(dm)` here,
|
||||
* we want to always access `dm->loopData`, `EditDerivedBMesh` would
|
||||
* return loop data from BMesh itself. */
|
||||
if (mesh->edit_mesh != nullptr && mesh->runtime.edit_data) {
|
||||
if (mesh->edit_mesh != nullptr && mesh->runtime->edit_data) {
|
||||
BMEditMesh *em = mesh->edit_mesh;
|
||||
BMesh *bm = em->bm;
|
||||
BMIter iter;
|
||||
BMFace *efa;
|
||||
|
||||
const float(*vertexCos)[3] = mesh->runtime.edit_data->vertexCos;
|
||||
const float(*vertexCos)[3] = mesh->runtime->edit_data->vertexCos;
|
||||
|
||||
/* XXX: investigate using EditMesh data. */
|
||||
const float(*lnors)[3] = (flag & MESH_FOREACH_USE_NORMAL) ?
|
||||
|
@ -231,7 +231,7 @@ void BKE_mesh_foreach_mapped_face_center(
|
|||
void *userData,
|
||||
MeshForeachFlag flag)
|
||||
{
|
||||
if (mesh->edit_mesh != nullptr && mesh->runtime.edit_data != nullptr) {
|
||||
if (mesh->edit_mesh != nullptr && mesh->runtime->edit_data != nullptr) {
|
||||
BMEditMesh *em = mesh->edit_mesh;
|
||||
BMesh *bm = em->bm;
|
||||
const float(*polyCos)[3];
|
||||
|
@ -240,12 +240,12 @@ void BKE_mesh_foreach_mapped_face_center(
|
|||
BMIter iter;
|
||||
int i;
|
||||
|
||||
BKE_editmesh_cache_ensure_poly_centers(em, mesh->runtime.edit_data);
|
||||
polyCos = mesh->runtime.edit_data->polyCos; /* always set */
|
||||
BKE_editmesh_cache_ensure_poly_centers(em, mesh->runtime->edit_data);
|
||||
polyCos = mesh->runtime->edit_data->polyCos; /* always set */
|
||||
|
||||
if (flag & MESH_FOREACH_USE_NORMAL) {
|
||||
BKE_editmesh_cache_ensure_poly_normals(em, mesh->runtime.edit_data);
|
||||
polyNos = mesh->runtime.edit_data->polyNos; /* maybe nullptr */
|
||||
BKE_editmesh_cache_ensure_poly_normals(em, mesh->runtime->edit_data);
|
||||
polyNos = mesh->runtime->edit_data->polyNos; /* maybe nullptr */
|
||||
}
|
||||
else {
|
||||
polyNos = nullptr;
|
||||
|
@ -317,7 +317,7 @@ void BKE_mesh_foreach_mapped_subdiv_face_center(
|
|||
BKE_mesh_vertex_normals_ensure(mesh) :
|
||||
nullptr;
|
||||
const int *index = static_cast<const int *>(CustomData_get_layer(&mesh->pdata, CD_ORIGINDEX));
|
||||
const BLI_bitmap *facedot_tags = mesh->runtime.subsurf_face_dot_tags;
|
||||
const BLI_bitmap *facedot_tags = mesh->runtime->subsurf_face_dot_tags;
|
||||
BLI_assert(facedot_tags != nullptr);
|
||||
|
||||
if (index) {
|
||||
|
|
|
@ -95,72 +95,72 @@ static void add_v3_v3_atomic(float r[3], const float a[3])
|
|||
|
||||
void BKE_mesh_normals_tag_dirty(Mesh *mesh)
|
||||
{
|
||||
mesh->runtime.vert_normals_dirty = true;
|
||||
mesh->runtime.poly_normals_dirty = true;
|
||||
mesh->runtime->vert_normals_dirty = true;
|
||||
mesh->runtime->poly_normals_dirty = true;
|
||||
}
|
||||
|
||||
float (*BKE_mesh_vertex_normals_for_write(Mesh *mesh))[3]
|
||||
{
|
||||
if (mesh->runtime.vert_normals == nullptr) {
|
||||
mesh->runtime.vert_normals = (float(*)[3])MEM_malloc_arrayN(
|
||||
if (mesh->runtime->vert_normals == nullptr) {
|
||||
mesh->runtime->vert_normals = (float(*)[3])MEM_malloc_arrayN(
|
||||
mesh->totvert, sizeof(float[3]), __func__);
|
||||
}
|
||||
|
||||
BLI_assert(MEM_allocN_len(mesh->runtime.vert_normals) >= sizeof(float[3]) * mesh->totvert);
|
||||
BLI_assert(MEM_allocN_len(mesh->runtime->vert_normals) >= sizeof(float[3]) * mesh->totvert);
|
||||
|
||||
return mesh->runtime.vert_normals;
|
||||
return mesh->runtime->vert_normals;
|
||||
}
|
||||
|
||||
float (*BKE_mesh_poly_normals_for_write(Mesh *mesh))[3]
|
||||
{
|
||||
if (mesh->runtime.poly_normals == nullptr) {
|
||||
mesh->runtime.poly_normals = (float(*)[3])MEM_malloc_arrayN(
|
||||
if (mesh->runtime->poly_normals == nullptr) {
|
||||
mesh->runtime->poly_normals = (float(*)[3])MEM_malloc_arrayN(
|
||||
mesh->totpoly, sizeof(float[3]), __func__);
|
||||
}
|
||||
|
||||
BLI_assert(MEM_allocN_len(mesh->runtime.poly_normals) >= sizeof(float[3]) * mesh->totpoly);
|
||||
BLI_assert(MEM_allocN_len(mesh->runtime->poly_normals) >= sizeof(float[3]) * mesh->totpoly);
|
||||
|
||||
return mesh->runtime.poly_normals;
|
||||
return mesh->runtime->poly_normals;
|
||||
}
|
||||
|
||||
void BKE_mesh_vertex_normals_clear_dirty(Mesh *mesh)
|
||||
{
|
||||
mesh->runtime.vert_normals_dirty = false;
|
||||
mesh->runtime->vert_normals_dirty = false;
|
||||
BKE_mesh_assert_normals_dirty_or_calculated(mesh);
|
||||
}
|
||||
|
||||
void BKE_mesh_poly_normals_clear_dirty(Mesh *mesh)
|
||||
{
|
||||
mesh->runtime.poly_normals_dirty = false;
|
||||
mesh->runtime->poly_normals_dirty = false;
|
||||
BKE_mesh_assert_normals_dirty_or_calculated(mesh);
|
||||
}
|
||||
|
||||
bool BKE_mesh_vertex_normals_are_dirty(const Mesh *mesh)
|
||||
{
|
||||
return mesh->runtime.vert_normals_dirty;
|
||||
return mesh->runtime->vert_normals_dirty;
|
||||
}
|
||||
|
||||
bool BKE_mesh_poly_normals_are_dirty(const Mesh *mesh)
|
||||
{
|
||||
return mesh->runtime.poly_normals_dirty;
|
||||
return mesh->runtime->poly_normals_dirty;
|
||||
}
|
||||
|
||||
void BKE_mesh_clear_derived_normals(Mesh *mesh)
|
||||
{
|
||||
MEM_SAFE_FREE(mesh->runtime.vert_normals);
|
||||
MEM_SAFE_FREE(mesh->runtime.poly_normals);
|
||||
MEM_SAFE_FREE(mesh->runtime->vert_normals);
|
||||
MEM_SAFE_FREE(mesh->runtime->poly_normals);
|
||||
|
||||
mesh->runtime.vert_normals_dirty = true;
|
||||
mesh->runtime.poly_normals_dirty = true;
|
||||
mesh->runtime->vert_normals_dirty = true;
|
||||
mesh->runtime->poly_normals_dirty = true;
|
||||
}
|
||||
|
||||
void BKE_mesh_assert_normals_dirty_or_calculated(const Mesh *mesh)
|
||||
{
|
||||
if (!mesh->runtime.vert_normals_dirty) {
|
||||
BLI_assert(mesh->runtime.vert_normals || mesh->totvert == 0);
|
||||
if (!mesh->runtime->vert_normals_dirty) {
|
||||
BLI_assert(mesh->runtime->vert_normals || mesh->totvert == 0);
|
||||
}
|
||||
if (!mesh->runtime.poly_normals_dirty) {
|
||||
BLI_assert(mesh->runtime.poly_normals || mesh->totpoly == 0);
|
||||
if (!mesh->runtime->poly_normals_dirty) {
|
||||
BLI_assert(mesh->runtime->poly_normals || mesh->totpoly == 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -348,20 +348,20 @@ void BKE_mesh_calc_normals_poly_and_vertex(const MVert *mvert,
|
|||
const float (*BKE_mesh_vertex_normals_ensure(const Mesh *mesh))[3]
|
||||
{
|
||||
if (!BKE_mesh_vertex_normals_are_dirty(mesh)) {
|
||||
BLI_assert(mesh->runtime.vert_normals != nullptr || mesh->totvert == 0);
|
||||
return mesh->runtime.vert_normals;
|
||||
BLI_assert(mesh->runtime->vert_normals != nullptr || mesh->totvert == 0);
|
||||
return mesh->runtime->vert_normals;
|
||||
}
|
||||
|
||||
if (mesh->totvert == 0) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ThreadMutex *normals_mutex = (ThreadMutex *)mesh->runtime.normals_mutex;
|
||||
ThreadMutex *normals_mutex = (ThreadMutex *)mesh->runtime->normals_mutex;
|
||||
BLI_mutex_lock(normals_mutex);
|
||||
if (!BKE_mesh_vertex_normals_are_dirty(mesh)) {
|
||||
BLI_assert(mesh->runtime.vert_normals != nullptr);
|
||||
BLI_assert(mesh->runtime->vert_normals != nullptr);
|
||||
BLI_mutex_unlock(normals_mutex);
|
||||
return mesh->runtime.vert_normals;
|
||||
return mesh->runtime->vert_normals;
|
||||
}
|
||||
|
||||
float(*vert_normals)[3];
|
||||
|
@ -397,20 +397,20 @@ const float (*BKE_mesh_vertex_normals_ensure(const Mesh *mesh))[3]
|
|||
const float (*BKE_mesh_poly_normals_ensure(const Mesh *mesh))[3]
|
||||
{
|
||||
if (!BKE_mesh_poly_normals_are_dirty(mesh)) {
|
||||
BLI_assert(mesh->runtime.poly_normals != nullptr || mesh->totpoly == 0);
|
||||
return mesh->runtime.poly_normals;
|
||||
BLI_assert(mesh->runtime->poly_normals != nullptr || mesh->totpoly == 0);
|
||||
return mesh->runtime->poly_normals;
|
||||
}
|
||||
|
||||
if (mesh->totpoly == 0) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ThreadMutex *normals_mutex = (ThreadMutex *)mesh->runtime.normals_mutex;
|
||||
ThreadMutex *normals_mutex = (ThreadMutex *)mesh->runtime->normals_mutex;
|
||||
BLI_mutex_lock(normals_mutex);
|
||||
if (!BKE_mesh_poly_normals_are_dirty(mesh)) {
|
||||
BLI_assert(mesh->runtime.poly_normals != nullptr);
|
||||
BLI_assert(mesh->runtime->poly_normals != nullptr);
|
||||
BLI_mutex_unlock(normals_mutex);
|
||||
return mesh->runtime.poly_normals;
|
||||
return mesh->runtime->poly_normals;
|
||||
}
|
||||
|
||||
float(*poly_normals)[3];
|
||||
|
@ -441,7 +441,7 @@ const float (*BKE_mesh_poly_normals_ensure(const Mesh *mesh))[3]
|
|||
|
||||
void BKE_mesh_ensure_normals_for_display(Mesh *mesh)
|
||||
{
|
||||
switch ((eMeshWrapperType)mesh->runtime.wrapper_type) {
|
||||
switch (mesh->runtime->wrapper_type) {
|
||||
case ME_WRAPPER_TYPE_SUBD:
|
||||
case ME_WRAPPER_TYPE_MDATA:
|
||||
BKE_mesh_vertex_normals_ensure(mesh);
|
||||
|
@ -449,7 +449,7 @@ void BKE_mesh_ensure_normals_for_display(Mesh *mesh)
|
|||
break;
|
||||
case ME_WRAPPER_TYPE_BMESH: {
|
||||
struct BMEditMesh *em = mesh->edit_mesh;
|
||||
EditMeshData *emd = mesh->runtime.edit_data;
|
||||
EditMeshData *emd = mesh->runtime->edit_data;
|
||||
if (emd->vertexCos) {
|
||||
BKE_editmesh_cache_ensure_vert_normals(em, emd);
|
||||
BKE_editmesh_cache_ensure_poly_normals(em, emd);
|
||||
|
|
|
@ -1529,7 +1529,7 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode,
|
|||
BLI_bitmap *looptri_active;
|
||||
|
||||
looptri_src = BKE_mesh_runtime_looptri_ensure(me_src);
|
||||
num_looptri_src = me_src->runtime.looptris.len;
|
||||
num_looptri_src = BKE_mesh_runtime_looptri_len(me_src);
|
||||
looptri_active = BLI_BITMAP_NEW((size_t)num_looptri_src, __func__);
|
||||
|
||||
for (tindex = 0; tindex < num_trees; tindex++) {
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include "BLI_task.hh"
|
||||
|
||||
#include "BKE_bvhutils.h"
|
||||
#include "BKE_editmesh_cache.h"
|
||||
#include "BKE_lib_id.h"
|
||||
#include "BKE_mesh.h"
|
||||
#include "BKE_mesh_runtime.h"
|
||||
|
@ -30,81 +31,50 @@ using blender::Span;
|
|||
/** \name Mesh Runtime Struct Utils
|
||||
* \{ */
|
||||
|
||||
/**
|
||||
* \brief Initialize the runtime mutexes of the given mesh.
|
||||
*
|
||||
* Any existing mutexes will be overridden.
|
||||
*/
|
||||
static void mesh_runtime_init_mutexes(Mesh *mesh)
|
||||
{
|
||||
mesh->runtime.eval_mutex = MEM_new<ThreadMutex>("mesh runtime eval_mutex");
|
||||
BLI_mutex_init(static_cast<ThreadMutex *>(mesh->runtime.eval_mutex));
|
||||
mesh->runtime.normals_mutex = MEM_new<ThreadMutex>("mesh runtime normals_mutex");
|
||||
BLI_mutex_init(static_cast<ThreadMutex *>(mesh->runtime.normals_mutex));
|
||||
mesh->runtime.render_mutex = MEM_new<ThreadMutex>("mesh runtime render_mutex");
|
||||
BLI_mutex_init(static_cast<ThreadMutex *>(mesh->runtime.render_mutex));
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief free the mutexes of the given mesh runtime.
|
||||
*/
|
||||
static void mesh_runtime_free_mutexes(Mesh *mesh)
|
||||
{
|
||||
if (mesh->runtime.eval_mutex != nullptr) {
|
||||
BLI_mutex_end(static_cast<ThreadMutex *>(mesh->runtime.eval_mutex));
|
||||
MEM_freeN(mesh->runtime.eval_mutex);
|
||||
mesh->runtime.eval_mutex = nullptr;
|
||||
}
|
||||
if (mesh->runtime.normals_mutex != nullptr) {
|
||||
BLI_mutex_end(static_cast<ThreadMutex *>(mesh->runtime.normals_mutex));
|
||||
MEM_freeN(mesh->runtime.normals_mutex);
|
||||
mesh->runtime.normals_mutex = nullptr;
|
||||
}
|
||||
if (mesh->runtime.render_mutex != nullptr) {
|
||||
BLI_mutex_end(static_cast<ThreadMutex *>(mesh->runtime.render_mutex));
|
||||
MEM_freeN(mesh->runtime.render_mutex);
|
||||
mesh->runtime.render_mutex = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void BKE_mesh_runtime_init_data(Mesh *mesh)
|
||||
{
|
||||
mesh_runtime_init_mutexes(mesh);
|
||||
}
|
||||
|
||||
void BKE_mesh_runtime_free_data(Mesh *mesh)
|
||||
{
|
||||
BKE_mesh_runtime_clear_cache(mesh);
|
||||
mesh_runtime_free_mutexes(mesh);
|
||||
}
|
||||
|
||||
void BKE_mesh_runtime_reset_on_copy(Mesh *mesh, const int /*flag*/)
|
||||
namespace blender::bke {
|
||||
|
||||
MeshRuntime::MeshRuntime()
|
||||
{
|
||||
Mesh_Runtime *runtime = &mesh->runtime;
|
||||
|
||||
runtime->mesh_eval = nullptr;
|
||||
runtime->edit_data = nullptr;
|
||||
runtime->batch_cache = nullptr;
|
||||
runtime->subdiv_ccg = nullptr;
|
||||
runtime->looptris = blender::dna::shallow_zero_initialize();
|
||||
runtime->bvh_cache = nullptr;
|
||||
runtime->shrinkwrap_data = nullptr;
|
||||
runtime->subsurf_face_dot_tags = nullptr;
|
||||
|
||||
runtime->vert_normals_dirty = true;
|
||||
runtime->poly_normals_dirty = true;
|
||||
runtime->vert_normals = nullptr;
|
||||
runtime->poly_normals = nullptr;
|
||||
|
||||
mesh_runtime_init_mutexes(mesh);
|
||||
this->eval_mutex = MEM_new<ThreadMutex>("mesh runtime eval_mutex");
|
||||
BLI_mutex_init(static_cast<ThreadMutex *>(this->eval_mutex));
|
||||
this->normals_mutex = MEM_new<ThreadMutex>("mesh runtime normals_mutex");
|
||||
BLI_mutex_init(static_cast<ThreadMutex *>(this->normals_mutex));
|
||||
this->render_mutex = MEM_new<ThreadMutex>("mesh runtime render_mutex");
|
||||
BLI_mutex_init(static_cast<ThreadMutex *>(this->render_mutex));
|
||||
}
|
||||
|
||||
MeshRuntime::~MeshRuntime()
|
||||
{
|
||||
if (this->eval_mutex != nullptr) {
|
||||
BLI_mutex_end(static_cast<ThreadMutex *>(this->eval_mutex));
|
||||
MEM_freeN(this->eval_mutex);
|
||||
this->eval_mutex = nullptr;
|
||||
}
|
||||
if (this->normals_mutex != nullptr) {
|
||||
BLI_mutex_end(static_cast<ThreadMutex *>(this->normals_mutex));
|
||||
MEM_freeN(this->normals_mutex);
|
||||
this->normals_mutex = nullptr;
|
||||
}
|
||||
if (this->render_mutex != nullptr) {
|
||||
BLI_mutex_end(static_cast<ThreadMutex *>(this->render_mutex));
|
||||
MEM_freeN(this->render_mutex);
|
||||
this->render_mutex = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace blender::bke
|
||||
|
||||
void BKE_mesh_runtime_clear_cache(Mesh *mesh)
|
||||
{
|
||||
if (mesh->runtime.mesh_eval != nullptr) {
|
||||
mesh->runtime.mesh_eval->edit_mesh = nullptr;
|
||||
BKE_id_free(nullptr, mesh->runtime.mesh_eval);
|
||||
mesh->runtime.mesh_eval = nullptr;
|
||||
if (mesh->runtime->mesh_eval != nullptr) {
|
||||
mesh->runtime->mesh_eval->edit_mesh = nullptr;
|
||||
BKE_id_free(nullptr, mesh->runtime->mesh_eval);
|
||||
mesh->runtime->mesh_eval = nullptr;
|
||||
}
|
||||
BKE_mesh_runtime_clear_geometry(mesh);
|
||||
BKE_mesh_batch_cache_free(mesh);
|
||||
|
@ -131,32 +101,32 @@ static void mesh_ensure_looptri_data(Mesh *mesh)
|
|||
const uint totpoly = mesh->totpoly;
|
||||
const int looptris_len = poly_to_tri_count(totpoly, mesh->totloop);
|
||||
|
||||
BLI_assert(mesh->runtime.looptris.array_wip == nullptr);
|
||||
BLI_assert(mesh->runtime->looptris.array_wip == nullptr);
|
||||
|
||||
SWAP(MLoopTri *, mesh->runtime.looptris.array, mesh->runtime.looptris.array_wip);
|
||||
SWAP(MLoopTri *, mesh->runtime->looptris.array, mesh->runtime->looptris.array_wip);
|
||||
|
||||
if ((looptris_len > mesh->runtime.looptris.len_alloc) ||
|
||||
(looptris_len < mesh->runtime.looptris.len_alloc * 2) || (totpoly == 0)) {
|
||||
MEM_SAFE_FREE(mesh->runtime.looptris.array_wip);
|
||||
mesh->runtime.looptris.len_alloc = 0;
|
||||
mesh->runtime.looptris.len = 0;
|
||||
if ((looptris_len > mesh->runtime->looptris.len_alloc) ||
|
||||
(looptris_len < mesh->runtime->looptris.len_alloc * 2) || (totpoly == 0)) {
|
||||
MEM_SAFE_FREE(mesh->runtime->looptris.array_wip);
|
||||
mesh->runtime->looptris.len_alloc = 0;
|
||||
mesh->runtime->looptris.len = 0;
|
||||
}
|
||||
|
||||
if (totpoly) {
|
||||
if (mesh->runtime.looptris.array_wip == nullptr) {
|
||||
mesh->runtime.looptris.array_wip = static_cast<MLoopTri *>(
|
||||
MEM_malloc_arrayN(looptris_len, sizeof(*mesh->runtime.looptris.array_wip), __func__));
|
||||
mesh->runtime.looptris.len_alloc = looptris_len;
|
||||
if (mesh->runtime->looptris.array_wip == nullptr) {
|
||||
mesh->runtime->looptris.array_wip = static_cast<MLoopTri *>(
|
||||
MEM_malloc_arrayN(looptris_len, sizeof(*mesh->runtime->looptris.array_wip), __func__));
|
||||
mesh->runtime->looptris.len_alloc = looptris_len;
|
||||
}
|
||||
|
||||
mesh->runtime.looptris.len = looptris_len;
|
||||
mesh->runtime->looptris.len = looptris_len;
|
||||
}
|
||||
}
|
||||
|
||||
void BKE_mesh_runtime_looptri_recalc(Mesh *mesh)
|
||||
{
|
||||
mesh_ensure_looptri_data(mesh);
|
||||
BLI_assert(mesh->totpoly == 0 || mesh->runtime.looptris.array_wip != nullptr);
|
||||
BLI_assert(mesh->totpoly == 0 || mesh->runtime->looptris.array_wip != nullptr);
|
||||
const Span<MVert> verts = mesh->verts();
|
||||
const Span<MPoly> polys = mesh->polys();
|
||||
const Span<MLoop> loops = mesh->loops();
|
||||
|
@ -167,7 +137,7 @@ void BKE_mesh_runtime_looptri_recalc(Mesh *mesh)
|
|||
verts.data(),
|
||||
mesh->totloop,
|
||||
mesh->totpoly,
|
||||
mesh->runtime.looptris.array_wip,
|
||||
mesh->runtime->looptris.array_wip,
|
||||
BKE_mesh_poly_normals_ensure(mesh));
|
||||
}
|
||||
else {
|
||||
|
@ -176,39 +146,39 @@ void BKE_mesh_runtime_looptri_recalc(Mesh *mesh)
|
|||
verts.data(),
|
||||
mesh->totloop,
|
||||
mesh->totpoly,
|
||||
mesh->runtime.looptris.array_wip);
|
||||
mesh->runtime->looptris.array_wip);
|
||||
}
|
||||
|
||||
BLI_assert(mesh->runtime.looptris.array == nullptr);
|
||||
atomic_cas_ptr((void **)&mesh->runtime.looptris.array,
|
||||
mesh->runtime.looptris.array,
|
||||
mesh->runtime.looptris.array_wip);
|
||||
mesh->runtime.looptris.array_wip = nullptr;
|
||||
BLI_assert(mesh->runtime->looptris.array == nullptr);
|
||||
atomic_cas_ptr((void **)&mesh->runtime->looptris.array,
|
||||
mesh->runtime->looptris.array,
|
||||
mesh->runtime->looptris.array_wip);
|
||||
mesh->runtime->looptris.array_wip = nullptr;
|
||||
}
|
||||
|
||||
int BKE_mesh_runtime_looptri_len(const Mesh *mesh)
|
||||
{
|
||||
/* This is a ported copy of `dm_getNumLoopTri(dm)`. */
|
||||
const int looptri_len = poly_to_tri_count(mesh->totpoly, mesh->totloop);
|
||||
BLI_assert(ELEM(mesh->runtime.looptris.len, 0, looptri_len));
|
||||
BLI_assert(ELEM(mesh->runtime->looptris.len, 0, looptri_len));
|
||||
return looptri_len;
|
||||
}
|
||||
|
||||
const MLoopTri *BKE_mesh_runtime_looptri_ensure(const Mesh *mesh)
|
||||
{
|
||||
ThreadMutex *mesh_eval_mutex = (ThreadMutex *)mesh->runtime.eval_mutex;
|
||||
ThreadMutex *mesh_eval_mutex = (ThreadMutex *)mesh->runtime->eval_mutex;
|
||||
BLI_mutex_lock(mesh_eval_mutex);
|
||||
|
||||
MLoopTri *looptri = mesh->runtime.looptris.array;
|
||||
MLoopTri *looptri = mesh->runtime->looptris.array;
|
||||
|
||||
if (looptri != nullptr) {
|
||||
BLI_assert(BKE_mesh_runtime_looptri_len(mesh) == mesh->runtime.looptris.len);
|
||||
BLI_assert(BKE_mesh_runtime_looptri_len(mesh) == mesh->runtime->looptris.len);
|
||||
}
|
||||
else {
|
||||
/* Must isolate multithreaded tasks while holding a mutex lock. */
|
||||
blender::threading::isolate_task(
|
||||
[&]() { BKE_mesh_runtime_looptri_recalc(const_cast<Mesh *>(mesh)); });
|
||||
looptri = mesh->runtime.looptris.array;
|
||||
looptri = mesh->runtime->looptris.array;
|
||||
}
|
||||
|
||||
BLI_mutex_unlock(mesh_eval_mutex);
|
||||
|
@ -230,17 +200,17 @@ void BKE_mesh_runtime_verttri_from_looptri(MVertTri *r_verttri,
|
|||
|
||||
bool BKE_mesh_runtime_ensure_edit_data(struct Mesh *mesh)
|
||||
{
|
||||
if (mesh->runtime.edit_data != nullptr) {
|
||||
if (mesh->runtime->edit_data != nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mesh->runtime.edit_data = MEM_cnew<EditMeshData>(__func__);
|
||||
mesh->runtime->edit_data = MEM_cnew<EditMeshData>(__func__);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BKE_mesh_runtime_reset_edit_data(Mesh *mesh)
|
||||
{
|
||||
EditMeshData *edit_data = mesh->runtime.edit_data;
|
||||
EditMeshData *edit_data = mesh->runtime->edit_data;
|
||||
if (edit_data == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
@ -255,13 +225,13 @@ bool BKE_mesh_runtime_reset_edit_data(Mesh *mesh)
|
|||
|
||||
bool BKE_mesh_runtime_clear_edit_data(Mesh *mesh)
|
||||
{
|
||||
if (mesh->runtime.edit_data == nullptr) {
|
||||
if (mesh->runtime->edit_data == nullptr) {
|
||||
return false;
|
||||
}
|
||||
BKE_mesh_runtime_reset_edit_data(mesh);
|
||||
|
||||
MEM_freeN(mesh->runtime.edit_data);
|
||||
mesh->runtime.edit_data = nullptr;
|
||||
MEM_freeN(mesh->runtime->edit_data);
|
||||
mesh->runtime->edit_data = nullptr;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -271,22 +241,22 @@ void BKE_mesh_runtime_clear_geometry(Mesh *mesh)
|
|||
BKE_mesh_tag_coords_changed(mesh);
|
||||
|
||||
/* TODO(sergey): Does this really belong here? */
|
||||
if (mesh->runtime.subdiv_ccg != nullptr) {
|
||||
BKE_subdiv_ccg_destroy(mesh->runtime.subdiv_ccg);
|
||||
mesh->runtime.subdiv_ccg = nullptr;
|
||||
if (mesh->runtime->subdiv_ccg != nullptr) {
|
||||
BKE_subdiv_ccg_destroy(mesh->runtime->subdiv_ccg);
|
||||
mesh->runtime->subdiv_ccg = nullptr;
|
||||
}
|
||||
BKE_shrinkwrap_discard_boundary_data(mesh);
|
||||
|
||||
MEM_SAFE_FREE(mesh->runtime.subsurf_face_dot_tags);
|
||||
MEM_SAFE_FREE(mesh->runtime->subsurf_face_dot_tags);
|
||||
}
|
||||
|
||||
void BKE_mesh_tag_coords_changed(Mesh *mesh)
|
||||
{
|
||||
BKE_mesh_normals_tag_dirty(mesh);
|
||||
MEM_SAFE_FREE(mesh->runtime.looptris.array);
|
||||
if (mesh->runtime.bvh_cache) {
|
||||
bvhcache_free(mesh->runtime.bvh_cache);
|
||||
mesh->runtime.bvh_cache = nullptr;
|
||||
MEM_SAFE_FREE(mesh->runtime->looptris.array);
|
||||
if (mesh->runtime->bvh_cache) {
|
||||
bvhcache_free(mesh->runtime->bvh_cache);
|
||||
mesh->runtime->bvh_cache = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -305,6 +275,16 @@ void BKE_mesh_tag_coords_changed_uniformly(Mesh *mesh)
|
|||
}
|
||||
}
|
||||
|
||||
bool BKE_mesh_is_deformed_only(const Mesh *mesh)
|
||||
{
|
||||
return mesh->runtime->deformed_only;
|
||||
}
|
||||
|
||||
eMeshWrapperType BKE_mesh_wrapper_type(const struct Mesh *mesh)
|
||||
{
|
||||
return mesh->runtime->wrapper_type;
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
@ -317,13 +297,13 @@ void (*BKE_mesh_batch_cache_free_cb)(Mesh *me) = nullptr;
|
|||
|
||||
void BKE_mesh_batch_cache_dirty_tag(Mesh *me, eMeshBatchDirtyMode mode)
|
||||
{
|
||||
if (me->runtime.batch_cache) {
|
||||
if (me->runtime->batch_cache) {
|
||||
BKE_mesh_batch_cache_dirty_tag_cb(me, mode);
|
||||
}
|
||||
}
|
||||
void BKE_mesh_batch_cache_free(Mesh *me)
|
||||
{
|
||||
if (me->runtime.batch_cache) {
|
||||
if (me->runtime->batch_cache) {
|
||||
BKE_mesh_batch_cache_free_cb(me);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -570,8 +570,6 @@ void BKE_mesh_calc_loop_tangents(Mesh *me_eval,
|
|||
const char (*tangent_names)[MAX_NAME],
|
||||
int tangent_names_len)
|
||||
{
|
||||
BKE_mesh_runtime_looptri_ensure(me_eval);
|
||||
|
||||
/* TODO(@campbellbarton): store in Mesh.runtime to avoid recalculation. */
|
||||
short tangent_mask = 0;
|
||||
BKE_mesh_calc_loop_tangent_ex(
|
||||
|
@ -579,8 +577,8 @@ void BKE_mesh_calc_loop_tangents(Mesh *me_eval,
|
|||
BKE_mesh_polys(me_eval),
|
||||
uint(me_eval->totpoly),
|
||||
BKE_mesh_loops(me_eval),
|
||||
me_eval->runtime.looptris.array,
|
||||
uint(me_eval->runtime.looptris.len),
|
||||
BKE_mesh_runtime_looptri_ensure(me_eval),
|
||||
uint(BKE_mesh_runtime_looptri_len(me_eval)),
|
||||
&me_eval->ldata,
|
||||
calc_active_tangent,
|
||||
tangent_names,
|
||||
|
|
|
@ -57,13 +57,13 @@ Mesh *BKE_mesh_wrapper_from_editmesh_with_coords(BMEditMesh *em,
|
|||
BKE_mesh_copy_parameters_for_eval(me, me_settings);
|
||||
BKE_mesh_runtime_ensure_edit_data(me);
|
||||
|
||||
me->runtime.wrapper_type = ME_WRAPPER_TYPE_BMESH;
|
||||
me->runtime->wrapper_type = ME_WRAPPER_TYPE_BMESH;
|
||||
if (cd_mask_extra) {
|
||||
me->runtime.cd_mask_extra = *cd_mask_extra;
|
||||
me->runtime->cd_mask_extra = *cd_mask_extra;
|
||||
}
|
||||
|
||||
/* Use edit-mesh directly where possible. */
|
||||
me->runtime.is_original_bmesh = true;
|
||||
me->runtime->is_original_bmesh = true;
|
||||
|
||||
me->edit_mesh = static_cast<BMEditMesh *>(MEM_dupallocN(em));
|
||||
me->edit_mesh->is_shallow_copy = true;
|
||||
|
@ -81,7 +81,7 @@ Mesh *BKE_mesh_wrapper_from_editmesh_with_coords(BMEditMesh *em,
|
|||
me->totloop = 0;
|
||||
#endif
|
||||
|
||||
EditMeshData *edit_data = me->runtime.edit_data;
|
||||
EditMeshData *edit_data = me->runtime->edit_data;
|
||||
edit_data->vertexCos = vert_coords;
|
||||
return me;
|
||||
}
|
||||
|
@ -95,17 +95,17 @@ Mesh *BKE_mesh_wrapper_from_editmesh(BMEditMesh *em,
|
|||
|
||||
void BKE_mesh_wrapper_ensure_mdata(Mesh *me)
|
||||
{
|
||||
ThreadMutex *mesh_eval_mutex = (ThreadMutex *)me->runtime.eval_mutex;
|
||||
ThreadMutex *mesh_eval_mutex = (ThreadMutex *)me->runtime->eval_mutex;
|
||||
BLI_mutex_lock(mesh_eval_mutex);
|
||||
|
||||
if (me->runtime.wrapper_type == ME_WRAPPER_TYPE_MDATA) {
|
||||
if (me->runtime->wrapper_type == ME_WRAPPER_TYPE_MDATA) {
|
||||
BLI_mutex_unlock(mesh_eval_mutex);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Must isolate multithreaded tasks while holding a mutex lock. */
|
||||
blender::threading::isolate_task([&]() {
|
||||
switch (static_cast<eMeshWrapperType>(me->runtime.wrapper_type)) {
|
||||
switch (static_cast<eMeshWrapperType>(me->runtime->wrapper_type)) {
|
||||
case ME_WRAPPER_TYPE_MDATA:
|
||||
case ME_WRAPPER_TYPE_SUBD: {
|
||||
break; /* Quiet warning. */
|
||||
|
@ -117,10 +117,10 @@ void BKE_mesh_wrapper_ensure_mdata(Mesh *me)
|
|||
me->totloop = 0;
|
||||
|
||||
BLI_assert(me->edit_mesh != nullptr);
|
||||
BLI_assert(me->runtime.edit_data != nullptr);
|
||||
BLI_assert(me->runtime->edit_data != nullptr);
|
||||
|
||||
BMEditMesh *em = me->edit_mesh;
|
||||
BM_mesh_bm_to_me_for_eval(em->bm, me, &me->runtime.cd_mask_extra);
|
||||
BM_mesh_bm_to_me_for_eval(em->bm, me, &me->runtime->cd_mask_extra);
|
||||
|
||||
/* Adding original index layers assumes that all BMesh mesh wrappers are created from
|
||||
* original edit mode meshes (the only case where adding original indices makes sense).
|
||||
|
@ -132,22 +132,22 @@ void BKE_mesh_wrapper_ensure_mdata(Mesh *me)
|
|||
* harmful. */
|
||||
BKE_mesh_ensure_default_orig_index_customdata_no_check(me);
|
||||
|
||||
EditMeshData *edit_data = me->runtime.edit_data;
|
||||
EditMeshData *edit_data = me->runtime->edit_data;
|
||||
if (edit_data->vertexCos) {
|
||||
BKE_mesh_vert_coords_apply(me, edit_data->vertexCos);
|
||||
me->runtime.is_original_bmesh = false;
|
||||
me->runtime->is_original_bmesh = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (me->runtime.wrapper_type_finalize) {
|
||||
BKE_mesh_wrapper_deferred_finalize_mdata(me, &me->runtime.cd_mask_extra);
|
||||
if (me->runtime->wrapper_type_finalize) {
|
||||
BKE_mesh_wrapper_deferred_finalize_mdata(me, &me->runtime->cd_mask_extra);
|
||||
}
|
||||
|
||||
/* Keep type assignment last, so that read-only access only uses the mdata code paths after all
|
||||
* the underlying data has been initialized. */
|
||||
me->runtime.wrapper_type = ME_WRAPPER_TYPE_MDATA;
|
||||
me->runtime->wrapper_type = ME_WRAPPER_TYPE_MDATA;
|
||||
});
|
||||
|
||||
BLI_mutex_unlock(mesh_eval_mutex);
|
||||
|
@ -155,9 +155,9 @@ void BKE_mesh_wrapper_ensure_mdata(Mesh *me)
|
|||
|
||||
bool BKE_mesh_wrapper_minmax(const Mesh *me, float min[3], float max[3])
|
||||
{
|
||||
switch ((eMeshWrapperType)me->runtime.wrapper_type) {
|
||||
switch (me->runtime->wrapper_type) {
|
||||
case ME_WRAPPER_TYPE_BMESH:
|
||||
return BKE_editmesh_cache_calc_minmax(me->edit_mesh, me->runtime.edit_data, min, max);
|
||||
return BKE_editmesh_cache_calc_minmax(me->edit_mesh, me->runtime->edit_data, min, max);
|
||||
case ME_WRAPPER_TYPE_MDATA:
|
||||
case ME_WRAPPER_TYPE_SUBD:
|
||||
return BKE_mesh_minmax(me, min, max);
|
||||
|
@ -174,11 +174,11 @@ void BKE_mesh_wrapper_vert_coords_copy(const Mesh *me,
|
|||
float (*vert_coords)[3],
|
||||
int vert_coords_len)
|
||||
{
|
||||
switch ((eMeshWrapperType)me->runtime.wrapper_type) {
|
||||
switch (me->runtime->wrapper_type) {
|
||||
case ME_WRAPPER_TYPE_BMESH: {
|
||||
BMesh *bm = me->edit_mesh->bm;
|
||||
BLI_assert(vert_coords_len <= bm->totvert);
|
||||
EditMeshData *edit_data = me->runtime.edit_data;
|
||||
EditMeshData *edit_data = me->runtime->edit_data;
|
||||
if (edit_data->vertexCos != nullptr) {
|
||||
for (int i = 0; i < vert_coords_len; i++) {
|
||||
copy_v3_v3(vert_coords[i], edit_data->vertexCos[i]);
|
||||
|
@ -212,11 +212,11 @@ void BKE_mesh_wrapper_vert_coords_copy_with_mat4(const Mesh *me,
|
|||
int vert_coords_len,
|
||||
const float mat[4][4])
|
||||
{
|
||||
switch ((eMeshWrapperType)me->runtime.wrapper_type) {
|
||||
switch (me->runtime->wrapper_type) {
|
||||
case ME_WRAPPER_TYPE_BMESH: {
|
||||
BMesh *bm = me->edit_mesh->bm;
|
||||
BLI_assert(vert_coords_len == bm->totvert);
|
||||
EditMeshData *edit_data = me->runtime.edit_data;
|
||||
EditMeshData *edit_data = me->runtime->edit_data;
|
||||
if (edit_data->vertexCos != nullptr) {
|
||||
for (int i = 0; i < vert_coords_len; i++) {
|
||||
mul_v3_m4v3(vert_coords[i], mat, edit_data->vertexCos[i]);
|
||||
|
@ -253,7 +253,7 @@ void BKE_mesh_wrapper_vert_coords_copy_with_mat4(const Mesh *me,
|
|||
|
||||
int BKE_mesh_wrapper_vert_len(const Mesh *me)
|
||||
{
|
||||
switch ((eMeshWrapperType)me->runtime.wrapper_type) {
|
||||
switch (me->runtime->wrapper_type) {
|
||||
case ME_WRAPPER_TYPE_BMESH:
|
||||
return me->edit_mesh->bm->totvert;
|
||||
case ME_WRAPPER_TYPE_MDATA:
|
||||
|
@ -266,7 +266,7 @@ int BKE_mesh_wrapper_vert_len(const Mesh *me)
|
|||
|
||||
int BKE_mesh_wrapper_edge_len(const Mesh *me)
|
||||
{
|
||||
switch ((eMeshWrapperType)me->runtime.wrapper_type) {
|
||||
switch (me->runtime->wrapper_type) {
|
||||
case ME_WRAPPER_TYPE_BMESH:
|
||||
return me->edit_mesh->bm->totedge;
|
||||
case ME_WRAPPER_TYPE_MDATA:
|
||||
|
@ -279,7 +279,7 @@ int BKE_mesh_wrapper_edge_len(const Mesh *me)
|
|||
|
||||
int BKE_mesh_wrapper_loop_len(const Mesh *me)
|
||||
{
|
||||
switch ((eMeshWrapperType)me->runtime.wrapper_type) {
|
||||
switch (me->runtime->wrapper_type) {
|
||||
case ME_WRAPPER_TYPE_BMESH:
|
||||
return me->edit_mesh->bm->totloop;
|
||||
case ME_WRAPPER_TYPE_MDATA:
|
||||
|
@ -292,7 +292,7 @@ int BKE_mesh_wrapper_loop_len(const Mesh *me)
|
|||
|
||||
int BKE_mesh_wrapper_poly_len(const Mesh *me)
|
||||
{
|
||||
switch ((eMeshWrapperType)me->runtime.wrapper_type) {
|
||||
switch (me->runtime->wrapper_type) {
|
||||
case ME_WRAPPER_TYPE_BMESH:
|
||||
return me->edit_mesh->bm->totface;
|
||||
case ME_WRAPPER_TYPE_MDATA:
|
||||
|
@ -311,7 +311,7 @@ int BKE_mesh_wrapper_poly_len(const Mesh *me)
|
|||
|
||||
static Mesh *mesh_wrapper_ensure_subdivision(Mesh *me)
|
||||
{
|
||||
SubsurfRuntimeData *runtime_data = (SubsurfRuntimeData *)me->runtime.subsurf_runtime_data;
|
||||
SubsurfRuntimeData *runtime_data = (SubsurfRuntimeData *)me->runtime->subsurf_runtime_data;
|
||||
if (runtime_data == nullptr || runtime_data->settings.level == 0) {
|
||||
return me;
|
||||
}
|
||||
|
@ -359,24 +359,24 @@ static Mesh *mesh_wrapper_ensure_subdivision(Mesh *me)
|
|||
}
|
||||
|
||||
if (subdiv_mesh != me) {
|
||||
if (me->runtime.mesh_eval != nullptr) {
|
||||
BKE_id_free(nullptr, me->runtime.mesh_eval);
|
||||
if (me->runtime->mesh_eval != nullptr) {
|
||||
BKE_id_free(nullptr, me->runtime->mesh_eval);
|
||||
}
|
||||
me->runtime.mesh_eval = subdiv_mesh;
|
||||
me->runtime.wrapper_type = ME_WRAPPER_TYPE_SUBD;
|
||||
me->runtime->mesh_eval = subdiv_mesh;
|
||||
me->runtime->wrapper_type = ME_WRAPPER_TYPE_SUBD;
|
||||
}
|
||||
|
||||
return me->runtime.mesh_eval;
|
||||
return me->runtime->mesh_eval;
|
||||
}
|
||||
|
||||
Mesh *BKE_mesh_wrapper_ensure_subdivision(Mesh *me)
|
||||
{
|
||||
ThreadMutex *mesh_eval_mutex = (ThreadMutex *)me->runtime.eval_mutex;
|
||||
ThreadMutex *mesh_eval_mutex = (ThreadMutex *)me->runtime->eval_mutex;
|
||||
BLI_mutex_lock(mesh_eval_mutex);
|
||||
|
||||
if (me->runtime.wrapper_type == ME_WRAPPER_TYPE_SUBD) {
|
||||
if (me->runtime->wrapper_type == ME_WRAPPER_TYPE_SUBD) {
|
||||
BLI_mutex_unlock(mesh_eval_mutex);
|
||||
return me->runtime.mesh_eval;
|
||||
return me->runtime->mesh_eval;
|
||||
}
|
||||
|
||||
Mesh *result;
|
||||
|
|
|
@ -963,9 +963,9 @@ void BKE_modifier_path_init(char *path, int path_maxlen, const char *name)
|
|||
*/
|
||||
static void modwrap_dependsOnNormals(Mesh *me)
|
||||
{
|
||||
switch ((eMeshWrapperType)me->runtime.wrapper_type) {
|
||||
switch (me->runtime->wrapper_type) {
|
||||
case ME_WRAPPER_TYPE_BMESH: {
|
||||
EditMeshData *edit_data = me->runtime.edit_data;
|
||||
EditMeshData *edit_data = me->runtime->edit_data;
|
||||
if (edit_data->vertexCos) {
|
||||
/* Note that 'ensure' is acceptable here since these values aren't modified in-place.
|
||||
* If that changes we'll need to recalculate. */
|
||||
|
@ -993,7 +993,7 @@ struct Mesh *BKE_modifier_modify_mesh(ModifierData *md,
|
|||
{
|
||||
const ModifierTypeInfo *mti = BKE_modifier_get_info(ModifierType(md->type));
|
||||
|
||||
if (me->runtime.wrapper_type == ME_WRAPPER_TYPE_BMESH) {
|
||||
if (me->runtime->wrapper_type == ME_WRAPPER_TYPE_BMESH) {
|
||||
if ((mti->flags & eModifierTypeFlag_AcceptsBMesh) == 0) {
|
||||
BKE_mesh_wrapper_ensure_mdata(me);
|
||||
}
|
||||
|
|
|
@ -397,7 +397,7 @@ void multires_mark_as_modified(Depsgraph *depsgraph, Object *object, MultiresMod
|
|||
* In a longer term maybe special dependency graph tag can help sanitizing this a bit. */
|
||||
Object *object_eval = DEG_get_evaluated_object(depsgraph, object);
|
||||
Mesh *mesh = static_cast<Mesh *>(object_eval->data);
|
||||
SubdivCCG *subdiv_ccg = mesh->runtime.subdiv_ccg;
|
||||
SubdivCCG *subdiv_ccg = mesh->runtime->subdiv_ccg;
|
||||
if (subdiv_ccg == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -1691,7 +1691,7 @@ static void object_update_from_subsurf_ccg(Object *object)
|
|||
if (mesh_eval == nullptr) {
|
||||
return;
|
||||
}
|
||||
SubdivCCG *subdiv_ccg = mesh_eval->runtime.subdiv_ccg;
|
||||
SubdivCCG *subdiv_ccg = mesh_eval->runtime->subdiv_ccg;
|
||||
if (subdiv_ccg == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
@ -1699,7 +1699,7 @@ static void object_update_from_subsurf_ccg(Object *object)
|
|||
if (!subdiv_ccg->dirty.coords && !subdiv_ccg->dirty.hidden) {
|
||||
return;
|
||||
}
|
||||
const int tot_level = mesh_eval->runtime.subdiv_ccg_tot_level;
|
||||
const int tot_level = mesh_eval->runtime->subdiv_ccg_tot_level;
|
||||
Object *object_orig = DEG_get_original_object(object);
|
||||
Mesh *mesh_orig = (Mesh *)object_orig->data;
|
||||
multiresModifier_reshapeFromCCG(tot_level, mesh_orig, subdiv_ccg);
|
||||
|
@ -3218,7 +3218,7 @@ static void give_parvert(Object *par, int nr, float vec[3])
|
|||
int count = 0;
|
||||
int numVerts = me_eval->totvert;
|
||||
|
||||
if (em && me_eval->runtime.wrapper_type == ME_WRAPPER_TYPE_BMESH) {
|
||||
if (em && me_eval->runtime->wrapper_type == ME_WRAPPER_TYPE_BMESH) {
|
||||
numVerts = em->bm->totvert;
|
||||
if (em->bm->elem_table_dirty & BM_VERT) {
|
||||
#ifdef VPARENT_THREADING_HACK
|
||||
|
@ -3233,8 +3233,8 @@ static void give_parvert(Object *par, int nr, float vec[3])
|
|||
#endif
|
||||
}
|
||||
if (nr < numVerts) {
|
||||
if (me_eval && me_eval->runtime.edit_data && me_eval->runtime.edit_data->vertexCos) {
|
||||
add_v3_v3(vec, me_eval->runtime.edit_data->vertexCos[nr]);
|
||||
if (me_eval && me_eval->runtime->edit_data && me_eval->runtime->edit_data->vertexCos) {
|
||||
add_v3_v3(vec, me_eval->runtime->edit_data->vertexCos[nr]);
|
||||
}
|
||||
else {
|
||||
const BMVert *v = BM_vert_at_index(em->bm, nr);
|
||||
|
|
|
@ -423,8 +423,8 @@ static const Mesh *mesh_data_from_duplicator_object(Object *ob,
|
|||
/* Note that this will only show deformation if #eModifierMode_OnCage is enabled.
|
||||
* We could change this but it matches 2.7x behavior. */
|
||||
me_eval = BKE_object_get_editmesh_eval_cage(ob);
|
||||
if ((me_eval == nullptr) || (me_eval->runtime.wrapper_type == ME_WRAPPER_TYPE_BMESH)) {
|
||||
EditMeshData *emd = me_eval ? me_eval->runtime.edit_data : nullptr;
|
||||
if ((me_eval == nullptr) || (me_eval->runtime->wrapper_type == ME_WRAPPER_TYPE_BMESH)) {
|
||||
EditMeshData *emd = me_eval ? me_eval->runtime->edit_data : nullptr;
|
||||
|
||||
/* Only assign edit-mesh in the case we can't use `me_eval`. */
|
||||
*r_em = em;
|
||||
|
|
|
@ -373,7 +373,7 @@ void BKE_object_select_update(Depsgraph *depsgraph, Object *object)
|
|||
DEG_debug_print_eval(depsgraph, __func__, object->id.name, object);
|
||||
if (object->type == OB_MESH && !object->runtime.is_data_eval_owned) {
|
||||
Mesh *mesh_input = (Mesh *)object->runtime.data_orig;
|
||||
Mesh_Runtime *mesh_runtime = &mesh_input->runtime;
|
||||
blender::bke::MeshRuntime *mesh_runtime = mesh_input->runtime;
|
||||
BLI_mutex_lock(static_cast<ThreadMutex *>(mesh_runtime->eval_mutex));
|
||||
BKE_object_data_select_update(depsgraph, static_cast<ID *>(object->data));
|
||||
BLI_mutex_unlock(static_cast<ThreadMutex *>(mesh_runtime->eval_mutex));
|
||||
|
|
|
@ -1743,7 +1743,7 @@ static void sculpt_update_object(
|
|||
|
||||
ss->hide_poly = (bool *)CustomData_get_layer_named(&me->pdata, CD_PROP_BOOL, ".hide_poly");
|
||||
|
||||
ss->subdiv_ccg = me_eval->runtime.subdiv_ccg;
|
||||
ss->subdiv_ccg = me_eval->runtime->subdiv_ccg;
|
||||
|
||||
PBVH *pbvh = BKE_sculpt_object_pbvh_ensure(depsgraph, ob);
|
||||
BLI_assert(pbvh == ss->pbvh);
|
||||
|
@ -2258,7 +2258,7 @@ PBVH *BKE_sculpt_object_pbvh_ensure(Depsgraph *depsgraph, Object *ob)
|
|||
if (BKE_pbvh_type(pbvh) == PBVH_GRIDS) {
|
||||
Object *object_eval = DEG_get_evaluated_object(depsgraph, ob);
|
||||
Mesh *mesh_eval = static_cast<Mesh *>(object_eval->data);
|
||||
SubdivCCG *subdiv_ccg = mesh_eval->runtime.subdiv_ccg;
|
||||
SubdivCCG *subdiv_ccg = mesh_eval->runtime->subdiv_ccg;
|
||||
if (subdiv_ccg != nullptr) {
|
||||
BKE_sculpt_bvh_update_from_ccg(pbvh, subdiv_ccg);
|
||||
}
|
||||
|
@ -2277,8 +2277,8 @@ PBVH *BKE_sculpt_object_pbvh_ensure(Depsgraph *depsgraph, Object *ob)
|
|||
else {
|
||||
Object *object_eval = DEG_get_evaluated_object(depsgraph, ob);
|
||||
Mesh *mesh_eval = static_cast<Mesh *>(object_eval->data);
|
||||
if (mesh_eval->runtime.subdiv_ccg != nullptr) {
|
||||
pbvh = build_pbvh_from_ccg(ob, mesh_eval->runtime.subdiv_ccg, respect_hide);
|
||||
if (mesh_eval->runtime->subdiv_ccg != nullptr) {
|
||||
pbvh = build_pbvh_from_ccg(ob, mesh_eval->runtime->subdiv_ccg, respect_hide);
|
||||
}
|
||||
else if (ob->type == OB_MESH) {
|
||||
Mesh *me_eval_deform = object_eval->runtime.mesh_deform_eval;
|
||||
|
|
|
@ -60,6 +60,7 @@
|
|||
#include "BKE_material.h"
|
||||
#include "BKE_mesh.h"
|
||||
#include "BKE_mesh_legacy_convert.h"
|
||||
#include "BKE_mesh_runtime.h"
|
||||
#include "BKE_modifier.h"
|
||||
#include "BKE_object.h"
|
||||
#include "BKE_particle.h"
|
||||
|
@ -1933,7 +1934,7 @@ int psys_particle_dm_face_lookup(Mesh *mesh_final,
|
|||
index_mf_to_mpoly_deformed = CustomData_get_layer(&mesh_original->fdata, CD_ORIGINDEX);
|
||||
}
|
||||
else {
|
||||
BLI_assert(mesh_final->runtime.deformed_only);
|
||||
BLI_assert(BKE_mesh_is_deformed_only(mesh_final));
|
||||
index_mf_to_mpoly_deformed = index_mf_to_mpoly;
|
||||
}
|
||||
BLI_assert(index_mf_to_mpoly_deformed);
|
||||
|
@ -2023,7 +2024,7 @@ static int psys_map_index_on_dm(Mesh *mesh,
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (mesh->runtime.deformed_only || index_dmcache == DMCACHE_ISCHILD) {
|
||||
if (BKE_mesh_is_deformed_only(mesh) || index_dmcache == DMCACHE_ISCHILD) {
|
||||
/* for meshes that are either only deformed or for child particles, the
|
||||
* index and fw do not require any mapping, so we can directly use it */
|
||||
if (from == PART_FROM_VERT) {
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include "BKE_lib_id.h"
|
||||
#include "BKE_mesh.h"
|
||||
#include "BKE_mesh_legacy_convert.h"
|
||||
#include "BKE_mesh_runtime.h"
|
||||
#include "BKE_object.h"
|
||||
#include "BKE_particle.h"
|
||||
|
||||
|
@ -899,7 +900,7 @@ static int psys_thread_context_init_distribute(ParticleThreadContext *ctx,
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (!final_mesh->runtime.deformed_only &&
|
||||
if (!BKE_mesh_is_deformed_only(final_mesh) &&
|
||||
!CustomData_get_layer(&final_mesh->fdata, CD_ORIGINDEX)) {
|
||||
printf(
|
||||
"Can't create particles with the current modifier stack, disable destructive modifiers\n");
|
||||
|
|
|
@ -48,6 +48,7 @@
|
|||
#include "BKE_lib_id.h"
|
||||
#include "BKE_lib_query.h"
|
||||
#include "BKE_mesh_legacy_convert.h"
|
||||
#include "BKE_mesh_runtime.h"
|
||||
#include "BKE_particle.h"
|
||||
|
||||
#include "BKE_bvhutils.h"
|
||||
|
@ -319,7 +320,7 @@ void psys_calc_dmcache(Object *ob, Mesh *mesh_final, Mesh *mesh_original, Partic
|
|||
PARTICLE_P;
|
||||
|
||||
/* CACHE LOCATIONS */
|
||||
if (!mesh_final->runtime.deformed_only) {
|
||||
if (!BKE_mesh_is_deformed_only(mesh_final)) {
|
||||
/* Will use later to speed up subsurf/evaluated mesh. */
|
||||
LinkNode *node, *nodedmelem, **nodearray;
|
||||
int totdmelem, totelem, i;
|
||||
|
|
|
@ -404,7 +404,7 @@ static rbCollisionShape *rigidbody_get_shape_trimesh_from_mesh(Object *ob)
|
|||
const MVert *mvert = BKE_mesh_verts(mesh);
|
||||
totvert = mesh->totvert;
|
||||
looptri = BKE_mesh_runtime_looptri_ensure(mesh);
|
||||
tottri = mesh->runtime.looptris.len;
|
||||
tottri = BKE_mesh_runtime_looptri_len(mesh);
|
||||
const MLoop *mloop = BKE_mesh_loops(mesh);
|
||||
|
||||
/* sanity checking - potential case when no data will be present */
|
||||
|
@ -679,7 +679,7 @@ void BKE_rigidbody_calc_volume(Object *ob, float *r_vol)
|
|||
const MVert *mvert = BKE_mesh_verts(mesh);
|
||||
totvert = mesh->totvert;
|
||||
lt = BKE_mesh_runtime_looptri_ensure(mesh);
|
||||
tottri = mesh->runtime.looptris.len;
|
||||
tottri = BKE_mesh_runtime_looptri_len(mesh);
|
||||
const MLoop *mloop = BKE_mesh_loops(mesh);
|
||||
|
||||
if (totvert > 0 && tottri > 0) {
|
||||
|
@ -753,7 +753,7 @@ void BKE_rigidbody_calc_center_of_mass(Object *ob, float r_center[3])
|
|||
const MVert *mvert = BKE_mesh_verts(mesh);
|
||||
totvert = mesh->totvert;
|
||||
looptri = BKE_mesh_runtime_looptri_ensure(mesh);
|
||||
tottri = mesh->runtime.looptris.len;
|
||||
tottri = BKE_mesh_runtime_looptri_len(mesh);
|
||||
const MLoop *mloop = BKE_mesh_loops(mesh);
|
||||
|
||||
if (totvert > 0 && tottri > 0) {
|
||||
|
|
|
@ -140,7 +140,7 @@ bool BKE_shrinkwrap_init_tree(
|
|||
}
|
||||
|
||||
if (shrinkType == MOD_SHRINKWRAP_TARGET_PROJECT) {
|
||||
data->boundary = mesh->runtime.shrinkwrap_data;
|
||||
data->boundary = mesh->runtime->shrinkwrap_data;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -153,7 +153,7 @@ void BKE_shrinkwrap_free_tree(ShrinkwrapTreeData *data)
|
|||
|
||||
void BKE_shrinkwrap_discard_boundary_data(Mesh *mesh)
|
||||
{
|
||||
ShrinkwrapBoundaryData *data = mesh->runtime.shrinkwrap_data;
|
||||
ShrinkwrapBoundaryData *data = mesh->runtime->shrinkwrap_data;
|
||||
|
||||
if (data != nullptr) {
|
||||
MEM_freeN((void *)data->edge_is_boundary);
|
||||
|
@ -164,7 +164,7 @@ void BKE_shrinkwrap_discard_boundary_data(Mesh *mesh)
|
|||
MEM_freeN(data);
|
||||
}
|
||||
|
||||
mesh->runtime.shrinkwrap_data = nullptr;
|
||||
mesh->runtime->shrinkwrap_data = nullptr;
|
||||
}
|
||||
|
||||
/* Accumulate edge for average boundary edge direction. */
|
||||
|
@ -327,7 +327,7 @@ void BKE_shrinkwrap_compute_boundary_data(Mesh *mesh)
|
|||
{
|
||||
BKE_shrinkwrap_discard_boundary_data(mesh);
|
||||
|
||||
mesh->runtime.shrinkwrap_data = shrinkwrap_build_boundary_data(mesh);
|
||||
mesh->runtime->shrinkwrap_data = shrinkwrap_build_boundary_data(mesh);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -615,7 +615,7 @@ Mesh *BKE_subdiv_to_ccg_mesh(Subdiv *subdiv,
|
|||
return nullptr;
|
||||
}
|
||||
Mesh *result = BKE_mesh_new_nomain_from_template(coarse_mesh, 0, 0, 0, 0, 0);
|
||||
result->runtime.subdiv_ccg = subdiv_ccg;
|
||||
result->runtime->subdiv_ccg = subdiv_ccg;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
@ -528,9 +528,9 @@ static bool subdiv_mesh_topology_info(const SubdivForeachContext *foreach_contex
|
|||
subdiv_context->coarse_mesh, num_vertices, num_edges, 0, num_loops, num_polygons, mask);
|
||||
subdiv_mesh_ctx_cache_custom_data_layers(subdiv_context);
|
||||
subdiv_mesh_prepare_accumulator(subdiv_context, num_vertices);
|
||||
MEM_SAFE_FREE(subdiv_context->subdiv_mesh->runtime.subsurf_face_dot_tags);
|
||||
subdiv_context->subdiv_mesh->runtime.subsurf_face_dot_tags = BLI_BITMAP_NEW(num_vertices,
|
||||
__func__);
|
||||
MEM_SAFE_FREE(subdiv_context->subdiv_mesh->runtime->subsurf_face_dot_tags);
|
||||
subdiv_context->subdiv_mesh->runtime->subsurf_face_dot_tags = BLI_BITMAP_NEW(num_vertices,
|
||||
__func__);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -595,7 +595,7 @@ static void evaluate_vertex_and_apply_displacement_copy(const SubdivMeshContext
|
|||
/* Evaluate undeformed texture coordinate. */
|
||||
subdiv_vertex_orco_evaluate(ctx, ptex_face_index, u, v, subdiv_vertex_index);
|
||||
/* Remove face-dot flag. This can happen if there is more than one subsurf modifier. */
|
||||
BLI_BITMAP_DISABLE(ctx->subdiv_mesh->runtime.subsurf_face_dot_tags, subdiv_vertex_index);
|
||||
BLI_BITMAP_DISABLE(ctx->subdiv_mesh->runtime->subsurf_face_dot_tags, subdiv_vertex_index);
|
||||
}
|
||||
|
||||
static void evaluate_vertex_and_apply_displacement_interpolate(
|
||||
|
@ -753,7 +753,7 @@ static void subdiv_mesh_tag_center_vertex(const MPoly *coarse_poly,
|
|||
Mesh *subdiv_mesh)
|
||||
{
|
||||
if (subdiv_mesh_is_center_vertex(coarse_poly, u, v)) {
|
||||
BLI_BITMAP_ENABLE(subdiv_mesh->runtime.subsurf_face_dot_tags, subdiv_vertex_index);
|
||||
BLI_BITMAP_ENABLE(subdiv_mesh->runtime->subsurf_face_dot_tags, subdiv_vertex_index);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include "DNA_scene_types.h"
|
||||
#include "DNA_userdef_types.h"
|
||||
|
||||
#include "BKE_mesh.h"
|
||||
#include "BKE_modifier.h"
|
||||
#include "BKE_subdiv.h"
|
||||
|
||||
|
@ -143,7 +144,7 @@ bool BKE_subsurf_modifier_can_do_gpu_subdiv(const Scene *scene,
|
|||
|
||||
bool BKE_subsurf_modifier_has_gpu_subdiv(const Mesh *mesh)
|
||||
{
|
||||
SubsurfRuntimeData *runtime_data = mesh->runtime.subsurf_runtime_data;
|
||||
SubsurfRuntimeData *runtime_data = mesh->runtime->subsurf_runtime_data;
|
||||
return runtime_data && runtime_data->has_gpu_subdiv;
|
||||
}
|
||||
|
||||
|
|
|
@ -1238,7 +1238,7 @@ void BM_mesh_bm_to_me_for_eval(BMesh *bm, Mesh *me, const CustomData_MeshMasks *
|
|||
* different than the BMesh's. */
|
||||
BKE_mesh_clear_derived_normals(me);
|
||||
|
||||
me->runtime.deformed_only = true;
|
||||
me->runtime->deformed_only = true;
|
||||
|
||||
bke::MutableAttributeAccessor mesh_attributes = me->attributes_for_write();
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include "BLI_alloca.h"
|
||||
|
||||
#include "BKE_editmesh.h"
|
||||
#include "BKE_mesh_runtime.h"
|
||||
#include "BKE_modifier.h"
|
||||
#include "BKE_object.h"
|
||||
#include "BKE_paint.h"
|
||||
|
@ -231,7 +232,7 @@ static void workbench_cache_hair_populate(WORKBENCH_PrivateData *wpd,
|
|||
|
||||
static const CustomData *workbench_mesh_get_loop_custom_data(const Mesh *mesh)
|
||||
{
|
||||
if (mesh->runtime.wrapper_type == ME_WRAPPER_TYPE_BMESH) {
|
||||
if (BKE_mesh_wrapper_type(mesh) == ME_WRAPPER_TYPE_BMESH) {
|
||||
BLI_assert(mesh->edit_mesh != NULL);
|
||||
BLI_assert(mesh->edit_mesh->bm != NULL);
|
||||
return &mesh->edit_mesh->bm->ldata;
|
||||
|
@ -241,7 +242,7 @@ static const CustomData *workbench_mesh_get_loop_custom_data(const Mesh *mesh)
|
|||
|
||||
static const CustomData *workbench_mesh_get_vert_custom_data(const Mesh *mesh)
|
||||
{
|
||||
if (mesh->runtime.wrapper_type == ME_WRAPPER_TYPE_BMESH) {
|
||||
if (BKE_mesh_wrapper_type(mesh) == ME_WRAPPER_TYPE_BMESH) {
|
||||
BLI_assert(mesh->edit_mesh != NULL);
|
||||
BLI_assert(mesh->edit_mesh->bm != NULL);
|
||||
return &mesh->edit_mesh->bm->vdata;
|
||||
|
|
|
@ -686,7 +686,7 @@ void mesh_buffer_cache_create_requested(struct TaskGraph *task_graph,
|
|||
MeshRenderData *mr = mesh_render_data_create(
|
||||
object, me, is_editmode, is_paint_mode, is_mode_active, obmat, do_final, do_uvedit, ts);
|
||||
mr->use_hide = use_hide;
|
||||
mr->use_subsurf_fdots = mr->me && mr->me->runtime.subsurf_face_dot_tags != nullptr;
|
||||
mr->use_subsurf_fdots = mr->me && mr->me->runtime->subsurf_face_dot_tags != nullptr;
|
||||
mr->use_final_mesh = do_final;
|
||||
|
||||
#ifdef DEBUG_TIME
|
||||
|
|
|
@ -463,7 +463,7 @@ MeshRenderData *mesh_render_data_create(Object *object,
|
|||
mr->bm = me->edit_mesh->bm;
|
||||
mr->edit_bmesh = me->edit_mesh;
|
||||
mr->me = (do_final) ? editmesh_eval_final : editmesh_eval_cage;
|
||||
mr->edit_data = is_mode_active ? mr->me->runtime.edit_data : nullptr;
|
||||
mr->edit_data = is_mode_active ? mr->me->runtime->edit_data : nullptr;
|
||||
|
||||
if (mr->edit_data) {
|
||||
EditMeshData *emd = mr->edit_data;
|
||||
|
@ -499,8 +499,8 @@ MeshRenderData *mesh_render_data_create(Object *object,
|
|||
/* Use bmesh directly when the object is in edit mode unchanged by any modifiers.
|
||||
* For non-final UVs, always use original bmesh since the UV editor does not support
|
||||
* using the cage mesh with deformed coordinates. */
|
||||
if ((is_mode_active && mr->me->runtime.is_original_bmesh &&
|
||||
mr->me->runtime.wrapper_type == ME_WRAPPER_TYPE_BMESH) ||
|
||||
if ((is_mode_active && mr->me->runtime->is_original_bmesh &&
|
||||
mr->me->runtime->wrapper_type == ME_WRAPPER_TYPE_BMESH) ||
|
||||
(do_uvedit && !do_final)) {
|
||||
mr->extract_type = MR_EXTRACT_BMESH;
|
||||
}
|
||||
|
|
|
@ -554,7 +554,7 @@ BLI_INLINE void mesh_batch_cache_add_request(MeshBatchCache *cache, DRWBatchFlag
|
|||
|
||||
static bool mesh_batch_cache_valid(Object *object, Mesh *me)
|
||||
{
|
||||
MeshBatchCache *cache = static_cast<MeshBatchCache *>(me->runtime.batch_cache);
|
||||
MeshBatchCache *cache = static_cast<MeshBatchCache *>(me->runtime->batch_cache);
|
||||
|
||||
if (cache == nullptr) {
|
||||
return false;
|
||||
|
@ -588,11 +588,11 @@ static bool mesh_batch_cache_valid(Object *object, Mesh *me)
|
|||
|
||||
static void mesh_batch_cache_init(Object *object, Mesh *me)
|
||||
{
|
||||
MeshBatchCache *cache = static_cast<MeshBatchCache *>(me->runtime.batch_cache);
|
||||
MeshBatchCache *cache = static_cast<MeshBatchCache *>(me->runtime->batch_cache);
|
||||
|
||||
if (!cache) {
|
||||
me->runtime.batch_cache = MEM_cnew<MeshBatchCache>(__func__);
|
||||
cache = static_cast<MeshBatchCache *>(me->runtime.batch_cache);
|
||||
me->runtime->batch_cache = MEM_cnew<MeshBatchCache>(__func__);
|
||||
cache = static_cast<MeshBatchCache *>(me->runtime->batch_cache);
|
||||
}
|
||||
else {
|
||||
memset(cache, 0, sizeof(*cache));
|
||||
|
@ -634,7 +634,7 @@ void DRW_mesh_batch_cache_validate(Object *object, Mesh *me)
|
|||
|
||||
static MeshBatchCache *mesh_batch_cache_get(Mesh *me)
|
||||
{
|
||||
return static_cast<MeshBatchCache *>(me->runtime.batch_cache);
|
||||
return static_cast<MeshBatchCache *>(me->runtime->batch_cache);
|
||||
}
|
||||
|
||||
static void mesh_batch_cache_check_vertex_group(MeshBatchCache *cache,
|
||||
|
@ -742,7 +742,7 @@ static void mesh_batch_cache_discard_uvedit_select(MeshBatchCache *cache)
|
|||
|
||||
void DRW_mesh_batch_cache_dirty_tag(Mesh *me, eMeshBatchDirtyMode mode)
|
||||
{
|
||||
MeshBatchCache *cache = static_cast<MeshBatchCache *>(me->runtime.batch_cache);
|
||||
MeshBatchCache *cache = static_cast<MeshBatchCache *>(me->runtime->batch_cache);
|
||||
if (cache == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
@ -830,7 +830,7 @@ static void mesh_batch_cache_free_subdiv_cache(MeshBatchCache *cache)
|
|||
|
||||
static void mesh_batch_cache_clear(Mesh *me)
|
||||
{
|
||||
MeshBatchCache *cache = static_cast<MeshBatchCache *>(me->runtime.batch_cache);
|
||||
MeshBatchCache *cache = static_cast<MeshBatchCache *>(me->runtime->batch_cache);
|
||||
if (!cache) {
|
||||
return;
|
||||
}
|
||||
|
@ -862,7 +862,7 @@ static void mesh_batch_cache_clear(Mesh *me)
|
|||
void DRW_mesh_batch_cache_free(Mesh *me)
|
||||
{
|
||||
mesh_batch_cache_clear(me);
|
||||
MEM_SAFE_FREE(me->runtime.batch_cache);
|
||||
MEM_SAFE_FREE(me->runtime->batch_cache);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
@ -1017,7 +1017,7 @@ GPUBatch **DRW_mesh_batch_cache_get_surface_shaded(Object *object,
|
|||
BLI_assert(gpumat_array_len == cache->mat_len);
|
||||
|
||||
mesh_cd_layers_type_merge(&cache->cd_needed, cd_needed);
|
||||
ThreadMutex *mesh_render_mutex = (ThreadMutex *)me->runtime.render_mutex;
|
||||
ThreadMutex *mesh_render_mutex = (ThreadMutex *)me->runtime->render_mutex;
|
||||
drw_attributes_merge(&cache->attr_needed, &attrs_needed, mesh_render_mutex);
|
||||
mesh_batch_cache_request_surface_batches(cache);
|
||||
return cache->surface_per_mat;
|
||||
|
@ -1046,7 +1046,7 @@ GPUBatch *DRW_mesh_batch_cache_get_surface_vertpaint(Object *object, Mesh *me)
|
|||
DRW_Attributes attrs_needed{};
|
||||
request_active_and_default_color_attributes(*object, *me, attrs_needed);
|
||||
|
||||
ThreadMutex *mesh_render_mutex = (ThreadMutex *)me->runtime.render_mutex;
|
||||
ThreadMutex *mesh_render_mutex = (ThreadMutex *)me->runtime->render_mutex;
|
||||
drw_attributes_merge(&cache->attr_needed, &attrs_needed, mesh_render_mutex);
|
||||
|
||||
mesh_batch_cache_request_surface_batches(cache);
|
||||
|
@ -1060,7 +1060,7 @@ GPUBatch *DRW_mesh_batch_cache_get_surface_sculpt(Object *object, Mesh *me)
|
|||
DRW_Attributes attrs_needed{};
|
||||
request_active_and_default_color_attributes(*object, *me, attrs_needed);
|
||||
|
||||
ThreadMutex *mesh_render_mutex = (ThreadMutex *)me->runtime.render_mutex;
|
||||
ThreadMutex *mesh_render_mutex = (ThreadMutex *)me->runtime->render_mutex;
|
||||
drw_attributes_merge(&cache->attr_needed, &attrs_needed, mesh_render_mutex);
|
||||
|
||||
mesh_batch_cache_request_surface_batches(cache);
|
||||
|
@ -1300,7 +1300,7 @@ GPUBatch *DRW_mesh_batch_cache_get_surface_edges(Object *object, Mesh *me)
|
|||
|
||||
void DRW_mesh_batch_cache_free_old(Mesh *me, int ctime)
|
||||
{
|
||||
MeshBatchCache *cache = static_cast<MeshBatchCache *>(me->runtime.batch_cache);
|
||||
MeshBatchCache *cache = static_cast<MeshBatchCache *>(me->runtime->batch_cache);
|
||||
|
||||
if (cache == nullptr) {
|
||||
return;
|
||||
|
@ -1446,7 +1446,7 @@ void DRW_mesh_batch_cache_create_requested(struct TaskGraph *task_graph,
|
|||
}
|
||||
}
|
||||
|
||||
ThreadMutex *mesh_render_mutex = (ThreadMutex *)me->runtime.render_mutex;
|
||||
ThreadMutex *mesh_render_mutex = (ThreadMutex *)me->runtime->render_mutex;
|
||||
|
||||
/* Verify that all surface batches have needed attribute layers.
|
||||
*/
|
||||
|
@ -1537,7 +1537,7 @@ void DRW_mesh_batch_cache_create_requested(struct TaskGraph *task_graph,
|
|||
const bool do_update_sculpt_normals = ob->sculpt && ob->sculpt->pbvh;
|
||||
if (do_update_sculpt_normals) {
|
||||
Mesh *mesh = static_cast<Mesh *>(ob->data);
|
||||
BKE_pbvh_update_normals(ob->sculpt->pbvh, mesh->runtime.subdiv_ccg);
|
||||
BKE_pbvh_update_normals(ob->sculpt->pbvh, mesh->runtime->subdiv_ccg);
|
||||
}
|
||||
|
||||
cache->batch_ready |= batch_requested;
|
||||
|
@ -1548,8 +1548,8 @@ void DRW_mesh_batch_cache_create_requested(struct TaskGraph *task_graph,
|
|||
Mesh *editmesh_eval_cage = BKE_object_get_editmesh_eval_cage(ob);
|
||||
|
||||
do_cage = editmesh_eval_final != editmesh_eval_cage;
|
||||
do_uvcage = !(editmesh_eval_final->runtime.is_original_bmesh &&
|
||||
editmesh_eval_final->runtime.wrapper_type == ME_WRAPPER_TYPE_BMESH);
|
||||
do_uvcage = !(editmesh_eval_final->runtime->is_original_bmesh &&
|
||||
editmesh_eval_final->runtime->wrapper_type == ME_WRAPPER_TYPE_BMESH);
|
||||
}
|
||||
|
||||
const bool do_subdivision = BKE_subsurf_modifier_has_gpu_subdiv(me);
|
||||
|
|
|
@ -2036,7 +2036,7 @@ static bool draw_subdiv_create_requested_buffers(Object *ob,
|
|||
const bool use_hide,
|
||||
OpenSubdiv_EvaluatorCache *evaluator_cache)
|
||||
{
|
||||
SubsurfRuntimeData *runtime_data = mesh->runtime.subsurf_runtime_data;
|
||||
SubsurfRuntimeData *runtime_data = mesh->runtime->subsurf_runtime_data;
|
||||
BLI_assert(runtime_data && runtime_data->has_gpu_subdiv);
|
||||
|
||||
if (runtime_data->settings.level == 0) {
|
||||
|
|
|
@ -1347,7 +1347,7 @@ static void drw_sculpt_generate_calls(DRWSculptCallbackData *scd)
|
|||
}
|
||||
|
||||
Mesh *mesh = static_cast<Mesh *>(scd->ob->data);
|
||||
BKE_pbvh_update_normals(pbvh, mesh->runtime.subdiv_ccg);
|
||||
BKE_pbvh_update_normals(pbvh, mesh->runtime->subdiv_ccg);
|
||||
|
||||
BKE_pbvh_draw_cb(pbvh,
|
||||
update_only_visible,
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include "BKE_editmesh.h"
|
||||
#include "BKE_editmesh_cache.h"
|
||||
#include "BKE_global.h"
|
||||
#include "BKE_mesh.h"
|
||||
#include "BKE_unit.h"
|
||||
|
||||
#include "DNA_mesh_types.h"
|
||||
|
@ -233,8 +234,8 @@ void DRW_text_edit_mesh_measure_stats(ARegion *region,
|
|||
float clip_planes[4][4];
|
||||
/* allow for displaying shape keys and deform mods */
|
||||
BMIter iter;
|
||||
const float(*vert_coords)[3] = (me->runtime.edit_data ? me->runtime.edit_data->vertexCos :
|
||||
nullptr);
|
||||
const float(*vert_coords)[3] = (me->runtime->edit_data ? me->runtime->edit_data->vertexCos :
|
||||
nullptr);
|
||||
const bool use_coords = (vert_coords != nullptr);
|
||||
|
||||
/* when 2 or more edge-info options are enabled, space apart */
|
||||
|
@ -339,8 +340,8 @@ void DRW_text_edit_mesh_measure_stats(ARegion *region,
|
|||
const float(*poly_normals)[3] = nullptr;
|
||||
if (use_coords) {
|
||||
BM_mesh_elem_index_ensure(em->bm, BM_VERT | BM_FACE);
|
||||
BKE_editmesh_cache_ensure_poly_normals(em, me->runtime.edit_data);
|
||||
poly_normals = me->runtime.edit_data->polyNos;
|
||||
BKE_editmesh_cache_ensure_poly_normals(em, me->runtime->edit_data);
|
||||
poly_normals = me->runtime->edit_data->polyNos;
|
||||
}
|
||||
|
||||
BM_ITER_MESH (eed, &iter, em->bm, BM_EDGES_OF_MESH) {
|
||||
|
|
|
@ -16,6 +16,8 @@
|
|||
|
||||
#include "BKE_customdata.h"
|
||||
#include "BKE_editmesh.h"
|
||||
#include "BKE_editmesh_cache.h"
|
||||
#include "BKE_mesh.h"
|
||||
|
||||
#include "draw_cache_extract.hh"
|
||||
|
||||
|
@ -116,7 +118,7 @@ BLI_INLINE const Mesh *editmesh_final_or_this(const Object *object, const Mesh *
|
|||
|
||||
BLI_INLINE const CustomData *mesh_cd_ldata_get_from_mesh(const Mesh *me)
|
||||
{
|
||||
switch ((eMeshWrapperType)me->runtime.wrapper_type) {
|
||||
switch (me->runtime->wrapper_type) {
|
||||
case ME_WRAPPER_TYPE_SUBD:
|
||||
case ME_WRAPPER_TYPE_MDATA:
|
||||
return &me->ldata;
|
||||
|
@ -132,7 +134,7 @@ BLI_INLINE const CustomData *mesh_cd_ldata_get_from_mesh(const Mesh *me)
|
|||
|
||||
BLI_INLINE const CustomData *mesh_cd_pdata_get_from_mesh(const Mesh *me)
|
||||
{
|
||||
switch ((eMeshWrapperType)me->runtime.wrapper_type) {
|
||||
switch (me->runtime->wrapper_type) {
|
||||
case ME_WRAPPER_TYPE_SUBD:
|
||||
case ME_WRAPPER_TYPE_MDATA:
|
||||
return &me->pdata;
|
||||
|
@ -148,7 +150,7 @@ BLI_INLINE const CustomData *mesh_cd_pdata_get_from_mesh(const Mesh *me)
|
|||
|
||||
BLI_INLINE const CustomData *mesh_cd_edata_get_from_mesh(const Mesh *me)
|
||||
{
|
||||
switch ((eMeshWrapperType)me->runtime.wrapper_type) {
|
||||
switch (me->runtime->wrapper_type) {
|
||||
case ME_WRAPPER_TYPE_SUBD:
|
||||
case ME_WRAPPER_TYPE_MDATA:
|
||||
return &me->edata;
|
||||
|
@ -164,7 +166,7 @@ BLI_INLINE const CustomData *mesh_cd_edata_get_from_mesh(const Mesh *me)
|
|||
|
||||
BLI_INLINE const CustomData *mesh_cd_vdata_get_from_mesh(const Mesh *me)
|
||||
{
|
||||
switch ((eMeshWrapperType)me->runtime.wrapper_type) {
|
||||
switch (me->runtime->wrapper_type) {
|
||||
case ME_WRAPPER_TYPE_SUBD:
|
||||
case ME_WRAPPER_TYPE_MDATA:
|
||||
return &me->vdata;
|
||||
|
|
|
@ -557,7 +557,7 @@ static void extract_edituv_fdots_iter_poly_mesh(const MeshRenderData *mr,
|
|||
const bool mp_select = (efa) ? BM_elem_flag_test_bool(efa, BM_ELEM_SELECT) : false;
|
||||
|
||||
if (mr->use_subsurf_fdots) {
|
||||
const BLI_bitmap *facedot_tags = mr->me->runtime.subsurf_face_dot_tags;
|
||||
const BLI_bitmap *facedot_tags = mr->me->runtime->subsurf_face_dot_tags;
|
||||
|
||||
const MLoop *mloop = mr->mloop;
|
||||
const int ml_index_end = mp->loopstart + mp->totloop;
|
||||
|
|
|
@ -46,7 +46,7 @@ static void extract_fdots_iter_poly_mesh(const MeshRenderData *mr,
|
|||
|
||||
GPUIndexBufBuilder *elb = static_cast<GPUIndexBufBuilder *>(_userdata);
|
||||
if (mr->use_subsurf_fdots) {
|
||||
const BLI_bitmap *facedot_tags = mr->me->runtime.subsurf_face_dot_tags;
|
||||
const BLI_bitmap *facedot_tags = mr->me->runtime->subsurf_face_dot_tags;
|
||||
|
||||
const MLoop *mloop = mr->mloop;
|
||||
const int ml_index_end = mp->loopstart + mp->totloop;
|
||||
|
|
|
@ -77,7 +77,7 @@ static void extract_fdots_pos_iter_poly_mesh(const MeshRenderData *mr,
|
|||
|
||||
const MVert *mvert = mr->mvert;
|
||||
const MLoop *mloop = mr->mloop;
|
||||
const BLI_bitmap *facedot_tags = mr->me->runtime.subsurf_face_dot_tags;
|
||||
const BLI_bitmap *facedot_tags = mr->me->runtime->subsurf_face_dot_tags;
|
||||
|
||||
const int ml_index_end = mp->loopstart + mp->totloop;
|
||||
for (int ml_index = mp->loopstart; ml_index < ml_index_end; ml_index += 1) {
|
||||
|
|
|
@ -74,7 +74,7 @@ static void extract_fdots_uv_iter_poly_mesh(const MeshRenderData *mr,
|
|||
void *_data)
|
||||
{
|
||||
MeshExtract_FdotUV_Data *data = static_cast<MeshExtract_FdotUV_Data *>(_data);
|
||||
const BLI_bitmap *facedot_tags = mr->me->runtime.subsurf_face_dot_tags;
|
||||
const BLI_bitmap *facedot_tags = mr->me->runtime->subsurf_face_dot_tags;
|
||||
|
||||
const MLoop *mloop = mr->mloop;
|
||||
const int ml_index_end = mp->loopstart + mp->totloop;
|
||||
|
|
|
@ -22,7 +22,9 @@
|
|||
#include "BKE_customdata.h"
|
||||
#include "BKE_deform.h"
|
||||
#include "BKE_editmesh.h"
|
||||
#include "BKE_editmesh_cache.h"
|
||||
#include "BKE_layer.h"
|
||||
#include "BKE_mesh.h"
|
||||
#include "BKE_report.h"
|
||||
|
||||
#include "WM_api.h"
|
||||
|
@ -1065,8 +1067,8 @@ bool EDBM_unified_findnearest_from_raycast(ViewContext *vc,
|
|||
{
|
||||
Mesh *me_eval = (Mesh *)DEG_get_evaluated_id(vc->depsgraph,
|
||||
static_cast<ID *>(obedit->data));
|
||||
if (me_eval->runtime.edit_data) {
|
||||
coords = me_eval->runtime.edit_data->vertexCos;
|
||||
if (me_eval->runtime->edit_data) {
|
||||
coords = me_eval->runtime->edit_data->vertexCos;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -597,6 +597,11 @@ static void *undomesh_from_editmesh(UndoMesh *um, BMEditMesh *em, Key *key, Undo
|
|||
* on it. Necessary to use the attribute API. */
|
||||
strcpy(um->me.id.name, "MEundomesh_from_editmesh");
|
||||
|
||||
/* Runtime data is necessary for some asserts in other code, and the overhead of creating it for
|
||||
* undo meshes should be low. */
|
||||
BLI_assert(um->me.runtime == nullptr);
|
||||
um->me.runtime = new blender::bke::MeshRuntime();
|
||||
|
||||
CustomData_MeshMasks cd_mask_extra{};
|
||||
cd_mask_extra.vmask = CD_MASK_SHAPE_KEYINDEX;
|
||||
BMeshToMeshParams params{};
|
||||
|
|
|
@ -3533,7 +3533,7 @@ static void PE_mirror_x(Depsgraph *depsgraph, Scene *scene, Object *ob, int tagg
|
|||
}
|
||||
|
||||
const bool use_dm_final_indices = (psys->part->use_modifier_stack &&
|
||||
!psmd_eval->mesh_final->runtime.deformed_only);
|
||||
!BKE_mesh_is_deformed_only(psmd_eval->mesh_final));
|
||||
|
||||
/* NOTE: this is not nice to use tessfaces but hard to avoid since pa->num uses tessfaces */
|
||||
BKE_mesh_tessface_ensure(me);
|
||||
|
@ -4353,7 +4353,7 @@ static void brush_add_count_iter(void *__restrict iter_data_v,
|
|||
0,
|
||||
0,
|
||||
0)) {
|
||||
if (psys->part->use_modifier_stack && !psmd_eval->mesh_final->runtime.deformed_only) {
|
||||
if (psys->part->use_modifier_stack && !BKE_mesh_is_deformed_only(psmd_eval->mesh_final)) {
|
||||
add_pars[iter].num = add_pars[iter].num_dmcache;
|
||||
add_pars[iter].num_dmcache = DMCACHE_ISCHILD;
|
||||
}
|
||||
|
@ -4430,7 +4430,7 @@ static int brush_add(const bContext *C, PEData *data, short number)
|
|||
|
||||
timestep = psys_get_timestep(&sim);
|
||||
|
||||
if (psys->part->use_modifier_stack || psmd_eval->mesh_final->runtime.deformed_only) {
|
||||
if (psys->part->use_modifier_stack || BKE_mesh_is_deformed_only(psmd_eval->mesh_final)) {
|
||||
mesh = psmd_eval->mesh_final;
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -732,7 +732,7 @@ static bool remap_hair_emitter(Depsgraph *depsgraph,
|
|||
invert_m4_m4(to_imat, to_mat);
|
||||
|
||||
const bool use_dm_final_indices = (target_psys->part->use_modifier_stack &&
|
||||
!target_psmd->mesh_final->runtime.deformed_only);
|
||||
!BKE_mesh_is_deformed_only(target_psmd->mesh_final));
|
||||
|
||||
if (use_dm_final_indices || !target_psmd->mesh_original) {
|
||||
mesh = target_psmd->mesh_final;
|
||||
|
|
|
@ -4074,7 +4074,7 @@ static bool proj_paint_state_mesh_eval_init(const bContext *C, ProjPaintState *p
|
|||
ps->totloop_eval = ps->me_eval->totloop;
|
||||
|
||||
ps->mlooptri_eval = BKE_mesh_runtime_looptri_ensure(ps->me_eval);
|
||||
ps->totlooptri_eval = ps->me_eval->runtime.looptris.len;
|
||||
ps->totlooptri_eval = BKE_mesh_runtime_looptri_len(ps->me_eval);
|
||||
|
||||
ps->poly_to_loop_uv = MEM_mallocN(ps->totpoly_eval * sizeof(MLoopUV *), "proj_paint_mtfaces");
|
||||
|
||||
|
|
|
@ -286,7 +286,7 @@ static void imapaint_pick_uv(
|
|||
const ePaintCanvasSource mode = scene->toolsettings->imapaint.mode;
|
||||
|
||||
const MLoopTri *lt = BKE_mesh_runtime_looptri_ensure(me_eval);
|
||||
const int tottri = me_eval->runtime.looptris.len;
|
||||
const int tottri = BKE_mesh_runtime_looptri_len(me_eval);
|
||||
|
||||
const MVert *mvert = BKE_mesh_verts(me_eval);
|
||||
const MLoop *mloop = BKE_mesh_loops(me_eval);
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
#include "BKE_key.h"
|
||||
#include "BKE_layer.h"
|
||||
#include "BKE_main.h"
|
||||
#include "BKE_mesh.h"
|
||||
#include "BKE_object.h"
|
||||
#include "BKE_paint.h"
|
||||
#include "BKE_particle.h"
|
||||
|
@ -94,8 +95,8 @@ static bool stats_mesheval(const Mesh *me_eval, bool is_selected, SceneStats *st
|
|||
|
||||
int totvert, totedge, totface, totloop;
|
||||
|
||||
const SubdivCCG *subdiv_ccg = me_eval->runtime.subdiv_ccg;
|
||||
const SubsurfRuntimeData *subsurf_runtime_data = me_eval->runtime.subsurf_runtime_data;
|
||||
const SubdivCCG *subdiv_ccg = me_eval->runtime->subdiv_ccg;
|
||||
const SubsurfRuntimeData *subsurf_runtime_data = me_eval->runtime->subsurf_runtime_data;
|
||||
|
||||
if (subdiv_ccg != nullptr) {
|
||||
BKE_subdiv_ccg_topology_counters(subdiv_ccg, &totvert, &totedge, &totface, &totloop);
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include "BKE_editmesh.h"
|
||||
#include "BKE_global.h"
|
||||
#include "BKE_mesh.h"
|
||||
#include "BKE_mesh_runtime.h"
|
||||
#include "BKE_object.h"
|
||||
|
||||
#include "DEG_depsgraph.h"
|
||||
|
@ -94,8 +95,8 @@ void ED_draw_object_facemap(Depsgraph *depsgraph,
|
|||
|
||||
const MPoly *mp;
|
||||
int i;
|
||||
if (me->runtime.looptris.array) {
|
||||
const MLoopTri *mlt = me->runtime.looptris.array;
|
||||
if (BKE_mesh_runtime_looptri_ensure(me)) {
|
||||
const MLoopTri *mlt = BKE_mesh_runtime_looptri_ensure(me);
|
||||
for (mp = polys, i = 0; i < mpoly_len; i++, mp++) {
|
||||
if (facemap_data[i] == facemap) {
|
||||
for (int j = 2; j < mp->totloop; j++) {
|
||||
|
|
|
@ -19,8 +19,10 @@
|
|||
|
||||
#include "BKE_context.h"
|
||||
#include "BKE_editmesh.h"
|
||||
#include "BKE_editmesh_cache.h"
|
||||
#include "BKE_global.h"
|
||||
#include "BKE_layer.h"
|
||||
#include "BKE_mesh.h"
|
||||
|
||||
#include "DEG_depsgraph.h"
|
||||
#include "DEG_depsgraph_query.h"
|
||||
|
@ -234,8 +236,8 @@ static int gizmo_preselect_elem_test_select(bContext *C, wmGizmo *gz, const int
|
|||
Object *ob = gz_ele->bases[gz_ele->base_index]->object;
|
||||
Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
|
||||
Mesh *me_eval = (Mesh *)DEG_get_evaluated_id(depsgraph, static_cast<ID *>(ob->data));
|
||||
if (me_eval->runtime.edit_data) {
|
||||
coords = me_eval->runtime.edit_data->vertexCos;
|
||||
if (me_eval->runtime->edit_data) {
|
||||
coords = me_eval->runtime->edit_data->vertexCos;
|
||||
}
|
||||
}
|
||||
EDBM_preselect_elem_update_from_single(gz_ele->psel, bm, best.ele, coords);
|
||||
|
|
|
@ -576,7 +576,7 @@ void mesh_foreachScreenFace(
|
|||
|
||||
BM_mesh_elem_table_ensure(vc->em->bm, BM_FACE);
|
||||
|
||||
if (me->runtime.subsurf_face_dot_tags != nullptr) {
|
||||
if (me->runtime->subsurf_face_dot_tags != nullptr) {
|
||||
BKE_mesh_foreach_mapped_subdiv_face_center(
|
||||
me, mesh_foreachScreenFace__mapFunc, &data, MESH_FOREACH_NOP);
|
||||
}
|
||||
|
|
|
@ -105,7 +105,7 @@ struct SnapData_EditMesh {
|
|||
/* Looptris. */
|
||||
BVHTreeFromEditMesh treedata_editmesh;
|
||||
|
||||
struct Mesh_Runtime *mesh_runtime;
|
||||
blender::bke::MeshRuntime *mesh_runtime;
|
||||
float min[3], max[3];
|
||||
|
||||
void clear()
|
||||
|
@ -189,14 +189,14 @@ static const Mesh *mesh_for_snap(Object *ob_eval, eSnapEditType edit_mode_type,
|
|||
const Mesh *editmesh_eval_cage = BKE_object_get_editmesh_eval_cage(ob_eval);
|
||||
|
||||
if ((edit_mode_type == SNAP_GEOM_FINAL) && editmesh_eval_final) {
|
||||
if (editmesh_eval_final->runtime.wrapper_type == ME_WRAPPER_TYPE_BMESH) {
|
||||
if (editmesh_eval_final->runtime->wrapper_type == ME_WRAPPER_TYPE_BMESH) {
|
||||
return nullptr;
|
||||
}
|
||||
me_eval = editmesh_eval_final;
|
||||
use_hide = true;
|
||||
}
|
||||
else if ((edit_mode_type == SNAP_GEOM_CAGE) && editmesh_eval_cage) {
|
||||
if (editmesh_eval_cage->runtime.wrapper_type == ME_WRAPPER_TYPE_BMESH) {
|
||||
if (editmesh_eval_cage->runtime->wrapper_type == ME_WRAPPER_TYPE_BMESH) {
|
||||
return nullptr;
|
||||
}
|
||||
me_eval = editmesh_eval_cage;
|
||||
|
@ -253,21 +253,21 @@ static SnapData_Mesh *snap_object_data_mesh_get(SnapObjectContext *sctx,
|
|||
sod = sod_p->get();
|
||||
bool is_dirty = false;
|
||||
if (sod->treedata_mesh.tree && sod->treedata_mesh.cached &&
|
||||
!bvhcache_has_tree(me_eval->runtime.bvh_cache, sod->treedata_mesh.tree)) {
|
||||
!bvhcache_has_tree(me_eval->runtime->bvh_cache, sod->treedata_mesh.tree)) {
|
||||
/* The tree is owned by the Mesh and may have been freed since we last used. */
|
||||
is_dirty = true;
|
||||
}
|
||||
else if (sod->bvhtree[0] && sod->cached[0] &&
|
||||
!bvhcache_has_tree(me_eval->runtime.bvh_cache, sod->bvhtree[0])) {
|
||||
!bvhcache_has_tree(me_eval->runtime->bvh_cache, sod->bvhtree[0])) {
|
||||
/* The tree is owned by the Mesh and may have been freed since we last used. */
|
||||
is_dirty = true;
|
||||
}
|
||||
else if (sod->bvhtree[1] && sod->cached[1] &&
|
||||
!bvhcache_has_tree(me_eval->runtime.bvh_cache, sod->bvhtree[1])) {
|
||||
!bvhcache_has_tree(me_eval->runtime->bvh_cache, sod->bvhtree[1])) {
|
||||
/* The tree is owned by the Mesh and may have been freed since we last used. */
|
||||
is_dirty = true;
|
||||
}
|
||||
else if (sod->treedata_mesh.looptri != me_eval->runtime.looptris.array) {
|
||||
else if (sod->treedata_mesh.looptri != me_eval->looptris().data()) {
|
||||
is_dirty = true;
|
||||
}
|
||||
else if (sod->treedata_mesh.vert != verts.data()) {
|
||||
|
@ -330,19 +330,19 @@ static SnapData_Mesh *snap_object_data_mesh_get(SnapObjectContext *sctx,
|
|||
|
||||
/* Searches for the #Mesh_Runtime associated with the object that is most likely to be updated due
|
||||
* to changes in the `edit_mesh`. */
|
||||
static Mesh_Runtime *snap_object_data_editmesh_runtime_get(Object *ob_eval)
|
||||
static blender::bke::MeshRuntime *snap_object_data_editmesh_runtime_get(Object *ob_eval)
|
||||
{
|
||||
Mesh *editmesh_eval_final = BKE_object_get_editmesh_eval_final(ob_eval);
|
||||
if (editmesh_eval_final) {
|
||||
return &editmesh_eval_final->runtime;
|
||||
return editmesh_eval_final->runtime;
|
||||
}
|
||||
|
||||
Mesh *editmesh_eval_cage = BKE_object_get_editmesh_eval_cage(ob_eval);
|
||||
if (editmesh_eval_cage) {
|
||||
return &editmesh_eval_cage->runtime;
|
||||
return editmesh_eval_cage->runtime;
|
||||
}
|
||||
|
||||
return &((Mesh *)ob_eval->data)->runtime;
|
||||
return ((Mesh *)ob_eval->data)->runtime;
|
||||
}
|
||||
|
||||
static SnapData_EditMesh *snap_object_data_editmesh_get(SnapObjectContext *sctx,
|
||||
|
|
|
@ -1953,8 +1953,6 @@ static LineartEdgeNeighbor *lineart_build_edge_neighbor(Mesh *me, int total_edge
|
|||
LineartEdgeNeighbor *edge_nabr = MEM_mallocN(sizeof(LineartEdgeNeighbor) * total_edges,
|
||||
"LineartEdgeNeighbor arr");
|
||||
|
||||
MLoopTri *mlooptri = me->runtime.looptris.array;
|
||||
|
||||
TaskParallelSettings en_settings;
|
||||
BLI_parallel_range_settings_defaults(&en_settings);
|
||||
/* Set the minimum amount of edges a thread has to process. */
|
||||
|
@ -1963,7 +1961,7 @@ static LineartEdgeNeighbor *lineart_build_edge_neighbor(Mesh *me, int total_edge
|
|||
EdgeNeighborData en_data;
|
||||
en_data.adj_e = adj_e;
|
||||
en_data.edge_nabr = edge_nabr;
|
||||
en_data.mlooptri = mlooptri;
|
||||
en_data.mlooptri = BKE_mesh_runtime_looptri_ensure(me);
|
||||
en_data.mloop = BKE_mesh_loops(me);
|
||||
|
||||
BLI_task_parallel_range(0, total_edges, &en_data, lineart_edge_neighbor_init_task, &en_settings);
|
||||
|
|
|
@ -19,10 +19,14 @@ namespace blender {
|
|||
template<typename T> class Span;
|
||||
template<typename T> class MutableSpan;
|
||||
namespace bke {
|
||||
struct MeshRuntime;
|
||||
class AttributeAccessor;
|
||||
class MutableAttributeAccessor;
|
||||
} // namespace bke
|
||||
} // namespace blender
|
||||
using MeshRuntimeHandle = blender::bke::MeshRuntime;
|
||||
#else
|
||||
typedef struct MeshRuntimeHandle MeshRuntimeHandle;
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -30,133 +34,14 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
struct AnimData;
|
||||
struct BVHCache;
|
||||
struct Ipo;
|
||||
struct Key;
|
||||
struct MCol;
|
||||
struct MEdge;
|
||||
struct MFace;
|
||||
struct MLoopCol;
|
||||
struct MLoopTri;
|
||||
struct MVert;
|
||||
struct Material;
|
||||
struct Mesh;
|
||||
struct SubdivCCG;
|
||||
struct SubsurfRuntimeData;
|
||||
|
||||
#
|
||||
#
|
||||
typedef struct EditMeshData {
|
||||
/** when set, \a vertexNos, polyNos are lazy initialized */
|
||||
const float (*vertexCos)[3];
|
||||
|
||||
/** lazy initialize (when \a vertexCos is set) */
|
||||
float const (*vertexNos)[3];
|
||||
float const (*polyNos)[3];
|
||||
/** also lazy init but don't depend on \a vertexCos */
|
||||
const float (*polyCos)[3];
|
||||
} EditMeshData;
|
||||
|
||||
/**
|
||||
* \warning Typical access is done via
|
||||
* #BKE_mesh_runtime_looptri_ensure, #BKE_mesh_runtime_looptri_len.
|
||||
*/
|
||||
struct MLoopTri_Store {
|
||||
DNA_DEFINE_CXX_METHODS(MLoopTri_Store)
|
||||
|
||||
/* WARNING! swapping between array (ready-to-be-used data) and array_wip
|
||||
* (where data is actually computed)
|
||||
* shall always be protected by same lock as one used for looptris computing. */
|
||||
struct MLoopTri *array, *array_wip;
|
||||
int len;
|
||||
int len_alloc;
|
||||
};
|
||||
|
||||
/** Runtime data, not saved in files. */
|
||||
typedef struct Mesh_Runtime {
|
||||
DNA_DEFINE_CXX_METHODS(Mesh_Runtime)
|
||||
|
||||
/* 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. */
|
||||
struct Mesh *mesh_eval;
|
||||
void *eval_mutex;
|
||||
|
||||
/* A separate mutex is needed for normal calculation, because sometimes
|
||||
* the normals are needed while #eval_mutex is already locked. */
|
||||
void *normals_mutex;
|
||||
|
||||
/** Needed to ensure some thread-safety during render data pre-processing. */
|
||||
void *render_mutex;
|
||||
|
||||
/** Lazily initialized SoA data from the #edit_mesh field in #Mesh. */
|
||||
struct 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;
|
||||
|
||||
/** Cache for derived triangulation of the mesh. */
|
||||
struct MLoopTri_Store looptris;
|
||||
|
||||
/** Cache for BVH trees generated for the mesh. Defined in 'BKE_bvhutil.c' */
|
||||
struct BVHCache *bvh_cache;
|
||||
|
||||
/** Cache of non-manifold boundary data for Shrinkwrap Target Project. */
|
||||
struct ShrinkwrapBoundaryData *shrinkwrap_data;
|
||||
|
||||
/** Needed in case we need to lazily initialize the mesh. */
|
||||
CustomData_MeshMasks cd_mask_extra;
|
||||
|
||||
struct SubdivCCG *subdiv_ccg;
|
||||
int subdiv_ccg_tot_level;
|
||||
|
||||
/** Set by modifier stack if only deformed from original. */
|
||||
char deformed_only;
|
||||
/**
|
||||
* 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 #eModifierTypeType_NonGeometrical modifiers). Otherwise the edit-mesh
|
||||
* data will be used for drawing, missing changes from modifiers. See T79517.
|
||||
*/
|
||||
char is_original_bmesh;
|
||||
|
||||
/** #eMeshWrapperType and others. */
|
||||
char wrapper_type;
|
||||
/**
|
||||
* A type mask from wrapper_type,
|
||||
* in case there are differences in finalizing logic between types.
|
||||
*/
|
||||
char wrapper_type_finalize;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
struct SubsurfRuntimeData *subsurf_runtime_data;
|
||||
void *_pad1;
|
||||
|
||||
/**
|
||||
* Caches for lazily computed vertex and polygon normals. These are stored here rather than in
|
||||
* #CustomData because they can be calculated on a const mesh, and adding custom data layers on a
|
||||
* const mesh is not thread-safe.
|
||||
*/
|
||||
char _pad2[6];
|
||||
char vert_normals_dirty;
|
||||
char poly_normals_dirty;
|
||||
float (*vert_normals)[3];
|
||||
float (*poly_normals)[3];
|
||||
|
||||
/**
|
||||
* A #BLI_bitmap containing tags for the center vertices of subdivided polygons, set by the
|
||||
* subdivision surface modifier and used by drawing code instead of polygon center face dots.
|
||||
*/
|
||||
uint32_t *subsurf_face_dot_tags;
|
||||
} Mesh_Runtime;
|
||||
|
||||
typedef struct Mesh {
|
||||
DNA_DEFINE_CXX_METHODS(Mesh)
|
||||
|
@ -316,9 +201,13 @@ typedef struct Mesh {
|
|||
|
||||
char _pad1[4];
|
||||
|
||||
void *_pad2;
|
||||
|
||||
Mesh_Runtime runtime;
|
||||
/**
|
||||
* Data that isn't saved in files, including caches of derived data, temporary data to improve
|
||||
* the editing experience, etc. Runtime data is created when reading files and can be accessed
|
||||
* without null checks, with the exception of some temporary meshes which should allocate and
|
||||
* free the data if they are passed to functions that expect run-time data.
|
||||
*/
|
||||
MeshRuntimeHandle *runtime;
|
||||
#ifdef __cplusplus
|
||||
/**
|
||||
* Array of vertex positions (and various other data). Edges and faces are defined by indices
|
||||
|
@ -383,16 +272,6 @@ typedef struct TFace {
|
|||
|
||||
/* **************** MESH ********************* */
|
||||
|
||||
/** #Mesh_Runtime.wrapper_type */
|
||||
typedef enum eMeshWrapperType {
|
||||
/** Use mesh data (#Mesh.mvert, #Mesh.medge, #Mesh.mloop, #Mesh.mpoly). */
|
||||
ME_WRAPPER_TYPE_MDATA = 0,
|
||||
/** Use edit-mesh data (#Mesh.edit_mesh, #Mesh_Runtime.edit_data). */
|
||||
ME_WRAPPER_TYPE_BMESH = 1,
|
||||
/** Use subdivision mesh data (#Mesh_Runtime.mesh_eval). */
|
||||
ME_WRAPPER_TYPE_SUBD = 2,
|
||||
} eMeshWrapperType;
|
||||
|
||||
/** #Mesh.texflag */
|
||||
enum {
|
||||
ME_AUTOSPACE = 1,
|
||||
|
|
|
@ -406,12 +406,39 @@ static int rna_MeshLoopTriangle_index_get(PointerRNA *ptr)
|
|||
{
|
||||
const Mesh *mesh = rna_mesh(ptr);
|
||||
const MLoopTri *ltri = (MLoopTri *)ptr->data;
|
||||
const int index = (int)(ltri - mesh->runtime.looptris.array);
|
||||
const int index = (int)(ltri - BKE_mesh_runtime_looptri_ensure(mesh));
|
||||
BLI_assert(index >= 0);
|
||||
BLI_assert(index < mesh->runtime.looptris.len);
|
||||
BLI_assert(index < BKE_mesh_runtime_looptri_len(mesh));
|
||||
return index;
|
||||
}
|
||||
|
||||
static void rna_Mesh_loop_triangles_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
|
||||
{
|
||||
const Mesh *mesh = rna_mesh(ptr);
|
||||
const MLoopTri *looptris = BKE_mesh_runtime_looptri_ensure(mesh);
|
||||
rna_iterator_array_begin(
|
||||
iter, (void *)looptris, sizeof(MLoopTri), BKE_mesh_runtime_looptri_len(mesh), false, NULL);
|
||||
}
|
||||
|
||||
static int rna_Mesh_loop_triangles_length(PointerRNA *ptr)
|
||||
{
|
||||
const Mesh *mesh = rna_mesh(ptr);
|
||||
return BKE_mesh_runtime_looptri_len(mesh);
|
||||
}
|
||||
|
||||
int rna_Mesh_loop_triangles_lookup_int(PointerRNA *ptr, int index, PointerRNA *r_ptr)
|
||||
{
|
||||
const Mesh *mesh = rna_mesh(ptr);
|
||||
if (index < 0 || index >= BKE_mesh_runtime_looptri_len(mesh)) {
|
||||
return false;
|
||||
}
|
||||
/* Casting away const is okay because this RNA type doesn't allow changing the value. */
|
||||
r_ptr->owner_id = (ID *)&mesh->id;
|
||||
r_ptr->type = &RNA_MeshLoopTriangle;
|
||||
r_ptr->data = (void *)&BKE_mesh_runtime_looptri_ensure(mesh)[index];
|
||||
return true;
|
||||
}
|
||||
|
||||
static void rna_MeshVertex_normal_get(PointerRNA *ptr, float *value)
|
||||
{
|
||||
Mesh *mesh = rna_mesh(ptr);
|
||||
|
@ -1502,8 +1529,9 @@ static char *rna_MeshPolygon_path(const PointerRNA *ptr)
|
|||
|
||||
static char *rna_MeshLoopTriangle_path(const PointerRNA *ptr)
|
||||
{
|
||||
return BLI_sprintfN("loop_triangles[%d]",
|
||||
(int)((MLoopTri *)ptr->data - rna_mesh(ptr)->runtime.looptris.array));
|
||||
return BLI_sprintfN(
|
||||
"loop_triangles[%d]",
|
||||
(int)((MLoopTri *)ptr->data - BKE_mesh_runtime_looptri_ensure(rna_mesh(ptr))));
|
||||
}
|
||||
|
||||
static char *rna_MeshEdge_path(const PointerRNA *ptr)
|
||||
|
@ -3684,7 +3712,15 @@ static void rna_def_mesh(BlenderRNA *brna)
|
|||
NULL);
|
||||
|
||||
prop = RNA_def_property(srna, "loop_triangles", PROP_COLLECTION, PROP_NONE);
|
||||
RNA_def_property_collection_sdna(prop, NULL, "runtime.looptris.array", "runtime.looptris.len");
|
||||
RNA_def_property_collection_funcs(prop,
|
||||
"rna_Mesh_loop_triangles_begin",
|
||||
"rna_iterator_array_next",
|
||||
"rna_iterator_array_end",
|
||||
"rna_iterator_array_get",
|
||||
"rna_Mesh_loop_triangles_length",
|
||||
"rna_Mesh_loop_triangles_lookup_int",
|
||||
NULL,
|
||||
NULL);
|
||||
RNA_def_property_struct_type(prop, "MeshLoopTriangle");
|
||||
RNA_def_property_override_flag(prop, PROPOVERRIDE_IGNORE);
|
||||
RNA_def_property_ui_text(prop, "Loop Triangles", "Tessellation of mesh polygons into triangles");
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include "BKE_lib_id.h"
|
||||
#include "BKE_lib_query.h"
|
||||
#include "BKE_mesh.h"
|
||||
#include "BKE_mesh_runtime.h"
|
||||
#include "BKE_mesh_wrapper.h"
|
||||
#include "BKE_modifier.h"
|
||||
#include "BKE_screen.h"
|
||||
|
@ -494,7 +495,7 @@ static void deformVertsEM(ModifierData *md,
|
|||
mesh_src = MOD_deform_mesh_eval_get(ctx->object, editData, mesh, NULL, verts_num, false);
|
||||
}
|
||||
|
||||
if (mesh && mesh->runtime.wrapper_type == ME_WRAPPER_TYPE_MDATA) {
|
||||
if (mesh && BKE_mesh_wrapper_type(mesh) == ME_WRAPPER_TYPE_MDATA) {
|
||||
BLI_assert(mesh->totvert == verts_num);
|
||||
}
|
||||
|
||||
|
|
|
@ -213,7 +213,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
|
|||
dtmd->defgrp_name,
|
||||
invert_vgroup,
|
||||
&reports)) {
|
||||
result->runtime.is_original_bmesh = false;
|
||||
result->runtime->is_original_bmesh = false;
|
||||
}
|
||||
|
||||
if (BKE_reports_contain(&reports, RPT_ERROR)) {
|
||||
|
|
|
@ -230,7 +230,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
|
|||
if ((ctx->object->mode & OB_MODE_SCULPT) && !for_orco && !for_render && !sculpt_base_mesh) {
|
||||
/* NOTE: CCG takes ownership over Subdiv. */
|
||||
result = multires_as_ccg(mmd, ctx, mesh, subdiv);
|
||||
result->runtime.subdiv_ccg_tot_level = mmd->totlvl;
|
||||
result->runtime->subdiv_ccg_tot_level = mmd->totlvl;
|
||||
/* TODO(sergey): Usually it is sculpt stroke's update variants which
|
||||
* takes care of this, but is possible that we need this before the
|
||||
* stroke: i.e. when exiting blender right after stroke is done.
|
||||
|
@ -238,7 +238,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
|
|||
* surely there is a better way of solving this. */
|
||||
if (ctx->object->sculpt != nullptr) {
|
||||
SculptSession *sculpt_session = ctx->object->sculpt;
|
||||
sculpt_session->subdiv_ccg = result->runtime.subdiv_ccg;
|
||||
sculpt_session->subdiv_ccg = result->runtime->subdiv_ccg;
|
||||
sculpt_session->multires.active = true;
|
||||
sculpt_session->multires.modifier = mmd;
|
||||
sculpt_session->multires.level = mmd->sculptlvl;
|
||||
|
|
|
@ -623,7 +623,7 @@ static Mesh *normalEditModifier_do(NormalEditModifierData *enmd,
|
|||
|
||||
MEM_SAFE_FREE(loopnors);
|
||||
|
||||
result->runtime.is_original_bmesh = false;
|
||||
result->runtime->is_original_bmesh = false;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -159,7 +159,7 @@ static void deformVerts(ModifierData *md,
|
|||
|
||||
BKE_mesh_tessface_ensure(psmd->mesh_final);
|
||||
|
||||
if (!psmd->mesh_final->runtime.deformed_only) {
|
||||
if (!psmd->mesh_final->runtime->deformed_only) {
|
||||
/* Get the original mesh from the object, this is what the particles
|
||||
* are attached to so in case of non-deform modifiers we need to remap
|
||||
* them to the final mesh (typically subdivision surfaces). */
|
||||
|
|
|
@ -67,10 +67,9 @@ static void init_dualcon_mesh(DualConInput *input, Mesh *mesh)
|
|||
input->mloop = (void *)BKE_mesh_loops(mesh);
|
||||
input->loop_stride = sizeof(MLoop);
|
||||
|
||||
BKE_mesh_runtime_looptri_ensure(mesh);
|
||||
input->looptri = (void *)mesh->runtime.looptris.array;
|
||||
input->looptri = (void *)BKE_mesh_runtime_looptri_ensure(mesh);
|
||||
input->tri_stride = sizeof(MLoopTri);
|
||||
input->tottri = mesh->runtime.looptris.len;
|
||||
input->tottri = BKE_mesh_runtime_looptri_len(mesh);
|
||||
|
||||
INIT_MINMAX(input->min, input->max);
|
||||
BKE_mesh_minmax(mesh, input->min, input->max);
|
||||
|
|
|
@ -208,7 +208,7 @@ static void subdiv_cache_mesh_wrapper_settings(const ModifierEvalContext *ctx,
|
|||
runtime_data->calc_loop_normals = false; /* Set at the end of modifier stack evaluation. */
|
||||
runtime_data->use_loop_normals = (smd->flags & eSubsurfModifierFlag_UseCustomNormals);
|
||||
|
||||
mesh->runtime.subsurf_runtime_data = runtime_data;
|
||||
mesh->runtime->subsurf_runtime_data = runtime_data;
|
||||
}
|
||||
|
||||
/* Modifier itself. */
|
||||
|
|
|
@ -188,7 +188,7 @@ Mesh *MOD_deform_mesh_eval_get(Object *ob,
|
|||
&mesh_prior_modifiers->id,
|
||||
nullptr,
|
||||
(LIB_ID_COPY_LOCALIZE | LIB_ID_COPY_CD_REFERENCE));
|
||||
mesh->runtime.deformed_only = 1;
|
||||
mesh->runtime->deformed_only = 1;
|
||||
}
|
||||
|
||||
if (em != nullptr) {
|
||||
|
@ -218,7 +218,7 @@ Mesh *MOD_deform_mesh_eval_get(Object *ob,
|
|||
}
|
||||
}
|
||||
|
||||
if (mesh && mesh->runtime.wrapper_type == ME_WRAPPER_TYPE_MDATA) {
|
||||
if (mesh && mesh->runtime->wrapper_type == ME_WRAPPER_TYPE_MDATA) {
|
||||
BLI_assert(mesh->totvert == verts_num);
|
||||
}
|
||||
|
||||
|
|
|
@ -283,7 +283,7 @@ static Mesh *uvprojectModifier_do(UVProjectModifierData *umd,
|
|||
}
|
||||
}
|
||||
|
||||
mesh->runtime.is_original_bmesh = false;
|
||||
mesh->runtime->is_original_bmesh = false;
|
||||
|
||||
return mesh;
|
||||
}
|
||||
|
|
|
@ -216,7 +216,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
|
|||
settings.use_threading = (polys_num > 1000);
|
||||
BLI_task_parallel_range(0, polys_num, &data, uv_warp_compute, &settings);
|
||||
|
||||
mesh->runtime.is_original_bmesh = false;
|
||||
mesh->runtime->is_original_bmesh = false;
|
||||
|
||||
return mesh;
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "BKE_context.h"
|
||||
#include "BKE_deform.h"
|
||||
#include "BKE_editmesh.h"
|
||||
#include "BKE_editmesh_cache.h"
|
||||
#include "BKE_lib_id.h"
|
||||
#include "BKE_lib_query.h"
|
||||
#include "BKE_mesh.h"
|
||||
|
@ -337,7 +338,7 @@ static void deformVertsEM(ModifierData *md,
|
|||
|
||||
if (!ELEM(mesh_src, nullptr, mesh)) {
|
||||
/* Important not to free `vertexCos` owned by the caller. */
|
||||
EditMeshData *edit_data = mesh_src->runtime.edit_data;
|
||||
EditMeshData *edit_data = mesh_src->runtime->edit_data;
|
||||
if (edit_data->vertexCos == vertexCos) {
|
||||
edit_data->vertexCos = nullptr;
|
||||
}
|
||||
|
|
|
@ -676,7 +676,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
|
|||
MEM_SAFE_FREE(wn_data.mode_pair);
|
||||
MEM_SAFE_FREE(wn_data.items_data);
|
||||
|
||||
result->runtime.is_original_bmesh = false;
|
||||
result->runtime->is_original_bmesh = false;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -278,7 +278,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
|
|||
MEM_freeN(new_w);
|
||||
MEM_freeN(dw);
|
||||
|
||||
mesh->runtime.is_original_bmesh = false;
|
||||
mesh->runtime->is_original_bmesh = false;
|
||||
|
||||
/* Return the vgroup-modified mesh. */
|
||||
return mesh;
|
||||
|
|
|
@ -438,7 +438,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
|
|||
MEM_freeN(dw2);
|
||||
MEM_SAFE_FREE(indices);
|
||||
|
||||
mesh->runtime.is_original_bmesh = false;
|
||||
mesh->runtime->is_original_bmesh = false;
|
||||
|
||||
/* Return the vgroup-modified mesh. */
|
||||
return mesh;
|
||||
|
|
|
@ -639,7 +639,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
|
|||
TIMEIT_END(perf);
|
||||
#endif
|
||||
|
||||
mesh->runtime.is_original_bmesh = false;
|
||||
mesh->runtime->is_original_bmesh = false;
|
||||
|
||||
/* Return the vgroup-modified mesh. */
|
||||
return mesh;
|
||||
|
|
|
@ -590,7 +590,7 @@ bool RE_bake_pixels_populate_from_objects(struct Mesh *me_low,
|
|||
me_highpoly[i] = highpoly[i].me;
|
||||
BKE_mesh_runtime_looptri_ensure(me_highpoly[i]);
|
||||
|
||||
if (me_highpoly[i]->runtime.looptris.len != 0) {
|
||||
if (BKE_mesh_runtime_looptri_len(me_highpoly[i]) != 0) {
|
||||
/* Create a BVH-tree for each `highpoly` object. */
|
||||
BKE_bvhtree_from_mesh_get(&treeData[i], me_highpoly[i], BVHTREE_FROM_LOOPTRI, 2);
|
||||
|
||||
|
|
Loading…
Reference in New Issue