diff --git a/source/blender/blenkernel/BKE_blender.h b/source/blender/blenkernel/BKE_blender.h index 0f19cfbc481..742240d53b5 100644 --- a/source/blender/blenkernel/BKE_blender.h +++ b/source/blender/blenkernel/BKE_blender.h @@ -44,7 +44,7 @@ extern "C" { * and keep comment above the defines. * Use STRINGIFY() rather than defining with quotes */ #define BLENDER_VERSION 259 -#define BLENDER_SUBVERSION 1 +#define BLENDER_SUBVERSION 2 #define BLENDER_MINVERSION 250 #define BLENDER_MINSUBVERSION 0 diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h index e44b5d96852..7207fb7d0fb 100644 --- a/source/blender/blenkernel/BKE_node.h +++ b/source/blender/blenkernel/BKE_node.h @@ -37,6 +37,10 @@ * \ingroup bke */ +#include "DNA_listBase.h" + +#include "RNA_types.h" + /* not very important, but the stack solver likes to know a maximum */ #define MAX_SOCKET 64 @@ -46,63 +50,151 @@ struct bNodeLink; struct bNodeSocket; struct bNodeStack; struct bNodeTree; +struct bNodeTreeExec; struct GPUMaterial; struct GPUNode; struct GPUNodeStack; struct ID; struct ListBase; struct Main; +struct uiBlock; +struct uiLayout; struct MTex; struct PointerRNA; struct rctf; struct RenderData; struct Scene; struct Tex; -struct uiLayout; - +struct SpaceNode; +struct ARegion; +struct Object; /* ************** NODE TYPE DEFINITIONS ***** */ -typedef struct bNodeSocketType { +/** Compact definition of a node socket. + * Can be used to quickly define a list of static sockets for a node, + * which are added to each new node of that type. + * + * \deprecated New nodes should add default sockets in the initialization + * function instead. This struct is mostly kept for old nodes and should + * be removed some time. + */ +typedef struct bNodeSocketTemplate { int type, limit; - const char *name; - float val1, val2, val3, val4; /* default alloc value for inputs */ - float min, max; /* default range for inputs */ + char name[32]; + float val1, val2, val3, val4; /* default alloc value for inputs */ + float min, max; + PropertySubType subtype; /* after this line is used internal only */ - struct bNodeSocket *sock; /* used during verify_types */ + struct bNodeSocket *sock; /* used to hold verified socket */ +} bNodeSocketTemplate; + +typedef void (*NodeSocketButtonFunction)(const struct bContext *C, struct uiBlock *block, + struct bNodeTree *ntree, struct bNode *node, struct bNodeSocket *sock, + const char *name, int x, int y, int width); + +/** Defines a socket type. + * Defines the appearance and behavior of a socket in the UI. + */ +typedef struct bNodeSocketType { + int type; + char ui_name[32]; + char ui_description[128]; + int ui_icon; + char ui_color[4]; + + const char *value_structname; + int value_structsize; + + NodeSocketButtonFunction buttonfunc; } bNodeSocketType; +/** Template for creating a node. + * Stored required parameters to make a new node of a specific type. + */ +typedef struct bNodeTemplate { + int type; + + /* group tree */ + struct bNodeTree *ngroup; +} bNodeTemplate; + +/** Defines a node type. + * Initial attributes and constants for a node as well as callback functions + * implementing the node behavior. + */ typedef struct bNodeType { void *next,*prev; + short needs_free; /* set for allocated types that need to be freed */ + int type; - const char *name; /* can be allocated too */ + char name[32]; float width, minwidth, maxwidth; + float height, minheight, maxheight; short nclass, flag; - bNodeSocketType *inputs, *outputs; + /* templates for static sockets */ + bNodeSocketTemplate *inputs, *outputs; char storagename[64]; /* struct name for DNA */ - void (*execfunc)(void *data, struct bNode *, struct bNodeStack **, struct bNodeStack **); - - /* this line is set on startup of blender */ + /// Main draw function for the node. + void (*drawfunc)(const struct bContext *C, struct ARegion *ar, struct SpaceNode *snode, struct bNodeTree *ntree, struct bNode *node); + /// Updates the node geometry attributes according to internal state before actual drawing. + void (*drawupdatefunc)(const struct bContext *C, struct bNodeTree *ntree, struct bNode *node); + /// Draw the option buttons on the node. void (*uifunc)(struct uiLayout *, struct bContext *C, struct PointerRNA *ptr); + /// Additional parameters in the side panel. void (*uifuncbut)(struct uiLayout *, struct bContext *C, struct PointerRNA *ptr); + /// Optional custom label function for the node header. const char *(*labelfunc)(struct bNode *); - - void (*initfunc)(struct bNode *); - void (*freestoragefunc)(struct bNode *); - void (*copystoragefunc)(struct bNode *, struct bNode *); + /// Optional custom resize handle polling. + int (*resize_area_func)(struct bNode *node, int x, int y); - /* for use with dynamic typedefs */ - ID *id; - void *pynode; /* holds pointer to python script */ - void *pydict; /* holds pointer to python script dictionary (scope)*/ - + /// Called when the node is updated in the editor. + void (*updatefunc)(struct bNodeTree *ntree, struct bNode *node); + /// Check and update if internal ID data has changed. + void (*verifyfunc)(struct bNodeTree *ntree, struct bNode *node, struct ID *id); + + /// Initialize a new node instance of this type after creation. + void (*initfunc)(struct bNodeTree *ntree, struct bNode *node, struct bNodeTemplate *ntemp); + /// Free the custom storage data. + void (*freestoragefunc)(struct bNode *node); + /// Make a copy of the custom storage data. + void (*copystoragefunc)(struct bNode *node, struct bNode *target); + + /// Create a template from an existing node. + struct bNodeTemplate (*templatefunc)(struct bNode *); + /** If a node can be made from the template in the given node tree. + * \example Node groups can not be created inside their own node tree. + */ + int (*validfunc)(struct bNodeTree *ntree, struct bNodeTemplate *ntemp); + + /// Initialize a node tree associated to this node type. + void (*inittreefunc)(struct bNodeTree *ntree); + /// Update a node tree associated to this node type. + void (*updatetreefunc)(struct bNodeTree *ntree); + + /* group edit callbacks for operators */ + /* XXX this is going to be changed as required by the UI */ + struct bNodeTree *(*group_edit_get)(struct bNode *node); + struct bNodeTree *(*group_edit_set)(struct bNode *node, int edit); + void (*group_edit_clear)(struct bNode *node); + + + /* **** execution callbacks **** */ + void *(*initexecfunc)(struct bNode *node); + void (*freeexecfunc)(struct bNode *node, void *nodedata); + void (*execfunc)(void *data, struct bNode *, struct bNodeStack **, struct bNodeStack **); + /* XXX this alternative exec function has been added to avoid changing all node types. + * when a final generic version of execution code is defined, this will be changed anyway + */ + void (*newexecfunc)(void *data, int thread, struct bNode *, void *nodedata, struct bNodeStack **, struct bNodeStack **); /* gpu */ int (*gpufunc)(struct GPUMaterial *mat, struct bNode *node, struct GPUNodeStack *in, struct GPUNodeStack *out); - + /* extended gpu function */ + int (*gpuextfunc)(struct GPUMaterial *mat, struct bNode *node, void *nodedata, struct GPUNodeStack *in, struct GPUNodeStack *out); } bNodeType; /* node->exec, now in use for composites (#define for break is same as ready yes) */ @@ -113,72 +205,124 @@ typedef struct bNodeType { #define NODE_FREEBUFS 8 #define NODE_SKIPPED 16 +/* sim_exec return value */ +#define NODE_EXEC_FINISHED 0 +#define NODE_EXEC_SUSPEND 1 + /* nodetype->nclass, for add-menu and themes */ -#define NODE_CLASS_INPUT 0 -#define NODE_CLASS_OUTPUT 1 -#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 -#define NODE_CLASS_MATTE 9 -#define NODE_CLASS_DISTORT 10 -#define NODE_CLASS_OP_DYNAMIC 11 -#define NODE_CLASS_PATTERN 12 -#define NODE_CLASS_TEXTURE 13 +#define NODE_CLASS_INPUT 0 +#define NODE_CLASS_OUTPUT 1 +#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 +#define NODE_CLASS_MATTE 9 +#define NODE_CLASS_DISTORT 10 +#define NODE_CLASS_OP_DYNAMIC 11 +#define NODE_CLASS_PATTERN 12 +#define NODE_CLASS_TEXTURE 13 +#define NODE_CLASS_EXECUTION 14 +#define NODE_CLASS_GETDATA 15 +#define NODE_CLASS_SETDATA 16 +#define NODE_CLASS_MATH 17 +#define NODE_CLASS_MATH_VECTOR 18 +#define NODE_CLASS_MATH_ROTATION 19 +#define NODE_CLASS_PARTICLES 25 +#define NODE_CLASS_TRANSFORM 30 +#define NODE_CLASS_COMBINE 31 +#define NODE_CLASS_LAYOUT 100 /* enum values for input/output */ #define SOCK_IN 1 #define SOCK_OUT 2 +struct bNodeTreeExec; + +typedef void (*bNodeTreeCallback)(void *calldata, struct ID *owner_id, struct bNodeTree *ntree); +typedef struct bNodeTreeType +{ + int type; /* type identifier */ + char idname[64]; /* id name for RNA identification */ + + ListBase node_types; /* type definitions */ + + /* callbacks */ + void (*free_cache)(struct bNodeTree *ntree); + void (*free_node_cache)(struct bNodeTree *ntree, struct bNode *node); + void (*foreach_nodetree)(struct Main *main, void *calldata, bNodeTreeCallback func); /* iteration over all node trees */ + + /* calls allowing threaded composite */ + void (*localize)(struct bNodeTree *localtree, struct bNodeTree *ntree); + void (*local_sync)(struct bNodeTree *localtree, struct bNodeTree *ntree); + void (*local_merge)(struct bNodeTree *localtree, struct bNodeTree *ntree); + + /* Tree update. Overrides nodetype->updatetreefunc! */ + void (*update)(struct bNodeTree *ntree); + /* Node update. Overrides nodetype->updatefunc! */ + void (*update_node)(struct bNodeTree *ntree, struct bNode *node); + + int (*validate_link)(struct bNodeTree *ntree, struct bNodeLink *link); +} bNodeTreeType; + /* ************** GENERIC API, TREES *************** */ -void ntreeVerifyTypes(struct bNodeTree *ntree); +struct bNodeTreeType *ntreeGetType(int type); +struct bNodeType *ntreeGetNodeType(struct bNodeTree *ntree); +struct bNodeSocketType *ntreeGetSocketType(int type); -struct bNodeTree *ntreeAddTree(const char *name, int type, const short is_group); +struct bNodeTree *ntreeAddTree(const char *name, int type, int nodetype); void ntreeInitTypes(struct bNodeTree *ntree); -//void ntreeMakeGroupSockets(struct bNodeTree *ntree); -void ntreeUpdateType(struct bNodeTree *ntree, struct bNodeType *ntype); void ntreeFreeTree(struct bNodeTree *ntree); struct bNodeTree *ntreeCopyTree(struct bNodeTree *ntree); void ntreeSwitchID(struct bNodeTree *ntree, struct ID *sce_from, struct ID *sce_to); void ntreeMakeLocal(struct bNodeTree *ntree); +int ntreeHasType(struct bNodeTree *ntree, int type); void ntreeSocketUseFlags(struct bNodeTree *ntree); -void ntreeSolveOrder(struct bNodeTree *ntree); +void ntreeUpdateTree(struct bNodeTree *ntree); +/* XXX Currently each tree update call does call to ntreeVerifyNodes too. + * Some day this should be replaced by a decent depsgraph automatism! + */ +void ntreeVerifyNodes(struct Main *main, struct ID *id); -void ntreeBeginExecTree(struct bNodeTree *ntree); -void ntreeExecTree(struct bNodeTree *ntree, void *callerdata, int thread); -void ntreeCompositExecTree(struct bNodeTree *ntree, struct RenderData *rd, int do_previews); -void ntreeEndExecTree(struct bNodeTree *ntree); +void ntreeGetDependencyList(struct bNodeTree *ntree, struct bNode ***deplist, int *totnodes); +/* XXX old trees handle output flags automatically based on special output node types and last active selection. + * new tree types have a per-output socket flag to indicate the final output to use explicitly. + */ +void ntreeSetOutput(struct bNodeTree *ntree); void ntreeInitPreview(struct bNodeTree *, int xsize, int ysize); void ntreeClearPreview(struct bNodeTree *ntree); void ntreeFreeCache(struct bNodeTree *ntree); - - /* calls allowing threaded composite */ + +int ntreeNodeExists(struct bNodeTree *ntree, struct bNode *testnode); +int ntreeOutputExists(struct bNode *node, struct bNodeSocket *testsock); struct bNodeTree *ntreeLocalize(struct bNodeTree *ntree); void ntreeLocalSync(struct bNodeTree *localtree, struct bNodeTree *ntree); void ntreeLocalMerge(struct bNodeTree *localtree, struct bNodeTree *ntree); /* ************** GENERIC API, NODES *************** */ -void nodeVerifyType(struct bNodeTree *ntree, struct bNode *node); +struct bNodeSocket *nodeAddSocket(struct bNodeTree *ntree, struct bNode *node, int in_out, const char *name, int type); +struct bNodeSocket *nodeInsertSocket(struct bNodeTree *ntree, struct bNode *node, int in_out, struct bNodeSocket *next_sock, const char *name, int type); +void nodeRemoveSocket(struct bNodeTree *ntree, struct bNode *node, struct bNodeSocket *sock); +void nodeRemoveAllSockets(struct bNodeTree *ntree, struct bNode *node); void nodeAddToPreview(struct bNode *, float *, int, int, int); +struct bNode *nodeAddNode(struct bNodeTree *ntree, struct bNodeTemplate *ntemp); void nodeUnlinkNode(struct bNodeTree *ntree, struct bNode *node); void nodeUniqueName(struct bNodeTree *ntree, struct bNode *node); -void nodeAddSockets(struct bNode *node, struct bNodeType *ntype); -struct bNode *nodeAddNodeType(struct bNodeTree *ntree, int type, struct bNodeTree *ngroup, struct ID *id); -void nodeRegisterType(struct ListBase *typelist, const struct bNodeType *ntype) ; -void nodeUpdateType(struct bNodeTree *ntree, struct bNode* node, struct bNodeType *ntype); + +void nodeRegisterType(struct ListBase *typelist, struct bNodeType *ntype) ; void nodeMakeDynamicType(struct bNode *node); int nodeDynamicUnlinkText(struct ID *txtid); + void nodeFreeNode(struct bNodeTree *ntree, struct bNode *node); struct bNode *nodeCopyNode(struct bNodeTree *ntree, struct bNode *node); @@ -186,6 +330,10 @@ struct bNodeLink *nodeAddLink(struct bNodeTree *ntree, struct bNode *fromnode, s void nodeRemLink(struct bNodeTree *ntree, struct bNodeLink *link); void nodeRemSocketLinks(struct bNodeTree *ntree, struct bNodeSocket *sock); +void nodeSpaceCoords(struct bNode *node, float *locx, float *locy); +void nodeAttachNode(struct bNode *node, struct bNode *parent); +void nodeDetachNode(struct bNode *node); + struct bNode *nodeFindNodebyName(struct bNodeTree *ntree, const char *name); int nodeFindNode(struct bNodeTree *ntree, struct bNodeSocket *sock, struct bNode **nodep, int *sockindex, int *in_out); @@ -202,41 +350,71 @@ void NodeTagChanged(struct bNodeTree *ntree, struct bNode *node); int NodeTagIDChanged(struct bNodeTree *ntree, struct ID *id); void ntreeClearTags(struct bNodeTree *ntree); -/* ************** Groups ****************** */ +void nodeFreePreview(struct bNode *node); -struct bNode *nodeMakeGroupFromSelected(struct bNodeTree *ntree); -int nodeGroupUnGroup(struct bNodeTree *ntree, struct bNode *gnode); +/* ************** NODE TYPE ACCESS *************** */ -void nodeGroupVerify(struct bNodeTree *ngroup); -void nodeGroupSocketUseFlags(struct bNodeTree *ngroup); - -void nodeGroupCopy(struct bNode *gnode); - -struct bNodeSocket *nodeGroupAddSocket(struct bNodeTree *ngroup, const char *name, int type, int in_out); -struct bNodeSocket *nodeGroupExposeSocket(struct bNodeTree *ngroup, struct bNodeSocket *sock, int in_out); -void nodeGroupExposeAllSockets(struct bNodeTree *ngroup); -void nodeGroupRemoveSocket(struct bNodeTree *ngroup, struct bNodeSocket *gsock, int in_out); - -/* ************** COMMON NODES *************** */ +struct bNodeTemplate nodeMakeTemplate(struct bNode *node); +int nodeValid(struct bNodeTree *ntree, struct bNodeTemplate *ntemp); +const char* nodeLabel(struct bNode *node); +struct bNodeTree *nodeGroupEditGet(struct bNode *node); +struct bNodeTree *nodeGroupEditSet(struct bNode *node, int edit); +void nodeGroupEditClear(struct bNode *node); /* Init a new node type struct with default values and callbacks */ -void node_type_base(struct bNodeType *ntype, int type, const char *name, short nclass, short flag, - struct bNodeSocketType *inputs, struct bNodeSocketType *outputs); +void node_type_base(struct bNodeType *ntype, int type, const char *name, short nclass, short flag); +void node_type_socket_templates(struct bNodeType *ntype, struct bNodeSocketTemplate *inputs, struct bNodeSocketTemplate *outputs); void node_type_size(struct bNodeType *ntype, int width, int minwidth, int maxwidth); -void node_type_init(struct bNodeType *ntype, void (*initfunc)(struct bNode *)); +void node_type_init(struct bNodeType *ntype, void (*initfunc)(struct bNodeTree *ntree, struct bNode *node, struct bNodeTemplate *ntemp)); +void node_type_valid(struct bNodeType *ntype, int (*validfunc)(struct bNodeTree *ntree, struct bNodeTemplate *ntemp)); void node_type_storage(struct bNodeType *ntype, const char *storagename, void (*freestoragefunc)(struct bNode *), void (*copystoragefunc)(struct bNode *, struct bNode *)); -void node_type_exec(struct bNodeType *ntype, void (*execfunc)(void *data, struct bNode *, struct bNodeStack **, struct bNodeStack **)); -void node_type_gpu(struct bNodeType *ntype, int (*gpufunc)(struct GPUMaterial *mat, struct bNode *node, struct GPUNodeStack *in, struct GPUNodeStack *out)); void node_type_label(struct bNodeType *ntype, const char *(*labelfunc)(struct bNode *)); +void node_type_template(struct bNodeType *ntype, struct bNodeTemplate (*templatefunc)(struct bNode *)); +void node_type_update(struct bNodeType *ntype, + void (*updatefunc)(struct bNodeTree *ntree, struct bNode *node), + void (*verifyfunc)(struct bNodeTree *ntree, struct bNode *node, struct ID *id)); +void node_type_tree(struct bNodeType *ntype, + void (*inittreefunc)(struct bNodeTree *), + void (*updatetreefunc)(struct bNodeTree *)); +void node_type_group_edit(struct bNodeType *ntype, + struct bNodeTree *(*group_edit_get)(struct bNode *node), + struct bNodeTree *(*group_edit_set)(struct bNode *node, int edit), + void (*group_edit_clear)(struct bNode *node)); + +void node_type_exec(struct bNodeType *ntype, void (*execfunc)(void *data, struct bNode *, struct bNodeStack **, struct bNodeStack **)); +void node_type_exec_new(struct bNodeType *ntype, + void *(*initexecfunc)(struct bNode *node), + void (*freeexecfunc)(struct bNode *node, void *nodedata), + void (*newexecfunc)(void *data, int thread, struct bNode *, void *nodedata, struct bNodeStack **, struct bNodeStack **)); +void node_type_gpu(struct bNodeType *ntype, int (*gpufunc)(struct GPUMaterial *mat, struct bNode *node, struct GPUNodeStack *in, struct GPUNodeStack *out)); +void node_type_gpu_ext(struct bNodeType *ntype, int (*gpuextfunc)(struct GPUMaterial *mat, struct bNode *node, void *nodedata, struct GPUNodeStack *in, struct GPUNodeStack *out)); + +/* ************** COMMON NODES *************** */ #define NODE_GROUP 2 -#define NODE_GROUP_MENU 1000 -#define NODE_DYNAMIC_MENU 4000 +#define NODE_FORLOOP 3 +#define NODE_WHILELOOP 4 +#define NODE_FRAME 5 +#define NODE_GROUP_MENU 10000 +#define NODE_DYNAMIC_MENU 20000 -void register_node_type_group(ListBase *lb); +/* look up a socket on a group node by the internal group socket */ +struct bNodeSocket *node_group_find_input(struct bNode *gnode, struct bNodeSocket *gsock); +struct bNodeSocket *node_group_find_output(struct bNode *gnode, struct bNodeSocket *gsock); + +struct bNodeSocket *node_group_add_socket(struct bNodeTree *ngroup, const char *name, int type, int in_out); +struct bNodeSocket *node_group_expose_socket(struct bNodeTree *ngroup, struct bNodeSocket *sock, int in_out); +void node_group_expose_all_sockets(struct bNodeTree *ngroup); +void node_group_remove_socket(struct bNodeTree *ngroup, struct bNodeSocket *gsock, int in_out); + +struct bNode *node_group_make_from_selected(struct bNodeTree *ntree); +int node_group_ungroup(struct bNodeTree *ntree, struct bNode *gnode); + +/* in node_common.c */ +void register_node_type_frame(ListBase *lb); /* ************** SHADER NODES *************** */ @@ -286,11 +464,10 @@ struct ShadeResult; #define NODE_DYNAMIC_REPARSE 6 /* 64 */ #define NODE_DYNAMIC_SET 15 /* sign */ -/* the type definitions array */ -extern struct ListBase node_all_shaders; - /* API */ +struct bNodeTreeExec *ntreeShaderBeginExecTree(struct bNodeTree *ntree); +void ntreeShaderEndExecTree(struct bNodeTreeExec *exec); void ntreeShaderExecTree(struct bNodeTree *ntree, struct ShadeInput *shi, struct ShadeResult *shr); void ntreeShaderGetTexcoMode(struct bNodeTree *ntree, int osa, short *texco, int *mode); void nodeShaderSynchronizeID(struct bNode *node, int copyto); @@ -415,11 +592,11 @@ void ntreeGPUMaterialNodes(struct bNodeTree *ntree, struct GPUMaterial *mat); #define CMP_SCALE_RENDERPERCENT 3 -/* the type definitions array */ -extern struct ListBase node_all_composit; - /* API */ struct CompBuf; +struct bNodeTreeExec *ntreeCompositBeginExecTree(struct bNodeTree *ntree); +void ntreeCompositEndExecTree(struct bNodeTreeExec *exec); +void ntreeCompositExecTree(struct bNodeTree *ntree, struct RenderData *rd, int do_previews); void ntreeCompositTagRender(struct Scene *sce); int ntreeCompositTagAnimated(struct bNodeTree *ntree); void ntreeCompositTagGenerators(struct bNodeTree *ntree); @@ -459,23 +636,22 @@ struct TexResult; #define TEX_NODE_PROC 500 #define TEX_NODE_PROC_MAX 600 -extern struct ListBase node_all_textures; - /* API */ int ntreeTexTagAnimated(struct bNodeTree *ntree); void ntreeTexSetPreviewFlag(int); -int ntreeTexExecTree(struct bNodeTree *ntree, struct TexResult *target, float *coord, float *dxt, float *dyt, int osatex, short thread, struct Tex *tex, short which_output, int cfra, int preview, struct ShadeInput *shi, struct MTex *mtex); void ntreeTexCheckCyclics(struct bNodeTree *ntree); char* ntreeTexOutputMenu(struct bNodeTree *ntree); +struct bNodeTreeExec *ntreeTexBeginExecTree(struct bNodeTree *ntree); +void ntreeTexEndExecTree(struct bNodeTreeExec *exec); +int ntreeTexExecTree(struct bNodeTree *ntree, struct TexResult *target, float *coord, float *dxt, float *dyt, int osatex, short thread, struct Tex *tex, short which_output, int cfra, int preview, struct ShadeInput *shi, struct MTex *mtex); -/**/ + +/*************************************************/ void init_nodesystem(void); void free_nodesystem(void); -/**/ - void clear_scene_in_nodes(struct Main *bmain, struct Scene *sce); #endif diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c index 29615986191..36631d5af90 100644 --- a/source/blender/blenkernel/intern/material.c +++ b/source/blender/blenkernel/intern/material.c @@ -925,7 +925,8 @@ void init_render_material(Material *mat, int r_mode, float *amb) if(mat->nodetree && mat->use_nodes) { init_render_nodetree(mat->nodetree, mat, r_mode, amb); - ntreeBeginExecTree(mat->nodetree); /* has internal flag to detect it only does it once */ + if (!mat->nodetree->execdata) + mat->nodetree->execdata = ntreeShaderBeginExecTree(mat->nodetree); } } @@ -957,8 +958,10 @@ void init_render_materials(Main *bmain, int r_mode, float *amb) /* only needed for nodes now */ void end_render_material(Material *mat) { - if(mat && mat->nodetree && mat->use_nodes) - ntreeEndExecTree(mat->nodetree); /* has internal flag to detect it only does it once */ + if(mat && mat->nodetree && mat->use_nodes) { + if (mat->nodetree->execdata) + ntreeShaderEndExecTree(mat->nodetree->execdata); + } } void end_render_materials(Main *bmain) diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c index 5f1a6c911bc..6f34383101d 100644 --- a/source/blender/blenkernel/intern/node.c +++ b/source/blender/blenkernel/intern/node.c @@ -46,84 +46,107 @@ #include #include "DNA_anim_types.h" -#include "DNA_action_types.h" #include "DNA_node_types.h" +#include "DNA_scene_types.h" +#include "DNA_action_types.h" + +#include "BLI_string.h" +#include "BLI_math.h" +#include "BLI_listbase.h" +#include "BLI_path_util.h" +#include "BLI_utildefines.h" + +#include "BKE_animsys.h" +#include "BKE_action.h" +#include "BKE_fcurve.h" +#include "BKE_global.h" +#include "BKE_image.h" +#include "BKE_library.h" +#include "BKE_main.h" +#include "BKE_node.h" +#include "BKE_utildefines.h" +#include "BKE_utildefines.h" #include "BLI_listbase.h" #include "RNA_access.h" -#include "BKE_animsys.h" -#include "BKE_action.h" -#include "BKE_fcurve.h" -#include "BKE_node.h" -#include "BKE_utildefines.h" +#include "NOD_socket.h" +#include "NOD_composite.h" +#include "NOD_shader.h" +#include "NOD_texture.h" -#include "PIL_time.h" -#include "CMP_node.h" -#include "intern/CMP_util.h" /* stupid include path... */ - -#include "SHD_node.h" -#include "TEX_node.h" -#include "intern/TEX_util.h" - -#include "GPU_material.h" - -static ListBase empty_list = {NULL, NULL}; -ListBase node_all_composit = {NULL, NULL}; -ListBase node_all_shaders = {NULL, NULL}; -ListBase node_all_textures = {NULL, NULL}; - -/* ************** Type stuff ********** */ - -static bNodeType *node_get_type(bNodeTree *ntree, int type, ID *id) +bNodeTreeType *ntreeGetType(int type) { - bNodeType *ntype = ntree->alltypes.first; + static bNodeTreeType *types[NUM_NTREE_TYPES]; + static int types_init = 1; + if (types_init) { + types[NTREE_SHADER] = &ntreeType_Shader; + types[NTREE_COMPOSIT] = &ntreeType_Composite; + types[NTREE_TEXTURE] = &ntreeType_Texture; + types_init = 0; + } + + if(type >= 0 && type < NUM_NTREE_TYPES) { + return types[type]; + } + else { + return NULL; + } +} + +static bNodeType *node_get_type(bNodeTree *ntree, int type) +{ + bNodeType *ntype = ntreeGetType(ntree->type)->node_types.first; for(; ntype; ntype= ntype->next) - if(ntype->type==type && id==ntype->id ) + if(ntype->type==type) return ntype; return NULL; } +bNodeType *ntreeGetNodeType(bNodeTree *ntree) +{ + return node_get_type(ntree, ntree->nodetype); +} + +bNodeSocketType *ntreeGetSocketType(int type) +{ + static bNodeSocketType *types[NUM_SOCKET_TYPES]= {NULL}; + static int types_init = 1; + + if (types_init) { + node_socket_type_init(types); + types_init= 0; + } + + if(type < NUM_SOCKET_TYPES) { + return types[type]; + } + else { + return NULL; + } +} + void ntreeInitTypes(bNodeTree *ntree) { bNode *node, *next; - if(ntree->type==NTREE_SHADER) - ntree->alltypes= node_all_shaders; - else if(ntree->type==NTREE_COMPOSIT) - ntree->alltypes= node_all_composit; - else if(ntree->type==NTREE_TEXTURE) - ntree->alltypes= node_all_textures; - else { - ntree->alltypes= empty_list; - printf("Error: no type definitions for nodes\n"); - } - for(node= ntree->nodes.first; node; node= next) { next= node->next; + + node->typeinfo= node_get_type(ntree, node->type); + if(node->type==NODE_DYNAMIC) { - bNodeType *stype= NULL; - if(node->id==NULL) { /* empty script node */ - stype= node_get_type(ntree, node->type, NULL); - } else { /* not an empty script node */ - stype= node_get_type(ntree, node->type, node->id); - if(!stype) { - stype= node_get_type(ntree, node->type, NULL); - /* needed info if the pynode script fails now: */ - if (node->id) node->storage= ntree; - } else { - node->custom1= 0; - node->custom1= BSET(node->custom1,NODE_DYNAMIC_ADDEXIST); - } + /* needed info if the pynode script fails now: */ + node->storage= ntree; + if(node->id!=NULL) { /* not an empty script node */ + node->custom1= 0; + node->custom1= BSET(node->custom1,NODE_DYNAMIC_ADDEXIST); } - node->typeinfo= stype; - if(node->typeinfo) - node->typeinfo->initfunc(node); - } else { - node->typeinfo= node_get_type(ntree, node->type, NULL); +// if(node->typeinfo) +// node->typeinfo->initfunc(node); } if(node->typeinfo==NULL) { @@ -135,66 +158,51 @@ void ntreeInitTypes(bNodeTree *ntree) ntree->init |= NTREE_TYPE_INIT; } -/* updates node with (modified) bNodeType.. this should be done for all trees */ -void ntreeUpdateType(bNodeTree *ntree, bNodeType *ntype) +static bNodeSocket *make_socket(bNodeTree *ntree, int in_out, const char *name, int type) { - bNode *node; - - for(node= ntree->nodes.first; node; node= node->next) { - if(node->typeinfo== ntype) { - nodeUpdateType(ntree, node, ntype); - } - } -} - -/* only used internal... we depend on type definitions! */ -static bNodeSocket *node_add_socket_type(ListBase *lb, bNodeSocketType *stype) -{ - bNodeSocket *sock= MEM_callocN(sizeof(bNodeSocket), "sock"); + bNodeSocketType *stype= ntreeGetSocketType(type); + bNodeSocket *sock; - BLI_strncpy(sock->name, stype->name, NODE_MAXSTR); - if(stype->limit==0) sock->limit= 0xFFF; - else sock->limit= stype->limit; - sock->type= stype->type; + sock= MEM_callocN(sizeof(bNodeSocket), "sock"); - sock->ns.vec[0]= stype->val1; - sock->ns.vec[1]= stype->val2; - sock->ns.vec[2]= stype->val3; - sock->ns.vec[3]= stype->val4; - sock->ns.min= stype->min; - sock->ns.max= stype->max; + BLI_strncpy(sock->name, name, NODE_MAXSTR); + sock->limit = (in_out==SOCK_IN ? 1 : 0xFFF); + sock->type= type; + sock->storage = NULL; + + if (stype->value_structsize > 0) + sock->default_value = MEM_callocN(stype->value_structsize, "default socket value"); - if(lb) - BLI_addtail(lb, sock); - return sock; } -static bNodeSocket *node_add_group_socket(ListBase *lb, bNodeSocket *gsock) +bNodeSocket *nodeAddSocket(bNodeTree *ntree, bNode *node, int in_out, const char *name, int type) { - bNodeSocket *sock= MEM_callocN(sizeof(bNodeSocket), "sock"); + bNodeSocket *sock = make_socket(ntree, in_out, name, type); + if (in_out==SOCK_IN) + BLI_addtail(&node->inputs, sock); + else if (in_out==SOCK_OUT) + BLI_addtail(&node->outputs, sock); - /* make a copy of the group socket */ - *sock = *gsock; - sock->link = NULL; - sock->next = sock->prev = NULL; - sock->new_sock = NULL; - sock->ns.data = NULL; + ntree->update |= NTREE_UPDATE_NODES; - sock->own_index = gsock->own_index; - sock->groupsock = gsock; - /* XXX hack: group socket input/output roles are inverted internally, - * need to change the limit value when making actual node sockets from them. - */ - sock->limit = (gsock->limit==1 ? 0xFFF : 1); - - if(lb) - BLI_addtail(lb, sock); - return sock; } -static void node_rem_socket(bNodeTree *ntree, ListBase *lb, bNodeSocket *sock) +bNodeSocket *nodeInsertSocket(bNodeTree *ntree, bNode *node, int in_out, bNodeSocket *next_sock, const char *name, int type) +{ + bNodeSocket *sock = make_socket(ntree, in_out, name, type); + if (in_out==SOCK_IN) + BLI_insertlinkbefore(&node->inputs, next_sock, sock); + else if (in_out==SOCK_OUT) + BLI_insertlinkbefore(&node->outputs, next_sock, sock); + + ntree->update |= NTREE_UPDATE_NODES; + + return sock; +} + +void nodeRemoveSocket(bNodeTree *ntree, bNode *node, bNodeSocket *sock) { bNodeLink *link, *next; @@ -205,428 +213,42 @@ static void node_rem_socket(bNodeTree *ntree, ListBase *lb, bNodeSocket *sock) } } - BLI_remlink(lb, sock); + /* this is fast, this way we don't need an in_out argument */ + BLI_remlink(&node->inputs, sock); + BLI_remlink(&node->outputs, sock); + + if (sock->default_value) + MEM_freeN(sock->default_value); MEM_freeN(sock); + + ntree->update |= NTREE_UPDATE_NODES; } -static bNodeSocket *verify_socket(ListBase *lb, bNodeSocketType *stype) +void nodeRemoveAllSockets(bNodeTree *ntree, bNode *node) { bNodeSocket *sock; + bNodeLink *link, *next; - for(sock= lb->first; sock; sock= sock->next) { - if(strncmp(sock->name, stype->name, NODE_MAXSTR)==0) - break; - } - if(sock) { - sock->type= stype->type; /* in future, read this from tydefs! */ - if(stype->limit==0) sock->limit= 0xFFF; - else sock->limit= stype->limit; - - sock->ns.min= stype->min; - sock->ns.max= stype->max; - - BLI_remlink(lb, sock); - - return sock; - } - else { - return node_add_socket_type(NULL, stype); + for(link= ntree->links.first; link; link= next) { + next= link->next; + if(link->fromnode==node || link->tonode==node) { + nodeRemLink(ntree, link); + } } + + for (sock=node->inputs.first; sock; sock=sock->next) + if (sock->default_value) + MEM_freeN(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); + + BLI_freelistN(&node->outputs); + + ntree->update |= NTREE_UPDATE_NODES; } -static bNodeSocket *verify_group_socket(ListBase *lb, bNodeSocket *gsock) -{ - bNodeSocket *sock; - - for(sock= lb->first; sock; sock= sock->next) { - if(sock->own_index==gsock->own_index) - break; - } - if(sock) { - sock->groupsock = gsock; - - strcpy(sock->name, gsock->name); - sock->type= gsock->type; - - /* XXX hack: group socket input/output roles are inverted internally, - * need to change the limit value when making actual node sockets from them. - */ - sock->limit = (gsock->limit==1 ? 0xFFF : 1); - - sock->ns.min= gsock->ns.min; - sock->ns.max= gsock->ns.max; - - BLI_remlink(lb, sock); - - return sock; - } - else { - return node_add_group_socket(NULL, gsock); - } -} - -static void verify_socket_list(bNodeTree *ntree, ListBase *lb, bNodeSocketType *stype_first) -{ - bNodeSocketType *stype; - - /* no inputs anymore? */ - if(stype_first==NULL) { - while(lb->first) - node_rem_socket(ntree, lb, lb->first); - } - else { - /* step by step compare */ - stype= stype_first; - while(stype->type != -1) { - stype->sock= verify_socket(lb, stype); - stype++; - } - /* leftovers are removed */ - while(lb->first) - node_rem_socket(ntree, lb, lb->first); - /* and we put back the verified sockets */ - stype= stype_first; - while(stype->type != -1) { - BLI_addtail(lb, stype->sock); - stype++; - } - } -} - -static void verify_group_socket_list(bNodeTree *ntree, ListBase *lb, ListBase *glb) -{ - bNodeSocket *gsock; - - /* step by step compare */ - for (gsock= glb->first; gsock; gsock=gsock->next) { - /* abusing new_sock pointer for verification here! only used inside this function */ - gsock->new_sock= verify_group_socket(lb, gsock); - } - /* leftovers are removed */ - while(lb->first) - node_rem_socket(ntree, lb, lb->first); - /* and we put back the verified sockets */ - for (gsock= glb->first; gsock; gsock=gsock->next) { - BLI_addtail(lb, gsock->new_sock); - gsock->new_sock = NULL; - } -} - -void nodeVerifyType(bNodeTree *ntree, bNode *node) -{ - /* node groups don't have static sock lists, but use external sockets from the tree instead */ - if (node->type==NODE_GROUP) { - bNodeTree *ngroup= (bNodeTree*)node->id; - if (ngroup) { - verify_group_socket_list(ntree, &node->inputs, &ngroup->inputs); - verify_group_socket_list(ntree, &node->outputs, &ngroup->outputs); - } - } - else { - bNodeType *ntype= node->typeinfo; - if(ntype) { - verify_socket_list(ntree, &node->inputs, ntype->inputs); - verify_socket_list(ntree, &node->outputs, ntype->outputs); - } - } -} - -void ntreeVerifyTypes(bNodeTree *ntree) -{ - bNode *node; - - /* if((ntree->init & NTREE_TYPE_INIT)==0) */ - ntreeInitTypes(ntree); - - /* check inputs and outputs, and remove or insert them */ - for(node= ntree->nodes.first; node; node= node->next) - nodeVerifyType(ntree, node); - -} - -/* ************** Group stuff ********** */ - -/* XXX group typeinfo struct is used directly in ntreeMakeOwnType, needs cleanup */ -static bNodeType ntype_group; - -/* groups display their internal tree name as label */ -static const char *group_label(bNode *node) -{ - return (node->id)? node->id->name+2: "Missing Datablock"; -} - -void register_node_type_group(ListBase *lb) -{ - node_type_base(&ntype_group, NODE_GROUP, "Group", NODE_CLASS_GROUP, NODE_OPTIONS, NULL, NULL); - node_type_size(&ntype_group, 120, 60, 200); - node_type_label(&ntype_group, group_label); - - nodeRegisterType(lb, &ntype_group); -} - -static bNodeSocket *find_group_node_input(bNode *gnode, bNodeSocket *gsock) -{ - bNodeSocket *sock; - for (sock=gnode->inputs.first; sock; sock=sock->next) - if (sock->groupsock == gsock) - return sock; - return NULL; -} - -static bNodeSocket *find_group_node_output(bNode *gnode, bNodeSocket *gsock) -{ - bNodeSocket *sock; - for (sock=gnode->outputs.first; sock; sock=sock->next) - if (sock->groupsock == gsock) - return sock; - return NULL; -} - -bNode *nodeMakeGroupFromSelected(bNodeTree *ntree) -{ - bNodeLink *link, *linkn; - bNode *node, *gnode, *nextn; - bNodeTree *ngroup; - bNodeSocket *gsock; - ListBase anim_basepaths = {NULL, NULL}; - float min[2], max[2]; - int totnode=0; - - INIT_MINMAX2(min, max); - - /* is there something to group? also do some clearing */ - for(node= ntree->nodes.first; node; node= node->next) { - if(node->flag & NODE_SELECT) { - /* no groups in groups */ - if(node->type==NODE_GROUP) - return NULL; - DO_MINMAX2( (&node->locx), min, max); - totnode++; - } - node->done= 0; - } - if(totnode==0) return NULL; - - /* check if all connections are OK, no unselected node has both - inputs and outputs to a selection */ - for(link= ntree->links.first; link; link= link->next) { - if(link->fromnode && link->tonode && link->fromnode->flag & NODE_SELECT) - link->tonode->done |= 1; - if(link->fromnode && link->tonode && link->tonode->flag & NODE_SELECT) - link->fromnode->done |= 2; - } - - for(node= ntree->nodes.first; node; node= node->next) { - if((node->flag & NODE_SELECT)==0) - if(node->done==3) - break; - } - if(node) - return NULL; - - /* OK! new nodetree */ - ngroup= ntreeAddTree("NodeGroup", ntree->type, TRUE); - - /* move nodes over */ - for(node= ntree->nodes.first; node; node= nextn) { - nextn= node->next; - if(node->flag & NODE_SELECT) { - /* keep track of this node's RNA "base" path (the part of the pat identifying the node) - * if the old nodetree has animation data which potentially covers this node - */ - if (ntree->adt) { - PointerRNA ptr; - char *path; - - RNA_pointer_create(&ntree->id, &RNA_Node, node, &ptr); - path = RNA_path_from_ID_to_struct(&ptr); - - if (path) - BLI_addtail(&anim_basepaths, BLI_genericNodeN(path)); - } - - /* change node-collection membership */ - BLI_remlink(&ntree->nodes, node); - BLI_addtail(&ngroup->nodes, node); - - node->locx-= 0.5f*(min[0]+max[0]); - node->locy-= 0.5f*(min[1]+max[1]); - } - } - - /* move animation data over */ - if (ntree->adt) { - LinkData *ld, *ldn=NULL; - - BKE_animdata_separate_by_basepath(&ntree->id, &ngroup->id, &anim_basepaths); - - /* paths + their wrappers need to be freed */ - for (ld = anim_basepaths.first; ld; ld = ldn) { - ldn = ld->next; - - MEM_freeN(ld->data); - BLI_freelinkN(&anim_basepaths, ld); - } - } - - /* make group node */ - gnode= nodeAddNodeType(ntree, NODE_GROUP, ngroup, NULL); - gnode->locx= 0.5f*(min[0]+max[0]); - gnode->locy= 0.5f*(min[1]+max[1]); - - /* relink external sockets */ - for(link= ntree->links.first; link; link= linkn) { - linkn= link->next; - - if(link->fromnode && link->tonode && (link->fromnode->flag & link->tonode->flag & NODE_SELECT)) { - BLI_remlink(&ntree->links, link); - BLI_addtail(&ngroup->links, link); - } - else if(link->tonode && (link->tonode->flag & NODE_SELECT)) { - gsock = nodeGroupExposeSocket(ngroup, link->tosock, SOCK_IN); - link->tosock->link = nodeAddLink(ngroup, NULL, gsock, link->tonode, link->tosock); - link->tosock = node_add_group_socket(&gnode->inputs, gsock); - link->tonode = gnode; - } - else if(link->fromnode && (link->fromnode->flag & NODE_SELECT)) { - /* search for existing group node socket */ - for (gsock=ngroup->outputs.first; gsock; gsock=gsock->next) - if (gsock->link && gsock->link->fromsock==link->fromsock) - break; - if (!gsock) { - gsock = nodeGroupExposeSocket(ngroup, link->fromsock, SOCK_OUT); - gsock->link = nodeAddLink(ngroup, link->fromnode, link->fromsock, NULL, gsock); - link->fromsock = node_add_group_socket(&gnode->outputs, gsock); - } - else - link->fromsock = find_group_node_output(gnode, gsock); - link->fromnode = gnode; - } - } - - /* update node levels */ - ntreeSolveOrder(ntree); - - return gnode; -} - -/* here's a nasty little one, need to check users... */ -/* should become callbackable... */ -void nodeGroupVerify(bNodeTree *ngroup) -{ - /* group changed, so we rebuild the type definition */ -// ntreeMakeGroupSockets(ngroup); - - if(ngroup->type==NTREE_SHADER) { - Material *ma; - for(ma= G.main->mat.first; ma; ma= ma->id.next) { - if(ma->nodetree) { - bNode *node; - for(node= ma->nodetree->nodes.first; node; node= node->next) - if(node->id == (ID *)ngroup) - nodeVerifyType(ma->nodetree, node); - } - } - } - else if(ngroup->type==NTREE_COMPOSIT) { - Scene *sce; - for(sce= G.main->scene.first; sce; sce= sce->id.next) { - if(sce->nodetree) { - bNode *node; - for(node= sce->nodetree->nodes.first; node; node= node->next) - if(node->id == (ID *)ngroup) - nodeVerifyType(sce->nodetree, node); - } - } - } - else if(ngroup->type==NTREE_TEXTURE) { - Tex *tx; - for(tx= G.main->tex.first; tx; tx= tx->id.next) { - if(tx->nodetree) { - bNode *node; - for(node= tx->nodetree->nodes.first; node; node= node->next) - if(node->id == (ID *)ngroup) - nodeVerifyType(tx->nodetree, node); - } - } - } -} - -/* also to check all users of groups. Now only used in editor for hide/unhide */ -/* should become callbackable? */ -void nodeGroupSocketUseFlags(bNodeTree *ngroup) -{ - bNode *node; - bNodeSocket *sock; - - /* clear flags */ - for(node= ngroup->nodes.first; node; node= node->next) { - for(sock= node->inputs.first; sock; sock= sock->next) - sock->flag &= ~SOCK_IN_USE; - for(sock= node->outputs.first; sock; sock= sock->next) - sock->flag &= ~SOCK_IN_USE; - } - - /* tag all thats in use */ - if(ngroup->type==NTREE_SHADER) { - Material *ma; - for(ma= G.main->mat.first; ma; ma= ma->id.next) { - if(ma->nodetree) { - for(node= ma->nodetree->nodes.first; node; node= node->next) { - if(node->id==&ngroup->id) { - for(sock= node->inputs.first; sock; sock= sock->next) - if(sock->link) - if(sock->groupsock) - sock->groupsock->flag |= SOCK_IN_USE; - for(sock= node->outputs.first; sock; sock= sock->next) - if(nodeCountSocketLinks(ma->nodetree, sock)) - if(sock->groupsock) - sock->groupsock->flag |= SOCK_IN_USE; - } - } - } - } - } - else if(ngroup->type==NTREE_COMPOSIT) { - Scene *sce; - for(sce= G.main->scene.first; sce; sce= sce->id.next) { - if(sce->nodetree) { - for(node= sce->nodetree->nodes.first; node; node= node->next) { - if(node->id==(ID *)ngroup) { - for(sock= node->inputs.first; sock; sock= sock->next) - if(sock->link) - if(sock->groupsock) - sock->groupsock->flag |= SOCK_IN_USE; - for(sock= node->outputs.first; sock; sock= sock->next) - if(nodeCountSocketLinks(sce->nodetree, sock)) - if(sock->groupsock) - sock->groupsock->flag |= SOCK_IN_USE; - } - } - } - } - } - else if(ngroup->type==NTREE_TEXTURE) { - Tex *tx; - for(tx= G.main->tex.first; tx; tx= tx->id.next) { - if(tx->nodetree) { - for(node= tx->nodetree->nodes.first; node; node= node->next) { - if(node->id==(ID *)ngroup) { - for(sock= node->inputs.first; sock; sock= sock->next) - if(sock->link) - if(sock->groupsock) - sock->groupsock->flag |= SOCK_IN_USE; - for(sock= node->outputs.first; sock; sock= sock->next) - if(nodeCountSocketLinks(tx->nodetree, sock)) - if(sock->groupsock) - sock->groupsock->flag |= SOCK_IN_USE; - } - } - } - } - } - -} /* finds a node based on its name */ bNode *nodeFindNodebyName(bNodeTree *ntree, const char *name) { @@ -669,272 +291,26 @@ int nodeFindNode(bNodeTree *ntree, bNodeSocket *sock, bNode **nodep, int *sockin return 0; } -/* returns 1 if its OK */ -int nodeGroupUnGroup(bNodeTree *ntree, bNode *gnode) -{ - bNodeLink *link, *linkn; - bNode *node, *nextn; - bNodeTree *ngroup, *wgroup; - ListBase anim_basepaths = {NULL, NULL}; - - ngroup= (bNodeTree *)gnode->id; - if(ngroup==NULL) return 0; - - /* clear new pointers, set in copytree */ - for(node= ntree->nodes.first; node; node= node->next) - node->new_node= NULL; - - /* wgroup is a temporary copy of the NodeTree we're merging in - * - all of wgroup's nodes are transferred across to their new home - * - ngroup (i.e. the source NodeTree) is left unscathed - */ - wgroup= ntreeCopyTree(ngroup); - - /* add the nodes into the ntree */ - for(node= wgroup->nodes.first; node; node= nextn) { - nextn= node->next; - - /* keep track of this node's RNA "base" path (the part of the pat identifying the node) - * if the old nodetree has animation data which potentially covers this node - */ - if (wgroup->adt) { - PointerRNA ptr; - char *path; - - RNA_pointer_create(&wgroup->id, &RNA_Node, node, &ptr); - path = RNA_path_from_ID_to_struct(&ptr); - - if (path) - BLI_addtail(&anim_basepaths, BLI_genericNodeN(path)); - } - - /* migrate node */ - BLI_remlink(&wgroup->nodes, node); - BLI_addtail(&ntree->nodes, node); - - node->locx+= gnode->locx; - node->locy+= gnode->locy; - - node->flag |= NODE_SELECT; - } - - /* restore external links to and from the gnode */ - for(link= ntree->links.first; link; link= link->next) { - if (link->fromnode==gnode) { - if (link->fromsock->groupsock) { - bNodeSocket *gsock= link->fromsock->groupsock; - if (gsock->link) { - if (gsock->link->fromnode) { - /* NB: using the new internal copies here! the groupsock pointer still maps to the old tree */ - link->fromnode = (gsock->link->fromnode ? gsock->link->fromnode->new_node : NULL); - link->fromsock = gsock->link->fromsock->new_sock; - } - else { - /* group output directly maps to group input */ - bNodeSocket *insock= find_group_node_input(gnode, gsock->link->fromsock); - if (insock->link) { - link->fromnode = insock->link->fromnode; - link->fromsock = insock->link->fromsock; - } - } - } - else { - /* constant group output: copy the stack value to the external socket. - * the link is kept here until all possible external users have been fixed. - */ - QUATCOPY(link->tosock->ns.vec, gsock->ns.vec); - } - } - } - } - /* remove internal output links, these are not used anymore */ - for(link=wgroup->links.first; link; link= linkn) { - linkn = link->next; - if (!link->tonode) - nodeRemLink(wgroup, link); - } - /* restore links from internal nodes */ - for(link= wgroup->links.first; link; link= link->next) { - /* indicates link to group input */ - if (!link->fromnode) { - /* NB: can't use find_group_node_input here, - * because gnode sockets still point to the old tree! - */ - bNodeSocket *insock; - for (insock= gnode->inputs.first; insock; insock= insock->next) - if (insock->groupsock->new_sock == link->fromsock) - break; - if (insock->link) { - link->fromnode = insock->link->fromnode; - link->fromsock = insock->link->fromsock; - } - else { - /* uses group constant input. copy the input value and remove the dead link. */ - QUATCOPY(link->tosock->ns.vec, insock->ns.vec); - nodeRemLink(wgroup, link); - } - } - } - - /* add internal links to the ntree */ - for(link= wgroup->links.first; link; link= linkn) { - linkn= link->next; - BLI_remlink(&wgroup->links, link); - BLI_addtail(&ntree->links, link); - } - - /* and copy across the animation */ - if (wgroup->adt) { - LinkData *ld, *ldn=NULL; - bAction *waction; - - /* firstly, wgroup needs to temporary dummy action that can be destroyed, as it shares copies */ - waction = wgroup->adt->action = copy_action(wgroup->adt->action); - - /* now perform the moving */ - BKE_animdata_separate_by_basepath(&wgroup->id, &ntree->id, &anim_basepaths); - - /* paths + their wrappers need to be freed */ - for (ld = anim_basepaths.first; ld; ld = ldn) { - ldn = ld->next; - - MEM_freeN(ld->data); - BLI_freelinkN(&anim_basepaths, ld); - } - - /* free temp action too */ - free_libblock(&G.main->action, waction); - } - - /* delete the group instance. this also removes old input links! */ - nodeFreeNode(ntree, gnode); - - /* free the group tree (takes care of user count) */ - free_libblock(&G.main->nodetree, wgroup); - - /* solve order goes fine, but the level tags not... doing it twice works for now. solve this once */ - /* XXX is this still necessary with new groups? it may have been caused by non-updated sock->link pointers. lukas */ - ntreeSolveOrder(ntree); - ntreeSolveOrder(ntree); - - return 1; -} - -void nodeGroupCopy(bNode *gnode) +/* ************** Add stuff ********** */ +static void node_add_sockets_from_type(bNodeTree *ntree, bNode *node, bNodeType *ntype) { + bNodeSocketTemplate *sockdef; bNodeSocket *sock; - gnode->id->us--; - gnode->id= (ID *)ntreeCopyTree((bNodeTree *)gnode->id); - - /* new_sock was set in nodeCopyNode */ - for(sock=gnode->inputs.first; sock; sock=sock->next) - if(sock->groupsock) - sock->groupsock= sock->groupsock->new_sock; - - for(sock=gnode->outputs.first; sock; sock=sock->next) - if(sock->groupsock) - sock->groupsock= sock->groupsock->new_sock; -} - -bNodeSocket *nodeGroupAddSocket(bNodeTree *ngroup, const char *name, int type, int in_out) -{ - bNodeSocket *gsock = MEM_callocN(sizeof(bNodeSocket), "bNodeSocket"); - - strncpy(gsock->name, name, sizeof(gsock->name)); - gsock->type = type; - gsock->ns.sockettype = type; - gsock->ns.min = INT_MIN; - gsock->ns.max = INT_MAX; - zero_v4(gsock->ns.vec); - gsock->ns.data = NULL; - gsock->flag = 0; - - gsock->next = gsock->prev = NULL; - gsock->new_sock = NULL; - gsock->link = NULL; - gsock->ns.data = NULL; - /* assign new unique index */ - gsock->own_index = ngroup->cur_index++; - gsock->limit = (in_out==SOCK_IN ? 0xFFF : 1); - - BLI_addtail(in_out==SOCK_IN ? &ngroup->inputs : &ngroup->outputs, gsock); - - return gsock; -} - -bNodeSocket *nodeGroupExposeSocket(bNodeTree *ngroup, bNodeSocket *sock, int in_out) -{ - bNodeSocket *gsock= nodeGroupAddSocket(ngroup, sock->name, sock->type, in_out); - /* initialize the default socket value */ - QUATCOPY(gsock->ns.vec, sock->ns.vec); - return gsock; -} - -void nodeGroupExposeAllSockets(bNodeTree *ngroup) -{ - bNode *node; - bNodeSocket *sock, *gsock; - - for (node=ngroup->nodes.first; node; node=node->next) { - for (sock=node->inputs.first; sock; sock=sock->next) { - if (!sock->link && !(sock->flag & SOCK_HIDDEN)) { - gsock = nodeGroupAddSocket(ngroup, sock->name, sock->type, SOCK_IN); - /* initialize the default socket value */ - QUATCOPY(gsock->ns.vec, sock->ns.vec); - sock->link = nodeAddLink(ngroup, NULL, gsock, node, sock); - } - } - for (sock=node->outputs.first; sock; sock=sock->next) { - if (nodeCountSocketLinks(ngroup, sock)==0 && !(sock->flag & SOCK_HIDDEN)) { - gsock = nodeGroupAddSocket(ngroup, sock->name, sock->type, SOCK_OUT); - /* initialize the default socket value */ - QUATCOPY(gsock->ns.vec, sock->ns.vec); - gsock->link = nodeAddLink(ngroup, node, sock, NULL, gsock); - } + if(ntype->inputs) { + sockdef= ntype->inputs; + while(sockdef->type != -1) { + sock = node_add_input_from_template(ntree, node, sockdef); + + sockdef++; } } -} - -void nodeGroupRemoveSocket(bNodeTree *ngroup, bNodeSocket *gsock, int in_out) -{ - nodeRemSocketLinks(ngroup, gsock); - switch (in_out) { - case SOCK_IN: BLI_remlink(&ngroup->inputs, gsock); break; - case SOCK_OUT: BLI_remlink(&ngroup->outputs, gsock); break; - } - MEM_freeN(gsock); -} - -/* ************** Add stuff ********** */ -void nodeAddSockets(bNode *node, bNodeType *ntype) -{ - if (node->type==NODE_GROUP) { - bNodeTree *ntree= (bNodeTree*)node->id; - if (ntree) { - bNodeSocket *gsock; - for (gsock=ntree->inputs.first; gsock; gsock=gsock->next) - node_add_group_socket(&node->inputs, gsock); - for (gsock=ntree->outputs.first; gsock; gsock=gsock->next) - node_add_group_socket(&node->outputs, gsock); - } - } - else { - bNodeSocketType *stype; - - if(ntype->inputs) { - stype= ntype->inputs; - while(stype->type != -1) { - node_add_socket_type(&node->inputs, stype); - stype++; - } - } - if(ntype->outputs) { - stype= ntype->outputs; - while(stype->type != -1) { - node_add_socket_type(&node->outputs, stype); - stype++; - } + if(ntype->outputs) { + sockdef= ntype->outputs; + while(sockdef->type != -1) { + sock = node_add_output_from_template(ntree, node, sockdef); + + sockdef++; } } } @@ -945,65 +321,40 @@ void nodeUniqueName(bNodeTree *ntree, bNode *node) BLI_uniquename(&ntree->nodes, node, "Node", '.', offsetof(bNode, name), sizeof(node->name)); } -bNode *nodeAddNodeType(bNodeTree *ntree, int type, bNodeTree *ngroup, ID *id) +bNode *nodeAddNode(bNodeTree *ntree, struct bNodeTemplate *ntemp) { - bNode *node= NULL; - bNodeType *ntype= NULL; - - if (ngroup && BLI_findindex(&G.main->nodetree, ngroup)==-1) { - printf("nodeAddNodeType() error: '%s' not in main->nodetree\n", ngroup->id.name); - return NULL; - } - - if(type>=NODE_DYNAMIC_MENU) { - int a=0, idx= type-NODE_DYNAMIC_MENU; - ntype= ntree->alltypes.first; - while(ntype) { - if(ntype->type==NODE_DYNAMIC) { - if(a==idx) - break; - a++; - } - ntype= ntype->next; - } - } else - ntype= node_get_type(ntree, type, id); - - if(ntype == NULL) { - printf("nodeAddNodeType() error: '%d' type invalid\n", type); - return NULL; - } - - node= MEM_callocN(sizeof(bNode), "new node"); - BLI_addtail(&ntree->nodes, node); - node->typeinfo= ntype; - if(type>=NODE_DYNAMIC_MENU) - node->custom2= type; /* for node_dynamic_init */ - - if(ngroup) - BLI_strncpy(node->name, ngroup->id.name+2, NODE_MAXSTR); - else if(type>NODE_DYNAMIC_MENU) { - BLI_strncpy(node->name, ntype->id->name+2, NODE_MAXSTR); - } - else - BLI_strncpy(node->name, ntype->name, NODE_MAXSTR); - - nodeUniqueName(ntree, node); + bNode *node; + bNodeType *ntype; + ntype= node_get_type(ntree, ntemp->type); + if(ntype == NULL) { + printf("nodeAddNodeType() error: '%d' type invalid\n", ntemp->type); + return NULL; + } + /* validity check */ + if (!nodeValid(ntree, ntemp)) + return NULL; + + node= MEM_callocN(sizeof(bNode), "new node"); node->type= ntype->type; + node->typeinfo= ntype; node->flag= NODE_SELECT|ntype->flag; node->width= ntype->width; - node->miniwidth= 42.0f; /* small value only, allows print of first chars */ - - if(type==NODE_GROUP) - node->id= (ID *)ngroup; - - /* need init handler later? */ - /* got it-bob*/ - if(ntype->initfunc!=NULL) - ntype->initfunc(node); + node->miniwidth= 42.0f; + node->height= ntype->height; - nodeAddSockets(node, ntype); + node_add_sockets_from_type(ntree, node, ntype); + + if(ntype->initfunc!=NULL) + ntype->initfunc(ntree, node, ntemp); + + /* initialize the node name with the node label */ + BLI_strncpy(node->name, nodeLabel(node), NODE_MAXSTR); + nodeUniqueName(ntree, node); + + BLI_addtail(&ntree->nodes, node); + + ntree->update |= NTREE_UPDATE_NODES; return node; } @@ -1011,9 +362,9 @@ bNode *nodeAddNodeType(bNodeTree *ntree, int type, bNodeTree *ngroup, ID *id) void nodeMakeDynamicType(bNode *node) { /* find SH_DYNAMIC_NODE ntype */ - bNodeType *ntype= node_all_shaders.first; + bNodeType *ntype= ntreeGetType(NTREE_SHADER)->node_types.first; while(ntype) { - if(ntype->type==NODE_DYNAMIC && ntype->id==NULL) + if(ntype->type==NODE_DYNAMIC) break; ntype= ntype->next; } @@ -1023,17 +374,11 @@ void nodeMakeDynamicType(bNode *node) /*node->typeinfo= MEM_dupallocN(ntype);*/ bNodeType *newtype= MEM_callocN(sizeof(bNodeType), "dynamic bNodeType"); *newtype= *ntype; - newtype->name= BLI_strdup(ntype->name); + strcpy(newtype->name, ntype->name); node->typeinfo= newtype; } } -void nodeUpdateType(bNodeTree *ntree, bNode* node, bNodeType *ntype) -{ - verify_socket_list(ntree, &node->inputs, ntype->inputs); - verify_socket_list(ntree, &node->outputs, ntype->outputs); -} - /* keep socket listorder identical, for copying links */ /* ntree is the target tree */ bNode *nodeCopyNode(struct bNodeTree *ntree, struct bNode *node) @@ -1045,19 +390,23 @@ bNode *nodeCopyNode(struct bNodeTree *ntree, struct bNode *node) nodeUniqueName(ntree, nnode); BLI_addtail(&ntree->nodes, nnode); - + BLI_duplicatelist(&nnode->inputs, &node->inputs); oldsock= node->inputs.first; for(sock= nnode->inputs.first; sock; sock= sock->next, oldsock= oldsock->next) { oldsock->new_sock= sock; + sock->stack_index= 0; + + sock->default_value = (oldsock->default_value ? MEM_dupallocN(oldsock->default_value) : NULL); } BLI_duplicatelist(&nnode->outputs, &node->outputs); oldsock= node->outputs.first; for(sock= nnode->outputs.first; sock; sock= sock->next, oldsock= oldsock->next) { - sock->stack_index= 0; - sock->ns.data= NULL; oldsock->new_sock= sock; + sock->stack_index= 0; + + sock->default_value = (oldsock->default_value ? MEM_dupallocN(oldsock->default_value) : NULL); } /* don't increase node->id users, freenode doesn't decrement either */ @@ -1069,10 +418,11 @@ bNode *nodeCopyNode(struct bNodeTree *ntree, struct bNode *node) nnode->new_node= NULL; nnode->preview= NULL; + ntree->update |= NTREE_UPDATE_NODES; + return nnode; } -/* fromsock and tosock can be NULL */ /* also used via rna api, so we check for proper input output direction */ bNodeLink *nodeAddLink(bNodeTree *ntree, bNode *fromnode, bNodeSocket *fromsock, bNode *tonode, bNodeSocket *tosock) { @@ -1095,6 +445,21 @@ bNodeLink *nodeAddLink(bNodeTree *ntree, bNode *fromnode, bNodeSocket *fromsock, from= -1; /* OK but flip */ } } + else { + /* check tree sockets */ + for(sock= ntree->inputs.first; sock; sock= sock->next) + if(sock==fromsock) + break; + if(sock) + from= 1; /* OK */ + else { + for(sock= ntree->outputs.first; sock; sock= sock->next) + if(sock==fromsock) + break; + if(sock) + from= -1; /* OK but flip */ + } + } if(tonode) { for(sock= tonode->inputs.first; sock; sock= sock->next) if(sock==tosock) @@ -1109,8 +474,22 @@ bNodeLink *nodeAddLink(bNodeTree *ntree, bNode *fromnode, bNodeSocket *fromsock, to= -1; /* OK but flip */ } } + else { + /* check tree sockets */ + for(sock= ntree->outputs.first; sock; sock= sock->next) + if(sock==tosock) + break; + if(sock) + to= 1; /* OK */ + else { + for(sock= ntree->inputs.first; sock; sock= sock->next) + if(sock==tosock) + break; + if(sock) + to= -1; /* OK but flip */ + } + } - /* this allows NULL sockets to work */ if(from >= 0 && to >= 0) { link= MEM_callocN(sizeof(bNodeLink), "link"); BLI_addtail(&ntree->links, link); @@ -1128,6 +507,8 @@ bNodeLink *nodeAddLink(bNodeTree *ntree, bNode *fromnode, bNodeSocket *fromsock, link->tosock= fromsock; } + ntree->update |= NTREE_UPDATE_LINKS; + return link; } @@ -1137,6 +518,8 @@ void nodeRemLink(bNodeTree *ntree, bNodeLink *link) if(link->tosock) link->tosock->link= NULL; MEM_freeN(link); + + ntree->update |= NTREE_UPDATE_LINKS; } void nodeRemSocketLinks(bNodeTree *ntree, bNodeSocket *sock) @@ -1149,26 +532,73 @@ void nodeRemSocketLinks(bNodeTree *ntree, bNodeSocket *sock) nodeRemLink(ntree, link); } } + + ntree->update |= NTREE_UPDATE_LINKS; } +/* transforms node location to area coords */ +void nodeSpaceCoords(bNode *node, float *locx, float *locy) +{ + if (node->parent) { + nodeSpaceCoords(node->parent, locx, locy); + *locx += node->locx; + *locy += node->locy; + } + else { + *locx = node->locx; + *locy = node->locy; + } +} -bNodeTree *ntreeAddTree(const char *name, int type, const short is_group) +void nodeAttachNode(bNode *node, bNode *parent) +{ + float parentx, parenty; + + node->parent = parent; + /* transform to parent space */ + nodeSpaceCoords(parent, &parentx, &parenty); + node->locx -= parentx; + node->locy -= parenty; +} + +void nodeDetachNode(struct bNode *node) +{ + float parentx, parenty; + + if (node->parent) { + /* transform to "global" (area) space */ + nodeSpaceCoords(node->parent, &parentx, &parenty); + node->locx += parentx; + node->locy += parenty; + node->parent = NULL; + } +} + +bNodeTree *ntreeAddTree(const char *name, int type, int nodetype) { bNodeTree *ntree; - - if (is_group) - ntree= alloc_libblock(&G.main->nodetree, ID_NT, name); - else { + bNodeType *ntype; + + /* trees are created as local trees if they of compositor, material or texture type, + * node groups and other tree types are created as library data. + */ + if (ELEM3(type, NTREE_COMPOSIT, NTREE_SHADER, NTREE_TEXTURE) && nodetype==0) { ntree= MEM_callocN(sizeof(bNodeTree), "new node tree"); *( (short *)ntree->id.name )= ID_NT; /* not "type", as that is ntree->type */ BLI_strncpy(ntree->id.name+2, name, sizeof(ntree->id.name)); } - + else + ntree= alloc_libblock(&G.main->nodetree, ID_NT, name); + ntree->type= type; - ntree->alltypes.first = NULL; - ntree->alltypes.last = NULL; - + ntree->nodetype = nodetype; + ntreeInitTypes(ntree); + + ntype = node_get_type(ntree, ntree->nodetype); + if (ntype && ntype->inittreefunc) + ntype->inittreefunc(ntree); + return ntree; } @@ -1199,9 +629,7 @@ bNodeTree *ntreeCopyTree(bNodeTree *ntree) id_us_plus((ID *)newtree->gpd); /* in case a running nodetree is copied */ - newtree->init &= ~(NTREE_EXEC_INIT); - newtree->threadstack= NULL; - newtree->stack= NULL; + newtree->execdata= NULL; newtree->nodes.first= newtree->nodes.last= NULL; newtree->links.first= newtree->links.last= NULL; @@ -1210,7 +638,10 @@ bNodeTree *ntreeCopyTree(bNodeTree *ntree) for(node= ntree->nodes.first; node; node= node->next) { node->new_node= NULL; nnode= nodeCopyNode(newtree, node); /* sets node->new */ - if(node==last) break; + + /* make sure we don't copy new nodes again! */ + if (node==last) + break; } /* socket definition for group usage */ @@ -1218,14 +649,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); } - 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); } - + /* copy links */ BLI_duplicatelist(&newtree->links, &ntree->links); for(link= newtree->links.first; link; link= link->next) { @@ -1237,7 +669,13 @@ bNodeTree *ntreeCopyTree(bNodeTree *ntree) if (link->tosock) link->tosock->link = link; } - + + /* update node->parent pointers */ + for (node=newtree->nodes.first; node; node=node->next) { + if (node->parent) + node->parent = node->parent->new_node; + } + return newtree; } @@ -1256,7 +694,7 @@ void ntreeSwitchID(bNodeTree *ntree, ID *id_from, ID *id_to) /* *************** preview *********** */ /* if node->preview, then we assume the rect to exist */ -static void node_free_preview(bNode *node) +void nodeFreePreview(bNode *node) { if(node->preview) { if(node->preview->rect) @@ -1360,7 +798,6 @@ void nodeAddToPreview(bNode *node, float *col, int x, int y, int do_manage) } } - /* ************** Free stuff ********** */ /* goes over entire tree */ @@ -1395,50 +832,84 @@ void nodeUnlinkNode(bNodeTree *ntree, bNode *node) } } -static void composit_free_node_cache(bNode *node) +static void node_unlink_attached(bNodeTree *ntree, bNode *parent) { - bNodeSocket *sock; - - for(sock= node->outputs.first; sock; sock= sock->next) { - if(sock->ns.data) { - free_compbuf(sock->ns.data); - sock->ns.data= NULL; - } + bNode *node; + for (node=ntree->nodes.first; node; node=node->next) { + if (node->parent == parent) + nodeDetachNode(node); } } void nodeFreeNode(bNodeTree *ntree, bNode *node) { + bNodeTreeType *treetype= ntreeGetType(ntree->type); + bNodeSocket *sock, *nextsock; + + /* remove all references to this node */ nodeUnlinkNode(ntree, node); + node_unlink_attached(ntree, node); + BLI_remlink(&ntree->nodes, node); /* since it is called while free database, node->id is undefined */ - if(ntree->type==NTREE_COMPOSIT) - composit_free_node_cache(node); - BLI_freelistN(&node->inputs); - BLI_freelistN(&node->outputs); + if (treetype->free_node_cache) + treetype->free_node_cache(ntree, node); - node_free_preview(node); + for (sock=node->inputs.first; sock; sock = nextsock) { + nextsock = sock->next; + if (sock->default_value) + MEM_freeN(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); + MEM_freeN(sock); + } + + nodeFreePreview(node); if(node->typeinfo && node->typeinfo->freestoragefunc) { node->typeinfo->freestoragefunc(node); } MEM_freeN(node); + + ntree->update |= NTREE_UPDATE_NODES; } /* do not free ntree itself here, free_libblock calls this function too */ void ntreeFreeTree(bNodeTree *ntree) { bNode *node, *next; + bNodeSocket *sock; if(ntree==NULL) return; - ntreeEndExecTree(ntree); /* checks for if it is still initialized */ + /* XXX hack! node trees should not store execution graphs at all. + * This should be removed when old tree types no longer require it. + * Currently the execution data for texture nodes remains in the tree + * after execution, until the node tree is updated or freed. + */ + if (ntree->execdata) { + switch (ntree->type) { + case NTREE_COMPOSIT: + ntreeCompositEndExecTree(ntree->execdata); + break; + case NTREE_SHADER: + ntreeShaderEndExecTree(ntree->execdata); + break; + case NTREE_TEXTURE: + ntreeTexEndExecTree(ntree->execdata); + break; + } + } BKE_free_animdata((ID *)ntree); - + id_us_min((ID *)ntree->gpd); BLI_freelistN(&ntree->links); /* do first, then unlink_node goes fast */ @@ -1448,25 +919,120 @@ void ntreeFreeTree(bNodeTree *ntree) nodeFreeNode(ntree, node); } + for (sock=ntree->inputs.first; sock; sock=sock->next) + if (sock->default_value) + MEM_freeN(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); BLI_freelistN(&ntree->outputs); } void ntreeFreeCache(bNodeTree *ntree) { - bNode *node; + bNodeTreeType *treetype; if(ntree==NULL) return; + + treetype= ntreeGetType(ntree->type); + if (treetype->free_cache) + treetype->free_cache(ntree); +} - if(ntree->type==NTREE_COMPOSIT) - for(node= ntree->nodes.first; node; node= node->next) - composit_free_node_cache(node); +void ntreeSetOutput(bNodeTree *ntree) +{ + bNode *node; + /* find the active outputs, might become tree type dependant handler */ + for(node= ntree->nodes.first; node; node= node->next) { + if(node->typeinfo->nclass==NODE_CLASS_OUTPUT) { + bNode *tnode; + int output= 0; + + /* we need a check for which output node should be tagged like this, below an exception */ + if(node->type==CMP_NODE_OUTPUT_FILE) + continue; + + /* there is more types having output class, each one is checked */ + for(tnode= ntree->nodes.first; tnode; tnode= tnode->next) { + if(tnode->typeinfo->nclass==NODE_CLASS_OUTPUT) { + + if(ntree->type==NTREE_COMPOSIT) { + + /* same type, exception for viewer */ + if(tnode->type==node->type || + (ELEM(tnode->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER) && + ELEM(node->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER))) { + if(tnode->flag & NODE_DO_OUTPUT) { + output++; + if(output>1) + tnode->flag &= ~NODE_DO_OUTPUT; + } + } + } + else { + /* same type */ + if(tnode->type==node->type) { + if(tnode->flag & NODE_DO_OUTPUT) { + output++; + if(output>1) + tnode->flag &= ~NODE_DO_OUTPUT; + } + } + } + } + } + if(output==0) + node->flag |= NODE_DO_OUTPUT; + } + } + + /* here we could recursively set which nodes have to be done, + might be different for editor or for "real" use... */ +} + +typedef struct MakeLocalCallData { + ID *group_id; + ID *new_id; + int lib, local; +} MakeLocalCallData; + +static void ntreeMakeLocal_CheckLocal(void *calldata, ID *owner_id, bNodeTree *ntree) +{ + MakeLocalCallData *cd= (MakeLocalCallData*)calldata; + bNode *node; + + /* find if group is in tree */ + for(node= ntree->nodes.first; node; node= node->next) { + if(node->id == cd->group_id) { + if(owner_id->lib) cd->lib= 1; + else cd->local= 1; + } + } +} + +static void ntreeMakeLocal_LinkNew(void *calldata, ID *owner_id, bNodeTree *ntree) +{ + MakeLocalCallData *cd= (MakeLocalCallData*)calldata; + bNode *node; + + /* find if group is in tree */ + for(node= ntree->nodes.first; node; node= node->next) { + if(node->id == cd->group_id) { + if(owner_id->lib==NULL) { + node->id= cd->new_id; + cd->new_id->us++; + cd->group_id->us--; + } + } + } } void ntreeMakeLocal(bNodeTree *ntree) { - int local=0, lib=0; + bNodeTreeType *treetype= ntreeGetType(ntree->type); + MakeLocalCallData cd; /* - only lib users: do nothing * - only local users: set flag @@ -1475,138 +1041,146 @@ void ntreeMakeLocal(bNodeTree *ntree) if(ntree->id.lib==NULL) return; if(ntree->id.us==1) { - ntree->id.lib= NULL; + ntree->id.lib= 0; ntree->id.flag= LIB_LOCAL; - new_id(NULL, (ID *)ntree, NULL); + new_id(0, (ID *)ntree, 0); return; } /* now check users of groups... again typedepending, callback... */ - if(ntree->type==NTREE_SHADER) { - Material *ma; - for(ma= G.main->mat.first; ma; ma= ma->id.next) { - if(ma->nodetree) { - bNode *node; - - /* find if group is in tree */ - for(node= ma->nodetree->nodes.first; node; node= node->next) { - if(node->id == (ID *)ntree) { - if(ma->id.lib) lib= 1; - else local= 1; - } - } - } - } - } - else if(ntree->type==NTREE_COMPOSIT) { - Scene *sce; - for(sce= G.main->scene.first; sce; sce= sce->id.next) { - if(sce->nodetree) { - bNode *node; - - /* find if group is in tree */ - for(node= sce->nodetree->nodes.first; node; node= node->next) { - if(node->id == (ID *)ntree) { - if(sce->id.lib) lib= 1; - else local= 1; - } - } - } - } - } - else if(ntree->type==NTREE_TEXTURE) { - Tex *tx; - for(tx= G.main->tex.first; tx; tx= tx->id.next) { - if(tx->nodetree) { - bNode *node; - - /* find if group is in tree */ - for(node= tx->nodetree->nodes.first; node; node= node->next) { - if(node->id == (ID *)ntree) { - if(tx->id.lib) lib= 1; - else local= 1; - } - } - } - } - } + cd.group_id = &ntree->id; + cd.new_id = NULL; + cd.local = 0; + cd.lib = 0; + + treetype->foreach_nodetree(G.main, &cd, &ntreeMakeLocal_CheckLocal); /* if all users are local, we simply make tree local */ - if(local && lib==0) { + if(cd.local && cd.lib==0) { ntree->id.lib= NULL; ntree->id.flag= LIB_LOCAL; - new_id(NULL, (ID *)ntree, NULL); + new_id(0, (ID *)ntree, 0); } - else if(local && lib) { + else if(cd.local && cd.lib) { /* this is the mixed case, we copy the tree and assign it to local users */ bNodeTree *newtree= ntreeCopyTree(ntree); newtree->id.us= 0; - if(ntree->type==NTREE_SHADER) { - Material *ma; - for(ma= G.main->mat.first; ma; ma= ma->id.next) { - if(ma->nodetree) { - bNode *node; - - /* find if group is in tree */ - for(node= ma->nodetree->nodes.first; node; node= node->next) { - if(node->id == (ID *)ntree) { - if(ma->id.lib==NULL) { - node->id= &newtree->id; - newtree->id.us++; - ntree->id.us--; - } - } - } - } - } - } - else if(ntree->type==NTREE_COMPOSIT) { - Scene *sce; - for(sce= G.main->scene.first; sce; sce= sce->id.next) { - if(sce->nodetree) { - bNode *node; - - /* find if group is in tree */ - for(node= sce->nodetree->nodes.first; node; node= node->next) { - if(node->id == (ID *)ntree) { - if(sce->id.lib==NULL) { - node->id= &newtree->id; - newtree->id.us++; - ntree->id.us--; - } - } - } - } - } - } - else if(ntree->type==NTREE_TEXTURE) { - Tex *tx; - for(tx= G.main->tex.first; tx; tx= tx->id.next) { - if(tx->nodetree) { - bNode *node; - - /* find if group is in tree */ - for(node= tx->nodetree->nodes.first; node; node= node->next) { - if(node->id == (ID *)ntree) { - if(tx->id.lib==NULL) { - node->id= &newtree->id; - newtree->id.us++; - ntree->id.us--; - } - } - } - } - } - } + + cd.new_id = &newtree->id; + treetype->foreach_nodetree(G.main, &cd, &ntreeMakeLocal_LinkNew); } } +int ntreeNodeExists(bNodeTree *ntree, bNode *testnode) +{ + bNode *node= ntree->nodes.first; + for(; node; node= node->next) + if(node==testnode) + return 1; + return 0; +} + +int ntreeOutputExists(bNode *node, bNodeSocket *testsock) +{ + bNodeSocket *sock= node->outputs.first; + for(; sock; sock= sock->next) + if(sock==testsock) + return 1; + return 0; +} + +/* returns localized tree for execution in threads */ +bNodeTree *ntreeLocalize(bNodeTree *ntree) +{ + bNodeTreeType *ntreetype= ntreeGetType(ntree->type); + + bNodeTree *ltree; + bNode *node; + + bAction *action_backup= NULL, *tmpact_backup= NULL; + + /* Workaround for copying an action on each render! + * set action to NULL so animdata actions dont get copied */ + AnimData *adt= BKE_animdata_from_id(&ntree->id); + + if(adt) { + action_backup= adt->action; + tmpact_backup= adt->tmpact; + + adt->action= NULL; + adt->tmpact= NULL; + } + + /* node copy func */ + ltree= ntreeCopyTree(ntree); + + if(adt) { + AnimData *ladt= BKE_animdata_from_id(<ree->id); + + adt->action= ladt->action= action_backup; + adt->tmpact= ladt->tmpact= tmpact_backup; + + if(action_backup) action_backup->id.us++; + if(tmpact_backup) tmpact_backup->id.us++; + + } + /* end animdata uglyness */ + + /* ensures only a single output node is enabled */ + ntreeSetOutput(ntree); + + for(node= ntree->nodes.first; node; node= node->next) { + /* store new_node pointer to original */ + node->new_node->new_node= node; + } + + if (ntreetype->localize) + ntreetype->localize(ltree, ntree); + + return ltree; +} + +/* sync local composite with real tree */ +/* local tree is supposed to be running, be careful moving previews! */ +/* is called by jobs manager, outside threads, so it doesnt happen during draw */ +void ntreeLocalSync(bNodeTree *localtree, bNodeTree *ntree) +{ + bNodeTreeType *ntreetype= ntreeGetType(ntree->type); + + if (ntreetype->local_sync) + ntreetype->local_sync(localtree, ntree); +} + +/* merge local tree results back, and free local tree */ +/* we have to assume the editor already changed completely */ +void ntreeLocalMerge(bNodeTree *localtree, bNodeTree *ntree) +{ + bNodeTreeType *ntreetype= ntreeGetType(ntree->type); + bNode *lnode; + + /* move over the compbufs and previews */ + for(lnode= localtree->nodes.first; lnode; lnode= lnode->next) { + if(ntreeNodeExists(ntree, lnode->new_node)) { + if(lnode->preview && lnode->preview->rect) { + nodeFreePreview(lnode->new_node); + lnode->new_node->preview= lnode->preview; + lnode->preview= NULL; + } + } + } + + if (ntreetype->local_merge) + ntreetype->local_merge(localtree, ntree); + + ntreeFreeTree(localtree); + MEM_freeN(localtree); +} /* ************ find stuff *************** */ -static int ntreeHasType(bNodeTree *ntree, int type) +int ntreeHasType(bNodeTree *ntree, int type) { bNode *node; @@ -1770,7 +1344,7 @@ void ntreeSocketUseFlags(bNodeTree *ntree) /* ************** dependency stuff *********** */ /* node is guaranteed to be not checked before */ -static int node_recurs_check(bNode *node, bNode ***nsort) +static int node_get_deplist_recurs(bNode *node, bNode ***nsort) { bNode *fromnode; bNodeSocket *sock; @@ -1778,163 +1352,207 @@ static int node_recurs_check(bNode *node, bNode ***nsort) node->done= 1; + /* check linked nodes */ for(sock= node->inputs.first; sock; sock= sock->next) { if(sock->link) { fromnode= sock->link->fromnode; if(fromnode) { if (fromnode->done==0) - fromnode->level= node_recurs_check(fromnode, nsort); + fromnode->level= node_get_deplist_recurs(fromnode, nsort); if (fromnode->level <= level) level = fromnode->level - 1; } } } - **nsort= node; - (*nsort)++; + + /* check parent node */ + if (node->parent) { + if (node->parent->done==0) + node->parent->level= node_get_deplist_recurs(node->parent, nsort); + if (node->parent->level <= level) + level = node->parent->level - 1; + } + + if (nsort) { + **nsort= node; + (*nsort)++; + } return level; } - -static void ntreeSetOutput(bNodeTree *ntree) +void ntreeGetDependencyList(struct bNodeTree *ntree, struct bNode ***deplist, int *totnodes) { - bNode *node; - - /* find the active outputs, might become tree type dependant handler */ - for(node= ntree->nodes.first; node; node= node->next) { - if(node->typeinfo->nclass==NODE_CLASS_OUTPUT) { - bNode *tnode; - int output= 0; - - /* we need a check for which output node should be tagged like this, below an exception */ - if(node->type==CMP_NODE_OUTPUT_FILE) - continue; - - /* there is more types having output class, each one is checked */ - for(tnode= ntree->nodes.first; tnode; tnode= tnode->next) { - if(tnode->typeinfo->nclass==NODE_CLASS_OUTPUT) { - - if(ntree->type==NTREE_COMPOSIT) { - - /* same type, exception for viewer */ - if(tnode->type==node->type || - (ELEM(tnode->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER) && - ELEM(node->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER))) { - if(tnode->flag & NODE_DO_OUTPUT) { - output++; - if(output>1) - tnode->flag &= ~NODE_DO_OUTPUT; - } - } - } - else { - /* same type */ - if(tnode->type==node->type) { - if(tnode->flag & NODE_DO_OUTPUT) { - output++; - if(output>1) - tnode->flag &= ~NODE_DO_OUTPUT; - } - } - } - } - } - if(output==0) - node->flag |= NODE_DO_OUTPUT; - } - } + bNode *node, **nsort; - /* here we could recursively set which nodes have to be done, - might be different for editor or for "real" use... */ -} - -void ntreeSolveOrder(bNodeTree *ntree) -{ - bNode *node, **nodesort, **nsort; - bNodeSocket *sock; - bNodeLink *link; - int a, totnode=0; + *totnodes=0; - /* the solve-order is called on each tree change, so we should be sure no exec can be running */ - ntreeEndExecTree(ntree); - - /* set links pointers the input sockets, to find dependencies */ /* first clear data */ for(node= ntree->nodes.first; node; node= node->next) { node->done= 0; - totnode++; - for(sock= node->inputs.first; sock; sock= sock->next) - sock->link= NULL; + (*totnodes)++; } - /* clear group socket links */ - for(sock= ntree->outputs.first; sock; sock= sock->next) - sock->link= NULL; - if(totnode==0) + if(*totnodes==0) { + *deplist = NULL; return; - - for(link= ntree->links.first; link; link= link->next) { - link->tosock->link= link; } - nsort= nodesort= MEM_callocN(totnode*sizeof(void *), "sorted node array"); + nsort= *deplist= MEM_callocN((*totnodes)*sizeof(bNode*), "sorted node array"); /* recursive check */ for(node= ntree->nodes.first; node; node= node->next) { if(node->done==0) { - node->level= node_recurs_check(node, &nsort); + node->level= node_get_deplist_recurs(node, &nsort); } } - - /* re-insert nodes in order, first a paranoia check */ - for(a=0; anodes.first= ntree->nodes.last= NULL; - for(a=0; anodes, nodesort[a]); - } - - MEM_freeN(nodesort); - - ntreeSetOutput(ntree); } +static void ntree_update_link_pointers(bNodeTree *ntree) +{ + bNode *node; + bNodeSocket *sock; + bNodeLink *link; + + /* first clear data */ + for(node= ntree->nodes.first; node; node= node->next) { + for(sock= node->inputs.first; sock; sock= sock->next) + sock->link= NULL; + } + /* clear socket links */ + for(sock= ntree->outputs.first; sock; sock= sock->next) + sock->link= NULL; + + for(link= ntree->links.first; link; link= link->next) { + if (link->tosock) + link->tosock->link= link; + } +} + +void ntree_validate_links(bNodeTree *ntree) +{ + bNodeTreeType *ntreetype = ntreeGetType(ntree->type); + bNodeLink *link; + + for (link = ntree->links.first; link; link = link->next) { + link->flag |= NODE_LINK_VALID; + if (link->fromnode && link->tonode && link->fromnode->level <= link->tonode->level) + link->flag &= ~NODE_LINK_VALID; + else if (ntreetype->validate_link) { + if (!ntreetype->validate_link(ntree, link)) + link->flag &= ~NODE_LINK_VALID; + } + } +} + +static void ntree_verify_nodes_cb(void *calldata, struct ID *UNUSED(owner_id), struct bNodeTree *ntree) +{ + ID *id= (ID*)calldata; + bNode *node; + + for (node=ntree->nodes.first; node; node=node->next) + if (node->typeinfo->verifyfunc) + node->typeinfo->verifyfunc(ntree, node, id); +} + +void ntreeVerifyNodes(struct Main *main, struct ID *id) +{ + bNodeTreeType *ntreetype; + bNodeTree *ntree; + int n; + + for (n=0; n < NUM_NTREE_TYPES; ++n) { + ntreetype= ntreeGetType(n); + if (ntreetype && ntreetype->foreach_nodetree) + ntreetype->foreach_nodetree(main, id, ntree_verify_nodes_cb); + } + for (ntree=main->nodetree.first; ntree; ntree=ntree->id.next) + ntree_verify_nodes_cb(id, NULL, ntree); +} + +void ntreeUpdateTree(bNodeTree *ntree) +{ + bNodeTreeType *ntreetype= ntreeGetType(ntree->type); + bNode *node; + bNode **deplist; + int totnodes, n; + + ntree_update_link_pointers(ntree); + + /* also updates the node level! */ + ntreeGetDependencyList(ntree, &deplist, &totnodes); + + if (deplist) { + /* update individual nodes */ + for (n=0; n < totnodes; ++n) { + node = deplist[n]; + if (ntreetype->update_node) + ntreetype->update_node(ntree, node); + else if (node->typeinfo->updatefunc) + node->typeinfo->updatefunc(ntree, node); + } + + MEM_freeN(deplist); + + /* ensures only a single output node is enabled, texnode allows multiple though */ + if(ntree->type!=NTREE_TEXTURE) + ntreeSetOutput(ntree); + + } + + /* general tree updates */ + if (ntree->update & (NTREE_UPDATE_LINKS|NTREE_UPDATE_NODES)) { + ntree_validate_links(ntree); + } + + /* update tree */ + if (ntreetype->update) + ntreetype->update(ntree); + else { + bNodeType *ntype= node_get_type(ntree, ntree->nodetype); + if (ntype && ntype->updatetreefunc) + ntype->updatetreefunc(ntree); + } + + /* XXX hack, should be done by depsgraph!! */ + ntreeVerifyNodes(G.main, &ntree->id); + + /* clear the update flag */ + ntree->update = 0; +} -/* Should be callback! */ -/* Do not call execs here */ void NodeTagChanged(bNodeTree *ntree, bNode *node) { - if(ntree->type==NTREE_COMPOSIT) { - bNodeSocket *sock; - - for(sock= node->outputs.first; sock; sock= sock->next) { - if(sock->ns.data) { - //free_compbuf(sock->ns.data); - //sock->ns.data= NULL; - } - } - node->need_exec= 1; - } + bNodeTreeType *ntreetype = ntreeGetType(ntree->type); + + if (ntreetype->update_node) + ntreetype->update_node(ntree, node); + else if (node->typeinfo->updatefunc) + node->typeinfo->updatefunc(ntree, node); } int NodeTagIDChanged(bNodeTree *ntree, ID *id) { + bNodeTreeType *ntreetype = ntreeGetType(ntree->type); + bNode *node; int change = FALSE; if(ELEM(NULL, id, ntree)) return change; - if(ntree->type==NTREE_COMPOSIT) { - bNode *node; - + if (ntreetype->update_node) { for(node= ntree->nodes.first; node; node= node->next) { if(node->id==id) { - change= TRUE; - NodeTagChanged(ntree, node); + change = TRUE; + ntreetype->update_node(ntree, node); + } + } + } + else { + for(node= ntree->nodes.first; node; node= node->next) { + if(node->id==id) { + change = TRUE; + if (node->typeinfo->updatefunc) + node->typeinfo->updatefunc(ntree, node); } } } @@ -1943,1454 +1561,108 @@ int NodeTagIDChanged(bNodeTree *ntree, ID *id) } +/* ************* node type access ********** */ -/* ******************* executing ************* */ - -/* for a given socket, find the actual stack entry */ -static bNodeStack *get_socket_stack(bNodeStack *stack, bNodeSocket *sock, bNodeStack **gin) +int nodeValid(bNodeTree *ntree, bNodeTemplate *ntemp) { - switch (sock->stack_type) { - case SOCK_STACK_LOCAL: - return stack + sock->stack_index; - case SOCK_STACK_EXTERN: - return (gin ? gin[sock->stack_index] : NULL); - case SOCK_STACK_CONST: - return sock->stack_ptr; - } - return NULL; -} - -/* see notes at ntreeBeginExecTree */ -static void node_get_stack(bNode *node, bNodeStack *stack, bNodeStack **in, bNodeStack **out, bNodeStack **gin) -{ - bNodeSocket *sock; - - /* build pointer stack */ - if (in) { - for(sock= node->inputs.first; sock; sock= sock->next) { - *(in++) = get_socket_stack(stack, sock, gin); - } - } - - if (out) { - for(sock= node->outputs.first; sock; sock= sock->next) { - *(out++) = get_socket_stack(stack, sock, gin); - } - } -} - -static void node_group_execute(bNodeStack *stack, void *data, bNode *gnode, bNodeStack **in) -{ - bNode *node; - bNodeTree *ntree= (bNodeTree *)gnode->id; - bNodeStack *nsin[MAX_SOCKET]; /* arbitrary... watch this */ - bNodeStack *nsout[MAX_SOCKET]; /* arbitrary... watch this */ - - if(ntree==NULL) return; - - stack+= gnode->stack_index; - - for(node= ntree->nodes.first; node; node= node->next) { - if(node->typeinfo->execfunc) { - node_get_stack(node, stack, nsin, nsout, in); - - /* for groups, only execute outputs for edited group */ - if(node->typeinfo->nclass==NODE_CLASS_OUTPUT) { - if(node->type==CMP_NODE_OUTPUT_FILE || (gnode->flag & NODE_GROUP_EDIT)) - node->typeinfo->execfunc(data, node, nsin, nsout); - } - else - node->typeinfo->execfunc(data, node, nsin, nsout); - } - } - - /* free internal buffers */ - if (ntree->type==NTREE_COMPOSIT) { - bNodeSocket *sock; - bNodeStack *ns; - - /* clear hasoutput on all local stack data, - * only the group output will be used from now on - */ - for (node=ntree->nodes.first; node; node=node->next) { - for (sock=node->outputs.first; sock; sock=sock->next) { - if (sock->stack_type==SOCK_STACK_LOCAL) { - ns= get_socket_stack(stack, sock, in); - ns->hasoutput = 0; - } - } - } - /* use the hasoutput flag to tag external sockets */ - for (sock=ntree->outputs.first; sock; sock=sock->next) { - if (sock->stack_type==SOCK_STACK_LOCAL) { - ns= get_socket_stack(stack, sock, in); - ns->hasoutput = 1; - } - } - /* now free all stacks that are not used from outside */ - for (node=ntree->nodes.first; node; node=node->next) { - for (sock=node->outputs.first; sock; sock=sock->next) { - if (sock->stack_type==SOCK_STACK_LOCAL ) { - ns= get_socket_stack(stack, sock, in); - if (ns->hasoutput==0 && ns->data) { - free_compbuf(ns->data); - ns->data = NULL; - } - } - } - } - } -} - -static int set_stack_indexes_default(bNode *node, int index) -{ - bNodeSocket *sock; - - for (sock=node->inputs.first; sock; sock=sock->next) { - if (sock->link && sock->link->fromsock) { - sock->stack_type = sock->link->fromsock->stack_type; - sock->stack_index = sock->link->fromsock->stack_index; - sock->stack_ptr = sock->link->fromsock->stack_ptr; - } - else { - sock->stack_type = SOCK_STACK_CONST; - sock->stack_index = -1; - sock->stack_ptr = &sock->ns; - } - } - - for (sock=node->outputs.first; sock; sock=sock->next) { - sock->stack_type = SOCK_STACK_LOCAL; - sock->stack_index = index++; - sock->stack_ptr = NULL; - } - - return index; -} - -static int ntree_begin_exec_tree(bNodeTree *ntree); -static int set_stack_indexes_group(bNode *node, int index) -{ - bNodeTree *ngroup= (bNodeTree*)node->id; - bNodeSocket *sock; - - if(ngroup && (ngroup->init & NTREE_TYPE_INIT)==0) - ntreeInitTypes(ngroup); - - node->stack_index = index; - if(ngroup) - index += ntree_begin_exec_tree(ngroup); - - for (sock=node->inputs.first; sock; sock=sock->next) { - if (sock->link && sock->link->fromsock) { - sock->stack_type = sock->link->fromsock->stack_type; - sock->stack_index = sock->link->fromsock->stack_index; - sock->stack_ptr = sock->link->fromsock->stack_ptr; - } - else { - sock->stack_type = SOCK_STACK_CONST; - sock->stack_index = -1; - sock->stack_ptr = &sock->ns; - } - } - - /* identify group node outputs from internal group sockets */ - for(sock= node->outputs.first; sock; sock= sock->next) { - if (sock->groupsock) { - bNodeSocket *insock, *gsock = sock->groupsock; - switch (gsock->stack_type) { - case SOCK_STACK_EXTERN: - /* extern stack is resolved for this group node instance */ - insock= find_group_node_input(node, gsock->link->fromsock); - sock->stack_type = insock->stack_type; - sock->stack_index = insock->stack_index; - sock->stack_ptr = insock->stack_ptr; - break; - case SOCK_STACK_LOCAL: - sock->stack_type = SOCK_STACK_LOCAL; - /* local stack index must be offset by group node instance */ - sock->stack_index = gsock->stack_index + node->stack_index; - sock->stack_ptr = NULL; - break; - case SOCK_STACK_CONST: - sock->stack_type = SOCK_STACK_CONST; - sock->stack_index = -1; - sock->stack_ptr = gsock->stack_ptr; - break; - } - } - else { - sock->stack_type = SOCK_STACK_LOCAL; - sock->stack_index = index++; - sock->stack_ptr = NULL; - } - } - - return index; -} - -/* recursively called for groups */ -/* we set all trees on own local indices, but put a total counter - in the groups, so each instance of a group has own stack */ -static int ntree_begin_exec_tree(bNodeTree *ntree) -{ - bNode *node; - bNodeSocket *gsock; - int index= 0, i; - - if((ntree->init & NTREE_TYPE_INIT)==0) - ntreeInitTypes(ntree); - - /* group inputs are numbered 0..totinputs, so external stack can easily be addressed */ - i = 0; - for(gsock=ntree->inputs.first; gsock; gsock = gsock->next) { - gsock->stack_type = SOCK_STACK_EXTERN; - gsock->stack_index = i++; - gsock->stack_ptr = NULL; - } - - /* create indices for stack, check preview */ - for(node= ntree->nodes.first; node; node= node->next) { - /* XXX can this be done by a generic one-for-all function? - * otherwise should use node-type callback. - */ - if(node->type==NODE_GROUP) - index = set_stack_indexes_group(node, index); + bNodeType *ntype= node_get_type(ntree, ntemp->type); + if (ntype) { + if (ntype->validfunc) + return ntype->validfunc(ntree, ntemp); else - index = set_stack_indexes_default(node, index); + return 1; } - - /* group outputs */ - for(gsock=ntree->outputs.first; gsock; gsock = gsock->next) { - if (gsock->link && gsock->link->fromsock) { - gsock->stack_type = gsock->link->fromsock->stack_type; - gsock->stack_index = gsock->link->fromsock->stack_index; - gsock->stack_ptr = gsock->link->fromsock->stack_ptr; - } - else { - gsock->stack_type = SOCK_STACK_CONST; - gsock->stack_index = -1; - gsock->stack_ptr = &gsock->ns; - } - } - - return index; + else + return 0; } -/* copy socket compbufs to stack, initialize usage of curve nodes */ -static void composit_begin_exec(bNodeTree *ntree, bNodeStack *stack) +const char* nodeLabel(bNode *node) { - bNode *node; - bNodeSocket *sock; - - for(node= ntree->nodes.first; node; node= node->next) { - - /* initialize needed for groups */ - node->exec= 0; - - for(sock= node->outputs.first; sock; sock= sock->next) { - bNodeStack *ns= get_socket_stack(stack, sock, NULL); - if(ns && sock->ns.data) { - ns->data= sock->ns.data; - sock->ns.data= NULL; - } - } - - /* cannot initialize them while using in threads */ - if(ELEM4(node->type, CMP_NODE_TIME, CMP_NODE_CURVE_VEC, CMP_NODE_CURVE_RGB, CMP_NODE_HUECORRECT)) { - curvemapping_initialize(node->storage); - if(node->type==CMP_NODE_CURVE_RGB) - curvemapping_premultiply(node->storage, 0); - } - if(node->type==NODE_GROUP && node->id) - composit_begin_exec((bNodeTree *)node->id, stack + node->stack_index); - - } + if (node->label[0]!='\0') + return node->label; + else if (node->typeinfo->labelfunc) + return node->typeinfo->labelfunc(node); + else + return node->typeinfo->name; } -/* copy stack compbufs to sockets */ -static void composit_end_exec(bNodeTree *ntree, bNodeStack *stack) +struct bNodeTree *nodeGroupEditGet(struct bNode *node) { - bNode *node; - bNodeStack *ns; - - for(node= ntree->nodes.first; node; node= node->next) { - bNodeSocket *sock; - - for(sock= node->outputs.first; sock; sock= sock->next) { - ns = get_socket_stack(stack, sock, NULL); - if(ns && ns->data) { - sock->ns.data= ns->data; - ns->data= NULL; - } - } - - if(node->type==CMP_NODE_CURVE_RGB) - curvemapping_premultiply(node->storage, 1); - - if(node->type==NODE_GROUP && node->id) - composit_end_exec((bNodeTree *)node->id, stack + node->stack_index); - - node->need_exec= 0; - } + if (node->typeinfo->group_edit_get) + return node->typeinfo->group_edit_get(node); + else + return NULL; } -static void group_tag_used_outputs(bNode *gnode, bNodeStack *stack, bNodeStack **gin) +struct bNodeTree *nodeGroupEditSet(struct bNode *node, int edit) { - bNodeTree *ntree= (bNodeTree *)gnode->id; - bNode *node; - bNodeSocket *sock; - - stack+= gnode->stack_index; - - for(node= ntree->nodes.first; node; node= node->next) { - if(node->typeinfo->execfunc) { - for(sock= node->inputs.first; sock; sock= sock->next) { - bNodeStack *ns = get_socket_stack(stack, sock, gin); - ns->hasoutput= 1; - } - } - - /* non-composite trees do all nodes by default */ - if (ntree->type!=NTREE_COMPOSIT) - node->need_exec = 1; - - for(sock= node->inputs.first; sock; sock= sock->next) { - bNodeStack *ns = get_socket_stack(stack, sock, gin); - if (ns) { - ns->hasoutput = 1; - - /* sock type is needed to detect rgba or value or vector types */ - if(sock->link && sock->link->fromsock) - ns->sockettype= sock->link->fromsock->type; - else - sock->ns.sockettype= sock->type; - } - - if(sock->link) { - bNodeLink *link= sock->link; - /* this is the test for a cyclic case */ - if(link->fromnode && link->tonode) { - if(link->fromnode->level >= link->tonode->level && link->tonode->level!=0xFFF); - else { - node->need_exec= 0; - } - } - } - } - - /* set stack types (for local stack entries) */ - for(sock= node->outputs.first; sock; sock= sock->next) { - bNodeStack *ns = get_socket_stack(stack, sock, gin); - if (ns) - ns->sockettype = sock->type; - } - } + if (node->typeinfo->group_edit_set) + return node->typeinfo->group_edit_set(node, edit); + else if (node->typeinfo->group_edit_get) + return node->typeinfo->group_edit_get(node); + else + return NULL; } -/* notes below are ancient! (ton) */ -/* stack indices make sure all nodes only write in allocated data, for making it thread safe */ -/* only root tree gets the stack, to enable instances to have own stack entries */ -/* per tree (and per group) unique indices are created */ -/* the index_ext we need to be able to map from groups to the group-node own stack */ - -typedef struct bNodeThreadStack { - struct bNodeThreadStack *next, *prev; - bNodeStack *stack; - int used; -} bNodeThreadStack; - -static bNodeThreadStack *ntreeGetThreadStack(bNodeTree *ntree, int thread) +void nodeGroupEditClear(struct bNode *node) { - ListBase *lb= &ntree->threadstack[thread]; - bNodeThreadStack *nts; - - for(nts=lb->first; nts; nts=nts->next) { - if(!nts->used) { - nts->used= 1; - return nts; - } - } - nts= MEM_callocN(sizeof(bNodeThreadStack), "bNodeThreadStack"); - nts->stack= MEM_dupallocN(ntree->stack); - nts->used= 1; - BLI_addtail(lb, nts); - - return nts; + if (node->typeinfo->group_edit_clear) + node->typeinfo->group_edit_clear(node); } -static void ntreeReleaseThreadStack(bNodeThreadStack *nts) +struct bNodeTemplate nodeMakeTemplate(struct bNode *node) { - nts->used= 0; -} - -/* free texture delegates */ -static void tex_end_exec(bNodeTree *ntree) -{ - bNodeThreadStack *nts; - bNodeStack *ns; - int th, a; - - if(ntree->threadstack) { - for(th=0; ththreadstack[th].first; nts; nts=nts->next) { - for(ns= nts->stack, a=0; astacksize; a++, ns++) { - if(ns->data) { - MEM_freeN(ns->data); - ns->data= NULL; - } - } - } - } - } -} - -void ntreeBeginExecTree(bNodeTree *ntree) -{ - bNodeStack *nsin[MAX_SOCKET]; /* arbitrary... watch this */ - - /* let's make it sure */ - if(ntree->init & NTREE_EXEC_INIT) - return; - - /* allocate the thread stack listbase array */ - if(ntree->type!=NTREE_COMPOSIT) - ntree->threadstack= MEM_callocN(BLENDER_MAX_THREADS*sizeof(ListBase), "thread stack array"); - - /* goes recursive over all groups */ - ntree->stacksize= ntree_begin_exec_tree(ntree); - - if(ntree->stacksize) { - bNode *node; - bNodeStack *ns; - int a; - - /* allocate the base stack */ - ns=ntree->stack= MEM_callocN(ntree->stacksize*sizeof(bNodeStack), "node stack"); - - /* tag inputs, the get_stack() gives own socket stackdata if not in use */ - for(a=0; astacksize; a++, ns++) ns->hasinput= 1; - - /* tag used outputs, so we know when we can skip operations */ - for(node= ntree->nodes.first; node; node= node->next) { - bNodeSocket *sock; - - /* non-composite trees do all nodes by default */ - if(ntree->type!=NTREE_COMPOSIT) - node->need_exec= 1; - - for(sock= node->inputs.first; sock; sock= sock->next) { - ns = get_socket_stack(ntree->stack, sock, NULL); - if (ns) { - ns->hasoutput = 1; - - /* sock type is needed to detect rgba or value or vector types */ - if(sock->link && sock->link->fromsock) - ns->sockettype= sock->link->fromsock->type; - else - sock->ns.sockettype= sock->type; - } - - if(sock->link) { - bNodeLink *link= sock->link; - /* this is the test for a cyclic case */ - if(link->fromnode && link->tonode) { - if(link->fromnode->level >= link->tonode->level && link->tonode->level!=0xFFF); - else { - node->need_exec= 0; - } - } - } - } - - /* set stack types (for local stack entries) */ - for(sock= node->outputs.first; sock; sock= sock->next) { - ns = get_socket_stack(ntree->stack, sock, NULL); - if (ns) - ns->sockettype = sock->type; - } - - if(node->type==NODE_GROUP && node->id) { - node_get_stack(node, ntree->stack, nsin, NULL, NULL); - group_tag_used_outputs(node, ntree->stack, nsin); - } - } - - if(ntree->type==NTREE_COMPOSIT) - composit_begin_exec(ntree, ntree->stack); - - /* ensures only a single output node is enabled, texnode allows multiple though */ - if(ntree->type!=NTREE_TEXTURE) - ntreeSetOutput(ntree); - - } - - ntree->init |= NTREE_EXEC_INIT; -} - -void ntreeEndExecTree(bNodeTree *ntree) -{ - bNodeStack *ns; - - if(ntree->init & NTREE_EXEC_INIT) { - bNodeThreadStack *nts; - int a; - - /* another callback candidate! */ - if(ntree->type==NTREE_COMPOSIT) { - composit_end_exec(ntree, ntree->stack); - - for(ns= ntree->stack, a=0; astacksize; a++, ns++) { - if(ns->data) { - printf("freed leftover buffer from stack\n"); - free_compbuf(ns->data); - ns->data= NULL; - } - } - } - else if(ntree->type==NTREE_TEXTURE) - tex_end_exec(ntree); - - if(ntree->stack) { - MEM_freeN(ntree->stack); - ntree->stack= NULL; - } - - if(ntree->threadstack) { - for(a=0; athreadstack[a].first; nts; nts=nts->next) - if (nts->stack) MEM_freeN(nts->stack); - BLI_freelistN(&ntree->threadstack[a]); - } - - MEM_freeN(ntree->threadstack); - ntree->threadstack= NULL; - } - - ntree->init &= ~NTREE_EXEC_INIT; - } -} - -/* nodes are presorted, so exec is in order of list */ -void ntreeExecTree(bNodeTree *ntree, void *callerdata, int thread) -{ - bNode *node; - bNodeStack *nsin[MAX_SOCKET]; /* arbitrary... watch this */ - bNodeStack *nsout[MAX_SOCKET]; /* arbitrary... watch this */ - bNodeStack *stack; - bNodeThreadStack *nts = NULL; - - /* only when initialized */ - if((ntree->init & NTREE_EXEC_INIT)==0) - ntreeBeginExecTree(ntree); - - /* composite does 1 node per thread, so no multiple stacks needed */ - if(ntree->type==NTREE_COMPOSIT) { - stack= ntree->stack; - } + bNodeTemplate ntemp; + if (node->typeinfo->templatefunc) + return node->typeinfo->templatefunc(node); else { - nts= ntreeGetThreadStack(ntree, thread); - stack= nts->stack; - } - - for(node= ntree->nodes.first; node; node= node->next) { - if(node->need_exec) { - if(node->typeinfo->execfunc) { - node_get_stack(node, stack, nsin, nsout, NULL); - node->typeinfo->execfunc(callerdata, node, nsin, nsout); - } - else if(node->type==NODE_GROUP && node->id) { - node_get_stack(node, stack, nsin, NULL, NULL); - node_group_execute(stack, callerdata, node, nsin); - } - } - } - - if(nts) - ntreeReleaseThreadStack(nts); -} - - -/* ***************************** threaded version for execute composite nodes ************* */ -/* these are nodes without input, only giving values */ -/* or nodes with only value inputs */ -static int node_only_value(bNode *node) -{ - bNodeSocket *sock; - - if(ELEM3(node->type, CMP_NODE_TIME, CMP_NODE_VALUE, CMP_NODE_RGB)) - return 1; - - /* doing this for all node types goes wrong. memory free errors */ - if(node->inputs.first && node->type==CMP_NODE_MAP_VALUE) { - int retval= 1; - for(sock= node->inputs.first; sock; sock= sock->next) { - if(sock->link && sock->link->fromnode) - retval &= node_only_value(sock->link->fromnode); - } - return retval; - } - return 0; -} - - -/* not changing info, for thread callback */ -typedef struct ThreadData { - bNodeStack *stack; - RenderData *rd; -} ThreadData; - -static void *exec_composite_node(void *node_v) -{ - bNodeStack *nsin[MAX_SOCKET]; /* arbitrary... watch this */ - bNodeStack *nsout[MAX_SOCKET]; /* arbitrary... watch this */ - bNode *node= node_v; - ThreadData *thd= (ThreadData *)node->threaddata; - - node_get_stack(node, thd->stack, nsin, nsout, NULL); - - if((node->flag & NODE_MUTED) && (!node_only_value(node))) { - /* viewers we execute, for feedback to user */ - if(ELEM(node->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER)) - node->typeinfo->execfunc(thd->rd, node, nsin, nsout); - else - node_compo_pass_on(node, nsin, nsout); - } - else if(node->typeinfo->execfunc) { - node->typeinfo->execfunc(thd->rd, node, nsin, nsout); - } - else if(node->type==NODE_GROUP && node->id) { - node_group_execute(thd->stack, thd->rd, node, nsin); - } - - node->exec |= NODE_READY; - return NULL; -} - -/* return total of executable nodes, for timecursor */ -/* only compositor uses it */ -static int setExecutableNodes(bNodeTree *ntree, ThreadData *thd) -{ - bNodeStack *nsin[MAX_SOCKET]; /* arbitrary... watch this */ - bNodeStack *nsout[MAX_SOCKET]; /* arbitrary... watch this */ - bNode *node; - bNodeSocket *sock; - int totnode= 0, group_edit= 0; - - /* note; do not add a dependency sort here, the stack was created already */ - - /* if we are in group edit, viewer nodes get skipped when group has viewer */ - for(node= ntree->nodes.first; node; node= node->next) - if(node->type==NODE_GROUP && (node->flag & NODE_GROUP_EDIT)) - if(ntreeHasType((bNodeTree *)node->id, CMP_NODE_VIEWER)) - group_edit= 1; - - for(node= ntree->nodes.first; node; node= node->next) { - int a; - - node_get_stack(node, thd->stack, nsin, nsout, NULL); - - /* test the outputs */ - /* skip value-only nodes (should be in type!) */ - if(!node_only_value(node)) { - for(a=0, sock= node->outputs.first; sock; sock= sock->next, a++) { - if(nsout[a]->data==NULL && nsout[a]->hasoutput) { - node->need_exec= 1; - break; - } - } - } - - /* test the inputs */ - for(a=0, sock= node->inputs.first; sock; sock= sock->next, a++) { - /* skip viewer nodes in bg render or group edit */ - if( ELEM(node->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER) && (G.background || group_edit)) - node->need_exec= 0; - /* is sock in use? */ - else if(sock->link) { - bNodeLink *link= sock->link; - - /* this is the test for a cyclic case */ - if(link->fromnode==NULL || link->tonode==NULL); - else if(link->fromnode->level >= link->tonode->level && link->tonode->level!=0xFFF) { - if(link->fromnode->need_exec) { - node->need_exec= 1; - break; - } - } - else { - node->need_exec= 0; - printf("Node %s skipped, cyclic dependency\n", node->name); - } - } - } - - if(node->need_exec) { - - /* free output buffers */ - for(a=0, sock= node->outputs.first; sock; sock= sock->next, a++) { - if(nsout[a]->data) { - free_compbuf(nsout[a]->data); - nsout[a]->data= NULL; - } - } - totnode++; - /* printf("node needs exec %s\n", node->name); */ - - /* tag for getExecutableNode() */ - node->exec= 0; - } - else { - /* tag for getExecutableNode() */ - node->exec= NODE_READY|NODE_FINISHED|NODE_SKIPPED; - - } - } - - /* last step: set the stack values for only-value nodes */ - /* just does all now, compared to a full buffer exec this is nothing */ - if(totnode) { - for(node= ntree->nodes.first; node; node= node->next) { - if(node->need_exec==0 && node_only_value(node)) { - if(node->typeinfo->execfunc) { - node_get_stack(node, thd->stack, nsin, nsout, NULL); - node->typeinfo->execfunc(thd->rd, node, nsin, nsout); - } - } - } - } - - return totnode; -} - -/* while executing tree, free buffers from nodes that are not needed anymore */ -static void freeExecutableNode(bNodeTree *ntree) -{ - /* node outputs can be freed when: - - not a render result or image node - - when node outputs go to nodes all being set NODE_FINISHED - */ - bNode *node; - bNodeSocket *sock; - - /* set exec flag for finished nodes that might need freed */ - for(node= ntree->nodes.first; node; node= node->next) { - if(node->type!=CMP_NODE_R_LAYERS) - if(node->exec & NODE_FINISHED) - node->exec |= NODE_FREEBUFS; - } - /* clear this flag for input links that are not done yet */ - for(node= ntree->nodes.first; node; node= node->next) { - if((node->exec & NODE_FINISHED)==0) { - for(sock= node->inputs.first; sock; sock= sock->next) - if(sock->link && sock->link->fromnode) - sock->link->fromnode->exec &= ~NODE_FREEBUFS; - } - } - /* now we can free buffers */ - for(node= ntree->nodes.first; node; node= node->next) { - if(node->exec & NODE_FREEBUFS) { - for(sock= node->outputs.first; sock; sock= sock->next) { - bNodeStack *ns= get_socket_stack(ntree->stack, sock, NULL); - if(ns && ns->data) { - free_compbuf(ns->data); - ns->data= NULL; - // printf("freed buf node %s \n", node->name); - } - } - } + ntemp.type = node->type; + return ntemp; } } -static bNode *getExecutableNode(bNodeTree *ntree) -{ - bNode *node; - bNodeSocket *sock; - - for(node= ntree->nodes.first; node; node= node->next) { - if(node->exec==0) { - - /* input sockets should be ready */ - for(sock= node->inputs.first; sock; sock= sock->next) { - if(sock->link && sock->link->fromnode) - if((sock->link->fromnode->exec & NODE_READY)==0) - break; - } - if(sock==NULL) - return node; - } - } - return NULL; -} - -/* check if texture nodes need exec or end */ -static void ntree_composite_texnode(bNodeTree *ntree, int init) -{ - bNode *node; - - for(node= ntree->nodes.first; node; node= node->next) { - if(node->type==CMP_NODE_TEXTURE && node->id) { - Tex *tex= (Tex *)node->id; - if(tex->nodetree && tex->use_nodes) { - /* has internal flag to detect it only does it once */ - if(init) - ntreeBeginExecTree(tex->nodetree); - else - ntreeEndExecTree(tex->nodetree); - } - } - } - -} - -/* optimized tree execute test for compositing */ -void ntreeCompositExecTree(bNodeTree *ntree, RenderData *rd, int do_preview) -{ - bNode *node; - ListBase threads; - ThreadData thdata; - int totnode, curnode, rendering= 1; - - if(ntree==NULL) return; - - if(do_preview) - ntreeInitPreview(ntree, 0, 0); - - ntreeBeginExecTree(ntree); - ntree_composite_texnode(ntree, 1); - - /* prevent unlucky accidents */ - if(G.background) - rd->scemode &= ~R_COMP_CROP; - - /* setup callerdata for thread callback */ - thdata.rd= rd; - thdata.stack= ntree->stack; - - /* fixed seed, for example noise texture */ - BLI_srandom(rd->cfra); - - /* sets need_exec tags in nodes */ - curnode = totnode= setExecutableNodes(ntree, &thdata); - - BLI_init_threads(&threads, exec_composite_node, rd->threads); - - while(rendering) { - - if(BLI_available_threads(&threads)) { - node= getExecutableNode(ntree); - if(node) { - if(ntree->progress && totnode) - ntree->progress(ntree->prh, (1.0f - curnode/(float)totnode)); - if(ntree->stats_draw) { - char str[64]; - sprintf(str, "Compositing %d %s", curnode, node->name); - ntree->stats_draw(ntree->sdh, str); - } - curnode--; - - node->threaddata = &thdata; - node->exec= NODE_PROCESSING; - BLI_insert_thread(&threads, node); - } - else - PIL_sleep_ms(50); - } - else - PIL_sleep_ms(50); - - rendering= 0; - /* test for ESC */ - if(ntree->test_break && ntree->test_break(ntree->tbh)) { - for(node= ntree->nodes.first; node; node= node->next) - node->exec |= NODE_READY; - } - - /* check for ready ones, and if we need to continue */ - for(node= ntree->nodes.first; node; node= node->next) { - if(node->exec & NODE_READY) { - if((node->exec & NODE_FINISHED)==0) { - BLI_remove_thread(&threads, node); /* this waits for running thread to finish btw */ - node->exec |= NODE_FINISHED; - - /* freeing unused buffers */ - if(rd->scemode & R_COMP_FREE) - freeExecutableNode(ntree); - } - } - else rendering= 1; - } - } - - BLI_end_threads(&threads); - - ntreeEndExecTree(ntree); -} - - -/* ********** copy composite tree entirely, to allow threaded exec ******************* */ -/* ***************** do NOT execute this in a thread! ****************** */ - -/* returns localized tree for execution in threads */ -/* local tree then owns all compbufs (for composite) */ -bNodeTree *ntreeLocalize(bNodeTree *ntree) -{ - bNodeTree *ltree; - bNode *node; - bNodeSocket *sock; - - bAction *action_backup= NULL, *tmpact_backup= NULL; - - /* Workaround for copying an action on each render! - * set action to NULL so animdata actions dont get copied */ - AnimData *adt= BKE_animdata_from_id(&ntree->id); - - if(adt) { - action_backup= adt->action; - tmpact_backup= adt->tmpact; - - adt->action= NULL; - adt->tmpact= NULL; - } - - /* node copy func */ - ltree= ntreeCopyTree(ntree); - - if(adt) { - AnimData *ladt= BKE_animdata_from_id(<ree->id); - - adt->action= ladt->action= action_backup; - adt->tmpact= ladt->tmpact= tmpact_backup; - - if(action_backup) action_backup->id.us++; - if(tmpact_backup) tmpact_backup->id.us++; - - } - /* end animdata uglyness */ - - /* ensures only a single output node is enabled */ - ntreeSetOutput(ltree); - - for(node= ntree->nodes.first; node; node= node->next) { - - /* store new_node pointer to original */ - node->new_node->new_node= node; - - if(ntree->type==NTREE_COMPOSIT) { - /* ensure new user input gets handled ok, only composites (texture nodes will break, for painting since it uses no tags) */ - node->need_exec= 0; - - /* move over the compbufs */ - /* right after ntreeCopyTree() oldsock pointers are valid */ - - if(ELEM(node->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER)) { - if(node->id) { - if(node->flag & NODE_DO_OUTPUT) - node->new_node->id= (ID *)copy_image((Image *)node->id); - else - node->new_node->id= NULL; - } - } - - for(sock= node->outputs.first; sock; sock= sock->next) { - - sock->new_sock->ns.data= sock->ns.data; - compbuf_set_node(sock->new_sock->ns.data, node->new_node); - - sock->ns.data= NULL; - sock->new_sock->new_sock= sock; - } - } - } - - return ltree; -} - -static int node_exists(bNodeTree *ntree, bNode *testnode) -{ - bNode *node= ntree->nodes.first; - for(; node; node= node->next) - if(node==testnode) - return 1; - return 0; -} - -static int outsocket_exists(bNode *node, bNodeSocket *testsock) -{ - bNodeSocket *sock= node->outputs.first; - for(; sock; sock= sock->next) - if(sock==testsock) - return 1; - return 0; -} - - -/* sync local composite with real tree */ -/* local composite is supposed to be running, be careful moving previews! */ -/* is called by jobs manager, outside threads, so it doesnt happen during draw */ -void ntreeLocalSync(bNodeTree *localtree, bNodeTree *ntree) -{ - bNode *lnode; - - if(ntree->type==NTREE_COMPOSIT) { - /* move over the compbufs and previews */ - for(lnode= localtree->nodes.first; lnode; lnode= lnode->next) { - if( (lnode->exec & NODE_READY) && !(lnode->exec & NODE_SKIPPED) ) { - if(node_exists(ntree, lnode->new_node)) { - - if(lnode->preview && lnode->preview->rect) { - node_free_preview(lnode->new_node); - lnode->new_node->preview= lnode->preview; - lnode->preview= NULL; - } - } - } - } - } - else if(ELEM(ntree->type, NTREE_SHADER, NTREE_TEXTURE)) { - /* copy over contents of previews */ - for(lnode= localtree->nodes.first; lnode; lnode= lnode->next) { - if(node_exists(ntree, lnode->new_node)) { - bNode *node= lnode->new_node; - - if(node->preview && node->preview->rect) { - if(lnode->preview && lnode->preview->rect) { - int xsize= node->preview->xsize; - int ysize= node->preview->ysize; - memcpy(node->preview->rect, lnode->preview->rect, 4*xsize + xsize*ysize*sizeof(char)*4); - } - } - } - } - } -} - -/* merge local tree results back, and free local tree */ -/* we have to assume the editor already changed completely */ -void ntreeLocalMerge(bNodeTree *localtree, bNodeTree *ntree) -{ - bNode *lnode; - bNodeSocket *lsock; - - /* move over the compbufs and previews */ - for(lnode= localtree->nodes.first; lnode; lnode= lnode->next) { - if(node_exists(ntree, lnode->new_node)) { - - if(lnode->preview && lnode->preview->rect) { - node_free_preview(lnode->new_node); - lnode->new_node->preview= lnode->preview; - lnode->preview= NULL; - } - - if(ELEM(lnode->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER)) { - if(lnode->id && (lnode->flag & NODE_DO_OUTPUT)) { - /* image_merge does sanity check for pointers */ - BKE_image_merge((Image *)lnode->new_node->id, (Image *)lnode->id); - } - } - - for(lsock= lnode->outputs.first; lsock; lsock= lsock->next) { - if(outsocket_exists(lnode->new_node, lsock->new_sock)) { - lsock->new_sock->ns.data= lsock->ns.data; - compbuf_set_node(lsock->new_sock->ns.data, lnode->new_node); - lsock->ns.data= NULL; - lsock->new_sock= NULL; - } - } - } - } - ntreeFreeTree(localtree); - MEM_freeN(localtree); -} - -/* *********************************************** */ - -/* GPU material from shader nodes */ - -static void gpu_from_node_stack(ListBase *sockets, bNodeStack **ns, GPUNodeStack *gs) -{ - bNodeSocket *sock; - int i; - - for (sock=sockets->first, i=0; sock; sock=sock->next, i++) { - memset(&gs[i], 0, sizeof(gs[i])); - - QUATCOPY(gs[i].vec, ns[i]->vec); - gs[i].link= ns[i]->data; - - if (sock->type == SOCK_VALUE) - gs[i].type= GPU_FLOAT; - else if (sock->type == SOCK_VECTOR) - gs[i].type= GPU_VEC3; - else if (sock->type == SOCK_RGBA) - gs[i].type= GPU_VEC4; - else - gs[i].type= GPU_NONE; - - gs[i].name = ""; - gs[i].hasinput= ns[i]->hasinput && ns[i]->data; - gs[i].hasoutput= ns[i]->hasoutput && ns[i]->data; - gs[i].sockettype= ns[i]->sockettype; - } - - gs[i].type= GPU_NONE; -} - -static void data_from_gpu_stack(ListBase *sockets, bNodeStack **ns, GPUNodeStack *gs) -{ - bNodeSocket *sock; - int i; - - for (sock=sockets->first, i=0; sock; sock=sock->next, i++) { - ns[i]->data= gs[i].link; - ns[i]->sockettype= gs[i].sockettype; - } -} - -static void gpu_node_group_execute(bNodeStack *stack, GPUMaterial *mat, bNode *gnode, bNodeStack **in) -{ - bNode *node; - bNodeTree *ntree= (bNodeTree *)gnode->id; - bNodeStack *nsin[MAX_SOCKET]; /* arbitrary... watch this */ - bNodeStack *nsout[MAX_SOCKET]; /* arbitrary... watch this */ - GPUNodeStack gpuin[MAX_SOCKET+1], gpuout[MAX_SOCKET+1]; - int doit = 0; - - if(ntree==NULL) return; - - stack+= gnode->stack_index; - - for(node= ntree->nodes.first; node; node= node->next) { - if(node->typeinfo->gpufunc) { - node_get_stack(node, stack, nsin, nsout, in); - - doit = 0; - - /* for groups, only execute outputs for edited group */ - if(node->typeinfo->nclass==NODE_CLASS_OUTPUT) { - if(gnode->flag & NODE_GROUP_EDIT) - if(node->flag & NODE_DO_OUTPUT) - doit = 1; - } - else - doit = 1; - - if(doit) { - gpu_from_node_stack(&node->inputs, nsin, gpuin); - gpu_from_node_stack(&node->outputs, nsout, gpuout); - if(node->typeinfo->gpufunc(mat, node, gpuin, gpuout)) - data_from_gpu_stack(&node->outputs, nsout, gpuout); - } - } - } -} - -void ntreeGPUMaterialNodes(bNodeTree *ntree, GPUMaterial *mat) -{ - bNode *node; - bNodeStack *stack; - bNodeStack *nsin[MAX_SOCKET]; /* arbitrary... watch this */ - bNodeStack *nsout[MAX_SOCKET]; /* arbitrary... watch this */ - GPUNodeStack gpuin[MAX_SOCKET+1], gpuout[MAX_SOCKET+1]; - - if((ntree->init & NTREE_EXEC_INIT)==0) - ntreeBeginExecTree(ntree); - - stack= ntree->stack; - - for(node= ntree->nodes.first; node; node= node->next) { - if(node->typeinfo->gpufunc) { - node_get_stack(node, stack, nsin, nsout, NULL); - gpu_from_node_stack(&node->inputs, nsin, gpuin); - gpu_from_node_stack(&node->outputs, nsout, gpuout); - if(node->typeinfo->gpufunc(mat, node, gpuin, gpuout)) - data_from_gpu_stack(&node->outputs, nsout, gpuout); - } - else if(node->type==NODE_GROUP && node->id) { - node_get_stack(node, stack, nsin, nsout, NULL); - gpu_node_group_execute(stack, mat, node, nsin); - } - } - - ntreeEndExecTree(ntree); -} - -/* **************** call to switch lamploop for material node ************ */ - -void (*node_shader_lamp_loop)(struct ShadeInput *, struct ShadeResult *); - -void set_node_shader_lamp_loop(void (*lamp_loop_func)(ShadeInput *, ShadeResult *)) -{ - node_shader_lamp_loop= lamp_loop_func; -} - -/* clumsy checking... should do dynamic outputs once */ -static void force_hidden_passes(bNode *node, int passflag) -{ - bNodeSocket *sock; - - for(sock= node->outputs.first; sock; sock= sock->next) - sock->flag &= ~SOCK_UNAVAIL; - - sock= BLI_findlink(&node->outputs, RRES_OUT_Z); - if(!(passflag & SCE_PASS_Z)) sock->flag |= SOCK_UNAVAIL; - sock= BLI_findlink(&node->outputs, RRES_OUT_NORMAL); - if(!(passflag & SCE_PASS_NORMAL)) sock->flag |= SOCK_UNAVAIL; - sock= BLI_findlink(&node->outputs, RRES_OUT_VEC); - if(!(passflag & SCE_PASS_VECTOR)) sock->flag |= SOCK_UNAVAIL; - sock= BLI_findlink(&node->outputs, RRES_OUT_UV); - if(!(passflag & SCE_PASS_UV)) sock->flag |= SOCK_UNAVAIL; - sock= BLI_findlink(&node->outputs, RRES_OUT_RGBA); - if(!(passflag & SCE_PASS_RGBA)) sock->flag |= SOCK_UNAVAIL; - sock= BLI_findlink(&node->outputs, RRES_OUT_DIFF); - if(!(passflag & SCE_PASS_DIFFUSE)) sock->flag |= SOCK_UNAVAIL; - sock= BLI_findlink(&node->outputs, RRES_OUT_SPEC); - if(!(passflag & SCE_PASS_SPEC)) sock->flag |= SOCK_UNAVAIL; - sock= BLI_findlink(&node->outputs, RRES_OUT_SHADOW); - if(!(passflag & SCE_PASS_SHADOW)) sock->flag |= SOCK_UNAVAIL; - sock= BLI_findlink(&node->outputs, RRES_OUT_AO); - if(!(passflag & SCE_PASS_AO)) sock->flag |= SOCK_UNAVAIL; - sock= BLI_findlink(&node->outputs, RRES_OUT_REFLECT); - if(!(passflag & SCE_PASS_REFLECT)) sock->flag |= SOCK_UNAVAIL; - sock= BLI_findlink(&node->outputs, RRES_OUT_REFRACT); - if(!(passflag & SCE_PASS_REFRACT)) sock->flag |= SOCK_UNAVAIL; - sock= BLI_findlink(&node->outputs, RRES_OUT_INDIRECT); - if(!(passflag & SCE_PASS_INDIRECT)) sock->flag |= SOCK_UNAVAIL; - sock= BLI_findlink(&node->outputs, RRES_OUT_INDEXOB); - if(!(passflag & SCE_PASS_INDEXOB)) sock->flag |= SOCK_UNAVAIL; - sock= BLI_findlink(&node->outputs, RRES_OUT_INDEXMA); - if(!(passflag & SCE_PASS_INDEXMA)) sock->flag |= SOCK_UNAVAIL; - sock= BLI_findlink(&node->outputs, RRES_OUT_MIST); - if(!(passflag & SCE_PASS_MIST)) sock->flag |= SOCK_UNAVAIL; - sock= BLI_findlink(&node->outputs, RRES_OUT_EMIT); - if(!(passflag & SCE_PASS_EMIT)) sock->flag |= SOCK_UNAVAIL; - sock= BLI_findlink(&node->outputs, RRES_OUT_ENV); - if(!(passflag & SCE_PASS_ENVIRONMENT)) sock->flag |= SOCK_UNAVAIL; - -} - -/* based on rules, force sockets hidden always */ -void ntreeCompositForceHidden(bNodeTree *ntree, Scene *curscene) -{ - bNode *node; - - if(ntree==NULL) return; - - for(node= ntree->nodes.first; node; node= node->next) { - if( node->type==CMP_NODE_R_LAYERS) { - Scene *sce= node->id?(Scene *)node->id:curscene; - SceneRenderLayer *srl= BLI_findlink(&sce->r.layers, node->custom1); - if(srl) - force_hidden_passes(node, srl->passflag); - } - else if( node->type==CMP_NODE_IMAGE) { - Image *ima= (Image *)node->id; - if(ima) { - if(ima->rr) { - ImageUser *iuser= node->storage; - RenderLayer *rl= BLI_findlink(&ima->rr->layers, iuser->layer); - if(rl) - force_hidden_passes(node, rl->passflag); - else - force_hidden_passes(node, 0); - } - else if(ima->type!=IMA_TYPE_MULTILAYER) { /* if ->rr not yet read we keep inputs */ - force_hidden_passes(node, RRES_OUT_Z); - } - else - force_hidden_passes(node, 0); - } - else - force_hidden_passes(node, 0); - } - } - -} - -/* called from render pipeline, to tag render input and output */ -/* need to do all scenes, to prevent errors when you re-render 1 scene */ -void ntreeCompositTagRender(Scene *curscene) -{ - Scene *sce; - - for(sce= G.main->scene.first; sce; sce= sce->id.next) { - if(sce->nodetree) { - bNode *node; - - for(node= sce->nodetree->nodes.first; node; node= node->next) { - if(node->id==(ID *)curscene || node->type==CMP_NODE_COMPOSITE) - NodeTagChanged(sce->nodetree, node); - else if(node->type==CMP_NODE_TEXTURE) /* uses scene sizex/sizey */ - NodeTagChanged(sce->nodetree, node); - } - } - } -} - -static int node_animation_properties(bNodeTree *ntree, bNode *node) -{ - bNodeSocket *sock; - const ListBase *lb; - Link *link; - PointerRNA ptr; - PropertyRNA *prop; - - /* check to see if any of the node's properties have fcurves */ - RNA_pointer_create((ID *)ntree, &RNA_Node, node, &ptr); - lb = RNA_struct_type_properties(ptr.type); - - for (link=lb->first; link; link=link->next) { - int driven, len=1, index; - prop = (PropertyRNA *)link; - - if (RNA_property_array_check(prop)) - len = RNA_property_array_length(&ptr, prop); - - for (index=0; indexinputs.first; sock; sock=sock->next) { - int driven, len=1, index; - - RNA_pointer_create((ID *)ntree, &RNA_NodeSocket, sock, &ptr); - prop = RNA_struct_find_property(&ptr, "default_value"); - - if (RNA_property_array_check(prop)) - len = RNA_property_array_length(&ptr, prop); - - for (index=0; indexnodes.first; node; node= node->next) { - - tagged = node_animation_properties(ntree, node); - - /* otherwise always tag these node types */ - if(node->type==CMP_NODE_IMAGE) { - Image *ima= (Image *)node->id; - if(ima && ELEM(ima->source, IMA_SRC_MOVIE, IMA_SRC_SEQUENCE)) { - NodeTagChanged(ntree, node); - tagged= 1; - } - } - else if(node->type==CMP_NODE_TIME) { - NodeTagChanged(ntree, node); - tagged= 1; - } - /* here was tag render layer, but this is called after a render, so re-composites fail */ - else if(node->type==NODE_GROUP) { - if( ntreeCompositTagAnimated((bNodeTree *)node->id) ) { - NodeTagChanged(ntree, node); - } - } - } - - return tagged; -} - - -/* called from image window preview */ -void ntreeCompositTagGenerators(bNodeTree *ntree) -{ - bNode *node; - - if(ntree==NULL) return; - - for(node= ntree->nodes.first; node; node= node->next) { - if( ELEM(node->type, CMP_NODE_R_LAYERS, CMP_NODE_IMAGE)) - NodeTagChanged(ntree, node); - } -} - -/* XXX after render animation system gets a refresh, this call allows composite to end clean */ -void ntreeClearTags(bNodeTree *ntree) -{ - bNode *node; - - if(ntree==NULL) return; - - for(node= ntree->nodes.first; node; node= node->next) { - node->need_exec= 0; - if(node->type==NODE_GROUP) - ntreeClearTags((bNodeTree *)node->id); - } -} - - -int ntreeTexTagAnimated(bNodeTree *ntree) -{ - bNode *node; - - if(ntree==NULL) return 0; - - for(node= ntree->nodes.first; node; node= node->next) { - if(node->type==TEX_NODE_CURVE_TIME) { - NodeTagChanged(ntree, node); - return 1; - } - else if(node->type==NODE_GROUP) { - if( ntreeTexTagAnimated((bNodeTree *)node->id) ) { - return 1; - } - } - } - - return 0; -} - -/* ************* node definition init ********** */ - -void node_type_base(bNodeType *ntype, int type, const char *name, short nclass, short flag, - struct bNodeSocketType *inputs, struct bNodeSocketType *outputs) +void node_type_base(bNodeType *ntype, int type, const char *name, short nclass, short flag) { memset(ntype, 0, sizeof(bNodeType)); ntype->type = type; - ntype->name = name; + BLI_strncpy(ntype->name, name, sizeof(ntype->name)); ntype->nclass = nclass; ntype->flag = flag; - ntype->inputs = inputs; - ntype->outputs = outputs; - /* default size values */ ntype->width = 140; ntype->minwidth = 100; ntype->maxwidth = 320; + ntype->height = 100; + ntype->minheight = 30; + ntype->maxheight = FLT_MAX; } -void node_type_init(bNodeType *ntype, void (*initfunc)(struct bNode *)) +void node_type_socket_templates(struct bNodeType *ntype, struct bNodeSocketTemplate *inputs, struct bNodeSocketTemplate *outputs) +{ + ntype->inputs = inputs; + ntype->outputs = outputs; +} + +void node_type_init(struct bNodeType *ntype, void (*initfunc)(struct bNodeTree *ntree, struct bNode *node, struct bNodeTemplate *ntemp)) { ntype->initfunc = initfunc; } +void node_type_valid(struct bNodeType *ntype, int (*validfunc)(struct bNodeTree *ntree, struct bNodeTemplate *ntemp)) +{ + ntype->validfunc = validfunc; +} + void node_type_size(struct bNodeType *ntype, int width, int minwidth, int maxwidth) { ntype->width = width; ntype->minwidth = minwidth; - ntype->maxwidth = maxwidth; + if (maxwidth <= minwidth) + ntype->maxwidth = FLT_MAX; + else + ntype->maxwidth = maxwidth; } void node_type_storage(bNodeType *ntype, const char *storagename, void (*freestoragefunc)(struct bNode *), void (*copystoragefunc)(struct bNode *, struct bNode *)) @@ -3403,47 +1675,92 @@ void node_type_storage(bNodeType *ntype, const char *storagename, void (*freesto ntype->freestoragefunc = freestoragefunc; } +void node_type_label(struct bNodeType *ntype, const char *(*labelfunc)(struct bNode *)) +{ + ntype->labelfunc = labelfunc; +} + +void node_type_template(struct bNodeType *ntype, struct bNodeTemplate (*templatefunc)(struct bNode *)) +{ + ntype->templatefunc = templatefunc; +} + +void node_type_update(struct bNodeType *ntype, + void (*updatefunc)(struct bNodeTree *ntree, struct bNode *node), + void (*verifyfunc)(struct bNodeTree *ntree, struct bNode *node, struct ID *id)) +{ + ntype->updatefunc = updatefunc; + ntype->verifyfunc = verifyfunc; +} + +void node_type_tree(struct bNodeType *ntype, void (*inittreefunc)(struct bNodeTree *), void (*updatetreefunc)(struct bNodeTree *)) +{ + ntype->inittreefunc = inittreefunc; + ntype->updatetreefunc = updatetreefunc; +} + +void node_type_group_edit(struct bNodeType *ntype, + struct bNodeTree *(*group_edit_get)(struct bNode *node), + struct bNodeTree *(*group_edit_set)(struct bNode *node, int edit), + void (*group_edit_clear)(struct bNode *node)) +{ + ntype->group_edit_get = group_edit_get; + ntype->group_edit_set = group_edit_set; + ntype->group_edit_clear = group_edit_clear; +} + void node_type_exec(struct bNodeType *ntype, void (*execfunc)(void *data, struct bNode *, struct bNodeStack **, struct bNodeStack **)) { ntype->execfunc = execfunc; } +void node_type_exec_new(struct bNodeType *ntype, + void *(*initexecfunc)(struct bNode *node), + void (*freeexecfunc)(struct bNode *node, void *nodedata), + void (*newexecfunc)(void *data, int thread, struct bNode *, void *nodedata, struct bNodeStack **, struct bNodeStack **)) +{ + ntype->initexecfunc = initexecfunc; + ntype->freeexecfunc = freeexecfunc; + ntype->newexecfunc = newexecfunc; +} + void node_type_gpu(struct bNodeType *ntype, int (*gpufunc)(struct GPUMaterial *mat, struct bNode *node, struct GPUNodeStack *in, struct GPUNodeStack *out)) { ntype->gpufunc = gpufunc; } -void node_type_label(struct bNodeType *ntype, const char *(*labelfunc)(struct bNode *)) +void node_type_gpu_ext(struct bNodeType *ntype, int (*gpuextfunc)(struct GPUMaterial *mat, struct bNode *node, void *nodedata, struct GPUNodeStack *in, struct GPUNodeStack *out)) { - ntype->labelfunc = labelfunc; + ntype->gpuextfunc = gpuextfunc; } -static bNodeType *is_nodetype_registered(ListBase *typelist, int type, ID *id) + +static bNodeType *is_nodetype_registered(ListBase *typelist, int type) { bNodeType *ntype= typelist->first; for(;ntype; ntype= ntype->next ) - if(ntype->type==type && ntype->id==id) + if(ntype->type==type) return ntype; return NULL; } -/* type can be from a static array, we make copy for duplicate types (like group) */ -void nodeRegisterType(ListBase *typelist, const bNodeType *ntype) +void nodeRegisterType(ListBase *typelist, bNodeType *ntype) { - bNodeType *found= is_nodetype_registered(typelist, ntype->type, ntype->id); + bNodeType *found= is_nodetype_registered(typelist, ntype->type); - if(found==NULL) { - bNodeType *ntypen= MEM_callocN(sizeof(bNodeType), "node type"); - *ntypen= *ntype; - BLI_addtail(typelist, ntypen); - } + if(found==NULL) + BLI_addtail(typelist, ntype); } static void registerCompositNodes(ListBase *ntypelist) { - register_node_type_group(ntypelist); + register_node_type_frame(ntypelist); + + register_node_type_cmp_group(ntypelist); +// register_node_type_cmp_forloop(ntypelist); +// register_node_type_cmp_whileloop(ntypelist); register_node_type_cmp_rlayers(ntypelist); register_node_type_cmp_image(ntypelist); @@ -3519,7 +1836,11 @@ static void registerCompositNodes(ListBase *ntypelist) static void registerShaderNodes(ListBase *ntypelist) { - register_node_type_group(ntypelist); + register_node_type_frame(ntypelist); + + register_node_type_sh_group(ntypelist); +// register_node_type_sh_forloop(ntypelist); +// register_node_type_sh_whileloop(ntypelist); register_node_type_sh_output(ntypelist); register_node_type_sh_mix_rgb(ntypelist); @@ -3548,7 +1869,11 @@ static void registerShaderNodes(ListBase *ntypelist) static void registerTextureNodes(ListBase *ntypelist) { - register_node_type_group(ntypelist); + register_node_type_frame(ntypelist); + + register_node_type_tex_group(ntypelist); +// register_node_type_tex_forloop(ntypelist); +// register_node_type_tex_whileloop(ntypelist); register_node_type_tex_math(ntypelist); register_node_type_tex_mix_rgb(ntypelist); @@ -3589,53 +1914,47 @@ static void registerTextureNodes(ListBase *ntypelist) register_node_type_tex_proc_distnoise(ntypelist); } -static void remove_dynamic_typeinfos(ListBase *list) +static void free_dynamic_typeinfo(bNodeType *ntype) { - bNodeType *ntype= list->first; - bNodeType *next= NULL; - while(ntype) { - next= ntype->next; - if(ntype->type==NODE_DYNAMIC && ntype->id!=NULL) { - BLI_remlink(list, ntype); - if(ntype->inputs) { - bNodeSocketType *sock= ntype->inputs; - while(sock->type!=-1) { - MEM_freeN((void *)sock->name); - sock++; - } - MEM_freeN(ntype->inputs); - } - if(ntype->outputs) { - bNodeSocketType *sock= ntype->outputs; - while(sock->type!=-1) { - MEM_freeN((void *)sock->name); - sock++; - } - MEM_freeN(ntype->outputs); - } - if(ntype->name) { - MEM_freeN((void *)ntype->name); - } - MEM_freeN(ntype); + if(ntype->type==NODE_DYNAMIC) { + if(ntype->inputs) { + MEM_freeN(ntype->inputs); } - ntype= next; + if(ntype->outputs) { + MEM_freeN(ntype->outputs); + } + if(ntype->name) { + MEM_freeN((void *)ntype->name); + } + } +} + +static void free_typeinfos(ListBase *list) +{ + bNodeType *ntype, *next; + for(ntype=list->first; ntype; ntype=next) { + next = ntype->next; + + if(ntype->type==NODE_DYNAMIC) + free_dynamic_typeinfo(ntype); + + if(ntype->needs_free) + MEM_freeN(ntype); } } void init_nodesystem(void) { - registerCompositNodes(&node_all_composit); - registerShaderNodes(&node_all_shaders); - registerTextureNodes(&node_all_textures); + registerCompositNodes(&ntreeGetType(NTREE_COMPOSIT)->node_types); + registerShaderNodes(&ntreeGetType(NTREE_SHADER)->node_types); + registerTextureNodes(&ntreeGetType(NTREE_TEXTURE)->node_types); } void free_nodesystem(void) { - /*remove_dynamic_typeinfos(&node_all_composit);*/ /* unused for now */ - BLI_freelistN(&node_all_composit); - remove_dynamic_typeinfos(&node_all_shaders); - BLI_freelistN(&node_all_shaders); - BLI_freelistN(&node_all_textures); + free_typeinfos(&ntreeGetType(NTREE_COMPOSIT)->node_types); + free_typeinfos(&ntreeGetType(NTREE_SHADER)->node_types); + free_typeinfos(&ntreeGetType(NTREE_TEXTURE)->node_types); } /* called from unlink_scene, when deleting a scene goes over all scenes diff --git a/source/blender/blenkernel/intern/texture.c b/source/blender/blenkernel/intern/texture.c index 493baebd197..6119a855366 100644 --- a/source/blender/blenkernel/intern/texture.c +++ b/source/blender/blenkernel/intern/texture.c @@ -766,7 +766,9 @@ Tex *copy_texture(Tex *tex) if(tex->preview) texn->preview = BKE_previewimg_copy(tex->preview); if(tex->nodetree) { - ntreeEndExecTree(tex->nodetree); + if (tex->nodetree->execdata) { + ntreeTexEndExecTree(tex->nodetree->execdata); + } texn->nodetree= ntreeCopyTree(tex->nodetree); } diff --git a/source/blender/blenlib/BLI_math_matrix.h b/source/blender/blenlib/BLI_math_matrix.h index d8719f399ae..18955c158c6 100644 --- a/source/blender/blenlib/BLI_math_matrix.h +++ b/source/blender/blenlib/BLI_math_matrix.h @@ -66,6 +66,9 @@ void swap_m4m4(float A[4][4], float B[4][4]); void add_m3_m3m3(float R[3][3], float A[3][3], float B[3][3]); void add_m4_m4m4(float R[4][4], float A[4][4], float B[4][4]); +void sub_m3_m3m3(float R[3][3], float A[3][3], float B[3][3]); +void sub_m4_m4m4(float R[4][4], float A[4][4], float B[4][4]); + void mul_m3_m3m3(float R[3][3], float A[3][3], float B[3][3]); void mul_m4_m4m4(float R[4][4], float A[4][4], float B[4][4]); void mul_m4_m3m4(float R[4][4], float A[3][3], float B[4][4]); diff --git a/source/blender/blenlib/BLI_math_vector.h b/source/blender/blenlib/BLI_math_vector.h index c8b598a1e85..d30168c8657 100644 --- a/source/blender/blenlib/BLI_math_vector.h +++ b/source/blender/blenlib/BLI_math_vector.h @@ -124,6 +124,7 @@ void interp_v3_v3v3v3(float p[3], const float v1[3], const float v2[3], const fl void interp_v3_v3v3v3v3(float p[3], const float v1[3], const float v2[3], const float v3[3], const float v4[3], const float w[4]); void interp_v4_v4v4(float r[4], const float a[4], const float b[4], const float t); void interp_v4_v4v4v4(float p[4], const float v1[4], const float v2[4], const float v3[4], const float w[3]); +void interp_v4_v4v4v4v4(float p[4], const float v1[4], const float v2[4], const float v3[4], const float v4[4], const float w[4]); void mid_v3_v3v3(float r[3], const float a[3], const float b[3]); diff --git a/source/blender/blenlib/intern/math_matrix.c b/source/blender/blenlib/intern/math_matrix.c index 3c79a77707a..e2f594376cb 100644 --- a/source/blender/blenlib/intern/math_matrix.c +++ b/source/blender/blenlib/intern/math_matrix.c @@ -451,6 +451,24 @@ void add_m4_m4m4(float m1[][4], float m2[][4], float m3[][4]) m1[i][j]= m2[i][j] + m3[i][j]; } +void sub_m3_m3m3(float m1[][3], float m2[][3], float m3[][3]) +{ + int i, j; + + for(i=0;i<3;i++) + for(j=0;j<3;j++) + m1[i][j]= m2[i][j] - m3[i][j]; +} + +void sub_m4_m4m4(float m1[][4], float m2[][4], float m3[][4]) +{ + int i, j; + + for(i=0;i<4;i++) + for(j=0;j<4;j++) + m1[i][j]= m2[i][j] - m3[i][j]; +} + int invert_m3(float m[3][3]) { float tmp[3][3]; diff --git a/source/blender/blenlib/intern/math_vector.c b/source/blender/blenlib/intern/math_vector.c index 15d671e38d7..7dbceff46e4 100644 --- a/source/blender/blenlib/intern/math_vector.c +++ b/source/blender/blenlib/intern/math_vector.c @@ -96,6 +96,14 @@ void interp_v4_v4v4v4(float p[4], const float v1[4], const float v2[4], const fl p[3] = v1[3]*w[0] + v2[3]*w[1] + v3[3]*w[2]; } +void interp_v4_v4v4v4v4(float p[4], const float v1[4], const float v2[4], const float v3[4], const float v4[4], const float w[4]) +{ + p[0] = v1[0]*w[0] + v2[0]*w[1] + v3[0]*w[2] + v4[0]*w[3]; + p[1] = v1[1]*w[0] + v2[1]*w[1] + v3[1]*w[2] + v4[1]*w[3]; + p[2] = v1[2]*w[0] + v2[2]*w[1] + v3[2]*w[2] + v4[2]*w[3]; + p[3] = v1[3]*w[0] + v2[3]*w[1] + v3[3]*w[2] + v4[3]*w[3]; +} + void mid_v3_v3v3(float v[3], const float v1[3], const float v2[3]) { v[0]= 0.5f*(v1[0] + v2[0]); diff --git a/source/blender/blenloader/CMakeLists.txt b/source/blender/blenloader/CMakeLists.txt index 4088481c844..ab00a8e90dd 100644 --- a/source/blender/blenloader/CMakeLists.txt +++ b/source/blender/blenloader/CMakeLists.txt @@ -30,6 +30,7 @@ set(INC ../blenlib ../makesdna ../makesrna + ../nodes ../render/extern/include ../../../intern/guardedalloc ) diff --git a/source/blender/blenloader/SConscript b/source/blender/blenloader/SConscript index be9908d84e6..d5d2df3ea35 100644 --- a/source/blender/blenloader/SConscript +++ b/source/blender/blenloader/SConscript @@ -5,7 +5,7 @@ sources = env.Glob('intern/*.c') incs = '. #/intern/guardedalloc ../blenlib ../blenkernel' incs += ' ../makesdna ../editors/include' -incs += ' ../render/extern/include ../makesrna' +incs += ' ../render/extern/include ../makesrna ../nodes' incs += ' ' + env['BF_ZLIB_INC'] diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 363e98d7a4b..355fc14705a 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -134,6 +134,8 @@ #include "BKE_utildefines.h" // SWITCH_INT DATA ENDB DNA1 O_BINARY GLOB USER TEST REND #include "BKE_sound.h" +#include "NOD_socket.h" + //XXX #include "BIF_butspace.h" // badlevel, for do_versions, patching event codes //XXX #include "BIF_filelist.h" // badlevel too, where to move this? - elubie //XXX #include "BIF_previewrender.h" // bedlelvel, for struct RenderInfo @@ -2052,10 +2054,21 @@ static void lib_link_nodetree(FileData *fd, Main *main) } } +static void lib_nodetree_init_types_cb(void *UNUSED(data), ID *UNUSED(id), bNodeTree *ntree) +{ + bNode *node; + + ntreeInitTypes(ntree); + + /* XXX could be replaced by do_versions for new nodes */ + for (node=ntree->nodes.first; node; node=node->next) + node_verify_socket_templates(ntree, node); +} + /* updates group node socket own_index so that * external links to/from the group node are preserved. */ -static void lib_node_do_versions_group(bNode *gnode) +static void lib_node_do_versions_group_indices(bNode *gnode) { bNodeTree *ngroup= (bNodeTree*)gnode->id; bNode *intnode; @@ -2088,92 +2101,101 @@ static void lib_node_do_versions_group(bNode *gnode) } /* updates external links for all group nodes in a tree */ -static void lib_nodetree_do_versions_group(bNodeTree *ntree) +static void lib_nodetree_do_versions_group_indices_cb(void *UNUSED(data), ID *UNUSED(id), bNodeTree *ntree) { bNode *node; for (node=ntree->nodes.first; node; node=node->next) { if (node->type==NODE_GROUP) { bNodeTree *ngroup= (bNodeTree*)node->id; - if (ngroup && (ngroup->flag & NTREE_DO_VERSIONS)) - lib_node_do_versions_group(node); + if (ngroup && (ngroup->flag & NTREE_DO_VERSIONS_GROUP_EXPOSE)) + lib_node_do_versions_group_indices(node); } } } +/* make an update call for the tree */ +static void lib_nodetree_do_versions_update_cb(void *UNUSED(data), ID *UNUSED(id), bNodeTree *ntree) +{ + if (ntree->update) + ntreeUpdateTree(ntree); +} + /* verify types for nodes and groups, all data has to be read */ /* open = 0: appending/linking, open = 1: open new file (need to clean out dynamic * typedefs*/ static void lib_verify_nodetree(Main *main, int UNUSED(open)) { - Scene *sce; - Material *ma; - Tex *tx; bNodeTree *ntree; - + int i; + bNodeTreeType *ntreetype; + /* this crashes blender on undo/redo if(open==1) { reinit_nodesystem(); }*/ - /* now create the own typeinfo structs an verify nodes */ - /* here we still assume no groups in groups */ - for(ntree= main->nodetree.first; ntree; ntree= ntree->id.next) { - ntreeVerifyTypes(ntree); /* internal nodes, no groups! */ + /* set node->typeinfo pointers */ + for (i=0; i < NUM_NTREE_TYPES; ++i) { + ntreetype= ntreeGetType(i); + if (ntreetype && ntreetype->foreach_nodetree) + ntreetype->foreach_nodetree(main, NULL, lib_nodetree_init_types_cb); } + for(ntree= main->nodetree.first; ntree; ntree= ntree->id.next) + ntreeInitTypes(ntree); { - /*int has_old_groups=0;*/ /*UNUSED*/ + int has_old_groups=0; /* XXX this should actually be part of do_versions, but since we need * finished library linking, it is not possible there. Instead in do_versions * we have set the NTREE_DO_VERSIONS flag, so at this point we can do the * actual group node updates. */ for(ntree= main->nodetree.first; ntree; ntree= ntree->id.next) { - if (ntree->flag & NTREE_DO_VERSIONS) { + if (ntree->flag & NTREE_DO_VERSIONS_GROUP_EXPOSE) { /* this adds copies and links from all unlinked internal sockets to group inputs/outputs. */ - nodeGroupExposeAllSockets(ntree); - /*has_old_groups = 1;*/ /*UNUSED*/ + node_group_expose_all_sockets(ntree); + has_old_groups = 1; } } - /* now verify all types in material trees, groups are set OK now */ - for(ma= main->mat.first; ma; ma= ma->id.next) { - if(ma->nodetree) - lib_nodetree_do_versions_group(ma->nodetree); - } - /* and scene trees */ - for(sce= main->scene.first; sce; sce= sce->id.next) { - if(sce->nodetree) - lib_nodetree_do_versions_group(sce->nodetree); - } - /* and texture trees */ - for(tx= main->tex.first; tx; tx= tx->id.next) { - if(tx->nodetree) - lib_nodetree_do_versions_group(tx->nodetree); + + if (has_old_groups) { + for (i=0; i < NUM_NTREE_TYPES; ++i) { + ntreetype= ntreeGetType(i); + if (ntreetype && ntreetype->foreach_nodetree) + ntreetype->foreach_nodetree(main, NULL, lib_nodetree_do_versions_group_indices_cb); + } } for(ntree= main->nodetree.first; ntree; ntree= ntree->id.next) - ntree->flag &= ~NTREE_DO_VERSIONS; + ntree->flag &= ~NTREE_DO_VERSIONS_GROUP_EXPOSE; } - - /* now verify all types in material trees, groups are set OK now */ - for(ma= main->mat.first; ma; ma= ma->id.next) { - if(ma->nodetree) - ntreeVerifyTypes(ma->nodetree); + + /* verify all group user nodes */ + for(ntree= main->nodetree.first; ntree; ntree= ntree->id.next) { + ntreeVerifyNodes(main, &ntree->id); } - /* and scene trees */ - for(sce= main->scene.first; sce; sce= sce->id.next) { - if(sce->nodetree) - ntreeVerifyTypes(sce->nodetree); - } - /* and texture trees */ - for(tx= main->tex.first; tx; tx= tx->id.next) { - if(tx->nodetree) - ntreeVerifyTypes(tx->nodetree); + + /* make update calls where necessary */ + { + for(ntree= main->nodetree.first; ntree; ntree= ntree->id.next) + if (ntree->update) + ntreeUpdateTree(ntree); + for (i=0; i < NUM_NTREE_TYPES; ++i) { + ntreetype= ntreeGetType(i); + if (ntreetype && ntreetype->foreach_nodetree) + ntreetype->foreach_nodetree(main, NULL, lib_nodetree_do_versions_update_cb); + } } } - +static void direct_link_node_socket(FileData *fd, bNodeSocket *sock) +{ + sock->link= newdataadr(fd, sock->link); + sock->storage= newdataadr(fd, sock->storage); + sock->default_value= newdataadr(fd, sock->default_value); + sock->cache= NULL; +} /* ntree itself has been read! */ static void direct_link_nodetree(FileData *fd, bNodeTree *ntree) @@ -2185,6 +2207,7 @@ static void direct_link_nodetree(FileData *fd, bNodeTree *ntree) ntree->init= 0; /* to set callbacks and force setting types */ ntree->progress= NULL; + ntree->execdata= NULL; ntree->adt= newdataadr(fd, ntree->adt); direct_link_animdata(fd, ntree->adt); @@ -2197,9 +2220,11 @@ static void direct_link_nodetree(FileData *fd, bNodeTree *ntree) node->typeinfo= NULL; } + link_list(fd, &node->inputs); + link_list(fd, &node->outputs); + node->storage= newdataadr(fd, node->storage); if(node->storage) { - /* could be handlerized at some point */ if(ntree->type==NTREE_SHADER && (node->type==SH_NODE_CURVE_VEC || node->type==SH_NODE_CURVE_RGB)) direct_link_curvemapping(fd, node->storage); @@ -2216,8 +2241,6 @@ static void direct_link_nodetree(FileData *fd, bNodeTree *ntree) ((ImageUser *)node->storage)->ok= 1; } } - link_list(fd, &node->inputs); - link_list(fd, &node->outputs); } link_list(fd, &ntree->links); @@ -2227,15 +2250,19 @@ static void direct_link_nodetree(FileData *fd, bNodeTree *ntree) /* and we connect the rest */ for(node= ntree->nodes.first; node; node= node->next) { + node->parent = newdataadr(fd, node->parent); node->preview= newimaadr(fd, node->preview); node->lasty= 0; + for(sock= node->inputs.first; sock; sock= sock->next) - sock->link= newdataadr(fd, sock->link); + direct_link_node_socket(fd, sock); for(sock= node->outputs.first; sock; sock= sock->next) - sock->ns.data= NULL; + direct_link_node_socket(fd, sock); } + for(sock= ntree->inputs.first; sock; sock= sock->next) + direct_link_node_socket(fd, sock); for(sock= ntree->outputs.first; sock; sock= sock->next) - sock->link= newdataadr(fd, sock->link); + direct_link_node_socket(fd, sock); for(link= ntree->links.first; link; link= link->next) { link->fromnode= newdataadr(fd, link->fromnode); @@ -4957,15 +4984,22 @@ static void lib_link_screen(FileData *fd, Main *main) SpaceNode *snode= (SpaceNode *)sl; snode->id= newlibadr(fd, sc->id.lib, snode->id); + snode->edittree= NULL; - /* internal data, a bit patchy */ - if(snode->id) { - if(GS(snode->id->name)==ID_MA) - snode->nodetree= ((Material *)snode->id)->nodetree; - else if(GS(snode->id->name)==ID_SCE) - snode->nodetree= ((Scene *)snode->id)->nodetree; - else if(GS(snode->id->name)==ID_TE) - snode->nodetree= ((Tex *)snode->id)->nodetree; + if (ELEM3(snode->treetype, NTREE_COMPOSIT, NTREE_SHADER, NTREE_TEXTURE)) { + /* internal data, a bit patchy */ + snode->nodetree= NULL; + if(snode->id) { + if(GS(snode->id->name)==ID_MA) + snode->nodetree= ((Material *)snode->id)->nodetree; + else if(GS(snode->id->name)==ID_SCE) + snode->nodetree= ((Scene *)snode->id)->nodetree; + else if(GS(snode->id->name)==ID_TE) + snode->nodetree= ((Tex *)snode->id)->nodetree; + } + } + else { + snode->nodetree= newlibadr_us(fd, sc->id.lib, snode->nodetree); } snode->linkdrag.first = snode->linkdrag.last = NULL; @@ -5185,15 +5219,19 @@ void lib_link_screen_restore(Main *newmain, bScreen *curscreen, Scene *curscene) snode->id= restore_pointer_by_name(newmain, snode->id, 1); snode->edittree= NULL; - if(snode->id==NULL) + if (ELEM3(snode->treetype, NTREE_COMPOSIT, NTREE_SHADER, NTREE_TEXTURE)) { snode->nodetree= NULL; + if(snode->id) { + if(GS(snode->id->name)==ID_MA) + snode->nodetree= ((Material *)snode->id)->nodetree; + else if(GS(snode->id->name)==ID_SCE) + snode->nodetree= ((Scene *)snode->id)->nodetree; + else if(GS(snode->id->name)==ID_TE) + snode->nodetree= ((Tex *)snode->id)->nodetree; + } + } else { - if(GS(snode->id->name)==ID_MA) - snode->nodetree= ((Material *)snode->id)->nodetree; - else if(GS(snode->id->name)==ID_SCE) - snode->nodetree= ((Scene *)snode->id)->nodetree; - else if(GS(snode->id->name)==ID_TE) - snode->nodetree= ((Tex *)snode->id)->nodetree; + snode->nodetree= restore_pointer_by_name(newmain, &snode->nodetree->id, 1); } } } @@ -5422,7 +5460,6 @@ static void direct_link_screen(FileData *fd, bScreen *sc) snode->gpd= newdataadr(fd, snode->gpd); direct_link_gpencil(fd, snode->gpd); } - snode->nodetree= snode->edittree= NULL; } else if(sl->spacetype==SPACE_TIME) { SpaceTime *stime= (SpaceTime *)sl; @@ -6931,6 +6968,53 @@ static void do_version_bone_roll_256(Bone *bone) do_version_bone_roll_256(child); } +static void do_versions_socket_default_value(bNodeSocket *sock) +{ + bNodeSocketValueFloat *valfloat; + bNodeSocketValueVector *valvector; + bNodeSocketValueRGBA *valrgba; + + if (sock->default_value) + return; + + switch (sock->type) { + case SOCK_FLOAT: + valfloat = sock->default_value = MEM_callocN(sizeof(bNodeSocketValueFloat), "default socket value"); + valfloat->value = sock->ns.vec[0]; + valfloat->min = sock->ns.min; + valfloat->max = sock->ns.max; + valfloat->subtype = PROP_NONE; + break; + case SOCK_VECTOR: + valvector = sock->default_value = MEM_callocN(sizeof(bNodeSocketValueVector), "default socket value"); + copy_v3_v3(valvector->value, sock->ns.vec); + valvector->min = sock->ns.min; + valvector->max = sock->ns.max; + valvector->subtype = PROP_NONE; + break; + case SOCK_RGBA: + valrgba = sock->default_value = MEM_callocN(sizeof(bNodeSocketValueRGBA), "default socket value"); + copy_v4_v4(valrgba->value, sock->ns.vec); + break; + } +} + +static void do_versions_nodetree_default_value(bNodeTree *ntree) +{ + bNode *node; + bNodeSocket *sock; + for (node=ntree->nodes.first; node; node=node->next) { + for (sock=node->inputs.first; sock; sock=sock->next) + do_versions_socket_default_value(sock); + for (sock=node->outputs.first; sock; sock=sock->next) + do_versions_socket_default_value(sock); + } + for (sock=ntree->inputs.first; sock; sock=sock->next) + do_versions_socket_default_value(sock); + for (sock=ntree->outputs.first; sock; sock=sock->next) + do_versions_socket_default_value(sock); +} + static void do_versions(FileData *fd, Library *lib, Main *main) { /* WATCH IT!!!: pointers from libdata have not been converted */ @@ -11582,7 +11666,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main) * is done in lib_verify_nodetree, because at this point the internal * nodes may not be up-to-date! (missing lib-link) */ - ntree->flag |= NTREE_DO_VERSIONS; + ntree->flag |= NTREE_DO_VERSIONS_GROUP_EXPOSE; } } @@ -11707,10 +11791,10 @@ static void do_versions(FileData *fd, Library *lib, Main *main) if(tex->pd) { if (tex->pd->falloff_speed_scale == 0.0f) tex->pd->falloff_speed_scale = 100.0f; - + if (!tex->pd->falloff_curve) { tex->pd->falloff_curve = curvemapping_add(1, 0, 0, 1, 1); - + tex->pd->falloff_curve->preset = CURVE_PRESET_LINE; tex->pd->falloff_curve->cm->flag &= ~CUMA_EXTEND_EXTRAPOLATE; curvemap_reset(tex->pd->falloff_curve->cm, &tex->pd->falloff_curve->clipr, tex->pd->falloff_curve->preset, CURVEMAP_SLOPE_POSITIVE); @@ -11861,6 +11945,35 @@ static void do_versions(FileData *fd, Library *lib, Main *main) } } + if (main->versionfile < 259 || (main->versionfile == 259 && main->subversionfile < 2)){ + { + /* Convert default socket values from bNodeStack */ + Scene *sce; + Material *mat; + Tex *tex; + bNodeTree *ntree; + for (ntree=main->nodetree.first; ntree; ntree=ntree->id.next) { + do_versions_nodetree_default_value(ntree); + ntree->update |= NTREE_UPDATE; + } + for (sce=main->scene.first; sce; sce=sce->id.next) + if (sce->nodetree) { + do_versions_nodetree_default_value(sce->nodetree); + sce->nodetree->update |= NTREE_UPDATE; + } + for (mat=main->mat.first; mat; mat=mat->id.next) + if (mat->nodetree) { + do_versions_nodetree_default_value(mat->nodetree); + mat->nodetree->update |= NTREE_UPDATE; + } + for (tex=main->tex.first; tex; tex=tex->id.next) + if (tex->nodetree) { + do_versions_nodetree_default_value(tex->nodetree); + tex->nodetree->update |= NTREE_UPDATE; + } + } + } + /* put compatibility code here until next subversion bump */ { diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index 406a9bdc02e..b982630ec41 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -642,6 +642,14 @@ static void write_curvemapping(WriteData *wd, CurveMapping *cumap) writestruct(wd, DATA, "CurveMapPoint", cumap->cm[a].totpoint, cumap->cm[a].curve); } +static void write_node_socket(WriteData *wd, bNodeSocket *sock) +{ + bNodeSocketType *stype= ntreeGetSocketType(sock->type); + writestruct(wd, DATA, "bNodeSocket", 1, sock); + if (sock->default_value) + writestruct(wd, DATA, stype->value_structname, 1, sock->default_value); +} + /* this is only direct data, tree itself should have been written */ static void write_nodetree(WriteData *wd, bNodeTree *ntree) { @@ -657,6 +665,12 @@ static void write_nodetree(WriteData *wd, bNodeTree *ntree) writestruct(wd, DATA, "bNode", 1, node); for(node= ntree->nodes.first; node; node= node->next) { + for(sock= node->inputs.first; sock; sock= sock->next) + write_node_socket(wd, sock); + for(sock= node->outputs.first; sock; sock= sock->next) + write_node_socket(wd, sock); + + if(node->storage && node->type!=NODE_DYNAMIC) { /* could be handlerized at some point, now only 1 exception still */ if(ntree->type==NTREE_SHADER && (node->type==SH_NODE_CURVE_VEC || node->type==SH_NODE_CURVE_RGB)) @@ -665,13 +679,9 @@ static void write_nodetree(WriteData *wd, bNodeTree *ntree) write_curvemapping(wd, node->storage); else if(ntree->type==NTREE_TEXTURE && (node->type==TEX_NODE_CURVE_RGB || node->type==TEX_NODE_CURVE_TIME) ) write_curvemapping(wd, node->storage); - else + else writestruct(wd, DATA, node->typeinfo->storagename, 1, node->storage); } - for(sock= node->inputs.first; sock; sock= sock->next) - writestruct(wd, DATA, "bNodeSocket", 1, sock); - for(sock= node->outputs.first; sock; sock= sock->next) - writestruct(wd, DATA, "bNodeSocket", 1, sock); } for(link= ntree->links.first; link; link= link->next) @@ -679,9 +689,9 @@ static void write_nodetree(WriteData *wd, bNodeTree *ntree) /* external sockets */ for(sock= ntree->inputs.first; sock; sock= sock->next) - writestruct(wd, DATA, "bNodeSocket", 1, sock); + write_node_socket(wd, sock); for(sock= ntree->outputs.first; sock; sock= sock->next) - writestruct(wd, DATA, "bNodeSocket", 1, sock); + write_node_socket(wd, sock); } static void current_screen_compat(Main *mainvar, bScreen **screen) @@ -933,7 +943,7 @@ static void write_particlesystems(WriteData *wd, ListBase *particles) writestruct(wd, DATA, "ClothSimSettings", 1, psys->clmd->sim_parms); writestruct(wd, DATA, "ClothCollSettings", 1, psys->clmd->coll_parms); } - + write_pointcaches(wd, &psys->ptcaches); } } diff --git a/source/blender/editors/include/ED_node.h b/source/blender/editors/include/ED_node.h index cc4dd6330fb..1cbf45960d3 100644 --- a/source/blender/editors/include/ED_node.h +++ b/source/blender/editors/include/ED_node.h @@ -39,6 +39,7 @@ struct Material; struct Scene; struct Tex; struct bContext; +struct bNodeTree; struct bNode; struct bNodeTree; struct ScrArea; @@ -47,6 +48,7 @@ struct ScrArea; void ED_init_node_butfuncs(void); /* node_draw.c */ +void ED_node_tree_update(struct SpaceNode *snode, struct Scene *scene); void ED_node_changed_update(struct ID *id, struct bNode *node); void ED_node_generic_update(struct Main *bmain, struct bNodeTree *ntree, struct bNode *node); @@ -57,8 +59,9 @@ void ED_node_texture_default(struct Tex *tex); void ED_node_link_intersect_test(struct ScrArea *sa, int test); void ED_node_link_insert(struct ScrArea *sa); -void ED_node_set_active(struct Main *bmain, struct bNodeTree *ntree, struct bNode *node); +void ED_node_update_hierarchy(struct bContext *C, struct bNodeTree *ntree); +void ED_node_set_active(struct Main *bmain, struct bNodeTree *ntree, struct bNode *node); /* node ops.c */ void ED_operatormacros_node(void); diff --git a/source/blender/editors/sculpt_paint/paint_image.c b/source/blender/editors/sculpt_paint/paint_image.c index d69c1d9c447..9539706468f 100644 --- a/source/blender/editors/sculpt_paint/paint_image.c +++ b/source/blender/editors/sculpt_paint/paint_image.c @@ -60,6 +60,7 @@ #include "DNA_brush_types.h" #include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" +#include "DNA_node_types.h" #include "DNA_object_types.h" #include "DNA_scene_types.h" #include "DNA_texture_types.h" @@ -4663,7 +4664,7 @@ static void paint_brush_init_tex(Brush *brush) if(brush) { MTex *mtex= &brush->mtex; if(mtex->tex && mtex->tex->nodetree) - ntreeBeginExecTree(mtex->tex->nodetree); /* has internal flag to detect it only does it once */ + ntreeTexBeginExecTree(mtex->tex->nodetree); /* has internal flag to detect it only does it once */ } } @@ -4805,7 +4806,7 @@ static void paint_brush_exit_tex(Brush *brush) if(brush) { MTex *mtex= &brush->mtex; if(mtex->tex && mtex->tex->nodetree) - ntreeEndExecTree(mtex->tex->nodetree); + ntreeTexEndExecTree(mtex->tex->nodetree->execdata); } } diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index 2ee49f71a78..bf34a3b8c9f 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -48,6 +48,7 @@ #include "BLI_rand.h" #include "DNA_meshdata_types.h" +#include "DNA_node_types.h" #include "DNA_object_types.h" #include "DNA_scene_types.h" #include "DNA_brush_types.h" @@ -3273,7 +3274,7 @@ static void sculpt_brush_init_tex(Sculpt *sd, SculptSession *ss) /* init mtex nodes */ if(mtex->tex && mtex->tex->nodetree) - ntreeBeginExecTree(mtex->tex->nodetree); /* has internal flag to detect it only does it once */ + ntreeTexBeginExecTree(mtex->tex->nodetree); /* has internal flag to detect it only does it once */ /* TODO: Shouldn't really have to do this at the start of every stroke, but sculpt would need some sort of notification when @@ -3454,7 +3455,7 @@ static void sculpt_brush_exit_tex(Sculpt *sd) MTex *mtex= &brush->mtex; if(mtex->tex && mtex->tex->nodetree) - ntreeEndExecTree(mtex->tex->nodetree); + ntreeTexEndExecTree(mtex->tex->nodetree->execdata); } static void sculpt_stroke_done(bContext *C, struct PaintStroke *UNUSED(stroke)) diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index 0474d1f3bb1..890b04dce91 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -53,9 +53,10 @@ #include "BKE_image.h" #include "BKE_library.h" #include "BKE_main.h" +#include "BKE_node.h" -#include "CMP_node.h" -#include "SHD_node.h" +#include "NOD_composite.h" +#include "NOD_shader.h" #include "BIF_gl.h" #include "BIF_glutil.h" @@ -81,6 +82,141 @@ #include "node_intern.h" +// XXX interface.h +extern void ui_dropshadow(rctf *rct, float radius, float aspect, int select); + +/* ****************** SOCKET BUTTON DRAW FUNCTIONS ***************** */ + +static void node_sync_cb(bContext *UNUSED(C), void *snode_v, void *node_v) +{ + SpaceNode *snode= snode_v; + + if(snode->treetype==NTREE_SHADER) { + nodeShaderSynchronizeID(node_v, 1); + // allqueue(REDRAWBUTSSHADING, 0); + } +} + +void node_socket_button_default(const bContext *C, uiBlock *block, + bNodeTree *ntree, bNode *node, bNodeSocket *sock, + const char *name, int x, int y, int width) +{ + PointerRNA ptr; + uiBut *bt; + + RNA_pointer_create(&ntree->id, &RNA_NodeSocket, sock, &ptr); + + bt = uiDefButR(block, NUM, B_NODE_EXEC, name, + x, y+1, width, NODE_DY-2, + &ptr, "default_value", 0, 0, 0, -1, -1, NULL); + if (node) + uiButSetFunc(bt, node_sync_cb, CTX_wm_space_node(C), node); +} + +typedef struct SocketComponentMenuArgs { + PointerRNA ptr; + int x, y, width; + uiButHandleFunc cb; + void *arg1, *arg2; +} SocketComponentMenuArgs; +/* NOTE: this is a block-menu, needs 0 events, otherwise the menu closes */ +static uiBlock *socket_component_menu(bContext *C, ARegion *ar, void *args_v) +{ + SocketComponentMenuArgs *args= (SocketComponentMenuArgs*)args_v; + uiBlock *block; + uiLayout *layout; + + block= uiBeginBlock(C, ar, "socket menu", UI_EMBOSS); + uiBlockSetFlag(block, UI_BLOCK_KEEP_OPEN); + + layout= uiLayoutColumn(uiBlockLayout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, args->x, args->y+2, args->width, NODE_DY, U.uistyles.first), 0); + + uiItemR(layout, &args->ptr, "default_value", UI_ITEM_R_EXPAND, "", ICON_NONE); + + return block; +} +void node_socket_button_components(const bContext *C, uiBlock *block, + bNodeTree *ntree, bNode *node, bNodeSocket *sock, + const char *name, int x, int y, int width) +{ + PointerRNA ptr; + SocketComponentMenuArgs *args; + + RNA_pointer_create(&ntree->id, &RNA_NodeSocket, sock, &ptr); + + args= MEM_callocN(sizeof(SocketComponentMenuArgs), "SocketComponentMenuArgs"); + + args->ptr = ptr; + args->x = x; + args->y = y; + args->width = width; + args->cb = node_sync_cb; + args->arg1 = CTX_wm_space_node(C); + args->arg2 = node; + + uiDefBlockButN(block, socket_component_menu, args, name, x, y+1, width, NODE_DY-2, ""); +} + +void node_socket_button_color(const bContext *C, uiBlock *block, + bNodeTree *ntree, bNode *node, bNodeSocket *sock, + const char *name, int x, int y, int width) +{ + PointerRNA ptr; + uiBut *bt; + int labelw= width - 40; + + RNA_pointer_create(&ntree->id, &RNA_NodeSocket, sock, &ptr); + + bt=uiDefButR(block, COL, B_NODE_EXEC, "", + x, y+2, (labelw>0 ? 40 : width), NODE_DY-2, + &ptr, "default_value", 0, 0, 0, -1, -1, NULL); + if (node) + uiButSetFunc(bt, node_sync_cb, CTX_wm_space_node(C), node); + + if (name[0]!='\0' && labelw>0) + uiDefBut(block, LABEL, 0, name, x + 40, y+2, labelw, NODE_DY-2, NULL, 0, 0, 0, 0, ""); +} + +/* ****************** BASE DRAW FUNCTIONS FOR NEW OPERATOR NODES ***************** */ + +void node_draw_socket_new(bNodeSocket *sock, float size) +{ + float x=sock->locx, y=sock->locy; + + /* 16 values of sin function */ + static float si[16] = { + 0.00000000f, 0.39435585f,0.72479278f,0.93775213f, + 0.99871650f,0.89780453f,0.65137248f,0.29936312f, + -0.10116832f,-0.48530196f,-0.79077573f,-0.96807711f, + -0.98846832f,-0.84864425f,-0.57126821f,-0.20129852f + }; + /* 16 values of cos function */ + static float co[16] ={ + 1.00000000f,0.91895781f,0.68896691f,0.34730525f, + -0.05064916f,-0.44039415f,-0.75875812f,-0.95413925f, + -0.99486932f,-0.87434661f,-0.61210598f,-0.25065253f, + 0.15142777f,0.52896401f,0.82076344f,0.97952994f, + }; + int a; + + glColor3ub(180, 180, 180); + + glBegin(GL_POLYGON); + for(a=0; a<16; a++) + glVertex2f(x+size*si[a], y+size*co[a]); + glEnd(); + + glColor4ub(0, 0, 0, 150); + glEnable(GL_BLEND); + glEnable( GL_LINE_SMOOTH ); + glBegin(GL_LINE_LOOP); + for(a=0; a<16; a++) + glVertex2f(x+size*si[a], y+size*co[a]); + glEnd(); + glDisable( GL_LINE_SMOOTH ); + glDisable(GL_BLEND); +} + /* ****************** BUTTON CALLBACKS FOR ALL TREES ***************** */ static void node_buts_value(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) @@ -192,11 +328,12 @@ static void node_buts_normal(uiLayout *layout, bContext *UNUSED(C), PointerRNA * bNode *node= ptr->data; rctf *butr= &node->butr; bNodeSocket *sock= node->outputs.first; /* first socket stores normal */ + float *nor= ((bNodeSocketValueVector*)sock->default_value)->value; uiBut *bt; bt= uiDefButF(block, BUT_NORMAL, B_NODE_EXEC, "", (short)butr->xmin, (short)butr->xmin, butr->xmax-butr->xmin, butr->xmax-butr->xmin, - sock->ns.vec, 0.0f, 1.0f, 0, 0, ""); + nor, 0.0f, 1.0f, 0, 0, ""); uiButSetFunc(bt, node_normal_cb, ntree, node); } #if 0 // not used in 2.5x yet @@ -287,6 +424,470 @@ static void node_buts_math(uiLayout *layout, bContext *UNUSED(C), PointerRNA *pt uiItemR(layout, ptr, "operation", 0, "", ICON_NONE); } +static int node_resize_area_default(bNode *node, int x, int y) +{ + if (node->flag & NODE_HIDDEN) { + rctf totr= node->totr; + /* right part of node */ + totr.xmin= node->totr.xmax-20.0f; + return BLI_in_rctf(&totr, x, y); + } + else { + /* rect we're interested in is just the bottom right corner */ + rctf totr= node->totr; + /* bottom right corner */ + totr.xmin= totr.xmax-10.0f; + totr.ymax= totr.ymin+10.0f; + return BLI_in_rctf(&totr, x, y); + } +} + +/* ****************** BUTTON CALLBACKS FOR COMMON NODES ***************** */ + +/* width of socket columns in group display */ +#define NODE_GROUP_FRAME 120 + +/* based on settings in node, sets drawing rect info. each redraw! */ +/* note: this assumes only 1 group at a time is drawn (linked data) */ +/* in node->totr the entire boundbox for the group is stored */ +static void node_update_group(const bContext *C, bNodeTree *ntree, bNode *gnode) +{ + if (!(gnode->flag & NODE_GROUP_EDIT)) { + node_update_default(C, ntree, gnode); + } + else { + bNodeTree *ngroup= (bNodeTree *)gnode->id; + bNode *node; + bNodeSocket *sock, *gsock; + float locx, locy; + rctf *rect= &gnode->totr; + float node_group_frame= U.dpi*NODE_GROUP_FRAME/72; + int counter; + int dy; + + /* get "global" coords */ + nodeSpaceCoords(gnode, &locx, &locy); + + /* center them, is a bit of abuse of locx and locy though */ + node_update_nodetree(C, ngroup, locx, locy); + + rect->xmin = rect->xmax = locx; + rect->ymin = rect->ymax = locy; + + counter= 1; + for(node= ngroup->nodes.first; node; node= node->next) { + if(counter) { + *rect= node->totr; + counter= 0; + } + else + BLI_union_rctf(rect, &node->totr); + } + + /* add some room for links to group sockets */ + rect->xmin -= 4*NODE_DY; + rect->xmax += 4*NODE_DY; + rect->ymin-= NODE_DY; + rect->ymax+= NODE_DY; + + /* input sockets */ + dy = 0.5f*(rect->ymin+rect->ymax) + NODE_DY*(BLI_countlist(&gnode->inputs)-1); + gsock=ngroup->inputs.first; + sock=gnode->inputs.first; + while (gsock || sock) { + while (sock && !sock->groupsock) { + sock->locx = rect->xmin - node_group_frame; + sock->locy = dy; + + /* prevent long socket lists from growing out of the group box */ + if (dy-3*NODE_DYS < rect->ymin) + rect->ymin = dy-3*NODE_DYS; + if (dy+3*NODE_DYS > rect->ymax) + rect->ymax = dy+3*NODE_DYS; + dy -= 2*NODE_DY; + + sock = sock->next; + } + while (gsock && (!sock || sock->groupsock!=gsock)) { + gsock->locx = rect->xmin; + gsock->locy = dy; + + /* prevent long socket lists from growing out of the group box */ + if (dy-3*NODE_DYS < rect->ymin) + rect->ymin = dy-3*NODE_DYS; + if (dy+3*NODE_DYS > rect->ymax) + rect->ymax = dy+3*NODE_DYS; + dy -= 2*NODE_DY; + + gsock = gsock->next; + } + while (sock && gsock && sock->groupsock==gsock) { + gsock->locx = rect->xmin; + sock->locx = rect->xmin - node_group_frame; + sock->locy = gsock->locy = dy; + + /* prevent long socket lists from growing out of the group box */ + if (dy-3*NODE_DYS < rect->ymin) + rect->ymin = dy-3*NODE_DYS; + if (dy+3*NODE_DYS > rect->ymax) + rect->ymax = dy+3*NODE_DYS; + dy -= 2*NODE_DY; + + sock = sock->next; + gsock = gsock->next; + } + } + + /* output sockets */ + dy = 0.5f*(rect->ymin+rect->ymax) + NODE_DY*(BLI_countlist(&gnode->outputs)-1); + gsock=ngroup->outputs.first; + sock=gnode->outputs.first; + while (gsock || sock) { + while (sock && !sock->groupsock) { + sock->locx = rect->xmax + node_group_frame; + sock->locy = dy - NODE_DYS; + + /* prevent long socket lists from growing out of the group box */ + if (dy-3*NODE_DYS < rect->ymin) + rect->ymin = dy-3*NODE_DYS; + if (dy+3*NODE_DYS > rect->ymax) + rect->ymax = dy+3*NODE_DYS; + dy -= 2*NODE_DY; + + sock = sock->next; + } + while (gsock && (!sock || sock->groupsock!=gsock)) { + gsock->locx = rect->xmax; + gsock->locy = dy - NODE_DYS; + + /* prevent long socket lists from growing out of the group box */ + if (dy-3*NODE_DYS < rect->ymin) + rect->ymin = dy-3*NODE_DYS; + if (dy+3*NODE_DYS > rect->ymax) + rect->ymax = dy+3*NODE_DYS; + dy -= 2*NODE_DY; + + gsock = gsock->next; + } + while (sock && gsock && sock->groupsock==gsock) { + gsock->locx = rect->xmax; + sock->locx = rect->xmax + node_group_frame; + sock->locy = gsock->locy = dy - NODE_DYS; + + /* prevent long socket lists from growing out of the group box */ + if (dy-3*NODE_DYS < rect->ymin) + rect->ymin = dy-3*NODE_DYS; + if (dy+3*NODE_DYS > rect->ymax) + rect->ymax = dy+3*NODE_DYS; + dy -= 2*NODE_DY; + + sock = sock->next; + gsock = gsock->next; + } + } + } +} + +static void update_group_input_cb(bContext *UNUSED(C), void *UNUSED(snode_v), void *ngroup_v) +{ + bNodeTree *ngroup= (bNodeTree*)ngroup_v; + + ngroup->update |= NTREE_UPDATE_GROUP_IN; + ntreeUpdateTree(ngroup); +} + +static void update_group_output_cb(bContext *UNUSED(C), void *UNUSED(snode_v), void *ngroup_v) +{ + bNodeTree *ngroup= (bNodeTree*)ngroup_v; + + ngroup->update |= NTREE_UPDATE_GROUP_OUT; + ntreeUpdateTree(ngroup); +} + +static void draw_group_socket_name(SpaceNode *snode, bNode *gnode, bNodeSocket *sock, int in_out, float xoffset, float yoffset) +{ + bNodeTree *ngroup= (bNodeTree*)gnode->id; + uiBut *bt; + + if (sock->flag & SOCK_DYNAMIC) { + bt = uiDefBut(gnode->block, TEX, 0, "", + sock->locx+xoffset, sock->locy+1+yoffset, 72, NODE_DY, + sock->name, 0, 31, 0, 0, ""); + if (in_out==SOCK_IN) + uiButSetFunc(bt, update_group_input_cb, snode, ngroup); + else + uiButSetFunc(bt, update_group_output_cb, snode, ngroup); + } + else { + uiDefBut(gnode->block, LABEL, 0, sock->name, + sock->locx+xoffset, sock->locy+1+yoffset, 72, NODE_DY, + NULL, 0, 31, 0, 0, ""); + } +} + +static void draw_group_socket(const bContext *C, SpaceNode *snode, bNodeTree *ntree, bNode *gnode, bNodeSocket *sock, bNodeSocket *gsock, int index, int in_out) +{ + bNodeTree *ngroup= (bNodeTree*)gnode->id; + bNodeSocketType *stype= ntreeGetSocketType(gsock ? gsock->type : sock->type); + uiBut *bt; + float offset; + int draw_value; + float node_group_frame= U.dpi*NODE_GROUP_FRAME/72; + float socket_size= NODE_SOCKSIZE*U.dpi/72; + float arrowbutw= 0.8f*UI_UNIT_X; + /* layout stuff for buttons on group left frame */ + float colw= 0.6f*node_group_frame; + float col1= 6; + float col2= col1 + colw+6; + float col3= node_group_frame - arrowbutw - 6; + /* layout stuff for buttons on group right frame */ + float cor1= 6; + float cor2= cor1 + arrowbutw + 6; + float cor3= cor2 + arrowbutw + 6; + + /* node and group socket circles */ + if (sock) + node_socket_circle_draw(ntree, sock, socket_size); + if (gsock) + node_socket_circle_draw(ngroup, gsock, socket_size); + + /* socket name */ + offset = (in_out==SOCK_IN ? col1 : cor3); + if (!gsock) + offset += (in_out==SOCK_IN ? node_group_frame : -node_group_frame); + + /* draw both name and value button if: + * 1) input: not internal + * 2) output: (node type uses const outputs) and (group output is unlinked) + */ + switch (in_out) { + case SOCK_IN: + draw_value = !(gsock && (gsock->flag & SOCK_INTERNAL)); + break; + case SOCK_OUT: + if (gnode->typeinfo->flag & NODE_CONST_OUTPUT) + draw_value = !(gsock && gsock->link); + else + draw_value = 0; + break; + } + if (draw_value) { + /* both name and value buttons */ + if (gsock) { + draw_group_socket_name(snode, gnode, gsock, in_out, offset, 0); + if (stype->buttonfunc) + stype->buttonfunc(C, gnode->block, ngroup, NULL, gsock, "", gsock->locx+offset, gsock->locy-NODE_DY, colw); + } + else { + draw_group_socket_name(snode, gnode, sock, in_out, offset, 0); + if (stype->buttonfunc) + stype->buttonfunc(C, gnode->block, ngroup, NULL, sock, "", sock->locx+offset, sock->locy-NODE_DY, colw); + } + } + else { + /* only name, no value button */ + if (gsock) + draw_group_socket_name(snode, gnode, gsock, in_out, offset, -NODE_DYS); + else + draw_group_socket_name(snode, gnode, sock, in_out, offset, -NODE_DYS); + } + + if (gsock && (gsock->flag & SOCK_DYNAMIC)) { + /* up/down buttons */ + offset = (in_out==SOCK_IN ? col2 : cor2); + uiBlockSetDirection(gnode->block, UI_TOP); + uiBlockBeginAlign(gnode->block); + bt = uiDefIconButO(gnode->block, BUT, "NODE_OT_group_socket_move_up", 0, ICON_TRIA_UP, + gsock->locx+offset, gsock->locy, arrowbutw, arrowbutw, ""); + if (!gsock->prev || !(gsock->prev->flag & SOCK_DYNAMIC)) + uiButSetFlag(bt, UI_BUT_DISABLED); + RNA_int_set(uiButGetOperatorPtrRNA(bt), "index", index); + RNA_enum_set(uiButGetOperatorPtrRNA(bt), "in_out", in_out); + bt = uiDefIconButO(gnode->block, BUT, "NODE_OT_group_socket_move_down", 0, ICON_TRIA_DOWN, + gsock->locx+offset, gsock->locy-arrowbutw, arrowbutw, arrowbutw, ""); + if (!gsock->next || !(gsock->next->flag & SOCK_DYNAMIC)) + uiButSetFlag(bt, UI_BUT_DISABLED); + RNA_int_set(uiButGetOperatorPtrRNA(bt), "index", index); + RNA_enum_set(uiButGetOperatorPtrRNA(bt), "in_out", in_out); + uiBlockEndAlign(gnode->block); + uiBlockSetDirection(gnode->block, 0); + + /* remove button */ + offset = (in_out==SOCK_IN ? col3 : col1); + uiBlockSetEmboss(gnode->block, UI_EMBOSSN); + bt = uiDefIconButO(gnode->block, BUT, "NODE_OT_group_socket_remove", 0, ICON_X, + gsock->locx+offset, gsock->locy-0.5f*arrowbutw, arrowbutw, arrowbutw, ""); + RNA_int_set(uiButGetOperatorPtrRNA(bt), "index", index); + RNA_enum_set(uiButGetOperatorPtrRNA(bt), "in_out", in_out); + uiBlockSetEmboss(gnode->block, UI_EMBOSS); + } +} + +/* groups are, on creation, centered around 0,0 */ +static void node_draw_group(const bContext *C, ARegion *ar, SpaceNode *snode, bNodeTree *ntree, bNode *gnode) +{ + if (!(gnode->flag & NODE_GROUP_EDIT)) { + node_draw_default(C, ar, snode, ntree, gnode); + } + else { + bNodeTree *ngroup= (bNodeTree *)gnode->id; + bNodeSocket *sock, *gsock; + uiLayout *layout; + PointerRNA ptr; + rctf rect= gnode->totr; + float node_group_frame= U.dpi*NODE_GROUP_FRAME/72; + float group_header= 26*U.dpi/72; + + int index; + + /* backdrop header */ + glEnable(GL_BLEND); + uiSetRoundBox(3); + UI_ThemeColorShadeAlpha(TH_NODE_GROUP, 0, -70); + uiDrawBox(GL_POLYGON, rect.xmin-node_group_frame, rect.ymax, rect.xmax+node_group_frame, rect.ymax+group_header, BASIS_RAD); + + /* backdrop body */ + UI_ThemeColorShadeAlpha(TH_BACK, -8, -70); + uiSetRoundBox(0); + uiDrawBox(GL_POLYGON, rect.xmin, rect.ymin, rect.xmax, rect.ymax, BASIS_RAD); + + /* input column */ + UI_ThemeColorShadeAlpha(TH_BACK, 10, -50); + uiSetRoundBox(8); + uiDrawBox(GL_POLYGON, rect.xmin-node_group_frame, rect.ymin, rect.xmin, rect.ymax, BASIS_RAD); + + /* output column */ + UI_ThemeColorShadeAlpha(TH_BACK, 10, -50); + uiSetRoundBox(4); + uiDrawBox(GL_POLYGON, rect.xmax, rect.ymin, rect.xmax+node_group_frame, rect.ymax, BASIS_RAD); + + /* input column separator */ + glColor4ub(200, 200, 200, 140); + glBegin(GL_LINES); + glVertex2f(rect.xmin, rect.ymin); + glVertex2f(rect.xmin, rect.ymax); + glEnd(); + + /* output column separator */ + glColor4ub(200, 200, 200, 140); + glBegin(GL_LINES); + glVertex2f(rect.xmax, rect.ymin); + glVertex2f(rect.xmax, rect.ymax); + glEnd(); + + /* group node outline */ + uiSetRoundBox(15); + glColor4ub(200, 200, 200, 140); + glEnable( GL_LINE_SMOOTH ); + uiDrawBox(GL_LINE_LOOP, rect.xmin-node_group_frame, rect.ymin, rect.xmax+node_group_frame, rect.ymax+group_header, BASIS_RAD); + glDisable( GL_LINE_SMOOTH ); + glDisable(GL_BLEND); + + /* backdrop title */ + UI_ThemeColor(TH_TEXT_HI); + + layout = uiBlockLayout(gnode->block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, (short)(rect.xmin+15), (short)(rect.ymax+group_header), + MIN2((int)(rect.xmax - rect.xmin-18.0f), node_group_frame+20), group_header, U.uistyles.first); + RNA_pointer_create(&ntree->id, &RNA_Node, gnode, &ptr); + uiTemplateIDBrowse(layout, (bContext*)C, &ptr, "node_tree", NULL, NULL, NULL); + uiBlockLayoutResolve(gnode->block, NULL, NULL); + + /* draw the internal tree nodes and links */ + node_draw_nodetree(C, ar, snode, ngroup); + + /* group sockets */ + gsock=ngroup->inputs.first; + sock=gnode->inputs.first; + index = 0; + while (gsock || sock) { + while (sock && !sock->groupsock) { + draw_group_socket(C, snode, ntree, gnode, sock, NULL, index, SOCK_IN); + sock = sock->next; + } + while (gsock && (!sock || sock->groupsock!=gsock)) { + draw_group_socket(C, snode, ntree, gnode, NULL, gsock, index, SOCK_IN); + gsock = gsock->next; + ++index; + } + while (sock && gsock && sock->groupsock==gsock) { + draw_group_socket(C, snode, ntree, gnode, sock, gsock, index, SOCK_IN); + sock = sock->next; + gsock = gsock->next; + ++index; + } + } + gsock=ngroup->outputs.first; + sock=gnode->outputs.first; + index = 0; + while (gsock || sock) { + while (sock && !sock->groupsock) { + draw_group_socket(C, snode, ntree, gnode, sock, NULL, index, SOCK_OUT); + sock = sock->next; + } + while (gsock && (!sock || sock->groupsock!=gsock)) { + draw_group_socket(C, snode, ntree, gnode, NULL, gsock, index, SOCK_OUT); + gsock = gsock->next; + ++index; + } + while (sock && gsock && sock->groupsock==gsock) { + draw_group_socket(C, snode, ntree, gnode, sock, gsock, index, SOCK_OUT); + sock = sock->next; + gsock = gsock->next; + ++index; + } + } + + uiEndBlock(C, gnode->block); + uiDrawBlock(C, gnode->block); + gnode->block= NULL; + } +} + +static void node_common_buts_whileloop(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) +{ + uiItemR(layout, ptr, "max_iterations", 0, NULL, 0); +} + +static void node_update_frame(const bContext *UNUSED(C), bNodeTree *UNUSED(ntree), bNode *node) +{ + float locx, locy; + + /* get "global" coords */ + nodeSpaceCoords(node, &locx, &locy); + + node->prvr.xmin= locx + NODE_DYS; + node->prvr.xmax= locx + node->width- NODE_DYS; + + node->totr.xmin= locx; + node->totr.xmax= locx + node->width; + node->totr.ymax= locy; + node->totr.ymin= locy - node->height; +} + +static void node_common_set_butfunc(bNodeType *ntype) +{ + switch(ntype->type) { + case NODE_GROUP: +// ntype->uifunc= node_common_buts_group; + ntype->drawfunc= node_draw_group; + ntype->drawupdatefunc= node_update_group; + break; + case NODE_FORLOOP: +// ntype->uifunc= node_common_buts_group; + ntype->drawfunc= node_draw_group; + ntype->drawupdatefunc= node_update_group; + break; + case NODE_WHILELOOP: + ntype->uifunc= node_common_buts_whileloop; + ntype->drawfunc= node_draw_group; + ntype->drawupdatefunc= node_update_group; + break; + case NODE_FRAME: + ntype->drawupdatefunc= node_update_frame; + break; + } +} + /* ****************** BUTTON CALLBACKS FOR SHADER NODES ***************** */ static void node_browse_text_cb(bContext *C, void *ntree_v, void *node_v) @@ -470,8 +1071,6 @@ static void node_shader_set_butfunc(bNodeType *ntype) case NODE_DYNAMIC: ntype->uifunc= node_shader_buts_dynamic; break; - default: - ntype->uifunc= NULL; } if (ntype->uifuncbut == NULL) ntype->uifuncbut = ntype->uifunc; } @@ -1225,8 +1824,6 @@ static void node_composit_set_butfunc(bNodeType *ntype) case CMP_NODE_SEPYCCA: ntype->uifunc=node_composit_buts_ycc; break; - default: - ntype->uifunc= NULL; } if (ntype->uifuncbut == NULL) ntype->uifuncbut = ntype->uifunc; @@ -1381,9 +1978,6 @@ static void node_texture_set_butfunc(bNodeType *ntype) case TEX_NODE_OUTPUT: ntype->uifunc = node_texture_buts_output; break; - - default: - ntype->uifunc= NULL; } if (ntype->uifuncbut == NULL) ntype->uifuncbut = ntype->uifunc; } @@ -1392,24 +1986,60 @@ static void node_texture_set_butfunc(bNodeType *ntype) void ED_init_node_butfuncs(void) { + bNodeTreeType *treetype; bNodeType *ntype; + bNodeSocketType *stype; + int i; - /* shader nodes */ - ntype= node_all_shaders.first; - while(ntype) { - node_shader_set_butfunc(ntype); - ntype= ntype->next; + /* node type ui functions */ + for (i=0; i < NUM_NTREE_TYPES; ++i) { + treetype = ntreeGetType(i); + if (treetype) { + for (ntype= treetype->node_types.first; ntype; ntype= ntype->next) { + /* default ui functions */ + ntype->drawfunc = node_draw_default; + ntype->drawupdatefunc = node_update_default; + ntype->uifunc = NULL; + ntype->uifuncbut = NULL; + ntype->resize_area_func = node_resize_area_default; + + node_common_set_butfunc(ntype); + + switch (i) { + case NTREE_COMPOSIT: + node_composit_set_butfunc(ntype); + break; + case NTREE_SHADER: + node_shader_set_butfunc(ntype); + break; + case NTREE_TEXTURE: + node_texture_set_butfunc(ntype); + break; + } + } + } } - /* composit nodes */ - ntype= node_all_composit.first; - while(ntype) { - node_composit_set_butfunc(ntype); - ntype= ntype->next; - } - ntype = node_all_textures.first; - while(ntype) { - node_texture_set_butfunc(ntype); - ntype= ntype->next; + + /* socket type ui functions */ + for (i=0; i < NUM_SOCKET_TYPES; ++i) { + stype = ntreeGetSocketType(i); + if (stype) { + switch(stype->type) { + case SOCK_FLOAT: + case SOCK_INT: + case SOCK_BOOLEAN: + stype->buttonfunc = node_socket_button_default; + break; + case SOCK_VECTOR: + stype->buttonfunc = node_socket_button_components; + break; + case SOCK_RGBA: + stype->buttonfunc = node_socket_button_color; + break; + default: + stype->buttonfunc = NULL; + } + } } } @@ -1840,6 +2470,69 @@ void node_draw_link_bezier(View2D *v2d, SpaceNode *snode, bNodeLink *link, int t } } +static void node_link_straight_points(View2D *UNUSED(v2d), SpaceNode *snode, bNodeLink *link, float coord_array[][2]) +{ + if(link->fromsock) { + coord_array[0][0]= link->fromsock->locx; + coord_array[0][1]= link->fromsock->locy; + } + else { + if(snode==NULL) return; + coord_array[0][0]= snode->mx; + coord_array[0][1]= snode->my; + } + if(link->tosock) { + coord_array[1][0]= link->tosock->locx; + coord_array[1][1]= link->tosock->locy; + } + else { + if(snode==NULL) return; + coord_array[1][0]= snode->mx; + coord_array[1][1]= snode->my; + } +} + +void node_draw_link_straight(View2D *v2d, SpaceNode *snode, bNodeLink *link, int th_col1, int do_shaded, int th_col2, int do_triple, int th_col3 ) +{ + float coord_array[2][2]; + float linew; + int i; + + node_link_straight_points(v2d, snode, link, coord_array); + + /* store current linewidth */ + glGetFloatv(GL_LINE_WIDTH, &linew); + + glEnable(GL_LINE_SMOOTH); + + if(do_triple) { + UI_ThemeColorShadeAlpha(th_col3, -80, -120); + glLineWidth(4.0f); + + glBegin(GL_LINES); + glVertex2fv(coord_array[0]); + glVertex2fv(coord_array[1]); + glEnd(); + } + + UI_ThemeColor(th_col1); + glLineWidth(1.5f); + + glBegin(GL_LINE_STRIP); + for (i=0; i < LINK_RESOL; ++i) { + float t= (float)i/(float)(LINK_RESOL-1); + if(do_shaded) + UI_ThemeColorBlend(th_col1, th_col2, t); + glVertex2f((1.0f-t)*coord_array[0][0]+t*coord_array[1][0], (1.0f-t)*coord_array[0][1]+t*coord_array[1][1]); + } + glEnd(); + + glDisable(GL_LINE_SMOOTH); + + /* restore previuos linewidth */ + glLineWidth(linew); +} + /* note; this is used for fake links in groups too */ void node_draw_link(View2D *v2d, SpaceNode *snode, bNodeLink *link) { @@ -1868,7 +2561,7 @@ void node_draw_link(View2D *v2d, SpaceNode *snode, bNodeLink *link) } else { /* check cyclic */ - if(link->fromnode->level >= link->tonode->level && link->tonode->level!=0xFFF) { + if((link->fromnode->level >= link->tonode->level && link->tonode->level!=0xFFF) && (link->flag & NODE_LINK_VALID)) { /* special indicated link, on drop-node */ if(link->flag & NODE_LINKFLAG_HILITE) { th_col1= th_col2= TH_ACTIVE; @@ -1890,6 +2583,5 @@ void node_draw_link(View2D *v2d, SpaceNode *snode, bNodeLink *link) } node_draw_link_bezier(v2d, snode, link, th_col1, do_shaded, th_col2, do_triple, th_col3); +// node_draw_link_straight(v2d, snode, link, th_col1, do_shaded, th_col2, do_triple, th_col3); } - - diff --git a/source/blender/editors/space_node/node_buttons.c b/source/blender/editors/space_node/node_buttons.c index 4b989a78fab..7b14e35e8fe 100644 --- a/source/blender/editors/space_node/node_buttons.c +++ b/source/blender/editors/space_node/node_buttons.c @@ -116,10 +116,12 @@ static void active_node_panel(const bContext *C, Panel *pa) uiItemS(layout); uiItemR(layout, &ptr, "name", 0, NULL, ICON_NODE); uiItemS(layout); - + /* draw this node's settings */ if (node->typeinfo && node->typeinfo->uifuncbut) node->typeinfo->uifuncbut(layout, (bContext *)C, &ptr); + else if (node->typeinfo && node->typeinfo->uifunc) + node->typeinfo->uifunc(layout, (bContext *)C, &ptr); } /* ******************* node buttons registration ************** */ diff --git a/source/blender/editors/space_node/node_draw.c b/source/blender/editors/space_node/node_draw.c index 950b3c72fe7..ec118bb3ca2 100644 --- a/source/blender/editors/space_node/node_draw.c +++ b/source/blender/editors/space_node/node_draw.c @@ -70,8 +70,8 @@ #include "RNA_access.h" -#include "CMP_node.h" -#include "SHD_node.h" +#include "NOD_composite.h" +#include "NOD_shader.h" #include "node_intern.h" @@ -81,6 +81,15 @@ // XXX interface.h extern void ui_dropshadow(rctf *rct, float radius, float aspect, int select); +/* XXX update functions for node editor are a mess, needs a clear concept */ +void ED_node_tree_update(SpaceNode *snode, Scene *scene) +{ + snode_set_context(snode, scene); + + if(snode->nodetree && snode->nodetree->id.us==0) + snode->nodetree->id.us= 1; +} + void ED_node_changed_update(ID *id, bNode *node) { bNodeTree *nodetree, *edittree; @@ -123,24 +132,25 @@ static int has_nodetree(bNodeTree *ntree, bNodeTree *lookup) return 0; } +typedef struct NodeUpdateCalldata { + bNodeTree *ntree; + bNode *node; +} NodeUpdateCalldata; +static void node_generic_update_cb(void *calldata, ID *owner_id, bNodeTree *ntree) +{ + NodeUpdateCalldata *cd= (NodeUpdateCalldata*)calldata; + /* check if nodetree uses the group stored in calldata */ + if (has_nodetree(ntree, cd->ntree)) + ED_node_changed_update(owner_id, cd->node); +} void ED_node_generic_update(Main *bmain, bNodeTree *ntree, bNode *node) { - Material *ma; - Tex *tex; - Scene *sce; - + bNodeTreeType *tti= ntreeGetType(ntree->type); + NodeUpdateCalldata cd; + cd.ntree = ntree; + cd.node = node; /* look through all datablocks, to support groups */ - for(ma=bmain->mat.first; ma; ma=ma->id.next) - if(ma->nodetree && ma->use_nodes && has_nodetree(ma->nodetree, ntree)) - ED_node_changed_update(&ma->id, node); - - for(tex=bmain->tex.first; tex; tex=tex->id.next) - if(tex->nodetree && tex->use_nodes && has_nodetree(tex->nodetree, ntree)) - ED_node_changed_update(&tex->id, node); - - for(sce=bmain->scene.first; sce; sce=sce->id.next) - if(sce->nodetree && sce->use_nodes && has_nodetree(sce->nodetree, ntree)) - ED_node_changed_update(&sce->id, node); + tti->foreach_nodetree(bmain, &cd, node_generic_update_cb); if(ntree->type == NTREE_TEXTURE) ntreeTexCheckCyclics(ntree); @@ -204,14 +214,19 @@ static void node_uiblocks_init(const bContext *C, bNodeTree *ntree) } /* based on settings in node, sets drawing rect info. each redraw! */ -static void node_update(const bContext *C, bNodeTree *ntree, bNode *node) +static void node_update_basis(const bContext *C, bNodeTree *ntree, bNode *node) { uiLayout *layout; PointerRNA ptr; bNodeSocket *nsock; - float dy= node->locy; + float locx, locy; + float dy= locy; int buty; + /* get "global" coords */ + nodeSpaceCoords(node, &locx, &locy); + dy= locy; + /* header */ dy-= NODE_DY; @@ -222,14 +237,14 @@ static void node_update(const bContext *C, bNodeTree *ntree, bNode *node) /* output sockets */ for(nsock= node->outputs.first; nsock; nsock= nsock->next) { if(!(nsock->flag & (SOCK_HIDDEN|SOCK_UNAVAIL))) { - nsock->locx= node->locx + node->width; + nsock->locx= locx + node->width; nsock->locy= dy - NODE_DYS; dy-= NODE_DY; } } - node->prvr.xmin= node->locx + NODE_DYS; - node->prvr.xmax= node->locx + node->width- NODE_DYS; + node->prvr.xmin= locx + NODE_DYS; + node->prvr.xmax= locx + node->width- NODE_DYS; /* preview rect? */ if(node->flag & NODE_PREVIEW) { @@ -286,21 +301,22 @@ static void node_update(const bContext *C, bNodeTree *ntree, bNode *node) node->butr.ymax= 0; RNA_pointer_create(&ntree->id, &RNA_Node, node, &ptr); - + layout= uiBlockLayout(node->block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, - node->locx+NODE_DYS, dy, node->butr.xmax, NODE_DY, U.uistyles.first); - + locx+NODE_DYS, dy, node->butr.xmax, NODE_DY, U.uistyles.first); + node->typeinfo->uifunc(layout, (bContext *)C, &ptr); + uiBlockEndAlign(node->block); uiBlockLayoutResolve(node->block, NULL, &buty); - + dy= buty - NODE_DYS/2; } /* input sockets */ for(nsock= node->inputs.first; nsock; nsock= nsock->next) { if(!(nsock->flag & (SOCK_HIDDEN|SOCK_UNAVAIL))) { - nsock->locx= node->locx; + nsock->locx= locx; nsock->locy= dy - NODE_DYS; dy-= NODE_DY; } @@ -310,19 +326,23 @@ static void node_update(const bContext *C, bNodeTree *ntree, bNode *node) if(node->inputs.first || (node->flag & (NODE_OPTIONS|NODE_PREVIEW))==0 ) dy-= NODE_DYS/2; - node->totr.xmin= node->locx; - node->totr.xmax= node->locx + node->width; - node->totr.ymax= node->locy; - node->totr.ymin= MIN2(dy, node->locy-2*NODE_DY); + node->totr.xmin= locx; + node->totr.xmax= locx + node->width; + node->totr.ymax= locy; + node->totr.ymin= MIN2(dy, locy-2*NODE_DY); } /* based on settings in node, sets drawing rect info. each redraw! */ static void node_update_hidden(bNode *node) { bNodeSocket *nsock; + float locx, locy; float rad, drad, hiddenrad= HIDDEN_RAD; int totin=0, totout=0, tot; + /* get "global" coords */ + nodeSpaceCoords(node, &locx, &locy); + /* calculate minimal radius */ for(nsock= node->inputs.first; nsock; nsock= nsock->next) if(!(nsock->flag & (SOCK_HIDDEN|SOCK_UNAVAIL))) @@ -336,9 +356,9 @@ static void node_update_hidden(bNode *node) hiddenrad += 5.0f*(float)(tot-4); } - node->totr.xmin= node->locx; - node->totr.xmax= node->locx + 3*hiddenrad + node->miniwidth; - node->totr.ymax= node->locy + (hiddenrad - 0.5f*NODE_DY); + node->totr.xmin= locx; + node->totr.xmax= locx + 3*hiddenrad + node->miniwidth; + node->totr.ymax= locy + (hiddenrad - 0.5f*NODE_DY); node->totr.ymin= node->totr.ymax - 2*hiddenrad; /* output sockets */ @@ -364,6 +384,14 @@ static void node_update_hidden(bNode *node) } } +void node_update_default(const bContext *C, bNodeTree *ntree, bNode *node) +{ + if(node->flag & NODE_HIDDEN) + node_update_hidden(node); + else + node_update_basis(C, ntree, node); +} + static int node_get_colorid(bNode *node) { if(node->typeinfo->nclass==NODE_CLASS_INPUT) @@ -383,138 +411,42 @@ static int node_get_colorid(bNode *node) return TH_NODE; } -/* based on settings in node, sets drawing rect info. each redraw! */ -/* note: this assumes only 1 group at a time is drawn (linked data) */ -/* in node->totr the entire boundbox for the group is stored */ -static void node_update_group(const bContext *C, bNodeTree *UNUSED(ntree), bNode *gnode) -{ - bNodeTree *ngroup= (bNodeTree *)gnode->id; - bNode *node; - bNodeSocket *sock, *gsock; - rctf *rect= &gnode->totr; - float node_group_frame= U.dpi*NODE_GROUP_FRAME/72; - int counter; - int dy; - - rect->xmin = rect->xmax = gnode->locx; - rect->ymin = rect->ymax = gnode->locy; - - /* center them, is a bit of abuse of locx and locy though */ - for(node= ngroup->nodes.first; node; node= node->next) { - node->locx+= gnode->locx; - node->locy+= gnode->locy; - - if(node->flag & NODE_HIDDEN) - node_update_hidden(node); - else - node_update(C, ngroup, node); - node->locx-= gnode->locx; - node->locy-= gnode->locy; - } - counter= 1; - for(node= ngroup->nodes.first; node; node= node->next) { - if(counter) { - *rect= node->totr; - counter= 0; - } - else - BLI_union_rctf(rect, &node->totr); - } - - /* add some room for links to group sockets */ - rect->xmin -= 4*NODE_DY; - rect->xmax += 4*NODE_DY; - rect->ymin-= NODE_DY; - rect->ymax+= NODE_DY; - - /* input sockets */ - dy = 0.5f*(rect->ymin+rect->ymax) + NODE_DY*(BLI_countlist(&gnode->inputs)-1); - for(gsock=ngroup->inputs.first, sock=gnode->inputs.first; gsock; gsock=gsock->next, sock=sock->next) { - gsock->locx = rect->xmin; - sock->locx = rect->xmin - node_group_frame; - sock->locy = gsock->locy = dy; - - /* prevent long socket lists from growing out of the group box */ - if (dy-3*NODE_DYS < rect->ymin) - rect->ymin = dy-3*NODE_DYS; - if (dy+3*NODE_DYS > rect->ymax) - rect->ymax = dy+3*NODE_DYS; - - dy -= 2*NODE_DY; - } - - /* output sockets */ - dy = 0.5f*(rect->ymin+rect->ymax) + NODE_DY*(BLI_countlist(&gnode->outputs)-1); - for(gsock=ngroup->outputs.first, sock=gnode->outputs.first; gsock; gsock=gsock->next, sock=sock->next) { - gsock->locx = rect->xmax; - sock->locx = rect->xmax + node_group_frame; - sock->locy = gsock->locy = dy - NODE_DYS; - - /* prevent long socket lists from growing out of the group box */ - if (dy-3*NODE_DYS < rect->ymin) - rect->ymin = dy-3*NODE_DYS; - if (dy+3*NODE_DYS > rect->ymax) - rect->ymax = dy+3*NODE_DYS; - - dy -= 2*NODE_DY; - } -} - /* note: in cmp_util.c is similar code, for node_compo_pass_on() */ /* note: in node_edit.c is similar code, for untangle node */ static void node_draw_mute_line(View2D *v2d, SpaceNode *snode, bNode *node) { - bNodeSocket *valsock= NULL, *colsock= NULL, *vecsock= NULL; - bNodeSocket *sock; + static int types[]= { SOCK_FLOAT, SOCK_VECTOR, SOCK_RGBA }; bNodeLink link= {NULL}; - int a; + int i; - /* connect the first value buffer in with first value out */ - /* connect the first RGBA buffer in with first RGBA out */ + /* connect the first input of each type with first output of the same type */ - /* test the inputs */ - for(a=0, sock= node->inputs.first; sock; sock= sock->next, a++) { - if(nodeCountSocketLinks(snode->edittree, sock)) { - if(sock->type==SOCK_VALUE && valsock==NULL) valsock= sock; - if(sock->type==SOCK_VECTOR && vecsock==NULL) vecsock= sock; - if(sock->type==SOCK_RGBA && colsock==NULL) colsock= sock; - } - } - - /* outputs, draw lines */ glEnable(GL_BLEND); glEnable( GL_LINE_SMOOTH ); - if(valsock || colsock || vecsock) { - for(a=0, sock= node->outputs.first; sock; sock= sock->next, a++) { - if(nodeCountSocketLinks(snode->edittree, sock)) { - link.tosock= sock; - - if(sock->type==SOCK_VALUE && valsock) { - link.fromsock= valsock; - node_draw_link_bezier(v2d, snode, &link, TH_REDALERT, 0, TH_WIRE, 0, TH_WIRE); - valsock= NULL; - } - if(sock->type==SOCK_VECTOR && vecsock) { - link.fromsock= vecsock; - node_draw_link_bezier(v2d, snode, &link, TH_REDALERT, 0, TH_WIRE, 0, TH_WIRE); - vecsock= NULL; - } - if(sock->type==SOCK_RGBA && colsock) { - link.fromsock= colsock; - node_draw_link_bezier(v2d, snode, &link, TH_REDALERT, 0, TH_WIRE, 0, TH_WIRE); - colsock= NULL; - } + link.fromnode = link.tonode = node; + for (i=0; i < 3; ++i) { + /* find input socket */ + for (link.fromsock=node->inputs.first; link.fromsock; link.fromsock=link.fromsock->next) + if (link.fromsock->type==types[i] && nodeCountSocketLinks(snode->edittree, link.fromsock)) + break; + if (link.fromsock) { + for (link.tosock=node->outputs.first; link.tosock; link.tosock=link.tosock->next) + if (link.tosock->type==types[i] && nodeCountSocketLinks(snode->edittree, link.tosock)) + break; + + if (link.tosock) { + node_draw_link_bezier(v2d, snode, &link, TH_REDALERT, 0, TH_WIRE, 0, TH_WIRE); } } } + glDisable(GL_BLEND); glDisable( GL_LINE_SMOOTH ); } -/* nice AA filled circle */ /* this might have some more generic use */ -static void circle_draw(float x, float y, float size, int col[3]) +static void node_circle_draw(float x, float y, float size, char *col) { /* 16 values of sin function */ static float si[16] = { @@ -550,37 +482,10 @@ static void circle_draw(float x, float y, float size, int col[3]) glDisable(GL_BLEND); } -static void socket_circle_draw(bNodeSocket *sock, float size) +void node_socket_circle_draw(bNodeTree *UNUSED(ntree), bNodeSocket *sock, float size) { - int col[3]; - - if(sock->type==-1) { - col[0]= 0; col[1]= 0; col[2]= 0; - } - else if(sock->type==SOCK_VALUE) { - col[0]= 160; col[1]= 160; col[2]= 160; - } - else if(sock->type==SOCK_VECTOR) { - col[0]= 100; col[1]= 100; col[2]= 200; - } - else if(sock->type==SOCK_RGBA) { - col[0]= 200; col[1]= 200; col[2]= 40; - } - else { - col[0]= 100; col[1]= 200; col[2]= 100; - } - - circle_draw(sock->locx, sock->locy, size, col); -} - -static void node_sync_cb(bContext *UNUSED(C), void *snode_v, void *node_v) -{ - SpaceNode *snode= snode_v; - - if(snode->treetype==NTREE_SHADER) { - nodeShaderSynchronizeID(node_v, 1); - // allqueue(REDRAWBUTSSHADING, 0); - } + bNodeSocketType *stype = ntreeGetSocketType(sock->type); + node_circle_draw(sock->locx, sock->locy, size, stype->ui_color); } /* ************** Socket callbacks *********** */ @@ -639,83 +544,6 @@ static void node_draw_preview(bNodePreview *preview, rctf *prv) } -typedef struct SocketVectorMenuArgs { - PointerRNA ptr; - int x, y, width; - uiButHandleFunc cb; - void *arg1, *arg2; -} SocketVectorMenuArgs; - -/* NOTE: this is a block-menu, needs 0 events, otherwise the menu closes */ -static uiBlock *socket_vector_menu(bContext *C, ARegion *ar, void *args_v) -{ - SocketVectorMenuArgs *args= (SocketVectorMenuArgs*)args_v; - uiBlock *block; - uiLayout *layout; - - block= uiBeginBlock(C, ar, "socket menu", UI_EMBOSS); - uiBlockSetFlag(block, UI_BLOCK_KEEP_OPEN); - - layout= uiLayoutColumn(uiBlockLayout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, args->x, args->y+2, args->width, NODE_DY, U.uistyles.first), 0); - - uiItemR(layout, &args->ptr, "default_value", UI_ITEM_R_EXPAND, "", ICON_NONE); - - return block; -} - -static void node_draw_socket_button(bNodeTree *ntree, bNodeSocket *sock, const char *name, - uiBlock *block, int x, int y, int width, - uiButHandleFunc cb, void *arg1, void *arg2) -{ - uiBut *bt= NULL; - PointerRNA ptr; - int labelw; - SocketVectorMenuArgs *args; - - RNA_pointer_create(&ntree->id, &RNA_NodeSocket, sock, &ptr); - - switch (sock->type) { - case SOCK_VALUE: - bt=uiDefButR(block, NUM, B_NODE_EXEC, name, - x, y+1, width, NODE_DY-2, - &ptr, "default_value", 0, sock->ns.min, sock->ns.max, -1, -1, NULL); - if (cb) - uiButSetFunc(bt, cb, arg1, arg2); - break; - - case SOCK_VECTOR: - args= MEM_callocN(sizeof(SocketVectorMenuArgs), "SocketVectorMenuArgs"); - - args->ptr = ptr; - args->x = x; - args->y = y; - args->width = width; - args->cb = cb; - args->arg1 = arg1; - args->arg2 = arg2; - - uiDefBlockButN(block, socket_vector_menu, args, name, - x, y+1, width, NODE_DY-2, - ""); - break; - - case SOCK_RGBA: - labelw= width - 40; - - bt=uiDefButR(block, COL, B_NODE_EXEC, "", - x, y+2, (labelw>0 ? 40 : width), NODE_DY-2, - &ptr, "default_value", 0, sock->ns.min, sock->ns.max, -1, -1, NULL); - if (cb) - uiButSetFunc(bt, cb, arg1, arg2); - - if (name[0]!='\0' && labelw>0) - uiDefBut(block, LABEL, 0, name, - x + 40, y+2, labelw, NODE_DY-2, - NULL, 0, 0, 0, 0, ""); - break; - } -} - static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bNodeTree *ntree, bNode *node) { bNodeSocket *sock; @@ -809,13 +637,8 @@ static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bN else UI_ThemeColor(TH_TEXT); */ - if (node->label[0]!='\0') - BLI_strncpy(showname, node->label, sizeof(showname)); - else if (node->typeinfo->labelfunc) - BLI_strncpy(showname, node->typeinfo->labelfunc(node), sizeof(showname)); - else - BLI_strncpy(showname, node->typeinfo->name, sizeof(showname)); - + BLI_strncpy(showname, nodeLabel(node), sizeof(showname)); + //if(node->flag & NODE_MUTED) // sprintf(showname, "[%s]", showname); @@ -855,37 +678,45 @@ static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bN /* socket inputs, buttons */ for(sock= node->inputs.first; sock; sock= sock->next) { - if(!(sock->flag & (SOCK_HIDDEN|SOCK_UNAVAIL))) { - socket_circle_draw(sock, socket_size); - - if(node->block && sock->link==NULL) { - node_draw_socket_button(ntree, sock, sock->name, node->block, sock->locx+NODE_DYS, sock->locy-NODE_DYS, node->width-NODE_DY, node_sync_cb, snode, node); - } - else { - uiDefBut(node->block, LABEL, 0, sock->name, (short)(sock->locx+7), (short)(sock->locy-9.0f), - (short)(node->width-NODE_DY), NODE_DY, NULL, 0, 0, 0, 0, ""); - } + bNodeSocketType *stype= ntreeGetSocketType(sock->type); + + if(sock->flag & (SOCK_HIDDEN|SOCK_UNAVAIL)) + continue; + + node_socket_circle_draw(ntree, sock, NODE_SOCKSIZE); + + if (sock->link) { + uiDefBut(node->block, LABEL, 0, sock->name, sock->locx+NODE_DYS, sock->locy-NODE_DYS, node->width-NODE_DY, NODE_DY, + NULL, 0, 0, 0, 0, ""); + } + else { + if (stype->buttonfunc) + stype->buttonfunc(C, node->block, ntree, node, sock, sock->name, sock->locx+NODE_DYS, sock->locy-NODE_DYS, node->width-NODE_DY); } } /* socket outputs */ for(sock= node->outputs.first; sock; sock= sock->next) { - if(!(sock->flag & (SOCK_HIDDEN|SOCK_UNAVAIL))) { - float slen; - int ofs= 0; - - socket_circle_draw(sock, socket_size); - - UI_ThemeColor(TH_TEXT); - slen= snode->aspect*UI_GetStringWidth(sock->name); - while(slen > node->width) { - ofs++; - slen= snode->aspect*UI_GetStringWidth(sock->name+ofs); - } - - uiDefBut(node->block, LABEL, 0, sock->name+ofs, (short)(sock->locx-15.0f-slen), (short)(sock->locy-9.0f), - (short)(node->width-NODE_DY), NODE_DY, NULL, 0, 0, 0, 0, ""); + PointerRNA sockptr; + float slen; + int ofs; + + RNA_pointer_create((ID*)ntree, &RNA_NodeSocket, sock, &sockptr); + + if(sock->flag & (SOCK_HIDDEN|SOCK_UNAVAIL)) + continue; + + node_socket_circle_draw(ntree, sock, NODE_SOCKSIZE); + + ofs= 0; + UI_ThemeColor(TH_TEXT); + slen= snode->aspect*UI_GetStringWidth(sock->name); + while(slen > node->width) { + ofs++; + slen= snode->aspect*UI_GetStringWidth(sock->name+ofs); } + uiDefBut(node->block, LABEL, 0, sock->name+ofs, (short)(sock->locx-15.0f-slen), (short)(sock->locy-9.0f), + (short)(node->width-NODE_DY), NODE_DY, NULL, 0, 0, 0, 0, ""); } /* preview */ @@ -956,12 +787,7 @@ static void node_draw_hidden(const bContext *C, ARegion *ar, SpaceNode *snode, b UI_ThemeColor(TH_TEXT); if(node->miniwidth>0.0f) { - if (node->label[0]!='\0') - BLI_strncpy(showname, node->label, sizeof(showname)); - else if (node->typeinfo->labelfunc) - BLI_strncpy(showname, node->typeinfo->labelfunc(node), sizeof(showname)); - else - BLI_strncpy(showname, node->typeinfo->name, sizeof(showname)); + BLI_strncpy(showname, nodeLabel(node), sizeof(showname)); //if(node->flag & NODE_MUTED) // sprintf(showname, "[%s]", showname); @@ -984,12 +810,12 @@ static void node_draw_hidden(const bContext *C, ARegion *ar, SpaceNode *snode, b /* sockets */ for(sock= node->inputs.first; sock; sock= sock->next) { if(!(sock->flag & (SOCK_HIDDEN|SOCK_UNAVAIL))) - socket_circle_draw(sock, socket_size); + node_socket_circle_draw(snode->nodetree, sock, socket_size); } for(sock= node->outputs.first; sock; sock= sock->next) { if(!(sock->flag & (SOCK_HIDDEN|SOCK_UNAVAIL))) - socket_circle_draw(sock, socket_size); + node_socket_circle_draw(snode->nodetree, sock, socket_size); } uiEndBlock(C, node->block); @@ -997,7 +823,43 @@ static void node_draw_hidden(const bContext *C, ARegion *ar, SpaceNode *snode, b node->block= NULL; } -static void node_draw_nodetree(const bContext *C, ARegion *ar, SpaceNode *snode, bNodeTree *ntree) +void node_draw_default(const bContext *C, ARegion *ar, SpaceNode *snode, bNodeTree *ntree, bNode *node) +{ + if(node->flag & NODE_HIDDEN) + node_draw_hidden(C, ar, snode, node); + else + node_draw_basis(C, ar, snode, ntree, node); +} + +static void node_update(const bContext *C, bNodeTree *ntree, bNode *node) +{ + if (node->typeinfo->drawupdatefunc) + node->typeinfo->drawupdatefunc(C, ntree, node); +} + +void node_update_nodetree(const bContext *C, bNodeTree *ntree, float offsetx, float offsety) +{ + bNode *node; + + for(node= ntree->nodes.first; node; node= node->next) { + /* XXX little hack */ + node->locx += offsetx; + node->locy += offsety; + + node_update(C, ntree, node); + + node->locx -= offsetx; + node->locy -= offsety; + } +} + +static void node_draw(const bContext *C, ARegion *ar, SpaceNode *snode, bNodeTree *ntree, bNode *node) +{ + if (node->typeinfo->drawfunc) + node->typeinfo->drawfunc(C, ar, snode, ntree, node); +} + +void node_draw_nodetree(const bContext *C, ARegion *ar, SpaceNode *snode, bNodeTree *ntree) { bNode *node; bNodeLink *link; @@ -1013,212 +875,11 @@ static void node_draw_nodetree(const bContext *C, ARegion *ar, SpaceNode *snode, glDisable(GL_LINE_SMOOTH); glDisable(GL_BLEND); - /* not selected first */ - for(a=0, node= ntree->nodes.first; node; node= node->next, a++) { + /* draw nodes, last nodes in front */ + for(a=0, node= ntree->nodes.first; node; node=node->next, a++) { node->nr= a; /* index of node in list, used for exec event code */ - if(!(node->flag & SELECT)) { - if(node->flag & NODE_GROUP_EDIT); - else if(node->flag & NODE_HIDDEN) - node_draw_hidden(C, ar, snode, node); - else - node_draw_basis(C, ar, snode, ntree, node); - } + node_draw(C, ar, snode, ntree, node); } - - /* selected */ - for(node= ntree->nodes.first; node; node= node->next) { - if(node->flag & SELECT) { - if(node->flag & NODE_GROUP_EDIT); - else if(node->flag & NODE_HIDDEN) - node_draw_hidden(C, ar, snode, node); - else - node_draw_basis(C, ar, snode, ntree, node); - } - } -} - -static void group_verify_cb(bContext *UNUSED(C), void *UNUSED(snode_v), void *ngroup_v) -{ - bNodeTree *ngroup= (bNodeTree*)ngroup_v; - - nodeGroupVerify(ngroup); -} - -/* groups are, on creation, centered around 0,0 */ -static void node_draw_group(const bContext *C, ARegion *ar, SpaceNode *snode, bNodeTree *ntree, bNode *gnode) -{ - bNodeTree *ngroup= (bNodeTree *)gnode->id; - bNodeSocket *sock; - uiLayout *layout; - PointerRNA ptr; - uiBut *bt; - rctf rect= gnode->totr; - float socket_size= NODE_SOCKSIZE*U.dpi/72; - float node_group_frame= U.dpi*NODE_GROUP_FRAME/72; - float group_header= 26*U.dpi/72; - float arrowbutw= 0.8f*UI_UNIT_X; - /* layout stuff for buttons on group left frame */ - float col1= 6, colw1= 0.6f*node_group_frame; - float col2= col1 + colw1+6; - float col3= node_group_frame - arrowbutw - 6; - /* layout stuff for buttons on group right frame */ - float cor1= 6; - float cor2= cor1 + arrowbutw + 6; - float cor3= cor2 + arrowbutw + 6, corw3= node_group_frame - cor3-6; - - int index; - - /* backdrop header */ - glEnable(GL_BLEND); - uiSetRoundBox(3); - UI_ThemeColorShadeAlpha(TH_NODE_GROUP, 0, -70); - uiDrawBox(GL_POLYGON, rect.xmin-node_group_frame, rect.ymax, rect.xmax+node_group_frame, rect.ymax+group_header, BASIS_RAD); - - /* backdrop body */ - UI_ThemeColorShadeAlpha(TH_BACK, -8, -70); - uiSetRoundBox(0); - uiDrawBox(GL_POLYGON, rect.xmin, rect.ymin, rect.xmax, rect.ymax, BASIS_RAD); - - /* input column */ - UI_ThemeColorShadeAlpha(TH_BACK, 10, -50); - uiSetRoundBox(8); - uiDrawBox(GL_POLYGON, rect.xmin-node_group_frame, rect.ymin, rect.xmin, rect.ymax, BASIS_RAD); - - /* output column */ - UI_ThemeColorShadeAlpha(TH_BACK, 10, -50); - uiSetRoundBox(4); - uiDrawBox(GL_POLYGON, rect.xmax, rect.ymin, rect.xmax+node_group_frame, rect.ymax, BASIS_RAD); - - /* input column separator */ - glColor4ub(200, 200, 200, 140); - glBegin(GL_LINES); - glVertex2f(rect.xmin, rect.ymin); - glVertex2f(rect.xmin, rect.ymax); - glEnd(); - - /* output column separator */ - glColor4ub(200, 200, 200, 140); - glBegin(GL_LINES); - glVertex2f(rect.xmax, rect.ymin); - glVertex2f(rect.xmax, rect.ymax); - glEnd(); - - /* group node outline */ - uiSetRoundBox(15); - glColor4ub(200, 200, 200, 140); - glEnable( GL_LINE_SMOOTH ); - uiDrawBox(GL_LINE_LOOP, rect.xmin-node_group_frame, rect.ymin, rect.xmax+node_group_frame, rect.ymax+group_header, BASIS_RAD); - glDisable( GL_LINE_SMOOTH ); - glDisable(GL_BLEND); - - /* backdrop title */ - UI_ThemeColor(TH_TEXT_HI); - - layout = uiBlockLayout(gnode->block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, (short)(rect.xmin+15), (short)(rect.ymax+group_header), - MIN2((int)(rect.xmax - rect.xmin-18.0f), node_group_frame+20), group_header, U.uistyles.first); - RNA_pointer_create(&ntree->id, &RNA_Node, gnode, &ptr); - uiTemplateIDBrowse(layout, (bContext*)C, &ptr, "node_tree", NULL, NULL, NULL); - uiBlockLayoutResolve(gnode->block, NULL, NULL); - - /* draw the internal tree nodes and links */ - node_draw_nodetree(C, ar, snode, ngroup); - - /* group sockets */ - for(sock=ngroup->inputs.first, index=0; sock; sock=sock->next, ++index) { - float locx= sock->locx - node_group_frame; - - socket_circle_draw(sock, socket_size); - /* small hack to use socket_circle_draw function with offset */ - sock->locx -= node_group_frame; - socket_circle_draw(sock, socket_size); - sock->locx += node_group_frame; - - bt = uiDefBut(gnode->block, TEX, 0, "", - locx+col1, sock->locy+1, colw1, NODE_DY, - sock->name, 0, 31, 0, 0, ""); - uiButSetFunc(bt, group_verify_cb, snode, ngroup); - - node_draw_socket_button(ngroup, sock, "", gnode->block, - locx+col1, sock->locy-NODE_DY, colw1, - NULL, NULL, NULL); - - uiBlockSetDirection(gnode->block, UI_TOP); - uiBlockBeginAlign(gnode->block); - bt = uiDefIconButO(gnode->block, BUT, "NODE_OT_group_socket_move_up", 0, ICON_TRIA_UP, - locx+col2, sock->locy, arrowbutw, arrowbutw, ""); - if (!sock->prev) - uiButSetFlag(bt, UI_BUT_DISABLED); - RNA_int_set(uiButGetOperatorPtrRNA(bt), "index", index); - RNA_enum_set(uiButGetOperatorPtrRNA(bt), "in_out", SOCK_IN); - bt = uiDefIconButO(gnode->block, BUT, "NODE_OT_group_socket_move_down", 0, ICON_TRIA_DOWN, - locx+col2, sock->locy-arrowbutw, arrowbutw, arrowbutw, ""); - if (!sock->next) - uiButSetFlag(bt, UI_BUT_DISABLED); - RNA_int_set(uiButGetOperatorPtrRNA(bt), "index", index); - RNA_enum_set(uiButGetOperatorPtrRNA(bt), "in_out", SOCK_IN); - uiBlockEndAlign(gnode->block); - uiBlockSetDirection(gnode->block, 0); - - uiBlockSetEmboss(gnode->block, UI_EMBOSSN); - bt = uiDefIconButO(gnode->block, BUT, "NODE_OT_group_socket_remove", 0, ICON_X, - locx+col3, sock->locy-0.5f*arrowbutw, arrowbutw, arrowbutw, ""); - RNA_int_set(uiButGetOperatorPtrRNA(bt), "index", index); - RNA_enum_set(uiButGetOperatorPtrRNA(bt), "in_out", SOCK_IN); - uiBlockSetEmboss(gnode->block, UI_EMBOSS); - } - - for(sock=ngroup->outputs.first, index=0; sock; sock=sock->next, ++index) { - float locx= sock->locx; - - socket_circle_draw(sock, socket_size); - /* small hack to use socket_circle_draw function with offset */ - sock->locx += node_group_frame; - socket_circle_draw(sock, socket_size); - sock->locx -= node_group_frame; - - uiBlockSetEmboss(gnode->block, UI_EMBOSSN); - bt = uiDefIconButO(gnode->block, BUT, "NODE_OT_group_socket_remove", 0, ICON_X, - locx+col1, sock->locy-0.5f*arrowbutw, arrowbutw, arrowbutw, ""); - RNA_int_set(uiButGetOperatorPtrRNA(bt), "index", index); - RNA_enum_set(uiButGetOperatorPtrRNA(bt), "in_out", SOCK_OUT); - uiBlockSetEmboss(gnode->block, UI_EMBOSS); - - uiBlockSetDirection(gnode->block, UI_TOP); - uiBlockBeginAlign(gnode->block); - bt = uiDefIconButO(gnode->block, BUT, "NODE_OT_group_socket_move_up", 0, ICON_TRIA_UP, - locx+cor2, sock->locy, arrowbutw, arrowbutw, ""); - if (!sock->prev) - uiButSetFlag(bt, UI_BUT_DISABLED); - RNA_int_set(uiButGetOperatorPtrRNA(bt), "index", index); - RNA_enum_set(uiButGetOperatorPtrRNA(bt), "in_out", SOCK_OUT); - bt = uiDefIconButO(gnode->block, BUT, "NODE_OT_group_socket_move_down", 0, ICON_TRIA_DOWN, - locx+cor2, sock->locy-arrowbutw, arrowbutw, arrowbutw, ""); - if (!sock->next) - uiButSetFlag(bt, UI_BUT_DISABLED); - RNA_int_set(uiButGetOperatorPtrRNA(bt), "index", index); - RNA_enum_set(uiButGetOperatorPtrRNA(bt), "in_out", SOCK_OUT); - uiBlockEndAlign(gnode->block); - uiBlockSetDirection(gnode->block, 0); - - if (sock->link) { - bt = uiDefBut(gnode->block, TEX, 0, "", - locx+cor3, sock->locy-NODE_DYS+1, corw3, NODE_DY, - sock->name, 0, 31, 0, 0, ""); - uiButSetFunc(bt, group_verify_cb, snode, ngroup); - } - else { - bt = uiDefBut(gnode->block, TEX, 0, "", - locx+cor3, sock->locy+1, corw3, NODE_DY, - sock->name, 0, 31, 0, 0, ""); - uiButSetFunc(bt, group_verify_cb, snode, ngroup); - - node_draw_socket_button(ngroup, sock, "", gnode->block, locx+cor3, sock->locy-NODE_DY, corw3, NULL, NULL, NULL); - } - } - - uiEndBlock(C, gnode->block); - uiDrawBlock(C, gnode->block); - gnode->block= NULL; } void drawnodespace(const bContext *C, ARegion *ar, View2D *v2d) @@ -1260,27 +921,19 @@ void drawnodespace(const bContext *C, ARegion *ar, View2D *v2d) if(node->flag & NODE_GROUP_EDIT) node_uiblocks_init(C, (bNodeTree *)node->id); } - + node_uiblocks_init(C, snode->nodetree); - - /* for now, we set drawing coordinates on each redraw */ - for(node= snode->nodetree->nodes.first; node; node= node->next) { - if(node->flag & NODE_GROUP_EDIT) - node_update_group(C, snode->nodetree, node); - else if(node->flag & NODE_HIDDEN) - node_update_hidden(node); - else - node_update(C, snode->nodetree, node); - } - + node_update_nodetree(C, snode->nodetree, 0.0f, 0.0f); node_draw_nodetree(C, ar, snode, snode->nodetree); - + + #if 0 /* active group */ for(node= snode->nodetree->nodes.first; node; node= node->next) { if(node->flag & NODE_GROUP_EDIT) node_draw_group(C, ar, snode, snode->nodetree, node); } + #endif } /* temporary links */ diff --git a/source/blender/editors/space_node/node_edit.c b/source/blender/editors/space_node/node_edit.c index 508cb82ee1b..214f375855d 100644 --- a/source/blender/editors/space_node/node_edit.c +++ b/source/blender/editors/space_node/node_edit.c @@ -40,9 +40,11 @@ #include "MEM_guardedalloc.h" +#include "DNA_ID.h" #include "DNA_object_types.h" #include "DNA_material_types.h" #include "DNA_node_types.h" +#include "DNA_particle_types.h" #include "DNA_scene_types.h" #include "BLI_math.h" @@ -58,11 +60,17 @@ #include "BKE_main.h" #include "BKE_node.h" #include "BKE_material.h" +#include "BKE_modifier.h" #include "BKE_paint.h" #include "BKE_screen.h" #include "BKE_texture.h" #include "BKE_report.h" + +#include "BLI_math.h" +#include "BLI_blenlib.h" +#include "BLI_storage_types.h" + #include "RE_pipeline.h" #include "IMB_imbuf_types.h" @@ -74,11 +82,13 @@ #include "RNA_access.h" #include "RNA_define.h" +#include "RNA_enum_types.h" #include "WM_api.h" #include "WM_types.h" #include "UI_interface.h" +#include "UI_resources.h" #include "UI_view2d.h" #include "IMB_imbuf.h" @@ -88,9 +98,9 @@ #include "node_intern.h" static EnumPropertyItem socket_in_out_items[] = { - { SOCK_IN, "IN", 0, "In", "" }, - { SOCK_OUT, "OUT", 0, "Out", "" }, - { 0, NULL, 0, NULL, NULL} + { SOCK_IN, "SOCK_IN", 0, "Input", "" }, + { SOCK_OUT, "SOCK_OUT", 0, "Output", "" }, + { 0, NULL, 0, NULL, NULL }, }; /* ***************** composite job manager ********************** */ @@ -227,7 +237,7 @@ static bNode *editnode_get_active(bNodeTree *ntree) /* check for edited group */ for(node= ntree->nodes.first; node; node= node->next) - if(node->flag & NODE_GROUP_EDIT) + if(nodeGroupEditGet(node)) break; if(node) return nodeGetActive((bNodeTree *)node->id); @@ -258,7 +268,7 @@ bNode *node_tree_get_editgroup(bNodeTree *nodetree) /* get the groupnode */ for(gnode= nodetree->nodes.first; gnode; gnode= gnode->next) - if(gnode->flag & NODE_GROUP_EDIT) + if(nodeGroupEditGet(gnode)) break; return gnode; } @@ -269,6 +279,7 @@ void ED_node_shader_default(Material *ma) { bNode *in, *out; bNodeSocket *fromsock, *tosock; + bNodeTemplate ntemp; /* but lets check it anyway */ if(ma->nodetree) { @@ -277,12 +288,14 @@ void ED_node_shader_default(Material *ma) return; } - ma->nodetree= ntreeAddTree("Shader Nodetree", NTREE_SHADER, FALSE); + ma->nodetree= ntreeAddTree("Shader Nodetree", NTREE_SHADER, 0); - out= nodeAddNodeType(ma->nodetree, SH_NODE_OUTPUT, NULL, NULL); + ntemp.type = SH_NODE_OUTPUT; + out= nodeAddNode(ma->nodetree, &ntemp); out->locx= 300.0f; out->locy= 300.0f; - in= nodeAddNodeType(ma->nodetree, SH_NODE_MATERIAL, NULL, NULL); + ntemp.type = SH_NODE_MATERIAL; + in= nodeAddNode(ma->nodetree, &ntemp); in->locx= 10.0f; in->locy= 300.0f; nodeSetActive(ma->nodetree, in); @@ -291,7 +304,7 @@ void ED_node_shader_default(Material *ma) tosock= out->inputs.first; nodeAddLink(ma->nodetree, in, fromsock, out, tosock); - ntreeSolveOrder(ma->nodetree); /* needed for pointers */ + ntreeUpdateTree(ma->nodetree); } /* assumes nothing being done in ntree yet, sets the default in/out node */ @@ -300,6 +313,7 @@ void ED_node_composit_default(Scene *sce) { bNode *in, *out; bNodeSocket *fromsock, *tosock; + bNodeTemplate ntemp; /* but lets check it anyway */ if(sce->nodetree) { @@ -308,14 +322,16 @@ void ED_node_composit_default(Scene *sce) return; } - sce->nodetree= ntreeAddTree("Compositing Nodetree", NTREE_COMPOSIT, FALSE); + sce->nodetree= ntreeAddTree("Compositing Nodetree", NTREE_COMPOSIT, 0); - out= nodeAddNodeType(sce->nodetree, CMP_NODE_COMPOSITE, NULL, NULL); + ntemp.type = CMP_NODE_COMPOSITE; + out= nodeAddNode(sce->nodetree, &ntemp); out->locx= 300.0f; out->locy= 400.0f; out->id= &sce->id; id_us_plus(out->id); - in= nodeAddNodeType(sce->nodetree, CMP_NODE_R_LAYERS, NULL, NULL); + ntemp.type = CMP_NODE_R_LAYERS; + in= nodeAddNode(sce->nodetree, &ntemp); in->locx= 10.0f; in->locy= 400.0f; in->id= &sce->id; id_us_plus(in->id); @@ -326,7 +342,7 @@ void ED_node_composit_default(Scene *sce) tosock= out->inputs.first; nodeAddLink(sce->nodetree, in, fromsock, out, tosock); - ntreeSolveOrder(sce->nodetree); /* needed for pointers */ + ntreeUpdateTree(sce->nodetree); // XXX ntreeCompositForceHidden(sce->nodetree); } @@ -337,6 +353,7 @@ void ED_node_texture_default(Tex *tx) { bNode *in, *out; bNodeSocket *fromsock, *tosock; + bNodeTemplate ntemp; /* but lets check it anyway */ if(tx->nodetree) { @@ -345,12 +362,14 @@ void ED_node_texture_default(Tex *tx) return; } - tx->nodetree= ntreeAddTree("Texture Nodetree", NTREE_TEXTURE, FALSE); + tx->nodetree= ntreeAddTree("Texture Nodetree", NTREE_TEXTURE, 0); - out= nodeAddNodeType(tx->nodetree, TEX_NODE_OUTPUT, NULL, NULL); + ntemp.type = TEX_NODE_OUTPUT; + out= nodeAddNode(tx->nodetree, &ntemp); out->locx= 300.0f; out->locy= 300.0f; - in= nodeAddNodeType(tx->nodetree, TEX_NODE_CHECKER, NULL, NULL); + ntemp.type = TEX_NODE_CHECKER; + in= nodeAddNode(tx->nodetree, &ntemp); in->locx= 10.0f; in->locy= 300.0f; nodeSetActive(tx->nodetree, in); @@ -358,43 +377,53 @@ void ED_node_texture_default(Tex *tx) tosock= out->inputs.first; nodeAddLink(tx->nodetree, in, fromsock, out, tosock); - ntreeSolveOrder(tx->nodetree); /* needed for pointers */ + ntreeUpdateTree(tx->nodetree); } /* id is supposed to contain a node tree */ void node_tree_from_ID(ID *id, bNodeTree **ntree, bNodeTree **edittree, int *treetype) { - bNode *node= NULL; - short idtype= GS(id->name); - - if(idtype == ID_MA) { - *ntree= ((Material*)id)->nodetree; - if(treetype) *treetype= NTREE_SHADER; - } - else if(idtype == ID_SCE) { - *ntree= ((Scene*)id)->nodetree; - if(treetype) *treetype= NTREE_COMPOSIT; - } - else if(idtype == ID_TE) { - *ntree= ((Tex*)id)->nodetree; - if(treetype) *treetype= NTREE_TEXTURE; + if (id) { + bNode *node= NULL; + short idtype= GS(id->name); + + if(idtype == ID_NT) { + *ntree= (bNodeTree*)id; + if(treetype) *treetype= (*ntree)->type; + } + else if(idtype == ID_MA) { + *ntree= ((Material*)id)->nodetree; + if(treetype) *treetype= NTREE_SHADER; + } + else if(idtype == ID_SCE) { + *ntree= ((Scene*)id)->nodetree; + if(treetype) *treetype= NTREE_COMPOSIT; + } + else if(idtype == ID_TE) { + *ntree= ((Tex*)id)->nodetree; + if(treetype) *treetype= NTREE_TEXTURE; + } + else { + if(treetype) *treetype= 0; + return; + } + + /* find editable group */ + if(edittree) { + if(*ntree) + for(node= (*ntree)->nodes.first; node; node= node->next) + if(nodeGroupEditGet(node)) + break; + + if(node && node->id) + *edittree= (bNodeTree *)node->id; + else + *edittree= *ntree; + } } else { + *ntree= NULL; if(treetype) *treetype= 0; - return; - } - - /* find editable group */ - if(edittree) { - if(*ntree) - for(node= (*ntree)->nodes.first; node; node= node->next) - if(node->flag & NODE_GROUP_EDIT) - break; - - if(node && node->id) - *edittree= (bNodeTree *)node->id; - else - *edittree= *ntree; } } @@ -403,8 +432,6 @@ void snode_set_context(SpaceNode *snode, Scene *scene) { Object *ob= OBACT; - snode->nodetree= NULL; - snode->edittree= NULL; snode->id= snode->from= NULL; if(snode->treetype==NTREE_SHADER) { @@ -418,7 +445,6 @@ void snode_set_context(SpaceNode *snode, Scene *scene) } } else if(snode->treetype==NTREE_COMPOSIT) { - snode->from= NULL; snode->id= &scene->id; /* bit clumsy but reliable way to see if we draw first time */ @@ -461,9 +487,14 @@ void snode_set_context(SpaceNode *snode, Scene *scene) } } } + else { + if (snode->nodetree && snode->nodetree->type == snode->treetype) + snode->id = &snode->nodetree->id; + else + snode->id = NULL; + } - if(snode->id) - node_tree_from_ID(snode->id, &snode->nodetree, &snode->edittree, NULL); + node_tree_from_ID(snode->id, &snode->nodetree, &snode->edittree, NULL); } static void snode_tag_changed(SpaceNode *snode, bNode *node) @@ -574,17 +605,199 @@ void ED_node_set_active(Main *bmain, bNodeTree *ntree, bNode *node) } } -/* when links in groups change, inputs/outputs change, nodes added/deleted... */ -void node_tree_verify_groups(bNodeTree *nodetree) +static int compare_nodes(bNode *a, bNode *b) { - bNode *gnode; + bNode *parent; - gnode= node_tree_get_editgroup(nodetree); + /* if one is an ancestor of the other */ + /* XXX there might be a better sorting algorithm for stable topological sort, this is O(n^2) worst case */ + for (parent = a->parent; parent; parent=parent->parent) { + if (parent==b) + return 1; + } + for (parent = b->parent; parent; parent=parent->parent) { + if (parent==a) + return 0; + } + + /* if one of the nodes is in the background and the other not */ + if ((a->flag & NODE_BACKGROUND) && !(b->typeinfo->flag & NODE_BACKGROUND)) + return 0; + else if (!(a->flag & NODE_BACKGROUND) && (b->typeinfo->flag & NODE_BACKGROUND)) + return 1; - /* does all materials */ - if(gnode) - nodeGroupVerify((bNodeTree *)gnode->id); + /* if one has a higher selection state (active > selected > nothing) */ + if (!(b->flag & NODE_ACTIVE) && (a->flag & NODE_ACTIVE)) + return 1; + else if (!(b->flag & NODE_SELECT) && ((a->flag & NODE_ACTIVE) || (a->flag & NODE_SELECT))) + return 1; + return 0; +} +/* Sorts nodes by selection: unselected nodes first, then selected, + * then the active node at the very end. Relative order is kept intact! + */ +void node_sort(bNodeTree *ntree) +{ + /* merge sort is the algorithm of choice here */ + bNode *first_a, *first_b, *node_a, *node_b, *tmp; + int totnodes= BLI_countlist(&ntree->nodes); + int k, a, b; + + k = 1; + while (k < totnodes) { + first_a = first_b = ntree->nodes.first; + + do { + /* setup first_b pointer */ + for (b=0; b < k && first_b; ++b) { + first_b = first_b->next; + } + /* all batches merged? */ + if (first_b==NULL) + break; + + /* merge batches */ + node_a = first_a; + node_b = first_b; + a = b = 0; + while (a < k && b < k && node_b) { + if (compare_nodes(node_a, node_b)==0) { + node_a = node_a->next; + ++a; + } + else { + tmp = node_b; + node_b = node_b->next; + ++b; + BLI_remlink(&ntree->nodes, tmp); + BLI_insertlinkbefore(&ntree->nodes, node_a, tmp); + } + } + + /* setup first pointers for next batch */ + first_b = node_b; + for (; b < k; ++b) { + /* all nodes sorted? */ + if (first_b==NULL) + break; + first_b = first_b->next; + } + first_a = first_b; + } while (first_b); + + k = k << 1; + } +} + +static int inside_rctf(rctf *bounds, rctf *rect) +{ + return (bounds->xmin <= rect->xmin && bounds->xmax >= rect->xmax + && bounds->ymin <= rect->ymin && bounds->ymax >= rect->ymax); +} + +static void node_frame_attach_nodes(bNodeTree *UNUSED(ntree), bNode *frame) +{ + bNode *node; + + /* only check nodes on top of the frame for attaching */ + for (node=frame->next; node; node=node->next) { + if (node->parent==frame) { + /* detach nodes that went outside the frame */ + if (!inside_rctf(&frame->totr, &node->totr)) + nodeDetachNode(node); + } + else if (node->flag & NODE_SELECT && node->parent==NULL) { + /* attach selected, still unparented nodes */ + if (inside_rctf(&frame->totr, &node->totr)) + nodeAttachNode(node, frame); + } + } +} + +void ED_node_update_hierarchy(bContext *UNUSED(C), bNodeTree *ntree) +{ + bNode *node; + + /* XXX This does not work due to layout functions relying on node->block, + * which only exists during actual drawing. Can we rely on valid totr rects? + */ + /* make sure nodes have correct bounding boxes after transform */ +// node_update_nodetree(C, ntree, 0.0f, 0.0f); + + /* all selected nodes are re-parented */ + for (node=ntree->nodes.last; node; node=node->prev) { + if (node->flag & NODE_SELECT && node->parent) + nodeDetachNode(node); + } + + /* update higher Z-level nodes first */ + for (node=ntree->nodes.last; node; node=node->prev) { + /* XXX callback? */ + if (node->type==NODE_FRAME) + node_frame_attach_nodes(ntree, node); + } +} + +/* ***************** generic operator functions for nodes ***************** */ + +static int edit_node_poll(bContext *C) +{ + return ED_operator_node_active(C); +} + +static void edit_node_properties(wmOperatorType *ot) +{ + /* XXX could node be a context pointer? */ + RNA_def_string(ot->srna, "node", "", 32, "Node", ""); + RNA_def_int(ot->srna, "socket", 0, 0, MAX_SOCKET, "Socket", "", 0, MAX_SOCKET); + RNA_def_enum(ot->srna, "in_out", socket_in_out_items, SOCK_IN, "Socket Side", ""); +} + +static int edit_node_invoke_properties(bContext *C, wmOperator *op) +{ + if (!RNA_property_is_set(op->ptr, "node")) { + bNode *node= CTX_data_pointer_get_type(C, "node", &RNA_Node).data; + if (!node) + return 0; + else + RNA_string_set(op->ptr, "node", node->name); + } + + if (!RNA_property_is_set(op->ptr, "in_out")) + RNA_enum_set(op->ptr, "in_out", SOCK_IN); + + if (!RNA_property_is_set(op->ptr, "socket")) + RNA_int_set(op->ptr, "socket", 0); + + return 1; +} + +static void edit_node_properties_get(wmOperator *op, bNodeTree *ntree, bNode **rnode, bNodeSocket **rsock, int *rin_out) +{ + bNode *node; + bNodeSocket *sock; + char nodename[32]; + int sockindex; + int in_out; + + RNA_string_get(op->ptr, "node", nodename); + node = nodeFindNodebyName(ntree, nodename); + + in_out = RNA_enum_get(op->ptr, "in_out"); + + sockindex = RNA_int_get(op->ptr, "socket"); + switch (in_out) { + case SOCK_IN: sock = BLI_findlink(&node->inputs, sockindex); break; + case SOCK_OUT: sock = BLI_findlink(&node->outputs, sockindex); break; + } + + if (rnode) + *rnode = node; + if (rsock) + *rsock = sock; + if (rin_out) + *rin_out = in_out; } /* ***************** Edit Group operator ************* */ @@ -594,8 +807,8 @@ void snode_make_group_editable(SpaceNode *snode, bNode *gnode) bNode *node; /* make sure nothing has group editing on */ - for(node= snode->nodetree->nodes.first; node; node= node->next) - node->flag &= ~NODE_GROUP_EDIT; + for(node=snode->nodetree->nodes.first; node; node=node->next) + nodeGroupEditClear(node); if(gnode==NULL) { /* with NULL argument we do a toggle */ @@ -603,34 +816,30 @@ void snode_make_group_editable(SpaceNode *snode, bNode *gnode) gnode= nodeGetActive(snode->nodetree); } - if(gnode && gnode->type==NODE_GROUP && gnode->id) { - if(gnode->id->lib) - ntreeMakeLocal((bNodeTree *)gnode->id); - - gnode->flag |= NODE_GROUP_EDIT; - snode->edittree= (bNodeTree *)gnode->id; + if (gnode) { + snode->edittree = nodeGroupEditSet(gnode, 1); /* deselect all other nodes, so we can also do grabbing of entire subtree */ for(node= snode->nodetree->nodes.first; node; node= node->next) node->flag &= ~SELECT; gnode->flag |= SELECT; - } else snode->edittree= snode->nodetree; - - ntreeSolveOrder(snode->nodetree); } static int node_group_edit_exec(bContext *C, wmOperator *UNUSED(op)) { SpaceNode *snode = CTX_wm_space_node(C); - bNode *gnode; ED_preview_kill_jobs(C); - gnode= nodeGetActive(snode->edittree); - snode_make_group_editable(snode, gnode); + if (snode->nodetree==snode->edittree) { + bNode *gnode= nodeGetActive(snode->nodetree); + snode_make_group_editable(snode, gnode); + } + else + snode_make_group_editable(snode, NULL); WM_event_add_notifier(C, NC_SCENE|ND_NODES, NULL); @@ -643,7 +852,8 @@ static int node_group_edit_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(e bNode *gnode; gnode= nodeGetActive(snode->edittree); - if(gnode && gnode->type==NODE_GROUP && gnode->id && gnode->id->lib) { + /* XXX callback? */ + if(gnode && gnode->id && GS(gnode->id->name)==ID_NT && gnode->id->lib) { uiPupMenuOkee(C, op->type->idname, "Make group local?"); return OPERATOR_CANCELLED; } @@ -674,7 +884,7 @@ static int node_group_socket_add_exec(bContext *C, wmOperator *op) SpaceNode *snode = CTX_wm_space_node(C); int in_out= -1; char name[32]= ""; - int type= SOCK_VALUE; + int type= SOCK_FLOAT; bNodeTree *ngroup= snode->edittree; bNodeSocket *sock; @@ -691,9 +901,10 @@ static int node_group_socket_add_exec(bContext *C, wmOperator *op) else return OPERATOR_CANCELLED; - sock = nodeGroupAddSocket(ngroup, name, type, in_out); + /* using placeholder subtype first */ + sock = node_group_add_socket(ngroup, name, type, in_out); - node_tree_verify_groups(snode->nodetree); + ntreeUpdateTree(ngroup); snode_notify(C, snode); @@ -716,7 +927,7 @@ void NODE_OT_group_socket_add(wmOperatorType *ot) RNA_def_enum(ot->srna, "in_out", socket_in_out_items, SOCK_IN, "Socket Type", "Input or Output"); RNA_def_string(ot->srna, "name", "", 32, "Name", "Group socket name"); - RNA_def_enum(ot->srna, "type", node_socket_type_items, SOCK_VALUE, "Type", "Type of the group socket"); + RNA_def_enum(ot->srna, "type", node_socket_type_items, SOCK_FLOAT, "Type", "Type of the group socket"); } /* ***************** Remove Group Socket operator ************* */ @@ -743,8 +954,8 @@ static int node_group_socket_remove_exec(bContext *C, wmOperator *op) sock = (bNodeSocket*)BLI_findlink(in_out==SOCK_IN ? &ngroup->inputs : &ngroup->outputs, index); if (sock) { - nodeGroupRemoveSocket(ngroup, sock, in_out); - node_tree_verify_groups(snode->nodetree); + node_group_remove_socket(ngroup, sock, in_out); + ntreeUpdateTree(ngroup); snode_notify(C, snode); } @@ -801,6 +1012,8 @@ static int node_group_socket_move_up_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; BLI_remlink(&ngroup->inputs, sock); BLI_insertlinkbefore(&ngroup->inputs, prev, sock); + + ngroup->update |= NTREE_UPDATE_GROUP_IN; } else if (in_out==SOCK_OUT) { sock = (bNodeSocket*)BLI_findlink(&ngroup->outputs, index); @@ -810,8 +1023,10 @@ static int node_group_socket_move_up_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; BLI_remlink(&ngroup->outputs, sock); BLI_insertlinkbefore(&ngroup->outputs, prev, sock); + + ngroup->update |= NTREE_UPDATE_GROUP_OUT; } - node_tree_verify_groups(snode->nodetree); + ntreeUpdateTree(ngroup); snode_notify(C, snode); @@ -867,6 +1082,8 @@ static int node_group_socket_move_down_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; BLI_remlink(&ngroup->inputs, sock); BLI_insertlinkafter(&ngroup->inputs, next, sock); + + ngroup->update |= NTREE_UPDATE_GROUP_IN; } else if (in_out==SOCK_OUT) { sock = (bNodeSocket*)BLI_findlink(&ngroup->outputs, index); @@ -876,8 +1093,10 @@ static int node_group_socket_move_down_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; BLI_remlink(&ngroup->outputs, sock); BLI_insertlinkafter(&ngroup->outputs, next, sock); + + ngroup->update |= NTREE_UPDATE_GROUP_OUT; } - node_tree_verify_groups(snode->nodetree); + ntreeUpdateTree(ngroup); snode_notify(C, snode); @@ -924,7 +1143,7 @@ static int node_group_ungroup_exec(bContext *C, wmOperator *op) BKE_report(op->reports, RPT_WARNING, "Not a group"); return OPERATOR_CANCELLED; } - else if(!nodeGroupUnGroup(snode->edittree, gnode)) { + else if(!node_group_ungroup(snode->edittree, gnode)) { BKE_report(op->reports, RPT_WARNING, "Can't ungroup"); return OPERATOR_CANCELLED; } @@ -952,70 +1171,16 @@ void NODE_OT_group_ungroup(wmOperatorType *ot) /* ************************** Node generic ************** */ -/* allows to walk the list in order of visibility */ -bNode *next_node(bNodeTree *ntree) -{ - static bNode *current=NULL, *last= NULL; - - if(ntree) { - /* set current to the first selected node */ - for(current= ntree->nodes.last; current; current= current->prev) - if(current->flag & NODE_SELECT) - break; - - /* set last to the first unselected node */ - for(last= ntree->nodes.last; last; last= last->prev) - if((last->flag & NODE_SELECT)==0) - break; - - if(current==NULL) - current= last; - - return NULL; - } - /* no nodes, or we are ready */ - if(current==NULL) - return NULL; - - /* now we walk the list backwards, but we always return current */ - if(current->flag & NODE_SELECT) { - bNode *node= current; - - /* find previous selected */ - current= current->prev; - while(current && (current->flag & NODE_SELECT)==0) - current= current->prev; - - /* find first unselected */ - if(current==NULL) - current= last; - - return node; - } - else { - bNode *node= current; - - /* find previous unselected */ - current= current->prev; - while(current && (current->flag & NODE_SELECT)) - current= current->prev; - - return node; - } - - return NULL; -} - /* is rct in visible part of node? */ static bNode *visible_node(SpaceNode *snode, rctf *rct) { - bNode *tnode; + bNode *node; - for(next_node(snode->edittree); (tnode=next_node(NULL));) { - if(BLI_isect_rctf(&tnode->totr, rct, NULL)) + for(node=snode->edittree->nodes.last; node; node=node->prev) { + if(BLI_isect_rctf(&node->totr, rct, NULL)) break; } - return tnode; + return node; } /* **************************** */ @@ -1318,8 +1483,9 @@ void NODE_OT_backimage_sample(wmOperatorType *ot) /* ********************** size widget operator ******************** */ typedef struct NodeSizeWidget { - float mxstart; - float oldwidth; + float mxstart, mystart; + float oldwidth, oldheight; + float oldminiwidth; } NodeSizeWidget; static int node_resize_modal(bContext *C, wmOperator *op, wmEvent *event) @@ -1338,13 +1504,16 @@ static int node_resize_modal(bContext *C, wmOperator *op, wmEvent *event) if (node) { if(node->flag & NODE_HIDDEN) { - node->miniwidth= nsw->oldwidth + mx - nsw->mxstart; + node->miniwidth= nsw->oldminiwidth + mx - nsw->mxstart; CLAMP(node->miniwidth, 0.0f, 100.0f); } else { node->width= nsw->oldwidth + mx - nsw->mxstart; CLAMP(node->width, UI_DPI_FAC*node->typeinfo->minwidth, UI_DPI_FAC*node->typeinfo->maxwidth); } + /* height works the other way round ... */ + node->height= nsw->oldheight - my + nsw->mystart; + CLAMP(node->height, node->typeinfo->minheight, node->typeinfo->maxheight); } ED_region_tag_redraw(ar); @@ -1358,6 +1527,8 @@ static int node_resize_modal(bContext *C, wmOperator *op, wmEvent *event) MEM_freeN(nsw); op->customdata= NULL; + ED_node_update_hierarchy(C, snode->edittree); + return OPERATOR_FINISHED; } @@ -1371,35 +1542,21 @@ static int node_resize_invoke(bContext *C, wmOperator *op, wmEvent *event) bNode *node= editnode_get_active(snode->edittree); if(node) { - rctf totr; - /* convert mouse coordinates to v2d space */ UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &snode->mx, &snode->my); - totr= node->totr; - - if(node->flag & NODE_HIDDEN) { - /* right part of node */ - totr.xmin= node->totr.xmax-20.0f; - } - else { - /* bottom right corner */ - totr.xmin= totr.xmax-10.0f; - totr.ymax= totr.ymin+10.0f; - } - - if(BLI_in_rctf(&totr, snode->mx, snode->my)) { + if(node->typeinfo->resize_area_func(node, snode->mx, snode->my)) { NodeSizeWidget *nsw= MEM_callocN(sizeof(NodeSizeWidget), "size widget op data"); op->customdata= nsw; nsw->mxstart= snode->mx; + nsw->mystart= snode->my; /* store old */ - if(node->flag & NODE_HIDDEN) - nsw->oldwidth= node->miniwidth; - else - nsw->oldwidth= node->width; + nsw->oldwidth= node->width; + nsw->oldheight= node->height; + nsw->oldminiwidth= node->miniwidth; /* add modal handler */ WM_event_add_modal_handler(C, op); @@ -1598,7 +1755,7 @@ static void node_link_viewer(SpaceNode *snode, bNode *tonode) link->fromnode= tonode; link->fromsock= sock; } - ntreeSolveOrder(snode->edittree); + ntreeUpdateTree(snode->edittree); snode_tag_changed(snode, node); } } @@ -1905,6 +2062,7 @@ void snode_autoconnect(SpaceNode *snode, int allow_multiple, int replace) ListBase *nodelist = MEM_callocN(sizeof(ListBase), "items_list"); bNodeListItem *nli; bNode *node; + bNodeLink *link; int i, numlinks=0; for(node= snode->edittree->nodes.first; node; node= node->next) { @@ -1941,7 +2099,15 @@ void snode_autoconnect(SpaceNode *snode, int allow_multiple, int replace) /* then we can connect */ if (replace) nodeRemSocketLinks(snode->edittree, sock_to); - nodeAddLink(snode->edittree, node_fr, sock_fr, node_to, sock_to); + + link = nodeAddLink(snode->edittree, node_fr, sock_fr, node_to, sock_to); + /* validate the new link */ + ntreeUpdateTree(snode->edittree); + if (!(link->flag & NODE_LINK_VALID)) { + nodeRemLink(snode->edittree, link); + continue; + } + snode_tag_changed(snode, node_to); ++numlinks; break; @@ -1949,8 +2115,7 @@ void snode_autoconnect(SpaceNode *snode, int allow_multiple, int replace) } if (numlinks > 0) { - node_tree_verify_groups(snode->nodetree); - ntreeSolveOrder(snode->edittree); + ntreeUpdateTree(snode->edittree); } BLI_freelistN(nodelist); @@ -1958,28 +2123,13 @@ void snode_autoconnect(SpaceNode *snode, int allow_multiple, int replace) } /* can be called from menus too, but they should do own undopush and redraws */ -bNode *node_add_node(SpaceNode *snode, Main *bmain, Scene *scene, int type, float locx, float locy) +bNode *node_add_node(SpaceNode *snode, Main *bmain, Scene *scene, bNodeTemplate *ntemp, float locx, float locy) { bNode *node= NULL, *gnode; node_deselectall(snode); - if(type>=NODE_DYNAMIC_MENU) { - node= nodeAddNodeType(snode->edittree, type, NULL, NULL); - } - else if(type>=NODE_GROUP_MENU) { - if(snode->edittree!=snode->nodetree) { - // XXX error("Can not add a Group in a Group"); - return NULL; - } - else { - bNodeTree *ngroup= BLI_findlink(&bmain->nodetree, type-NODE_GROUP_MENU); - if(ngroup) - node= nodeAddNodeType(snode->edittree, NODE_GROUP, ngroup, NULL); - } - } - else - node= nodeAddNodeType(snode->edittree, type, NULL, NULL); + node = nodeAddNode(snode->edittree, ntemp); /* generics */ if(node) { @@ -1993,7 +2143,7 @@ bNode *node_add_node(SpaceNode *snode, Main *bmain, Scene *scene, int type, floa node->locy -= gnode->locy; } - node_tree_verify_groups(snode->nodetree); + ntreeUpdateTree(snode->edittree); ED_node_set_active(bmain, snode->edittree, node); if(snode->nodetree->type==NTREE_COMPOSIT) { @@ -2025,6 +2175,7 @@ static int node_duplicate_exec(bContext *C, wmOperator *op) bNode *node, *newnode, *lastnode; bNodeLink *link, *newlink, *lastlink; int keep_inputs = RNA_boolean_get(op->ptr, "keep_inputs"); + bNodeSocket *sock; ED_preview_kill_jobs(C); @@ -2094,9 +2245,8 @@ static int node_duplicate_exec(bContext *C, wmOperator *op) break; } - ntreeSolveOrder(ntree); + ntreeUpdateTree(snode->edittree); - node_tree_verify_groups(snode->nodetree); snode_notify(C, snode); snode_dag_update(C, snode); @@ -2185,17 +2335,25 @@ static int node_link_modal(bContext *C, wmOperator *op, wmEvent *event) if( link->tosock!= tsock && (!tnode || (tnode!=node && link->tonode!=tnode)) ) { link->tonode= tnode; link->tosock= tsock; - if (link->prev==NULL && link->next==NULL) + if (link->prev==NULL && link->next==NULL) { BLI_addtail(&snode->edittree->links, link); - ntreeSolveOrder(snode->edittree); /* for interactive red line warning */ + } + + snode->edittree->update |= NTREE_UPDATE_LINKS; + ntreeUpdateTree(snode->edittree); } } } else { - BLI_remlink(&snode->edittree->links, link); - link->prev = link->next = NULL; - link->tonode= NULL; - link->tosock= NULL; + if (link->tonode || link->tosock) { + BLI_remlink(&snode->edittree->links, link); + link->prev = link->next = NULL; + link->tonode= NULL; + link->tosock= NULL; + + snode->edittree->update |= NTREE_UPDATE_LINKS; + ntreeUpdateTree(snode->edittree); + } } } else { @@ -2205,18 +2363,25 @@ static int node_link_modal(bContext *C, wmOperator *op, wmEvent *event) if( link->fromsock!= tsock && (!tnode || (tnode!=node && link->fromnode!=tnode)) ) { link->fromnode= tnode; link->fromsock= tsock; - if (link->prev==NULL && link->next==NULL) + if (link->prev==NULL && link->next==NULL) { BLI_addtail(&snode->edittree->links, link); - ntreeSolveOrder(snode->edittree); /* for interactive red line warning */ + } + + snode->edittree->update |= NTREE_UPDATE_LINKS; + ntreeUpdateTree(snode->edittree); } } } } else { - BLI_remlink(&snode->edittree->links, link); - link->prev = link->next = NULL; - link->fromnode= NULL; - link->fromsock= NULL; + if (link->tonode || link->tosock) { + BLI_remlink(&snode->edittree->links, link); + link->prev = link->next = NULL; + link->fromnode= NULL; + link->fromsock= NULL; + snode->edittree->update |= NTREE_UPDATE_LINKS; + ntreeUpdateTree(snode->edittree); + } } } /* hilight target sockets only */ @@ -2244,23 +2409,26 @@ static int node_link_modal(bContext *C, wmOperator *op, wmEvent *event) else if (outside_group_rect(snode) && (link->tonode || link->fromnode)) { /* automatically add new group socket */ if (link->tonode && link->tosock) { - link->fromsock = nodeGroupExposeSocket(snode->edittree, link->tosock, SOCK_IN); + link->fromsock = node_group_expose_socket(snode->edittree, link->tosock, SOCK_IN); link->fromnode = NULL; - if (link->prev==NULL && link->next==NULL) + if (link->prev==NULL && link->next==NULL) { BLI_addtail(&snode->edittree->links, link); + } + snode->edittree->update |= NTREE_UPDATE_GROUP_IN | NTREE_UPDATE_LINKS; } else if (link->fromnode && link->fromsock) { - link->tosock = nodeGroupExposeSocket(snode->edittree, link->fromsock, SOCK_OUT); + link->tosock = node_group_expose_socket(snode->edittree, link->fromsock, SOCK_OUT); link->tonode = NULL; - if (link->prev==NULL && link->next==NULL) + if (link->prev==NULL && link->next==NULL) { BLI_addtail(&snode->edittree->links, link); + } + snode->edittree->update |= NTREE_UPDATE_GROUP_OUT | NTREE_UPDATE_LINKS; } } else nodeRemLink(snode->edittree, link); - ntreeSolveOrder(snode->edittree); - node_tree_verify_groups(snode->nodetree); + ntreeUpdateTree(snode->edittree); snode_notify(C, snode); snode_dag_update(C, snode); @@ -2335,7 +2503,7 @@ static int node_link_invoke(bContext *C, wmOperator *op, wmEvent *event) ED_preview_kill_jobs(C); nldrag->in_out= node_link_init(snode, nldrag); - + if(nldrag->in_out) { op->customdata= nldrag; @@ -2408,7 +2576,7 @@ static int node_make_link_exec(bContext *C, wmOperator *op) snode_autoconnect(snode, 1, replace); - node_tree_verify_groups(snode->nodetree); + ntreeUpdateTree(snode->edittree); snode_notify(C, snode); snode_dag_update(C, snode); @@ -2482,8 +2650,7 @@ static int cut_links_exec(bContext *C, wmOperator *op) } } - ntreeSolveOrder(snode->edittree); - node_tree_verify_groups(snode->nodetree); + ntreeUpdateTree(snode->edittree); snode_notify(C, snode); snode_dag_update(C, snode); @@ -2608,7 +2775,7 @@ void ED_node_link_insert(ScrArea *sa) link->flag &= ~NODE_LINKFLAG_HILITE; nodeAddLink(snode->edittree, select, socket_best_match(&select->outputs, sockto->type), node, sockto); - ntreeSolveOrder(snode->edittree); /* needed for pointers */ + ntreeUpdateTree(snode->edittree); /* needed for pointers */ snode_tag_changed(snode, select); ED_node_changed_update(snode->id, select); } @@ -2819,14 +2986,14 @@ static int node_group_make_exec(bContext *C, wmOperator *op) ED_preview_kill_jobs(C); - gnode= nodeMakeGroupFromSelected(snode->nodetree); + gnode= node_group_make_from_selected(snode->nodetree); if(gnode==NULL) { BKE_report(op->reports, RPT_WARNING, "Can not make Group"); return OPERATOR_CANCELLED; } else { nodeSetActive(snode->nodetree, gnode); - ntreeSolveOrder(snode->nodetree); + ntreeUpdateTree(snode->nodetree); } snode_notify(C, snode); @@ -2972,7 +3139,7 @@ static int node_socket_toggle_exec(bContext *C, wmOperator *UNUSED(op)) } } - node_tree_verify_groups(snode->nodetree); + ntreeUpdateTree(snode->edittree); snode_notify(C, snode); @@ -3056,7 +3223,7 @@ static int node_delete_exec(bContext *C, wmOperator *UNUSED(op)) } } - node_tree_verify_groups(snode->nodetree); + ntreeUpdateTree(snode->edittree); snode_notify(C, snode); snode_dag_update(C, snode); @@ -3126,7 +3293,7 @@ static void node_delete_reconnect(bNodeTree* tree, bNode* node) deliveringvecsocket = link->fromsock; } break; - case SOCK_VALUE: + case SOCK_FLOAT: if (valsocket == NULL) { valsocket = link->tosock; deliveringvalnode = link->fromnode; @@ -3147,7 +3314,7 @@ static void node_delete_reconnect(bNodeTree* tree, bNode* node) numberOfConnectedOutputSockets ++; if (!first) first = link; switch(sock->type) { - case SOCK_VALUE: + case SOCK_FLOAT: if (deliveringvalsocket) { link->fromnode = deliveringvalnode; link->fromsock = deliveringvalsocket; @@ -3205,7 +3372,7 @@ static int node_delete_reconnect_exec(bContext *C, wmOperator *UNUSED(op)) } } - node_tree_verify_groups(snode->nodetree); + ntreeUpdateTree(snode->edittree); snode_notify(C, snode); snode_dag_update(C, snode); @@ -3235,7 +3402,7 @@ static int node_show_cycles_exec(bContext *C, wmOperator *UNUSED(op)) SpaceNode *snode= CTX_wm_space_node(C); /* this is just a wrapper around this call... */ - ntreeSolveOrder(snode->edittree); + ntreeUpdateTree(snode->nodetree); snode_notify(C, snode); return OPERATOR_FINISHED; @@ -3265,7 +3432,9 @@ static int node_add_file_exec(bContext *C, wmOperator *op) SpaceNode *snode= CTX_wm_space_node(C); bNode *node; Image *ima= NULL; - int ntype=0; + bNodeTemplate ntemp; + + ntemp.type = -1; /* check input variables */ if (RNA_property_is_set(op->ptr, "filepath")) @@ -3297,11 +3466,14 @@ static int node_add_file_exec(bContext *C, wmOperator *op) node_deselectall(snode); if (snode->nodetree->type==NTREE_COMPOSIT) - ntype = CMP_NODE_IMAGE; + ntemp.type = CMP_NODE_IMAGE; + if (ntemp.type < 0) + return OPERATOR_CANCELLED; + ED_preview_kill_jobs(C); - node = node_add_node(snode, bmain, scene, ntype, snode->mx, snode->my); + node = node_add_node(snode, bmain, scene, &ntemp, snode->mx, snode->my); if (!node) { BKE_report(op->reports, RPT_WARNING, "Could not add an image node."); @@ -3350,5 +3522,67 @@ void NODE_OT_add_file(wmOperatorType *ot) RNA_def_string(ot->srna, "name", "Image", 24, "Name", "Datablock name to assign."); } +/********************** New node tree operator *********************/ +static int new_node_tree_exec(bContext *C, wmOperator *op) +{ + SpaceNode *snode; + bNodeTree *ntree; + PointerRNA ptr, idptr; + PropertyRNA *prop; + int treetype; + char treename[MAX_ID_NAME-2] = "NodeTree"; + + /* retrieve state */ + snode= CTX_wm_space_node(C); + + if (RNA_property_is_set(op->ptr, "type")) + treetype = RNA_enum_get(op->ptr, "type"); + else + treetype = snode->treetype; + + if (RNA_property_is_set(op->ptr, "name")) + RNA_string_get(op->ptr, "name", treename); + + ntree = ntreeAddTree(treename, treetype, 0); + if(!ntree) + return OPERATOR_CANCELLED; + + /* hook into UI */ + uiIDContextProperty(C, &ptr, &prop); + if(prop) { + RNA_id_pointer_create(&ntree->id, &idptr); + RNA_property_pointer_set(&ptr, prop, idptr); + /* RNA_property_pointer_set increases the user count, + * fixed here as the editor is the initial user. + */ + --ntree->id.us; + RNA_property_update(C, &ptr, prop); + } + else if(snode) { + Scene *scene= CTX_data_scene(C); + snode->nodetree = ntree; + + ED_node_tree_update(snode, scene); + } + + return OPERATOR_FINISHED; +} + +void NODE_OT_new_node_tree(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "New node tree"; + ot->idname= "NODE_OT_new_node_tree"; + + /* api callbacks */ + ot->exec= new_node_tree_exec; + ot->poll= ED_operator_node_active; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + RNA_def_enum(ot->srna, "type", nodetree_type_items, NTREE_COMPOSIT, "Tree Type", ""); + RNA_def_string(ot->srna, "name", "NodeTree", MAX_ID_NAME-2, "Name", ""); +} diff --git a/source/blender/editors/space_node/node_header.c b/source/blender/editors/space_node/node_header.c index 634e49dc515..5c921d40344 100644 --- a/source/blender/editors/space_node/node_header.c +++ b/source/blender/editors/space_node/node_header.c @@ -45,24 +45,26 @@ #include "BLI_utildefines.h" #include "BKE_context.h" +#include "BKE_global.h" #include "BKE_screen.h" #include "BKE_node.h" #include "BKE_main.h" +#include "RNA_access.h" + #include "WM_api.h" #include "WM_types.h" - #include "UI_interface.h" -#include "UI_resources.h" #include "UI_interface_icons.h" +#include "UI_resources.h" #include "UI_view2d.h" #include "node_intern.h" /* ************************ add menu *********************** */ -static void do_node_add(bContext *C, void *UNUSED(arg), int event) +static void do_node_add(bContext *C, bNodeTemplate *ntemp) { Main *bmain= CTX_data_main(C); Scene *scene= CTX_data_scene(C); @@ -89,7 +91,7 @@ static void do_node_add(bContext *C, void *UNUSED(arg), int event) else node->flag &= ~NODE_TEST; } - node= node_add_node(snode, bmain, scene, event, snode->mx, snode->my); + node= node_add_node(snode, bmain, scene, ntemp, snode->mx, snode->my); /* select previous selection before autoconnect */ for(node= snode->edittree->nodes.first; node; node= node->next) { @@ -105,69 +107,111 @@ static void do_node_add(bContext *C, void *UNUSED(arg), int event) snode_dag_update(C, snode); } -static void node_auto_add_menu(bContext *C, uiLayout *layout, void *arg_nodeclass) +static void do_node_add_static(bContext *C, void *UNUSED(arg), int event) +{ + bNodeTemplate ntemp; + ntemp.type = event; + do_node_add(C, &ntemp); +} + +static void do_node_add_group(bContext *C, void *UNUSED(arg), int event) +{ + SpaceNode *snode= CTX_wm_space_node(C); + bNodeTemplate ntemp; + + if (event>=0) { + ntemp.ngroup= BLI_findlink(&G.main->nodetree, event); + ntemp.type = ntemp.ngroup->nodetype; + } + else { + ntemp.type = -event; + switch (ntemp.type) { + case NODE_GROUP: + ntemp.ngroup = ntreeAddTree("Group", snode->treetype, ntemp.type); + break; + case NODE_FORLOOP: + ntemp.ngroup = ntreeAddTree("For Loop", snode->treetype, ntemp.type); + break; + case NODE_WHILELOOP: + ntemp.ngroup = ntreeAddTree("While Loop", snode->treetype, ntemp.type); + break; + default: + ntemp.ngroup = NULL; + } + } + if (!ntemp.ngroup) + return; + + do_node_add(C, &ntemp); +} + +#if 0 /* disabled */ +static void do_node_add_dynamic(bContext *C, void *UNUSED(arg), int event) +{ + bNodeTemplate ntemp; + ntemp.type = NODE_DYNAMIC; + do_node_add(C, &ntemp); +} +#endif + +static int node_tree_has_type(int treetype, int nodetype) +{ + bNodeTreeType *ttype= ntreeGetType(treetype); + bNodeType *ntype; + for (ntype=ttype->node_types.first; ntype; ntype=ntype->next) { + if (ntype->type==nodetype) + return 1; + } + return 0; +} + +static void node_add_menu(bContext *C, uiLayout *layout, void *arg_nodeclass) { Main *bmain= CTX_data_main(C); SpaceNode *snode= CTX_wm_space_node(C); bNodeTree *ntree; int nodeclass= GET_INT_FROM_POINTER(arg_nodeclass); - int tot= 0, a; + int event; ntree = snode->nodetree; - + if(!ntree) { uiItemS(layout); return; } - - /* mostly taken from toolbox.c, node_add_sublevel() */ - if(nodeclass==NODE_CLASS_GROUP) { - bNodeTree *ngroup= bmain->nodetree.first; - for(; ngroup; ngroup= ngroup->id.next) - if(ngroup->type==ntree->type) - tot++; - } - else { - bNodeType *type = ntree->alltypes.first; - while(type) { - if(type->nclass == nodeclass) - tot++; - type= type->next; - } - } - if(tot==0) { + if (nodeclass==NODE_CLASS_GROUP) { + bNodeTree *ngroup; + + uiLayoutSetFunc(layout, do_node_add_group, NULL); + + /* XXX hack: negative numbers used for empty group types */ + if (node_tree_has_type(ntree->type, NODE_GROUP)) + uiItemV(layout, "New Group", 0, -NODE_GROUP); + if (node_tree_has_type(ntree->type, NODE_FORLOOP)) + uiItemV(layout, "New For Loop", 0, -NODE_FORLOOP); + if (node_tree_has_type(ntree->type, NODE_WHILELOOP)) + uiItemV(layout, "New While Loop", 0, -NODE_WHILELOOP); uiItemS(layout); - return; - } - - uiLayoutSetFunc(layout, do_node_add, NULL); - - if(nodeclass==NODE_CLASS_GROUP) { - bNodeTree *ngroup= bmain->nodetree.first; - - for(tot=0, a=0; ngroup; ngroup= ngroup->id.next, tot++) { - if(ngroup->type==ntree->type) { - uiItemV(layout, ngroup->id.name+2, ICON_NONE, NODE_GROUP_MENU+tot); - a++; + + for(ngroup=bmain->nodetree.first, event=0; ngroup; ngroup= ngroup->id.next, ++event) { + /* only use group trees */ + if (ngroup->type==ntree->type && ELEM3(ngroup->nodetype, NODE_GROUP, NODE_FORLOOP, NODE_WHILELOOP)) { + uiItemV(layout, ngroup->id.name+2, 0, event); } } } + else if (nodeclass==NODE_DYNAMIC) { + /* disabled */ + } else { - bNodeType *type; - int script=0; - - for(a=0, type= ntree->alltypes.first; type; type=type->next) { - if(type->nclass == nodeclass && type->name) { - if(type->type == NODE_DYNAMIC) { - uiItemV(layout, type->name, ICON_NONE, NODE_DYNAMIC_MENU+script); - script++; - } - else - uiItemV(layout, type->name, ICON_NONE, type->type); - - a++; - } + bNodeType *ntype; + + uiLayoutSetFunc(layout, do_node_add_static, NULL); + + for (ntype=ntreeGetType(ntree->type)->node_types.first; ntype; ntype=ntype->next) { + if(ntype->nclass==nodeclass && ntype->name) + uiItemV(layout, ntype->name, 0, ntype->type); } } } @@ -181,34 +225,34 @@ static void node_menu_add(const bContext *C, Menu *menu) uiLayoutSetActive(layout, 0); if(snode->treetype==NTREE_SHADER) { - uiItemMenuF(layout, "Input", 0, node_auto_add_menu, SET_INT_IN_POINTER(NODE_CLASS_INPUT)); - uiItemMenuF(layout, "Output", 0, node_auto_add_menu, SET_INT_IN_POINTER(NODE_CLASS_OUTPUT)); - uiItemMenuF(layout, "Color", 0, node_auto_add_menu, SET_INT_IN_POINTER(NODE_CLASS_OP_COLOR)); - uiItemMenuF(layout, "Vector", 0, node_auto_add_menu, SET_INT_IN_POINTER(NODE_CLASS_OP_VECTOR)); - uiItemMenuF(layout, "Convertor", 0, node_auto_add_menu, SET_INT_IN_POINTER(NODE_CLASS_CONVERTOR)); - uiItemMenuF(layout, "Group", 0, node_auto_add_menu, SET_INT_IN_POINTER(NODE_CLASS_GROUP)); - uiItemMenuF(layout, "Dynamic", 0, node_auto_add_menu, SET_INT_IN_POINTER(NODE_CLASS_OP_DYNAMIC)); + uiItemMenuF(layout, "Input", 0, node_add_menu, SET_INT_IN_POINTER(NODE_CLASS_INPUT)); + uiItemMenuF(layout, "Output", 0, node_add_menu, SET_INT_IN_POINTER(NODE_CLASS_OUTPUT)); + uiItemMenuF(layout, "Color", 0, node_add_menu, SET_INT_IN_POINTER(NODE_CLASS_OP_COLOR)); + uiItemMenuF(layout, "Vector", 0, node_add_menu, SET_INT_IN_POINTER(NODE_CLASS_OP_VECTOR)); + uiItemMenuF(layout, "Convertor", 0, node_add_menu, SET_INT_IN_POINTER(NODE_CLASS_CONVERTOR)); + uiItemMenuF(layout, "Group", 0, node_add_menu, SET_INT_IN_POINTER(NODE_CLASS_GROUP)); + uiItemMenuF(layout, "Dynamic", 0, node_add_menu, SET_INT_IN_POINTER(NODE_CLASS_OP_DYNAMIC)); } else if(snode->treetype==NTREE_COMPOSIT) { - uiItemMenuF(layout, "Input", 0, node_auto_add_menu, SET_INT_IN_POINTER(NODE_CLASS_INPUT)); - uiItemMenuF(layout, "Output", 0, node_auto_add_menu, SET_INT_IN_POINTER(NODE_CLASS_OUTPUT)); - uiItemMenuF(layout, "Color", 0, node_auto_add_menu, SET_INT_IN_POINTER(NODE_CLASS_OP_COLOR)); - uiItemMenuF(layout, "Vector", 0, node_auto_add_menu, SET_INT_IN_POINTER(NODE_CLASS_OP_VECTOR)); - uiItemMenuF(layout, "Filter", 0, node_auto_add_menu, SET_INT_IN_POINTER(NODE_CLASS_OP_FILTER)); - uiItemMenuF(layout, "Convertor", 0, node_auto_add_menu, SET_INT_IN_POINTER(NODE_CLASS_CONVERTOR)); - uiItemMenuF(layout, "Matte", 0, node_auto_add_menu, SET_INT_IN_POINTER(NODE_CLASS_MATTE)); - uiItemMenuF(layout, "Distort", 0, node_auto_add_menu, SET_INT_IN_POINTER(NODE_CLASS_DISTORT)); - uiItemMenuF(layout, "Group", 0, node_auto_add_menu, SET_INT_IN_POINTER(NODE_CLASS_GROUP)); + uiItemMenuF(layout, "Input", 0, node_add_menu, SET_INT_IN_POINTER(NODE_CLASS_INPUT)); + uiItemMenuF(layout, "Output", 0, node_add_menu, SET_INT_IN_POINTER(NODE_CLASS_OUTPUT)); + uiItemMenuF(layout, "Color", 0, node_add_menu, SET_INT_IN_POINTER(NODE_CLASS_OP_COLOR)); + uiItemMenuF(layout, "Vector", 0, node_add_menu, SET_INT_IN_POINTER(NODE_CLASS_OP_VECTOR)); + uiItemMenuF(layout, "Filter", 0, node_add_menu, SET_INT_IN_POINTER(NODE_CLASS_OP_FILTER)); + uiItemMenuF(layout, "Convertor", 0, node_add_menu, SET_INT_IN_POINTER(NODE_CLASS_CONVERTOR)); + uiItemMenuF(layout, "Matte", 0, node_add_menu, SET_INT_IN_POINTER(NODE_CLASS_MATTE)); + uiItemMenuF(layout, "Distort", 0, node_add_menu, SET_INT_IN_POINTER(NODE_CLASS_DISTORT)); + uiItemMenuF(layout, "Group", 0, node_add_menu, SET_INT_IN_POINTER(NODE_CLASS_GROUP)); } else if(snode->treetype==NTREE_TEXTURE) { - uiItemMenuF(layout, "Input", 0, node_auto_add_menu, SET_INT_IN_POINTER(NODE_CLASS_INPUT)); - uiItemMenuF(layout, "Output", 0, node_auto_add_menu, SET_INT_IN_POINTER(NODE_CLASS_OUTPUT)); - uiItemMenuF(layout, "Color", 0, node_auto_add_menu, SET_INT_IN_POINTER(NODE_CLASS_OP_COLOR)); - uiItemMenuF(layout, "Patterns", 0, node_auto_add_menu, SET_INT_IN_POINTER(NODE_CLASS_PATTERN)); - uiItemMenuF(layout, "Textures", 0, node_auto_add_menu, SET_INT_IN_POINTER(NODE_CLASS_TEXTURE)); - uiItemMenuF(layout, "Convertor", 0, node_auto_add_menu, SET_INT_IN_POINTER(NODE_CLASS_CONVERTOR)); - uiItemMenuF(layout, "Distort", 0, node_auto_add_menu, SET_INT_IN_POINTER(NODE_CLASS_DISTORT)); - uiItemMenuF(layout, "Group", 0, node_auto_add_menu, SET_INT_IN_POINTER(NODE_CLASS_GROUP)); + uiItemMenuF(layout, "Input", 0, node_add_menu, SET_INT_IN_POINTER(NODE_CLASS_INPUT)); + uiItemMenuF(layout, "Output", 0, node_add_menu, SET_INT_IN_POINTER(NODE_CLASS_OUTPUT)); + uiItemMenuF(layout, "Color", 0, node_add_menu, SET_INT_IN_POINTER(NODE_CLASS_OP_COLOR)); + uiItemMenuF(layout, "Patterns", 0, node_add_menu, SET_INT_IN_POINTER(NODE_CLASS_PATTERN)); + uiItemMenuF(layout, "Textures", 0, node_add_menu, SET_INT_IN_POINTER(NODE_CLASS_TEXTURE)); + uiItemMenuF(layout, "Convertor", 0, node_add_menu, SET_INT_IN_POINTER(NODE_CLASS_CONVERTOR)); + uiItemMenuF(layout, "Distort", 0, node_add_menu, SET_INT_IN_POINTER(NODE_CLASS_DISTORT)); + uiItemMenuF(layout, "Group", 0, node_add_menu, SET_INT_IN_POINTER(NODE_CLASS_GROUP)); } } diff --git a/source/blender/editors/space_node/node_intern.h b/source/blender/editors/space_node/node_intern.h index 4cfde22b8a0..3751d8efae8 100644 --- a/source/blender/editors/space_node/node_intern.h +++ b/source/blender/editors/space_node/node_intern.h @@ -33,6 +33,8 @@ #ifndef ED_NODE_INTERN_H #define ED_NODE_INTERN_H +#include "UI_interface.h" + /* internal exports only */ struct ARegion; @@ -40,6 +42,7 @@ struct ARegionType; struct View2D; struct bContext; struct wmWindowManager; +struct bNodeTemplate; struct bNode; struct bNodeSocket; struct bNodeLink; @@ -64,6 +67,11 @@ void node_header_buttons(const bContext *C, ARegion *ar); void node_menus_register(void); /* node_draw.c */ +void node_socket_circle_draw(struct bNodeTree *ntree, struct bNodeSocket *sock, float size); +void node_draw_default(const struct bContext *C, struct ARegion *ar, struct SpaceNode *snode, struct bNodeTree *ntree, struct bNode *node); +void node_update_default(const struct bContext *C, struct bNodeTree *ntree, struct bNode *node); +void node_update_nodetree(const struct bContext *C, struct bNodeTree *ntree, float offsetx, float offsety); +void node_draw_nodetree(const struct bContext *C, struct ARegion *ar, struct SpaceNode *snode, struct bNodeTree *ntree); void drawnodespace(const bContext *C, ARegion *ar, View2D *v2d); /* node_buttons.c */ @@ -90,6 +98,7 @@ void NODE_OT_select_same_type_prev(wmOperatorType *ot); void node_draw_link(View2D *v2d, SpaceNode *snode, bNodeLink *link); void node_draw_link_bezier(View2D *v2d, SpaceNode *snode, bNodeLink *link, int th_col1, int do_shaded, int th_col2, int do_triple, int th_col3 ); int node_link_bezier_points(View2D *v2d, SpaceNode *snode, bNodeLink *link, float coord_array[][2], int resol); +void node_draw_link_straight(View2D *v2d, SpaceNode *snode, bNodeLink *link, int th_col1, int do_shaded, int th_col2, int do_triple, int th_col3 ); void draw_nodespace_back_pix(ARegion *ar, SpaceNode *snode, int color_manage); void draw_nodespace_color_info(struct ARegion *ar, int color_manage, int channels, int x, int y, char *cp, float *fp); @@ -97,10 +106,10 @@ void draw_nodespace_color_info(struct ARegion *ar, int color_manage, int channel void node_tree_from_ID(ID *id, bNodeTree **ntree, bNodeTree **edittree, int *treetype); void snode_notify(bContext *C, SpaceNode *snode); void snode_dag_update(bContext *C, SpaceNode *snode); -bNode *next_node(bNodeTree *ntree); -bNode *node_add_node(SpaceNode *snode, struct Main *bmain, Scene *scene, int type, float locx, float locy); +bNode *node_add_node(struct SpaceNode *snode, struct Main *bmain, struct Scene *scene, struct bNodeTemplate *ntemp, float locx, float locy); void snode_set_context(SpaceNode *snode, Scene *scene); void snode_make_group_editable(SpaceNode *snode, bNode *gnode); +void node_sort(struct bNodeTree *ntree); void node_deselectall(SpaceNode *snode); int node_select_same_type(SpaceNode *snode); int node_select_same_type_np(SpaceNode *snode, int dir); @@ -146,6 +155,8 @@ void NODE_OT_backimage_sample(wmOperatorType *ot); void NODE_OT_add_file(struct wmOperatorType *ot); +void NODE_OT_new_node_tree(struct wmOperatorType *ot); + extern const char *node_context_dir[]; // XXXXXX diff --git a/source/blender/editors/space_node/node_ops.c b/source/blender/editors/space_node/node_ops.c index 4bb0283690b..153d703ddf6 100644 --- a/source/blender/editors/space_node/node_ops.c +++ b/source/blender/editors/space_node/node_ops.c @@ -96,6 +96,8 @@ void node_operatortypes(void) WM_operatortype_append(NODE_OT_backimage_sample); WM_operatortype_append(NODE_OT_add_file); + + WM_operatortype_append(NODE_OT_new_node_tree); } void ED_operatormacros_node(void) @@ -193,6 +195,5 @@ void node_keymap(struct wmKeyConfig *keyconf) WM_keymap_add_item(keymap, "NODE_OT_read_fullsamplelayers", RKEY, KM_PRESS, KM_SHIFT, 0); WM_keymap_add_item(keymap, "NODE_OT_render_changed", ZKEY, KM_PRESS, 0, 0); - transform_keymap_for_space(keyconf, keymap, SPACE_NODE); } diff --git a/source/blender/editors/space_node/node_select.c b/source/blender/editors/space_node/node_select.c index ca673277739..3d8b1676ea5 100644 --- a/source/blender/editors/space_node/node_select.c +++ b/source/blender/editors/space_node/node_select.c @@ -62,7 +62,7 @@ static bNode *node_under_mouse(bNodeTree *ntree, int mx, int my) { bNode *node; - for(next_node(ntree); (node=next_node(NULL));) { + for(node=ntree->nodes.last; node; node=node->prev) { /* node body (header and scale are in other operators) */ if (BLI_in_rctf(&node->totr, mx, my)) return node; @@ -93,8 +93,10 @@ static bNode *node_mouse_select(Main *bmain, SpaceNode *snode, ARegion *ar, cons } else node->flag ^= SELECT; - + ED_node_set_active(bmain, snode->edittree, node); + + node_sort(snode->edittree); } return node; @@ -182,6 +184,8 @@ static int node_borderselect_exec(bContext *C, wmOperator *op) } } + node_sort(snode->edittree); + WM_event_add_notifier(C, NC_NODE|NA_SELECTED, NULL); return OPERATOR_FINISHED; @@ -252,6 +256,8 @@ static int node_select_all_exec(bContext *C, wmOperator *UNUSED(op)) node->flag |= NODE_SELECT; } + node_sort(snode->edittree); + WM_event_add_notifier(C, NC_NODE|NA_SELECTED, NULL); return OPERATOR_FINISHED; } @@ -292,6 +298,8 @@ static int node_select_linked_to_exec(bContext *C, wmOperator *UNUSED(op)) node->flag |= NODE_SELECT; } + node_sort(snode->edittree); + WM_event_add_notifier(C, NC_NODE|NA_SELECTED, NULL); return OPERATOR_FINISHED; } @@ -332,6 +340,8 @@ static int node_select_linked_from_exec(bContext *C, wmOperator *UNUSED(op)) node->flag |= NODE_SELECT; } + node_sort(snode->edittree); + WM_event_add_notifier(C, NC_NODE|NA_SELECTED, NULL); return OPERATOR_FINISHED; } @@ -358,6 +368,9 @@ static int node_select_same_type_exec(bContext *C, wmOperator *UNUSED(op)) SpaceNode *snode = CTX_wm_space_node(C); node_select_same_type(snode); + + node_sort(snode->edittree); + WM_event_add_notifier(C, NC_NODE|NA_SELECTED, NULL); return OPERATOR_FINISHED; } @@ -384,7 +397,11 @@ static int node_select_same_type_next_exec(bContext *C, wmOperator *UNUSED(op)) SpaceNode *snode = CTX_wm_space_node(C); node_select_same_type_np(snode, 0); + + node_sort(snode->edittree); + WM_event_add_notifier(C, NC_NODE|NA_SELECTED, NULL); + return OPERATOR_FINISHED; } @@ -408,6 +425,9 @@ static int node_select_same_type_prev_exec(bContext *C, wmOperator *UNUSED(op)) SpaceNode *snode = CTX_wm_space_node(C); node_select_same_type_np(snode, 1); + + node_sort(snode->edittree); + WM_event_add_notifier(C, NC_NODE|NA_SELECTED, NULL); return OPERATOR_FINISHED; } diff --git a/source/blender/editors/space_node/node_state.c b/source/blender/editors/space_node/node_state.c index 601ffbd313d..c4567bea648 100644 --- a/source/blender/editors/space_node/node_state.c +++ b/source/blender/editors/space_node/node_state.c @@ -69,30 +69,14 @@ void node_set_hidden_sockets(SpaceNode *snode, bNode *node, int set) sock->flag &= ~SOCK_HIDDEN; } else { - bNode *gnode= node_tree_get_editgroup(snode->nodetree); - - /* hiding inside group should not break links in other group users */ - if(gnode) { - nodeGroupSocketUseFlags((bNodeTree *)gnode->id); - for(sock= node->inputs.first; sock; sock= sock->next) - if(!(sock->flag & SOCK_IN_USE)) - if(sock->link==NULL) - sock->flag |= SOCK_HIDDEN; - for(sock= node->outputs.first; sock; sock= sock->next) - if(!(sock->flag & SOCK_IN_USE)) - if(nodeCountSocketLinks(snode->edittree, sock)==0) - sock->flag |= SOCK_HIDDEN; + /* hide unused sockets */ + for(sock= node->inputs.first; sock; sock= sock->next) { + if(sock->link==NULL) + sock->flag |= SOCK_HIDDEN; } - else { - /* hide unused sockets */ - for(sock= node->inputs.first; sock; sock= sock->next) { - if(sock->link==NULL) - sock->flag |= SOCK_HIDDEN; - } - for(sock= node->outputs.first; sock; sock= sock->next) { - if(nodeCountSocketLinks(snode->edittree, sock)==0) - sock->flag |= SOCK_HIDDEN; - } + for(sock= node->outputs.first; sock; sock= sock->next) { + if(nodeCountSocketLinks(snode->edittree, sock)==0) + sock->flag |= SOCK_HIDDEN; } } } @@ -100,7 +84,7 @@ void node_set_hidden_sockets(SpaceNode *snode, bNode *node, int set) static void node_hide_unhide_sockets(SpaceNode *snode, bNode *node) { node_set_hidden_sockets(snode, node, !node_has_hidden_sockets(node)); - node_tree_verify_groups(snode->nodetree); + ntreeUpdateTree(snode->edittree); } static int do_header_node(SpaceNode *snode, bNode *node, float mx, float my) @@ -168,7 +152,7 @@ static int node_toggle_visibility(SpaceNode *snode, ARegion *ar, const int mval[ UI_view2d_region_to_view(&ar->v2d, mval[0], mval[1], &mx, &my); - for(next_node(snode->edittree); (node=next_node(NULL));) { + for(node=snode->edittree->nodes.last; node; node=node->prev) { if(node->flag & NODE_HIDDEN) { if(do_header_hidden_node(node, mx, my)) { ED_region_tag_redraw(ar); diff --git a/source/blender/editors/space_node/space_node.c b/source/blender/editors/space_node/space_node.c index 3c5f4a163a2..0990afa4fe6 100644 --- a/source/blender/editors/space_node/space_node.c +++ b/source/blender/editors/space_node/space_node.c @@ -439,14 +439,30 @@ static int node_context(const bContext *C, const char *member, bContextDataResul else if(CTX_data_equals(member, "selected_nodes")) { bNode *node; - for(next_node(snode->edittree); (node=next_node(NULL));) { - if(node->flag & NODE_SELECT) { - CTX_data_list_add(result, &snode->edittree->id, &RNA_Node, node); + if(snode->edittree) { + for(node=snode->edittree->nodes.last; node; node=node->prev) { + if(node->flag & NODE_SELECT) { + CTX_data_list_add(result, &snode->edittree->id, &RNA_Node, node); + } } } CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); return 1; } + else if(CTX_data_equals(member, "active_node")) { + bNode *node; + + if(snode->edittree) { + for(node=snode->edittree->nodes.last; node; node=node->prev) { + if(node->flag & NODE_ACTIVE) { + CTX_data_pointer_set(result, &snode->edittree->id, &RNA_Node, node); + break; + } + } + } + CTX_data_type_set(result, CTX_DATA_TYPE_POINTER); + return 1; + } return 0; } diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index 7b43d0955a7..cae64899aeb 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -4771,12 +4771,14 @@ void special_aftertrans_update(bContext *C, TransInfo *t) } else if (t->spacetype == SPACE_NODE) { + SpaceNode *snode= (SpaceNode *)t->sa->spacedata.first; + ED_node_update_hierarchy(C, snode->edittree); + if(cancelled == 0) ED_node_link_insert(t->sa); /* clear link line */ ED_node_link_intersect_test(t->sa, 0); - } else if (t->spacetype == SPACE_ACTION) { SpaceAction *saction= (SpaceAction *)t->sa->spacedata.first; @@ -5194,6 +5196,11 @@ static void NodeToTransData(TransData *td, TransData2D *td2d, bNode *node) td2d->loc2d = &node->locx; /* current location */ td->flag = 0; + /* exclude nodes whose parent is also transformed */ + if (node->parent && (node->parent->flag & NODE_TRANSFORM)) { + td->flag |= TD_SKIP; + } + td->loc = td2d->loc; VECCOPY(td->center, td->loc); VECCOPY(td->iloc, td->loc); @@ -5214,6 +5221,16 @@ static void createTransNodeData(bContext *C, TransInfo *t) { TransData *td; TransData2D *td2d; + SpaceNode *snode= t->sa->spacedata.first; + bNode *node; + + /* set transform flags on nodes */ + for (node=snode->edittree->nodes.first; node; node=node->next) { + if ((node->flag & NODE_SELECT) || (node->parent && (node->parent->flag & NODE_TRANSFORM))) + node->flag |= NODE_TRANSFORM; + else + node->flag &= ~NODE_TRANSFORM; + } t->total= CTX_DATA_COUNT(C, selected_nodes); diff --git a/source/blender/gpu/SConscript b/source/blender/gpu/SConscript index b48e1d5a8e2..adb52d577a1 100644 --- a/source/blender/gpu/SConscript +++ b/source/blender/gpu/SConscript @@ -5,7 +5,7 @@ sources = env.Glob('intern/*.c') defs = [ 'GLEW_STATIC' ] -incs = '../blenlib ../blenkernel ../makesdna ../include ../blenloader' +incs = '../blenlib ../blenkernel ../makesdna ../makesrna ../include ../blenloader' incs += ' #/extern/glew/include #intern/guardedalloc #intern/smoke/extern ../imbuf .' if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc'): diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h index efaf30b02f6..3a51a6a56a4 100644 --- a/source/blender/makesdna/DNA_node_types.h +++ b/source/blender/makesdna/DNA_node_types.h @@ -38,26 +38,29 @@ #include "DNA_vec_types.h" #include "DNA_listBase.h" +struct ID; struct ListBase; struct SpaceNode; struct bNodeLink; struct bNodeType; -struct bNodeGroup; +struct bNodeTreeExec; struct AnimData; struct bGPdata; struct uiBlock; #define NODE_MAXSTR 32 - typedef struct bNodeStack { float vec[4]; - float min, max; /* min/max for values (UI writes it, execute might use it) */ + float min, max; void *data; short hasinput; /* when input has link, tagged before executing */ short hasoutput; /* when output is linked, tagged before executing */ short datatype; /* type of data pointer */ short sockettype; /* type of socket stack comes from, to remap linking different sockets */ + short is_copy; /* data is a copy of external data (no freeing) */ + short external; /* data is used by external nodes (no freeing) */ + short pad[2]; } bNodeStack; /* ns->datatype, shadetree only */ @@ -68,50 +71,58 @@ typedef struct bNodeSocket { struct bNodeSocket *next, *prev, *new_sock; char name[32]; - bNodeStack ns; /* custom data for inputs, only UI writes in this */ + + void *storage; /* custom storage */ short type, flag; short limit; /* max. number of links */ - - /* stack data info (only during execution!) */ - short stack_type; /* type of stack reference */ - /* XXX only one of stack_ptr or stack_index is used (depending on stack_type). - * could store the index in the pointer with SET_INT_IN_POINTER (a bit ugly). - * (union won't work here, not supported by DNA) - */ - struct bNodeStack *stack_ptr; /* constant input value */ - short stack_index; /* local stack index or external input number */ short pad1; float locx, locy; + void *default_value; /* default input value used for unlinked sockets */ + + /* execution data */ + short stack_index; /* local stack index */ + short pad2; + int pad3; + void *cache; /* cached data from execution */ + /* internal data to retrieve relations and groups */ - int own_index; /* group socket identifiers, to find matching pairs after reading files */ - struct bNodeSocket *groupsock; int to_index; /* XXX deprecated, only used for restoring old group node links */ - int pad2; + struct bNodeSocket *groupsock; - struct bNodeLink *link; /* a link pointer, set in nodeSolveOrder() */ + struct bNodeLink *link; /* a link pointer, set in ntreeUpdateTree */ + + /* DEPRECATED only needed for do_versions */ + bNodeStack ns; /* custom data for inputs, only UI writes in this */ } bNodeSocket; /* sock->type */ -#define SOCK_VALUE 0 -#define SOCK_VECTOR 1 -#define SOCK_RGBA 2 +#define SOCK_FLOAT 0 +#define SOCK_VECTOR 1 +#define SOCK_RGBA 2 +#define SOCK_INT 3 +#define SOCK_BOOLEAN 4 +#define SOCK_MESH 5 +#define NUM_SOCKET_TYPES 6 /* must be last! */ + +/* socket side (input/output) */ +#define SOCK_IN 1 +#define SOCK_OUT 2 /* sock->flag, first bit is select */ - /* hidden is user defined, to hide unused */ + /* hidden is user defined, to hide unused */ #define SOCK_HIDDEN 2 - /* only used now for groups... */ -#define SOCK_IN_USE 4 - /* unavailable is for dynamic sockets */ + /* only used now for groups... */ +#define SOCK_IN_USE 4 /* XXX deprecated */ + /* unavailable is for dynamic sockets */ #define SOCK_UNAVAIL 8 - -/* sock->stack_type */ -#define SOCK_STACK_LOCAL 1 /* part of the local tree stack */ -#define SOCK_STACK_EXTERN 2 /* use input stack pointer */ -#define SOCK_STACK_CONST 3 /* use pointer to constant input value */ + /* dynamic socket (can be modified by user) */ +#define SOCK_DYNAMIC 16 + /* group socket should not be exposed */ +#define SOCK_INTERNAL 32 typedef struct bNodePreview { unsigned char *rect; @@ -119,7 +130,6 @@ typedef struct bNodePreview { int pad; } bNodePreview; - /* limit data in bNode to what we want to see saved? */ typedef struct bNode { struct bNode *next, *prev, *new_node; @@ -132,11 +142,14 @@ typedef struct bNode { short nr; /* number of this node in list, used for UI exec events */ ListBase inputs, outputs; + struct bNode *parent; /* parent node */ struct ID *id; /* optional link to libdata */ void *storage; /* custom data, must be struct, for storage in file */ float locx, locy; /* root offset for drawing */ - float width, miniwidth; + float width, height; /* node custom width and height */ + float miniwidth; /* node width if hidden */ + int pad; char label[32]; /* custom user-defined label */ short custom1, custom2; /* to be abused for buttons */ float custom3, custom4; @@ -151,7 +164,6 @@ typedef struct bNode { struct uiBlock *block; /* runtime during drawing */ struct bNodeType *typeinfo; /* lookup of callbacks and defaults */ - } bNode; /* node->flag */ @@ -163,11 +175,17 @@ typedef struct bNode { #define NODE_ACTIVE_ID 32 #define NODE_DO_OUTPUT 64 #define NODE_GROUP_EDIT 128 - /* free test flag, undefined */ + /* free test flag, undefined */ #define NODE_TEST 256 - /* composite: don't do node but pass on buffer(s) */ + /* composite: don't do node but pass on buffer(s) */ #define NODE_MUTED 512 -#define NODE_CUSTOM_NAME 1024 /* deprecated! */ +#define NODE_CUSTOM_NAME 1024 /* deprecated! */ + /* group node types: use const outputs by default */ +#define NODE_CONST_OUTPUT (1<<11) + /* node is always behind others */ +#define NODE_BACKGROUND (1<<12) + /* automatic flag for nodes included in transforms */ +#define NODE_TRANSFORM (1<<13) typedef struct bNodeLink { struct bNodeLink *next, *prev; @@ -175,13 +193,13 @@ typedef struct bNodeLink { bNode *fromnode, *tonode; bNodeSocket *fromsock, *tosock; - int flag, pad; - + int flag; + int pad; } bNodeLink; - /* link->flag */ -#define NODE_LINKFLAG_HILITE 1 +#define NODE_LINK_VALID 1 /* link has been successfully validated */ +#define NODE_LINKFLAG_HILITE 2 /* the basis for a Node tree, all links and nodes reside internal here */ /* only re-usable node trees are in the library though, materials and textures allocate own tree struct */ @@ -193,19 +211,24 @@ typedef struct bNodeTree { ListBase nodes, links; - bNodeStack *stack; /* stack is only while executing, no read/write in file */ - struct ListBase *threadstack; /* same as above */ - int type, init; /* set init on fileread */ - int stacksize; /* amount of elements in stack */ int cur_index; /* sockets in groups have unique identifiers, adding new sockets always will increase this counter */ - int flag, pad; + int flag; + int update; /* update flags */ + + int nodetype; /* specific node type this tree is used for */ - ListBase alltypes; /* type definitions */ ListBase inputs, outputs; /* external sockets for group nodes */ - - int pad2[2]; + + /* execution data */ + /* XXX It would be preferable to completely move this data out of the underlying node tree, + * so node tree execution could finally run independent of the tree itself. This would allow node trees + * to be merely linked by other data (materials, textures, etc.), as ID data is supposed to. + * Execution data is generated from the tree once at execution start and can then be used + * as long as necessary, even while the tree is being modified. + */ + struct bNodeTreeExec *execdata; /* callbacks */ void (*progress)(void *, float progress); @@ -216,20 +239,59 @@ typedef struct bNodeTree { } bNodeTree; /* ntree->type, index */ -#define NTREE_SHADER 0 -#define NTREE_COMPOSIT 1 -#define NTREE_TEXTURE 2 +#define NTREE_SHADER 0 +#define NTREE_COMPOSIT 1 +#define NTREE_TEXTURE 2 +#define NUM_NTREE_TYPES 3 /* ntree->init, flag */ -#define NTREE_TYPE_INIT 1 -#define NTREE_EXEC_INIT 2 +#define NTREE_TYPE_INIT 1 /* ntree->flag */ #define NTREE_DS_EXPAND 1 /* for animation editors */ -/* XXX not nice, but needed as a temporary flag +/* XXX not nice, but needed as a temporary flags * for group updates after library linking. */ -#define NTREE_DO_VERSIONS 1024 +#define NTREE_DO_VERSIONS_GROUP_EXPOSE 1024 + +/* ntree->update */ +#define NTREE_UPDATE 0xFFFF /* generic update flag (includes all others) */ +#define NTREE_UPDATE_LINKS 1 /* links have been added or removed */ +#define NTREE_UPDATE_NODES 2 /* nodes or sockets have been added or removed */ +#define NTREE_UPDATE_GROUP_IN 16 /* group inputs have changed */ +#define NTREE_UPDATE_GROUP_OUT 32 /* group outputs have changed */ +#define NTREE_UPDATE_GROUP 48 /* group has changed (generic flag including all other group flags) */ + + +/* socket value structs for input buttons */ + +typedef struct bNodeSocketValueInt { + int subtype; /* RNA subtype */ + int value; + int min, max; +} bNodeSocketValueInt; + +typedef struct bNodeSocketValueFloat { + int subtype; /* RNA subtype */ + float value; + float min, max; +} bNodeSocketValueFloat; + +typedef struct bNodeSocketValueBoolean { + char value; + char pad[3]; +} bNodeSocketValueBoolean; + +typedef struct bNodeSocketValueVector { + int subtype; /* RNA subtype */ + float value[3]; + float min, max; +} bNodeSocketValueVector; + +typedef struct bNodeSocketValueRGBA { + float value[4]; +} bNodeSocketValueRGBA; + /* data structs, for node->storage */ @@ -354,7 +416,6 @@ typedef struct TexNodeOutput { char name[32]; } TexNodeOutput; - /* comp channel matte */ #define CMP_NODE_CHANNEL_MATTE_CS_RGB 1 #define CMP_NODE_CHANNEL_MATTE_CS_HSV 2 diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h index 259c7de5cd4..477ee2fe43e 100644 --- a/source/blender/makesrna/RNA_access.h +++ b/source/blender/makesrna/RNA_access.h @@ -327,10 +327,13 @@ extern StructRNA RNA_NearSensor; extern StructRNA RNA_NlaStrip; extern StructRNA RNA_NlaTrack; extern StructRNA RNA_Node; +extern StructRNA RNA_NodeForLoop; extern StructRNA RNA_NodeGroup; extern StructRNA RNA_NodeLink; extern StructRNA RNA_NodeSocket; +extern StructRNA RNA_NodeSocketPanel; extern StructRNA RNA_NodeTree; +extern StructRNA RNA_NodeWhileLoop; extern StructRNA RNA_NoiseTexture; extern StructRNA RNA_NorController; extern StructRNA RNA_Object; @@ -376,7 +379,6 @@ extern StructRNA RNA_PropertyGroupItem; extern StructRNA RNA_PropertySensor; extern StructRNA RNA_PythonConstraint; extern StructRNA RNA_PythonController; -extern StructRNA RNA_RGBANodeSocket; extern StructRNA RNA_RadarSensor; extern StructRNA RNA_RandomSensor; extern StructRNA RNA_RaySensor; @@ -553,9 +555,7 @@ extern StructRNA RNA_UserPreferencesFilePaths; extern StructRNA RNA_UserPreferencesSystem; extern StructRNA RNA_UserPreferencesView; extern StructRNA RNA_UserSolidLight; -extern StructRNA RNA_ValueNodeSocket; extern StructRNA RNA_VectorFont; -extern StructRNA RNA_VectorNodeSocket; extern StructRNA RNA_VertexGroup; extern StructRNA RNA_VertexGroupElement; extern StructRNA RNA_VertexPaint; @@ -599,6 +599,8 @@ extern const PointerRNA PointerRNA_NULL; /* Structs */ +StructRNA *RNA_struct_find(const char *identifier); + const char *RNA_struct_identifier(StructRNA *type); const char *RNA_struct_ui_name(StructRNA *type); const char *RNA_struct_ui_description(StructRNA *type); diff --git a/source/blender/makesrna/RNA_enum_types.h b/source/blender/makesrna/RNA_enum_types.h index 0b63bb02436..2300b72910d 100644 --- a/source/blender/makesrna/RNA_enum_types.h +++ b/source/blender/makesrna/RNA_enum_types.h @@ -102,10 +102,12 @@ extern EnumPropertyItem transform_mode_types[]; extern EnumPropertyItem posebone_rotmode_items[]; extern EnumPropertyItem property_type_items[]; +extern EnumPropertyItem property_subtype_items[]; extern EnumPropertyItem property_unit_items[]; extern EnumPropertyItem viewport_shade_items[]; +extern EnumPropertyItem nodetree_type_items[]; extern EnumPropertyItem node_socket_type_items[]; extern EnumPropertyItem node_math_items[]; diff --git a/source/blender/makesrna/RNA_types.h b/source/blender/makesrna/RNA_types.h index f8199074f27..4a18518dde9 100644 --- a/source/blender/makesrna/RNA_types.h +++ b/source/blender/makesrna/RNA_types.h @@ -99,7 +99,10 @@ typedef enum PropertyUnit { #define RNA_ENUM_BITFLAG_SIZE 32 -/* also update enums in bpy_props.c when adding items here */ +/* also update enums in bpy_props.c when adding items here + * watch it: these values are written to files as part of + * node socket button subtypes! + */ typedef enum PropertySubType { PROP_NONE = 0, diff --git a/source/blender/makesrna/SConscript b/source/blender/makesrna/SConscript index 1cb24630fbe..10b20fc795a 100644 --- a/source/blender/makesrna/SConscript +++ b/source/blender/makesrna/SConscript @@ -9,6 +9,7 @@ objs += o incs = '#/intern/guardedalloc #/intern/memutil #/intern/audaspace/intern ../blenkernel ../blenlib ../makesdna intern .' incs += ' ../windowmanager ../editors/include ../gpu ../imbuf ../ikplugin ../blenfont ../blenloader' incs += ' ../render/extern/include' +incs += ' ../nodes' incs += ' #/extern/glew/include' defs = [] diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c index ad79771416d..936f2e5e40c 100644 --- a/source/blender/makesrna/intern/rna_access.c +++ b/source/blender/makesrna/intern/rna_access.c @@ -475,6 +475,17 @@ static const char *rna_ensure_property_name(PropertyRNA *prop) /* Structs */ +StructRNA *RNA_struct_find(const char *identifier) +{ + StructRNA *type; + if (identifier) { + for (type = BLENDER_RNA.structs.first; type; type = type->cont.next) + if (strcmp(type->identifier, identifier)==0) + return type; + } + return NULL; +} + const char *RNA_struct_identifier(StructRNA *type) { return type->identifier; diff --git a/source/blender/makesrna/intern/rna_main_api.c b/source/blender/makesrna/intern/rna_main_api.c index d69cb2063ab..1ba6905ea37 100644 --- a/source/blender/makesrna/intern/rna_main_api.c +++ b/source/blender/makesrna/intern/rna_main_api.c @@ -214,9 +214,7 @@ void rna_Main_materials_remove(Main *bmain, ReportList *reports, struct Material struct bNodeTree *rna_Main_nodetree_new(Main *UNUSED(bmain), const char *name, int type) { - bNodeTree *tree = ntreeAddTree(name, type, TRUE); - -// ntreeMakeGroupSockets(tree); + bNodeTree *tree = ntreeAddTree(name, type, NODE_GROUP); id_us_min(&tree->id); return tree; diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index d6e475fdbad..49a0458977a 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -30,13 +30,17 @@ #include #include +#include "RNA_access.h" #include "RNA_define.h" #include "RNA_enum_types.h" #include "rna_internal.h" +#include "rna_internal_types.h" #include "DNA_material_types.h" +#include "DNA_mesh_types.h" #include "DNA_node_types.h" +#include "DNA_object_types.h" #include "DNA_scene_types.h" #include "DNA_texture_types.h" @@ -53,9 +57,16 @@ #include "MEM_guardedalloc.h" +EnumPropertyItem nodetree_type_items[] = { + {NTREE_SHADER, "MATERIAL", ICON_MATERIAL, "Material", "Material nodes" }, + {NTREE_TEXTURE, "TEXTURE", ICON_TEXTURE, "Texture", "Texture nodes" }, + {NTREE_COMPOSIT, "COMPOSITING", ICON_RENDERLAYERS, "Compositing", "Compositing nodes" }, + {0, NULL, 0, NULL, NULL} +}; + EnumPropertyItem node_socket_type_items[] = { - {SOCK_VALUE, "VALUE", 0, "Value", ""}, + {SOCK_FLOAT, "VALUE", 0, "Value", ""}, {SOCK_VECTOR, "VECTOR", 0, "Vector", ""}, {SOCK_RGBA, "RGBA", 0, "RGBA", ""}, {0, NULL, 0, NULL, NULL}}; @@ -99,6 +110,41 @@ EnumPropertyItem node_filter_items[] = { {6, "SHADOW", 0, "Shadow", ""}, {0, NULL, 0, NULL, NULL}}; + +/* Add any new socket value subtype here. + * When adding a new subtype here, make sure you also add it + * to the subtype definitions in DNA_node_types.h. + * This macro is used by the RNA and the internal converter functions + * to define all socket subtypes. The SUBTYPE macro must be defined + * before using this macro, and undefined afterwards. + */ +#define NODE_DEFINE_SUBTYPES_INT \ +SUBTYPE(INT, Int, NONE, None) \ +SUBTYPE(INT, Int, UNSIGNED, Unsigned) + +#define NODE_DEFINE_SUBTYPES_FLOAT \ +SUBTYPE(FLOAT, Float, NONE, None) \ +SUBTYPE(FLOAT, Float, UNSIGNED, Unsigned) \ +SUBTYPE(FLOAT, Float, PERCENTAGE, Percentage) \ +SUBTYPE(FLOAT, Float, FACTOR, Factor) \ +SUBTYPE(FLOAT, Float, ANGLE, Angle) \ +SUBTYPE(FLOAT, Float, TIME, Time) \ +SUBTYPE(FLOAT, Float, DISTANCE, Distance) + +#define NODE_DEFINE_SUBTYPES_VECTOR \ +SUBTYPE(VECTOR, Vector, NONE, None) \ +SUBTYPE(VECTOR, Vector, TRANSLATION, Translation) \ +SUBTYPE(VECTOR, Vector, DIRECTION, Direction) \ +SUBTYPE(VECTOR, Vector, VELOCITY, Velocity) \ +SUBTYPE(VECTOR, Vector, ACCELERATION, Acceleration) \ +SUBTYPE(VECTOR, Vector, EULER, Euler) \ +SUBTYPE(VECTOR, Vector, XYZ, XYZ) + +#define NODE_DEFINE_SUBTYPES \ +NODE_DEFINE_SUBTYPES_INT \ +NODE_DEFINE_SUBTYPES_FLOAT \ +NODE_DEFINE_SUBTYPES_VECTOR + #ifdef RNA_RUNTIME #include "BLI_linklist.h" @@ -121,32 +167,18 @@ static StructRNA *rna_Node_refine(struct PointerRNA *ptr) #include "rna_nodetree_types.h" - #undef DefNode - case NODE_GROUP: return &RNA_NodeGroup; + case NODE_FORLOOP: + return &RNA_NodeForLoop; + case NODE_WHILELOOP: + return &RNA_NodeWhileLoop; default: return &RNA_Node; } } -static StructRNA *rna_NodeSocketType_refine(struct PointerRNA *ptr) -{ - bNodeSocket *ns= (bNodeSocket*)ptr->data; - - switch(ns->type) { - case SOCK_VALUE: - return &RNA_ValueNodeSocket; - case SOCK_VECTOR: - return &RNA_VectorNodeSocket; - case SOCK_RGBA: - return &RNA_RGBANodeSocket; - default: - return &RNA_UnknownType; - } -} - static StructRNA *rna_NodeTree_refine(struct PointerRNA *ptr) { bNodeTree *ntree= (bNodeTree*)ptr->data; @@ -170,6 +202,46 @@ static char *rna_Node_path(PointerRNA *ptr) return BLI_sprintfN("nodes[\"%s\"]", node->name); } +static StructRNA *rna_NodeSocket_refine(PointerRNA *ptr) +{ + bNodeSocket *sock= (bNodeSocket*)ptr->data; + + if (sock->default_value) { + /* This returns the refined socket type with the full definition + * of the default input value with type and subtype. + */ + + #define SUBTYPE(socktype, stypename, id, idname) \ + { \ + bNodeSocketValue##stypename *value= (bNodeSocketValue##stypename*)sock->default_value; \ + if (value->subtype==PROP_##id) \ + return &RNA_NodeSocket##stypename##idname; \ + } + + switch (sock->type) { + case SOCK_FLOAT: + NODE_DEFINE_SUBTYPES_FLOAT + break; + case SOCK_INT: + NODE_DEFINE_SUBTYPES_INT + break; + case SOCK_BOOLEAN: + return &RNA_NodeSocketBoolean; + break; + case SOCK_VECTOR: + NODE_DEFINE_SUBTYPES_VECTOR + break; + case SOCK_RGBA: + return &RNA_NodeSocketRGBA; + break; + } + + #undef SUBTYPE + } + + return &RNA_NodeSocket; +} + static char *rna_NodeSocket_path(PointerRNA *ptr) { bNodeTree *ntree= (bNodeTree*)ptr->id.data; @@ -275,7 +347,7 @@ static void rna_NodeGroup_update(Main *bmain, Scene *scene, PointerRNA *ptr) bNodeTree *ntree= (bNodeTree*)ptr->id.data; bNode *node= (bNode*)ptr->data; - nodeGroupVerify((bNodeTree *)node->id); + ntreeUpdateTree((bNodeTree *)node->id); node_update(bmain, scene, ntree, node); } @@ -313,18 +385,42 @@ static void rna_NodeGroupSocket_update(Main *bmain, Scene *scene, PointerRNA *pt bNodeSocket *sock= (bNodeSocket*)ptr->data; bNode *node; - nodeGroupVerify(ntree); + ntreeUpdateTree(ntree); if (nodeFindNode(ntree, sock, &node, NULL, NULL)) node_update(bmain, scene, ntree, node); } -static void rna_NodeSocket_defvalue_range(PointerRNA *ptr, float *min, float *max) +static void rna_NodeLink_update(Main *bmain, Scene *scene, PointerRNA *ptr) +{ + bNodeTree *ntree= (bNodeTree*)ptr->id.data; + + ntree->update |= NTREE_UPDATE_LINKS; + ntreeUpdateTree(ntree); +} + +static void rna_NodeSocketInt_range(PointerRNA *ptr, int *min, int *max) { bNodeSocket *sock= (bNodeSocket*)ptr->data; + bNodeSocketValueInt *val= (bNodeSocketValueInt*)sock->default_value; + *min = val->min; + *max = val->max; +} - *min = sock->ns.min; - *max = sock->ns.max; +static void rna_NodeSocketFloat_range(PointerRNA *ptr, float *min, float *max) +{ + bNodeSocket *sock= (bNodeSocket*)ptr->data; + bNodeSocketValueFloat *val= (bNodeSocketValueFloat*)sock->default_value; + *min = val->min; + *max = val->max; +} + +static void rna_NodeSocketVector_range(PointerRNA *ptr, float *min, float *max) +{ + bNodeSocket *sock= (bNodeSocket*)ptr->data; + bNodeSocketValueVector *val= (bNodeSocketValueVector*)sock->default_value; + *min = val->min; + *max = val->max; } static void rna_Node_mapping_update(Main *bmain, Scene *scene, PointerRNA *ptr) @@ -454,18 +550,22 @@ static EnumPropertyItem *rna_Node_channel_itemf(bContext *UNUSED(C), PointerRNA static bNode *rna_NodeTree_node_new(bNodeTree *ntree, bContext *UNUSED(C), ReportList *reports, int type, bNodeTree *group) { bNode *node; + bNodeTemplate ntemp; if (type == NODE_GROUP && group == NULL) { BKE_reportf(reports, RPT_ERROR, "node type \'GROUP\' missing group argument"); return NULL; } - node = nodeAddNodeType(ntree, type, group, NULL); - + + ntemp.type = type; + ntemp.ngroup = group; + node = nodeAddNode(ntree, &ntemp); + if (node == NULL) { BKE_reportf(reports, RPT_ERROR, "Unable to create node"); } else { - nodeGroupVerify(ntree); /* update group node socket links*/ + ntreeUpdateTree(ntree); /* update group node socket links*/ NodeTagChanged(ntree, node); WM_main_add_notifier(NC_NODE|NA_EDITED, ntree); @@ -495,7 +595,7 @@ static bNode *rna_NodeTree_node_composite_new(bNodeTree *ntree, bContext *C, Rep } ntreeCompositForceHidden(ntree, CTX_data_scene(C)); - ntreeSolveOrder(ntree); + ntreeUpdateTree(ntree); } return node; @@ -523,7 +623,7 @@ static void rna_NodeTree_node_remove(bNodeTree *ntree, ReportList *reports, bNod id_us_min(node->id); nodeFreeNode(ntree, node); - nodeGroupVerify(ntree); /* update group node socket links*/ + ntreeUpdateTree(ntree); /* update group node socket links*/ WM_main_add_notifier(NC_NODE|NA_EDITED, ntree); } @@ -551,9 +651,7 @@ static bNodeLink *rna_NodeTree_link_new(bNodeTree *ntree, ReportList *reports, b if(ret) { NodeTagChanged(ntree, tonode); - nodeGroupVerify(ntree); /* update group node socket links*/ - - ntreeSolveOrder(ntree); + ntreeUpdateTree(ntree); WM_main_add_notifier(NC_NODE|NA_EDITED, ntree); } @@ -567,8 +665,7 @@ static void rna_NodeTree_link_remove(bNodeTree *ntree, ReportList *reports, bNod } else { nodeRemLink(ntree, link); - ntreeSolveOrder(ntree); - nodeGroupVerify(ntree); /* update group node socket links*/ + ntreeUpdateTree(ntree); WM_main_add_notifier(NC_NODE|NA_EDITED, ntree); } @@ -577,9 +674,10 @@ static void rna_NodeTree_link_remove(bNodeTree *ntree, ReportList *reports, bNod static bNodeSocket *rna_NodeTree_input_new(bNodeTree *ntree, ReportList *UNUSED(reports), const char *name, int type) { /* XXX should check if tree is a group here! no good way to do this currently. */ - bNodeSocket *gsock= nodeGroupAddSocket(ntree, name, type, SOCK_IN); + bNodeSocket *gsock= node_group_add_socket(ntree, name, type, SOCK_IN); - nodeGroupVerify(ntree); /* update group node socket links*/ + ntree->update |= NTREE_UPDATE_GROUP_IN; + ntreeUpdateTree(ntree); WM_main_add_notifier(NC_NODE|NA_EDITED, ntree); return gsock; } @@ -587,9 +685,10 @@ static bNodeSocket *rna_NodeTree_input_new(bNodeTree *ntree, ReportList *UNUSED( static bNodeSocket *rna_NodeTree_output_new(bNodeTree *ntree, ReportList *UNUSED(reports), const char *name, int type) { /* XXX should check if tree is a group here! no good way to do this currently. */ - bNodeSocket *gsock= nodeGroupAddSocket(ntree, name, type, SOCK_OUT); + bNodeSocket *gsock= node_group_add_socket(ntree, name, type, SOCK_OUT); - nodeGroupVerify(ntree); /* update group node socket links*/ + ntree->update |= NTREE_UPDATE_GROUP_OUT; + ntreeUpdateTree(ntree); WM_main_add_notifier(NC_NODE|NA_EDITED, ntree); return gsock; } @@ -606,11 +705,12 @@ static bNodeSocket *rna_NodeTree_input_expose(bNodeTree *ntree, ReportList *repo BKE_reportf(reports, RPT_ERROR, "Socket is not an input"); else { /* XXX should check if tree is a group here! no good way to do this currently. */ - gsock = nodeGroupAddSocket(ntree, sock->name, sock->type, SOCK_IN); + gsock = node_group_add_socket(ntree, sock->name, sock->type, SOCK_IN); if (add_link) nodeAddLink(ntree, NULL, gsock, node, sock); - nodeGroupVerify(ntree); /* update group node socket links*/ + ntree->update |= NTREE_UPDATE_GROUP_IN; + ntreeUpdateTree(ntree); WM_main_add_notifier(NC_NODE|NA_EDITED, ntree); return gsock; } @@ -629,11 +729,12 @@ static bNodeSocket *rna_NodeTree_output_expose(bNodeTree *ntree, ReportList *rep BKE_reportf(reports, RPT_ERROR, "Socket is not an output"); else { /* XXX should check if tree is a group here! no good way to do this currently. */ - gsock = nodeGroupAddSocket(ntree, sock->name, sock->type, SOCK_OUT); + gsock = node_group_add_socket(ntree, sock->name, sock->type, SOCK_OUT); if (add_link) nodeAddLink(ntree, node, sock, NULL, gsock); - nodeGroupVerify(ntree); /* update group node socket links*/ + ntree->update |= NTREE_UPDATE_GROUP_OUT; + ntreeUpdateTree(ntree); WM_main_add_notifier(NC_NODE|NA_EDITED, ntree); return gsock; } @@ -668,14 +769,16 @@ static EnumPropertyItem node_ycc_items[] = { { 2, "JFIF", 0, "Jpeg", ""}, {0, NULL, 0, NULL, NULL}}; -#define MaxNodes 1000 +#define MaxNodes 50000 enum { Category_GroupNode, + Category_LoopNode, + Category_LayoutNode, Category_ShaderNode, Category_CompositorNode, - Category_TextureNode + Category_TextureNode, }; typedef struct NodeInfo @@ -715,9 +818,10 @@ static void init(void) #include "rna_nodetree_types.h" - #undef DefNode - reg_node(NODE_GROUP, Category_GroupNode, "GROUP", "NodeGroup", "Node", "Group", ""); + reg_node(NODE_FORLOOP, Category_LoopNode, "FORLOOP", "NodeForLoop", "Node", "ForLoop", ""); + reg_node(NODE_WHILELOOP, Category_LoopNode, "WHILELOOP", "NodeWhileLoop", "Node", "WhileLoop", ""); + reg_node(NODE_FRAME, Category_LayoutNode, "FRAME", "NodeFrame", "Node", "Frame", ""); } static StructRNA* def_node(BlenderRNA *brna, int node_id) @@ -793,6 +897,41 @@ static void def_group(StructRNA *srna) RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_NodeGroup_update"); } +static void def_forloop(StructRNA *srna) +{ + PropertyRNA *prop; + + prop = RNA_def_property(srna, "node_tree", PROP_POINTER, PROP_NONE); + RNA_def_property_pointer_sdna(prop, NULL, "id"); + RNA_def_property_struct_type(prop, "NodeTree"); + RNA_def_property_flag(prop, PROP_EDITABLE); + RNA_def_property_ui_text(prop, "Node Tree", ""); + RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_NodeGroup_update"); +} + +static void def_whileloop(StructRNA *srna) +{ + PropertyRNA *prop; + + prop = RNA_def_property(srna, "node_tree", PROP_POINTER, PROP_NONE); + RNA_def_property_pointer_sdna(prop, NULL, "id"); + RNA_def_property_struct_type(prop, "NodeTree"); + RNA_def_property_flag(prop, PROP_EDITABLE); + RNA_def_property_ui_text(prop, "Node Tree", ""); + RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_NodeGroup_update"); + + prop = RNA_def_property(srna, "max_iterations", PROP_INT, PROP_NONE); + RNA_def_property_int_sdna(prop, NULL, "custom1"); + RNA_def_property_range(prop, 0.0f, 10000000.0f); + RNA_def_property_ui_text(prop, "Max. Iterations", "Limit for number of iterations"); + RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_NodeGroup_update"); +} + +static void def_frame(StructRNA *srna) +{ +// PropertyRNA *prop; + +} static void def_math(StructRNA *srna) { @@ -2510,94 +2649,112 @@ static void rna_def_node_socket(BlenderRNA *brna) srna = RNA_def_struct(brna, "NodeSocket", NULL); RNA_def_struct_ui_text(srna, "Node Socket", "Input or output socket of a node"); - RNA_def_struct_refine_func(srna, "rna_NodeSocketType_refine"); RNA_def_struct_sdna(srna, "bNodeSocket"); + RNA_def_struct_refine_func(srna, "rna_NodeSocket_refine"); RNA_def_struct_ui_icon(srna, ICON_PLUG); RNA_def_struct_path_func(srna, "rna_NodeSocket_path"); + prop = RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "type"); + RNA_def_property_enum_items(prop, node_socket_type_items); + RNA_def_property_enum_default(prop, 0); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_ui_text(prop, "Type", "Node Socket type"); + prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE); /* XXX must be editable for group sockets. if necessary use a special rna definition for these */ // RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text(prop, "Name", "Socket name"); RNA_def_struct_name_property(srna, prop); RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_NodeGroupSocket_update"); - - /* can add back if there is any use in reading them */ -#if 0 - prop = RNA_def_property(srna, "min", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "ns.min"); - RNA_def_property_clear_flag(prop, PROP_EDITABLE); - RNA_def_property_ui_text(prop, "Minimum Value", ""); - RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_NodeSocket_update"); - - prop = RNA_def_property(srna, "max", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "ns.max"); - RNA_def_property_clear_flag(prop, PROP_EDITABLE); - RNA_def_property_ui_text(prop, "Maximum Value", ""); - RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_NodeSocket_update"); -#endif - - prop = RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE); - RNA_def_property_clear_flag(prop, PROP_EDITABLE); - RNA_def_property_enum_items(prop, node_socket_type_items); - RNA_def_property_ui_text(prop, "Type", "Node Socket type"); } -static void rna_def_node_socket_value(BlenderRNA *brna) +static void rna_def_node_socket_subtype(BlenderRNA *brna, int type, int subtype, const char *name, const char *ui_name) { StructRNA *srna; - PropertyRNA *prop; + PropertyRNA *prop=NULL; + PropertySubType propsubtype= PROP_NONE; + + #define SUBTYPE(socktype, stypename, id, idname) { PROP_##id, #id, 0, #idname, ""}, + static EnumPropertyItem subtype_items[] = { + NODE_DEFINE_SUBTYPES + {0, NULL, 0, NULL, NULL} + }; + #undef SUBTYPE - srna = RNA_def_struct(brna, "ValueNodeSocket", "NodeSocket"); - RNA_def_struct_ui_text(srna, "Value Node Socket", "Input or output socket of a node"); + #define SUBTYPE(socktype, stypename, id, idname) if (subtype==PROP_##id) propsubtype = PROP_##id; + NODE_DEFINE_SUBTYPES + #undef SUBTYPE + + srna = RNA_def_struct(brna, name, "NodeSocket"); + RNA_def_struct_ui_text(srna, ui_name, "Input or output socket of a node"); RNA_def_struct_sdna(srna, "bNodeSocket"); RNA_def_struct_ui_icon(srna, ICON_PLUG); RNA_def_struct_path_func(srna, "rna_NodeSocket_path"); - - prop = RNA_def_property(srna, "default_value", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "ns.vec"); - RNA_def_property_array(prop, 1); - RNA_def_property_ui_text(prop, "Default Value", "Default value of the socket when no link is attached"); - RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_NodeSocket_update"); - RNA_def_property_float_funcs(prop, NULL, NULL, "rna_NodeSocket_defvalue_range"); -} - -static void rna_def_node_socket_vector(BlenderRNA *brna) -{ - StructRNA *srna; - PropertyRNA *prop; - - srna = RNA_def_struct(brna, "VectorNodeSocket", "NodeSocket"); - RNA_def_struct_ui_text(srna, "Vector Node Socket", "Input or output socket of a node"); - RNA_def_struct_sdna(srna, "bNodeSocket"); - RNA_def_struct_ui_icon(srna, ICON_PLUG); - RNA_def_struct_path_func(srna, "rna_NodeSocket_path"); - - prop = RNA_def_property(srna, "default_value", PROP_FLOAT, PROP_XYZ); - RNA_def_property_float_sdna(prop, NULL, "ns.vec"); - RNA_def_property_array(prop, 3); - RNA_def_property_ui_text(prop, "Default Value", "Default value of the socket when no link is attached"); - RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_NodeSocket_update"); - RNA_def_property_float_funcs(prop, NULL, NULL, "rna_NodeSocket_defvalue_range"); -} - -static void rna_def_node_socket_rgba(BlenderRNA *brna) -{ - StructRNA *srna; - PropertyRNA *prop; - - srna = RNA_def_struct(brna, "RGBANodeSocket", "NodeSocket"); - RNA_def_struct_ui_text(srna, "RGBA Node Socket", "Input or output socket of a node"); - RNA_def_struct_sdna(srna, "bNodeSocket"); - RNA_def_struct_ui_icon(srna, ICON_PLUG); - RNA_def_struct_path_func(srna, "rna_NodeSocket_path"); - - prop = RNA_def_property(srna, "default_value", PROP_FLOAT, PROP_COLOR); - RNA_def_property_float_sdna(prop, NULL, "ns.vec"); - RNA_def_property_array(prop, 4); - RNA_def_property_ui_text(prop, "Default Value", "Default value of the socket when no link is attached"); - RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_NodeSocket_update"); - RNA_def_property_float_funcs(prop, NULL, NULL, "rna_NodeSocket_defvalue_range"); + + switch (type) { + case SOCK_INT: + RNA_def_struct_sdna_from(srna, "bNodeSocketValueInt", "default_value"); + + prop = RNA_def_property(srna, "subtype", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "subtype"); + RNA_def_property_enum_items(prop, subtype_items); + RNA_def_property_ui_text(prop, "Subtype", "Subtype defining the socket value details"); + RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_NodeSocket_update"); + + prop = RNA_def_property(srna, "default_value", PROP_INT, propsubtype); + RNA_def_property_int_sdna(prop, NULL, "value"); + RNA_def_property_int_funcs(prop, NULL, NULL, "rna_NodeSocketInt_range"); + RNA_def_property_ui_text(prop, "Default Value", ""); + RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_NodeSocket_update"); + break; + case SOCK_FLOAT: + RNA_def_struct_sdna_from(srna, "bNodeSocketValueFloat", "default_value"); + + prop = RNA_def_property(srna, "subtype", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "subtype"); + RNA_def_property_enum_items(prop, subtype_items); + RNA_def_property_ui_text(prop, "Subtype", "Subtype defining the socket value details"); + RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_NodeSocket_update"); + + prop = RNA_def_property(srna, "default_value", PROP_FLOAT, propsubtype); + RNA_def_property_float_sdna(prop, NULL, "value"); + RNA_def_property_float_funcs(prop, NULL, NULL, "rna_NodeSocketFloat_range"); + RNA_def_property_ui_text(prop, "Default Value", ""); + RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_NodeSocket_update"); + break; + case SOCK_BOOLEAN: + RNA_def_struct_sdna_from(srna, "bNodeSocketValueBoolean", "default_value"); + + prop = RNA_def_property(srna, "default_value", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "value", 1); + RNA_def_property_ui_text(prop, "Default Value", ""); + RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_NodeSocket_update"); + break; + case SOCK_VECTOR: + RNA_def_struct_sdna_from(srna, "bNodeSocketValueVector", "default_value"); + + prop = RNA_def_property(srna, "subtype", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "subtype"); + RNA_def_property_enum_items(prop, subtype_items); + RNA_def_property_ui_text(prop, "Subtype", "Subtype defining the socket value details"); + RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_NodeSocket_update"); + + prop = RNA_def_property(srna, "default_value", PROP_FLOAT, propsubtype); + RNA_def_property_float_sdna(prop, NULL, "value"); + RNA_def_property_float_funcs(prop, NULL, NULL, "rna_NodeSocketVector_range"); + RNA_def_property_ui_text(prop, "Default Value", ""); + RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_NodeSocket_update"); + break; + case SOCK_RGBA: + RNA_def_struct_sdna_from(srna, "bNodeSocketValueRGBA", "default_value"); + + prop = RNA_def_property(srna, "default_value", PROP_FLOAT, PROP_COLOR); + RNA_def_property_float_sdna(prop, NULL, "value"); + RNA_def_property_ui_text(prop, "Default Value", ""); + RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_NodeSocket_update"); + break; + } } static void rna_def_node(BlenderRNA *brna) @@ -2625,6 +2782,11 @@ static void rna_def_node(BlenderRNA *brna) RNA_def_property_string_funcs(prop, NULL, NULL, "rna_Node_name_set"); RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_update"); + prop = RNA_def_property(srna, "label", PROP_STRING, PROP_NONE); + RNA_def_property_string_sdna(prop, NULL, "label"); + RNA_def_property_ui_text(prop, "Label", "Optional custom node label"); + RNA_def_property_update(prop, NC_NODE, "rna_Node_update"); + prop = RNA_def_property(srna, "inputs", PROP_COLLECTION, PROP_NONE); RNA_def_property_collection_sdna(prop, NULL, "inputs", NULL); RNA_def_property_struct_type(prop, "NodeSocket"); @@ -2634,18 +2796,19 @@ static void rna_def_node(BlenderRNA *brna) RNA_def_property_collection_sdna(prop, NULL, "outputs", NULL); RNA_def_property_struct_type(prop, "NodeSocket"); RNA_def_property_ui_text(prop, "Outputs", ""); - - prop = RNA_def_property(srna, "label", PROP_STRING, PROP_NONE); - RNA_def_property_string_sdna(prop, NULL, "label"); - RNA_def_property_ui_text(prop, "Label", "Optional custom node label"); - RNA_def_property_update(prop, NC_NODE, "rna_Node_update"); + + prop = RNA_def_property(srna, "parent", PROP_POINTER, PROP_NONE); + RNA_def_property_pointer_sdna(prop, NULL, "parent"); + RNA_def_property_struct_type(prop, "Node"); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_ui_text(prop, "Parent", "Parent this node is attached to"); } static void rna_def_node_link(BlenderRNA *brna) { StructRNA *srna; PropertyRNA *prop; - + srna = RNA_def_struct(brna, "NodeLink", NULL); RNA_def_struct_ui_text(srna, "NodeLink", "Link between nodes in a node tree"); RNA_def_struct_sdna(srna, "bNodeLink"); @@ -2687,7 +2850,7 @@ static void rna_def_group_sockets_api(BlenderRNA *brna, PropertyRNA *cprop, int RNA_def_function_ui_description(func, "Add a socket to the group tree."); RNA_def_function_flag(func, FUNC_USE_REPORTS); RNA_def_string(func, "name", "Socket", 32, "Name", "Name of the socket"); - RNA_def_enum(func, "type", node_socket_type_items, SOCK_VALUE, "Type", "Type of socket"); + RNA_def_enum(func, "type", node_socket_type_items, SOCK_FLOAT, "Type", "Type of socket"); /* return value */ parm= RNA_def_pointer(func, "socket", "NodeSocket", "", "New socket."); RNA_def_function_return(func, parm); @@ -2708,12 +2871,6 @@ static void rna_def_nodetree(BlenderRNA *brna) StructRNA *srna; PropertyRNA *prop; - static EnumPropertyItem nodetree_type_items[] = { - {NTREE_SHADER, "SHADER", 0, "Shader", ""}, - {NTREE_COMPOSIT, "COMPOSITE", 0, "Composite", ""}, - {NTREE_TEXTURE, "TEXTURE", 0, "Texture", ""}, - {0, NULL, 0, NULL, NULL}}; - srna = RNA_def_struct(brna, "NodeTree", "ID"); RNA_def_struct_ui_text(srna, "Node Tree", "Node tree consisting of linked nodes used for materials, textures and compositing"); RNA_def_struct_sdna(srna, "bNodeTree"); @@ -2826,15 +2983,23 @@ void RNA_def_nodetree(BlenderRNA *brna) { init(); rna_def_nodetree(brna); + rna_def_node_socket(brna); - rna_def_node_socket_value(brna); - rna_def_node_socket_vector(brna); - rna_def_node_socket_rgba(brna); + + /* Generate RNA definitions for all socket subtypes */ + #define SUBTYPE(socktype, stypename, id, idname) \ + rna_def_node_socket_subtype(brna, SOCK_##socktype, PROP_##id, "NodeSocket"#stypename#idname, #idname" "#stypename" Node Socket"); + NODE_DEFINE_SUBTYPES + #undef SUBTYPE + rna_def_node_socket_subtype(brna, SOCK_BOOLEAN, 0, "NodeSocketBoolean", "Boolean Node Socket"); + rna_def_node_socket_subtype(brna, SOCK_RGBA, 0, "NodeSocketRGBA", "RGBA Node Socket"); + rna_def_node(brna); rna_def_node_link(brna); rna_def_shader_node(brna); rna_def_compositor_node(brna); rna_def_texture_node(brna); + rna_def_composite_nodetree(brna); rna_def_shader_nodetree(brna); rna_def_texture_nodetree(brna); @@ -2843,10 +3008,14 @@ void RNA_def_nodetree(BlenderRNA *brna) #include "rna_nodetree_types.h" - #undef DefNode - define_specific_node(brna, NODE_GROUP, def_group); + define_specific_node(brna, NODE_FORLOOP, def_forloop); + define_specific_node(brna, NODE_WHILELOOP, def_whileloop); + define_specific_node(brna, NODE_FRAME, def_frame); } +/* clean up macro definition */ +#undef NODE_DEFINE_SUBTYPES + #endif diff --git a/source/blender/makesrna/intern/rna_nodetree_types.h b/source/blender/makesrna/intern/rna_nodetree_types.h index d48df85697a..a624d1d6403 100644 --- a/source/blender/makesrna/intern/rna_nodetree_types.h +++ b/source/blender/makesrna/intern/rna_nodetree_types.h @@ -26,7 +26,12 @@ * \ingroup RNA */ - + +/* Empty definitions for undefined macros to avoid warnings */ +#ifndef DefNode +#define DefNode(Category, ID, DefFunc, EnumName, StructName, UIName, UIDesc) +#endif + /* Tree type Node ID RNA def function Enum name Struct name UI Name UI Description */ DefNode( ShaderNode, SH_NODE_OUTPUT, 0, "OUTPUT", Output, "Output", "" ) DefNode( ShaderNode, SH_NODE_MATERIAL, def_sh_material, "MATERIAL", Material, "Material", "" ) @@ -138,3 +143,6 @@ DefNode( TextureNode, TEX_NODE_DECOMPOSE, 0, "DECOM DefNode( TextureNode, TEX_NODE_VALTONOR, 0, "VALTONOR", ValToNor, "Val to Nor", "" ) DefNode( TextureNode, TEX_NODE_SCALE, 0, "SCALE", Scale, "Scale", "" ) + +/* undefine macros */ +#undef DefNode diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c index 4e2be7682f8..83efd9d1a9f 100644 --- a/source/blender/makesrna/intern/rna_object.c +++ b/source/blender/makesrna/intern/rna_object.c @@ -132,6 +132,7 @@ EnumPropertyItem object_type_curve_items[] = { #include "DNA_key_types.h" #include "DNA_constraint_types.h" #include "DNA_lattice_types.h" +#include "DNA_node_types.h" #include "BKE_armature.h" #include "BKE_bullet.h" @@ -2035,18 +2036,19 @@ static void rna_def_object(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Matrix", "Inverse of object's parent matrix at time of parenting"); RNA_def_property_update(prop, NC_OBJECT|ND_TRANSFORM, "rna_Object_internal_update"); - /* collections */ + /* modifiers */ + prop= RNA_def_property(srna, "modifiers", PROP_COLLECTION, PROP_NONE); + RNA_def_property_struct_type(prop, "Modifier"); + RNA_def_property_ui_text(prop, "Modifiers", "Modifiers affecting the geometric data of the object"); + rna_def_object_modifiers(brna, prop); + + /* constraints */ prop= RNA_def_property(srna, "constraints", PROP_COLLECTION, PROP_NONE); RNA_def_property_struct_type(prop, "Constraint"); RNA_def_property_ui_text(prop, "Constraints", "Constraints affecting the transformation of the object"); // RNA_def_property_collection_funcs(prop, 0, 0, 0, 0, 0, 0, 0, "constraints__add", "constraints__remove"); rna_def_object_constraints(brna, prop); - prop= RNA_def_property(srna, "modifiers", PROP_COLLECTION, PROP_NONE); - RNA_def_property_struct_type(prop, "Modifier"); - RNA_def_property_ui_text(prop, "Modifiers", "Modifiers affecting the geometric data of the object"); - rna_def_object_modifiers(brna, prop); - /* game engine */ prop= RNA_def_property(srna, "game", PROP_POINTER, PROP_NONE); RNA_def_property_flag(prop, PROP_NEVER_NULL); diff --git a/source/blender/makesrna/intern/rna_rna.c b/source/blender/makesrna/intern/rna_rna.c index e063f8ec85a..7f85a2fa1d7 100644 --- a/source/blender/makesrna/intern/rna_rna.c +++ b/source/blender/makesrna/intern/rna_rna.c @@ -46,6 +46,42 @@ EnumPropertyItem property_type_items[] = { {PROP_COLLECTION, "COLLECTION", 0, "Collection", ""}, {0, NULL, 0, NULL, NULL}}; +EnumPropertyItem property_subtype_items[] = { + {PROP_NONE, "NONE", 0, "None", ""}, + + /* strings */ + {PROP_FILEPATH, "FILEPATH", 0, "File Path", ""}, + {PROP_DIRPATH, "DIRPATH", 0, "Directory Path", ""}, + {PROP_FILENAME, "FILENAME", 0, "File Name", ""}, + + /* numbers */ + {PROP_UNSIGNED, "UNSIGNED", 0, "Unsigned", ""}, + {PROP_PERCENTAGE, "PERCENTAGE", 0, "Percentage", ""}, + {PROP_FACTOR, "FACTOR", 0, "Factor", ""}, + {PROP_ANGLE, "ANGLE", 0, "Angle", ""}, + {PROP_TIME, "TIME", 0, "Time", ""}, + {PROP_DISTANCE, "DISTANCE", 0, "Distance", ""}, + + /* number arrays */ + {PROP_COLOR, "COLOR", 0, "Color", ""}, + {PROP_TRANSLATION, "TRANSLATION", 0, "Translation", ""}, + {PROP_DIRECTION, "DIRECTION", 0, "Direction", ""}, + {PROP_VELOCITY, "VELOCITY", 0, "Velocity", ""}, + {PROP_ACCELERATION, "ACCELERATION", 0, "Acceleration", ""}, + {PROP_MATRIX, "MATRIX", 0, "Matrix", ""}, + {PROP_EULER, "EULER", 0, "Euler Angles", ""}, + {PROP_QUATERNION, "QUATERNION", 0, "Quaternion", ""}, + {PROP_AXISANGLE, "AXISANGLE", 0, "Axis-Angle", ""}, + {PROP_XYZ, "XYZ", 0, "XYZ", ""}, + {PROP_XYZ_LENGTH, "XYZ_LENGTH", 0, "XYZ Length", ""}, + {PROP_COLOR_GAMMA, "COLOR_GAMMA", 0, "Color", ""}, + {PROP_COORDS, "COORDS", 0, "Coordinates", ""}, + + /* booleans */ + {PROP_LAYER, "LAYER", 0, "Layer", ""}, + {PROP_LAYER_MEMBER, "LAYER_MEMBER", 0, "Layer Member", ""}, + {0, NULL, 0, NULL, NULL}}; + EnumPropertyItem property_unit_items[] = { {PROP_UNIT_NONE, "NONE", 0, "None", ""}, {PROP_UNIT_LENGTH, "LENGTH", 0, "Length", ""}, diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index 35115b40d59..249cdb28ae1 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -48,6 +48,8 @@ #include "WM_api.h" #include "WM_types.h" +#include "RNA_enum_types.h" + EnumPropertyItem space_type_items[] = { {SPACE_EMPTY, "EMPTY", 0, "Empty", ""}, {SPACE_VIEW3D, "VIEW_3D", 0, "3D View", ""}, @@ -119,6 +121,7 @@ EnumPropertyItem viewport_shade_items[] = { #include "BKE_paint.h" #include "ED_image.h" +#include "ED_node.h" #include "ED_screen.h" #include "ED_view3d.h" #include "ED_sequencer.h" @@ -839,6 +842,24 @@ static void rna_BackgroundImage_opacity_set(PointerRNA *ptr, float value) bgpic->blend = 1.0f - value; } +/* Space Node Editor */ + +static int rna_SpaceNodeEditor_node_tree_poll(PointerRNA *ptr, PointerRNA value) +{ + SpaceNode *snode= (SpaceNode*)ptr->data; + bNodeTree *ntree= (bNodeTree*)value.data; + + /* exclude group trees, only trees of the active type */ + return (ntree->nodetype==0 && ntree->type == snode->treetype); +} + +static void rna_SpaceNodeEditor_node_tree_update(Main *bmain, Scene *scene, PointerRNA *ptr) +{ + SpaceNode *snode= (SpaceNode*)ptr->data; + + ED_node_tree_update(snode, scene); +} + static EnumPropertyItem *rna_SpaceProperties_texture_context_itemf(bContext *C, PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), int *free) { Scene *scene = CTX_data_scene(C); @@ -2414,12 +2435,6 @@ static void rna_def_space_node(BlenderRNA *brna) StructRNA *srna; PropertyRNA *prop; - static EnumPropertyItem tree_type_items[] = { - {NTREE_SHADER, "MATERIAL", ICON_MATERIAL, "Material", "Material nodes"}, - {NTREE_TEXTURE, "TEXTURE", ICON_TEXTURE, "Texture", "Texture nodes"}, - {NTREE_COMPOSIT, "COMPOSITING", ICON_RENDERLAYERS, "Compositing", "Compositing nodes"}, - {0, NULL, 0, NULL, NULL}}; - static EnumPropertyItem texture_type_items[] = { {SNODE_TEX_OBJECT, "OBJECT", ICON_OBJECT_DATA, "Object", "Edit texture nodes from Object"}, {SNODE_TEX_WORLD, "WORLD", ICON_WORLD_DATA, "World", "Edit texture nodes from World"}, @@ -2438,7 +2453,7 @@ static void rna_def_space_node(BlenderRNA *brna) prop= RNA_def_property(srna, "tree_type", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "treetype"); - RNA_def_property_enum_items(prop, tree_type_items); + RNA_def_property_enum_items(prop, nodetree_type_items); RNA_def_property_ui_text(prop, "Tree Type", "Node tree type to display and edit"); RNA_def_property_update(prop, NC_SPACE|ND_SPACE_NODE, NULL); @@ -2459,8 +2474,10 @@ static void rna_def_space_node(BlenderRNA *brna) prop= RNA_def_property(srna, "node_tree", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "nodetree"); - RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_pointer_funcs(prop, NULL, NULL, NULL, "rna_SpaceNodeEditor_node_tree_poll"); + RNA_def_property_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text(prop, "Node Tree", "Node tree being displayed and edited"); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_NODE, "rna_SpaceNodeEditor_node_tree_update"); prop= RNA_def_property(srna, "show_backdrop", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", SNODE_BACKDRAW); diff --git a/source/blender/modifiers/CMakeLists.txt b/source/blender/modifiers/CMakeLists.txt index d1f153265ac..1d942de348b 100644 --- a/source/blender/modifiers/CMakeLists.txt +++ b/source/blender/modifiers/CMakeLists.txt @@ -32,6 +32,7 @@ set(INC ../blenlib ../blenloader ../makesdna + ../makesrna ../render/extern/include ../../../intern/elbeem/extern ../../../intern/guardedalloc diff --git a/source/blender/modifiers/SConscript b/source/blender/modifiers/SConscript index d1bb95761ff..66dd00f0248 100644 --- a/source/blender/modifiers/SConscript +++ b/source/blender/modifiers/SConscript @@ -6,7 +6,7 @@ sources = env.Glob('intern/*.c') incs = '. ./intern' incs += ' #/intern/guardedalloc #/intern/decimation/extern #/intern/bsp/extern #/intern/elbeem/extern' incs += ' ../render/extern/include ../blenloader' -incs += ' ../include ../blenlib ../makesdna ../blenkernel ../blenkernel/intern' +incs += ' ../include ../blenlib ../makesdna ../makesrna ../blenkernel ../blenkernel/intern' incs += ' ' + env['BF_ZLIB_INC'] diff --git a/source/blender/nodes/CMakeLists.txt b/source/blender/nodes/CMakeLists.txt index c3bd37c18ee..82848c6a5d7 100644 --- a/source/blender/nodes/CMakeLists.txt +++ b/source/blender/nodes/CMakeLists.txt @@ -38,117 +38,137 @@ set(INC set(INC_SYS ${GLEW_INCLUDE_PATH} + intern + composite + shader + texture ) set(SRC - intern/CMP_nodes/CMP_alphaOver.c - intern/CMP_nodes/CMP_bilateralblur.c - intern/CMP_nodes/CMP_blur.c - intern/CMP_nodes/CMP_brightness.c - intern/CMP_nodes/CMP_channelMatte.c - intern/CMP_nodes/CMP_chromaMatte.c - intern/CMP_nodes/CMP_colorMatte.c - intern/CMP_nodes/CMP_colorSpill.c - intern/CMP_nodes/CMP_colorbalance.c - intern/CMP_nodes/CMP_composite.c - intern/CMP_nodes/CMP_crop.c - intern/CMP_nodes/CMP_curves.c - intern/CMP_nodes/CMP_defocus.c - intern/CMP_nodes/CMP_diffMatte.c - intern/CMP_nodes/CMP_dilate.c - intern/CMP_nodes/CMP_directionalblur.c - intern/CMP_nodes/CMP_displace.c - intern/CMP_nodes/CMP_distanceMatte.c - intern/CMP_nodes/CMP_filter.c - intern/CMP_nodes/CMP_flip.c - intern/CMP_nodes/CMP_gamma.c - intern/CMP_nodes/CMP_glare.c - intern/CMP_nodes/CMP_hueSatVal.c - intern/CMP_nodes/CMP_huecorrect.c - intern/CMP_nodes/CMP_idMask.c - intern/CMP_nodes/CMP_image.c - intern/CMP_nodes/CMP_invert.c - intern/CMP_nodes/CMP_lensdist.c - intern/CMP_nodes/CMP_levels.c - intern/CMP_nodes/CMP_lummaMatte.c - intern/CMP_nodes/CMP_mapUV.c - intern/CMP_nodes/CMP_mapValue.c - intern/CMP_nodes/CMP_math.c - intern/CMP_nodes/CMP_mixrgb.c - intern/CMP_nodes/CMP_normal.c - intern/CMP_nodes/CMP_normalize.c - intern/CMP_nodes/CMP_outputFile.c - intern/CMP_nodes/CMP_premulkey.c - intern/CMP_nodes/CMP_rgb.c - intern/CMP_nodes/CMP_rotate.c - intern/CMP_nodes/CMP_scale.c - intern/CMP_nodes/CMP_sepcombHSVA.c - intern/CMP_nodes/CMP_sepcombRGBA.c - intern/CMP_nodes/CMP_sepcombYCCA.c - intern/CMP_nodes/CMP_sepcombYUVA.c - intern/CMP_nodes/CMP_setalpha.c - intern/CMP_nodes/CMP_splitViewer.c - intern/CMP_nodes/CMP_texture.c - intern/CMP_nodes/CMP_tonemap.c - intern/CMP_nodes/CMP_translate.c - intern/CMP_nodes/CMP_valToRgb.c - intern/CMP_nodes/CMP_value.c - intern/CMP_nodes/CMP_vecBlur.c - intern/CMP_nodes/CMP_viewer.c - intern/CMP_nodes/CMP_zcombine.c - intern/CMP_util.c - intern/SHD_nodes/SHD_camera.c - intern/SHD_nodes/SHD_curves.c - intern/SHD_nodes/SHD_dynamic.c - intern/SHD_nodes/SHD_geom.c - intern/SHD_nodes/SHD_hueSatVal.c - intern/SHD_nodes/SHD_invert.c - intern/SHD_nodes/SHD_mapping.c - intern/SHD_nodes/SHD_material.c - intern/SHD_nodes/SHD_math.c - intern/SHD_nodes/SHD_mixRgb.c - intern/SHD_nodes/SHD_normal.c - intern/SHD_nodes/SHD_output.c - intern/SHD_nodes/SHD_rgb.c - intern/SHD_nodes/SHD_sepcombRGB.c - intern/SHD_nodes/SHD_squeeze.c - intern/SHD_nodes/SHD_texture.c - intern/SHD_nodes/SHD_valToRgb.c - intern/SHD_nodes/SHD_value.c - intern/SHD_nodes/SHD_vectMath.c - intern/SHD_util.c - intern/TEX_nodes/TEX_at.c - intern/TEX_nodes/TEX_bricks.c - intern/TEX_nodes/TEX_checker.c - intern/TEX_nodes/TEX_compose.c - intern/TEX_nodes/TEX_coord.c - intern/TEX_nodes/TEX_curves.c - intern/TEX_nodes/TEX_decompose.c - intern/TEX_nodes/TEX_distance.c - intern/TEX_nodes/TEX_hueSatVal.c - intern/TEX_nodes/TEX_image.c - intern/TEX_nodes/TEX_invert.c - intern/TEX_nodes/TEX_math.c - intern/TEX_nodes/TEX_mixRgb.c - intern/TEX_nodes/TEX_output.c - intern/TEX_nodes/TEX_proc.c - intern/TEX_nodes/TEX_rotate.c - intern/TEX_nodes/TEX_scale.c - intern/TEX_nodes/TEX_texture.c - intern/TEX_nodes/TEX_translate.c - intern/TEX_nodes/TEX_valToNor.c - intern/TEX_nodes/TEX_valToRgb.c - intern/TEX_nodes/TEX_viewer.c - intern/TEX_util.c - intern/node_util.c + composite/nodes/node_composite_alphaOver.c + composite/nodes/node_composite_bilateralblur.c + composite/nodes/node_composite_blur.c + composite/nodes/node_composite_brightness.c + composite/nodes/node_composite_channelMatte.c + composite/nodes/node_composite_chromaMatte.c + composite/nodes/node_composite_colorMatte.c + composite/nodes/node_composite_colorSpill.c + composite/nodes/node_composite_colorbalance.c + composite/nodes/node_composite_common.c + composite/nodes/node_composite_composite.c + composite/nodes/node_composite_crop.c + composite/nodes/node_composite_curves.c + composite/nodes/node_composite_defocus.c + composite/nodes/node_composite_diffMatte.c + composite/nodes/node_composite_dilate.c + composite/nodes/node_composite_directionalblur.c + composite/nodes/node_composite_displace.c + composite/nodes/node_composite_distanceMatte.c + composite/nodes/node_composite_filter.c + composite/nodes/node_composite_flip.c + composite/nodes/node_composite_gamma.c + composite/nodes/node_composite_glare.c + composite/nodes/node_composite_hueSatVal.c + composite/nodes/node_composite_huecorrect.c + composite/nodes/node_composite_idMask.c + composite/nodes/node_composite_image.c + composite/nodes/node_composite_invert.c + composite/nodes/node_composite_lensdist.c + composite/nodes/node_composite_levels.c + composite/nodes/node_composite_lummaMatte.c + composite/nodes/node_composite_mapUV.c + composite/nodes/node_composite_mapValue.c + composite/nodes/node_composite_math.c + composite/nodes/node_composite_mixrgb.c + composite/nodes/node_composite_normal.c + composite/nodes/node_composite_normalize.c + composite/nodes/node_composite_outputFile.c + composite/nodes/node_composite_premulkey.c + composite/nodes/node_composite_rgb.c + composite/nodes/node_composite_rotate.c + composite/nodes/node_composite_scale.c + composite/nodes/node_composite_sepcombHSVA.c + composite/nodes/node_composite_sepcombRGBA.c + composite/nodes/node_composite_sepcombYCCA.c + composite/nodes/node_composite_sepcombYUVA.c + composite/nodes/node_composite_setalpha.c + composite/nodes/node_composite_splitViewer.c + composite/nodes/node_composite_texture.c + composite/nodes/node_composite_tonemap.c + composite/nodes/node_composite_translate.c + composite/nodes/node_composite_valToRgb.c + composite/nodes/node_composite_value.c + composite/nodes/node_composite_vecBlur.c + composite/nodes/node_composite_viewer.c + composite/nodes/node_composite_zcombine.c + composite/node_composite_tree.c + composite/node_composite_util.c - CMP_node.h - SHD_node.h - TEX_node.h - intern/CMP_util.h - intern/SHD_util.h - intern/TEX_util.h + shader/nodes/node_shader_camera.c + shader/nodes/node_shader_common.c + shader/nodes/node_shader_curves.c + shader/nodes/node_shader_dynamic.c + shader/nodes/node_shader_geom.c + shader/nodes/node_shader_hueSatVal.c + shader/nodes/node_shader_invert.c + shader/nodes/node_shader_mapping.c + shader/nodes/node_shader_material.c + shader/nodes/node_shader_math.c + shader/nodes/node_shader_mixRgb.c + shader/nodes/node_shader_normal.c + shader/nodes/node_shader_output.c + shader/nodes/node_shader_rgb.c + shader/nodes/node_shader_sepcombRGB.c + shader/nodes/node_shader_squeeze.c + shader/nodes/node_shader_texture.c + shader/nodes/node_shader_valToRgb.c + shader/nodes/node_shader_value.c + shader/nodes/node_shader_vectMath.c + shader/node_shader_tree.c + shader/node_shader_util.c + + texture/nodes/node_texture_at.c + texture/nodes/node_texture_bricks.c + texture/nodes/node_texture_checker.c + texture/nodes/node_texture_common.c + texture/nodes/node_texture_compose.c + texture/nodes/node_texture_coord.c + texture/nodes/node_texture_curves.c + texture/nodes/node_texture_decompose.c + texture/nodes/node_texture_distance.c + texture/nodes/node_texture_hueSatVal.c + texture/nodes/node_texture_image.c + texture/nodes/node_texture_invert.c + texture/nodes/node_texture_math.c + texture/nodes/node_texture_mixRgb.c + texture/nodes/node_texture_output.c + texture/nodes/node_texture_proc.c + texture/nodes/node_texture_rotate.c + texture/nodes/node_texture_scale.c + texture/nodes/node_texture_texture.c + texture/nodes/node_texture_translate.c + texture/nodes/node_texture_valToNor.c + texture/nodes/node_texture_valToRgb.c + texture/nodes/node_texture_viewer.c + texture/node_texture_tree.c + texture/node_texture_util.c + + intern/node_util.c + intern/node_exec.c + intern/node_common.c + intern/node_socket.c + + composite/node_composite_util.h + shader/node_shader_util.h + texture/node_texture_util.h + + NOD_composite.h + NOD_shader.h + NOD_texture.h + NOD_socket.h intern/node_util.h + intern/node_exec.h + intern/node_common.h ) if(WITH_PYTHON) diff --git a/source/blender/nodes/CMP_node.h b/source/blender/nodes/NOD_composite.h similarity index 93% rename from source/blender/nodes/CMP_node.h rename to source/blender/nodes/NOD_composite.h index 65c9236710f..ab56199079e 100644 --- a/source/blender/nodes/CMP_node.h +++ b/source/blender/nodes/NOD_composite.h @@ -1,5 +1,5 @@ /* - * $Id$ + * $Id: CMP_node.h 36550 2011-05-08 16:08:08Z lukastoenne $ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -30,18 +30,24 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file CMP_node.h +/** \file NOD_composite.h * \ingroup nodes */ -#ifndef CMP_NODE_H -#define CMP_NODE_H +#ifndef NOD_composite_H +#define NOD_composite_H #include "BKE_node.h" +extern bNodeTreeType ntreeType_Composite; + /* ****************** types array for all composite nodes ****************** */ +void register_node_type_cmp_group(ListBase *lb); +void register_node_type_cmp_forloop(ListBase *lb); +void register_node_type_cmp_whileloop(ListBase *lb); + void register_node_type_cmp_rlayers(ListBase *lb); void register_node_type_cmp_image(ListBase *lb); void register_node_type_cmp_texture(ListBase *lb); diff --git a/source/blender/nodes/SHD_node.h b/source/blender/nodes/NOD_shader.h similarity index 88% rename from source/blender/nodes/SHD_node.h rename to source/blender/nodes/NOD_shader.h index 80e5eec6893..5bc0c381f0b 100644 --- a/source/blender/nodes/SHD_node.h +++ b/source/blender/nodes/NOD_shader.h @@ -1,5 +1,5 @@ /* - * $Id$ + * $Id: SHD_node.h 36550 2011-05-08 16:08:08Z lukastoenne $ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -30,19 +30,25 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file SHD_node.h +/** \file NOD_shader.h * \ingroup nodes */ -#ifndef SHD_NODE_H -#define SHD_NODE_H +#ifndef NOD_SHADER_H +#define NOD_SHADER_H #include "BKE_node.h" +extern struct bNodeTreeType ntreeType_Shader; + /* the type definitions array */ /* ****************** types array for all shaders ****************** */ +void register_node_type_sh_group(ListBase *lb); +void register_node_type_sh_forloop(ListBase *lb); +void register_node_type_sh_whileloop(ListBase *lb); + void register_node_type_sh_output(ListBase *lb); void register_node_type_sh_material(ListBase *lb); void register_node_type_sh_camera(ListBase *lb); diff --git a/source/blender/nodes/NOD_socket.h b/source/blender/nodes/NOD_socket.h new file mode 100644 index 00000000000..92e8a8e058d --- /dev/null +++ b/source/blender/nodes/NOD_socket.h @@ -0,0 +1,89 @@ +/** + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2007 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): Lukas Toenne + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file NOD_socket.h + * \ingroup nodes + */ + + +#ifndef NOD_SOCKET_H_ +#define NOD_SOCKET_H_ + +#include "DNA_listBase.h" + +#include "BLI_utildefines.h" + +#include "BKE_node.h" + +#include "RNA_types.h" + +struct bNodeTree; +struct bNode; +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 *nodeAddInputMesh(struct bNodeTree *ntree, struct bNode *node, const char *name); +struct bNodeSocket *nodeAddOutputMesh(struct bNodeTree *ntree, struct bNode *node, const char *name); + +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); + +void node_verify_socket_templates(struct bNodeTree *ntree, struct bNode *node); + + +/* Socket Converters */ + +#define SOCK_VECTOR_X 1 +#define SOCK_VECTOR_Y 2 +#define SOCK_VECTOR_Z 3 + +#define SOCK_RGBA_R 1 +#define SOCK_RGBA_G 2 +#define SOCK_RGBA_B 3 +#define SOCK_RGBA_A 4 + +#define SOCK_MESH_VERT_CO 1 +#define SOCK_MESH_VERT_NO 2 + +#endif diff --git a/source/blender/nodes/TEX_node.h b/source/blender/nodes/NOD_texture.h similarity index 90% rename from source/blender/nodes/TEX_node.h rename to source/blender/nodes/NOD_texture.h index 23a6b4427af..6f30685aff1 100644 --- a/source/blender/nodes/TEX_node.h +++ b/source/blender/nodes/NOD_texture.h @@ -1,5 +1,5 @@ /* - * $Id$ + * $Id: TEX_node.h 36550 2011-05-08 16:08:08Z lukastoenne $ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -30,18 +30,24 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file TEX_node.h +/** \file NOD_texture.h * \ingroup nodes */ -#ifndef TEX_NODE_H -#define TEX_NODE_H +#ifndef NOD_TEXTURE_H +#define NOD_TEXTURE_H #include "BKE_node.h" +extern bNodeTreeType ntreeType_Texture; + /* ****************** types array for all texture nodes ****************** */ +void register_node_type_tex_group(ListBase *lb); +void register_node_type_tex_forloop(ListBase *lb); +void register_node_type_tex_whileloop(ListBase *lb); + void register_node_type_tex_math(ListBase *lb); void register_node_type_tex_mix_rgb(ListBase *lb); void register_node_type_tex_valtorgb(ListBase *lb); diff --git a/source/blender/nodes/SConscript b/source/blender/nodes/SConscript index 8d17c6f5e16..0cbc7b80933 100644 --- a/source/blender/nodes/SConscript +++ b/source/blender/nodes/SConscript @@ -2,11 +2,11 @@ Import ('env') sources = env.Glob('intern/*.c') -cmpsources = env.Glob('intern/CMP_nodes/*.c') -shdsources = env.Glob('intern/SHD_nodes/*.c') -texsources = env.Glob('intern/TEX_nodes/*.c') - +cmpsources = env.Glob('composite/*.c') + env.Glob('composite/nodes/*.c') +shdsources = env.Glob('shader/*.c') + env.Glob('shader/nodes/*.c') +texsources = env.Glob('texture/*.c') + env.Glob('texture/nodes/*.c') incs = '. ./intern ' +incs += './composite ./shader ./texture ' incs += '#/intern/guardedalloc ../editors/include ../blenlib ../makesdna' incs += ' ../render/extern/include ../makesrna ' incs += ' ../imbuf ../avi ' diff --git a/source/blender/nodes/composite/node_composite_tree.c b/source/blender/nodes/composite/node_composite_tree.c new file mode 100644 index 00000000000..1a2fb04be8c --- /dev/null +++ b/source/blender/nodes/composite/node_composite_tree.c @@ -0,0 +1,811 @@ +/** + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2007 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/nodes/composite/node_composite_tree.c + * \ingroup nodes + */ + + +#include + +#include "DNA_anim_types.h" +#include "DNA_scene_types.h" +#include "DNA_node_types.h" + +#include "BLI_listbase.h" +#include "BLI_threads.h" + +#include "BKE_animsys.h" +#include "BKE_colortools.h" +#include "BKE_fcurve.h" +#include "BKE_global.h" +#include "BKE_main.h" +#include "BKE_node.h" +#include "BKE_utildefines.h" + +#include "node_exec.h" +#include "node_util.h" + +#include "PIL_time.h" + +#include "RNA_access.h" + +#include "NOD_composite.h" +#include "node_composite_util.h" + +static void foreach_nodetree(Main *main, void *calldata, bNodeTreeCallback func) +{ + Scene *sce; + for(sce= main->scene.first; sce; sce= sce->id.next) { + if(sce->nodetree) { + func(calldata, &sce->id, sce->nodetree); + } + } +} + +static void free_node_cache(bNodeTree *UNUSED(ntree), bNode *node) +{ + bNodeSocket *sock; + + for(sock= node->outputs.first; sock; sock= sock->next) { + if(sock->cache) { + free_compbuf(sock->cache); + sock->cache= NULL; + } + } +} + +static void free_cache(bNodeTree *ntree) +{ + bNode *node; + for(node= ntree->nodes.first; node; node= node->next) + free_node_cache(ntree, node); +} + +static void update_node(bNodeTree *ntree, bNode *node) +{ + bNodeSocket *sock; + + for(sock= node->outputs.first; sock; sock= sock->next) { + if(sock->cache) { + //free_compbuf(sock->cache); + //sock->cache= NULL; + } + } + node->need_exec= 1; + + /* individual node update call */ + if (node->typeinfo->updatefunc) + node->typeinfo->updatefunc(ntree, node); +} + +/* local tree then owns all compbufs */ +static void localize(bNodeTree *UNUSED(localtree), bNodeTree *ntree) +{ + bNode *node; + bNodeSocket *sock; + + for(node= ntree->nodes.first; node; node= node->next) { + /* ensure new user input gets handled ok */ + node->need_exec= 0; + + /* move over the compbufs */ + /* right after ntreeCopyTree() oldsock pointers are valid */ + + if(ELEM(node->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER)) { + if(node->id) { + if(node->flag & NODE_DO_OUTPUT) + node->new_node->id= (ID *)copy_image((Image *)node->id); + else + node->new_node->id= NULL; + } + } + + for(sock= node->outputs.first; sock; sock= sock->next) { + sock->new_sock->cache= sock->cache; + compbuf_set_node(sock->new_sock->cache, node->new_node); + + sock->cache= NULL; + sock->new_sock->new_sock= sock; + } + } +} + +static void local_sync(bNodeTree *localtree, bNodeTree *ntree) +{ + bNode *lnode; + + /* move over the compbufs and previews */ + for(lnode= localtree->nodes.first; lnode; lnode= lnode->next) { + if( (lnode->exec & NODE_READY) && !(lnode->exec & NODE_SKIPPED) ) { + if(ntreeNodeExists(ntree, lnode->new_node)) { + + if(lnode->preview && lnode->preview->rect) { + nodeFreePreview(lnode->new_node); + lnode->new_node->preview= lnode->preview; + lnode->preview= NULL; + } + } + } + } +} + +static void local_merge(bNodeTree *localtree, bNodeTree *ntree) +{ + bNode *lnode; + bNodeSocket *lsock; + + /* move over the compbufs and previews */ + for(lnode= localtree->nodes.first; lnode; lnode= lnode->next) { + if(ntreeNodeExists(ntree, lnode->new_node)) { + if(ELEM(lnode->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER)) { + if(lnode->id && (lnode->flag & NODE_DO_OUTPUT)) { + /* image_merge does sanity check for pointers */ + BKE_image_merge((Image *)lnode->new_node->id, (Image *)lnode->id); + } + } + + for(lsock= lnode->outputs.first; lsock; lsock= lsock->next) { + if(ntreeOutputExists(lnode->new_node, lsock->new_sock)) { + lsock->new_sock->cache= lsock->cache; + compbuf_set_node(lsock->new_sock->cache, lnode->new_node); + lsock->cache= NULL; + lsock->new_sock= NULL; + } + } + } + } +} + +bNodeTreeType ntreeType_Composite = { + /* type */ NTREE_COMPOSIT, + /* idname */ "NTCompositing Nodetree", + + /* node_types */ { NULL, NULL }, + + /* free_cache */ free_cache, + /* free_node_cache */ free_node_cache, + /* foreach_nodetree */ foreach_nodetree, + /* localize */ localize, + /* local_sync */ local_sync, + /* local_merge */ local_merge, + /* update */ NULL, + /* update_node */ update_node +}; + + +struct bNodeTreeExec *ntreeCompositBeginExecTree(bNodeTree *ntree) +{ + bNodeTreeExec *exec; + bNode *node; + bNodeSocket *sock; + + /* XXX hack: prevent exec data from being generated twice. + * this should be handled by the renderer! + */ + if (ntree->execdata) + return ntree->execdata; + + /* ensures only a single output node is enabled */ + ntreeSetOutput(ntree); + + exec = ntree_exec_begin(ntree); + + for(node= exec->nodetree->nodes.first; node; node= node->next) { + /* initialize needed for groups */ + node->exec= 0; + + for(sock= node->outputs.first; sock; sock= sock->next) { + bNodeStack *ns= node_get_socket_stack(exec->stack, sock); + if(ns && sock->cache) { + ns->data= sock->cache; + sock->cache= NULL; + } + } + /* cannot initialize them while using in threads */ + if(ELEM4(node->type, CMP_NODE_TIME, CMP_NODE_CURVE_VEC, CMP_NODE_CURVE_RGB, CMP_NODE_HUECORRECT)) { + curvemapping_initialize(node->storage); + if(node->type==CMP_NODE_CURVE_RGB) + curvemapping_premultiply(node->storage, 0); + } + } + + /* XXX this should not be necessary, but is still used for cmp/sha/tex nodes, + * which only store the ntree pointer. Should be fixed at some point! + */ + ntree->execdata = exec; + + return exec; +} + +void ntreeCompositEndExecTree(bNodeTreeExec *exec) +{ + if(exec) { + bNodeTree *ntree= exec->nodetree; + bNode *node; + bNodeStack *ns; + + for(node= exec->nodetree->nodes.first; node; node= node->next) { + bNodeSocket *sock; + + for(sock= node->outputs.first; sock; sock= sock->next) { + ns = node_get_socket_stack(exec->stack, sock); + if(ns && ns->data) { + sock->cache= ns->data; + ns->data= NULL; + } + } + if(node->type==CMP_NODE_CURVE_RGB) + curvemapping_premultiply(node->storage, 1); + + node->need_exec= 0; + } + + ntree_exec_end(exec); + + /* XXX clear nodetree backpointer to exec data, same problem as noted in ntreeBeginExecTree */ + ntree->execdata = NULL; + } +} + +/* ***************************** threaded version for execute composite nodes ************* */ +/* these are nodes without input, only giving values */ +/* or nodes with only value inputs */ +static int node_only_value(bNode *node) +{ + bNodeSocket *sock; + + if(ELEM3(node->type, CMP_NODE_TIME, CMP_NODE_VALUE, CMP_NODE_RGB)) + return 1; + + /* doing this for all node types goes wrong. memory free errors */ + if(node->inputs.first && node->type==CMP_NODE_MAP_VALUE) { + int retval= 1; + for(sock= node->inputs.first; sock; sock= sock->next) { + if(sock->link) + retval &= node_only_value(sock->link->fromnode); + } + return retval; + } + return 0; +} + +/* not changing info, for thread callback */ +typedef struct ThreadData { + bNodeStack *stack; + RenderData *rd; +} ThreadData; + +static void *exec_composite_node(void *nodeexec_v) +{ + bNodeStack *nsin[MAX_SOCKET]; /* arbitrary... watch this */ + bNodeStack *nsout[MAX_SOCKET]; /* arbitrary... watch this */ + bNodeExec *nodeexec= nodeexec_v; + bNode *node= nodeexec->node; + ThreadData *thd= (ThreadData *)node->threaddata; + + node_get_stack(node, thd->stack, nsin, nsout); + + if((node->flag & NODE_MUTED) && (!node_only_value(node))) { + /* viewers we execute, for feedback to user */ + if(ELEM(node->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER)) + node->typeinfo->execfunc(thd->rd, node, nsin, nsout); + else + node_compo_pass_on(node, nsin, nsout); + } + else if(node->typeinfo->execfunc) + node->typeinfo->execfunc(thd->rd, node, nsin, nsout); + else if (node->typeinfo->newexecfunc) + node->typeinfo->newexecfunc(thd->rd, 0, node, nodeexec->data, nsin, nsout); + + node->exec |= NODE_READY; + return 0; +} + +/* return total of executable nodes, for timecursor */ +static int setExecutableNodes(bNodeTree *ntree, ThreadData *thd) +{ + bNodeStack *nsin[MAX_SOCKET]; /* arbitrary... watch this */ + bNodeStack *nsout[MAX_SOCKET]; /* arbitrary... watch this */ + bNode *node; + bNodeSocket *sock; + int totnode= 0, group_edit= 0; + + /* note; do not add a dependency sort here, the stack was created already */ + + /* if we are in group edit, viewer nodes get skipped when group has viewer */ + for(node= ntree->nodes.first; node; node= node->next) + if(node->type==NODE_GROUP && (node->flag & NODE_GROUP_EDIT)) + if(ntreeHasType((bNodeTree *)node->id, CMP_NODE_VIEWER)) + group_edit= 1; + + for(node= ntree->nodes.first; node; node= node->next) { + int a; + + node_get_stack(node, thd->stack, nsin, nsout); + + /* test the outputs */ + /* skip value-only nodes (should be in type!) */ + if(!node_only_value(node)) { + for(a=0, sock= node->outputs.first; sock; sock= sock->next, a++) { + if(nsout[a]->data==NULL && nsout[a]->hasoutput) { + node->need_exec= 1; + break; + } + } + } + + /* test the inputs */ + for(a=0, sock= node->inputs.first; sock; sock= sock->next, a++) { + /* skip viewer nodes in bg render or group edit */ + if( ELEM(node->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER) && (G.background || group_edit)) + node->need_exec= 0; + /* is sock in use? */ + else if(sock->link) { + bNodeLink *link= sock->link; + + /* this is the test for a cyclic case */ + if(link->fromnode==NULL || link->tonode==NULL); + else if(link->fromnode->level >= link->tonode->level && link->tonode->level!=0xFFF) { + if(link->fromnode->need_exec) { + node->need_exec= 1; + break; + } + } + else { + node->need_exec= 0; + printf("Node %s skipped, cyclic dependency\n", node->name); + } + } + } + + if(node->need_exec) { + + /* free output buffers */ + for(a=0, sock= node->outputs.first; sock; sock= sock->next, a++) { + if(nsout[a]->data) { + free_compbuf(nsout[a]->data); + nsout[a]->data= NULL; + } + } + totnode++; + /* printf("node needs exec %s\n", node->name); */ + + /* tag for getExecutableNode() */ + node->exec= 0; + } + else { + /* tag for getExecutableNode() */ + node->exec= NODE_READY|NODE_FINISHED|NODE_SKIPPED; + + } + } + + /* last step: set the stack values for only-value nodes */ + /* just does all now, compared to a full buffer exec this is nothing */ + if(totnode) { + for(node= ntree->nodes.first; node; node= node->next) { + if(node->need_exec==0 && node_only_value(node)) { + if(node->typeinfo->execfunc) { + node_get_stack(node, thd->stack, nsin, nsout); + node->typeinfo->execfunc(thd->rd, node, nsin, nsout); + } + } + } + } + + return totnode; +} + +/* while executing tree, free buffers from nodes that are not needed anymore */ +static void freeExecutableNode(bNodeTree *ntree, bNodeTreeExec *exec) +{ + /* node outputs can be freed when: + - not a render result or image node + - when node outputs go to nodes all being set NODE_FINISHED + */ + bNode *node; + bNodeSocket *sock; + + /* set exec flag for finished nodes that might need freed */ + for(node= ntree->nodes.first; node; node= node->next) { + if(node->type!=CMP_NODE_R_LAYERS) + if(node->exec & NODE_FINISHED) + node->exec |= NODE_FREEBUFS; + } + /* clear this flag for input links that are not done yet */ + for(node= ntree->nodes.first; node; node= node->next) { + if((node->exec & NODE_FINISHED)==0) { + for(sock= node->inputs.first; sock; sock= sock->next) + if(sock->link) + sock->link->fromnode->exec &= ~NODE_FREEBUFS; + } + } + /* now we can free buffers */ + for(node= ntree->nodes.first; node; node= node->next) { + if(node->exec & NODE_FREEBUFS) { + for(sock= node->outputs.first; sock; sock= sock->next) { + bNodeStack *ns= node_get_socket_stack(exec->stack, sock); + if(ns && ns->data) { + free_compbuf(ns->data); + ns->data= NULL; + // printf("freed buf node %s \n", node->name); + } + } + } + } +} + +static bNodeExec *getExecutableNode(bNodeTreeExec *exec) +{ + bNodeExec *nodeexec; + bNodeSocket *sock; + int n; + + for(n=0, nodeexec=exec->nodeexec; n < exec->totnodes; ++n, ++nodeexec) { + if(nodeexec->node->exec==0) { + /* input sockets should be ready */ + for(sock= nodeexec->node->inputs.first; sock; sock= sock->next) { + if(sock->link && sock->link->fromnode) + if((sock->link->fromnode->exec & NODE_READY)==0) + break; + } + if(sock==NULL) + return nodeexec; + } + } + return NULL; +} + +/* check if texture nodes need exec or end */ +static void ntree_composite_texnode(bNodeTree *ntree, int init) +{ + bNode *node; + + for(node= ntree->nodes.first; node; node= node->next) { + if(node->type==CMP_NODE_TEXTURE && node->id) { + Tex *tex= (Tex *)node->id; + if(tex->nodetree && tex->use_nodes) { + /* has internal flag to detect it only does it once */ + if(init) { + if (!tex->nodetree->execdata) + tex->nodetree->execdata = ntreeTexBeginExecTree(tex->nodetree); + } + else + ntreeTexEndExecTree(tex->nodetree->execdata); + tex->nodetree->execdata = NULL; + } + } + } + +} + +/* optimized tree execute test for compositing */ +void ntreeCompositExecTree(bNodeTree *ntree, RenderData *rd, int do_preview) +{ + bNodeExec *nodeexec; + bNode *node; + ListBase threads; + ThreadData thdata; + int totnode, curnode, rendering= 1, n; + bNodeTreeExec *exec= NULL; + + if(ntree==NULL) return; + + if(do_preview) + ntreeInitPreview(ntree, 0, 0); + + if (!ntree->execdata) + exec = ntreeCompositBeginExecTree(ntree); + ntree_composite_texnode(ntree, 1); + + /* prevent unlucky accidents */ + if(G.background) + rd->scemode &= ~R_COMP_CROP; + + /* setup callerdata for thread callback */ + thdata.rd= rd; + thdata.stack= exec->stack; + + /* fixed seed, for example noise texture */ + BLI_srandom(rd->cfra); + + /* sets need_exec tags in nodes */ + curnode = totnode= setExecutableNodes(ntree, &thdata); + + BLI_init_threads(&threads, exec_composite_node, rd->threads); + + while(rendering) { + + if(BLI_available_threads(&threads)) { + nodeexec= getExecutableNode(exec); + if(nodeexec) { + node = nodeexec->node; + if(ntree->progress && totnode) + ntree->progress(ntree->prh, (1.0 - curnode/(float)totnode)); + if(ntree->stats_draw) { + char str[64]; + sprintf(str, "Compositing %d %s", curnode, node->name); + ntree->stats_draw(ntree->sdh, str); + } + curnode--; + + node->threaddata = &thdata; + node->exec= NODE_PROCESSING; + BLI_insert_thread(&threads, nodeexec); + } + else + PIL_sleep_ms(50); + } + else + PIL_sleep_ms(50); + + rendering= 0; + /* test for ESC */ + if(ntree->test_break && ntree->test_break(ntree->tbh)) { + for(node= ntree->nodes.first; node; node= node->next) + node->exec |= NODE_READY; + } + + /* check for ready ones, and if we need to continue */ + for(n=0, nodeexec=exec->nodeexec; n < exec->totnodes; ++n, ++nodeexec) { + node = nodeexec->node; + if(node->exec & NODE_READY) { + if((node->exec & NODE_FINISHED)==0) { + BLI_remove_thread(&threads, nodeexec); /* this waits for running thread to finish btw */ + node->exec |= NODE_FINISHED; + + /* freeing unused buffers */ + if(rd->scemode & R_COMP_FREE) + freeExecutableNode(ntree, exec); + } + } + else rendering= 1; + } + } + + BLI_end_threads(&threads); + + ntreeCompositEndExecTree(exec); +} + +/* *********************************************** */ + +/* clumsy checking... should do dynamic outputs once */ +static void force_hidden_passes(bNode *node, int passflag) +{ + bNodeSocket *sock; + + for(sock= node->outputs.first; sock; sock= sock->next) + sock->flag &= ~SOCK_UNAVAIL; + + sock= BLI_findlink(&node->outputs, RRES_OUT_Z); + if(!(passflag & SCE_PASS_Z)) sock->flag |= SOCK_UNAVAIL; + sock= BLI_findlink(&node->outputs, RRES_OUT_NORMAL); + if(!(passflag & SCE_PASS_NORMAL)) sock->flag |= SOCK_UNAVAIL; + sock= BLI_findlink(&node->outputs, RRES_OUT_VEC); + if(!(passflag & SCE_PASS_VECTOR)) sock->flag |= SOCK_UNAVAIL; + sock= BLI_findlink(&node->outputs, RRES_OUT_UV); + if(!(passflag & SCE_PASS_UV)) sock->flag |= SOCK_UNAVAIL; + sock= BLI_findlink(&node->outputs, RRES_OUT_RGBA); + if(!(passflag & SCE_PASS_RGBA)) sock->flag |= SOCK_UNAVAIL; + sock= BLI_findlink(&node->outputs, RRES_OUT_DIFF); + if(!(passflag & SCE_PASS_DIFFUSE)) sock->flag |= SOCK_UNAVAIL; + sock= BLI_findlink(&node->outputs, RRES_OUT_SPEC); + if(!(passflag & SCE_PASS_SPEC)) sock->flag |= SOCK_UNAVAIL; + sock= BLI_findlink(&node->outputs, RRES_OUT_SHADOW); + if(!(passflag & SCE_PASS_SHADOW)) sock->flag |= SOCK_UNAVAIL; + sock= BLI_findlink(&node->outputs, RRES_OUT_AO); + if(!(passflag & SCE_PASS_AO)) sock->flag |= SOCK_UNAVAIL; + sock= BLI_findlink(&node->outputs, RRES_OUT_REFLECT); + if(!(passflag & SCE_PASS_REFLECT)) sock->flag |= SOCK_UNAVAIL; + sock= BLI_findlink(&node->outputs, RRES_OUT_REFRACT); + if(!(passflag & SCE_PASS_REFRACT)) sock->flag |= SOCK_UNAVAIL; + sock= BLI_findlink(&node->outputs, RRES_OUT_INDIRECT); + if(!(passflag & SCE_PASS_INDIRECT)) sock->flag |= SOCK_UNAVAIL; + sock= BLI_findlink(&node->outputs, RRES_OUT_INDEXOB); + if(!(passflag & SCE_PASS_INDEXOB)) sock->flag |= SOCK_UNAVAIL; + sock= BLI_findlink(&node->outputs, RRES_OUT_INDEXMA); + if(!(passflag & SCE_PASS_INDEXMA)) sock->flag |= SOCK_UNAVAIL; + sock= BLI_findlink(&node->outputs, RRES_OUT_MIST); + if(!(passflag & SCE_PASS_MIST)) sock->flag |= SOCK_UNAVAIL; + sock= BLI_findlink(&node->outputs, RRES_OUT_EMIT); + if(!(passflag & SCE_PASS_EMIT)) sock->flag |= SOCK_UNAVAIL; + sock= BLI_findlink(&node->outputs, RRES_OUT_ENV); + if(!(passflag & SCE_PASS_ENVIRONMENT)) sock->flag |= SOCK_UNAVAIL; + +} + +/* based on rules, force sockets hidden always */ +void ntreeCompositForceHidden(bNodeTree *ntree, Scene *curscene) +{ + bNode *node; + + if(ntree==NULL) return; + + for(node= ntree->nodes.first; node; node= node->next) { + if( node->type==CMP_NODE_R_LAYERS) { + Scene *sce= node->id?(Scene *)node->id:curscene; + SceneRenderLayer *srl= BLI_findlink(&sce->r.layers, node->custom1); + if(srl) + force_hidden_passes(node, srl->passflag); + } + else if( node->type==CMP_NODE_IMAGE) { + Image *ima= (Image *)node->id; + if(ima) { + if(ima->rr) { + ImageUser *iuser= node->storage; + RenderLayer *rl= BLI_findlink(&ima->rr->layers, iuser->layer); + if(rl) + force_hidden_passes(node, rl->passflag); + else + force_hidden_passes(node, 0); + } + else if(ima->type!=IMA_TYPE_MULTILAYER) { /* if ->rr not yet read we keep inputs */ + force_hidden_passes(node, RRES_OUT_Z); + } + else + force_hidden_passes(node, 0); + } + else + force_hidden_passes(node, 0); + } + } + +} + +/* called from render pipeline, to tag render input and output */ +/* need to do all scenes, to prevent errors when you re-render 1 scene */ +void ntreeCompositTagRender(Scene *curscene) +{ + Scene *sce; + + for(sce= G.main->scene.first; sce; sce= sce->id.next) { + if(sce->nodetree) { + bNode *node; + + for(node= sce->nodetree->nodes.first; node; node= node->next) { + if(node->id==(ID *)curscene || node->type==CMP_NODE_COMPOSITE) + NodeTagChanged(sce->nodetree, node); + else if(node->type==CMP_NODE_TEXTURE) /* uses scene sizex/sizey */ + NodeTagChanged(sce->nodetree, node); + } + } + } +} + +static int node_animation_properties(bNodeTree *ntree, bNode *node) +{ + bNodeSocket *sock; + const ListBase *lb; + Link *link; + PointerRNA ptr; + PropertyRNA *prop; + + /* check to see if any of the node's properties have fcurves */ + RNA_pointer_create((ID *)ntree, &RNA_Node, node, &ptr); + lb = RNA_struct_type_properties(ptr.type); + + for (link=lb->first; link; link=link->next) { + int driven, len=1, index; + prop = (PropertyRNA *)link; + + if (RNA_property_array_check(prop)) + len = RNA_property_array_length(&ptr, prop); + + for (index=0; indexinputs.first; sock; sock=sock->next) { + int driven, len=1, index; + + RNA_pointer_create((ID *)ntree, &RNA_NodeSocket, sock, &ptr); + prop = RNA_struct_find_property(&ptr, "default_value"); + if (prop) { + if (RNA_property_array_check(prop)) + len = RNA_property_array_length(&ptr, prop); + + for (index=0; indexnodes.first; node; node= node->next) { + + tagged = node_animation_properties(ntree, node); + + /* otherwise always tag these node types */ + if(node->type==CMP_NODE_IMAGE) { + Image *ima= (Image *)node->id; + if(ima && ELEM(ima->source, IMA_SRC_MOVIE, IMA_SRC_SEQUENCE)) { + NodeTagChanged(ntree, node); + tagged= 1; + } + } + else if(node->type==CMP_NODE_TIME) { + NodeTagChanged(ntree, node); + tagged= 1; + } + /* here was tag render layer, but this is called after a render, so re-composites fail */ + else if(node->type==NODE_GROUP) { + if( ntreeCompositTagAnimated((bNodeTree *)node->id) ) { + NodeTagChanged(ntree, node); + } + } + } + + return tagged; +} + + +/* called from image window preview */ +void ntreeCompositTagGenerators(bNodeTree *ntree) +{ + bNode *node; + + if(ntree==NULL) return; + + for(node= ntree->nodes.first; node; node= node->next) { + if( ELEM(node->type, CMP_NODE_R_LAYERS, CMP_NODE_IMAGE)) + NodeTagChanged(ntree, node); + } +} + +/* XXX after render animation system gets a refresh, this call allows composite to end clean */ +void ntreeClearTags(bNodeTree *ntree) +{ + bNode *node; + + if(ntree==NULL) return; + + for(node= ntree->nodes.first; node; node= node->next) { + node->need_exec= 0; + if(node->type==NODE_GROUP) + ntreeClearTags((bNodeTree *)node->id); + } +} diff --git a/source/blender/nodes/intern/CMP_util.c b/source/blender/nodes/composite/node_composite_util.c similarity index 99% rename from source/blender/nodes/intern/CMP_util.c rename to source/blender/nodes/composite/node_composite_util.c index a763f34a644..f7759775af0 100644 --- a/source/blender/nodes/intern/CMP_util.c +++ b/source/blender/nodes/composite/node_composite_util.c @@ -1,5 +1,5 @@ /* - * $Id$ + * $Id: CMP_util.c 36536 2011-05-07 13:27:27Z lukastoenne $ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -27,12 +27,12 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/nodes/intern/CMP_util.c +/** \file blender/nodes/composite/node_composite_util.c * \ingroup nodes */ -#include "CMP_util.h" +#include "node_composite_util.h" CompBuf *alloc_compbuf(int sizex, int sizey, int type, int alloc) { @@ -67,7 +67,7 @@ CompBuf *dupalloc_compbuf(CompBuf *cbuf) { CompBuf *dupbuf= alloc_compbuf(cbuf->x, cbuf->y, cbuf->type, 1); if(dupbuf) { - memmove(dupbuf->rect, cbuf->rect, cbuf->type*sizeof(float)*cbuf->x*cbuf->y); + memcpy(dupbuf->rect, cbuf->rect, cbuf->type*sizeof(float)*cbuf->x*cbuf->y); dupbuf->xof= cbuf->xof; dupbuf->yof= cbuf->yof; @@ -156,7 +156,7 @@ void node_compo_pass_on(bNode *node, bNodeStack **nsin, bNodeStack **nsout) if(valbuf || colbuf || vecbuf) { for(a=0, sock= node->outputs.first; sock; sock= sock->next, a++) { if(nsout[a]->hasoutput) { - if(sock->type==SOCK_VALUE && valbuf) { + if(sock->type==SOCK_FLOAT && valbuf) { nsout[a]->data= pass_on_compbuf(valbuf); valbuf= NULL; } @@ -1325,7 +1325,7 @@ void IIR_gauss(CompBuf* src, float sigma, int chan, int xy) if (src->x < 3) xy &= ~(int) 1; if (src->y < 3) xy &= ~(int) 2; if (xy < 1) return; - + // see "Recursive Gabor Filtering" by Young/VanVliet // all factors here in double.prec. Required, because for single.prec it seems to blow up if sigma > ~200 if (sigma >= 3.556) diff --git a/source/blender/nodes/intern/CMP_util.h b/source/blender/nodes/composite/node_composite_util.h similarity index 97% rename from source/blender/nodes/intern/CMP_util.h rename to source/blender/nodes/composite/node_composite_util.h index 3f37eae2af9..e3158b2a286 100644 --- a/source/blender/nodes/intern/CMP_util.h +++ b/source/blender/nodes/composite/node_composite_util.h @@ -1,5 +1,5 @@ /* - * $Id$ + * $Id: CMP_util.h 35562 2011-03-15 20:10:32Z lukastoenne $ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -27,13 +27,13 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/nodes/intern/CMP_util.h +/** \file blender/nodes/composite/node_composite_util.h * \ingroup nodes */ -#ifndef CMP_NODE_UTILS_H_ -#define CMP_NODE_UTILS_H_ +#ifndef NODE_COMPOSITE_UTIL_H_ +#define NODE_COMPOSITE_UTIL_H_ #include #include @@ -70,7 +70,6 @@ #include "BKE_library.h" #include "BKE_object.h" -#include "../CMP_node.h" #include "node_util.h" #include "IMB_imbuf_types.h" diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_alphaOver.c b/source/blender/nodes/composite/nodes/node_composite_alphaOver.c similarity index 86% rename from source/blender/nodes/intern/CMP_nodes/CMP_alphaOver.c rename to source/blender/nodes/composite/nodes/node_composite_alphaOver.c index 9dcdfaf21e6..400bdd92b6f 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_alphaOver.c +++ b/source/blender/nodes/composite/nodes/node_composite_alphaOver.c @@ -1,5 +1,5 @@ /* - * $Id$ + * $Id: CMP_alphaOver.c 36593 2011-05-10 11:19:26Z lukastoenne $ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -27,22 +27,22 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/nodes/intern/CMP_nodes/CMP_alphaOver.c +/** \file blender/nodes/composite/nodes/node_composite_alphaOver.c * \ingroup cmpnodes */ -#include "../CMP_util.h" +#include "node_composite_util.h" /* **************** ALPHAOVER ******************** */ -static bNodeSocketType cmp_node_alphaover_in[]= { - { SOCK_VALUE, 1, "Fac", 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f}, - { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, - { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate cmp_node_alphaover_in[]= { + { SOCK_FLOAT, 1, "Fac", 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, PROP_FACTOR}, + { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f}, + { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f}, { -1, 0, "" } }; -static bNodeSocketType cmp_node_alphaover_out[]= { - { SOCK_RGBA, 0, "Image", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate cmp_node_alphaover_out[]= { + { SOCK_RGBA, 0, "Image"}, { -1, 0, "" } }; @@ -140,7 +140,7 @@ static void node_composit_exec_alphaover(void *UNUSED(data), bNode *node, bNodeS } } -static void node_alphaover_init(bNode* node) +static void node_alphaover_init(bNodeTree *UNUSED(ntree), bNode* node, bNodeTemplate *UNUSED(ntemp)) { node->storage= MEM_callocN(sizeof(NodeTwoFloats), "NodeTwoFloats"); } @@ -149,8 +149,8 @@ void register_node_type_cmp_alphaover(ListBase *lb) { static bNodeType ntype; - node_type_base(&ntype, CMP_NODE_ALPHAOVER, "AlphaOver", NODE_CLASS_OP_COLOR, NODE_OPTIONS, - cmp_node_alphaover_in, cmp_node_alphaover_out); + node_type_base(&ntype, CMP_NODE_ALPHAOVER, "AlphaOver", NODE_CLASS_OP_COLOR, NODE_OPTIONS); + node_type_socket_templates(&ntype, cmp_node_alphaover_in, cmp_node_alphaover_out); node_type_size(&ntype, 80, 40, 120); node_type_init(&ntype, node_alphaover_init); node_type_storage(&ntype, "NodeTwoFloats", node_free_standard_storage, node_copy_standard_storage); diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_bilateralblur.c b/source/blender/nodes/composite/nodes/node_composite_bilateralblur.c similarity index 91% rename from source/blender/nodes/intern/CMP_nodes/CMP_bilateralblur.c rename to source/blender/nodes/composite/nodes/node_composite_bilateralblur.c index c106b437e17..e7a9ee12ca1 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_bilateralblur.c +++ b/source/blender/nodes/composite/nodes/node_composite_bilateralblur.c @@ -27,21 +27,21 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/nodes/intern/CMP_nodes/CMP_bilateralblur.c +/** \file blender/nodes/composite/nodes/node_composite_bilateralblur.c * \ingroup cmpnodes */ -#include "../CMP_util.h" +#include "node_composite_util.h" /* **************** BILATERALBLUR ******************** */ -static bNodeSocketType cmp_node_bilateralblur_in[]= { - { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, - { SOCK_RGBA, 1, "Determinator", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate cmp_node_bilateralblur_in[]= { + { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f}, + { SOCK_RGBA, 1, "Determinator", 0.8f, 0.8f, 0.8f, 1.0f}, { -1, 0, "" } }; -static bNodeSocketType cmp_node_bilateralblur_out[]= { - { SOCK_RGBA, 0, "Image", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate cmp_node_bilateralblur_out[]= { + { SOCK_RGBA, 0, "Image"}, { -1, 0, "" } }; @@ -247,7 +247,7 @@ static void node_composit_exec_bilateralblur(void *UNUSED(data), bNode *node, bN free_compbuf(new); } -static void node_composit_init_bilateralblur(bNode* node) +static void node_composit_init_bilateralblur(bNodeTree *UNUSED(ntree), bNode* node, bNodeTemplate *UNUSED(ntemp)) { NodeBilateralBlurData *nbbd= MEM_callocN(sizeof(NodeBilateralBlurData), "node bilateral blur data"); node->storage= nbbd; @@ -259,8 +259,8 @@ void register_node_type_cmp_bilateralblur(ListBase *lb) { static bNodeType ntype; - node_type_base(&ntype, CMP_NODE_BILATERALBLUR, "Bilateral Blur", NODE_CLASS_OP_FILTER, NODE_OPTIONS, - cmp_node_bilateralblur_in, cmp_node_bilateralblur_out); + node_type_base(&ntype, CMP_NODE_BILATERALBLUR, "Bilateral Blur", NODE_CLASS_OP_FILTER, NODE_OPTIONS); + node_type_socket_templates(&ntype, cmp_node_bilateralblur_in, cmp_node_bilateralblur_out); node_type_size(&ntype, 150, 120, 200); node_type_init(&ntype, node_composit_init_bilateralblur); node_type_storage(&ntype, "NodeBilateralBlurData", node_free_standard_storage, node_copy_standard_storage); diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_blur.c b/source/blender/nodes/composite/nodes/node_composite_blur.c similarity index 96% rename from source/blender/nodes/intern/CMP_nodes/CMP_blur.c rename to source/blender/nodes/composite/nodes/node_composite_blur.c index 718578a921b..7b1a9623845 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_blur.c +++ b/source/blender/nodes/composite/nodes/node_composite_blur.c @@ -1,5 +1,5 @@ /* - * $Id$ + * $Id: CMP_blur.c 36593 2011-05-10 11:19:26Z lukastoenne $ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -28,21 +28,21 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/nodes/intern/CMP_nodes/CMP_blur.c +/** \file blender/nodes/composite/nodes/node_composite_blur.c * \ingroup cmpnodes */ -#include "../CMP_util.h" +#include "node_composite_util.h" /* **************** BLUR ******************** */ -static bNodeSocketType cmp_node_blur_in[]= { - { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, - { SOCK_VALUE, 1, "Size", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate cmp_node_blur_in[]= { + { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f}, + { SOCK_FLOAT, 1, "Size", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR}, { -1, 0, "" } }; -static bNodeSocketType cmp_node_blur_out[]= { - { SOCK_RGBA, 0, "Image", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate cmp_node_blur_out[]= { + { SOCK_RGBA, 0, "Image"}, { -1, 0, "" } }; @@ -713,7 +713,7 @@ static void node_composit_exec_blur(void *data, bNode *node, bNodeStack **in, bN generate_preview(data, node, out[0]->data); } -static void node_composit_init_blur(bNode* node) +static void node_composit_init_blur(bNodeTree *UNUSED(ntree), bNode* node, bNodeTemplate *UNUSED(ntemp)) { node->storage= MEM_callocN(sizeof(NodeBlurData), "node blur data"); } @@ -722,8 +722,8 @@ void register_node_type_cmp_blur(ListBase *lb) { static bNodeType ntype; - node_type_base(&ntype, CMP_NODE_BLUR, "Blur", NODE_CLASS_OP_FILTER, NODE_PREVIEW|NODE_OPTIONS, - cmp_node_blur_in, cmp_node_blur_out); + node_type_base(&ntype, CMP_NODE_BLUR, "Blur", NODE_CLASS_OP_FILTER, NODE_PREVIEW|NODE_OPTIONS); + node_type_socket_templates(&ntype, cmp_node_blur_in, cmp_node_blur_out); node_type_size(&ntype, 120, 80, 200); node_type_init(&ntype, node_composit_init_blur); node_type_storage(&ntype, "NodeBlurData", node_free_standard_storage, node_copy_standard_storage); diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_brightness.c b/source/blender/nodes/composite/nodes/node_composite_brightness.c similarity index 79% rename from source/blender/nodes/intern/CMP_nodes/CMP_brightness.c rename to source/blender/nodes/composite/nodes/node_composite_brightness.c index 50a8d05b03d..1a5cf956a52 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_brightness.c +++ b/source/blender/nodes/composite/nodes/node_composite_brightness.c @@ -1,5 +1,5 @@ /* -* $Id$ +* $Id: CMP_brightness.c 36593 2011-05-10 11:19:26Z lukastoenne $ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -28,24 +28,24 @@ */ -/** \file blender/nodes/intern/CMP_nodes/CMP_brightness.c +/** \file blender/nodes/composite/nodes/node_composite_brightness.c * \ingroup cmpnodes */ -#include "../CMP_util.h" +#include "node_composite_util.h" /* **************** Brigh and contrsast ******************** */ -static bNodeSocketType cmp_node_brightcontrast_in[]= { - { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, - { SOCK_VALUE, 1, "Bright", 0.0f, 0.0f, 0.0f, 0.0f, -100.0f, 100.0f}, - { SOCK_VALUE, 1, "Contrast", 0.0f, 0.0f, 0.0f, 0.0f, -100.0f, 100.0f}, +static bNodeSocketTemplate cmp_node_brightcontrast_in[]= { + { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f}, + { SOCK_FLOAT, 1, "Bright", 0.0f, 0.0f, 0.0f, 0.0f, -100.0f, 100.0f, PROP_NONE}, + { SOCK_FLOAT, 1, "Contrast", 0.0f, 0.0f, 0.0f, 0.0f, -100.0f, 100.0f, PROP_NONE}, { -1, 0, "" } }; -static bNodeSocketType cmp_node_brightcontrast_out[]= { - { SOCK_RGBA, 0, "Image", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate cmp_node_brightcontrast_out[]= { + { SOCK_RGBA, 0, "Image"}, { -1, 0, "" } }; @@ -100,8 +100,8 @@ void register_node_type_cmp_brightcontrast(ListBase *lb) { static bNodeType ntype; - node_type_base(&ntype, CMP_NODE_BRIGHTCONTRAST, "Bright/Contrast", NODE_CLASS_OP_COLOR, NODE_OPTIONS, - cmp_node_brightcontrast_in, cmp_node_brightcontrast_out); + node_type_base(&ntype, CMP_NODE_BRIGHTCONTRAST, "Bright/Contrast", NODE_CLASS_OP_COLOR, NODE_OPTIONS); + node_type_socket_templates(&ntype, cmp_node_brightcontrast_in, cmp_node_brightcontrast_out); node_type_size(&ntype, 140, 100, 320); node_type_exec(&ntype, node_composit_exec_brightcontrast); diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_channelMatte.c b/source/blender/nodes/composite/nodes/node_composite_channelMatte.c similarity index 89% rename from source/blender/nodes/intern/CMP_nodes/CMP_channelMatte.c rename to source/blender/nodes/composite/nodes/node_composite_channelMatte.c index e395716f36d..afdbe82aebc 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_channelMatte.c +++ b/source/blender/nodes/composite/nodes/node_composite_channelMatte.c @@ -1,5 +1,5 @@ /* - * $Id$ + * $Id: CMP_channelMatte.c 36536 2011-05-07 13:27:27Z lukastoenne $ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -27,23 +27,23 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/nodes/intern/CMP_nodes/CMP_channelMatte.c +/** \file blender/nodes/composite/nodes/node_composite_channelMatte.c * \ingroup cmpnodes */ -#include "../CMP_util.h" +#include "node_composite_util.h" /* ******************* Channel Matte Node ********************************* */ -static bNodeSocketType cmp_node_channel_matte_in[]={ - {SOCK_RGBA,1,"Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate cmp_node_channel_matte_in[]={ + {SOCK_RGBA,1,"Image", 0.8f, 0.8f, 0.8f, 1.0f}, {-1,0,""} }; -static bNodeSocketType cmp_node_channel_matte_out[]={ - {SOCK_RGBA,0,"Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, - {SOCK_VALUE,0,"Matte",0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate cmp_node_channel_matte_out[]={ + {SOCK_RGBA,0,"Image"}, + {SOCK_FLOAT,0,"Matte"}, {-1,0,""} }; @@ -187,7 +187,7 @@ static void node_composit_exec_channel_matte(void *data, bNode *node, bNodeStack } -static void node_composit_init_channel_matte(bNode *node) +static void node_composit_init_channel_matte(bNodeTree *UNUSED(ntree), bNode* node, bNodeTemplate *UNUSED(ntemp)) { NodeChroma *c= MEM_callocN(sizeof(NodeChroma), "node chroma"); node->storage=c; @@ -206,8 +206,8 @@ void register_node_type_cmp_channel_matte(ListBase *lb) { static bNodeType ntype; - node_type_base(&ntype, CMP_NODE_CHANNEL_MATTE, "Channel Key", NODE_CLASS_MATTE, NODE_PREVIEW|NODE_OPTIONS, - cmp_node_channel_matte_in, cmp_node_channel_matte_out); + node_type_base(&ntype, CMP_NODE_CHANNEL_MATTE, "Channel Key", NODE_CLASS_MATTE, NODE_PREVIEW|NODE_OPTIONS); + node_type_socket_templates(&ntype, cmp_node_channel_matte_in, cmp_node_channel_matte_out); node_type_size(&ntype, 200, 80, 250); node_type_init(&ntype, node_composit_init_channel_matte); node_type_storage(&ntype, "NodeChroma", node_free_standard_storage, node_copy_standard_storage); diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_chromaMatte.c b/source/blender/nodes/composite/nodes/node_composite_chromaMatte.c similarity index 88% rename from source/blender/nodes/intern/CMP_nodes/CMP_chromaMatte.c rename to source/blender/nodes/composite/nodes/node_composite_chromaMatte.c index 03230f2e212..db5e6d93856 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_chromaMatte.c +++ b/source/blender/nodes/composite/nodes/node_composite_chromaMatte.c @@ -1,5 +1,5 @@ /* - * $Id$ + * $Id: CMP_chromaMatte.c 36536 2011-05-07 13:27:27Z lukastoenne $ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -27,23 +27,23 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/nodes/intern/CMP_nodes/CMP_chromaMatte.c +/** \file blender/nodes/composite/nodes/node_composite_chromaMatte.c * \ingroup cmpnodes */ -#include "../CMP_util.h" +#include "node_composite_util.h" /* ******************* Chroma Key ********************************************************** */ -static bNodeSocketType cmp_node_chroma_in[]={ - {SOCK_RGBA,1,"Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, - {SOCK_RGBA,1,"Key Color", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate cmp_node_chroma_in[]={ + {SOCK_RGBA,1,"Image", 0.8f, 0.8f, 0.8f, 1.0f}, + {SOCK_RGBA,1,"Key Color", 0.8f, 0.8f, 0.8f, 1.0f}, {-1,0,""} }; -static bNodeSocketType cmp_node_chroma_out[]={ - {SOCK_RGBA,0,"Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, - {SOCK_VALUE,0,"Matte",0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate cmp_node_chroma_out[]={ + {SOCK_RGBA,0,"Image"}, + {SOCK_FLOAT,0,"Matte"}, {-1,0,""} }; @@ -178,7 +178,7 @@ static void node_composit_exec_chroma_matte(void *data, bNode *node, bNodeStack } -static void node_composit_init_chroma_matte(bNode *node) +static void node_composit_init_chroma_matte(bNodeTree *UNUSED(ntree), bNode* node, bNodeTemplate *UNUSED(ntemp)) { NodeChroma *c= MEM_callocN(sizeof(NodeChroma), "node chroma"); node->storage= c; @@ -193,8 +193,8 @@ void register_node_type_cmp_chroma_matte(ListBase *lb) { static bNodeType ntype; - node_type_base(&ntype, CMP_NODE_CHROMA_MATTE, "Chroma Key", NODE_CLASS_MATTE, NODE_PREVIEW|NODE_OPTIONS, - cmp_node_chroma_in, cmp_node_chroma_out); + node_type_base(&ntype, CMP_NODE_CHROMA_MATTE, "Chroma Key", NODE_CLASS_MATTE, NODE_PREVIEW|NODE_OPTIONS); + node_type_socket_templates(&ntype, cmp_node_chroma_in, cmp_node_chroma_out); node_type_size(&ntype, 200, 80, 300); node_type_init(&ntype, node_composit_init_chroma_matte); node_type_storage(&ntype, "NodeChroma", node_free_standard_storage, node_copy_standard_storage); diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_colorMatte.c b/source/blender/nodes/composite/nodes/node_composite_colorMatte.c similarity index 84% rename from source/blender/nodes/intern/CMP_nodes/CMP_colorMatte.c rename to source/blender/nodes/composite/nodes/node_composite_colorMatte.c index 55d77a902b9..7f687240daf 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_colorMatte.c +++ b/source/blender/nodes/composite/nodes/node_composite_colorMatte.c @@ -1,5 +1,5 @@ /* - * $Id$ + * $Id: CMP_colorMatte.c 36536 2011-05-07 13:27:27Z lukastoenne $ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -27,23 +27,23 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/nodes/intern/CMP_nodes/CMP_colorMatte.c +/** \file blender/nodes/composite/nodes/node_composite_colorMatte.c * \ingroup cmpnodes */ -#include "../CMP_util.h" +#include "node_composite_util.h" /* ******************* Color Key ********************************************************** */ -static bNodeSocketType cmp_node_color_in[]={ - {SOCK_RGBA,1,"Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, - {SOCK_RGBA,1,"Key Color", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate cmp_node_color_in[]={ + {SOCK_RGBA,1,"Image", 0.8f, 0.8f, 0.8f, 1.0f}, + {SOCK_RGBA,1,"Key Color", 0.8f, 0.8f, 0.8f, 1.0f}, {-1,0,""} }; -static bNodeSocketType cmp_node_color_out[]={ - {SOCK_RGBA,0,"Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, - {SOCK_VALUE,0,"Matte",0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate cmp_node_color_out[]={ + {SOCK_RGBA,0,"Image"}, + {SOCK_FLOAT,0,"Matte"}, {-1,0,""} }; @@ -114,7 +114,7 @@ static void node_composit_exec_color_matte(void *data, bNode *node, bNodeStack * free_compbuf(cbuf); } -static void node_composit_init_color_matte(bNode *node) +static void node_composit_init_color_matte(bNodeTree *UNUSED(ntree), bNode* node, bNodeTemplate *UNUSED(ntemp)) { NodeChroma *c= MEM_callocN(sizeof(NodeChroma), "node color"); node->storage= c; @@ -129,8 +129,8 @@ void register_node_type_cmp_color_matte(ListBase *lb) { static bNodeType ntype; - node_type_base(&ntype, CMP_NODE_COLOR_MATTE, "Color Key", NODE_CLASS_MATTE, NODE_PREVIEW|NODE_OPTIONS, - cmp_node_color_in, cmp_node_color_out); + node_type_base(&ntype, CMP_NODE_COLOR_MATTE, "Color Key", NODE_CLASS_MATTE, NODE_PREVIEW|NODE_OPTIONS); + node_type_socket_templates(&ntype, cmp_node_color_in, cmp_node_color_out); node_type_size(&ntype, 200, 80, 300); node_type_init(&ntype, node_composit_init_color_matte); node_type_storage(&ntype, "NodeChroma", node_free_standard_storage, node_copy_standard_storage); diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_colorSpill.c b/source/blender/nodes/composite/nodes/node_composite_colorSpill.c similarity index 93% rename from source/blender/nodes/intern/CMP_nodes/CMP_colorSpill.c rename to source/blender/nodes/composite/nodes/node_composite_colorSpill.c index 905d97709c3..18b6d806c82 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_colorSpill.c +++ b/source/blender/nodes/composite/nodes/node_composite_colorSpill.c @@ -1,5 +1,5 @@ /* - * $Id$ + * $Id: CMP_colorSpill.c 36593 2011-05-10 11:19:26Z lukastoenne $ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -27,25 +27,25 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/nodes/intern/CMP_nodes/CMP_colorSpill.c +/** \file blender/nodes/composite/nodes/node_composite_colorSpill.c * \ingroup cmpnodes */ -#include "../CMP_util.h" +#include "node_composite_util.h" #define avg(a,b) ((a+b)/2) /* ******************* Color Spill Supression ********************************* */ -static bNodeSocketType cmp_node_color_spill_in[]={ - {SOCK_RGBA,1,"Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, - {SOCK_VALUE, 1, "Fac", 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate cmp_node_color_spill_in[]={ + {SOCK_RGBA,1,"Image", 0.8f, 0.8f, 0.8f, 1.0f}, + {SOCK_FLOAT, 1, "Fac", 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, PROP_FACTOR}, {-1,0,""} }; -static bNodeSocketType cmp_node_color_spill_out[]={ - {SOCK_RGBA,0,"Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate cmp_node_color_spill_out[]={ + {SOCK_RGBA,0,"Image"}, {-1,0,""} }; @@ -315,7 +315,7 @@ static void node_composit_exec_color_spill(void *UNUSED(data), bNode *node, bNod free_compbuf(spillmap); } -static void node_composit_init_color_spill(bNode *node) +static void node_composit_init_color_spill(bNodeTree *UNUSED(ntree), bNode* node, bNodeTemplate *UNUSED(ntemp)) { NodeColorspill *ncs= MEM_callocN(sizeof(NodeColorspill), "node colorspill"); node->storage=ncs; @@ -330,8 +330,8 @@ void register_node_type_cmp_color_spill(ListBase *lb) { static bNodeType ntype; - node_type_base(&ntype, CMP_NODE_COLOR_SPILL, "Color Spill", NODE_CLASS_MATTE, NODE_OPTIONS, - cmp_node_color_spill_in, cmp_node_color_spill_out); + node_type_base(&ntype, CMP_NODE_COLOR_SPILL, "Color Spill", NODE_CLASS_MATTE, NODE_OPTIONS); + node_type_socket_templates(&ntype, cmp_node_color_spill_in, cmp_node_color_spill_out); node_type_size(&ntype, 140, 80, 200); node_type_init(&ntype, node_composit_init_color_spill); node_type_storage(&ntype, "NodeColorspill", node_free_standard_storage, node_copy_standard_storage); diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_colorbalance.c b/source/blender/nodes/composite/nodes/node_composite_colorbalance.c similarity index 91% rename from source/blender/nodes/intern/CMP_nodes/CMP_colorbalance.c rename to source/blender/nodes/composite/nodes/node_composite_colorbalance.c index 4074ea2fa29..7ebceb5c206 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_colorbalance.c +++ b/source/blender/nodes/composite/nodes/node_composite_colorbalance.c @@ -27,24 +27,24 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/nodes/intern/CMP_nodes/CMP_colorbalance.c +/** \file blender/nodes/composite/nodes/node_composite_colorbalance.c * \ingroup cmpnodes */ -#include "../CMP_util.h" +#include "node_composite_util.h" /* ******************* Color Balance ********************************* */ -static bNodeSocketType cmp_node_colorbalance_in[]={ - {SOCK_VALUE, 1, "Fac", 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, - {SOCK_RGBA,1,"Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate cmp_node_colorbalance_in[]={ + {SOCK_FLOAT, 1, "Fac", 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, PROP_FACTOR}, + {SOCK_RGBA,1,"Image", 0.8f, 0.8f, 0.8f, 1.0f}, {-1,0,""} }; -static bNodeSocketType cmp_node_colorbalance_out[]={ - {SOCK_RGBA,0,"Image", 0.0f, 0.0f, 1.0f, 1.0f, -1.0f, 1.0f}, +static bNodeSocketTemplate cmp_node_colorbalance_out[]={ + {SOCK_RGBA,0,"Image"}, {-1,0,""} }; @@ -175,7 +175,7 @@ static void node_composit_exec_colorbalance(void *UNUSED(data), bNode *node, bNo } } -static void node_composit_init_colorbalance(bNode *node) +static void node_composit_init_colorbalance(bNodeTree *UNUSED(ntree), bNode* node, bNodeTemplate *UNUSED(ntemp)) { NodeColorBalance *n= node->storage= MEM_callocN(sizeof(NodeColorBalance), "node colorbalance"); @@ -188,8 +188,8 @@ void register_node_type_cmp_colorbalance(ListBase *lb) { static bNodeType ntype; - node_type_base(&ntype, CMP_NODE_COLORBALANCE, "Color Balance", NODE_CLASS_OP_COLOR, NODE_OPTIONS, - cmp_node_colorbalance_in, cmp_node_colorbalance_out); + node_type_base(&ntype, CMP_NODE_COLORBALANCE, "Color Balance", NODE_CLASS_OP_COLOR, NODE_OPTIONS); + node_type_socket_templates(&ntype, cmp_node_colorbalance_in, cmp_node_colorbalance_out); node_type_size(&ntype, 400, 200, 400); node_type_init(&ntype, node_composit_init_colorbalance); node_type_storage(&ntype, "NodeColorBalance", node_free_standard_storage, node_copy_standard_storage); diff --git a/source/blender/nodes/composite/nodes/node_composite_common.c b/source/blender/nodes/composite/nodes/node_composite_common.c new file mode 100644 index 00000000000..ab8cf663ef2 --- /dev/null +++ b/source/blender/nodes/composite/nodes/node_composite_common.c @@ -0,0 +1,373 @@ +/* + * $Id: CMP_blur.c 35562 2011-03-15 20:10:32Z lukastoenne $ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2006 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): Campbell Barton, Alfredo de Greef, David Millan Escriva, + * Juho Vepsäläinen + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/nodes/composite/nodes/node_composite_common.c + * \ingroup cmpnodes + */ + + +#include "DNA_node_types.h" + +#include "BKE_node.h" + +#include "node_composite_util.h" +#include "node_common.h" +#include "node_exec.h" + +#if 0 +static void PRINT_BUFFERS(bNodeTreeExec *exec) +{ + bNodeTree *ntree= exec->nodetree; + bNode *node; + bNodeSocket *sock; + bNodeStack *ns; + int i; + + printf("-------------- DEBUG --------------\n"); + for (sock=ntree->inputs.first, i=0; sock; sock=sock->next, ++i) { + ns = node_get_socket_stack(exec->stack, sock); + printf("%d. Tree Input %s", i, sock->name); + if (ns->external) + printf(" (external)"); + printf(": data=%p\n", ns->data); + } + for (sock=ntree->outputs.first, i=0; sock; sock=sock->next, ++i) { + ns = node_get_socket_stack(exec->stack, sock); + printf("%d. Tree Output %s", i, sock->name); + if (ns->external) + printf(" (external)"); + printf(": data=%p\n", ns->data); + } + for (node=ntree->nodes.first; node; node=node->next) { + printf("Node %s:\n", node->name); + for (sock=node->inputs.first, i=0; sock; sock=sock->next, ++i) { + ns = node_get_socket_stack(exec->stack, sock); + printf("\t%d. Input %s", i, sock->name); + if (ns->external) + printf(" (external)"); + printf(": data=%p\n", ns->data); + } + for (sock=node->outputs.first, i=0; sock; sock=sock->next, ++i) { + ns = node_get_socket_stack(exec->stack, sock); + printf("\t%d. Output %s", i, sock->name); + if (ns->external) + printf(" (external)"); + printf(": data=%p\n", ns->data); + } + } +} +#endif + +static void copy_stack(bNodeStack *to, bNodeStack *from) +{ + if (to != from) { + copy_v4_v4(to->vec, from->vec); + to->data = from->data; + to->datatype = from->datatype; + + /* tag as copy to prevent freeing */ + to->is_copy = 1; + } +} + +static void move_stack(bNodeStack *to, bNodeStack *from) +{ + if (to != from) { + copy_v4_v4(to->vec, from->vec); + to->data = from->data; + to->datatype = from->datatype; + to->is_copy = from->is_copy; + + zero_v4(from->vec); + from->data = NULL; + from->datatype = 0; + from->is_copy = 0; + } +} + +/**** GROUP ****/ + +static void *group_initexec(bNode *node) +{ + bNodeTree *ngroup= (bNodeTree*)node->id; + bNodeTreeExec *exec; + bNodeSocket *sock; + bNodeStack *ns; + + /* initialize the internal node tree execution */ + exec = ntreeCompositBeginExecTree(ngroup); + + /* tag group outputs as external to prevent freeing */ + for (sock=ngroup->outputs.first; sock; sock=sock->next) { + if (!(sock->flag & SOCK_INTERNAL)) { + ns = node_get_socket_stack(exec->stack, sock); + ns->external = 1; + } + } + + return exec; +} + +static void group_freeexec(bNode *UNUSED(node), void *nodedata) +{ + bNodeTreeExec *gexec= (bNodeTreeExec*)nodedata; + + ntreeCompositEndExecTree(gexec); +} + +/* Copy inputs to the internal stack. + * This is a shallow copy, no buffers are duplicated here! + */ +static void group_copy_inputs(bNode *node, bNodeStack **in, bNodeStack *gstack) +{ + bNodeSocket *sock; + bNodeStack *ns; + int a; + for (sock=node->inputs.first, a=0; sock; sock=sock->next, ++a) { + if (sock->groupsock) { + ns = node_get_socket_stack(gstack, sock->groupsock); + copy_stack(ns, in[a]); + } + } +} + +/* Copy internal results to the external outputs. + */ +static void group_move_outputs(bNode *node, bNodeStack **out, bNodeStack *gstack) +{ + bNodeSocket *sock; + bNodeStack *ns; + int a; + for (sock=node->outputs.first, a=0; sock; sock=sock->next, ++a) { + if (sock->groupsock) { + ns = node_get_socket_stack(gstack, sock->groupsock); + move_stack(out[a], ns); + } + } +} + +/* Free internal buffers */ +static void group_free_internal(bNodeTreeExec *gexec) { + bNodeStack *ns; + int i; + + for (i=0, ns=gexec->stack; i < gexec->stacksize; ++i, ++ns) { + if (!ns->external && !ns->is_copy) { + if (ns->data) { + free_compbuf(ns->data); + ns->data = NULL; + } + } + } +} + +static void group_execute(void *data, int thread, struct bNode *node, void *nodedata, struct bNodeStack **in, struct bNodeStack **out) +{ + bNodeTreeExec *exec= (bNodeTreeExec*)nodedata; + + /* XXX same behavior as trunk: all nodes inside group are executed. + * it's stupid, but just makes it work. compo redesign will do this better. + */ + { + bNode *inode; + for (inode=exec->nodetree->nodes.first; inode; inode=inode->next) + inode->need_exec = 1; + } + + group_copy_inputs(node, in, exec->stack); + ntreeExecNodes(exec, data, thread); + group_free_internal(exec); + group_move_outputs(node, out, exec->stack); +} + +void register_node_type_cmp_group(ListBase *lb) +{ + static bNodeType ntype; + + node_type_base(&ntype, NODE_GROUP, "Group", NODE_CLASS_GROUP, NODE_OPTIONS|NODE_CONST_OUTPUT); + node_type_socket_templates(&ntype, NULL, NULL); + node_type_size(&ntype, 120, 60, 200); + node_type_label(&ntype, node_group_label); + node_type_init(&ntype, node_group_init); + node_type_valid(&ntype, node_group_valid); + node_type_template(&ntype, node_group_template); + node_type_update(&ntype, NULL, node_group_verify); + node_type_group_edit(&ntype, node_group_edit_get, node_group_edit_set, node_group_edit_clear); + node_type_exec_new(&ntype, group_initexec, group_freeexec, group_execute); + + nodeRegisterType(lb, &ntype); +} + + +/**** FOR LOOP ****/ + +#if 0 /* XXX loop nodes don't work nicely with current trees */ +/* Move the results from the previous iteration back to the input sockets. */ +static void loop_iteration_reset(bNodeTree *ngroup, bNodeStack *gstack) +{ + bNodeSocket *gin, *gout; + bNodeStack *nsin, *nsout; + + gin = ngroup->inputs.first; + gout = ngroup->outputs.first; + + while (gin && gout) { + /* skip static (non-looping) sockets */ + while (gin && !(gin->flag & SOCK_DYNAMIC)) + gin=gin->next; + while (gout && !(gout->flag & SOCK_DYNAMIC)) + gout=gout->next; + + if (gin && gout) { + nsin = node_get_socket_stack(gstack, gin); + nsout = node_get_socket_stack(gstack, gout); + + move_stack(nsin, nsout); + + gin=gin->next; + gout=gout->next; + } + } +} + +static void forloop_execute(void *data, int thread, struct bNode *node, void *nodedata, struct bNodeStack **in, struct bNodeStack **out) +{ + bNodeTreeExec *exec= (bNodeTreeExec*)nodedata; + int totiterations= (int)in[0]->vec[0]; + bNodeSocket *sock; + bNodeStack *ns; + int iteration; + + /* XXX same behavior as trunk: all nodes inside group are executed. + * it's stupid, but just makes it work. compo redesign will do this better. + */ + { + bNode *inode; + for (inode=exec->nodetree->nodes.first; inode; inode=inode->next) + inode->need_exec = 1; + } + + /* "Iteration" socket */ + sock = exec->nodetree->inputs.first; + ns = node_get_socket_stack(exec->stack, sock); + + group_copy_inputs(node, in, exec->stack); + for (iteration=0; iteration < totiterations; ++iteration) { + /* first input contains current iteration counter */ + ns->vec[0] = (float)iteration; + + if (iteration > 0) + loop_iteration_reset(exec->nodetree, exec->stack); + ntreeExecNodes(exec, data, thread); + group_free_internal(exec); + } + group_move_outputs(node, out, exec->stack); +} + +void register_node_type_cmp_forloop(ListBase *lb) +{ + static bNodeType ntype; + + node_type_base(&ntype, NODE_FORLOOP, "For", NODE_CLASS_GROUP, NODE_OPTIONS); + node_type_socket_templates(&ntype, NULL, NULL); + node_type_size(&ntype, 120, 60, 200); + node_type_label(&ntype, node_group_label); + node_type_init(&ntype, node_forloop_init); + node_type_valid(&ntype, node_group_valid); + node_type_template(&ntype, node_forloop_template); + node_type_update(&ntype, NULL, node_group_verify); + node_type_tree(&ntype, node_forloop_init_tree, node_loop_update_tree); + node_type_group_edit(&ntype, node_group_edit_get, node_group_edit_set, node_group_edit_clear); + node_type_exec_new(&ntype, group_initexec, group_freeexec, forloop_execute); + + nodeRegisterType(lb, &ntype); +} +#endif + + +/**** WHILE LOOP ****/ + +#if 0 /* XXX loop nodes don't work nicely with current trees */ +static void whileloop_execute(void *data, int thread, struct bNode *node, void *nodedata, struct bNodeStack **in, struct bNodeStack **out) +{ + bNodeTreeExec *exec= (bNodeTreeExec*)nodedata; + int condition= (in[0]->vec[0] > 0.0f); + bNodeSocket *sock; + bNodeStack *ns; + int iteration; + + /* XXX same behavior as trunk: all nodes inside group are executed. + * it's stupid, but just makes it work. compo redesign will do this better. + */ + { + bNode *inode; + for (inode=exec->nodetree->nodes.first; inode; inode=inode->next) + inode->need_exec = 1; + } + + /* "Condition" socket */ + sock = exec->nodetree->outputs.first; + ns = node_get_socket_stack(exec->stack, sock); + + iteration = 0; + group_copy_inputs(node, in, exec->stack); + while (condition && iteration < node->custom1) { + if (iteration > 0) + loop_iteration_reset(exec->nodetree, exec->stack); + ntreeExecNodes(exec, data, thread); + group_free_internal(exec); + +// PRINT_BUFFERS(exec); + + condition = (ns->vec[0] > 0.0f); + ++iteration; + } + group_move_outputs(node, out, exec->stack); +} + +void register_node_type_cmp_whileloop(ListBase *lb) +{ + static bNodeType ntype; + + node_type_base(&ntype, NODE_WHILELOOP, "While", NODE_CLASS_GROUP, NODE_OPTIONS); + node_type_socket_templates(&ntype, NULL, NULL); + node_type_size(&ntype, 120, 60, 200); + node_type_label(&ntype, node_group_label); + node_type_init(&ntype, node_whileloop_init); + node_type_valid(&ntype, node_group_valid); + node_type_template(&ntype, node_whileloop_template); + node_type_update(&ntype, NULL, node_group_verify); + node_type_tree(&ntype, node_whileloop_init_tree, node_loop_update_tree); + node_type_group_edit(&ntype, node_group_edit_get, node_group_edit_set, node_group_edit_clear); + node_type_exec_new(&ntype, group_initexec, group_freeexec, whileloop_execute); + + nodeRegisterType(lb, &ntype); +} +#endif diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_composite.c b/source/blender/nodes/composite/nodes/node_composite_composite.c similarity index 85% rename from source/blender/nodes/intern/CMP_nodes/CMP_composite.c rename to source/blender/nodes/composite/nodes/node_composite_composite.c index fb68f56ae64..be6246b42d8 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_composite.c +++ b/source/blender/nodes/composite/nodes/node_composite_composite.c @@ -1,5 +1,5 @@ /* - * $Id$ + * $Id: CMP_composite.c 36593 2011-05-10 11:19:26Z lukastoenne $ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -27,20 +27,20 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/nodes/intern/CMP_nodes/CMP_composite.c +/** \file blender/nodes/composite/nodes/node_composite_composite.c * \ingroup cmpnodes */ -#include "../CMP_util.h" +#include "node_composite_util.h" /* **************** COMPOSITE ******************** */ -static bNodeSocketType cmp_node_composite_in[]= { - { SOCK_RGBA, 1, "Image", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, - { SOCK_VALUE, 1, "Alpha", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, - { SOCK_VALUE, 1, "Z", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate cmp_node_composite_in[]= { + { SOCK_RGBA, 1, "Image", 0.0f, 0.0f, 0.0f, 1.0f}, + { SOCK_FLOAT, 1, "Alpha", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR}, + { SOCK_FLOAT, 1, "Z", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR}, { -1, 0, "" } }; @@ -103,8 +103,8 @@ void register_node_type_cmp_composite(ListBase *lb) { static bNodeType ntype; - node_type_base(&ntype, CMP_NODE_COMPOSITE, "Composite", NODE_CLASS_OUTPUT, NODE_PREVIEW, - cmp_node_composite_in, NULL); + node_type_base(&ntype, CMP_NODE_COMPOSITE, "Composite", NODE_CLASS_OUTPUT, NODE_PREVIEW); + node_type_socket_templates(&ntype, cmp_node_composite_in, NULL); node_type_size(&ntype, 80, 60, 200); node_type_exec(&ntype, node_composit_exec_composite); diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_crop.c b/source/blender/nodes/composite/nodes/node_composite_crop.c similarity index 87% rename from source/blender/nodes/intern/CMP_nodes/CMP_crop.c rename to source/blender/nodes/composite/nodes/node_composite_crop.c index 0331217f0cb..332ecf39616 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_crop.c +++ b/source/blender/nodes/composite/nodes/node_composite_crop.c @@ -27,21 +27,21 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/nodes/intern/CMP_nodes/CMP_crop.c +/** \file blender/nodes/composite/nodes/node_composite_crop.c * \ingroup cmpnodes */ -#include "../CMP_util.h" +#include "node_composite_util.h" /* **************** Crop ******************** */ -static bNodeSocketType cmp_node_crop_in[]= { - { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate cmp_node_crop_in[]= { + { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f}, { -1, 0, "" } }; -static bNodeSocketType cmp_node_crop_out[]= { - { SOCK_RGBA, 0, "Image", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate cmp_node_crop_out[]= { + { SOCK_RGBA, 0, "Image"}, { -1, 0, "" } }; @@ -103,7 +103,7 @@ static void node_composit_exec_crop(void *UNUSED(data), bNode *node, bNodeStack } } -static void node_composit_init_crop(bNode* node) +static void node_composit_init_crop(bNodeTree *UNUSED(ntree), bNode* node, bNodeTemplate *UNUSED(ntemp)) { NodeTwoXYs *nxy= MEM_callocN(sizeof(NodeTwoXYs), "node xy data"); node->storage= nxy; @@ -117,8 +117,8 @@ void register_node_type_cmp_crop(ListBase *lb) { static bNodeType ntype; - node_type_base(&ntype, CMP_NODE_CROP, "Crop", NODE_CLASS_DISTORT, NODE_OPTIONS, - cmp_node_crop_in, cmp_node_crop_out); + node_type_base(&ntype, CMP_NODE_CROP, "Crop", NODE_CLASS_DISTORT, NODE_OPTIONS); + node_type_socket_templates(&ntype, cmp_node_crop_in, cmp_node_crop_out); node_type_size(&ntype, 140, 100, 320); node_type_init(&ntype, node_composit_init_crop); node_type_storage(&ntype, "NodeTwoXYs", node_free_standard_storage, node_copy_standard_storage); diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_curves.c b/source/blender/nodes/composite/nodes/node_composite_curves.c similarity index 78% rename from source/blender/nodes/intern/CMP_nodes/CMP_curves.c rename to source/blender/nodes/composite/nodes/node_composite_curves.c index 921c5e21fea..a830b595321 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_curves.c +++ b/source/blender/nodes/composite/nodes/node_composite_curves.c @@ -1,5 +1,5 @@ /* - * $Id$ + * $Id: CMP_curves.c 36593 2011-05-10 11:19:26Z lukastoenne $ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -27,19 +27,19 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/nodes/intern/CMP_nodes/CMP_curves.c +/** \file blender/nodes/composite/nodes/node_composite_curves.c * \ingroup cmpnodes */ -#include "../CMP_util.h" +#include "node_composite_util.h" /* **************** CURVE Time ******************** */ /* custom1 = sfra, custom2 = efra */ -static bNodeSocketType cmp_node_time_out[]= { - { SOCK_VALUE, 0, "Fac", 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate cmp_node_time_out[]= { + { SOCK_FLOAT, 0, "Fac"}, { -1, 0, "" } }; @@ -57,7 +57,7 @@ static void node_composit_exec_curves_time(void *data, bNode *node, bNodeStack * } -static void node_composit_init_curves_time(bNode* node) +static void node_composit_init_curves_time(bNodeTree *UNUSED(ntree), bNode* node, bNodeTemplate *UNUSED(ntemp)) { node->custom1= 1; node->custom2= 250; @@ -68,8 +68,8 @@ void register_node_type_cmp_curve_time(ListBase *lb) { static bNodeType ntype; - node_type_base(&ntype, CMP_NODE_TIME, "Time", NODE_CLASS_INPUT, NODE_OPTIONS, - NULL, cmp_node_time_out); + node_type_base(&ntype, CMP_NODE_TIME, "Time", NODE_CLASS_INPUT, NODE_OPTIONS); + node_type_socket_templates(&ntype, NULL, cmp_node_time_out); node_type_size(&ntype, 140, 100, 320); node_type_init(&ntype, node_composit_init_curves_time); node_type_storage(&ntype, "CurveMapping", node_free_curves, node_copy_curves); @@ -82,13 +82,13 @@ void register_node_type_cmp_curve_time(ListBase *lb) /* **************** CURVE VEC ******************** */ -static bNodeSocketType cmp_node_curve_vec_in[]= { - { SOCK_VECTOR, 1, "Vector", 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f}, +static bNodeSocketTemplate cmp_node_curve_vec_in[]= { + { SOCK_VECTOR, 1, "Vector", 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, PROP_NONE}, { -1, 0, "" } }; -static bNodeSocketType cmp_node_curve_vec_out[]= { - { SOCK_VECTOR, 0, "Vector", 0.0f, 0.0f, 1.0f, 1.0f, -1.0f, 1.0f}, +static bNodeSocketTemplate cmp_node_curve_vec_out[]= { + { SOCK_VECTOR, 0, "Vector"}, { -1, 0, "" } }; @@ -100,7 +100,7 @@ static void node_composit_exec_curve_vec(void *UNUSED(data), bNode *node, bNodeS curvemapping_evaluate_premulRGBF(node->storage, out[0]->vec, in[0]->vec); } -static void node_composit_init_curve_vec(bNode* node) +static void node_composit_init_curve_vec(bNodeTree *UNUSED(ntree), bNode* node, bNodeTemplate *UNUSED(ntemp)) { node->storage= curvemapping_add(3, -1.0f, -1.0f, 1.0f, 1.0f); } @@ -109,8 +109,8 @@ void register_node_type_cmp_curve_vec(ListBase *lb) { static bNodeType ntype; - node_type_base(&ntype, CMP_NODE_CURVE_VEC, "Vector Curves", NODE_CLASS_OP_VECTOR, NODE_OPTIONS, - cmp_node_curve_vec_in, cmp_node_curve_vec_out); + node_type_base(&ntype, CMP_NODE_CURVE_VEC, "Vector Curves", NODE_CLASS_OP_VECTOR, NODE_OPTIONS); + node_type_socket_templates(&ntype, cmp_node_curve_vec_in, cmp_node_curve_vec_out); node_type_size(&ntype, 200, 140, 320); node_type_init(&ntype, node_composit_init_curve_vec); node_type_storage(&ntype, "CurveMapping", node_free_curves, node_copy_curves); @@ -121,16 +121,16 @@ void register_node_type_cmp_curve_vec(ListBase *lb) /* **************** CURVE RGB ******************** */ -static bNodeSocketType cmp_node_curve_rgb_in[]= { - { SOCK_VALUE, 1, "Fac", 1.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f}, - { SOCK_RGBA, 1, "Image", 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f}, - { SOCK_RGBA, 1, "Black Level", 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f}, - { SOCK_RGBA, 1, "White Level", 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f}, +static bNodeSocketTemplate cmp_node_curve_rgb_in[]= { + { SOCK_FLOAT, 1, "Fac", 1.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, PROP_FACTOR}, + { SOCK_RGBA, 1, "Image", 0.0f, 0.0f, 0.0f, 1.0f}, + { SOCK_RGBA, 1, "Black Level", 0.0f, 0.0f, 0.0f, 1.0f}, + { SOCK_RGBA, 1, "White Level", 1.0f, 1.0f, 1.0f, 1.0f}, { -1, 0, "" } }; -static bNodeSocketType cmp_node_curve_rgb_out[]= { - { SOCK_RGBA, 0, "Image", 0.0f, 0.0f, 1.0f, 1.0f, -1.0f, 1.0f}, +static bNodeSocketTemplate cmp_node_curve_rgb_out[]= { + { SOCK_RGBA, 0, "Image"}, { -1, 0, "" } }; @@ -187,7 +187,7 @@ static void node_composit_exec_curve_rgb(void *UNUSED(data), bNode *node, bNodeS } -static void node_composit_init_curve_rgb(bNode* node) +static void node_composit_init_curve_rgb(bNodeTree *UNUSED(ntree), bNode* node, bNodeTemplate *UNUSED(ntemp)) { node->storage= curvemapping_add(4, 0.0f, 0.0f, 1.0f, 1.0f); } @@ -196,8 +196,8 @@ void register_node_type_cmp_curve_rgb(ListBase *lb) { static bNodeType ntype; - node_type_base(&ntype, CMP_NODE_CURVE_RGB, "RGB Curves", NODE_CLASS_OP_COLOR, NODE_OPTIONS, - cmp_node_curve_rgb_in, cmp_node_curve_rgb_out); + node_type_base(&ntype, CMP_NODE_CURVE_RGB, "RGB Curves", NODE_CLASS_OP_COLOR, NODE_OPTIONS); + node_type_socket_templates(&ntype, cmp_node_curve_rgb_in, cmp_node_curve_rgb_out); node_type_size(&ntype, 200, 140, 320); node_type_init(&ntype, node_composit_init_curve_rgb); node_type_storage(&ntype, "CurveMapping", node_free_curves, node_copy_curves); diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_defocus.c b/source/blender/nodes/composite/nodes/node_composite_defocus.c similarity index 97% rename from source/blender/nodes/intern/CMP_nodes/CMP_defocus.c rename to source/blender/nodes/composite/nodes/node_composite_defocus.c index f249e2cff6c..a218bfb009d 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_defocus.c +++ b/source/blender/nodes/composite/nodes/node_composite_defocus.c @@ -1,5 +1,5 @@ /* - * $Id$ + * $Id: CMP_defocus.c 36593 2011-05-10 11:19:26Z lukastoenne $ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -27,21 +27,21 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/nodes/intern/CMP_nodes/CMP_defocus.c +/** \file blender/nodes/composite/nodes/node_composite_defocus.c * \ingroup cmpnodes */ -#include "../CMP_util.h" +#include "node_composite_util.h" /* ************ qdn: Defocus node ****************** */ -static bNodeSocketType cmp_node_defocus_in[]= { - { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, - { SOCK_VALUE, 1, "Z", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate cmp_node_defocus_in[]= { + { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f}, + { SOCK_FLOAT, 1, "Z", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f, PROP_FACTOR}, { -1, 0, "" } }; -static bNodeSocketType cmp_node_defocus_out[]= { - { SOCK_RGBA, 0, "Image", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate cmp_node_defocus_out[]= { + { SOCK_RGBA, 0, "Image"}, { -1, 0, "" } }; @@ -857,7 +857,7 @@ static void node_composit_exec_defocus(void *UNUSED(data), bNode *node, bNodeSta if (zbuf_use && (zbuf_use != zbuf)) free_compbuf(zbuf_use); } -static void node_composit_init_defocus(bNode* node) +static void node_composit_init_defocus(bNodeTree *UNUSED(ntree), bNode* node, bNodeTemplate *UNUSED(ntemp)) { /* qdn: defocus node */ NodeDefocus *nbd = MEM_callocN(sizeof(NodeDefocus), "node defocus data"); @@ -878,8 +878,8 @@ void register_node_type_cmp_defocus(ListBase *lb) { static bNodeType ntype; - node_type_base(&ntype, CMP_NODE_DEFOCUS, "Defocus", NODE_CLASS_OP_FILTER, NODE_OPTIONS, - cmp_node_defocus_in, cmp_node_defocus_out); + node_type_base(&ntype, CMP_NODE_DEFOCUS, "Defocus", NODE_CLASS_OP_FILTER, NODE_OPTIONS); + node_type_socket_templates(&ntype, cmp_node_defocus_in, cmp_node_defocus_out); node_type_size(&ntype, 150, 120, 200); node_type_init(&ntype, node_composit_init_defocus); node_type_storage(&ntype, "NodeDefocus", node_free_standard_storage, node_copy_standard_storage); diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_diffMatte.c b/source/blender/nodes/composite/nodes/node_composite_diffMatte.c similarity index 84% rename from source/blender/nodes/intern/CMP_nodes/CMP_diffMatte.c rename to source/blender/nodes/composite/nodes/node_composite_diffMatte.c index 296053298da..a0fff88f5dc 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_diffMatte.c +++ b/source/blender/nodes/composite/nodes/node_composite_diffMatte.c @@ -1,5 +1,5 @@ /* - * $Id$ + * $Id: CMP_diffMatte.c 36536 2011-05-07 13:27:27Z lukastoenne $ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -27,23 +27,23 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/nodes/intern/CMP_nodes/CMP_diffMatte.c +/** \file blender/nodes/composite/nodes/node_composite_diffMatte.c * \ingroup cmpnodes */ -#include "../CMP_util.h" +#include "node_composite_util.h" /* ******************* channel Difference Matte ********************************* */ -static bNodeSocketType cmp_node_diff_matte_in[]={ - {SOCK_RGBA,1,"Image 1", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, - {SOCK_RGBA,1,"Image 2", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate cmp_node_diff_matte_in[]={ + {SOCK_RGBA,1,"Image 1", 0.8f, 0.8f, 0.8f, 1.0f}, + {SOCK_RGBA,1,"Image 2", 0.8f, 0.8f, 0.8f, 1.0f}, {-1,0,""} }; -static bNodeSocketType cmp_node_diff_matte_out[]={ - {SOCK_RGBA,0,"Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, - {SOCK_VALUE,0,"Matte",0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate cmp_node_diff_matte_out[]={ + {SOCK_RGBA,0,"Image"}, + {SOCK_FLOAT,0,"Matte"}, {-1,0,""} }; @@ -125,7 +125,7 @@ static void node_composit_exec_diff_matte(void *data, bNode *node, bNodeStack ** free_compbuf(imbuf2); } -static void node_composit_init_diff_matte(bNode *node) +static void node_composit_init_diff_matte(bNodeTree *UNUSED(ntree), bNode* node, bNodeTemplate *UNUSED(ntemp)) { NodeChroma *c= MEM_callocN(sizeof(NodeChroma), "node chroma"); node->storage= c; @@ -137,8 +137,8 @@ void register_node_type_cmp_diff_matte(ListBase *lb) { static bNodeType ntype; - node_type_base(&ntype, CMP_NODE_DIFF_MATTE, "Difference Key", NODE_CLASS_MATTE, NODE_PREVIEW|NODE_OPTIONS, - cmp_node_diff_matte_in, cmp_node_diff_matte_out); + node_type_base(&ntype, CMP_NODE_DIFF_MATTE, "Difference Key", NODE_CLASS_MATTE, NODE_PREVIEW|NODE_OPTIONS); + node_type_socket_templates(&ntype, cmp_node_diff_matte_in, cmp_node_diff_matte_out); node_type_size(&ntype, 200, 80, 250); node_type_init(&ntype, node_composit_init_diff_matte); node_type_storage(&ntype, "NodeChroma", node_free_standard_storage, node_copy_standard_storage); diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_dilate.c b/source/blender/nodes/composite/nodes/node_composite_dilate.c similarity index 87% rename from source/blender/nodes/intern/CMP_nodes/CMP_dilate.c rename to source/blender/nodes/composite/nodes/node_composite_dilate.c index f5d16ff0ab8..ef47fdbfef0 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_dilate.c +++ b/source/blender/nodes/composite/nodes/node_composite_dilate.c @@ -1,5 +1,5 @@ /* - * $Id$ + * $Id: CMP_dilate.c 36593 2011-05-10 11:19:26Z lukastoenne $ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -27,22 +27,22 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/nodes/intern/CMP_nodes/CMP_dilate.c +/** \file blender/nodes/composite/nodes/node_composite_dilate.c * \ingroup cmpnodes */ -#include "../CMP_util.h" +#include "node_composite_util.h" /* **************** Dilate/Erode ******************** */ -static bNodeSocketType cmp_node_dilateerode_in[]= { - { SOCK_VALUE, 1, "Mask", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate cmp_node_dilateerode_in[]= { + { SOCK_FLOAT, 1, "Mask", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, PROP_FACTOR}, { -1, 0, "" } }; -static bNodeSocketType cmp_node_dilateerode_out[]= { - { SOCK_VALUE, 0, "Mask", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate cmp_node_dilateerode_out[]= { + { SOCK_FLOAT, 0, "Mask"}, { -1, 0, "" } }; @@ -152,8 +152,8 @@ void register_node_type_cmp_dilateerode(ListBase *lb) { static bNodeType ntype; - node_type_base(&ntype, CMP_NODE_DILATEERODE, "Dilate/Erode", NODE_CLASS_OP_FILTER, NODE_OPTIONS, - cmp_node_dilateerode_in, cmp_node_dilateerode_out); + node_type_base(&ntype, CMP_NODE_DILATEERODE, "Dilate/Erode", NODE_CLASS_OP_FILTER, NODE_OPTIONS); + node_type_socket_templates(&ntype, cmp_node_dilateerode_in, cmp_node_dilateerode_out); node_type_size(&ntype, 130, 100, 320); node_type_exec(&ntype, node_composit_exec_dilateerode); diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_directionalblur.c b/source/blender/nodes/composite/nodes/node_composite_directionalblur.c similarity index 88% rename from source/blender/nodes/intern/CMP_nodes/CMP_directionalblur.c rename to source/blender/nodes/composite/nodes/node_composite_directionalblur.c index 2a8bbcc9ad5..3d541120a61 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_directionalblur.c +++ b/source/blender/nodes/composite/nodes/node_composite_directionalblur.c @@ -26,20 +26,20 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/nodes/intern/CMP_nodes/CMP_directionalblur.c +/** \file blender/nodes/composite/nodes/node_composite_directionalblur.c * \ingroup cmpnodes */ -#include "../CMP_util.h" +#include "node_composite_util.h" -static bNodeSocketType cmp_node_dblur_in[]= { - { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.f, 0.f, 1.f}, +static bNodeSocketTemplate cmp_node_dblur_in[]= { + { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.f}, { -1, 0, "" } }; -static bNodeSocketType cmp_node_dblur_out[]= { - { SOCK_RGBA, 0, "Image", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate cmp_node_dblur_out[]= { + { SOCK_RGBA, 0, "Image"}, { -1, 0, "" } }; @@ -122,7 +122,7 @@ static void node_composit_exec_dblur(void *UNUSED(data), bNode *node, bNodeStack out[0]->data= dblur(node, new, ndbd->iter, ndbd->wrap, ndbd->center_x, ndbd->center_y, ndbd->distance, ndbd->angle, ndbd->spin, ndbd->zoom); } -static void node_composit_init_dblur(bNode* node) +static void node_composit_init_dblur(bNodeTree *UNUSED(ntree), bNode* node, bNodeTemplate *UNUSED(ntemp)) { NodeDBlurData *ndbd= MEM_callocN(sizeof(NodeDBlurData), "node dblur data"); node->storage= ndbd; @@ -134,8 +134,8 @@ void register_node_type_cmp_dblur(ListBase *lb) { static bNodeType ntype; - node_type_base(&ntype, CMP_NODE_DBLUR, "Directional Blur", NODE_CLASS_OP_FILTER, NODE_OPTIONS, - cmp_node_dblur_in, cmp_node_dblur_out); + node_type_base(&ntype, CMP_NODE_DBLUR, "Directional Blur", NODE_CLASS_OP_FILTER, NODE_OPTIONS); + node_type_socket_templates(&ntype, cmp_node_dblur_in, cmp_node_dblur_out); node_type_size(&ntype, 150, 120, 200); node_type_init(&ntype, node_composit_init_dblur); node_type_storage(&ntype, "NodeDBlurData", node_free_standard_storage, node_copy_standard_storage); diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_displace.c b/source/blender/nodes/composite/nodes/node_composite_displace.c similarity index 88% rename from source/blender/nodes/intern/CMP_nodes/CMP_displace.c rename to source/blender/nodes/composite/nodes/node_composite_displace.c index 9139edf8560..4688553d27f 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_displace.c +++ b/source/blender/nodes/composite/nodes/node_composite_displace.c @@ -1,5 +1,5 @@ /* - * $Id$ + * $Id: CMP_displace.c 36593 2011-05-10 11:19:26Z lukastoenne $ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -27,25 +27,25 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/nodes/intern/CMP_nodes/CMP_displace.c +/** \file blender/nodes/composite/nodes/node_composite_displace.c * \ingroup cmpnodes */ -#include "../CMP_util.h" +#include "node_composite_util.h" /* **************** Displace ******************** */ -static bNodeSocketType cmp_node_displace_in[]= { - { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, - { SOCK_VECTOR, 1, "Vector", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, - { SOCK_VALUE, 1, "X Scale", 0.0f, 0.0f, 0.0f, 0.0f, -1000.0f, 1000.0f}, - { SOCK_VALUE, 1, "Y Scale", 0.0f, 0.0f, 0.0f, 0.0f, -1000.0f, 1000.0f}, +static bNodeSocketTemplate cmp_node_displace_in[]= { + { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f}, + { SOCK_VECTOR, 1, "Vector", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_TRANSLATION}, + { SOCK_FLOAT, 1, "X Scale", 0.0f, 0.0f, 0.0f, 0.0f, -1000.0f, 1000.0f, PROP_FACTOR}, + { SOCK_FLOAT, 1, "Y Scale", 0.0f, 0.0f, 0.0f, 0.0f, -1000.0f, 1000.0f, PROP_FACTOR}, { -1, 0, "" } }; -static bNodeSocketType cmp_node_displace_out[]= { - { SOCK_RGBA, 0, "Image", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate cmp_node_displace_out[]= { + { SOCK_RGBA, 0, "Image"}, { -1, 0, "" } }; @@ -188,8 +188,8 @@ void register_node_type_cmp_displace(ListBase *lb) { static bNodeType ntype; - node_type_base(&ntype, CMP_NODE_DISPLACE, "Displace", NODE_CLASS_DISTORT, NODE_OPTIONS, - cmp_node_displace_in, cmp_node_displace_out); + node_type_base(&ntype, CMP_NODE_DISPLACE, "Displace", NODE_CLASS_DISTORT, NODE_OPTIONS); + node_type_socket_templates(&ntype, cmp_node_displace_in, cmp_node_displace_out); node_type_size(&ntype, 140, 100, 320); node_type_exec(&ntype, node_composit_exec_displace); diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_distanceMatte.c b/source/blender/nodes/composite/nodes/node_composite_distanceMatte.c similarity index 83% rename from source/blender/nodes/intern/CMP_nodes/CMP_distanceMatte.c rename to source/blender/nodes/composite/nodes/node_composite_distanceMatte.c index 5f7613464c1..c895eab391c 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_distanceMatte.c +++ b/source/blender/nodes/composite/nodes/node_composite_distanceMatte.c @@ -1,5 +1,5 @@ /* - * $Id$ + * $Id: CMP_distanceMatte.c 36536 2011-05-07 13:27:27Z lukastoenne $ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -27,23 +27,23 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/nodes/intern/CMP_nodes/CMP_distanceMatte.c +/** \file blender/nodes/composite/nodes/node_composite_distanceMatte.c * \ingroup cmpnodes */ -#include "../CMP_util.h" +#include "node_composite_util.h" /* ******************* channel Distance Matte ********************************* */ -static bNodeSocketType cmp_node_distance_matte_in[]={ - {SOCK_RGBA,1,"Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, - {SOCK_RGBA,1,"Key Color", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate cmp_node_distance_matte_in[]={ + {SOCK_RGBA,1,"Image", 0.8f, 0.8f, 0.8f, 1.0f}, + {SOCK_RGBA,1,"Key Color", 0.8f, 0.8f, 0.8f, 1.0f}, {-1,0,""} }; -static bNodeSocketType cmp_node_distance_matte_out[]={ - {SOCK_RGBA,0,"Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, - {SOCK_VALUE,0,"Matte",0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate cmp_node_distance_matte_out[]={ + {SOCK_RGBA,0,"Image"}, + {SOCK_FLOAT,0,"Matte"}, {-1,0,""} }; @@ -122,7 +122,7 @@ static void node_composit_exec_distance_matte(void *data, bNode *node, bNodeStac free_compbuf(inbuf); } -static void node_composit_init_distance_matte(bNode *node) +static void node_composit_init_distance_matte(bNodeTree *UNUSED(ntree), bNode* node, bNodeTemplate *UNUSED(ntemp)) { NodeChroma *c= MEM_callocN(sizeof(NodeChroma), "node chroma"); node->storage= c; @@ -134,8 +134,8 @@ void register_node_type_cmp_distance_matte(ListBase *lb) { static bNodeType ntype; - node_type_base(&ntype, CMP_NODE_DIST_MATTE, "Distance Key", NODE_CLASS_MATTE, NODE_PREVIEW|NODE_OPTIONS, - cmp_node_distance_matte_in, cmp_node_distance_matte_out); + node_type_base(&ntype, CMP_NODE_DIST_MATTE, "Distance Key", NODE_CLASS_MATTE, NODE_PREVIEW|NODE_OPTIONS); + node_type_socket_templates(&ntype, cmp_node_distance_matte_in, cmp_node_distance_matte_out); node_type_size(&ntype, 200, 80, 250); node_type_init(&ntype, node_composit_init_distance_matte); node_type_storage(&ntype, "NodeChroma", node_free_standard_storage, node_copy_standard_storage); diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_filter.c b/source/blender/nodes/composite/nodes/node_composite_filter.c similarity index 92% rename from source/blender/nodes/intern/CMP_nodes/CMP_filter.c rename to source/blender/nodes/composite/nodes/node_composite_filter.c index 915cb01d2d4..6beeec49c63 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_filter.c +++ b/source/blender/nodes/composite/nodes/node_composite_filter.c @@ -1,5 +1,5 @@ /* - * $Id$ + * $Id: CMP_filter.c 36593 2011-05-10 11:19:26Z lukastoenne $ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -27,21 +27,21 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/nodes/intern/CMP_nodes/CMP_filter.c +/** \file blender/nodes/composite/nodes/node_composite_filter.c * \ingroup cmpnodes */ -#include "../CMP_util.h" +#include "node_composite_util.h" /* **************** FILTER ******************** */ -static bNodeSocketType cmp_node_filter_in[]= { - { SOCK_VALUE, 1, "Fac", 1.0f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, - { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate cmp_node_filter_in[]= { + { SOCK_FLOAT, 1, "Fac", 1.0f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f, PROP_FACTOR}, + { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f}, { -1, 0, "" } }; -static bNodeSocketType cmp_node_filter_out[]= { - { SOCK_RGBA, 0, "Image", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate cmp_node_filter_out[]= { + { SOCK_RGBA, 0, "Image"}, { -1, 0, "" } }; @@ -226,8 +226,8 @@ void register_node_type_cmp_filter(ListBase *lb) { static bNodeType ntype; - node_type_base(&ntype, CMP_NODE_FILTER, "Filter", NODE_CLASS_OP_FILTER, NODE_PREVIEW|NODE_OPTIONS, - cmp_node_filter_in, cmp_node_filter_out); + node_type_base(&ntype, CMP_NODE_FILTER, "Filter", NODE_CLASS_OP_FILTER, NODE_PREVIEW|NODE_OPTIONS); + node_type_socket_templates(&ntype, cmp_node_filter_in, cmp_node_filter_out); node_type_size(&ntype, 80, 40, 120); node_type_label(&ntype, node_filter_label); node_type_exec(&ntype, node_composit_exec_filter); diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_flip.c b/source/blender/nodes/composite/nodes/node_composite_flip.c similarity index 85% rename from source/blender/nodes/intern/CMP_nodes/CMP_flip.c rename to source/blender/nodes/composite/nodes/node_composite_flip.c index b5fd7b46e03..026130641a3 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_flip.c +++ b/source/blender/nodes/composite/nodes/node_composite_flip.c @@ -1,5 +1,5 @@ /* - * $Id$ + * $Id: CMP_flip.c 36333 2011-04-26 09:27:43Z lukastoenne $ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -27,21 +27,21 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/nodes/intern/CMP_nodes/CMP_flip.c +/** \file blender/nodes/composite/nodes/node_composite_flip.c * \ingroup cmpnodes */ -#include "../CMP_util.h" +#include "node_composite_util.h" /* **************** Flip ******************** */ -static bNodeSocketType cmp_node_flip_in[]= { - { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate cmp_node_flip_in[]= { + { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f}, { -1, 0, "" } }; -static bNodeSocketType cmp_node_flip_out[]= { - { SOCK_RGBA, 0, "Image", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate cmp_node_flip_out[]= { + { SOCK_RGBA, 0, "Image"}, { -1, 0, "" } }; @@ -94,8 +94,8 @@ void register_node_type_cmp_flip(ListBase *lb) { static bNodeType ntype; - node_type_base(&ntype, CMP_NODE_FLIP, "Flip", NODE_CLASS_DISTORT, NODE_OPTIONS, - cmp_node_flip_in, cmp_node_flip_out); + node_type_base(&ntype, CMP_NODE_FLIP, "Flip", NODE_CLASS_DISTORT, NODE_OPTIONS); + node_type_socket_templates(&ntype, cmp_node_flip_in, cmp_node_flip_out); node_type_size(&ntype, 140, 100, 320); node_type_exec(&ntype, node_composit_exec_flip); diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_gamma.c b/source/blender/nodes/composite/nodes/node_composite_gamma.c similarity index 81% rename from source/blender/nodes/intern/CMP_nodes/CMP_gamma.c rename to source/blender/nodes/composite/nodes/node_composite_gamma.c index 261257d3b5f..d191f649f1f 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_gamma.c +++ b/source/blender/nodes/composite/nodes/node_composite_gamma.c @@ -1,5 +1,5 @@ /* -* $Id$ +* $Id: CMP_gamma.c 36593 2011-05-10 11:19:26Z lukastoenne $ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -28,22 +28,22 @@ */ -/** \file blender/nodes/intern/CMP_nodes/CMP_gamma.c +/** \file blender/nodes/composite/nodes/node_composite_gamma.c * \ingroup cmpnodes */ -#include "../CMP_util.h" +#include "node_composite_util.h" /* **************** Gamma Tools ******************** */ -static bNodeSocketType cmp_node_gamma_in[]= { - { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, - { SOCK_VALUE, 1, "Gamma", 1.0f, 0.0f, 0.0f, 0.0f, 0.001f, 10.0f}, +static bNodeSocketTemplate cmp_node_gamma_in[]= { + { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f}, + { SOCK_FLOAT, 1, "Gamma", 1.0f, 0.0f, 0.0f, 0.0f, 0.001f, 10.0f, PROP_UNSIGNED}, { -1, 0, "" } }; -static bNodeSocketType cmp_node_gamma_out[]= { - { SOCK_RGBA, 0, "Image", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate cmp_node_gamma_out[]= { + { SOCK_RGBA, 0, "Image"}, { -1, 0, "" } }; @@ -81,8 +81,8 @@ void register_node_type_cmp_gamma(ListBase *lb) { static bNodeType ntype; - node_type_base(&ntype, CMP_NODE_GAMMA, "Gamma", NODE_CLASS_OP_COLOR, NODE_OPTIONS, - cmp_node_gamma_in, cmp_node_gamma_out); + node_type_base(&ntype, CMP_NODE_GAMMA, "Gamma", NODE_CLASS_OP_COLOR, NODE_OPTIONS); + node_type_socket_templates(&ntype, cmp_node_gamma_in, cmp_node_gamma_out); node_type_size(&ntype, 140, 100, 320); node_type_exec(&ntype, node_composit_exec_gamma); diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_glare.c b/source/blender/nodes/composite/nodes/node_composite_glare.c similarity index 96% rename from source/blender/nodes/intern/CMP_nodes/CMP_glare.c rename to source/blender/nodes/composite/nodes/node_composite_glare.c index 2e0822a4511..0890b9ba24b 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_glare.c +++ b/source/blender/nodes/composite/nodes/node_composite_glare.c @@ -26,19 +26,19 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/nodes/intern/CMP_nodes/CMP_glare.c +/** \file blender/nodes/composite/nodes/node_composite_glare.c * \ingroup cmpnodes */ -#include "../CMP_util.h" +#include "node_composite_util.h" -static bNodeSocketType cmp_node_glare_in[]= { - { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate cmp_node_glare_in[]= { + { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f}, { -1, 0, "" } }; -static bNodeSocketType cmp_node_glare_out[]= { - { SOCK_RGBA, 0, "Image", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate cmp_node_glare_out[]= { + { SOCK_RGBA, 0, "Image"}, { -1, 0, "" } }; @@ -474,7 +474,7 @@ static void node_composit_exec_glare(void *UNUSED(data), bNode *node, bNodeStack out[0]->data = new; } -static void node_composit_init_glare(bNode* node) +static void node_composit_init_glare(bNodeTree *UNUSED(ntree), bNode* node, bNodeTemplate *UNUSED(ntemp)) { NodeGlare *ndg = MEM_callocN(sizeof(NodeGlare), "node glare data"); ndg->quality = 1; @@ -494,8 +494,8 @@ void register_node_type_cmp_glare(ListBase *lb) { static bNodeType ntype; - node_type_base(&ntype, CMP_NODE_GLARE, "Glare", NODE_CLASS_OP_FILTER, NODE_OPTIONS, - cmp_node_glare_in, cmp_node_glare_out); + node_type_base(&ntype, CMP_NODE_GLARE, "Glare", NODE_CLASS_OP_FILTER, NODE_OPTIONS); + node_type_socket_templates(&ntype, cmp_node_glare_in, cmp_node_glare_out); node_type_size(&ntype, 150, 120, 200); node_type_init(&ntype, node_composit_init_glare); node_type_storage(&ntype, "NodeGlare", node_free_standard_storage, node_copy_standard_storage); diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_hueSatVal.c b/source/blender/nodes/composite/nodes/node_composite_hueSatVal.c similarity index 82% rename from source/blender/nodes/intern/CMP_nodes/CMP_hueSatVal.c rename to source/blender/nodes/composite/nodes/node_composite_hueSatVal.c index 7b5511c699c..525728ade31 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_hueSatVal.c +++ b/source/blender/nodes/composite/nodes/node_composite_hueSatVal.c @@ -1,5 +1,5 @@ /* - * $Id$ + * $Id: CMP_hueSatVal.c 36593 2011-05-10 11:19:26Z lukastoenne $ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -27,22 +27,22 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/nodes/intern/CMP_nodes/CMP_hueSatVal.c +/** \file blender/nodes/composite/nodes/node_composite_hueSatVal.c * \ingroup cmpnodes */ -#include "../CMP_util.h" +#include "node_composite_util.h" /* **************** Hue Saturation ******************** */ -static bNodeSocketType cmp_node_hue_sat_in[]= { - { SOCK_VALUE, 1, "Fac", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, - { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate cmp_node_hue_sat_in[]= { + { SOCK_FLOAT, 1, "Fac", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR}, + { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 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}, +static bNodeSocketTemplate cmp_node_hue_sat_out[]= { + { SOCK_RGBA, 0, "Image"}, { -1, 0, "" } }; @@ -95,7 +95,7 @@ static void node_composit_exec_hue_sat(void *UNUSED(data), bNode *node, bNodeSta } } -static void node_composit_init_hue_sat(bNode* node) +static void node_composit_init_hue_sat(bNodeTree *UNUSED(ntree), bNode* node, bNodeTemplate *UNUSED(ntemp)) { NodeHueSat *nhs= MEM_callocN(sizeof(NodeHueSat), "node hue sat"); node->storage= nhs; @@ -108,8 +108,8 @@ void register_node_type_cmp_hue_sat(ListBase *lb) { static bNodeType ntype; - node_type_base(&ntype, CMP_NODE_HUE_SAT, "Hue Saturation Value", NODE_CLASS_OP_COLOR, NODE_OPTIONS, - cmp_node_hue_sat_in, cmp_node_hue_sat_out); + node_type_base(&ntype, CMP_NODE_HUE_SAT, "Hue Saturation Value", NODE_CLASS_OP_COLOR, NODE_OPTIONS); + node_type_socket_templates(&ntype, cmp_node_hue_sat_in, cmp_node_hue_sat_out); node_type_size(&ntype, 150, 80, 250); node_type_init(&ntype, node_composit_init_hue_sat); node_type_storage(&ntype, "NodeHueSat", node_free_standard_storage, node_copy_standard_storage); diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_huecorrect.c b/source/blender/nodes/composite/nodes/node_composite_huecorrect.c similarity index 87% rename from source/blender/nodes/intern/CMP_nodes/CMP_huecorrect.c rename to source/blender/nodes/composite/nodes/node_composite_huecorrect.c index edf6c454285..edf26aed882 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_huecorrect.c +++ b/source/blender/nodes/composite/nodes/node_composite_huecorrect.c @@ -1,5 +1,5 @@ /* - * $Id$ + * $Id: CMP_huecorrect.c 36593 2011-05-10 11:19:26Z lukastoenne $ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -27,21 +27,21 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/nodes/intern/CMP_nodes/CMP_huecorrect.c +/** \file blender/nodes/composite/nodes/node_composite_huecorrect.c * \ingroup cmpnodes */ -#include "../CMP_util.h" +#include "node_composite_util.h" -static bNodeSocketType cmp_node_huecorrect_in[]= { - { SOCK_VALUE, 1, "Fac", 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, - { SOCK_RGBA, 1, "Image", 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f}, +static bNodeSocketTemplate cmp_node_huecorrect_in[]= { + { SOCK_FLOAT, 1, "Fac", 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, PROP_FACTOR}, + { SOCK_RGBA, 1, "Image", 0.0f, 0.0f, 0.0f, 1.0f}, { -1, 0, "" } }; -static bNodeSocketType cmp_node_huecorrect_out[]= { - { SOCK_RGBA, 0, "Image", 0.0f, 0.0f, 1.0f, 1.0f, -1.0f, 1.0f}, +static bNodeSocketTemplate cmp_node_huecorrect_out[]= { + { SOCK_RGBA, 0, "Image"}, { -1, 0, "" } }; @@ -137,7 +137,7 @@ static void node_composit_exec_huecorrect(void *UNUSED(data), bNode *node, bNode } -static void node_composit_init_huecorrect(bNode* node) +static void node_composit_init_huecorrect(bNodeTree *UNUSED(ntree), bNode* node, bNodeTemplate *UNUSED(ntemp)) { CurveMapping *cumapping = node->storage= curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f); int c; @@ -157,8 +157,8 @@ void register_node_type_cmp_huecorrect(ListBase *lb) { static bNodeType ntype; - node_type_base(&ntype, CMP_NODE_HUECORRECT, "Hue Correct", NODE_CLASS_OP_COLOR, NODE_OPTIONS, - cmp_node_huecorrect_in, cmp_node_huecorrect_out); + node_type_base(&ntype, CMP_NODE_HUECORRECT, "Hue Correct", NODE_CLASS_OP_COLOR, NODE_OPTIONS); + node_type_socket_templates(&ntype, cmp_node_huecorrect_in, cmp_node_huecorrect_out); node_type_size(&ntype, 320, 140, 400); node_type_init(&ntype, node_composit_init_huecorrect); node_type_storage(&ntype, "CurveMapping", node_free_curves, node_copy_curves); diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_idMask.c b/source/blender/nodes/composite/nodes/node_composite_idMask.c similarity index 84% rename from source/blender/nodes/intern/CMP_nodes/CMP_idMask.c rename to source/blender/nodes/composite/nodes/node_composite_idMask.c index 72d0de7d15e..97d84997697 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_idMask.c +++ b/source/blender/nodes/composite/nodes/node_composite_idMask.c @@ -1,5 +1,5 @@ /* - * $Id$ + * $Id: CMP_idMask.c 36593 2011-05-10 11:19:26Z lukastoenne $ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -27,22 +27,22 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/nodes/intern/CMP_nodes/CMP_idMask.c +/** \file blender/nodes/composite/nodes/node_composite_idMask.c * \ingroup cmpnodes */ -#include "../CMP_util.h" +#include "node_composite_util.h" /* **************** ID Mask ******************** */ -static bNodeSocketType cmp_node_idmask_in[]= { - { SOCK_VALUE, 1, "ID value", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate cmp_node_idmask_in[]= { + { SOCK_FLOAT, 1, "ID value", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f, PROP_NONE}, { -1, 0, "" } }; -static bNodeSocketType cmp_node_idmask_out[]= { - { SOCK_VALUE, 0, "Alpha", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate cmp_node_idmask_out[]= { + { SOCK_FLOAT, 0, "Alpha"}, { -1, 0, "" } }; @@ -113,8 +113,8 @@ void register_node_type_cmp_idmask(ListBase *lb) { static bNodeType ntype; - node_type_base(&ntype, CMP_NODE_ID_MASK, "ID Mask", NODE_CLASS_CONVERTOR, NODE_OPTIONS, - cmp_node_idmask_in, cmp_node_idmask_out); + node_type_base(&ntype, CMP_NODE_ID_MASK, "ID Mask", NODE_CLASS_CONVERTOR, NODE_OPTIONS); + node_type_socket_templates(&ntype, cmp_node_idmask_in, cmp_node_idmask_out); node_type_size(&ntype, 140, 100, 320); node_type_exec(&ntype, node_composit_exec_idmask); diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_image.c b/source/blender/nodes/composite/nodes/node_composite_image.c similarity index 93% rename from source/blender/nodes/intern/CMP_nodes/CMP_image.c rename to source/blender/nodes/composite/nodes/node_composite_image.c index a5f256054cd..1278202d5b5 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_image.c +++ b/source/blender/nodes/composite/nodes/node_composite_image.c @@ -1,5 +1,5 @@ /* - * $Id$ + * $Id: CMP_image.c 36536 2011-05-07 13:27:27Z lukastoenne $ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -27,20 +27,20 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/nodes/intern/CMP_nodes/CMP_image.c +/** \file blender/nodes/composite/nodes/node_composite_image.c * \ingroup cmpnodes */ -#include "../CMP_util.h" +#include "node_composite_util.h" /* **************** IMAGE (and RenderResult, multilayer image) ******************** */ -static bNodeSocketType cmp_node_rlayers_out[]= { +static bNodeSocketTemplate cmp_node_rlayers_out[]= { { SOCK_RGBA, 0, "Image", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, - { SOCK_VALUE, 0, "Alpha", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, - { SOCK_VALUE, 0, "Z", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, + { SOCK_FLOAT, 0, "Alpha", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, + { SOCK_FLOAT, 0, "Z", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, { SOCK_VECTOR, 0, "Normal", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, { SOCK_VECTOR, 0, "UV", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, { SOCK_VECTOR, 0, "Speed", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, @@ -52,9 +52,9 @@ static bNodeSocketType cmp_node_rlayers_out[]= { { SOCK_RGBA, 0, "Reflect", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, { SOCK_RGBA, 0, "Refract", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, { SOCK_RGBA, 0, "Indirect", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, - { SOCK_VALUE, 0, "IndexOB", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, - { SOCK_VALUE, 0, "IndexMA", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, - { SOCK_VALUE, 0, "Mist", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, + { SOCK_FLOAT, 0, "IndexOB", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, + { SOCK_FLOAT, 0, "IndexMA", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, + { SOCK_FLOAT, 0, "Mist", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, { SOCK_RGBA, 0, "Emit", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, { SOCK_RGBA, 0, "Environment",0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, { -1, 0, "" } @@ -74,7 +74,7 @@ static CompBuf *node_composit_get_image(RenderData *rd, Image *ima, ImageUser *i ibuf= BKE_image_get_ibuf(ima, iuser); if(ibuf==NULL || (ibuf->rect==NULL && ibuf->rect_float==NULL)) { - return NULL; + return NULL; } if (ibuf->rect_float == NULL) { @@ -213,7 +213,7 @@ static void outputs_multilayer_get(RenderData *rd, RenderLayer *rl, bNodeStack * if(out[RRES_OUT_INDEXOB]->hasoutput) out[RRES_OUT_INDEXOB]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_INDEXOB); if(out[RRES_OUT_INDEXMA]->hasoutput) - out[RRES_OUT_INDEXMA]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_INDEXMA); + out[RRES_OUT_INDEXMA]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_INDEXMA); if(out[RRES_OUT_MIST]->hasoutput) out[RRES_OUT_MIST]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_MIST); if(out[RRES_OUT_EMIT]->hasoutput) @@ -295,7 +295,7 @@ static void node_composit_exec_image(void *data, bNode *node, bNodeStack **UNUSE } } -static void node_composit_init_image(bNode* node) +static void node_composit_init_image(bNodeTree *UNUSED(ntree), bNode* node, bNodeTemplate *UNUSED(ntemp)) { ImageUser *iuser= MEM_callocN(sizeof(ImageUser), "node image user"); node->storage= iuser; @@ -309,8 +309,8 @@ void register_node_type_cmp_image(ListBase *lb) { static bNodeType ntype; - node_type_base(&ntype, CMP_NODE_IMAGE, "Image", NODE_CLASS_INPUT, NODE_PREVIEW|NODE_OPTIONS, - NULL, cmp_node_rlayers_out); + node_type_base(&ntype, CMP_NODE_IMAGE, "Image", NODE_CLASS_INPUT, NODE_PREVIEW|NODE_OPTIONS); + node_type_socket_templates(&ntype, NULL, cmp_node_rlayers_out); node_type_size(&ntype, 120, 80, 300); node_type_init(&ntype, node_composit_init_image); node_type_storage(&ntype, "ImageUser", node_free_standard_storage, node_copy_standard_storage); @@ -440,8 +440,8 @@ void register_node_type_cmp_rlayers(ListBase *lb) { static bNodeType ntype; - node_type_base(&ntype, CMP_NODE_R_LAYERS, "Render Layers", NODE_CLASS_INPUT, NODE_PREVIEW|NODE_OPTIONS, - NULL, cmp_node_rlayers_out); + node_type_base(&ntype, CMP_NODE_R_LAYERS, "Render Layers", NODE_CLASS_INPUT, NODE_PREVIEW|NODE_OPTIONS); + node_type_socket_templates(&ntype, NULL, cmp_node_rlayers_out); node_type_size(&ntype, 150, 100, 300); node_type_exec(&ntype, node_composit_exec_rlayers); diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_invert.c b/source/blender/nodes/composite/nodes/node_composite_invert.c similarity index 84% rename from source/blender/nodes/intern/CMP_nodes/CMP_invert.c rename to source/blender/nodes/composite/nodes/node_composite_invert.c index 27b0324dfe0..1f7589cae8f 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_invert.c +++ b/source/blender/nodes/composite/nodes/node_composite_invert.c @@ -1,5 +1,5 @@ /* - * $Id$ + * $Id: CMP_invert.c 36593 2011-05-10 11:19:26Z lukastoenne $ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -27,21 +27,21 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/nodes/intern/CMP_nodes/CMP_invert.c +/** \file blender/nodes/composite/nodes/node_composite_invert.c * \ingroup cmpnodes */ -#include "../CMP_util.h" +#include "node_composite_util.h" /* **************** INVERT ******************** */ -static bNodeSocketType cmp_node_invert_in[]= { - { SOCK_VALUE, 1, "Fac", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, - { SOCK_RGBA, 1, "Color", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate cmp_node_invert_in[]= { + { SOCK_FLOAT, 1, "Fac", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR}, + { SOCK_RGBA, 1, "Color", 0.0f, 0.0f, 0.0f, 1.0f}, { -1, 0, "" } }; -static bNodeSocketType cmp_node_invert_out[]= { - { SOCK_RGBA, 0, "Color", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate cmp_node_invert_out[]= { + { SOCK_RGBA, 0, "Color"}, { -1, 0, "" } }; @@ -114,7 +114,7 @@ static void node_composit_exec_invert(void *UNUSED(data), bNode *node, bNodeStac } } -static void node_composit_init_invert(bNode *node) +static void node_composit_init_invert(bNodeTree *UNUSED(ntree), bNode* node, bNodeTemplate *UNUSED(ntemp)) { node->custom1 |= CMP_CHAN_RGB; } @@ -124,8 +124,8 @@ void register_node_type_cmp_invert(ListBase *lb) { static bNodeType ntype; - node_type_base(&ntype, CMP_NODE_INVERT, "Invert", NODE_CLASS_OP_COLOR, NODE_OPTIONS, - cmp_node_invert_in, cmp_node_invert_out); + node_type_base(&ntype, CMP_NODE_INVERT, "Invert", NODE_CLASS_OP_COLOR, NODE_OPTIONS); + node_type_socket_templates(&ntype, cmp_node_invert_in, cmp_node_invert_out); node_type_size(&ntype, 120, 120, 140); node_type_init(&ntype, node_composit_init_invert); node_type_exec(&ntype, node_composit_exec_invert); diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_lensdist.c b/source/blender/nodes/composite/nodes/node_composite_lensdist.c similarity index 90% rename from source/blender/nodes/intern/CMP_nodes/CMP_lensdist.c rename to source/blender/nodes/composite/nodes/node_composite_lensdist.c index 3a005210c6a..85578deecbb 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_lensdist.c +++ b/source/blender/nodes/composite/nodes/node_composite_lensdist.c @@ -26,21 +26,21 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/nodes/intern/CMP_nodes/CMP_lensdist.c +/** \file blender/nodes/composite/nodes/node_composite_lensdist.c * \ingroup cmpnodes */ -#include "../CMP_util.h" +#include "node_composite_util.h" -static bNodeSocketType cmp_node_lensdist_in[]= { - { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, - { SOCK_VALUE, 1, "Distort", 0.f, 0.f, 0.f, 0.f, -0.999f, 1.f}, - { SOCK_VALUE, 1, "Dispersion", 0.f, 0.f, 0.f, 0.f, 0.f, 1.f}, +static bNodeSocketTemplate cmp_node_lensdist_in[]= { + { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f}, + { SOCK_FLOAT, 1, "Distort", 0.f, 0.f, 0.f, 0.f, -0.999f, 1.f, PROP_NONE}, + { SOCK_FLOAT, 1, "Dispersion", 0.f, 0.f, 0.f, 0.f, 0.f, 1.f, PROP_NONE}, { -1, 0, "" } }; -static bNodeSocketType cmp_node_lensdist_out[]= { - { SOCK_RGBA, 0, "Image", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate cmp_node_lensdist_out[]= { + { SOCK_RGBA, 0, "Image"}, { -1, 0, "" } }; @@ -183,7 +183,7 @@ static void node_composit_exec_lensdist(void *UNUSED(data), bNode *node, bNodeSt } -static void node_composit_init_lensdist(bNode* node) +static void node_composit_init_lensdist(bNodeTree *UNUSED(ntree), bNode* node, bNodeTemplate *UNUSED(ntemp)) { NodeLensDist *nld = MEM_callocN(sizeof(NodeLensDist), "node lensdist data"); nld->jit = nld->proj = nld->fit = 0; @@ -195,8 +195,8 @@ void register_node_type_cmp_lensdist(ListBase *lb) { static bNodeType ntype; - node_type_base(&ntype, CMP_NODE_LENSDIST, "Lens Distortion", NODE_CLASS_DISTORT, NODE_OPTIONS, - cmp_node_lensdist_in, cmp_node_lensdist_out); + node_type_base(&ntype, CMP_NODE_LENSDIST, "Lens Distortion", NODE_CLASS_DISTORT, NODE_OPTIONS); + node_type_socket_templates(&ntype, cmp_node_lensdist_in, cmp_node_lensdist_out); node_type_size(&ntype, 150, 120, 200); node_type_init(&ntype, node_composit_init_lensdist); node_type_storage(&ntype, "NodeLensDist", node_free_standard_storage, node_copy_standard_storage); diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_levels.c b/source/blender/nodes/composite/nodes/node_composite_levels.c similarity index 87% rename from source/blender/nodes/intern/CMP_nodes/CMP_levels.c rename to source/blender/nodes/composite/nodes/node_composite_levels.c index 2c9f7d97f09..673ffe4cbef 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_levels.c +++ b/source/blender/nodes/composite/nodes/node_composite_levels.c @@ -1,5 +1,5 @@ /* - * $Id$ + * $Id: CMP_levels.c 36536 2011-05-07 13:27:27Z lukastoenne $ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -27,23 +27,23 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/nodes/intern/CMP_nodes/CMP_levels.c +/** \file blender/nodes/composite/nodes/node_composite_levels.c * \ingroup cmpnodes */ -#include "../CMP_util.h" +#include "node_composite_util.h" /* **************** LEVELS ******************** */ -static bNodeSocketType cmp_node_view_levels_in[]= { - { SOCK_RGBA, 1, "Image", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate cmp_node_view_levels_in[]= { + { SOCK_RGBA, 1, "Image", 0.0f, 0.0f, 0.0f, 1.0f}, { -1, 0, "" } }; -static bNodeSocketType cmp_node_view_levels_out[]={ - {SOCK_VALUE, 0,"Mean",0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, - {SOCK_VALUE, 0,"Std Dev",0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate cmp_node_view_levels_out[]={ + {SOCK_FLOAT, 0,"Mean"}, + {SOCK_FLOAT, 0,"Std Dev"}, {-1,0,""} }; @@ -52,7 +52,7 @@ static void rgb_tobw(float r, float g, float b, float* out) *out= r*0.35f + g*0.45f + b*0.2f; } -static void fill_bins(bNode* node, CompBuf* in, int* bins, int colorcor) +static void fill_bins(bNode* node, CompBuf* in, int* bins) { float value[4]; int ivalue=0; @@ -68,39 +68,29 @@ static void fill_bins(bNode* node, CompBuf* in, int* bins, int colorcor) if(value[3] > 0.0) { /* don't count transparent pixels */ switch(node->custom1) { case 1: { /* all colors */ - if(colorcor) - linearrgb_to_srgb_v3_v3(&value[0],&value[0]); rgb_tobw(value[0],value[1],value[2], &value[0]); value[0]=value[0]*255; /* scale to 0-255 range */ ivalue=(int)value[0]; break; } case 2: { /* red channel */ - if(colorcor) - value[0]=linearrgb_to_srgb(value[0]); value[0]=value[0]*255; /* scale to 0-255 range */ ivalue=(int)value[0]; break; } case 3: { /* green channel */ - if(colorcor) - value[1]=linearrgb_to_srgb(value[1]); value[1]=value[1]*255; /* scale to 0-255 range */ ivalue=(int)value[1]; break; } case 4: /*blue channel */ { - if(colorcor) - value[2]=linearrgb_to_srgb(value[2]); value[2]=value[2]*255; /* scale to 0-255 range */ ivalue=(int)value[2]; break; } case 5: /* luminence */ { - if(colorcor) - linearrgb_to_srgb_v3_v3(&value[0],&value[0]); rgb_to_yuv(value[0],value[1],value[2], &value[0], &value[1], &value[2]); value[0]=value[0]*255; /* scale to 0-255 range */ ivalue=(int)value[0]; @@ -285,7 +275,6 @@ static void node_composit_exec_view_levels(void *data, bNode *node, bNodeStack * { CompBuf* cbuf; CompBuf* histogram; - RenderData *rd=data; float mean, std_dev; int bins[256]; int x; @@ -302,7 +291,7 @@ static void node_composit_exec_view_levels(void *data, bNode *node, bNodeStack * } /*fill bins */ - fill_bins(node, in[0]->data, bins, rd->color_mgt_flag & R_COLOR_MANAGEMENT); + fill_bins(node, in[0]->data, bins); /* draw the histogram chart */ draw_histogram(node, histogram, bins); @@ -328,7 +317,7 @@ static void node_composit_exec_view_levels(void *data, bNode *node, bNodeStack * free_compbuf(histogram); } -static void node_composit_init_view_levels(bNode* node) +static void node_composit_init_view_levels(bNodeTree *UNUSED(ntree), bNode* node, bNodeTemplate *UNUSED(ntemp)) { node->custom1=1; /*All channels*/ } @@ -337,8 +326,8 @@ void register_node_type_cmp_view_levels(ListBase *lb) { static bNodeType ntype; - node_type_base(&ntype, CMP_NODE_VIEW_LEVELS, "Levels", NODE_CLASS_OUTPUT, NODE_OPTIONS|NODE_PREVIEW, - cmp_node_view_levels_in, cmp_node_view_levels_out); + node_type_base(&ntype, CMP_NODE_VIEW_LEVELS, "Levels", NODE_CLASS_OUTPUT, NODE_OPTIONS|NODE_PREVIEW); + node_type_socket_templates(&ntype, cmp_node_view_levels_in, cmp_node_view_levels_out); node_type_size(&ntype, 140, 100, 320); node_type_init(&ntype, node_composit_init_view_levels); node_type_storage(&ntype, "ImageUser", NULL, NULL); diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_lummaMatte.c b/source/blender/nodes/composite/nodes/node_composite_lummaMatte.c similarity index 82% rename from source/blender/nodes/intern/CMP_nodes/CMP_lummaMatte.c rename to source/blender/nodes/composite/nodes/node_composite_lummaMatte.c index 34e58791932..bc7676934fa 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_lummaMatte.c +++ b/source/blender/nodes/composite/nodes/node_composite_lummaMatte.c @@ -1,5 +1,5 @@ /* - * $Id$ + * $Id: CMP_lummaMatte.c 36536 2011-05-07 13:27:27Z lukastoenne $ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -27,23 +27,23 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/nodes/intern/CMP_nodes/CMP_lummaMatte.c +/** \file blender/nodes/composite/nodes/node_composite_lummaMatte.c * \ingroup cmpnodes */ -#include "../CMP_util.h" +#include "node_composite_util.h" /* ******************* Luma Matte Node ********************************* */ -static bNodeSocketType cmp_node_luma_matte_in[]={ - {SOCK_RGBA,1,"Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate cmp_node_luma_matte_in[]={ + {SOCK_RGBA,1,"Image", 0.8f, 0.8f, 0.8f, 1.0f}, {-1,0,""} }; -static bNodeSocketType cmp_node_luma_matte_out[]={ - {SOCK_RGBA,0,"Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, - {SOCK_VALUE,0,"Matte",0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate cmp_node_luma_matte_out[]={ + {SOCK_RGBA,0,"Image"}, + {SOCK_FLOAT,0,"Matte"}, {-1,0,""} }; @@ -100,7 +100,7 @@ static void node_composit_exec_luma_matte(void *data, bNode *node, bNodeStack ** free_compbuf(cbuf); } -static void node_composit_init_luma_matte(bNode *node) +static void node_composit_init_luma_matte(bNodeTree *UNUSED(ntree), bNode* node, bNodeTemplate *UNUSED(ntemp)) { NodeChroma *c= MEM_callocN(sizeof(NodeChroma), "node chroma"); node->storage=c; @@ -112,8 +112,8 @@ void register_node_type_cmp_luma_matte(ListBase *lb) { static bNodeType ntype; - node_type_base(&ntype, CMP_NODE_LUMA_MATTE, "Luminance Key", NODE_CLASS_MATTE, NODE_PREVIEW|NODE_OPTIONS, - cmp_node_luma_matte_in, cmp_node_luma_matte_out); + node_type_base(&ntype, CMP_NODE_LUMA_MATTE, "Luminance Key", NODE_CLASS_MATTE, NODE_PREVIEW|NODE_OPTIONS); + node_type_socket_templates(&ntype, cmp_node_luma_matte_in, cmp_node_luma_matte_out); node_type_size(&ntype, 200, 80, 250); node_type_init(&ntype, node_composit_init_luma_matte); node_type_storage(&ntype, "NodeChroma", node_free_standard_storage, node_copy_standard_storage); diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_mapUV.c b/source/blender/nodes/composite/nodes/node_composite_mapUV.c similarity index 90% rename from source/blender/nodes/intern/CMP_nodes/CMP_mapUV.c rename to source/blender/nodes/composite/nodes/node_composite_mapUV.c index 6b2c561b14a..2d92c26b554 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_mapUV.c +++ b/source/blender/nodes/composite/nodes/node_composite_mapUV.c @@ -1,5 +1,5 @@ /* - * $Id$ + * $Id: CMP_mapUV.c 36593 2011-05-10 11:19:26Z lukastoenne $ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -27,22 +27,22 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/nodes/intern/CMP_nodes/CMP_mapUV.c +/** \file blender/nodes/composite/nodes/node_composite_mapUV.c * \ingroup cmpnodes */ -#include "../CMP_util.h" +#include "node_composite_util.h" /* **************** Map UV ******************** */ -static bNodeSocketType cmp_node_mapuv_in[]= { - { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, - { SOCK_VECTOR, 1, "UV", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate cmp_node_mapuv_in[]= { + { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f}, + { SOCK_VECTOR, 1, "UV", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_NONE}, { -1, 0, "" } }; -static bNodeSocketType cmp_node_mapuv_out[]= { - { SOCK_RGBA, 0, "Image", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate cmp_node_mapuv_out[]= { + { SOCK_RGBA, 0, "Image"}, { -1, 0, "" } }; @@ -168,8 +168,8 @@ void register_node_type_cmp_mapuv(ListBase *lb) { static bNodeType ntype; - node_type_base(&ntype, CMP_NODE_MAP_UV, "Map UV", NODE_CLASS_DISTORT, NODE_OPTIONS, - cmp_node_mapuv_in, cmp_node_mapuv_out); + node_type_base(&ntype, CMP_NODE_MAP_UV, "Map UV", NODE_CLASS_DISTORT, NODE_OPTIONS); + node_type_socket_templates(&ntype, cmp_node_mapuv_in, cmp_node_mapuv_out); node_type_size(&ntype, 140, 100, 320); node_type_exec(&ntype, node_composit_exec_mapuv); diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_mapValue.c b/source/blender/nodes/composite/nodes/node_composite_mapValue.c similarity index 80% rename from source/blender/nodes/intern/CMP_nodes/CMP_mapValue.c rename to source/blender/nodes/composite/nodes/node_composite_mapValue.c index f14e0fbd804..0d38aca4ce3 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_mapValue.c +++ b/source/blender/nodes/composite/nodes/node_composite_mapValue.c @@ -1,5 +1,5 @@ /* - * $Id$ + * $Id: CMP_mapValue.c 36593 2011-05-10 11:19:26Z lukastoenne $ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -27,20 +27,20 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/nodes/intern/CMP_nodes/CMP_mapValue.c +/** \file blender/nodes/composite/nodes/node_composite_mapValue.c * \ingroup cmpnodes */ -#include "../CMP_util.h" +#include "node_composite_util.h" /* **************** MAP VALUE ******************** */ -static bNodeSocketType cmp_node_map_value_in[]= { - { SOCK_VALUE, 1, "Value", 1.0f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate cmp_node_map_value_in[]= { + { SOCK_FLOAT, 1, "Value", 1.0f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f, PROP_NONE}, { -1, 0, "" } }; -static bNodeSocketType cmp_node_map_value_out[]= { - { SOCK_VALUE, 0, "Value", 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate cmp_node_map_value_out[]= { + { SOCK_FLOAT, 0, "Value"}, { -1, 0, "" } }; @@ -79,7 +79,7 @@ static void node_composit_exec_map_value(void *UNUSED(data), bNode *node, bNodeS } -static void node_composit_init_map_value(bNode* node) +static void node_composit_init_map_value(bNodeTree *UNUSED(ntree), bNode* node, bNodeTemplate *UNUSED(ntemp)) { node->storage= add_mapping(); } @@ -88,8 +88,8 @@ void register_node_type_cmp_map_value(ListBase *lb) { static bNodeType ntype; - node_type_base(&ntype, CMP_NODE_MAP_VALUE, "Map Value", NODE_CLASS_OP_VECTOR, NODE_OPTIONS, - cmp_node_map_value_in, cmp_node_map_value_out); + node_type_base(&ntype, CMP_NODE_MAP_VALUE, "Map Value", NODE_CLASS_OP_VECTOR, NODE_OPTIONS); + node_type_socket_templates(&ntype, cmp_node_map_value_in, cmp_node_map_value_out); node_type_size(&ntype, 100, 60, 150); node_type_init(&ntype, node_composit_init_map_value); node_type_storage(&ntype, "TexMapping", node_free_standard_storage, node_copy_standard_storage); diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_math.c b/source/blender/nodes/composite/nodes/node_composite_math.c similarity index 89% rename from source/blender/nodes/intern/CMP_nodes/CMP_math.c rename to source/blender/nodes/composite/nodes/node_composite_math.c index b7a67f3563b..2489491fdd8 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_math.c +++ b/source/blender/nodes/composite/nodes/node_composite_math.c @@ -1,5 +1,5 @@ /* - * $Id$ + * $Id: CMP_math.c 36593 2011-05-10 11:19:26Z lukastoenne $ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -27,22 +27,22 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/nodes/intern/CMP_nodes/CMP_math.c +/** \file blender/nodes/composite/nodes/node_composite_math.c * \ingroup cmpnodes */ -#include "../CMP_util.h" +#include "node_composite_util.h" /* **************** SCALAR MATH ******************** */ -static bNodeSocketType cmp_node_math_in[]= { - { SOCK_VALUE, 1, "Value", 0.5f, 0.5f, 0.5f, 1.0f, -10000.0f, 10000.0f}, - { SOCK_VALUE, 1, "Value", 0.5f, 0.5f, 0.5f, 1.0f, -10000.0f, 10000.0f}, +static bNodeSocketTemplate cmp_node_math_in[]= { + { SOCK_FLOAT, 1, "Value", 0.5f, 0.5f, 0.5f, 1.0f, -10000.0f, 10000.0f, PROP_NONE}, + { SOCK_FLOAT, 1, "Value", 0.5f, 0.5f, 0.5f, 1.0f, -10000.0f, 10000.0f, PROP_NONE}, { -1, 0, "" } }; -static bNodeSocketType cmp_node_math_out[]= { - { SOCK_VALUE, 0, "Value", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate cmp_node_math_out[]= { + { SOCK_FLOAT, 0, "Value"}, { -1, 0, "" } }; @@ -145,7 +145,6 @@ static void do_math(bNode *node, float *out, float *in, float *in2) out[0]= floorf(in[0] / in2[0] + 0.5f) * in2[0]; else out[0]= floorf(in[0] + 0.5f); - } break; case 15: /* Less Than */ @@ -201,8 +200,8 @@ void register_node_type_cmp_math(ListBase *lb) { static bNodeType ntype; - node_type_base(&ntype, CMP_NODE_MATH, "Math", NODE_CLASS_CONVERTOR, NODE_OPTIONS, - cmp_node_math_in, cmp_node_math_out); + node_type_base(&ntype, CMP_NODE_MATH, "Math", NODE_CLASS_CONVERTOR, NODE_OPTIONS); + node_type_socket_templates(&ntype, cmp_node_math_in, cmp_node_math_out); node_type_size(&ntype, 120, 110, 160); node_type_label(&ntype, node_math_label); node_type_exec(&ntype, node_composit_exec_math); diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_mixrgb.c b/source/blender/nodes/composite/nodes/node_composite_mixrgb.c similarity index 81% rename from source/blender/nodes/intern/CMP_nodes/CMP_mixrgb.c rename to source/blender/nodes/composite/nodes/node_composite_mixrgb.c index d2454b37c29..a5dcfcc44da 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_mixrgb.c +++ b/source/blender/nodes/composite/nodes/node_composite_mixrgb.c @@ -1,5 +1,5 @@ /* - * $Id$ + * $Id: CMP_mixrgb.c 36593 2011-05-10 11:19:26Z lukastoenne $ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -27,21 +27,21 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/nodes/intern/CMP_nodes/CMP_mixrgb.c +/** \file blender/nodes/composite/nodes/node_composite_mixrgb.c * \ingroup cmpnodes */ -#include "../CMP_util.h" +#include "node_composite_util.h" /* **************** MIX RGB ******************** */ -static bNodeSocketType cmp_node_mix_rgb_in[]= { - { SOCK_VALUE, 1, "Fac", 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 5.0f}, - { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, - { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate cmp_node_mix_rgb_in[]= { + { SOCK_FLOAT, 1, "Fac", 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 5.0f, PROP_FACTOR}, + { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f}, + { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f}, { -1, 0, "" } }; -static bNodeSocketType cmp_node_mix_rgb_out[]= { - { SOCK_RGBA, 0, "Image", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate cmp_node_mix_rgb_out[]= { + { SOCK_RGBA, 0, "Image"}, { -1, 0, "" } }; @@ -88,8 +88,8 @@ void register_node_type_cmp_mix_rgb(ListBase *lb) { static bNodeType ntype; - node_type_base(&ntype, CMP_NODE_MIX_RGB, "Mix", NODE_CLASS_OP_COLOR, NODE_PREVIEW|NODE_OPTIONS, - cmp_node_mix_rgb_in, cmp_node_mix_rgb_out); + node_type_base(&ntype, CMP_NODE_MIX_RGB, "Mix", NODE_CLASS_OP_COLOR, NODE_PREVIEW|NODE_OPTIONS); + node_type_socket_templates(&ntype, cmp_node_mix_rgb_in, cmp_node_mix_rgb_out); node_type_size(&ntype, 110, 60, 120); node_type_label(&ntype, node_blend_label); node_type_exec(&ntype, node_composit_exec_mix_rgb); diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_normal.c b/source/blender/nodes/composite/nodes/node_composite_normal.c similarity index 72% rename from source/blender/nodes/intern/CMP_nodes/CMP_normal.c rename to source/blender/nodes/composite/nodes/node_composite_normal.c index f53d3041947..5f3c848903c 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_normal.c +++ b/source/blender/nodes/composite/nodes/node_composite_normal.c @@ -1,5 +1,5 @@ /* - * $Id$ + * $Id: CMP_normal.c 36593 2011-05-10 11:19:26Z lukastoenne $ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -27,30 +27,30 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/nodes/intern/CMP_nodes/CMP_normal.c +/** \file blender/nodes/composite/nodes/node_composite_normal.c * \ingroup cmpnodes */ -#include "../CMP_util.h" +#include "node_composite_util.h" /* **************** NORMAL ******************** */ -static bNodeSocketType cmp_node_normal_in[]= { - { SOCK_VECTOR, 1, "Normal", 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f}, +static bNodeSocketTemplate cmp_node_normal_in[]= { + { SOCK_VECTOR, 1, "Normal", 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, PROP_DIRECTION}, { -1, 0, "" } }; -static bNodeSocketType cmp_node_normal_out[]= { - { SOCK_VECTOR, 0, "Normal", 0.0f, 0.0f, 1.0f, 1.0f, -1.0f, 1.0f}, - { SOCK_VALUE, 0, "Dot", 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate cmp_node_normal_out[]= { + { SOCK_VECTOR, 0, "Normal"}, + { SOCK_FLOAT, 0, "Dot"}, { -1, 0, "" } }; static void do_normal(bNode *node, float *out, float *in) { bNodeSocket *sock= node->outputs.first; - float *nor= sock->ns.vec; + float *nor= ((bNodeSocketValueVector*)sock->default_value)->value; /* render normals point inside... the widget points outside */ out[0]= -INPR(nor, in); @@ -60,12 +60,13 @@ static void do_normal(bNode *node, float *out, float *in) static void node_composit_exec_normal(void *UNUSED(data), bNode *node, bNodeStack **in, bNodeStack **out) { bNodeSocket *sock= node->outputs.first; + float *nor= ((bNodeSocketValueVector*)sock->default_value)->value; /* stack order input: normal */ /* stack order output: normal, value */ /* input no image? then only vector op */ if(in[0]->data==NULL) { - VECCOPY(out[0]->vec, sock->ns.vec); + VECCOPY(out[0]->vec, nor); /* render normals point inside... the widget points outside */ out[1]->vec[0]= -INPR(out[0]->vec, in[0]->vec); } @@ -82,12 +83,23 @@ static void node_composit_exec_normal(void *UNUSED(data), bNode *node, bNodeStac } +static void init(bNodeTree *UNUSED(ntree), bNode *node, bNodeTemplate *UNUSED(ntemp)) +{ + bNodeSocket *sock= node->outputs.first; + float *nor= ((bNodeSocketValueVector*)sock->default_value)->value; + + nor[0] = 0.0f; + nor[1] = 0.0f; + nor[2] = 1.0f; +} + void register_node_type_cmp_normal(ListBase *lb) { static bNodeType ntype; - node_type_base(&ntype, CMP_NODE_NORMAL, "Normal", NODE_CLASS_OP_VECTOR, NODE_OPTIONS, - cmp_node_normal_in, cmp_node_normal_out); + node_type_base(&ntype, CMP_NODE_NORMAL, "Normal", NODE_CLASS_OP_VECTOR, NODE_OPTIONS); + node_type_socket_templates(&ntype, cmp_node_normal_in, cmp_node_normal_out); + node_type_init(&ntype, init); node_type_size(&ntype, 100, 60, 200); node_type_exec(&ntype, node_composit_exec_normal); diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_normalize.c b/source/blender/nodes/composite/nodes/node_composite_normalize.c similarity index 86% rename from source/blender/nodes/intern/CMP_nodes/CMP_normalize.c rename to source/blender/nodes/composite/nodes/node_composite_normalize.c index 22ebd924f09..1c5c3b57b80 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_normalize.c +++ b/source/blender/nodes/composite/nodes/node_composite_normalize.c @@ -1,5 +1,5 @@ /* - * $Id$ + * $Id: CMP_normalize.c 36593 2011-05-10 11:19:26Z lukastoenne $ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -27,21 +27,21 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/nodes/intern/CMP_nodes/CMP_normalize.c +/** \file blender/nodes/composite/nodes/node_composite_normalize.c * \ingroup cmpnodes */ -#include "../CMP_util.h" +#include "node_composite_util.h" /* **************** NORMALIZE single channel, useful for Z buffer ******************** */ -static bNodeSocketType cmp_node_normalize_in[]= { - { SOCK_VALUE, 1, "Value", 1.0f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate cmp_node_normalize_in[]= { + { SOCK_FLOAT, 1, "Value", 1.0f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f, PROP_NONE}, { -1, 0, "" } }; -static bNodeSocketType cmp_node_normalize_out[]= { - { SOCK_VALUE, 0, "Value", 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate cmp_node_normalize_out[]= { + { SOCK_FLOAT, 0, "Value"}, { -1, 0, "" } }; @@ -107,8 +107,8 @@ void register_node_type_cmp_normalize(ListBase *lb) { static bNodeType ntype; - node_type_base(&ntype, CMP_NODE_NORMALIZE, "Normalize", NODE_CLASS_OP_VECTOR, NODE_OPTIONS, - cmp_node_normalize_in, cmp_node_normalize_out); + node_type_base(&ntype, CMP_NODE_NORMALIZE, "Normalize", NODE_CLASS_OP_VECTOR, NODE_OPTIONS); + node_type_socket_templates(&ntype, cmp_node_normalize_in, cmp_node_normalize_out); node_type_size(&ntype, 100, 60, 150); node_type_exec(&ntype, node_composit_exec_normalize); node_type_storage(&ntype, "TexMapping", NULL, NULL); diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_outputFile.c b/source/blender/nodes/composite/nodes/node_composite_outputFile.c similarity index 85% rename from source/blender/nodes/intern/CMP_nodes/CMP_outputFile.c rename to source/blender/nodes/composite/nodes/node_composite_outputFile.c index 1d52e694ea9..13391a4a790 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_outputFile.c +++ b/source/blender/nodes/composite/nodes/node_composite_outputFile.c @@ -1,5 +1,5 @@ /* - * $Id$ + * $Id: CMP_outputFile.c 36593 2011-05-10 11:19:26Z lukastoenne $ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -27,17 +27,17 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/nodes/intern/CMP_nodes/CMP_outputFile.c +/** \file blender/nodes/composite/nodes/node_composite_outputFile.c * \ingroup cmpnodes */ -#include "../CMP_util.h" +#include "node_composite_util.h" /* **************** OUTPUT FILE ******************** */ -static bNodeSocketType cmp_node_output_file_in[]= { - { SOCK_RGBA, 1, "Image", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, - { SOCK_VALUE, 1, "Z", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate cmp_node_output_file_in[]= { + { SOCK_RGBA, 1, "Image", 0.0f, 0.0f, 0.0f, 1.0f}, + { SOCK_FLOAT, 1, "Z", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, PROP_NONE}, { -1, 0, "" } }; @@ -93,7 +93,7 @@ static void node_composit_exec_output_file(void *data, bNode *node, bNodeStack * } } -static void node_composit_init_output_file(bNode *node) +static void node_composit_init_output_file(bNodeTree *UNUSED(ntree), bNode* node, bNodeTemplate *UNUSED(ntemp)) { Scene *scene= (Scene *)node->id; NodeImageFile *nif= MEM_callocN(sizeof(NodeImageFile), "node image file"); @@ -113,8 +113,8 @@ void register_node_type_cmp_output_file(ListBase *lb) { static bNodeType ntype; - node_type_base(&ntype, CMP_NODE_OUTPUT_FILE, "File Output", NODE_CLASS_OUTPUT, NODE_PREVIEW|NODE_OPTIONS, - cmp_node_output_file_in, NULL); + node_type_base(&ntype, CMP_NODE_OUTPUT_FILE, "File Output", NODE_CLASS_OUTPUT, NODE_PREVIEW|NODE_OPTIONS); + node_type_socket_templates(&ntype, cmp_node_output_file_in, NULL); node_type_size(&ntype, 140, 80, 300); node_type_init(&ntype, node_composit_init_output_file); node_type_storage(&ntype, "NodeImageFile", node_free_standard_storage, node_copy_standard_storage); diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_premulkey.c b/source/blender/nodes/composite/nodes/node_composite_premulkey.c similarity index 79% rename from source/blender/nodes/intern/CMP_nodes/CMP_premulkey.c rename to source/blender/nodes/composite/nodes/node_composite_premulkey.c index 15d2ac25180..066a8a81891 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_premulkey.c +++ b/source/blender/nodes/composite/nodes/node_composite_premulkey.c @@ -1,5 +1,5 @@ /* -* $Id$ +* $Id: CMP_premulkey.c 36333 2011-04-26 09:27:43Z lukastoenne $ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -28,21 +28,21 @@ */ -/** \file blender/nodes/intern/CMP_nodes/CMP_premulkey.c +/** \file blender/nodes/composite/nodes/node_composite_premulkey.c * \ingroup cmpnodes */ -#include "../CMP_util.h" +#include "node_composite_util.h" /* **************** Premul and Key Alpha Convert ******************** */ -static bNodeSocketType cmp_node_premulkey_in[]= { - { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate cmp_node_premulkey_in[]= { + { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f}, { -1, 0, "" } }; -static bNodeSocketType cmp_node_premulkey_out[]= { - { SOCK_RGBA, 0, "Image", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate cmp_node_premulkey_out[]= { + { SOCK_RGBA, 0, "Image"}, { -1, 0, "" } }; @@ -67,8 +67,8 @@ void register_node_type_cmp_premulkey(ListBase *lb) { static bNodeType ntype; - node_type_base(&ntype, CMP_NODE_PREMULKEY, "Alpha Convert", NODE_CLASS_CONVERTOR, NODE_OPTIONS, - cmp_node_premulkey_in, cmp_node_premulkey_out); + node_type_base(&ntype, CMP_NODE_PREMULKEY, "Alpha Convert", NODE_CLASS_CONVERTOR, NODE_OPTIONS); + node_type_socket_templates(&ntype, cmp_node_premulkey_in, cmp_node_premulkey_out); node_type_size(&ntype, 140, 100, 320); node_type_exec(&ntype, node_composit_exec_premulkey); diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_rgb.c b/source/blender/nodes/composite/nodes/node_composite_rgb.c similarity index 64% rename from source/blender/nodes/intern/CMP_nodes/CMP_rgb.c rename to source/blender/nodes/composite/nodes/node_composite_rgb.c index 36b7988c4e0..41a13487edd 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_rgb.c +++ b/source/blender/nodes/composite/nodes/node_composite_rgb.c @@ -1,5 +1,5 @@ /* - * $Id$ + * $Id: CMP_rgb.c 36333 2011-04-26 09:27:43Z lukastoenne $ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -27,33 +27,46 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/nodes/intern/CMP_nodes/CMP_rgb.c +/** \file blender/nodes/composite/nodes/node_composite_rgb.c * \ingroup cmpnodes */ -#include "../CMP_util.h" +#include "node_composite_util.h" /* **************** RGB ******************** */ -static bNodeSocketType cmp_node_rgb_out[]= { - { SOCK_RGBA, 0, "RGBA", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate cmp_node_rgb_out[]= { + { SOCK_RGBA, 0, "RGBA", 0.8f, 0.8f, 0.8f, 1.0f}, { -1, 0, "" } }; +static void node_composit_init_rgb(bNodeTree *UNUSED(ntree), bNode *node, bNodeTemplate *UNUSED(ntemp)) +{ + bNodeSocket *sock= node->outputs.first; + float *col= ((bNodeSocketValueRGBA*)sock->default_value)->value; + /* uses the default value of the output socket, must be initialized here */ + col[0] = 0.5f; + col[1] = 0.5f; + col[2] = 0.5f; + col[3] = 1.0f; +} + static void node_composit_exec_rgb(void *UNUSED(data), bNode *node, bNodeStack **UNUSED(in), bNodeStack **out) { bNodeSocket *sock= node->outputs.first; + float *col= ((bNodeSocketValueRGBA*)sock->default_value)->value; - QUATCOPY(out[0]->vec, sock->ns.vec); + QUATCOPY(out[0]->vec, col); } void register_node_type_cmp_rgb(ListBase *lb) { static bNodeType ntype; - node_type_base(&ntype, CMP_NODE_RGB, "RGB", NODE_CLASS_INPUT, NODE_OPTIONS, - NULL, cmp_node_rgb_out); + node_type_base(&ntype, CMP_NODE_RGB, "RGB", NODE_CLASS_INPUT, NODE_OPTIONS); + node_type_socket_templates(&ntype, NULL, cmp_node_rgb_out); + node_type_init(&ntype, node_composit_init_rgb); node_type_size(&ntype, 140, 80, 140); node_type_exec(&ntype, node_composit_exec_rgb); diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_rotate.c b/source/blender/nodes/composite/nodes/node_composite_rotate.c similarity index 83% rename from source/blender/nodes/intern/CMP_nodes/CMP_rotate.c rename to source/blender/nodes/composite/nodes/node_composite_rotate.c index eccac4f0e6d..4ece562c508 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_rotate.c +++ b/source/blender/nodes/composite/nodes/node_composite_rotate.c @@ -1,5 +1,5 @@ /* - * $Id$ + * $Id: CMP_rotate.c 36593 2011-05-10 11:19:26Z lukastoenne $ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -27,22 +27,22 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/nodes/intern/CMP_nodes/CMP_rotate.c +/** \file blender/nodes/composite/nodes/node_composite_rotate.c * \ingroup cmpnodes */ -#include "../CMP_util.h" +#include "node_composite_util.h" /* **************** Rotate ******************** */ -static bNodeSocketType cmp_node_rotate_in[]= { - { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, - { SOCK_VALUE, 1, "Degr", 0.0f, 0.0f, 0.0f, 0.0f, -10000.0f, 10000.0f}, +static bNodeSocketTemplate cmp_node_rotate_in[]= { + { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f}, + { SOCK_FLOAT, 1, "Degr", 0.0f, 0.0f, 0.0f, 0.0f, -10000.0f, 10000.0f, PROP_ANGLE}, { -1, 0, "" } }; -static bNodeSocketType cmp_node_rotate_out[]= { - { SOCK_RGBA, 0, "Image", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate cmp_node_rotate_out[]= { + { SOCK_RGBA, 0, "Image"}, { -1, 0, "" } }; @@ -122,7 +122,7 @@ static void node_composit_exec_rotate(void *UNUSED(data), bNode *node, bNodeStac } } -static void node_composit_init_rotate(bNode *node) +static void node_composit_init_rotate(bNodeTree *UNUSED(ntree), bNode* node, bNodeTemplate *UNUSED(ntemp)) { node->custom1= 1; /* Bilinear Filter*/ } @@ -131,8 +131,8 @@ void register_node_type_cmp_rotate(ListBase *lb) { static bNodeType ntype; - node_type_base(&ntype, CMP_NODE_ROTATE, "Rotate", NODE_CLASS_DISTORT, NODE_OPTIONS, - cmp_node_rotate_in, cmp_node_rotate_out); + node_type_base(&ntype, CMP_NODE_ROTATE, "Rotate", NODE_CLASS_DISTORT, NODE_OPTIONS); + node_type_socket_templates(&ntype, cmp_node_rotate_in, cmp_node_rotate_out); node_type_size(&ntype, 140, 100, 320); node_type_init(&ntype, node_composit_init_rotate); node_type_exec(&ntype, node_composit_exec_rotate); diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_scale.c b/source/blender/nodes/composite/nodes/node_composite_scale.c similarity index 84% rename from source/blender/nodes/intern/CMP_nodes/CMP_scale.c rename to source/blender/nodes/composite/nodes/node_composite_scale.c index b6030cc5a5f..4ba654e82d4 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_scale.c +++ b/source/blender/nodes/composite/nodes/node_composite_scale.c @@ -1,5 +1,5 @@ /* - * $Id$ + * $Id: CMP_scale.c 36593 2011-05-10 11:19:26Z lukastoenne $ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -27,25 +27,25 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/nodes/intern/CMP_nodes/CMP_scale.c +/** \file blender/nodes/composite/nodes/node_composite_scale.c * \ingroup cmpnodes */ -#include "../CMP_util.h" +#include "node_composite_util.h" /* **************** Scale ******************** */ #define CMP_SCALE_MAX 12000 -static bNodeSocketType cmp_node_scale_in[]= { - { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, - { SOCK_VALUE, 1, "X", 1.0f, 0.0f, 0.0f, 0.0f, 0.0001f, CMP_SCALE_MAX}, - { SOCK_VALUE, 1, "Y", 1.0f, 0.0f, 0.0f, 0.0f, 0.0001f, CMP_SCALE_MAX}, +static bNodeSocketTemplate cmp_node_scale_in[]= { + { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f}, + { SOCK_FLOAT, 1, "X", 1.0f, 0.0f, 0.0f, 0.0f, 0.0001f, CMP_SCALE_MAX, PROP_FACTOR}, + { SOCK_FLOAT, 1, "Y", 1.0f, 0.0f, 0.0f, 0.0f, 0.0001f, CMP_SCALE_MAX, PROP_FACTOR}, { -1, 0, "" } }; -static bNodeSocketType cmp_node_scale_out[]= { - { SOCK_RGBA, 0, "Image", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate cmp_node_scale_out[]= { + { SOCK_RGBA, 0, "Image"}, { -1, 0, "" } }; @@ -118,8 +118,8 @@ void register_node_type_cmp_scale(ListBase *lb) { static bNodeType ntype; - node_type_base(&ntype, CMP_NODE_SCALE, "Scale", NODE_CLASS_DISTORT, NODE_OPTIONS, - cmp_node_scale_in, cmp_node_scale_out); + node_type_base(&ntype, CMP_NODE_SCALE, "Scale", NODE_CLASS_DISTORT, NODE_OPTIONS); + node_type_socket_templates(&ntype, cmp_node_scale_in, cmp_node_scale_out); node_type_size(&ntype, 140, 100, 320); node_type_exec(&ntype, node_composit_exec_scale); diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_sepcombHSVA.c b/source/blender/nodes/composite/nodes/node_composite_sepcombHSVA.c similarity index 80% rename from source/blender/nodes/intern/CMP_nodes/CMP_sepcombHSVA.c rename to source/blender/nodes/composite/nodes/node_composite_sepcombHSVA.c index 87c4ed1dac0..5460427fd73 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_sepcombHSVA.c +++ b/source/blender/nodes/composite/nodes/node_composite_sepcombHSVA.c @@ -1,5 +1,5 @@ /* - * $Id$ + * $Id: CMP_sepcombHSVA.c 36593 2011-05-10 11:19:26Z lukastoenne $ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -27,24 +27,24 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/nodes/intern/CMP_nodes/CMP_sepcombHSVA.c +/** \file blender/nodes/composite/nodes/node_composite_sepcombHSVA.c * \ingroup cmpnodes */ -#include "../CMP_util.h" +#include "node_composite_util.h" /* **************** SEPARATE HSVA ******************** */ -static bNodeSocketType cmp_node_sephsva_in[]= { - { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate cmp_node_sephsva_in[]= { + { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f}, { -1, 0, "" } }; -static bNodeSocketType cmp_node_sephsva_out[]= { - { SOCK_VALUE, 0, "H", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, - { SOCK_VALUE, 0, "S", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, - { SOCK_VALUE, 0, "V", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, - { SOCK_VALUE, 0, "A", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate cmp_node_sephsva_out[]= { + { SOCK_FLOAT, 0, "H"}, + { SOCK_FLOAT, 0, "S"}, + { SOCK_FLOAT, 0, "V"}, + { SOCK_FLOAT, 0, "A"}, { -1, 0, "" } }; @@ -105,8 +105,8 @@ void register_node_type_cmp_sephsva(ListBase *lb) { static bNodeType ntype; - node_type_base(&ntype, CMP_NODE_SEPHSVA, "Separate HSVA", NODE_CLASS_CONVERTOR, 0, - cmp_node_sephsva_in, cmp_node_sephsva_out); + node_type_base(&ntype, CMP_NODE_SEPHSVA, "Separate HSVA", NODE_CLASS_CONVERTOR, 0); + node_type_socket_templates(&ntype, cmp_node_sephsva_in, cmp_node_sephsva_out); node_type_size(&ntype, 80, 40, 140); node_type_exec(&ntype, node_composit_exec_sephsva); @@ -115,15 +115,15 @@ void register_node_type_cmp_sephsva(ListBase *lb) /* **************** COMBINE HSVA ******************** */ -static bNodeSocketType cmp_node_combhsva_in[]= { - { SOCK_VALUE, 1, "H", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, - { SOCK_VALUE, 1, "S", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, - { SOCK_VALUE, 1, "V", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, - { SOCK_VALUE, 1, "A", 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate cmp_node_combhsva_in[]= { + { SOCK_FLOAT, 1, "H", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, PROP_NONE}, + { SOCK_FLOAT, 1, "S", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, PROP_NONE}, + { SOCK_FLOAT, 1, "V", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, PROP_NONE}, + { SOCK_FLOAT, 1, "A", 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, PROP_NONE}, { -1, 0, "" } }; -static bNodeSocketType cmp_node_combhsva_out[]= { - { SOCK_RGBA, 0, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate cmp_node_combhsva_out[]= { + { SOCK_RGBA, 0, "Image"}, { -1, 0, "" } }; @@ -175,8 +175,8 @@ void register_node_type_cmp_combhsva(ListBase *lb) { static bNodeType ntype; - node_type_base(&ntype, CMP_NODE_COMBHSVA, "Combine HSVA", NODE_CLASS_CONVERTOR, NODE_OPTIONS, - cmp_node_combhsva_in, cmp_node_combhsva_out); + node_type_base(&ntype, CMP_NODE_COMBHSVA, "Combine HSVA", NODE_CLASS_CONVERTOR, NODE_OPTIONS); + node_type_socket_templates(&ntype, cmp_node_combhsva_in, cmp_node_combhsva_out); node_type_size(&ntype, 80, 40, 140); node_type_exec(&ntype, node_composit_exec_combhsva); diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_sepcombRGBA.c b/source/blender/nodes/composite/nodes/node_composite_sepcombRGBA.c similarity index 78% rename from source/blender/nodes/intern/CMP_nodes/CMP_sepcombRGBA.c rename to source/blender/nodes/composite/nodes/node_composite_sepcombRGBA.c index 11afd1eaaef..a074d895acb 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_sepcombRGBA.c +++ b/source/blender/nodes/composite/nodes/node_composite_sepcombRGBA.c @@ -1,5 +1,5 @@ /* - * $Id$ + * $Id: CMP_sepcombRGBA.c 36593 2011-05-10 11:19:26Z lukastoenne $ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -27,23 +27,23 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/nodes/intern/CMP_nodes/CMP_sepcombRGBA.c +/** \file blender/nodes/composite/nodes/node_composite_sepcombRGBA.c * \ingroup cmpnodes */ -#include "../CMP_util.h" +#include "node_composite_util.h" /* **************** SEPARATE RGBA ******************** */ -static bNodeSocketType cmp_node_seprgba_in[]= { - { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate cmp_node_seprgba_in[]= { + { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f}, { -1, 0, "" } }; -static bNodeSocketType cmp_node_seprgba_out[]= { - { SOCK_VALUE, 0, "R", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, - { SOCK_VALUE, 0, "G", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, - { SOCK_VALUE, 0, "B", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, - { SOCK_VALUE, 0, "A", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate cmp_node_seprgba_out[]= { + { SOCK_FLOAT, 0, "R"}, + { SOCK_FLOAT, 0, "G"}, + { SOCK_FLOAT, 0, "B"}, + { SOCK_FLOAT, 0, "A"}, { -1, 0, "" } }; @@ -83,8 +83,8 @@ void register_node_type_cmp_seprgba(ListBase *lb) { static bNodeType ntype; - node_type_base(&ntype, CMP_NODE_SEPRGBA, "Separate RGBA", NODE_CLASS_CONVERTOR, 0, - cmp_node_seprgba_in, cmp_node_seprgba_out); + node_type_base(&ntype, CMP_NODE_SEPRGBA, "Separate RGBA", NODE_CLASS_CONVERTOR, 0); + node_type_socket_templates(&ntype, cmp_node_seprgba_in, cmp_node_seprgba_out); node_type_size(&ntype, 80, 40, 140); node_type_exec(&ntype, node_composit_exec_seprgba); @@ -94,15 +94,15 @@ void register_node_type_cmp_seprgba(ListBase *lb) /* **************** COMBINE RGBA ******************** */ -static bNodeSocketType cmp_node_combrgba_in[]= { - { SOCK_VALUE, 1, "R", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, - { SOCK_VALUE, 1, "G", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, - { SOCK_VALUE, 1, "B", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, - { SOCK_VALUE, 1, "A", 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate cmp_node_combrgba_in[]= { + { SOCK_FLOAT, 1, "R", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, PROP_NONE}, + { SOCK_FLOAT, 1, "G", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, PROP_NONE}, + { SOCK_FLOAT, 1, "B", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, PROP_NONE}, + { SOCK_FLOAT, 1, "A", 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, PROP_NONE}, { -1, 0, "" } }; -static bNodeSocketType cmp_node_combrgba_out[]= { - { SOCK_RGBA, 0, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate cmp_node_combrgba_out[]= { + { SOCK_RGBA, 0, "Image"}, { -1, 0, "" } }; @@ -151,8 +151,8 @@ void register_node_type_cmp_combrgba(ListBase *lb) { static bNodeType ntype; - node_type_base(&ntype, CMP_NODE_COMBRGBA, "Combine RGBA", NODE_CLASS_CONVERTOR, NODE_OPTIONS, - cmp_node_combrgba_in, cmp_node_combrgba_out); + node_type_base(&ntype, CMP_NODE_COMBRGBA, "Combine RGBA", NODE_CLASS_CONVERTOR, NODE_OPTIONS); + node_type_socket_templates(&ntype, cmp_node_combrgba_in, cmp_node_combrgba_out); node_type_size(&ntype, 80, 40, 140); node_type_exec(&ntype, node_composit_exec_combrgba); diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_sepcombYCCA.c b/source/blender/nodes/composite/nodes/node_composite_sepcombYCCA.c similarity index 87% rename from source/blender/nodes/intern/CMP_nodes/CMP_sepcombYCCA.c rename to source/blender/nodes/composite/nodes/node_composite_sepcombYCCA.c index 81591602dae..61e88418e59 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_sepcombYCCA.c +++ b/source/blender/nodes/composite/nodes/node_composite_sepcombYCCA.c @@ -1,5 +1,5 @@ /* - * $Id$ + * $Id: CMP_sepcombYCCA.c 36593 2011-05-10 11:19:26Z lukastoenne $ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -27,24 +27,24 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/nodes/intern/CMP_nodes/CMP_sepcombYCCA.c +/** \file blender/nodes/composite/nodes/node_composite_sepcombYCCA.c * \ingroup cmpnodes */ -#include "../CMP_util.h" +#include "node_composite_util.h" /* **************** SEPARATE YCCA ******************** */ -static bNodeSocketType cmp_node_sepycca_in[]= { - { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate cmp_node_sepycca_in[]= { + { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f}, { -1, 0, "" } }; -static bNodeSocketType cmp_node_sepycca_out[]= { - { SOCK_VALUE, 0, "Y", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, - { SOCK_VALUE, 0, "Cb", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, - { SOCK_VALUE, 0, "Cr", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, - { SOCK_VALUE, 0, "A", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate cmp_node_sepycca_out[]= { + { SOCK_FLOAT, 0, "Y"}, + { SOCK_FLOAT, 0, "Cb"}, + { SOCK_FLOAT, 0, "Cr"}, + { SOCK_FLOAT, 0, "A"}, { -1, 0, "" } }; @@ -154,8 +154,8 @@ void register_node_type_cmp_sepycca(ListBase *lb) { static bNodeType ntype; - node_type_base(&ntype, CMP_NODE_SEPYCCA, "Separate YCbCrA", NODE_CLASS_CONVERTOR, NODE_OPTIONS, - cmp_node_sepycca_in, cmp_node_sepycca_out); + node_type_base(&ntype, CMP_NODE_SEPYCCA, "Separate YCbCrA", NODE_CLASS_CONVERTOR, NODE_OPTIONS); + node_type_socket_templates(&ntype, cmp_node_sepycca_in, cmp_node_sepycca_out); node_type_size(&ntype, 80, 40, 140); node_type_exec(&ntype, node_composit_exec_sepycca); @@ -165,15 +165,15 @@ void register_node_type_cmp_sepycca(ListBase *lb) /* **************** COMBINE YCCA ******************** */ -static bNodeSocketType cmp_node_combycca_in[]= { - { SOCK_VALUE, 1, "Y", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, - { SOCK_VALUE, 1, "Cb", 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, - { SOCK_VALUE, 1, "Cr", 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, - { SOCK_VALUE, 1, "A", 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate cmp_node_combycca_in[]= { + { SOCK_FLOAT, 1, "Y", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, PROP_NONE}, + { SOCK_FLOAT, 1, "Cb", 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, PROP_NONE}, + { SOCK_FLOAT, 1, "Cr", 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, PROP_NONE}, + { SOCK_FLOAT, 1, "A", 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, PROP_NONE}, { -1, 0, "" } }; -static bNodeSocketType cmp_node_combycca_out[]= { - { SOCK_RGBA, 0, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate cmp_node_combycca_out[]= { + { SOCK_RGBA, 0, "Image"}, { -1, 0, "" } }; @@ -301,8 +301,8 @@ void register_node_type_cmp_combycca(ListBase *lb) { static bNodeType ntype; - node_type_base(&ntype, CMP_NODE_COMBYCCA, "Combine YCbCrA", NODE_CLASS_CONVERTOR, NODE_OPTIONS, - cmp_node_combycca_in, cmp_node_combycca_out); + node_type_base(&ntype, CMP_NODE_COMBYCCA, "Combine YCbCrA", NODE_CLASS_CONVERTOR, NODE_OPTIONS); + node_type_socket_templates(&ntype, cmp_node_combycca_in, cmp_node_combycca_out); node_type_size(&ntype, 80, 40, 140); node_type_exec(&ntype, node_composit_exec_combycca); diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_sepcombYUVA.c b/source/blender/nodes/composite/nodes/node_composite_sepcombYUVA.c similarity index 80% rename from source/blender/nodes/intern/CMP_nodes/CMP_sepcombYUVA.c rename to source/blender/nodes/composite/nodes/node_composite_sepcombYUVA.c index 8687e307df3..14f086300c0 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_sepcombYUVA.c +++ b/source/blender/nodes/composite/nodes/node_composite_sepcombYUVA.c @@ -1,5 +1,5 @@ /* - * $Id$ + * $Id: CMP_sepcombYUVA.c 36593 2011-05-10 11:19:26Z lukastoenne $ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -27,24 +27,24 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/nodes/intern/CMP_nodes/CMP_sepcombYUVA.c +/** \file blender/nodes/composite/nodes/node_composite_sepcombYUVA.c * \ingroup cmpnodes */ -#include "../CMP_util.h" +#include "node_composite_util.h" /* **************** SEPARATE YUVA ******************** */ -static bNodeSocketType cmp_node_sepyuva_in[]= { - { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate cmp_node_sepyuva_in[]= { + { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f}, { -1, 0, "" } }; -static bNodeSocketType cmp_node_sepyuva_out[]= { - { SOCK_VALUE, 0, "Y", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, - { SOCK_VALUE, 0, "U", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, - { SOCK_VALUE, 0, "V", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, - { SOCK_VALUE, 0, "A", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate cmp_node_sepyuva_out[]= { + { SOCK_FLOAT, 0, "Y"}, + { SOCK_FLOAT, 0, "U"}, + { SOCK_FLOAT, 0, "V"}, + { SOCK_FLOAT, 0, "A"}, { -1, 0, "" } }; @@ -105,8 +105,8 @@ void register_node_type_cmp_sepyuva(ListBase *lb) { static bNodeType ntype; - node_type_base(&ntype, CMP_NODE_SEPYUVA, "Separate YUVA", NODE_CLASS_CONVERTOR, 0, - cmp_node_sepyuva_in, cmp_node_sepyuva_out); + node_type_base(&ntype, CMP_NODE_SEPYUVA, "Separate YUVA", NODE_CLASS_CONVERTOR, 0); + node_type_socket_templates(&ntype, cmp_node_sepyuva_in, cmp_node_sepyuva_out); node_type_size(&ntype, 80, 40, 140); node_type_exec(&ntype, node_composit_exec_sepyuva); @@ -116,15 +116,15 @@ void register_node_type_cmp_sepyuva(ListBase *lb) /* **************** COMBINE YUVA ******************** */ -static bNodeSocketType cmp_node_combyuva_in[]= { - { SOCK_VALUE, 1, "Y", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, - { SOCK_VALUE, 1, "U", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, - { SOCK_VALUE, 1, "V", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, - { SOCK_VALUE, 1, "A", 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate cmp_node_combyuva_in[]= { + { SOCK_FLOAT, 1, "Y", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, PROP_NONE}, + { SOCK_FLOAT, 1, "U", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, PROP_NONE}, + { SOCK_FLOAT, 1, "V", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, PROP_NONE}, + { SOCK_FLOAT, 1, "A", 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, PROP_NONE}, { -1, 0, "" } }; -static bNodeSocketType cmp_node_combyuva_out[]= { - { SOCK_RGBA, 0, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate cmp_node_combyuva_out[]= { + { SOCK_RGBA, 0, "Image"}, { -1, 0, "" } }; @@ -176,8 +176,8 @@ void register_node_type_cmp_combyuva(ListBase *lb) { static bNodeType ntype; - node_type_base(&ntype, CMP_NODE_COMBYUVA, "Combine YUVA", NODE_CLASS_CONVERTOR, NODE_OPTIONS, - cmp_node_combyuva_in, cmp_node_combyuva_out); + node_type_base(&ntype, CMP_NODE_COMBYUVA, "Combine YUVA", NODE_CLASS_CONVERTOR, NODE_OPTIONS); + node_type_socket_templates(&ntype, cmp_node_combyuva_in, cmp_node_combyuva_out); node_type_size(&ntype, 80, 40, 140); node_type_exec(&ntype, node_composit_exec_combyuva); diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_setalpha.c b/source/blender/nodes/composite/nodes/node_composite_setalpha.c similarity index 81% rename from source/blender/nodes/intern/CMP_nodes/CMP_setalpha.c rename to source/blender/nodes/composite/nodes/node_composite_setalpha.c index bb8533a79f6..781d6f11614 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_setalpha.c +++ b/source/blender/nodes/composite/nodes/node_composite_setalpha.c @@ -1,5 +1,5 @@ /* - * $Id$ + * $Id: CMP_setalpha.c 36593 2011-05-10 11:19:26Z lukastoenne $ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -27,21 +27,21 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/nodes/intern/CMP_nodes/CMP_setalpha.c +/** \file blender/nodes/composite/nodes/node_composite_setalpha.c * \ingroup cmpnodes */ -#include "../CMP_util.h" +#include "node_composite_util.h" /* **************** SET ALPHA ******************** */ -static bNodeSocketType cmp_node_setalpha_in[]= { - { SOCK_RGBA, 1, "Image", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, - { SOCK_VALUE, 1, "Alpha", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate cmp_node_setalpha_in[]= { + { SOCK_RGBA, 1, "Image", 0.0f, 0.0f, 0.0f, 1.0f}, + { SOCK_FLOAT, 1, "Alpha", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_NONE}, { -1, 0, "" } }; -static bNodeSocketType cmp_node_setalpha_out[]= { - { SOCK_RGBA, 0, "Image", 0.0f, 0.0f, 1.0f, 1.0f, -1.0f, 1.0f}, +static bNodeSocketTemplate cmp_node_setalpha_out[]= { + { SOCK_RGBA, 0, "Image"}, { -1, 0, "" } }; @@ -79,8 +79,8 @@ void register_node_type_cmp_setalpha(ListBase *lb) { static bNodeType ntype; - node_type_base(&ntype, CMP_NODE_SETALPHA, "Set Alpha", NODE_CLASS_CONVERTOR, NODE_OPTIONS, - cmp_node_setalpha_in, cmp_node_setalpha_out); + node_type_base(&ntype, CMP_NODE_SETALPHA, "Set Alpha", NODE_CLASS_CONVERTOR, NODE_OPTIONS); + node_type_socket_templates(&ntype, cmp_node_setalpha_in, cmp_node_setalpha_out); node_type_size(&ntype, 120, 40, 140); node_type_exec(&ntype, node_composit_exec_setalpha); diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_splitViewer.c b/source/blender/nodes/composite/nodes/node_composite_splitViewer.c similarity index 88% rename from source/blender/nodes/intern/CMP_nodes/CMP_splitViewer.c rename to source/blender/nodes/composite/nodes/node_composite_splitViewer.c index 13cb3bcfed5..d78faf69e26 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_splitViewer.c +++ b/source/blender/nodes/composite/nodes/node_composite_splitViewer.c @@ -1,5 +1,5 @@ /* - * $Id$ + * $Id: CMP_splitViewer.c 36340 2011-04-26 13:24:20Z lukastoenne $ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -27,17 +27,17 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/nodes/intern/CMP_nodes/CMP_splitViewer.c +/** \file blender/nodes/composite/nodes/node_composite_splitViewer.c * \ingroup cmpnodes */ -#include "../CMP_util.h" +#include "node_composite_util.h" /* **************** SPLIT VIEWER ******************** */ -static bNodeSocketType cmp_node_splitviewer_in[]= { - { SOCK_RGBA, 1, "Image", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, - { SOCK_RGBA, 1, "Image", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate cmp_node_splitviewer_in[]= { + { SOCK_RGBA, 1, "Image", 0.0f, 0.0f, 0.0f, 1.0f}, + { SOCK_RGBA, 1, "Image", 0.0f, 0.0f, 0.0f, 1.0f}, { -1, 0, "" } }; @@ -141,7 +141,7 @@ static void node_composit_exec_splitviewer(void *data, bNode *node, bNodeStack * } } -static void node_composit_init_splitviewer(bNode* node) +static void node_composit_init_splitviewer(bNodeTree *UNUSED(ntree), bNode* node, bNodeTemplate *UNUSED(ntemp)) { ImageUser *iuser= MEM_callocN(sizeof(ImageUser), "node image user"); node->storage= iuser; @@ -155,8 +155,8 @@ void register_node_type_cmp_splitviewer(ListBase *lb) { static bNodeType ntype; - node_type_base(&ntype, CMP_NODE_SPLITVIEWER, "SplitViewer", NODE_CLASS_OUTPUT, NODE_PREVIEW|NODE_OPTIONS, - cmp_node_splitviewer_in, NULL); + node_type_base(&ntype, CMP_NODE_SPLITVIEWER, "SplitViewer", NODE_CLASS_OUTPUT, NODE_PREVIEW|NODE_OPTIONS); + node_type_socket_templates(&ntype, cmp_node_splitviewer_in, NULL); node_type_size(&ntype, 140, 100, 320); node_type_init(&ntype, node_composit_init_splitviewer); node_type_storage(&ntype, "ImageUser", node_free_standard_storage, node_copy_standard_storage); diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_texture.c b/source/blender/nodes/composite/nodes/node_composite_texture.c similarity index 90% rename from source/blender/nodes/intern/CMP_nodes/CMP_texture.c rename to source/blender/nodes/composite/nodes/node_composite_texture.c index 46e71b8b8e5..bdeef74c617 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_texture.c +++ b/source/blender/nodes/composite/nodes/node_composite_texture.c @@ -1,5 +1,5 @@ /* - * $Id$ + * $Id: CMP_texture.c 36593 2011-05-10 11:19:26Z lukastoenne $ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -27,22 +27,22 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/nodes/intern/CMP_nodes/CMP_texture.c +/** \file blender/nodes/composite/nodes/node_composite_texture.c * \ingroup cmpnodes */ -#include "../CMP_util.h" +#include "node_composite_util.h" /* **************** TEXTURE ******************** */ -static bNodeSocketType cmp_node_texture_in[]= { - { SOCK_VECTOR, 1, "Offset", 0.0f, 0.0f, 0.0f, 0.0f, -2.0f, 2.0f}, - { SOCK_VECTOR, 1, "Scale", 1.0f, 1.0f, 1.0f, 1.0f, -10.0f, 10.0f}, +static bNodeSocketTemplate cmp_node_texture_in[]= { + { SOCK_VECTOR, 1, "Offset", 0.0f, 0.0f, 0.0f, 0.0f, -2.0f, 2.0f, PROP_TRANSLATION}, + { SOCK_VECTOR, 1, "Scale", 1.0f, 1.0f, 1.0f, 1.0f, -10.0f, 10.0f, PROP_XYZ}, { -1, 0, "" } }; -static bNodeSocketType cmp_node_texture_out[]= { - { SOCK_VALUE, 0, "Value", 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, - { SOCK_RGBA , 0, "Color", 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate cmp_node_texture_out[]= { + { SOCK_FLOAT, 0, "Value"}, + { SOCK_RGBA , 0, "Color"}, { -1, 0, "" } }; @@ -148,8 +148,8 @@ void register_node_type_cmp_texture(ListBase *lb) { static bNodeType ntype; - node_type_base(&ntype, CMP_NODE_TEXTURE, "Texture", NODE_CLASS_INPUT, NODE_OPTIONS|NODE_PREVIEW, - cmp_node_texture_in, cmp_node_texture_out); + node_type_base(&ntype, CMP_NODE_TEXTURE, "Texture", NODE_CLASS_INPUT, NODE_OPTIONS|NODE_PREVIEW); + node_type_socket_templates(&ntype, cmp_node_texture_in, cmp_node_texture_out); node_type_size(&ntype, 120, 80, 240); node_type_exec(&ntype, node_composit_exec_texture); diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_tonemap.c b/source/blender/nodes/composite/nodes/node_composite_tonemap.c similarity index 91% rename from source/blender/nodes/intern/CMP_nodes/CMP_tonemap.c rename to source/blender/nodes/composite/nodes/node_composite_tonemap.c index f15811ec790..31ffed08c95 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_tonemap.c +++ b/source/blender/nodes/composite/nodes/node_composite_tonemap.c @@ -26,19 +26,19 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/nodes/intern/CMP_nodes/CMP_tonemap.c +/** \file blender/nodes/composite/nodes/node_composite_tonemap.c * \ingroup cmpnodes */ -#include "../CMP_util.h" +#include "node_composite_util.h" -static bNodeSocketType cmp_node_tonemap_in[]= { - { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate cmp_node_tonemap_in[]= { + { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f}, { -1, 0, "" } }; -static bNodeSocketType cmp_node_tonemap_out[]= { - { SOCK_RGBA, 0, "Image", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate cmp_node_tonemap_out[]= { + { SOCK_RGBA, 0, "Image"}, { -1, 0, "" } }; @@ -147,7 +147,7 @@ static void node_composit_exec_tonemap(void *UNUSED(data), bNode *node, bNodeSta free_compbuf(img); } -static void node_composit_init_tonemap(bNode* node) +static void node_composit_init_tonemap(bNodeTree *UNUSED(ntree), bNode* node, bNodeTemplate *UNUSED(ntemp)) { NodeTonemap *ntm = MEM_callocN(sizeof(NodeTonemap), "node tonemap data"); ntm->type = 1; @@ -167,8 +167,8 @@ void register_node_type_cmp_tonemap(ListBase *lb) { static bNodeType ntype; - node_type_base(&ntype, CMP_NODE_TONEMAP, "Tonemap", NODE_CLASS_OP_COLOR, NODE_OPTIONS, - cmp_node_tonemap_in, cmp_node_tonemap_out); + node_type_base(&ntype, CMP_NODE_TONEMAP, "Tonemap", NODE_CLASS_OP_COLOR, NODE_OPTIONS); + node_type_socket_templates(&ntype, cmp_node_tonemap_in, cmp_node_tonemap_out); node_type_size(&ntype, 150, 120, 200); node_type_init(&ntype, node_composit_init_tonemap); node_type_storage(&ntype, "NodeTonemap", node_free_standard_storage, node_copy_standard_storage); diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_translate.c b/source/blender/nodes/composite/nodes/node_composite_translate.c similarity index 73% rename from source/blender/nodes/intern/CMP_nodes/CMP_translate.c rename to source/blender/nodes/composite/nodes/node_composite_translate.c index eb69523e7a9..a07dfb936ae 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_translate.c +++ b/source/blender/nodes/composite/nodes/node_composite_translate.c @@ -1,5 +1,5 @@ /* - * $Id$ + * $Id: CMP_translate.c 36593 2011-05-10 11:19:26Z lukastoenne $ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -27,24 +27,24 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/nodes/intern/CMP_nodes/CMP_translate.c +/** \file blender/nodes/composite/nodes/node_composite_translate.c * \ingroup cmpnodes */ -#include "../CMP_util.h" +#include "node_composite_util.h" /* **************** Translate ******************** */ -static bNodeSocketType cmp_node_translate_in[]= { - { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, - { SOCK_VALUE, 1, "X", 0.0f, 0.0f, 0.0f, 0.0f, -10000.0f, 10000.0f}, - { SOCK_VALUE, 1, "Y", 0.0f, 0.0f, 0.0f, 0.0f, -10000.0f, 10000.0f}, +static bNodeSocketTemplate cmp_node_translate_in[]= { + { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f}, + { SOCK_FLOAT, 1, "X", 0.0f, 0.0f, 0.0f, 0.0f, -10000.0f, 10000.0f, PROP_NONE}, + { SOCK_FLOAT, 1, "Y", 0.0f, 0.0f, 0.0f, 0.0f, -10000.0f, 10000.0f, PROP_NONE}, { -1, 0, "" } }; -static bNodeSocketType cmp_node_translate_out[]= { - { SOCK_RGBA, 0, "Image", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate cmp_node_translate_out[]= { + { SOCK_RGBA, 0, "Image"}, { -1, 0, "" } }; @@ -65,8 +65,8 @@ void register_node_type_cmp_translate(ListBase *lb) { static bNodeType ntype; - node_type_base(&ntype, CMP_NODE_TRANSLATE, "Translate", NODE_CLASS_DISTORT, NODE_OPTIONS, - cmp_node_translate_in, cmp_node_translate_out); + node_type_base(&ntype, CMP_NODE_TRANSLATE, "Translate", NODE_CLASS_DISTORT, NODE_OPTIONS); + node_type_socket_templates(&ntype, cmp_node_translate_in, cmp_node_translate_out); node_type_size(&ntype, 140, 100, 320); node_type_exec(&ntype, node_composit_exec_translate); diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_valToRgb.c b/source/blender/nodes/composite/nodes/node_composite_valToRgb.c similarity index 80% rename from source/blender/nodes/intern/CMP_nodes/CMP_valToRgb.c rename to source/blender/nodes/composite/nodes/node_composite_valToRgb.c index 1e1c8c61b46..9481d769557 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_valToRgb.c +++ b/source/blender/nodes/composite/nodes/node_composite_valToRgb.c @@ -1,5 +1,5 @@ /* - * $Id$ + * $Id: CMP_valToRgb.c 36593 2011-05-10 11:19:26Z lukastoenne $ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -27,22 +27,22 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/nodes/intern/CMP_nodes/CMP_valToRgb.c +/** \file blender/nodes/composite/nodes/node_composite_valToRgb.c * \ingroup cmpnodes */ -#include "../CMP_util.h" +#include "node_composite_util.h" /* **************** VALTORGB ******************** */ -static bNodeSocketType cmp_node_valtorgb_in[]= { - { SOCK_VALUE, 1, "Fac", 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate cmp_node_valtorgb_in[]= { + { SOCK_FLOAT, 1, "Fac", 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR}, { -1, 0, "" } }; -static bNodeSocketType cmp_node_valtorgb_out[]= { - { SOCK_RGBA, 0, "Image", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, - { SOCK_VALUE, 0, "Alpha", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate cmp_node_valtorgb_out[]= { + { SOCK_RGBA, 0, "Image"}, + { SOCK_FLOAT, 0, "Alpha"}, { -1, 0, "" } }; @@ -80,7 +80,7 @@ static void node_composit_exec_valtorgb(void *UNUSED(data), bNode *node, bNodeSt } } -static void node_composit_init_valtorgb(bNode* node) +static void node_composit_init_valtorgb(bNodeTree *UNUSED(ntree), bNode* node, bNodeTemplate *UNUSED(ntemp)) { node->storage= add_colorband(1); } @@ -89,8 +89,8 @@ void register_node_type_cmp_valtorgb(ListBase *lb) { static bNodeType ntype; - node_type_base(&ntype, CMP_NODE_VALTORGB, "ColorRamp", NODE_CLASS_CONVERTOR, NODE_OPTIONS, - cmp_node_valtorgb_in, cmp_node_valtorgb_out); + node_type_base(&ntype, CMP_NODE_VALTORGB, "ColorRamp", NODE_CLASS_CONVERTOR, NODE_OPTIONS); + node_type_socket_templates(&ntype, cmp_node_valtorgb_in, cmp_node_valtorgb_out); node_type_size(&ntype, 240, 200, 300); node_type_init(&ntype, node_composit_init_valtorgb); node_type_storage(&ntype, "ColorBand", node_free_standard_storage, node_copy_standard_storage); @@ -102,12 +102,12 @@ void register_node_type_cmp_valtorgb(ListBase *lb) /* **************** RGBTOBW ******************** */ -static bNodeSocketType cmp_node_rgbtobw_in[]= { +static bNodeSocketTemplate cmp_node_rgbtobw_in[]= { { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, { -1, 0, "" } }; -static bNodeSocketType cmp_node_rgbtobw_out[]= { - { SOCK_VALUE, 0, "Val", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate cmp_node_rgbtobw_out[]= { + { SOCK_FLOAT, 0, "Val", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, { -1, 0, "" } }; @@ -143,8 +143,8 @@ void register_node_type_cmp_rgbtobw(ListBase *lb) { static bNodeType ntype; - node_type_base(&ntype, CMP_NODE_RGBTOBW, "RGB to BW", NODE_CLASS_CONVERTOR, 0, - cmp_node_rgbtobw_in, cmp_node_rgbtobw_out); + node_type_base(&ntype, CMP_NODE_RGBTOBW, "RGB to BW", NODE_CLASS_CONVERTOR, 0); + node_type_socket_templates(&ntype, cmp_node_rgbtobw_in, cmp_node_rgbtobw_out); node_type_size(&ntype, 80, 40, 120); node_type_exec(&ntype, node_composit_exec_rgbtobw); diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_value.c b/source/blender/nodes/composite/nodes/node_composite_value.c similarity index 65% rename from source/blender/nodes/intern/CMP_nodes/CMP_value.c rename to source/blender/nodes/composite/nodes/node_composite_value.c index 46762065bb4..e99b665f2ae 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_value.c +++ b/source/blender/nodes/composite/nodes/node_composite_value.c @@ -1,5 +1,5 @@ /* - * $Id$ + * $Id: CMP_value.c 36536 2011-05-07 13:27:27Z lukastoenne $ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -27,32 +27,42 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/nodes/intern/CMP_nodes/CMP_value.c +/** \file blender/nodes/composite/nodes/node_composite_value.c * \ingroup cmpnodes */ -#include "../CMP_util.h" +#include "node_composite_util.h" /* **************** VALUE ******************** */ -static bNodeSocketType cmp_node_value_out[]= { - { SOCK_VALUE, 0, "Value", 0.5f, 0.0f, 0.0f, 0.0f, -10000.0f, 10000.0f}, +static bNodeSocketTemplate cmp_node_value_out[]= { + { SOCK_FLOAT, 0, "Value"}, { -1, 0, "" } }; +static void node_composit_init_value(bNodeTree *UNUSED(ntree), bNode *node, bNodeTemplate *UNUSED(ntemp)) +{ + bNodeSocket *sock= node->outputs.first; + bNodeSocketValueFloat *dval= (bNodeSocketValueFloat*)sock->default_value; + /* uses the default value of the output socket, must be initialized here */ + dval->value = 0.5f; +} + static void node_composit_exec_value(void *UNUSED(data), bNode *node, bNodeStack **UNUSED(in), bNodeStack **out) { bNodeSocket *sock= node->outputs.first; + float val= ((bNodeSocketValueFloat*)sock->default_value)->value; - out[0]->vec[0]= sock->ns.vec[0]; + out[0]->vec[0]= val; } void register_node_type_cmp_value(ListBase *lb) { static bNodeType ntype; - node_type_base(&ntype, CMP_NODE_VALUE, "Value", NODE_CLASS_INPUT, NODE_OPTIONS, - NULL, cmp_node_value_out); + node_type_base(&ntype, CMP_NODE_VALUE, "Value", NODE_CLASS_INPUT, NODE_OPTIONS); + node_type_socket_templates(&ntype, NULL, cmp_node_value_out); + node_type_init(&ntype, node_composit_init_value); node_type_size(&ntype, 80, 40, 120); node_type_exec(&ntype, node_composit_exec_value); diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_vecBlur.c b/source/blender/nodes/composite/nodes/node_composite_vecBlur.c similarity index 81% rename from source/blender/nodes/intern/CMP_nodes/CMP_vecBlur.c rename to source/blender/nodes/composite/nodes/node_composite_vecBlur.c index c43bfa2435a..e730728d077 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_vecBlur.c +++ b/source/blender/nodes/composite/nodes/node_composite_vecBlur.c @@ -1,5 +1,5 @@ /* - * $Id$ + * $Id: CMP_vecBlur.c 36593 2011-05-10 11:19:26Z lukastoenne $ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -27,23 +27,23 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/nodes/intern/CMP_nodes/CMP_vecBlur.c +/** \file blender/nodes/composite/nodes/node_composite_vecBlur.c * \ingroup cmpnodes */ -#include "../CMP_util.h" +#include "node_composite_util.h" /* **************** VECTOR BLUR ******************** */ -static bNodeSocketType cmp_node_vecblur_in[]= { - { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, - { SOCK_VALUE, 1, "Z", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, - { SOCK_VECTOR, 1, "Speed", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate cmp_node_vecblur_in[]= { + { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f}, + { SOCK_FLOAT, 1, "Z", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_NONE}, + { SOCK_VECTOR, 1, "Speed", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_VELOCITY}, { -1, 0, "" } }; -static bNodeSocketType cmp_node_vecblur_out[]= { - { SOCK_RGBA, 0, "Image", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate cmp_node_vecblur_out[]= { + { SOCK_RGBA, 0, "Image"}, { -1, 0, "" } }; @@ -87,7 +87,7 @@ static void node_composit_exec_vecblur(void *UNUSED(data), bNode *node, bNodeSta free_compbuf(img); } -static void node_composit_init_vecblur(bNode* node) +static void node_composit_init_vecblur(bNodeTree *UNUSED(ntree), bNode* node, bNodeTemplate *UNUSED(ntemp)) { NodeBlurData *nbd= MEM_callocN(sizeof(NodeBlurData), "node blur data"); node->storage= nbd; @@ -100,8 +100,8 @@ void register_node_type_cmp_vecblur(ListBase *lb) { static bNodeType ntype; - node_type_base(&ntype, CMP_NODE_VECBLUR, "Vector Blur", NODE_CLASS_OP_FILTER, NODE_OPTIONS, - cmp_node_vecblur_in, cmp_node_vecblur_out); + node_type_base(&ntype, CMP_NODE_VECBLUR, "Vector Blur", NODE_CLASS_OP_FILTER, NODE_OPTIONS); + node_type_socket_templates(&ntype, cmp_node_vecblur_in, cmp_node_vecblur_out); node_type_size(&ntype, 120, 80, 200); node_type_init(&ntype, node_composit_init_vecblur); node_type_storage(&ntype, "NodeBlurData", node_free_standard_storage, node_copy_standard_storage); diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_viewer.c b/source/blender/nodes/composite/nodes/node_composite_viewer.c similarity index 86% rename from source/blender/nodes/intern/CMP_nodes/CMP_viewer.c rename to source/blender/nodes/composite/nodes/node_composite_viewer.c index c4e719efbf9..bcfb45411f1 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_viewer.c +++ b/source/blender/nodes/composite/nodes/node_composite_viewer.c @@ -1,5 +1,5 @@ /* - * $Id$ + * $Id: CMP_viewer.c 36593 2011-05-10 11:19:26Z lukastoenne $ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -27,19 +27,19 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/nodes/intern/CMP_nodes/CMP_viewer.c +/** \file blender/nodes/composite/nodes/node_composite_viewer.c * \ingroup cmpnodes */ -#include "../CMP_util.h" +#include "node_composite_util.h" /* **************** VIEWER ******************** */ -static bNodeSocketType cmp_node_viewer_in[]= { - { SOCK_RGBA, 1, "Image", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, - { SOCK_VALUE, 1, "Alpha", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, - { SOCK_VALUE, 1, "Z", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate cmp_node_viewer_in[]= { + { SOCK_RGBA, 1, "Image", 0.0f, 0.0f, 0.0f, 1.0f}, + { SOCK_FLOAT, 1, "Alpha", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_NONE}, + { SOCK_FLOAT, 1, "Z", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_NONE}, { -1, 0, "" } }; @@ -124,7 +124,7 @@ static void node_composit_exec_viewer(void *data, bNode *node, bNodeStack **in, } } -static void node_composit_init_viewer(bNode* node) +static void node_composit_init_viewer(bNodeTree *UNUSED(ntree), bNode* node, bNodeTemplate *UNUSED(ntemp)) { ImageUser *iuser= MEM_callocN(sizeof(ImageUser), "node image user"); node->storage= iuser; @@ -137,8 +137,8 @@ void register_node_type_cmp_viewer(ListBase *lb) { static bNodeType ntype; - node_type_base(&ntype, CMP_NODE_VIEWER, "Viewer", NODE_CLASS_OUTPUT, NODE_PREVIEW, - cmp_node_viewer_in, NULL); + node_type_base(&ntype, CMP_NODE_VIEWER, "Viewer", NODE_CLASS_OUTPUT, NODE_PREVIEW); + node_type_socket_templates(&ntype, cmp_node_viewer_in, NULL); node_type_size(&ntype, 80, 60, 200); node_type_init(&ntype, node_composit_init_viewer); node_type_storage(&ntype, "ImageUser", node_free_standard_storage, node_copy_standard_storage); @@ -146,5 +146,3 @@ void register_node_type_cmp_viewer(ListBase *lb) nodeRegisterType(lb, &ntype); } - - diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_zcombine.c b/source/blender/nodes/composite/nodes/node_composite_zcombine.c similarity index 89% rename from source/blender/nodes/intern/CMP_nodes/CMP_zcombine.c rename to source/blender/nodes/composite/nodes/node_composite_zcombine.c index 0fae0fcd4d5..dfed26be343 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_zcombine.c +++ b/source/blender/nodes/composite/nodes/node_composite_zcombine.c @@ -1,5 +1,5 @@ /* - * $Id$ + * $Id: CMP_zcombine.c 36593 2011-05-10 11:19:26Z lukastoenne $ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -27,26 +27,26 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/nodes/intern/CMP_nodes/CMP_zcombine.c +/** \file blender/nodes/composite/nodes/node_composite_zcombine.c * \ingroup cmpnodes */ -#include "../CMP_util.h" +#include "node_composite_util.h" /* **************** Z COMBINE ******************** */ /* lazy coder note: node->custom2 is abused to send signal */ -static bNodeSocketType cmp_node_zcombine_in[]= { - { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, - { SOCK_VALUE, 1, "Z", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 10000.0f}, - { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, - { SOCK_VALUE, 1, "Z", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 10000.0f}, +static bNodeSocketTemplate cmp_node_zcombine_in[]= { + { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f}, + { SOCK_FLOAT, 1, "Z", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 10000.0f, PROP_NONE}, + { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f}, + { SOCK_FLOAT, 1, "Z", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 10000.0f, PROP_NONE}, { -1, 0, "" } }; -static bNodeSocketType cmp_node_zcombine_out[]= { - { SOCK_RGBA, 0, "Image", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, - { SOCK_VALUE, 0, "Z", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 10000.0f}, +static bNodeSocketTemplate cmp_node_zcombine_out[]= { + { SOCK_RGBA, 0, "Image"}, + { SOCK_FLOAT, 0, "Z"}, { -1, 0, "" } }; @@ -228,8 +228,8 @@ void register_node_type_cmp_zcombine(ListBase *lb) { static bNodeType ntype; - node_type_base(&ntype, CMP_NODE_ZCOMBINE, "Z Combine", NODE_CLASS_OP_COLOR, NODE_OPTIONS, - cmp_node_zcombine_in, cmp_node_zcombine_out); + node_type_base(&ntype, CMP_NODE_ZCOMBINE, "Z Combine", NODE_CLASS_OP_COLOR, NODE_OPTIONS); + node_type_socket_templates(&ntype, cmp_node_zcombine_in, cmp_node_zcombine_out); node_type_size(&ntype, 80, 40, 120); node_type_exec(&ntype, node_composit_exec_zcombine); diff --git a/source/blender/nodes/intern/SHD_util.c b/source/blender/nodes/intern/SHD_util.c deleted file mode 100644 index 190f68ce19a..00000000000 --- a/source/blender/nodes/intern/SHD_util.c +++ /dev/null @@ -1,219 +0,0 @@ -/* - * $Id$ - * - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2005 Blender Foundation. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/nodes/intern/SHD_util.c - * \ingroup nodes - */ - - -#include "SHD_util.h" - - - - - -/* ****** */ - -void nodestack_get_vec(float *in, short type_in, bNodeStack *ns) -{ - float *from= ns->vec; - - if(type_in==SOCK_VALUE) { - if(ns->sockettype==SOCK_VALUE) - *in= *from; - else - *in= 0.333333f*(from[0]+from[1]+from[2]); - } - else if(type_in==SOCK_VECTOR) { - if(ns->sockettype==SOCK_VALUE) { - in[0]= from[0]; - in[1]= from[0]; - in[2]= from[0]; - } - else { - VECCOPY(in, from); - } - } - else { /* type_in==SOCK_RGBA */ - if(ns->sockettype==SOCK_RGBA) { - QUATCOPY(in, from); - } - else if(ns->sockettype==SOCK_VALUE) { - in[0]= from[0]; - in[1]= from[0]; - in[2]= from[0]; - in[3]= 1.0f; - } - else { - VECCOPY(in, from); - in[3]= 1.0f; - } - } -} - - -/* ******************* execute and parse ************ */ - -void ntreeShaderExecTree(bNodeTree *ntree, ShadeInput *shi, ShadeResult *shr) -{ - ShaderCallData scd; - /* - @note: preserve material from ShadeInput for material id, nodetree execs change it - fix for bug "[#28012] Mat ID messy with shader nodes" - */ - Material *mat = shi->mat; - /* convert caller data to struct */ - scd.shi= shi; - scd.shr= shr; - - /* each material node has own local shaderesult, with optional copying */ - memset(shr, 0, sizeof(ShadeResult)); - - ntreeExecTree(ntree, &scd, shi->thread); /* threads */ - // @note: set material back to preserved material - shi->mat = mat; - /* better not allow negative for now */ - if(shr->combined[0]<0.0f) shr->combined[0]= 0.0f; - if(shr->combined[1]<0.0f) shr->combined[1]= 0.0f; - if(shr->combined[2]<0.0f) shr->combined[2]= 0.0f; - -} - -/* go over all used Geometry and Texture nodes, and return a texco flag */ -/* no group inside needed, this function is called for groups too */ -void ntreeShaderGetTexcoMode(bNodeTree *ntree, int r_mode, short *texco, int *mode) -{ - bNode *node; - bNodeSocket *sock; - int a; - - ntreeSocketUseFlags(ntree); - - for(node= ntree->nodes.first; node; node= node->next) { - if(node->type==SH_NODE_TEXTURE) { - if((r_mode & R_OSA) && node->id) { - Tex *tex= (Tex *)node->id; - if ELEM3(tex->type, TEX_IMAGE, TEX_PLUGIN, TEX_ENVMAP) - *texco |= TEXCO_OSA|NEED_UV; - } - /* usability exception... without input we still give the node orcos */ - sock= node->inputs.first; - if(sock==NULL || sock->link==NULL) - *texco |= TEXCO_ORCO|NEED_UV; - } - else if(node->type==SH_NODE_GEOMETRY) { - /* note; sockets always exist for the given type! */ - for(a=0, sock= node->outputs.first; sock; sock= sock->next, a++) { - if(sock->flag & SOCK_IN_USE) { - switch(a) { - case GEOM_OUT_GLOB: - *texco |= TEXCO_GLOB|NEED_UV; break; - case GEOM_OUT_VIEW: - *texco |= TEXCO_VIEW|NEED_UV; break; - case GEOM_OUT_ORCO: - *texco |= TEXCO_ORCO|NEED_UV; break; - case GEOM_OUT_UV: - *texco |= TEXCO_UV|NEED_UV; break; - case GEOM_OUT_NORMAL: - *texco |= TEXCO_NORM|NEED_UV; break; - case GEOM_OUT_VCOL: - *texco |= NEED_UV; *mode |= MA_VERTEXCOL; break; - } - } - } - } - } -} - -/* nodes that use ID data get synced with local data */ -void nodeShaderSynchronizeID(bNode *node, int copyto) -{ - if(node->id==NULL) return; - - if(ELEM(node->type, SH_NODE_MATERIAL, SH_NODE_MATERIAL_EXT)) { - bNodeSocket *sock; - Material *ma= (Material *)node->id; - int a; - - /* hrmf, case in loop isnt super fast, but we dont edit 100s of material at same time either! */ - for(a=0, sock= node->inputs.first; sock; sock= sock->next, a++) { - if(!(sock->flag & SOCK_HIDDEN)) { - if(copyto) { - switch(a) { - case MAT_IN_COLOR: - VECCOPY(&ma->r, sock->ns.vec); break; - case MAT_IN_SPEC: - VECCOPY(&ma->specr, sock->ns.vec); break; - case MAT_IN_REFL: - ma->ref= sock->ns.vec[0]; break; - case MAT_IN_MIR: - VECCOPY(&ma->mirr, sock->ns.vec); break; - case MAT_IN_AMB: - ma->amb= sock->ns.vec[0]; break; - case MAT_IN_EMIT: - ma->emit= sock->ns.vec[0]; break; - case MAT_IN_SPECTRA: - ma->spectra= sock->ns.vec[0]; break; - case MAT_IN_RAY_MIRROR: - ma->ray_mirror= sock->ns.vec[0]; break; - case MAT_IN_ALPHA: - ma->alpha= sock->ns.vec[0]; break; - case MAT_IN_TRANSLUCENCY: - ma->translucency= sock->ns.vec[0]; break; - } - } - else { - switch(a) { - case MAT_IN_COLOR: - VECCOPY(sock->ns.vec, &ma->r); break; - case MAT_IN_SPEC: - VECCOPY(sock->ns.vec, &ma->specr); break; - case MAT_IN_REFL: - sock->ns.vec[0]= ma->ref; break; - case MAT_IN_MIR: - VECCOPY(sock->ns.vec, &ma->mirr); break; - case MAT_IN_AMB: - sock->ns.vec[0]= ma->amb; break; - case MAT_IN_EMIT: - sock->ns.vec[0]= ma->emit; break; - case MAT_IN_SPECTRA: - sock->ns.vec[0]= ma->spectra; break; - case MAT_IN_RAY_MIRROR: - sock->ns.vec[0]= ma->ray_mirror; break; - case MAT_IN_ALPHA: - sock->ns.vec[0]= ma->alpha; break; - case MAT_IN_TRANSLUCENCY: - sock->ns.vec[0]= ma->translucency; break; - } - } - } - } - } - -} diff --git a/source/blender/nodes/intern/node_common.c b/source/blender/nodes/intern/node_common.c new file mode 100644 index 00000000000..76203c52293 --- /dev/null +++ b/source/blender/nodes/intern/node_common.c @@ -0,0 +1,982 @@ +/** + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2007 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): Lukas Toenne. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/nodes/intern/node_common.c + * \ingroup nodes + */ + + +#include + +#include "DNA_action_types.h" +#include "DNA_anim_types.h" +#include "DNA_node_types.h" + +#include "BLI_listbase.h" +#include "BLI_string.h" +#include "BLI_utildefines.h" + +#include "BKE_action.h" +#include "BKE_animsys.h" +#include "BKE_global.h" +#include "BKE_library.h" +#include "BKE_main.h" +#include "BLI_math.h" +#include "BKE_node.h" +#include "BKE_utildefines.h" + +#include "RNA_access.h" +#include "RNA_types.h" + +#include "MEM_guardedalloc.h" + +#include "node_common.h" +#include "node_exec.h" +#include "NOD_socket.h" + +/**** Group ****/ + +bNodeSocket *node_group_find_input(bNode *gnode, bNodeSocket *gsock) +{ + bNodeSocket *sock; + for (sock=gnode->inputs.first; sock; sock=sock->next) + if (sock->groupsock == gsock) + return sock; + return NULL; +} + +bNodeSocket *node_group_find_output(bNode *gnode, bNodeSocket *gsock) +{ + bNodeSocket *sock; + for (sock=gnode->outputs.first; sock; sock=sock->next) + if (sock->groupsock == gsock) + return sock; + return NULL; +} + +bNodeSocket *node_group_add_extern_socket(bNodeTree *UNUSED(ntree), ListBase *lb, int in_out, bNodeSocket *gsock) +{ + bNodeSocket *sock; + + if (gsock->flag & SOCK_INTERNAL) + return NULL; + + sock= MEM_callocN(sizeof(bNodeSocket), "sock"); + + /* make a copy of the group socket */ + *sock = *gsock; + sock->link = NULL; + sock->next = sock->prev = NULL; + sock->new_sock = NULL; + + /* group sockets are dynamically added */ + sock->flag |= SOCK_DYNAMIC; + + sock->own_index = gsock->own_index; + sock->groupsock = gsock; + sock->limit = (in_out==SOCK_IN ? 1 : 0xFFF); + + if (gsock->default_value) + sock->default_value = MEM_dupallocN(gsock->default_value); + + if(lb) + BLI_addtail(lb, sock); + + return sock; +} + +bNode *node_group_make_from_selected(bNodeTree *ntree) +{ + bNodeLink *link, *linkn; + bNode *node, *gnode, *nextn; + bNodeTree *ngroup; + bNodeSocket *gsock; + ListBase anim_basepaths = {NULL, NULL}; + float min[2], max[2]; + int totnode=0; + bNodeTemplate ntemp; + + INIT_MINMAX2(min, max); + + /* is there something to group? also do some clearing */ + for(node= ntree->nodes.first; node; node= node->next) { + if(node->flag & NODE_SELECT) { + /* no groups in groups */ + if(node->type==NODE_GROUP) + return NULL; + DO_MINMAX2( (&node->locx), min, max); + totnode++; + } + node->done= 0; + } + if(totnode==0) return NULL; + + /* check if all connections are OK, no unselected node has both + inputs and outputs to a selection */ + for(link= ntree->links.first; link; link= link->next) { + if(link->fromnode && link->tonode && link->fromnode->flag & NODE_SELECT) + link->tonode->done |= 1; + if(link->fromnode && link->tonode && link->tonode->flag & NODE_SELECT) + link->fromnode->done |= 2; + } + + for(node= ntree->nodes.first; node; node= node->next) { + if((node->flag & NODE_SELECT)==0) + if(node->done==3) + break; + } + if(node) + return NULL; + + /* OK! new nodetree */ + ngroup= ntreeAddTree("NodeGroup", ntree->type, NODE_GROUP); + + /* move nodes over */ + for(node= ntree->nodes.first; node; node= nextn) { + nextn= node->next; + if(node->flag & NODE_SELECT) { + /* keep track of this node's RNA "base" path (the part of the pat identifying the node) + * if the old nodetree has animation data which potentially covers this node + */ + if (ntree->adt) { + PointerRNA ptr; + char *path; + + RNA_pointer_create(&ntree->id, &RNA_Node, node, &ptr); + path = RNA_path_from_ID_to_struct(&ptr); + + if (path) + BLI_addtail(&anim_basepaths, BLI_genericNodeN(path)); + } + + /* change node-collection membership */ + BLI_remlink(&ntree->nodes, node); + BLI_addtail(&ngroup->nodes, node); + + node->locx-= 0.5f*(min[0]+max[0]); + node->locy-= 0.5f*(min[1]+max[1]); + } + } + + /* move animation data over */ + if (ntree->adt) { + LinkData *ld, *ldn=NULL; + + BKE_animdata_separate_by_basepath(&ntree->id, &ngroup->id, &anim_basepaths); + + /* paths + their wrappers need to be freed */ + for (ld = anim_basepaths.first; ld; ld = ldn) { + ldn = ld->next; + + MEM_freeN(ld->data); + BLI_freelinkN(&anim_basepaths, ld); + } + } + + /* make group node */ + ntemp.type = NODE_GROUP; + ntemp.ngroup = ngroup; + gnode= nodeAddNode(ntree, &ntemp); + gnode->locx= 0.5f*(min[0]+max[0]); + gnode->locy= 0.5f*(min[1]+max[1]); + + /* relink external sockets */ + for(link= ntree->links.first; link; link= linkn) { + linkn= link->next; + + if(link->fromnode && link->tonode && (link->fromnode->flag & link->tonode->flag & NODE_SELECT)) { + BLI_remlink(&ntree->links, link); + BLI_addtail(&ngroup->links, link); + } + else if(link->tonode && (link->tonode->flag & NODE_SELECT)) { + gsock = node_group_expose_socket(ngroup, link->tosock, SOCK_IN); + link->tosock->link = nodeAddLink(ngroup, NULL, gsock, link->tonode, link->tosock); + link->tosock = node_group_add_extern_socket(ntree, &gnode->inputs, SOCK_IN, gsock); + link->tonode = gnode; + } + else if(link->fromnode && (link->fromnode->flag & NODE_SELECT)) { + /* search for existing group node socket */ + for (gsock=ngroup->outputs.first; gsock; gsock=gsock->next) + if (gsock->link && gsock->link->fromsock==link->fromsock) + break; + if (!gsock) { + gsock = node_group_expose_socket(ngroup, link->fromsock, SOCK_OUT); + gsock->link = nodeAddLink(ngroup, link->fromnode, link->fromsock, NULL, gsock); + link->fromsock = node_group_add_extern_socket(ntree, &gnode->outputs, SOCK_OUT, gsock); + } + else + link->fromsock = node_group_find_output(gnode, gsock); + link->fromnode = gnode; + } + } + + ngroup->update |= NTREE_UPDATE; + ntreeUpdateTree(ngroup); + ntree->update |= NTREE_UPDATE_NODES|NTREE_UPDATE_LINKS; + ntreeUpdateTree(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) +{ + bNodeLink *link, *linkn; + bNode *node, *nextn; + bNodeTree *ngroup, *wgroup; + ListBase anim_basepaths = {NULL, NULL}; + + ngroup= (bNodeTree *)gnode->id; + if(ngroup==NULL) return 0; + + /* clear new pointers, set in copytree */ + for(node= ntree->nodes.first; node; node= node->next) + node->new_node= NULL; + + /* wgroup is a temporary copy of the NodeTree we're merging in + * - all of wgroup's nodes are transferred across to their new home + * - ngroup (i.e. the source NodeTree) is left unscathed + */ + wgroup= ntreeCopyTree(ngroup); + + /* add the nodes into the ntree */ + for(node= wgroup->nodes.first; node; node= nextn) { + nextn= node->next; + + /* keep track of this node's RNA "base" path (the part of the pat identifying the node) + * if the old nodetree has animation data which potentially covers this node + */ + if (wgroup->adt) { + PointerRNA ptr; + char *path; + + RNA_pointer_create(&wgroup->id, &RNA_Node, node, &ptr); + path = RNA_path_from_ID_to_struct(&ptr); + + if (path) + BLI_addtail(&anim_basepaths, BLI_genericNodeN(path)); + } + + /* migrate node */ + BLI_remlink(&wgroup->nodes, node); + BLI_addtail(&ntree->nodes, node); + + node->locx+= gnode->locx; + node->locy+= gnode->locy; + + node->flag |= NODE_SELECT; + } + + /* restore external links to and from the gnode */ + for(link= ntree->links.first; link; link= link->next) { + if (link->fromnode==gnode) { + if (link->fromsock->groupsock) { + bNodeSocket *gsock= link->fromsock->groupsock; + if (gsock->link) { + if (gsock->link->fromnode) { + /* NB: using the new internal copies here! the groupsock pointer still maps to the old tree */ + link->fromnode = (gsock->link->fromnode ? gsock->link->fromnode->new_node : NULL); + link->fromsock = gsock->link->fromsock->new_sock; + } + else { + /* group output directly maps to group input */ + bNodeSocket *insock= node_group_find_input(gnode, gsock->link->fromsock); + if (insock->link) { + link->fromnode = insock->link->fromnode; + link->fromsock = insock->link->fromsock; + } + } + } + else { + /* copy the default input value from the group socket default to the external socket */ + convert_socket_value(gsock, link->tosock); + } + } + } + } + /* remove internal output links, these are not used anymore */ + for(link=wgroup->links.first; link; link= linkn) { + linkn = link->next; + if (!link->tonode) + nodeRemLink(wgroup, link); + } + /* restore links from internal nodes */ + for(link= wgroup->links.first; link; link= link->next) { + /* indicates link to group input */ + if (!link->fromnode) { + /* NB: can't use find_group_node_input here, + * because gnode sockets still point to the old tree! + */ + bNodeSocket *insock; + for (insock= gnode->inputs.first; insock; insock= insock->next) + if (insock->groupsock->new_sock == link->fromsock) + break; + if (insock->link) { + link->fromnode = insock->link->fromnode; + link->fromsock = insock->link->fromsock; + } + else { + /* copy the default input value from the group node socket default to the internal socket */ + convert_socket_value(insock, link->tosock); + nodeRemLink(wgroup, link); + } + } + } + + /* add internal links to the ntree */ + for(link= wgroup->links.first; link; link= linkn) { + linkn= link->next; + BLI_remlink(&wgroup->links, link); + BLI_addtail(&ntree->links, link); + } + + /* and copy across the animation */ + if (wgroup->adt) { + LinkData *ld, *ldn=NULL; + bAction *waction; + + /* firstly, wgroup needs to temporary dummy action that can be destroyed, as it shares copies */ + waction = wgroup->adt->action = copy_action(wgroup->adt->action); + + /* now perform the moving */ + BKE_animdata_separate_by_basepath(&wgroup->id, &ntree->id, &anim_basepaths); + + /* paths + their wrappers need to be freed */ + for (ld = anim_basepaths.first; ld; ld = ldn) { + ldn = ld->next; + + MEM_freeN(ld->data); + BLI_freelinkN(&anim_basepaths, ld); + } + + /* free temp action too */ + free_libblock(&G.main->action, waction); + } + + /* delete the group instance. this also removes old input links! */ + nodeFreeNode(ntree, gnode); + + /* free the group tree (takes care of user count) */ + free_libblock(&G.main->nodetree, wgroup); + + ntree->update |= NTREE_UPDATE_NODES|NTREE_UPDATE_LINKS; + ntreeUpdateTree(ntree); + + return 1; +} + +bNodeSocket *node_group_add_socket(bNodeTree *ngroup, const char *name, int type, int in_out) +{ + bNodeSocketType *stype = ntreeGetSocketType(type); + bNodeSocket *gsock = MEM_callocN(sizeof(bNodeSocket), "bNodeSocket"); + + strncpy(gsock->name, name, sizeof(gsock->name)); + gsock->type = type; + /* group sockets are dynamically added */ + gsock->flag |= SOCK_DYNAMIC; + + gsock->next = gsock->prev = NULL; + gsock->new_sock = NULL; + gsock->link = NULL; + /* assign new unique index */ + gsock->own_index = ngroup->cur_index++; + gsock->limit = (in_out==SOCK_IN ? 0xFFF : 1); + + if (stype->value_structsize > 0) + gsock->default_value = MEM_callocN(stype->value_structsize, "default socket value"); + + BLI_addtail(in_out==SOCK_IN ? &ngroup->inputs : &ngroup->outputs, gsock); + + ngroup->update |= (in_out==SOCK_IN ? NTREE_UPDATE_GROUP_IN : NTREE_UPDATE_GROUP_OUT); + + return gsock; +} + +bNodeSocket *node_group_expose_socket(bNodeTree *ngroup, bNodeSocket *sock, int in_out) +{ + bNodeSocket *gsock= node_group_add_socket(ngroup, sock->name, sock->type, in_out); + + /* initialize the default value. */ + copy_socket_value(sock, gsock); + + return gsock; +} + +void node_group_expose_all_sockets(bNodeTree *ngroup) +{ + bNode *node; + bNodeSocket *sock, *gsock; + + for (node=ngroup->nodes.first; node; node=node->next) { + for (sock=node->inputs.first; sock; sock=sock->next) { + if (!sock->link && !(sock->flag & SOCK_HIDDEN)) { + gsock = node_group_add_socket(ngroup, sock->name, sock->type, SOCK_IN); + + /* initialize the default value. */ + copy_socket_value(sock, gsock); + + sock->link = nodeAddLink(ngroup, NULL, gsock, node, sock); + } + } + for (sock=node->outputs.first; sock; sock=sock->next) { + if (nodeCountSocketLinks(ngroup, sock)==0 && !(sock->flag & SOCK_HIDDEN)) { + gsock = node_group_add_socket(ngroup, sock->name, sock->type, SOCK_OUT); + + /* initialize the default value. */ + copy_socket_value(sock, gsock); + + gsock->link = nodeAddLink(ngroup, node, sock, NULL, gsock); + } + } + } +} + +void node_group_remove_socket(bNodeTree *ngroup, bNodeSocket *gsock, int in_out) +{ + nodeRemSocketLinks(ngroup, gsock); + + switch (in_out) { + case SOCK_IN: + BLI_remlink(&ngroup->inputs, gsock); + ngroup->update |= NTREE_UPDATE_GROUP_IN; + break; + case SOCK_OUT: + BLI_remlink(&ngroup->outputs, gsock); + ngroup->update |= NTREE_UPDATE_GROUP_OUT; + break; + } + + if (gsock->default_value) + MEM_freeN(gsock->default_value); + + MEM_freeN(gsock); +} + +/* groups display their internal tree name as label */ +const char *node_group_label(bNode *node) +{ + return (node->id)? node->id->name+2: "Missing Datablock"; +} + +int node_group_valid(bNodeTree *ntree, bNodeTemplate *ntemp) +{ + bNodeTemplate childtemp; + bNode *node; + + /* regular groups cannot be recursive */ + if (ntree == ntemp->ngroup) + return 0; + + /* make sure all children are valid */ + for (node=ntemp->ngroup->nodes.first; node; node=node->next) { + childtemp = nodeMakeTemplate(node); + if (!nodeValid(ntree, &childtemp)) + return 0; + } + + return 1; +} + +bNodeTemplate node_group_template(bNode *node) +{ + bNodeTemplate ntemp; + ntemp.type = NODE_GROUP; + ntemp.ngroup = (bNodeTree*)node->id; + return ntemp; +} + +void node_group_init(bNodeTree *ntree, bNode *node, bNodeTemplate *ntemp) +{ + node->id = (ID*)ntemp->ngroup; + + /* NB: group socket input/output roles are inverted internally! + * Group "inputs" work as outputs in links and vice versa. + */ + if (ntemp->ngroup) { + bNodeSocket *gsock; + for (gsock=ntemp->ngroup->inputs.first; gsock; gsock=gsock->next) + node_group_add_extern_socket(ntree, &node->inputs, SOCK_IN, gsock); + for (gsock=ntemp->ngroup->outputs.first; gsock; gsock=gsock->next) + node_group_add_extern_socket(ntree, &node->outputs, SOCK_OUT, gsock); + } +} + +static bNodeSocket *group_verify_socket(bNodeTree *ntree, ListBase *lb, int in_out, bNodeSocket *gsock) +{ + bNodeSocket *sock; + + /* group sockets tagged as internal are not exposed ever */ + if (gsock->flag & SOCK_INTERNAL) + return NULL; + + for(sock= lb->first; sock; sock= sock->next) { + if(sock->own_index==gsock->own_index) + break; + } + if(sock) { + sock->groupsock = gsock; + + strcpy(sock->name, gsock->name); + sock->type= gsock->type; + + /* XXX hack: group socket input/output roles are inverted internally, + * need to change the limit value when making actual node sockets from them. + */ + sock->limit = (in_out==SOCK_IN ? 1 : 0xFFF); + + BLI_remlink(lb, sock); + + return sock; + } + else { + return node_group_add_extern_socket(ntree, NULL, in_out, gsock); + } +} + +static void group_verify_socket_list(bNodeTree *ntree, bNode *node, ListBase *lb, int in_out, ListBase *glb) +{ + bNodeSocket *sock, *nextsock, *gsock; + + /* step by step compare */ + for (gsock= glb->first; gsock; gsock=gsock->next) { + /* abusing new_sock pointer for verification here! only used inside this function */ + gsock->new_sock= group_verify_socket(ntree, lb, in_out, gsock); + } + /* leftovers are removed */ + for (sock=lb->first; sock; sock=nextsock) { + nextsock=sock->next; + if (sock->flag & SOCK_DYNAMIC) + nodeRemoveSocket(ntree, node, sock); + } + /* and we put back the verified sockets */ + for (gsock= glb->first; gsock; gsock=gsock->next) { + if (gsock->new_sock) { + BLI_addtail(lb, gsock->new_sock); + gsock->new_sock = NULL; + } + } +} + +/* make sure all group node in ntree, which use ngroup, are sync'd */ +void node_group_verify(struct bNodeTree *ntree, struct bNode *node, struct ID *id) +{ + /* check inputs and outputs, and remove or insert them */ + if (node->id==id) { + bNodeTree *ngroup= (bNodeTree*)node->id; + group_verify_socket_list(ntree, node, &node->inputs, SOCK_IN, &ngroup->inputs); + group_verify_socket_list(ntree, node, &node->outputs, SOCK_OUT, &ngroup->outputs); + } +} + +struct bNodeTree *node_group_edit_get(bNode *node) +{ + if (node->flag & NODE_GROUP_EDIT) + return (bNodeTree*)node->id; + else + return NULL; +} + +struct bNodeTree *node_group_edit_set(bNode *node, int edit) +{ + if (edit) { + bNodeTree *ngroup= (bNodeTree*)node->id; + if (ngroup) { + if(ngroup->id.lib) + ntreeMakeLocal(ngroup); + + node->flag |= NODE_GROUP_EDIT; + } + return ngroup; + } + else { + node->flag &= ~NODE_GROUP_EDIT; + return NULL; + } +} + +void node_group_edit_clear(bNode *node) +{ + bNodeTree *ngroup= (bNodeTree*)node->id; + bNode *inode; + + node->flag &= ~NODE_GROUP_EDIT; + + if (ngroup) + for (inode=ngroup->nodes.first; inode; inode=inode->next) + nodeGroupEditClear(inode); +} + +void node_group_link(bNodeTree *ntree, bNodeSocket *sock, int in_out) +{ + node_group_expose_socket(ntree, sock, in_out); +} + +/**** For Loop ****/ + +/* Essentially a group node with slightly different behavior. + * The internal tree is executed several times, with each output being re-used + * as an input in the next iteration. For this purpose, input and output socket + * lists are kept identical! + */ + +bNodeTemplate node_forloop_template(bNode *node) +{ + bNodeTemplate ntemp; + ntemp.type = NODE_FORLOOP; + ntemp.ngroup = (bNodeTree*)node->id; + return ntemp; +} + +void node_forloop_init(bNodeTree *ntree, bNode *node, bNodeTemplate *ntemp) +{ + bNodeSocket *sock; + + node->id = (ID*)ntemp->ngroup; + + sock = nodeAddInputFloat(ntree, node, "Iterations", PROP_UNSIGNED, 1, 0, 10000); + + /* NB: group socket input/output roles are inverted internally! + * Group "inputs" work as outputs in links and vice versa. + */ + if (ntemp->ngroup) { + bNodeSocket *gsock; + for (gsock=ntemp->ngroup->inputs.first; gsock; gsock=gsock->next) + node_group_add_extern_socket(ntree, &node->inputs, SOCK_IN, gsock); + for (gsock=ntemp->ngroup->outputs.first; gsock; gsock=gsock->next) + node_group_add_extern_socket(ntree, &node->outputs, SOCK_OUT, gsock); + } +} + +void node_forloop_init_tree(bNodeTree *ntree) +{ + bNodeSocket *sock; + sock = node_group_add_socket(ntree, "Iteration", SOCK_FLOAT, SOCK_IN); + sock->flag |= SOCK_INTERNAL; +} + +static void loop_sync(bNodeTree *ntree, int sync_in_out) +{ + bNodeSocket *sock, *sync, *nsync, *mirror; + ListBase *sync_lb; + + if (sync_in_out==SOCK_IN) { + sock = ntree->outputs.first; + + sync = ntree->inputs.first; + sync_lb = &ntree->inputs; + } + else { + sock = ntree->inputs.first; + + sync = ntree->outputs.first; + sync_lb = &ntree->outputs; + } + + /* NB: the sock->storage pointer is used here directly to store the own_index int + * out the mirrored socket counterpart! + */ + + while (sock) { + /* skip static and internal sockets on the sync side (preserves socket order!) */ + while (sync && ((sync->flag & SOCK_INTERNAL) || !(sync->flag & SOCK_DYNAMIC))) + sync = sync->next; + + if (!(sync->flag & SOCK_INTERNAL) && (sync->flag & SOCK_DYNAMIC)) { + if (sock->storage==NULL) { + /* if mirror index is 0, the sockets is newly added and a new mirror must be created. */ + mirror = node_group_expose_socket(ntree, sock, sync_in_out); + /* store the mirror index */ + sock->storage = SET_INT_IN_POINTER(mirror->own_index); + mirror->storage = SET_INT_IN_POINTER(sock->own_index); + /* move mirror to the right place */ + BLI_remlink(sync_lb, mirror); + if (sync) + BLI_insertlinkbefore(sync_lb, sync, mirror); + else + BLI_addtail(sync_lb, mirror); + } + else { + /* look up the mirror socket */ + for (mirror=sync; mirror; mirror=mirror->next) + if (mirror->own_index == GET_INT_FROM_POINTER(sock->storage)) + break; + /* make sure the name is the same (only for identification by user, no deeper meaning) */ + strcpy(mirror->name, sock->name); + /* fix the socket order if necessary */ + if (mirror != sync) { + BLI_remlink(sync_lb, mirror); + BLI_insertlinkbefore(sync_lb, sync, mirror); + } + else + sync = sync->next; + } + } + + sock = sock->next; + } + + /* remaining sockets in sync_lb are leftovers from deleted sockets, remove them */ + while (sync) { + nsync = sync->next; + if (!(sync->flag & SOCK_INTERNAL) && (sync->flag & SOCK_DYNAMIC)) + node_group_remove_socket(ntree, sync, sync_in_out); + sync = nsync; + } +} + +void node_loop_update_tree(bNodeTree *ngroup) +{ + /* make sure inputs & outputs are identical */ + if (ngroup->update & NTREE_UPDATE_GROUP_IN) + loop_sync(ngroup, SOCK_OUT); + if (ngroup->update & NTREE_UPDATE_GROUP_OUT) + loop_sync(ngroup, SOCK_IN); +} + +void node_whileloop_init(bNodeTree *ntree, bNode *node, bNodeTemplate *ntemp) +{ + bNodeSocket *sock; + + node->id = (ID*)ntemp->ngroup; + + sock = nodeAddInputFloat(ntree, node, "Condition", PROP_NONE, 1, 0, 1); + + /* max iterations */ + node->custom1 = 10000; + + /* NB: group socket input/output roles are inverted internally! + * Group "inputs" work as outputs in links and vice versa. + */ + if (ntemp->ngroup) { + bNodeSocket *gsock; + for (gsock=ntemp->ngroup->inputs.first; gsock; gsock=gsock->next) + node_group_add_extern_socket(ntree, &node->inputs, SOCK_IN, gsock); + for (gsock=ntemp->ngroup->outputs.first; gsock; gsock=gsock->next) + node_group_add_extern_socket(ntree, &node->outputs, SOCK_OUT, gsock); + } +} + +void node_whileloop_init_tree(bNodeTree *ntree) +{ + bNodeSocket *sock; + sock = node_group_add_socket(ntree, "Condition", SOCK_FLOAT, SOCK_OUT); + sock->flag |= SOCK_INTERNAL; +} + +bNodeTemplate node_whileloop_template(bNode *node) +{ + bNodeTemplate ntemp; + ntemp.type = NODE_WHILELOOP; + ntemp.ngroup = (bNodeTree*)node->id; + return ntemp; +} + +/**** FRAME ****/ + +void register_node_type_frame(ListBase *lb) +{ + /* frame type is used for all tree types, needs dynamic allocation */ + bNodeType *ntype= MEM_callocN(sizeof(bNodeType), "frame node type"); + + node_type_base(ntype, NODE_FRAME, "Frame", NODE_CLASS_LAYOUT, NODE_BACKGROUND); + node_type_size(ntype, 150, 100, 0); + + ntype->needs_free = 1; + nodeRegisterType(lb, ntype); +} diff --git a/source/blender/nodes/intern/node_common.h b/source/blender/nodes/intern/node_common.h new file mode 100644 index 00000000000..31a13d8168d --- /dev/null +++ b/source/blender/nodes/intern/node_common.h @@ -0,0 +1,65 @@ +/** + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2007 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): Lukas Toenne. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/nodes/intern/node_common.h + * \ingroup nodes + */ + + +#ifndef NODE_COMMON_H_ +#define NODE_COMMON_H_ + +#include "DNA_listBase.h" + +struct bNodeTree; + +struct bNodeSocket *node_group_add_extern_socket(struct bNodeTree *ntree, ListBase *lb, int in_out, struct bNodeSocket *gsock); + +void node_group_init(struct bNodeTree *ntree, struct bNode *node, struct bNodeTemplate *ntemp); +void node_forloop_init(struct bNodeTree *ntree, struct bNode *node, struct bNodeTemplate *ntemp); +void node_whileloop_init(struct bNodeTree *ntree, struct bNode *node, struct bNodeTemplate *ntemp); + +void node_forloop_init_tree(struct bNodeTree *ntree); +void node_whileloop_init_tree(struct bNodeTree *ntree); + +const char *node_group_label(struct bNode *node); + +struct bNodeTemplate node_group_template(struct bNode *node); +struct bNodeTemplate node_forloop_template(struct bNode *node); +struct bNodeTemplate node_whileloop_template(struct bNode *node); + +int node_group_valid(struct bNodeTree *ntree, struct bNodeTemplate *ntemp); +void node_group_verify(struct bNodeTree *ntree, struct bNode *node, struct ID *id); + +struct bNodeTree *node_group_edit_get(struct bNode *node); +struct bNodeTree *node_group_edit_set(struct bNode *node, int edit); +void node_group_edit_clear(bNode *node); + +void node_loop_update_tree(struct bNodeTree *ngroup); + +#endif diff --git a/source/blender/nodes/intern/node_exec.c b/source/blender/nodes/intern/node_exec.c new file mode 100644 index 00000000000..0d688438cf9 --- /dev/null +++ b/source/blender/nodes/intern/node_exec.c @@ -0,0 +1,308 @@ +/** + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2007 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): Nathan Letwory. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/nodes/intern/node_exec.c + * \ingroup nodes + */ + + +#include "DNA_node_types.h" + +#include "BLI_listbase.h" +#include "BLI_math.h" +#include "BLI_utildefines.h" + +#include "BKE_node.h" + +#include "MEM_guardedalloc.h" + +#include "node_exec.h" + + +/* for a given socket, find the actual stack entry */ +bNodeStack *node_get_socket_stack(bNodeStack *stack, bNodeSocket *sock) +{ + return stack + sock->stack_index; +} + +void node_get_stack(bNode *node, bNodeStack *stack, bNodeStack **in, bNodeStack **out) +{ + bNodeSocket *sock; + + /* build pointer stack */ + if (in) { + for(sock= node->inputs.first; sock; sock= sock->next) { + *(in++) = node_get_socket_stack(stack, sock); + } + } + + if (out) { + for(sock= node->outputs.first; sock; sock= sock->next) { + *(out++) = node_get_socket_stack(stack, sock); + } + } +} + +void node_init_input_index(bNodeSocket *sock, int *index) +{ + if (sock->link && sock->link->fromsock) { + sock->stack_index = sock->link->fromsock->stack_index; + } + else { + sock->stack_index = (*index)++; + } +} + +void node_init_output_index(bNodeSocket *sock, int *index) +{ + sock->stack_index = (*index)++; +} + +/* basic preparation of socket stacks */ +static struct bNodeStack *setup_stack(bNodeStack *stack, bNodeSocket *sock) +{ + bNodeStack *ns = node_get_socket_stack(stack, sock); + float null_value[4]= {0.0f, 0.0f, 0.0f, 0.0f}; + + /* don't mess with remote socket stacks, these are initialized by other nodes! */ + if (sock->link) + return ns; + + ns->sockettype = sock->type; + + if (sock->default_value) { + switch (sock->type) { + case SOCK_FLOAT: + ns->vec[0] = ((bNodeSocketValueFloat*)sock->default_value)->value; + break; + case SOCK_VECTOR: + copy_v3_v3(ns->vec, ((bNodeSocketValueVector*)sock->default_value)->value); + break; + case SOCK_RGBA: + copy_v4_v4(ns->vec, ((bNodeSocketValueRGBA*)sock->default_value)->value); + break; + } + } + else { + switch (sock->type) { + case SOCK_FLOAT: + ns->vec[0] = 0.0f; + break; + case SOCK_VECTOR: + copy_v3_v3(ns->vec, null_value); + break; + case SOCK_RGBA: + copy_v4_v4(ns->vec, null_value); + break; + } + } + + return ns; +} + +bNodeTreeExec *ntree_exec_begin(bNodeTree *ntree) +{ + bNodeTreeExec *exec; + bNode *node; + bNodeExec *nodeexec; + bNodeSocket *sock, *gsock; + bNodeStack *ns; + int index= 0; + bNode **nodelist; + int totnodes, n; + + if((ntree->init & NTREE_TYPE_INIT)==0) + ntreeInitTypes(ntree); + + /* get a dependency-sorted list of nodes */ + ntreeGetDependencyList(ntree, &nodelist, &totnodes); + + /* XXX could let callbacks do this for specialized data */ + exec = MEM_callocN(sizeof(bNodeTreeExec), "node tree execution data"); + /* backpointer to node tree */ + exec->nodetree = ntree; + + /* group inputs essentially work as outputs */ + for(gsock=ntree->inputs.first; gsock; gsock = gsock->next) + node_init_output_index(gsock, &index); + /* set stack indexes */ + for(n=0; n < totnodes; ++n) { + node = nodelist[n]; + + node->stack_index = index; + + /* init node socket stack indexes */ + for (sock=node->inputs.first; sock; sock=sock->next) + node_init_input_index(sock, &index); + for (sock=node->outputs.first; sock; sock=sock->next) + node_init_output_index(sock, &index); + } + /* group outputs essentially work as inputs */ + for(gsock=ntree->outputs.first; gsock; gsock = gsock->next) + node_init_input_index(gsock, &index); + + /* allocated exec data pointers for nodes */ + exec->totnodes = totnodes; + exec->nodeexec = MEM_callocN(exec->totnodes * sizeof(bNodeExec), "node execution data"); + /* allocate data pointer for node stack */ + exec->stacksize = index; + exec->stack = MEM_callocN(exec->stacksize * sizeof(bNodeStack), "bNodeStack"); + + /* prepare group tree inputs */ + for (sock=ntree->inputs.first; sock; sock=sock->next) { + ns = setup_stack(exec->stack, sock); + if (ns->hasoutput) + ns->hasinput = 1; + } + /* prepare all internal nodes for execution */ + for(n=0, nodeexec= exec->nodeexec; n < totnodes; ++n, ++nodeexec) { + node = nodeexec->node = nodelist[n]; + + /* tag inputs */ + for (sock=node->inputs.first; sock; sock=sock->next) { + /* disable the node if an input link is invalid */ + if(sock->link && !(sock->link->flag & NODE_LINK_VALID)) + node->need_exec= 0; + + ns = setup_stack(exec->stack, sock); + if (ns->hasoutput) + ns->hasinput = 1; + } + + /* tag all outputs */ + for (sock=node->outputs.first; sock; sock=sock->next) { + ns = setup_stack(exec->stack, sock); + ns->hasoutput = 1; + } + + if(node->typeinfo->initexecfunc) + nodeexec->data = node->typeinfo->initexecfunc(node); + } + /* prepare group tree outputs */ + for (sock=ntree->outputs.first; sock; sock=sock->next) { + ns = setup_stack(exec->stack, sock); + ns->hasoutput = 1; + } + + if (nodelist) + MEM_freeN(nodelist); + + return exec; +} + +void ntree_exec_end(bNodeTreeExec *exec) +{ + bNodeExec *nodeexec; + int n; + + if (exec->stack) + MEM_freeN(exec->stack); + + for(n=0, nodeexec= exec->nodeexec; n < exec->totnodes; ++n, ++nodeexec) { + if (nodeexec->node->typeinfo->freeexecfunc) + nodeexec->node->typeinfo->freeexecfunc(nodeexec->node, nodeexec->data); + } + + if (exec->nodeexec) + MEM_freeN(exec->nodeexec); + + MEM_freeN(exec); +} + +/**** Compositor/Material/Texture trees ****/ + +bNodeThreadStack *ntreeGetThreadStack(bNodeTreeExec *exec, int thread) +{ + ListBase *lb= &exec->threadstack[thread]; + bNodeThreadStack *nts; + + for(nts=lb->first; nts; nts=nts->next) { + if(!nts->used) { + nts->used= 1; + break; + } + } + + if (!nts) { + nts= MEM_callocN(sizeof(bNodeThreadStack), "bNodeThreadStack"); + nts->stack= MEM_dupallocN(exec->stack); + nts->used= 1; + BLI_addtail(lb, nts); + } + + return nts; +} + +void ntreeReleaseThreadStack(bNodeThreadStack *nts) +{ + nts->used = 0; +} + +void ntreeExecNodes(bNodeTreeExec *exec, void *callerdata, int thread) +{ + bNodeStack *nsin[MAX_SOCKET]; /* arbitrary... watch this */ + bNodeStack *nsout[MAX_SOCKET]; /* arbitrary... watch this */ + bNodeExec *nodeexec; + bNode *node; + int n; + + /* nodes are presorted, so exec is in order of list */ + + for(n=0, nodeexec= exec->nodeexec; n < exec->totnodes; ++n, ++nodeexec) { + node = nodeexec->node; + if(node->need_exec) { + node_get_stack(node, exec->stack, nsin, nsout); + if(node->typeinfo->execfunc) + node->typeinfo->execfunc(callerdata, node, nsin, nsout); + else if (node->typeinfo->newexecfunc) + node->typeinfo->newexecfunc(callerdata, thread, node, nodeexec->data, nsin, nsout); + } + } +} + +void ntreeExecThreadNodes(bNodeTreeExec *exec, bNodeThreadStack *nts, void *callerdata, int thread) +{ + bNodeStack *nsin[MAX_SOCKET]; /* arbitrary... watch this */ + bNodeStack *nsout[MAX_SOCKET]; /* arbitrary... watch this */ + bNodeExec *nodeexec; + bNode *node; + int n; + + /* nodes are presorted, so exec is in order of list */ + + for(n=0, nodeexec= exec->nodeexec; n < exec->totnodes; ++n, ++nodeexec) { + node = nodeexec->node; + if(node->need_exec) { + node_get_stack(node, nts->stack, nsin, nsout); + if(node->typeinfo->execfunc) + node->typeinfo->execfunc(callerdata, node, nsin, nsout); + else if (node->typeinfo->newexecfunc) + node->typeinfo->newexecfunc(callerdata, thread, node, nodeexec->data, nsin, nsout); + } + } +} diff --git a/source/blender/nodes/intern/node_exec.h b/source/blender/nodes/intern/node_exec.h new file mode 100644 index 00000000000..457e119613b --- /dev/null +++ b/source/blender/nodes/intern/node_exec.h @@ -0,0 +1,89 @@ +/** + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2007 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): Nathan Letwory. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/nodes/intern/node_exec.h + * \ingroup nodes + */ + + +#ifndef NODE_EXEC_H_ +#define NODE_EXEC_H_ + +#include "DNA_listBase.h" + +#include "BLI_utildefines.h" + +#include "BKE_node.h" + +#include "RNA_types.h" + +struct bNodeTree; +struct bNode; +struct bNodeStack; + +/* Node execution data */ +typedef struct bNodeExec { + struct bNode *node; /* backpointer to node */ + void *data; /* custom data storage */ +} bNodeExec; + +/* Execution Data for each instance of node tree execution */ +typedef struct bNodeTreeExec { + struct bNodeTree *nodetree; /* backpointer to node tree */ + + int totnodes; /* total node count */ + struct bNodeExec *nodeexec; /* per-node execution data */ + + int stacksize; + struct bNodeStack *stack; /* socket data stack */ + /* only used by material and texture trees to keep one stack for each thread */ + ListBase *threadstack; /* one instance of the stack for each thread */ +} bNodeTreeExec; + +/* stores one stack copy for each thread (material and texture trees) */ +typedef struct bNodeThreadStack { + struct bNodeThreadStack *next, *prev; + struct bNodeStack *stack; + int used; +} bNodeThreadStack; + +struct bNodeStack *node_get_socket_stack(struct bNodeStack *stack, struct bNodeSocket *sock); +void node_get_stack(struct bNode *node, struct bNodeStack *stack, struct bNodeStack **in, struct bNodeStack **out); +void node_init_input_index(struct bNodeSocket *sock, int *index); +void node_init_output_index(struct bNodeSocket *sock, int *index); + +struct bNodeTreeExec *ntree_exec_begin(struct bNodeTree *ntree); +void ntree_exec_end(struct bNodeTreeExec *exec); + +void ntreeExecNodes(struct bNodeTreeExec *exec, void *callerdata, int thread); + +struct bNodeThreadStack *ntreeGetThreadStack(struct bNodeTreeExec *exec, int thread); +void ntreeReleaseThreadStack(struct bNodeThreadStack *nts); +void ntreeExecThreadNodes(struct bNodeTreeExec *exec, struct bNodeThreadStack *nts, void *callerdata, int thread); + +#endif diff --git a/source/blender/nodes/intern/node_socket.c b/source/blender/nodes/intern/node_socket.c new file mode 100644 index 00000000000..ef8b3e797ce --- /dev/null +++ b/source/blender/nodes/intern/node_socket.c @@ -0,0 +1,428 @@ +/** + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2007 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): Lukas Toennne + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/nodes/intern/node_socket.c + * \ingroup nodes + */ + + +#include "DNA_node_types.h" + +#include "DNA_mesh_types.h" +#include "DNA_meshdata_types.h" +#include "DNA_object_types.h" +#include "DNA_scene_types.h" + +#include "BLI_listbase.h" +#include "BLI_math.h" +#include "BLI_utildefines.h" + +#include "BKE_DerivedMesh.h" +#include "BKE_node.h" + +#include "RNA_access.h" +#include "RNA_types.h" + +#include "MEM_guardedalloc.h" + +#include "NOD_socket.h" + +/****************** FLOAT ******************/ + +static bNodeSocketType node_socket_type_float = { + /* type */ SOCK_FLOAT, + /* ui_name */ "Float", + /* ui_description */ "Floating Point", + /* ui_icon */ 0, + /* ui_color */ {160,160,160,255}, + + /* value_structname */ "bNodeSocketValueFloat", + /* value_structsize */ sizeof(bNodeSocketValueFloat), + + /* buttonfunc */ NULL, +}; + +/****************** VECTOR ******************/ + +static bNodeSocketType node_socket_type_vector = { + /* type */ SOCK_VECTOR, + /* ui_name */ "Vector", + /* ui_description */ "3-dimensional floating point vector", + /* ui_icon */ 0, + /* ui_color */ {100,100,200,255}, + + /* value_structname */ "bNodeSocketValueVector", + /* value_structsize */ sizeof(bNodeSocketValueVector), + + /* buttonfunc */ NULL, +}; + +/****************** RGBA ******************/ + +static bNodeSocketType node_socket_type_rgba = { + /* type */ SOCK_RGBA, + /* ui_name */ "RGBA", + /* ui_description */ "RGBA color", + /* ui_icon */ 0, + /* ui_color */ {200,200,40,255}, + + /* value_structname */ "bNodeSocketValueRGBA", + /* value_structsize */ sizeof(bNodeSocketValueRGBA), + + /* buttonfunc */ NULL, +}; + +/****************** INT ******************/ + +static bNodeSocketType node_socket_type_int = { + /* type */ SOCK_INT, + /* ui_name */ "Int", + /* ui_description */ "Integer", + /* ui_icon */ 0, + /* ui_color */ {17,133,37,255}, + + /* value_structname */ "bNodeSocketValueInt", + /* value_structsize */ sizeof(bNodeSocketValueInt), + + /* buttonfunc */ NULL, +}; + +/****************** BOOLEAN ******************/ + +static bNodeSocketType node_socket_type_boolean = { + /* type */ SOCK_BOOLEAN, + /* ui_name */ "Boolean", + /* ui_description */ "Boolean", + /* ui_icon */ 0, + /* ui_color */ {158,139,63,255}, + + /* value_structname */ "bNodeSocketValueBoolean", + /* value_structsize */ sizeof(bNodeSocketValueBoolean), + + /* buttonfunc */ NULL, +}; + +/****************** MESH ******************/ + +static bNodeSocketType node_socket_type_mesh = { + /* type */ SOCK_MESH, + /* ui_name */ "Mesh", + /* ui_description */ "Mesh geometry data", + /* ui_icon */ 0, + /* ui_color */ {255,133,7,255}, + + /* value_structname */ NULL, + /* value_structsize */ 0, + + /* buttonfunc */ NULL, +}; + + +void node_socket_type_init(bNodeSocketType *types[]) +{ + #define INIT_TYPE(name) types[node_socket_type_##name.type] = &node_socket_type_##name; + + INIT_TYPE(float); + INIT_TYPE(vector); + INIT_TYPE(rgba); + INIT_TYPE(int); + INIT_TYPE(boolean); + INIT_TYPE(mesh); + + #undef INIT_TYPE +} + +struct bNodeSocket *nodeAddInputInt(struct bNodeTree *ntree, struct bNode *node, const char *name, PropertySubType subtype, + int value, int min, int max) +{ + 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; +} + +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) +{ + bNodeSocket *sock= nodeAddSocket(ntree, node, SOCK_OUT, name, SOCK_FLOAT); + return sock; +} + +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) +{ + bNodeSocket *sock= nodeAddSocket(ntree, node, SOCK_OUT, name, SOCK_BOOLEAN); + return sock; +} + +struct bNodeSocket *nodeAddInputVector(struct bNodeTree *ntree, struct bNode *node, const char *name, PropertySubType subtype, + float x, float y, float z, float min, float 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; +} + +struct bNodeSocket *nodeAddInputRGBA(struct bNodeTree *ntree, struct bNode *node, const char *name, + float r, float g, float b, float a) +{ + 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; +} +struct bNodeSocket *nodeAddOutputRGBA(struct bNodeTree *ntree, struct bNode *node, const char *name) +{ + bNodeSocket *sock= nodeAddSocket(ntree, node, SOCK_OUT, name, SOCK_RGBA); + return sock; +} + +struct bNodeSocket *nodeAddInputMesh(struct bNodeTree *ntree, struct bNode *node, const char *name) +{ + bNodeSocket *sock= nodeAddSocket(ntree, node, SOCK_IN, name, SOCK_MESH); + return sock; +} +struct bNodeSocket *nodeAddOutputMesh(struct bNodeTree *ntree, struct bNode *node, const char *name) +{ + 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) +{ + 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; + case SOCK_FLOAT: + sock = nodeAddInputFloat(ntree, node, stemp->name, stemp->subtype, stemp->val1, stemp->min, stemp->max); + break; + case SOCK_BOOLEAN: + sock = nodeAddInputBoolean(ntree, node, stemp->name, (char)stemp->val1); + break; + case SOCK_VECTOR: + sock = nodeAddInputVector(ntree, node, stemp->name, stemp->subtype, stemp->val1, stemp->val2, stemp->val3, stemp->min, stemp->max); + break; + case SOCK_RGBA: + sock = nodeAddInputRGBA(ntree, node, stemp->name, stemp->val1, stemp->val2, stemp->val3, stemp->val4); + break; + case SOCK_MESH: + sock = nodeAddInputMesh(ntree, node, stemp->name); + break; + default: + sock = nodeAddSocket(ntree, node, SOCK_IN, stemp->name, stemp->type); + } + return sock; +} + +struct bNodeSocket *node_add_output_from_template(struct bNodeTree *ntree, struct bNode *node, struct bNodeSocketTemplate *stemp) +{ + bNodeSocket *sock; + switch (stemp->type) { + case SOCK_INT: + sock = nodeAddOutputInt(ntree, node, stemp->name); + break; + case SOCK_FLOAT: + sock = nodeAddOutputFloat(ntree, node, stemp->name); + break; + case SOCK_BOOLEAN: + sock = nodeAddOutputBoolean(ntree, node, stemp->name); + break; + case SOCK_VECTOR: + sock = nodeAddOutputVector(ntree, node, stemp->name); + break; + case SOCK_RGBA: + sock = nodeAddOutputRGBA(ntree, node, stemp->name); + break; + case SOCK_MESH: + sock = nodeAddOutputMesh(ntree, node, stemp->name); + break; + default: + sock = nodeAddSocket(ntree, node, SOCK_OUT, stemp->name, stemp->type); + } + return sock; +} + +static bNodeSocket *verify_socket_template(bNodeTree *ntree, bNode *node, int in_out, ListBase *socklist, bNodeSocketTemplate *stemp) +{ + bNodeSocket *sock; + + for(sock= socklist->first; sock; sock= sock->next) { + if(!(sock->flag & SOCK_DYNAMIC) && strncmp(sock->name, stemp->name, NODE_MAXSTR)==0) + break; + } + if(sock) { + sock->type= stemp->type; /* in future, read this from tydefs! */ + if(stemp->limit==0) sock->limit= 0xFFF; + else sock->limit= stemp->limit; + + /* Copy the property range and subtype parameters in case the template changed. + * NOT copying the actual value here, only button behavior changes! + */ + switch (sock->type) { + case SOCK_FLOAT: + { + bNodeSocketValueFloat *dval= sock->default_value; + dval->min = stemp->min; + dval->max = stemp->max; + dval->subtype = stemp->subtype; + } + break; + case SOCK_INT: + { + bNodeSocketValueInt *dval= sock->default_value; + dval->min = stemp->min; + dval->max = stemp->max; + dval->subtype = stemp->subtype; + } + break; + case SOCK_VECTOR: + { + bNodeSocketValueVector *dval= sock->default_value; + dval->min = stemp->min; + dval->max = stemp->max; + dval->subtype = stemp->subtype; + } + break; + } + + BLI_remlink(socklist, sock); + + return sock; + } + else { + /* no socket for this template found, make a new one */ + if (in_out==SOCK_IN) + sock = node_add_input_from_template(ntree, node, stemp); + else + sock = node_add_output_from_template(ntree, node, stemp); + /* remove the new socket from the node socket list first, + * will be added back after verification. + */ + BLI_remlink(socklist, sock); + } + + return sock; +} + +static void verify_socket_template_list(bNodeTree *ntree, bNode *node, int in_out, ListBase *socklist, bNodeSocketTemplate *stemp_first) +{ + bNodeSocket *sock; + bNodeSocketTemplate *stemp; + + /* no inputs anymore? */ + if(stemp_first==NULL) { + while(socklist->first) { + sock = (bNodeSocket*)socklist->first; + if (!(sock->flag & SOCK_DYNAMIC)) + nodeRemoveSocket(ntree, node, socklist->first); + } + } + else { + /* step by step compare */ + stemp= stemp_first; + while(stemp->type != -1) { + stemp->sock= verify_socket_template(ntree, node, in_out, socklist, stemp); + stemp++; + } + /* leftovers are removed */ + while(socklist->first) { + sock = (bNodeSocket*)socklist->first; + if (!(sock->flag & SOCK_DYNAMIC)) + nodeRemoveSocket(ntree, node, socklist->first); + } + + /* and we put back the verified sockets */ + stemp= stemp_first; + if (socklist->first) { + /* some dynamic sockets left, store the list start + * so we can add static sockets infront of it. + */ + sock = socklist->first; + while(stemp->type != -1) { + /* put static sockets infront of dynamic */ + BLI_insertlinkbefore(socklist, sock, stemp->sock); + stemp++; + } + } + else { + while(stemp->type != -1) { + BLI_addtail(socklist, stemp->sock); + stemp++; + } + } + } +} + +void node_verify_socket_templates(bNodeTree *ntree, bNode *node) +{ + bNodeType *ntype= node->typeinfo; + if(ntype) { + verify_socket_template_list(ntree, node, SOCK_IN, &node->inputs, ntype->inputs); + verify_socket_template_list(ntree, node, SOCK_OUT, &node->outputs, ntype->outputs); + } +} diff --git a/source/blender/nodes/intern/node_util.c b/source/blender/nodes/intern/node_util.c index 1cc8c282179..bdf53df06af 100644 --- a/source/blender/nodes/intern/node_util.c +++ b/source/blender/nodes/intern/node_util.c @@ -32,12 +32,24 @@ */ -#include "CMP_util.h" -#include "SHD_util.h" +#include "DNA_action_types.h" +#include "DNA_node_types.h" + +#include "BLI_listbase.h" +#include "BLI_utildefines.h" + +#include "BKE_colortools.h" +#include "BKE_node.h" #include "RNA_access.h" #include "RNA_enum_types.h" +#include "MEM_guardedalloc.h" + +#include "node_util.h" + +/**** Storage Data ****/ + void node_free_curves(bNode *node) { curvemapping_free(node->storage); @@ -58,6 +70,8 @@ void node_copy_standard_storage(bNode *orig_node, bNode *new_node) new_node->storage= MEM_dupallocN(orig_node->storage); } +/**** Labels ****/ + const char *node_blend_label(bNode *node) { const char *name; diff --git a/source/blender/nodes/intern/node_util.h b/source/blender/nodes/intern/node_util.h index 5a78fc07883..8d38d57f577 100644 --- a/source/blender/nodes/intern/node_util.h +++ b/source/blender/nodes/intern/node_util.h @@ -35,14 +35,27 @@ #ifndef NODE_UTIL_H_ #define NODE_UTIL_H_ +#include "DNA_listBase.h" + +#include "BKE_node.h" + #include "MEM_guardedalloc.h" +#include "NOD_socket.h" + +struct bNodeTree; +struct bNode; + +/**** Storage Data ****/ + extern void node_free_curves(struct bNode *node); extern void node_free_standard_storage(struct bNode *node); extern void node_copy_curves(struct bNode *orig_node, struct bNode *new_node); extern void node_copy_standard_storage(struct bNode *orig_node, struct bNode *new_node); +/**** Labels ****/ + const char *node_blend_label(struct bNode *node); const char *node_math_label(struct bNode *node); const char *node_vect_math_label(struct bNode *node); diff --git a/source/blender/nodes/shader/node_shader_tree.c b/source/blender/nodes/shader/node_shader_tree.c new file mode 100644 index 00000000000..620da7553b3 --- /dev/null +++ b/source/blender/nodes/shader/node_shader_tree.c @@ -0,0 +1,212 @@ +/** + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2007 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/nodes/shader/node_shader_tree.c + * \ingroup nodes + */ + + +#include + +#include "DNA_material_types.h" +#include "DNA_node_types.h" + +#include "BLI_listbase.h" +#include "BLI_math.h" +#include "BLI_threads.h" +#include "BLI_utildefines.h" + +#include "BKE_global.h" +#include "BKE_main.h" +#include "BKE_node.h" +#include "BKE_utildefines.h" + +#include "GPU_material.h" + +#include "RE_shader_ext.h" + +#include "node_exec.h" +#include "node_util.h" +#include "node_shader_util.h" + +static void foreach_nodetree(Main *main, void *calldata, bNodeTreeCallback func) +{ + Material *ma; + for(ma= main->mat.first; ma; ma= ma->id.next) { + if(ma->nodetree) { + func(calldata, &ma->id, ma->nodetree); + } + } +} + +static void local_sync(bNodeTree *localtree, bNodeTree *ntree) +{ + bNode *lnode; + + /* copy over contents of previews */ + for(lnode= localtree->nodes.first; lnode; lnode= lnode->next) { + if(ntreeNodeExists(ntree, lnode->new_node)) { + bNode *node= lnode->new_node; + + if(node->preview && node->preview->rect) { + if(lnode->preview && lnode->preview->rect) { + int xsize= node->preview->xsize; + int ysize= node->preview->ysize; + memcpy(node->preview->rect, lnode->preview->rect, 4*xsize + xsize*ysize*sizeof(char)*4); + } + } + } + } +} + +bNodeTreeType ntreeType_Shader = { + /* type */ NTREE_SHADER, + /* id_name */ "NTShader Nodetree", + + /* node_types */ { NULL, NULL }, + + /* free_cache */ NULL, + /* free_node_cache */ NULL, + /* foreach_nodetree */ foreach_nodetree, + /* localize */ NULL, + /* local_sync */ local_sync, + /* local_merge */ NULL, + /* update */ NULL, + /* update_node */ NULL +}; + +/* GPU material from shader nodes */ + +void ntreeGPUMaterialNodes(bNodeTree *ntree, GPUMaterial *mat) +{ + bNodeTreeExec *exec; + + if(!ntree->execdata) + exec = ntreeShaderBeginExecTree(ntree); + + ntreeExecGPUNodes(exec, mat, 1); + + ntreeShaderEndExecTree(exec); +} + +/* **************** call to switch lamploop for material node ************ */ + +void (*node_shader_lamp_loop)(struct ShadeInput *, struct ShadeResult *); + +void set_node_shader_lamp_loop(void (*lamp_loop_func)(ShadeInput *, ShadeResult *)) +{ + node_shader_lamp_loop= lamp_loop_func; +} + + +bNodeTreeExec *ntreeShaderBeginExecTree(bNodeTree *ntree) +{ + bNodeTreeExec *exec; + bNode *node; + + /* XXX hack: prevent exec data from being generated twice. + * this should be handled by the renderer! + */ + if (ntree->execdata) + return ntree->execdata; + + /* ensures only a single output node is enabled */ + ntreeSetOutput(ntree); + + /* common base initialization */ + exec = ntree_exec_begin(ntree); + + /* allocate the thread stack listbase array */ + exec->threadstack= MEM_callocN(BLENDER_MAX_THREADS*sizeof(ListBase), "thread stack array"); + + for(node= exec->nodetree->nodes.first; node; node= node->next) + node->need_exec= 1; + + /* XXX this should not be necessary, but is still used for cmp/sha/tex nodes, + * which only store the ntree pointer. Should be fixed at some point! + */ + ntree->execdata = exec; + + return exec; +} + +void ntreeShaderEndExecTree(bNodeTreeExec *exec) +{ + if(exec) { + bNodeTree *ntree= exec->nodetree; + bNodeThreadStack *nts; + int a; + + if(exec->threadstack) { + for(a=0; athreadstack[a].first; nts; nts=nts->next) + if (nts->stack) MEM_freeN(nts->stack); + BLI_freelistN(&exec->threadstack[a]); + } + + MEM_freeN(exec->threadstack); + exec->threadstack= NULL; + } + + ntree_exec_end(exec); + + /* XXX clear nodetree backpointer to exec data, same problem as noted in ntreeBeginExecTree */ + ntree->execdata = NULL; + } +} + +void ntreeShaderExecTree(bNodeTree *ntree, ShadeInput *shi, ShadeResult *shr) +{ + ShaderCallData scd; + /* + @note: preserve material from ShadeInput for material id, nodetree execs change it + fix for bug "[#28012] Mat ID messy with shader nodes" + */ + Material *mat = shi->mat; bNodeThreadStack *nts = NULL; + bNodeTreeExec *exec = ntree->execdata; + + /* convert caller data to struct */ + scd.shi= shi; + scd.shr= shr; + + /* each material node has own local shaderesult, with optional copying */ + memset(shr, 0, sizeof(ShadeResult)); + + if (!exec) + exec = ntree->execdata = ntreeShaderBeginExecTree(exec->nodetree); + + nts= ntreeGetThreadStack(exec, shi->thread); + ntreeExecThreadNodes(exec, nts, &scd, shi->thread); + ntreeReleaseThreadStack(nts); + + // @note: set material back to preserved material + shi->mat = mat; + /* better not allow negative for now */ + if(shr->combined[0]<0.0f) shr->combined[0]= 0.0f; + if(shr->combined[1]<0.0f) shr->combined[1]= 0.0f; + if(shr->combined[2]<0.0f) shr->combined[2]= 0.0f; +} diff --git a/source/blender/nodes/shader/node_shader_util.c b/source/blender/nodes/shader/node_shader_util.c new file mode 100644 index 00000000000..cf910ba3f64 --- /dev/null +++ b/source/blender/nodes/shader/node_shader_util.c @@ -0,0 +1,287 @@ +/* + * $Id: SHD_util.c 36549 2011-05-08 14:23:38Z lukastoenne $ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2005 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/nodes/shader/node_shader_util.c + * \ingroup nodes + */ + + +#include "DNA_node_types.h" + +#include "node_shader_util.h" + +#include "node_exec.h" + +/* ****** */ + +void nodestack_get_vec(float *in, short type_in, bNodeStack *ns) +{ + float *from= ns->vec; + + if(type_in==SOCK_FLOAT) { + if(ns->sockettype==SOCK_FLOAT) + *in= *from; + else + *in= 0.333333f*(from[0]+from[1]+from[2]); + } + else if(type_in==SOCK_VECTOR) { + if(ns->sockettype==SOCK_FLOAT) { + in[0]= from[0]; + in[1]= from[0]; + in[2]= from[0]; + } + else { + VECCOPY(in, from); + } + } + else { /* type_in==SOCK_RGBA */ + if(ns->sockettype==SOCK_RGBA) { + QUATCOPY(in, from); + } + else if(ns->sockettype==SOCK_FLOAT) { + in[0]= from[0]; + in[1]= from[0]; + in[2]= from[0]; + in[3]= 1.0f; + } + else { + VECCOPY(in, from); + in[3]= 1.0f; + } + } +} + + +/* ******************* execute and parse ************ */ + +/* go over all used Geometry and Texture nodes, and return a texco flag */ +/* no group inside needed, this function is called for groups too */ +void ntreeShaderGetTexcoMode(bNodeTree *ntree, int r_mode, short *texco, int *mode) +{ + bNode *node; + bNodeSocket *sock; + int a; + + ntreeSocketUseFlags(ntree); + + for(node= ntree->nodes.first; node; node= node->next) { + if(node->type==SH_NODE_TEXTURE) { + if((r_mode & R_OSA) && node->id) { + Tex *tex= (Tex *)node->id; + if ELEM3(tex->type, TEX_IMAGE, TEX_PLUGIN, TEX_ENVMAP) + *texco |= TEXCO_OSA|NEED_UV; + } + /* usability exception... without input we still give the node orcos */ + sock= node->inputs.first; + if(sock==NULL || sock->link==NULL) + *texco |= TEXCO_ORCO|NEED_UV; + } + else if(node->type==SH_NODE_GEOMETRY) { + /* note; sockets always exist for the given type! */ + for(a=0, sock= node->outputs.first; sock; sock= sock->next, a++) { + if(sock->flag & SOCK_IN_USE) { + switch(a) { + case GEOM_OUT_GLOB: + *texco |= TEXCO_GLOB|NEED_UV; break; + case GEOM_OUT_VIEW: + *texco |= TEXCO_VIEW|NEED_UV; break; + case GEOM_OUT_ORCO: + *texco |= TEXCO_ORCO|NEED_UV; break; + case GEOM_OUT_UV: + *texco |= TEXCO_UV|NEED_UV; break; + case GEOM_OUT_NORMAL: + *texco |= TEXCO_NORM|NEED_UV; break; + case GEOM_OUT_VCOL: + *texco |= NEED_UV; *mode |= MA_VERTEXCOL; break; + } + } + } + } + } +} + +/* nodes that use ID data get synced with local data */ +void nodeShaderSynchronizeID(bNode *node, int copyto) +{ + if(node->id==NULL) return; + + if(ELEM(node->type, SH_NODE_MATERIAL, SH_NODE_MATERIAL_EXT)) { + bNodeSocket *sock; + Material *ma= (Material *)node->id; + int a; + + /* hrmf, case in loop isnt super fast, but we dont edit 100s of material at same time either! */ + for(a=0, sock= node->inputs.first; sock; sock= sock->next, a++) { + if(!(sock->flag & SOCK_HIDDEN)) { + if(copyto) { + switch(a) { + case MAT_IN_COLOR: + VECCOPY(&ma->r, ((bNodeSocketValueRGBA*)sock->default_value)->value); break; + case MAT_IN_SPEC: + VECCOPY(&ma->specr, ((bNodeSocketValueRGBA*)sock->default_value)->value); break; + case MAT_IN_REFL: + ma->ref= ((bNodeSocketValueFloat*)sock->default_value)->value; break; + case MAT_IN_MIR: + VECCOPY(&ma->mirr, ((bNodeSocketValueRGBA*)sock->default_value)->value); break; + case MAT_IN_AMB: + ma->amb= ((bNodeSocketValueFloat*)sock->default_value)->value; break; + case MAT_IN_EMIT: + ma->emit= ((bNodeSocketValueFloat*)sock->default_value)->value; break; + case MAT_IN_SPECTRA: + ma->spectra= ((bNodeSocketValueFloat*)sock->default_value)->value; break; + case MAT_IN_RAY_MIRROR: + ma->ray_mirror= ((bNodeSocketValueFloat*)sock->default_value)->value; break; + case MAT_IN_ALPHA: + ma->alpha= ((bNodeSocketValueFloat*)sock->default_value)->value; break; + case MAT_IN_TRANSLUCENCY: + ma->translucency= ((bNodeSocketValueFloat*)sock->default_value)->value; break; + } + } + else { + switch(a) { + case MAT_IN_COLOR: + VECCOPY(((bNodeSocketValueRGBA*)sock->default_value)->value, &ma->r); break; + case MAT_IN_SPEC: + VECCOPY(((bNodeSocketValueRGBA*)sock->default_value)->value, &ma->specr); break; + case MAT_IN_REFL: + ((bNodeSocketValueFloat*)sock->default_value)->value= ma->ref; break; + case MAT_IN_MIR: + VECCOPY(((bNodeSocketValueRGBA*)sock->default_value)->value, &ma->mirr); break; + case MAT_IN_AMB: + ((bNodeSocketValueFloat*)sock->default_value)->value= ma->amb; break; + case MAT_IN_EMIT: + ((bNodeSocketValueFloat*)sock->default_value)->value= ma->emit; break; + case MAT_IN_SPECTRA: + ((bNodeSocketValueFloat*)sock->default_value)->value= ma->spectra; break; + case MAT_IN_RAY_MIRROR: + ((bNodeSocketValueFloat*)sock->default_value)->value= ma->ray_mirror; break; + case MAT_IN_ALPHA: + ((bNodeSocketValueFloat*)sock->default_value)->value= ma->alpha; break; + case MAT_IN_TRANSLUCENCY: + ((bNodeSocketValueFloat*)sock->default_value)->value= ma->translucency; break; + } + } + } + } + } + +} + + +void node_gpu_stack_from_data(struct GPUNodeStack *gs, int type, bNodeStack *ns) +{ + memset(gs, 0, sizeof(*gs)); + + QUATCOPY(gs->vec, ns->vec); + gs->link= ns->data; + + if (type == SOCK_FLOAT) + gs->type= GPU_FLOAT; + else if (type == SOCK_VECTOR) + gs->type= GPU_VEC3; + else if (type == SOCK_RGBA) + gs->type= GPU_VEC4; + else + gs->type= GPU_NONE; + + gs->name = ""; + gs->hasinput= ns->hasinput && ns->data; + gs->hasoutput= ns->hasoutput && ns->data; + gs->sockettype= ns->sockettype; +} + +void node_data_from_gpu_stack(bNodeStack *ns, GPUNodeStack *gs) +{ + ns->data= gs->link; + ns->sockettype= gs->sockettype; +} + +static void gpu_stack_from_data_list(GPUNodeStack *gs, ListBase *sockets, bNodeStack **ns) +{ + bNodeSocket *sock; + int i; + + for (sock=sockets->first, i=0; sock; sock=sock->next, i++) + node_gpu_stack_from_data(&gs[i], sock->type, ns[i]); + + gs[i].type= GPU_NONE; +} + +static void data_from_gpu_stack_list(ListBase *sockets, bNodeStack **ns, GPUNodeStack *gs) +{ + bNodeSocket *sock; + int i; + + for (sock=sockets->first, i=0; sock; sock=sock->next, i++) + node_data_from_gpu_stack(ns[i], &gs[i]); +} + +void ntreeExecGPUNodes(bNodeTreeExec *exec, GPUMaterial *mat, int do_outputs) +{ + bNodeExec *nodeexec; + bNode *node; + int n; + bNodeStack *stack; + bNodeStack *nsin[MAX_SOCKET]; /* arbitrary... watch this */ + bNodeStack *nsout[MAX_SOCKET]; /* arbitrary... watch this */ + GPUNodeStack gpuin[MAX_SOCKET+1], gpuout[MAX_SOCKET+1]; + int doit; + + stack= exec->stack; + + for(n=0, nodeexec= exec->nodeexec; n < exec->totnodes; ++n, ++nodeexec) { + node = nodeexec->node; + + doit = 0; + /* for groups, only execute outputs for edited group */ + if(node->typeinfo->nclass==NODE_CLASS_OUTPUT) { + if(do_outputs && (node->flag & NODE_DO_OUTPUT)) + doit = 1; + } + else + doit = 1; + + if (doit) { + if(node->typeinfo->gpufunc) { + node_get_stack(node, stack, nsin, nsout); + gpu_stack_from_data_list(gpuin, &node->inputs, nsin); + gpu_stack_from_data_list(gpuout, &node->outputs, nsout); + if(node->typeinfo->gpufunc(mat, node, gpuin, gpuout)) + data_from_gpu_stack_list(&node->outputs, nsout, gpuout); + } + else if(node->typeinfo->gpuextfunc) { + node_get_stack(node, stack, nsin, nsout); + gpu_stack_from_data_list(gpuin, &node->inputs, nsin); + gpu_stack_from_data_list(gpuout, &node->outputs, nsout); + if(node->typeinfo->gpuextfunc(mat, node, nodeexec->data, gpuin, gpuout)) + data_from_gpu_stack_list(&node->outputs, nsout, gpuout); + } + } + } +} diff --git a/source/blender/nodes/intern/SHD_util.h b/source/blender/nodes/shader/node_shader_util.h similarity index 86% rename from source/blender/nodes/intern/SHD_util.h rename to source/blender/nodes/shader/node_shader_util.h index e6b1377067d..1cc04d95d6f 100644 --- a/source/blender/nodes/intern/SHD_util.h +++ b/source/blender/nodes/shader/node_shader_util.h @@ -1,5 +1,5 @@ /* - * $Id$ + * $Id: SHD_util.h 36549 2011-05-08 14:23:38Z lukastoenne $ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -27,13 +27,13 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/nodes/intern/SHD_util.h +/** \file blender/nodes/shader/node_shader_util.h * \ingroup nodes */ -#ifndef SHD_NODE_UTIL_H_ -#define SHD_NODE_UTIL_H_ +#ifndef NODE_SHADER_UTIL_H_ +#define NODE_SHADER_UTIL_H_ #include #include @@ -61,7 +61,7 @@ #include "BKE_library.h" -#include "../SHD_node.h" +#include "NOD_shader.h" #include "node_util.h" #include "BLI_math.h" @@ -122,4 +122,9 @@ typedef struct ShaderCallData { extern void node_ID_title_cb(void *node_v, void *unused_v); void nodestack_get_vec(float *in, short type_in, bNodeStack *ns); +void node_gpu_stack_from_data(struct GPUNodeStack *gs, int type, struct bNodeStack *ns); +void node_data_from_gpu_stack(struct bNodeStack *ns, struct GPUNodeStack *gs); + +void ntreeExecGPUNodes(struct bNodeTreeExec *exec, struct GPUMaterial *mat, int do_outputs); + #endif diff --git a/source/blender/nodes/intern/SHD_nodes/SHD_camera.c b/source/blender/nodes/shader/nodes/node_shader_camera.c similarity index 80% rename from source/blender/nodes/intern/SHD_nodes/SHD_camera.c rename to source/blender/nodes/shader/nodes/node_shader_camera.c index eea572bf271..ecb7c486dc4 100644 --- a/source/blender/nodes/intern/SHD_nodes/SHD_camera.c +++ b/source/blender/nodes/shader/nodes/node_shader_camera.c @@ -1,5 +1,5 @@ /* - * $Id$ + * $Id: SHD_camera.c 36536 2011-05-07 13:27:27Z lukastoenne $ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -27,18 +27,18 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/nodes/intern/SHD_nodes/SHD_camera.c +/** \file blender/nodes/shader/nodes/node_shader_camera.c * \ingroup shdnodes */ -#include "../SHD_util.h" +#include "node_shader_util.h" /* **************** CAMERA INFO ******************** */ -static bNodeSocketType sh_node_camera_out[]= { - { SOCK_VECTOR, 0, "View Vector", 1.0f, 0.0f, 0.0f, 0.0f, -1.0f, 1.0f}, /* None of these actually */ - { SOCK_VALUE, 0, "View Z Depth", 0.f, 0.0f, 0.0f, 0.0f, 0.0f, 99999999999.0f}, /* have any limits on their */ - { SOCK_VALUE, 0, "View Distance", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 99999999999.0f}, /* values. */ +static bNodeSocketTemplate sh_node_camera_out[]= { + { SOCK_VECTOR, 0, "View Vector"}, + { SOCK_FLOAT, 0, "View Z Depth"}, + { SOCK_FLOAT, 0, "View Distance"}, { -1, 0, "" } }; @@ -63,8 +63,8 @@ void register_node_type_sh_camera(ListBase *lb) { static bNodeType ntype; - node_type_base(&ntype, SH_NODE_CAMERA, "Camera Data", NODE_CLASS_INPUT, 0, - NULL, sh_node_camera_out); + node_type_base(&ntype, SH_NODE_CAMERA, "Camera Data", NODE_CLASS_INPUT, 0); + node_type_socket_templates(&ntype, NULL, sh_node_camera_out); node_type_size(&ntype, 95, 95, 120); node_type_storage(&ntype, "node_camera", NULL, NULL); node_type_exec(&ntype, node_shader_exec_camera); diff --git a/source/blender/nodes/shader/nodes/node_shader_common.c b/source/blender/nodes/shader/nodes/node_shader_common.c new file mode 100644 index 00000000000..ab3638436f1 --- /dev/null +++ b/source/blender/nodes/shader/nodes/node_shader_common.c @@ -0,0 +1,327 @@ +/* + * $Id: CMP_blur.c 35562 2011-03-15 20:10:32Z lukastoenne $ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2006 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): Campbell Barton, Alfredo de Greef, David Millan Escriva, + * Juho Vepsäläinen + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/nodes/shader/nodes/node_shader_common.c + * \ingroup shdnodes + */ + + +#include "DNA_node_types.h" + +#include "BKE_node.h" + +#include "node_shader_util.h" +#include "node_common.h" +#include "node_exec.h" + +static void copy_stack(bNodeStack *to, bNodeStack *from) +{ + if (to != from) { + copy_v4_v4(to->vec, from->vec); + to->data = from->data; + to->datatype = from->datatype; + + /* tag as copy to prevent freeing */ + to->is_copy = 1; + } +} + +static void move_stack(bNodeStack *to, bNodeStack *from) +{ + if (to != from) { + copy_v4_v4(to->vec, from->vec); + to->data = from->data; + to->datatype = from->datatype; + to->is_copy = from->is_copy; + + zero_v4(from->vec); + from->data = NULL; + from->datatype = 0; + from->is_copy = 0; + } +} + +/**** GROUP ****/ + +static void *group_initexec(bNode *node) +{ + bNodeTree *ngroup= (bNodeTree*)node->id; + bNodeTreeExec *exec; + + /* initialize the internal node tree execution */ + exec = ntreeShaderBeginExecTree(ngroup); + + return exec; +} + +static void group_freeexec(bNode *UNUSED(node), void *nodedata) +{ + bNodeTreeExec*gexec= (bNodeTreeExec*)nodedata; + + ntreeShaderEndExecTree(gexec); +} + +/* Copy inputs to the internal stack. + */ +static void group_copy_inputs(bNode *node, bNodeStack **in, bNodeStack *gstack) +{ + bNodeSocket *sock; + bNodeStack *ns; + int a; + for (sock=node->inputs.first, a=0; sock; sock=sock->next, ++a) { + if (sock->groupsock) { + ns = node_get_socket_stack(gstack, sock->groupsock); + copy_stack(ns, in[a]); + } + } +} + +/* Copy internal results to the external outputs. + */ +static void group_move_outputs(bNode *node, bNodeStack **out, bNodeStack *gstack) +{ + bNodeSocket *sock; + bNodeStack *ns; + int a; + for (sock=node->outputs.first, a=0; sock; sock=sock->next, ++a) { + if (sock->groupsock) { + ns = node_get_socket_stack(gstack, sock->groupsock); + move_stack(out[a], ns); + } + } +} + +static void group_execute(void *data, int thread, struct bNode *node, void *nodedata, struct bNodeStack **in, struct bNodeStack **out) +{ + bNodeTreeExec *exec= (bNodeTreeExec*)nodedata; + bNodeThreadStack *nts; + + /* XXX same behavior as trunk: all nodes inside group are executed. + * it's stupid, but just makes it work. compo redesign will do this better. + */ + { + bNode *inode; + for (inode=exec->nodetree->nodes.first; inode; inode=inode->next) + inode->need_exec = 1; + } + + nts = ntreeGetThreadStack(exec, thread); + + group_copy_inputs(node, in, nts->stack); + ntreeExecThreadNodes(exec, nts, data, thread); + group_move_outputs(node, out, nts->stack); + + ntreeReleaseThreadStack(nts); +} + +static void group_gpu_copy_inputs(bNode *node, GPUNodeStack *in, bNodeStack *gstack) +{ + bNodeSocket *sock; + bNodeStack *ns; + int a; + for (sock=node->inputs.first, a=0; sock; sock=sock->next, ++a) { + if (sock->groupsock) { + ns = node_get_socket_stack(gstack, sock->groupsock); + /* convert the external gpu stack back to internal node stack data */ + node_data_from_gpu_stack(ns, &in[a]); + } + } +} + +/* Copy internal results to the external outputs. + */ +static void group_gpu_move_outputs(bNode *node, GPUNodeStack *out, bNodeStack *gstack) +{ + bNodeSocket *sock; + bNodeStack *ns; + int a; + for (sock=node->outputs.first, a=0; sock; sock=sock->next, ++a) { + if (sock->groupsock) { + ns = node_get_socket_stack(gstack, sock->groupsock); + /* convert the node stack data result back to gpu stack */ + node_gpu_stack_from_data(&out[a], sock->type, ns); + } + } +} + +static int gpu_group_execute(GPUMaterial *mat, bNode *node, void *nodedata, GPUNodeStack *in, GPUNodeStack *out) +{ + bNodeTreeExec *exec= (bNodeTreeExec*)nodedata; + + group_gpu_copy_inputs(node, in, exec->stack); + ntreeExecGPUNodes(exec, mat, (node->flag & NODE_GROUP_EDIT)); + group_gpu_move_outputs(node, out, exec->stack); + + return 1; +} + +void register_node_type_sh_group(ListBase *lb) +{ + static bNodeType ntype; + + node_type_base(&ntype, NODE_GROUP, "Group", NODE_CLASS_GROUP, NODE_OPTIONS|NODE_CONST_OUTPUT); + node_type_socket_templates(&ntype, NULL, NULL); + node_type_size(&ntype, 120, 60, 200); + node_type_label(&ntype, node_group_label); + node_type_init(&ntype, node_group_init); + node_type_valid(&ntype, node_group_valid); + node_type_template(&ntype, node_group_template); + node_type_update(&ntype, NULL, node_group_verify); + node_type_group_edit(&ntype, node_group_edit_get, node_group_edit_set, node_group_edit_clear); + node_type_exec_new(&ntype, group_initexec, group_freeexec, group_execute); + node_type_gpu_ext(&ntype, gpu_group_execute); + + nodeRegisterType(lb, &ntype); +} + + +/**** FOR LOOP ****/ + +#if 0 /* XXX loop nodes don't work nicely with current trees */ +static void forloop_execute(void *data, int thread, struct bNode *node, void *nodedata, struct bNodeStack **in, struct bNodeStack **out) +{ + bNodeTreeExec *exec= (bNodeTreeExec*)nodedata; + bNodeThreadStack *nts; + int iterations= (int)in[0]->vec[0]; + bNodeSocket *sock; + bNodeStack *ns; + int iteration; + + /* XXX same behavior as trunk: all nodes inside group are executed. + * it's stupid, but just makes it work. compo redesign will do this better. + */ + { + bNode *inode; + for (inode=exec->nodetree->nodes.first; inode; inode=inode->next) + inode->need_exec = 1; + } + + nts = ntreeGetThreadStack(exec, thread); + + /* "Iteration" socket */ + sock = exec->nodetree->inputs.first; + ns = node_get_socket_stack(nts->stack, sock); + +// group_copy_inputs(node, in, nts->stack); + for (iteration=0; iteration < iterations; ++iteration) { + /* first input contains current iteration counter */ + ns->vec[0] = (float)iteration; + ns->vec[1]=ns->vec[2]=ns->vec[3] = 0.0f; + +// if (iteration > 0) +// loop_init_iteration(exec->nodetree, nts->stack); +// ntreeExecThreadNodes(exec, nts, data, thread); + } +// loop_copy_outputs(node, in, out, exec->stack); + + ntreeReleaseThreadStack(nts); +} + +void register_node_type_sh_forloop(ListBase *lb) +{ + static bNodeType ntype; + + node_type_base(&ntype, NODE_FORLOOP, "For", NODE_CLASS_GROUP, NODE_OPTIONS); + node_type_socket_templates(&ntype, NULL, NULL); + node_type_size(&ntype, 120, 60, 200); + node_type_label(&ntype, node_group_label); + node_type_init(&ntype, node_forloop_init); + node_type_valid(&ntype, node_group_valid); + node_type_template(&ntype, node_forloop_template); + node_type_update(&ntype, NULL, node_group_verify); + node_type_tree(&ntype, node_forloop_init_tree, node_loop_update_tree); + node_type_group_edit(&ntype, node_group_edit_get, node_group_edit_set, node_group_edit_clear); + node_type_exec_new(&ntype, group_initexec, group_freeexec, forloop_execute); + + nodeRegisterType(lb, &ntype); +} +#endif + +/**** WHILE LOOP ****/ + +#if 0 /* XXX loop nodes don't work nicely with current trees */ +static void whileloop_execute(void *data, int thread, struct bNode *node, void *nodedata, struct bNodeStack **in, struct bNodeStack **out) +{ + bNodeTreeExec *exec= (bNodeTreeExec*)nodedata; + bNodeThreadStack *nts; + int condition= (in[0]->vec[0] > 0.0f); + bNodeSocket *sock; + bNodeStack *ns; + int iteration; + + /* XXX same behavior as trunk: all nodes inside group are executed. + * it's stupid, but just makes it work. compo redesign will do this better. + */ + { + bNode *inode; + for (inode=exec->nodetree->nodes.first; inode; inode=inode->next) + inode->need_exec = 1; + } + + nts = ntreeGetThreadStack(exec, thread); + + /* "Condition" socket */ + sock = exec->nodetree->outputs.first; + ns = node_get_socket_stack(nts->stack, sock); + + iteration = 0; +// group_copy_inputs(node, in, nts->stack); + while (condition && iteration < node->custom1) { +// if (iteration > 0) +// loop_init_iteration(exec->nodetree, nts->stack); +// ntreeExecThreadNodes(exec, nts, data, thread); + + condition = (ns->vec[0] > 0.0f); + ++iteration; + } +// loop_copy_outputs(node, in, out, exec->stack); + + ntreeReleaseThreadStack(nts); +} + +void register_node_type_sh_whileloop(ListBase *lb) +{ + static bNodeType ntype; + + node_type_base(&ntype, NODE_WHILELOOP, "While", NODE_CLASS_GROUP, NODE_OPTIONS); + node_type_socket_templates(&ntype, NULL, NULL); + node_type_size(&ntype, 120, 60, 200); + node_type_label(&ntype, node_group_label); + node_type_init(&ntype, node_whileloop_init); + node_type_valid(&ntype, node_group_valid); + node_type_template(&ntype, node_whileloop_template); + node_type_update(&ntype, NULL, node_group_verify); + node_type_tree(&ntype, node_whileloop_init_tree, node_loop_update_tree); + node_type_group_edit(&ntype, node_group_edit_get, node_group_edit_set, node_group_edit_clear); + node_type_exec_new(&ntype, group_initexec, group_freeexec, whileloop_execute); + + nodeRegisterType(lb, &ntype); +} +#endif diff --git a/source/blender/nodes/intern/SHD_nodes/SHD_curves.c b/source/blender/nodes/shader/nodes/node_shader_curves.c similarity index 76% rename from source/blender/nodes/intern/SHD_nodes/SHD_curves.c rename to source/blender/nodes/shader/nodes/node_shader_curves.c index a39a639897e..ded867ec441 100644 --- a/source/blender/nodes/intern/SHD_nodes/SHD_curves.c +++ b/source/blender/nodes/shader/nodes/node_shader_curves.c @@ -1,5 +1,5 @@ /* - * $Id$ + * $Id: SHD_curves.c 36593 2011-05-10 11:19:26Z lukastoenne $ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -27,23 +27,23 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/nodes/intern/SHD_nodes/SHD_curves.c +/** \file blender/nodes/shader/nodes/node_shader_curves.c * \ingroup shdnodes */ -#include "../SHD_util.h" +#include "node_shader_util.h" /* **************** CURVE VEC ******************** */ -static bNodeSocketType sh_node_curve_vec_in[]= { - { SOCK_VALUE, 0, "Fac", 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f}, - { SOCK_VECTOR, 1, "Vector", 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f}, +static bNodeSocketTemplate sh_node_curve_vec_in[]= { + { SOCK_FLOAT, 0, "Fac", 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, PROP_FACTOR}, + { SOCK_VECTOR, 1, "Vector", 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, PROP_NONE}, { -1, 0, "" } }; -static bNodeSocketType sh_node_curve_vec_out[]= { - { SOCK_VECTOR, 0, "Vector", 0.0f, 0.0f, 1.0f, 1.0f, -1.0f, 1.0f}, +static bNodeSocketTemplate sh_node_curve_vec_out[]= { + { SOCK_VECTOR, 0, "Vector"}, { -1, 0, "" } }; @@ -57,7 +57,7 @@ static void node_shader_exec_curve_vec(void *UNUSED(data), bNode *node, bNodeSta curvemapping_evaluate3F(node->storage, out[0]->vec, vec); } -static void node_shader_init_curve_vec(bNode* node) +static void node_shader_init_curve_vec(bNodeTree *UNUSED(ntree), bNode* node, bNodeTemplate *UNUSED(ntemp)) { node->storage= curvemapping_add(3, -1.0f, -1.0f, 1.0f, 1.0f); } @@ -75,8 +75,8 @@ void register_node_type_sh_curve_vec(ListBase *lb) { static bNodeType ntype; - node_type_base(&ntype, SH_NODE_CURVE_VEC, "Vector Curves", NODE_CLASS_OP_VECTOR, NODE_OPTIONS, - sh_node_curve_vec_in, sh_node_curve_vec_out); + node_type_base(&ntype, SH_NODE_CURVE_VEC, "Vector Curves", NODE_CLASS_OP_VECTOR, NODE_OPTIONS); + node_type_socket_templates(&ntype, sh_node_curve_vec_in, sh_node_curve_vec_out); node_type_size(&ntype, 200, 140, 320); node_type_init(&ntype, node_shader_init_curve_vec); node_type_storage(&ntype, "CurveMapping", node_free_curves, node_copy_curves); @@ -88,14 +88,14 @@ void register_node_type_sh_curve_vec(ListBase *lb) /* **************** CURVE RGB ******************** */ -static bNodeSocketType sh_node_curve_rgb_in[]= { - { SOCK_VALUE, 1, "Fac", 1.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f}, - { SOCK_RGBA, 1, "Color", 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f}, +static bNodeSocketTemplate sh_node_curve_rgb_in[]= { + { SOCK_FLOAT, 1, "Fac", 1.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, PROP_FACTOR}, + { SOCK_RGBA, 1, "Color", 0.0f, 0.0f, 0.0f, 1.0f}, { -1, 0, "" } }; -static bNodeSocketType sh_node_curve_rgb_out[]= { - { SOCK_RGBA, 0, "Color", 0.0f, 0.0f, 1.0f, 1.0f, -1.0f, 1.0f}, +static bNodeSocketTemplate sh_node_curve_rgb_out[]= { + { SOCK_RGBA, 0, "Color"}, { -1, 0, "" } }; @@ -112,7 +112,7 @@ static void node_shader_exec_curve_rgb(void *UNUSED(data), bNode *node, bNodeSta } } -static void node_shader_init_curve_rgb(bNode *node) +static void node_shader_init_curve_rgb(bNodeTree *UNUSED(ntree), bNode* node, bNodeTemplate *UNUSED(ntemp)) { node->storage= curvemapping_add(4, 0.0f, 0.0f, 1.0f, 1.0f); } @@ -129,8 +129,8 @@ void register_node_type_sh_curve_rgb(ListBase *lb) { static bNodeType ntype; - node_type_base(&ntype, SH_NODE_CURVE_RGB, "RGB Curves", NODE_CLASS_OP_COLOR, NODE_OPTIONS, - sh_node_curve_rgb_in, sh_node_curve_rgb_out); + node_type_base(&ntype, SH_NODE_CURVE_RGB, "RGB Curves", NODE_CLASS_OP_COLOR, NODE_OPTIONS); + node_type_socket_templates(&ntype, sh_node_curve_rgb_in, sh_node_curve_rgb_out); node_type_size(&ntype, 200, 140, 320); node_type_init(&ntype, node_shader_init_curve_rgb); node_type_storage(&ntype, "CurveMapping", node_free_curves, node_copy_curves); diff --git a/source/blender/nodes/intern/SHD_nodes/SHD_dynamic.c b/source/blender/nodes/shader/nodes/node_shader_dynamic.c similarity index 99% rename from source/blender/nodes/intern/SHD_nodes/SHD_dynamic.c rename to source/blender/nodes/shader/nodes/node_shader_dynamic.c index d5e5d5eeb93..6490ee00787 100644 --- a/source/blender/nodes/intern/SHD_nodes/SHD_dynamic.c +++ b/source/blender/nodes/shader/nodes/node_shader_dynamic.c @@ -1,5 +1,5 @@ /* - * $Id$ + * $Id: SHD_dynamic.c 35927 2011-03-31 20:59:55Z lukastoenne $ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -27,7 +27,7 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/nodes/intern/SHD_nodes/SHD_dynamic.c +/** \file blender/nodes/shader/nodes/node_shader_dynamic.c * \ingroup shdnodes */ @@ -54,7 +54,7 @@ #endif #endif -#include "../SHD_util.h" +#include "node_shader_util.h" // XXX #if 0 @@ -95,7 +95,7 @@ static bNodeType *node_dynamic_find_typeinfo(ListBase *list, ID *id) static void node_dynamic_free_typeinfo_sockets(bNodeType *tinfo) { - bNodeSocketType *sock; + bNodeSocketTemplate *sock; if (!tinfo) return; @@ -782,7 +782,7 @@ void register_node_type_sh_dynamic(ListBase *lb) { static bNodeType ntype; - node_type_base(&ntype, NODE_DYNAMIC, "Dynamic", NODE_CLASS_OP_DYNAMIC, 0, NULL, NULL); + node_type_base(&ntype, NODE_DYNAMIC, "Dynamic", NODE_CLASS_OP_DYNAMIC, 0); nodeRegisterType(lb, &ntype); } diff --git a/source/blender/nodes/intern/SHD_nodes/SHD_geom.c b/source/blender/nodes/shader/nodes/node_shader_geom.c similarity index 84% rename from source/blender/nodes/intern/SHD_nodes/SHD_geom.c rename to source/blender/nodes/shader/nodes/node_shader_geom.c index 379f54bec57..b88c5979b54 100644 --- a/source/blender/nodes/intern/SHD_nodes/SHD_geom.c +++ b/source/blender/nodes/shader/nodes/node_shader_geom.c @@ -1,5 +1,5 @@ /* - * $Id$ + * $Id: SHD_geom.c 36536 2011-05-07 13:27:27Z lukastoenne $ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -27,27 +27,27 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/nodes/intern/SHD_nodes/SHD_geom.c +/** \file blender/nodes/shader/nodes/node_shader_geom.c * \ingroup shdnodes */ -#include "../SHD_util.h" +#include "node_shader_util.h" #include "DNA_customdata_types.h" /* **************** GEOMETRY ******************** */ /* output socket type definition */ -static bNodeSocketType sh_node_geom_out[]= { - { SOCK_VECTOR, 0, "Global", 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f}, /* btw; uses no limit */ - { SOCK_VECTOR, 0, "Local", 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f}, - { SOCK_VECTOR, 0, "View", 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f}, - { SOCK_VECTOR, 0, "Orco", 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f}, - { SOCK_VECTOR, 0, "UV", 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f}, - { SOCK_VECTOR, 0, "Normal", 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f}, - { SOCK_RGBA, 0, "Vertex Color", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, - { SOCK_VALUE, 0, "Front/Back", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate sh_node_geom_out[]= { + { SOCK_VECTOR, 0, "Global"}, + { SOCK_VECTOR, 0, "Local"}, + { SOCK_VECTOR, 0, "View"}, + { SOCK_VECTOR, 0, "Orco"}, + { SOCK_VECTOR, 0, "UV"}, + { SOCK_VECTOR, 0, "Normal"}, + { SOCK_RGBA, 0, "Vertex Color"}, + { SOCK_FLOAT, 0, "Front/Back"}, { -1, 0, "" } }; @@ -118,7 +118,7 @@ static void node_shader_exec_geom(void *data, bNode *node, bNodeStack **UNUSED(i } } -static void node_shader_init_geometry(bNode *node) +static void node_shader_init_geometry(bNodeTree *UNUSED(ntree), bNode* node, bNodeTemplate *UNUSED(ntemp)) { node->storage= MEM_callocN(sizeof(NodeGeometry), "NodeGeometry"); } @@ -140,8 +140,8 @@ void register_node_type_sh_geom(ListBase *lb) { static bNodeType ntype; - node_type_base(&ntype, SH_NODE_GEOMETRY, "Geometry", NODE_CLASS_INPUT, NODE_OPTIONS, - NULL, sh_node_geom_out); + node_type_base(&ntype, SH_NODE_GEOMETRY, "Geometry", NODE_CLASS_INPUT, NODE_OPTIONS); + node_type_socket_templates(&ntype, NULL, sh_node_geom_out); node_type_size(&ntype, 120, 80, 160); node_type_init(&ntype, node_shader_init_geometry); node_type_storage(&ntype, "NodeGeometry", node_free_standard_storage, node_copy_standard_storage); diff --git a/source/blender/nodes/intern/SHD_nodes/SHD_hueSatVal.c b/source/blender/nodes/shader/nodes/node_shader_hueSatVal.c similarity index 77% rename from source/blender/nodes/intern/SHD_nodes/SHD_hueSatVal.c rename to source/blender/nodes/shader/nodes/node_shader_hueSatVal.c index 91fd995dbbe..ef1434b82ca 100644 --- a/source/blender/nodes/intern/SHD_nodes/SHD_hueSatVal.c +++ b/source/blender/nodes/shader/nodes/node_shader_hueSatVal.c @@ -27,25 +27,25 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/nodes/intern/SHD_nodes/SHD_hueSatVal.c +/** \file blender/nodes/shader/nodes/node_shader_hueSatVal.c * \ingroup shdnodes */ -#include "../SHD_util.h" +#include "node_shader_util.h" /* **************** Hue Saturation ******************** */ -static bNodeSocketType sh_node_hue_sat_in[]= { - { SOCK_VALUE, 1, "Hue", 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, - { SOCK_VALUE, 1, "Saturation", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 2.0f}, - { SOCK_VALUE, 1, "Value", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 2.0f}, - { SOCK_VALUE, 1, "Fac", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, - { SOCK_RGBA, 1, "Color", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate sh_node_hue_sat_in[]= { + { SOCK_FLOAT, 1, "Hue", 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_NONE}, + { SOCK_FLOAT, 1, "Saturation", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 2.0f, PROP_FACTOR}, + { SOCK_FLOAT, 1, "Value", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 2.0f, PROP_FACTOR}, + { SOCK_FLOAT, 1, "Fac", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR}, + { SOCK_RGBA, 1, "Color", 0.8f, 0.8f, 0.8f, 1.0f}, { -1, 0, "" } }; -static bNodeSocketType sh_node_hue_sat_out[]= { - { SOCK_RGBA, 0, "Color", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate sh_node_hue_sat_out[]= { + { SOCK_RGBA, 0, "Color"}, { -1, 0, "" } }; @@ -86,8 +86,8 @@ void register_node_type_sh_hue_sat(ListBase *lb) { static bNodeType ntype; - node_type_base(&ntype, SH_NODE_HUE_SAT, "Hue Saturation Value", NODE_CLASS_OP_COLOR, NODE_OPTIONS, - sh_node_hue_sat_in, sh_node_hue_sat_out); + node_type_base(&ntype, SH_NODE_HUE_SAT, "Hue Saturation Value", NODE_CLASS_OP_COLOR, NODE_OPTIONS); + node_type_socket_templates(&ntype, sh_node_hue_sat_in, sh_node_hue_sat_out); node_type_size(&ntype, 150, 80, 250); node_type_exec(&ntype, node_shader_exec_hue_sat); node_type_gpu(&ntype, gpu_shader_hue_sat); diff --git a/source/blender/nodes/intern/SHD_nodes/SHD_invert.c b/source/blender/nodes/shader/nodes/node_shader_invert.c similarity index 80% rename from source/blender/nodes/intern/SHD_nodes/SHD_invert.c rename to source/blender/nodes/shader/nodes/node_shader_invert.c index f8d6e54859e..bd7e571f073 100644 --- a/source/blender/nodes/intern/SHD_nodes/SHD_invert.c +++ b/source/blender/nodes/shader/nodes/node_shader_invert.c @@ -1,5 +1,5 @@ /* - * $Id$ + * $Id: SHD_invert.c 36593 2011-05-10 11:19:26Z lukastoenne $ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -27,24 +27,24 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/nodes/intern/SHD_nodes/SHD_invert.c +/** \file blender/nodes/shader/nodes/node_shader_invert.c * \ingroup shdnodes */ -#include "../SHD_util.h" +#include "node_shader_util.h" /* **************** INVERT ******************** */ -static bNodeSocketType sh_node_invert_in[]= { - { SOCK_VALUE, 1, "Fac", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, - { SOCK_RGBA, 1, "Color", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate sh_node_invert_in[]= { + { SOCK_FLOAT, 1, "Fac", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR}, + { SOCK_RGBA, 1, "Color", 0.0f, 0.0f, 0.0f, 1.0f}, { -1, 0, "" } }; -static bNodeSocketType sh_node_invert_out[]= { - { SOCK_RGBA, 0, "Color", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate sh_node_invert_out[]= { + { SOCK_RGBA, 0, "Color"}, { -1, 0, "" } }; @@ -78,8 +78,8 @@ void register_node_type_sh_invert(ListBase *lb) { static bNodeType ntype; - node_type_base(&ntype, SH_NODE_INVERT, "Invert", NODE_CLASS_OP_COLOR, NODE_OPTIONS, - sh_node_invert_in, sh_node_invert_out); + node_type_base(&ntype, SH_NODE_INVERT, "Invert", NODE_CLASS_OP_COLOR, NODE_OPTIONS); + node_type_socket_templates(&ntype, sh_node_invert_in, sh_node_invert_out); node_type_size(&ntype, 90, 80, 100); node_type_exec(&ntype, node_shader_exec_invert); node_type_gpu(&ntype, gpu_shader_invert); diff --git a/source/blender/nodes/intern/SHD_nodes/SHD_mapping.c b/source/blender/nodes/shader/nodes/node_shader_mapping.c similarity index 85% rename from source/blender/nodes/intern/SHD_nodes/SHD_mapping.c rename to source/blender/nodes/shader/nodes/node_shader_mapping.c index eb300301ce2..21cea4853ad 100644 --- a/source/blender/nodes/intern/SHD_nodes/SHD_mapping.c +++ b/source/blender/nodes/shader/nodes/node_shader_mapping.c @@ -1,5 +1,5 @@ /* - * $Id$ + * $Id: SHD_mapping.c 36593 2011-05-10 11:19:26Z lukastoenne $ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -27,21 +27,21 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/nodes/intern/SHD_nodes/SHD_mapping.c +/** \file blender/nodes/shader/nodes/node_shader_mapping.c * \ingroup shdnodes */ -#include "../SHD_util.h" +#include "node_shader_util.h" /* **************** MAPPING ******************** */ -static bNodeSocketType sh_node_mapping_in[]= { - { SOCK_VECTOR, 1, "Vector", 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f}, +static bNodeSocketTemplate sh_node_mapping_in[]= { + { SOCK_VECTOR, 1, "Vector", 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, PROP_NONE}, { -1, 0, "" } }; -static bNodeSocketType sh_node_mapping_out[]= { - { SOCK_VECTOR, 0, "Vector", 0.0f, 0.0f, 1.0f, 1.0f, -1.0f, 1.0f}, +static bNodeSocketTemplate sh_node_mapping_out[]= { + { SOCK_VECTOR, 0, "Vector"}, { -1, 0, "" } }; @@ -69,7 +69,7 @@ static void node_shader_exec_mapping(void *UNUSED(data), bNode *node, bNodeStack } -static void node_shader_init_mapping(bNode *node) +static void node_shader_init_mapping(bNodeTree *UNUSED(ntree), bNode* node, bNodeTemplate *UNUSED(ntemp)) { node->storage= add_mapping(); } @@ -92,8 +92,8 @@ void register_node_type_sh_mapping(ListBase *lb) { static bNodeType ntype; - node_type_base(&ntype, SH_NODE_MAPPING, "Mapping", NODE_CLASS_OP_VECTOR, NODE_OPTIONS, - sh_node_mapping_in, sh_node_mapping_out); + node_type_base(&ntype, SH_NODE_MAPPING, "Mapping", NODE_CLASS_OP_VECTOR, NODE_OPTIONS); + node_type_socket_templates(&ntype, sh_node_mapping_in, sh_node_mapping_out); node_type_size(&ntype, 240, 160, 320); node_type_init(&ntype, node_shader_init_mapping); node_type_storage(&ntype, "TexMapping", node_free_standard_storage, node_copy_standard_storage); diff --git a/source/blender/nodes/intern/SHD_nodes/SHD_material.c b/source/blender/nodes/shader/nodes/node_shader_material.c similarity index 77% rename from source/blender/nodes/intern/SHD_nodes/SHD_material.c rename to source/blender/nodes/shader/nodes/node_shader_material.c index f78dd9ec727..a0bfd430506 100644 --- a/source/blender/nodes/intern/SHD_nodes/SHD_material.c +++ b/source/blender/nodes/shader/nodes/node_shader_material.c @@ -1,5 +1,5 @@ /* - * $Id$ + * $Id: SHD_material.c 36593 2011-05-10 11:19:26Z lukastoenne $ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -27,54 +27,54 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/nodes/intern/SHD_nodes/SHD_material.c +/** \file blender/nodes/shader/nodes/node_shader_material.c * \ingroup shdnodes */ -#include "../SHD_util.h" +#include "node_shader_util.h" /* **************** MATERIAL ******************** */ -static bNodeSocketType sh_node_material_in[]= { - { SOCK_RGBA, 1, "Color", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, - { SOCK_RGBA, 1, "Spec", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, - { SOCK_VALUE, 1, "Refl", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, - { SOCK_VECTOR, 1, "Normal", 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f}, +static bNodeSocketTemplate sh_node_material_in[]= { + { SOCK_RGBA, 1, "Color", 0.0f, 0.0f, 0.0f, 1.0f}, + { SOCK_RGBA, 1, "Spec", 0.0f, 0.0f, 0.0f, 1.0f}, + { SOCK_FLOAT, 1, "Refl", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, PROP_FACTOR}, + { SOCK_VECTOR, 1, "Normal", 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, PROP_DIRECTION}, { -1, 0, "" } }; -static bNodeSocketType sh_node_material_out[]= { - { SOCK_RGBA, 0, "Color", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, - { SOCK_VALUE, 0, "Alpha", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, - { SOCK_VECTOR, 0, "Normal", 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f}, +static bNodeSocketTemplate sh_node_material_out[]= { + { SOCK_RGBA, 0, "Color"}, + { SOCK_FLOAT, 0, "Alpha"}, + { SOCK_VECTOR, 0, "Normal"}, { -1, 0, "" } }; /* **************** EXTENDED MATERIAL ******************** */ -static bNodeSocketType sh_node_material_ext_in[]= { - { SOCK_RGBA, 1, "Color", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, - { SOCK_RGBA, 1, "Spec", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, - { SOCK_VALUE, 1, "Refl", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, - { SOCK_VECTOR, 1, "Normal", 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f}, - { SOCK_RGBA, 1, "Mirror", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, - { SOCK_VALUE, 1, "Ambient", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, - { SOCK_VALUE, 1, "Emit", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, - { SOCK_VALUE, 1, "SpecTra", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, - { SOCK_VALUE, 1, "Ray Mirror", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, - { SOCK_VALUE, 1, "Alpha", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, - { SOCK_VALUE, 1, "Translucency", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate sh_node_material_ext_in[]= { + { SOCK_RGBA, 1, "Color", 0.0f, 0.0f, 0.0f, 1.0f}, + { SOCK_RGBA, 1, "Spec", 0.0f, 0.0f, 0.0f, 1.0f}, + { SOCK_FLOAT, 1, "Refl", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, PROP_FACTOR}, + { SOCK_VECTOR, 1, "Normal", 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, PROP_DIRECTION}, + { SOCK_RGBA, 1, "Mirror", 0.0f, 0.0f, 0.0f, 1.0f}, + { SOCK_FLOAT, 1, "Ambient", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, PROP_FACTOR}, + { SOCK_FLOAT, 1, "Emit", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, PROP_UNSIGNED}, + { SOCK_FLOAT, 1, "SpecTra", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, PROP_FACTOR}, + { SOCK_FLOAT, 1, "Ray Mirror", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR}, + { SOCK_FLOAT, 1, "Alpha", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, PROP_UNSIGNED}, + { SOCK_FLOAT, 1, "Translucency", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, PROP_FACTOR}, { -1, 0, "" } }; -static bNodeSocketType sh_node_material_ext_out[]= { - { SOCK_RGBA, 0, "Color", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, - { SOCK_VALUE, 0, "Alpha", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, - { SOCK_VECTOR, 0, "Normal", 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f}, - { SOCK_RGBA, 0, "Diffuse", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, - { SOCK_RGBA, 0, "Spec", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, - { SOCK_RGBA, 0, "AO", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate sh_node_material_ext_out[]= { + { SOCK_RGBA, 0, "Color"}, + { SOCK_FLOAT, 0, "Alpha"}, + { SOCK_VECTOR, 0, "Normal"}, + { SOCK_RGBA, 0, "Diffuse"}, + { SOCK_RGBA, 0, "Spec"}, + { SOCK_RGBA, 0, "AO"}, { -1, 0, "" } }; @@ -112,7 +112,7 @@ static void node_shader_exec_material(void *data, bNode *node, bNodeStack **in, nodestack_get_vec(&shi->specr, SOCK_VECTOR, in[MAT_IN_SPEC]); if(hasinput[MAT_IN_REFL]) - nodestack_get_vec(&shi->refl, SOCK_VALUE, in[MAT_IN_REFL]); + nodestack_get_vec(&shi->refl, SOCK_FLOAT, in[MAT_IN_REFL]); /* retrieve normal */ if(hasinput[MAT_IN_NORMAL]) { @@ -133,17 +133,17 @@ static void node_shader_exec_material(void *data, bNode *node, bNodeStack **in, if(hasinput[MAT_IN_MIR]) nodestack_get_vec(&shi->mirr, SOCK_VECTOR, in[MAT_IN_MIR]); if(hasinput[MAT_IN_AMB]) - nodestack_get_vec(&shi->amb, SOCK_VALUE, in[MAT_IN_AMB]); + nodestack_get_vec(&shi->amb, SOCK_FLOAT, in[MAT_IN_AMB]); if(hasinput[MAT_IN_EMIT]) - nodestack_get_vec(&shi->emit, SOCK_VALUE, in[MAT_IN_EMIT]); + nodestack_get_vec(&shi->emit, SOCK_FLOAT, in[MAT_IN_EMIT]); if(hasinput[MAT_IN_SPECTRA]) - nodestack_get_vec(&shi->spectra, SOCK_VALUE, in[MAT_IN_SPECTRA]); + nodestack_get_vec(&shi->spectra, SOCK_FLOAT, in[MAT_IN_SPECTRA]); if(hasinput[MAT_IN_RAY_MIRROR]) - nodestack_get_vec(&shi->ray_mirror, SOCK_VALUE, in[MAT_IN_RAY_MIRROR]); + nodestack_get_vec(&shi->ray_mirror, SOCK_FLOAT, in[MAT_IN_RAY_MIRROR]); if(hasinput[MAT_IN_ALPHA]) - nodestack_get_vec(&shi->alpha, SOCK_VALUE, in[MAT_IN_ALPHA]); + nodestack_get_vec(&shi->alpha, SOCK_FLOAT, in[MAT_IN_ALPHA]); if(hasinput[MAT_IN_TRANSLUCENCY]) - nodestack_get_vec(&shi->translucency, SOCK_VALUE, in[MAT_IN_TRANSLUCENCY]); + nodestack_get_vec(&shi->translucency, SOCK_FLOAT, in[MAT_IN_TRANSLUCENCY]); } shi->nodes= 1; /* temp hack to prevent trashadow recursion */ @@ -204,7 +204,7 @@ static void node_shader_exec_material(void *data, bNode *node, bNodeStack **in, } -static void node_shader_init_material(bNode* node) +static void node_shader_init_material(bNodeTree *UNUSED(ntree), bNode* node, bNodeTemplate *UNUSED(ntemp)) { node->custom1= SH_NODE_MAT_DIFF|SH_NODE_MAT_SPEC; } @@ -308,8 +308,8 @@ void register_node_type_sh_material(ListBase *lb) { static bNodeType ntype; - node_type_base(&ntype, SH_NODE_MATERIAL, "Material", NODE_CLASS_INPUT, NODE_OPTIONS|NODE_PREVIEW, - sh_node_material_in, sh_node_material_out); + node_type_base(&ntype, SH_NODE_MATERIAL, "Material", NODE_CLASS_INPUT, NODE_OPTIONS|NODE_PREVIEW); + node_type_socket_templates(&ntype, sh_node_material_in, sh_node_material_out); node_type_size(&ntype, 120, 80, 240); node_type_init(&ntype, node_shader_init_material); node_type_exec(&ntype, node_shader_exec_material); @@ -323,8 +323,8 @@ void register_node_type_sh_material_ext(ListBase *lb) { static bNodeType ntype; - node_type_base(&ntype, SH_NODE_MATERIAL_EXT, "Extended Material", NODE_CLASS_INPUT, NODE_OPTIONS|NODE_PREVIEW, - sh_node_material_ext_in, sh_node_material_ext_out); + node_type_base(&ntype, SH_NODE_MATERIAL_EXT, "Extended Material", NODE_CLASS_INPUT, NODE_OPTIONS|NODE_PREVIEW); + node_type_socket_templates(&ntype, sh_node_material_ext_in, sh_node_material_ext_out); node_type_size(&ntype, 120, 80, 240); node_type_init(&ntype, node_shader_init_material); node_type_exec(&ntype, node_shader_exec_material); diff --git a/source/blender/nodes/intern/SHD_nodes/SHD_math.c b/source/blender/nodes/shader/nodes/node_shader_math.c similarity index 92% rename from source/blender/nodes/intern/SHD_nodes/SHD_math.c rename to source/blender/nodes/shader/nodes/node_shader_math.c index dd0a564dc4b..0618598379f 100644 --- a/source/blender/nodes/intern/SHD_nodes/SHD_math.c +++ b/source/blender/nodes/shader/nodes/node_shader_math.c @@ -1,5 +1,5 @@ /* - * $Id$ + * $Id: SHD_math.c 36593 2011-05-10 11:19:26Z lukastoenne $ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -27,23 +27,23 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/nodes/intern/SHD_nodes/SHD_math.c +/** \file blender/nodes/shader/nodes/node_shader_math.c * \ingroup shdnodes */ -#include "../SHD_util.h" +#include "node_shader_util.h" /* **************** SCALAR MATH ******************** */ -static bNodeSocketType sh_node_math_in[]= { - { SOCK_VALUE, 1, "Value", 0.5f, 0.5f, 0.5f, 1.0f, -100.0f, 100.0f}, - { SOCK_VALUE, 1, "Value", 0.5f, 0.5f, 0.5f, 1.0f, -100.0f, 100.0f}, +static bNodeSocketTemplate sh_node_math_in[]= { + { SOCK_FLOAT, 1, "Value", 0.5f, 0.5f, 0.5f, 1.0f, -100.0f, 100.0f, PROP_NONE}, + { SOCK_FLOAT, 1, "Value", 0.5f, 0.5f, 0.5f, 1.0f, -100.0f, 100.0f, PROP_NONE}, { -1, 0, "" } }; -static bNodeSocketType sh_node_math_out[]= { - { SOCK_VALUE, 0, "Value", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate sh_node_math_out[]= { + { SOCK_FLOAT, 0, "Value"}, { -1, 0, "" } }; @@ -242,8 +242,8 @@ void register_node_type_sh_math(ListBase *lb) { static bNodeType ntype; - node_type_base(&ntype, SH_NODE_MATH, "Math", NODE_CLASS_CONVERTOR, NODE_OPTIONS, - sh_node_math_in, sh_node_math_out); + node_type_base(&ntype, SH_NODE_MATH, "Math", NODE_CLASS_CONVERTOR, NODE_OPTIONS); + node_type_socket_templates(&ntype, sh_node_math_in, sh_node_math_out); node_type_size(&ntype, 120, 110, 160); node_type_label(&ntype, node_math_label); node_type_storage(&ntype, "node_math", NULL, NULL); diff --git a/source/blender/nodes/intern/SHD_nodes/SHD_mixRgb.c b/source/blender/nodes/shader/nodes/node_shader_mixRgb.c similarity index 79% rename from source/blender/nodes/intern/SHD_nodes/SHD_mixRgb.c rename to source/blender/nodes/shader/nodes/node_shader_mixRgb.c index 8b3033a98ca..a89faa66fc0 100644 --- a/source/blender/nodes/intern/SHD_nodes/SHD_mixRgb.c +++ b/source/blender/nodes/shader/nodes/node_shader_mixRgb.c @@ -1,5 +1,5 @@ /* - * $Id$ + * $Id: SHD_mixRgb.c 36593 2011-05-10 11:19:26Z lukastoenne $ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -27,22 +27,22 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/nodes/intern/SHD_nodes/SHD_mixRgb.c +/** \file blender/nodes/shader/nodes/node_shader_mixRgb.c * \ingroup shdnodes */ -#include "../SHD_util.h" +#include "node_shader_util.h" /* **************** MIX RGB ******************** */ -static bNodeSocketType sh_node_mix_rgb_in[]= { - { SOCK_VALUE, 1, "Fac", 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, - { SOCK_RGBA, 1, "Color1", 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 1.0f}, - { SOCK_RGBA, 1, "Color2", 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate sh_node_mix_rgb_in[]= { + { SOCK_FLOAT, 1, "Fac", 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR}, + { SOCK_RGBA, 1, "Color1", 0.5f, 0.5f, 0.5f, 1.0f}, + { SOCK_RGBA, 1, "Color2", 0.5f, 0.5f, 0.5f, 1.0f}, { -1, 0, "" } }; -static bNodeSocketType sh_node_mix_rgb_out[]= { - { SOCK_RGBA, 0, "Color", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate sh_node_mix_rgb_out[]= { + { SOCK_RGBA, 0, "Color"}, { -1, 0, "" } }; @@ -54,7 +54,7 @@ static void node_shader_exec_mix_rgb(void *UNUSED(data), bNode *node, bNodeStack float fac; float vec[3]; - nodestack_get_vec(&fac, SOCK_VALUE, in[0]); + nodestack_get_vec(&fac, SOCK_FLOAT, in[0]); CLAMP(fac, 0.0f, 1.0f); nodestack_get_vec(col, SOCK_VECTOR, in[1]); @@ -79,8 +79,8 @@ void register_node_type_sh_mix_rgb(ListBase *lb) { static bNodeType ntype; - node_type_base(&ntype, SH_NODE_MIX_RGB, "Mix", NODE_CLASS_OP_COLOR, NODE_OPTIONS, - sh_node_mix_rgb_in, sh_node_mix_rgb_out); + node_type_base(&ntype, SH_NODE_MIX_RGB, "Mix", NODE_CLASS_OP_COLOR, NODE_OPTIONS); + node_type_socket_templates(&ntype, sh_node_mix_rgb_in, sh_node_mix_rgb_out); node_type_size(&ntype, 100, 60, 150); node_type_label(&ntype, node_blend_label); node_type_exec(&ntype, node_shader_exec_mix_rgb); diff --git a/source/blender/nodes/intern/SHD_nodes/SHD_normal.c b/source/blender/nodes/shader/nodes/node_shader_normal.c similarity index 67% rename from source/blender/nodes/intern/SHD_nodes/SHD_normal.c rename to source/blender/nodes/shader/nodes/node_shader_normal.c index a4e39935cea..099a9bed10d 100644 --- a/source/blender/nodes/intern/SHD_nodes/SHD_normal.c +++ b/source/blender/nodes/shader/nodes/node_shader_normal.c @@ -1,5 +1,5 @@ /* - * $Id$ + * $Id: SHD_normal.c 36593 2011-05-10 11:19:26Z lukastoenne $ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -27,25 +27,36 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/nodes/intern/SHD_nodes/SHD_normal.c +/** \file blender/nodes/shader/nodes/node_shader_normal.c * \ingroup shdnodes */ -#include "../SHD_util.h" +#include "node_shader_util.h" /* **************** NORMAL ******************** */ -static bNodeSocketType sh_node_normal_in[]= { - { SOCK_VECTOR, 1, "Normal", 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f}, +static bNodeSocketTemplate sh_node_normal_in[]= { + { SOCK_VECTOR, 1, "Normal", 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, PROP_NONE}, { -1, 0, "" } }; -static bNodeSocketType sh_node_normal_out[]= { - { SOCK_VECTOR, 0, "Normal", 0.0f, 0.0f, 1.0f, 1.0f, -1.0f, 1.0f}, - { SOCK_VALUE, 0, "Dot", 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate sh_node_normal_out[]= { + { SOCK_VECTOR, 0, "Normal"}, + { SOCK_FLOAT, 0, "Dot"}, { -1, 0, "" } }; +static void node_shader_init_normal(bNodeTree *UNUSED(ntree), bNode *node, bNodeTemplate *UNUSED(ntemp)) +{ + bNodeSocket *sock= node->outputs.first; + bNodeSocketValueVector *dval= (bNodeSocketValueVector*)sock->default_value; + + /* output value is used for normal vector */ + dval->value[0] = 0.0f; + dval->value[1] = 0.0f; + dval->value[2] = 1.0f; +} + /* generates normal, does dot product */ static void node_shader_exec_normal(void *UNUSED(data), bNode *node, bNodeStack **in, bNodeStack **out) { @@ -57,7 +68,7 @@ static void node_shader_exec_normal(void *UNUSED(data), bNode *node, bNodeStack nodestack_get_vec(vec, SOCK_VECTOR, in[0]); - VECCOPY(out[0]->vec, sock->ns.vec); + VECCOPY(out[0]->vec, ((bNodeSocketValueVector*)sock->default_value)->value); /* render normals point inside... the widget points outside */ out[1]->vec[0]= -INPR(out[0]->vec, vec); } @@ -65,7 +76,7 @@ static void node_shader_exec_normal(void *UNUSED(data), bNode *node, bNodeStack static int gpu_shader_normal(GPUMaterial *mat, bNode *node, GPUNodeStack *in, GPUNodeStack *out) { bNodeSocket *sock= node->outputs.first; - GPUNodeLink *vec = GPU_uniform(sock->ns.vec); + GPUNodeLink *vec = GPU_uniform(((bNodeSocketValueVector*)sock->default_value)->value); return GPU_stack_link(mat, "normal", in, out, vec); } @@ -74,8 +85,9 @@ void register_node_type_sh_normal(ListBase *lb) { static bNodeType ntype; - node_type_base(&ntype, SH_NODE_NORMAL, "Normal", NODE_CLASS_OP_VECTOR, NODE_OPTIONS, - sh_node_normal_in, sh_node_normal_out); + node_type_base(&ntype, SH_NODE_NORMAL, "Normal", NODE_CLASS_OP_VECTOR, NODE_OPTIONS); + node_type_socket_templates(&ntype, sh_node_normal_in, sh_node_normal_out); + node_type_init(&ntype, node_shader_init_normal); node_type_exec(&ntype, node_shader_exec_normal); node_type_gpu(&ntype, gpu_shader_normal); diff --git a/source/blender/nodes/intern/SHD_nodes/SHD_output.c b/source/blender/nodes/shader/nodes/node_shader_output.c similarity index 83% rename from source/blender/nodes/intern/SHD_nodes/SHD_output.c rename to source/blender/nodes/shader/nodes/node_shader_output.c index e42caabff34..638af7d4eb3 100644 --- a/source/blender/nodes/intern/SHD_nodes/SHD_output.c +++ b/source/blender/nodes/shader/nodes/node_shader_output.c @@ -1,5 +1,5 @@ /* - * $Id$ + * $Id: SHD_output.c 36593 2011-05-10 11:19:26Z lukastoenne $ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -27,17 +27,17 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/nodes/intern/SHD_nodes/SHD_output.c +/** \file blender/nodes/shader/nodes/node_shader_output.c * \ingroup shdnodes */ -#include "../SHD_util.h" +#include "node_shader_util.h" /* **************** OUTPUT ******************** */ -static bNodeSocketType sh_node_output_in[]= { - { SOCK_RGBA, 1, "Color", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, - { SOCK_VALUE, 1, "Alpha", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate sh_node_output_in[]= { + { SOCK_RGBA, 1, "Color", 0.0f, 0.0f, 0.0f, 1.0f}, + { SOCK_FLOAT, 1, "Alpha", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR}, { -1, 0, "" } }; @@ -49,7 +49,7 @@ static void node_shader_exec_output(void *data, bNode *node, bNodeStack **in, bN /* stack order input sockets: col, alpha, normal */ nodestack_get_vec(col, SOCK_VECTOR, in[0]); - nodestack_get_vec(col+3, SOCK_VALUE, in[1]); + nodestack_get_vec(col+3, SOCK_FLOAT, in[1]); if(shi->do_preview) { nodeAddToPreview(node, col, shi->xs, shi->ys, shi->do_manage); @@ -84,8 +84,8 @@ void register_node_type_sh_output(ListBase *lb) { static bNodeType ntype; - node_type_base(&ntype, SH_NODE_OUTPUT, "Output", NODE_CLASS_OUTPUT, NODE_PREVIEW, - sh_node_output_in, NULL); + node_type_base(&ntype, SH_NODE_OUTPUT, "Output", NODE_CLASS_OUTPUT, NODE_PREVIEW); + node_type_socket_templates(&ntype, sh_node_output_in, NULL); node_type_size(&ntype, 80, 60, 200); node_type_exec(&ntype, node_shader_exec_output); node_type_gpu(&ntype, gpu_shader_output); diff --git a/source/blender/nodes/intern/SHD_nodes/SHD_rgb.c b/source/blender/nodes/shader/nodes/node_shader_rgb.c similarity index 65% rename from source/blender/nodes/intern/SHD_nodes/SHD_rgb.c rename to source/blender/nodes/shader/nodes/node_shader_rgb.c index 3d7f401b055..c9bb78b45dd 100644 --- a/source/blender/nodes/intern/SHD_nodes/SHD_rgb.c +++ b/source/blender/nodes/shader/nodes/node_shader_rgb.c @@ -1,5 +1,5 @@ /* - * $Id$ + * $Id: SHD_rgb.c 36481 2011-05-04 11:42:25Z lukastoenne $ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -27,30 +27,43 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/nodes/intern/SHD_nodes/SHD_rgb.c +/** \file blender/nodes/shader/nodes/node_shader_rgb.c * \ingroup shdnodes */ -#include "../SHD_util.h" +#include "node_shader_util.h" /* **************** RGB ******************** */ -static bNodeSocketType sh_node_rgb_out[]= { - { SOCK_RGBA, 0, "Color", 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate sh_node_rgb_out[]= { + { SOCK_RGBA, 0, "Color"}, { -1, 0, "" } }; +static void node_shader_init_rgb(bNodeTree *UNUSED(ntree), bNode *node, bNodeTemplate *UNUSED(ntemp)) +{ + bNodeSocket *sock= node->outputs.first; + bNodeSocketValueRGBA *dval= (bNodeSocketValueRGBA*)sock->default_value; + /* uses the default value of the output socket, must be initialized here */ + dval->value[0] = 0.5f; + dval->value[1] = 0.5f; + dval->value[2] = 0.5f; + dval->value[3] = 1.0f; +} + static void node_shader_exec_rgb(void *UNUSED(data), bNode *node, bNodeStack **UNUSED(in), bNodeStack **out) { bNodeSocket *sock= node->outputs.first; + float *col= ((bNodeSocketValueRGBA*)sock->default_value)->value; - VECCOPY(out[0]->vec, sock->ns.vec); + VECCOPY(out[0]->vec, col); } static int gpu_shader_rgb(GPUMaterial *mat, bNode *node, GPUNodeStack *in, GPUNodeStack *out) { bNodeSocket *sock= node->outputs.first; - GPUNodeLink *vec = GPU_uniform(sock->ns.vec); + float *col= ((bNodeSocketValueRGBA*)sock->default_value)->value; + GPUNodeLink *vec = GPU_uniform(col); return GPU_stack_link(mat, "set_rgba", in, out, vec); } @@ -59,8 +72,9 @@ void register_node_type_sh_rgb(ListBase *lb) { static bNodeType ntype; - node_type_base(&ntype, SH_NODE_RGB, "RGB", NODE_CLASS_INPUT, NODE_OPTIONS, - NULL, sh_node_rgb_out); + node_type_base(&ntype, SH_NODE_RGB, "RGB", NODE_CLASS_INPUT, NODE_OPTIONS); + node_type_socket_templates(&ntype, NULL, sh_node_rgb_out); + node_type_init(&ntype, node_shader_init_rgb); node_type_size(&ntype, 140, 80, 140); node_type_exec(&ntype, node_shader_exec_rgb); node_type_gpu(&ntype, gpu_shader_rgb); diff --git a/source/blender/nodes/intern/SHD_nodes/SHD_sepcombRGB.c b/source/blender/nodes/shader/nodes/node_shader_sepcombRGB.c similarity index 74% rename from source/blender/nodes/intern/SHD_nodes/SHD_sepcombRGB.c rename to source/blender/nodes/shader/nodes/node_shader_sepcombRGB.c index e4fa0b02521..9528aca2574 100644 --- a/source/blender/nodes/intern/SHD_nodes/SHD_sepcombRGB.c +++ b/source/blender/nodes/shader/nodes/node_shader_sepcombRGB.c @@ -27,22 +27,22 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/nodes/intern/SHD_nodes/SHD_sepcombRGB.c +/** \file blender/nodes/shader/nodes/node_shader_sepcombRGB.c * \ingroup shdnodes */ -#include "../SHD_util.h" +#include "node_shader_util.h" /* **************** SEPARATE RGBA ******************** */ -static bNodeSocketType sh_node_seprgb_in[]= { - { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate sh_node_seprgb_in[]= { + { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f}, { -1, 0, "" } }; -static bNodeSocketType sh_node_seprgb_out[]= { - { SOCK_VALUE, 0, "R", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, - { SOCK_VALUE, 0, "G", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, - { SOCK_VALUE, 0, "B", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate sh_node_seprgb_out[]= { + { SOCK_FLOAT, 0, "R"}, + { SOCK_FLOAT, 0, "G"}, + { SOCK_FLOAT, 0, "B"}, { -1, 0, "" } }; @@ -62,8 +62,8 @@ void register_node_type_sh_seprgb(ListBase *lb) { static bNodeType ntype; - node_type_base(&ntype, SH_NODE_SEPRGB, "Separate RGB", NODE_CLASS_CONVERTOR, 0, - sh_node_seprgb_in, sh_node_seprgb_out); + node_type_base(&ntype, SH_NODE_SEPRGB, "Separate RGB", NODE_CLASS_CONVERTOR, 0); + node_type_socket_templates(&ntype, sh_node_seprgb_in, sh_node_seprgb_out); node_type_size(&ntype, 80, 40, 140); node_type_exec(&ntype, node_shader_exec_seprgb); node_type_gpu(&ntype, gpu_shader_seprgb); @@ -74,14 +74,14 @@ void register_node_type_sh_seprgb(ListBase *lb) /* **************** COMBINE RGB ******************** */ -static bNodeSocketType sh_node_combrgb_in[]= { - { SOCK_VALUE, 1, "R", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, - { SOCK_VALUE, 1, "G", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, - { SOCK_VALUE, 1, "B", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate sh_node_combrgb_in[]= { + { SOCK_FLOAT, 1, "R", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, PROP_UNSIGNED}, + { SOCK_FLOAT, 1, "G", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, PROP_UNSIGNED}, + { SOCK_FLOAT, 1, "B", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, PROP_UNSIGNED}, { -1, 0, "" } }; -static bNodeSocketType sh_node_combrgb_out[]= { - { SOCK_RGBA, 0, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate sh_node_combrgb_out[]= { + { SOCK_RGBA, 0, "Image"}, { -1, 0, "" } }; @@ -101,8 +101,8 @@ void register_node_type_sh_combrgb(ListBase *lb) { static bNodeType ntype; - node_type_base(&ntype, SH_NODE_COMBRGB, "Combine RGB", NODE_CLASS_CONVERTOR, NODE_OPTIONS, - sh_node_combrgb_in, sh_node_combrgb_out); + node_type_base(&ntype, SH_NODE_COMBRGB, "Combine RGB", NODE_CLASS_CONVERTOR, NODE_OPTIONS); + node_type_socket_templates(&ntype, sh_node_combrgb_in, sh_node_combrgb_out); node_type_size(&ntype, 80, 40, 140); node_type_exec(&ntype, node_shader_exec_combrgb); node_type_gpu(&ntype, gpu_shader_combrgb); diff --git a/source/blender/nodes/intern/SHD_nodes/SHD_squeeze.c b/source/blender/nodes/shader/nodes/node_shader_squeeze.c similarity index 70% rename from source/blender/nodes/intern/SHD_nodes/SHD_squeeze.c rename to source/blender/nodes/shader/nodes/node_shader_squeeze.c index 80693ff08f0..305639dff21 100644 --- a/source/blender/nodes/intern/SHD_nodes/SHD_squeeze.c +++ b/source/blender/nodes/shader/nodes/node_shader_squeeze.c @@ -1,5 +1,5 @@ /* - * $Id$ + * $Id: SHD_squeeze.c 36593 2011-05-10 11:19:26Z lukastoenne $ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -27,23 +27,23 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/nodes/intern/SHD_nodes/SHD_squeeze.c +/** \file blender/nodes/shader/nodes/node_shader_squeeze.c * \ingroup shdnodes */ -#include "../SHD_util.h" +#include "node_shader_util.h" /* **************** VALUE SQUEEZE ******************** */ -static bNodeSocketType sh_node_squeeze_in[]= { - { SOCK_VALUE, 1, "Value", 0.0f, 0.0f, 0.0f, 0.0f, -100.0f, 100.0f}, - { SOCK_VALUE, 1, "Width", 1.0f, 0.0f, 0.0f, 0.0f, -100.0f, 100.0f}, - { SOCK_VALUE, 1, "Center", 0.0f, 0.0f, 0.0f, 0.0f, -100.0f, 100.0f}, +static bNodeSocketTemplate sh_node_squeeze_in[]= { + { SOCK_FLOAT, 1, "Value", 0.0f, 0.0f, 0.0f, 0.0f, -100.0f, 100.0f, PROP_NONE}, + { SOCK_FLOAT, 1, "Width", 1.0f, 0.0f, 0.0f, 0.0f, -100.0f, 100.0f, PROP_NONE}, + { SOCK_FLOAT, 1, "Center", 0.0f, 0.0f, 0.0f, 0.0f, -100.0f, 100.0f, PROP_NONE}, { -1, 0, "" } }; -static bNodeSocketType sh_node_squeeze_out[]= { - { SOCK_VALUE, 0, "Value", 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate sh_node_squeeze_out[]= { + { SOCK_FLOAT, 0, "Value"}, { -1, 0, "" } }; @@ -52,9 +52,9 @@ bNodeStack **out) { float vec[3]; - nodestack_get_vec(vec, SOCK_VALUE, in[0]); - nodestack_get_vec(vec+1, SOCK_VALUE, in[1]); - nodestack_get_vec(vec+2, SOCK_VALUE, in[2]); + nodestack_get_vec(vec, SOCK_FLOAT, in[0]); + nodestack_get_vec(vec+1, SOCK_FLOAT, in[1]); + nodestack_get_vec(vec+2, SOCK_FLOAT, in[2]); out[0]->vec[0] = 1.0f / (1.0f + pow(2.71828183,-((vec[0]-vec[2])*vec[1]))) ; } @@ -68,8 +68,8 @@ void register_node_type_sh_squeeze(ListBase *lb) { static bNodeType ntype; - node_type_base(&ntype, SH_NODE_SQUEEZE, "Squeeze Value", NODE_CLASS_CONVERTOR, NODE_OPTIONS, - sh_node_squeeze_in, sh_node_squeeze_out); + node_type_base(&ntype, SH_NODE_SQUEEZE, "Squeeze Value", NODE_CLASS_CONVERTOR, NODE_OPTIONS); + node_type_socket_templates(&ntype, sh_node_squeeze_in, sh_node_squeeze_out); node_type_size(&ntype, 120, 110, 160); node_type_storage(&ntype, "node_squeeze", NULL, NULL); node_type_exec(&ntype, node_shader_exec_squeeze); diff --git a/source/blender/nodes/intern/SHD_nodes/SHD_texture.c b/source/blender/nodes/shader/nodes/node_shader_texture.c similarity index 88% rename from source/blender/nodes/intern/SHD_nodes/SHD_texture.c rename to source/blender/nodes/shader/nodes/node_shader_texture.c index 249e4eeca5d..a4957d8f683 100644 --- a/source/blender/nodes/intern/SHD_nodes/SHD_texture.c +++ b/source/blender/nodes/shader/nodes/node_shader_texture.c @@ -1,5 +1,5 @@ /* - * $Id$ + * $Id: SHD_texture.c 36593 2011-05-10 11:19:26Z lukastoenne $ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -27,24 +27,24 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/nodes/intern/SHD_nodes/SHD_texture.c +/** \file blender/nodes/shader/nodes/node_shader_texture.c * \ingroup shdnodes */ #include "DNA_texture_types.h" -#include "../SHD_util.h" +#include "node_shader_util.h" /* **************** TEXTURE ******************** */ -static bNodeSocketType sh_node_texture_in[]= { - { SOCK_VECTOR, 1, "Vector", 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f}, /* no limit */ +static bNodeSocketTemplate sh_node_texture_in[]= { + { SOCK_VECTOR, 1, "Vector", 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, PROP_NONE}, /* no limit */ { -1, 0, "" } }; -static bNodeSocketType sh_node_texture_out[]= { - { SOCK_VALUE, 0, "Value", 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, - { SOCK_RGBA , 0, "Color", 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f}, - { SOCK_VECTOR, 0, "Normal", 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f}, +static bNodeSocketTemplate sh_node_texture_out[]= { + { SOCK_FLOAT, 0, "Value"}, + { SOCK_RGBA , 0, "Color"}, + { SOCK_VECTOR, 0, "Normal"}, { -1, 0, "" } }; @@ -137,8 +137,8 @@ void register_node_type_sh_texture(ListBase *lb) { static bNodeType ntype; - node_type_base(&ntype, SH_NODE_TEXTURE, "Texture", NODE_CLASS_INPUT, NODE_OPTIONS|NODE_PREVIEW, - sh_node_texture_in, sh_node_texture_out); + node_type_base(&ntype, SH_NODE_TEXTURE, "Texture", NODE_CLASS_INPUT, NODE_OPTIONS|NODE_PREVIEW); + node_type_socket_templates(&ntype, sh_node_texture_in, sh_node_texture_out); node_type_size(&ntype, 120, 80, 240); node_type_exec(&ntype, node_shader_exec_texture); node_type_gpu(&ntype, gpu_shader_texture); diff --git a/source/blender/nodes/intern/SHD_nodes/SHD_valToRgb.c b/source/blender/nodes/shader/nodes/node_shader_valToRgb.c similarity index 76% rename from source/blender/nodes/intern/SHD_nodes/SHD_valToRgb.c rename to source/blender/nodes/shader/nodes/node_shader_valToRgb.c index 86f832c12ee..9353143095a 100644 --- a/source/blender/nodes/intern/SHD_nodes/SHD_valToRgb.c +++ b/source/blender/nodes/shader/nodes/node_shader_valToRgb.c @@ -1,5 +1,5 @@ /* - * $Id$ + * $Id: SHD_valToRgb.c 36593 2011-05-10 11:19:26Z lukastoenne $ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -27,21 +27,21 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/nodes/intern/SHD_nodes/SHD_valToRgb.c +/** \file blender/nodes/shader/nodes/node_shader_valToRgb.c * \ingroup shdnodes */ -#include "../SHD_util.h" +#include "node_shader_util.h" /* **************** VALTORGB ******************** */ -static bNodeSocketType sh_node_valtorgb_in[]= { - { SOCK_VALUE, 1, "Fac", 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate sh_node_valtorgb_in[]= { + { SOCK_FLOAT, 1, "Fac", 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR}, { -1, 0, "" } }; -static bNodeSocketType sh_node_valtorgb_out[]= { - { SOCK_RGBA, 0, "Color", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, - { SOCK_VALUE, 0, "Alpha", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate sh_node_valtorgb_out[]= { + { SOCK_RGBA, 0, "Color"}, + { SOCK_FLOAT, 0, "Alpha"}, { -1, 0, "" } }; @@ -52,14 +52,14 @@ static void node_shader_exec_valtorgb(void *UNUSED(data), bNode *node, bNodeStac if(node->storage) { float fac; - nodestack_get_vec(&fac, SOCK_VALUE, in[0]); + nodestack_get_vec(&fac, SOCK_FLOAT, in[0]); do_colorband(node->storage, fac, out[0]->vec); out[1]->vec[0]= out[0]->vec[3]; } } -static void node_shader_init_valtorgb(bNode *node) +static void node_shader_init_valtorgb(bNodeTree *UNUSED(ntree), bNode* node, bNodeTemplate *UNUSED(ntemp)) { node->storage= add_colorband(1); } @@ -77,8 +77,8 @@ void register_node_type_sh_valtorgb(ListBase *lb) { static bNodeType ntype; - node_type_base(&ntype, SH_NODE_VALTORGB, "ColorRamp", NODE_CLASS_CONVERTOR, NODE_OPTIONS, - sh_node_valtorgb_in, sh_node_valtorgb_out); + node_type_base(&ntype, SH_NODE_VALTORGB, "ColorRamp", NODE_CLASS_CONVERTOR, NODE_OPTIONS); + node_type_socket_templates(&ntype, sh_node_valtorgb_in, sh_node_valtorgb_out); node_type_size(&ntype, 240, 200, 300); node_type_init(&ntype, node_shader_init_valtorgb); node_type_storage(&ntype, "ColorBand", node_free_standard_storage, node_copy_standard_storage); @@ -90,12 +90,12 @@ void register_node_type_sh_valtorgb(ListBase *lb) /* **************** RGBTOBW ******************** */ -static bNodeSocketType sh_node_rgbtobw_in[]= { +static bNodeSocketTemplate sh_node_rgbtobw_in[]= { { SOCK_RGBA, 1, "Color", 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 1.0f}, { -1, 0, "" } }; -static bNodeSocketType sh_node_rgbtobw_out[]= { - { SOCK_VALUE, 0, "Val", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate sh_node_rgbtobw_out[]= { + { SOCK_FLOAT, 0, "Val", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, { -1, 0, "" } }; @@ -117,8 +117,8 @@ void register_node_type_sh_rgbtobw(ListBase *lb) { static bNodeType ntype; - node_type_base(&ntype, SH_NODE_RGBTOBW, "RGB to BW", NODE_CLASS_CONVERTOR, 0, - sh_node_rgbtobw_in, sh_node_rgbtobw_out); + node_type_base(&ntype, SH_NODE_RGBTOBW, "RGB to BW", NODE_CLASS_CONVERTOR, 0); + node_type_socket_templates(&ntype, sh_node_rgbtobw_in, sh_node_rgbtobw_out); node_type_size(&ntype, 80, 40, 120); node_type_exec(&ntype, node_shader_exec_rgbtobw); node_type_gpu(&ntype, gpu_shader_rgbtobw); diff --git a/source/blender/nodes/intern/SHD_nodes/SHD_value.c b/source/blender/nodes/shader/nodes/node_shader_value.c similarity index 66% rename from source/blender/nodes/intern/SHD_nodes/SHD_value.c rename to source/blender/nodes/shader/nodes/node_shader_value.c index 29a75bbf36d..21ff565306d 100644 --- a/source/blender/nodes/intern/SHD_nodes/SHD_value.c +++ b/source/blender/nodes/shader/nodes/node_shader_value.c @@ -1,5 +1,5 @@ /* - * $Id$ + * $Id: SHD_value.c 36536 2011-05-07 13:27:27Z lukastoenne $ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -27,30 +27,40 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/nodes/intern/SHD_nodes/SHD_value.c +/** \file blender/nodes/shader/nodes/node_shader_value.c * \ingroup shdnodes */ -#include "../SHD_util.h" +#include "node_shader_util.h" /* **************** VALUE ******************** */ -static bNodeSocketType sh_node_value_out[]= { - { SOCK_VALUE, 0, "Value", 0.5f, 0.0f, 0.0f, 0.0f, -10000.0f, 10000.0f}, +static bNodeSocketTemplate sh_node_value_out[]= { + { SOCK_FLOAT, 0, "Value"}, { -1, 0, "" } }; +static void node_shader_init_value(bNodeTree *UNUSED(ntree), bNode *node, bNodeTemplate *UNUSED(ntemp)) +{ + bNodeSocket *sock= node->outputs.first; + bNodeSocketValueFloat *dval= (bNodeSocketValueFloat*)sock->default_value; + /* uses the default value of the output socket, must be initialized here */ + dval->value = 0.5f; +} + static void node_shader_exec_value(void *UNUSED(data), bNode *node, bNodeStack **UNUSED(in), bNodeStack **out) { bNodeSocket *sock= node->outputs.first; + float val= ((bNodeSocketValueFloat*)sock->default_value)->value; - out[0]->vec[0]= sock->ns.vec[0]; + out[0]->vec[0]= val; } static int gpu_shader_value(GPUMaterial *mat, bNode *node, GPUNodeStack *in, GPUNodeStack *out) { bNodeSocket *sock= node->outputs.first; - GPUNodeLink *vec = GPU_uniform(sock->ns.vec); + float *val= &((bNodeSocketValueFloat*)sock->default_value)->value; + GPUNodeLink *vec = GPU_uniform(val); return GPU_stack_link(mat, "set_value", in, out, vec); } @@ -59,8 +69,9 @@ void register_node_type_sh_value(ListBase *lb) { static bNodeType ntype; - node_type_base(&ntype, SH_NODE_VALUE, "Value", NODE_CLASS_INPUT, NODE_OPTIONS, - NULL, sh_node_value_out); + node_type_base(&ntype, SH_NODE_VALUE, "Value", NODE_CLASS_INPUT, NODE_OPTIONS); + node_type_socket_templates(&ntype, NULL, sh_node_value_out); + node_type_init(&ntype, node_shader_init_value); node_type_size(&ntype, 80, 50, 120); node_type_exec(&ntype, node_shader_exec_value); node_type_gpu(&ntype, gpu_shader_value); diff --git a/source/blender/nodes/intern/SHD_nodes/SHD_vectMath.c b/source/blender/nodes/shader/nodes/node_shader_vectMath.c similarity index 87% rename from source/blender/nodes/intern/SHD_nodes/SHD_vectMath.c rename to source/blender/nodes/shader/nodes/node_shader_vectMath.c index 9979e488a71..c6a081431a2 100644 --- a/source/blender/nodes/intern/SHD_nodes/SHD_vectMath.c +++ b/source/blender/nodes/shader/nodes/node_shader_vectMath.c @@ -1,5 +1,5 @@ /* - * $Id$ + * $Id: SHD_vectMath.c 36593 2011-05-10 11:19:26Z lukastoenne $ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -27,25 +27,25 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/nodes/intern/SHD_nodes/SHD_vectMath.c +/** \file blender/nodes/shader/nodes/node_shader_vectMath.c * \ingroup shdnodes */ -#include "../SHD_util.h" +#include "node_shader_util.h" /* **************** VECTOR MATH ******************** */ -static bNodeSocketType sh_node_vect_math_in[]= { - { SOCK_VECTOR, 1, "Vector", 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 1.0f}, - { SOCK_VECTOR, 1, "Vector", 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate sh_node_vect_math_in[]= { + { SOCK_VECTOR, 1, "Vector", 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 1.0f, PROP_NONE}, + { SOCK_VECTOR, 1, "Vector", 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 1.0f, PROP_NONE}, { -1, 0, "" } }; -static bNodeSocketType sh_node_vect_math_out[]= { - { SOCK_VECTOR, 0, "Vector", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, - { SOCK_VALUE, 0, "Value", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate sh_node_vect_math_out[]= { + { SOCK_VECTOR, 0, "Vector"}, + { SOCK_FLOAT, 0, "Value"}, { -1, 0, "" } }; @@ -136,8 +136,8 @@ void register_node_type_sh_vect_math(ListBase *lb) { static bNodeType ntype; - node_type_base(&ntype, SH_NODE_VECT_MATH, "Vector Math", NODE_CLASS_CONVERTOR, NODE_OPTIONS, - sh_node_vect_math_in, sh_node_vect_math_out); + node_type_base(&ntype, SH_NODE_VECT_MATH, "Vector Math", NODE_CLASS_CONVERTOR, NODE_OPTIONS); + node_type_socket_templates(&ntype, sh_node_vect_math_in, sh_node_vect_math_out); node_type_size(&ntype, 80, 75, 140); node_type_label(&ntype, node_vect_math_label); node_type_storage(&ntype, "node_vect_math", NULL, NULL); diff --git a/source/blender/nodes/texture/node_texture_tree.c b/source/blender/nodes/texture/node_texture_tree.c new file mode 100644 index 00000000000..75a57c64f2f --- /dev/null +++ b/source/blender/nodes/texture/node_texture_tree.c @@ -0,0 +1,237 @@ +/** + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2007 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/nodes/texture/node_texture_tree.c + * \ingroup nodes + */ + + +#include + +#include "DNA_texture_types.h" +#include "DNA_node_types.h" + +#include "BLI_listbase.h" +#include "BLI_threads.h" +#include "BLI_utildefines.h" + +#include "BKE_global.h" +#include "BKE_main.h" +#include "BKE_node.h" + +#include "node_exec.h" +#include "node_util.h" +#include "NOD_texture.h" +#include "node_texture_util.h" + +#include "RE_pipeline.h" +#include "RE_shader_ext.h" + + +static void foreach_nodetree(Main *main, void *calldata, bNodeTreeCallback func) +{ + Tex *tx; + for(tx= main->tex.first; tx; tx= tx->id.next) { + if(tx->nodetree) { + func(calldata, &tx->id, tx->nodetree); + } + } +} + +static void local_sync(bNodeTree *localtree, bNodeTree *ntree) +{ + bNode *lnode; + + /* copy over contents of previews */ + for(lnode= localtree->nodes.first; lnode; lnode= lnode->next) { + if(ntreeNodeExists(ntree, lnode->new_node)) { + bNode *node= lnode->new_node; + + if(node->preview && node->preview->rect) { + if(lnode->preview && lnode->preview->rect) { + int xsize= node->preview->xsize; + int ysize= node->preview->ysize; + memcpy(node->preview->rect, lnode->preview->rect, 4*xsize + xsize*ysize*sizeof(char)*4); + } + } + } + } +} + +bNodeTreeType ntreeType_Texture = { + /* type */ NTREE_TEXTURE, + /* id_name */ "NTTexture Nodetree", + + /* node_types */ { NULL, NULL }, + + /* free_cache */ NULL, + /* free_node_cache */ NULL, + /* foreach_nodetree */ foreach_nodetree, + /* localize */ NULL, + /* local_sync */ local_sync, + /* local_merge */ NULL, + /* update */ NULL, + /* update_node */ NULL +}; + +int ntreeTexTagAnimated(bNodeTree *ntree) +{ + bNode *node; + + if(ntree==NULL) return 0; + + for(node= ntree->nodes.first; node; node= node->next) { + if(node->type==TEX_NODE_CURVE_TIME) { + NodeTagChanged(ntree, node); + return 1; + } + else if(node->type==NODE_GROUP) { + if( ntreeTexTagAnimated((bNodeTree *)node->id) ) { + return 1; + } + } + } + + return 0; +} + +bNodeTreeExec *ntreeTexBeginExecTree(bNodeTree *ntree) +{ + bNodeTreeExec *exec; + bNode *node; + + /* XXX hack: prevent exec data from being generated twice. + * this should be handled by the renderer! + */ + if (ntree->execdata) + return ntree->execdata; + + /* common base initialization */ + exec = ntree_exec_begin(ntree); + + /* allocate the thread stack listbase array */ + exec->threadstack= MEM_callocN(BLENDER_MAX_THREADS*sizeof(ListBase), "thread stack array"); + + for(node= exec->nodetree->nodes.first; node; node= node->next) + node->need_exec= 1; + + /* XXX this should not be necessary, but is still used for cmp/sha/tex nodes, + * which only store the ntree pointer. Should be fixed at some point! + */ + ntree->execdata = exec; + + return exec; +} + +/* free texture delegates */ +static void tex_free_delegates(bNodeTreeExec *exec) +{ + bNodeThreadStack *nts; + bNodeStack *ns; + int th, a; + + for(th=0; ththreadstack[th].first; nts; nts=nts->next) + for(ns= nts->stack, a=0; astacksize; a++, ns++) + if(ns->data && !ns->is_copy) + MEM_freeN(ns->data); +} + +void ntreeTexEndExecTree(bNodeTreeExec *exec) +{ + if(exec) { + bNodeTree *ntree= exec->nodetree; + bNodeThreadStack *nts; + int a; + + if(exec->threadstack) { + tex_free_delegates(exec); + + for(a=0; athreadstack[a].first; nts; nts=nts->next) + if (nts->stack) MEM_freeN(nts->stack); + BLI_freelistN(&exec->threadstack[a]); + } + + MEM_freeN(exec->threadstack); + exec->threadstack= NULL; + } + + ntree_exec_end(exec); + + /* XXX clear nodetree backpointer to exec data, same problem as noted in ntreeBeginExecTree */ + ntree->execdata = NULL; + } +} + +int ntreeTexExecTree( + bNodeTree *nodes, + TexResult *texres, + float *co, + float *dxt, float *dyt, + int osatex, + short thread, + Tex *UNUSED(tex), + short which_output, + int cfra, + int preview, + ShadeInput *shi, + MTex *mtex +){ + TexCallData data; + float *nor= texres->nor; + int retval = TEX_INT; + bNodeThreadStack *nts = NULL; + bNodeTreeExec *exec= nodes->execdata; + + data.co = co; + data.dxt = dxt; + data.dyt = dyt; + data.osatex = osatex; + data.target = texres; + data.do_preview = preview; + data.thread = thread; + data.which_output = which_output; + data.cfra= cfra; + data.mtex= mtex; + data.shi= shi; + + if (!exec) + exec = ntreeTexBeginExecTree(nodes); + + nts= ntreeGetThreadStack(exec, thread); + ntreeExecThreadNodes(exec, nts, &data, thread); + ntreeReleaseThreadStack(nts); + + if(texres->nor) retval |= TEX_NOR; + retval |= TEX_RGB; + /* confusing stuff; the texture output node sets this to NULL to indicate no normal socket was set + however, the texture code checks this for other reasons (namely, a normal is required for material) */ + texres->nor= nor; + + return retval; +} diff --git a/source/blender/nodes/intern/TEX_util.c b/source/blender/nodes/texture/node_texture_util.c similarity index 78% rename from source/blender/nodes/intern/TEX_util.c rename to source/blender/nodes/texture/node_texture_util.c index b5e27ca2ccb..5aedd8681ab 100644 --- a/source/blender/nodes/intern/TEX_util.c +++ b/source/blender/nodes/texture/node_texture_util.c @@ -26,7 +26,7 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/nodes/intern/TEX_util.c +/** \file blender/nodes/texture/node_texture_util.c * \ingroup nodes */ @@ -48,11 +48,11 @@ */ #include -#include "TEX_util.h" +#include "node_texture_util.h" #define PREV_RES 128 /* default preview resolution */ -void tex_call_delegate(TexDelegate *dg, float *out, TexParams *params, short thread) +static void tex_call_delegate(TexDelegate *dg, float *out, TexParams *params, short thread) { if(dg->node->need_exec) { dg->fn(out, params, dg->node, dg->in, thread); @@ -68,7 +68,7 @@ static void tex_input(float *out, int sz, bNodeStack *in, TexParams *params, sho if(dg) { tex_call_delegate(dg, in->vec, params, thread); - if(in->hasoutput && in->sockettype == SOCK_VALUE) + if(in->hasoutput && in->sockettype == SOCK_FLOAT) in->vec[1] = in->vec[2] = in->vec[0]; } memcpy(out, in->vec, sz * sizeof(float)); @@ -83,7 +83,7 @@ void tex_input_rgba(float *out, bNodeStack *in, TexParams *params, short thread) { tex_input(out, 4, in, params, thread); - if(in->hasoutput && in->sockettype == SOCK_VALUE) + if(in->hasoutput && in->sockettype == SOCK_FLOAT) { out[1] = out[2] = out[0]; out[3] = 1; @@ -170,45 +170,3 @@ void ntreeTexCheckCyclics(struct bNodeTree *ntree) } } - -int ntreeTexExecTree( - bNodeTree *nodes, - TexResult *texres, - float *co, - float *dxt, float *dyt, - int osatex, - short thread, - Tex *UNUSED(tex), - short which_output, - int cfra, - int preview, - ShadeInput *shi, - MTex *mtex -){ - TexCallData data; - float *nor= texres->nor; - int retval = TEX_INT; - - data.co = co; - data.dxt = dxt; - data.dyt = dyt; - data.osatex = osatex; - data.target = texres; - data.do_preview = preview; - data.thread = thread; - data.which_output = which_output; - data.cfra= cfra; - data.mtex= mtex; - data.shi= shi; - - ntreeExecTree(nodes, &data, thread); - - if(texres->nor) retval |= TEX_NOR; - retval |= TEX_RGB; - /* confusing stuff; the texture output node sets this to NULL to indicate no normal socket was set - however, the texture code checks this for other reasons (namely, a normal is required for material) */ - texres->nor= nor; - - return retval; -} - diff --git a/source/blender/nodes/intern/TEX_util.h b/source/blender/nodes/texture/node_texture_util.h similarity index 93% rename from source/blender/nodes/intern/TEX_util.h rename to source/blender/nodes/texture/node_texture_util.h index 0875bcd52bf..867b4142052 100644 --- a/source/blender/nodes/intern/TEX_util.h +++ b/source/blender/nodes/texture/node_texture_util.h @@ -26,13 +26,13 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/nodes/intern/TEX_util.h +/** \file blender/nodes/texture/node_texture_util.h * \ingroup nodes */ -#ifndef TEX_NODE_UTIL_H_ -#define TEX_NODE_UTIL_H_ +#ifndef NODE_TEXTURE_UTIL_H_ +#define NODE_TEXTURE_UTIL_H_ #include #include @@ -60,7 +60,6 @@ #include "BKE_library.h" -#include "../SHD_node.h" #include "node_util.h" #include "BLI_math.h" @@ -112,8 +111,6 @@ typedef struct TexDelegate { int type; } TexDelegate; -void tex_call_delegate(TexDelegate*, float *out, TexParams *params, short thread); - void tex_input_rgba(float *out, bNodeStack *in, TexParams *params, short thread); void tex_input_vec(float *out, bNodeStack *in, TexParams *params, short thread); float tex_input_value(bNodeStack *in, TexParams *params, short thread); diff --git a/source/blender/nodes/intern/TEX_nodes/TEX_at.c b/source/blender/nodes/texture/nodes/node_texture_at.c similarity index 82% rename from source/blender/nodes/intern/TEX_nodes/TEX_at.c rename to source/blender/nodes/texture/nodes/node_texture_at.c index d5980b786b0..f3275f2bcdf 100644 --- a/source/blender/nodes/intern/TEX_nodes/TEX_at.c +++ b/source/blender/nodes/texture/nodes/node_texture_at.c @@ -26,21 +26,21 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/nodes/intern/TEX_nodes/TEX_at.c +/** \file blender/nodes/texture/nodes/node_texture_at.c * \ingroup texnodes */ -#include "../TEX_util.h" -#include "TEX_node.h" +#include "node_texture_util.h" +#include "NOD_texture.h" -static bNodeSocketType inputs[]= { - { SOCK_RGBA, 1, "Texture", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f }, - { SOCK_VECTOR, 1, "Coordinates", 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, 1.0f }, +static bNodeSocketTemplate inputs[]= { + { SOCK_RGBA, 1, "Texture", 0.0f, 0.0f, 0.0f, 1.0f }, + { SOCK_VECTOR, 1, "Coordinates", 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, 1.0f, PROP_NONE }, { -1, 0, "" } }; -static bNodeSocketType outputs[]= { - { SOCK_RGBA, 0, "Texture", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f }, +static bNodeSocketTemplate outputs[]= { + { SOCK_RGBA, 0, "Texture" }, { -1, 0, "" } }; @@ -63,8 +63,8 @@ void register_node_type_tex_at(ListBase *lb) { static bNodeType ntype; - node_type_base(&ntype, TEX_NODE_AT, "At", NODE_CLASS_DISTORT, 0, - inputs, outputs); + node_type_base(&ntype, TEX_NODE_AT, "At", NODE_CLASS_DISTORT, 0); + node_type_socket_templates(&ntype, inputs, outputs); node_type_size(&ntype, 140, 100, 320); node_type_exec(&ntype, exec); diff --git a/source/blender/nodes/intern/TEX_nodes/TEX_bricks.c b/source/blender/nodes/texture/nodes/node_texture_bricks.c similarity index 76% rename from source/blender/nodes/intern/TEX_nodes/TEX_bricks.c rename to source/blender/nodes/texture/nodes/node_texture_bricks.c index 0eb982496a9..060ed791871 100644 --- a/source/blender/nodes/intern/TEX_nodes/TEX_bricks.c +++ b/source/blender/nodes/texture/nodes/node_texture_bricks.c @@ -26,32 +26,33 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/nodes/intern/TEX_nodes/TEX_bricks.c +/** \file blender/nodes/texture/nodes/node_texture_bricks.c * \ingroup texnodes */ -#include "../TEX_util.h" -#include "TEX_node.h" +#include "node_texture_util.h" +#include "NOD_texture.h" #include -static bNodeSocketType inputs[]= { - { SOCK_RGBA, 1, "Bricks 1", 0.596f, 0.282f, 0.0f, 1.0f, 0.0f, 1.0f }, - { SOCK_RGBA, 1, "Bricks 2", 0.632f, 0.504f, 0.05f, 1.0f, 0.0f, 1.0f }, - { SOCK_RGBA, 1, "Mortar", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f }, - { SOCK_VALUE, 1, "Thickness", 0.02f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f }, - { SOCK_VALUE, 1, "Bias", 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, 1.0f }, - { SOCK_VALUE, 1, "Brick Width", 0.5f, 0.0f, 0.0f, 0.0f, 0.001f, 99.0f }, - { SOCK_VALUE, 1, "Row Height", 0.25f, 0.0f, 0.0f, 0.0f, 0.001f, 99.0f }, +static bNodeSocketTemplate inputs[]= { + { SOCK_RGBA, 1, "Bricks 1", 0.596f, 0.282f, 0.0f, 1.0f }, + { SOCK_RGBA, 1, "Bricks 2", 0.632f, 0.504f, 0.05f, 1.0f }, + { SOCK_RGBA, 1, "Mortar", 0.0f, 0.0f, 0.0f, 1.0f }, + { SOCK_FLOAT, 1, "Thickness", 0.02f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_UNSIGNED }, + { SOCK_FLOAT, 1, "Bias", 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, 1.0f, PROP_NONE }, + { SOCK_FLOAT, 1, "Brick Width", 0.5f, 0.0f, 0.0f, 0.0f, 0.001f, 99.0f, PROP_UNSIGNED }, + { SOCK_FLOAT, 1, "Row Height", 0.25f, 0.0f, 0.0f, 0.0f, 0.001f, 99.0f, PROP_UNSIGNED }, { -1, 0, "" } }; -static bNodeSocketType outputs[]= { - { SOCK_RGBA, 0, "Color", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate outputs[]= { + { SOCK_RGBA, 0, "Color"}, { -1, 0, "" } }; -static void init(bNode *node) { +static void init(bNodeTree *UNUSED(ntree), bNode* node, bNodeTemplate *UNUSED(ntemp)) +{ node->custom3 = 0.5; /* offset */ node->custom4 = 1.0; /* squash */ } @@ -123,8 +124,8 @@ void register_node_type_tex_bricks(ListBase *lb) { static bNodeType ntype; - node_type_base(&ntype, TEX_NODE_BRICKS, "Bricks", NODE_CLASS_PATTERN, NODE_PREVIEW|NODE_OPTIONS, - inputs, outputs); + node_type_base(&ntype, TEX_NODE_BRICKS, "Bricks", NODE_CLASS_PATTERN, NODE_PREVIEW|NODE_OPTIONS); + node_type_socket_templates(&ntype, inputs, outputs); node_type_size(&ntype, 150, 60, 150); node_type_init(&ntype, init); node_type_exec(&ntype, exec); diff --git a/source/blender/nodes/intern/TEX_nodes/TEX_checker.c b/source/blender/nodes/texture/nodes/node_texture_checker.c similarity index 79% rename from source/blender/nodes/intern/TEX_nodes/TEX_checker.c rename to source/blender/nodes/texture/nodes/node_texture_checker.c index c6c25ba1a8a..916ee80d66b 100644 --- a/source/blender/nodes/intern/TEX_nodes/TEX_checker.c +++ b/source/blender/nodes/texture/nodes/node_texture_checker.c @@ -26,23 +26,23 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/nodes/intern/TEX_nodes/TEX_checker.c +/** \file blender/nodes/texture/nodes/node_texture_checker.c * \ingroup texnodes */ -#include "../TEX_util.h" -#include "TEX_node.h" +#include "node_texture_util.h" +#include "NOD_texture.h" #include -static bNodeSocketType inputs[]= { - { SOCK_RGBA, 1, "Color1", 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f }, - { SOCK_RGBA, 1, "Color2", 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f }, - { SOCK_VALUE, 1, "Size", 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 100.0f }, +static bNodeSocketTemplate inputs[]= { + { SOCK_RGBA, 1, "Color1", 1.0f, 0.0f, 0.0f, 1.0f }, + { SOCK_RGBA, 1, "Color2", 1.0f, 1.0f, 1.0f, 1.0f }, + { SOCK_FLOAT, 1, "Size", 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 100.0f, PROP_UNSIGNED }, { -1, 0, "" } }; -static bNodeSocketType outputs[]= { - { SOCK_RGBA, 0, "Color", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f }, +static bNodeSocketTemplate outputs[]= { + { SOCK_RGBA, 0, "Color" }, { -1, 0, "" } }; @@ -74,8 +74,8 @@ void register_node_type_tex_checker(ListBase *lb) { static bNodeType ntype; - node_type_base(&ntype, TEX_NODE_CHECKER, "Checker", NODE_CLASS_PATTERN, NODE_PREVIEW|NODE_OPTIONS, - inputs, outputs); + node_type_base(&ntype, TEX_NODE_CHECKER, "Checker", NODE_CLASS_PATTERN, NODE_PREVIEW|NODE_OPTIONS); + node_type_socket_templates(&ntype, inputs, outputs); node_type_size(&ntype, 100, 60, 150); node_type_exec(&ntype, exec); diff --git a/source/blender/nodes/texture/nodes/node_texture_common.c b/source/blender/nodes/texture/nodes/node_texture_common.c new file mode 100644 index 00000000000..cb5102bae4e --- /dev/null +++ b/source/blender/nodes/texture/nodes/node_texture_common.c @@ -0,0 +1,271 @@ +/* + * $Id: CMP_blur.c 35562 2011-03-15 20:10:32Z lukastoenne $ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2006 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): Campbell Barton, Alfredo de Greef, David Millan Escriva, + * Juho Vepsäläinen + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/nodes/texture/nodes/node_texture_common.c + * \ingroup texnodes + */ + + +#include "DNA_node_types.h" + +#include "BKE_node.h" + +#include "node_texture_util.h" +#include "node_common.h" +#include "node_exec.h" + +static void copy_stack(bNodeStack *to, bNodeStack *from) +{ + if (to != from) { + copy_v4_v4(to->vec, from->vec); + to->data = from->data; + to->datatype = from->datatype; + + /* tag as copy to prevent freeing */ + to->is_copy = 1; + } +} + +/**** GROUP ****/ + +static void *group_initexec(bNode *node) +{ + bNodeTree *ngroup= (bNodeTree*)node->id; + void *exec; + + /* initialize the internal node tree execution */ + exec = ntreeTexBeginExecTree(ngroup); + + return exec; +} + +static void group_freeexec(bNode *UNUSED(node), void *nodedata) +{ + bNodeTreeExec*gexec= (bNodeTreeExec*)nodedata; + + ntreeTexEndExecTree(gexec); +} + +/* Copy inputs to the internal stack. + * This is a shallow copy, no buffers are duplicated here! + */ +static void group_copy_inputs(bNode *node, bNodeStack **in, bNodeStack *gstack) +{ + bNodeSocket *sock; + bNodeStack *ns; + int a; + for (sock=node->inputs.first, a=0; sock; sock=sock->next, ++a) { + if (sock->groupsock) { + ns = node_get_socket_stack(gstack, sock->groupsock); + copy_stack(ns, in[a]); + } + } +} + +/* Copy internal results to the external outputs. + */ +static void group_copy_outputs(bNode *node, bNodeStack **out, bNodeStack *gstack) +{ + bNodeSocket *sock; + bNodeStack *ns; + int a; + for (sock=node->outputs.first, a=0; sock; sock=sock->next, ++a) { + if (sock->groupsock) { + ns = node_get_socket_stack(gstack, sock->groupsock); + copy_stack(out[a], ns); + } + } +} + +static void group_execute(void *data, int thread, struct bNode *node, void *nodedata, struct bNodeStack **in, struct bNodeStack **out) +{ + bNodeTreeExec *exec= (bNodeTreeExec*)nodedata; + bNodeThreadStack *nts; + + /* XXX same behavior as trunk: all nodes inside group are executed. + * it's stupid, but just makes it work. compo redesign will do this better. + */ + { + bNode *inode; + for (inode=exec->nodetree->nodes.first; inode; inode=inode->next) + inode->need_exec = 1; + } + + nts = ntreeGetThreadStack(exec, thread); + + group_copy_inputs(node, in, nts->stack); + ntreeExecThreadNodes(exec, nts, data, thread); + group_copy_outputs(node, out, nts->stack); + + ntreeReleaseThreadStack(nts); +} + +void register_node_type_tex_group(ListBase *lb) +{ + static bNodeType ntype; + + node_type_base(&ntype, NODE_GROUP, "Group", NODE_CLASS_GROUP, NODE_OPTIONS|NODE_CONST_OUTPUT); + node_type_socket_templates(&ntype, NULL, NULL); + node_type_size(&ntype, 120, 60, 200); + node_type_label(&ntype, node_group_label); + node_type_init(&ntype, node_group_init); + node_type_valid(&ntype, node_group_valid); + node_type_template(&ntype, node_group_template); + node_type_update(&ntype, NULL, node_group_verify); + node_type_group_edit(&ntype, node_group_edit_get, node_group_edit_set, node_group_edit_clear); + node_type_exec_new(&ntype, group_initexec, group_freeexec, group_execute); + + nodeRegisterType(lb, &ntype); +} + + +/**** FOR LOOP ****/ + +#if 0 /* XXX loop nodes don't work nicely with current trees */ +static void forloop_execute(void *data, int thread, struct bNode *node, void *nodedata, struct bNodeStack **in, struct bNodeStack **out) +{ + bNodeTreeExec *exec= (bNodeTreeExec*)nodedata; + bNodeThreadStack *nts; + int iterations= (int)in[0]->vec[0]; + bNodeSocket *sock; + bNodeStack *ns; + int iteration; + + /* XXX same behavior as trunk: all nodes inside group are executed. + * it's stupid, but just makes it work. compo redesign will do this better. + */ + { + bNode *inode; + for (inode=exec->nodetree->nodes.first; inode; inode=inode->next) + inode->need_exec = 1; + } + + nts = ntreeGetThreadStack(exec, thread); + + /* "Iteration" socket */ + sock = exec->nodetree->inputs.first; + ns = node_get_socket_stack(nts->stack, sock); + +// group_copy_inputs(node, in, nts->stack); + for (iteration=0; iteration < iterations; ++iteration) { + /* first input contains current iteration counter */ + ns->vec[0] = (float)iteration; + ns->vec[1]=ns->vec[2]=ns->vec[3] = 0.0f; + +// if (iteration > 0) +// loop_init_iteration(exec->nodetree, nts->stack); +// ntreeExecThreadNodes(exec, nts, data, thread); + } +// loop_copy_outputs(node, in, out, exec->stack); + + ntreeReleaseThreadStack(nts); +} + +void register_node_type_tex_forloop(ListBase *lb) +{ + static bNodeType ntype; + + node_type_base(&ntype, NODE_FORLOOP, "For", NODE_CLASS_GROUP, NODE_OPTIONS); + node_type_socket_templates(&ntype, NULL, NULL); + node_type_size(&ntype, 120, 60, 200); + node_type_label(&ntype, node_group_label); + node_type_init(&ntype, node_forloop_init); + node_type_valid(&ntype, node_group_valid); + node_type_template(&ntype, node_forloop_template); + node_type_update(&ntype, NULL, node_group_verify); + node_type_tree(&ntype, node_forloop_init_tree, node_loop_update_tree); + node_type_group_edit(&ntype, node_group_edit_get, node_group_edit_set, node_group_edit_clear); + node_type_exec_new(&ntype, group_initexec, group_freeexec, forloop_execute); + + nodeRegisterType(lb, &ntype); +} +#endif + +/**** WHILE LOOP ****/ + +#if 0 /* XXX loop nodes don't work nicely with current trees */ +static void whileloop_execute(void *data, int thread, struct bNode *node, void *nodedata, struct bNodeStack **in, struct bNodeStack **out) +{ + bNodeTreeExec *exec= (bNodeTreeExec*)nodedata; + bNodeThreadStack *nts; + int condition= (in[0]->vec[0] > 0.0f); + bNodeSocket *sock; + bNodeStack *ns; + int iteration; + + /* XXX same behavior as trunk: all nodes inside group are executed. + * it's stupid, but just makes it work. compo redesign will do this better. + */ + { + bNode *inode; + for (inode=exec->nodetree->nodes.first; inode; inode=inode->next) + inode->need_exec = 1; + } + + nts = ntreeGetThreadStack(exec, thread); + + /* "Condition" socket */ + sock = exec->nodetree->outputs.first; + ns = node_get_socket_stack(nts->stack, sock); + + iteration = 0; +// group_copy_inputs(node, in, nts->stack); + while (condition && iteration < node->custom1) { +// if (iteration > 0) +// loop_init_iteration(exec->nodetree, nts->stack); +// ntreeExecThreadNodes(exec, nts, data, thread); + + condition = (ns->vec[0] > 0.0f); + ++iteration; + } +// loop_copy_outputs(node, in, out, exec->stack); + + ntreeReleaseThreadStack(nts); +} + +void register_node_type_tex_whileloop(ListBase *lb) +{ + static bNodeType ntype; + + node_type_base(&ntype, NODE_WHILELOOP, "While", NODE_CLASS_GROUP, NODE_OPTIONS); + node_type_socket_templates(&ntype, NULL, NULL); + node_type_size(&ntype, 120, 60, 200); + node_type_label(&ntype, node_group_label); + node_type_init(&ntype, node_whileloop_init); + node_type_valid(&ntype, node_group_valid); + node_type_template(&ntype, node_whileloop_template); + node_type_update(&ntype, NULL, node_group_verify); + node_type_tree(&ntype, node_whileloop_init_tree, node_loop_update_tree); + node_type_group_edit(&ntype, node_group_edit_get, node_group_edit_set, node_group_edit_clear); + node_type_exec_new(&ntype, group_initexec, group_freeexec, whileloop_execute); + + nodeRegisterType(lb, &ntype); +} +#endif diff --git a/source/blender/nodes/intern/TEX_nodes/TEX_compose.c b/source/blender/nodes/texture/nodes/node_texture_compose.c similarity index 71% rename from source/blender/nodes/intern/TEX_nodes/TEX_compose.c rename to source/blender/nodes/texture/nodes/node_texture_compose.c index 6eae78ec3de..a11769173a3 100644 --- a/source/blender/nodes/intern/TEX_nodes/TEX_compose.c +++ b/source/blender/nodes/texture/nodes/node_texture_compose.c @@ -26,23 +26,23 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/nodes/intern/TEX_nodes/TEX_compose.c +/** \file blender/nodes/texture/nodes/node_texture_compose.c * \ingroup texnodes */ -#include "../TEX_util.h" -#include "TEX_node.h" +#include "node_texture_util.h" +#include "NOD_texture.h" -static bNodeSocketType inputs[]= { - { SOCK_VALUE, 1, "Red", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f }, - { SOCK_VALUE, 1, "Green", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f }, - { SOCK_VALUE, 1, "Blue", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f }, - { SOCK_VALUE, 1, "Alpha", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f }, +static bNodeSocketTemplate inputs[]= { + { SOCK_FLOAT, 1, "Red", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_UNSIGNED }, + { SOCK_FLOAT, 1, "Green", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_UNSIGNED }, + { SOCK_FLOAT, 1, "Blue", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_UNSIGNED }, + { SOCK_FLOAT, 1, "Alpha", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_UNSIGNED }, { -1, 0, "" } }; -static bNodeSocketType outputs[]= { - { SOCK_RGBA, 0, "Color", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f }, +static bNodeSocketTemplate outputs[]= { + { SOCK_RGBA, 0, "Color" }, { -1, 0, "" } }; @@ -62,8 +62,8 @@ void register_node_type_tex_compose(ListBase *lb) { static bNodeType ntype; - node_type_base(&ntype, TEX_NODE_COMPOSE, "Compose RGBA", NODE_CLASS_OP_COLOR, 0, - inputs, outputs); + node_type_base(&ntype, TEX_NODE_COMPOSE, "Compose RGBA", NODE_CLASS_OP_COLOR, 0); + node_type_socket_templates(&ntype, inputs, outputs); node_type_size(&ntype, 100, 60, 150); node_type_exec(&ntype, exec); diff --git a/source/blender/nodes/intern/TEX_nodes/TEX_coord.c b/source/blender/nodes/texture/nodes/node_texture_coord.c similarity index 86% rename from source/blender/nodes/intern/TEX_nodes/TEX_coord.c rename to source/blender/nodes/texture/nodes/node_texture_coord.c index 3c46971f0d4..b2d9cecc164 100644 --- a/source/blender/nodes/intern/TEX_nodes/TEX_coord.c +++ b/source/blender/nodes/texture/nodes/node_texture_coord.c @@ -26,16 +26,16 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/nodes/intern/TEX_nodes/TEX_coord.c +/** \file blender/nodes/texture/nodes/node_texture_coord.c * \ingroup texnodes */ -#include "../TEX_util.h" -#include "TEX_node.h" +#include "node_texture_util.h" +#include "NOD_texture.h" -static bNodeSocketType outputs[]= { - { SOCK_VECTOR, 0, "Coordinates", 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, 1.0f }, +static bNodeSocketTemplate outputs[]= { + { SOCK_VECTOR, 0, "Coordinates" }, { -1, 0, "" } }; @@ -55,8 +55,8 @@ void register_node_type_tex_coord(ListBase *lb) { static bNodeType ntype; - node_type_base(&ntype, TEX_NODE_COORD, "Coordinates", NODE_CLASS_INPUT, NODE_OPTIONS, - NULL, outputs); + node_type_base(&ntype, TEX_NODE_COORD, "Coordinates", NODE_CLASS_INPUT, NODE_OPTIONS); + node_type_socket_templates(&ntype, NULL, outputs); node_type_size(&ntype, 120, 110, 160); node_type_storage(&ntype, "node_coord", NULL, NULL); node_type_exec(&ntype, exec); diff --git a/source/blender/nodes/intern/TEX_nodes/TEX_curves.c b/source/blender/nodes/texture/nodes/node_texture_curves.c similarity index 80% rename from source/blender/nodes/intern/TEX_nodes/TEX_curves.c rename to source/blender/nodes/texture/nodes/node_texture_curves.c index b7af6c748ff..af6d880cc18 100644 --- a/source/blender/nodes/intern/TEX_nodes/TEX_curves.c +++ b/source/blender/nodes/texture/nodes/node_texture_curves.c @@ -26,19 +26,19 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/nodes/intern/TEX_nodes/TEX_curves.c +/** \file blender/nodes/texture/nodes/node_texture_curves.c * \ingroup texnodes */ -#include "../TEX_util.h" -#include "TEX_node.h" +#include "node_texture_util.h" +#include "NOD_texture.h" /* **************** CURVE Time ******************** */ /* custom1 = sfra, custom2 = efra */ -static bNodeSocketType time_outputs[]= { - { SOCK_VALUE, 0, "Value", 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f }, +static bNodeSocketTemplate time_outputs[]= { + { SOCK_FLOAT, 0, "Value" }, { -1, 0, "" } }; @@ -60,7 +60,7 @@ static void time_exec(void *data, bNode *node, bNodeStack **in, bNodeStack **out } -static void time_init(bNode* node) +static void time_init(bNodeTree *UNUSED(ntree), bNode* node, bNodeTemplate *UNUSED(ntemp)) { node->custom1= 1; node->custom2= 250; @@ -71,8 +71,8 @@ void register_node_type_tex_curve_time(ListBase *lb) { static bNodeType ntype; - node_type_base(&ntype, TEX_NODE_CURVE_TIME, "Time", NODE_CLASS_INPUT, NODE_OPTIONS, - NULL, time_outputs); + node_type_base(&ntype, TEX_NODE_CURVE_TIME, "Time", NODE_CLASS_INPUT, NODE_OPTIONS); + node_type_socket_templates(&ntype, NULL, time_outputs); node_type_size(&ntype, 140, 100, 320); node_type_init(&ntype, time_init); node_type_storage(&ntype, "CurveMapping", node_free_curves, node_copy_curves); @@ -82,13 +82,13 @@ void register_node_type_tex_curve_time(ListBase *lb) } /* **************** CURVE RGB ******************** */ -static bNodeSocketType rgb_inputs[]= { - { SOCK_RGBA, 1, "Color", 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f}, +static bNodeSocketTemplate rgb_inputs[]= { + { SOCK_RGBA, 1, "Color", 0.0f, 0.0f, 0.0f, 1.0f}, { -1, 0, "" } }; -static bNodeSocketType rgb_outputs[]= { - { SOCK_RGBA, 0, "Color", 0.0f, 0.0f, 1.0f, 1.0f, -1.0f, 1.0f}, +static bNodeSocketTemplate rgb_outputs[]= { + { SOCK_RGBA, 0, "Color"}, { -1, 0, "" } }; @@ -106,7 +106,7 @@ static void rgb_exec(void *data, bNode *node, bNodeStack **in, bNodeStack **out) tex_output(node, in, out[0], &rgb_colorfn, data); } -static void rgb_init(bNode *node) +static void rgb_init(bNodeTree *UNUSED(ntree), bNode* node, bNodeTemplate *UNUSED(ntemp)) { node->storage= curvemapping_add(4, 0.0f, 0.0f, 1.0f, 1.0f); } @@ -115,8 +115,8 @@ void register_node_type_tex_curve_rgb(ListBase *lb) { static bNodeType ntype; - node_type_base(&ntype, TEX_NODE_CURVE_RGB, "RGB Curves", NODE_CLASS_OP_COLOR, NODE_OPTIONS, - rgb_inputs, rgb_outputs); + node_type_base(&ntype, TEX_NODE_CURVE_RGB, "RGB Curves", NODE_CLASS_OP_COLOR, NODE_OPTIONS); + node_type_socket_templates(&ntype, rgb_inputs, rgb_outputs); node_type_size(&ntype, 200, 140, 320); node_type_init(&ntype, rgb_init); node_type_storage(&ntype, "CurveMapping", node_free_curves, node_copy_curves); diff --git a/source/blender/nodes/intern/TEX_nodes/TEX_decompose.c b/source/blender/nodes/texture/nodes/node_texture_decompose.c similarity index 80% rename from source/blender/nodes/intern/TEX_nodes/TEX_decompose.c rename to source/blender/nodes/texture/nodes/node_texture_decompose.c index f27d8c98716..312765f866e 100644 --- a/source/blender/nodes/intern/TEX_nodes/TEX_decompose.c +++ b/source/blender/nodes/texture/nodes/node_texture_decompose.c @@ -26,24 +26,24 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/nodes/intern/TEX_nodes/TEX_decompose.c +/** \file blender/nodes/texture/nodes/node_texture_decompose.c * \ingroup texnodes */ -#include "../TEX_util.h" -#include "TEX_node.h" +#include "node_texture_util.h" +#include "NOD_texture.h" #include -static bNodeSocketType inputs[]= { - { SOCK_RGBA, 1, "Color", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f }, +static bNodeSocketTemplate inputs[]= { + { SOCK_RGBA, 1, "Color", 0.0f, 0.0f, 0.0f, 1.0f }, { -1, 0, "" } }; -static bNodeSocketType outputs[]= { - { SOCK_VALUE, 0, "Red", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f }, - { SOCK_VALUE, 0, "Green", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f }, - { SOCK_VALUE, 0, "Blue", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f }, - { SOCK_VALUE, 0, "Alpha", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f }, +static bNodeSocketTemplate outputs[]= { + { SOCK_FLOAT, 0, "Red" }, + { SOCK_FLOAT, 0, "Green" }, + { SOCK_FLOAT, 0, "Blue" }, + { SOCK_FLOAT, 0, "Alpha" }, { -1, 0, "" } }; @@ -83,8 +83,8 @@ void register_node_type_tex_decompose(ListBase *lb) { static bNodeType ntype; - node_type_base(&ntype, TEX_NODE_DECOMPOSE, "Decompose RGBA", NODE_CLASS_OP_COLOR, 0, - inputs, outputs); + node_type_base(&ntype, TEX_NODE_DECOMPOSE, "Decompose RGBA", NODE_CLASS_OP_COLOR, 0); + node_type_socket_templates(&ntype, inputs, outputs); node_type_size(&ntype, 100, 60, 150); node_type_exec(&ntype, exec); diff --git a/source/blender/nodes/intern/TEX_nodes/TEX_distance.c b/source/blender/nodes/texture/nodes/node_texture_distance.c similarity index 84% rename from source/blender/nodes/intern/TEX_nodes/TEX_distance.c rename to source/blender/nodes/texture/nodes/node_texture_distance.c index b460844ba4a..fe524baaa96 100644 --- a/source/blender/nodes/intern/TEX_nodes/TEX_distance.c +++ b/source/blender/nodes/texture/nodes/node_texture_distance.c @@ -26,24 +26,24 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/nodes/intern/TEX_nodes/TEX_distance.c +/** \file blender/nodes/texture/nodes/node_texture_distance.c * \ingroup texnodes */ #include #include "BLI_math.h" -#include "../TEX_util.h" -#include "TEX_node.h" +#include "node_texture_util.h" +#include "NOD_texture.h" -static bNodeSocketType inputs[]= { - { SOCK_VECTOR, 1, "Coordinate 1", 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, 1.0f }, - { SOCK_VECTOR, 1, "Coordinate 2", 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, 1.0f }, +static bNodeSocketTemplate inputs[]= { + { SOCK_VECTOR, 1, "Coordinate 1", 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, 1.0f, PROP_NONE }, + { SOCK_VECTOR, 1, "Coordinate 2", 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, 1.0f, PROP_NONE }, { -1, 0, "" } }; -static bNodeSocketType outputs[]= { - { SOCK_VALUE, 0, "Value", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f }, +static bNodeSocketTemplate outputs[]= { + { SOCK_FLOAT, 0, "Value" }, { -1, 0, "" } }; @@ -66,8 +66,8 @@ void register_node_type_tex_distance(ListBase *lb) { static bNodeType ntype; - node_type_base(&ntype, TEX_NODE_DISTANCE, "Distance", NODE_CLASS_CONVERTOR, NODE_OPTIONS, - inputs, outputs); + node_type_base(&ntype, TEX_NODE_DISTANCE, "Distance", NODE_CLASS_CONVERTOR, NODE_OPTIONS); + node_type_socket_templates(&ntype, inputs, outputs); node_type_size(&ntype, 120, 110, 160); node_type_storage(&ntype, "node_distance", NULL, NULL); node_type_exec(&ntype, exec); diff --git a/source/blender/nodes/intern/TEX_nodes/TEX_hueSatVal.c b/source/blender/nodes/texture/nodes/node_texture_hueSatVal.c similarity index 78% rename from source/blender/nodes/intern/TEX_nodes/TEX_hueSatVal.c rename to source/blender/nodes/texture/nodes/node_texture_hueSatVal.c index 471d8db2c03..ebc2501cee3 100644 --- a/source/blender/nodes/intern/TEX_nodes/TEX_hueSatVal.c +++ b/source/blender/nodes/texture/nodes/node_texture_hueSatVal.c @@ -26,25 +26,25 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/nodes/intern/TEX_nodes/TEX_hueSatVal.c +/** \file blender/nodes/texture/nodes/node_texture_hueSatVal.c * \ingroup texnodes */ -#include "../TEX_util.h" -#include "TEX_node.h" +#include "node_texture_util.h" +#include "NOD_texture.h" -static bNodeSocketType inputs[]= { - { SOCK_VALUE, 1, "Hue", 0.0f, 0.0f, 0.0f, 0.0f, -0.5f, 0.5f }, - { SOCK_VALUE, 1, "Saturation", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 2.0f }, - { SOCK_VALUE, 1, "Value", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 2.0f }, - { SOCK_VALUE, 1, "Factor", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f }, - { SOCK_RGBA, 1, "Color", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f }, +static bNodeSocketTemplate inputs[]= { + { SOCK_FLOAT, 1, "Hue", 0.0f, 0.0f, 0.0f, 0.0f, -0.5f, 0.5f, PROP_NONE }, + { SOCK_FLOAT, 1, "Saturation", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 2.0f, PROP_FACTOR }, + { SOCK_FLOAT, 1, "Value", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 2.0f, PROP_FACTOR }, + { SOCK_FLOAT, 1, "Factor", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR }, + { SOCK_RGBA, 1, "Color", 0.8f, 0.8f, 0.8f, 1.0f }, { -1, 0, "" } }; -static bNodeSocketType outputs[]= { - { SOCK_RGBA, 0, "Color", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f }, +static bNodeSocketTemplate outputs[]= { + { SOCK_RGBA, 0, "Color" }, { -1, 0, "" } }; @@ -97,8 +97,8 @@ void register_node_type_tex_hue_sat(ListBase *lb) { static bNodeType ntype; - node_type_base(&ntype, TEX_NODE_HUE_SAT, "Hue Saturation Value", NODE_CLASS_OP_COLOR, NODE_OPTIONS, - inputs, outputs); + node_type_base(&ntype, TEX_NODE_HUE_SAT, "Hue Saturation Value", NODE_CLASS_OP_COLOR, NODE_OPTIONS); + node_type_socket_templates(&ntype, inputs, outputs); node_type_size(&ntype, 150, 80, 250); node_type_exec(&ntype, exec); diff --git a/source/blender/nodes/intern/TEX_nodes/TEX_image.c b/source/blender/nodes/texture/nodes/node_texture_image.c similarity index 86% rename from source/blender/nodes/intern/TEX_nodes/TEX_image.c rename to source/blender/nodes/texture/nodes/node_texture_image.c index a54ca4bb119..1359cf4275f 100644 --- a/source/blender/nodes/intern/TEX_nodes/TEX_image.c +++ b/source/blender/nodes/texture/nodes/node_texture_image.c @@ -1,5 +1,5 @@ /* - * $Id$ + * $Id: TEX_image.c 36481 2011-05-04 11:42:25Z lukastoenne $ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -27,16 +27,16 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/nodes/intern/TEX_nodes/TEX_image.c +/** \file blender/nodes/texture/nodes/node_texture_image.c * \ingroup texnodes */ -#include "../TEX_util.h" -#include "TEX_node.h" +#include "node_texture_util.h" +#include "NOD_texture.h" -static bNodeSocketType outputs[]= { - { SOCK_RGBA, 0, "Image", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate outputs[]= { + { SOCK_RGBA, 0, "Image"}, { -1, 0, "" } }; @@ -88,7 +88,7 @@ static void exec(void *data, bNode *node, bNodeStack **in, bNodeStack **out) tex_output(node, in, out[0], &colorfn, data); } -static void init(bNode* node) +static void init(bNodeTree *UNUSED(ntree), bNode* node, bNodeTemplate *UNUSED(ntemp)) { ImageUser *iuser= MEM_callocN(sizeof(ImageUser), "node image user"); node->storage= iuser; @@ -101,8 +101,8 @@ void register_node_type_tex_image(ListBase *lb) { static bNodeType ntype; - node_type_base(&ntype, TEX_NODE_IMAGE, "Image", NODE_CLASS_INPUT, NODE_PREVIEW|NODE_OPTIONS, - NULL, outputs); + node_type_base(&ntype, TEX_NODE_IMAGE, "Image", NODE_CLASS_INPUT, NODE_PREVIEW|NODE_OPTIONS); + node_type_socket_templates(&ntype, NULL, outputs); node_type_size(&ntype, 120, 80, 300); node_type_init(&ntype, init); node_type_storage(&ntype, "ImageUser", node_free_standard_storage, node_copy_standard_storage); diff --git a/source/blender/nodes/intern/TEX_nodes/TEX_invert.c b/source/blender/nodes/texture/nodes/node_texture_invert.c similarity index 83% rename from source/blender/nodes/intern/TEX_nodes/TEX_invert.c rename to source/blender/nodes/texture/nodes/node_texture_invert.c index e908bdcff07..8ba4f292fec 100644 --- a/source/blender/nodes/intern/TEX_nodes/TEX_invert.c +++ b/source/blender/nodes/texture/nodes/node_texture_invert.c @@ -26,22 +26,22 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/nodes/intern/TEX_nodes/TEX_invert.c +/** \file blender/nodes/texture/nodes/node_texture_invert.c * \ingroup texnodes */ -#include "../TEX_util.h" -#include "TEX_node.h" +#include "node_texture_util.h" +#include "NOD_texture.h" /* **************** INVERT ******************** */ -static bNodeSocketType inputs[]= { - { SOCK_RGBA, 1, "Color", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate inputs[]= { + { SOCK_RGBA, 1, "Color", 0.0f, 0.0f, 0.0f, 1.0f}, { -1, 0, "" } }; -static bNodeSocketType outputs[]= { - { SOCK_RGBA, 0, "Color", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate outputs[]= { + { SOCK_RGBA, 0, "Color"}, { -1, 0, "" } }; @@ -68,8 +68,8 @@ void register_node_type_tex_invert(ListBase *lb) { static bNodeType ntype; - node_type_base(&ntype, TEX_NODE_INVERT, "Invert", NODE_CLASS_OP_COLOR, NODE_OPTIONS, - inputs, outputs); + node_type_base(&ntype, TEX_NODE_INVERT, "Invert", NODE_CLASS_OP_COLOR, NODE_OPTIONS); + node_type_socket_templates(&ntype, inputs, outputs); node_type_size(&ntype, 90, 80, 100); node_type_exec(&ntype, exec); diff --git a/source/blender/nodes/intern/TEX_nodes/TEX_math.c b/source/blender/nodes/texture/nodes/node_texture_math.c similarity index 89% rename from source/blender/nodes/intern/TEX_nodes/TEX_math.c rename to source/blender/nodes/texture/nodes/node_texture_math.c index 18468bdd55c..182bc37978f 100644 --- a/source/blender/nodes/intern/TEX_nodes/TEX_math.c +++ b/source/blender/nodes/texture/nodes/node_texture_math.c @@ -26,24 +26,24 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/nodes/intern/TEX_nodes/TEX_math.c +/** \file blender/nodes/texture/nodes/node_texture_math.c * \ingroup texnodes */ -#include "../TEX_util.h" -#include "TEX_node.h" +#include "node_texture_util.h" +#include "NOD_texture.h" /* **************** SCALAR MATH ******************** */ -static bNodeSocketType inputs[]= { - { SOCK_VALUE, 1, "Value", 0.5f, 0.5f, 0.5f, 1.0f, -100.0f, 100.0f}, - { SOCK_VALUE, 1, "Value", 0.5f, 0.5f, 0.5f, 1.0f, -100.0f, 100.0f}, +static bNodeSocketTemplate inputs[]= { + { SOCK_FLOAT, 1, "Value", 0.5f, 0.5f, 0.5f, 1.0f, -100.0f, 100.0f, PROP_NONE}, + { SOCK_FLOAT, 1, "Value", 0.5f, 0.5f, 0.5f, 1.0f, -100.0f, 100.0f, PROP_NONE}, { -1, 0, "" } }; -static bNodeSocketType outputs[]= { - { SOCK_VALUE, 0, "Value", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate outputs[]= { + { SOCK_FLOAT, 0, "Value"}, { -1, 0, "" } }; @@ -189,8 +189,8 @@ void register_node_type_tex_math(ListBase *lb) { static bNodeType ntype; - node_type_base(&ntype, TEX_NODE_MATH, "Math", NODE_CLASS_CONVERTOR, NODE_OPTIONS, - inputs, outputs); + node_type_base(&ntype, TEX_NODE_MATH, "Math", NODE_CLASS_CONVERTOR, NODE_OPTIONS); + node_type_socket_templates(&ntype, inputs, outputs); node_type_size(&ntype, 120, 110, 160); node_type_label(&ntype, node_math_label); node_type_storage(&ntype, "node_math", NULL, NULL); diff --git a/source/blender/nodes/intern/TEX_nodes/TEX_mixRgb.c b/source/blender/nodes/texture/nodes/node_texture_mixRgb.c similarity index 79% rename from source/blender/nodes/intern/TEX_nodes/TEX_mixRgb.c rename to source/blender/nodes/texture/nodes/node_texture_mixRgb.c index c7668c27b99..8baac682b18 100644 --- a/source/blender/nodes/intern/TEX_nodes/TEX_mixRgb.c +++ b/source/blender/nodes/texture/nodes/node_texture_mixRgb.c @@ -26,23 +26,23 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/nodes/intern/TEX_nodes/TEX_mixRgb.c +/** \file blender/nodes/texture/nodes/node_texture_mixRgb.c * \ingroup texnodes */ -#include "../TEX_util.h" -#include "TEX_node.h" +#include "node_texture_util.h" +#include "NOD_texture.h" /* **************** MIX RGB ******************** */ -static bNodeSocketType inputs[]= { - { SOCK_VALUE, 1, "Factor", 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f }, - { SOCK_RGBA, 1, "Color1", 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 1.0f }, - { SOCK_RGBA , 1, "Color2", 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 1.0f }, +static bNodeSocketTemplate inputs[]= { + { SOCK_FLOAT, 1, "Factor", 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR }, + { SOCK_RGBA, 1, "Color1", 0.5f, 0.5f, 0.5f, 1.0f }, + { SOCK_RGBA , 1, "Color2", 0.5f, 0.5f, 0.5f, 1.0f }, { -1, 0, "" } }; -static bNodeSocketType outputs[]= { - { SOCK_RGBA, 0, "Color", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f }, +static bNodeSocketTemplate outputs[]= { + { SOCK_RGBA, 0, "Color" }, { -1, 0, "" } }; @@ -69,8 +69,8 @@ void register_node_type_tex_mix_rgb(ListBase *lb) { static bNodeType ntype; - node_type_base(&ntype, TEX_NODE_MIX_RGB, "Mix", NODE_CLASS_OP_COLOR, NODE_OPTIONS, - inputs, outputs); + node_type_base(&ntype, TEX_NODE_MIX_RGB, "Mix", NODE_CLASS_OP_COLOR, NODE_OPTIONS); + node_type_socket_templates(&ntype, inputs, outputs); node_type_size(&ntype, 100, 60, 150); node_type_label(&ntype, node_blend_label); node_type_exec(&ntype, exec); diff --git a/source/blender/nodes/intern/TEX_nodes/TEX_output.c b/source/blender/nodes/texture/nodes/node_texture_output.c similarity index 89% rename from source/blender/nodes/intern/TEX_nodes/TEX_output.c rename to source/blender/nodes/texture/nodes/node_texture_output.c index 046ad724507..c321f5738a1 100644 --- a/source/blender/nodes/intern/TEX_nodes/TEX_output.c +++ b/source/blender/nodes/texture/nodes/node_texture_output.c @@ -26,18 +26,18 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/nodes/intern/TEX_nodes/TEX_output.c +/** \file blender/nodes/texture/nodes/node_texture_output.c * \ingroup texnodes */ -#include "../TEX_util.h" -#include "TEX_node.h" +#include "node_texture_util.h" +#include "NOD_texture.h" /* **************** COMPOSITE ******************** */ -static bNodeSocketType inputs[]= { - { SOCK_RGBA, 1, "Color", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, - { SOCK_VECTOR, 1, "Normal", 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate inputs[]= { + { SOCK_RGBA, 1, "Color", 0.0f, 0.0f, 0.0f, 1.0f}, + { SOCK_VECTOR, 1, "Normal", 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, PROP_DIRECTION}, { -1, 0, "" } }; @@ -141,7 +141,7 @@ static void assign_index(struct bNode *node) node->custom1 = index; } -static void init(bNode *node) +static void init(bNodeTree *UNUSED(ntree), bNode* node, bNodeTemplate *UNUSED(ntemp)) { TexNodeOutput *tno = MEM_callocN(sizeof(TexNodeOutput), "TEX_output"); node->storage= tno; @@ -162,8 +162,8 @@ void register_node_type_tex_output(ListBase *lb) { static bNodeType ntype; - node_type_base(&ntype, TEX_NODE_OUTPUT, "Output", NODE_CLASS_OUTPUT, NODE_PREVIEW|NODE_OPTIONS, - inputs, NULL); + node_type_base(&ntype, TEX_NODE_OUTPUT, "Output", NODE_CLASS_OUTPUT, NODE_PREVIEW|NODE_OPTIONS); + node_type_socket_templates(&ntype, inputs, NULL); node_type_size(&ntype, 150, 60, 200); node_type_init(&ntype, init); node_type_storage(&ntype, "TexNodeOutput", node_free_standard_storage, copy); diff --git a/source/blender/nodes/intern/TEX_nodes/TEX_proc.c b/source/blender/nodes/texture/nodes/node_texture_proc.c similarity index 72% rename from source/blender/nodes/intern/TEX_nodes/TEX_proc.c rename to source/blender/nodes/texture/nodes/node_texture_proc.c index 294c1f7322f..8b4c25d85c9 100644 --- a/source/blender/nodes/intern/TEX_nodes/TEX_proc.c +++ b/source/blender/nodes/texture/nodes/node_texture_proc.c @@ -26,13 +26,13 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/nodes/intern/TEX_nodes/TEX_proc.c +/** \file blender/nodes/texture/nodes/node_texture_proc.c * \ingroup texnodes */ -#include "../TEX_util.h" -#include "TEX_node.h" +#include "node_texture_util.h" +#include "NOD_texture.h" #include "RE_shader_ext.h" @@ -41,21 +41,21 @@ */ -static bNodeSocketType outputs_both[]= { - { SOCK_RGBA, 0, "Color", 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f }, - { SOCK_VECTOR, 0, "Normal", 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f }, +static bNodeSocketTemplate outputs_both[]= { + { SOCK_RGBA, 0, "Color", 1.0f, 0.0f, 0.0f, 1.0f }, + { SOCK_VECTOR, 0, "Normal", 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, PROP_DIRECTION }, { -1, 0, "" } }; -static bNodeSocketType outputs_color_only[]= { - { SOCK_RGBA, 0, "Color", 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f }, +static bNodeSocketTemplate outputs_color_only[]= { + { SOCK_RGBA, 0, "Color" }, { -1, 0, "" } }; /* Inputs common to all, #defined because nodes will need their own inputs too */ #define I 2 /* count */ #define COMMON_INPUTS \ - { SOCK_RGBA, 1, "Color 1", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f }, \ - { SOCK_RGBA, 1, "Color 2", 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f } + { SOCK_RGBA, 1, "Color 1", 0.0f, 0.0f, 0.0f, 1.0f }, \ + { SOCK_RGBA, 1, "Color 2", 1.0f, 1.0f, 1.0f, 1.0f } /* Calls multitex and copies the result to the outputs. Called by xxx_exec, which handles inputs. */ static void do_proc(float *result, TexParams *p, float *col1, float *col2, char is_normal, Tex *tex, short thread) @@ -139,15 +139,15 @@ static int count_outputs(bNode *node) /* --- VORONOI -- */ -static bNodeSocketType voronoi_inputs[]= { +static bNodeSocketTemplate voronoi_inputs[]= { COMMON_INPUTS, - { SOCK_VALUE, 1, "W1", 1.0f, 0.0f, 0.0f, 0.0f, -2.0f, 2.0f }, - { SOCK_VALUE, 1, "W2", 0.0f, 0.0f, 0.0f, 0.0f, -2.0f, 2.0f }, - { SOCK_VALUE, 1, "W3", 0.0f, 0.0f, 0.0f, 0.0f, -2.0f, 2.0f }, - { SOCK_VALUE, 1, "W4", 0.0f, 0.0f, 0.0f, 0.0f, -2.0f, 2.0f }, + { SOCK_FLOAT, 1, "W1", 1.0f, 0.0f, 0.0f, 0.0f, -2.0f, 2.0f, PROP_NONE }, + { SOCK_FLOAT, 1, "W2", 0.0f, 0.0f, 0.0f, 0.0f, -2.0f, 2.0f, PROP_NONE }, + { SOCK_FLOAT, 1, "W3", 0.0f, 0.0f, 0.0f, 0.0f, -2.0f, 2.0f, PROP_NONE }, + { SOCK_FLOAT, 1, "W4", 0.0f, 0.0f, 0.0f, 0.0f, -2.0f, 2.0f, PROP_NONE }, - { SOCK_VALUE, 1, "iScale", 1.0f, 0.0f, 0.0f, 0.0f, 0.01f, 10.0f }, - { SOCK_VALUE, 1, "Size", 0.25f, 0.0f, 0.0f, 0.0f, 0.0001f, 4.0f }, + { SOCK_FLOAT, 1, "iScale", 1.0f, 0.0f, 0.0f, 0.0f, 0.01f, 10.0f, PROP_UNSIGNED }, + { SOCK_FLOAT, 1, "Size", 0.25f, 0.0f, 0.0f, 0.0f, 0.0001f, 4.0f, PROP_UNSIGNED }, { -1, 0, "" } }; @@ -164,7 +164,7 @@ static void voronoi_map_inputs(Tex *tex, bNodeStack **in, TexParams *p, short th ProcDef(voronoi) /* --- BLEND -- */ -static bNodeSocketType blend_inputs[]= { +static bNodeSocketTemplate blend_inputs[]= { COMMON_INPUTS, { -1, 0, "" } }; @@ -172,9 +172,9 @@ ProcNoInputs(blend) ProcDef(blend) /* -- MAGIC -- */ -static bNodeSocketType magic_inputs[]= { +static bNodeSocketTemplate magic_inputs[]= { COMMON_INPUTS, - { SOCK_VALUE, 1, "Turbulence", 5.0f, 0.0f, 0.0f, 0.0f, 0.0f, 200.0f }, + { SOCK_FLOAT, 1, "Turbulence", 5.0f, 0.0f, 0.0f, 0.0f, 0.0f, 200.0f, PROP_UNSIGNED }, { -1, 0, "" } }; static void magic_map_inputs(Tex *tex, bNodeStack **in, TexParams *p, short thread) @@ -184,10 +184,10 @@ static void magic_map_inputs(Tex *tex, bNodeStack **in, TexParams *p, short thre ProcDef(magic) /* --- MARBLE --- */ -static bNodeSocketType marble_inputs[]= { +static bNodeSocketTemplate marble_inputs[]= { COMMON_INPUTS, - { SOCK_VALUE, 1, "Size", 0.25f, 0.0f, 0.0f, 0.0f, 0.0001f, 2.0f }, - { SOCK_VALUE, 1, "Turbulence", 5.0f, 0.0f, 0.0f, 0.0f, 0.0f, 200.0f }, + { SOCK_FLOAT, 1, "Size", 0.25f, 0.0f, 0.0f, 0.0f, 0.0001f, 2.0f, PROP_UNSIGNED }, + { SOCK_FLOAT, 1, "Turbulence", 5.0f, 0.0f, 0.0f, 0.0f, 0.0f, 200.0f, PROP_UNSIGNED }, { -1, 0, "" } }; static void marble_map_inputs(Tex *tex, bNodeStack **in, TexParams *p, short thread) @@ -198,9 +198,9 @@ static void marble_map_inputs(Tex *tex, bNodeStack **in, TexParams *p, short thr ProcDef(marble) /* --- CLOUDS --- */ -static bNodeSocketType clouds_inputs[]= { +static bNodeSocketTemplate clouds_inputs[]= { COMMON_INPUTS, - { SOCK_VALUE, 1, "Size", 0.25f, 0.0f, 0.0f, 0.0f, 0.0001f, 2.0f }, + { SOCK_FLOAT, 1, "Size", 0.25f, 0.0f, 0.0f, 0.0f, 0.0001f, 2.0f, PROP_UNSIGNED }, { -1, 0, "" } }; static void clouds_map_inputs(Tex *tex, bNodeStack **in, TexParams *p, short thread) @@ -210,10 +210,10 @@ static void clouds_map_inputs(Tex *tex, bNodeStack **in, TexParams *p, short thr ProcDef(clouds) /* --- DISTORTED NOISE --- */ -static bNodeSocketType distnoise_inputs[]= { +static bNodeSocketTemplate distnoise_inputs[]= { COMMON_INPUTS, - { SOCK_VALUE, 1, "Size", 0.25f, 0.0f, 0.0f, 0.0f, 0.0001f, 2.0f }, - { SOCK_VALUE, 1, "Distortion", 1.00f, 0.0f, 0.0f, 0.0f, 0.0000f, 10.0f }, + { SOCK_FLOAT, 1, "Size", 0.25f, 0.0f, 0.0f, 0.0f, 0.0001f, 2.0f, PROP_UNSIGNED }, + { SOCK_FLOAT, 1, "Distortion", 1.00f, 0.0f, 0.0f, 0.0f, 0.0000f, 10.0f, PROP_UNSIGNED }, { -1, 0, "" } }; static void distnoise_map_inputs(Tex *tex, bNodeStack **in, TexParams *p, short thread) @@ -224,10 +224,10 @@ static void distnoise_map_inputs(Tex *tex, bNodeStack **in, TexParams *p, short ProcDef(distnoise) /* --- WOOD --- */ -static bNodeSocketType wood_inputs[]= { +static bNodeSocketTemplate wood_inputs[]= { COMMON_INPUTS, - { SOCK_VALUE, 1, "Size", 0.25f, 0.0f, 0.0f, 0.0f, 0.0001f, 2.0f }, - { SOCK_VALUE, 1, "Turbulence", 5.0f, 0.0f, 0.0f, 0.0f, 0.0f, 200.0f }, + { SOCK_FLOAT, 1, "Size", 0.25f, 0.0f, 0.0f, 0.0f, 0.0001f, 2.0f, PROP_UNSIGNED }, + { SOCK_FLOAT, 1, "Turbulence", 5.0f, 0.0f, 0.0f, 0.0f, 0.0f, 200.0f, PROP_UNSIGNED }, { -1, 0, "" } }; static void wood_map_inputs(Tex *tex, bNodeStack **in, TexParams *p, short thread) @@ -238,14 +238,14 @@ static void wood_map_inputs(Tex *tex, bNodeStack **in, TexParams *p, short threa ProcDef(wood) /* --- MUSGRAVE --- */ -static bNodeSocketType musgrave_inputs[]= { +static bNodeSocketTemplate musgrave_inputs[]= { COMMON_INPUTS, - { SOCK_VALUE, 1, "H", 1.0f, 0.0f, 0.0f, 0.0f, 0.0001f, 2.0f }, - { SOCK_VALUE, 1, "Lacunarity", 2.0f, 0.0f, 0.0f, 0.0f, 0.0f, 6.0f }, - { SOCK_VALUE, 1, "Octaves", 2.0f, 0.0f, 0.0f, 0.0f, 0.0f, 8.0f }, + { SOCK_FLOAT, 1, "H", 1.0f, 0.0f, 0.0f, 0.0f, 0.0001f, 2.0f, PROP_UNSIGNED }, + { SOCK_FLOAT, 1, "Lacunarity", 2.0f, 0.0f, 0.0f, 0.0f, 0.0f, 6.0f, PROP_UNSIGNED }, + { SOCK_FLOAT, 1, "Octaves", 2.0f, 0.0f, 0.0f, 0.0f, 0.0f, 8.0f, PROP_UNSIGNED }, - { SOCK_VALUE, 1, "iScale", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 10.0f }, - { SOCK_VALUE, 1, "Size", 0.25f, 0.0f, 0.0f, 0.0f, 0.0001f, 2.0f }, + { SOCK_FLOAT, 1, "iScale", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 10.0f, PROP_UNSIGNED }, + { SOCK_FLOAT, 1, "Size", 0.25f, 0.0f, 0.0f, 0.0f, 0.0001f, 2.0f, PROP_UNSIGNED }, { -1, 0, "" } }; static void musgrave_map_inputs(Tex *tex, bNodeStack **in, TexParams *p, short thread) @@ -259,7 +259,7 @@ static void musgrave_map_inputs(Tex *tex, bNodeStack **in, TexParams *p, short t ProcDef(musgrave) /* --- NOISE --- */ -static bNodeSocketType noise_inputs[]= { +static bNodeSocketTemplate noise_inputs[]= { COMMON_INPUTS, { -1, 0, "" } }; @@ -267,10 +267,10 @@ ProcNoInputs(noise) ProcDef(noise) /* --- STUCCI --- */ -static bNodeSocketType stucci_inputs[]= { +static bNodeSocketTemplate stucci_inputs[]= { COMMON_INPUTS, - { SOCK_VALUE, 1, "Size", 0.25f, 0.0f, 0.0f, 0.0f, 0.0001f, 2.0f }, - { SOCK_VALUE, 1, "Turbulence", 5.0f, 0.0f, 0.0f, 0.0f, 0.0f, 200.0f }, + { SOCK_FLOAT, 1, "Size", 0.25f, 0.0f, 0.0f, 0.0f, 0.0001f, 2.0f, PROP_UNSIGNED }, + { SOCK_FLOAT, 1, "Turbulence", 5.0f, 0.0f, 0.0f, 0.0f, 0.0f, 200.0f, PROP_UNSIGNED }, { -1, 0, "" } }; static void stucci_map_inputs(Tex *tex, bNodeStack **in, TexParams *p, short thread) @@ -282,7 +282,7 @@ ProcDef(stucci) /* --- */ -static void init(bNode *node) +static void init(bNodeTree *UNUSED(ntree), bNode* node, bNodeTemplate *UNUSED(ntemp)) { Tex *tex = MEM_callocN(sizeof(Tex), "Tex"); node->storage= tex; @@ -301,7 +301,8 @@ void register_node_type_tex_proc_##name(ListBase *lb) \ { \ static bNodeType ntype; \ \ - node_type_base(&ntype, TEX_NODE_PROC+TEXTYPE, Name, NODE_CLASS_TEXTURE, NODE_PREVIEW|NODE_OPTIONS, name##_inputs, outputs); \ + node_type_base(&ntype, TEX_NODE_PROC+TEXTYPE, Name, NODE_CLASS_TEXTURE, NODE_PREVIEW|NODE_OPTIONS); \ + node_type_socket_templates(&ntype, name##_inputs, outputs); \ node_type_size(&ntype, 140, 80, 140); \ node_type_init(&ntype, init); \ node_type_storage(&ntype, "Tex", node_free_standard_storage, node_copy_standard_storage); \ diff --git a/source/blender/nodes/intern/TEX_nodes/TEX_rotate.c b/source/blender/nodes/texture/nodes/node_texture_rotate.c similarity index 84% rename from source/blender/nodes/intern/TEX_nodes/TEX_rotate.c rename to source/blender/nodes/texture/nodes/node_texture_rotate.c index 1be6152a2b3..a788b9cbbde 100644 --- a/source/blender/nodes/intern/TEX_nodes/TEX_rotate.c +++ b/source/blender/nodes/texture/nodes/node_texture_rotate.c @@ -26,25 +26,25 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/nodes/intern/TEX_nodes/TEX_rotate.c +/** \file blender/nodes/texture/nodes/node_texture_rotate.c * \ingroup texnodes */ #include -#include "../TEX_util.h" -#include "TEX_node.h" +#include "node_texture_util.h" +#include "NOD_texture.h" -static bNodeSocketType inputs[]= { - { SOCK_RGBA, 1, "Color", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, - { SOCK_VALUE, 1, "Turns", 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, 1.0f }, - { SOCK_VECTOR, 1, "Axis", 0.0f, 0.0f, 1.0f, 0.0f, -1.0f, 1.0f }, +static bNodeSocketTemplate inputs[]= { + { SOCK_RGBA, 1, "Color", 0.0f, 0.0f, 0.0f, 1.0f}, + { SOCK_FLOAT, 1, "Turns", 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, 1.0f, PROP_NONE }, + { SOCK_VECTOR, 1, "Axis", 0.0f, 0.0f, 1.0f, 0.0f, -1.0f, 1.0f, PROP_DIRECTION }, { -1, 0, "" } }; -static bNodeSocketType outputs[]= { - { SOCK_RGBA, 0, "Color", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate outputs[]= { + { SOCK_RGBA, 0, "Color"}, { -1, 0, "" } }; @@ -100,8 +100,8 @@ void register_node_type_tex_rotate(ListBase *lb) { static bNodeType ntype; - node_type_base(&ntype, TEX_NODE_ROTATE, "Rotate", NODE_CLASS_DISTORT, NODE_OPTIONS, - inputs, outputs); + node_type_base(&ntype, TEX_NODE_ROTATE, "Rotate", NODE_CLASS_DISTORT, NODE_OPTIONS); + node_type_socket_templates(&ntype, inputs, outputs); node_type_size(&ntype, 140, 100, 320); node_type_exec(&ntype, exec); diff --git a/source/blender/nodes/intern/TEX_nodes/TEX_scale.c b/source/blender/nodes/texture/nodes/node_texture_scale.c similarity index 85% rename from source/blender/nodes/intern/TEX_nodes/TEX_scale.c rename to source/blender/nodes/texture/nodes/node_texture_scale.c index cfffcfda2e5..136dde0d52f 100644 --- a/source/blender/nodes/intern/TEX_nodes/TEX_scale.c +++ b/source/blender/nodes/texture/nodes/node_texture_scale.c @@ -26,22 +26,22 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/nodes/intern/TEX_nodes/TEX_scale.c +/** \file blender/nodes/texture/nodes/node_texture_scale.c * \ingroup texnodes */ #include -#include "../TEX_util.h" +#include "node_texture_util.h" -static bNodeSocketType inputs[]= { - { SOCK_RGBA, 1, "Color", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f }, - { SOCK_VECTOR, 1, "Scale", 1.0f, 1.0f, 1.0f, 0.0f, -10.0f, 10.0f }, +static bNodeSocketTemplate inputs[]= { + { SOCK_RGBA, 1, "Color", 0.0f, 0.0f, 0.0f, 1.0f }, + { SOCK_VECTOR, 1, "Scale", 1.0f, 1.0f, 1.0f, 0.0f, -10.0f, 10.0f, PROP_FACTOR }, { -1, 0, "" } }; -static bNodeSocketType outputs[]= { - { SOCK_RGBA, 0, "Color", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate outputs[]= { + { SOCK_RGBA, 0, "Color"}, { -1, 0, "" } }; @@ -73,8 +73,8 @@ void register_node_type_tex_scale(ListBase *lb) { static bNodeType ntype; - node_type_base(&ntype, TEX_NODE_SCALE, "Scale", NODE_CLASS_DISTORT, NODE_OPTIONS, - inputs, outputs); + node_type_base(&ntype, TEX_NODE_SCALE, "Scale", NODE_CLASS_DISTORT, NODE_OPTIONS); + node_type_socket_templates(&ntype, inputs, outputs); node_type_size(&ntype, 90, 80, 100); node_type_exec(&ntype, exec); diff --git a/source/blender/nodes/intern/TEX_nodes/TEX_texture.c b/source/blender/nodes/texture/nodes/node_texture_texture.c similarity index 84% rename from source/blender/nodes/intern/TEX_nodes/TEX_texture.c rename to source/blender/nodes/texture/nodes/node_texture_texture.c index c58595866af..10b9b8979f8 100644 --- a/source/blender/nodes/intern/TEX_nodes/TEX_texture.c +++ b/source/blender/nodes/texture/nodes/node_texture_texture.c @@ -26,24 +26,24 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/nodes/intern/TEX_nodes/TEX_texture.c +/** \file blender/nodes/texture/nodes/node_texture_texture.c * \ingroup texnodes */ -#include "../TEX_util.h" -#include "TEX_node.h" +#include "node_texture_util.h" +#include "NOD_texture.h" #include "RE_shader_ext.h" -static bNodeSocketType inputs[]= { - { SOCK_RGBA, 1, "Color1", 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f }, - { SOCK_RGBA, 1, "Color2", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f }, +static bNodeSocketTemplate inputs[]= { + { SOCK_RGBA, 1, "Color1", 1.0f, 1.0f, 1.0f, 1.0f }, + { SOCK_RGBA, 1, "Color2", 0.0f, 0.0f, 0.0f, 1.0f }, { -1, 0, "" } }; -static bNodeSocketType outputs[]= { - { SOCK_RGBA, 0, "Color", 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f }, +static bNodeSocketTemplate outputs[]= { + { SOCK_RGBA, 0, "Color" }, { -1, 0, "" } }; @@ -53,7 +53,7 @@ static void colorfn(float *out, TexParams *p, bNode *node, bNodeStack **in, shor static float red[] = {1,0,0,1}; static float white[] = {1,1,1,1}; float co[3], dxt[3], dyt[3]; - + copy_v3_v3(co, p->co); copy_v3_v3(dxt, p->dxt); copy_v3_v3(dyt, p->dyt); @@ -70,7 +70,7 @@ static void colorfn(float *out, TexParams *p, bNode *node, bNodeStack **in, shor tex_input_rgba(col1, in[0], p, thread); tex_input_rgba(col2, in[1], p, thread); - + texres.nor = nor; textype = multitex_nodes(nodetex, co, dxt, dyt, p->osatex, &texres, thread, 0, p->shi, p->mtex); @@ -94,8 +94,8 @@ void register_node_type_tex_texture(ListBase *lb) { static bNodeType ntype; - node_type_base(&ntype, TEX_NODE_TEXTURE, "Texture", NODE_CLASS_INPUT, NODE_PREVIEW|NODE_OPTIONS, - inputs, outputs); + node_type_base(&ntype, TEX_NODE_TEXTURE, "Texture", NODE_CLASS_INPUT, NODE_PREVIEW|NODE_OPTIONS); + node_type_socket_templates(&ntype, inputs, outputs); node_type_size(&ntype, 120, 80, 240); node_type_exec(&ntype, exec); diff --git a/source/blender/nodes/intern/TEX_nodes/TEX_translate.c b/source/blender/nodes/texture/nodes/node_texture_translate.c similarity index 82% rename from source/blender/nodes/intern/TEX_nodes/TEX_translate.c rename to source/blender/nodes/texture/nodes/node_texture_translate.c index 8f7d6d837d7..395404a9411 100644 --- a/source/blender/nodes/intern/TEX_nodes/TEX_translate.c +++ b/source/blender/nodes/texture/nodes/node_texture_translate.c @@ -26,23 +26,23 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/nodes/intern/TEX_nodes/TEX_translate.c +/** \file blender/nodes/texture/nodes/node_texture_translate.c * \ingroup texnodes */ #include -#include "../TEX_util.h" -#include "TEX_node.h" +#include "node_texture_util.h" +#include "NOD_texture.h" -static bNodeSocketType inputs[]= { - { SOCK_RGBA, 1, "Color", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, - { SOCK_VECTOR, 1, "Offset", 0.0f, 0.0f, 0.0f, 0.0f, -10000.0f, 10000.0f }, +static bNodeSocketTemplate inputs[]= { + { SOCK_RGBA, 1, "Color", 0.0f, 0.0f, 0.0f, 1.0f}, + { SOCK_VECTOR, 1, "Offset", 0.0f, 0.0f, 0.0f, 0.0f, -10000.0f, 10000.0f, PROP_TRANSLATION }, { -1, 0, "" } }; -static bNodeSocketType outputs[]= { - { SOCK_RGBA, 0, "Color", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate outputs[]= { + { SOCK_RGBA, 0, "Color"}, { -1, 0, "" } }; @@ -69,8 +69,8 @@ void register_node_type_tex_translate(ListBase *lb) { static bNodeType ntype; - node_type_base(&ntype, TEX_NODE_TRANSLATE, "Translate", NODE_CLASS_DISTORT, NODE_OPTIONS, - inputs, outputs); + node_type_base(&ntype, TEX_NODE_TRANSLATE, "Translate", NODE_CLASS_DISTORT, NODE_OPTIONS); + node_type_socket_templates(&ntype, inputs, outputs); node_type_size(&ntype, 90, 80, 100); node_type_exec(&ntype, exec); diff --git a/source/blender/nodes/intern/TEX_nodes/TEX_valToNor.c b/source/blender/nodes/texture/nodes/node_texture_valToNor.c similarity index 81% rename from source/blender/nodes/intern/TEX_nodes/TEX_valToNor.c rename to source/blender/nodes/texture/nodes/node_texture_valToNor.c index e430c0c9a95..62b457bc862 100644 --- a/source/blender/nodes/intern/TEX_nodes/TEX_valToNor.c +++ b/source/blender/nodes/texture/nodes/node_texture_valToNor.c @@ -26,22 +26,22 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/nodes/intern/TEX_nodes/TEX_valToNor.c +/** \file blender/nodes/texture/nodes/node_texture_valToNor.c * \ingroup texnodes */ -#include "../TEX_util.h" -#include "TEX_node.h" +#include "node_texture_util.h" +#include "NOD_texture.h" -static bNodeSocketType inputs[]= { - { SOCK_VALUE, 1, "Val", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f }, - { SOCK_VALUE, 1, "Nabla", 0.025f, 0.0f, 0.0f, 0.0f, 0.001f, 0.1f }, +static bNodeSocketTemplate inputs[]= { + { SOCK_FLOAT, 1, "Val", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, PROP_NONE }, + { SOCK_FLOAT, 1, "Nabla", 0.025f, 0.0f, 0.0f, 0.0f, 0.001f, 0.1f, PROP_UNSIGNED }, { -1, 0, "" } }; -static bNodeSocketType outputs[]= { - { SOCK_VECTOR, 0, "Normal", 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f }, +static bNodeSocketTemplate outputs[]= { + { SOCK_VECTOR, 0, "Normal" }, { -1, 0, "" } }; @@ -85,8 +85,8 @@ void register_node_type_tex_valtonor(ListBase *lb) { static bNodeType ntype; - node_type_base(&ntype, TEX_NODE_VALTONOR, "Value to Normal", NODE_CLASS_CONVERTOR, NODE_OPTIONS, - inputs, outputs); + node_type_base(&ntype, TEX_NODE_VALTONOR, "Value to Normal", NODE_CLASS_CONVERTOR, NODE_OPTIONS); + node_type_socket_templates(&ntype, inputs, outputs); node_type_size(&ntype, 90, 80, 100); node_type_exec(&ntype, exec); diff --git a/source/blender/nodes/intern/TEX_nodes/TEX_valToRgb.c b/source/blender/nodes/texture/nodes/node_texture_valToRgb.c similarity index 77% rename from source/blender/nodes/intern/TEX_nodes/TEX_valToRgb.c rename to source/blender/nodes/texture/nodes/node_texture_valToRgb.c index 8f59828081c..caca6fa97a4 100644 --- a/source/blender/nodes/intern/TEX_nodes/TEX_valToRgb.c +++ b/source/blender/nodes/texture/nodes/node_texture_valToRgb.c @@ -1,5 +1,5 @@ /* - * $Id$ + * $Id: TEX_valToRgb.c 36593 2011-05-10 11:19:26Z lukastoenne $ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -27,21 +27,21 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/nodes/intern/TEX_nodes/TEX_valToRgb.c +/** \file blender/nodes/texture/nodes/node_texture_valToRgb.c * \ingroup texnodes */ -#include "../TEX_util.h" -#include "TEX_node.h" +#include "node_texture_util.h" +#include "NOD_texture.h" /* **************** VALTORGB ******************** */ -static bNodeSocketType valtorgb_in[]= { - { SOCK_VALUE, 1, "Fac", 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate valtorgb_in[]= { + { SOCK_FLOAT, 1, "Fac", 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR}, { -1, 0, "" } }; -static bNodeSocketType valtorgb_out[]= { - { SOCK_RGBA, 0, "Color", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate valtorgb_out[]= { + { SOCK_RGBA, 0, "Color"}, { -1, 0, "" } }; @@ -59,7 +59,7 @@ static void valtorgb_exec(void *data, bNode *node, bNodeStack **in, bNodeStack * tex_output(node, in, out[0], &valtorgb_colorfn, data); } -static void valtorgb_init(bNode *node) +static void valtorgb_init(bNodeTree *UNUSED(ntree), bNode* node, bNodeTemplate *UNUSED(ntemp)) { node->storage = add_colorband(1); } @@ -68,8 +68,8 @@ void register_node_type_tex_valtorgb(ListBase *lb) { static bNodeType ntype; - node_type_base(&ntype, TEX_NODE_VALTORGB, "ColorRamp", NODE_CLASS_CONVERTOR, NODE_OPTIONS, - valtorgb_in, valtorgb_out); + node_type_base(&ntype, TEX_NODE_VALTORGB, "ColorRamp", NODE_CLASS_CONVERTOR, NODE_OPTIONS); + node_type_socket_templates(&ntype, valtorgb_in, valtorgb_out); node_type_size(&ntype, 240, 200, 300); node_type_init(&ntype, valtorgb_init); node_type_storage(&ntype, "ColorBand", node_free_standard_storage, node_copy_standard_storage); @@ -79,12 +79,12 @@ void register_node_type_tex_valtorgb(ListBase *lb) } /* **************** RGBTOBW ******************** */ -static bNodeSocketType rgbtobw_in[]= { +static bNodeSocketTemplate rgbtobw_in[]= { { SOCK_RGBA, 1, "Color", 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 1.0f}, { -1, 0, "" } }; -static bNodeSocketType rgbtobw_out[]= { - { SOCK_VALUE, 0, "Val", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, +static bNodeSocketTemplate rgbtobw_out[]= { + { SOCK_FLOAT, 0, "Val", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, { -1, 0, "" } }; @@ -106,8 +106,8 @@ void register_node_type_tex_rgbtobw(ListBase *lb) { static bNodeType ntype; - node_type_base(&ntype, TEX_NODE_RGBTOBW, "RGB to BW", NODE_CLASS_CONVERTOR, 0, - rgbtobw_in, rgbtobw_out); + node_type_base(&ntype, TEX_NODE_RGBTOBW, "RGB to BW", NODE_CLASS_CONVERTOR, 0); + node_type_socket_templates(&ntype, rgbtobw_in, rgbtobw_out); node_type_size(&ntype, 80, 40, 120); node_type_exec(&ntype, rgbtobw_exec); diff --git a/source/blender/nodes/intern/TEX_nodes/TEX_viewer.c b/source/blender/nodes/texture/nodes/node_texture_viewer.c similarity index 83% rename from source/blender/nodes/intern/TEX_nodes/TEX_viewer.c rename to source/blender/nodes/texture/nodes/node_texture_viewer.c index e917e525e17..01734f56937 100644 --- a/source/blender/nodes/intern/TEX_nodes/TEX_viewer.c +++ b/source/blender/nodes/texture/nodes/node_texture_viewer.c @@ -26,20 +26,20 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/nodes/intern/TEX_nodes/TEX_viewer.c +/** \file blender/nodes/texture/nodes/node_texture_viewer.c * \ingroup texnodes */ -#include "../TEX_util.h" -#include "TEX_node.h" +#include "node_texture_util.h" +#include "NOD_texture.h" #include -static bNodeSocketType inputs[]= { - { SOCK_RGBA, 1, "Color", 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f }, +static bNodeSocketTemplate inputs[]= { + { SOCK_RGBA, 1, "Color", 1.0f, 0.0f, 0.0f, 1.0f }, { -1, 0, "" } }; -static bNodeSocketType outputs[]= { +static bNodeSocketTemplate outputs[]= { { -1, 0, "" } }; @@ -61,8 +61,8 @@ void register_node_type_tex_viewer(ListBase *lb) { static bNodeType ntype; - node_type_base(&ntype, TEX_NODE_VIEWER, "Viewer", NODE_CLASS_OUTPUT, NODE_PREVIEW, - inputs, outputs); + node_type_base(&ntype, TEX_NODE_VIEWER, "Viewer", NODE_CLASS_OUTPUT, NODE_PREVIEW); + node_type_socket_templates(&ntype, inputs, outputs); node_type_size(&ntype, 100, 60, 150); node_type_exec(&ntype, exec); diff --git a/source/blender/render/intern/source/render_texture.c b/source/blender/render/intern/source/render_texture.c index fbbb33d0172..e35b3e53f5b 100644 --- a/source/blender/render/intern/source/render_texture.c +++ b/source/blender/render/intern/source/render_texture.c @@ -125,7 +125,7 @@ static void init_render_texture(Render *re, Tex *tex) } if(tex->nodetree && tex->use_nodes) { - ntreeBeginExecTree(tex->nodetree); /* has internal flag to detect it only does it once */ + ntreeTexBeginExecTree(tex->nodetree); /* has internal flag to detect it only does it once */ } } @@ -144,8 +144,8 @@ void init_render_textures(Render *re) static void end_render_texture(Tex *tex) { - if(tex && tex->use_nodes && tex->nodetree) - ntreeEndExecTree(tex->nodetree); + if(tex && tex->use_nodes && tex->nodetree && tex->nodetree->execdata) + ntreeTexEndExecTree(tex->nodetree->execdata); } void end_render_textures(Render *re) diff --git a/source/creator/CMakeLists.txt b/source/creator/CMakeLists.txt index 315cd5312cf..bf2808ba4c0 100644 --- a/source/creator/CMakeLists.txt +++ b/source/creator/CMakeLists.txt @@ -718,7 +718,6 @@ if(WITH_MOD_FLUID) list(APPEND BLENDER_LINK_LIBS bf_intern_elbeem) endif() - #if(UNIX) # Sort libraries set(BLENDER_SORTED_LIBS