Nodes: add support for shader nodes on world and lamps, in addition to materials.
authorBrecht Van Lommel <brechtvanlommel@pandora.be>
Wed, 2 Nov 2011 18:55:32 +0000 (18:55 +0000)
committerBrecht Van Lommel <brechtvanlommel@pandora.be>
Wed, 2 Nov 2011 18:55:32 +0000 (18:55 +0000)
The internal render engine does not support them, and they are not accesible in
the UI yet, but cycles will use them.

23 files changed:
release/scripts/startup/bl_ui/space_node.py
source/blender/blenkernel/intern/anim_sys.c
source/blender/blenkernel/intern/object.c
source/blender/blenkernel/intern/world.c
source/blender/blenloader/intern/readfile.c
source/blender/blenloader/intern/writefile.c
source/blender/editors/include/ED_node.h
source/blender/editors/render/render_preview.c
source/blender/editors/render/render_update.c
source/blender/editors/space_node/node_draw.c
source/blender/editors/space_node/node_edit.c
source/blender/editors/space_node/space_node.c
source/blender/makesdna/DNA_lamp_types.h
source/blender/makesdna/DNA_space_types.h
source/blender/makesdna/DNA_world_types.h
source/blender/makesrna/intern/rna_lamp.c
source/blender/makesrna/intern/rna_material.c
source/blender/makesrna/intern/rna_nodetree.c
source/blender/makesrna/intern/rna_object.c
source/blender/makesrna/intern/rna_space.c
source/blender/makesrna/intern/rna_world.c
source/blender/nodes/shader/node_shader_tree.c
source/blender/nodes/shader/node_shader_util.c

index 708017b..2b2cc50 100644 (file)
@@ -42,7 +42,7 @@ class NODE_HT_header(Header):
 
         layout.prop(snode, "tree_type", text="", expand=True)
 
-        if snode.tree_type == 'MATERIAL':
+        if snode.tree_type == 'SHADER':
             if id_from:
                 layout.template_ID(id_from, "active_material", new="material.new")
             if snode_id:
index 13abf18..981c20d 100644 (file)
 #include "BLI_utildefines.h"
 
 #include "DNA_anim_types.h"
+#include "DNA_lamp_types.h"
 #include "DNA_material_types.h"
 #include "DNA_scene_types.h"
 #include "DNA_texture_types.h"
+#include "DNA_world_types.h"
 
 #include "BKE_animsys.h"
 #include "BKE_action.h"
@@ -2291,7 +2293,7 @@ void BKE_animsys_evaluate_all_animation (Main *main, Scene *scene, float ctime)
        EVAL_ANIM_NODETREE_IDS(main->tex.first, Tex, ADT_RECALC_ANIM);
        
        /* lamps */
-       EVAL_ANIM_IDS(main->lamp.first, ADT_RECALC_ANIM);
+       EVAL_ANIM_NODETREE_IDS(main->lamp.first, Lamp, ADT_RECALC_ANIM);
        
        /* materials */
        EVAL_ANIM_NODETREE_IDS(main->mat.first, Material, ADT_RECALC_ANIM);
@@ -2331,7 +2333,7 @@ void BKE_animsys_evaluate_all_animation (Main *main, Scene *scene, float ctime)
        EVAL_ANIM_IDS(main->object.first, 0); 
        
        /* worlds */
-       EVAL_ANIM_IDS(main->world.first, ADT_RECALC_ANIM);
+       EVAL_ANIM_NODETREE_IDS(main->world.first, World, ADT_RECALC_ANIM);
        
        /* scenes */
        EVAL_ANIM_NODETREE_IDS(main->scene.first, Scene, ADT_RECALC_ANIM);
index 635e074..a5edd56 100644 (file)
@@ -86,6 +86,7 @@
 #include "BKE_mesh.h"
 #include "BKE_mball.h"
 #include "BKE_modifier.h"
+#include "BKE_node.h"
 #include "BKE_object.h"
 #include "BKE_paint.h"
 #include "BKE_particle.h"
@@ -877,6 +878,9 @@ Lamp *copy_lamp(Lamp *la)
        }
        
        lan->curfalloff = curvemapping_copy(la->curfalloff);
+
+       if(la->nodetree)
+               lan->nodetree= ntreeCopyTree(la->nodetree);
        
        if(la->preview)
                lan->preview = BKE_previewimg_copy(la->preview);
@@ -903,6 +907,9 @@ Lamp *localize_lamp(Lamp *la)
        
        lan->curfalloff = curvemapping_copy(la->curfalloff);
 
+       if(la->nodetree)
+               lan->nodetree= ntreeLocalize(la->nodetree);
+       
        lan->preview= NULL;
        
        return lan;
@@ -978,6 +985,12 @@ void free_lamp(Lamp *la)
        BKE_free_animdata((ID *)la);
 
        curvemapping_free(la->curfalloff);
+
+       /* is no lib link block, but lamp extension */
+       if(la->nodetree) {
+               ntreeFreeTree(la->nodetree);
+               MEM_freeN(la->nodetree);
+       }
        
        BKE_previewimg_free(&la->preview);
        BKE_icon_delete(&la->id);
index 5797c6c..c7d2763 100644 (file)
 #include "BLI_utildefines.h"
 #include "BLI_bpath.h"
 
-#include "BKE_world.h"
-#include "BKE_library.h"
 #include "BKE_animsys.h"
 #include "BKE_global.h"
-#include "BKE_main.h"
 #include "BKE_icons.h"
+#include "BKE_library.h"
+#include "BKE_library.h"
+#include "BKE_main.h"
+#include "BKE_node.h"
+#include "BKE_world.h"
 
 void free_world(World *wrld)
 {
@@ -63,6 +65,12 @@ void free_world(World *wrld)
 
        BKE_free_animdata((ID *)wrld);
 
+       /* is no lib link block, but world extension */
+       if(wrld->nodetree) {
+               ntreeFreeTree(wrld->nodetree);
+               MEM_freeN(wrld->nodetree);
+       }
+
        BKE_icon_delete((struct ID*)wrld);
        wrld->id.icon_id = 0;
 }
@@ -119,6 +127,9 @@ World *copy_world(World *wrld)
                        id_us_plus((ID *)wrldn->mtex[a]->tex);
                }
        }
+
+       if(wrld->nodetree)
+               wrldn->nodetree= ntreeCopyTree(wrld->nodetree);
        
        if(wrld->preview)
                wrldn->preview = BKE_previewimg_copy(wrld->preview);
@@ -143,6 +154,9 @@ World *localize_world(World *wrld)
                }
        }
 
+       if(wrld->nodetree)
+               wrldn->nodetree= ntreeLocalize(wrld->nodetree);
+       
        wrldn->preview= NULL;
        
        return wrldn;
index b1a3182..15f5b49 100644 (file)
@@ -2182,6 +2182,7 @@ static void lib_verify_nodetree(Main *main, int UNUSED(open))
                for(ntree= main->nodetree.first; ntree; ntree= ntree->id.next)
                        if (ntree->update)
                                ntreeUpdateTree(ntree);
+
                for (i=0; i < NUM_NTREE_TYPES; ++i) {
                        ntreetype= ntreeGetType(i);
                        if (ntreetype && ntreetype->foreach_nodetree)
@@ -2507,6 +2508,9 @@ static void lib_link_lamp(FileData *fd, Main *main)
                        }
                        
                        la->ipo= newlibadr_us(fd, la->id.lib, la->ipo); // XXX depreceated - old animation system
+
+                       if(la->nodetree)
+                               lib_link_ntree(fd, &la->id, la->nodetree);
                        
                        la->id.flag -= LIB_NEEDLINK;
                }
@@ -2528,6 +2532,10 @@ static void direct_link_lamp(FileData *fd, Lamp *la)
        la->curfalloff= newdataadr(fd, la->curfalloff);
        if(la->curfalloff)
                direct_link_curvemapping(fd, la->curfalloff);
+
+       la->nodetree= newdataadr(fd, la->nodetree);
+       if(la->nodetree)
+               direct_link_nodetree(fd, la->nodetree);
        
        la->preview = direct_link_preview_image(fd, la->preview);
 }
@@ -2670,6 +2678,9 @@ static void lib_link_world(FileData *fd, Main *main)
                                        mtex->object= newlibadr(fd, wrld->id.lib, mtex->object);
                                }
                        }
+
+                       if(wrld->nodetree)
+                               lib_link_ntree(fd, &wrld->id, wrld->nodetree);
                        
                        wrld->id.flag -= LIB_NEEDLINK;
                }
@@ -2687,6 +2698,11 @@ static void direct_link_world(FileData *fd, World *wrld)
        for(a=0; a<MAX_MTEX; a++) {
                wrld->mtex[a]= newdataadr(fd, wrld->mtex[a]);
        }
+
+       wrld->nodetree= newdataadr(fd, wrld->nodetree);
+       if(wrld->nodetree)
+               direct_link_nodetree(fd, wrld->nodetree);
+
        wrld->preview = direct_link_preview_image(fd, wrld->preview);
 }
 
@@ -5004,6 +5020,10 @@ static void lib_link_screen(FileData *fd, Main *main)
                                                        if(snode->id) {
                                                                if(GS(snode->id->name)==ID_MA)
                                                                        snode->nodetree= ((Material *)snode->id)->nodetree;
+                                                               else if(GS(snode->id->name)==ID_WO)
+                                                                       snode->nodetree= ((World *)snode->id)->nodetree;
+                                                               else if(GS(snode->id->name)==ID_LA)
+                                                                       snode->nodetree= ((Lamp *)snode->id)->nodetree;
                                                                else if(GS(snode->id->name)==ID_SCE)
                                                                        snode->nodetree= ((Scene *)snode->id)->nodetree;
                                                                else if(GS(snode->id->name)==ID_TE)
@@ -12723,6 +12743,9 @@ static void expand_lamp(FileData *fd, Main *mainvar, Lamp *la)
        
        if (la->adt)
                expand_animdata(fd, mainvar, la->adt);
+
+       if(la->nodetree)
+               expand_nodetree(fd, mainvar, la->nodetree);
 }
 
 static void expand_lattice(FileData *fd, Main *mainvar, Lattice *lt)
@@ -12750,6 +12773,9 @@ static void expand_world(FileData *fd, Main *mainvar, World *wrld)
        
        if (wrld->adt)
                expand_animdata(fd, mainvar, wrld->adt);
+
+       if(wrld->nodetree)
+               expand_nodetree(fd, mainvar, wrld->nodetree);
 }
 
 
index 4640fa0..1e0ef4a 100644 (file)
@@ -1857,6 +1857,12 @@ static void write_worlds(WriteData *wd, ListBase *idbase)
                        for(a=0; a<MAX_MTEX; a++) {
                                if(wrld->mtex[a]) writestruct(wd, DATA, "MTex", 1, wrld->mtex[a]);
                        }
+
+                       /* nodetree is integral part of lamps, no libdata */
+                       if(wrld->nodetree) {
+                               writestruct(wd, DATA, "bNodeTree", 1, wrld->nodetree);
+                               write_nodetree(wd, wrld->nodetree);
+                       }
                        
                        write_previews(wd, wrld->preview);
                }
@@ -1886,6 +1892,12 @@ static void write_lamps(WriteData *wd, ListBase *idbase)
                        if(la->curfalloff)
                                write_curvemapping(wd, la->curfalloff); 
                        
+                       /* nodetree is integral part of lamps, no libdata */
+                       if(la->nodetree) {
+                               writestruct(wd, DATA, "bNodeTree", 1, la->nodetree);
+                               write_nodetree(wd, la->nodetree);
+                       }
+
                        write_previews(wd, la->preview);
                        
                }
index b6cb59e..18bb497 100644 (file)
@@ -51,7 +51,7 @@ void ED_node_changed_update(struct ID *id, struct bNode *node);
 void ED_node_generic_update(struct Main *bmain, struct bNodeTree *ntree, struct bNode *node);
 
 /* node_edit.c */
-void ED_node_shader_default(struct Material *ma);
+void ED_node_shader_default(struct Scene *scene, struct ID *id);
 void ED_node_composit_default(struct Scene *sce);
 void ED_node_texture_default(struct Tex *tex);
 void ED_node_link_intersect_test(struct ScrArea *sa, int test);
index 49bdb10..9da1609 100644 (file)
@@ -420,6 +420,12 @@ 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;
@@ -432,6 +438,12 @@ static Scene *preview_prepare_scene(Scene *scene, ID *id, int id_type, ShaderPre
 
                        sce->lay= 1<<MA_SKY;
                        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;
@@ -566,6 +578,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);
+                       }
                }               
        }
 }
index c4ce695..72ea79f 100644 (file)
@@ -234,6 +234,7 @@ static void texture_changed(Main *bmain, Tex *tex)
        /* find lamps */
        for(la=bmain->lamp.first; la; la=la->id.next) {
                if(mtex_use_tex(la->mtex, MAX_MTEX, tex));
+               else if(la->nodetree && nodes_use_tex(la->nodetree, tex));
                else continue;
 
                BKE_icon_changed(BKE_icon_getid(&la->id));
@@ -242,6 +243,7 @@ static void texture_changed(Main *bmain, Tex *tex)
        /* find worlds */
        for(wo=bmain->world.first; wo; wo=wo->id.next) {
                if(mtex_use_tex(wo->mtex, MAX_MTEX, tex));
+               else if(wo->nodetree && nodes_use_tex(wo->nodetree, tex));
                else continue;
 
                BKE_icon_changed(BKE_icon_getid(&wo->id));
index fd7a6ee..c2a2f31 100644 (file)
 #include "MEM_guardedalloc.h"
 
 #include "DNA_node_types.h"
+#include "DNA_lamp_types.h"
 #include "DNA_material_types.h"
 #include "DNA_object_types.h"
 #include "DNA_scene_types.h"
 #include "DNA_space_types.h"
 #include "DNA_screen_types.h"
+#include "DNA_world_types.h"
 
 #include "BLI_math.h"
 #include "BLI_blenlib.h"
@@ -97,7 +99,13 @@ void ED_node_changed_update(ID *id, bNode *node)
 
        if(treetype==NTREE_SHADER) {
                DAG_id_tag_update(id, 0);
-               WM_main_add_notifier(NC_MATERIAL|ND_SHADING_DRAW, id);
+
+               if(GS(id->name) == ID_MA)
+                       WM_main_add_notifier(NC_MATERIAL|ND_SHADING_DRAW, id);
+               else if(GS(id->name) == ID_LA)
+                       WM_main_add_notifier(NC_LAMP|ND_LIGHTING_DRAW, id);
+               else if(GS(id->name) == ID_WO)
+                       WM_main_add_notifier(NC_WORLD|ND_WORLD_DRAW, id);
        }
        else if(treetype==NTREE_COMPOSIT) {
                nodeUpdate(edittree, node);
index 4c98028..c1e50c1 100644 (file)
 #include "MEM_guardedalloc.h"
 
 #include "DNA_ID.h"
-#include "DNA_object_types.h"
+#include "DNA_lamp_types.h"
 #include "DNA_material_types.h"
 #include "DNA_node_types.h"
+#include "DNA_object_types.h"
 #include "DNA_particle_types.h"
 #include "DNA_scene_types.h"
+#include "DNA_world_types.h"
 
 #include "BLI_math.h"
 #include "BLI_blenlib.h"
@@ -267,36 +269,61 @@ bNode *node_tree_get_editgroup(bNodeTree *nodetree)
 
 /* assumes nothing being done in ntree yet, sets the default in/out node */
 /* called from shading buttons or header */
-void ED_node_shader_default(Material *ma)
+void ED_node_shader_default(Scene *UNUSED(scene), ID *id)
 {
        bNode *in, *out;
        bNodeSocket *fromsock, *tosock;
+       bNodeTree *ntree;
        bNodeTemplate ntemp;
+       int output_type, shader_type;
        
-       /* but lets check it anyway */
-       if(ma->nodetree) {
-               if (G.f & G_DEBUG)
-                       printf("error in shader initialize\n");
-               return;
+       ntree= ntreeAddTree("Shader Nodetree", NTREE_SHADER, 0);
+
+       switch(GS(id->name)) {
+               case ID_MA: {
+                       Material *ma= (Material*)id;
+                       ma->nodetree = ntree;
+
+                       output_type = SH_NODE_OUTPUT;
+                       shader_type = SH_NODE_MATERIAL;
+                       break;
+               }
+               case ID_WO: {
+                       World *wo= (World*)id;
+                       wo->nodetree = ntree;
+
+                       output_type = SH_NODE_OUTPUT;
+                       shader_type = SH_NODE_MATERIAL;
+                       break;
+               }
+               case ID_LA: {
+                       Lamp *la= (Lamp*)id;
+                       la->nodetree = ntree;
+
+                       output_type = SH_NODE_OUTPUT;
+                       shader_type = SH_NODE_MATERIAL;
+                       break;
+               }
+               default:
+                       printf("ED_node_shader_default called on wrong ID type.\n");
+                       return;
        }
        
-       ma->nodetree= ntreeAddTree("Shader Nodetree", NTREE_SHADER, 0);
-       
-       ntemp.type = SH_NODE_OUTPUT;
-       out= nodeAddNode(ma->nodetree, &ntemp);
+       ntemp.type = output_type;
+       out= nodeAddNode(ntree, &ntemp);
        out->locx= 300.0f; out->locy= 300.0f;
        
-       ntemp.type = SH_NODE_MATERIAL;
-       in= nodeAddNode(ma->nodetree, &ntemp);
+       ntemp.type = shader_type;
+       in= nodeAddNode(ntree, &ntemp);
        in->locx= 10.0f; in->locy= 300.0f;
-       nodeSetActive(ma->nodetree, in);
+       nodeSetActive(ntree, in);
        
        /* only a link from color to color */
        fromsock= in->outputs.first;
        tosock= out->inputs.first;
-       nodeAddLink(ma->nodetree, in, fromsock, out, tosock);
+       nodeAddLink(ntree, in, fromsock, out, tosock);
        
-       ntreeUpdateTree(ma->nodetree);
+       ntreeUpdateTree(ntree);
 }
 
 /* assumes nothing being done in ntree yet, sets the default in/out node */
@@ -387,6 +414,14 @@ void node_tree_from_ID(ID *id, bNodeTree **ntree, bNodeTree **edittree, int *tre
                        *ntree= ((Material*)id)->nodetree;
                        if(treetype) *treetype= NTREE_SHADER;
                }
+               else if(idtype == ID_LA) {
+                       *ntree= ((Lamp*)id)->nodetree;
+                       if(treetype) *treetype= NTREE_SHADER;
+               }
+               else if(idtype == ID_WO) {
+                       *ntree= ((World*)id)->nodetree;
+                       if(treetype) *treetype= NTREE_SHADER;
+               }
                else if(idtype == ID_SCE) {
                        *ntree= ((Scene*)id)->nodetree;
                        if(treetype) *treetype= NTREE_COMPOSIT;
@@ -428,11 +463,25 @@ void snode_set_context(SpaceNode *snode, Scene *scene)
        
        if(snode->treetype==NTREE_SHADER) {
                /* need active object, or we allow pinning... */
-               if(ob) {
-                       Material *ma= give_current_material(ob, ob->actcol);
-                       if(ma) {
-                               snode->from= &ob->id;
-                               snode->id= &ma->id;
+               if(snode->shaderfrom == SNODE_SHADER_OBJECT) {
+                       if(ob) {
+                               if(ob->type == OB_LAMP) {
+                                       snode->from= &ob->id;
+                                       snode->id= ob->data;
+                               }
+                               else {
+                                       Material *ma= give_current_material(ob, ob->actcol);
+                                       if(ma) {
+                                               snode->from= &ob->id;
+                                               snode->id= &ma->id;
+                                       }
+                               }
+                       }
+               }
+               else { /* SNODE_SHADER_WORLD */
+                       if(scene->world) {
+                               snode->from= NULL;
+                               snode->id= &scene->world->id;
                        }
                }
        }
@@ -526,7 +575,7 @@ void ED_node_set_active(Main *bmain, bNodeTree *ntree, bNode *node)
                /* tree specific activate calls */
                if(ntree->type==NTREE_SHADER) {
                        /* when we select a material, active texture is cleared, for buttons */
-                       if(node->id && GS(node->id->name)==ID_MA)
+                       if(node->id && ELEM3(GS(node->id->name), ID_MA, ID_LA, ID_WO))
                                nodeClearActiveID(ntree, ID_TE);
                        
                        if(node->type==SH_NODE_OUTPUT) {
index 35b8666..1a808e8 100644 (file)
 #include <string.h>
 #include <stdio.h>
 
+#include "DNA_lamp_types.h"
+#include "DNA_material_types.h"
 #include "DNA_node_types.h"
 #include "DNA_object_types.h"
-#include "DNA_material_types.h"
 #include "DNA_scene_types.h"
+#include "DNA_world_types.h"
 
 #include "MEM_guardedalloc.h"
 
@@ -268,9 +270,21 @@ static void node_area_refresh(const struct bContext *C, struct ScrArea *sa)
        
        if(snode->nodetree) {
                if(snode->treetype==NTREE_SHADER) {
-                       Material *ma= (Material *)snode->id;
-                       if(ma->use_nodes)
-                               ED_preview_shader_job(C, sa, snode->id, NULL, NULL, 100, 100, PR_NODE_RENDER);
+                       if(GS(snode->id->name) == ID_MA) {
+                               Material *ma= (Material *)snode->id;
+                               if(ma->use_nodes)
+                                       ED_preview_shader_job(C, sa, snode->id, NULL, NULL, 100, 100, PR_NODE_RENDER);
+                       }
+                       else if(GS(snode->id->name) == ID_LA) {
+                               Lamp *la= (Lamp *)snode->id;
+                               if(la->use_nodes)
+                                       ED_preview_shader_job(C, sa, snode->id, NULL, NULL, 100, 100, PR_NODE_RENDER);
+                       }
+                       else if(GS(snode->id->name) == ID_WO) {
+                               World *wo= (World *)snode->id;
+                               if(wo->use_nodes)
+                                       ED_preview_shader_job(C, sa, snode->id, NULL, NULL, 100, 100, PR_NODE_RENDER);
+                       }
                }
                else if(snode->treetype==NTREE_COMPOSIT) {
                        Scene *scene= (Scene *)snode->id;
@@ -426,6 +440,10 @@ static void node_region_listener(ARegion *ar, wmNotifier *wmn)
                case NC_NODE:
                        ED_region_tag_redraw(ar);
                        break;
+               case NC_OBJECT:
+                       if(wmn->data==ND_OB_SHADING)
+                               ED_region_tag_redraw(ar);
+                       break;
                case NC_ID:
                        if(wmn->action == NA_RENAME)
                                ED_region_tag_redraw(ar);
index e365734..91930f5 100644 (file)
 #define MAX_MTEX       18
 #endif
 
-struct MTex;
-struct CurveMapping;
 struct AnimData;
+struct bNodeTree;
+struct CurveMapping;
 struct Ipo;
+struct MTex;
 
 typedef struct Lamp {
        ID id;
@@ -98,11 +99,14 @@ typedef struct Lamp {
 
        struct Ipo *ipo;                                // XXX depreceated... old animation system
        struct MTex *mtex[18];                  /* MAX_MTEX */
-       short pr_texture;
-       char pad6[6];
+       short pr_texture, use_nodes;
+       char pad6[4];
 
        /* preview */
        struct PreviewImage *preview;
+
+       /* nodes */
+       struct bNodeTree *nodetree;     
 } Lamp;
 
 /* **************** LAMP ********************* */
index 37c2ea5..0c7943c 100644 (file)
@@ -400,7 +400,9 @@ typedef struct SpaceNode {
        struct bNodeTree *nodetree, *edittree;
        int treetype;           /* treetype: as same nodetree->type */
        short texfrom;          /* texfrom object, world or brush */
+       short shaderfrom;       /* shader from object or world */
        short recalc;           /* currently on 0/1, for auto compo */
+       short pad[3];
        ListBase linkdrag;      /* temporary data for modal linking operator */
        
        struct bGPdata *gpd;            /* grease-pencil data */
@@ -418,6 +420,10 @@ typedef struct SpaceNode {
 #define SNODE_TEX_WORLD                1
 #define SNODE_TEX_BRUSH                2
 
+/* snode->shaderfrom */
+#define SNODE_SHADER_OBJECT    0
+#define SNODE_SHADER_WORLD     1
+
 typedef struct SpaceLogic {
        SpaceLink *next, *prev;
        ListBase regionbase;            /* storage of regions for inactive spaces */
index 2bc384b..0c45502 100644 (file)
@@ -34,6 +34,7 @@
 #include "DNA_ID.h"
 
 struct AnimData;
+struct bNodeTree;
 struct Ipo;
 struct MTex;
 
@@ -120,11 +121,14 @@ typedef struct World {
        
        struct Ipo *ipo;                        // XXX depreceated... old animation system
        struct MTex *mtex[18];          /* MAX_MTEX */
-       short pr_texture, pad[3];
+       short pr_texture, use_nodes, pad[2];
 
        /* previews */
        struct PreviewImage *preview;
 
+       /* nodes */
+       struct bNodeTree *nodetree;     
+
 } World;
 
 /* **************** WORLD ********************* */
index 5725595..629711f 100644 (file)
@@ -46,6 +46,7 @@
 #include "BKE_main.h"
 #include "BKE_texture.h"
 
+#include "ED_node.h"
 #include "WM_api.h"
 #include "WM_types.h"
 
@@ -145,6 +146,15 @@ static void rna_Lamp_spot_size_set(PointerRNA *ptr, float value)
        la->spotsize= RAD2DEGF(value);
 }
 
+static void rna_Lamp_use_nodes_update(Main *blain, Scene *scene, PointerRNA *ptr)
+{
+       Lamp *la= (Lamp*)ptr->data;
+
+       if(la->use_nodes && la->nodetree==NULL)
+               ED_node_shader_default(scene, &la->id);
+       
+       rna_Lamp_update(blain, scene, ptr);
+}
 
 #else
 
@@ -366,6 +376,17 @@ static void rna_def_lamp(BlenderRNA *brna)
        RNA_def_property_boolean_negative_sdna(prop, NULL, "mode", LA_NO_DIFF);
        RNA_def_property_ui_text(prop, "Diffuse", "Lamp does diffuse shading");
        RNA_def_property_update(prop, 0, "rna_Lamp_update");
+
+       /* nodes */
+       prop= RNA_def_property(srna, "node_tree", PROP_POINTER, PROP_NONE);
+       RNA_def_property_pointer_sdna(prop, NULL, "nodetree");
+       RNA_def_property_ui_text(prop, "Node Tree", "Node tree for node based lamps");
+
+       prop= RNA_def_property(srna, "use_nodes", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_boolean_sdna(prop, NULL, "use_nodes", 1);
+       RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+       RNA_def_property_ui_text(prop, "Use Nodes", "Use shader nodes to render the lamp");
+       RNA_def_property_update(prop, 0, "rna_Lamp_use_nodes_update");
        
        /* common */
        rna_def_animdata_common(srna);
index 990d3b8..57770be 100644 (file)
@@ -269,13 +269,14 @@ static void rna_Material_use_specular_ramp_set(PointerRNA *ptr, int value)
                ma->ramp_spec= add_colorband(0);
 }
 
-static void rna_Material_use_nodes_set(PointerRNA *ptr, int value)
+static void rna_Material_use_nodes_update(Main *bmain, Scene *scene, PointerRNA *ptr)
 {
        Material *ma= (Material*)ptr->data;
 
-       ma->use_nodes= value;
        if(ma->use_nodes && ma->nodetree==NULL)
-               ED_node_shader_default(ma);
+               ED_node_shader_default(scene, &ma->id);
+       
+       rna_Material_update(bmain, scene, ptr);
 }
 
 static EnumPropertyItem *rna_Material_texture_coordinates_itemf(bContext *UNUSED(C), PointerRNA *ptr,
@@ -1954,9 +1955,9 @@ void RNA_def_material(BlenderRNA *brna)
 
        prop= RNA_def_property(srna, "use_nodes", PROP_BOOLEAN, PROP_NONE);
        RNA_def_property_boolean_sdna(prop, NULL, "use_nodes", 1);
-       RNA_def_property_boolean_funcs(prop, NULL, "rna_Material_use_nodes_set");
+       RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
        RNA_def_property_ui_text(prop, "Use Nodes", "Use shader nodes to render the material");
-       RNA_def_property_update(prop, 0, "rna_Material_update");
+       RNA_def_property_update(prop, 0, "rna_Material_use_nodes_update");
 
        prop= RNA_def_property(srna, "active_node_material", PROP_POINTER, PROP_NONE);
        RNA_def_property_struct_type(prop, "Material");
index 96c23ef..1445cf3 100644 (file)
@@ -56,7 +56,7 @@
 #include "MEM_guardedalloc.h"
 
 EnumPropertyItem nodetree_type_items[] = {
-       {NTREE_SHADER,          "MATERIAL",             ICON_MATERIAL,          "Material",             "Material nodes"        },
+       {NTREE_SHADER,          "SHADER",               ICON_MATERIAL,          "Shader",               "Shader nodes"  },
        {NTREE_TEXTURE,         "TEXTURE",              ICON_TEXTURE,           "Texture",              "Texture nodes"         },
        {NTREE_COMPOSIT,        "COMPOSITING",  ICON_RENDERLAYERS,      "Compositing",  "Compositing nodes"     },
        {0, NULL, 0, NULL, NULL}
@@ -189,7 +189,7 @@ static StructRNA *rna_NodeTree_refine(struct PointerRNA *ptr)
                case NTREE_TEXTURE:
                        return &RNA_TextureNodeTree;
                default:
-                       return &RNA_UnknownType;
+                       return &RNA_NodeTree;
        }
 }
 
@@ -232,6 +232,8 @@ static StructRNA *rna_NodeSocket_refine(PointerRNA *ptr)
                case SOCK_RGBA:
                        return &RNA_NodeSocketRGBA;
                        break;
+               case SOCK_SHADER:
+                       return &RNA_NodeSocketShader;
                }
                
                #undef SUBTYPE
@@ -2998,6 +3000,7 @@ void RNA_def_nodetree(BlenderRNA *brna)
        #undef SUBTYPE
        rna_def_node_socket_subtype(brna, SOCK_BOOLEAN, 0, "NodeSocketBoolean", "Boolean Node Socket");
        rna_def_node_socket_subtype(brna, SOCK_RGBA, 0, "NodeSocketRGBA", "RGBA Node Socket");
+       rna_def_node_socket_subtype(brna, SOCK_SHADER, 0, "NodeSocketShader", "Shader Closure Node Socket");
        
        rna_def_node(brna);
        rna_def_node_link(brna);
index f0ba435..137eebe 100644 (file)
@@ -1793,7 +1793,6 @@ static void rna_def_object(BlenderRNA *brna)
                {OB_BOUNDBOX, "BOUNDS", 0, "Bounds", "Draw the bounding box of the object"},
                {OB_WIRE, "WIRE", 0, "Wire", "Draw the object as a wireframe"},
                {OB_SOLID, "SOLID", 0, "Solid", "Draw the object as a solid (if solid drawing is enabled in the viewport)"},
-               // disabled {OB_SHADED, "SHADED", 0, "Shaded", ""},
                {OB_TEXTURE, "TEXTURED", 0, "Textured", "Draw the object with textures (if textures are enabled in the viewport)"},
                {0, NULL, 0, NULL, NULL}};
 
index 5c494a3..0dc4ca3 100644 (file)
@@ -2505,6 +2505,11 @@ static void rna_def_space_node(BlenderRNA *brna)
                {SNODE_TEX_BRUSH, "BRUSH", ICON_BRUSH_DATA, "Brush", "Edit texture nodes from Brush"},
                {0, NULL, 0, NULL, NULL}};
 
+       static EnumPropertyItem shader_type_items[] = {
+               {SNODE_SHADER_OBJECT, "OBJECT", ICON_OBJECT_DATA, "Object", "Edit shader nodes from Object"},
+               {SNODE_SHADER_WORLD, "WORLD", ICON_WORLD_DATA, "World", "Edit shader nodes from World"},
+               {0, NULL, 0, NULL, NULL}};
+
        static EnumPropertyItem backdrop_channels_items[] = {
                {0, "COLOR", ICON_IMAGE_RGB, "Color", "Draw image with RGB colors"},
                {SNODE_USE_ALPHA, "COLOR_ALPHA", ICON_IMAGE_RGB_ALPHA, "Color and Alpha",
@@ -2528,6 +2533,12 @@ static void rna_def_space_node(BlenderRNA *brna)
        RNA_def_property_ui_text(prop, "Texture Type", "Type of data to take texture from");
        RNA_def_property_update(prop, NC_SPACE|ND_SPACE_NODE, NULL);
 
+       prop= RNA_def_property(srna, "shader_type", PROP_ENUM, PROP_NONE);
+       RNA_def_property_enum_sdna(prop, NULL, "shaderfrom");
+       RNA_def_property_enum_items(prop, shader_type_items);
+       RNA_def_property_ui_text(prop, "Shader Type", "Type of data to take shader from");
+       RNA_def_property_update(prop, NC_SPACE|ND_SPACE_NODE, NULL);
+
        prop= RNA_def_property(srna, "id", PROP_POINTER, PROP_NONE);
        RNA_def_property_clear_flag(prop, PROP_EDITABLE);
        RNA_def_property_ui_text(prop, "ID", "Datablock whose nodes are being edited");
index 21ab9d9..d421aff 100644 (file)
@@ -46,6 +46,8 @@
 #include "BKE_main.h"
 #include "BKE_texture.h"
 
+#include "ED_node.h"
+
 #include "WM_api.h"
 
 static PointerRNA rna_World_lighting_get(PointerRNA *ptr)
@@ -119,6 +121,15 @@ static void rna_World_stars_update(Main *UNUSED(bmain), Scene *UNUSED(scene), Po
        WM_main_add_notifier(NC_WORLD|ND_WORLD_STARS, wo);
 }
 
+static void rna_World_use_nodes_update(Main *bmain, Scene *scene, PointerRNA *ptr)
+{
+       World *wrld= (World*)ptr->data;
+
+       if(wrld->use_nodes && wrld->nodetree==NULL)
+               ED_node_shader_default(scene, &wrld->id);
+       
+       rna_World_update(bmain, scene, ptr);
+}
 
 #else
 
@@ -552,6 +563,17 @@ void RNA_def_world(BlenderRNA *brna)
        RNA_def_property_pointer_funcs(prop, "rna_World_stars_get", NULL, NULL, NULL);
        RNA_def_property_ui_text(prop, "Stars", "World stars settings");
 
+       /* nodes */
+       prop= RNA_def_property(srna, "node_tree", PROP_POINTER, PROP_NONE);
+       RNA_def_property_pointer_sdna(prop, NULL, "nodetree");
+       RNA_def_property_ui_text(prop, "Node Tree", "Node tree for node based worlds");
+
+       prop= RNA_def_property(srna, "use_nodes", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_boolean_sdna(prop, NULL, "use_nodes", 1);
+       RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+       RNA_def_property_ui_text(prop, "Use Nodes", "Use shader nodes to render the world");
+       RNA_def_property_update(prop, 0, "rna_World_use_nodes_update");
+
        rna_def_lighting(brna);
        rna_def_world_mist(brna);
        rna_def_world_stars(brna);
index a83b320..d0ae179 100644 (file)
 
 #include <string.h>
 
+#include "DNA_lamp_types.h"
 #include "DNA_material_types.h"
 #include "DNA_node_types.h"
+#include "DNA_world_types.h"
 
 #include "BLI_listbase.h"
 #include "BLI_math.h"
 static void foreach_nodetree(Main *main, void *calldata, bNodeTreeCallback func)
 {
        Material *ma;
-       for(ma= main->mat.first; ma; ma= ma->id.next) {
-               if(ma->nodetree) {
+       Lamp *la;
+       World *wo;
+
+       for(ma= main->mat.first; ma; ma= ma->id.next)
+               if(ma->nodetree)
                        func(calldata, &ma->id, ma->nodetree);
-               }
-       }
+
+       for(la= main->lamp.first; la; la= la->id.next)
+               if(la->nodetree)
+                       func(calldata, &la->id, la->nodetree);
+
+       for(wo= main->world.first; wo; wo= wo->id.next)
+               if(wo->nodetree)
+                       func(calldata, &wo->id, wo->nodetree);
 }
 
 static void local_sync(bNodeTree *localtree, bNodeTree *ntree)
index 3b0211a..1acb04c 100644 (file)
@@ -205,6 +205,8 @@ void node_gpu_stack_from_data(struct GPUNodeStack *gs, int type, bNodeStack *ns)
                gs->type= GPU_VEC3;
        else if (type == SOCK_RGBA)
                gs->type= GPU_VEC4;
+       else if (type == SOCK_SHADER)
+               gs->type= GPU_VEC4;
        else
                gs->type= GPU_NONE;