From b9fba005bdd4400902bd3ed43b260d6e79949820 Mon Sep 17 00:00:00 2001 From: Antonio Vazquez Date: Tue, 28 Nov 2023 16:38:59 +0100 Subject: [PATCH] GPv3: Lock unselect materials operator Conversion of GPv2 operator Pull Request: https://projects.blender.org/blender/blender/pulls/115278 --- .../bl_ui/properties_material_gpencil.py | 1 + .../intern/grease_pencil_material.cc | 81 +++++++++++++++++++ 2 files changed, 82 insertions(+) diff --git a/scripts/startup/bl_ui/properties_material_gpencil.py b/scripts/startup/bl_ui/properties_material_gpencil.py index 5711f1f2763..53246ef8b57 100644 --- a/scripts/startup/bl_ui/properties_material_gpencil.py +++ b/scripts/startup/bl_ui/properties_material_gpencil.py @@ -25,6 +25,7 @@ class GPENCIL_MT_material_context_menu(Menu): layout.operator("grease_pencil.material_lock_all", icon='LOCKED', text="Lock All") layout.operator("grease_pencil.material_unlock_all", icon='UNLOCKED', text="Unlock All") + layout.operator("grease_pencil.material_lock_unselected", text="Lock Unselected") layout.operator("grease_pencil.material_lock_unused", text="Lock Unused") else: layout.operator("gpencil.material_reveal", icon='RESTRICT_VIEW_OFF', text="Show All") diff --git a/source/blender/editors/grease_pencil/intern/grease_pencil_material.cc b/source/blender/editors/grease_pencil/intern/grease_pencil_material.cc index be22e1c7bce..060104342d0 100644 --- a/source/blender/editors/grease_pencil/intern/grease_pencil_material.cc +++ b/source/blender/editors/grease_pencil/intern/grease_pencil_material.cc @@ -9,9 +9,13 @@ #include "DNA_material_types.h" #include "BKE_context.hh" +#include "BKE_curves_utils.hh" #include "BKE_grease_pencil.hh" #include "BKE_material.h" +#include "BLI_vector.hh" +#include "BLI_vector_set.hh" + #include "DEG_depsgraph.hh" #include "ED_grease_pencil.hh" @@ -253,6 +257,82 @@ static void GREASE_PENCIL_OT_material_lock_unused(wmOperatorType *ot) /** \} */ +/* -------------------------------------------------------------------- */ +/** \name Lock Unselected Materials Operator + * \{ */ + +static int grease_pencil_material_lock_unselected_exec(bContext *C, wmOperator * /*op*/) +{ + using namespace blender; + using namespace blender::bke; + + const Scene *scene = CTX_data_scene(C); + Object *object = CTX_data_active_object(C); + GreasePencil &grease_pencil = *static_cast(object->data); + + bool changed = false; + const Array drawings = retrieve_editable_drawings(*scene, grease_pencil); + + Set materials_used; + + for (const MutableDrawingInfo &info : drawings) { + IndexMaskMemory memory; + const IndexMask strokes = ed::greasepencil::retrieve_editable_and_selected_strokes( + *object, info.drawing, memory); + if (strokes.is_empty()) { + return OPERATOR_CANCELLED; + } + + AttributeAccessor attributes = info.drawing.strokes().attributes(); + const VArray material_indices = *attributes.lookup_or_default( + "material_index", ATTR_DOMAIN_CURVE, 0); + + if (const std::optional single = material_indices.get_if_single()) { + materials_used.add(*single); + } + else { + strokes.foreach_index([&](const int i) { materials_used.add(material_indices[i]); }); + } + }; + + /* The material lock must be done outside of the drawing loop to prevent + * 'retrieve_editable_and_selected_strokes' from returning an incorrect IndexMask. + */ + for (const int i : IndexRange(object->totcol)) { + if (!materials_used.contains(i)) { + if (Material *ma = BKE_object_material_get(object, i + 1)) { + MaterialGPencilStyle &gp_style = *ma->gp_style; + gp_style.flag |= GP_MATERIAL_LOCKED; + DEG_id_tag_update(&ma->id, ID_RECALC_COPY_ON_WRITE); + changed = true; + } + } + } + + if (changed) { + DEG_id_tag_update(&grease_pencil.id, ID_RECALC_GEOMETRY); + WM_event_add_notifier(C, NC_GEOM | ND_DATA | NA_EDITED, &grease_pencil); + } + + return OPERATOR_FINISHED; +} + +static void GREASE_PENCIL_OT_material_lock_unselected(wmOperatorType *ot) +{ + /* Identifiers. */ + ot->name = "Lock Unselected Materials"; + ot->idname = "GREASE_PENCIL_OT_material_lock_unselected"; + ot->description = "Lock any material not used in any selected stroke"; + + /* Callbacks. */ + ot->exec = grease_pencil_material_lock_unselected_exec; + ot->poll = active_grease_pencil_poll; + + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + +/** \} */ + } // namespace blender::ed::greasepencil void ED_operatortypes_grease_pencil_material() @@ -263,4 +343,5 @@ void ED_operatortypes_grease_pencil_material() WM_operatortype_append(GREASE_PENCIL_OT_material_lock_all); WM_operatortype_append(GREASE_PENCIL_OT_material_unlock_all); WM_operatortype_append(GREASE_PENCIL_OT_material_lock_unused); + WM_operatortype_append(GREASE_PENCIL_OT_material_lock_unselected); }