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:
committed by
Brecht Van Lommel
parent
841ae6e8ab
commit
b109f26e05
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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 };
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user