Blender V2.61 - r43446
|
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 }