Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/blenkernel/intern/library.c')
-rw-r--r--source/blender/blenkernel/intern/library.c132
1 files changed, 64 insertions, 68 deletions
diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c
index 834e7de5811..6eb5399404a 100644
--- a/source/blender/blenkernel/intern/library.c
+++ b/source/blender/blenkernel/intern/library.c
@@ -39,6 +39,7 @@
#include <string.h>
#include <stdlib.h>
#include <stddef.h>
+#include <assert.h>
#include "MEM_guardedalloc.h"
@@ -66,9 +67,10 @@
#include "DNA_world_types.h"
#include "DNA_gpencil_types.h"
-
#include "BLI_blenlib.h"
#include "BLI_dynstr.h"
+#include "BLI_utildefines.h"
+
#include "BKE_animsys.h"
#include "BKE_context.h"
@@ -136,8 +138,14 @@ void id_us_plus(ID *id)
void id_us_min(ID *id)
{
- if(id)
- id->us--;
+ if(id) {
+ if(id->us<2 && (id->flag & LIB_FAKEUSER))
+ id->us= 1;
+ else if(id->us<=0)
+ printf("ID user decrement error: %s \n", id->name);
+ else
+ id->us--;
+ }
}
int id_make_local(ID *id, int test)
@@ -302,7 +310,7 @@ int id_copy(ID *id, ID **newid, int test)
if(!test) *newid= (ID*)copy_action((bAction*)id);
return 1;
case ID_NT:
- if(!test) *newid= (ID*)ntreeCopyTree((bNodeTree*)id, 0);
+ if(!test) *newid= (ID*)ntreeCopyTree((bNodeTree*)id);
return 1;
case ID_BR:
if(!test) *newid= (ID*)copy_brush((Brush*)id);
@@ -335,7 +343,7 @@ int id_unlink(ID *id, int test)
break;
case ID_OB:
if(test) return 1;
- unlink_object(NULL, (Object*)id);
+ unlink_object((Object*)id);
break;
}
@@ -442,7 +450,7 @@ void recalc_all_library_objects(Main *main)
/* flag for full recalc */
for(ob=main->object.first; ob; ob=ob->id.next)
if(ob->id.lib)
- ob->recalc |= OB_RECALC_ALL;
+ ob->recalc |= OB_RECALC_OB|OB_RECALC_DATA|OB_RECALC_TIME;
}
/* note: MAX_LIBARRAY define should match this code */
@@ -450,11 +458,13 @@ int set_listbasepointers(Main *main, ListBase **lb)
{
int a = 0;
- /* BACKWARDS! also watch order of free-ing! (mesh<->mat) */
-
+ /* BACKWARDS! also watch order of free-ing! (mesh<->mat), first items freed last.
+ * This is important because freeing data decreases usercounts of other datablocks,
+ * if this data is its self freed it can crash. */
lb[a++]= &(main->ipo);
lb[a++]= &(main->action); // xxx moved here to avoid problems when freeing with animato (aligorith)
lb[a++]= &(main->key);
+ lb[a++]= &(main->gpencil); /* referenced by nodes, objects, view, scene etc, before to free after. */
lb[a++]= &(main->nodetree);
lb[a++]= &(main->image);
lb[a++]= &(main->tex);
@@ -481,14 +491,13 @@ int set_listbasepointers(Main *main, ListBase **lb)
lb[a++]= &(main->brush);
lb[a++]= &(main->script);
lb[a++]= &(main->particle);
-
+
lb[a++]= &(main->world);
lb[a++]= &(main->screen);
lb[a++]= &(main->object);
lb[a++]= &(main->scene);
lb[a++]= &(main->library);
lb[a++]= &(main->wm);
- lb[a++]= &(main->gpencil);
lb[a]= NULL;
@@ -617,24 +626,24 @@ void *alloc_libblock(ListBase *lb, short type, const char *name)
/* by spec, animdata is first item after ID */
/* and, trust that BKE_animdata_from_id() will only find AnimData for valid ID-types */
-static void id_copy_animdata(ID *id)
+static void id_copy_animdata(ID *id, const short do_action)
{
AnimData *adt= BKE_animdata_from_id(id);
if (adt) {
IdAdtTemplate *iat = (IdAdtTemplate *)id;
- iat->adt= BKE_copy_animdata(iat->adt);
+ iat->adt= BKE_copy_animdata(iat->adt, do_action); /* could be set to FALSE, need to investigate */
}
}
/* material nodes use this since they are not treated as libdata */
-void copy_libblock_data(ID *id, const ID *id_from)
+void copy_libblock_data(ID *id, const ID *id_from, const short do_action)
{
if (id_from->properties)
id->properties = IDP_CopyProperty(id_from->properties);
/* the duplicate should get a copy of the animdata */
- id_copy_animdata(id);
+ id_copy_animdata(id, do_action);
}
/* used everywhere in blenkernel */
@@ -649,11 +658,9 @@ void *copy_libblock(void *rt)
lb= which_libbase(G.main, GS(id->name));
idn= alloc_libblock(lb, GS(id->name), id->name+2);
-
- if(idn==NULL) {
- printf("ERROR: Illegal ID name for %s (Crashing now)\n", id->name);
- }
-
+
+ assert(idn != NULL);
+
idn_len= MEM_allocN_len(idn);
if(idn_len - sizeof(ID) > 0) {
cp= (char *)id;
@@ -664,12 +671,12 @@ void *copy_libblock(void *rt)
id->newid= idn;
idn->flag |= LIB_NEW;
- copy_libblock_data(idn, id);
+ copy_libblock_data(idn, id, FALSE);
return idn;
}
-static void free_library(Library *lib)
+static void free_library(Library *UNUSED(lib))
{
/* no freeing needed for libraries yet */
}
@@ -681,7 +688,7 @@ void set_free_windowmanager_cb(void (*func)(bContext *C, wmWindowManager *) )
free_windowmanager_cb= func;
}
-void animdata_dtar_clear_cb(ID *id, AnimData *adt, void *userdata)
+void animdata_dtar_clear_cb(ID *UNUSED(id), AnimData *adt, void *userdata)
{
ChannelDriver *driver;
FCurve *fcu;
@@ -822,7 +829,7 @@ void free_libblock_us(ListBase *lb, void *idv) /* test users */
else printf("ERROR block %s users %d\n", id->name, id->us);
}
if(id->us==0) {
- if( GS(id->name)==ID_OB ) unlink_object(NULL, (Object *)id);
+ if( GS(id->name)==ID_OB ) unlink_object((Object *)id);
free_libblock(lb, id);
}
@@ -851,7 +858,7 @@ void free_main(Main *mainvar)
/* ***************** ID ************************ */
-ID *find_id(char *type, char *name) /* type: "OB" or "MA" etc */
+ID *find_id(const char *type, const char *name) /* type: "OB" or "MA" etc */
{
ListBase *lb= which_libbase(G.main, GS(type));
return BLI_findstring(lb, name, offsetof(ID, name) + 2);
@@ -940,7 +947,7 @@ static void IDnames_to_dyn_pupstring(DynStr *pupds, ListBase *lb, ID *link, shor
/* used by headerbuttons.c buttons.c editobject.c editseq.c */
/* if nr==NULL no MAX_IDPUP, this for non-header browsing */
-void IDnames_to_pupstring(char **str, char *title, char *extraops, ListBase *lb, ID *link, short *nr)
+void IDnames_to_pupstring(const char **str, const char *title, const char *extraops, ListBase *lb, ID *link, short *nr)
{
DynStr *pupds= BLI_dynstr_new();
@@ -962,7 +969,7 @@ void IDnames_to_pupstring(char **str, char *title, char *extraops, ListBase *lb,
}
/* skips viewer images */
-void IMAnames_to_pupstring(char **str, char *title, char *extraops, ListBase *lb, ID *link, short *nr)
+void IMAnames_to_pupstring(const char **str, const char *title, const char *extraops, ListBase *lb, ID *link, short *nr)
{
DynStr *pupds= BLI_dynstr_new();
@@ -983,35 +990,6 @@ void IMAnames_to_pupstring(char **str, char *title, char *extraops, ListBase *lb
BLI_dynstr_free(pupds);
}
-
-/* used by buttons.c library.c mball.c */
-int splitIDname(char *name, char *left, int *nr)
-{
- int a;
-
- *nr= 0;
- strncpy(left, name, 21);
-
- a= strlen(name);
- if(a>1 && name[a-1]=='.') return a;
-
- while(a--) {
- if( name[a]=='.' ) {
- left[a]= 0;
- *nr= atol(name+a+1);
- return a;
- }
- if( isdigit(name[a])==0 ) break;
-
- left[a]= 0;
- }
-
- for(a= 0; name[a]; a++)
- left[a]= name[a];
-
- return a;
-}
-
static void sort_alpha_id(ListBase *lb, ID *id)
{
ID *idtest;
@@ -1040,7 +1018,7 @@ static void sort_alpha_id(ListBase *lb, ID *id)
* Check to see if there is an ID with the same name as 'name'.
* Returns the ID if so, if not, returns NULL
*/
-static ID *is_dupid(ListBase *lb, ID *id, char *name)
+static ID *is_dupid(ListBase *lb, ID *id, const char *name)
{
ID *idtest=NULL;
@@ -1091,7 +1069,7 @@ static int check_for_dupid(ListBase *lb, ID *id, char *name)
memset(in_use, 0, sizeof(in_use));
/* get name portion, number portion ("name.number") */
- left_len= splitIDname(name, left, &nr);
+ left_len= BLI_split_name_num(left, &nr, name, '.');
/* if new name will be too long, truncate it */
if(nr > 999 && left_len > 16) {
@@ -1108,7 +1086,7 @@ static int check_for_dupid(ListBase *lb, ID *id, char *name)
(idtest->lib == NULL) &&
(*name == *(idtest->name+2)) &&
(strncmp(name, idtest->name+2, left_len)==0) &&
- (splitIDname(idtest->name+2, leftest, &nrtest) == left_len)
+ (BLI_split_name_num(leftest, &nrtest, idtest->name+2, '.') == left_len)
) {
if(nrtest < sizeof(in_use))
in_use[nrtest]= 1; /* mark as used */
@@ -1234,7 +1212,7 @@ static void image_fix_relative_path(Image *ima)
if(ima->id.lib==NULL) return;
if(strncmp(ima->name, "//", 2)==0) {
BLI_path_abs(ima->name, ima->id.lib->filepath);
- BLI_path_rel(ima->name, G.sce);
+ BLI_path_rel(ima->name, G.main->name);
}
}
@@ -1279,18 +1257,36 @@ static void lib_indirect_test_id(ID *id, Library *lib)
}
}
-void tag_main(struct Main *mainvar, int tag)
+void tag_main_lb(ListBase *lb, const short tag)
{
- ListBase *lbarray[MAX_LIBARRAY];
ID *id;
+ if(tag) {
+ for(id= lb->first; id; id= id->next) {
+ id->flag |= LIB_DOIT;
+ }
+ }
+ else {
+ for(id= lb->first; id; id= id->next) {
+ id->flag &= ~LIB_DOIT;
+ }
+ }
+}
+
+void tag_main_idcode(struct Main *mainvar, const short type, const short tag)
+{
+ ListBase *lb= which_libbase(mainvar, type);
+
+ tag_main_lb(lb, tag);
+}
+
+void tag_main(struct Main *mainvar, const short tag)
+{
+ ListBase *lbarray[MAX_LIBARRAY];
int a;
a= set_listbasepointers(mainvar, lbarray);
while(a--) {
- for(id= lbarray[a]->first; id; id= id->next) {
- if(tag) id->flag |= LIB_DOIT;
- else id->flag &= ~LIB_DOIT;
- }
+ tag_main_lb(lbarray[a], tag);
}
}
@@ -1389,11 +1385,11 @@ void text_idbutton(struct ID *id, char *text)
}
}
-void rename_id(ID *id, char *name)
+void rename_id(ID *id, const char *name)
{
ListBase *lb;
- strncpy(id->name+2, name, 21);
+ BLI_strncpy(id->name+2, name, sizeof(id->name)-2);
lb= which_libbase(G.main, GS(id->name) );
new_id(lb, id, name);
@@ -1402,7 +1398,7 @@ void rename_id(ID *id, char *name)
void name_uiprefix_id(char *name, ID *id)
{
name[0] = id->lib ? 'L':' ';
- name[1] = id->flag & LIB_FAKEUSER ? 'F':' ';
+ name[1] = id->flag & LIB_FAKEUSER ? 'F': (id->us==0)?'0':' ';
name[2] = ' ';
strcpy(name+3, id->name+2);