bugfix [#28111] material.pop breaks mt->mat_nr

create a new parameter for materials.pop() to not remove material slot.
this way the mat_nr is still the old one.

for the default behaviour we now have material remapping (i.e. data_delete_material_index_id(id, index)).
This new function is brought from the material_slot remove function.
This commit is contained in:
Dalai Felinto 2011-07-31 11:12:38 +00:00
parent f4a1dc4c8d
commit 432bd158fb
4 changed files with 67 additions and 43 deletions

@ -78,7 +78,7 @@ int object_remove_material_slot(struct Object *ob);
/* rna api */
void material_append_id(struct ID *id, struct Material *ma);
struct Material *material_pop_id(struct ID *id, int index);
struct Material *material_pop_id(struct ID *id, int index, int remove_material_slot);
/* rendering */

@ -61,7 +61,7 @@
#include "BKE_material.h"
#include "BKE_mesh.h"
#include "BKE_node.h"
#include "BKE_curve.h"
#include "GPU_material.h"
@ -515,6 +515,37 @@ short *give_totcolp_id(ID *id)
return NULL;
}
void data_delete_material_index_id(ID *id, int index)
{
Mesh *me;
Curve *cu;
Nurb *nu;
int curvetype;
switch(GS(id->name)) {
case ID_ME:
me=(Mesh *)id;
mesh_delete_material_index(me, index);
break;
case ID_CU:
cu= (Curve *)id;
nu= cu->nurb.first;
curvetype=curve_type(cu);
if (!ELEM(curvetype, OB_CURVE, OB_SURF))
return;
while (nu) {
if(nu->mat_nr && nu->mat_nr>=index) {
nu->mat_nr--;
if (curvetype == OB_CURVE) nu->charidx--;
}
nu= nu->next;
}
break;
}
}
void material_append_id(ID *id, Material *ma)
{
Material ***matar;
@ -532,7 +563,7 @@ void material_append_id(ID *id, Material *ma)
}
}
Material *material_pop_id(ID *id, int index)
Material *material_pop_id(ID *id, int index, int remove_material_slot)
{
Material *ret= NULL;
Material ***matar;
@ -540,27 +571,36 @@ Material *material_pop_id(ID *id, int index)
short *totcol= give_totcolp_id(id);
if(index >= 0 && index < (*totcol)) {
ret= (*matar)[index];
id_us_min((ID *)ret);
if(*totcol <= 1) {
*totcol= 0;
MEM_freeN(*matar);
*matar= NULL;
id_us_min((ID *)ret);
if (remove_material_slot) {
if(*totcol <= 1) {
*totcol= 0;
MEM_freeN(*matar);
*matar= NULL;
}
else {
Material **mat;
if(index + 1 != (*totcol))
memmove((*matar)+index, (*matar)+(index+1), sizeof(void *) * ((*totcol) - (index + 1)));
(*totcol)--;
mat= MEM_callocN(sizeof(void *) * (*totcol), "newmatar");
memcpy(mat, *matar, sizeof(void *) * (*totcol));
MEM_freeN(*matar);
*matar= mat;
test_object_materials(id);
}
/* decrease mat_nr index */
data_delete_material_index_id(id, index);
}
else {
Material **mat;
if(index + 1 != (*totcol))
memmove((*matar)+index, (*matar)+(index+1), sizeof(void *) * ((*totcol) - (index + 1)));
(*totcol)--;
mat= MEM_callocN(sizeof(void *) * (*totcol), "newmatar");
memcpy(mat, *matar, sizeof(void *) * (*totcol));
MEM_freeN(*matar);
*matar= mat;
test_object_materials(id);
}
/* don't remove material slot, only clear it*/
else
(*matar)[index]= NULL;
}
}
@ -1025,8 +1065,6 @@ int object_remove_material_slot(Object *ob)
{
Material *mao, ***matarar;
Object *obt;
Curve *cu;
Nurb *nu;
short *totcolp;
int a, actcol;
@ -1086,23 +1124,8 @@ int object_remove_material_slot(Object *ob)
}
/* check indices from mesh */
if(ob->type==OB_MESH) {
Mesh *me= get_mesh(ob);
mesh_delete_material_index(me, actcol-1);
freedisplist(&ob->disp);
}
else if ELEM(ob->type, OB_CURVE, OB_SURF) {
cu= ob->data;
nu= cu->nurb.first;
while(nu) {
if(nu->mat_nr && nu->mat_nr>=actcol-1) {
nu->mat_nr--;
if (ob->type == OB_CURVE) nu->charidx--;
}
nu= nu->next;
}
if (ELEM3(ob->type, OB_MESH, OB_CURVE, OB_SURF)) {
data_delete_material_index_id(&ob->id, actcol-1);
freedisplist(&ob->disp);
}

@ -1254,10 +1254,10 @@ void mesh_to_curve(Scene *scene, Object *ob)
void mesh_delete_material_index(Mesh *me, int index)
{
MFace *mf;
int i;
for (i=0; i<me->totface; i++) {
MFace *mf = &((MFace*) me->mface)[i];
for (i=0, mf=me->mface; i<me->totface; i++, mf++) {
if (mf->mat_nr && mf->mat_nr>=index)
mf->mat_nr--;
}

@ -418,6 +418,7 @@ static void rna_def_ID_materials(BlenderRNA *brna)
RNA_def_function_ui_description(func, "Remove a material from the data block.");
parm= RNA_def_int(func, "index", 0, 0, INT_MAX, "", "Index of material to remove.", 0, INT_MAX);
RNA_def_property_flag(parm, PROP_REQUIRED);
RNA_def_boolean(func, "remove_material_slot", 1, "", "Remove the material slot and assign 1st material to old faces.");
parm= RNA_def_pointer(func, "material", "Material", "", "Material to remove.");
RNA_def_function_return(func, parm);
}