Fix #131814: Cycles bake crash with geometry nodes instances

Don't rely on object name matching, this is not reliable when there
can be multiple instances with the same name.

Pull Request: https://projects.blender.org/blender/blender/pulls/132496
This commit is contained in:
Brecht Van Lommel
2025-01-02 12:48:21 +01:00
committed by Brecht Van Lommel
parent 841ae6e8ab
commit b109f26e05
9 changed files with 48 additions and 34 deletions

View File

@@ -1111,10 +1111,12 @@ void BlenderSync::sync_mesh(BL::Depsgraph b_depsgraph, BObjectInfo &b_ob_info, M
if (view_layer.use_surfaces) {
/* Adaptive subdivision setup. Not for baking since that requires
* exact mapping to the Blender mesh. */
if (!scene->bake_manager->get_baking()) {
new_mesh.set_subdivision_type(
object_subdivision_type(b_ob_info.real_object, preview, experimental));
}
Mesh::SubdivisionType subdivision_type = (b_ob_info.real_object != b_bake_target) ?
object_subdivision_type(b_ob_info.real_object,
preview,
experimental) :
Mesh::SUBDIVISION_NONE;
new_mesh.set_subdivision_type(subdivision_type);
/* For some reason, meshes do not need this... */
bool need_undeformed = new_mesh.need_attribute(scene, ATTR_STD_GENERATED);

View File

@@ -316,6 +316,8 @@ Object *BlenderSync::sync_object(BL::Depsgraph &b_depsgraph,
bool is_caustics_receiver = get_boolean(cobject, "is_caustics_receiver");
object->set_is_caustics_receiver(is_caustics_receiver);
object->set_is_bake_target(b_ob_info.real_object == b_bake_target);
/* sync the asset name for Cryptomatte */
BL::Object parent = b_ob.parent();
ustring parent_name;

View File

@@ -686,7 +686,7 @@ void BlenderSession::bake(BL::Depsgraph &b_depsgraph_,
b_engine, b_userpref, b_scene, background);
/* Initialize bake manager, before we load the baking kernels. */
scene->bake_manager->set(scene, b_object.name());
scene->bake_manager->set_baking(scene, true);
session->set_display_driver(nullptr);
session->set_output_driver(make_unique<BlenderOutputDriver>(b_engine));
@@ -694,6 +694,7 @@ void BlenderSession::bake(BL::Depsgraph &b_depsgraph_,
/* Sync scene. */
BL::Object b_camera_override(b_engine.camera_override());
sync->set_bake_target(b_object);
sync->sync_camera(b_render, b_camera_override, width, height, "");
sync->sync_data(b_render,
b_depsgraph,
@@ -727,8 +728,8 @@ void BlenderSession::bake(BL::Depsgraph &b_depsgraph_,
* other way, in that case Blender will report a warning afterwards. */
Object *bake_object = nullptr;
if (!session->progress.get_cancel()) {
foreach (Object *ob, scene->objects) {
if (ob->name == b_object.name()) {
for (Object *ob : scene->objects) {
if (ob->get_is_bake_target()) {
bake_object = ob;
break;
}

View File

@@ -2,6 +2,7 @@
*
* SPDX-License-Identifier: Apache-2.0 */
#include "RNA_types.hh"
#include "scene/background.h"
#include "scene/camera.h"
#include "scene/curves.h"
@@ -47,6 +48,7 @@ BlenderSync::BlenderSync(BL::RenderEngine &b_engine,
: b_engine(b_engine),
b_data(b_data),
b_scene(b_scene),
b_bake_target(PointerRNA_NULL),
shader_map(scene),
object_map(scene),
procedural_map(scene),
@@ -87,6 +89,11 @@ void BlenderSync::tag_update()
has_updates_ = true;
}
void BlenderSync::set_bake_target(BL::Object &b_object)
{
b_bake_target = b_object;
}
/* Sync */
void BlenderSync::sync_recalc(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d)
@@ -386,9 +393,8 @@ void BlenderSync::sync_integrator(BL::ViewLayer &b_view_layer,
break;
}
const bool is_vertex_baking = scene->bake_manager->get_baking() &&
b_scene.render().bake().target() !=
BL::BakeSettings::target_IMAGE_TEXTURES;
const bool is_vertex_baking = b_bake_target && b_scene.render().bake().target() !=
BL::BakeSettings::target_IMAGE_TEXTURES;
scene->bake_manager->set_use_seed(is_vertex_baking);
if (is_vertex_baking) {
/* When baking vertex colors, the "pixels" in the output are unrelated to their neighbors,
@@ -578,7 +584,7 @@ void BlenderSync::sync_view_layer(BL::ViewLayer &b_view_layer)
/* Filter. */
view_layer.use_background_shader = b_view_layer.use_sky();
/* Always enable surfaces for baking, otherwise there is nothing to bake to. */
view_layer.use_surfaces = b_view_layer.use_solid() || scene->bake_manager->get_baking();
view_layer.use_surfaces = b_view_layer.use_solid() || b_bake_target;
view_layer.use_hair = b_view_layer.use_strand();
view_layer.use_volumes = b_view_layer.use_volumes();
view_layer.use_motion_blur = b_view_layer.use_motion_blur() &&
@@ -807,7 +813,7 @@ void BlenderSync::free_data_after_sync(BL::Depsgraph &b_depsgraph)
/* Baking re-uses the depsgraph multiple times, clearing crashes
* reading un-evaluated mesh data which isn't aligned with the
* geometry we're baking, see #71012. */
!scene->bake_manager->get_baking() &&
!b_bake_target &&
/* Persistent data must main caches for performance and correctness. */
!is_persistent_data;

View File

@@ -57,6 +57,8 @@ class BlenderSync {
void tag_update();
void set_bake_target(BL::Object &b_object);
/* sync */
void sync_recalc(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d);
void sync_data(BL::RenderSettings &b_render,
@@ -223,6 +225,7 @@ class BlenderSync {
BL::RenderEngine b_engine;
BL::BlendData b_data;
BL::Scene b_scene;
BL::Object b_bake_target;
enum ShaderFlags { SHADER_WITH_LAYER_ATTRS };

View File

@@ -14,22 +14,18 @@
CCL_NAMESPACE_BEGIN
BakeManager::BakeManager()
{
need_update_ = true;
use_camera_ = false;
}
BakeManager::~BakeManager() {}
bool BakeManager::get_baking() const
{
return !object_name.empty();
return use_baking_;
}
void BakeManager::set(Scene *scene, const std::string &object_name_)
void BakeManager::set_baking(Scene *scene, const bool use)
{
object_name = object_name_;
if (use_baking_ == use) {
return;
}
use_baking_ = use;
/* create device and update scene */
scene->film->tag_modified();
@@ -70,8 +66,8 @@ void BakeManager::device_update(Device * /*device*/,
kbake->use_camera = use_camera_;
if (!object_name.empty()) {
scoped_callback_timer timer([scene](double time) {
if (use_baking_) {
const scoped_callback_timer timer([scene](double time) {
if (scene->update_stats) {
scene->update_stats->bake.times.add_entry({"device_update", time});
}
@@ -80,9 +76,9 @@ void BakeManager::device_update(Device * /*device*/,
kbake->use = true;
int object_index = 0;
foreach (Object *object, scene->objects) {
for (Object *object : scene->objects) {
const Geometry *geom = object->get_geometry();
if (object->name == object_name && geom->is_mesh()) {
if (object->get_is_bake_target() && geom->is_mesh()) {
kbake->object_index = object_index;
kbake->tri_offset = geom->prim_offset;
break;

View File

@@ -15,10 +15,10 @@ CCL_NAMESPACE_BEGIN
class BakeManager {
public:
BakeManager();
~BakeManager();
BakeManager() = default;
~BakeManager() = default;
void set(Scene *scene, const std::string &object_name);
void set_baking(Scene *scene, const bool use);
bool get_baking() const;
void set_use_camera(bool use_camera);
@@ -34,10 +34,10 @@ class BakeManager {
bool need_update() const;
private:
bool need_update_;
std::string object_name;
bool use_camera_;
bool use_seed_;
bool need_update_ = true;
bool use_baking_ = false;
bool use_camera_ = false;
bool use_seed_ = false;
};
CCL_NAMESPACE_END

View File

@@ -95,6 +95,8 @@ NODE_DEFINE(Object)
SOCKET_BOOLEAN(is_caustics_caster, "Cast Shadow Caustics", false);
SOCKET_BOOLEAN(is_caustics_receiver, "Receive Shadow Caustics", false);
SOCKET_BOOLEAN(is_bake_target, "Bake Target", false);
SOCKET_NODE(particle_system, "Particle System", ParticleSystem::get_node_type());
SOCKET_INT(particle_index, "Particle Index", 0);

View File

@@ -60,6 +60,8 @@ class Object : public Node {
NODE_SOCKET_API(bool, is_caustics_caster)
NODE_SOCKET_API(bool, is_caustics_receiver)
NODE_SOCKET_API(bool, is_bake_target)
NODE_SOCKET_API(float3, dupli_generated)
NODE_SOCKET_API(float2, dupli_uv)