bugfix [#28111] material.pop breaks mt->mat_nr
authorDalai Felinto <dfelinto@gmail.com>
Sun, 31 Jul 2011 11:12:38 +0000 (11:12 +0000)
committerDalai Felinto <dfelinto@gmail.com>
Sun, 31 Jul 2011 11:12:38 +0000 (11:12 +0000)
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.

source/blender/blenkernel/BKE_material.h
source/blender/blenkernel/intern/material.c
source/blender/blenkernel/intern/mesh.c
source/blender/makesrna/intern/rna_ID.c

index c445408609cd0c4c28138d820e4cfd2f1d150fcd..88965d12e4a4d8f776bcb35dd1a8e49512f04dba 100644 (file)
@@ -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 */
 
index 3f01c55e935bdba3be7115db0fd3556a7cc2bc24..1f2544c9706a33daba85394209c966a635722ac1 100644 (file)
@@ -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;
-                       }
-                       else {
-                               Material **mat;
-
-                               if(index + 1 != (*totcol))
-                                       memmove((*matar)+index, (*matar)+(index+1), sizeof(void *) * ((*totcol) - (index + 1)));
+                       id_us_min((ID *)ret);
 
-                               (*totcol)--;
-                               
-                               mat= MEM_callocN(sizeof(void *) * (*totcol), "newmatar");
-                               memcpy(mat, *matar, sizeof(void *) * (*totcol));
-                               MEM_freeN(*matar);
+                       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);
+                               }
 
-                               *matar= mat;
-                               test_object_materials(id);
+                               /* decrease mat_nr index */
+                               data_delete_material_index_id(id, index);
                        }
+
+                       /* 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);
        }
 
index 45a60b842a7e633e29a9387b15a14f2bf14a96c5..328192263612c637759c1814ad86d951b2110a75 100644 (file)
@@ -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--;
        }
index 3ce84e3a19f91a9bc037541080bd3ae9ad728aca..6d7fc0ee57bf7d081a3c5e9e70c0dce5804d8c67 100644 (file)
@@ -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);
 }