Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLukas Toenne <lukas.toenne@googlemail.com>2013-03-18 20:34:57 +0400
committerLukas Toenne <lukas.toenne@googlemail.com>2013-03-18 20:34:57 +0400
commit4638e5f99a9ba59ad0b8a1fd52b12e876480b9e8 (patch)
tree2444f12b4612440f44cf02835cdf5951b6564e92 /source/blender/blenloader/intern/versioning_250.c
parent7bfef29f2f2a1b262d28abdc6e30fcd9c1f1caad (diff)
Merge of the PyNodes branch (aka "custom nodes") into trunk.
PyNodes opens up the node system in Blender to scripters and adds a number of UI-level improvements. === Dynamic node type registration === Node types can now be added at runtime, using the RNA registration mechanism from python. This enables addons such as render engines to create a complete user interface with nodes. Examples of how such nodes can be defined can be found in my personal wiki docs atm [1] and as a script template in release/scripts/templates_py/custom_nodes.py [2]. === Node group improvements === Each node editor now has a tree history of edited node groups, which allows opening and editing nested node groups. The node editor also supports pinning now, so that different spaces can be used to edit different node groups simultaneously. For more ramblings and rationale see (really old) blog post on code.blender.org [3]. The interface of node groups has been overhauled. Sockets of a node group are no longer displayed in columns on either side, but instead special input/output nodes are used to mirror group sockets inside a node tree. This solves the problem of long node lines in groups and allows more adaptable node layout. Internal sockets can be exposed from a group by either connecting to the extension sockets in input/output nodes (shown as empty circle) or by adding sockets from the node property bar in the "Interface" panel. Further details such as the socket name can also be changed there. [1] http://wiki.blender.org/index.php/User:Phonybone/Python_Nodes [2] http://projects.blender.org/scm/viewvc.php/trunk/blender/release/scripts/templates_py/custom_nodes.py?view=markup&root=bf-blender [3] http://code.blender.org/index.php/2012/01/improving-node-group-interface-editing/
Diffstat (limited to 'source/blender/blenloader/intern/versioning_250.c')
-rw-r--r--source/blender/blenloader/intern/versioning_250.c180
1 files changed, 155 insertions, 25 deletions
diff --git a/source/blender/blenloader/intern/versioning_250.c b/source/blender/blenloader/intern/versioning_250.c
index 36f3ea3654c..f92a8678300 100644
--- a/source/blender/blenloader/intern/versioning_250.c
+++ b/source/blender/blenloader/intern/versioning_250.c
@@ -672,13 +672,90 @@ static void do_version_bone_roll_256(Bone *bone)
do_version_bone_roll_256(child);
}
-static void do_versions_nodetree_dynamic_sockets(bNodeTree *ntree)
+/* deprecated, only keep this for readfile.c */
+/* XXX Deprecated function to add a socket in ntree->inputs/ntree->outputs list
+ * (previously called node_group_add_socket). This function has been superseded
+ * by the implementation of proxy nodes. It is still necessary though
+ * for do_versions of pre-2.56.2 code (r35033), so later proxy nodes
+ * can be generated consistently from ntree socket lists.
+ */
+static bNodeSocket *do_versions_node_group_add_socket_2_56_2(bNodeTree *ngroup, const char *name, int type, int in_out)
+{
+// bNodeSocketType *stype = ntreeGetSocketType(type);
+ bNodeSocket *gsock = MEM_callocN(sizeof(bNodeSocket), "bNodeSocket");
+
+ BLI_strncpy(gsock->name, name, sizeof(gsock->name));
+ gsock->type = type;
+
+ 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;
+}
+
+/* Create default_value structs for node sockets from the internal bNodeStack value.
+ * These structs were used from 2.59.2 on, but are replaced in the subsequent do_versions for custom nodes
+ * by generic ID property values. This conversion happened _after_ do_versions originally due to messy type initialization
+ * for node sockets. Now created here intermediately for convenience and to keep do_versions consistent.
+ *
+ * Node compatibility code is gross ...
+ */
+static void do_versions_socket_default_value_259(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_259(bNodeTree *ntree)
{
+ bNode *node;
bNodeSocket *sock;
- for (sock = ntree->inputs.first; sock; sock = sock->next)
- sock->flag |= SOCK_DYNAMIC;
- for (sock = ntree->outputs.first; sock; sock = sock->next)
- sock->flag |= SOCK_DYNAMIC;
+ for (node=ntree->nodes.first; node; node=node->next) {
+ for (sock=node->inputs.first; sock; sock=sock->next)
+ do_versions_socket_default_value_259(sock);
+ for (sock=node->outputs.first; sock; sock=sock->next)
+ do_versions_socket_default_value_259(sock);
+ }
+ for (sock=ntree->inputs.first; sock; sock=sock->next)
+ do_versions_socket_default_value_259(sock);
+ for (sock=ntree->outputs.first; sock; sock=sock->next)
+ do_versions_socket_default_value_259(sock);
}
void blo_do_versions_250(FileData *fd, Library *lib, Main *main)
@@ -2289,16 +2366,79 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *main)
if (main->versionfile < 256 || (main->versionfile == 256 && main->subversionfile < 2)) {
bNodeTree *ntree;
-
+ bNode *node;
+ bNodeSocket *sock, *gsock;
+ bNodeLink *link;
+
/* node sockets are not exposed automatically any more,
* this mimics the old behavior by adding all unlinked sockets to groups.
*/
- for (ntree = main->nodetree.first; ntree; ntree = ntree->id.next) {
- /* XXX Only setting a flag here. Actual adding of group sockets
- * is done in lib_verify_nodetree, because at this point the internal
- * nodes may not be up-to-date! (missing lib-link)
+ for (ntree=main->nodetree.first; ntree; ntree=ntree->id.next) {
+ /* this adds copies and links from all unlinked internal sockets to group inputs/outputs. */
+
+ /* first make sure the own_index for new sockets is valid */
+ for (node=ntree->nodes.first; node; node=node->next) {
+ for (sock=node->inputs.first; sock; sock=sock->next)
+ if (sock->own_index >= ntree->cur_index)
+ ntree->cur_index = sock->own_index+1;
+ for (sock=node->outputs.first; sock; sock=sock->next)
+ if (sock->own_index >= ntree->cur_index)
+ ntree->cur_index = sock->own_index+1;
+ }
+
+ /* add ntree->inputs/ntree->outputs sockets for all unlinked sockets in the group tree. */
+ for (node=ntree->nodes.first; node; node=node->next) {
+ for (sock=node->inputs.first; sock; sock=sock->next) {
+ if (!sock->link && !nodeSocketIsHidden(sock)) {
+
+ gsock = do_versions_node_group_add_socket_2_56_2(ntree, sock->name, sock->type, SOCK_IN);
+
+ /* initialize the default socket value */
+ copy_v4_v4(gsock->ns.vec, sock->ns.vec);
+
+ /* XXX nodeAddLink does not work with incomplete (node==NULL) links any longer,
+ * have to create these directly here. These links are updated again in subsequent do_version!
+ */
+ link= MEM_callocN(sizeof(bNodeLink), "link");
+ BLI_addtail(&ntree->links, link);
+ link->fromnode= NULL;
+ link->fromsock= gsock;
+ link->tonode= node;
+ link->tosock= sock;
+ ntree->update |= NTREE_UPDATE_LINKS;
+
+ sock->link = link;
+ }
+ }
+ for (sock=node->outputs.first; sock; sock=sock->next) {
+ if (nodeCountSocketLinks(ntree, sock)==0 && !nodeSocketIsHidden(sock)) {
+ gsock = do_versions_node_group_add_socket_2_56_2(ntree, sock->name, sock->type, SOCK_OUT);
+
+ /* initialize the default socket value */
+ copy_v4_v4(gsock->ns.vec, sock->ns.vec);
+
+ /* XXX nodeAddLink does not work with incomplete (node==NULL) links any longer,
+ * have to create these directly here. These links are updated again in subsequent do_version!
+ */
+ link= MEM_callocN(sizeof(bNodeLink), "link");
+ BLI_addtail(&ntree->links, link);
+ link->fromnode= node;
+ link->fromsock= sock;
+ link->tonode= NULL;
+ link->tosock= gsock;
+ ntree->update |= NTREE_UPDATE_LINKS;
+
+ gsock->link = link;
+ }
+ }
+ }
+
+ /* XXX The external group node sockets needs to adjust their own_index to point at
+ * associated ntree inputs/outputs internal sockets. However, this can only happen
+ * after lib-linking (needs access to internal node group tree)!
+ * Setting a temporary flag here, actual do_versions happens in lib_verify_nodetree.
*/
- ntree->flag |= NTREE_DO_VERSIONS_GROUP_EXPOSE;
+ ntree->flag |= NTREE_DO_VERSIONS_GROUP_EXPOSE_2_56_2;
}
}
@@ -2601,39 +2741,29 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *main)
bNodeTree *ntree;
for (ntree = main->nodetree.first; ntree; ntree = ntree->id.next) {
- blo_do_versions_nodetree_default_value(ntree);
+ do_versions_nodetree_default_value_259(ntree);
ntree->update |= NTREE_UPDATE;
}
for (sce = main->scene.first; sce; sce = sce->id.next)
if (sce->nodetree) {
- blo_do_versions_nodetree_default_value(sce->nodetree);
+ do_versions_nodetree_default_value_259(sce->nodetree);
sce->nodetree->update |= NTREE_UPDATE;
}
for (mat = main->mat.first; mat; mat = mat->id.next)
if (mat->nodetree) {
- blo_do_versions_nodetree_default_value(mat->nodetree);
+ do_versions_nodetree_default_value_259(mat->nodetree);
mat->nodetree->update |= NTREE_UPDATE;
}
for (tex = main->tex.first; tex; tex = tex->id.next)
if (tex->nodetree) {
- blo_do_versions_nodetree_default_value(tex->nodetree);
+ do_versions_nodetree_default_value_259(tex->nodetree);
tex->nodetree->update |= NTREE_UPDATE;
}
}
- /* add SOCK_DYNAMIC flag to existing group sockets */
- {
- bNodeTree *ntree;
- /* only need to do this for trees in main, local trees are not used as groups */
- for (ntree = main->nodetree.first; ntree; ntree = ntree->id.next) {
- do_versions_nodetree_dynamic_sockets(ntree);
- ntree->update |= NTREE_UPDATE;
- }
- }
-
{
/* Initialize group tree nodetypes.
* These are used to distinguish tree types and