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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'release')
-rw-r--r--release/datafiles/brushicons/gp_brush_block.pngbin0 -> 6088 bytes
-rw-r--r--release/datafiles/brushicons/gp_brush_clone.pngbin0 -> 2586 bytes
-rw-r--r--release/datafiles/brushicons/gp_brush_erase_hard.pngbin0 -> 6107 bytes
-rw-r--r--release/datafiles/brushicons/gp_brush_erase_soft.pngbin0 -> 6252 bytes
-rw-r--r--release/datafiles/brushicons/gp_brush_erase_stroke.pngbin0 -> 5955 bytes
-rw-r--r--release/datafiles/brushicons/gp_brush_fill.pngbin0 -> 5707 bytes
-rw-r--r--release/datafiles/brushicons/gp_brush_grab.pngbin0 -> 2741 bytes
-rw-r--r--release/datafiles/brushicons/gp_brush_ink.pngbin0 -> 4034 bytes
-rw-r--r--release/datafiles/brushicons/gp_brush_inknoise.pngbin0 -> 5591 bytes
-rw-r--r--release/datafiles/brushicons/gp_brush_marker.pngbin0 -> 5996 bytes
-rw-r--r--release/datafiles/brushicons/gp_brush_pen.pngbin0 -> 4920 bytes
-rw-r--r--release/datafiles/brushicons/gp_brush_pencil.pngbin0 -> 3965 bytes
-rw-r--r--release/datafiles/brushicons/gp_brush_pinch.pngbin0 -> 5432 bytes
-rw-r--r--release/datafiles/brushicons/gp_brush_push.pngbin0 -> 2914 bytes
-rw-r--r--release/datafiles/brushicons/gp_brush_randomize.pngbin0 -> 5726 bytes
-rw-r--r--release/datafiles/brushicons/gp_brush_smooth.pngbin0 -> 3105 bytes
-rw-r--r--release/datafiles/brushicons/gp_brush_strength.pngbin0 -> 3229 bytes
-rw-r--r--release/datafiles/brushicons/gp_brush_thickness.pngbin0 -> 5066 bytes
-rw-r--r--release/datafiles/brushicons/gp_brush_twist.pngbin0 -> 4776 bytes
-rw-r--r--release/datafiles/brushicons/gp_brush_weight.pngbin0 -> 2460 bytes
-rw-r--r--release/datafiles/colormanagement/config.ocio2
-rw-r--r--release/datafiles/icons/brush.gpencil.draw.eraser_hard.datbin0 -> 1736 bytes
-rw-r--r--release/datafiles/icons/brush.gpencil.draw.eraser_soft.datbin0 -> 1880 bytes
-rw-r--r--release/datafiles/icons/brush.gpencil.draw.eraser_stroke.datbin0 -> 2456 bytes
-rw-r--r--release/datafiles/icons/brush.gpencil.draw_block.datbin0 -> 2006 bytes
-rw-r--r--release/datafiles/icons/brush.gpencil.draw_fill.datbin0 -> 6326 bytes
-rw-r--r--release/datafiles/icons/brush.gpencil.draw_ink.datbin0 -> 2240 bytes
-rw-r--r--release/datafiles/icons/brush.gpencil.draw_marker.datbin0 -> 2690 bytes
-rw-r--r--release/datafiles/icons/brush.gpencil.draw_noise.datbin0 -> 3086 bytes
-rw-r--r--release/datafiles/icons/brush.gpencil.draw_pen.datbin0 -> 3158 bytes
-rw-r--r--release/datafiles/icons/brush.gpencil.draw_pencil.datbin0 -> 2780 bytes
-rw-r--r--release/datafiles/icons/brush.particle.add.datbin0 -> 2060 bytes
-rw-r--r--release/datafiles/icons/brush.particle.comb.datbin0 -> 3590 bytes
-rw-r--r--release/datafiles/icons/brush.particle.cut.datbin0 -> 6578 bytes
-rw-r--r--release/datafiles/icons/brush.particle.length.datbin0 -> 3824 bytes
-rw-r--r--release/datafiles/icons/brush.particle.puff.datbin0 -> 3644 bytes
-rw-r--r--release/datafiles/icons/brush.particle.smooth.datbin0 -> 2870 bytes
-rw-r--r--release/datafiles/icons/brush.particle.weight.datbin0 -> 3878 bytes
-rw-r--r--release/datafiles/icons/ops.gpencil.draw.datbin0 -> 2492 bytes
-rw-r--r--release/datafiles/icons/ops.gpencil.draw.eraser.datbin0 -> 2384 bytes
-rw-r--r--release/datafiles/icons/ops.gpencil.draw.line.datbin0 -> 1664 bytes
-rw-r--r--release/datafiles/icons/ops.gpencil.draw.poly.datbin0 -> 1736 bytes
-rw-r--r--release/datafiles/icons/ops.gpencil.edit_bend.datbin0 -> 2330 bytes
-rw-r--r--release/datafiles/icons/ops.gpencil.edit_mirror.datbin0 -> 620 bytes
-rw-r--r--release/datafiles/icons/ops.gpencil.edit_shear.datbin0 -> 332 bytes
-rw-r--r--release/datafiles/icons/ops.gpencil.edit_to_sphere.datbin0 -> 1790 bytes
-rw-r--r--release/datafiles/icons/ops.gpencil.sculpt_clone.datbin0 -> 4328 bytes
-rw-r--r--release/datafiles/icons/ops.gpencil.sculpt_grab.datbin0 -> 1664 bytes
-rw-r--r--release/datafiles/icons/ops.gpencil.sculpt_pinch.datbin0 -> 3482 bytes
-rw-r--r--release/datafiles/icons/ops.gpencil.sculpt_push.datbin0 -> 1664 bytes
-rw-r--r--release/datafiles/icons/ops.gpencil.sculpt_randomize.datbin0 -> 6254 bytes
-rw-r--r--release/datafiles/icons/ops.gpencil.sculpt_smooth.datbin0 -> 3788 bytes
-rw-r--r--release/datafiles/icons/ops.gpencil.sculpt_strength.datbin0 -> 5228 bytes
-rw-r--r--release/datafiles/icons/ops.gpencil.sculpt_thickness.datbin0 -> 1700 bytes
-rw-r--r--release/datafiles/icons/ops.gpencil.sculpt_twist.datbin0 -> 2942 bytes
-rw-r--r--release/datafiles/icons/ops.gpencil.sculpt_weight.datbin0 -> 1736 bytes
m---------release/datafiles/locale0
-rw-r--r--release/datafiles/preview_grease_pencil.blendbin0 -> 947876 bytes
-rw-r--r--release/datafiles/studiolights/matcap/basic_1.exrbin0 -> 44539 bytes
-rw-r--r--release/datafiles/studiolights/matcap/basic_2.exrbin0 -> 61142 bytes
-rw-r--r--release/datafiles/studiolights/matcap/basic_dark.exrbin0 -> 38734 bytes
-rw-r--r--release/datafiles/studiolights/matcap/basic_side.exrbin0 -> 41554 bytes
-rw-r--r--release/datafiles/studiolights/matcap/ceramic_dark.exrbin0 -> 63518 bytes
-rw-r--r--release/datafiles/studiolights/matcap/ceramic_lightbulb.exrbin0 -> 102212 bytes
-rw-r--r--release/datafiles/studiolights/matcap/check_normal+y.exrbin0 -> 87477 bytes
-rw-r--r--release/datafiles/studiolights/matcap/check_reflection.exrbin0 -> 151596 bytes
-rw-r--r--release/datafiles/studiolights/matcap/check_rim_dark.exrbin0 -> 50807 bytes
-rw-r--r--release/datafiles/studiolights/matcap/check_rim_light.exrbin0 -> 56757 bytes
-rw-r--r--release/datafiles/studiolights/matcap/clay_brown.exrbin0 -> 65156 bytes
-rw-r--r--release/datafiles/studiolights/matcap/clay_muddy.exrbin0 -> 53778 bytes
-rw-r--r--release/datafiles/studiolights/matcap/clay_studio.exrbin0 -> 51624 bytes
-rw-r--r--release/datafiles/studiolights/matcap/jade.exrbin0 -> 63103 bytes
-rw-r--r--release/datafiles/studiolights/matcap/license.txt4
-rw-r--r--release/datafiles/studiolights/matcap/mc01.jpgbin20830 -> 0 bytes
-rw-r--r--release/datafiles/studiolights/matcap/mc02.jpgbin23428 -> 0 bytes
-rw-r--r--release/datafiles/studiolights/matcap/mc03.jpgbin17550 -> 0 bytes
-rw-r--r--release/datafiles/studiolights/matcap/mc04.jpgbin29197 -> 0 bytes
-rw-r--r--release/datafiles/studiolights/matcap/mc05.jpgbin25454 -> 0 bytes
-rw-r--r--release/datafiles/studiolights/matcap/mc06.jpgbin19864 -> 0 bytes
-rw-r--r--release/datafiles/studiolights/matcap/mc07.jpgbin59262 -> 0 bytes
-rw-r--r--release/datafiles/studiolights/matcap/mc08.jpgbin24133 -> 0 bytes
-rw-r--r--release/datafiles/studiolights/matcap/mc09.jpgbin31101 -> 0 bytes
-rw-r--r--release/datafiles/studiolights/matcap/mc10.jpgbin28973 -> 0 bytes
-rw-r--r--release/datafiles/studiolights/matcap/mc11.jpgbin21395 -> 0 bytes
-rw-r--r--release/datafiles/studiolights/matcap/mc12.jpgbin23797 -> 0 bytes
-rw-r--r--release/datafiles/studiolights/matcap/mc13.jpgbin45661 -> 0 bytes
-rw-r--r--release/datafiles/studiolights/matcap/mc14.jpgbin44762 -> 0 bytes
-rw-r--r--release/datafiles/studiolights/matcap/mc15.jpgbin27456 -> 0 bytes
-rw-r--r--release/datafiles/studiolights/matcap/mc16.jpgbin33401 -> 0 bytes
-rw-r--r--release/datafiles/studiolights/matcap/mc17.jpgbin49292 -> 0 bytes
-rw-r--r--release/datafiles/studiolights/matcap/mc18.jpgbin40254 -> 0 bytes
-rw-r--r--release/datafiles/studiolights/matcap/mc19.jpgbin46330 -> 0 bytes
-rw-r--r--release/datafiles/studiolights/matcap/mc20.jpgbin52893 -> 0 bytes
-rw-r--r--release/datafiles/studiolights/matcap/mc21.jpgbin28717 -> 0 bytes
-rw-r--r--release/datafiles/studiolights/matcap/mc22.jpgbin33801 -> 0 bytes
-rw-r--r--release/datafiles/studiolights/matcap/mc23.jpgbin26688 -> 0 bytes
-rw-r--r--release/datafiles/studiolights/matcap/mc24.jpgbin14149 -> 0 bytes
-rw-r--r--release/datafiles/studiolights/matcap/metal_anisotropic.exrbin0 -> 118909 bytes
-rw-r--r--release/datafiles/studiolights/matcap/metal_carpaint.exrbin0 -> 91775 bytes
-rw-r--r--release/datafiles/studiolights/matcap/metal_lead.exrbin0 -> 41455 bytes
-rw-r--r--release/datafiles/studiolights/matcap/metal_shiny.exrbin0 -> 126238 bytes
-rw-r--r--release/datafiles/studiolights/matcap/pearl.exrbin0 -> 70218 bytes
-rw-r--r--release/datafiles/studiolights/matcap/resin.exrbin0 -> 91009 bytes
-rw-r--r--release/datafiles/studiolights/matcap/skin.exrbin0 -> 55351 bytes
-rw-r--r--release/datafiles/studiolights/matcap/toon.exrbin0 -> 55733 bytes
-rw-r--r--release/datafiles/userdef/userdef_default_theme.c10
m---------release/scripts/addons0
-rw-r--r--release/scripts/modules/addon_utils.py16
-rw-r--r--release/scripts/modules/bpy_extras/keyconfig_utils.py7
-rw-r--r--release/scripts/modules/bpy_extras/object_utils.py4
-rw-r--r--release/scripts/modules/bpy_extras/view3d_utils.py4
-rw-r--r--release/scripts/modules/bpy_types.py30
-rw-r--r--release/scripts/modules/rna_prop_ui.py17
-rw-r--r--release/scripts/startup/bl_operators/add_mesh_torus.py9
-rw-r--r--release/scripts/startup/bl_operators/clip.py16
-rw-r--r--release/scripts/startup/bl_operators/mesh.py50
-rw-r--r--release/scripts/startup/bl_operators/object.py2
-rw-r--r--release/scripts/startup/bl_operators/object_align.py8
-rw-r--r--release/scripts/startup/bl_operators/presets.py39
-rw-r--r--release/scripts/startup/bl_operators/rigidbody.py14
-rw-r--r--release/scripts/startup/bl_operators/uvcalc_lightmap.py2
-rw-r--r--release/scripts/startup/bl_operators/uvcalc_smart_project.py8
-rw-r--r--release/scripts/startup/bl_operators/wm.py15
-rw-r--r--release/scripts/startup/bl_ui/__init__.py3
-rw-r--r--release/scripts/startup/bl_ui/properties_animviz.py2
-rw-r--r--release/scripts/startup/bl_ui/properties_data_armature.py5
-rw-r--r--release/scripts/startup/bl_ui/properties_data_bone.py2
-rw-r--r--release/scripts/startup/bl_ui/properties_data_camera.py31
-rw-r--r--release/scripts/startup/bl_ui/properties_data_curve.py4
-rw-r--r--release/scripts/startup/bl_ui/properties_data_gpencil.py404
-rw-r--r--release/scripts/startup/bl_ui/properties_data_lattice.py2
-rw-r--r--release/scripts/startup/bl_ui/properties_data_light.py77
-rw-r--r--release/scripts/startup/bl_ui/properties_data_lightprobe.py7
-rw-r--r--release/scripts/startup/bl_ui/properties_data_mesh.py30
-rw-r--r--release/scripts/startup/bl_ui/properties_data_metaball.py4
-rw-r--r--release/scripts/startup/bl_ui/properties_data_modifier.py496
-rw-r--r--release/scripts/startup/bl_ui/properties_data_shaderfx.py135
-rw-r--r--release/scripts/startup/bl_ui/properties_data_speaker.py10
-rw-r--r--release/scripts/startup/bl_ui/properties_grease_pencil_common.py789
-rw-r--r--release/scripts/startup/bl_ui/properties_material.py17
-rw-r--r--release/scripts/startup/bl_ui/properties_material_gpencil.py321
-rw-r--r--release/scripts/startup/bl_ui/properties_object.py3
-rw-r--r--release/scripts/startup/bl_ui/properties_particle.py541
-rw-r--r--release/scripts/startup/bl_ui/properties_physics_cloth.py212
-rw-r--r--release/scripts/startup/bl_ui/properties_physics_common.py89
-rw-r--r--release/scripts/startup/bl_ui/properties_physics_dynamicpaint.py346
-rw-r--r--release/scripts/startup/bl_ui/properties_physics_field.py10
-rw-r--r--release/scripts/startup/bl_ui/properties_physics_rigidbody.py139
-rw-r--r--release/scripts/startup/bl_ui/properties_physics_rigidbody_constraint.py7
-rw-r--r--release/scripts/startup/bl_ui/properties_physics_smoke.py16
-rw-r--r--release/scripts/startup/bl_ui/properties_physics_softbody.py14
-rw-r--r--release/scripts/startup/bl_ui/properties_render.py122
-rw-r--r--release/scripts/startup/bl_ui/properties_scene.py246
-rw-r--r--release/scripts/startup/bl_ui/properties_texture.py596
-rw-r--r--release/scripts/startup/bl_ui/properties_view_layer.py2
-rw-r--r--release/scripts/startup/bl_ui/properties_world.py23
-rw-r--r--release/scripts/startup/bl_ui/space_clip.py41
-rw-r--r--release/scripts/startup/bl_ui/space_filebrowser.py4
-rw-r--r--release/scripts/startup/bl_ui/space_image.py40
-rw-r--r--release/scripts/startup/bl_ui/space_node.py74
-rw-r--r--release/scripts/startup/bl_ui/space_outliner.py11
-rw-r--r--release/scripts/startup/bl_ui/space_sequencer.py27
-rw-r--r--release/scripts/startup/bl_ui/space_toolsystem_common.py4
-rw-r--r--release/scripts/startup/bl_ui/space_toolsystem_toolbar.py608
-rw-r--r--release/scripts/startup/bl_ui/space_topbar.py105
-rw-r--r--release/scripts/startup/bl_ui/space_userpref.py124
-rw-r--r--release/scripts/startup/bl_ui/space_view3d.py504
-rw-r--r--release/scripts/startup/bl_ui/space_view3d_toolbar.py435
-rw-r--r--release/scripts/startup/nodeitems_builtins.py2
-rw-r--r--release/scripts/templates_py/batch_export.py8
-rw-r--r--release/scripts/templates_py/gizmo_custom_geometry.py4
-rw-r--r--release/scripts/templates_py/gizmo_operator.py6
-rw-r--r--release/scripts/templates_py/gizmo_operator_target.py4
-rw-r--r--release/scripts/templates_py/gizmo_simple.py4
-rw-r--r--release/scripts/templates_py/operator_modal_view3d_raycast.py2
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
new file mode 100644
index 00000000000..2db3964e573
--- /dev/null
+++ b/release/datafiles/brushicons/gp_brush_block.png
Binary files differ
diff --git a/release/datafiles/brushicons/gp_brush_clone.png b/release/datafiles/brushicons/gp_brush_clone.png
new file mode 100644
index 00000000000..8358ace23b3
--- /dev/null
+++ b/release/datafiles/brushicons/gp_brush_clone.png
Binary files differ
diff --git a/release/datafiles/brushicons/gp_brush_erase_hard.png b/release/datafiles/brushicons/gp_brush_erase_hard.png
new file mode 100644
index 00000000000..2ac52840678
--- /dev/null
+++ b/release/datafiles/brushicons/gp_brush_erase_hard.png
Binary files differ
diff --git a/release/datafiles/brushicons/gp_brush_erase_soft.png b/release/datafiles/brushicons/gp_brush_erase_soft.png
new file mode 100644
index 00000000000..416923004dd
--- /dev/null
+++ b/release/datafiles/brushicons/gp_brush_erase_soft.png
Binary files differ
diff --git a/release/datafiles/brushicons/gp_brush_erase_stroke.png b/release/datafiles/brushicons/gp_brush_erase_stroke.png
new file mode 100644
index 00000000000..cd6d21532cf
--- /dev/null
+++ b/release/datafiles/brushicons/gp_brush_erase_stroke.png
Binary files differ
diff --git a/release/datafiles/brushicons/gp_brush_fill.png b/release/datafiles/brushicons/gp_brush_fill.png
new file mode 100644
index 00000000000..9dac633139c
--- /dev/null
+++ b/release/datafiles/brushicons/gp_brush_fill.png
Binary files differ
diff --git a/release/datafiles/brushicons/gp_brush_grab.png b/release/datafiles/brushicons/gp_brush_grab.png
new file mode 100644
index 00000000000..2123ac69aef
--- /dev/null
+++ b/release/datafiles/brushicons/gp_brush_grab.png
Binary files differ
diff --git a/release/datafiles/brushicons/gp_brush_ink.png b/release/datafiles/brushicons/gp_brush_ink.png
new file mode 100644
index 00000000000..410a77f6117
--- /dev/null
+++ b/release/datafiles/brushicons/gp_brush_ink.png
Binary files differ
diff --git a/release/datafiles/brushicons/gp_brush_inknoise.png b/release/datafiles/brushicons/gp_brush_inknoise.png
new file mode 100644
index 00000000000..5356f697e01
--- /dev/null
+++ b/release/datafiles/brushicons/gp_brush_inknoise.png
Binary files differ
diff --git a/release/datafiles/brushicons/gp_brush_marker.png b/release/datafiles/brushicons/gp_brush_marker.png
new file mode 100644
index 00000000000..c7a62b78ca7
--- /dev/null
+++ b/release/datafiles/brushicons/gp_brush_marker.png
Binary files differ
diff --git a/release/datafiles/brushicons/gp_brush_pen.png b/release/datafiles/brushicons/gp_brush_pen.png
new file mode 100644
index 00000000000..9aaaa861f49
--- /dev/null
+++ b/release/datafiles/brushicons/gp_brush_pen.png
Binary files differ
diff --git a/release/datafiles/brushicons/gp_brush_pencil.png b/release/datafiles/brushicons/gp_brush_pencil.png
new file mode 100644
index 00000000000..2d1fbdfd916
--- /dev/null
+++ b/release/datafiles/brushicons/gp_brush_pencil.png
Binary files differ
diff --git a/release/datafiles/brushicons/gp_brush_pinch.png b/release/datafiles/brushicons/gp_brush_pinch.png
new file mode 100644
index 00000000000..e38236d1be0
--- /dev/null
+++ b/release/datafiles/brushicons/gp_brush_pinch.png
Binary files differ
diff --git a/release/datafiles/brushicons/gp_brush_push.png b/release/datafiles/brushicons/gp_brush_push.png
new file mode 100644
index 00000000000..542764309cc
--- /dev/null
+++ b/release/datafiles/brushicons/gp_brush_push.png
Binary files differ
diff --git a/release/datafiles/brushicons/gp_brush_randomize.png b/release/datafiles/brushicons/gp_brush_randomize.png
new file mode 100644
index 00000000000..0dd1a131d86
--- /dev/null
+++ b/release/datafiles/brushicons/gp_brush_randomize.png
Binary files differ
diff --git a/release/datafiles/brushicons/gp_brush_smooth.png b/release/datafiles/brushicons/gp_brush_smooth.png
new file mode 100644
index 00000000000..7518a358219
--- /dev/null
+++ b/release/datafiles/brushicons/gp_brush_smooth.png
Binary files differ
diff --git a/release/datafiles/brushicons/gp_brush_strength.png b/release/datafiles/brushicons/gp_brush_strength.png
new file mode 100644
index 00000000000..a0513119f29
--- /dev/null
+++ b/release/datafiles/brushicons/gp_brush_strength.png
Binary files differ
diff --git a/release/datafiles/brushicons/gp_brush_thickness.png b/release/datafiles/brushicons/gp_brush_thickness.png
new file mode 100644
index 00000000000..6026716f026
--- /dev/null
+++ b/release/datafiles/brushicons/gp_brush_thickness.png
Binary files differ
diff --git a/release/datafiles/brushicons/gp_brush_twist.png b/release/datafiles/brushicons/gp_brush_twist.png
new file mode 100644
index 00000000000..84b9a90e9d6
--- /dev/null
+++ b/release/datafiles/brushicons/gp_brush_twist.png
Binary files differ
diff --git a/release/datafiles/brushicons/gp_brush_weight.png b/release/datafiles/brushicons/gp_brush_weight.png
new file mode 100644
index 00000000000..171e9221e92
--- /dev/null
+++ b/release/datafiles/brushicons/gp_brush_weight.png
Binary files differ
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
new file mode 100644
index 00000000000..1e909ca8ac9
--- /dev/null
+++ b/release/datafiles/icons/brush.gpencil.draw.eraser_hard.dat
Binary files differ
diff --git a/release/datafiles/icons/brush.gpencil.draw.eraser_soft.dat b/release/datafiles/icons/brush.gpencil.draw.eraser_soft.dat
new file mode 100644
index 00000000000..7242f76a0f9
--- /dev/null
+++ b/release/datafiles/icons/brush.gpencil.draw.eraser_soft.dat
Binary files differ
diff --git a/release/datafiles/icons/brush.gpencil.draw.eraser_stroke.dat b/release/datafiles/icons/brush.gpencil.draw.eraser_stroke.dat
new file mode 100644
index 00000000000..6bf620bf3c2
--- /dev/null
+++ b/release/datafiles/icons/brush.gpencil.draw.eraser_stroke.dat
Binary files differ
diff --git a/release/datafiles/icons/brush.gpencil.draw_block.dat b/release/datafiles/icons/brush.gpencil.draw_block.dat
new file mode 100644
index 00000000000..7a7402ef673
--- /dev/null
+++ b/release/datafiles/icons/brush.gpencil.draw_block.dat
Binary files differ
diff --git a/release/datafiles/icons/brush.gpencil.draw_fill.dat b/release/datafiles/icons/brush.gpencil.draw_fill.dat
new file mode 100644
index 00000000000..809aed7f3cf
--- /dev/null
+++ b/release/datafiles/icons/brush.gpencil.draw_fill.dat
Binary files differ
diff --git a/release/datafiles/icons/brush.gpencil.draw_ink.dat b/release/datafiles/icons/brush.gpencil.draw_ink.dat
new file mode 100644
index 00000000000..3c654712783
--- /dev/null
+++ b/release/datafiles/icons/brush.gpencil.draw_ink.dat
Binary files differ
diff --git a/release/datafiles/icons/brush.gpencil.draw_marker.dat b/release/datafiles/icons/brush.gpencil.draw_marker.dat
new file mode 100644
index 00000000000..77a52dd83d4
--- /dev/null
+++ b/release/datafiles/icons/brush.gpencil.draw_marker.dat
Binary files differ
diff --git a/release/datafiles/icons/brush.gpencil.draw_noise.dat b/release/datafiles/icons/brush.gpencil.draw_noise.dat
new file mode 100644
index 00000000000..127f469b9fb
--- /dev/null
+++ b/release/datafiles/icons/brush.gpencil.draw_noise.dat
Binary files differ
diff --git a/release/datafiles/icons/brush.gpencil.draw_pen.dat b/release/datafiles/icons/brush.gpencil.draw_pen.dat
new file mode 100644
index 00000000000..cb6fb77924a
--- /dev/null
+++ b/release/datafiles/icons/brush.gpencil.draw_pen.dat
Binary files differ
diff --git a/release/datafiles/icons/brush.gpencil.draw_pencil.dat b/release/datafiles/icons/brush.gpencil.draw_pencil.dat
new file mode 100644
index 00000000000..a8898a94917
--- /dev/null
+++ b/release/datafiles/icons/brush.gpencil.draw_pencil.dat
Binary files differ
diff --git a/release/datafiles/icons/brush.particle.add.dat b/release/datafiles/icons/brush.particle.add.dat
new file mode 100644
index 00000000000..e78bf251371
--- /dev/null
+++ b/release/datafiles/icons/brush.particle.add.dat
Binary files differ
diff --git a/release/datafiles/icons/brush.particle.comb.dat b/release/datafiles/icons/brush.particle.comb.dat
new file mode 100644
index 00000000000..5ece6bf754d
--- /dev/null
+++ b/release/datafiles/icons/brush.particle.comb.dat
Binary files differ
diff --git a/release/datafiles/icons/brush.particle.cut.dat b/release/datafiles/icons/brush.particle.cut.dat
new file mode 100644
index 00000000000..79306d5d7e9
--- /dev/null
+++ b/release/datafiles/icons/brush.particle.cut.dat
Binary files differ
diff --git a/release/datafiles/icons/brush.particle.length.dat b/release/datafiles/icons/brush.particle.length.dat
new file mode 100644
index 00000000000..4c9da271316
--- /dev/null
+++ b/release/datafiles/icons/brush.particle.length.dat
Binary files differ
diff --git a/release/datafiles/icons/brush.particle.puff.dat b/release/datafiles/icons/brush.particle.puff.dat
new file mode 100644
index 00000000000..b0e797853c3
--- /dev/null
+++ b/release/datafiles/icons/brush.particle.puff.dat
Binary files differ
diff --git a/release/datafiles/icons/brush.particle.smooth.dat b/release/datafiles/icons/brush.particle.smooth.dat
new file mode 100644
index 00000000000..a3cbe3cf657
--- /dev/null
+++ b/release/datafiles/icons/brush.particle.smooth.dat
Binary files differ
diff --git a/release/datafiles/icons/brush.particle.weight.dat b/release/datafiles/icons/brush.particle.weight.dat
new file mode 100644
index 00000000000..309ee157a19
--- /dev/null
+++ b/release/datafiles/icons/brush.particle.weight.dat
Binary files differ
diff --git a/release/datafiles/icons/ops.gpencil.draw.dat b/release/datafiles/icons/ops.gpencil.draw.dat
new file mode 100644
index 00000000000..3adc50ab17d
--- /dev/null
+++ b/release/datafiles/icons/ops.gpencil.draw.dat
Binary files differ
diff --git a/release/datafiles/icons/ops.gpencil.draw.eraser.dat b/release/datafiles/icons/ops.gpencil.draw.eraser.dat
new file mode 100644
index 00000000000..323d8c23245
--- /dev/null
+++ b/release/datafiles/icons/ops.gpencil.draw.eraser.dat
Binary files differ
diff --git a/release/datafiles/icons/ops.gpencil.draw.line.dat b/release/datafiles/icons/ops.gpencil.draw.line.dat
new file mode 100644
index 00000000000..238db63807a
--- /dev/null
+++ b/release/datafiles/icons/ops.gpencil.draw.line.dat
Binary files differ
diff --git a/release/datafiles/icons/ops.gpencil.draw.poly.dat b/release/datafiles/icons/ops.gpencil.draw.poly.dat
new file mode 100644
index 00000000000..8351e48fec1
--- /dev/null
+++ b/release/datafiles/icons/ops.gpencil.draw.poly.dat
Binary files differ
diff --git a/release/datafiles/icons/ops.gpencil.edit_bend.dat b/release/datafiles/icons/ops.gpencil.edit_bend.dat
new file mode 100644
index 00000000000..32f7b2e9631
--- /dev/null
+++ b/release/datafiles/icons/ops.gpencil.edit_bend.dat
Binary files differ
diff --git a/release/datafiles/icons/ops.gpencil.edit_mirror.dat b/release/datafiles/icons/ops.gpencil.edit_mirror.dat
new file mode 100644
index 00000000000..ee073664f78
--- /dev/null
+++ b/release/datafiles/icons/ops.gpencil.edit_mirror.dat
Binary files differ
diff --git a/release/datafiles/icons/ops.gpencil.edit_shear.dat b/release/datafiles/icons/ops.gpencil.edit_shear.dat
new file mode 100644
index 00000000000..e6b51f988f8
--- /dev/null
+++ b/release/datafiles/icons/ops.gpencil.edit_shear.dat
Binary files differ
diff --git a/release/datafiles/icons/ops.gpencil.edit_to_sphere.dat b/release/datafiles/icons/ops.gpencil.edit_to_sphere.dat
new file mode 100644
index 00000000000..bf1181cd500
--- /dev/null
+++ b/release/datafiles/icons/ops.gpencil.edit_to_sphere.dat
Binary files differ
diff --git a/release/datafiles/icons/ops.gpencil.sculpt_clone.dat b/release/datafiles/icons/ops.gpencil.sculpt_clone.dat
new file mode 100644
index 00000000000..dbae6a68159
--- /dev/null
+++ b/release/datafiles/icons/ops.gpencil.sculpt_clone.dat
Binary files differ
diff --git a/release/datafiles/icons/ops.gpencil.sculpt_grab.dat b/release/datafiles/icons/ops.gpencil.sculpt_grab.dat
new file mode 100644
index 00000000000..291b4fd12dc
--- /dev/null
+++ b/release/datafiles/icons/ops.gpencil.sculpt_grab.dat
Binary files differ
diff --git a/release/datafiles/icons/ops.gpencil.sculpt_pinch.dat b/release/datafiles/icons/ops.gpencil.sculpt_pinch.dat
new file mode 100644
index 00000000000..cb2b43f5597
--- /dev/null
+++ b/release/datafiles/icons/ops.gpencil.sculpt_pinch.dat
Binary files differ
diff --git a/release/datafiles/icons/ops.gpencil.sculpt_push.dat b/release/datafiles/icons/ops.gpencil.sculpt_push.dat
new file mode 100644
index 00000000000..e1c4961ff86
--- /dev/null
+++ b/release/datafiles/icons/ops.gpencil.sculpt_push.dat
Binary files differ
diff --git a/release/datafiles/icons/ops.gpencil.sculpt_randomize.dat b/release/datafiles/icons/ops.gpencil.sculpt_randomize.dat
new file mode 100644
index 00000000000..35042936757
--- /dev/null
+++ b/release/datafiles/icons/ops.gpencil.sculpt_randomize.dat
Binary files differ
diff --git a/release/datafiles/icons/ops.gpencil.sculpt_smooth.dat b/release/datafiles/icons/ops.gpencil.sculpt_smooth.dat
new file mode 100644
index 00000000000..3a132ed4049
--- /dev/null
+++ b/release/datafiles/icons/ops.gpencil.sculpt_smooth.dat
Binary files differ
diff --git a/release/datafiles/icons/ops.gpencil.sculpt_strength.dat b/release/datafiles/icons/ops.gpencil.sculpt_strength.dat
new file mode 100644
index 00000000000..7e52b0d7648
--- /dev/null
+++ b/release/datafiles/icons/ops.gpencil.sculpt_strength.dat
Binary files differ
diff --git a/release/datafiles/icons/ops.gpencil.sculpt_thickness.dat b/release/datafiles/icons/ops.gpencil.sculpt_thickness.dat
new file mode 100644
index 00000000000..1e558806888
--- /dev/null
+++ b/release/datafiles/icons/ops.gpencil.sculpt_thickness.dat
Binary files differ
diff --git a/release/datafiles/icons/ops.gpencil.sculpt_twist.dat b/release/datafiles/icons/ops.gpencil.sculpt_twist.dat
new file mode 100644
index 00000000000..4ce958cb7ec
--- /dev/null
+++ b/release/datafiles/icons/ops.gpencil.sculpt_twist.dat
Binary files differ
diff --git a/release/datafiles/icons/ops.gpencil.sculpt_weight.dat b/release/datafiles/icons/ops.gpencil.sculpt_weight.dat
new file mode 100644
index 00000000000..41b58abfda7
--- /dev/null
+++ b/release/datafiles/icons/ops.gpencil.sculpt_weight.dat
Binary files differ
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
new file mode 100644
index 00000000000..82661d80029
--- /dev/null
+++ b/release/datafiles/preview_grease_pencil.blend
Binary files differ
diff --git a/release/datafiles/studiolights/matcap/basic_1.exr b/release/datafiles/studiolights/matcap/basic_1.exr
new file mode 100644
index 00000000000..bb2e09abbd2
--- /dev/null
+++ b/release/datafiles/studiolights/matcap/basic_1.exr
Binary files differ
diff --git a/release/datafiles/studiolights/matcap/basic_2.exr b/release/datafiles/studiolights/matcap/basic_2.exr
new file mode 100644
index 00000000000..d97f7630d63
--- /dev/null
+++ b/release/datafiles/studiolights/matcap/basic_2.exr
Binary files differ
diff --git a/release/datafiles/studiolights/matcap/basic_dark.exr b/release/datafiles/studiolights/matcap/basic_dark.exr
new file mode 100644
index 00000000000..b623c8030f8
--- /dev/null
+++ b/release/datafiles/studiolights/matcap/basic_dark.exr
Binary files differ
diff --git a/release/datafiles/studiolights/matcap/basic_side.exr b/release/datafiles/studiolights/matcap/basic_side.exr
new file mode 100644
index 00000000000..6e4452e7511
--- /dev/null
+++ b/release/datafiles/studiolights/matcap/basic_side.exr
Binary files differ
diff --git a/release/datafiles/studiolights/matcap/ceramic_dark.exr b/release/datafiles/studiolights/matcap/ceramic_dark.exr
new file mode 100644
index 00000000000..837b020c96d
--- /dev/null
+++ b/release/datafiles/studiolights/matcap/ceramic_dark.exr
Binary files differ
diff --git a/release/datafiles/studiolights/matcap/ceramic_lightbulb.exr b/release/datafiles/studiolights/matcap/ceramic_lightbulb.exr
new file mode 100644
index 00000000000..e05b6612e46
--- /dev/null
+++ b/release/datafiles/studiolights/matcap/ceramic_lightbulb.exr
Binary files differ
diff --git a/release/datafiles/studiolights/matcap/check_normal+y.exr b/release/datafiles/studiolights/matcap/check_normal+y.exr
new file mode 100644
index 00000000000..4e2a97ac3b9
--- /dev/null
+++ b/release/datafiles/studiolights/matcap/check_normal+y.exr
Binary files differ
diff --git a/release/datafiles/studiolights/matcap/check_reflection.exr b/release/datafiles/studiolights/matcap/check_reflection.exr
new file mode 100644
index 00000000000..245d6059241
--- /dev/null
+++ b/release/datafiles/studiolights/matcap/check_reflection.exr
Binary files differ
diff --git a/release/datafiles/studiolights/matcap/check_rim_dark.exr b/release/datafiles/studiolights/matcap/check_rim_dark.exr
new file mode 100644
index 00000000000..e6a32004ea1
--- /dev/null
+++ b/release/datafiles/studiolights/matcap/check_rim_dark.exr
Binary files differ
diff --git a/release/datafiles/studiolights/matcap/check_rim_light.exr b/release/datafiles/studiolights/matcap/check_rim_light.exr
new file mode 100644
index 00000000000..6318c0f9346
--- /dev/null
+++ b/release/datafiles/studiolights/matcap/check_rim_light.exr
Binary files differ
diff --git a/release/datafiles/studiolights/matcap/clay_brown.exr b/release/datafiles/studiolights/matcap/clay_brown.exr
new file mode 100644
index 00000000000..fe1e0305383
--- /dev/null
+++ b/release/datafiles/studiolights/matcap/clay_brown.exr
Binary files differ
diff --git a/release/datafiles/studiolights/matcap/clay_muddy.exr b/release/datafiles/studiolights/matcap/clay_muddy.exr
new file mode 100644
index 00000000000..d219578c62b
--- /dev/null
+++ b/release/datafiles/studiolights/matcap/clay_muddy.exr
Binary files differ
diff --git a/release/datafiles/studiolights/matcap/clay_studio.exr b/release/datafiles/studiolights/matcap/clay_studio.exr
new file mode 100644
index 00000000000..7746e6d0e35
--- /dev/null
+++ b/release/datafiles/studiolights/matcap/clay_studio.exr
Binary files differ
diff --git a/release/datafiles/studiolights/matcap/jade.exr b/release/datafiles/studiolights/matcap/jade.exr
new file mode 100644
index 00000000000..fe1211f1b65
--- /dev/null
+++ b/release/datafiles/studiolights/matcap/jade.exr
Binary files differ
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
deleted file mode 100644
index 8c7aef287ee..00000000000
--- a/release/datafiles/studiolights/matcap/mc01.jpg
+++ /dev/null
Binary files differ
diff --git a/release/datafiles/studiolights/matcap/mc02.jpg b/release/datafiles/studiolights/matcap/mc02.jpg
deleted file mode 100644
index 11deddfeaed..00000000000
--- a/release/datafiles/studiolights/matcap/mc02.jpg
+++ /dev/null
Binary files differ
diff --git a/release/datafiles/studiolights/matcap/mc03.jpg b/release/datafiles/studiolights/matcap/mc03.jpg
deleted file mode 100644
index 64d992fb61a..00000000000
--- a/release/datafiles/studiolights/matcap/mc03.jpg
+++ /dev/null
Binary files differ
diff --git a/release/datafiles/studiolights/matcap/mc04.jpg b/release/datafiles/studiolights/matcap/mc04.jpg
deleted file mode 100644
index 42be580ee93..00000000000
--- a/release/datafiles/studiolights/matcap/mc04.jpg
+++ /dev/null
Binary files differ
diff --git a/release/datafiles/studiolights/matcap/mc05.jpg b/release/datafiles/studiolights/matcap/mc05.jpg
deleted file mode 100644
index 586d233ef31..00000000000
--- a/release/datafiles/studiolights/matcap/mc05.jpg
+++ /dev/null
Binary files differ
diff --git a/release/datafiles/studiolights/matcap/mc06.jpg b/release/datafiles/studiolights/matcap/mc06.jpg
deleted file mode 100644
index 657883d0866..00000000000
--- a/release/datafiles/studiolights/matcap/mc06.jpg
+++ /dev/null
Binary files differ
diff --git a/release/datafiles/studiolights/matcap/mc07.jpg b/release/datafiles/studiolights/matcap/mc07.jpg
deleted file mode 100644
index 372caf7e87c..00000000000
--- a/release/datafiles/studiolights/matcap/mc07.jpg
+++ /dev/null
Binary files differ
diff --git a/release/datafiles/studiolights/matcap/mc08.jpg b/release/datafiles/studiolights/matcap/mc08.jpg
deleted file mode 100644
index 50eec402812..00000000000
--- a/release/datafiles/studiolights/matcap/mc08.jpg
+++ /dev/null
Binary files differ
diff --git a/release/datafiles/studiolights/matcap/mc09.jpg b/release/datafiles/studiolights/matcap/mc09.jpg
deleted file mode 100644
index e05d441aaf9..00000000000
--- a/release/datafiles/studiolights/matcap/mc09.jpg
+++ /dev/null
Binary files differ
diff --git a/release/datafiles/studiolights/matcap/mc10.jpg b/release/datafiles/studiolights/matcap/mc10.jpg
deleted file mode 100644
index ab82f17bb93..00000000000
--- a/release/datafiles/studiolights/matcap/mc10.jpg
+++ /dev/null
Binary files differ
diff --git a/release/datafiles/studiolights/matcap/mc11.jpg b/release/datafiles/studiolights/matcap/mc11.jpg
deleted file mode 100644
index 053550f082c..00000000000
--- a/release/datafiles/studiolights/matcap/mc11.jpg
+++ /dev/null
Binary files differ
diff --git a/release/datafiles/studiolights/matcap/mc12.jpg b/release/datafiles/studiolights/matcap/mc12.jpg
deleted file mode 100644
index beb16f3742e..00000000000
--- a/release/datafiles/studiolights/matcap/mc12.jpg
+++ /dev/null
Binary files differ
diff --git a/release/datafiles/studiolights/matcap/mc13.jpg b/release/datafiles/studiolights/matcap/mc13.jpg
deleted file mode 100644
index 7fb8fa58e8f..00000000000
--- a/release/datafiles/studiolights/matcap/mc13.jpg
+++ /dev/null
Binary files differ
diff --git a/release/datafiles/studiolights/matcap/mc14.jpg b/release/datafiles/studiolights/matcap/mc14.jpg
deleted file mode 100644
index ba868d2f95a..00000000000
--- a/release/datafiles/studiolights/matcap/mc14.jpg
+++ /dev/null
Binary files differ
diff --git a/release/datafiles/studiolights/matcap/mc15.jpg b/release/datafiles/studiolights/matcap/mc15.jpg
deleted file mode 100644
index b10ea326a42..00000000000
--- a/release/datafiles/studiolights/matcap/mc15.jpg
+++ /dev/null
Binary files differ
diff --git a/release/datafiles/studiolights/matcap/mc16.jpg b/release/datafiles/studiolights/matcap/mc16.jpg
deleted file mode 100644
index c6ce02d59df..00000000000
--- a/release/datafiles/studiolights/matcap/mc16.jpg
+++ /dev/null
Binary files differ
diff --git a/release/datafiles/studiolights/matcap/mc17.jpg b/release/datafiles/studiolights/matcap/mc17.jpg
deleted file mode 100644
index 14f15f70460..00000000000
--- a/release/datafiles/studiolights/matcap/mc17.jpg
+++ /dev/null
Binary files differ
diff --git a/release/datafiles/studiolights/matcap/mc18.jpg b/release/datafiles/studiolights/matcap/mc18.jpg
deleted file mode 100644
index db572856b07..00000000000
--- a/release/datafiles/studiolights/matcap/mc18.jpg
+++ /dev/null
Binary files differ
diff --git a/release/datafiles/studiolights/matcap/mc19.jpg b/release/datafiles/studiolights/matcap/mc19.jpg
deleted file mode 100644
index 56d2efb1734..00000000000
--- a/release/datafiles/studiolights/matcap/mc19.jpg
+++ /dev/null
Binary files differ
diff --git a/release/datafiles/studiolights/matcap/mc20.jpg b/release/datafiles/studiolights/matcap/mc20.jpg
deleted file mode 100644
index 002a0910dd9..00000000000
--- a/release/datafiles/studiolights/matcap/mc20.jpg
+++ /dev/null
Binary files differ
diff --git a/release/datafiles/studiolights/matcap/mc21.jpg b/release/datafiles/studiolights/matcap/mc21.jpg
deleted file mode 100644
index cb2fea573b8..00000000000
--- a/release/datafiles/studiolights/matcap/mc21.jpg
+++ /dev/null
Binary files differ
diff --git a/release/datafiles/studiolights/matcap/mc22.jpg b/release/datafiles/studiolights/matcap/mc22.jpg
deleted file mode 100644
index 2fc71b98c5a..00000000000
--- a/release/datafiles/studiolights/matcap/mc22.jpg
+++ /dev/null
Binary files differ
diff --git a/release/datafiles/studiolights/matcap/mc23.jpg b/release/datafiles/studiolights/matcap/mc23.jpg
deleted file mode 100644
index 3793c0fcaa5..00000000000
--- a/release/datafiles/studiolights/matcap/mc23.jpg
+++ /dev/null
Binary files differ
diff --git a/release/datafiles/studiolights/matcap/mc24.jpg b/release/datafiles/studiolights/matcap/mc24.jpg
deleted file mode 100644
index 2a9618d8fe1..00000000000
--- a/release/datafiles/studiolights/matcap/mc24.jpg
+++ /dev/null
Binary files differ
diff --git a/release/datafiles/studiolights/matcap/metal_anisotropic.exr b/release/datafiles/studiolights/matcap/metal_anisotropic.exr
new file mode 100644
index 00000000000..38ea94ac676
--- /dev/null
+++ b/release/datafiles/studiolights/matcap/metal_anisotropic.exr
Binary files differ
diff --git a/release/datafiles/studiolights/matcap/metal_carpaint.exr b/release/datafiles/studiolights/matcap/metal_carpaint.exr
new file mode 100644
index 00000000000..c5bcdf67abf
--- /dev/null
+++ b/release/datafiles/studiolights/matcap/metal_carpaint.exr
Binary files differ
diff --git a/release/datafiles/studiolights/matcap/metal_lead.exr b/release/datafiles/studiolights/matcap/metal_lead.exr
new file mode 100644
index 00000000000..4d6b2954ccd
--- /dev/null
+++ b/release/datafiles/studiolights/matcap/metal_lead.exr
Binary files differ
diff --git a/release/datafiles/studiolights/matcap/metal_shiny.exr b/release/datafiles/studiolights/matcap/metal_shiny.exr
new file mode 100644
index 00000000000..3b5d20ffda2
--- /dev/null
+++ b/release/datafiles/studiolights/matcap/metal_shiny.exr
Binary files differ
diff --git a/release/datafiles/studiolights/matcap/pearl.exr b/release/datafiles/studiolights/matcap/pearl.exr
new file mode 100644
index 00000000000..e657c67936e
--- /dev/null
+++ b/release/datafiles/studiolights/matcap/pearl.exr
Binary files differ
diff --git a/release/datafiles/studiolights/matcap/resin.exr b/release/datafiles/studiolights/matcap/resin.exr
new file mode 100644
index 00000000000..80e405aaa67
--- /dev/null
+++ b/release/datafiles/studiolights/matcap/resin.exr
Binary files differ
diff --git a/release/datafiles/studiolights/matcap/skin.exr b/release/datafiles/studiolights/matcap/skin.exr
new file mode 100644
index 00000000000..ffc3213dad9
--- /dev/null
+++ b/release/datafiles/studiolights/matcap/skin.exr
Binary files differ
diff --git a/release/datafiles/studiolights/matcap/toon.exr b/release/datafiles/studiolights/matcap/toon.exr
new file mode 100644
index 00000000000..242f5055e2b
--- /dev/null
+++ b/release/datafiles/studiolights/matcap/toon.exr
Binary files differ
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):