Cycles: svn merge -r36352:36495 https://svn.blender.org/svnroot/bf-blender/trunk...
[blender.git] / source / blender / editors / render / render_preview.c
index 1abf5df223c86c6c9a9f89cb2f4e02d5790d739f..c94ce46c40e869c9d40b05253c115f8e0906ec0a 100644 (file)
@@ -74,7 +74,9 @@
 #include "BKE_main.h"
 #include "BKE_material.h"
 #include "BKE_node.h"
+#include "BKE_object.h"
 #include "BKE_texture.h"
+#include "BKE_world.h"
 
 #include "IMB_imbuf.h"
 #include "IMB_imbuf_types.h"
@@ -158,9 +160,11 @@ typedef struct ShaderPreview {
        ID *parent;
        MTex *slot;
        
-       /* node materials/texture need full copy during preview render, glsl uses it too */
+       /* datablocks with nodes need full copy during preview render, glsl uses it too */
        Material *matcopy;
        Tex *texcopy;
+       Lamp *lampcopy;
+       World *worldcopy;
        
        float col[4];           /* active object color */
        
@@ -385,7 +389,7 @@ static Scene *preview_prepare_scene(Scene *scene, ID *id, int id_type, ShaderPre
                if(id_type==ID_MA) {
                        Material *mat= NULL, *origmat= (Material *)id;
                        
-                       if(id) {
+                       if(origmat) {
                                /* work on a copy */
                                mat= localize_material(origmat);
                                sp->matcopy= mat;
@@ -515,7 +519,14 @@ static Scene *preview_prepare_scene(Scene *scene, ID *id, int id_type, ShaderPre
                        }
                }
                else if(id_type==ID_LA) {
-                       Lamp *la= (Lamp *)id;
+                       Lamp *la= NULL, *origla= (Lamp *)id;
+
+                       /* work on a copy */
+                       if(origla) {
+                               la= localize_lamp(origla);
+                               sp->lampcopy= la;
+                               BLI_addtail(&pr_main->lamp, la);
+                       }
                        
                        if(la && la->type==LA_SUN && (la->sun_effect_type & LA_SUN_EFFECT_SKY)) {
                                sce->lay= 1<<MA_ATMOS;
@@ -535,10 +546,30 @@ static Scene *preview_prepare_scene(Scene *scene, ID *id, int id_type, ShaderPre
                                                base->object->data= la;
                                }
                        }
+
+                       if(la && la->nodetree && sp->pr_method==PR_NODE_RENDER) {
+                               /* two previews, they get copied by wmJob */
+                               ntreeInitPreview(origla->nodetree, sp->sizex, sp->sizey);
+                               ntreeInitPreview(la->nodetree, sp->sizex, sp->sizey);
+                       }
                }
                else if(id_type==ID_WO) {
+                       World *wrld= NULL, *origwrld= (World *)id;
+
+                       if(origwrld) {
+                               wrld= localize_world(origwrld);
+                               sp->worldcopy= wrld;
+                               BLI_addtail(&pr_main->world, wrld);
+                       }
+
                        sce->lay= 1<<MA_SKY;
-                       sce->world= (World *)id;
+                       sce->world= wrld;
+
+                       if(wrld && wrld->nodetree && sp->pr_method==PR_NODE_RENDER) {
+                               /* two previews, they get copied by wmJob */
+                               ntreeInitPreview(wrld->nodetree, sp->sizex, sp->sizey);
+                               ntreeInitPreview(origwrld->nodetree, sp->sizex, sp->sizey);
+                       }
                }
                
                return sce;
@@ -988,6 +1019,18 @@ static void shader_preview_updatejob(void *spv)
                                if(sp->texcopy && tex->nodetree && sp->texcopy->nodetree)
                                        ntreeLocalSync(sp->texcopy->nodetree, tex->nodetree);
                        }
+                       else if( GS(sp->id->name) == ID_WO) {
+                               World *wrld= (World *)sp->id;
+                               
+                               if(sp->worldcopy && wrld->nodetree && sp->worldcopy->nodetree)
+                                       ntreeLocalSync(sp->worldcopy->nodetree, wrld->nodetree);
+                       }
+                       else if( GS(sp->id->name) == ID_LA) {
+                               Lamp *la= (Lamp *)sp->id;
+                               
+                               if(sp->lampcopy && la->nodetree && sp->lampcopy->nodetree)
+                                       ntreeLocalSync(sp->lampcopy->nodetree, la->nodetree);
+                       }
                }               
        }
 }
@@ -1148,6 +1191,38 @@ static void shader_preview_free(void *customdata)
                }
                MEM_freeN(sp->texcopy);
        }
+       if(sp->worldcopy) {
+               struct IDProperty *properties;
+               /* node previews */
+               shader_preview_updatejob(sp);
+               
+               /* get rid of copied world */
+               BLI_remlink(&pr_main->world, sp->worldcopy);
+               free_world(sp->worldcopy);
+               
+               properties= IDP_GetProperties((ID *)sp->worldcopy, FALSE);
+               if (properties) {
+                       IDP_FreeProperty(properties);
+                       MEM_freeN(properties);
+               }
+               MEM_freeN(sp->worldcopy);
+       }
+       if(sp->lampcopy) {
+               struct IDProperty *properties;
+               /* node previews */
+               shader_preview_updatejob(sp);
+               
+               /* get rid of copied lamp */
+               BLI_remlink(&pr_main->lamp, sp->lampcopy);
+               free_lamp(sp->lampcopy);
+               
+               properties= IDP_GetProperties((ID *)sp->lampcopy, FALSE);
+               if (properties) {
+                       IDP_FreeProperty(properties);
+                       MEM_freeN(properties);
+               }
+               MEM_freeN(sp->lampcopy);
+       }
        
        MEM_freeN(sp);
 }