Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--release/scripts/startup/bl_ui/properties_data_gpencil.py3
-rw-r--r--release/scripts/startup/bl_ui/properties_material_gpencil.py4
-rw-r--r--release/scripts/startup/bl_ui/space_view3d.py86
-rw-r--r--source/blender/editors/gpencil/gpencil_data.c177
-rw-r--r--source/blender/editors/gpencil/gpencil_intern.h1
-rw-r--r--source/blender/editors/gpencil/gpencil_ops.c1
6 files changed, 221 insertions, 51 deletions
diff --git a/release/scripts/startup/bl_ui/properties_data_gpencil.py b/release/scripts/startup/bl_ui/properties_data_gpencil.py
index 69720a6c54b..d88c9a3502d 100644
--- a/release/scripts/startup/bl_ui/properties_data_gpencil.py
+++ b/release/scripts/startup/bl_ui/properties_data_gpencil.py
@@ -113,7 +113,8 @@ class GPENCIL_MT_layer_context_menu(Menu):
layout.operator("gpencil.layer_merge", icon='SORT_ASC', text="Merge Down")
layout.separator()
- layout.menu("VIEW3D_MT_gpencil_copy_layer")
+ layout.menu("VIEW3D_MT_gpencil_append_active_layer")
+ layout.menu("VIEW3D_MT_gpencil_append_all_layers")
class DATA_PT_gpencil_layers(DataButtonsPanel, Panel):
diff --git a/release/scripts/startup/bl_ui/properties_material_gpencil.py b/release/scripts/startup/bl_ui/properties_material_gpencil.py
index 6a5c000116f..ed5863b463a 100644
--- a/release/scripts/startup/bl_ui/properties_material_gpencil.py
+++ b/release/scripts/startup/bl_ui/properties_material_gpencil.py
@@ -53,6 +53,10 @@ class GPENCIL_MT_material_context_menu(Menu):
layout.operator("gpencil.material_to_vertex_color", text="Convert Materials to Vertex Color")
layout.operator("gpencil.extract_palette_vertex", text="Extract Palette from Vertex Color")
+ layout.separator()
+ layout.menu("VIEW3D_MT_gpencil_append_active_material")
+ layout.menu("VIEW3D_MT_gpencil_append_all_materials")
+
class GPENCIL_UL_matslots(UIList):
def draw_item(self, _context, layout, _data, item, icon, _active_data, _active_propname, _index):
diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py
index bdc924e3197..4b06a2df3a0 100644
--- a/release/scripts/startup/bl_ui/space_view3d.py
+++ b/release/scripts/startup/bl_ui/space_view3d.py
@@ -4956,26 +4956,73 @@ class VIEW3D_MT_assign_material(Menu):
icon='LAYER_ACTIVE' if mat == mat_active else 'BLANK1').material = mat.name
-class VIEW3D_MT_gpencil_copy_layer(Menu):
- bl_label = "Copy Layer to Object"
+def gpencil_layer_append_menu_items(context, layout, only_active):
+ done = False
+ view_layer = context.view_layer
+ obact = context.active_object
+ gpl = context.active_gpencil_layer
+
+ done = False
+ if gpl is not None:
+ for ob in view_layer.objects:
+ if ob.type == 'GPENCIL' and ob != obact:
+ op = layout.operator("gpencil.layer_duplicate_object", text=ob.name)
+ op.object = ob.name
+ op.only_active = only_active
+ done = True
+
+ if done is False:
+ layout.label(text="No destination object", icon='ERROR')
+ else:
+ layout.label(text="No layer to copy", icon='ERROR')
+
+
+class VIEW3D_MT_gpencil_append_active_layer(Menu):
+ bl_label = "Append Active Layer to Object"
def draw(self, context):
layout = self.layout
- view_layer = context.view_layer
- obact = context.active_object
- gpl = context.active_gpencil_layer
-
- done = False
- if gpl is not None:
- for ob in view_layer.objects:
- if ob.type == 'GPENCIL' and ob != obact:
- layout.operator("gpencil.layer_duplicate_object", text=ob.name).object = ob.name
- done = True
-
- if done is False:
- layout.label(text="No destination object", icon='ERROR')
- else:
- layout.label(text="No layer to copy", icon='ERROR')
+ gpencil_layer_append_menu_items(context, layout, True)
+
+
+class VIEW3D_MT_gpencil_append_all_layers(Menu):
+ bl_label = "Append All Layers to Object"
+
+ def draw(self, context):
+ layout = self.layout
+ gpencil_layer_append_menu_items(context, layout, False)
+
+
+def gpencil_material_menu_items(context, layout, only_selected):
+ done = False
+ view_layer = context.view_layer
+ obact = context.active_object
+
+ for ob in view_layer.objects:
+ if ob.type == 'GPENCIL' and ob != obact:
+ op = layout.operator("gpencil.materials_append_to_object", text=ob.name)
+ op.object = ob.name
+ op.only_selected = only_selected
+ done = True
+
+ if done is False:
+ layout.label(text="No destination object", icon='ERROR')
+
+
+class VIEW3D_MT_gpencil_append_active_material(Menu):
+ bl_label = "Append Active Material to Object"
+
+ def draw(self, context):
+ layout = self.layout
+ gpencil_material_menu_items(context, layout, True)
+
+
+class VIEW3D_MT_gpencil_append_all_materials(Menu):
+ bl_label = "Append All Materials to Object"
+
+ def draw(self, context):
+ layout = self.layout
+ gpencil_material_menu_items(context, layout, False)
class VIEW3D_MT_edit_gpencil(Menu):
@@ -7642,7 +7689,10 @@ classes = (
VIEW3D_MT_weight_gpencil,
VIEW3D_MT_gpencil_animation,
VIEW3D_MT_gpencil_simplify,
- VIEW3D_MT_gpencil_copy_layer,
+ VIEW3D_MT_gpencil_append_active_layer,
+ VIEW3D_MT_gpencil_append_all_layers,
+ VIEW3D_MT_gpencil_append_active_material,
+ VIEW3D_MT_gpencil_append_all_materials,
VIEW3D_MT_gpencil_autoweights,
VIEW3D_MT_gpencil_edit_context_menu,
VIEW3D_MT_edit_curve,
diff --git a/source/blender/editors/gpencil/gpencil_data.c b/source/blender/editors/gpencil/gpencil_data.c
index c93fcb9eb8c..c5f094e030a 100644
--- a/source/blender/editors/gpencil/gpencil_data.c
+++ b/source/blender/editors/gpencil/gpencil_data.c
@@ -557,6 +557,7 @@ static int gpencil_layer_duplicate_object_exec(bContext *C, wmOperator *op)
if (name[0] == '\0') {
return OPERATOR_CANCELLED;
}
+ const bool only_active = RNA_boolean_get(op->ptr, "only_active");
Object *ob_dst = (Object *)BKE_scene_object_find_by_name(scene, name);
@@ -564,10 +565,10 @@ static int gpencil_layer_duplicate_object_exec(bContext *C, wmOperator *op)
Object *ob_src = CTX_data_active_object(C);
bGPdata *gpd_src = (bGPdata *)ob_src->data;
- bGPDlayer *gpl_src = BKE_gpencil_layer_active_get(gpd_src);
+ bGPDlayer *gpl_active = BKE_gpencil_layer_active_get(gpd_src);
/* Sanity checks. */
- if (ELEM(NULL, gpd_src, gpl_src, ob_dst)) {
+ if (ELEM(NULL, gpd_src, ob_dst)) {
return OPERATOR_CANCELLED;
}
/* Cannot copy itself and check destination type. */
@@ -576,47 +577,55 @@ static int gpencil_layer_duplicate_object_exec(bContext *C, wmOperator *op)
}
bGPdata *gpd_dst = (bGPdata *)ob_dst->data;
+ /* Disable destination active layer to keep order. */
+ LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd_dst->layers) {
+ gpl->flag &= ~GP_LAYER_ACTIVE;
+ }
- /* Create new layer. */
- bGPDlayer *gpl_dst = BKE_gpencil_layer_addnew(gpd_dst, gpl_src->info, true);
- /* Need to copy some variables (not all). */
- gpl_dst->onion_flag = gpl_src->onion_flag;
- gpl_dst->thickness = gpl_src->thickness;
- gpl_dst->line_change = gpl_src->line_change;
- copy_v4_v4(gpl_dst->tintcolor, gpl_src->tintcolor);
- gpl_dst->opacity = gpl_src->opacity;
-
- /* Create all frames. */
- LISTBASE_FOREACH (bGPDframe *, gpf_src, &gpl_src->frames) {
-
- if ((mode == GP_LAYER_COPY_OBJECT_ACT_FRAME) && (gpf_src != gpl_src->actframe)) {
+ LISTBASE_FOREACH (bGPDlayer *, gpl_src, &gpd_src->layers) {
+ if ((only_active) && (gpl_src != gpl_active)) {
continue;
}
+ /* Create new layer. */
+ bGPDlayer *gpl_dst = BKE_gpencil_layer_addnew(gpd_dst, gpl_src->info, true);
+ /* Need to copy some variables (not all). */
+ gpl_dst->onion_flag = gpl_src->onion_flag;
+ gpl_dst->thickness = gpl_src->thickness;
+ gpl_dst->line_change = gpl_src->line_change;
+ copy_v4_v4(gpl_dst->tintcolor, gpl_src->tintcolor);
+ gpl_dst->opacity = gpl_src->opacity;
- /* Create new frame. */
- bGPDframe *gpf_dst = BKE_gpencil_frame_addnew(gpl_dst, gpf_src->framenum);
+ /* Create all frames. */
+ LISTBASE_FOREACH (bGPDframe *, gpf_src, &gpl_src->frames) {
- /* Copy strokes. */
- LISTBASE_FOREACH (bGPDstroke *, gps_src, &gpf_src->strokes) {
+ if ((mode == GP_LAYER_COPY_OBJECT_ACT_FRAME) && (gpf_src != gpl_src->actframe)) {
+ continue;
+ }
- /* Make copy of source stroke. */
- bGPDstroke *gps_dst = BKE_gpencil_stroke_duplicate(gps_src, true, true);
+ /* Create new frame. */
+ bGPDframe *gpf_dst = BKE_gpencil_frame_addnew(gpl_dst, gpf_src->framenum);
- /* Check if material is in destination object,
- * otherwise add the slot with the material. */
- Material *ma_src = BKE_object_material_get(ob_src, gps_src->mat_nr + 1);
- if (ma_src != NULL) {
- int idx = BKE_gpencil_object_material_ensure(bmain, ob_dst, ma_src);
+ /* Copy strokes. */
+ LISTBASE_FOREACH (bGPDstroke *, gps_src, &gpf_src->strokes) {
- /* Reassign the stroke material to the right slot in destination object. */
- gps_dst->mat_nr = idx;
- }
+ /* Make copy of source stroke. */
+ bGPDstroke *gps_dst = BKE_gpencil_stroke_duplicate(gps_src, true, true);
+
+ /* Check if material is in destination object,
+ * otherwise add the slot with the material. */
+ Material *ma_src = BKE_object_material_get(ob_src, gps_src->mat_nr + 1);
+ if (ma_src != NULL) {
+ int idx = BKE_gpencil_object_material_ensure(bmain, ob_dst, ma_src);
- /* Add new stroke to frame. */
- BLI_addtail(&gpf_dst->strokes, gps_dst);
+ /* Reassign the stroke material to the right slot in destination object. */
+ gps_dst->mat_nr = idx;
+ }
+
+ /* Add new stroke to frame. */
+ BLI_addtail(&gpf_dst->strokes, gps_dst);
+ }
}
}
-
/* notifiers */
DEG_id_tag_update(&gpd_dst->id,
ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY | ID_RECALC_COPY_ON_WRITE);
@@ -628,6 +637,8 @@ static int gpencil_layer_duplicate_object_exec(bContext *C, wmOperator *op)
void GPENCIL_OT_layer_duplicate_object(wmOperatorType *ot)
{
+ PropertyRNA *prop;
+
static const EnumPropertyItem copy_mode[] = {
{GP_LAYER_COPY_OBJECT_ALL_FRAME, "ALL", 0, "All Frames", ""},
{GP_LAYER_COPY_OBJECT_ACT_FRAME, "ACTIVE", 0, "Active Frame", ""},
@@ -651,6 +662,13 @@ void GPENCIL_OT_layer_duplicate_object(wmOperatorType *ot)
RNA_def_property_flag(ot->prop, PROP_HIDDEN | PROP_SKIP_SAVE);
RNA_def_enum(ot->srna, "mode", copy_mode, GP_LAYER_COPY_OBJECT_ALL_FRAME, "Mode", "");
+
+ prop = RNA_def_boolean(ot->srna,
+ "only_active",
+ true,
+ "Only Active",
+ "Append only active Layer, uncheck to append all layers");
+ RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
}
/* ********************* Duplicate Frame ************************** */
@@ -3589,6 +3607,101 @@ void GPENCIL_OT_set_active_material(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
+/* ********************* Append Materials in a new object ************************** */
+static bool gpencil_materials_append_to_object_poll(bContext *C)
+{
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ Object *ob = CTX_data_active_object(C);
+ if ((ob == NULL) || (ob->type != OB_GPENCIL)) {
+ return false;
+ }
+ short *totcolp = BKE_object_material_len_p(ob);
+ if (*totcolp == 0) {
+ return false;
+ }
+
+ /* check there are more grease pencil objects */
+ LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) {
+ if ((base->object != ob) && (base->object->type == OB_GPENCIL)) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+static int gpencil_materials_append_to_object_exec(bContext *C, wmOperator *op)
+{
+ Main *bmain = CTX_data_main(C);
+ Scene *scene = CTX_data_scene(C);
+ char name[MAX_ID_NAME - 2];
+ RNA_string_get(op->ptr, "object", name);
+
+ if (name[0] == '\0') {
+ return OPERATOR_CANCELLED;
+ }
+ const bool only_selected = RNA_boolean_get(op->ptr, "only_selected");
+
+ Object *ob_dst = (Object *)BKE_scene_object_find_by_name(scene, name);
+ Object *ob_src = CTX_data_active_object(C);
+ Material *ma_active = BKE_gpencil_material(ob_src, ob_src->actcol);
+
+ /* Sanity checks. */
+ if (ELEM(NULL, ob_src, ob_dst)) {
+ return OPERATOR_CANCELLED;
+ }
+ /* Cannot copy itself and check destination type. */
+ if ((ob_src == ob_dst) || (ob_dst->type != OB_GPENCIL)) {
+ return OPERATOR_CANCELLED;
+ }
+
+ /* Duplicate materials. */
+ for (short i = 0; i < ob_src->totcol; i++) {
+ Material *ma_src = BKE_object_material_get(ob_src, i + 1);
+ if (only_selected && ma_src != ma_active) {
+ continue;
+ }
+
+ if (ma_src != NULL) {
+ BKE_gpencil_object_material_ensure(bmain, ob_dst, ma_src);
+ }
+ }
+
+ /* notifiers */
+ DEG_id_tag_update(&ob_dst->id, ID_RECALC_COPY_ON_WRITE);
+ WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
+
+ return OPERATOR_FINISHED;
+}
+
+void GPENCIL_OT_materials_append_to_object(wmOperatorType *ot)
+{
+ PropertyRNA *prop;
+
+ /* identifiers */
+ ot->name = "Append Materials to New Object";
+ ot->idname = "GPENCIL_OT_materials_append_to_object";
+ ot->description = "Append Materials of the active Grease Pencil to other object";
+
+ /* callbacks */
+ ot->exec = gpencil_materials_append_to_object_exec;
+ ot->poll = gpencil_materials_append_to_object_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ ot->prop = RNA_def_string(
+ ot->srna, "object", NULL, MAX_ID_NAME - 2, "Object", "Name of the destination object");
+ RNA_def_property_flag(ot->prop, PROP_HIDDEN | PROP_SKIP_SAVE);
+
+ prop = RNA_def_boolean(ot->srna,
+ "only_selected",
+ true,
+ "Only Selected",
+ "Append only selected material, uncheck to append all materials");
+ RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
+}
+
/* Parent GPencil object to Lattice */
bool ED_gpencil_add_lattice_modifier(const bContext *C,
ReportList *reports,
diff --git a/source/blender/editors/gpencil/gpencil_intern.h b/source/blender/editors/gpencil/gpencil_intern.h
index 09200125cb7..cce56acd3e4 100644
--- a/source/blender/editors/gpencil/gpencil_intern.h
+++ b/source/blender/editors/gpencil/gpencil_intern.h
@@ -538,6 +538,7 @@ void GPENCIL_OT_material_lock_unused(struct wmOperatorType *ot);
void GPENCIL_OT_material_select(struct wmOperatorType *ot);
void GPENCIL_OT_material_set(struct wmOperatorType *ot);
void GPENCIL_OT_set_active_material(struct wmOperatorType *ot);
+void GPENCIL_OT_materials_append_to_object(struct wmOperatorType *ot);
/* convert old 2.7 files to 2.8 */
void GPENCIL_OT_convert_old_files(struct wmOperatorType *ot);
diff --git a/source/blender/editors/gpencil/gpencil_ops.c b/source/blender/editors/gpencil/gpencil_ops.c
index 7d454eb3be1..6ac1161bff8 100644
--- a/source/blender/editors/gpencil/gpencil_ops.c
+++ b/source/blender/editors/gpencil/gpencil_ops.c
@@ -651,6 +651,7 @@ void ED_operatortypes_gpencil(void)
WM_operatortype_append(GPENCIL_OT_material_to_vertex_color);
WM_operatortype_append(GPENCIL_OT_extract_palette_vertex);
+ WM_operatortype_append(GPENCIL_OT_materials_append_to_object);
WM_operatortype_append(GPENCIL_OT_transform_fill);
WM_operatortype_append(GPENCIL_OT_reset_transform_fill);