Fix T94479: GPU Subdivision surface modifier does not apply to Cycles renders

Since now we delegate the evaluation of the last subsurf modifier in the stack
to the draw code, Cycles does not get a subdivided mesh anymore. This is because
the subdivision wrapper for generating a CPU side subdivision is never created
as it is only ever created via `BKE_object_get_evaluated_mesh` which Cycles does
not call (rather, it accesses the Mesh either via `object.data()`, or via
`object.to_mesh()`).

This ensures that a subdivision wrapper is created when accessing the object data
or converting an Object to a Mesh via the RNA/Python API.

Reviewed by: brecht

Differential Revision: https://developer.blender.org/D14048
This commit is contained in:
Kévin Dietrich 2022-02-14 16:35:25 +01:00
parent 0999a01b03
commit 56407432a6
Notes: blender-bot 2023-02-14 03:52:45 +01:00
Referenced by commit a2dacefb46, Fix T96289: Crash when accessing mesh via `ob.data` in a driver
Referenced by commit 53fe4f62fe, Fix T95806: subdivision missing in Cycles when using autosmooth
Referenced by issue #96289, Regression: Crash when accessing animated 'object.data' property in a driver of a Mesh
Referenced by issue #94479, GPU Subdivision surface modifier does not apply to Cycles renders
2 changed files with 24 additions and 3 deletions

View File

@ -1051,7 +1051,12 @@ static Mesh *mesh_new_from_mesh(Object *object, Mesh *mesh)
{
/* While we could copy this into the new mesh,
* add the data to 'mesh' so future calls to this function don't need to re-convert the data. */
BKE_mesh_wrapper_ensure_mdata(mesh);
if (mesh->runtime.wrapper_type == ME_WRAPPER_TYPE_BMESH) {
BKE_mesh_wrapper_ensure_mdata(mesh);
}
else {
BKE_mesh_wrapper_ensure_subdivision(object, mesh);
}
Mesh *mesh_result = (Mesh *)BKE_id_copy_ex(
nullptr, &mesh->id, nullptr, LIB_ID_CREATE_NO_MAIN | LIB_ID_CREATE_NO_USER_REFCOUNT);
@ -1088,6 +1093,7 @@ static Mesh *mesh_new_from_mesh_object_with_layers(Depsgraph *depsgraph,
mask.pmask |= CD_MASK_ORIGINDEX;
}
Mesh *result = mesh_create_eval_final(depsgraph, scene, &object_for_eval, &mask);
BKE_mesh_wrapper_ensure_subdivision(object, result);
return result;
}

View File

@ -345,6 +345,7 @@ const EnumPropertyItem rna_enum_object_axis_items[] = {
# include "BKE_key.h"
# include "BKE_material.h"
# include "BKE_mesh.h"
# include "BKE_mesh_wrapper.h"
# include "BKE_modifier.h"
# include "BKE_object.h"
# include "BKE_particle.h"
@ -524,6 +525,17 @@ void rna_Object_data_update(Main *bmain, Scene *scene, PointerRNA *ptr)
rna_Object_internal_update_data_dependency(bmain, scene, ptr);
}
static PointerRNA rna_Object_data_get(PointerRNA *ptr)
{
Object *ob = (Object *)ptr->data;
if (ob->type == OB_MESH) {
Mesh *me = (Mesh *)ob->data;
me = BKE_mesh_wrapper_ensure_subdivision(ob, me);
return rna_pointer_inherit_refine(ptr, &RNA_Mesh, me);
}
return rna_pointer_inherit_refine(ptr, &RNA_ID, ob->data);
}
static void rna_Object_data_set(PointerRNA *ptr, PointerRNA value, struct ReportList *reports)
{
Object *ob = (Object *)ptr->data;
@ -3055,8 +3067,11 @@ static void rna_def_object(BlenderRNA *brna)
prop = RNA_def_property(srna, "data", PROP_POINTER, PROP_NONE);
RNA_def_property_struct_type(prop, "ID");
RNA_def_property_pointer_funcs(
prop, NULL, "rna_Object_data_set", "rna_Object_data_typef", "rna_Object_data_poll");
RNA_def_property_pointer_funcs(prop,
"rna_Object_data_get",
"rna_Object_data_set",
"rna_Object_data_typef",
"rna_Object_data_poll");
RNA_def_property_flag(prop, PROP_EDITABLE | PROP_NEVER_UNLINK);
RNA_def_property_ui_text(prop, "Data", "Object data");
RNA_def_property_update(prop, 0, "rna_Object_data_update");