Tex *copy_texture(Tex *tex) { Tex *texn; texn= copy_libblock(tex); if(texn->type==TEX_IMAGE) id_us_plus((ID *)texn->ima); else texn->ima= NULL; if(texn->plugin) { texn->plugin= MEM_dupallocN(texn->plugin); open_plugin_tex(texn->plugin); } if(texn->coba) texn->coba= MEM_dupallocN(texn->coba); if(texn->env) texn->env= BKE_copy_envmap(texn->env); if(texn->pd) texn->pd= BKE_copy_pointdensity(texn->pd); if(texn->vd) texn->vd= MEM_dupallocN(texn->vd); if(tex->preview) texn->preview = BKE_previewimg_copy(tex->preview); if(tex->nodetree) { if (tex->nodetree->execdata) { ntreeTexEndExecTree(tex->nodetree->execdata); } texn->nodetree= ntreeCopyTree(tex->nodetree); } return texn; }
World *BKE_world_copy(World *wrld) { World *wrldn; int a; wrldn = BKE_libblock_copy(&wrld->id); for (a = 0; a < MAX_MTEX; a++) { if (wrld->mtex[a]) { wrldn->mtex[a] = MEM_mallocN(sizeof(MTex), "BKE_world_copy"); memcpy(wrldn->mtex[a], wrld->mtex[a], sizeof(MTex)); id_us_plus((ID *)wrldn->mtex[a]->tex); } } if (wrld->nodetree) { wrldn->nodetree = ntreeCopyTree(wrld->nodetree); } if (wrld->preview) wrldn->preview = BKE_previewimg_copy(wrld->preview); BLI_listbase_clear(&wrldn->gpumaterial); if (wrld->id.lib) { BKE_id_lib_local_paths(G.main, wrld->id.lib, &wrldn->id); } return wrldn; }
Lamp *BKE_lamp_copy(Lamp *la) { Lamp *lan; int a; lan = BKE_libblock_copy(&la->id); for (a = 0; a < MAX_MTEX; a++) { if (lan->mtex[a]) { lan->mtex[a] = MEM_mallocN(sizeof(MTex), "copylamptex"); memcpy(lan->mtex[a], la->mtex[a], sizeof(MTex)); id_us_plus((ID *)lan->mtex[a]->tex); } } lan->curfalloff = curvemapping_copy(la->curfalloff); if (la->nodetree) lan->nodetree = ntreeCopyTree(la->nodetree); if (la->preview) lan->preview = BKE_previewimg_copy(la->preview); return lan; }
/* XXX keep synced with next function */ Material *copy_material(Material *ma) { Material *man; int a; man= copy_libblock(ma); id_lib_extern((ID *)man->group); for(a=0; a<MAX_MTEX; a++) { if(ma->mtex[a]) { man->mtex[a]= MEM_mallocN(sizeof(MTex), "copymaterial"); memcpy(man->mtex[a], ma->mtex[a], sizeof(MTex)); id_us_plus((ID *)man->mtex[a]->tex); } } if(ma->ramp_col) man->ramp_col= MEM_dupallocN(ma->ramp_col); if(ma->ramp_spec) man->ramp_spec= MEM_dupallocN(ma->ramp_spec); if (ma->preview) man->preview = BKE_previewimg_copy(ma->preview); if(ma->nodetree) { man->nodetree= ntreeCopyTree(ma->nodetree); /* 0 == full new tree */ } man->gpumaterial.first= man->gpumaterial.last= NULL; return man; }
Tex *BKE_texture_copy(Tex *tex) { Tex *texn; texn = BKE_libblock_copy(&tex->id); if (texn->type == TEX_IMAGE) id_us_plus((ID *)texn->ima); else texn->ima = NULL; if (texn->coba) texn->coba = MEM_dupallocN(texn->coba); if (texn->env) texn->env = BKE_copy_envmap(texn->env); if (texn->pd) texn->pd = BKE_copy_pointdensity(texn->pd); if (texn->vd) texn->vd = MEM_dupallocN(texn->vd); if (texn->ot) texn->ot = BKE_copy_oceantex(texn->ot); if (tex->preview) texn->preview = BKE_previewimg_copy(tex->preview); if (tex->nodetree) { if (tex->nodetree->execdata) { ntreeTexEndExecTree(tex->nodetree->execdata); } texn->nodetree = ntreeCopyTree(tex->nodetree); } return texn; }
World *BKE_world_copy(World *wrld) { World *wrldn; int a; wrldn = BKE_libblock_copy(&wrld->id); for (a = 0; a < MAX_MTEX; a++) { if (wrld->mtex[a]) { wrldn->mtex[a] = MEM_mallocN(sizeof(MTex), "BKE_world_copy"); memcpy(wrldn->mtex[a], wrld->mtex[a], sizeof(MTex)); id_us_plus((ID *)wrldn->mtex[a]->tex); } } if (wrld->nodetree) { wrldn->nodetree = ntreeCopyTree(wrld->nodetree); } if (wrld->preview) wrldn->preview = BKE_previewimg_copy(wrld->preview); return wrldn; }
int id_copy(ID *id, ID **newid, int test) { if(!test) *newid= NULL; /* conventions: * - make shallow copy, only this ID block * - id.us of the new ID is set to 1 */ switch(GS(id->name)) { case ID_SCE: return 0; /* can't be copied from here */ case ID_LI: return 0; /* can't be copied from here */ case ID_OB: if(!test) *newid= (ID*)copy_object((Object*)id); return 1; case ID_ME: if(!test) *newid= (ID*)copy_mesh((Mesh*)id); return 1; case ID_CU: if(!test) *newid= (ID*)copy_curve((Curve*)id); return 1; case ID_MB: if(!test) *newid= (ID*)copy_mball((MetaBall*)id); return 1; case ID_MA: if(!test) *newid= (ID*)copy_material((Material*)id); return 1; case ID_TE: if(!test) *newid= (ID*)copy_texture((Tex*)id); return 1; case ID_IM: if(!test) *newid= (ID*)copy_image((Image*)id); return 1; case ID_LT: if(!test) *newid= (ID*)copy_lattice((Lattice*)id); return 1; case ID_LA: if(!test) *newid= (ID*)copy_lamp((Lamp*)id); return 1; case ID_SPK: if(!test) *newid= (ID*)copy_speaker((Speaker*)id); return 1; case ID_CA: if(!test) *newid= (ID*)copy_camera((Camera*)id); return 1; case ID_IP: return 0; /* deprecated */ case ID_KE: if(!test) *newid= (ID*)copy_key((Key*)id); return 1; case ID_WO: if(!test) *newid= (ID*)copy_world((World*)id); return 1; case ID_SCR: return 0; /* can't be copied from here */ case ID_VF: return 0; /* not implemented */ case ID_TXT: if(!test) *newid= (ID*)copy_text((Text*)id); return 1; case ID_SCRIPT: return 0; /* deprecated */ case ID_SO: return 0; /* not implemented */ case ID_GR: if(!test) *newid= (ID*)copy_group((Group*)id); return 1; case ID_AR: if(!test) *newid= (ID*)copy_armature((bArmature*)id); return 1; case ID_AC: if(!test) *newid= (ID*)copy_action((bAction*)id); return 1; case ID_NT: if(!test) *newid= (ID*)ntreeCopyTree((bNodeTree*)id); return 1; case ID_BR: if(!test) *newid= (ID*)copy_brush((Brush*)id); return 1; case ID_PA: if(!test) *newid= (ID*)psys_copy_settings((ParticleSettings*)id); return 1; case ID_WM: return 0; /* can't be copied from here */ case ID_GD: return 0; /* not implemented */ } return 0; }
/** * Invokes the appropriate copy method for the block and returns the result in * newid, unless test. Returns true iff the block can be copied. */ bool id_copy(ID *id, ID **newid, bool test) { if (!test) *newid = NULL; /* conventions: * - make shallow copy, only this ID block * - id.us of the new ID is set to 1 */ switch (GS(id->name)) { case ID_SCE: return false; /* can't be copied from here */ case ID_LI: return false; /* can't be copied from here */ case ID_OB: if (!test) *newid = (ID *)BKE_object_copy((Object *)id); return true; case ID_ME: if (!test) *newid = (ID *)BKE_mesh_copy((Mesh *)id); return true; case ID_CU: if (!test) *newid = (ID *)BKE_curve_copy((Curve *)id); return true; case ID_MB: if (!test) *newid = (ID *)BKE_mball_copy((MetaBall *)id); return true; case ID_MA: if (!test) *newid = (ID *)BKE_material_copy((Material *)id); return true; case ID_TE: if (!test) *newid = (ID *)BKE_texture_copy((Tex *)id); return true; case ID_IM: if (!test) *newid = (ID *)BKE_image_copy(G.main, (Image *)id); return true; case ID_LT: if (!test) *newid = (ID *)BKE_lattice_copy((Lattice *)id); return true; case ID_LA: if (!test) *newid = (ID *)BKE_lamp_copy((Lamp *)id); return true; case ID_SPK: if (!test) *newid = (ID *)BKE_speaker_copy((Speaker *)id); return true; case ID_CA: if (!test) *newid = (ID *)BKE_camera_copy((Camera *)id); return true; case ID_IP: return false; /* deprecated */ case ID_KE: if (!test) *newid = (ID *)BKE_key_copy((Key *)id); return true; case ID_WO: if (!test) *newid = (ID *)BKE_world_copy((World *)id); return true; case ID_SCR: return false; /* can't be copied from here */ case ID_VF: return false; /* not implemented */ case ID_TXT: if (!test) *newid = (ID *)BKE_text_copy((Text *)id); return true; case ID_SCRIPT: return false; /* deprecated */ case ID_SO: return false; /* not implemented */ case ID_GR: if (!test) *newid = (ID *)BKE_group_copy((Group *)id); return true; case ID_AR: if (!test) *newid = (ID *)BKE_armature_copy((bArmature *)id); return true; case ID_AC: if (!test) *newid = (ID *)BKE_action_copy((bAction *)id); return true; case ID_NT: if (!test) *newid = (ID *)ntreeCopyTree((bNodeTree *)id); return true; case ID_BR: if (!test) *newid = (ID *)BKE_brush_copy((Brush *)id); return true; case ID_PA: if (!test) *newid = (ID *)BKE_particlesettings_copy((ParticleSettings *)id); return true; case ID_WM: return false; /* can't be copied from here */ case ID_GD: return false; /* not implemented */ case ID_MSK: if (!test) *newid = (ID *)BKE_mask_copy((Mask *)id); return true; case ID_LS: if (!test) *newid = (ID *)BKE_copy_linestyle((FreestyleLineStyle *)id); return true; } return false; }
FreestyleLineStyle *BKE_linestyle_copy(struct Main *bmain, FreestyleLineStyle *linestyle) { FreestyleLineStyle *new_linestyle; LineStyleModifier *m; int a; new_linestyle = BKE_linestyle_new(bmain, linestyle->id.name + 2); BKE_linestyle_free(new_linestyle); for (a = 0; a < MAX_MTEX; a++) { if (linestyle->mtex[a]) { new_linestyle->mtex[a] = MEM_mallocN(sizeof(MTex), "BKE_linestyle_copy"); memcpy(new_linestyle->mtex[a], linestyle->mtex[a], sizeof(MTex)); id_us_plus((ID *)new_linestyle->mtex[a]->tex); } } if (linestyle->nodetree) { new_linestyle->nodetree = ntreeCopyTree(bmain, linestyle->nodetree); } new_linestyle->r = linestyle->r; new_linestyle->g = linestyle->g; new_linestyle->b = linestyle->b; new_linestyle->alpha = linestyle->alpha; new_linestyle->thickness = linestyle->thickness; new_linestyle->thickness_position = linestyle->thickness_position; new_linestyle->thickness_ratio = linestyle->thickness_ratio; new_linestyle->flag = linestyle->flag; new_linestyle->caps = linestyle->caps; new_linestyle->chaining = linestyle->chaining; new_linestyle->rounds = linestyle->rounds; new_linestyle->split_length = linestyle->split_length; new_linestyle->min_angle = linestyle->min_angle; new_linestyle->max_angle = linestyle->max_angle; new_linestyle->min_length = linestyle->min_length; new_linestyle->max_length = linestyle->max_length; new_linestyle->chain_count = linestyle->chain_count; new_linestyle->split_dash1 = linestyle->split_dash1; new_linestyle->split_gap1 = linestyle->split_gap1; new_linestyle->split_dash2 = linestyle->split_dash2; new_linestyle->split_gap2 = linestyle->split_gap2; new_linestyle->split_dash3 = linestyle->split_dash3; new_linestyle->split_gap3 = linestyle->split_gap3; new_linestyle->dash1 = linestyle->dash1; new_linestyle->gap1 = linestyle->gap1; new_linestyle->dash2 = linestyle->dash2; new_linestyle->gap2 = linestyle->gap2; new_linestyle->dash3 = linestyle->dash3; new_linestyle->gap3 = linestyle->gap3; new_linestyle->panel = linestyle->panel; new_linestyle->sort_key = linestyle->sort_key; new_linestyle->integration_type = linestyle->integration_type; new_linestyle->texstep = linestyle->texstep; new_linestyle->pr_texture = linestyle->pr_texture; new_linestyle->use_nodes = linestyle->use_nodes; for (m = (LineStyleModifier *)linestyle->color_modifiers.first; m; m = m->next) BKE_linestyle_color_modifier_copy(new_linestyle, m); for (m = (LineStyleModifier *)linestyle->alpha_modifiers.first; m; m = m->next) BKE_linestyle_alpha_modifier_copy(new_linestyle, m); for (m = (LineStyleModifier *)linestyle->thickness_modifiers.first; m; m = m->next) BKE_linestyle_thickness_modifier_copy(new_linestyle, m); for (m = (LineStyleModifier *)linestyle->geometry_modifiers.first; m; m = m->next) BKE_linestyle_geometry_modifier_copy(new_linestyle, m); BKE_id_copy_ensure_local(bmain, &linestyle->id, &new_linestyle->id); return new_linestyle; }
Scene *BKE_scene_copy(Scene *sce, int type) { Scene *scen; ToolSettings *ts; Base *base, *obase; if (type == SCE_COPY_EMPTY) { ListBase lb; /* XXX. main should become an arg */ scen = BKE_scene_add(G.main, sce->id.name + 2); lb = scen->r.layers; scen->r = sce->r; scen->r.layers = lb; scen->unit = sce->unit; scen->physics_settings = sce->physics_settings; scen->gm = sce->gm; scen->audio = sce->audio; MEM_freeN(scen->toolsettings); } else { scen = BKE_libblock_copy(&sce->id); BLI_duplicatelist(&(scen->base), &(sce->base)); clear_id_newpoins(); id_us_plus((ID *)scen->world); id_us_plus((ID *)scen->set); id_us_plus((ID *)scen->gm.dome.warptext); scen->ed = NULL; scen->theDag = NULL; scen->obedit = NULL; scen->stats = NULL; scen->fps_info = NULL; BLI_duplicatelist(&(scen->markers), &(sce->markers)); BLI_duplicatelist(&(scen->transform_spaces), &(sce->transform_spaces)); BLI_duplicatelist(&(scen->r.layers), &(sce->r.layers)); BKE_keyingsets_copy(&(scen->keyingsets), &(sce->keyingsets)); if (sce->nodetree) { /* ID's are managed on both copy and switch */ scen->nodetree = ntreeCopyTree(sce->nodetree); ntreeSwitchID(scen->nodetree, &sce->id, &scen->id); } obase = sce->base.first; base = scen->base.first; while (base) { id_us_plus(&base->object->id); if (obase == sce->basact) scen->basact = base; obase = obase->next; base = base->next; } /* copy color management settings */ BKE_color_managed_display_settings_copy(&scen->display_settings, &sce->display_settings); BKE_color_managed_view_settings_copy(&scen->view_settings, &sce->view_settings); BKE_color_managed_view_settings_copy(&scen->r.im_format.view_settings, &sce->r.im_format.view_settings); BLI_strncpy(scen->sequencer_colorspace_settings.name, sce->sequencer_colorspace_settings.name, sizeof(scen->sequencer_colorspace_settings.name)); /* remove animation used by sequencer */ if (type != SCE_COPY_FULL) remove_sequencer_fcurves(scen); } /* tool settings */ scen->toolsettings = MEM_dupallocN(sce->toolsettings); ts = scen->toolsettings; if (ts) { if (ts->vpaint) { ts->vpaint = MEM_dupallocN(ts->vpaint); ts->vpaint->paintcursor = NULL; ts->vpaint->vpaint_prev = NULL; ts->vpaint->wpaint_prev = NULL; BKE_paint_copy(&ts->vpaint->paint, &ts->vpaint->paint); } if (ts->wpaint) { ts->wpaint = MEM_dupallocN(ts->wpaint); ts->wpaint->paintcursor = NULL; ts->wpaint->vpaint_prev = NULL; ts->wpaint->wpaint_prev = NULL; BKE_paint_copy(&ts->wpaint->paint, &ts->wpaint->paint); } if (ts->sculpt) { ts->sculpt = MEM_dupallocN(ts->sculpt); BKE_paint_copy(&ts->sculpt->paint, &ts->sculpt->paint); } BKE_paint_copy(&ts->imapaint.paint, &ts->imapaint.paint); ts->imapaint.paintcursor = NULL; ts->particle.paintcursor = NULL; } /* make a private copy of the avicodecdata */ if (sce->r.avicodecdata) { scen->r.avicodecdata = MEM_dupallocN(sce->r.avicodecdata); scen->r.avicodecdata->lpFormat = MEM_dupallocN(scen->r.avicodecdata->lpFormat); scen->r.avicodecdata->lpParms = MEM_dupallocN(scen->r.avicodecdata->lpParms); } /* make a private copy of the qtcodecdata */ if (sce->r.qtcodecdata) { scen->r.qtcodecdata = MEM_dupallocN(sce->r.qtcodecdata); scen->r.qtcodecdata->cdParms = MEM_dupallocN(scen->r.qtcodecdata->cdParms); } if (sce->r.ffcodecdata.properties) { /* intentionally check scen not sce. */ scen->r.ffcodecdata.properties = IDP_CopyProperty(sce->r.ffcodecdata.properties); } /* NOTE: part of SCE_COPY_LINK_DATA and SCE_COPY_FULL operations * are done outside of blenkernel with ED_objects_single_users! */ /* camera */ if (type == SCE_COPY_LINK_DATA || type == SCE_COPY_FULL) { ID_NEW(scen->camera); } /* before scene copy */ sound_create_scene(scen); /* world */ if (type == SCE_COPY_FULL) { BKE_copy_animdata_id_action((ID *)scen); if (scen->world) { id_us_plus((ID *)scen->world); scen->world = BKE_world_copy(scen->world); BKE_copy_animdata_id_action((ID *)scen->world); } if (sce->ed) { scen->ed = MEM_callocN(sizeof(Editing), "addseq"); scen->ed->seqbasep = &scen->ed->seqbase; BKE_sequence_base_dupli_recursive(sce, scen, &scen->ed->seqbase, &sce->ed->seqbase, SEQ_DUPE_ALL); } } return scen; }
FreestyleLineStyle *BKE_copy_linestyle(FreestyleLineStyle *linestyle) { FreestyleLineStyle *new_linestyle; LineStyleModifier *m; int a; new_linestyle = BKE_new_linestyle(linestyle->id.name + 2, NULL); BKE_free_linestyle(new_linestyle); for (a = 0; a < MAX_MTEX; a++) { if (linestyle->mtex[a]) { new_linestyle->mtex[a] = MEM_mallocN(sizeof(MTex), "BKE_copy_linestyle"); memcpy(new_linestyle->mtex[a], linestyle->mtex[a], sizeof(MTex)); id_us_plus((ID *)new_linestyle->mtex[a]->tex); } } if (linestyle->nodetree) { linestyle->nodetree = ntreeCopyTree(linestyle->nodetree); } new_linestyle->r = linestyle->r; new_linestyle->g = linestyle->g; new_linestyle->b = linestyle->b; new_linestyle->alpha = linestyle->alpha; new_linestyle->thickness = linestyle->thickness; new_linestyle->thickness_position = linestyle->thickness_position; new_linestyle->thickness_ratio = linestyle->thickness_ratio; new_linestyle->flag = linestyle->flag; new_linestyle->caps = linestyle->caps; new_linestyle->chaining = linestyle->chaining; new_linestyle->rounds = linestyle->rounds; new_linestyle->split_length = linestyle->split_length; new_linestyle->min_angle = linestyle->min_angle; new_linestyle->max_angle = linestyle->max_angle; new_linestyle->min_length = linestyle->min_length; new_linestyle->max_length = linestyle->max_length; new_linestyle->split_dash1 = linestyle->split_dash1; new_linestyle->split_gap1 = linestyle->split_gap1; new_linestyle->split_dash2 = linestyle->split_dash2; new_linestyle->split_gap2 = linestyle->split_gap2; new_linestyle->split_dash3 = linestyle->split_dash3; new_linestyle->split_gap3 = linestyle->split_gap3; new_linestyle->dash1 = linestyle->dash1; new_linestyle->gap1 = linestyle->gap1; new_linestyle->dash2 = linestyle->dash2; new_linestyle->gap2 = linestyle->gap2; new_linestyle->dash3 = linestyle->dash3; new_linestyle->gap3 = linestyle->gap3; new_linestyle->panel = linestyle->panel; new_linestyle->texstep = linestyle->texstep; new_linestyle->pr_texture = linestyle->pr_texture; for (m = (LineStyleModifier *)linestyle->color_modifiers.first; m; m = m->next) BKE_copy_linestyle_color_modifier(new_linestyle, m); for (m = (LineStyleModifier *)linestyle->alpha_modifiers.first; m; m = m->next) BKE_copy_linestyle_alpha_modifier(new_linestyle, m); for (m = (LineStyleModifier *)linestyle->thickness_modifiers.first; m; m = m->next) BKE_copy_linestyle_thickness_modifier(new_linestyle, m); for (m = (LineStyleModifier *)linestyle->geometry_modifiers.first; m; m = m->next) BKE_copy_linestyle_geometry_modifier(new_linestyle, m); return new_linestyle; }
/* 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; }