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:
authorCampbell Barton <ideasman42@gmail.com>2020-08-30 06:33:35 +0300
committerCampbell Barton <ideasman42@gmail.com>2020-08-30 06:48:30 +0300
commit1a650fdcb286ad3759c65a9952aa2e02966eba0b (patch)
tree3cdff242e5c707ce1a54cfa6d20f18b816e67917 /source/blender/editors/render
parent47908f015551fa5acf1359b3f1c0e1930856af83 (diff)
Object: support removing unused material slots for selected objects
This is useful to run in object-mode, instead of from the property editor, note that this still only used the current object when activated from the property editor.
Diffstat (limited to 'source/blender/editors/render')
-rw-r--r--source/blender/editors/render/render_shading.c187
1 files changed, 131 insertions, 56 deletions
diff --git a/source/blender/editors/render/render_shading.c b/source/blender/editors/render/render_shading.c
index 3f31cbf7e48..078817e091a 100644
--- a/source/blender/editors/render/render_shading.c
+++ b/source/blender/editors/render/render_shading.c
@@ -56,6 +56,7 @@
#include "BKE_linestyle.h"
#include "BKE_main.h"
#include "BKE_material.h"
+#include "BKE_object.h"
#include "BKE_paint.h"
#include "BKE_report.h"
#include "BKE_scene.h"
@@ -95,42 +96,114 @@
#include "render_intern.h" // own include
+static bool object_materials_supported_poll_ex(bContext *C, const Object *ob);
+
/* -------------------------------------------------------------------- */
/** \name Local Utilities
* \{ */
-/**
- * Object list for material operations.
- * has exception for pinned object.
- */
-static Object **object_array_for_shading(bContext *C, uint *r_objects_len)
-{
- ScrArea *area = CTX_wm_area(C);
- SpaceProperties *sbuts = NULL;
- View3D *v3d = NULL;
- if (area != NULL) {
- if (area->spacetype == SPACE_PROPERTIES) {
- sbuts = area->spacedata.first;
- }
- else if (area->spacetype == SPACE_VIEW3D) {
- v3d = area->spacedata.first;
- }
+static Object **object_array_for_shading_impl(bContext *C,
+ bool (*filter_fn)(struct Object *ob,
+ void *user_data),
+ void *filter_user_data,
+ uint *r_objects_len)
+{
+ Object **objects;
+
+ Object *ob = NULL;
+ bool use_ob = true;
+ if (CTX_wm_space_properties(C)) {
+ /* May return pinned object. */
+ ob = ED_object_context(C);
+ }
+ else {
+ /* Otherwise use full selection. */
+ use_ob = false;
}
- Object **objects;
- if (sbuts != NULL && sbuts->pinid && GS(sbuts->pinid->name) == ID_OB) {
- objects = MEM_mallocN(sizeof(*objects), __func__);
- objects[0] = (Object *)sbuts->pinid;
- *r_objects_len = 1;
+ if (use_ob) {
+ if (!filter_fn(ob, filter_user_data)) {
+ ob = NULL;
+ }
+ *r_objects_len = (ob != NULL) ? 1 : 0;
+ objects = MEM_mallocN(sizeof(*objects) * *r_objects_len, __func__);
+ if (ob != NULL) {
+ objects[0] = ob;
+ }
}
else {
ViewLayer *view_layer = CTX_data_view_layer(C);
- objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, v3d, r_objects_len);
+ const View3D *v3d = CTX_wm_view3d(C); /* may be NULL. */
+ objects = BKE_view_layer_array_selected_objects_params(
+ view_layer,
+ v3d,
+ r_objects_len,
+ &((const struct ObjectsInViewLayerParams){
+ .no_dup_data = true,
+ .filter_fn = filter_fn,
+ .filter_userdata = filter_user_data,
+ }));
}
return objects;
}
+static bool object_array_for_shading_edit_mode_enabled_filter(Object *ob, void *user_data)
+{
+ bContext *C = user_data;
+ if (object_materials_supported_poll_ex(C, ob)) {
+ if (BKE_object_is_in_editmode(ob) == true) {
+ return true;
+ }
+ }
+ return false;
+}
+
+static Object **object_array_for_shading_edit_mode_enabled(bContext *C, uint *r_objects_len)
+{
+ return object_array_for_shading_impl(
+ C, object_array_for_shading_edit_mode_enabled_filter, C, r_objects_len);
+}
+
+static bool object_array_for_shading_edit_mode_disabled_filter(Object *ob, void *user_data)
+{
+ bContext *C = user_data;
+ if (object_materials_supported_poll_ex(C, ob)) {
+ if (BKE_object_is_in_editmode(ob) == false) {
+ return true;
+ }
+ }
+ return false;
+}
+
+static Object **object_array_for_shading_edit_mode_disabled(bContext *C, uint *r_objects_len)
+{
+ return object_array_for_shading_impl(
+ C, object_array_for_shading_edit_mode_disabled_filter, C, r_objects_len);
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Shared Operator Poll Functions
+ * \{ */
+
+static bool object_materials_supported_poll_ex(bContext *C, const Object *ob)
+{
+ if (!ED_operator_object_active_local_editable_ex(C, ob)) {
+ return false;
+ }
+ const ID *data = ob->data;
+ return (OB_TYPE_SUPPORT_MATERIAL(ob->type) &&
+ /* Object data checks. */
+ data && !ID_IS_LINKED(data) && !ID_IS_OVERRIDE_LIBRARY(data));
+}
+
+static bool object_materials_supported_poll(bContext *C)
+{
+ Object *ob = ED_object_context(C);
+ return object_materials_supported_poll_ex(C, ob);
+}
+
/** \} */
/* -------------------------------------------------------------------- */
@@ -170,7 +243,7 @@ void OBJECT_OT_material_slot_add(wmOperatorType *ot)
/* api callbacks */
ot->exec = material_slot_add_exec;
- ot->poll = ED_operator_object_active_local_editable;
+ ot->poll = object_materials_supported_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
@@ -221,7 +294,7 @@ void OBJECT_OT_material_slot_remove(wmOperatorType *ot)
/* api callbacks */
ot->exec = material_slot_remove_exec;
- ot->poll = ED_operator_object_active_local_editable;
+ ot->poll = object_materials_supported_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
@@ -242,7 +315,7 @@ static int material_slot_assign_exec(bContext *C, wmOperator *UNUSED(op))
const Material *mat_active = obact ? BKE_object_material_get(obact, obact->actcol) : NULL;
uint objects_len = 0;
- Object **objects = object_array_for_shading(C, &objects_len);
+ Object **objects = object_array_for_shading_edit_mode_enabled(C, &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *ob = objects[ob_index];
short mat_nr_active = -1;
@@ -330,7 +403,7 @@ void OBJECT_OT_material_slot_assign(wmOperatorType *ot)
/* api callbacks */
ot->exec = material_slot_assign_exec;
- ot->poll = ED_operator_object_active_local_editable;
+ ot->poll = object_materials_supported_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
@@ -349,7 +422,7 @@ static int material_slot_de_select(bContext *C, bool select)
const Material *mat_active = obact ? BKE_object_material_get(obact, obact->actcol) : NULL;
uint objects_len = 0;
- Object **objects = object_array_for_shading(C, &objects_len);
+ Object **objects = object_array_for_shading_edit_mode_enabled(C, &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *ob = objects[ob_index];
short mat_nr_active = -1;
@@ -614,8 +687,8 @@ void OBJECT_OT_material_slot_move(wmOperatorType *ot)
ot->description = "Move the active material up/down in the list";
/* api callbacks */
- ot->poll = ED_operator_object_active_local_editable;
ot->exec = material_slot_move_exec;
+ ot->poll = object_materials_supported_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -636,35 +709,38 @@ void OBJECT_OT_material_slot_move(wmOperatorType *ot)
static int material_slot_remove_unused_exec(bContext *C, wmOperator *op)
{
- Object *ob = CTX_data_active_object(C);
-
- if (!ob) {
- return OPERATOR_CANCELLED;
- }
-
/* Removing material slots in edit mode screws things up, see bug #21822.*/
- if (ob == CTX_data_edit_object(C)) {
+ Object *ob_active = CTX_data_active_object(C);
+ if (ob_active && BKE_object_is_in_editmode(ob_active)) {
BKE_report(op->reports, RPT_ERROR, "Unable to remove material slot in edit mode");
return OPERATOR_CANCELLED;
}
- int actcol = ob->actcol;
-
+ Main *bmain = CTX_data_main(C);
int removed = 0;
- for (int slot = 1; slot <= ob->totcol; slot++) {
- while (slot <= ob->totcol && !BKE_object_material_slot_used(ob->data, slot)) {
- ob->actcol = slot;
- BKE_object_material_slot_remove(CTX_data_main(C), ob);
- if (actcol >= slot) {
- actcol--;
- }
+ uint objects_len = 0;
+ Object **objects = object_array_for_shading_edit_mode_disabled(C, &objects_len);
+ for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
+ 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)) {
+ ob->actcol = slot;
+ BKE_object_material_slot_remove(bmain, ob);
+
+ if (actcol >= slot) {
+ actcol--;
+ }
- removed++;
+ removed++;
+ }
}
- }
+ ob->actcol = actcol;
- ob->actcol = actcol;
+ DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
+ }
+ MEM_freeN(objects);
if (!removed) {
return OPERATOR_CANCELLED;
@@ -672,16 +748,15 @@ static int material_slot_remove_unused_exec(bContext *C, wmOperator *op)
BKE_reportf(op->reports, RPT_INFO, "Removed %d slots", removed);
- if (ob->mode & OB_MODE_TEXTURE_PAINT) {
+ if (ob_active->mode & OB_MODE_TEXTURE_PAINT) {
Scene *scene = CTX_data_scene(C);
- BKE_paint_proj_mesh_data_check(scene, ob, NULL, NULL, NULL, NULL);
+ BKE_paint_proj_mesh_data_check(scene, ob_active, NULL, NULL, NULL, NULL);
WM_event_add_notifier(C, NC_SCENE | ND_TOOLSETTINGS, NULL);
}
- DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
- WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
- WM_event_add_notifier(C, NC_OBJECT | ND_OB_SHADING, ob);
- WM_event_add_notifier(C, NC_MATERIAL | ND_SHADING_PREVIEW, ob);
+ WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob_active);
+ WM_event_add_notifier(C, NC_OBJECT | ND_OB_SHADING, ob_active);
+ WM_event_add_notifier(C, NC_MATERIAL | ND_SHADING_PREVIEW, ob_active);
return OPERATOR_FINISHED;
}
@@ -695,7 +770,7 @@ void OBJECT_OT_material_slot_remove_unused(wmOperatorType *ot)
/* api callbacks */
ot->exec = material_slot_remove_unused_exec;
- ot->poll = ED_operator_object_active_local_editable;
+ ot->poll = object_materials_supported_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -768,8 +843,8 @@ void MATERIAL_OT_new(wmOperatorType *ot)
ot->description = "Add a new material";
/* api callbacks */
- ot->poll = ED_operator_object_active_local_editable;
ot->exec = new_material_exec;
+ ot->poll = object_materials_supported_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;