diff options
-rw-r--r-- | source/blender/blenkernel/BKE_material.h | 1 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/material.c | 82 | ||||
-rw-r--r-- | source/blender/blenloader/intern/readfile.c | 14 |
3 files changed, 48 insertions, 49 deletions
diff --git a/source/blender/blenkernel/BKE_material.h b/source/blender/blenkernel/BKE_material.h index 5687fcb4c01..53bb95cb8be 100644 --- a/source/blender/blenkernel/BKE_material.h +++ b/source/blender/blenkernel/BKE_material.h @@ -45,6 +45,7 @@ struct Object; void init_def_material(void); void free_material(struct Material *sc); void test_object_materials(struct ID *id); +void resize_object_material(struct Object *ob, const short totcol); void init_material(struct Material *ma); struct Material *add_material(const char *name); struct Material *copy_material(struct Material *ma); diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c index ac61acac56a..90017ba3d5b 100644 --- a/source/blender/blenkernel/intern/material.c +++ b/source/blender/blenkernel/intern/material.c @@ -590,67 +590,53 @@ Material *give_node_material(Material *ma) /* from misc_util: flip the bytes from x */ /* #define GS(x) (((unsigned char *)(x))[0] << 8 | ((unsigned char *)(x))[1]) */ -void test_object_materials(ID *id) +void resize_object_material(Object *ob, const short totcol) { - /* make the ob mat-array same size as 'ob->data' mat-array */ - Object *ob; - Mesh *me; - Curve *cu; - MetaBall *mb; Material **newmatar; char *newmatbits; - int totcol=0; - if(id==0) return; - - if( GS(id->name)==ID_ME ) { - me= (Mesh *)id; - totcol= me->totcol; + if(totcol==0) { + if(ob->totcol) { + MEM_freeN(ob->mat); + MEM_freeN(ob->matbits); + ob->mat= NULL; + ob->matbits= NULL; + } } - else if( GS(id->name)==ID_CU ) { - cu= (Curve *)id; - totcol= cu->totcol; + else if(ob->totcol<totcol) { + newmatar= MEM_callocN(sizeof(void *)*totcol, "newmatar"); + newmatbits= MEM_callocN(sizeof(char)*totcol, "newmatbits"); + if(ob->totcol) { + memcpy(newmatar, ob->mat, sizeof(void *)*ob->totcol); + memcpy(newmatbits, ob->matbits, sizeof(char)*ob->totcol); + MEM_freeN(ob->mat); + MEM_freeN(ob->matbits); + } + ob->mat= newmatar; + ob->matbits= newmatbits; } - else if( GS(id->name)==ID_MB ) { - mb= (MetaBall *)id; - totcol= mb->totcol; + ob->totcol= totcol; + if(ob->totcol && ob->actcol==0) ob->actcol= 1; + if(ob->actcol>ob->totcol) ob->actcol= ob->totcol; +} + +void test_object_materials(ID *id) +{ + /* make the ob mat-array same size as 'ob->data' mat-array */ + Object *ob; + short *totcol; + + if(id || (totcol=give_totcolp_id(id))==NULL) { + return; } - else return; - ob= G.main->object.first; - while(ob) { - + for(ob= G.main->object.first; ob; ob= ob->id.next) { if(ob->data==id) { - - if(totcol==0) { - if(ob->totcol) { - MEM_freeN(ob->mat); - MEM_freeN(ob->matbits); - ob->mat= NULL; - ob->matbits= NULL; - } - } - else if(ob->totcol<totcol) { - newmatar= MEM_callocN(sizeof(void *)*totcol, "newmatar"); - newmatbits= MEM_callocN(sizeof(char)*totcol, "newmatbits"); - if(ob->totcol) { - memcpy(newmatar, ob->mat, sizeof(void *)*ob->totcol); - memcpy(newmatbits, ob->matbits, sizeof(char)*ob->totcol); - MEM_freeN(ob->mat); - MEM_freeN(ob->matbits); - } - ob->mat= newmatar; - ob->matbits= newmatbits; - } - ob->totcol= totcol; - if(ob->totcol && ob->actcol==0) ob->actcol= 1; - if(ob->actcol>ob->totcol) ob->actcol= ob->totcol; + resize_object_material(ob, *totcol); } - ob= ob->id.next; } } - void assign_material(Object *ob, Material *ma, int act) { Material *mao, **matar, ***matarar; diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 20ef7f04daf..1fcbb95156b 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -106,6 +106,7 @@ #include "BKE_lattice.h" #include "BKE_library.h" // for which_libbase #include "BKE_idcode.h" +#include "BKE_material.h" #include "BKE_main.h" // for Main #include "BKE_mesh.h" // for ME_ defines (patching) #include "BKE_modifier.h" @@ -3507,7 +3508,7 @@ static void lib_link_object(FileData *fd, Main *main) poin= ob->data; ob->data= newlibadr_us(fd, ob->id.lib, ob->data); - + if(ob->data==NULL && poin!=NULL) { if(ob->id.lib) printf("Can't find obdata of %s lib %s\n", ob->id.name+2, ob->id.lib->name); @@ -3525,6 +3526,17 @@ static void lib_link_object(FileData *fd, Main *main) } for(a=0; a<ob->totcol; a++) ob->mat[a]= newlibadr_us(fd, ob->id.lib, ob->mat[a]); + /* When the object is local and the data is library its possible + * the material list size gets out of sync. [#22663] */ + if(ob->data && ob->id.lib != ((ID *)ob->data)->lib) { + short *totcol_data= give_totcolp(ob); + /* Only expand so as not to loose any object materials that might be set. */ + if(totcol_data && *totcol_data > ob->totcol) { + /* printf("'%s' %d -> %d\n", ob->id.name, ob->totcol, *totcol_data); */ + resize_object_material(ob, *totcol_data); + } + } + ob->gpd= newlibadr_us(fd, ob->id.lib, ob->gpd); ob->duplilist= NULL; |