mirror of
https://github.com/blender/blender
synced 2026-09-29 04:37:17 +03:00
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:
parent
b50598bc78
commit
fdcf30d01d
8 changed files with 24 additions and 17 deletions
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue