Refactor: Simplify mesh edit mode modifier evaluation #108637

Merged
Hans Goudey merged 38 commits from HooglyBoogly/blender:cleanup-modifier-edit-mode-eval into main 2023-07-07 13:07:22 +02:00
35 changed files with 203 additions and 812 deletions

View File

@ -246,7 +246,7 @@ struct Mesh *editbmesh_get_eval_cage_from_orig(struct Depsgraph *depsgraph,
struct Object *obedit,
const struct CustomData_MeshMasks *dataMask);
float (*editbmesh_vert_coords_alloc(struct BMEditMesh *em, int *r_vert_len))[3];
float (*editbmesh_vert_coords_alloc(struct BMEditMesh *em))[3];
bool editbmesh_modifier_is_enabled(const struct Scene *scene,
const struct Object *ob,
struct ModifierData *md,

View File

@ -16,7 +16,7 @@ struct BMEditMesh;
typedef struct EditMeshData {
/** when set, \a vertexNos, polyNos are lazy initialized */
const float (*vertexCos)[3];
float (*vertexCos)[3];
Review

I think this should remain const, any changes to this wont be reflected in normals resulting in an invalid state, from what I can see manipulating this is only valid while building. Worst case assigning these values could cast to non-const with a note why it's acceptable in this particular case.

I think this should remain const, any changes to this wont be reflected in normals resulting in an invalid state, from what I can see manipulating this is only valid while building. Worst case assigning these values could cast to non-const with a note why it's acceptable in this particular case.
Review

I don't think const is correct here-- we really do change the values in every modifier. Instead I added a separate BKE_mesh_wrapper_tag_positions_changed function for this situation which handles clearing the cached "edit data" normals and poly centers.

I don't think `const` is correct here-- we really do change the values in every modifier. Instead I added a separate `BKE_mesh_wrapper_tag_positions_changed` function for this situation which handles clearing the cached "edit data" normals and poly centers.
Review

It's only changed in modifier evaluation, this can is also used by operators where it should be treated as const.

Unlike regular meshes, this is not actually the coordinate data, so any changes to this outside modifier evaluation put the mesh in an undefined state because changes are never written back to the mesh & any changes will be lost on any modifier evaluation.

We could even have a non-const member which is only used during modifier evaluation which is cleared once evaluation is complete. Then any calls to BKE_mesh_wrapper_vert_coords_ensure_for_write outside modifier evaluation can assert as this indicates incorrect API use.

It's only changed in modifier evaluation, this can is also used by operators where it should be treated as const. Unlike regular meshes, this is not actually the coordinate data, so any changes to this outside modifier evaluation put the mesh in an undefined state because changes are never written back to the mesh & any changes will be lost on any modifier evaluation. We could even have a non-const member which is only used during modifier evaluation which is cleared once evaluation is complete. Then any calls to `BKE_mesh_wrapper_vert_coords_ensure_for_write` outside modifier evaluation can assert as this indicates incorrect API use.
Review

changes are never written back to the mesh & any changes will be lost on any modifier evaluation.
If I understand right, mesh.runtime.edit_data is only ever used on evaluated meshes (which makes the name a bit wrong TBH). So this is sort of a hypothetical problem?

I think the problem is just the general lack of const correctness that comes from using pointers instead of an owning type like Array here. I'll change these to use Array<float3> next if that works for you? That resolves the problem since you won't be able to retrieve a mutable pointer from a const EditMeshData.

>changes are never written back to the mesh & any changes will be lost on any modifier evaluation. If I understand right, `mesh.runtime.edit_data` is only ever used on evaluated meshes (which makes the name a bit wrong TBH). So this is sort of a hypothetical problem? I think the problem is just the general lack of const correctness that comes from using pointers instead of an owning type like `Array` here. I'll change these to use `Array<float3>` next if that works for you? That resolves the problem since you won't be able to retrieve a mutable pointer from a `const EditMeshData`.
Review

Not so convinced Array<float3> helps that much as we simply never want this changed once the modifiers are evaluated, even if EditMeshData is otherwise mutable.
It may be impractical to use a const EditMeshData as allocating the cache for normals for e.g. requires it to be modified. On the other hand this patch is otherwise fine so this change can be handled separately.

Not so convinced `Array<float3>` helps that much as we simply never want this changed once the modifiers are evaluated, even if `EditMeshData` is otherwise mutable. It may be impractical to use a `const` `EditMeshData` as allocating the cache for normals for e.g. requires it to be modified. On the other hand this patch is otherwise fine so this change can be handled separately.
/** lazy initialize (when \a vertexCos is set) */
float const (*vertexNos)[3];

View File

@ -15,11 +15,6 @@ struct Mesh;
extern "C" {
#endif
struct Mesh *BKE_mesh_wrapper_from_editmesh_with_coords(
struct BMEditMesh *em,
const struct CustomData_MeshMasks *cd_mask_extra,
const float (*vert_coords)[3],
const struct Mesh *me_settings);
struct Mesh *BKE_mesh_wrapper_from_editmesh(struct BMEditMesh *em,
const struct CustomData_MeshMasks *cd_mask_extra,
const struct Mesh *me_settings);
@ -31,6 +26,21 @@ int BKE_mesh_wrapper_edge_len(const struct Mesh *me);
int BKE_mesh_wrapper_loop_len(const struct Mesh *me);
int BKE_mesh_wrapper_poly_len(const struct Mesh *me);
/**
* Return a contiguous array of vertex position values, if available.
* Otherwise, vertex positions are stored in BMesh vertices.
*/
const float (*BKE_mesh_wrapper_vert_coords(const struct Mesh *mesh))[3];
/**
* Return a contiguous array of face normal values, if available.
* Otherwise, normals are stored in BMesh faces.
*/
const float (*BKE_mesh_wrapper_poly_normals(struct Mesh *mesh))[3];
void BKE_mesh_wrapper_tag_positions_changed(struct Mesh *mesh);
void BKE_mesh_wrapper_vert_coords_copy(const struct Mesh *me,
float (*vert_coords)[3],
int vert_coords_len);

View File

@ -187,10 +187,9 @@ typedef struct ModifierTypeInfo {
/********************* Deform modifier functions *********************/
/**
* Only for deform types, should apply the deformation
* to the given vertex array. If the deformer requires information from
* the object it can obtain it from the mesh argument if non-NULL,
* and otherwise the ob argument.
* Apply a deformation to the positions in the \a vertexCos array. If the \a mesh argument is
* non-null, if will contain proper (not wrapped) mesh data. The \a vertexCos array may or may
* not be the same as the mesh's position attribute.
*/
void (*deformVerts)(struct ModifierData *md,
const struct ModifierEvalContext *ctx,
@ -208,7 +207,8 @@ typedef struct ModifierTypeInfo {
float (*defMats)[3][3],
int numVerts);
/**
* Like deformVerts but called during editmode (for supporting modifiers)
* Like deformVerts but called during edit-mode if supported. The \a mesh argument might be a
* wrapper around edit BMesh data.
*/
void (*deformVertsEM)(struct ModifierData *md,
const struct ModifierEvalContext *ctx,

View File

@ -1053,15 +1053,13 @@ static void mesh_calc_modifiers(Depsgraph *depsgraph,
}
}
float (*editbmesh_vert_coords_alloc(BMEditMesh *em, int *r_vert_len))[3]
float (*editbmesh_vert_coords_alloc(BMEditMesh *em))[3]
{
BMIter iter;
BMVert *eve;
float(*cos)[3];
int i;
*r_vert_len = em->bm->totvert;
cos = (float(*)[3])MEM_malloc_arrayN(em->bm->totvert, sizeof(float[3]), "vertexcos");
BM_ITER_MESH_INDEX (eve, &iter, em->bm, BM_VERTS_OF_MESH, i) {
@ -1135,6 +1133,21 @@ static void editbmesh_calc_modifier_final_normals_or_defer(
editbmesh_calc_modifier_final_normals(mesh_final, final_datamask);
}
static float (*mesh_wrapper_vert_coords_ensure_for_write(Mesh *mesh))[3]
{
switch (mesh->runtime->wrapper_type) {
case ME_WRAPPER_TYPE_BMESH:
if (mesh->runtime->edit_data->vertexCos == nullptr) {
mesh->runtime->edit_data->vertexCos = editbmesh_vert_coords_alloc(mesh->edit_mesh);
}
return mesh->runtime->edit_data->vertexCos;
case ME_WRAPPER_TYPE_MDATA:
case ME_WRAPPER_TYPE_SUBD:
return reinterpret_cast<float(*)[3]>(mesh->vert_positions_for_write().data());
}
return nullptr;
}
static void editbmesh_calc_modifiers(Depsgraph *depsgraph,
const Scene *scene,
Object *ob,
@ -1145,21 +1158,11 @@ static void editbmesh_calc_modifiers(Depsgraph *depsgraph,
Mesh **r_final,
GeometrySet **r_geometry_set)
{
/* Input and final mesh. Final mesh is only created the moment the first
* constructive modifier is executed, or a deform modifier needs normals
* or certain data layers. */
Mesh *mesh_input = (Mesh *)ob->data;
Mesh *mesh_final = nullptr;
Mesh *mesh_cage = nullptr;
/* This geometry set contains the non-mesh data that might be generated by modifiers. */
GeometrySet geometry_set_final;
/* TODO: Remove use of `deformed_verts` in mesh modifier stack
* since mesh positions are now stored in a contiguous array. */
float(*deformed_verts)[3] = nullptr;
int num_deformed_verts = 0;
bool isPrevDeform = false;
/* Mesh with constructive modifiers but no deformation applied. Tracked
* along with final mesh if undeformed / orco coordinates are requested
* for texturing. */
@ -1189,11 +1192,11 @@ static void editbmesh_calc_modifiers(Depsgraph *depsgraph,
CDMaskLink *md_datamask = datamasks;
CustomData_MeshMasks append_mask = CD_MASK_BAREMESH;
/* Evaluate modifiers up to certain index to get the mesh cage. */
Mesh *mesh_final = BKE_mesh_wrapper_from_editmesh(em_input, &final_datamask, mesh_input);
int cageIndex = BKE_modifiers_get_cage_index(scene, ob, nullptr, true);
if (r_cage && cageIndex == -1) {
mesh_cage = BKE_mesh_wrapper_from_editmesh_with_coords(
em_input, &final_datamask, nullptr, mesh_input);
mesh_cage = mesh_final;
}
/* The mesh from edit mode should not have any original index layers already, since those
HooglyBoogly marked this conversation as resolved Outdated

I don't think i == 0 does the same thing. This is used for multires to check that there are only deforming modifiers that don't change the topology preceding it.

I guess you can just add a boolean that track if any non-deforming modifiers were applied?

I don't think `i == 0` does the same thing. This is used for multires to check that there are only deforming modifiers that don't change the topology preceding it. I guess you can just add a boolean that track if any non-deforming modifiers were applied?
@ -1206,24 +1209,21 @@ static void editbmesh_calc_modifiers(Depsgraph *depsgraph,
BKE_modifiers_clear_errors(ob);
if (ob->modifier_flag & OB_MODIFIER_FLAG_ADD_REST_POSITION) {
if (mesh_final == nullptr) {
mesh_final = BKE_mesh_from_bmesh_for_eval_nomain(em_input->bm, nullptr, mesh_input);
ASSERT_IS_VALID_MESH(mesh_final);
}
BKE_mesh_wrapper_ensure_mdata(mesh_final);
set_rest_position(*mesh_final);
}
bool non_deform_modifier_applied = false;
for (int i = 0; md; i++, md = md->next, md_datamask = md_datamask->next) {
const ModifierTypeInfo *mti = BKE_modifier_get_info((ModifierType)md->type);
if (!editbmesh_modifier_is_enabled(scene, ob, md, mesh_final != nullptr)) {
if (!editbmesh_modifier_is_enabled(scene, ob, md, non_deform_modifier_applied)) {
continue;
}
blender::bke::ScopedModifierTimer modifier_timer{*md};
/* Add an orco mesh as layer if needed by this modifier. */
if (mesh_final && mesh_orco && mti->requiredDataMask) {
if (mesh_orco && mti->requiredDataMask) {
CustomData_MeshMasks mask = {0};
mti->requiredDataMask(md, &mask);
if (mask.vmask & CD_MASK_ORCO) {
@ -1231,61 +1231,41 @@ static void editbmesh_calc_modifiers(Depsgraph *depsgraph,
}
}
/* How to apply modifier depends on (a) what we already have as
* a result of previous modifiers (could be a mesh or just
* deformed vertices) and (b) what type the modifier is. */
if (mti->type == eModifierTypeType_OnlyDeform) {
/* No existing verts to deform, need to build them. */
if (!deformed_verts) {
if (mesh_final) {
/* Deforming a derived mesh, read the vertex locations
* out of the mesh and deform them. Once done with this
* run of deformers verts will be written back. */
deformed_verts = BKE_mesh_vert_coords_alloc(mesh_final, &num_deformed_verts);
}
else {
deformed_verts = editbmesh_vert_coords_alloc(em_input, &num_deformed_verts);
}
}
else if (isPrevDeform && mti->dependsOnNormals && mti->dependsOnNormals(md)) {
if (mesh_final == nullptr) {
mesh_final = BKE_mesh_from_bmesh_for_eval_nomain(em_input->bm, nullptr, mesh_input);
BKE_mesh_ensure_default_orig_index_customdata(mesh_final);
ASSERT_IS_VALID_MESH(mesh_final);
}
BLI_assert(deformed_verts != nullptr);
BKE_mesh_vert_coords_apply(mesh_final, deformed_verts);
if (mesh_final == mesh_cage) {
/* If the cage mesh has already been assigned, we have passed the cage index in the modifier
* list. If the cage and final meshes are still the same, duplicate the final mesh so the
* cage mesh isn't modified anymore. */
mesh_final = BKE_mesh_copy_for_eval(mesh_final);
if (mesh_cage->edit_mesh) {
mesh_final->edit_mesh = static_cast<BMEditMesh *>(MEM_dupallocN(mesh_cage->edit_mesh));
mesh_final->edit_mesh->is_shallow_copy = true;
mesh_final->runtime->is_original_bmesh = true;
BKE_mesh_runtime_ensure_edit_data(mesh_final);
}
}
if (mti->type == eModifierTypeType_OnlyDeform) {
if (mti->deformVertsEM) {
BKE_modifier_deform_vertsEM(
md, &mectx, em_input, mesh_final, deformed_verts, num_deformed_verts);
BKE_modifier_deform_vertsEM(md,
&mectx,
em_input,
mesh_final,
mesh_wrapper_vert_coords_ensure_for_write(mesh_final),
BKE_mesh_wrapper_vert_len(mesh_final));
BKE_mesh_wrapper_tag_positions_changed(mesh_final);
}
else {
BKE_modifier_deform_verts(md, &mectx, mesh_final, deformed_verts, num_deformed_verts);
BKE_mesh_wrapper_ensure_mdata(mesh_final);
BKE_modifier_deform_verts(md,
&mectx,
mesh_final,
BKE_mesh_vert_positions_for_write(mesh_final),
mesh_final->totvert);
BKE_mesh_tag_positions_changed(mesh_final);
}
}
else {
/* apply vertex coordinates or build a DerivedMesh as necessary */
if (mesh_final) {
if (deformed_verts) {
Mesh *mesh_tmp = BKE_mesh_copy_for_eval(mesh_final);
if (mesh_final != mesh_cage) {
BKE_id_free(nullptr, mesh_final);
}
mesh_final = mesh_tmp;
BKE_mesh_vert_coords_apply(mesh_final, deformed_verts);
}
else if (mesh_final == mesh_cage) {
/* 'me' may be changed by this modifier, so we need to copy it. */
mesh_final = BKE_mesh_copy_for_eval(mesh_final);
}
}
else {
mesh_final = BKE_mesh_wrapper_from_editmesh_with_coords(
em_input, nullptr, deformed_verts, mesh_input);
deformed_verts = nullptr;
}
non_deform_modifier_applied = true;
/* create an orco derivedmesh in parallel */
CustomData_MeshMasks mask = md_datamask->mask;
@ -1336,77 +1316,21 @@ static void editbmesh_calc_modifiers(Depsgraph *depsgraph,
ASSERT_IS_VALID_MESH(mesh_next);
if (mesh_next) {
if (mesh_final && mesh_final != mesh_next) {
if (mesh_final != mesh_next) {
BKE_id_free(nullptr, mesh_final);
}
mesh_final = mesh_next;
if (deformed_verts) {
MEM_freeN(deformed_verts);
deformed_verts = nullptr;
}
}
mesh_final->runtime->deformed_only = false;
}
if (r_cage && i == cageIndex) {
if (mesh_final && deformed_verts) {
mesh_cage = BKE_mesh_copy_for_eval(mesh_final);
BKE_mesh_vert_coords_apply(mesh_cage, deformed_verts);
}
else if (mesh_final) {
mesh_cage = mesh_final;
}
else {
Mesh *me_orig = mesh_input;
/* Modifying the input mesh is weak, however as there can only be one object in edit mode
* even if multiple are sharing the same mesh this should be thread safe. */
if ((me_orig->id.tag & LIB_TAG_COPIED_ON_WRITE) && (ob->mode & OB_MODE_EDIT)) {
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);
}
mesh_cage = BKE_mesh_wrapper_from_editmesh_with_coords(
em_input,
&final_datamask,
deformed_verts ? (const float(*)[3])MEM_dupallocN(deformed_verts) : nullptr,
mesh_input);
}
mesh_cage = mesh_final;
}
isPrevDeform = (mti->type == eModifierTypeType_OnlyDeform);
}
BLI_linklist_free((LinkNode *)datamasks, nullptr);
/* Yay, we are done. If we have a DerivedMesh and deformed vertices need
* to apply these back onto the DerivedMesh. If we have no DerivedMesh
* then we need to build one. */
if (mesh_final) {
if (deformed_verts) {
if (mesh_final == mesh_cage) {
mesh_final = BKE_mesh_copy_for_eval(mesh_final);
}
BKE_mesh_vert_coords_apply(mesh_final, deformed_verts);
}
}
else if (!deformed_verts && mesh_cage) {
/* cage should already have up to date normals */
mesh_final = mesh_cage;
}
else {
/* this is just a copy of the editmesh, no need to calc normals */
mesh_final = BKE_mesh_wrapper_from_editmesh_with_coords(
em_input, &final_datamask, deformed_verts, mesh_input);
deformed_verts = nullptr;
}
if (deformed_verts) {
MEM_freeN(deformed_verts);
}
/* Add orco coordinates to final and deformed mesh if requested. */
if (final_datamask.vmask & CD_MASK_ORCO) {
/* FIXME(@ideasman42): avoid the need to convert to mesh data just to add an orco layer. */

View File

@ -247,7 +247,8 @@ int BKE_crazyspace_get_first_deform_matrices_editbmesh(Depsgraph *depsgraph,
ModifierData *md;
Mesh *me_input = static_cast<Mesh *>(ob->data);
Mesh *me = nullptr;
int i, a, modifiers_left_num = 0, verts_num = 0;
int i, a, modifiers_left_num = 0;
const int verts_num = em->bm->totvert;
int cageIndex = BKE_modifiers_get_cage_index(scene, ob, nullptr, true);
float(*defmats)[3][3] = nullptr, (*deformedVerts)[3] = nullptr;
VirtualModifierData virtualModifierData;
@ -276,8 +277,8 @@ int BKE_crazyspace_get_first_deform_matrices_editbmesh(Depsgraph *depsgraph,
cd_mask_extra = datamasks->mask;
BLI_linklist_free((LinkNode *)datamasks, nullptr);
me = BKE_mesh_wrapper_from_editmesh_with_coords(em, &cd_mask_extra, nullptr, me_input);
deformedVerts = editbmesh_vert_coords_alloc(em, &verts_num);
me = BKE_mesh_wrapper_from_editmesh(em, &cd_mask_extra, me_input);
deformedVerts = editbmesh_vert_coords_alloc(em);
defmats = static_cast<float(*)[3][3]>(
MEM_mallocN(sizeof(*defmats) * verts_num, "defmats"));

View File

@ -230,9 +230,9 @@ 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 (BKE_mesh_wrapper_vert_coords(me) != nullptr) {
/* Deformed, and we have deformed coords already. */
coords = me->runtime->edit_data->vertexCos;
coords = BKE_mesh_wrapper_vert_coords(me);
}
else if ((editmesh_eval_final != nullptr) &&
(editmesh_eval_final->runtime->wrapper_type == ME_WRAPPER_TYPE_BMESH))

View File

@ -366,10 +366,11 @@ void BKE_mesh_ensure_normals_for_display(Mesh *mesh)
break;
case ME_WRAPPER_TYPE_BMESH: {
BMEditMesh *em = mesh->edit_mesh;
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);
if (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);
}
}
return;
}

View File

@ -34,6 +34,7 @@
#include "BLI_threads.h"
#include "BLI_utildefines.h"
#include "BKE_DerivedMesh.h"
#include "BKE_editmesh.h"
#include "BKE_editmesh_cache.h"
#include "BKE_lib_id.h"
@ -52,10 +53,9 @@
using blender::float3;
using blender::Span;
Mesh *BKE_mesh_wrapper_from_editmesh_with_coords(BMEditMesh *em,
const CustomData_MeshMasks *cd_mask_extra,
const float (*vert_coords)[3],
const Mesh *me_settings)
Mesh *BKE_mesh_wrapper_from_editmesh(BMEditMesh *em,
const CustomData_MeshMasks *cd_mask_extra,
const Mesh *me_settings)
{
Mesh *me = static_cast<Mesh *>(BKE_id_new_nomain(ID_ME, nullptr));
BKE_mesh_copy_parameters_for_eval(me, me_settings);
@ -85,18 +85,9 @@ Mesh *BKE_mesh_wrapper_from_editmesh_with_coords(BMEditMesh *em,
me->totloop = 0;
#endif
EditMeshData *edit_data = me->runtime->edit_data;
edit_data->vertexCos = vert_coords;
return me;
}
Mesh *BKE_mesh_wrapper_from_editmesh(BMEditMesh *em,
const CustomData_MeshMasks *cd_mask_extra,
const Mesh *me_settings)
{
return BKE_mesh_wrapper_from_editmesh_with_coords(em, cd_mask_extra, nullptr, me_settings);
}
void BKE_mesh_wrapper_ensure_mdata(Mesh *me)
{
std::lock_guard lock{me->runtime->eval_mutex};
@ -138,6 +129,8 @@ void BKE_mesh_wrapper_ensure_mdata(Mesh *me)
BKE_mesh_vert_coords_apply(me, edit_data->vertexCos);
me->runtime->is_original_bmesh = false;
}
BKE_mesh_runtime_reset_edit_data(me);
MEM_SAFE_FREE(me->runtime->edit_data);
break;
}
}
@ -176,6 +169,49 @@ bool BKE_mesh_wrapper_minmax(const Mesh *me, float min[3], float max[3])
/** \name Mesh Coordinate Access
* \{ */
const float (*BKE_mesh_wrapper_vert_coords(const Mesh *mesh))[3]
HooglyBoogly marked this conversation as resolved Outdated

Should be if (mesh->runtime->edit_data->vertexCos == nullptr) { (the hook modifier was crashing in edit-mode)

Should be `if (mesh->runtime->edit_data->vertexCos == nullptr) {` (the hook modifier was crashing in edit-mode)
{
switch (mesh->runtime->wrapper_type) {
case ME_WRAPPER_TYPE_BMESH:
return mesh->runtime->edit_data->vertexCos;
case ME_WRAPPER_TYPE_MDATA:
case ME_WRAPPER_TYPE_SUBD:
return reinterpret_cast<const float(*)[3]>(mesh->vert_positions().data());
}
return nullptr;
}
const float (*BKE_mesh_wrapper_poly_normals(Mesh *mesh))[3]
{
switch (mesh->runtime->wrapper_type) {
case ME_WRAPPER_TYPE_BMESH:
BKE_editmesh_cache_ensure_poly_normals(mesh->edit_mesh, mesh->runtime->edit_data);
return mesh->runtime->edit_data->polyNos;
case ME_WRAPPER_TYPE_MDATA:

I don't think this should be possible, or - edit_data could store track if it's building (in debug mode), then assert if this is ever called outside of modifier evaluation.

I don't think this should be possible, or - `edit_data` could store track if it's building (in debug mode), then assert if this is ever called outside of modifier evaluation.
case ME_WRAPPER_TYPE_SUBD:
return reinterpret_cast<const float(*)[3]>(mesh->poly_normals().data());
}
return nullptr;
}
void BKE_mesh_wrapper_tag_positions_changed(Mesh *mesh)
{
switch (mesh->runtime->wrapper_type) {
case ME_WRAPPER_TYPE_BMESH:
if (mesh->runtime->edit_data) {
MEM_SAFE_FREE(mesh->runtime->edit_data->vertexNos);
MEM_SAFE_FREE(mesh->runtime->edit_data->polyCos);
MEM_SAFE_FREE(mesh->runtime->edit_data->polyNos);
}
break;
case ME_WRAPPER_TYPE_MDATA:
case ME_WRAPPER_TYPE_SUBD:
BKE_mesh_tag_positions_changed(mesh);
break;
}
}
void BKE_mesh_wrapper_vert_coords_copy(const Mesh *me,
float (*vert_coords)[3],
int vert_coords_len)

View File

@ -17,6 +17,7 @@
#include "BKE_editmesh_cache.h"
#include "BKE_global.h"
#include "BKE_mesh.hh"
#include "BKE_mesh_wrapper.h"
#include "BKE_unit.h"
#include "DNA_mesh_types.h"
@ -236,8 +237,7 @@ 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] = BKE_mesh_wrapper_vert_coords(me);
const bool use_coords = (vert_coords != nullptr);
/* when 2 or more edge-info options are enabled, space apart */
@ -344,8 +344,7 @@ 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;
poly_normals = BKE_mesh_wrapper_poly_normals(me);
}
BM_ITER_MESH (eed, &iter, em->bm, BM_EDGES_OF_MESH) {

View File

@ -23,9 +23,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.hh"
#include "BKE_mesh_wrapper.h"
#include "BKE_report.h"
#include "WM_api.h"
@ -1075,8 +1075,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 (BKE_mesh_wrapper_vert_len(me_eval) == bm->totvert) {
coords = BKE_mesh_wrapper_vert_coords(me_eval);
}
}

View File

@ -21,10 +21,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.hh"
#include "BKE_mesh_wrapper.h"
#include "DEG_depsgraph.h"
#include "DEG_depsgraph_query.h"
@ -240,8 +240,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 (BKE_mesh_wrapper_vert_len(me_eval) == bm->totvert) {
coords = BKE_mesh_wrapper_vert_coords(me_eval);
}
}
EDBM_preselect_elem_update_from_single(gz_ele->psel, bm, best.ele, coords);

View File

@ -154,7 +154,7 @@ static void deformVertsEM(ModifierData *md,
float (*vertexCos)[3],
int verts_num)
{
if (mesh != nullptr) {
if (mesh->runtime->wrapper_type == ME_WRAPPER_TYPE_MDATA) {
deformVerts(md, ctx, mesh, vertexCos, verts_num);
return;
}
@ -206,8 +206,6 @@ static void deformMatrices(ModifierData *md,
int verts_num)
{
ArmatureModifierData *amd = (ArmatureModifierData *)md;
Mesh *mesh_src = MOD_deform_mesh_eval_get(ctx->object, nullptr, mesh, nullptr);
BKE_armature_deform_coords_with_mesh(amd->object,
ctx->object,
vertexCos,
@ -216,11 +214,7 @@ static void deformMatrices(ModifierData *md,
amd->deformflag,
nullptr,
amd->defgrp_name,
mesh_src);
if (!ELEM(mesh_src, nullptr, mesh)) {
BKE_id_free(nullptr, mesh_src);
}
mesh);
}
static void panel_draw(const bContext * /*C*/, Panel *panel)

View File

@ -462,57 +462,12 @@ static void deformVerts(ModifierData *md,
int verts_num)
{
CastModifierData *cmd = (CastModifierData *)md;
Mesh *mesh_src = nullptr;
if (ctx->object->type == OB_MESH && cmd->defgrp_name[0] != '\0') {
/* mesh_src is only needed for vgroups. */
mesh_src = MOD_deform_mesh_eval_get(ctx->object, nullptr, mesh, nullptr);
}
if (cmd->type == MOD_CAST_TYPE_CUBOID) {
cuboid_do(cmd, ctx, ctx->object, mesh_src, vertexCos, verts_num);
cuboid_do(cmd, ctx, ctx->object, mesh, vertexCos, verts_num);
}
else { /* MOD_CAST_TYPE_SPHERE or MOD_CAST_TYPE_CYLINDER */
sphere_do(cmd, ctx, ctx->object, mesh_src, vertexCos, verts_num);
}
if (!ELEM(mesh_src, nullptr, mesh)) {
BKE_id_free(nullptr, mesh_src);
}
}
static void deformVertsEM(ModifierData *md,
const ModifierEvalContext *ctx,
BMEditMesh *editData,
Mesh *mesh,
float (*vertexCos)[3],
int verts_num)
{
CastModifierData *cmd = (CastModifierData *)md;
Mesh *mesh_src = nullptr;
if (cmd->defgrp_name[0] != '\0') {
mesh_src = MOD_deform_mesh_eval_get(ctx->object, editData, mesh, nullptr);
}
if (mesh && BKE_mesh_wrapper_type(mesh) == ME_WRAPPER_TYPE_MDATA) {
BLI_assert(mesh->totvert == verts_num);
}
/* TODO(@ideasman42): use edit-mode data only (remove this line). */
if (mesh_src != nullptr) {
BKE_mesh_wrapper_ensure_mdata(mesh_src);
}
if (cmd->type == MOD_CAST_TYPE_CUBOID) {
cuboid_do(cmd, ctx, ctx->object, mesh_src, vertexCos, verts_num);
}
else { /* MOD_CAST_TYPE_SPHERE or MOD_CAST_TYPE_CYLINDER */
sphere_do(cmd, ctx, ctx->object, mesh_src, vertexCos, verts_num);
}
if (!ELEM(mesh_src, nullptr, mesh)) {
BKE_id_free(nullptr, mesh_src);
sphere_do(cmd, ctx, ctx->object, mesh, vertexCos, verts_num);
}
}
@ -570,7 +525,7 @@ ModifierTypeInfo modifierType_Cast = {
/*deformVerts*/ deformVerts,
/*deformMatrices*/ nullptr,
/*deformVertsEM*/ deformVertsEM,
/*deformVertsEM*/ nullptr,
/*deformMatricesEM*/ nullptr,
/*modifyMesh*/ nullptr,
/*modifyGeometrySet*/ nullptr,

View File

@ -81,7 +81,6 @@ static void deformVerts(ModifierData *md,
float (*vertexCos)[3],
int verts_num)
{
Mesh *mesh_src;
ClothModifierData *clmd = (ClothModifierData *)md;
Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph);
@ -94,15 +93,6 @@ static void deformVerts(ModifierData *md,
}
}
if (mesh == nullptr) {
mesh_src = MOD_deform_mesh_eval_get(ctx->object, nullptr, nullptr, nullptr);
}
else {
/* Not possible to use get_mesh() in this case as we'll modify its vertices
* and get_mesh() would return 'mesh' directly. */
mesh_src = (Mesh *)BKE_id_copy_ex(nullptr, (ID *)mesh, nullptr, LIB_ID_COPY_LOCALIZE);
}
/* TODO(sergey): For now it actually duplicates logic from DerivedMesh.cc
* and needs some more generic solution. But starting experimenting with
* this so close to the release is not that nice..
@ -114,22 +104,20 @@ static void deformVerts(ModifierData *md,
clmd->sim_parms->shapekey_rest);
if (kb && kb->data != nullptr) {
float(*layerorco)[3];
if (!(layerorco = static_cast<float(*)[3]>(CustomData_get_layer_for_write(
&mesh_src->vdata, CD_CLOTH_ORCO, mesh_src->totvert))))
if (!(layerorco = static_cast<float(*)[3]>(
CustomData_get_layer_for_write(&mesh->vdata, CD_CLOTH_ORCO, mesh->totvert))))
{
layerorco = static_cast<float(*)[3]>(CustomData_add_layer(
&mesh_src->vdata, CD_CLOTH_ORCO, CD_SET_DEFAULT, mesh_src->totvert));
layerorco = static_cast<float(*)[3]>(
CustomData_add_layer(&mesh->vdata, CD_CLOTH_ORCO, CD_SET_DEFAULT, mesh->totvert));
}
memcpy(layerorco, kb->data, sizeof(float[3]) * verts_num);
}
}
BKE_mesh_vert_coords_apply(mesh_src, vertexCos);
BKE_mesh_vert_coords_apply(mesh, vertexCos);
clothModifier_do(clmd, ctx->depsgraph, scene, ctx->object, mesh_src, vertexCos);
BKE_id_free(nullptr, mesh_src);
clothModifier_do(clmd, ctx->depsgraph, scene, ctx->object, mesh, vertexCos);
}
static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphContext *ctx)

View File

@ -93,7 +93,6 @@ static void deformVerts(ModifierData *md,
int /*verts_num*/)
{
CollisionModifierData *collmd = (CollisionModifierData *)md;
Mesh *mesh_src;
Object *ob = ctx->object;
/* If collision is disabled, free the stale data and exit. */
@ -106,20 +105,11 @@ static void deformVerts(ModifierData *md,
return;
}
if (mesh == nullptr) {
mesh_src = MOD_deform_mesh_eval_get(ob, nullptr, nullptr, nullptr);
}
else {
/* Not possible to use get_mesh() in this case as we'll modify its vertices
* and get_mesh() would return 'mesh' directly. */
mesh_src = (Mesh *)BKE_id_copy_ex(nullptr, (ID *)mesh, nullptr, LIB_ID_COPY_LOCALIZE);
}
if (mesh_src) {
if (mesh) {
float current_time = 0;
int mvert_num = 0;
BKE_mesh_vert_coords_apply(mesh_src, vertexCos);
BKE_mesh_vert_coords_apply(mesh, vertexCos);
current_time = DEG_get_ctime(ctx->depsgraph);
@ -127,7 +117,7 @@ static void deformVerts(ModifierData *md,
printf("current_time %f, collmd->time_xnew %f\n", current_time, collmd->time_xnew);
}
mvert_num = mesh_src->totvert;
mvert_num = mesh->totvert;
if (current_time < collmd->time_xnew) {
freeData((ModifierData *)collmd);
@ -145,7 +135,7 @@ static void deformVerts(ModifierData *md,
if (collmd->time_xnew == -1000) { /* first time */
collmd->x = BKE_mesh_vert_coords_alloc(mesh_src, &mvert_num); /* frame start position */
collmd->x = BKE_mesh_vert_coords_alloc(mesh, &mvert_num); /* frame start position */
for (uint i = 0; i < mvert_num; i++) {
/* we save global positions */
@ -160,12 +150,12 @@ static void deformVerts(ModifierData *md,
collmd->mvert_num = mvert_num;
{
const MLoopTri *looptri = BKE_mesh_runtime_looptri_ensure(mesh_src);
collmd->tri_num = BKE_mesh_runtime_looptri_len(mesh_src);
const MLoopTri *looptri = BKE_mesh_runtime_looptri_ensure(mesh);
collmd->tri_num = BKE_mesh_runtime_looptri_len(mesh);
MVertTri *tri = static_cast<MVertTri *>(
MEM_mallocN(sizeof(*tri) * collmd->tri_num, __func__));
BKE_mesh_runtime_verttri_from_looptri(
tri, mesh_src->corner_verts().data(), looptri, collmd->tri_num);
tri, mesh->corner_verts().data(), looptri, collmd->tri_num);
collmd->tri = tri;
}
@ -183,7 +173,7 @@ static void deformVerts(ModifierData *md,
collmd->xnew = temp;
collmd->time_x = collmd->time_xnew;
memcpy(collmd->xnew, mesh_src->vert_positions().data(), mvert_num * sizeof(float[3]));
memcpy(collmd->xnew, mesh->vert_positions().data(), mvert_num * sizeof(float[3]));
bool is_static = true;
@ -229,10 +219,6 @@ static void deformVerts(ModifierData *md,
freeData((ModifierData *)collmd);
}
}
if (!ELEM(mesh_src, nullptr, mesh)) {
BKE_id_free(nullptr, mesh_src);
}
}
static void updateDepsgraph(ModifierData * /*md*/, const ModifierUpdateDepsgraphContext *ctx)

View File

@ -744,36 +744,8 @@ static void deformVerts(ModifierData *md,
float (*vertexCos)[3],
int verts_num)
{
Mesh *mesh_src = MOD_deform_mesh_eval_get(ctx->object, nullptr, mesh, nullptr);
correctivesmooth_modifier_do(
md, ctx->depsgraph, ctx->object, mesh_src, vertexCos, uint(verts_num), nullptr);
if (!ELEM(mesh_src, nullptr, mesh)) {
BKE_id_free(nullptr, mesh_src);
}
}
static void deformVertsEM(ModifierData *md,
const ModifierEvalContext *ctx,
BMEditMesh *editData,
Mesh *mesh,
float (*vertexCos)[3],
int verts_num)
{
Mesh *mesh_src = MOD_deform_mesh_eval_get(ctx->object, editData, mesh, nullptr);
/* TODO(@ideasman42): use edit-mode data only (remove this line). */
if (mesh_src != nullptr) {
BKE_mesh_wrapper_ensure_mdata(mesh_src);
}
correctivesmooth_modifier_do(
md, ctx->depsgraph, ctx->object, mesh_src, vertexCos, uint(verts_num), editData);
if (!ELEM(mesh_src, nullptr, mesh)) {
BKE_id_free(nullptr, mesh_src);
}
md, ctx->depsgraph, ctx->object, mesh, vertexCos, uint(verts_num), nullptr);
}
static void panel_draw(const bContext * /*C*/, Panel *panel)
@ -860,7 +832,7 @@ ModifierTypeInfo modifierType_CorrectiveSmooth = {
/*deformVerts*/ deformVerts,
/*deformMatrices*/ nullptr,
/*deformVertsEM*/ deformVertsEM,
/*deformVertsEM*/ nullptr,
/*deformMatricesEM*/ nullptr,
/*modifyMesh*/ nullptr,
/*modifyGeometrySet*/ nullptr,

View File

@ -106,16 +106,10 @@ static void deformVerts(ModifierData *md,
int verts_num)
{
CurveModifierData *cmd = (CurveModifierData *)md;
Mesh *mesh_src = nullptr;
if (ctx->object->type == OB_MESH && cmd->name[0] != '\0') {
/* mesh_src is only needed for vgroups. */
mesh_src = MOD_deform_mesh_eval_get(ctx->object, nullptr, mesh, nullptr);
}
const MDeformVert *dvert = nullptr;
int defgrp_index = -1;
MOD_get_vgroup(ctx->object, mesh_src, cmd->name, &dvert, &defgrp_index);
MOD_get_vgroup(ctx->object, mesh, cmd->name, &dvert, &defgrp_index);
/* Silly that defaxis and BKE_curve_deform_coords are off by 1
* but leave for now to save having to call do_versions */
@ -128,10 +122,6 @@ static void deformVerts(ModifierData *md,
defgrp_index,
cmd->flag,
cmd->defaxis - 1);
if (!ELEM(mesh_src, nullptr, mesh)) {
BKE_id_free(nullptr, mesh_src);
}
}
static void deformVertsEM(ModifierData *md,
@ -141,7 +131,7 @@ static void deformVertsEM(ModifierData *md,
float (*vertexCos)[3],
int verts_num)
{
if (mesh != nullptr) {
if (mesh->runtime->wrapper_type == ME_WRAPPER_TYPE_MDATA) {
deformVerts(md, ctx, mesh, vertexCos, verts_num);
return;
}

View File

@ -372,34 +372,7 @@ static void deformVerts(ModifierData *md,
float (*vertexCos)[3],
int verts_num)
{
Mesh *mesh_src = MOD_deform_mesh_eval_get(ctx->object, nullptr, mesh, nullptr);
displaceModifier_do((DisplaceModifierData *)md, ctx, mesh_src, vertexCos, verts_num);
if (!ELEM(mesh_src, nullptr, mesh)) {
BKE_id_free(nullptr, mesh_src);
}
}
static void deformVertsEM(ModifierData *md,
const ModifierEvalContext *ctx,
BMEditMesh *editData,
Mesh *mesh,
float (*vertexCos)[3],
int verts_num)
{
Mesh *mesh_src = MOD_deform_mesh_eval_get(ctx->object, editData, mesh, nullptr);
/* TODO(@ideasman42): use edit-mode data only (remove this line). */
if (mesh_src != nullptr) {
BKE_mesh_wrapper_ensure_mdata(mesh_src);
}
displaceModifier_do((DisplaceModifierData *)md, ctx, mesh_src, vertexCos, verts_num);
if (!ELEM(mesh_src, nullptr, mesh)) {
BKE_id_free(nullptr, mesh_src);
}
displaceModifier_do((DisplaceModifierData *)md, ctx, mesh, vertexCos, verts_num);
}
static void panel_draw(const bContext *C, Panel *panel)
@ -485,7 +458,7 @@ ModifierTypeInfo modifierType_Displace = {
/*deformVerts*/ deformVerts,
/*deformMatrices*/ nullptr,
/*deformVertsEM*/ deformVertsEM,
/*deformVertsEM*/ nullptr,
/*deformMatricesEM*/ nullptr,
/*modifyMesh*/ nullptr,
/*modifyGeometrySet*/ nullptr,

View File

@ -431,13 +431,7 @@ static void deformVerts(ModifierData *md,
int verts_num)
{
HookModifierData *hmd = (HookModifierData *)md;
Mesh *mesh_src = MOD_deform_mesh_eval_get(ctx->object, nullptr, mesh, nullptr);
deformVerts_do(hmd, ctx, ctx->object, mesh_src, nullptr, vertexCos, verts_num);
if (!ELEM(mesh_src, nullptr, mesh)) {
BKE_id_free(nullptr, mesh_src);
}
deformVerts_do(hmd, ctx, ctx->object, mesh, nullptr, vertexCos, verts_num);
}
static void deformVertsEM(ModifierData *md,
@ -449,7 +443,13 @@ static void deformVertsEM(ModifierData *md,
{
HookModifierData *hmd = (HookModifierData *)md;
deformVerts_do(hmd, ctx, ctx->object, mesh, mesh ? nullptr : editData, vertexCos, verts_num);
deformVerts_do(hmd,
ctx,
ctx->object,
mesh,
mesh->runtime->wrapper_type == ME_WRAPPER_TYPE_BMESH ? editData : nullptr,
vertexCos,
verts_num);
}
static void panel_draw(const bContext * /*C*/, Panel *panel)

View File

@ -749,36 +749,8 @@ static void deformVerts(ModifierData *md,
float (*vertexCos)[3],
int verts_num)
{
Mesh *mesh_src = MOD_deform_mesh_eval_get(ctx->object, nullptr, mesh, nullptr);
LaplacianDeformModifier_do(
(LaplacianDeformModifierData *)md, ctx->object, mesh_src, vertexCos, verts_num);
if (!ELEM(mesh_src, nullptr, mesh)) {
BKE_id_free(nullptr, mesh_src);
}
}
static void deformVertsEM(ModifierData *md,
const ModifierEvalContext *ctx,
BMEditMesh *editData,
Mesh *mesh,
float (*vertexCos)[3],
int verts_num)
{
Mesh *mesh_src = MOD_deform_mesh_eval_get(ctx->object, editData, mesh, nullptr);
/* TODO(@ideasman42): use edit-mode data only (remove this line). */
if (mesh_src != nullptr) {
BKE_mesh_wrapper_ensure_mdata(mesh_src);
}
LaplacianDeformModifier_do(
(LaplacianDeformModifierData *)md, ctx->object, mesh_src, vertexCos, verts_num);
if (!ELEM(mesh_src, nullptr, mesh)) {
BKE_id_free(nullptr, mesh_src);
}
(LaplacianDeformModifierData *)md, ctx->object, mesh, vertexCos, verts_num);
}
static void freeData(ModifierData *md)
@ -869,7 +841,7 @@ ModifierTypeInfo modifierType_LaplacianDeform = {
/*deformVerts*/ deformVerts,
/*deformMatrices*/ nullptr,
/*deformVertsEM*/ deformVertsEM,
/*deformVertsEM*/ nullptr,
/*deformMatricesEM*/ nullptr,
/*modifyMesh*/ nullptr,
/*modifyGeometrySet*/ nullptr,

View File

@ -508,48 +508,12 @@ static void deformVerts(ModifierData *md,
float (*vertexCos)[3],
int verts_num)
{
Mesh *mesh_src;
if (verts_num == 0) {
return;
}
mesh_src = MOD_deform_mesh_eval_get(ctx->object, nullptr, mesh, nullptr);
laplaciansmoothModifier_do(
(LaplacianSmoothModifierData *)md, ctx->object, mesh_src, vertexCos, verts_num);
if (!ELEM(mesh_src, nullptr, mesh)) {
BKE_id_free(nullptr, mesh_src);
}
}
static void deformVertsEM(ModifierData *md,
const ModifierEvalContext *ctx,
BMEditMesh *editData,
Mesh *mesh,
float (*vertexCos)[3],
int verts_num)
{
Mesh *mesh_src;
if (verts_num == 0) {
return;
}
mesh_src = MOD_deform_mesh_eval_get(ctx->object, editData, mesh, nullptr);
/* TODO(@ideasman42): use edit-mode data only (remove this line). */
if (mesh_src != nullptr) {
BKE_mesh_wrapper_ensure_mdata(mesh_src);
}
laplaciansmoothModifier_do(
(LaplacianSmoothModifierData *)md, ctx->object, mesh_src, vertexCos, verts_num);
if (!ELEM(mesh_src, nullptr, mesh)) {
BKE_id_free(nullptr, mesh_src);
}
(LaplacianSmoothModifierData *)md, ctx->object, mesh, vertexCos, verts_num);
}
static void panel_draw(const bContext * /*C*/, Panel *panel)
@ -599,7 +563,7 @@ ModifierTypeInfo modifierType_LaplacianSmooth = {
/*deformVerts*/ deformVerts,
/*deformMatrices*/ nullptr,
/*deformVertsEM*/ deformVertsEM,
/*deformVertsEM*/ nullptr,
/*deformMatricesEM*/ nullptr,
/*modifyMesh*/ nullptr,
/*modifyGeometrySet*/ nullptr,

View File

@ -100,22 +100,11 @@ static void deformVerts(ModifierData *md,
int verts_num)
{
LatticeModifierData *lmd = (LatticeModifierData *)md;
Mesh *mesh_src = MOD_deform_mesh_eval_get(ctx->object, nullptr, mesh, nullptr);
MOD_previous_vcos_store(md, vertexCos); /* if next modifier needs original vertices */
BKE_lattice_deform_coords_with_mesh(lmd->object,
ctx->object,
vertexCos,
verts_num,
lmd->flag,
lmd->name,
lmd->strength,
mesh_src);
if (!ELEM(mesh_src, nullptr, mesh)) {
BKE_id_free(nullptr, mesh_src);
}
BKE_lattice_deform_coords_with_mesh(
lmd->object, ctx->object, vertexCos, verts_num, lmd->flag, lmd->name, lmd->strength, mesh);
}
static void deformVertsEM(ModifierData *md,
@ -125,7 +114,7 @@ static void deformVertsEM(ModifierData *md,
float (*vertexCos)[3],
int verts_num)
{
if (mesh != nullptr) {
if (mesh->runtime->wrapper_type == ME_WRAPPER_TYPE_MDATA) {
deformVerts(md, ctx, mesh, vertexCos, verts_num);
return;
}

View File

@ -282,44 +282,7 @@ static void deformVerts(ModifierData *md,
MeshCacheModifierData *mcmd = (MeshCacheModifierData *)md;
Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph);
Mesh *mesh_src = nullptr;
if (ctx->object->type == OB_MESH && mcmd->defgrp_name[0] != '\0') {
/* `mesh_src` is only needed for vertex groups. */
mesh_src = MOD_deform_mesh_eval_get(ctx->object, nullptr, mesh, nullptr);
}
meshcache_do(mcmd, scene, ctx->object, mesh_src, vertexCos, verts_num);
if (!ELEM(mesh_src, nullptr, mesh)) {
BKE_id_free(nullptr, mesh_src);
}
}
static void deformVertsEM(ModifierData *md,
const ModifierEvalContext *ctx,
BMEditMesh *editData,
Mesh *mesh,
float (*vertexCos)[3],
int verts_num)
{
MeshCacheModifierData *mcmd = (MeshCacheModifierData *)md;
Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph);
Mesh *mesh_src = nullptr;
if (ctx->object->type == OB_MESH && mcmd->defgrp_name[0] != '\0') {
/* `mesh_src` is only needed for vertex groups. */
mesh_src = MOD_deform_mesh_eval_get(ctx->object, editData, mesh, nullptr);
}
if (mesh_src != nullptr) {
BKE_mesh_wrapper_ensure_mdata(mesh_src);
}
meshcache_do(mcmd, scene, ctx->object, mesh_src, vertexCos, verts_num);
if (!ELEM(mesh_src, nullptr, mesh)) {
BKE_id_free(nullptr, mesh_src);
}
meshcache_do(mcmd, scene, ctx->object, mesh, vertexCos, verts_num);
}
static void panel_draw(const bContext * /*C*/, Panel *panel)
@ -417,7 +380,7 @@ ModifierTypeInfo modifierType_MeshCache = {
/*deformVerts*/ deformVerts,
/*deformMatrices*/ nullptr,
/*deformVertsEM*/ deformVertsEM,
/*deformVertsEM*/ nullptr,
/*deformMatricesEM*/ nullptr,
/*modifyMesh*/ nullptr,
/*modifyGeometrySet*/ nullptr,

View File

@ -441,36 +441,8 @@ static void deformVerts(ModifierData *md,
float (*vertexCos)[3],
int verts_num)
{
Mesh *mesh_src = MOD_deform_mesh_eval_get(ctx->object, nullptr, mesh, nullptr);
MOD_previous_vcos_store(md, vertexCos); /* if next modifier needs original vertices */
meshdeformModifier_do(md, ctx, mesh_src, vertexCos, verts_num);
if (!ELEM(mesh_src, nullptr, mesh)) {
BKE_id_free(nullptr, mesh_src);
}
}
static void deformVertsEM(ModifierData *md,
const ModifierEvalContext *ctx,
BMEditMesh *editData,
Mesh *mesh,
float (*vertexCos)[3],
int verts_num)
{
Mesh *mesh_src = MOD_deform_mesh_eval_get(ctx->object, editData, mesh, nullptr);
/* TODO(@ideasman42): use edit-mode data only (remove this line). */
if (mesh_src != nullptr) {
BKE_mesh_wrapper_ensure_mdata(mesh_src);
}
meshdeformModifier_do(md, ctx, mesh_src, vertexCos, verts_num);
if (!ELEM(mesh_src, nullptr, mesh)) {
BKE_id_free(nullptr, mesh_src);
}
meshdeformModifier_do(md, ctx, mesh, vertexCos, verts_num);
}
#define MESHDEFORM_MIN_INFLUENCE 0.00001f
@ -658,7 +630,7 @@ ModifierTypeInfo modifierType_MeshDeform = {
/*deformVerts*/ deformVerts,
/*deformMatrices*/ nullptr,
/*deformVertsEM*/ deformVertsEM,
/*deformVertsEM*/ nullptr,
/*deformMatricesEM*/ nullptr,
/*modifyMesh*/ nullptr,
/*modifyGeometrySet*/ nullptr,

View File

@ -102,7 +102,6 @@ static void deformVerts(ModifierData *md,
float (*vertexCos)[3],
int /*verts_num*/)
{
Mesh *mesh_src = mesh;
ParticleSystemModifierData *psmd = (ParticleSystemModifierData *)md;
ParticleSystem *psys = nullptr;
@ -117,14 +116,6 @@ static void deformVerts(ModifierData *md,
return;
}
if (mesh_src == nullptr) {
mesh_src = MOD_deform_mesh_eval_get(ctx->object, nullptr, nullptr, vertexCos);
if (mesh_src == nullptr) {
return;
}
BKE_mesh_orco_ensure(ctx->object, mesh_src);
}
/* Clear old evaluated mesh. */
bool had_mesh_final = (psmd->mesh_final != nullptr);
if (psmd->mesh_final) {
@ -156,7 +147,7 @@ static void deformVerts(ModifierData *md,
}
/* make new mesh */
psmd->mesh_final = BKE_mesh_copy_for_eval(mesh_src);
psmd->mesh_final = BKE_mesh_copy_for_eval(mesh);
BKE_mesh_vert_coords_apply(psmd->mesh_final, vertexCos);
BKE_mesh_tessface_ensure(psmd->mesh_final);
@ -180,7 +171,7 @@ static void deformVerts(ModifierData *md,
}
}
else {
mesh_original = mesh_src;
mesh_original = mesh;
}
if (mesh_original) {
@ -193,10 +184,6 @@ static void deformVerts(ModifierData *md,
BKE_mesh_tessface_ensure(psmd->mesh_original);
}
if (!ELEM(mesh_src, nullptr, mesh, psmd->mesh_final)) {
BKE_id_free(nullptr, mesh_src);
}
/* Report change in mesh structure.
* This is an unreliable check for the topology check, but allows some
* handy configuration like emitting particles from inside particle

View File

@ -93,59 +93,13 @@ static void deformVerts(ModifierData *md,
{
ShrinkwrapModifierData *swmd = (ShrinkwrapModifierData *)md;
Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph);
Mesh *mesh_src = nullptr;
if (ELEM(ctx->object->type, OB_MESH, OB_LATTICE) || (swmd->shrinkType == MOD_SHRINKWRAP_PROJECT))
{
/* mesh_src is needed for vgroups, but also used as ShrinkwrapCalcData.vert when projecting.
* Avoid time-consuming mesh conversion for curves when not projecting. */
mesh_src = MOD_deform_mesh_eval_get(ctx->object, nullptr, mesh, nullptr);
}
const MDeformVert *dvert = nullptr;
int defgrp_index = -1;
MOD_get_vgroup(ctx->object, mesh_src, swmd->vgroup_name, &dvert, &defgrp_index);
MOD_get_vgroup(ctx->object, mesh, swmd->vgroup_name, &dvert, &defgrp_index);
shrinkwrapModifier_deform(
swmd, ctx, scene, ctx->object, mesh_src, dvert, defgrp_index, vertexCos, verts_num);
if (!ELEM(mesh_src, nullptr, mesh)) {
BKE_id_free(nullptr, mesh_src);
}
}
static void deformVertsEM(ModifierData *md,
const ModifierEvalContext *ctx,
BMEditMesh *editData,
Mesh *mesh,
float (*vertexCos)[3],
int verts_num)
{
ShrinkwrapModifierData *swmd = (ShrinkwrapModifierData *)md;
Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph);
Mesh *mesh_src = nullptr;
if ((swmd->vgroup_name[0] != '\0') || (swmd->shrinkType == MOD_SHRINKWRAP_PROJECT)) {
mesh_src = MOD_deform_mesh_eval_get(ctx->object, editData, mesh, nullptr);
}
/* TODO(@ideasman42): use edit-mode data only (remove this line). */
if (mesh_src != nullptr) {
BKE_mesh_wrapper_ensure_mdata(mesh_src);
}
const MDeformVert *dvert = nullptr;
int defgrp_index = -1;
if (swmd->vgroup_name[0] != '\0') {
MOD_get_vgroup(ctx->object, mesh_src, swmd->vgroup_name, &dvert, &defgrp_index);
}
shrinkwrapModifier_deform(
swmd, ctx, scene, ctx->object, mesh_src, dvert, defgrp_index, vertexCos, verts_num);
if (!ELEM(mesh_src, nullptr, mesh)) {
BKE_id_free(nullptr, mesh_src);
}
swmd, ctx, scene, ctx->object, mesh, dvert, defgrp_index, vertexCos, verts_num);
}
static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphContext *ctx)
@ -264,7 +218,7 @@ ModifierTypeInfo modifierType_Shrinkwrap = {
/*deformVerts*/ deformVerts,
/*deformMatrices*/ nullptr,
/*deformVertsEM*/ deformVertsEM,
/*deformVertsEM*/ nullptr,
/*deformMatricesEM*/ nullptr,
/*modifyMesh*/ nullptr,
/*modifyGeometrySet*/ nullptr,

View File

@ -446,45 +446,7 @@ static void deformVerts(ModifierData *md,
int verts_num)
{
SimpleDeformModifierData *sdmd = (SimpleDeformModifierData *)md;
Mesh *mesh_src = nullptr;
if (ctx->object->type == OB_MESH && sdmd->vgroup_name[0] != '\0') {
/* mesh_src is only needed for vgroups. */
mesh_src = MOD_deform_mesh_eval_get(ctx->object, nullptr, mesh, nullptr);
}
SimpleDeformModifier_do(sdmd, ctx, ctx->object, mesh_src, vertexCos, verts_num);
if (!ELEM(mesh_src, nullptr, mesh)) {
BKE_id_free(nullptr, mesh_src);
}
}
static void deformVertsEM(ModifierData *md,
const ModifierEvalContext *ctx,
BMEditMesh *editData,
Mesh *mesh,
float (*vertexCos)[3],
int verts_num)
{
SimpleDeformModifierData *sdmd = (SimpleDeformModifierData *)md;
Mesh *mesh_src = nullptr;
if (ctx->object->type == OB_MESH && sdmd->vgroup_name[0] != '\0') {
/* mesh_src is only needed for vgroups. */
mesh_src = MOD_deform_mesh_eval_get(ctx->object, editData, mesh, nullptr);
}
/* TODO(@ideasman42): use edit-mode data only (remove this line). */
if (mesh_src != nullptr) {
BKE_mesh_wrapper_ensure_mdata(mesh_src);
}
SimpleDeformModifier_do(sdmd, ctx, ctx->object, mesh_src, vertexCos, verts_num);
if (!ELEM(mesh_src, nullptr, mesh)) {
BKE_id_free(nullptr, mesh_src);
}
SimpleDeformModifier_do(sdmd, ctx, ctx->object, mesh, vertexCos, verts_num);
}
static void panel_draw(const bContext * /*C*/, Panel *panel)
@ -576,7 +538,7 @@ ModifierTypeInfo modifierType_SimpleDeform = {
/*deformVerts*/ deformVerts,
/*deformMatrices*/ nullptr,
/*deformVertsEM*/ deformVertsEM,
/*deformVertsEM*/ nullptr,
/*deformMatricesEM*/ nullptr,
/*modifyMesh*/ nullptr,
/*modifyGeometrySet*/ nullptr,

View File

@ -183,37 +183,7 @@ static void deformVerts(ModifierData *md,
int verts_num)
{
SmoothModifierData *smd = (SmoothModifierData *)md;
/* mesh_src is needed for vgroups, and taking edges into account. */
Mesh *mesh_src = MOD_deform_mesh_eval_get(ctx->object, nullptr, mesh, nullptr);
smoothModifier_do(smd, ctx->object, mesh_src, vertexCos, verts_num);
if (!ELEM(mesh_src, nullptr, mesh)) {
BKE_id_free(nullptr, mesh_src);
}
}
static void deformVertsEM(ModifierData *md,
const ModifierEvalContext *ctx,
BMEditMesh *editData,
Mesh *mesh,
float (*vertexCos)[3],
int verts_num)
{
SmoothModifierData *smd = (SmoothModifierData *)md;
/* mesh_src is needed for vgroups, and taking edges into account. */
Mesh *mesh_src = MOD_deform_mesh_eval_get(ctx->object, editData, mesh, nullptr);
/* TODO(@ideasman42): use edit-mode data only (remove this line). */
BKE_mesh_wrapper_ensure_mdata(mesh_src);
smoothModifier_do(smd, ctx->object, mesh_src, vertexCos, verts_num);
if (!ELEM(mesh_src, nullptr, mesh)) {
BKE_id_free(nullptr, mesh_src);
}
smoothModifier_do(smd, ctx->object, mesh, vertexCos, verts_num);
}
static void panel_draw(const bContext * /*C*/, Panel *panel)
@ -260,7 +230,7 @@ ModifierTypeInfo modifierType_Smooth = {
/*deformVerts*/ deformVerts,
/*deformMatrices*/ nullptr,
/*deformVertsEM*/ deformVertsEM,
/*deformVertsEM*/ nullptr,
/*deformMatricesEM*/ nullptr,
/*modifyMesh*/ nullptr,
/*modifyGeometrySet*/ nullptr,

View File

@ -107,13 +107,7 @@ static void deformVerts(ModifierData *md,
}
if (mesh) {
/* Not possible to use get_mesh() in this case as we'll modify its vertices
* and get_mesh() would return 'mesh' directly. */
surmd->runtime.mesh = (Mesh *)BKE_id_copy_ex(
nullptr, (ID *)mesh, nullptr, LIB_ID_COPY_LOCALIZE);
}
else {
surmd->runtime.mesh = MOD_deform_mesh_eval_get(ctx->object, nullptr, nullptr, nullptr);
surmd->runtime.mesh = BKE_mesh_copy_for_eval(mesh);
}
if (!ctx->object->pd) {

View File

@ -1574,46 +1574,7 @@ static void deformVerts(ModifierData *md,
float (*vertexCos)[3],
int verts_num)
{
SurfaceDeformModifierData *smd = (SurfaceDeformModifierData *)md;
Mesh *mesh_src = nullptr;
if (smd->defgrp_name[0] != '\0') {
/* Only need to use mesh_src when a vgroup is used. */
mesh_src = MOD_deform_mesh_eval_get(ctx->object, nullptr, mesh, nullptr);
}
surfacedeformModifier_do(md, ctx, vertexCos, verts_num, ctx->object, mesh_src);
if (!ELEM(mesh_src, nullptr, mesh)) {
BKE_id_free(nullptr, mesh_src);
}
}
static void deformVertsEM(ModifierData *md,
const ModifierEvalContext *ctx,
BMEditMesh *em,
Mesh *mesh,
float (*vertexCos)[3],
int verts_num)
{
SurfaceDeformModifierData *smd = (SurfaceDeformModifierData *)md;
Mesh *mesh_src = nullptr;
if (smd->defgrp_name[0] != '\0') {
/* Only need to use mesh_src when a vgroup is used. */
mesh_src = MOD_deform_mesh_eval_get(ctx->object, em, mesh, nullptr);
}
/* TODO(@ideasman42): use edit-mode data only (remove this line). */
if (mesh_src != nullptr) {
BKE_mesh_wrapper_ensure_mdata(mesh_src);
}
surfacedeformModifier_do(md, ctx, vertexCos, verts_num, ctx->object, mesh_src);
if (!ELEM(mesh_src, nullptr, mesh)) {
BKE_id_free(nullptr, mesh_src);
}
surfacedeformModifier_do(md, ctx, vertexCos, verts_num, ctx->object, mesh);
}
static bool isDisabled(const Scene * /*scene*/, ModifierData *md, bool /*useRenderParams*/)
@ -1759,7 +1720,7 @@ ModifierTypeInfo modifierType_SurfaceDeform = {
/*deformVerts*/ deformVerts,
/*deformMatrices*/ nullptr,
/*deformVertsEM*/ deformVertsEM,
/*deformVertsEM*/ nullptr,
/*deformMatricesEM*/ nullptr,
/*modifyMesh*/ nullptr,
/*modifyGeometrySet*/ nullptr,

View File

@ -164,38 +164,6 @@ void MOD_previous_vcos_store(ModifierData *md, const float (*vert_coords)[3])
/* lattice/mesh modifier too */
}
Mesh *MOD_deform_mesh_eval_get(Object *ob, BMEditMesh *em, Mesh *mesh, const float (*vertexCos)[3])
{
if (mesh != nullptr) {
/* pass */
}
else if (ob->type == OB_MESH) {
if (em) {
mesh = BKE_mesh_wrapper_from_editmesh_with_coords(
em, nullptr, vertexCos, static_cast<const Mesh *>(ob->data));
}
else {
/* TODO(sybren): after modifier conversion of DM to Mesh is done, check whether
* we really need a copy here. Maybe the CoW ob->data can be directly used. */
Mesh *mesh_prior_modifiers = BKE_object_get_pre_modified_mesh(ob);
mesh = (Mesh *)BKE_id_copy_ex(
nullptr, &mesh_prior_modifiers->id, nullptr, LIB_ID_COPY_LOCALIZE);
mesh->runtime->deformed_only = true;
}
if (em != nullptr) {
/* pass */
}
/* TODO(sybren): after modifier conversion of DM to Mesh is done, check whether
* we really need vertexCos here. */
else if (vertexCos) {
BKE_mesh_vert_coords_apply(mesh, vertexCos);
}
}
return mesh;
}
void MOD_get_vgroup(const Object *ob,
const Mesh *mesh,
const char *name,

View File

@ -32,14 +32,6 @@ void MOD_get_texture_coords(MappingInfoModifierData *dmd,
void MOD_previous_vcos_store(ModifierData *md, const float (*vert_coords)[3]);
/**
* \returns a mesh if mesh == null, for deforming modifiers that need it.
*/
Mesh *MOD_deform_mesh_eval_get(Object *ob,
BMEditMesh *em,
Mesh *mesh,
const float (*vertexCos)[3]);
void MOD_get_vgroup(const Object *ob,
const Mesh *mesh,
const char *name,

View File

@ -342,45 +342,7 @@ static void deformVerts(ModifierData *md,
int verts_num)
{
WarpModifierData *wmd = (WarpModifierData *)md;
Mesh *mesh_src = nullptr;
if (wmd->defgrp_name[0] != '\0' || wmd->texture != nullptr) {
/* mesh_src is only needed for vgroups and textures. */
mesh_src = MOD_deform_mesh_eval_get(ctx->object, nullptr, mesh, nullptr);
}
warpModifier_do(wmd, ctx, mesh_src, vertexCos, verts_num);
if (!ELEM(mesh_src, nullptr, mesh)) {
BKE_id_free(nullptr, mesh_src);
}
}
static void deformVertsEM(ModifierData *md,
const ModifierEvalContext *ctx,
BMEditMesh *em,
Mesh *mesh,
float (*vertexCos)[3],
int verts_num)
{
WarpModifierData *wmd = (WarpModifierData *)md;
Mesh *mesh_src = nullptr;
if (wmd->defgrp_name[0] != '\0' || wmd->texture != nullptr) {
/* mesh_src is only needed for vgroups and textures. */
mesh_src = MOD_deform_mesh_eval_get(ctx->object, em, mesh, nullptr);
}
/* TODO(@ideasman42): use edit-mode data only (remove this line). */
if (mesh_src != nullptr) {
BKE_mesh_wrapper_ensure_mdata(mesh_src);
}
warpModifier_do(wmd, ctx, mesh_src, vertexCos, verts_num);
if (!ELEM(mesh_src, nullptr, mesh)) {
BKE_id_free(nullptr, mesh_src);
}
warpModifier_do(wmd, ctx, mesh, vertexCos, verts_num);
}
static void panel_draw(const bContext * /*C*/, Panel *panel)
@ -521,7 +483,7 @@ ModifierTypeInfo modifierType_Warp = {
/*deformVerts*/ deformVerts,
/*deformMatrices*/ nullptr,
/*deformVertsEM*/ deformVertsEM,
/*deformVertsEM*/ nullptr,
/*deformMatricesEM*/ nullptr,
/*modifyMesh*/ nullptr,
/*modifyGeometrySet*/ nullptr,

View File

@ -296,55 +296,7 @@ static void deformVerts(ModifierData *md,
int verts_num)
{
WaveModifierData *wmd = (WaveModifierData *)md;
Mesh *mesh_src = nullptr;
if (wmd->flag & MOD_WAVE_NORM) {
mesh_src = MOD_deform_mesh_eval_get(ctx->object, nullptr, mesh, vertexCos);
}
else if (wmd->texture != nullptr || wmd->defgrp_name[0] != '\0') {
mesh_src = MOD_deform_mesh_eval_get(ctx->object, nullptr, mesh, nullptr);
}
waveModifier_do(wmd, ctx, ctx->object, mesh_src, vertexCos, verts_num);
if (!ELEM(mesh_src, nullptr, mesh)) {
BKE_id_free(nullptr, mesh_src);
}
}
static void deformVertsEM(ModifierData *md,
const ModifierEvalContext *ctx,
BMEditMesh *editData,
Mesh *mesh,
float (*vertexCos)[3],
int verts_num)
{
WaveModifierData *wmd = (WaveModifierData *)md;
Mesh *mesh_src = nullptr;
if (wmd->flag & MOD_WAVE_NORM) {
mesh_src = MOD_deform_mesh_eval_get(ctx->object, editData, mesh, vertexCos);
}
else if (wmd->texture != nullptr || wmd->defgrp_name[0] != '\0') {
mesh_src = MOD_deform_mesh_eval_get(ctx->object, editData, mesh, nullptr);
}
/* TODO(@ideasman42): use edit-mode data only (remove this line). */
if (mesh_src != nullptr) {
BKE_mesh_wrapper_ensure_mdata(mesh_src);
}
waveModifier_do(wmd, ctx, ctx->object, mesh_src, vertexCos, verts_num);
if (!ELEM(mesh_src, nullptr, mesh)) {
/* Important not to free `vertexCos` owned by the caller. */
EditMeshData *edit_data = mesh_src->runtime->edit_data;
if (edit_data->vertexCos == vertexCos) {
edit_data->vertexCos = nullptr;
}
BKE_id_free(nullptr, mesh_src);
}
waveModifier_do(wmd, ctx, ctx->object, mesh, vertexCos, verts_num);
}
static void panel_draw(const bContext * /*C*/, Panel *panel)
@ -478,7 +430,7 @@ ModifierTypeInfo modifierType_Wave = {
/*deformVerts*/ deformVerts,
/*deformMatrices*/ nullptr,
/*deformVertsEM*/ deformVertsEM,
/*deformVertsEM*/ nullptr,
/*deformMatricesEM*/ nullptr,
/*modifyMesh*/ nullptr,
/*modifyGeometrySet*/ nullptr,