|
|
|
@ -240,50 +240,26 @@ static void mesh_calc_finalize(const Mesh &mesh_input, Mesh &mesh_eval)
|
|
|
|
|
* The purpose of the geometry set is to store all geometry components that are generated
|
|
|
|
|
* by modifiers to allow outputting non-mesh data from modifiers.
|
|
|
|
|
*/
|
|
|
|
|
static Mesh *modifier_modify_mesh_and_geometry_set(ModifierData *md,
|
|
|
|
|
const ModifierEvalContext &mectx,
|
|
|
|
|
Mesh *input_mesh,
|
|
|
|
|
GeometrySet &geometry_set)
|
|
|
|
|
static void modifier_modify_mesh_and_geometry_set(ModifierData *md,
|
|
|
|
|
const ModifierEvalContext &mectx,
|
|
|
|
|
GeometrySet &geometry_set)
|
|
|
|
|
{
|
|
|
|
|
Mesh *mesh_output = nullptr;
|
|
|
|
|
const ModifierTypeInfo *mti = BKE_modifier_get_info((ModifierType)md->type);
|
|
|
|
|
if (mti->modify_geometry_set == nullptr) {
|
|
|
|
|
mesh_output = BKE_modifier_modify_mesh(md, &mectx, input_mesh);
|
|
|
|
|
if (mti->modify_geometry_set) {
|
|
|
|
|
if (Mesh *mesh = geometry_set.get_mesh_for_write()) {
|
|
|
|
|
BKE_mesh_wrapper_ensure_mdata(mesh);
|
|
|
|
|
}
|
|
|
|
|
mti->modify_geometry_set(md, &mectx, &geometry_set);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
/* For performance reasons, this should be called by the modifier and/or nodes themselves at
|
|
|
|
|
* some point. */
|
|
|
|
|
BKE_mesh_wrapper_ensure_mdata(input_mesh);
|
|
|
|
|
|
|
|
|
|
/* Replace only the mesh rather than the whole component, because the entire #MeshComponent
|
|
|
|
|
* might have been replaced by data from a different object in the node tree, which means the
|
|
|
|
|
* component contains vertex group name data for that object that should not be removed. */
|
|
|
|
|
geometry_set.replace_mesh(input_mesh, GeometryOwnershipType::Editable);
|
|
|
|
|
|
|
|
|
|
/* Let the modifier change the geometry set. */
|
|
|
|
|
mti->modify_geometry_set(md, &mectx, &geometry_set);
|
|
|
|
|
|
|
|
|
|
/* Release the mesh from the geometry set again. */
|
|
|
|
|
if (geometry_set.has<MeshComponent>()) {
|
|
|
|
|
MeshComponent &mesh_component = geometry_set.get_component_for_write<MeshComponent>();
|
|
|
|
|
if (mesh_component.get() != input_mesh) {
|
|
|
|
|
/* Make sure the mesh component actually owns the mesh before taking over ownership. */
|
|
|
|
|
mesh_component.ensure_owns_direct_data();
|
|
|
|
|
}
|
|
|
|
|
mesh_output = mesh_component.release();
|
|
|
|
|
}
|
|
|
|
|
/* Need to ensure that non-mesh data is also owned by the geometry set. Otherwise it might be
|
|
|
|
|
* freed while there is still a reference to it in the geometry. */
|
|
|
|
|
geometry_set.ensure_owns_direct_data();
|
|
|
|
|
|
|
|
|
|
/* Return an empty mesh instead of null. */
|
|
|
|
|
if (mesh_output == nullptr) {
|
|
|
|
|
mesh_output = BKE_mesh_new_nomain(0, 0, 0, 0);
|
|
|
|
|
BKE_mesh_copy_parameters_for_eval(mesh_output, input_mesh);
|
|
|
|
|
if (Mesh *mesh = geometry_set.get_mesh_for_write()) {
|
|
|
|
|
geometry_set.replace_mesh(BKE_modifier_modify_mesh(md, &mectx, mesh));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return mesh_output;
|
|
|
|
|
if (!geometry_set.has_mesh()) {
|
|
|
|
|
geometry_set.replace_mesh(BKE_mesh_new_nomain(0, 0, 0, 0));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void set_rest_position(Mesh &mesh)
|
|
|
|
@ -305,30 +281,36 @@ static void set_rest_position(Mesh &mesh)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void mesh_calc_modifiers(Depsgraph &depsgraph,
|
|
|
|
|
const Scene &scene,
|
|
|
|
|
Object &ob,
|
|
|
|
|
const bool use_deform,
|
|
|
|
|
const bool need_mapping,
|
|
|
|
|
const CustomData_MeshMasks &dataMask,
|
|
|
|
|
const bool use_cache,
|
|
|
|
|
const bool allow_shared_mesh,
|
|
|
|
|
/* return args */
|
|
|
|
|
Mesh **r_deform,
|
|
|
|
|
Mesh **r_final,
|
|
|
|
|
GeometrySet **r_geometry_set)
|
|
|
|
|
static MeshEditHints &geometry_mesh_edit_hints_ensure(GeometrySet &geometry)
|
|
|
|
|
{
|
|
|
|
|
/* Input mesh shouldn't be modified. */
|
|
|
|
|
Mesh &mesh_input = *static_cast<Mesh *>(ob.data);
|
|
|
|
|
/* The final mesh is the result of calculating all enabled modifiers. */
|
|
|
|
|
Mesh *mesh = nullptr;
|
|
|
|
|
/* The result of calculating all leading deform modifiers. */
|
|
|
|
|
Mesh *mesh_deform = nullptr;
|
|
|
|
|
/* This geometry set contains the non-mesh data that might be generated by modifiers. */
|
|
|
|
|
GeometrySet geometry_set_final;
|
|
|
|
|
auto &edit_data = geometry.get_component_for_write<GeometryComponentEditData>();
|
|
|
|
|
if (!edit_data.mesh_edit_hints_) {
|
|
|
|
|
edit_data.mesh_edit_hints_ = std::make_unique<MeshEditHints>();
|
|
|
|
|
}
|
|
|
|
|
return *edit_data.mesh_edit_hints_;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void save_deform_mesh(GeometrySet &geometry)
|
|
|
|
|
{
|
|
|
|
|
MeshEditHints &edit_data = geometry_mesh_edit_hints_ensure(geometry);
|
|
|
|
|
edit_data.mesh_deform = geometry.get_component_ptr<MeshComponent>();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static GeometrySet mesh_calc_modifiers(Depsgraph &depsgraph,
|
|
|
|
|
const Scene &scene,
|
|
|
|
|
Object &ob,
|
|
|
|
|
const bool use_deform,
|
|
|
|
|
const bool need_mapping,
|
|
|
|
|
const CustomData_MeshMasks &dataMask,
|
|
|
|
|
const bool use_cache)
|
|
|
|
|
{
|
|
|
|
|
const Mesh &mesh_input = *static_cast<const Mesh *>(ob.data);
|
|
|
|
|
|
|
|
|
|
BLI_assert((mesh_input.id.tag & LIB_TAG_COPIED_ON_EVAL_FINAL_RESULT) == 0);
|
|
|
|
|
|
|
|
|
|
GeometrySet geometry_set = GeometrySet::from_mesh(const_cast<Mesh *>(&mesh_input),
|
|
|
|
|
GeometryOwnershipType::ReadOnly);
|
|
|
|
|
|
|
|
|
|
/* Mesh with constructive modifiers but no deformation applied. Tracked
|
|
|
|
|
* along with final mesh if undeformed / orco coordinates are requested
|
|
|
|
|
* for texturing. */
|
|
|
|
@ -371,11 +353,9 @@ static void mesh_calc_modifiers(Depsgraph &depsgraph,
|
|
|
|
|
BKE_modifiers_clear_errors(&ob);
|
|
|
|
|
|
|
|
|
|
if (ob.modifier_flag & OB_MODIFIER_FLAG_ADD_REST_POSITION) {
|
|
|
|
|
if (mesh == nullptr) {
|
|
|
|
|
mesh = BKE_mesh_copy_for_eval(mesh_input);
|
|
|
|
|
ASSERT_IS_VALID_MESH(mesh);
|
|
|
|
|
if (Mesh *mesh = geometry_set.get_mesh_for_write()) {
|
|
|
|
|
set_rest_position(*mesh);
|
|
|
|
|
}
|
|
|
|
|
set_rest_position(*mesh);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Apply all leading deform modifiers. */
|
|
|
|
@ -389,20 +369,17 @@ static void mesh_calc_modifiers(Depsgraph &depsgraph,
|
|
|
|
|
|
|
|
|
|
if (mti->type == ModifierTypeType::OnlyDeform && !sculpt_dyntopo) {
|
|
|
|
|
ScopedModifierTimer modifier_timer{*md};
|
|
|
|
|
if (!mesh) {
|
|
|
|
|
mesh = BKE_mesh_copy_for_eval(mesh_input);
|
|
|
|
|
ASSERT_IS_VALID_MESH(mesh);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (mti->required_data_mask) {
|
|
|
|
|
CustomData_MeshMasks mask{};
|
|
|
|
|
mti->required_data_mask(md, &mask);
|
|
|
|
|
if (mask.vmask & CD_MASK_ORCO) {
|
|
|
|
|
add_orco_mesh(ob, nullptr, *mesh, nullptr, CD_ORCO);
|
|
|
|
|
if (Mesh *mesh = geometry_set.get_mesh_for_write()) {
|
|
|
|
|
if (mti->required_data_mask) {
|
|
|
|
|
CustomData_MeshMasks mask{};
|
|
|
|
|
mti->required_data_mask(md, &mask);
|
|
|
|
|
if (mask.vmask & CD_MASK_ORCO) {
|
|
|
|
|
add_orco_mesh(ob, nullptr, *mesh, nullptr, CD_ORCO);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BKE_modifier_deform_verts(md, &mectx, mesh, mesh->vert_positions_for_write());
|
|
|
|
|
BKE_modifier_deform_verts(md, &mectx, mesh, mesh->vert_positions_for_write());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
break;
|
|
|
|
@ -412,9 +389,7 @@ static void mesh_calc_modifiers(Depsgraph &depsgraph,
|
|
|
|
|
/* Result of all leading deforming modifiers is cached for
|
|
|
|
|
* places that wish to use the original mesh but with deformed
|
|
|
|
|
* coordinates (like vertex paint). */
|
|
|
|
|
if (r_deform) {
|
|
|
|
|
mesh_deform = BKE_mesh_copy_for_eval(mesh ? *mesh : mesh_input);
|
|
|
|
|
}
|
|
|
|
|
save_deform_mesh(geometry_set);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Apply all remaining constructive and deforming modifiers. */
|
|
|
|
@ -475,42 +450,28 @@ static void mesh_calc_modifiers(Depsgraph &depsgraph,
|
|
|
|
|
ScopedModifierTimer modifier_timer{*md};
|
|
|
|
|
|
|
|
|
|
/* Add orco mesh as layer if needed by this modifier. */
|
|
|
|
|
if (mesh && mesh_orco && mti->required_data_mask) {
|
|
|
|
|
CustomData_MeshMasks mask = {0};
|
|
|
|
|
mti->required_data_mask(md, &mask);
|
|
|
|
|
if (mask.vmask & CD_MASK_ORCO) {
|
|
|
|
|
add_orco_mesh(ob, nullptr, *mesh, mesh_orco, CD_ORCO);
|
|
|
|
|
if (Mesh *mesh = geometry_set.get_mesh_for_write()) {
|
|
|
|
|
if (mesh_orco && mti->required_data_mask) {
|
|
|
|
|
CustomData_MeshMasks mask = {0};
|
|
|
|
|
mti->required_data_mask(md, &mask);
|
|
|
|
|
if (mask.vmask & CD_MASK_ORCO) {
|
|
|
|
|
add_orco_mesh(ob, nullptr, *mesh, mesh_orco, CD_ORCO);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (mti->type == ModifierTypeType::OnlyDeform) {
|
|
|
|
|
if (!mesh) {
|
|
|
|
|
mesh = BKE_mesh_copy_for_eval(mesh_input);
|
|
|
|
|
ASSERT_IS_VALID_MESH(mesh);
|
|
|
|
|
if (Mesh *mesh = geometry_set.get_mesh_for_write()) {
|
|
|
|
|
BKE_modifier_deform_verts(md, &mectx, mesh, mesh->vert_positions_for_write());
|
|
|
|
|
}
|
|
|
|
|
BKE_modifier_deform_verts(md, &mectx, mesh, mesh->vert_positions_for_write());
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
bool check_for_needs_mapping = false;
|
|
|
|
|
if (mesh != nullptr) {
|
|
|
|
|
if (have_non_onlydeform_modifiers_applied == false) {
|
|
|
|
|
/* If we only deformed, we won't have initialized #CD_ORIGINDEX.
|
|
|
|
|
* as this is the only part of the function that initializes mapping. */
|
|
|
|
|
check_for_needs_mapping = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
mesh = BKE_mesh_copy_for_eval(mesh_input);
|
|
|
|
|
ASSERT_IS_VALID_MESH(mesh);
|
|
|
|
|
check_for_needs_mapping = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
have_non_onlydeform_modifiers_applied = true;
|
|
|
|
|
|
|
|
|
|
/* determine which data layers are needed by following modifiers */
|
|
|
|
|
CustomData_MeshMasks nextmask = md_datamask->next ? md_datamask->next->mask : final_datamask;
|
|
|
|
|
|
|
|
|
|
if (check_for_needs_mapping) {
|
|
|
|
|
if (Mesh *mesh = geometry_set.get_mesh_for_write()) {
|
|
|
|
|
/* Initialize original indices the first time we evaluate a
|
|
|
|
|
* constructive modifier. Modifiers will then do mapping mostly
|
|
|
|
|
* automatic by copying them through CustomData_copy_data along
|
|
|
|
@ -541,45 +502,35 @@ static void mesh_calc_modifiers(Depsgraph &depsgraph,
|
|
|
|
|
mesh->faces_num,
|
|
|
|
|
0);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* set the Mesh to only copy needed data */
|
|
|
|
|
CustomData_MeshMasks mask = md_datamask->mask;
|
|
|
|
|
/* needMapping check here fixes bug #28112, otherwise it's
|
|
|
|
|
* possible that it won't be copied */
|
|
|
|
|
CustomData_MeshMasks_update(&mask, &append_mask);
|
|
|
|
|
if (need_mapping) {
|
|
|
|
|
mask.vmask |= CD_MASK_ORIGINDEX;
|
|
|
|
|
mask.emask |= CD_MASK_ORIGINDEX;
|
|
|
|
|
mask.pmask |= CD_MASK_ORIGINDEX;
|
|
|
|
|
}
|
|
|
|
|
mesh_set_only_copy(mesh, &mask);
|
|
|
|
|
/* set the Mesh to only copy needed data */
|
|
|
|
|
CustomData_MeshMasks mask = md_datamask->mask;
|
|
|
|
|
/* needMapping check here fixes bug #28112, otherwise it's
|
|
|
|
|
* possible that it won't be copied */
|
|
|
|
|
CustomData_MeshMasks_update(&mask, &append_mask);
|
|
|
|
|
if (need_mapping) {
|
|
|
|
|
mask.vmask |= CD_MASK_ORIGINDEX;
|
|
|
|
|
mask.emask |= CD_MASK_ORIGINDEX;
|
|
|
|
|
mask.pmask |= CD_MASK_ORIGINDEX;
|
|
|
|
|
}
|
|
|
|
|
mesh_set_only_copy(mesh, &mask);
|
|
|
|
|
|
|
|
|
|
/* add cloth rest shape key if needed */
|
|
|
|
|
if (mask.vmask & CD_MASK_CLOTH_ORCO) {
|
|
|
|
|
add_orco_mesh(ob, nullptr, *mesh, mesh_orco, CD_CLOTH_ORCO);
|
|
|
|
|
}
|
|
|
|
|
/* add cloth rest shape key if needed */
|
|
|
|
|
if (mask.vmask & CD_MASK_CLOTH_ORCO) {
|
|
|
|
|
add_orco_mesh(ob, nullptr, *mesh, mesh_orco, CD_CLOTH_ORCO);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* add an origspace layer if needed */
|
|
|
|
|
if ((md_datamask->mask.lmask) & CD_MASK_ORIGSPACE_MLOOP) {
|
|
|
|
|
if (!CustomData_has_layer(&mesh->corner_data, CD_ORIGSPACE_MLOOP)) {
|
|
|
|
|
CustomData_add_layer(
|
|
|
|
|
&mesh->corner_data, CD_ORIGSPACE_MLOOP, CD_SET_DEFAULT, mesh->corners_num);
|
|
|
|
|
mesh_init_origspace(*mesh);
|
|
|
|
|
/* add an origspace layer if needed */
|
|
|
|
|
if ((md_datamask->mask.lmask) & CD_MASK_ORIGSPACE_MLOOP) {
|
|
|
|
|
if (!CustomData_has_layer(&mesh->corner_data, CD_ORIGSPACE_MLOOP)) {
|
|
|
|
|
CustomData_add_layer(
|
|
|
|
|
&mesh->corner_data, CD_ORIGSPACE_MLOOP, CD_SET_DEFAULT, mesh->corners_num);
|
|
|
|
|
mesh_init_origspace(*mesh);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Mesh *mesh_next = modifier_modify_mesh_and_geometry_set(md, mectx, mesh, geometry_set_final);
|
|
|
|
|
ASSERT_IS_VALID_MESH(mesh_next);
|
|
|
|
|
|
|
|
|
|
if (mesh_next) {
|
|
|
|
|
/* if the modifier returned a new mesh, release the old one */
|
|
|
|
|
if (mesh != mesh_next) {
|
|
|
|
|
BLI_assert(mesh != &mesh_input);
|
|
|
|
|
BKE_id_free(nullptr, mesh);
|
|
|
|
|
}
|
|
|
|
|
mesh = mesh_next;
|
|
|
|
|
}
|
|
|
|
|
modifier_modify_mesh_and_geometry_set(md, mectx, geometry_set);
|
|
|
|
|
|
|
|
|
|
/* create an orco mesh in parallel */
|
|
|
|
|
if (nextmask.vmask & CD_MASK_ORCO) {
|
|
|
|
@ -600,17 +551,14 @@ static void mesh_calc_modifiers(Depsgraph &depsgraph,
|
|
|
|
|
CustomData_MeshMasks_update(&temp_cddata_masks, &nextmask);
|
|
|
|
|
mesh_set_only_copy(mesh_orco, &temp_cddata_masks);
|
|
|
|
|
|
|
|
|
|
mesh_next = BKE_modifier_modify_mesh(md, &mectx_orco, mesh_orco);
|
|
|
|
|
ASSERT_IS_VALID_MESH(mesh_next);
|
|
|
|
|
|
|
|
|
|
if (mesh_next) {
|
|
|
|
|
/* if the modifier returned a new mesh, release the old one */
|
|
|
|
|
if (mesh_orco != mesh_next) {
|
|
|
|
|
BLI_assert(mesh_orco != &mesh_input);
|
|
|
|
|
Mesh *mesh_orco_new = BKE_modifier_modify_mesh(md, &mectx_orco, mesh_orco);
|
|
|
|
|
ASSERT_IS_VALID_MESH(mesh_orco_new);
|
|
|
|
|
if (mesh_orco_new) {
|
|
|
|
|
if (mesh_orco != mesh_orco_new) {
|
|
|
|
|
BLI_assert(mesh_orco != mesh_input);
|
|
|
|
|
BKE_id_free(nullptr, mesh_orco);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
mesh_orco = mesh_next;
|
|
|
|
|
mesh_orco = mesh_orco_new;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -626,21 +574,23 @@ static void mesh_calc_modifiers(Depsgraph &depsgraph,
|
|
|
|
|
nextmask.pmask |= CD_MASK_ORIGINDEX;
|
|
|
|
|
mesh_set_only_copy(mesh_orco_cloth, &nextmask);
|
|
|
|
|
|
|
|
|
|
mesh_next = BKE_modifier_modify_mesh(md, &mectx_orco, mesh_orco_cloth);
|
|
|
|
|
ASSERT_IS_VALID_MESH(mesh_next);
|
|
|
|
|
|
|
|
|
|
if (mesh_next) {
|
|
|
|
|
/* if the modifier returned a new mesh, release the old one */
|
|
|
|
|
if (mesh_orco_cloth != mesh_next) {
|
|
|
|
|
BLI_assert(mesh_orco != &mesh_input);
|
|
|
|
|
Mesh *mesh_orco_cloth_new = BKE_modifier_modify_mesh(md, &mectx_orco, mesh_orco_cloth);
|
|
|
|
|
ASSERT_IS_VALID_MESH(mesh_orco_cloth_new);
|
|
|
|
|
if (mesh_orco_cloth_new) {
|
|
|
|
|
if (mesh_orco_cloth != mesh_orco_cloth_new) {
|
|
|
|
|
BLI_assert(mesh_orco != mesh_input);
|
|
|
|
|
BKE_id_free(nullptr, mesh_orco_cloth);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
mesh_orco_cloth = mesh_next;
|
|
|
|
|
mesh_orco_cloth = mesh_orco_cloth_new;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
mesh->runtime->deformed_only = false;
|
|
|
|
|
if (const Mesh *mesh = geometry_set.get_mesh()) {
|
|
|
|
|
if (mesh->runtime->deformed_only) {
|
|
|
|
|
Mesh *mesh_mut = geometry_set.get_mesh_for_write();
|
|
|
|
|
mesh_mut->runtime->deformed_only = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (sculpt_mode && md->type == eModifierType_Multires) {
|
|
|
|
@ -654,32 +604,6 @@ static void mesh_calc_modifiers(Depsgraph &depsgraph,
|
|
|
|
|
BKE_modifier_free_temporary_data(md);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (mesh == nullptr) {
|
|
|
|
|
if (allow_shared_mesh) {
|
|
|
|
|
mesh = &mesh_input;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
mesh = BKE_mesh_copy_for_eval(mesh_input);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Denotes whether the object which the modifier stack came from owns the mesh or whether the
|
|
|
|
|
* mesh is shared across multiple objects since there are no effective modifiers. */
|
|
|
|
|
const bool is_own_mesh = (mesh != &mesh_input);
|
|
|
|
|
|
|
|
|
|
/* Add orco coordinates to final and deformed mesh if requested. */
|
|
|
|
|
if (final_datamask.vmask & CD_MASK_ORCO) {
|
|
|
|
|
/* No need in ORCO layer if the mesh was not deformed or modified: undeformed mesh in this case
|
|
|
|
|
* matches input mesh. */
|
|
|
|
|
if (is_own_mesh) {
|
|
|
|
|
add_orco_mesh(ob, nullptr, *mesh, mesh_orco, CD_ORCO);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (mesh_deform) {
|
|
|
|
|
add_orco_mesh(ob, nullptr, *mesh_deform, nullptr, CD_ORCO);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (mesh_orco) {
|
|
|
|
|
BKE_id_free(nullptr, mesh_orco);
|
|
|
|
|
}
|
|
|
|
@ -689,44 +613,14 @@ static void mesh_calc_modifiers(Depsgraph &depsgraph,
|
|
|
|
|
|
|
|
|
|
/* Remove temporary data layer only needed for modifier evaluation.
|
|
|
|
|
* Save some memory, and ensure GPU subdivision does not need to deal with this. */
|
|
|
|
|
CustomData_free_layers(&mesh->vert_data, CD_CLOTH_ORCO, mesh->verts_num);
|
|
|
|
|
|
|
|
|
|
/* Compute normals. */
|
|
|
|
|
if (is_own_mesh) {
|
|
|
|
|
mesh_calc_finalize(mesh_input, *mesh);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
MeshRuntime *runtime = mesh_input.runtime;
|
|
|
|
|
if (runtime->mesh_eval == nullptr) {
|
|
|
|
|
std::lock_guard lock{mesh_input.runtime->eval_mutex};
|
|
|
|
|
if (runtime->mesh_eval == nullptr) {
|
|
|
|
|
/* Not yet finalized by any instance, do it now
|
|
|
|
|
* Isolate since computing normals is multithreaded and we are holding a lock. */
|
|
|
|
|
threading::isolate_task([&] {
|
|
|
|
|
mesh = BKE_mesh_copy_for_eval(mesh_input);
|
|
|
|
|
mesh_calc_finalize(mesh_input, *mesh);
|
|
|
|
|
runtime->mesh_eval = mesh;
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
/* Already finalized by another instance, reuse. */
|
|
|
|
|
mesh = runtime->mesh_eval;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
/* Already finalized by another instance, reuse. */
|
|
|
|
|
mesh = runtime->mesh_eval;
|
|
|
|
|
if (const Mesh *mesh = geometry_set.get_mesh()) {
|
|
|
|
|
if (CustomData_has_layer(&mesh->vert_data, CD_CLOTH_ORCO)) {
|
|
|
|
|
Mesh *mesh_mut = geometry_set.get_mesh_for_write();
|
|
|
|
|
CustomData_free_layers(&mesh_mut->vert_data, CD_CLOTH_ORCO, mesh_mut->verts_num);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Return final mesh */
|
|
|
|
|
*r_final = mesh;
|
|
|
|
|
if (r_deform) {
|
|
|
|
|
*r_deform = mesh_deform;
|
|
|
|
|
}
|
|
|
|
|
if (r_geometry_set) {
|
|
|
|
|
*r_geometry_set = new GeometrySet(std::move(geometry_set_final));
|
|
|
|
|
}
|
|
|
|
|
return geometry_set;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool editbmesh_modifier_is_enabled(const Scene *scene,
|
|
|
|
@ -766,21 +660,19 @@ static MutableSpan<float3> mesh_wrapper_vert_coords_ensure_for_write(Mesh *mesh)
|
|
|
|
|
return {};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void editbmesh_calc_modifiers(Depsgraph &depsgraph,
|
|
|
|
|
const Scene &scene,
|
|
|
|
|
Object &ob,
|
|
|
|
|
const CustomData_MeshMasks &dataMask,
|
|
|
|
|
/* return args */
|
|
|
|
|
Mesh **r_cage,
|
|
|
|
|
Mesh **r_final,
|
|
|
|
|
GeometrySet **r_geometry_set)
|
|
|
|
|
static void save_cage_mesh(GeometrySet &geometry)
|
|
|
|
|
{
|
|
|
|
|
Mesh &mesh_input = *static_cast<Mesh *>(ob.data);
|
|
|
|
|
BMEditMesh &em_input = *mesh_input.runtime->edit_mesh;
|
|
|
|
|
MeshEditHints &edit_data = geometry_mesh_edit_hints_ensure(geometry);
|
|
|
|
|
edit_data.mesh_cage = geometry.get_component_ptr<MeshComponent>();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Mesh *mesh_cage = nullptr;
|
|
|
|
|
/* This geometry set contains the non-mesh data that might be generated by modifiers. */
|
|
|
|
|
GeometrySet geometry_set_final;
|
|
|
|
|
static GeometrySet editbmesh_calc_modifiers(Depsgraph &depsgraph,
|
|
|
|
|
const Scene &scene,
|
|
|
|
|
Object &ob,
|
|
|
|
|
const CustomData_MeshMasks &dataMask)
|
|
|
|
|
{
|
|
|
|
|
const Mesh &mesh_input = *static_cast<const Mesh *>(ob.data);
|
|
|
|
|
const BMEditMesh &em_input = *mesh_input.runtime->edit_mesh;
|
|
|
|
|
|
|
|
|
|
/* Mesh with constructive modifiers but no deformation applied. Tracked
|
|
|
|
|
* along with final mesh if undeformed / orco coordinates are requested
|
|
|
|
@ -810,12 +702,12 @@ static void editbmesh_calc_modifiers(Depsgraph &depsgraph,
|
|
|
|
|
CDMaskLink *md_datamask = datamasks;
|
|
|
|
|
CustomData_MeshMasks append_mask = CD_MASK_BAREMESH;
|
|
|
|
|
|
|
|
|
|
Mesh *mesh = BKE_mesh_wrapper_from_editmesh(
|
|
|
|
|
mesh_input.runtime->edit_mesh, &final_datamask, &mesh_input);
|
|
|
|
|
GeometrySet geometry_set = GeometrySet::from_mesh(
|
|
|
|
|
BKE_mesh_wrapper_from_editmesh(mesh_input.runtime->edit_mesh, &final_datamask, &mesh_input));
|
|
|
|
|
|
|
|
|
|
int cageIndex = BKE_modifiers_get_cage_index(&scene, &ob, nullptr, true);
|
|
|
|
|
if (r_cage && cageIndex == -1) {
|
|
|
|
|
mesh_cage = mesh;
|
|
|
|
|
if (cageIndex == -1) {
|
|
|
|
|
save_cage_mesh(geometry_set);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* The mesh from edit mode should not have any original index layers already, since those
|
|
|
|
@ -828,8 +720,10 @@ static void editbmesh_calc_modifiers(Depsgraph &depsgraph,
|
|
|
|
|
BKE_modifiers_clear_errors(&ob);
|
|
|
|
|
|
|
|
|
|
if (ob.modifier_flag & OB_MODIFIER_FLAG_ADD_REST_POSITION) {
|
|
|
|
|
BKE_mesh_wrapper_ensure_mdata(mesh);
|
|
|
|
|
set_rest_position(*mesh);
|
|
|
|
|
if (Mesh *mesh = geometry_set.get_mesh_for_write()) {
|
|
|
|
|
BKE_mesh_wrapper_ensure_mdata(mesh);
|
|
|
|
|
set_rest_position(*mesh);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool non_deform_modifier_applied = false;
|
|
|
|
@ -846,35 +740,24 @@ static void editbmesh_calc_modifiers(Depsgraph &depsgraph,
|
|
|
|
|
CustomData_MeshMasks mask = {0};
|
|
|
|
|
mti->required_data_mask(md, &mask);
|
|
|
|
|
if (mask.vmask & CD_MASK_ORCO) {
|
|
|
|
|
add_orco_mesh(ob, &em_input, *mesh, mesh_orco, CD_ORCO);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (mesh == 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 = BKE_mesh_copy_for_eval(*mesh);
|
|
|
|
|
if (mesh_cage->runtime->edit_mesh) {
|
|
|
|
|
mesh->runtime->edit_mesh = mesh_cage->runtime->edit_mesh;
|
|
|
|
|
mesh->runtime->is_original_bmesh = true;
|
|
|
|
|
if (mesh_cage->runtime->edit_data) {
|
|
|
|
|
mesh->runtime->edit_data = std::make_unique<EditMeshData>(
|
|
|
|
|
*mesh_cage->runtime->edit_data);
|
|
|
|
|
if (Mesh *mesh = geometry_set.get_mesh_for_write()) {
|
|
|
|
|
add_orco_mesh(ob, &em_input, *mesh, mesh_orco, CD_ORCO);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (mti->type == ModifierTypeType::OnlyDeform) {
|
|
|
|
|
if (mti->deform_verts_EM) {
|
|
|
|
|
BKE_modifier_deform_vertsEM(
|
|
|
|
|
md, &mectx, &em_input, mesh, mesh_wrapper_vert_coords_ensure_for_write(mesh));
|
|
|
|
|
BKE_mesh_wrapper_tag_positions_changed(mesh);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
BKE_mesh_wrapper_ensure_mdata(mesh);
|
|
|
|
|
BKE_modifier_deform_verts(md, &mectx, mesh, mesh->vert_positions_for_write());
|
|
|
|
|
mesh->tag_positions_changed();
|
|
|
|
|
if (Mesh *mesh = geometry_set.get_mesh_for_write()) {
|
|
|
|
|
if (mti->deform_verts_EM) {
|
|
|
|
|
BKE_modifier_deform_vertsEM(
|
|
|
|
|
md, &mectx, &em_input, mesh, mesh_wrapper_vert_coords_ensure_for_write(mesh));
|
|
|
|
|
BKE_mesh_wrapper_tag_positions_changed(mesh);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
BKE_mesh_wrapper_ensure_mdata(mesh);
|
|
|
|
|
BKE_modifier_deform_verts(md, &mectx, mesh, mesh->vert_positions_for_write());
|
|
|
|
|
mesh->tag_positions_changed();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
@ -914,30 +797,25 @@ static void editbmesh_calc_modifiers(Depsgraph &depsgraph,
|
|
|
|
|
mask.emask |= CD_MASK_ORIGINDEX;
|
|
|
|
|
mask.pmask |= CD_MASK_ORIGINDEX;
|
|
|
|
|
|
|
|
|
|
mesh_set_only_copy(mesh, &mask);
|
|
|
|
|
if (Mesh *mesh = geometry_set.get_mesh_for_write()) {
|
|
|
|
|
mesh_set_only_copy(mesh, &mask);
|
|
|
|
|
|
|
|
|
|
if (mask.lmask & CD_MASK_ORIGSPACE_MLOOP) {
|
|
|
|
|
if (!CustomData_has_layer(&mesh->corner_data, CD_ORIGSPACE_MLOOP)) {
|
|
|
|
|
CustomData_add_layer(
|
|
|
|
|
&mesh->corner_data, CD_ORIGSPACE_MLOOP, CD_SET_DEFAULT, mesh->corners_num);
|
|
|
|
|
mesh_init_origspace(*mesh);
|
|
|
|
|
if (mask.lmask & CD_MASK_ORIGSPACE_MLOOP) {
|
|
|
|
|
if (!CustomData_has_layer(&mesh->corner_data, CD_ORIGSPACE_MLOOP)) {
|
|
|
|
|
CustomData_add_layer(
|
|
|
|
|
&mesh->corner_data, CD_ORIGSPACE_MLOOP, CD_SET_DEFAULT, mesh->corners_num);
|
|
|
|
|
mesh_init_origspace(*mesh);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
mesh->runtime->deformed_only = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Mesh *mesh_next = modifier_modify_mesh_and_geometry_set(md, mectx, mesh, geometry_set_final);
|
|
|
|
|
ASSERT_IS_VALID_MESH(mesh_next);
|
|
|
|
|
|
|
|
|
|
if (mesh_next) {
|
|
|
|
|
if (mesh != mesh_next) {
|
|
|
|
|
BKE_id_free(nullptr, mesh);
|
|
|
|
|
}
|
|
|
|
|
mesh = mesh_next;
|
|
|
|
|
}
|
|
|
|
|
mesh->runtime->deformed_only = false;
|
|
|
|
|
modifier_modify_mesh_and_geometry_set(md, mectx, geometry_set);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (r_cage && i == cageIndex) {
|
|
|
|
|
mesh_cage = mesh;
|
|
|
|
|
if (i == cageIndex) {
|
|
|
|
|
save_cage_mesh(geometry_set);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -945,24 +823,18 @@ static void editbmesh_calc_modifiers(Depsgraph &depsgraph,
|
|
|
|
|
|
|
|
|
|
/* 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. */
|
|
|
|
|
BKE_mesh_wrapper_ensure_mdata(mesh);
|
|
|
|
|
|
|
|
|
|
add_orco_mesh(ob, &em_input, *mesh, mesh_orco, CD_ORCO);
|
|
|
|
|
if (Mesh *mesh = geometry_set.get_mesh_for_write()) {
|
|
|
|
|
/* FIXME(@ideasman42): avoid the need to convert to mesh data just to add an orco layer. */
|
|
|
|
|
BKE_mesh_wrapper_ensure_mdata(mesh);
|
|
|
|
|
add_orco_mesh(ob, &em_input, *mesh, mesh_orco, CD_ORCO);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (mesh_orco) {
|
|
|
|
|
BKE_id_free(nullptr, mesh_orco);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Return final mesh. */
|
|
|
|
|
*r_final = mesh;
|
|
|
|
|
if (r_cage) {
|
|
|
|
|
*r_cage = mesh_cage;
|
|
|
|
|
}
|
|
|
|
|
if (r_geometry_set) {
|
|
|
|
|
*r_geometry_set = new GeometrySet(std::move(geometry_set_final));
|
|
|
|
|
}
|
|
|
|
|
return geometry_set;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void mesh_build_extra_data(const Depsgraph &depsgraph,
|
|
|
|
@ -982,53 +854,28 @@ static void mesh_build_data(Depsgraph &depsgraph,
|
|
|
|
|
const CustomData_MeshMasks &dataMask,
|
|
|
|
|
const bool need_mapping)
|
|
|
|
|
{
|
|
|
|
|
#if 0 /* XXX This is already taken care of in #mesh_calc_modifiers... */
|
|
|
|
|
if (need_mapping) {
|
|
|
|
|
/* Also add the flag so that it is recorded in lastDataMask. */
|
|
|
|
|
dataMask->vmask |= CD_MASK_ORIGINDEX;
|
|
|
|
|
dataMask->emask |= CD_MASK_ORIGINDEX;
|
|
|
|
|
dataMask->pmask |= CD_MASK_ORIGINDEX;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
const Mesh &mesh_input = *static_cast<const Mesh *>(ob.data);
|
|
|
|
|
GeometrySet geometry_set = mesh_calc_modifiers(
|
|
|
|
|
depsgraph, scene, ob, true, need_mapping, dataMask, true);
|
|
|
|
|
const Mesh *mesh_eval = geometry_set.get_mesh();
|
|
|
|
|
|
|
|
|
|
Mesh *mesh_eval = nullptr, *mesh_deform_eval = nullptr;
|
|
|
|
|
GeometrySet *geometry_set_eval = nullptr;
|
|
|
|
|
mesh_calc_modifiers(depsgraph,
|
|
|
|
|
scene,
|
|
|
|
|
ob,
|
|
|
|
|
true,
|
|
|
|
|
need_mapping,
|
|
|
|
|
dataMask,
|
|
|
|
|
true,
|
|
|
|
|
true,
|
|
|
|
|
&mesh_deform_eval,
|
|
|
|
|
&mesh_eval,
|
|
|
|
|
&geometry_set_eval);
|
|
|
|
|
BKE_object_eval_assign_data(&ob, &const_cast<ID &>(mesh_eval->id), false);
|
|
|
|
|
ob.runtime->geometry_set_eval = new GeometrySet(std::move(geometry_set));
|
|
|
|
|
|
|
|
|
|
/* The modifier stack evaluation is storing result in mesh->runtime.mesh_eval, but this result
|
|
|
|
|
* is not guaranteed to be owned by object.
|
|
|
|
|
*
|
|
|
|
|
* Check ownership now, since later on we can not go to a mesh owned by someone else via
|
|
|
|
|
* 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);
|
|
|
|
|
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. */
|
|
|
|
|
MeshComponent &mesh_component = geometry_set_eval->get_component_for_write<MeshComponent>();
|
|
|
|
|
mesh_component.replace(mesh_eval, GeometryOwnershipType::Editable);
|
|
|
|
|
ob.runtime->geometry_set_eval = geometry_set_eval;
|
|
|
|
|
|
|
|
|
|
ob.runtime->mesh_deform_eval = mesh_deform_eval;
|
|
|
|
|
ob.runtime->last_data_mask = dataMask;
|
|
|
|
|
ob.runtime->last_need_mapping = need_mapping;
|
|
|
|
|
|
|
|
|
|
/* Make sure that drivers can target shapekey properties.
|
|
|
|
|
* Note that this causes a potential inconsistency, as the shapekey may have a
|
|
|
|
|
* different topology than the evaluated mesh. */
|
|
|
|
|
BLI_assert(mesh->key == nullptr || DEG_is_evaluated_id(&mesh->key->id));
|
|
|
|
|
mesh_eval->key = mesh->key;
|
|
|
|
|
if (Key *key = mesh_input.key) {
|
|
|
|
|
BLI_assert(DEG_is_evaluated_id(&key->id));
|
|
|
|
|
if (geometry_set.get_mesh() != &mesh_input) {
|
|
|
|
|
if (Mesh *mesh = geometry_set.get_mesh_for_write()) {
|
|
|
|
|
mesh->key = key;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ((ob.mode & OB_MODE_ALL_SCULPT) && ob.sculpt) {
|
|
|
|
|
if (DEG_is_active(&depsgraph)) {
|
|
|
|
@ -1044,43 +891,52 @@ static void editbmesh_build_data(Depsgraph &depsgraph,
|
|
|
|
|
Object &obedit,
|
|
|
|
|
CustomData_MeshMasks &dataMask)
|
|
|
|
|
{
|
|
|
|
|
Mesh *mesh = static_cast<Mesh *>(obedit.data);
|
|
|
|
|
Mesh *me_cage;
|
|
|
|
|
Mesh *me_final;
|
|
|
|
|
GeometrySet *non_mesh_components;
|
|
|
|
|
const Mesh &mesh_input = *static_cast<const Mesh *>(obedit.data);
|
|
|
|
|
|
|
|
|
|
editbmesh_calc_modifiers(
|
|
|
|
|
depsgraph, scene, obedit, dataMask, &me_cage, &me_final, &non_mesh_components);
|
|
|
|
|
|
|
|
|
|
/* The modifier stack result is expected to share edit mesh pointer with the input.
|
|
|
|
|
* This is similar `mesh_calc_finalize()`. */
|
|
|
|
|
BKE_mesh_free_editmesh(me_final);
|
|
|
|
|
BKE_mesh_free_editmesh(me_cage);
|
|
|
|
|
me_final->runtime->edit_mesh = me_cage->runtime->edit_mesh = mesh->runtime->edit_mesh;
|
|
|
|
|
GeometrySet geometry_set = editbmesh_calc_modifiers(depsgraph, scene, obedit, dataMask);
|
|
|
|
|
|
|
|
|
|
/* Object has edit_mesh but is not in edit mode (object shares mesh datablock with another object
|
|
|
|
|
* with is in edit mode).
|
|
|
|
|
* Convert edit mesh to mesh until the draw manager can draw mesh wrapper which is not in the
|
|
|
|
|
* edit mode. */
|
|
|
|
|
if (!(obedit.mode & OB_MODE_EDIT)) {
|
|
|
|
|
BKE_mesh_wrapper_ensure_mdata(me_final);
|
|
|
|
|
if (me_final != me_cage) {
|
|
|
|
|
BKE_mesh_wrapper_ensure_mdata(me_cage);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
// if (!(obedit.mode & OB_MODE_EDIT)) {
|
|
|
|
|
// MeshEditHints &edit_hints =
|
|
|
|
|
// *geometry_set.get_component_for_write<GeometryComponentEditData>().mesh_edit_hints_;
|
|
|
|
|
// const bool cage_mesh_shared = edit_hints.mesh_cage->get() == geometry_set.get_mesh();
|
|
|
|
|
// Mesh *mesh = geometry_set.get_mesh_for_write();
|
|
|
|
|
// BKE_mesh_wrapper_ensure_mdata(mesh);
|
|
|
|
|
// if (cage_mesh_shared) {
|
|
|
|
|
// save_cage_mesh(geometry_set);
|
|
|
|
|
// }
|
|
|
|
|
// else {
|
|
|
|
|
// if (edit_hints.mesh_cage->is_mutable()) {
|
|
|
|
|
// edit_hints.mesh_cage->tag_ensured_mutable();
|
|
|
|
|
// }
|
|
|
|
|
// else {
|
|
|
|
|
// Mesh *mesh_copy = BKE_mesh_copy_for_eval(*edit_hints.mesh_cage->get());
|
|
|
|
|
// MeshComponent *copy = new MeshComponent(mesh_copy);
|
|
|
|
|
// edit_hints.mesh_cage = ImplicitSharingPtr<MeshComponent>(copy);
|
|
|
|
|
// }
|
|
|
|
|
// Mesh *mesh_cage = const_cast<MeshComponent &>(*edit_hints.mesh_cage).get_for_write();
|
|
|
|
|
// BKE_mesh_wrapper_ensure_mdata(mesh_cage);
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
/* Make sure that drivers can target shapekey properties.
|
|
|
|
|
* Note that this causes a potential inconsistency, as the shapekey may have a
|
|
|
|
|
* different topology than the evaluated mesh. */
|
|
|
|
|
BLI_assert(mesh->key == nullptr || DEG_is_evaluated_id(&mesh->key->id));
|
|
|
|
|
me_final->key = mesh->key;
|
|
|
|
|
if (Key *key = mesh_input.key) {
|
|
|
|
|
BLI_assert(DEG_is_evaluated_id(&key->id));
|
|
|
|
|
if (Mesh *mesh = geometry_set.get_mesh_for_write()) {
|
|
|
|
|
mesh->key = key;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
obedit.runtime->editmesh_eval_cage = me_cage;
|
|
|
|
|
Mesh *mesh_final = const_cast<Mesh *>(geometry_set.get_mesh());
|
|
|
|
|
|
|
|
|
|
obedit.runtime->geometry_set_eval = non_mesh_components;
|
|
|
|
|
BKE_object_eval_assign_data(&obedit, &mesh_final->id, false);
|
|
|
|
|
|
|
|
|
|
obedit.runtime->geometry_set_eval = new GeometrySet(std::move(geometry_set));
|
|
|
|
|
|
|
|
|
|
obedit.runtime->last_data_mask = dataMask;
|
|
|
|
|
}
|
|
|
|
@ -1202,7 +1058,7 @@ Mesh *mesh_get_eval_deform(Depsgraph *depsgraph,
|
|
|
|
|
CustomData_MeshMasks cddata_masks = *dataMask;
|
|
|
|
|
object_get_datamask(*depsgraph, *ob, cddata_masks, &need_mapping);
|
|
|
|
|
|
|
|
|
|
if (!ob->runtime->mesh_deform_eval ||
|
|
|
|
|
if (!BKE_object_get_mesh_deform_eval(ob) ||
|
|
|
|
|
!CustomData_MeshMasks_are_matching(&(ob->runtime->last_data_mask), &cddata_masks) ||
|
|
|
|
|
(need_mapping && !ob->runtime->last_need_mapping))
|
|
|
|
|
{
|
|
|
|
@ -1211,7 +1067,7 @@ Mesh *mesh_get_eval_deform(Depsgraph *depsgraph,
|
|
|
|
|
*depsgraph, *scene, *ob, cddata_masks, need_mapping || ob->runtime->last_need_mapping);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ob->runtime->mesh_deform_eval;
|
|
|
|
|
return const_cast<Mesh *>(BKE_object_get_mesh_deform_eval(ob));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Mesh *mesh_create_eval_final(Depsgraph *depsgraph,
|
|
|
|
@ -1219,10 +1075,10 @@ Mesh *mesh_create_eval_final(Depsgraph *depsgraph,
|
|
|
|
|
Object *ob,
|
|
|
|
|
const CustomData_MeshMasks *dataMask)
|
|
|
|
|
{
|
|
|
|
|
Mesh *result;
|
|
|
|
|
mesh_calc_modifiers(
|
|
|
|
|
*depsgraph, *scene, *ob, true, false, *dataMask, false, false, nullptr, &result, nullptr);
|
|
|
|
|
return result;
|
|
|
|
|
GeometrySet geometry_set = mesh_calc_modifiers(
|
|
|
|
|
*depsgraph, *scene, *ob, true, false, *dataMask, false);
|
|
|
|
|
geometry_set.ensure_owns_direct_data();
|
|
|
|
|
return geometry_set.get_component_for_write<MeshComponent>().release();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Mesh *mesh_create_eval_no_deform(Depsgraph *depsgraph,
|
|
|
|
@ -1230,10 +1086,10 @@ Mesh *mesh_create_eval_no_deform(Depsgraph *depsgraph,
|
|
|
|
|
Object *ob,
|
|
|
|
|
const CustomData_MeshMasks *dataMask)
|
|
|
|
|
{
|
|
|
|
|
Mesh *result;
|
|
|
|
|
mesh_calc_modifiers(
|
|
|
|
|
*depsgraph, *scene, *ob, false, false, *dataMask, false, false, nullptr, &result, nullptr);
|
|
|
|
|
return result;
|
|
|
|
|
GeometrySet geometry_set = mesh_calc_modifiers(
|
|
|
|
|
*depsgraph, *scene, *ob, false, false, *dataMask, false);
|
|
|
|
|
geometry_set.ensure_owns_direct_data();
|
|
|
|
|
return geometry_set.get_component_for_write<MeshComponent>().release();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Mesh *mesh_create_eval_no_deform_render(Depsgraph *depsgraph,
|
|
|
|
@ -1241,10 +1097,10 @@ Mesh *mesh_create_eval_no_deform_render(Depsgraph *depsgraph,
|
|
|
|
|
Object *ob,
|
|
|
|
|
const CustomData_MeshMasks *dataMask)
|
|
|
|
|
{
|
|
|
|
|
Mesh *result;
|
|
|
|
|
mesh_calc_modifiers(
|
|
|
|
|
*depsgraph, *scene, *ob, false, false, *dataMask, false, false, nullptr, &result, nullptr);
|
|
|
|
|
return result;
|
|
|
|
|
GeometrySet geometry_set = mesh_calc_modifiers(
|
|
|
|
|
*depsgraph, *scene, *ob, false, false, *dataMask, false);
|
|
|
|
|
geometry_set.ensure_owns_direct_data();
|
|
|
|
|
return geometry_set.get_component_for_write<MeshComponent>().release();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Mesh *editbmesh_get_eval_cage(Depsgraph *depsgraph,
|
|
|
|
@ -1260,13 +1116,13 @@ Mesh *editbmesh_get_eval_cage(Depsgraph *depsgraph,
|
|
|
|
|
*/
|
|
|
|
|
object_get_datamask(*depsgraph, *obedit, cddata_masks, nullptr);
|
|
|
|
|
|
|
|
|
|
if (!obedit->runtime->editmesh_eval_cage ||
|
|
|
|
|
if (!BKE_object_get_editmesh_eval_cage(obedit) ||
|
|
|
|
|
!CustomData_MeshMasks_are_matching(&(obedit->runtime->last_data_mask), &cddata_masks))
|
|
|
|
|
{
|
|
|
|
|
editbmesh_build_data(*depsgraph, *scene, *obedit, cddata_masks);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return obedit->runtime->editmesh_eval_cage;
|
|
|
|
|
return const_cast<Mesh *>(BKE_object_get_editmesh_eval_cage(obedit));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Mesh *editbmesh_get_eval_cage_from_orig(Depsgraph *depsgraph,
|
|
|
|
|