Fix T41109: Reloading image that has been modified outside Blender does not update...
authorSergey Sharybin <sergey.vfx@gmail.com>
Fri, 18 Jul 2014 13:28:33 +0000 (19:28 +0600)
committerSergey Sharybin <sergey.vfx@gmail.com>
Fri, 18 Jul 2014 13:37:32 +0000 (19:37 +0600)
intern/cycles/blender/blender_shader.cpp
intern/cycles/render/image.cpp
intern/cycles/render/image.h
source/blender/blenkernel/intern/depsgraph.c
source/blender/editors/space_image/image_ops.c

index 51d8a4da744b1ef0b19ad663e4a6132440d9dc55..193eb69173b0f17d409e4a0a3f341b9692ffb753 100644 (file)
@@ -572,6 +572,13 @@ static ShaderNode *add_node(Scene *scene, BL::BlendData b_data, BL::Scene b_scen
 
                        image->animated = b_image_node.image_user().use_auto_refresh();
                        image->use_alpha = b_image.use_alpha();
+
+                       /* TODO(sergey): Does not work properly when we change builtin type. */
+                       if (b_image.is_updated()) {
+                               scene->image_manager->tag_reload_image(image->filename,
+                                                                      image->builtin_data,
+                                                                      (InterpolationType)b_image_node.interpolation());
+                       }
                }
                image->color_space = ImageTextureNode::color_space_enum[(int)b_image_node.color_space()];
                image->projection = ImageTextureNode::projection_enum[(int)b_image_node.projection()];
@@ -602,6 +609,13 @@ static ShaderNode *add_node(Scene *scene, BL::BlendData b_data, BL::Scene b_scen
                        }
 
                        env->use_alpha = b_image.use_alpha();
+
+                       /* TODO(sergey): Does not work properly when we change builtin type. */
+                       if (b_image.is_updated()) {
+                               scene->image_manager->tag_reload_image(env->filename,
+                                                                      env->builtin_data,
+                                                                      INTERPOLATION_LINEAR);
+                       }
                }
                env->color_space = EnvironmentTextureNode::color_space_enum[(int)b_env_node.color_space()];
                env->projection = EnvironmentTextureNode::projection_enum[(int)b_env_node.projection()];
index 8369df5e137f6a1ab4ea951ec2b60c78ef048cfe..f84396ab6a1424e3bf213d02642dafdbcadb8280 100644 (file)
@@ -313,6 +313,32 @@ void ImageManager::remove_image(const string& filename, void *builtin_data, Inte
        }
 }
 
+/* TODO(sergey): Deduplicate with the iteration above, but make it pretty,
+ * without bunch of arguments passing around making code readability even
+ * more cluttered.
+ */
+void ImageManager::tag_reload_image(const string& filename, void *builtin_data, InterpolationType interpolation)
+{
+       size_t slot;
+
+       for(slot = 0; slot < images.size(); slot++) {
+               if(images[slot] && image_equals(images[slot], filename, builtin_data, interpolation)) {
+                       images[slot]->need_load = true;
+                       break;
+               }
+       }
+
+       if(slot == images.size()) {
+               /* see if it's in a float texture slot */
+               for(slot = 0; slot < float_images.size(); slot++) {
+                       if(float_images[slot] && image_equals(float_images[slot], filename, builtin_data, interpolation)) {
+                               images[slot]->need_load = true;
+                               break;
+                       }
+               }
+       }
+}
+
 bool ImageManager::file_load_image(Image *img, device_vector<uchar4>& tex_img)
 {
        if(img->filename == "")
index 50ea346c03493c95a0fa1eab248a9bb07fe39af3..535f0ff156d2114be39be9f780d718c436452a0f 100644 (file)
@@ -59,6 +59,7 @@ public:
                bool& is_float, bool& is_linear, InterpolationType interpolation, bool use_alpha);
        void remove_image(int slot);
        void remove_image(const string& filename, void *builtin_data, InterpolationType interpolation);
+       void tag_reload_image(const string& filename, void *builtin_data, InterpolationType interpolation);
        bool is_float_image(const string& filename, void *builtin_data, bool& is_linear);
 
        void device_update(Device *device, DeviceScene *dscene, Progress& progress);
index 24b580672d1f10e290d5d4d11792a12d22fa0001..95e608a5d4db1a48997fb4cd9de2d35febf91d44 100644 (file)
@@ -2502,6 +2502,23 @@ static void dag_id_flush_update(Main *bmain, Scene *sce, ID *id)
                        }
                }
 
+               /* Not pretty to iterate all the nodes here, but it's as good as it
+                * could be with the current depsgraph design/
+                */
+               if (idtype == ID_IM) {
+                       FOREACH_NODETREE(bmain, ntree, parent_id) {
+                               if (ntree->type == NTREE_SHADER) {
+                                       bNode *node;
+                                       for (node = ntree->nodes.first; node; node = node->next) {
+                                               if (node->id == id) {
+                                                       lib_id_recalc_tag(bmain, &ntree->id);
+                                                       break;
+                                               }
+                                       }
+                               }
+                       } FOREACH_NODETREE_END
+               }
+
                if (idtype == ID_MSK) {
                        if (sce->nodetree) {
                                bNode *node;
index 7c021cf6645e993ecb9ac96042f838eca54fb9db..4ae05d8f64f6c1f1759278c177a60ac6e1c338d7 100644 (file)
@@ -48,6 +48,7 @@
 
 #include "BKE_colortools.h"
 #include "BKE_context.h"
+#include "BKE_depsgraph.h"
 #include "BKE_icons.h"
 #include "BKE_image.h"
 #include "BKE_global.h"
@@ -1866,6 +1867,7 @@ static int image_reload_exec(bContext *C, wmOperator *UNUSED(op))
        
        // XXX other users?
        BKE_image_signal(ima, (sima) ? &sima->iuser : NULL, IMA_SIGNAL_RELOAD);
+       DAG_id_tag_update(&ima->id, 0);
 
        WM_event_add_notifier(C, NC_IMAGE | NA_EDITED, ima);