Refactor: Some tweaks to Cycles geometry sync for upcoming changes

* Use BKE functions directly instead of RNA in some places
* Remove various unused arguments

Pull Request: https://projects.blender.org/blender/blender/pulls/135895
This commit is contained in:
Brecht Van Lommel
2025-03-12 19:07:59 +01:00
parent 53b84851c5
commit e4503a991d
8 changed files with 81 additions and 95 deletions

View File

@@ -1031,7 +1031,7 @@ void BlenderSync::sync_hair(Hair *hair, BObjectInfo &b_ob_info, bool motion, con
}
}
void BlenderSync::sync_hair(BL::Depsgraph b_depsgraph, BObjectInfo &b_ob_info, Hair *hair)
void BlenderSync::sync_hair(BObjectInfo &b_ob_info, Hair *hair)
{
/* make a copy of the shaders as the caller in the main thread still need them for syncing the
* attributes */
@@ -1047,13 +1047,11 @@ void BlenderSync::sync_hair(BL::Depsgraph b_depsgraph, BObjectInfo &b_ob_info, H
}
else {
/* Particle hair. */
const bool need_undeformed = new_hair.need_attribute(scene, ATTR_STD_GENERATED);
BL::Mesh b_mesh = object_to_mesh(
b_data, b_ob_info, b_depsgraph, need_undeformed, Mesh::SUBDIVISION_NONE);
BL::Mesh b_mesh = object_to_mesh(b_ob_info);
if (b_mesh) {
sync_particle_hair(&new_hair, b_mesh, b_ob_info, false);
free_object_to_mesh(b_data, b_ob_info, b_mesh);
free_object_to_mesh(b_ob_info, b_mesh);
}
}
}
@@ -1079,10 +1077,7 @@ void BlenderSync::sync_hair(BL::Depsgraph b_depsgraph, BObjectInfo &b_ob_info, H
hair->tag_update(scene, rebuild);
}
void BlenderSync::sync_hair_motion(BL::Depsgraph b_depsgraph,
BObjectInfo &b_ob_info,
Hair *hair,
const int motion_step)
void BlenderSync::sync_hair_motion(BObjectInfo &b_ob_info, Hair *hair, const int motion_step)
{
/* Skip if nothing exported. */
if (hair->num_keys() == 0) {
@@ -1098,11 +1093,10 @@ void BlenderSync::sync_hair_motion(BL::Depsgraph b_depsgraph,
}
/* Particle hair. */
BL::Mesh b_mesh = object_to_mesh(
b_data, b_ob_info, b_depsgraph, false, Mesh::SUBDIVISION_NONE);
BL::Mesh b_mesh = object_to_mesh(b_ob_info);
if (b_mesh) {
sync_particle_hair(hair, b_mesh, b_ob_info, true, motion_step);
free_object_to_mesh(b_data, b_ob_info, b_mesh);
free_object_to_mesh(b_ob_info, b_mesh);
return;
}
}

View File

@@ -32,7 +32,7 @@ static Geometry::Type determine_geom_type(BObjectInfo &b_ob_info, bool use_parti
}
if (b_ob_info.object_data.is_a(&RNA_Volume) ||
(b_ob_info.object_data == b_ob_info.real_object.data() &&
(b_ob_info.object_data == object_get_data(b_ob_info.real_object) &&
object_fluid_gas_domain_find(b_ob_info.real_object)))
{
return Geometry::VOLUME;
@@ -76,8 +76,7 @@ array<Node *> BlenderSync::find_used_shaders(BL::Object &b_ob)
return used_shaders;
}
Geometry *BlenderSync::sync_geometry(BL::Depsgraph &b_depsgraph,
BObjectInfo &b_ob_info,
Geometry *BlenderSync::sync_geometry(BObjectInfo &b_ob_info,
bool object_updated,
bool use_particle_hair,
TaskPool *task_pool)
@@ -167,7 +166,7 @@ Geometry *BlenderSync::sync_geometry(BL::Depsgraph &b_depsgraph,
/* Store the shaders immediately for the object attribute code. */
geom->set_used_shaders(used_shaders);
auto sync_func = [this, geom_type, b_depsgraph, b_ob_info, geom]() mutable {
auto sync_func = [this, geom_type, b_ob_info, geom]() mutable {
if (progress.get_cancel()) {
return;
}
@@ -176,11 +175,11 @@ Geometry *BlenderSync::sync_geometry(BL::Depsgraph &b_depsgraph,
if (geom_type == Geometry::LIGHT) {
Light *light = static_cast<Light *>(geom);
sync_light(b_depsgraph, b_ob_info, light);
sync_light(b_ob_info, light);
}
else if (geom_type == Geometry::HAIR) {
Hair *hair = static_cast<Hair *>(geom);
sync_hair(b_depsgraph, b_ob_info, hair);
sync_hair(b_ob_info, hair);
}
else if (geom_type == Geometry::VOLUME) {
Volume *volume = static_cast<Volume *>(geom);
@@ -192,7 +191,7 @@ Geometry *BlenderSync::sync_geometry(BL::Depsgraph &b_depsgraph,
}
else {
Mesh *mesh = static_cast<Mesh *>(geom);
sync_mesh(b_depsgraph, b_ob_info, mesh);
sync_mesh(b_ob_info, mesh);
}
};
@@ -207,8 +206,7 @@ Geometry *BlenderSync::sync_geometry(BL::Depsgraph &b_depsgraph,
return geom;
}
void BlenderSync::sync_geometry_motion(BL::Depsgraph &b_depsgraph,
BObjectInfo &b_ob_info,
void BlenderSync::sync_geometry_motion(BObjectInfo &b_ob_info,
Object *object,
const float motion_time,
bool use_particle_hair,
@@ -256,14 +254,14 @@ void BlenderSync::sync_geometry_motion(BL::Depsgraph &b_depsgraph,
return;
}
auto sync_func = [this, b_depsgraph, b_ob_info, use_particle_hair, motion_step, geom]() mutable {
auto sync_func = [this, b_ob_info, use_particle_hair, motion_step, geom]() mutable {
if (progress.get_cancel()) {
return;
}
if (b_ob_info.object_data.is_a(&RNA_Curves) || use_particle_hair) {
Hair *hair = static_cast<Hair *>(geom);
sync_hair_motion(b_depsgraph, b_ob_info, hair, motion_step);
sync_hair_motion(b_ob_info, hair, motion_step);
}
else if (b_ob_info.object_data.is_a(&RNA_Volume) ||
object_fluid_gas_domain_find(b_ob_info.real_object))
@@ -276,7 +274,7 @@ void BlenderSync::sync_geometry_motion(BL::Depsgraph &b_depsgraph,
}
else {
Mesh *mesh = static_cast<Mesh *>(geom);
sync_mesh_motion(b_depsgraph, b_ob_info, mesh, motion_step);
sync_mesh_motion(b_ob_info, mesh, motion_step);
}
};

View File

@@ -10,7 +10,7 @@
CCL_NAMESPACE_BEGIN
void BlenderSync::sync_light(BL::Depsgraph /*b_depsgraph*/, BObjectInfo &b_ob_info, Light *light)
void BlenderSync::sync_light(BObjectInfo &b_ob_info, Light *light)
{
BL::Light b_light(b_ob_info.object_data);

View File

@@ -10,7 +10,6 @@
#include "blender/sync.h"
#include "blender/util.h"
#include "scene/bake.h"
#include "scene/camera.h"
#include "scene/mesh.h"
#include "scene/object.h"
@@ -1097,7 +1096,7 @@ static void create_subd_mesh(Scene *scene,
/* Sync */
void BlenderSync::sync_mesh(BL::Depsgraph b_depsgraph, BObjectInfo &b_ob_info, Mesh *mesh)
void BlenderSync::sync_mesh(BObjectInfo &b_ob_info, Mesh *mesh)
{
/* make a copy of the shaders as the caller in the main thread still need them for syncing the
* attributes */
@@ -1114,9 +1113,7 @@ void BlenderSync::sync_mesh(BL::Depsgraph b_depsgraph, BObjectInfo &b_ob_info, M
}
/* For some reason, meshes do not need this... */
const bool need_undeformed = new_mesh.need_attribute(scene, ATTR_STD_GENERATED);
BL::Mesh b_mesh = object_to_mesh(
b_data, b_ob_info, b_depsgraph, need_undeformed, new_mesh.get_subdivision_type());
BL::Mesh b_mesh = object_to_mesh(b_ob_info, new_mesh.get_subdivision_type());
if (b_mesh) {
/* Motion blur attribute is relative to seconds, we need it relative to frames. */
@@ -1148,7 +1145,7 @@ void BlenderSync::sync_mesh(BL::Depsgraph b_depsgraph, BObjectInfo &b_ob_info, M
false);
}
free_object_to_mesh(b_data, b_ob_info, b_mesh);
free_object_to_mesh(b_ob_info, b_mesh);
}
}
@@ -1179,10 +1176,7 @@ void BlenderSync::sync_mesh(BL::Depsgraph b_depsgraph, BObjectInfo &b_ob_info, M
mesh->tag_update(scene, rebuild);
}
void BlenderSync::sync_mesh_motion(BL::Depsgraph b_depsgraph,
BObjectInfo &b_ob_info,
Mesh *mesh,
const int motion_step)
void BlenderSync::sync_mesh_motion(BObjectInfo &b_ob_info, Mesh *mesh, const int motion_step)
{
/* Skip if no vertices were exported. */
const size_t numverts = mesh->get_verts().size();
@@ -1195,8 +1189,7 @@ void BlenderSync::sync_mesh_motion(BL::Depsgraph b_depsgraph,
BL::Mesh b_mesh_rna(PointerRNA_NULL);
if (ccl::BKE_object_is_deform_modified(b_ob_info, b_scene, preview)) {
/* get derived mesh */
b_mesh_rna = object_to_mesh(
b_data, b_ob_info, b_depsgraph, false, mesh->get_subdivision_type());
b_mesh_rna = object_to_mesh(b_ob_info, mesh->get_subdivision_type());
}
const std::string ob_name = b_ob_info.real_object.name();
@@ -1207,7 +1200,7 @@ void BlenderSync::sync_mesh_motion(BL::Depsgraph b_depsgraph,
const int b_verts_num = b_mesh.verts_num;
const blender::Span<blender::float3> positions = b_mesh.vert_positions();
if (positions.is_empty()) {
free_object_to_mesh(b_data, b_ob_info, b_mesh_rna);
free_object_to_mesh(b_ob_info, b_mesh_rna);
return;
}
@@ -1290,7 +1283,7 @@ void BlenderSync::sync_mesh_motion(BL::Depsgraph b_depsgraph,
}
}
free_object_to_mesh(b_data, b_ob_info, b_mesh_rna);
free_object_to_mesh(b_ob_info, b_mesh_rna);
return;
}

View File

@@ -91,14 +91,14 @@ bool BlenderSync::object_can_have_geometry(BL::Object &b_ob)
bool BlenderSync::object_is_light(BL::Object &b_ob)
{
BL::ID b_ob_data = b_ob.data();
BL::ID b_ob_data = object_get_data(b_ob);
return (b_ob_data && b_ob_data.is_a(&RNA_Light));
}
bool BlenderSync::object_is_camera(BL::Object &b_ob)
{
BL::ID b_ob_data = b_ob.data();
BL::ID b_ob_data = object_get_data(b_ob);
return (b_ob_data && b_ob_data.is_a(&RNA_Camera));
}
@@ -145,8 +145,7 @@ void BlenderSync::sync_object_motion_init(BL::Object &b_parent, BL::Object &b_ob
}
}
Object *BlenderSync::sync_object(BL::Depsgraph &b_depsgraph,
BL::ViewLayer &b_view_layer,
Object *BlenderSync::sync_object(BL::ViewLayer &b_view_layer,
BL::DepsgraphObjectInstance &b_instance,
const float motion_time,
bool use_particle_hair,
@@ -157,7 +156,8 @@ Object *BlenderSync::sync_object(BL::Depsgraph &b_depsgraph,
const bool is_instance = b_instance.is_instance();
BL::Object b_ob = b_instance.object();
BL::Object b_parent = is_instance ? b_instance.parent() : b_instance.object();
BObjectInfo b_ob_info{b_ob, is_instance ? b_instance.instance_object() : b_ob, b_ob.data()};
BL::Object b_real_object = is_instance ? b_instance.instance_object() : b_ob;
BObjectInfo b_ob_info{b_ob, b_real_object, object_get_data(b_ob)};
const bool motion = motion_time != 0.0f;
/*const*/ Transform tfm = get_transform(b_ob.matrix_world());
int *persistent_id = nullptr;
@@ -239,7 +239,7 @@ Object *BlenderSync::sync_object(BL::Depsgraph &b_depsgraph,
/* mesh deformation */
if (object->get_geometry()) {
sync_geometry_motion(
b_depsgraph, b_ob_info, object, motion_time, use_particle_hair, object_geom_task_pool);
b_ob_info, object, motion_time, use_particle_hair, object_geom_task_pool);
}
}
@@ -252,7 +252,7 @@ Object *BlenderSync::sync_object(BL::Depsgraph &b_depsgraph,
/* mesh sync */
Geometry *geometry = sync_geometry(
b_depsgraph, b_ob_info, object_updated, use_particle_hair, object_geom_task_pool);
b_ob_info, object_updated, use_particle_hair, object_geom_task_pool);
object->set_geometry(geometry);
/* special case not tracked by object update flags */
@@ -597,8 +597,7 @@ void BlenderSync::sync_objects(BL::Depsgraph &b_depsgraph,
else
#endif
{
sync_object(b_depsgraph,
b_view_layer,
sync_object(b_view_layer,
b_instance,
motion_time,
false,
@@ -610,14 +609,8 @@ void BlenderSync::sync_objects(BL::Depsgraph &b_depsgraph,
/* Particle hair as separate object. */
if (sync_hair) {
sync_object(b_depsgraph,
b_view_layer,
b_instance,
motion_time,
true,
show_lights,
culling,
&geom_task_pool);
sync_object(
b_view_layer, b_instance, motion_time, true, show_lights, culling, &geom_task_pool);
}
cancel = progress.get_cancel();

View File

@@ -180,7 +180,7 @@ void BlenderSync::sync_recalc(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d
if (updated_geometry ||
(object_subdivision_type(b_ob, preview, experimental) != Mesh::SUBDIVISION_NONE))
{
BL::ID const key = BKE_object_is_modified(b_ob) ? b_ob : b_ob.data();
BL::ID const key = BKE_object_is_modified(b_ob) ? b_ob : object_get_data(b_ob);
geometry_map.set_recalc(key);
/* Sync all contained geometry instances as well when the object changed.. */

View File

@@ -16,7 +16,6 @@
#include "util/map.h"
#include "util/set.h"
#include "util/transform.h"
CCL_NAMESPACE_BEGIN
@@ -137,8 +136,7 @@ class BlenderSync {
BL::Depsgraph &b_depsgraph);
/* Object */
Object *sync_object(BL::Depsgraph &b_depsgraph,
BL::ViewLayer &b_view_layer,
Object *sync_object(BL::ViewLayer &b_view_layer,
BL::DepsgraphObjectInstance &b_instance,
const float motion_time,
bool use_particle_hair,
@@ -157,18 +155,12 @@ class BlenderSync {
void sync_volume(BObjectInfo &b_ob_info, Volume *volume);
/* Mesh */
void sync_mesh(BL::Depsgraph b_depsgraph, BObjectInfo &b_ob_info, Mesh *mesh);
void sync_mesh_motion(BL::Depsgraph b_depsgraph,
BObjectInfo &b_ob_info,
Mesh *mesh,
int motion_step);
void sync_mesh(BObjectInfo &b_ob_info, Mesh *mesh);
void sync_mesh_motion(BObjectInfo &b_ob_info, Mesh *mesh, int motion_step);
/* Hair */
void sync_hair(BL::Depsgraph b_depsgraph, BObjectInfo &b_ob_info, Hair *hair);
void sync_hair_motion(BL::Depsgraph b_depsgraph,
BObjectInfo &b_ob_info,
Hair *hair,
int motion_step);
void sync_hair(BObjectInfo &b_ob_info, Hair *hair);
void sync_hair_motion(BObjectInfo &b_ob_info, Hair *hair, int motion_step);
void sync_hair(Hair *hair, BObjectInfo &b_ob_info, bool motion, const int motion_step = 0);
void sync_particle_hair(Hair *hair,
BL::Mesh &b_mesh,
@@ -191,21 +183,19 @@ class BlenderSync {
const float motion_time);
/* Geometry */
Geometry *sync_geometry(BL::Depsgraph &b_depsgraph,
BObjectInfo &b_ob_info,
Geometry *sync_geometry(BObjectInfo &b_ob_info,
bool object_updated,
bool use_particle_hair,
TaskPool *task_pool);
void sync_geometry_motion(BL::Depsgraph &b_depsgraph,
BObjectInfo &b_ob_info,
void sync_geometry_motion(BObjectInfo &b_ob_info,
Object *object,
const float motion_time,
bool use_particle_hair,
TaskPool *task_pool);
/* Light */
void sync_light(BL::Depsgraph b_depsgraph, BObjectInfo &b_ob_info, Light *light);
void sync_light(BObjectInfo &b_ob_info, Light *light);
void sync_background_light(BL::SpaceView3D &b_v3d);
/* Particles */

View File

@@ -4,6 +4,9 @@
#pragma once
#include "RNA_access.hh"
#include "RNA_blender_cpp.hh"
#include "scene/mesh.h"
#include "scene/scene.h"
@@ -14,16 +17,30 @@
#include "util/transform.h"
#include "util/types.h"
#include "RNA_blender_cpp.hh"
#include "DNA_mesh_types.h"
#include "DNA_object_types.h"
#include "BKE_image.hh"
#include "BKE_lib_id.hh"
#include "BKE_mesh.h"
#include "BKE_mesh_types.hh"
#include "BKE_mesh_wrapper.hh"
CCL_NAMESPACE_BEGIN
static inline BL::ID object_get_data(const BL::Object &b_ob)
{
::Object *object = reinterpret_cast<::Object *>(b_ob.ptr.data);
if (object->type == OB_MESH) {
::Mesh *mesh = static_cast<::Mesh *>(object->data);
mesh = BKE_mesh_wrapper_ensure_subdivision(mesh);
return BL::ID(RNA_id_pointer_create(&mesh->id));
}
return BL::ID(RNA_id_pointer_create(reinterpret_cast<ID *>(object->data)));
}
struct BObjectInfo {
/* Object directly provided by the depsgraph iterator. This object is only valid during one
* iteration and must not be accessed afterwards. Transforms and visibility should be checked on
@@ -35,17 +52,26 @@ struct BObjectInfo {
BL::Object real_object;
/* The object-data referenced by the iter object. This is still valid after the depsgraph
* iterator is done. It might have a different type compared to real_object.data(). */
* iterator is done. It might have a different type compared to object_get_data(real_object). */
BL::ID object_data;
/* True when the current geometry is the data of the referenced object. False when it is a
* geometry instance that does not have a 1-to-1 relationship with an object. */
bool is_real_object_data() const
{
return const_cast<BL::Object &>(real_object).data() == object_data;
return object_get_data(const_cast<BL::Object &>(real_object)) == object_data;
}
};
static inline BL::Mesh object_copy_mesh_data(const BObjectInfo &b_ob_info,
const Mesh::SubdivisionType subdivision_type)
{
::Object *object = static_cast<::Object *>(b_ob_info.real_object.ptr.data);
::Mesh *mesh = BKE_mesh_new_from_object(
nullptr, object, false, false, subdivision_type == Mesh::SUBDIVISION_NONE);
return BL::Mesh(RNA_id_pointer_create(&mesh->id));
}
using BlenderAttributeType = BL::ShaderNodeAttribute::attribute_type_enum;
BlenderAttributeType blender_attribute_name_split_type(ustring name, string *r_real_name);
@@ -59,11 +85,8 @@ static bool mesh_use_corner_normals(BL::Mesh &mesh, Mesh::SubdivisionType subdiv
blender::bke::MeshNormalDomain::Corner);
}
static inline BL::Mesh object_to_mesh(BL::BlendData & /*data*/,
BObjectInfo &b_ob_info,
BL::Depsgraph & /*depsgraph*/,
bool /*calc_undeformed*/,
Mesh::SubdivisionType subdivision_type)
static inline BL::Mesh object_to_mesh(
BObjectInfo &b_ob_info, Mesh::SubdivisionType subdivision_type = Mesh::SUBDIVISION_NONE)
{
/* TODO: make this work with copy-on-evaluation, modifiers are already evaluated. */
#if 0
@@ -90,20 +113,17 @@ static inline BL::Mesh object_to_mesh(BL::BlendData & /*data*/,
if (mesh) {
if (mesh.is_editmode()) {
/* Flush edit-mesh to mesh, including all data layers. */
BL::Depsgraph depsgraph(PointerRNA_NULL);
mesh = b_ob_info.real_object.to_mesh(false, depsgraph);
mesh = object_copy_mesh_data(b_ob_info, subdivision_type);
use_corner_normals = mesh_use_corner_normals(mesh, subdivision_type);
}
else if (mesh_use_corner_normals(mesh, subdivision_type)) {
/* Make a copy to split faces. */
BL::Depsgraph depsgraph(PointerRNA_NULL);
mesh = b_ob_info.real_object.to_mesh(false, depsgraph);
mesh = object_copy_mesh_data(b_ob_info, subdivision_type);
use_corner_normals = true;
}
}
else {
BL::Depsgraph depsgraph(PointerRNA_NULL);
mesh = b_ob_info.real_object.to_mesh(false, depsgraph);
mesh = object_copy_mesh_data(b_ob_info, subdivision_type);
use_corner_normals = mesh_use_corner_normals(mesh, subdivision_type);
}
}
@@ -134,17 +154,15 @@ static inline BL::Mesh object_to_mesh(BL::BlendData & /*data*/,
return mesh;
}
static inline void free_object_to_mesh(BL::BlendData & /*data*/,
BObjectInfo &b_ob_info,
BL::Mesh &mesh)
static inline void free_object_to_mesh(BObjectInfo &b_ob_info, BL::Mesh &mesh)
{
if (!b_ob_info.is_real_object_data()) {
return;
}
/* Free mesh if we didn't just use the existing one. */
BL::Object object = b_ob_info.real_object;
if (object.data().ptr.data != mesh.ptr.data) {
object.to_mesh_clear();
if (object_get_data(object).ptr.data != mesh.ptr.data) {
BKE_id_free(nullptr, static_cast<ID *>(mesh.ptr.data));
}
}