New Grease Pencil object for 2D animation
authorAntonioya <blendergit@gmail.com>
Tue, 31 Jul 2018 08:22:19 +0000 (10:22 +0200)
committerAntonioya <blendergit@gmail.com>
Tue, 31 Jul 2018 08:50:43 +0000 (10:50 +0200)
This commit merge the full development done in greasepencil-object branch and include mainly the following features.

- New grease pencil object.
- New drawing engine.
- New grease pencil modes Draw/Sculpt/Edit and Weight Paint.
- New brushes for grease pencil.
- New modifiers for grease pencil.
- New shaders FX.
- New material system (replace old palettes and colors).
- Split of annotations (old grease pencil) and new grease pencil object.
- UI adapted to blender 2.8.

You can get more info here:

https://code.blender.org/2017/12/drawing-2d-animation-in-blender-2-8/
https://code.blender.org/2018/07/grease-pencil-status-update/

This is the result of nearly two years of development and I want thanks firstly the other members of the grease pencil team: Daniel M. Lara, Matias Mendiola and Joshua Leung for their support, ideas and to keep working in the project all the time, without them this project had been impossible.

Also, I want thanks other Blender developers for their help, advices and to be there always to help me, and specially to Clément Foucault, Dalai Felinto, Pablo Vázquez and Campbell Barton.

322 files changed:
build_files/cmake/macros.cmake
intern/cycles/blender/addon/ui.py
release/datafiles/brushicons/gp_brush_block.png [new file with mode: 0644]
release/datafiles/brushicons/gp_brush_clone.png [new file with mode: 0644]
release/datafiles/brushicons/gp_brush_erase_hard.png [new file with mode: 0644]
release/datafiles/brushicons/gp_brush_erase_soft.png [new file with mode: 0644]
release/datafiles/brushicons/gp_brush_erase_stroke.png [new file with mode: 0644]
release/datafiles/brushicons/gp_brush_fill.png [new file with mode: 0644]
release/datafiles/brushicons/gp_brush_grab.png [new file with mode: 0644]
release/datafiles/brushicons/gp_brush_ink.png [new file with mode: 0644]
release/datafiles/brushicons/gp_brush_inknoise.png [new file with mode: 0644]
release/datafiles/brushicons/gp_brush_marker.png [new file with mode: 0644]
release/datafiles/brushicons/gp_brush_pen.png [new file with mode: 0644]
release/datafiles/brushicons/gp_brush_pencil.png [new file with mode: 0644]
release/datafiles/brushicons/gp_brush_pinch.png [new file with mode: 0644]
release/datafiles/brushicons/gp_brush_push.png [new file with mode: 0644]
release/datafiles/brushicons/gp_brush_randomize.png [new file with mode: 0644]
release/datafiles/brushicons/gp_brush_smooth.png [new file with mode: 0644]
release/datafiles/brushicons/gp_brush_strength.png [new file with mode: 0644]
release/datafiles/brushicons/gp_brush_thickness.png [new file with mode: 0644]
release/datafiles/brushicons/gp_brush_twist.png [new file with mode: 0644]
release/datafiles/brushicons/gp_brush_weight.png [new file with mode: 0644]
release/datafiles/icons/brush.gpencil.draw.eraser_hard.dat [new file with mode: 0644]
release/datafiles/icons/brush.gpencil.draw.eraser_soft.dat [new file with mode: 0644]
release/datafiles/icons/brush.gpencil.draw.eraser_stroke.dat [new file with mode: 0644]
release/datafiles/icons/brush.gpencil.draw_block.dat [new file with mode: 0644]
release/datafiles/icons/brush.gpencil.draw_fill.dat [new file with mode: 0644]
release/datafiles/icons/brush.gpencil.draw_ink.dat [new file with mode: 0644]
release/datafiles/icons/brush.gpencil.draw_marker.dat [new file with mode: 0644]
release/datafiles/icons/brush.gpencil.draw_noise.dat [new file with mode: 0644]
release/datafiles/icons/brush.gpencil.draw_pen.dat [new file with mode: 0644]
release/datafiles/icons/brush.gpencil.draw_pencil.dat [new file with mode: 0644]
release/datafiles/icons/ops.gpencil.draw.dat [new file with mode: 0644]
release/datafiles/icons/ops.gpencil.draw.eraser.dat [new file with mode: 0644]
release/datafiles/icons/ops.gpencil.draw.line.dat [new file with mode: 0644]
release/datafiles/icons/ops.gpencil.draw.poly.dat [new file with mode: 0644]
release/datafiles/icons/ops.gpencil.edit_bend.dat [new file with mode: 0644]
release/datafiles/icons/ops.gpencil.edit_mirror.dat [new file with mode: 0644]
release/datafiles/icons/ops.gpencil.edit_shear.dat [new file with mode: 0644]
release/datafiles/icons/ops.gpencil.edit_to_sphere.dat [new file with mode: 0644]
release/datafiles/icons/ops.gpencil.sculpt_clone.dat [new file with mode: 0644]
release/datafiles/icons/ops.gpencil.sculpt_grab.dat [new file with mode: 0644]
release/datafiles/icons/ops.gpencil.sculpt_pinch.dat [new file with mode: 0644]
release/datafiles/icons/ops.gpencil.sculpt_push.dat [new file with mode: 0644]
release/datafiles/icons/ops.gpencil.sculpt_randomize.dat [new file with mode: 0644]
release/datafiles/icons/ops.gpencil.sculpt_smooth.dat [new file with mode: 0644]
release/datafiles/icons/ops.gpencil.sculpt_strength.dat [new file with mode: 0644]
release/datafiles/icons/ops.gpencil.sculpt_thickness.dat [new file with mode: 0644]
release/datafiles/icons/ops.gpencil.sculpt_twist.dat [new file with mode: 0644]
release/datafiles/icons/ops.gpencil.sculpt_weight.dat [new file with mode: 0644]
release/datafiles/preview_grease_pencil.blend [new file with mode: 0644]
release/datafiles/userdef/userdef_default_theme.c
release/scripts/addons
release/scripts/addons_contrib
release/scripts/modules/bpy_extras/keyconfig_utils.py
release/scripts/startup/bl_operators/presets.py
release/scripts/startup/bl_ui/__init__.py
release/scripts/startup/bl_ui/properties_data_gpencil.py [new file with mode: 0644]
release/scripts/startup/bl_ui/properties_data_modifier.py
release/scripts/startup/bl_ui/properties_data_shaderfx.py [new file with mode: 0644]
release/scripts/startup/bl_ui/properties_grease_pencil_common.py
release/scripts/startup/bl_ui/properties_material.py
release/scripts/startup/bl_ui/properties_material_gpencil.py [new file with mode: 0644]
release/scripts/startup/bl_ui/properties_scene.py
release/scripts/startup/bl_ui/space_clip.py
release/scripts/startup/bl_ui/space_image.py
release/scripts/startup/bl_ui/space_node.py
release/scripts/startup/bl_ui/space_sequencer.py
release/scripts/startup/bl_ui/space_toolsystem_toolbar.py
release/scripts/startup/bl_ui/space_topbar.py
release/scripts/startup/bl_ui/space_userpref.py
release/scripts/startup/bl_ui/space_view3d.py
release/scripts/startup/bl_ui/space_view3d_toolbar.py
source/blender/CMakeLists.txt
source/blender/blenkernel/BKE_brush.h
source/blender/blenkernel/BKE_context.h
source/blender/blenkernel/BKE_gpencil.h
source/blender/blenkernel/BKE_gpencil_modifier.h [new file with mode: 0644]
source/blender/blenkernel/BKE_icons.h
source/blender/blenkernel/BKE_lattice.h
source/blender/blenkernel/BKE_material.h
source/blender/blenkernel/BKE_object.h
source/blender/blenkernel/BKE_paint.h
source/blender/blenkernel/BKE_shader_fx.h [new file with mode: 0644]
source/blender/blenkernel/CMakeLists.txt
source/blender/blenkernel/intern/anim_sys.c
source/blender/blenkernel/intern/brush.c
source/blender/blenkernel/intern/colortools.c
source/blender/blenkernel/intern/context.c
source/blender/blenkernel/intern/deform.c
source/blender/blenkernel/intern/gpencil.c
source/blender/blenkernel/intern/gpencil_modifier.c [new file with mode: 0644]
source/blender/blenkernel/intern/icons.c
source/blender/blenkernel/intern/library.c
source/blender/blenkernel/intern/library_query.c
source/blender/blenkernel/intern/material.c
source/blender/blenkernel/intern/object.c
source/blender/blenkernel/intern/object_deform.c
source/blender/blenkernel/intern/object_update.c
source/blender/blenkernel/intern/paint.c
source/blender/blenkernel/intern/scene.c
source/blender/blenkernel/intern/shader_fx.c [new file with mode: 0644]
source/blender/blenlib/BLI_math_vector.h
source/blender/blenlib/BLI_rand.h
source/blender/blenlib/intern/listbase.c
source/blender/blenlib/intern/math_vector_inline.c
source/blender/blenlib/intern/rand.c
source/blender/blenloader/intern/readfile.c
source/blender/blenloader/intern/versioning_260.c
source/blender/blenloader/intern/versioning_270.c
source/blender/blenloader/intern/versioning_280.c
source/blender/blenloader/intern/versioning_defaults.c
source/blender/blenloader/intern/writefile.c
source/blender/collada/SceneExporter.cpp
source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
source/blender/depsgraph/intern/builder/deg_builder_nodes_view_layer.cc
source/blender/depsgraph/intern/builder/deg_builder_relations.cc
source/blender/depsgraph/intern/builder/deg_builder_relations_view_layer.cc
source/blender/depsgraph/intern/depsgraph_tag.cc
source/blender/draw/CMakeLists.txt
source/blender/draw/DRW_engine.h
source/blender/draw/engines/gpencil/gpencil_cache_utils.c [new file with mode: 0644]
source/blender/draw/engines/gpencil/gpencil_draw_cache_impl.c [new file with mode: 0644]
source/blender/draw/engines/gpencil/gpencil_draw_utils.c [new file with mode: 0644]
source/blender/draw/engines/gpencil/gpencil_engine.c [new file with mode: 0644]
source/blender/draw/engines/gpencil/gpencil_engine.h [new file with mode: 0644]
source/blender/draw/engines/gpencil/gpencil_render.c [new file with mode: 0644]
source/blender/draw/engines/gpencil/gpencil_shader_fx.c [new file with mode: 0644]
source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_blur_frag.glsl [new file with mode: 0644]
source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_colorize_frag.glsl [new file with mode: 0644]
source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_flip_frag.glsl [new file with mode: 0644]
source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_light_frag.glsl [new file with mode: 0644]
source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_pixel_frag.glsl [new file with mode: 0644]
source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_rim_prepare_frag.glsl [new file with mode: 0644]
source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_rim_resolve_frag.glsl [new file with mode: 0644]
source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_swirl_frag.glsl [new file with mode: 0644]
source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_wave_frag.glsl [new file with mode: 0644]
source/blender/draw/engines/gpencil/shaders/gpencil_background_frag.glsl [new file with mode: 0644]
source/blender/draw/engines/gpencil/shaders/gpencil_edit_point_frag.glsl [new file with mode: 0644]
source/blender/draw/engines/gpencil/shaders/gpencil_edit_point_geom.glsl [new file with mode: 0644]
source/blender/draw/engines/gpencil/shaders/gpencil_edit_point_vert.glsl [new file with mode: 0644]
source/blender/draw/engines/gpencil/shaders/gpencil_fill_frag.glsl [new file with mode: 0644]
source/blender/draw/engines/gpencil/shaders/gpencil_fill_vert.glsl [new file with mode: 0644]
source/blender/draw/engines/gpencil/shaders/gpencil_paper_frag.glsl [new file with mode: 0644]
source/blender/draw/engines/gpencil/shaders/gpencil_point_frag.glsl [new file with mode: 0644]
source/blender/draw/engines/gpencil/shaders/gpencil_point_geom.glsl [new file with mode: 0644]
source/blender/draw/engines/gpencil/shaders/gpencil_point_vert.glsl [new file with mode: 0644]
source/blender/draw/engines/gpencil/shaders/gpencil_simple_mix_frag.glsl [new file with mode: 0644]
source/blender/draw/engines/gpencil/shaders/gpencil_stroke_frag.glsl [new file with mode: 0644]
source/blender/draw/engines/gpencil/shaders/gpencil_stroke_geom.glsl [new file with mode: 0644]
source/blender/draw/engines/gpencil/shaders/gpencil_stroke_vert.glsl [new file with mode: 0644]
source/blender/draw/engines/gpencil/shaders/gpencil_zdepth_mix_frag.glsl [new file with mode: 0644]
source/blender/draw/intern/DRW_render.h
source/blender/draw/intern/draw_cache.c
source/blender/draw/intern/draw_cache.h
source/blender/draw/intern/draw_cache_impl.h
source/blender/draw/intern/draw_manager.c
source/blender/draw/modes/draw_mode_engines.h
source/blender/draw/modes/object_mode.c
source/blender/editors/animation/anim_channels_defines.c
source/blender/editors/animation/anim_channels_edit.c
source/blender/editors/animation/anim_deps.c
source/blender/editors/animation/anim_draw.c
source/blender/editors/animation/anim_filter.c
source/blender/editors/animation/keyframes_draw.c
source/blender/editors/datafiles/CMakeLists.txt
source/blender/editors/gpencil/CMakeLists.txt
source/blender/editors/gpencil/annotate_draw.c [new file with mode: 0644]
source/blender/editors/gpencil/annotate_paint.c [new file with mode: 0644]
source/blender/editors/gpencil/drawgpencil.c
source/blender/editors/gpencil/editaction_gpencil.c
source/blender/editors/gpencil/gpencil_add_monkey.c [new file with mode: 0644]
source/blender/editors/gpencil/gpencil_brush.c
source/blender/editors/gpencil/gpencil_convert.c
source/blender/editors/gpencil/gpencil_data.c
source/blender/editors/gpencil/gpencil_edit.c
source/blender/editors/gpencil/gpencil_fill.c [new file with mode: 0644]
source/blender/editors/gpencil/gpencil_intern.h
source/blender/editors/gpencil/gpencil_interpolate.c
source/blender/editors/gpencil/gpencil_old.c [new file with mode: 0644]
source/blender/editors/gpencil/gpencil_ops.c
source/blender/editors/gpencil/gpencil_paint.c
source/blender/editors/gpencil/gpencil_primitive.c [new file with mode: 0644]
source/blender/editors/gpencil/gpencil_select.c
source/blender/editors/gpencil/gpencil_undo.c
source/blender/editors/gpencil/gpencil_utils.c
source/blender/editors/include/ED_anim_api.h
source/blender/editors/include/ED_datafiles.h
source/blender/editors/include/ED_gpencil.h
source/blender/editors/include/ED_keyframes_draw.h
source/blender/editors/include/ED_object.h
source/blender/editors/include/UI_icons.h
source/blender/editors/include/UI_interface.h
source/blender/editors/interface/interface_icons.c
source/blender/editors/interface/interface_layout.c
source/blender/editors/interface/interface_templates.c
source/blender/editors/interface/resources.c
source/blender/editors/object/CMakeLists.txt
source/blender/editors/object/object_add.c
source/blender/editors/object/object_edit.c
source/blender/editors/object/object_gpencil_modifier.c [new file with mode: 0644]
source/blender/editors/object/object_intern.h
source/blender/editors/object/object_modes.c
source/blender/editors/object/object_modifier.c
source/blender/editors/object/object_ops.c
source/blender/editors/object/object_relations.c
source/blender/editors/object/object_select.c
source/blender/editors/object/object_shader_fx.c [new file with mode: 0644]
source/blender/editors/object/object_transform.c
source/blender/editors/render/render_opengl.c
source/blender/editors/render/render_preview.c
source/blender/editors/render/render_shading.c
source/blender/editors/screen/area.c
source/blender/editors/screen/screen_context.c
source/blender/editors/screen/screen_ops.c
source/blender/editors/sculpt_paint/paint_ops.c
source/blender/editors/space_action/action_select.c
source/blender/editors/space_buttons/buttons_context.c
source/blender/editors/space_buttons/buttons_texture.c
source/blender/editors/space_buttons/space_buttons.c
source/blender/editors/space_clip/clip_buttons.c
source/blender/editors/space_clip/space_clip.c
source/blender/editors/space_image/image_buttons.c
source/blender/editors/space_info/info_stats.c
source/blender/editors/space_nla/nla_buttons.c
source/blender/editors/space_nla/nla_channels.c
source/blender/editors/space_node/drawnode.c
source/blender/editors/space_outliner/outliner_draw.c
source/blender/editors/space_outliner/outliner_select.c
source/blender/editors/space_outliner/outliner_tree.c
source/blender/editors/space_topbar/space_topbar.c
source/blender/editors/space_view3d/drawobject.c
source/blender/editors/space_view3d/space_view3d.c
source/blender/editors/space_view3d/view3d_draw.c
source/blender/editors/space_view3d/view3d_draw_legacy.c
source/blender/editors/space_view3d/view3d_edit.c
source/blender/editors/space_view3d/view3d_gizmo_ruler.c
source/blender/editors/space_view3d/view3d_ruler.c
source/blender/editors/space_view3d/view3d_select.c
source/blender/editors/transform/transform.c
source/blender/editors/transform/transform_conversions.c
source/blender/editors/transform/transform_generics.c
source/blender/editors/transform/transform_gizmo_3d.c
source/blender/editors/transform/transform_snap_object.c
source/blender/editors/undo/ed_undo.c
source/blender/gpencil_modifiers/CMakeLists.txt [new file with mode: 0644]
source/blender/gpencil_modifiers/MOD_gpencil_modifiertypes.h [new file with mode: 0644]
source/blender/gpencil_modifiers/intern/MOD_gpencil_util.c [new file with mode: 0644]
source/blender/gpencil_modifiers/intern/MOD_gpencil_util.h [new file with mode: 0644]
source/blender/gpencil_modifiers/intern/MOD_gpencilbuild.c [new file with mode: 0644]
source/blender/gpencil_modifiers/intern/MOD_gpencilcolor.c [new file with mode: 0644]
source/blender/gpencil_modifiers/intern/MOD_gpencilhook.c [new file with mode: 0644]
source/blender/gpencil_modifiers/intern/MOD_gpencilinstance.c [new file with mode: 0644]
source/blender/gpencil_modifiers/intern/MOD_gpencillattice.c [new file with mode: 0644]
source/blender/gpencil_modifiers/intern/MOD_gpencilmirror.c [new file with mode: 0644]
source/blender/gpencil_modifiers/intern/MOD_gpencilnoise.c [new file with mode: 0644]
source/blender/gpencil_modifiers/intern/MOD_gpenciloffset.c [new file with mode: 0644]
source/blender/gpencil_modifiers/intern/MOD_gpencilopacity.c [new file with mode: 0644]
source/blender/gpencil_modifiers/intern/MOD_gpencilsimplify.c [new file with mode: 0644]
source/blender/gpencil_modifiers/intern/MOD_gpencilsmooth.c [new file with mode: 0644]
source/blender/gpencil_modifiers/intern/MOD_gpencilsubdiv.c [new file with mode: 0644]
source/blender/gpencil_modifiers/intern/MOD_gpencilthick.c [new file with mode: 0644]
source/blender/gpencil_modifiers/intern/MOD_gpenciltint.c [new file with mode: 0644]
source/blender/gpu/CMakeLists.txt
source/blender/gpu/GPU_shader.h
source/blender/gpu/intern/gpu_shader.c
source/blender/gpu/shaders/gpu_shader_gpencil_fill_frag.glsl [new file with mode: 0644]
source/blender/gpu/shaders/gpu_shader_gpencil_fill_vert.glsl [new file with mode: 0644]
source/blender/gpu/shaders/gpu_shader_gpencil_stroke_frag.glsl [new file with mode: 0644]
source/blender/gpu/shaders/gpu_shader_gpencil_stroke_geom.glsl [new file with mode: 0644]
source/blender/gpu/shaders/gpu_shader_gpencil_stroke_vert.glsl [new file with mode: 0644]
source/blender/makesdna/DNA_ID.h
source/blender/makesdna/DNA_brush_types.h
source/blender/makesdna/DNA_color_types.h
source/blender/makesdna/DNA_gpencil_modifier_types.h [new file with mode: 0644]
source/blender/makesdna/DNA_gpencil_types.h
source/blender/makesdna/DNA_material_types.h
source/blender/makesdna/DNA_object_enums.h
source/blender/makesdna/DNA_object_types.h
source/blender/makesdna/DNA_scene_types.h
source/blender/makesdna/DNA_shader_fx_types.h [new file with mode: 0644]
source/blender/makesdna/DNA_space_types.h
source/blender/makesdna/DNA_userdef_types.h
source/blender/makesdna/DNA_view3d_types.h
source/blender/makesdna/intern/makesdna.c
source/blender/makesrna/RNA_access.h
source/blender/makesrna/RNA_enum_types.h
source/blender/makesrna/intern/CMakeLists.txt
source/blender/makesrna/intern/makesrna.c
source/blender/makesrna/intern/rna_brush.c
source/blender/makesrna/intern/rna_context.c
source/blender/makesrna/intern/rna_gpencil.c
source/blender/makesrna/intern/rna_gpencil_modifier.c [new file with mode: 0644]
source/blender/makesrna/intern/rna_internal.h
source/blender/makesrna/intern/rna_main_api.c
source/blender/makesrna/intern/rna_material.c
source/blender/makesrna/intern/rna_movieclip.c
source/blender/makesrna/intern/rna_nodetree.c
source/blender/makesrna/intern/rna_object.c
source/blender/makesrna/intern/rna_palette.c
source/blender/makesrna/intern/rna_scene.c
source/blender/makesrna/intern/rna_sculpt_paint.c
source/blender/makesrna/intern/rna_shader_fx.c [new file with mode: 0644]
source/blender/makesrna/intern/rna_space.c
source/blender/makesrna/intern/rna_tracking.c
source/blender/makesrna/intern/rna_ui_api.c
source/blender/makesrna/intern/rna_userdef.c
source/blender/render/intern/source/external_engine.c
source/blender/shader_fx/CMakeLists.txt [new file with mode: 0644]
source/blender/shader_fx/FX_shader_types.h [new file with mode: 0644]
source/blender/shader_fx/intern/FX_shader_blur.c [new file with mode: 0644]
source/blender/shader_fx/intern/FX_shader_colorize.c [new file with mode: 0644]
source/blender/shader_fx/intern/FX_shader_flip.c [new file with mode: 0644]
source/blender/shader_fx/intern/FX_shader_light.c [new file with mode: 0644]
source/blender/shader_fx/intern/FX_shader_pixel.c [new file with mode: 0644]
source/blender/shader_fx/intern/FX_shader_rim.c [new file with mode: 0644]
source/blender/shader_fx/intern/FX_shader_swirl.c [new file with mode: 0644]
source/blender/shader_fx/intern/FX_shader_util.c [new file with mode: 0644]
source/blender/shader_fx/intern/FX_shader_util.h [new file with mode: 0644]
source/blender/shader_fx/intern/FX_shader_wave.c [new file with mode: 0644]
source/blender/windowmanager/intern/wm_operators.c
source/creator/creator.c

index ae26565..65f962d 100644 (file)
@@ -598,12 +598,12 @@ function(SETUP_BLENDER_SORTED_LIBS)
                bf_editor_util
                bf_editor_uvedit
                bf_editor_curve
-               bf_editor_gpencil
                bf_editor_interface
                bf_editor_gizmo_library
                bf_editor_mesh
                bf_editor_metaball
                bf_editor_object
+               bf_editor_gpencil
                bf_editor_lattice
                bf_editor_armature
                bf_editor_physics
@@ -626,12 +626,15 @@ function(SETUP_BLENDER_SORTED_LIBS)
                bf_freestyle
                bf_ikplugin
                bf_modifiers
+               bf_gpencil_modifiers
                bf_alembic
                bf_bmesh
                bf_gpu
                bf_draw
                bf_blenloader
                bf_blenkernel
+               bf_shader_fx
+               bf_gpencil_modifiers
                bf_physics
                bf_nodes
                bf_rna
index a1941ce..737f741 100644 (file)
@@ -895,7 +895,10 @@ class CYCLES_PT_context_material(CyclesButtonsPanel, Panel):
 
     @classmethod
     def poll(cls, context):
-        return (context.material or context.object) and CyclesButtonsPanel.poll(context)
+        if context.active_object and context.active_object.type == 'GPENCIL':
+            return False
+        else:
+            return (context.material or context.object) and CyclesButtonsPanel.poll(context)
 
     def draw(self, context):
         layout = self.layout
diff --git a/release/datafiles/brushicons/gp_brush_block.png b/release/datafiles/brushicons/gp_brush_block.png
new file mode 100644 (file)
index 0000000..2db3964
Binary files /dev/null and b/release/datafiles/brushicons/gp_brush_block.png differ
diff --git a/release/datafiles/brushicons/gp_brush_clone.png b/release/datafiles/brushicons/gp_brush_clone.png
new file mode 100644 (file)
index 0000000..8358ace
Binary files /dev/null and b/release/datafiles/brushicons/gp_brush_clone.png differ
diff --git a/release/datafiles/brushicons/gp_brush_erase_hard.png b/release/datafiles/brushicons/gp_brush_erase_hard.png
new file mode 100644 (file)
index 0000000..2ac5284
Binary files /dev/null and b/release/datafiles/brushicons/gp_brush_erase_hard.png differ
diff --git a/release/datafiles/brushicons/gp_brush_erase_soft.png b/release/datafiles/brushicons/gp_brush_erase_soft.png
new file mode 100644 (file)
index 0000000..4169230
Binary files /dev/null and b/release/datafiles/brushicons/gp_brush_erase_soft.png differ
diff --git a/release/datafiles/brushicons/gp_brush_erase_stroke.png b/release/datafiles/brushicons/gp_brush_erase_stroke.png
new file mode 100644 (file)
index 0000000..cd6d215
Binary files /dev/null and b/release/datafiles/brushicons/gp_brush_erase_stroke.png differ
diff --git a/release/datafiles/brushicons/gp_brush_fill.png b/release/datafiles/brushicons/gp_brush_fill.png
new file mode 100644 (file)
index 0000000..9dac633
Binary files /dev/null and b/release/datafiles/brushicons/gp_brush_fill.png differ
diff --git a/release/datafiles/brushicons/gp_brush_grab.png b/release/datafiles/brushicons/gp_brush_grab.png
new file mode 100644 (file)
index 0000000..2123ac6
Binary files /dev/null and b/release/datafiles/brushicons/gp_brush_grab.png differ
diff --git a/release/datafiles/brushicons/gp_brush_ink.png b/release/datafiles/brushicons/gp_brush_ink.png
new file mode 100644 (file)
index 0000000..410a77f
Binary files /dev/null and b/release/datafiles/brushicons/gp_brush_ink.png differ
diff --git a/release/datafiles/brushicons/gp_brush_inknoise.png b/release/datafiles/brushicons/gp_brush_inknoise.png
new file mode 100644 (file)
index 0000000..5356f69
Binary files /dev/null and b/release/datafiles/brushicons/gp_brush_inknoise.png differ
diff --git a/release/datafiles/brushicons/gp_brush_marker.png b/release/datafiles/brushicons/gp_brush_marker.png
new file mode 100644 (file)
index 0000000..c7a62b7
Binary files /dev/null and b/release/datafiles/brushicons/gp_brush_marker.png differ
diff --git a/release/datafiles/brushicons/gp_brush_pen.png b/release/datafiles/brushicons/gp_brush_pen.png
new file mode 100644 (file)
index 0000000..9aaaa86
Binary files /dev/null and b/release/datafiles/brushicons/gp_brush_pen.png differ
diff --git a/release/datafiles/brushicons/gp_brush_pencil.png b/release/datafiles/brushicons/gp_brush_pencil.png
new file mode 100644 (file)
index 0000000..2d1fbdf
Binary files /dev/null and b/release/datafiles/brushicons/gp_brush_pencil.png differ
diff --git a/release/datafiles/brushicons/gp_brush_pinch.png b/release/datafiles/brushicons/gp_brush_pinch.png
new file mode 100644 (file)
index 0000000..e38236d
Binary files /dev/null and b/release/datafiles/brushicons/gp_brush_pinch.png differ
diff --git a/release/datafiles/brushicons/gp_brush_push.png b/release/datafiles/brushicons/gp_brush_push.png
new file mode 100644 (file)
index 0000000..5427643
Binary files /dev/null and b/release/datafiles/brushicons/gp_brush_push.png differ
diff --git a/release/datafiles/brushicons/gp_brush_randomize.png b/release/datafiles/brushicons/gp_brush_randomize.png
new file mode 100644 (file)
index 0000000..0dd1a13
Binary files /dev/null and b/release/datafiles/brushicons/gp_brush_randomize.png differ
diff --git a/release/datafiles/brushicons/gp_brush_smooth.png b/release/datafiles/brushicons/gp_brush_smooth.png
new file mode 100644 (file)
index 0000000..7518a35
Binary files /dev/null and b/release/datafiles/brushicons/gp_brush_smooth.png differ
diff --git a/release/datafiles/brushicons/gp_brush_strength.png b/release/datafiles/brushicons/gp_brush_strength.png
new file mode 100644 (file)
index 0000000..a051311
Binary files /dev/null and b/release/datafiles/brushicons/gp_brush_strength.png differ
diff --git a/release/datafiles/brushicons/gp_brush_thickness.png b/release/datafiles/brushicons/gp_brush_thickness.png
new file mode 100644 (file)
index 0000000..6026716
Binary files /dev/null and b/release/datafiles/brushicons/gp_brush_thickness.png differ
diff --git a/release/datafiles/brushicons/gp_brush_twist.png b/release/datafiles/brushicons/gp_brush_twist.png
new file mode 100644 (file)
index 0000000..84b9a90
Binary files /dev/null and b/release/datafiles/brushicons/gp_brush_twist.png differ
diff --git a/release/datafiles/brushicons/gp_brush_weight.png b/release/datafiles/brushicons/gp_brush_weight.png
new file mode 100644 (file)
index 0000000..171e922
Binary files /dev/null and b/release/datafiles/brushicons/gp_brush_weight.png differ
diff --git a/release/datafiles/icons/brush.gpencil.draw.eraser_hard.dat b/release/datafiles/icons/brush.gpencil.draw.eraser_hard.dat
new file mode 100644 (file)
index 0000000..1e909ca
Binary files /dev/null and b/release/datafiles/icons/brush.gpencil.draw.eraser_hard.dat differ
diff --git a/release/datafiles/icons/brush.gpencil.draw.eraser_soft.dat b/release/datafiles/icons/brush.gpencil.draw.eraser_soft.dat
new file mode 100644 (file)
index 0000000..7242f76
Binary files /dev/null and b/release/datafiles/icons/brush.gpencil.draw.eraser_soft.dat differ
diff --git a/release/datafiles/icons/brush.gpencil.draw.eraser_stroke.dat b/release/datafiles/icons/brush.gpencil.draw.eraser_stroke.dat
new file mode 100644 (file)
index 0000000..6bf620b
Binary files /dev/null and b/release/datafiles/icons/brush.gpencil.draw.eraser_stroke.dat differ
diff --git a/release/datafiles/icons/brush.gpencil.draw_block.dat b/release/datafiles/icons/brush.gpencil.draw_block.dat
new file mode 100644 (file)
index 0000000..7a7402e
Binary files /dev/null and b/release/datafiles/icons/brush.gpencil.draw_block.dat differ
diff --git a/release/datafiles/icons/brush.gpencil.draw_fill.dat b/release/datafiles/icons/brush.gpencil.draw_fill.dat
new file mode 100644 (file)
index 0000000..809aed7
Binary files /dev/null and b/release/datafiles/icons/brush.gpencil.draw_fill.dat differ
diff --git a/release/datafiles/icons/brush.gpencil.draw_ink.dat b/release/datafiles/icons/brush.gpencil.draw_ink.dat
new file mode 100644 (file)
index 0000000..3c65471
Binary files /dev/null and b/release/datafiles/icons/brush.gpencil.draw_ink.dat differ
diff --git a/release/datafiles/icons/brush.gpencil.draw_marker.dat b/release/datafiles/icons/brush.gpencil.draw_marker.dat
new file mode 100644 (file)
index 0000000..77a52dd
Binary files /dev/null and b/release/datafiles/icons/brush.gpencil.draw_marker.dat differ
diff --git a/release/datafiles/icons/brush.gpencil.draw_noise.dat b/release/datafiles/icons/brush.gpencil.draw_noise.dat
new file mode 100644 (file)
index 0000000..127f469
Binary files /dev/null and b/release/datafiles/icons/brush.gpencil.draw_noise.dat differ
diff --git a/release/datafiles/icons/brush.gpencil.draw_pen.dat b/release/datafiles/icons/brush.gpencil.draw_pen.dat
new file mode 100644 (file)
index 0000000..cb6fb77
Binary files /dev/null and b/release/datafiles/icons/brush.gpencil.draw_pen.dat differ
diff --git a/release/datafiles/icons/brush.gpencil.draw_pencil.dat b/release/datafiles/icons/brush.gpencil.draw_pencil.dat
new file mode 100644 (file)
index 0000000..a8898a9
Binary files /dev/null and b/release/datafiles/icons/brush.gpencil.draw_pencil.dat differ
diff --git a/release/datafiles/icons/ops.gpencil.draw.dat b/release/datafiles/icons/ops.gpencil.draw.dat
new file mode 100644 (file)
index 0000000..3adc50a
Binary files /dev/null and b/release/datafiles/icons/ops.gpencil.draw.dat differ
diff --git a/release/datafiles/icons/ops.gpencil.draw.eraser.dat b/release/datafiles/icons/ops.gpencil.draw.eraser.dat
new file mode 100644 (file)
index 0000000..323d8c2
Binary files /dev/null and b/release/datafiles/icons/ops.gpencil.draw.eraser.dat differ
diff --git a/release/datafiles/icons/ops.gpencil.draw.line.dat b/release/datafiles/icons/ops.gpencil.draw.line.dat
new file mode 100644 (file)
index 0000000..238db63
Binary files /dev/null and b/release/datafiles/icons/ops.gpencil.draw.line.dat differ
diff --git a/release/datafiles/icons/ops.gpencil.draw.poly.dat b/release/datafiles/icons/ops.gpencil.draw.poly.dat
new file mode 100644 (file)
index 0000000..8351e48
Binary files /dev/null and b/release/datafiles/icons/ops.gpencil.draw.poly.dat differ
diff --git a/release/datafiles/icons/ops.gpencil.edit_bend.dat b/release/datafiles/icons/ops.gpencil.edit_bend.dat
new file mode 100644 (file)
index 0000000..32f7b2e
Binary files /dev/null and b/release/datafiles/icons/ops.gpencil.edit_bend.dat differ
diff --git a/release/datafiles/icons/ops.gpencil.edit_mirror.dat b/release/datafiles/icons/ops.gpencil.edit_mirror.dat
new file mode 100644 (file)
index 0000000..ee07366
Binary files /dev/null and b/release/datafiles/icons/ops.gpencil.edit_mirror.dat differ
diff --git a/release/datafiles/icons/ops.gpencil.edit_shear.dat b/release/datafiles/icons/ops.gpencil.edit_shear.dat
new file mode 100644 (file)
index 0000000..e6b51f9
Binary files /dev/null and b/release/datafiles/icons/ops.gpencil.edit_shear.dat differ
diff --git a/release/datafiles/icons/ops.gpencil.edit_to_sphere.dat b/release/datafiles/icons/ops.gpencil.edit_to_sphere.dat
new file mode 100644 (file)
index 0000000..bf1181c
Binary files /dev/null and b/release/datafiles/icons/ops.gpencil.edit_to_sphere.dat differ
diff --git a/release/datafiles/icons/ops.gpencil.sculpt_clone.dat b/release/datafiles/icons/ops.gpencil.sculpt_clone.dat
new file mode 100644 (file)
index 0000000..dbae6a6
Binary files /dev/null and b/release/datafiles/icons/ops.gpencil.sculpt_clone.dat differ
diff --git a/release/datafiles/icons/ops.gpencil.sculpt_grab.dat b/release/datafiles/icons/ops.gpencil.sculpt_grab.dat
new file mode 100644 (file)
index 0000000..291b4fd
Binary files /dev/null and b/release/datafiles/icons/ops.gpencil.sculpt_grab.dat differ
diff --git a/release/datafiles/icons/ops.gpencil.sculpt_pinch.dat b/release/datafiles/icons/ops.gpencil.sculpt_pinch.dat
new file mode 100644 (file)
index 0000000..cb2b43f
Binary files /dev/null and b/release/datafiles/icons/ops.gpencil.sculpt_pinch.dat differ
diff --git a/release/datafiles/icons/ops.gpencil.sculpt_push.dat b/release/datafiles/icons/ops.gpencil.sculpt_push.dat
new file mode 100644 (file)
index 0000000..e1c4961
Binary files /dev/null and b/release/datafiles/icons/ops.gpencil.sculpt_push.dat differ
diff --git a/release/datafiles/icons/ops.gpencil.sculpt_randomize.dat b/release/datafiles/icons/ops.gpencil.sculpt_randomize.dat
new file mode 100644 (file)
index 0000000..3504293
Binary files /dev/null and b/release/datafiles/icons/ops.gpencil.sculpt_randomize.dat differ
diff --git a/release/datafiles/icons/ops.gpencil.sculpt_smooth.dat b/release/datafiles/icons/ops.gpencil.sculpt_smooth.dat
new file mode 100644 (file)
index 0000000..3a132ed
Binary files /dev/null and b/release/datafiles/icons/ops.gpencil.sculpt_smooth.dat differ
diff --git a/release/datafiles/icons/ops.gpencil.sculpt_strength.dat b/release/datafiles/icons/ops.gpencil.sculpt_strength.dat
new file mode 100644 (file)
index 0000000..7e52b0d
Binary files /dev/null and b/release/datafiles/icons/ops.gpencil.sculpt_strength.dat differ
diff --git a/release/datafiles/icons/ops.gpencil.sculpt_thickness.dat b/release/datafiles/icons/ops.gpencil.sculpt_thickness.dat
new file mode 100644 (file)
index 0000000..1e55880
Binary files /dev/null and b/release/datafiles/icons/ops.gpencil.sculpt_thickness.dat differ
diff --git a/release/datafiles/icons/ops.gpencil.sculpt_twist.dat b/release/datafiles/icons/ops.gpencil.sculpt_twist.dat
new file mode 100644 (file)
index 0000000..4ce958c
Binary files /dev/null and b/release/datafiles/icons/ops.gpencil.sculpt_twist.dat differ
diff --git a/release/datafiles/icons/ops.gpencil.sculpt_weight.dat b/release/datafiles/icons/ops.gpencil.sculpt_weight.dat
new file mode 100644 (file)
index 0000000..41b58ab
Binary files /dev/null and b/release/datafiles/icons/ops.gpencil.sculpt_weight.dat differ
diff --git a/release/datafiles/preview_grease_pencil.blend b/release/datafiles/preview_grease_pencil.blend
new file mode 100644 (file)
index 0000000..82661d8
Binary files /dev/null and b/release/datafiles/preview_grease_pencil.blend differ
index 11a9fba..69ad58e 100644 (file)
@@ -1,8 +1,8 @@
 /*
- * Generated by 'source/tools/utils/blender_theme_as_c.py'
- *
- * Do not hand edit this file!
- */
+* Generated by 'source/tools/utils/blender_theme_as_c.py'
+*
+* Do not hand edit this file!
+*/
 
 #include "DNA_userdef_types.h"
 
@@ -1040,5 +1040,5 @@ const bTheme U_theme_default = {
                        .select = RGBA(0x000000ff),
                        .active = RGBA(0x000000ff),
                },
-       },
+},
 };
index c87ee4d..3719604 160000 (submodule)
@@ -1 +1 @@
-Subproject commit c87ee4d46f16d60a2e1db7514c8d5ab42c5d93df
+Subproject commit 371960484a38fc64e0a2635170a41a0d8ab2f6bd
index 15b25a4..4747021 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 15b25a42783d1e516b5298d70b582fae2559ae17
+Subproject commit 474702157831f1a58bb50f5240ab8b1b02b6ba37
index 6859e32..4e5cb7d 100644 (file)
@@ -121,6 +121,12 @@ KM_HIERARCHY = [
 
     ('Grease Pencil', 'EMPTY', 'WINDOW', [  # grease pencil stuff (per region)
         ('Grease Pencil Stroke Edit Mode', 'EMPTY', 'WINDOW', []),
+        ('Grease Pencil Stroke Paint (Draw brush)', 'EMPTY', 'WINDOW', []),
+        ('Grease Pencil Stroke Paint (Fill)', 'EMPTY', 'WINDOW', []),
+        ('Grease Pencil Stroke Paint (Erase)', 'EMPTY', 'WINDOW', []),
+        ('Grease Pencil Stroke Paint Mode', 'EMPTY', 'WINDOW', []),
+        ('Grease Pencil Stroke Sculpt Mode', 'EMPTY', 'WINDOW', []),
+        ('Grease Pencil Stroke Weight Mode', 'EMPTY', 'WINDOW', []),
     ]),
     ('Mask Editing', 'EMPTY', 'WINDOW', []),
     ('Frames', 'EMPTY', 'WINDOW', []),    # frame navigation (per region)
index fe09fad..0fe45f8 100644 (file)
@@ -670,6 +670,42 @@ class AddPresetUnitsLength(AddPresetBase, Operator):
     preset_subdir = "units_length"
 
 
+class AddPresetGpencilBrush(AddPresetBase, Operator):
+    """Add or remove grease pencil brush preset"""
+    bl_idname = "scene.gpencil_brush_preset_add"
+    bl_label = "Add Grease Pencil Brush Preset"
+    preset_menu = "VIEW3D_PT_gpencil_brush_presets"
+
+    preset_defines = [
+        "brush = bpy.context.active_gpencil_brush",
+        "settings = brush.gpencil_settings"
+    ]
+
+    preset_values = [
+        "settings.input_samples",
+        "settings.active_smooth_factor",
+        "settings.angle",
+        "settings.angle_factor",
+        "settings.use_stabilizer",
+        "brush.smooth_stroke_radius",
+        "brush.smooth_stroke_factor",
+        "settings.pen_smooth_factor",
+        "settings.pen_smooth_steps",
+        "settings.pen_thick_smooth_factor",
+        "settings.pen_thick_smooth_steps",
+        "settings.pen_subdivision_steps",
+        "settings.random_subdiv",
+        "settings.enable_random",
+        "settings.random_pressure",
+        "settings.random_strength",
+        "settings.uv_random",
+        "settings.pen_jitter",
+        "settings.use_jitter_pressure",
+    ]
+
+    preset_subdir = "gpencil_brush"
+
+
 classes = (
     AddPresetCamera,
     AddPresetCloth,
@@ -686,6 +722,7 @@ classes = (
     AddPresetTrackingSettings,
     AddPresetTrackingTrackColor,
     AddPresetUnitsLength,
+    AddPresetGpencilBrush,
     ExecutePreset,
     WM_MT_operator_presets,
 )
index 51ba45c..89aed37 100644 (file)
@@ -34,16 +34,19 @@ _modules = [
     "properties_data_camera",
     "properties_data_curve",
     "properties_data_empty",
+    "properties_data_gpencil",
     "properties_data_light",
     "properties_data_lattice",
     "properties_data_mesh",
     "properties_data_metaball",
     "properties_data_modifier",
+    "properties_data_shaderfx",
     "properties_data_lightprobe",
     "properties_data_speaker",
     "properties_data_workspace",
     "properties_mask_common",
     "properties_material",
+    "properties_material_gpencil",
     "properties_object",
     "properties_paint_common",
     "properties_grease_pencil_common",
diff --git a/release/scripts/startup/bl_ui/properties_data_gpencil.py b/release/scripts/startup/bl_ui/properties_data_gpencil.py
new file mode 100644 (file)
index 0000000..14407af
--- /dev/null
@@ -0,0 +1,402 @@
+# ##### BEGIN GPL LICENSE BLOCK #####
+#
+#  This program is free software; you can redistribute it and/or
+#  modify it under the terms of the GNU General Public License
+#  as published by the Free Software Foundation; either version 2
+#  of the License, or (at your option) any later version.
+#
+#  This program is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with this program; if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# ##### END GPL LICENSE BLOCK #####
+
+# <pep8 compliant>
+import bpy
+from bpy.types import Menu, Panel, UIList
+from rna_prop_ui import PropertyPanel
+from .properties_grease_pencil_common import (
+        GreasePencilDataPanel,
+        GreasePencilOnionPanel,
+        )
+
+###############################
+# Base-Classes (for shared stuff - e.g. poll, attributes, etc.)
+
+class DataButtonsPanel:
+    bl_space_type = 'PROPERTIES'
+    bl_region_type = 'WINDOW'
+    bl_context = "data"
+
+    @classmethod
+    def poll(cls, context):
+        return context.object and context.object.type == 'GPENCIL'
+
+
+class LayerDataButtonsPanel:
+    bl_space_type = 'PROPERTIES'
+    bl_region_type = 'WINDOW'
+    bl_context = "data"
+
+    @classmethod
+    def poll(cls, context):
+        return (context.object and
+                context.object.type == 'GPENCIL' and
+                context.active_gpencil_layer)
+
+
+###############################
+# GP Object Properties Panels and Helper Classes
+
+class DATA_PT_gpencil(DataButtonsPanel, Panel):
+    bl_label = ""
+    bl_options = {'HIDE_HEADER'}
+
+    def draw(self, context):
+        layout = self.layout
+
+        # Grease Pencil data selector
+        gpd_owner = context.gpencil_data_owner
+        gpd = context.gpencil_data
+
+        layout.template_ID(gpd_owner, "data")
+
+
+class GPENCIL_UL_layer(UIList):
+    def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
+        # assert(isinstance(item, bpy.types.GPencilLayer)
+        gpl = item
+        gpd = context.gpencil_data
+
+        if self.layout_type in {'DEFAULT', 'COMPACT'}:
+            if gpl.lock:
+                layout.active = False
+
+            row = layout.row(align=True)
+            if gpl.is_parented:
+                icon = 'BONE_DATA'
+            else:
+                icon = 'BLANK1'
+
+            row.label(text="", icon=icon)
+            row.prop(gpl, "info", text="", emboss=False)
+
+            row = layout.row(align=True)
+            row.prop(gpl, "lock", text="", emboss=False)
+            row.prop(gpl, "hide", text="", emboss=False)
+            row.prop(gpl, "unlock_color", text="", emboss=False)
+            if gpl.use_onion_skinning is False:
+                icon = 'GHOST_DISABLED'
+            else:
+                icon = 'GHOST_ENABLED'
+            subrow = row.row(align=True)
+            subrow.prop(gpl, "use_onion_skinning", text="", icon=icon, emboss=False)
+            subrow.active = gpd.use_onion_skinning
+        elif self.layout_type == 'GRID':
+            layout.alignment = 'CENTER'
+            layout.label(text="", icon_value=icon)
+
+
+class GPENCIL_MT_layer_specials(Menu):
+    bl_label = "Layer"
+
+    def draw(self, context):
+        layout = self.layout
+
+        layout.operator("gpencil.layer_duplicate", icon='COPY_ID')  # XXX: needs a dedicated icon
+
+        layout.separator()
+
+        layout.operator("gpencil.reveal", icon='RESTRICT_VIEW_OFF', text="Show All")
+        layout.operator("gpencil.hide", icon='RESTRICT_VIEW_ON', text="Hide Others").unselected = True
+
+        layout.separator()
+
+        layout.operator("gpencil.lock_all", icon='LOCKED', text="Lock All")
+        layout.operator("gpencil.unlock_all", icon='UNLOCKED', text="UnLock All")
+
+        layout.separator()
+
+        layout.operator("gpencil.layer_merge", icon='NLA', text="Merge Down")
+
+
+class DATA_PT_gpencil_datapanel(Panel):
+    bl_space_type = 'PROPERTIES'
+    bl_region_type = 'WINDOW'
+    bl_context = "data"
+    bl_label = "Layers"
+
+    @classmethod
+    def poll(cls, context):
+        if context.gpencil_data is None:
+            return False
+
+        ob = context.object
+        if ob is not None and ob.type == 'GPENCIL':
+            return True
+
+        return False
+
+    @staticmethod
+    def draw(self, context):
+        layout = self.layout
+        #layout.use_property_split = True
+        layout.use_property_decorate = False
+
+        gpd = context.gpencil_data
+
+        # Grease Pencil data...
+        if (gpd is None) or (not gpd.layers):
+            layout.operator("gpencil.layer_add", text="New Layer")
+        else:
+            self.draw_layers(context, layout, gpd)
+
+    def draw_layers(self, context, layout, gpd):
+        row = layout.row()
+
+        col = row.column()
+        if len(gpd.layers) >= 2:
+            layer_rows = 5
+        else:
+            layer_rows = 2
+        col.template_list("GPENCIL_UL_layer", "", gpd, "layers", gpd.layers, "active_index", rows=layer_rows)
+
+        col = row.column()
+
+        sub = col.column(align=True)
+        sub.operator("gpencil.layer_add", icon='ZOOMIN', text="")
+        sub.operator("gpencil.layer_remove", icon='ZOOMOUT', text="")
+
+        gpl = context.active_gpencil_layer
+        if gpl:
+            sub.menu("GPENCIL_MT_layer_specials", icon='DOWNARROW_HLT', text="")
+
+            if len(gpd.layers) > 1:
+                col.separator()
+
+                sub = col.column(align=True)
+                sub.operator("gpencil.layer_move", icon='TRIA_UP', text="").type = 'UP'
+                sub.operator("gpencil.layer_move", icon='TRIA_DOWN', text="").type = 'DOWN'
+
+                col.separator()
+
+                sub = col.column(align=True)
+                sub.operator("gpencil.layer_isolate", icon='LOCKED', text="").affect_visibility = False
+                sub.operator("gpencil.layer_isolate", icon='RESTRICT_VIEW_OFF', text="").affect_visibility = True
+
+        row = layout.row(align=True)
+        if gpl:
+            row.prop(gpl, "opacity", text="Opacity", slider=True)
+
+
+class DATA_PT_gpencil_layer_optionpanel(LayerDataButtonsPanel, Panel):
+    bl_space_type = 'PROPERTIES'
+    bl_region_type = 'WINDOW'
+    bl_context = "data"
+    bl_label = "Adjustments"
+    bl_parent_id = 'DATA_PT_gpencil_datapanel'
+    bl_options = {'DEFAULT_CLOSED'}
+
+    def draw(self, context):
+        layout = self.layout
+        layout.use_property_split = True
+
+        gpl = context.active_gpencil_layer
+        layout.active = not gpl.lock
+
+        # Layer options
+        # Offsets - Color Tint
+        layout.enabled = not gpl.lock
+        col = layout.column(align=True)
+        col.prop(gpl, "tint_color")
+        col.prop(gpl, "tint_factor", slider=True)
+
+        # Offsets - Thickness
+        col = layout.row(align=True)
+        col.prop(gpl, "line_change", text="Stroke Thickness")
+
+
+class DATA_PT_gpencil_parentpanel(LayerDataButtonsPanel, Panel):
+    bl_space_type = 'PROPERTIES'
+    bl_region_type = 'WINDOW'
+    bl_context = "data"
+    bl_label = "Relations"
+    bl_parent_id = 'DATA_PT_gpencil_datapanel'
+    bl_options = {'DEFAULT_CLOSED'}
+
+    def draw(self, context):
+        layout = self.layout
+        layout.use_property_split = True
+        layout.use_property_decorate = False
+
+        gpl = context.active_gpencil_layer
+        col = layout.column(align=True)
+        col.active = not gpl.lock
+        col.prop(gpl, "parent", text="Parent")
+        col.prop(gpl, "parent_type", text="Parent Type")
+        parent = gpl.parent
+
+        if parent and gpl.parent_type == 'BONE' and parent.type == 'ARMATURE':
+            col.prop_search(gpl, "parent_bone", parent.data, "bones", text="Bone")
+
+
+class DATA_PT_gpencil_onionpanel(Panel):
+    bl_space_type = 'PROPERTIES'
+    bl_region_type = 'WINDOW'
+    bl_context = "data"
+    bl_label = "Onion Skinning"
+    bl_options = {'DEFAULT_CLOSED'}
+
+    @classmethod
+    def poll(cls, context):
+        return bool(context.active_gpencil_layer)
+
+    @staticmethod
+    def draw_header(self, context):
+        self.layout.prop(context.gpencil_data, "use_onion_skinning", text="")
+
+    def draw(self, context):
+        gpd = context.gpencil_data
+
+        layout = self.layout
+        layout.use_property_split = True
+        layout.enabled = gpd.use_onion_skinning
+
+        GreasePencilOnionPanel.draw_settings(layout, gpd)
+
+
+class GPENCIL_MT_gpencil_vertex_group(Menu):
+    bl_label = "GP Vertex Groups"
+
+    def draw(self, context):
+        layout = self.layout
+
+        layout.operator_context = 'EXEC_AREA'
+        layout.operator("object.vertex_group_add")
+
+        ob = context.active_object
+        if ob.vertex_groups.active:
+            layout.separator()
+
+            layout.operator("gpencil.vertex_group_assign", text="Assign to Active Group")
+            layout.operator("gpencil.vertex_group_remove_from", text="Remove from Active Group")
+
+            layout.separator()
+            layout.operator_menu_enum("object.vertex_group_set_active", "group", text="Set Active Group")
+            layout.operator("object.vertex_group_remove", text="Remove Active Group").all = False
+            layout.operator("object.vertex_group_remove", text="Remove All Groups").all = True
+
+            layout.separator()
+            layout.operator("gpencil.vertex_group_select", text="Select Points")
+            layout.operator("gpencil.vertex_group_deselect", text="Deselect Points")
+
+
+class GPENCIL_UL_vgroups(UIList):
+    def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
+        vgroup = item
+        if self.layout_type in {'DEFAULT', 'COMPACT'}:
+            layout.prop(vgroup, "name", text="", emboss=False, icon_value=icon)
+            # icon = 'LOCKED' if vgroup.lock_weight else 'UNLOCKED'
+            # layout.prop(vgroup, "lock_weight", text="", icon=icon, emboss=False)
+        elif self.layout_type == 'GRID':
+            layout.alignment = 'CENTER'
+            layout.label(text="", icon_value=icon)
+
+
+class DATA_PT_gpencil_vertexpanel(DataButtonsPanel, Panel):
+    bl_space_type = 'PROPERTIES'
+    bl_region_type = 'WINDOW'
+    bl_context = "data"
+    bl_label = "Vertex Groups"
+    bl_options = {'DEFAULT_CLOSED'}
+
+    def draw(self, context):
+        layout = self.layout
+
+        ob = context.object
+        group = ob.vertex_groups.active
+
+        rows = 2
+        if group:
+            rows = 4
+
+        row = layout.row()
+        row.template_list("GPENCIL_UL_vgroups", "", ob, "vertex_groups", ob.vertex_groups, "active_index", rows=rows)
+
+        col = row.column(align=True)
+        col.operator("object.vertex_group_add", icon='ZOOMIN', text="")
+        col.operator("object.vertex_group_remove", icon='ZOOMOUT', text="").all = False
+
+        if ob.vertex_groups:
+            row = layout.row()
+
+            sub = row.row(align=True)
+            sub.operator("gpencil.vertex_group_assign", text="Assign")
+            sub.operator("gpencil.vertex_group_remove_from", text="Remove")
+
+            sub = row.row(align=True)
+            sub.operator("gpencil.vertex_group_select", text="Select")
+            sub.operator("gpencil.vertex_group_deselect", text="Deselect")
+
+            layout.prop(context.tool_settings, "vertex_group_weight", text="Weight")
+
+
+class DATA_PT_gpencil_display(DataButtonsPanel, Panel):
+    bl_label = "Viewport Display"
+    bl_options = {'DEFAULT_CLOSED'}
+
+    def draw(self, context):
+        layout = self.layout
+        layout.use_property_split = True
+
+        ob = context.object
+
+        gpd = context.gpencil_data
+        gpl = context.active_gpencil_layer
+
+        layout.prop(gpd, "xray_mode", text="Depth Ordering")
+        layout.prop(gpd, "edit_line_color", text="Edit Line Color")
+        layout.prop(ob, "empty_draw_size", text="Marker Size")
+
+        col = layout.column(align=True)
+        col.prop(gpd, "show_constant_thickness")
+        sub = col.column()
+        sub.active = not gpd.show_constant_thickness
+        sub.prop(gpd, "pixfactor", text="Thickness Scale")
+
+        if gpl:
+            layout.prop(gpd, "show_stroke_direction", text="Show Stroke Directions")
+
+
+class DATA_PT_custom_props_gpencil(DataButtonsPanel, PropertyPanel, Panel):
+    _context_path = "object.data"
+    _property_type = bpy.types.GreasePencil
+
+###############################
+
+classes = (
+    DATA_PT_gpencil,
+    DATA_PT_gpencil_datapanel,
+    DATA_PT_gpencil_onionpanel,
+    DATA_PT_gpencil_layer_optionpanel,
+    DATA_PT_gpencil_parentpanel,
+    DATA_PT_gpencil_vertexpanel,
+    DATA_PT_gpencil_display,
+    DATA_PT_custom_props_gpencil,
+
+    GPENCIL_UL_layer,
+    GPENCIL_UL_vgroups,
+
+    GPENCIL_MT_layer_specials,
+    GPENCIL_MT_gpencil_vertex_group,
+)
+
+if __name__ == "__main__":  # only for live edit.
+    from bpy.utils import register_class
+    for cls in classes:
+        register_class(cls)
index 03ebea6..2328925 100644 (file)
@@ -28,10 +28,14 @@ class ModifierButtonsPanel:
     bl_context = "modifier"
     bl_options = {'HIDE_HEADER'}
 
-
 class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
     bl_label = "Modifiers"
 
+    @classmethod
+    def poll(cls, context):
+        ob = context.object
+        return ob and ob.type != 'GPENCIL'
+
     def draw(self, context):
         layout = self.layout
 
@@ -1563,8 +1567,447 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
             layout.operator("object.correctivesmooth_bind", text="Unbind" if is_bind else "Bind")
 
 
+class DATA_PT_gpencil_modifiers(ModifierButtonsPanel, Panel):
+    bl_label = "Modifiers"
+
+    @classmethod
+    def poll(cls, context):
+        ob = context.object
+        return ob and ob.type == 'GPENCIL'
+
+    def draw(self, context):
+        layout = self.layout
+
+        ob = context.object
+
+        layout.operator_menu_enum("object.gpencil_modifier_add", "type")
+
+        for md in ob.grease_pencil_modifiers:
+            box = layout.template_greasepencil_modifier(md)
+            if box:
+                # match enum type to our functions, avoids a lookup table.
+                getattr(self, md.type)(box, ob, md)
+
+    # the mt.type enum is (ab)used for a lookup on function names
+    # ...to avoid lengthy if statements
+    # so each type must have a function here.
+
+    def GP_NOISE(self, layout, ob, md):
+        gpd = ob.data
+        split = layout.split()
+
+        col = split.column()
+        row = col.row(align=True)
+        row.prop(md, "factor")
+        row.prop(md, "random", text="", icon="TIME", toggle=True)
+        row = col.row()
+        row.enabled = md.random
+        row.prop(md, "step")
+        col.prop(md, "full_stroke")
+        col.prop(md, "move_extreme")
+
+        col = split.column()
+        col.label("Layer:")
+        row = col.row(align=True)
+        row.prop_search(md, "layer", gpd, "layers", text="", icon='GREASEPENCIL')
+        row.prop(md, "invert_layers", text="", icon="ARROW_LEFTRIGHT")
+
+        col.label("Vertex Group:")
+        row = col.row(align=True)
+        row.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
+        row.prop(md, "invert_vertex", text="", icon="ARROW_LEFTRIGHT")
+
+        row = col.row(align=True)
+        row.prop(md, "pass_index", text="Pass")
+        row.prop(md, "invert_pass", text="", icon="ARROW_LEFTRIGHT")
+
+        row = layout.row(align=True)
+        row.label("Affect:")
+        row = layout.row(align=True)
+        row.prop(md, "affect_position", text="Position", icon='MESH_DATA', toggle=True)
+        row.prop(md, "affect_strength", text="Strength", icon='COLOR', toggle=True)
+        row.prop(md, "affect_thickness", text="Thickness", icon='LINE_DATA', toggle=True)
+        row.prop(md, "affect_uv", text="UV", icon='MOD_UVPROJECT', toggle=True)
+
+    def GP_SMOOTH(self, layout, ob, md):
+        gpd = ob.data
+        row = layout.row(align=False)
+        row.prop(md, "factor")
+        row.prop(md, "step")
+
+        split = layout.split()
+        col = split.column()
+        col.label("Layer:")
+        row = col.row(align=True)
+        row.prop_search(md, "layer", gpd, "layers", text="", icon='GREASEPENCIL')
+        row.prop(md, "invert_layers", text="", icon="ARROW_LEFTRIGHT")
+
+        col = split.column()
+        col.label("Vertex Group:")
+        row = col.row(align=True)
+        row.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
+        row.prop(md, "invert_vertex", text="", icon="ARROW_LEFTRIGHT")
+
+        row = col.row(align=True)
+        row.prop(md, "pass_index", text="Pass")
+        row.prop(md, "invert_pass", text="", icon="ARROW_LEFTRIGHT")
+
+        row = layout.row(align=True)
+        row.label("Affect:")
+        row = layout.row(align=True)
+        row.prop(md, "affect_position", text="Position", icon='MESH_DATA', toggle=True)
+        row.prop(md, "affect_strength", text="Strength", icon='COLOR', toggle=True)
+        row.prop(md, "affect_thickness", text="Thickness", icon='LINE_DATA', toggle=True)
+        row.prop(md, "affect_uv", text="UV", icon='MOD_UVPROJECT', toggle=True)
+
+    def GP_SUBDIV(self, layout, ob, md):
+        gpd = ob.data
+        split = layout.split()
+
+        col = split.column()
+        row = col.row(align=True)
+        row.prop(md, "level")
+        row.prop(md, "simple", text="", icon="PARTICLE_POINT")
+        row = col.row(align=True)
+        row.prop(md, "pass_index", text="Pass")
+        row.prop(md, "invert_pass", text="", icon="ARROW_LEFTRIGHT")
+
+        col = split.column()
+        col.label("Layer:")
+        row = col.row(align=True)
+        row.prop_search(md, "layer", gpd, "layers", text="", icon='GREASEPENCIL')
+        row.prop(md, "invert_layers", text="", icon="ARROW_LEFTRIGHT")
+
+    def GP_SIMPLIFY(self, layout, ob, md):
+        gpd = ob.data
+
+        row = layout.row()
+        row.prop(md, "mode")
+
+        split = layout.split()
+
+        col = split.column()
+        col.label("Settings:")
+        row = col.row(align=True)
+        row.enabled = md.mode == 'FIXED'
+        row.prop(md, "step")
+
+        row = col.row(align=True)
+        row.enabled = not md.mode == 'FIXED'
+        row.prop(md, "factor")
+
+        col = split.column()
+        col.label("Layer:")
+        row = col.row(align=True)
+        row.prop_search(md, "layer", gpd, "layers", text="", icon='GREASEPENCIL')
+
+        row = col.row(align=True)
+        row.prop(md, "pass_index", text="Pass")
+        row.prop(md, "invert_pass", text="", icon="ARROW_LEFTRIGHT")
+
+    def GP_THICK(self, layout, ob, md):
+        gpd = ob.data
+        split = layout.split()
+
+        col = split.column()
+        row = col.row(align=True)
+        row.prop(md, "thickness")
+        row = col.row(align=True)
+        row.prop(md, "pass_index", text="Pass")
+        row.prop(md, "invert_pass", text="", icon="ARROW_LEFTRIGHT")
+
+        col.prop(md, "normalize_thickness")
+
+        col = split.column()
+        col.label("Layer:")
+        row = col.row(align=True)
+        row.prop_search(md, "layer", gpd, "layers", text="", icon='GREASEPENCIL')
+        row.prop(md, "invert_layers", text="", icon="ARROW_LEFTRIGHT")
+
+        col.label("Vertex Group:")
+        row = col.row(align=True)
+        row.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
+        row.prop(md, "invert_vertex", text="", icon="ARROW_LEFTRIGHT")
+
+        if not md.normalize_thickness:
+            split = layout.split()
+            col = split.column()
+            col.prop(md, "use_custom_curve")
+
+            if md.use_custom_curve:
+                col.template_curve_mapping(md, "curve")
+
+    def GP_TINT(self, layout, ob, md):
+        gpd = ob.data
+        split = layout.split()
+
+        col = split.column()
+        col.prop(md, "color")
+        col.prop(md, "factor")
+
+        col = split.column()
+        col.label("Layer:")
+        row = col.row(align=True)
+        row.prop_search(md, "layer", gpd, "layers", text="", icon='GREASEPENCIL')
+        row.prop(md, "invert_layers", text="", icon="ARROW_LEFTRIGHT")
+        row = col.row(align=True)
+        row.prop(md, "pass_index", text="Pass")
+        row.prop(md, "invert_pass", text="", icon="ARROW_LEFTRIGHT")
+
+        row = layout.row()
+        row.prop(md, "create_colors")
+
+    def GP_COLOR(self, layout, ob, md):
+        gpd = ob.data
+        split = layout.split()
+
+        col = split.column()
+        col.label("Color:")
+        col.prop(md, "hue", text="H")
+        col.prop(md, "saturation", text="S")
+        col.prop(md, "value", text="V")
+
+        col = split.column()
+        col.label("Layer:")
+        row = col.row(align=True)
+        row.prop_search(md, "layer", gpd, "layers", text="", icon='GREASEPENCIL')
+        row.prop(md, "invert_layers", text="", icon="ARROW_LEFTRIGHT")
+        row = col.row(align=True)
+        row.prop(md, "pass_index", text="Pass")
+        row.prop(md, "invert_pass", text="", icon="ARROW_LEFTRIGHT")
+
+        row = layout.row()
+        row.prop(md, "create_colors")
+
+    def GP_OPACITY(self, layout, ob, md):
+        gpd = ob.data
+        split = layout.split()
+
+        col = split.column()
+        col.label("Opacity:")
+        col.prop(md, "factor")
+
+        col = split.column()
+        col.label("Layer:")
+        row = col.row(align=True)
+        row.prop_search(md, "layer", gpd, "layers", text="", icon='GREASEPENCIL')
+        row.prop(md, "invert_layers", text="", icon="ARROW_LEFTRIGHT")
+
+        col.label("Vertex Group:")
+        row = col.row(align=True)
+        row.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
+        row.prop(md, "invert_vertex", text="", icon="ARROW_LEFTRIGHT")
+
+        row = col.row(align=True)
+        row.prop(md, "pass_index", text="Pass")
+        row.prop(md, "invert_pass", text="", icon="ARROW_LEFTRIGHT")
+
+    def GP_INSTANCE(self, layout, ob, md):
+        gpd = ob.data
+
+        col = layout.column()
+        col.prop(md, "count")
+        col.prop(md, "use_make_objects")
+
+        split = layout.split()
+        col = split.column()
+        col.label("Offset:")
+        col.prop(md, "offset", text="")
+
+        col = split.column()
+        col.label("Shift:")
+        col.prop(md, "shift", text="")
+        row = col.row(align=True)
+        row.prop(md, "lock_axis", expand=True)
+
+        split = layout.split()
+        col = split.column()
+        col.label("Rotation:")
+        col.prop(md, "rotation", text="")
+        col.separator()
+        row = col.row(align=True)
+        row.prop(md, "random_rot", text="", icon="TIME", toggle=True)
+        row.prop(md, "rot_factor", text="")
+
+        col = split.column()
+        col.label("Scale:")
+        col.prop(md, "scale", text="")
+        col.separator()
+        row = col.row(align=True)
+        row.prop(md, "random_scale", text="", icon="TIME", toggle=True)
+        row.prop(md, "scale_factor", text="")
+
+        split = layout.split()
+        col = split.column()
+        col.label("Layer:")
+        row = col.row(align=True)
+        row.prop_search(md, "layer", gpd, "layers", text="", icon='GREASEPENCIL')
+        row.prop(md, "invert_layers", text="", icon="ARROW_LEFTRIGHT")
+        row = col.row(align=True)
+        row.prop(md, "pass_index", text="Pass")
+        row.prop(md, "invert_pass", text="", icon="ARROW_LEFTRIGHT")
+
+    def GP_BUILD(self, layout, ob, md):
+        gpd = ob.data
+
+        split = layout.split()
+
+        col = split.column()
+        col.prop(md, "mode")
+        if md.mode == 'CONCURRENT':
+            col.prop(md, "concurrent_time_alignment")
+        else:
+            col.separator() # For spacing
+            col.separator()
+        col.separator()
+
+        col.prop(md, "transition")
+        sub = col.column(align=True)
+        sub.prop(md, "start_delay")
+        sub.prop(md, "length")
+
+        col = split.column(align=True)
+        col.prop(md, "use_restrict_frame_range")
+        sub = col.column(align=True)
+        sub.active = md.use_restrict_frame_range
+        sub.prop(md, "frame_start", text="Start")
+        sub.prop(md, "frame_end", text="End")
+        col.separator()
+
+        col.label("Layer:")
+        row = col.row(align=True)
+        row.prop_search(md, "layer", gpd, "layers", text="", icon='GREASEPENCIL')
+        row.prop(md, "invert_layers", text="", icon="ARROW_LEFTRIGHT")
+
+    def GP_LATTICE(self, layout, ob, md):
+        gpd = ob.data
+        split = layout.split()
+
+        col = split.column()
+        col.label(text="Object:")
+        col.prop(md, "object", text="")
+
+        col = split.column()
+        col.label("Layer:")
+        row = col.row(align=True)
+        row.prop_search(md, "layer", gpd, "layers", text="", icon='GREASEPENCIL')
+        row.prop(md, "invert_layers", text="", icon="ARROW_LEFTRIGHT")
+
+        col.label("Vertex Group:")
+        row = col.row(align=True)
+        row.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
+        row.prop(md, "invert_vertex", text="", icon="ARROW_LEFTRIGHT")
+
+        row = col.row(align=True)
+        row.prop(md, "pass_index", text="Pass")
+        row.prop(md, "invert_pass", text="", icon="ARROW_LEFTRIGHT")
+
+        layout.separator()
+        layout.prop(md, "strength", slider=True)
+
+    def GP_MIRROR(self, layout, ob, md):
+        gpd = ob.data
+
+        row = layout.row(align=True)
+        row.prop(md, "x_axis")
+        row.prop(md, "y_axis")
+        row.prop(md, "z_axis")
+
+        # GPXX: Not implemented yet
+        # layout.separator()
+        # layout.prop(md, "clip")
+
+        layout.label("Layer:")
+        row = layout.row(align=True)
+        row.prop_search(md, "layer", gpd, "layers", text="", icon='GREASEPENCIL')
+        row.prop(md, "invert_layers", text="", icon="ARROW_LEFTRIGHT")
+
+        row = layout.row(align=True)
+        row.prop(md, "pass_index", text="Pass")
+        row.prop(md, "invert_pass", text="", icon="ARROW_LEFTRIGHT")
+
+        layout.label(text="Object:")
+        layout.prop(md, "object", text="")
+
+
+    def GP_HOOK(self, layout, ob, md):
+        gpd = ob.data
+        split = layout.split()
+
+        col = split.column()
+        col.label(text="Object:")
+        col.prop(md, "object", text="")
+        if md.object and md.object.type == 'ARMATURE':
+            col.label(text="Bone:")
+            col.prop_search(md, "subtarget", md.object.data, "bones", text="")
+
+        col = split.column()
+        col.label("Layer:")
+        row = col.row(align=True)
+        row.prop_search(md, "layer", gpd, "layers", text="", icon='GREASEPENCIL')
+        row.prop(md, "invert_layers", text="", icon="ARROW_LEFTRIGHT")
+
+        col.label("Vertex Group:")
+        row = col.row(align=True)
+        row.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
+        row.prop(md, "invert_vertex", text="", icon="ARROW_LEFTRIGHT")
+
+        row = col.row(align=True)
+        row.prop(md, "pass_index", text="Pass")
+        row.prop(md, "invert_pass", text="", icon="ARROW_LEFTRIGHT")
+
+        use_falloff = (md.falloff_type != 'NONE')
+        split = layout.split()
+
+        layout.separator()
+
+        row = layout.row(align=True)
+        if use_falloff:
+            row.prop(md, "falloff_radius")
+        row.prop(md, "strength", slider=True)
+        layout.prop(md, "falloff_type")
+
+        col = layout.column()
+        if use_falloff:
+            if md.falloff_type == 'CURVE':
+                col.template_curve_mapping(md, "falloff_curve")
+
+        split = layout.split()
+
+        col = split.column()
+        col.prop(md, "use_falloff_uniform")
+
+
+    def GP_OFFSET(self, layout, ob, md):
+        gpd = ob.data
+        split = layout.split()
+
+        col = split.column()
+        col.prop(md, "location")
+        col.prop(md, "scale")
+
+        col = split.column()
+        col.prop(md, "rotation")
+
+
+        col.label("Layer:")
+        row = col.row(align=True)
+        row.prop_search(md, "layer", gpd, "layers", text="", icon='GREASEPENCIL')
+        row.prop(md, "invert_layers", text="", icon="ARROW_LEFTRIGHT")
+
+        col.label("Vertex Group:")
+        row = col.row(align=True)
+        row.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
+        row.prop(md, "invert_vertex", text="", icon="ARROW_LEFTRIGHT")
+
+        row = col.row(align=True)
+        row.prop(md, "pass_index", text="Pass")
+        row.prop(md, "invert_pass", text="", icon="ARROW_LEFTRIGHT")
+
+
 classes = (
     DATA_PT_modifiers,
+    DATA_PT_gpencil_modifiers,
 )
 
 if __name__ == "__main__":  # only for live edit.
diff --git a/release/scripts/startup/bl_ui/properties_data_shaderfx.py b/release/scripts/startup/bl_ui/properties_data_shaderfx.py
new file mode 100644 (file)
index 0000000..5010f56
--- /dev/null
@@ -0,0 +1,134 @@
+# ##### BEGIN GPL LICENSE BLOCK #####
+#
+#  This program is free software; you can redistribute it and/or
+#  modify it under the terms of the GNU General Public License
+#  as published by the Free Software Foundation; either version 2
+#  of the License, or (at your option) any later version.
+#
+#  This program is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with this program; if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# ##### END GPL LICENSE BLOCK #####
+
+# <pep8 compliant>
+import bpy
+from bpy.types import Panel
+from bpy.app.translations import pgettext_iface as iface_
+
+
+class ShaderFxButtonsPanel:
+    bl_space_type = 'PROPERTIES'
+    bl_region_type = 'WINDOW'
+    bl_context = "shaderfx"
+    bl_options = {'HIDE_HEADER'}
+
+class DATA_PT_shader_fx(ShaderFxButtonsPanel, Panel):
+    bl_label = "Effects"
+
+    @classmethod
+    def poll(cls, context):
+        return True
+        ob = context.object
+        return ob and ob.type == 'GPENCIL'
+
+    def draw(self, context):
+        layout = self.layout
+        layout.use_property_split = True
+
+        ob = context.object
+
+        layout.operator_menu_enum("object.shaderfx_add", "type")
+
+        for fx in ob.shader_effects:
+            box = layout.template_shaderfx(fx)
+            if box:
+                # match enum type to our functions, avoids a lookup table.
+                getattr(self, fx.type)(box, fx)
+
+    # the mt.type enum is (ab)used for a lookup on function names
+    # ...to avoid lengthy if statements
+    # so each type must have a function here.
+
+    def FX_BLUR(self, layout, fx):
+
+        layout.prop(fx, "factor", text="Factor")
+        layout.prop(fx, "samples", text="Samples")
+
+        layout.separator()
+        layout.prop(fx, "use_dof_mode")
+        if fx.use_dof_mode:
+            layout.prop(fx, "coc")
+
+    def FX_COLORIZE(self, layout, fx):
+        layout.prop(fx, "mode", text="Mode")
+
+        if fx.mode == 'BITONE':
+            layout.prop(fx, "low_color", text="Low Color")
+        if fx.mode == 'CUSTOM':
+            layout.prop(fx, "low_color", text="Color")
+
+        if fx.mode == 'BITONE':
+            layout.prop(fx, "high_color", text="High Color")
+
+        if fx.mode in {'BITONE', 'CUSTOM', 'TRANSPARENT'}:
+            layout.prop(fx, "factor")
+
+    def FX_WAVE(self, layout,fx):
+        layout.prop(fx, "orientation", expand=True)
+
+        layout.separator()
+        layout.prop(fx, "amplitude")
+        layout.prop(fx, "period")
+        layout.prop(fx, "phase")
+
+    def FX_PIXEL(self, layout, fx):
+        layout.prop(fx, "size", text="Size")
+
+        layout.prop(fx, "use_lines", text="Display Lines")
+
+        col = layout.column()
+        col.enabled = fx.use_lines
+        col.prop(fx, "color")
+
+    def FX_RIM(self, layout, fx):
+        layout.prop(fx, "offset", text="Offset")
+
+        layout.prop(fx, "rim_color")
+        layout.prop(fx, "mask_color")
+        layout.prop(fx, "mode")
+        layout.prop(fx, "blur")
+        layout.prop(fx, "samples")
+
+    def FX_SWIRL(self, layout, fx):
+        layout.prop(fx, "object", text="Object")
+
+        layout.prop(fx, "radius")
+        layout.prop(fx, "angle")
+
+        layout.prop(fx, "transparent")
+
+    def FX_FLIP(self, layout, fx):
+        layout.prop(fx, "flip_horizontal")
+        layout.prop(fx, "flip_vertical")
+
+    def FX_LIGHT(self, layout, fx):
+        layout.prop(fx, "object", text="Object")
+
+        layout.prop(fx, "energy")
+        layout.prop(fx, "ambient")
+
+
+classes = (
+    DATA_PT_shader_fx,
+)
+
+if __name__ == "__main__":  # only for live edit.
+    from bpy.utils import register_class
+    for cls in classes:
+        register_class(cls)
index 55b798d..252f87d 100644 (file)
 
 # <pep8 compliant>
 
-
+import bpy
 from bpy.types import Menu, UIList
 from bpy.app.translations import pgettext_iface as iface_
 
 
 def gpencil_stroke_placement_settings(context, layout):
     if context.space_data.type == 'VIEW_3D':
-        propname = "gpencil_stroke_placement_view3d"
+        propname = "annotation_stroke_placement_view3d"
     elif context.space_data.type == 'SEQUENCE_EDITOR':
-        propname = "gpencil_stroke_placement_sequencer_preview"
+        propname = "annotation_stroke_placement_sequencer_preview"
     elif context.space_data.type == 'IMAGE_EDITOR':
-        propname = "gpencil_stroke_placement_image_editor"
+        propname = "annotation_stroke_placement_image_editor"
     else:
-        propname = "gpencil_stroke_placement_view2d"
+        propname = "annotation_stroke_placement_view2d"
 
     ts = context.tool_settings
 
     col = layout.column(align=True)
 
-    col.label(text="Stroke Placement:")
-
-    row = col.row(align=True)
-    row.prop_enum(ts, propname, 'VIEW')
-    row.prop_enum(ts, propname, 'CURSOR')
-
-    if context.space_data.type == 'VIEW_3D':
+    if context.space_data.type != 'VIEW_3D':
+        col.label(text="Stroke Placement:")
         row = col.row(align=True)
-        row.prop_enum(ts, propname, 'SURFACE')
-        row.prop_enum(ts, propname, 'STROKE')
-
-        row = col.row(align=False)
-        row.active = getattr(ts, propname) in {'SURFACE', 'STROKE'}
-        row.prop(ts, "use_gpencil_stroke_endpoints")
-
-        if context.scene.tool_settings.gpencil_stroke_placement_view3d == 'CURSOR':
-            row = col.row(align=True)
-            row.label("Lock axis:")
-            row = col.row(align=True)
-            row.prop(ts.gpencil_sculpt, "lockaxis", expand=True)
+        row.prop_enum(ts, propname, 'VIEW')
+        row.prop_enum(ts, propname, 'CURSOR', text="Cursor")
 
 
 def gpencil_active_brush_settings_simple(context, layout):
@@ -73,7 +58,7 @@ def gpencil_active_brush_settings_simple(context, layout):
     row.operator_menu_enum("gpencil.brush_change", "brush", text="", icon='BRUSH_DATA')
     row.prop(brush, "name", text="")
 
-    col.prop(brush, "line_width", slider=True)
+    col.prop(brush, "size", slider=True)
     row = col.row(align=True)
     row.prop(brush, "use_random_pressure", text="", icon='RNDCURVE')
     row.prop(brush, "pen_sensitivity_factor", slider=True)
@@ -90,6 +75,7 @@ def gpencil_active_brush_settings_simple(context, layout):
     row.prop(brush, "angle_factor", text="Factor", slider=True)
 
 
+# XXX: To be replaced with active tools
 class GreasePencilDrawingToolsPanel:
     # subclass must set
     # bl_space_type = 'IMAGE_EDITOR'
@@ -99,8 +85,7 @@ class GreasePencilDrawingToolsPanel:
 
     @classmethod
     def poll(cls, context):
-        # XXX - disabled in 2.8 branch.
-        return False
+        return True
 
     @staticmethod
     def draw(self, context):
@@ -113,12 +98,12 @@ class GreasePencilDrawingToolsPanel:
 
         col.label(text="Draw:")
         row = col.row(align=True)
-        row.operator("gpencil.draw", icon='GREASEPENCIL', text="Draw").mode = 'DRAW'
-        row.operator("gpencil.draw", icon='FORCE_CURVE', text="Erase").mode = 'ERASER'  # XXX: Needs a dedicated icon
+        row.operator("gpencil.annotate", icon='GREASEPENCIL', text="Draw").mode = 'DRAW'
+        row.operator("gpencil.annotate", icon='FORCE_CURVE', text="Erase").mode = 'ERASER'  # XXX: Needs a dedicated icon
 
         row = col.row(align=True)
-        row.operator("gpencil.draw", icon='LINE_DATA', text="Line").mode = 'DRAW_STRAIGHT'
-        row.operator("gpencil.draw", icon='MESH_DATA', text="Poly").mode = 'DRAW_POLY'
+        row.operator("gpencil.annotate", icon='LINE_DATA', text="Line").mode = 'DRAW_STRAIGHT'
+        row.operator("gpencil.annotate", icon='MESH_DATA', text="Poly").mode = 'DRAW_POLY'
 
         col.separator()
 
@@ -126,15 +111,15 @@ class GreasePencilDrawingToolsPanel:
         sub.operator("gpencil.blank_frame_add", icon='NEW')
         sub.operator("gpencil.active_frames_delete_all", icon='X', text="Delete Frame(s)")
 
-        sub = col.column(align=True)
-        sub.prop(context.tool_settings, "use_gpencil_additive_drawing", text="Additive Drawing")
-        sub.prop(context.tool_settings, "use_gpencil_continuous_drawing", text="Continuous Drawing")
-        sub.prop(context.tool_settings, "use_gpencil_draw_onback", text="Draw on Back")
+        #sub = col.column(align=True)
+        #sub.prop(context.tool_settings, "use_gpencil_additive_drawing", text="Additive Drawing")
+        #sub.prop(context.tool_settings, "use_gpencil_continuous_drawing", text="Continuous Drawing")
+        #sub.prop(context.tool_settings, "use_gpencil_draw_onback", text="Draw on Back")
 
         col.separator()
         col.separator()
 
-        if context.space_data.type in {'VIEW_3D', 'CLIP_EDITOR'}:
+        if context.space_data.type in {'CLIP_EDITOR'}:
             col.separator()
             col.label("Data Source:")
             row = col.row(align=True)
@@ -143,8 +128,8 @@ class GreasePencilDrawingToolsPanel:
             elif is_clip_editor:
                 row.prop(context.space_data, "grease_pencil_source", expand=True)
 
-        col.separator()
-        col.separator()
+        #col.separator()
+        #col.separator()
 
         gpencil_stroke_placement_settings(context, col)
 
@@ -157,28 +142,16 @@ class GreasePencilDrawingToolsPanel:
             col = layout.column(align=True)
             col.prop(gpd, "use_stroke_edit_mode", text="Enable Editing", icon='EDIT', toggle=True)
 
-        if is_3d_view:
-            col.separator()
-            col.separator()
-
-            col.label(text="Tools:")
-            col.operator_menu_enum("gpencil.convert", text="Convert to Geometry...", property="type")
-            col.operator("view3d.ruler")
-
 
 class GreasePencilStrokeEditPanel:
     # subclass must set
     # bl_space_type = 'IMAGE_EDITOR'
     bl_label = "Edit Strokes"
-    bl_category = "Grease Pencil"
+    bl_category = "Tools"
     bl_region_type = 'TOOLS'
-    bl_options = {'DEFAULT_CLOSED'}
 
     @classmethod
     def poll(cls, context):
-        # XXX - disabled in 2.8 branch.
-        return False
-
         if context.gpencil_data is None:
             return False
 
@@ -204,7 +177,7 @@ class GreasePencilStrokeEditPanel:
             col.operator("gpencil.select_linked")
             col.operator("gpencil.select_more")
             col.operator("gpencil.select_less")
-            col.operator("gpencil.palettecolor_select")
+            col.operator("gpencil.select_alternate")
 
         layout.label(text="Edit:")
         row = layout.row(align=True)
@@ -228,258 +201,124 @@ class GreasePencilStrokeEditPanel:
 
             layout.separator()
 
-        col = layout.column(align=True)
-        col.operator("transform.bend", text="Bend")
-        col.operator("transform.mirror", text="Mirror")
-        col.operator("transform.shear", text="Shear")
-        col.operator("transform.tosphere", text="To Sphere")
-
         layout.separator()
         col = layout.column(align=True)
         col.operator_menu_enum("gpencil.stroke_arrange", text="Arrange Strokes...", property="direction")
         col.operator("gpencil.stroke_change_color", text="Move to Color")
 
-        if is_3d_view:
-            layout.separator()
-
         layout.separator()
         col = layout.column(align=True)
         col.operator("gpencil.stroke_subdivide", text="Subdivide")
-        col.operator("gpencil.stroke_join", text="Join").type = 'JOIN'
-        col.operator("gpencil.stroke_join", text="Join & Copy").type = 'JOINCOPY'
-        col.operator("gpencil.stroke_flip", text="Flip Direction")
-
-        gpd = context.gpencil_data
-        if gpd:
-            col.prop(gpd, "show_stroke_direction", text="Show Directions")
-
-        if is_3d_view:
-            layout.separator()
-            layout.operator_menu_enum("gpencil.reproject", text="Reproject Strokes...", property="type")
-
-
-class GreasePencilInterpolatePanel:
-    bl_space_type = 'VIEW_3D'
-    bl_label = "Interpolate"
-    bl_category = "Grease Pencil"
-    bl_region_type = 'TOOLS'
-    bl_options = {'DEFAULT_CLOSED'}
-
-    @classmethod
-    def poll(cls, context):
-        # XXX - disabled in 2.8 branch.
-        return False
-
-        if context.gpencil_data is None:
-            return False
-        elif context.space_data.type != 'VIEW_3D':
-            return False
-
-        gpd = context.gpencil_data
-        return bool(context.editable_gpencil_strokes) and bool(gpd.use_stroke_edit_mode)
-
-    @staticmethod
-    def draw(self, context):
-        layout = self.layout
-        settings = context.tool_settings.gpencil_interpolate
-
-        col = layout.column(align=True)
-        col.operator("gpencil.interpolate", text="Interpolate")
-        col.operator("gpencil.interpolate_sequence", text="Sequence")
-        col.operator("gpencil.interpolate_reverse", text="Remove Breakdowns")
-
-        col = layout.column(align=True)
-        col.label(text="Options:")
-        col.prop(settings, "interpolate_all_layers")
-        col.prop(settings, "interpolate_selected_only")
-
-        col = layout.column(align=True)
-        col.label(text="Sequence Options:")
-        col.prop(settings, "type")
-        if settings.type == 'CUSTOM':
-            box = layout.box()
-            # TODO: Options for loading/saving curve presets?
-            box.template_curve_mapping(settings, "interpolation_curve", brush=True)
-        elif settings.type != 'LINEAR':
-            col.prop(settings, "easing")
-
-            if settings.type == 'BACK':
-                layout.prop(settings, "back")
-            elif setting.type == 'ELASTIC':
-                sub = layout.column(align=True)
-                sub.prop(settings, "amplitude")
-                sub.prop(settings, "period")
-
-
-class GreasePencilBrushPanel:
-    # subclass must set
-    # bl_space_type = 'IMAGE_EDITOR'
-    bl_label = "Drawing Brushes"
-    bl_category = "Grease Pencil"
-    bl_region_type = 'TOOLS'
-
-    @classmethod
-    def poll(cls, context):
-        # XXX - disabled in 2.8 branch.
-        return False
+        row = col.row(align=True)
+        row.operator("gpencil.stroke_simplify_fixed", text="Simplify")
+        row.operator("gpencil.stroke_simplify", text="Adaptative")
 
-    @staticmethod
-    def draw(self, context):
-        layout = self.layout
+        col.separator()
 
-        row = layout.row()
-        col = row.column()
-        ts = context.scene.tool_settings
-        if len(ts.gpencil_brushes) >= 2:
-            brows = 3
-        else:
-            brows = 2
-        col.template_list("GPENCIL_UL_brush", "", ts, "gpencil_brushes", ts.gpencil_brushes, "active_index", rows=brows)
+        row = col.row(align=True)
+        row.operator("gpencil.stroke_join", text="Join").type = 'JOIN'
+        row.operator("gpencil.stroke_join", text="& Copy").type = 'JOINCOPY'
 
-        col = row.column()
+        col.operator("gpencil.stroke_flip", text="Flip Direction")
 
-        sub = col.column(align=True)
-        sub.operator("gpencil.brush_add", icon='ZOOMIN', text="")
-        sub.operator("gpencil.brush_remove", icon='ZOOMOUT', text="")
-        sub.menu("GPENCIL_MT_brush_specials", icon='DOWNARROW_HLT', text="")
-        brush = context.active_gpencil_brush
-        if brush:
-            if len(ts.gpencil_brushes) > 1:
-                col.separator()
-                sub = col.column(align=True)
-                sub.operator("gpencil.brush_move", icon='TRIA_UP', text="").type = 'UP'
-                sub.operator("gpencil.brush_move", icon='TRIA_DOWN', text="").type = 'DOWN'
+        if is_3d_view:
+            layout.separator()
 
-        # Brush details
-        if brush is not None:
-            row = layout.row()
-            row.prop(brush, "line_width")
-            row = layout.row(align=True)
-            row.prop(brush, "use_random_pressure", text="", icon='RNDCURVE')
-            row.prop(brush, "pen_sensitivity_factor", slider=True)
-            row.prop(brush, "use_pressure", text="", icon='STYLUS_PRESSURE')
-            row = layout.row(align=True)
-            row.prop(brush, "use_random_strength", text="", icon='RNDCURVE')
-            row.prop(brush, "strength", slider=True)
-            row.prop(brush, "use_strength_pressure", text="", icon='STYLUS_PRESSURE')
-            row = layout.row(align=True)
-            row.prop(brush, "random_press", slider=True)
+            col = layout.column(align=True)
+            col.operator_menu_enum("gpencil.stroke_separate", text="Separate...", property="mode")
+            col.operator("gpencil.stroke_split", text="Split")
 
-            row = layout.row(align=True)
-            row.prop(brush, "jitter", slider=True)
-            row.prop(brush, "use_jitter_pressure", text="", icon='STYLUS_PRESSURE')
-            row = layout.row()
-            row.prop(brush, "angle", slider=True)
-            row.prop(brush, "angle_factor", text="Factor", slider=True)
-
-            box = layout.box()
-            col = box.column(align=True)
-            col.label(text="Stroke Quality:")
-            col.prop(brush, "pen_smooth_factor")
-            col.prop(brush, "pen_smooth_steps")
-            col.separator()
-            row = col.row(align=False)
-            row.prop(brush, "pen_subdivision_steps")
-            row.prop(brush, "random_subdiv", text="Randomness", slider=True)
+            col = layout.column(align=True)
+            col.label(text="Cleanup:")
+            col.operator_menu_enum("gpencil.reproject", text="Reproject Strokes...", property="type")
+            col.operator_menu_enum("gpencil.frame_clean_fill", text="Clean Boundary Strokes...", property="mode")
 
 
 class GreasePencilStrokeSculptPanel:
     # subclass must set
     # bl_space_type = 'IMAGE_EDITOR'
     bl_label = "Sculpt Strokes"
-    bl_category = "Grease Pencil"
-    bl_region_type = 'TOOLS'
-
-    @classmethod
-    def poll(cls, context):
-        # XXX - disabled in 2.8 branch.
-        return False
-
-        if context.gpencil_data is None:
-            return False
-
-        gpd = context.gpencil_data
-        return bool(context.editable_gpencil_strokes) and bool(gpd.use_stroke_edit_mode)
+    bl_category = "Tools"
 
     @staticmethod
     def draw(self, context):
         layout = self.layout
+        layout.use_property_split = True
+        layout.use_property_decorate = False
 
         settings = context.tool_settings.gpencil_sculpt
         tool = settings.tool
         brush = settings.brush
 
-        layout.column().prop(settings, "tool")
+        layout.template_icon_view(settings, "tool", show_labels=True)
 
-        col = layout.column()
-        col.prop(brush, "size", slider=True)
-        row = col.row(align=True)
+        layout.prop(brush, "size", slider=True)
+        row = layout.row(align=True)
         row.prop(brush, "strength", slider=True)
         row.prop(brush, "use_pressure_strength", text="")
-        col.prop(brush, "use_falloff")
-        if tool in {'SMOOTH', 'RANDOMIZE'}:
-            row = layout.row(align=True)
-            row.prop(settings, "affect_position", text="Position", icon='MESH_DATA', toggle=True)
-            row.prop(settings, "affect_strength", text="Strength", icon='COLOR', toggle=True)
-            row.prop(settings, "affect_thickness", text="Thickness", icon='LINE_DATA', toggle=True)
 
-        layout.separator()
+        layout.prop(brush, "use_falloff")
 
-        if tool == 'THICKNESS':
-            layout.row().prop(brush, "direction", expand=True)
-        elif tool == 'PINCH':
-            row = layout.row(align=True)
-            row.prop_enum(brush, "direction", 'ADD', text="Pinch")
-            row.prop_enum(brush, "direction", 'SUBTRACT', text="Inflate")
-        elif settings.tool == 'TWIST':
-            row = layout.row(align=True)
-            row.prop_enum(brush, "direction", 'SUBTRACT', text="CW")
-            row.prop_enum(brush, "direction", 'ADD', text="CCW")
+        if tool in {'SMOOTH', 'RANDOMIZE'}:
+            layout.prop(settings, "affect_position", text="Affect Position")
+            layout.prop(settings, "affect_strength", text="Affect Strength")
+            layout.prop(settings, "affect_thickness", text="Affect Thickness")
 
-        row = layout.row(align=True)
-        row.prop(settings, "use_select_mask")
-        row = layout.row(align=True)
-        row.prop(settings, "selection_alpha", slider=True)
+            if tool == 'SMOOTH':
+                layout.prop(brush, "affect_pressure")
 
-        if tool == 'SMOOTH':
-            layout.prop(brush, "affect_pressure")
+            layout.prop(settings, "affect_uv", text="Affect UV")
 
+        if tool in {'THICKNESS', 'PINCH', 'TWIST'}:
+            layout.prop(brush, "direction", expand=True)
 
-class GreasePencilBrushCurvesPanel:
-    # subclass must set
-    # bl_space_type = 'IMAGE_EDITOR'
-    bl_label = "Brush Curves"
-    bl_category = "Grease Pencil"
-    bl_region_type = 'TOOLS'
+
+# GP Object Tool Settings
+class GreasePencilAppearancePanel:
+    bl_label = "Brush Appearance"
     bl_options = {'DEFAULT_CLOSED'}
 
     @classmethod
     def poll(cls, context):
-        # XXX - disabled in 2.8 branch.
-        return False
-
-        if context.active_gpencil_brush is None:
-            return False
-
-        brush = context.active_gpencil_brush
-        return bool(brush)
+        ob = context.active_object
+        return ob and ob.type == 'GPENCIL'
 
     @staticmethod
     def draw(self, context):
         layout = self.layout
-        brush = context.active_gpencil_brush
-        # Brush
-        layout.label("Sensitivity")
-        box = layout.box()
-        box.template_curve_mapping(brush, "curve_sensitivity", brush=True)
+        layout.use_property_split = True
+        layout.use_property_decorate = False
 
-        layout.label("Strength")
-        box = layout.box()
-        box.template_curve_mapping(brush, "curve_strength", brush=True)
+        ob = context.active_object
 
-        layout.label("Jitter")
-        box = layout.box()
-        box.template_curve_mapping(brush, "curve_jitter", brush=True)
+        if ob.mode == 'GPENCIL_PAINT':
+            brush = context.active_gpencil_brush
+            gp_settings = brush.gpencil_settings
+
+            layout.prop(gp_settings, "gpencil_brush_type", text="Brush Type")
+
+            sub = layout.column(align=True)
+            sub.enabled = not brush.use_custom_icon
+            sub.prop(gp_settings, "gp_icon", text="Icon")
+
+            layout.prop(brush, "use_custom_icon")
+            sub = layout.column()
+            sub.active = brush.use_custom_icon
+            sub.prop(brush, "icon_filepath", text="")
+
+            layout.prop(gp_settings, "use_cursor", text="Show Brush")
+
+            if gp_settings.gpencil_brush_type == 'FILL':
+                layout.prop(brush, "cursor_color_add", text="Color")
+
+        elif ob.mode in ('GPENCIL_SCULPT', 'GPENCIL_WEIGHT'):
+            settings = context.tool_settings.gpencil_sculpt
+            brush = settings.brush
+
+            col = layout.column(align=True)
+            col.prop(brush, "use_cursor", text="Show Brush")
+            col.row().prop(brush, "cursor_color_add", text="Add")
+            col.row().prop(brush, "cursor_color_sub", text="Subtract")
 
 
 ###############################
@@ -539,6 +378,7 @@ class GPENCIL_MT_pie_tool_palette(Menu):
                 col.operator("gpencil.select_border", text="Border Select", icon='BORDER_RECT')
                 col.operator("gpencil.select_circle", text="Circle Select", icon='META_EMPTY')
                 col.operator("gpencil.select_lasso", text="Lasso Select", icon='BORDER_LASSO')
+                col.operator("gpencil.select_alternate", text="Alternate Select", icon='BORDER_LASSO')
 
                 # SW - Edit Tools
                 col = pie.column()
@@ -566,7 +406,7 @@ class GPENCIL_MT_pie_settings_palette(Menu):
         pie = layout.menu_pie()
         gpd = context.gpencil_data
         gpl = context.active_gpencil_layer
-        palcolor = context.active_gpencil_palettecolor
+        palcolor = None #context.active_gpencil_palettecolor
         brush = context.active_gpencil_brush
 
         is_editmode = bool(gpd and gpd.use_stroke_edit_mode and context.editable_gpencil_strokes)
@@ -737,6 +577,16 @@ class GPENCIL_MT_snap(Menu):
         layout.operator("view3d.snap_cursor_to_grid", text="Cursor to Grid")
 
 
+class GPENCIL_MT_separate(Menu):
+    bl_label = "Separate"
+
+    def draw(self, context):
+        layout = self.layout
+        layout.operator("gpencil.stroke_separate", text="Selected Points").mode = 'POINT'
+        layout.operator("gpencil.stroke_separate", text="Selected Strokes").mode = 'STROKE'
+        layout.operator("gpencil.stroke_separate", text="Active Layer").mode = 'LAYER'
+
+
 class GPENCIL_MT_gpencil_edit_specials(Menu):
     bl_label = "GPencil Specials"
 
@@ -747,6 +597,14 @@ class GPENCIL_MT_gpencil_edit_specials(Menu):
         layout.operator_context = 'INVOKE_REGION_WIN'
 
         layout.operator("gpencil.stroke_subdivide", text="Subdivide")
+        layout.operator("gpencil.stroke_simplify_fixed", text="Simplify")
+        layout.operator("gpencil.stroke_simplify", text="Simplify Adaptative")
+
+        layout.separator()
+        layout.menu("GPENCIL_MT_separate", text="Separate")
+
+        layout.separator()
+        layout.operator("gpencil.stroke_split", text="Split")
 
         layout.separator()
 
@@ -754,167 +612,129 @@ class GPENCIL_MT_gpencil_edit_specials(Menu):
         layout.operator("gpencil.stroke_join", text="Join & Copy").type = 'JOINCOPY'
         layout.operator("gpencil.stroke_flip", text="Flip Direction")
 
+        layout.separator()
+        layout.operator("gpencil.frame_duplicate", text="Duplicate Active Frame")
+        layout.operator("gpencil.frame_duplicate", text="Duplicate Active Frame All Layers").mode = 'ALL'
+
         if is_3d_view:
             layout.separator()
             layout.operator("gpencil.reproject")
 
 
-###############################
-
-
-class GPENCIL_UL_brush(UIList):
-    def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
-        # assert(isinstance(item, bpy.types.GPencilBrush)
-        brush = item
-
-        if self.layout_type in {'DEFAULT', 'COMPACT'}:
-            row = layout.row(align=True)
-            row.prop(brush, "name", text="", emboss=False, icon='BRUSH_DATA')
-        elif self.layout_type == 'GRID':
-            layout.alignment = 'CENTER'
-            layout.label(text="", icon_value=icon)
-
-
-class GPENCIL_UL_palettecolor(UIList):
-    def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
-        # assert(isinstance(item, bpy.types.PaletteColor)
-        palcolor = item
-
-        if self.layout_type in {'DEFAULT', 'COMPACT'}:
-            if palcolor.lock:
-                layout.active = False
-
-            split = layout.split(percentage=0.25)
-            row = split.row(align=True)
-            row.enabled = not palcolor.lock
-            row.prop(palcolor, "color", text="", emboss=palcolor.is_stroke_visible)
-            row.prop(palcolor, "fill_color", text="", emboss=palcolor.is_fill_visible)
-            split.prop(palcolor, "name", text="", emboss=False)
-
-            row = layout.row(align=True)
-            row.prop(palcolor, "lock", text="", emboss=False)
-            row.prop(palcolor, "hide", text="", emboss=False)
-            if palcolor.ghost is True:
-                icon = 'GHOST_DISABLED'
-            else:
-                icon = 'GHOST_ENABLED'
-            row.prop(palcolor, "ghost", text="", icon=icon, emboss=False)
-
-        elif self.layout_type == 'GRID':
-            layout.alignment = 'CENTER'
-            layout.label(text="", icon_value=icon)
-
+class GPENCIL_MT_gpencil_sculpt_specials(Menu):
+    bl_label = "GPencil Specials"
 
-class GPENCIL_UL_layer(UIList):
-    def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
-        # assert(isinstance(item, bpy.types.GPencilLayer)
-        gpl = item
+    def draw(self, context):
+        layout = self.layout
+        is_3d_view = context.space_data.type == 'VIEW_3D'
 
-        if self.layout_type in {'DEFAULT', 'COMPACT'}:
-            if gpl.lock:
-                layout.active = False
+        layout.operator_context = 'INVOKE_REGION_WIN'
 
-            row = layout.row(align=True)
-            if gpl.is_parented:
-                icon = 'BONE_DATA'
-            else:
-                icon = 'BLANK1'
+        layout.operator("gpencil.frame_duplicate", text="Duplicate Active Frame")
+        layout.operator("gpencil.frame_duplicate", text="Duplicate Active Frame All Layers").mode = 'ALL'
 
-            row.label(text="", icon=icon)
-            row.prop(gpl, "info", text="", emboss=False)
+        layout.separator()
 
-            row = layout.row(align=True)
-            row.prop(gpl, "lock", text="", emboss=False)
-            row.prop(gpl, "hide", text="", emboss=False)
-            row.prop(gpl, "unlock_color", text="", emboss=False)
-        elif self.layout_type == 'GRID':
-            layout.alignment = 'CENTER'
-            layout.label(text="", icon_value=icon)
+        layout.operator("gpencil.stroke_subdivide", text="Subdivide")
+        layout.operator("gpencil.stroke_simplify_fixed", text="Simplify")
+        layout.operator("gpencil.stroke_simplify", text="Simplify Adaptative")
 
 
-class GPENCIL_MT_layer_specials(Menu):
-    bl_label = "Layer"
+class GPENCIL_MT_gpencil_draw_specials(Menu):
+    bl_label = "GPencil Draw Specials"
 
     def draw(self, context):
         layout = self.layout
+        is_3d_view = context.space_data.type == 'VIEW_3D'
 
-        layout.operator("gpencil.layer_duplicate", icon='COPY_ID')  # XXX: needs a dedicated icon
-
-        layout.separator()
+        layout.operator_context = 'INVOKE_REGION_WIN'
 
-        layout.operator("gpencil.reveal", icon='RESTRICT_VIEW_OFF', text="Show All")
-        layout.operator("gpencil.hide", icon='RESTRICT_VIEW_ON', text="Hide Others").unselected = True
+        layout.operator("gpencil.frame_duplicate", text="Duplicate Active Frame")
+        layout.operator("gpencil.frame_duplicate", text="Duplicate Active Frame All Layers").mode = 'ALL'
 
         layout.separator()
+        layout.operator("gpencil.primitive", text="Line", icon='IPO_CONSTANT').type = 'LINE'
+        layout.operator("gpencil.primitive", text="Rectangle", icon='UV_FACESEL').type = 'BOX'
+        layout.operator("gpencil.primitive", text="Circle", icon='ANTIALIASED').type = 'CIRCLE'
 
-        layout.operator("gpencil.lock_all", icon='LOCKED', text="Lock All")
-        layout.operator("gpencil.unlock_all", icon='UNLOCKED', text="UnLock All")
-
+        # colors
         layout.separator()
+        layout.operator("gpencil.colorpick", text="Colors", icon="GROUP_VCOL")
 
-        layout.operator("gpencil.layer_merge", icon='NLA', text="Merge Down")
 
-
-class GPENCIL_MT_brush_specials(Menu):
-    bl_label = "Layer"
+class GPENCIL_MT_gpencil_draw_delete(Menu):
+    bl_label = "GPencil Draw Delete"
 
     def draw(self, context):
         layout = self.layout
-        layout.operator("gpencil.brush_copy", icon='PASTEDOWN', text="Copy Current Drawing Brush")
-        layout.operator("gpencil.brush_presets_create", icon='HELP', text="Create a Set of Predefined Brushes")
-
+        is_3d_view = context.space_data.type == 'VIEW_3D'
 
-class GPENCIL_MT_palettecolor_specials(Menu):
-    bl_label = "Layer"
+        layout.operator_context = 'INVOKE_REGION_WIN'
 
-    def draw(self, context):
-        layout = self.layout
+        layout.operator("gpencil.active_frames_delete_all", text="Delete Frame")
 
-        layout.operator("gpencil.palettecolor_reveal", icon='RESTRICT_VIEW_OFF', text="Show All")
-        layout.operator("gpencil.palettecolor_hide", icon='RESTRICT_VIEW_ON', text="Hide Others").unselected = True
 
-        layout.separator()
+class GPENCIL_UL_annotation_layer(UIList):
+    def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
+        # assert(isinstance(item, bpy.types.GPencilLayer)
+        gpl = item
+        gpd = context.gpencil_data
 
-        layout.operator("gpencil.palettecolor_lock_all", icon='LOCKED', text="Lock All")
-        layout.operator("gpencil.palettecolor_unlock_all", icon='UNLOCKED', text="UnLock All")
-        layout.operator("gpencil.palettecolor_copy", icon='PASTEDOWN', text="Copy Color")
+        if self.layout_type in {'DEFAULT', 'COMPACT'}:
+            if gpl.lock:
+                layout.active = False
 
-        layout.separator()
+            split = layout.split(percentage=0.2)
+            split.prop(gpl, "color", text="", emboss=True)
+            split.prop(gpl, "info", text="", emboss=False)
 
-        layout.operator("gpencil.palettecolor_select", icon='COLOR', text="Select Strokes")
-        layout.operator("gpencil.stroke_change_color", icon='MAN_TRANS', text="Move to Color")
+            row = layout.row(align=True)
+            # row.prop(gpl, "lock", text="", emboss=False)
+            row.prop(gpl, "hide", text="", emboss=False)
+        elif self.layout_type == 'GRID':
+            layout.alignment = 'CENTER'
+            layout.label(text="", icon_value=icon)
 
 
 class GreasePencilDataPanel:
-    # subclass must set
-    # bl_space_type = 'IMAGE_EDITOR'
-    bl_label = "Grease Pencil Layers"
+    bl_label = "Annotations"
     bl_region_type = 'UI'
 
+    @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:
+            return True
+
     @staticmethod
     def draw_header(self, context):
-        self.layout.prop(context.space_data, "show_grease_pencil", text="")
+        if context.space_data.type != 'VIEW_3D':
+            self.layout.prop(context.space_data, "show_annotation", text="")
 
     @staticmethod
     def draw(self, context):
         layout = self.layout
+        #layout.use_property_split = True
+        layout.use_property_decorate = False
 
         # owner of Grease Pencil data
         gpd_owner = context.gpencil_data_owner
         gpd = context.gpencil_data
 
         # Owner Selector
-        if context.space_data.type == 'VIEW_3D':
-            layout.row().prop(context.tool_settings, "grease_pencil_source", expand=True)
-        elif context.space_data.type == 'CLIP_EDITOR':
+        if context.space_data.type == 'CLIP_EDITOR':
             layout.row().prop(context.space_data, "grease_pencil_source", expand=True)
-
         # Grease Pencil data selector
         layout.template_ID(gpd_owner, "grease_pencil", new="gpencil.data_add", unlink="gpencil.data_unlink")
 
         # Grease Pencil data...
         if (gpd is None) or (not gpd.layers):
-            layout.operator("gpencil.layer_add", text="New Layer")
+            layout.operator("gpencil.layer_add", text="New Note")
         else:
             self.draw_layers(context, layout, gpd)
 
@@ -926,7 +746,7 @@ class GreasePencilDataPanel:
             layer_rows = 5
         else:
             layer_rows = 2
-        col.template_list("GPENCIL_UL_layer", "", gpd, "layers", gpd.layers, "active_index", rows=layer_rows)
+        col.template_list("GPENCIL_UL_annotation_layer", "", gpd, "layers", gpd.layers, "active_index", rows=layer_rows)
 
         col = row.column()
 
@@ -936,8 +756,6 @@ class GreasePencilDataPanel:
 
         gpl = context.active_gpencil_layer
         if gpl:
-            sub.menu("GPENCIL_MT_layer_specials", icon='DOWNARROW_HLT', text="")
-
             if len(gpd.layers) > 1:
                 col.separator()
 
@@ -945,203 +763,70 @@ class GreasePencilDataPanel:
                 sub.operator("gpencil.layer_move", icon='TRIA_UP', text="").type = 'UP'
                 sub.operator("gpencil.layer_move", icon='TRIA_DOWN', text="").type = 'DOWN'
 
-                col.separator()
-
-                sub = col.column(align=True)
-                sub.operator("gpencil.layer_isolate", icon='LOCKED', text="").affect_visibility = False
-                sub.operator("gpencil.layer_isolate", icon='RESTRICT_VIEW_OFF', text="").affect_visibility = True
-
         if gpl:
-            self.draw_layer(context, layout, gpl)
-
-    def draw_layer(self, context, layout, gpl):
-        row = layout.row(align=True)
-        row.prop(gpl, "opacity", text="Opacity", slider=True)
-
-        # Layer options
-        split = layout.split(percentage=0.5)
-        split.active = not gpl.lock
-        split.prop(gpl, "show_x_ray")
-        split.prop(gpl, "show_points")
-
-        # Offsets + Parenting (where available)
-        if context.space_data.type == 'VIEW_3D':
-            split = layout.split(percentage=0.5)
-        else:
-            split = layout.column()  # parenting is not available in 2D editors...
-        split.active = not gpl.lock
-
-        # Offsets - Color Tint
-        col = split.column()
-        subcol = col.column(align=True)
-        subcol.label("Tint")
-        subcol.enabled = not gpl.lock
-        subcol.prop(gpl, "tint_color", text="")
-        subcol.prop(gpl, "tint_factor", text="Factor", slider=True)
-
-        # Offsets - Thickness
-        row = col.row(align=True)
-        row.prop(gpl, "line_change", text="Thickness Change", slider=True)
-        row.operator("gpencil.stroke_apply_thickness", icon='STYLUS_PRESSURE', text="")
+            # layout.prop(gpl, "opacity", text="Opacity", slider=True)
+            # layout.prop(gpl, "thickness", text="Thickness")
+            #
+            # layout.separator()
 
-        # Parenting
-        if context.space_data.type == 'VIEW_3D':
-            col = split.column(align=True)
-            col.label(text="Parent:")
-            col.prop(gpl, "parent", text="")
+            # Full-Row - Frame Locking (and Delete Frame)
+            row = layout.row(align=True)
+            row.active = not gpl.lock
 
-            sub = col.column()
-            sub.prop(gpl, "parent_type", text="")
-            parent = gpl.parent
-            if parent and gpl.parent_type == 'BONE' and parent.type == 'ARMATURE':
-                sub.prop_search(gpl, "parent_bone", parent.data, "bones", text="")
+            if gpl.active_frame:
+                lock_status = iface_("Locked") if gpl.lock_frame else iface_("Unlocked")
+                lock_label = iface_("Frame: %d (%s)") % (gpl.active_frame.frame_number, lock_status)
+            else:
+                lock_label = iface_("Lock Frame")
+            row.prop(gpl, "lock_frame", text=lock_label, icon='UNLOCKED')
+            row.operator("gpencil.active_frame_delete", text="", icon='X')
 
-        layout.separator()
 
-        # Full-Row - Frame Locking (and Delete Frame)
-        row = layout.row(align=True)
-        row.active = not gpl.lock
 
-        if gpl.active_frame:
-            lock_status = iface_("Locked") if gpl.lock_frame else iface_("Unlocked")
-            lock_label = iface_("Frame: %d (%s)") % (gpl.active_frame.frame_number, lock_status)
-        else:
-            lock_label = iface_("Lock Frame")
-        row.prop(gpl, "lock_frame", text=lock_label, icon='UNLOCKED')
-        row.operator("gpencil.active_frame_delete", text="", icon='X')
-
-        layout.separator()
+class GreasePencilOnionPanel:
+    @staticmethod
+    def draw_settings(layout, gp):
+        col = layout.column()
 
-        # Onion skinning
-        col = layout.column(align=True)
-        col.active = not gpl.lock
+        col.prop(gp, "onion_mode")
 
         row = col.row()
-        row.prop(gpl, "use_onion_skinning")
-        sub = row.row(align=True)
-        icon = 'RESTRICT_RENDER_OFF' if gpl.use_ghosts_always else 'RESTRICT_RENDER_ON'
-        sub.prop(gpl, "use_ghosts_always", text="", icon=icon)
-        sub.prop(gpl, "use_ghost_custom_colors", text="", icon='COLOR')
-
-        split = col.split(percentage=0.5)
-        split.active = gpl.use_onion_skinning
+        row.prop(gp, "onion_factor", text="Opacity", slider=True)
 
         # - Before Frames
-        sub = split.column(align=True)
+        sub = layout.column(align=True)
         row = sub.row(align=True)
-        row.active = gpl.use_ghost_custom_colors
-        row.prop(gpl, "before_color", text="")
-        sub.prop(gpl, "ghost_before_range", text="Before")
+        row.active = gp.use_ghost_custom_colors
+        row.prop(gp, "before_color", text="Color Before")
 
-        # - After Frames
-        sub = split.column(align=True)
         row = sub.row(align=True)
-        row.active = gpl.use_ghost_custom_colors
-        row.prop(gpl, "after_color", text="")
-        sub.prop(gpl, "ghost_after_range", text="After")
-
-
-class GreasePencilPaletteColorPanel:
-    # subclass must set
-    bl_label = "Grease Pencil Colors"
-    bl_region_type = 'UI'
-
-    @classmethod
-    def poll(cls, context):
-        # XXX - disabled in 2.8 branch.
-        return False
-
-        if context.gpencil_data is None:
-            return False
-
-        gpd = context.gpencil_data
-        return bool(gpd.layers.active)
-
-    @staticmethod
-    def draw(self, context):
-        layout = self.layout
-        palette = context.active_gpencil_palette
+        row.active = gp.onion_mode in ('ABSOLUTE', 'RELATIVE')
+        row.prop(gp, "ghost_before_range", text="Frames Before")
 
-        if palette:
-            row = layout.row(align=True)
-            row.operator_context = 'EXEC_REGION_WIN'
-            row.operator_menu_enum("gpencil.palette_change", "palette", text="", icon='COLOR')
-            row.prop(palette, "name", text="")
-            row.operator("gpencil.palette_add", icon='ZOOMIN', text="")
-            row.operator("gpencil.palette_remove", icon='X', text="")
-
-            # Palette colors
-            row = layout.row()
-            col = row.column()
-            if len(palette.colors) >= 2:
-                color_rows = 5
-            else:
-                color_rows = 2
-            col.template_list("GPENCIL_UL_palettecolor", "", palette, "colors", palette.colors, "active_index",
-                              rows=color_rows)
-
-            col = row.column()
+        # - After Frames
+        sub = layout.column(align=True)
+        row = sub.row(align=True)
+        row.active = gp.use_ghost_custom_colors
+        row.prop(gp, "after_color", text="Color After")
 
-            sub = col.column(align=True)
-            sub.operator("gpencil.palettecolor_add", icon='ZOOMIN', text="")
-            sub.operator("gpencil.palettecolor_remove", icon='ZOOMOUT', text="")
+        row = sub.row(align=True)
+        row.active = gp.onion_mode in ('ABSOLUTE', 'RELATIVE')
+        row.prop(gp, "ghost_after_range", text="Frames After")
 
-            palcol = context.active_gpencil_palettecolor
-            if palcol:
-                sub.menu("GPENCIL_MT_palettecolor_specials", icon='DOWNARROW_HLT', text="")
+        layout.prop(gp, "use_ghost_custom_colors", text="Use Custom Color")
+        layout.prop(gp, "use_ghosts_always", text="View In Render")
 
-            if len(palette.colors) > 1:
-                col.separator()
+        # - fade and loop
+        row = layout.row()
+        row.active = gp.use_onion_skinning
+        row.prop(gp, "use_onion_fade", text="Fade")
+        if hasattr(gp, "use_onion_loop"): # XXX
+            subrow = layout.row()
+            subrow.active = gp.onion_mode in ('RELATIVE', 'SELECTED')
+            subrow.prop(gp, "use_onion_loop", text="Loop")
 
-                sub = col.column(align=True)
-                sub.operator("gpencil.palettecolor_move", icon='TRIA_UP', text="").direction = 'UP'
-                sub.operator("gpencil.palettecolor_move", icon='TRIA_DOWN', text="").direction = 'DOWN'
-
-                row = layout.row()
-                sub = row.row(align=True)
-                sub.label(text="Isolate:")  # based on active color only
-                sub.operator("gpencil.palettecolor_isolate", icon='LOCKED', text="").affect_visibility = False
-                sub.operator("gpencil.palettecolor_isolate", icon='RESTRICT_VIEW_OFF', text="").affect_visibility = True
-                sub = row.row(align=True)
-                sub.label(text="Lock:")  # based on other stuff...
-                sub.operator("gpencil.stroke_lock_color", icon='BORDER_RECT', text="")
-                sub.operator("gpencil.palette_lock_layer", icon='COLOR', text="")
-
-            pcolor = palette.colors.active
-            if pcolor:
-                self.draw_palettecolors(layout, pcolor)
-
-    # Draw palette colors
-    def draw_palettecolors(self, layout, pcolor):
-        # color settings
-        split = layout.split(percentage=0.5)
-        split.active = not pcolor.lock
-
-        # Column 1 - Stroke
-        col = split.column(align=True)
-        col.enabled = not pcolor.lock
-        col.label(text="Stroke:")
-        col.prop(pcolor, "color", text="")
-        col.prop(pcolor, "alpha", slider=True)
-
-        # Column 2 - Fill
-        col = split.column(align=True)
-        col.enabled = not pcolor.lock
-        col.label(text="Fill:")
-        col.prop(pcolor, "fill_color", text="")
-        col.prop(pcolor, "fill_alpha", text="Opacity", slider=True)
-
-        # Options
-        split = layout.split(percentage=0.5)
-        split.active = not pcolor.lock
-
-        col = split.column(align=True)
-        col.active = not pcolor.lock
-        col.prop(pcolor, "use_volumetric_strokes")
-        col = split.column(align=True)
-        col.active = not pcolor.lock
-        col.prop(pcolor, "use_hq_fill")
 
+###############################
 
 class GreasePencilToolsPanel:
     # For use in "2D" Editors without their own toolbar
@@ -1150,6 +835,7 @@ class GreasePencilToolsPanel:
     # bl_options = {'DEFAULT_CLOSED'}
     bl_label = "Grease Pencil Settings"
     bl_region_type = 'UI'
+    bl_options = {'DEFAULT_CLOSED'}
 
     @classmethod
     def poll(cls, context):
@@ -1183,20 +869,23 @@ class GreasePencilToolsPanel:
 
         gpencil_stroke_placement_settings(context, layout)
 
+###############################
 
 classes = (
     GPENCIL_MT_pie_tool_palette,
     GPENCIL_MT_pie_settings_palette,
     GPENCIL_MT_pie_tools_more,
     GPENCIL_MT_pie_sculpt,
+
     GPENCIL_MT_snap,
+    GPENCIL_MT_separate,
+
     GPENCIL_MT_gpencil_edit_specials,
-    GPENCIL_UL_brush,
-    GPENCIL_UL_palettecolor,
-    GPENCIL_UL_layer,
-    GPENCIL_MT_layer_specials,
-    GPENCIL_MT_brush_specials,
-    GPENCIL_MT_palettecolor_specials,
+    GPENCIL_MT_gpencil_sculpt_specials,
+    GPENCIL_MT_gpencil_draw_specials,
+    GPENCIL_MT_gpencil_draw_delete,
+
+    GPENCIL_UL_annotation_layer,
 )
 
 if __name__ == "__main__":  # only for live edit.
index 0e3e50b..5d12f76 100644 (file)
@@ -86,8 +86,11 @@ class EEVEE_MATERIAL_PT_context_material(MaterialButtonsPanel, Panel):
 
     @classmethod
     def poll(cls, context):
-        engine = context.engine
-        return (context.material or context.object) and (engine in cls.COMPAT_ENGINES)
+        if context.active_object and context.active_object.type == 'GPENCIL':
+            return False
+        else:
+            engine = context.engine
+            return (context.material or context.object) and (engine in cls.COMPAT_ENGINES)
 
     def draw(self, context):
         layout = self.layout
diff --git a/release/scripts/startup/bl_ui/properties_material_gpencil.py b/release/scripts/startup/bl_ui/properties_material_gpencil.py
new file mode 100644 (file)
index 0000000..2d82359
--- /dev/null
@@ -0,0 +1,322 @@
+# ##### BEGIN GPL LICENSE BLOCK #####
+#
+#  This program is free software; you can redistribute it and/or
+#  modify it under the terms of the GNU General Public License
+#  as published by the Free Software Foundation; either version 2
+#  of the License, or (at your option) any later version.
+#
+#  This program is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with this program; if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# ##### END GPL LICENSE BLOCK #####
+
+# <pep8 compliant>
+import bpy
+from bpy.types import Menu, Panel, UIList
+from rna_prop_ui import PropertyPanel
+
+
+class GPENCIL_MT_color_specials(Menu):
+    bl_label = "Layer"
+
+    def draw(self, context):
+        layout = self.layout
+
+        layout.operator("gpencil.color_reveal", icon='RESTRICT_VIEW_OFF', text="Show All")
+        layout.operator("gpencil.color_hide", icon='RESTRICT_VIEW_ON', text="Hide Others").unselected = True
+
+        layout.separator()
+
+        layout.operator("gpencil.color_lock_all", icon='LOCKED', text="Lock All")
+        layout.operator("gpencil.color_unlock_all", icon='UNLOCKED', text="UnLock All")
+
+        layout.separator()
+
+        layout.operator("gpencil.stroke_lock_color", icon='BORDER_RECT', text="Lock Unselected")
+        layout.operator("gpencil.lock_layer", icon='COLOR', text="Lock Unused")
+
+
+class GPENCIL_UL_matslots(UIList):
+    def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
+        slot = item
+        ma = slot.material
+        if (ma is not None) and (ma.grease_pencil is not None):
+            gpcolor = ma.grease_pencil
+
+            if self.layout_type in {'DEFAULT', 'COMPACT'}:
+                if gpcolor.lock:
+                    layout.active = False
+
+                row = layout.row(align=True)
+                row.enabled = not gpcolor.lock
+                row.prop(ma, "name", text="", emboss=False, icon_value=icon)
+
+                row = layout.row(align=True)
+                row.prop(gpcolor, "lock", text="", emboss=False)
+                row.prop(gpcolor, "hide", text="", emboss=False)
+                if gpcolor.ghost is True:
+                    icon = 'GHOST_DISABLED'
+                else:
+                    icon = 'GHOST_ENABLED'
+                row.prop(gpcolor, "ghost", text="", icon=icon, emboss=False)
+
+            elif self.layout_type == 'GRID':
+                layout.alignment = 'CENTER'
+                layout.label(text="", icon_value=icon)
+
+
+class GPMaterialButtonsPanel:
+    bl_space_type = 'PROPERTIES'
+    bl_region_type = 'WINDOW'
+    bl_context = "material"
+
+    @classmethod
+    def poll(cls, context):
+        ob = context.object
+        return (ob and ob.type == 'GPENCIL' and
+                ob.active_material and
+                ob.active_material.grease_pencil)
+
+
+
+class MATERIAL_PT_gpencil_slots(Panel):
+    bl_label = "Grease Pencil Material Slots"
+    bl_space_type = 'PROPERTIES'
+    bl_region_type = 'WINDOW'
+    bl_context = "material"
+    bl_options = {'HIDE_HEADER'}
+
+    @classmethod
+    def poll(cls, context):
+        ob = context.object
+        return ob and ob.type == 'GPENCIL'
+
+    @staticmethod
+    def draw(self, context):
+        layout = self.layout
+        gpd = context.gpencil_data
+
+        mat = context.object.active_material
+        ob = context.object
+        slot = context.material_slot
+        space = context.space_data
+
+        if ob:
+            is_sortable = len(ob.material_slots) > 1
+            rows = 1
+            if (is_sortable):
+                rows = 4
+
+            row = layout.row()
+
+            row.template_list("GPENCIL_UL_matslots", "", ob, "material_slots", ob, "active_material_index", rows=rows)
+
+            col = row.column(align=True)
+            col.operator("object.material_slot_add", icon='ZOOMIN', text="")
+            col.operator("object.material_slot_remove", icon='ZOOMOUT', text="")
+
+            col.menu("GPENCIL_MT_color_specials", icon='DOWNARROW_HLT', text="")
+
+            if is_sortable:
+                col.separator()
+
+                col.operator("object.material_slot_move", icon='TRIA_UP', text="").direction = 'UP'
+                col.operator("object.material_slot_move", icon='TRIA_DOWN', text="").direction = 'DOWN'
+
+                col.separator()
+
+                sub = col.column(align=True)
+                sub.operator("gpencil.color_isolate", icon='LOCKED', text="").affect_visibility = False
+                sub.operator("gpencil.color_isolate", icon='RESTRICT_VIEW_OFF', text="").affect_visibility = True
+
+        row = layout.row()
+
+        if ob:
+            row.template_ID(ob, "active_material", new="material.new", live_icon=True)
+
+            if slot:
+                icon_link = 'MESH_DATA' if slot.link == 'DATA' else 'OBJECT_DATA'
+                row.prop(slot, "link", icon=icon_link, icon_only=True)
+
+            if gpd.use_stroke_edit_mode:
+                row = layout.row(align=True)
+                row.operator("gpencil.stroke_change_color", text="Assign")
+                row.operator("gpencil.color_select", text="Select")
+
+        elif mat:
+            row.template_ID(space, "pin_id")
+
+
+# Used as parent for "Stroke" and "Fill" panels
+class MATERIAL_PT_gpencil_surface(GPMaterialButtonsPanel, Panel):
+    bl_label = "Surface"
+
+    @classmethod
+    def poll(cls, context):
+        ob = context.object
+        ma = context.object.active_material
+        if ma is None or ma.grease_pencil is None:
+            return False
+
+        return ob and ob.type == 'GPENCIL'
+
+    @staticmethod
+    def draw(self, context):
+        layout = self.layout
+        layout.use_property_split = True
+
+
+class MATERIAL_PT_gpencil_strokecolor(GPMaterialButtonsPanel, Panel):
+    bl_label = "Stroke"
+    bl_parent_id = 'MATERIAL_PT_gpencil_surface'
+
+    @staticmethod
+    def draw(self, context):
+        layout = self.layout
+        layout.use_property_split = True
+
+        ma = context.object.active_material
+        if ma is not None and ma.grease_pencil is not None:
+            gpcolor = ma.grease_pencil
+
+            col = layout.column()
+            col.active = not gpcolor.lock
+
+            col.prop(gpcolor, "mode")
+
+            col.prop(gpcolor, "stroke_style", text="Style")
+
+            if gpcolor.stroke_style == 'TEXTURE':
+                row = col.row()
+                row.enabled = not gpcolor.lock
+                col = row.column(align=True)
+                col.template_ID(gpcolor, "stroke_image", open="image.open")
+                col.prop(gpcolor, "pixel_size", text="UV Factor")
+                col.prop(gpcolor, "use_stroke_pattern", text="Use As Pattern")
+
+            if gpcolor.stroke_style == 'SOLID' or gpcolor.use_stroke_pattern is True:
+                col.prop(gpcolor, "color", text="Color")
+
+
+class MATERIAL_PT_gpencil_fillcolor(GPMaterialButtonsPanel, Panel):
+    bl_label = "Fill"
+    bl_parent_id = 'MATERIAL_PT_gpencil_surface'
+
+    @staticmethod
+    def draw(self, context):
+        layout = self.layout
+        layout.use_property_split = True
+
+        ma = context.object.active_material
+        if ma is not None and ma.grease_pencil:
+            gpcolor = ma.grease_pencil
+
+            # color settings
+            col = layout.column()
+            col.active = not gpcolor.lock
+            col.prop(gpcolor, "fill_style", text="Style")
+
+            if gpcolor.fill_style == 'GRADIENT':
+                col.prop(gpcolor, "gradient_type")
+
+            if gpcolor.fill_style != 'TEXTURE':
+                col.prop(gpcolor, "fill_color", text="Color")
+
+                if gpcolor.fill_style in ('GRADIENT', 'CHESSBOARD'):
+                    col.prop(gpcolor, "mix_color", text="Secondary Color")
+
+                if gpcolor.fill_style == 'GRADIENT':
+                    col.prop(gpcolor, "mix_factor", text="Mix Factor", slider=True)
+
+                if gpcolor.fill_style in ('GRADIENT', 'CHESSBOARD'):
+                    col.prop(gpcolor, "flip", text="Flip Colors")
+
+                    col.prop(gpcolor, "pattern_shift", text="Location")
+                    col.prop(gpcolor, "pattern_scale", text="Scale")
+
+                if gpcolor.gradient_type == 'RADIAL' and gpcolor.fill_style not in ('SOLID', 'CHESSBOARD'):
+                    col.prop(gpcolor, "pattern_radius", text="Radius")
+                else:
+                    if gpcolor.fill_style != 'SOLID':
+                        col.prop(gpcolor, "pattern_angle", text="Angle")
+
+                if gpcolor.fill_style == 'CHESSBOARD':
+                    col.prop(gpcolor, "pattern_gridsize", text="Box Size")
+
+            # Texture
+            if gpcolor.fill_style == 'TEXTURE' or (gpcolor.texture_mix is True and gpcolor.fill_style == 'SOLID'):
+                col.template_ID(gpcolor, "fill_image", open="image.open")
+
+                if gpcolor.fill_style == 'TEXTURE':
+                    col.prop(gpcolor, "use_fill_pattern", text="Use As Pattern")
+                    if gpcolor.use_fill_pattern is True:
+                        col.prop(gpcolor, "fill_color", text="Color")
+
+                col.prop(gpcolor, "texture_offset", text="Offset")
+                col.prop(gpcolor, "texture_scale", text="Scale")
+                col.prop(gpcolor, "texture_angle")
+                col.prop(gpcolor, "texture_opacity")
+                col.prop(gpcolor, "texture_clamp", text="Clip Image")
+
+                if gpcolor.use_fill_pattern is False:
+                    col.prop(gpcolor, "texture_mix", text="Mix With Color")
+
+                    if gpcolor.texture_mix is True:
+                        col.prop(gpcolor, "fill_color", text="Mix Color")
+                        col.prop(gpcolor, "mix_factor", text="Mix Factor", slider=True)
+
+
+class MATERIAL_PT_gpencil_preview(GPMaterialButtonsPanel, Panel):
+    bl_label = "Preview"
+    COMPAT_ENGINES = {'BLENDER_EEVEE'}
+    bl_options = {'DEFAULT_CLOSED'}
+
+    def draw(self, context):
+        ma = context.object.active_material
+        self.layout.label(ma.name)
+        self.layout.template_preview(ma)
+
+
+class MATERIAL_PT_gpencil_custom_props(GPMaterialButtonsPanel, PropertyPanel, Panel):
+    COMPAT_ENGINES = {'BLENDER_EEVEE', 'BLENDER_OPENGL'}
+    _context_path = "object.active_material"
+    _property_type = bpy.types.Material
+
+
+class MATERIAL_PT_gpencil_options(GPMaterialButtonsPanel, Panel):
+    bl_label = "Options"
+    bl_options = {'DEFAULT_CLOSED'}
+
+    @staticmethod
+    def draw(self, context):
+        layout = self.layout
+        layout.use_property_split = True
+
+        ma = context.object.active_material
+        if ma is not None and ma.grease_pencil is not None:
+            gpcolor = ma.grease_pencil
+            layout.prop(gpcolor, "pass_index")
+
+
+classes = (
+    GPENCIL_UL_matslots,
+    GPENCIL_MT_color_specials,
+    MATERIAL_PT_gpencil_slots,
+    MATERIAL_PT_gpencil_preview,
+    MATERIAL_PT_gpencil_surface,
+    MATERIAL_PT_gpencil_strokecolor,
+    MATERIAL_PT_gpencil_fillcolor,
+    MATERIAL_PT_gpencil_options,
+    MATERIAL_PT_gpencil_custom_props,
+)
+
+if __name__ == "__main__":  # only for live edit.
+    from bpy.utils import register_class
+    for cls in classes:
+        register_class(cls)
index 38bfc6a..91be9bb 100644 (file)
@@ -28,9 +28,9 @@ from rna_prop_ui import PropertyPanel
 from bl_operators.presets import PresetMenu
 
 from .properties_physics_common import (
-    point_cache_ui,
-    effector_weights_ui,
-)
+        point_cache_ui,
+        effector_weights_ui,
+        )
 
 
 class SCENE_PT_units_length_presets(PresetMenu):
@@ -104,7 +104,6 @@ class SCENE_PT_unit(SceneButtonsPanel, Panel):
         col.prop(unit, "scale_length")
         col.prop(unit, "use_separate")
 
-
 class SceneKeyingSetsPanel:
 
     @staticmethod
@@ -568,6 +567,33 @@ class SCENE_PT_simplify_render(SceneButtonsPanel, Panel):
         col.prop(rd, "simplify_child_particles_render", text="Max Child Particles")
 
 
+class SCENE_PT_simplify_greasepencil(SceneButtonsPanel, Panel):
+    bl_label = "Simplify Grease Pencil"
+    COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME', 'BLENDER_CLAY', 'BLENDER_EEVEE'}
+    bl_options = {'DEFAULT_CLOSED'}
+
+    def draw_header(self, context):
+        rd = context.scene.render
+        self.layout.prop(rd, "simplify_gpencil", text="")
+
+    def draw(self, context):
+        layout = self.layout
+
+        rd = context.scene.render
+
+        layout.active = rd.simplify_gpencil
+
+        row = layout.row()
+        row.prop(rd, "simplify_gpencil_onplay", text="Only on Play")
+
+        split = layout.split()
+
+        col = split.column()
+        col.prop(rd, "simplify_gpencil_view_fill", text="Fill")
+        col.prop(rd, "simplify_gpencil_remove_lines", text="Remove Fill Lines")
+        col.prop(rd, "simplify_gpencil_view_modifier", text="Modifiers")
+
+
 class SCENE_PT_custom_props(SceneButtonsPanel, PropertyPanel, Panel):
     COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'}
     _context_path = "scene"
@@ -593,6 +619,7 @@ classes = (
     SCENE_PT_simplify,
     SCENE_PT_simplify_viewport,
     SCENE_PT_simplify_render,
+    SCENE_PT_simplify_greasepencil,
     SCENE_PT_custom_props,
 )
 
index 23c3e97..8e32d98 100644 (file)
@@ -23,14 +23,8 @@ from bpy.types import Panel, Header, Menu, UIList
 from bpy.app.translations import pgettext_iface as iface_
 from bl_operators.presets import PresetMenu
 from .properties_grease_pencil_common import (
-    GreasePencilDrawingToolsPanel,
-    GreasePencilStrokeEditPanel,
-    GreasePencilStrokeSculptPanel,
-    GreasePencilBrushPanel,
-    GreasePencilBrushCurvesPanel,
-    GreasePencilDataPanel,
-    GreasePencilPaletteColorPanel,
-)
+        GreasePencilDrawingToolsPanel,
+        GreasePencilDataPanel)
 
 
 class CLIP_UL_tracking_objects(UIList):
@@ -1154,40 +1148,12 @@ class CLIP_PT_grease_pencil(GreasePencilDataPanel, CLIP_PT_clip_view_panel, Pane
     # But, this should only be visible in "clip" view
 
 
-# Grease Pencil palette colors
-class CLIP_PT_grease_pencil_palettecolor(GreasePencilPaletteColorPanel, CLIP_PT_clip_view_panel, Panel):
-    bl_space_type = 'CLIP_EDITOR'
-    bl_region_type = 'UI'
-    bl_options = {'DEFAULT_CLOSED'}
-
-    # NOTE: this is just a wrapper around the generic GP Panel
-    # But, this should only be visible in "clip" view
-
-
 # Grease Pencil drawing tools
 class CLIP_PT_tools_grease_pencil_draw(GreasePencilDrawingToolsPanel, Panel):
     bl_space_type = 'CLIP_EDITOR'
+    bl_region_type = 'TOOLS'
 
 
-# Grease Pencil stroke editing tools
-class CLIP_PT_tools_grease_pencil_edit(GreasePencilStrokeEditPanel, Panel):
-    bl_space_type = 'CLIP_EDITOR'
-
-
-# Grease Pencil stroke sculpting tools
-class CLIP_PT_tools_grease_pencil_sculpt(GreasePencilStrokeSculptPanel, Panel):
-    bl_space_type = 'CLIP_EDITOR'
-
-
-# Grease Pencil drawing brushes
-class CLIP_PT_tools_grease_pencil_brush(GreasePencilBrushPanel, Panel):
-    bl_space_type = 'CLIP_EDITOR'
-
-
-# Grease Pencil drawing curves
-class CLIP_PT_tools_grease_pencil_brushcurves(GreasePencilBrushCurvesPanel, Panel):
-    bl_space_type = 'CLIP_EDITOR'
-
 
 class CLIP_MT_view(Menu):
     bl_label = "View"
@@ -1515,12 +1481,7 @@ classes = (
     CLIP_PT_footage_info,
     CLIP_PT_tools_scenesetup,
     CLIP_PT_grease_pencil,
-    CLIP_PT_grease_pencil_palettecolor,
     CLIP_PT_tools_grease_pencil_draw,
-    CLIP_PT_tools_grease_pencil_edit,
-    CLIP_PT_tools_grease_pencil_sculpt,
-    CLIP_PT_tools_grease_pencil_brush,
-    CLIP_PT_tools_grease_pencil_brushcurves,
     CLIP_MT_view,
     CLIP_MT_clip,
     CLIP_MT_proxy,
index 1303e46..501f58e 100644 (file)
@@ -21,20 +21,15 @@ import bpy
 import math
 from bpy.types import Header, Menu, Panel, UIList
 from .properties_paint_common import (
-    UnifiedPaintPanel,
-    brush_texture_settings,
-    brush_texpaint_common,
-    brush_mask_texture_settings,
-)
+        UnifiedPaintPanel,
+        brush_texture_settings,
+        brush_texpaint_common,
+        brush_mask_texture_settings,
+        )
 from .properties_grease_pencil_common import (
-    GreasePencilDrawingToolsPanel,
-    GreasePencilStrokeEditPanel,
-    GreasePencilStrokeSculptPanel,
-    GreasePencilBrushPanel,
-    GreasePencilBrushCurvesPanel,
-    GreasePencilDataPanel,
-    GreasePencilPaletteColorPanel,
-)
+        GreasePencilDrawingToolsPanel,
+        GreasePencilDataPanel
+        )
 from bpy.app.translations import pgettext_iface as iface_
 
 
@@ -1346,39 +1341,12 @@ class IMAGE_PT_grease_pencil(GreasePencilDataPanel, Panel):
 
     # NOTE: this is just a wrapper around the generic GP Panel
 
-
-# Grease Pencil palette colors
-class IMAGE_PT_grease_pencil_palettecolor(GreasePencilPaletteColorPanel, Panel):
-    bl_space_type = 'IMAGE_EDITOR'
-    bl_region_type = 'UI'
-
-    # NOTE: this is just a wrapper around the generic GP Panel
-
-
 # Grease Pencil drawing tools
 class IMAGE_PT_tools_grease_pencil_draw(GreasePencilDrawingToolsPanel, Panel):
     bl_space_type = 'IMAGE_EDITOR'
+    bl_region_type = 'TOOLS'
 
 
-# Grease Pencil stroke editing tools
-class IMAGE_PT_tools_grease_pencil_edit(GreasePencilStrokeEditPanel, Panel):
-    bl_space_type = 'IMAGE_EDITOR'
-
-
-# Grease Pencil stroke sculpting tools
-class IMAGE_PT_tools_grease_pencil_sculpt(GreasePencilStrokeSculptPanel, Panel):
-    bl_space_type = 'IMAGE_EDITOR'
-
-
-# Grease Pencil drawing brushes
-class IMAGE_PT_tools_grease_pencil_brush(GreasePencilBrushPanel, Panel):
-    bl_space_type = 'IMAGE_EDITOR'
-
-
-# Grease Pencil drawing curves
-class IMAGE_PT_tools_grease_pencil_brushcurves(GreasePencilBrushCurvesPanel, Panel):
-    bl_space_type = 'IMAGE_EDITOR'
-
 
 classes = (
     IMAGE_MT_view,
@@ -1430,12 +1398,7 @@ classes = (
     IMAGE_PT_sample_line,
     IMAGE_PT_scope_sample,
     IMAGE_PT_grease_pencil,
-    IMAGE_PT_grease_pencil_palettecolor,
     IMAGE_PT_tools_grease_pencil_draw,
-    IMAGE_PT_tools_grease_pencil_edit,
-    IMAGE_PT_tools_grease_pencil_sculpt,
-    IMAGE_PT_tools_grease_pencil_brush,
-    IMAGE_PT_tools_grease_pencil_brushcurves,
 )
 
 if __name__ == "__main__":  # only for live edit.
index 45343c0..affbf70 100644 (file)
@@ -23,15 +23,10 @@ from bpy.types import Header, Menu, Panel
 from bpy.app.translations import pgettext_iface as iface_
 from bl_operators.presets import PresetMenu
 from .properties_grease_pencil_common import (
-    GreasePencilDrawingToolsPanel,
-    GreasePencilStrokeEditPanel,
-    GreasePencilStrokeSculptPanel,
-    GreasePencilBrushPanel,
-    GreasePencilBrushCurvesPanel,
-    GreasePencilDataPanel,
-    GreasePencilPaletteColorPanel,
-    GreasePencilToolsPanel
-)
+        GreasePencilDrawingToolsPanel,
+        GreasePencilDataPanel,
+        GreasePencilToolsPanel
+        )
 
 
 class NODE_HT_header(Header):
@@ -539,19 +534,6 @@ class NODE_PT_grease_pencil(GreasePencilDataPanel, Panel):
         return snode is not None and snode.node_tree is not None
 
 
-# Grease Pencil palette colors
-class NODE_PT_grease_pencil_palettecolor(GreasePencilPaletteColorPanel, Panel):
-    bl_space_type = 'NODE_EDITOR'
-    bl_region_type = 'UI'
-
-    # NOTE: this is just a wrapper around the generic GP Panel
-
-    @classmethod
-    def poll(cls, context):
-        snode = context.space_data
-        return snode is not None and snode.node_tree is not None
-
-
 class NODE_PT_grease_pencil_tools(GreasePencilToolsPanel, Panel):
     bl_space_type = 'NODE_EDITOR'
     bl_region_type = 'UI'
@@ -571,31 +553,6 @@ class NODE_PT_tools_grease_pencil_draw(GreasePencilDrawingToolsPanel, Panel):
     bl_region_type = 'TOOLS'
 
 
-# Grease Pencil stroke editing tools
-class NODE_PT_tools_grease_pencil_edit(GreasePencilStrokeEditPanel, Panel):
-    bl_space_type = 'NODE_EDITOR'
-    bl_region_type = 'TOOLS'
-
-
-# Grease Pencil stroke sculpting tools
-class NODE_PT_tools_grease_pencil_sculpt(GreasePencilStrokeSculptPanel, Panel):
-    bl_space_type = 'NODE_EDITOR'
-    bl_region_type = 'TOOLS'
-
-# Grease Pencil drawing brushes
-
-
-class NODE_PT_tools_grease_pencil_brush(GreasePencilBrushPanel, Panel):
-    bl_space_type = 'NODE_EDITOR'
-    bl_region_type = 'TOOLS'
-
-# Grease Pencil drawing curves
-
-
-class NODE_PT_tools_grease_pencil_brushcurves(GreasePencilBrushCurvesPanel, Panel):
-    bl_space_type = 'NODE_EDITOR'
-    bl_region_type = 'TOOLS'
-
 # -----------------------------
 
 
@@ -620,13 +577,8 @@ classes = (
     NODE_PT_quality,
     NODE_UL_interface_sockets,
     NODE_PT_grease_pencil,
-    NODE_PT_grease_pencil_palettecolor,
     NODE_PT_grease_pencil_tools,
     NODE_PT_tools_grease_pencil_draw,
-    NODE_PT_tools_grease_pencil_edit,
-    NODE_PT_tools_grease_pencil_sculpt,
-    NODE_PT_tools_grease_pencil_brush,
-    NODE_PT_tools_grease_pencil_brushcurves,
 )
 
 
index bac462d..84ae597 100644 (file)
@@ -22,7 +22,6 @@ from bpy.types import Header, Menu, Panel
 from rna_prop_ui import PropertyPanel
 from .properties_grease_pencil_common import (
     GreasePencilDataPanel,
-    GreasePencilPaletteColorPanel,
     GreasePencilToolsPanel,
 )
 from bpy.app.translations import pgettext_iface as iface_
@@ -1281,14 +1280,6 @@ class SEQUENCER_PT_grease_pencil(GreasePencilDataPanel, SequencerButtonsPanel_Ou
     # But, it should only show up when there are images in the preview region
 
 
-class SEQUENCER_PT_grease_pencil_palettecolor(GreasePencilPaletteColorPanel, SequencerButtonsPanel_Output, Panel):
-    bl_space_type = 'SEQUENCE_EDITOR'
-    bl_region_type = 'UI'
-
-    # 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'
@@ -1333,7 +1324,6 @@ classes = (
     SEQUENCER_PT_view_safe_areas,
     SEQUENCER_PT_modifiers,
     SEQUENCER_PT_grease_pencil,
-    SEQUENCER_PT_grease_pencil_palettecolor,
     SEQUENCER_PT_grease_pencil_tools,
     SEQUENCER_PT_custom_props,
 )
index 3101ffc..b682588 100644 (file)
@@ -24,6 +24,7 @@
 # For now keep this in a single file since it's an area that may change,
 # so avoid making changes all over the place.
 
+import bpy
 from bpy.types import Panel
 
 from .space_toolsystem_common import (
@@ -39,21 +40,77 @@ def generate_from_brushes_ex(
         brush_category_attr,
         brush_category_layout,
 ):
+    def draw_settings(context, layout, tool):
+        _defs_gpencil_paint.draw_settings_common(context, layout, tool)
+
     # Categories
     brush_categories = {}
-    for brush in context.blend_data.brushes:
-        if getattr(brush, brush_test_attr):
-            category = getattr(brush, brush_category_attr)
-            name = brush.name
-            brush_categories.setdefault(category, []).append(
-                ToolDef.from_dict(
-                    dict(
-                        text=name,
-                        icon=icon_prefix + category.lower(),
-                        data_block=name,
+    if context.mode != 'GPENCIL_PAINT':
+        for brush in context.blend_data.brushes:
+            if getattr(brush, brush_test_attr) and brush.gpencil_settings is None:
+                category = getattr(brush, brush_category_attr)
+                name = brush.name
+                brush_categories.setdefault(category, []).append(
+                    ToolDef.from_dict(
+                        dict(
+                            text=name,
+                            icon=icon_prefix + category.lower(),
+                            data_block=name,
+                        )
                     )
                 )
-            )
+    else:
+        for brush_type in brush_category_layout:
+            for brush in context.blend_data.brushes:
+                if getattr(brush, brush_test_attr) and brush.gpencil_settings.gp_icon == brush_type[0]:
+                    category = brush_type[0]
+                    name = brush.name
+
+                    # rename default brushes for tool bar
+                    if name.startswith("Draw "):
+                        text = name.replace("Draw ", "")
+                    elif name.startswith("Eraser "):
+                        text = name.replace("Eraser ", "")
+                    elif name.startswith("Fill "):
+                        text = name.replace(" Area", "")
+                    else:
+                        text = name
+
+                    # define icon
+                    gp_icon = brush.gpencil_settings.gp_icon
+                    if gp_icon == 'PENCIL':
+                        icon_name = 'draw_pencil'
+                    elif gp_icon == 'PEN':
+                        icon_name = 'draw_pen'
+                    elif gp_icon == 'INK':
+                        icon_name = 'draw_ink'
+                    elif gp_icon == 'INKNOISE':
+                        icon_name = 'draw_noise'
+                    elif gp_icon == 'BLOCK':
+                        icon_name = 'draw_block'
+                    elif gp_icon == 'MARKER':
+                        icon_name = 'draw_marker'
+                    elif gp_icon == 'FILL':
+                        icon_name = 'draw_fill'
+                    elif gp_icon == 'SOFT':
+                        icon_name = 'draw.eraser_soft'
+                    elif gp_icon == 'HARD':
+                        icon_name = 'draw.eraser_hard'
+                    elif gp_icon == 'STROKE':
+                        icon_name = 'draw.eraser_stroke'
+
+                    brush_categories.setdefault(category, []).append(
+                        ToolDef.from_dict(
+                            dict(
+                                text=text,
+                                icon=icon_prefix + icon_name,
+                                data_block=name,
+                                widget=None,
+                                operator="gpencil.draw",
+                                draw_settings=draw_settings,
+                            )
+                        )
+                    )
 
     def tools_from_brush_group(groups):
         assert(type(groups) is tuple)
@@ -61,6 +118,7 @@ def generate_from_brushes_ex(
             tool_defs = tuple(brush_categories.pop(groups[0], ()))
         else:
             tool_defs = tuple(item for g in groups for item in brush_categories.pop(g, ()))
+
         if len(tool_defs) > 1:
             return (tool_defs,)
         else:
@@ -125,6 +183,112 @@ class _defs_view3d_generic:
         )
 
 
+class _defs_annotate:
+    @classmethod
+    def draw_settings_common(cls, context, layout, tool):
+        user_prefs = context.user_preferences
+        ts = context.tool_settings
+
+        # XXX: These context checks are needed for layer-dependent settings,
+        # but this breaks for using topbar for 2D editor active tools, etc.
+        if type(context.gpencil_data_owner) is bpy.types.Object:
+            gpd = context.scene.grease_pencil
+        else:
+            gpd = context.gpencil_data
+
+        gpl = gpd.layers.active if gpd else None
+
+        if gpd and gpl:
+            layout.prop(gpd.layers, "active_note", text="")
+            layout.prop(gpl, "thickness", text="Thickness")
+        else:
+            layout.prop(user_prefs.edit, "grease_pencil_default_color", text="Color")
+            layout.prop(ts, "annotation_thickness", text="Thickness")
+
+        # For 3D view, show the stroke placement settings
+        # XXX: How to tell what editor the active tool comes from?
+        is_3d_view = True
+        if is_3d_view:
+            layout.separator()
+
+            row = layout.row(align=True)
+            row.prop(ts, "annotation_stroke_placement_view3d", text="Orientation")
+            if ts.gpencil_stroke_placement_view3d == 'CURSOR':
+                row.prop(ts.gpencil_sculpt, "lockaxis")
+            elif ts.gpencil_stroke_placement_view3d in {'SURFACE', 'STROKE'}:
+                row.prop(ts, "use_gpencil_stroke_endpoints")
+
+    @ToolDef.from_fn
+    def scribble():
+        def draw_settings(context, layout, tool):
+            _defs_annotate.draw_settings_common(context, layout, tool)
+
+        return dict(
+            text="Annotate",
+            icon="ops.gpencil.draw",
+            cursor='PAINT_BRUSH',
+            keymap=(
+                ("gpencil.annotate",
+                 dict(mode='DRAW', wait_for_input=False),
+                 dict(type='EVT_TWEAK_A', value='ANY')),
+            ),
+            draw_settings=draw_settings,
+        )
+
+    @ToolDef.from_fn
+    def line():
+        def draw_settings(context, layout, tool):
+            _defs_annotate.draw_settings_common(context, layout, tool)
+
+        return dict(
+            text="Draw Line",
+            icon="ops.gpencil.draw.line",
+            cursor='CROSSHAIR',
+            keymap=(
+                ("gpencil.annotate",
+                 dict(mode='DRAW_STRAIGHT', wait_for_input=False),
+                 dict(type='EVT_TWEAK_A', value='ANY')),
+            ),
+            draw_settings=draw_settings,
+        )
+
+    @ToolDef.from_fn
+    def poly():
+        def draw_settings(context, layout, tool):
+            _defs_annotate.draw_settings_common(context, layout, tool)
+
+        return dict(
+            text="Draw Polygon",
+            icon="ops.gpencil.draw.poly",
+            cursor='CROSSHAIR',
+            keymap=(
+                ("gpencil.annotate",
+                 dict(mode='DRAW_POLY', wait_for_input=False),
+                 dict(type='ACTIONMOUSE', value='PRESS')),
+            ),
+            draw_settings=draw_settings,
+        )
+
+    @ToolDef.from_fn
+    def eraser():
+        def draw_settings(context, layout, tool):
+            # TODO: Move this setting to toolsettings
+            user_prefs = context.user_preferences
+            layout.prop(user_prefs.edit, "grease_pencil_eraser_radius", text="Radius")
+
+        return dict(
+            text="Eraser",
+            icon="ops.gpencil.draw.eraser",
+            cursor='CROSSHAIR', # XXX: Always show brush circle when enabled
+            keymap=(
+                ("gpencil.annotate",
+                 dict(mode='ERASER', wait_for_input=False),
+                 dict(type='ACTIONMOUSE', value='PRESS')),
+            ),
+            draw_settings=draw_settings,
+        )
+
+
 class _defs_transform:
 
     @ToolDef.from_fn
@@ -865,6 +1029,331 @@ class _defs_uv_select:
             ),
         )
 
+class _defs_gpencil_paint:
+    @classmethod
+    def draw_color_selector(cls, context, layout):
+        brush = context.active_gpencil_brush
+        gp_settings = brush.gpencil_settings
+        ts = context.tool_settings
+        row = layout.row(align=True)
+        row.prop(ts, "use_gpencil_thumbnail_list", text="", icon="IMGDISPLAY")
+        if ts.use_gpencil_thumbnail_list is False:
+            row.template_ID(gp_settings, "material", live_icon=True)
+        else:
+            row.template_greasepencil_color(gp_settings, "material", rows=3, cols=8, scale=0.8)
+
+    @classmethod
+    def draw_settings_common(cls, context, layout, tool):
+        ob = context.active_object
+        if ob and ob.mode == 'GPENCIL_PAINT':
+            brush = context.active_gpencil_brush
+            gp_settings = brush.gpencil_settings
+            tool_settings= context.tool_settings
+
+            if gp_settings.gpencil_brush_type == 'ERASE':
+                row = layout.row()
+                row.prop(brush, "size", text="Radius")
+            elif gp_settings.gpencil_brush_type == 'FILL':
+                row = layout.row()
+                row.prop(gp_settings, "gpencil_fill_leak", text="Leak Size")
+                row.prop(brush, "size", text="Thickness")
+                row.prop(gp_settings, "gpencil_fill_simplyfy_level", text="Simplify")
+
+                _defs_gpencil_paint.draw_color_selector(context, layout)
+
+                row = layout.row(align=True)
+                row.prop(gp_settings, "gpencil_fill_draw_mode", text="")
+                row.prop(gp_settings, "gpencil_fill_show_boundary", text="", icon='GRID')
+
+            else:  # bgpsettings.gpencil_brush_type == 'DRAW':
+                row = layout.row(align=True)
+                row.prop(brush, "size", text="Radius")
+                row.prop(gp_settings, "use_pressure", text="", icon='STYLUS_PRESSURE')
+                row = layout.row(align=True)
+                row.prop(gp_settings, "pen_strength", slider=True)
+                row.prop(gp_settings, "use_strength_pressure", text="", icon='STYLUS_PRESSURE')
+
+                _defs_gpencil_paint.draw_color_selector(context, layout)
+
+
+    @staticmethod
+    def generate_from_brushes(context):
+        return generate_from_brushes_ex(
+            context,
+            icon_prefix="brush.gpencil.",
+            brush_test_attr="use_paint_grease_pencil",
+            brush_category_attr="grease_pencil_tool",
+            brush_category_layout=(
+                ('PENCIL',),
+                ('PEN',),
+                ('INK',),
+                ('INKNOISE',),
+                ('BLOCK',),
+                ('MARKER',),
+                ('FILL',),
+                ('SOFT',),
+                ('HARD',),
+                ('STROKE',),
+            )
+        )
+
+
+class _defs_gpencil_edit:
+    @ToolDef.from_fn
+    def bend():
+        return dict(
+            text="Bend",
+            icon="ops.gpencil.edit_bend",
+            widget=None,
+            keymap=(
+                ("transform.bend",
+                 dict(),
+                 dict(type='EVT_TWEAK_A', value='ANY')),
+            ),
+        )
+
+    @ToolDef.from_fn
+    def mirror():
+        return dict(
+            text="Mirror",
+            icon="ops.gpencil.edit_mirror",
+            widget=None,
+            keymap=(
+                ("transform.mirror",
+                 dict(),
+                 dict(type='EVT_TWEAK_A', value='ANY')),
+            ),
+        )
+
+    @ToolDef.from_fn
+    def shear():
+        return dict(
+            text="Shear",
+            icon="ops.gpencil.edit_shear",
+            widget=None,
+            keymap=(
+                ("transform.shear",
+                 dict(),
+                 dict(type='EVT_TWEAK_A', value='ANY')),
+            ),
+        )
+
+    @ToolDef.from_fn
+    def tosphere():
+        return dict(
+            text="To Sphere",
+            icon="ops.gpencil.edit_to_sphere",
+            widget=None,
+            keymap=(
+                ("transform.tosphere",
+                 dict(),
+                 dict(type='EVT_TWEAK_A', value='ANY')),
+            ),
+        )
+
+
+class _defs_gpencil_sculpt:
+    @classmethod
+    def draw_settings_common(cls, context, layout, tool):
+        ob = context.active_object
+        if ob and ob.mode == 'GPENCIL_SCULPT':
+            ts = context.tool_settings
+            settings = ts.gpencil_sculpt
+            brush = settings.brush
+
+            layout.prop(brush, "size", slider=True)
+
+            row = layout.row(align=True)
+            row.prop(brush, "strength", slider=True)
+            row.prop(brush, "use_pressure_strength", text="")
+            row.separator()
+            row.prop(ts.gpencil_sculpt, "use_select_mask", text="")
+
+    @ToolDef.from_fn
+    def smooth():
+        def draw_settings(context, layout, tool):
+            _defs_gpencil_sculpt.draw_settings_common(context, layout, tool)
+
+        return dict(
+            text="Smooth",
+            icon="ops.gpencil.sculpt_smooth",
+            widget=None,
+            keymap=(
+                ("gpencil.brush_paint",
+                 dict(mode='SMOOTH', wait_for_input=False),
+                 dict(type='EVT_TWEAK_A', value='ANY')),
+            ),
+            draw_settings=draw_settings,
+        )
+
+    @ToolDef.from_fn
+    def thickness():
+        def draw_settings(context, layout, tool):
+            _defs_gpencil_sculpt.draw_settings_common(context, layout, tool)
+
+        return dict(
+            text="Thickness",
+            icon="ops.gpencil.sculpt_thickness",
+            widget=None,
+            keymap=(
+                ("gpencil.brush_paint",
+                 dict(mode='THICKNESS', wait_for_input=False),
+                 dict(type='EVT_TWEAK_A', value='ANY')),
+            ),
+            draw_settings=draw_settings,
+        )
+
+    @ToolDef.from_fn
+    def strength():
+        def draw_settings(context, layout, tool):
+            _defs_gpencil_sculpt.draw_settings_common(context, layout, tool)
+
+        return dict(
+            text="Strength",
+            icon="ops.gpencil.sculpt_strength",
+            widget=None,
+            keymap=(
+                ("gpencil.brush_paint",
+                 dict(mode='STRENGTH', wait_for_input=False),
+                 dict(type='EVT_TWEAK_A', value='ANY')),
+            ),
+            draw_settings=draw_settings,
+        )
+
+    @ToolDef.from_fn
+    def grab():
+        def draw_settings(context, layout, tool):
+            _defs_gpencil_sculpt.draw_settings_common(context, layout, tool)
+
+        return dict(
+            text="Grab",
+            icon="ops.gpencil.sculpt_grab",
+            widget=None,
+            keymap=(
+                ("gpencil.brush_paint",
+                 dict(mode='GRAB', wait_for_input=False),
+                 dict(type='EVT_TWEAK_A', value='ANY')),
+            ),
+            draw_settings=draw_settings,
+        )
+
+    @ToolDef.from_fn
+    def push():
+        def draw_settings(context, layout, tool):
+            _defs_gpencil_sculpt.draw_settings_common(context, layout, tool)
+
+        return dict(
+            text="Push",
+            icon="ops.gpencil.sculpt_push",
+            widget=None,
+            keymap=(
+                ("gpencil.brush_paint",
+                 dict(mode='PUSH', wait_for_input=False),
+                 dict(type='EVT_TWEAK_A', value='ANY')),
+            ),
+            draw_settings=draw_settings,
+        )
+
+    @ToolDef.from_fn
+    def twist():
+        def draw_settings(context, layout, tool):
+            _defs_gpencil_sculpt.draw_settings_common(context, layout, tool)
+
+        return dict(
+            text="Twist",
+            icon="ops.gpencil.sculpt_twist",
+            widget=None,
+            keymap=(
+                ("gpencil.brush_paint",
+                 dict(mode='TWIST', wait_for_input=False),
+                 dict(type='EVT_TWEAK_A', value='ANY')),
+            ),
+            draw_settings=draw_settings,
+        )
+
+    @ToolDef.from_fn
+    def pinch():
+        def draw_settings(context, layout, tool):
+            _defs_gpencil_sculpt.draw_settings_common(context, layout, tool)
+
+        return dict(
+            text="Pinch",
+            icon="ops.gpencil.sculpt_pinch",
+            widget=None,
+            keymap=(
+                ("gpencil.brush_paint",
+                 dict(mode='PINCH', wait_for_input=False),
+                 dict(type='EVT_TWEAK_A', value='ANY')),
+            ),
+            draw_settings=draw_settings,
+        )
+
+    @ToolDef.from_fn
+    def randomize():
+        def draw_settings(context, layout, tool):
+            _defs_gpencil_sculpt.draw_settings_common(context, layout, tool)
+
+        return dict(
+            text="Randomize",
+            icon="ops.gpencil.sculpt_randomize",
+            widget=None,
+            keymap=(
+                ("gpencil.brush_paint",
+                 dict(mode='RANDOMIZE', wait_for_input=False),
+                 dict(type='EVT_TWEAK_A', value='ANY')),
+            ),
+            draw_settings=draw_settings,
+        )
+
+    @ToolDef.from_fn
+    def clone():
+        def draw_settings(context, layout, tool):
+            _defs_gpencil_sculpt.draw_settings_common(context, layout, tool)
+
+        return dict(
+            text="Clone",
+            icon="ops.gpencil.sculpt_clone",
+            widget=None,
+            keymap=(
+                ("gpencil.brush_paint",
+                 dict(mode='CLONE', wait_for_input=False),
+                 dict(type='EVT_TWEAK_A', value='ANY')),
+            ),
+            draw_settings=draw_settings,
+        )
+
+
+class _defs_gpencil_weight:
+    @classmethod
+    def draw_settings_common(cls, context, layout, tool):
+        ob = context.active_object
+        if ob and ob.mode == 'GPENCIL_WEIGHT':
+            settings = context.tool_settings.gpencil_sculpt
+            brush = settings.brush
+
+            layout.prop(brush, "size", slider=True)
+
+            row = layout.row(align=True)
+            row.prop(brush, "strength", slider=True)
+            row.prop(brush, "use_pressure_strength", text="")
+
+    @ToolDef.from_fn
+    def paint():
+        def draw_settings(context, layout, tool):
+            _defs_gpencil_weight.draw_settings_common(context, layout, tool)
+
+        return dict(
+            text="Draw",
+            icon="ops.gpencil.sculpt_weight",
+            widget=None,
+            keymap=(
+                ("gpencil.brush_paint",
+                 dict(mode='WEIGHT', wait_for_input=False),
+                 dict(type='EVT_TWEAK_A', value='ANY')),
+            ),
+            draw_settings=draw_settings,
+        )
+
 
 class IMAGE_PT_tools_active(ToolSelectPanelHelper, Panel):
     bl_space_type = 'IMAGE_EDITOR'
@@ -951,8 +1440,6 @@ class VIEW3D_PT_tools_active(ToolSelectPanelHelper, Panel):
             _defs_transform.scale,
             _defs_transform.scale_cage,
         ),
-        None,
-        _defs_view3d_generic.ruler,
     )
 
     _tools_select = (
@@ -963,6 +1450,16 @@ class VIEW3D_PT_tools_active(ToolSelectPanelHelper, Panel):
         ),
     )
 
+    _tools_annotate = (
+        (
+            _defs_annotate.scribble,
+            _defs_annotate.line,
+            _defs_annotate.poly,
+            _defs_annotate.eraser,
+        ),
+        _defs_view3d_generic.ruler,
+    )
+
     _tools = {
         None: [
             _defs_view3d_generic.cursor,
@@ -972,21 +1469,27 @@ class VIEW3D_PT_tools_active(ToolSelectPanelHelper, Panel):
             *_tools_select,
             None,
             *_tools_transform,
+            None,
+            *_tools_annotate,
         ],
         'POSE': [
             *_tools_select,
             *_tools_transform,
             None,
+            *_tools_annotate,
+            None,
             (
                 _defs_pose.breakdown,
                 _defs_pose.push,
                 _defs_pose.relax,
-            )
+            ),
         ],
         'EDIT_ARMATURE': [
             *_tools_select,
             None,
             *_tools_transform,
+            None,
+            *_tools_annotate,
             _defs_edit_armature.roll,
             (
                 _defs_edit_armature.bone_size,
@@ -996,13 +1499,15 @@ class VIEW3D_PT_tools_active(ToolSelectPanelHelper, Panel):
             (
                 _defs_edit_armature.extrude,
                 _defs_edit_armature.extrude_cursor,
-            )
+            ),
         ],
         'EDIT_MESH': [
             *_tools_select,
             None,
             *_tools_transform,
             None,
+            *_tools_annotate,
+            None,
             _defs_edit_mesh.cube_add,
             None,
             (
@@ -1047,6 +1552,8 @@ class VIEW3D_PT_tools_active(ToolSelectPanelHelper, Panel):
             None,
             *_tools_transform,
             None,
+            *_tools_annotate,
+            None,
             _defs_edit_curve.draw,
             _defs_edit_curve.extrude_cursor,
         ],
@@ -1075,6 +1582,33 @@ class VIEW3D_PT_tools_active(ToolSelectPanelHelper, Panel):
             None,
             _defs_weight_paint.gradient,
         ],
+        'GPENCIL_PAINT': [
+            _defs_gpencil_paint.generate_from_brushes,
+        ],
+        'GPENCIL_EDIT': [
+            *_tools_select,
+            None,
+            *_tools_transform,
+            None,
+            _defs_gpencil_edit.bend,
+            _defs_gpencil_edit.mirror,
+            _defs_gpencil_edit.shear,
+            _defs_gpencil_edit.tosphere,
+        ],
+        'GPENCIL_SCULPT': [
+            _defs_gpencil_sculpt.smooth,
+            _defs_gpencil_sculpt.thickness,
+            _defs_gpencil_sculpt.strength,
+            _defs_gpencil_sculpt.grab,
+            _defs_gpencil_sculpt.push,
+            _defs_gpencil_sculpt.twist,
+            _defs_gpencil_sculpt.pinch,
+            _defs_gpencil_sculpt.randomize,
+            _defs_gpencil_sculpt.clone,
+        ],
+        'GPENCIL_WEIGHT': [
+            _defs_gpencil_weight.paint,
+        ],
     }
 
 
index 55129aa..0d837ae 100644 (file)
@@ -128,6 +128,8 @@ class TOPBAR_HT_lower_bar(Header):
             pass
         elif mode == 'PARTICLE':
             layout.popover_group(space_type='PROPERTIES', region_type='WINDOW', context=".paint_common", category="")
+        elif mode == 'GPENCIL_PAINT':
+            layout.popover_group(space_type='PROPERTIES', region_type='WINDOW', context=".greasepencil_paint", category="")
 
     def draw_center(self, context):
         pass
@@ -165,6 +167,15 @@ class TOPBAR_HT_lower_bar(Header):
             layout.popover_group(space_type='PROPERTIES', region_type='WINDOW', context=".particlemode", category="")
         elif mode == 'OBJECT':
             layout.popover_group(space_type='PROPERTIES', region_type='WINDOW', context=".objectmode", category="")
+        elif mode == 'GPENCIL_PAINT':
+            layout.prop(context.tool_settings, "gpencil_stroke_placement_view3d", text='')
+            if context.tool_settings.gpencil_stroke_placement_view3d in ('ORIGIN', 'CURSOR'):
+                layout.prop(context.tool_settings.gpencil_sculpt, "lockaxis", text='')
+            layout.prop(context.tool_settings, "use_gpencil_draw_onback", text="", icon='ORTHO')
+            layout.prop(context.tool_settings, "use_gpencil_additive_drawing", text="", icon='FREEZE')
+
+        elif mode == 'GPENCIL_SCULPT':
+            layout.prop(context.tool_settings.gpencil_sculpt, "lockaxis", text='')
 
 
 class _draw_left_context_mode:
index 53aaff7..52d4640 100644 (file)
@@ -361,14 +361,16 @@ class USERPREF_PT_edit(Panel):
         row.separator()
 
         col = row.column()
-        col.label(text="Grease Pencil:")
+        col.label(text="Annotations:")
+        sub = col.row()
+        sub.prop(edit, "grease_pencil_default_color", text="Default Color")
         col.prop(edit, "grease_pencil_eraser_radius", text="Eraser Radius")
         col.separator()
+        col.label(text="Grease Pencil/Annotations:")
+        col.separator()
         col.prop(edit, "grease_pencil_manhattan_distance", text="Manhattan Distance")
         col.prop(edit, "grease_pencil_euclidean_distance", text="Euclidean Distance")
         col.separator()
-        col.prop(edit, "grease_pencil_default_color", text="Default Color")
-        col.separator()
         col.prop(edit, "use_grease_pencil_simplify_stroke", text="Simplify Stroke")
         col.separator()
         col.separator()
@@ -527,7 +529,10 @@ class USERPREF_PT_system(Panel):
         col.prop(system, "gpu_viewport_quality")
 
         col.separator()
+        col.label(text="Grease Pencil Options:")
+        col.prop(system, "gpencil_multi_sample", text="")
 
+        col.separator()
         col.label(text="Text Draw Options:")
         col.prop(system, "use_text_antialiasing")
         if system.use_text_antialiasing:
index aed5faf..eb595e9 100644 (file)
 # <pep8 compliant>
 import bpy
 from bpy.types import Header, Menu, Panel
-from .properties_grease_pencil_common import (
-    GreasePencilDataPanel,
-    GreasePencilPaletteColorPanel,
-)
 from .properties_paint_common import UnifiedPaintPanel
+from .properties_grease_pencil_common import GreasePencilDataPanel
 from bpy.app.translations import contexts as i18n_contexts
 
 
@@ -80,18 +77,40 @@ class VIEW3D_HT_header(Header):
             row.operator("pose.paste", text="", icon='PASTEDOWN').flipped = False
             row.operator("pose.paste", text="", icon='PASTEFLIPDOWN').flipped = True
 
-        # GPencil
-        if context.gpencil_data and context.gpencil_data.use_stroke_edit_mode:
-            row = layout.row(align=True)
-            row.operator("gpencil.copy", text="", icon='COPYDOWN')
-            row.operator("gpencil.paste", text="", icon='PASTEDOWN')
+        # Grease Pencil
+        if obj and obj.type == 'GPENCIL' and context.gpencil_data:
+            gpd = context.gpencil_data
 
-            # XXX: icon
-            layout.prop(context.gpencil_data, "use_onion_skinning", text="Onion Skins", icon='PARTICLE_PATH')
+            if gpd.is_stroke_paint_mode:
+                row = layout.row(align=True)
+                row.popover(
+                    panel="VIEW3D_PT_tools_grease_pencil_shapes",
+                    text="Shapes"
+                )
 
-            row = layout.row(align=True)
-            row.prop(tool_settings.gpencil_sculpt, "use_select_mask")
-            row.prop(tool_settings.gpencil_sculpt, "selection_alpha", slider=True)
+            if gpd.use_stroke_edit_mode or gpd.is_stroke_sculpt_mode or gpd.is_stroke_weight_mode:
+                row = layout.row(align=True)
+                row.prop(gpd, "use_multiedit", text="", icon="FORCE_HARMONIC")
+
+                sub = row.row(align=True)
+                sub.active = gpd.use_multiedit
+                sub.popover(
+                    panel="VIEW3D_PT_gpencil_multi_frame",
+                    text="Multiframe"
+                )
+
+            if gpd.use_stroke_edit_mode:
+                row = layout.row(align=True)
+                row.operator("gpencil.copy", text="", icon='COPYDOWN')
+                row.operator("gpencil.paste", text="", icon='PASTEDOWN')
+
+                row = layout.row(align=True)
+                row.prop(tool_settings.gpencil_sculpt, "use_select_mask", text="")
+
+                row.popover(
+                    panel="VIEW3D_PT_tools_grease_pencil_interpolate",
+                    text="Interpolate"
+                )
 
         VIEW3D_MT_editor_menus.draw_collapsible(context, layout)
 
@@ -101,7 +120,7 @@ class VIEW3D_HT_header(Header):
         scene = context.scene
 
         # Orientation
-        if object_mode in {'OBJECT', 'EDIT', 'POSE'}:
+        if object_mode in {'OBJECT', 'EDIT', 'POSE', 'GPENCIL_EDIT'}:
             orientation = scene.transform_orientation
             current_orientation = scene.current_orientation
 
@@ -126,7 +145,8 @@ class VIEW3D_HT_header(Header):
         if obj is None:
             show_snap = True
         else:
-            if object_mode not in {'SCULPT', 'VERTEX_PAINT', 'WEIGHT_PAINT', 'TEXTURE_PAINT'}:
+            if object_mode not in {'SCULPT', 'VERTEX_PAINT', 'WEIGHT_PAINT', 'TEXTURE_PAINT',
+                                   'GPENCIL_PAINT', 'GPENCIL_SCULPT', 'GPENCIL_WEIGHT'}:
                 show_snap = True
             else:
 
@@ -160,13 +180,15 @@ class VIEW3D_HT_header(Header):
 
         # Proportional editing
         if obj:
-            if context.gpencil_data and context.gpencil_data.use_stroke_edit_mode:
-                row = layout.row(align=True)
-                row.prop(tool_settings, "proportional_edit", icon_only=True)
+            gpd = context.gpencil_data
+            if gpd is not None:
+                if gpd.use_stroke_edit_mode or gpd.is_stroke_sculpt_mode:
+                    row = layout.row(align=True)
+                    row.prop(tool_settings, "proportional_edit", icon_only=True)
 
-                sub = row.row(align=True)
-                sub.active = tool_settings.proportional_edit != 'DISABLED'
-                sub.prop(tool_settings, "proportional_edit_falloff", icon_only=True)
+                    sub = row.row(align=True)
+                    sub.active = tool_settings.proportional_edit != 'DISABLED'
+                    sub.prop(tool_settings, "proportional_edit_falloff", icon_only=True)
 
             elif object_mode in {'EDIT', 'PARTICLE_EDIT'}:
                 row = layout.row(align=True)
@@ -190,7 +212,7 @@ class VIEW3D_HT_header(Header):
                 sub.prop(tool_settings, "proportional_edit_falloff", icon_only=True)
 
         # Pivot
-        if object_mode in {'OBJECT', 'EDIT', 'POSE'}:
+        if object_mode in {'OBJECT', 'EDIT', 'POSE', 'GPENCIL_EDIT', 'GPENCIL_SCULPT'}:
             pivot_point = tool_settings.transform_pivot_point
             act_pivot_point = bpy.types.ToolSettings.bl_rna.properties["transform_pivot_point"].enum_items[pivot_point]
             row = layout.row(align=True)
@@ -234,13 +256,14 @@ class VIEW3D_MT_editor_menus(Menu):
         obj = context.active_object
         mode_string = context.mode
         edit_object = context.edit_object
-        gp_edit = context.gpencil_data and context.gpencil_data.use_stroke_edit_mode
+        gp_edit = obj and obj.mode in {'GPENCIL_EDIT', 'GPENCIL_PAINT', 'GPENCIL_SCULPT', 'GPENCIL_WEIGHT'}
 
         layout.menu("VIEW3D_MT_view")
 
         # Select Menu
         if gp_edit:
-            layout.menu("VIEW3D_MT_select_gpencil")
+            if mode_string not in {'GPENCIL_PAINT', 'GPENCIL_WEIGHT'}:
+                layout.menu("VIEW3D_MT_select_gpencil")
         elif mode_string in {'PAINT_WEIGHT', 'PAINT_VERTEX', 'PAINT_TEXTURE'}:
             mesh = obj.data
             if mesh.use_paint_mask:
@@ -266,7 +289,15 @@ class VIEW3D_MT_editor_menus(Menu):
             layout.menu("INFO_MT_edit_armature_add", text="Add")
 
         if gp_edit:
-            layout.menu("VIEW3D_MT_edit_gpencil")
+            if obj and obj.mode == 'GPENCIL_PAINT':
+                layout.menu("VIEW3D_MT_paint_gpencil")
+            elif obj and obj.mode == 'GPENCIL_EDIT':
+                layout.menu("VIEW3D_MT_edit_gpencil")
+            elif obj and obj.mode == 'GPENCIL_SCULPT':
+                layout.menu("VIEW3D_MT_sculpt_gpencil")
+            elif obj and obj.mode == 'GPENCIL_WEIGHT':
+                layout.menu("VIEW3D_MT_weight_gpencil")
+
         elif edit_object:
             layout.menu("VIEW3D_MT_edit_%s" % edit_object.type.lower())
 
@@ -1194,6 +1225,7 @@ class VIEW3D_MT_select_gpencil(Menu):
         layout.separator()
 
         layout.operator("gpencil.select_linked", text="Linked")
+        layout.operator("gpencil.select_alternate")
         layout.operator_menu_enum("gpencil.select_grouped", "type", text="Grouped")
 
         layout.separator()
@@ -1454,6 +1486,7 @@ class INFO_MT_add(Menu):
         layout.menu("INFO_MT_armature_add", icon='OUTLINER_OB_ARMATURE')
         layout.operator("object.add", text="Lattice", icon='OUTLINER_OB_LATTICE').type = 'LATTICE'
         layout.operator_menu_enum("object.empty_add", "type", text="Empty", icon='OUTLINER_OB_EMPTY')
+        layout.operator_menu_enum("object.gpencil_add", "type", text="Grease Pencil", icon='OUTLINER_OB_GREASEPENCIL')
         layout.separator()
 
         layout.operator("object.speaker_add", text="Speaker", icon='OUTLINER_OB_SPEAKER')
@@ -3110,12 +3143,17 @@ class VIEW3D_MT_edit_gpencil_delete(Menu):
 
         layout.separator()
 
-        layout.operator("gpencil.dissolve")
+        layout.operator_enum("gpencil.dissolve", "type")
 
         layout.separator()
 
         layout.operator("gpencil.active_frames_delete_all")
 
+        layout.separator()
+
+        layout.operator("gpencil.frame_clean_fill", text="Clean Boundary Strokes").mode = 'ACTIVE'
+        layout.operator("gpencil.frame_clean_fill", text="Clean Boundary Strokes all Frames").mode = 'ALL'
+
 
 # Edit Curve
 # draw_curve is used by VIEW3D_MT_edit_curve and VIEW3D_MT_edit_surface
@@ -3476,11 +3514,34 @@ class VIEW3D_MT_edit_armature_delete(Menu):
         layout.operator("armature.dissolve", text="Dissolve")
 
 
-# ********** GPencil Stroke Edit menu **********
+# ********** Grease Pencil Stroke menus **********
+class VIEW3D_MT_gpencil_simplify(Menu):
+    bl_label = "Simplify"
+
+    def draw(self, context):
+        layout = self.layout
+        layout.operator("gpencil.stroke_simplify_fixed", text="Fixed")
+        layout.operator("gpencil.stroke_simplify", text="Adaptative")
+
+
+class VIEW3D_MT_paint_gpencil(Menu):
+    bl_label = "Strokes"
+
+    def draw(self, context):
+
+        layout = self.layout
+
+        layout.menu("VIEW3D_MT_gpencil_animation")
+        layout.menu("VIEW3D_MT_edit_gpencil_interpolate")
+
+        layout.separator()
+
+        layout.operator("gpencil.delete", text="Delete Frame").type = 'FRAME'
+        layout.operator("gpencil.active_frames_delete_all")
 
 
 class VIEW3D_MT_edit_gpencil(Menu):
-    bl_label = "GPencil"
+    bl_label = "Strokes"
 
     def draw(self, context):
         tool_settings = context.tool_settings
@@ -3488,53 +3549,126 @@ class VIEW3D_MT_edit_gpencil(Menu):
         layout = self.layout
 
         layout.menu("VIEW3D_MT_edit_gpencil_transform")
-        layout.operator("transform.mirror", text="Mirror")
+
+        layout.separator()
         layout.menu("GPENCIL_MT_snap")
 
         layout.separator()
 
-        layout.operator("gpencil.brush_paint", text="Sculpt Strokes").wait_for_input = True
-        layout.prop_menu_enum(tool_settings.gpencil_sculpt, "tool", text="Sculpt Brush")
+        layout.menu("VIEW3D_MT_gpencil_animation")
 
         layout.separator()
 
-        layout.menu("VIEW3D_MT_object_animation")   # NOTE: provides keyingset access...
         layout.menu("VIEW3D_MT_edit_gpencil_interpolate")
 
         layout.separator()
 
         layout.operator("gpencil.duplicate_move", text="Duplicate")
         layout.operator("gpencil.stroke_subdivide", text="Subdivide")
+        layout.menu("VIEW3D_MT_gpencil_simplify")
 
         layout.separator()
 
+        layout.operator_menu_enum("gpencil.stroke_separate", "mode", text="Separate...")
+        layout.operator("gpencil.stroke_split", text="Split")
         layout.operator_menu_enum("gpencil.stroke_join", "type", text="Join...")
         layout.operator("gpencil.stroke_flip", text="Flip Direction")
 
         layout.separator()
 
         layout.operator("gpencil.copy", text="Copy")
-        layout.operator("gpencil.paste", text="Paste")
+        layout.operator("gpencil.paste", text="Paste").type = 'COPY'
+        layout.operator("gpencil.paste", text="Paste & Merge").type = 'MERGE'
+
+        layout.separator()
+
+        layout.operator_menu_enum("gpencil.move_to_layer", "layer", text="Move to Layer")
+        layout.operator("gpencil.stroke_change_color", text="Change Color")
+        layout.operator_menu_enum("gpencil.stroke_arrange", "direction", text="Arrange Strokes...")
+
+        layout.separator()
+
+        layout.operator_menu_enum("gpencil.convert", "type", text="Convert to Geometry...")
+
+        layout.separator()
+
+        layout.menu("VIEW3D_MT_edit_gpencil_delete")
+        layout.operator("gpencil.stroke_cyclical_set", text="Toggle Cyclic").type = 'TOGGLE'
+
+        layout.separator()
+
+        layout.operator_menu_enum("gpencil.frame_clean_fill", text="Clean Boundary Strokes...", property="mode")
+
+
+class VIEW3D_MT_sculpt_gpencil(Menu):
+    bl_label = "Strokes"
+
+    def draw(self, context):
+        layout = self.layout
+
+        layout.menu("VIEW3D_MT_edit_gpencil_transform")
 
         layout.separator()
+        layout.menu("GPENCIL_MT_snap")
 
-        layout.operator("gpencil.reveal")
-        layout.operator("gpencil.hide", text="Show Active Layer Only").unselected = True
-        layout.operator("gpencil.hide", text="Hide Active Layer").unselected = False
+        layout.separator()
+
+        layout.operator("gpencil.duplicate_move", text="Duplicate")
+        layout.operator("gpencil.stroke_subdivide", text="Subdivide")
+        layout.menu("VIEW3D_MT_gpencil_simplify")
+
+        layout.separator()
+
+        layout.operator_menu_enum("gpencil.stroke_separate", "mode", text="Separate...")
+        layout.operator("gpencil.stroke_split", text="Split")
+        layout.operator_menu_enum("gpencil.stroke_join", "type", text="Join...")
+        layout.operator("gpencil.stroke_flip", text="Flip Direction")
+
+        layout.separator()
+
+        layout.operator("gpencil.copy", text="Copy")
+        layout.operator("gpencil.paste", text="Paste").type = 'COPY'
+        layout.operator("gpencil.paste", text="Paste & Merge").type = 'MERGE'
 
         layout.separator()
 
         layout.operator_menu_enum("gpencil.move_to_layer", "layer", text="Move to Layer")
-        layout.operator("gpencil.stroke_change_color", text="Move to Color")
+        layout.operator("gpencil.stroke_change_color", text="Change Color")
         layout.operator_menu_enum("gpencil.stroke_arrange", "direction", text="Arrange Strokes...")
 
         layout.separator()
 
         layout.operator_menu_enum("gpencil.convert", "type", text="Convert to Geometry...")
 
-        layout.separator()
 
-        layout.menu("VIEW3D_MT_edit_gpencil_delete")
+class VIEW3D_MT_weight_gpencil(Menu):
+    bl_label = "Weights"
+
+    def draw(self, context):
+        layout = self.layout
+
+        layout.operator("gpencil.vertex_group_invert", text="Invert")
+        layout.operator("gpencil.vertex_group_smooth", text="Smooth")
+
+
+class VIEW3D_MT_gpencil_animation(Menu):
+    bl_label = "Animation"
+
+    @classmethod
+    def poll(cls, context):
+        ob = context.active_object
+        return ob and ob.type == 'GPENCIL' and ob.mode != 'OBJECT'
+
+    @staticmethod
+    def draw(self, context):
+        layout = self.layout
+
+        layout.operator("gpencil.blank_frame_add")
+        layout.operator("gpencil.active_frames_delete_all", text="Delete Frame(s)")
+
+        layout.separator()
+        layout.operator("gpencil.frame_duplicate", text="Duplicate Active Frame")
+        layout.operator("gpencil.frame_duplicate", text="Duplicate All Layers").mode = 'ALL'
 
 
 class VIEW3D_MT_edit_gpencil_transform(Menu):
@@ -3595,20 +3729,6 @@ class VIEW3D_MT_view_pie(Menu):
 # ********** Panel **********
 
 
-class VIEW3D_PT_grease_pencil(GreasePencilDataPanel, Panel):
-    bl_space_type = 'VIEW_3D'
-    bl_region_type = 'UI'
-
-    # NOTE: this is just a wrapper around the generic GP Panel
-
-
-class VIEW3D_PT_grease_pencil_palettecolor(GreasePencilPaletteColorPanel, Panel):
-    bl_space_type = 'VIEW_3D'
-    bl_region_type = 'UI'
-
-    # NOTE: this is just a wrapper around the generic GP Panel
-
-
 class VIEW3D_PT_view3d_properties(Panel):
     bl_space_type = 'VIEW_3D'
     bl_region_type = 'UI'
@@ -3720,6 +3840,7 @@ class VIEW3D_PT_object_type_visibility(Panel):
             "armature",
             "lattice",
             "empty",
+                   "grease_pencil",
             "camera",
             "light",
             "light_probe",
@@ -4040,6 +4161,8 @@ class VIEW3D_PT_overlay_guides(Panel):
         if shading.type == 'MATERIAL':
             col.prop(overlay, "show_look_dev")
 
+        col.prop(overlay, "show_annotation", text="Annotations")
+
 
 class VIEW3D_PT_overlay_object(Panel):
     bl_space_type = 'VIEW_3D'
@@ -4578,6 +4701,60 @@ class VIEW3D_PT_transform_orientations(Panel):
             row.operator("transform.delete_orientation", text="", icon='X', emboss=False)
 
 
+class VIEW3D_PT_overlay_gpencil_options(Panel):
+    bl_space_type = 'VIEW_3D'
+    bl_region_type = 'HEADER'
+    bl_parent_id = 'VIEW3D_PT_overlay'
+    bl_label = ""
+
+    @classmethod
+    def poll(cls, context):
+        return context.object and context.object.type == 'GPENCIL'
+
+    def draw_header(self, context):
+        layout = self.layout
+        layout.label(text={
+            'GPENCIL_PAINT': "Draw Grease Pencil",
+            'GPENCIL_EDIT': "Edit Grease Pencil",
+            'GPENCIL_SCULPT': "Sculpt Grease Pencil",
+            'GPENCIL_WEIGHT': "Weight Grease Pencil",
+            'OBJECT': "Grease Pencil",
+        }[context.mode])
+
+    def draw(self, context):
+        layout = self.layout
+        view = context.space_data
+        overlay = view.overlay
+
+        layout.prop(overlay, "use_gpencil_onion_skin", text="Onion Skin")
+
+        col = layout.column()
+        row = col.row()
+        row.prop(overlay, "use_gpencil_paper", text="")
+        sub = row.row()
+        sub.active = overlay.use_gpencil_paper
+        sub.prop(overlay, "gpencil_paper_opacity", text="Fade 3D Objects", slider=True)
+
+        col = layout.column()
+        row = col.row()
+        row.prop(overlay, "use_gpencil_grid", text="")
+        sub = row.row()
+        sub.active = overlay.use_gpencil_grid
+        sub.prop(overlay, "gpencil_grid_opacity", text="Canvas Grid", slider=True)
+
+        if overlay.use_gpencil_grid:
+            row = layout.row(align=True)
+            row.prop(overlay, "gpencil_grid_scale")
+            col = row.column()
+            col.prop(overlay, "gpencil_grid_lines", text="Subdivisions")
+            col.prop(overlay, "gpencil_grid_axis")
+
+        if context.object.mode in {'GPENCIL_EDIT', 'GPENCIL_SCULPT', 'GPENCIL_WEIGHT'}:
+            layout.prop(overlay, "use_gpencil_edit_lines", text="Edit Lines")
+            layout.prop(overlay, "use_gpencil_multiedit_line_only", text="Show Edit Lines only in multiframe")
+            layout.prop(overlay, "vertex_opacity", text="Vertex Opacity", slider=True)
+
+
 class VIEW3D_PT_quad_view(Panel):
     bl_space_type = 'VIEW_3D'
     bl_region_type = 'UI'
@@ -4605,6 +4782,14 @@ class VIEW3D_PT_quad_view(Panel):
         row.prop(region, "use_box_clip")
 
 
+# Annotation properties
+class VIEW3D_PT_grease_pencil(GreasePencilDataPanel, Panel):
+    bl_space_type = 'VIEW_3D'
+    bl_region_type = 'UI'
+
+    # NOTE: this is just a wrapper around the generic GP Panel
+
+
 class VIEW3D_PT_view3d_stereo(Panel):
     bl_space_type = 'VIEW_3D'
     bl_region_type = 'UI'
@@ -4684,6 +4869,27 @@ class VIEW3D_PT_context_properties(Panel):
             rna_prop_ui.draw(self.layout, context, member, object, False)
 
 
+# Grease Pencil Object - Multiframe falloff tools
+class VIEW3D_PT_gpencil_multi_frame(Panel):
+    bl_space_type = 'VIEW_3D'
+    bl_region_type = 'HEADER'
+    bl_label = "Multi Frame"
+
+    @staticmethod
+    def draw(self, context):
+        gpd = context.gpencil_data
+        settings = context.tool_settings.gpencil_sculpt
+
+        layout = self.layout
+        col = layout.column(align=True)
+        col.prop(settings, "use_multiframe_falloff")
+
+        # Falloff curve
+        if gpd.use_multiedit and settings.use_multiframe_falloff:
+            layout.template_curve_mapping(settings, "multiframe_falloff_curve", brush=True)
+
+
+
 classes = (
     VIEW3D_HT_header,
     VIEW3D_MT_editor_menus,
@@ -4791,8 +4997,13 @@ classes = (
     VIEW3D_MT_edit_mesh_clean,
     VIEW3D_MT_edit_mesh_delete,
     VIEW3D_MT_edit_mesh_showhide,
+    VIEW3D_MT_paint_gpencil,
     VIEW3D_MT_edit_gpencil,
     VIEW3D_MT_edit_gpencil_delete,
+    VIEW3D_MT_sculpt_gpencil,
+    VIEW3D_MT_weight_gpencil,
+    VIEW3D_MT_gpencil_animation,
+    VIEW3D_MT_gpencil_simplify,
     VIEW3D_MT_edit_curve,
     VIEW3D_MT_edit_curve_ctrlpoints,
     VIEW3D_MT_edit_curve_segments,
@@ -4815,12 +5026,12 @@ classes = (
     VIEW3D_MT_edit_gpencil_interpolate,
     VIEW3D_MT_object_mode_pie,
     VIEW3D_MT_view_pie,
-    VIEW3D_PT_grease_pencil,
-    VIEW3D_PT_grease_pencil_palettecolor,
     VIEW3D_PT_view3d_properties,
     VIEW3D_PT_view3d_camera_lock,
     VIEW3D_PT_view3d_cursor,
     VIEW3D_PT_object_type_visibility,
+    VIEW3D_PT_grease_pencil,
+    VIEW3D_PT_gpencil_multi_frame,
     VIEW3D_PT_quad_view,
     VIEW3D_PT_view3d_stereo,
     VIEW3D_PT_shading,
@@ -4849,6 +5060,7 @@ classes = (
     VIEW3D_PT_pivot_point,
     VIEW3D_PT_snapping,
     VIEW3D_PT_transform_orientations,
+    VIEW3D_PT_overlay_gpencil_options,
     VIEW3D_PT_context_properties,
 )
 
index 87c6a38..70d8c40 100644 (file)
 import bpy
 from bpy.types import Menu, Panel, UIList
 from .properties_grease_pencil_common import (
-    GreasePencilDrawingToolsPanel,
-    GreasePencilStrokeEditPanel,
-    GreasePencilInterpolatePanel,
-    GreasePencilStrokeSculptPanel,
-    GreasePencilBrushPanel,
-    GreasePencilBrushCurvesPanel
-)
+        GreasePencilStrokeEditPanel,
+        GreasePencilStrokeSculptPanel,
+        GreasePencilAppearancePanel,
+        )
 from .properties_paint_common import (
-    UnifiedPaintPanel,
-    brush_texture_settings,
-    brush_texpaint_common,
-    brush_mask_texture_settings,
-)
+        UnifiedPaintPanel,
+        brush_texture_settings,
+        brush_texpaint_common,
+        brush_mask_texture_settings,
+        )
+from bl_operators.presets import PresetMenu
 
 
 class View3DPanel:
@@ -70,6 +68,12 @@ def draw_vpaint_symmetry(layout, vpaint):
     col.use_property_split = True
     col.prop(vpaint, "radial_symmetry", text="Radial")
 
+# Most of these panels should not be visible in GP edit modes
+def is_not_gpencil_edit_mode(context):
+    is_gpmode = context.active_object and \
+                context.active_object.mode in {'GPENCIL_EDIT', 'GPENCIL_PAINT', 'GPENCIL_SCULPT', 'GPENCIL_WEIGHT'}
+    return not is_gpmode
+
 
 # ********** default tools for editmode_mesh ****************
 
@@ -1341,9 +1345,272 @@ class VIEW3D_PT_tools_particlemode(View3DPanel, Panel):
             sub.prop(pe, "fade_frames", slider=True)
 
 
-# Grease Pencil drawing tools
-class VIEW3D_PT_tools_grease_pencil_draw(GreasePencilDrawingToolsPanel, Panel):
+# ********** grease pencil object tool panels ****************
+
+# Grease Pencil drawing brushes
+class VIEW3D_PT_tools_grease_pencil_brush(View3DPanel, Panel):
+    bl_context = ".greasepencil_paint"
+    bl_label = "Brush"
+
+    @classmethod
+    def poll(cls, context):
+        is_3d_view = context.space_data.type == 'VIEW_3D'
+        if is_3d_view:
+            if context.gpencil_data is None:
+                return False
+
+            gpd = context.gpencil_data
+            return bool(gpd.is_stroke_paint_mode)
+        else:
+            return True
+
+    @staticmethod
+    def draw(self, context):
+        layout = self.layout
+        layout.use_property_split = True
+        layout.use_property_decorate = False
+
+        ts = context.scene.tool_settings
+        settings = ts.gpencil_paint
+
+        row = layout.row()
+        col = row.column()
+        col.template_ID_preview(settings, "brush", new="brush.add_gpencil", rows=3, cols=8)
+
+        col = row.column()
+        brush = context.active_gpencil_brush
+        gp_settings = brush.gpencil_settings
+
+        sub = col.column(align=True)
+        sub.operator("gpencil.brush_presets_create", icon='HELP', text="")
+
+        if brush is not None:
+            # XXX: Items in "sub" currently show up beside the brush selector in a separate column
+            if gp_settings.gpencil_brush_type == 'ERASE':
+                sub.prop(gp_settings, "default_eraser", text="")
+
+            # Brush details
+            if gp_settings.gpencil_brush_type == 'ERASE':
+                col = layout.column(align=True)
+                col.prop(brush, "size", text="Radius")
+
+                col.separator()
+                row = col.row()
+                row.prop(gp_settings, "eraser_mode", expand=True)
+            elif gp_settings.gpencil_brush_type == 'FILL':
+                col = layout.column(align=True)
+                col.prop(gp_settings, "gpencil_fill_leak", text="Leak Size")
+                col.prop(brush, "size", text="Thickness")
+                col.prop(gp_settings, "gpencil_fill_simplyfy_level", text="Simplify")
+
+                col = layout.row(align=True)
+                col.template_ID(gp_settings, "material")
+
+                row = layout.row(align=True)
+                row.prop(gp_settings, "gpencil_fill_draw_mode", text="Boundary Draw Mode")
+                row.prop(gp_settings, "gpencil_fill_show_boundary", text="", icon='GRID')
+
+                col = layout.column(align=True)
+                col.enabled = gp_settings.gpencil_fill_draw_mode != "STROKE"
+                col.prop(gp_settings, "gpencil_fill_hide", text="Hide Transparent Lines")
+                sub = col.row(align=True)
+                sub.enabled = gp_settings.gpencil_fill_hide
+                sub.prop(gp_settings, "gpencil_fill_threshold", text="Threshold")
+            else:  # bgpsettings.gpencil_brush_type == 'DRAW':
+                row = layout.row(align=True)
+                row.prop(brush, "size", text="Radius")
+                row.prop(gp_settings, "use_pressure", text="", icon='STYLUS_PRESSURE')
+                row = layout.row(align=True)
+                row.prop(gp_settings, "pen_strength", slider=True)
+                row.prop(gp_settings, "use_strength_pressure", text="", icon='STYLUS_PRESSURE')
+
+                row = layout.row(align=True)
+                row.template_ID(gp_settings, "material")
+
+
+# Grease Pencil drawing brushes options
+class VIEW3D_PT_tools_grease_pencil_brush_option(View3DPanel, Panel):
+    bl_context = ".greasepencil_paint"
+    bl_label = "Options"
+    bl_options = {'DEFAULT_CLOSED'}
+
+    def draw_header_preset(self, context):
+        VIEW3D_PT_gpencil_brush_presets.draw_panel_header(self.layout)
+
+    @staticmethod
+    def draw(self, context):
+        layout = self.layout
+        layout.use_property_split = True
+        layout.use_property_decorate = False
+
+        brush = context.active_gpencil_brush
+        gp_settings = brush.gpencil_settings
+
+        if brush is not None:
+            col = layout.column(align=True)
+            col.prop(gp_settings, "input_samples")
+            col.separator()
+
+            col.prop(gp_settings, "active_smooth_factor")
+            col.separator()
+
+            col.prop(gp_settings, "angle", slider=True)
+            col.prop(gp_settings, "angle_factor", text="Factor", slider=True)
+            col.separator()
+
+
+class VIEW3D_PT_tools_grease_pencil_brush_stabilizer(View3DPanel, Panel):
+    bl_context = ".greasepencil_paint"
+    bl_parent_id = 'VIEW3D_PT_tools_grease_pencil_brush_option'
+    bl_label = "Stabilizer"
+    bl_options = {'DEFAULT_CLOSED'}
+
+    @classmethod
+    def poll(cls, context):
+        brush = context.active_gpencil_brush
+        gp_settings = brush.gpencil_settings
+
+        return brush is not None and gp_settings.gpencil_brush_type == 'DRAW'
+
+    def draw_header(self, context):
+        brush = context.active_gpencil_brush
+        gp_settings = brush.gpencil_settings
+        self.layout.prop(gp_settings, "use_stabilizer", text="")
+
+    @staticmethod
+    def draw(self, context):
+        layout = self.layout
+        layout.use_property_split = True
+        layout.use_property_decorate = False
+
+        brush = context.active_gpencil_brush
+        gp_settings = brush.gpencil_settings
+        layout.active = gp_settings.use_stabilizer
+
+        layout.prop(brush, "smooth_stroke_radius", text="Radius", slider=True)
+        layout.prop(brush, "smooth_stroke_factor", text="Factor", slider=True)
+
+
+class VIEW3D_PT_tools_grease_pencil_brush_settings(View3DPanel, Panel):
+    bl_context = ".greasepencil_paint"
+    bl_parent_id = 'VIEW3D_PT_tools_grease_pencil_brush_option'
+    bl_label = "Post-processing Settings"
+    bl_options = {'DEFAULT_CLOSED'}
+
+    @classmethod
+    def poll(cls, context):
+        brush = context.active_gpencil_brush
+
+        return brush is not None
+
+    def draw_header(self, context):
+        brush = context.active_gpencil_brush
+        gp_settings = brush.gpencil_settings
+        self.layout.prop(gp_settings, "enable_settings", text="")
+
+    @staticmethod
+    def draw(self, context):
+        layout = self.layout
+        layout.use_property_split = True
+        layout.use_property_decorate = False
+
+        brush = context.active_gpencil_brush
+        gp_settings = brush.gpencil_settings
+        layout.active = gp_settings.enable_settings
+
+        layout.prop(gp_settings, "pen_smooth_factor")
+        layout.prop(gp_settings, "pen_smooth_steps")
+
+        layout.prop(gp_settings, "pen_thick_smooth_factor")
+        layout.prop(gp_settings, "pen_thick_smooth_steps")
+
+        layout.prop(gp_settings, "pen_subdivision_steps")
+        layout.prop(gp_settings, "random_subdiv", text="Randomness", slider=True)
+
+
+class VIEW3D_PT_tools_grease_pencil_brush_random(View3DPanel, Panel):
+    bl_context = ".greasepencil_paint"
+    bl_parent_id = 'VIEW3D_PT_tools_grease_pencil_brush_option'
+    bl_label = "Random Settings"
+    bl_options = {'DEFAULT_CLOSED'}
+
+    @classmethod
+    def poll(cls, context):
+        brush = context.active_gpencil_brush
+
+        return brush is not None
+
+    def draw_header(self, context):
+        brush = context.active_gpencil_brush
+        gp_settings = brush.gpencil_settings
+        self.layout.prop(gp_settings, "enable_random", text="")
+
+    @staticmethod
+    def draw(self, context):
+        layout = self.layout
+        layout.use_property_split = True
+        layout.use_property_decorate = False
+
+        brush = context.active_gpencil_brush
+        gp_settings = brush.gpencil_settings
+        layout.active = gp_settings.enable_random
+
+        layout.prop(gp_settings, "random_pressure", text="Pressure", slider=True)
+        layout.prop(gp_settings, "random_strength", text="Strength", slider=True)
+        layout.prop(gp_settings, "uv_random", text="UV", slider=True)
+
+        row = layout.row(align=True)
+        row.prop(gp_settings, "pen_jitter", slider=True)
+        row.prop(gp_settings, "use_jitter_pressure", text="", icon='STYLUS_PRESSURE')
+
+
+# Grease Pencil drawingcurves
+class VIEW3D_PT_tools_grease_pencil_brushcurves(View3DPanel, Panel):
+    bl_context = ".greasepencil_paint"
+    bl_label = "Curves"
+    bl_options = {'DEFAULT_CLOSED'}
+
+    @staticmethod
+    def draw(self, context):
+        layout = self.layout
+        layout.use_property_split = True
+
+        brush = context.active_gpencil_brush
+        gp_settings = brush.gpencil_settings
+
+        # Brush
+        layout.label("Sensitivity")
+        layout.template_curve_mapping(gp_settings, "curve_sensitivity", brush=True)
+
+        layout.label("Strength")
+        layout.template_curve_mapping(gp_settings, "curve_strength", brush=True)
+
+        layout.label("Jitter")
+        layout.template_curve_mapping(gp_settings, "curve_jitter", brush=True)
+
+
+# Grease Pencil create shapes
+class VIEW3D_PT_tools_grease_pencil_shapes(View3DPanel, Panel):
     bl_space_type = 'VIEW_3D'
+    bl_region_type = 'HEADER'
+    bl_label = "Shapes"
+
+    @classmethod
+    def poll(cls, context):
+        ob = context.active_object
+        return ob and ob.type == 'GPENCIL'
+
+    @staticmethod
+    def draw(self, context):
+        layout = self.layout
+        layout.use_property_split = True
+
+        col = layout.column(align=True)
+        col.operator("gpencil.primitive", text="Line", icon='IPO_CONSTANT').type = 'LINE'
+        col.operator("gpencil.primitive", text="Rectangle", icon='UV_FACESEL').type = 'BOX'
+        col.operator("gpencil.primitive", text="Circle", icon='ANTIALIASED').type = 'CIRCLE'
+
+        layout.operator("object.gpencil_add", text="Monkey", icon='MONKEY').type = 'MONKEY'
 
 
 # Grease Pencil stroke editing tools
@@ -1352,24 +1619,109 @@ class VIEW3D_PT_tools_grease_pencil_edit(GreasePencilStrokeEditPanel, Panel):
 
 
 # Grease Pencil stroke interpolation tools
-class VIEW3D_PT_tools_grease_pencil_interpolate(GreasePencilInterpolatePanel, Panel):
+class VIEW3D_PT_tools_grease_pencil_interpolate(Panel):
     bl_space_type = 'VIEW_3D'
+    bl_region_type = 'HEADER'
+    bl_label = "Interpolate"
+
+    @classmethod
+    def poll(cls, context):
+        if context.gpencil_data is None:
+            return False
+
+        gpd = context.gpencil_data
+        return bool(context.editable_gpencil_strokes) and bool(gpd.use_stroke_edit_mode)
+
+    @staticmethod
+    def draw(self, context):
+        layout = self.layout
+        settings = context.tool_settings.gpencil_interpolate
+
+        col = layout.column(align=True)
+        col.label("Interpolate Strokes")
+        col.operator("gpencil.interpolate", text="Interpolate")
+        col.operator("gpencil.interpolate_sequence", text="Sequence")
+        col.operator("gpencil.interpolate_reverse", text="Remove Breakdowns")
+
+        col = layout.column(align=True)
+        col.label(text="Options:")
+        col.prop(settings, "interpolate_all_layers")
+        col.prop(settings, "interpolate_selected_only")
+
+        col = layout.column(align=True)
+        col.label(text="Sequence Options:")
+        col.prop(settings, "type")
+        if settings.type == 'CUSTOM':
+            # TODO: Options for loading/saving curve presets?
+            col.template_curve_mapping(settings, "interpolation_curve", brush=True)
+        elif settings.type != 'LINEAR':
+            col.prop(settings, "easing")
+
+            if settings.type == 'BACK':
+                layout.prop(settings, "back")
+            elif setting.type == 'ELASTIC':
+                sub = layout.column(align=True)
+                sub.prop(settings, "amplitude")
+                sub.prop(settings, "period")
 
 
 # Grease Pencil stroke sculpting tools
-class VIEW3D_PT_tools_grease_pencil_sculpt(GreasePencilStrokeSculptPanel, Panel):
-    bl_space_type = 'VIEW_3D'
+class VIEW3D_PT_tools_grease_pencil_sculpt(GreasePencilStrokeSculptPanel, View3DPanel, Panel):
+    bl_context = ".greasepencil_sculpt"
+    bl_category = "Tools"
+    bl_label = "Sculpt Strokes"
 
 
-# Grease Pencil drawing brushes
-class VIEW3D_PT_tools_grease_pencil_brush(GreasePencilBrushPanel, Panel):
-    bl_space_type = 'VIEW_3D'
+# Grease Pencil weight painting tools
+class VIEW3D_PT_tools_grease_pencil_weight_paint(View3DPanel, Panel):
+    bl_context = ".greasepencil_weight"
+    bl_category = "Tools"
+    bl_label = "Weight Paint"
 
-# Grease Pencil drawingcurves
+    @staticmethod
+    def draw(self, context):
+        layout = self.layout
+        layout.use_property_split = True
+        layout.use_property_decorate = False
 
+        gpd = context.gpencil_data
+        settings = context.tool_settings.gpencil_sculpt
+        tool = settings.tool
+        brush = settings.brush
 
-class VIEW3D_PT_tools_grease_pencil_brushcurves(GreasePencilBrushCurvesPanel, Panel):
-    bl_space_type = 'VIEW_3D'
+        layout.template_icon_view(settings, "weight_tool", show_labels=True)
+
+        col = layout.column()
+        col.prop(brush, "size", slider=True)
+        row = col.row(align=True)
+        row.prop(brush, "strength", slider=True)
+        row.prop(brush, "use_pressure_strength", text="")
+
+        col.prop(brush, "use_falloff")
+
+
+# Grease Pencil Brush Appeareance (one for each mode)
+class VIEW3D_PT_tools_grease_pencil_paint_appearance(GreasePencilAppearancePanel, View3DPanel, Panel):
+    bl_context = ".greasepencil_paint"
+    bl_label = "Appearance"
+
+
+class VIEW3D_PT_tools_grease_pencil_sculpt_appearance(GreasePencilAppearancePanel, View3DPanel, Panel):
+    bl_context = ".greasepencil_sculpt"
+    bl_label = "Appearance"
+
+
+class VIEW3D_PT_tools_grease_pencil_weight_appearance(GreasePencilAppearancePanel, View3DPanel, Panel):
+    bl_context = ".greasepencil_weight"
+    bl_label = "Appearance"
+
+
+class VIEW3D_PT_gpencil_brush_presets(PresetMenu):
+    """Brush settings"""
+    bl_label = "Brush Presets"
+    preset_subdir = "gpencil_brush"
+    preset_operator = "script.execute_preset"
+    preset_add_operator = "scene.gpencil_brush_preset_add"
 
 
 classes = (
@@ -1401,12 +1753,21 @@ classes = (
     VIEW3D_PT_tools_projectpaint,
     VIEW3D_MT_tools_projectpaint_stencil,
     VIEW3D_PT_tools_particlemode,
-    VIEW3D_PT_tools_grease_pencil_draw,
-    VIEW3D_PT_tools_grease_pencil_edit,
-    VIEW3D_PT_tools_grease_pencil_interpolate,
-    VIEW3D_PT_tools_grease_pencil_sculpt,
+
+    VIEW3D_PT_gpencil_brush_presets,
     VIEW3D_PT_tools_grease_pencil_brush,
+    VIEW3D_PT_tools_grease_pencil_brush_option,
+    VIEW3D_PT_tools_grease_pencil_brush_settings,
+    VIEW3D_PT_tools_grease_pencil_brush_stabilizer,
+    VIEW3D_PT_tools_grease_pencil_brush_random,
     VIEW3D_PT_tools_grease_pencil_brushcurves,
+    VIEW3D_PT_tools_grease_pencil_shapes,
+    VIEW3D_PT_tools_grease_pencil_sculpt,
+    VIEW3D_PT_tools_grease_pencil_weight_paint,
+    VIEW3D_PT_tools_grease_pencil_paint_appearance,
+    VIEW3D_PT_tools_grease_pencil_sculpt_appearance,
+    VIEW3D_PT_tools_grease_pencil_weight_appearance,
+    VIEW3D_PT_tools_grease_pencil_interpolate,
 )
 
 if __name__ == "__main__":  # only for live edit.
index 5709ac7..2c9b1ef 100644 (file)
@@ -44,7 +44,9 @@ set(SRC_DNA_INC
        ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_fileglobal_types.h
        ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_freestyle_types.h
        ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_genfile.h
+       ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_gpencil_modifier_types.h
        ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_gpencil_types.h
+       ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_shader_fx_types.h
        ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_gpu_types.h
        ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_group_types.h
        ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_image_types.h
@@ -112,6 +114,8 @@ add_subdirectory(gpu)
 add_subdirectory(imbuf)
 add_subdirectory(nodes)
 add_subdirectory(modifiers)
+add_subdirectory(gpencil_modifiers)
+add_subdirectory(shader_fx)
 add_subdirectory(makesdna)
 add_subdirectory(makesrna)
 
index eda1c51..489746c 100644 (file)
  */
 
 enum eCurveMappingPreset;
+struct bContext;
 struct Brush;
+struct Paint;
 struct ImBuf;
 struct ImagePool;
 struct Main;
 struct Scene;
+struct ToolSettings;
 struct UnifiedPaintSettings;
 // enum eCurveMappingPreset;
 
@@ -45,14 +48,17 @@ void BKE_brush_system_exit(void);
 /* datablock functions */
 void BKE_brush_init(struct Brush *brush);
 struct Brush *BKE_brush_add(struct Main *bmain, const char *name, const eObjectMode ob_mode);
+struct Brush *BKE_brush_add_gpencil(struct Main *bmain, struct ToolSettings *ts, const char *name);
 struct Brush *BKE_brush_first_search(struct Main *bmain, const eObjectMode ob_mode);
 void BKE_brush_copy_data(struct Main *bmain, struct Brush *brush_dst, const struct Brush *brush_src, const int flag);
 struct Brush *BKE_brush_copy(struct Main *bmain, const struct Brush *brush);
 void BKE_brush_make_local(struct Main *bmain, struct Brush *brush, const bool lib_local);
-void BKE_brush_unlink(struct Main *bmain, struct Brush *brush);
 void BKE_brush_free(struct Brush *brush);
 
 void BKE_brush_sculpt_reset(struct Brush *brush);
+void BKE_brush_gpencil_presets(struct bContext *C);
+struct Brush *BKE_brush_getactive_gpencil(struct ToolSettings *ts);
+struct Paint *BKE_brush_get_gpencil_paint(struct ToolSettings *ts);
 
 /* image icon function */
 struct ImBuf *get_brush_icon(struct Brush *brush);
index 9f57859..28dcf9c 100644 (file)
@@ -65,9 +65,7 @@ struct bPoseChannel;
 struct bGPdata;
 struct bGPDlayer;
 struct bGPDframe;
-struct bGPDpalette;
-struct bGPDpalettecolor;
-struct bGPDbrush;
+struct Brush;
 struct wmWindow;
 struct wmWindowManager;
 struct RenderEngineType;
@@ -120,6 +118,10 @@ enum {
        CTX_MODE_PAINT_TEXTURE,
        CTX_MODE_PARTICLE,
        CTX_MODE_OBJECT,
+       CTX_MODE_GPENCIL_PAINT,
+       CTX_MODE_GPENCIL_EDIT,
+       CTX_MODE_GPENCIL_SCULPT,
+       CTX_MODE_GPENCIL_WEIGHT,
        CTX_MODE_NUM /* must be last */
 };
 
@@ -313,9 +315,7 @@ int CTX_data_visible_pose_bones(const bContext *C, ListBase *list);
 struct bGPdata *CTX_data_gpencil_data(const bContext *C);
 struct bGPDlayer *CTX_data_active_gpencil_layer(const bContext *C);
 struct bGPDframe *CTX_data_active_gpencil_frame(const bContext *C);
-struct bGPDpalette *CTX_data_active_gpencil_palette(const bContext *C);
-struct bGPDpalettecolor *CTX_data_active_gpencil_palettecolor(const bContext *C);
-struct bGPDbrush *CTX_data_active_gpencil_brush(const bContext *C);
+struct Brush *CTX_data_active_gpencil_brush(const bContext *C);
 int CTX_data_visible_gpencil_layers(const bContext *C, ListBase *list);
 int CTX_data_editable_gpencil_layers(const bContext *C, ListBase *list);
 int CTX_data_editable_gpencil_strokes(const bContext *C, ListBase *list);
index 3a951b7..887a7f4 100644 (file)
  *  \author Joshua Leung
  */
 
+struct CurveMapping;
+struct Depsgraph;
+struct GpencilModifierData;
 struct ToolSettings;
 struct ListBase;
 struct bGPdata;
 struct bGPDlayer;
 struct bGPDframe;
+struct bGPDspoint;
 struct bGPDstroke;
+struct Material;
 struct bGPDpalette;
 struct bGPDpalettecolor;
 struct Main;
+struct BoundBox;
+struct Brush;
+struct Object;
+struct bDeformGroup;
+struct SimplifyGpencilModifierData;
+struct InstanceGpencilModifierData;
+struct LatticeGpencilModifierData;
+
+struct MDeformVert;
+struct MDeformWeight;
 
 /* ------------ Grease-Pencil API ------------------ */
 
+void BKE_gpencil_free_point_weights(struct MDeformVert *dvert);
+void BKE_gpencil_free_stroke_weights(struct bGPDstroke *gps);
 void BKE_gpencil_free_stroke(struct bGPDstroke *gps);
 bool BKE_gpencil_free_strokes(struct bGPDframe *gpf);
 void BKE_gpencil_free_frames(struct bGPDlayer *gpl);
 void BKE_gpencil_free_layers(struct ListBase *list);
-void BKE_gpencil_free_brushes(struct ListBase *list);
-void BKE_gpencil_free_palettes(struct ListBase *list);
-void BKE_gpencil_free(struct bGPdata *gpd, bool free_palettes);
+bool BKE_gpencil_free_frame_runtime_data(struct bGPDframe *derived_gpf);
+void BKE_gpencil_free_derived_frames(struct bGPdata *gpd);
+void BKE_gpencil_free(struct bGPdata *gpd, bool free_all);
+
+void BKE_gpencil_batch_cache_dirty(struct bGPdata *gpd);
+void BKE_gpencil_batch_cache_free(struct bGPdata *gpd);
 
 void BKE_gpencil_stroke_sync_selection(struct bGPDstroke *gps);
 
@@ -60,21 +80,36 @@ struct bGPdata   *BKE_gpencil_data_addnew(struct Main *bmain, const char name[])
 
 struct bGPDframe *BKE_gpencil_frame_duplicate(const struct bGPDframe *gpf_src);
 struct bGPDlayer *BKE_gpencil_layer_duplicate(const struct bGPDlayer *gpl_src);
+void BKE_gpencil_frame_copy_strokes(struct bGPDframe *gpf_src, struct bGPDframe *gpf_dst);
+struct bGPDstroke *BKE_gpencil_stroke_duplicate(struct bGPDstroke *gps_src);
+
 void BKE_gpencil_copy_data(struct Main *bmain, struct bGPdata *gpd_dst, const struct bGPdata *gpd_src, const int flag);
+struct bGPdata   *BKE_gpencil_copy(struct Main *bmain, const struct bGPdata *gpd);
 struct bGPdata   *BKE_gpencil_data_duplicate(struct Main *bmain, const struct bGPdata *gpd, bool internal_copy);
 
 void BKE_gpencil_make_local(struct Main *bmain, struct bGPdata *gpd, const bool lib_local);
 
 void BKE_gpencil_frame_delete_laststroke(struct bGPDlayer *gpl, struct bGPDframe *gpf);
 
-struct bGPDpalette *BKE_gpencil_palette_addnew(struct bGPdata *gpd, const char *name, bool setactive);
-struct bGPDpalette *BKE_gpencil_palette_duplicate(const struct bGPDpalette *palette_src);
-struct bGPDpalettecolor *BKE_gpencil_palettecolor_addnew(struct bGPDpalette *palette, const char *name, bool setactive);
+/* materials */
+void BKE_gpencil_material_index_remove(struct bGPdata *gpd, int index);
+void BKE_gpencil_material_remap(struct bGPdata *gpd, const unsigned int *remap, unsigned int remap_len);
 
-struct bGPDbrush *BKE_gpencil_brush_addnew(struct ToolSettings *ts, const char *name, bool setactive);
-struct bGPDbrush *BKE_gpencil_brush_duplicate(const struct bGPDbrush *brush_src);
-void BKE_gpencil_brush_init_presets(struct ToolSettings *ts);
+/* statistics functions */
+void BKE_gpencil_stats_update(struct bGPdata *gpd);
 
+/* Utilities for creating and populating GP strokes */
+/* - Number of values defining each point in the built-in data
+ *   buffers for primitives (e.g. 2D Monkey)
+ */
+#define GP_PRIM_DATABUF_SIZE  5
+
+void BKE_gpencil_stroke_add_points(
+        struct bGPDstroke *gps,
+        const float *array, const int totpoints,
+        const float mat[4][4]);
+
+struct bGPDstroke *BKE_gpencil_add_stroke(struct bGPDframe *gpf, int mat_idx, int totpoints, short thickness);
 
 /* Stroke and Fill - Alpha Visibility Threshold */
 #define GPENCIL_ALPHA_OPACITY_THRESH 0.001f
@@ -103,20 +138,40 @@ struct bGPDlayer *BKE_gpencil_layer_getactive(struct bGPdata *gpd);
 void BKE_gpencil_layer_setactive(struct bGPdata *gpd, struct bGPDlayer *active);
 void BKE_gpencil_layer_delete(struct bGPdata *gpd, struct bGPDlayer *gpl);
 
-struct bGPDbrush *BKE_gpencil_brush_getactive(struct ToolSettings *ts);
-void BKE_gpencil_brush_setactive(struct ToolSettings *ts, struct bGPDbrush *active);
-void BKE_gpencil_brush_delete(struct ToolSettings *ts, struct bGPDbrush *brush);
-
-struct bGPDpalette *BKE_gpencil_palette_getactive(struct bGPdata *gpd);
-void BKE_gpencil_palette_setactive(struct bGPdata *gpd, struct bGPDpalette *active);
-void BKE_gpencil_palette_delete(struct bGPdata *gpd, struct bGPDpalette *palette);
-void BKE_gpencil_palette_change_strokes(struct bGPdata *gpd);
-
-struct bGPDpalettecolor *BKE_gpencil_palettecolor_getactive(struct bGPDpalette *palette);
-void BKE_gpencil_palettecolor_setactive(struct bGPDpalette *palette, struct bGPDpalettecolor *active);
-void BKE_gpencil_palettecolor_delete(struct bGPDpalette *palette, struct bGPDpalettecolor *palcolor);
-struct bGPDpalettecolor *BKE_gpencil_palettecolor_getbyname(struct bGPDpalette *palette, char *name);
-void BKE_gpencil_palettecolor_changename(struct bGPdata *gpd, char *oldname, const char *newname);
-void BKE_gpencil_palettecolor_delete_strokes(struct bGPdata *gpd, char *name);
+struct Material *BKE_gpencil_get_material_from_brush(struct Brush *brush);
+struct Material *BKE_gpencil_material_ensure(struct Main *bmain, struct Object *ob);
+
+/* object boundbox */
+bool BKE_gpencil_stroke_minmax(
+        const struct bGPDstroke *gps, const bool use_select,
+        float r_min[3], float r_max[3]);
+
+struct BoundBox *BKE_gpencil_boundbox_get(struct Object *ob);
+void BKE_gpencil_centroid_3D(struct bGPdata *gpd, float r_centroid[3]);
+
+/* vertex groups */
+float BKE_gpencil_vgroup_use_index(struct MDeformVert *dvert, int index);
+void BKE_gpencil_vgroup_remove(struct Object *ob, struct bDeformGroup *defgroup);
+struct MDeformWeight *BKE_gpencil_vgroup_add_point_weight(struct MDeformVert *dvert, int index, float weight);
+bool BKE_gpencil_vgroup_remove_point_weight(struct MDeformVert *dvert, int index);
+void BKE_gpencil_stroke_weights_duplicate(struct bGPDstroke *gps_src, struct bGPDstroke *gps_dst);
+
+/* GPencil geometry evaluation */
+void BKE_gpencil_eval_geometry(struct Depsgraph *depsgraph, struct bGPdata *gpd);
+
+/* stroke geometry utilities */
+void BKE_gpencil_stroke_normal(const struct bGPDstroke *gps, float r_normal[3]);
+void BKE_gpencil_simplify_stroke(struct bGPDstroke *gps, float factor);
+void BKE_gpencil_simplify_fixed(struct bGPDstroke *gps);
+
+void BKE_gpencil_transform(struct bGPdata *gpd, float mat[4][4]);
+
+bool BKE_gpencil_smooth_stroke(struct bGPDstroke *gps, int i, float inf);
+bool BKE_gpencil_smooth_stroke_strength(struct bGPDstroke *gps, int point_index, float influence);
+bool BKE_gpencil_smooth_stroke_thickness(struct bGPDstroke *gps, int point_index, float influence);
+bool BKE_gpencil_smooth_stroke_uv(struct bGPDstroke *gps, int point_index, float influence);
+
+void BKE_gpencil_get_range_selected(struct bGPDlayer *gpl, int *r_initframe, int *r_endframe);
+float BKE_gpencil_multiframe_falloff_calc(struct bGPDframe *gpf, int actnum, int f_init, int f_end, struct CurveMapping *cur_falloff);
 
 #endif /*  __BKE_GPENCIL_H__ */
diff --git a/source/blender/blenkernel/BKE_gpencil_modifier.h b/source/blender/blenkernel/BKE_gpencil_modifier.h
new file mode 100644 (file)
index 0000000..cd6b654
--- /dev/null
@@ -0,0 +1,256 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is: all of this file.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+#ifndef __BKE_GPENCIL_MODIFIER_H__
+#define __BKE_GPENCIL_MODIFIER_H__
+
+/** \file BKE_greasepencil_modifier.h
+ *  \ingroup bke
+ */
+
+#include "DNA_gpencil_modifier_types.h"     /* needed for all enum typdefs */
+#include "BLI_compiler_attrs.h"
+#include "BKE_customdata.h"
+
+struct ID;
+struct Depsgraph;
+struct DerivedMesh;
+struct bContext; /* NOTE: bakeModifier() - called from UI - needs to create new datablocks, hence the need for this */
+struct Mesh;
+struct Object;
+struct Scene;
+struct ViewLayer;
+struct ListBase;
+struct bArmature;
+struct Main;
+struct GpencilModifierData;
+struct BMEditMesh;
+struct DepsNodeHandle;
+struct bGPDlayer;
+struct bGPDframe;
+struct bGPDstroke;
+struct ModifierUpdateDepsgraphContext;
+
+#define GPENCIL_MODIFIER_ACTIVE(_md, _is_render) (((_md->mode & eGpencilModifierMode_Realtime) && (_is_render == false)) || \
+                                                                                                 ((_md->mode & eGpencilModifierMode_Render) && (_is_render == true)))
+#define GPENCIL_MODIFIER_EDIT(_md, _is_edit) (((_md->mode & eGpencilModifierMode_Editmode) == 0) && (_is_edit))
+
+typedef enum {
+       /* Should not be used, only for None modifier type */
+       eGpencilModifierTypeType_None,
+
+       /* grease pencil modifiers */
+       eGpencilModifierTypeType_Gpencil,
+}  GpencilModifierTypeType;
+
+typedef enum {
+       eGpencilModifierTypeFlag_SupportsMapping = (1 << 0),
+       eGpencilModifierTypeFlag_SupportsEditmode = (1 << 1),
+
+       /* For modifiers that support editmode this determines if the
+       * modifier should be enabled by default in editmode. This should
+       * only be used by modifiers that are relatively speedy and
+       * also generally used in editmode, otherwise let the user enable
+       * it by hand.
+       */
+       eGpencilModifierTypeFlag_EnableInEditmode = (1 << 2),
+
+       /* For modifiers that require original data and so cannot
+       * be placed after any non-deformative modifier.
+       */
+       eGpencilModifierTypeFlag_RequiresOriginalData = (1 << 3),
+
+       /* max one per type */
+       eGpencilModifierTypeFlag_Single = (1 << 4),
+
+       /* can't be added manually by user */
+       eGpencilModifierTypeFlag_NoUserAdd = (1 << 5),
+} GpencilModifierTypeFlag;
+
+/* IMPORTANT! Keep ObjectWalkFunc and IDWalkFunc signatures compatible. */
+typedef void(*GreasePencilObjectWalkFunc)(void *userData, struct Object *ob, struct Object **obpoin, int cb_flag);
+typedef void(*GreasePencilIDWalkFunc)(void *userData, struct Object *ob, struct ID **idpoin, int cb_flag);
+typedef void(*GreasePencilTexWalkFunc)(void *userData, struct Object *ob, struct GpencilModifierData *md, const char *propname);
+
+typedef struct GpencilModifierTypeInfo {
+       /* The user visible name for this modifier */
+       char name[32];
+
+       /* The DNA struct name for the modifier data type, used to
+        * write the DNA data out.
+        */
+       char struct_name[32];
+
+       /* The size of the modifier data type, used by allocation. */
+       int struct_size;
+
+       GpencilModifierType type;
+       GpencilModifierTypeFlag flags;
+
+
+       /********************* Non-optional functions *********************/
+
+       /* Copy instance data for this modifier type. Should copy all user
+        * level settings to the target modifier.
+        */
+       void (*copyData)(const struct GpencilModifierData *md, struct GpencilModifierData *target);
+
+       /* Callback for GP "stroke" modifiers that operate on the
+        * shape and parameters of the provided strokes (e.g. Thickness, Noise, etc.)
+        *
+        * The gpl parameter contains the GP layer that the strokes come from.
+        * While access is provided to this data, you should not directly access
+        * the gpl->frames data from the modifier. Instead, use the gpf parameter
+        * instead.
+        *
+        * The gps parameter contains the GP stroke to operate on. This is usually a copy
+        * of the original (unmodified and saved to files) stroke data.
+        */
+       void (*deformStroke)(struct GpencilModifierData *md, struct Depsgraph *depsgraph,
+                            struct Object *ob, struct bGPDlayer *gpl, struct bGPDstroke *gps);
+
+       /* Callback for GP "geometry" modifiers that create extra geometry
+        * in the frame (e.g. Array)
+        *
+        * The gpf parameter contains the GP frame/strokes to operate on. This is
+        * usually a copy of the original (unmodified and saved to files) stroke data.
+        * Modifiers should only add any generated strokes to this frame (and not one accessed
+        * via the gpl parameter).
+        *
+        * The modifier_index parameter indicates where the modifier is
+        * in the modifier stack in relation to other modifiers.
+        */
+       void (*generateStrokes)(struct GpencilModifierData *md, struct Depsgraph *depsgraph,
+                               struct Object *ob, struct bGPDlayer *gpl, struct bGPDframe *gpf);
+
+       /* Bake-down GP modifier's effects into the GP datablock.
+        *
+        * This gets called when the user clicks the "Apply" button in the UI.
+        * As such, this callback needs to go through all layers/frames in the
+        * datablock, mutating the geometry and/or creating new datablocks/objects
+        */
+       void (*bakeModifier)(struct Main *bmain, struct Depsgraph *depsgraph,
+                           struct GpencilModifierData *md, struct Object *ob);
+
+       /********************* Optional functions *********************/
+
+       /* Initialize new instance data for this modifier type, this function
+        * should set modifier variables to their default values.
+        *
+        * This function is optional.
+        */
+       void (*initData)(struct GpencilModifierData *md);
+
+       /* Free internal modifier data variables, this function should
+        * not free the md variable itself.
+        *
+        * This function is optional.
+        */
+       void (*freeData)(struct GpencilModifierData *md);
+
+       /* Return a boolean value indicating if this modifier is able to be
+        * calculated based on the modifier data. This is *not* regarding the
+        * md->flag, that is tested by the system, this is just if the data
+        * validates (for example, a lattice will return false if the lattice
+        * object is not defined).
+        *
+        * This function is optional (assumes never disabled if not present).
+        */
+       bool (*isDisabled)(struct GpencilModifierData *md, int userRenderParams);
+
+       /* Add the appropriate relations to the dependency graph.
+        *
+        * This function is optional.
+        */
+       void (*updateDepsgraph)(struct GpencilModifierData *md,
+                               const struct ModifierUpdateDepsgraphContext *ctx);
+
+       /* Should return true if the modifier needs to be recalculated on time
+        * changes.
+        *
+        * This function is optional (assumes false if not present).
+        */
+       bool (*dependsOnTime)(struct GpencilModifierData *md);
+
+
+       /* Should call the given walk function on with a pointer to each Object
+        * pointer that the modifier data stores. This is used for linking on file
+        * load and for unlinking objects or forwarding object references.
+        *
+        * This function is optional.
+        */
+       void (*foreachObjectLink)(struct GpencilModifierData *md, struct Object *ob,
+                                 GreasePencilObjectWalkFunc walk, void *userData);
+
+       /* Should call the given walk function with a pointer to each ID
+        * pointer (i.e. each datablock pointer) that the modifier data
+        * stores. This is used for linking on file load and for
+        * unlinking datablocks or forwarding datablock references.
+        *
+        * This function is optional. If it is not present, foreachObjectLink
+        * will be used.
+        */
+       void (*foreachIDLink)(struct GpencilModifierData *md, struct Object *ob,
+                             GreasePencilIDWalkFunc walk, void *userData);
+
+       /* Should call the given walk function for each texture that the
+        * modifier data stores. This is used for finding all textures in
+        * the context for the UI.
+        *
+        * This function is optional. If it is not present, it will be
+        * assumed the modifier has no textures.
+        */
+       void (*foreachTexLink)(struct GpencilModifierData *md, struct Object *ob,
+                              GreasePencilTexWalkFunc walk, void *userData);
+} GpencilModifierTypeInfo;
+
+void BKE_gpencil_instance_modifier_instance_tfm(struct InstanceGpencilModifierData *mmd, const int elem_idx[3], float r_mat[4][4]);
+
+/* Initialize modifier's global data (type info and some common global storages). */
+void BKE_gpencil_modifier_init(void);
+
+const GpencilModifierTypeInfo *BKE_gpencil_modifierType_getInfo(GpencilModifierType type);
+struct GpencilModifierData  *BKE_gpencil_modifier_new(int type);
+void BKE_gpencil_modifier_free_ex(struct GpencilModifierData *md, const int flag);
+void BKE_gpencil_modifier_free(struct GpencilModifierData *md);
+bool BKE_gpencil_modifier_unique_name(struct ListBase *modifiers, struct GpencilModifierData *gmd);
+bool BKE_gpencil_modifier_dependsOnTime(struct GpencilModifierData *md);
+struct GpencilModifierData *BKE_gpencil_modifiers_findByType(struct Object *ob, GpencilModifierType type);
+struct GpencilModifierData *BKE_gpencil_modifiers_findByName(struct Object *ob, const char *name);
+void BKE_gpencil_modifier_copyData_generic(const struct GpencilModifierData *md_src, struct GpencilModifierData *md_dst);
+void BKE_gpencil_modifier_copyData(struct GpencilModifierData *md, struct GpencilModifierData *target);
+void BKE_gpencil_modifier_copyData_ex(struct GpencilModifierData *md, struct GpencilModifierData *target, const int flag);
+void BKE_gpencil_modifiers_foreachIDLink(struct Object *ob, GreasePencilIDWalkFunc walk, void *userData);
+void BKE_gpencil_modifiers_foreachTexLink(struct Object *ob, GreasePencilTexWalkFunc walk, void *userData);
+
+bool BKE_gpencil_has_geometry_modifiers(struct Object *ob);
+
+void BKE_gpencil_stroke_modifiers(
+       struct Depsgraph *depsgraph, struct Object *ob,
+       struct bGPDlayer *gpl, struct bGPDframe *gpf, struct bGPDstroke *gps, bool is_render);
+void BKE_gpencil_geometry_modifiers(
+       struct Depsgraph *depsgraph, struct Object *ob,
+       struct bGPDlayer *gpl, struct bGPDframe *gpf, bool is_render);
+
+void BKE_gpencil_lattice_init(struct Object *ob);
+void BKE_gpencil_lattice_clear(struct Object *ob);
+
+#endif /* __BKE_GPENCIL_MODIFIER_H__ */
index 22897d2..7a5262e 100644 (file)
@@ -43,7 +43,10 @@ enum {
        ICON_DATA_PREVIEW,
        /** 2D triangles: obj is #Icon_Geom */
        ICON_DATA_GEOM,
+       /** Studiolight */
        ICON_DATA_STUDIOLIGHT,
+       /** GPencil Layer color preview (annotations): obj is #bGPDlayer */
+       ICON_DATA_GPLAYER,
 };
 
 struct Icon {
@@ -79,6 +82,7 @@ struct ImBuf;
 struct PreviewImage;
 struct ID;
 struct StudioLight;
+struct bGPDlayer;
 
 enum eIconSizes;
 
@@ -87,6 +91,9 @@ void BKE_icons_init(int first_dyn_id);
 /* return icon id for library object or create new icon if not found */
 int BKE_icon_id_ensure(struct ID *id);
 
+/* return icon id for Grease Pencil layer (color preview) or create new icon if not found */
+int BKE_icon_gplayer_color_ensure(struct bGPDlayer *gpl);
+
 int BKE_icon_preview_ensure(struct ID *id, struct PreviewImage *preview);
 
 /* retrieve icon for id */
index c2ac5e9..67e6a32 100644 (file)
@@ -54,7 +54,6 @@ void BKE_lattice_free(struct Lattice *lt);
 void BKE_lattice_make_local(struct Main *bmain, struct Lattice *lt, const bool lib_local);
 void calc_lat_fudu(int flag, int res, float *r_fu, float *r_du);
 
-struct LatticeDeformData;
 struct LatticeDeformData *init_latt_deform(struct Object *oblatt, struct Object *ob) ATTR_WARN_UNUSED_RESULT;
 void calc_latt_deform(struct LatticeDeformData *lattice_deform_data, float co[3], float weight);
 void end_latt_deform(struct LatticeDeformData *lattice_deform_data);
index c85017a..1ca8928 100644 (file)
@@ -54,11 +54,13 @@ void BKE_material_init(struct Material *ma);
 void BKE_material_remap_object(struct Object *ob, const unsigned int *remap);
 void BKE_material_remap_object_calc(struct  Object *ob_dst, struct Object *ob_src, short *remap_src_to_dst);
 struct Material *BKE_material_add(struct Main *bmain, const char *name);
+struct Material *BKE_material_add_gpencil(struct Main *bmain, const char *name);
 void BKE_material_copy_data(struct Main *bmain, struct Material *ma_dst, const struct Material *ma_src, const int flag);
 struct Material *BKE_material_copy(struct Main *bmain, const struct Material *ma);
 struct Material *BKE_material_localize(struct Material *ma);
 struct Material *give_node_material(struct Material *ma); /* returns node material or self */
 void BKE_material_make_local(struct Main *bmain, struct Material *ma, const bool lib_local);
+void BKE_material_init_gpencil_settings(struct Material *ma);
 
 /* UNUSED */
 // void automatname(struct Material *);
@@ -87,6 +89,8 @@ short BKE_object_material_slot_find_index(struct Object *ob, struct Material *ma
 bool  BKE_object_material_slot_add(struct Main *bmain, struct Object *ob);
 bool  BKE_object_material_slot_remove(struct Main *bmain, struct Object *ob);
 
+struct MaterialGPencilStyle *BKE_material_gpencil_settings_get(struct Object *ob, short act);
+
 void BKE_texpaint_slot_refresh_cache(struct Scene *scene, struct Material *ma);
 void BKE_texpaint_slots_refresh_object(struct Scene *scene, struct Object *ob);
 
index 79e4f1d..7d795c2 100644 (file)
@@ -37,8 +37,11 @@ extern "C" {
 
 struct Base;
 struct Depsgraph;
+struct GpencilModifierData;
 struct Scene;
+struct ShaderFxData;
 struct ViewLayer;
+struct ID;
 struct Object;
 struct BoundBox;
 struct View3D;
@@ -49,6 +52,7 @@ struct Mesh;
 struct RigidBodyWorld;
 struct HookModifierData;
 struct ModifierData;
+struct HookGpencilModifierData;
 
 #include "DNA_object_enums.h"
 
@@ -69,11 +73,16 @@ void BKE_object_free_derived_mesh_caches(struct Object *ob);
 void BKE_object_free_caches(struct Object *object);
 
 void BKE_object_modifier_hook_reset(struct Object *ob, struct HookModifierData *hmd);
+void BKE_object_modifier_gpencil_hook_reset(struct Object *ob, struct HookGpencilModifierData *hmd);
+bool BKE_object_modifier_gpencil_use_time(struct Object *ob, struct GpencilModifierData *md);
+
+bool BKE_object_shaderfx_use_time(struct Object *ob, struct ShaderFxData *md);
 
 bool BKE_object_support_modifier_type_check(const struct Object *ob, int modifier_type);
 
 void BKE_object_link_modifiers(struct Scene *scene, struct Object *ob_dst, const struct Object *ob_src);
 void BKE_object_free_modifiers(struct Object *ob, const int flag);
+void BKE_object_free_shaderfx(struct Object *ob, const int flag);
 
 void BKE_object_make_proxy(struct Main *bmain, struct Object *ob, struct Object *target, struct Object *gob);
 void BKE_object_copy_proxy_drivers(struct Object *ob, struct Object *target);
@@ -108,6 +117,9 @@ struct Object *BKE_object_add_from(
         struct Main *bmain, struct Scene *scene, struct ViewLayer *view_layer,
         int type, const char *name, struct Object *ob_src)
         ATTR_NONNULL(1, 2, 3, 6) ATTR_RETURNS_NONNULL;
+struct Object *BKE_object_add_for_data(
+        struct Main *bmain, struct ViewLayer *view_layer,
+        int type, const char *name, struct ID *data, bool do_id_user) ATTR_RETURNS_NONNULL;
 void *BKE_object_obdata_add_from_type(
         struct Main *bmain,
         int type, const char *name)
index 6ade14b..c440a63 100644 (file)
@@ -77,7 +77,8 @@ typedef enum ePaintMode {
        ePaintTextureProjective = 3,
        ePaintTexture2D = 4,
        ePaintSculptUV = 5,
-       ePaintInvalid = 6
+       ePaintInvalid = 6,
+       ePaintGpencil = 7
 } ePaintMode;
 
 /* overlay invalidation */
diff --git a/source/blender/blenkernel/BKE_shader_fx.h b/source/blender/blenkernel/BKE_shader_fx.h
new file mode 100644 (file)
index 0000000..11c5983
--- /dev/null
@@ -0,0 +1,180 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is: all of this file.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+#ifndef __BKE_SHADER_FX_H__
+#define __BKE_SHADER_FX_H__
+
+/** \file BKE_shader_fx.h
+ *  \ingroup bke
+ */
+
+#include "DNA_shader_fx_types.h"     /* needed for all enum typdefs */
+#include "BLI_compiler_attrs.h"
+#include "BKE_customdata.h"
+
+struct ID;
+struct Depsgraph;
+struct DerivedMesh;
+struct Mesh;
+struct Object;
+struct Scene;
+struct ViewLayer;
+struct ListBase;
+struct bArmature;
+struct Main;
+struct ShaderFxData;
+struct DepsNodeHandle;
+struct bGPDlayer;
+struct bGPDframe;
+struct bGPDstroke;
+struct ModifierUpdateDepsgraphContext;
+
+#define SHADER_FX_ACTIVE(_fx, _is_render) (((_fx->mode & eShaderFxMode_Realtime) && (_is_render == false)) || \
+                                                                                                 ((_fx->mode & eShaderFxMode_Render) && (_is_render == true))) 
+#define SHADER_FX_EDIT(_fx, _is_edit) (((_fx->mode & eShaderFxMode_Editmode) == 0) && (_is_edit))
+
+typedef enum {
+       /* Should not be used, only for None type */
+       eShaderFxType_NoneType,
+
+       /* grease pencil effects */
+       eShaderFxType_GpencilType,
+}  ShaderFxTypeType;
+
+typedef enum {
+       eShaderFxTypeFlag_SupportsEditmode = (1 << 0),
+
+       /* For effects that support editmode this determines if the
+       * effect should be enabled by default in editmode. 
+       */
+       eShaderFxTypeFlag_EnableInEditmode = (1 << 2),
+
+       /* max one per type */
+       eShaderFxTypeFlag_Single = (1 << 4),
+
+       /* can't be added manually by user */
+       eShaderFxTypeFlag_NoUserAdd = (1 << 5),
+} ShaderFxTypeFlag;
+
+/* IMPORTANT! Keep ObjectWalkFunc and IDWalkFunc signatures compatible. */
+typedef void(*ShaderFxObjectWalkFunc)(void *userData, struct Object *ob, struct Object **obpoin, int cb_flag);
+typedef void(*ShaderFxIDWalkFunc)(void *userData, struct Object *ob, struct ID **idpoin, int cb_flag);
+typedef void(*ShaderFxTexWalkFunc)(void *userData, struct Object *ob, struct ShaderFxData *fx, const char *propname);
+
+typedef struct ShaderFxTypeInfo {
+       /* The user visible name for this effect */
+       char name[32];
+
+       /* The DNA struct name for the effect data type, used to
+        * write the DNA data out.
+        */
+       char struct_name[32];
+
+       /* The size of the effect data type, used by allocation. */
+       int struct_size;
+
+       ShaderFxTypeType type;
+       ShaderFxTypeFlag flags;
+
+       /* Copy instance data for this effect type. Should copy all user
+       * level settings to the target effect.
+       */
+       void(*copyData)(const struct ShaderFxData *fx, struct ShaderFxData *target);
+
+       /* Initialize new instance data for this effect type, this function
+        * should set effect variables to their default values.
+        * 
+        * This function is optional.
+        */
+       void (*initData)(struct ShaderFxData *fx);
+
+       /* Free internal effect data variables, this function should
+        * not free the fx variable itself.
+        *
+        * This function is optional.
+        */
+       void (*freeData)(struct ShaderFxData *fx);
+
+       /* Return a boolean value indicating if this effect is able to be
+        * calculated based on the effect data. This is *not* regarding the
+        * fx->flag, that is tested by the system, this is just if the data
+        * validates (for example, a lattice will return false if the lattice
+        * object is not defined).
+        *
+        * This function is optional (assumes never disabled if not present).
+        */
+       bool (*isDisabled)(struct ShaderFxData *fx, int userRenderParams);
+
+       /* Add the appropriate relations to the dependency graph.
+        *
+        * This function is optional.
+        */
+       void (*updateDepsgraph)(struct ShaderFxData *fx,
+                               const struct ModifierUpdateDepsgraphContext *ctx);
+       /* Should return true if the effect needs to be recalculated on time
+        * changes.
+        *
+        * This function is optional (assumes false if not present).
+        */
+       bool (*dependsOnTime)(struct ShaderFxData *fx);
+
+
+       /* Should call the given walk function on with a pointer to each Object
+        * pointer that the effect data stores. This is used for linking on file
+        * load and for unlinking objects or forwarding object references.
+        *
+        * This function is optional.
+        */
+       void (*foreachObjectLink)(struct ShaderFxData *fx, struct Object *ob,
+                                 ShaderFxObjectWalkFunc walk, void *userData);
+
+       /* Should call the given walk function with a pointer to each ID
+        * pointer (i.e. each datablock pointer) that the effect data
+        * stores. This is used for linking on file load and for
+        * unlinking datablocks or forwarding datablock references.
+        *
+        * This function is optional. If it is not present, foreachObjectLink
+        * will be used.
+        */
+       void (*foreachIDLink)(struct ShaderFxData *fx, struct Object *ob,
+                             ShaderFxIDWalkFunc walk, void *userData);
+} ShaderFxTypeInfo;
+
+/* Initialize  global data (type info and some common global storages). */
+void BKE_shaderfx_init(void);
+
+const ShaderFxTypeInfo *BKE_shaderfxType_getInfo(ShaderFxType type);
+struct ShaderFxData  *BKE_shaderfx_new(int type);
+void BKE_shaderfx_free_ex(struct ShaderFxData *fx, const int flag);
+void BKE_shaderfx_free(struct ShaderFxData *fx);
+bool BKE_shaderfx_unique_name(struct ListBase *shaderfx, struct ShaderFxData *fx);
+bool BKE_shaderfx_dependsOnTime(struct ShaderFxData *fx);
+struct ShaderFxData *BKE_shaderfx_findByType(struct Object *ob, ShaderFxType type);
+struct ShaderFxData *BKE_shaderfx_findByName(struct Object *ob, const char *name);
+void BKE_shaderfx_copyData_generic(const struct ShaderFxData *fx_src, struct ShaderFxData *fx_dst);
+void BKE_shaderfx_copyData(struct ShaderFxData *fx, struct ShaderFxData *target);
+void BKE_shaderfx_copyData_ex(struct ShaderFxData *fx, struct ShaderFxData *target, const int flag);
+void BKE_shaderfx_foreachIDLink(struct Object *ob, ShaderFxIDWalkFunc walk, void *userData);
+
+bool BKE_shaderfx_has_gpencil(struct Object *ob);
+
+#endif /* __BKE_SHADER_FX_H__ */
index 01910bf..7169597 100644 (file)
@@ -38,6 +38,8 @@ set(INC
        ../makesrna
        ../bmesh
        ../modifiers
+       ../gpencil_modifiers
+       ../shader_fx
        ../nodes
        ../physics
        ../render/extern/include
@@ -115,6 +117,7 @@ set(SRC
        intern/font.c
        intern/freestyle.c
        intern/gpencil.c
+       intern/gpencil_modifier.c
        intern/icons.c
        intern/icons_rasterize.c
        intern/idcode.c
@@ -180,6 +183,7 @@ set(SRC
        intern/seqeffects.c
        intern/seqmodifier.c
        intern/sequencer.c
+       intern/shader_fx.c
        intern/shrinkwrap.c
        intern/smoke.c
        intern/softbody.c
@@ -259,6 +263,7 @@ set(SRC
        BKE_freestyle.h
        BKE_global.h
        BKE_gpencil.h
+       BKE_gpencil_modifier.h
        BKE_icons.h
        BKE_idcode.h
        BKE_idprop.h
@@ -306,6 +311,7 @@ set(SRC
        BKE_scene.h
        BKE_screen.h
        BKE_sequencer.h
+       BKE_shader_fx.h
        BKE_shrinkwrap.h
        BKE_smoke.h
        BKE_softbody.h
index fd7497f..7dfedfe 100644 (file)
@@ -104,6 +104,7 @@ bool id_type_can_have_animdata(const short id_type)
                case ID_MSK:
                case ID_GD:
                case ID_CF:
+               case ID_PAL:
                        return true;
 
                /* no AnimData */
@@ -1150,6 +1151,9 @@ void BKE_animdata_main_cb(Main *bmain, ID_AnimData_Edit_Callback func, void *use
        /* grease pencil */
        ANIMDATA_IDS_CB(bmain->gpencil.first);
 
+       /* palettes */
+       ANIMDATA_IDS_CB(bmain->palettes.first);
+
        /* cache files */
        ANIMDATA_IDS_CB(bmain->cachefiles.first);
 }
@@ -2925,6 +2929,9 @@ void BKE_animsys_evaluate_all_animation(Main *main, Depsgraph *depsgraph, Scene
        /* grease pencil */
        EVAL_ANIM_IDS(main->gpencil.first, ADT_RECALC_ANIM);
 
+       /* palettes */
+       EVAL_ANIM_IDS(main->palettes.first, ADT_RECALC_ANIM);
+
        /* cache files */
        EVAL_ANIM_IDS(main->cachefiles.first, ADT_RECALC_ANIM);
 
index 42cd796..598eb9b 100644 (file)
@@ -29,6 +29,7 @@
 #include "DNA_brush_types.h"
 #include "DNA_scene_types.h"
 #include "DNA_object_types.h"
+#include "DNA_gpencil_types.h"
 
 #include "BLI_math.h"
 #include "BLI_blenlib.h"
@@ -36,6 +37,7 @@
 
 #include "BKE_brush.h"
 #include "BKE_colortools.h"
+#include "BKE_context.h"
 #include "BKE_global.h"
 #include "BKE_library.h"
 #include "BKE_library_query.h"
@@ -129,6 +131,7 @@ static void brush_defaults(Brush *brush)
 
        brush->stencil_dimension[0] = 256;
        brush->stencil_dimension[1] = 256;
+
 }
 
 /* Datablock add/copy/free/make_local */
@@ -164,6 +167,368 @@ Brush *BKE_brush_add(Main *bmain, const char *name, const eObjectMode ob_mode)
        return brush;
 }
 
+/* add a new gp-brush */
+Brush *BKE_brush_add_gpencil(Main *bmain, ToolSettings *ts, const char *name)
+{
+       Brush *brush;
+       Paint *paint = BKE_brush_get_gpencil_paint(ts);
+       brush = BKE_brush_add(bmain, name, OB_MODE_GPENCIL_PAINT);
+
+       BKE_paint_brush_set(paint, brush);
+       id_us_min(&brush->id);
+
+       /* grease pencil basic settings */
+       brush->size = 3;
+
+       brush->gpencil_settings = MEM_callocN(sizeof(BrushGpencilSettings), "BrushGpencilSettings");
+
+       brush->gpencil_settings->draw_smoothlvl = 1;
+       brush->gpencil_settings->flag = 0;
+       brush->gpencil_settings->flag |= GP_BRUSH_USE_PRESSURE;
+       brush->gpencil_settings->draw_sensitivity = 1.0f;
+       brush->gpencil_settings->draw_strength = 1.0f;
+       brush->gpencil_settings->draw_jitter = 0.0f;
+       brush->gpencil_settings->flag |= GP_BRUSH_USE_JITTER_PRESSURE;
+       brush->gpencil_settings->icon_id = GP_BRUSH_ICON_PEN;
+
+       /* curves */
+       brush->gpencil_settings->curve_sensitivity = curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f);
+       brush->gpencil_settings->curve_strength = curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f);
+       brush->gpencil_settings->curve_jitter = curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f);
+
+       /* return brush */
+       return brush;
+}
+
+Paint *BKE_brush_get_gpencil_paint(ToolSettings *ts)
+{
+       /* alloc paint session */
+       if (ts->gp_paint == NULL) {
+               ts->gp_paint = MEM_callocN(sizeof(GpPaint), "GpPaint");
+       }
+
+       return &ts->gp_paint->paint;
+}
+
+/* grease pencil cumapping->preset */
+typedef enum eGPCurveMappingPreset {
+       GPCURVE_PRESET_PENCIL = 0,
+       GPCURVE_PRESET_INK = 1,
+       GPCURVE_PRESET_INKNOISE = 2,
+} eGPCurveMappingPreset;
+
+static void brush_gpencil_curvemap_reset(CurveMap *cuma, int preset)
+{
+       if (cuma->curve)
+               MEM_freeN(cuma->curve);
+
+       cuma->totpoint = 3;
+       cuma->curve = MEM_callocN(cuma->totpoint * sizeof(CurveMapPoint), __func__);
+
+       switch (preset) {
+               case GPCURVE_PRESET_PENCIL:
+                       cuma->curve[0].x = 0.0f;
+                       cuma->curve[0].y = 0.0f;
+                       cuma->curve[1].x = 0.75115f;
+                       cuma->curve[1].y = 0.25f;
+                       cuma->curve[2].x = 1.0f;
+                       cuma->curve[2].y = 1.0f;
+                       break;
+               case GPCURVE_PRESET_INK:
+                       cuma->curve[0].x = 0.0f;
+                       cuma->curve[0].y = 0.0f;
+                       cuma->curve[1].x = 0.63448f;
+                       cuma->curve[1].y = 0.375f;
+                       cuma->curve[2].x = 1.0f;
+                       cuma->curve[2].y = 1.0f;
+                       break;
+               case GPCURVE_PRESET_INKNOISE:
+                       cuma->curve[0].x = 0.0f;
+                       cuma->curve[0].y = 0.0f;
+                       cuma->curve[1].x = 0.63134f;
+                       cuma->curve[1].y = 0.3625f;
+                       cuma->curve[2].x = 1.0f;
+                       cuma->curve[2].y = 1.0f;
+                       break;
+       }
+
+       if (cuma->table) {
+               MEM_freeN(cuma->table);
+               cuma->table = NULL;
+       }
+}
+
+/* create a set of grease pencil presets */
+void BKE_brush_gpencil_presets(bContext *C)
+{
+#define SMOOTH_STROKE_RADIUS 40
+#define SMOOTH_STROKE_FACTOR 0.9f
+
+       ToolSettings *ts = CTX_data_tool_settings(C);
+       Paint *paint = BKE_brush_get_gpencil_paint(ts);
+       Main *bmain = CTX_data_main(C);
+
+       Brush *brush, *deft;
+       CurveMapping *custom_curve;
+
+       /* Pencil brush */
+       brush = BKE_brush_add_gpencil(bmain, ts, "Draw Pencil");
+       brush->size = 25.0f;
+       brush->gpencil_settings->flag |= (GP_BRUSH_USE_PRESSURE | GP_BRUSH_ENABLE_CURSOR);
+       brush->gpencil_settings->draw_sensitivity = 1.0f;
+
+       brush->gpencil_settings->draw_strength = 0.6f;
+       brush->gpencil_settings->flag |= GP_BRUSH_USE_STENGTH_PRESSURE;
+
+       brush->gpencil_settings->draw_random_press = 0.0f;
+
+       brush->gpencil_settings->draw_jitter = 0.0f;
+       brush->gpencil_settings->flag |= GP_BRUSH_USE_JITTER_PRESSURE;
+
+       brush->gpencil_settings->draw_angle = 0.0f;
+       brush->gpencil_settings->draw_angle_factor = 0.0f;
+
+       brush->gpencil_settings->flag |= GP_BRUSH_GROUP_SETTINGS;
+       brush->gpencil_settings->draw_smoothfac = 0.5f;
+       brush->gpencil_settings->draw_smoothlvl = 1;
+       brush->gpencil_settings->thick_smoothfac = 1.0f;
+       brush->gpencil_settings->thick_smoothlvl = 3;
+       brush->gpencil_settings->draw_subdivide = 1;
+       brush->gpencil_settings->draw_random_sub = 0.0f;
+       brush->gpencil_settings->icon_id = GP_BRUSH_ICON_PENCIL;
+       brush->gpencil_settings->brush_type = GP_BRUSH_TYPE_DRAW;
+
+       brush->smooth_stroke_radius = SMOOTH_STROKE_RADIUS;
+       brush->smooth_stroke_factor = SMOOTH_STROKE_FACTOR;
+
+       /* Pen brush */
+       brush = BKE_brush_add_gpencil(bmain, ts, "Draw Pen");
+       deft = brush; /* save default brush */
+       brush->size = 30.0f;
+       brush->gpencil_settings->flag |= (GP_BRUSH_USE_PRESSURE | GP_BRUSH_ENABLE_CURSOR);
+       brush->gpencil_settings->draw_sensitivity = 1.0f;
+
+       brush->gpencil_settings->draw_strength = 1.0f;
+       brush->gpencil_settings->flag |= GP_BRUSH_USE_STENGTH_PRESSURE;
+
+       brush->gpencil_settings->draw_random_press = 0.0f;
+       brush->gpencil_settings->draw_random_strength = 0.0f;
+
+       brush->gpencil_settings->draw_jitter = 0.0f;
+       brush->gpencil_settings->flag |= GP_BRUSH_USE_JITTER_PRESSURE;
+
+       brush->gpencil_settings->draw_angle = 0.0f;
+       brush->gpencil_settings->draw_angle_factor = 0.0f;
+
+       brush->gpencil_settings->flag |= GP_BRUSH_GROUP_SETTINGS;
+       brush->gpencil_settings->draw_smoothfac = 0.5f;
+       brush->gpencil_settings->draw_smoothlvl = 1;
+       brush->gpencil_settings->draw_subdivide = 1;
+       brush->gpencil_settings->thick_smoothfac = 1.0f;
+       brush->gpencil_settings->thick_smoothlvl = 3;
+       brush->gpencil_settings->draw_random_sub = 0.0f;
+       brush->gpencil_settings->icon_id = GP_BRUSH_ICON_PEN;
+       brush->gpencil_settings->brush_type = GP_BRUSH_TYPE_DRAW;
+
+       brush->smooth_stroke_radius = SMOOTH_STROKE_RADIUS;
+       brush->smooth_stroke_factor = SMOOTH_STROKE_FACTOR;
+
+       /* Ink brush */
+       brush = BKE_brush_add_gpencil(bmain, ts, "Draw Ink");
+       brush->size = 60.0f;
+       brush->gpencil_settings->flag |= (GP_BRUSH_USE_PRESSURE | GP_BRUSH_ENABLE_CURSOR);
+       brush->gpencil_settings->draw_sensitivity = 1.6f;
+
+       brush->gpencil_settings->draw_strength = 1.0f;
+
+       brush->gpencil_settings->draw_random_press = 0.0f;
+
+       brush->gpencil_settings->draw_jitter = 0.0f;
+       brush->gpencil_settings->flag |= GP_BRUSH_USE_JITTER_PRESSURE;
+
+       brush->gpencil_settings->draw_angle = 0.0f;
+       brush->gpencil_settings->draw_angle_factor = 0.0f;
+
+       brush->gpencil_settings->flag |= GP_BRUSH_GROUP_SETTINGS;
+       brush->gpencil_settings->draw_smoothfac = 0.5f;
+       brush->gpencil_settings->draw_smoothlvl = 1;
+       brush->gpencil_settings->thick_smoothfac = 1.0f;
+       brush->gpencil_settings->thick_smoothlvl = 3;
+       brush->gpencil_settings->draw_subdivide = 1;
+       brush->gpencil_settings->draw_random_sub = 0.0f;
+       brush->gpencil_settings->icon_id = GP_BRUSH_ICON_INK;
+       brush->gpencil_settings->brush_type = GP_BRUSH_TYPE_DRAW;
+
+       brush->smooth_stroke_radius = SMOOTH_STROKE_RADIUS;
+       brush->smooth_stroke_factor = SMOOTH_STROKE_FACTOR;
+
+       /* Curve */
+       custom_curve = brush->gpencil_settings->curve_sensitivity;
+       curvemapping_set_defaults(custom_curve, 0, 0.0f, 0.0f, 1.0f, 1.0f);
+       curvemapping_initialize(custom_curve);
+       brush_gpencil_curvemap_reset(custom_curve->cm, GPCURVE_PRESET_INK);
+
+       /* Ink Noise brush */
+       brush = BKE_brush_add_gpencil(bmain, ts, "Draw Noise");
+       brush->size = 60.0f;
+       brush->gpencil_settings->flag |= (GP_BRUSH_USE_PRESSURE | GP_BRUSH_ENABLE_CURSOR);
+       brush->gpencil_settings->draw_sensitivity = 1.0f;
+
+       brush->gpencil_settings->draw_strength = 1.0f;
+
+       brush->gpencil_settings->flag |= GP_BRUSH_GROUP_RANDOM;
+       brush->gpencil_settings->draw_random_press = 0.7f;
+       brush->gpencil_settings->draw_random_strength = 0.0f;
+
+       brush->gpencil_settings->draw_jitter = 0.0f;
+       brush->gpencil_settings->flag |= GP_BRUSH_USE_JITTER_PRESSURE;
+
+       brush->gpencil_settings->draw_angle = 0.0f;
+       brush->gpencil_settings->draw_angle_factor = 0.0f;
+
+       brush->gpencil_settings->flag |= GP_BRUSH_GROUP_SETTINGS;
+       brush->gpencil_settings->draw_smoothfac = 1.0f;
+       brush->gpencil_settings->draw_smoothlvl = 2;
+       brush->gpencil_settings->thick_smoothfac = 0.5f;
+       brush->gpencil_settings->thick_smoothlvl = 2;
+       brush->gpencil_settings->draw_subdivide = 1;
+       brush->gpencil_settings->draw_random_sub = 0.0f;
+       brush->gpencil_settings->icon_id = GP_BRUSH_ICON_INKNOISE;
+       brush->gpencil_settings->brush_type = GP_BRUSH_TYPE_DRAW;
+
+       brush->smooth_stroke_radius = SMOOTH_STROKE_RADIUS;
+       brush->smooth_stroke_factor = SMOOTH_STROKE_FACTOR;
+
+       /* Curve */
+       custom_curve = brush->gpencil_settings->curve_sensitivity;
+       curvemapping_set_defaults(custom_curve, 0, 0.0f, 0.0f, 1.0f, 1.0f);
+       curvemapping_initialize(custom_curve);
+       brush_gpencil_curvemap_reset(custom_curve->cm, GPCURVE_PRESET_INKNOISE);
+
+       /* Block Basic brush */
+       brush = BKE_brush_add_gpencil(bmain, ts, "Draw Block");
+       brush->size = 150.0f;
+       brush->gpencil_settings->flag |= (GP_BRUSH_USE_PRESSURE | GP_BRUSH_ENABLE_CURSOR);
+       brush->gpencil_settings->draw_sensitivity = 1.0f;
+
+       brush->gpencil_settings->draw_strength = 0.7f;
+       brush->gpencil_settings->flag |= GP_BRUSH_USE_STENGTH_PRESSURE;
+
+       brush->gpencil_settings->draw_random_press = 0.0f;
+
+       brush->gpencil_settings->draw_jitter = 0.0f;
+       brush->gpencil_settings->flag |= GP_BRUSH_USE_JITTER_PRESSURE;
+
+       brush->gpencil_settings->draw_angle = 0.0f;
+       brush->gpencil_settings->draw_angle_factor = 0.0f;
+
+       brush->gpencil_settings->flag |= GP_BRUSH_GROUP_SETTINGS;
+       brush->gpencil_settings->draw_smoothfac = 0.0f;
+       brush->gpencil_settings->draw_smoothlvl = 1;
+       brush->gpencil_settings->thick_smoothfac = 1.0f;
+       brush->gpencil_settings->thick_smoothlvl = 3;
+       brush->gpencil_settings->draw_subdivide = 0;
+       brush->gpencil_settings->draw_random_sub = 0;
+       brush->gpencil_settings->icon_id = GP_BRUSH_ICON_BLOCK;
+       brush->gpencil_settings->brush_type = GP_BRUSH_TYPE_DRAW;
+
+       brush->smooth_stroke_radius = SMOOTH_STROKE_RADIUS;
+       brush->smooth_stroke_factor = SMOOTH_STROKE_FACTOR;
+
+       /* Marker brush */
+       brush = BKE_brush_add_gpencil(bmain, ts, "Draw Marker");
+       brush->size = 80.0f;
+       brush->gpencil_settings->flag |= (GP_BRUSH_USE_PRESSURE | GP_BRUSH_ENABLE_CURSOR);
+       brush->gpencil_settings->draw_sensitivity = 1.0f;
+
+       brush->gpencil_settings->draw_strength = 1.0f;
+
+       brush->gpencil_settings->flag |= GP_BRUSH_GROUP_RANDOM;
+       brush->gpencil_settings->draw_random_press = 0.374f;
+       brush->gpencil_settings->draw_random_strength = 0.0f;
+
+       brush->gpencil_settings->draw_jitter = 0.0f;
+       brush->gpencil_settings->flag |= GP_BRUSH_USE_JITTER_PRESSURE;
+
+       brush->gpencil_settings->draw_angle = M_PI_4; /* 45 degrees */
+       brush->gpencil_settings->draw_angle_factor = 1.0f;
+
+       brush->gpencil_settings->flag |= GP_BRUSH_GROUP_SETTINGS;
+       brush->gpencil_settings->draw_smoothfac = 0.5f;
+       brush->gpencil_settings->draw_smoothlvl = 1;
+       brush->gpencil_settings->thick_smoothfac = 1.0f;
+       brush->gpencil_settings->thick_smoothlvl = 3;
+       brush->gpencil_settings->draw_subdivide = 1;
+       brush->gpencil_settings->draw_random_sub = 0.0f;
+       brush->gpencil_settings->icon_id = GP_BRUSH_ICON_MARKER;
+       brush->gpencil_settings->brush_type = GP_BRUSH_TYPE_DRAW;
+
+       brush->smooth_stroke_radius = SMOOTH_STROKE_RADIUS;
+       brush->smooth_stroke_factor = SMOOTH_STROKE_FACTOR;
+
+       /* Fill brush */
+       brush = BKE_brush_add_gpencil(bmain, ts, "Fill Area");
+       brush->size = 1.0f;
+       brush->gpencil_settings->flag |= GP_BRUSH_ENABLE_CURSOR;
+       brush->gpencil_settings->draw_sensitivity = 1.0f;
+       brush->gpencil_settings->fill_leak = 3;
+       brush->gpencil_settings->fill_threshold = 0.1f;
+       brush->gpencil_settings->fill_simplylvl = 1;
+       brush->gpencil_settings->icon_id = GP_BRUSH_ICON_FILL;
+       brush->gpencil_settings->brush_type = GP_BRUSH_TYPE_FILL;
+
+       brush->gpencil_settings->draw_smoothfac = 0.5f;
+       brush->gpencil_settings->draw_smoothlvl = 1;
+       brush->gpencil_settings->thick_smoothfac = 1.0f;
+       brush->gpencil_settings->thick_smoothlvl = 3;
+       brush->gpencil_settings->draw_subdivide = 1;
+
+       brush->smooth_stroke_radius = SMOOTH_STROKE_RADIUS;
+       brush->smooth_stroke_factor = SMOOTH_STROKE_FACTOR;
+
+       brush->gpencil_settings->draw_strength = 1.0f;
+
+       /* Soft Eraser brush */
+       brush = BKE_brush_add_gpencil(bmain, ts, "Eraser Soft");
+       brush->size = 30.0f;
+       brush->gpencil_settings->flag |= (GP_BRUSH_ENABLE_CURSOR | GP_BRUSH_DEFAULT_ERASER);
+       brush->gpencil_settings->icon_id = GP_BRUSH_ICON_ERASE_SOFT;
+       brush->gpencil_settings->brush_type = GP_BRUSH_TYPE_ERASE;
+       brush->gpencil_settings->eraser_mode = GP_BRUSH_ERASER_SOFT;
+
+       /* Hard Eraser brush */
+       brush = BKE_brush_add_gpencil(bmain, ts, "Eraser Hard");
+       brush->size = 30.0f;
+       brush->gpencil_settings->flag |= GP_BRUSH_ENABLE_CURSOR;
+       brush->gpencil_settings->icon_id = GP_BRUSH_ICON_ERASE_HARD;
+       brush->gpencil_settings->brush_type = GP_BRUSH_TYPE_ERASE;
+       brush->gpencil_settings->eraser_mode = GP_BRUSH_ERASER_HARD;
+
+       /* Stroke Eraser brush */
+       brush = BKE_brush_add_gpencil(bmain, ts, "Eraser Stroke");
+       brush->size = 30.0f;
+       brush->gpencil_settings->flag |= GP_BRUSH_ENABLE_CURSOR;
+       brush->gpencil_settings->icon_id = GP_BRUSH_ICON_ERASE_STROKE;
+       brush->gpencil_settings->brush_type = GP_BRUSH_TYPE_ERASE;
+       brush->gpencil_settings->eraser_mode = GP_BRUSH_ERASER_STROKE;
+
+       /* set defaut brush */
+       BKE_paint_brush_set(paint, deft);
+
+}
+
+/* get the active gp-brush for editing */
+Brush *BKE_brush_getactive_gpencil(ToolSettings *ts)
+{
+       /* error checking */
+       if (ELEM(NULL, ts, ts->gp_paint)) {
+               return NULL;
+       }
+       Paint *paint = &ts->gp_paint->paint;
+
+       return paint->brush;
+}
+
 struct Brush *BKE_brush_first_search(struct Main *bmain, const eObjectMode ob_mode)
 {
        Brush *brush;
@@ -197,6 +562,12 @@ void BKE_brush_copy_data(Main *UNUSED(bmain), Brush *brush_dst, const Brush *bru
        }
 
        brush_dst->curve = curvemapping_copy(brush_src->curve);
+       if (brush_src->gpencil_settings != NULL) {
+               brush_dst->gpencil_settings = MEM_dupallocN(brush_src->gpencil_settings);
+               brush_dst->gpencil_settings->curve_sensitivity = curvemapping_copy(brush_src->gpencil_settings->curve_sensitivity);
+               brush_dst->gpencil_settings->curve_strength = curvemapping_copy(brush_src->gpencil_settings->curve_strength);
+               brush_dst->gpencil_settings->curve_jitter = curvemapping_copy(brush_src->gpencil_settings->curve_jitter);
+       }
 
        /* enable fake user by default */
        id_fake_user_set(&brush_dst->id);
@@ -215,11 +586,18 @@ void BKE_brush_free(Brush *brush)
        if (brush->icon_imbuf) {
                IMB_freeImBuf(brush->icon_imbuf);
        }
-
        curvemapping_free(brush->curve);
 
+       if (brush->gpencil_settings != NULL) {
+               curvemapping_free(brush->gpencil_settings->curve_sensitivity);
+               curvemapping_free(brush->gpencil_settings->curve_strength);
+               curvemapping_free(brush->gpencil_settings->curve_jitter);
+               MEM_SAFE_FREE(brush->gpencil_settings);
+       }
+
        MEM_SAFE_FREE(brush->gradient);
 
+
        BKE_previewimg_free(&(brush->preview));
 }
 
index ff4795a..d18572a 100644 (file)
@@ -282,6 +282,7 @@ void curvemap_reset(CurveMap *cuma, const rctf *clipr, int preset, int slope)
                case CURVE_PRESET_MID9: cuma->totpoint = 9; break;
                case CURVE_PRESET_ROUND: cuma->totpoint = 4; break;
                case CURVE_PRESET_ROOT: cuma->totpoint = 4; break;
+               case CURVE_PRESET_GAUSS: cuma->totpoint = 7; break;
        }
 
        cuma->curve = MEM_callocN(cuma->totpoint * sizeof(CurveMapPoint), "curve points");
@@ -352,6 +353,24 @@ void curvemap_reset(CurveMap *cuma, const rctf *clipr, int preset, int slope)
                        cuma->curve[3].x = 1;
                        cuma->curve[3].y = 0;
                        break;
+               case CURVE_PRESET_GAUSS:
+                       cuma->curve[0].x = 0;
+                       cuma->curve[0].y = 0.025f;
+                       cuma->curve[1].x = 0.16f;
+                       cuma->curve[1].y = 0.135f;
+                       cuma->curve[2].x = 0.298f;
+                       cuma->curve[2].y = 0.36f;
+
+                       cuma->curve[3].x = 0.50f;
+                       cuma->curve[3].y = 1.0f;
+
+                       cuma->curve[4].x = 0.70f;
+                       cuma->curve[4].y = 0.36f;
+                       cuma->curve[5].x = 0.84f;
+                       cuma->curve[5].y = 0.135f;
+                       cuma->curve[6].x = 1.0f;
+                       cuma->curve[6].y = 0.025f;
+                       break;
        }
 
        /* mirror curve in x direction to have positive slope