static void rna_ColorRamp_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr) { if (ptr->id.data) { ID *id = ptr->id.data; switch (GS(id->name)) { case ID_MA: { Material *ma = ptr->id.data; DAG_id_tag_update(&ma->id, 0); WM_main_add_notifier(NC_MATERIAL | ND_SHADING_DRAW, ma); break; } case ID_NT: { bNodeTree *ntree = (bNodeTree *)id; bNode *node; for (node = ntree->nodes.first; node; node = node->next) { if (ELEM(node->type, SH_NODE_VALTORGB, CMP_NODE_VALTORGB, TEX_NODE_VALTORGB)) { ED_node_tag_update_nodetree(bmain, ntree, node); } } break; } case ID_TE: { Tex *tex = ptr->id.data; DAG_id_tag_update(&tex->id, 0); WM_main_add_notifier(NC_TEXTURE, tex); break; } case ID_LS: { FreestyleLineStyle *linestyle = ptr->id.data; WM_main_add_notifier(NC_LINESTYLE, linestyle); break; } case ID_PA: { ParticleSettings *part = ptr->id.data; DAG_id_tag_update(&part->id, OB_RECALC_DATA | PSYS_RECALC_REDO); WM_main_add_notifier(NC_OBJECT | ND_PARTICLE | NA_EDITED, part); } default: break; } } }
/* remove all nodes connected to this socket, if they aren't connected to other nodes */ static void node_socket_remove(Main *bmain, bNodeTree *ntree, bNode *node_to, bNodeSocket *sock_to) { if (!sock_to->link) return; node_remove_linked(ntree, sock_to->link->fromnode); sock_to->flag |= SOCK_COLLAPSED; nodeUpdate(ntree, node_to); ntreeUpdateTree(bmain, ntree); ED_node_tag_update_nodetree(bmain, ntree); }
/* disconnect socket from the node it is connected to */ static void node_socket_disconnect(Main *bmain, bNodeTree *ntree, bNode *node_to, bNodeSocket *sock_to) { if (!sock_to->link) return; nodeRemLink(ntree, sock_to->link); sock_to->flag |= SOCK_COLLAPSED; nodeUpdate(ntree, node_to); ntreeUpdateTree(bmain, ntree); ED_node_tag_update_nodetree(bmain, ntree); }
static void rna_ImageUser_update(Main *bmain, Scene *scene, PointerRNA *ptr) { ImageUser *iuser = ptr->data; ID *id = ptr->id.data; BKE_image_user_frame_calc(iuser, scene->r.cfra); if (id) { if (GS(id->name) == ID_NT) { /* Special update for nodetrees to find parent datablock. */ ED_node_tag_update_nodetree(bmain, (bNodeTree *)id, NULL); } else { /* Update material or texture for render preview. */ DEG_id_tag_update(id, 0); DEG_id_tag_update(id, ID_RECALC_EDITORS); } } }
/* 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); }
/* /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// */ static void get_material_startjob(void *customdata, short *stop, short *do_update, float *progress) { Main *bmain; bContext *C; bNodeTree *ntree; MatItem *items; uint32_t buf_size; GetMaterialJob *mj = customdata; mj->stop = stop; mj->do_update = do_update; mj->progress = progress; ntree = mj->ntree; bmain = mj->bmain; C = mj->C; *progress = 0.1f; items = mat_livedb_get_material(mj->address, mj->mat_id, &buf_size); *progress = 0.9f; if(items) { bNode *node, *next; MatItem *cur_item = items; bNode *node_to; bNodeSocket *sock_to; char file_path[FILE_MAX]; float cur_y_pos = 0; /* Remove all existing nodes */ ED_preview_kill_jobs(CTX_wm_manager(C), bmain); for (node = ntree->nodes.first; node; node = next) { next = node->next; /* check id user here, nodeFreeNode is called for free dbase too */ if (node->id) node->id->us--; nodeFreeNode(ntree, node); } ntreeUpdateTree(bmain, ntree); node_to = nodeAddNode(C, ntree, "ShaderNodeOutputMaterial"); node_to->locx = 0; node_to->locy = 0; for (sock_to = node_to->inputs.first; sock_to; sock_to = sock_to->next) { if(!sock_to || strcmp(sock_to->name, "Surface")) continue; break; } /* create file path */ if(!strlen(G.main->name)) { char *cur_path = (char*)BKE_appdir_folder_id_create(BLENDER_USER_DATAFILES, 0); strcpy(file_path, cur_path); strcat(file_path, "/livedb/"); } else { BLI_strncpy(file_path, "//livedb/", sizeof(file_path)); BLI_path_abs(file_path, G.main->name); } strcat(file_path, mj->address); strcat(file_path, "/textures/"); BLI_path_native_slash(file_path); BLI_dir_create_recursive(file_path); mat_livedb_add_mat_element(bmain, C, ntree, node_to, sock_to, &cur_item, file_path, 0, &cur_y_pos); ED_node_tree_update(C); ED_node_tag_update_nodetree(bmain, ntree, 0); MEM_freeN(items); } *do_update = 1; *stop = 0; *progress = 1.0f; return; } /* get_material_job() */