Four-in-one commit:
authorTon Roosendaal <ton@blender.org>
Sat, 18 Feb 2006 13:28:44 +0000 (13:28 +0000)
committerTon Roosendaal <ton@blender.org>
Sat, 18 Feb 2006 13:28:44 +0000 (13:28 +0000)
(NOTE: new include dependency in Render module, might need MSVC update!
It has to include the imbuf/intern/openexr/ directory in search path)

-> New Composite node: "Hue Saturation".
Works like the former 'post process' menu. There's no gamma, brightness or
multiply needed in this node, for that the Curves Node functions better.

-> Enabled Toolbox in Node editor
This now also replaces the SHIFT+A for adding nodes. The nodes are
automatically added to the menus, using the 'class' category from the
type definition.

Current classes are (compositor examples):

Inputs: RenderResult, Image
Outputs: Composite, Viewer
Color Ops: RGB Curves, Mix, Hue Saturation, AlphaOver
Vector Ops: Normal, Vector Curves, Map Value
Filters: Filter, Blur, VectorBlur
Convertors: ColorRamp, RGBtoBW, Separate RGBA, Separate HSVA, Set Alpha
Generators: RGB, Value, Time
Groups: the list of custom defined nodes

-> OpenEXR tile saving support
Created an API for for saving tile-based Images with an unlimited amount
of layers/channels. I've tested it for 'render result' now, with the idea
that this can (optionally) replace the current inserting of tiles in the
main result buffers. Especially with a lot of layers, the used memory for
these buffers can easily go into the 100s of megs.
Two other advantages:
- all 'render result' layers can be saved entirely in a single file, for
  later use in compositing, also for animation output.
- on each render, per scene, a unique temp file can be stored, allowing
  to re-use these temp files on starting Blender or loading files, showing
  the last result of a render command.

The option is currently disabled, needs more work... but I had to commit
this because of the rest of the work I did!

-> Bug fix
The Image node didn't call an execute event when browsing another image.

15 files changed:
source/blender/blenkernel/BKE_node.h
source/blender/blenkernel/intern/node.c
source/blender/blenkernel/intern/node_composite.c
source/blender/blenkernel/intern/node_shaders.c
source/blender/imbuf/intern/openexr/Makefile
source/blender/imbuf/intern/openexr/SConscript
source/blender/imbuf/intern/openexr/openexr_api.cpp
source/blender/imbuf/intern/openexr/openexr_api.h
source/blender/include/BIF_toolbox.h
source/blender/makesdna/DNA_node_types.h
source/blender/render/intern/source/pipeline.c
source/blender/src/drawnode.c
source/blender/src/editnode.c
source/blender/src/interface.c
source/blender/src/toolbox.c

index cbae7034d1addfbd2afb524b87683ced257d6c0e..9bb01431a6843428b5bbd00960d7c9db05b57753 100644 (file)
@@ -78,13 +78,16 @@ typedef struct bNodeType {
 
 } bNodeType;
 
-/* nodetype->nclass, also for themes */
+/* nodetype->nclass, for add-menu and themes */
 #define NODE_CLASS_INPUT               0
 #define NODE_CLASS_OUTPUT              1
 #define NODE_CLASS_GENERATOR   2
-#define NODE_CLASS_OPERATOR            3
-#define NODE_CLASS_GROUP               4
-#define NODE_CLASS_FILE                        5
+#define NODE_CLASS_OP_COLOR            3
+#define NODE_CLASS_OP_VECTOR   4
+#define NODE_CLASS_OP_FILTER   5
+#define NODE_CLASS_GROUP               6
+#define NODE_CLASS_FILE                        7
+#define NODE_CLASS_CONVERTOR   8
 
 /* ************** GENERIC API, TREES *************** */
 
@@ -142,7 +145,8 @@ void                        nodeGroupSocketUseFlags(struct bNodeTree *ngroup);
 
 /* ************** COMMON NODES *************** */
 
-#define NODE_GROUP             2
+#define NODE_GROUP                     2
+#define NODE_GROUP_MENU                1000
 
 extern bNodeType node_group_typeinfo;
 
@@ -153,6 +157,9 @@ struct ShadeInput;
 struct ShadeResult;
 
 /* note: types are needed to restore callbacks, don't change values */
+/* range 1 - 100 is reserved for common nodes */
+/* using toolbox, we add node groups by assuming the values below don't exceed NODE_GROUP_MENU for now */
+
 #define SH_NODE_OUTPUT         1
 
 #define SH_NODE_MATERIAL       100
@@ -206,6 +213,7 @@ void                        set_node_shader_lamp_loop(void (*lamp_loop_func)(struct ShadeInput *, str
 #define CMP_NODE_SEPRGBA       216
 #define CMP_NODE_SEPHSVA       217
 #define CMP_NODE_SETALPHA      218
+#define CMP_NODE_HUE_SAT       219
 
 #define CMP_NODE_IMAGE                 220
 #define CMP_NODE_R_RESULT              221
index a76294a78e3fb615baedb200c52128e5bb50cd29..4125762495d0437f5499c67530fe3a5b7d3b283b 100644 (file)
@@ -790,6 +790,11 @@ bNode *nodeAddNodeType(bNodeTree *ntree, int type, bNodeTree *ngroup)
                        nbd->samples= 32;
                        nbd->fac= 1.0f;
                }
+               else if(type==CMP_NODE_HUE_SAT) {
+                       NodeHueSat *nhs= MEM_callocN(sizeof(NodeHueSat), "node hue sat");
+                       node->storage= nhs;
+                       nhs->sat= 1.0f;
+               }
        }
        
        return node;
index b04c540adcda49c17030137413595aa9f6ff7d8d..b1787e8b1a149f0f5bd2a6c4aa78338d21c2e892 100644 (file)
@@ -914,7 +914,7 @@ static bNodeType cmp_node_image= {
        /* type code   */       CMP_NODE_IMAGE,
        /* name        */       "Image",
        /* width+range */       120, 80, 300,
-       /* class+opts  */       NODE_CLASS_GENERATOR, NODE_PREVIEW|NODE_OPTIONS,
+       /* class+opts  */       NODE_CLASS_INPUT, NODE_PREVIEW|NODE_OPTIONS,
        /* input sock  */       NULL,
        /* output sock */       cmp_node_image_out,
        /* storage     */       "NodeImageAnim",
@@ -1036,7 +1036,7 @@ static bNodeType cmp_node_rresult= {
        /* type code   */       CMP_NODE_R_RESULT,
        /* name        */       "Render Result",
        /* width+range */       120, 80, 300,
-       /* class+opts  */       NODE_CLASS_GENERATOR, NODE_PREVIEW|NODE_OPTIONS,
+       /* class+opts  */       NODE_CLASS_INPUT, NODE_PREVIEW|NODE_OPTIONS,
        /* input sock  */       NULL,
        /* output sock */       cmp_node_rresult_out,
        /* storage     */       "",
@@ -1095,7 +1095,7 @@ static bNodeType cmp_node_normal= {
        /* type code   */       CMP_NODE_NORMAL,
        /* name        */       "Normal",
        /* width+range */       100, 60, 200,
-       /* class+opts  */       NODE_CLASS_OPERATOR, NODE_OPTIONS,
+       /* class+opts  */       NODE_CLASS_OP_VECTOR, NODE_OPTIONS,
        /* input sock  */       cmp_node_normal_in,
        /* output sock */       cmp_node_normal_out,
        /* storage     */       "",
@@ -1156,7 +1156,7 @@ static bNodeType cmp_node_curve_vec= {
        /* type code   */       CMP_NODE_CURVE_VEC,
        /* name        */       "Vector Curves",
        /* width+range */       200, 140, 320,
-       /* class+opts  */       NODE_CLASS_OPERATOR, NODE_OPTIONS,
+       /* class+opts  */       NODE_CLASS_OP_VECTOR, NODE_OPTIONS,
        /* input sock  */       cmp_node_curve_vec_in,
        /* output sock */       cmp_node_curve_vec_out,
        /* storage     */       "CurveMapping",
@@ -1231,7 +1231,7 @@ static bNodeType cmp_node_curve_rgb= {
        /* type code   */       CMP_NODE_CURVE_RGB,
        /* name        */       "RGB Curves",
        /* width+range */       200, 140, 320,
-       /* class+opts  */       NODE_CLASS_OPERATOR, NODE_OPTIONS,
+       /* class+opts  */       NODE_CLASS_OP_COLOR, NODE_OPTIONS,
        /* input sock  */       cmp_node_curve_rgb_in,
        /* output sock */       cmp_node_curve_rgb_out,
        /* storage     */       "CurveMapping",
@@ -1289,6 +1289,71 @@ static bNodeType cmp_node_rgb= {
        
 };
 
+/* **************** Hue Saturation ******************** */
+static bNodeSocketType cmp_node_hue_sat_in[]= {
+       {       SOCK_RGBA, 1, "Image",                  0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f},
+       {       -1, 0, ""       }
+};
+static bNodeSocketType cmp_node_hue_sat_out[]= {
+       {       SOCK_RGBA, 0, "Image",                  0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
+       {       -1, 0, ""       }
+};
+
+static void do_hue_sat(bNode *node, float *out, float *in)
+{
+       NodeHueSat *nhs= node->storage;
+       
+       if(nhs->hue!=0.0f || nhs->sat!=1.0) {
+               float hsv[3];
+               
+               rgb_to_hsv(in[0], in[1], in[2], hsv, hsv+1, hsv+2);
+               hsv[0]+= nhs->hue;
+               if(hsv[0]>1.0) hsv[0]-=1.0; else if(hsv[0]<0.0) hsv[0]+= 1.0;
+               hsv[1]*= nhs->sat;
+               if(hsv[1]>1.0) hsv[1]= 1.0; else if(hsv[1]<0.0) hsv[1]= 0.0;
+               hsv_to_rgb(hsv[0], hsv[1], hsv[2], out, out+1, out+2);
+               
+               out[3]= in[3];
+       }
+       else {
+               QUATCOPY(out, in);
+       }
+}
+
+static void node_composit_exec_hue_sat(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
+{
+       /* stack order in: Image */
+       /* stack order out: Image */
+       
+       /* input no image? then only color operation */
+       if(in[0]->data==NULL) {
+               do_hue_sat(node, out[0]->vec, in[0]->vec);
+       }
+       else {
+               /* make output size of input image */
+               CompBuf *cbuf= in[0]->data;
+               if(cbuf->type==CB_RGBA) {
+                       CompBuf *stackbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_RGBA, 1); // allocs
+                       
+                       composit1_pixel_processor(node, stackbuf, cbuf, NULL, do_hue_sat);
+                       
+                       out[0]->data= stackbuf;
+               }
+       }
+}
+
+static bNodeType cmp_node_hue_sat= {
+       /* type code   */       CMP_NODE_HUE_SAT,
+       /* name        */       "Hue Saturation",
+       /* width+range */       150, 80, 250,
+       /* class+opts  */       NODE_CLASS_OP_COLOR, NODE_OPTIONS,
+       /* input sock  */       cmp_node_hue_sat_in,
+       /* output sock */       cmp_node_hue_sat_out,
+       /* storage     */       "NodeHueSat", 
+       /* execfunc    */       node_composit_exec_hue_sat
+       
+};
+
 /* **************** MIX RGB ******************** */
 static bNodeSocketType cmp_node_mix_rgb_in[]= {
        {       SOCK_VALUE, 1, "Fac",                   0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
@@ -1339,7 +1404,7 @@ static bNodeType cmp_node_mix_rgb= {
        /* type code   */       CMP_NODE_MIX_RGB,
        /* name        */       "Mix",
        /* width+range */       80, 40, 120,
-       /* class+opts  */       NODE_CLASS_OPERATOR, NODE_OPTIONS,
+       /* class+opts  */       NODE_CLASS_OP_COLOR, NODE_OPTIONS,
        /* input sock  */       cmp_node_mix_rgb_in,
        /* output sock */       cmp_node_mix_rgb_out,
        /* storage     */       "", 
@@ -1470,7 +1535,7 @@ static bNodeType cmp_node_filter= {
        /* type code   */       CMP_NODE_FILTER,
        /* name        */       "Filter",
        /* width+range */       80, 40, 120,
-       /* class+opts  */       NODE_CLASS_OPERATOR, NODE_OPTIONS,
+       /* class+opts  */       NODE_CLASS_OP_FILTER, NODE_OPTIONS,
        /* input sock  */       cmp_node_filter_in,
        /* output sock */       cmp_node_filter_out,
        /* storage     */       "", 
@@ -1525,7 +1590,7 @@ static bNodeType cmp_node_valtorgb= {
        /* type code   */       CMP_NODE_VALTORGB,
        /* name        */       "ColorRamp",
        /* width+range */       240, 200, 300,
-       /* class+opts  */       NODE_CLASS_OPERATOR, NODE_OPTIONS,
+       /* class+opts  */       NODE_CLASS_CONVERTOR, NODE_OPTIONS,
        /* input sock  */       cmp_node_valtorgb_in,
        /* output sock */       cmp_node_valtorgb_out,
        /* storage     */       "ColorBand",
@@ -1573,7 +1638,7 @@ static bNodeType cmp_node_rgbtobw= {
        /* type code   */       CMP_NODE_RGBTOBW,
        /* name        */       "RGB to BW",
        /* width+range */       80, 40, 120,
-       /* class+opts  */       NODE_CLASS_OPERATOR, 0,
+       /* class+opts  */       NODE_CLASS_CONVERTOR, 0,
        /* input sock  */       cmp_node_rgbtobw_in,
        /* output sock */       cmp_node_rgbtobw_out,
        /* storage     */       "",
@@ -1626,7 +1691,7 @@ static bNodeType cmp_node_seprgba= {
        /* type code   */       CMP_NODE_SEPRGBA,
        /* name        */       "Separate RGBA",
        /* width+range */       80, 40, 140,
-       /* class+opts  */       NODE_CLASS_OPERATOR, 0,
+       /* class+opts  */       NODE_CLASS_CONVERTOR, 0,
        /* input sock  */       cmp_node_seprgba_in,
        /* output sock */       cmp_node_seprgba_out,
        /* storage     */       "",
@@ -1702,7 +1767,7 @@ static bNodeType cmp_node_sephsva= {
        /* type code   */       CMP_NODE_SEPHSVA,
        /* name        */       "Separate HSVA",
        /* width+range */       80, 40, 140,
-       /* class+opts  */       NODE_CLASS_OPERATOR, 0,
+       /* class+opts  */       NODE_CLASS_CONVERTOR, 0,
        /* input sock  */       cmp_node_sephsva_in,
        /* output sock */       cmp_node_sephsva_out,
        /* storage     */       "",
@@ -1755,7 +1820,7 @@ static bNodeType cmp_node_setalpha= {
        /* type code   */       CMP_NODE_SETALPHA,
        /* name        */       "Set Alpha",
        /* width+range */       120, 40, 140,
-       /* class+opts  */       NODE_CLASS_OPERATOR, NODE_OPTIONS,
+       /* class+opts  */       NODE_CLASS_CONVERTOR, NODE_OPTIONS,
        /* input sock  */       cmp_node_setalpha_in,
        /* output sock */       cmp_node_setalpha_out,
        /* storage     */       "",
@@ -1861,7 +1926,7 @@ static bNodeType cmp_node_alphaover= {
        /* type code   */       CMP_NODE_ALPHAOVER,
        /* name        */       "AlphaOver",
        /* width+range */       80, 40, 120,
-       /* class+opts  */       NODE_CLASS_OPERATOR, NODE_OPTIONS,
+       /* class+opts  */       NODE_CLASS_OP_COLOR, NODE_OPTIONS,
        /* input sock  */       cmp_node_alphaover_in,
        /* output sock */       cmp_node_alphaover_out,
        /* storage     */       "",
@@ -1916,7 +1981,7 @@ static bNodeType cmp_node_map_value= {
        /* type code   */       CMP_NODE_MAP_VALUE,
        /* name        */       "Map Value",
        /* width+range */       100, 60, 150,
-       /* class+opts  */       NODE_CLASS_OPERATOR, NODE_OPTIONS,
+       /* class+opts  */       NODE_CLASS_OP_VECTOR, NODE_OPTIONS,
        /* input sock  */       cmp_node_map_value_in,
        /* output sock */       cmp_node_map_value_out,
        /* storage     */       "TexMapping",
@@ -2499,7 +2564,7 @@ static bNodeType cmp_node_blur= {
        /* type code   */       CMP_NODE_BLUR,
        /* name        */       "Blur",
        /* width+range */       120, 80, 200,
-       /* class+opts  */       NODE_CLASS_OPERATOR, NODE_OPTIONS,
+       /* class+opts  */       NODE_CLASS_OP_FILTER, NODE_OPTIONS,
        /* input sock  */       cmp_node_blur_in,
        /* output sock */       cmp_node_blur_out,
        /* storage     */       "NodeBlurData",
@@ -2558,7 +2623,7 @@ static bNodeType cmp_node_vecblur= {
        /* type code   */       CMP_NODE_VECBLUR,
        /* name        */       "Vector Blur",
        /* width+range */       120, 80, 200,
-       /* class+opts  */       NODE_CLASS_OPERATOR, NODE_OPTIONS,
+       /* class+opts  */       NODE_CLASS_OP_FILTER, NODE_OPTIONS,
        /* input sock  */       cmp_node_vecblur_in,
        /* output sock */       cmp_node_vecblur_out,
        /* storage     */       "NodeBlurData",
@@ -2571,25 +2636,26 @@ static bNodeType cmp_node_vecblur= {
 
 bNodeType *node_all_composit[]= {
        &node_group_typeinfo,
-       &cmp_node_viewer,
        &cmp_node_composite,
+       &cmp_node_viewer,
        &cmp_node_output_file,
+       &cmp_node_rresult,
+       &cmp_node_image,
+       &cmp_node_curve_rgb,
+       &cmp_node_mix_rgb,
+       &cmp_node_hue_sat,
+       &cmp_node_alphaover,
        &cmp_node_value,
        &cmp_node_rgb,
-       &cmp_node_mix_rgb,
-       &cmp_node_filter,
-       &cmp_node_valtorgb,
-       &cmp_node_rgbtobw,
        &cmp_node_normal,
        &cmp_node_curve_vec,
-       &cmp_node_curve_rgb,
        &cmp_node_time,
-       &cmp_node_image,
-       &cmp_node_rresult,
-       &cmp_node_alphaover,
+       &cmp_node_filter,
        &cmp_node_blur,
        &cmp_node_vecblur,
        &cmp_node_map_value,
+       &cmp_node_valtorgb,
+       &cmp_node_rgbtobw,
        &cmp_node_seprgba,
        &cmp_node_sephsva,
        &cmp_node_setalpha,
index 5e8204d3f00fa567da6696d1f1728bf120f6ef14..f1f39100574edc7851db614b8db559209b71b597 100644 (file)
@@ -297,7 +297,7 @@ static bNodeType sh_node_material= {
        /* type code   */       SH_NODE_MATERIAL,
        /* name        */       "Material",
        /* width+range */       120, 80, 240,
-       /* class+opts  */       NODE_CLASS_GENERATOR, NODE_OPTIONS|NODE_PREVIEW,
+       /* class+opts  */       NODE_CLASS_INPUT, NODE_OPTIONS|NODE_PREVIEW,
        /* input sock  */       sh_node_material_in,
        /* output sock */       sh_node_material_out,
        /* storage     */       "",
@@ -390,7 +390,7 @@ static bNodeType sh_node_texture= {
        /* type code   */       SH_NODE_TEXTURE,
        /* name        */       "Texture",
        /* width+range */       120, 80, 240,
-       /* class+opts  */       NODE_CLASS_GENERATOR, NODE_OPTIONS|NODE_PREVIEW,
+       /* class+opts  */       NODE_CLASS_INPUT, NODE_OPTIONS|NODE_PREVIEW,
        /* input sock  */       sh_node_texture_in,
        /* output sock */       sh_node_texture_out,
        /* storage     */       "",
@@ -436,7 +436,7 @@ static bNodeType sh_node_mapping= {
        /* type code   */       SH_NODE_MAPPING,
        /* name        */       "Mapping",
        /* width+range */       240, 160, 320,
-       /* class+opts  */       NODE_CLASS_OPERATOR, NODE_OPTIONS,
+       /* class+opts  */       NODE_CLASS_OP_VECTOR, NODE_OPTIONS,
        /* input sock  */       sh_node_mapping_in,
        /* output sock */       sh_node_mapping_out,
        /* storage     */       "TexMapping",
@@ -472,7 +472,7 @@ static bNodeType sh_node_normal= {
        /* type code   */       SH_NODE_NORMAL,
        /* name        */       "Normal",
        /* width+range */       100, 60, 200,
-       /* class+opts  */       NODE_CLASS_OPERATOR, NODE_OPTIONS,
+       /* class+opts  */       NODE_CLASS_OP_VECTOR, NODE_OPTIONS,
        /* input sock  */       sh_node_normal_in,
        /* output sock */       sh_node_normal_out,
        /* storage     */       "",
@@ -503,7 +503,7 @@ static bNodeType sh_node_curve_vec= {
        /* type code   */       SH_NODE_CURVE_VEC,
        /* name        */       "Vector Curves",
        /* width+range */       200, 140, 320,
-       /* class+opts  */       NODE_CLASS_OPERATOR, NODE_OPTIONS,
+       /* class+opts  */       NODE_CLASS_OP_VECTOR, NODE_OPTIONS,
        /* input sock  */       sh_node_curve_vec_in,
        /* output sock */       sh_node_curve_vec_out,
        /* storage     */       "CurveMapping",
@@ -534,7 +534,7 @@ static bNodeType sh_node_curve_rgb= {
        /* type code   */       SH_NODE_CURVE_RGB,
        /* name        */       "RGB Curves",
        /* width+range */       200, 140, 320,
-       /* class+opts  */       NODE_CLASS_OPERATOR, NODE_OPTIONS,
+       /* class+opts  */       NODE_CLASS_OP_COLOR, NODE_OPTIONS,
        /* input sock  */       sh_node_curve_rgb_in,
        /* output sock */       sh_node_curve_rgb_out,
        /* storage     */       "CurveMapping",
@@ -622,7 +622,7 @@ static bNodeType sh_node_mix_rgb= {
        /* type code   */       SH_NODE_MIX_RGB,
        /* name        */       "Mix",
        /* width+range */       80, 40, 120,
-       /* class+opts  */       NODE_CLASS_OPERATOR, NODE_OPTIONS,
+       /* class+opts  */       NODE_CLASS_OP_COLOR, NODE_OPTIONS,
        /* input sock  */       sh_node_mix_rgb_in,
        /* output sock */       sh_node_mix_rgb_out,
        /* storage     */       "", 
@@ -657,7 +657,7 @@ static bNodeType sh_node_valtorgb= {
        /* type code   */       SH_NODE_VALTORGB,
        /* name        */       "ColorRamp",
        /* width+range */       240, 200, 300,
-       /* class+opts  */       NODE_CLASS_OPERATOR, NODE_OPTIONS,
+       /* class+opts  */       NODE_CLASS_CONVERTOR, NODE_OPTIONS,
        /* input sock  */       sh_node_valtorgb_in,
        /* output sock */       sh_node_valtorgb_out,
        /* storage     */       "ColorBand",
@@ -689,7 +689,7 @@ static bNodeType sh_node_rgbtobw= {
        /* type code   */       SH_NODE_RGBTOBW,
        /* name        */       "RGB to BW",
        /* width+range */       80, 40, 120,
-       /* class+opts  */       NODE_CLASS_OPERATOR, 0,
+       /* class+opts  */       NODE_CLASS_CONVERTOR, 0,
        /* input sock  */       sh_node_rgbtobw_in,
        /* output sock */       sh_node_rgbtobw_out,
        /* storage     */       "",
index 48abc4c4331b3001bf5220a807b22194c1baeab2..65b9a058e014021663486e0fa444a9cb98959be0 100644 (file)
@@ -47,5 +47,6 @@ CPPFLAGS += -I../../../blenkernel
 CPPFLAGS += -I../../../blenlib
 CPPFLAGS += -I../../../imbuf
 CPPFLAGS += -I../../../imbuf/intern
+CPPFLAGS += -I$(NAN_GUARDEDALLOC)/include
 CPPFLAGS += $(NAN_OPENEXR_INC)
 CPPFLAGS += -I.
index a710e26ad5d579cda4980bd74c2ca9ea55b0f31a..133a965138068053b295692bf189caa21d593d17 100644 (file)
@@ -8,6 +8,7 @@ incs = ['.',
        '../../',
        '..',
        '../../../blenlib',
+       'intern/include #/intern/guardedalloc',
        '../../../makesdna']
 incs += Split(env['BF_OPENEXR_INC'])
 
index 5cf8005cb992dfb5f5532a5186f33893f793d40f..13ac8b14edfcccba72de7d3d51a746c9d7e7aa06 100644 (file)
 
 extern "C"
 {
+#include "MEM_guardedalloc.h"
+
+#include "BLI_blenlib.h"
+
 #include "IMB_imbuf_types.h"
 #include "IMB_imbuf.h"
-       
 #include "IMB_allocimbuf.h"
 }
 
@@ -54,6 +57,7 @@ extern "C"
 #include <IlmImf/ImfOutputFile.h>
 #include <IlmImf/ImfCompression.h>
 #include <IlmImf/ImfCompressionAttribute.h>
+#include <IlmImf/ImfStringAttribute.h>
 #include <Imath/ImathBox.h>
 #else
 #include <OpenEXR/half.h>
@@ -67,6 +71,7 @@ extern "C"
 #include <OpenEXR/ImfOutputFile.h>
 #include <OpenEXR/ImfCompression.h>
 #include <OpenEXR/ImfCompressionAttribute.h>
+#include <OpenEXR/ImfStringAttribute.h>
 #endif
 
 using namespace Imf;
@@ -326,6 +331,111 @@ short imb_save_openexr(struct ImBuf *ibuf, char *name, int flags)
        }
 }
 
+/* ********************* Tile file support ************************************ */
+
+typedef struct ExrTileHandle {
+       TiledOutputFile *file;
+       int tilex, tiley;
+       int width, height;
+       ListBase channels;
+} ExrTileHandle;
+
+typedef struct ExrTileChannel {
+       struct ExrTileChannel *next, *prev;
+       char *name;
+       int xstride, ystride;
+       float *rect;
+} ExrTileChannel;
+
+/* not threaded! write one tiled file at a time */
+void *imb_exrtile_get_handle(void)
+{
+       static ExrTileHandle data;
+       
+       data.channels.first= data.channels.last= NULL;
+       return &data;
+}
+
+void imb_exrtile_add_channel(void *handle, char *channame)
+{
+       ExrTileHandle *data= (ExrTileHandle *)handle;
+       ExrTileChannel *echan;
+       
+       echan= (ExrTileChannel *)MEM_callocN(sizeof(ExrTileChannel), "exr tile channel");
+       echan->name= channame;
+       BLI_addtail(&data->channels, echan);
+}
+
+void imb_exrtile_begin_write(void *handle, char *filename, int width, int height, int tilex, int tiley)
+{
+       ExrTileHandle *data= (ExrTileHandle *)handle;
+       Header header (width, height);
+       ExrTileChannel *echan;
+       
+       data->tilex= tilex;
+       data->tiley= tiley;
+       data->width= width;
+       data->height= height;
+       
+       for(echan= (ExrTileChannel *)data->channels.first; echan; echan= echan->next)
+               header.channels().insert (echan->name, Channel (FLOAT));
+       
+       header.setTileDescription (TileDescription (tilex, tiley, ONE_LEVEL));
+       
+       header.insert ("comments", StringAttribute ("Blender RenderResult"));
+       
+       data->file = new TiledOutputFile(filename, header);
+}
+
+
+void imb_exrtile_set_channel(void *handle, char *channame, int xstride, int ystride, float *rect)
+{
+       ExrTileHandle *data= (ExrTileHandle *)handle;
+       ExrTileChannel *echan;
+       
+       for(echan= (ExrTileChannel *)data->channels.first; echan; echan= echan->next)
+               if(strcmp(echan->name, channame)==0)
+                       break;
+       if(echan) {
+               echan->xstride= xstride;
+               echan->ystride= ystride;
+               echan->rect= rect;
+       }
+       else
+               printf("imb_exrtile_set_channel error\n");
+}
+
+
+void imb_exrtile_write_channels(void *handle, int partx, int party)
+{
+       ExrTileHandle *data= (ExrTileHandle *)handle;
+       FrameBuffer frameBuffer;
+       ExrTileChannel *echan;
+       
+       for(echan= (ExrTileChannel *)data->channels.first; echan; echan= echan->next) {
+               float *rect= echan->rect - echan->xstride*partx - echan->ystride*party;
+
+               frameBuffer.insert (echan->name, Slice (FLOAT,  (char *)rect, 
+                                                       echan->xstride*sizeof(float), echan->ystride*sizeof(float)));
+       }
+       
+       data->file->setFrameBuffer (frameBuffer);
+       printf("write tile %d %d\n", partx/data->tilex, party/data->tiley);
+       data->file->writeTile (partx/data->tilex, party/data->tiley);   
+       
+}
+
+void imb_exrtile_close(void *handle)
+{
+       ExrTileHandle *data= (ExrTileHandle *)handle;
+       
+       delete data->file;
+       
+       BLI_freelistN(&data->channels);
+}
+
+
+/* ********************************************************* */
 
 typedef struct RGBA
 {
@@ -360,6 +470,16 @@ static int exr_has_zbuffer(InputFile *file)
        return 0;
 }
 
+static int exr_is_renderresult(InputFile *file)
+{
+       const StringAttribute *comments= file->header().findTypedAttribute<StringAttribute>("comments");
+       if(comments) {
+       
+               if(comments->value() == "Blender RenderResult")
+                       return 1;
+       }
+       return 0;
+}
 
 struct ImBuf *imb_load_openexr(unsigned char *mem, int size, int flags)
 {
@@ -381,6 +501,7 @@ struct ImBuf *imb_load_openexr(unsigned char *mem, int size, int flags)
                //         dw.min.x, dw.min.y, dw.max.x, dw.max.y);
 
                //exr_print_filecontents(file);
+               int flipped= exr_is_renderresult(file);
                
                ibuf = IMB_allocImBuf(width, height, 32, 0, 0);
                
@@ -393,14 +514,14 @@ struct ImBuf *imb_load_openexr(unsigned char *mem, int size, int flags)
                                FrameBuffer frameBuffer;
                                float *first;
                                int xstride = sizeof(float) * 4;
-                               int ystride = - xstride*width;
+                               int ystride = flipped ? xstride*width : - xstride*width;
                                
                                imb_addrectfloatImBuf(ibuf);
                                
                                /* inverse correct first pixel for datawindow coordinates (- dw.min.y because of y flip) */
                                first= ibuf->rect_float - 4*(dw.min.x - dw.min.y*width);
                                /* but, since we read y-flipped (negative y stride) we move to last scanline */
-                               first+= 4*(height-1)*width;
+                               if(!flipped) first+= 4*(height-1)*width;
                                
                                frameBuffer.insert ("R", Slice (FLOAT,  (char *) first, xstride, ystride));
                                frameBuffer.insert ("G", Slice (FLOAT,  (char *) (first+1), xstride, ystride));
@@ -413,7 +534,7 @@ struct ImBuf *imb_load_openexr(unsigned char *mem, int size, int flags)
                                        
                                        addzbuffloatImBuf(ibuf);
                                        firstz= ibuf->zbuf_float - (dw.min.x - dw.min.y*width);
-                                       firstz+= (height-1)*width;
+                                       if(!flipped) firstz+= (height-1)*width;
                                        frameBuffer.insert ("Z", Slice (FLOAT,  (char *)firstz , sizeof(float), -width*sizeof(float)));
                                }
                                
index c12eb1f05ae8b70296265274506514f109c5dc8f..a82713b65955dda434f7d1980e254922732fc5ce 100644 (file)
@@ -47,11 +47,20 @@ extern "C" {
  * @param mem pointer to loaded OpenEXR bitstream
  */
   
-int imb_is_a_openexr(unsigned char *mem);
+int            imb_is_a_openexr                        (unsigned char *mem);
        
-short imb_save_openexr(struct ImBuf *ibuf, char *name, int flags);
+short  imb_save_openexr                        (struct ImBuf *ibuf, char *name, int flags);
+
+struct ImBuf *imb_load_openexr         (unsigned char *mem, int size, int flags);
+
+
+void * imb_exrtile_get_handle          (void);
+void   imb_exrtile_add_channel         (void *handle, char *channame);
+void   imb_exrtile_begin_write         (void *handle, char *filename, int width, int height, int tilex, int tiley);
+void   imb_exrtile_set_channel         (void *handle, char *channame, int xstride, int ystride, float *rect);
+void   imb_exrtile_write_channels      (void *handle, int partx, int party);
+void   imb_exrtile_close                       (void *handle);
 
-struct ImBuf *imb_load_openexr(unsigned char *mem, int size, int flags);
 
 #ifdef __cplusplus
 }
index 9e9365f3bc34416e6d7649d8c226563afdaddabb..eef78e482cc0b7ea897fa32eab78005699237e0d 100644 (file)
 #ifndef BIF_TOOLBOX_H
 #define BIF_TOOLBOX_H
 
-
-       /* TBOXX: width in pixels */
-#define TBOXXL  80
-#define TBOXXR  200
-#define TBOXX  (TBOXXL+TBOXXR)
-       /* TBOXEL: amount of element vertically */
-#define TBOXEL 14
-       /* TBOXH: height of 1 element */
-#define TBOXH  20
-#define TBOXY  TBOXH*TBOXEL
-
-#define TBOXBLACK      1
-#define TBOXDGREY      2
-#define TBOXWHITE      3
-#define TBOXGREY       4
-#define TBOXLGREY      5
-
-/* toolbox menu code defines
-   -> SPACE->(MAIN_ENTRY) */
-#ifdef MAART
-enum {
-       TBOX_MAIN_FILE,
-       TBOX_MAIN_ADD,
-       TBOX_MAIN_EDIT,
-       TBOX_MAIN_OBJECT1,
-       TBOX_MAIN_OBJECT2,
-       TBOX_MAIN_MESH,
-       TBOX_MAIN_CURVE,
-       TBOX_MAIN_KEY,
-       TBOX_MAIN_RENDER,
-       TBOX_MAIN_VIEW,
-        TBOX_MAIN_SEQ,
-       TBOX_MAIN_PYTOOL = 13
-};
-
-#else
-enum {
-       TBOX_MAIN_ADD,
-       TBOX_MAIN_FILE,
-       TBOX_MAIN_EDIT,
-       TBOX_MAIN_OBJECT1,
-       TBOX_MAIN_OBJECT2,
-       TBOX_MAIN_MESH,
-       TBOX_MAIN_CURVE,
-       TBOX_MAIN_KEY,
-       TBOX_MAIN_RENDER,
-       TBOX_MAIN_VIEW,
-        TBOX_MAIN_SEQ,
-       TBOX_MAIN_PYTOOL = 13
-};
-#endif
-
-/* protos */
-
 /* toolbox.c */
-void ColorFunc (int i);
-void mygetcursor (short int *index);
-void tbox_setinfo (int x, int y);
-void bgnpupdraw (int startx, int starty, int endx, int endy);
-void endpupdraw (void);
 void asciitoraw (int ch, short unsigned int *event, short unsigned int *qual);
-void tbox_execute (void);
-void tbox_getmouse (short int *mval);
-void tbox_setmain (int val);
-void bgntoolbox (void);
-void endtoolbox (void);
-void tbox_embossbox (short int x1, short int y1, short int x2, short int y2, short int type);
-void tbox_drawelem_body (int x, int y, int type);
-void tbox_drawelem_text (int x, int y, int type);
-void tbox_drawelem (int x, int y, int type);
-void tbox_getactive (int *x, int *y);
-void drawtoolbox (void);
-void toolbox (void);
 
 void toolbox_n(void);
 void toolbox_n_add(void);
index 9ad1ed323576c43e164b67125b77ba3cdda34e9a..afc0728a26d697986ac0fdd81efbe5f246dde04c 100644 (file)
@@ -194,5 +194,9 @@ typedef struct NodeBlurData {
        int pad2;
 } NodeBlurData;
 
+typedef struct NodeHueSat {
+       float hue, sat;
+} NodeHueSat;
+
 #endif
 
index c326f8627d9551c5645e1756d74059752a4370d4..c14ee2ece8ed78fca44598b470960737f4eeca6d 100644 (file)
@@ -51,6 +51,7 @@
 #include "PIL_time.h"
 #include "IMB_imbuf.h"
 #include "IMB_imbuf_types.h"
+#include "intern/openexr/openexr_api.h"
 
 #include "RE_pipeline.h"
 #include "radio.h"
@@ -104,6 +105,7 @@ static struct ListBase RenderList= {NULL, NULL};
 /* hardcopy of current render, used while rendering for speed */
 Render R;
 
+void *exrhandle= NULL;
 /* ********* alloc and free ******** */
 
 
@@ -365,6 +367,37 @@ static void merge_render_result(RenderResult *rr, RenderResult *rrpart)
 }
 
 
+static void save_render_result_tile(Render *re, RenderPart *pa)
+{
+       RenderResult *rrpart= pa->result;
+       RenderLayer *rlp;
+       int offs, partx, party;
+       
+       for(rlp= rrpart->layers.first; rlp; rlp= rlp->next) {
+               
+               if(rrpart->crop) {      /* filters add pixel extra */
+                       offs= (rrpart->crop + rrpart->crop*rrpart->rectx);
+               }
+               else {
+                       offs= 0;
+               }
+               party= rrpart->tilerect.ymin + rrpart->crop;
+               partx= rrpart->tilerect.xmin + rrpart->crop;
+               
+               /* combined */
+               if(rlp->rectf) {
+                       int xstride= 4;
+                       imb_exrtile_set_channel(exrhandle, "R", xstride, xstride*pa->rectx, rlp->rectf   + xstride*offs);
+                       imb_exrtile_set_channel(exrhandle, "G", xstride, xstride*pa->rectx, rlp->rectf+1 + xstride*offs);
+                       imb_exrtile_set_channel(exrhandle, "B", xstride, xstride*pa->rectx, rlp->rectf+2 + xstride*offs);
+                       imb_exrtile_set_channel(exrhandle, "A", xstride, xstride*pa->rectx, rlp->rectf+3 + xstride*offs);
+                       
+                       imb_exrtile_write_channels(exrhandle, partx, party);
+               }               
+       }
+}
+
+
 /* *************************************************** */
 
 Render *RE_GetRender(const char *name)
@@ -709,6 +742,7 @@ static void render_tile_processor(Render *re, int firsttile)
                        if(pa->result) {
                                if(!re->test_break()) {
                                        re->display_draw(pa->result, NULL);
+                                       
                                        re->i.partsdone++;
                                }
                                free_render_result(pa->result);
@@ -817,6 +851,9 @@ static void threaded_tile_processor(Render *re)
                                        BLI_remove_thread(&threads, pa);
                                        re->display_draw(pa->result, NULL);
                                        print_part_stats(re, pa);
+                                       
+                                       if(exrhandle) save_render_result_tile(re, pa);
+                                       
                                        free_render_result(pa->result);
                                        pa->result= NULL;
                                        re->i.partsdone++;
@@ -872,6 +909,7 @@ void render_one_frame(Render *re)
           RE_Database_FromScene(re, re->scene, 1);
        
        threaded_tile_processor(re);
+       //render_tile_processor(re, 0);
        
        /* free all render verts etc */
        RE_Database_Free(re);
@@ -1072,11 +1110,6 @@ static int is_rendering_allowed(Render *re)
                return 0;
        }
        
-       if(re->r.xparts*re->r.yparts>64) {
-               re->error("No more than 64 parts supported");
-               return 0;
-       }
-       
        if(re->r.yparts>1 && (re->r.mode & R_PANORAMA)) {
                re->error("No Y-Parts supported for Panorama");
                return 0;
@@ -1132,6 +1165,15 @@ static int render_initialize_from_scene(Render *re, Scene *scene)
        re->display_init(re->result);
        re->display_clear(re->result);
        
+       if(0) {
+               exrhandle= imb_exrtile_get_handle();
+               imb_exrtile_add_channel(exrhandle, "R");
+               imb_exrtile_add_channel(exrhandle, "G");
+               imb_exrtile_add_channel(exrhandle, "B");
+               imb_exrtile_add_channel(exrhandle, "A");
+               imb_exrtile_begin_write(exrhandle, "/tmp/render.exr", winx, winy, winx/scene->r.xparts, winy/scene->r.yparts);
+       }
+       
        return 1;
 }
 
@@ -1144,6 +1186,10 @@ void RE_BlenderFrame(Render *re, Scene *scene, int frame)
        
        if(render_initialize_from_scene(re, scene)) {
                do_render_final(re);
+               
+               if(exrhandle)
+                       imb_exrtile_close(exrhandle);
+               exrhandle= NULL;
        }
 }
 
index d554628377431e580e2aa4aedf86be3d270120c3..dd98a877bcb6035e9a231628268d00af997e6cfd 100644 (file)
@@ -573,6 +573,7 @@ static void node_browse_image_cb(void *ntree_v, void *node_v)
                BLI_strncpy(node->name, node->id->name+2, 21);
 
                NodeTagChanged(ntree, node); 
+               addqueue(curarea->win, UI_BUT_EVENT, B_NODE_EXEC+node->nr);
        }
        node->menunr= 0;
 }
@@ -891,12 +892,28 @@ static int node_composit_buts_alphaover(uiBlock *block, bNodeTree *ntree, bNode
                
                /* alpha type */
                uiDefButS(block, TOG, B_NODE_EXEC+node->nr, "ConvertPremul",
-                                        butr->xmin, butr->ymin, butr->xmax-butr->xmin, 19, 
-                                        &node->custom1, 0, 0, 0, 0, "");
+                                 butr->xmin, butr->ymin, butr->xmax-butr->xmin, 19, 
+                                 &node->custom1, 0, 0, 0, 0, "");
        }
        return 19;
 }
 
+static int node_composit_buts_hue_sat(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr)
+{
+       if(block) {
+               NodeHueSat *nhs= node->storage;
+               
+               uiBlockBeginAlign(block);
+               uiDefButF(block, NUMSLI, B_NODE_EXEC+node->nr, "Hue ",
+                                 butr->xmin, butr->ymin+19.0f, butr->xmax-butr->xmin, 19, 
+                                 &nhs->hue, 0.0f, 1.0f, 100, 0, "");
+               uiDefButF(block, NUMSLI, B_NODE_EXEC+node->nr, "Sat ",
+                                 butr->xmin, butr->ymin, butr->xmax-butr->xmin, 19, 
+                                 &nhs->sat, 0.0f, 1.0f, 100, 0, "");
+       }
+       return 38;
+}
+
 
 /* only once called */
 static void node_composit_set_butfunc(bNodeType *ntype)
@@ -950,6 +967,9 @@ static void node_composit_set_butfunc(bNodeType *ntype)
                case CMP_NODE_ALPHAOVER:
                        ntype->butfunc= node_composit_buts_alphaover;
                        break;
+               case CMP_NODE_HUE_SAT:
+                       ntype->butfunc= node_composit_buts_hue_sat;
+                       break;
                default:
                        ntype->butfunc= NULL;
        }
@@ -1339,7 +1359,7 @@ static int node_get_colorid(bNode *node)
        }
        if(node->typeinfo->nclass==NODE_CLASS_GENERATOR)
                return TH_NODE_GENERATOR;
-       if(node->typeinfo->nclass==NODE_CLASS_OPERATOR)
+       if(ELEM4(node->typeinfo->nclass, NODE_CLASS_OP_COLOR, NODE_CLASS_OP_VECTOR, NODE_CLASS_OP_FILTER, NODE_CLASS_CONVERTOR))
                return TH_NODE_OPERATOR;
        if(node->typeinfo->nclass==NODE_CLASS_GROUP)
                return TH_NODE_GROUP;
index 7d09404b9cfc9d1cd593fca0fac14b9c7d3e9127..af65a9209cc6d953456e65d8dfa823e3ed592aed 100644 (file)
@@ -1221,7 +1221,19 @@ bNode *node_add_node(SpaceNode *snode, int type, float locx, float locy)
        
        node_deselectall(snode, 0);
        
-       node= nodeAddNodeType(snode->edittree, type, NULL);
+       if(type>=NODE_GROUP_MENU) {
+               if(snode->edittree!=snode->nodetree) {
+                       error("Can not add a Group in a Group");
+                       return NULL;
+               }
+               else {
+                       bNodeTree *ngroup= BLI_findlink(&G.main->nodetree, type-NODE_GROUP_MENU);
+                       if(ngroup)
+                               node= nodeAddNodeType(snode->edittree, NODE_GROUP, ngroup);
+               }
+       }
+       else
+               node= nodeAddNodeType(snode->edittree, type, NULL);
        
        /* generics */
        if(node) {
@@ -1237,37 +1249,13 @@ bNode *node_add_node(SpaceNode *snode, int type, float locx, float locy)
 
                node_set_active(snode, node);
                snode_verify_groups(snode);
+               
+               if(node->id)
+                       id_us_plus(node->id);
        }
        return node;
 }
 
-/* hotkey context */
-static void node_add_menu(SpaceNode *snode)
-{
-       float locx, locy;
-       short event, mval[2];
-       
-       if(snode->treetype==NTREE_SHADER) {
-               /* shader menu, still hardcoded defines... solve */
-               event= pupmenu("Add Node%t|Output%x1|Geometry%x108|Material%x100|Texture%x106|Mapping%x109|Normal%x107|RGB Curves%x111|Vector Curves%x110|Value %x102|Color %x101|Mix Color %x103|ColorRamp %x104|Color to BW %x105");
-               if(event<1) return;
-       }
-       else if(snode->treetype==NTREE_COMPOSIT) {
-               /* compo menu, still hardcoded defines... solve */
-               event= pupmenu("Add Node%t|Render Result %x221|Composite %x222|Viewer%x201|Image %x220|RGB Curves%x209|AlphaOver %x210|Blur %x211|Vector Blur %x215|Filter %x212|Value %x203|Color %x202|Mix %x204|ColorRamp %x205|Color to BW %x206|Map Value %x213|Time %x214|Normal %x207||Separate RGBA %x216|Separate HSVA %x217|Set Alpha %x218");
-               if(event<1) return;
-       }
-       else return;
-       
-       getmouseco_areawin(mval);
-       areamouseco_to_ipoco(G.v2d, mval, &locx, &locy);
-       node_add_node(snode, event, locx, locy);
-       
-       snode_handle_recalc(snode);
-       
-       BIF_undo_push("Add Node");
-}
-
 void node_adduplicate(SpaceNode *snode)
 {
        
@@ -1772,7 +1760,7 @@ void winqreadnodespace(ScrArea *sa, void *spacedata, BWinEvent *evt)
                case AKEY:
                        if(G.qual==LR_SHIFTKEY) {
                                if(fromlib) fromlib= -1;
-                               else node_add_menu(snode);
+                               else toolbox_n_add();
                        }
                        else if(G.qual==0) {
                                node_deselectall(snode, 1);
index 748947c5644b2fa9978c14552f21fa5613aac326..89b5f1ae50b0d53ecf10099bedf81d55bed86b2e 100644 (file)
@@ -1123,7 +1123,7 @@ static void ui_warp_pointer(short x, short y)
        #endif
 }
 
-
+#define TBOXH 20
 static int ui_do_but_MENU(uiBut *but)
 {
        uiBlock *block;
index 992ee099c91d3fc6e8c57c6c9097e7b54ac751c7..183884eb19df8358d5237f40b20d716fafac75ce 100644 (file)
 #include "DNA_image_types.h"
 #include "DNA_lamp_types.h"
 #include "DNA_mesh_types.h"
+#include "DNA_node_types.h"
 #include "DNA_object_types.h"
 #include "DNA_screen_types.h"
+#include "DNA_space_types.h"
 #include "DNA_scene_types.h"
 #include "DNA_userdef_types.h"
 #include "DNA_view3d_types.h"
@@ -73,6 +75,7 @@
 #include "BKE_global.h"
 #include "BKE_library.h"
 #include "BKE_mesh.h"
+#include "BKE_node.h"
 #include "BKE_main.h"
 #include "BKE_plugin_types.h"
 #include "BKE_utildefines.h"
 #include "BDR_editcurve.h"
 #include "BDR_editmball.h"
 
+#include "BSE_drawipo.h"
+#include "BSE_edit.h"
 #include "BSE_editipo.h"
 #include "BSE_filesel.h"
-#include "BSE_edit.h"
 #include "BSE_headerbuttons.h"
+#include "BSE_node.h"
 
 #include "IMB_imbuf.h"
 
-#include "mydevice.h"
 #include "blendef.h"
-
-static int tbx1, tbx2, tby1, tby2, tbfontyofs, tbmain=0;
-static int tbmemx=TBOXX/2, tbmemy=(TBOXEL-0.5)*TBOXH, tboldwin, addmode= 0;
-static int oldcursor;
-
-       /* variables per item */
-static char *tbstr, *tbstr1, *keystr;  
-static void (*tbfunc)(int);
-static int tbval;
-
-/* prototypes ----------------------- */
-TBcallback *callback_dummy(int level, int entry);
-
-
-/* *********** PC PATCH ************* */
-
-void ColorFunc(int i)
-{
-       if(i==TBOXBLACK) glColor3ub(0, 0, 0);
-       else if(i==TBOXWHITE) glColor3ub(240, 240, 240);
-       else if(i==TBOXGREY) glColor3ub(160, 160, 160);
-       else glColor3ub(0, 0, 0);
-}
-
-/* ********************* PYTHON TOOLBOX CALLBACK ************************* */
-
-#ifdef PY_TOOLBOX 
-/* see bpython/intern/py_toolbox.c */
-
-/* moved to BIF_toolbox.h */
-/* typedef char** (*tbox_callback)(int, int); */
-
-TBcallback *callback_dummy(int level, int entry)
-{
-       return NULL;
-}      
-
-/* callback func ptr for py_toolbox */
-Tbox_callbackfunc g_toolbox_menucallback = &callback_dummy;
-
-void tboxSetCallback(Tbox_callbackfunc f)
-{
-       g_toolbox_menucallback = f;
-}
-
-#endif
-
-/* ********************* TOOLBOX ITEMS ************************* */
-
-void tbox_setinfo(int x, int y)
-{
-       /* dependant of tbmain vars are set */
-       tbstr= 0;
-       tbstr1= 0;
-       tbfunc= 0;
-       tbval= 0;
-       keystr = NULL;
-
-/* main menu entries: defined in BIF_toolbox.h */
-       
-       if(x==0) {
-               switch(y) {
-                       case TBOX_MAIN_FILE:            tbstr= "FILE";          break;
-                       case TBOX_MAIN_EDIT:            tbstr= "EDIT";          break;
-                       case TBOX_MAIN_ADD:             
-                               if (addmode==OB_MESH) tbstr= "  MESH";
-                               else if(addmode==OB_CURVE) tbstr= "  CURVE";
-                               else if(addmode==OB_SURF) tbstr= "  SURF";
-                               else if(addmode==OB_MBALL) tbstr= "  META";
-                               else tbstr= "ADD";
-                               break;
-                       case TBOX_MAIN_OBJECT1:         tbstr= "OBJECT";        break;
-                       case TBOX_MAIN_OBJECT2:         tbstr= "OBJECT";        break;
-                       case TBOX_MAIN_MESH:            tbstr= "MESH";          break;
-                       case TBOX_MAIN_CURVE:           tbstr= "CURVE";         break;
-                       case TBOX_MAIN_KEY:                     tbstr= "KEY";           break;
-                       case TBOX_MAIN_RENDER:          tbstr= "RENDER";        break;
-                       case TBOX_MAIN_VIEW:            tbstr= "VIEW";          break;
-                       case TBOX_MAIN_SEQ:             tbstr= "SEQUENCE";      break;
-#ifdef PY_TOOLBOX
-                       case TBOX_MAIN_PYTOOL:          
-                       {
-                               if (g_toolbox_menucallback(0, 0)) // valid callback?
-                                       tbstr= "PYTOOL";        
-                               break;
-                       }
-#endif
-               }
-       }
-       
-/* TOPICS */
-       else {
-               
-               
-/* FILE TOPICS */
-               if(tbmain==TBOX_MAIN_FILE) {
-                       switch(y) {
-                               case 0: tbstr= "New";                           tbstr1= "c|x";          keystr= "Ctrl X";       break;
-                               case 1: tbstr= "Open";                          tbstr1= "F1";           keystr= "F1";           break;
-                               case 2: tbstr= "Reopen Last";           tbstr1= "c|o";          keystr= "Ctrl O";       break;
-                               case 3: tbstr= "Append";                        tbstr1= "shift+F1";     keystr= "Shift F1";     break;
-                               case 4: tbstr= "";                                      tbstr1= "";                     keystr= "";                     break;
-                               case 5: tbstr= "Save As";                       tbstr1= "F2";           keystr= "F2";           break;
-                               case 6: tbstr= "Save";                          tbstr1= "c|w";          keystr= "Ctrl W";       break;
-                               case 7: tbstr= "";                                      tbstr1= "";                     keystr= "";                     break;
-                               case 8: tbstr= "Save Image";            tbstr1= "F3";           keystr= "F3";           break;
-                               case 9: tbstr= "Save VRML";                     tbstr1= "c|F2";         keystr= "Ctrl F2";      break;
-                               case 10: tbstr= "Save DXF";                     tbstr1= "shift+F2";     keystr= "Shift F2";     break;
-                               case 11: tbstr= "Save VideoScape";      tbstr1= "a|w";          keystr= "Alt W";        break;
-                               case 12: tbstr= "Save UserPrefs";       tbstr1= "c|u";          keystr= "Ctrl U";       break;
-                               case 13: tbstr= "Quit";                         tbstr1= "q";            keystr= "Q";            break;
-                       }
-               }
-
-/* EDIT TOPICS */
-               if(tbmain==TBOX_MAIN_EDIT) {
-                       switch(y) {
-                               case 0: tbstr= "(De)Select All";        tbstr1= "a";    keystr= "A";            break;
-                               case 1: tbstr= "Border Select";         tbstr1= "b";    keystr= "B";            break;
-                               case 2: tbstr= "Select Linked";         tbstr1= "l";    keystr= "L";            break;
-                               case 3: tbstr= "Hide Selected";         tbstr1= "h";    keystr= "H";            break;
-                               case 4: tbstr= "Duplicate";                     tbstr1= "D";    keystr= "Shift D";      break;
-                               case 5: tbstr= "Delete";                        tbstr1= "x";    keystr= "X";            break;
-                               case 6: tbstr= "Edit Mode";                     tbstr1= "Tab";  keystr= "Tab";          break;
-                               case 7: tbstr= "Grabber";                       tbstr1= "g";    keystr= "G";            break;
-                               case 8: tbstr= "Rotate";                        tbstr1= "r";    keystr= "R";            break;
-                               case 9: tbstr= "Scale";                         tbstr1= "s";    keystr= "S";            break;
-                               case 10: tbstr= "Shrink/Fatten";        tbstr1= "a|s";  keystr= "Alt S";        break;
-                               case 11: tbstr= "Shear";                        tbstr1= "c|s";  keystr= "Ctrl S";       break;
-                               case 12: tbstr= "Warp/Bend";            tbstr1= "W";    keystr= "Shift W";      break;
-                               case 13: tbstr= "Snap Menu";            tbstr1= "S";    keystr= "Shift S";      break;
-                       }
-               }
-
-/* ADD TOPICS */
-               if(tbmain==TBOX_MAIN_ADD) {
-
-                       if(addmode==0) {
-                               switch(y) {
-                                       case 0: tbstr= "Mesh";          tbstr1= ">>";   keystr= ">>";   tbval=OB_MESH;                                                                          break;
-                                       case 1: tbstr= "Curve";         tbstr1= ">>";   keystr= ">>";   tbval=OB_CURVE;                                                                         break;
-                                       case 2: tbstr= "Surface";       tbstr1= ">>";   keystr= ">>";   tbval=OB_SURF;                                                                          break;
-                                       case 3: tbstr= "Meta";          tbstr1= ">>";   keystr= ">>";   tbval=OB_MBALL;                                                                         break;
-                                       case 4: tbstr= "Text";          tbstr1= "";             keystr= "";             tbval=OB_FONT;  tbfunc= add_primitiveFont;                      break;
-                                       case 5: tbstr= "Empty";         tbstr1= "A";    keystr= "";             tbval=OB_EMPTY;                                                                         break;
-                                       case 6: tbstr= "";                      tbstr1= "";             keystr= "";             tbval=0;                                                                                        break;
-                                       case 7: tbstr= "Camera";        tbstr1= "A";    keystr= "";             tbval=OB_CAMERA;                                                                        break;
-                                       case 8: tbstr= "Lamp";          tbstr1= "A";    keystr= "";             tbval=OB_LAMP;                                                                          break;
-                                       case 9: tbstr= "Armature";      tbstr1= "";             keystr= "";             tbval=OB_ARMATURE;      tbfunc=add_primitiveArmature;   break;
-                                       case 10: tbstr= "";                     tbstr1= "";             keystr= "";             tbval=0;                                                                                        break;
-                                       case 11: tbstr= "Lattice";      tbstr1= "A";    keystr= "";             tbval=OB_LATTICE;                                                                       break;
-                                       case 12: tbstr= "";                     tbstr1= "";             keystr= "";             tbval=0;                                                                                        break;
-                                       case 13: tbstr= "";                     tbstr1= "";             keystr= "";             tbval=0;                                                                                        break;
-                               }
-                               if(tbstr1 && tbstr1[0]=='A') tbfunc= (void (*)(int))add_object_draw;
-                       }
-                       else if(addmode==OB_MESH) {             
-                               switch(y) {
-                                       case 0: tbstr= ">Plane";        tbstr1= "A";    keystr= "";             tbval=0;        break;
-                                       case 1: tbstr= ">Cube";         tbstr1= "A";    keystr= "";             tbval=1;        break;
-                                       case 2: tbstr= ">Circle";       tbstr1= "A";    keystr= "";             tbval=4;        break;
-                                       case 3: tbstr= ">UVsphere";     tbstr1= "A";    keystr= "";             tbval=11;       break;
-                                       case 4: tbstr= ">Icosphere";tbstr1= "A";        keystr= "";             tbval=12;       break;
-                                       case 5: tbstr= ">Cylinder";     tbstr1= "A";    keystr= "";             tbval=5;        break;
-                                       case 6: tbstr= ">Tube";         tbstr1= "A";    keystr= "";             tbval=6;        break;
-                                       case 7: tbstr= ">Cone";         tbstr1= "A";    keystr= "";             tbval=7;        break;
-                                       case 8: tbstr= ">";                     tbstr1= "";             keystr= "";                                     break;
-                                       case 9: tbstr= ">Grid";         tbstr1= "A";    keystr= "";             tbval=10;       break;
-                                       case 13: tbstr= ">Monkey";      tbstr1= "A";    keystr= "";             tbval=13;       break;
-                               }
-                               if(tbstr1 && tbstr1[0]=='A') tbfunc= add_primitiveMesh;
-                       }
-                       else if(addmode==OB_SURF) {
-                               switch(y) {
-                                       case 0: tbstr= ">Curve";        tbstr1= "A";    keystr= "";             tbval=0; break;
-                                       case 1: tbstr= ">Circle";       tbstr1= "A";    keystr= "";             tbval=1; break;
-                                       case 2: tbstr= ">Surface";      tbstr1= "A";    keystr= "";             tbval=2; break;
-                                       case 3: tbstr= ">Tube";         tbstr1= "A";    keystr= "";             tbval=3; break;
-                                       case 4: tbstr= ">Sphere";       tbstr1= "A";    keystr= "";             tbval=4; break;
-                                       case 5: tbstr= ">Donut";        tbstr1= "A";    keystr= "";             tbval=5; break;
-                               }
-                               if(tbstr1 && tbstr1[0]=='A') tbfunc= add_primitiveNurb;
-                       }
-/*                     else if (addmode==OB_ARMATURE){
-                               switch(y) {
-                                       case 0: tbstr= ">Bone";         tbstr1= "A";    keystr= "";             tbval=0; break;
-                                       case 1: tbstr= ">Hand";         tbstr1= "A";    keystr= "";             tbval=1; break;
-                                       case 2: tbstr= ">Biped";        tbstr1= "A";    keystr= "";             tbval=2; break;
-                               }
-                               if(tbstr1 && tbstr1[0]=='A') tbfunc= add_primitiveArmature;     
-                       }
-*/
-                       else if(addmode==OB_CURVE) {
-                               switch(y) {
-                                       case 0: tbstr= ">Bezier Curve";         tbstr1= "A";    keystr= "";     tbval=10;       break;
-                                       case 1: tbstr= ">Bezier Circle";        tbstr1= "A";    keystr= "";     tbval=11;       break;
-                                       case 2: tbstr= ">";                                     tbstr1= "";             keystr= "";                             break;
-                                       case 3: tbstr= ">Nurbs Curve";          tbstr1= "A";    keystr= "";     tbval=40;       break;
-                                       case 4: tbstr= ">Nurbs Circle";         tbstr1= "A";    keystr= "";     tbval=41;       break;
-                                       case 5: tbstr= ">";                                     tbstr1= "";             keystr= "";                             break;
-                                       case 6: tbstr= ">Path";                         tbstr1= "A";    keystr= "";     tbval=46;       break;
-                               }
-                               if(tbstr1 && tbstr1[0]=='A') tbfunc= add_primitiveCurve;
-                       }
-                       else if(addmode==OB_MBALL) {
-                               switch(y) {
-                                       case 0: tbstr= "Ball";                  tbstr1= "A";    tbval=1; break;
-                                       case 1: tbstr= "Tube";                  tbstr1= "A";    tbval=2; break;
-                                       case 2: tbstr= "Plane";                 tbstr1= "A";    tbval=3; break;
-                                       case 3: tbstr= "Elipsoid";              tbstr1= "A";    tbval=4; break;
-                                       case 4: tbstr= "Cube";                  tbstr1= "A";    tbval=5; break;
-                                       case 5: tbstr= "";                      tbstr1= "";             break;
-                                       case 6: tbstr= "";                      tbstr1= "";             break;
-                                       case 7: tbstr= "";                      tbstr1= "";             break;
-                                       case 8: tbstr= "";                      tbstr1= "";             break;
-                                       case 9: tbstr= "";                      tbstr1= "";             break;
-                                       case 10: tbstr= "";                     tbstr1= "";             break;
-                                       case 11: tbstr= "Duplicate";tbstr1= "D";        break;
-                               }
-                               if(tbstr1 && tbstr1[0]=='A') tbfunc= add_primitiveMball;
-                       }
-               }
-               
-/* OB TOPICS 1 */
-               else if(tbmain==TBOX_MAIN_OBJECT1) {
-                       switch(y) {
-                               case 0: tbstr= "Clear Size";            tbstr1= "a|s";  keystr= "Alt S";        break;
-                               case 1: tbstr= "Clear Rotation";        tbstr1= "a|r";  keystr= "Alt R";        break;
-                               case 2: tbstr= "Clear Location";        tbstr1= "a|g";  keystr= "Alt G";        break;
-                               case 3: tbstr= "Clear Origin";          tbstr1= "a|o";  keystr= "Alt O";        break;
-                               case 4: tbstr= "Make Parent";           tbstr1= "c|p";  keystr= "Ctrl P";       break;
-                               case 5: tbstr= "Clear Parent";          tbstr1= "a|p";  keystr= "Alt P";        break;
-/*     Unkown what tbstr1 should be...
-                               case 6: tbstr= "MkVert Parent";         tbstr1= "c|a|p";        keystr= "Ctrl Alt P";   break;
-*/
-                               case 7: tbstr= "Make Track";            tbstr1= "c|t";  keystr= "Ctrl T";       break;
-                               case 8: tbstr= "Clear Track";           tbstr1= "a|t";  keystr= "Alt T";        break;
-/*                             case 9: tbstr= "";                                      tbstr1= "";             keystr= "";                     break; */
-                               case 10: tbstr= "Image Displist";       tbstr1= "c|d";  keystr= "Ctrl D";       break;
-                               case 11: tbstr= "Image Aspect";         tbstr1= "a|v";  keystr= "Alt V";        break;
-                               case 12: tbstr= "Vect Paint";           tbstr1= "v";    keystr= "V";    break;
-                       }
-               }
-               
-/* OB TOPICS 2 */
-               else if(tbmain==TBOX_MAIN_OBJECT2) {
-                       switch(y) {
-                               case 0: tbstr= "Edit Mode";                     tbstr1= "Tab";  keystr= "Tab";                  break;
-                               case 1: tbstr= "Move To Layer";         tbstr1= "m";    keystr= "M";                    break;
-                               case 2: tbstr= "Delete";                        tbstr1= "x";    keystr= "X";                    break;
-                               case 3: tbstr= "Delete All";            tbstr1= "c|x";  keystr= "Ctrl X";               break;
-                               case 4: tbstr= "Apply Size/Rot";        tbstr1= "c|a";  keystr= "Ctrl A";               break;
-                               case 5: tbstr= "Apply Deform";          tbstr1= "c|A";  keystr= "Ctrl Shift A"; break;
-                               case 6: tbstr= "Join";                          tbstr1= "c|j";  keystr= "Ctrl J";               break;
-                               case 7: tbstr= "Make Local";            tbstr1= "l";    keystr= "L";                    break;
-                               case 8: tbstr= "Select Linked";         tbstr1= "L";    keystr= "Shift L";              break;
-                               case 9: tbstr= "Make Links";            tbstr1= "c|l";  keystr= "Ctrl L";               break;
-                               case 10: tbstr= "Copy Menu";            tbstr1= "c|c";  keystr= "Ctrl C";               break;
-                               case 11: tbstr= "Convert Menu";         tbstr1= "a|c";  keystr= "Alt C";                break;
-                               case 12: tbstr= "Boolean Op";           tbstr1= "w";    keystr= "W";            break;
-                       }
-               }
-
-/* mesh TOPICS */
-               else if(tbmain==TBOX_MAIN_MESH) {
-                       switch(y) {
-                               case 0: tbstr= "Select Linked";         tbstr1= "l";    keystr= "L";            break;
-                               case 1: tbstr= "Deselect Linked";       tbstr1= "L";    keystr= "Shift L";      break;
-                               case 2: tbstr= "Extrude";                       tbstr1= "e";    keystr= "E";            break;
-                               case 3: tbstr= "Delete Menu";           tbstr1= "x";    keystr= "X";            break;
-                               case 4: tbstr= "Make edge/face";        tbstr1= "f";    keystr= "F";            break;
-                               case 5: tbstr= "Fill";                          tbstr1= "F";    keystr= "Shift F";      break;
-                               case 6: tbstr= "Split";                         tbstr1= "y";    keystr= "Y";            break;
-                               case 7: tbstr= "Undo/reload";           tbstr1= "u";    keystr= "U";            break;
-                               case 8: tbstr= "Calc Normals";          tbstr1= "c|n";  keystr= "Ctrl N";       break;
-                               case 9: tbstr= "Separate";                      tbstr1= "p";    keystr= "P";            break;
-                               case 10: tbstr= "Write Videosc";        tbstr1= "a|w";  keystr= "Alt W";        break;
-/*                             case 11: tbstr= "";                                     tbstr1= "";             keystr= "";                     break; */
-                       }
-               }
-       
-/* CURVE TOPICS */
-               else if(tbmain==TBOX_MAIN_CURVE) {
-                       switch(y) {
-                               case 0: tbstr= "Select Linked";         tbstr1= "l";    keystr= "L";            break;
-                               case 1: tbstr= "Deselect Linked";       tbstr1= "L";    keystr= "Shift L";      break;
-                               case 2: tbstr= "Extrude";                       tbstr1= "e";    keystr= "E";            break;
-                               case 3: tbstr= "Delete Menu";           tbstr1= "x";    keystr= "X";            break;
-                               case 4: tbstr= "Make Segment";          tbstr1= "f";    keystr= "F";            break;
-                               case 5: tbstr= "Cyclic";                        tbstr1= "c";    keystr= "C";            break;
-/*                             case 6: tbstr= "";                                      tbstr1= "";             keystr= "";                     break; */
-                               case 7: tbstr= "Select Row";            tbstr1= "R";    keystr= "Shift R";      break;
-                               case 8: tbstr= "Calc Handle";           tbstr1= "h";    keystr= "H";            break;
-                               case 9: tbstr= "Auto Handle";           tbstr1= "H";    keystr= "Shift H";      break;
-                               case 10: tbstr= "Vect Handle";          tbstr1= "v";    keystr= "V";            break;
-                               case 11: tbstr= "Specials";                     tbstr1= "w";    keystr= "W";            break;
-                       }
-               }
-       
-/* KEY TOPICS */
-               else if(tbmain==TBOX_MAIN_KEY) {
-                       switch(y) {
-                               case 0: tbstr= "Insert";        tbstr1= "i";            keystr= "I";            break;
-                               case 1: tbstr= "Show";          tbstr1= "k";            keystr= "K";            break;
-                               case 2: tbstr= "Next";          tbstr1= "PageUp";       keystr= "PgUp";         break;
-                               case 3: tbstr= "Prev";          tbstr1= "PageDn";       keystr= "PgDn";         break;
-                               case 4: tbstr= "Show+Sel";      tbstr1= "K";            keystr= "Shift K";      break;
-/*                             case 5: tbstr= "";                      tbstr1= "";                     keystr= "";                     break;
-                               case 6: tbstr= "";                      tbstr1= "";                     keystr= "";                     break;
-                               case 7: tbstr= "";                      tbstr1= "";                     keystr= "";                     break;
-                               case 8: tbstr= "";                      tbstr1= "";                     keystr= "";                     break;
-                               case 9: tbstr= "";                      tbstr1= "";                     keystr= "";                     break;
-                               case 10: tbstr= "";                     tbstr1= "";                     keystr= "";                     break;
-                               case 11: tbstr= "";                     tbstr1= "";                     keystr= "";                     break; */
-                       }
-               }
-/* SEQUENCER TOPICS */
-                else if(tbmain==TBOX_MAIN_SEQ) {
-                        switch(y) {
-                                case 0: tbstr= "Add Strip";  tbstr1= "A"; keystr= "Shift A"; break;
-                                case 1: tbstr= "Change Str"; tbstr1= "c"; keystr= "C";       break;
-                                case 2: tbstr= "Delete Str"; tbstr1= "x"; keystr= "X";       break;
-                                case 3: tbstr= "Make Meta";  tbstr1= "m"; keystr= "M";       break;
-                                case 4: tbstr= "Str Params"; tbstr1= "n"; keystr= "N";       break;
-                        }
-                }
-
-/* RENDER TOPICS */
-               else if(tbmain==TBOX_MAIN_RENDER) {
-                       switch(y) {
-                               case 0: tbstr= "Render Window"; tbstr1= "F11";  keystr= "F11";          break;
-                               case 1: tbstr= "Render";                tbstr1= "F12";  keystr= "F12";          break;
-                               case 2: tbstr= "Set Border";    tbstr1= "B";    keystr= "Shift B";      break;
-                               case 3: tbstr= "Image Zoom";    tbstr1= "z";    keystr= "Z";            break;
-/*                             case 4: tbstr= "";                              tbstr1= "";             keystr= "";                     break;
-                               case 5: tbstr= "";                              tbstr1= "";             keystr= "";                     break;
-                               case 6: tbstr= "";                              tbstr1= "";             keystr= "";                     break;
-                               case 7: tbstr= "";                              tbstr1= "";             keystr= "";                     break;
-                               case 8: tbstr= "";                              tbstr1= "";             keystr= "";                     break;
-                               case 9: tbstr= "";                              tbstr1= "";             keystr= "";                     break;
-                               case 10: tbstr= "";                             tbstr1= "";             keystr= "";                     break;
-                               case 11: tbstr= "";                             tbstr1= "";             keystr= "";                     break; */
-                       }
-               }
-       
-/* VIEW TOPICS */
-               else if(tbmain==TBOX_MAIN_VIEW) {
-                       switch(y) {
-/*                             case 0: tbstr= "";              tbstr1= "";     break;
-                               case 1: tbstr= "";              tbstr1= "";     break;
-                               case 2: tbstr= "";              tbstr1= "";     break;
-                               case 3: tbstr= "";              tbstr1= "";     break; */
-                               case 4: tbstr= "Centre";                tbstr1= "c";    keystr= "C";            break;
-                               case 5: tbstr= "Home";                  tbstr1= "C";    keystr= "Shift C";      break;
-/*                             case 6: tbstr= "";              tbstr1= "";     break;
-                               case 7: tbstr= "";              tbstr1= "";     break;
-                               case 8: tbstr= "";              tbstr1= "";     break;*/
-                               case 9: tbstr= "Z-Buffer";              tbstr1= "z";    keystr= "Z";            break;
-/*                             case 10: tbstr= "";             tbstr1= "";     break;
-                               case 11: tbstr= "";             tbstr1= "";     break;*/
-                       }
-               }
-#ifdef PY_TOOLBOX
-               else if(tbmain==TBOX_MAIN_PYTOOL) {
-                       TBcallback *t= g_toolbox_menucallback(0, y); // call python menu constructor
-                       if (t) { 
-                               tbstr = t->desc; 
-                               keystr = t->key;
-                               tbfunc = t->cb;
-                               tbval = t->val;
-                       }
-               }
-#endif
-       }
-}
-
-/* ******************** INIT ************************** */
-
-void bgnpupdraw(int startx, int starty, int endx, int endy)
-{
-       #if defined(__sgi) || defined(__sun__) || defined( __sun ) || defined (__sparc) || defined (__sparc__)
-
-       /* this is a dirty patch: XgetImage gets sometimes the backbuffer */
-       my_get_frontbuffer_image(0, 0, 1, 1);
-       my_put_frontbuffer_image();
-       #endif
-
-       tboldwin= mywinget();
-
-       mywinset(G.curscreen->mainwin);
-       
-       /* tinsy bit larger, 1 pixel on the rand */
-       
-       glReadBuffer(GL_FRONT);
-       glDrawBuffer(GL_FRONT);
-
-       glFlush();
-
-       my_get_frontbuffer_image(startx-1, starty-4, endx-startx+5, endy-starty+6);
-
-       oldcursor= get_cursor();
-       set_cursor(CURSOR_STD);
-       
-       tbfontyofs= (TBOXH-11)/2 +1;    /* ypos text in toolbox */
-}
-
-void endpupdraw(void)
-{
-       glFlush();
-       my_put_frontbuffer_image();
-       
-       if(tboldwin) {
-               mywinset(tboldwin);
-               set_cursor(oldcursor);
-       }
-
-       glReadBuffer(GL_BACK);
-       glDrawBuffer(GL_BACK);
-}
-
-/* ********************************************** */
+#include "butspace.h"
+#include "mydevice.h"
 
 void asciitoraw(int ch, unsigned short *event, unsigned short *qual)
 {
@@ -574,471 +159,6 @@ void asciitoraw(int ch, unsigned short *event, unsigned short *qual)
        }
 }
 
-void tbox_execute(void)
-{
-       /* if tbfunc: call function */
-       /* if tbstr1 is a string: put value tbval in queue */
-       unsigned short event=0;
-       unsigned short qual1=0, qual2=0;
-
-       /* needed to check for valid selected objects */
-       Base *base=NULL;
-       Object *ob=NULL;
-
-       base= BASACT;
-       if (base) ob= base->object;
-
-       if(tbfunc) {
-               tbfunc(tbval);
-       }
-       else if(tbstr1) {
-               if(strcmp(tbstr1, "Tab")==0) {
-                       event= TABKEY;
-               }
-               else if(strcmp(tbstr1, "PageUp")==0) {
-                       event= PAGEUPKEY;
-               }
-               else if(strcmp(tbstr1, "PageDn")==0) {
-                       event= PAGEDOWNKEY;
-               }
-               else if(strcmp(tbstr1, "shift+F1")==0) {
-                       qual1= LEFTSHIFTKEY;
-                       event= F1KEY;
-               }
-               else if(strcmp(tbstr1, "shift+F2")==0) {
-                       qual1= LEFTSHIFTKEY;
-                       event= F2KEY;
-               }
-               /* ctrl-s (Shear): switch into editmode ### */
-               else if(strcmp(tbstr1, "c|s")==0) {
-                       /* check that a valid object is selected to prevent crash */
-                       if(!ob) error("Only selected objects can be sheared");
-                       else if ((ob->type==OB_LAMP) || (ob->type==OB_EMPTY) || (ob->type==OB_FONT) || (ob->type==OB_CAMERA)) {
-                               error("Only editable 3D objects can be sheared");
-                       }
-                       else if ((base->lay & G.vd->lay)==0) {
-                               error("Only objects on visible layers can be sheared");
-                       }
-                       else {
-                               if (!G.obedit) {
-                                       enter_editmode();
-                                       /* ### put these into a deselectall_gen() */
-                                       if(G.obedit->type==OB_MESH) deselectall_mesh();
-                                       else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) deselectall_nurb();
-                                       else if(G.obedit->type==OB_MBALL) deselectall_mball();
-                                       else if(G.obedit->type==OB_LATTICE) deselectall_Latt();
-                                       /* ### */
-                               }
-                               qual1 = LEFTCTRLKEY;
-                               event = SKEY;
-                       }
-               }
-               else if(strcmp(tbstr1, "W")==0) {
-                       if (!ob) error ("Only selected objects can be warped");
-                       /* check that a valid object is selected to prevent crash */
-                       else if ((ob->type==OB_LAMP) || (ob->type==OB_EMPTY) || (ob->type==OB_FONT) || (ob->type==OB_CAMERA)) {
-                               error("Only editable 3D objects can be warped");
-                       }
-                       else if ((base->lay & G.vd->lay)==0) {
-                               error("Only objects on visible layers can be warped");
-                       }
-                       else {
-                               if (!G.obedit) {
-                                       enter_editmode();
-                                       /* ### put these into a deselectall_gen() */
-                                       if(G.obedit->type==OB_MESH) deselectall_mesh();
-                                       else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) deselectall_nurb();
-                                       else if(G.obedit->type==OB_MBALL) deselectall_mball();
-                                       else if(G.obedit->type==OB_LATTICE) deselectall_Latt();
-                                       /* ### */
-                               }
-                               qual1 = LEFTSHIFTKEY;
-                               event = WKEY;
-                       }
-               }
-
-               else if(strlen(tbstr1)<4 || (strlen(tbstr1)==4 && tbstr1[2]=='F')) {
-                               
-                       if(tbstr1[1]=='|') {
-                               if(tbstr1[0]=='c') qual1= LEFTCTRLKEY;
-                               else if(tbstr1[0]=='a') qual1= LEFTALTKEY;
-                               
-                               if (tbstr1[2]=='F') {
-                                       switch(tbstr1[3]) {
-                                       case '1': event= F1KEY; break;
-                                       case '2': event= F2KEY; break;
-                                       case '3': event= F3KEY; break;
-                                       case '4': event= F4KEY; break;
-                                       case '5': event= F5KEY; break;
-                                       case '6': event= F6KEY; break;
-                                       case '7': event= F7KEY; break;
-                                       case '8': event= F8KEY; break;
-                                       case '9': event= F9KEY; break;
-                                       }
-                               }
-                               else asciitoraw(tbstr1[2], &event, &qual2);
-                       }
-                       else if(tbstr1[1]==0) {
-                               asciitoraw(tbstr1[0], &event, &qual2);
-                       }
-                       else if(tbstr1[0]=='F') {
-                               event= atoi(tbstr1+1);
-                               switch(event) {
-                                       case 1: event= F1KEY; break;
-                                       case 2: event= F2KEY; break;
-                                       case 3: event= F3KEY; break;
-                                       case 4: event= F4KEY; break;
-                                       case 5: event= F5KEY; break;
-                                       case 6: event= F6KEY; break;
-                                       case 7: event= F7KEY; break;
-                                       case 8: event= F8KEY; break;
-                                       case 9: event= F9KEY; break;
-                                       case 10: event= F10KEY; break;
-                                       case 11: event= F11KEY; break;
-                                       case 12: event= F12KEY; break;
-                               }
-                       }
-               }
-               
-               if(event) {
-                       if(qual1) mainqenter(qual1, 1);
-                       if(qual2) mainqenter(qual2, 1);
-                       mainqenter(event, 1);
-                       mainqenter(event, 0);
-                       mainqenter(EXECUTE, 1);
-                       if(qual1) mainqenter(qual1, 0);
-                       if(qual2) mainqenter(qual2, 0);
-               }
-       }
-       
-}
-
-void tbox_getmouse(mval)
-short *mval;
-{
-
-       getmouseco_sc(mval);
-
-}
-
-void tbox_setmain(int val)
-{
-       tbmain= val;
-
-       if(tbmain==0 && G.obedit) {
-               addmode= G.obedit->type;
-       }
-}
-
-void bgntoolbox(void)
-{
-       short xmax, ymax, mval[2];
-       
-       xmax = G.curscreen->sizex;
-       ymax = G.curscreen->sizey;
-
-       tbox_getmouse(mval);
-       
-       if(mval[0]<95) mval[0]= 95;
-       if(mval[0]>xmax-95) mval[0]= xmax-95;
-
-       warp_pointer(mval[0], mval[1]);
-
-       tbx1= mval[0]-tbmemx;
-       tby1= mval[1]-tbmemy;
-       if(tbx1<10) tbx1= 10;
-       if(tby1<10) tby1= 10;
-       
-       tbx2= tbx1+TBOXX;
-       tby2= tby1+TBOXY;
-       if(tbx2>xmax) {
-               tbx2= xmax-10;
-               tbx1= tbx2-TBOXX;
-       }
-       if(tby2>ymax) {
-               tby2= ymax-10;
-               tby1= tby2-TBOXY;
-       }
-
-       bgnpupdraw(tbx1, tby1, tbx2, tby2);
-}
-
-void endtoolbox(void)
-{
-       short mval[2];
-       
-       tbox_getmouse(mval);
-       if(mval[0]>tbx1 && mval[0]<tbx2)
-               if(mval[1]>tby1 && mval[1]<tby2) {
-                       tbmemx= mval[0]-(tbx1);
-                       tbmemy= mval[1]-(tby1);
-       }
-       
-       endpupdraw();
-}
-
-
-void tbox_embossbox(short x1, short y1, short x2, short y2, short type)        
-/* type: 0=menu, 1=menusel, 2=topic, 3=topicsel */
-{
-       
-       if(type==0) {
-               glColor3ub(160, 160, 160);
-               glRects(x1+1, y1+1, x2-1, y2-1);
-       }
-       if(type==1) {
-               glColor3ub(50, 50, 100);
-               glRects(x1+1, y1+1, x2-1, y2-1);
-       }
-       if(type==2) {
-               glColor3ub(190, 190, 190);
-               glRects(x1+1, y1+1, x2-1, y2-1);
-       }
-       if(type==3) {
-               cpack(0xc07070);
-               glRects(x1+1, y1+1, x2-1, y2-1);
-       }
-       
-       if(type & 1) cpack(0xFFFFFF);
-       else cpack(0x0);
-}
-
-
-void tbox_drawelem_body( int x, int y, int type)
-{
-       int x1 = 0, y1, x2 = 0, y2;
-       
-       if(x==0) {
-               x1= tbx1; x2= tbx1+TBOXXL;
-       }
-       else if(x==1) {
-               x1= tbx1+TBOXXL;
-               x2= x1+ TBOXXR-1;
-       }
-       
-       y1= tby1+ (TBOXEL-y-1)*TBOXH;
-       y2= y1+TBOXH-1;
-       
-       tbox_embossbox(x1, y1, x2, y2, type);
-       
-}
-
-void tbox_drawelem_text( int x, int y, int type)
-{
-       int x1 = 0, y1, x2 = 0, y2, len1, len2;
-       
-       if(x==0) {
-               x1= tbx1; x2= tbx1+TBOXXL;
-       }
-       else if(x==1) {
-               x1= tbx1+TBOXXL;
-               x2= x1+ TBOXXR-1;
-       }
-       
-       y1= tby1+ (TBOXEL-y-1)*TBOXH;
-       y2= y1+TBOXH-1;
-       
-       if(type==0 || type==2) {
-               ColorFunc(TBOXBLACK);
-       }
-       else {
-               glColor3ub(240, 240, 240);
-       }
-       
-       /* text */
-       tbox_setinfo(x, y);
-       if(tbstr && tbstr[0]) {
-               len1= 5+BMF_GetStringWidth(G.font, tbstr);
-               if(keystr) len2= 5+BMF_GetStringWidth(G.font, keystr); else len2= 0;
-               
-               while(len1>0 && (len1+len2+5>x2-x1) ) {
-                       tbstr[strlen(tbstr)-1]= 0;
-                       len1= BMF_GetStringWidth(G.font, tbstr);
-               }
-               
-               glRasterPos2i(x1+5, y1+tbfontyofs);
-               BIF_DrawString(G.font, tbstr, (U.transopts & USER_TR_MENUS));
-               
-               if(keystr && keystr[0]) {
-                       if(type & 1) {
-                               ColorFunc(TBOXBLACK);
-       
-                               glRecti(x2-len2-2,  y1+2,  x2-3,  y2-2);
-                               ColorFunc(TBOXWHITE);
-                               glRasterPos2i(x2-len2,  y1+tbfontyofs);
-                               BIF_DrawString(G.font, keystr, (U.transopts & USER_TR_MENUS));
-                       }
-                       else {
-                               ColorFunc(TBOXBLACK);
-                               glRasterPos2i(x2-len2,  y1+tbfontyofs);
-                               BIF_DrawString(G.font, keystr, (U.transopts & USER_TR_MENUS));
-                       }
-               }
-       }
-}
-
-
-void tbox_drawelem(x, y, type)
-int x, y, type;        
-{
-       /* type: 0=menu, 1=menusel, 2=topic, 3=topicsel */
-
-       tbox_drawelem_body(x, y, type);
-       tbox_drawelem_text(x, y, type);
-       
-}
-
-void tbox_getactive(x, y)
-int *x, *y;
-{
-       short mval[2];
-       
-       tbox_getmouse(mval);
-       
-       mval[0]-=tbx1;
-       if(mval[0]<TBOXXL) *x= 0;
-       else *x= 1;
-       
-       *y= mval[1]-tby1;
-       *y/= TBOXH;
-       *y= TBOXEL- *y-1;
-       if(*y<0) *y= 0;
-       if(*y>TBOXEL-1) *y= TBOXEL-1;
-       
-}
-
-void drawtoolbox(void)
-{
-       int x, y, actx, acty, type;
-
-       tbox_getactive(&actx, &acty);
-
-       /* background */
-       for(x=0; x<2; x++) {
-               
-               for(y=0; y<TBOXEL; y++) {
-                       
-                       if(x==0) type= 0; 
-                       else type= 2;
-                       
-                       if(actx==x && acty==y) type++;
-                       if(type==0) {
-                               if(tbmain==y) type= 1;
-                       }
-                       
-                       tbox_drawelem_body(x, y, type);
-                       
-               }
-       }
-
-       /* text */
-       for(x=0; x<2; x++) {
-               
-               for(y=0; y<TBOXEL; y++) {
-                       
-                       if(x==0) type= 0; 
-                       else type= 2;
-                       
-                       if(actx==x && acty==y) type++;
-                       if(type==0) {
-                               if(tbmain==y) type= 1;
-                       }
-                       
-                       tbox_drawelem_text(x, y, type);
-                       
-               }
-       }
-       glFlush();              /* for geforce, to show it in the frontbuffer */
-
-}
-
-
-void toolbox(void)
-{
-       int actx, acty, y;
-       unsigned short event;
-       short val, mval[2], xo= -1, yo=0;
-       
-       bgntoolbox();
-       glColor3ub(0xB0, 0xB0, 0xB0);
-       uiDrawMenuBox((float)tbx1, (float)tby1-1, (float)tbx2, (float)tby2, 0);
-       drawtoolbox();
-       
-       /* 
-        *      The active window will be put back in the queue.
-        */
-
-       while(1) {
-               event= extern_qread(&val);
-               if(event) {
-                       switch(event) {
-                               case LEFTMOUSE: case MIDDLEMOUSE: case RIGHTMOUSE: case RETKEY: case PADENTER:
-                                       if(val==1) {
-                                               tbox_getactive(&actx, &acty);
-                                               tbox_setinfo(actx, acty);
-                                               
-                                               if(event==RIGHTMOUSE) {
-                                                       if(addmode) {
-                                                               addmode= 0;
-                                                               drawtoolbox();
-                                                       }
-                                               }
-                                               else if(tbstr1 && tbstr1[0]=='>') {
-                                                       addmode= tbval;
-                                                       drawtoolbox();
-                                               }
-                                               else {
-                                                       endtoolbox();
-                                                       tbox_execute();
-                                                       return;
-                                               }
-                                       }
-                                       break;
-                               case ESCKEY:
-                                       /* alt keys: to prevent conflicts with over-draw and stow/push/pop at sgis */
-#ifndef MAART
-/* Temporary for making screen dumps (Alt+PrtSc) */
-                               case LEFTALTKEY:
-                               case RIGHTALTKEY:
-#endif /* MAART */
-                                       if(val) endtoolbox();
-                                       return;
-                       }
-               }
-               
-               tbox_getmouse(mval);
-               if(mval[0]<tbx1-10 || mval[0]>tbx2+10 || mval[1]<tby1-10 || mval[1]>tby2+10) break;
-               
-               tbox_getactive(&actx, &acty);
-               
-               /* mouse handling and redraw */
-               if(xo!=actx || yo!=acty) {
-                       if(actx==0) {
-                               if (acty==0) addmode=0;
-                               
-                               tbox_drawelem(0, tbmain, 0);
-                               tbox_drawelem(0, acty, 1);
-                               
-                               tbmain= acty;
-                               addmode= 0;
-                               for(y=0; y<TBOXEL; y++) tbox_drawelem(1, y, 2);
-                       }
-                       else if(xo> -1) {
-                               if(xo==0) tbox_drawelem(xo, yo, 1);
-                               else tbox_drawelem(xo, yo, 2);
-                               tbox_drawelem(actx, acty, 3);
-                       }
-                       
-                       glFlush();              /* for geforce, to show it in the frontbuffer */
-                       
-                       xo= actx;
-                       yo= acty;
-               }
-       }
-
-       endtoolbox();
-}
-
 /* ************************************  */
 
 /* this va_ stuff allows printf() style codes in these menus */
@@ -1322,7 +442,6 @@ int movetolayer_short_buts(short *lay)
 }
 
 
-
 /* ********************** CLEVER_NUMBUTS ******************** */
 
 #define MAXNUMBUTS     24
@@ -1615,6 +734,8 @@ static void tb_do_hotkey(void *arg, int event)
        else if(event & TB_PAD) {
                event &= ~TB_PAD;
                switch(event) {
+               case '-': key= PADMINUS; break;
+               case '+': key= PADPLUSKEY; break;
                case '0': key= PAD0; break;
                case '5': key= PAD5; break;
                case '/': key= PADSLASHKEY; break;
@@ -2328,6 +1449,154 @@ static TBitem tb_render[]= {
        {       0, "Anim",                                      3, NULL},
        {  -1, "",                      0, tb_do_render}};
 
+/* ************************* NODES *********************** */
+
+
+/* dynamic items */
+#define TB_SH_INPUTS           0
+#define TB_SH_OUTPUTS          1
+#define TB_SH_OP_COLOR         2
+#define TB_SH_OP_VECTOR                3
+#define TB_SH_CONVERTORS       4
+#define TB_SH_GENERATORS       5
+#define TB_SH_GROUPS           6
+
+static TBitem tb_node_addsh[]= {
+       {       0, "Inputs",            1, NULL},
+       {       0, "Outputs",           2, NULL},
+       {       0, "Color Ops",         3, NULL},
+       {       0, "Vector Ops",        4, NULL},
+       {       0, "Convertors",        5, NULL},
+       {       0, "Generators",        6, NULL},
+       {       0, "Groups",            7, NULL},
+       {  -1, "",                      0, NULL}};
+
+
+#define TB_CMP_INPUTS          0
+#define TB_CMP_OUTPUTS         1
+#define TB_CMP_OP_COLOR                2
+#define TB_CMP_OP_VECTOR       3
+#define TB_CMP_OP_FILTER       4
+#define TB_CMP_CONVERTORS      5
+#define TB_CMP_GENERATORS      6
+#define TB_CMP_GROUPS          7
+
+static TBitem tb_node_addcomp[]= {
+       {       0, "Inputs",            1, NULL},
+       {       0, "Outputs",           2, NULL},
+       {       0, "Color Ops",         3, NULL},
+       {       0, "Vector Ops",        4, NULL},
+       {       0, "Filters",           5, NULL},
+       {       0, "Convertors",        6, NULL},
+       {       0, "Generators",        7, NULL},
+       {       0, "Groups",            8, NULL},
+       {  -1, "",                      0, NULL}};
+
+static void do_node_addmenu(void *arg, int event)
+{
+       SpaceNode *snode= curarea->spacedata.first;
+       float locx, locy;
+       short mval[2];
+       
+       getmouseco_areawin(mval);
+       areamouseco_to_ipoco(G.v2d, mval, &locx, &locy);
+       node_add_node(snode, event, locx, locy);
+       
+       addqueue(curarea->win, B_NODE_TREE_EXEC, 1);
+       
+       BIF_undo_push("Add Node");
+       
+}
+
+/* dynamic toolbox sublevel */
+static TBitem *node_add_sublevel(void **poin, bNodeTree *ntree, int nodeclass)
+{
+       static TBitem _addmenu[]= { {   0, "Empty",     0, NULL}, {  -1, "",                    0, NULL}};
+       bNodeType **typedefs;
+       TBitem *addmenu;
+       int tot= 0, a;
+       
+       if(ntree) {
+               if(nodeclass==NODE_CLASS_GROUP) {
+                       bNodeTree *ngroup= G.main->nodetree.first;
+                       for(; ngroup; ngroup= ngroup->id.next)
+                               if(ngroup->type==ntree->type)
+                                       tot++;
+               }
+               else {
+                       for(typedefs= ntree->alltypes; *typedefs; typedefs++)
+                               if( (*typedefs)->nclass == nodeclass )
+                                       tot++;
+               }
+       }       
+       if(tot==0) {
+               *poin= _addmenu;
+               return NULL;
+       }
+       
+       addmenu= MEM_callocN(sizeof(TBitem)*(tot+1), "types menu");
+       
+       if(nodeclass==NODE_CLASS_GROUP) {
+               bNodeTree *ngroup= G.main->nodetree.first;
+               for(tot=0, a=0; ngroup; ngroup= ngroup->id.next, tot++) {
+                       if(ngroup->type==ntree->type) {
+                               addmenu[a].name= ngroup->id.name+2;
+                               addmenu[a].retval= NODE_GROUP_MENU+tot; /* so we can use BLI_findlink() */
+                               a++;
+                       }
+               }
+       }
+       else {
+               for(a=0, typedefs= ntree->alltypes; *typedefs; typedefs++) {
+                       if( (*typedefs)->nclass == nodeclass ) {
+                               addmenu[a].name= (*typedefs)->name;
+                               addmenu[a].retval= (*typedefs)->type;
+                               a++;
+                       }
+               }
+       }
+
+       addmenu[a].icon= -1;    /* end signal */
+       addmenu[a].name= "";
+       addmenu[a].retval= a;
+       addmenu[a].poin= do_node_addmenu;
+       
+       *poin= addmenu;
+       
+       return addmenu;
+}
+
+
+static TBitem tb_node_edit[]= {
+       {       0, "Duplicate|Shift D", TB_SHIFT|'d',           NULL},
+       {       0, "Delete|X", 'x',             NULL},
+       {       0, "SEPR",              0, NULL},
+       {       0, "Make Group|Ctrl G", TB_CTRL|'g',            NULL},
+       {       0, "Ungroup|Alt G", TB_ALT|'g',                 NULL},
+       {       0, "Edit Group", TB_TAB, NULL},
+       {       0, "SEPR",              0, NULL},
+       {       0, "Hide/Unhide|H", 'h', NULL},
+       {       0, "SEPR",              0, NULL},
+       {       0, "Show Cyclic Dependencies", 'c', NULL},
+       {  -1, "",                      0, tb_do_hotkey}};
+
+static TBitem tb_node_select[]= {
+       {       0, "Select/Deselect All|A",     'a', NULL},
+       {       0, "Border Select|B",   'b', NULL},
+       {  -1, "",                      0, tb_do_hotkey}};
+
+static TBitem tb_node_transform[]= {
+       {       0, "Grab/Move|G", 'g',          NULL},
+       {  -1, "",                      0, tb_do_hotkey}};
+
+static TBitem tb_node_view[]= {
+       {       0, "Zoom in|NumPad +",  TB_PAD|'+', NULL},
+       {       0, "Zoom out|NumPad -", TB_PAD|'-', NULL},
+       {       0, "View all|Home",     TB_PAD|'h', NULL},
+       {  -1, "",                      0, tb_do_hotkey}};
+
+
+/* *********************************************** */
 
 static uiBlock *tb_makemenu(void *arg)
 {
@@ -2434,7 +1703,9 @@ void toolbox_n(void)
        uiBut *but;
        TBitem *menu1=NULL, *menu2=NULL, *menu3=NULL; 
        TBitem *menu4=NULL, *menu5=NULL, *menu6=NULL;
-       TBitem *menu7=NULL, *groupmenu;
+       TBitem *menu7=NULL, *groupmenu= NULL;
+       TBitem *node_add_gen= NULL, *node_add_group= NULL, *node_add_out= NULL, *node_add_in= NULL;
+       TBitem *node_add_op_col= NULL, *node_add_op_filt= NULL, *node_add_op_vec= NULL, *node_add_con= NULL;
        int dx=0;
        short event, mval[2], tot=0;
        char *str1=NULL, *str2=NULL, *str3=NULL, *str4=NULL, *str5=NULL, *str6=NULL, *str7=NULL;
@@ -2456,17 +1727,17 @@ void toolbox_n(void)
        uiBlockSetFlag(block, UI_BLOCK_LOOP|UI_BLOCK_REDRAW|UI_BLOCK_RET_1);
        uiBlockSetCol(block, TH_MENU_ITEM);
        
-       /* dynamic menu entries */
-       groupmenu= create_group_sublevel();
-       
-       if (G.scene->r.renderer==R_YAFRAY)
-               tb_add[TB_ADD_LAMP].poin= addmenu_YF_lamp;
-       else
-               tb_add[TB_ADD_LAMP].poin= addmenu_lamp;
-       
        /* select context for main items */
        if(curarea->spacetype==SPACE_VIEW3D) {
 
+               /* dynamic menu entries */
+               groupmenu= create_group_sublevel();
+               
+               if (G.scene->r.renderer==R_YAFRAY)
+                       tb_add[TB_ADD_LAMP].poin= addmenu_YF_lamp;
+               else
+                       tb_add[TB_ADD_LAMP].poin= addmenu_lamp;
+               
                if(U.uiflag & USER_PLAINMENUS) {
                        menu1= tb_add; str1= "Add";
                        menu2= tb_object_edit; str2= "Edit";
@@ -2585,6 +1856,43 @@ void toolbox_n(void)
                else {
                }
        }
+       else if(curarea->spacetype==SPACE_NODE) {
+               SpaceNode *snode= curarea->spacedata.first;
+               
+               if(snode->treetype==NTREE_COMPOSIT)
+                       menu1= tb_node_addcomp; 
+               else
+                       menu1= tb_node_addsh; 
+               str1= "Add";
+               menu2= tb_node_edit; str2= "Edit";
+               menu3= tb_node_select; str3= "Select";
+               menu4= tb_node_transform; str4= "Transform";
+               menu5= tb_node_view; str5= "View";
+               
+               if(snode->treetype==NTREE_SHADER) {
+                       node_add_in= node_add_sublevel(&menu1[TB_SH_INPUTS].poin, snode->nodetree, NODE_CLASS_INPUT);
+                       node_add_out= node_add_sublevel(&menu1[TB_SH_OUTPUTS].poin, snode->nodetree, NODE_CLASS_OUTPUT);
+                       node_add_op_col= node_add_sublevel(&menu1[TB_SH_OP_COLOR].poin, snode->nodetree, NODE_CLASS_OP_COLOR);
+                       node_add_op_vec= node_add_sublevel(&menu1[TB_SH_OP_VECTOR].poin, snode->nodetree, NODE_CLASS_OP_VECTOR);
+                       node_add_con= node_add_sublevel(&menu1[TB_SH_CONVERTORS].poin, snode->nodetree, NODE_CLASS_CONVERTOR);
+                       node_add_gen= node_add_sublevel(&menu1[TB_SH_GENERATORS].poin, snode->nodetree, NODE_CLASS_GENERATOR);
+                       node_add_group= node_add_sublevel(&menu1[TB_SH_GROUPS].poin, snode->nodetree, NODE_CLASS_GROUP);
+               }
+               else if(snode->treetype==NTREE_COMPOSIT) {
+                       node_add_in= node_add_sublevel(&menu1[TB_CMP_INPUTS].poin, snode->nodetree, NODE_CLASS_INPUT);
+                       node_add_out= node_add_sublevel(&menu1[TB_CMP_OUTPUTS].poin, snode->nodetree, NODE_CLASS_OUTPUT);
+                       node_add_op_col= node_add_sublevel(&menu1[TB_CMP_OP_COLOR].poin, snode->nodetree, NODE_CLASS_OP_COLOR);
+                       node_add_op_filt= node_add_sublevel(&menu1[TB_CMP_OP_FILTER].poin, snode->nodetree, NODE_CLASS_OP_FILTER);
+                       node_add_op_vec= node_add_sublevel(&menu1[TB_CMP_OP_VECTOR].poin, snode->nodetree, NODE_CLASS_OP_VECTOR);
+                       node_add_con= node_add_sublevel(&menu1[TB_CMP_CONVERTORS].poin, snode->nodetree, NODE_CLASS_CONVERTOR);
+                       node_add_gen= node_add_sublevel(&menu1[TB_CMP_GENERATORS].poin, snode->nodetree, NODE_CLASS_GENERATOR);
+                       node_add_group= node_add_sublevel(&menu1[TB_CMP_GROUPS].poin, snode->nodetree, NODE_CLASS_GROUP);
+               }
+               
+               dx= 96;
+               tot= 5;
+               
+       }
        
        getmouseco_sc(mval);
        
@@ -2623,7 +1931,7 @@ void toolbox_n(void)
                but=uiDefBlockBut(block, tb_makemenu, menu6, str6,      mval[0]+(0.5*dx)+tb_mainx,mval[1]+tb_mainy-20, dx, 19, "");
                uiButSetFlag(but, UI_MAKE_DOWN|UI_MAKE_LEFT);
                uiButSetFunc(but, store_main, (void *)-dx, (void *)5);
-       } else if (tot==7) {
+       } else if (tot==5 || tot==7) {
                 /* check if it fits, dubious */
                if(mval[0]-0.25*dx+tb_mainx < 6) mval[0]= 6 + 0.25*dx -tb_mainx;
                else if(mval[0]+0.25*dx+tb_mainx > G.curscreen->sizex-6)
@@ -2652,21 +1960,34 @@ void toolbox_n(void)
                but=uiDefIconTextBlockBut(block, tb_makemenu, menu5, ICON_RIGHTARROW_THIN, str5, mval[0]+tb_mainx,mval[1]+tb_mainy-80, dx, 19, "");
                uiButSetFlag(but, UI_MAKE_RIGHT);
                uiButSetFunc(but, store_main, (void *)-32, (void *)75);
-
-               but=uiDefIconTextBlockBut(block, tb_makemenu, menu6, ICON_RIGHTARROW_THIN, str6, mval[0]+tb_mainx,mval[1]+tb_mainy-100, dx, 19, "");
-               uiButSetFlag(but, UI_MAKE_RIGHT);
-               uiButSetFunc(but, store_main, (void *)-32, (void *)95);
-
-               but=uiDefIconTextBlockBut(block, tb_makemenu, menu7, ICON_RIGHTARROW_THIN, str7, mval[0]+tb_mainx,mval[1]+tb_mainy-120, dx, 19, "");
-               uiButSetFlag(but, UI_MAKE_RIGHT);
-               uiButSetFunc(but, store_main, (void *)-32, (void *)105);
+               
+               if(tot>5) {
+                       but=uiDefIconTextBlockBut(block, tb_makemenu, menu6, ICON_RIGHTARROW_THIN, str6, mval[0]+tb_mainx,mval[1]+tb_mainy-100, dx, 19, "");
+                       uiButSetFlag(but, UI_MAKE_RIGHT);
+                       uiButSetFunc(but, store_main, (void *)-32, (void *)95);
+               }
+               if(tot>6) {
+                       but=uiDefIconTextBlockBut(block, tb_makemenu, menu7, ICON_RIGHTARROW_THIN, str7, mval[0]+tb_mainx,mval[1]+tb_mainy-120, dx, 19, "");
+                       uiButSetFlag(but, UI_MAKE_RIGHT);
+                       uiButSetFunc(but, store_main, (void *)-32, (void *)105);
+               }
        }
        
        uiBoundsBlock(block, 2);
        event= uiDoBlocks(&tb_listb, 0);
        
+       /* free all dynamic entries... clumsy! */
        if(groupmenu) MEM_freeN(groupmenu);
        
+       if(node_add_in) MEM_freeN(node_add_in);
+       if(node_add_out) MEM_freeN(node_add_out);
+       if(node_add_op_col) MEM_freeN(node_add_op_col);
+       if(node_add_op_filt) MEM_freeN(node_add_op_filt);
+       if(node_add_op_vec) MEM_freeN(node_add_op_vec);
+       if(node_add_con) MEM_freeN(node_add_con);
+       if(node_add_gen) MEM_freeN(node_add_gen);
+       if(node_add_group) MEM_freeN(node_add_group);
+       
        mywinset(curarea->win);
 }