Fix T91691: Selecting "Remove unused slots" in Materials panel removes slots that are assigned to particle systems/hair.

`BKE_object_material_slot_used` would only check obdata usages, but
particle settings can also (weirdly enough) use objects' material slots.

So now, as its name suggests, `BKE_object_material_slot_used` does take
an object as parameter, and also checks for potential slot usage from
psys in the object.
This commit is contained in:
Bastien Montagne 2021-09-27 18:07:01 +02:00
parent 824733ea47
commit 6578db57cd
Notes: blender-bot 2023-02-14 08:38:11 +01:00
Referenced by issue #91691, Selecting "Remove unused slots" in Materials panel removes slots that are assigned to particle systems/hair
7 changed files with 27 additions and 14 deletions

View File

@ -90,7 +90,7 @@ void BKE_object_material_array_assign(struct Main *bmain,
short BKE_object_material_slot_find_index(struct Object *ob, struct Material *ma);
bool BKE_object_material_slot_add(struct Main *bmain, struct Object *ob);
bool BKE_object_material_slot_remove(struct Main *bmain, struct Object *ob);
bool BKE_object_material_slot_used(struct ID *id, short actcol);
bool BKE_object_material_slot_used(struct Object *object, short actcol);
struct Material *BKE_gpencil_material(struct Object *ob, short act);
struct MaterialGPencilStyle *BKE_gpencil_material_settings(struct Object *ob, short act);

View File

@ -543,7 +543,7 @@ void BKE_gpencil_convert_curve(Main *bmain,
int actcol = ob_gp->actcol;
for (int slot = 1; slot <= ob_gp->totcol; slot++) {
while (slot <= ob_gp->totcol && !BKE_object_material_slot_used(ob_gp->data, slot)) {
while (slot <= ob_gp->totcol && !BKE_object_material_slot_used(ob_gp, slot)) {
ob_gp->actcol = slot;
BKE_object_material_slot_remove(bmain, ob_gp);

View File

@ -46,6 +46,7 @@
#include "DNA_meta_types.h"
#include "DNA_node_types.h"
#include "DNA_object_types.h"
#include "DNA_particle_types.h"
#include "DNA_pointcloud_types.h"
#include "DNA_scene_types.h"
#include "DNA_volume_types.h"
@ -73,6 +74,7 @@
#include "BKE_material.h"
#include "BKE_mesh.h"
#include "BKE_node.h"
#include "BKE_object.h"
#include "BKE_scene.h"
#include "DEG_depsgraph.h"
@ -462,21 +464,33 @@ static void material_data_index_remove_id(ID *id, short index)
}
}
bool BKE_object_material_slot_used(ID *id, short actcol)
bool BKE_object_material_slot_used(Object *object, short actcol)
{
/* ensure we don't try get materials from non-obdata */
BLI_assert(OB_DATA_SUPPORT_ID(GS(id->name)));
if (!BKE_object_supports_material_slots(object)) {
return false;
}
switch (GS(id->name)) {
LISTBASE_FOREACH (ParticleSystem *, psys, &object->particlesystem) {
if (psys->part->omat == actcol) {
return true;
}
}
ID *ob_data = object->data;
if (ob_data == NULL || !OB_DATA_SUPPORT_ID(GS(ob_data->name))) {
return false;
}
switch (GS(ob_data->name)) {
case ID_ME:
return BKE_mesh_material_index_used((Mesh *)id, actcol - 1);
return BKE_mesh_material_index_used((Mesh *)ob_data, actcol - 1);
case ID_CU:
return BKE_curve_material_index_used((Curve *)id, actcol - 1);
return BKE_curve_material_index_used((Curve *)ob_data, actcol - 1);
case ID_MB:
/* Meta-elements don't support materials at the moment. */
return false;
case ID_GD:
return BKE_gpencil_material_index_used((bGPdata *)id, actcol - 1);
return BKE_gpencil_material_index_used((bGPdata *)ob_data, actcol - 1);
default:
return false;
}

View File

@ -4729,7 +4729,7 @@ static int gpencil_stroke_separate_exec(bContext *C, wmOperator *op)
/* Remove unused slots. */
int actcol = ob_dst->actcol;
for (int slot = 1; slot <= ob_dst->totcol; slot++) {
while (slot <= ob_dst->totcol && !BKE_object_material_slot_used(ob_dst->data, slot)) {
while (slot <= ob_dst->totcol && !BKE_object_material_slot_used(ob_dst, slot)) {
ob_dst->actcol = slot;
BKE_object_material_slot_remove(bmain, ob_dst);
if (actcol >= slot) {

View File

@ -345,7 +345,7 @@ static int gpencil_bake_mesh_animation_exec(bContext *C, wmOperator *op)
/* Remove unused materials. */
int actcol = ob_gpencil->actcol;
for (int slot = 1; slot <= ob_gpencil->totcol; slot++) {
while (slot <= ob_gpencil->totcol && !BKE_object_material_slot_used(ob_gpencil->data, slot)) {
while (slot <= ob_gpencil->totcol && !BKE_object_material_slot_used(ob_gpencil, slot)) {
ob_gpencil->actcol = slot;
BKE_object_material_slot_remove(CTX_data_main(C), ob_gpencil);

View File

@ -2828,8 +2828,7 @@ static int object_convert_exec(bContext *C, wmOperator *op)
/* Remove unused materials. */
int actcol = ob_gpencil->actcol;
for (int slot = 1; slot <= ob_gpencil->totcol; slot++) {
while (slot <= ob_gpencil->totcol &&
!BKE_object_material_slot_used(ob_gpencil->data, slot)) {
while (slot <= ob_gpencil->totcol && !BKE_object_material_slot_used(ob_gpencil, slot)) {
ob_gpencil->actcol = slot;
BKE_object_material_slot_remove(CTX_data_main(C), ob_gpencil);

View File

@ -690,7 +690,7 @@ static int material_slot_remove_unused_exec(bContext *C, wmOperator *op)
Object *ob = objects[ob_index];
int actcol = ob->actcol;
for (int slot = 1; slot <= ob->totcol; slot++) {
while (slot <= ob->totcol && !BKE_object_material_slot_used(ob->data, slot)) {
while (slot <= ob->totcol && !BKE_object_material_slot_used(ob, slot)) {
ob->actcol = slot;
BKE_object_material_slot_remove(bmain, ob);