Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--intern/cycles/blender/blender_mesh.cpp2
-rw-r--r--intern/cycles/graph/node.cpp20
-rw-r--r--intern/cycles/graph/node.h4
-rw-r--r--intern/cycles/render/film.cpp2
-rw-r--r--intern/cycles/render/graph.cpp29
-rw-r--r--intern/cycles/render/graph.h3
-rw-r--r--intern/cycles/render/mesh.cpp4
-rw-r--r--intern/cycles/render/shader.cpp23
-rw-r--r--intern/cycles/render/shader.h2
-rw-r--r--intern/cycles/util/util_md5.cpp7
-rw-r--r--intern/cycles/util/util_md5.h1
11 files changed, 87 insertions, 10 deletions
diff --git a/intern/cycles/blender/blender_mesh.cpp b/intern/cycles/blender/blender_mesh.cpp
index 3b07464cd96..cda9fb59e49 100644
--- a/intern/cycles/blender/blender_mesh.cpp
+++ b/intern/cycles/blender/blender_mesh.cpp
@@ -1123,7 +1123,7 @@ Mesh *BlenderSync::sync_mesh(BL::Object& b_ob,
bool attribute_recalc = false;
foreach(Shader *shader, mesh->used_shaders)
- if(shader->need_update_attributes)
+ if(shader->need_update_mesh)
attribute_recalc = true;
if(!attribute_recalc)
diff --git a/intern/cycles/graph/node.cpp b/intern/cycles/graph/node.cpp
index 10d91a1e4ef..c71221746ad 100644
--- a/intern/cycles/graph/node.cpp
+++ b/intern/cycles/graph/node.cpp
@@ -18,6 +18,7 @@
#include "graph/node_type.h"
#include "util/util_foreach.h"
+#include "util/util_md5.h"
#include "util/util_param.h"
#include "util/util_transform.h"
@@ -403,5 +404,24 @@ bool Node::equals(const Node& other) const
return true;
}
+/* Hash */
+
+void Node::hash(MD5Hash& md5)
+{
+ md5.append(type->name.string());
+
+ foreach(const SocketType& socket, type->inputs) {
+ md5.append(socket.name.string());
+
+ if(socket.is_array()) {
+ const array<bool>* a = (const array<bool>*)(((char*)this) + socket.struct_offset);
+ md5.append((uint8_t*)a->data(), socket.size() * a->size());
+ }
+ else {
+ md5.append(((uint8_t*)this) + socket.struct_offset, socket.size());
+ }
+ }
+}
+
CCL_NAMESPACE_END
diff --git a/intern/cycles/graph/node.h b/intern/cycles/graph/node.h
index 53425f5faf1..d198c38be32 100644
--- a/intern/cycles/graph/node.h
+++ b/intern/cycles/graph/node.h
@@ -24,6 +24,7 @@
CCL_NAMESPACE_BEGIN
+class MD5Hash;
struct Node;
struct NodeType;
struct Transform;
@@ -88,6 +89,9 @@ struct Node
/* equals */
bool equals(const Node& other) const;
+ /* compute hash of node and its socket values */
+ void hash(MD5Hash& md5);
+
ustring name;
const NodeType *type;
};
diff --git a/intern/cycles/render/film.cpp b/intern/cycles/render/film.cpp
index b305f01095f..69828cc78da 100644
--- a/intern/cycles/render/film.cpp
+++ b/intern/cycles/render/film.cpp
@@ -496,7 +496,7 @@ void Film::tag_passes_update(Scene *scene, const array<Pass>& passes_)
scene->mesh_manager->tag_update(scene);
foreach(Shader *shader, scene->shaders)
- shader->need_update_attributes = true;
+ shader->need_update_mesh = true;
}
else if(Pass::contains(passes, PASS_MOTION) != Pass::contains(passes_, PASS_MOTION))
scene->mesh_manager->tag_update(scene);
diff --git a/intern/cycles/render/graph.cpp b/intern/cycles/render/graph.cpp
index fb2e34c2fc7..096de878e51 100644
--- a/intern/cycles/render/graph.cpp
+++ b/intern/cycles/render/graph.cpp
@@ -23,8 +23,9 @@
#include "util/util_algorithm.h"
#include "util/util_foreach.h"
-#include "util/util_queue.h"
#include "util/util_logging.h"
+#include "util/util_md5.h"
+#include "util/util_queue.h"
CCL_NAMESPACE_BEGIN
@@ -683,6 +684,32 @@ void ShaderGraph::break_cycles(ShaderNode *node, vector<bool>& visited, vector<b
on_stack[node->id] = false;
}
+void ShaderGraph::compute_displacement_hash()
+{
+ /* Compute hash of all nodes linked to displacement, to detect if we need
+ * to recompute displacement when shader nodes change. */
+ ShaderInput *displacement_in = output()->input("Displacement");
+
+ if(!displacement_in->link) {
+ displacement_hash = "";
+ return;
+ }
+
+ ShaderNodeSet nodes_displace;
+ find_dependencies(nodes_displace, displacement_in);
+
+ MD5Hash md5;
+ foreach(ShaderNode *node, nodes_displace) {
+ node->hash(md5);
+ foreach(ShaderInput *input, node->inputs) {
+ int link_id = (input->link) ? input->link->parent->id : 0;
+ md5.append((uint8_t*)&link_id, sizeof(link_id));
+ }
+ }
+
+ displacement_hash = md5.get_hex();
+}
+
void ShaderGraph::clean(Scene *scene)
{
/* Graph simplification */
diff --git a/intern/cycles/render/graph.h b/intern/cycles/render/graph.h
index 1d1701b30a2..7ed292b5b96 100644
--- a/intern/cycles/render/graph.h
+++ b/intern/cycles/render/graph.h
@@ -42,6 +42,7 @@ class SVMCompiler;
class OSLCompiler;
class OutputNode;
class ConstantFolder;
+class MD5Hash;
/* Bump
*
@@ -243,6 +244,7 @@ public:
size_t num_node_ids;
bool finalized;
bool simplified;
+ string displacement_hash;
ShaderGraph();
~ShaderGraph();
@@ -256,6 +258,7 @@ public:
void relink(ShaderNode *node, ShaderOutput *from, ShaderOutput *to);
void remove_proxy_nodes();
+ void compute_displacement_hash();
void simplify(Scene *scene);
void finalize(Scene *scene,
bool do_bump = false,
diff --git a/intern/cycles/render/mesh.cpp b/intern/cycles/render/mesh.cpp
index 4bf5b60a737..5bcb47deb65 100644
--- a/intern/cycles/render/mesh.cpp
+++ b/intern/cycles/render/mesh.cpp
@@ -1964,7 +1964,7 @@ void MeshManager::device_update(Device *device, DeviceScene *dscene, Scene *scen
/* Update normals. */
foreach(Mesh *mesh, scene->meshes) {
foreach(Shader *shader, mesh->used_shaders) {
- if(shader->need_update_attributes)
+ if(shader->need_update_mesh)
mesh->need_update = true;
}
@@ -2104,7 +2104,7 @@ void MeshManager::device_update(Device *device, DeviceScene *dscene, Scene *scen
<< summary.full_report();
foreach(Shader *shader, scene->shaders) {
- shader->need_update_attributes = false;
+ shader->need_update_mesh = false;
}
Scene::MotionType need_motion = scene->need_motion();
diff --git a/intern/cycles/render/shader.cpp b/intern/cycles/render/shader.cpp
index abb9e19a074..51b7f76b9d5 100644
--- a/intern/cycles/render/shader.cpp
+++ b/intern/cycles/render/shader.cpp
@@ -200,7 +200,7 @@ Shader::Shader()
used = false;
need_update = true;
- need_update_attributes = true;
+ need_update_mesh = true;
}
Shader::~Shader()
@@ -235,9 +235,24 @@ void Shader::set_graph(ShaderGraph *graph_)
/* do this here already so that we can detect if mesh or object attributes
* are needed, since the node attribute callbacks check if their sockets
* are connected but proxy nodes should not count */
- if(graph_)
+ if(graph_) {
graph_->remove_proxy_nodes();
+ if(displacement_method != DISPLACE_BUMP) {
+ graph_->compute_displacement_hash();
+ }
+ }
+
+ /* update geometry if displacement changed */
+ if(displacement_method != DISPLACE_BUMP) {
+ const char *old_hash = (graph)? graph->displacement_hash.c_str() : "";
+ const char *new_hash = (graph_)? graph_->displacement_hash.c_str() : "";
+
+ if(strcmp(old_hash, new_hash) != 0) {
+ need_update_mesh = true;
+ }
+ }
+
/* assign graph */
delete graph;
graph = graph_;
@@ -294,9 +309,9 @@ void Shader::tag_update(Scene *scene)
}
/* compare if the attributes changed, mesh manager will check
- * need_update_attributes, update the relevant meshes and clear it. */
+ * need_update_mesh, update the relevant meshes and clear it. */
if(attributes.modified(prev_attributes)) {
- need_update_attributes = true;
+ need_update_mesh = true;
scene->mesh_manager->need_update = true;
}
diff --git a/intern/cycles/render/shader.h b/intern/cycles/render/shader.h
index 3fdcd3c0c5b..4a48c1347da 100644
--- a/intern/cycles/render/shader.h
+++ b/intern/cycles/render/shader.h
@@ -98,7 +98,7 @@ public:
/* synchronization */
bool need_update;
- bool need_update_attributes;
+ bool need_update_mesh;
/* If the shader has only volume components, the surface is assumed to
* be transparent.
diff --git a/intern/cycles/util/util_md5.cpp b/intern/cycles/util/util_md5.cpp
index 19168135f01..749760d84f0 100644
--- a/intern/cycles/util/util_md5.cpp
+++ b/intern/cycles/util/util_md5.cpp
@@ -310,6 +310,13 @@ void MD5Hash::append(const uint8_t *data, int nbytes)
memcpy(buf, p, left);
}
+void MD5Hash::append(const string& str)
+{
+ if(str.size()) {
+ append((const uint8_t*)str.c_str(), str.size());
+ }
+}
+
bool MD5Hash::append_file(const string& filepath)
{
FILE *f = path_fopen(filepath, "rb");
diff --git a/intern/cycles/util/util_md5.h b/intern/cycles/util/util_md5.h
index e4cd66c85b0..b043b591e67 100644
--- a/intern/cycles/util/util_md5.h
+++ b/intern/cycles/util/util_md5.h
@@ -41,6 +41,7 @@ public:
~MD5Hash();
void append(const uint8_t *data, int size);
+ void append(const string& str);
bool append_file(const string& filepath);
string get_hex();