static int node_group_insert_exec(bContext *C, wmOperator *op) { SpaceNode *snode = CTX_wm_space_node(C); bNodeTree *ntree = snode->edittree; bNodeTree *ngroup; const char *node_idname = group_node_idname(C); bNode *gnode; Main *bmain = CTX_data_main(C); ED_preview_kill_jobs(C); gnode = node_group_get_active(C, node_idname); if (!gnode || !gnode->id) return OPERATOR_CANCELLED; ngroup = (bNodeTree *)gnode->id; if (!node_group_make_test_selected(ntree, gnode, ngroup->idname, op->reports)) return OPERATOR_CANCELLED; node_group_make_insert_selected(C, ntree, gnode); nodeSetActive(ntree, gnode); ED_node_tree_push(snode, ngroup, gnode); ntreeUpdateTree(bmain, ngroup); ntreeUpdateTree(bmain, ntree); snode_notify(C, snode); snode_dag_update(C, snode); return OPERATOR_FINISHED; }
void BKE_linestyle_default_shader(const bContext *C, FreestyleLineStyle *linestyle) { bNode *uv_along_stroke, *input_texure, *output_linestyle; bNodeSocket *fromsock, *tosock; bNodeTree *ntree; BLI_assert(linestyle->nodetree == NULL); ntree = ntreeAddTree(NULL, "stroke_shader", "ShaderNodeTree"); linestyle->nodetree = ntree; uv_along_stroke = nodeAddStaticNode(C, ntree, SH_NODE_UVALONGSTROKE); uv_along_stroke->locx = 0.0f; uv_along_stroke->locy = 300.0f; uv_along_stroke->custom1 = 0; // use_tips input_texure = nodeAddStaticNode(C, ntree, SH_NODE_TEX_IMAGE); input_texure->locx = 200.0f; input_texure->locy = 300.0f; output_linestyle = nodeAddStaticNode(C, ntree, SH_NODE_OUTPUT_LINESTYLE); output_linestyle->locx = 400.0f; output_linestyle->locy = 300.0f; output_linestyle->custom1 = MA_RAMP_BLEND; output_linestyle->custom2 = 0; // use_clamp nodeSetActive(ntree, input_texure); fromsock = BLI_findlink(&uv_along_stroke->outputs, 0); // UV tosock = BLI_findlink(&input_texure->inputs, 0); // UV nodeAddLink(ntree, uv_along_stroke, fromsock, input_texure, tosock); fromsock = BLI_findlink(&input_texure->outputs, 0); // Color tosock = BLI_findlink(&output_linestyle->inputs, 0); // Color nodeAddLink(ntree, input_texure, fromsock, output_linestyle, tosock); ntreeUpdateTree(CTX_data_main(C), ntree); }
/* add new node connected to this socket, or replace an existing one */ static void node_socket_add_replace(const bContext *C, bNodeTree *ntree, bNode *node_to, bNodeSocket *sock_to, int type, NodeLinkItem *item) { bNode *node_from; bNodeSocket *sock_from_tmp; bNode *node_prev = NULL; /* unlink existing node */ if (sock_to->link) { node_prev = sock_to->link->fromnode; nodeRemLink(ntree, sock_to->link); } /* find existing node that we can use */ for (node_from = ntree->nodes.first; node_from; node_from = node_from->next) if (node_from->type == type) break; if (node_from) if (node_from->inputs.first || node_from->typeinfo->draw_buttons || node_from->typeinfo->draw_buttons_ex) node_from = NULL; if (node_prev && node_prev->type == type && node_link_item_compare(node_prev, item)) { /* keep the previous node if it's the same type */ node_from = node_prev; } else if (!node_from) { node_from = nodeAddStaticNode(C, ntree, type); if (node_prev != NULL) { /* If we're replacing existing node, use it's location. */ node_from->locx = node_prev->locx; node_from->locy = node_prev->locy; node_from->offsetx = node_prev->offsetx; node_from->offsety = node_prev->offsety; } else { /* Avoid exact intersection of nodes. * TODO(sergey): Still not ideal, but better than nothing. */ int index = BLI_findindex(&node_to->inputs, sock_to); BLI_assert(index != -1); node_from->locx = node_to->locx - (node_from->typeinfo->width + 50); node_from->locy = node_to->locy - (node_from->typeinfo->height * index); } node_link_item_apply(node_from, item); } nodeSetActive(ntree, node_from); /* add link */ sock_from_tmp = BLI_findlink(&node_from->outputs, item->socket_index); nodeAddLink(ntree, node_from, sock_from_tmp, node_to, sock_to); sock_to->flag &= ~SOCK_COLLAPSED; /* copy input sockets from previous node */ if (node_prev && node_from != node_prev) { bNodeSocket *sock_prev, *sock_from; for (sock_prev = node_prev->inputs.first; sock_prev; sock_prev = sock_prev->next) { for (sock_from = node_from->inputs.first; sock_from; sock_from = sock_from->next) { if (nodeCountSocketLinks(ntree, sock_from) >= sock_from->limit) continue; if (STREQ(sock_prev->name, sock_from->name) && sock_prev->type == sock_from->type) { bNodeLink *link = sock_prev->link; if (link && link->fromnode) { nodeAddLink(ntree, link->fromnode, link->fromsock, node_from, sock_from); nodeRemLink(ntree, link); } node_socket_copy_default_value(sock_from, sock_prev); } } } /* also preserve mapping for texture nodes */ if (node_from->typeinfo->nclass == NODE_CLASS_TEXTURE && node_prev->typeinfo->nclass == NODE_CLASS_TEXTURE) { memcpy(node_from->storage, node_prev->storage, sizeof(NodeTexBase)); } /* remove node */ node_remove_linked(ntree, node_prev); } nodeUpdate(ntree, node_from); nodeUpdate(ntree, node_to); ntreeUpdateTree(CTX_data_main(C), ntree); ED_node_tag_update_nodetree(CTX_data_main(C), ntree); }
/* add new node connected to this socket, or replace an existing one */ static void node_socket_add_replace(Main *bmain, bNodeTree *ntree, bNode *node_to, bNodeSocket *sock_to, bNodeTemplate *ntemp, int sock_num) { bNode *node_from; bNodeSocket *sock_from; bNode *node_prev = NULL; /* unlink existing node */ if (sock_to->link) { node_prev = sock_to->link->fromnode; nodeRemLink(ntree, sock_to->link); } /* find existing node that we can use */ for (node_from=ntree->nodes.first; node_from; node_from=node_from->next) if (node_from->type == ntemp->type) break; if (node_from) if (!(node_from->inputs.first == NULL && !(node_from->typeinfo->flag & NODE_OPTIONS))) node_from = NULL; if (node_prev && node_prev->type == ntemp->type && (ntemp->type != NODE_GROUP || node_prev->id == &ntemp->ngroup->id)) { /* keep the previous node if it's the same type */ node_from = node_prev; } else if (!node_from) { node_from= nodeAddNode(ntree, ntemp); node_from->locx = node_to->locx - (node_from->typeinfo->width + 50); node_from->locy = node_to->locy; if (node_from->id) id_us_plus(node_from->id); } nodeSetActive(ntree, node_from); /* add link */ sock_from = BLI_findlink(&node_from->outputs, sock_num); nodeAddLink(ntree, node_from, sock_from, node_to, sock_to); /* copy input sockets from previous node */ if (node_prev && node_from != node_prev) { bNodeSocket *sock_prev, *sock_from; for (sock_prev=node_prev->inputs.first; sock_prev; sock_prev=sock_prev->next) { for (sock_from=node_from->inputs.first; sock_from; sock_from=sock_from->next) { if (nodeCountSocketLinks(ntree, sock_from) >= sock_from->limit) continue; if (strcmp(sock_prev->name, sock_from->name) == 0 && sock_prev->type == sock_from->type) { bNodeLink *link = sock_prev->link; if (link && link->fromnode) { nodeAddLink(ntree, link->fromnode, link->fromsock, node_from, sock_from); nodeRemLink(ntree, link); } node_socket_free_default_value(sock_from->type, sock_from->default_value); sock_from->default_value = node_socket_make_default_value(sock_from->type); node_socket_copy_default_value(sock_from->type, sock_from->default_value, sock_prev->default_value); } } } /* also preserve mapping for texture nodes */ if (node_from->typeinfo->nclass == NODE_CLASS_TEXTURE && node_prev->typeinfo->nclass == NODE_CLASS_TEXTURE) { memcpy(node_from->storage, node_prev->storage, sizeof(NodeTexBase)); } /* remove node */ node_remove_linked(ntree, node_prev); } nodeUpdate(ntree, node_from); nodeUpdate(ntree, node_to); ntreeUpdateTree(ntree); ED_node_generic_update(bmain, ntree, node_to); }