Fix T83300: constant scene refreshing in Cycles with empty volumes

This infinite loop is caused by a conflict between the volume mesh
creation which unintentionally clears the shaders before early exiting
when no grid is found, and the Blender exporter which adds back the
shaders causing us to reupdate as the shaders changed.

To fix this simply preserve the shaders on the Volume node.

(Backported bugfix with additional changes to make it work in 2.91)
This commit is contained in:
Kévin Dietrich 2020-12-02 11:17:13 +01:00 • committed by Brecht Van Lommel
parent b50598bc78
commit fdcf30d01d
8 changed files with 24 additions and 17 deletions

View file

@ -81,9 +81,11 @@ Geometry::~Geometry()
delete bvh;
}
void Geometry::clear()
void Geometry::clear(bool preserve_shaders)
{
used_shaders.clear();
if (!preserve_shaders)
used_shaders.clear();
transform_applied = false;
transform_negative_scaled = false;
transform_normal = transform_identity();

View file

@ -96,7 +96,7 @@ class Geometry : public Node {
virtual ~Geometry();
/* Geometry */
virtual void clear();
virtual void clear(bool preserve_shaders = false);
virtual void compute_bounds() = 0;
virtual void apply_transform(const Transform &tfm, const bool apply_to_motion) = 0;

View file

@ -321,9 +321,9 @@ void Hair::reserve_curves(int numcurves, int numkeys)
attributes.resize(true);
}
void Hair::clear()
void Hair::clear(bool preserve_shaders)
{
Geometry::clear();
Geometry::clear(preserve_shaders);
curve_keys.clear();
curve_radius.clear();

View file

@ -103,7 +103,7 @@ class Hair : public Geometry {
~Hair();
/* Geometry */
void clear() override;
void clear(bool preserve_shaders = false) override;
void resize_curves(int numcurves, int numkeys);
void reserve_curves(int numcurves, int numkeys);

View file

@ -213,9 +213,9 @@ void Mesh::reserve_subd_faces(int numfaces, int num_ngons_, int numcorners)
subd_attributes.resize(true);
}
void Mesh::clear(bool preserve_voxel_data)
void Mesh::clear(bool preserve_shaders, bool preserve_voxel_data)
{
Geometry::clear();
Geometry::clear(preserve_shaders);
/* clear all verts and triangles */
verts.clear();
@ -243,9 +243,9 @@ void Mesh::clear(bool preserve_voxel_data)
patch_table = NULL;
}
void Mesh::clear()
void Mesh::clear(bool preserve_shaders)
{
clear(false);
clear(preserve_shaders, false);
}
void Mesh::add_vertex(float3 P)

View file

@ -174,8 +174,7 @@ class Mesh : public Geometry {
void reserve_mesh(int numverts, int numfaces);
void resize_subd_faces(int numfaces, int num_ngons, int numcorners);
void reserve_subd_faces(int numfaces, int num_ngons, int numcorners);
void clear(bool preserve_voxel_data);
void clear() override;
void clear(bool preserve_shaders = false) override;
void add_vertex(float3 P);
void add_vertex_slow(float3 P);
void add_triangle(int v0, int v1, int v2, int shader, bool smooth);
@ -202,6 +201,9 @@ class Mesh : public Geometry {
void pack_patches(uint *patch_data, uint vert_offset, uint face_offset, uint corner_offset);
void tessellate(DiagSplit *split);
protected:
void clear(bool preserve_shaders, bool preserve_voxel_data);
};
CCL_NAMESPACE_END

View file

@ -56,9 +56,9 @@ Volume::Volume() : Mesh(node_type, Geometry::VOLUME)
object_space = false;
}
void Volume::clear()
void Volume::clear(bool preserve_shaders)
{
Mesh::clear(true);
Mesh::clear(preserve_shaders, true);
}
struct QuadData {
@ -530,8 +530,10 @@ void GeometryManager::create_volume_mesh(Volume *volume, Progress &progress)
}
/* Clear existing volume mesh, done here in case we early out due to
* empty grid or missing volume shader. */
volume->clear();
* empty grid or missing volume shader.
* Also keep the shaders to avoid infinite loops when synchronizing, as this will tag the shaders
* as having changed. */
volume->clear(true);
volume->need_update_rebuild = true;
if (!volume_shader) {
@ -606,6 +608,7 @@ void GeometryManager::create_volume_mesh(Volume *volume, Progress &progress)
builder.create_mesh(vertices, indices, face_normals, face_overlap_avoidance);
volume->reserve_mesh(vertices.size(), indices.size() / 3);
volume->used_shaders.clear();
volume->used_shaders.push_back(volume_shader);
for (size_t i = 0; i < vertices.size(); ++i) {

View file

@ -32,7 +32,7 @@ class Volume : public Mesh {
float step_size;
bool object_space;
virtual void clear() override;
virtual void clear(bool preserve_shaders = false) override;
};
CCL_NAMESPACE_END