GPv3: Add operator to add new layer group

This commit is contained in:
Falk David 2023-06-26 18:23:08 +02:00
parent 8a39f438c3
commit b61316c7ad
5 changed files with 149 additions and 4 deletions

@ -2,7 +2,7 @@
#
# SPDX-License-Identifier: GPL-2.0-or-later
import bpy
from bpy.types import Panel
from bpy.types import Panel, Menu
class DataButtonsPanel:
@ -32,6 +32,15 @@ class DATA_PT_context_grease_pencil(DataButtonsPanel, Panel):
layout.template_ID(space, "pin_id")
class GREASE_PENCIL_MT_grease_pencil_add_layer_extra(Menu):
bl_label = "Add Extra"
def draw(self, context):
layout = self.layout
layout.operator("grease_pencil.layer_group_add", text="Add Group")
class DATA_PT_grease_pencil_layers(DataButtonsPanel, Panel):
bl_label = "Layers"
@ -42,13 +51,17 @@ class DATA_PT_grease_pencil_layers(DataButtonsPanel, Panel):
row.template_grease_pencil_layer_tree()
col = row.column()
col.operator("grease_pencil.layer_add", icon='ADD', text="")
sub = col.column(align=True)
sub.operator("grease_pencil.layer_add", icon='ADD', text="")
sub.menu("GREASE_PENCIL_MT_grease_pencil_add_layer_extra", icon='DOWNARROW_HLT', text="")
col.operator("grease_pencil.layer_remove", icon='REMOVE', text="")
classes = (
DATA_PT_context_grease_pencil,
DATA_PT_grease_pencil_layers,
GREASE_PENCIL_MT_grease_pencil_add_layer_extra,
)
if __name__ == "__main__": # only for live edit.

@ -207,6 +207,12 @@ class Layer : public ::GreasePencilLayer {
*/
LayerGroup &parent_group() const;
/**
* \returns the layer as a `TreeNode`.
*/
const TreeNode &as_node() const;
TreeNode &as_node();
/**
* \returns the frames mapping.
*/
@ -287,6 +293,12 @@ class LayerGroup : public ::GreasePencilLayerTreeGroup {
LayerGroup &add_group(LayerGroup *group);
LayerGroup &add_group(StringRefNull name);
/**
* Adds a layer group after \a link and returns it.
*/
LayerGroup &add_group_after(LayerGroup *group, TreeNode *link);
LayerGroup &add_group_after(StringRefNull name, TreeNode *link);
/**
* Adds a layer at the end of this group and returns it.
*/
@ -359,6 +371,15 @@ inline LayerGroup &Layer::parent_group() const
return this->base.parent->wrap();
}
inline const TreeNode &Layer::as_node() const
{
return *reinterpret_cast<const TreeNode *>(this);
}
inline TreeNode &Layer::as_node()
{
return *reinterpret_cast<TreeNode *>(this);
}
namespace convert {
void legacy_gpencil_frame_to_grease_pencil_drawing(const bGPDframe &gpf,

@ -631,6 +631,23 @@ LayerGroup &LayerGroup::add_group(StringRefNull name)
return this->add_group(new_group);
}
LayerGroup &LayerGroup::add_group_after(LayerGroup *group, TreeNode *link)
{
BLI_assert(group != nullptr && link != nullptr);
BLI_insertlinkafter(&this->children,
reinterpret_cast<GreasePencilLayerTreeNode *>(link),
reinterpret_cast<GreasePencilLayerTreeNode *>(group));
group->base.parent = reinterpret_cast<GreasePencilLayerTreeGroup *>(this);
this->tag_nodes_cache_dirty();
return *group;
}
LayerGroup &LayerGroup::add_group_after(StringRefNull name, TreeNode *link)
{
LayerGroup *new_group = MEM_new<LayerGroup>(__func__, name);
return this->add_group_after(new_group, link);
}
Layer &LayerGroup::add_layer(Layer *layer)
{
BLI_assert(layer != nullptr);
@ -1245,7 +1262,7 @@ static blender::VectorSet<blender::StringRefNull> get_node_names(GreasePencil &g
return names;
}
static bool check_unique_layer_cb(void *arg, const char *name)
static bool check_unique_node_cb(void *arg, const char *name)
{
using namespace blender;
VectorSet<StringRefNull> &names = *reinterpret_cast<VectorSet<StringRefNull> *>(arg);
@ -1254,7 +1271,12 @@ static bool check_unique_layer_cb(void *arg, const char *name)
static bool unique_layer_name(VectorSet<blender::StringRefNull> &names, char *name)
{
return BLI_uniquename_cb(check_unique_layer_cb, &names, "GP_Layer", '.', name, MAX_NAME);
return BLI_uniquename_cb(check_unique_node_cb, &names, "GP_Layer", '.', name, MAX_NAME);
}
static bool unique_layer_group_name(VectorSet<blender::StringRefNull> &names, char *name)
{
return BLI_uniquename_cb(check_unique_node_cb, &names, "GP_Group", '.', name, MAX_NAME);
}
blender::bke::greasepencil::Layer &GreasePencil::add_layer(
@ -1284,6 +1306,34 @@ blender::bke::greasepencil::Layer &GreasePencil::add_layer(const blender::String
return this->add_layer(this->root_group.wrap(), name);
}
blender::bke::greasepencil::LayerGroup &GreasePencil::add_layer_group(
blender::bke::greasepencil::LayerGroup &group, const blender::StringRefNull name)
{
using namespace blender;
VectorSet<StringRefNull> names = get_node_names(*this);
std::string unique_name(name.c_str());
unique_layer_group_name(names, unique_name.data());
return group.add_group(unique_name);
}
blender::bke::greasepencil::LayerGroup &GreasePencil::add_layer_group_after(
blender::bke::greasepencil::LayerGroup &group,
blender::bke::greasepencil::TreeNode *node,
const blender::StringRefNull name)
{
using namespace blender;
VectorSet<StringRefNull> names = get_node_names(*this);
std::string unique_name(name.c_str());
unique_layer_group_name(names, unique_name.data());
return group.add_group_after(unique_name, node);
}
blender::bke::greasepencil::LayerGroup &GreasePencil::add_layer_group(
const blender::StringRefNull name)
{
return this->add_layer_group(this->root_group.wrap(), name);
}
const blender::bke::greasepencil::Layer *GreasePencil::find_layer_by_name(
const blender::StringRefNull name) const
{

@ -179,6 +179,57 @@ static void GREASE_PENCIL_OT_layer_reorder(wmOperatorType *ot)
ot->srna, "location", prop_layer_reorder_location, LAYER_REORDER_ABOVE, "Location", "");
}
static int grease_pencil_layer_group_add_exec(bContext *C, wmOperator *op)
{
using namespace blender::bke::greasepencil;
Object *object = CTX_data_active_object(C);
GreasePencil &grease_pencil = *static_cast<GreasePencil *>(object->data);
int new_layer_group_name_length;
char *new_layer_group_name = RNA_string_get_alloc(
op->ptr, "new_layer_group_name", nullptr, 0, &new_layer_group_name_length);
if (grease_pencil.has_active_layer()) {
LayerGroup &active_group = grease_pencil.get_active_layer()->parent_group();
grease_pencil.add_layer_group_after(active_group,
&grease_pencil.get_active_layer_for_write()->as_node(),
new_layer_group_name);
}
else {
grease_pencil.add_layer_group(new_layer_group_name);
}
MEM_SAFE_FREE(new_layer_group_name);
DEG_id_tag_update(&grease_pencil.id, ID_RECALC_GEOMETRY);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, &grease_pencil);
return OPERATOR_FINISHED;
}
static void GREASE_PENCIL_OT_layer_group_add(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Add New Layer Group";
ot->idname = "GREASE_PENCIL_OT_layer_group_add";
ot->description = "Add a new Grease Pencil layer group in the active object";
/* callbacks */
ot->exec = grease_pencil_layer_group_add_exec;
ot->poll = active_grease_pencil_poll;
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
PropertyRNA *prop = RNA_def_string(ot->srna,
"new_layer_group_name",
"GP_Group",
INT16_MAX,
"Name",
"Name of the new layer group");
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
ot->prop = prop;
}
} // namespace blender::ed::greasepencil
void ED_operatortypes_grease_pencil_layers(void)
@ -187,4 +238,6 @@ void ED_operatortypes_grease_pencil_layers(void)
WM_operatortype_append(GREASE_PENCIL_OT_layer_add);
WM_operatortype_append(GREASE_PENCIL_OT_layer_remove);
WM_operatortype_append(GREASE_PENCIL_OT_layer_reorder);
WM_operatortype_append(GREASE_PENCIL_OT_layer_group_add);
}

@ -450,6 +450,14 @@ typedef struct GreasePencil {
blender::bke::greasepencil::Layer *layer,
blender::StringRefNull name);
blender::bke::greasepencil::LayerGroup &add_layer_group(
blender::bke::greasepencil::LayerGroup &group, blender::StringRefNull name);
blender::bke::greasepencil::LayerGroup &add_layer_group(blender::StringRefNull name);
blender::bke::greasepencil::LayerGroup &add_layer_group_after(
blender::bke::greasepencil::LayerGroup &group,
blender::bke::greasepencil::TreeNode *node,
blender::StringRefNull name);
const blender::bke::greasepencil::Layer *find_layer_by_name(blender::StringRefNull name) const;
blender::bke::greasepencil::Layer *find_layer_by_name(blender::StringRefNull name);