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:
authorAntonioya <blendergit@gmail.com>2018-11-28 21:19:01 +0300
committerAntonioya <blendergit@gmail.com>2018-11-28 21:19:53 +0300
commit303b49ea37b7e1be96f357436428806b950897c1 (patch)
treeefbbab9298dd67125a5cd220fff0c1a6527c09d8
parent565de7750b95db4296c421de9e96a8d334319e03 (diff)
Add Onion Skin support to Annotations
The old onion skinning used in 2.7x has been ported and converted to 2.8. Only basic features have been included. For more advanced onion skin features, use grease pencil objects. Onion Skin is supported in View 3D and Sequencer.
-rw-r--r--release/scripts/startup/bl_ui/properties_grease_pencil_common.py48
-rw-r--r--release/scripts/startup/bl_ui/space_sequencer.py12
-rw-r--r--release/scripts/startup/bl_ui/space_view3d.py12
-rw-r--r--source/blender/blenkernel/intern/gpencil.c3
-rw-r--r--source/blender/blenloader/intern/versioning_280.c13
-rw-r--r--source/blender/editors/gpencil/annotate_draw.c98
-rw-r--r--source/blender/makesdna/DNA_gpencil_types.h8
-rw-r--r--source/blender/makesrna/intern/rna_gpencil.c38
8 files changed, 223 insertions, 9 deletions
diff --git a/release/scripts/startup/bl_ui/properties_grease_pencil_common.py b/release/scripts/startup/bl_ui/properties_grease_pencil_common.py
index b18254a9102..ff294e7d922 100644
--- a/release/scripts/startup/bl_ui/properties_grease_pencil_common.py
+++ b/release/scripts/startup/bl_ui/properties_grease_pencil_common.py
@@ -779,6 +779,54 @@ class AnnotationDataPanel:
row.operator("gpencil.active_frame_delete", text="", icon='X')
+class AnnotationOnionSkin:
+ bl_label = "Onion Skin"
+ bl_region_type = 'UI'
+ bl_options = {'DEFAULT_CLOSED'}
+
+ @classmethod
+ def poll(cls, context):
+ # Show this panel as long as someone that might own this exists
+ # AND the owner isn't an object (e.g. GP Object)
+ if context.gpencil_data_owner is None:
+ return False
+ elif type(context.gpencil_data_owner) is bpy.types.Object:
+ return False
+ else:
+ gpl = context.active_gpencil_layer
+ if gpl is None:
+ return False
+
+ return True
+
+ @staticmethod
+ def draw_header(self, context):
+ gpl = context.active_gpencil_layer
+ self.layout.prop(gpl, "use_annotation_onion_skinning", text="")
+
+ @staticmethod
+ def draw(self, context):
+ layout = self.layout
+ layout.use_property_decorate = False
+
+ gpl = context.active_gpencil_layer
+ col = layout.column()
+ split = col.split(factor=0.5)
+ split.active = gpl.use_annotation_onion_skinning
+
+ # - Before Frames
+ sub = split.column(align=True)
+ row = sub.row(align=True)
+ row.prop(gpl, "annotation_onion_before_color", text="")
+ sub.prop(gpl, "annotation_onion_before_range", text="Before")
+
+ # - After Frames
+ sub = split.column(align=True)
+ row = sub.row(align=True)
+ row.prop(gpl, "annotation_onion_after_color", text="")
+ sub.prop(gpl, "annotation_onion_after_range", text="After")
+
+
class GreasePencilOnionPanel:
@staticmethod
def draw_settings(layout, gp):
diff --git a/release/scripts/startup/bl_ui/space_sequencer.py b/release/scripts/startup/bl_ui/space_sequencer.py
index eb72d5cabb6..199b1f98fa9 100644
--- a/release/scripts/startup/bl_ui/space_sequencer.py
+++ b/release/scripts/startup/bl_ui/space_sequencer.py
@@ -22,6 +22,7 @@ from bpy.types import Header, Menu, Panel
from rna_prop_ui import PropertyPanel
from .properties_grease_pencil_common import (
AnnotationDataPanel,
+ AnnotationOnionSkin,
GreasePencilToolsPanel,
)
from bpy.app.translations import pgettext_iface as iface_
@@ -1335,6 +1336,16 @@ class SEQUENCER_PT_grease_pencil(AnnotationDataPanel, SequencerButtonsPanel_Outp
# But, it should only show up when there are images in the preview region
+class SEQUENCER_PT_annotation_onion(AnnotationOnionSkin, SequencerButtonsPanel_Output, Panel):
+ bl_space_type = 'SEQUENCE_EDITOR'
+ bl_region_type = 'UI'
+ bl_category = "Strip"
+ bl_parent_id = 'SEQUENCER_PT_grease_pencil'
+
+ # NOTE: this is just a wrapper around the generic GP Panel
+ # But, it should only show up when there are images in the preview region
+
+
class SEQUENCER_PT_grease_pencil_tools(GreasePencilToolsPanel, SequencerButtonsPanel_Output, Panel):
bl_space_type = 'SEQUENCE_EDITOR'
bl_region_type = 'UI'
@@ -1381,6 +1392,7 @@ classes = (
SEQUENCER_PT_view_safe_areas,
SEQUENCER_PT_modifiers,
SEQUENCER_PT_grease_pencil,
+ SEQUENCER_PT_annotation_onion,
SEQUENCER_PT_grease_pencil_tools,
SEQUENCER_PT_custom_props,
)
diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py
index 8eac3cec976..5321c7d655e 100644
--- a/release/scripts/startup/bl_ui/space_view3d.py
+++ b/release/scripts/startup/bl_ui/space_view3d.py
@@ -20,7 +20,7 @@
import bpy
from bpy.types import Header, Menu, Panel
from .properties_paint_common import UnifiedPaintPanel
-from .properties_grease_pencil_common import AnnotationDataPanel
+from .properties_grease_pencil_common import AnnotationDataPanel, AnnotationOnionSkin
from bpy.app.translations import contexts as i18n_contexts
@@ -5171,6 +5171,15 @@ class VIEW3D_PT_grease_pencil(AnnotationDataPanel, Panel):
# NOTE: this is just a wrapper around the generic GP Panel
+class VIEW3D_PT_annotation_onion(AnnotationOnionSkin, Panel):
+ bl_space_type = 'VIEW_3D'
+ bl_region_type = 'UI'
+ bl_category = "View"
+ bl_parent_id = 'VIEW3D_PT_grease_pencil'
+
+ # NOTE: this is just a wrapper around the generic GP Panel
+
+
class TOPBAR_PT_annotation_layers(Panel, AnnotationDataPanel):
bl_space_type = 'VIEW_3D'
bl_region_type = 'HEADER'
@@ -5539,6 +5548,7 @@ classes = (
VIEW3D_PT_collections,
VIEW3D_PT_object_type_visibility,
VIEW3D_PT_grease_pencil,
+ VIEW3D_PT_annotation_onion,
VIEW3D_PT_gpencil_multi_frame,
VIEW3D_MT_gpencil_autoweights,
VIEW3D_MT_gpencil_edit_specials,
diff --git a/source/blender/blenkernel/intern/gpencil.c b/source/blender/blenkernel/intern/gpencil.c
index 98d255df080..e694c12e543 100644
--- a/source/blender/blenkernel/intern/gpencil.c
+++ b/source/blender/blenkernel/intern/gpencil.c
@@ -373,6 +373,9 @@ bGPDlayer *BKE_gpencil_layer_addnew(bGPdata *gpd, const char *name, bool setacti
/* set default thickness of new strokes for this layer */
gpl->thickness = 3;
+ /* Onion colors */
+ ARRAY_SET_ITEMS(gpl->gcolor_prev, 0.302f, 0.851f, 0.302f);
+ ARRAY_SET_ITEMS(gpl->gcolor_next, 0.250f, 0.1f, 1.0f);
}
else {
/* thickness parameter represents "thickness change", not absolute thickness */
diff --git a/source/blender/blenloader/intern/versioning_280.c b/source/blender/blenloader/intern/versioning_280.c
index 1bec320b00a..5d1d4a9ad2f 100644
--- a/source/blender/blenloader/intern/versioning_280.c
+++ b/source/blender/blenloader/intern/versioning_280.c
@@ -1116,7 +1116,7 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain)
}
/* Init grease pencil pixel size factor */
- if (!DNA_struct_elem_find(fd->filesdna, "bGPDdata", "int", "pixfactor")) {
+ if (!DNA_struct_elem_find(fd->filesdna, "bGPdata", "int", "pixfactor")) {
for (bGPdata *gpd = bmain->gpencil.first; gpd; gpd = gpd->id.next) {
gpd->pixfactor = GP_DEFAULT_PIX_FACTOR;
}
@@ -2463,5 +2463,16 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain)
STRNCPY(scene->r.engine, RE_engine_id_BLENDER_WORKBENCH);
}
}
+
+ /* init Annotations onion skin */
+ if (!DNA_struct_elem_find(fd->filesdna, "bGPDlayer", "int", "gstep")) {
+ for (bGPdata *gpd = bmain->gpencil.first; gpd; gpd = gpd->id.next) {
+ for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) {
+ ARRAY_SET_ITEMS(gpl->gcolor_prev, 0.302f, 0.851f, 0.302f);
+ ARRAY_SET_ITEMS(gpl->gcolor_next, 0.250f, 0.1f, 1.0f);
+ }
+ }
+ }
+
}
}
diff --git a/source/blender/editors/gpencil/annotate_draw.c b/source/blender/editors/gpencil/annotate_draw.c
index c83015675a0..345a623a234 100644
--- a/source/blender/editors/gpencil/annotate_draw.c
+++ b/source/blender/editors/gpencil/annotate_draw.c
@@ -242,7 +242,7 @@ static void gp_draw_stroke_point(
/* draw a given stroke in 3d (i.e. in 3d-space), using simple ogl lines */
static void gp_draw_stroke_3d(
- const bGPDspoint *points, int totpoints, short thickness, bool UNUSED(debug),
+ const bGPDspoint *points, int totpoints, short thickness,
short UNUSED(sflag), const float ink[4], bool cyclic)
{
float curpressure = points[0].pressure;
@@ -323,7 +323,7 @@ static void gp_draw_stroke_3d(
/* draw a given stroke in 2d */
static void gp_draw_stroke_2d(
const bGPDspoint *points, int totpoints, short thickness_s, short dflag, short sflag,
- bool UNUSED(debug), int offsx, int offsy, int winx, int winy, const float ink[4])
+ int offsx, int offsy, int winx, int winy, const float ink[4])
{
/* otherwise thickness is twice that of the 3D view */
float thickness = (float)thickness_s * 0.5f;
@@ -521,7 +521,7 @@ static bool gp_can_draw_stroke(const bGPDstroke *gps, const int dflag)
/* draw a set of strokes */
static void gp_draw_strokes(
bGPdata *UNUSED(gpd), bGPDlayer *UNUSED(gpl), const bGPDframe *gpf, int offsx, int offsy, int winx, int winy,
- int dflag, bool debug, short lthick, const float color[4])
+ int dflag, short lthick, const float color[4])
{
GPU_enable_program_point_size();
@@ -552,7 +552,7 @@ static void gp_draw_strokes(
}
else {
gp_draw_stroke_3d(
- gps->points, gps->totpoints, lthick, debug, gps->flag,
+ gps->points, gps->totpoints, lthick, gps->flag,
color, gps->flag & GP_STROKE_CYCLIC);
}
@@ -570,7 +570,7 @@ static void gp_draw_strokes(
}
else {
gp_draw_stroke_2d(
- gps->points, gps->totpoints, lthick, dflag, gps->flag, debug,
+ gps->points, gps->totpoints, lthick, dflag, gps->flag,
offsx, offsy, winx, winy, color);
}
}
@@ -714,6 +714,86 @@ static void gp_draw_strokes_edit(
}
/* ----- General Drawing ------ */
+/* draw onion-skinning for a layer */
+static void gp_draw_onionskins(
+ bGPdata *gpd, bGPDlayer *gpl, bGPDframe *gpf, int offsx, int offsy, int winx, int winy,
+ int UNUSED(cfra), int dflag)
+{
+ const float alpha = 1.0f;
+ float color[4];
+
+ /* 1) Draw Previous Frames First */
+ copy_v3_v3(color, gpl->gcolor_prev);
+
+ if (gpl->gstep > 0) {
+ bGPDframe *gf;
+ float fac;
+
+ /* draw previous frames first */
+ for (gf = gpf->prev; gf; gf = gf->prev) {
+ /* check if frame is drawable */
+ if ((gpf->framenum - gf->framenum) <= gpl->gstep) {
+ /* alpha decreases with distance from curframe index */
+ fac = 1.0f - ((float)(gpf->framenum - gf->framenum) / (float)(gpl->gstep + 1));
+ color[3] = alpha * fac * 0.66f;
+ gp_draw_strokes(
+ gpd, gpl, gf, offsx, offsy, winx, winy, dflag,
+ gpl->thickness, color);
+ }
+ else
+ break;
+ }
+ }
+ else if (gpl->gstep == 0) {
+ /* draw the strokes for the ghost frames (at half of the alpha set by user) */
+ if (gpf->prev) {
+ color[3] = (alpha / 7);
+ gp_draw_strokes(
+ gpd, gpl, gpf->prev, offsx, offsy, winx, winy, dflag,
+ gpl->thickness, color);
+ }
+ }
+ else {
+ /* don't draw - disabled */
+ }
+
+
+ /* 2) Now draw next frames */
+ copy_v3_v3(color, gpl->gcolor_next);
+
+ if (gpl->gstep_next > 0) {
+ bGPDframe *gf;
+ float fac;
+
+ /* now draw next frames */
+ for (gf = gpf->next; gf; gf = gf->next) {
+ /* check if frame is drawable */
+ if ((gf->framenum - gpf->framenum) <= gpl->gstep_next) {
+ /* alpha decreases with distance from curframe index */
+ fac = 1.0f - ((float)(gf->framenum - gpf->framenum) / (float)(gpl->gstep_next + 1));
+ color[3] = alpha * fac * 0.66f;
+ gp_draw_strokes(
+ gpd, gpl, gf, offsx, offsy, winx, winy, dflag,
+ gpl->thickness, color);
+ }
+ else
+ break;
+ }
+ }
+ else if (gpl->gstep_next == 0) {
+ /* draw the strokes for the ghost frames (at half of the alpha set by user) */
+ if (gpf->next) {
+ color[3] = (alpha / 4);
+ gp_draw_strokes(
+ gpd, gpl, gpf->next, offsx, offsy, winx, winy, dflag,
+ gpl->thickness, color);
+ }
+ }
+ else {
+ /* don't draw - disabled */
+ }
+
+}
/* loop over gpencil data layers, drawing them */
static void gp_draw_data_layers(
@@ -723,7 +803,6 @@ static void gp_draw_data_layers(
float ink[4];
for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) {
- bool debug = (gpl->flag & GP_LAYER_DRAWDEBUG);
short lthick = gpl->thickness;
/* apply layer opacity */
@@ -750,8 +829,13 @@ static void gp_draw_data_layers(
/* xray... */
SET_FLAG_FROM_TEST(dflag, gpl->flag & GP_LAYER_NO_XRAY, GP_DRAWDATA_NO_XRAY);
+ /* Draw 'onionskins' (frame left + right) */
+ if (gpl->onion_flag & GP_LAYER_ONIONSKIN) {
+ gp_draw_onionskins(gpd, gpl, gpf, offsx, offsy, winx, winy, cfra, dflag);
+ }
+
/* draw the strokes already in active frame */
- gp_draw_strokes(gpd, gpl, gpf, offsx, offsy, winx, winy, dflag, debug, lthick, ink);
+ gp_draw_strokes(gpd, gpl, gpf, offsx, offsy, winx, winy, dflag, lthick, ink);
/* Draw verts of selected strokes
* - when doing OpenGL renders, we don't want to be showing these, as that ends up flickering
diff --git a/source/blender/makesdna/DNA_gpencil_types.h b/source/blender/makesdna/DNA_gpencil_types.h
index cebdc4b29b9..43ce3649db3 100644
--- a/source/blender/makesdna/DNA_gpencil_types.h
+++ b/source/blender/makesdna/DNA_gpencil_types.h
@@ -272,6 +272,14 @@ typedef struct bGPDlayer {
int blend_mode; /* blend modes */
char pad_[4];
+ /* annotation onion skin */
+ short gstep; /* Ghosts Before: max number of ghost frames to show between active frame and the one before it (0 = only the ghost itself) */
+ short gstep_next; /* Ghosts After: max number of ghost frames to show after active frame and the following it (0 = only the ghost itself) */
+
+ float gcolor_prev[3]; /* color for ghosts before the active frame */
+ float gcolor_next[3]; /* color for ghosts after the active frame */
+ char pad_1[4];
+
bGPDlayer_Runtime runtime;
} bGPDlayer;
diff --git a/source/blender/makesrna/intern/rna_gpencil.c b/source/blender/makesrna/intern/rna_gpencil.c
index d6257aa0c1b..0006a8859bf 100644
--- a/source/blender/makesrna/intern/rna_gpencil.c
+++ b/source/blender/makesrna/intern/rna_gpencil.c
@@ -1076,6 +1076,8 @@ static void rna_def_gpencil_layer(BlenderRNA *brna)
PropertyRNA *prop;
FunctionRNA *func;
+ static const float default_onion_color_b[] = { 0.302f, 0.851f, 0.302f };
+ static const float default_onion_color_a[] = { 0.250f, 0.1f, 1.0f };
srna = RNA_def_struct(brna, "GPencilLayer", NULL);
RNA_def_struct_sdna(srna, "bGPDlayer");
@@ -1157,6 +1159,42 @@ static void rna_def_gpencil_layer(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Onion Skinning", "Display onion skins before and after the current frame");
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
+ prop = RNA_def_property(srna, "use_annotation_onion_skinning", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "onion_flag", GP_LAYER_ONIONSKIN);
+ RNA_def_property_ui_text(prop, "Onion Skinning",
+ "Display annotation onion skins before and after the current frame");
+ RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
+
+ prop = RNA_def_property(srna, "annotation_onion_before_range", PROP_INT, PROP_NONE);
+ RNA_def_property_int_sdna(prop, NULL, "gstep");
+ RNA_def_property_range(prop, -1, 120);
+ RNA_def_property_ui_text(prop, "Frames Before",
+ "Maximum number of frames to show before current frame");
+ RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
+
+ prop = RNA_def_property(srna, "annotation_onion_after_range", PROP_INT, PROP_NONE);
+ RNA_def_property_int_sdna(prop, NULL, "gstep_next");
+ RNA_def_property_range(prop, -1, 120);
+ RNA_def_property_ui_text(prop, "Frames After",
+ "Maximum number of frames to show after current frame");
+ RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
+
+ prop = RNA_def_property(srna, "annotation_onion_before_color", PROP_FLOAT, PROP_COLOR_GAMMA);
+ RNA_def_property_float_sdna(prop, NULL, "gcolor_prev");
+ RNA_def_property_array(prop, 3);
+ RNA_def_property_range(prop, 0.0f, 1.0f);
+ RNA_def_property_float_array_default(prop, default_onion_color_b);
+ RNA_def_property_ui_text(prop, "Before Color", "Base color for ghosts before the active frame");
+ RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
+
+ prop = RNA_def_property(srna, "annotation_onion_after_color", PROP_FLOAT, PROP_COLOR_GAMMA);
+ RNA_def_property_float_sdna(prop, NULL, "gcolor_next");
+ RNA_def_property_array(prop, 3);
+ RNA_def_property_range(prop, 0.0f, 1.0f);
+ RNA_def_property_float_array_default(prop, default_onion_color_a);
+ RNA_def_property_ui_text(prop, "After Color", "Base color for ghosts after the active frame");
+ RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
+
/* pass index for compositing and modifiers */
prop = RNA_def_property(srna, "pass_index", PROP_INT, PROP_UNSIGNED);
RNA_def_property_int_sdna(prop, NULL, "pass_index");