46 if (!pchan || !pchan->
bone) {
59 const bool keep_transform)
85 if (layer.
parent ==
nullptr) {
102 if (layer !=
nullptr) {
103 layer->set_selected(
true);
106 if (grease_pencil.get_active_layer() != layer) {
107 grease_pencil.set_active_layer(layer);
118 int new_layer_name_length;
120 op->
ptr,
"new_layer_name",
nullptr, 0, &new_layer_name_length);
122 Layer &new_layer = grease_pencil.add_layer(new_layer_name);
126 if (grease_pencil.has_active_layer()) {
127 grease_pencil.move_node_after(new_layer.as_node(),
128 grease_pencil.get_active_layer()->as_node());
130 else if (grease_pencil.has_active_group()) {
131 grease_pencil.move_node_into(new_layer.as_node(), *grease_pencil.get_active_group());
135 GreasePencilv3LayerGroup,
139 grease_pencil.set_active_layer(&new_layer);
143 grease_pencil.insert_frame(new_layer, scene->
r.
cfra);
158 IFACE_(
"Add New Grease Pencil Layer"),
165 ot->name =
"Add New Layer";
166 ot->idname =
"GREASE_PENCIL_OT_layer_add";
167 ot->description =
"Add a new Grease Pencil layer in the active object";
177 ot->srna,
"new_layer_name",
"Layer",
INT16_MAX,
"Name",
"Name of the new layer");
187 if (!grease_pencil.has_active_layer()) {
191 grease_pencil.remove_layer(*grease_pencil.get_active_layer());
207 ot->name =
"Remove Layer";
208 ot->idname =
"GREASE_PENCIL_OT_layer_remove";
209 ot->description =
"Remove the active Grease Pencil layer";
223 {0,
nullptr, 0,
nullptr,
nullptr},
234 const TreeNode *active_node = grease_pencil.get_active_node();
236 if (active_node ==
nullptr) {
256 TreeNode &active_node = *grease_pencil.get_active_node();
259 grease_pencil.move_node_up(active_node);
262 grease_pencil.move_node_down(active_node);
277 ot->name =
"Reorder Layer";
278 ot->idname =
"GREASE_PENCIL_OT_layer_move";
279 ot->description =
"Move the active Grease Pencil layer or Group";
297 if (!grease_pencil.layers().index_range().contains(layer_index)) {
301 Layer &layer = grease_pencil.layer(layer_index);
302 if (grease_pencil.is_layer_active(&layer)) {
306 if (grease_pencil.has_active_group()) {
310 GreasePencilv3LayerGroup,
313 grease_pencil.set_active_layer(&layer);
326 ot->name =
"Set Active Layer";
327 ot->idname =
"GREASE_PENCIL_OT_layer_active";
328 ot->description =
"Set the active Grease Pencil layer";
337 ot->srna,
"layer", 0, 0, INT_MAX,
"Grease Pencil Layer",
"", 0, INT_MAX);
346 int new_layer_group_name_length;
348 op->
ptr,
"new_layer_group_name",
nullptr, 0, &new_layer_group_name_length);
350 LayerGroup &new_group = grease_pencil.add_layer_group(new_layer_group_name);
354 if (grease_pencil.has_active_layer()) {
355 grease_pencil.move_node_after(new_group.
as_node(),
356 grease_pencil.get_active_layer()->as_node());
360 else if (grease_pencil.has_active_group()) {
361 grease_pencil.move_node_into(new_group.
as_node(), *grease_pencil.get_active_group());
365 GreasePencilv3LayerGroup,
370 grease_pencil.set_active_node(&new_group.
as_node());
385 ot->name =
"Add New Layer Group";
386 ot->idname =
"GREASE_PENCIL_OT_layer_group_add";
387 ot->description =
"Add a new Grease Pencil layer group in the active object";
396 ot->srna,
"new_layer_group_name",
nullptr,
INT16_MAX,
"Name",
"Name of the new layer group");
407 if (!grease_pencil.has_active_group()) {
411 grease_pencil.remove_group(*grease_pencil.get_active_group(), keep_children);
427 ot->name =
"Remove Layer Group";
428 ot->idname =
"GREASE_PENCIL_OT_layer_group_remove";
429 ot->description =
"Remove Grease Pencil layer group in the active object";
440 "Keep children nodes",
441 "Keep the children nodes of the group and only delete the group itself");
450 TreeNode *active_node = grease_pencil.get_active_node();
460 for (
TreeNode *node : grease_pencil.nodes_for_write()) {
461 bool should_be_visible =
false;
464 should_be_visible = node->is_child_of(active_node->
as_group());
465 if (node->is_group()) {
466 should_be_visible |= active_node->is_child_of(node->as_group());
469 else if (node->is_group()) {
470 should_be_visible = active_node->is_child_of(node->as_group());
473 node->set_visible(should_be_visible);
475 active_node->set_visible(
true);
479 active_node->set_visible(
false);
493 ot->name =
"Hide Layer(s)";
494 ot->idname =
"GREASE_PENCIL_OT_layer_hide";
495 ot->description =
"Hide selected/unselected Grease Pencil layers";
506 ot->srna,
"unselected",
false,
"Unselected",
"Hide unselected rather than selected layers");
516 if (!grease_pencil.get_active_node()) {
520 for (
TreeNode *node : grease_pencil.nodes_for_write()) {
521 node->set_visible(
true);
535 ot->name =
"Show All Layers";
536 ot->idname =
"GREASE_PENCIL_OT_layer_reveal";
537 ot->description =
"Show all Grease Pencil layers";
552 bool isolate =
false;
554 for (
const Layer *layer : grease_pencil.layers()) {
555 if (grease_pencil.is_layer_active(layer)) {
558 if ((affect_visibility && layer->is_visible()) || !layer->is_locked()) {
564 for (
Layer *layer : grease_pencil.layers_for_write()) {
565 if (grease_pencil.is_layer_active(layer) || !isolate) {
566 layer->set_locked(
false);
567 if (affect_visibility) {
568 layer->set_visible(
true);
572 layer->set_locked(
true);
573 if (affect_visibility) {
574 layer->set_visible(
false);
589 ot->name =
"Isolate Layers";
590 ot->idname =
"GREASE_PENCIL_OT_layer_isolate";
591 ot->description =
"Make only active layer visible/editable";
602 ot->srna,
"affect_visibility",
false,
"Affect Visibility",
"Also affect the visibility");
611 if (grease_pencil.nodes().is_empty()) {
615 for (
TreeNode *node : grease_pencil.nodes_for_write()) {
616 node->set_locked(lock_value);
629 ot->name =
"Lock All Layers";
630 ot->idname =
"GREASE_PENCIL_OT_layer_lock_all";
632 "Lock all Grease Pencil layers to prevent them from being accidentally modified";
651 if (!grease_pencil.has_active_layer()) {
657 Layer &active_layer = *grease_pencil.get_active_layer();
658 Layer &new_layer = grease_pencil.duplicate_layer(active_layer);
665 for (
auto [frame_number, frame] : active_layer.
frames().
items()) {
668 Drawing *dst_drawing = grease_pencil.insert_frame(
670 if (!empty_keyframes) {
673 const Drawing &src_drawing = *grease_pencil.get_drawing_at(active_layer, frame_number);
675 *dst_drawing = src_drawing;
679 grease_pencil.move_node_after(new_layer.
as_node(), active_layer.
as_node());
680 grease_pencil.set_active_layer(&new_layer);
694 ot->name =
"Duplicate Layer";
695 ot->idname =
"GREASE_PENCIL_OT_layer_duplicate";
696 ot->description =
"Make a copy of the active Grease Pencil layer";
706 RNA_def_boolean(
ot->srna,
"empty_keyframes",
false,
"Empty Keyframes",
"Add Empty Keyframes");
724 std::string merged_layer_name;
726 if (!grease_pencil.has_active_layer()) {
730 const Layer &active_layer = *grease_pencil.get_active_layer();
732 if (prev_node ==
nullptr || !prev_node->wrap().is_layer()) {
736 const Layer &prev_layer = prev_node->wrap().as_layer();
738 const int prev_layer_index = *grease_pencil.get_layer_index(prev_layer);
739 const int active_layer_index = *grease_pencil.get_layer_index(active_layer);
744 if (layer_i == active_layer_index) {
747 else if (layer_i == prev_layer_index) {
749 src_layer_indices_by_dst_layer.
append({prev_layer_index, active_layer_index});
753 src_layer_indices_by_dst_layer.
append({layer_i});
758 merged_layer_name = grease_pencil.layer(prev_layer_index).name();
761 if (!grease_pencil.has_active_group()) {
765 LayerGroup &active_group = *grease_pencil.get_active_group();
767 if (active_group.
layers().is_empty()) {
776 grease_pencil.remove_group(*group,
true);
782 const Layer &layer = grease_pencil.layer(layer_i);
783 if (!layer.is_child_of(active_group)) {
784 src_layer_indices_by_dst_layer.
append({layer_i});
793 merged_layer_name = active_group.name();
796 grease_pencil.remove_group(active_group,
true);
800 GreasePencilv3LayerGroup,
804 grease_pencil.rename_node(
805 *bmain, grease_pencil.layer(
indices[0]).as_node(), merged_layer_name);
808 if (grease_pencil.layers().is_empty()) {
814 grease_pencil.remove_group(*group,
true);
818 for (
const int layer_i : grease_pencil.layers().index_range()) {
823 merged_layer_name =
N_(
"Layer");
824 grease_pencil.rename_node(
825 *bmain, grease_pencil.layer(
indices[0]).as_node(), merged_layer_name);
834 grease_pencil, src_layer_indices_by_dst_layer, *merged_grease_pencil);
841 TreeNode *node = grease_pencil.find_node_by_name(merged_layer_name);
844 grease_pencil.set_active_layer(&layer);
863 "Combine the active layer with the layer just below (if it exists)"},
868 "Combine layers in the active group into a single layer"},
869 {int(
MergeMode::All),
"ALL", 0,
"All",
"Combine all layers into a single layer"},
870 {0,
nullptr, 0,
nullptr,
nullptr},
874 ot->idname =
"GREASE_PENCIL_OT_layer_merge";
875 ot->description =
"Combine layers based on the mode into one layer";
890 if (!grease_pencil.has_active_layer()) {
893 Layer &active_layer = *grease_pencil.get_active_layer();
895 int mask_name_length;
899 if (
TreeNode *node = grease_pencil.find_node_by_name(mask_name)) {
900 if (grease_pencil.is_layer_active(&node->as_layer())) {
913 LayerMask *new_mask = MEM_new<LayerMask>(__func__, mask_name);
932 ot->name =
"Add New Mask Layer";
933 ot->idname =
"GREASE_PENCIL_OT_layer_mask_add";
934 ot->description =
"Add new layer as masking";
954 Layer &active_layer = *grease_pencil.get_active_layer();
964 if (!grease_pencil.has_active_layer()) {
968 Layer &active_layer = *grease_pencil.get_active_layer();
989 ot->name =
"Remove Mask Layer";
990 ot->idname =
"GREASE_PENCIL_OT_layer_mask_remove";
991 ot->description =
"Remove Layer Mask";
1008 Layer &active_layer = *grease_pencil.get_active_layer();
1018 if (!grease_pencil.has_active_layer()) {
1021 Layer &active_layer = *grease_pencil.get_active_layer();
1024 bool changed =
false;
1048 ot->name =
"Reorder Grease Pencil Layer Mask";
1049 ot->idname =
"GREASE_PENCIL_OT_layer_mask_reorder";
1050 ot->description =
"Reorder the active Grease Pencil mask layer up/down in the list";
1072 {0,
nullptr, 0,
nullptr,
nullptr},
1081 LayerGroup *active_group = grease_pencil.get_active_group();
1093 ot->name =
"Grease Pencil Group Color Tag";
1094 ot->idname =
"GREASE_PENCIL_OT_layer_group_color_tag";
1095 ot->description =
"Change layer group icon";
1114 const int current_frame)
1118 if (&dst_grease_pencil == &src_grease_pencil) {
1122 Layer &dst_layer = dst_grease_pencil.duplicate_layer(src_layer);
1125 for (
const auto [frame_number, frame] : src_layer.
frames().
items()) {
1127 (&frame != src_layer.
frame_at(current_frame)))
1133 Drawing *dst_drawing = dst_grease_pencil.insert_frame(
1135 if (dst_drawing !=
nullptr) {
1137 const Drawing &src_drawing = *src_grease_pencil.get_drawing_at(src_layer, frame_number);
1138 *dst_drawing = src_drawing;
1144 const int src_layer_index = *src_grease_pencil.get_layer_index(src_layer);
1146 Layer &dst_layer = dst_grease_pencil.add_layer(src_layer.name());
1147 const int dst_layer_index = dst_grease_pencil.layers().size() - 1;
1164 reader.
varray.
get(src_layer_index, buffer);
1170 std::optional<int> frame_select = std::nullopt;
1172 frame_select = current_frame;
1174 dst_grease_pencil.copy_frames_from_layer(
1175 dst_layer, src_grease_pencil, src_layer, frame_select);
1184 const int current_frame = scene->
r.
cfra;
1196 const Layer &active_layer = *src_grease_pencil.get_active_layer();
1198 dst_grease_pencil, src_grease_pencil, active_layer, copy_frame_mode, current_frame);
1201 for (
const Layer *layer : src_grease_pencil.layers()) {
1203 dst_grease_pencil, src_grease_pencil, *layer, copy_frame_mode, current_frame);
1218 ot->name =
"Duplicate Layer to New Object";
1219 ot->idname =
"GREASE_PENCIL_OT_layer_duplicate_object";
1220 ot->description =
"Make a copy of the active Grease Pencil layer to selected object";
1233 "Copy only active Layer, uncheck to append all layers");
1238 {0,
nullptr, 0,
nullptr,
nullptr},
bPoseChannel * BKE_pose_channel_find_name(const bPose *pose, const char *name)
#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()
void BKE_grease_pencil_copy_layer_parameters(const blender::bke::greasepencil::Layer &src, blender::bke::greasepencil::Layer &dst)
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()
#define BUFFER_FOR_CPP_TYPE_VALUE(type, variable_name)
void * BLI_findlink(const ListBase *listbase, int number) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
BLI_INLINE bool BLI_listbase_is_empty(const ListBase *lb)
void BLI_addtail(ListBase *listbase, void *vlink) ATTR_NONNULL(1)
void BLI_remlink(ListBase *listbase, void *vlink) ATTR_NONNULL(1)
void void void bool BLI_listbase_link_move(ListBase *listbase, void *vlink, int step) ATTR_NONNULL()
void * BLI_findstring_ptr(const ListBase *listbase, const char *id, int offset) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
int BLI_listbase_count(const ListBase *listbase) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
void copy_m4_m4(float m1[4][4], const float m2[4][4])
void unit_m4(float m[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)
@ BONE_RELATIVE_PARENTING
ItemIterator items() const &
void get(int64_t index, void *r_value) const
void set_by_copy(int64_t index, const void *value)
constexpr IndexRange index_range() const
constexpr const char * c_str() const
void append(const T &value)
void foreach_attribute(const FunctionRef< void(const AttributeIter &)> fn) const
GAttributeReader lookup(const StringRef attribute_id) const
eCustomDataType data_type
GAttributeWriter lookup_or_add_for_write(StringRef attribute_id, AttrDomain domain, eCustomDataType data_type, const AttributeInit &initializer=AttributeInitDefaultValue())
const TreeNode & as_node() const
int64_t num_direct_nodes() const
Span< const Layer * > layers() 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 & as_group() const
const Layer & as_layer() const
const LayerGroup * parent_group() const
MatBase< C, R > inverse(MatBase< C, R >) RET
void ED_operatortypes_grease_pencil_layers()
ccl_device_inline float2 mask(const MaskType mask, const float2 a)
const CPPType * custom_data_type_to_cpp_type(eCustomDataType type)
static void GREASE_PENCIL_OT_layer_lock_all(wmOperatorType *ot)
static wmOperatorStatus grease_pencil_layer_mask_reorder_exec(bContext *C, wmOperator *op)
static wmOperatorStatus grease_pencil_layer_mask_remove_exec(bContext *C, wmOperator *)
static bool grease_pencil_layer_mask_reorder_poll(bContext *C)
static wmOperatorStatus grease_pencil_layer_move_exec(bContext *C, wmOperator *op)
static const EnumPropertyItem enum_layer_move_direction[]
static wmOperatorStatus grease_pencil_layer_hide_exec(bContext *C, wmOperator *op)
static wmOperatorStatus grease_pencil_layer_add_invoke(bContext *C, wmOperator *op, const wmEvent *event)
GreasePencil * from_context(bContext &C)
static void GREASE_PENCIL_OT_layer_group_add(wmOperatorType *ot)
static wmOperatorStatus grease_pencil_layer_group_add_exec(bContext *C, wmOperator *op)
void grease_pencil_layer_parent_clear(bke::greasepencil::Layer &layer, const bool keep_transform)
static wmOperatorStatus grease_pencil_merge_layer_exec(bContext *C, wmOperator *op)
static wmOperatorStatus grease_pencil_layer_active_exec(bContext *C, wmOperator *op)
static void GREASE_PENCIL_OT_layer_group_color_tag(wmOperatorType *ot)
static float4x4 get_bone_mat(const Object *parent, const char *parsubstr)
static void GREASE_PENCIL_OT_layer_remove(wmOperatorType *ot)
static void GREASE_PENCIL_OT_layer_isolate(wmOperatorType *ot)
static wmOperatorStatus grease_pencil_layer_duplicate_object_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 bool grease_pencil_layer_mask_poll(bContext *C)
static wmOperatorStatus grease_pencil_layer_add_exec(bContext *C, wmOperator *op)
bool editable_grease_pencil_poll(bContext *C)
static void GREASE_PENCIL_OT_layer_mask_add(wmOperatorType *ot)
static wmOperatorStatus grease_pencil_layer_mask_add_exec(bContext *C, wmOperator *op)
static wmOperatorStatus grease_pencil_layer_remove_exec(bContext *C, wmOperator *)
static void GREASE_PENCIL_OT_layer_active(wmOperatorType *ot)
const EnumPropertyItem enum_layergroup_color_items[]
static void GREASE_PENCIL_OT_layer_move(wmOperatorType *ot)
static wmOperatorStatus grease_pencil_layer_lock_all_exec(bContext *C, wmOperator *op)
static void GREASE_PENCIL_OT_layer_duplicate_object(wmOperatorType *ot)
static void GREASE_PENCIL_OT_layer_group_remove(wmOperatorType *ot)
static void GREASE_PENCIL_OT_layer_duplicate(wmOperatorType *ot)
static wmOperatorStatus grease_pencil_layer_group_remove_exec(bContext *C, wmOperator *op)
bool grease_pencil_layer_parent_set(bke::greasepencil::Layer &layer, Object *parent, StringRefNull bone, const bool keep_transform)
bool grease_pencil_context_poll(bContext *C)
static wmOperatorStatus grease_pencil_layer_duplicate_exec(bContext *C, wmOperator *op)
static void GREASE_PENCIL_OT_layer_mask_reorder(wmOperatorType *ot)
void merge_layers(const GreasePencil &src_grease_pencil, const Span< Vector< int > > src_layer_indices_by_dst_layer, GreasePencil &dst_grease_pencil)
bool active_grease_pencil_layer_group_poll(bContext *C)
static wmOperatorStatus grease_pencil_layer_group_color_tag_exec(bContext *C, wmOperator *op)
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 wmOperatorStatus grease_pencil_layer_reveal_exec(bContext *C, wmOperator *)
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 wmOperatorStatus grease_pencil_layer_isolate_exec(bContext *C, wmOperator *op)
static bool grease_pencil_layer_move_poll(bContext *C)
CartesianBasis invert(const CartesianBasis &basis)
MatBase< float, 4, 4 > float4x4
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
static MatBase identity()
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 *))
wmOperatorStatus 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)