svn merge ^/trunk/blender -r43554:43564
authorCampbell Barton <ideasman42@gmail.com>
Fri, 20 Jan 2012 15:34:40 +0000 (15:34 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Fri, 20 Jan 2012 15:34:40 +0000 (15:34 +0000)
16 files changed:
build_files/scons/tools/Blender.py
source/blender/blenkernel/intern/key.c
source/blender/blenkernel/intern/node.c
source/blender/blenkernel/intern/text.c
source/blender/editors/include/ED_image.h
source/blender/editors/space_image/image_draw.c
source/blender/editors/space_image/image_ops.c
source/blender/editors/space_node/node_edit.c
source/blender/editors/space_node/node_templates.c
source/blender/editors/space_view3d/view3d_edit.c
source/blender/editors/uvedit/uvedit_smart_stitch.c
source/blender/imbuf/intern/divers.c
source/blender/makesrna/intern/rna_tracking.c
source/blender/nodes/NOD_socket.h
source/blender/nodes/intern/node_common.c
source/blender/nodes/intern/node_socket.c

index e9195fe207de47abf5d3dc466a4d6e87c7ed70a9..f8d9eb8b3e1902124ff653afb9c95584d146bed8 100644 (file)
@@ -272,7 +272,7 @@ def setup_syslibs(lenv):
         syslibs += Split(lenv['BF_PTHREADS_LIB'])
     if lenv['WITH_BF_COLLADA']:
         syslibs.append(lenv['BF_PCRE_LIB'])
-        if lenv['BF_DEBUG']:
+        if lenv['BF_DEBUG'] and (lenv['OURPLATFORM'] != 'linux'):
             syslibs += [colladalib+'_d' for colladalib in Split(lenv['BF_OPENCOLLADA_LIB'])]
         else:
             syslibs += Split(lenv['BF_OPENCOLLADA_LIB'])
index 94868ffee87d95a0031aeb80db20d2615cde0696..670ffd2b7c6888d828b6de5699c825d4cef614c6 100644 (file)
@@ -420,7 +420,7 @@ static int setkeys(float fac, ListBase *lb, KeyBlock *k[], float *t, int cycl)
                        if(k1->next==NULL) k[0]=k1;
                        k1=k1->next;
                }
-               k1= k[1];
+               /* k1= k[1]; */ /* UNUSED */
                t[0]= k[0]->pos;
                t[1]+= dpos;
                t[2]= k[2]->pos + dpos;
index a2d7d9b502cdaaaf6c03e7355d7597852b0625d4..96ee2bd03490a25e699aef83c0a49ee9f72ca2ca 100644 (file)
@@ -159,7 +159,6 @@ void ntreeInitTypes(bNodeTree *ntree)
 
 static bNodeSocket *make_socket(bNodeTree *UNUSED(ntree), int in_out, const char *name, int type)
 {
-       bNodeSocketType *stype= ntreeGetSocketType(type);
        bNodeSocket *sock;
        
        sock= MEM_callocN(sizeof(bNodeSocket), "sock");
@@ -169,8 +168,8 @@ static bNodeSocket *make_socket(bNodeTree *UNUSED(ntree), int in_out, const char
        sock->type= type;
        sock->storage = NULL;
        
-       if (stype->value_structsize > 0)
-               sock->default_value = MEM_callocN(stype->value_structsize, "default socket value");
+       sock->default_value = node_socket_make_default_value(type);
+       node_socket_init_default_value(type, sock->default_value);
        
        return sock;
 }
@@ -216,8 +215,7 @@ void nodeRemoveSocket(bNodeTree *ntree, bNode *node, bNodeSocket *sock)
        BLI_remlink(&node->inputs, sock);
        BLI_remlink(&node->outputs, sock);
        
-       if (sock->default_value)
-               MEM_freeN(sock->default_value);
+       node_socket_free_default_value(sock->type, sock->default_value);
        MEM_freeN(sock);
        
        node->update |= NODE_UPDATE;
@@ -236,13 +234,10 @@ void nodeRemoveAllSockets(bNodeTree *ntree, bNode *node)
        }
        
        for (sock=node->inputs.first; sock; sock=sock->next)
-               if (sock->default_value)
-                       MEM_freeN(sock->default_value);
+               node_socket_free_default_value(sock->type, sock->default_value);
        BLI_freelistN(&node->inputs);
        for (sock=node->outputs.first; sock; sock=sock->next)
-               if (sock->default_value)
-                       MEM_freeN(sock->default_value);
-       
+               node_socket_free_default_value(sock->type, sock->default_value);
        BLI_freelistN(&node->outputs);
        
        node->update |= NODE_UPDATE;
@@ -396,7 +391,8 @@ bNode *nodeCopyNode(struct bNodeTree *ntree, struct bNode *node)
                oldsock->new_sock= sock;
                sock->stack_index= 0;
                
-               sock->default_value = (oldsock->default_value ? MEM_dupallocN(oldsock->default_value) : NULL);
+               sock->default_value = node_socket_make_default_value(oldsock->type);
+               node_socket_copy_default_value(oldsock->type, sock->default_value, oldsock->default_value);
                
                /* XXX some compositor node (e.g. image, render layers) still store
                 * some persistent buffer data here, need to clear this to avoid dangling pointers.
@@ -410,7 +406,8 @@ bNode *nodeCopyNode(struct bNodeTree *ntree, struct bNode *node)
                oldsock->new_sock= sock;
                sock->stack_index= 0;
                
-               sock->default_value = (oldsock->default_value ? MEM_dupallocN(oldsock->default_value) : NULL);
+               sock->default_value = node_socket_make_default_value(oldsock->type);
+               node_socket_copy_default_value(oldsock->type, sock->default_value, oldsock->default_value);
                
                /* XXX some compositor node (e.g. image, render layers) still store
                 * some persistent buffer data here, need to clear this to avoid dangling pointers.
@@ -658,13 +655,15 @@ bNodeTree *ntreeCopyTree(bNodeTree *ntree)
        for(gsock= newtree->inputs.first, oldgsock= ntree->inputs.first; gsock; gsock=gsock->next, oldgsock=oldgsock->next) {
                oldgsock->new_sock= gsock;
                gsock->groupsock = (oldgsock->groupsock ? oldgsock->groupsock->new_sock : NULL);
-               gsock->default_value = (oldgsock->default_value ? MEM_dupallocN(oldgsock->default_value) : NULL);
+               gsock->default_value = node_socket_make_default_value(oldgsock->type);
+               node_socket_copy_default_value(oldgsock->type, gsock->default_value, oldgsock->default_value);
        }
        BLI_duplicatelist(&newtree->outputs, &ntree->outputs);
        for(gsock= newtree->outputs.first, oldgsock= ntree->outputs.first; gsock; gsock=gsock->next, oldgsock=oldgsock->next) {
                oldgsock->new_sock= gsock;
                gsock->groupsock = (oldgsock->groupsock ? oldgsock->groupsock->new_sock : NULL);
-               gsock->default_value = (oldgsock->default_value ? MEM_dupallocN(oldgsock->default_value) : NULL);
+               gsock->default_value = node_socket_make_default_value(oldgsock->type);
+               node_socket_copy_default_value(oldgsock->type, gsock->default_value, oldgsock->default_value);
        }
        
        /* copy links */
@@ -863,14 +862,12 @@ void nodeFreeNode(bNodeTree *ntree, bNode *node)
        
        for (sock=node->inputs.first; sock; sock = nextsock) {
                nextsock = sock->next;
-               if (sock->default_value)
-                       MEM_freeN(sock->default_value);
+               node_socket_free_default_value(sock->type, sock->default_value);
                MEM_freeN(sock);
        }
        for (sock=node->outputs.first; sock; sock = nextsock) {
                nextsock = sock->next;
-               if (sock->default_value)
-                       MEM_freeN(sock->default_value);
+               node_socket_free_default_value(sock->type, sock->default_value);
                MEM_freeN(sock);
        }
 
@@ -924,12 +921,10 @@ void ntreeFreeTree(bNodeTree *ntree)
        }
        
        for (sock=ntree->inputs.first; sock; sock=sock->next)
-               if (sock->default_value)
-                       MEM_freeN(sock->default_value);
+               node_socket_free_default_value(sock->type, sock->default_value);
        BLI_freelistN(&ntree->inputs);
        for (sock=ntree->outputs.first; sock; sock=sock->next)
-               if (sock->default_value)
-                       MEM_freeN(sock->default_value);
+               node_socket_free_default_value(sock->type, sock->default_value);
        BLI_freelistN(&ntree->outputs);
 }
 
index 1fe385dbf81c3a962c642a039694560bd5ecb864..b8f37a90a4d5839d20605d9ec8b8367587a8f8dd 100644 (file)
@@ -1944,6 +1944,10 @@ static unsigned int txt_redo_read_unicode(const char *undo_buf, int *undo_pos, s
                        break;
                case 4: /* 32-bit unicode symbol */
                        unicode= txt_undo_read_uint32(undo_buf, undo_pos);
+               default:
+                       /* should never happen */
+                       BLI_assert(0);
+                       unicode= 0;
        }
        
        return unicode;
index 2058479bed82b70622619594aebf699ffa950b82..05cde05f25cf9d16d2cf272b78964f284aee2821 100644 (file)
@@ -67,8 +67,8 @@ int ED_space_image_show_uvshadow(struct SpaceImage *sima, struct Object *obedit)
 /* UI level image (texture) updating... render calls own stuff (too) */
 void ED_image_update_frame(const struct Main *mainp, int cfra);
 
-void ED_image_draw_info(struct ARegion *ar, int color_manage, int channels,
-                        int x, int y, const char cp[4], const float fp[4], int *zp, float *zpf);
+void ED_image_draw_info(struct ARegion *ar, int color_manage, int channels, int x, int y,
+                        const unsigned char cp[4], const float fp[4], int *zp, float *zpf);
 
 #endif /* ED_IMAGE_H */
 
index 41fc861f8e469ca3a3361aba676efdddb8b26d32..9ec9c5ef0e02c387c93af773508070c3af597092 100644 (file)
@@ -111,7 +111,8 @@ static void draw_render_info(Scene *scene, Image *ima, ARegion *ar)
 }
 
 /* used by node view too */
-void ED_image_draw_info(ARegion *ar, int color_manage, int channels, int x, int y, const char cp[4], const float fp[4], int *zp, float *zpf)
+void ED_image_draw_info(ARegion *ar, int color_manage, int channels, int x, int y,
+                        const unsigned char cp[4], const float fp[4], int *zp, float *zpf)
 {
        char str[256];
        float dx= 6;
@@ -211,39 +212,46 @@ void ED_image_draw_info(ARegion *ar, int color_manage, int channels, int x, int
        
        /* color rectangle */
        if (channels==1) {
-               if (fp)
+               if (fp) {
                        col[0] = col[1] = col[2] = fp[0];
-               else if (cp)
+               }
+               else if (cp) {
                        col[0] = col[1] = col[2] = (float)cp[0]/255.0f;
-               else
+               }
+               else {
                        col[0] = col[1] = col[2] = 0.0f;
+               }
+               col[3] = 1.0f;
        }
        else if (channels==3) {
-               if (fp)
+               if (fp) {
                        copy_v3_v3(col, fp);
+               }
                else if (cp) {
-                       col[0] = (float)cp[0]/255.0f;
-                       col[1] = (float)cp[1]/255.0f;
-                       col[2] = (float)cp[2]/255.0f;
+                       rgb_uchar_to_float(col, cp);
                }
-               else
+               else {
                        zero_v3(col);
+               }
+               col[3] = 1.0f;
        }
        else if (channels==4) {
                if (fp)
                        copy_v4_v4(col, fp);
                else if (cp) {
-                       col[0] = (float)cp[0]/255.0f;
-                       col[1] = (float)cp[1]/255.0f;
-                       col[2] = (float)cp[2]/255.0f;
-                       col[3] = (float)cp[3]/255.0f;
+                       rgba_uchar_to_float(col, cp);
                }
-               else
+               else {
                        zero_v4(col);
+               }
        }
+       else {
+               BLI_assert(0);
+               zero_v4(col);
+       }
+
        if (color_manage) {
-               linearrgb_to_srgb_v3_v3(finalcol, col);
-               finalcol[3] = col[3];
+               linearrgb_to_srgb_v4(finalcol, col);
        }
        else {
                copy_v4_v4(finalcol, col);
index 2a8a5b3452f974ed67e28534489b00db8d8b9206..1ac5ba56145963e24de87f197a6fb74234936dac 100644 (file)
@@ -1780,12 +1780,12 @@ typedef struct ImageSampleInfo {
        int x, y;
        int channels;
 
-       char col[4];
+       unsigned char col[4];
        float colf[4];
        int z;
        float zf;
 
-       char *colp;
+       unsigned char *colp;
        float *colfp;
        int *zp;
        float *zfp;
@@ -1820,7 +1820,7 @@ static void image_sample_apply(bContext *C, wmOperator *op, wmEvent *event)
 
        if(fx>=0.0f && fy>=0.0f && fx<1.0f && fy<1.0f) {
                float *fp;
-               char *cp;
+               unsigned char *cp;
                int x= (int)(fx*ibuf->x), y= (int)(fy*ibuf->y);
 
                CLAMP(x, 0, ibuf->x-1);
@@ -1837,7 +1837,7 @@ static void image_sample_apply(bContext *C, wmOperator *op, wmEvent *event)
                info->zfp= NULL;
                
                if(ibuf->rect) {
-                       cp= (char *)(ibuf->rect + y*ibuf->x + x);
+                       cp= (unsigned char *)(ibuf->rect + y*ibuf->x + x);
 
                        info->col[0]= cp[0];
                        info->col[1]= cp[1];
index 5beac4ea212b3b966fb3f8ffe378d0645e3c0a24..3301f89ab7a9398129c2973f5ec5305937d2a173 100644 (file)
@@ -1334,7 +1334,7 @@ typedef struct ImageSampleInfo {
        int channels;
        int color_manage;
 
-       char col[4];
+       unsigned char col[4];
        float colf[4];
 
        int draw;
index a733d45c20b1f670b13fdc5cc5fe0546a19eb0b9..8d82dd3fb53d951a3200e740487b424d88d0fc0a 100644 (file)
@@ -49,6 +49,8 @@
 
 #include "RNA_access.h"
 
+#include "NOD_socket.h"
+
 #include "WM_api.h"
 #include "WM_types.h"
 
@@ -205,12 +207,9 @@ static void node_socket_add_replace(Main *bmain, bNodeTree *ntree, bNode *node_t
                                                nodeRemLink(ntree, link);
                                        }
 
-                                       if(sock_prev->default_value) {
-                                               if(sock_from->default_value)
-                                                       MEM_freeN(sock_from->default_value);
-
-                                               sock_from->default_value = MEM_dupallocN(sock_prev->default_value);
-                                       }
+                                       node_socket_free_default_value(sock_from->type, sock_from->default_value);
+                                       sock_from->default_value = node_socket_make_default_value(sock_from->type);
+                                       node_socket_copy_default_value(sock_from->type, sock_from->default_value, sock_prev->default_value);
                                }
                        }
                }
index d7d9a62ec295c21c7e12148570cdfe08611f29e0..03dc906a84b0859a35c228adcdf44895a5fd79c1 100644 (file)
@@ -3239,6 +3239,7 @@ static int set_3dcursor_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *eve
                /* re initialize */
                project_int_noclip(ar, fp, mval);
                flip= initgrabz(rv3d, fp[0], fp[1], fp[2]);
+               (void)flip;
        }
 
        if(mval[0]!=IS_CLIPPED) {
index 023d55d053dac8f8ec6a34105c6443544431d6c9..346020464482cb84930f8579eaa17041634a72ca 100644 (file)
@@ -1071,7 +1071,7 @@ static int stitch_init(bContext *C, wmOperator *op)
        ghi = BLI_ghashIterator_new(edgeHash);
        total_edges = 0;
        /* fill the edges with data */
-       for(i = 0; !BLI_ghashIterator_isDone(ghi); BLI_ghashIterator_step(ghi)){
+       for(; !BLI_ghashIterator_isDone(ghi); BLI_ghashIterator_step(ghi)){
                UvEdge *edge = ((UvEdge *)BLI_ghashIterator_getKey(ghi));
                if(edge->flag & STITCH_BOUNDARY){
                        total_edges++;
index 7e086716d3e064bf18001baba1d42e9534d1e1de..a8ca282de66fc8bd99488fc5779908f13c13e837 100644 (file)
@@ -645,15 +645,19 @@ void IMB_convert_profile(ImBuf *ibuf, int profile)
                profile_from = IB_PROFILE_LINEAR_RGB;
        else if(ELEM(ibuf->profile, IB_PROFILE_SRGB, IB_PROFILE_NONE))
                profile_from = IB_PROFILE_SRGB;
-       else
+       else {
                BLI_assert(0);
+               profile_from = IB_PROFILE_SRGB; /* dummy, should never happen */
+       }
 
        if(profile == IB_PROFILE_LINEAR_RGB)
                profile_to = IB_PROFILE_LINEAR_RGB;
        else if(ELEM(profile, IB_PROFILE_SRGB, IB_PROFILE_NONE))
                profile_to = IB_PROFILE_SRGB;
-       else
+       else {
                BLI_assert(0);
+               profile_to = IB_PROFILE_SRGB; /* dummy, should never happen */
+       }
        
        /* do conversion */
        if(ibuf->rect_float) {
index 01f3889d684a0d516c7d47ec6ac2071dd8c1eb39..5573ceccf8f713ededa4eb85d829b477728c50cf 100644 (file)
@@ -1232,7 +1232,7 @@ static void rna_def_trackingObjects(BlenderRNA *brna, PropertyRNA *cprop)
 
        func= RNA_def_function(srna, "remove", "rna_trackingObject_remove");
        RNA_def_function_ui_description(func, "Remove tracking object from this movie clip");
-       parm= RNA_def_pointer(func, "object", "MovieTrackingObject", "", "Motion tracking object to be removed");
+       RNA_def_pointer(func, "object", "MovieTrackingObject", "", "Motion tracking object to be removed");
 
        /* active object */
        prop= RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE);
index 6a6413d508f95daffbff50fb5eee7246701b91d5..fb3946bae6c68a9522e57ac50d2db5b4147d9bcd 100644 (file)
@@ -47,26 +47,19 @@ struct bNodeStack;
 
 void node_socket_type_init(struct bNodeSocketType *types[]);
 
-struct bNodeSocket *nodeAddInputInt(struct bNodeTree *ntree, struct bNode *node, const char *name, PropertySubType subtype, int value, int min, int max);
-struct bNodeSocket *nodeAddOutputInt(struct bNodeTree *ntree, struct bNode *node, const char *name);
-
-struct bNodeSocket *nodeAddInputFloat(struct bNodeTree *ntree, struct bNode *node, const char *name, PropertySubType subtype, float value, float min, float max);
-struct bNodeSocket *nodeAddOutputFloat(struct bNodeTree *ntree, struct bNode *node, const char *name);
-
-struct bNodeSocket *nodeAddInputBoolean(struct bNodeTree *ntree, struct bNode *node, const char *name, char value);
-struct bNodeSocket *nodeAddOutputBoolean(struct bNodeTree *ntree, struct bNode *node, const char *name);
-
-struct bNodeSocket *nodeAddInputVector(struct bNodeTree *ntree, struct bNode *node, const char *name, PropertySubType subtype, float x, float y, float z, float min, float max);
-struct bNodeSocket *nodeAddOutputVector(struct bNodeTree *ntree, struct bNode *node, const char *name);
-
-struct bNodeSocket *nodeAddInputRGBA(struct bNodeTree *ntree, struct bNode *node, const char *name, float r, float g, float b, float a);
-struct bNodeSocket *nodeAddOutputRGBA(struct bNodeTree *ntree, struct bNode *node, const char *name);
-
-struct bNodeSocket *nodeAddInputShader(struct bNodeTree *ntree, struct bNode *node, const char *name);
-struct bNodeSocket *nodeAddOutputShader(struct bNodeTree *ntree, struct bNode *node, const char *name);
-
-struct bNodeSocket *nodeAddInputMesh(struct bNodeTree *ntree, struct bNode *node, const char *name);
-struct bNodeSocket *nodeAddOutputMesh(struct bNodeTree *ntree, struct bNode *node, const char *name);
+void *node_socket_make_default_value(int type);
+void node_socket_free_default_value(int type, void *default_value);
+void node_socket_init_default_value(int type, void *default_value);
+void node_socket_copy_default_value(int type, void *to_default_value, void *from_default_value);
+void node_socket_convert_default_value(int to_type, void *to_default_value, int from_type, void *from_default_value);
+
+void node_socket_set_default_value_int(void *default_value, PropertySubType subtype, int value, int min, int max);
+void node_socket_set_default_value_float(void *default_value, PropertySubType subtype, float value, float min, float max);
+void node_socket_set_default_value_boolean(void *default_value, char value);
+void node_socket_set_default_value_vector(void *default_value, PropertySubType subtype, float x, float y, float z, float min, float max);
+void node_socket_set_default_value_rgba(void *default_value, float r, float g, float b, float a);
+void node_socket_set_default_value_shader(void *default_value);
+void node_socket_set_default_value_mesh(void *default_value);
 
 struct bNodeSocket *node_add_input_from_template(struct bNodeTree *ntree, struct bNode *node, struct bNodeSocketTemplate *stemp);
 struct bNodeSocket *node_add_output_from_template(struct bNodeTree *ntree, struct bNode *node, struct bNodeSocketTemplate *stemp);
index 5a6cebb51ce67d14ca56ab00f53a15fce05904c1..e5571b1961474c073c07a784acee8cf2b5f8a808 100644 (file)
@@ -100,8 +100,8 @@ bNodeSocket *node_group_add_extern_socket(bNodeTree *UNUSED(ntree), ListBase *lb
        sock->groupsock = gsock;
        sock->limit = (in_out==SOCK_IN ? 1 : 0xFFF);
        
-       if (gsock->default_value)
-               sock->default_value = MEM_dupallocN(gsock->default_value);
+       sock->default_value = node_socket_make_default_value(sock->type);
+       node_socket_copy_default_value(sock->type, sock->default_value, gsock->default_value);
        
        if(lb)
                BLI_addtail(lb, sock);
@@ -247,177 +247,6 @@ bNode *node_group_make_from_selected(bNodeTree *ntree)
        return gnode;
 }
 
-/* XXX This is a makeshift function to have useful initial group socket values.
- * In the end this should be implemented by a flexible socket data conversion system,
- * which is yet to be implemented. The idea is that beside default standard conversions,
- * such as int-to-float, it should be possible to quickly select a conversion method or
- * a chain of conversions for each input, whenever there is more than one option.
- * E.g. a vector-to-float conversion could use either of the x/y/z components or
- * the vector length.
- *
- * In the interface this could be implemented by a pseudo-script textbox on linked inputs,
- * with quick selection from a predefined list of conversion options. Some Examples:
- * - vector component 'z' (vector->float):                                             "z"
- * - greyscale color (float->color):                                                   "grey"
- * - color luminance (color->float):                                                   "lum"
- * - matrix column 2 length (matrix->vector->float):                   "col[1].len"
- * - mesh vertex coordinate 'y' (mesh->vertex->vector->float): "vertex.co.y"
- *
- * The actual conversion is then done by a series of conversion functions,
- * which are defined in the socket type structs.
- */
-static void convert_socket_value(bNodeSocket *from, bNodeSocket *to)
-{
-       /* XXX only one of these pointers is valid! just putting them here for convenience */
-       bNodeSocketValueFloat *fromfloat= (bNodeSocketValueFloat*)from->default_value;
-       bNodeSocketValueInt *fromint= (bNodeSocketValueInt*)from->default_value;
-       bNodeSocketValueBoolean *frombool= (bNodeSocketValueBoolean*)from->default_value;
-       bNodeSocketValueVector *fromvector= (bNodeSocketValueVector*)from->default_value;
-       bNodeSocketValueRGBA *fromrgba= (bNodeSocketValueRGBA*)from->default_value;
-
-       bNodeSocketValueFloat *tofloat= (bNodeSocketValueFloat*)to->default_value;
-       bNodeSocketValueInt *toint= (bNodeSocketValueInt*)to->default_value;
-       bNodeSocketValueBoolean *tobool= (bNodeSocketValueBoolean*)to->default_value;
-       bNodeSocketValueVector *tovector= (bNodeSocketValueVector*)to->default_value;
-       bNodeSocketValueRGBA *torgba= (bNodeSocketValueRGBA*)to->default_value;
-
-       switch (from->type) {
-       case SOCK_FLOAT:
-               switch (to->type) {
-               case SOCK_FLOAT:
-                       tofloat->value = fromfloat->value;
-                       break;
-               case SOCK_INT:
-                       toint->value = (int)fromfloat->value;
-                       break;
-               case SOCK_BOOLEAN:
-                       tobool->value = (fromfloat->value > 0.0f);
-                       break;
-               case SOCK_VECTOR:
-                       tovector->value[0] = tovector->value[1] = tovector->value[2] = fromfloat->value;
-                       break;
-               case SOCK_RGBA:
-                       torgba->value[0] = torgba->value[1] = torgba->value[2] = torgba->value[3] = fromfloat->value;
-                       break;
-               }
-               break;
-       case SOCK_INT:
-               switch (to->type) {
-               case SOCK_FLOAT:
-                       tofloat->value = (float)fromint->value;
-                       break;
-               case SOCK_INT:
-                       toint->value = fromint->value;
-                       break;
-               case SOCK_BOOLEAN:
-                       tobool->value = (fromint->value > 0);
-                       break;
-               case SOCK_VECTOR:
-                       tovector->value[0] = tovector->value[1] = tovector->value[2] = (float)fromint->value;
-                       break;
-               case SOCK_RGBA:
-                       torgba->value[0] = torgba->value[1] = torgba->value[2] = torgba->value[3] = (float)fromint->value;
-                       break;
-               }
-               break;
-       case SOCK_BOOLEAN:
-               switch (to->type) {
-               case SOCK_FLOAT:
-                       tofloat->value = (float)frombool->value;
-                       break;
-               case SOCK_INT:
-                       toint->value = (int)frombool->value;
-                       break;
-               case SOCK_BOOLEAN:
-                       tobool->value = frombool->value;
-                       break;
-               case SOCK_VECTOR:
-                       tovector->value[0] = tovector->value[1] = tovector->value[2] = (float)frombool->value;
-                       break;
-               case SOCK_RGBA:
-                       torgba->value[0] = torgba->value[1] = torgba->value[2] = torgba->value[3] = (float)frombool->value;
-                       break;
-               }
-               break;
-       case SOCK_VECTOR:
-               switch (to->type) {
-               case SOCK_FLOAT:
-                       tofloat->value = fromvector->value[0];
-                       break;
-               case SOCK_INT:
-                       toint->value = (int)fromvector->value[0];
-                       break;
-               case SOCK_BOOLEAN:
-                       tobool->value = (fromvector->value[0] > 0.0f);
-                       break;
-               case SOCK_VECTOR:
-                       copy_v3_v3(tovector->value, fromvector->value);
-                       break;
-               case SOCK_RGBA:
-                       copy_v3_v3(torgba->value, fromvector->value);
-                       torgba->value[3] = 1.0f;
-                       break;
-               }
-               break;
-       case SOCK_RGBA:
-               switch (to->type) {
-               case SOCK_FLOAT:
-                       tofloat->value = fromrgba->value[0];
-                       break;
-               case SOCK_INT:
-                       toint->value = (int)fromrgba->value[0];
-                       break;
-               case SOCK_BOOLEAN:
-                       tobool->value = (fromrgba->value[0] > 0.0f);
-                       break;
-               case SOCK_VECTOR:
-                       copy_v3_v3(tovector->value, fromrgba->value);
-                       break;
-               case SOCK_RGBA:
-                       copy_v4_v4(torgba->value, fromrgba->value);
-                       break;
-               }
-               break;
-       }
-}
-
-static void copy_socket_value(bNodeSocket *from, bNodeSocket *to)
-{
-       /* XXX only one of these pointers is valid! just putting them here for convenience */
-       bNodeSocketValueFloat *fromfloat= (bNodeSocketValueFloat*)from->default_value;
-       bNodeSocketValueInt *fromint= (bNodeSocketValueInt*)from->default_value;
-       bNodeSocketValueBoolean *frombool= (bNodeSocketValueBoolean*)from->default_value;
-       bNodeSocketValueVector *fromvector= (bNodeSocketValueVector*)from->default_value;
-       bNodeSocketValueRGBA *fromrgba= (bNodeSocketValueRGBA*)from->default_value;
-
-       bNodeSocketValueFloat *tofloat= (bNodeSocketValueFloat*)to->default_value;
-       bNodeSocketValueInt *toint= (bNodeSocketValueInt*)to->default_value;
-       bNodeSocketValueBoolean *tobool= (bNodeSocketValueBoolean*)to->default_value;
-       bNodeSocketValueVector *tovector= (bNodeSocketValueVector*)to->default_value;
-       bNodeSocketValueRGBA *torgba= (bNodeSocketValueRGBA*)to->default_value;
-
-       if (from->type != to->type)
-               return;
-
-       switch (from->type) {
-       case SOCK_FLOAT:
-               *tofloat = *fromfloat;
-               break;
-       case SOCK_INT:
-               *toint = *fromint;
-               break;
-       case SOCK_BOOLEAN:
-               *tobool = *frombool;
-               break;
-       case SOCK_VECTOR:
-               *tovector = *fromvector;
-               break;
-       case SOCK_RGBA:
-               *torgba = *fromrgba;
-               break;
-       }
-}
-
 /* returns 1 if its OK */
 int node_group_ungroup(bNodeTree *ntree, bNode *gnode)
 {
@@ -489,7 +318,7 @@ int node_group_ungroup(bNodeTree *ntree, bNode *gnode)
                                }
                                else {
                                        /* copy the default input value from the group socket default to the external socket */
-                                       convert_socket_value(gsock, link->tosock);
+                                       node_socket_convert_default_value(link->tosock->type, link->tosock->default_value, gsock->type, gsock->default_value);
                                }
                        }
                }
@@ -517,7 +346,7 @@ int node_group_ungroup(bNodeTree *ntree, bNode *gnode)
                        }
                        else {
                                /* copy the default input value from the group node socket default to the internal socket */
-                               convert_socket_value(insock, link->tosock);
+                               node_socket_convert_default_value(link->tosock->type, link->tosock->default_value, insock->type, insock->default_value);
                                nodeRemLink(wgroup, link);
                        }
                }
@@ -600,7 +429,7 @@ bNodeSocket *node_group_expose_socket(bNodeTree *ngroup, bNodeSocket *sock, int
        bNodeSocket *gsock= node_group_add_socket(ngroup, sock->name, sock->type, in_out);
        
        /* initialize the default value. */
-       copy_socket_value(sock, gsock);
+       node_socket_copy_default_value(gsock->type, gsock->default_value, sock->default_value);
        
        return gsock;
 }
@@ -616,7 +445,7 @@ void node_group_expose_all_sockets(bNodeTree *ngroup)
                                gsock = node_group_add_socket(ngroup, sock->name, sock->type, SOCK_IN);
                                
                                /* initialize the default value. */
-                               copy_socket_value(sock, gsock);
+                               node_socket_copy_default_value(gsock->type, gsock->default_value, sock->default_value);
                                
                                sock->link = nodeAddLink(ngroup, NULL, gsock, node, sock);
                        }
@@ -626,7 +455,7 @@ void node_group_expose_all_sockets(bNodeTree *ngroup)
                                gsock = node_group_add_socket(ngroup, sock->name, sock->type, SOCK_OUT);
                                
                                /* initialize the default value. */
-                               copy_socket_value(sock, gsock);
+                               node_socket_copy_default_value(gsock->type, gsock->default_value, sock->default_value);
                                
                                gsock->link = nodeAddLink(ngroup, node, sock, NULL, gsock);
                        }
@@ -832,11 +661,12 @@ bNodeTemplate node_forloop_template(bNode *node)
 
 void node_forloop_init(bNodeTree *ntree, bNode *node, bNodeTemplate *ntemp)
 {
-       /* bNodeSocket *sock; */ /* UNUSED */
+       bNodeSocket *sock;
        
        node->id = (ID*)ntemp->ngroup;
        
-       /* sock = */ nodeAddInputFloat(ntree, node, "Iterations", PROP_UNSIGNED, 1, 0, 10000);
+       sock = nodeAddSocket(ntree, node, SOCK_IN, "Iterations", SOCK_FLOAT);
+       node_socket_set_default_value_float(sock->default_value, PROP_UNSIGNED, 1, 0, 10000);
        
        /* NB: group socket input/output roles are inverted internally!
         * Group "inputs" work as outputs in links and vice versa.
@@ -938,11 +768,12 @@ void node_loop_update_tree(bNodeTree *ngroup)
 
 void node_whileloop_init(bNodeTree *ntree, bNode *node, bNodeTemplate *ntemp)
 {
-       /* bNodeSocket *sock; */ /* UNUSED */
+       bNodeSocket *sock;
        
        node->id = (ID*)ntemp->ngroup;
        
-       /* sock = */ nodeAddInputFloat(ntree, node, "Condition", PROP_NONE, 1, 0, 1);
+       sock = nodeAddSocket(ntree, node, SOCK_IN, "Condition", SOCK_FLOAT);
+       node_socket_set_default_value_float(sock->default_value, PROP_NONE, 1, 0, 1);
        
        /* max iterations */
        node->custom1 = 10000;
index 9381eff30ddb80aca602d6d57cbc71d1ccc19105..8f468a574a1aeca3dbd453ff64d8212ff12ca2ac 100644 (file)
@@ -29,6 +29,7 @@
  *  \ingroup nodes
  */
 
+#include <limits.h>
 
 #include "DNA_node_types.h"
 
@@ -172,171 +173,310 @@ void node_socket_type_init(bNodeSocketType *types[])
        #undef INIT_TYPE
 }
 
-struct bNodeSocket *nodeAddInputInt(struct bNodeTree *ntree, struct bNode *node, const char *name, PropertySubType subtype,
-                                                                       int value, int min, int max)
+void *node_socket_make_default_value(int type)
 {
-       bNodeSocket *sock= nodeAddSocket(ntree, node, SOCK_IN, name, SOCK_INT);
-       bNodeSocketValueInt *dval= (bNodeSocketValueInt*)sock->default_value;
-       dval->subtype = subtype;
-       dval->value = value;
-       dval->min = min;
-       dval->max = max;
-       return sock;
-}
-struct bNodeSocket *nodeAddOutputInt(struct bNodeTree *ntree, struct bNode *node, const char *name)
-{
-       bNodeSocket *sock= nodeAddSocket(ntree, node, SOCK_OUT, name, SOCK_INT);
-       return sock;
+       /* XXX currently just allocates from stype->structsize.
+        * it might become necessary to do more complex allocations for later types.
+        */
+       bNodeSocketType *stype = ntreeGetSocketType(type);
+       if (stype->value_structsize > 0) {
+               void *default_value = MEM_callocN(stype->value_structsize, "default socket value");
+               return default_value;
+       }
+       else
+               return NULL;
 }
 
-struct bNodeSocket *nodeAddInputFloat(struct bNodeTree *ntree, struct bNode *node, const char *name, PropertySubType subtype,
-                                                                         float value, float min, float max)
-{
-       bNodeSocket *sock= nodeAddSocket(ntree, node, SOCK_IN, name, SOCK_FLOAT);
-       bNodeSocketValueFloat *dval= (bNodeSocketValueFloat*)sock->default_value;
-       dval->subtype = subtype;
-       dval->value = value;
-       dval->min = min;
-       dval->max = max;
-       return sock;
-}
-struct bNodeSocket *nodeAddOutputFloat(struct bNodeTree *ntree, struct bNode *node, const char *name)
+void node_socket_free_default_value(int UNUSED(type), void *default_value)
 {
-       bNodeSocket *sock= nodeAddSocket(ntree, node, SOCK_OUT, name, SOCK_FLOAT);
-       return sock;
+       /* XXX can just free the pointee for all current socket types. */
+       MEM_freeN(default_value);
 }
 
-struct bNodeSocket *nodeAddInputBoolean(struct bNodeTree *ntree, struct bNode *node, const char *name, char value)
-{
-       bNodeSocket *sock= nodeAddSocket(ntree, node, SOCK_IN, name, SOCK_BOOLEAN);
-       bNodeSocketValueBoolean *dval= (bNodeSocketValueBoolean*)sock->default_value;
-       dval->value = value;
-       return sock;
-}
-struct bNodeSocket *nodeAddOutputBoolean(struct bNodeTree *ntree, struct bNode *node, const char *name)
+void node_socket_init_default_value(int type, void *default_value)
 {
-       bNodeSocket *sock= nodeAddSocket(ntree, node, SOCK_OUT, name, SOCK_BOOLEAN);
-       return sock;
+       switch (type) {
+       case SOCK_FLOAT:
+               node_socket_set_default_value_float(default_value, PROP_NONE, 0.0f, -FLT_MAX, FLT_MAX);
+               break;
+       case SOCK_INT:
+               node_socket_set_default_value_int(default_value, PROP_NONE, 0, INT_MIN, INT_MAX);
+               break;
+       case SOCK_BOOLEAN:
+               node_socket_set_default_value_boolean(default_value, FALSE);
+               break;
+       case SOCK_VECTOR:
+               node_socket_set_default_value_vector(default_value, PROP_NONE, 0.0f, 0.0f, 0.0f, -FLT_MAX, FLT_MAX);
+               break;
+       case SOCK_RGBA:
+               node_socket_set_default_value_rgba(default_value, 0.0f, 0.0f, 0.0f, 1.0f);
+               break;
+       case SOCK_SHADER:
+               node_socket_set_default_value_shader(default_value);
+               break;
+       case SOCK_MESH:
+               node_socket_set_default_value_mesh(default_value);
+               break;
+       }
 }
 
-struct bNodeSocket *nodeAddInputVector(struct bNodeTree *ntree, struct bNode *node, const char *name, PropertySubType subtype,
-                                                                          float x, float y, float z, float min, float max)
+void node_socket_set_default_value_int(void *default_value, PropertySubType subtype, int value, int min, int max)
 {
-       bNodeSocket *sock= nodeAddSocket(ntree, node, SOCK_IN, name, SOCK_VECTOR);
-       bNodeSocketValueVector *dval= (bNodeSocketValueVector*)sock->default_value;
-       dval->subtype = subtype;
-       dval->value[0] = x;
-       dval->value[1] = y;
-       dval->value[2] = z;
-       dval->min = min;
-       dval->max = max;
-       return sock;
-}
-struct bNodeSocket *nodeAddOutputVector(struct bNodeTree *ntree, struct bNode *node, const char *name)
-{
-       bNodeSocket *sock= nodeAddSocket(ntree, node, SOCK_OUT, name, SOCK_VECTOR);
-       return sock;
+       bNodeSocketValueInt *val = default_value;
+       val->subtype = subtype;
+       val->value = value;
+       val->min = min;
+       val->max = max;
 }
 
-struct bNodeSocket *nodeAddInputRGBA(struct bNodeTree *ntree, struct bNode *node, const char *name,
-                                                                        float r, float g, float b, float a)
+void node_socket_set_default_value_float(void *default_value, PropertySubType subtype, float value, float min, float max)
 {
-       bNodeSocket *sock= nodeAddSocket(ntree, node, SOCK_IN, name, SOCK_RGBA);
-       bNodeSocketValueRGBA *dval= (bNodeSocketValueRGBA*)sock->default_value;
-       dval->value[0] = r;
-       dval->value[1] = g;
-       dval->value[2] = b;
-       dval->value[3] = a;
-       return sock;
+       bNodeSocketValueFloat *val = default_value;
+       val->subtype = subtype;
+       val->value = value;
+       val->min = min;
+       val->max = max;
 }
-struct bNodeSocket *nodeAddOutputRGBA(struct bNodeTree *ntree, struct bNode *node, const char *name)
+
+void node_socket_set_default_value_boolean(void *default_value, char value)
 {
-       bNodeSocket *sock= nodeAddSocket(ntree, node, SOCK_OUT, name, SOCK_RGBA);
-       return sock;
+       bNodeSocketValueBoolean *val = default_value;
+       val->value = value;
 }
 
-struct bNodeSocket *nodeAddInputShader(struct bNodeTree *ntree, struct bNode *node, const char *name)
+void node_socket_set_default_value_vector(void *default_value, PropertySubType subtype, float x, float y, float z, float min, float max)
 {
-       bNodeSocket *sock= nodeAddSocket(ntree, node, SOCK_IN, name, SOCK_SHADER);
-       return sock;
+       bNodeSocketValueVector *val = default_value;
+       val->subtype = subtype;
+       val->value[0] = x;
+       val->value[1] = y;
+       val->value[2] = z;
+       val->min = min;
+       val->max = max;
 }
-struct bNodeSocket *nodeAddOutputShader(struct bNodeTree *ntree, struct bNode *node, const char *name)
+
+void node_socket_set_default_value_rgba(void *default_value, float r, float g, float b, float a)
 {
-       bNodeSocket *sock= nodeAddSocket(ntree, node, SOCK_OUT, name, SOCK_SHADER);
-       return sock;
+       bNodeSocketValueRGBA *val = default_value;
+       val->value[0] = r;
+       val->value[1] = g;
+       val->value[2] = b;
+       val->value[3] = a;
 }
 
-struct bNodeSocket *nodeAddInputMesh(struct bNodeTree *ntree, struct bNode *node, const char *name)
+void node_socket_set_default_value_shader(void *UNUSED(default_value))
 {
-       bNodeSocket *sock= nodeAddSocket(ntree, node, SOCK_IN, name, SOCK_MESH);
-       return sock;
 }
-struct bNodeSocket *nodeAddOutputMesh(struct bNodeTree *ntree, struct bNode *node, const char *name)
+
+void node_socket_set_default_value_mesh(void *UNUSED(default_value))
 {
-       bNodeSocket *sock= nodeAddSocket(ntree, node, SOCK_OUT, name, SOCK_MESH);
-       return sock;
 }
 
-struct bNodeSocket *node_add_input_from_template(struct bNodeTree *ntree, struct bNode *node, struct bNodeSocketTemplate *stemp)
+
+void node_socket_copy_default_value(int type, void *to_default_value, void *from_default_value)
 {
-       bNodeSocket *sock;
-       switch (stemp->type) {
-       case SOCK_INT:
-               sock = nodeAddInputInt(ntree, node, stemp->name, stemp->subtype, (int)stemp->val1, (int)stemp->min, (int)stemp->max);
-               break;
+       /* XXX only one of these pointers is valid! just putting them here for convenience */
+       bNodeSocketValueFloat *fromfloat= (bNodeSocketValueFloat*)from_default_value;
+       bNodeSocketValueInt *fromint= (bNodeSocketValueInt*)from_default_value;
+       bNodeSocketValueBoolean *frombool= (bNodeSocketValueBoolean*)from_default_value;
+       bNodeSocketValueVector *fromvector= (bNodeSocketValueVector*)from_default_value;
+       bNodeSocketValueRGBA *fromrgba= (bNodeSocketValueRGBA*)from_default_value;
+
+       bNodeSocketValueFloat *tofloat= (bNodeSocketValueFloat*)to_default_value;
+       bNodeSocketValueInt *toint= (bNodeSocketValueInt*)to_default_value;
+       bNodeSocketValueBoolean *tobool= (bNodeSocketValueBoolean*)to_default_value;
+       bNodeSocketValueVector *tovector= (bNodeSocketValueVector*)to_default_value;
+       bNodeSocketValueRGBA *torgba= (bNodeSocketValueRGBA*)to_default_value;
+
+       switch (type) {
        case SOCK_FLOAT:
-               sock = nodeAddInputFloat(ntree, node, stemp->name, stemp->subtype, stemp->val1, stemp->min, stemp->max);
+               *tofloat = *fromfloat;
+               break;
+       case SOCK_INT:
+               *toint = *fromint;
                break;
        case SOCK_BOOLEAN:
-               sock = nodeAddInputBoolean(ntree, node, stemp->name, (char)stemp->val1);
+               *tobool = *frombool;
                break;
        case SOCK_VECTOR:
-               sock = nodeAddInputVector(ntree, node, stemp->name, stemp->subtype, stemp->val1, stemp->val2, stemp->val3, stemp->min, stemp->max);
+               *tovector = *fromvector;
                break;
        case SOCK_RGBA:
-               sock = nodeAddInputRGBA(ntree, node, stemp->name, stemp->val1, stemp->val2, stemp->val3, stemp->val4);
+               *torgba = *fromrgba;
                break;
-       case SOCK_SHADER:
-               sock = nodeAddInputShader(ntree, node, stemp->name);
+       }
+}
+
+/* XXX This is a makeshift function to have useful initial group socket values.
+ * In the end this should be implemented by a flexible socket data conversion system,
+ * which is yet to be implemented. The idea is that beside default standard conversions,
+ * such as int-to-float, it should be possible to quickly select a conversion method or
+ * a chain of conversions for each input, whenever there is more than one option.
+ * E.g. a vector-to-float conversion could use either of the x/y/z components or
+ * the vector length.
+ *
+ * In the interface this could be implemented by a pseudo-script textbox on linked inputs,
+ * with quick selection from a predefined list of conversion options. Some Examples:
+ * - vector component 'z' (vector->float):                                             "z"
+ * - greyscale color (float->color):                                                   "grey"
+ * - color luminance (color->float):                                                   "lum"
+ * - matrix column 2 length (matrix->vector->float):                   "col[1].len"
+ * - mesh vertex coordinate 'y' (mesh->vertex->vector->float): "vertex.co.y"
+ *
+ * The actual conversion is then done by a series of conversion functions,
+ * which are defined in the socket type structs.
+ */
+void node_socket_convert_default_value(int to_type, void *to_default_value, int from_type, void *from_default_value)
+{
+       /* XXX only one of these pointers is valid! just putting them here for convenience */
+       bNodeSocketValueFloat *fromfloat= (bNodeSocketValueFloat*)from_default_value;
+       bNodeSocketValueInt *fromint= (bNodeSocketValueInt*)from_default_value;
+       bNodeSocketValueBoolean *frombool= (bNodeSocketValueBoolean*)from_default_value;
+       bNodeSocketValueVector *fromvector= (bNodeSocketValueVector*)from_default_value;
+       bNodeSocketValueRGBA *fromrgba= (bNodeSocketValueRGBA*)from_default_value;
+
+       bNodeSocketValueFloat *tofloat= (bNodeSocketValueFloat*)to_default_value;
+       bNodeSocketValueInt *toint= (bNodeSocketValueInt*)to_default_value;
+       bNodeSocketValueBoolean *tobool= (bNodeSocketValueBoolean*)to_default_value;
+       bNodeSocketValueVector *tovector= (bNodeSocketValueVector*)to_default_value;
+       bNodeSocketValueRGBA *torgba= (bNodeSocketValueRGBA*)to_default_value;
+
+       switch (from_type) {
+       case SOCK_FLOAT:
+               switch (to_type) {
+               case SOCK_FLOAT:
+                       tofloat->value = fromfloat->value;
+                       break;
+               case SOCK_INT:
+                       toint->value = (int)fromfloat->value;
+                       break;
+               case SOCK_BOOLEAN:
+                       tobool->value = (fromfloat->value > 0.0f);
+                       break;
+               case SOCK_VECTOR:
+                       tovector->value[0] = tovector->value[1] = tovector->value[2] = fromfloat->value;
+                       break;
+               case SOCK_RGBA:
+                       torgba->value[0] = torgba->value[1] = torgba->value[2] = torgba->value[3] = fromfloat->value;
+                       break;
                break;
-       case SOCK_MESH:
-               sock = nodeAddInputMesh(ntree, node, stemp->name);
+               }
+       case SOCK_INT:
+               switch (to_type) {
+               case SOCK_FLOAT:
+                       tofloat->value = (float)fromint->value;
+                       break;
+               case SOCK_INT:
+                       toint->value = fromint->value;
+                       break;
+               case SOCK_BOOLEAN:
+                       tobool->value = (fromint->value > 0);
+                       break;
+               case SOCK_VECTOR:
+                       tovector->value[0] = tovector->value[1] = tovector->value[2] = (float)fromint->value;
+                       break;
+               case SOCK_RGBA:
+                       torgba->value[0] = torgba->value[1] = torgba->value[2] = torgba->value[3] = (float)fromint->value;
+                       break;
+               }
+               break;
+       case SOCK_BOOLEAN:
+               switch (to_type) {
+               case SOCK_FLOAT:
+                       tofloat->value = (float)frombool->value;
+                       break;
+               case SOCK_INT:
+                       toint->value = (int)frombool->value;
+                       break;
+               case SOCK_BOOLEAN:
+                       tobool->value = frombool->value;
+                       break;
+               case SOCK_VECTOR:
+                       tovector->value[0] = tovector->value[1] = tovector->value[2] = (float)frombool->value;
+                       break;
+               case SOCK_RGBA:
+                       torgba->value[0] = torgba->value[1] = torgba->value[2] = torgba->value[3] = (float)frombool->value;
+                       break;
+               }
+               break;
+       case SOCK_VECTOR:
+               switch (to_type) {
+               case SOCK_FLOAT:
+                       tofloat->value = fromvector->value[0];
+                       break;
+               case SOCK_INT:
+                       toint->value = (int)fromvector->value[0];
+                       break;
+               case SOCK_BOOLEAN:
+                       tobool->value = (fromvector->value[0] > 0.0f);
+                       break;
+               case SOCK_VECTOR:
+                       copy_v3_v3(tovector->value, fromvector->value);
+                       break;
+               case SOCK_RGBA:
+                       copy_v3_v3(torgba->value, fromvector->value);
+                       torgba->value[3] = 1.0f;
+                       break;
+               }
+               break;
+       case SOCK_RGBA:
+               switch (to_type) {
+               case SOCK_FLOAT:
+                       tofloat->value = fromrgba->value[0];
+                       break;
+               case SOCK_INT:
+                       toint->value = (int)fromrgba->value[0];
+                       break;
+               case SOCK_BOOLEAN:
+                       tobool->value = (fromrgba->value[0] > 0.0f);
+                       break;
+               case SOCK_VECTOR:
+                       copy_v3_v3(tovector->value, fromrgba->value);
+                       break;
+               case SOCK_RGBA:
+                       copy_v4_v4(torgba->value, fromrgba->value);
+                       break;
+               }
                break;
-       default:
-               sock = nodeAddSocket(ntree, node, SOCK_IN, stemp->name, stemp->type);
        }
-       sock->flag |= stemp->flag;
-       return sock;
 }
 
-struct bNodeSocket *node_add_output_from_template(struct bNodeTree *ntree, struct bNode *node, struct bNodeSocketTemplate *stemp)
+
+struct bNodeSocket *node_add_input_from_template(struct bNodeTree *ntree, struct bNode *node, struct bNodeSocketTemplate *stemp)
 {
-       bNodeSocket *sock;
+       bNodeSocket *sock = nodeAddSocket(ntree, node, SOCK_IN, stemp->name, stemp->type);
+       sock->flag |= stemp->flag;
+       
        switch (stemp->type) {
        case SOCK_INT:
-               sock = nodeAddOutputInt(ntree, node, stemp->name);
+               node_socket_set_default_value_int(sock->default_value, stemp->subtype, (int)stemp->val1, (int)stemp->min, (int)stemp->max);
                break;
        case SOCK_FLOAT:
-               sock = nodeAddOutputFloat(ntree, node, stemp->name);
+               node_socket_set_default_value_float(sock->default_value, stemp->subtype, stemp->val1, stemp->min, stemp->max);
                break;
        case SOCK_BOOLEAN:
-               sock = nodeAddOutputBoolean(ntree, node, stemp->name);
+               node_socket_set_default_value_boolean(sock->default_value, (char)stemp->val1);
                break;
        case SOCK_VECTOR:
-               sock = nodeAddOutputVector(ntree, node, stemp->name);
+               node_socket_set_default_value_vector(sock->default_value, stemp->subtype, stemp->val1, stemp->val2, stemp->val3, stemp->min, stemp->max);
                break;
        case SOCK_RGBA:
-               sock = nodeAddOutputRGBA(ntree, node, stemp->name);
+               node_socket_set_default_value_rgba(sock->default_value, stemp->val1, stemp->val2, stemp->val3, stemp->val4);
                break;
        case SOCK_SHADER:
-               sock = nodeAddOutputShader(ntree, node, stemp->name);
+               node_socket_set_default_value_shader(sock->default_value);
                break;
        case SOCK_MESH:
-               sock = nodeAddOutputMesh(ntree, node, stemp->name);
+               node_socket_set_default_value_mesh(sock->default_value);
                break;
-       default:
-               sock = nodeAddSocket(ntree, node, SOCK_OUT, stemp->name, stemp->type);
        }
+       
+       return sock;
+}
+
+struct bNodeSocket *node_add_output_from_template(struct bNodeTree *ntree, struct bNode *node, struct bNodeSocketTemplate *stemp)
+{
+       bNodeSocket *sock = nodeAddSocket(ntree, node, SOCK_OUT, stemp->name, stemp->type);
        return sock;
 }