39 const bool keep_transform)
45 layer.parent = parent;
49 copy_m4_m4(layer.parentinv, parent->world_to_object().ptr());
60 if (layer.parent ==
nullptr) {
67 layer.parent =
nullptr;
77 if (layer !=
nullptr) {
78 layer->set_selected(
true);
81 if (grease_pencil.get_active_layer() != layer) {
82 grease_pencil.set_active_layer(layer);
93 int new_layer_name_length;
95 op->
ptr,
"new_layer_name",
nullptr, 0, &new_layer_name_length);
97 Layer &new_layer = grease_pencil.add_layer(new_layer_name);
101 if (grease_pencil.has_active_layer()) {
102 grease_pencil.move_node_after(new_layer.as_node(),
103 grease_pencil.get_active_layer()->as_node());
105 else if (grease_pencil.has_active_group()) {
106 grease_pencil.move_node_into(new_layer.as_node(), *grease_pencil.get_active_group());
110 GreasePencilv3LayerGroup,
114 grease_pencil.set_active_layer(&new_layer);
118 grease_pencil.insert_frame(new_layer, scene->r.cfra);
131 IFACE_(
"Add New Grease Pencil Layer"),
138 ot->
name =
"Add New Layer";
139 ot->
idname =
"GREASE_PENCIL_OT_layer_add";
140 ot->
description =
"Add a new Grease Pencil layer in the active object";
150 ot->
srna,
"new_layer_name",
"Layer",
INT16_MAX,
"Name",
"Name of the new layer");
160 if (!grease_pencil.has_active_layer()) {
164 grease_pencil.remove_layer(*grease_pencil.get_active_layer());
180 ot->
name =
"Remove Layer";
181 ot->
idname =
"GREASE_PENCIL_OT_layer_remove";
194 {0,
nullptr, 0,
nullptr,
nullptr},
203 if (!grease_pencil.has_active_layer()) {
207 int target_layer_name_length;
209 op->
ptr,
"target_layer_name",
nullptr, 0, &target_layer_name_length);
212 TreeNode *target_node = grease_pencil.find_node_by_name(target_layer_name);
213 if (!target_node || !target_node->
is_layer()) {
218 Layer &active_layer = *grease_pencil.get_active_layer();
219 switch (reorder_location) {
223 grease_pencil.move_node_after(active_layer.
as_node(), *target_node);
229 grease_pencil.move_node_before(active_layer.
as_node(), *target_node);
252 ot->
name =
"Reorder Layer";
253 ot->
idname =
"GREASE_PENCIL_OT_layer_reorder";
267 "Name of the target layer");
279 {0,
nullptr, 0,
nullptr,
nullptr},
290 const TreeNode *active_node = grease_pencil.get_active_node();
292 if (active_node ==
nullptr) {
312 TreeNode &active_node = *grease_pencil.get_active_node();
315 grease_pencil.move_node_up(active_node);
318 grease_pencil.move_node_down(active_node);
333 ot->
name =
"Reorder Layer";
334 ot->
idname =
"GREASE_PENCIL_OT_layer_move";
335 ot->
description =
"Move the active Grease Pencil layer or Group";
353 Layer &layer = grease_pencil.layer(layer_index);
354 if (grease_pencil.is_layer_active(&layer)) {
358 if (grease_pencil.has_active_group()) {
362 GreasePencilv3LayerGroup,
365 grease_pencil.set_active_layer(&layer);
378 ot->
name =
"Set Active Layer";
379 ot->
idname =
"GREASE_PENCIL_OT_layer_active";
389 ot->
srna,
"layer", 0, 0, INT_MAX,
"Grease Pencil Layer",
"", 0, INT_MAX);
398 int new_layer_group_name_length;
400 op->
ptr,
"new_layer_group_name",
nullptr, 0, &new_layer_group_name_length);
402 LayerGroup &new_group = grease_pencil.add_layer_group(new_layer_group_name);
406 if (grease_pencil.has_active_layer()) {
407 grease_pencil.move_node_after(new_group.
as_node(),
408 grease_pencil.get_active_layer()->as_node());
412 else if (grease_pencil.has_active_group()) {
413 grease_pencil.move_node_into(new_group.
as_node(), *grease_pencil.get_active_group());
417 GreasePencilv3LayerGroup,
422 grease_pencil.set_active_node(&new_group.
as_node());
437 ot->
name =
"Add New Layer Group";
438 ot->
idname =
"GREASE_PENCIL_OT_layer_group_add";
439 ot->
description =
"Add a new Grease Pencil layer group in the active object";
448 ot->
srna,
"new_layer_group_name",
nullptr,
INT16_MAX,
"Name",
"Name of the new layer group");
460 if (!grease_pencil.has_active_group()) {
464 grease_pencil.remove_group(*grease_pencil.get_active_group(), keep_children);
480 ot->
name =
"Remove Layer Group";
481 ot->
idname =
"GREASE_PENCIL_OT_layer_group_remove";
482 ot->
description =
"Remove Grease Pencil layer group in the active object";
493 "Keep children nodes",
494 "Keep the children nodes of the group and only delete the group itself");
503 if (!grease_pencil.has_active_layer()) {
509 for (
Layer *layer : grease_pencil.layers_for_write()) {
510 const bool is_active = grease_pencil.is_layer_active(layer);
511 layer->set_visible(is_active);
516 Layer &active_layer = *grease_pencil.get_active_layer();
517 active_layer.set_visible(
false);
531 ot->
name =
"Hide Layer(s)";
532 ot->
idname =
"GREASE_PENCIL_OT_layer_hide";
533 ot->
description =
"Hide selected/unselected Grease Pencil layers";
544 ot->
srna,
"unselected",
false,
"Unselected",
"Hide unselected rather than selected layers");
554 if (!grease_pencil.has_active_layer()) {
558 for (
Layer *layer : grease_pencil.layers_for_write()) {
559 layer->set_visible(
true);
573 ot->
name =
"Show All Layers";
574 ot->
idname =
"GREASE_PENCIL_OT_layer_reveal";
590 bool isolate =
false;
592 for (
const Layer *layer : grease_pencil.layers()) {
593 if (grease_pencil.is_layer_active(layer)) {
596 if ((affect_visibility && layer->is_visible()) || !layer->is_locked()) {
602 for (
Layer *layer : grease_pencil.layers_for_write()) {
603 if (grease_pencil.is_layer_active(layer) || !isolate) {
604 layer->set_locked(
false);
605 if (affect_visibility) {
606 layer->set_visible(
true);
610 layer->set_locked(
true);
611 if (affect_visibility) {
612 layer->set_visible(
false);
627 ot->
name =
"Isolate Layers";
628 ot->
idname =
"GREASE_PENCIL_OT_layer_isolate";
640 ot->
srna,
"affect_visibility",
false,
"Affect Visibility",
"Also affect the visibility");
649 if (grease_pencil.layers().is_empty()) {
653 for (
Layer *layer : grease_pencil.layers_for_write()) {
654 layer->set_locked(lock_value);
667 ot->
name =
"Lock All Layers";
668 ot->
idname =
"GREASE_PENCIL_OT_layer_lock_all";
670 "Lock all Grease Pencil layers to prevent them from being accidentally modified";
689 if (!grease_pencil.has_active_layer()) {
695 Layer &active_layer = *grease_pencil.get_active_layer();
696 Layer &new_layer = grease_pencil.duplicate_layer(active_layer);
703 for (
auto [frame_number, frame] : active_layer.
frames().
items()) {
706 Drawing *dst_drawing = grease_pencil.insert_frame(
708 if (!empty_keyframes) {
711 const Drawing &src_drawing = *grease_pencil.get_drawing_at(active_layer, frame_number);
713 *dst_drawing = src_drawing;
717 grease_pencil.move_node_after(new_layer.
as_node(), active_layer.
as_node());
718 grease_pencil.set_active_layer(&new_layer);
732 ot->
name =
"Duplicate Layer";
733 ot->
idname =
"GREASE_PENCIL_OT_layer_duplicate";
734 ot->
description =
"Make a copy of the active Grease Pencil layer";
762 std::string merged_layer_name;
764 if (!grease_pencil.has_active_layer()) {
768 const Layer &active_layer = *grease_pencil.get_active_layer();
770 if (prev_node ==
nullptr || !prev_node->wrap().is_layer()) {
774 const Layer &prev_layer = prev_node->wrap().as_layer();
776 const int prev_layer_index = *grease_pencil.get_layer_index(prev_layer);
777 const int active_layer_index = *grease_pencil.get_layer_index(active_layer);
781 for (
const int layer_i : layers.index_range()) {
782 if (layer_i == active_layer_index) {
785 else if (layer_i == prev_layer_index) {
787 src_layer_indices_by_dst_layer.
append({prev_layer_index, active_layer_index});
791 src_layer_indices_by_dst_layer.
append({layer_i});
796 merged_layer_name = grease_pencil.layer(prev_layer_index).name();
799 if (!grease_pencil.has_active_group()) {
803 LayerGroup &active_group = *grease_pencil.get_active_group();
808 grease_pencil.remove_group(*group,
true);
813 for (
const int layer_i : layers.index_range()) {
814 const Layer &layer = grease_pencil.layer(layer_i);
815 if (!layer.is_child_of(active_group)) {
816 src_layer_indices_by_dst_layer.
append({layer_i});
819 indices.append(layer_i);
822 src_layer_indices_by_dst_layer.
append(indices);
825 merged_layer_name = active_group.name();
828 grease_pencil.remove_group(active_group,
true);
832 GreasePencilv3LayerGroup,
836 grease_pencil.rename_node(
837 *bmain, grease_pencil.layer(indices[0]).as_node(), merged_layer_name);
843 grease_pencil.remove_group(*group,
true);
847 for (
const int layer_i : grease_pencil.layers().index_range()) {
850 src_layer_indices_by_dst_layer.
append(indices);
852 merged_layer_name =
N_(
"Layer");
853 grease_pencil.rename_node(
854 *bmain, grease_pencil.layer(indices[0]).as_node(), merged_layer_name);
863 grease_pencil, src_layer_indices_by_dst_layer, *merged_grease_pencil);
870 TreeNode *node = grease_pencil.find_node_by_name(merged_layer_name);
871 if (node && node->is_layer()) {
872 Layer &layer = node->as_layer();
873 grease_pencil.set_active_layer(&layer);
892 "Combine the active layer with the layer just below (if it exists)"},
897 "Combine layers in the active group into a single layer"},
898 {
int(
MergeMode::All),
"ALL", 0,
"All",
"Combine all layers into a single layer"},
899 {0,
nullptr, 0,
nullptr,
nullptr},
903 ot->
idname =
"GREASE_PENCIL_OT_layer_merge";
904 ot->
description =
"Combine layers based on the mode into one layer";
919 if (!grease_pencil.has_active_layer()) {
922 Layer &active_layer = *grease_pencil.get_active_layer();
924 int mask_name_length;
928 if (
TreeNode *node = grease_pencil.find_node_by_name(mask_name)) {
929 if (grease_pencil.is_layer_active(&node->as_layer())) {
942 LayerMask *new_mask = MEM_new<LayerMask>(__func__, mask_name);
961 ot->
name =
"Add New Mask Layer";
962 ot->
idname =
"GREASE_PENCIL_OT_layer_mask_add";
980 if (!grease_pencil.has_active_layer()) {
984 Layer &active_layer = *grease_pencil.get_active_layer();
989 MEM_delete(
reinterpret_cast<LayerMask *
>(mask));
1005 ot->
name =
"Remove Mask Layer";
1006 ot->
idname =
"GREASE_PENCIL_OT_layer_mask_remove";
1021 if (!grease_pencil.has_active_layer()) {
1024 Layer &active_layer = *grease_pencil.get_active_layer();
1027 bool changed =
false;
1051 ot->
name =
"Reorder Grease Pencil Layer Mask";
1052 ot->
idname =
"GREASE_PENCIL_OT_layer_mask_reorder";
1053 ot->
description =
"Reorder the active Grease Pencil mask layer up/down in the list";
1075 {0,
nullptr, 0,
nullptr,
nullptr},
1084 LayerGroup *active_group = grease_pencil.get_active_group();
1096 ot->
name =
"Grease Pencil group color tag";
1097 ot->
idname =
"GREASE_PENCIL_OT_layer_group_color_tag";
1117 const int current_frame)
1120 Layer &dst_layer = dst_grease_pencil.duplicate_layer(src_layer);
1123 for (
const auto [frame_number, frame] : src_layer.
frames().
items()) {
1125 (&frame != src_layer.
frame_at(current_frame)))
1131 Drawing *dst_drawing = dst_grease_pencil.insert_frame(
1133 if (dst_drawing !=
nullptr) {
1135 const Drawing &src_drawing = *src_grease_pencil.get_drawing_at(src_layer, frame_number);
1136 *dst_drawing = src_drawing;
1146 const int current_frame = scene->r.cfra;
1158 const Layer &active_layer = *src_grease_pencil.get_active_layer();
1160 dst_grease_pencil, src_grease_pencil, active_layer, copy_frame_mode, current_frame);
1163 for (
const Layer *layer : src_grease_pencil.layers()) {
1165 dst_grease_pencil, src_grease_pencil, *layer, copy_frame_mode, current_frame);
1180 ot->
name =
"Duplicate Layer to New Object";
1181 ot->
idname =
"GREASE_PENCIL_OT_layer_duplicate_object";
1182 ot->
description =
"Make a copy of the active Grease Pencil layer to selected object";
1195 "Copy only active Layer, uncheck to append all layers");
1200 {0,
nullptr, 0,
nullptr,
nullptr},
#define CTX_DATA_BEGIN(C, Type, instance, member)
Object * CTX_data_active_object(const bContext *C)
Scene * CTX_data_scene(const bContext *C)
Main * CTX_data_main(const bContext *C)
wmMsgBus * CTX_wm_message_bus(const bContext *C)
Low-level operations for grease pencil.
void BKE_grease_pencil_copy_parameters(const GreasePencil &src, GreasePencil &dst)
void BKE_grease_pencil_nomain_to_grease_pencil(GreasePencil *grease_pencil_src, GreasePencil *grease_pencil_dst)
GreasePencil * BKE_grease_pencil_new_nomain()
General operations, lookup, etc. for blender objects.
void BKE_reportf(ReportList *reports, eReportType type, const char *format,...) ATTR_PRINTF_FORMAT(3
void BKE_report(ReportList *reports, eReportType type, const char *message)
#define BLI_assert_unreachable()
void * BLI_findstring(const struct ListBase *listbase, const char *id, int offset) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
void * BLI_findlink(const struct ListBase *listbase, int number) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
void BLI_remlink(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
void void void bool BLI_listbase_link_move(ListBase *listbase, void *vlink, int step) ATTR_NONNULL()
int BLI_listbase_count(const struct ListBase *listbase) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
void unit_m4(float m[4][4])
void copy_m4_m4(float m1[4][4], const float m2[4][4])
#define BLI_SCOPED_DEFER(function_to_defer)
char * BLI_strdup_null(const char *str) ATTR_WARN_UNUSED_RESULT ATTR_MALLOC
#define CTX_IFACE_(context, msgid)
#define BLT_I18NCONTEXT_OPERATOR_DEFAULT
void DEG_id_tag_update(ID *id, unsigned int flags)
ItemIterator items() const
constexpr const char * c_str() const
void append(const T &value)
const TreeNode & as_node() const
int64_t num_direct_nodes() const
Span< LayerGroup * > groups_for_write()
const Map< FramesMapKeyT, GreasePencilFrame > & frames() const
const TreeNode & as_node() const
const GreasePencilFrame * frame_at(const int frame_number) const
int get_frame_duration_at(const int frame_number) const
Map< FramesMapKeyT, GreasePencilFrame > & frames_for_write()
const LayerGroup * parent_group() const
draw_view push_constant(Type::INT, "radiance_src") .push_constant(Type capture_info_buf storage_buf(1, Qualifier::READ, "ObjectBounds", "bounds_buf[]") .push_constant(Type draw_view int
void ED_operatortypes_grease_pencil_layers()
static int grease_pencil_layer_lock_all_exec(bContext *C, wmOperator *op)
static void GREASE_PENCIL_OT_layer_lock_all(wmOperatorType *ot)
bool active_grease_pencil_poll(bContext *C)
static int grease_pencil_layer_group_color_tag_exec(bContext *C, wmOperator *op)
static int grease_pencil_layer_reveal_exec(bContext *C, wmOperator *)
static int grease_pencil_layer_isolate_exec(bContext *C, wmOperator *op)
static const EnumPropertyItem enum_layer_move_direction[]
static int grease_pencil_layer_group_add_exec(bContext *C, wmOperator *op)
static int grease_pencil_merge_layer_exec(bContext *C, wmOperator *op)
GreasePencil * from_context(bContext &C)
static void GREASE_PENCIL_OT_layer_group_add(wmOperatorType *ot)
void grease_pencil_layer_parent_clear(bke::greasepencil::Layer &layer, const bool keep_transform)
static void GREASE_PENCIL_OT_layer_group_color_tag(wmOperatorType *ot)
static int grease_pencil_layer_hide_exec(bContext *C, wmOperator *op)
static void GREASE_PENCIL_OT_layer_remove(wmOperatorType *ot)
static void GREASE_PENCIL_OT_layer_isolate(wmOperatorType *ot)
static int grease_pencil_layer_group_remove_exec(bContext *C, wmOperator *op)
static void GREASE_PENCIL_OT_layer_hide(wmOperatorType *ot)
static void GREASE_PENCIL_OT_layer_merge(wmOperatorType *ot)
static void GREASE_PENCIL_OT_layer_add(wmOperatorType *ot)
static int grease_pencil_layer_mask_remove_exec(bContext *C, wmOperator *)
static const EnumPropertyItem prop_layer_reorder_location[]
static void GREASE_PENCIL_OT_layer_mask_add(wmOperatorType *ot)
static void GREASE_PENCIL_OT_layer_active(wmOperatorType *ot)
const EnumPropertyItem enum_layergroup_color_items[]
static int grease_pencil_layer_mask_reorder_exec(bContext *C, wmOperator *op)
static int grease_pencil_layer_duplicate_object_exec(bContext *C, wmOperator *op)
static int grease_pencil_layer_reorder_exec(bContext *C, wmOperator *op)
static void GREASE_PENCIL_OT_layer_move(wmOperatorType *ot)
static int grease_pencil_layer_move_exec(bContext *C, wmOperator *op)
static int grease_pencil_layer_mask_add_exec(bContext *C, wmOperator *op)
static void GREASE_PENCIL_OT_layer_duplicate_object(wmOperatorType *ot)
static int grease_pencil_layer_remove_exec(bContext *C, wmOperator *)
static int grease_pencil_layer_active_exec(bContext *C, wmOperator *op)
static void GREASE_PENCIL_OT_layer_group_remove(wmOperatorType *ot)
static void GREASE_PENCIL_OT_layer_duplicate(wmOperatorType *ot)
bool grease_pencil_layer_parent_set(bke::greasepencil::Layer &layer, Object *parent, StringRefNull bone, const bool keep_transform)
static int grease_pencil_layer_add_invoke(bContext *C, wmOperator *op, const wmEvent *event)
bool grease_pencil_context_poll(bContext *C)
static int grease_pencil_layer_add_exec(bContext *C, wmOperator *op)
static void GREASE_PENCIL_OT_layer_mask_reorder(wmOperatorType *ot)
static int grease_pencil_layer_duplicate_exec(bContext *C, wmOperator *op)
void merge_layers(const GreasePencil &src_grease_pencil, const Span< Vector< int > > src_layer_indices_by_dst_layer, GreasePencil &dst_grease_pencil)
void select_layer_channel(GreasePencil &grease_pencil, bke::greasepencil::Layer *layer)
static void GREASE_PENCIL_OT_layer_reveal(wmOperatorType *ot)
bool active_grease_pencil_layer_poll(bContext *C)
static void GREASE_PENCIL_OT_layer_reorder(wmOperatorType *ot)
static void GREASE_PENCIL_OT_layer_mask_remove(wmOperatorType *ot)
static void duplicate_layer_and_frames(GreasePencil &dst_grease_pencil, const GreasePencil &src_grease_pencil, const blender::bke::greasepencil::Layer &src_layer, const DuplicateCopyMode copy_frame_mode, const int current_frame)
static bool grease_pencil_layer_move_poll(bContext *C)
int RNA_int_get(PointerRNA *ptr, const char *name)
char * RNA_string_get_alloc(PointerRNA *ptr, const char *name, char *fixedbuf, int fixedlen, int *r_len)
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
int RNA_enum_get(PointerRNA *ptr, const char *name)
PropertyRNA * RNA_def_string(StructOrFunctionRNA *cont_, const char *identifier, const char *default_value, const int maxlen, const char *ui_name, const char *ui_description)
PropertyRNA * RNA_def_enum(StructOrFunctionRNA *cont_, const char *identifier, const EnumPropertyItem *items, const int default_value, const char *ui_name, const char *ui_description)
PropertyRNA * RNA_def_boolean(StructOrFunctionRNA *cont_, const char *identifier, const bool default_value, const char *ui_name, const char *ui_description)
void RNA_def_property_flag(PropertyRNA *prop, PropertyFlag flag)
PropertyRNA * RNA_def_int(StructOrFunctionRNA *cont_, const char *identifier, const int default_value, const int hardmin, const int hardmax, const char *ui_name, const char *ui_description, const int softmin, const int softmax)
struct GreasePencilLayerTreeNode * prev
const c_style_mat & ptr() const
static MatBase identity()
bool(* poll)(bContext *C) ATTR_WARN_UNUSED_RESULT
int(* invoke)(bContext *C, wmOperator *op, const wmEvent *event) ATTR_WARN_UNUSED_RESULT
int(* exec)(bContext *C, wmOperator *op) ATTR_WARN_UNUSED_RESULT
struct ReportList * reports
void WM_main_add_notifier(uint type, void *reference)
void WM_event_add_notifier(const bContext *C, uint type, void *reference)
#define WM_msg_publish_rna_prop(mbus, id_, data_, type_, prop_)
void WM_operatortype_append(void(*opfunc)(wmOperatorType *))
int WM_operator_props_popup_confirm_ex(bContext *C, wmOperator *op, const wmEvent *, std::optional< std::string > title, std::optional< std::string > confirm_text, const bool cancel_default)