Blender V2.61 - r43446

library.c

Go to the documentation of this file.
00001 /*
00002  * ***** BEGIN GPL LICENSE BLOCK *****
00003  *
00004  * This program is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU General Public License
00006  * as published by the Free Software Foundation; either version 2
00007  * of the License, or (at your option) any later version.
00008  *
00009  * This program is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program; if not, write to the Free Software Foundation,
00016  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00017  *
00018  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
00019  * All rights reserved.
00020  *
00021  * The Original Code is: all of this file.
00022  *
00023  * Contributor(s): none yet.
00024  *
00025  * ***** END GPL LICENSE BLOCK *****
00026  */
00027 
00033 /*
00034  *  Contains management of ID's and libraries
00035  *  allocate and free of all library data
00036  * 
00037  */
00038 
00039 
00040 #include <stdio.h>
00041 #include <ctype.h>
00042 #include <string.h>
00043 #include <stdlib.h>
00044 #include <stddef.h>
00045 #include <assert.h>
00046 
00047 #include "MEM_guardedalloc.h"
00048 
00049 /* all types are needed here, in order to do memory operations */
00050 #include "DNA_anim_types.h"
00051 #include "DNA_armature_types.h"
00052 #include "DNA_brush_types.h"
00053 #include "DNA_camera_types.h"
00054 #include "DNA_group_types.h"
00055 #include "DNA_ipo_types.h"
00056 #include "DNA_key_types.h"
00057 #include "DNA_lamp_types.h"
00058 #include "DNA_lattice_types.h"
00059 #include "DNA_material_types.h"
00060 #include "DNA_mesh_types.h"
00061 #include "DNA_meta_types.h"
00062 #include "DNA_nla_types.h"
00063 #include "DNA_node_types.h"
00064 #include "DNA_scene_types.h"
00065 #include "DNA_screen_types.h"
00066 #include "DNA_speaker_types.h"
00067 #include "DNA_sound_types.h"
00068 #include "DNA_text_types.h"
00069 #include "DNA_vfont_types.h"
00070 #include "DNA_windowmanager_types.h"
00071 #include "DNA_world_types.h"
00072 #include "DNA_gpencil_types.h"
00073 #include "DNA_movieclip_types.h"
00074 
00075 #include "BLI_blenlib.h"
00076 #include "BLI_dynstr.h"
00077 #include "BLI_utildefines.h"
00078 #include "BLI_bpath.h"
00079 
00080 #include "BKE_animsys.h"
00081 #include "BKE_camera.h"
00082 #include "BKE_context.h"
00083 #include "BKE_lamp.h"
00084 #include "BKE_library.h"
00085 #include "BKE_main.h"
00086 #include "BKE_global.h"
00087 #include "BKE_sound.h"
00088 #include "BKE_object.h"
00089 #include "BKE_screen.h"
00090 #include "BKE_mesh.h"
00091 #include "BKE_material.h"
00092 #include "BKE_curve.h"
00093 #include "BKE_mball.h"
00094 #include "BKE_text.h"
00095 #include "BKE_texture.h"
00096 #include "BKE_scene.h"
00097 #include "BKE_icons.h"
00098 #include "BKE_image.h"
00099 #include "BKE_ipo.h"
00100 #include "BKE_key.h"
00101 #include "BKE_world.h"
00102 #include "BKE_font.h"
00103 #include "BKE_group.h"
00104 #include "BKE_lattice.h"
00105 #include "BKE_armature.h"
00106 #include "BKE_action.h"
00107 #include "BKE_node.h"
00108 #include "BKE_brush.h"
00109 #include "BKE_idprop.h"
00110 #include "BKE_particle.h"
00111 #include "BKE_gpencil.h"
00112 #include "BKE_fcurve.h"
00113 #include "BKE_speaker.h"
00114 #include "BKE_utildefines.h"
00115 #include "BKE_movieclip.h"
00116 
00117 #include "RNA_access.h"
00118 
00119 #ifdef WITH_PYTHON
00120 #include "BPY_extern.h"
00121 #endif
00122 
00123 #define MAX_IDPUP       60  /* was 24 */
00124 
00125 /* GS reads the memory pointed at in a specific ordering. 
00126    only use this definition, makes little and big endian systems
00127    work fine, in conjunction with MAKE_ID */
00128 
00129 /* from blendef: */
00130 #define GS(a)   (*((short *)(a)))
00131 
00132 /* ************* general ************************ */
00133 
00134 
00135 /* this has to be called from each make_local_* func, we could call
00136  * from id_make_local() but then the make local functions would not be self
00137  * contained.
00138  * also note that the id _must_ have a library - campbell */
00139 void BKE_id_lib_local_paths(Main *bmain, Library *lib, ID *id)
00140 {
00141     char *bpath_user_data[2]= {bmain->name, lib->filepath};
00142 
00143     bpath_traverse_id(bmain, id,
00144                       bpath_relocate_visitor,
00145                       BPATH_TRAVERSE_SKIP_MULTIFILE,
00146                       bpath_user_data);
00147 }
00148 
00149 void id_lib_extern(ID *id)
00150 {
00151     if(id) {
00152         if(id->flag & LIB_INDIRECT) {
00153             id->flag -= LIB_INDIRECT;
00154             id->flag |= LIB_EXTERN;
00155         }
00156     }
00157 }
00158 
00159 void id_us_plus(ID *id)
00160 {
00161     if(id) {
00162         id->us++;
00163         if(id->flag & LIB_INDIRECT) {
00164             id->flag -= LIB_INDIRECT;
00165             id->flag |= LIB_EXTERN;
00166         }
00167     }
00168 }
00169 
00170 void id_us_min(ID *id)
00171 {
00172     if(id) {
00173         if(id->us<2 && (id->flag & LIB_FAKEUSER))
00174            id->us= 1;
00175         else if(id->us<=0)
00176             printf("ID user decrement error: %s \n", id->name);
00177         else
00178             id->us--;
00179     }
00180 }
00181 
00182 int id_make_local(ID *id, int test)
00183 {
00184     if(id->flag & LIB_INDIRECT)
00185         return 0;
00186 
00187     switch(GS(id->name)) {
00188         case ID_SCE:
00189             return 0; /* not implemented */
00190         case ID_LI:
00191             return 0; /* can't be linked */
00192         case ID_OB:
00193             if(!test) make_local_object((Object*)id);
00194             return 1;
00195         case ID_ME:
00196             if(!test) {
00197                 make_local_mesh((Mesh*)id);
00198                 make_local_key(((Mesh*)id)->key);
00199             }
00200             return 1;
00201         case ID_CU:
00202             if(!test) {
00203                 make_local_curve((Curve*)id);
00204                 make_local_key(((Curve*)id)->key);
00205             }
00206             return 1;
00207         case ID_MB:
00208             if(!test) make_local_mball((MetaBall*)id);
00209             return 1;
00210         case ID_MA:
00211             if(!test) make_local_material((Material*)id);
00212             return 1;
00213         case ID_TE:
00214             if(!test) make_local_texture((Tex*)id);
00215             return 1;
00216         case ID_IM:
00217             if(!test) make_local_image((Image*)id);
00218             return 1;
00219         case ID_LT:
00220             if(!test) {
00221                 make_local_lattice((Lattice*)id);
00222                 make_local_key(((Lattice*)id)->key);
00223             }
00224             return 1;
00225         case ID_LA:
00226             if(!test) make_local_lamp((Lamp*)id);
00227             return 1;
00228         case ID_CA:
00229             if(!test) make_local_camera((Camera*)id);
00230             return 1;
00231         case ID_SPK:
00232             if(!test) make_local_speaker((Speaker*)id);
00233             return 1;
00234         case ID_IP:
00235             return 0; /* deprecated */
00236         case ID_KE:
00237             if(!test) make_local_key((Key*)id);
00238             return 1;
00239         case ID_WO:
00240             if(!test) make_local_world((World*)id);
00241             return 1;
00242         case ID_SCR:
00243             return 0; /* can't be linked */
00244         case ID_VF:
00245             return 0; /* not implemented */
00246         case ID_TXT:
00247             return 0; /* not implemented */
00248         case ID_SCRIPT:
00249             return 0; /* deprecated */
00250         case ID_SO:
00251             return 0; /* not implemented */
00252         case ID_GR:
00253             return 0; /* not implemented */
00254         case ID_AR:
00255             if(!test) make_local_armature((bArmature*)id);
00256             return 1;
00257         case ID_AC:
00258             if(!test) make_local_action((bAction*)id);
00259             return 1;
00260         case ID_NT:
00261             return 0; /* not implemented */
00262         case ID_BR:
00263             if(!test) make_local_brush((Brush*)id);
00264             return 1;
00265         case ID_PA:
00266             if(!test) make_local_particlesettings((ParticleSettings*)id);
00267             return 1;
00268         case ID_WM:
00269             return 0; /* can't be linked */
00270         case ID_GD:
00271             return 0; /* not implemented */
00272     }
00273 
00274     return 0;
00275 }
00276 
00277 int id_copy(ID *id, ID **newid, int test)
00278 {
00279     if(!test) *newid= NULL;
00280 
00281     /* conventions:
00282      * - make shallow copy, only this ID block
00283      * - id.us of the new ID is set to 1 */
00284     switch(GS(id->name)) {
00285         case ID_SCE:
00286             return 0; /* can't be copied from here */
00287         case ID_LI:
00288             return 0; /* can't be copied from here */
00289         case ID_OB:
00290             if(!test) *newid= (ID*)copy_object((Object*)id);
00291             return 1;
00292         case ID_ME:
00293             if(!test) *newid= (ID*)copy_mesh((Mesh*)id);
00294             return 1;
00295         case ID_CU:
00296             if(!test) *newid= (ID*)copy_curve((Curve*)id);
00297             return 1;
00298         case ID_MB:
00299             if(!test) *newid= (ID*)copy_mball((MetaBall*)id);
00300             return 1;
00301         case ID_MA:
00302             if(!test) *newid= (ID*)copy_material((Material*)id);
00303             return 1;
00304         case ID_TE:
00305             if(!test) *newid= (ID*)copy_texture((Tex*)id);
00306             return 1;
00307         case ID_IM:
00308             if(!test) *newid= (ID*)copy_image((Image*)id);
00309             return 1;
00310         case ID_LT:
00311             if(!test) *newid= (ID*)copy_lattice((Lattice*)id);
00312             return 1;
00313         case ID_LA:
00314             if(!test) *newid= (ID*)copy_lamp((Lamp*)id);
00315             return 1;
00316         case ID_SPK:
00317             if(!test) *newid= (ID*)copy_speaker((Speaker*)id);
00318             return 1;
00319         case ID_CA:
00320             if(!test) *newid= (ID*)copy_camera((Camera*)id);
00321             return 1;
00322         case ID_IP:
00323             return 0; /* deprecated */
00324         case ID_KE:
00325             if(!test) *newid= (ID*)copy_key((Key*)id);
00326             return 1;
00327         case ID_WO:
00328             if(!test) *newid= (ID*)copy_world((World*)id);
00329             return 1;
00330         case ID_SCR:
00331             return 0; /* can't be copied from here */
00332         case ID_VF:
00333             return 0; /* not implemented */
00334         case ID_TXT:
00335             if(!test) *newid= (ID*)copy_text((Text*)id);
00336             return 1;
00337         case ID_SCRIPT:
00338             return 0; /* deprecated */
00339         case ID_SO:
00340             return 0; /* not implemented */
00341         case ID_GR:
00342             if(!test) *newid= (ID*)copy_group((Group*)id);
00343             return 1;
00344         case ID_AR:
00345             if(!test) *newid= (ID*)copy_armature((bArmature*)id);
00346             return 1;
00347         case ID_AC:
00348             if(!test) *newid= (ID*)copy_action((bAction*)id);
00349             return 1;
00350         case ID_NT:
00351             if(!test) *newid= (ID*)ntreeCopyTree((bNodeTree*)id);
00352             return 1;
00353         case ID_BR:
00354             if(!test) *newid= (ID*)copy_brush((Brush*)id);
00355             return 1;
00356         case ID_PA:
00357             if(!test) *newid= (ID*)psys_copy_settings((ParticleSettings*)id);
00358             return 1;
00359         case ID_WM:
00360             return 0; /* can't be copied from here */
00361         case ID_GD:
00362             return 0; /* not implemented */
00363     }
00364     
00365     return 0;
00366 }
00367 
00368 int id_unlink(ID *id, int test)
00369 {
00370     Main *mainlib= G.main;
00371     ListBase *lb;
00372 
00373     switch(GS(id->name)) {
00374         case ID_TXT:
00375             if(test) return 1;
00376             unlink_text(mainlib, (Text*)id);
00377             break;
00378         case ID_GR:
00379             if(test) return 1;
00380             unlink_group((Group*)id);
00381             break;
00382         case ID_OB:
00383             if(test) return 1;
00384             unlink_object((Object*)id);
00385             break;
00386     }
00387 
00388     if(id->us == 0) {
00389         if(test) return 1;
00390 
00391         lb= which_libbase(mainlib, GS(id->name));
00392         free_libblock(lb, id);
00393 
00394         return 1;
00395     }
00396 
00397     return 0;
00398 }
00399 
00400 int id_single_user(bContext *C, ID *id, PointerRNA *ptr, PropertyRNA *prop)
00401 {
00402     ID *newid = NULL;
00403     PointerRNA idptr;
00404     
00405     if (id) {
00406         /* if property isn't editable, we're going to have an extra block hanging around until we save */
00407         if (RNA_property_editable(ptr, prop)) {
00408             if (id_copy(id, &newid, 0) && newid) {
00409                 /* copy animation actions too */
00410                 BKE_copy_animdata_id_action(id);
00411                 /* us is 1 by convention, but RNA_property_pointer_set
00412                    will also incremement it, so set it to zero */
00413                 newid->us= 0;
00414                 
00415                 /* assign copy */
00416                 RNA_id_pointer_create(newid, &idptr);
00417                 RNA_property_pointer_set(ptr, prop, idptr);
00418                 RNA_property_update(C, ptr, prop);
00419                 
00420                 return 1;
00421             }
00422         }
00423     }
00424     
00425     return 0;
00426 }
00427 
00428 ListBase *which_libbase(Main *mainlib, short type)
00429 {
00430     switch( type ) {
00431         case ID_SCE:
00432             return &(mainlib->scene);
00433         case ID_LI:
00434             return &(mainlib->library);
00435         case ID_OB:
00436             return &(mainlib->object);
00437         case ID_ME:
00438             return &(mainlib->mesh);
00439         case ID_CU:
00440             return &(mainlib->curve);
00441         case ID_MB:
00442             return &(mainlib->mball);
00443         case ID_MA:
00444             return &(mainlib->mat);
00445         case ID_TE:
00446             return &(mainlib->tex);
00447         case ID_IM:
00448             return &(mainlib->image);
00449         case ID_LT:
00450             return &(mainlib->latt);
00451         case ID_LA:
00452             return &(mainlib->lamp);
00453         case ID_CA:
00454             return &(mainlib->camera);
00455         case ID_IP:
00456             return &(mainlib->ipo);
00457         case ID_KE:
00458             return &(mainlib->key);
00459         case ID_WO:
00460             return &(mainlib->world);
00461         case ID_SCR:
00462             return &(mainlib->screen);
00463         case ID_VF:
00464             return &(mainlib->vfont);
00465         case ID_TXT:
00466             return &(mainlib->text);
00467         case ID_SCRIPT:
00468             return &(mainlib->script);
00469         case ID_SPK:
00470             return &(mainlib->speaker);
00471         case ID_SO:
00472             return &(mainlib->sound);
00473         case ID_GR:
00474             return &(mainlib->group);
00475         case ID_AR:
00476             return &(mainlib->armature);
00477         case ID_AC:
00478             return &(mainlib->action);
00479         case ID_NT:
00480             return &(mainlib->nodetree);
00481         case ID_BR:
00482             return &(mainlib->brush);
00483         case ID_PA:
00484             return &(mainlib->particle);
00485         case ID_WM:
00486             return &(mainlib->wm);
00487         case ID_GD:
00488             return &(mainlib->gpencil);
00489         case ID_MC:
00490             return &(mainlib->movieclip);
00491     }
00492     return NULL;
00493 }
00494 
00495 /* Flag all ids in listbase */
00496 void flag_listbase_ids(ListBase *lb, short flag, short value)
00497 {
00498     ID *id;
00499     if (value) {
00500         for(id= lb->first; id; id= id->next) id->flag |= flag;
00501     } else {
00502         flag = ~flag;
00503         for(id= lb->first; id; id= id->next) id->flag &= flag;
00504     }
00505 }
00506 
00507 /* Flag all ids in listbase */
00508 void flag_all_listbases_ids(short flag, short value)
00509 {
00510     ListBase *lbarray[MAX_LIBARRAY];
00511     int a;
00512     a= set_listbasepointers(G.main, lbarray);
00513     while(a--)  flag_listbase_ids(lbarray[a], flag, value);
00514 }
00515 
00516 void recalc_all_library_objects(Main *main)
00517 {
00518     Object *ob;
00519 
00520     /* flag for full recalc */
00521     for(ob=main->object.first; ob; ob=ob->id.next)
00522         if(ob->id.lib)
00523             ob->recalc |= OB_RECALC_OB|OB_RECALC_DATA|OB_RECALC_TIME;
00524 }
00525 
00526 /* note: MAX_LIBARRAY define should match this code */
00527 int set_listbasepointers(Main *main, ListBase **lb)
00528 {
00529     int a = 0;
00530 
00531     /* BACKWARDS! also watch order of free-ing! (mesh<->mat), first items freed last.
00532      * This is important because freeing data decreases usercounts of other datablocks,
00533      * if this data is its self freed it can crash. */
00534     lb[a++]= &(main->ipo);
00535     lb[a++]= &(main->action); // xxx moved here to avoid problems when freeing with animato (aligorith)
00536     lb[a++]= &(main->key);
00537     lb[a++]= &(main->gpencil); /* referenced by nodes, objects, view, scene etc, before to free after. */
00538     lb[a++]= &(main->nodetree);
00539     lb[a++]= &(main->image);
00540     lb[a++]= &(main->tex);
00541     lb[a++]= &(main->mat);
00542     lb[a++]= &(main->vfont);
00543     
00544     /* Important!: When adding a new object type,
00545      * the specific data should be inserted here 
00546      */
00547 
00548     lb[a++]= &(main->armature);
00549 
00550     lb[a++]= &(main->mesh);
00551     lb[a++]= &(main->curve);
00552     lb[a++]= &(main->mball);
00553 
00554     lb[a++]= &(main->latt);
00555     lb[a++]= &(main->lamp);
00556     lb[a++]= &(main->camera);
00557 
00558     lb[a++]= &(main->text);
00559     lb[a++]= &(main->sound);
00560     lb[a++]= &(main->group);
00561     lb[a++]= &(main->brush);
00562     lb[a++]= &(main->script);
00563     lb[a++]= &(main->particle);
00564     lb[a++]= &(main->speaker);
00565 
00566     lb[a++]= &(main->world);
00567     lb[a++]= &(main->screen);
00568     lb[a++]= &(main->object);
00569     lb[a++]= &(main->scene);
00570     lb[a++]= &(main->library);
00571     lb[a++]= &(main->wm);
00572     lb[a++]= &(main->movieclip);
00573     
00574     lb[a]= NULL;
00575 
00576     return a;
00577 }
00578 
00579 /* *********** ALLOC AND FREE *****************
00580   
00581 free_libblock(ListBase *lb, ID *id )
00582     provide a list-basis and datablock, but only ID is read
00583 
00584 void *alloc_libblock(ListBase *lb, type, name)
00585     inserts in list and returns a new ID
00586 
00587  ***************************** */
00588 
00589 static ID *alloc_libblock_notest(short type)
00590 {
00591     ID *id= NULL;
00592     
00593     switch( type ) {
00594         case ID_SCE:
00595             id= MEM_callocN(sizeof(Scene), "scene");
00596             break;
00597         case ID_LI:
00598             id= MEM_callocN(sizeof(Library), "library");
00599             break;
00600         case ID_OB:
00601             id= MEM_callocN(sizeof(Object), "object");
00602             break;
00603         case ID_ME:
00604             id= MEM_callocN(sizeof(Mesh), "mesh");
00605             break;
00606         case ID_CU:
00607             id= MEM_callocN(sizeof(Curve), "curve");
00608             break;
00609         case ID_MB:
00610             id= MEM_callocN(sizeof(MetaBall), "mball");
00611             break;
00612         case ID_MA:
00613             id= MEM_callocN(sizeof(Material), "mat");
00614             break;
00615         case ID_TE:
00616             id= MEM_callocN(sizeof(Tex), "tex");
00617             break;
00618         case ID_IM:
00619             id= MEM_callocN(sizeof(Image), "image");
00620             break;
00621         case ID_LT:
00622             id= MEM_callocN(sizeof(Lattice), "latt");
00623             break;
00624         case ID_LA:
00625             id= MEM_callocN(sizeof(Lamp), "lamp");
00626             break;
00627         case ID_CA:
00628             id= MEM_callocN(sizeof(Camera), "camera");
00629             break;
00630         case ID_IP:
00631             id= MEM_callocN(sizeof(Ipo), "ipo");
00632             break;
00633         case ID_KE:
00634             id= MEM_callocN(sizeof(Key), "key");
00635             break;
00636         case ID_WO:
00637             id= MEM_callocN(sizeof(World), "world");
00638             break;
00639         case ID_SCR:
00640             id= MEM_callocN(sizeof(bScreen), "screen");
00641             break;
00642         case ID_VF:
00643             id= MEM_callocN(sizeof(VFont), "vfont");
00644             break;
00645         case ID_TXT:
00646             id= MEM_callocN(sizeof(Text), "text");
00647             break;
00648         case ID_SCRIPT:
00649             //XXX id= MEM_callocN(sizeof(Script), "script");
00650             break;
00651         case ID_SPK:
00652             id= MEM_callocN(sizeof(Speaker), "speaker");
00653             break;
00654         case ID_SO:
00655             id= MEM_callocN(sizeof(bSound), "sound");
00656             break;
00657         case ID_GR:
00658             id= MEM_callocN(sizeof(Group), "group");
00659             break;
00660         case ID_AR:
00661             id = MEM_callocN(sizeof(bArmature), "armature");
00662             break;
00663         case ID_AC:
00664             id = MEM_callocN(sizeof(bAction), "action");
00665             break;
00666         case ID_NT:
00667             id = MEM_callocN(sizeof(bNodeTree), "nodetree");
00668             break;
00669         case ID_BR:
00670             id = MEM_callocN(sizeof(Brush), "brush");
00671             break;
00672         case ID_PA:
00673             id = MEM_callocN(sizeof(ParticleSettings), "ParticleSettings");
00674             break;
00675         case ID_WM:
00676             id = MEM_callocN(sizeof(wmWindowManager), "Window manager");
00677             break;
00678         case ID_GD:
00679             id = MEM_callocN(sizeof(bGPdata), "Grease Pencil");
00680             break;
00681         case ID_MC:
00682             id = MEM_callocN(sizeof(MovieClip), "Movie Clip");
00683             break;
00684     }
00685     return id;
00686 }
00687 
00688 /* used everywhere in blenkernel and text.c */
00689 void *alloc_libblock(ListBase *lb, short type, const char *name)
00690 {
00691     ID *id= NULL;
00692     
00693     id= alloc_libblock_notest(type);
00694     if(id) {
00695         BLI_addtail(lb, id);
00696         id->us= 1;
00697         id->icon_id = 0;
00698         *( (short *)id->name )= type;
00699         new_id(lb, id, name);
00700         /* alphabetic insterion: is in new_id */
00701     }
00702     return id;
00703 }
00704 
00705 /* by spec, animdata is first item after ID */
00706 /* and, trust that BKE_animdata_from_id() will only find AnimData for valid ID-types */
00707 static void id_copy_animdata(ID *id, const short do_action)
00708 {
00709     AnimData *adt= BKE_animdata_from_id(id);
00710     
00711     if (adt) {
00712         IdAdtTemplate *iat = (IdAdtTemplate *)id;
00713         iat->adt= BKE_copy_animdata(iat->adt, do_action); /* could be set to FALSE, need to investigate */
00714     }
00715 }
00716 
00717 /* material nodes use this since they are not treated as libdata */
00718 void copy_libblock_data(ID *id, const ID *id_from, const short do_action)
00719 {
00720     if (id_from->properties)
00721         id->properties = IDP_CopyProperty(id_from->properties);
00722 
00723     /* the duplicate should get a copy of the animdata */
00724     id_copy_animdata(id, do_action);
00725 }
00726 
00727 /* used everywhere in blenkernel */
00728 void *copy_libblock(ID *id)
00729 {
00730     ID *idn;
00731     ListBase *lb;
00732     size_t idn_len;
00733 
00734     lb= which_libbase(G.main, GS(id->name));
00735     idn= alloc_libblock(lb, GS(id->name), id->name+2);
00736 
00737     assert(idn != NULL);
00738 
00739     idn_len= MEM_allocN_len(idn);
00740     if((int)idn_len - (int)sizeof(ID) > 0) { /* signed to allow neg result */
00741         const char *cp= (const char *)id;
00742         char *cpn= (char *)idn;
00743 
00744         memcpy(cpn+sizeof(ID), cp+sizeof(ID), idn_len - sizeof(ID));
00745     }
00746     
00747     id->newid= idn;
00748     idn->flag |= LIB_NEW;
00749 
00750     copy_libblock_data(idn, id, FALSE);
00751     
00752     return idn;
00753 }
00754 
00755 static void free_library(Library *UNUSED(lib))
00756 {
00757     /* no freeing needed for libraries yet */
00758 }
00759 
00760 static void (*free_windowmanager_cb)(bContext *, wmWindowManager *)= NULL;
00761 
00762 void set_free_windowmanager_cb(void (*func)(bContext *C, wmWindowManager *) )
00763 {
00764     free_windowmanager_cb= func;
00765 }
00766 
00767 static void animdata_dtar_clear_cb(ID *UNUSED(id), AnimData *adt, void *userdata)
00768 {
00769     ChannelDriver *driver;
00770     FCurve *fcu;
00771 
00772     /* find the driver this belongs to and update it */
00773     for (fcu=adt->drivers.first; fcu; fcu=fcu->next) {
00774         driver= fcu->driver;
00775         
00776         if (driver) {
00777             DriverVar *dvar;
00778             for (dvar= driver->variables.first; dvar; dvar= dvar->next) {
00779                 DRIVER_TARGETS_USED_LOOPER(dvar) 
00780                 {
00781                     if (dtar->id == userdata)
00782                         dtar->id= NULL;
00783                 }
00784                 DRIVER_TARGETS_LOOPER_END
00785             }
00786         }
00787     }
00788 }
00789 
00790 
00791 /* used in headerbuttons.c image.c mesh.c screen.c sound.c and library.c */
00792 void free_libblock(ListBase *lb, void *idv)
00793 {
00794     ID *id= idv;
00795 
00796 #ifdef WITH_PYTHON
00797     BPY_id_release(id);
00798 #endif
00799 
00800     switch( GS(id->name) ) {    /* GetShort from util.h */
00801         case ID_SCE:
00802             free_scene((Scene *)id);
00803             break;
00804         case ID_LI:
00805             free_library((Library *)id);
00806             break;
00807         case ID_OB:
00808             free_object((Object *)id);
00809             break;
00810         case ID_ME:
00811             free_mesh((Mesh *)id);
00812             break;
00813         case ID_CU:
00814             free_curve((Curve *)id);
00815             break;
00816         case ID_MB:
00817             free_mball((MetaBall *)id);
00818             break;
00819         case ID_MA:
00820             free_material((Material *)id);
00821             break;
00822         case ID_TE:
00823             free_texture((Tex *)id);
00824             break;
00825         case ID_IM:
00826             free_image((Image *)id);
00827             break;
00828         case ID_LT:
00829             free_lattice((Lattice *)id);
00830             break;
00831         case ID_LA:
00832             free_lamp((Lamp *)id);
00833             break;
00834         case ID_CA:
00835             free_camera((Camera*) id);
00836             break;
00837         case ID_IP:
00838             free_ipo((Ipo *)id);
00839             break;
00840         case ID_KE:
00841             free_key((Key *)id);
00842             break;
00843         case ID_WO:
00844             free_world((World *)id);
00845             break;
00846         case ID_SCR:
00847             free_screen((bScreen *)id);
00848             break;
00849         case ID_VF:
00850             free_vfont((VFont *)id);
00851             break;
00852         case ID_TXT:
00853             free_text((Text *)id);
00854             break;
00855         case ID_SCRIPT:
00856             //XXX free_script((Script *)id);
00857             break;
00858         case ID_SPK:
00859             free_speaker((Speaker *)id);
00860             break;
00861         case ID_SO:
00862             sound_free((bSound*)id);
00863             break;
00864         case ID_GR:
00865             free_group_objects((Group *)id);
00866             break;
00867         case ID_AR:
00868             free_armature((bArmature *)id);
00869             break;
00870         case ID_AC:
00871             free_action((bAction *)id);
00872             break;
00873         case ID_NT:
00874             ntreeFreeTree((bNodeTree *)id);
00875             break;
00876         case ID_BR:
00877             free_brush((Brush *)id);
00878             break;
00879         case ID_PA:
00880             psys_free_settings((ParticleSettings *)id);
00881             break;
00882         case ID_WM:
00883             if(free_windowmanager_cb)
00884                 free_windowmanager_cb(NULL, (wmWindowManager *)id);
00885             break;
00886         case ID_GD:
00887             free_gpencil_data((bGPdata *)id);
00888             break;
00889         case ID_MC:
00890             free_movieclip((MovieClip *)id);
00891             break;
00892     }
00893 
00894     if (id->properties) {
00895         IDP_FreeProperty(id->properties);
00896         MEM_freeN(id->properties);
00897     }
00898 
00899     BLI_remlink(lb, id);
00900 
00901     /* this ID may be a driver target! */
00902     BKE_animdata_main_cb(G.main, animdata_dtar_clear_cb, (void *)id);
00903 
00904     MEM_freeN(id);
00905 }
00906 
00907 void free_libblock_us(ListBase *lb, void *idv)      /* test users */
00908 {
00909     ID *id= idv;
00910     
00911     id->us--;
00912 
00913     if(id->us<0) {
00914         if(id->lib) printf("ERROR block %s %s users %d\n", id->lib->name, id->name, id->us);
00915         else printf("ERROR block %s users %d\n", id->name, id->us);
00916     }
00917     if(id->us==0) {
00918         if( GS(id->name)==ID_OB ) unlink_object((Object *)id);
00919         
00920         free_libblock(lb, id);
00921     }
00922 }
00923 
00924 
00925 void free_main(Main *mainvar)
00926 {
00927     /* also call when reading a file, erase all, etc */
00928     ListBase *lbarray[MAX_LIBARRAY];
00929     int a;
00930 
00931     a= set_listbasepointers(mainvar, lbarray);
00932     while(a--) {
00933         ListBase *lb= lbarray[a];
00934         ID *id;
00935         
00936         while ( (id= lb->first) ) {
00937             free_libblock(lb, id);
00938         }
00939     }
00940 
00941     MEM_freeN(mainvar);
00942 }
00943 
00944 /* ***************** ID ************************ */
00945 
00946 
00947 ID *find_id(const char *type, const char *name)     /* type: "OB" or "MA" etc */
00948 {
00949     ListBase *lb= which_libbase(G.main, GS(type));
00950     return BLI_findstring(lb, name, offsetof(ID, name) + 2);
00951 }
00952 
00953 static void get_flags_for_id(ID *id, char *buf) 
00954 {
00955     int isfake= id->flag & LIB_FAKEUSER;
00956     int isnode=0;
00957         /* Writeout the flags for the entry, note there
00958          * is a small hack that writes 5 spaces instead
00959          * of 4 if no flags are displayed... this makes
00960          * things usually line up ok - better would be
00961          * to have that explicit, oh well - zr
00962          */
00963 
00964     if(GS(id->name)==ID_MA)
00965         isnode= ((Material *)id)->use_nodes;
00966     if(GS(id->name)==ID_TE)
00967         isnode= ((Tex *)id)->use_nodes;
00968     
00969     if (id->us<0)
00970         strcpy(buf, "-1W ");
00971     else if (!id->lib && !isfake && id->us && !isnode)
00972         strcpy(buf, "     ");
00973     else if(isnode)
00974         sprintf(buf, "%c%cN%c ", id->lib?'L':' ', isfake?'F':' ', (id->us==0)?'O':' ');
00975     else
00976         sprintf(buf, "%c%c%c ", id->lib?'L':' ', isfake?'F':' ', (id->us==0)?'O':' ');
00977 }
00978 
00979 #define IDPUP_NO_VIEWER 1
00980 
00981 static void IDnames_to_dyn_pupstring(DynStr *pupds, ListBase *lb, ID *link, short *nr, int hideflag)
00982 {
00983     int i, nids= BLI_countlist(lb);
00984         
00985     if (nr) *nr= -1;
00986     
00987     if (nr && nids>MAX_IDPUP) {
00988         BLI_dynstr_append(pupds, "DataBrowse %x-2");
00989         *nr= -2;
00990     } else {
00991         ID *id;
00992         
00993         for (i=0, id= lb->first; id; id= id->next, i++) {
00994             char numstr[32];
00995             
00996             if (nr && id==link) *nr= i+1;
00997 
00998             if (U.uiflag & USER_HIDE_DOT && id->name[2]=='.')
00999                 continue;
01000             if (hideflag & IDPUP_NO_VIEWER)
01001                 if (GS(id->name)==ID_IM)
01002                     if ( ((Image *)id)->source==IMA_SRC_VIEWER )
01003                         continue;
01004             
01005             get_flags_for_id(id, numstr);
01006                 
01007             BLI_dynstr_append(pupds, numstr);
01008             BLI_dynstr_append(pupds, id->name+2);
01009             BLI_snprintf(numstr, sizeof(numstr), "%%x%d", i+1);
01010             BLI_dynstr_append(pupds, numstr);
01011             
01012             /* icon */
01013             switch(GS(id->name))
01014             {
01015             case ID_MA: /* fall through */
01016             case ID_TE: /* fall through */
01017             case ID_IM: /* fall through */
01018             case ID_WO: /* fall through */
01019             case ID_LA: /* fall through */
01020                 BLI_snprintf(numstr, sizeof(numstr), "%%i%d", BKE_icon_getid(id) );
01021                 BLI_dynstr_append(pupds, numstr);
01022                 break;
01023             default:
01024                 break;
01025             }
01026             
01027             if(id->next)
01028                 BLI_dynstr_append(pupds, "|");
01029         }
01030     }
01031 }
01032 
01033 
01034 /* used by headerbuttons.c buttons.c editobject.c editseq.c */
01035 /* if nr==NULL no MAX_IDPUP, this for non-header browsing */
01036 void IDnames_to_pupstring(const char **str, const char *title, const char *extraops, ListBase *lb, ID *link, short *nr)
01037 {
01038     DynStr *pupds= BLI_dynstr_new();
01039 
01040     if (title) {
01041         BLI_dynstr_append(pupds, title);
01042         BLI_dynstr_append(pupds, "%t|");
01043     }
01044     
01045     if (extraops) {
01046         BLI_dynstr_append(pupds, extraops);
01047         if (BLI_dynstr_get_len(pupds))
01048             BLI_dynstr_append(pupds, "|");
01049     }
01050 
01051     IDnames_to_dyn_pupstring(pupds, lb, link, nr, 0);
01052     
01053     *str= BLI_dynstr_get_cstring(pupds);
01054     BLI_dynstr_free(pupds);
01055 }
01056 
01057 /* skips viewer images */
01058 void IMAnames_to_pupstring(const char **str, const char *title, const char *extraops, ListBase *lb, ID *link, short *nr)
01059 {
01060     DynStr *pupds= BLI_dynstr_new();
01061     
01062     if (title) {
01063         BLI_dynstr_append(pupds, title);
01064         BLI_dynstr_append(pupds, "%t|");
01065     }
01066     
01067     if (extraops) {
01068         BLI_dynstr_append(pupds, extraops);
01069         if (BLI_dynstr_get_len(pupds))
01070             BLI_dynstr_append(pupds, "|");
01071     }
01072     
01073     IDnames_to_dyn_pupstring(pupds, lb, link, nr, IDPUP_NO_VIEWER);
01074     
01075     *str= BLI_dynstr_get_cstring(pupds);
01076     BLI_dynstr_free(pupds);
01077 }
01078 
01079 static void sort_alpha_id(ListBase *lb, ID *id)
01080 {
01081     ID *idtest;
01082     
01083     /* insert alphabetically */
01084     if(lb->first!=lb->last) {
01085         BLI_remlink(lb, id);
01086         
01087         idtest= lb->first;
01088         while(idtest) {
01089             if(BLI_strcasecmp(idtest->name, id->name)>0 || idtest->lib) {
01090                 BLI_insertlinkbefore(lb, idtest, id);
01091                 break;
01092             }
01093             idtest= idtest->next;
01094         }
01095         /* as last */
01096         if(idtest==NULL) {
01097             BLI_addtail(lb, id);
01098         }
01099     }
01100     
01101 }
01102 
01103 /*
01104  * Check to see if there is an ID with the same name as 'name'.
01105  * Returns the ID if so, if not, returns NULL
01106  */
01107 static ID *is_dupid(ListBase *lb, ID *id, const char *name)
01108 {
01109     ID *idtest=NULL;
01110     
01111     for( idtest = lb->first; idtest; idtest = idtest->next ) {
01112         /* if idtest is not a lib */ 
01113         if( id != idtest && idtest->lib == NULL ) {
01114             /* do not test alphabetic! */
01115             /* optimized */
01116             if( idtest->name[2] == name[0] ) {
01117                 if(strcmp(name, idtest->name+2)==0) break;
01118             }
01119         }
01120     }
01121     
01122     return idtest;
01123 }
01124 
01125 /* 
01126  * Check to see if an ID name is already used, and find a new one if so.
01127  * Return 1 if created a new name (returned in name).
01128  *
01129  * Normally the ID that's being check is already in the ListBase, so ID *id
01130  * points at the new entry.  The Python Library module needs to know what
01131  * the name of a datablock will be before it is appended; in this case ID *id
01132  * id is NULL;
01133  */
01134 
01135 static int check_for_dupid(ListBase *lb, ID *id, char *name)
01136 {
01137     ID *idtest;
01138     int nr= 0, nrtest, a, left_len;
01139     char in_use[64]; /* use as a boolean array, unrelated to name length */
01140 
01141     char left[MAX_ID_NAME + 8], leftest[MAX_ID_NAME + 8];
01142 
01143     /* make sure input name is terminated properly */
01144     /* if( strlen(name) > MAX_ID_NAME-3 ) name[MAX_ID_NAME-3]= 0; */
01145     /* removed since this is only ever called from one place - campbell */
01146 
01147     while (1) {
01148 
01149         /* phase 1: id already exists? */
01150         idtest = is_dupid(lb, id, name);
01151 
01152         /* if there is no double, done */
01153         if( idtest == NULL ) return 0;
01154 
01155         /* we have a dup; need to make a new name */
01156         /* quick check so we can reuse one of first 64 ids if vacant */
01157         memset(in_use, 0, sizeof(in_use));
01158 
01159         /* get name portion, number portion ("name.number") */
01160         left_len= BLI_split_name_num(left, &nr, name, '.');
01161 
01162         /* if new name will be too long, truncate it */
01163         if(nr > 999 && left_len > (MAX_ID_NAME - 8)) {
01164             left[MAX_ID_NAME - 8]= 0;
01165             left_len= MAX_ID_NAME - 8;
01166         }
01167         else if(left_len > (MAX_ID_NAME - 7)) {
01168             left[MAX_ID_NAME - 7]= 0;
01169             left_len= MAX_ID_NAME - 7;
01170         }
01171 
01172         for(idtest= lb->first; idtest; idtest= idtest->next) {
01173             if(     (id != idtest) &&
01174                     (idtest->lib == NULL) &&
01175                     (*name == *(idtest->name+2)) &&
01176                     (strncmp(name, idtest->name+2, left_len)==0) &&
01177                     (BLI_split_name_num(leftest, &nrtest, idtest->name+2, '.') == left_len)
01178             ) {
01179                 if(nrtest < sizeof(in_use))
01180                     in_use[nrtest]= 1;  /* mark as used */
01181                 if(nr <= nrtest)
01182                     nr= nrtest+1;       /* track largest unused */
01183             }
01184         }
01185 
01186         /* decide which value of nr to use */
01187         for(a=0; a < sizeof(in_use); a++) {
01188             if(a>=nr) break;    /* stop when we've check up to biggest */
01189             if( in_use[a]==0 ) { /* found an unused value */
01190                 nr = a;
01191                 break;
01192             }
01193         }
01194 
01195         /* If the original name has no numeric suffix, 
01196          * rather than just chopping and adding numbers, 
01197          * shave off the end chars until we have a unique name.
01198          * Check the null terminators match as well so we dont get Cube.000 -> Cube.00 */
01199         if (nr==0 && name[left_len]== '\0') {
01200             int len = left_len-1;
01201             idtest= is_dupid(lb, id, name);
01202             
01203             while (idtest && len> 1) {
01204                 name[len--] = '\0';
01205                 idtest= is_dupid(lb, id, name);
01206             }
01207             if (idtest == NULL) return 1;
01208             /* otherwise just continue and use a number suffix */
01209         }
01210         
01211         if(nr > 999 && left_len > (MAX_ID_NAME - 8)) {
01212             /* this would overflow name buffer */
01213             left[MAX_ID_NAME - 8] = 0;
01214             /* left_len = MAX_ID_NAME - 8; */ /* for now this isnt used again */
01215             memcpy(name, left, sizeof(char) * (MAX_ID_NAME - 7));
01216             continue;
01217         }
01218         /* this format specifier is from hell... */
01219         BLI_snprintf(name, sizeof(id->name) - 2,"%s.%.3d", left, nr);
01220 
01221         return 1;
01222     }
01223 }
01224 
01225 /*
01226  * Only for local blocks: external en indirect blocks already have a
01227  * unique ID.
01228  *
01229  * return 1: created a new name
01230  */
01231 
01232 int new_id(ListBase *lb, ID *id, const char *tname)
01233 {
01234     int result;
01235     char name[MAX_ID_NAME-2];
01236 
01237     /* if library, don't rename */
01238     if(id->lib) return 0;
01239 
01240     /* if no libdata given, look up based on ID */
01241     if(lb==NULL) lb= which_libbase(G.main, GS(id->name));
01242 
01243     /* if no name given, use name of current ID
01244      * else make a copy (tname args can be const) */
01245     if(tname==NULL)
01246         tname= id->name+2;
01247 
01248     strncpy(name, tname, sizeof(name)-1);
01249 
01250     /* if result > MAX_ID_NAME-3, strncpy don't put the final '\0' to name.
01251      * easier to assign each time then to check if its needed */
01252     name[sizeof(name)-1]= 0;
01253 
01254     if(name[0] == '\0') {
01255         /* disallow empty names */
01256         strcpy(name, ID_FALLBACK_NAME);
01257     }
01258     else {
01259         /* disallow non utf8 chars,
01260          * the interface checks for this but new ID's based on file names dont */
01261         BLI_utf8_invalid_strip(name, strlen(name));
01262     }
01263 
01264     result = check_for_dupid(lb, id, name);
01265     strcpy(id->name+2, name);
01266 
01267     /* This was in 2.43 and previous releases
01268      * however all data in blender should be sorted, not just duplicate names
01269      * sorting should not hurt, but noting just incause it alters the way other
01270      * functions work, so sort every time */
01271     /* if( result )
01272         sort_alpha_id(lb, id);*/
01273     
01274     sort_alpha_id(lb, id);
01275     
01276     return result;
01277 }
01278 
01279 /* Pull an ID out of a library (make it local). Only call this for IDs that
01280    don't have other library users. */
01281 void id_clear_lib_data(Main *bmain, ID *id)
01282 {
01283     BKE_id_lib_local_paths(bmain, id->lib, id);
01284 
01285     id->lib= NULL;
01286     id->flag= LIB_LOCAL;
01287     new_id(which_libbase(bmain, GS(id->name)), id, NULL);
01288 }
01289 
01290 /* next to indirect usage in read/writefile also in editobject.c scene.c */
01291 void clear_id_newpoins(void)
01292 {
01293     ListBase *lbarray[MAX_LIBARRAY];
01294     ID *id;
01295     int a;
01296 
01297     a= set_listbasepointers(G.main, lbarray);
01298     while(a--) {
01299         id= lbarray[a]->first;
01300         while(id) {
01301             id->newid= NULL;
01302             id->flag &= ~LIB_NEW;
01303             id= id->next;
01304         }
01305     }
01306 }
01307 
01308 #define LIBTAG(a)   if(a && a->id.lib) {a->id.flag &=~LIB_INDIRECT; a->id.flag |= LIB_EXTERN;}
01309 
01310 static void lib_indirect_test_id(ID *id, Library *lib)
01311 {
01312     
01313     if(id->lib) {
01314         /* datablocks that were indirectly related are now direct links
01315          * without this, appending data that has a link to other data will fail to write */
01316         if(lib && id->lib->parent == lib) {
01317             id_lib_extern(id);
01318         }
01319         return;
01320     }
01321     
01322     if(GS(id->name)==ID_OB) {       
01323         Object *ob= (Object *)id;
01324         Mesh *me;
01325 
01326         int a;
01327 
01328 #if 0   /* XXX OLD ANIMSYS, NLASTRIPS ARE NO LONGER USED */
01329         // XXX old animation system! --------------------------------------
01330         {
01331             bActionStrip *strip;
01332             for (strip=ob->nlastrips.first; strip; strip=strip->next){
01333                 LIBTAG(strip->object);
01334                 LIBTAG(strip->act);
01335                 LIBTAG(strip->ipo);
01336             }
01337         }
01338         // XXX: new animation system needs something like this?
01339 #endif
01340 
01341         for(a=0; a<ob->totcol; a++) {
01342             LIBTAG(ob->mat[a]);
01343         }
01344     
01345         LIBTAG(ob->dup_group);
01346         LIBTAG(ob->proxy);
01347         
01348         me= ob->data;
01349         LIBTAG(me);
01350     }
01351 }
01352 
01353 void tag_main_lb(ListBase *lb, const short tag)
01354 {
01355     ID *id;
01356     if(tag) {
01357         for(id= lb->first; id; id= id->next) {
01358             id->flag |= LIB_DOIT;
01359         }
01360     }
01361     else {
01362         for(id= lb->first; id; id= id->next) {
01363             id->flag &= ~LIB_DOIT;
01364         }
01365     }
01366 }
01367 
01368 void tag_main_idcode(struct Main *mainvar, const short type, const short tag)
01369 {
01370     ListBase *lb= which_libbase(mainvar, type);
01371 
01372     tag_main_lb(lb, tag);
01373 }
01374 
01375 void tag_main(struct Main *mainvar, const short tag)
01376 {
01377     ListBase *lbarray[MAX_LIBARRAY];
01378     int a;
01379 
01380     a= set_listbasepointers(mainvar, lbarray);
01381     while(a--) {
01382         tag_main_lb(lbarray[a], tag);
01383     }
01384 }
01385 
01386 /* if lib!=NULL, only all from lib local
01387  * bmain is almost certainly G.main */
01388 void BKE_library_make_local(Main *bmain, Library *lib, int untagged_only)
01389 {
01390     ListBase *lbarray[MAX_LIBARRAY], tempbase={NULL, NULL};
01391     ID *id, *idn;
01392     int a;
01393 
01394     a= set_listbasepointers(bmain, lbarray);
01395     while(a--) {
01396         id= lbarray[a]->first;
01397         
01398         while(id) {
01399             id->newid= NULL;
01400             idn= id->next;      /* id is possibly being inserted again */
01401             
01402             /* The check on the second line (LIB_PRE_EXISTING) is done so its
01403              * possible to tag data you dont want to be made local, used for
01404              * appending data, so any libdata already linked wont become local
01405              * (very nasty to discover all your links are lost after appending)  
01406              * */
01407             if(id->flag & (LIB_EXTERN|LIB_INDIRECT|LIB_NEW) &&
01408               (untagged_only==0 || !(id->flag & LIB_PRE_EXISTING)))
01409             {
01410                 if(lib==NULL || id->lib==lib) {
01411                     if(id->lib) {
01412                         id_clear_lib_data(bmain, id); /* sets 'id->flag' */
01413 
01414                         /* why sort alphabetically here but not in
01415                          * id_clear_lib_data() ? - campbell */
01416                         sort_alpha_id(lbarray[a], id);
01417                     }
01418                     else {
01419                         id->flag &= ~(LIB_EXTERN|LIB_INDIRECT|LIB_NEW);
01420                     }
01421                 }
01422             }
01423             id= idn;
01424         }
01425         
01426         /* patch2: make it aphabetically */
01427         while( (id=tempbase.first) ) {
01428             BLI_remlink(&tempbase, id);
01429             BLI_addtail(lbarray[a], id);
01430             new_id(lbarray[a], id, NULL);
01431         }
01432     }
01433 
01434     /* patch 3: make sure library data isn't indirect falsely... */
01435     a= set_listbasepointers(bmain, lbarray);
01436     while(a--) {
01437         for(id= lbarray[a]->first; id; id=id->next)
01438             lib_indirect_test_id(id, lib);
01439     }
01440 }
01441 
01442 
01443 void test_idbutton(char *name)
01444 {
01445     /* called from buttons: when name already exists: call new_id */
01446     ListBase *lb;
01447     ID *idtest;
01448     
01449 
01450     lb= which_libbase(G.main, GS(name-2) );
01451     if(lb==NULL) return;
01452     
01453     /* search for id */
01454     idtest= BLI_findstring(lb, name, offsetof(ID, name) + 2);
01455 
01456     if(idtest) if( new_id(lb, idtest, name)==0 ) sort_alpha_id(lb, idtest);
01457 }
01458 
01459 void text_idbutton(struct ID *id, char *text)
01460 {
01461     if(id) {
01462         if(GS(id->name)==ID_SCE)
01463             strcpy(text, "SCE: ");
01464         else if(GS(id->name)==ID_SCR)
01465             strcpy(text, "SCR: ");
01466         else if(GS(id->name)==ID_MA && ((Material*)id)->use_nodes)
01467             strcpy(text, "NT: ");
01468         else {
01469             text[0]= id->name[0];
01470             text[1]= id->name[1];
01471             text[2]= ':';
01472             text[3]= ' ';
01473             text[4]= 0;
01474         }
01475     }
01476     else {
01477         text[0]= '\0';
01478     }
01479 }
01480 
01481 void rename_id(ID *id, const char *name)
01482 {
01483     ListBase *lb;
01484 
01485     BLI_strncpy(id->name+2, name, sizeof(id->name)-2);
01486     lb= which_libbase(G.main, GS(id->name) );
01487     
01488     new_id(lb, id, name);               
01489 }
01490 
01491 void name_uiprefix_id(char *name, ID *id)
01492 {
01493     name[0] = id->lib ? 'L':' ';
01494     name[1] = id->flag & LIB_FAKEUSER ? 'F': (id->us==0)?'0':' ';
01495     name[2] = ' ';
01496 
01497     strcpy(name+3, id->name+2);
01498 }
01499 
01500 void BKE_library_filepath_set(Library *lib, const char *filepath)
01501 {
01502     /* in some cases this is used to update the absolute path from the
01503      * relative */
01504     if (lib->name != filepath) {
01505         BLI_strncpy(lib->name, filepath, sizeof(lib->name));
01506     }
01507 
01508     BLI_strncpy(lib->filepath, filepath, sizeof(lib->filepath));
01509 
01510     /* not essential but set filepath is an absolute copy of value which
01511      * is more useful if its kept in sync */
01512     if (strncmp(lib->filepath, "//", 2) == 0) {
01513         /* note that the file may be unsaved, in this case, setting the
01514          * filepath on an indirectly linked path is not allowed from the
01515          * outliner, and its not really supported but allow from here for now
01516          * since making local could cause this to be directly linked - campbell
01517          */
01518         const char *basepath= lib->parent ? lib->parent->filepath : G.main->name;
01519         BLI_path_abs(lib->filepath, basepath);
01520     }
01521 }