Refactor: Add BKE_mesh_new_from_object argument to ignore subdivision

Pull Request: https://projects.blender.org/blender/blender/pulls/135895
This commit is contained in:
Brecht Van Lommel
2025-03-12 02:38:37 +01:00
parent 3c984667e8
commit 9526fe9993
10 changed files with 29 additions and 23 deletions

View File

@@ -183,7 +183,8 @@ void BKE_mesh_texspace_get_reference(Mesh *mesh,
Mesh *BKE_mesh_new_from_object(Depsgraph *depsgraph,
Object *object,
bool preserve_all_data_layers,
bool preserve_origindex);
bool preserve_origindex,
bool ensure_subdivision);
/**
* This is a version of BKE_mesh_new_from_object() which stores mesh in the given main database.

View File

@@ -673,7 +673,7 @@ bool BKE_object_empty_image_data_is_visible_in_view3d(const Object *ob, const Re
* The mesh will be freed when object is re-evaluated or is destroyed. It is possible to force to
* clear memory used by this mesh by calling BKE_object_to_mesh_clear().
*
* If preserve_all_data_layers is truth then the modifier stack is re-evaluated to ensure it
* If preserve_all_data_layers is true then the modifier stack is re-evaluated to ensure it
* preserves all possible custom data layers.
*
* NOTE: Dependency graph argument is required when preserve_all_data_layers is truth, and is

View File

@@ -766,14 +766,14 @@ static Mesh *mesh_new_from_mball_object(Object *object)
return BKE_mesh_copy_for_eval(*mesh_eval);
}
static Mesh *mesh_new_from_mesh(Object *object, const Mesh *mesh)
static Mesh *mesh_new_from_mesh(Object *object, const Mesh *mesh, const bool ensure_subdivision)
{
/* While we could copy this into the new mesh,
* add the data to 'mesh' so future calls to this function don't need to re-convert the data. */
if (mesh->runtime->wrapper_type == ME_WRAPPER_TYPE_BMESH) {
BKE_mesh_wrapper_ensure_mdata(const_cast<Mesh *>(mesh));
}
else {
else if (ensure_subdivision) {
mesh = BKE_mesh_wrapper_ensure_subdivision(const_cast<Mesh *>(mesh));
}
@@ -787,10 +787,11 @@ static Mesh *mesh_new_from_mesh(Object *object, const Mesh *mesh)
static Mesh *mesh_new_from_mesh_object_with_layers(Depsgraph *depsgraph,
Object *object,
const bool preserve_origindex)
const bool preserve_origindex,
const bool ensure_subdivision)
{
if (DEG_is_original_id(&object->id)) {
return mesh_new_from_mesh(object, (Mesh *)object->data);
return mesh_new_from_mesh(object, (Mesh *)object->data, ensure_subdivision);
}
if (depsgraph == nullptr) {
@@ -814,13 +815,14 @@ static Mesh *mesh_new_from_mesh_object_with_layers(Depsgraph *depsgraph,
mask.pmask |= CD_MASK_ORIGINDEX;
}
Mesh *result = blender::bke::mesh_create_eval_final(depsgraph, scene, &object_for_eval, &mask);
return BKE_mesh_wrapper_ensure_subdivision(result);
return (ensure_subdivision) ? BKE_mesh_wrapper_ensure_subdivision(result) : result;
}
static Mesh *mesh_new_from_mesh_object(Depsgraph *depsgraph,
Object *object,
const bool preserve_all_data_layers,
const bool preserve_origindex)
const bool preserve_origindex,
const bool use_subdivision)
{
/* This function tries to reevaluate the object from the original data. If the original object
* was not a mesh object, this won't work because it uses mesh object evaluation which assumes
@@ -828,7 +830,8 @@ static Mesh *mesh_new_from_mesh_object(Depsgraph *depsgraph,
if (!(object->runtime->data_orig && GS(object->runtime->data_orig->name) != ID_ME) &&
(preserve_all_data_layers || preserve_origindex))
{
return mesh_new_from_mesh_object_with_layers(depsgraph, object, preserve_origindex);
return mesh_new_from_mesh_object_with_layers(
depsgraph, object, preserve_origindex, use_subdivision);
}
const Mesh *mesh_input = (const Mesh *)object->data;
/* If we are in edit mode, use evaluated mesh from edit structure, matching to what
@@ -838,13 +841,14 @@ static Mesh *mesh_new_from_mesh_object(Depsgraph *depsgraph,
mesh_input = editmesh_eval_final;
}
}
return mesh_new_from_mesh(object, mesh_input);
return mesh_new_from_mesh(object, mesh_input, use_subdivision);
}
Mesh *BKE_mesh_new_from_object(Depsgraph *depsgraph,
Object *object,
const bool preserve_all_data_layers,
const bool preserve_origindex)
const bool preserve_origindex,
const bool ensure_subdivision)
{
Mesh *new_mesh = nullptr;
switch (object->type) {
@@ -858,7 +862,7 @@ Mesh *BKE_mesh_new_from_object(Depsgraph *depsgraph,
break;
case OB_MESH:
new_mesh = mesh_new_from_mesh_object(
depsgraph, object, preserve_all_data_layers, preserve_origindex);
depsgraph, object, preserve_all_data_layers, preserve_origindex, ensure_subdivision);
break;
default:
/* Object does not have geometry data. */
@@ -923,7 +927,7 @@ Mesh *BKE_mesh_new_from_object_to_bmain(Main *bmain,
{
BLI_assert(ELEM(object->type, OB_FONT, OB_CURVES_LEGACY, OB_SURF, OB_MBALL, OB_MESH));
Mesh *mesh = BKE_mesh_new_from_object(depsgraph, object, preserve_all_data_layers, false);
Mesh *mesh = BKE_mesh_new_from_object(depsgraph, object, preserve_all_data_layers, false, true);
if (mesh == nullptr) {
/* Unable to convert the object to a mesh, return an empty one. */
Mesh *mesh_in_bmain = BKE_mesh_add(bmain, ((ID *)object->data)->name + 2);

View File

@@ -5320,7 +5320,7 @@ Mesh *BKE_object_to_mesh(Depsgraph *depsgraph, Object *object, bool preserve_all
{
BKE_object_to_mesh_clear(object);
Mesh *mesh = BKE_mesh_new_from_object(depsgraph, object, preserve_all_data_layers, false);
Mesh *mesh = BKE_mesh_new_from_object(depsgraph, object, preserve_all_data_layers, false, true);
object->runtime->object_as_temp_mesh = mesh;
return mesh;
}

View File

@@ -714,7 +714,7 @@ static Mesh *bake_mesh_new_from_object(Depsgraph *depsgraph,
Object *object,
const bool preserve_origindex)
{
Mesh *mesh = BKE_mesh_new_from_object(depsgraph, object, false, preserve_origindex);
Mesh *mesh = BKE_mesh_new_from_object(depsgraph, object, false, preserve_origindex, true);
if (mesh->normals_domain() == bke::MeshNormalDomain::Corner) {
ED_mesh_split_faces(mesh);
@@ -1577,7 +1577,8 @@ static int bake(const BakeAPIRender *bkr,
BKE_object_handle_data_update(depsgraph, scene, ob_low_eval);
}
me_cage_eval = BKE_mesh_new_from_object(nullptr, ob_low_eval, false, preserve_origindex);
me_cage_eval = BKE_mesh_new_from_object(
nullptr, ob_low_eval, false, preserve_origindex, true);
if (!CustomData_has_layer(&me_cage_eval->corner_data, CD_PROP_FLOAT2)) {
BKE_reportf(reports,
RPT_ERROR,
@@ -1611,7 +1612,7 @@ static int bake(const BakeAPIRender *bkr,
ob_eval->visibility_flag &= ~OB_HIDE_RENDER;
ob_eval->base_flag |= (BASE_ENABLED_AND_MAYBE_VISIBLE_IN_VIEWPORT | BASE_ENABLED_RENDER);
Mesh *mesh_eval = BKE_mesh_new_from_object(nullptr, ob_eval, false, false);
Mesh *mesh_eval = BKE_mesh_new_from_object(nullptr, ob_eval, false, false, true);
/* Initialize `highpoly` data. */
highpoly[i].ob = ob_iter;
@@ -1766,7 +1767,7 @@ static int bake(const BakeAPIRender *bkr,
md->mode &= ~eModifierMode_Render;
/* Evaluate modifiers again. */
me_nores = BKE_mesh_new_from_object(nullptr, ob_low_eval, false, false);
me_nores = BKE_mesh_new_from_object(nullptr, ob_low_eval, false, false, true);
if (!CustomData_has_layer(&me_nores->corner_data, CD_PROP_FLOAT2)) {
BKE_reportf(reports,
RPT_ERROR,

View File

@@ -55,7 +55,7 @@ Mesh *ABCMetaballWriter::get_export_mesh(Object *object_eval, bool &r_needsfree)
return mesh_eval;
}
r_needsfree = true;
return BKE_mesh_new_from_object(args_.depsgraph, object_eval, false, false);
return BKE_mesh_new_from_object(args_.depsgraph, object_eval, false, false, true);
}
void ABCMetaballWriter::free_export_mesh(Mesh *mesh)

View File

@@ -39,7 +39,7 @@ Mesh *USDMetaballWriter::get_export_mesh(Object *object_eval, bool &r_needsfree)
return mesh_eval;
}
r_needsfree = true;
return BKE_mesh_new_from_object(usd_export_context_.depsgraph, object_eval, false, false);
return BKE_mesh_new_from_object(usd_export_context_.depsgraph, object_eval, false, false, true);
}
void USDMetaballWriter::free_export_mesh(Mesh *mesh)

View File

@@ -58,7 +58,7 @@ OBJMesh::OBJMesh(Depsgraph *depsgraph, const OBJExportParams &export_params, Obj
/* Curves and NURBS surfaces need a new mesh when they're
* exported in the form of vertices and edges.
*/
this->set_mesh(BKE_mesh_new_from_object(depsgraph, obj_eval, true, true));
this->set_mesh(BKE_mesh_new_from_object(depsgraph, obj_eval, true, true, true));
}
if (export_params.export_triangulated_mesh && obj_eval->type == OB_MESH) {
this->triangulate_mesh_eval();

View File

@@ -2505,7 +2505,7 @@ static void lineart_object_load_single_instance(LineartData *ld,
}
}
else {
use_mesh = BKE_mesh_new_from_object(depsgraph, ob, true, true);
use_mesh = BKE_mesh_new_from_object(depsgraph, ob, true, true, true);
}
/* In case we still can not get any mesh geometry data from the object, same as above. */

View File

@@ -1314,7 +1314,7 @@ static PyObject *bpy_bmesh_from_object(BPy_BMesh *self, PyObject *args, PyObject
return nullptr;
}
mesh_eval = BKE_mesh_new_from_object(depsgraph, ob_eval, true, false);
mesh_eval = BKE_mesh_new_from_object(depsgraph, ob_eval, true, false, true);
need_free = true;
}
else {