GPv3: Lock material layer property #119913

Open
Pratik Borhade wants to merge 6 commits from PratikPB2123/blender:gpv3-lock-material-layer-prop into main

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.
11 changed files with 78 additions and 51 deletions

View File

@ -84,6 +84,7 @@ class GREASE_PENCIL_MT_grease_pencil_add_layer_extra(Menu):
layout = self.layout
ob = context.object
grease_pencil = ob.data
layer = grease_pencil.layers.active
space = context.space_data
if space.type == 'PROPERTIES':
@ -103,6 +104,7 @@ class GREASE_PENCIL_MT_grease_pencil_add_layer_extra(Menu):
layout.separator()
layout.prop(grease_pencil, "use_autolock_layers", text="Autolock Inactive Layers")
layout.prop(layer, "use_locked_material")
class DATA_PT_grease_pencil_layers(DataButtonsPanel, Panel):

View File

@ -461,7 +461,7 @@ static void grease_pencil_edit_batch_ensure(Object &object,
const VArray<bool> cyclic = curves.cyclic();
IndexMaskMemory memory;
const IndexMask editable_strokes = ed::greasepencil::retrieve_editable_strokes(
object, info.drawing, memory);
object, info.drawing, info.layer_index, memory);
/* Assumes that if the ".selection" attribute does not exist, all points are selected. */
const VArray<float> selection_float = *attributes.lookup_or_default<float>(
@ -531,7 +531,7 @@ static void grease_pencil_edit_batch_ensure(Object &object,
const VArray<bool> cyclic = curves.cyclic();
IndexMaskMemory memory;
const IndexMask editable_strokes = ed::greasepencil::retrieve_editable_strokes(
object, info.drawing, memory);
object, info.drawing, info.layer_index, memory);
/* Fill line indices. */
editable_strokes.foreach_index([&](const int curve_i) {

View File

@ -80,7 +80,7 @@ static int grease_pencil_stroke_smooth_exec(bContext *C, wmOperator *op)
IndexMaskMemory memory;
const IndexMask strokes = ed::greasepencil::retrieve_editable_and_selected_strokes(
*object, info.drawing, memory);
*object, info, memory);
if (strokes.is_empty()) {
return;
}
@ -242,7 +242,7 @@ static int grease_pencil_stroke_simplify_exec(bContext *C, wmOperator *op)
IndexMaskMemory memory;
const IndexMask strokes = ed::greasepencil::retrieve_editable_and_selected_strokes(
*object, info.drawing, memory);
*object, info, memory);
if (strokes.is_empty()) {
return;
}
@ -452,7 +452,7 @@ static int grease_pencil_delete_exec(bContext *C, wmOperator * /*op*/)
threading::parallel_for_each(drawings, [&](const MutableDrawingInfo &info) {
IndexMaskMemory memory;
const IndexMask elements = ed::greasepencil::retrieve_editable_and_selected_elements(
*object, info.drawing, selection_domain, memory);
*object, info, selection_domain, memory);
if (elements.is_empty()) {
return;
}
@ -599,7 +599,7 @@ static int grease_pencil_dissolve_exec(bContext *C, wmOperator *op)
IndexMaskMemory memory;
const IndexMask points = ed::greasepencil::retrieve_editable_and_selected_points(
*object, info.drawing, memory);
*object, info, memory);
if (points.is_empty()) {
return;
}
@ -768,7 +768,7 @@ static int grease_pencil_stroke_material_set_exec(bContext *C, wmOperator *op)
threading::parallel_for_each(drawings, [&](const MutableDrawingInfo &info) {
IndexMaskMemory memory;
IndexMask strokes = ed::greasepencil::retrieve_editable_and_selected_strokes(
*object, info.drawing, memory);
*object, info, memory);
if (strokes.is_empty()) {
return;
}
@ -843,7 +843,7 @@ static int grease_pencil_cyclical_set_exec(bContext *C, wmOperator *op)
IndexMaskMemory memory;
const IndexMask strokes = ed::greasepencil::retrieve_editable_and_selected_strokes(
*object, info.drawing, memory);
*object, info, memory);
if (strokes.is_empty()) {
return;
}
@ -918,7 +918,7 @@ static int grease_pencil_set_active_material_exec(bContext *C, wmOperator * /*op
for (const MutableDrawingInfo &info : drawings) {
IndexMaskMemory memory;
const IndexMask strokes = ed::greasepencil::retrieve_editable_and_selected_strokes(
*object, info.drawing, memory);
*object, info, memory);
if (strokes.is_empty()) {
continue;
}
@ -966,7 +966,7 @@ static int grease_pencil_set_uniform_thickness_exec(bContext *C, wmOperator *op)
threading::parallel_for_each(drawings, [&](const MutableDrawingInfo &info) {
IndexMaskMemory memory;
const IndexMask strokes = ed::greasepencil::retrieve_editable_and_selected_strokes(
*object, info.drawing, memory);
*object, info, memory);
if (strokes.is_empty()) {
return;
}
@ -1023,7 +1023,7 @@ static int grease_pencil_set_uniform_opacity_exec(bContext *C, wmOperator *op)
threading::parallel_for_each(drawings, [&](const MutableDrawingInfo &info) {
IndexMaskMemory memory;
const IndexMask strokes = ed::greasepencil::retrieve_editable_and_selected_strokes(
*object, info.drawing, memory);
*object, info, memory);
if (strokes.is_empty()) {
return;
}
@ -1078,7 +1078,7 @@ static int grease_pencil_stroke_switch_direction_exec(bContext *C, wmOperator *
threading::parallel_for_each(drawings, [&](const MutableDrawingInfo &info) {
IndexMaskMemory memory;
const IndexMask strokes = ed::greasepencil::retrieve_editable_and_selected_strokes(
*object, info.drawing, memory);
*object, info, memory);
if (strokes.is_empty()) {
return;
}
@ -1155,7 +1155,7 @@ static int grease_pencil_caps_set_exec(bContext *C, wmOperator *op)
bke::CurvesGeometry &curves = info.drawing.strokes_for_write();
IndexMaskMemory memory;
const IndexMask strokes = ed::greasepencil::retrieve_editable_and_selected_strokes(
*object, info.drawing, memory);
*object, info, memory);
if (strokes.is_empty()) {
return;
}
@ -1330,7 +1330,7 @@ static int grease_pencil_duplicate_exec(bContext *C, wmOperator * /*op*/)
threading::parallel_for_each(drawings, [&](const MutableDrawingInfo &info) {
IndexMaskMemory memory;
const IndexMask elements = retrieve_editable_and_selected_elements(
*object, info.drawing, selection_domain, memory);
*object, info, selection_domain, memory);
if (elements.is_empty()) {
return;
}
@ -1382,7 +1382,7 @@ static int grease_pencil_clean_loose_exec(bContext *C, wmOperator *op)
IndexMaskMemory memory;
const IndexMask editable_strokes = ed::greasepencil::retrieve_editable_strokes(
*object, info.drawing, memory);
*object, info.drawing, info.layer_index, memory);
const IndexMask curves_to_delete = IndexMask::from_predicate(
editable_strokes, GrainSize(4096), memory, [&](const int i) {
@ -1445,7 +1445,7 @@ static int gpencil_stroke_subdivide_exec(bContext *C, wmOperator *op)
threading::parallel_for_each(drawings, [&](const MutableDrawingInfo &info) {
IndexMaskMemory memory;
const IndexMask strokes = ed::greasepencil::retrieve_editable_and_selected_strokes(
*object, info.drawing, memory);
*object, info, memory);
if (strokes.is_empty()) {
return;
}
@ -1641,7 +1641,7 @@ static int grease_pencil_stroke_reorder_exec(bContext *C, wmOperator *op)
threading::parallel_for_each(drawings, [&](const MutableDrawingInfo &info) {
IndexMaskMemory memory;
const IndexMask strokes = ed::greasepencil::retrieve_editable_and_selected_strokes(
*object, info.drawing, memory);
*object, info, memory);
if (strokes.is_empty()) {
return;
}
@ -1988,7 +1988,8 @@ static bool grease_pencil_separate_layer(bContext &C,
for (const MutableDrawingInfo &info : drawings_src) {
bke::CurvesGeometry &curves_src = info.drawing.strokes_for_write();
IndexMaskMemory memory;
const IndexMask strokes = retrieve_editable_strokes(object_src, info.drawing, memory);
const IndexMask strokes = retrieve_editable_strokes(
object_src, info.drawing, info.layer_index, memory);
if (strokes.is_empty()) {
continue;
}

View File

@ -278,7 +278,7 @@ static int grease_pencil_material_lock_unselected_exec(bContext *C, wmOperator *
for (const MutableDrawingInfo &info : drawings) {
IndexMaskMemory memory;
const IndexMask strokes = ed::greasepencil::retrieve_editable_and_selected_strokes(
*object, info.drawing, memory);
*object, info, memory);
if (strokes.is_empty()) {
return OPERATOR_CANCELLED;
}

View File

@ -40,7 +40,7 @@ static int select_all_exec(bContext *C, wmOperator *op)
threading::parallel_for_each(drawings, [&](const MutableDrawingInfo &info) {
IndexMaskMemory memory;
const IndexMask selectable_elements = retrieve_editable_elements(
*object, info.drawing, selection_domain, memory);
*object, info, selection_domain, memory);
if (selectable_elements.is_empty()) {
return;
}
@ -80,7 +80,7 @@ static int select_more_exec(bContext *C, wmOperator * /*op*/)
threading::parallel_for_each(drawings, [&](const MutableDrawingInfo &info) {
IndexMaskMemory memory;
const IndexMask selectable_strokes = ed::greasepencil::retrieve_editable_strokes(
*object, info.drawing, memory);
*object, info.drawing, info.layer_index, memory);
if (selectable_strokes.is_empty()) {
return;
}
@ -118,7 +118,7 @@ static int select_less_exec(bContext *C, wmOperator * /*op*/)
threading::parallel_for_each(drawings, [&](const MutableDrawingInfo &info) {
IndexMaskMemory memory;
const IndexMask selectable_strokes = ed::greasepencil::retrieve_editable_strokes(
*object, info.drawing, memory);
*object, info.drawing, info.layer_index, memory);
if (selectable_strokes.is_empty()) {
return;
}
@ -156,7 +156,7 @@ static int select_linked_exec(bContext *C, wmOperator * /*op*/)
threading::parallel_for_each(drawings, [&](const MutableDrawingInfo &info) {
IndexMaskMemory memory;
const IndexMask selectable_strokes = ed::greasepencil::retrieve_editable_strokes(
*object, info.drawing, memory);
*object, info.drawing, info.layer_index, memory);
if (selectable_strokes.is_empty()) {
return;
}
@ -199,7 +199,7 @@ static int select_random_exec(bContext *C, wmOperator *op)
IndexMaskMemory memory;
const IndexMask selectable_elements = retrieve_editable_elements(
*object, info.drawing, selection_domain, memory);
*object, info, selection_domain, memory);
if (selectable_elements.is_empty()) {
return;
}
@ -298,7 +298,7 @@ static int select_ends_exec(bContext *C, wmOperator *op)
IndexMaskMemory memory;
const IndexMask selectable_strokes = ed::greasepencil::retrieve_editable_strokes(
*object, info.drawing, memory);
*object, info.drawing, info.layer_index, memory);
if (selectable_strokes.is_empty()) {
return;
}
@ -306,7 +306,7 @@ static int select_ends_exec(bContext *C, wmOperator *op)
curves, selectable_strokes, amount_start, amount_end, true, memory);
const IndexMask selectable_points = ed::greasepencil::retrieve_editable_points(
*object, info.drawing, memory);
*object, info.drawing, info.layer_index, memory);
const bool was_anything_selected = ed::curves::has_anything_selected(curves,
selectable_points);
bke::GSpanAttributeWriter selection = ed::curves::ensure_selection_attribute(

View File

@ -667,6 +667,7 @@ static VectorSet<int> get_hidden_material_indices(Object &object)
IndexMask retrieve_editable_strokes(Object &object,
const bke::greasepencil::Drawing &drawing,
int layer_index,
IndexMaskMemory &memory)
{
using namespace blender;
@ -684,6 +685,8 @@ IndexMask retrieve_editable_strokes(Object &object,
}
const bke::AttributeAccessor attributes = curves.attributes();
GreasePencil &grease_pencil = *static_cast<GreasePencil *>(object.data);
const bke::greasepencil::Layer &layer = *grease_pencil.layers()[layer_index];
const VArray<int> materials = *attributes.lookup<int>("material_index", bke::AttrDomain::Curve);
if (!materials) {
@ -697,7 +700,8 @@ IndexMask retrieve_editable_strokes(Object &object,
return IndexMask::from_predicate(
curves_range, GrainSize(4096), memory, [&](const int64_t curve_i) {
const int material_index = materials[curve_i];
return editable_material_indices.contains(material_index);
return editable_material_indices.contains(material_index) ||
(layer.as_node().flag & GP_LAYER_TREE_NODE_USE_LOCKED_MATERIAL);
});
}
@ -739,6 +743,7 @@ IndexMask retrieve_editable_strokes_by_material(Object &object,
IndexMask retrieve_editable_points(Object &object,
const bke::greasepencil::Drawing &drawing,
int layer_index,
IndexMaskMemory &memory)
{
const bke::CurvesGeometry &curves = drawing.strokes();
@ -755,6 +760,8 @@ IndexMask retrieve_editable_points(Object &object,
}
const bke::AttributeAccessor attributes = curves.attributes();
GreasePencil &grease_pencil = *static_cast<GreasePencil *>(object.data);
const bke::greasepencil::Layer &layer = *grease_pencil.layers()[layer_index];
/* Propagate the material index to the points. */
const VArray<int> materials = *attributes.lookup<int>("material_index", bke::AttrDomain::Point);
@ -769,20 +776,23 @@ IndexMask retrieve_editable_points(Object &object,
return IndexMask::from_predicate(
points_range, GrainSize(4096), memory, [&](const int64_t point_i) {
const int material_index = materials[point_i];
return editable_material_indices.contains(material_index);
return editable_material_indices.contains(material_index) ||
(layer.as_node().flag & GP_LAYER_TREE_NODE_USE_LOCKED_MATERIAL);
});
}
IndexMask retrieve_editable_elements(Object &object,
const bke::greasepencil::Drawing &drawing,
const MutableDrawingInfo &info,
const bke::AttrDomain selection_domain,
IndexMaskMemory &memory)
{
const bke::greasepencil::Drawing &drawing = info.drawing;
if (selection_domain == bke::AttrDomain::Curve) {
return ed::greasepencil::retrieve_editable_strokes(object, drawing, memory);
return ed::greasepencil::retrieve_editable_strokes(object, drawing, info.layer_index, memory);
}
else if (selection_domain == bke::AttrDomain::Point) {
return ed::greasepencil::retrieve_editable_points(object, drawing, memory);
return ed::greasepencil::retrieve_editable_points(object, drawing, info.layer_index, memory);
}
return {};
}
@ -848,41 +858,44 @@ IndexMask retrieve_visible_points(Object &object,
}
IndexMask retrieve_editable_and_selected_strokes(Object &object,
const bke::greasepencil::Drawing &drawing,
const MutableDrawingInfo &info,
IndexMaskMemory &memory)
{
using namespace blender;
const bke::greasepencil::Drawing &drawing = info.drawing;
const bke::CurvesGeometry &curves = drawing.strokes();
const IndexMask editable_strokes = retrieve_editable_strokes(object, drawing, memory);
const IndexMask editable_strokes = retrieve_editable_strokes(
object, drawing, info.layer_index, memory);
const IndexMask selected_strokes = ed::curves::retrieve_selected_curves(curves, memory);
return IndexMask::from_intersection(editable_strokes, selected_strokes, memory);
}
IndexMask retrieve_editable_and_selected_points(Object &object,
const bke::greasepencil::Drawing &drawing,
const MutableDrawingInfo &info,
IndexMaskMemory &memory)
{
const bke::greasepencil::Drawing &drawing = info.drawing;
const bke::CurvesGeometry &curves = drawing.strokes();
const IndexMask editable_points = retrieve_editable_points(object, drawing, memory);
const IndexMask editable_points = retrieve_editable_points(
object, drawing, info.layer_index, memory);
const IndexMask selected_points = ed::curves::retrieve_selected_points(curves, memory);
return IndexMask::from_intersection(editable_points, selected_points, memory);
}
IndexMask retrieve_editable_and_selected_elements(Object &object,
const bke::greasepencil::Drawing &drawing,
const MutableDrawingInfo &info,
const bke::AttrDomain selection_domain,
IndexMaskMemory &memory)
{
if (selection_domain == bke::AttrDomain::Curve) {
return ed::greasepencil::retrieve_editable_and_selected_strokes(object, drawing, memory);
return ed::greasepencil::retrieve_editable_and_selected_strokes(object, info, memory);
}
else if (selection_domain == bke::AttrDomain::Point) {
return ed::greasepencil::retrieve_editable_and_selected_points(object, drawing, memory);
return ed::greasepencil::retrieve_editable_and_selected_points(object, info, memory);
}
return {};
}

View File

@ -266,6 +266,7 @@ Vector<DrawingInfo> retrieve_visible_drawings(const Scene &scene,
IndexMask retrieve_editable_strokes(Object &grease_pencil_object,
const bke::greasepencil::Drawing &drawing,
int layer_index,
IndexMaskMemory &memory);
IndexMask retrieve_editable_strokes_by_material(Object &object,
const bke::greasepencil::Drawing &drawing,
@ -273,9 +274,10 @@ IndexMask retrieve_editable_strokes_by_material(Object &object,
IndexMaskMemory &memory);
IndexMask retrieve_editable_points(Object &object,
const bke::greasepencil::Drawing &drawing,
int layer_index,
IndexMaskMemory &memory);
IndexMask retrieve_editable_elements(Object &object,
const bke::greasepencil::Drawing &drawing,
const MutableDrawingInfo &info,
bke::AttrDomain selection_domain,
IndexMaskMemory &memory);
@ -287,13 +289,13 @@ IndexMask retrieve_visible_points(Object &object,
IndexMaskMemory &memory);
IndexMask retrieve_editable_and_selected_strokes(Object &grease_pencil_object,
const bke::greasepencil::Drawing &drawing,
const MutableDrawingInfo &info,
IndexMaskMemory &memory);
IndexMask retrieve_editable_and_selected_points(Object &object,
const bke::greasepencil::Drawing &drawing,
const MutableDrawingInfo &info,
IndexMaskMemory &memory);
IndexMask retrieve_editable_and_selected_elements(Object &object,
const bke::greasepencil::Drawing &drawing,
const MutableDrawingInfo &info,
bke::AttrDomain selection_domain,
IndexMaskMemory &memory);

View File

@ -1202,7 +1202,7 @@ static bool do_lasso_select_grease_pencil(const ViewContext *vc,
IndexMaskMemory memory;
const IndexMask elements = ed::greasepencil::retrieve_editable_elements(
*vc->obedit, info.drawing, selection_domain, memory);
*vc->obedit, info, selection_domain, memory);
if (elements.is_empty()) {
continue;
}
@ -3246,7 +3246,7 @@ static bool ed_grease_pencil_select_pick(bContext *C,
IndexMaskMemory memory;
const IndexMask elements = ed::greasepencil::retrieve_editable_elements(
*vc.obedit, info.drawing, selection_domain, memory);
*vc.obedit, info, selection_domain, memory);
if (elements.is_empty()) {
continue;
}
@ -3280,7 +3280,7 @@ static bool ed_grease_pencil_select_pick(bContext *C,
ed::greasepencil::MutableDrawingInfo info = drawings[i];
IndexMaskMemory memory;
const IndexMask elements = ed::greasepencil::retrieve_editable_elements(
*vc.obedit, info.drawing, selection_domain, memory);
*vc.obedit, info, selection_domain, memory);
if (elements.is_empty()) {
continue;
}
@ -4260,7 +4260,7 @@ static bool do_grease_pencil_box_select(const ViewContext *vc,
ob_eval, *vc->obedit, info.layer_index, info.frame_number);
IndexMaskMemory memory;
const IndexMask elements = ed::greasepencil::retrieve_editable_elements(
*vc->obedit, info.drawing, selection_domain, memory);
*vc->obedit, info, selection_domain, memory);
if (elements.is_empty()) {
continue;
}
@ -5122,7 +5122,7 @@ static bool grease_pencil_circle_select(const ViewContext *vc,
ob_eval, *vc->obedit, info.layer_index, info.frame_number);
IndexMaskMemory memory;
const IndexMask elements = ed::greasepencil::retrieve_editable_elements(
*vc->obedit, info.drawing, selection_domain, memory);
*vc->obedit, info, selection_domain, memory);
if (elements.is_empty()) {
continue;
}

View File

@ -56,13 +56,13 @@ static void createTransGreasePencilVerts(bContext *C, TransInfo *t)
for (ed::greasepencil::MutableDrawingInfo info : drawings) {
if (use_proportional_edit) {
points_per_layer_per_object[layer_offset] = ed::greasepencil::retrieve_editable_points(
*object, info.drawing, curves_transform_data->memory);
*object, info.drawing, info.layer_index, curves_transform_data->memory);
tc.data_len += points_per_layer_per_object[layer_offset].size();
}
else {
points_per_layer_per_object[layer_offset] =
ed::greasepencil::retrieve_editable_and_selected_points(
*object, info.drawing, curves_transform_data->memory);
*object, info, curves_transform_data->memory);
tc.data_len += points_per_layer_per_object[layer_offset].size();
}
@ -109,7 +109,7 @@ static void createTransGreasePencilVerts(bContext *C, TransInfo *t)
const IndexMask affected_strokes = use_proportional_edit ?
ed::greasepencil::retrieve_editable_strokes(
*object, info.drawing, memory) :
*object, info.drawing, info.layer_index, memory) :
IndexMask();
curve_populate_trans_data_structs(tc,
curves,

View File

@ -242,6 +242,7 @@ typedef enum GreasePencilLayerTreeNodeFlag {
GP_LAYER_TREE_NODE_EXPANDED = (1 << 6),
GP_LAYER_TREE_NODE_HIDE_MASKS = (1 << 7),
GP_LAYER_TREE_NODE_DISABLE_MASKS_IN_VIEWLAYER = (1 << 8),
GP_LAYER_TREE_NODE_USE_LOCKED_MATERIAL = (1 << 9),
} GreasePencilLayerTreeNodeFlag;
struct GreasePencilLayerTreeGroup;

View File

@ -487,6 +487,14 @@ static void rna_def_grease_pencil_layer(BlenderRNA *brna)
RNA_def_property_enum_items(prop, rna_enum_layer_blend_modes_items);
RNA_def_property_ui_text(prop, "Blend Mode", "Blend mode");
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_grease_pencil_update");
prop = RNA_def_property(srna, "use_locked_material", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(
prop, "GreasePencilLayerTreeNode", "flag", GP_LAYER_TREE_NODE_USE_LOCKED_MATERIAL);
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_ui_text(
prop, "Use Locked Materials Editing", "Allow editing locked materials in the layer");
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, nullptr);
}
static void rna_def_grease_pencil_layers_api(BlenderRNA *brna, PropertyRNA *cprop)