diff options
Diffstat (limited to 'release')
175 files changed, 4941 insertions, 2028 deletions
diff --git a/release/datafiles/brushicons/gp_brush_block.png b/release/datafiles/brushicons/gp_brush_block.png Binary files differnew file mode 100644 index 00000000000..2db3964e573 --- /dev/null +++ b/release/datafiles/brushicons/gp_brush_block.png diff --git a/release/datafiles/brushicons/gp_brush_clone.png b/release/datafiles/brushicons/gp_brush_clone.png Binary files differnew file mode 100644 index 00000000000..8358ace23b3 --- /dev/null +++ b/release/datafiles/brushicons/gp_brush_clone.png diff --git a/release/datafiles/brushicons/gp_brush_erase_hard.png b/release/datafiles/brushicons/gp_brush_erase_hard.png Binary files differnew file mode 100644 index 00000000000..2ac52840678 --- /dev/null +++ b/release/datafiles/brushicons/gp_brush_erase_hard.png diff --git a/release/datafiles/brushicons/gp_brush_erase_soft.png b/release/datafiles/brushicons/gp_brush_erase_soft.png Binary files differnew file mode 100644 index 00000000000..416923004dd --- /dev/null +++ b/release/datafiles/brushicons/gp_brush_erase_soft.png diff --git a/release/datafiles/brushicons/gp_brush_erase_stroke.png b/release/datafiles/brushicons/gp_brush_erase_stroke.png Binary files differnew file mode 100644 index 00000000000..cd6d21532cf --- /dev/null +++ b/release/datafiles/brushicons/gp_brush_erase_stroke.png diff --git a/release/datafiles/brushicons/gp_brush_fill.png b/release/datafiles/brushicons/gp_brush_fill.png Binary files differnew file mode 100644 index 00000000000..9dac633139c --- /dev/null +++ b/release/datafiles/brushicons/gp_brush_fill.png diff --git a/release/datafiles/brushicons/gp_brush_grab.png b/release/datafiles/brushicons/gp_brush_grab.png Binary files differnew file mode 100644 index 00000000000..2123ac69aef --- /dev/null +++ b/release/datafiles/brushicons/gp_brush_grab.png diff --git a/release/datafiles/brushicons/gp_brush_ink.png b/release/datafiles/brushicons/gp_brush_ink.png Binary files differnew file mode 100644 index 00000000000..410a77f6117 --- /dev/null +++ b/release/datafiles/brushicons/gp_brush_ink.png diff --git a/release/datafiles/brushicons/gp_brush_inknoise.png b/release/datafiles/brushicons/gp_brush_inknoise.png Binary files differnew file mode 100644 index 00000000000..5356f697e01 --- /dev/null +++ b/release/datafiles/brushicons/gp_brush_inknoise.png diff --git a/release/datafiles/brushicons/gp_brush_marker.png b/release/datafiles/brushicons/gp_brush_marker.png Binary files differnew file mode 100644 index 00000000000..c7a62b78ca7 --- /dev/null +++ b/release/datafiles/brushicons/gp_brush_marker.png diff --git a/release/datafiles/brushicons/gp_brush_pen.png b/release/datafiles/brushicons/gp_brush_pen.png Binary files differnew file mode 100644 index 00000000000..9aaaa861f49 --- /dev/null +++ b/release/datafiles/brushicons/gp_brush_pen.png diff --git a/release/datafiles/brushicons/gp_brush_pencil.png b/release/datafiles/brushicons/gp_brush_pencil.png Binary files differnew file mode 100644 index 00000000000..2d1fbdfd916 --- /dev/null +++ b/release/datafiles/brushicons/gp_brush_pencil.png diff --git a/release/datafiles/brushicons/gp_brush_pinch.png b/release/datafiles/brushicons/gp_brush_pinch.png Binary files differnew file mode 100644 index 00000000000..e38236d1be0 --- /dev/null +++ b/release/datafiles/brushicons/gp_brush_pinch.png diff --git a/release/datafiles/brushicons/gp_brush_push.png b/release/datafiles/brushicons/gp_brush_push.png Binary files differnew file mode 100644 index 00000000000..542764309cc --- /dev/null +++ b/release/datafiles/brushicons/gp_brush_push.png diff --git a/release/datafiles/brushicons/gp_brush_randomize.png b/release/datafiles/brushicons/gp_brush_randomize.png Binary files differnew file mode 100644 index 00000000000..0dd1a131d86 --- /dev/null +++ b/release/datafiles/brushicons/gp_brush_randomize.png diff --git a/release/datafiles/brushicons/gp_brush_smooth.png b/release/datafiles/brushicons/gp_brush_smooth.png Binary files differnew file mode 100644 index 00000000000..7518a358219 --- /dev/null +++ b/release/datafiles/brushicons/gp_brush_smooth.png diff --git a/release/datafiles/brushicons/gp_brush_strength.png b/release/datafiles/brushicons/gp_brush_strength.png Binary files differnew file mode 100644 index 00000000000..a0513119f29 --- /dev/null +++ b/release/datafiles/brushicons/gp_brush_strength.png diff --git a/release/datafiles/brushicons/gp_brush_thickness.png b/release/datafiles/brushicons/gp_brush_thickness.png Binary files differnew file mode 100644 index 00000000000..6026716f026 --- /dev/null +++ b/release/datafiles/brushicons/gp_brush_thickness.png diff --git a/release/datafiles/brushicons/gp_brush_twist.png b/release/datafiles/brushicons/gp_brush_twist.png Binary files differnew file mode 100644 index 00000000000..84b9a90e9d6 --- /dev/null +++ b/release/datafiles/brushicons/gp_brush_twist.png diff --git a/release/datafiles/brushicons/gp_brush_weight.png b/release/datafiles/brushicons/gp_brush_weight.png Binary files differnew file mode 100644 index 00000000000..171e9221e92 --- /dev/null +++ b/release/datafiles/brushicons/gp_brush_weight.png diff --git a/release/datafiles/colormanagement/config.ocio b/release/datafiles/colormanagement/config.ocio index ce79dfeb540..c8466ab99fc 100644 --- a/release/datafiles/colormanagement/config.ocio +++ b/release/datafiles/colormanagement/config.ocio @@ -70,7 +70,7 @@ displays: - !<View> {name: Default, colorspace: Raw} active_displays: [sRGB, DCIP3, Rec709, XYZ, None] -active_views: [Default, RRT, Raw, Log] +active_views: [Filmic, Default, RRT, Raw, Log] colorspaces: - !<ColorSpace> diff --git a/release/datafiles/icons/brush.gpencil.draw.eraser_hard.dat b/release/datafiles/icons/brush.gpencil.draw.eraser_hard.dat Binary files differnew file mode 100644 index 00000000000..1e909ca8ac9 --- /dev/null +++ b/release/datafiles/icons/brush.gpencil.draw.eraser_hard.dat diff --git a/release/datafiles/icons/brush.gpencil.draw.eraser_soft.dat b/release/datafiles/icons/brush.gpencil.draw.eraser_soft.dat Binary files differnew file mode 100644 index 00000000000..7242f76a0f9 --- /dev/null +++ b/release/datafiles/icons/brush.gpencil.draw.eraser_soft.dat diff --git a/release/datafiles/icons/brush.gpencil.draw.eraser_stroke.dat b/release/datafiles/icons/brush.gpencil.draw.eraser_stroke.dat Binary files differnew file mode 100644 index 00000000000..6bf620bf3c2 --- /dev/null +++ b/release/datafiles/icons/brush.gpencil.draw.eraser_stroke.dat diff --git a/release/datafiles/icons/brush.gpencil.draw_block.dat b/release/datafiles/icons/brush.gpencil.draw_block.dat Binary files differnew file mode 100644 index 00000000000..7a7402ef673 --- /dev/null +++ b/release/datafiles/icons/brush.gpencil.draw_block.dat diff --git a/release/datafiles/icons/brush.gpencil.draw_fill.dat b/release/datafiles/icons/brush.gpencil.draw_fill.dat Binary files differnew file mode 100644 index 00000000000..809aed7f3cf --- /dev/null +++ b/release/datafiles/icons/brush.gpencil.draw_fill.dat diff --git a/release/datafiles/icons/brush.gpencil.draw_ink.dat b/release/datafiles/icons/brush.gpencil.draw_ink.dat Binary files differnew file mode 100644 index 00000000000..3c654712783 --- /dev/null +++ b/release/datafiles/icons/brush.gpencil.draw_ink.dat diff --git a/release/datafiles/icons/brush.gpencil.draw_marker.dat b/release/datafiles/icons/brush.gpencil.draw_marker.dat Binary files differnew file mode 100644 index 00000000000..77a52dd83d4 --- /dev/null +++ b/release/datafiles/icons/brush.gpencil.draw_marker.dat diff --git a/release/datafiles/icons/brush.gpencil.draw_noise.dat b/release/datafiles/icons/brush.gpencil.draw_noise.dat Binary files differnew file mode 100644 index 00000000000..127f469b9fb --- /dev/null +++ b/release/datafiles/icons/brush.gpencil.draw_noise.dat diff --git a/release/datafiles/icons/brush.gpencil.draw_pen.dat b/release/datafiles/icons/brush.gpencil.draw_pen.dat Binary files differnew file mode 100644 index 00000000000..cb6fb77924a --- /dev/null +++ b/release/datafiles/icons/brush.gpencil.draw_pen.dat diff --git a/release/datafiles/icons/brush.gpencil.draw_pencil.dat b/release/datafiles/icons/brush.gpencil.draw_pencil.dat Binary files differnew file mode 100644 index 00000000000..a8898a94917 --- /dev/null +++ b/release/datafiles/icons/brush.gpencil.draw_pencil.dat diff --git a/release/datafiles/icons/brush.particle.add.dat b/release/datafiles/icons/brush.particle.add.dat Binary files differnew file mode 100644 index 00000000000..e78bf251371 --- /dev/null +++ b/release/datafiles/icons/brush.particle.add.dat diff --git a/release/datafiles/icons/brush.particle.comb.dat b/release/datafiles/icons/brush.particle.comb.dat Binary files differnew file mode 100644 index 00000000000..5ece6bf754d --- /dev/null +++ b/release/datafiles/icons/brush.particle.comb.dat diff --git a/release/datafiles/icons/brush.particle.cut.dat b/release/datafiles/icons/brush.particle.cut.dat Binary files differnew file mode 100644 index 00000000000..79306d5d7e9 --- /dev/null +++ b/release/datafiles/icons/brush.particle.cut.dat diff --git a/release/datafiles/icons/brush.particle.length.dat b/release/datafiles/icons/brush.particle.length.dat Binary files differnew file mode 100644 index 00000000000..4c9da271316 --- /dev/null +++ b/release/datafiles/icons/brush.particle.length.dat diff --git a/release/datafiles/icons/brush.particle.puff.dat b/release/datafiles/icons/brush.particle.puff.dat Binary files differnew file mode 100644 index 00000000000..b0e797853c3 --- /dev/null +++ b/release/datafiles/icons/brush.particle.puff.dat diff --git a/release/datafiles/icons/brush.particle.smooth.dat b/release/datafiles/icons/brush.particle.smooth.dat Binary files differnew file mode 100644 index 00000000000..a3cbe3cf657 --- /dev/null +++ b/release/datafiles/icons/brush.particle.smooth.dat diff --git a/release/datafiles/icons/brush.particle.weight.dat b/release/datafiles/icons/brush.particle.weight.dat Binary files differnew file mode 100644 index 00000000000..309ee157a19 --- /dev/null +++ b/release/datafiles/icons/brush.particle.weight.dat diff --git a/release/datafiles/icons/ops.gpencil.draw.dat b/release/datafiles/icons/ops.gpencil.draw.dat Binary files differnew file mode 100644 index 00000000000..3adc50ab17d --- /dev/null +++ b/release/datafiles/icons/ops.gpencil.draw.dat diff --git a/release/datafiles/icons/ops.gpencil.draw.eraser.dat b/release/datafiles/icons/ops.gpencil.draw.eraser.dat Binary files differnew file mode 100644 index 00000000000..323d8c23245 --- /dev/null +++ b/release/datafiles/icons/ops.gpencil.draw.eraser.dat diff --git a/release/datafiles/icons/ops.gpencil.draw.line.dat b/release/datafiles/icons/ops.gpencil.draw.line.dat Binary files differnew file mode 100644 index 00000000000..238db63807a --- /dev/null +++ b/release/datafiles/icons/ops.gpencil.draw.line.dat diff --git a/release/datafiles/icons/ops.gpencil.draw.poly.dat b/release/datafiles/icons/ops.gpencil.draw.poly.dat Binary files differnew file mode 100644 index 00000000000..8351e48fec1 --- /dev/null +++ b/release/datafiles/icons/ops.gpencil.draw.poly.dat diff --git a/release/datafiles/icons/ops.gpencil.edit_bend.dat b/release/datafiles/icons/ops.gpencil.edit_bend.dat Binary files differnew file mode 100644 index 00000000000..32f7b2e9631 --- /dev/null +++ b/release/datafiles/icons/ops.gpencil.edit_bend.dat diff --git a/release/datafiles/icons/ops.gpencil.edit_mirror.dat b/release/datafiles/icons/ops.gpencil.edit_mirror.dat Binary files differnew file mode 100644 index 00000000000..ee073664f78 --- /dev/null +++ b/release/datafiles/icons/ops.gpencil.edit_mirror.dat diff --git a/release/datafiles/icons/ops.gpencil.edit_shear.dat b/release/datafiles/icons/ops.gpencil.edit_shear.dat Binary files differnew file mode 100644 index 00000000000..e6b51f988f8 --- /dev/null +++ b/release/datafiles/icons/ops.gpencil.edit_shear.dat diff --git a/release/datafiles/icons/ops.gpencil.edit_to_sphere.dat b/release/datafiles/icons/ops.gpencil.edit_to_sphere.dat Binary files differnew file mode 100644 index 00000000000..bf1181cd500 --- /dev/null +++ b/release/datafiles/icons/ops.gpencil.edit_to_sphere.dat diff --git a/release/datafiles/icons/ops.gpencil.sculpt_clone.dat b/release/datafiles/icons/ops.gpencil.sculpt_clone.dat Binary files differnew file mode 100644 index 00000000000..dbae6a68159 --- /dev/null +++ b/release/datafiles/icons/ops.gpencil.sculpt_clone.dat diff --git a/release/datafiles/icons/ops.gpencil.sculpt_grab.dat b/release/datafiles/icons/ops.gpencil.sculpt_grab.dat Binary files differnew file mode 100644 index 00000000000..291b4fd12dc --- /dev/null +++ b/release/datafiles/icons/ops.gpencil.sculpt_grab.dat diff --git a/release/datafiles/icons/ops.gpencil.sculpt_pinch.dat b/release/datafiles/icons/ops.gpencil.sculpt_pinch.dat Binary files differnew file mode 100644 index 00000000000..cb2b43f5597 --- /dev/null +++ b/release/datafiles/icons/ops.gpencil.sculpt_pinch.dat diff --git a/release/datafiles/icons/ops.gpencil.sculpt_push.dat b/release/datafiles/icons/ops.gpencil.sculpt_push.dat Binary files differnew file mode 100644 index 00000000000..e1c4961ff86 --- /dev/null +++ b/release/datafiles/icons/ops.gpencil.sculpt_push.dat diff --git a/release/datafiles/icons/ops.gpencil.sculpt_randomize.dat b/release/datafiles/icons/ops.gpencil.sculpt_randomize.dat Binary files differnew file mode 100644 index 00000000000..35042936757 --- /dev/null +++ b/release/datafiles/icons/ops.gpencil.sculpt_randomize.dat diff --git a/release/datafiles/icons/ops.gpencil.sculpt_smooth.dat b/release/datafiles/icons/ops.gpencil.sculpt_smooth.dat Binary files differnew file mode 100644 index 00000000000..3a132ed4049 --- /dev/null +++ b/release/datafiles/icons/ops.gpencil.sculpt_smooth.dat diff --git a/release/datafiles/icons/ops.gpencil.sculpt_strength.dat b/release/datafiles/icons/ops.gpencil.sculpt_strength.dat Binary files differnew file mode 100644 index 00000000000..7e52b0d7648 --- /dev/null +++ b/release/datafiles/icons/ops.gpencil.sculpt_strength.dat diff --git a/release/datafiles/icons/ops.gpencil.sculpt_thickness.dat b/release/datafiles/icons/ops.gpencil.sculpt_thickness.dat Binary files differnew file mode 100644 index 00000000000..1e558806888 --- /dev/null +++ b/release/datafiles/icons/ops.gpencil.sculpt_thickness.dat diff --git a/release/datafiles/icons/ops.gpencil.sculpt_twist.dat b/release/datafiles/icons/ops.gpencil.sculpt_twist.dat Binary files differnew file mode 100644 index 00000000000..4ce958cb7ec --- /dev/null +++ b/release/datafiles/icons/ops.gpencil.sculpt_twist.dat diff --git a/release/datafiles/icons/ops.gpencil.sculpt_weight.dat b/release/datafiles/icons/ops.gpencil.sculpt_weight.dat Binary files differnew file mode 100644 index 00000000000..41b58abfda7 --- /dev/null +++ b/release/datafiles/icons/ops.gpencil.sculpt_weight.dat diff --git a/release/datafiles/locale b/release/datafiles/locale -Subproject d3349b42856d00c278f72f2a5909a6c96b9cdb5 +Subproject 59495b4b59077aa1cc68fffbdae1463af980f08 diff --git a/release/datafiles/preview_grease_pencil.blend b/release/datafiles/preview_grease_pencil.blend Binary files differnew file mode 100644 index 00000000000..82661d80029 --- /dev/null +++ b/release/datafiles/preview_grease_pencil.blend diff --git a/release/datafiles/studiolights/matcap/basic_1.exr b/release/datafiles/studiolights/matcap/basic_1.exr Binary files differnew file mode 100644 index 00000000000..bb2e09abbd2 --- /dev/null +++ b/release/datafiles/studiolights/matcap/basic_1.exr diff --git a/release/datafiles/studiolights/matcap/basic_2.exr b/release/datafiles/studiolights/matcap/basic_2.exr Binary files differnew file mode 100644 index 00000000000..d97f7630d63 --- /dev/null +++ b/release/datafiles/studiolights/matcap/basic_2.exr diff --git a/release/datafiles/studiolights/matcap/basic_dark.exr b/release/datafiles/studiolights/matcap/basic_dark.exr Binary files differnew file mode 100644 index 00000000000..b623c8030f8 --- /dev/null +++ b/release/datafiles/studiolights/matcap/basic_dark.exr diff --git a/release/datafiles/studiolights/matcap/basic_side.exr b/release/datafiles/studiolights/matcap/basic_side.exr Binary files differnew file mode 100644 index 00000000000..6e4452e7511 --- /dev/null +++ b/release/datafiles/studiolights/matcap/basic_side.exr diff --git a/release/datafiles/studiolights/matcap/ceramic_dark.exr b/release/datafiles/studiolights/matcap/ceramic_dark.exr Binary files differnew file mode 100644 index 00000000000..837b020c96d --- /dev/null +++ b/release/datafiles/studiolights/matcap/ceramic_dark.exr diff --git a/release/datafiles/studiolights/matcap/ceramic_lightbulb.exr b/release/datafiles/studiolights/matcap/ceramic_lightbulb.exr Binary files differnew file mode 100644 index 00000000000..e05b6612e46 --- /dev/null +++ b/release/datafiles/studiolights/matcap/ceramic_lightbulb.exr diff --git a/release/datafiles/studiolights/matcap/check_normal+y.exr b/release/datafiles/studiolights/matcap/check_normal+y.exr Binary files differnew file mode 100644 index 00000000000..4e2a97ac3b9 --- /dev/null +++ b/release/datafiles/studiolights/matcap/check_normal+y.exr diff --git a/release/datafiles/studiolights/matcap/check_reflection.exr b/release/datafiles/studiolights/matcap/check_reflection.exr Binary files differnew file mode 100644 index 00000000000..245d6059241 --- /dev/null +++ b/release/datafiles/studiolights/matcap/check_reflection.exr diff --git a/release/datafiles/studiolights/matcap/check_rim_dark.exr b/release/datafiles/studiolights/matcap/check_rim_dark.exr Binary files differnew file mode 100644 index 00000000000..e6a32004ea1 --- /dev/null +++ b/release/datafiles/studiolights/matcap/check_rim_dark.exr diff --git a/release/datafiles/studiolights/matcap/check_rim_light.exr b/release/datafiles/studiolights/matcap/check_rim_light.exr Binary files differnew file mode 100644 index 00000000000..6318c0f9346 --- /dev/null +++ b/release/datafiles/studiolights/matcap/check_rim_light.exr diff --git a/release/datafiles/studiolights/matcap/clay_brown.exr b/release/datafiles/studiolights/matcap/clay_brown.exr Binary files differnew file mode 100644 index 00000000000..fe1e0305383 --- /dev/null +++ b/release/datafiles/studiolights/matcap/clay_brown.exr diff --git a/release/datafiles/studiolights/matcap/clay_muddy.exr b/release/datafiles/studiolights/matcap/clay_muddy.exr Binary files differnew file mode 100644 index 00000000000..d219578c62b --- /dev/null +++ b/release/datafiles/studiolights/matcap/clay_muddy.exr diff --git a/release/datafiles/studiolights/matcap/clay_studio.exr b/release/datafiles/studiolights/matcap/clay_studio.exr Binary files differnew file mode 100644 index 00000000000..7746e6d0e35 --- /dev/null +++ b/release/datafiles/studiolights/matcap/clay_studio.exr diff --git a/release/datafiles/studiolights/matcap/jade.exr b/release/datafiles/studiolights/matcap/jade.exr Binary files differnew file mode 100644 index 00000000000..fe1211f1b65 --- /dev/null +++ b/release/datafiles/studiolights/matcap/jade.exr diff --git a/release/datafiles/studiolights/matcap/license.txt b/release/datafiles/studiolights/matcap/license.txt index 358c8dcd832..09a0f7a439e 100644 --- a/release/datafiles/studiolights/matcap/license.txt +++ b/release/datafiles/studiolights/matcap/license.txt @@ -1,3 +1,3 @@ -These matcap images are licensed as GNU GPL 2 or later, like the rest of Blender's code. +These matcap images are licensed as CC0 or public domain. -Thanks to Kent Trammell, Aidy Burrows, John Herreno , Terry Wallwork and David Silverman for making the pictures. +Thanks to the Blender community for contributing these matcaps. diff --git a/release/datafiles/studiolights/matcap/mc01.jpg b/release/datafiles/studiolights/matcap/mc01.jpg Binary files differdeleted file mode 100644 index 8c7aef287ee..00000000000 --- a/release/datafiles/studiolights/matcap/mc01.jpg +++ /dev/null diff --git a/release/datafiles/studiolights/matcap/mc02.jpg b/release/datafiles/studiolights/matcap/mc02.jpg Binary files differdeleted file mode 100644 index 11deddfeaed..00000000000 --- a/release/datafiles/studiolights/matcap/mc02.jpg +++ /dev/null diff --git a/release/datafiles/studiolights/matcap/mc03.jpg b/release/datafiles/studiolights/matcap/mc03.jpg Binary files differdeleted file mode 100644 index 64d992fb61a..00000000000 --- a/release/datafiles/studiolights/matcap/mc03.jpg +++ /dev/null diff --git a/release/datafiles/studiolights/matcap/mc04.jpg b/release/datafiles/studiolights/matcap/mc04.jpg Binary files differdeleted file mode 100644 index 42be580ee93..00000000000 --- a/release/datafiles/studiolights/matcap/mc04.jpg +++ /dev/null diff --git a/release/datafiles/studiolights/matcap/mc05.jpg b/release/datafiles/studiolights/matcap/mc05.jpg Binary files differdeleted file mode 100644 index 586d233ef31..00000000000 --- a/release/datafiles/studiolights/matcap/mc05.jpg +++ /dev/null diff --git a/release/datafiles/studiolights/matcap/mc06.jpg b/release/datafiles/studiolights/matcap/mc06.jpg Binary files differdeleted file mode 100644 index 657883d0866..00000000000 --- a/release/datafiles/studiolights/matcap/mc06.jpg +++ /dev/null diff --git a/release/datafiles/studiolights/matcap/mc07.jpg b/release/datafiles/studiolights/matcap/mc07.jpg Binary files differdeleted file mode 100644 index 372caf7e87c..00000000000 --- a/release/datafiles/studiolights/matcap/mc07.jpg +++ /dev/null diff --git a/release/datafiles/studiolights/matcap/mc08.jpg b/release/datafiles/studiolights/matcap/mc08.jpg Binary files differdeleted file mode 100644 index 50eec402812..00000000000 --- a/release/datafiles/studiolights/matcap/mc08.jpg +++ /dev/null diff --git a/release/datafiles/studiolights/matcap/mc09.jpg b/release/datafiles/studiolights/matcap/mc09.jpg Binary files differdeleted file mode 100644 index e05d441aaf9..00000000000 --- a/release/datafiles/studiolights/matcap/mc09.jpg +++ /dev/null diff --git a/release/datafiles/studiolights/matcap/mc10.jpg b/release/datafiles/studiolights/matcap/mc10.jpg Binary files differdeleted file mode 100644 index ab82f17bb93..00000000000 --- a/release/datafiles/studiolights/matcap/mc10.jpg +++ /dev/null diff --git a/release/datafiles/studiolights/matcap/mc11.jpg b/release/datafiles/studiolights/matcap/mc11.jpg Binary files differdeleted file mode 100644 index 053550f082c..00000000000 --- a/release/datafiles/studiolights/matcap/mc11.jpg +++ /dev/null diff --git a/release/datafiles/studiolights/matcap/mc12.jpg b/release/datafiles/studiolights/matcap/mc12.jpg Binary files differdeleted file mode 100644 index beb16f3742e..00000000000 --- a/release/datafiles/studiolights/matcap/mc12.jpg +++ /dev/null diff --git a/release/datafiles/studiolights/matcap/mc13.jpg b/release/datafiles/studiolights/matcap/mc13.jpg Binary files differdeleted file mode 100644 index 7fb8fa58e8f..00000000000 --- a/release/datafiles/studiolights/matcap/mc13.jpg +++ /dev/null diff --git a/release/datafiles/studiolights/matcap/mc14.jpg b/release/datafiles/studiolights/matcap/mc14.jpg Binary files differdeleted file mode 100644 index ba868d2f95a..00000000000 --- a/release/datafiles/studiolights/matcap/mc14.jpg +++ /dev/null diff --git a/release/datafiles/studiolights/matcap/mc15.jpg b/release/datafiles/studiolights/matcap/mc15.jpg Binary files differdeleted file mode 100644 index b10ea326a42..00000000000 --- a/release/datafiles/studiolights/matcap/mc15.jpg +++ /dev/null diff --git a/release/datafiles/studiolights/matcap/mc16.jpg b/release/datafiles/studiolights/matcap/mc16.jpg Binary files differdeleted file mode 100644 index c6ce02d59df..00000000000 --- a/release/datafiles/studiolights/matcap/mc16.jpg +++ /dev/null diff --git a/release/datafiles/studiolights/matcap/mc17.jpg b/release/datafiles/studiolights/matcap/mc17.jpg Binary files differdeleted file mode 100644 index 14f15f70460..00000000000 --- a/release/datafiles/studiolights/matcap/mc17.jpg +++ /dev/null diff --git a/release/datafiles/studiolights/matcap/mc18.jpg b/release/datafiles/studiolights/matcap/mc18.jpg Binary files differdeleted file mode 100644 index db572856b07..00000000000 --- a/release/datafiles/studiolights/matcap/mc18.jpg +++ /dev/null diff --git a/release/datafiles/studiolights/matcap/mc19.jpg b/release/datafiles/studiolights/matcap/mc19.jpg Binary files differdeleted file mode 100644 index 56d2efb1734..00000000000 --- a/release/datafiles/studiolights/matcap/mc19.jpg +++ /dev/null diff --git a/release/datafiles/studiolights/matcap/mc20.jpg b/release/datafiles/studiolights/matcap/mc20.jpg Binary files differdeleted file mode 100644 index 002a0910dd9..00000000000 --- a/release/datafiles/studiolights/matcap/mc20.jpg +++ /dev/null diff --git a/release/datafiles/studiolights/matcap/mc21.jpg b/release/datafiles/studiolights/matcap/mc21.jpg Binary files differdeleted file mode 100644 index cb2fea573b8..00000000000 --- a/release/datafiles/studiolights/matcap/mc21.jpg +++ /dev/null diff --git a/release/datafiles/studiolights/matcap/mc22.jpg b/release/datafiles/studiolights/matcap/mc22.jpg Binary files differdeleted file mode 100644 index 2fc71b98c5a..00000000000 --- a/release/datafiles/studiolights/matcap/mc22.jpg +++ /dev/null diff --git a/release/datafiles/studiolights/matcap/mc23.jpg b/release/datafiles/studiolights/matcap/mc23.jpg Binary files differdeleted file mode 100644 index 3793c0fcaa5..00000000000 --- a/release/datafiles/studiolights/matcap/mc23.jpg +++ /dev/null diff --git a/release/datafiles/studiolights/matcap/mc24.jpg b/release/datafiles/studiolights/matcap/mc24.jpg Binary files differdeleted file mode 100644 index 2a9618d8fe1..00000000000 --- a/release/datafiles/studiolights/matcap/mc24.jpg +++ /dev/null diff --git a/release/datafiles/studiolights/matcap/metal_anisotropic.exr b/release/datafiles/studiolights/matcap/metal_anisotropic.exr Binary files differnew file mode 100644 index 00000000000..38ea94ac676 --- /dev/null +++ b/release/datafiles/studiolights/matcap/metal_anisotropic.exr diff --git a/release/datafiles/studiolights/matcap/metal_carpaint.exr b/release/datafiles/studiolights/matcap/metal_carpaint.exr Binary files differnew file mode 100644 index 00000000000..c5bcdf67abf --- /dev/null +++ b/release/datafiles/studiolights/matcap/metal_carpaint.exr diff --git a/release/datafiles/studiolights/matcap/metal_lead.exr b/release/datafiles/studiolights/matcap/metal_lead.exr Binary files differnew file mode 100644 index 00000000000..4d6b2954ccd --- /dev/null +++ b/release/datafiles/studiolights/matcap/metal_lead.exr diff --git a/release/datafiles/studiolights/matcap/metal_shiny.exr b/release/datafiles/studiolights/matcap/metal_shiny.exr Binary files differnew file mode 100644 index 00000000000..3b5d20ffda2 --- /dev/null +++ b/release/datafiles/studiolights/matcap/metal_shiny.exr diff --git a/release/datafiles/studiolights/matcap/pearl.exr b/release/datafiles/studiolights/matcap/pearl.exr Binary files differnew file mode 100644 index 00000000000..e657c67936e --- /dev/null +++ b/release/datafiles/studiolights/matcap/pearl.exr diff --git a/release/datafiles/studiolights/matcap/resin.exr b/release/datafiles/studiolights/matcap/resin.exr Binary files differnew file mode 100644 index 00000000000..80e405aaa67 --- /dev/null +++ b/release/datafiles/studiolights/matcap/resin.exr diff --git a/release/datafiles/studiolights/matcap/skin.exr b/release/datafiles/studiolights/matcap/skin.exr Binary files differnew file mode 100644 index 00000000000..ffc3213dad9 --- /dev/null +++ b/release/datafiles/studiolights/matcap/skin.exr diff --git a/release/datafiles/studiolights/matcap/toon.exr b/release/datafiles/studiolights/matcap/toon.exr Binary files differnew file mode 100644 index 00000000000..242f5055e2b --- /dev/null +++ b/release/datafiles/studiolights/matcap/toon.exr diff --git a/release/datafiles/userdef/userdef_default_theme.c b/release/datafiles/userdef/userdef_default_theme.c index 11a9fbaca00..69ad58ea1c5 100644 --- a/release/datafiles/userdef/userdef_default_theme.c +++ b/release/datafiles/userdef/userdef_default_theme.c @@ -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), }, - }, +}, }; diff --git a/release/scripts/addons b/release/scripts/addons -Subproject ebd058d7a6438d137522063bb3286c8acc325ca +Subproject 371960484a38fc64e0a2635170a41a0d8ab2f6b diff --git a/release/scripts/modules/addon_utils.py b/release/scripts/modules/addon_utils.py index 86185b96e9d..f73d23c150b 100644 --- a/release/scripts/modules/addon_utils.py +++ b/release/scripts/modules/addon_utils.py @@ -367,14 +367,14 @@ def enable(module_name, *, default_set=False, persistent=False, handle_error=Non # Silent default, we know these need updating. if module_name in { - "io_anim_bvh", - "io_mesh_ply", - "io_mesh_stl", - "io_mesh_uv_layout", - "io_scene_3ds", - "io_scene_fbx", - "io_scene_obj", - "io_scene_x3d", + "io_anim_bvh", + "io_mesh_ply", + "io_mesh_stl", + "io_mesh_uv_layout", + "io_scene_3ds", + "io_scene_fbx", + "io_scene_obj", + "io_scene_x3d", }: return None diff --git a/release/scripts/modules/bpy_extras/keyconfig_utils.py b/release/scripts/modules/bpy_extras/keyconfig_utils.py index 6859e327b66..ec4db69986c 100644 --- a/release/scripts/modules/bpy_extras/keyconfig_utils.py +++ b/release/scripts/modules/bpy_extras/keyconfig_utils.py @@ -56,6 +56,7 @@ KM_HIERARCHY = [ ('Particle', 'EMPTY', 'WINDOW', []), ('Knife Tool Modal Map', 'EMPTY', 'WINDOW', []), + ('Custom Normals Modal Map', 'EMPTY', 'WINDOW', []), ('Paint Stroke Modal', 'EMPTY', 'WINDOW', []), ('Paint Curve', 'EMPTY', 'WINDOW', []), @@ -121,6 +122,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) diff --git a/release/scripts/modules/bpy_extras/object_utils.py b/release/scripts/modules/bpy_extras/object_utils.py index 7719e2f6e30..c9ea684862d 100644 --- a/release/scripts/modules/bpy_extras/object_utils.py +++ b/release/scripts/modules/bpy_extras/object_utils.py @@ -100,7 +100,7 @@ def add_object_align_init(context, operator): if operator: properties.rotation = rotation.to_euler() - return location * rotation + return location @ rotation def object_data_add(context, obdata, operator=None, name=None): @@ -166,7 +166,7 @@ def object_data_add(context, obdata, operator=None, name=None): obj_act.select_set(action='SELECT') scene.update() # apply location - # scene.objects.active = obj_new + # layer.objects.active = obj_new # Match up UV layers, this is needed so adding an object with UV's # doesn't create new layers when there happens to be a naming mis-match. diff --git a/release/scripts/modules/bpy_extras/view3d_utils.py b/release/scripts/modules/bpy_extras/view3d_utils.py index a4834a4531c..a2e394b270f 100644 --- a/release/scripts/modules/bpy_extras/view3d_utils.py +++ b/release/scripts/modules/bpy_extras/view3d_utils.py @@ -54,7 +54,7 @@ def region_2d_to_vector_3d(region, rv3d, coord): w = out.dot(persinv[3].xyz) + persinv[3][3] - view_vector = ((persinv * out) / w) - viewinv.translation + view_vector = ((persinv @ out) / w) - viewinv.translation else: view_vector = -viewinv.col[2].xyz @@ -179,7 +179,7 @@ def location_3d_to_region_2d(region, rv3d, coord, default=None): """ from mathutils import Vector - prj = rv3d.perspective_matrix * Vector((coord[0], coord[1], coord[2], 1.0)) + prj = rv3d.perspective_matrix @ Vector((coord[0], coord[1], coord[2], 1.0)) if prj.w > 0.0: width_half = region.width / 2.0 height_half = region.height / 2.0 diff --git a/release/scripts/modules/bpy_types.py b/release/scripts/modules/bpy_types.py index f4fd188c641..96193b047c6 100644 --- a/release/scripts/modules/bpy_types.py +++ b/release/scripts/modules/bpy_types.py @@ -205,21 +205,21 @@ class _GenericBone: """ Vector pointing down the x-axis of the bone. """ from mathutils import Vector - return self.matrix.to_3x3() * Vector((1.0, 0.0, 0.0)) + return self.matrix.to_3x3() @ Vector((1.0, 0.0, 0.0)) @property def y_axis(self): """ Vector pointing down the y-axis of the bone. """ from mathutils import Vector - return self.matrix.to_3x3() * Vector((0.0, 1.0, 0.0)) + return self.matrix.to_3x3() @ Vector((0.0, 1.0, 0.0)) @property def z_axis(self): """ Vector pointing down the z-axis of the bone. """ from mathutils import Vector - return self.matrix.to_3x3() * Vector((0.0, 0.0, 1.0)) + return self.matrix.to_3x3() @ Vector((0.0, 0.0, 1.0)) @property def basename(self): @@ -378,9 +378,9 @@ class EditBone(StructRNA, _GenericBone, metaclass=StructMetaPropGroup): :type roll: bool """ from mathutils import Vector - z_vec = self.matrix.to_3x3() * Vector((0.0, 0.0, 1.0)) - self.tail = matrix * self.tail - self.head = matrix * self.head + z_vec = self.matrix.to_3x3() @ Vector((0.0, 0.0, 1.0)) + self.tail = matrix @ self.tail + self.head = matrix @ self.head if scale: scalar = matrix.median_scale @@ -388,7 +388,7 @@ class EditBone(StructRNA, _GenericBone, metaclass=StructMetaPropGroup): self.tail_radius *= scalar if roll: - self.align_roll(matrix * z_vec) + self.align_roll(matrix @ z_vec) def ord_ind(i1, i2): @@ -587,7 +587,7 @@ class Gizmo(StructRNA): _rna_gizmo_target_get_range as target_get_range, ) - # Convenience wrappers around private `_gawain` module. + # Convenience wrappers around private `_gpu` module. def draw_custom_shape(self, shape, *, matrix=None, select_id=None): """ Draw a shape created form :class:`bpy.types.Gizmo.draw_custom_shape`. @@ -638,19 +638,19 @@ class Gizmo(StructRNA): :return: The newly created shape. :rtype: Undefined (it may change). """ - from _gawain.types import ( - Gwn_Batch, - Gwn_VertBuf, - Gwn_VertFormat, + from _gpu.types import ( + GPUBatch, + GPUVertBuf, + GPUVertFormat, ) dims = len(verts[0]) if dims not in {2, 3}: raise ValueError("Expected 2D or 3D vertex") - fmt = Gwn_VertFormat() + fmt = GPUVertFormat() pos_id = fmt.attr_add(id="pos", comp_type='F32', len=dims, fetch_mode='FLOAT') - vbo = Gwn_VertBuf(len=len(verts), format=fmt) + vbo = GPUVertBuf(len=len(verts), format=fmt) vbo.fill(id=pos_id, data=verts) - batch = Gwn_Batch(type=type, buf=vbo) + batch = GPUBatch(type=type, buf=vbo) return (batch, dims) diff --git a/release/scripts/modules/rna_prop_ui.py b/release/scripts/modules/rna_prop_ui.py index bdb0751c973..0d17c11456e 100644 --- a/release/scripts/modules/rna_prop_ui.py +++ b/release/scripts/modules/rna_prop_ui.py @@ -132,6 +132,11 @@ def draw(layout, context, context_member, property_type, use_edit=True): show_developer_ui = context.user_preferences.view.show_developer_ui rna_properties = {prop.identifier for prop in rna_item.bl_rna.properties if prop.is_runtime} if items else None + layout.use_property_split = True + layout.use_property_decorate = False # No animation. + + flow = layout.grid_flow(row_major=False, columns=0, even_columns=True, even_rows=False, align=True) + for key, val in items: if key == '_RNA_UI': @@ -143,7 +148,6 @@ def draw(layout, context, context_member, property_type, use_edit=True): if is_rna and not show_developer_ui: continue - row = layout.row() to_dict = getattr(val, "to_dict", None) to_list = getattr(val, "to_list", None) @@ -157,17 +161,20 @@ def draw(layout, context, context_member, property_type, use_edit=True): else: val_draw = val + row = flow.row(align=True) box = row.box() if use_edit: split = box.split(percentage=0.75) - row = split.row() + row = split.row(align=True) else: - row = box.row() + row = box.row(align=True) + + row.alignment = 'RIGHT' row.label(text=key, translate=False) - # explicit exception for arrays + # explicit exception for arrays. if to_dict or to_list: row.label(text=val_draw, translate=False) else: @@ -186,6 +193,8 @@ def draw(layout, context, context_member, property_type, use_edit=True): else: row.label(text="API Defined") + del flow + class PropertyPanel: """ diff --git a/release/scripts/startup/bl_operators/add_mesh_torus.py b/release/scripts/startup/bl_operators/add_mesh_torus.py index 4460af173ff..68f49acc186 100644 --- a/release/scripts/startup/bl_operators/add_mesh_torus.py +++ b/release/scripts/startup/bl_operators/add_mesh_torus.py @@ -46,10 +46,11 @@ def add_torus(major_rad, minor_rad, major_seg, minor_seg): for minor_index in range(minor_seg): angle = pi_2 * minor_index / minor_seg - vec = matrix * Vector((major_rad + (cos(angle) * minor_rad), - 0.0, - sin(angle) * minor_rad, - )) + vec = matrix @ Vector(( + major_rad + (cos(angle) * minor_rad), + 0.0, + sin(angle) * minor_rad, + )) verts.extend(vec[:]) diff --git a/release/scripts/startup/bl_operators/clip.py b/release/scripts/startup/bl_operators/clip.py index 2717a4f62a3..d05082b0dd8 100644 --- a/release/scripts/startup/bl_operators/clip.py +++ b/release/scripts/startup/bl_operators/clip.py @@ -238,7 +238,7 @@ class CLIP_OT_track_to_empty(Operator): ob = bpy.data.objects.new(name=track.name, object_data=None) ob.select_set(action='SELECT') context.scene.objects.link(ob) - context.scene.objects.active = ob + context.view_layer.objects.active = ob for con in ob.constraints: if con.type == 'FOLLOW_TRACK': @@ -300,7 +300,7 @@ class CLIP_OT_bundles_to_mesh(Operator): reconstruction = tracking_object.reconstruction framenr = scene.frame_current - clip.frame_start + 1 reconstructed_matrix = reconstruction.cameras.matrix_from_frame(framenr) - matrix = camera.matrix_world * reconstructed_matrix.inverted() + matrix = camera.matrix_world @ reconstructed_matrix.inverted() for track in tracking_object.tracks: if track.has_bundle and track.select: @@ -314,7 +314,7 @@ class CLIP_OT_bundles_to_mesh(Operator): ob.matrix_world = matrix context.scene.objects.link(ob) ob.select = True - context.scene.objects.active = ob + context.view_layer.objects.active = ob else: self.report({'WARNING'}, "No usable tracks selected") @@ -580,10 +580,12 @@ class CLIP_OT_setup_tracking_scene(Operator): scene.camera = camob - camob.matrix_local = (Matrix.Translation((7.481, -6.508, 5.344)) * - Matrix.Rotation(0.815, 4, 'Z') * - Matrix.Rotation(0.011, 4, 'Y') * - Matrix.Rotation(1.109, 4, 'X')) + camob.matrix_local = ( + Matrix.Translation((7.481, -6.508, 5.344)) @ + Matrix.Rotation(0.815, 4, 'Z') @ + Matrix.Rotation(0.011, 4, 'Y') @ + Matrix.Rotation(1.109, 4, 'X') + ) return camob diff --git a/release/scripts/startup/bl_operators/mesh.py b/release/scripts/startup/bl_operators/mesh.py index a7475dcc6ef..1149d7a0dfb 100644 --- a/release/scripts/startup/bl_operators/mesh.py +++ b/release/scripts/startup/bl_operators/mesh.py @@ -205,57 +205,7 @@ class MeshSelectPrev(Operator): return {'FINISHED'} -# XXX This is hackish (going forth and back from Object mode...), to be redone once we have proper support of -# custom normals in BMesh/edit mode. -class MehsSetNormalsFromFaces(Operator): - """Set the custom vertex normals from the selected faces ones""" - bl_idname = "mesh.set_normals_from_faces" - bl_label = "Set Normals From Faces" - bl_options = {'REGISTER', 'UNDO'} - - @classmethod - def poll(cls, context): - return (context.mode == 'EDIT_MESH' and context.edit_object.data.polygons) - - def execute(self, context): - import mathutils - - bpy.ops.object.mode_set(mode='OBJECT') - obj = context.active_object - me = obj.data - - v2nors = {} - for p in me.polygons: - if not p.select: - continue - for lidx, vidx in zip(p.loop_indices, p.vertices): - assert(me.loops[lidx].vertex_index == vidx) - v2nors.setdefault(vidx, []).append(p.normal) - - for nors in v2nors.values(): - nors[:] = [sum(nors, mathutils.Vector((0, 0, 0))).normalized()] - - if not me.has_custom_normals: - me.create_normals_split() - me.calc_normals_split() - - normals = [] - for l in me.loops: - nor = v2nors.get(l.vertex_index, [None])[0] - if nor is None: - nor = l.normal - normals.append(nor.to_tuple()) - - me.normals_split_custom_set(normals) - - me.free_normals_split() - bpy.ops.object.mode_set(mode='EDIT') - - return {'FINISHED'} - - classes = ( - MehsSetNormalsFromFaces, MeshMirrorUV, MeshSelectNext, MeshSelectPrev, diff --git a/release/scripts/startup/bl_operators/object.py b/release/scripts/startup/bl_operators/object.py index be379ec6089..c49591ff300 100644 --- a/release/scripts/startup/bl_operators/object.py +++ b/release/scripts/startup/bl_operators/object.py @@ -599,7 +599,7 @@ class MakeDupliFace(Operator): trans = matrix.to_translation() rot = matrix.to_3x3() # also contains scale - return [(rot * b) + trans for b in base_tri] + return [(rot @ b) + trans for b in base_tri] scene = context.scene linked = {} for obj in context.selected_objects: diff --git a/release/scripts/startup/bl_operators/object_align.py b/release/scripts/startup/bl_operators/object_align.py index f627fd30162..60fb360480f 100644 --- a/release/scripts/startup/bl_operators/object_align.py +++ b/release/scripts/startup/bl_operators/object_align.py @@ -75,7 +75,7 @@ def worldspace_bounds_from_object_data(scene, obj): me = obj.to_mesh(scene=scene, apply_modifiers=True, settings='PREVIEW') verts = me.vertices - val = matrix_world * (verts[-1].co if verts else Vector((0.0, 0.0, 0.0))) + val = matrix_world @ (verts[-1].co if verts else Vector((0.0, 0.0, 0.0))) left, right, front, back, down, up = ( val[0], @@ -88,7 +88,7 @@ def worldspace_bounds_from_object_data(scene, obj): # Test against all other verts for v in verts: - vco = matrix_world * v.co + vco = matrix_world @ v.co # X Range val = vco[0] @@ -146,7 +146,7 @@ def align_objects(context, for obj in context.selected_objects: matrix_world = obj.matrix_world.copy() - bb_world = [matrix_world * Vector(v) for v in obj.bound_box] + bb_world = [matrix_world @ Vector(v) for v in obj.bound_box] objects.append((obj, bb_world)) if not objects: @@ -216,7 +216,7 @@ def align_objects(context, for obj, bb_world in objects: matrix_world = obj.matrix_world.copy() - bb_world = [matrix_world * Vector(v[:]) for v in obj.bound_box] + bb_world = [matrix_world @ Vector(v[:]) for v in obj.bound_box] if bb_quality and obj.type == 'MESH': GBB = worldspace_bounds_from_object_data(scene, obj) diff --git a/release/scripts/startup/bl_operators/presets.py b/release/scripts/startup/bl_operators/presets.py index 530194e5bb7..0fe45f8fee3 100644 --- a/release/scripts/startup/bl_operators/presets.py +++ b/release/scripts/startup/bl_operators/presets.py @@ -257,7 +257,7 @@ class PresetMenu(Panel): bl_space_type = 'PROPERTIES' bl_region_type = 'HEADER' bl_label = "Presets" - path_menu: Menu.path_menu + path_menu = Menu.path_menu @classmethod def draw_panel_header(cls, layout): @@ -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, ) diff --git a/release/scripts/startup/bl_operators/rigidbody.py b/release/scripts/startup/bl_operators/rigidbody.py index 36150a63895..46f3d0a1436 100644 --- a/release/scripts/startup/bl_operators/rigidbody.py +++ b/release/scripts/startup/bl_operators/rigidbody.py @@ -60,7 +60,7 @@ class CopyRigidbodySettings(Operator): def execute(self, context): obj_act = context.object - scene = context.scene + view_layer = context.view_layer # deselect all but mesh objects for o in context.selected_objects: @@ -68,9 +68,9 @@ class CopyRigidbodySettings(Operator): o.select_set(action='DESELECT') elif o.rigid_body is None: # Add rigidbody to object! - scene.objects.active = o + view_layer.objects.active = o bpy.ops.rigidbody.object_add() - scene.objects.active = obj_act + view_layer.objects.active = obj_act objects = context.selected_objects if objects: @@ -149,7 +149,7 @@ class BakeToKeyframes(Operator): mat = bake[i][j] # convert world space transform to parent space, so parented objects don't get offset after baking if (obj.parent): - mat = obj.matrix_parent_inverse.inverted() * obj.parent.matrix_world.inverted() * mat + mat = obj.matrix_parent_inverse.inverted() @ obj.parent.matrix_world.inverted() @ mat obj.location = mat.to_translation() @@ -265,7 +265,7 @@ class ConnectRigidBodies(Operator): ob = bpy.data.objects.new("Constraint", object_data=None) ob.location = loc context.scene.objects.link(ob) - context.scene.objects.active = ob + context.view_layer.objects.active = ob ob.select_set(action='SELECT') bpy.ops.rigidbody.constraint_add() @@ -278,7 +278,7 @@ class ConnectRigidBodies(Operator): con.object2 = object2 def execute(self, context): - scene = context.scene + view_layer = context.view_layer objects = context.selected_objects obj_act = context.active_object change = False @@ -312,7 +312,7 @@ class ConnectRigidBodies(Operator): bpy.ops.object.select_all(action='DESELECT') for obj in objects: obj.select_set(action='SELECT') - scene.objects.active = obj_act + view_layer.objects.active = obj_act return {'FINISHED'} else: self.report({'WARNING'}, "No other objects selected") diff --git a/release/scripts/startup/bl_operators/uvcalc_lightmap.py b/release/scripts/startup/bl_operators/uvcalc_lightmap.py index 95a3d18304b..b866fb1ce40 100644 --- a/release/scripts/startup/bl_operators/uvcalc_lightmap.py +++ b/release/scripts/startup/bl_operators/uvcalc_lightmap.py @@ -579,7 +579,7 @@ def unwrap(operator, context, **kwargs): # define list of meshes meshes = [] if PREF_ACT_ONLY: - obj = context.scene.objects.active + obj = context.view_layer.objects.active if obj and obj.type == 'MESH': meshes = [obj.data] else: diff --git a/release/scripts/startup/bl_operators/uvcalc_smart_project.py b/release/scripts/startup/bl_operators/uvcalc_smart_project.py index fe15b9fa345..b01a50d5d6a 100644 --- a/release/scripts/startup/bl_operators/uvcalc_smart_project.py +++ b/release/scripts/startup/bl_operators/uvcalc_smart_project.py @@ -89,7 +89,7 @@ def pointInTri2D(v, v1, v2, v3): dict_matrix[key] = mtx - uvw = (v - v1) * mtx + uvw = (v - v1) @ mtx return 0 <= uvw[0] and 0 <= uvw[1] and uvw[0] + uvw[1] <= 1 @@ -258,7 +258,7 @@ def rotate_uvs(uv_points, angle): if angle != 0.0: mat = Matrix.Rotation(angle, 2) for uv in uv_points: - uv[:] = mat * uv + uv[:] = mat @ uv def optiRotateUvIsland(faces): @@ -858,7 +858,7 @@ def main(context, # Initialize projectVecs if USER_VIEW_INIT: # Generate Projection - projectVecs = [Vector(Window.GetViewVector()) * ob.matrix_world.inverted().to_3x3()] # We add to this along the way + projectVecs = [Vector(Window.GetViewVector()) @ ob.matrix_world.inverted().to_3x3()] # We add to this along the way else: projectVecs = [] @@ -975,7 +975,7 @@ def main(context, f_uv = f.uv for j, v in enumerate(f.v): # XXX - note, between mathutils in 2.4 and 2.5 the order changed. - f_uv[j][:] = (MatQuat * v.co).xy + f_uv[j][:] = (MatQuat @ v.co).xy if USER_SHARE_SPACE: # Should we collect and pack later? diff --git a/release/scripts/startup/bl_operators/wm.py b/release/scripts/startup/bl_operators/wm.py index cfbc96696d6..0ccdd3cf5c6 100644 --- a/release/scripts/startup/bl_operators/wm.py +++ b/release/scripts/startup/bl_operators/wm.py @@ -2440,9 +2440,9 @@ class WM_OT_studiolight_install(Operator): ) orientation: EnumProperty( items=( - ("MATCAP", "MatCap", ""), - ("WORLD", "World", ""), - ("CAMERA", "Camera", ""), + ('MATCAP', "MatCap", ""), + ('WORLD', "World", ""), + ('CAMERA', "Camera", ""), ) ) @@ -2499,9 +2499,12 @@ class WM_OT_studiolight_uninstall(Operator): userpref = context.user_preferences for studio_light in userpref.studio_lights: if studio_light.index == self.index: - self._remove_path(pathlib.Path(studio_light.path)) - self._remove_path(pathlib.Path(studio_light.path_irr_cache)) - self._remove_path(pathlib.Path(studio_light.path_sh_cache)) + if len(studio_light.path) > 0: + self._remove_path(pathlib.Path(studio_light.path)) + if len(studio_light.path_irr_cache) > 0: + self._remove_path(pathlib.Path(studio_light.path_irr_cache)) + if len(studio_light.path_sh_cache) > 0: + self._remove_path(pathlib.Path(studio_light.path_sh_cache)) userpref.studio_lights.remove(studio_light) return {'FINISHED'} return {'CANCELLED'} diff --git a/release/scripts/startup/bl_ui/__init__.py b/release/scripts/startup/bl_ui/__init__.py index 1ef6566ed8e..76adb544b49 100644 --- a/release/scripts/startup/bl_ui/__init__.py +++ b/release/scripts/startup/bl_ui/__init__.py @@ -34,18 +34,21 @@ _modules = [ "properties_data_camera", "properties_data_curve", "properties_data_empty", + "properties_data_gpencil", "properties_data_groom", "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_hair_common", "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_animviz.py b/release/scripts/startup/bl_ui/properties_animviz.py index 901e15c181a..4033d5c2448 100644 --- a/release/scripts/startup/bl_ui/properties_animviz.py +++ b/release/scripts/startup/bl_ui/properties_animviz.py @@ -29,7 +29,7 @@ class MotionPathButtonsPanel: bl_space_type = 'PROPERTIES' bl_region_type = 'WINDOW' bl_label = "Motion Paths" - bl_options = {'DEFAULT_CLOSED'} + # bl_options = {'DEFAULT_CLOSED'} def draw_settings(self, context, avs, mpath, bones=False): layout = self.layout diff --git a/release/scripts/startup/bl_ui/properties_data_armature.py b/release/scripts/startup/bl_ui/properties_data_armature.py index 6cfc4b6ea3f..8ea20ada390 100644 --- a/release/scripts/startup/bl_ui/properties_data_armature.py +++ b/release/scripts/startup/bl_ui/properties_data_armature.py @@ -211,6 +211,7 @@ class DATA_PT_pose_library(ArmatureButtonsPanel, Panel): # TODO: this panel will soon be deprecated too class DATA_PT_ghost(ArmatureButtonsPanel, Panel): bl_label = "Ghost" + bl_options = {'DEFAULT_CLOSED'} def draw(self, context): layout = self.layout @@ -328,7 +329,7 @@ class DATA_PT_onion_skinning(OnionSkinButtonsPanel): # , Panel): # inherit from class DATA_PT_custom_props_arm(ArmatureButtonsPanel, PropertyPanel, Panel): - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} _context_path = "object.data" _property_type = bpy.types.Armature @@ -340,9 +341,9 @@ classes = ( DATA_MT_bone_group_specials, DATA_PT_bone_groups, DATA_PT_pose_library, + DATA_PT_motion_paths, DATA_PT_ghost, DATA_PT_iksolver_itasc, - DATA_PT_motion_paths, DATA_PT_custom_props_arm, ) diff --git a/release/scripts/startup/bl_ui/properties_data_bone.py b/release/scripts/startup/bl_ui/properties_data_bone.py index cc593fbb0a2..6d364ee6539 100644 --- a/release/scripts/startup/bl_ui/properties_data_bone.py +++ b/release/scripts/startup/bl_ui/properties_data_bone.py @@ -402,7 +402,7 @@ class BONE_PT_deform(BoneButtonsPanel, Panel): class BONE_PT_custom_props(BoneButtonsPanel, PropertyPanel, Panel): - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} _property_type = bpy.types.Bone, bpy.types.EditBone, bpy.types.PoseBone @property diff --git a/release/scripts/startup/bl_ui/properties_data_camera.py b/release/scripts/startup/bl_ui/properties_data_camera.py index 4730fc56602..cc0bde46189 100644 --- a/release/scripts/startup/bl_ui/properties_data_camera.py +++ b/release/scripts/startup/bl_ui/properties_data_camera.py @@ -39,7 +39,7 @@ class CAMERA_PT_presets(PresetMenu): preset_subdir = "camera" preset_operator = "script.execute_preset" preset_add_operator = "camera.preset_add" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} class SAFE_AREAS_PT_presets(PresetMenu): @@ -47,13 +47,13 @@ class SAFE_AREAS_PT_presets(PresetMenu): preset_subdir = "safe_areas" preset_operator = "script.execute_preset" preset_add_operator = "safe_areas.preset_add" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} class DATA_PT_context_camera(CameraButtonsPanel, Panel): bl_label = "" bl_options = {'HIDE_HEADER'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw(self, context): layout = self.layout @@ -70,7 +70,7 @@ class DATA_PT_context_camera(CameraButtonsPanel, Panel): class DATA_PT_lens(CameraButtonsPanel, Panel): bl_label = "Lens" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw(self, context): layout = self.layout @@ -88,7 +88,7 @@ class DATA_PT_lens(CameraButtonsPanel, Panel): if cam.lens_unit == 'MILLIMETERS': col.prop(cam, "lens") elif cam.lens_unit == 'FOV': - row.prop(cam, "angle") + col.prop(cam, "angle") col.prop(cam, "lens_unit") elif cam.type == 'ORTHO': @@ -111,7 +111,7 @@ class DATA_PT_lens(CameraButtonsPanel, Panel): sub = col.column(align=True) sub.prop(ccam, "longitude_min", text="Longiture Min") sub.prop(ccam, "longitude_max", text="Max") - elif engine in {'BLENDER_RENDER', 'BLENDER_EEVEE'}: + elif engine in {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'}: if cam.lens_unit == 'MILLIMETERS': col.prop(cam, "lens") elif cam.lens_unit == 'FOV': @@ -133,7 +133,7 @@ class DATA_PT_lens(CameraButtonsPanel, Panel): class DATA_PT_camera_stereoscopy(CameraButtonsPanel, Panel): bl_label = "Stereoscopy" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -181,7 +181,7 @@ class DATA_PT_camera_stereoscopy(CameraButtonsPanel, Panel): class DATA_PT_camera(CameraButtonsPanel, Panel): bl_label = "Camera" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw_header_preset(self, context): CAMERA_PT_presets.draw_panel_header(self.layout) @@ -250,21 +250,16 @@ class DATA_PT_camera_dof_aperture(CameraButtonsPanel, Panel): col.prop(dof_options, "rotation") col.prop(dof_options, "ratio") else: - hq_support = dof_options.is_hq_supported col = flow.column() col.label("Viewport") - sub = col.column() - sub.active = hq_support - sub.prop(dof_options, "use_high_quality") col.prop(dof_options, "fstop") - if dof_options.use_high_quality and hq_support: - col.prop(dof_options, "blades") + col.prop(dof_options, "blades") class DATA_PT_camera_background_image(CameraButtonsPanel, Panel): bl_label = "Background Images" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw_header(self, context): cam = context.camera @@ -365,7 +360,7 @@ class DATA_PT_camera_background_image(CameraButtonsPanel, Panel): class DATA_PT_camera_display(CameraButtonsPanel, Panel): bl_label = "Viewport Display" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw(self, context): layout = self.layout @@ -398,7 +393,7 @@ class DATA_PT_camera_display(CameraButtonsPanel, Panel): class DATA_PT_camera_safe_areas(CameraButtonsPanel, Panel): bl_label = "Safe Areas" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw_header(self, context): cam = context.camera @@ -417,7 +412,7 @@ class DATA_PT_camera_safe_areas(CameraButtonsPanel, Panel): class DATA_PT_custom_props_camera(CameraButtonsPanel, PropertyPanel, Panel): - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} _context_path = "object.data" _property_type = bpy.types.Camera diff --git a/release/scripts/startup/bl_ui/properties_data_curve.py b/release/scripts/startup/bl_ui/properties_data_curve.py index c0ab9da949f..4002568fb7d 100644 --- a/release/scripts/startup/bl_ui/properties_data_curve.py +++ b/release/scripts/startup/bl_ui/properties_data_curve.py @@ -135,7 +135,7 @@ class DATA_PT_shape_curve(CurveButtonsPanel, Panel): class DATA_PT_curve_texture_space(CurveButtonsPanel, Panel): bl_label = "Texture Space" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw(self, context): layout = self.layout @@ -459,7 +459,7 @@ class DATA_PT_text_boxes(CurveButtonsPanelText, Panel): class DATA_PT_custom_props_curve(CurveButtonsPanel, PropertyPanel, Panel): - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} _context_path = "object.data" _property_type = bpy.types.Curve 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 index 00000000000..90dc86a20bb --- /dev/null +++ b/release/scripts/startup/bl_ui/properties_data_gpencil.py @@ -0,0 +1,404 @@ +# ##### 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", text="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() + col.active = not gpl.lock + col.prop(gpl, "parent") + col.prop(gpl, "parent_type", text="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) diff --git a/release/scripts/startup/bl_ui/properties_data_lattice.py b/release/scripts/startup/bl_ui/properties_data_lattice.py index 40e82bc0a52..9aa8a4dee64 100644 --- a/release/scripts/startup/bl_ui/properties_data_lattice.py +++ b/release/scripts/startup/bl_ui/properties_data_lattice.py @@ -85,7 +85,7 @@ class DATA_PT_lattice(DataButtonsPanel, Panel): class DATA_PT_custom_props_lattice(DataButtonsPanel, PropertyPanel, Panel): - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} _context_path = "object.data" _property_type = bpy.types.Lattice diff --git a/release/scripts/startup/bl_ui/properties_data_light.py b/release/scripts/startup/bl_ui/properties_data_light.py index a92414c0e7c..f5c985f2abe 100644 --- a/release/scripts/startup/bl_ui/properties_data_light.py +++ b/release/scripts/startup/bl_ui/properties_data_light.py @@ -36,7 +36,7 @@ class DataButtonsPanel: class DATA_PT_context_light(DataButtonsPanel, Panel): bl_label = "" bl_options = {'HIDE_HEADER'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw(self, context): layout = self.layout @@ -62,7 +62,7 @@ class DATA_PT_preview(DataButtonsPanel, Panel): class DATA_PT_light(DataButtonsPanel, Panel): bl_label = "Light" - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_OPENGL'} def draw(self, context): layout = self.layout @@ -71,38 +71,6 @@ class DATA_PT_light(DataButtonsPanel, Panel): layout.row().prop(light, "type", expand=True) - layout.use_property_split = True - - col = col.column() - col.prop(light, "color") - col.prop(light, "energy") - - if light.type in {'POINT', 'SPOT'}: - - col = col.column() - col.label(text="Falloff") - col.prop(light, "falloff_type") - col.prop(light, "distance") - col.prop(light, "shadow_soft_size") - - if light.falloff_type == 'LINEAR_QUADRATIC_WEIGHTED': - sub = col.column(align=True) - sub.prop(light, "linear_attenuation", slider=True, text="Linear") - sub.prop(light, "quadratic_attenuation", slider=True, text="Quadratic") - - elif light.falloff_type == 'INVERSE_COEFFICIENTS': - col.label(text="Inverse Coefficients") - sub = col.column(align=True) - sub.prop(light, "constant_coefficient", text="Constant") - sub.prop(light, "linear_coefficient", text="Linear") - sub.prop(light, "quadratic_coefficient", text="Quadratic") - - if light.type == 'AREA': - col.prop(light, "distance") - - col = split.column() - col.label() - class DATA_PT_EEVEE_light(DataButtonsPanel, Panel): bl_label = "Light" @@ -234,7 +202,7 @@ class DATA_PT_EEVEE_shadow_contact(DataButtonsPanel, Panel): class DATA_PT_area(DataButtonsPanel, Panel): bl_label = "Area Shape" - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -260,43 +228,8 @@ class DATA_PT_area(DataButtonsPanel, Panel): class DATA_PT_spot(DataButtonsPanel, Panel): bl_label = "Spot Shape" - COMPAT_ENGINES = {'BLENDER_RENDER'} - - @classmethod - def poll(cls, context): - light = context.light - engine = context.engine - return (light and light.type == 'SPOT') and (engine in cls.COMPAT_ENGINES) - - def draw(self, context): - layout = self.layout - - light = context.light - - split = layout.split() - - col = split.column() - sub = col.column() - sub.prop(light, "spot_size", text="Size") - sub.prop(light, "spot_blend", text="Blend", slider=True) - col.prop(light, "use_square") - col.prop(light, "show_cone") - - col = split.column() - - col.active = (light.shadow_method != 'BUFFER_SHADOW' or light.shadow_buffer_type != 'DEEP') - col.prop(light, "use_halo") - sub = col.column(align=True) - sub.active = light.use_halo - sub.prop(light, "halo_intensity", text="Intensity") - if light.shadow_method == 'BUFFER_SHADOW': - sub.prop(light, "halo_step", text="Step") - - -class DATA_PT_spot(DataButtonsPanel, Panel): - bl_label = "Spot Shape" bl_parent_id = "DATA_PT_EEVEE_light" - COMPAT_ENGINES = {'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -337,7 +270,7 @@ class DATA_PT_falloff_curve(DataButtonsPanel, Panel): class DATA_PT_custom_props_light(DataButtonsPanel, PropertyPanel, Panel): - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} _context_path = "object.data" _property_type = bpy.types.Light diff --git a/release/scripts/startup/bl_ui/properties_data_lightprobe.py b/release/scripts/startup/bl_ui/properties_data_lightprobe.py index 10b66dd0033..5924a796b65 100644 --- a/release/scripts/startup/bl_ui/properties_data_lightprobe.py +++ b/release/scripts/startup/bl_ui/properties_data_lightprobe.py @@ -155,12 +155,9 @@ class DATA_PT_lightprobe_display(DataButtonsPanel, Panel): col = layout.column() - if probe.type != 'PLANAR': - col.prop(probe, "data_draw_size", text="Size") - else: + if probe.type == 'PLANAR': col.prop(ob, "empty_draw_size", text="Arrow Size") - - col.prop(probe, "show_data") + col.prop(probe, "show_data") if probe.type in {'GRID', 'CUBEMAP'}: col.prop(probe, "show_influence") diff --git a/release/scripts/startup/bl_ui/properties_data_mesh.py b/release/scripts/startup/bl_ui/properties_data_mesh.py index e8015327c1d..f096ff83957 100644 --- a/release/scripts/startup/bl_ui/properties_data_mesh.py +++ b/release/scripts/startup/bl_ui/properties_data_mesh.py @@ -24,7 +24,6 @@ from rna_prop_ui import PropertyPanel class MESH_MT_vertex_group_specials(Menu): bl_label = "Vertex Group Specials" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} def draw(self, context): layout = self.layout @@ -48,7 +47,6 @@ class MESH_MT_vertex_group_specials(Menu): class MESH_MT_shape_key_specials(Menu): bl_label = "Shape Key Specials" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} def draw(self, context): layout = self.layout @@ -137,7 +135,7 @@ class MeshButtonsPanel: class DATA_PT_context_mesh(MeshButtonsPanel, Panel): bl_label = "" bl_options = {'HIDE_HEADER'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw(self, context): layout = self.layout @@ -154,7 +152,8 @@ class DATA_PT_context_mesh(MeshButtonsPanel, Panel): class DATA_PT_normals(MeshButtonsPanel, Panel): bl_label = "Normals" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + bl_options = {'DEFAULT_CLOSED'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw(self, context): layout = self.layout @@ -174,7 +173,7 @@ class DATA_PT_normals(MeshButtonsPanel, Panel): class DATA_PT_texture_space(MeshButtonsPanel, Panel): bl_label = "Texture Space" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw(self, context): layout = self.layout @@ -194,7 +193,7 @@ class DATA_PT_texture_space(MeshButtonsPanel, Panel): class DATA_PT_vertex_groups(MeshButtonsPanel, Panel): bl_label = "Vertex Groups" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -241,7 +240,8 @@ class DATA_PT_vertex_groups(MeshButtonsPanel, Panel): class DATA_PT_face_maps(MeshButtonsPanel, Panel): bl_label = "Face Maps" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + bl_options = {'DEFAULT_CLOSED'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -283,7 +283,7 @@ class DATA_PT_face_maps(MeshButtonsPanel, Panel): class DATA_PT_shape_keys(MeshButtonsPanel, Panel): bl_label = "Shape Keys" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -373,7 +373,7 @@ class DATA_PT_shape_keys(MeshButtonsPanel, Panel): class DATA_PT_uv_texture(MeshButtonsPanel, Panel): bl_label = "UV Maps" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw(self, context): layout = self.layout @@ -392,7 +392,7 @@ class DATA_PT_uv_texture(MeshButtonsPanel, Panel): class DATA_PT_vertex_colors(MeshButtonsPanel, Panel): bl_label = "Vertex Colors" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw(self, context): layout = self.layout @@ -412,7 +412,7 @@ class DATA_PT_vertex_colors(MeshButtonsPanel, Panel): class DATA_PT_customdata(MeshButtonsPanel, Panel): bl_label = "Geometry Data" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw(self, context): layout = self.layout @@ -439,7 +439,7 @@ class DATA_PT_customdata(MeshButtonsPanel, Panel): class DATA_PT_custom_props_mesh(MeshButtonsPanel, PropertyPanel, Panel): - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} _context_path = "object.data" _property_type = bpy.types.Mesh @@ -452,13 +452,13 @@ classes = ( MESH_UL_shape_keys, MESH_UL_uvmaps_vcols, DATA_PT_context_mesh, - DATA_PT_normals, - DATA_PT_texture_space, DATA_PT_vertex_groups, - DATA_PT_face_maps, DATA_PT_shape_keys, DATA_PT_uv_texture, DATA_PT_vertex_colors, + DATA_PT_face_maps, + DATA_PT_normals, + DATA_PT_texture_space, DATA_PT_customdata, DATA_PT_custom_props_mesh, ) diff --git a/release/scripts/startup/bl_ui/properties_data_metaball.py b/release/scripts/startup/bl_ui/properties_data_metaball.py index 2a61e6cda79..75015a57f5f 100644 --- a/release/scripts/startup/bl_ui/properties_data_metaball.py +++ b/release/scripts/startup/bl_ui/properties_data_metaball.py @@ -71,7 +71,7 @@ class DATA_PT_metaball(DataButtonsPanel, Panel): class DATA_PT_mball_texture_space(DataButtonsPanel, Panel): bl_label = "Texture Space" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw(self, context): layout = self.layout @@ -125,7 +125,7 @@ class DATA_PT_metaball_element(DataButtonsPanel, Panel): class DATA_PT_custom_props_metaball(DataButtonsPanel, PropertyPanel, Panel): - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} _context_path = "object.data" _property_type = bpy.types.MetaBall diff --git a/release/scripts/startup/bl_ui/properties_data_modifier.py b/release/scripts/startup/bl_ui/properties_data_modifier.py index cd0617d8f26..e2a537acadd 100644 --- a/release/scripts/startup/bl_ui/properties_data_modifier.py +++ b/release/scripts/startup/bl_ui/properties_data_modifier.py @@ -32,6 +32,11 @@ class ModifierButtonsPanel: 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 @@ -140,6 +145,8 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel): col.prop(md, "use_only_vertices") col.prop(md, "use_clamp_overlap") col.prop(md, "loop_slide") + col.prop(md, "mark_seam") + col.prop(md, "mark_sharp") layout.label(text="Limit Method:") layout.row().prop(md, "limit_method", expand=True) @@ -152,6 +159,12 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel): layout.label(text="Width Method:") layout.row().prop(md, "offset_type", expand=True) + layout.label(text="Normal Mode") + layout.row().prop(md, "hnmode", expand=True) + layout.prop(md, "hn_strength") + layout.prop(md, "set_wn_strength") + + def BOOLEAN(self, layout, ob, md): split = layout.split() @@ -736,23 +749,25 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel): row.prop(md, "particle_amount", text="Amount") row.prop(md, "particle_offset", text="Offset") + row = layout.row(align=True) + row.prop(md, "axis", expand=True) + layout.separator() layout.prop(md, "use_path", text="Create Along Paths") - split = layout.split() - split.active = md.use_path - col = split.column() - col.row().prop(md, "axis", expand=True) + col = layout.column() + col.active = md.use_path col.prop(md, "use_preserve_shape") - col = split.column() - col2 = col.column(align=True) - col2.prop(md, "position", slider=True) - col2.prop(md, "random_position", text="Random", slider=True) - col2 = col.column(align=True) - col2.prop(md, "rotation", slider=True) - col2.prop(md, "random_rotation", text="Random", slider=True) + row = col.row(align=True) + row.prop(md, "position", slider=True) + row.prop(md, "random_position", text="Random", slider=True) + row = col.row(align=True) + row.prop(md, "rotation", slider=True) + row.prop(md, "random_rotation", text="Random", slider=True) + + layout.separator() col = layout.column() col.prop_search(md, "index_layer_name", ob.data, "vertex_colors", text="Index Layer") @@ -1583,9 +1598,468 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel): col.label("Display Settings:") draw_hair_display_settings(col, md.draw_settings) + def WEIGHTED_NORMAL(self, layout, ob, md): + layout.label("Weighting Mode:") + split = layout.split(align=True) + col = split.column(align=True) + col.prop(md, "mode", text="") + col.prop(md, "weight", text="Weight") + col.prop(md, "keep_sharp") + + col = split.column(align=True) + row = col.row(align=True) + row.prop_search(md, "vertex_group", ob, "vertex_groups", text="") + row.active = bool(md.vertex_group) + row.prop(md, "invert_vertex_group", text="", icon='ARROW_LEFTRIGHT') + col.prop(md, "thresh", text="Threshold") + col.prop(md, "face_influence") + + +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_materials") + row.prop(md, "modify_color") + + + 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_materials") + row.prop(md, "modify_color") + + 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") + + row = layout.row() + row.prop(md, "create_materials") + row.prop(md, "modify_color") + + 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 index 00000000000..3798a273e09 --- /dev/null +++ b/release/scripts/startup/bl_ui/properties_data_shaderfx.py @@ -0,0 +1,135 @@ +# ##### 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) diff --git a/release/scripts/startup/bl_ui/properties_data_speaker.py b/release/scripts/startup/bl_ui/properties_data_speaker.py index 2a3dc4d02c1..d7c93095489 100644 --- a/release/scripts/startup/bl_ui/properties_data_speaker.py +++ b/release/scripts/startup/bl_ui/properties_data_speaker.py @@ -36,7 +36,7 @@ class DataButtonsPanel: class DATA_PT_context_speaker(DataButtonsPanel, Panel): bl_label = "" bl_options = {'HIDE_HEADER'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw(self, context): layout = self.layout @@ -55,7 +55,7 @@ class DATA_PT_context_speaker(DataButtonsPanel, Panel): class DATA_PT_speaker(DataButtonsPanel, Panel): bl_label = "Sound" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw(self, context): layout = self.layout @@ -76,7 +76,7 @@ class DATA_PT_speaker(DataButtonsPanel, Panel): class DATA_PT_distance(DataButtonsPanel, Panel): bl_label = "Distance" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw(self, context): layout = self.layout @@ -99,7 +99,7 @@ class DATA_PT_distance(DataButtonsPanel, Panel): class DATA_PT_cone(DataButtonsPanel, Panel): bl_label = "Cone" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw(self, context): layout = self.layout @@ -121,7 +121,7 @@ class DATA_PT_cone(DataButtonsPanel, Panel): class DATA_PT_custom_props_speaker(DataButtonsPanel, PropertyPanel, Panel): - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} _context_path = "object.data" _property_type = bpy.types.Speaker diff --git a/release/scripts/startup/bl_ui/properties_grease_pencil_common.py b/release/scripts/startup/bl_ui/properties_grease_pencil_common.py index a2ccfb4f1b8..336e4acfd8f 100644 --- a/release/scripts/startup/bl_ui/properties_grease_pencil_common.py +++ b/release/scripts/startup/bl_ui/properties_grease_pencil_common.py @@ -18,45 +18,30 @@ # <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,261 +201,125 @@ 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() + col.operator("gpencil.stroke_change_color", text="Assign Material") 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 + + ob = context.active_object - layout.label("Strength") - box = layout.box() - box.template_curve_mapping(brush, "curve_strength", brush=True) + if ob.mode == 'GPENCIL_PAINT': + brush = context.active_gpencil_brush + gp_settings = brush.gpencil_settings - layout.label("Jitter") - box = layout.box() - box.template_curve_mapping(brush, "curve_jitter", brush=True) + 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") -############################### class GPENCIL_MT_pie_tool_palette(Menu): """A pie menu for quick access to Grease Pencil tools""" @@ -539,6 +376,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 +404,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) @@ -668,7 +506,7 @@ class GPENCIL_MT_pie_tools_more(Menu): class GPENCIL_MT_pie_sculpt(Menu): - """A pie menu for accessing Grease Pencil stroke sculpting settings""" + """A pie menu for accessing Grease Pencil stroke sculpt settings""" bl_label = "Grease Pencil Sculpt" @classmethod @@ -717,9 +555,6 @@ class GPENCIL_MT_pie_sculpt(Menu): row.prop_enum(settings, "tool", value='RANDOMIZE') -############################### - - class GPENCIL_MT_snap(Menu): bl_label = "Snap" @@ -728,7 +563,7 @@ class GPENCIL_MT_snap(Menu): layout.operator("gpencil.snap_to_grid", text="Selection to Grid") layout.operator("gpencil.snap_to_cursor", text="Selection to Cursor").use_offset = False - layout.operator("gpencil.snap_to_cursor", text="Selection to Cursor (Offset)").use_offset = True + layout.operator("gpencil.snap_to_cursor", text="Selection to Cursor (Keep Offset)").use_offset = True layout.separator() @@ -737,185 +572,110 @@ class GPENCIL_MT_snap(Menu): layout.operator("view3d.snap_cursor_to_grid", text="Cursor to Grid") -class GPENCIL_MT_gpencil_edit_specials(Menu): - bl_label = "GPencil Specials" +class GPENCIL_MT_separate(Menu): + bl_label = "Separate" def draw(self, context): layout = self.layout - is_3d_view = context.space_data.type == 'VIEW_3D' + 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' - layout.operator_context = 'INVOKE_REGION_WIN' - - layout.operator("gpencil.stroke_subdivide", text="Subdivide") - layout.separator() +class GPENCIL_MT_gpencil_draw_specials(Menu): + bl_label = "GPencil Draw Specials" - layout.operator("gpencil.stroke_join", text="Join").type = 'JOIN' - layout.operator("gpencil.stroke_join", text="Join & Copy").type = 'JOINCOPY' - layout.operator("gpencil.stroke_flip", text="Flip Direction") - - if is_3d_view: - layout.separator() - layout.operator("gpencil.reproject") - - -############################### + def draw(self, context): + layout = self.layout + is_3d_view = context.space_data.type == 'VIEW_3D' + layout.operator_context = 'INVOKE_REGION_WIN' -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 + layout.operator("gpencil.frame_duplicate", text="Duplicate Active Frame") + layout.operator("gpencil.frame_duplicate", text="Duplicate Active Frame All Layers").mode = 'ALL' - 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) + 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' + # Colors. + layout.separator() + layout.operator("gpencil.colorpick", text="Colors", icon="GROUP_VCOL") -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 +class GPENCIL_MT_gpencil_draw_delete(Menu): + bl_label = "GPencil Draw Delete" - 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) + def draw(self, context): + layout = self.layout + is_3d_view = context.space_data.type == 'VIEW_3D' - 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) + layout.operator_context = 'INVOKE_REGION_WIN' - elif self.layout_type == 'GRID': - layout.alignment = 'CENTER' - layout.label(text="", icon_value=icon) + layout.operator("gpencil.active_frames_delete_all", text="Delete Frame") -class GPENCIL_UL_layer(UIList): +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 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) + split = layout.split(percentage=0.2) + split.prop(gpl, "color", text="", emboss=True) + split.prop(gpl, "info", text="", emboss=False) row = layout.row(align=True) - row.prop(gpl, "lock", text="", emboss=False) + # 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) -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 GPENCIL_MT_brush_specials(Menu): - bl_label = "Layer" - - 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") - - -class GPENCIL_MT_palettecolor_specials(Menu): - bl_label = "Layer" - - def draw(self, context): - layout = self.layout - - 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() - - 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") - - layout.separator() - - layout.operator("gpencil.palettecolor_select", icon='COLOR', text="Select Strokes") - layout.operator("gpencil.stroke_change_color", icon='MAN_TRANS', text="Move to Color") - - class GreasePencilDataPanel: - # subclass must set - # bl_space_type = 'IMAGE_EDITOR' - bl_label = "Grease Pencil Layers" + bl_label = "Annotations" bl_region_type = 'UI' + bl_options = {'DEFAULT_CLOSED'} + + @classmethod + def poll(cls, context): + # Show this panel as long as someone that might own this exists + # AND the owner isn't an object (e.g. GP Object) + if context.gpencil_data_owner is None: + return False + elif type(context.gpencil_data_owner) is bpy.types.Object: + return False + else: + 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_decorate = False - # owner of Grease Pencil data + # Grease Pencil owner. 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': + # Owner selector. + 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") - else: + # List of layers/notes. + if gpd and gpd.layers: self.draw_layers(context, layout, gpd) def draw_layers(self, context, layout, gpd): @@ -926,7 +686,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 +696,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,211 +703,66 @@ 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) + tool_settings = context.tool_settings + if gpd and gpl: + layout.prop(gpl, "thickness") 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="") - - # Parenting - if context.space_data.type == 'VIEW_3D': - col = split.column(align=True) - col.label(text="Parent:") - col.prop(gpl, "parent", text="") - - 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="") - - layout.separator() - - # Full-Row - Frame Locking (and Delete Frame) - row = layout.row(align=True) - row.active = not gpl.lock + layout.prop(tool_settings, "annotation_thickness", text="Thickness") - 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() - - # Onion skinning - col = layout.column(align=True) - col.active = not gpl.lock - - 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 - - # - Before Frames - sub = split.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") - - # - 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' + if gpl: + # layout.prop(gpl, "opacity", text="Opacity", slider=True) + # Full-Row - Frame Locking (and Delete Frame) + row = layout.row(align=True) + row.active = not gpl.lock - @classmethod - def poll(cls, context): - # XXX - disabled in 2.8 branch. - return False + 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') - if context.gpencil_data is None: - return False - gpd = context.gpencil_data - return bool(gpd.layers.active) +class GreasePencilOnionPanel: @staticmethod - def draw(self, context): - layout = self.layout - palette = context.active_gpencil_palette - - 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) + def draw_settings(layout, gp): + col = layout.column() + col.prop(gp, "onion_mode") + col.prop(gp, "onion_factor", text="Opacity", slider=True) - col = row.column() + if gp.onion_mode in ('ABSOLUTE', 'RELATIVE'): + col = layout.column(align=True) + col.prop(gp, "ghost_before_range", text="Frames Before") + col.prop(gp, "ghost_after_range", text="After") - sub = col.column(align=True) - sub.operator("gpencil.palettecolor_add", icon='ZOOMIN', text="") - sub.operator("gpencil.palettecolor_remove", icon='ZOOMOUT', text="") + layout.prop(gp, "use_ghost_custom_colors", text="Use Custom Colors") - palcol = context.active_gpencil_palettecolor - if palcol: - sub.menu("GPENCIL_MT_palettecolor_specials", icon='DOWNARROW_HLT', text="") + if gp.use_ghost_custom_colors: + col = layout.column(align=True) + col.active = gp.use_ghost_custom_colors + col.prop(gp, "before_color", text="Color Before") + col.prop(gp, "after_color", text="After") - if len(palette.colors) > 1: - col.separator() + layout.prop(gp, "use_ghosts_always", text="View In Render") - 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") + col = layout.column(align=True) + col.active = gp.use_onion_skinning + col.prop(gp, "use_onion_fade", text="Fade") + if hasattr(gp, "use_onion_loop"): # XXX + sub = layout.column() + sub.active = gp.onion_mode in ('RELATIVE', 'SELECTED') + sub.prop(gp, "use_onion_loop", text="Loop") class GreasePencilToolsPanel: # For use in "2D" Editors without their own toolbar # subclass must set # bl_space_type = 'IMAGE_EDITOR' - # bl_options = {'DEFAULT_CLOSED'} bl_label = "Grease Pencil Settings" bl_region_type = 'UI' + bl_options = {'DEFAULT_CLOSED'} @classmethod def poll(cls, context): @@ -1189,14 +802,14 @@ classes = ( GPENCIL_MT_pie_settings_palette, GPENCIL_MT_pie_tools_more, GPENCIL_MT_pie_sculpt, + GPENCIL_MT_snap, - 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_separate, + + GPENCIL_MT_gpencil_draw_specials, + GPENCIL_MT_gpencil_draw_delete, + + GPENCIL_UL_annotation_layer, ) if __name__ == "__main__": # only for live edit. diff --git a/release/scripts/startup/bl_ui/properties_material.py b/release/scripts/startup/bl_ui/properties_material.py index b601922e944..706ce497dee 100644 --- a/release/scripts/startup/bl_ui/properties_material.py +++ b/release/scripts/startup/bl_ui/properties_material.py @@ -73,7 +73,7 @@ class MATERIAL_PT_preview(MaterialButtonsPanel, Panel): class MATERIAL_PT_custom_props(MaterialButtonsPanel, PropertyPanel, Panel): - COMPAT_ENGINES = {'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_EEVEE', 'BLENDER_OPENGL'} _context_path = "material" _property_type = bpy.types.Material @@ -82,12 +82,15 @@ class EEVEE_MATERIAL_PT_context_material(MaterialButtonsPanel, Panel): bl_label = "" bl_context = "material" bl_options = {'HIDE_HEADER'} - COMPAT_ENGINES = {'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_EEVEE', 'BLENDER_OPENGL'} @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 @@ -209,11 +212,7 @@ class EEVEE_MATERIAL_PT_options(MaterialButtonsPanel, Panel): layout.prop(mat, "use_screen_refraction") layout.prop(mat, "refraction_depth") - - layout.prop(mat, "use_screen_subsurface") - row = layout.row() - row.active = mat.use_screen_subsurface - row.prop(mat, "use_sss_translucency") + layout.prop(mat, "use_sss_translucency") class MATERIAL_PT_viewport(MaterialButtonsPanel, Panel): 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 index 00000000000..d83639a361c --- /dev/null +++ b/release/scripts/startup/bl_ui/properties_material_gpencil.py @@ -0,0 +1,321 @@ +# ##### 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) diff --git a/release/scripts/startup/bl_ui/properties_object.py b/release/scripts/startup/bl_ui/properties_object.py index 63b708ae059..79b2f7b8df8 100644 --- a/release/scripts/startup/bl_ui/properties_object.py +++ b/release/scripts/startup/bl_ui/properties_object.py @@ -329,6 +329,7 @@ from .properties_animviz import ( class OBJECT_PT_motion_paths(MotionPathButtonsPanel, Panel): #bl_label = "Object Motion Paths" bl_context = "object" + bl_options = {'DEFAULT_CLOSED'} @classmethod def poll(cls, context): @@ -359,7 +360,7 @@ class OBJECT_PT_onion_skinning(OnionSkinButtonsPanel): # , Panel): # inherit fr class OBJECT_PT_custom_props(ObjectButtonsPanel, PropertyPanel, Panel): - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} _context_path = "object" _property_type = bpy.types.Object diff --git a/release/scripts/startup/bl_ui/properties_particle.py b/release/scripts/startup/bl_ui/properties_particle.py index 05538e71faf..393c9784be8 100644 --- a/release/scripts/startup/bl_ui/properties_particle.py +++ b/release/scripts/startup/bl_ui/properties_particle.py @@ -67,7 +67,7 @@ def particle_get_settings(context): class PARTICLE_MT_specials(Menu): bl_label = "Particle Specials" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw(self, context): layout = self.layout @@ -88,7 +88,7 @@ class PARTICLE_PT_hair_dynamics_presets(PresetMenu): preset_subdir = "hair_dynamics" preset_operator = "script.execute_preset" preset_add_operator = "particle.hair_dynamics_preset_add" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} class ParticleButtonsPanel: @@ -132,7 +132,7 @@ class PARTICLE_UL_particle_systems(bpy.types.UIList): class PARTICLE_PT_context_particles(ParticleButtonsPanel, Panel): bl_label = "" bl_options = {'HIDE_HEADER'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -235,7 +235,7 @@ class PARTICLE_PT_context_particles(ParticleButtonsPanel, Panel): class PARTICLE_PT_emission(ParticleButtonsPanel, Panel): bl_label = "Emission" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -287,7 +287,7 @@ class PARTICLE_PT_emission_source(ParticleButtonsPanel, Panel): bl_label = "Source" bl_parent_id = "PARTICLE_PT_emission" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw(self, context): layout = self.layout @@ -325,7 +325,7 @@ class PARTICLE_PT_emission_source(ParticleButtonsPanel, Panel): class PARTICLE_PT_hair_dynamics(ParticleButtonsPanel, Panel): bl_label = "Hair Dynamics" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -406,7 +406,7 @@ class PARTICLE_PT_hair_dynamics_structure(ParticleButtonsPanel, Panel): bl_label = "Structure" bl_parent_id = "PARTICLE_PT_hair_dynamics" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -438,7 +438,7 @@ class PARTICLE_PT_hair_dynamics_volume(ParticleButtonsPanel, Panel): bl_label = "Volume" bl_parent_id = "PARTICLE_PT_hair_dynamics" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -470,7 +470,7 @@ class PARTICLE_PT_hair_dynamics_volume(ParticleButtonsPanel, Panel): class PARTICLE_PT_cache(ParticleButtonsPanel, Panel): bl_label = "Cache" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -501,7 +501,7 @@ class PARTICLE_PT_cache(ParticleButtonsPanel, Panel): class PARTICLE_PT_velocity(ParticleButtonsPanel, Panel): bl_label = "Velocity" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -550,7 +550,7 @@ class PARTICLE_PT_velocity(ParticleButtonsPanel, Panel): class PARTICLE_PT_rotation(ParticleButtonsPanel, Panel): bl_label = "Rotation" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -603,7 +603,7 @@ class PARTICLE_PT_rotation_angular_velocity(ParticleButtonsPanel, Panel): bl_label = "Angular Velocity" bl_parent_id = "PARTICLE_PT_rotation" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw(self, context): layout = self.layout @@ -628,7 +628,7 @@ class PARTICLE_PT_rotation_angular_velocity(ParticleButtonsPanel, Panel): class PARTICLE_PT_physics(ParticleButtonsPanel, Panel): bl_label = "Physics" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -662,171 +662,343 @@ class PARTICLE_PT_physics(ParticleButtonsPanel, Panel): if part.physics_type == 'FLUID': fluid = part.fluid - col.label(text="Fluid") + col.separator() col.prop(fluid, "solver") col.prop(fluid, "stiffness", text="Stiffness") col.prop(fluid, "linear_viscosity", text="Viscosity") col.prop(fluid, "buoyancy", text="Buoyancy", slider=True) - col.label(text="Advanced") + elif part.physics_type == 'KEYED': + + sub = col.column() + sub.active = not psys.use_keyed_timing + sub.prop(part, "keyed_loops", text="Loops") + if psys: + col.prop(psys, "use_keyed_timing", text="Use Timing") + + col.label(text="Keys") + + +class PARTICLE_PT_physics_fluid_advanced(ParticleButtonsPanel, Panel): + bl_label = "Advanced" + bl_parent_id = "PARTICLE_PT_physics" + bl_options = {'DEFAULT_CLOSED'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} - if fluid.solver == 'DDR': - sub = col.column() - sub.prop(fluid, "repulsion", slider=fluid.factor_repulsion) - sub.prop(fluid, "factor_repulsion") + @classmethod + def poll(cls, context): + part = particle_get_settings(context) + fluid = part.fluid + if part.physics_type == 'FLUID': + return True + else: + return False - sub.prop(fluid, "stiff_viscosity", slider=fluid.factor_stiff_viscosity) - sub.prop(fluid, "factor_stiff_viscosity") + def draw(self, context): + layout = self.layout + layout.use_property_split = True + psys = context.particle_system + part = particle_get_settings(context) + fluid = part.fluid + + col = layout.column() + + if fluid.solver == 'DDR': sub = col.column() - sub.prop(fluid, "fluid_radius", slider=fluid.factor_radius) - sub.prop(fluid, "factor_radius") + sub.prop(fluid, "repulsion", slider=fluid.factor_repulsion) + sub.prop(fluid, "factor_repulsion") - sub.prop(fluid, "rest_density", slider=fluid.use_factor_density) - sub.prop(fluid, "use_factor_density") + sub.prop(fluid, "stiff_viscosity", slider=fluid.factor_stiff_viscosity) + sub.prop(fluid, "factor_stiff_viscosity") - if fluid.solver == 'CLASSICAL': - # With the classical solver, it is possible to calculate the - # spacing between particles when the fluid is at rest. This - # makes it easier to set stable initial conditions. - particle_volume = part.mass / fluid.rest_density - spacing = pow(particle_volume, 1.0 / 3.0) + sub = col.column() + sub.prop(fluid, "fluid_radius", slider=fluid.factor_radius) + sub.prop(fluid, "factor_radius") - sub.label(text="Spacing: %g" % spacing) + sub.prop(fluid, "rest_density", slider=fluid.use_factor_density) + sub.prop(fluid, "use_factor_density") - elif fluid.solver == 'DDR': + if fluid.solver == 'CLASSICAL': + # With the classical solver, it is possible to calculate the + # spacing between particles when the fluid is at rest. This + # makes it easier to set stable initial conditions. + particle_volume = part.mass / fluid.rest_density + spacing = pow(particle_volume, 1.0 / 3.0) - col.label(text="Springs") - col.prop(fluid, "spring_force", text="Force") - col.prop(fluid, "use_viscoelastic_springs") + sub.label(text="Spacing: %g" % spacing) - sub = col.column() - sub.active = fluid.use_viscoelastic_springs - sub.prop(fluid, "yield_ratio", slider=True) - sub.prop(fluid, "plasticity", slider=True) - col.label(text="Advanced") - sub = col.column() - sub.prop(fluid, "rest_length", slider=fluid.factor_rest_length) - sub.prop(fluid, "factor_rest_length", text="") +class PARTICLE_PT_physics_fluid_springs(ParticleButtonsPanel, Panel): + bl_label = "Springs" + bl_parent_id = "PARTICLE_PT_physics" + bl_options = {'DEFAULT_CLOSED'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} - sub = col.column() - sub.active = fluid.use_viscoelastic_springs - sub.prop(fluid, "use_initial_rest_length") - sub.prop(fluid, "spring_frames", text="Frames") + @classmethod + def poll(cls, context): + part = particle_get_settings(context) + fluid = part.fluid + if part.physics_type == 'FLUID' and fluid.solver == 'DDR': + return True + else: + return False - elif part.physics_type == 'KEYED': + def draw(self, context): + layout = self.layout + layout.use_property_split = True - sub = col.column() - sub.active = not psys.use_keyed_timing - sub.prop(part, "keyed_loops", text="Loops") - if psys: - col.prop(psys, "use_keyed_timing", text="Use Timing") + psys = context.particle_system + part = particle_get_settings(context) + fluid = part.fluid - col.label(text="Keys") + col = layout.column() - elif part.physics_type == 'BOIDS': - boids = part.boids + col.prop(fluid, "spring_force", text="Force") - row = layout.row() - row.prop(boids, "use_flight") - row.prop(boids, "use_land") - row.prop(boids, "use_climb") - - split = layout.split() - - col = split.column(align=True) - col.active = boids.use_flight - col.prop(boids, "air_speed_max") - col.prop(boids, "air_speed_min", slider=True) - col.prop(boids, "air_acc_max", slider=True) - col.prop(boids, "air_ave_max", slider=True) - col.prop(boids, "air_personal_space") - row = col.row(align=True) - row.active = (boids.use_land or boids.use_climb) and boids.use_flight - row.prop(boids, "land_smooth") - - col = split.column(align=True) - col.active = boids.use_land or boids.use_climb - col.prop(boids, "land_speed_max") - col.prop(boids, "land_jump_speed") - col.prop(boids, "land_acc_max", slider=True) - col.prop(boids, "land_ave_max", slider=True) - col.prop(boids, "land_personal_space") - col.prop(boids, "land_stick_force") - - layout.prop(part, "collision_group") - - split = layout.split() - - col = split.column(align=True) - col.label(text="Battle:") - col.prop(boids, "health") - col.prop(boids, "strength") - col.prop(boids, "aggression") - col.prop(boids, "accuracy") - col.prop(boids, "range") - col = split.column() - col.label(text="Misc:") - col.prop(boids, "bank", slider=True) - col.prop(boids, "pitch", slider=True) - col.prop(boids, "height", slider=True) - - if psys and part.physics_type in {'KEYED', 'BOIDS', 'FLUID'}: - if part.physics_type == 'BOIDS': - layout.label(text="Relations:") - elif part.physics_type == 'FLUID': - layout.label(text="Fluid Interaction:") +class PARTICLE_PT_physics_fluid_springs_viscoelastic(ParticleButtonsPanel, Panel): + bl_label = "Viscoelastic Springs" + bl_parent_id = "PARTICLE_PT_physics_fluid_springs" + bl_options = {'DEFAULT_CLOSED'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} - row = layout.row() - row.template_list("UI_UL_list", "particle_targets", psys, "targets", - psys, "active_particle_target_index", rows=4) - - col = row.column() - sub = col.row() - subsub = sub.column(align=True) - subsub.operator("particle.new_target", icon='ZOOMIN', text="") - subsub.operator("particle.target_remove", icon='ZOOMOUT', text="") - sub = col.row() - subsub = sub.column(align=True) - subsub.operator("particle.target_move_up", icon='TRIA_UP', text="") - subsub.operator("particle.target_move_down", icon='TRIA_DOWN', text="") - - key = psys.active_particle_target - if key: - row = layout.row() - if part.physics_type == 'KEYED': - col = row.column() - # doesn't work yet - #col.alert = key.valid - col.prop(key, "object", text="") - col.prop(key, "system", text="System") - col = row.column() - col.active = psys.use_keyed_timing - col.prop(key, "time") - col.prop(key, "duration") - elif part.physics_type == 'BOIDS': - sub = row.row() - # doesn't work yet - #sub.alert = key.valid - sub.prop(key, "object", text="") - sub.prop(key, "system", text="System") - - layout.row().prop(key, "alliance", expand=True) - elif part.physics_type == 'FLUID': - sub = row.row() - # doesn't work yet - #sub.alert = key.valid - sub.prop(key, "object", text="") - sub.prop(key, "system", text="System") + @classmethod + def poll(cls, context): + part = particle_get_settings(context) + fluid = part.fluid + if part.physics_type == 'FLUID' and fluid.solver == 'DDR': + return True + else: + return False + + def draw_header(self, context): + psys = context.particle_system + part = particle_get_settings(context) + fluid = part.fluid + + self.layout.prop(fluid, "use_viscoelastic_springs", text="") + + def draw(self, context): + layout = self.layout + layout.use_property_split = True + + psys = context.particle_system + part = particle_get_settings(context) + fluid = part.fluid + + col = layout.column() + col.active = fluid.use_viscoelastic_springs + col.prop(fluid, "yield_ratio", slider=True) + col.prop(fluid, "plasticity", slider=True) + + col.separator() + + col.prop(fluid, "use_initial_rest_length") + col.prop(fluid, "spring_frames", text="Frames") + + +class PARTICLE_PT_physics_fluid_springs_advanced(ParticleButtonsPanel, Panel): + bl_label = "Advanced" + bl_parent_id = "PARTICLE_PT_physics_fluid_springs" + bl_options = {'DEFAULT_CLOSED'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} + + @classmethod + def poll(cls, context): + part = particle_get_settings(context) + fluid = part.fluid + if part.physics_type == 'FLUID' and fluid.solver == 'DDR': + return True + else: + return False + + def draw(self, context): + layout = self.layout + layout.use_property_split = True + + psys = context.particle_system + part = particle_get_settings(context) + fluid = part.fluid + + sub = layout.column() + sub.prop(fluid, "rest_length", slider=fluid.factor_rest_length) + sub.prop(fluid, "factor_rest_length") + + +class PARTICLE_PT_physics_boids_movement(ParticleButtonsPanel, Panel): + bl_label = "Movement" + bl_parent_id = "PARTICLE_PT_physics" + bl_options = {'DEFAULT_CLOSED'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} + + @classmethod + def poll(cls, context): + part = particle_get_settings(context) + return part.physics_type in {'BOIDS'} + + def draw(self, context): + layout = self.layout + layout.use_property_split = True + + psys = context.particle_system + part = particle_get_settings(context) + boids = part.boids + + col = layout.column() + + col.prop(boids, "use_flight") + col.prop(boids, "use_land") + col.prop(boids, "use_climb") + + col = layout.column() + + col.active = boids.use_flight + sub = col.column() + sub.prop(boids, "air_speed_max") + sub.prop(boids, "air_speed_min", slider=True) + col.prop(boids, "air_acc_max", slider=True) + col.prop(boids, "air_ave_max", slider=True) + col.prop(boids, "air_personal_space") + row = col.row(align=True) + row.active = (boids.use_land or boids.use_climb) and boids.use_flight + row.prop(boids, "land_smooth") + + layout.separator() + + col = layout.column() + col.active = boids.use_land or boids.use_climb + col.prop(boids, "land_speed_max") + col.prop(boids, "land_jump_speed") + col.prop(boids, "land_acc_max", slider=True) + col.prop(boids, "land_ave_max", slider=True) + col.prop(boids, "land_personal_space") + col.prop(boids, "land_stick_force") + + layout.separator() + + layout.prop(part, "collision_group") + + +class PARTICLE_PT_physics_boids_battle(ParticleButtonsPanel, Panel): + bl_label = "Battle" + bl_parent_id = "PARTICLE_PT_physics" + bl_options = {'DEFAULT_CLOSED'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} + + @classmethod + def poll(cls, context): + part = particle_get_settings(context) + return part.physics_type in {'BOIDS'} + + def draw(self, context): + layout = self.layout + layout.use_property_split = True + + psys = context.particle_system + part = particle_get_settings(context) + boids = part.boids + + col = layout.column() + + col.prop(boids, "health") + col.prop(boids, "strength") + col.prop(boids, "aggression") + col.prop(boids, "accuracy") + col.prop(boids, "range") + + +class PARTICLE_PT_physics_boids_misc(ParticleButtonsPanel, Panel): + bl_label = "Misc" + bl_parent_id = "PARTICLE_PT_physics" + bl_options = {'DEFAULT_CLOSED'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} + + @classmethod + def poll(cls, context): + part = particle_get_settings(context) + return part.physics_type in {'BOIDS'} + + def draw(self, context): + layout = self.layout + layout.use_property_split = True + + psys = context.particle_system + part = particle_get_settings(context) + boids = part.boids + + col = layout.column() + + col.prop(boids, "bank", slider=True) + col.prop(boids, "pitch", slider=True) + col.prop(boids, "height", slider=True) + + +class PARTICLE_PT_physics_relations(ParticleButtonsPanel, Panel): + bl_label = "Relations" + bl_parent_id = "PARTICLE_PT_physics" + bl_options = {'DEFAULT_CLOSED'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} + + @classmethod + def poll(cls, context): + part = particle_get_settings(context) + return part.physics_type in {'KEYED', 'BOIDS', 'FLUID'} + + def draw(self, context): + layout = self.layout + layout.use_property_split = True + + psys = context.particle_system + part = particle_get_settings(context) + + row = layout.row() + row.template_list("UI_UL_list", "particle_targets", psys, "targets", + psys, "active_particle_target_index", rows=4) + + col = row.column() + sub = col.row() + subsub = sub.column(align=True) + subsub.operator("particle.new_target", icon='ZOOMIN', text="") + subsub.operator("particle.target_remove", icon='ZOOMOUT', text="") + sub = col.row() + subsub = sub.column(align=True) + subsub.operator("particle.target_move_up", icon='TRIA_UP', text="") + subsub.operator("particle.target_move_down", icon='TRIA_DOWN', text="") + + key = psys.active_particle_target + + if key: + if part.physics_type == 'KEYED': + col = layout.column() + # doesn't work yet + #col.alert = key.valid + col.prop(key, "object") + col.prop(key, "system", text="System") + + col.active = psys.use_keyed_timing + col.prop(key, "time") + col.prop(key, "duration") + elif part.physics_type == 'BOIDS': + sub = layout.column() + # doesn't work yet + #sub.alert = key.valid + sub.prop(key, "object") + sub.prop(key, "system", text="System") + layout.prop(key, "alliance") + elif part.physics_type == 'FLUID': + sub = layout.column() + # doesn't work yet + #sub.alert = key.valid + sub.prop(key, "object") + sub.prop(key, "system", text="System") class PARTICLE_PT_physics_deflection(ParticleButtonsPanel, Panel): bl_label = "Deflection" bl_parent_id = "PARTICLE_PT_physics" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -852,7 +1024,7 @@ class PARTICLE_PT_physics_deflection(ParticleButtonsPanel, Panel): class PARTICLE_PT_physics_forces(ParticleButtonsPanel, Panel): bl_label = "Forces" bl_parent_id = "PARTICLE_PT_physics" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -879,7 +1051,7 @@ class PARTICLE_PT_physics_integration(ParticleButtonsPanel, Panel): bl_label = "Integration" bl_options = {'DEFAULT_CLOSED'} bl_parent_id = "PARTICLE_PT_physics" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -911,7 +1083,10 @@ class PARTICLE_PT_physics_integration(ParticleButtonsPanel, Panel): class PARTICLE_PT_boidbrain(ParticleButtonsPanel, Panel): bl_label = "Boid Brain" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + bl_options = {'DEFAULT_CLOSED'} + bl_parent_id = "PARTICLE_PT_physics" + + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -1015,7 +1190,7 @@ class PARTICLE_PT_boidbrain(ParticleButtonsPanel, Panel): class PARTICLE_PT_render(ParticleButtonsPanel, Panel): bl_label = "Render" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -1055,7 +1230,7 @@ class PARTICLE_PT_render_extra(ParticleButtonsPanel, Panel): bl_label = "Extra" bl_parent_id = "PARTICLE_PT_render" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -1082,7 +1257,7 @@ class PARTICLE_PT_render_line(ParticleButtonsPanel, Panel): bl_label = "Line" bl_parent_id = "PARTICLE_PT_render" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -1110,7 +1285,7 @@ class PARTICLE_PT_render_path(ParticleButtonsPanel, Panel): bl_label = "Path" bl_parent_id = "PARTICLE_PT_render" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -1145,7 +1320,7 @@ class PARTICLE_PT_render_path_timing(ParticleButtonsPanel, Panel): bl_label = "Timing" bl_parent_id = "PARTICLE_PT_render" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -1177,7 +1352,7 @@ class PARTICLE_PT_render_object(ParticleButtonsPanel, Panel): bl_label = "Object" bl_parent_id = "PARTICLE_PT_render" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -1205,7 +1380,7 @@ class PARTICLE_PT_render_collection(ParticleButtonsPanel, Panel): bl_label = "Collection" bl_parent_id = "PARTICLE_PT_render" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -1237,7 +1412,7 @@ class PARTICLE_PT_render_collection_use_count(ParticleButtonsPanel, Panel): bl_label = "Use Count" bl_parent_id = "PARTICLE_PT_render_collection" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -1288,7 +1463,7 @@ class PARTICLE_PT_render_billboards_alignment(ParticleButtonsPanel, Panel): bl_label = "Billboard Alignment" bl_parent_id = "PARTICLE_PT_render" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -1314,7 +1489,7 @@ class PARTICLE_PT_render_billboards_tilt(ParticleButtonsPanel, Panel): bl_label = "Billboard Tilt" bl_parent_id = "PARTICLE_PT_render" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -1348,7 +1523,7 @@ class PARTICLE_PT_render_billboards_uv(ParticleButtonsPanel, Panel): bl_label = "Billboard UVs" bl_parent_id = "PARTICLE_PT_render" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -1384,7 +1559,7 @@ class PARTICLE_PT_render_trails(ParticleButtonsPanel, Panel): bl_label = "Trails" bl_parent_id = "PARTICLE_PT_render" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -1412,7 +1587,7 @@ class PARTICLE_PT_render_trails(ParticleButtonsPanel, Panel): class PARTICLE_PT_draw(ParticleButtonsPanel, Panel): bl_label = "Viewport Display" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -1474,7 +1649,7 @@ class PARTICLE_PT_draw(ParticleButtonsPanel, Panel): class PARTICLE_PT_children(ParticleButtonsPanel, Panel): bl_label = "Children" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -1530,7 +1705,7 @@ class PARTICLE_PT_children_parting(ParticleButtonsPanel, Panel): bl_label = "Parting" bl_parent_id = "PARTICLE_PT_children" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -1555,7 +1730,7 @@ class PARTICLE_PT_children_clumping(ParticleButtonsPanel, Panel): bl_label = "Clumping" bl_parent_id = "PARTICLE_PT_children" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -1597,7 +1772,7 @@ class PARTICLE_PT_children_roughness(ParticleButtonsPanel, Panel): bl_label = "Roughness" bl_parent_id = "PARTICLE_PT_children" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -1639,7 +1814,7 @@ class PARTICLE_PT_children_kink(ParticleButtonsPanel, Panel): bl_label = "Kink" bl_parent_id = "PARTICLE_PT_children" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -1690,7 +1865,7 @@ class PARTICLE_PT_children_kink(ParticleButtonsPanel, Panel): class PARTICLE_PT_field_weights(ParticleButtonsPanel, Panel): bl_label = "Field Weights" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -1711,7 +1886,7 @@ class PARTICLE_PT_field_weights(ParticleButtonsPanel, Panel): class PARTICLE_PT_force_fields(ParticleButtonsPanel, Panel): bl_label = "Force Field Settings" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw(self, context): layout = self.layout @@ -1727,7 +1902,7 @@ class PARTICLE_PT_force_fields(ParticleButtonsPanel, Panel): class PARTICLE_PT_force_fields_type1(ParticleButtonsPanel, Panel): bl_label = "Type 1" bl_parent_id = "PARTICLE_PT_force_fields" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw(self, context): layout = self.layout @@ -1743,7 +1918,7 @@ class PARTICLE_PT_force_fields_type1(ParticleButtonsPanel, Panel): class PARTICLE_PT_force_fields_type2(ParticleButtonsPanel, Panel): bl_label = "Type 2" bl_parent_id = "PARTICLE_PT_force_fields" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw(self, context): layout = self.layout @@ -1760,7 +1935,7 @@ class PARTICLE_PT_force_fields_type1_falloff(ParticleButtonsPanel, Panel): bl_label = "Falloff" bl_options = {'DEFAULT_CLOSED'} bl_parent_id = "PARTICLE_PT_force_fields_type1" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw(self, context): layout = self.layout @@ -1775,7 +1950,7 @@ class PARTICLE_PT_force_fields_type2_falloff(ParticleButtonsPanel, Panel): bl_label = "Falloff" bl_options = {'DEFAULT_CLOSED'} bl_parent_id = "PARTICLE_PT_force_fields_type2" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw(self, context): layout = self.layout @@ -1789,7 +1964,7 @@ class PARTICLE_PT_force_fields_type2_falloff(ParticleButtonsPanel, Panel): class PARTICLE_PT_vertexgroups(ParticleButtonsPanel, Panel): bl_label = "Vertex Groups" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -1862,7 +2037,7 @@ class PARTICLE_PT_vertexgroups(ParticleButtonsPanel, Panel): class PARTICLE_PT_textures(ParticleButtonsPanel, Panel): bl_label = "Textures" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -1894,7 +2069,7 @@ class PARTICLE_PT_textures(ParticleButtonsPanel, Panel): class PARTICLE_PT_hair_shape(ParticleButtonsPanel, Panel): bl_label = "Hair Shape" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -1921,7 +2096,7 @@ class PARTICLE_PT_hair_shape(ParticleButtonsPanel, Panel): class PARTICLE_PT_custom_props(ParticleButtonsPanel, PropertyPanel, Panel): - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} _context_path = "particle_system.settings" _property_type = bpy.types.ParticleSettings @@ -1941,9 +2116,17 @@ classes = ( PARTICLE_PT_rotation, PARTICLE_PT_rotation_angular_velocity, PARTICLE_PT_physics, + PARTICLE_PT_physics_fluid_springs, + PARTICLE_PT_physics_fluid_springs_viscoelastic, + PARTICLE_PT_physics_fluid_springs_advanced, + PARTICLE_PT_physics_fluid_advanced, + PARTICLE_PT_physics_boids_movement, + PARTICLE_PT_physics_boids_battle, + PARTICLE_PT_physics_boids_misc, PARTICLE_PT_physics_forces, PARTICLE_PT_physics_deflection, PARTICLE_PT_physics_integration, + PARTICLE_PT_physics_relations, PARTICLE_PT_boidbrain, PARTICLE_PT_render, PARTICLE_PT_render_line, diff --git a/release/scripts/startup/bl_ui/properties_physics_cloth.py b/release/scripts/startup/bl_ui/properties_physics_cloth.py index 2f659af3891..0a7318864a3 100644 --- a/release/scripts/startup/bl_ui/properties_physics_cloth.py +++ b/release/scripts/startup/bl_ui/properties_physics_cloth.py @@ -17,8 +17,11 @@ # ##### END GPL LICENSE BLOCK ##### # <pep8 compliant> + import bpy -from bpy.types import Menu, Panel +from bpy.types import ( + Panel, +) from bl_operators.presets import PresetMenu from .properties_physics_common import ( @@ -51,13 +54,14 @@ class PhysicButtonsPanel: class PHYSICS_PT_cloth(PhysicButtonsPanel, Panel): bl_label = "Cloth" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw_header_preset(self, context): CLOTH_PT_presets.draw_panel_header(self.layout) def draw(self, context): layout = self.layout + layout.use_property_split = True md = context.cloth ob = context.object @@ -65,71 +69,89 @@ class PHYSICS_PT_cloth(PhysicButtonsPanel, Panel): layout.active = cloth_panel_enabled(md) - split = layout.split(percentage=0.25) - - split.label(text="Quality:") - split.prop(cloth, "quality", text="Steps") - - split = layout.split(percentage=0.25) + flow = layout.grid_flow(row_major=False, columns=0, even_columns=True, even_rows=False, align=True) - split.label(text="Speed:") - split.prop(cloth, "time_scale", text="Multiplier") + col = flow.column() + col.prop(cloth, "quality", text="Quality Steps") + col.prop(cloth, "time_scale", text="Speed Multiplier") - split = layout.split() + col.separator() - col = split.column() - - col.label(text="Material:") - col.prop(cloth, "mass") + col = flow.column() + col.prop(cloth, "mass", text="Material Mass") col.prop(cloth, "structural_stiffness", text="Structural") col.prop(cloth, "bending_stiffness", text="Bending") - col = split.column() + col.separator() - col.label(text="Damping:") - col.prop(cloth, "spring_damping", text="Spring") + col = flow.column() + col.prop(cloth, "spring_damping", text="Damping Spring") col.prop(cloth, "air_damping", text="Air") col.prop(cloth, "vel_damping", text="Velocity") - split = layout.split() + col = flow.column() + col.prop(cloth, "use_dynamic_mesh", text="Dynamic Mesh") - col = split.column() + key = ob.data.shape_keys - col.prop(cloth, "use_pin_cloth", text="Pinning:") - sub = col.column() - sub.active = cloth.use_pin_cloth - sub.prop_search(cloth, "vertex_group_mass", ob, "vertex_groups", text="") - sub.prop(cloth, "pin_stiffness", text="Stiffness") + if key: + # Note: TODO prop_search doesn't align on the right. + row = col.row(align=True) + row.active = not cloth.use_dynamic_mesh + row.prop_search(cloth, "rest_shape_key", key, "key_blocks", text="Rest Shape Key") + row.label(text="", icon='BLANK1') - # Disabled for now - """ - if cloth.vertex_group_mass: - layout.label(text="Goal:") - col = layout.column_flow() - col.prop(cloth, "goal_default", text="Default") - col.prop(cloth, "goal_spring", text="Stiffness") - col.prop(cloth, "goal_friction", text="Friction") - """ +class PHYSICS_PT_cloth_pinning(PhysicButtonsPanel, Panel): + bl_label = "Pinning" + bl_parent_id = 'PHYSICS_PT_cloth' + bl_options = {'DEFAULT_CLOSED'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} - col = split.column() + def draw_header(self, context): + md = context.cloth + cloth = md.settings - col.prop(cloth, "use_dynamic_mesh", text="Dynamic Mesh") + self.layout.active = cloth_panel_enabled(md) and cloth.use_pin_cloth + self.layout.prop(cloth, "use_pin_cloth", text="") - key = ob.data.shape_keys + def draw(self, context): + layout = self.layout + layout.use_property_split = True - if key: - sub = col.column() - sub.active = not cloth.use_dynamic_mesh - sub.label(text="Rest Shape Key:") - sub.prop_search(cloth, "rest_shape_key", key, "key_blocks", text="") + md = context.cloth + ob = context.object + cloth = md.settings + + layout.active = cloth_panel_enabled(md) and cloth.use_pin_cloth + + flow = layout.grid_flow(row_major=False, columns=0, even_columns=True, even_rows=False, align=True) + + col = flow.column() + + # Note: TODO prop_search doesn't align on the right. + row = col.row(align=True) + row.prop_search(cloth, "vertex_group_mass", ob, "vertex_groups", text="Mass Group") + row.label(text="", icon='BLANK1') + + col = flow.column() + col.prop(cloth, "pin_stiffness", text="Stiffness") + + # Disabled for now. + """ + if cloth.vertex_group_mass: + col = flow.column() + col.prop(cloth, "goal_default", text="Goal Default") + col.prop(cloth, "goal_spring", text="Stiffness") + col.prop(cloth, "goal_friction", text="Friction") + """ class PHYSICS_PT_cloth_cache(PhysicButtonsPanel, Panel): bl_label = "Cache" bl_parent_id = 'PHYSICS_PT_cloth' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw(self, context): md = context.cloth @@ -140,7 +162,7 @@ class PHYSICS_PT_cloth_collision(PhysicButtonsPanel, Panel): bl_label = "Collision" bl_parent_id = 'PHYSICS_PT_cloth' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw_header(self, context): cloth = context.cloth.collision_settings @@ -150,38 +172,66 @@ class PHYSICS_PT_cloth_collision(PhysicButtonsPanel, Panel): def draw(self, context): layout = self.layout + layout.use_property_split = True cloth = context.cloth.collision_settings md = context.cloth - ob = context.object layout.active = cloth.use_collision and cloth_panel_enabled(md) - split = layout.split() + flow = layout.grid_flow(row_major=False, columns=0, even_columns=True, even_rows=False, align=True) - col = split.column() + col = flow.column() col.prop(cloth, "collision_quality", text="Quality") col.prop(cloth, "distance_min", slider=True, text="Distance") col.prop(cloth, "repel_force", slider=True, text="Repel") + + col = flow.column() col.prop(cloth, "distance_repel", slider=True, text="Repel Distance") col.prop(cloth, "friction") + col.prop(cloth, "group") + + +class PHYSICS_PT_cloth_self_collision(PhysicButtonsPanel, Panel): + bl_label = "Self Collision" + bl_parent_id = 'PHYSICS_PT_cloth_collision' + bl_options = {'DEFAULT_CLOSED'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} - col = split.column() - col.prop(cloth, "use_self_collision", text="Self Collision") - sub = col.column() - sub.active = cloth.use_self_collision - sub.prop(cloth, "self_collision_quality", text="Quality") - sub.prop(cloth, "self_distance_min", slider=True, text="Distance") - sub.prop_search(cloth, "vertex_group_self_collisions", ob, "vertex_groups", text="") + def draw_header(self, context): + cloth = context.cloth.collision_settings + + self.layout.active = cloth_panel_enabled(context.cloth) and cloth.use_self_collision + self.layout.prop(cloth, "use_self_collision", text="") + + def draw(self, context): + layout = self.layout + layout.use_property_split = True + + cloth = context.cloth.collision_settings + md = context.cloth + ob = context.object + + layout.active = cloth.use_collision and cloth_panel_enabled(md) and cloth.use_self_collision - layout.prop(cloth, "group") + flow = layout.grid_flow(row_major=False, columns=0, even_columns=True, even_rows=False, align=True) + + col = flow.column() + col.prop(cloth, "self_collision_quality", text="Quality") + col.prop(cloth, "self_distance_min", slider=True, text="Distance") + + col = flow.column() + # Note: TODO prop_search doesn't align on the right. + row = col.row(align=True) + row.prop_search(cloth, "vertex_group_self_collisions", ob, "vertex_groups", text="Vertex Group") + row.label(text="", icon='BLANK1') class PHYSICS_PT_cloth_stiffness(PhysicButtonsPanel, Panel): bl_label = "Stiffness Scaling" bl_parent_id = 'PHYSICS_PT_cloth' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw_header(self, context): cloth = context.cloth.settings @@ -191,6 +241,7 @@ class PHYSICS_PT_cloth_stiffness(PhysicButtonsPanel, Panel): def draw(self, context): layout = self.layout + layout.use_property_split = True md = context.cloth ob = context.object @@ -198,16 +249,27 @@ class PHYSICS_PT_cloth_stiffness(PhysicButtonsPanel, Panel): layout.active = (cloth.use_stiffness_scale and cloth_panel_enabled(md)) - split = layout.split() + flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=True) - col = split.column() - col.label(text="Structural Stiffness:") - col.prop_search(cloth, "vertex_group_structural_stiffness", ob, "vertex_groups", text="") + col = flow.column() + # Note: TODO prop_search doesn't align on the right. + row = col.row(align=True) + row.prop_search( + cloth, "vertex_group_structural_stiffness", ob, "vertex_groups", + text="Structural Group" + ) + row.label(text="", icon='BLANK1') col.prop(cloth, "structural_stiffness_max", text="Max") - col = split.column() - col.label(text="Bending Stiffness:") - col.prop_search(cloth, "vertex_group_bending", ob, "vertex_groups", text="") + col.separator() + + col = flow.column() + row = col.row(align=True) + row.prop_search( + cloth, "vertex_group_bending", ob, "vertex_groups", + text="Bending Group" + ) + row.label(text="", icon='BLANK1') col.prop(cloth, "bending_stiffness_max", text="Max") @@ -215,7 +277,7 @@ class PHYSICS_PT_cloth_sewing(PhysicButtonsPanel, Panel): bl_label = "Sewing Springs" bl_parent_id = 'PHYSICS_PT_cloth' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw_header(self, context): cloth = context.cloth.settings @@ -225,23 +287,27 @@ class PHYSICS_PT_cloth_sewing(PhysicButtonsPanel, Panel): def draw(self, context): layout = self.layout + layout.use_property_split = True md = context.cloth ob = context.object cloth = context.cloth.settings layout.active = (cloth.use_sewing_springs and cloth_panel_enabled(md)) + flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=True) - layout.prop(cloth, "sewing_force_max", text="Sewing Force") + col = flow.column() + col.prop(cloth, "sewing_force_max", text="Sewing Force") - split = layout.split() + col.separator() - col = split.column(align=True) - col.label(text="Shrinking:") - col.prop_search(cloth, "vertex_group_shrink", ob, "vertex_groups", text="") + col = col.column() + # Note: TODO prop_search doesn't align on the right. + row = col.row(align=True) + row.prop_search(cloth, "vertex_group_shrink", ob, "vertex_groups", text="Shrinking Group") + row.label(text="", icon='BLANK1') - col = split.column(align=True) - col.label() + col = flow.column(align=True) col.prop(cloth, "shrink_min", text="Min") col.prop(cloth, "shrink_max", text="Max") @@ -250,7 +316,7 @@ class PHYSICS_PT_cloth_field_weights(PhysicButtonsPanel, Panel): bl_label = "Field Weights" bl_parent_id = 'PHYSICS_PT_cloth' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw(self, context): cloth = context.cloth.settings @@ -262,6 +328,8 @@ classes = ( PHYSICS_PT_cloth, PHYSICS_PT_cloth_cache, PHYSICS_PT_cloth_collision, + PHYSICS_PT_cloth_self_collision, + PHYSICS_PT_cloth_pinning, PHYSICS_PT_cloth_stiffness, PHYSICS_PT_cloth_sewing, PHYSICS_PT_cloth_field_weights, diff --git a/release/scripts/startup/bl_ui/properties_physics_common.py b/release/scripts/startup/bl_ui/properties_physics_common.py index e071de0108b..2da84ad84da 100644 --- a/release/scripts/startup/bl_ui/properties_physics_common.py +++ b/release/scripts/startup/bl_ui/properties_physics_common.py @@ -56,7 +56,7 @@ def physics_add_special(self, layout, data, name, addop, removeop, typeicon): class PHYSICS_PT_add(PhysicButtonsPanel, Panel): bl_label = "" bl_options = {'HIDE_HEADER'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw(self, context): obj = context.object @@ -97,7 +97,7 @@ class PHYSICS_PT_add(PhysicButtonsPanel, Panel): 'CONSTRAINT') # RB_TODO needs better icon -# cache-type can be 'PSYS' 'HAIR' 'SMOKE' etc +# cache-type can be 'PSYS' 'HAIR' 'SMOKE' etc. def point_cache_ui(self, context, cache, enabled, cachetype): layout = self.layout @@ -112,8 +112,8 @@ def point_cache_ui(self, context, cache, enabled, cachetype): col.operator("ptcache.add", icon='ZOOMIN', text="") col.operator("ptcache.remove", icon='ZOOMOUT', text="") - row = layout.row() if cachetype in {'PSYS', 'HAIR', 'SMOKE'}: + row = layout.row() row.prop(cache, "use_external") if cachetype == 'SMOKE': @@ -131,7 +131,9 @@ def point_cache_ui(self, context, cache, enabled, cachetype): cache_info = cache.info if cache_info: - layout.label(text=cache_info) + col = layout.column() + col.alignment = 'RIGHT' + col.label(text=cache_info) else: if cachetype in {'SMOKE', 'DYNAMIC_PAINT'}: if not bpy.data.is_saved: @@ -147,45 +149,54 @@ def point_cache_ui(self, context, cache, enabled, cachetype): col.enabled = enabled col.prop(cache, "frame_start", text="Simulation Start") col.prop(cache, "frame_end") + if cachetype not in {'SMOKE', 'CLOTH', 'DYNAMIC_PAINT', 'RIGID_BODY'}: col.prop(cache, "frame_step") - if cachetype != 'SMOKE': - layout.label(text=cache.info) + cache_info = cache.info + if cachetype != 'SMOKE' and cache_info: # avoid empty space. + col = layout.column(align=True) + col.alignment = 'RIGHT' + col.label(text=cache_info) can_bake = True if cachetype not in {'SMOKE', 'DYNAMIC_PAINT', 'RIGID_BODY'}: - split = layout.split() - split.enabled = enabled and bpy.data.is_saved + flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=True) + flow.enabled = enabled and bpy.data.is_saved - col = split.column() - col.prop(cache, "use_disk_cache") + flow.use_property_split = True - col = split.column() - col.active = cache.use_disk_cache - col.prop(cache, "use_library_path", "Use Lib Path") + # NOTE: TODO temporarly used until the animate properties are properly skipped. + flow.use_property_decorate = False # No animation (remove this later on) - row = layout.row() - row.enabled = enabled and bpy.data.is_saved - row.active = cache.use_disk_cache - row.label(text="Compression:") - row.prop(cache, "compression", expand=True) + col = flow.column() + col.prop(cache, "use_disk_cache") - layout.separator() + subcol = col.column() + subcol.active = cache.use_disk_cache + subcol.prop(cache, "use_library_path", "Use Lib Path") + + col = flow.column() + col.enabled = enabled and bpy.data.is_saved + col.active = cache.use_disk_cache + col.prop(cache, "compression", text="Compression", expand=True) if cache.id_data.library and not cache.use_disk_cache: can_bake = False col = layout.column(align=True) - col.label(text="Linked object baking requires Disk Cache to be enabled", icon='INFO') + col.alignment = 'RIGHT' + + col.separator() + + col.label(text="Linked object baking requires Disk Cache to be enabled") else: layout.separator() - split = layout.split() - split.active = can_bake - - col = split.column() + flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=False) + col = flow.column() + col.active = can_bake if cache.is_baked is True: col.operator("ptcache.free_bake", text="Free Bake") @@ -200,7 +211,7 @@ def point_cache_ui(self, context, cache, enabled, cachetype): sub.enabled = enabled sub.operator("ptcache.bake_from_cache", text="Current Cache to Bake") - col = split.column() + col = flow.column() col.operator("ptcache.bake_all", text="Bake All Dynamics").bake = True col.operator("ptcache.free_bake_all", text="Free All Bakes") col.operator("ptcache.bake_all", text="Update All To Frame").bake = False @@ -212,31 +223,31 @@ def effector_weights_ui(self, context, weights, weight_type): layout.prop(weights, "group") - layout.use_property_split = False - - split = layout.split() - - split.prop(weights, "gravity", slider=True) - split.prop(weights, "all", slider=True) + # NOTE: TODO temporarly used until the animate properties are properly skipped + layout.use_property_decorate = False # No animation (remove this later on) - layout.separator() + flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=True) - split = layout.split() - - col = split.column() + col = flow.column() + col.prop(weights, "gravity", slider=True) + col.prop(weights, "all", slider=True) col.prop(weights, "force", slider=True) col.prop(weights, "vortex", slider=True) + + col = flow.column() col.prop(weights, "magnetic", slider=True) + col.prop(weights, "harmonic", slider=True) + col.prop(weights, "charge", slider=True) + col.prop(weights, "lennardjones", slider=True) + + col = flow.column() col.prop(weights, "wind", slider=True) col.prop(weights, "curve_guide", slider=True) col.prop(weights, "texture", slider=True) if weight_type != 'SMOKE': col.prop(weights, "smokeflow", slider=True) - col = split.column() - col.prop(weights, "harmonic", slider=True) - col.prop(weights, "charge", slider=True) - col.prop(weights, "lennardjones", slider=True) + col = flow.column() col.prop(weights, "turbulence", slider=True) col.prop(weights, "drag", slider=True) col.prop(weights, "boid", slider=True) diff --git a/release/scripts/startup/bl_ui/properties_physics_dynamicpaint.py b/release/scripts/startup/bl_ui/properties_physics_dynamicpaint.py index 6a66dafadf0..3a475c82f5c 100644 --- a/release/scripts/startup/bl_ui/properties_physics_dynamicpaint.py +++ b/release/scripts/startup/bl_ui/properties_physics_dynamicpaint.py @@ -60,7 +60,7 @@ class PhysicButtonsPanel: class PHYSICS_PT_dynamic_paint(PhysicButtonsPanel, Panel): bl_label = "Dynamic Paint" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw(self, context): layout = self.layout @@ -87,24 +87,21 @@ class PHYSICS_PT_dynamic_paint(PhysicButtonsPanel, Panel): col.operator("dpaint.surface_slot_add", icon='ZOOMIN', text="") col.operator("dpaint.surface_slot_remove", icon='ZOOMOUT', text="") + layout.use_property_split = True + if surface: layout.prop(surface, "surface_format") col = layout.column() if surface.surface_format != 'VERTEX': - col.label(text="Quality:") col.prop(surface, "image_resolution") col.prop(surface, "use_antialiasing") - col = layout.column() - col.label(text="Frames:") - split = col.split() - - col = split.column(align=True) - col.prop(surface, "frame_start", text="Start") - col.prop(surface, "frame_end", text="End") + sub = col.column(align=True) + sub.prop(surface, "frame_start", text="Frame Start") + sub.prop(surface, "frame_end", text="End") - split.prop(surface, "frame_substeps") + col.prop(surface, "frame_substeps") elif md.ui_type == 'BRUSH': brush = md.brush_settings @@ -114,22 +111,20 @@ class PHYSICS_PT_dynamic_paint(PhysicButtonsPanel, Panel): else: layout.operator("dpaint.type_toggle", text="Remove Brush", icon='X').type = 'BRUSH' - split = layout.split() + layout.use_property_split = True - col = split.column() + col = layout.column() + col.prop(brush, "paint_color") + col.prop(brush, "paint_alpha", text="Alpha", slider=True) + col.prop(brush, "paint_wetness", text="Wetness", slider=True) col.prop(brush, "use_absolute_alpha") col.prop(brush, "use_paint_erase") - col.prop(brush, "paint_wetness", text="Wetness") - - col = split.column() - col.prop(brush, "paint_color", text="") - col.prop(brush, "paint_alpha", text="Alpha") class PHYSICS_PT_dp_advanced_canvas(PhysicButtonsPanel, Panel): bl_label = "Advanced" bl_parent_id = "PHYSICS_PT_dynamic_paint" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -141,72 +136,119 @@ class PHYSICS_PT_dp_advanced_canvas(PhysicButtonsPanel, Panel): canvas = context.dynamic_paint.canvas_settings surface = canvas.canvas_surfaces.active - surface_type = surface.surface_type + layout.use_property_split = True + layout.prop(surface, "surface_type") + layout.separator() - # dissolve - if surface_type == 'PAINT': - split = layout.split(percentage=0.35) - split.prop(surface, "use_drying", text="Dry:") - - col = split.column() - col.active = surface.use_drying - split = col.split(percentage=0.7) - col = split.column(align=True) - col.prop(surface, "dry_speed", text="Time") - col.prop(surface, "color_dry_threshold") - split.prop(surface, "use_dry_log", text="Slow") - - if surface_type != 'WAVE': - split = layout.split(percentage=0.35) - col = split.column() - if surface_type == 'WEIGHT': - col.prop(surface, "use_dissolve", text="Fade:") - else: - col.prop(surface, "use_dissolve", text="Dissolve:") - col = split.column() - col.active = surface.use_dissolve - split = col.split(percentage=0.7) - split.prop(surface, "dissolve_speed", text="Time") - split.prop(surface, "use_dissolve_log", text="Slow") + col = layout.column() # per type settings if surface_type == 'DISPLACE': - layout.prop(surface, "use_incremental_displace") + col.prop(surface, "use_incremental_displace") if surface.surface_format == 'VERTEX': - row = layout.row() - row.prop(surface, "depth_clamp") - row.prop(surface, "displace_factor") - - elif surface_type == 'WAVE': - layout.prop(surface, "use_wave_open_border") + col.prop(surface, "depth_clamp") + col.prop(surface, "displace_factor") - split = layout.split() + col.separator() - col = split.column(align=True) + elif surface_type == 'WAVE': + col.prop(surface, "use_wave_open_border") col.prop(surface, "wave_timescale") col.prop(surface, "wave_speed") - - col = split.column(align=True) col.prop(surface, "wave_damping") col.prop(surface, "wave_spring") col.prop(surface, "wave_smoothness") - layout.separator() - layout.prop(surface, "brush_group") - row = layout.row() - row.prop(surface, "brush_influence_scale") - row.prop(surface, "brush_radius_scale") + col.separator() + + col.prop(surface, "brush_group") + col.prop(surface, "brush_influence_scale") + col.prop(surface, "brush_radius_scale") + + +class PHYSICS_PT_dp_advanced_canvas_paint_dry(PhysicButtonsPanel, Panel): + bl_label = "Dry" + bl_parent_id = "PHYSICS_PT_dp_advanced_canvas" + bl_options = {'DEFAULT_CLOSED'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} + + @classmethod + def poll(cls, context): + md = context.dynamic_paint + canvas = context.dynamic_paint.canvas_settings + surface = canvas.canvas_surfaces.active + surface_type = surface.surface_type + + return md and md.ui_type == 'CANVAS' and md.canvas_settings and md.canvas_settings.canvas_surfaces.active and surface_type == 'PAINT' and context.engine in cls.COMPAT_ENGINES + + def draw_header(self, context): + canvas = context.dynamic_paint.canvas_settings + surface = canvas.canvas_surfaces.active + self.layout.prop(surface, "use_drying", text="") + + def draw(self, context): + layout = self.layout + + canvas = context.dynamic_paint.canvas_settings + surface = canvas.canvas_surfaces.active + surface_type = surface.surface_type + + layout.use_property_split = True + + layout.active = surface.use_drying + + col = layout.column() + col.prop(surface, "dry_speed", text="Time") + col.prop(surface, "color_dry_threshold") + col.prop(surface, "use_dry_log", text="Slow") + + +class PHYSICS_PT_dp_advanced_canvas_paint_dissolve(PhysicButtonsPanel, Panel): + bl_label = "Dissolve" + bl_parent_id = "PHYSICS_PT_dp_advanced_canvas" + bl_options = {'DEFAULT_CLOSED'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} + + @classmethod + def poll(cls, context): + md = context.dynamic_paint + canvas = context.dynamic_paint.canvas_settings + surface = canvas.canvas_surfaces.active + surface_type = surface.surface_type + + return md and md.ui_type == 'CANVAS' and md.canvas_settings and md.canvas_settings.canvas_surfaces.active and surface_type != 'WAVE' and context.engine in cls.COMPAT_ENGINES + + def draw_header(self, context): + canvas = context.dynamic_paint.canvas_settings + surface = canvas.canvas_surfaces.active + self.layout.prop(surface, "use_dissolve", text="") + + def draw(self, context): + layout = self.layout + + canvas = context.dynamic_paint.canvas_settings + surface = canvas.canvas_surfaces.active + surface_type = surface.surface_type + + layout.use_property_split = True + + layout.active = surface.use_dissolve + + col = layout.column() + + col.prop(surface, "dissolve_speed", text="Time") + col.prop(surface, "use_dissolve_log", text="Slow") class PHYSICS_PT_dp_canvas_output(PhysicButtonsPanel, Panel): bl_label = "Output" bl_parent_id = "PHYSICS_PT_dynamic_paint" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -220,6 +262,7 @@ class PHYSICS_PT_dp_canvas_output(PhysicButtonsPanel, Panel): def draw(self, context): layout = self.layout + layout.use_property_split = True canvas = context.dynamic_paint.canvas_settings surface = canvas.canvas_surfaces.active @@ -300,7 +343,7 @@ class PHYSICS_PT_dp_canvas_initial_color(PhysicButtonsPanel, Panel): bl_label = "Initial Color" bl_parent_id = "PHYSICS_PT_dynamic_paint" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -317,6 +360,8 @@ class PHYSICS_PT_dp_canvas_initial_color(PhysicButtonsPanel, Panel): surface = canvas.canvas_surfaces.active ob = context.object + layout.use_property_split = True + layout.prop(surface, "init_color_type", expand=False) if surface.init_color_type != 'NONE': layout.separator() @@ -337,7 +382,7 @@ class PHYSICS_PT_dp_effects(PhysicButtonsPanel, Panel): bl_label = "Effects" bl_parent_id = "PHYSICS_PT_dynamic_paint" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -350,44 +395,93 @@ class PHYSICS_PT_dp_effects(PhysicButtonsPanel, Panel): def draw(self, context): layout = self.layout + +class PHYSICS_PT_dp_effects_spread(PhysicButtonsPanel, Panel): + bl_label = "Spread" + bl_parent_id = "PHYSICS_PT_dp_effects" + bl_options = {'DEFAULT_CLOSED'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} + + def draw_header(self, context): canvas = context.dynamic_paint.canvas_settings surface = canvas.canvas_surfaces.active - layout.row().prop(surface, "effect_ui", expand=True) + self.layout.prop(surface, "use_spread", text="") - if surface.effect_ui == 'SPREAD': - layout.prop(surface, "use_spread") + def draw(self, context): + layout = self.layout - row = layout.row() - row.active = surface.use_spread - row.prop(surface, "spread_speed") - row.prop(surface, "color_spread_speed") + layout.use_property_split = True - elif surface.effect_ui == 'DRIP': - layout.prop(surface, "use_drip") + canvas = context.dynamic_paint.canvas_settings + surface = canvas.canvas_surfaces.active + layout.active = surface.use_spread - col = layout.column() - col.active = surface.use_drip - effector_weights_ui(self, context, surface.effector_weights, 'DYNAMIC_PAINT') + col = layout.column() - layout.label(text="Surface Movement:") - row = layout.row() - row.prop(surface, "drip_velocity", slider=True) - row.prop(surface, "drip_acceleration", slider=True) + col.prop(surface, "spread_speed") + col.prop(surface, "color_spread_speed") - elif surface.effect_ui == 'SHRINK': - layout.prop(surface, "use_shrink") - row = layout.row() - row.active = surface.use_shrink - row.prop(surface, "shrink_speed") +class PHYSICS_PT_dp_effects_drip(PhysicButtonsPanel, Panel): + bl_label = "Drip" + bl_parent_id = "PHYSICS_PT_dp_effects" + bl_options = {'DEFAULT_CLOSED'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} + + def draw_header(self, context): + canvas = context.dynamic_paint.canvas_settings + surface = canvas.canvas_surfaces.active + + self.layout.prop(surface, "use_drip", text="") + + def draw(self, context): + layout = self.layout + layout.use_property_split = True + + canvas = context.dynamic_paint.canvas_settings + surface = canvas.canvas_surfaces.active + + layout.active = surface.use_drip + + col = layout.column() + col.prop(surface, "drip_velocity", slider=True) + col.prop(surface, "drip_acceleration", slider=True) + + col.separator() + + effector_weights_ui(self, context, surface.effector_weights, 'DYNAMIC_PAINT') + + +class PHYSICS_PT_dp_effects_shrink(PhysicButtonsPanel, Panel): + bl_label = "Shrink" + bl_parent_id = "PHYSICS_PT_dp_effects" + bl_options = {'DEFAULT_CLOSED'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} + + def draw_header(self, context): + canvas = context.dynamic_paint.canvas_settings + surface = canvas.canvas_surfaces.active + + self.layout.prop(surface, "use_shrink", text="") + + def draw(self, context): + layout = self.layout + + layout.use_property_split = True + + canvas = context.dynamic_paint.canvas_settings + surface = canvas.canvas_surfaces.active + layout.active = surface.use_shrink + + layout.prop(surface, "shrink_speed") class PHYSICS_PT_dp_cache(PhysicButtonsPanel, Panel): bl_label = "Cache" bl_parent_id = "PHYSICS_PT_dynamic_paint" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -409,7 +503,7 @@ class PHYSICS_PT_dp_cache(PhysicButtonsPanel, Panel): class PHYSICS_PT_dp_brush_source(PhysicButtonsPanel, Panel): bl_label = "Source" bl_parent_id = "PHYSICS_PT_dynamic_paint" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -418,6 +512,7 @@ class PHYSICS_PT_dp_brush_source(PhysicButtonsPanel, Panel): def draw(self, context): layout = self.layout + layout.use_property_split = True brush = context.dynamic_paint.brush_settings ob = context.object @@ -427,7 +522,7 @@ class PHYSICS_PT_dp_brush_source(PhysicButtonsPanel, Panel): col.prop(brush, "paint_source") if brush.paint_source == 'PARTICLE_SYSTEM': - col.prop_search(brush, "particle_system", ob, "particle_systems", text="") + col.prop_search(brush, "particle_system", ob, "particle_systems") if brush.particle_system: col.label(text="Particle Effect:") sub = col.column() @@ -438,22 +533,19 @@ class PHYSICS_PT_dp_brush_source(PhysicButtonsPanel, Panel): if brush.paint_source in {'DISTANCE', 'VOLUME_DISTANCE', 'POINT'}: col.prop(brush, "paint_distance", text="Paint Distance") - split = layout.row().split(percentage=0.4) - sub = split.column() + if brush.paint_source in {'DISTANCE', 'VOLUME_DISTANCE'}: - sub.prop(brush, "use_proximity_project") + col.prop(brush, "use_proximity_project") if brush.paint_source == 'VOLUME_DISTANCE': - sub.prop(brush, "invert_proximity") - sub.prop(brush, "use_negative_volume") - - sub = split.column() + col.prop(brush, "invert_proximity") + col.prop(brush, "use_negative_volume") if brush.paint_source in {'DISTANCE', 'VOLUME_DISTANCE'}: - column = sub.column() - column.active = brush.use_proximity_project - column.prop(brush, "ray_direction") - sub.prop(brush, "proximity_falloff") + sub = col.column() + sub.active = brush.use_proximity_project + sub.prop(brush, "ray_direction") + col.prop(brush, "proximity_falloff") if brush.proximity_falloff == 'RAMP': - col = layout.row().column() + col.separator() col.prop(brush, "use_proximity_ramp_alpha", text="Only Use Alpha") col.template_color_ramp(brush, "paint_ramp", expand=True) @@ -463,7 +555,7 @@ class PHYSICS_PT_dp_brush_velocity(PhysicButtonsPanel, Panel): bl_label = "Velocity" bl_parent_id = "PHYSICS_PT_dynamic_paint" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -472,35 +564,52 @@ class PHYSICS_PT_dp_brush_velocity(PhysicButtonsPanel, Panel): def draw(self, context): layout = self.layout + layout.use_property_split = True brush = context.dynamic_paint.brush_settings - split = layout.split() - - col = split.column() + col = layout.column() col.prop(brush, "use_velocity_alpha") col.prop(brush, "use_velocity_color") - - split.prop(brush, "use_velocity_depth") + col.prop(brush, "use_velocity_depth") col = layout.column() col.active = (brush.use_velocity_alpha or brush.use_velocity_color or brush.use_velocity_depth) col.prop(brush, "velocity_max") col.template_color_ramp(brush, "velocity_ramp", expand=True) - layout.separator() - row = layout.row() - row.prop(brush, "use_smudge") - sub = row.row() - sub.active = brush.use_smudge - sub.prop(brush, "smudge_strength") + +class PHYSICS_PT_dp_brush_velocity_smudge(PhysicButtonsPanel, Panel): + bl_label = "Smudge" + bl_parent_id = "PHYSICS_PT_dp_brush_velocity" + bl_options = {'DEFAULT_CLOSED'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} + + @classmethod + def poll(cls, context): + md = context.dynamic_paint + return md and md.ui_type == 'BRUSH' and md.brush_settings and (context.engine in cls.COMPAT_ENGINES) + + def draw_header(self, context): + brush = context.dynamic_paint.brush_settings + + self.layout.prop(brush, "use_smudge", text="") + + def draw(self, context): + layout = self.layout + layout.use_property_split = True + + brush = context.dynamic_paint.brush_settings + + layout.active = brush.use_smudge + layout.prop(brush, "smudge_strength", slider=True) class PHYSICS_PT_dp_brush_wave(PhysicButtonsPanel, Panel): bl_label = "Waves" bl_parent_id = "PHYSICS_PT_dynamic_paint" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -509,26 +618,33 @@ class PHYSICS_PT_dp_brush_wave(PhysicButtonsPanel, Panel): def draw(self, context): layout = self.layout + layout.use_property_split = True brush = context.dynamic_paint.brush_settings layout.prop(brush, "wave_type") if brush.wave_type != 'REFLECT': - row = layout.row() - row.prop(brush, "wave_factor") - row.prop(brush, "wave_clamp") + col = layout.column() + col.prop(brush, "wave_factor") + col.prop(brush, "wave_clamp") classes = ( PHYSICS_UL_dynapaint_surfaces, PHYSICS_PT_dynamic_paint, PHYSICS_PT_dp_advanced_canvas, + PHYSICS_PT_dp_advanced_canvas_paint_dry, + PHYSICS_PT_dp_advanced_canvas_paint_dissolve, PHYSICS_PT_dp_canvas_output, PHYSICS_PT_dp_canvas_initial_color, PHYSICS_PT_dp_effects, + PHYSICS_PT_dp_effects_spread, + PHYSICS_PT_dp_effects_drip, + PHYSICS_PT_dp_effects_shrink, PHYSICS_PT_dp_cache, PHYSICS_PT_dp_brush_source, PHYSICS_PT_dp_brush_velocity, + PHYSICS_PT_dp_brush_velocity_smudge, PHYSICS_PT_dp_brush_wave, ) diff --git a/release/scripts/startup/bl_ui/properties_physics_field.py b/release/scripts/startup/bl_ui/properties_physics_field.py index 3b01015047f..1a4e24fbc0c 100644 --- a/release/scripts/startup/bl_ui/properties_physics_field.py +++ b/release/scripts/startup/bl_ui/properties_physics_field.py @@ -38,7 +38,7 @@ class PhysicButtonsPanel: class PHYSICS_PT_field(PhysicButtonsPanel, Panel): bl_label = "Force Fields" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -112,7 +112,7 @@ class PHYSICS_PT_field(PhysicButtonsPanel, Panel): class PHYSICS_PT_field_falloff(PhysicButtonsPanel, Panel): bl_label = "Falloff" bl_parent_id = "PHYSICS_PT_field" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -170,7 +170,7 @@ class PHYSICS_PT_field_falloff(PhysicButtonsPanel, Panel): class PHYSICS_PT_collision(PhysicButtonsPanel, Panel): bl_label = "Collision" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -199,7 +199,7 @@ class PHYSICS_PT_collision(PhysicButtonsPanel, Panel): class PHYSICS_PT_collision_particle(PhysicButtonsPanel, Panel): bl_label = "Particle" bl_parent_id = "PHYSICS_PT_collision" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -241,7 +241,7 @@ class PHYSICS_PT_collision_particle(PhysicButtonsPanel, Panel): class PHYSICS_PT_collision_softbody(PhysicButtonsPanel, Panel): bl_label = "Softbody" bl_parent_id = "PHYSICS_PT_collision" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): diff --git a/release/scripts/startup/bl_ui/properties_physics_rigidbody.py b/release/scripts/startup/bl_ui/properties_physics_rigidbody.py index db59665e21d..d121b6a389d 100644 --- a/release/scripts/startup/bl_ui/properties_physics_rigidbody.py +++ b/release/scripts/startup/bl_ui/properties_physics_rigidbody.py @@ -29,7 +29,7 @@ class PHYSICS_PT_rigidbody_panel: class PHYSICS_PT_rigid_body(PHYSICS_PT_rigidbody_panel, Panel): bl_label = "Rigid Body" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -39,25 +39,27 @@ class PHYSICS_PT_rigid_body(PHYSICS_PT_rigidbody_panel, Panel): def draw(self, context): layout = self.layout + layout.use_property_split = True ob = context.object rbo = ob.rigid_body if rbo is not None: layout.prop(rbo, "type", text="Type") - row = layout.row() - if rbo.type == 'ACTIVE': - row.prop(rbo, "enabled", text="Dynamic") - row.prop(rbo, "kinematic", text="Animated") if rbo.type == 'ACTIVE': layout.prop(rbo, "mass") + col = layout.column() + if rbo.type == 'ACTIVE': + col.prop(rbo, "enabled", text="Dynamic") + col.prop(rbo, "kinematic", text="Animated") + class PHYSICS_PT_rigid_body_collisions(PHYSICS_PT_rigidbody_panel, Panel): bl_label = "Collisions" bl_parent_id = 'PHYSICS_PT_rigid_body' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -70,6 +72,7 @@ class PHYSICS_PT_rigid_body_collisions(PHYSICS_PT_rigidbody_panel, Panel): ob = context.object rbo = ob.rigid_body + layout.use_property_split = True layout.prop(rbo, "collision_shape", text="Shape") @@ -79,15 +82,52 @@ class PHYSICS_PT_rigid_body_collisions(PHYSICS_PT_rigidbody_panel, Panel): if rbo.collision_shape == 'MESH' and rbo.mesh_source == 'DEFORM': layout.prop(rbo, "use_deform", text="Deforming") - split = layout.split() - col = split.column() - col.label(text="Surface Response:") +class PHYSICS_PT_rigid_body_collisions_surface(PHYSICS_PT_rigidbody_panel, Panel): + bl_label = "Surface Response" + bl_parent_id = 'PHYSICS_PT_rigid_body_collisions' + bl_options = {'DEFAULT_CLOSED'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} + + @classmethod + def poll(cls, context): + obj = context.object + return (obj and obj.rigid_body and + (context.engine in cls.COMPAT_ENGINES)) + + def draw(self, context): + layout = self.layout + + ob = context.object + rbo = ob.rigid_body + layout.use_property_split = True + + col = layout.column() col.prop(rbo, "friction") col.prop(rbo, "restitution", text="Bounciness") - col = split.column() - col.label(text="Sensitivity:") + +class PHYSICS_PT_rigid_body_collisions_sensitivity(PHYSICS_PT_rigidbody_panel, Panel): + bl_label = "Sensitivity" + bl_parent_id = 'PHYSICS_PT_rigid_body_collisions' + bl_options = {'DEFAULT_CLOSED'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} + + @classmethod + def poll(cls, context): + obj = context.object + return (obj and obj.rigid_body and + (context.engine in cls.COMPAT_ENGINES)) + + def draw(self, context): + layout = self.layout + + ob = context.object + rbo = ob.rigid_body + layout.use_property_split = True + + col = layout.column() + if rbo.collision_shape in {'MESH', 'CONE'}: col.prop(rbo, "collision_margin", text="Margin") else: @@ -96,14 +136,33 @@ class PHYSICS_PT_rigid_body_collisions(PHYSICS_PT_rigidbody_panel, Panel): sub.active = rbo.use_margin sub.prop(rbo, "collision_margin", text="Margin") - layout.prop(rbo, "collision_groups") + +class PHYSICS_PT_rigid_body_collisions_collections(PHYSICS_PT_rigidbody_panel, Panel): + bl_label = "Collision Collections" + bl_parent_id = 'PHYSICS_PT_rigid_body_collisions' + bl_options = {'DEFAULT_CLOSED'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} + + @classmethod + def poll(cls, context): + obj = context.object + return (obj and obj.rigid_body and + (context.engine in cls.COMPAT_ENGINES)) + + def draw(self, context): + layout = self.layout + + ob = context.object + rbo = ob.rigid_body + + layout.prop(rbo, "collision_groups", text="") class PHYSICS_PT_rigid_body_dynamics(PHYSICS_PT_rigidbody_panel, Panel): bl_label = "Dynamics" bl_parent_id = 'PHYSICS_PT_rigid_body' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -114,6 +173,7 @@ class PHYSICS_PT_rigid_body_dynamics(PHYSICS_PT_rigidbody_panel, Panel): def draw(self, context): layout = self.layout + layout.use_property_split = True ob = context.object rbo = ob.rigid_body @@ -122,28 +182,53 @@ class PHYSICS_PT_rigid_body_dynamics(PHYSICS_PT_rigidbody_panel, Panel): # col.label(text="Activation:") # XXX: settings such as activate on collison/etc. - split = layout.split() + col = layout.column() + col.prop(rbo, "linear_damping", text="Translation Damping") + col.prop(rbo, "angular_damping", text="Rotation Damping") - col = split.column() - col.label(text="Deactivation:") - col.prop(rbo, "use_deactivation") - sub = col.column() - sub.active = rbo.use_deactivation - sub.prop(rbo, "use_start_deactivated") - sub.prop(rbo, "deactivate_linear_velocity", text="Linear Vel") - sub.prop(rbo, "deactivate_angular_velocity", text="Angular Vel") - # TODO: other params such as time? - col = split.column() - col.label(text="Damping:") - col.prop(rbo, "linear_damping", text="Translation") - col.prop(rbo, "angular_damping", text="Rotation") +class PHYSICS_PT_rigid_body_dynamics_deactivation(PHYSICS_PT_rigidbody_panel, Panel): + bl_label = "Deactivation" + bl_parent_id = 'PHYSICS_PT_rigid_body_dynamics' + bl_options = {'DEFAULT_CLOSED'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} + + @classmethod + def poll(cls, context): + obj = context.object + return (obj and obj.rigid_body and + obj.rigid_body.type == 'ACTIVE' and + (context.engine in cls.COMPAT_ENGINES)) + + def draw_header(self, context): + ob = context.object + rbo = ob.rigid_body + self.layout.prop(rbo, "use_deactivation", text="") + + def draw(self, context): + layout = self.layout + layout.use_property_split = True + + ob = context.object + rbo = ob.rigid_body + + layout.active = rbo.use_deactivation + + col = layout.column() + col.prop(rbo, "use_start_deactivated") + col.prop(rbo, "deactivate_linear_velocity", text="Linear Velocity") + col.prop(rbo, "deactivate_angular_velocity", text="Angular Velocity") + # TODO: other params such as time? classes = ( PHYSICS_PT_rigid_body, PHYSICS_PT_rigid_body_collisions, + PHYSICS_PT_rigid_body_collisions_surface, + PHYSICS_PT_rigid_body_collisions_sensitivity, + PHYSICS_PT_rigid_body_collisions_collections, PHYSICS_PT_rigid_body_dynamics, + PHYSICS_PT_rigid_body_dynamics_deactivation, ) if __name__ == "__main__": # only for live edit. diff --git a/release/scripts/startup/bl_ui/properties_physics_rigidbody_constraint.py b/release/scripts/startup/bl_ui/properties_physics_rigidbody_constraint.py index aca989fd0ba..5e67caadc90 100644 --- a/release/scripts/startup/bl_ui/properties_physics_rigidbody_constraint.py +++ b/release/scripts/startup/bl_ui/properties_physics_rigidbody_constraint.py @@ -29,7 +29,7 @@ class PHYSICS_PT_rigidbody_constraint_panel: class PHYSICS_PT_rigid_body_constraint(PHYSICS_PT_rigidbody_constraint_panel, Panel): bl_label = "Rigid Body Constraint" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -139,6 +139,11 @@ class PHYSICS_PT_rigid_body_constraint(PHYSICS_PT_rigidbody_constraint_panel, Pa sub.prop(rbc, "motor_ang_max_impulse", text="Max Impulse") elif rbc.type in {'GENERIC', 'GENERIC_SPRING'}: + if rbc.type == 'GENERIC_SPRING': + row = layout.row() + row.label("Spring Type:") + row.prop(rbc, "spring_type", text="") + col = layout.column(align=True) col.label("Limits:") diff --git a/release/scripts/startup/bl_ui/properties_physics_smoke.py b/release/scripts/startup/bl_ui/properties_physics_smoke.py index acbaecbda4c..0a4f1c71126 100644 --- a/release/scripts/startup/bl_ui/properties_physics_smoke.py +++ b/release/scripts/startup/bl_ui/properties_physics_smoke.py @@ -39,7 +39,7 @@ class PhysicButtonsPanel: class PHYSICS_PT_smoke(PhysicButtonsPanel, Panel): bl_label = "Smoke" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw(self, context): layout = self.layout @@ -138,7 +138,7 @@ class PHYSICS_PT_smoke_flow_advanced(PhysicButtonsPanel, Panel): bl_label = "Advanced" bl_parent_id = 'PHYSICS_PT_smoke' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -174,7 +174,7 @@ class PHYSICS_PT_smoke_fire(PhysicButtonsPanel, Panel): bl_label = "Flames" bl_parent_id = 'PHYSICS_PT_smoke' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -205,7 +205,7 @@ class PHYSICS_PT_smoke_adaptive_domain(PhysicButtonsPanel, Panel): bl_label = "Adaptive Domain" bl_parent_id = 'PHYSICS_PT_smoke' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -240,7 +240,7 @@ class PHYSICS_PT_smoke_highres(PhysicButtonsPanel, Panel): bl_label = "High Resolution" bl_parent_id = 'PHYSICS_PT_smoke' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -280,7 +280,7 @@ class PHYSICS_PT_smoke_groups(PhysicButtonsPanel, Panel): bl_label = "Groups" bl_parent_id = 'PHYSICS_PT_smoke' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -309,7 +309,7 @@ class PHYSICS_PT_smoke_cache(PhysicButtonsPanel, Panel): bl_label = "Cache" bl_parent_id = 'PHYSICS_PT_smoke' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -346,7 +346,7 @@ class PHYSICS_PT_smoke_field_weights(PhysicButtonsPanel, Panel): bl_label = "Field Weights" bl_parent_id = 'PHYSICS_PT_smoke' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): diff --git a/release/scripts/startup/bl_ui/properties_physics_softbody.py b/release/scripts/startup/bl_ui/properties_physics_softbody.py index 68db165875e..77440bdc628 100644 --- a/release/scripts/startup/bl_ui/properties_physics_softbody.py +++ b/release/scripts/startup/bl_ui/properties_physics_softbody.py @@ -46,7 +46,7 @@ class PhysicButtonsPanel: class PHYSICS_PT_softbody(PhysicButtonsPanel, Panel): bl_label = "Soft Body" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw(self, context): layout = self.layout @@ -77,7 +77,7 @@ class PHYSICS_PT_softbody_cache(PhysicButtonsPanel, Panel): bl_label = "Cache" bl_parent_id = 'PHYSICS_PT_softbody' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw(self, context): md = context.soft_body @@ -88,7 +88,7 @@ class PHYSICS_PT_softbody_goal(PhysicButtonsPanel, Panel): bl_label = "Goal" bl_parent_id = 'PHYSICS_PT_softbody' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw_header(self, context): softbody = context.soft_body.settings @@ -129,7 +129,7 @@ class PHYSICS_PT_softbody_edge(PhysicButtonsPanel, Panel): bl_label = "Edges" bl_parent_id = 'PHYSICS_PT_softbody' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw_header(self, context): softbody = context.soft_body.settings @@ -180,7 +180,7 @@ class PHYSICS_PT_softbody_collision(PhysicButtonsPanel, Panel): bl_label = "Self Collision" bl_parent_id = 'PHYSICS_PT_softbody' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw_header(self, context): softbody = context.soft_body.settings @@ -210,7 +210,7 @@ class PHYSICS_PT_softbody_solver(PhysicButtonsPanel, Panel): bl_label = "Solver" bl_parent_id = 'PHYSICS_PT_softbody' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw(self, context): layout = self.layout @@ -244,7 +244,7 @@ class PHYSICS_PT_softbody_field_weights(PhysicButtonsPanel, Panel): bl_label = "Field Weights" bl_parent_id = 'PHYSICS_PT_softbody' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw(self, context): md = context.soft_body diff --git a/release/scripts/startup/bl_ui/properties_render.py b/release/scripts/startup/bl_ui/properties_render.py index a7cfee5ed8f..2b91eec67c4 100644 --- a/release/scripts/startup/bl_ui/properties_render.py +++ b/release/scripts/startup/bl_ui/properties_render.py @@ -21,6 +21,11 @@ import bpy from bpy.types import Menu, Panel, UIList from bl_operators.presets import PresetMenu +from .space_view3d import ( + VIEW3D_PT_shading_lighting, + VIEW3D_PT_shading_color, + VIEW3D_PT_shading_options, +) class RENDER_PT_presets(PresetMenu): @@ -79,7 +84,7 @@ class RENDER_PT_context(Panel): class RENDER_PT_dimensions(RenderButtonsPanel, Panel): bl_label = "Dimensions" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} _frame_rate_args_prev = None _preset_class = None @@ -115,7 +120,7 @@ class RENDER_PT_dimensions(RenderButtonsPanel, Panel): return args @staticmethod - def draw_framerate(sub, rd): + def draw_framerate(layout, sub, rd): if RENDER_PT_dimensions._preset_class is None: RENDER_PT_dimensions._preset_class = bpy.types.RENDER_MT_framerate_presets @@ -125,8 +130,9 @@ class RENDER_PT_dimensions(RenderButtonsPanel, Panel): sub.menu("RENDER_MT_framerate_presets", text=fps_label_text) if show_framerate: - sub.prop(rd, "fps") - sub.prop(rd, "fps_base", text="/") + col = layout.column(align=True) + col.prop(rd, "fps") + col.prop(rd, "fps_base", text="Base") def draw(self, context): layout = self.layout @@ -156,17 +162,17 @@ class RENDER_PT_dimensions(RenderButtonsPanel, Panel): col.prop(scene, "frame_end", text="End") col.prop(scene, "frame_step", text="Step") - col = layout.split(percentage=0.5) + col = layout.split() col.alignment = 'RIGHT' col.label(text="Frame Rate") - self.draw_framerate(col, rd) + self.draw_framerate(layout, col, rd) class RENDER_PT_frame_remapping(RenderButtonsPanel, Panel): bl_label = "Time Remapping" bl_parent_id = "RENDER_PT_dimensions" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw(self, context): layout = self.layout @@ -183,7 +189,7 @@ class RENDER_PT_frame_remapping(RenderButtonsPanel, Panel): class RENDER_PT_post_processing(RenderButtonsPanel, Panel): bl_label = "Post Processing" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw(self, context): layout = self.layout @@ -201,7 +207,7 @@ class RENDER_PT_post_processing(RenderButtonsPanel, Panel): class RENDER_PT_stamp(RenderButtonsPanel, Panel): bl_label = "Metadata" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw(self, context): layout = self.layout @@ -213,23 +219,35 @@ class RENDER_PT_stamp(RenderButtonsPanel, Panel): split = layout.split() col = split.column(align=True) - col.prop(rd, "use_stamp_time", text="Time") col.prop(rd, "use_stamp_date", text="Date") - col.prop(rd, "use_stamp_render_time", text="RenderTime") + col.prop(rd, "use_stamp_time", text="Time") + + col.separator() + + col.prop(rd, "use_stamp_render_time", text="Render Time") col.prop(rd, "use_stamp_frame", text="Frame") - col.prop(rd, "use_stamp_scene", text="Scene") + col.prop(rd, "use_stamp_frame_range", text="Frame Range") col.prop(rd, "use_stamp_memory", text="Memory") col = split.column(align=True) col.prop(rd, "use_stamp_camera", text="Camera") col.prop(rd, "use_stamp_lens", text="Lens") - col.prop(rd, "use_stamp_filename", text="Filename") - col.prop(rd, "use_stamp_frame_range", text="Frame range") + + col.separator() + + col.prop(rd, "use_stamp_scene", text="Scene") col.prop(rd, "use_stamp_marker", text="Marker") - col.prop(rd, "use_stamp_sequencer_strip", text="Seq. Strip") + + col.separator() + + col.prop(rd, "use_stamp_filename", text="Filename") + + col.separator() + + col.prop(rd, "use_stamp_sequencer_strip", text="Strip Name") if rd.use_sequencer: - col.prop(rd, "use_stamp_strip_meta", text="Sequence Strip") + col.prop(rd, "use_stamp_strip_meta", text="Use Strip Metadata") row = layout.split(percentage=0.3) row.prop(rd, "use_stamp_note", text="Note") @@ -242,7 +260,7 @@ class RENDER_PT_stamp_burn(RenderButtonsPanel, Panel): bl_label = "Burn Into Image" bl_parent_id = "RENDER_PT_stamp" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw_header(self, context): rd = context.scene.render @@ -266,7 +284,7 @@ class RENDER_PT_stamp_burn(RenderButtonsPanel, Panel): class RENDER_PT_output(RenderButtonsPanel, Panel): bl_label = "Output" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw(self, context): layout = self.layout @@ -298,7 +316,7 @@ class RENDER_PT_output(RenderButtonsPanel, Panel): class RENDER_PT_encoding(RenderButtonsPanel, Panel): bl_label = "Encoding" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw_header_preset(self, context): RENDER_PT_ffmpeg_presets.draw_panel_header(self.layout) @@ -395,7 +413,7 @@ class RENDER_UL_renderviews(UIList): class RENDER_PT_stereoscopy(RenderButtonsPanel, Panel): bl_label = "Stereoscopy" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} bl_options = {'DEFAULT_CLOSED'} def draw_header(self, context): @@ -589,8 +607,6 @@ class RENDER_PT_eevee_volumetric(RenderButtonsPanel, Panel): sub = col.column() sub.active = props.use_volumetric_shadows sub.prop(props, "volumetric_shadow_samples", text="Shadow Samples") - col.separator() - col.prop(props, "use_volumetric_colored_transmittance") class RENDER_PT_eevee_subsurface_scattering(RenderButtonsPanel, Panel): @@ -777,7 +793,7 @@ class RENDER_PT_eevee_film(RenderButtonsPanel, Panel): col.prop(rd, "alpha_mode", text="Alpha") -class RENDER_PT_hair(RenderButtonsPanel, Panel): +class RENDER_PT_eevee_hair(RenderButtonsPanel, Panel): bl_label = "Hair" bl_options = {'DEFAULT_CLOSED'} COMPAT_ENGINES = {'BLENDER_EEVEE'} @@ -798,6 +814,60 @@ class RENDER_PT_hair(RenderButtonsPanel, Panel): layout.prop(rd, "hair_subdiv") +class RENDER_PT_opengl_film(RenderButtonsPanel, Panel): + bl_label = "Film" + bl_options = {'DEFAULT_CLOSED'} + COMPAT_ENGINES = {'BLENDER_OPENGL'} + + def draw(self, context): + layout = self.layout + layout.use_property_split = True + layout.use_property_decorate = False # No animation. + + rd = context.scene.render + + layout.prop(rd, "use_antialiasing") + + layout.prop(rd, "antialiasing_samples") + layout.prop(rd, "alpha_mode") + + +class RENDER_PT_opengl_lighting(RenderButtonsPanel, Panel): + bl_label = "Lighting" + COMPAT_ENGINES = {'BLENDER_OPENGL'} + + @classmethod + def poll(cls, context): + return (context.engine in cls.COMPAT_ENGINES) + + def draw(self, context): + VIEW3D_PT_shading_lighting.draw(self, context) + + +class RENDER_PT_opengl_color(RenderButtonsPanel, Panel): + bl_label = "Color" + COMPAT_ENGINES = {'BLENDER_OPENGL'} + + @classmethod + def poll(cls, context): + return (context.engine in cls.COMPAT_ENGINES) + + def draw(self, context): + VIEW3D_PT_shading_color.draw(self, context) + + +class RENDER_PT_opengl_options(RenderButtonsPanel, Panel): + bl_label = "Options" + COMPAT_ENGINES = {'BLENDER_OPENGL'} + + @classmethod + def poll(cls, context): + return (context.engine in cls.COMPAT_ENGINES) + + def draw(self, context): + VIEW3D_PT_shading_options.draw(self, context) + + classes = ( RENDER_PT_presets, RENDER_PT_ffmpeg_presets, @@ -812,7 +882,7 @@ classes = ( RENDER_PT_stamp_burn, RENDER_UL_renderviews, RENDER_PT_stereoscopy, - RENDER_PT_hair, + RENDER_PT_eevee_hair, RENDER_PT_eevee_sampling, RENDER_PT_eevee_film, RENDER_PT_eevee_shadows, @@ -824,6 +894,10 @@ classes = ( RENDER_PT_eevee_motion_blur, RENDER_PT_eevee_depth_of_field, RENDER_PT_eevee_bloom, + RENDER_PT_opengl_film, + RENDER_PT_opengl_lighting, + RENDER_PT_opengl_color, + RENDER_PT_opengl_options, ) if __name__ == "__main__": # only for live edit. diff --git a/release/scripts/startup/bl_ui/properties_scene.py b/release/scripts/startup/bl_ui/properties_scene.py index d0fce0a2582..5d87b858da6 100644 --- a/release/scripts/startup/bl_ui/properties_scene.py +++ b/release/scripts/startup/bl_ui/properties_scene.py @@ -17,9 +17,9 @@ # ##### END GPL LICENSE BLOCK ##### # <pep8 compliant> + import bpy from bpy.types import ( - Menu, Panel, UIList, ) @@ -66,11 +66,12 @@ class SceneButtonsPanel: class SCENE_PT_scene(SceneButtonsPanel, Panel): bl_label = "Scene" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw(self, context): layout = self.layout layout.use_property_split = True + scene = context.scene layout.prop(scene, "camera") @@ -80,7 +81,7 @@ class SCENE_PT_scene(SceneButtonsPanel, Panel): class SCENE_PT_unit(SceneButtonsPanel, Panel): bl_label = "Units" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw_header_preset(self, context): SCENE_PT_units_length_presets.draw_panel_header(self.layout) @@ -92,13 +93,13 @@ class SCENE_PT_unit(SceneButtonsPanel, Panel): layout.use_property_split = True - col = layout.column() - col.prop(unit, "system") + flow = layout.grid_flow(row_major=True, columns=0, even_columns=False, even_rows=False, align=True) - col = layout.column() + col = flow.column() + col.prop(unit, "system") col.prop(unit, "system_rotation") - col = layout.column() + col = flow.column() col.enabled = unit.system != 'NONE' col.prop(unit, "scale_length") col.prop(unit, "use_separate") @@ -147,25 +148,28 @@ class SceneKeyingSetsPanel: propname = prop row = layout.row(align=True) - row.prop(item, toggle_prop, text="", icon='STYLUS_PRESSURE', toggle=True) # XXX: needs dedicated icon - subrow = row.row() + subrow = row.row(align=True) subrow.active = getattr(item, toggle_prop) + if subrow.active: subrow.prop(item, prop, text=label) else: subrow.prop(owner, propname, text=label) + row.prop(item, toggle_prop, text="", icon='STYLUS_PRESSURE', toggle=True) # XXX: needs dedicated icon + class SCENE_PT_keying_sets(SceneButtonsPanel, SceneKeyingSetsPanel, Panel): bl_label = "Keying Sets" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw(self, context): layout = self.layout scene = context.scene + row = layout.row() col = row.column() @@ -175,26 +179,62 @@ class SCENE_PT_keying_sets(SceneButtonsPanel, SceneKeyingSetsPanel, Panel): col.operator("anim.keying_set_add", icon='ZOOMIN', text="") col.operator("anim.keying_set_remove", icon='ZOOMOUT', text="") + layout.use_property_split = True + layout.use_property_decorate = False # No animation. + + flow = layout.grid_flow(row_major=False, columns=0, even_columns=False, even_rows=False, align=False) + ks = scene.keying_sets.active if ks and ks.is_path_absolute: - row = layout.row() - - col = row.column() + col = flow.column() col.prop(ks, "bl_description") - subcol = col.column() + subcol = flow.column() subcol.operator_context = 'INVOKE_DEFAULT' subcol.operator("anim.keying_set_export", text="Export to File").filepath = "keyingset.py" - col = row.column() - col.label(text="Keyframing Settings:") - self.draw_keyframing_settings(context, col, ks, None) + +class SCENE_PT_keyframing_settings(SceneButtonsPanel, SceneKeyingSetsPanel, Panel): + bl_label = "Keyframing Settings" + bl_parent_id = "SCENE_PT_keying_sets" + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + + @classmethod + def poll(cls, context): + ks = context.scene.keying_sets.active + return (ks and ks.is_path_absolute) + + def draw(self, context): + layout = self.layout + layout.use_property_split = True + layout.use_property_decorate = False # No animation. + + scene = context.scene + ks = scene.keying_sets.active + + flow = layout.grid_flow(row_major=True, columns=0, even_columns=False, even_rows=False, align=True) + + col = flow.column(align=True) + col.alignment = 'RIGHT' + col.label(text="General Override") + + self.draw_keyframing_settings(context, col, ks, None) + + ksp = ks.paths.active + if ksp: + col.separator() + + col = flow.column(align=True) + col.alignment = 'RIGHT' + col.label(text="Active Set Override") + + self.draw_keyframing_settings(context, col, ks, ksp) class SCENE_PT_keying_set_paths(SceneButtonsPanel, SceneKeyingSetsPanel, Panel): bl_label = "Active Keying Set" bl_parent_id = "SCENE_PT_keying_sets" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -219,39 +259,45 @@ class SCENE_PT_keying_set_paths(SceneButtonsPanel, SceneKeyingSetsPanel, Panel): col.operator("anim.keying_set_path_add", icon='ZOOMIN', text="") col.operator("anim.keying_set_path_remove", icon='ZOOMOUT', text="") + # TODO: 1) the template_any_ID needs to be fixed for the text alignment. + # 2) use_property_decorate has to properly skip the non animatable properties. + # Properties affected with needless draw: + # group_method, template_any_ID dropdown, use_entire_array + + layout.use_property_split = True + layout.use_property_decorate = False # No animation (remove this later on). + + flow = layout.grid_flow(row_major=False, columns=0, even_columns=False, even_rows=False, align=True) + ksp = ks.paths.active if ksp: - col = layout.column() - col.label(text="Target:") - col.template_any_ID(ksp, "id", "id_type") - col.template_path_builder(ksp, "data_path", ksp.id) - - row = col.row(align=True) - row.label(text="Array Target:") - row.prop(ksp, "use_entire_array", text="All Items") - if ksp.use_entire_array: - row.label(text=" ") # padding - else: - row.prop(ksp, "array_index", text="Index") + col = flow.column(align=True) + col.alignment = 'RIGHT' - layout.separator() + col.template_any_ID(ksp, "id", "id_type", text="Target ID-Block") - row = layout.row() - col = row.column() - col.label(text="F-Curve Grouping:") - col.prop(ksp, "group_method", text="") + col.separator() + + col.template_path_builder(ksp, "data_path", ksp.id, text="Data Path") + + col = flow.column() + + col.prop(ksp, "use_entire_array", text="Array All Items") + + if not ksp.use_entire_array: + col.prop(ksp, "array_index", text="Index") + + col.separator() + + col.prop(ksp, "group_method", text="F-Curve Grouping") if ksp.group_method == 'NAMED': col.prop(ksp, "group") - col = row.column() - col.label(text="Keyframing Settings:") - self.draw_keyframing_settings(context, col, ks, ksp) - class SCENE_PT_color_management(SceneButtonsPanel, Panel): bl_label = "Color Management" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw(self, context): layout = self.layout @@ -260,16 +306,19 @@ class SCENE_PT_color_management(SceneButtonsPanel, Panel): scene = context.scene view = scene.view_settings - col = layout.column() + flow = layout.grid_flow(row_major=True, columns=0, even_columns=False, even_rows=False, align=True) + + col = flow.column() col.prop(scene.display_settings, "display_device") col.separator() - col = layout.column() col.prop(view, "view_transform") + col.prop(view, "look") + + col = flow.column() col.prop(view, "exposure") col.prop(view, "gamma") - col.prop(view, "look") col.separator() @@ -280,7 +329,7 @@ class SCENE_PT_color_management_curves(SceneButtonsPanel, Panel): bl_label = "Use Curves" bl_parent_id = "SCENE_PT_color_management" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw_header(self, context): @@ -304,7 +353,7 @@ class SCENE_PT_color_management_curves(SceneButtonsPanel, Panel): class SCENE_PT_audio(SceneButtonsPanel, Panel): bl_label = "Audio" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw(self, context): layout = self.layout @@ -314,21 +363,28 @@ class SCENE_PT_audio(SceneButtonsPanel, Panel): rd = context.scene.render ffmpeg = rd.ffmpeg - layout.prop(scene, "audio_volume") + flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=True) - col = layout.column() - col.prop(scene, "audio_distance_model") + col = flow.column() + col.prop(scene, "audio_volume") + + col.separator() + col.prop(scene, "audio_distance_model") col.prop(ffmpeg, "audio_channels") + + col.separator() + + col = flow.column() col.prop(ffmpeg, "audio_mixrate", text="Sample Rate") - layout.separator() + col.separator() - col = layout.column(align=True) + col = col.column(align=True) col.prop(scene, "audio_doppler_speed", text="Doppler Speed") col.prop(scene, "audio_doppler_factor", text="Doppler Factor") - layout.separator() + col.separator() layout.operator("sound.bake_animation") @@ -336,7 +392,7 @@ class SCENE_PT_audio(SceneButtonsPanel, Panel): class SCENE_PT_physics(SceneButtonsPanel, Panel): bl_label = "Gravity" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw_header(self, context): self.layout.prop(context.scene, "use_gravity", text="") @@ -355,7 +411,7 @@ class SCENE_PT_physics(SceneButtonsPanel, Panel): class SCENE_PT_rigid_body_world(SceneButtonsPanel, Panel): bl_label = "Rigid Body World" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -372,7 +428,6 @@ class SCENE_PT_rigid_body_world(SceneButtonsPanel, Panel): layout.use_property_split = True scene = context.scene - rbw = scene.rigidbody_world if rbw is None: @@ -380,7 +435,28 @@ class SCENE_PT_rigid_body_world(SceneButtonsPanel, Panel): else: layout.operator("rigidbody.world_remove") - col = layout.column() + +class SCENE_PT_rigid_body_world_settings(SceneButtonsPanel, Panel): + bl_label = "Settings" + bl_parent_id = "SCENE_PT_rigid_body_world" + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + + @classmethod + def poll(cls, context): + scene = context.scene + return scene and scene.rigidbody_world and (context.engine in cls.COMPAT_ENGINES) + + def draw(self, context): + layout = self.layout + layout.use_property_split = True + + scene = context.scene + rbw = scene.rigidbody_world + + if rbw: + flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=True) + + col = flow.column() col.active = rbw.enabled col = col.column() @@ -389,6 +465,9 @@ class SCENE_PT_rigid_body_world(SceneButtonsPanel, Panel): col = col.column() col.prop(rbw, "time_scale", text="Speed") + + col = flow.column() + col.active = rbw.enabled col.prop(rbw, "use_split_impulse") col = col.column() @@ -400,7 +479,7 @@ class SCENE_PT_rigid_body_cache(SceneButtonsPanel, Panel): bl_label = "Cache" bl_parent_id = "SCENE_PT_rigid_body_world" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -418,7 +497,7 @@ class SCENE_PT_rigid_body_field_weights(SceneButtonsPanel, Panel): bl_label = "Field Weights" bl_parent_id = "SCENE_PT_rigid_body_world" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -435,7 +514,7 @@ class SCENE_PT_rigid_body_field_weights(SceneButtonsPanel, Panel): class SCENE_PT_simplify(SceneButtonsPanel, Panel): bl_label = "Simplify" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw_header(self, context): rd = context.scene.render @@ -448,7 +527,7 @@ class SCENE_PT_simplify(SceneButtonsPanel, Panel): class SCENE_PT_simplify_viewport(SceneButtonsPanel, Panel): bl_label = "Viewport" bl_parent_id = "SCENE_PT_simplify" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw(self, context): layout = self.layout @@ -458,15 +537,19 @@ class SCENE_PT_simplify_viewport(SceneButtonsPanel, Panel): layout.active = rd.use_simplify - col = layout.column() + flow = layout.grid_flow(row_major=True, columns=0, even_columns=False, even_rows=False, align=True) + + col = flow.column() col.prop(rd, "simplify_subdivision", text="Max Subdivision") + + col = flow.column() col.prop(rd, "simplify_child_particles", text="Max Child Particles") class SCENE_PT_simplify_render(SceneButtonsPanel, Panel): bl_label = "Render" bl_parent_id = "SCENE_PT_simplify" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw(self, context): layout = self.layout @@ -476,13 +559,47 @@ class SCENE_PT_simplify_render(SceneButtonsPanel, Panel): layout.active = rd.use_simplify - col = layout.column() + flow = layout.grid_flow(row_major=True, columns=0, even_columns=False, even_rows=False, align=True) + + col = flow.column() col.prop(rd, "simplify_subdivision_render", text="Max Subdivision") + + col = flow.column() col.prop(rd, "simplify_child_particles_render", text="Max Child Particles") +class SCENE_PT_simplify_greasepencil(SceneButtonsPanel, Panel): + bl_label = "Grease Pencil" + bl_parent_id = "SCENE_PT_simplify" + 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 + layout.use_property_split = True + + rd = context.scene.render + + layout.active = rd.simplify_gpencil + + col = layout.column() + col.prop(rd, "simplify_gpencil_onplay", text="Playback Only") + col.prop(rd, "simplify_gpencil_view_modifier", text="Modifiers") + col.prop(rd, "simplify_gpencil_shader_fx", text="ShaderFX") + + col = layout.column(align=True) + col.prop(rd, "simplify_gpencil_view_fill") + sub = col.column() + sub.active = rd.simplify_gpencil_view_fill + sub.prop(rd, "simplify_gpencil_remove_lines", text="Lines") + + class SCENE_PT_custom_props(SceneButtonsPanel, PropertyPanel, Panel): - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} _context_path = "scene" _property_type = bpy.types.Scene @@ -494,16 +611,19 @@ classes = ( SCENE_PT_unit, SCENE_PT_keying_sets, SCENE_PT_keying_set_paths, + SCENE_PT_keyframing_settings, SCENE_PT_color_management, SCENE_PT_color_management_curves, SCENE_PT_audio, SCENE_PT_physics, SCENE_PT_rigid_body_world, + SCENE_PT_rigid_body_world_settings, SCENE_PT_rigid_body_cache, SCENE_PT_rigid_body_field_weights, SCENE_PT_simplify, SCENE_PT_simplify_viewport, SCENE_PT_simplify_render, + SCENE_PT_simplify_greasepencil, SCENE_PT_custom_props, ) diff --git a/release/scripts/startup/bl_ui/properties_texture.py b/release/scripts/startup/bl_ui/properties_texture.py index b3b7341a734..a4f6f753669 100644 --- a/release/scripts/startup/bl_ui/properties_texture.py +++ b/release/scripts/startup/bl_ui/properties_texture.py @@ -17,19 +17,21 @@ # ##### END GPL LICENSE BLOCK ##### # <pep8 compliant> -import bpy -from bpy.types import Menu, Panel, UIList +import bpy +from bpy.types import ( + Menu, + Panel, + UIList, +) from bpy.types import ( Brush, FreestyleLineStyle, - Object, ParticleSettings, Texture, ) from rna_prop_ui import PropertyPanel - from .properties_paint_common import brush_texture_settings @@ -47,9 +49,9 @@ class TEXTURE_MT_specials(Menu): class TEXTURE_UL_texslots(UIList): def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index): - ma = data slot = item tex = slot.texture if slot else None + if self.layout_type in {'DEFAULT', 'COMPACT'}: if tex: layout.prop(tex, "name", text="", emboss=False, icon_value=icon) @@ -83,7 +85,7 @@ class TextureButtonsPanel: class TEXTURE_PT_preview(TextureButtonsPanel, Panel): bl_label = "Preview" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -112,7 +114,7 @@ class TEXTURE_PT_context(TextureButtonsPanel, Panel): bl_label = "" bl_context = "texture" bl_options = {'HIDE_HEADER'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw(self, context): layout = self.layout @@ -131,18 +133,18 @@ class TEXTURE_PT_context(TextureButtonsPanel, Panel): if not pin_id: col.template_texture_user() - col.separator() - if user or pin_id: + col.separator() + if pin_id: col.template_ID(space, "pin_id") else: propname = context.texture_user_property.identifier col.template_ID(user, propname, new="texture.new") - col.separator() - if tex: + col.separator() + split = col.split(percentage=0.2) split.label(text="Type") split.prop(tex, "type", text="") @@ -151,7 +153,7 @@ class TEXTURE_PT_context(TextureButtonsPanel, Panel): class TEXTURE_PT_node(TextureButtonsPanel, Panel): bl_label = "Node" bl_context = "texture" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -169,7 +171,7 @@ class TEXTURE_PT_node(TextureButtonsPanel, Panel): class TEXTURE_PT_node_mapping(TextureButtonsPanel, Panel): bl_label = "Mapping" bl_context = "texture" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -179,25 +181,35 @@ class TEXTURE_PT_node_mapping(TextureButtonsPanel, Panel): def draw(self, context): layout = self.layout + layout.use_property_split = True + layout.use_property_decorate = False # No animation. + + flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=False) node = context.texture_node mapping = node.texture_mapping - layout.prop(mapping, "vector_type", expand=True) + col = flow.column() + col.prop(mapping, "vector_type") + + col.separator() + + col = col.column(align=True) + col.prop(mapping, "mapping_x", text="Projection X") + col.prop(mapping, "mapping_y", text="Y") + col.prop(mapping, "mapping_z", text="Z") - row = layout.row() + col.separator() - row.column().prop(mapping, "translation") - row.column().prop(mapping, "rotation") - row.column().prop(mapping, "scale") + col = flow.column() + col.column().prop(mapping, "translation") - layout.label(text="Projection:") + col = flow.column() + col.column().prop(mapping, "rotation") - row = layout.row() - row.prop(mapping, "mapping_x", text="") - row.prop(mapping, "mapping_y", text="") - row.prop(mapping, "mapping_z", text="") + col = flow.column() + col.column().prop(mapping, "scale") class TextureTypePanel(TextureButtonsPanel): @@ -212,79 +224,102 @@ class TextureTypePanel(TextureButtonsPanel): class TEXTURE_PT_clouds(TextureTypePanel, Panel): bl_label = "Clouds" tex_type = 'CLOUDS' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw(self, context): layout = self.layout + layout.use_property_split = True + flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=True) tex = context.texture - layout.row().prop(tex, "cloud_type", expand=True) - layout.label(text="Noise:") - layout.row().prop(tex, "noise_type", text="Type", expand=True) - layout.prop(tex, "noise_basis", text="Basis") + col = flow.column() + col.prop(tex, "noise_basis", text="Noise Basis") + + col.separator() + + col.prop(tex, "noise_type", text="Type") - split = layout.split() + col.separator() - col = split.column() + col = flow.column() + col.prop(tex, "cloud_type") + + col.separator() + + col = flow.column() col.prop(tex, "noise_scale", text="Size") col.prop(tex, "noise_depth", text="Depth") - - split.prop(tex, "nabla", text="Nabla") + col.prop(tex, "nabla", text="Nabla") class TEXTURE_PT_wood(TextureTypePanel, Panel): bl_label = "Wood" tex_type = 'WOOD' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw(self, context): layout = self.layout + layout.use_property_split = True + flow = layout.grid_flow(row_major=True, columns=0, even_columns=False, even_rows=False, align=False) tex = context.texture - layout.row().prop(tex, "noise_basis_2", expand=True) - layout.row().prop(tex, "wood_type", expand=True) + col = flow.column() + col.prop(tex, "noise_basis", text="Noise Basis") - col = layout.column() - col.active = tex.wood_type in {'RINGNOISE', 'BANDNOISE'} - col.label(text="Noise:") - col.row().prop(tex, "noise_type", text="Type", expand=True) - layout.prop(tex, "noise_basis", text="Basis") + col.separator() - split = layout.split() - split.active = tex.wood_type in {'RINGNOISE', 'BANDNOISE'} + col.prop(tex, "wood_type") - col = split.column() - col.prop(tex, "noise_scale", text="Size") - col.prop(tex, "turbulence") + col.separator() - split.prop(tex, "nabla") + col = flow.column() + col.prop(tex, "noise_basis_2", text="Second Basis") + + col = col.column() + col.active = tex.wood_type in {'RINGNOISE', 'BANDNOISE'} + col.prop(tex, "noise_type", text="Type") + + col.separator() + + sub = flow.column() + sub.active = tex.wood_type in {'RINGNOISE', 'BANDNOISE'} + sub.prop(tex, "noise_scale", text="Size") + sub.prop(tex, "turbulence") + sub.prop(tex, "nabla") class TEXTURE_PT_marble(TextureTypePanel, Panel): bl_label = "Marble" tex_type = 'MARBLE' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw(self, context): layout = self.layout + layout.use_property_split = True + flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=True) tex = context.texture - layout.row().prop(tex, "marble_type", expand=True) - layout.row().prop(tex, "noise_basis_2", expand=True) - layout.label(text="Noise:") - layout.row().prop(tex, "noise_type", text="Type", expand=True) - layout.prop(tex, "noise_basis", text="Basis") + col = flow.column() + col.prop(tex, "noise_basis", text="Noise Basis") + + col.separator() + + col.prop(tex, "marble_type") + + col.separator() + + col = flow.column() + col.prop(tex, "noise_basis_2", text="Second Basis") + col.prop(tex, "noise_type", text="Type") - split = layout.split() + col.separator() - col = split.column() + col = flow.column() col.prop(tex, "noise_scale", text="Size") col.prop(tex, "noise_depth", text="Depth") - - col = split.column() col.prop(tex, "turbulence") col.prop(tex, "nabla") @@ -292,60 +327,91 @@ class TEXTURE_PT_marble(TextureTypePanel, Panel): class TEXTURE_PT_magic(TextureTypePanel, Panel): bl_label = "Magic" tex_type = 'MAGIC' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw(self, context): layout = self.layout + layout.use_property_split = True + flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=False) tex = context.texture - row = layout.row() - row.prop(tex, "noise_depth", text="Depth") - row.prop(tex, "turbulence") + col = flow.column() + col.prop(tex, "noise_depth", text="Depth") + + col = flow.column() + col.prop(tex, "turbulence") class TEXTURE_PT_blend(TextureTypePanel, Panel): bl_label = "Blend" tex_type = 'BLEND' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw(self, context): layout = self.layout + layout.use_property_split = True + flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=True) tex = context.texture - layout.prop(tex, "progression") + col = flow.column() + col.prop(tex, "progression") - sub = layout.row() + col.separator() - sub.active = (tex.progression in {'LINEAR', 'QUADRATIC', 'EASING', 'RADIAL'}) - sub.prop(tex, "use_flip_axis", expand=True) + col = flow.column() + col.active = (tex.progression in {'LINEAR', 'QUADRATIC', 'EASING', 'RADIAL'}) + col.prop(tex, "use_flip_axis", text="Orientation") class TEXTURE_PT_stucci(TextureTypePanel, Panel): bl_label = "Stucci" tex_type = 'STUCCI' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw(self, context): layout = self.layout + layout.use_property_split = True + flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=False) tex = context.texture - layout.row().prop(tex, "stucci_type", expand=True) - layout.label(text="Noise:") - layout.row().prop(tex, "noise_type", text="Type", expand=True) - layout.prop(tex, "noise_basis", text="Basis") + col = flow.column() + col.prop(tex, "noise_basis", text="Noise Basis") + + col.separator() + + col.row().prop(tex, "stucci_type") + + col.separator() + + col = flow.column() + col.prop(tex, "noise_type", text="Type") + + col.separator() - row = layout.row() - row.prop(tex, "noise_scale", text="Size") - row.prop(tex, "turbulence") + col = flow.column() + col.prop(tex, "noise_scale", text="Size") + col.prop(tex, "turbulence") class TEXTURE_PT_image(TextureTypePanel, Panel): bl_label = "Image" tex_type = 'IMAGE' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} + + def draw(self, context): + # TODO: maybe expose the template_ID from the template image here. + layout = self.layout + del layout + + +class TEXTURE_PT_image_settings(TextureTypePanel, Panel): + bl_label = "Settings" + bl_parent_id = 'TEXTURE_PT_image' + tex_type = 'IMAGE' + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw(self, context): layout = self.layout @@ -356,11 +422,13 @@ class TEXTURE_PT_image(TextureTypePanel, Panel): def texture_filter_common(tex, layout): layout.prop(tex, "filter_type", text="Filter Type") + if tex.use_mipmap and tex.filter_type in {'AREA', 'EWA', 'FELINE'}: + col = layout.column() if tex.filter_type == 'FELINE': - layout.prop(tex, "filter_lightprobes", text="Light Probes") + col.prop(tex, "filter_lightprobes", text="Light Probes") else: - layout.prop(tex, "filter_eccentricity", text="Eccentricity") + col.prop(tex, "filter_eccentricity", text="Eccentricity") layout.prop(tex, "filter_size", text="Size") layout.prop(tex, "use_filter_size_min", text="Minimum Size") @@ -376,14 +444,11 @@ class TEXTURE_PT_image_sampling(TextureTypePanel, Panel): def draw(self, context): layout = self.layout layout.use_property_split = True - flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=False) + flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=True) - idblock = context_tex_datablock(context) tex = context.texture - slot = getattr(context, "texture_slot", None) col = flow.column() - col.prop(tex, "use_flip_axis", text="Flip X/Y Axis") col.prop(tex, "use_interpolation") col.separator() @@ -396,8 +461,7 @@ class TEXTURE_PT_image_sampling(TextureTypePanel, Panel): col.separator() - col = flow.column() - texture_filter_common(tex, col) + texture_filter_common(tex, flow) class TEXTURE_PT_image_alpha(TextureTypePanel, Panel): @@ -433,141 +497,200 @@ class TEXTURE_PT_image_mapping(TextureTypePanel, Panel): def draw(self, context): layout = self.layout layout.use_property_split = True - flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=False) tex = context.texture - col = flow.column() - col.prop(tex, "extension") + col = layout.column() + col.prop(tex, "use_flip_axis", text="Flip Axes") + + col.separator() + + subcol = layout.column() + subcol.prop(tex, "extension") # use layout, to keep the same location in case of button cycling. + + flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=True) if tex.extension == 'REPEAT': + + col = flow.column() sub = col.column(align=True) sub.prop(tex, "repeat_x", text="Repeat X") sub.prop(tex, "repeat_y", text="Y") + col = flow.column() sub = col.column() - sub.prop(tex, "use_mirror_x", text="Mirror X") sub.active = (tex.repeat_x > 1) + sub.prop(tex, "use_mirror_x", text="Mirror X") sub = col.column() - sub.prop(tex, "use_mirror_y", text="Y") sub.active = (tex.repeat_y > 1) + sub.prop(tex, "use_mirror_y", text="Y") elif tex.extension == 'CHECKER': - col = layout.column(align=True) - col.prop(tex, "use_checker_even", text="Even") - col.prop(tex, "use_checker_odd", text="Odd") + subcol.separator() - col = layout.column() + col = flow.column() col.prop(tex, "checker_distance", text="Distance") - col = flow.column() - sub = col.column(align=True) + col = flow.column() + col.prop(tex, "use_checker_even", text="Tiles Even") + col.prop(tex, "use_checker_odd", text="Odd") + else: + del flow + + +class TEXTURE_PT_image_mapping_crop(TextureTypePanel, Panel): + bl_label = "Crop" + bl_options = {'DEFAULT_CLOSED'} + bl_parent_id = 'TEXTURE_PT_image_mapping' + tex_type = 'IMAGE' + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + + def draw(self, context): + layout = self.layout + layout.use_property_split = True + flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=False) + + tex = context.texture + + col = flow.column(align=True) # col.prop(tex, "crop_rectangle") - sub.prop(tex, "crop_min_x", text="Crop Minimum X") - sub.prop(tex, "crop_min_y", text="Y") + col.prop(tex, "crop_min_x", text="Minimum X") + col.prop(tex, "crop_min_y", text="Y") - sub = col.column(align=True) - sub.prop(tex, "crop_max_x", text="Crop Maximum X") - sub.prop(tex, "crop_max_y", text="Y") + col = flow.column(align=True) + col.prop(tex, "crop_max_x", text="Maximum X") + col.prop(tex, "crop_max_y", text="Y") class TEXTURE_PT_musgrave(TextureTypePanel, Panel): bl_label = "Musgrave" tex_type = 'MUSGRAVE' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw(self, context): layout = self.layout + layout.use_property_split = True + flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=True) tex = context.texture - layout.prop(tex, "musgrave_type") + col = flow.column() + col.prop(tex, "noise_basis", text="Noise Basis") + + col.separator() + + col.prop(tex, "musgrave_type") - split = layout.split() + col.separator() - col = split.column() + col.prop(tex, "noise_scale", text="Size") + col.prop(tex, "nabla") + + col.separator() + + col = flow.column() col.prop(tex, "dimension_max", text="Dimension") col.prop(tex, "lacunarity") col.prop(tex, "octaves") + col.separator() + musgrave_type = tex.musgrave_type - col = split.column() + + col = flow.column() + if musgrave_type in {'HETERO_TERRAIN', 'RIDGED_MULTIFRACTAL', 'HYBRID_MULTIFRACTAL'}: col.prop(tex, "offset") col.prop(tex, "noise_intensity", text="Intensity") + if musgrave_type in {'RIDGED_MULTIFRACTAL', 'HYBRID_MULTIFRACTAL'}: col.prop(tex, "gain") - layout.label(text="Noise:") - - layout.prop(tex, "noise_basis", text="Basis") - - row = layout.row() - row.prop(tex, "noise_scale", text="Size") - row.prop(tex, "nabla") - class TEXTURE_PT_voronoi(TextureTypePanel, Panel): bl_label = "Voronoi" tex_type = 'VORONOI' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw(self, context): layout = self.layout + layout.use_property_split = True + flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=False) tex = context.texture - split = layout.split() + col = flow.column() + col.prop(tex, "distance_metric") - col = split.column() - col.label(text="Distance Metric:") - col.prop(tex, "distance_metric", text="") sub = col.column() sub.active = tex.distance_metric == 'MINKOVSKY' sub.prop(tex, "minkovsky_exponent", text="Exponent") - col.label(text="Coloring:") - col.prop(tex, "color_mode", text="") + + sub.separator() + + col = flow.column() + col.prop(tex, "color_mode") col.prop(tex, "noise_intensity", text="Intensity") - col = split.column() - sub = col.column(align=True) - sub.label(text="Feature Weights:") - sub.prop(tex, "weight_1", text="1", slider=True) - sub.prop(tex, "weight_2", text="2", slider=True) - sub.prop(tex, "weight_3", text="3", slider=True) - sub.prop(tex, "weight_4", text="4", slider=True) + col.separator() - layout.label(text="Noise:") - row = layout.row() - row.prop(tex, "noise_scale", text="Size") - row.prop(tex, "nabla") + col = flow.column() + col.prop(tex, "noise_scale", text="Size") + col.prop(tex, "nabla") + + +class TEXTURE_PT_voronoi_feature_weights(TextureTypePanel, Panel): + bl_label = "Feature Weights" + bl_parent_id = "TEXTURE_PT_voronoi" + tex_type = 'VORONOI' + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} + + def draw(self, context): + layout = self.layout + layout.use_property_split = True + flow = layout.grid_flow(row_major=False, columns=0, even_columns=True, even_rows=False, align=True) + + tex = context.texture + + col = flow.column(align=True) + col.prop(tex, "weight_1", text="First", slider=True) + col.prop(tex, "weight_2", text="Second", slider=True) + + sub = flow.column(align=True) + sub.prop(tex, "weight_3", text="Third", slider=True) + sub.prop(tex, "weight_4", text="Fourth", slider=True) class TEXTURE_PT_distortednoise(TextureTypePanel, Panel): bl_label = "Distorted Noise" tex_type = 'DISTORTED_NOISE' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw(self, context): layout = self.layout + layout.use_property_split = True + flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=True) tex = context.texture - layout.prop(tex, "noise_distortion") - layout.prop(tex, "noise_basis", text="Basis") + col = flow.column() + col.prop(tex, "noise_basis", text="Noise Basis") - split = layout.split() + col.separator() - col = split.column() - col.prop(tex, "distortion", text="Distortion") - col.prop(tex, "noise_scale", text="Size") + col.prop(tex, "noise_distortion", text="Distortion") - split.prop(tex, "nabla") + col.separator() + + col = flow.column() + col.prop(tex, "distortion", text="Amount") + col.prop(tex, "noise_scale", text="Size") + col.prop(tex, "nabla") class TextureSlotPanel(TextureButtonsPanel): - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -579,7 +702,7 @@ class TextureSlotPanel(TextureButtonsPanel): class TEXTURE_PT_mapping(TextureSlotPanel, Panel): bl_label = "Mapping" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -595,69 +718,65 @@ class TEXTURE_PT_mapping(TextureSlotPanel, Panel): def draw(self, context): layout = self.layout + layout.use_property_split = True + flow = layout.grid_flow(row_major=False, columns=0, even_columns=True, even_rows=False, align=True) idblock = context_tex_datablock(context) tex = context.texture_slot - if not isinstance(idblock, Brush): - split = layout.split(percentage=0.3) - col = split.column() - col.label(text="Coordinates:") - col = split.column() - col.prop(tex, "texture_coords", text="") + if isinstance(idblock, Brush): + if context.sculpt_object or context.image_paint_object: + brush_texture_settings(layout, idblock, context.sculpt_object) + else: + col = flow.column() - if tex.texture_coords == 'ORCO': - """ - ob = context.object - if ob and ob.type == 'MESH': - split = layout.split(percentage=0.3) - split.label(text="Mesh:") - split.prop(ob.data, "texco_mesh", text="") - """ - elif tex.texture_coords == 'UV': - split = layout.split(percentage=0.3) - split.label(text="Map:") + col.prop(tex, "texture_coords", text="Coordinates") + + # Note: the ORCO case used to call ob.data, "texco_mesh" prop. + if tex.texture_coords == 'UV': ob = context.object + if ob and ob.type == 'MESH': - split.prop_search(tex, "uv_layer", ob.data, "uv_layers", text="") + # Note: TODO prop_search doesn't align on the right. + row = col.row(align=True) + row.prop_search(tex, "uv_layer", ob.data, "uv_layers", text="Map") + row.label(text="", icon='BLANK1') else: - split.prop(tex, "uv_layer", text="") + col.prop(tex, "uv_layer", text="Map") elif tex.texture_coords == 'OBJECT': - split = layout.split(percentage=0.3) - split.label(text="Object:") - split.prop(tex, "object", text="") + col.prop(tex, "object", text="Object") elif tex.texture_coords == 'ALONG_STROKE': - split = layout.split(percentage=0.3) - split.label(text="Use Tips:") - split.prop(tex, "use_tips", text="") + col.prop(tex, "use_tips", text="Use Tips") + + col.separator() - if isinstance(idblock, Brush): - if context.sculpt_object or context.image_paint_object: - brush_texture_settings(layout, idblock, context.sculpt_object) - else: if isinstance(idblock, FreestyleLineStyle): - split = layout.split(percentage=0.3) - split.label(text="Projection:") - split.prop(tex, "mapping", text="") + col = flow.column() + col.prop(tex, "mapping", text="Projection") + + col.separator() + + col = flow.column() + col.prop(tex, "mapping_x", text="Mapping X") + col.prop(tex, "mapping_y", text="Y") + col.prop(tex, "mapping_z", text="Z") + + col.separator() - split = layout.split(percentage=0.3) - split.separator() - row = split.row() - row.prop(tex, "mapping_x", text="") - row.prop(tex, "mapping_y", text="") - row.prop(tex, "mapping_z", text="") + col = flow.column(align=True) + col.column().prop(tex, "offset") - row = layout.row() - row.column().prop(tex, "offset") - row.column().prop(tex, "scale") + col = flow.column(align=True) + col.column().prop(tex, "scale") class TEXTURE_PT_influence(TextureSlotPanel, Panel): bl_label = "Influence" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + bl_options = {'DEFAULT_CLOSED'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -672,111 +791,130 @@ class TEXTURE_PT_influence(TextureSlotPanel, Panel): return (engine in cls.COMPAT_ENGINES) def draw(self, context): - layout = self.layout + layout.use_property_split = True + flow = layout.grid_flow(row_major=False, columns=0, even_columns=False, even_rows=False, align=False) idblock = context_tex_datablock(context) - tex = context.texture_slot def factor_but(layout, toggle, factor, name): row = layout.row(align=True) - row.prop(tex, toggle, text="") + row.active = getattr(tex, toggle) + + row.prop(tex, factor, text=name, slider=True) sub = row.row(align=True) - sub.active = getattr(tex, toggle) - sub.prop(tex, factor, text=name, slider=True) + sub.prop(tex, toggle, text="") return sub # XXX, temp. use_map_normal needs to override. if isinstance(idblock, ParticleSettings): - split = layout.split() - - col = split.column() - col.label(text="General:") - factor_but(col, "use_map_time", "time_factor", "Time") + col = flow.column() + factor_but(col, "use_map_time", "time_factor", "General Time") factor_but(col, "use_map_life", "life_factor", "Lifetime") factor_but(col, "use_map_density", "density_factor", "Density") factor_but(col, "use_map_size", "size_factor", "Size") - col = split.column() - col.label(text="Physics:") - factor_but(col, "use_map_velocity", "velocity_factor", "Velocity") + col.separator() + + col = flow.column() + factor_but(col, "use_map_velocity", "velocity_factor", "Physics Velocity") factor_but(col, "use_map_damp", "damp_factor", "Damp") factor_but(col, "use_map_gravity", "gravity_factor", "Gravity") factor_but(col, "use_map_field", "field_factor", "Force Fields") - layout.label(text="Hair:") - - split = layout.split() + col.separator() - col = split.column() - factor_but(col, "use_map_length", "length_factor", "Length") + col = flow.column() + factor_but(col, "use_map_length", "length_factor", "Hair Length") factor_but(col, "use_map_clump", "clump_factor", "Clump") factor_but(col, "use_map_twist", "twist_factor", "Twist") - col = split.column() + col = flow.column() factor_but(col, "use_map_kink_amp", "kink_amp_factor", "Kink Amplitude") factor_but(col, "use_map_kink_freq", "kink_freq_factor", "Kink Frequency") factor_but(col, "use_map_rough", "rough_factor", "Rough") elif isinstance(idblock, FreestyleLineStyle): - split = layout.split() - - col = split.column() + col = flow.column() factor_but(col, "use_map_color_diffuse", "diffuse_color_factor", "Color") - col = split.column() factor_but(col, "use_map_alpha", "alpha_factor", "Alpha") - layout.separator() - if not isinstance(idblock, ParticleSettings): - split = layout.split() + col = flow.column() - col = split.column() col.prop(tex, "blend_type", text="Blend") col.prop(tex, "use_rgb_to_intensity") + # color is used on gray-scale textures even when use_rgb_to_intensity is disabled. col.prop(tex, "color", text="") - col = split.column() + col = flow.column() col.prop(tex, "invert", text="Negative") col.prop(tex, "use_stencil") -class TEXTURE_PT_colors(TextureButtonsPanel, Panel): - bl_label = "Colors" - bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} - +class TextureColorsPoll: @classmethod def poll(cls, context): tex = context.texture return tex and (tex.type != 'NONE' or tex.use_nodes) and (context.engine in cls.COMPAT_ENGINES) + +class TEXTURE_PT_colors(TextureButtonsPanel, TextureColorsPoll, Panel): + bl_label = "Colors" + bl_options = {'DEFAULT_CLOSED'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} + def draw(self, context): layout = self.layout layout.use_property_split = True + flow = layout.grid_flow(row_major=False, columns=0, even_columns=False, even_rows=False, align=False) tex = context.texture - col = layout.column() - sub = col.column(align=True) - sub.prop(tex, "factor_red", text="Multiply R") - sub.prop(tex, "factor_green", text="G") - sub.prop(tex, "factor_blue", text="B") + col = flow.column() + col.prop(tex, "use_clamp", text="Clamp") + col = flow.column(align=True) + col.prop(tex, "factor_red", text="Multiply R") + col.prop(tex, "factor_green", text="G") + col.prop(tex, "factor_blue", text="B") + + col.separator() + + col = flow.column() col.prop(tex, "intensity") col.prop(tex, "contrast") col.prop(tex, "saturation") - col.prop(tex, "use_clamp", text="Clamp") - col.prop(tex, "use_color_ramp", text="Ramp") - if tex.use_color_ramp: - layout.use_property_split = False + +class TEXTURE_PT_colors_ramp(TextureButtonsPanel, TextureColorsPoll, Panel): + bl_label = "Color Ramp" + bl_options = {'DEFAULT_CLOSED'} + bl_parent_id = 'TEXTURE_PT_colors' + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} + + def draw_header(self, context): + tex = context.texture + self.layout.prop(tex, "use_color_ramp", text="") + + def draw(self, context): + layout = self.layout + + tex = context.texture + + # Note: TODO after creation of a new texture, the template_color_ramp will be blank. + # Possibly needs to be fixed in the template itself. + is_active = bool(tex and tex.use_color_ramp) + if is_active: layout.template_color_ramp(tex, "color_ramp", expand=True) + else: + layout.alignment = 'RIGHT' + layout.label("Please enable the Color Ramp first") class TEXTURE_PT_custom_props(TextureButtonsPanel, PropertyPanel, Panel): - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} _context_path = "texture" _property_type = Texture @@ -792,8 +930,6 @@ classes = ( TEXTURE_PT_context, TEXTURE_PT_node, TEXTURE_PT_node_mapping, - TEXTURE_PT_mapping, - TEXTURE_PT_influence, TEXTURE_PT_clouds, TEXTURE_PT_wood, TEXTURE_PT_marble, @@ -801,13 +937,19 @@ classes = ( TEXTURE_PT_blend, TEXTURE_PT_stucci, TEXTURE_PT_image, + TEXTURE_PT_image_settings, TEXTURE_PT_image_alpha, - TEXTURE_PT_image_sampling, TEXTURE_PT_image_mapping, + TEXTURE_PT_image_mapping_crop, + TEXTURE_PT_image_sampling, TEXTURE_PT_musgrave, TEXTURE_PT_voronoi, + TEXTURE_PT_voronoi_feature_weights, TEXTURE_PT_distortednoise, + TEXTURE_PT_influence, + TEXTURE_PT_mapping, TEXTURE_PT_colors, + TEXTURE_PT_colors_ramp, TEXTURE_PT_custom_props, ) diff --git a/release/scripts/startup/bl_ui/properties_view_layer.py b/release/scripts/startup/bl_ui/properties_view_layer.py index 05dc15216a2..f96bf041311 100644 --- a/release/scripts/startup/bl_ui/properties_view_layer.py +++ b/release/scripts/startup/bl_ui/properties_view_layer.py @@ -34,7 +34,7 @@ class ViewLayerButtonsPanel: class VIEWLAYER_PT_layer(ViewLayerButtonsPanel, Panel): bl_label = "View Layer" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw(self, context): layout = self.layout diff --git a/release/scripts/startup/bl_ui/properties_world.py b/release/scripts/startup/bl_ui/properties_world.py index b6ea8054b0c..7395fa13d9a 100644 --- a/release/scripts/startup/bl_ui/properties_world.py +++ b/release/scripts/startup/bl_ui/properties_world.py @@ -37,7 +37,7 @@ class WorldButtonsPanel: class WORLD_PT_context_world(WorldButtonsPanel, Panel): bl_label = "" bl_options = {'HIDE_HEADER'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -83,14 +83,13 @@ class EEVEE_WORLD_PT_mist(WorldButtonsPanel, Panel): class WORLD_PT_custom_props(WorldButtonsPanel, PropertyPanel, Panel): - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} _context_path = "world" _property_type = bpy.types.World class EEVEE_WORLD_PT_surface(WorldButtonsPanel, Panel): bl_label = "Surface" - bl_context = "world" COMPAT_ENGINES = {'BLENDER_EEVEE'} @classmethod @@ -119,13 +118,29 @@ class EEVEE_WORLD_PT_surface(WorldButtonsPanel, Panel): else: layout.label(text="No output node") else: - layout.prop(world, "horizon_color", text="Color") + layout.prop(world, "color") + + +class WORLD_PT_viewport_display(WorldButtonsPanel, Panel): + bl_label = "Viewport Display" + bl_options = {'DEFAULT_CLOSED'} + + @classmethod + def poll(cls, context): + return context.world + + def draw(self, context): + layout = self.layout + layout.use_property_split = True + world = context.world + layout.prop(world, "color") classes = ( WORLD_PT_context_world, EEVEE_WORLD_PT_surface, EEVEE_WORLD_PT_mist, + WORLD_PT_viewport_display, WORLD_PT_custom_props, ) diff --git a/release/scripts/startup/bl_ui/space_clip.py b/release/scripts/startup/bl_ui/space_clip.py index 23c3e97ac9a..1564204c613 100644 --- a/release/scripts/startup/bl_ui/space_clip.py +++ b/release/scripts/startup/bl_ui/space_clip.py @@ -24,12 +24,7 @@ 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, ) @@ -1154,39 +1149,10 @@ 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' - - -# 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' + bl_region_type = 'TOOLS' class CLIP_MT_view(Menu): @@ -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, diff --git a/release/scripts/startup/bl_ui/space_filebrowser.py b/release/scripts/startup/bl_ui/space_filebrowser.py index 9d903829bbb..a85dd591b2f 100644 --- a/release/scripts/startup/bl_ui/space_filebrowser.py +++ b/release/scripts/startup/bl_ui/space_filebrowser.py @@ -56,6 +56,8 @@ class FILEBROWSER_HT_header(Header): layout.separator_spacer() + layout.template_running_jobs() + if params: layout.prop(params, "use_filter", text="", icon='FILTER') @@ -86,8 +88,6 @@ class FILEBROWSER_HT_header(Header): row.separator() row.prop(params, "filter_search", text="", icon='VIEWZOOM') - layout.template_running_jobs() - class FILEBROWSER_UL_dir(UIList): def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index): diff --git a/release/scripts/startup/bl_ui/space_image.py b/release/scripts/startup/bl_ui/space_image.py index 1303e46ab6c..7a1d4117451 100644 --- a/release/scripts/startup/bl_ui/space_image.py +++ b/release/scripts/startup/bl_ui/space_image.py @@ -28,12 +28,7 @@ from .properties_paint_common import ( ) from .properties_grease_pencil_common import ( GreasePencilDrawingToolsPanel, - GreasePencilStrokeEditPanel, - GreasePencilStrokeSculptPanel, - GreasePencilBrushPanel, - GreasePencilBrushCurvesPanel, GreasePencilDataPanel, - GreasePencilPaletteColorPanel, ) from bpy.app.translations import pgettext_iface as iface_ @@ -1346,38 +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' - - -# 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): +class IMAGE_PT_tools_grease_pencil_draw(GreasePencilDrawingToolsPanel, Panel): bl_space_type = 'IMAGE_EDITOR' + bl_region_type = 'TOOLS' classes = ( @@ -1430,12 +1399,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. diff --git a/release/scripts/startup/bl_ui/space_node.py b/release/scripts/startup/bl_ui/space_node.py index 9d8c14ba9c3..43a124cd48f 100644 --- a/release/scripts/startup/bl_ui/space_node.py +++ b/release/scripts/startup/bl_ui/space_node.py @@ -24,13 +24,8 @@ 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 + GreasePencilToolsPanel, ) @@ -364,7 +359,6 @@ class NODE_PT_active_node_generic(Panel): bl_space_type = 'NODE_EDITOR' bl_region_type = 'UI' bl_label = "Node" -# bl_options = {'HIDE_HEADER'} @classmethod def poll(cls, context): @@ -383,6 +377,7 @@ class NODE_PT_active_node_color(Panel): bl_region_type = 'UI' bl_label = "Color" bl_options = {'DEFAULT_CLOSED'} + bl_parent_id = 'NODE_PT_active_node_generic' @classmethod def poll(cls, context): @@ -410,6 +405,8 @@ class NODE_PT_active_node_properties(Panel): bl_space_type = 'NODE_EDITOR' bl_region_type = 'UI' bl_label = "Properties" + bl_options = {'DEFAULT_CLOSED'} + bl_parent_id = 'NODE_PT_active_node_generic' @classmethod def poll(cls, context): @@ -453,18 +450,22 @@ class NODE_PT_backdrop(Panel): def draw(self, context): layout = self.layout + layout.use_property_split = True snode = context.space_data layout.active = snode.show_backdrop - layout.prop(snode, "backdrop_channels", text="") - layout.prop(snode, "backdrop_zoom", text="Zoom") - col = layout.column(align=True) - col.label(text="Offset:") - col.prop(snode, "backdrop_offset", text="") - col.operator("node.backimage_move", text="Move") + col = layout.column() - layout.operator("node.backimage_fit", text="Fit") + col.prop(snode, "backdrop_channels", text="Channels") + col.prop(snode, "backdrop_zoom", text="Zoom") + + col.prop(snode, "backdrop_offset", text="Offset") + + col.separator() + + col.operator("node.backimage_move", text="Move") + col.operator("node.backimage_fit", text="Fit") class NODE_PT_quality(bpy.types.Panel): @@ -479,6 +480,7 @@ class NODE_PT_quality(bpy.types.Panel): def draw(self, context): layout = self.layout + layout.use_property_split = True snode = context.space_data tree = snode.node_tree @@ -522,19 +524,7 @@ class NODE_UL_interface_sockets(bpy.types.UIList): class NODE_PT_grease_pencil(GreasePencilDataPanel, 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 - - -# Grease Pencil palette colors -class NODE_PT_grease_pencil_palettecolor(GreasePencilPaletteColorPanel, Panel): - bl_space_type = 'NODE_EDITOR' - bl_region_type = 'UI' + bl_options = {'DEFAULT_CLOSED'} # NOTE: this is just a wrapper around the generic GP Panel @@ -563,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' - # ----------------------------- @@ -612,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, ) diff --git a/release/scripts/startup/bl_ui/space_outliner.py b/release/scripts/startup/bl_ui/space_outliner.py index 8f722c4d3ce..20ef5ae0c53 100644 --- a/release/scripts/startup/bl_ui/space_outliner.py +++ b/release/scripts/startup/bl_ui/space_outliner.py @@ -142,8 +142,15 @@ class OUTLINER_MT_collection_view_layer(Menu): space = context.space_data - layout.operator("outliner.collection_exclude_set", text="Exclude") - layout.operator("outliner.collection_include_set", text="Include") + layout.operator("outliner.collection_exclude_set") + layout.operator("outliner.collection_exclude_clear") + + if context.engine == 'CYCLES': + layout.operator("outliner.collection_indirect_only_set") + layout.operator("outliner.collection_indirect_only_clear") + + layout.operator("outliner.collection_holdout_set") + layout.operator("outliner.collection_holdout_clear") class OUTLINER_MT_collection(Menu): diff --git a/release/scripts/startup/bl_ui/space_sequencer.py b/release/scripts/startup/bl_ui/space_sequencer.py index 0bdfcc39ed9..84ae59772b6 100644 --- a/release/scripts/startup/bl_ui/space_sequencer.py +++ b/release/scripts/startup/bl_ui/space_sequencer.py @@ -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_ @@ -343,9 +342,21 @@ class SEQUENCER_MT_add(Menu): layout.operator("sequencer.image_strip_add", text="Image") layout.operator("sequencer.sound_strip_add", text="Sound") + layout.menu("SEQUENCER_MT_add_generate") layout.menu("SEQUENCER_MT_add_effect") +class SEQUENCER_MT_add_generate(Menu): + bl_label = "Generate" + + def draw(self, context): + layout = self.layout + + layout.operator_context = 'INVOKE_REGION_WIN' + layout.operator("sequencer.effect_strip_add", text="Color").type = 'COLOR' + layout.operator("sequencer.effect_strip_add", text="Text").type = 'TEXT' + + class SEQUENCER_MT_add_effect(Menu): bl_label = "Effect Strip" @@ -365,10 +376,8 @@ class SEQUENCER_MT_add_effect(Menu): layout.operator("sequencer.effect_strip_add", text="Over Drop").type = 'OVER_DROP' layout.operator("sequencer.effect_strip_add", text="Wipe").type = 'WIPE' layout.operator("sequencer.effect_strip_add", text="Glow").type = 'GLOW' - layout.operator("sequencer.effect_strip_add", text="Text").type = 'TEXT' layout.operator("sequencer.effect_strip_add", text="Color Mix").type = 'COLORMIX' layout.operator("sequencer.effect_strip_add", text="Transform").type = 'TRANSFORM' - layout.operator("sequencer.effect_strip_add", text="Color").type = 'COLOR' layout.operator("sequencer.effect_strip_add", text="Speed Control").type = 'SPEED' layout.operator("sequencer.effect_strip_add", text="Multicam Selector").type = 'MULTICAM' layout.operator("sequencer.effect_strip_add", text="Adjustment Layer").type = 'ADJUSTMENT' @@ -1271,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' @@ -1289,7 +1290,7 @@ class SEQUENCER_PT_grease_pencil_tools(GreasePencilToolsPanel, SequencerButtonsP class SEQUENCER_PT_custom_props(SequencerButtonsPanel, PropertyPanel, Panel): - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} _context_path = "scene.sequence_editor.active_strip" _property_type = (bpy.types.Sequence,) bl_category = "Strip" @@ -1304,6 +1305,7 @@ classes = ( SEQUENCER_MT_marker, SEQUENCER_MT_frame, SEQUENCER_MT_add, + SEQUENCER_MT_add_generate, SEQUENCER_MT_add_effect, SEQUENCER_MT_strip, SEQUENCER_MT_strip_transform, @@ -1322,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, ) diff --git a/release/scripts/startup/bl_ui/space_toolsystem_common.py b/release/scripts/startup/bl_ui/space_toolsystem_common.py index 4c954874f0d..91ded3e4456 100644 --- a/release/scripts/startup/bl_ui/space_toolsystem_common.py +++ b/release/scripts/startup/bl_ui/space_toolsystem_common.py @@ -74,7 +74,7 @@ ToolDef = namedtuple( "icon", # An optional cursor to use when this tool is active. "cursor", - # An optional manipulator group to activate when the tool is set or None for no widget. + # An optional gizmo group to activate when the tool is set or None for no gizmo. "widget", # Optional keymap for tool, either: # - A function that populates a keymaps passed in as an argument. @@ -275,6 +275,7 @@ class ToolSelectPanelHelper: mode = context.mode tool = context.workspace.tools.from_space_view3d_mode(mode, create) if tool is not None: + tool.refresh_from_context() return tool elif space_type == 'IMAGE_EDITOR': space_data = context.space_data @@ -282,6 +283,7 @@ class ToolSelectPanelHelper: mode = space_data.mode tool = context.workspace.tools.from_space_image_mode(mode, create) if tool is not None: + tool.refresh_from_context() return tool return None diff --git a/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py b/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py index dbab7c7e037..e1ecba1550a 100644 --- a/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py +++ b/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py @@ -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 ( @@ -41,19 +42,68 @@ def generate_from_brushes_ex( ): # 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: + def draw_settings(context, layout, tool): + _defs_gpencil_paint.draw_settings_common(context, layout, tool) + + 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 + text = name + + # XXX, disabled since changing the brush needs to sync back to the tool. + """ + # 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. + icon_name = { + 'PENCIL': 'draw_pencil', + 'PEN': 'draw_pen', + 'INK': 'draw_ink', + 'INKNOISE': 'draw_noise', + 'BLOCK': 'draw_block', + 'MARKER': 'draw_marker', + 'FILL': 'draw_fill', + 'SOFT': 'draw.eraser_soft', + 'HARD': 'draw.eraser_hard', + 'STROKE': 'draw.eraser_stroke', + }[category] + 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 +111,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: @@ -80,6 +131,28 @@ def generate_from_brushes_ex( return tool_defs +def generate_from_enum_ex( + context, *, + icon_prefix, + data, + attr, +): + tool_defs = [] + for enum in data.rna_type.properties[attr].enum_items_static: + name = enum.name + identifier = enum.identifier + tool_defs.append( + ToolDef.from_dict( + dict( + text=name, + icon=icon_prefix + identifier.lower(), + data_block=identifier, + ) + ) + ) + return tuple(tool_defs) + + class _defs_view3d_generic: @ToolDef.from_fn def cursor(): @@ -118,55 +191,157 @@ class _defs_view3d_generic: return dict( text="Ruler", icon="ops.view3d.ruler", - widget="VIEW3D_WGT_ruler", + widget="VIEW3D_GGT_ruler", keymap=( ("view3d.ruler_add", dict(), dict(type='EVT_TWEAK_A', value='ANY')), ), ) +class _defs_annotate: + @classmethod + def draw_settings_common(cls, context, layout, tool): + ts = context.tool_settings + + space_type = tool.space_type + if space_type == 'VIEW_3D': + layout.separator() + + row = layout.row(align=True) + row.prop(ts, "annotation_stroke_placement_view3d", text="Placement") + 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 def translate(): + def draw_settings(context, layout, tool): + tool_settings = context.tool_settings + layout.prop(tool_settings, "use_gizmo_apron") + return dict( text="Grab", # cursor='SCROLL_XY', icon="ops.transform.translate", - widget="TRANSFORM_WGT_gizmo", + widget="TRANSFORM_GGT_gizmo", operator="transform.translate", # TODO, implement as optional fallback gizmo # keymap=( # ("transform.translate", dict(release_confirm=True), dict(type='EVT_TWEAK_A', value='ANY')), # ), + draw_settings=draw_settings, ) @ToolDef.from_fn def rotate(): + def draw_settings(context, layout, tool): + tool_settings = context.tool_settings + layout.prop(tool_settings, "use_gizmo_apron") + return dict( text="Rotate", # cursor='SCROLL_XY', icon="ops.transform.rotate", - widget="TRANSFORM_WGT_gizmo", + widget="TRANSFORM_GGT_gizmo", operator="transform.rotate", # TODO, implement as optional fallback gizmo # keymap=( # ("transform.rotate", dict(release_confirm=True), dict(type='EVT_TWEAK_A', value='ANY')), # ), + draw_settings=draw_settings, ) @ToolDef.from_fn def scale(): + def draw_settings(context, layout, tool): + tool_settings = context.tool_settings + layout.prop(tool_settings, "use_gizmo_apron") + return dict( text="Scale", # cursor='SCROLL_XY', icon="ops.transform.resize", - widget="TRANSFORM_WGT_gizmo", + widget="TRANSFORM_GGT_gizmo", operator="transform.resize", # TODO, implement as optional fallback gizmo # keymap=( # ("transform.resize", dict(release_confirm=True), dict(type='EVT_TWEAK_A', value='ANY')), # ), + draw_settings=draw_settings, ) @ToolDef.from_fn @@ -174,7 +349,7 @@ class _defs_transform: return dict( text="Scale Cage", icon="ops.transform.resize.cage", - widget="VIEW3D_WGT_xform_cage", + widget="VIEW3D_GGT_xform_cage", operator="transform.resize", ) @@ -182,12 +357,13 @@ class _defs_transform: def transform(): def draw_settings(context, layout, tool): tool_settings = context.tool_settings - layout.prop(tool_settings, "use_gizmo") + layout.prop(tool_settings, "use_gizmo_apron") + layout.prop(tool_settings, "use_gizmo_mode") return dict( text="Transform", icon="ops.transform.transform", - widget="TRANSFORM_WGT_gizmo", + widget="TRANSFORM_GGT_gizmo", # No keymap default action, only for gizmo! draw_settings=draw_settings, ) @@ -462,7 +638,7 @@ class _defs_edit_mesh: return dict( text="Extrude Region", icon="ops.mesh.extrude_region_move", - widget="MESH_WGT_extrude", + widget="MESH_GGT_extrude", operator="view3d.edit_mesh_extrude_move_normal", keymap=( ("mesh.extrude_context_move", dict(TRANSFORM_OT_translate=dict(release_confirm=True)), @@ -684,6 +860,18 @@ class _defs_pose: ) +class _defs_particle: + + @staticmethod + def generate_from_brushes(context): + return generate_from_enum_ex( + context, + icon_prefix="brush.particle.", + data=context.tool_settings.particle_edit, + attr="tool", + ) + + class _defs_sculpt: @staticmethod @@ -866,6 +1054,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' bl_region_type = 'TOOLS' @@ -951,8 +1464,6 @@ class VIEW3D_PT_tools_active(ToolSelectPanelHelper, Panel): _defs_transform.scale, _defs_transform.scale_cage, ), - None, - _defs_view3d_generic.ruler, ) _tools_select = ( @@ -963,6 +1474,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 +1493,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 +1523,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,13 +1576,13 @@ class VIEW3D_PT_tools_active(ToolSelectPanelHelper, Panel): None, *_tools_transform, None, + *_tools_annotate, + None, _defs_edit_curve.draw, _defs_edit_curve.extrude_cursor, ], 'PARTICLE': [ - # TODO(campbell): use cursor click tool to allow paint tools to run, - # we need to integrate particle system tools properly. - _defs_view3d_generic.cursor_click, + _defs_particle.generate_from_brushes, ], 'SCULPT': [ _defs_sculpt.generate_from_brushes, @@ -1075,6 +1604,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, + ], } diff --git a/release/scripts/startup/bl_ui/space_topbar.py b/release/scripts/startup/bl_ui/space_topbar.py index 96ef2e51e60..a417ef856f9 100644 --- a/release/scripts/startup/bl_ui/space_topbar.py +++ b/release/scripts/startup/bl_ui/space_topbar.py @@ -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: @@ -213,6 +224,27 @@ class _draw_left_context_mode: UnifiedPaintPanel.prop_unified_size(layout, context, brush, "size", slider=True, text="Radius") UnifiedPaintPanel.prop_unified_strength(layout, context, brush, "strength", slider=True, text="Strength") + def PARTICLE(context, layout): + # See: 'VIEW3D_PT_tools_brush', basically a duplicate + settings = context.tool_settings.particle_edit + brush = settings.brush + tool = settings.tool + if tool != 'NONE': + layout.prop(brush, "size", slider=True) + if tool == 'ADD': + layout.prop(brush, "count") + else: + layout.prop(brush, "strength", slider=True) + + if tool == 'ADD': + layout.prop(settings, "use_default_interpolate") + layout.prop(brush, "steps", slider=True) + layout.prop(settings, "default_key_count", slider=True) + elif tool == 'LENGTH': + layout.row().prop(brush, "length_mode", expand=True) + elif tool == 'PUFF': + layout.row().prop(brush, "puff_mode", expand=True) + layout.prop(brush, "use_puff_volume") class INFO_MT_editor_menus(Menu): bl_idname = "INFO_MT_editor_menus" @@ -265,8 +297,8 @@ class INFO_MT_file(Menu): layout.separator() layout.operator_context = 'INVOKE_AREA' - layout.operator("wm.link", text="Link", icon='LINK_BLEND') - layout.operator("wm.append", text="Append", icon='APPEND_BLEND') + layout.operator("wm.link", text="Link...", icon='LINK_BLEND') + layout.operator("wm.append", text="Append...", icon='APPEND_BLEND') layout.menu("INFO_MT_file_previews") layout.separator() @@ -383,26 +415,20 @@ class INFO_MT_render(Menu): props = layout.operator("render.render", text="Render Animation", icon='RENDER_ANIMATION') props.animation = True props.use_viewport = True - layout.operator("sound.mixdown", text="Render Audio", icon='PLAY_AUDIO') layout.separator() - layout.prop_menu_enum(rd, "display_mode", text="Display Mode") - layout.prop(rd, "use_lock_interface", text="Lock Interface") + layout.operator("sound.mixdown", text="Render Audio...") layout.separator() - props = layout.operator("render.opengl", text="OpenGL Render Image", icon='RENDER_STILL') - props.view_context = False - props = layout.operator("render.opengl", text="OpenGL Render Animation", icon='RENDER_ANIMATION') - props.view_context = False - props.animation = True - layout.menu("INFO_MT_opengl_render") + layout.operator("render.view_show", text="View Render") + layout.operator("render.play_rendered_anim", text="View Animation") + layout.prop_menu_enum(rd, "display_mode", text="Display Mode") layout.separator() - layout.operator("render.view_show") - layout.operator("render.play_rendered_anim", icon='PLAY') + layout.prop(rd, "use_lock_interface", text="Lock Interface") class INFO_MT_opengl_render(Menu): @@ -495,12 +521,25 @@ class INFO_MT_help(Menu): def draw(self, context): layout = self.layout + show_developer = context.user_preferences.view.show_developer_ui + layout.operator( "wm.url_open", text="Manual", icon='HELP', ).url = "https://docs.blender.org/manual/en/dev/" + layout.operator( - "wm.url_open", text="Release Log", icon='URL', - ).url = "http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/%d.%d" % bpy.app.version[:2] + "wm.url_open", text="Report a Bug", icon='URL', + ).url = "https://developer.blender.org/maniphest/task/edit/form/1" + + layout.separator() + + layout.operator( + "wm.url_open", text="User Communities", icon='URL', + ).url = "https://www.blender.org/community/" + layout.operator( + "wm.url_open", text="Developer Community", icon='URL', + ).url = "https://www.blender.org/get-involved/developers/" + layout.separator() layout.operator( @@ -509,24 +548,22 @@ class INFO_MT_help(Menu): layout.operator( "wm.url_open", text="Blender Store", icon='URL', ).url = "https://store.blender.org" + layout.operator( - "wm.url_open", text="Developer Community", icon='URL', - ).url = "https://www.blender.org/get-involved/" - layout.operator( - "wm.url_open", text="User Community", icon='URL', - ).url = "https://www.blender.org/support/user-community" - layout.separator() - layout.operator( - "wm.url_open", text="Report a Bug", icon='URL', - ).url = "https://developer.blender.org/maniphest/task/edit/form/1" + "wm.url_open", text="Release Notes", icon='URL', + ).url = "https://www.blender.org/download/releases/%d-%d/" % bpy.app.version[:2] + layout.separator() - layout.operator( - "wm.url_open", text="Python API Reference", icon='URL', - ).url = bpy.types.WM_OT_doc_view._prefix + if show_developer: + layout.operator( + "wm.url_open", text="Python API Reference", icon='URL', + ).url = bpy.types.WM_OT_doc_view._prefix + + layout.operator("wm.operator_cheat_sheet", icon='TEXT') + + layout.operator("wm.sysinfo") - layout.operator("wm.operator_cheat_sheet", icon='TEXT') - layout.operator("wm.sysinfo", icon='TEXT') layout.separator() layout.operator("wm.splash", icon='BLENDER') @@ -539,8 +576,13 @@ class TOPBAR_MT_file_specials(Menu): layout = self.layout layout.operator_context = 'INVOKE_AREA' - layout.operator("wm.link", text="Link", icon='LINK_BLEND') - layout.operator("wm.append", text="Append", icon='APPEND_BLEND') + layout.operator("wm.read_homefile", text="New", icon='NEW') + layout.operator("wm.open_mainfile", text="Open...", icon='FILE_FOLDER') + + layout.separator() + + layout.operator("wm.link", text="Link...", icon='LINK_BLEND') + layout.operator("wm.append", text="Append...", icon='APPEND_BLEND') layout.separator() @@ -589,7 +631,6 @@ classes = ( INFO_MT_edit, INFO_MT_game, INFO_MT_render, - INFO_MT_opengl_render, INFO_MT_window, INFO_MT_help, ) diff --git a/release/scripts/startup/bl_ui/space_userpref.py b/release/scripts/startup/bl_ui/space_userpref.py index e2bca0b6b33..52d4640806d 100644 --- a/release/scripts/startup/bl_ui/space_userpref.py +++ b/release/scripts/startup/bl_ui/space_userpref.py @@ -28,25 +28,6 @@ from bpy.app.translations import pgettext_iface as iface_ from bpy.app.translations import contexts as i18n_contexts -def opengl_light_buttons(column, light): - split = column.row() - - split.prop(light, "use", text="", icon='OUTLINER_OB_LIGHT' if light.use else 'LIGHT_DATA') - - col = split.column() - col.active = light.use - row = col.row() - row.label(text="Diffuse:") - row.prop(light, "diffuse_color", text="") - row = col.row() - row.label(text="Specular:") - row.prop(light, "specular_color", text="") - - col = split.column() - col.active = light.use - col.prop(light, "direction", text="") - - class USERPREF_HT_header(Header): bl_space_type = 'USER_PREFERENCES' @@ -380,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() @@ -546,47 +529,34 @@ 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") - - col.separator() - - col.label(text="Textures:") - col.prop(system, "gl_texture_limit", text="Limit Size") - col.prop(system, "texture_time_out", text="Time Out") - col.prop(system, "texture_collection_rate", text="Collection Rate") - - col.separator() - - col.label(text="Images Draw Method:") - col.prop(system, "image_draw_method", text="") - - col.separator() - - col.label(text="Sequencer/Clip Editor:") - # currently disabled in the code - # col.prop(system, "prefetch_frames") - col.prop(system, "memory_cache_limit") + if system.use_text_antialiasing: + col.prop(system, "use_text_hinting") # 3. Column column = split.column() - column.label(text="Solid OpenGL Lights:") + column.label(text="Textures:") + column.prop(system, "gl_texture_limit", text="Limit Size") + column.prop(system, "texture_time_out", text="Time Out") + column.prop(system, "texture_collection_rate", text="Collection Rate") - split = column.split(percentage=0.1) - split.label() - split.label(text="Colors:") - split.label(text="Direction:") + column.separator() - light = system.solid_lights[0] - opengl_light_buttons(column, light) + column.label(text="Images Draw Method:") + column.prop(system, "image_draw_method", text="") - light = system.solid_lights[1] - opengl_light_buttons(column, light) + column.separator() - light = system.solid_lights[2] - opengl_light_buttons(column, light) + column.label(text="Sequencer/Clip Editor:") + # currently disabled in the code + # column.prop(system, "prefetch_frames") + column.prop(system, "memory_cache_limit") column.separator() @@ -1596,13 +1566,6 @@ class StudioLightPanelMixin(): def _get_lights(self, userpref): return [light for light in userpref.studio_lights if light.is_user_defined and light.orientation == self.sl_orientation] - def draw_header(self, context): - layout = self.layout - row = layout.row() - userpref = context.user_preferences - lights = self._get_lights(userpref) - row.label("({})".format(len(lights))) - def draw(self, context): layout = self.layout userpref = context.user_preferences @@ -1640,6 +1603,48 @@ class USERPREF_PT_studiolight_camera(Panel, StudioLightPanelMixin): sl_orientation = 'CAMERA' +class USERPREF_PT_studiolight_specular(Panel, StudioLightPanelMixin): + bl_label = "Specular Lights" + sl_orientation = 'CAMERA' + + @classmethod + def poll(cls, context): + userpref = context.user_preferences + return (userpref.active_section == 'LIGHTS') + + def opengl_light_buttons(self, column, light): + split = column.split() + + col = split.column() + col.prop(light, "use", text="Use", icon='OUTLINER_OB_LIGHT' if light.use else 'LIGHT_DATA') + + sub = col.column() + sub.active = light.use + sub.prop(light, "specular_color") + + col = split.column() + col.active = light.use + col.prop(light, "direction", text="") + + def draw(self, context): + layout = self.layout + column = layout.split() + + userpref = context.user_preferences + system = userpref.system + + light = system.solid_lights[0] + colsplit = column.split(percentage=0.85) + self.opengl_light_buttons(colsplit, light) + + light = system.solid_lights[1] + colsplit = column.split(percentage=0.85) + self.opengl_light_buttons(colsplit, light) + + light = system.solid_lights[2] + self.opengl_light_buttons(column, light) + + classes = ( USERPREF_HT_header, USERPREF_PT_tabs, @@ -1663,6 +1668,7 @@ classes = ( USERPREF_PT_studiolight_matcaps, USERPREF_PT_studiolight_world, USERPREF_PT_studiolight_camera, + USERPREF_PT_studiolight_specular, ) if __name__ == "__main__": # only for live edit. diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index a508790c046..e8350a9642f 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -19,11 +19,8 @@ # <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 @@ -51,7 +48,7 @@ class VIEW3D_HT_header(Header): layout.template_header_3D_mode() - # Contains buttons like Mode, Pivot, Manipulator, Layer, Mesh Select Mode... + # Contains buttons like Mode, Pivot, Layer, Mesh Select Mode... shading_type = view.shading.type shading_item = bpy.types.View3DShading.bl_rna.properties["type"].enum_items[shading_type] @@ -83,18 +80,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) @@ -104,7 +123,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 @@ -129,7 +148,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: @@ -163,13 +183,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 and obj.type == 'GPENCIL': + 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) @@ -193,7 +215,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) @@ -237,13 +259,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: @@ -271,7 +294,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()) @@ -458,7 +489,7 @@ class VIEW3D_MT_snap(Menu): layout.operator("view3d.snap_selected_to_grid", text="Selection to Grid") layout.operator("view3d.snap_selected_to_cursor", text="Selection to Cursor").use_offset = False - layout.operator("view3d.snap_selected_to_cursor", text="Selection to Cursor (Offset)").use_offset = True + layout.operator("view3d.snap_selected_to_cursor", text="Selection to Cursor (Keep Offset)").use_offset = True layout.operator("view3d.snap_selected_to_active", text="Selection to Active") layout.separator() @@ -647,9 +678,12 @@ class VIEW3D_MT_view_align(Menu): layout.separator() - layout.operator("view3d.view_all", text="Center Cursor and View All").center = True layout.operator("view3d.camera_to_view", text="Align Active Camera to View") layout.operator("view3d.camera_to_view_selected", text="Align Active Camera to Selected") + + layout.separator() + + layout.operator("view3d.view_all", text="Center Cursor and View All").center = True layout.operator("view3d.view_center_cursor") layout.separator() @@ -672,6 +706,8 @@ class VIEW3D_MT_view_align_selected(Menu): props.align_active = True props.type = 'BOTTOM' + layout.separator() + props = layout.operator("view3d.view_axis", text="Front") props.align_active = True props.type = 'FRONT' @@ -680,6 +716,8 @@ class VIEW3D_MT_view_align_selected(Menu): props.align_active = True props.type = 'BACK' + layout.separator() + props = layout.operator("view3d.view_axis", text="Right") props.align_active = True props.type = 'RIGHT' @@ -1192,6 +1230,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() @@ -1459,6 +1498,7 @@ class INFO_MT_add(Menu): layout.menu("INFO_MT_metaball_add", text="Metaball", icon='OUTLINER_OB_META') layout.menu("INFO_MT_groom_add", text="Groom", icon='OUTLINER_OB_GROOM') layout.operator("object.text_add", text="Text", icon='OUTLINER_OB_FONT') + layout.operator_menu_enum("object.gpencil_add", "type", text="Grease Pencil", icon='OUTLINER_OB_GREASEPENCIL') layout.separator() layout.menu("INFO_MT_armature_add", icon='OUTLINER_OB_ARMATURE') @@ -1558,8 +1598,8 @@ class VIEW3D_MT_object(Menu): layout.separator() - layout.operator("object.shade_smooth", text="Smooth Shading") - layout.operator("object.shade_flat", text="Flat Shading") + layout.operator("object.shade_smooth") + layout.operator("object.shade_flat") layout.separator() @@ -2672,6 +2712,9 @@ class VIEW3D_MT_edit_mesh(Menu): layout.menu("VIEW3D_MT_edit_mesh_showhide") layout.operator_menu_enum("mesh.separate", "type") layout.menu("VIEW3D_MT_edit_mesh_clean") + + layout.separator() + layout.menu("VIEW3D_MT_edit_mesh_delete") @@ -2896,14 +2939,11 @@ class VIEW3D_MT_edit_mesh_edges_data(Menu): props.use_verts = True props.clear = True - layout.separator() - - layout.separator() - if with_freestyle: + layout.separator() + layout.operator("mesh.mark_freestyle_edge").clear = False layout.operator("mesh.mark_freestyle_edge", text="Clear Freestyle Edge").clear = True - layout.separator() class VIEW3D_MT_edit_mesh_edges(Menu): @@ -3028,6 +3068,30 @@ class VIEW3D_MT_edit_mesh_normals(Menu): layout.operator("mesh.flip_normals") layout.operator("mesh.set_normals_from_faces", text="Set From Faces") + layout.operator("transform.rotate_normal", text="Rotate Normal") + layout.operator("mesh.point_normals", text="Point normals to target") + + layout.operator("mesh.merge_normals", text="Merge") + layout.operator("mesh.split_normals", text="Split") + + layout.operator("mesh.average_normals", text="Average Normals") + + layout.label(text="Normal Vector") + + layout.operator("mesh.normals_tools", text="Copy").mode = 'COPY' + layout.operator("mesh.normals_tools", text="Paste").mode = 'PASTE' + + layout.operator("mesh.normals_tools", text="Multiply").mode = 'MULTIPLY' + layout.operator("mesh.normals_tools", text="Add").mode = 'ADD' + + layout.operator("mesh.normals_tools", text="Reset").mode = 'RESET' + + layout.operator("mesh.smoothen_normals", text="Smoothen") + + layout.label(text="Face Strength") + layout.operator("mesh.mod_weighted_strength", text="Face select", icon = "FACESEL").set = False + layout.operator("mesh.mod_weighted_strength", text="Set Strength", icon = "ZOOMIN").set = True + class VIEW3D_MT_edit_mesh_shading(Menu): bl_label = "Shading" @@ -3120,12 +3184,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 @@ -3508,11 +3577,46 @@ 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_assign_material(Menu): + bl_label = "Assign Material" + + def draw(self, context): + layout = self.layout + ob = context.active_object + + for slot in ob.material_slots: + mat = slot.material + layout.operator("gpencil.stroke_change_color", text=mat.name).material = mat.name class VIEW3D_MT_edit_gpencil(Menu): - bl_label = "GPencil" + bl_label = "Strokes" def draw(self, context): tool_settings = context.tool_settings @@ -3520,53 +3624,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.menu("VIEW3D_MT_assign_material") + 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.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.reveal") - layout.operator("gpencil.hide", text="Show Active Layer Only").unselected = True - layout.operator("gpencil.hide", text="Hide Active Layer").unselected = False + 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.menu("VIEW3D_MT_assign_material") 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): @@ -3627,20 +3804,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' @@ -3752,8 +3915,9 @@ class VIEW3D_PT_object_type_visibility(Panel): "armature", "lattice", "empty", + "grease_pencil", "camera", - "lamp", + "light", "light_probe", "speaker", ) @@ -3780,6 +3944,15 @@ class VIEW3D_PT_shading(Panel): bl_label = "Shading" bl_ui_units_x = 11 + @classmethod + def get_shading(cls, context): + # Get settings from 3D viewport or OpenGL render engine + view = context.space_data + if view.type == 'VIEW_3D': + return view.shading + else: + return context.scene.display.shading + def draw(self, context): pass @@ -3792,9 +3965,7 @@ class VIEW3D_PT_shading_lighting(Panel): def draw(self, context): layout = self.layout - - view = context.space_data - shading = view.shading + shading = VIEW3D_PT_shading.get_shading(context) col = layout.column() split = col.split(0.9) @@ -3806,10 +3977,10 @@ class VIEW3D_PT_shading_lighting(Panel): split = layout.split(0.9) col = split.column() sub = col.row() - sub.scale_y = 0.6 # smaller matcap/hdri preview + sub.scale_y = 0.6 # smaller matcap/hdri preview if shading.light == 'STUDIO': - sub.template_icon_view(shading, "studio_light", show_labels=True, scale=3) + sub.template_icon_view(shading, "studio_light", scale=3) if shading.selected_studio_light.orientation == 'WORLD': col.prop(shading, "studiolight_rotate_z", text="Rotation") @@ -3818,7 +3989,7 @@ class VIEW3D_PT_shading_lighting(Panel): col.operator('wm.studiolight_userpref_show', emboss=False, text="", icon='PREFERENCES') elif shading.light == 'MATCAP': - sub.template_icon_view(shading, "studio_light", show_labels=True, scale=3) + sub.template_icon_view(shading, "studio_light", scale=3) col = split.column() col.operator('wm.studiolight_userpref_show', emboss=False, text="", icon='PREFERENCES') @@ -3835,7 +4006,7 @@ class VIEW3D_PT_shading_lighting(Panel): col = split.column() sub = col.row() sub.scale_y = 0.6 - sub.template_icon_view(shading, "studio_light", show_labels=True, scale=3) + sub.template_icon_view(shading, "studio_light", scale=3) col = split.column() col.operator('wm.studiolight_userpref_show', emboss=False, text="", icon='PREFERENCES') @@ -3845,7 +4016,7 @@ class VIEW3D_PT_shading_lighting(Panel): col = split.column() col.prop(shading, "studiolight_rotate_z", text="Rotation") col.prop(shading, "studiolight_background_alpha") - col = split.column() # to align properly with above + col = split.column() # to align properly with above class VIEW3D_PT_shading_color(Panel): @@ -3856,20 +4027,22 @@ class VIEW3D_PT_shading_color(Panel): @classmethod def poll(cls, context): - view = context.space_data - shading = view.shading + shading = VIEW3D_PT_shading.get_shading(context) return shading.type == 'SOLID' def draw(self, context): layout = self.layout - view = context.space_data - shading = view.shading - - layout.row().prop(shading, "color_type", expand=True) + shading = VIEW3D_PT_shading.get_shading(context) + layout.row().prop(shading, 'color_type', expand=True) if shading.color_type == 'SINGLE': - layout.row().prop(shading, "single_color", text="") + layout.row().prop(shading, 'single_color', text="") + + layout.row().label("Background") + layout.row().prop(shading, 'background_type', expand=True) + if shading.background_type == 'VIEWPORT': + layout.row().prop(shading, "background_color", text="") class VIEW3D_PT_shading_options(Panel): @@ -3880,15 +4053,13 @@ class VIEW3D_PT_shading_options(Panel): @classmethod def poll(cls, context): - view = context.space_data - shading = view.shading + shading = VIEW3D_PT_shading.get_shading(context) return shading.type == 'SOLID' def draw(self, context): layout = self.layout - view = context.space_data - shading = view.shading + shading = VIEW3D_PT_shading.get_shading(context) col = layout.column() @@ -3941,8 +4112,6 @@ class VIEW3D_PT_shading_options(Panel): if not shading.light == 'MATCAP': col.prop(shading, "show_specular_highlight") - col.prop(view, "show_world") - class VIEW3D_PT_shading_options_shadow(Panel): bl_label = "Shadow Settings" @@ -4067,6 +4236,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' @@ -4387,7 +4558,7 @@ class VIEW3D_PT_overlay_edit_curve(Panel): bl_space_type = 'VIEW_3D' bl_region_type = 'HEADER' bl_parent_id = 'VIEW3D_PT_overlay' - bl_label = "Edit Curve" + bl_label = "Curve Edit Mode" @classmethod def poll(cls, context): @@ -4462,7 +4633,7 @@ class VIEW3D_PT_overlay_edit_armature(Panel): bl_space_type = 'VIEW_3D' bl_region_type = 'HEADER' bl_parent_id = 'VIEW3D_PT_overlay' - bl_label = "Edit Armature" + bl_label = "Armature Edit Mode" @classmethod def poll(cls, context): @@ -4532,9 +4703,9 @@ class VIEW3D_PT_pivot_point(Panel): col.label("Pivot Point") col.prop(toolsettings, "transform_pivot_point", expand=True) - col.separator() - if (obj is None) or (mode in {'OBJECT', 'POSE', 'WEIGHT_PAINT'}): + col.separator() + col.prop( toolsettings, "use_transform_pivot_point_align", @@ -4605,6 +4776,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' @@ -4632,6 +4857,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' @@ -4711,6 +4944,84 @@ 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) + + +class VIEW3D_MT_gpencil_edit_specials(Menu): + bl_label = "Grease Pencil Specials" + + def draw(self, context): + layout = self.layout + is_3d_view = context.space_data.type == 'VIEW_3D' + + layout.operator_context = 'INVOKE_REGION_WIN' + + layout.menu("VIEW3D_MT_assign_material") + layout.separator() + + 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() + + layout.operator("gpencil.stroke_join", text="Join").type = 'JOIN' + 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 VIEW3D_MT_gpencil_sculpt_specials(Menu): + bl_label = "Grease Pencil Specials" + + def draw(self, context): + layout = self.layout + is_3d_view = context.space_data.type == 'VIEW_3D' + + layout.operator_context = 'INVOKE_REGION_WIN' + layout.menu("VIEW3D_MT_assign_material") + layout.separator() + + 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.stroke_subdivide", text="Subdivide") + layout.operator("gpencil.stroke_simplify_fixed", text="Simplify") + layout.operator("gpencil.stroke_simplify", text="Simplify Adaptative") + + classes = ( VIEW3D_HT_header, VIEW3D_MT_editor_menus, @@ -4819,8 +5130,14 @@ classes = ( VIEW3D_MT_edit_mesh_clean, VIEW3D_MT_edit_mesh_delete, VIEW3D_MT_edit_mesh_showhide, + VIEW3D_MT_paint_gpencil, + VIEW3D_MT_assign_material, 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, @@ -4844,12 +5161,14 @@ 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_MT_gpencil_edit_specials, + VIEW3D_MT_gpencil_sculpt_specials, VIEW3D_PT_quad_view, VIEW3D_PT_view3d_stereo, VIEW3D_PT_shading, @@ -4878,6 +5197,7 @@ classes = ( VIEW3D_PT_pivot_point, VIEW3D_PT_snapping, VIEW3D_PT_transform_orientations, + VIEW3D_PT_overlay_gpencil_options, VIEW3D_PT_context_properties, ) diff --git a/release/scripts/startup/bl_ui/space_view3d_toolbar.py b/release/scripts/startup/bl_ui/space_view3d_toolbar.py index 8d1b124578c..febe95c5522 100644 --- a/release/scripts/startup/bl_ui/space_view3d_toolbar.py +++ b/release/scripts/startup/bl_ui/space_view3d_toolbar.py @@ -20,12 +20,9 @@ import bpy from bpy.types import Menu, Panel, UIList from .properties_grease_pencil_common import ( - GreasePencilDrawingToolsPanel, GreasePencilStrokeEditPanel, - GreasePencilInterpolatePanel, GreasePencilStrokeSculptPanel, - GreasePencilBrushPanel, - GreasePencilBrushCurvesPanel + GreasePencilAppearancePanel, ) from .properties_paint_common import ( UnifiedPaintPanel, @@ -33,6 +30,7 @@ from .properties_paint_common import ( brush_texpaint_common, brush_mask_texture_settings, ) +from bl_operators.presets import PresetMenu class View3DPanel: @@ -70,6 +68,16 @@ 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 **************** @@ -280,16 +288,16 @@ class VIEW3D_PT_tools_brush(Panel, View3DPaintPanel): if context.particle_edit_object: tool = settings.tool - layout.column().prop(settings, "tool", expand=True) - if tool != 'NONE': + layout.column().prop(settings, "tool") col = layout.column() col.prop(brush, "size", slider=True) - if tool != 'ADD': + if tool == 'ADD': + col.prop(brush, "count") + else: col.prop(brush, "strength", slider=True) if tool == 'ADD': - col.prop(brush, "count") col = layout.column() col.prop(settings, "use_default_interpolate") col.prop(brush, "steps", slider=True) @@ -1340,9 +1348,295 @@ 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): +class VIEW3D_PT_tools_normal(View3DPanel, Panel): + bl_category = "" + bl_context = ".mesh_edit" + bl_label = "Normal Tools" + + def draw(self, context): + layout = self.layout + toolsettings = context.tool_settings + + col = layout.column(align=True) + col.label(text="Normal Vector") + col.prop(toolsettings, "normal_vector", text="") + + layout.separator() + layout.label(text="Face Strength") + layout.prop(toolsettings, "face_strength", text="") + + col = layout.column(align=True) + + +# ********** 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 + + col = layout.column(align=True) + col.prop(gp_settings, "pen_smooth_factor") + col.prop(gp_settings, "pen_thick_smooth_factor") + + col = layout.column(align=True) + col.prop(gp_settings, "pen_smooth_steps") + col.prop(gp_settings, "pen_thick_smooth_steps") + + col = layout.column(align=True) + col.prop(gp_settings, "pen_subdivision_steps") + col.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 @@ -1351,24 +1645,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 = ( @@ -1400,12 +1779,22 @@ 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, + VIEW3D_PT_tools_normal, ) if __name__ == "__main__": # only for live edit. diff --git a/release/scripts/startup/nodeitems_builtins.py b/release/scripts/startup/nodeitems_builtins.py index e6500b7c2c0..a70d78c16c6 100644 --- a/release/scripts/startup/nodeitems_builtins.py +++ b/release/scripts/startup/nodeitems_builtins.py @@ -216,6 +216,7 @@ shader_node_categories = [ NodeItem("ShaderNodeVolumeScatter", poll=eevee_cycles_shader_nodes_poll), NodeItem("ShaderNodeVolumePrincipled"), NodeItem("ShaderNodeEeveeSpecular", poll=object_eevee_shader_nodes_poll), + NodeItem("ShaderNodeBsdfHairPrincipled", poll=object_shader_nodes_poll) ]), ShaderNodeCategory("SH_NEW_TEXTURE", "Texture", items=[ NodeItem("ShaderNodeTexImage"), @@ -365,6 +366,7 @@ compositor_node_categories = [ NodeItem("CompositorNodeChromaMatte"), NodeItem("CompositorNodeColorMatte"), NodeItem("CompositorNodeDoubleEdgeMask"), + NodeItem("CompositorNodeCryptomatte"), ]), CompositorNodeCategory("CMP_DISTORT", "Distort", items=[ NodeItem("CompositorNodeScale"), diff --git a/release/scripts/templates_py/batch_export.py b/release/scripts/templates_py/batch_export.py index 1463915886a..a07491742ec 100644 --- a/release/scripts/templates_py/batch_export.py +++ b/release/scripts/templates_py/batch_export.py @@ -9,9 +9,9 @@ basedir = os.path.dirname(bpy.data.filepath) if not basedir: raise Exception("Blend file is not saved") -scene = bpy.context.scene +view_layer = bpy.context.view_layer -obj_active = scene.objects.active +obj_active = view_layer.objects.active selection = bpy.context.selected_objects bpy.ops.object.select_all(action='DESELECT') @@ -21,7 +21,7 @@ for obj in selection: obj.select_set(action='SELECT') # some exporters only use the active object - scene.objects.active = obj + view_layer.objects.active = obj name = bpy.path.clean_name(obj.name) fn = os.path.join(basedir, name) @@ -36,7 +36,7 @@ for obj in selection: print("written:", fn) -scene.objects.active = obj_active +view_layer.objects.active = obj_active for obj in selection: obj.select_set(action='SELECT') diff --git a/release/scripts/templates_py/gizmo_custom_geometry.py b/release/scripts/templates_py/gizmo_custom_geometry.py index f71237f52f7..8125498fa85 100644 --- a/release/scripts/templates_py/gizmo_custom_geometry.py +++ b/release/scripts/templates_py/gizmo_custom_geometry.py @@ -63,7 +63,7 @@ custom_shape_verts = ( class MyCustomShapeWidget(Gizmo): - bl_idname = "VIEW3D_WT_auto_facemap" + bl_idname = "VIEW3D_GT_auto_facemap" bl_target_properties = ( {"id": "offset", "type": 'FLOAT', "array_length": 1}, ) @@ -113,7 +113,7 @@ class MyCustomShapeWidget(Gizmo): class MyCustomShapeWidgetGroup(GizmoGroup): - bl_idname = "OBJECT_WGT_light_test" + bl_idname = "OBJECT_GGT_light_test" bl_label = "Test Light Widget" bl_space_type = 'VIEW_3D' bl_region_type = 'WINDOW' diff --git a/release/scripts/templates_py/gizmo_operator.py b/release/scripts/templates_py/gizmo_operator.py index 3cbb0801e9c..bdc1bc9893c 100644 --- a/release/scripts/templates_py/gizmo_operator.py +++ b/release/scripts/templates_py/gizmo_operator.py @@ -80,7 +80,7 @@ class SelectSideOfPlane(Operator): # Gizmos for plane_co, plane_no class SelectSideOfPlaneGizmoGroup(GizmoGroup): - bl_idname = "MESH_WGT_select_side_of_plane" + bl_idname = "MESH_GGT_select_side_of_plane" bl_label = "Side of Plane Gizmo" bl_space_type = 'VIEW_3D' bl_region_type = 'WINDOW' @@ -126,7 +126,7 @@ class SelectSideOfPlaneGizmoGroup(GizmoGroup): # XXX, this may change! op.execute(context) - mpr = self.gizmos.new("GIZMO_WT_grab_3d") + mpr = self.gizmos.new("GIZMO_GT_grab_3d") mpr.target_set_handler("offset", get=grab_get_cb, set=grab_set_cb) mpr.use_draw_value = True @@ -161,7 +161,7 @@ class SelectSideOfPlaneGizmoGroup(GizmoGroup): op.plane_no = no op.execute(context) - mpr = self.gizmos.new("GIZMO_WT_dial_3d") + mpr = self.gizmos.new("GIZMO_GT_dial_3d") mpr.target_set_handler("offset", get=direction_get_cb, set=direction_set_cb) mpr.draw_options = {'ANGLE_START_Y'} diff --git a/release/scripts/templates_py/gizmo_operator_target.py b/release/scripts/templates_py/gizmo_operator_target.py index 08fe63ef0b7..606aa6749d0 100644 --- a/release/scripts/templates_py/gizmo_operator_target.py +++ b/release/scripts/templates_py/gizmo_operator_target.py @@ -10,7 +10,7 @@ from bpy.types import ( class MyCameraWidgetGroup(GizmoGroup): - bl_idname = "OBJECT_WGT_test_camera" + bl_idname = "OBJECT_GGT_test_camera" bl_label = "Object Camera Test Widget" bl_space_type = 'VIEW_3D' bl_region_type = 'WINDOW' @@ -24,7 +24,7 @@ class MyCameraWidgetGroup(GizmoGroup): def setup(self, context): # Run an operator using the dial gizmo ob = context.object - mpr = self.gizmos.new("GIZMO_WT_dial_3d") + mpr = self.gizmos.new("GIZMO_GT_dial_3d") props = mpr.target_set_operator("transform.rotate") props.constraint_axis = False, False, True props.constraint_orientation = 'LOCAL' diff --git a/release/scripts/templates_py/gizmo_simple.py b/release/scripts/templates_py/gizmo_simple.py index 0fd1e0b386b..396378da04c 100644 --- a/release/scripts/templates_py/gizmo_simple.py +++ b/release/scripts/templates_py/gizmo_simple.py @@ -11,7 +11,7 @@ from bpy.types import ( class MyLightWidgetGroup(GizmoGroup): - bl_idname = "OBJECT_WGT_light_test" + bl_idname = "OBJECT_GGT_light_test" bl_label = "Test Light Widget" bl_space_type = 'VIEW_3D' bl_region_type = 'WINDOW' @@ -25,7 +25,7 @@ class MyLightWidgetGroup(GizmoGroup): def setup(self, context): # Arrow gizmo has one 'offset' property we can assign to the light energy. ob = context.object - mpr = self.gizmos.new("GIZMO_WT_arrow_3d") + mpr = self.gizmos.new("GIZMO_GT_arrow_3d") mpr.target_set_prop("offset", ob.data, "energy") mpr.matrix_basis = ob.matrix_world.normalized() mpr.draw_style = 'BOX' diff --git a/release/scripts/templates_py/operator_modal_view3d_raycast.py b/release/scripts/templates_py/operator_modal_view3d_raycast.py index e3b63813fc4..613501143f7 100644 --- a/release/scripts/templates_py/operator_modal_view3d_raycast.py +++ b/release/scripts/templates_py/operator_modal_view3d_raycast.py @@ -68,7 +68,7 @@ def main(context, event): # we could do lots of stuff but for the example just select. if best_obj is not None: best_obj.select_set(action='SELECT') - context.scene.objects.active = best_obj + context.view_layer.objects.active = best_obj class ViewOperatorRayCast(bpy.types.Operator): |