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);
119 Layer &new_layer = grease_pencil.add_layer(new_layer_name);
123 if (grease_pencil.has_active_layer()) {
124 grease_pencil.move_node_after(new_layer.
as_node(),
125 grease_pencil.get_active_layer()->as_node());
127 else if (grease_pencil.has_active_group()) {
128 grease_pencil.move_node_into(new_layer.
as_node(), *grease_pencil.get_active_group());
132 GreasePencilv3LayerGroup,
136 grease_pencil.set_active_layer(&new_layer);
140 grease_pencil.insert_frame(new_layer, scene->
r.
cfra);
155 IFACE_(
"Add New Grease Pencil Layer"),
162 ot->name =
"Add New Layer";
163 ot->idname =
"GREASE_PENCIL_OT_layer_add";
164 ot->description =
"Add a new Grease Pencil layer in the active object";
174 ot->srna,
"new_layer_name",
"Layer",
INT16_MAX,
"Name",
"Name of the new layer");
184 if (!grease_pencil.has_active_layer()) {
188 grease_pencil.remove_layer(*grease_pencil.get_active_layer());
204 ot->name =
"Remove Layer";
205 ot->idname =
"GREASE_PENCIL_OT_layer_remove";
206 ot->description =
"Remove the active Grease Pencil layer";
220 {0,
nullptr, 0,
nullptr,
nullptr},
231 const TreeNode *active_node = grease_pencil.get_active_node();
233 if (active_node ==
nullptr) {
253 TreeNode &active_node = *grease_pencil.get_active_node();
256 grease_pencil.move_node_up(active_node);
259 grease_pencil.move_node_down(active_node);
274 ot->name =
"Reorder Layer";
275 ot->idname =
"GREASE_PENCIL_OT_layer_move";
276 ot->description =
"Move the active Grease Pencil layer or Group";
294 if (!grease_pencil.layers().index_range().contains(layer_index)) {
298 Layer &layer = grease_pencil.layer(layer_index);
299 if (grease_pencil.is_layer_active(&layer)) {
303 if (grease_pencil.has_active_group()) {
307 GreasePencilv3LayerGroup,
310 grease_pencil.set_active_layer(&layer);
323 ot->name =
"Set Active Layer";
324 ot->idname =
"GREASE_PENCIL_OT_layer_active";
325 ot->description =
"Set the active Grease Pencil layer";
334 ot->srna,
"layer", 0, 0, INT_MAX,
"Grease Pencil Layer",
"", 0, INT_MAX);
343 std::string new_layer_group_name =
RNA_string_get(op->
ptr,
"new_layer_group_name");
345 LayerGroup &new_group = grease_pencil.add_layer_group(new_layer_group_name);
349 if (grease_pencil.has_active_layer()) {
350 grease_pencil.move_node_after(new_group.
as_node(),
351 grease_pencil.get_active_layer()->as_node());
355 else if (grease_pencil.has_active_group()) {
356 grease_pencil.move_node_into(new_group.
as_node(), *grease_pencil.get_active_group());
360 GreasePencilv3LayerGroup,
364 grease_pencil.set_active_node(&new_group.
as_node());
379 ot->name =
"Add New Layer Group";
380 ot->idname =
"GREASE_PENCIL_OT_layer_group_add";
381 ot->description =
"Add a new Grease Pencil layer group in the active object";
390 ot->srna,
"new_layer_group_name",
nullptr,
INT16_MAX,
"Name",
"Name of the new layer group");
401 if (!grease_pencil.has_active_group()) {
405 grease_pencil.remove_group(*grease_pencil.get_active_group(), keep_children);
421 ot->name =
"Remove Layer Group";
422 ot->idname =
"GREASE_PENCIL_OT_layer_group_remove";
423 ot->description =
"Remove Grease Pencil layer group in the active object";
434 "Keep children nodes",
435 "Keep the children nodes of the group and only delete the group itself");
444 TreeNode *active_node = grease_pencil.get_active_node();
454 for (
TreeNode *node : grease_pencil.nodes_for_write()) {
455 bool should_be_visible =
false;
458 should_be_visible = node->is_child_of(active_node->
as_group());
459 if (node->is_group()) {
460 should_be_visible |= active_node->is_child_of(node->as_group());
463 else if (node->is_group()) {
464 should_be_visible = active_node->is_child_of(node->as_group());
467 node->set_visible(should_be_visible);
469 active_node->set_visible(
true);
473 active_node->set_visible(
false);
487 ot->name =
"Hide Layer(s)";
488 ot->idname =
"GREASE_PENCIL_OT_layer_hide";
489 ot->description =
"Hide selected/unselected Grease Pencil layers";
500 ot->srna,
"unselected",
false,
"Unselected",
"Hide unselected rather than selected layers");
510 if (!grease_pencil.get_active_node()) {
514 for (
TreeNode *node : grease_pencil.nodes_for_write()) {
515 node->set_visible(
true);
529 ot->name =
"Show All Layers";
530 ot->idname =
"GREASE_PENCIL_OT_layer_reveal";
531 ot->description =
"Show all Grease Pencil layers";
546 bool isolate =
false;
548 for (
const Layer *layer : grease_pencil.layers()) {
549 if (grease_pencil.is_layer_active(layer)) {
552 if ((affect_visibility && layer->is_visible()) || !layer->is_locked()) {
558 for (
Layer *layer : grease_pencil.layers_for_write()) {
559 if (grease_pencil.is_layer_active(layer) || !isolate) {
560 layer->set_locked(
false);
561 if (affect_visibility) {
562 layer->set_visible(
true);
566 layer->set_locked(
true);
567 if (affect_visibility) {
568 layer->set_visible(
false);
583 ot->name =
"Isolate Layers";
584 ot->idname =
"GREASE_PENCIL_OT_layer_isolate";
585 ot->description =
"Make only active layer visible/editable";
596 ot->srna,
"affect_visibility",
false,
"Affect Visibility",
"Also affect the visibility");
605 if (grease_pencil.nodes().is_empty()) {
609 for (
TreeNode *node : grease_pencil.nodes_for_write()) {
610 node->set_locked(lock_value);
623 ot->name =
"Lock All Layers";
624 ot->idname =
"GREASE_PENCIL_OT_layer_lock_all";
626 "Lock all Grease Pencil layers to prevent them from being accidentally modified";
645 if (!grease_pencil.has_active_layer()) {
651 Layer &active_layer = *grease_pencil.get_active_layer();
652 const bool duplicate_frames =
true;
653 const bool duplicate_drawings = !empty_keyframes;
654 Layer &new_layer = grease_pencil.duplicate_layer(
655 active_layer, duplicate_frames, duplicate_drawings);
660 grease_pencil.move_node_after(new_layer.
as_node(), active_layer.
as_node());
661 grease_pencil.set_active_layer(&new_layer);
675 ot->name =
"Duplicate Layer";
676 ot->idname =
"GREASE_PENCIL_OT_layer_duplicate";
677 ot->description =
"Make a copy of the active Grease Pencil layer";
687 RNA_def_boolean(
ot->srna,
"empty_keyframes",
false,
"Empty Keyframes",
"Add Empty Keyframes");
705 std::string merged_layer_name;
707 if (!grease_pencil.has_active_layer()) {
711 const Layer &active_layer = *grease_pencil.get_active_layer();
713 if (prev_node ==
nullptr || !prev_node->wrap().is_layer()) {
717 const Layer &prev_layer = prev_node->wrap().as_layer();
719 const int prev_layer_index = *grease_pencil.get_layer_index(prev_layer);
720 const int active_layer_index = *grease_pencil.get_layer_index(active_layer);
725 if (layer_i == active_layer_index) {
728 else if (layer_i == prev_layer_index) {
730 src_layer_indices_by_dst_layer.
append({prev_layer_index, active_layer_index});
734 src_layer_indices_by_dst_layer.
append({layer_i});
739 merged_layer_name = grease_pencil.layer(prev_layer_index).name();
742 if (!grease_pencil.has_active_group()) {
746 LayerGroup &active_group = *grease_pencil.get_active_group();
748 if (active_group.
layers().is_empty()) {
757 grease_pencil.remove_group(*group,
true);
763 const Layer &layer = grease_pencil.layer(layer_i);
764 if (!layer.is_child_of(active_group)) {
765 src_layer_indices_by_dst_layer.
append({layer_i});
774 merged_layer_name = active_group.name();
777 grease_pencil.remove_group(active_group,
true);
781 GreasePencilv3LayerGroup,
785 grease_pencil.rename_node(
786 *bmain, grease_pencil.layer(
indices[0]).as_node(), merged_layer_name);
789 if (grease_pencil.layers().is_empty()) {
795 grease_pencil.remove_group(*group,
true);
799 for (
const int layer_i : grease_pencil.layers().index_range()) {
804 merged_layer_name =
N_(
"Layer");
805 grease_pencil.rename_node(
806 *bmain, grease_pencil.layer(
indices[0]).as_node(), merged_layer_name);
815 grease_pencil, src_layer_indices_by_dst_layer, *merged_grease_pencil);
822 TreeNode *node = grease_pencil.find_node_by_name(merged_layer_name);
825 grease_pencil.set_active_layer(&layer);
844 "Combine the active layer with the layer just below (if it exists)"},
849 "Combine layers in the active group into a single layer"},
850 {int(
MergeMode::All),
"ALL", 0,
"All",
"Combine all layers into a single layer"},
851 {0,
nullptr, 0,
nullptr,
nullptr},
855 ot->idname =
"GREASE_PENCIL_OT_layer_merge";
856 ot->description =
"Combine layers based on the mode into one layer";
871 if (!grease_pencil.has_active_layer()) {
874 Layer &active_layer = *grease_pencil.get_active_layer();
878 if (
TreeNode *node = grease_pencil.find_node_by_name(mask_name)) {
879 if (grease_pencil.is_layer_active(&node->as_layer())) {
892 LayerMask *new_mask = MEM_new<LayerMask>(__func__, mask_name);
911 ot->name =
"Add New Mask Layer";
912 ot->idname =
"GREASE_PENCIL_OT_layer_mask_add";
913 ot->description =
"Add new layer as masking";
933 Layer &active_layer = *grease_pencil.get_active_layer();
943 if (!grease_pencil.has_active_layer()) {
947 Layer &active_layer = *grease_pencil.get_active_layer();
968 ot->name =
"Remove Mask Layer";
969 ot->idname =
"GREASE_PENCIL_OT_layer_mask_remove";
970 ot->description =
"Remove Layer Mask";
987 Layer &active_layer = *grease_pencil.get_active_layer();
997 if (!grease_pencil.has_active_layer()) {
1000 Layer &active_layer = *grease_pencil.get_active_layer();
1003 bool changed =
false;
1027 ot->name =
"Reorder Grease Pencil Layer Mask";
1028 ot->idname =
"GREASE_PENCIL_OT_layer_mask_reorder";
1029 ot->description =
"Reorder the active Grease Pencil mask layer up/down in the list";
1051 {0,
nullptr, 0,
nullptr,
nullptr},
1060 LayerGroup *active_group = grease_pencil.get_active_group();
1072 ot->name =
"Grease Pencil Group Color Tag";
1073 ot->idname =
"GREASE_PENCIL_OT_layer_group_color_tag";
1074 ot->description =
"Change layer group icon";
1094 const int current_frame)
1097 BLI_assert(&src_grease_pencil != &dst_grease_pencil);
1100 const int src_layer_index = *src_grease_pencil.get_layer_index(src_layer);
1102 Layer &dst_layer = dst_grease_pencil.add_layer(src_layer.name());
1103 const int dst_layer_index = dst_grease_pencil.layers().size() - 1;
1120 reader.
varray.
get(src_layer_index, buffer);
1126 std::optional<int> frame_select = std::nullopt;
1128 frame_select = current_frame;
1130 dst_grease_pencil.copy_frames_from_layer(dst_layer, src_grease_pencil, src_layer, frame_select);
1138 const int current_frame = scene->
r.
cfra;
1150 const Layer &active_layer = *src_grease_pencil.get_active_layer();
1152 dst_grease_pencil, src_grease_pencil, active_layer, copy_frame_mode, current_frame);
1155 for (
const Layer *layer : src_grease_pencil.layers()) {
1157 dst_grease_pencil, src_grease_pencil, *layer, copy_frame_mode, current_frame);
1172 ot->name =
"Duplicate Layer to New Object";
1173 ot->idname =
"GREASE_PENCIL_OT_layer_duplicate_object";
1174 ot->description =
"Make a copy of the active Grease Pencil layer to selected object";
1187 "Copy only active Layer, uncheck to append all layers");
1192 {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])
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
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
GAttributeWriter lookup_or_add_for_write(StringRef attribute_id, AttrDomain domain, AttrType 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 TreeNode & as_node() const
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 & attribute_type_to_cpp_type(AttrType 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 void copy_layer_and_frames_to_target_object(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_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 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)
std::string RNA_string_get(PointerRNA *ptr, const char *name)
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, std::optional< std::string > message)