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:
authorBenoit Bolsee <benoit.bolsee@online.be>2011-09-07 19:34:04 +0400
committerBenoit Bolsee <benoit.bolsee@online.be>2011-09-07 19:34:04 +0400
commitdbd6658d737b1592a633ddf6397be14e50e434d9 (patch)
tree57081721d70622a3c3141909b258f9bce8a5b1e3 /release
parentb5bd86e5907c3fa98546dabeda9703dfb15862f4 (diff)
parent884fc84793be1c5fdd6643ad267331381f8e1c6b (diff)
svn merge -r 37306:39975 https://svn.blender.org/svnroot/bf-blender/trunk/blender
Diffstat (limited to 'release')
-rw-r--r--release/datafiles/blenderbuttonsbin210335 -> 215334 bytes
-rw-r--r--release/datafiles/splash.pngbin268962 -> 204738 bytes
-rw-r--r--release/scripts/modules/addon_utils.py89
-rw-r--r--release/scripts/modules/bpy/__init__.py41
-rw-r--r--release/scripts/modules/bpy/ops.py20
-rw-r--r--release/scripts/modules/bpy/path.py97
-rw-r--r--release/scripts/modules/bpy/utils.py90
-rw-r--r--release/scripts/modules/bpy_extras/__init__.py4
-rw-r--r--release/scripts/modules/bpy_extras/image_utils.py28
-rw-r--r--release/scripts/modules/bpy_extras/io_utils.py258
-rw-r--r--release/scripts/modules/bpy_extras/mesh_utils.py131
-rw-r--r--release/scripts/modules/bpy_extras/object_utils.py53
-rw-r--r--release/scripts/modules/bpy_extras/view3d_utils.py52
-rw-r--r--release/scripts/modules/bpy_types.py34
-rw-r--r--release/scripts/modules/bpyml.py2
-rw-r--r--release/scripts/modules/bpyml_ui.py7
-rw-r--r--release/scripts/modules/console/complete_namespace.py7
-rw-r--r--release/scripts/modules/console/intellisense.py23
-rw-r--r--release/scripts/modules/console_python.py4
-rw-r--r--release/scripts/modules/keyingsets_utils.py9
-rw-r--r--release/scripts/modules/rna_info.py8
-rw-r--r--release/scripts/modules/rna_prop_ui.py18
-rw-r--r--release/scripts/presets/ffmpeg/DV.py1
-rw-r--r--release/scripts/presets/ffmpeg/DVD.py1
-rw-r--r--release/scripts/presets/ffmpeg/SVCD.py1
-rw-r--r--release/scripts/presets/ffmpeg/VCD.py1
-rw-r--r--release/scripts/presets/ffmpeg/xvid.py3
-rw-r--r--release/scripts/startup/bl_operators/add_mesh_torus.py86
-rw-r--r--release/scripts/startup/bl_operators/animsys_update.py3
-rw-r--r--release/scripts/startup/bl_operators/image.py52
-rw-r--r--release/scripts/startup/bl_operators/mesh.py45
-rw-r--r--release/scripts/startup/bl_operators/nla.py191
-rw-r--r--release/scripts/startup/bl_operators/object.py305
-rw-r--r--release/scripts/startup/bl_operators/object_align.py272
-rw-r--r--release/scripts/startup/bl_operators/object_quick_effects.py365
-rw-r--r--release/scripts/startup/bl_operators/object_randomize_transform.py105
-rw-r--r--release/scripts/startup/bl_operators/presets.py78
-rw-r--r--release/scripts/startup/bl_operators/screen_play_rendered_anim.py99
-rw-r--r--release/scripts/startup/bl_operators/sequencer.py15
-rw-r--r--release/scripts/startup/bl_operators/uvcalc_follow_active.py4
-rw-r--r--release/scripts/startup/bl_operators/uvcalc_lightmap.py81
-rw-r--r--release/scripts/startup/bl_operators/uvcalc_smart_project.py117
-rw-r--r--release/scripts/startup/bl_operators/vertexpaint_dirt.py37
-rw-r--r--release/scripts/startup/bl_operators/wm.py570
-rw-r--r--release/scripts/startup/bl_ui/__init__.py6
-rw-r--r--release/scripts/startup/bl_ui/properties_animviz.py1
-rw-r--r--release/scripts/startup/bl_ui/properties_data_armature.py62
-rw-r--r--release/scripts/startup/bl_ui/properties_data_bone.py17
-rw-r--r--release/scripts/startup/bl_ui/properties_data_camera.py11
-rw-r--r--release/scripts/startup/bl_ui/properties_data_curve.py44
-rw-r--r--release/scripts/startup/bl_ui/properties_data_empty.py7
-rw-r--r--release/scripts/startup/bl_ui/properties_data_lamp.py23
-rw-r--r--release/scripts/startup/bl_ui/properties_data_lattice.py7
-rw-r--r--release/scripts/startup/bl_ui/properties_data_mesh.py29
-rw-r--r--release/scripts/startup/bl_ui/properties_data_metaball.py28
-rw-r--r--release/scripts/startup/bl_ui/properties_data_modifier.py14
-rw-r--r--release/scripts/startup/bl_ui/properties_data_speaker.py125
-rw-r--r--release/scripts/startup/bl_ui/properties_game.py45
-rw-r--r--release/scripts/startup/bl_ui/properties_material.py71
-rw-r--r--release/scripts/startup/bl_ui/properties_object.py26
-rw-r--r--release/scripts/startup/bl_ui/properties_object_constraint.py18
-rw-r--r--release/scripts/startup/bl_ui/properties_particle.py52
-rw-r--r--release/scripts/startup/bl_ui/properties_physics_cloth.py15
-rw-r--r--release/scripts/startup/bl_ui/properties_physics_common.py3
-rw-r--r--release/scripts/startup/bl_ui/properties_physics_field.py5
-rw-r--r--release/scripts/startup/bl_ui/properties_physics_fluid.py10
-rw-r--r--release/scripts/startup/bl_ui/properties_physics_smoke.py11
-rw-r--r--release/scripts/startup/bl_ui/properties_physics_softbody.py15
-rw-r--r--release/scripts/startup/bl_ui/properties_render.py51
-rw-r--r--release/scripts/startup/bl_ui/properties_scene.py45
-rw-r--r--release/scripts/startup/bl_ui/properties_texture.py75
-rw-r--r--release/scripts/startup/bl_ui/properties_world.py27
-rw-r--r--release/scripts/startup/bl_ui/space_console.py34
-rw-r--r--release/scripts/startup/bl_ui/space_dopesheet.py121
-rw-r--r--release/scripts/startup/bl_ui/space_filebrowser.py3
-rw-r--r--release/scripts/startup/bl_ui/space_graph.py38
-rw-r--r--release/scripts/startup/bl_ui/space_image.py122
-rw-r--r--release/scripts/startup/bl_ui/space_info.py48
-rw-r--r--release/scripts/startup/bl_ui/space_logic.py21
-rw-r--r--release/scripts/startup/bl_ui/space_nla.py39
-rw-r--r--release/scripts/startup/bl_ui/space_node.py42
-rw-r--r--release/scripts/startup/bl_ui/space_outliner.py38
-rw-r--r--release/scripts/startup/bl_ui/space_sequencer.py132
-rw-r--r--release/scripts/startup/bl_ui/space_text.py93
-rw-r--r--release/scripts/startup/bl_ui/space_time.py20
-rw-r--r--release/scripts/startup/bl_ui/space_userpref.py254
-rw-r--r--release/scripts/startup/bl_ui/space_userpref_keymap.py189
-rw-r--r--release/scripts/startup/bl_ui/space_view3d.py300
-rw-r--r--release/scripts/startup/bl_ui/space_view3d_toolbar.py97
-rw-r--r--release/scripts/startup/keyingsets_builtins.py35
-rw-r--r--release/scripts/templates/addon_add_object.py12
-rw-r--r--release/scripts/templates/batch_export.py33
-rw-r--r--release/scripts/templates/operator_export.py28
-rw-r--r--release/scripts/templates/operator_mesh_add.py41
-rw-r--r--release/scripts/templates/operator_modal.py4
-rw-r--r--release/scripts/templates/operator_modal_draw.py2
-rw-r--r--release/scripts/templates/operator_modal_timer.py2
-rw-r--r--release/scripts/templates/operator_modal_view3d.py7
-rw-r--r--release/scripts/templates/operator_simple.py2
-rw-r--r--release/scripts/templates/ui_menu.py49
-rw-r--r--release/scripts/templates/ui_menu_simple.py26
-rw-r--r--release/scripts/templates/ui_panel_simple.py (renamed from release/scripts/templates/panel_simple.py)7
-rw-r--r--release/text/GPL-license.txt2
-rw-r--r--release/text/readme.html12
104 files changed, 4111 insertions, 1992 deletions
diff --git a/release/datafiles/blenderbuttons b/release/datafiles/blenderbuttons
index 9872e53585e..4c064182a8c 100644
--- a/release/datafiles/blenderbuttons
+++ b/release/datafiles/blenderbuttons
Binary files differ
diff --git a/release/datafiles/splash.png b/release/datafiles/splash.png
index cad2bc5f06c..79339095b07 100644
--- a/release/datafiles/splash.png
+++ b/release/datafiles/splash.png
Binary files differ
diff --git a/release/scripts/modules/addon_utils.py b/release/scripts/modules/addon_utils.py
index 3877f711b7f..0c5ef69e805 100644
--- a/release/scripts/modules/addon_utils.py
+++ b/release/scripts/modules/addon_utils.py
@@ -16,7 +16,7 @@
#
# ##### END GPL LICENSE BLOCK #####
-# <pep8 compliant>
+# <pep8-80 compliant>
__all__ = (
"paths",
@@ -26,11 +26,15 @@ __all__ = (
"disable",
"reset_all",
"module_bl_info",
-)
+ )
import bpy as _bpy
+error_duplicates = False
+error_encoding = False
+
+
def paths():
# RELEASE SCRIPTS: official scripts distributed in Blender releases
paths = _bpy.utils.script_paths("addons")
@@ -47,14 +51,19 @@ def paths():
def modules(module_cache):
+ global error_duplicates
+ global error_encoding
import os
- import sys
- import time
+
+ error_duplicates = False
+ error_encoding = False
path_list = paths()
# fake module importing
def fake_module(mod_name, mod_path, speedy=True):
+ global error_encoding
+
if _bpy.app.debug:
print("fake_module", mod_path, mod_name)
import ast
@@ -65,12 +74,28 @@ def modules(module_cache):
line_iter = iter(file_mod)
l = ""
while not l.startswith("bl_info"):
- l = line_iter.readline()
+ try:
+ l = line_iter.readline()
+ except UnicodeDecodeError as e:
+ if not error_encoding:
+ error_encoding = True
+ print("Error reading file as UTF-8:", mod_path, e)
+ file_mod.close()
+ return None
+
if len(l) == 0:
break
while l.rstrip():
lines.append(l)
- l = line_iter.readline()
+ try:
+ l = line_iter.readline()
+ except UnicodeDecodeError as e:
+ if not error_encoding:
+ error_encoding = True
+ print("Error reading file as UTF-8:", mod_path, e)
+ file_mod.close()
+ return None
+
data = "".join(lines)
else:
@@ -119,8 +144,18 @@ def modules(module_cache):
modules_stale -= {mod_name}
mod = module_cache.get(mod_name)
if mod:
- if mod.__time__ != os.path.getmtime(mod_path):
- print("reloading addon:", mod_name, mod.__time__, os.path.getmtime(mod_path), mod_path)
+ if mod.__file__ != mod_path:
+ print("multiple addons with the same name:\n %r\n %r" %
+ (mod.__file__, mod_path))
+ error_duplicates = True
+
+ elif mod.__time__ != os.path.getmtime(mod_path):
+ print("reloading addon:",
+ mod_name,
+ mod.__time__,
+ os.path.getmtime(mod_path),
+ mod_path,
+ )
del module_cache[mod_name]
mod = None
@@ -135,7 +170,9 @@ def modules(module_cache):
del modules_stale
mod_list = list(module_cache.values())
- mod_list.sort(key=lambda mod: (mod.bl_info['category'], mod.bl_info['name']))
+ mod_list.sort(key=lambda mod: (mod.bl_info['category'],
+ mod.bl_info['name'],
+ ))
return mod_list
@@ -155,8 +192,9 @@ def check(module_name):
loaded_state = mod and getattr(mod, "__addon_enabled__", Ellipsis)
if loaded_state is Ellipsis:
- print("Warning: addon-module %r found module but without"
- " __addon_enabled__ field, possible name collision from file: %r" %
+ print("Warning: addon-module %r found module "
+ "but without __addon_enabled__ field, "
+ "possible name collision from file: %r" %
(module_name, getattr(mod, "__file__", "<unknown>")))
loaded_state = False
@@ -173,11 +211,9 @@ def enable(module_name, default_set=True):
:return: the loaded module or None on failier.
:rtype: module
"""
- # note, this still gets added to _bpy_types.TypeMap
import os
import sys
- import bpy_types as _bpy_types
import imp
def handle_error():
@@ -201,7 +237,8 @@ def enable(module_name, default_set=True):
return None
mod.__addon_enabled__ = False
- # Split registering up into 3 steps so we can undo if it fails par way through
+ # Split registering up into 3 steps so we can undo
+ # if it fails par way through.
# 1) try import
try:
mod = __import__(module_name)
@@ -246,12 +283,11 @@ def disable(module_name, default_set=True):
:type module_name: string
"""
import sys
- import bpy_types as _bpy_types
-
mod = sys.modules.get(module_name)
- # possible this addon is from a previous session and didnt load a module this time.
- # so even if the module is not found, still disable the addon in the user prefs.
+ # possible this addon is from a previous session and didnt load a
+ # module this time. So even if the module is not found, still disable
+ # the addon in the user prefs.
if mod:
mod.__addon_enabled__ = False
@@ -306,7 +342,22 @@ def reset_all(reload_scripts=False):
disable(mod_name)
-def module_bl_info(mod, info_basis={"name": "", "author": "", "version": (), "blender": (), "api": 0, "location": "", "description": "", "wiki_url": "", "tracker_url": "", "support": 'COMMUNITY', "category": "", "warning": "", "show_expanded": False}):
+def module_bl_info(mod, info_basis={"name": "",
+ "author": "",
+ "version": (),
+ "blender": (),
+ "api": 0,
+ "location": "",
+ "description": "",
+ "wiki_url": "",
+ "tracker_url": "",
+ "support": 'COMMUNITY',
+ "category": "",
+ "warning": "",
+ "show_expanded": False,
+ }
+ ):
+
addon_info = getattr(mod, "bl_info", {})
# avoid re-initializing
diff --git a/release/scripts/modules/bpy/__init__.py b/release/scripts/modules/bpy/__init__.py
index 1df8e9e5588..5c371fd750a 100644
--- a/release/scripts/modules/bpy/__init__.py
+++ b/release/scripts/modules/bpy/__init__.py
@@ -16,34 +16,45 @@
#
# ##### END GPL LICENSE BLOCK #####
-# <pep8 compliant>
+# <pep8-80 compliant>
"""
Give access to blender data and utility functions.
"""
-# internal blender C module
-import _bpy
-from _bpy import types, props, app
+__all__ = (
+ "app",
+ "context",
+ "data",
+ "ops",
+ "path",
+ "props",
+ "types",
+ "utils",
+ )
+
-data = _bpy.data
-context = _bpy.context
+# internal blender C module
+from _bpy import types, props, app, data, context
# python modules
-from . import utils, path
-from . import ops as _ops_module
+from . import utils, path, ops
# fake operator module
-ops = _ops_module.ops_fake_module
+ops = ops.ops_fake_module
-import sys as _sys
-
-def _main():
+def main():
+ import sys
# Possibly temp. addons path
from os.path import join, dirname, normpath
- _sys.path.append(normpath(join(dirname(__file__), "..", "..", "addons", "modules")))
+ sys.path.append(normpath(join(dirname(__file__),
+ "..", "..", "addons", "modules")))
+
+ # fake module to allow:
+ # from bpy.types import Panel
+ sys.modules["bpy.types"] = types
# if "-d" in sys.argv: # Enable this to measure startup speed
if 0:
@@ -58,4 +69,6 @@ def _main():
utils.load_scripts()
-_main()
+main()
+
+del main
diff --git a/release/scripts/modules/bpy/ops.py b/release/scripts/modules/bpy/ops.py
index f54b0a1fefc..64c5a1a5f5f 100644
--- a/release/scripts/modules/bpy/ops.py
+++ b/release/scripts/modules/bpy/ops.py
@@ -29,7 +29,7 @@ op_as_string = ops_module.as_string
op_get_rna = ops_module.get_rna
-class bpy_ops(object):
+class BPyOps(object):
'''
Fake module like class.
@@ -42,7 +42,7 @@ class bpy_ops(object):
'''
if module.startswith('__'):
raise AttributeError(module)
- return bpy_ops_submodule(module)
+ return BPyOpsSubMod(module)
def __dir__(self):
@@ -67,7 +67,7 @@ class bpy_ops(object):
return "<module like class 'bpy.ops'>"
-class bpy_ops_submodule(object):
+class BPyOpsSubMod(object):
'''
Utility class to fake submodules.
@@ -84,7 +84,7 @@ class bpy_ops_submodule(object):
'''
if func.startswith('__'):
raise AttributeError(func)
- return bpy_ops_submodule_op(self.module, func)
+ return BPyOpsSubModOp(self.module, func)
def __dir__(self):
@@ -103,7 +103,7 @@ class bpy_ops_submodule(object):
return "<module like class 'bpy.ops.%s'>" % self.module
-class bpy_ops_submodule_op(object):
+class BPyOpsSubModOp(object):
'''
Utility class to fake submodule operators.
@@ -151,7 +151,7 @@ class bpy_ops_submodule_op(object):
self.func = func
def poll(self, *args):
- C_dict, C_exec = __class__._parse_args(args)
+ C_dict, C_exec = BPyOpsSubModOp._parse_args(args)
return op_poll(self.idname_py(), C_dict, C_exec)
def idname(self):
@@ -170,16 +170,16 @@ class bpy_ops_submodule_op(object):
wm = context.window_manager
# run to account for any rna values the user changes.
- __class__._scene_update(context)
+ BPyOpsSubModOp._scene_update(context)
if args:
- C_dict, C_exec = __class__._parse_args(args)
+ C_dict, C_exec = BPyOpsSubModOp._parse_args(args)
ret = op_call(self.idname_py(), C_dict, kw, C_exec)
else:
ret = op_call(self.idname_py(), None, kw)
if 'FINISHED' in ret and context.window_manager == wm:
- __class__._scene_update(context)
+ BPyOpsSubModOp._scene_update(context)
return ret
@@ -208,4 +208,4 @@ class bpy_ops_submodule_op(object):
return "<function bpy.ops.%s.%s at 0x%x'>" % \
(self.module, self.func, id(self))
-ops_fake_module = bpy_ops()
+ops_fake_module = BPyOps()
diff --git a/release/scripts/modules/bpy/path.py b/release/scripts/modules/bpy/path.py
index 5e95428f641..284fef97795 100644
--- a/release/scripts/modules/bpy/path.py
+++ b/release/scripts/modules/bpy/path.py
@@ -16,26 +16,44 @@
#
# ##### END GPL LICENSE BLOCK #####
-# <pep8 compliant>
+# <pep8-80 compliant>
"""
This module has a similar scope to os.path, containing utility
functions for dealing with paths in Blender.
"""
+__all__ = (
+ "abspath",
+ "basename",
+ "clean_name",
+ "display_name",
+ "display_name_from_filepath",
+ "ensure_ext",
+ "is_subdir",
+ "module_names",
+ "relpath",
+ "resolve_ncase",
+ )
+
import bpy as _bpy
import os as _os
def abspath(path, start=None):
"""
- Returns the absolute path relative to the current blend file using the "//" prefix.
+ Returns the absolute path relative to the current blend file
+ using the "//" prefix.
- :arg start: Relative to this path, when not set the current filename is used.
+ :arg start: Relative to this path,
+ when not set the current filename is used.
:type start: string
"""
if path.startswith("//"):
- return _os.path.join(_os.path.dirname(_bpy.data.filepath if start is None else start), path[2:])
+ return _os.path.join(_os.path.dirname(_bpy.data.filepath)
+ if start is None else start,
+ path[2:],
+ )
return path
@@ -44,7 +62,8 @@ def relpath(path, start=None):
"""
Returns the path relative to the current blend file using the "//" prefix.
- :arg start: Relative to this path, when not set the current filename is used.
+ :arg start: Relative to this path,
+ when not set the current filename is used.
:type start: string
"""
if not path.startswith("//"):
@@ -68,27 +87,28 @@ def is_subdir(path, directory):
def clean_name(name, replace="_"):
"""
- Returns a name with characters replaced that may cause problems under various circumstances, such as writing to a file.
+ Returns a name with characters replaced that
+ may cause problems under various circumstances,
+ such as writing to a file.
All characters besides A-Z/a-z, 0-9 are replaced with "_"
or the replace argument if defined.
"""
- unclean_chars = \
- "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\
- \x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\
- \x1e\x1f\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\
- \x2e\x2f\x3a\x3b\x3c\x3d\x3e\x3f\x40\x5b\x5c\x5d\x5e\x60\x7b\
- \x7c\x7d\x7e\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\
- \x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\
- \x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\
- \xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\
- \xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\
- \xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\
- \xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\
- \xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\
- \xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe"
-
- for ch in unclean_chars:
+ bad_chars = ("\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e"
+ "\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d"
+ "\x1e\x1f\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c"
+ "\x2e\x2f\x3a\x3b\x3c\x3d\x3e\x3f\x40\x5b\x5c\x5d\x5e\x60\x7b"
+ "\x7c\x7d\x7e\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a"
+ "\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99"
+ "\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8"
+ "\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7"
+ "\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6"
+ "\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5"
+ "\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4"
+ "\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3"
+ "\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe")
+
+ for ch in bad_chars:
name = name.replace(ch, replace)
return name
@@ -96,8 +116,9 @@ def clean_name(name, replace="_"):
def display_name(name):
"""
Creates a display string from name to be used menus and the user interface.
- Capitalize the first letter in all lowercase names, mixed case names are kept as is.
- Intended for use with filenames and module names.
+ Capitalize the first letter in all lowercase names,
+ mixed case names are kept as is. Intended for use with
+ filenames and module names.
"""
name_base = _os.path.splitext(name)[0]
@@ -115,9 +136,11 @@ def display_name(name):
def display_name_from_filepath(name):
"""
- Returns the path stripped of directort and extension, ensured to be utf8 compatible.
+ Returns the path stripped of directory and extension,
+ ensured to be utf8 compatible.
"""
- return _os.path.splitext(_os.path.basename(name))[0].encode("utf8", "replace").decode("utf8")
+ name = _os.path.splitext(basename(name))[0]
+ return name.encode("utf8", "replace").decode("utf8")
def resolve_ncase(path):
@@ -132,7 +155,8 @@ def resolve_ncase(path):
if not path or os.path.exists(path):
return path, True
- filename = os.path.basename(path) # filename may be a directory or a file
+ # filename may be a directory or a file
+ filename = os.path.basename(path)
dirpath = os.path.dirname(path)
suffix = path[:0] # "" but ensure byte/str match
@@ -180,7 +204,7 @@ def resolve_ncase(path):
def ensure_ext(filepath, ext, case_sensitive=False):
"""
- Return the path with the extension added its its not alredy set.
+ Return the path with the extension added if it is not already set.
:arg ext: The extension to check for.
:type ext: string
@@ -190,7 +214,9 @@ def ensure_ext(filepath, ext, case_sensitive=False):
import os
fn_base, fn_ext = os.path.splitext(filepath)
if fn_base and fn_ext:
- if (case_sensitive and ext == fn_ext) or (ext.lower() == fn_ext.lower()):
+ if ((case_sensitive and ext == fn_ext) or
+ (ext.lower() == fn_ext.lower())):
+
return filepath
else:
return fn_base + ext
@@ -228,6 +254,17 @@ def module_names(path, recursive=False):
modules.append((filename, fullpath))
if recursive:
for mod_name, mod_path in module_names(directory, True):
- modules.append(("%s.%s" % (filename, mod_name), mod_path))
+ modules.append(("%s.%s" % (filename, mod_name),
+ mod_path,
+ ))
return modules
+
+
+def basename(path):
+ """
+ Equivalent to os.path.basename, but skips a "//" suffix.
+
+ Use for Windows compatibility.
+ """
+ return _os.path.basename(path[2:] if path[:2] in {"//", b"//"} else path)
diff --git a/release/scripts/modules/bpy/utils.py b/release/scripts/modules/bpy/utils.py
index 7c0d3d24cba..a6304378cc4 100644
--- a/release/scripts/modules/bpy/utils.py
+++ b/release/scripts/modules/bpy/utils.py
@@ -16,13 +16,33 @@
#
# ##### END GPL LICENSE BLOCK #####
-# <pep8 compliant>
+# <pep8-80 compliant>
"""
This module contains utility functions specific to blender but
not assosiated with blenders internal data.
"""
+__all__ = (
+ "blend_paths",
+ "keyconfig_set",
+ "load_scripts",
+ "modules_from_path",
+ "preset_find",
+ "preset_paths",
+ "refresh_script_paths",
+ "register_class",
+ "register_module",
+ "resource_path",
+ "script_paths",
+ "smpte_from_frame",
+ "smpte_from_seconds",
+ "unregister_class",
+ "unregister_module",
+ "user_resource",
+ "user_script_path",
+ )
+
from _bpy import register_class, unregister_class, blend_paths, resource_path
from _bpy import script_paths as _bpy_script_paths
from _bpy import user_resource as _user_resource
@@ -42,7 +62,8 @@ def _test_import(module_name, loaded_modules):
if module_name in loaded_modules:
return None
if "." in module_name:
- print("Ignoring '%s', can't import files containing multiple periods." % module_name)
+ print("Ignoring '%s', can't import files containing "
+ "multiple periods." % module_name)
return None
if use_time:
@@ -74,7 +95,8 @@ def modules_from_path(path, loaded_modules):
:arg path: this path is scanned for scripts and packages.
:type path: string
- :arg loaded_modules: already loaded module names, files matching these names will be ignored.
+ :arg loaded_modules: already loaded module names, files matching these
+ names will be ignored.
:type loaded_modules: set
:return: all loaded modules.
:rtype: list
@@ -97,13 +119,17 @@ def load_scripts(reload_scripts=False, refresh_scripts=False):
"""
Load scripts and run each modules register function.
- :arg reload_scripts: Causes all scripts to have their unregister method called before loading.
+ :arg reload_scripts: Causes all scripts to have their unregister method
+ called before loading.
:type reload_scripts: bool
- :arg refresh_scripts: only load scripts which are not already loaded as modules.
+ :arg refresh_scripts: only load scripts which are not already loaded
+ as modules.
:type refresh_scripts: bool
"""
use_time = _bpy.app.debug
+ prefs = _bpy.context.user_preferences
+
if use_time:
import time
t_main = time.time()
@@ -116,10 +142,11 @@ def load_scripts(reload_scripts=False, refresh_scripts=False):
if reload_scripts:
_bpy_types.TypeMap.clear()
- # just unload, dont change user defaults, this means we can sync to reload.
- # note that they will only actually reload of the modification time changes.
- # this `wont` work for packages so... its not perfect.
- for module_name in [ext.module for ext in _bpy.context.user_preferences.addons]:
+ # just unload, dont change user defaults, this means we can sync
+ # to reload. note that they will only actually reload of the
+ # modification time changes. This `wont` work for packages so...
+ # its not perfect.
+ for module_name in [ext.module for ext in prefs.addons]:
_addon_utils.disable(module_name, default_set=False)
def register_module_call(mod):
@@ -131,7 +158,9 @@ def load_scripts(reload_scripts=False, refresh_scripts=False):
import traceback
traceback.print_exc()
else:
- print("\nWarning! '%s' has no register function, this is now a requirement for registerable scripts." % mod.__file__)
+ print("\nWarning! '%s' has no register function, "
+ "this is now a requirement for registerable scripts." %
+ mod.__file__)
def unregister_module_call(mod):
unregister = getattr(mod, "unregister", None)
@@ -172,7 +201,8 @@ def load_scripts(reload_scripts=False, refresh_scripts=False):
if reload_scripts:
# module names -> modules
- _global_loaded_modules[:] = [_sys.modules[mod_name] for mod_name in _global_loaded_modules]
+ _global_loaded_modules[:] = [_sys.modules[mod_name]
+ for mod_name in _global_loaded_modules]
# loop over and unload all scripts
_global_loaded_modules.reverse()
@@ -201,7 +231,8 @@ def load_scripts(reload_scripts=False, refresh_scripts=False):
_addon_utils.reset_all(reload_scripts)
# run the active integration preset
- filepath = preset_find(_bpy.context.user_preferences.inputs.active_keyconfig, "keyconfig")
+ filepath = preset_find(prefs.inputs.active_keyconfig, "keyconfig")
+
if filepath:
keyconfig_set(filepath)
@@ -214,12 +245,16 @@ def load_scripts(reload_scripts=False, refresh_scripts=False):
# base scripts
-_scripts = _os.path.join(_os.path.dirname(__file__), _os.path.pardir, _os.path.pardir)
+_scripts = _os.path.join(_os.path.dirname(__file__),
+ _os.path.pardir,
+ _os.path.pardir,
+ )
_scripts = (_os.path.normpath(_scripts), )
def user_script_path():
- path = _bpy.context.user_preferences.filepaths.script_directory
+ prefs = _bpy.context.user_preferences
+ path = prefs.filepaths.script_directory
if path:
path = _os.path.normpath(path)
@@ -236,22 +271,25 @@ def script_paths(subdir=None, user_pref=True, all=False):
:type subdir: string
:arg user_pref: Include the user preference script path.
:type user_pref: bool
- :arg all: Include local, user and system paths rather just the paths blender uses.
+ :arg all: Include local, user and system paths rather just the paths
+ blender uses.
:type all: bool
:return: script paths.
:rtype: list
"""
scripts = list(_scripts)
+ prefs = _bpy.context.user_preferences
# add user scripts dir
if user_pref:
- user_script_path = _bpy.context.user_preferences.filepaths.script_directory
+ user_script_path = prefs.filepaths.script_directory
else:
user_script_path = None
if all:
# all possible paths
- base_paths = tuple(_os.path.join(resource_path(res), "scripts") for res in ('LOCAL', 'USER', 'SYSTEM'))
+ base_paths = tuple(_os.path.join(resource_path(res), "scripts")
+ for res in ('LOCAL', 'USER', 'SYSTEM'))
else:
# only paths blender uses
base_paths = _bpy_script_paths()
@@ -298,11 +336,18 @@ _presets = _os.path.join(_scripts[0], "presets") # FIXME - multiple paths
def preset_paths(subdir):
"""
Returns a list of paths for a specific preset.
+
+ :arg subdir: preset subdirectory (must not be an absolute path).
+ :type subdir: string
+ :return: script paths.
+ :rtype: list
"""
dirs = []
for path in script_paths("presets", all=True):
directory = _os.path.join(path, subdir)
- if _os.path.isdir(directory):
+ if not directory.startswith(path):
+ raise Exception("invalid subdir given %r" % subdir)
+ elif _os.path.isdir(directory):
dirs.append(directory)
return dirs
@@ -419,7 +464,8 @@ def user_resource(type, path="", create=False):
:type type: string
:arg subdir: Optional subdirectory.
:type subdir: string
- :arg create: Treat the path as a directory and create it if its not existing.
+ :arg create: Treat the path as a directory and create
+ it if its not existing.
:type create: boolean
:return: a path.
:rtype: string
@@ -470,7 +516,8 @@ def register_module(module, verbose=False):
try:
register_class(cls)
except:
- print("bpy.utils.register_module(): failed to registering class %r" % cls)
+ print("bpy.utils.register_module(): "
+ "failed to registering class %r" % cls)
import traceback
traceback.print_exc()
if verbose:
@@ -488,7 +535,8 @@ def unregister_module(module, verbose=False):
try:
unregister_class(cls)
except:
- print("bpy.utils.unregister_module(): failed to unregistering class %r" % cls)
+ print("bpy.utils.unregister_module(): "
+ "failed to unregistering class %r" % cls)
import traceback
traceback.print_exc()
if verbose:
diff --git a/release/scripts/modules/bpy_extras/__init__.py b/release/scripts/modules/bpy_extras/__init__.py
index 06d41fa670e..d853d5fda10 100644
--- a/release/scripts/modules/bpy_extras/__init__.py
+++ b/release/scripts/modules/bpy_extras/__init__.py
@@ -16,7 +16,7 @@
#
# ##### END GPL LICENSE BLOCK #####
-# <pep8 compliant>
+# <pep8-80 compliant>
"""
Utility modules assosiated with the bpy module.
@@ -28,4 +28,4 @@ __all__ = (
"image_utils",
"mesh_utils",
"view3d_utils",
-)
+ )
diff --git a/release/scripts/modules/bpy_extras/image_utils.py b/release/scripts/modules/bpy_extras/image_utils.py
index f45f9c6f225..02959fae534 100644
--- a/release/scripts/modules/bpy_extras/image_utils.py
+++ b/release/scripts/modules/bpy_extras/image_utils.py
@@ -16,11 +16,12 @@
#
# ##### END GPL LICENSE BLOCK #####
-# <pep8 compliant>
+# <pep8-80 compliant>
__all__ = (
"load_image",
-)
+ )
+
# limited replacement for BPyImage.comprehensiveImageLoad
def load_image(imagepath,
@@ -32,8 +33,8 @@ def load_image(imagepath,
verbose=False,
):
"""
- Return an image from the file path with options to search multiple paths and
- return a placeholder if its not found.
+ Return an image from the file path with options to search multiple paths
+ and return a placeholder if its not found.
:arg filepath: The image filename
If a path precedes it, this will be searched as well.
@@ -50,13 +51,14 @@ def load_image(imagepath,
:type recursive: bool
:arg ncase_cmp: on non windows systems, find the correct case for the file.
:type ncase_cmp: bool
- :arg convert_callback: a function that takes an existing path and returns a new one.
- Use this when loading image formats blender may not support, the CONVERT_CALLBACK
- can take the path for a GIF (for example), convert it to a PNG and return the PNG's path.
+ :arg convert_callback: a function that takes an existing path and returns
+ a new one. Use this when loading image formats blender may not support,
+ the CONVERT_CALLBACK can take the path for a GIF (for example),
+ convert it to a PNG and return the PNG's path.
For formats blender can read, simply return the path that is given.
:type convert_callback: function
:return: an image or None
- :rtype: :class:`Image`
+ :rtype: :class:`bpy.types.Image`
"""
import os
import bpy
@@ -85,11 +87,15 @@ def load_image(imagepath,
variants = [imagepath]
if dirname:
- variants += [os.path.join(dirname, imagepath), os.path.join(dirname, os.path.basename(imagepath))]
+ variants += [os.path.join(dirname, imagepath),
+ os.path.join(dirname, bpy.path.basename(imagepath)),
+ ]
for filepath_test in variants:
if ncase_cmp:
- ncase_variants = filepath_test, bpy.path.resolve_ncase(filepath_test)
+ ncase_variants = (filepath_test,
+ bpy.path.resolve_ncase(filepath_test),
+ )
else:
ncase_variants = (filepath_test, )
@@ -98,7 +104,7 @@ def load_image(imagepath,
return _image_load(nfilepath)
if place_holder:
- image = bpy.data.images.new(os.path.basename(filepath), 128, 128)
+ image = bpy.data.images.new(bpy.path.basename(imagepath), 128, 128)
# allow the path to be resolved later
image.filepath = imagepath
return image
diff --git a/release/scripts/modules/bpy_extras/io_utils.py b/release/scripts/modules/bpy_extras/io_utils.py
index 12c2d809132..3f6a3682e7c 100644
--- a/release/scripts/modules/bpy_extras/io_utils.py
+++ b/release/scripts/modules/bpy_extras/io_utils.py
@@ -16,12 +16,13 @@
#
# ##### END GPL LICENSE BLOCK #####
-# <pep8 compliant>
+# <pep8-80 compliant>
__all__ = (
"ExportHelper",
"ImportHelper",
"axis_conversion",
+ "axis_conversion_ensure",
"create_derived_objects",
"free_derived_objects",
"unpack_list",
@@ -30,15 +31,34 @@ __all__ = (
"path_reference_copy",
"path_reference_mode",
"unique_name"
-)
+ )
import bpy
from bpy.props import StringProperty, BoolProperty, EnumProperty
+def _check_axis_conversion(op):
+ if hasattr(op, "axis_forward") and hasattr(op, "axis_up"):
+ return axis_conversion_ensure(op,
+ "axis_forward",
+ "axis_up",
+ )
+ return False
+
+
class ExportHelper:
- filepath = StringProperty(name="File Path", description="Filepath used for exporting the file", maxlen=1024, default="", subtype='FILE_PATH')
- check_existing = BoolProperty(name="Check Existing", description="Check and warn on overwriting existing files", default=True, options={'HIDDEN'})
+ filepath = StringProperty(
+ name="File Path",
+ description="Filepath used for exporting the file",
+ maxlen=1024,
+ subtype='FILE_PATH',
+ )
+ check_existing = BoolProperty(
+ name="Check Existing",
+ description="Check and warn on overwriting existing files",
+ default=True,
+ options={'HIDDEN'},
+ )
# subclasses can override with decorator
# True == use ext, False == no ext, None == do nothing.
@@ -59,27 +79,39 @@ class ExportHelper:
return {'RUNNING_MODAL'}
def check(self, context):
- check_extension = self.check_extension
+ change_ext = False
+ change_axis = _check_axis_conversion(self)
- if check_extension is None:
- return False
+ check_extension = self.check_extension
- filepath = bpy.path.ensure_ext(self.filepath, self.filename_ext if check_extension else "")
+ if check_extension is not None:
+ filepath = bpy.path.ensure_ext(self.filepath,
+ self.filename_ext
+ if check_extension
+ else "")
- if filepath != self.filepath:
- self.filepath = filepath
- return True
+ if filepath != self.filepath:
+ self.filepath = filepath
+ change_ext = True
- return False
+ return (change_ext or change_axis)
class ImportHelper:
- filepath = StringProperty(name="File Path", description="Filepath used for importing the file", maxlen=1024, default="", subtype='FILE_PATH')
+ filepath = StringProperty(
+ name="File Path",
+ description="Filepath used for importing the file",
+ maxlen=1024,
+ subtype='FILE_PATH',
+ )
def invoke(self, context, event):
context.window_manager.fileselect_add(self)
return {'RUNNING_MODAL'}
+ def check(self, context):
+ return _check_axis_conversion(self)
+
# Axis conversion function, not pretty LUT
# use lookup tabes to convert between any axis
@@ -115,29 +147,75 @@ _axis_convert_matrix = (
# where all 4 values are or'd into a single value...
# (i1<<0 | i1<<3 | i1<<6 | i1<<9)
_axis_convert_lut = (
- {0x8C8, 0x4D0, 0x2E0, 0xAE8, 0x701, 0x511, 0x119, 0xB29, 0x682, 0x88A, 0x09A, 0x2A2, 0x80B, 0x413, 0x223, 0xA2B, 0x644, 0x454, 0x05C, 0xA6C, 0x745, 0x94D, 0x15D, 0x365},
- {0xAC8, 0x8D0, 0x4E0, 0x2E8, 0x741, 0x951, 0x159, 0x369, 0x702, 0xB0A, 0x11A, 0x522, 0xA0B, 0x813, 0x423, 0x22B, 0x684, 0x894, 0x09C, 0x2AC, 0x645, 0xA4D, 0x05D, 0x465},
- {0x4C8, 0x2D0, 0xAE0, 0x8E8, 0x681, 0x291, 0x099, 0x8A9, 0x642, 0x44A, 0x05A, 0xA62, 0x40B, 0x213, 0xA23, 0x82B, 0x744, 0x354, 0x15C, 0x96C, 0x705, 0x50D, 0x11D, 0xB25},
- {0x2C8, 0xAD0, 0x8E0, 0x4E8, 0x641, 0xA51, 0x059, 0x469, 0x742, 0x34A, 0x15A, 0x962, 0x20B, 0xA13, 0x823, 0x42B, 0x704, 0xB14, 0x11C, 0x52C, 0x685, 0x28D, 0x09D, 0x8A5},
- {0x708, 0xB10, 0x120, 0x528, 0x8C1, 0xAD1, 0x2D9, 0x4E9, 0x942, 0x74A, 0x35A, 0x162, 0x64B, 0xA53, 0x063, 0x46B, 0x804, 0xA14, 0x21C, 0x42C, 0x885, 0x68D, 0x29D, 0x0A5},
- {0xB08, 0x110, 0x520, 0x728, 0x941, 0x151, 0x359, 0x769, 0x802, 0xA0A, 0x21A, 0x422, 0xA4B, 0x053, 0x463, 0x66B, 0x884, 0x094, 0x29C, 0x6AC, 0x8C5, 0xACD, 0x2DD, 0x4E5},
- {0x508, 0x710, 0xB20, 0x128, 0x881, 0x691, 0x299, 0x0A9, 0x8C2, 0x4CA, 0x2DA, 0xAE2, 0x44B, 0x653, 0xA63, 0x06B, 0x944, 0x754, 0x35C, 0x16C, 0x805, 0x40D, 0x21D, 0xA25},
- {0x108, 0x510, 0x720, 0xB28, 0x801, 0x411, 0x219, 0xA29, 0x882, 0x08A, 0x29A, 0x6A2, 0x04B, 0x453, 0x663, 0xA6B, 0x8C4, 0x4D4, 0x2DC, 0xAEC, 0x945, 0x14D, 0x35D, 0x765},
- {0x748, 0x350, 0x160, 0x968, 0xAC1, 0x2D1, 0x4D9, 0x8E9, 0xA42, 0x64A, 0x45A, 0x062, 0x68B, 0x293, 0x0A3, 0x8AB, 0xA04, 0x214, 0x41C, 0x82C, 0xB05, 0x70D, 0x51D, 0x125},
- {0x948, 0x750, 0x360, 0x168, 0xB01, 0x711, 0x519, 0x129, 0xAC2, 0x8CA, 0x4DA, 0x2E2, 0x88B, 0x693, 0x2A3, 0x0AB, 0xA44, 0x654, 0x45C, 0x06C, 0xA05, 0x80D, 0x41D, 0x225},
- {0x348, 0x150, 0x960, 0x768, 0xA41, 0x051, 0x459, 0x669, 0xA02, 0x20A, 0x41A, 0x822, 0x28B, 0x093, 0x8A3, 0x6AB, 0xB04, 0x114, 0x51C, 0x72C, 0xAC5, 0x2CD, 0x4DD, 0x8E5},
- {0x148, 0x950, 0x760, 0x368, 0xA01, 0x811, 0x419, 0x229, 0xB02, 0x10A, 0x51A, 0x722, 0x08B, 0x893, 0x6A3, 0x2AB, 0xAC4, 0x8D4, 0x4DC, 0x2EC, 0xA45, 0x04D, 0x45D, 0x665},
- {0x688, 0x890, 0x0A0, 0x2A8, 0x4C1, 0x8D1, 0xAD9, 0x2E9, 0x502, 0x70A, 0xB1A, 0x122, 0x74B, 0x953, 0x163, 0x36B, 0x404, 0x814, 0xA1C, 0x22C, 0x445, 0x64D, 0xA5D, 0x065},
- {0x888, 0x090, 0x2A0, 0x6A8, 0x501, 0x111, 0xB19, 0x729, 0x402, 0x80A, 0xA1A, 0x222, 0x94B, 0x153, 0x363, 0x76B, 0x444, 0x054, 0xA5C, 0x66C, 0x4C5, 0x8CD, 0xADD, 0x2E5},
- {0x288, 0x690, 0x8A0, 0x0A8, 0x441, 0x651, 0xA59, 0x069, 0x4C2, 0x2CA, 0xADA, 0x8E2, 0x34B, 0x753, 0x963, 0x16B, 0x504, 0x714, 0xB1C, 0x12C, 0x405, 0x20D, 0xA1D, 0x825},
- {0x088, 0x290, 0x6A0, 0x8A8, 0x401, 0x211, 0xA19, 0x829, 0x442, 0x04A, 0xA5A, 0x662, 0x14B, 0x353, 0x763, 0x96B, 0x4C4, 0x2D4, 0xADC, 0x8EC, 0x505, 0x10D, 0xB1D, 0x725},
- {0x648, 0x450, 0x060, 0xA68, 0x2C1, 0x4D1, 0x8D9, 0xAE9, 0x282, 0x68A, 0x89A, 0x0A2, 0x70B, 0x513, 0x123, 0xB2B, 0x204, 0x414, 0x81C, 0xA2C, 0x345, 0x74D, 0x95D, 0x165},
- {0xA48, 0x650, 0x460, 0x068, 0x341, 0x751, 0x959, 0x169, 0x2C2, 0xACA, 0x8DA, 0x4E2, 0xB0B, 0x713, 0x523, 0x12B, 0x284, 0x694, 0x89C, 0x0AC, 0x205, 0xA0D, 0x81D, 0x425},
- {0x448, 0x050, 0xA60, 0x668, 0x281, 0x091, 0x899, 0x6A9, 0x202, 0x40A, 0x81A, 0xA22, 0x50B, 0x113, 0xB23, 0x72B, 0x344, 0x154, 0x95C, 0x76C, 0x2C5, 0x4CD, 0x8DD, 0xAE5},
- {0x048, 0xA50, 0x660, 0x468, 0x201, 0xA11, 0x819, 0x429, 0x342, 0x14A, 0x95A, 0x762, 0x10B, 0xB13, 0x723, 0x52B, 0x2C4, 0xAD4, 0x8DC, 0x4EC, 0x285, 0x08D, 0x89D, 0x6A5},
- {0x808, 0xA10, 0x220, 0x428, 0x101, 0xB11, 0x719, 0x529, 0x142, 0x94A, 0x75A, 0x362, 0x8CB, 0xAD3, 0x2E3, 0x4EB, 0x044, 0xA54, 0x65C, 0x46C, 0x085, 0x88D, 0x69D, 0x2A5},
- {0xA08, 0x210, 0x420, 0x828, 0x141, 0x351, 0x759, 0x969, 0x042, 0xA4A, 0x65A, 0x462, 0xACB, 0x2D3, 0x4E3, 0x8EB, 0x084, 0x294, 0x69C, 0x8AC, 0x105, 0xB0D, 0x71D, 0x525},
- {0x408, 0x810, 0xA20, 0x228, 0x081, 0x891, 0x699, 0x2A9, 0x102, 0x50A, 0x71A, 0xB22, 0x4CB, 0x8D3, 0xAE3, 0x2EB, 0x144, 0x954, 0x75C, 0x36C, 0x045, 0x44D, 0x65D, 0xA65},
+ {0x8C8, 0x4D0, 0x2E0, 0xAE8, 0x701, 0x511, 0x119, 0xB29, 0x682, 0x88A,
+ 0x09A, 0x2A2, 0x80B, 0x413, 0x223, 0xA2B, 0x644, 0x454, 0x05C, 0xA6C,
+ 0x745, 0x94D, 0x15D, 0x365},
+ {0xAC8, 0x8D0, 0x4E0, 0x2E8, 0x741, 0x951, 0x159, 0x369, 0x702, 0xB0A,
+ 0x11A, 0x522, 0xA0B, 0x813, 0x423, 0x22B, 0x684, 0x894, 0x09C, 0x2AC,
+ 0x645, 0xA4D, 0x05D, 0x465},
+ {0x4C8, 0x2D0, 0xAE0, 0x8E8, 0x681, 0x291, 0x099, 0x8A9, 0x642, 0x44A,
+ 0x05A, 0xA62, 0x40B, 0x213, 0xA23, 0x82B, 0x744, 0x354, 0x15C, 0x96C,
+ 0x705, 0x50D, 0x11D, 0xB25},
+ {0x2C8, 0xAD0, 0x8E0, 0x4E8, 0x641, 0xA51, 0x059, 0x469, 0x742, 0x34A,
+ 0x15A, 0x962, 0x20B, 0xA13, 0x823, 0x42B, 0x704, 0xB14, 0x11C, 0x52C,
+ 0x685, 0x28D, 0x09D, 0x8A5},
+ {0x708, 0xB10, 0x120, 0x528, 0x8C1, 0xAD1, 0x2D9, 0x4E9, 0x942, 0x74A,
+ 0x35A, 0x162, 0x64B, 0xA53, 0x063, 0x46B, 0x804, 0xA14, 0x21C, 0x42C,
+ 0x885, 0x68D, 0x29D, 0x0A5},
+ {0xB08, 0x110, 0x520, 0x728, 0x941, 0x151, 0x359, 0x769, 0x802, 0xA0A,
+ 0x21A, 0x422, 0xA4B, 0x053, 0x463, 0x66B, 0x884, 0x094, 0x29C, 0x6AC,
+ 0x8C5, 0xACD, 0x2DD, 0x4E5},
+ {0x508, 0x710, 0xB20, 0x128, 0x881, 0x691, 0x299, 0x0A9, 0x8C2, 0x4CA,
+ 0x2DA, 0xAE2, 0x44B, 0x653, 0xA63, 0x06B, 0x944, 0x754, 0x35C, 0x16C,
+ 0x805, 0x40D, 0x21D, 0xA25},
+ {0x108, 0x510, 0x720, 0xB28, 0x801, 0x411, 0x219, 0xA29, 0x882, 0x08A,
+ 0x29A, 0x6A2, 0x04B, 0x453, 0x663, 0xA6B, 0x8C4, 0x4D4, 0x2DC, 0xAEC,
+ 0x945, 0x14D, 0x35D, 0x765},
+ {0x748, 0x350, 0x160, 0x968, 0xAC1, 0x2D1, 0x4D9, 0x8E9, 0xA42, 0x64A,
+ 0x45A, 0x062, 0x68B, 0x293, 0x0A3, 0x8AB, 0xA04, 0x214, 0x41C, 0x82C,
+ 0xB05, 0x70D, 0x51D, 0x125},
+ {0x948, 0x750, 0x360, 0x168, 0xB01, 0x711, 0x519, 0x129, 0xAC2, 0x8CA,
+ 0x4DA, 0x2E2, 0x88B, 0x693, 0x2A3, 0x0AB, 0xA44, 0x654, 0x45C, 0x06C,
+ 0xA05, 0x80D, 0x41D, 0x225},
+ {0x348, 0x150, 0x960, 0x768, 0xA41, 0x051, 0x459, 0x669, 0xA02, 0x20A,
+ 0x41A, 0x822, 0x28B, 0x093, 0x8A3, 0x6AB, 0xB04, 0x114, 0x51C, 0x72C,
+ 0xAC5, 0x2CD, 0x4DD, 0x8E5},
+ {0x148, 0x950, 0x760, 0x368, 0xA01, 0x811, 0x419, 0x229, 0xB02, 0x10A,
+ 0x51A, 0x722, 0x08B, 0x893, 0x6A3, 0x2AB, 0xAC4, 0x8D4, 0x4DC, 0x2EC,
+ 0xA45, 0x04D, 0x45D, 0x665},
+ {0x688, 0x890, 0x0A0, 0x2A8, 0x4C1, 0x8D1, 0xAD9, 0x2E9, 0x502, 0x70A,
+ 0xB1A, 0x122, 0x74B, 0x953, 0x163, 0x36B, 0x404, 0x814, 0xA1C, 0x22C,
+ 0x445, 0x64D, 0xA5D, 0x065},
+ {0x888, 0x090, 0x2A0, 0x6A8, 0x501, 0x111, 0xB19, 0x729, 0x402, 0x80A,
+ 0xA1A, 0x222, 0x94B, 0x153, 0x363, 0x76B, 0x444, 0x054, 0xA5C, 0x66C,
+ 0x4C5, 0x8CD, 0xADD, 0x2E5},
+ {0x288, 0x690, 0x8A0, 0x0A8, 0x441, 0x651, 0xA59, 0x069, 0x4C2, 0x2CA,
+ 0xADA, 0x8E2, 0x34B, 0x753, 0x963, 0x16B, 0x504, 0x714, 0xB1C, 0x12C,
+ 0x405, 0x20D, 0xA1D, 0x825},
+ {0x088, 0x290, 0x6A0, 0x8A8, 0x401, 0x211, 0xA19, 0x829, 0x442, 0x04A,
+ 0xA5A, 0x662, 0x14B, 0x353, 0x763, 0x96B, 0x4C4, 0x2D4, 0xADC, 0x8EC,
+ 0x505, 0x10D, 0xB1D, 0x725},
+ {0x648, 0x450, 0x060, 0xA68, 0x2C1, 0x4D1, 0x8D9, 0xAE9, 0x282, 0x68A,
+ 0x89A, 0x0A2, 0x70B, 0x513, 0x123, 0xB2B, 0x204, 0x414, 0x81C, 0xA2C,
+ 0x345, 0x74D, 0x95D, 0x165},
+ {0xA48, 0x650, 0x460, 0x068, 0x341, 0x751, 0x959, 0x169, 0x2C2, 0xACA,
+ 0x8DA, 0x4E2, 0xB0B, 0x713, 0x523, 0x12B, 0x284, 0x694, 0x89C, 0x0AC,
+ 0x205, 0xA0D, 0x81D, 0x425},
+ {0x448, 0x050, 0xA60, 0x668, 0x281, 0x091, 0x899, 0x6A9, 0x202, 0x40A,
+ 0x81A, 0xA22, 0x50B, 0x113, 0xB23, 0x72B, 0x344, 0x154, 0x95C, 0x76C,
+ 0x2C5, 0x4CD, 0x8DD, 0xAE5},
+ {0x048, 0xA50, 0x660, 0x468, 0x201, 0xA11, 0x819, 0x429, 0x342, 0x14A,
+ 0x95A, 0x762, 0x10B, 0xB13, 0x723, 0x52B, 0x2C4, 0xAD4, 0x8DC, 0x4EC,
+ 0x285, 0x08D, 0x89D, 0x6A5},
+ {0x808, 0xA10, 0x220, 0x428, 0x101, 0xB11, 0x719, 0x529, 0x142, 0x94A,
+ 0x75A, 0x362, 0x8CB, 0xAD3, 0x2E3, 0x4EB, 0x044, 0xA54, 0x65C, 0x46C,
+ 0x085, 0x88D, 0x69D, 0x2A5},
+ {0xA08, 0x210, 0x420, 0x828, 0x141, 0x351, 0x759, 0x969, 0x042, 0xA4A,
+ 0x65A, 0x462, 0xACB, 0x2D3, 0x4E3, 0x8EB, 0x084, 0x294, 0x69C, 0x8AC,
+ 0x105, 0xB0D, 0x71D, 0x525},
+ {0x408, 0x810, 0xA20, 0x228, 0x081, 0x891, 0x699, 0x2A9, 0x102, 0x50A,
+ 0x71A, 0xB22, 0x4CB, 0x8D3, 0xAE3, 0x2EB, 0x144, 0x954, 0x75C, 0x36C,
+ 0x045, 0x44D, 0x65D, 0xA65},
)
_axis_convert_num = {'X': 0, 'Y': 1, 'Z': 2, '-X': 3, '-Y': 4, '-Z': 5}
@@ -154,17 +232,61 @@ def axis_conversion(from_forward='Y', from_up='Z', to_forward='Y', to_up='Z'):
if from_forward == to_forward and from_up == to_up:
return Matrix().to_3x3()
- value = reduce(int.__or__, (_axis_convert_num[a] << (i * 3) for i, a in enumerate((from_forward, from_up, to_forward, to_up))))
+ if from_forward[-1] == from_up[-1] or to_forward[-1] == to_up[-1]:
+ raise Exception("invalid axis arguments passed, "
+ "can't use up/forward on the same axis.")
+
+ value = reduce(int.__or__, (_axis_convert_num[a] << (i * 3)
+ for i, a in enumerate((from_forward,
+ from_up,
+ to_forward,
+ to_up,
+ ))))
for i, axis_lut in enumerate(_axis_convert_lut):
if value in axis_lut:
return Matrix(_axis_convert_matrix[i])
- assert("internal error")
+ assert(0)
+
+
+def axis_conversion_ensure(operator, forward_attr, up_attr):
+ """
+ Function to ensure an operator has valid axis conversion settings, intended
+ to be used from :class:`bpy.types.Operator.check`.
+
+ :arg operator: the operator to access axis attributes from.
+ :type operator: :class:`bpy.types.Operator`
+ :arg forward_attr: attribute storing the forward axis
+ :type forward_attr: string
+ :arg up_attr: attribute storing the up axis
+ :type up_attr: string
+ :return: True if the value was modified.
+ :rtype: boolean
+ """
+ def validate(axis_forward, axis_up):
+ if axis_forward[-1] == axis_up[-1]:
+ axis_up = axis_up[0:-1] + 'XYZ'[('XYZ'.index(axis_up[-1]) + 1) % 3]
+
+ return axis_forward, axis_up
+
+ change = False
+
+ axis = getattr(operator, forward_attr), getattr(operator, up_attr)
+ axis_new = validate(*axis)
+
+ if axis != axis_new:
+ setattr(operator, forward_attr, axis_new[0])
+ setattr(operator, up_attr, axis_new[1])
+
+ return True
+ else:
+ return False
-# return a tuple (free, object list), free is True if memory should be freed later with free_derived_objects()
+# return a tuple (free, object list), free is True if memory should be freed
+# later with free_derived_objects()
def create_derived_objects(scene, ob):
- if ob.parent and ob.parent.dupli_type != 'NONE':
+ if ob.parent and ob.parent.dupli_type in {'VERTS', 'FACES'}:
return False, None
if ob.dupli_type != 'NONE':
@@ -210,31 +332,45 @@ path_reference_mode = EnumProperty(
description="Method used to reference paths",
items=(('AUTO', "Auto", "Use Relative paths with subdirectories only"),
('ABSOLUTE', "Absolute", "Always write absolute paths"),
- ('RELATIVE', "Relative", "Always write relative patsh (where possible)"),
- ('MATCH', "Match", "Match Absolute/Relative setting with input path"),
+ ('RELATIVE', "Relative", "Always write relative patsh "
+ "(where possible)"),
+ ('MATCH', "Match", "Match Absolute/Relative "
+ "setting with input path"),
('STRIP', "Strip Path", "Filename only"),
- ('COPY', "Copy", "copy the file to the destination path (or subdirectory)"),
+ ('COPY', "Copy", "copy the file to the destination path "
+ "(or subdirectory)"),
),
default='AUTO'
)
-def path_reference(filepath, base_src, base_dst, mode='AUTO', copy_subdir="", copy_set=None):
+def path_reference(filepath,
+ base_src,
+ base_dst,
+ mode='AUTO',
+ copy_subdir="",
+ copy_set=None,
+ ):
"""
Return a filepath relative to a destination directory, for use with
exporters.
- :arg filepath: the file path to return, supporting blenders relative '//' prefix.
+ :arg filepath: the file path to return,
+ supporting blenders relative '//' prefix.
:type filepath: string
- :arg base_src: the directory the *filepath* is relative too (normally the blend file).
+ :arg base_src: the directory the *filepath* is relative too
+ (normally the blend file).
:type base_src: string
- :arg base_dst: the directory the *filepath* will be referenced from (normally the export path).
+ :arg base_dst: the directory the *filepath* will be referenced from
+ (normally the export path).
:type base_dst: string
- :arg mode: the method used get the path in ['AUTO', 'ABSOLUTE', 'RELATIVE', 'MATCH', 'STRIP', 'COPY']
+ :arg mode: the method used get the path in
+ ['AUTO', 'ABSOLUTE', 'RELATIVE', 'MATCH', 'STRIP', 'COPY']
:type mode: string
:arg copy_subdir: the subdirectory of *base_dst* to use when mode='COPY'.
:type copy_subdir: string
- :arg copy_set: collect from/to pairs when mode='COPY', pass to *path_reference_copy* when exportign is done.
+ :arg copy_set: collect from/to pairs when mode='COPY',
+ pass to *path_reference_copy* when exportign is done.
:type copy_set: set
:return: the new filepath.
:rtype: string
@@ -243,12 +379,14 @@ def path_reference(filepath, base_src, base_dst, mode='AUTO', copy_subdir="", co
is_relative = filepath.startswith("//")
filepath_abs = os.path.normpath(bpy.path.abspath(filepath, base_src))
- if mode in ('ABSOLUTE', 'RELATIVE', 'STRIP'):
+ if mode in {'ABSOLUTE', 'RELATIVE', 'STRIP'}:
pass
elif mode == 'MATCH':
mode = 'RELATIVE' if is_relative else 'ABSOLUTE'
elif mode == 'AUTO':
- mode = 'RELATIVE' if bpy.path.is_subdir(filepath, base_dst) else 'ABSOLUTE'
+ mode = ('RELATIVE'
+ if bpy.path.is_subdir(filepath, base_dst)
+ else 'ABSOLUTE')
elif mode == 'COPY':
if copy_subdir:
subdir_abs = os.path.join(os.path.normpath(base_dst), copy_subdir)
@@ -262,7 +400,7 @@ def path_reference(filepath, base_src, base_dst, mode='AUTO', copy_subdir="", co
filepath_abs = filepath_cpy
mode = 'RELATIVE'
else:
- Excaption("invalid mode given %r" % mode)
+ raise Exception("invalid mode given %r" % mode)
if mode == 'ABSOLUTE':
return filepath_abs
@@ -301,7 +439,7 @@ def path_reference_copy(copy_set, report=print):
shutil.copy(file_src, file_dst)
-def unique_name(key, name, name_dict, name_max=-1, clean_func=None):
+def unique_name(key, name, name_dict, name_max=-1, clean_func=None, sep="."):
"""
Helper function for storing unique names which may have special characters
stripped and restricted to a maximum length.
@@ -318,22 +456,30 @@ def unique_name(key, name, name_dict, name_max=-1, clean_func=None):
:type name_dict: dict
:arg clean_func: Function to call on *name* before creating a unique value.
:type clean_func: function
+ :arg sep: Separator to use when between the name and a number when a
+ duplicate name is found.
+ :type sep: string
"""
name_new = name_dict.get(key)
if name_new is None:
count = 1
name_dict_values = name_dict.values()
- name_new = name_new_orig = name if clean_func is None else clean_func(name)
+ name_new = name_new_orig = (name if clean_func is None
+ else clean_func(name))
if name_max == -1:
while name_new in name_dict_values:
- name_new = "%s.%03d" % (name_new_orig, count)
+ name_new = "%s%s%03d" % (name_new_orig, sep, count)
count += 1
else:
name_new = name_new[:name_max]
while name_new in name_dict_values:
count_str = "%03d" % count
- name_new = "%.*s.%s" % (name_max - (len(count_str) + 1), name_new_orig, count_str)
+ name_new = "%.*s%s%s" % (name_max - (len(count_str) + 1),
+ name_new_orig,
+ sep,
+ count_str,
+ )
count += 1
name_dict[key] = name_new
diff --git a/release/scripts/modules/bpy_extras/mesh_utils.py b/release/scripts/modules/bpy_extras/mesh_utils.py
index b6d8a1fcf16..7bc6dae3cc6 100644
--- a/release/scripts/modules/bpy_extras/mesh_utils.py
+++ b/release/scripts/modules/bpy_extras/mesh_utils.py
@@ -16,7 +16,7 @@
#
# ##### END GPL LICENSE BLOCK #####
-# <pep8 compliant>
+# <pep8-80 compliant>
__all__ = (
"mesh_linked_faces",
@@ -25,7 +25,9 @@ __all__ = (
"edge_loops_from_faces",
"edge_loops_from_edges",
"ngon_tesselate",
-)
+ "face_random_points",
+ )
+
def mesh_linked_faces(mesh):
"""
@@ -33,7 +35,7 @@ def mesh_linked_faces(mesh):
other mesh elements within 1 mesh datablock.
:arg mesh: the mesh used to group with.
- :type mesh: :class:`Mesh`
+ :type mesh: :class:`bpy.types.Mesh`
:return: lists of lists containing faces.
:rtype: list
"""
@@ -66,7 +68,8 @@ def mesh_linked_faces(mesh):
if mapped_index != nxt_mapped_index:
ok = True
- # Assign mapping to this group so they all map to this group
+ # Assign mapping to this group so they
+ # all map to this group
for grp_f in face_groups[nxt_mapped_index]:
face_mapping[grp_f.index] = mapped_index
@@ -104,9 +107,9 @@ def edge_face_count(mesh):
:return: list face users for each item in mesh.edges.
:rtype: list
"""
- edge_face_count_dict = edge_face_count_dict(mesh)
+ edge_face_count = edge_face_count_dict(mesh)
get = dict.get
- return [get(edge_face_count_dict, ed.key, 0) for ed in mesh.edges]
+ return [get(edge_face_count, ed.key, 0) for ed in mesh.edges]
def edge_loops_from_faces(mesh, faces=None, seams=()):
@@ -122,9 +125,9 @@ def edge_loops_from_faces(mesh, faces=None, seams=()):
[[(0, 1), (4, 8), (3, 8)], ...]
:arg mesh: the mesh used to get edge loops from.
- :type mesh: :class:`Mesh`
+ :type mesh: :class:`bpy.types.Mesh`
:arg faces: optional face list to only use some of the meshes faces.
- :type faces: :class:`MeshFaces`, sequence or or NoneType
+ :type faces: :class:`bpy.types.MeshFaces`, sequence or or NoneType
:return: return a list of edge vertex index lists.
:rtype: list
"""
@@ -167,8 +170,8 @@ def edge_loops_from_faces(mesh, faces=None, seams=()):
# from knowing the last 2, look for th next.
ed_adj = edges[context_loop[-1]]
if len(ed_adj) != 2:
-
- if other_dir and flipped == False: # the original edge had 2 other edges
+ # the original edge had 2 other edges
+ if other_dir and flipped == False:
flipped = True # only flip the list once
context_loop.reverse()
ed_adj[:] = []
@@ -211,8 +214,6 @@ def edge_loops_from_edges(mesh, edges=None):
if not hasattr(edges, "pop"):
edges = edges[:]
- edge_dict = {ed.key: ed for ed in mesh.edges if ed.select}
-
while edges:
current_edge = edges.pop()
vert_end, vert_start = current_edge.vertices[:]
@@ -258,15 +259,18 @@ def edge_loops_from_edges(mesh, edges=None):
def ngon_tesselate(from_data, indices, fix_loops=True):
'''
- Takes a polyline of indices (fgon)
- and returns a list of face indicie lists.
- Designed to be used for importers that need indices for an fgon to create from existing verts.
+ Takes a polyline of indices (fgon) and returns a list of face
+ indicie lists. Designed to be used for importers that need indices for an
+ fgon to create from existing verts.
from_data: either a mesh, or a list/tuple of vectors.
- indices: a list of indices to use this list is the ordered closed polyline to fill, and can be a subset of the data given.
- fix_loops: If this is enabled polylines that use loops to make multiple polylines are delt with correctly.
+ indices: a list of indices to use this list is the ordered closed polyline
+ to fill, and can be a subset of the data given.
+ fix_loops: If this is enabled polylines that use loops to make multiple
+ polylines are delt with correctly.
'''
+ from mathutils.geometry import tesselate_polygon
from mathutils import Vector
vector_to_tuple = Vector.to_tuple
@@ -274,7 +278,8 @@ def ngon_tesselate(from_data, indices, fix_loops=True):
return []
def mlen(co):
- return abs(co[0]) + abs(co[1]) + abs(co[2]) # manhatten length of a vector, faster then length
+ # manhatten length of a vector, faster then length
+ return abs(co[0]) + abs(co[1]) + abs(co[2])
def vert_treplet(v, i):
return v, vector_to_tuple(v, 6), i, mlen(v)
@@ -285,31 +290,34 @@ def ngon_tesselate(from_data, indices, fix_loops=True):
else:
return v1[1], v2[1]
- if not PREF_FIX_LOOPS:
+ if not fix_loops:
'''
Normal single concave loop filling
'''
- if type(from_data) in (tuple, list):
+ if type(from_data) in {tuple, list}:
verts = [Vector(from_data[i]) for ii, i in enumerate(indices)]
else:
verts = [from_data.vertices[i].co for ii, i in enumerate(indices)]
- for i in range(len(verts) - 1, 0, -1): # same as reversed(xrange(1, len(verts))):
+ # same as reversed(range(1, len(verts))):
+ for i in range(len(verts) - 1, 0, -1):
if verts[i][1] == verts[i - 1][0]:
verts.pop(i - 1)
- fill = fill_polygon([verts])
+ fill = tesselate_polygon([verts])
else:
'''
- Seperate this loop into multiple loops be finding edges that are used twice
- This is used by lightwave LWO files a lot
+ Seperate this loop into multiple loops be finding edges that are
+ used twice. This is used by lightwave LWO files a lot
'''
- if type(from_data) in (tuple, list):
- verts = [vert_treplet(Vector(from_data[i]), ii) for ii, i in enumerate(indices)]
+ if type(from_data) in {tuple, list}:
+ verts = [vert_treplet(Vector(from_data[i]), ii)
+ for ii, i in enumerate(indices)]
else:
- verts = [vert_treplet(from_data.vertices[i].co, ii) for ii, i in enumerate(indices)]
+ verts = [vert_treplet(from_data.vertices[i].co, ii)
+ for ii, i in enumerate(indices)]
edges = [(i, i - 1) for i in range(len(verts))]
if edges:
@@ -418,7 +426,7 @@ def ngon_tesselate(from_data, indices, fix_loops=True):
# See if its flipped the wrong way.
flip = None
for fi in fill:
- if flip != None:
+ if flip is not None:
break
for i, vi in enumerate(fi):
if vi == 0 and fi[i - 1] == 1:
@@ -433,3 +441,70 @@ def ngon_tesselate(from_data, indices, fix_loops=True):
fill[i] = tuple([ii for ii in reversed(fi)])
return fill
+
+
+def face_random_points(num_points, faces):
+ """
+ Generates a list of random points over mesh faces.
+
+ :arg num_points: the number of random points to generate on each face.
+ :type int:
+ :arg faces: list of the faces to generate points on.
+ :type faces: :class:`bpy.types.MeshFaces`, sequence
+ :return: list of random points over all faces.
+ :rtype: list
+ """
+
+ from random import random
+ from mathutils.geometry import area_tri
+
+ # Split all quads into 2 tris, tris remain unchanged
+ tri_faces = []
+ for f in faces:
+ tris = []
+ verts = f.id_data.vertices
+ fv = f.vertices[:]
+ tris.append((verts[fv[0]].co,
+ verts[fv[1]].co,
+ verts[fv[2]].co,
+ ))
+ if len(fv) == 4:
+ tris.append((verts[fv[0]].co,
+ verts[fv[3]].co,
+ verts[fv[2]].co,
+ ))
+ tri_faces.append(tris)
+
+ # For each face, generate the required number of random points
+ sampled_points = [None] * (num_points * len(faces))
+ for i, tf in enumerate(tri_faces):
+ for k in range(num_points):
+ # If this is a quad, we need to weight its 2 tris by their area
+ if len(tf) != 1:
+ area1 = area_tri(*tf[0])
+ area2 = area_tri(*tf[1])
+ area_tot = area1 + area2
+
+ area1 = area1 / area_tot
+ area2 = area2 / area_tot
+
+ vecs = tf[0 if (random() < area1) else 1]
+ else:
+ vecs = tf[0]
+
+ u1 = random()
+ u2 = random()
+ u_tot = u1 + u2
+
+ if u_tot > 1:
+ u1 = 1.0 - u1
+ u2 = 1.0 - u2
+
+ side1 = vecs[1] - vecs[0]
+ side2 = vecs[2] - vecs[0]
+
+ p = vecs[0] + u1 * side1 + u2 * side2
+
+ sampled_points[num_points * i + k] = p
+
+ return sampled_points
diff --git a/release/scripts/modules/bpy_extras/object_utils.py b/release/scripts/modules/bpy_extras/object_utils.py
index 51a8d4b5e23..3081e6f172e 100644
--- a/release/scripts/modules/bpy_extras/object_utils.py
+++ b/release/scripts/modules/bpy_extras/object_utils.py
@@ -16,12 +16,12 @@
#
# ##### END GPL LICENSE BLOCK #####
-# <pep8 compliant>
+# <pep8-80 compliant>
__all__ = (
"add_object_align_init",
"object_data_add",
-)
+ )
import bpy
@@ -33,48 +33,55 @@ def add_object_align_init(context, operator):
Return a matrix using the operator settings and view context.
:arg context: The context to use.
- :type context: :class:`Context`
+ :type context: :class:`bpy.types.Context`
:arg operator: The operator, checked for location and rotation properties.
- :type operator: :class:`Operator`
+ :type operator: :class:`bpy.types.Operator`
:return: the matrix from the context and settings.
- :rtype: :class:`Matrix`
+ :rtype: :class:`mathutils.Matrix`
"""
+
+ from mathutils import Matrix, Vector, Euler
+ properties = operator.properties if operator is not None else None
+
space_data = context.space_data
if space_data.type != 'VIEW_3D':
space_data = None
# location
- if operator and operator.properties.is_property_set("location"):
- location = mathutils.Matrix.Translation(mathutils.Vector(operator.properties.location))
+ if operator and properties.is_property_set("location"):
+ location = Matrix.Translation(Vector(properties.location))
else:
if space_data: # local view cursor is detected below
- location = mathutils.Matrix.Translation(space_data.cursor_location)
+ location = Matrix.Translation(space_data.cursor_location)
else:
- location = mathutils.Matrix.Translation(context.scene.cursor_location)
+ location = Matrix.Translation(context.scene.cursor_location)
if operator:
- operator.properties.location = location.to_translation()
+ properties.location = location.to_translation()
# rotation
view_align = (context.user_preferences.edit.object_align == 'VIEW')
view_align_force = False
if operator:
- if operator.properties.is_property_set("view_align"):
+ if properties.is_property_set("view_align"):
view_align = view_align_force = operator.view_align
else:
- operator.properties.view_align = view_align
+ properties.view_align = view_align
- if operator and operator.properties.is_property_set("rotation") and not view_align_force:
- rotation = mathutils.Euler(operator.properties.rotation).to_matrix().to_4x4()
+ if operator and (properties.is_property_set("rotation") and
+ not view_align_force):
+
+ rotation = Euler(properties.rotation).to_matrix().to_4x4()
else:
if view_align and space_data:
- rotation = space_data.region_3d.view_matrix.to_3x3().inverted().to_4x4()
+ rotation = space_data.region_3d.view_matrix.to_3x3().inverted()
+ rotation.resize_4x4()
else:
rotation = mathutils.Matrix()
# set the operator properties
if operator:
- operator.properties.rotation = rotation.to_euler()
+ properties.rotation = rotation.to_euler()
return location * rotation
@@ -85,13 +92,13 @@ def object_data_add(context, obdata, operator=None):
location, rotation and layer.
:arg context: The context to use.
- :type context: :class:`Context`
+ :type context: :class:`bpy.types.Context`
:arg obdata: the data used for the new object.
:type obdata: valid object data type or None.
:arg operator: The operator, checked for location and rotation properties.
- :type operator: :class:`Operator`
+ :type operator: :class:`bpy.types.Operator`
:return: the newly created object in the scene.
- :rtype: :class:`ObjectBase`
+ :rtype: :class:`bpy.types.ObjectBase`
"""
scene = context.scene
@@ -114,14 +121,18 @@ def object_data_add(context, obdata, operator=None):
# XXX
# caused because entering editmodedoes not add a empty undo slot!
if context.user_preferences.edit.use_enter_edit_mode:
- if not (obj_act and obj_act.mode == 'EDIT' and obj_act.type == obj_new.type):
+ if not (obj_act and
+ obj_act.mode == 'EDIT' and
+ obj_act.type == obj_new.type):
+
_obdata = bpy.data.meshes.new(obdata.name)
obj_act = bpy.data.objects.new(_obdata.name, _obdata)
obj_act.matrix_world = obj_new.matrix_world
scene.objects.link(obj_act)
scene.objects.active = obj_act
bpy.ops.object.mode_set(mode='EDIT')
- bpy.ops.ed.undo_push(message="Enter Editmode") # need empty undo step
+ # need empty undo step
+ bpy.ops.ed.undo_push(message="Enter Editmode")
# XXX
if obj_act and obj_act.mode == 'EDIT' and obj_act.type == obj_new.type:
diff --git a/release/scripts/modules/bpy_extras/view3d_utils.py b/release/scripts/modules/bpy_extras/view3d_utils.py
index 45f537ebd2f..c18a74bbb09 100644
--- a/release/scripts/modules/bpy_extras/view3d_utils.py
+++ b/release/scripts/modules/bpy_extras/view3d_utils.py
@@ -16,14 +16,14 @@
#
# ##### END GPL LICENSE BLOCK #####
-# <pep8 compliant>
+# <pep8-80 compliant>
__all__ = (
"region_2d_to_vector_3d",
"region_2d_to_location_3d",
"location_3d_to_region_2d",
- "location_3d_to_region_2d",
-)
+ )
+
def region_2d_to_vector_3d(region, rv3d, coord):
"""
@@ -31,14 +31,14 @@ def region_2d_to_vector_3d(region, rv3d, coord):
coordinate.
:arg region: region of the 3D viewport, typically bpy.context.region.
- :type region: :class:`Region`
+ :type region: :class:`bpy.types.Region`
:arg rv3d: 3D region data, typically bpy.context.space_data.region_3d.
- :type rv3d: :class:`RegionView3D`
+ :type rv3d: :class:`bpy.types.RegionView3D`
:arg coord: 2d coordinates relative to the region:
(event.mouse_region_x, event.mouse_region_y) for example.
:type coord: 2d vector
:return: normalized 3d vector.
- :rtype: :class:`Vector`
+ :rtype: :class:`mathutils.Vector`
"""
from mathutils import Vector
@@ -48,13 +48,13 @@ def region_2d_to_vector_3d(region, rv3d, coord):
out = Vector(((2.0 * coord[0] / region.width) - 1.0,
(2.0 * coord[1] / region.height) - 1.0,
-0.5
- ))
+ ))
- w = (out[0] * persinv[0][3]) + \
- (out[1] * persinv[1][3]) + \
- (out[2] * persinv[2][3]) + persinv[3][3]
+ w = ((out[0] * persinv[0][3]) +
+ (out[1] * persinv[1][3]) +
+ (out[2] * persinv[2][3]) + persinv[3][3])
- return ((out * persinv) / w) - rv3d.view_matrix.inverted()[3].xyz
+ return ((persinv * out) / w) - rv3d.view_matrix.inverted()[3].xyz
else:
return rv3d.view_matrix.inverted()[2].xyz.normalized()
@@ -65,9 +65,9 @@ def region_2d_to_location_3d(region, rv3d, coord, depth_location):
*depth_location*.
:arg region: region of the 3D viewport, typically bpy.context.region.
- :type region: :class:`Region`
+ :type region: :class:`bpy.types.Region`
:arg rv3d: 3D region data, typically bpy.context.space_data.region_3d.
- :type rv3d: :class:`RegionView3D`
+ :type rv3d: :class:`bpy.types.RegionView3D`
:arg coord: 2d coordinates relative to the region;
(event.mouse_region_x, event.mouse_region_y) for example.
:type coord: 2d vector
@@ -75,7 +75,7 @@ def region_2d_to_location_3d(region, rv3d, coord, depth_location):
there is no defined depth with a 2d region input.
:type depth_location: 3d vector
:return: normalized 3d vector.
- :rtype: :class:`Vector`
+ :rtype: :class:`mathutils.Vector`
"""
from mathutils import Vector
from mathutils.geometry import intersect_point_line
@@ -90,15 +90,23 @@ def region_2d_to_location_3d(region, rv3d, coord, depth_location):
origin_start = rv3d.view_matrix.inverted()[3].to_3d()
origin_end = origin_start + coord_vec
view_vec = rv3d.view_matrix.inverted()[2]
- return intersect_line_plane(origin_start, origin_end, depth_location, view_vec, 1)
+ return intersect_line_plane(origin_start,
+ origin_end,
+ depth_location,
+ view_vec, 1,
+ )
else:
dx = (2.0 * coord[0] / region.width) - 1.0
dy = (2.0 * coord[1] / region.height) - 1.0
persinv = persmat.inverted()
viewinv = rv3d.view_matrix.inverted()
- origin_start = (persinv[0].xyz * dx) + (persinv[1].xyz * dy) + viewinv[3].xyz
+ origin_start = ((persinv[0].xyz * dx) +
+ (persinv[1].xyz * dy) + viewinv[3].xyz)
origin_end = origin_start + coord_vec
- return intersect_point_line(depth_location, origin_start, origin_end)[0]
+ return intersect_point_line(depth_location,
+ origin_start,
+ origin_end,
+ )[0]
def location_3d_to_region_2d(region, rv3d, coord):
@@ -106,15 +114,17 @@ def location_3d_to_region_2d(region, rv3d, coord):
Return the *region* relative 2d location of a 3d position.
:arg region: region of the 3D viewport, typically bpy.context.region.
- :type region: :class:`Region`
+ :type region: :class:`bpy.types.Region`
:arg rv3d: 3D region data, typically bpy.context.space_data.region_3d.
- :type rv3d: :class:`RegionView3D`
+ :type rv3d: :class:`bpy.types.RegionView3D`
:arg coord: 3d worldspace location.
:type coord: 3d vector
:return: 2d location
- :rtype: :class:`Vector`
+ :rtype: :class:`mathutils.Vector`
"""
- prj = Vector((coord[0], coord[1], coord[2], 1.0)) * rv3d.perspective_matrix
+ from mathutils import Vector
+
+ 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 3c1b454e72e..101416f4943 100644
--- a/release/scripts/modules/bpy_types.py
+++ b/release/scripts/modules/bpy_types.py
@@ -20,7 +20,6 @@
from _bpy import types as bpy_types
import _bpy
-from mathutils import Vector
StructRNA = bpy_types.Struct.__bases__[0]
StructMetaPropGroup = _bpy.StructMetaPropGroup
@@ -58,7 +57,7 @@ class Library(bpy_types.ID):
"curves", "grease_pencil", "groups", "images", \
"lamps", "lattices", "materials", "metaballs", \
"meshes", "node_groups", "objects", "scenes", \
- "sounds", "textures", "texts", "fonts", "worlds"
+ "sounds", "speakers", "textures", "texts", "fonts", "worlds"
return tuple(id_block for attr in attr_links for id_block in getattr(bpy.data, attr) if id_block.library == self)
@@ -144,19 +143,22 @@ class _GenericBone:
def x_axis(self):
""" Vector pointing down the x-axis of the bone.
"""
- return Vector((1.0, 0.0, 0.0)) * self.matrix.to_3x3()
+ from mathutils import Vector
+ return self.matrix.to_3x3() * Vector((1.0, 0.0, 0.0))
@property
def y_axis(self):
""" Vector pointing down the x-axis of the bone.
"""
- return Vector((0.0, 1.0, 0.0)) * self.matrix.to_3x3()
+ from mathutils import Vector
+ return self.matrix.to_3x3() * Vector((0.0, 1.0, 0.0))
@property
def z_axis(self):
""" Vector pointing down the x-axis of the bone.
"""
- return Vector((0.0, 0.0, 1.0)) * self.matrix.to_3x3()
+ from mathutils import Vector
+ return self.matrix.to_3x3() * Vector((0.0, 0.0, 1.0))
@property
def basename(self):
@@ -239,7 +241,7 @@ class _GenericBone:
chain.append(child)
else:
if len(children_basename):
- print("multiple basenames found, this is probably not what you want!", bone.name, children_basename)
+ print("multiple basenames found, this is probably not what you want!", self.name, children_basename)
break
@@ -285,16 +287,16 @@ class EditBone(StructRNA, _GenericBone, metaclass=StructMetaPropGroup):
Transform the the bones head, tail, roll and envalope (when the matrix has a scale component).
:arg matrix: 3x3 or 4x4 transformation matrix.
- :type matrix: :class:`Matrix`
+ :type matrix: :class:`mathutils.Matrix`
:arg scale: Scale the bone envalope by the matrix.
:type scale: bool
:arg roll: Correct the roll to point in the same relative direction to the head and tail.
:type roll: bool
"""
from mathutils import Vector
- z_vec = Vector((0.0, 0.0, 1.0)) * self.matrix.to_3x3()
- self.tail = self.tail * matrix
- self.head = self.head * matrix
+ 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
@@ -302,7 +304,7 @@ class EditBone(StructRNA, _GenericBone, metaclass=StructMetaPropGroup):
self.tail_radius *= scalar
if roll:
- self.align_roll(z_vec * matrix)
+ self.align_roll(matrix * z_vec)
def ord_ind(i1, i2):
@@ -409,6 +411,16 @@ class Text(bpy_types.ID):
TypeMap = {}
+class Sound(bpy_types.ID):
+ __slots__ = ()
+
+ @property
+ def factory(self):
+ """The aud.Factory object of the sound."""
+ import aud
+ return aud._sound_from_pointer(self.as_pointer())
+
+
class RNAMeta(type):
def __new__(cls, name, bases, classdict, **args):
result = type.__new__(cls, name, bases, classdict)
diff --git a/release/scripts/modules/bpyml.py b/release/scripts/modules/bpyml.py
index fdf5172a0b3..42d2bf94fba 100644
--- a/release/scripts/modules/bpyml.py
+++ b/release/scripts/modules/bpyml.py
@@ -120,7 +120,7 @@ def fromxml(data):
py_item = (xml_node.tagName, _fromxml_kwargs(xml_node), [])
#_fromxml_iter(py_item, xml_node.childNodes)
for xml_node_child in xml_node.childNodes:
- if xml_node_child.nodeType not in (xml_node_child.TEXT_NODE, xml_node_child.COMMENT_NODE):
+ if xml_node_child.nodeType not in {xml_node_child.TEXT_NODE, xml_node_child.COMMENT_NODE}:
py_item[CHILDREN].append(_fromxml(xml_node_child))
return py_item
diff --git a/release/scripts/modules/bpyml_ui.py b/release/scripts/modules/bpyml_ui.py
index 1e0522974d1..f4b6de23dbb 100644
--- a/release/scripts/modules/bpyml_ui.py
+++ b/release/scripts/modules/bpyml_ui.py
@@ -22,7 +22,6 @@
import bpy as _bpy
import bpyml
from bpyml import TAG, ARGS, CHILDREN
-from types import ModuleType
_uilayout_rna = _bpy.types.UILayout.bl_rna
@@ -41,13 +40,13 @@ def _parse_rna(prop, value):
elif prop.type == 'INT':
value = int(value)
elif prop.type == 'BOOLEAN':
- if value in (True, False):
+ if value in {True, False}:
pass
else:
- if value not in ("True", "False"):
+ if value not in {"True", "False"}:
raise Exception("invalid bool value: %s" % value)
value = bool(value == "True")
- elif prop.type in ('STRING', 'ENUM'):
+ elif prop.type in {'STRING', 'ENUM'}:
pass
elif prop.type == 'POINTER':
value = eval("_bpy." + value)
diff --git a/release/scripts/modules/console/complete_namespace.py b/release/scripts/modules/console/complete_namespace.py
index a31280ebff0..d787fed0967 100644
--- a/release/scripts/modules/console/complete_namespace.py
+++ b/release/scripts/modules/console/complete_namespace.py
@@ -37,6 +37,11 @@ def is_dict(obj):
return hasattr(obj, 'keys') and hasattr(getattr(obj, 'keys'), '__call__')
+def is_struct_seq(obj):
+ """Returns whether obj is a structured sequence subclass: sys.float_info"""
+ return isinstance(obj, tuple) and hasattr(obj, 'n_fields')
+
+
def complete_names(word, namespace):
"""Complete variable names or attributes
@@ -174,7 +179,7 @@ def complete(word, namespace, private=True):
if type(obj) in (bool, float, int, str):
return []
# an extra char '[', '(' or '.' will be added
- if hasattr(obj, '__getitem__'):
+ if hasattr(obj, '__getitem__') and not is_struct_seq(obj):
# list or dictionary
matches = complete_indices(word, namespace, obj)
elif hasattr(obj, '__call__'):
diff --git a/release/scripts/modules/console/intellisense.py b/release/scripts/modules/console/intellisense.py
index 9352d7c14e1..a177b305fda 100644
--- a/release/scripts/modules/console/intellisense.py
+++ b/release/scripts/modules/console/intellisense.py
@@ -53,7 +53,7 @@ RE_UNQUOTED_WORD = re.compile(
re.UNICODE)
-def complete(line, cursor, namespace, private=True):
+def complete(line, cursor, namespace, private):
"""Returns a list of possible completions:
* name completion
@@ -82,6 +82,9 @@ def complete(line, cursor, namespace, private=True):
if RE_MODULE.match(line):
from . import complete_import
matches = complete_import.complete(line)
+ if not private:
+ matches[:] = [m for m in matches if m[:1] != "_"]
+ matches.sort()
else:
from . import complete_namespace
matches = complete_namespace.complete(word, namespace, private)
@@ -120,15 +123,29 @@ def expand(line, cursor, namespace, private=True):
from . import complete_calltip
matches, word, scrollback = complete_calltip.complete(line,
cursor, namespace)
+ prefix = os.path.commonprefix(matches)[len(word):]
no_calltip = False
else:
matches, word = complete(line, cursor, namespace, private)
+ prefix = os.path.commonprefix(matches)[len(word):]
if len(matches) == 1:
scrollback = ''
else:
- scrollback = ' '.join([m.split('.')[-1] for m in matches])
+ # causes blender bug [#27495] since string keys may contain '.'
+ # scrollback = ' '.join([m.split('.')[-1] for m in matches])
+
+ # add white space to align with the cursor
+ white_space = " " + (" " * (cursor + len(prefix)))
+ word_prefix = word + prefix
+ scrollback = '\n'.join(
+ [white_space + m[len(word_prefix):]
+ if (word_prefix and m.startswith(word_prefix))
+ else
+ white_space + m.split('.')[-1]
+ for m in matches])
+
no_calltip = True
- prefix = os.path.commonprefix(matches)[len(word):]
+
if prefix:
line = line[:cursor] + prefix + line[cursor:]
cursor += len(prefix)
diff --git a/release/scripts/modules/console_python.py b/release/scripts/modules/console_python.py
index 3048fa1d597..425ea210104 100644
--- a/release/scripts/modules/console_python.py
+++ b/release/scripts/modules/console_python.py
@@ -80,7 +80,7 @@ def get_console(console_id):
if console_data:
console, stdout, stderr = console_data
- # XXX, bug in python 3.1.2 ? (worked in 3.1.1)
+ # XXX, bug in python 3.1.2, 3.2 ? (worked in 3.1.1)
# seems there is no way to clear StringIO objects for writing, have to make new ones each time.
import io
stdout = io.StringIO()
@@ -179,7 +179,7 @@ def execute(context):
# special exception. its possible the command loaded a new user interface
if hash(sc) != hash(context.space_data):
- return
+ return {'FINISHED'}
bpy.ops.console.scrollback_append(text=sc.prompt + line, type='INPUT')
diff --git a/release/scripts/modules/keyingsets_utils.py b/release/scripts/modules/keyingsets_utils.py
index dc61ce2a4af..03400edc904 100644
--- a/release/scripts/modules/keyingsets_utils.py
+++ b/release/scripts/modules/keyingsets_utils.py
@@ -16,14 +16,14 @@
#
# ##### END GPL LICENSE BLOCK #####
-# <pep8 compliant>
+# <pep8-80 compliant>
# This file defines a set of methods that are useful for various
# Relative Keying Set (RKS) related operations, such as: callbacks
# for polling, iterator callbacks, and also generate callbacks.
# All of these can be used in conjunction with the others.
-__all__ = [
+__all__ = (
"path_add_property",
"RKS_POLL_selected_objects",
"RKS_POLL_selected_bones",
@@ -33,7 +33,7 @@ __all__ = [
"RKS_GEN_location",
"RKS_GEN_rotation",
"RKS_GEN_scaling",
-]
+ )
import bpy
@@ -75,7 +75,8 @@ def RKS_POLL_selected_bones(ksi, context):
# selected bones or objects
def RKS_POLL_selected_items(ksi, context):
- return RKS_POLL_selected_bones(ksi, context) or RKS_POLL_selected_objects(ksi, context)
+ return (RKS_POLL_selected_bones(ksi, context) or
+ RKS_POLL_selected_objects(ksi, context))
###########################
# Iterator Callbacks
diff --git a/release/scripts/modules/rna_info.py b/release/scripts/modules/rna_info.py
index 93a344f4b09..943f86adecb 100644
--- a/release/scripts/modules/rna_info.py
+++ b/release/scripts/modules/rna_info.py
@@ -148,7 +148,7 @@ class InfoStructRNA:
import types
functions = []
for identifier, attr in self._get_py_visible_attrs():
- if type(attr) in (types.FunctionType, types.MethodType):
+ if type(attr) in {types.FunctionType, types.MethodType}:
functions.append((identifier, attr))
return functions
@@ -156,7 +156,7 @@ class InfoStructRNA:
import types
functions = []
for identifier, attr in self._get_py_visible_attrs():
- if type(attr) in (types.BuiltinMethodType, types.BuiltinFunctionType):
+ if type(attr) in {types.BuiltinMethodType, types.BuiltinFunctionType}:
functions.append((identifier, attr))
return functions
@@ -260,7 +260,7 @@ class InfoPropertyRNA:
if self.array_length:
type_str += " array of %d items" % (self.array_length)
- if self.type in ("float", "int"):
+ if self.type in {"float", "int"}:
type_str += " in [%s, %s]" % (range_str(self.min), range_str(self.max))
elif self.type == "enum":
if self.is_enum_flag:
@@ -595,7 +595,7 @@ def BuildRNAInfo():
for prop in rna_info.properties:
# ERROR CHECK
default = prop.default
- if type(default) in (float, int):
+ if type(default) in {float, int}:
if default < prop.min or default > prop.max:
print("\t %s.%s, %s not in [%s - %s]" % (rna_info.identifier, prop.identifier, default, prop.min, prop.max))
diff --git a/release/scripts/modules/rna_prop_ui.py b/release/scripts/modules/rna_prop_ui.py
index 9311987e2e7..388ae2b0e13 100644
--- a/release/scripts/modules/rna_prop_ui.py
+++ b/release/scripts/modules/rna_prop_ui.py
@@ -111,12 +111,16 @@ def draw(layout, context, context_member, property_type, use_edit=True):
continue
row = layout.row()
- convert_to_pyobject = getattr(val, "convert_to_pyobject", None)
-
- val_orig = val
- if convert_to_pyobject:
- val_draw = val = val.convert_to_pyobject()
- val_draw = str(val_draw)
+ to_dict = getattr(val, "to_dict", None)
+ to_list = getattr(val, "to_list", None)
+
+ # val_orig = val # UNUSED
+ if to_dict:
+ val = to_dict()
+ val_draw = str(val)
+ elif to_list:
+ val = to_list()
+ val_draw = str(val)
else:
val_draw = val
@@ -131,7 +135,7 @@ def draw(layout, context, context_member, property_type, use_edit=True):
row.label(text=key)
# explicit exception for arrays
- if convert_to_pyobject and not hasattr(val_orig, "len"):
+ if to_dict or to_list:
row.label(text=val_draw)
else:
if key in rna_properties:
diff --git a/release/scripts/presets/ffmpeg/DV.py b/release/scripts/presets/ffmpeg/DV.py
index 46d2a0a4a2f..926fb241747 100644
--- a/release/scripts/presets/ffmpeg/DV.py
+++ b/release/scripts/presets/ffmpeg/DV.py
@@ -11,3 +11,4 @@ else:
bpy.context.scene.render.ffmpeg_audio_mixrate = 48000
bpy.context.scene.render.ffmpeg_audio_codec = "PCM"
+bpy.context.scene.render.ffmpeg_audio_channels = 2
diff --git a/release/scripts/presets/ffmpeg/DVD.py b/release/scripts/presets/ffmpeg/DVD.py
index e18ec9f817b..196b5d68406 100644
--- a/release/scripts/presets/ffmpeg/DVD.py
+++ b/release/scripts/presets/ffmpeg/DVD.py
@@ -21,3 +21,4 @@ bpy.context.scene.render.ffmpeg_muxrate = 10080000
bpy.context.scene.render.ffmpeg_audio_codec = "AC3"
bpy.context.scene.render.ffmpeg_audio_bitrate = 448
bpy.context.scene.render.ffmpeg_audio_mixrate = 48000
+bpy.context.scene.render.ffmpeg_audio_channels = 6
diff --git a/release/scripts/presets/ffmpeg/SVCD.py b/release/scripts/presets/ffmpeg/SVCD.py
index c71a3851af0..e4459ab5c5c 100644
--- a/release/scripts/presets/ffmpeg/SVCD.py
+++ b/release/scripts/presets/ffmpeg/SVCD.py
@@ -21,3 +21,4 @@ bpy.context.scene.render.ffmpeg_muxrate = 0
bpy.context.scene.render.ffmpeg_audio_bitrate = 224
bpy.context.scene.render.ffmpeg_audio_mixrate = 44100
bpy.context.scene.render.ffmpeg_audio_codec = "MP2"
+bpy.context.scene.render.ffmpeg_audio_channels = 2
diff --git a/release/scripts/presets/ffmpeg/VCD.py b/release/scripts/presets/ffmpeg/VCD.py
index faf27efe9e6..c2b73e682a2 100644
--- a/release/scripts/presets/ffmpeg/VCD.py
+++ b/release/scripts/presets/ffmpeg/VCD.py
@@ -21,3 +21,4 @@ bpy.context.scene.render.ffmpeg_muxrate = 2352 * 75 * 8
bpy.context.scene.render.ffmpeg_audio_bitrate = 224
bpy.context.scene.render.ffmpeg_audio_mixrate = 44100
bpy.context.scene.render.ffmpeg_audio_codec = "MP2"
+bpy.context.scene.render.ffmpeg_audio_channels = 2
diff --git a/release/scripts/presets/ffmpeg/xvid.py b/release/scripts/presets/ffmpeg/xvid.py
index fa64562e566..c006ba267cc 100644
--- a/release/scripts/presets/ffmpeg/xvid.py
+++ b/release/scripts/presets/ffmpeg/xvid.py
@@ -1,8 +1,7 @@
import bpy
is_ntsc = (bpy.context.scene.render.fps != 25)
-bpy.context.scene.render.ffmpeg_format = "AVI"
-bpy.context.scene.render.ffmpeg_codec = "XVID"
+bpy.context.scene.render.ffmpeg_format = "XVID"
if is_ntsc:
bpy.context.scene.render.ffmpeg_gopsize = 18
diff --git a/release/scripts/startup/bl_operators/add_mesh_torus.py b/release/scripts/startup/bl_operators/add_mesh_torus.py
index 6ab803cc469..056b3478c2b 100644
--- a/release/scripts/startup/bl_operators/add_mesh_torus.py
+++ b/release/scripts/startup/bl_operators/add_mesh_torus.py
@@ -16,8 +16,9 @@
#
# ##### END GPL LICENSE BLOCK #####
-# <pep8 compliant>
+# <pep8-80 compliant>
import bpy
+from bpy.types import Operator
import mathutils
@@ -40,8 +41,10 @@ def add_torus(major_rad, minor_rad, major_seg, minor_seg):
for minor_index in range(minor_seg):
angle = 2 * pi * minor_index / minor_seg
- vec = Vector((major_rad + (cos(angle) * minor_rad), 0.0,
- (sin(angle) * minor_rad))) * quat
+ vec = quat * Vector((major_rad + (cos(angle) * minor_rad),
+ 0.0,
+ (sin(angle) * minor_rad),
+ ))
verts.extend(vec[:])
@@ -72,44 +75,75 @@ def add_torus(major_rad, minor_rad, major_seg, minor_seg):
return verts, faces
-from bpy.props import FloatProperty, IntProperty, BoolProperty, FloatVectorProperty
+from bpy.props import (FloatProperty,
+ IntProperty,
+ BoolProperty,
+ FloatVectorProperty,
+ )
-class AddTorus(bpy.types.Operator):
+class AddTorus(Operator):
'''Add a torus mesh'''
bl_idname = "mesh.primitive_torus_add"
bl_label = "Add Torus"
bl_options = {'REGISTER', 'UNDO'}
- major_radius = FloatProperty(name="Major Radius",
- description="Radius from the origin to the center of the cross sections",
- default=1.0, min=0.01, max=100.0)
- minor_radius = FloatProperty(name="Minor Radius",
+ major_radius = FloatProperty(
+ name="Major Radius",
+ description=("Radius from the origin to the "
+ "center of the cross sections"),
+ min=0.01, max=100.0,
+ default=1.0,
+ )
+ minor_radius = FloatProperty(
+ name="Minor Radius",
description="Radius of the torus' cross section",
- default=0.25, min=0.01, max=100.0)
- major_segments = IntProperty(name="Major Segments",
+ min=0.01, max=100.0,
+ default=0.25,
+ )
+ major_segments = IntProperty(
+ name="Major Segments",
description="Number of segments for the main ring of the torus",
- default=48, min=3, max=256)
- minor_segments = IntProperty(name="Minor Segments",
+ min=3, max=256,
+ default=48,
+ )
+ minor_segments = IntProperty(
+ name="Minor Segments",
description="Number of segments for the minor ring of the torus",
- default=12, min=3, max=256)
- use_abso = BoolProperty(name="Use Int+Ext Controls",
+ min=3, max=256,
+ default=12,
+ )
+ use_abso = BoolProperty(
+ name="Use Int+Ext Controls",
description="Use the Int / Ext controls for torus dimensions",
- default=False)
- abso_major_rad = FloatProperty(name="Exterior Radius",
+ default=False,
+ )
+ abso_major_rad = FloatProperty(
+ name="Exterior Radius",
description="Total Exterior Radius of the torus",
- default=1.0, min=0.01, max=100.0)
- abso_minor_rad = FloatProperty(name="Inside Radius",
+ min=0.01, max=100.0,
+ default=1.0,
+ )
+ abso_minor_rad = FloatProperty(
+ name="Inside Radius",
description="Total Interior Radius of the torus",
- default=0.5, min=0.01, max=100.0)
+ min=0.01, max=100.0,
+ default=0.5,
+ )
# generic transform props
- view_align = BoolProperty(name="Align to View",
- default=False)
- location = FloatVectorProperty(name="Location",
- subtype='TRANSLATION')
- rotation = FloatVectorProperty(name="Rotation",
- subtype='EULER')
+ view_align = BoolProperty(
+ name="Align to View",
+ default=False,
+ )
+ location = FloatVectorProperty(
+ name="Location",
+ subtype='TRANSLATION',
+ )
+ rotation = FloatVectorProperty(
+ name="Rotation",
+ subtype='EULER',
+ )
def execute(self, context):
diff --git a/release/scripts/startup/bl_operators/animsys_update.py b/release/scripts/startup/bl_operators/animsys_update.py
index 63d438a5066..3710c57ac16 100644
--- a/release/scripts/startup/bl_operators/animsys_update.py
+++ b/release/scripts/startup/bl_operators/animsys_update.py
@@ -686,9 +686,10 @@ data_path_update = [
import bpy
+from bpy.types import Operator
-class UpdateAnimData(bpy.types.Operator):
+class UpdateAnimData(Operator):
"""Update data paths from 2.56 and previous versions, modifying data paths of drivers and fcurves"""
bl_idname = "anim.update_data_paths"
bl_label = "Update Animation Data"
diff --git a/release/scripts/startup/bl_operators/image.py b/release/scripts/startup/bl_operators/image.py
index 462db3a2c5e..9226cbed51b 100644
--- a/release/scripts/startup/bl_operators/image.py
+++ b/release/scripts/startup/bl_operators/image.py
@@ -16,19 +16,24 @@
#
# ##### END GPL LICENSE BLOCK #####
-# <pep8 compliant>
+# <pep8-80 compliant>
import bpy
+from bpy.types import Operator
from bpy.props import StringProperty
-class EditExternally(bpy.types.Operator):
+class EditExternally(Operator):
'''Edit image in an external application'''
bl_idname = "image.external_edit"
bl_label = "Image Edit Externally"
bl_options = {'REGISTER'}
- filepath = StringProperty(name="File Path", description="Path to an image file", maxlen=1024, default="")
+ filepath = StringProperty(
+ name="File Path",
+ description="Path to an image file",
+ maxlen=1024,
+ )
def _editor_guess(self, context):
import sys
@@ -57,10 +62,19 @@ class EditExternally(bpy.types.Operator):
def execute(self, context):
import os
import subprocess
- filepath = bpy.path.abspath(self.filepath)
+
+ filepath = self.filepath
+
+ if not filepath:
+ self.report({'ERROR'}, "Image path not set")
+ return {'CANCELLED'}
+
+ filepath = os.path.normpath(bpy.path.abspath(filepath))
if not os.path.exists(filepath):
- self.report({'ERROR'}, "Image path %r not found." % filepath)
+ self.report({'ERROR'},
+ "Image path %r not found, image may be packed or "
+ "unsaved." % filepath)
return {'CANCELLED'}
cmd = self._editor_guess(context) + [filepath]
@@ -70,7 +84,10 @@ class EditExternally(bpy.types.Operator):
except:
import traceback
traceback.print_exc()
- self.report({'ERROR'}, "Image editor not found, please specify in User Preferences > File")
+ self.report({'ERROR'},
+ "Image editor not found, "
+ "please specify in User Preferences > File")
+
return {'CANCELLED'}
return {'FINISHED'}
@@ -90,7 +107,7 @@ class EditExternally(bpy.types.Operator):
return {'FINISHED'}
-class SaveDirty(bpy.types.Operator):
+class SaveDirty(Operator):
"""Save all modified textures"""
bl_idname = "image.save_dirty"
bl_label = "Save Dirty"
@@ -104,14 +121,16 @@ class SaveDirty(bpy.types.Operator):
if "\\" not in filepath and "/" not in filepath:
self.report({'WARNING'}, "Invalid path: " + filepath)
elif filepath in unique_paths:
- self.report({'WARNING'}, "Path used by more then one image: " + filepath)
+ self.report({'WARNING'},
+ "Path used by more then one image: %r" %
+ filepath)
else:
unique_paths.add(filepath)
image.save()
return {'FINISHED'}
-class ProjectEdit(bpy.types.Operator):
+class ProjectEdit(Operator):
"""Edit a snapshot of the viewport in an external image editor"""
bl_idname = "image.project_edit"
bl_label = "Project Edit"
@@ -121,7 +140,6 @@ class ProjectEdit(bpy.types.Operator):
def execute(self, context):
import os
- import subprocess
EXT = "png" # could be made an option but for now ok
@@ -143,14 +161,14 @@ class ProjectEdit(bpy.types.Operator):
filepath = os.path.basename(bpy.data.filepath)
filepath = os.path.splitext(filepath)[0]
- # filepath = bpy.path.clean_name(filepath) # fixes <memory> rubbish, needs checking
+ # fixes <memory> rubbish, needs checking
+ # filepath = bpy.path.clean_name(filepath)
- if filepath.startswith(".") or filepath == "":
- # TODO, have a way to check if the file is saved, assume startup.blend
+ if bpy.data.is_saved:
+ filepath = "//" + filepath
+ else:
tmpdir = context.user_preferences.filepaths.temporary_directory
filepath = os.path.join(tmpdir, "project_edit")
- else:
- filepath = "//" + filepath
obj = context.object
@@ -164,7 +182,7 @@ class ProjectEdit(bpy.types.Operator):
filepath_final = filepath + ("%.3d.%s" % (i, EXT))
i += 1
- image_new.name = os.path.basename(filepath_final)
+ image_new.name = bpy.path.basename(filepath_final)
ProjectEdit._proj_hack[0] = image_new.name
image_new.filepath_raw = filepath_final # TODO, filepath raw is crummy
@@ -179,7 +197,7 @@ class ProjectEdit(bpy.types.Operator):
return {'FINISHED'}
-class ProjectApply(bpy.types.Operator):
+class ProjectApply(Operator):
"""Project edited image back onto the object"""
bl_idname = "image.project_apply"
bl_label = "Project Apply"
diff --git a/release/scripts/startup/bl_operators/mesh.py b/release/scripts/startup/bl_operators/mesh.py
index 89802d7ba5c..5f6583754e9 100644
--- a/release/scripts/startup/bl_operators/mesh.py
+++ b/release/scripts/startup/bl_operators/mesh.py
@@ -16,14 +16,15 @@
#
# ##### END GPL LICENSE BLOCK #####
-# <pep8 compliant>
+# <pep8-80 compliant>
import bpy
+from bpy.types import Operator
from bpy.props import EnumProperty
-class MeshSelectInteriorFaces(bpy.types.Operator):
+class MeshSelectInteriorFaces(Operator):
'''Select faces where all edges have more then 2 face users.'''
bl_idname = "mesh.faces_select_interior"
@@ -67,28 +68,26 @@ class MeshSelectInteriorFaces(bpy.types.Operator):
return {'FINISHED'}
-class MeshMirrorUV(bpy.types.Operator):
+class MeshMirrorUV(Operator):
'''Copy mirror UV coordinates on the X axis based on a mirrored mesh'''
bl_idname = "mesh.faces_mirror_uv"
bl_label = "Copy Mirrored UV coords"
bl_options = {'REGISTER', 'UNDO'}
- direction = EnumProperty(items=(
- ('POSITIVE', "Positive", ""),
- ('NEGATIVE', "Negative", "")),
- name="Axis Direction",
- description="")
+ direction = EnumProperty(
+ name="Axis Direction",
+ items=(('POSITIVE', "Positive", ""),
+ ('NEGATIVE', "Negative", "")),
+ )
@classmethod
def poll(cls, context):
- ob = context.active_object
- return (ob and ob.type == 'MESH')
+ obj = context.active_object
+ return (obj and obj.type == 'MESH' and obj.data.uv_textures.active)
def execute(self, context):
DIR = (self.direction == 'NEGATIVE')
- from mathutils import Vector
-
ob = context.active_object
is_editmode = (ob.mode == 'EDIT')
if is_editmode:
@@ -113,21 +112,18 @@ class MeshMirrorUV(bpy.types.Operator):
#for i, v in enumerate(mesh.vertices):
vmap = {}
- for mirror_a, mirror_b in (mirror_gt, mirror_lt), (mirror_lt, mirror_gt):
+ for mirror_a, mirror_b in ((mirror_gt, mirror_lt),
+ (mirror_lt, mirror_gt)):
for co, i in mirror_a.items():
nco = (-co[0], co[1], co[2])
j = mirror_b.get(nco)
if j is not None:
vmap[i] = j
- active_uv_layer = None
- for lay in mesh.uv_textures:
- if lay.active:
- active_uv_layer = lay.data
- break
-
+ active_uv_layer = mesh.uv_textures.active.data
fuvs = [(uv.uv1, uv.uv2, uv.uv3, uv.uv4) for uv in active_uv_layer]
- fuvs_cpy = [(uv[0].copy(), uv[1].copy(), uv[2].copy(), uv[3].copy()) for uv in fuvs]
+ fuvs_cpy = [(uv[0].copy(), uv[1].copy(), uv[2].copy(), uv[3].copy())
+ for uv in fuvs]
# as a list
faces = mesh.faces[:]
@@ -152,7 +148,6 @@ class MeshMirrorUV(bpy.types.Operator):
if j is not None:
fmap[i] = j
- done = [False] * len(faces)
for i, j in fmap.items():
if not fuvsel[i] or not fuvsel[j]:
@@ -170,10 +165,10 @@ class MeshMirrorUV(bpy.types.Operator):
v1 = faces[j].vertices[:]
v2 = [vmap[k] for k in faces[i].vertices[:]]
- for k in range(len(uv1)):
- k_map = v1.index(v2[k])
- uv1[k].x = - (uv2[k_map].x - 0.5) + 0.5
- uv1[k].y = uv2[k_map].y
+ if len(v1) == len(v2):
+ for k in range(len(v1)):
+ k_map = v1.index(v2[k])
+ uv1[k].xy = - (uv2[k_map].x - 0.5) + 0.5, uv2[k_map].y
if is_editmode:
bpy.ops.object.mode_set(mode='EDIT', toggle=False)
diff --git a/release/scripts/startup/bl_operators/nla.py b/release/scripts/startup/bl_operators/nla.py
index 923ca92a162..c764f7d62f1 100644
--- a/release/scripts/startup/bl_operators/nla.py
+++ b/release/scripts/startup/bl_operators/nla.py
@@ -16,17 +16,17 @@
#
# ##### END GPL LICENSE BLOCK #####
-# <pep8 compliant>
+# <pep8-80 compliant>
import bpy
+from bpy.types import Operator
-def pose_info():
+def pose_frame_info(obj):
from mathutils import Matrix
info = {}
- obj = bpy.context.object
pose = obj.pose
pose_items = pose.bones.items()
@@ -51,7 +51,6 @@ def pose_info():
except:
binfo["matrix_pose_inv"] = Matrix()
- print(binfo["matrix_pose"])
info[name] = binfo
for name, pbone in pose_items:
@@ -67,45 +66,87 @@ def pose_info():
matrix = binfo_parent["matrix_pose_inv"] * matrix
rest_matrix = binfo_parent["matrix_local_inv"] * rest_matrix
- matrix = rest_matrix.inverted() * matrix
+ binfo["matrix_key"] = rest_matrix.inverted() * matrix
+
+ return info
- binfo["matrix_key"] = matrix.copy()
+def obj_frame_info(obj):
+ info = {}
+ # parent = obj.parent
+ info["matrix_key"] = obj.matrix_local.copy()
return info
-def bake(frame_start, frame_end, step=1, only_selected=False):
+def bake(frame_start,
+ frame_end, step=1,
+ only_selected=False,
+ do_pose=True,
+ do_object=True,
+ do_constraint_clear=False,
+ action=None):
+
scene = bpy.context.scene
obj = bpy.context.object
pose = obj.pose
+ frame_back = scene.frame_current
- info_ls = []
+ if pose is None:
+ do_pose = False
+
+ if do_pose is None and do_object is None:
+ return None
+
+ pose_info = []
+ obj_info = []
frame_range = range(frame_start, frame_end + 1, step)
- # could spped this up by applying steps here too...
+ # -------------------------------------------------------------------------
+ # Collect transformations
+
+ # could speed this up by applying steps here too...
for f in frame_range:
scene.frame_set(f)
- info = pose_info()
- info_ls.append(info)
+ if do_pose:
+ pose_info.append(pose_frame_info(obj))
+ if do_object:
+ obj_info.append(obj_frame_info(obj))
+
f += 1
- action = bpy.data.actions.new("Action")
+ # -------------------------------------------------------------------------
+ # Create action
- bpy.context.object.animation_data.action = action
+ # incase animation data hassnt been created
+ atd = obj.animation_data_create()
+ if action is None:
+ action = bpy.data.actions.new("Action")
+ atd.action = action
- pose_items = pose.bones.items()
+ if do_pose:
+ pose_items = pose.bones.items()
+ else:
+ pose_items = [] # skip
- for name, pbone in pose_items:
+ # -------------------------------------------------------------------------
+ # Apply transformations to action
+
+ # pose
+ for name, pbone in (pose_items if do_pose else ()):
if only_selected and not pbone.bone.select:
continue
+ if do_constraint_clear:
+ while pbone.constraints:
+ pbone.constraints.remove(pbone.constraints[0])
+
for f in frame_range:
- matrix = info_ls[int((f - frame_start) / step)][name]["matrix_key"]
+ matrix = pose_info[(f - frame_start) // step][name]["matrix_key"]
- #pbone.location = matrix.to_translation()
- #pbone.rotation_quaternion = matrix.to_quaternion()
+ # pbone.location = matrix.to_translation()
+ # pbone.rotation_quaternion = matrix.to_quaternion()
pbone.matrix_basis = matrix
pbone.keyframe_insert("location", -1, f, name)
@@ -121,33 +162,92 @@ def bake(frame_start, frame_end, step=1, only_selected=False):
pbone.keyframe_insert("scale", -1, f, name)
+ # object. TODO. multiple objects
+ if do_object:
+ if do_constraint_clear:
+ while obj.constraints:
+ obj.constraints.remove(obj.constraints[0])
+
+ for f in frame_range:
+ matrix = obj_info[(f - frame_start) // step]["matrix_key"]
+ obj.matrix_local = matrix
+
+ obj.keyframe_insert("location", -1, f)
+
+ rotation_mode = obj.rotation_mode
+
+ if rotation_mode == 'QUATERNION':
+ obj.keyframe_insert("rotation_quaternion", -1, f)
+ elif rotation_mode == 'AXIS_ANGLE':
+ obj.keyframe_insert("rotation_axis_angle", -1, f)
+ else: # euler, XYZ, ZXY etc
+ obj.keyframe_insert("rotation_euler", -1, f)
+
+ obj.keyframe_insert("scale", -1, f)
+
+ scene.frame_set(frame_back)
+
return action
-from bpy.props import IntProperty, BoolProperty
+from bpy.props import IntProperty, BoolProperty, EnumProperty
-class BakeAction(bpy.types.Operator):
+class BakeAction(Operator):
'''Bake animation to an Action'''
bl_idname = "nla.bake"
bl_label = "Bake Action"
bl_options = {'REGISTER', 'UNDO'}
- frame_start = IntProperty(name="Start Frame",
+ frame_start = IntProperty(
+ name="Start Frame",
description="Start frame for baking",
- default=1, min=1, max=300000)
- frame_end = IntProperty(name="End Frame",
+ min=0, max=300000,
+ default=1,
+ )
+ frame_end = IntProperty(
+ name="End Frame",
description="End frame for baking",
- default=250, min=1, max=300000)
- step = IntProperty(name="Frame Step",
+ min=1, max=300000,
+ default=250,
+ )
+ step = IntProperty(
+ name="Frame Step",
description="Frame Step",
- default=1, min=1, max=120)
- only_selected = BoolProperty(name="Only Selected",
- default=True)
+ min=1, max=120,
+ default=1,
+ )
+ only_selected = BoolProperty(
+ name="Only Selected",
+ default=True,
+ )
+ clear_consraints = BoolProperty(
+ name="Clear Constraints",
+ default=False,
+ )
+ bake_types = EnumProperty(
+ name="Bake Data",
+ options={'ENUM_FLAG'},
+ items=(('POSE', "Pose", ""),
+ ('OBJECT', "Object", ""),
+ ),
+ default={'POSE'},
+ )
def execute(self, context):
- action = bake(self.frame_start, self.frame_end, self.step, self.only_selected)
+ action = bake(self.frame_start,
+ self.frame_end,
+ self.step,
+ self.only_selected,
+ 'POSE' in self.bake_types,
+ 'OBJECT' in self.bake_types,
+ self.clear_consraints,
+ )
+
+ if action is None:
+ self.report({'INFO'}, "Nothing to bake")
+ return {'CANCELLED'}
# basic cleanup, could move elsewhere
for fcu in action.fcurves:
@@ -168,3 +268,36 @@ class BakeAction(bpy.types.Operator):
def invoke(self, context, event):
wm = context.window_manager
return wm.invoke_props_dialog(self)
+
+
+class ClearUselessActions(Operator):
+ '''Mark actions with no F-Curves for deletion after save+reload of file preserving "action libraries"'''
+ bl_idname = "anim.clear_useless_actions"
+ bl_label = "Clear Useless Actions"
+ bl_options = {'REGISTER', 'UNDO'}
+
+ only_unused = BoolProperty(name="Only Unused",
+ description="Only unused (Fake User only) actions get considered",
+ default=True)
+
+ @classmethod
+ def poll(cls, context):
+ return len(bpy.data.actions) != 0
+
+ def execute(self, context):
+ removed = 0
+
+ for action in bpy.data.actions:
+ # if only user is "fake" user...
+ if ((self.only_unused is False) or
+ (action.use_fake_user and action.users == 1)):
+
+ # if it has F-Curves, then it's a "action library" (i.e. walk, wave, jump, etc.)
+ # and should be left alone as that's what fake users are for!
+ if not action.fcurves:
+ # mark action for deletion
+ action.user_clear()
+ removed += 1
+
+ self.report({'INFO'}, "Removed %d empty and/or fake-user only Actions" % (removed))
+ return {'FINISHED'}
diff --git a/release/scripts/startup/bl_operators/object.py b/release/scripts/startup/bl_operators/object.py
index 0342a14a1b2..6c9f27afaa5 100644
--- a/release/scripts/startup/bl_operators/object.py
+++ b/release/scripts/startup/bl_operators/object.py
@@ -16,21 +16,35 @@
#
# ##### END GPL LICENSE BLOCK #####
-# <pep8 compliant>
+# <pep8-80 compliant>
import bpy
+from bpy.types import Operator
from bpy.props import StringProperty, BoolProperty, EnumProperty, IntProperty
-class SelectPattern(bpy.types.Operator):
+class SelectPattern(Operator):
'''Select object matching a naming pattern'''
bl_idname = "object.select_pattern"
bl_label = "Select Pattern"
bl_options = {'REGISTER', 'UNDO'}
- pattern = StringProperty(name="Pattern", description="Name filter using '*' and '?' wildcard chars", maxlen=32, default="*")
- case_sensitive = BoolProperty(name="Case Sensitive", description="Do a case sensitive compare", default=False)
- extend = BoolProperty(name="Extend", description="Extend the existing selection", default=True)
+ pattern = StringProperty(
+ name="Pattern",
+ description="Name filter using '*' and '?' wildcard chars",
+ maxlen=32,
+ default="*",
+ )
+ case_sensitive = BoolProperty(
+ name="Case Sensitive",
+ description="Do a case sensitive compare",
+ default=False,
+ )
+ extend = BoolProperty(
+ name="Extend",
+ description="Extend the existing selection",
+ default=True,
+ )
def execute(self, context):
@@ -39,22 +53,37 @@ class SelectPattern(bpy.types.Operator):
if self.case_sensitive:
pattern_match = fnmatch.fnmatchcase
else:
- pattern_match = lambda a, b: fnmatch.fnmatchcase(a.upper(), b.upper())
-
+ pattern_match = (lambda a, b:
+ fnmatch.fnmatchcase(a.upper(), b.upper()))
+ is_ebone = False
obj = context.object
if obj and obj.mode == 'POSE':
items = obj.data.bones
+ if not self.extend:
+ bpy.ops.pose.select_all(action='DESELECT')
elif obj and obj.type == 'ARMATURE' and obj.mode == 'EDIT':
items = obj.data.edit_bones
+ if not self.extend:
+ bpy.ops.armature.select_all(action='DESELECT')
+ is_ebone = True
else:
items = context.visible_objects
+ if not self.extend:
+ bpy.ops.object.select_all(action='DESELECT')
# Can be pose bones or objects
for item in items:
if pattern_match(item.name, self.pattern):
item.select = True
- elif not self.extend:
- item.select = False
+
+ # hrmf, perhaps there should be a utility function for this.
+ if is_ebone:
+ item.select_head = True
+ item.select_tail = True
+ if item.use_connect:
+ item_parent = item.parent
+ if item_parent is not None:
+ item_parent.select_tail = True
return {'FINISHED'}
@@ -71,7 +100,7 @@ class SelectPattern(bpy.types.Operator):
row.prop(self, "extend")
-class SelectCamera(bpy.types.Operator):
+class SelectCamera(Operator):
'''Select object matching a naming pattern'''
bl_idname = "object.select_camera"
bl_label = "Select Camera"
@@ -92,20 +121,26 @@ class SelectCamera(bpy.types.Operator):
return {'FINISHED'}
-class SelectHierarchy(bpy.types.Operator):
- '''Select object relative to the active objects position in the hierarchy'''
+class SelectHierarchy(Operator):
+ '''Select object relative to the active objects position''' \
+ '''in the hierarchy'''
bl_idname = "object.select_hierarchy"
bl_label = "Select Hierarchy"
bl_options = {'REGISTER', 'UNDO'}
- direction = EnumProperty(items=(
- ('PARENT', "Parent", ""),
- ('CHILD', "Child", "")),
- name="Direction",
- description="Direction to select in the hierarchy",
- default='PARENT')
+ direction = EnumProperty(
+ items=(('PARENT', "Parent", ""),
+ ('CHILD', "Child", ""),
+ ),
+ name="Direction",
+ description="Direction to select in the hierarchy",
+ default='PARENT')
- extend = BoolProperty(name="Extend", description="Extend the existing selection", default=False)
+ extend = BoolProperty(
+ name="Extend",
+ description="Extend the existing selection",
+ default=False,
+ )
@classmethod
def poll(cls, context):
@@ -153,17 +188,26 @@ class SelectHierarchy(bpy.types.Operator):
return {'CANCELLED'}
-class SubdivisionSet(bpy.types.Operator):
+class SubdivisionSet(Operator):
'''Sets a Subdivision Surface Level (1-5)'''
bl_idname = "object.subdivision_set"
bl_label = "Subdivision Set"
bl_options = {'REGISTER', 'UNDO'}
- level = IntProperty(name="Level",
- default=1, min=-100, max=100, soft_min=-6, soft_max=6)
+ level = IntProperty(
+ name="Level",
+ min=-100, max=100,
+ soft_min=-6, soft_max=6,
+ default=1,
+ )
- relative = BoolProperty(name="Relative", description="Apply the subsurf level as an offset relative to the current level", default=False)
+ relative = BoolProperty(
+ name="Relative",
+ description=("Apply the subsurf level as an offset "
+ "relative to the current level"),
+ default=False,
+ )
@classmethod
def poll(cls, context):
@@ -215,7 +259,8 @@ class SubdivisionSet(bpy.types.Operator):
mod = obj.modifiers.new("Subsurf", 'SUBSURF')
mod.levels = level
except:
- self.report({'WARNING'}, "Modifiers cannot be added to object: " + obj.name)
+ self.report({'WARNING'},
+ "Modifiers cannot be added to object: " + obj.name)
for obj in context.selected_editable_objects:
set_object_subd(obj)
@@ -223,24 +268,38 @@ class SubdivisionSet(bpy.types.Operator):
return {'FINISHED'}
-class ShapeTransfer(bpy.types.Operator):
- '''Copy another selected objects active shape to this one by applying the relative offsets'''
+class ShapeTransfer(Operator):
+ '''Copy another selected objects active shape to this one by ''' \
+ '''applying the relative offsets'''
bl_idname = "object.shape_key_transfer"
bl_label = "Transfer Shape Key"
bl_options = {'REGISTER', 'UNDO'}
- mode = EnumProperty(items=(
- ('OFFSET', "Offset", "Apply the relative positional offset"),
- ('RELATIVE_FACE', "Relative Face", "Calculate the geometricly relative position (using faces)."),
- ('RELATIVE_EDGE', "Relative Edge", "Calculate the geometricly relative position (using edges).")),
- name="Transformation Mode",
- description="Method to apply relative shape positions to the new shape",
- default='OFFSET')
-
- use_clamp = BoolProperty(name="Clamp Offset",
- description="Clamp the transformation to the distance each vertex moves in the original shape.",
- default=False)
+ mode = EnumProperty(
+ items=(('OFFSET',
+ "Offset",
+ "Apply the relative positional offset",
+ ),
+ ('RELATIVE_FACE',
+ "Relative Face",
+ "Calculate relative position (using faces).",
+ ),
+ ('RELATIVE_EDGE',
+ "Relative Edge",
+ "Calculate relative position (using edges).",
+ ),
+ ),
+ name="Transformation Mode",
+ description="Relative shape positions to the new shape method",
+ default='OFFSET',
+ )
+ use_clamp = BoolProperty(
+ name="Clamp Offset",
+ description=("Clamp the transformation to the distance each "
+ "vertex moves in the original shape."),
+ default=False,
+ )
def _main(self, ob_act, objects, mode='OFFSET', use_clamp=False):
@@ -272,13 +331,16 @@ class ShapeTransfer(bpy.types.Operator):
orig_shape_coords = me_cos(ob_act.active_shape_key.data)
orig_normals = me_nos(me.vertices)
- # orig_coords = me_cos(me.vertices) # the actual mverts location isnt as relyable as the base shape :S
+ # the actual mverts location isnt as relyable as the base shape :S
+ # orig_coords = me_cos(me.vertices)
orig_coords = me_cos(me.shape_keys.key_blocks[0].data)
for ob_other in objects:
me_other = ob_other.data
if len(me_other.vertices) != len(me.vertices):
- self.report({'WARNING'}, "Skipping '%s', vertex count differs" % ob_other.name)
+ self.report({'WARNING'},
+ ("Skipping '%s', "
+ "vertex count differs") % ob_other.name)
continue
target_normals = me_nos(me_other.vertices)
@@ -290,53 +352,90 @@ class ShapeTransfer(bpy.types.Operator):
ob_add_shape(ob_other, orig_key_name)
# editing the final coords, only list that stores wrapped coords
- target_shape_coords = [v.co for v in ob_other.active_shape_key.data]
+ target_shape_coords = [v.co for v in
+ ob_other.active_shape_key.data]
median_coords = [[] for i in range(len(me.vertices))]
# Method 1, edge
if mode == 'OFFSET':
for i, vert_cos in enumerate(median_coords):
- vert_cos.append(target_coords[i] + (orig_shape_coords[i] - orig_coords[i]))
+ vert_cos.append(target_coords[i] +
+ (orig_shape_coords[i] - orig_coords[i]))
elif mode == 'RELATIVE_FACE':
for face in me.faces:
i1, i2, i3, i4 = face.vertices_raw
if i4 != 0:
pt = barycentric_transform(orig_shape_coords[i1],
- orig_coords[i4], orig_coords[i1], orig_coords[i2],
- target_coords[i4], target_coords[i1], target_coords[i2])
+ orig_coords[i4],
+ orig_coords[i1],
+ orig_coords[i2],
+ target_coords[i4],
+ target_coords[i1],
+ target_coords[i2],
+ )
median_coords[i1].append(pt)
pt = barycentric_transform(orig_shape_coords[i2],
- orig_coords[i1], orig_coords[i2], orig_coords[i3],
- target_coords[i1], target_coords[i2], target_coords[i3])
+ orig_coords[i1],
+ orig_coords[i2],
+ orig_coords[i3],
+ target_coords[i1],
+ target_coords[i2],
+ target_coords[i3],
+ )
median_coords[i2].append(pt)
pt = barycentric_transform(orig_shape_coords[i3],
- orig_coords[i2], orig_coords[i3], orig_coords[i4],
- target_coords[i2], target_coords[i3], target_coords[i4])
+ orig_coords[i2],
+ orig_coords[i3],
+ orig_coords[i4],
+ target_coords[i2],
+ target_coords[i3],
+ target_coords[i4],
+ )
median_coords[i3].append(pt)
pt = barycentric_transform(orig_shape_coords[i4],
- orig_coords[i3], orig_coords[i4], orig_coords[i1],
- target_coords[i3], target_coords[i4], target_coords[i1])
+ orig_coords[i3],
+ orig_coords[i4],
+ orig_coords[i1],
+ target_coords[i3],
+ target_coords[i4],
+ target_coords[i1],
+ )
median_coords[i4].append(pt)
else:
pt = barycentric_transform(orig_shape_coords[i1],
- orig_coords[i3], orig_coords[i1], orig_coords[i2],
- target_coords[i3], target_coords[i1], target_coords[i2])
+ orig_coords[i3],
+ orig_coords[i1],
+ orig_coords[i2],
+ target_coords[i3],
+ target_coords[i1],
+ target_coords[i2],
+ )
median_coords[i1].append(pt)
pt = barycentric_transform(orig_shape_coords[i2],
- orig_coords[i1], orig_coords[i2], orig_coords[i3],
- target_coords[i1], target_coords[i2], target_coords[i3])
+ orig_coords[i1],
+ orig_coords[i2],
+ orig_coords[i3],
+ target_coords[i1],
+ target_coords[i2],
+ target_coords[i3],
+ )
median_coords[i2].append(pt)
pt = barycentric_transform(orig_shape_coords[i3],
- orig_coords[i2], orig_coords[i3], orig_coords[i1],
- target_coords[i2], target_coords[i3], target_coords[i1])
+ orig_coords[i2],
+ orig_coords[i3],
+ orig_coords[i1],
+ target_coords[i2],
+ target_coords[i3],
+ target_coords[i1],
+ )
median_coords[i3].append(pt)
elif mode == 'RELATIVE_EDGE':
@@ -374,7 +473,8 @@ class ShapeTransfer(bpy.types.Operator):
if use_clamp:
# clamp to the same movement as the original
# breaks copy between different scaled meshes.
- len_from = (orig_shape_coords[i] - orig_coords[i]).length
+ len_from = (orig_shape_coords[i] -
+ orig_coords[i]).length
ofs = co - target_coords[i]
ofs.length = len_from
co = target_coords[i] + ofs
@@ -395,7 +495,10 @@ class ShapeTransfer(bpy.types.Operator):
if 1: # swap from/to, means we cant copy to many at once.
if len(objects) != 1:
- self.report({'ERROR'}, "Expected one other selected mesh object to copy from")
+ self.report({'ERROR'},
+ ("Expected one other selected "
+ "mesh object to copy from"))
+
return {'CANCELLED'}
ob_act, objects = objects[0], [ob_act]
@@ -409,7 +512,7 @@ class ShapeTransfer(bpy.types.Operator):
return self._main(ob_act, objects, self.mode, self.use_clamp)
-class JoinUVs(bpy.types.Operator):
+class JoinUVs(Operator):
'''Copy UV Layout to objects with matching geometry'''
bl_idname = "object.join_uvs"
bl_label = "Join as UVs"
@@ -429,11 +532,14 @@ class JoinUVs(bpy.types.Operator):
bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
if not mesh.uv_textures:
- self.report({'WARNING'}, "Object: %s, Mesh: '%s' has no UVs\n" % (obj.name, mesh.name))
+ self.report({'WARNING'},
+ "Object: %s, Mesh: '%s' has no UVs"
+ % (obj.name, mesh.name))
else:
len_faces = len(mesh.faces)
- uv_array = array.array('f', [0.0] * 8) * len_faces # seems to be the fastest way to create an array
+ # seems to be the fastest way to create an array
+ uv_array = array.array('f', [0.0] * 8) * len_faces
mesh.uv_textures.active.data.foreach_get("uv_raw", uv_array)
objects = context.selected_editable_objects[:]
@@ -450,11 +556,18 @@ class JoinUVs(bpy.types.Operator):
mesh_other.tag = True
if len(mesh_other.faces) != len_faces:
- self.report({'WARNING'}, "Object: %s, Mesh: '%s' has %d faces, expected %d\n" % (obj_other.name, mesh_other.name, len(mesh_other.faces), len_faces))
+ self.report({'WARNING'}, "Object: %s, Mesh: "
+ "'%s' has %d faces, expected %d\n"
+ % (obj_other.name,
+ mesh_other.name,
+ len(mesh_other.faces),
+ len_faces),
+ )
else:
uv_other = mesh_other.uv_textures.active
if not uv_other:
- uv_other = mesh_other.uv_textures.new() # should return the texture it adds
+ # should return the texture it adds
+ uv_other = mesh_other.uv_textures.new()
# finally do the copy
uv_other.data.foreach_set("uv_raw", uv_array)
@@ -467,7 +580,7 @@ class JoinUVs(bpy.types.Operator):
return {'FINISHED'}
-class MakeDupliFace(bpy.types.Operator):
+class MakeDupliFace(Operator):
'''Make linked objects into dupli-faces'''
bl_idname = "object.make_dupli_face"
bl_label = "Make Dupli-Face"
@@ -482,14 +595,18 @@ class MakeDupliFace(bpy.types.Operator):
SCALE_FAC = 0.01
offset = 0.5 * SCALE_FAC
- base_tri = Vector((-offset, -offset, 0.0)), Vector((offset, -offset, 0.0)), Vector((offset, offset, 0.0)), Vector((-offset, offset, 0.0))
+ base_tri = (Vector((-offset, -offset, 0.0)),
+ Vector((+offset, -offset, 0.0)),
+ Vector((+offset, +offset, 0.0)),
+ Vector((-offset, +offset, 0.0)),
+ )
def matrix_to_quat(matrix):
# scale = matrix.median_scale
trans = matrix.to_translation()
rot = matrix.to_3x3() # also contains scale
- return [(b * rot) + trans for b in base_tri]
+ return [(rot * b) + trans for b in base_tri]
scene = bpy.context.scene
linked = {}
for obj in bpy.context.selected_objects:
@@ -498,7 +615,10 @@ class MakeDupliFace(bpy.types.Operator):
linked.setdefault(data, []).append(obj)
for data, objects in linked.items():
- face_verts = [axis for obj in objects for v in matrix_to_quat(obj.matrix_world) for axis in v]
+ face_verts = [axis for obj in objects
+ for v in matrix_to_quat(obj.matrix_world)
+ for axis in v]
+
faces = list(range(len(face_verts) // 3))
mesh = bpy.data.meshes.new(data.name + "_dupli")
@@ -534,8 +654,9 @@ class MakeDupliFace(bpy.types.Operator):
return {'FINISHED'}
-class IsolateTypeRender(bpy.types.Operator):
- '''Hide unselected render objects of same type as active by setting the hide render flag'''
+class IsolateTypeRender(Operator):
+ '''Hide unselected render objects of same type as active ''' \
+ '''by setting the hide render flag'''
bl_idname = "object.isolate_type_render"
bl_label = "Restrict Render Unselected"
bl_options = {'REGISTER', 'UNDO'}
@@ -554,7 +675,7 @@ class IsolateTypeRender(bpy.types.Operator):
return {'FINISHED'}
-class ClearAllRestrictRender(bpy.types.Operator):
+class ClearAllRestrictRender(Operator):
'''Reveal all render objects by setting the hide render flag'''
bl_idname = "object.hide_render_clear_all"
bl_label = "Clear All Restrict Render"
@@ -564,3 +685,49 @@ class ClearAllRestrictRender(bpy.types.Operator):
for obj in context.scene.objects:
obj.hide_render = False
return {'FINISHED'}
+
+
+class TransformsToDeltasAnim(Operator):
+ '''Convert object animation for normal transforms to delta transforms'''
+ bl_idname = "object.anim_transforms_to_deltas"
+ bl_label = "Animated Transforms to Deltas"
+ bl_options = {'REGISTER', 'UNDO'}
+
+ @classmethod
+ def poll(cls, context):
+ obs = context.selected_editable_objects
+ return (obs is not None)
+
+ def execute(self, context):
+ for obj in context.selected_editable_objects:
+ # get animation data
+ adt = obj.animation_data
+ if (adt is None) or (adt.action is None):
+ self.report({'WARNING'},
+ "No animation data to convert on object: %r" %
+ obj.name)
+ continue
+
+ # if F-Curve uses standard transform path
+ # just append "delta_" to this path
+ for fcu in adt.action.fcurves:
+ if fcu.data_path == "location":
+ fcu.data_path = "delta_location"
+ obj.location.zero()
+ elif fcu.data_path == "rotation_euler":
+ fcu.data_path = "delta_rotation_euler"
+ obj.rotation_euler.zero()
+ elif fcu.data_path == "rotation_quaternion":
+ fcu.data_path = "delta_rotation_quaternion"
+ obj.rotation_quaternion.identity()
+ # XXX: currently not implemented
+ # elif fcu.data_path == "rotation_axis_angle":
+ # fcu.data_path = "delta_rotation_axis_angle"
+ elif fcu.data_path == "scale":
+ fcu.data_path = "delta_scale"
+ obj.scale = 1.0, 1.0, 1.0
+
+ # hack: force animsys flush by changing frame, so that deltas get run
+ context.scene.frame_set(context.scene.frame_current)
+
+ return {'FINISHED'}
diff --git a/release/scripts/startup/bl_operators/object_align.py b/release/scripts/startup/bl_operators/object_align.py
index 644f30a4745..50e9bfb5b98 100644
--- a/release/scripts/startup/bl_operators/object_align.py
+++ b/release/scripts/startup/bl_operators/object_align.py
@@ -16,106 +16,213 @@
#
# ##### END GPL LICENSE BLOCK #####
-# <pep8 compliant>
+# <pep8-80 compliant>
import bpy
+from bpy.types import Operator
from mathutils import Vector
-def align_objects(align_x, align_y, align_z, align_mode, relative_to):
+def GlobalBB_LQ(bb_world):
+
+ # Initialize the variables with the 8th vertex
+ left, right, front, back, down, up = (bb_world[7][0],
+ bb_world[7][0],
+ bb_world[7][1],
+ bb_world[7][1],
+ bb_world[7][2],
+ bb_world[7][2],
+ )
+
+ # Test against the other 7 verts
+ for i in range(7):
+
+ # X Range
+ val = bb_world[i][0]
+ if val < left:
+ left = val
+
+ if val > right:
+ right = val
+
+ # Y Range
+ val = bb_world[i][1]
+ if val < front:
+ front = val
+
+ if val > back:
+ back = val
+
+ # Z Range
+ val = bb_world[i][2]
+ if val < down:
+ down = val
+
+ if val > up:
+ up = val
+
+ return (Vector((left, front, up)), Vector((right, back, down)))
+
+
+def GlobalBB_HQ(obj):
+
+ matrix_world = obj.matrix_world.copy()
+
+ # Initialize the variables with the last vertex
+
+ verts = obj.data.vertices
+
+ val = matrix_world * verts[-1].co
+
+ left, right, front, back, down, up = (val[0],
+ val[0],
+ val[1],
+ val[1],
+ val[2],
+ val[2],
+ )
+
+ # Test against all other verts
+ for i in range(len(verts) - 1):
+
+ vco = matrix_world * verts[i].co
+
+ # X Range
+ val = vco[0]
+ if val < left:
+ left = val
+
+ if val > right:
+ right = val
+
+ # Y Range
+ val = vco[1]
+ if val < front:
+ front = val
+
+ if val > back:
+ back = val
+
+ # Z Range
+ val = vco[2]
+ if val < down:
+ down = val
+
+ if val > up:
+ up = val
+
+ return Vector((left, front, up)), Vector((right, back, down))
+
+
+def align_objects(align_x,
+ align_y,
+ align_z,
+ align_mode,
+ relative_to,
+ bb_quality):
cursor = bpy.context.scene.cursor_location
- Left_Up_Front_SEL = [0.0, 0.0, 0.0]
- Right_Down_Back_SEL = [0.0, 0.0, 0.0]
+ Left_Front_Up_SEL = [0.0, 0.0, 0.0]
+ Right_Back_Down_SEL = [0.0, 0.0, 0.0]
flag_first = True
objs = []
for obj in bpy.context.selected_objects:
- matrix_world = obj.matrix_world
- bb_world = [Vector(v[:]) * matrix_world for v in obj.bound_box]
+ matrix_world = obj.matrix_world.copy()
+ bb_world = [matrix_world * Vector(v[:]) for v in obj.bound_box]
objs.append((obj, bb_world))
if not objs:
return False
for obj, bb_world in objs:
- Left_Up_Front = bb_world[1]
- Right_Down_Back = bb_world[7]
+
+ if bb_quality:
+ GBB = GlobalBB_HQ(obj)
+ else:
+ GBB = GlobalBB_LQ(bb_world)
+
+ Left_Front_Up = GBB[0]
+ Right_Back_Down = GBB[1]
# Active Center
if obj == bpy.context.active_object:
- center_active_x = (Left_Up_Front[0] + Right_Down_Back[0]) / 2.0
- center_active_y = (Left_Up_Front[1] + Right_Down_Back[1]) / 2.0
- center_active_z = (Left_Up_Front[2] + Right_Down_Back[2]) / 2.0
+ center_active_x = (Left_Front_Up[0] + Right_Back_Down[0]) / 2.0
+ center_active_y = (Left_Front_Up[1] + Right_Back_Down[1]) / 2.0
+ center_active_z = (Left_Front_Up[2] + Right_Back_Down[2]) / 2.0
- size_active_x = (Right_Down_Back[0] - Left_Up_Front[0]) / 2.0
- size_active_y = (Right_Down_Back[1] - Left_Up_Front[1]) / 2.0
- size_active_z = (Left_Up_Front[2] - Right_Down_Back[2]) / 2.0
+ size_active_x = (Right_Back_Down[0] - Left_Front_Up[0]) / 2.0
+ size_active_y = (Right_Back_Down[1] - Left_Front_Up[1]) / 2.0
+ size_active_z = (Left_Front_Up[2] - Right_Back_Down[2]) / 2.0
# Selection Center
if flag_first:
flag_first = False
- Left_Up_Front_SEL[0] = Left_Up_Front[0]
- Left_Up_Front_SEL[1] = Left_Up_Front[1]
- Left_Up_Front_SEL[2] = Left_Up_Front[2]
+ Left_Front_Up_SEL[0] = Left_Front_Up[0]
+ Left_Front_Up_SEL[1] = Left_Front_Up[1]
+ Left_Front_Up_SEL[2] = Left_Front_Up[2]
- Right_Down_Back_SEL[0] = Right_Down_Back[0]
- Right_Down_Back_SEL[1] = Right_Down_Back[1]
- Right_Down_Back_SEL[2] = Right_Down_Back[2]
+ Right_Back_Down_SEL[0] = Right_Back_Down[0]
+ Right_Back_Down_SEL[1] = Right_Back_Down[1]
+ Right_Back_Down_SEL[2] = Right_Back_Down[2]
else:
# X axis
- if Left_Up_Front[0] < Left_Up_Front_SEL[0]:
- Left_Up_Front_SEL[0] = Left_Up_Front[0]
+ if Left_Front_Up[0] < Left_Front_Up_SEL[0]:
+ Left_Front_Up_SEL[0] = Left_Front_Up[0]
# Y axis
- if Left_Up_Front[1] < Left_Up_Front_SEL[1]:
- Left_Up_Front_SEL[1] = Left_Up_Front[1]
+ if Left_Front_Up[1] < Left_Front_Up_SEL[1]:
+ Left_Front_Up_SEL[1] = Left_Front_Up[1]
# Z axis
- if Left_Up_Front[2] > Left_Up_Front_SEL[2]:
- Left_Up_Front_SEL[2] = Left_Up_Front[2]
+ if Left_Front_Up[2] > Left_Front_Up_SEL[2]:
+ Left_Front_Up_SEL[2] = Left_Front_Up[2]
# X axis
- if Right_Down_Back[0] > Right_Down_Back_SEL[0]:
- Right_Down_Back_SEL[0] = Right_Down_Back[0]
+ if Right_Back_Down[0] > Right_Back_Down_SEL[0]:
+ Right_Back_Down_SEL[0] = Right_Back_Down[0]
# Y axis
- if Right_Down_Back[1] > Right_Down_Back_SEL[1]:
- Right_Down_Back_SEL[1] = Right_Down_Back[1]
+ if Right_Back_Down[1] > Right_Back_Down_SEL[1]:
+ Right_Back_Down_SEL[1] = Right_Back_Down[1]
# Z axis
- if Right_Down_Back[2] < Right_Down_Back_SEL[2]:
- Right_Down_Back_SEL[2] = Right_Down_Back[2]
+ if Right_Back_Down[2] < Right_Back_Down_SEL[2]:
+ Right_Back_Down_SEL[2] = Right_Back_Down[2]
- center_sel_x = (Left_Up_Front_SEL[0] + Right_Down_Back_SEL[0]) / 2.0
- center_sel_y = (Left_Up_Front_SEL[1] + Right_Down_Back_SEL[1]) / 2.0
- center_sel_z = (Left_Up_Front_SEL[2] + Right_Down_Back_SEL[2]) / 2.0
+ center_sel_x = (Left_Front_Up_SEL[0] + Right_Back_Down_SEL[0]) / 2.0
+ center_sel_y = (Left_Front_Up_SEL[1] + Right_Back_Down_SEL[1]) / 2.0
+ center_sel_z = (Left_Front_Up_SEL[2] + Right_Back_Down_SEL[2]) / 2.0
# Main Loop
for obj, bb_world in objs:
+ matrix_world = obj.matrix_world.copy()
+ bb_world = [matrix_world * Vector(v[:]) for v in obj.bound_box]
- loc_world = obj.location
- bb_world = [Vector(v[:]) * obj.matrix_world for v in obj.bound_box]
+ if bb_quality:
+ GBB = GlobalBB_HQ(obj)
+ else:
+ GBB = GlobalBB_LQ(bb_world)
- Left_Up_Front = bb_world[1]
- Right_Down_Back = bb_world[7]
+ Left_Front_Up = GBB[0]
+ Right_Back_Down = GBB[1]
- center_x = (Left_Up_Front[0] + Right_Down_Back[0]) / 2.0
- center_y = (Left_Up_Front[1] + Right_Down_Back[1]) / 2.0
- center_z = (Left_Up_Front[2] + Right_Down_Back[2]) / 2.0
+ center_x = (Left_Front_Up[0] + Right_Back_Down[0]) / 2.0
+ center_y = (Left_Front_Up[1] + Right_Back_Down[1]) / 2.0
+ center_z = (Left_Front_Up[2] + Right_Back_Down[2]) / 2.0
- positive_x = Right_Down_Back[0]
- positive_y = Right_Down_Back[1]
- positive_z = Left_Up_Front[2]
+ positive_x = Right_Back_Down[0]
+ positive_y = Right_Back_Down[1]
+ positive_z = Left_Front_Up[2]
- negative_x = Left_Up_Front[0]
- negative_y = Left_Up_Front[1]
- negative_z = Right_Down_Back[2]
+ negative_x = Left_Front_Up[0]
+ negative_y = Left_Front_Up[1]
+ negative_z = Right_Back_Down[2]
obj_loc = obj.location
@@ -230,40 +337,48 @@ def align_objects(align_x, align_y, align_z, align_mode, relative_to):
return True
-from bpy.props import EnumProperty
+from bpy.props import EnumProperty, BoolProperty
-class AlignObjects(bpy.types.Operator):
+class AlignObjects(Operator):
'''Align Objects'''
bl_idname = "object.align"
bl_label = "Align Objects"
bl_options = {'REGISTER', 'UNDO'}
- align_mode = EnumProperty(items=(
- ('OPT_1', "Negative Sides", ""),
- ('OPT_2', "Centers", ""),
- ('OPT_3', "Positive Sides", "")),
- name="Align Mode:",
- description="",
- default='OPT_2')
-
- relative_to = EnumProperty(items=(
- ('OPT_1', "Scene Origin", ""),
- ('OPT_2', "3D Cursor", ""),
- ('OPT_3', "Selection", ""),
- ('OPT_4', "Active", "")),
- name="Relative To:",
- description="",
- default='OPT_4')
-
- align_axis = EnumProperty(items=(
- ('X', "X", ""),
- ('Y', "Y", ""),
- ('Z', "Z", ""),
- ),
- name="Align",
- description="Align to axis",
- options={'ENUM_FLAG'})
+ bb_quality = BoolProperty(
+ name="High Quality",
+ description=("Enables high quality calculation of the "
+ "bounding box for perfect results on complex "
+ "shape meshes with rotation/scale (Slow)"),
+ default=True,
+ )
+ align_mode = EnumProperty(
+ name="Align Mode:",
+ items=(('OPT_1', "Negative Sides", ""),
+ ('OPT_2', "Centers", ""),
+ ('OPT_3', "Positive Sides", ""),
+ ),
+ default='OPT_2',
+ )
+ relative_to = EnumProperty(
+ name="Relative To:",
+ items=(('OPT_1', "Scene Origin", ""),
+ ('OPT_2', "3D Cursor", ""),
+ ('OPT_3', "Selection", ""),
+ ('OPT_4', "Active", ""),
+ ),
+ default='OPT_4',
+ )
+ align_axis = EnumProperty(
+ name="Align",
+ description="Align to axis",
+ items=(('X', "X", ""),
+ ('Y', "Y", ""),
+ ('Z', "Z", ""),
+ ),
+ options={'ENUM_FLAG'},
+ )
@classmethod
def poll(cls, context):
@@ -271,7 +386,12 @@ class AlignObjects(bpy.types.Operator):
def execute(self, context):
align_axis = self.align_axis
- ret = align_objects('X' in align_axis, 'Y' in align_axis, 'Z' in align_axis, self.align_mode, self.relative_to)
+ ret = align_objects('X' in align_axis,
+ 'Y' in align_axis,
+ 'Z' in align_axis,
+ self.align_mode,
+ self.relative_to,
+ self.bb_quality)
if not ret:
self.report({'WARNING'}, "No objects with bound-box selected")
diff --git a/release/scripts/startup/bl_operators/object_quick_effects.py b/release/scripts/startup/bl_operators/object_quick_effects.py
index 21640fa3ee6..48b547980d4 100644
--- a/release/scripts/startup/bl_operators/object_quick_effects.py
+++ b/release/scripts/startup/bl_operators/object_quick_effects.py
@@ -16,35 +16,65 @@
#
# ##### END GPL LICENSE BLOCK #####
-# <pep8 compliant>
+# <pep8-80 compliant>
from mathutils import Vector
import bpy
-from bpy.props import BoolProperty, EnumProperty, IntProperty, FloatProperty, FloatVectorProperty
+from bpy.types import Operator
+from bpy.props import (BoolProperty,
+ EnumProperty,
+ IntProperty,
+ FloatProperty,
+ FloatVectorProperty,
+ )
+
+
+def object_ensure_material(obj, mat_name):
+ """ Use an existing material or add a new one.
+ """
+ mat = mat_slot = None
+ for mat_slot in obj.material_slots:
+ mat = mat_slot.material
+ if mat:
+ break
+ if mat is None:
+ mat = bpy.data.materials.new(mat_name)
+ if mat_slot:
+ mat_slot.material = mat
+ else:
+ obj.data.materials.append(mat)
+ return mat
-class MakeFur(bpy.types.Operator):
- bl_idname = "object.make_fur"
- bl_label = "Make Fur"
+class QuickFur(Operator):
+ bl_idname = "object.quick_fur"
+ bl_label = "Quick Fur"
bl_options = {'REGISTER', 'UNDO'}
- density = EnumProperty(items=(
- ('LIGHT', "Light", ""),
- ('MEDIUM', "Medium", ""),
- ('HEAVY', "Heavy", "")),
- name="Fur Density",
- description="",
- default='MEDIUM')
-
- view_percentage = IntProperty(name="View %",
- default=10, min=1, max=100, soft_min=1, soft_max=100)
-
- length = FloatProperty(name="Length",
- default=0.1, min=0.001, max=100, soft_min=0.01, soft_max=10)
+ density = EnumProperty(
+ name="Fur Density",
+ items=(('LIGHT', "Light", ""),
+ ('MEDIUM', "Medium", ""),
+ ('HEAVY', "Heavy", "")),
+ default='MEDIUM',
+ )
+ view_percentage = IntProperty(
+ name="View %",
+ min=1, max=100,
+ soft_min=1, soft_max=100,
+ default=10,
+ )
+ length = FloatProperty(
+ name="Length",
+ min=0.001, max=100,
+ soft_min=0.01, soft_max=10,
+ default=0.1,
+ )
def execute(self, context):
fake_context = bpy.context.copy()
- mesh_objects = [obj for obj in context.selected_objects if obj.type == 'MESH']
+ mesh_objects = [obj for obj in context.selected_objects
+ if obj.type == 'MESH']
if not mesh_objects:
self.report({'ERROR'}, "Select at least one mesh object.")
@@ -75,14 +105,183 @@ class MakeFur(bpy.types.Operator):
psys.settings.child_type = 'INTERPOLATED'
obj.data.materials.append(mat)
- obj.particle_systems[-1].settings.material = len(obj.data.materials)
+ obj.particle_systems[-1].settings.material = \
+ len(obj.data.materials)
+
+ return {'FINISHED'}
+
+
+class QuickExplode(Operator):
+ bl_idname = "object.quick_explode"
+ bl_label = "Quick Explode"
+ bl_options = {'REGISTER', 'UNDO'}
+
+ style = EnumProperty(
+ name="Explode Style",
+ items=(('EXPLODE', "Explode", ""),
+ ('BLEND', "Blend", "")),
+ default='EXPLODE',
+ )
+ amount = IntProperty(
+ name="Amount of pieces",
+ min=2, max=10000,
+ soft_min=2, soft_max=10000,
+ default=100,
+ )
+ frame_duration = IntProperty(
+ name="Duration",
+ min=1, max=300000,
+ soft_min=1, soft_max=10000,
+ default=50,
+ )
+
+ frame_start = IntProperty(
+ name="Start Frame",
+ min=1, max=300000,
+ soft_min=1, soft_max=10000,
+ default=1,
+ )
+ frame_end = IntProperty(
+ name="End Frame",
+ min=1, max=300000,
+ soft_min=1, soft_max=10000,
+ default=10,
+ )
+
+ velocity = FloatProperty(
+ name="Outwards Velocity",
+ min=0, max=300000,
+ soft_min=0, soft_max=10,
+ default=1,
+ )
+
+ fade = BoolProperty(
+ name="Fade",
+ description="Fade the pieces over time.",
+ default=True,
+ )
+
+ def execute(self, context):
+ fake_context = bpy.context.copy()
+ obj_act = context.active_object
+
+ if obj_act is None or obj_act.type != 'MESH':
+ self.report({'ERROR'}, "Active object is not a mesh")
+ return {'CANCELLED'}
+
+ mesh_objects = [obj for obj in context.selected_objects
+ if obj.type == 'MESH' and obj != obj_act]
+ mesh_objects.insert(0, obj_act)
+
+ if self.style == 'BLEND' and len(mesh_objects) != 2:
+ self.report({'ERROR'}, "Select two mesh objects")
+ return {'CANCELLED'}
+ elif not mesh_objects:
+ self.report({'ERROR'}, "Select at least one mesh object")
+ return {'CANCELLED'}
+
+ for obj in mesh_objects:
+ if obj.particle_systems:
+ self.report({'ERROR'},
+ "Object %r already has a "
+ "particle system" % obj.name)
+
+ return {'CANCELLED'}
+
+ if self.fade:
+ tex = bpy.data.textures.new("Explode fade", 'BLEND')
+ tex.use_color_ramp = True
+
+ if self.style == 'BLEND':
+ tex.color_ramp.elements[0].position = 0.333
+ tex.color_ramp.elements[1].position = 0.666
+
+ tex.color_ramp.elements[0].color[3] = 1.0
+ tex.color_ramp.elements[1].color[3] = 0.0
+
+ if self.style == 'BLEND':
+ from_obj = mesh_objects[1]
+ to_obj = mesh_objects[0]
+
+ for obj in mesh_objects:
+ fake_context["object"] = obj
+ bpy.ops.object.particle_system_add(fake_context)
+
+ settings = obj.particle_systems[-1].settings
+ settings.count = self.amount
+ settings.frame_start = self.frame_start
+ settings.frame_end = self.frame_end - self.frame_duration
+ settings.lifetime = self.frame_duration
+ settings.normal_factor = self.velocity
+ settings.render_type = 'NONE'
+
+ explode = obj.modifiers.new(name='Explode', type='EXPLODE')
+ explode.use_edge_cut = True
+
+ if self.fade:
+ explode.show_dead = False
+ uv = obj.data.uv_textures.new("Explode fade")
+ explode.particle_uv = uv.name
+
+ mat = object_ensure_material(obj, "Explode Fade")
+
+ mat.use_transparency = True
+ mat.use_transparent_shadows = True
+ mat.alpha = 0.0
+ mat.specular_alpha = 0.0
+
+ tex_slot = mat.texture_slots.add()
+
+ tex_slot.texture = tex
+ tex_slot.texture_coords = 'UV'
+ tex_slot.uv_layer = uv.name
+
+ tex_slot.use_map_alpha = True
+
+ if self.style == 'BLEND':
+ if obj == to_obj:
+ tex_slot.alpha_factor = -1.0
+ elem = tex.color_ramp.elements[1]
+ elem.color = mat.diffuse_color
+ else:
+ elem = tex.color_ramp.elements[0]
+ elem.color = mat.diffuse_color
+ else:
+ tex_slot.use_map_color_diffuse = False
+
+ if self.style == 'BLEND':
+ settings.physics_type = 'KEYED'
+ settings.use_emit_random = False
+ settings.rotation_mode = 'NOR'
+
+ psys = obj.particle_systems[-1]
+
+ fake_context["particle_system"] = obj.particle_systems[-1]
+ bpy.ops.particle.new_target(fake_context)
+ bpy.ops.particle.new_target(fake_context)
+
+ if obj == from_obj:
+ psys.targets[1].object = to_obj
+ else:
+ psys.targets[0].object = from_obj
+ settings.normal_factor = -self.velocity
+ explode.show_unborn = False
+ explode.show_dead = True
+ else:
+ settings.factor_random = self.velocity
+ settings.angular_velocity_factor = self.velocity / 10.0
return {'FINISHED'}
+ def invoke(self, context, event):
+ self.frame_start = context.scene.frame_current
+ self.frame_end = self.frame_start + self.frame_duration
+ return self.execute(context)
+
def obj_bb_minmax(obj, min_co, max_co):
for i in range(0, 8):
- bb_vec = Vector((obj.bound_box[i][0], obj.bound_box[i][1], obj.bound_box[i][2])) * obj.matrix_world
+ bb_vec = obj.matrix_world * Vector(obj.bound_box[i])
min_co[0] = min(bb_vec[0], min_co[0])
min_co[1] = min(bb_vec[1], min_co[1])
@@ -92,28 +291,32 @@ def obj_bb_minmax(obj, min_co, max_co):
max_co[2] = max(bb_vec[2], max_co[2])
-class MakeSmoke(bpy.types.Operator):
- bl_idname = "object.make_smoke"
- bl_label = "Make Smoke"
+class QuickSmoke(Operator):
+ bl_idname = "object.quick_smoke"
+ bl_label = "Quick Smoke"
bl_options = {'REGISTER', 'UNDO'}
- style = EnumProperty(items=(
- ('STREAM', "Stream", ""),
- ('PUFF', "Puff", ""),
- ('FIRE', "Fire", "")),
- name="Smoke Style",
- description="",
- default='STREAM')
-
- show_flows = BoolProperty(name="Render Smoke Objects",
- description="Keep the smoke objects visible during rendering.",
- default=False)
+ style = EnumProperty(
+ name="Smoke Style",
+ items=(('STREAM', "Stream", ""),
+ ('PUFF', "Puff", ""),
+ ('FIRE', "Fire", ""),
+ ),
+ default='STREAM',
+ )
+
+ show_flows = BoolProperty(
+ name="Render Smoke Objects",
+ description="Keep the smoke objects visible during rendering.",
+ default=False,
+ )
def execute(self, context):
fake_context = bpy.context.copy()
- mesh_objects = [obj for obj in context.selected_objects if obj.type == 'MESH']
- min_co = Vector((100000, 100000, 100000))
- max_co = Vector((-100000, -100000, -100000))
+ mesh_objects = [obj for obj in context.selected_objects
+ if obj.type == 'MESH']
+ min_co = Vector((100000.0, 100000.0, 100000.0))
+ max_co = -min_co
if not mesh_objects:
self.report({'ERROR'}, "Select at least one mesh object.")
@@ -171,21 +374,25 @@ class MakeSmoke(bpy.types.Operator):
mat.volume.density = 0
mat.volume.density_scale = 5
- mat.texture_slots.add()
- mat.texture_slots[0].texture = bpy.data.textures.new("Smoke Density", 'VOXEL_DATA')
- mat.texture_slots[0].texture.voxel_data.domain_object = obj
- mat.texture_slots[0].use_map_color_emission = False
- mat.texture_slots[0].use_map_density = True
+ tex = bpy.data.textures.new("Smoke Density", 'VOXEL_DATA')
+ tex.voxel_data.domain_object = obj
+
+ tex_slot = mat.texture_slots.add()
+ tex_slot.texture = tex
+ tex_slot.use_map_color_emission = False
+ tex_slot.use_map_density = True
# for fire add a second texture for emission and emission color
if self.style == 'FIRE':
mat.volume.emission = 5
- mat.texture_slots.add()
- mat.texture_slots[1].texture = bpy.data.textures.new("Smoke Heat", 'VOXEL_DATA')
- mat.texture_slots[1].texture.voxel_data.domain_object = obj
- mat.texture_slots[1].texture.use_color_ramp = True
+ tex = bpy.data.textures.new("Smoke Heat", 'VOXEL_DATA')
+ tex.voxel_data.domain_object = obj
+ tex.use_color_ramp = True
+
+ tex_slot = mat.texture_slots.add()
+ tex_slot.texture = tex
- ramp = mat.texture_slots[1].texture.color_ramp
+ ramp = tex.color_ramp
elem = ramp.elements.new(0.333)
elem.color[0] = elem.color[3] = 1
@@ -201,33 +408,40 @@ class MakeSmoke(bpy.types.Operator):
return {'FINISHED'}
-class MakeFluid(bpy.types.Operator):
- bl_idname = "object.make_fluid"
- bl_label = "Make Fluid"
+class QuickFluid(Operator):
+ bl_idname = "object.quick_fluid"
+ bl_label = "Quick Fluid"
bl_options = {'REGISTER', 'UNDO'}
- style = EnumProperty(items=(
- ('INFLOW', "Inflow", ""),
- ('BASIC', "Basic", "")),
- name="Fluid Style",
- description="",
- default='BASIC')
-
- initial_velocity = FloatVectorProperty(name="Initial Velocity",
- description="Initial velocity of the fluid",
- default=(0.0, 0.0, 0.0), min=-100.0, max=100.0, subtype='VELOCITY')
-
- show_flows = BoolProperty(name="Render Fluid Objects",
- description="Keep the fluid objects visible during rendering.",
- default=False)
-
- start_baking = BoolProperty(name="Start Fluid Bake",
- description="Start baking the fluid immediately after creating the domain object.",
- default=False)
+ style = EnumProperty(
+ name="Fluid Style",
+ items=(('INFLOW', "Inflow", ""),
+ ('BASIC', "Basic", "")),
+ default='BASIC',
+ )
+ initial_velocity = FloatVectorProperty(
+ name="Initial Velocity",
+ description="Initial velocity of the fluid",
+ min=-100.0, max=100.0,
+ default=(0.0, 0.0, 0.0),
+ subtype='VELOCITY',
+ )
+ show_flows = BoolProperty(
+ name="Render Fluid Objects",
+ description="Keep the fluid objects visible during rendering.",
+ default=False,
+ )
+ start_baking = BoolProperty(
+ name="Start Fluid Bake",
+ description=("Start baking the fluid immediately "
+ "after creating the domain object"),
+ default=False,
+ )
def execute(self, context):
fake_context = bpy.context.copy()
- mesh_objects = [obj for obj in context.selected_objects if (obj.type == 'MESH' and not 0 in obj.dimensions)]
+ mesh_objects = [obj for obj in context.selected_objects
+ if (obj.type == 'MESH' and not 0.0 in obj.dimensions)]
min_co = Vector((100000, 100000, 100000))
max_co = Vector((-100000, -100000, -100000))
@@ -240,7 +454,8 @@ class MakeFluid(bpy.types.Operator):
# make each selected object a fluid
bpy.ops.object.modifier_add(fake_context, type='FLUID_SIMULATION')
- # fluid has to be before constructive modifiers, so it might not be the last modifier
+ # fluid has to be before constructive modifiers,
+ # so it might not be the last modifier
for mod in obj.modifiers:
if mod.type == 'FLUID_SIMULATION':
break
@@ -264,10 +479,14 @@ class MakeFluid(bpy.types.Operator):
obj = context.active_object
obj.name = "Fluid Domain"
- # give the fluid some room below the flows and scale with initial velocity
+ # give the fluid some room below the flows
+ # and scale with initial velocity
v = 0.5 * self.initial_velocity
obj.location = 0.5 * (max_co + min_co) + Vector((0.0, 0.0, -1.0)) + v
- obj.scale = 0.5 * (max_co - min_co) + Vector((1.0, 1.0, 2.0)) + Vector((abs(v[0]), abs(v[1]), abs(v[2])))
+ obj.scale = (0.5 * (max_co - min_co) +
+ Vector((1.0, 1.0, 2.0)) +
+ Vector((abs(v[0]), abs(v[1]), abs(v[2])))
+ )
# setup smoke domain
bpy.ops.object.modifier_add(type='FLUID_SIMULATION')
diff --git a/release/scripts/startup/bl_operators/object_randomize_transform.py b/release/scripts/startup/bl_operators/object_randomize_transform.py
index 9dc5086086f..7aea18487f3 100644
--- a/release/scripts/startup/bl_operators/object_randomize_transform.py
+++ b/release/scripts/startup/bl_operators/object_randomize_transform.py
@@ -16,9 +16,10 @@
#
# ##### END GPL LICENSE BLOCK #####
-# <pep8 compliant>
+# <pep8-80 compliant>
import bpy
+from bpy.types import Operator
def randomize_selected(seed, delta, loc, rot, scale, scale_even):
@@ -87,46 +88,78 @@ def randomize_selected(seed, delta, loc, rot, scale, scale_even):
from bpy.props import IntProperty, BoolProperty, FloatVectorProperty
-class RandomizeLocRotSize(bpy.types.Operator):
+class RandomizeLocRotSize(Operator):
'''Randomize objects loc/rot/scale'''
bl_idname = "object.randomize_transform"
bl_label = "Randomize Transform"
bl_options = {'REGISTER', 'UNDO'}
- random_seed = IntProperty(name="Random Seed",
- description="Seed value for the random generator",
- default=0, min=0, max=1000)
-
- use_delta = BoolProperty(name="Transform Delta",
- description="Randomize delta transform values instead of regular transform", default=False)
-
- use_loc = BoolProperty(name="Randomize Location",
- description="Randomize the location values", default=True)
-
- loc = FloatVectorProperty(name="Location",
- description="Maximun distance the objects can spread over each axis",
- default=(0.0, 0.0, 0.0), min=-100.0, max=100.0, subtype='TRANSLATION')
-
- use_rot = BoolProperty(name="Randomize Rotation",
- description="Randomize the rotation values", default=True)
-
- rot = FloatVectorProperty(name="Rotation",
- description="Maximun rotation over each axis",
- default=(0.0, 0.0, 0.0), min=-180.0, max=180.0, subtype='TRANSLATION')
-
- use_scale = BoolProperty(name="Randomize Scale",
- description="Randomize the scale values", default=True)
-
- scale_even = BoolProperty(name="Scale Even",
- description="Use the same scale value for all axis", default=False)
-
- '''scale_min = FloatProperty(name="Minimun Scale Factor",
- description="Lowest scale percentage possible",
- default=0.15, min=-1.0, max=1.0, precision=3)'''
-
- scale = FloatVectorProperty(name="Scale",
- description="Maximum scale randomization over each axis",
- default=(0.0, 0.0, 0.0), min=-100.0, max=100.0, subtype='TRANSLATION')
+ random_seed = IntProperty(
+ name="Random Seed",
+ description="Seed value for the random generator",
+ min=0,
+ max=1000,
+ default=0,
+ )
+ use_delta = BoolProperty(
+ name="Transform Delta",
+ description=("Randomize delta transform values "
+ "instead of regular transform"),
+ default=False,
+ )
+ use_loc = BoolProperty(
+ name="Randomize Location",
+ description="Randomize the location values",
+ default=True,
+ )
+ loc = FloatVectorProperty(
+ name="Location",
+ description=("Maximun distance the objects "
+ "can spread over each axis"),
+ min=-100.0,
+ max=100.0,
+ default=(0.0, 0.0, 0.0),
+ subtype='TRANSLATION',
+ )
+ use_rot = BoolProperty(
+ name="Randomize Rotation",
+ description="Randomize the rotation values",
+ default=True,
+ )
+ rot = FloatVectorProperty(
+ name="Rotation",
+ description="Maximun rotation over each axis",
+ min=-180.0,
+ max=180.0,
+ default=(0.0, 0.0, 0.0),
+ subtype='TRANSLATION',
+ )
+ use_scale = BoolProperty(
+ name="Randomize Scale",
+ description="Randomize the scale values",
+ default=True,
+ )
+ scale_even = BoolProperty(
+ name="Scale Even",
+ description="Use the same scale value for all axis",
+ default=False,
+ )
+
+ '''scale_min = FloatProperty(
+ name="Minimun Scale Factor",
+ description="Lowest scale percentage possible",
+ min=-1.0, max=1.0, precision=3,
+ default=0.15,
+ )'''
+
+ scale = FloatVectorProperty(
+ name="Scale",
+ description="Maximum scale randomization over each axis",
+ min=-100.0,
+ max=100.0,
+ default=(0.0, 0.0, 0.0),
+ subtype='TRANSLATION',
+ )
def execute(self, context):
from math import radians
diff --git a/release/scripts/startup/bl_operators/presets.py b/release/scripts/startup/bl_operators/presets.py
index 2175d7528a4..2fd0c4a9e12 100644
--- a/release/scripts/startup/bl_operators/presets.py
+++ b/release/scripts/startup/bl_operators/presets.py
@@ -16,9 +16,10 @@
#
# ##### END GPL LICENSE BLOCK #####
-# <pep8 compliant>
+# <pep8-80 compliant>
import bpy
+from bpy.types import Menu, Operator
class AddPresetBase():
@@ -30,8 +31,15 @@ class AddPresetBase():
# bl_label = "Add a Python Preset"
bl_options = {'REGISTER'} # only because invoke_props_popup requires.
- name = bpy.props.StringProperty(name="Name", description="Name of the preset, used to make the path name", maxlen=64, default="")
- remove_active = bpy.props.BoolProperty(default=False, options={'HIDDEN'})
+ name = bpy.props.StringProperty(
+ name="Name",
+ description="Name of the preset, used to make the path name",
+ maxlen=64,
+ )
+ remove_active = bpy.props.BoolProperty(
+ default=False,
+ options={'HIDDEN'},
+ )
@staticmethod
def as_filename(name): # could reuse for other presets
@@ -54,7 +62,10 @@ class AddPresetBase():
filename = self.as_filename(name)
- target_path = bpy.utils.user_resource('SCRIPTS', os.path.join("presets", self.preset_subdir), create=True)
+ target_path = os.path.join("presets", self.preset_subdir)
+ target_path = bpy.utils.user_resource('SCRIPTS',
+ target_path,
+ create=True)
if not target_path:
self.report({'WARNING'}, "Failed to create presets path")
@@ -95,7 +106,9 @@ class AddPresetBase():
filepath = bpy.utils.preset_find(preset_active, self.preset_subdir)
if not filepath:
- filepath = bpy.utils.preset_find(preset_active, self.preset_subdir, display_name=True)
+ filepath = bpy.utils.preset_find(preset_active,
+ self.preset_subdir,
+ display_name=True)
if not filepath:
return {'CANCELLED'}
@@ -128,13 +141,20 @@ class AddPresetBase():
return self.execute(context)
-class ExecutePreset(bpy.types.Operator):
+class ExecutePreset(Operator):
''' Executes a preset '''
bl_idname = "script.execute_preset"
bl_label = "Execute a Python Preset"
- filepath = bpy.props.StringProperty(name="Path", description="Path of the Python file to execute", maxlen=512, default="")
- menu_idname = bpy.props.StringProperty(name="Menu ID Name", description="ID name of the menu this was called from", default="")
+ filepath = bpy.props.StringProperty(
+ name="Path",
+ description="Path of the Python file to execute",
+ maxlen=512,
+ )
+ menu_idname = bpy.props.StringProperty(
+ name="Menu ID Name",
+ description="ID name of the menu this was called from",
+ )
def execute(self, context):
from os.path import basename
@@ -149,7 +169,7 @@ class ExecutePreset(bpy.types.Operator):
return {'FINISHED'}
-class AddPresetRender(AddPresetBase, bpy.types.Operator):
+class AddPresetRender(AddPresetBase, Operator):
'''Add a Render Preset'''
bl_idname = "render.preset_add"
bl_label = "Add Render Preset"
@@ -175,14 +195,17 @@ class AddPresetRender(AddPresetBase, bpy.types.Operator):
preset_subdir = "render"
-class AddPresetSSS(AddPresetBase, bpy.types.Operator):
+class AddPresetSSS(AddPresetBase, Operator):
'''Add a Subsurface Scattering Preset'''
bl_idname = "material.sss_preset_add"
bl_label = "Add SSS Preset"
preset_menu = "MATERIAL_MT_sss_presets"
preset_defines = [
- "material = (bpy.context.material.active_node_material if bpy.context.material.active_node_material else bpy.context.material)"
+ ("material = "
+ "bpy.context.material.active_node_material "
+ "if bpy.context.material.active_node_material "
+ "else bpy.context.material")
]
preset_values = [
@@ -200,7 +223,7 @@ class AddPresetSSS(AddPresetBase, bpy.types.Operator):
preset_subdir = "sss"
-class AddPresetCloth(AddPresetBase, bpy.types.Operator):
+class AddPresetCloth(AddPresetBase, Operator):
'''Add a Cloth Preset'''
bl_idname = "cloth.preset_add"
bl_label = "Add Cloth Preset"
@@ -222,7 +245,7 @@ class AddPresetCloth(AddPresetBase, bpy.types.Operator):
preset_subdir = "cloth"
-class AddPresetSunSky(AddPresetBase, bpy.types.Operator):
+class AddPresetSunSky(AddPresetBase, Operator):
'''Add a Sky & Atmosphere Preset'''
bl_idname = "lamp.sunsky_preset_add"
bl_label = "Add Sunsky Preset"
@@ -251,7 +274,7 @@ class AddPresetSunSky(AddPresetBase, bpy.types.Operator):
preset_subdir = "sunsky"
-class AddPresetInteraction(AddPresetBase, bpy.types.Operator):
+class AddPresetInteraction(AddPresetBase, Operator):
'''Add an Application Interaction Preset'''
bl_idname = "wm.interaction_preset_add"
bl_label = "Add Interaction Preset"
@@ -277,7 +300,7 @@ class AddPresetInteraction(AddPresetBase, bpy.types.Operator):
preset_subdir = "interaction"
-class AddPresetKeyconfig(AddPresetBase, bpy.types.Operator):
+class AddPresetKeyconfig(AddPresetBase, Operator):
'''Add a Keyconfig Preset'''
bl_idname = "wm.keyconfig_preset_add"
bl_label = "Add Keyconfig Preset"
@@ -300,13 +323,17 @@ class AddPresetKeyconfig(AddPresetBase, bpy.types.Operator):
keyconfigs.remove(keyconfigs.active)
-class AddPresetOperator(AddPresetBase, bpy.types.Operator):
+class AddPresetOperator(AddPresetBase, Operator):
'''Add an Application Interaction Preset'''
bl_idname = "wm.operator_preset_add"
bl_label = "Operator Preset"
preset_menu = "WM_MT_operator_presets"
- operator = bpy.props.StringProperty(name="Operator", maxlen=64, options={'HIDDEN'})
+ operator = bpy.props.StringProperty(
+ name="Operator",
+ maxlen=64,
+ options={'HIDDEN'},
+ )
# XXX, not ideal
preset_defines = [
@@ -315,19 +342,22 @@ class AddPresetOperator(AddPresetBase, bpy.types.Operator):
@property
def preset_subdir(self):
- return __class__.operator_path(self.operator)
+ return AddPresetOperator.operator_path(self.operator)
@property
def preset_values(self):
- properties_blacklist = bpy.types.Operator.bl_rna.properties.keys()
+ properties_blacklist = Operator.bl_rna.properties.keys()
prefix, suffix = self.operator.split("_OT_", 1)
- operator_rna = getattr(getattr(bpy.ops, prefix.lower()), suffix).get_rna().bl_rna
+ op = getattr(getattr(bpy.ops, prefix.lower()), suffix)
+ operator_rna = op.get_rna().bl_rna
+ del op
ret = []
for prop_id, prop in operator_rna.properties.items():
- if (not (prop.is_hidden or prop.is_skip_save)) and prop_id not in properties_blacklist:
- ret.append("op.%s" % prop_id)
+ if not (prop.is_hidden or prop.is_skip_save):
+ if prop_id not in properties_blacklist:
+ ret.append("op.%s" % prop_id)
return ret
@@ -338,12 +368,12 @@ class AddPresetOperator(AddPresetBase, bpy.types.Operator):
return os.path.join("operator", "%s.%s" % (prefix.lower(), suffix))
-class WM_MT_operator_presets(bpy.types.Menu):
+class WM_MT_operator_presets(Menu):
bl_label = "Operator Presets"
def draw(self, context):
self.operator = context.space_data.operator.bl_idname
- bpy.types.Menu.draw_preset(self, context)
+ Menu.draw_preset(self, context)
@property
def preset_subdir(self):
diff --git a/release/scripts/startup/bl_operators/screen_play_rendered_anim.py b/release/scripts/startup/bl_operators/screen_play_rendered_anim.py
index 64af25e7b0f..c2a09d6a4ae 100644
--- a/release/scripts/startup/bl_operators/screen_play_rendered_anim.py
+++ b/release/scripts/startup/bl_operators/screen_play_rendered_anim.py
@@ -1,30 +1,27 @@
-# ***** BEGIN GPL LICENSE BLOCK *****
+# ##### BEGIN GPL LICENSE BLOCK #####
#
-# Script copyright (C) Campbell J Barton
+# 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 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.
#
-# 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.
#
-# 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 LICENCE BLOCK *****
+# ##### END GPL LICENSE BLOCK #####
-# <pep8 compliant>
+# <pep8-80 compliant>
-# History
-#
# Originally written by Matt Ebb
import bpy
+from bpy.types import Operator
import os
@@ -46,8 +43,10 @@ def guess_player_path(preset):
player_path = "djv_view"
if sys.platform == "darwin":
- # TODO, crummy supporting only 1 version, could find the newest installed version
- test_path = '/Applications/djv-0.8.2.app/Contents/Resources/bin/djv_view'
+ # TODO, crummy supporting only 1 version,
+ # could find the newest installed version
+ test_path = ("/Applications/djv-0.8.2.app"
+ "/Contents/Resources/bin/djv_view")
if os.path.exists(test_path):
player_path = test_path
@@ -60,10 +59,13 @@ def guess_player_path(preset):
elif preset == 'MPLAYER':
player_path = "mplayer"
+ else:
+ player_path = ""
+
return player_path
-class PlayRenderedAnim(bpy.types.Operator):
+class PlayRenderedAnim(Operator):
'''Plays back rendered frames/movies using an external player.'''
bl_idname = "render.play_rendered_anim"
bl_label = "Play Rendered Animation"
@@ -78,14 +80,14 @@ class PlayRenderedAnim(bpy.types.Operator):
preset = prefs.filepaths.animation_player_preset
player_path = prefs.filepaths.animation_player
- file_path = bpy.path.abspath(rd.filepath)
+ # file_path = bpy.path.abspath(rd.filepath) # UNUSED
is_movie = rd.is_movie_format
# try and guess a command line if it doesn't exist
- if player_path == '':
+ if player_path == "":
player_path = guess_player_path(preset)
- if is_movie == False and preset in ('FRAMECYCLER', 'RV', 'MPLAYER'):
+ if is_movie == False and preset in {'FRAMECYCLER', 'RV', 'MPLAYER'}:
# replace the number with '#'
file_a = rd.frame_path(frame=0)
@@ -95,11 +97,11 @@ class PlayRenderedAnim(bpy.types.Operator):
while len(file_a) == len(file_b):
frame_tmp = (frame_tmp * 10) + 9
- print(frame_tmp)
file_b = rd.frame_path(frame=frame_tmp)
file_b = rd.frame_path(frame=int(frame_tmp / 10))
- file = "".join((c if file_b[i] == c else "#") for i, c in enumerate(file_a))
+ file = ("".join((c if file_b[i] == c else "#")
+ for i, c in enumerate(file_a)))
else:
# works for movies and images
file = rd.frame_path(frame=scene.frame_start)
@@ -109,10 +111,35 @@ class PlayRenderedAnim(bpy.types.Operator):
cmd = [player_path]
# extra options, fps controls etc.
if preset == 'BLENDER24':
+ # -----------------------------------------------------------------
+ # Check blender is not 2.5x until it supports playback again
+ try:
+ process = subprocess.Popen([player_path, '--version'],
+ stdout=subprocess.PIPE,
+ )
+ except:
+ # ignore and allow the main execution to catch the problem.
+ process = None
+
+ if process is not None:
+ process.wait()
+ out = process.stdout.read()
+ process.stdout.close()
+ out_split = out.strip().split()
+ if out_split[0] == b'Blender':
+ if not out_split[1].startswith(b'2.4'):
+ self.report({'ERROR'},
+ "Blender %s doesn't support playback: %r" %
+ (out_split[1].decode(), player_path))
+ return {'CANCELLED'}
+ del out, out_split
+ del process
+ # -----------------------------------------------------------------
+
opts = ["-a", "-f", str(rd.fps), str(rd.fps_base), file]
cmd.extend(opts)
elif preset == 'DJV':
- opts = [file, "-playback_speed", str(rd.fps)]
+ opts = [file, "-playback_speed", "%d" % int(rd.fps / rd.fps_base)]
cmd.extend(opts)
elif preset == 'FRAMECYCLER':
opts = [file, "%d-%d" % (scene.frame_start, scene.frame_end)]
@@ -125,18 +152,26 @@ class PlayRenderedAnim(bpy.types.Operator):
if is_movie:
opts.append(file)
else:
- opts.append("mf://%s" % file.replace("#", "?"))
- opts += ["-mf", "fps=%.4f" % (rd.fps / rd.fps_base)]
+ opts += [("mf://%s" % file.replace("#", "?")),
+ "-mf",
+ "fps=%.4f" % (rd.fps / rd.fps_base),
+ ]
+
opts += ["-loop", "0", "-really-quiet", "-fs"]
cmd.extend(opts)
else: # 'CUSTOM'
cmd.append(file)
# launch it
+ print("Executing command:\n %r" % " ".join(cmd))
+
try:
process = subprocess.Popen(cmd)
- except:
- pass
- #raise OSError("Couldn't find an external animation player.")
+ except Exception as e:
+ import traceback
+ self.report({'ERROR'},
+ "Couldn't run external animation player with command "
+ "%r\n%s" % (" ".join(cmd), str(e)))
+ return {'CANCELLED'}
return {'FINISHED'}
diff --git a/release/scripts/startup/bl_operators/sequencer.py b/release/scripts/startup/bl_operators/sequencer.py
index 16b72406c49..856e182279a 100644
--- a/release/scripts/startup/bl_operators/sequencer.py
+++ b/release/scripts/startup/bl_operators/sequencer.py
@@ -19,11 +19,12 @@
# <pep8 compliant>
import bpy
+from bpy.types import Operator
from bpy.props import IntProperty
-class SequencerCrossfadeSounds(bpy.types.Operator):
+class SequencerCrossfadeSounds(Operator):
'''Do crossfading volume animation of two selected sound strips.'''
bl_idname = "sequencer.crossfade_sounds"
@@ -74,15 +75,19 @@ class SequencerCrossfadeSounds(bpy.types.Operator):
return {'CANCELLED'}
-class SequencerCutMulticam(bpy.types.Operator):
+class SequencerCutMulticam(Operator):
'''Cut multicam strip and select camera.'''
bl_idname = "sequencer.cut_multicam"
bl_label = "Cut multicam"
bl_options = {'REGISTER', 'UNDO'}
- camera = IntProperty(name="Camera",
- default=1, min=1, max=32, soft_min=1, soft_max=32)
+ camera = IntProperty(
+ name="Camera",
+ min=1, max=32,
+ soft_min=1, soft_max=32,
+ default=1,
+ )
@classmethod
def poll(cls, context):
@@ -112,7 +117,7 @@ class SequencerCutMulticam(bpy.types.Operator):
return {'FINISHED'}
-class SequencerDeinterlaceSelectedMovies(bpy.types.Operator):
+class SequencerDeinterlaceSelectedMovies(Operator):
'''Deinterlace all selected movie sources.'''
bl_idname = "sequencer.deinterlace_selected_movies"
diff --git a/release/scripts/startup/bl_operators/uvcalc_follow_active.py b/release/scripts/startup/bl_operators/uvcalc_follow_active.py
index edd09d9c66b..6c258d094e8 100644
--- a/release/scripts/startup/bl_operators/uvcalc_follow_active.py
+++ b/release/scripts/startup/bl_operators/uvcalc_follow_active.py
@@ -22,6 +22,7 @@
# http://mediawiki.blender.org/index.php/Scripts/Manual/UV_Calculate/Follow_active_quads
import bpy
+from bpy.types import Operator
def extend(obj, operator, EXTEND_MODE):
@@ -42,7 +43,6 @@ def extend(obj, operator, EXTEND_MODE):
edge_average_lengths = {}
OTHER_INDEX = 2, 3, 0, 1
- FAST_INDICIES = 0, 2, 1, 3 # order is faster
def extend_uvs(face_source, face_target, edge_key):
'''
@@ -227,7 +227,7 @@ def main(context, operator):
extend(obj, operator, operator.properties.mode)
-class FollowActiveQuads(bpy.types.Operator):
+class FollowActiveQuads(Operator):
'''Follow UVs from active quads along continuous face loops'''
bl_idname = "uv.follow_active_quads"
bl_label = "Follow Active Quads"
diff --git a/release/scripts/startup/bl_operators/uvcalc_lightmap.py b/release/scripts/startup/bl_operators/uvcalc_lightmap.py
index 3893612437a..060fe400045 100644
--- a/release/scripts/startup/bl_operators/uvcalc_lightmap.py
+++ b/release/scripts/startup/bl_operators/uvcalc_lightmap.py
@@ -19,11 +19,20 @@
# <pep8 compliant>
import bpy
+from bpy.types import Operator
import mathutils
class prettyface(object):
- __slots__ = "uv", "width", "height", "children", "xoff", "yoff", "has_parent", "rot"
+ __slots__ = ("uv",
+ "width",
+ "height",
+ "children",
+ "xoff",
+ "yoff",
+ "has_parent",
+ "rot",
+ )
def __init__(self, data):
self.has_parent = False
@@ -263,10 +272,9 @@ def lightmap_uvpack(meshes,
del trylens
def trilensdiff(t1, t2):
- return\
- abs(t1[1][t1[2][0]] - t2[1][t2[2][0]]) + \
- abs(t1[1][t1[2][1]] - t2[1][t2[2][1]]) + \
- abs(t1[1][t1[2][2]] - t2[1][t2[2][2]])
+ return (abs(t1[1][t1[2][0]] - t2[1][t2[2][0]]) +
+ abs(t1[1][t1[2][1]] - t2[1][t2[2][1]]) +
+ abs(t1[1][t1[2][2]] - t2[1][t2[2][2]]))
while tri_lengths:
tri1 = tri_lengths.pop()
@@ -406,7 +414,7 @@ def lightmap_uvpack(meshes,
ok = False
# Tall boxes in groups of 2
- for d, boxes in odd_dict.items():
+ for d, boxes in list(odd_dict.items()):
if d[1] < max_int_dimension:
#\boxes.sort(key = lambda a: len(a.children))
while len(boxes) >= 2:
@@ -427,7 +435,7 @@ def lightmap_uvpack(meshes,
odd_dict.setdefault((w, h), []).append(pf_parent)
# Even boxes in groups of 4
- for d, boxes in even_dict.items():
+ for d, boxes in list(even_dict.items()):
if d < max_int_dimension:
boxes.sort(key=lambda a: len(a.children))
@@ -444,7 +452,7 @@ def lightmap_uvpack(meshes,
del even_dict
del odd_dict
- orig = len(pretty_faces)
+ # orig = len(pretty_faces)
pretty_faces = [pf for pf in pretty_faces if not pf.has_parent]
@@ -489,7 +497,10 @@ def lightmap_uvpack(meshes,
if PREF_APPLY_IMAGE:
if not PREF_PACK_IN_ONE:
- image = Image.New("lightmap", PREF_IMG_PX_SIZE, PREF_IMG_PX_SIZE, 24)
+ image = bpy.data.images.new(name="lightmap",
+ width=PREF_IMG_PX_SIZE,
+ height=PREF_IMG_PX_SIZE,
+ )
for f in face_sel:
# f.image = image
@@ -517,7 +528,7 @@ def unwrap(operator, context, **kwargs):
if obj and obj.type == 'MESH':
meshes = [obj.data]
else:
- meshes = {me.name: me for obj in context.selected_objects if obj.type == 'MESH' for me in (obj.data,) if not me.library if len(me.faces)}.values()
+ meshes = list({me for obj in context.selected_objects if obj.type == 'MESH' for me in (obj.data,) if me.faces and me.library is None})
if not meshes:
operator.report({'ERROR'}, "No mesh object.")
@@ -530,32 +541,60 @@ def unwrap(operator, context, **kwargs):
return {'FINISHED'}
-from bpy.props import BoolProperty, FloatProperty, IntProperty, EnumProperty
+from bpy.props import BoolProperty, FloatProperty, IntProperty
-class LightMapPack(bpy.types.Operator):
+class LightMapPack(Operator):
'''Follow UVs from active quads along continuous face loops'''
bl_idname = "uv.lightmap_pack"
bl_label = "Lightmap Pack"
bl_options = {'REGISTER', 'UNDO'}
PREF_CONTEXT = bpy.props.EnumProperty(
+ name="Selection",
items=(("SEL_FACES", "Selected Faces", "Space all UVs evently"),
("ALL_FACES", "All Faces", "Average space UVs edge length of each loop"),
("ALL_OBJECTS", "Selected Mesh Object", "Average space UVs edge length of each loop")
),
- name="Selection",
- description="")
+ )
# Image & UVs...
- PREF_PACK_IN_ONE = BoolProperty(name="Share Tex Space", default=True, description="Objects Share texture space, map all objects into 1 uvmap")
- PREF_NEW_UVLAYER = BoolProperty(name="New UV Layer", default=False, description="Create a new UV layer for every mesh packed")
- PREF_APPLY_IMAGE = BoolProperty(name="New Image", default=False, description="Assign new images for every mesh (only one if shared tex space enabled)")
- PREF_IMG_PX_SIZE = IntProperty(name="Image Size", min=64, max=5000, default=512, description="Width and Height for the new image")
-
+ PREF_PACK_IN_ONE = BoolProperty(
+ name="Share Tex Space",
+ description=("Objects Share texture space, map all objects "
+ "into 1 uvmap"),
+ default=True,
+ )
+ PREF_NEW_UVLAYER = BoolProperty(
+ name="New UV Layer",
+ description="Create a new UV layer for every mesh packed",
+ default=False,
+ )
+ PREF_APPLY_IMAGE = BoolProperty(
+ name="New Image",
+ description=("Assign new images for every mesh (only one if "
+ "shared tex space enabled)"),
+ default=False,
+ )
+ PREF_IMG_PX_SIZE = IntProperty(
+ name="Image Size",
+ description="Width and Height for the new image",
+ min=64, max=5000,
+ default=512,
+ )
# UV Packing...
- PREF_BOX_DIV = IntProperty(name="Pack Quality", min=1, max=48, default=12, description="Pre Packing before the complex boxpack")
- PREF_MARGIN_DIV = FloatProperty(name="Margin", min=0.001, max=1.0, default=0.1, description="Size of the margin as a division of the UV")
+ PREF_BOX_DIV = IntProperty(
+ name="Pack Quality",
+ description="Pre Packing before the complex boxpack",
+ min=1, max=48,
+ default=12,
+ )
+ PREF_MARGIN_DIV = FloatProperty(
+ name="Margin",
+ description="Size of the margin as a division of the UV",
+ min=0.001, max=1.0,
+ default=0.1,
+ )
def execute(self, context):
kwargs = self.as_keywords()
diff --git a/release/scripts/startup/bl_operators/uvcalc_smart_project.py b/release/scripts/startup/bl_operators/uvcalc_smart_project.py
index 4f5b1d8b233..23838588f43 100644
--- a/release/scripts/startup/bl_operators/uvcalc_smart_project.py
+++ b/release/scripts/startup/bl_operators/uvcalc_smart_project.py
@@ -16,10 +16,11 @@
#
# ##### END GPL LICENSE BLOCK #####
-# <pep8 compliant>
+# TODO <pep8 compliant>
from mathutils import Matrix, Vector, geometry
import bpy
+from bpy.types import Operator
DEG_TO_RAD = 0.017453292519943295 # pi/180.0
SMALL_NUM = 0.000000001
@@ -177,7 +178,7 @@ def pointInEdges(pt, edges):
intersectCount = 0
for ed in edges:
xi, yi = lineIntersection2D(x1,y1, x2,y2, ed[0][0], ed[0][1], ed[1][0], ed[1][1])
- if xi != None: # Is there an intersection.
+ if xi is not None: # Is there an intersection.
intersectCount+=1
return intersectCount % 2
@@ -243,7 +244,7 @@ def testNewVecLs2DRotIsBetter(vecs, mat=-1, bestAreaSoFar = -1):
# Do this allong the way
if mat != -1:
- v = vecs[i] = v*mat
+ v = vecs[i] = mat * v
x= v.x
y= v.y
if x<minx: minx= x
@@ -746,13 +747,9 @@ def packIslands(islandList):
uv.y= (uv.y+yoffset) * yfactor
-
def VectoQuat(vec):
vec = vec.normalized()
- if abs(vec.x) > 0.5:
- return vec.to_track_quat('Z', 'X')
- else:
- return vec.to_track_quat('Z', 'Y')
+ return vec.to_track_quat('Z', 'X' if abs(vec.x) > 0.5 else 'Y').inverted()
class thickface(object):
@@ -791,7 +788,11 @@ def main_consts():
global ob
ob = None
-def main(context, island_margin, projection_limit):
+def main(context,
+ island_margin,
+ projection_limit,
+ user_area_weight,
+ ):
global USER_FILL_HOLES
global USER_FILL_HOLES_QUALITY
global USER_STRETCH_ASPECT
@@ -812,35 +813,25 @@ def main(context, island_margin, projection_limit):
global RotMatStepRotation
main_consts()
-#XXX objects= bpy.data.scenes.active.objects
- objects = context.selected_editable_objects
-
-
- # we can will tag them later.
- obList = [ob for ob in objects if ob.type == 'MESH']
-
- # Face select object may not be selected.
-#XXX ob = objects.active
- ob= objects[0]
-
- if ob and (not ob.select) and ob.type == 'MESH':
- # Add to the list
- obList =[ob]
- del objects
-
- if not obList:
- raise('error, no selected mesh objects')
-
# Create the variables.
USER_PROJECTION_LIMIT = projection_limit
- USER_ONLY_SELECTED_FACES = (1)
- USER_SHARE_SPACE = (1) # Only for hole filling.
- USER_STRETCH_ASPECT = (1) # Only for hole filling.
+ USER_ONLY_SELECTED_FACES = True
+ USER_SHARE_SPACE = 1 # Only for hole filling.
+ USER_STRETCH_ASPECT = 1 # Only for hole filling.
USER_ISLAND_MARGIN = island_margin # Only for hole filling.
- USER_FILL_HOLES = (0)
- USER_FILL_HOLES_QUALITY = (50) # Only for hole filling.
- USER_VIEW_INIT = (0) # Only for hole filling.
- USER_AREA_WEIGHT = (1) # Only for hole filling.
+ USER_FILL_HOLES = 0
+ USER_FILL_HOLES_QUALITY = 50 # Only for hole filling.
+ USER_VIEW_INIT = 0 # Only for hole filling.
+
+ is_editmode = (context.active_object.mode == 'EDIT')
+ if is_editmode:
+ obList = [ob for ob in [context.active_object] if ob and ob.type == 'MESH']
+ else:
+ obList = [ob for ob in context.selected_editable_objects if ob and ob.type == 'MESH']
+ USER_ONLY_SELECTED_FACES = False
+
+ if not obList:
+ raise('error, no selected mesh objects')
# Reuse variable
if len(obList) == 1:
@@ -902,8 +893,8 @@ def main(context, island_margin, projection_limit):
if USER_ONLY_SELECTED_FACES:
meshFaces = [thickface(f, uv_layer[i], me_verts) for i, f in enumerate(me.faces) if f.select]
- #else:
- # meshFaces = map(thickface, me.faces)
+ else:
+ meshFaces = [thickface(f, uv_layer[i], me_verts) for i, f in enumerate(me.faces)]
if not meshFaces:
continue
@@ -918,7 +909,7 @@ def main(context, island_margin, projection_limit):
# meshFaces = []
# meshFaces.sort( lambda a, b: cmp(b.area , a.area) ) # Biggest first.
- meshFaces.sort( key = lambda a: -a.area )
+ meshFaces.sort(key=lambda a: -a.area)
# remove all zero area faces
while meshFaces and meshFaces[-1].area <= SMALL_NUM:
@@ -966,12 +957,15 @@ def main(context, island_margin, projection_limit):
# Add the average of all these faces normals as a projectionVec
averageVec = Vector((0.0, 0.0, 0.0))
- if USER_AREA_WEIGHT:
+ if user_area_weight == 0.0:
for fprop in newProjectMeshFaces:
- averageVec += (fprop.no * fprop.area)
+ averageVec += fprop.no
+ elif user_area_weight == 1.0:
+ for fprop in newProjectMeshFaces:
+ averageVec += fprop.no * fprop.area
else:
for fprop in newProjectMeshFaces:
- averageVec += fprop.no
+ averageVec += fprop.no * ((fprop.area * user_area_weight) + (1.0 - user_area_weight))
if averageVec.x != 0 or averageVec.y != 0 or averageVec.z != 0: # Avoid NAN
projectVecs.append(averageVec.normalized())
@@ -1058,7 +1052,7 @@ def main(context, island_margin, projection_limit):
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][:] = (v.co * MatQuat)[:2]
+ f_uv[j][:] = (MatQuat * v.co).xy
if USER_SHARE_SPACE:
@@ -1094,12 +1088,8 @@ def main(context, island_margin, projection_limit):
"""
pup_block = [\
'Projection',\
-* ('Angle Limit:', USER_PROJECTION_LIMIT, 1, 89, ''),\
('Selected Faces Only', USER_ONLY_SELECTED_FACES, 'Use only selected faces from all selected meshes.'),\
('Init from view', USER_VIEW_INIT, 'The first projection will be from the view vector.'),\
- ('Area Weight', USER_AREA_WEIGHT, 'Weight projections vector by face area.'),\
- '',\
- '',\
'',\
'UV Layout',\
('Share Tex Space', USER_SHARE_SPACE, 'Objects Share texture space, map all objects into 1 uvmap.'),\
@@ -1114,26 +1104,41 @@ def main(context, island_margin, projection_limit):
from bpy.props import FloatProperty
-class SmartProject(bpy.types.Operator):
+class SmartProject(Operator):
'''This script projection unwraps the selected faces of a mesh. it operates on all selected mesh objects, and can be used unwrap selected faces, or all faces.'''
bl_idname = "uv.smart_project"
bl_label = "Smart UV Project"
bl_options = {'REGISTER', 'UNDO'}
- angle_limit = FloatProperty(name="Angle Limit",
- description="lower for more projection groups, higher for less distortion.",
- default=66.0, min=1.0, max=89.0)
-
- island_margin = FloatProperty(name="Island Margin",
- description="Margin to reduce bleed from adjacent islands.",
- default=0.0, min=0.0, max=1.0)
+ angle_limit = FloatProperty(
+ name="Angle Limit",
+ description="lower for more projection groups, higher for less distortion",
+ min=1.0, max=89.0,
+ default=66.0,
+ )
+ island_margin = FloatProperty(
+ name="Island Margin",
+ description="Margin to reduce bleed from adjacent islands",
+ min=0.0, max=1.0,
+ default=0.0,
+ )
+ user_area_weight = FloatProperty(
+ name="Area Weight",
+ description="Weight projections vector by faces with larger areas",
+ min=0.0, max=1.0,
+ default=0.0,
+ )
@classmethod
def poll(cls, context):
- return context.active_object != None
+ return context.active_object is not None
def execute(self, context):
- main(context, self.island_margin, self.angle_limit)
+ main(context,
+ self.island_margin,
+ self.angle_limit,
+ self.user_area_weight,
+ )
return {'FINISHED'}
def invoke(self, context, event):
diff --git a/release/scripts/startup/bl_operators/vertexpaint_dirt.py b/release/scripts/startup/bl_operators/vertexpaint_dirt.py
index 672db71e361..4c78adb7161 100644
--- a/release/scripts/startup/bl_operators/vertexpaint_dirt.py
+++ b/release/scripts/startup/bl_operators/vertexpaint_dirt.py
@@ -142,19 +142,44 @@ def applyVertexDirt(me, blur_iterations, blur_strength, clamp_dirt, clamp_clean,
import bpy
+from bpy.types import Operator
from bpy.props import FloatProperty, IntProperty, BoolProperty
-class VertexPaintDirt(bpy.types.Operator):
+class VertexPaintDirt(Operator):
bl_idname = "paint.vertex_color_dirt"
bl_label = "Dirty Vertex Colors"
bl_options = {'REGISTER', 'UNDO'}
- blur_strength = FloatProperty(name="Blur Strength", description="Blur strength per iteration", default=1.0, min=0.01, max=1.0)
- blur_iterations = IntProperty(name="Blur Iterations", description="Number times to blur the colors. (higher blurs more)", default=1, min=0, max=40)
- clean_angle = FloatProperty(name="Highlight Angle", description="Less then 90 limits the angle used in the tonal range", default=180.0, min=0.0, max=180.0)
- dirt_angle = FloatProperty(name="Dirt Angle", description="Less then 90 limits the angle used in the tonal range", default=0.0, min=0.0, max=180.0)
- dirt_only = BoolProperty(name="Dirt Only", description="Dont calculate cleans for convex areas", default=False)
+ blur_strength = FloatProperty(
+ name="Blur Strength",
+ description="Blur strength per iteration",
+ min=0.01, max=1.0,
+ default=1.0,
+ )
+ blur_iterations = IntProperty(
+ name="Blur Iterations",
+ description="Number times to blur the colors. (higher blurs more)",
+ min=0, max=40,
+ default=1,
+ )
+ clean_angle = FloatProperty(
+ name="Highlight Angle",
+ description="Less then 90 limits the angle used in the tonal range",
+ min=0.0, max=180.0,
+ default=180.0,
+ )
+ dirt_angle = FloatProperty(
+ name="Dirt Angle",
+ description="Less then 90 limits the angle used in the tonal range",
+ min=0.0, max=180.0,
+ default=0.0,
+ )
+ dirt_only = BoolProperty(
+ name="Dirt Only",
+ description="Dont calculate cleans for convex areas",
+ default=False,
+ )
def execute(self, context):
import time
diff --git a/release/scripts/startup/bl_operators/wm.py b/release/scripts/startup/bl_operators/wm.py
index fcc30ecbb4b..aa09a088c4f 100644
--- a/release/scripts/startup/bl_operators/wm.py
+++ b/release/scripts/startup/bl_operators/wm.py
@@ -19,11 +19,18 @@
# <pep8 compliant>
import bpy
-from bpy.props import StringProperty, BoolProperty, IntProperty, FloatProperty
+from bpy.types import Menu, Operator
+from bpy.props import (StringProperty,
+ BoolProperty,
+ IntProperty,
+ FloatProperty,
+ EnumProperty,
+ )
+
from rna_prop_ui import rna_idprop_ui_prop_get, rna_idprop_ui_prop_clear
-class MESH_OT_delete_edgeloop(bpy.types.Operator):
+class MESH_OT_delete_edgeloop(Operator):
'''Delete an edge loop by merging the faces on each side to a single face loop'''
bl_idname = "mesh.delete_edgeloop"
bl_label = "Delete Edge Loop"
@@ -36,23 +43,30 @@ class MESH_OT_delete_edgeloop(bpy.types.Operator):
return {'CANCELLED'}
-rna_path_prop = StringProperty(name="Context Attributes",
- description="rna context string", maxlen=1024, default="")
+rna_path_prop = StringProperty(
+ name="Context Attributes",
+ description="rna context string",
+ maxlen=1024,
+ )
-rna_reverse_prop = BoolProperty(name="Reverse",
- description="Cycle backwards", default=False)
+rna_reverse_prop = BoolProperty(
+ name="Reverse",
+ description="Cycle backwards",
+ default=False,
+ )
-rna_relative_prop = BoolProperty(name="Relative",
+rna_relative_prop = BoolProperty(
+ name="Relative",
description="Apply relative to the current value (delta)",
- default=False)
+ default=False,
+ )
def context_path_validate(context, data_path):
- import sys
try:
value = eval("context.%s" % data_path) if data_path else Ellipsis
- except AttributeError:
- if "'NoneType'" in str(sys.exc_info()[1]):
+ except AttributeError as e:
+ if str(e).startswith("'NoneType'"):
# One of the items in the rna path is None, just ignore this
value = Ellipsis
else:
@@ -62,32 +76,87 @@ def context_path_validate(context, data_path):
return value
+def operator_value_is_undo(value):
+ if value in {None, Ellipsis}:
+ return False
+
+ # typical properties or objects
+ id_data = getattr(value, "id_data", Ellipsis)
+
+ if id_data is None:
+ return False
+ elif id_data is Ellipsis:
+ # handle mathutils types
+ id_data = getattr(getattr(value, "owner", None), "id_data", None)
+
+ if id_data is None:
+ return False
+
+ # return True if its a non window ID type
+ return (isinstance(id_data, bpy.types.ID) and
+ (not isinstance(id_data, (bpy.types.WindowManager,
+ bpy.types.Screen,
+ bpy.types.Scene,
+ bpy.types.Brush,
+ ))))
+
+
+def operator_path_is_undo(context, data_path):
+ # note that if we have data paths that use strings this could fail
+ # luckily we dont do this!
+ #
+ # When we cant find the data owner assume no undo is needed.
+ data_path_head, data_path_sep, data_path_tail = data_path.rpartition(".")
+
+ if not data_path_head:
+ return False
+
+ value = context_path_validate(context, data_path_head)
+
+ return operator_value_is_undo(value)
+
+
+def operator_path_undo_return(context, data_path):
+ return {'FINISHED'} if operator_path_is_undo(context, data_path) else {'CANCELLED'}
+
+
+def operator_value_undo_return(value):
+ return {'FINISHED'} if operator_value_is_undo(value) else {'CANCELLED'}
+
+
def execute_context_assign(self, context):
- if context_path_validate(context, self.data_path) is Ellipsis:
+ data_path = self.data_path
+ if context_path_validate(context, data_path) is Ellipsis:
return {'PASS_THROUGH'}
if getattr(self, "relative", False):
- exec("context.%s+=self.value" % self.data_path)
+ exec("context.%s += self.value" % data_path)
else:
- exec("context.%s=self.value" % self.data_path)
+ exec("context.%s = self.value" % data_path)
- return {'FINISHED'}
+ return operator_path_undo_return(context, data_path)
-class BRUSH_OT_active_index_set(bpy.types.Operator):
+class BRUSH_OT_active_index_set(Operator):
'''Set active sculpt/paint brush from it's number'''
bl_idname = "brush.active_index_set"
bl_label = "Set Brush Number"
- mode = StringProperty(name="mode",
- description="Paint mode to set brush for", maxlen=1024)
- index = IntProperty(name="number",
- description="Brush number")
+ mode = StringProperty(
+ name="mode",
+ description="Paint mode to set brush for",
+ maxlen=1024,
+ )
+ index = IntProperty(
+ name="number",
+ description="Brush number",
+ )
_attr_dict = {"sculpt": "use_paint_sculpt",
"vertex_paint": "use_paint_vertex",
"weight_paint": "use_paint_weight",
- "image_paint": "use_paint_image"}
+ "image_paint": "use_paint_image",
+ }
def execute(self, context):
attr = self._attr_dict.get(self.mode)
@@ -102,50 +171,63 @@ class BRUSH_OT_active_index_set(bpy.types.Operator):
return {'CANCELLED'}
-class WM_OT_context_set_boolean(bpy.types.Operator):
+class WM_OT_context_set_boolean(Operator):
'''Set a context value.'''
bl_idname = "wm.context_set_boolean"
bl_label = "Context Set Boolean"
bl_options = {'UNDO', 'INTERNAL'}
data_path = rna_path_prop
- value = BoolProperty(name="Value",
- description="Assignment value", default=True)
+ value = BoolProperty(
+ name="Value",
+ description="Assignment value",
+ default=True,
+ )
execute = execute_context_assign
-class WM_OT_context_set_int(bpy.types.Operator): # same as enum
+class WM_OT_context_set_int(Operator): # same as enum
'''Set a context value.'''
bl_idname = "wm.context_set_int"
bl_label = "Context Set"
bl_options = {'UNDO', 'INTERNAL'}
data_path = rna_path_prop
- value = IntProperty(name="Value", description="Assign value", default=0)
+ value = IntProperty(
+ name="Value",
+ description="Assign value",
+ default=0,
+ )
relative = rna_relative_prop
execute = execute_context_assign
-class WM_OT_context_scale_int(bpy.types.Operator):
+class WM_OT_context_scale_int(Operator):
'''Scale an int context value.'''
bl_idname = "wm.context_scale_int"
bl_label = "Context Set"
bl_options = {'UNDO', 'INTERNAL'}
data_path = rna_path_prop
- value = FloatProperty(name="Value", description="Assign value", default=1.0)
- always_step = BoolProperty(name="Always Step",
- description="Always adjust the value by a minimum of 1 when 'value' is not 1.0.",
- default=True)
+ value = FloatProperty(
+ name="Value",
+ description="Assign value",
+ default=1.0,
+ )
+ always_step = BoolProperty(
+ name="Always Step",
+ description="Always adjust the value by a minimum of 1 when 'value' is not 1.0.",
+ default=True,
+ )
def execute(self, context):
- if context_path_validate(context, self.data_path) is Ellipsis:
+ data_path = self.data_path
+ if context_path_validate(context, data_path) is Ellipsis:
return {'PASS_THROUGH'}
value = self.value
- data_path = self.data_path
if value == 1.0: # nothing to do
return {'CANCELLED'}
@@ -157,73 +239,85 @@ class WM_OT_context_scale_int(bpy.types.Operator):
else:
add = "-1"
func = "min"
- exec("context.%s = %s(round(context.%s * value), context.%s + %s)" % (data_path, func, data_path, data_path, add))
+ exec("context.%s = %s(round(context.%s * value), context.%s + %s)" %
+ (data_path, func, data_path, data_path, add))
else:
- exec("context.%s *= value" % self.data_path)
+ exec("context.%s *= value" % data_path)
- return {'FINISHED'}
+ return operator_path_undo_return(context, data_path)
-class WM_OT_context_set_float(bpy.types.Operator): # same as enum
+class WM_OT_context_set_float(Operator): # same as enum
'''Set a context value.'''
bl_idname = "wm.context_set_float"
bl_label = "Context Set Float"
bl_options = {'UNDO', 'INTERNAL'}
data_path = rna_path_prop
- value = FloatProperty(name="Value",
- description="Assignment value", default=0.0)
+ value = FloatProperty(
+ name="Value",
+ description="Assignment value",
+ default=0.0,
+ )
relative = rna_relative_prop
execute = execute_context_assign
-class WM_OT_context_set_string(bpy.types.Operator): # same as enum
+class WM_OT_context_set_string(Operator): # same as enum
'''Set a context value.'''
bl_idname = "wm.context_set_string"
bl_label = "Context Set String"
bl_options = {'UNDO', 'INTERNAL'}
data_path = rna_path_prop
- value = StringProperty(name="Value",
- description="Assign value", maxlen=1024, default="")
+ value = StringProperty(
+ name="Value",
+ description="Assign value",
+ maxlen=1024,
+ )
execute = execute_context_assign
-class WM_OT_context_set_enum(bpy.types.Operator):
+class WM_OT_context_set_enum(Operator):
'''Set a context value.'''
bl_idname = "wm.context_set_enum"
bl_label = "Context Set Enum"
bl_options = {'UNDO', 'INTERNAL'}
data_path = rna_path_prop
- value = StringProperty(name="Value",
+ value = StringProperty(
+ name="Value",
description="Assignment value (as a string)",
- maxlen=1024, default="")
+ maxlen=1024,
+ )
execute = execute_context_assign
-class WM_OT_context_set_value(bpy.types.Operator):
+class WM_OT_context_set_value(Operator):
'''Set a context value.'''
bl_idname = "wm.context_set_value"
bl_label = "Context Set Value"
bl_options = {'UNDO', 'INTERNAL'}
data_path = rna_path_prop
- value = StringProperty(name="Value",
+ value = StringProperty(
+ name="Value",
description="Assignment value (as a string)",
- maxlen=1024, default="")
+ maxlen=1024,
+ )
def execute(self, context):
- if context_path_validate(context, self.data_path) is Ellipsis:
+ data_path = self.data_path
+ if context_path_validate(context, data_path) is Ellipsis:
return {'PASS_THROUGH'}
- exec("context.%s=%s" % (self.data_path, self.value))
- return {'FINISHED'}
+ exec("context.%s = %s" % (data_path, self.value))
+ return operator_path_undo_return(context, data_path)
-class WM_OT_context_toggle(bpy.types.Operator):
+class WM_OT_context_toggle(Operator):
'''Toggle a context value.'''
bl_idname = "wm.context_toggle"
bl_label = "Context Toggle"
@@ -232,43 +326,50 @@ class WM_OT_context_toggle(bpy.types.Operator):
data_path = rna_path_prop
def execute(self, context):
+ data_path = self.data_path
- if context_path_validate(context, self.data_path) is Ellipsis:
+ if context_path_validate(context, data_path) is Ellipsis:
return {'PASS_THROUGH'}
- exec("context.%s=not (context.%s)" %
- (self.data_path, self.data_path))
+ exec("context.%s = not (context.%s)" % (data_path, data_path))
- return {'FINISHED'}
+ return operator_path_undo_return(context, data_path)
-class WM_OT_context_toggle_enum(bpy.types.Operator):
+class WM_OT_context_toggle_enum(Operator):
'''Toggle a context value.'''
bl_idname = "wm.context_toggle_enum"
bl_label = "Context Toggle Values"
bl_options = {'UNDO', 'INTERNAL'}
data_path = rna_path_prop
- value_1 = StringProperty(name="Value", \
- description="Toggle enum", maxlen=1024, default="")
-
- value_2 = StringProperty(name="Value", \
- description="Toggle enum", maxlen=1024, default="")
+ value_1 = StringProperty(
+ name="Value",
+ description="Toggle enum",
+ maxlen=1024,
+ )
+ value_2 = StringProperty(
+ name="Value",
+ description="Toggle enum",
+ maxlen=1024,
+ )
def execute(self, context):
+ data_path = self.data_path
- if context_path_validate(context, self.data_path) is Ellipsis:
+ if context_path_validate(context, data_path) is Ellipsis:
return {'PASS_THROUGH'}
- exec("context.%s = ['%s', '%s'][context.%s!='%s']" % \
- (self.data_path, self.value_1,\
- self.value_2, self.data_path,
- self.value_2))
+ exec("context.%s = ('%s', '%s')[context.%s != '%s']" %
+ (data_path, self.value_1,
+ self.value_2, data_path,
+ self.value_2,
+ ))
- return {'FINISHED'}
+ return operator_path_undo_return(context, data_path)
-class WM_OT_context_cycle_int(bpy.types.Operator):
+class WM_OT_context_cycle_int(Operator):
'''Set a context value. Useful for cycling active material, '''
'''vertex keys, groups' etc.'''
bl_idname = "wm.context_cycle_int"
@@ -289,7 +390,7 @@ class WM_OT_context_cycle_int(bpy.types.Operator):
else:
value += 1
- exec("context.%s=value" % data_path)
+ exec("context.%s = value" % data_path)
if value != eval("context.%s" % data_path):
# relies on rna clamping int's out of the range
@@ -298,12 +399,12 @@ class WM_OT_context_cycle_int(bpy.types.Operator):
else:
value = -1 << 31
- exec("context.%s=value" % data_path)
+ exec("context.%s = value" % data_path)
- return {'FINISHED'}
+ return operator_path_undo_return(context, data_path)
-class WM_OT_context_cycle_enum(bpy.types.Operator):
+class WM_OT_context_cycle_enum(Operator):
'''Toggle a context value.'''
bl_idname = "wm.context_cycle_enum"
bl_label = "Context Enum Cycle"
@@ -313,15 +414,15 @@ class WM_OT_context_cycle_enum(bpy.types.Operator):
reverse = rna_reverse_prop
def execute(self, context):
-
- value = context_path_validate(context, self.data_path)
+ data_path = self.data_path
+ value = context_path_validate(context, data_path)
if value is Ellipsis:
return {'PASS_THROUGH'}
orig_value = value
# Have to get rna enum values
- rna_struct_str, rna_prop_str = self.data_path.rsplit('.', 1)
+ rna_struct_str, rna_prop_str = data_path.rsplit('.', 1)
i = rna_prop_str.find('[')
# just incse we get "context.foo.bar[0]"
@@ -351,11 +452,11 @@ class WM_OT_context_cycle_enum(bpy.types.Operator):
advance_enum = enums[orig_index + 1]
# set the new value
- exec("context.%s=advance_enum" % self.data_path)
- return {'FINISHED'}
+ exec("context.%s = advance_enum" % data_path)
+ return operator_path_undo_return(context, data_path)
-class WM_OT_context_cycle_array(bpy.types.Operator):
+class WM_OT_context_cycle_array(Operator):
'''Set a context array value.
Useful for cycling the active mesh edit mode.'''
bl_idname = "wm.context_cycle_array"
@@ -378,12 +479,12 @@ class WM_OT_context_cycle_array(bpy.types.Operator):
array.append(array.pop(0))
return array
- exec("context.%s=cycle(context.%s[:])" % (data_path, data_path))
+ exec("context.%s = cycle(context.%s[:])" % (data_path, data_path))
- return {'FINISHED'}
+ return operator_path_undo_return(context, data_path)
-class WM_MT_context_menu_enum(bpy.types.Menu):
+class WM_MT_context_menu_enum(Menu):
bl_label = ""
data_path = "" # BAD DESIGN, set from operator below.
@@ -403,7 +504,7 @@ class WM_MT_context_menu_enum(bpy.types.Menu):
prop.value = identifier
-class WM_OT_context_menu_enum(bpy.types.Operator):
+class WM_OT_context_menu_enum(Operator):
bl_idname = "wm.context_menu_enum"
bl_label = "Context Enum Menu"
bl_options = {'UNDO', 'INTERNAL'}
@@ -416,15 +517,18 @@ class WM_OT_context_menu_enum(bpy.types.Operator):
return {'PASS_THROUGH'}
-class WM_OT_context_set_id(bpy.types.Operator):
+class WM_OT_context_set_id(Operator):
'''Toggle a context value.'''
bl_idname = "wm.context_set_id"
bl_label = "Set Library ID"
bl_options = {'UNDO', 'INTERNAL'}
data_path = rna_path_prop
- value = StringProperty(name="Value",
- description="Assign value", maxlen=1024, default="")
+ value = StringProperty(
+ name="Value",
+ description="Assign value",
+ maxlen=1024,
+ )
def execute(self, context):
value = self.value
@@ -446,28 +550,105 @@ class WM_OT_context_set_id(bpy.types.Operator):
if id_iter:
value_id = getattr(bpy.data, id_iter).get(value)
- exec("context.%s=value_id" % data_path)
+ exec("context.%s = value_id" % data_path)
- return {'FINISHED'}
+ return operator_path_undo_return(context, data_path)
+
+
+doc_id = StringProperty(
+ name="Doc ID",
+ maxlen=1024,
+ options={'HIDDEN'},
+ )
+
+doc_new = StringProperty(
+ name="Edit Description",
+ maxlen=1024,
+ )
+
+data_path_iter = StringProperty(
+ description="The data path relative to the context, must point to an iterable.")
+
+data_path_item = StringProperty(
+ description="The data path from each iterable to the value (int or float)")
+
+
+class WM_OT_context_collection_boolean_set(Operator):
+ '''Set boolean values for a collection of items'''
+ bl_idname = "wm.context_collection_boolean_set"
+ bl_label = "Context Collection Boolean Set"
+ bl_options = {'UNDO', 'REGISTER', 'INTERNAL'}
+ data_path_iter = data_path_iter
+ data_path_item = data_path_item
-doc_id = StringProperty(name="Doc ID",
- description="", maxlen=1024, default="", options={'HIDDEN'})
+ type = EnumProperty(
+ name="Type",
+ items=(('TOGGLE', "Toggle", ""),
+ ('ENABLE', "Enable", ""),
+ ('DISABLE', "Disable", ""),
+ ),
+ )
-doc_new = StringProperty(name="Edit Description",
- description="", maxlen=1024, default="")
+ def execute(self, context):
+ data_path_iter = self.data_path_iter
+ data_path_item = self.data_path_item
+
+ items = list(getattr(context, data_path_iter))
+ items_ok = []
+ is_set = False
+ for item in items:
+ try:
+ value_orig = eval("item." + data_path_item)
+ except:
+ continue
+
+ if value_orig == True:
+ is_set = True
+ elif value_orig == False:
+ pass
+ else:
+ self.report({'WARNING'}, "Non boolean value found: %s[ ].%s" %
+ (data_path_iter, data_path_item))
+ return {'CANCELLED'}
+
+ items_ok.append(item)
+
+ # avoid undo push when nothing to do
+ if not items_ok:
+ return {'CANCELLED'}
+
+ if self.type == 'ENABLE':
+ is_set = True
+ elif self.type == 'DISABLE':
+ is_set = False
+ else:
+ is_set = not is_set
+
+ exec_str = "item.%s = %s" % (data_path_item, is_set)
+ for item in items_ok:
+ exec(exec_str)
+
+ return operator_value_undo_return(item)
-class WM_OT_context_modal_mouse(bpy.types.Operator):
+class WM_OT_context_modal_mouse(Operator):
'''Adjust arbitrary values with mouse input'''
bl_idname = "wm.context_modal_mouse"
bl_label = "Context Modal Mouse"
- bl_options = {'INTERNAL'}
-
- data_path_iter = StringProperty(description="The data path relative to the context, must point to an iterable.")
- data_path_item = StringProperty(description="The data path from each iterable to the value (int or float)")
- input_scale = FloatProperty(default=0.01, description="Scale the mouse movement by this value before applying the delta")
- invert = BoolProperty(default=False, description="Invert the mouse input")
+ bl_options = {'GRAB_POINTER', 'BLOCKING', 'UNDO', 'INTERNAL'}
+
+ data_path_iter = data_path_iter
+ data_path_item = data_path_item
+
+ input_scale = FloatProperty(
+ description="Scale the mouse movement by this value before applying the delta",
+ default=0.01,
+ )
+ invert = BoolProperty(
+ description="Invert the mouse input",
+ default=False,
+ )
initial_x = IntProperty(options={'HIDDEN'})
def _values_store(self, context):
@@ -520,12 +701,13 @@ class WM_OT_context_modal_mouse(bpy.types.Operator):
self._values_delta(delta)
elif 'LEFTMOUSE' == event_type:
+ item = next(iter(self._values.keys()))
self._values_clear()
- return {'FINISHED'}
+ return operator_value_undo_return(item)
- elif event_type in ('RIGHTMOUSE', 'ESC'):
+ elif event_type in {'RIGHTMOUSE', 'ESC'}:
self._values_restore()
- return {'FINISHED'}
+ return {'CANCELLED'}
return {'RUNNING_MODAL'}
@@ -544,26 +726,32 @@ class WM_OT_context_modal_mouse(bpy.types.Operator):
return {'RUNNING_MODAL'}
-class WM_OT_url_open(bpy.types.Operator):
+class WM_OT_url_open(Operator):
"Open a website in the Webbrowser"
bl_idname = "wm.url_open"
bl_label = ""
- url = StringProperty(name="URL", description="URL to open")
+ url = StringProperty(
+ name="URL",
+ description="URL to open",
+ )
def execute(self, context):
import webbrowser
- _webbrowser_bug_fix()
webbrowser.open(self.url)
return {'FINISHED'}
-class WM_OT_path_open(bpy.types.Operator):
+class WM_OT_path_open(Operator):
"Open a path in a file browser"
bl_idname = "wm.path_open"
bl_label = ""
- filepath = StringProperty(name="File Path", maxlen=1024, subtype='FILE_PATH')
+ filepath = StringProperty(
+ name="File Path",
+ maxlen=1024,
+ subtype='FILE_PATH',
+ )
def execute(self, context):
import sys
@@ -591,16 +779,18 @@ class WM_OT_path_open(bpy.types.Operator):
return {'FINISHED'}
-class WM_OT_doc_view(bpy.types.Operator):
+class WM_OT_doc_view(Operator):
'''Load online reference docs'''
bl_idname = "wm.doc_view"
bl_label = "View Documentation"
doc_id = doc_id
if bpy.app.version_cycle == "release":
- _prefix = "http://www.blender.org/documentation/blender_python_api_%s%s_release" % ("_".join(str(v) for v in bpy.app.version[:2]), bpy.app.version_char)
+ _prefix = ("http://www.blender.org/documentation/blender_python_api_%s%s_release" %
+ ("_".join(str(v) for v in bpy.app.version[:2]), bpy.app.version_char))
else:
- _prefix = "http://www.blender.org/documentation/blender_python_api_%s" % "_".join(str(v) for v in bpy.app.version)
+ _prefix = ("http://www.blender.org/documentation/blender_python_api_%s" %
+ "_".join(str(v) for v in bpy.app.version))
def _nested_class_string(self, class_string):
ls = []
@@ -618,8 +808,8 @@ class WM_OT_doc_view(bpy.types.Operator):
class_name, class_prop = id_split
if hasattr(bpy.types, class_name.upper() + '_OT_' + class_prop):
- url = '%s/bpy.ops.%s.html#bpy.ops.%s.%s' % \
- (self._prefix, class_name, class_name, class_prop)
+ url = ("%s/bpy.ops.%s.html#bpy.ops.%s.%s" %
+ (self._prefix, class_name, class_name, class_prop))
else:
# detect if this is a inherited member and use that name instead
@@ -632,20 +822,19 @@ class WM_OT_doc_view(bpy.types.Operator):
# It so happens that epydoc nests these, not sphinx
# class_name_full = self._nested_class_string(class_name)
- url = '%s/bpy.types.%s.html#bpy.types.%s.%s' % \
- (self._prefix, class_name, class_name, class_prop)
+ url = ("%s/bpy.types.%s.html#bpy.types.%s.%s" %
+ (self._prefix, class_name, class_name, class_prop))
else:
return {'PASS_THROUGH'}
import webbrowser
- _webbrowser_bug_fix()
webbrowser.open(url)
return {'FINISHED'}
-class WM_OT_doc_edit(bpy.types.Operator):
+class WM_OT_doc_edit(Operator):
'''Load online reference docs'''
bl_idname = "wm.doc_edit"
bl_label = "Edit Documentation"
@@ -716,20 +905,39 @@ class WM_OT_doc_edit(bpy.types.Operator):
return wm.invoke_props_dialog(self, width=600)
-rna_path = StringProperty(name="Property Edit",
- description="Property data_path edit", maxlen=1024, default="", options={'HIDDEN'})
+rna_path = StringProperty(
+ name="Property Edit",
+ description="Property data_path edit",
+ maxlen=1024,
+ options={'HIDDEN'},
+ )
+
+rna_value = StringProperty(
+ name="Property Value",
+ description="Property value edit",
+ maxlen=1024,
+ )
-rna_value = StringProperty(name="Property Value",
- description="Property value edit", maxlen=1024, default="")
+rna_property = StringProperty(
+ name="Property Name",
+ description="Property name edit",
+ maxlen=1024,
+ )
-rna_property = StringProperty(name="Property Name",
- description="Property name edit", maxlen=1024, default="")
+rna_min = FloatProperty(
+ name="Min",
+ default=0.0,
+ precision=3,
+ )
-rna_min = FloatProperty(name="Min", default=0.0, precision=3)
-rna_max = FloatProperty(name="Max", default=1.0, precision=3)
+rna_max = FloatProperty(
+ name="Max",
+ default=1.0,
+ precision=3,
+ )
-class WM_OT_properties_edit(bpy.types.Operator):
+class WM_OT_properties_edit(Operator):
'''Internal use (edit a property data_path)'''
bl_idname = "wm.properties_edit"
bl_label = "Edit Property"
@@ -740,7 +948,9 @@ class WM_OT_properties_edit(bpy.types.Operator):
value = rna_value
min = rna_min
max = rna_max
- description = StringProperty(name="Tip", default="")
+ description = StringProperty(
+ name="Tip",
+ )
def execute(self, context):
data_path = self.data_path
@@ -776,7 +986,7 @@ class WM_OT_properties_edit(bpy.types.Operator):
prop_ui = rna_idprop_ui_prop_get(item, prop)
- if prop_type in (float, int):
+ if prop_type in {float, int}:
prop_ui['soft_min'] = prop_ui['min'] = prop_type(self.min)
prop_ui['soft_max'] = prop_ui['max'] = prop_type(self.max)
@@ -793,14 +1003,15 @@ class WM_OT_properties_edit(bpy.types.Operator):
return {'FINISHED'}
def invoke(self, context, event):
+ data_path = self.data_path
- if not self.data_path:
+ if not data_path:
self.report({'ERROR'}, "Data path not set")
return {'CANCELLED'}
self._last_prop = [self.property]
- item = eval("context.%s" % self.data_path)
+ item = eval("context.%s" % data_path)
# setup defaults
prop_ui = rna_idprop_ui_prop_get(item, self.property, False) # dont create
@@ -813,7 +1024,7 @@ class WM_OT_properties_edit(bpy.types.Operator):
return wm.invoke_props_dialog(self)
-class WM_OT_properties_add(bpy.types.Operator):
+class WM_OT_properties_add(Operator):
'''Internal use (edit a property data_path)'''
bl_idname = "wm.properties_add"
bl_label = "Add Property"
@@ -821,7 +1032,8 @@ class WM_OT_properties_add(bpy.types.Operator):
data_path = rna_path
def execute(self, context):
- item = eval("context.%s" % self.data_path)
+ data_path = self.data_path
+ item = eval("context.%s" % data_path)
def unique_name(names):
prop = 'prop'
@@ -839,19 +1051,22 @@ class WM_OT_properties_add(bpy.types.Operator):
return {'FINISHED'}
-class WM_OT_properties_context_change(bpy.types.Operator):
+class WM_OT_properties_context_change(Operator):
"Change the context tab in a Properties Window"
bl_idname = "wm.properties_context_change"
bl_label = ""
- context = StringProperty(name="Context", maxlen=32)
+ context = StringProperty(
+ name="Context",
+ maxlen=32,
+ )
def execute(self, context):
- context.space_data.context = (self.context)
+ context.space_data.context = self.context
return {'FINISHED'}
-class WM_OT_properties_remove(bpy.types.Operator):
+class WM_OT_properties_remove(Operator):
'''Internal use (edit a property data_path)'''
bl_idname = "wm.properties_remove"
bl_label = "Remove Property"
@@ -860,23 +1075,27 @@ class WM_OT_properties_remove(bpy.types.Operator):
property = rna_property
def execute(self, context):
- item = eval("context.%s" % self.data_path)
+ data_path = self.data_path
+ item = eval("context.%s" % data_path)
del item[self.property]
return {'FINISHED'}
-class WM_OT_keyconfig_activate(bpy.types.Operator):
+class WM_OT_keyconfig_activate(Operator):
bl_idname = "wm.keyconfig_activate"
bl_label = "Activate Keyconfig"
- filepath = StringProperty(name="File Path", maxlen=1024)
+ filepath = StringProperty(
+ name="File Path",
+ maxlen=1024,
+ )
def execute(self, context):
bpy.utils.keyconfig_set(self.filepath)
return {'FINISHED'}
-class WM_OT_appconfig_default(bpy.types.Operator):
+class WM_OT_appconfig_default(Operator):
bl_idname = "wm.appconfig_default"
bl_label = "Default Application Configuration"
@@ -893,11 +1112,14 @@ class WM_OT_appconfig_default(bpy.types.Operator):
return {'FINISHED'}
-class WM_OT_appconfig_activate(bpy.types.Operator):
+class WM_OT_appconfig_activate(Operator):
bl_idname = "wm.appconfig_activate"
bl_label = "Activate Application Configuration"
- filepath = StringProperty(name="File Path", maxlen=1024)
+ filepath = StringProperty(
+ name="File Path",
+ maxlen=1024,
+ )
def execute(self, context):
import os
@@ -911,7 +1133,7 @@ class WM_OT_appconfig_activate(bpy.types.Operator):
return {'FINISHED'}
-class WM_OT_sysinfo(bpy.types.Operator):
+class WM_OT_sysinfo(Operator):
'''Generate System Info'''
bl_idname = "wm.sysinfo"
bl_label = "System Info"
@@ -922,7 +1144,7 @@ class WM_OT_sysinfo(bpy.types.Operator):
return {'FINISHED'}
-class WM_OT_copy_prev_settings(bpy.types.Operator):
+class WM_OT_copy_prev_settings(Operator):
'''Copy settings from previous version'''
bl_idname = "wm.copy_prev_settings"
bl_label = "Copy Previous Settings"
@@ -957,65 +1179,3 @@ class WM_OT_copy_prev_settings(bpy.types.Operator):
return {'FINISHED'}
return {'CANCELLED'}
-
-
-def _webbrowser_bug_fix():
- # test for X11
- import os
-
- if os.environ.get("DISPLAY"):
-
- # BSD licenced code copied from python, temp fix for bug
- # http://bugs.python.org/issue11432, XXX == added code
- def _invoke(self, args, remote, autoraise):
- # XXX, added imports
- import io
- import subprocess
- import time
-
- raise_opt = []
- if remote and self.raise_opts:
- # use autoraise argument only for remote invocation
- autoraise = int(autoraise)
- opt = self.raise_opts[autoraise]
- if opt:
- raise_opt = [opt]
-
- cmdline = [self.name] + raise_opt + args
-
- if remote or self.background:
- inout = io.open(os.devnull, "r+")
- else:
- # for TTY browsers, we need stdin/out
- inout = None
- # if possible, put browser in separate process group, so
- # keyboard interrupts don't affect browser as well as Python
- setsid = getattr(os, 'setsid', None)
- if not setsid:
- setsid = getattr(os, 'setpgrp', None)
-
- p = subprocess.Popen(cmdline, close_fds=True, # XXX, stdin=inout,
- stdout=(self.redirect_stdout and inout or None),
- stderr=inout, preexec_fn=setsid)
- if remote:
- # wait five secons. If the subprocess is not finished, the
- # remote invocation has (hopefully) started a new instance.
- time.sleep(1)
- rc = p.poll()
- if rc is None:
- time.sleep(4)
- rc = p.poll()
- if rc is None:
- return True
- # if remote call failed, open() will try direct invocation
- return not rc
- elif self.background:
- if p.poll() is None:
- return True
- else:
- return False
- else:
- return not p.wait()
-
- import webbrowser
- webbrowser.UnixBrowser._invoke = _invoke
diff --git a/release/scripts/startup/bl_ui/__init__.py b/release/scripts/startup/bl_ui/__init__.py
index bf63c6071b9..778571632b2 100644
--- a/release/scripts/startup/bl_ui/__init__.py
+++ b/release/scripts/startup/bl_ui/__init__.py
@@ -36,6 +36,7 @@ _modules = (
"properties_data_mesh",
"properties_data_metaball",
"properties_data_modifier",
+ "properties_data_speaker",
"properties_game",
"properties_material",
"properties_object_constraint",
@@ -102,7 +103,10 @@ def register():
items.extend([(cat, cat, "") for cat in sorted(items_unique)])
return items
- WindowManager.addon_search = StringProperty(name="Search", description="Search within the selected filter")
+ WindowManager.addon_search = StringProperty(
+ name="Search",
+ description="Search within the selected filter",
+ )
WindowManager.addon_filter = EnumProperty(
items=addon_filter_items,
name="Category",
diff --git a/release/scripts/startup/bl_ui/properties_animviz.py b/release/scripts/startup/bl_ui/properties_animviz.py
index eb1bbfd2fb1..3b33a7ccc61 100644
--- a/release/scripts/startup/bl_ui/properties_animviz.py
+++ b/release/scripts/startup/bl_ui/properties_animviz.py
@@ -94,4 +94,5 @@ class OnionSkinButtonsPanel():
col.prop(arm, "show_only_ghost_selected", text="Selected Only")
if __name__ == "__main__": # only for live edit.
+ import bpy
bpy.utils.register_module(__name__)
diff --git a/release/scripts/startup/bl_ui/properties_data_armature.py b/release/scripts/startup/bl_ui/properties_data_armature.py
index 9477dc866ab..463ba84470f 100644
--- a/release/scripts/startup/bl_ui/properties_data_armature.py
+++ b/release/scripts/startup/bl_ui/properties_data_armature.py
@@ -18,6 +18,7 @@
# <pep8 compliant>
import bpy
+from bpy.types import Panel, Menu
from rna_prop_ui import PropertyPanel
@@ -31,7 +32,7 @@ class ArmatureButtonsPanel():
return context.armature
-class DATA_PT_context_arm(ArmatureButtonsPanel, bpy.types.Panel):
+class DATA_PT_context_arm(ArmatureButtonsPanel, Panel):
bl_label = ""
bl_options = {'HIDE_HEADER'}
@@ -48,7 +49,7 @@ class DATA_PT_context_arm(ArmatureButtonsPanel, bpy.types.Panel):
layout.template_ID(space, "pin_id")
-class DATA_PT_skeleton(ArmatureButtonsPanel, bpy.types.Panel):
+class DATA_PT_skeleton(ArmatureButtonsPanel, Panel):
bl_label = "Skeleton"
def draw(self, context):
@@ -70,8 +71,10 @@ class DATA_PT_skeleton(ArmatureButtonsPanel, bpy.types.Panel):
flow.prop(arm, "use_deform_envelopes", text="Envelopes")
flow.prop(arm, "use_deform_preserve_volume", text="Quaternion")
+ if context.scene.render.engine == "BLENDER_GAME":
+ layout.row().prop(arm, "vert_deformer", expand=True)
-class DATA_PT_display(ArmatureButtonsPanel, bpy.types.Panel):
+class DATA_PT_display(ArmatureButtonsPanel, Panel):
bl_label = "Display"
def draw(self, context):
@@ -96,7 +99,16 @@ class DATA_PT_display(ArmatureButtonsPanel, bpy.types.Panel):
col.prop(arm, "use_deform_delay", text="Delay Refresh")
-class DATA_PT_bone_groups(ArmatureButtonsPanel, bpy.types.Panel):
+class DATA_PT_bone_group_specials(Menu):
+ bl_label = "Bone Group Specials"
+
+ def draw(self, context):
+ layout = self.layout
+
+ layout.operator("pose.group_sort", icon='SORTALPHA')
+
+
+class DATA_PT_bone_groups(ArmatureButtonsPanel, Panel):
bl_label = "Bone Groups"
@classmethod
@@ -108,16 +120,25 @@ class DATA_PT_bone_groups(ArmatureButtonsPanel, bpy.types.Panel):
ob = context.object
pose = ob.pose
+ group = pose.bone_groups.active
row = layout.row()
- row.template_list(pose, "bone_groups", pose.bone_groups, "active_index", rows=2)
+
+ rows = 2
+ if group:
+ rows = 5
+ row.template_list(pose, "bone_groups", pose.bone_groups, "active_index", rows=rows)
col = row.column(align=True)
col.active = (ob.proxy is None)
col.operator("pose.group_add", icon='ZOOMIN', text="")
col.operator("pose.group_remove", icon='ZOOMOUT', text="")
+ col.menu("DATA_PT_bone_group_specials", icon='DOWNARROW_HLT', text="")
+ if group:
+ col.separator()
+ col.operator("pose.group_move", icon='TRIA_UP', text="").direction = 'UP'
+ col.operator("pose.group_move", icon='TRIA_DOWN', text="").direction = 'DOWN'
- group = pose.bone_groups.active
if group:
col = layout.column()
col.active = (ob.proxy is None)
@@ -147,7 +168,7 @@ class DATA_PT_bone_groups(ArmatureButtonsPanel, bpy.types.Panel):
sub.operator("pose.group_deselect", text="Deselect")
-class DATA_PT_pose_library(ArmatureButtonsPanel, bpy.types.Panel):
+class DATA_PT_pose_library(ArmatureButtonsPanel, Panel):
bl_label = "Pose Library"
bl_options = {'DEFAULT_CLOSED'}
@@ -164,9 +185,13 @@ class DATA_PT_pose_library(ArmatureButtonsPanel, bpy.types.Panel):
layout.template_ID(ob, "pose_library", new="poselib.new", unlink="poselib.unlink")
if poselib:
+
+ # list of poses in pose library
row = layout.row()
row.template_list(poselib, "pose_markers", poselib.pose_markers, "active_index", rows=5)
-
+
+ # column of operators for active pose
+ # - goes beside list
col = row.column(align=True)
col.active = (poselib.library is None)
@@ -181,12 +206,16 @@ class DATA_PT_pose_library(ArmatureButtonsPanel, bpy.types.Panel):
if pose_marker_active is not None:
col.operator("poselib.pose_remove", icon='ZOOMOUT', text="").pose = pose_marker_active.name
col.operator("poselib.apply_pose", icon='ZOOM_SELECTED', text="").pose_index = poselib.pose_markers.active_index
-
- layout.operator("poselib.action_sanitise")
+
+ col.operator("poselib.action_sanitise", icon='HELP', text="") # XXX: put in menu?
+
+ # properties for active marker
+ if pose_marker_active is not None:
+ layout.prop(pose_marker_active, "name")
# TODO: this panel will soon be depreceated too
-class DATA_PT_ghost(ArmatureButtonsPanel, bpy.types.Panel):
+class DATA_PT_ghost(ArmatureButtonsPanel, Panel):
bl_label = "Ghost"
def draw(self, context):
@@ -213,7 +242,7 @@ class DATA_PT_ghost(ArmatureButtonsPanel, bpy.types.Panel):
col.prop(arm, "show_only_ghost_selected", text="Selected Only")
-class DATA_PT_iksolver_itasc(ArmatureButtonsPanel, bpy.types.Panel):
+class DATA_PT_iksolver_itasc(ArmatureButtonsPanel, Panel):
bl_label = "iTaSC parameters"
bl_options = {'DEFAULT_CLOSED'}
@@ -266,7 +295,7 @@ from bl_ui.properties_animviz import (
)
-class DATA_PT_motion_paths(MotionPathButtonsPanel, bpy.types.Panel):
+class DATA_PT_motion_paths(MotionPathButtonsPanel, Panel):
#bl_label = "Bones Motion Paths"
bl_context = "data"
@@ -289,7 +318,7 @@ class DATA_PT_motion_paths(MotionPathButtonsPanel, bpy.types.Panel):
split.operator("pose.paths_clear", text="Clear Paths")
-class DATA_PT_onion_skinning(OnionSkinButtonsPanel): # , bpy.types.Panel): # inherit from panel when ready
+class DATA_PT_onion_skinning(OnionSkinButtonsPanel): # , Panel): # inherit from panel when ready
#bl_label = "Bones Onion Skinning"
bl_context = "data"
@@ -299,14 +328,11 @@ class DATA_PT_onion_skinning(OnionSkinButtonsPanel): # , bpy.types.Panel): # in
return (context.object) and (context.armature)
def draw(self, context):
- layout = self.layout
-
ob = context.object
-
self.draw_settings(context, ob.pose.animation_visualisation, bones=True)
-class DATA_PT_custom_props_arm(ArmatureButtonsPanel, PropertyPanel, bpy.types.Panel):
+class DATA_PT_custom_props_arm(ArmatureButtonsPanel, PropertyPanel, Panel):
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
_context_path = "object.data"
_property_type = bpy.types.Armature
diff --git a/release/scripts/startup/bl_ui/properties_data_bone.py b/release/scripts/startup/bl_ui/properties_data_bone.py
index 9fc055e9343..b3eaf88d5bf 100644
--- a/release/scripts/startup/bl_ui/properties_data_bone.py
+++ b/release/scripts/startup/bl_ui/properties_data_bone.py
@@ -19,6 +19,7 @@
# <pep8 compliant>
import bpy
+from bpy.types import Panel
from rna_prop_ui import PropertyPanel
@@ -32,7 +33,7 @@ class BoneButtonsPanel():
return (context.bone or context.edit_bone)
-class BONE_PT_context_bone(BoneButtonsPanel, bpy.types.Panel):
+class BONE_PT_context_bone(BoneButtonsPanel, Panel):
bl_label = ""
bl_options = {'HIDE_HEADER'}
@@ -48,7 +49,7 @@ class BONE_PT_context_bone(BoneButtonsPanel, bpy.types.Panel):
row.prop(bone, "name", text="")
-class BONE_PT_transform(BoneButtonsPanel, bpy.types.Panel):
+class BONE_PT_transform(BoneButtonsPanel, Panel):
bl_label = "Transform"
@classmethod
@@ -102,7 +103,7 @@ class BONE_PT_transform(BoneButtonsPanel, bpy.types.Panel):
sub.prop(bone, "lock")
-class BONE_PT_transform_locks(BoneButtonsPanel, bpy.types.Panel):
+class BONE_PT_transform_locks(BoneButtonsPanel, Panel):
bl_label = "Transform Locks"
bl_options = {'DEFAULT_CLOSED'}
@@ -135,7 +136,7 @@ class BONE_PT_transform_locks(BoneButtonsPanel, bpy.types.Panel):
row.column().prop(pchan, "lock_scale")
-class BONE_PT_relations(BoneButtonsPanel, bpy.types.Panel):
+class BONE_PT_relations(BoneButtonsPanel, Panel):
bl_label = "Relations"
def draw(self, context):
@@ -180,7 +181,7 @@ class BONE_PT_relations(BoneButtonsPanel, bpy.types.Panel):
sub.prop(bone, "use_local_location", text="Local Location")
-class BONE_PT_display(BoneButtonsPanel, bpy.types.Panel):
+class BONE_PT_display(BoneButtonsPanel, Panel):
bl_label = "Display"
@classmethod
@@ -217,7 +218,7 @@ class BONE_PT_display(BoneButtonsPanel, bpy.types.Panel):
col.prop_search(pchan, "custom_shape_transform", ob.pose, "bones", text="At")
-class BONE_PT_inverse_kinematics(BoneButtonsPanel, bpy.types.Panel):
+class BONE_PT_inverse_kinematics(BoneButtonsPanel, Panel):
bl_label = "Inverse Kinematics"
bl_options = {'DEFAULT_CLOSED'}
@@ -308,7 +309,7 @@ class BONE_PT_inverse_kinematics(BoneButtonsPanel, bpy.types.Panel):
#row.prop(pchan, "ik_linear_weight", text="Weight", slider=True)
-class BONE_PT_deform(BoneButtonsPanel, bpy.types.Panel):
+class BONE_PT_deform(BoneButtonsPanel, Panel):
bl_label = "Deform"
bl_options = {'DEFAULT_CLOSED'}
@@ -357,7 +358,7 @@ class BONE_PT_deform(BoneButtonsPanel, bpy.types.Panel):
col.prop(bone, "use_cyclic_offset")
-class BONE_PT_custom_props(BoneButtonsPanel, PropertyPanel, bpy.types.Panel):
+class BONE_PT_custom_props(BoneButtonsPanel, PropertyPanel, Panel):
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
_property_type = bpy.types.Bone, bpy.types.EditBone, bpy.types.PoseBone
diff --git a/release/scripts/startup/bl_ui/properties_data_camera.py b/release/scripts/startup/bl_ui/properties_data_camera.py
index 80cd5227fca..5255af40951 100644
--- a/release/scripts/startup/bl_ui/properties_data_camera.py
+++ b/release/scripts/startup/bl_ui/properties_data_camera.py
@@ -18,6 +18,7 @@
# <pep8 compliant>
import bpy
+from bpy.types import Panel
from rna_prop_ui import PropertyPanel
@@ -32,7 +33,7 @@ class CameraButtonsPanel():
return context.camera and (engine in cls.COMPAT_ENGINES)
-class DATA_PT_context_camera(CameraButtonsPanel, bpy.types.Panel):
+class DATA_PT_context_camera(CameraButtonsPanel, Panel):
bl_label = ""
bl_options = {'HIDE_HEADER'}
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
@@ -53,7 +54,7 @@ class DATA_PT_context_camera(CameraButtonsPanel, bpy.types.Panel):
split.separator()
-class DATA_PT_camera(CameraButtonsPanel, bpy.types.Panel):
+class DATA_PT_camera(CameraButtonsPanel, Panel):
bl_label = "Lens"
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
@@ -106,12 +107,12 @@ class DATA_PT_camera(CameraButtonsPanel, bpy.types.Panel):
col = split.column()
- if cam.dof_object != None:
+ if cam.dof_object is not None:
col.enabled = False
col.prop(cam, "dof_distance", text="Distance")
-class DATA_PT_camera_display(CameraButtonsPanel, bpy.types.Panel):
+class DATA_PT_camera_display(CameraButtonsPanel, Panel):
bl_label = "Display"
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
@@ -138,7 +139,7 @@ class DATA_PT_camera_display(CameraButtonsPanel, bpy.types.Panel):
sub.prop(cam, "passepartout_alpha", text="Alpha", slider=True)
-class DATA_PT_custom_props_camera(CameraButtonsPanel, PropertyPanel, bpy.types.Panel):
+class DATA_PT_custom_props_camera(CameraButtonsPanel, PropertyPanel, Panel):
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
_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 11a129377e8..6448b9a5229 100644
--- a/release/scripts/startup/bl_ui/properties_data_curve.py
+++ b/release/scripts/startup/bl_ui/properties_data_curve.py
@@ -18,6 +18,7 @@
# <pep8 compliant>
import bpy
+from bpy.types import Panel
from rna_prop_ui import PropertyPanel
@@ -48,7 +49,7 @@ class CurveButtonsPanelActive(CurveButtonsPanel):
return (curve and type(curve) is not bpy.types.TextCurve and curve.splines.active)
-class DATA_PT_context_curve(CurveButtonsPanel, bpy.types.Panel):
+class DATA_PT_context_curve(CurveButtonsPanel, Panel):
bl_label = ""
bl_options = {'HIDE_HEADER'}
@@ -65,7 +66,7 @@ class DATA_PT_context_curve(CurveButtonsPanel, bpy.types.Panel):
layout.template_ID(space, "pin_id") # XXX: broken
-class DATA_PT_shape_curve(CurveButtonsPanel, bpy.types.Panel):
+class DATA_PT_shape_curve(CurveButtonsPanel, Panel):
bl_label = "Shape"
def draw(self, context):
@@ -108,21 +109,32 @@ class DATA_PT_shape_curve(CurveButtonsPanel, bpy.types.Panel):
if (is_curve or is_text):
col.label(text="Fill:")
sub = col.column()
- sub.active = (curve.bevel_object is None)
+ sub.active = (curve.dimensions == '2D' or (curve.bevel_object is None and curve.dimensions == '3D'))
sub.prop(curve, "use_fill_front")
sub.prop(curve, "use_fill_back")
col.prop(curve, "use_fill_deform", text="Fill Deformed")
- col.label(text="Textures:")
- col.prop(curve, "use_uv_as_generated")
- col.prop(curve, "use_auto_texspace")
-
+
+class DATA_PT_curve_texture_space(CurveButtonsPanel, Panel):
+ bl_label = "Texture Space"
+ bl_options = {'DEFAULT_CLOSED'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
+
+ def draw(self, context):
+ layout = self.layout
+
+ curve = context.curve
+
+ row = layout.row()
+ row.prop(curve, "use_auto_texspace")
+ row.prop(curve, "use_uv_as_generated")
+
row = layout.row()
- row.column().prop(curve, "texspace_location")
- row.column().prop(curve, "texspace_size")
+ row.column().prop(curve, "texspace_location", text="Location")
+ row.column().prop(curve, "texspace_size", text="Size")
-class DATA_PT_geometry_curve(CurveButtonsPanel, bpy.types.Panel):
+class DATA_PT_geometry_curve(CurveButtonsPanel, Panel):
bl_label = "Geometry"
@classmethod
@@ -155,7 +167,7 @@ class DATA_PT_geometry_curve(CurveButtonsPanel, bpy.types.Panel):
col.prop(curve, "bevel_object", text="")
-class DATA_PT_pathanim(CurveButtonsPanelCurve, bpy.types.Panel):
+class DATA_PT_pathanim(CurveButtonsPanelCurve, Panel):
bl_label = "Path Animation"
def draw_header(self, context):
@@ -186,7 +198,7 @@ class DATA_PT_pathanim(CurveButtonsPanelCurve, bpy.types.Panel):
col.prop(curve, "use_time_offset", text="Offset Children")
-class DATA_PT_active_spline(CurveButtonsPanelActive, bpy.types.Panel):
+class DATA_PT_active_spline(CurveButtonsPanelActive, Panel):
bl_label = "Active Spline"
def draw(self, context):
@@ -257,7 +269,7 @@ class DATA_PT_active_spline(CurveButtonsPanelActive, bpy.types.Panel):
layout.prop(act_spline, "use_smooth")
-class DATA_PT_font(CurveButtonsPanel, bpy.types.Panel):
+class DATA_PT_font(CurveButtonsPanel, Panel):
bl_label = "Font"
@classmethod
@@ -321,7 +333,7 @@ class DATA_PT_font(CurveButtonsPanel, bpy.types.Panel):
row.prop(char, "use_small_caps")
-class DATA_PT_paragraph(CurveButtonsPanel, bpy.types.Panel):
+class DATA_PT_paragraph(CurveButtonsPanel, Panel):
bl_label = "Paragraph"
@classmethod
@@ -350,7 +362,7 @@ class DATA_PT_paragraph(CurveButtonsPanel, bpy.types.Panel):
col.prop(text, "offset_y", text="Y")
-class DATA_PT_textboxes(CurveButtonsPanel, bpy.types.Panel):
+class DATA_PT_text_boxes(CurveButtonsPanel, Panel):
bl_label = "Text Boxes"
@classmethod
@@ -390,7 +402,7 @@ class DATA_PT_textboxes(CurveButtonsPanel, bpy.types.Panel):
row.operator("font.textbox_remove", text='', icon='X', emboss=False).index = i
-class DATA_PT_custom_props_curve(CurveButtonsPanel, PropertyPanel, bpy.types.Panel):
+class DATA_PT_custom_props_curve(CurveButtonsPanel, PropertyPanel, Panel):
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
_context_path = "object.data"
_property_type = bpy.types.Curve
diff --git a/release/scripts/startup/bl_ui/properties_data_empty.py b/release/scripts/startup/bl_ui/properties_data_empty.py
index 5a0d327f90d..c781873e16c 100644
--- a/release/scripts/startup/bl_ui/properties_data_empty.py
+++ b/release/scripts/startup/bl_ui/properties_data_empty.py
@@ -18,6 +18,7 @@
# <pep8 compliant>
import bpy
+from bpy.types import Panel
class DataButtonsPanel():
@@ -30,7 +31,7 @@ class DataButtonsPanel():
return (context.object and context.object.type == 'EMPTY')
-class DATA_PT_empty(DataButtonsPanel, bpy.types.Panel):
+class DATA_PT_empty(DataButtonsPanel, Panel):
bl_label = "Empty"
def draw(self, context):
@@ -41,11 +42,9 @@ class DATA_PT_empty(DataButtonsPanel, bpy.types.Panel):
layout.prop(ob, "empty_draw_type", text="Display")
if ob.empty_draw_type == 'IMAGE':
- # layout.template_image(ob, "data", None)
layout.template_ID(ob, "data", open="image.open", unlink="image.unlink")
- row = layout.row(align=True)
- row.prop(ob, "color", text="Transparency", index=3, slider=True)
+ layout.prop(ob, "color", text="Transparency", index=3, slider=True)
row = layout.row(align=True)
row.prop(ob, "empty_image_offset", text="Offset X", index=0)
row.prop(ob, "empty_image_offset", text="Offset Y", index=1)
diff --git a/release/scripts/startup/bl_ui/properties_data_lamp.py b/release/scripts/startup/bl_ui/properties_data_lamp.py
index 36010c8b511..4ff180f74fb 100644
--- a/release/scripts/startup/bl_ui/properties_data_lamp.py
+++ b/release/scripts/startup/bl_ui/properties_data_lamp.py
@@ -18,15 +18,16 @@
# <pep8 compliant>
import bpy
+from bpy.types import Menu, Panel
from rna_prop_ui import PropertyPanel
-class LAMP_MT_sunsky_presets(bpy.types.Menu):
+class LAMP_MT_sunsky_presets(Menu):
bl_label = "Sun & Sky Presets"
preset_subdir = "sunsky"
preset_operator = "script.execute_preset"
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
- draw = bpy.types.Menu.draw_preset
+ draw = Menu.draw_preset
class DataButtonsPanel():
@@ -40,7 +41,7 @@ class DataButtonsPanel():
return context.lamp and (engine in cls.COMPAT_ENGINES)
-class DATA_PT_context_lamp(DataButtonsPanel, bpy.types.Panel):
+class DATA_PT_context_lamp(DataButtonsPanel, Panel):
bl_label = ""
bl_options = {'HIDE_HEADER'}
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
@@ -65,7 +66,7 @@ class DATA_PT_context_lamp(DataButtonsPanel, bpy.types.Panel):
split.label(text=str(texture_count), icon='TEXTURE')
-class DATA_PT_preview(DataButtonsPanel, bpy.types.Panel):
+class DATA_PT_preview(DataButtonsPanel, Panel):
bl_label = "Preview"
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
@@ -73,7 +74,7 @@ class DATA_PT_preview(DataButtonsPanel, bpy.types.Panel):
self.layout.template_preview(context.lamp)
-class DATA_PT_lamp(DataButtonsPanel, bpy.types.Panel):
+class DATA_PT_lamp(DataButtonsPanel, Panel):
bl_label = "Lamp"
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
@@ -115,7 +116,7 @@ class DATA_PT_lamp(DataButtonsPanel, bpy.types.Panel):
col.prop(lamp, "use_diffuse")
-class DATA_PT_sunsky(DataButtonsPanel, bpy.types.Panel):
+class DATA_PT_sunsky(DataButtonsPanel, Panel):
bl_label = "Sky & Atmosphere"
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
@@ -187,7 +188,7 @@ class DATA_PT_sunsky(DataButtonsPanel, bpy.types.Panel):
sub.prop(lamp, "atmosphere_extinction", slider=True, text="Extinction")
-class DATA_PT_shadow(DataButtonsPanel, bpy.types.Panel):
+class DATA_PT_shadow(DataButtonsPanel, Panel):
bl_label = "Shadow"
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
@@ -302,7 +303,7 @@ class DATA_PT_shadow(DataButtonsPanel, bpy.types.Panel):
sub.prop(lamp, "shadow_buffer_clip_end", text=" Clip End")
-class DATA_PT_area(DataButtonsPanel, bpy.types.Panel):
+class DATA_PT_area(DataButtonsPanel, Panel):
bl_label = "Area Shape"
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
@@ -328,7 +329,7 @@ class DATA_PT_area(DataButtonsPanel, bpy.types.Panel):
sub.prop(lamp, "size_y", text="Size Y")
-class DATA_PT_spot(DataButtonsPanel, bpy.types.Panel):
+class DATA_PT_spot(DataButtonsPanel, Panel):
bl_label = "Spot Shape"
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
@@ -362,7 +363,7 @@ class DATA_PT_spot(DataButtonsPanel, bpy.types.Panel):
sub.prop(lamp, "halo_step", text="Step")
-class DATA_PT_falloff_curve(DataButtonsPanel, bpy.types.Panel):
+class DATA_PT_falloff_curve(DataButtonsPanel, Panel):
bl_label = "Falloff Curve"
bl_options = {'DEFAULT_CLOSED'}
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
@@ -380,7 +381,7 @@ class DATA_PT_falloff_curve(DataButtonsPanel, bpy.types.Panel):
self.layout.template_curve_mapping(lamp, "falloff_curve")
-class DATA_PT_custom_props_lamp(DataButtonsPanel, PropertyPanel, bpy.types.Panel):
+class DATA_PT_custom_props_lamp(DataButtonsPanel, PropertyPanel, Panel):
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
_context_path = "object.data"
_property_type = bpy.types.Lamp
diff --git a/release/scripts/startup/bl_ui/properties_data_lattice.py b/release/scripts/startup/bl_ui/properties_data_lattice.py
index cd719b6fe84..14d6ea66894 100644
--- a/release/scripts/startup/bl_ui/properties_data_lattice.py
+++ b/release/scripts/startup/bl_ui/properties_data_lattice.py
@@ -18,6 +18,7 @@
# <pep8 compliant>
import bpy
+from bpy.types import Panel
from rna_prop_ui import PropertyPanel
@@ -31,7 +32,7 @@ class DataButtonsPanel():
return context.lattice
-class DATA_PT_context_lattice(DataButtonsPanel, bpy.types.Panel):
+class DATA_PT_context_lattice(DataButtonsPanel, Panel):
bl_label = ""
bl_options = {'HIDE_HEADER'}
@@ -51,7 +52,7 @@ class DATA_PT_context_lattice(DataButtonsPanel, bpy.types.Panel):
split.separator()
-class DATA_PT_lattice(DataButtonsPanel, bpy.types.Panel):
+class DATA_PT_lattice(DataButtonsPanel, Panel):
bl_label = "Lattice"
def draw(self, context):
@@ -76,7 +77,7 @@ class DATA_PT_lattice(DataButtonsPanel, bpy.types.Panel):
row.prop_search(lat, "vertex_group", context.object, "vertex_groups", text="")
-class DATA_PT_custom_props_lattice(DataButtonsPanel, PropertyPanel, bpy.types.Panel):
+class DATA_PT_custom_props_lattice(DataButtonsPanel, PropertyPanel, Panel):
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
_context_path = "object.data"
_property_type = bpy.types.Lattice
diff --git a/release/scripts/startup/bl_ui/properties_data_mesh.py b/release/scripts/startup/bl_ui/properties_data_mesh.py
index e2c88413177..75df7dad5f2 100644
--- a/release/scripts/startup/bl_ui/properties_data_mesh.py
+++ b/release/scripts/startup/bl_ui/properties_data_mesh.py
@@ -18,10 +18,11 @@
# <pep8 compliant>
import bpy
+from bpy.types import Menu, Panel
from rna_prop_ui import PropertyPanel
-class MESH_MT_vertex_group_specials(bpy.types.Menu):
+class MESH_MT_vertex_group_specials(Menu):
bl_label = "Vertex Group Specials"
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
@@ -36,7 +37,7 @@ class MESH_MT_vertex_group_specials(bpy.types.Menu):
layout.operator("object.vertex_group_remove", icon='X', text="Delete All").all = True
-class MESH_MT_shape_key_specials(bpy.types.Menu):
+class MESH_MT_shape_key_specials(Menu):
bl_label = "Shape Key Specials"
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
@@ -61,7 +62,7 @@ class MeshButtonsPanel():
return context.mesh and (engine in cls.COMPAT_ENGINES)
-class DATA_PT_context_mesh(MeshButtonsPanel, bpy.types.Panel):
+class DATA_PT_context_mesh(MeshButtonsPanel, Panel):
bl_label = ""
bl_options = {'HIDE_HEADER'}
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
@@ -79,7 +80,7 @@ class DATA_PT_context_mesh(MeshButtonsPanel, bpy.types.Panel):
layout.template_ID(space, "pin_id")
-class DATA_PT_normals(MeshButtonsPanel, bpy.types.Panel):
+class DATA_PT_normals(MeshButtonsPanel, Panel):
bl_label = "Normals"
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
@@ -99,7 +100,7 @@ class DATA_PT_normals(MeshButtonsPanel, bpy.types.Panel):
split.prop(mesh, "show_double_sided")
-class DATA_PT_texture_space(MeshButtonsPanel, bpy.types.Panel):
+class DATA_PT_texture_space(MeshButtonsPanel, Panel):
bl_label = "Texture Space"
bl_options = {'DEFAULT_CLOSED'}
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
@@ -118,7 +119,8 @@ class DATA_PT_texture_space(MeshButtonsPanel, bpy.types.Panel):
row.column().prop(mesh, "texspace_location", text="Location")
row.column().prop(mesh, "texspace_size", text="Size")
-class DATA_PT_vertex_groups(MeshButtonsPanel, bpy.types.Panel):
+
+class DATA_PT_vertex_groups(MeshButtonsPanel, Panel):
bl_label = "Vertex Groups"
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
@@ -167,7 +169,7 @@ class DATA_PT_vertex_groups(MeshButtonsPanel, bpy.types.Panel):
layout.prop(context.tool_settings, "vertex_group_weight", text="Weight")
-class DATA_PT_shape_keys(MeshButtonsPanel, bpy.types.Panel):
+class DATA_PT_shape_keys(MeshButtonsPanel, Panel):
bl_label = "Shape Keys"
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
@@ -260,7 +262,7 @@ class DATA_PT_shape_keys(MeshButtonsPanel, bpy.types.Panel):
row.prop(key, "slurph")
-class DATA_PT_uv_texture(MeshButtonsPanel, bpy.types.Panel):
+class DATA_PT_uv_texture(MeshButtonsPanel, Panel):
bl_label = "UV Texture"
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
@@ -283,15 +285,14 @@ class DATA_PT_uv_texture(MeshButtonsPanel, bpy.types.Panel):
layout.prop(lay, "name")
-class DATA_PT_texface(MeshButtonsPanel, bpy.types.Panel):
+class DATA_PT_texface(MeshButtonsPanel, Panel):
bl_label = "Texture Face"
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
@classmethod
def poll(cls, context):
- ob = context.active_object
-
- return (context.mode == 'EDIT_MESH') and ob and ob.type == 'MESH'
+ obj = context.object
+ return (context.mode == 'EDIT_MESH') and obj and obj.type == 'MESH'
def draw(self, context):
layout = self.layout
@@ -331,7 +332,7 @@ class DATA_PT_texface(MeshButtonsPanel, bpy.types.Panel):
col.label(text="No UV Texture")
-class DATA_PT_vertex_colors(MeshButtonsPanel, bpy.types.Panel):
+class DATA_PT_vertex_colors(MeshButtonsPanel, Panel):
bl_label = "Vertex Colors"
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
@@ -354,7 +355,7 @@ class DATA_PT_vertex_colors(MeshButtonsPanel, bpy.types.Panel):
layout.prop(lay, "name")
-class DATA_PT_custom_props_mesh(MeshButtonsPanel, PropertyPanel, bpy.types.Panel):
+class DATA_PT_custom_props_mesh(MeshButtonsPanel, PropertyPanel, Panel):
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
_context_path = "object.data"
_property_type = bpy.types.Mesh
diff --git a/release/scripts/startup/bl_ui/properties_data_metaball.py b/release/scripts/startup/bl_ui/properties_data_metaball.py
index c568d10b3b0..cd894e60dbb 100644
--- a/release/scripts/startup/bl_ui/properties_data_metaball.py
+++ b/release/scripts/startup/bl_ui/properties_data_metaball.py
@@ -18,6 +18,7 @@
# <pep8 compliant>
import bpy
+from bpy.types import Panel
from rna_prop_ui import PropertyPanel
@@ -31,7 +32,7 @@ class DataButtonsPanel():
return context.meta_ball
-class DATA_PT_context_metaball(DataButtonsPanel, bpy.types.Panel):
+class DATA_PT_context_metaball(DataButtonsPanel, Panel):
bl_label = ""
bl_options = {'HIDE_HEADER'}
@@ -48,7 +49,7 @@ class DATA_PT_context_metaball(DataButtonsPanel, bpy.types.Panel):
layout.template_ID(space, "pin_id")
-class DATA_PT_metaball(DataButtonsPanel, bpy.types.Panel):
+class DATA_PT_metaball(DataButtonsPanel, Panel):
bl_label = "Metaball"
def draw(self, context):
@@ -70,13 +71,26 @@ class DATA_PT_metaball(DataButtonsPanel, bpy.types.Panel):
layout.label(text="Update:")
layout.prop(mball, "update_method", expand=True)
-
+
+
+class DATA_PT_mball_texture_space(DataButtonsPanel, Panel):
+ bl_label = "Texture Space"
+ bl_options = {'DEFAULT_CLOSED'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
+
+ def draw(self, context):
+ layout = self.layout
+
+ mball = context.meta_ball
+
+ layout.prop(mball, "use_auto_texspace")
+
row = layout.row()
- row.column().prop(mball, "texspace_location")
- row.column().prop(mball, "texspace_size")
+ row.column().prop(mball, "texspace_location", text="Location")
+ row.column().prop(mball, "texspace_size", text="Size")
-class DATA_PT_metaball_element(DataButtonsPanel, bpy.types.Panel):
+class DATA_PT_metaball_element(DataButtonsPanel, Panel):
bl_label = "Active Element"
@classmethod
@@ -116,7 +130,7 @@ class DATA_PT_metaball_element(DataButtonsPanel, bpy.types.Panel):
col.prop(metaelem, "size_y", text="Y")
-class DATA_PT_custom_props_metaball(DataButtonsPanel, PropertyPanel, bpy.types.Panel):
+class DATA_PT_custom_props_metaball(DataButtonsPanel, PropertyPanel, Panel):
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
_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 6fd5890590d..dc6b5401168 100644
--- a/release/scripts/startup/bl_ui/properties_data_modifier.py
+++ b/release/scripts/startup/bl_ui/properties_data_modifier.py
@@ -18,6 +18,7 @@
# <pep8 compliant>
import bpy
+from bpy.types import Panel
class ModifierButtonsPanel():
@@ -26,7 +27,7 @@ class ModifierButtonsPanel():
bl_context = "modifier"
-class DATA_PT_modifiers(ModifierButtonsPanel, bpy.types.Panel):
+class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
bl_label = "Modifiers"
def draw(self, context):
@@ -402,6 +403,7 @@ class DATA_PT_modifiers(ModifierButtonsPanel, bpy.types.Panel):
col.operator("object.multires_higher_levels_delete", text="Delete Higher")
col.operator("object.multires_reshape", text="Reshape")
col.operator("object.multires_base_apply", text="Apply Base")
+ col.prop(md, "use_subsurf_uv")
col.prop(md, "show_only_control_edges")
layout.separator()
@@ -491,11 +493,10 @@ class DATA_PT_modifiers(ModifierButtonsPanel, bpy.types.Panel):
col.label(text="Mode:")
col.prop(md, "wrap_method", text="")
- split = layout.split(percentage=0.25)
-
- col = split.column()
-
if md.wrap_method == 'PROJECT':
+ split = layout.split(percentage=0.25)
+
+ col = split.column()
col.label(text="Axis:")
col.prop(md, "use_project_x")
col.prop(md, "use_project_y")
@@ -507,7 +508,6 @@ class DATA_PT_modifiers(ModifierButtonsPanel, bpy.types.Panel):
col.prop(md, "use_positive_direction")
col = split.column()
-
col.label(text="Cull Faces:")
col.prop(md, "cull_face", expand=True)
@@ -585,13 +585,13 @@ class DATA_PT_modifiers(ModifierButtonsPanel, bpy.types.Panel):
sub = col.column()
sub.active = bool(md.vertex_group)
sub.prop(md, "invert_vertex_group", text="Invert")
+ sub.prop(md, "thickness_vertex_group", text="Factor")
col.prop(md, "use_even_offset")
col.prop(md, "use_quality_normals")
col.prop(md, "use_rim")
sub = col.column()
- sub.label()
row = sub.split(align=True, percentage=0.4)
row.prop(md, "material_offset", text="")
row = row.row()
diff --git a/release/scripts/startup/bl_ui/properties_data_speaker.py b/release/scripts/startup/bl_ui/properties_data_speaker.py
new file mode 100644
index 00000000000..657c0fe652a
--- /dev/null
+++ b/release/scripts/startup/bl_ui/properties_data_speaker.py
@@ -0,0 +1,125 @@
+# ##### 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 rna_prop_ui import PropertyPanel
+
+
+class DataButtonsPanel():
+ bl_space_type = 'PROPERTIES'
+ bl_region_type = 'WINDOW'
+ bl_context = "data"
+
+ @classmethod
+ def poll(cls, context):
+ engine = context.scene.render.engine
+ return context.speaker and (engine in cls.COMPAT_ENGINES)
+
+
+class DATA_PT_context_speaker(DataButtonsPanel, bpy.types.Panel):
+ bl_label = ""
+ bl_options = {'HIDE_HEADER'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
+
+ def draw(self, context):
+ layout = self.layout
+
+ ob = context.object
+ speaker = context.speaker
+ space = context.space_data
+
+ split = layout.split(percentage=0.65)
+
+ if ob:
+ split.template_ID(ob, "data")
+ elif speaker:
+ split.template_ID(space, "pin_id")
+
+
+class DATA_PT_speaker(DataButtonsPanel, bpy.types.Panel):
+ bl_label = "Sound"
+ COMPAT_ENGINES = {'BLENDER_RENDER'}
+
+ def draw(self, context):
+ layout = self.layout
+
+ speaker = context.speaker
+
+ split = layout.split(percentage=0.75)
+
+ split.template_ID(speaker, "sound", open="sound.open_mono")
+ split.prop(speaker, "muted")
+
+ row = layout.row()
+ row.prop(speaker, "volume")
+ row.prop(speaker, "pitch")
+
+
+class DATA_PT_distance(DataButtonsPanel, bpy.types.Panel):
+ bl_label = "Distance"
+ COMPAT_ENGINES = {'BLENDER_RENDER'}
+
+ def draw(self, context):
+ layout = self.layout
+
+ speaker = context.speaker
+
+ split = layout.split()
+
+ col = split.column()
+ col.label("Volume:")
+ col.prop(speaker, "volume_min", text="Minimum")
+ col.prop(speaker, "volume_max", text="Maximum")
+ col.prop(speaker, "attenuation")
+
+ col = split.column()
+ col.label("Distance:")
+ col.prop(speaker, "distance_max", text="Maximum")
+ col.prop(speaker, "distance_reference", text="Reference")
+
+
+class DATA_PT_cone(DataButtonsPanel, bpy.types.Panel):
+ bl_label = "Cone"
+ COMPAT_ENGINES = {'BLENDER_RENDER'}
+
+ def draw(self, context):
+ layout = self.layout
+
+ speaker = context.speaker
+
+ split = layout.split()
+ col = split.column()
+
+ col.label("Angle:")
+ col.prop(speaker, "cone_angle_outer", text="Outer")
+ col.prop(speaker, "cone_angle_inner", text="Inner")
+
+ col = split.column()
+
+ col.label("Volume:")
+ col.prop(speaker, "cone_volume_outer", text="Outer")
+
+
+class DATA_PT_custom_props_speaker(DataButtonsPanel, PropertyPanel, bpy.types.Panel):
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
+ _context_path = "object.data"
+ _property_type = bpy.types.Speaker
+
+if __name__ == "__main__": # only for live edit.
+ bpy.utils.register_module(__name__)
diff --git a/release/scripts/startup/bl_ui/properties_game.py b/release/scripts/startup/bl_ui/properties_game.py
index 6952f3c31db..16c7adbe5ff 100644
--- a/release/scripts/startup/bl_ui/properties_game.py
+++ b/release/scripts/startup/bl_ui/properties_game.py
@@ -18,6 +18,7 @@
# <pep8 compliant>
import bpy
+from bpy.types import Panel
class PhysicsButtonsPanel():
@@ -26,7 +27,7 @@ class PhysicsButtonsPanel():
bl_context = "physics"
-class PHYSICS_PT_game_physics(PhysicsButtonsPanel, bpy.types.Panel):
+class PHYSICS_PT_game_physics(PhysicsButtonsPanel, Panel):
bl_label = "Physics"
COMPAT_ENGINES = {'BLENDER_GAME'}
@@ -167,7 +168,7 @@ class PHYSICS_PT_game_physics(PhysicsButtonsPanel, bpy.types.Panel):
layout.prop(ob, "hide_render", text="Invisible")
-class PHYSICS_PT_game_collision_bounds(PhysicsButtonsPanel, bpy.types.Panel):
+class PHYSICS_PT_game_collision_bounds(PhysicsButtonsPanel, Panel):
bl_label = "Collision Bounds"
COMPAT_ENGINES = {'BLENDER_GAME'}
@@ -231,7 +232,7 @@ class RenderButtonsPanel():
return (rd.engine in cls.COMPAT_ENGINES)
-class RENDER_PT_game(RenderButtonsPanel, bpy.types.Panel):
+class RENDER_PT_game(RenderButtonsPanel, Panel):
bl_label = "Game"
COMPAT_ENGINES = {'BLENDER_GAME'}
@@ -243,7 +244,7 @@ class RENDER_PT_game(RenderButtonsPanel, bpy.types.Panel):
row.label()
-class RENDER_PT_game_player(RenderButtonsPanel, bpy.types.Panel):
+class RENDER_PT_game_player(RenderButtonsPanel, Panel):
bl_label = "Standalone Player"
COMPAT_ENGINES = {'BLENDER_GAME'}
@@ -276,7 +277,7 @@ class RENDER_PT_game_player(RenderButtonsPanel, bpy.types.Panel):
col.prop(gs, "frame_color", text="")
-class RENDER_PT_game_stereo(RenderButtonsPanel, bpy.types.Panel):
+class RENDER_PT_game_stereo(RenderButtonsPanel, Panel):
bl_label = "Stereo"
COMPAT_ENGINES = {'BLENDER_GAME'}
@@ -330,7 +331,7 @@ class RENDER_PT_game_stereo(RenderButtonsPanel, bpy.types.Panel):
layout.prop(gs, "dome_text")
-class RENDER_PT_game_shading(RenderButtonsPanel, bpy.types.Panel):
+class RENDER_PT_game_shading(RenderButtonsPanel, Panel):
bl_label = "Shading"
COMPAT_ENGINES = {'BLENDER_GAME'}
@@ -356,7 +357,7 @@ class RENDER_PT_game_shading(RenderButtonsPanel, bpy.types.Panel):
col.prop(gs, "use_glsl_extra_textures", text="Extra Textures")
-class RENDER_PT_game_performance(RenderButtonsPanel, bpy.types.Panel):
+class RENDER_PT_game_performance(RenderButtonsPanel, Panel):
bl_label = "Performance"
COMPAT_ENGINES = {'BLENDER_GAME'}
@@ -364,12 +365,15 @@ class RENDER_PT_game_performance(RenderButtonsPanel, bpy.types.Panel):
layout = self.layout
gs = context.scene.game_settings
- row = layout.row()
+ col = layout.column()
+ row = col.row()
row.prop(gs, "use_frame_rate")
row.prop(gs, "use_display_lists")
+
+ col.prop(gs, "restrict_animation_updates")
-class RENDER_PT_game_display(RenderButtonsPanel, bpy.types.Panel):
+class RENDER_PT_game_display(RenderButtonsPanel, Panel):
bl_label = "Display"
COMPAT_ENGINES = {'BLENDER_GAME'}
@@ -385,28 +389,13 @@ class RENDER_PT_game_display(RenderButtonsPanel, bpy.types.Panel):
flow.prop(gs, "show_mouse", text="Mouse Cursor")
-class RENDER_PT_game_sound(RenderButtonsPanel, bpy.types.Panel):
- bl_label = "Sound"
- COMPAT_ENGINES = {'BLENDER_GAME'}
-
- def draw(self, context):
- layout = self.layout
-
- scene = context.scene
-
- layout.prop(scene, "audio_distance_model")
-
- layout.prop(scene, "audio_doppler_speed", text="Speed")
- layout.prop(scene, "audio_doppler_factor")
-
-
class WorldButtonsPanel():
bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW'
bl_context = "world"
-class WORLD_PT_game_context_world(WorldButtonsPanel, bpy.types.Panel):
+class WORLD_PT_game_context_world(WorldButtonsPanel, Panel):
bl_label = ""
bl_options = {'HIDE_HEADER'}
COMPAT_ENGINES = {'BLENDER_GAME'}
@@ -430,7 +419,7 @@ class WORLD_PT_game_context_world(WorldButtonsPanel, bpy.types.Panel):
split.template_ID(space, "pin_id")
-class WORLD_PT_game_world(WorldButtonsPanel, bpy.types.Panel):
+class WORLD_PT_game_world(WorldButtonsPanel, Panel):
bl_label = "World"
COMPAT_ENGINES = {'BLENDER_GAME'}
@@ -449,7 +438,7 @@ class WORLD_PT_game_world(WorldButtonsPanel, bpy.types.Panel):
row.column().prop(world, "ambient_color")
-class WORLD_PT_game_mist(WorldButtonsPanel, bpy.types.Panel):
+class WORLD_PT_game_mist(WorldButtonsPanel, Panel):
bl_label = "Mist"
COMPAT_ENGINES = {'BLENDER_GAME'}
@@ -475,7 +464,7 @@ class WORLD_PT_game_mist(WorldButtonsPanel, bpy.types.Panel):
row.prop(world.mist_settings, "depth")
-class WORLD_PT_game_physics(WorldButtonsPanel, bpy.types.Panel):
+class WORLD_PT_game_physics(WorldButtonsPanel, Panel):
bl_label = "Physics"
COMPAT_ENGINES = {'BLENDER_GAME'}
diff --git a/release/scripts/startup/bl_ui/properties_material.py b/release/scripts/startup/bl_ui/properties_material.py
index 52d6b5f1376..13ce92f084c 100644
--- a/release/scripts/startup/bl_ui/properties_material.py
+++ b/release/scripts/startup/bl_ui/properties_material.py
@@ -18,6 +18,7 @@
# <pep8 compliant>
import bpy
+from bpy.types import Menu, Panel
from rna_prop_ui import PropertyPanel
@@ -50,14 +51,14 @@ def simple_material(mat):
return False
-class MATERIAL_MT_sss_presets(bpy.types.Menu):
+class MATERIAL_MT_sss_presets(Menu):
bl_label = "SSS Presets"
preset_subdir = "sss"
preset_operator = "script.execute_preset"
- draw = bpy.types.Menu.draw_preset
+ draw = Menu.draw_preset
-class MATERIAL_MT_specials(bpy.types.Menu):
+class MATERIAL_MT_specials(Menu):
bl_label = "Material Specials"
def draw(self, context):
@@ -79,7 +80,7 @@ class MaterialButtonsPanel():
return context.material and (context.scene.render.engine in cls.COMPAT_ENGINES)
-class MATERIAL_PT_context_material(MaterialButtonsPanel, bpy.types.Panel):
+class MATERIAL_PT_context_material(MaterialButtonsPanel, Panel):
bl_label = ""
bl_options = {'HIDE_HEADER'}
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
@@ -144,7 +145,7 @@ class MATERIAL_PT_context_material(MaterialButtonsPanel, bpy.types.Panel):
row.label(text="No material node selected")
-class MATERIAL_PT_preview(MaterialButtonsPanel, bpy.types.Panel):
+class MATERIAL_PT_preview(MaterialButtonsPanel, Panel):
bl_label = "Preview"
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
@@ -152,7 +153,7 @@ class MATERIAL_PT_preview(MaterialButtonsPanel, bpy.types.Panel):
self.layout.template_preview(context.material)
-class MATERIAL_PT_pipeline(MaterialButtonsPanel, bpy.types.Panel):
+class MATERIAL_PT_pipeline(MaterialButtonsPanel, Panel):
bl_label = "Render Pipeline Options"
bl_options = {'DEFAULT_CLOSED'}
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
@@ -174,6 +175,7 @@ class MATERIAL_PT_pipeline(MaterialButtonsPanel, bpy.types.Panel):
row.prop(mat, "use_transparency")
sub = row.column()
sub.prop(mat, "offset_z")
+
sub.active = mat_type and mat.use_transparency and mat.transparency_method == 'Z_TRANSPARENCY'
row = layout.row()
@@ -199,9 +201,10 @@ class MATERIAL_PT_pipeline(MaterialButtonsPanel, bpy.types.Panel):
col.prop(mat, "shadow_cast_alpha", text="Casting Alpha")
col.prop(mat, "use_cast_buffer_shadows")
col.prop(mat, "use_cast_approximate")
+ col.prop(mat, "pass_index")
-class MATERIAL_PT_diffuse(MaterialButtonsPanel, bpy.types.Panel):
+class MATERIAL_PT_diffuse(MaterialButtonsPanel, Panel):
bl_label = "Diffuse"
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
@@ -245,18 +248,20 @@ class MATERIAL_PT_diffuse(MaterialButtonsPanel, bpy.types.Panel):
row.prop(mat, "diffuse_fresnel_factor", text="Factor")
if mat.use_diffuse_ramp:
- layout.separator()
- layout.template_color_ramp(mat, "diffuse_ramp", expand=True)
- layout.separator()
+ col = layout.column()
+ col.active = (not mat.use_shadeless)
+ col.separator()
+ col.template_color_ramp(mat, "diffuse_ramp", expand=True)
+ col.separator()
- row = layout.row()
+ row = col.row()
row.prop(mat, "diffuse_ramp_input", text="Input")
row.prop(mat, "diffuse_ramp_blend", text="Blend")
- layout.prop(mat, "diffuse_ramp_factor", text="Factor")
+ col.prop(mat, "diffuse_ramp_factor", text="Factor")
-class MATERIAL_PT_specular(MaterialButtonsPanel, bpy.types.Panel):
+class MATERIAL_PT_specular(MaterialButtonsPanel, Panel):
bl_label = "Specular"
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
@@ -309,7 +314,7 @@ class MATERIAL_PT_specular(MaterialButtonsPanel, bpy.types.Panel):
layout.prop(mat, "specular_ramp_factor", text="Factor")
-class MATERIAL_PT_shading(MaterialButtonsPanel, bpy.types.Panel):
+class MATERIAL_PT_shading(MaterialButtonsPanel, Panel):
bl_label = "Shading"
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
@@ -343,7 +348,7 @@ class MATERIAL_PT_shading(MaterialButtonsPanel, bpy.types.Panel):
sub.prop(mat, "use_cubic")
-class MATERIAL_PT_transp(MaterialButtonsPanel, bpy.types.Panel):
+class MATERIAL_PT_transp(MaterialButtonsPanel, Panel):
bl_label = "Transparency"
# bl_options = {'DEFAULT_CLOSED'}
COMPAT_ENGINES = {'BLENDER_RENDER'}
@@ -409,7 +414,7 @@ class MATERIAL_PT_transp(MaterialButtonsPanel, bpy.types.Panel):
sub.prop(rayt, "gloss_samples", text="Samples")
-class MATERIAL_PT_mirror(MaterialButtonsPanel, bpy.types.Panel):
+class MATERIAL_PT_mirror(MaterialButtonsPanel, Panel):
bl_label = "Mirror"
bl_options = {'DEFAULT_CLOSED'}
COMPAT_ENGINES = {'BLENDER_RENDER'}
@@ -467,7 +472,7 @@ class MATERIAL_PT_mirror(MaterialButtonsPanel, bpy.types.Panel):
sub.prop(raym, "gloss_anisotropic", text="Anisotropic")
-class MATERIAL_PT_sss(MaterialButtonsPanel, bpy.types.Panel):
+class MATERIAL_PT_sss(MaterialButtonsPanel, Panel):
bl_label = "Subsurface Scattering"
bl_options = {'DEFAULT_CLOSED'}
COMPAT_ENGINES = {'BLENDER_RENDER'}
@@ -519,7 +524,7 @@ class MATERIAL_PT_sss(MaterialButtonsPanel, bpy.types.Panel):
col.prop(sss, "error_threshold", text="Error")
-class MATERIAL_PT_halo(MaterialButtonsPanel, bpy.types.Panel):
+class MATERIAL_PT_halo(MaterialButtonsPanel, Panel):
bl_label = "Halo"
COMPAT_ENGINES = {'BLENDER_RENDER'}
@@ -572,7 +577,7 @@ class MATERIAL_PT_halo(MaterialButtonsPanel, bpy.types.Panel):
number_but(col, "use_star", "star_tip_count", "Star tips", "")
-class MATERIAL_PT_flare(MaterialButtonsPanel, bpy.types.Panel):
+class MATERIAL_PT_flare(MaterialButtonsPanel, Panel):
bl_label = "Flare"
COMPAT_ENGINES = {'BLENDER_RENDER'}
@@ -607,7 +612,7 @@ class MATERIAL_PT_flare(MaterialButtonsPanel, bpy.types.Panel):
col.prop(halo, "flare_subflare_size", text="Subsize")
-class MATERIAL_PT_physics(MaterialButtonsPanel, bpy.types.Panel):
+class MATERIAL_PT_physics(MaterialButtonsPanel, Panel):
bl_label = "Physics"
COMPAT_ENGINES = {'BLENDER_GAME'}
@@ -637,7 +642,7 @@ class MATERIAL_PT_physics(MaterialButtonsPanel, bpy.types.Panel):
row.prop(phys, "use_fh_normal")
-class MATERIAL_PT_strand(MaterialButtonsPanel, bpy.types.Panel):
+class MATERIAL_PT_strand(MaterialButtonsPanel, Panel):
bl_label = "Strand"
bl_options = {'DEFAULT_CLOSED'}
COMPAT_ENGINES = {'BLENDER_RENDER'}
@@ -684,7 +689,7 @@ class MATERIAL_PT_strand(MaterialButtonsPanel, bpy.types.Panel):
sub.prop(tan, "blend_distance", text="Distance")
-class MATERIAL_PT_options(MaterialButtonsPanel, bpy.types.Panel):
+class MATERIAL_PT_options(MaterialButtonsPanel, Panel):
bl_label = "Options"
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
@@ -729,9 +734,11 @@ class MATERIAL_PT_options(MaterialButtonsPanel, bpy.types.Panel):
col.prop(mat, "use_vertex_color_paint")
col.prop(mat, "use_vertex_color_light")
col.prop(mat, "use_object_color")
+ if simple_material(base_mat):
+ col.prop(mat, "pass_index")
-class MATERIAL_PT_shadow(MaterialButtonsPanel, bpy.types.Panel):
+class MATERIAL_PT_shadow(MaterialButtonsPanel, Panel):
bl_label = "Shadow"
bl_options = {'DEFAULT_CLOSED'}
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
@@ -775,7 +782,7 @@ class MATERIAL_PT_shadow(MaterialButtonsPanel, bpy.types.Panel):
col.prop(mat, "use_cast_approximate")
-class MATERIAL_PT_transp_game(MaterialButtonsPanel, bpy.types.Panel):
+class MATERIAL_PT_transp_game(MaterialButtonsPanel, Panel):
bl_label = "Transparency"
bl_options = {'DEFAULT_CLOSED'}
COMPAT_ENGINES = {'BLENDER_GAME'}
@@ -818,7 +825,7 @@ class VolumeButtonsPanel():
return mat and (mat.type == 'VOLUME') and (engine in cls.COMPAT_ENGINES)
-class MATERIAL_PT_volume_density(VolumeButtonsPanel, bpy.types.Panel):
+class MATERIAL_PT_volume_density(VolumeButtonsPanel, Panel):
bl_label = "Density"
COMPAT_ENGINES = {'BLENDER_RENDER'}
@@ -832,7 +839,7 @@ class MATERIAL_PT_volume_density(VolumeButtonsPanel, bpy.types.Panel):
row.prop(vol, "density_scale")
-class MATERIAL_PT_volume_shading(VolumeButtonsPanel, bpy.types.Panel):
+class MATERIAL_PT_volume_shading(VolumeButtonsPanel, Panel):
bl_label = "Shading"
COMPAT_ENGINES = {'BLENDER_RENDER'}
@@ -857,7 +864,7 @@ class MATERIAL_PT_volume_shading(VolumeButtonsPanel, bpy.types.Panel):
sub.prop(vol, "reflection_color", text="")
-class MATERIAL_PT_volume_lighting(VolumeButtonsPanel, bpy.types.Panel):
+class MATERIAL_PT_volume_lighting(VolumeButtonsPanel, Panel):
bl_label = "Lighting"
COMPAT_ENGINES = {'BLENDER_RENDER'}
@@ -883,7 +890,7 @@ class MATERIAL_PT_volume_lighting(VolumeButtonsPanel, bpy.types.Panel):
sub = col.column()
sub.enabled = True
sub.active = False
- sub.prop(vol, "use_light_cache")
+ sub.label("Light Cache Enabled")
col.prop(vol, "cache_resolution")
sub = col.column(align=True)
@@ -892,7 +899,7 @@ class MATERIAL_PT_volume_lighting(VolumeButtonsPanel, bpy.types.Panel):
sub.prop(vol, "ms_intensity")
-class MATERIAL_PT_volume_transp(VolumeButtonsPanel, bpy.types.Panel):
+class MATERIAL_PT_volume_transp(VolumeButtonsPanel, Panel):
bl_label = "Transparency"
COMPAT_ENGINES = {'BLENDER_RENDER'}
@@ -910,7 +917,7 @@ class MATERIAL_PT_volume_transp(VolumeButtonsPanel, bpy.types.Panel):
layout.prop(mat, "transparency_method", expand=True)
-class MATERIAL_PT_volume_integration(VolumeButtonsPanel, bpy.types.Panel):
+class MATERIAL_PT_volume_integration(VolumeButtonsPanel, Panel):
bl_label = "Integration"
COMPAT_ENGINES = {'BLENDER_RENDER'}
@@ -932,7 +939,7 @@ class MATERIAL_PT_volume_integration(VolumeButtonsPanel, bpy.types.Panel):
col.prop(vol, "depth_threshold")
-class MATERIAL_PT_volume_options(VolumeButtonsPanel, bpy.types.Panel):
+class MATERIAL_PT_volume_options(VolumeButtonsPanel, Panel):
bl_label = "Options"
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
bl_options = {'DEFAULT_CLOSED'}
@@ -964,7 +971,7 @@ class MATERIAL_PT_volume_options(VolumeButtonsPanel, bpy.types.Panel):
row.prop(mat, "use_light_group_exclusive", text="Exclusive")
-class MATERIAL_PT_custom_props(MaterialButtonsPanel, PropertyPanel, bpy.types.Panel):
+class MATERIAL_PT_custom_props(MaterialButtonsPanel, PropertyPanel, Panel):
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
_context_path = "material"
_property_type = bpy.types.Material
diff --git a/release/scripts/startup/bl_ui/properties_object.py b/release/scripts/startup/bl_ui/properties_object.py
index ae66642e903..0779debb102 100644
--- a/release/scripts/startup/bl_ui/properties_object.py
+++ b/release/scripts/startup/bl_ui/properties_object.py
@@ -18,6 +18,7 @@
# <pep8 compliant>
import bpy
+from bpy.types import Panel
from rna_prop_ui import PropertyPanel
@@ -27,14 +28,13 @@ class ObjectButtonsPanel():
bl_context = "object"
-class OBJECT_PT_context_object(ObjectButtonsPanel, bpy.types.Panel):
+class OBJECT_PT_context_object(ObjectButtonsPanel, Panel):
bl_label = ""
bl_options = {'HIDE_HEADER'}
def draw(self, context):
layout = self.layout
space = context.space_data
- ob = context.object
if space.use_pin_id:
layout.template_ID(space, "pin_id")
@@ -43,7 +43,7 @@ class OBJECT_PT_context_object(ObjectButtonsPanel, bpy.types.Panel):
row.template_ID(context.scene.objects, "active")
-class OBJECT_PT_transform(ObjectButtonsPanel, bpy.types.Panel):
+class OBJECT_PT_transform(ObjectButtonsPanel, Panel):
bl_label = "Transform"
def draw(self, context):
@@ -69,7 +69,7 @@ class OBJECT_PT_transform(ObjectButtonsPanel, bpy.types.Panel):
layout.prop(ob, "rotation_mode")
-class OBJECT_PT_delta_transform(ObjectButtonsPanel, bpy.types.Panel):
+class OBJECT_PT_delta_transform(ObjectButtonsPanel, Panel):
bl_label = "Delta Transform"
bl_options = {'DEFAULT_CLOSED'}
@@ -95,7 +95,7 @@ class OBJECT_PT_delta_transform(ObjectButtonsPanel, bpy.types.Panel):
row.column().prop(ob, "delta_scale")
-class OBJECT_PT_transform_locks(ObjectButtonsPanel, bpy.types.Panel):
+class OBJECT_PT_transform_locks(ObjectButtonsPanel, Panel):
bl_label = "Transform Locks"
bl_options = {'DEFAULT_CLOSED'}
@@ -121,7 +121,7 @@ class OBJECT_PT_transform_locks(ObjectButtonsPanel, bpy.types.Panel):
row.column().prop(ob, "lock_scale", text="Scale")
-class OBJECT_PT_relations(ObjectButtonsPanel, bpy.types.Panel):
+class OBJECT_PT_relations(ObjectButtonsPanel, Panel):
bl_label = "Relations"
def draw(self, context):
@@ -148,7 +148,7 @@ class OBJECT_PT_relations(ObjectButtonsPanel, bpy.types.Panel):
sub.active = (parent is not None)
-class OBJECT_PT_groups(ObjectButtonsPanel, bpy.types.Panel):
+class OBJECT_PT_groups(ObjectButtonsPanel, Panel):
bl_label = "Groups"
def draw(self, context):
@@ -187,7 +187,7 @@ class OBJECT_PT_groups(ObjectButtonsPanel, bpy.types.Panel):
index += 1
-class OBJECT_PT_display(ObjectButtonsPanel, bpy.types.Panel):
+class OBJECT_PT_display(ObjectButtonsPanel, Panel):
bl_label = "Display"
def draw(self, context):
@@ -221,7 +221,7 @@ class OBJECT_PT_display(ObjectButtonsPanel, bpy.types.Panel):
col.prop(ob, "show_transparent", text="Transparency")
-class OBJECT_PT_duplication(ObjectButtonsPanel, bpy.types.Panel):
+class OBJECT_PT_duplication(ObjectButtonsPanel, Panel):
bl_label = "Duplication"
def draw(self, context):
@@ -259,7 +259,7 @@ class OBJECT_PT_duplication(ObjectButtonsPanel, bpy.types.Panel):
# XXX: the following options are all quite buggy, ancient hacks that should be dropped
-class OBJECT_PT_animation(ObjectButtonsPanel, bpy.types.Panel):
+class OBJECT_PT_animation(ObjectButtonsPanel, Panel):
bl_label = "Animation Hacks"
bl_options = {'DEFAULT_CLOSED'}
@@ -294,7 +294,7 @@ from bl_ui.properties_animviz import (
)
-class OBJECT_PT_motion_paths(MotionPathButtonsPanel, bpy.types.Panel):
+class OBJECT_PT_motion_paths(MotionPathButtonsPanel, Panel):
#bl_label = "Object Motion Paths"
bl_context = "object"
@@ -316,7 +316,7 @@ class OBJECT_PT_motion_paths(MotionPathButtonsPanel, bpy.types.Panel):
row.operator("object.paths_clear", text="Clear Paths")
-class OBJECT_PT_onion_skinning(OnionSkinButtonsPanel): # , bpy.types.Panel): # inherit from panel when ready
+class OBJECT_PT_onion_skinning(OnionSkinButtonsPanel): # , Panel): # inherit from panel when ready
#bl_label = "Object Onion Skinning"
bl_context = "object"
@@ -330,7 +330,7 @@ class OBJECT_PT_onion_skinning(OnionSkinButtonsPanel): # , bpy.types.Panel): #
self.draw_settings(context, ob.animation_visualisation)
-class OBJECT_PT_custom_props(ObjectButtonsPanel, PropertyPanel, bpy.types.Panel):
+class OBJECT_PT_custom_props(ObjectButtonsPanel, PropertyPanel, Panel):
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
_context_path = "object"
_property_type = bpy.types.Object
diff --git a/release/scripts/startup/bl_ui/properties_object_constraint.py b/release/scripts/startup/bl_ui/properties_object_constraint.py
index 03823ad7345..05fac2026a0 100644
--- a/release/scripts/startup/bl_ui/properties_object_constraint.py
+++ b/release/scripts/startup/bl_ui/properties_object_constraint.py
@@ -18,6 +18,7 @@
# <pep8 compliant>
import bpy
+from bpy.types import Panel
class ConstraintButtonsPanel():
@@ -234,7 +235,6 @@ class ConstraintButtonsPanel():
row.label()
def LIMIT_ROTATION(self, context, layout, con):
-
split = layout.split()
col = split.column(align=True)
@@ -258,9 +258,7 @@ class ConstraintButtonsPanel():
sub.prop(con, "min_z", text="Min")
sub.prop(con, "max_z", text="Max")
- row = layout.row()
- row.prop(con, "use_transform_limit")
- row.label()
+ layout.prop(con, "use_transform_limit")
row = layout.row()
row.label(text="Convert:")
@@ -476,6 +474,10 @@ class ConstraintButtonsPanel():
row.label(text="Clamp Region:")
row.prop(con, "limit_mode", text="")
+ row = layout.row()
+ row.prop(con, "use_transform_limit")
+ row.label()
+
def STRETCH_TO(self, context, layout, con):
self.target_template(layout, con)
@@ -655,8 +657,8 @@ class ConstraintButtonsPanel():
row = col.row()
row.label(text="Source to Destination Mapping:")
- # note: chr(187) is the ASCII arrow ( >> ). Blender Text Editor can't
- # open it. Thus we are using the hardcoded value instead.
+ # note: chr(187) is the ASCII arrow ( >> ). Blender Text Editor can't
+ # open it. Thus we are using the hardcoded value instead.
row = col.row()
row.prop(con, "map_to_x_from", expand=False, text="")
row.label(text=" %s X" % chr(187))
@@ -755,7 +757,7 @@ class ConstraintButtonsPanel():
layout.label("Blender 2.5 has no py-constraints")
-class OBJECT_PT_constraints(ConstraintButtonsPanel, bpy.types.Panel):
+class OBJECT_PT_constraints(ConstraintButtonsPanel, Panel):
bl_label = "Object Constraints"
bl_context = "constraint"
@@ -779,7 +781,7 @@ class OBJECT_PT_constraints(ConstraintButtonsPanel, bpy.types.Panel):
self.draw_constraint(context, con)
-class BONE_PT_constraints(ConstraintButtonsPanel, bpy.types.Panel):
+class BONE_PT_constraints(ConstraintButtonsPanel, Panel):
bl_label = "Bone Constraints"
bl_context = "bone_constraint"
diff --git a/release/scripts/startup/bl_ui/properties_particle.py b/release/scripts/startup/bl_ui/properties_particle.py
index 63333083cb2..6f58f060504 100644
--- a/release/scripts/startup/bl_ui/properties_particle.py
+++ b/release/scripts/startup/bl_ui/properties_particle.py
@@ -18,6 +18,7 @@
# <pep8 compliant>
import bpy
+from bpy.types import Panel
from rna_prop_ui import PropertyPanel
from bl_ui.properties_physics_common import (
@@ -72,7 +73,7 @@ class ParticleButtonsPanel():
return particle_panel_poll(cls, context)
-class PARTICLE_PT_context_particles(ParticleButtonsPanel, bpy.types.Panel):
+class PARTICLE_PT_context_particles(ParticleButtonsPanel, Panel):
bl_label = ""
bl_options = {'HIDE_HEADER'}
COMPAT_ENGINES = {'BLENDER_RENDER'}
@@ -155,7 +156,7 @@ class PARTICLE_PT_context_particles(ParticleButtonsPanel, bpy.types.Panel):
if part:
split = layout.split(percentage=0.65)
if part.type == 'HAIR':
- if psys != None and psys.is_edited:
+ if psys is not None and psys.is_edited:
split.operator("particle.edited_clear", text="Free Edit")
else:
row = split.row()
@@ -165,18 +166,18 @@ class PARTICLE_PT_context_particles(ParticleButtonsPanel, bpy.types.Panel):
row = split.row()
row.enabled = particle_panel_enabled(context, psys)
row.prop(part, "hair_step")
- if psys != None and psys.is_edited:
+ if psys is not None and psys.is_edited:
if psys.is_global_hair:
layout.operator("particle.connect_hair")
else:
layout.operator("particle.disconnect_hair")
- elif psys != None and part.type == 'REACTOR':
+ elif psys is not None and part.type == 'REACTOR':
split.enabled = particle_panel_enabled(context, psys)
split.prop(psys, "reactor_target_object")
split.prop(psys, "reactor_target_particle_system", text="Particle System")
-class PARTICLE_PT_emission(ParticleButtonsPanel, bpy.types.Panel):
+class PARTICLE_PT_emission(ParticleButtonsPanel, Panel):
bl_label = "Emission"
COMPAT_ENGINES = {'BLENDER_RENDER'}
@@ -245,7 +246,7 @@ class PARTICLE_PT_emission(ParticleButtonsPanel, bpy.types.Panel):
row.prop(part, "grid_random", text="Random", slider=True)
-class PARTICLE_PT_hair_dynamics(ParticleButtonsPanel, bpy.types.Panel):
+class PARTICLE_PT_hair_dynamics(ParticleButtonsPanel, Panel):
bl_label = "Hair dynamics"
bl_options = {'DEFAULT_CLOSED'}
COMPAT_ENGINES = {'BLENDER_RENDER'}
@@ -301,7 +302,7 @@ class PARTICLE_PT_hair_dynamics(ParticleButtonsPanel, bpy.types.Panel):
col.prop(cloth, "quality", text="Steps", slider=True)
-class PARTICLE_PT_cache(ParticleButtonsPanel, bpy.types.Panel):
+class PARTICLE_PT_cache(ParticleButtonsPanel, Panel):
bl_label = "Cache"
bl_options = {'DEFAULT_CLOSED'}
COMPAT_ENGINES = {'BLENDER_RENDER'}
@@ -327,7 +328,7 @@ class PARTICLE_PT_cache(ParticleButtonsPanel, bpy.types.Panel):
point_cache_ui(self, context, psys.point_cache, True, 'HAIR' if (psys.settings.type == 'HAIR') else 'PSYS')
-class PARTICLE_PT_velocity(ParticleButtonsPanel, bpy.types.Panel):
+class PARTICLE_PT_velocity(ParticleButtonsPanel, Panel):
bl_label = "Velocity"
COMPAT_ENGINES = {'BLENDER_RENDER'}
@@ -377,7 +378,7 @@ class PARTICLE_PT_velocity(ParticleButtonsPanel, bpy.types.Panel):
# sub.prop(part, "reaction_shape", slider=True)
-class PARTICLE_PT_rotation(ParticleButtonsPanel, bpy.types.Panel):
+class PARTICLE_PT_rotation(ParticleButtonsPanel, Panel):
bl_label = "Rotation"
COMPAT_ENGINES = {'BLENDER_RENDER'}
@@ -426,7 +427,7 @@ class PARTICLE_PT_rotation(ParticleButtonsPanel, bpy.types.Panel):
col.prop(part, "angular_velocity_factor", text="")
-class PARTICLE_PT_physics(ParticleButtonsPanel, bpy.types.Panel):
+class PARTICLE_PT_physics(ParticleButtonsPanel, Panel):
bl_label = "Physics"
COMPAT_ENGINES = {'BLENDER_RENDER'}
@@ -462,7 +463,7 @@ class PARTICLE_PT_physics(ParticleButtonsPanel, bpy.types.Panel):
col.prop(part, "mass")
col.prop(part, "use_multiply_size_mass", text="Multiply mass with size")
- if part.physics_type in ('NEWTON', 'FLUID'):
+ if part.physics_type in {'NEWTON', 'FLUID'}:
split = layout.split()
col = split.column()
@@ -641,7 +642,7 @@ class PARTICLE_PT_physics(ParticleButtonsPanel, bpy.types.Panel):
sub.prop(key, "system", text="System")
-class PARTICLE_PT_boidbrain(ParticleButtonsPanel, bpy.types.Panel):
+class PARTICLE_PT_boidbrain(ParticleButtonsPanel, Panel):
bl_label = "Boid Brain"
COMPAT_ENGINES = {'BLENDER_RENDER'}
@@ -653,7 +654,7 @@ class PARTICLE_PT_boidbrain(ParticleButtonsPanel, bpy.types.Panel):
if settings is None:
return False
- if psys != None and psys.point_cache.use_external:
+ if psys is not None and psys.point_cache.use_external:
return False
return settings.physics_type == 'BOIDS' and engine in cls.COMPAT_ENGINES
@@ -742,7 +743,7 @@ class PARTICLE_PT_boidbrain(ParticleButtonsPanel, bpy.types.Panel):
row.prop(rule, "flee_distance")
-class PARTICLE_PT_render(ParticleButtonsPanel, bpy.types.Panel):
+class PARTICLE_PT_render(ParticleButtonsPanel, Panel):
bl_label = "Render"
COMPAT_ENGINES = {'BLENDER_RENDER'}
@@ -879,6 +880,15 @@ class PARTICLE_PT_render(ParticleButtonsPanel, bpy.types.Panel):
col = row.column()
col.prop(part, "billboard_offset")
+ row = layout.row()
+ col = row.column()
+ col.prop(part, "billboard_size", text="Scale")
+ if part.billboard_align == 'VEL':
+ col = row.column(align=True)
+ col.label("Velocity Scale:")
+ col.prop(part, "billboard_velocity_head", text="Head")
+ col.prop(part, "billboard_velocity_tail", text="Tail")
+
if psys:
col = layout.column()
col.prop_search(psys, "billboard_normal_uv", ob.data, "uv_textures")
@@ -912,13 +922,13 @@ class PARTICLE_PT_render(ParticleButtonsPanel, bpy.types.Panel):
col = row.column()
col.label(text="")
- if part.render_type in ('OBJECT', 'GROUP') and not part.use_advanced_hair:
+ if part.render_type in {'OBJECT', 'GROUP'} and not part.use_advanced_hair:
row = layout.row(align=True)
row.prop(part, "particle_size")
row.prop(part, "size_random", slider=True)
-class PARTICLE_PT_draw(ParticleButtonsPanel, bpy.types.Panel):
+class PARTICLE_PT_draw(ParticleButtonsPanel, Panel):
bl_label = "Display"
bl_options = {'DEFAULT_CLOSED'}
COMPAT_ENGINES = {'BLENDER_RENDER'}
@@ -980,7 +990,7 @@ class PARTICLE_PT_draw(ParticleButtonsPanel, bpy.types.Panel):
col.prop(part, "draw_step")
-class PARTICLE_PT_children(ParticleButtonsPanel, bpy.types.Panel):
+class PARTICLE_PT_children(ParticleButtonsPanel, Panel):
bl_label = "Children"
bl_options = {'DEFAULT_CLOSED'}
COMPAT_ENGINES = {'BLENDER_RENDER'}
@@ -1080,7 +1090,7 @@ class PARTICLE_PT_children(ParticleButtonsPanel, bpy.types.Panel):
sub.prop(part, "kink_shape", slider=True)
-class PARTICLE_PT_field_weights(ParticleButtonsPanel, bpy.types.Panel):
+class PARTICLE_PT_field_weights(ParticleButtonsPanel, Panel):
bl_label = "Field Weights"
bl_options = {'DEFAULT_CLOSED'}
COMPAT_ENGINES = {'BLENDER_RENDER'}
@@ -1101,7 +1111,7 @@ class PARTICLE_PT_field_weights(ParticleButtonsPanel, bpy.types.Panel):
row.prop(part, "effect_hair", slider=True)
-class PARTICLE_PT_force_fields(ParticleButtonsPanel, bpy.types.Panel):
+class PARTICLE_PT_force_fields(ParticleButtonsPanel, Panel):
bl_label = "Force Field Settings"
bl_options = {'DEFAULT_CLOSED'}
COMPAT_ENGINES = {'BLENDER_RENDER'}
@@ -1135,7 +1145,7 @@ class PARTICLE_PT_force_fields(ParticleButtonsPanel, bpy.types.Panel):
basic_force_field_falloff_ui(self, context, part.force_field_2)
-class PARTICLE_PT_vertexgroups(ParticleButtonsPanel, bpy.types.Panel):
+class PARTICLE_PT_vertexgroups(ParticleButtonsPanel, Panel):
bl_label = "Vertexgroups"
bl_options = {'DEFAULT_CLOSED'}
COMPAT_ENGINES = {'BLENDER_RENDER'}
@@ -1206,7 +1216,7 @@ class PARTICLE_PT_vertexgroups(ParticleButtonsPanel, bpy.types.Panel):
# row.prop(psys, "invert_vertex_group_field", text="")
-class PARTICLE_PT_custom_props(ParticleButtonsPanel, PropertyPanel, bpy.types.Panel):
+class PARTICLE_PT_custom_props(ParticleButtonsPanel, PropertyPanel, Panel):
COMPAT_ENGINES = {'BLENDER_RENDER'}
_context_path = "particle_system.settings"
_property_type = bpy.types.ParticleSettings
diff --git a/release/scripts/startup/bl_ui/properties_physics_cloth.py b/release/scripts/startup/bl_ui/properties_physics_cloth.py
index bce6ab993a7..d5427d8bae8 100644
--- a/release/scripts/startup/bl_ui/properties_physics_cloth.py
+++ b/release/scripts/startup/bl_ui/properties_physics_cloth.py
@@ -18,6 +18,7 @@
# <pep8 compliant>
import bpy
+from bpy.types import Menu, Panel
from bl_ui.properties_physics_common import (
@@ -30,14 +31,14 @@ def cloth_panel_enabled(md):
return md.point_cache.is_baked is False
-class CLOTH_MT_presets(bpy.types.Menu):
+class CLOTH_MT_presets(Menu):
'''
Creates the menu items by scanning scripts/templates
'''
bl_label = "Cloth Presets"
preset_subdir = "cloth"
preset_operator = "script.execute_preset"
- draw = bpy.types.Menu.draw_preset
+ draw = Menu.draw_preset
class PhysicButtonsPanel():
@@ -52,7 +53,7 @@ class PhysicButtonsPanel():
return (ob and ob.type == 'MESH') and (not rd.use_game_engine) and (context.cloth)
-class PHYSICS_PT_cloth(PhysicButtonsPanel, bpy.types.Panel):
+class PHYSICS_PT_cloth(PhysicButtonsPanel, Panel):
bl_label = "Cloth"
def draw(self, context):
@@ -117,7 +118,7 @@ class PHYSICS_PT_cloth(PhysicButtonsPanel, bpy.types.Panel):
col.prop_search(cloth, "rest_shape_key", key, "key_blocks", text="")
-class PHYSICS_PT_cloth_cache(PhysicButtonsPanel, bpy.types.Panel):
+class PHYSICS_PT_cloth_cache(PhysicButtonsPanel, Panel):
bl_label = "Cloth Cache"
bl_options = {'DEFAULT_CLOSED'}
@@ -130,7 +131,7 @@ class PHYSICS_PT_cloth_cache(PhysicButtonsPanel, bpy.types.Panel):
point_cache_ui(self, context, md.point_cache, cloth_panel_enabled(md), 'CLOTH')
-class PHYSICS_PT_cloth_collision(PhysicButtonsPanel, bpy.types.Panel):
+class PHYSICS_PT_cloth_collision(PhysicButtonsPanel, Panel):
bl_label = "Cloth Collision"
bl_options = {'DEFAULT_CLOSED'}
@@ -171,7 +172,7 @@ class PHYSICS_PT_cloth_collision(PhysicButtonsPanel, bpy.types.Panel):
layout.prop(cloth, "group")
-class PHYSICS_PT_cloth_stiffness(PhysicButtonsPanel, bpy.types.Panel):
+class PHYSICS_PT_cloth_stiffness(PhysicButtonsPanel, Panel):
bl_label = "Cloth Stiffness Scaling"
bl_options = {'DEFAULT_CLOSED'}
@@ -207,7 +208,7 @@ class PHYSICS_PT_cloth_stiffness(PhysicButtonsPanel, bpy.types.Panel):
col.prop(cloth, "bending_stiffness_max", text="Max")
-class PHYSICS_PT_cloth_field_weights(PhysicButtonsPanel, bpy.types.Panel):
+class PHYSICS_PT_cloth_field_weights(PhysicButtonsPanel, Panel):
bl_label = "Cloth Field Weights"
bl_options = {'DEFAULT_CLOSED'}
diff --git a/release/scripts/startup/bl_ui/properties_physics_common.py b/release/scripts/startup/bl_ui/properties_physics_common.py
index f7cf8da1840..204e25d9f01 100644
--- a/release/scripts/startup/bl_ui/properties_physics_common.py
+++ b/release/scripts/startup/bl_ui/properties_physics_common.py
@@ -19,6 +19,7 @@
# <pep8 compliant>
import bpy
+from bpy.types import Panel
class PhysicButtonsPanel():
@@ -44,7 +45,7 @@ def physics_add(self, layout, md, name, type, typeicon, toggles):
sub.operator("object.modifier_add", text=name, icon=typeicon).type = type
-class PHYSICS_PT_add(PhysicButtonsPanel, bpy.types.Panel):
+class PHYSICS_PT_add(PhysicButtonsPanel, Panel):
bl_label = ""
bl_options = {'HIDE_HEADER'}
diff --git a/release/scripts/startup/bl_ui/properties_physics_field.py b/release/scripts/startup/bl_ui/properties_physics_field.py
index 9f96f0a5b9f..e1dc4d04378 100644
--- a/release/scripts/startup/bl_ui/properties_physics_field.py
+++ b/release/scripts/startup/bl_ui/properties_physics_field.py
@@ -18,6 +18,7 @@
# <pep8 compliant>
import bpy
+from bpy.types import Panel
from bl_ui.properties_physics_common import (
@@ -37,7 +38,7 @@ class PhysicButtonsPanel():
return (context.object) and (not rd.use_game_engine)
-class PHYSICS_PT_field(PhysicButtonsPanel, bpy.types.Panel):
+class PHYSICS_PT_field(PhysicButtonsPanel, Panel):
bl_label = "Force Fields"
@classmethod
@@ -164,7 +165,7 @@ class PHYSICS_PT_field(PhysicButtonsPanel, bpy.types.Panel):
sub.prop(field, "radial_max", text="Distance")
-class PHYSICS_PT_collision(PhysicButtonsPanel, bpy.types.Panel):
+class PHYSICS_PT_collision(PhysicButtonsPanel, Panel):
bl_label = "Collision"
#bl_options = {'DEFAULT_CLOSED'}
diff --git a/release/scripts/startup/bl_ui/properties_physics_fluid.py b/release/scripts/startup/bl_ui/properties_physics_fluid.py
index 5da89d0090a..46893af3582 100644
--- a/release/scripts/startup/bl_ui/properties_physics_fluid.py
+++ b/release/scripts/startup/bl_ui/properties_physics_fluid.py
@@ -18,6 +18,7 @@
# <pep8 compliant>
import bpy
+from bpy.types import Panel
class PhysicButtonsPanel():
@@ -32,7 +33,7 @@ class PhysicButtonsPanel():
return (ob and ob.type == 'MESH') and (not rd.use_game_engine) and (context.fluid)
-class PHYSICS_PT_fluid(PhysicButtonsPanel, bpy.types.Panel):
+class PHYSICS_PT_fluid(PhysicButtonsPanel, Panel):
bl_label = "Fluid"
def draw(self, context):
@@ -186,7 +187,7 @@ class PHYSICS_PT_fluid(PhysicButtonsPanel, bpy.types.Panel):
sub.prop(fluid, "velocity_radius", text="Radius")
-class PHYSICS_PT_domain_gravity(PhysicButtonsPanel, bpy.types.Panel):
+class PHYSICS_PT_domain_gravity(PhysicButtonsPanel, Panel):
bl_label = "Domain World"
bl_options = {'DEFAULT_CLOSED'}
@@ -236,7 +237,7 @@ class PHYSICS_PT_domain_gravity(PhysicButtonsPanel, bpy.types.Panel):
col.prop(fluid, "compressibility", slider=True)
-class PHYSICS_PT_domain_boundary(PhysicButtonsPanel, bpy.types.Panel):
+class PHYSICS_PT_domain_boundary(PhysicButtonsPanel, Panel):
bl_label = "Domain Boundary"
bl_options = {'DEFAULT_CLOSED'}
@@ -257,6 +258,7 @@ class PHYSICS_PT_domain_boundary(PhysicButtonsPanel, bpy.types.Panel):
col.prop(fluid, "slip_type", text="")
if fluid.slip_type == 'PARTIALSLIP':
col.prop(fluid, "partial_slip_factor", slider=True, text="Amount")
+ col.prop(fluid, "surface_noobs")
col = split.column()
col.label(text="Surface:")
@@ -264,7 +266,7 @@ class PHYSICS_PT_domain_boundary(PhysicButtonsPanel, bpy.types.Panel):
col.prop(fluid, "surface_subdivisions", text="Subdivisions")
-class PHYSICS_PT_domain_particles(PhysicButtonsPanel, bpy.types.Panel):
+class PHYSICS_PT_domain_particles(PhysicButtonsPanel, Panel):
bl_label = "Domain Particles"
bl_options = {'DEFAULT_CLOSED'}
diff --git a/release/scripts/startup/bl_ui/properties_physics_smoke.py b/release/scripts/startup/bl_ui/properties_physics_smoke.py
index 61d8d2e3825..771a778380d 100644
--- a/release/scripts/startup/bl_ui/properties_physics_smoke.py
+++ b/release/scripts/startup/bl_ui/properties_physics_smoke.py
@@ -18,6 +18,7 @@
# <pep8 compliant>
import bpy
+from bpy.types import Panel
from bl_ui.properties_physics_common import (
@@ -38,7 +39,7 @@ class PhysicButtonsPanel():
return (ob and ob.type == 'MESH') and (not rd.use_game_engine) and (context.smoke)
-class PHYSICS_PT_smoke(PhysicButtonsPanel, bpy.types.Panel):
+class PHYSICS_PT_smoke(PhysicButtonsPanel, Panel):
bl_label = "Smoke"
def draw(self, context):
@@ -103,7 +104,7 @@ class PHYSICS_PT_smoke(PhysicButtonsPanel, bpy.types.Panel):
sub.prop(flow, "temperature")
-class PHYSICS_PT_smoke_groups(PhysicButtonsPanel, bpy.types.Panel):
+class PHYSICS_PT_smoke_groups(PhysicButtonsPanel, Panel):
bl_label = "Smoke Groups"
bl_options = {'DEFAULT_CLOSED'}
@@ -131,7 +132,7 @@ class PHYSICS_PT_smoke_groups(PhysicButtonsPanel, bpy.types.Panel):
col.prop(group, "collision_group", text="")
-class PHYSICS_PT_smoke_highres(PhysicButtonsPanel, bpy.types.Panel):
+class PHYSICS_PT_smoke_highres(PhysicButtonsPanel, Panel):
bl_label = "Smoke High Resolution"
bl_options = {'DEFAULT_CLOSED'}
@@ -168,7 +169,7 @@ class PHYSICS_PT_smoke_highres(PhysicButtonsPanel, bpy.types.Panel):
layout.prop(md, "show_high_resolution")
-class PHYSICS_PT_smoke_cache(PhysicButtonsPanel, bpy.types.Panel):
+class PHYSICS_PT_smoke_cache(PhysicButtonsPanel, Panel):
bl_label = "Smoke Cache"
bl_options = {'DEFAULT_CLOSED'}
@@ -189,7 +190,7 @@ class PHYSICS_PT_smoke_cache(PhysicButtonsPanel, bpy.types.Panel):
point_cache_ui(self, context, cache, (cache.is_baked is False), 'SMOKE')
-class PHYSICS_PT_smoke_field_weights(PhysicButtonsPanel, bpy.types.Panel):
+class PHYSICS_PT_smoke_field_weights(PhysicButtonsPanel, Panel):
bl_label = "Smoke Field Weights"
bl_options = {'DEFAULT_CLOSED'}
diff --git a/release/scripts/startup/bl_ui/properties_physics_softbody.py b/release/scripts/startup/bl_ui/properties_physics_softbody.py
index 61115a0590e..0b55ccf9516 100644
--- a/release/scripts/startup/bl_ui/properties_physics_softbody.py
+++ b/release/scripts/startup/bl_ui/properties_physics_softbody.py
@@ -18,6 +18,7 @@
# <pep8 compliant>
import bpy
+from bpy.types import Panel
from bl_ui.properties_physics_common import (
@@ -44,7 +45,7 @@ class PhysicButtonsPanel():
return (ob and (ob.type == 'MESH' or ob.type == 'LATTICE'or ob.type == 'CURVE')) and (not rd.use_game_engine) and (context.soft_body)
-class PHYSICS_PT_softbody(PhysicButtonsPanel, bpy.types.Panel):
+class PHYSICS_PT_softbody(PhysicButtonsPanel, Panel):
bl_label = "Soft Body"
def draw(self, context):
@@ -71,7 +72,7 @@ class PHYSICS_PT_softbody(PhysicButtonsPanel, bpy.types.Panel):
col.prop(softbody, "speed")
-class PHYSICS_PT_softbody_cache(PhysicButtonsPanel, bpy.types.Panel):
+class PHYSICS_PT_softbody_cache(PhysicButtonsPanel, Panel):
bl_label = "Soft Body Cache"
bl_options = {'DEFAULT_CLOSED'}
@@ -84,7 +85,7 @@ class PHYSICS_PT_softbody_cache(PhysicButtonsPanel, bpy.types.Panel):
point_cache_ui(self, context, md.point_cache, softbody_panel_enabled(md), 'SOFTBODY')
-class PHYSICS_PT_softbody_goal(PhysicButtonsPanel, bpy.types.Panel):
+class PHYSICS_PT_softbody_goal(PhysicButtonsPanel, Panel):
bl_label = "Soft Body Goal"
bl_options = {'DEFAULT_CLOSED'}
@@ -127,7 +128,7 @@ class PHYSICS_PT_softbody_goal(PhysicButtonsPanel, bpy.types.Panel):
layout.prop_search(softbody, "vertex_group_goal", ob, "vertex_groups", text="Vertex Group")
-class PHYSICS_PT_softbody_edge(PhysicButtonsPanel, bpy.types.Panel):
+class PHYSICS_PT_softbody_edge(PhysicButtonsPanel, Panel):
bl_label = "Soft Body Edges"
bl_options = {'DEFAULT_CLOSED'}
@@ -180,7 +181,7 @@ class PHYSICS_PT_softbody_edge(PhysicButtonsPanel, bpy.types.Panel):
col.prop(softbody, "use_face_collision", text="Face")
-class PHYSICS_PT_softbody_collision(PhysicButtonsPanel, bpy.types.Panel):
+class PHYSICS_PT_softbody_collision(PhysicButtonsPanel, Panel):
bl_label = "Soft Body Self Collision"
bl_options = {'DEFAULT_CLOSED'}
@@ -212,7 +213,7 @@ class PHYSICS_PT_softbody_collision(PhysicButtonsPanel, bpy.types.Panel):
col.prop(softbody, "ball_damp", text="Dampening")
-class PHYSICS_PT_softbody_solver(PhysicButtonsPanel, bpy.types.Panel):
+class PHYSICS_PT_softbody_solver(PhysicButtonsPanel, Panel):
bl_label = "Soft Body Solver"
bl_options = {'DEFAULT_CLOSED'}
@@ -248,7 +249,7 @@ class PHYSICS_PT_softbody_solver(PhysicButtonsPanel, bpy.types.Panel):
layout.prop(softbody, "use_estimate_matrix")
-class PHYSICS_PT_softbody_field_weights(PhysicButtonsPanel, bpy.types.Panel):
+class PHYSICS_PT_softbody_field_weights(PhysicButtonsPanel, Panel):
bl_label = "Soft Body Field Weights"
bl_options = {'DEFAULT_CLOSED'}
diff --git a/release/scripts/startup/bl_ui/properties_render.py b/release/scripts/startup/bl_ui/properties_render.py
index 4e1c1b34363..395cfc6934e 100644
--- a/release/scripts/startup/bl_ui/properties_render.py
+++ b/release/scripts/startup/bl_ui/properties_render.py
@@ -18,27 +18,28 @@
# <pep8 compliant>
import bpy
+from bpy.types import Menu, Panel
-class RENDER_MT_presets(bpy.types.Menu):
+class RENDER_MT_presets(Menu):
bl_label = "Render Presets"
preset_subdir = "render"
preset_operator = "script.execute_preset"
- draw = bpy.types.Menu.draw_preset
+ draw = Menu.draw_preset
-class RENDER_MT_ffmpeg_presets(bpy.types.Menu):
+class RENDER_MT_ffmpeg_presets(Menu):
bl_label = "FFMPEG Presets"
preset_subdir = "ffmpeg"
preset_operator = "script.python_file_run"
- draw = bpy.types.Menu.draw_preset
+ draw = Menu.draw_preset
-class RENDER_MT_framerate_presets(bpy.types.Menu):
+class RENDER_MT_framerate_presets(Menu):
bl_label = "Frame Rate Presets"
preset_subdir = "framerate"
preset_operator = "script.execute_preset"
- draw = bpy.types.Menu.draw_preset
+ draw = Menu.draw_preset
class RenderButtonsPanel():
@@ -53,7 +54,7 @@ class RenderButtonsPanel():
return (context.scene and rd.use_game_engine is False) and (rd.engine in cls.COMPAT_ENGINES)
-class RENDER_PT_render(RenderButtonsPanel, bpy.types.Panel):
+class RENDER_PT_render(RenderButtonsPanel, Panel):
bl_label = "Render"
COMPAT_ENGINES = {'BLENDER_RENDER'}
@@ -69,7 +70,7 @@ class RENDER_PT_render(RenderButtonsPanel, bpy.types.Panel):
layout.prop(rd, "display_mode", text="Display")
-class RENDER_PT_layers(RenderButtonsPanel, bpy.types.Panel):
+class RENDER_PT_layers(RenderButtonsPanel, Panel):
bl_label = "Layers"
bl_options = {'DEFAULT_CLOSED'}
COMPAT_ENGINES = {'BLENDER_RENDER'}
@@ -141,6 +142,7 @@ class RENDER_PT_layers(RenderButtonsPanel, bpy.types.Panel):
col.prop(rl, "use_pass_uv")
col.prop(rl, "use_pass_mist")
col.prop(rl, "use_pass_object_index")
+ col.prop(rl, "use_pass_material_index")
col.prop(rl, "use_pass_color")
col = split.column()
@@ -172,7 +174,7 @@ class RENDER_PT_layers(RenderButtonsPanel, bpy.types.Panel):
row.prop(rl, "exclude_refraction", text="")
-class RENDER_PT_dimensions(RenderButtonsPanel, bpy.types.Panel):
+class RENDER_PT_dimensions(RenderButtonsPanel, Panel):
bl_label = "Dimensions"
COMPAT_ENGINES = {'BLENDER_RENDER'}
@@ -239,7 +241,7 @@ class RENDER_PT_dimensions(RenderButtonsPanel, bpy.types.Panel):
subrow.prop(rd, "frame_map_new", text="New")
-class RENDER_PT_antialiasing(RenderButtonsPanel, bpy.types.Panel):
+class RENDER_PT_antialiasing(RenderButtonsPanel, Panel):
bl_label = "Anti-Aliasing"
COMPAT_ENGINES = {'BLENDER_RENDER'}
@@ -267,7 +269,7 @@ class RENDER_PT_antialiasing(RenderButtonsPanel, bpy.types.Panel):
col.prop(rd, "filter_size", text="Size")
-class RENDER_PT_motion_blur(RenderButtonsPanel, bpy.types.Panel):
+class RENDER_PT_motion_blur(RenderButtonsPanel, Panel):
bl_label = "Sampled Motion Blur"
bl_options = {'DEFAULT_CLOSED'}
COMPAT_ENGINES = {'BLENDER_RENDER'}
@@ -293,7 +295,7 @@ class RENDER_PT_motion_blur(RenderButtonsPanel, bpy.types.Panel):
row.prop(rd, "motion_blur_shutter")
-class RENDER_PT_shading(RenderButtonsPanel, bpy.types.Panel):
+class RENDER_PT_shading(RenderButtonsPanel, Panel):
bl_label = "Shading"
bl_options = {'DEFAULT_CLOSED'}
COMPAT_ENGINES = {'BLENDER_RENDER'}
@@ -317,7 +319,7 @@ class RENDER_PT_shading(RenderButtonsPanel, bpy.types.Panel):
col.prop(rd, "alpha_mode", text="Alpha")
-class RENDER_PT_performance(RenderButtonsPanel, bpy.types.Panel):
+class RENDER_PT_performance(RenderButtonsPanel, Panel):
bl_label = "Performance"
bl_options = {'DEFAULT_CLOSED'}
COMPAT_ENGINES = {'BLENDER_RENDER'}
@@ -360,7 +362,7 @@ class RENDER_PT_performance(RenderButtonsPanel, bpy.types.Panel):
sub.prop(rd, "use_local_coords", text="Local Coordinates")
-class RENDER_PT_post_processing(RenderButtonsPanel, bpy.types.Panel):
+class RENDER_PT_post_processing(RenderButtonsPanel, Panel):
bl_label = "Post Processing"
bl_options = {'DEFAULT_CLOSED'}
COMPAT_ENGINES = {'BLENDER_RENDER'}
@@ -376,8 +378,7 @@ class RENDER_PT_post_processing(RenderButtonsPanel, bpy.types.Panel):
col.prop(rd, "use_compositing")
col.prop(rd, "use_sequencer")
- col = split.column()
- col.prop(rd, "dither_intensity", text="Dither", slider=True)
+ split.prop(rd, "dither_intensity", text="Dither", slider=True)
layout.separator()
@@ -398,7 +399,7 @@ class RENDER_PT_post_processing(RenderButtonsPanel, bpy.types.Panel):
sub.prop(rd, "edge_color", text="")
-class RENDER_PT_stamp(RenderButtonsPanel, bpy.types.Panel):
+class RENDER_PT_stamp(RenderButtonsPanel, Panel):
bl_label = "Stamp"
bl_options = {'DEFAULT_CLOSED'}
COMPAT_ENGINES = {'BLENDER_RENDER'}
@@ -443,7 +444,7 @@ class RENDER_PT_stamp(RenderButtonsPanel, bpy.types.Panel):
sub.prop(rd, "stamp_note_text", text="")
-class RENDER_PT_output(RenderButtonsPanel, bpy.types.Panel):
+class RENDER_PT_output(RenderButtonsPanel, Panel):
bl_label = "Output"
COMPAT_ENGINES = {'BLENDER_RENDER'}
@@ -543,7 +544,7 @@ class RENDER_PT_output(RenderButtonsPanel, bpy.types.Panel):
col.prop(rd, "quicktime_audio_resampling_hq")
-class RENDER_PT_encoding(RenderButtonsPanel, bpy.types.Panel):
+class RENDER_PT_encoding(RenderButtonsPanel, Panel):
bl_label = "Encoding"
bl_options = {'DEFAULT_CLOSED'}
COMPAT_ENGINES = {'BLENDER_RENDER'}
@@ -591,16 +592,12 @@ class RENDER_PT_encoding(RenderButtonsPanel, bpy.types.Panel):
if rd.ffmpeg_format not in {'MP3'}:
layout.prop(rd, "ffmpeg_audio_codec", text="Audio Codec")
- split = layout.split()
-
- col = split.column()
- col.prop(rd, "ffmpeg_audio_bitrate")
- col.prop(rd, "ffmpeg_audio_mixrate")
-
- split.prop(rd, "ffmpeg_audio_volume", slider=True)
+ row = layout.row()
+ row.prop(rd, "ffmpeg_audio_bitrate")
+ row.prop(rd, "ffmpeg_audio_volume", slider=True)
-class RENDER_PT_bake(RenderButtonsPanel, bpy.types.Panel):
+class RENDER_PT_bake(RenderButtonsPanel, Panel):
bl_label = "Bake"
bl_options = {'DEFAULT_CLOSED'}
COMPAT_ENGINES = {'BLENDER_RENDER'}
diff --git a/release/scripts/startup/bl_ui/properties_scene.py b/release/scripts/startup/bl_ui/properties_scene.py
index ce5ac0c62d3..001897c222f 100644
--- a/release/scripts/startup/bl_ui/properties_scene.py
+++ b/release/scripts/startup/bl_ui/properties_scene.py
@@ -18,6 +18,7 @@
# <pep8 compliant>
import bpy
+from bpy.types import Operator, Panel
from rna_prop_ui import PropertyPanel
@@ -31,7 +32,7 @@ class SceneButtonsPanel():
return context.scene
-class SCENE_PT_scene(SceneButtonsPanel, bpy.types.Panel):
+class SCENE_PT_scene(SceneButtonsPanel, Panel):
bl_label = "Scene"
COMPAT_ENGINES = {'BLENDER_RENDER'}
@@ -43,7 +44,35 @@ class SCENE_PT_scene(SceneButtonsPanel, bpy.types.Panel):
layout.prop(scene, "background_set", text="Background")
-class SCENE_PT_unit(SceneButtonsPanel, bpy.types.Panel):
+class SCENE_PT_audio(SceneButtonsPanel, Panel):
+ bl_label = "Audio"
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
+
+ def draw(self, context):
+ layout = self.layout
+ scene = context.scene
+ rd = context.scene.render
+
+ layout.prop(scene, "audio_volume")
+ layout.operator("sound.bake_animation")
+
+ split = layout.split()
+
+ col = split.column()
+ col.label("Listener:")
+ col.prop(scene, "audio_distance_model", text="")
+ col.prop(scene, "audio_doppler_speed", text="Speed")
+ col.prop(scene, "audio_doppler_factor", text="Doppler")
+
+ col = split.column()
+ col.label("Format:")
+ col.prop(rd, "ffmpeg_audio_channels", text="")
+ col.prop(rd, "ffmpeg_audio_mixrate", text="Rate")
+
+ layout.operator("sound.mixdown")
+
+
+class SCENE_PT_unit(SceneButtonsPanel, Panel):
bl_label = "Units"
COMPAT_ENGINES = {'BLENDER_RENDER'}
@@ -61,7 +90,7 @@ class SCENE_PT_unit(SceneButtonsPanel, bpy.types.Panel):
row.prop(unit, "use_separate")
-class SCENE_PT_keying_sets(SceneButtonsPanel, bpy.types.Panel):
+class SCENE_PT_keying_sets(SceneButtonsPanel, Panel):
bl_label = "Keying Sets"
def draw(self, context):
@@ -94,7 +123,7 @@ class SCENE_PT_keying_sets(SceneButtonsPanel, bpy.types.Panel):
col.prop(ks, "bl_options")
-class SCENE_PT_keying_set_paths(SceneButtonsPanel, bpy.types.Panel):
+class SCENE_PT_keying_set_paths(SceneButtonsPanel, Panel):
bl_label = "Active Keying Set"
@classmethod
@@ -144,7 +173,7 @@ class SCENE_PT_keying_set_paths(SceneButtonsPanel, bpy.types.Panel):
col.prop(ksp, "bl_options")
-class SCENE_PT_physics(SceneButtonsPanel, bpy.types.Panel):
+class SCENE_PT_physics(SceneButtonsPanel, Panel):
bl_label = "Gravity"
COMPAT_ENGINES = {'BLENDER_RENDER'}
@@ -161,7 +190,7 @@ class SCENE_PT_physics(SceneButtonsPanel, bpy.types.Panel):
layout.prop(scene, "gravity", text="")
-class SCENE_PT_simplify(SceneButtonsPanel, bpy.types.Panel):
+class SCENE_PT_simplify(SceneButtonsPanel, Panel):
bl_label = "Simplify"
COMPAT_ENGINES = {'BLENDER_RENDER'}
@@ -190,7 +219,7 @@ class SCENE_PT_simplify(SceneButtonsPanel, bpy.types.Panel):
col.prop(rd, "simplify_ao_sss", text="AO and SSS")
-class SCENE_PT_custom_props(SceneButtonsPanel, PropertyPanel, bpy.types.Panel):
+class SCENE_PT_custom_props(SceneButtonsPanel, PropertyPanel, Panel):
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
_context_path = "scene"
_property_type = bpy.types.Scene
@@ -198,7 +227,7 @@ class SCENE_PT_custom_props(SceneButtonsPanel, PropertyPanel, bpy.types.Panel):
# XXX, move operator to op/ dir
-class ANIM_OT_keying_set_export(bpy.types.Operator):
+class ANIM_OT_keying_set_export(Operator):
"Export Keying Set to a python script."
bl_idname = "anim.keying_set_export"
bl_label = "Export Keying Set..."
diff --git a/release/scripts/startup/bl_ui/properties_texture.py b/release/scripts/startup/bl_ui/properties_texture.py
index 01890bc3c99..34f5a948ee7 100644
--- a/release/scripts/startup/bl_ui/properties_texture.py
+++ b/release/scripts/startup/bl_ui/properties_texture.py
@@ -18,10 +18,11 @@
# <pep8 compliant>
import bpy
+from bpy.types import Menu, Panel
from rna_prop_ui import PropertyPanel
-class TEXTURE_MT_specials(bpy.types.Menu):
+class TEXTURE_MT_specials(Menu):
bl_label = "Texture Specials"
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
@@ -32,7 +33,7 @@ class TEXTURE_MT_specials(bpy.types.Menu):
layout.operator("texture.slot_paste", icon='PASTEDOWN')
-class TEXTURE_MT_envmap_specials(bpy.types.Menu):
+class TEXTURE_MT_envmap_specials(Menu):
bl_label = "Environment Map Specials"
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
@@ -80,7 +81,7 @@ class TextureButtonsPanel():
return tex and (tex.type != 'NONE' or tex.use_nodes) and (context.scene.render.engine in cls.COMPAT_ENGINES)
-class TEXTURE_PT_context_texture(TextureButtonsPanel, bpy.types.Panel):
+class TEXTURE_PT_context_texture(TextureButtonsPanel, Panel):
bl_label = ""
bl_options = {'HIDE_HEADER'}
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
@@ -88,15 +89,15 @@ class TEXTURE_PT_context_texture(TextureButtonsPanel, bpy.types.Panel):
@classmethod
def poll(cls, context):
engine = context.scene.render.engine
- if not hasattr(context, "texture_slot"):
+ if not (hasattr(context, "texture_slot") or hasattr(context, "texture_node")):
return False
return ((context.material or context.world or context.lamp or context.brush or context.texture or context.particle_system or isinstance(context.space_data.pin_id, bpy.types.ParticleSettings))
and (engine in cls.COMPAT_ENGINES))
def draw(self, context):
layout = self.layout
- slot = context.texture_slot
- node = context.texture_node
+ slot = getattr(context, "texture_slot", None)
+ node = getattr(context, "texture_node", None)
space = context.space_data
tex = context.texture
idblock = context_tex_datablock(context)
@@ -150,7 +151,7 @@ class TEXTURE_PT_context_texture(TextureButtonsPanel, bpy.types.Panel):
split.prop(tex, "type", text="")
-class TEXTURE_PT_preview(TextureButtonsPanel, bpy.types.Panel):
+class TEXTURE_PT_preview(TextureButtonsPanel, Panel):
bl_label = "Preview"
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
@@ -167,7 +168,7 @@ class TEXTURE_PT_preview(TextureButtonsPanel, bpy.types.Panel):
layout.template_preview(tex, slot=slot)
-class TEXTURE_PT_colors(TextureButtonsPanel, bpy.types.Panel):
+class TEXTURE_PT_colors(TextureButtonsPanel, Panel):
bl_label = "Colors"
bl_options = {'DEFAULT_CLOSED'}
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
@@ -208,7 +209,7 @@ class TextureSlotPanel(TextureButtonsPanel):
return False
engine = context.scene.render.engine
- return TextureButtonsPanel.poll(self, context) and (engine in cls.COMPAT_ENGINES)
+ return TextureButtonsPanel.poll(cls, context) and (engine in cls.COMPAT_ENGINES)
# Texture Type Panels #
@@ -223,7 +224,7 @@ class TextureTypePanel(TextureButtonsPanel):
return tex and ((tex.type == cls.tex_type and not tex.use_nodes) and (engine in cls.COMPAT_ENGINES))
-class TEXTURE_PT_clouds(TextureTypePanel, bpy.types.Panel):
+class TEXTURE_PT_clouds(TextureTypePanel, Panel):
bl_label = "Clouds"
tex_type = 'CLOUDS'
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
@@ -247,7 +248,7 @@ class TEXTURE_PT_clouds(TextureTypePanel, bpy.types.Panel):
split.prop(tex, "nabla", text="Nabla")
-class TEXTURE_PT_wood(TextureTypePanel, bpy.types.Panel):
+class TEXTURE_PT_wood(TextureTypePanel, Panel):
bl_label = "Wood"
tex_type = 'WOOD'
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
@@ -276,7 +277,7 @@ class TEXTURE_PT_wood(TextureTypePanel, bpy.types.Panel):
split.prop(tex, "nabla")
-class TEXTURE_PT_marble(TextureTypePanel, bpy.types.Panel):
+class TEXTURE_PT_marble(TextureTypePanel, Panel):
bl_label = "Marble"
tex_type = 'MARBLE'
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
@@ -303,7 +304,7 @@ class TEXTURE_PT_marble(TextureTypePanel, bpy.types.Panel):
col.prop(tex, "nabla")
-class TEXTURE_PT_magic(TextureTypePanel, bpy.types.Panel):
+class TEXTURE_PT_magic(TextureTypePanel, Panel):
bl_label = "Magic"
tex_type = 'MAGIC'
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
@@ -318,7 +319,7 @@ class TEXTURE_PT_magic(TextureTypePanel, bpy.types.Panel):
row.prop(tex, "turbulence")
-class TEXTURE_PT_blend(TextureTypePanel, bpy.types.Panel):
+class TEXTURE_PT_blend(TextureTypePanel, Panel):
bl_label = "Blend"
tex_type = 'BLEND'
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
@@ -336,7 +337,7 @@ class TEXTURE_PT_blend(TextureTypePanel, bpy.types.Panel):
sub.prop(tex, "use_flip_axis", expand=True)
-class TEXTURE_PT_stucci(TextureTypePanel, bpy.types.Panel):
+class TEXTURE_PT_stucci(TextureTypePanel, Panel):
bl_label = "Stucci"
tex_type = 'STUCCI'
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
@@ -356,7 +357,7 @@ class TEXTURE_PT_stucci(TextureTypePanel, bpy.types.Panel):
row.prop(tex, "turbulence")
-class TEXTURE_PT_image(TextureTypePanel, bpy.types.Panel):
+class TEXTURE_PT_image(TextureTypePanel, Panel):
bl_label = "Image"
tex_type = 'IMAGE'
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
@@ -382,7 +383,7 @@ def texture_filter_common(tex, layout):
layout.prop(tex, "use_filter_size_min")
-class TEXTURE_PT_image_sampling(TextureTypePanel, bpy.types.Panel):
+class TEXTURE_PT_image_sampling(TextureTypePanel, Panel):
bl_label = "Image Sampling"
bl_options = {'DEFAULT_CLOSED'}
tex_type = 'IMAGE'
@@ -393,7 +394,7 @@ class TEXTURE_PT_image_sampling(TextureTypePanel, bpy.types.Panel):
idblock = context_tex_datablock(context)
tex = context.texture
- slot = context.texture_slot
+ slot = getattr(context, "texture_slot", None)
split = layout.split()
@@ -408,12 +409,16 @@ class TEXTURE_PT_image_sampling(TextureTypePanel, bpy.types.Panel):
col = split.column()
#Only for Material based textures, not for Lamp/World...
- if isinstance(idblock, bpy.types.Material):
+ if slot and isinstance(idblock, bpy.types.Material):
col.prop(tex, "use_normal_map")
row = col.row()
row.active = tex.use_normal_map
row.prop(slot, "normal_map_space", text="")
+ row = col.row()
+ row.active = not tex.use_normal_map
+ row.prop(tex, "use_derivative_map")
+
col.prop(tex, "use_mipmap")
row = col.row()
row.active = tex.use_mipmap
@@ -423,7 +428,7 @@ class TEXTURE_PT_image_sampling(TextureTypePanel, bpy.types.Panel):
texture_filter_common(tex, col)
-class TEXTURE_PT_image_mapping(TextureTypePanel, bpy.types.Panel):
+class TEXTURE_PT_image_mapping(TextureTypePanel, Panel):
bl_label = "Image Mapping"
bl_options = {'DEFAULT_CLOSED'}
tex_type = 'IMAGE'
@@ -479,7 +484,7 @@ class TEXTURE_PT_image_mapping(TextureTypePanel, bpy.types.Panel):
col.prop(tex, "crop_max_y", text="Y")
-class TEXTURE_PT_envmap(TextureTypePanel, bpy.types.Panel):
+class TEXTURE_PT_envmap(TextureTypePanel, Panel):
bl_label = "Environment Map"
tex_type = 'ENVIRONMENT_MAP'
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
@@ -517,7 +522,7 @@ class TEXTURE_PT_envmap(TextureTypePanel, bpy.types.Panel):
col.prop(env, "clip_end", text="End")
-class TEXTURE_PT_envmap_sampling(TextureTypePanel, bpy.types.Panel):
+class TEXTURE_PT_envmap_sampling(TextureTypePanel, Panel):
bl_label = "Environment Map Sampling"
bl_options = {'DEFAULT_CLOSED'}
tex_type = 'ENVIRONMENT_MAP'
@@ -531,7 +536,7 @@ class TEXTURE_PT_envmap_sampling(TextureTypePanel, bpy.types.Panel):
texture_filter_common(tex, layout)
-class TEXTURE_PT_musgrave(TextureTypePanel, bpy.types.Panel):
+class TEXTURE_PT_musgrave(TextureTypePanel, Panel):
bl_label = "Musgrave"
tex_type = 'MUSGRAVE'
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
@@ -568,7 +573,7 @@ class TEXTURE_PT_musgrave(TextureTypePanel, bpy.types.Panel):
row.prop(tex, "nabla")
-class TEXTURE_PT_voronoi(TextureTypePanel, bpy.types.Panel):
+class TEXTURE_PT_voronoi(TextureTypePanel, Panel):
bl_label = "Voronoi"
tex_type = 'VORONOI'
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
@@ -604,7 +609,7 @@ class TEXTURE_PT_voronoi(TextureTypePanel, bpy.types.Panel):
row.prop(tex, "nabla")
-class TEXTURE_PT_distortednoise(TextureTypePanel, bpy.types.Panel):
+class TEXTURE_PT_distortednoise(TextureTypePanel, Panel):
bl_label = "Distorted Noise"
tex_type = 'DISTORTED_NOISE'
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
@@ -626,7 +631,7 @@ class TEXTURE_PT_distortednoise(TextureTypePanel, bpy.types.Panel):
split.prop(tex, "nabla")
-class TEXTURE_PT_voxeldata(TextureButtonsPanel, bpy.types.Panel):
+class TEXTURE_PT_voxeldata(TextureButtonsPanel, Panel):
bl_label = "Voxel Data"
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
@@ -666,7 +671,7 @@ class TEXTURE_PT_voxeldata(TextureButtonsPanel, bpy.types.Panel):
layout.prop(vd, "intensity")
-class TEXTURE_PT_pointdensity(TextureButtonsPanel, bpy.types.Panel):
+class TEXTURE_PT_pointdensity(TextureButtonsPanel, Panel):
bl_label = "Point Density"
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
@@ -732,7 +737,7 @@ class TEXTURE_PT_pointdensity(TextureButtonsPanel, bpy.types.Panel):
col.template_curve_mapping(pd, "falloff_curve", brush=False)
-class TEXTURE_PT_pointdensity_turbulence(TextureButtonsPanel, bpy.types.Panel):
+class TEXTURE_PT_pointdensity_turbulence(TextureButtonsPanel, Panel):
bl_label = "Turbulence"
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
@@ -769,7 +774,7 @@ class TEXTURE_PT_pointdensity_turbulence(TextureButtonsPanel, bpy.types.Panel):
col.prop(pd, "turbulence_strength")
-class TEXTURE_PT_mapping(TextureSlotPanel, bpy.types.Panel):
+class TEXTURE_PT_mapping(TextureSlotPanel, Panel):
bl_label = "Mapping"
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
@@ -857,7 +862,7 @@ class TEXTURE_PT_mapping(TextureSlotPanel, bpy.types.Panel):
row.column().prop(tex, "scale")
-class TEXTURE_PT_influence(TextureSlotPanel, bpy.types.Panel):
+class TEXTURE_PT_influence(TextureSlotPanel, Panel):
bl_label = "Influence"
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
@@ -1024,16 +1029,18 @@ class TEXTURE_PT_influence(TextureSlotPanel, bpy.types.Panel):
# only show bump settings if activated but not for normalmap images
row = layout.row()
- row.active = (tex.use_map_normal or tex.use_map_warp) and not (tex.texture.type == 'IMAGE' and tex.texture.use_normal_map)
- row.prop(tex, "bump_method", text="Method")
+ sub = row.row()
+ sub.active = (tex.use_map_normal or tex.use_map_warp) and not (tex.texture.type == 'IMAGE' and (tex.texture.use_normal_map or tex.texture.use_derivative_map))
+ sub.prop(tex, "bump_method", text="Method")
+ # the space setting is supported for: derivmaps + bumpmaps (DEFAULT,BEST_QUALITY), not for normalmaps
sub = row.row()
- sub.active = tex.bump_method in {'BUMP_DEFAULT', 'BUMP_BEST_QUALITY'}
+ sub.active = (tex.use_map_normal or tex.use_map_warp) and not (tex.texture.type == 'IMAGE' and tex.texture.use_normal_map) and ((tex.bump_method in {'BUMP_DEFAULT', 'BUMP_BEST_QUALITY'}) or (tex.texture.type == 'IMAGE' and tex.texture.use_derivative_map))
sub.prop(tex, "bump_objectspace", text="Space")
-class TEXTURE_PT_custom_props(TextureButtonsPanel, PropertyPanel, bpy.types.Panel):
+class TEXTURE_PT_custom_props(TextureButtonsPanel, PropertyPanel, Panel):
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
_context_path = "texture"
_property_type = bpy.types.Texture
diff --git a/release/scripts/startup/bl_ui/properties_world.py b/release/scripts/startup/bl_ui/properties_world.py
index 4f398c9fbd9..71ee03296a0 100644
--- a/release/scripts/startup/bl_ui/properties_world.py
+++ b/release/scripts/startup/bl_ui/properties_world.py
@@ -18,10 +18,9 @@
# <pep8 compliant>
import bpy
+from bpy.types import Panel
from rna_prop_ui import PropertyPanel
-# TODO, "color_range" not in the UI
-
class WorldButtonsPanel():
bl_space_type = 'PROPERTIES'
@@ -34,7 +33,7 @@ class WorldButtonsPanel():
return (context.world and context.scene.render.engine in cls.COMPAT_ENGINES)
-class WORLD_PT_context_world(WorldButtonsPanel, bpy.types.Panel):
+class WORLD_PT_context_world(WorldButtonsPanel, Panel):
bl_label = ""
bl_options = {'HIDE_HEADER'}
COMPAT_ENGINES = {'BLENDER_RENDER'}
@@ -63,7 +62,7 @@ class WORLD_PT_context_world(WorldButtonsPanel, bpy.types.Panel):
split.label(text=str(texture_count), icon='TEXTURE')
-class WORLD_PT_preview(WorldButtonsPanel, bpy.types.Panel):
+class WORLD_PT_preview(WorldButtonsPanel, Panel):
bl_label = "Preview"
COMPAT_ENGINES = {'BLENDER_RENDER'}
@@ -76,7 +75,7 @@ class WORLD_PT_preview(WorldButtonsPanel, bpy.types.Panel):
self.layout.template_preview(context.world)
-class WORLD_PT_world(WorldButtonsPanel, bpy.types.Panel):
+class WORLD_PT_world(WorldButtonsPanel, Panel):
bl_label = "World"
COMPAT_ENGINES = {'BLENDER_RENDER'}
@@ -96,8 +95,12 @@ class WORLD_PT_world(WorldButtonsPanel, bpy.types.Panel):
col.active = world.use_sky_blend
row.column().prop(world, "ambient_color")
+ row = layout.row()
+ row.prop(world, "exposure")
+ row.prop(world, "color_range")
+
-class WORLD_PT_ambient_occlusion(WorldButtonsPanel, bpy.types.Panel):
+class WORLD_PT_ambient_occlusion(WorldButtonsPanel, Panel):
bl_label = "Ambient Occlusion"
COMPAT_ENGINES = {'BLENDER_RENDER'}
@@ -116,7 +119,7 @@ class WORLD_PT_ambient_occlusion(WorldButtonsPanel, bpy.types.Panel):
split.prop(light, "ao_blend_type", text="")
-class WORLD_PT_environment_lighting(WorldButtonsPanel, bpy.types.Panel):
+class WORLD_PT_environment_lighting(WorldButtonsPanel, Panel):
bl_label = "Environment Lighting"
COMPAT_ENGINES = {'BLENDER_RENDER'}
@@ -135,7 +138,7 @@ class WORLD_PT_environment_lighting(WorldButtonsPanel, bpy.types.Panel):
split.prop(light, "environment_color", text="")
-class WORLD_PT_indirect_lighting(WorldButtonsPanel, bpy.types.Panel):
+class WORLD_PT_indirect_lighting(WorldButtonsPanel, Panel):
bl_label = "Indirect Lighting"
COMPAT_ENGINES = {'BLENDER_RENDER'}
@@ -157,7 +160,7 @@ class WORLD_PT_indirect_lighting(WorldButtonsPanel, bpy.types.Panel):
layout.label(text="Only works with Approximate gather method")
-class WORLD_PT_gather(WorldButtonsPanel, bpy.types.Panel):
+class WORLD_PT_gather(WorldButtonsPanel, Panel):
bl_label = "Gather"
COMPAT_ENGINES = {'BLENDER_RENDER'}
@@ -205,7 +208,7 @@ class WORLD_PT_gather(WorldButtonsPanel, bpy.types.Panel):
col.prop(light, "correction")
-class WORLD_PT_mist(WorldButtonsPanel, bpy.types.Panel):
+class WORLD_PT_mist(WorldButtonsPanel, Panel):
bl_label = "Mist"
bl_options = {'DEFAULT_CLOSED'}
COMPAT_ENGINES = {'BLENDER_RENDER'}
@@ -234,7 +237,7 @@ class WORLD_PT_mist(WorldButtonsPanel, bpy.types.Panel):
layout.prop(world.mist_settings, "falloff")
-class WORLD_PT_stars(WorldButtonsPanel, bpy.types.Panel):
+class WORLD_PT_stars(WorldButtonsPanel, Panel):
bl_label = "Stars"
bl_options = {'DEFAULT_CLOSED'}
COMPAT_ENGINES = {'BLENDER_RENDER'}
@@ -261,7 +264,7 @@ class WORLD_PT_stars(WorldButtonsPanel, bpy.types.Panel):
col.prop(world.star_settings, "average_separation", text="Separation")
-class WORLD_PT_custom_props(WorldButtonsPanel, PropertyPanel, bpy.types.Panel):
+class WORLD_PT_custom_props(WorldButtonsPanel, PropertyPanel, Panel):
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
_context_path = "world"
_property_type = bpy.types.World
diff --git a/release/scripts/startup/bl_ui/space_console.py b/release/scripts/startup/bl_ui/space_console.py
index da6c102100b..cbbefa01a3c 100644
--- a/release/scripts/startup/bl_ui/space_console.py
+++ b/release/scripts/startup/bl_ui/space_console.py
@@ -18,32 +18,30 @@
# <pep8 compliant>
import bpy
+from bpy.types import Header, Menu, Operator
from bpy.props import StringProperty
-class CONSOLE_HT_header(bpy.types.Header):
+class CONSOLE_HT_header(Header):
bl_space_type = 'CONSOLE'
def draw(self, context):
- layout = self.layout
+ layout = self.layout.row(align=True)
- row = layout.row(align=True)
- row.template_header()
+ layout.template_header()
if context.area.show_menus:
- sub = row.row(align=True)
- sub.menu("CONSOLE_MT_console")
+ layout.menu("CONSOLE_MT_console")
- row = layout.row(align=True)
- row.operator("console.autocomplete", text="Autocomplete")
+ layout.operator("console.autocomplete", text="Autocomplete")
-class CONSOLE_MT_console(bpy.types.Menu):
+class CONSOLE_MT_console(Menu):
bl_label = "Console"
def draw(self, context):
layout = self.layout
- layout.column()
+
layout.operator("console.clear")
layout.operator("console.copy")
layout.operator("console.paste")
@@ -55,7 +53,7 @@ class CONSOLE_MT_console(bpy.types.Menu):
layout.operator("screen.screen_full_area")
-class CONSOLE_MT_language(bpy.types.Menu):
+class CONSOLE_MT_language(Menu):
bl_label = "Languages..."
def draw(self, context):
@@ -82,7 +80,7 @@ def add_scrollback(text, text_type):
type=text_type)
-class ConsoleExec(bpy.types.Operator):
+class ConsoleExec(Operator):
'''Execute the current console line as a python expression'''
bl_idname = "console.execute"
bl_label = "Console Execute"
@@ -100,7 +98,7 @@ class ConsoleExec(bpy.types.Operator):
return {'FINISHED'}
-class ConsoleAutocomplete(bpy.types.Operator):
+class ConsoleAutocomplete(Operator):
'''Evaluate the namespace up until the cursor and give a list of options or complete the name if there is only one'''
bl_idname = "console.autocomplete"
bl_label = "Console Autocomplete"
@@ -117,7 +115,7 @@ class ConsoleAutocomplete(bpy.types.Operator):
return {'FINISHED'}
-class ConsoleBanner(bpy.types.Operator):
+class ConsoleBanner(Operator):
'''Print a message whem the terminal initializes'''
bl_idname = "console.banner"
bl_label = "Console Banner"
@@ -139,11 +137,15 @@ class ConsoleBanner(bpy.types.Operator):
return {'FINISHED'}
-class ConsoleLanguage(bpy.types.Operator):
+class ConsoleLanguage(Operator):
'''Set the current language for this console'''
bl_idname = "console.language"
bl_label = "Console Language"
- language = StringProperty(name="Language", maxlen=32, default="")
+
+ language = StringProperty(
+ name="Language",
+ maxlen=32,
+ )
def execute(self, context):
sc = context.space_data
diff --git a/release/scripts/startup/bl_ui/space_dopesheet.py b/release/scripts/startup/bl_ui/space_dopesheet.py
index 930a2029d32..90dcc99e6d7 100644
--- a/release/scripts/startup/bl_ui/space_dopesheet.py
+++ b/release/scripts/startup/bl_ui/space_dopesheet.py
@@ -19,6 +19,7 @@
# <pep8 compliant>
import bpy
+from bpy.types import Header, Menu
#######################################
@@ -33,41 +34,10 @@ def dopesheet_filter(layout, context, genericFiltersOnly=False):
row.prop(dopesheet, "show_only_selected", text="")
row.prop(dopesheet, "show_hidden", text="")
- if not genericFiltersOnly:
- row = layout.row(align=True)
- row.prop(dopesheet, "show_transforms", text="")
-
- if is_nla:
- row.prop(dopesheet, "show_missing_nla", text="")
-
- row = layout.row(align=True)
- row.prop(dopesheet, "show_scenes", text="")
- row.prop(dopesheet, "show_worlds", text="")
- row.prop(dopesheet, "show_nodes", text="")
-
- if bpy.data.meshes:
- row.prop(dopesheet, "show_meshes", text="")
- if bpy.data.shape_keys:
- row.prop(dopesheet, "show_shapekeys", text="")
- if bpy.data.materials:
- row.prop(dopesheet, "show_materials", text="")
- if bpy.data.lamps:
- row.prop(dopesheet, "show_lamps", text="")
- if bpy.data.textures:
- row.prop(dopesheet, "show_textures", text="")
- if bpy.data.cameras:
- row.prop(dopesheet, "show_cameras", text="")
- if bpy.data.curves:
- row.prop(dopesheet, "show_curves", text="")
- if bpy.data.metaballs:
- row.prop(dopesheet, "show_metaballs", text="")
- if bpy.data.lattices:
- row.prop(dopesheet, "show_lattices", text="")
- if bpy.data.armatures:
- row.prop(dopesheet, "show_armatures", text="")
- if bpy.data.particles:
- row.prop(dopesheet, "show_particles", text="")
+ if is_nla:
+ row.prop(dopesheet, "show_missing_nla", text="")
+ if not genericFiltersOnly:
if bpy.data.groups:
row = layout.row(align=True)
row.prop(dopesheet, "show_only_group_objects", text="")
@@ -80,11 +50,47 @@ def dopesheet_filter(layout, context, genericFiltersOnly=False):
if dopesheet.show_only_matching_fcurves:
row.prop(dopesheet, "filter_fcurve_name", text="")
+ if not genericFiltersOnly:
+ row = layout.row(align=True)
+ row.prop(dopesheet, "show_datablock_filters", text="Filters")
+
+ if dopesheet.show_datablock_filters:
+ row.prop(dopesheet, "show_scenes", text="")
+ row.prop(dopesheet, "show_worlds", text="")
+ row.prop(dopesheet, "show_nodes", text="")
+
+ row.prop(dopesheet, "show_transforms", text="")
+
+ if bpy.data.meshes:
+ row.prop(dopesheet, "show_meshes", text="")
+ if bpy.data.shape_keys:
+ row.prop(dopesheet, "show_shapekeys", text="")
+ if bpy.data.materials:
+ row.prop(dopesheet, "show_materials", text="")
+ if bpy.data.lamps:
+ row.prop(dopesheet, "show_lamps", text="")
+ if bpy.data.textures:
+ row.prop(dopesheet, "show_textures", text="")
+ if bpy.data.cameras:
+ row.prop(dopesheet, "show_cameras", text="")
+ if bpy.data.curves:
+ row.prop(dopesheet, "show_curves", text="")
+ if bpy.data.metaballs:
+ row.prop(dopesheet, "show_metaballs", text="")
+ if bpy.data.lattices:
+ row.prop(dopesheet, "show_lattices", text="")
+ if bpy.data.armatures:
+ row.prop(dopesheet, "show_armatures", text="")
+ if bpy.data.particles:
+ row.prop(dopesheet, "show_particles", text="")
+ if bpy.data.speakers:
+ row.prop(dopesheet, "show_speakers", text="")
+
#######################################
# DopeSheet Editor - General/Standard UI
-class DOPESHEET_HT_header(bpy.types.Header):
+class DOPESHEET_HT_header(Header):
bl_space_type = 'DOPESHEET_EDITOR'
def draw(self, context):
@@ -96,21 +102,19 @@ class DOPESHEET_HT_header(bpy.types.Header):
row.template_header()
if context.area.show_menus:
- sub = row.row(align=True)
+ row.menu("DOPESHEET_MT_view")
+ row.menu("DOPESHEET_MT_select")
+ row.menu("DOPESHEET_MT_marker")
- sub.menu("DOPESHEET_MT_view")
- sub.menu("DOPESHEET_MT_select")
- sub.menu("DOPESHEET_MT_marker")
-
- if st.mode == 'DOPESHEET' or (st.mode == 'ACTION' and st.action != None):
- sub.menu("DOPESHEET_MT_channel")
+ if st.mode == 'DOPESHEET' or (st.mode == 'ACTION' and st.action is not None):
+ row.menu("DOPESHEET_MT_channel")
elif st.mode == 'GPENCIL':
- sub.menu("DOPESHEET_MT_gpencil_channel")
+ row.menu("DOPESHEET_MT_gpencil_channel")
if st.mode != 'GPENCIL':
- sub.menu("DOPESHEET_MT_key")
+ row.menu("DOPESHEET_MT_key")
else:
- sub.menu("DOPESHEET_MT_gpencil_frame")
+ row.menu("DOPESHEET_MT_gpencil_frame")
layout.prop(st, "mode", text="")
layout.prop(st.dopesheet, "show_summary", text="Summary")
@@ -134,7 +138,7 @@ class DOPESHEET_HT_header(bpy.types.Header):
row.operator("action.paste", text="", icon='PASTEDOWN')
-class DOPESHEET_MT_view(bpy.types.Menu):
+class DOPESHEET_MT_view(Menu):
bl_label = "View"
def draw(self, context):
@@ -142,8 +146,6 @@ class DOPESHEET_MT_view(bpy.types.Menu):
st = context.space_data
- layout.column()
-
layout.prop(st, "use_realtime_update")
layout.prop(st, "show_frame_indicator")
layout.prop(st, "show_sliders")
@@ -170,13 +172,12 @@ class DOPESHEET_MT_view(bpy.types.Menu):
layout.operator("screen.screen_full_area")
-class DOPESHEET_MT_select(bpy.types.Menu):
+class DOPESHEET_MT_select(Menu):
bl_label = "Select"
def draw(self, context):
layout = self.layout
- layout.column()
# This is a bit misleading as the operator's default text is "Select All" while it actually *toggles* All/None
layout.operator("action.select_all_toggle")
layout.operator("action.select_all_toggle", text="Invert Selection").invert = True
@@ -206,7 +207,7 @@ class DOPESHEET_MT_select(bpy.types.Menu):
layout.operator("action.select_linked")
-class DOPESHEET_MT_marker(bpy.types.Menu):
+class DOPESHEET_MT_marker(Menu):
bl_label = "Marker"
def draw(self, context):
@@ -216,7 +217,6 @@ class DOPESHEET_MT_marker(bpy.types.Menu):
#layout.operator_context = 'EXEC_REGION_WIN'
- layout.column()
layout.operator("marker.add", "Add Marker")
layout.operator("marker.duplicate", text="Duplicate Marker")
layout.operator("marker.delete", text="Delete Marker")
@@ -237,7 +237,7 @@ class DOPESHEET_MT_marker(bpy.types.Menu):
#######################################
# Keyframe Editing
-class DOPESHEET_MT_channel(bpy.types.Menu):
+class DOPESHEET_MT_channel(Menu):
bl_label = "Channel"
def draw(self, context):
@@ -245,7 +245,6 @@ class DOPESHEET_MT_channel(bpy.types.Menu):
layout.operator_context = 'INVOKE_REGION_CHANNELS'
- layout.column()
layout.operator("anim.channels_delete")
layout.separator()
@@ -268,13 +267,12 @@ class DOPESHEET_MT_channel(bpy.types.Menu):
layout.operator("anim.channels_fcurves_enable")
-class DOPESHEET_MT_key(bpy.types.Menu):
+class DOPESHEET_MT_key(Menu):
bl_label = "Key"
def draw(self, context):
layout = self.layout
- layout.column()
layout.menu("DOPESHEET_MT_key_transform", text="Transform")
layout.operator_menu_enum("action.snap", "type", text="Snap")
@@ -284,7 +282,7 @@ class DOPESHEET_MT_key(bpy.types.Menu):
layout.operator("action.keyframe_insert")
layout.separator()
- layout.operator("action.duplicate")
+ layout.operator("action.duplicate_move")
layout.operator("action.delete")
layout.separator()
@@ -301,13 +299,12 @@ class DOPESHEET_MT_key(bpy.types.Menu):
layout.operator("action.paste")
-class DOPESHEET_MT_key_transform(bpy.types.Menu):
+class DOPESHEET_MT_key_transform(Menu):
bl_label = "Transform"
def draw(self, context):
layout = self.layout
- layout.column()
layout.operator("transform.transform", text="Grab/Move").mode = 'TIME_TRANSLATE'
layout.operator("transform.transform", text="Extend").mode = 'TIME_EXTEND'
layout.operator("transform.transform", text="Slide").mode = 'TIME_SLIDE'
@@ -317,7 +314,7 @@ class DOPESHEET_MT_key_transform(bpy.types.Menu):
#######################################
# Grease Pencil Editing
-class DOPESHEET_MT_gpencil_channel(bpy.types.Menu):
+class DOPESHEET_MT_gpencil_channel(Menu):
bl_label = "Channel"
def draw(self, context):
@@ -325,7 +322,6 @@ class DOPESHEET_MT_gpencil_channel(bpy.types.Menu):
layout.operator_context = 'INVOKE_REGION_CHANNELS'
- layout.column()
layout.operator("anim.channels_delete")
layout.separator()
@@ -345,13 +341,12 @@ class DOPESHEET_MT_gpencil_channel(bpy.types.Menu):
#layout.operator_menu_enum("anim.channels_move", "direction", text="Move...")
-class DOPESHEET_MT_gpencil_frame(bpy.types.Menu):
+class DOPESHEET_MT_gpencil_frame(Menu):
bl_label = "Frame"
def draw(self, context):
layout = self.layout
- layout.column()
layout.menu("DOPESHEET_MT_key_transform", text="Transform")
#layout.operator_menu_enum("action.snap", "type", text="Snap")
diff --git a/release/scripts/startup/bl_ui/space_filebrowser.py b/release/scripts/startup/bl_ui/space_filebrowser.py
index 73fe1a97252..cf0d10c5844 100644
--- a/release/scripts/startup/bl_ui/space_filebrowser.py
+++ b/release/scripts/startup/bl_ui/space_filebrowser.py
@@ -18,9 +18,10 @@
# <pep8 compliant>
import bpy
+from bpy.types import Header
-class FILEBROWSER_HT_header(bpy.types.Header):
+class FILEBROWSER_HT_header(Header):
bl_space_type = 'FILE_BROWSER'
def draw(self, context):
diff --git a/release/scripts/startup/bl_ui/space_graph.py b/release/scripts/startup/bl_ui/space_graph.py
index bfc1a0e3a23..d4b8c415a7f 100644
--- a/release/scripts/startup/bl_ui/space_graph.py
+++ b/release/scripts/startup/bl_ui/space_graph.py
@@ -19,9 +19,10 @@
# <pep8 compliant>
import bpy
+from bpy.types import Header, Menu
-class GRAPH_HT_header(bpy.types.Header):
+class GRAPH_HT_header(Header):
bl_space_type = 'GRAPH_EDITOR'
def draw(self, context):
@@ -35,13 +36,11 @@ class GRAPH_HT_header(bpy.types.Header):
row.template_header()
if context.area.show_menus:
- sub = row.row(align=True)
-
- sub.menu("GRAPH_MT_view")
- sub.menu("GRAPH_MT_select")
- sub.menu("GRAPH_MT_marker")
- sub.menu("GRAPH_MT_channel")
- sub.menu("GRAPH_MT_key")
+ row.menu("GRAPH_MT_view")
+ row.menu("GRAPH_MT_select")
+ row.menu("GRAPH_MT_marker")
+ row.menu("GRAPH_MT_channel")
+ row.menu("GRAPH_MT_key")
layout.prop(st, "mode", text="")
@@ -61,7 +60,7 @@ class GRAPH_HT_header(bpy.types.Header):
row.operator("graph.ghost_curves_create", text="", icon='GHOST_ENABLED')
-class GRAPH_MT_view(bpy.types.Menu):
+class GRAPH_MT_view(Menu):
bl_label = "View"
def draw(self, context):
@@ -69,8 +68,6 @@ class GRAPH_MT_view(bpy.types.Menu):
st = context.space_data
- layout.column()
-
layout.operator("graph.properties", icon='MENU_PANEL')
layout.separator()
@@ -81,7 +78,7 @@ class GRAPH_MT_view(bpy.types.Menu):
layout.prop(st, "use_auto_merge_keyframes")
layout.separator()
- layout.prop(st, "use_fancy_drawing")
+ layout.prop(st, "use_beauty_drawing")
layout.separator()
if st.show_handles:
@@ -107,13 +104,12 @@ class GRAPH_MT_view(bpy.types.Menu):
layout.operator("screen.screen_full_area")
-class GRAPH_MT_select(bpy.types.Menu):
+class GRAPH_MT_select(Menu):
bl_label = "Select"
def draw(self, context):
layout = self.layout
- layout.column()
# This is a bit misleading as the operator's default text is "Select All" while it actually *toggles* All/None
layout.operator("graph.select_all_toggle")
layout.operator("graph.select_all_toggle", text="Invert Selection").invert = True
@@ -142,7 +138,7 @@ class GRAPH_MT_select(bpy.types.Menu):
layout.operator("graph.select_linked")
-class GRAPH_MT_marker(bpy.types.Menu):
+class GRAPH_MT_marker(Menu):
bl_label = "Marker"
def draw(self, context):
@@ -150,7 +146,6 @@ class GRAPH_MT_marker(bpy.types.Menu):
#layout.operator_context = 'EXEC_REGION_WIN'
- layout.column()
layout.operator("marker.add", "Add Marker")
layout.operator("marker.duplicate", text="Duplicate Marker")
layout.operator("marker.delete", text="Delete Marker")
@@ -163,7 +158,7 @@ class GRAPH_MT_marker(bpy.types.Menu):
# TODO: pose markers for action edit mode only?
-class GRAPH_MT_channel(bpy.types.Menu):
+class GRAPH_MT_channel(Menu):
bl_label = "Channel"
def draw(self, context):
@@ -171,7 +166,6 @@ class GRAPH_MT_channel(bpy.types.Menu):
layout.operator_context = 'INVOKE_REGION_CHANNELS'
- layout.column()
layout.operator("anim.channels_delete")
layout.separator()
@@ -195,13 +189,12 @@ class GRAPH_MT_channel(bpy.types.Menu):
layout.operator("anim.channels_fcurves_enable")
-class GRAPH_MT_key(bpy.types.Menu):
+class GRAPH_MT_key(Menu):
bl_label = "Key"
def draw(self, context):
layout = self.layout
- layout.column()
layout.menu("GRAPH_MT_key_transform", text="Transform")
layout.operator_menu_enum("graph.snap", "type", text="Snap")
@@ -213,7 +206,7 @@ class GRAPH_MT_key(bpy.types.Menu):
layout.operator("graph.sound_bake")
layout.separator()
- layout.operator("graph.duplicate")
+ layout.operator("graph.duplicate_move")
layout.operator("graph.delete")
layout.separator()
@@ -234,13 +227,12 @@ class GRAPH_MT_key(bpy.types.Menu):
layout.operator("graph.euler_filter", text="Discontinuity (Euler) Filter")
-class GRAPH_MT_key_transform(bpy.types.Menu):
+class GRAPH_MT_key_transform(Menu):
bl_label = "Transform"
def draw(self, context):
layout = self.layout
- layout.column()
layout.operator("transform.translate", text="Grab/Move")
layout.operator("transform.transform", text="Extend").mode = 'TIME_EXTEND'
layout.operator("transform.rotate", text="Rotate")
diff --git a/release/scripts/startup/bl_ui/space_image.py b/release/scripts/startup/bl_ui/space_image.py
index 9f69ca17076..97b5d8457e0 100644
--- a/release/scripts/startup/bl_ui/space_image.py
+++ b/release/scripts/startup/bl_ui/space_image.py
@@ -18,6 +18,7 @@
# <pep8 compliant>
import bpy
+from bpy.types import Header, Menu, Panel
class BrushButtonsPanel():
@@ -31,7 +32,7 @@ class BrushButtonsPanel():
return sima.show_paint and toolsettings.brush
-class IMAGE_MT_view(bpy.types.Menu):
+class IMAGE_MT_view(Menu):
bl_label = "View"
def draw(self, context):
@@ -79,7 +80,7 @@ class IMAGE_MT_view(bpy.types.Menu):
layout.operator("screen.screen_full_area")
-class IMAGE_MT_select(bpy.types.Menu):
+class IMAGE_MT_select(Menu):
bl_label = "Select"
def draw(self, context):
@@ -100,7 +101,7 @@ class IMAGE_MT_select(bpy.types.Menu):
layout.operator("uv.select_linked")
-class IMAGE_MT_image(bpy.types.Menu):
+class IMAGE_MT_image(Menu):
bl_label = "Image"
def draw(self, context):
@@ -151,7 +152,7 @@ class IMAGE_MT_image(bpy.types.Menu):
layout.prop(sima, "use_image_paint")
-class IMAGE_MT_image_invert(bpy.types.Menu):
+class IMAGE_MT_image_invert(Menu):
bl_label = "Invert"
def draw(self, context):
@@ -177,7 +178,7 @@ class IMAGE_MT_image_invert(bpy.types.Menu):
op.invert_a = True
-class IMAGE_MT_uvs_showhide(bpy.types.Menu):
+class IMAGE_MT_uvs_showhide(Menu):
bl_label = "Show/Hide Faces"
def draw(self, context):
@@ -188,7 +189,7 @@ class IMAGE_MT_uvs_showhide(bpy.types.Menu):
layout.operator("uv.hide", text="Hide Unselected").unselected = True
-class IMAGE_MT_uvs_transform(bpy.types.Menu):
+class IMAGE_MT_uvs_transform(Menu):
bl_label = "Transform"
def draw(self, context):
@@ -198,8 +199,12 @@ class IMAGE_MT_uvs_transform(bpy.types.Menu):
layout.operator("transform.rotate")
layout.operator("transform.resize")
+ layout.separator()
+
+ layout.operator("transform.shear")
+
-class IMAGE_MT_uvs_snap(bpy.types.Menu):
+class IMAGE_MT_uvs_snap(Menu):
bl_label = "Snap"
def draw(self, context):
@@ -216,7 +221,7 @@ class IMAGE_MT_uvs_snap(bpy.types.Menu):
layout.operator("uv.snap_cursor", text="Cursor to Selected").target = 'SELECTED'
-class IMAGE_MT_uvs_mirror(bpy.types.Menu):
+class IMAGE_MT_uvs_mirror(Menu):
bl_label = "Mirror"
def draw(self, context):
@@ -227,7 +232,7 @@ class IMAGE_MT_uvs_mirror(bpy.types.Menu):
layout.operator("transform.mirror", text="Y Axis").constraint_axis[1] = True
-class IMAGE_MT_uvs_weldalign(bpy.types.Menu):
+class IMAGE_MT_uvs_weldalign(Menu):
bl_label = "Weld/Align"
def draw(self, context):
@@ -237,7 +242,7 @@ class IMAGE_MT_uvs_weldalign(bpy.types.Menu):
layout.operator_enum("uv.align", "axis") # W, 2/3/4
-class IMAGE_MT_uvs(bpy.types.Menu):
+class IMAGE_MT_uvs(Menu):
bl_label = "UVs"
def draw(self, context):
@@ -282,7 +287,7 @@ class IMAGE_MT_uvs(bpy.types.Menu):
layout.menu("IMAGE_MT_uvs_showhide")
-class IMAGE_MT_uvs_select_mode(bpy.types.Menu):
+class IMAGE_MT_uvs_select_mode(Menu):
bl_label = "UV Select Mode"
def draw(self, context):
@@ -324,7 +329,7 @@ class IMAGE_MT_uvs_select_mode(bpy.types.Menu):
prop.data_path = "tool_settings.uv_select_mode"
-class IMAGE_HT_header(bpy.types.Header):
+class IMAGE_HT_header(Header):
bl_space_type = 'IMAGE_EDITOR'
def draw(self, context):
@@ -382,7 +387,7 @@ class IMAGE_HT_header(bpy.types.Header):
row = layout.row(align=True)
row.prop(toolsettings, "use_snap", text="")
- row.prop(toolsettings, "snap_element", text="", icon_only=True)
+ row.prop(toolsettings, "snap_target", text="")
mesh = context.edit_object.data
layout.prop_search(mesh.uv_textures, "active", mesh, "uv_textures", text="")
@@ -408,7 +413,7 @@ class IMAGE_HT_header(bpy.types.Header):
layout.prop(sima, "use_realtime_update", text="", icon_only=True, icon='LOCKED')
-class IMAGE_PT_image_properties(bpy.types.Panel):
+class IMAGE_PT_image_properties(Panel):
bl_space_type = 'IMAGE_EDITOR'
bl_region_type = 'UI'
bl_label = "Image"
@@ -427,14 +432,13 @@ class IMAGE_PT_image_properties(bpy.types.Panel):
layout.template_image(sima, "image", iuser)
-class IMAGE_PT_game_properties(bpy.types.Panel):
+class IMAGE_PT_game_properties(Panel):
bl_space_type = 'IMAGE_EDITOR'
bl_region_type = 'UI'
bl_label = "Game Properties"
@classmethod
def poll(cls, context):
- rd = context.scene.render
sima = context.space_data
# display even when not in game mode because these settings effect the 3d view
return (sima and sima.image) # and (rd.engine == 'BLENDER_GAME')
@@ -449,14 +453,12 @@ class IMAGE_PT_game_properties(bpy.types.Panel):
col = split.column()
+ col.prop(ima, "use_animation")
sub = col.column(align=True)
- sub.prop(ima, "use_animation")
-
- subsub = sub.column()
- subsub.active = ima.use_animation
- subsub.prop(ima, "frame_start", text="Start")
- subsub.prop(ima, "frame_end", text="End")
- subsub.prop(ima, "fps", text="Speed")
+ sub.active = ima.use_animation
+ sub.prop(ima, "frame_start", text="Start")
+ sub.prop(ima, "frame_end", text="End")
+ sub.prop(ima, "fps", text="Speed")
col.prop(ima, "use_tiles")
sub = col.column(align=True)
@@ -472,7 +474,7 @@ class IMAGE_PT_game_properties(bpy.types.Panel):
col.prop(ima, "mapping", expand=True)
-class IMAGE_PT_view_histogram(bpy.types.Panel):
+class IMAGE_PT_view_histogram(Panel):
bl_space_type = 'IMAGE_EDITOR'
bl_region_type = 'PREVIEW'
bl_label = "Histogram"
@@ -491,7 +493,7 @@ class IMAGE_PT_view_histogram(bpy.types.Panel):
layout.prop(sima.scopes.histogram, "mode", icon_only=True)
-class IMAGE_PT_view_waveform(bpy.types.Panel):
+class IMAGE_PT_view_waveform(Panel):
bl_space_type = 'IMAGE_EDITOR'
bl_region_type = 'PREVIEW'
bl_label = "Waveform"
@@ -505,13 +507,14 @@ class IMAGE_PT_view_waveform(bpy.types.Panel):
layout = self.layout
sima = context.space_data
+
layout.template_waveform(sima, "scopes")
- sub = layout.row().split(percentage=0.75)
- sub.prop(sima.scopes, "waveform_alpha")
- sub.prop(sima.scopes, "waveform_mode", text="", icon_only=True)
+ row = layout.split(percentage=0.75)
+ row.prop(sima.scopes, "waveform_alpha")
+ row.prop(sima.scopes, "waveform_mode", text="", icon_only=True)
-class IMAGE_PT_view_vectorscope(bpy.types.Panel):
+class IMAGE_PT_view_vectorscope(Panel):
bl_space_type = 'IMAGE_EDITOR'
bl_region_type = 'PREVIEW'
bl_label = "Vectorscope"
@@ -529,7 +532,7 @@ class IMAGE_PT_view_vectorscope(bpy.types.Panel):
layout.prop(sima.scopes, "vectorscope_alpha")
-class IMAGE_PT_sample_line(bpy.types.Panel):
+class IMAGE_PT_sample_line(Panel):
bl_space_type = 'IMAGE_EDITOR'
bl_region_type = 'PREVIEW'
bl_label = "Sample Line"
@@ -541,13 +544,15 @@ class IMAGE_PT_sample_line(bpy.types.Panel):
def draw(self, context):
layout = self.layout
- layout.operator("image.sample_line")
+
sima = context.space_data
+
+ layout.operator("image.sample_line")
layout.template_histogram(sima, "sample_histogram")
layout.prop(sima.sample_histogram, "mode")
-class IMAGE_PT_scope_sample(bpy.types.Panel):
+class IMAGE_PT_scope_sample(Panel):
bl_space_type = 'IMAGE_EDITOR'
bl_region_type = 'PREVIEW'
bl_label = "Scope Samples"
@@ -559,16 +564,17 @@ class IMAGE_PT_scope_sample(bpy.types.Panel):
def draw(self, context):
layout = self.layout
+
sima = context.space_data
- split = layout.split()
- row = split.row()
+
+ row = layout.row()
row.prop(sima.scopes, "use_full_resolution")
- row = split.row()
- row.active = not sima.scopes.use_full_resolution
- row.prop(sima.scopes, "accuracy")
+ sub = row.row()
+ sub.active = not sima.scopes.use_full_resolution
+ sub.prop(sima.scopes, "accuracy")
-class IMAGE_PT_view_properties(bpy.types.Panel):
+class IMAGE_PT_view_properties(Panel):
bl_space_type = 'IMAGE_EDITOR'
bl_region_type = 'UI'
bl_label = "Display"
@@ -605,21 +611,20 @@ class IMAGE_PT_view_properties(bpy.types.Panel):
if show_uvedit:
col = layout.column()
- col.label("Cursor Location")
- row = col.row()
- row.prop(uvedit, "cursor_location", text="")
+ col.label("Cursor Location:")
+ col.row().prop(uvedit, "cursor_location", text="")
+
+ col.separator()
- col = layout.column()
col.label(text="UVs:")
- row = col.row()
- row.prop(uvedit, "edge_draw_type", expand=True)
+ col.row().prop(uvedit, "edge_draw_type", expand=True)
split = layout.split()
+
col = split.column()
+ col.prop(uvedit, "show_faces")
col.prop(uvedit, "show_smooth_edges", text="Smooth")
col.prop(uvedit, "show_modified_edges", text="Modified")
- #col.prop(uvedit, "show_edges")
- #col.prop(uvedit, "show_faces")
col = split.column()
col.prop(uvedit, "show_stretch", text="Stretch")
@@ -628,7 +633,7 @@ class IMAGE_PT_view_properties(bpy.types.Panel):
sub.row().prop(uvedit, "draw_stretch_type", expand=True)
-class IMAGE_PT_paint(bpy.types.Panel):
+class IMAGE_PT_paint(Panel):
bl_space_type = 'IMAGE_EDITOR'
bl_region_type = 'UI'
bl_label = "Paint"
@@ -644,9 +649,8 @@ class IMAGE_PT_paint(bpy.types.Panel):
toolsettings = context.tool_settings.image_paint
brush = toolsettings.brush
- col = layout.split().column()
- row = col.row()
- col.template_ID_preview(toolsettings, "brush", new="brush.add", rows=3, cols=8)
+ col = layout.column()
+ col.template_ID_preview(toolsettings, "brush", new="brush.add", rows=2, cols=6)
if brush:
col = layout.column()
@@ -673,7 +677,7 @@ class IMAGE_PT_paint(bpy.types.Panel):
col.prop(brush, "clone_alpha", text="Alpha")
-class IMAGE_PT_tools_brush_texture(BrushButtonsPanel, bpy.types.Panel):
+class IMAGE_PT_tools_brush_texture(BrushButtonsPanel, Panel):
bl_label = "Texture"
bl_options = {'DEFAULT_CLOSED'}
@@ -688,7 +692,7 @@ class IMAGE_PT_tools_brush_texture(BrushButtonsPanel, bpy.types.Panel):
col.prop(brush, "use_fixed_texture")
-class IMAGE_PT_tools_brush_tool(BrushButtonsPanel, bpy.types.Panel):
+class IMAGE_PT_tools_brush_tool(BrushButtonsPanel, Panel):
bl_label = "Tool"
bl_options = {'DEFAULT_CLOSED'}
@@ -697,9 +701,7 @@ class IMAGE_PT_tools_brush_tool(BrushButtonsPanel, bpy.types.Panel):
settings = context.tool_settings.image_paint
brush = settings.brush
- col = layout.column(align=True)
-
- col.prop(brush, "image_tool", expand=False, text="")
+ layout.prop(brush, "image_tool", text="")
row = layout.row(align=True)
row.prop(brush, "use_paint_sculpt", text="", icon='SCULPTMODE_HLT')
@@ -708,7 +710,7 @@ class IMAGE_PT_tools_brush_tool(BrushButtonsPanel, bpy.types.Panel):
row.prop(brush, "use_paint_image", text="", icon='TPAINT_HLT')
-class IMAGE_PT_paint_stroke(BrushButtonsPanel, bpy.types.Panel):
+class IMAGE_PT_paint_stroke(BrushButtonsPanel, Panel):
bl_label = "Paint Stroke"
bl_options = {'DEFAULT_CLOSED'}
@@ -719,9 +721,9 @@ class IMAGE_PT_paint_stroke(BrushButtonsPanel, bpy.types.Panel):
brush = toolsettings.brush
layout.prop(brush, "use_airbrush")
- col = layout.column()
- col.active = brush.use_airbrush
- col.prop(brush, "rate", slider=True)
+ row = layout.row()
+ row.active = brush.use_airbrush
+ row.prop(brush, "rate", slider=True)
layout.prop(brush, "use_space")
row = layout.row(align=True)
@@ -732,7 +734,7 @@ class IMAGE_PT_paint_stroke(BrushButtonsPanel, bpy.types.Panel):
layout.prop(brush, "use_wrap")
-class IMAGE_PT_paint_curve(BrushButtonsPanel, bpy.types.Panel):
+class IMAGE_PT_paint_curve(BrushButtonsPanel, Panel):
bl_label = "Paint Curve"
bl_options = {'DEFAULT_CLOSED'}
diff --git a/release/scripts/startup/bl_ui/space_info.py b/release/scripts/startup/bl_ui/space_info.py
index 1fb2e5b735e..7f5a5f231cf 100644
--- a/release/scripts/startup/bl_ui/space_info.py
+++ b/release/scripts/startup/bl_ui/space_info.py
@@ -18,9 +18,10 @@
# <pep8 compliant>
import bpy
+from bpy.types import Header, Menu, Operator
-class INFO_HT_header(bpy.types.Header):
+class INFO_HT_header(Header):
bl_space_type = 'INFO'
def draw(self, context):
@@ -61,7 +62,9 @@ class INFO_HT_header(bpy.types.Header):
layout.template_reports_banner()
- layout.label(text=scene.statistics())
+ row = layout.row(align=True)
+ row.operator("wm.splash", text="", icon='BLENDER', emboss=False)
+ row.label(text=scene.statistics())
# XXX: this should be right-aligned to the RHS of the region
layout.operator("wm.window_fullscreen_toggle", icon='FULLSCREEN_ENTER', text="")
@@ -84,19 +87,19 @@ class INFO_HT_header(bpy.types.Header):
"""
-class INFO_MT_report(bpy.types.Menu):
+class INFO_MT_report(Menu):
bl_label = "Report"
def draw(self, context):
layout = self.layout
- layout.column()
+
layout.operator("console.select_all_toggle")
layout.operator("console.select_border")
layout.operator("console.report_delete")
layout.operator("console.report_copy")
-class INFO_MT_file(bpy.types.Menu):
+class INFO_MT_file(Menu):
bl_label = "File"
def draw(self, context):
@@ -150,7 +153,7 @@ class INFO_MT_file(bpy.types.Menu):
layout.operator("wm.quit_blender", text="Quit", icon='QUIT')
-class INFO_MT_file_import(bpy.types.Menu):
+class INFO_MT_file_import(Menu):
bl_idname = "INFO_MT_file_import"
bl_label = "Import"
@@ -159,7 +162,7 @@ class INFO_MT_file_import(bpy.types.Menu):
self.layout.operator("wm.collada_import", text="COLLADA (.dae)")
-class INFO_MT_file_export(bpy.types.Menu):
+class INFO_MT_file_export(Menu):
bl_idname = "INFO_MT_file_export"
bl_label = "Export"
@@ -168,7 +171,7 @@ class INFO_MT_file_export(bpy.types.Menu):
self.layout.operator("wm.collada_export", text="COLLADA (.dae)")
-class INFO_MT_file_external_data(bpy.types.Menu):
+class INFO_MT_file_external_data(Menu):
bl_label = "External Data"
def draw(self, context):
@@ -185,12 +188,13 @@ class INFO_MT_file_external_data(bpy.types.Menu):
layout.operator("file.find_missing_files")
-class INFO_MT_mesh_add(bpy.types.Menu):
+class INFO_MT_mesh_add(Menu):
bl_idname = "INFO_MT_mesh_add"
bl_label = "Mesh"
def draw(self, context):
layout = self.layout
+
layout.operator_context = 'INVOKE_REGION_WIN'
layout.operator("mesh.primitive_plane_add", icon='MESH_PLANE', text="Plane")
layout.operator("mesh.primitive_cube_add", icon='MESH_CUBE', text="Cube")
@@ -205,12 +209,13 @@ class INFO_MT_mesh_add(bpy.types.Menu):
layout.operator("mesh.primitive_torus_add", text="Torus", icon='MESH_TORUS')
-class INFO_MT_curve_add(bpy.types.Menu):
+class INFO_MT_curve_add(Menu):
bl_idname = "INFO_MT_curve_add"
bl_label = "Curve"
def draw(self, context):
layout = self.layout
+
layout.operator_context = 'INVOKE_REGION_WIN'
layout.operator("curve.primitive_bezier_curve_add", icon='CURVE_BEZCURVE', text="Bezier")
layout.operator("curve.primitive_bezier_circle_add", icon='CURVE_BEZCIRCLE', text="Circle")
@@ -219,7 +224,7 @@ class INFO_MT_curve_add(bpy.types.Menu):
layout.operator("curve.primitive_nurbs_path_add", icon='CURVE_PATH', text="Path")
-class INFO_MT_edit_curve_add(bpy.types.Menu):
+class INFO_MT_edit_curve_add(Menu):
bl_idname = "INFO_MT_edit_curve_add"
bl_label = "Add"
@@ -235,12 +240,13 @@ class INFO_MT_edit_curve_add(bpy.types.Menu):
INFO_MT_curve_add.draw(self, context)
-class INFO_MT_surface_add(bpy.types.Menu):
+class INFO_MT_surface_add(Menu):
bl_idname = "INFO_MT_surface_add"
bl_label = "Surface"
def draw(self, context):
layout = self.layout
+
layout.operator_context = 'INVOKE_REGION_WIN'
layout.operator("surface.primitive_nurbs_surface_curve_add", icon='SURFACE_NCURVE', text="NURBS Curve")
layout.operator("surface.primitive_nurbs_surface_circle_add", icon='SURFACE_NCIRCLE', text="NURBS Circle")
@@ -250,17 +256,18 @@ class INFO_MT_surface_add(bpy.types.Menu):
layout.operator("surface.primitive_nurbs_surface_torus_add", icon='SURFACE_NTORUS', text="NURBS Torus")
-class INFO_MT_armature_add(bpy.types.Menu):
+class INFO_MT_armature_add(Menu):
bl_idname = "INFO_MT_armature_add"
bl_label = "Armature"
def draw(self, context):
layout = self.layout
+
layout.operator_context = 'INVOKE_REGION_WIN'
layout.operator("object.armature_add", text="Single Bone", icon='BONE_DATA')
-class INFO_MT_add(bpy.types.Menu):
+class INFO_MT_add(Menu):
bl_label = "Add"
def draw(self, context):
@@ -285,6 +292,9 @@ class INFO_MT_add(bpy.types.Menu):
layout.operator("object.add", text="Empty", icon='OUTLINER_OB_EMPTY').type = 'EMPTY'
layout.separator()
+ layout.operator("object.speaker_add", text="Speaker", icon='OUTLINER_OB_SPEAKER')
+ layout.separator()
+
layout.operator("object.camera_add", text="Camera", icon='OUTLINER_OB_CAMERA')
layout.operator_context = 'EXEC_SCREEN'
layout.operator_menu_enum("object.lamp_add", "type", text="Lamp", icon='OUTLINER_OB_LAMP')
@@ -300,7 +310,7 @@ class INFO_MT_add(bpy.types.Menu):
layout.operator_menu_enum("object.group_instance_add", "group", text="Group Instance", icon='OUTLINER_OB_EMPTY')
-class INFO_MT_game(bpy.types.Menu):
+class INFO_MT_game(Menu):
bl_label = "Game"
def draw(self, context):
@@ -321,7 +331,7 @@ class INFO_MT_game(bpy.types.Menu):
layout.prop(gs, "use_auto_start")
-class INFO_MT_render(bpy.types.Menu):
+class INFO_MT_render(Menu):
bl_label = "Render"
def draw(self, context):
@@ -341,7 +351,7 @@ class INFO_MT_render(bpy.types.Menu):
layout.operator("render.play_rendered_anim")
-class INFO_MT_help(bpy.types.Menu):
+class INFO_MT_help(Menu):
bl_label = "Help"
def draw(self, context):
@@ -350,7 +360,7 @@ class INFO_MT_help(bpy.types.Menu):
layout = self.layout
layout.operator("wm.url_open", text="Manual", icon='HELP').url = 'http://wiki.blender.org/index.php/Doc:Manual'
- layout.operator("wm.url_open", text="Release Log", icon='URL').url = 'http://www.blender.org/development/release-logs/blender-257/'
+ layout.operator("wm.url_open", text="Release Log", icon='URL').url = 'http://www.blender.org/development/release-logs/blender-259/'
layout.separator()
@@ -377,7 +387,7 @@ class INFO_MT_help(bpy.types.Menu):
# Help operators
-class HELP_OT_operator_cheat_sheet(bpy.types.Operator):
+class HELP_OT_operator_cheat_sheet(Operator):
bl_idname = "help.operator_cheat_sheet"
bl_label = "Operator Cheat Sheet"
diff --git a/release/scripts/startup/bl_ui/space_logic.py b/release/scripts/startup/bl_ui/space_logic.py
index 7f7aba71a46..869a91124d3 100644
--- a/release/scripts/startup/bl_ui/space_logic.py
+++ b/release/scripts/startup/bl_ui/space_logic.py
@@ -18,9 +18,10 @@
# <pep8 compliant>
import bpy
+from bpy.types import Header, Menu, Panel
-class LOGIC_PT_properties(bpy.types.Panel):
+class LOGIC_PT_properties(Panel):
bl_space_type = 'LOGIC_EDITOR'
bl_region_type = 'UI'
bl_label = "Properties"
@@ -49,7 +50,7 @@ class LOGIC_PT_properties(bpy.types.Panel):
row.operator("object.game_property_remove", text="", icon='X', emboss=False).index = i
-class LOGIC_MT_logicbricks_add(bpy.types.Menu):
+class LOGIC_MT_logicbricks_add(Menu):
bl_label = "Add"
def draw(self, context):
@@ -60,30 +61,24 @@ class LOGIC_MT_logicbricks_add(bpy.types.Menu):
layout.operator_menu_enum("logic.actuator_add", "type", text="Actuator")
-class LOGIC_HT_header(bpy.types.Header):
+class LOGIC_HT_header(Header):
bl_space_type = 'LOGIC_EDITOR'
def draw(self, context):
- layout = self.layout
+ layout = self.layout.row(align=True)
- row = layout.row(align=True)
- row.template_header()
+ layout.template_header()
if context.area.show_menus:
- sub = row.row(align=True)
- sub.menu("LOGIC_MT_view")
- #sub.menu("LOGIC_MT_select")
- #sub.menu("LOGIC_MT_add")
+ layout.menu("LOGIC_MT_view")
-class LOGIC_MT_view(bpy.types.Menu):
+class LOGIC_MT_view(Menu):
bl_label = "View"
def draw(self, context):
layout = self.layout
- layout.column()
-
layout.operator("logic.properties", icon='MENU_PANEL')
if __name__ == "__main__": # only for live edit.
diff --git a/release/scripts/startup/bl_ui/space_nla.py b/release/scripts/startup/bl_ui/space_nla.py
index 717adb3baa8..ffead81c507 100644
--- a/release/scripts/startup/bl_ui/space_nla.py
+++ b/release/scripts/startup/bl_ui/space_nla.py
@@ -19,9 +19,10 @@
# <pep8 compliant>
import bpy
+from bpy.types import Header, Menu
-class NLA_HT_header(bpy.types.Header):
+class NLA_HT_header(Header):
bl_space_type = 'NLA_EDITOR'
def draw(self, context):
@@ -35,20 +36,18 @@ class NLA_HT_header(bpy.types.Header):
row.template_header()
if context.area.show_menus:
- sub = row.row(align=True)
-
- sub.menu("NLA_MT_view")
- sub.menu("NLA_MT_select")
- sub.menu("NLA_MT_marker")
- sub.menu("NLA_MT_edit")
- sub.menu("NLA_MT_add")
+ row.menu("NLA_MT_view")
+ row.menu("NLA_MT_select")
+ row.menu("NLA_MT_marker")
+ row.menu("NLA_MT_edit")
+ row.menu("NLA_MT_add")
dopesheet_filter(layout, context)
layout.prop(st, "auto_snap", text="")
-class NLA_MT_view(bpy.types.Menu):
+class NLA_MT_view(Menu):
bl_label = "View"
def draw(self, context):
@@ -56,8 +55,6 @@ class NLA_MT_view(bpy.types.Menu):
st = context.space_data
- layout.column()
-
layout.operator("nla.properties", icon='MENU_PANEL')
layout.separator()
@@ -74,17 +71,20 @@ class NLA_MT_view(bpy.types.Menu):
layout.operator("anim.previewrange_clear")
layout.separator()
+ layout.operator("nla.view_all")
+ layout.operator("nla.view_selected")
+
+ layout.separator()
layout.operator("screen.area_dupli")
layout.operator("screen.screen_full_area")
-class NLA_MT_select(bpy.types.Menu):
+class NLA_MT_select(Menu):
bl_label = "Select"
def draw(self, context):
layout = self.layout
- layout.column()
# This is a bit misleading as the operator's default text is "Select All" while it actually *toggles* All/None
layout.operator("nla.select_all_toggle")
layout.operator("nla.select_all_toggle", text="Invert Selection").invert = True
@@ -98,7 +98,7 @@ class NLA_MT_select(bpy.types.Menu):
layout.operator("nla.select_leftright", text="After Current Frame").mode = 'RIGHT'
-class NLA_MT_marker(bpy.types.Menu):
+class NLA_MT_marker(Menu):
bl_label = "Marker"
def draw(self, context):
@@ -106,7 +106,6 @@ class NLA_MT_marker(bpy.types.Menu):
#layout.operator_context = 'EXEC_REGION_WIN'
- layout.column()
layout.operator("marker.add", "Add Marker")
layout.operator("marker.duplicate", text="Duplicate Marker")
layout.operator("marker.delete", text="Delete Marker")
@@ -117,7 +116,7 @@ class NLA_MT_marker(bpy.types.Menu):
layout.operator("marker.move", text="Grab/Move Marker")
-class NLA_MT_edit(bpy.types.Menu):
+class NLA_MT_edit(Menu):
bl_label = "Edit"
def draw(self, context):
@@ -125,7 +124,6 @@ class NLA_MT_edit(bpy.types.Menu):
scene = context.scene
- layout.column()
layout.menu("NLA_MT_edit_transform", text="Transform")
layout.operator_menu_enum("nla.snap", "type", text="Snap")
@@ -160,15 +158,15 @@ class NLA_MT_edit(bpy.types.Menu):
layout.operator("nla.tweakmode_enter", text="Start Tweaking Strip Actions")
-class NLA_MT_add(bpy.types.Menu):
+class NLA_MT_add(Menu):
bl_label = "Add"
def draw(self, context):
layout = self.layout
- layout.column()
layout.operator("nla.actionclip_add")
layout.operator("nla.transition_add")
+ layout.operator("nla.soundclip_add")
layout.separator()
layout.operator("nla.meta_add")
@@ -179,13 +177,12 @@ class NLA_MT_add(bpy.types.Menu):
layout.operator("nla.tracks_add", text="Add Tracks Above Selected").above_selected = True
-class NLA_MT_edit_transform(bpy.types.Menu):
+class NLA_MT_edit_transform(Menu):
bl_label = "Transform"
def draw(self, context):
layout = self.layout
- layout.column()
layout.operator("transform.translate", text="Grab/Move")
layout.operator("transform.transform", text="Extend").mode = 'TIME_EXTEND'
layout.operator("transform.transform", text="Scale").mode = 'TIME_SCALE'
diff --git a/release/scripts/startup/bl_ui/space_node.py b/release/scripts/startup/bl_ui/space_node.py
index fed1cc49c4c..708017ba749 100644
--- a/release/scripts/startup/bl_ui/space_node.py
+++ b/release/scripts/startup/bl_ui/space_node.py
@@ -18,42 +18,39 @@
# <pep8 compliant>
import bpy
+from bpy.types import Header, Menu, Panel
-class NODE_HT_header(bpy.types.Header):
+class NODE_HT_header(Header):
bl_space_type = 'NODE_EDITOR'
def draw(self, context):
layout = self.layout
snode = context.space_data
+ snode_id = snode.id
+ id_from = snode.id_from
row = layout.row(align=True)
row.template_header()
if context.area.show_menus:
- sub = row.row(align=True)
- sub.menu("NODE_MT_view")
- sub.menu("NODE_MT_select")
- sub.menu("NODE_MT_add")
- sub.menu("NODE_MT_node")
+ row.menu("NODE_MT_view")
+ row.menu("NODE_MT_select")
+ row.menu("NODE_MT_add")
+ row.menu("NODE_MT_node")
- row = layout.row()
- row.prop(snode, "tree_type", text="", expand=True)
+ layout.prop(snode, "tree_type", text="", expand=True)
if snode.tree_type == 'MATERIAL':
- ob = snode.id_from
- snode_id = snode.id
- if ob:
- layout.template_ID(ob, "active_material", new="material.new")
+ if id_from:
+ layout.template_ID(id_from, "active_material", new="material.new")
if snode_id:
layout.prop(snode_id, "use_nodes")
elif snode.tree_type == 'TEXTURE':
- row.prop(snode, "texture_type", text="", expand=True)
+ layout.prop(snode, "texture_type", text="", expand=True)
- snode_id = snode.id
- id_from = snode.id_from
if id_from:
if snode.texture_type == 'BRUSH':
layout.template_ID(id_from, "texture", new="texture.new")
@@ -63,10 +60,8 @@ class NODE_HT_header(bpy.types.Header):
layout.prop(snode_id, "use_nodes")
elif snode.tree_type == 'COMPOSITING':
- scene = snode.id
-
- layout.prop(scene, "use_nodes")
- layout.prop(scene.render, "use_free_unused_nodes", text="Free Unused")
+ layout.prop(snode_id, "use_nodes")
+ layout.prop(snode_id.render, "use_free_unused_nodes", text="Free Unused")
layout.prop(snode, "show_backdrop")
if snode.show_backdrop:
row = layout.row(align=True)
@@ -78,7 +73,7 @@ class NODE_HT_header(bpy.types.Header):
layout.template_running_jobs()
-class NODE_MT_view(bpy.types.Menu):
+class NODE_MT_view(Menu):
bl_label = "View"
def draw(self, context):
@@ -107,7 +102,7 @@ class NODE_MT_view(bpy.types.Menu):
layout.operator("screen.screen_full_area")
-class NODE_MT_select(bpy.types.Menu):
+class NODE_MT_select(Menu):
bl_label = "Select"
def draw(self, context):
@@ -124,7 +119,7 @@ class NODE_MT_select(bpy.types.Menu):
layout.operator("node.select_same_type_prev")
-class NODE_MT_node(bpy.types.Menu):
+class NODE_MT_node(Menu):
bl_label = "Node"
def draw(self, context):
@@ -138,6 +133,7 @@ class NODE_MT_node(bpy.types.Menu):
layout.operator("node.duplicate_move")
layout.operator("node.delete")
+ layout.operator("node.delete_reconnect")
layout.separator()
layout.operator("node.link_make")
@@ -164,7 +160,7 @@ class NODE_MT_node(bpy.types.Menu):
# Node Backdrop options
-class NODE_PT_properties(bpy.types.Panel):
+class NODE_PT_properties(Panel):
bl_space_type = 'NODE_EDITOR'
bl_region_type = 'UI'
bl_label = "Backdrop"
diff --git a/release/scripts/startup/bl_ui/space_outliner.py b/release/scripts/startup/bl_ui/space_outliner.py
index 1f196cbd191..b1e6eaf3245 100644
--- a/release/scripts/startup/bl_ui/space_outliner.py
+++ b/release/scripts/startup/bl_ui/space_outliner.py
@@ -18,9 +18,10 @@
# <pep8 compliant>
import bpy
+from bpy.types import Header, Menu
-class OUTLINER_HT_header(bpy.types.Header):
+class OUTLINER_HT_header(Header):
bl_space_type = 'OUTLINER'
def draw(self, context):
@@ -63,7 +64,7 @@ class OUTLINER_HT_header(bpy.types.Header):
row.label(text="No Keying Set active")
-class OUTLINER_MT_view(bpy.types.Menu):
+class OUTLINER_MT_view(Menu):
bl_label = "View"
def draw(self, context):
@@ -71,14 +72,13 @@ class OUTLINER_MT_view(bpy.types.Menu):
space = context.space_data
- col = layout.column()
if space.display_mode not in {'DATABLOCKS', 'USER_PREFERENCES', 'KEYMAPS'}:
- col.prop(space, "show_restrict_columns")
- col.separator()
- col.operator("outliner.show_active")
+ layout.prop(space, "show_restrict_columns")
+ layout.separator()
+ layout.operator("outliner.show_active")
- col.operator("outliner.show_one_level")
- col.operator("outliner.show_hierarchy")
+ layout.operator("outliner.show_one_level")
+ layout.operator("outliner.show_hierarchy")
layout.separator()
@@ -86,7 +86,7 @@ class OUTLINER_MT_view(bpy.types.Menu):
layout.operator("screen.screen_full_area")
-class OUTLINER_MT_search(bpy.types.Menu):
+class OUTLINER_MT_search(Menu):
bl_label = "Search"
def draw(self, context):
@@ -94,27 +94,23 @@ class OUTLINER_MT_search(bpy.types.Menu):
space = context.space_data
- col = layout.column()
+ layout.prop(space, "use_filter_case_sensitive")
+ layout.prop(space, "use_filter_complete")
- col.prop(space, "use_filter_case_sensitive")
- col.prop(space, "use_filter_complete")
-
-class OUTLINER_MT_edit_datablocks(bpy.types.Menu):
+class OUTLINER_MT_edit_datablocks(Menu):
bl_label = "Edit"
def draw(self, context):
layout = self.layout
- col = layout.column()
-
- col.operator("outliner.keyingset_add_selected")
- col.operator("outliner.keyingset_remove_selected")
+ layout.operator("outliner.keyingset_add_selected")
+ layout.operator("outliner.keyingset_remove_selected")
- col.separator()
+ layout.separator()
- col.operator("outliner.drivers_add_selected")
- col.operator("outliner.drivers_delete_selected")
+ layout.operator("outliner.drivers_add_selected")
+ layout.operator("outliner.drivers_delete_selected")
if __name__ == "__main__": # only for live edit.
bpy.utils.register_module(__name__)
diff --git a/release/scripts/startup/bl_ui/space_sequencer.py b/release/scripts/startup/bl_ui/space_sequencer.py
index 858c619d3c1..36f606da635 100644
--- a/release/scripts/startup/bl_ui/space_sequencer.py
+++ b/release/scripts/startup/bl_ui/space_sequencer.py
@@ -18,6 +18,7 @@
# <pep8 compliant>
import bpy
+from bpy.types import Header, Menu, Panel
def act_strip(context):
@@ -27,7 +28,7 @@ def act_strip(context):
return None
-class SEQUENCER_HT_header(bpy.types.Header):
+class SEQUENCER_HT_header(Header):
bl_space_type = 'SEQUENCE_EDITOR'
def draw(self, context):
@@ -39,28 +40,28 @@ class SEQUENCER_HT_header(bpy.types.Header):
row.template_header()
if context.area.show_menus:
- sub = row.row(align=True)
- sub.menu("SEQUENCER_MT_view")
+ row.menu("SEQUENCER_MT_view")
- if (st.view_type == 'SEQUENCER') or (st.view_type == 'SEQUENCER_PREVIEW'):
- sub.menu("SEQUENCER_MT_select")
- sub.menu("SEQUENCER_MT_marker")
- sub.menu("SEQUENCER_MT_add")
- sub.menu("SEQUENCER_MT_strip")
+ if st.view_type in {'SEQUENCER', 'SEQUENCER_PREVIEW'}:
+ row.menu("SEQUENCER_MT_select")
+ row.menu("SEQUENCER_MT_marker")
+ row.menu("SEQUENCER_MT_add")
+ row.menu("SEQUENCER_MT_strip")
layout.prop(st, "view_type", expand=True, text="")
- if (st.view_type == 'PREVIEW') or (st.view_type == 'SEQUENCER_PREVIEW'):
+ if st.view_type in {'PREVIEW', 'SEQUENCER_PREVIEW'}:
layout.prop(st, "display_mode", expand=True, text="")
- if (st.view_type == 'SEQUENCER'):
+ if st.view_type == 'SEQUENCER':
row = layout.row(align=True)
row.operator("sequencer.copy", text="", icon='COPYDOWN')
row.operator("sequencer.paste", text="", icon='PASTEDOWN')
layout.separator()
layout.operator("sequencer.refresh_all")
- elif (st.view_type == 'SEQUENCER_PREVIEW'):
+ layout.template_running_jobs()
+ elif st.view_type == 'SEQUENCER_PREVIEW':
layout.separator()
layout.operator("sequencer.refresh_all")
layout.prop(st, "display_channel", text="Channel")
@@ -76,7 +77,7 @@ class SEQUENCER_HT_header(bpy.types.Header):
row.prop(ed, "overlay_lock", text="", icon='LOCKED')
-class SEQUENCER_MT_view_toggle(bpy.types.Menu):
+class SEQUENCER_MT_view_toggle(Menu):
bl_label = "View Type"
def draw(self, context):
@@ -87,7 +88,7 @@ class SEQUENCER_MT_view_toggle(bpy.types.Menu):
layout.operator("sequencer.view_toggle").type = 'SEQUENCER_PREVIEW'
-class SEQUENCER_MT_view(bpy.types.Menu):
+class SEQUENCER_MT_view(Menu):
bl_label = "View"
def draw(self, context):
@@ -95,15 +96,13 @@ class SEQUENCER_MT_view(bpy.types.Menu):
st = context.space_data
- layout.column()
-
layout.operator("sequencer.properties", icon='MENU_PANEL')
layout.separator()
- if (st.view_type == 'SEQUENCER') or (st.view_type == 'SEQUENCER_PREVIEW'):
+ if st.view_type in {'SEQUENCER', 'SEQUENCER_PREVIEW'}:
layout.operator("sequencer.view_all", text='View all Sequences')
- if (st.view_type == 'PREVIEW') or (st.view_type == 'SEQUENCER_PREVIEW'):
+ if st.view_type in {'PREVIEW', 'SEQUENCER_PREVIEW'}:
layout.operator_context = 'INVOKE_REGION_PREVIEW'
layout.operator("sequencer.view_all_preview", text='Fit preview in window')
layout.operator("sequencer.view_zoom_ratio", text='Show preview 1:1').ratio = 1.0
@@ -114,7 +113,11 @@ class SEQUENCER_MT_view(bpy.types.Menu):
layout.operator("sequencer.view_selected")
- layout.prop(st, "show_frames")
+ if st.show_frames:
+ layout.operator("anim.time_toggle", text="Show Seconds")
+ else:
+ layout.operator("anim.time_toggle", text="Show Frames")
+
layout.prop(st, "show_frame_indicator")
if st.display_mode == 'IMAGE':
layout.prop(st, "show_safe_margin")
@@ -129,13 +132,12 @@ class SEQUENCER_MT_view(bpy.types.Menu):
layout.operator("screen.screen_full_area")
-class SEQUENCER_MT_select(bpy.types.Menu):
+class SEQUENCER_MT_select(Menu):
bl_label = "Select"
def draw(self, context):
layout = self.layout
- layout.column()
layout.operator("sequencer.select_active_side", text="Strips to the Left").side = 'LEFT'
layout.operator("sequencer.select_active_side", text="Strips to the Right").side = 'RIGHT'
layout.separator()
@@ -148,7 +150,7 @@ class SEQUENCER_MT_select(bpy.types.Menu):
layout.operator("sequencer.select_inverse")
-class SEQUENCER_MT_marker(bpy.types.Menu):
+class SEQUENCER_MT_marker(Menu):
bl_label = "Marker"
def draw(self, context):
@@ -156,7 +158,6 @@ class SEQUENCER_MT_marker(bpy.types.Menu):
#layout.operator_context = 'EXEC_REGION_WIN'
- layout.column()
layout.operator("marker.add", "Add Marker")
layout.operator("marker.duplicate", text="Duplicate Marker")
layout.operator("marker.delete", text="Delete Marker")
@@ -169,14 +170,26 @@ class SEQUENCER_MT_marker(bpy.types.Menu):
#layout.operator("sequencer.sound_strip_add", text="Transform Markers") # toggle, will be rna - (sseq->flag & SEQ_MARKER_TRANS)
-class SEQUENCER_MT_add(bpy.types.Menu):
+class SEQUENCER_MT_change(Menu):
+ bl_label = "Change"
+
+ def draw(self, context):
+ layout = self.layout
+
+ layout.operator_context = 'INVOKE_REGION_WIN'
+
+ layout.operator_menu_enum("sequencer.change_effect_input", "swap")
+ layout.operator_menu_enum("sequencer.change_effect_type", "type")
+ layout.operator("sequencer.change_path", text="Path/Files")
+
+
+class SEQUENCER_MT_add(Menu):
bl_label = "Add"
def draw(self, context):
layout = self.layout
layout.operator_context = 'INVOKE_REGION_WIN'
- layout.column()
if len(bpy.data.scenes) > 10:
layout.operator_context = 'INVOKE_DEFAULT'
layout.operator("sequencer.scene_strip_add", text="Scene...")
@@ -190,14 +203,13 @@ class SEQUENCER_MT_add(bpy.types.Menu):
layout.menu("SEQUENCER_MT_add_effect")
-class SEQUENCER_MT_add_effect(bpy.types.Menu):
+class SEQUENCER_MT_add_effect(Menu):
bl_label = "Effect Strip..."
def draw(self, context):
layout = self.layout
layout.operator_context = 'INVOKE_REGION_WIN'
- layout.column()
layout.operator("sequencer.effect_strip_add", text="Add").type = 'ADD'
layout.operator("sequencer.effect_strip_add", text="Subtract").type = 'SUBTRACT'
layout.operator("sequencer.effect_strip_add", text="Alpha Over").type = 'ALPHA_OVER'
@@ -216,7 +228,7 @@ class SEQUENCER_MT_add_effect(bpy.types.Menu):
layout.operator("sequencer.effect_strip_add", text="Adjustment Layer").type = 'ADJUSTMENT'
-class SEQUENCER_MT_strip(bpy.types.Menu):
+class SEQUENCER_MT_strip(Menu):
bl_label = "Strip"
def draw(self, context):
@@ -224,7 +236,6 @@ class SEQUENCER_MT_strip(bpy.types.Menu):
layout.operator_context = 'INVOKE_REGION_WIN'
- layout.column()
layout.operator("transform.transform", text="Grab/Move").mode = 'TRANSLATION'
layout.operator("transform.transform", text="Grab/Extend from frame").mode = 'TIME_EXTEND'
# uiItemO(layout, NULL, 0, "sequencer.strip_snap"); // TODO - add this operator
@@ -233,7 +244,9 @@ class SEQUENCER_MT_strip(bpy.types.Menu):
layout.operator("sequencer.cut", text="Cut (hard) at frame").type = 'HARD'
layout.operator("sequencer.cut", text="Cut (soft) at frame").type = 'SOFT'
layout.operator("sequencer.images_separate")
+ layout.operator("sequencer.offset_clear")
layout.operator("sequencer.deinterlace_selected_movies")
+ layout.operator("sequencer.rebuild_proxy")
layout.separator()
layout.operator("sequencer.duplicate")
@@ -292,6 +305,7 @@ class SEQUENCER_MT_strip(bpy.types.Menu):
layout.separator()
layout.operator("sequencer.swap_data")
+ layout.menu("SEQUENCER_MT_change")
class SequencerButtonsPanel():
@@ -300,7 +314,7 @@ class SequencerButtonsPanel():
@staticmethod
def has_sequencer(context):
- return (context.space_data.view_type == 'SEQUENCER') or (context.space_data.view_type == 'SEQUENCER_PREVIEW')
+ return (context.space_data.view_type in {'SEQUENCER', 'SEQUENCER_PREVIEW'})
@classmethod
def poll(cls, context):
@@ -313,14 +327,14 @@ class SequencerButtonsPanel_Output():
@staticmethod
def has_preview(context):
- return (context.space_data.view_type == 'PREVIEW') or (context.space_data.view_type == 'SEQUENCER_PREVIEW')
+ return (context.space_data.view_type in {'PREVIEW', 'SEQUENCER_PREVIEW'})
@classmethod
def poll(cls, context):
return cls.has_preview(context)
-class SEQUENCER_PT_edit(SequencerButtonsPanel, bpy.types.Panel):
+class SEQUENCER_PT_edit(SequencerButtonsPanel, Panel):
bl_label = "Edit Strip"
def draw(self, context):
@@ -374,9 +388,11 @@ class SEQUENCER_PT_edit(SequencerButtonsPanel, bpy.types.Panel):
if elem and elem.orig_width > 0 and elem.orig_height > 0:
col.label(text="Orig Dim: %dx%d" % (elem.orig_width, elem.orig_height))
+ else:
+ col.label(text="Orig Dim: None")
-class SEQUENCER_PT_effect(SequencerButtonsPanel, bpy.types.Panel):
+class SEQUENCER_PT_effect(SequencerButtonsPanel, Panel):
bl_label = "Effect Strip"
@classmethod
@@ -514,7 +530,7 @@ class SEQUENCER_PT_effect(SequencerButtonsPanel, bpy.types.Panel):
col.prop(strip, "rotation_start", text="Rotation")
-class SEQUENCER_PT_input(SequencerButtonsPanel, bpy.types.Panel):
+class SEQUENCER_PT_input(SequencerButtonsPanel, Panel):
bl_label = "Strip Input"
@classmethod
@@ -558,6 +574,9 @@ class SEQUENCER_PT_input(SequencerButtonsPanel, bpy.types.Panel):
col = split.column()
col.prop(elem, "filename", text="") # strip.elements[0] could be a fallback
+ # also accessible from the menu
+ layout.operator("sequencer.change_path")
+
elif seq_type == 'MOVIE':
split = layout.split(percentage=0.2)
col = split.column()
@@ -565,6 +584,7 @@ class SEQUENCER_PT_input(SequencerButtonsPanel, bpy.types.Panel):
col = split.column()
col.prop(strip, "filepath", text="")
col.prop(strip, "mpeg_preseek", text="MPEG Preseek")
+ col.prop(strip, "streamindex", text="Stream Index")
# TODO, sound???
# end drawing filename
@@ -595,7 +615,7 @@ class SEQUENCER_PT_input(SequencerButtonsPanel, bpy.types.Panel):
col.prop(strip, "frame_offset_end", text="End")
-class SEQUENCER_PT_sound(SequencerButtonsPanel, bpy.types.Panel):
+class SEQUENCER_PT_sound(SequencerButtonsPanel, Panel):
bl_label = "Sound"
@classmethod
@@ -627,8 +647,10 @@ class SEQUENCER_PT_sound(SequencerButtonsPanel, bpy.types.Panel):
row.prop(strip.sound, "use_memory_cache")
+ layout.prop(strip, "waveform")
layout.prop(strip, "volume")
- layout.prop(strip, "attenuation")
+ layout.prop(strip, "pitch")
+ layout.prop(strip, "pan")
col = layout.column(align=True)
col.label(text="Trim Duration:")
@@ -636,7 +658,7 @@ class SEQUENCER_PT_sound(SequencerButtonsPanel, bpy.types.Panel):
col.prop(strip, "animation_offset_end", text="End")
-class SEQUENCER_PT_scene(SequencerButtonsPanel, bpy.types.Panel):
+class SEQUENCER_PT_scene(SequencerButtonsPanel, Panel):
bl_label = "Scene"
@classmethod
@@ -657,14 +679,20 @@ class SEQUENCER_PT_scene(SequencerButtonsPanel, bpy.types.Panel):
layout.template_ID(strip, "scene")
+ scene = strip.scene
+ if scene:
+ layout.prop(scene.render, "use_sequencer")
+
layout.label(text="Camera Override")
layout.template_ID(strip, "scene_camera")
- sce = strip.scene
- layout.label(text="Original frame range: %d-%d (%d)" % (sce.frame_start, sce.frame_end, sce.frame_end - sce.frame_start + 1))
+ if scene:
+ sta = scene.frame_start
+ end = scene.frame_end
+ layout.label(text="Original frame range: %d-%d (%d)" % (sta, end, end - sta + 1))
-class SEQUENCER_PT_filter(SequencerButtonsPanel, bpy.types.Panel):
+class SEQUENCER_PT_filter(SequencerButtonsPanel, Panel):
bl_label = "Filter"
@classmethod
@@ -726,8 +754,8 @@ class SEQUENCER_PT_filter(SequencerButtonsPanel, bpy.types.Panel):
col.prop(strip.color_balance, "invert_gain", text="Inverse")
-class SEQUENCER_PT_proxy(SequencerButtonsPanel, bpy.types.Panel):
- bl_label = "Proxy"
+class SEQUENCER_PT_proxy(SequencerButtonsPanel, Panel):
+ bl_label = "Proxy / Timecode"
@classmethod
def poll(cls, context):
@@ -753,14 +781,30 @@ class SEQUENCER_PT_proxy(SequencerButtonsPanel, bpy.types.Panel):
flow = layout.column_flow()
flow.prop(strip, "use_proxy_custom_directory")
flow.prop(strip, "use_proxy_custom_file")
- if strip.proxy: # TODO - need to add this somehow
+ if strip.proxy:
if strip.use_proxy_custom_directory and not strip.use_proxy_custom_file:
flow.prop(strip.proxy, "directory")
if strip.use_proxy_custom_file:
flow.prop(strip.proxy, "filepath")
+ row = layout.row()
+ row.prop(strip.proxy, "build_25")
+ row.prop(strip.proxy, "build_50")
+ row.prop(strip.proxy, "build_75")
+ row.prop(strip.proxy, "build_100")
+
+ col = layout.column()
+ col.label(text="Build JPEG quality")
+ col.prop(strip.proxy, "quality")
+
+ if strip.type == "MOVIE":
+ col = layout.column()
+ col.label(text="Use timecode index:")
+
+ col.prop(strip.proxy, "timecode")
+
-class SEQUENCER_PT_preview(SequencerButtonsPanel_Output, bpy.types.Panel):
+class SEQUENCER_PT_preview(SequencerButtonsPanel_Output, Panel):
bl_label = "Scene Preview/Render"
bl_space_type = 'SEQUENCE_EDITOR'
bl_region_type = 'UI'
@@ -785,7 +829,7 @@ class SEQUENCER_PT_preview(SequencerButtonsPanel_Output, bpy.types.Panel):
'''
-class SEQUENCER_PT_view(SequencerButtonsPanel_Output, bpy.types.Panel):
+class SEQUENCER_PT_view(SequencerButtonsPanel_Output, Panel):
bl_label = "View Settings"
def draw(self, context):
diff --git a/release/scripts/startup/bl_ui/space_text.py b/release/scripts/startup/bl_ui/space_text.py
index 0fc8d937f66..12e07c19ca1 100644
--- a/release/scripts/startup/bl_ui/space_text.py
+++ b/release/scripts/startup/bl_ui/space_text.py
@@ -16,11 +16,12 @@
#
# ##### END GPL LICENSE BLOCK #####
-# <pep8 compliant>
+# <pep8-80 compliant>
import bpy
+from bpy.types import Header, Menu, Panel
-class TEXT_HT_header(bpy.types.Header):
+class TEXT_HT_header(Header):
bl_space_type = 'TEXT_EDITOR'
def draw(self, context):
@@ -33,19 +34,21 @@ class TEXT_HT_header(bpy.types.Header):
row.template_header()
if context.area.show_menus:
- sub = row.row(align=True)
- sub.menu("TEXT_MT_view")
- sub.menu("TEXT_MT_text")
+ row.menu("TEXT_MT_view")
+ row.menu("TEXT_MT_text")
+
if text:
- sub.menu("TEXT_MT_edit")
- sub.menu("TEXT_MT_format")
+ row.menu("TEXT_MT_edit")
+ row.menu("TEXT_MT_format")
+
+ row.menu("TEXT_MT_templates")
if text and text.is_modified:
- row = layout.row()
- row.alert = True
- row.operator("text.resolve_conflict", text="", icon='HELP')
+ sub = row.row()
+ sub.alert = True
+ sub.operator("text.resolve_conflict", text="", icon='HELP')
- layout.template_ID(st, "text", new="text.new", unlink="text.unlink")
+ row.template_ID(st, "text", new="text.new", unlink="text.unlink")
row = layout.row(align=True)
row.prop(st, "show_line_numbers", text="")
@@ -63,14 +66,16 @@ class TEXT_HT_header(bpy.types.Header):
row = layout.row()
if text.filepath:
if text.is_dirty:
- row.label(text="File: *%s (unsaved)" % text.filepath)
+ row.label(text="File: *%r (unsaved)" % text.filepath)
else:
- row.label(text="File: %s" % text.filepath)
+ row.label(text="File: %r" % text.filepath)
else:
- row.label(text="Text: External" if text.library else "Text: Internal")
+ row.label(text="Text: External"
+ if text.library
+ else "Text: Internal")
-class TEXT_PT_properties(bpy.types.Panel):
+class TEXT_PT_properties(Panel):
bl_space_type = 'TEXT_EDITOR'
bl_region_type = 'UI'
bl_label = "Properties"
@@ -101,7 +106,7 @@ class TEXT_PT_properties(bpy.types.Panel):
col.prop(st, "margin_column")
-class TEXT_PT_find(bpy.types.Panel):
+class TEXT_PT_find(Panel):
bl_space_type = 'TEXT_EDITOR'
bl_region_type = 'UI'
bl_label = "Find"
@@ -135,7 +140,7 @@ class TEXT_PT_find(bpy.types.Panel):
row.prop(st, "use_find_all", text="All")
-class TEXT_MT_view(bpy.types.Menu):
+class TEXT_MT_view(Menu):
bl_label = "View"
def draw(self, context):
@@ -150,11 +155,15 @@ class TEXT_MT_view(bpy.types.Menu):
layout.separator()
- layout.operator("text.move", text="Top of File").type = 'FILE_TOP'
- layout.operator("text.move", text="Bottom of File").type = 'FILE_BOTTOM'
+ layout.operator("text.move",
+ text="Top of File",
+ ).type = 'FILE_TOP'
+ layout.operator("text.move",
+ text="Bottom of File",
+ ).type = 'FILE_BOTTOM'
-class TEXT_MT_text(bpy.types.Menu):
+class TEXT_MT_text(Menu):
bl_label = "Text"
def draw(self, context):
@@ -163,8 +172,9 @@ class TEXT_MT_text(bpy.types.Menu):
st = context.space_data
text = st.text
- layout.column()
+ layout.operator_context = 'EXEC_AREA'
layout.operator("text.new")
+ layout.operator_context = 'INVOKE_AREA'
layout.operator("text.open")
if text:
@@ -180,27 +190,18 @@ class TEXT_MT_text(bpy.types.Menu):
layout.column()
layout.operator("text.run_script")
- #ifdef WITH_PYTHON
- # XXX if(BPY_is_pyconstraint(text))
- # XXX uiMenuItemO(head, 0, "text.refresh_pyconstraints");
- #endif
-
- layout.separator()
-
- layout.menu("TEXT_MT_templates")
-
-class TEXT_MT_templates(bpy.types.Menu):
- '''
- Creates the menu items by scanning scripts/templates
- '''
- bl_label = "Script Templates"
+class TEXT_MT_templates(Menu):
+ bl_label = "Templates"
def draw(self, context):
- self.path_menu(bpy.utils.script_paths("templates"), "text.open", {"internal": True})
+ self.path_menu(bpy.utils.script_paths("templates"),
+ "text.open",
+ {"internal": True},
+ )
-class TEXT_MT_edit_select(bpy.types.Menu):
+class TEXT_MT_edit_select(Menu):
bl_label = "Select"
def draw(self, context):
@@ -210,7 +211,7 @@ class TEXT_MT_edit_select(bpy.types.Menu):
layout.operator("text.select_line")
-class TEXT_MT_edit_markers(bpy.types.Menu):
+class TEXT_MT_edit_markers(Menu):
bl_label = "Markers"
def draw(self, context):
@@ -221,7 +222,7 @@ class TEXT_MT_edit_markers(bpy.types.Menu):
layout.operator("text.previous_marker")
-class TEXT_MT_format(bpy.types.Menu):
+class TEXT_MT_format(Menu):
bl_label = "Format"
def draw(self, context):
@@ -240,17 +241,21 @@ class TEXT_MT_format(bpy.types.Menu):
layout.operator_menu_enum("text.convert_whitespace", "type")
-class TEXT_MT_edit_to3d(bpy.types.Menu):
+class TEXT_MT_edit_to3d(Menu):
bl_label = "Text To 3D Object"
def draw(self, context):
layout = self.layout
- layout.operator("text.to_3d_object", text="One Object").split_lines = False
- layout.operator("text.to_3d_object", text="One Object Per Line").split_lines = True
+ layout.operator("text.to_3d_object",
+ text="One Object",
+ ).split_lines = False
+ layout.operator("text.to_3d_object",
+ text="One Object Per Line",
+ ).split_lines = True
-class TEXT_MT_edit(bpy.types.Menu):
+class TEXT_MT_edit(Menu):
bl_label = "Edit"
@classmethod
@@ -284,7 +289,7 @@ class TEXT_MT_edit(bpy.types.Menu):
layout.menu("TEXT_MT_edit_to3d")
-class TEXT_MT_toolbox(bpy.types.Menu):
+class TEXT_MT_toolbox(Menu):
bl_label = ""
def draw(self, context):
diff --git a/release/scripts/startup/bl_ui/space_time.py b/release/scripts/startup/bl_ui/space_time.py
index 7e62465d1ee..db009fe43c2 100644
--- a/release/scripts/startup/bl_ui/space_time.py
+++ b/release/scripts/startup/bl_ui/space_time.py
@@ -18,9 +18,10 @@
# <pep8 compliant>
import bpy
+from bpy.types import Header, Menu
-class TIME_HT_header(bpy.types.Header):
+class TIME_HT_header(Header):
bl_space_type = 'TIMELINE'
def draw(self, context):
@@ -34,10 +35,9 @@ class TIME_HT_header(bpy.types.Header):
row.template_header()
if context.area.show_menus:
- sub = row.row(align=True)
- sub.menu("TIME_MT_view")
- sub.menu("TIME_MT_frame")
- sub.menu("TIME_MT_playback")
+ row.menu("TIME_MT_view")
+ row.menu("TIME_MT_frame")
+ row.menu("TIME_MT_playback")
layout.prop(scene, "use_preview_range", text="", toggle=True)
@@ -91,7 +91,7 @@ class TIME_HT_header(bpy.types.Header):
row.operator("anim.keyframe_delete", text="", icon='KEY_DEHLT')
-class TIME_MT_view(bpy.types.Menu):
+class TIME_MT_view(Menu):
bl_label = "View"
def draw(self, context):
@@ -116,7 +116,7 @@ class TIME_MT_view(bpy.types.Menu):
layout.operator("marker.camera_bind")
-class TIME_MT_cache(bpy.types.Menu):
+class TIME_MT_cache(Menu):
bl_label = "Cache"
def draw(self, context):
@@ -136,7 +136,7 @@ class TIME_MT_cache(bpy.types.Menu):
col.prop(st, "cache_smoke")
-class TIME_MT_frame(bpy.types.Menu):
+class TIME_MT_frame(Menu):
bl_label = "Frame"
def draw(self, context):
@@ -162,7 +162,7 @@ class TIME_MT_frame(bpy.types.Menu):
sub.menu("TIME_MT_autokey")
-class TIME_MT_playback(bpy.types.Menu):
+class TIME_MT_playback(Menu):
bl_label = "Playback"
def draw(self, context):
@@ -187,7 +187,7 @@ class TIME_MT_playback(bpy.types.Menu):
layout.prop(scene, "use_audio_scrub")
-class TIME_MT_autokey(bpy.types.Menu):
+class TIME_MT_autokey(Menu):
bl_label = "Auto-Keyframing Mode"
def draw(self, context):
diff --git a/release/scripts/startup/bl_ui/space_userpref.py b/release/scripts/startup/bl_ui/space_userpref.py
index f018785a925..13edc3471d2 100644
--- a/release/scripts/startup/bl_ui/space_userpref.py
+++ b/release/scripts/startup/bl_ui/space_userpref.py
@@ -18,6 +18,7 @@
# <pep8 compliant>
import bpy
+from bpy.types import Header, Menu, Operator, Panel
import os
import addon_utils
@@ -75,7 +76,7 @@ def opengl_lamp_buttons(column, lamp):
col.prop(lamp, "direction", text="")
-class USERPREF_HT_header(bpy.types.Header):
+class USERPREF_HT_header(Header):
bl_space_type = 'USER_PREFERENCES'
def draw(self, context):
@@ -94,12 +95,12 @@ class USERPREF_HT_header(bpy.types.Header):
layout.operator("wm.keyconfig_import")
elif userpref.active_section == 'ADDONS':
layout.operator("wm.addon_install")
- layout.menu("USERPREF_MT_addons_dev_guides", text=" Addons Developer Guides", icon='INFO')
+ layout.menu("USERPREF_MT_addons_dev_guides")
elif userpref.active_section == 'THEMES':
layout.operator("ui.reset_default_theme")
-class USERPREF_PT_tabs(bpy.types.Panel):
+class USERPREF_PT_tabs(Panel):
bl_label = ""
bl_space_type = 'USER_PREFERENCES'
bl_region_type = 'WINDOW'
@@ -113,26 +114,26 @@ class USERPREF_PT_tabs(bpy.types.Panel):
layout.prop(userpref, "active_section", expand=True)
-class USERPREF_MT_interaction_presets(bpy.types.Menu):
+class USERPREF_MT_interaction_presets(Menu):
bl_label = "Presets"
preset_subdir = "interaction"
preset_operator = "script.execute_preset"
- draw = bpy.types.Menu.draw_preset
+ draw = Menu.draw_preset
-class USERPREF_MT_appconfigs(bpy.types.Menu):
+class USERPREF_MT_appconfigs(Menu):
bl_label = "AppPresets"
preset_subdir = "keyconfig"
preset_operator = "wm.appconfig_activate"
def draw(self, context):
- props = self.layout.operator("wm.appconfig_default", text="Blender (default)")
+ self.layout.operator("wm.appconfig_default", text="Blender (default)")
# now draw the presets
- bpy.types.Menu.draw_preset(self, context)
+ Menu.draw_preset(self, context)
-class USERPREF_MT_splash(bpy.types.Menu):
+class USERPREF_MT_splash(Menu):
bl_label = "Splash"
def draw(self, context):
@@ -149,7 +150,7 @@ class USERPREF_MT_splash(bpy.types.Menu):
row.menu("USERPREF_MT_appconfigs", text="Preset")
-class USERPREF_PT_interface(bpy.types.Panel):
+class USERPREF_PT_interface(Panel):
bl_space_type = 'USER_PREFERENCES'
bl_label = "Interface"
bl_region_type = 'WINDOW'
@@ -246,7 +247,7 @@ class USERPREF_PT_interface(bpy.types.Panel):
col.prop(view, "show_splash")
-class USERPREF_PT_edit(bpy.types.Panel):
+class USERPREF_PT_edit(Panel):
bl_space_type = 'USER_PREFERENCES'
bl_label = "Edit"
bl_region_type = 'WINDOW'
@@ -359,7 +360,7 @@ class USERPREF_PT_edit(bpy.types.Panel):
col.prop(edit, "use_duplicate_particle", text="Particle")
-class USERPREF_PT_system(bpy.types.Panel):
+class USERPREF_PT_system(Panel):
bl_space_type = 'USER_PREFERENCES'
bl_label = "System"
bl_region_type = 'WINDOW'
@@ -438,6 +439,8 @@ class USERPREF_PT_system(bpy.types.Panel):
col.label(text="OpenGL:")
col.prop(system, "gl_clip_alpha", slider=True)
col.prop(system, "use_mipmaps")
+ col.label(text="Anisotropic Filtering")
+ col.prop(system, "anisotropic_filter", text="")
col.prop(system, "use_vertex_buffer_objects")
#Anti-aliasing is disabled as it breaks broder/lasso select
#col.prop(system, "use_antialiasing")
@@ -494,7 +497,7 @@ class USERPREF_PT_system(bpy.types.Panel):
sub.template_color_ramp(system, "weight_color_range", expand=True)
-class USERPREF_PT_theme(bpy.types.Panel):
+class USERPREF_PT_theme(Panel):
bl_space_type = 'USER_PREFERENCES'
bl_label = "Themes"
bl_region_type = 'WINDOW'
@@ -677,7 +680,7 @@ class USERPREF_PT_theme(bpy.types.Panel):
self._theme_generic(split, getattr(theme, theme.theme_area.lower()))
-class USERPREF_PT_file(bpy.types.Panel):
+class USERPREF_PT_file(Panel):
bl_space_type = 'USER_PREFERENCES'
bl_label = "Files"
bl_region_type = 'WINDOW'
@@ -753,7 +756,32 @@ class USERPREF_PT_file(bpy.types.Panel):
from bl_ui.space_userpref_keymap import InputKeyMapPanel
-class USERPREF_PT_input(bpy.types.Panel, InputKeyMapPanel):
+class USERPREF_MT_ndof_settings(Menu):
+ # accessed from the window keybindings in C (only)
+ bl_label = "3D Mouse Settings"
+
+ def draw(self, context):
+ layout = self.layout
+ input_prefs = context.user_preferences.inputs
+
+ layout.separator()
+ layout.prop(input_prefs, "ndof_sensitivity")
+
+ if context.space_data.type == 'VIEW_3D':
+ layout.separator()
+ layout.prop(input_prefs, "ndof_show_guide")
+
+ layout.separator()
+ layout.label(text="orbit options")
+ layout.prop(input_prefs, "ndof_orbit_invert_axes")
+
+ layout.separator()
+ layout.label(text="fly options")
+ layout.prop(input_prefs, "ndof_fly_helicopter", icon='NDOF_FLY')
+ layout.prop(input_prefs, "ndof_lock_horizon", icon='NDOF_DOM')
+
+
+class USERPREF_PT_input(Panel, InputKeyMapPanel):
bl_space_type = 'USER_PREFERENCES'
bl_label = "Input"
@@ -815,12 +843,9 @@ class USERPREF_PT_input(bpy.types.Panel, InputKeyMapPanel):
#sub.prop(view, "wheel_scroll_lines", text="Scroll Lines")
col.separator()
- ''' not implemented yet
sub = col.column()
sub.label(text="NDOF Device:")
- sub.prop(inputs, "ndof_pan_speed", text="Pan Speed")
- sub.prop(inputs, "ndof_rotate_speed", text="Orbit Speed")
- '''
+ sub.prop(inputs, "ndof_sensitivity", text="NDOF Sensitivity")
row.separator()
@@ -846,21 +871,18 @@ class USERPREF_PT_input(bpy.types.Panel, InputKeyMapPanel):
#print("runtime", time.time() - start)
-class USERPREF_MT_addons_dev_guides(bpy.types.Menu):
- bl_label = "Addons develoment guides"
+class USERPREF_MT_addons_dev_guides(Menu):
+ bl_label = "Development Guides"
# menu to open webpages with addons development guides
def draw(self, context):
layout = self.layout
- layout.operator('wm.url_open', text='API Concepts'
- ).url = 'http://wiki.blender.org/index.php/Dev:2.5/Py/API/Intro'
- layout.operator('wm.url_open', text='Addons guidelines',
- ).url = 'http://wiki.blender.org/index.php/Dev:2.5/Py/Scripts/Guidelines/Addons'
- layout.operator('wm.url_open', text='How to share your addon',
- ).url = 'http://wiki.blender.org/index.php/Dev:Py/Sharing'
+ layout.operator('wm.url_open', text='API Concepts', icon='URL').url = 'http://wiki.blender.org/index.php/Dev:2.5/Py/API/Intro'
+ layout.operator('wm.url_open', text='Addon Guidelines', icon='URL').url = 'http://wiki.blender.org/index.php/Dev:2.5/Py/Scripts/Guidelines/Addons'
+ layout.operator('wm.url_open', text='How to share your addon', icon='URL').url = 'http://wiki.blender.org/index.php/Dev:Py/Sharing'
-class USERPREF_PT_addons(bpy.types.Panel):
+class USERPREF_PT_addons(Panel):
bl_space_type = 'USER_PREFERENCES'
bl_label = "Addons"
bl_region_type = 'WINDOW'
@@ -877,6 +899,29 @@ class USERPREF_PT_addons(bpy.types.Panel):
def module_get(mod_name):
return USERPREF_PT_addons._addons_fake_modules[mod_name]
+ @staticmethod
+ def is_user_addon(mod, user_addon_paths):
+ if not user_addon_paths:
+ user_script_path = bpy.utils.user_script_path()
+ if user_script_path is not None:
+ user_addon_paths.append(os.path.join(user_script_path, "addons"))
+ user_addon_paths.append(os.path.join(bpy.utils.resource_path('USER'), "scripts", "addons"))
+
+ for path in user_addon_paths:
+ if bpy.path.is_subdir(mod.__file__, path):
+ return True
+ return False
+
+ @staticmethod
+ def draw_error(layout, message):
+ lines = message.split("\n")
+ box = layout.box()
+ rowsub = box.row()
+ rowsub.label(lines[0])
+ rowsub.label(icon='ERROR')
+ for l in lines[1:]:
+ box.label(l)
+
def draw(self, context):
layout = self.layout
@@ -897,10 +942,27 @@ class USERPREF_PT_addons(bpy.types.Panel):
col = split.column()
+ # set in addon_utils.modules(...)
+ if addon_utils.error_duplicates:
+ self.draw_error(col,
+ "Multiple addons using the same name found!\n"
+ "likely a problem with the script search path.\n"
+ "(see console for details)",
+ )
+
+ if addon_utils.error_encoding:
+ self.draw_error(col,
+ "One or more addons do not have UTF-8 encoding\n"
+ "(see console for details)",
+ )
+
filter = context.window_manager.addon_filter
search = context.window_manager.addon_search.lower()
support = context.window_manager.addon_support
+ # initialized on demand
+ user_addon_paths = []
+
for mod, info in addons:
module_name = mod.__name__
@@ -970,18 +1032,21 @@ class USERPREF_PT_addons(bpy.types.Panel):
split = colsub.row().split(percentage=0.15)
split.label(text="Warning:")
split.label(text=' ' + info["warning"], icon='ERROR')
- if info["wiki_url"] or info["tracker_url"]:
+
+ user_addon = USERPREF_PT_addons.is_user_addon(mod, user_addon_paths)
+ tot_row = bool(info["wiki_url"]) + bool(info["tracker_url"]) + bool(user_addon)
+
+ if tot_row:
split = colsub.row().split(percentage=0.15)
split.label(text="Internet:")
if info["wiki_url"]:
split.operator("wm.url_open", text="Link to the Wiki", icon='HELP').url = info["wiki_url"]
if info["tracker_url"]:
split.operator("wm.url_open", text="Report a Bug", icon='URL').url = info["tracker_url"]
+ if user_addon:
+ split.operator("wm.addon_remove", text="Remove", icon='CANCEL').module = mod.__name__
- if info["wiki_url"] and info["tracker_url"]:
- split.separator()
- else:
- split.separator()
+ for i in range(4 - tot_row):
split.separator()
# Append missing scripts
@@ -1007,54 +1072,84 @@ class USERPREF_PT_addons(bpy.types.Panel):
row.operator("wm.addon_disable", icon='CHECKBOX_HLT', text="", emboss=False).module = module_name
-class WM_OT_addon_enable(bpy.types.Operator):
+class WM_OT_addon_enable(Operator):
"Enable an addon"
bl_idname = "wm.addon_enable"
bl_label = "Enable Add-On"
- module = StringProperty(name="Module", description="Module name of the addon to enable")
+ module = StringProperty(
+ name="Module",
+ description="Module name of the addon to enable",
+ )
def execute(self, context):
mod = addon_utils.enable(self.module)
if mod:
- # check if add-on is written for current blender version, or raise a warning
info = addon_utils.module_bl_info(mod)
- if info.get("blender", (0, 0, 0)) > bpy.app.version:
- self.report("WARNING','This script was written for a newer version of Blender and might not function (correctly).\nThe script is enabled though.")
+ info_ver = info.get("blender", (0, 0, 0))
+
+ if info_ver > bpy.app.version:
+ self.report({'WARNING'}, ("This script was written Blender "
+ "version %d.%d.%d and might not "
+ "function (correctly).\n"
+ "The script is enabled though.") %
+ info_ver)
return {'FINISHED'}
else:
return {'CANCELLED'}
-class WM_OT_addon_disable(bpy.types.Operator):
+class WM_OT_addon_disable(Operator):
"Disable an addon"
bl_idname = "wm.addon_disable"
bl_label = "Disable Add-On"
- module = StringProperty(name="Module", description="Module name of the addon to disable")
+ module = StringProperty(
+ name="Module",
+ description="Module name of the addon to disable",
+ )
def execute(self, context):
addon_utils.disable(self.module)
return {'FINISHED'}
-class WM_OT_addon_install(bpy.types.Operator):
+class WM_OT_addon_install(Operator):
"Install an addon"
bl_idname = "wm.addon_install"
bl_label = "Install Add-On..."
- overwrite = BoolProperty(name="Overwrite", description="Remove existing addons with the same ID", default=True)
+ overwrite = BoolProperty(
+ name="Overwrite",
+ description="Remove existing addons with the same ID",
+ default=True,
+ )
target = EnumProperty(
name="Target Path",
items=(('DEFAULT', "Default", ""),
- ('PREFS', "User Prefs", "")))
-
- filepath = StringProperty(name="File Path", description="File path to write file to")
- filter_folder = BoolProperty(name="Filter folders", description="", default=True, options={'HIDDEN'})
- filter_python = BoolProperty(name="Filter python", description="", default=True, options={'HIDDEN'})
- filter_glob = StringProperty(default="*.py;*.zip", options={'HIDDEN'})
+ ('PREFS', "User Prefs", "")),
+ )
+
+ filepath = StringProperty(
+ name="File Path",
+ description="File path to write file to",
+ )
+ filter_folder = BoolProperty(
+ name="Filter folders",
+ default=True,
+ options={'HIDDEN'},
+ )
+ filter_python = BoolProperty(
+ name="Filter python",
+ default=True,
+ options={'HIDDEN'},
+ )
+ filter_glob = StringProperty(
+ default="*.py;*.zip",
+ options={'HIDDEN'},
+ )
@staticmethod
def _module_remove(path_addons, module):
@@ -1105,7 +1200,6 @@ class WM_OT_addon_install(bpy.types.Operator):
del pyfile_dir
# done checking for exceptional case
- addon_files_old = set(os.listdir(path_addons))
addons_old = {mod.__name__ for mod in addon_utils.modules(USERPREF_PT_addons._addons_fake_modules)}
#check to see if the file is in compressed format (.zip)
@@ -1118,7 +1212,7 @@ class WM_OT_addon_install(bpy.types.Operator):
if self.overwrite:
for f in file_to_extract.namelist():
- __class__._module_remove(path_addons, f)
+ WM_OT_addon_install._module_remove(path_addons, f)
else:
for f in file_to_extract.namelist():
path_dest = os.path.join(path_addons, os.path.basename(f))
@@ -1142,7 +1236,7 @@ class WM_OT_addon_install(bpy.types.Operator):
path_dest = os.path.join(path_addons, os.path.basename(pyfile))
if self.overwrite:
- __class__._module_remove(path_addons, os.path.basename(pyfile))
+ WM_OT_addon_install._module_remove(path_addons, os.path.basename(pyfile))
elif os.path.exists(path_dest):
self.report({'WARNING'}, "File already installed to %r\n" % path_dest)
return {'CANCELLED'}
@@ -1187,12 +1281,66 @@ class WM_OT_addon_install(bpy.types.Operator):
return {'RUNNING_MODAL'}
-class WM_OT_addon_expand(bpy.types.Operator):
+class WM_OT_addon_remove(Operator):
+ "Disable an addon"
+ bl_idname = "wm.addon_remove"
+ bl_label = "Remove Add-On"
+
+ module = StringProperty(
+ name="Module",
+ description="Module name of the addon to remove",
+ )
+
+ @staticmethod
+ def path_from_addon(module):
+ for mod in addon_utils.modules(USERPREF_PT_addons._addons_fake_modules):
+ if mod.__name__ == module:
+ filepath = mod.__file__
+ if os.path.exists(filepath):
+ if os.path.splitext(os.path.basename(filepath))[0] == "__init__":
+ return os.path.dirname(filepath), True
+ else:
+ return filepath, False
+ return None, False
+
+ def execute(self, context):
+ path, isdir = WM_OT_addon_remove.path_from_addon(self.module)
+ if path is None:
+ self.report('WARNING', "Addon path %r could not be found" % path)
+ return {'CANCELLED'}
+
+ # incase its enabled
+ addon_utils.disable(self.module)
+
+ import shutil
+ if isdir:
+ shutil.rmtree(path)
+ else:
+ os.remove(path)
+
+ context.area.tag_redraw()
+ return {'FINISHED'}
+
+ # lame confirmation check
+ def draw(self, context):
+ self.layout.label(text="Remove Addon: %r?" % self.module)
+ path, isdir = WM_OT_addon_remove.path_from_addon(self.module)
+ self.layout.label(text="Path: %r" % path)
+
+ def invoke(self, context, event):
+ wm = context.window_manager
+ return wm.invoke_props_dialog(self, width=600)
+
+
+class WM_OT_addon_expand(Operator):
"Display more information on this add-on"
bl_idname = "wm.addon_expand"
bl_label = ""
- module = StringProperty(name="Module", description="Module name of the addon to expand")
+ module = StringProperty(
+ name="Module",
+ description="Module name of the addon to expand",
+ )
def execute(self, context):
module_name = self.module
diff --git a/release/scripts/startup/bl_ui/space_userpref_keymap.py b/release/scripts/startup/bl_ui/space_userpref_keymap.py
index e99cefb91b8..9ed1591cbf3 100644
--- a/release/scripts/startup/bl_ui/space_userpref_keymap.py
+++ b/release/scripts/startup/bl_ui/space_userpref_keymap.py
@@ -18,6 +18,7 @@
# <pep8 compliant>
import bpy
+from bpy.types import Menu, Operator, OperatorProperties
import os
@@ -124,7 +125,7 @@ def _merge_keymaps(kc1, kc2):
return merged_keymaps
-class USERPREF_MT_keyconfigs(bpy.types.Menu):
+class USERPREF_MT_keyconfigs(Menu):
bl_label = "KeyPresets"
preset_subdir = "keyconfig"
preset_operator = "wm.keyconfig_activate"
@@ -135,7 +136,7 @@ class USERPREF_MT_keyconfigs(bpy.types.Menu):
props.value = "context.window_manager.keyconfigs.default"
# now draw the presets
- bpy.types.Menu.draw_preset(self, context)
+ Menu.draw_preset(self, context)
class InputKeyMapPanel:
@@ -188,10 +189,10 @@ class InputKeyMapPanel:
if km.is_modal:
row.label(text="", icon='LINKED')
- if km.is_user_defined:
- op = row.operator("wm.keymap_restore", text="Restore")
+ if km.is_user_modified:
+ row.operator("wm.keymap_restore", text="Restore")
else:
- op = row.operator("wm.keymap_edit", text="Edit")
+ row.label()
if km.show_expanded_children:
if children:
@@ -212,8 +213,7 @@ class InputKeyMapPanel:
# "Add New" at end of keymap item list
col = self.indented_layout(col, level + 1)
subcol = col.split(percentage=0.2).column()
- subcol.enabled = km.is_user_defined
- op = subcol.operator("wm.keyitem_add", text="Add New", icon='ZOOMIN')
+ subcol.operator("wm.keyitem_add", text="Add New", icon='ZOOMIN')
col.separator()
@@ -233,8 +233,8 @@ class InputKeyMapPanel:
flow = box.column_flow(columns=2)
for pname, value in properties.bl_rna.properties.items():
if pname != "rna_type" and not properties.is_property_hidden(pname):
- if isinstance(value, bpy.types.OperatorProperties):
- __class__.draw_kmi_properties(box, value, title=pname)
+ if isinstance(value, OperatorProperties):
+ InputKeyMapPanel.draw_kmi_properties(box, value, title=pname)
else:
flow.prop(properties, pname)
@@ -243,7 +243,7 @@ class InputKeyMapPanel:
col = self.indented_layout(layout, level)
- if km.is_user_defined:
+ if kmi.show_expanded:
col = col.column(align=True)
box = col.box()
else:
@@ -256,7 +256,6 @@ class InputKeyMapPanel:
row.prop(kmi, "show_expanded", text="", emboss=False)
row = split.row()
- row.enabled = km.is_user_defined
row.prop(kmi, "active", text="", emboss=False)
if km.is_modal:
@@ -265,12 +264,13 @@ class InputKeyMapPanel:
row.label(text=kmi.name)
row = split.row()
- row.enabled = km.is_user_defined
row.prop(kmi, "map_type", text="")
if map_type == 'KEYBOARD':
row.prop(kmi, "type", text="", full_event=True)
elif map_type == 'MOUSE':
row.prop(kmi, "type", text="", full_event=True)
+ elif map_type == 'NDOF':
+ row.prop(kmi, "type", text="", full_event=True)
elif map_type == 'TWEAK':
subrow = row.row()
subrow.prop(kmi, "type", text="")
@@ -280,18 +280,17 @@ class InputKeyMapPanel:
else:
row.label()
- if not kmi.is_user_defined:
+ if (not kmi.is_user_defined) and kmi.is_user_modified:
op = row.operator("wm.keyitem_restore", text="", icon='BACK')
op.item_id = kmi.id
- op = row.operator("wm.keyitem_remove", text="", icon='X')
- op.item_id = kmi.id
+ else:
+ op = row.operator("wm.keyitem_remove", text="", icon='X')
+ op.item_id = kmi.id
# Expanded, additional event settings
if kmi.show_expanded:
box = col.box()
- box.enabled = km.is_user_defined
-
if map_type not in {'TEXTINPUT', 'TIMER'}:
split = box.split(percentage=0.4)
sub = split.row()
@@ -306,7 +305,7 @@ class InputKeyMapPanel:
sub = split.column()
subrow = sub.row(align=True)
- if map_type == 'KEYBOARD':
+ if map_type in {'KEYBOARD', 'NDOF'}:
subrow.prop(kmi, "type", text="", event=True)
subrow.prop(kmi, "value", text="")
elif map_type == 'MOUSE':
@@ -325,7 +324,7 @@ class InputKeyMapPanel:
# Operator properties
props = kmi.properties
if props is not None:
- __class__.draw_kmi_properties(box, props)
+ InputKeyMapPanel.draw_kmi_properties(box, props)
# Modal key maps attached to this operator
if not km.is_modal:
@@ -350,10 +349,10 @@ class InputKeyMapPanel:
row.label()
row.label()
- if km.is_user_defined:
- op = row.operator("wm.keymap_restore", text="Restore")
+ if km.is_user_modified:
+ row.operator("wm.keymap_restore", text="Restore")
else:
- op = row.operator("wm.keymap_edit", text="Edit")
+ row.label()
for kmi in filtered_items:
self.draw_kmi(display_keymaps, kc, km, kmi, col, 1)
@@ -361,8 +360,7 @@ class InputKeyMapPanel:
# "Add New" at end of keymap item list
col = self.indented_layout(layout, 1)
subcol = col.split(percentage=0.2).column()
- subcol.enabled = km.is_user_defined
- op = subcol.operator("wm.keyitem_add", text="Add New", icon='ZOOMIN')
+ subcol.operator("wm.keyitem_add", text="Add New", icon='ZOOMIN')
def draw_hierarchy(self, display_keymaps, layout):
for entry in KM_HIERARCHY:
@@ -370,8 +368,7 @@ class InputKeyMapPanel:
def draw_keymaps(self, context, layout):
wm = context.window_manager
- kc = wm.keyconfigs.active
- defkc = wm.keyconfigs.default
+ kc = wm.keyconfigs.user
col = layout.column()
sub = col.column()
@@ -396,7 +393,7 @@ class InputKeyMapPanel:
col.separator()
- display_keymaps = _merge_keymaps(kc, defkc)
+ display_keymaps = _merge_keymaps(kc, kc)
if context.space_data.filter_text != "":
filter_text = context.space_data.filter_text.lower()
self.draw_filtered(display_keymaps, filter_text, col)
@@ -414,7 +411,7 @@ def export_properties(prefix, properties, lines=None):
for pname in properties.bl_rna.properties.keys():
if pname != "rna_type" and not properties.is_property_hidden(pname):
value = getattr(properties, pname)
- if isinstance(value, bpy.types.OperatorProperties):
+ if isinstance(value, OperatorProperties):
export_properties(prefix + "." + pname, value, lines)
elif properties.is_property_set(pname):
value = _string_value(value)
@@ -423,7 +420,7 @@ def export_properties(prefix, properties, lines=None):
return lines
-class WM_OT_keyconfig_test(bpy.types.Operator):
+class WM_OT_keyconfig_test(Operator):
"Test keyconfig for conflicts"
bl_idname = "wm.keyconfig_test"
bl_label = "Test Key Configuration for Conflicts"
@@ -531,37 +528,58 @@ def _string_value(value):
return result
-class WM_OT_keyconfig_import(bpy.types.Operator):
+class WM_OT_keyconfig_import(Operator):
"Import key configuration from a python script"
bl_idname = "wm.keyconfig_import"
bl_label = "Import Key Configuration..."
- filepath = StringProperty(name="File Path", description="Filepath to write file to", default="keymap.py")
- filter_folder = BoolProperty(name="Filter folders", description="", default=True, options={'HIDDEN'})
- filter_text = BoolProperty(name="Filter text", description="", default=True, options={'HIDDEN'})
- filter_python = BoolProperty(name="Filter python", description="", default=True, options={'HIDDEN'})
-
- keep_original = BoolProperty(name="Keep original", description="Keep original file after copying to configuration folder", default=True)
+ filepath = StringProperty(
+ name="File Path",
+ description="Filepath to write file to",
+ default="keymap.py",
+ )
+ filter_folder = BoolProperty(
+ name="Filter folders",
+ default=True,
+ options={'HIDDEN'},
+ )
+ filter_text = BoolProperty(
+ name="Filter text",
+ default=True,
+ options={'HIDDEN'},
+ )
+ filter_python = BoolProperty(
+ name="Filter python",
+ default=True,
+ options={'HIDDEN'},
+ )
+ keep_original = BoolProperty(
+ name="Keep original",
+ description="Keep original file after copying to configuration folder",
+ default=True,
+ )
def execute(self, context):
from os.path import basename
import shutil
- if not self.filepath:
- raise Exception("Filepath not set")
- f = open(self.filepath, "r")
- if not f:
- raise Exception("Could not open file")
+ if not self.filepath:
+ self.report({'ERROR'}, "Filepath not set")
+ return {'CANCELLED'}
config_name = basename(self.filepath)
path = bpy.utils.user_resource('SCRIPTS', os.path.join("presets", "keyconfig"), create=True)
path = os.path.join(path, config_name)
- if self.keep_original:
- shutil.copy(self.filepath, path)
- else:
- shutil.move(self.filepath, path)
+ try:
+ if self.keep_original:
+ shutil.copy(self.filepath, path)
+ else:
+ shutil.move(self.filepath, path)
+ except Exception as e:
+ self.report({'ERROR'}, "Installing keymap failed: %s" % e)
+ return {'CANCELLED'}
# sneaky way to check we're actually running the code.
bpy.utils.keyconfig_set(path)
@@ -576,20 +594,39 @@ class WM_OT_keyconfig_import(bpy.types.Operator):
# This operator is also used by interaction presets saving - AddPresetBase
-class WM_OT_keyconfig_export(bpy.types.Operator):
+class WM_OT_keyconfig_export(Operator):
"Export key configuration to a python script"
bl_idname = "wm.keyconfig_export"
bl_label = "Export Key Configuration..."
- filepath = StringProperty(name="File Path", description="Filepath to write file to", default="keymap.py")
- filter_folder = BoolProperty(name="Filter folders", description="", default=True, options={'HIDDEN'})
- filter_text = BoolProperty(name="Filter text", description="", default=True, options={'HIDDEN'})
- filter_python = BoolProperty(name="Filter python", description="", default=True, options={'HIDDEN'})
+ filepath = StringProperty(
+ name="File Path",
+ description="Filepath to write file to",
+ default="keymap.py",
+ )
+ filter_folder = BoolProperty(
+ name="Filter folders",
+ default=True,
+ options={'HIDDEN'},
+ )
+ filter_text = BoolProperty(
+ name="Filter text",
+ default=True,
+ options={'HIDDEN'},
+ )
+ filter_python = BoolProperty(
+ name="Filter python",
+ default=True,
+ options={'HIDDEN'},
+ )
def execute(self, context):
if not self.filepath:
raise Exception("Filepath not set")
+ if not self.filepath.endswith('.py'):
+ self.filepath += '.py'
+
f = open(self.filepath, "w")
if not f:
raise Exception("Could not open file")
@@ -604,7 +641,7 @@ class WM_OT_keyconfig_export(bpy.types.Operator):
# Generate a list of keymaps to export:
#
- # First add all user_defined keymaps (found in inputs.edited_keymaps list),
+ # First add all user_modified keymaps (found in keyconfigs.user.keymaps list),
# then add all remaining keymaps from the currently active custom keyconfig.
#
# This will create a final list of keymaps that can be used as a 'diff' against
@@ -614,7 +651,9 @@ class WM_OT_keyconfig_export(bpy.types.Operator):
class FakeKeyConfig():
keymaps = []
edited_kc = FakeKeyConfig()
- edited_kc.keymaps.extend(context.user_preferences.inputs.edited_keymaps)
+ for km in wm.keyconfigs.user.keymaps:
+ if km.is_user_modified:
+ edited_kc.keymaps.append(km)
# merge edited keymaps with non-default keyconfig, if it exists
if kc != wm.keyconfigs.default:
export_keymaps = _merge_keymaps(edited_kc, kc)
@@ -664,29 +703,21 @@ class WM_OT_keyconfig_export(bpy.types.Operator):
return {'RUNNING_MODAL'}
-class WM_OT_keymap_edit(bpy.types.Operator):
- "Edit stored key map"
- bl_idname = "wm.keymap_edit"
- bl_label = "Edit Key Map"
-
- def execute(self, context):
- km = context.keymap
- km.copy_to_user()
- return {'FINISHED'}
-
-
-class WM_OT_keymap_restore(bpy.types.Operator):
+class WM_OT_keymap_restore(Operator):
"Restore key map(s)"
bl_idname = "wm.keymap_restore"
bl_label = "Restore Key Map(s)"
- all = BoolProperty(name="All Keymaps", description="Restore all keymaps to default")
+ all = BoolProperty(
+ name="All Keymaps",
+ description="Restore all keymaps to default",
+ )
def execute(self, context):
wm = context.window_manager
if self.all:
- for km in wm.keyconfigs.default.keymaps:
+ for km in wm.keyconfigs.user.keymaps:
km.restore_to_default()
else:
km = context.keymap
@@ -695,37 +726,38 @@ class WM_OT_keymap_restore(bpy.types.Operator):
return {'FINISHED'}
-class WM_OT_keyitem_restore(bpy.types.Operator):
+class WM_OT_keyitem_restore(Operator):
"Restore key map item"
bl_idname = "wm.keyitem_restore"
bl_label = "Restore Key Map Item"
- item_id = IntProperty(name="Item Identifier", description="Identifier of the item to remove")
+ item_id = IntProperty(
+ name="Item Identifier",
+ description="Identifier of the item to remove",
+ )
@classmethod
def poll(cls, context):
keymap = getattr(context, "keymap", None)
- return keymap and keymap.is_user_defined
+ return keymap
def execute(self, context):
km = context.keymap
kmi = km.keymap_items.from_id(self.item_id)
- if not kmi.is_user_defined:
+ if (not kmi.is_user_defined) and kmi.is_user_modified:
km.restore_item_to_default(kmi)
return {'FINISHED'}
-class WM_OT_keyitem_add(bpy.types.Operator):
+class WM_OT_keyitem_add(Operator):
"Add key map item"
bl_idname = "wm.keyitem_add"
bl_label = "Add Key Map Item"
def execute(self, context):
- wm = context.window_manager
km = context.keymap
- kc = wm.keyconfigs.default
if km.is_modal:
km.keymap_items.new_modal("", 'A', 'PRESS') # kmi
@@ -741,16 +773,19 @@ class WM_OT_keyitem_add(bpy.types.Operator):
return {'FINISHED'}
-class WM_OT_keyitem_remove(bpy.types.Operator):
+class WM_OT_keyitem_remove(Operator):
"Remove key map item"
bl_idname = "wm.keyitem_remove"
bl_label = "Remove Key Map Item"
- item_id = IntProperty(name="Item Identifier", description="Identifier of the item to remove")
+ item_id = IntProperty(
+ name="Item Identifier",
+ description="Identifier of the item to remove",
+ )
@classmethod
def poll(cls, context):
- return hasattr(context, "keymap") and context.keymap.is_user_defined
+ return hasattr(context, "keymap")
def execute(self, context):
km = context.keymap
@@ -759,7 +794,7 @@ class WM_OT_keyitem_remove(bpy.types.Operator):
return {'FINISHED'}
-class WM_OT_keyconfig_remove(bpy.types.Operator):
+class WM_OT_keyconfig_remove(Operator):
"Remove key config"
bl_idname = "wm.keyconfig_remove"
bl_label = "Remove Key Config"
diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py
index 02004283264..9f96df1eb66 100644
--- a/release/scripts/startup/bl_ui/space_view3d.py
+++ b/release/scripts/startup/bl_ui/space_view3d.py
@@ -18,9 +18,10 @@
# <pep8 compliant>
import bpy
+from bpy.types import Header, Menu, Operator, Panel
-class VIEW3D_HT_header(bpy.types.Header):
+class VIEW3D_HT_header(Header):
bl_space_type = 'VIEW_3D'
def draw(self, context):
@@ -54,21 +55,13 @@ class VIEW3D_HT_header(bpy.types.Header):
sub.menu("VIEW3D_MT_object")
row = layout.row()
+ # Contains buttons like Mode, Pivot, Manipulator, Layer, Mesh Select Mode...
row.template_header_3D()
- # do in C for now since these buttons cant be both toggle AND exclusive.
- '''
- if obj and obj.mode == 'EDIT' and obj.type == 'MESH':
- row_sub = row.row(align=True)
- row_sub.prop(toolsettings, "mesh_select_mode", text="", index=0, icon='VERTEXSEL')
- row_sub.prop(toolsettings, "mesh_select_mode", text="", index=1, icon='EDGESEL')
- row_sub.prop(toolsettings, "mesh_select_mode", text="", index=2, icon='FACESEL')
- '''
-
if obj:
# Particle edit
if obj.mode == 'PARTICLE_EDIT':
- row.prop(toolsettings.particle_edit, "select_mode", text="", expand=True, toggle=True)
+ row.prop(toolsettings.particle_edit, "select_mode", text="", expand=True)
# Occlude geometry
if view.viewport_shade in {'SOLID', 'SHADED', 'TEXTURED'} and (obj.mode == 'PARTICLE_EDIT' or (obj.mode == 'EDIT' and obj.type == 'MESH')):
@@ -87,16 +80,21 @@ class VIEW3D_HT_header(bpy.types.Header):
row.prop(toolsettings, "proportional_edit_falloff", text="", icon_only=True)
# Snap
+ snap_element = toolsettings.snap_element
row = layout.row(align=True)
row.prop(toolsettings, "use_snap", text="")
row.prop(toolsettings, "snap_element", text="", icon_only=True)
- if toolsettings.snap_element != 'INCREMENT':
+ if snap_element != 'INCREMENT':
row.prop(toolsettings, "snap_target", text="")
- if obj and obj.mode == 'OBJECT':
- row.prop(toolsettings, "use_snap_align_rotation", text="")
- if toolsettings.snap_element == 'VOLUME':
+ if obj:
+ if obj.mode == 'OBJECT':
+ row.prop(toolsettings, "use_snap_align_rotation", text="")
+ elif obj.mode == 'EDIT':
+ row.prop(toolsettings, "use_snap_self", text="")
+
+ if snap_element == 'VOLUME':
row.prop(toolsettings, "use_snap_peel_object", text="")
- elif toolsettings.snap_element == 'FACE':
+ elif snap_element == 'FACE':
row.prop(toolsettings, "use_snap_project", text="")
# OpenGL render
@@ -131,7 +129,7 @@ class ShowHideMenu():
layout.operator("%s.hide" % self._operator_name, text="Hide Unselected").unselected = True
-class VIEW3D_MT_transform(bpy.types.Menu):
+class VIEW3D_MT_transform(Menu):
bl_label = "Transform"
# TODO: get rid of the custom text strings?
@@ -182,8 +180,12 @@ class VIEW3D_MT_transform(bpy.types.Menu):
layout.operator("object.randomize_transform")
layout.operator("object.align")
+ layout.separator()
+
+ layout.operator("object.anim_transforms_to_deltas")
-class VIEW3D_MT_mirror(bpy.types.Menu):
+
+class VIEW3D_MT_mirror(Menu):
bl_label = "Mirror"
def draw(self, context):
@@ -221,7 +223,7 @@ class VIEW3D_MT_mirror(bpy.types.Menu):
layout.operator("object.vertex_group_mirror")
-class VIEW3D_MT_snap(bpy.types.Menu):
+class VIEW3D_MT_snap(Menu):
bl_label = "Snap"
def draw(self, context):
@@ -238,7 +240,7 @@ class VIEW3D_MT_snap(bpy.types.Menu):
layout.operator("view3d.snap_cursor_to_active", text="Cursor to Active")
-class VIEW3D_MT_uv_map(bpy.types.Menu):
+class VIEW3D_MT_uv_map(Menu):
bl_label = "UV Mapping"
def draw(self, context):
@@ -271,7 +273,7 @@ class VIEW3D_MT_uv_map(bpy.types.Menu):
# ********** View menus **********
-class VIEW3D_MT_view(bpy.types.Menu):
+class VIEW3D_MT_view(Menu):
bl_label = "View"
def draw(self, context):
@@ -329,7 +331,7 @@ class VIEW3D_MT_view(bpy.types.Menu):
layout.operator("screen.screen_full_area")
-class VIEW3D_MT_view_navigation(bpy.types.Menu):
+class VIEW3D_MT_view_navigation(Menu):
bl_label = "Navigation"
def draw(self, context):
@@ -352,7 +354,7 @@ class VIEW3D_MT_view_navigation(bpy.types.Menu):
layout.operator("view3d.fly")
-class VIEW3D_MT_view_align(bpy.types.Menu):
+class VIEW3D_MT_view_align(Menu):
bl_label = "Align View"
def draw(self, context):
@@ -368,7 +370,7 @@ class VIEW3D_MT_view_align(bpy.types.Menu):
layout.operator("view3d.view_center_cursor")
-class VIEW3D_MT_view_align_selected(bpy.types.Menu):
+class VIEW3D_MT_view_align_selected(Menu):
bl_label = "Align View to Selected"
def draw(self, context):
@@ -394,7 +396,7 @@ class VIEW3D_MT_view_align_selected(bpy.types.Menu):
props.type = 'LEFT'
-class VIEW3D_MT_view_cameras(bpy.types.Menu):
+class VIEW3D_MT_view_cameras(Menu):
bl_label = "Cameras"
def draw(self, context):
@@ -406,7 +408,7 @@ class VIEW3D_MT_view_cameras(bpy.types.Menu):
# ********** Select menus, suffix from context.mode **********
-class VIEW3D_MT_select_object(bpy.types.Menu):
+class VIEW3D_MT_select_object(Menu):
bl_label = "Select"
def draw(self, context):
@@ -432,7 +434,7 @@ class VIEW3D_MT_select_object(bpy.types.Menu):
layout.operator("object.select_pattern", text="Select Pattern...")
-class VIEW3D_MT_select_pose(bpy.types.Menu):
+class VIEW3D_MT_select_pose(Menu):
bl_label = "Select"
def draw(self, context):
@@ -469,7 +471,7 @@ class VIEW3D_MT_select_pose(bpy.types.Menu):
layout.operator("object.select_pattern", text="Select Pattern...")
-class VIEW3D_MT_select_particle(bpy.types.Menu):
+class VIEW3D_MT_select_particle(Menu):
bl_label = "Select"
def draw(self, context):
@@ -494,7 +496,7 @@ class VIEW3D_MT_select_particle(bpy.types.Menu):
layout.operator("particle.select_tips", text="Tips")
-class VIEW3D_MT_select_edit_mesh(bpy.types.Menu):
+class VIEW3D_MT_select_edit_mesh(Menu):
bl_label = "Select"
def draw(self, context):
@@ -546,7 +548,7 @@ class VIEW3D_MT_select_edit_mesh(bpy.types.Menu):
layout.operator("mesh.region_to_loop")
-class VIEW3D_MT_select_edit_curve(bpy.types.Menu):
+class VIEW3D_MT_select_edit_curve(Menu):
bl_label = "Select"
def draw(self, context):
@@ -575,7 +577,7 @@ class VIEW3D_MT_select_edit_curve(bpy.types.Menu):
layout.operator("curve.select_less")
-class VIEW3D_MT_select_edit_surface(bpy.types.Menu):
+class VIEW3D_MT_select_edit_surface(Menu):
bl_label = "Select"
def draw(self, context):
@@ -601,7 +603,7 @@ class VIEW3D_MT_select_edit_surface(bpy.types.Menu):
layout.operator("curve.select_less")
-class VIEW3D_MT_select_edit_metaball(bpy.types.Menu):
+class VIEW3D_MT_select_edit_metaball(Menu):
bl_label = "Select"
def draw(self, context):
@@ -619,7 +621,7 @@ class VIEW3D_MT_select_edit_metaball(bpy.types.Menu):
layout.operator("mball.select_random_metaelems")
-class VIEW3D_MT_select_edit_lattice(bpy.types.Menu):
+class VIEW3D_MT_select_edit_lattice(Menu):
bl_label = "Select"
def draw(self, context):
@@ -632,7 +634,7 @@ class VIEW3D_MT_select_edit_lattice(bpy.types.Menu):
layout.operator("lattice.select_all", text="Select/Deselect All")
-class VIEW3D_MT_select_edit_armature(bpy.types.Menu):
+class VIEW3D_MT_select_edit_armature(Menu):
bl_label = "Select"
def draw(self, context):
@@ -663,7 +665,7 @@ class VIEW3D_MT_select_edit_armature(bpy.types.Menu):
layout.operator("object.select_pattern", text="Select Pattern...")
-class VIEW3D_MT_select_face(bpy.types.Menu): # XXX no matching enum
+class VIEW3D_MT_select_face(Menu): # XXX no matching enum
bl_label = "Select"
def draw(self, context):
@@ -676,7 +678,7 @@ class VIEW3D_MT_select_face(bpy.types.Menu): # XXX no matching enum
# ********** Object menu **********
-class VIEW3D_MT_object(bpy.types.Menu):
+class VIEW3D_MT_object(Menu):
bl_context = "objectmode"
bl_label = "Object"
@@ -734,7 +736,7 @@ class VIEW3D_MT_object(bpy.types.Menu):
layout.operator_menu_enum("object.convert", "target")
-class VIEW3D_MT_object_animation(bpy.types.Menu):
+class VIEW3D_MT_object_animation(Menu):
bl_label = "Animation"
def draw(self, context):
@@ -745,7 +747,7 @@ class VIEW3D_MT_object_animation(bpy.types.Menu):
layout.operator("anim.keying_set_active_set", text="Change Keying Set...")
-class VIEW3D_MT_object_clear(bpy.types.Menu):
+class VIEW3D_MT_object_clear(Menu):
bl_label = "Clear"
def draw(self, context):
@@ -757,7 +759,7 @@ class VIEW3D_MT_object_clear(bpy.types.Menu):
layout.operator("object.origin_clear", text="Origin")
-class VIEW3D_MT_object_specials(bpy.types.Menu):
+class VIEW3D_MT_object_specials(Menu):
bl_label = "Specials"
@classmethod
@@ -772,10 +774,16 @@ class VIEW3D_MT_object_specials(bpy.types.Menu):
if obj.type == 'CAMERA':
layout.operator_context = 'INVOKE_REGION_WIN'
- props = layout.operator("wm.context_modal_mouse", text="Camera Lens Angle")
- props.data_path_iter = "selected_editable_objects"
- props.data_path_item = "data.lens"
- props.input_scale = 0.1
+ if obj.data.type == 'PERSP':
+ props = layout.operator("wm.context_modal_mouse", text="Camera Lens Angle")
+ props.data_path_iter = "selected_editable_objects"
+ props.data_path_item = "data.lens"
+ props.input_scale = 0.1
+ else:
+ props = layout.operator("wm.context_modal_mouse", text="Camera Lens Scale")
+ props.data_path_iter = "selected_editable_objects"
+ props.data_path_item = "data.ortho_scale"
+ props.input_scale = 0.01
if not obj.data.dof_object:
#layout.label(text="Test Has DOF obj");
@@ -846,7 +854,7 @@ class VIEW3D_MT_object_specials(bpy.types.Menu):
props = layout.operator("object.hide_render_clear_all")
-class VIEW3D_MT_object_apply(bpy.types.Menu):
+class VIEW3D_MT_object_apply(Menu):
bl_label = "Apply"
def draw(self, context):
@@ -865,7 +873,7 @@ class VIEW3D_MT_object_apply(bpy.types.Menu):
layout.operator("object.duplicates_make_real")
-class VIEW3D_MT_object_parent(bpy.types.Menu):
+class VIEW3D_MT_object_parent(Menu):
bl_label = "Parent"
def draw(self, context):
@@ -875,7 +883,7 @@ class VIEW3D_MT_object_parent(bpy.types.Menu):
layout.operator("object.parent_clear", text="Clear")
-class VIEW3D_MT_object_track(bpy.types.Menu):
+class VIEW3D_MT_object_track(Menu):
bl_label = "Track"
def draw(self, context):
@@ -885,7 +893,7 @@ class VIEW3D_MT_object_track(bpy.types.Menu):
layout.operator("object.track_clear", text="Clear")
-class VIEW3D_MT_object_group(bpy.types.Menu):
+class VIEW3D_MT_object_group(Menu):
bl_label = "Group"
def draw(self, context):
@@ -900,7 +908,7 @@ class VIEW3D_MT_object_group(bpy.types.Menu):
layout.operator("group.objects_remove_active")
-class VIEW3D_MT_object_constraints(bpy.types.Menu):
+class VIEW3D_MT_object_constraints(Menu):
bl_label = "Constraints"
def draw(self, context):
@@ -911,7 +919,7 @@ class VIEW3D_MT_object_constraints(bpy.types.Menu):
layout.operator("object.constraints_clear")
-class VIEW3D_MT_object_showhide(bpy.types.Menu):
+class VIEW3D_MT_object_showhide(Menu):
bl_label = "Show/Hide"
def draw(self, context):
@@ -922,7 +930,7 @@ class VIEW3D_MT_object_showhide(bpy.types.Menu):
layout.operator("object.hide_view_set", text="Hide Unselected").unselected = True
-class VIEW3D_MT_make_single_user(bpy.types.Menu):
+class VIEW3D_MT_make_single_user(Menu):
bl_label = "Make Single User"
def draw(self, context):
@@ -944,7 +952,7 @@ class VIEW3D_MT_make_single_user(bpy.types.Menu):
props.animation = True
-class VIEW3D_MT_make_links(bpy.types.Menu):
+class VIEW3D_MT_make_links(Menu):
bl_label = "Make Links"
def draw(self, context):
@@ -961,7 +969,7 @@ class VIEW3D_MT_make_links(bpy.types.Menu):
layout.operator_enum("object.make_links_data", "type") # inline
-class VIEW3D_MT_object_game(bpy.types.Menu):
+class VIEW3D_MT_object_game(Menu):
bl_label = "Game"
def draw(self, context):
@@ -983,7 +991,7 @@ class VIEW3D_MT_object_game(bpy.types.Menu):
# ********** Vertex paint menu **********
-class VIEW3D_MT_paint_vertex(bpy.types.Menu):
+class VIEW3D_MT_paint_vertex(Menu):
bl_label = "Paint"
def draw(self, context):
@@ -998,7 +1006,7 @@ class VIEW3D_MT_paint_vertex(bpy.types.Menu):
layout.operator("paint.vertex_color_dirt")
-class VIEW3D_MT_hook(bpy.types.Menu):
+class VIEW3D_MT_hook(Menu):
bl_label = "Hooks"
def draw(self, context):
@@ -1017,7 +1025,7 @@ class VIEW3D_MT_hook(bpy.types.Menu):
layout.operator_menu_enum("object.hook_recenter", "modifier")
-class VIEW3D_MT_vertex_group(bpy.types.Menu):
+class VIEW3D_MT_vertex_group(Menu):
bl_label = "Vertex Groups"
def draw(self, context):
@@ -1042,7 +1050,7 @@ class VIEW3D_MT_vertex_group(bpy.types.Menu):
# ********** Weight paint menu **********
-class VIEW3D_MT_paint_weight(bpy.types.Menu):
+class VIEW3D_MT_paint_weight(Menu):
bl_label = "Weights"
def draw(self, context):
@@ -1072,7 +1080,7 @@ class VIEW3D_MT_paint_weight(bpy.types.Menu):
# ********** Sculpt menu **********
-class VIEW3D_MT_sculpt(bpy.types.Menu):
+class VIEW3D_MT_sculpt(Menu):
bl_label = "Sculpt"
def draw(self, context):
@@ -1098,17 +1106,18 @@ class VIEW3D_MT_sculpt(bpy.types.Menu):
layout.operator_menu_enum("brush.curve_preset", "shape")
layout.separator()
- sculpt_tool = brush.sculpt_tool
+ if brush is not None: # unlikely but can happen
+ sculpt_tool = brush.sculpt_tool
- if sculpt_tool != 'GRAB':
- layout.prop_menu_enum(brush, "stroke_method")
+ if sculpt_tool != 'GRAB':
+ layout.prop_menu_enum(brush, "stroke_method")
- if sculpt_tool in {'DRAW', 'PINCH', 'INFLATE', 'LAYER', 'CLAY'}:
- layout.prop_menu_enum(brush, "direction")
+ if sculpt_tool in {'DRAW', 'PINCH', 'INFLATE', 'LAYER', 'CLAY'}:
+ layout.prop_menu_enum(brush, "direction")
- if sculpt_tool == 'LAYER':
- layout.prop(brush, "use_persistent")
- layout.operator("sculpt.set_persistent_base")
+ if sculpt_tool == 'LAYER':
+ layout.prop(brush, "use_persistent")
+ layout.operator("sculpt.set_persistent_base")
layout.separator()
layout.prop(sculpt, "use_threaded", text="Threaded Sculpt")
@@ -1121,7 +1130,7 @@ class VIEW3D_MT_sculpt(bpy.types.Menu):
# ********** Particle menu **********
-class VIEW3D_MT_particle(bpy.types.Menu):
+class VIEW3D_MT_particle(Menu):
bl_label = "Particle"
def draw(self, context):
@@ -1153,7 +1162,7 @@ class VIEW3D_MT_particle(bpy.types.Menu):
layout.menu("VIEW3D_MT_particle_showhide")
-class VIEW3D_MT_particle_specials(bpy.types.Menu):
+class VIEW3D_MT_particle_specials(Menu):
bl_label = "Specials"
def draw(self, context):
@@ -1171,13 +1180,13 @@ class VIEW3D_MT_particle_specials(bpy.types.Menu):
layout.operator("particle.remove_doubles")
-class VIEW3D_MT_particle_showhide(ShowHideMenu, bpy.types.Menu):
+class VIEW3D_MT_particle_showhide(ShowHideMenu, Menu):
_operator_name = "particle"
# ********** Pose Menu **********
-class VIEW3D_MT_pose(bpy.types.Menu):
+class VIEW3D_MT_pose(Menu):
bl_label = "Pose"
def draw(self, context):
@@ -1243,10 +1252,10 @@ class VIEW3D_MT_pose(bpy.types.Menu):
layout.separator()
layout.menu("VIEW3D_MT_pose_showhide")
- layout.operator_menu_enum("pose.flags_set", 'mode', text="Bone Settings")
+ layout.menu("VIEW3D_MT_bone_options_toggle", text="Bone Settings")
-class VIEW3D_MT_pose_transform(bpy.types.Menu):
+class VIEW3D_MT_pose_transform(Menu):
bl_label = "Clear Transform"
def draw(self, context):
@@ -1254,14 +1263,18 @@ class VIEW3D_MT_pose_transform(bpy.types.Menu):
layout.operator("pose.transforms_clear", text="All")
+ layout.separator()
+
layout.operator("pose.loc_clear", text="Location")
layout.operator("pose.rot_clear", text="Rotation")
layout.operator("pose.scale_clear", text="Scale")
- layout.label(text="Origin")
+ layout.separator()
+
+ layout.operator("pose.user_transforms_clear", text="Reset unkeyed")
-class VIEW3D_MT_pose_slide(bpy.types.Menu):
+class VIEW3D_MT_pose_slide(Menu):
bl_label = "In-Betweens"
def draw(self, context):
@@ -1272,7 +1285,7 @@ class VIEW3D_MT_pose_slide(bpy.types.Menu):
layout.operator("pose.breakdown")
-class VIEW3D_MT_pose_propagate(bpy.types.Menu):
+class VIEW3D_MT_pose_propagate(Menu):
bl_label = "Propagate"
def draw(self, context):
@@ -1290,7 +1303,7 @@ class VIEW3D_MT_pose_propagate(bpy.types.Menu):
layout.operator("pose.propagate", text="On Selected Markers").mode = 'SELECTED_MARKERS'
-class VIEW3D_MT_pose_library(bpy.types.Menu):
+class VIEW3D_MT_pose_library(Menu):
bl_label = "Pose Library"
def draw(self, context):
@@ -1305,7 +1318,7 @@ class VIEW3D_MT_pose_library(bpy.types.Menu):
layout.operator("poselib.pose_remove", text="Remove Pose...")
-class VIEW3D_MT_pose_motion(bpy.types.Menu):
+class VIEW3D_MT_pose_motion(Menu):
bl_label = "Motion Paths"
def draw(self, context):
@@ -1315,7 +1328,7 @@ class VIEW3D_MT_pose_motion(bpy.types.Menu):
layout.operator("pose.paths_clear", text="Clear")
-class VIEW3D_MT_pose_group(bpy.types.Menu):
+class VIEW3D_MT_pose_group(Menu):
bl_label = "Bone Groups"
def draw(self, context):
@@ -1329,7 +1342,7 @@ class VIEW3D_MT_pose_group(bpy.types.Menu):
layout.operator("pose.group_unassign")
-class VIEW3D_MT_pose_ik(bpy.types.Menu):
+class VIEW3D_MT_pose_ik(Menu):
bl_label = "Inverse Kinematics"
def draw(self, context):
@@ -1339,7 +1352,7 @@ class VIEW3D_MT_pose_ik(bpy.types.Menu):
layout.operator("pose.ik_clear")
-class VIEW3D_MT_pose_constraints(bpy.types.Menu):
+class VIEW3D_MT_pose_constraints(Menu):
bl_label = "Constraints"
def draw(self, context):
@@ -1350,11 +1363,11 @@ class VIEW3D_MT_pose_constraints(bpy.types.Menu):
layout.operator("pose.constraints_clear")
-class VIEW3D_MT_pose_showhide(ShowHideMenu, bpy.types.Menu):
+class VIEW3D_MT_pose_showhide(ShowHideMenu, Menu):
_operator_name = "pose"
-class VIEW3D_MT_pose_apply(bpy.types.Menu):
+class VIEW3D_MT_pose_apply(Menu):
bl_label = "Apply"
def draw(self, context):
@@ -1364,10 +1377,53 @@ class VIEW3D_MT_pose_apply(bpy.types.Menu):
layout.operator("pose.visual_transform_apply")
+class BoneOptions:
+ def draw(self, context):
+ layout = self.layout
+
+ options = [
+ "show_wire",
+ "use_deform",
+ "use_envelope_multiply",
+ "use_inherit_rotation",
+ "use_inherit_scale",
+ ]
+
+ if context.mode == 'EDIT_ARMATURE':
+ bone_props = bpy.types.EditBone.bl_rna.properties
+ data_path_iter = "selected_bones"
+ opt_suffix = ""
+ options.append("lock")
+ else: # posemode
+ bone_props = bpy.types.Bone.bl_rna.properties
+ data_path_iter = "selected_pose_bones"
+ opt_suffix = "bone."
+
+ for opt in options:
+ props = layout.operator("wm.context_collection_boolean_set", text=bone_props[opt].name)
+ props.data_path_iter = data_path_iter
+ props.data_path_item = opt_suffix + opt
+ props.type = self.type
+
+
+class VIEW3D_MT_bone_options_toggle(Menu, BoneOptions):
+ bl_label = "Toggle Bone Options"
+ type = 'TOGGLE'
+
+
+class VIEW3D_MT_bone_options_enable(Menu, BoneOptions):
+ bl_label = "Enable Bone Options"
+ type = 'ENABLE'
+
+
+class VIEW3D_MT_bone_options_disable(Menu, BoneOptions):
+ bl_label = "Disable Bone Options"
+ type = 'DISABLE'
+
# ********** Edit Menus, suffix from ob.type **********
-class VIEW3D_MT_edit_mesh(bpy.types.Menu):
+class VIEW3D_MT_edit_mesh(Menu):
bl_label = "Mesh"
def draw(self, context):
@@ -1414,7 +1470,7 @@ class VIEW3D_MT_edit_mesh(bpy.types.Menu):
layout.menu("VIEW3D_MT_edit_mesh_showhide")
-class VIEW3D_MT_edit_mesh_specials(bpy.types.Menu):
+class VIEW3D_MT_edit_mesh_specials(Menu):
bl_label = "Specials"
def draw(self, context):
@@ -1439,7 +1495,7 @@ class VIEW3D_MT_edit_mesh_specials(bpy.types.Menu):
layout.operator("mesh.select_vertex_path")
-class VIEW3D_MT_edit_mesh_select_mode(bpy.types.Menu):
+class VIEW3D_MT_edit_mesh_select_mode(Menu):
bl_label = "Mesh Select Mode"
def draw(self, context):
@@ -1460,7 +1516,7 @@ class VIEW3D_MT_edit_mesh_select_mode(bpy.types.Menu):
prop.data_path = "tool_settings.mesh_select_mode"
-class VIEW3D_MT_edit_mesh_extrude(bpy.types.Menu):
+class VIEW3D_MT_edit_mesh_extrude(Menu):
bl_label = "Extrude"
_extrude_funcs = { \
@@ -1494,7 +1550,7 @@ class VIEW3D_MT_edit_mesh_extrude(bpy.types.Menu):
self._extrude_funcs[menu_id](layout)
-class VIEW3D_OT_edit_mesh_extrude_individual_move(bpy.types.Operator):
+class VIEW3D_OT_edit_mesh_extrude_individual_move(Operator):
"Extrude individual elements and move"
bl_label = "Extrude Individual and Move"
bl_idname = "view3d.edit_mesh_extrude_individual_move"
@@ -1523,7 +1579,7 @@ class VIEW3D_OT_edit_mesh_extrude_individual_move(bpy.types.Operator):
return self.execute(context)
-class VIEW3D_OT_edit_mesh_extrude_move(bpy.types.Operator):
+class VIEW3D_OT_edit_mesh_extrude_move(Operator):
"Extrude and move along normals"
bl_label = "Extrude and Move on Normals"
bl_idname = "view3d.edit_mesh_extrude_move_normal"
@@ -1549,7 +1605,7 @@ class VIEW3D_OT_edit_mesh_extrude_move(bpy.types.Operator):
return self.execute(context)
-class VIEW3D_MT_edit_mesh_vertices(bpy.types.Menu):
+class VIEW3D_MT_edit_mesh_vertices(Menu):
bl_label = "Vertices"
def draw(self, context):
@@ -1581,7 +1637,7 @@ class VIEW3D_MT_edit_mesh_vertices(bpy.types.Menu):
layout.menu("VIEW3D_MT_hook")
-class VIEW3D_MT_edit_mesh_edges(bpy.types.Menu):
+class VIEW3D_MT_edit_mesh_edges(Menu):
bl_label = "Edges"
def draw(self, context):
@@ -1621,7 +1677,7 @@ class VIEW3D_MT_edit_mesh_edges(bpy.types.Menu):
layout.operator("mesh.region_to_loop")
-class VIEW3D_MT_edit_mesh_faces(bpy.types.Menu):
+class VIEW3D_MT_edit_mesh_faces(Menu):
bl_label = "Faces"
bl_idname = "VIEW3D_MT_edit_mesh_faces"
@@ -1669,7 +1725,7 @@ class VIEW3D_MT_edit_mesh_faces(bpy.types.Menu):
layout.operator_menu_enum("mesh.colors_mirror", "axis")
-class VIEW3D_MT_edit_mesh_normals(bpy.types.Menu):
+class VIEW3D_MT_edit_mesh_normals(Menu):
bl_label = "Normals"
def draw(self, context):
@@ -1683,7 +1739,7 @@ class VIEW3D_MT_edit_mesh_normals(bpy.types.Menu):
layout.operator("mesh.flip_normals")
-class VIEW3D_MT_edit_mesh_showhide(ShowHideMenu, bpy.types.Menu):
+class VIEW3D_MT_edit_mesh_showhide(ShowHideMenu, Menu):
_operator_name = "mesh"
# Edit Curve
@@ -1723,13 +1779,13 @@ def draw_curve(self, context):
layout.menu("VIEW3D_MT_edit_curve_showhide")
-class VIEW3D_MT_edit_curve(bpy.types.Menu):
+class VIEW3D_MT_edit_curve(Menu):
bl_label = "Curve"
draw = draw_curve
-class VIEW3D_MT_edit_curve_ctrlpoints(bpy.types.Menu):
+class VIEW3D_MT_edit_curve_ctrlpoints(Menu):
bl_label = "Control Points"
def draw(self, context):
@@ -1751,7 +1807,7 @@ class VIEW3D_MT_edit_curve_ctrlpoints(bpy.types.Menu):
layout.menu("VIEW3D_MT_hook")
-class VIEW3D_MT_edit_curve_segments(bpy.types.Menu):
+class VIEW3D_MT_edit_curve_segments(Menu):
bl_label = "Segments"
def draw(self, context):
@@ -1761,7 +1817,7 @@ class VIEW3D_MT_edit_curve_segments(bpy.types.Menu):
layout.operator("curve.switch_direction")
-class VIEW3D_MT_edit_curve_specials(bpy.types.Menu):
+class VIEW3D_MT_edit_curve_specials(Menu):
bl_label = "Specials"
def draw(self, context):
@@ -1775,17 +1831,17 @@ class VIEW3D_MT_edit_curve_specials(bpy.types.Menu):
layout.operator("curve.smooth_radius")
-class VIEW3D_MT_edit_curve_showhide(ShowHideMenu, bpy.types.Menu):
+class VIEW3D_MT_edit_curve_showhide(ShowHideMenu, Menu):
_operator_name = "curve"
-class VIEW3D_MT_edit_surface(bpy.types.Menu):
+class VIEW3D_MT_edit_surface(Menu):
bl_label = "Surface"
draw = draw_curve
-class VIEW3D_MT_edit_font(bpy.types.Menu):
+class VIEW3D_MT_edit_font(Menu):
bl_label = "Text"
def draw(self, context):
@@ -1805,7 +1861,7 @@ class VIEW3D_MT_edit_font(bpy.types.Menu):
layout.operator("font.style_toggle", text="Toggle Small Caps").style = 'SMALL_CAPS'
-class VIEW3D_MT_edit_text_chars(bpy.types.Menu):
+class VIEW3D_MT_edit_text_chars(Menu):
bl_label = "Special Characters"
def draw(self, context):
@@ -1839,7 +1895,7 @@ class VIEW3D_MT_edit_text_chars(bpy.types.Menu):
layout.operator("font.text_insert", text="Spanish Exclamation Mark|Alt !").text = b'\xC2\xA1'.decode()
-class VIEW3D_MT_edit_meta(bpy.types.Menu):
+class VIEW3D_MT_edit_meta(Menu):
bl_label = "Metaball"
def draw(self, context):
@@ -1872,7 +1928,7 @@ class VIEW3D_MT_edit_meta(bpy.types.Menu):
layout.menu("VIEW3D_MT_edit_meta_showhide")
-class VIEW3D_MT_edit_meta_showhide(bpy.types.Menu):
+class VIEW3D_MT_edit_meta_showhide(Menu):
bl_label = "Show/Hide"
def draw(self, context):
@@ -1883,7 +1939,7 @@ class VIEW3D_MT_edit_meta_showhide(bpy.types.Menu):
layout.operator("mball.hide_metaelems", text="Hide Unselected").unselected = True
-class VIEW3D_MT_edit_lattice(bpy.types.Menu):
+class VIEW3D_MT_edit_lattice(Menu):
bl_label = "Lattice"
def draw(self, context):
@@ -1905,7 +1961,7 @@ class VIEW3D_MT_edit_lattice(bpy.types.Menu):
layout.prop_menu_enum(settings, "proportional_edit_falloff")
-class VIEW3D_MT_edit_armature(bpy.types.Menu):
+class VIEW3D_MT_edit_armature(Menu):
bl_label = "Armature"
def draw(self, context):
@@ -1957,10 +2013,10 @@ class VIEW3D_MT_edit_armature(bpy.types.Menu):
layout.separator()
- layout.operator_menu_enum("armature.flags_set", "mode", text="Bone Settings")
+ layout.menu("VIEW3D_MT_bone_options_toggle", text="Bone Settings")
-class VIEW3D_MT_armature_specials(bpy.types.Menu):
+class VIEW3D_MT_armature_specials(Menu):
bl_label = "Specials"
def draw(self, context):
@@ -1980,7 +2036,7 @@ class VIEW3D_MT_armature_specials(bpy.types.Menu):
layout.operator("armature.flip_names", text="Flip Names")
-class VIEW3D_MT_edit_armature_parent(bpy.types.Menu):
+class VIEW3D_MT_edit_armature_parent(Menu):
bl_label = "Parent"
def draw(self, context):
@@ -1990,7 +2046,7 @@ class VIEW3D_MT_edit_armature_parent(bpy.types.Menu):
layout.operator("armature.parent_clear", text="Clear")
-class VIEW3D_MT_edit_armature_roll(bpy.types.Menu):
+class VIEW3D_MT_edit_armature_roll(Menu):
bl_label = "Bone Roll"
def draw(self, context):
@@ -2005,7 +2061,7 @@ class VIEW3D_MT_edit_armature_roll(bpy.types.Menu):
# ********** Panel **********
-class VIEW3D_PT_view3d_properties(bpy.types.Panel):
+class VIEW3D_PT_view3d_properties(Panel):
bl_space_type = 'VIEW_3D'
bl_region_type = 'UI'
bl_label = "View"
@@ -2025,9 +2081,11 @@ class VIEW3D_PT_view3d_properties(bpy.types.Panel):
col.prop(view, "lens")
col.label(text="Lock to Object:")
col.prop(view, "lock_object", text="")
- if view.lock_object and view.lock_object.type == 'ARMATURE':
- col.prop_search(view, "lock_bone", view.lock_object.data, "bones", text="")
- elif not view.lock_object:
+ lock_object = view.lock_object
+ if lock_object:
+ if lock_object.type == 'ARMATURE':
+ col.prop_search(view, "lock_bone", lock_object.data, "edit_bones" if lock_object.mode == 'EDIT' else "bones", text="")
+ else:
col.prop(view, "lock_cursor", text="Lock to Cursor")
col = layout.column()
@@ -2046,7 +2104,7 @@ class VIEW3D_PT_view3d_properties(bpy.types.Panel):
layout.column().prop(view, "cursor_location")
-class VIEW3D_PT_view3d_name(bpy.types.Panel):
+class VIEW3D_PT_view3d_name(Panel):
bl_space_type = 'VIEW_3D'
bl_region_type = 'UI'
bl_label = "Item"
@@ -2071,7 +2129,7 @@ class VIEW3D_PT_view3d_name(bpy.types.Panel):
row.prop(bone, "name", text="")
-class VIEW3D_PT_view3d_display(bpy.types.Panel):
+class VIEW3D_PT_view3d_display(Panel):
bl_space_type = 'VIEW_3D'
bl_region_type = 'UI'
bl_label = "Display"
@@ -2143,7 +2201,7 @@ class VIEW3D_PT_view3d_display(bpy.types.Panel):
row.prop(region, "use_box_clip")
-class VIEW3D_PT_view3d_meshdisplay(bpy.types.Panel):
+class VIEW3D_PT_view3d_meshdisplay(Panel):
bl_space_type = 'VIEW_3D'
bl_region_type = 'UI'
bl_label = "Mesh Display"
@@ -2180,7 +2238,7 @@ class VIEW3D_PT_view3d_meshdisplay(bpy.types.Panel):
col.prop(mesh, "show_extra_face_area")
-class VIEW3D_PT_view3d_curvedisplay(bpy.types.Panel):
+class VIEW3D_PT_view3d_curvedisplay(Panel):
bl_space_type = 'VIEW_3D'
bl_region_type = 'UI'
bl_label = "Curve Display"
@@ -2202,7 +2260,7 @@ class VIEW3D_PT_view3d_curvedisplay(bpy.types.Panel):
col.prop(context.scene.tool_settings, "normal_size", text="Normal Size")
-class VIEW3D_PT_background_image(bpy.types.Panel):
+class VIEW3D_PT_background_image(Panel):
bl_space_type = 'VIEW_3D'
bl_region_type = 'UI'
bl_label = "Background Images"
@@ -2255,7 +2313,7 @@ class VIEW3D_PT_background_image(bpy.types.Panel):
row.prop(bg, "offset_y", text="Y")
-class VIEW3D_PT_transform_orientations(bpy.types.Panel):
+class VIEW3D_PT_transform_orientations(Panel):
bl_space_type = 'VIEW_3D'
bl_region_type = 'UI'
bl_label = "Transform Orientations"
@@ -2283,7 +2341,7 @@ class VIEW3D_PT_transform_orientations(bpy.types.Panel):
col.operator("transform.delete_orientation", text="Delete")
-class VIEW3D_PT_etch_a_ton(bpy.types.Panel):
+class VIEW3D_PT_etch_a_ton(Panel):
bl_space_type = 'VIEW_3D'
bl_region_type = 'UI'
bl_label = "Skeleton Sketching"
@@ -2328,7 +2386,7 @@ class VIEW3D_PT_etch_a_ton(bpy.types.Panel):
col.operator("sketch.convert", text="Convert")
-class VIEW3D_PT_context_properties(bpy.types.Panel):
+class VIEW3D_PT_context_properties(Panel):
bl_space_type = 'VIEW_3D'
bl_region_type = 'UI'
bl_label = "Properties"
@@ -2358,7 +2416,7 @@ class VIEW3D_PT_context_properties(bpy.types.Panel):
def draw(self, context):
import rna_prop_ui
- member = __class__._active_context_member(context)
+ member = VIEW3D_PT_context_properties._active_context_member(context)
if member:
# Draw with no edit button
diff --git a/release/scripts/startup/bl_ui/space_view3d_toolbar.py b/release/scripts/startup/bl_ui/space_view3d_toolbar.py
index 503a1d806ac..aa26cb43eed 100644
--- a/release/scripts/startup/bl_ui/space_view3d_toolbar.py
+++ b/release/scripts/startup/bl_ui/space_view3d_toolbar.py
@@ -18,6 +18,7 @@
# <pep8 compliant>
import bpy
+from bpy.types import Menu, Panel
class View3DPanel():
@@ -53,15 +54,18 @@ def draw_gpencil_tools(context, layout):
row = col.row()
row.operator("gpencil.draw", text="Draw").mode = 'DRAW'
row.operator("gpencil.draw", text="Line").mode = 'DRAW_STRAIGHT'
+
+ row = col.row()
+ row.operator("gpencil.draw", text="Poly").mode = 'DRAW_POLY'
row.operator("gpencil.draw", text="Erase").mode = 'ERASER'
row = col.row()
row.prop(context.tool_settings, "use_grease_pencil_sessions")
-# ********** default tools for objectmode ****************
+# ********** default tools for objectmode ****************
-class VIEW3D_PT_tools_objectmode(View3DPanel, bpy.types.Panel):
+class VIEW3D_PT_tools_objectmode(View3DPanel, Panel):
bl_context = "objectmode"
bl_label = "Object Tools"
@@ -88,8 +92,9 @@ class VIEW3D_PT_tools_objectmode(View3DPanel, bpy.types.Panel):
col = layout.column(align=True)
col.label(text="Shading:")
- col.operator("object.shade_smooth", text="Smooth")
- col.operator("object.shade_flat", text="Flat")
+ row = col.row(align=True)
+ row.operator("object.shade_smooth", text="Smooth")
+ row.operator("object.shade_flat", text="Flat")
draw_keyframing_tools(context, layout)
@@ -105,7 +110,7 @@ class VIEW3D_PT_tools_objectmode(View3DPanel, bpy.types.Panel):
# ********** default tools for editmode_mesh ****************
-class VIEW3D_PT_tools_meshedit(View3DPanel, bpy.types.Panel):
+class VIEW3D_PT_tools_meshedit(View3DPanel, Panel):
bl_context = "mesh_edit"
bl_label = "Mesh Tools"
@@ -117,7 +122,8 @@ class VIEW3D_PT_tools_meshedit(View3DPanel, bpy.types.Panel):
col.operator("transform.translate")
col.operator("transform.rotate")
col.operator("transform.resize", text="Scale")
- col.operator("transform.shrink_fatten", text="Along Normal")
+ col.operator("transform.shrink_fatten", text="Shrink/Fatten")
+ col.operator("transform.push_pull", text="Push/Pull")
col = layout.column(align=True)
col.label(text="Deform:")
@@ -154,15 +160,16 @@ class VIEW3D_PT_tools_meshedit(View3DPanel, bpy.types.Panel):
col = layout.column(align=True)
col.label(text="Shading:")
- col.operator("mesh.faces_shade_smooth", text="Smooth")
- col.operator("mesh.faces_shade_flat", text="Flat")
+ row = col.row(align=True)
+ row.operator("mesh.faces_shade_smooth", text="Smooth")
+ row.operator("mesh.faces_shade_flat", text="Flat")
draw_repeat_tools(context, layout)
draw_gpencil_tools(context, layout)
-class VIEW3D_PT_tools_meshedit_options(View3DPanel, bpy.types.Panel):
+class VIEW3D_PT_tools_meshedit_options(View3DPanel, Panel):
bl_context = "mesh_edit"
bl_label = "Mesh Options"
@@ -188,7 +195,7 @@ class VIEW3D_PT_tools_meshedit_options(View3DPanel, bpy.types.Panel):
# ********** default tools for editmode_curve ****************
-class VIEW3D_PT_tools_curveedit(View3DPanel, bpy.types.Panel):
+class VIEW3D_PT_tools_curveedit(View3DPanel, Panel):
bl_context = "curve_edit"
bl_label = "Curve Tools"
@@ -234,7 +241,7 @@ class VIEW3D_PT_tools_curveedit(View3DPanel, bpy.types.Panel):
# ********** default tools for editmode_surface ****************
-class VIEW3D_PT_tools_surfaceedit(View3DPanel, bpy.types.Panel):
+class VIEW3D_PT_tools_surfaceedit(View3DPanel, Panel):
bl_context = "surface_edit"
bl_label = "Surface Tools"
@@ -266,7 +273,7 @@ class VIEW3D_PT_tools_surfaceedit(View3DPanel, bpy.types.Panel):
# ********** default tools for editmode_text ****************
-class VIEW3D_PT_tools_textedit(View3DPanel, bpy.types.Panel):
+class VIEW3D_PT_tools_textedit(View3DPanel, Panel):
bl_context = "text_edit"
bl_label = "Text Tools"
@@ -296,7 +303,7 @@ class VIEW3D_PT_tools_textedit(View3DPanel, bpy.types.Panel):
# ********** default tools for editmode_armature ****************
-class VIEW3D_PT_tools_armatureedit(View3DPanel, bpy.types.Panel):
+class VIEW3D_PT_tools_armatureedit(View3DPanel, Panel):
bl_context = "armature_edit"
bl_label = "Armature Tools"
@@ -325,7 +332,7 @@ class VIEW3D_PT_tools_armatureedit(View3DPanel, bpy.types.Panel):
draw_gpencil_tools(context, layout)
-class VIEW3D_PT_tools_armatureedit_options(View3DPanel, bpy.types.Panel):
+class VIEW3D_PT_tools_armatureedit_options(View3DPanel, Panel):
bl_context = "armature_edit"
bl_label = "Armature Options"
@@ -337,7 +344,7 @@ class VIEW3D_PT_tools_armatureedit_options(View3DPanel, bpy.types.Panel):
# ********** default tools for editmode_mball ****************
-class VIEW3D_PT_tools_mballedit(View3DPanel, bpy.types.Panel):
+class VIEW3D_PT_tools_mballedit(View3DPanel, Panel):
bl_context = "mball_edit"
bl_label = "Meta Tools"
@@ -357,7 +364,7 @@ class VIEW3D_PT_tools_mballedit(View3DPanel, bpy.types.Panel):
# ********** default tools for editmode_lattice ****************
-class VIEW3D_PT_tools_latticeedit(View3DPanel, bpy.types.Panel):
+class VIEW3D_PT_tools_latticeedit(View3DPanel, Panel):
bl_context = "lattice_edit"
bl_label = "Lattice Tools"
@@ -381,7 +388,7 @@ class VIEW3D_PT_tools_latticeedit(View3DPanel, bpy.types.Panel):
# ********** default tools for posemode ****************
-class VIEW3D_PT_tools_posemode(View3DPanel, bpy.types.Panel):
+class VIEW3D_PT_tools_posemode(View3DPanel, Panel):
bl_context = "posemode"
bl_label = "Pose Tools"
@@ -422,7 +429,7 @@ class VIEW3D_PT_tools_posemode(View3DPanel, bpy.types.Panel):
draw_gpencil_tools(context, layout)
-class VIEW3D_PT_tools_posemode_options(View3DPanel, bpy.types.Panel):
+class VIEW3D_PT_tools_posemode_options(View3DPanel, Panel):
bl_context = "posemode"
bl_label = "Pose Options"
@@ -456,7 +463,7 @@ class PaintPanel():
return None
-class VIEW3D_PT_tools_brush(PaintPanel, bpy.types.Panel):
+class VIEW3D_PT_tools_brush(PaintPanel, Panel):
bl_label = "Brush"
@classmethod
@@ -466,7 +473,7 @@ class VIEW3D_PT_tools_brush(PaintPanel, bpy.types.Panel):
def draw(self, context):
layout = self.layout
- settings = __class__.paint_settings(context)
+ settings = self.paint_settings(context)
brush = settings.brush
if not context.particle_edit_object:
@@ -674,7 +681,7 @@ class VIEW3D_PT_tools_brush(PaintPanel, bpy.types.Panel):
#row.prop(brush, "use_pressure_jitter", toggle=True, text="")
-class VIEW3D_PT_tools_brush_texture(PaintPanel, bpy.types.Panel):
+class VIEW3D_PT_tools_brush_texture(PaintPanel, Panel):
bl_label = "Texture"
bl_options = {'DEFAULT_CLOSED'}
@@ -687,7 +694,7 @@ class VIEW3D_PT_tools_brush_texture(PaintPanel, bpy.types.Panel):
def draw(self, context):
layout = self.layout
- settings = __class__.paint_settings(context)
+ settings = self.paint_settings(context)
brush = settings.brush
tex_slot = brush.texture_slot
@@ -772,7 +779,7 @@ class VIEW3D_PT_tools_brush_texture(PaintPanel, bpy.types.Panel):
col.active = tex_slot.map_mode in {'FIXED', 'TILED'} and brush.use_texture_overlay
-class VIEW3D_PT_tools_brush_tool(PaintPanel, bpy.types.Panel):
+class VIEW3D_PT_tools_brush_tool(PaintPanel, Panel):
bl_label = "Tool"
bl_options = {'DEFAULT_CLOSED'}
@@ -786,7 +793,7 @@ class VIEW3D_PT_tools_brush_tool(PaintPanel, bpy.types.Panel):
def draw(self, context):
layout = self.layout
- settings = __class__.paint_settings(context)
+ settings = self.paint_settings(context)
brush = settings.brush
col = layout.column(align=True)
@@ -806,7 +813,7 @@ class VIEW3D_PT_tools_brush_tool(PaintPanel, bpy.types.Panel):
row.prop(brush, "use_paint_image", text="", icon='TPAINT_HLT')
-class VIEW3D_PT_tools_brush_stroke(PaintPanel, bpy.types.Panel):
+class VIEW3D_PT_tools_brush_stroke(PaintPanel, Panel):
bl_label = "Stroke"
bl_options = {'DEFAULT_CLOSED'}
@@ -821,7 +828,7 @@ class VIEW3D_PT_tools_brush_stroke(PaintPanel, bpy.types.Panel):
def draw(self, context):
layout = self.layout
- settings = __class__.paint_settings(context)
+ settings = self.paint_settings(context)
brush = settings.brush
image_paint = context.image_paint_object
@@ -904,7 +911,7 @@ class VIEW3D_PT_tools_brush_stroke(PaintPanel, bpy.types.Panel):
# row.prop(brush, "use_pressure_spacing", toggle=True, text="")
-class VIEW3D_PT_tools_brush_curve(PaintPanel, bpy.types.Panel):
+class VIEW3D_PT_tools_brush_curve(PaintPanel, Panel):
bl_label = "Curve"
bl_options = {'DEFAULT_CLOSED'}
@@ -931,7 +938,7 @@ class VIEW3D_PT_tools_brush_curve(PaintPanel, bpy.types.Panel):
row.operator("brush.curve_preset", icon="NOCURVE", text="").shape = 'MAX'
-class VIEW3D_PT_sculpt_options(PaintPanel, bpy.types.Panel):
+class VIEW3D_PT_sculpt_options(PaintPanel, Panel):
bl_label = "Options"
bl_options = {'DEFAULT_CLOSED'}
@@ -944,7 +951,6 @@ class VIEW3D_PT_sculpt_options(PaintPanel, bpy.types.Panel):
tool_settings = context.tool_settings
sculpt = tool_settings.sculpt
- settings = __class__.paint_settings(context)
layout.label(text="Lock:")
row = layout.row(align=True)
@@ -962,7 +968,7 @@ class VIEW3D_PT_sculpt_options(PaintPanel, bpy.types.Panel):
layout.prop(tool_settings, "sculpt_paint_use_unified_strength", text="Strength")
-class VIEW3D_PT_sculpt_symmetry(PaintPanel, bpy.types.Panel):
+class VIEW3D_PT_sculpt_symmetry(PaintPanel, Panel):
bl_label = "Symmetry"
bl_options = {'DEFAULT_CLOSED'}
@@ -974,7 +980,6 @@ class VIEW3D_PT_sculpt_symmetry(PaintPanel, bpy.types.Panel):
layout = self.layout
sculpt = context.tool_settings.sculpt
- settings = __class__.paint_settings(context)
split = layout.split()
@@ -991,20 +996,28 @@ class VIEW3D_PT_sculpt_symmetry(PaintPanel, bpy.types.Panel):
layout.prop(sculpt, "use_symmetry_feather", text="Feather")
-class VIEW3D_PT_tools_brush_appearance(PaintPanel, bpy.types.Panel):
+class VIEW3D_PT_tools_brush_appearance(PaintPanel, Panel):
bl_label = "Appearance"
bl_options = {'DEFAULT_CLOSED'}
@classmethod
def poll(cls, context):
- return (context.sculpt_object and context.tool_settings.sculpt) or (context.vertex_paint_object and context.tool_settings.vertex_paint) or (context.weight_paint_object and context.tool_settings.weight_paint) or (context.image_paint_object and context.tool_settings.image_paint)
+ ts = context.tool_settings
+ return ((context.sculpt_object and ts.sculpt) or
+ (context.vertex_paint_object and ts.vertex_paint) or
+ (context.weight_paint_object and ts.weight_paint) or
+ (context.image_paint_object and ts.image_paint))
def draw(self, context):
layout = self.layout
- settings = __class__.paint_settings(context)
+ settings = self.paint_settings(context)
brush = settings.brush
+ if brush is None: # unlikely but can happen
+ layout.label(text="Brush Unset")
+ return
+
col = layout.column()
if context.sculpt_object and context.tool_settings.sculpt:
@@ -1029,7 +1042,7 @@ class VIEW3D_PT_tools_brush_appearance(PaintPanel, bpy.types.Panel):
# ********** default tools for weightpaint ****************
-class VIEW3D_PT_tools_weightpaint(View3DPanel, bpy.types.Panel):
+class VIEW3D_PT_tools_weightpaint(View3DPanel, Panel):
bl_context = "weightpaint"
bl_label = "Weight Tools"
@@ -1039,7 +1052,7 @@ class VIEW3D_PT_tools_weightpaint(View3DPanel, bpy.types.Panel):
ob = context.active_object
col = layout.column()
- col.active = ob.vertex_groups.active != None
+ col.active = ob.vertex_groups.active is not None
col.operator("object.vertex_group_normalize_all", text="Normalize All")
col.operator("object.vertex_group_normalize", text="Normalize")
col.operator("object.vertex_group_invert", text="Invert")
@@ -1047,7 +1060,7 @@ class VIEW3D_PT_tools_weightpaint(View3DPanel, bpy.types.Panel):
col.operator("object.vertex_group_levels", text="Levels")
-class VIEW3D_PT_tools_weightpaint_options(View3DPanel, bpy.types.Panel):
+class VIEW3D_PT_tools_weightpaint_options(View3DPanel, Panel):
bl_context = "weightpaint"
bl_label = "Options"
@@ -1084,7 +1097,7 @@ class VIEW3D_PT_tools_weightpaint_options(View3DPanel, bpy.types.Panel):
# ********** default tools for vertexpaint ****************
-class VIEW3D_PT_tools_vertexpaint(View3DPanel, bpy.types.Panel):
+class VIEW3D_PT_tools_vertexpaint(View3DPanel, Panel):
bl_context = "vertexpaint"
bl_label = "Options"
@@ -1113,7 +1126,7 @@ class VIEW3D_PT_tools_vertexpaint(View3DPanel, bpy.types.Panel):
# ********** default tools for texturepaint ****************
-class VIEW3D_PT_tools_projectpaint(View3DPanel, bpy.types.Panel):
+class VIEW3D_PT_tools_projectpaint(View3DPanel, Panel):
bl_context = "imagepaint"
bl_label = "Project Paint"
@@ -1205,7 +1218,7 @@ class VIEW3D_PT_imagepaint_options(PaintPanel):
col.prop(tool_settings, "sculpt_paint_use_unified_strength", text="Strength")
-class VIEW3D_MT_tools_projectpaint_clone(bpy.types.Menu):
+class VIEW3D_MT_tools_projectpaint_clone(Menu):
bl_label = "Clone Layer"
def draw(self, context):
@@ -1216,7 +1229,7 @@ class VIEW3D_MT_tools_projectpaint_clone(bpy.types.Menu):
prop.value = i
-class VIEW3D_MT_tools_projectpaint_stencil(bpy.types.Menu):
+class VIEW3D_MT_tools_projectpaint_stencil(Menu):
bl_label = "Mask Layer"
def draw(self, context):
@@ -1227,7 +1240,7 @@ class VIEW3D_MT_tools_projectpaint_stencil(bpy.types.Menu):
prop.value = i
-class VIEW3D_PT_tools_particlemode(View3DPanel, bpy.types.Panel):
+class VIEW3D_PT_tools_particlemode(View3DPanel, Panel):
'''default tools for particle mode'''
bl_context = "particlemode"
bl_label = "Options"
diff --git a/release/scripts/startup/keyingsets_builtins.py b/release/scripts/startup/keyingsets_builtins.py
index 8cb63ea48cf..6b12c95e072 100644
--- a/release/scripts/startup/keyingsets_builtins.py
+++ b/release/scripts/startup/keyingsets_builtins.py
@@ -32,13 +32,14 @@ in lost (i.e. unkeyed) animation.
import bpy
import keyingsets_utils
+from bpy.types import KeyingSetInfo
###############################
# Built-In KeyingSets
# Location
-class BUILTIN_KSI_Location(bpy.types.KeyingSetInfo):
+class BUILTIN_KSI_Location(KeyingSetInfo):
bl_label = "Location"
# poll - use predefined callback for selected bones/objects
@@ -52,7 +53,7 @@ class BUILTIN_KSI_Location(bpy.types.KeyingSetInfo):
# Rotation
-class BUILTIN_KSI_Rotation(bpy.types.KeyingSetInfo):
+class BUILTIN_KSI_Rotation(KeyingSetInfo):
bl_label = "Rotation"
# poll - use predefined callback for selected bones/objects
@@ -66,7 +67,7 @@ class BUILTIN_KSI_Rotation(bpy.types.KeyingSetInfo):
# Scale
-class BUILTIN_KSI_Scaling(bpy.types.KeyingSetInfo):
+class BUILTIN_KSI_Scaling(KeyingSetInfo):
bl_label = "Scaling"
# poll - use predefined callback for selected bones/objects
@@ -82,7 +83,7 @@ class BUILTIN_KSI_Scaling(bpy.types.KeyingSetInfo):
# LocRot
-class BUILTIN_KSI_LocRot(bpy.types.KeyingSetInfo):
+class BUILTIN_KSI_LocRot(KeyingSetInfo):
bl_label = "LocRot"
# poll - use predefined callback for selected bones/objects
@@ -100,7 +101,7 @@ class BUILTIN_KSI_LocRot(bpy.types.KeyingSetInfo):
# LocScale
-class BUILTIN_KSI_LocScale(bpy.types.KeyingSetInfo):
+class BUILTIN_KSI_LocScale(KeyingSetInfo):
bl_label = "LocScale"
# poll - use predefined callback for selected bones/objects
@@ -118,7 +119,7 @@ class BUILTIN_KSI_LocScale(bpy.types.KeyingSetInfo):
# LocRotScale
-class BUILTIN_KSI_LocRotScale(bpy.types.KeyingSetInfo):
+class BUILTIN_KSI_LocRotScale(KeyingSetInfo):
bl_label = "LocRotScale"
# poll - use predefined callback for selected bones/objects
@@ -138,7 +139,7 @@ class BUILTIN_KSI_LocRotScale(bpy.types.KeyingSetInfo):
# RotScale
-class BUILTIN_KSI_RotScale(bpy.types.KeyingSetInfo):
+class BUILTIN_KSI_RotScale(KeyingSetInfo):
bl_label = "RotScale"
# poll - use predefined callback for selected bones/objects
@@ -158,7 +159,7 @@ class BUILTIN_KSI_RotScale(bpy.types.KeyingSetInfo):
# Location
-class BUILTIN_KSI_VisualLoc(bpy.types.KeyingSetInfo):
+class BUILTIN_KSI_VisualLoc(KeyingSetInfo):
bl_label = "Visual Location"
bl_options = {'INSERTKEY_VISUAL'}
@@ -174,7 +175,7 @@ class BUILTIN_KSI_VisualLoc(bpy.types.KeyingSetInfo):
# Rotation
-class BUILTIN_KSI_VisualRot(bpy.types.KeyingSetInfo):
+class BUILTIN_KSI_VisualRot(KeyingSetInfo):
bl_label = "Visual Rotation"
bl_options = {'INSERTKEY_VISUAL'}
@@ -190,7 +191,7 @@ class BUILTIN_KSI_VisualRot(bpy.types.KeyingSetInfo):
# VisualLocRot
-class BUILTIN_KSI_VisualLocRot(bpy.types.KeyingSetInfo):
+class BUILTIN_KSI_VisualLocRot(KeyingSetInfo):
bl_label = "Visual LocRot"
bl_options = {'INSERTKEY_VISUAL'}
@@ -212,7 +213,7 @@ class BUILTIN_KSI_VisualLocRot(bpy.types.KeyingSetInfo):
# Available
-class BUILTIN_KSI_Available(bpy.types.KeyingSetInfo):
+class BUILTIN_KSI_Available(KeyingSetInfo):
bl_label = "Available"
# poll - selected objects or selected object with animation data
@@ -234,7 +235,7 @@ class BUILTIN_KSI_Available(bpy.types.KeyingSetInfo):
# All properties that are likely to get animated in a character rig
-class BUILTIN_KSI_WholeCharacter(bpy.types.KeyingSetInfo):
+class BUILTIN_KSI_WholeCharacter(KeyingSetInfo):
bl_label = "Whole Character"
# these prefixes should be avoided, as they are not really bones
@@ -265,7 +266,7 @@ class BUILTIN_KSI_WholeCharacter(bpy.types.KeyingSetInfo):
# loc, rot, scale - only include unlocked ones
ksi.doLoc(ks, bone)
- if bone.rotation_mode in ('QUATERNION', 'AXIS_ANGLE'):
+ if bone.rotation_mode in {'QUATERNION', 'AXIS_ANGLE'}:
ksi.doRot4d(ks, bone)
else:
ksi.doRot3d(ks, bone)
@@ -365,7 +366,7 @@ class BUILTIN_KSI_WholeCharacter(bpy.types.KeyingSetInfo):
# Delta Location
-class BUILTIN_KSI_DeltaLocation(bpy.types.KeyingSetInfo):
+class BUILTIN_KSI_DeltaLocation(KeyingSetInfo):
bl_label = "Delta Location"
# poll - selected objects only (and only if active object in object mode)
@@ -390,7 +391,7 @@ class BUILTIN_KSI_DeltaLocation(bpy.types.KeyingSetInfo):
# Delta Rotation
-class BUILTIN_KSI_DeltaRotation(bpy.types.KeyingSetInfo):
+class BUILTIN_KSI_DeltaRotation(KeyingSetInfo):
bl_label = "Delta Rotation"
# poll - selected objects only (and only if active object in object mode)
@@ -407,7 +408,7 @@ class BUILTIN_KSI_DeltaRotation(bpy.types.KeyingSetInfo):
# add the property name to the base path
# rotation mode affects the property used
if data.rotation_mode == 'QUATERNION':
- path = path_add_property(base_path, "delta_rotation_quaternion")
+ path = keyingsets_utils.path_add_property(base_path, "delta_rotation_quaternion")
elif data.rotation_mode == 'AXIS_ANGLE':
# XXX: for now, this is not available yet
#path = path_add_property(base_path, "delta_rotation_axis_angle")
@@ -423,7 +424,7 @@ class BUILTIN_KSI_DeltaRotation(bpy.types.KeyingSetInfo):
# Delta Scale
-class BUILTIN_KSI_DeltaScale(bpy.types.KeyingSetInfo):
+class BUILTIN_KSI_DeltaScale(KeyingSetInfo):
bl_label = "Delta Scale"
# poll - selected objects only (and only if active object in object mode)
diff --git a/release/scripts/templates/addon_add_object.py b/release/scripts/templates/addon_add_object.py
index 67e033271f4..833ac600995 100644
--- a/release/scripts/templates/addon_add_object.py
+++ b/release/scripts/templates/addon_add_object.py
@@ -35,7 +35,7 @@ def add_object(self, context):
mesh.from_pydata(verts, edges, faces)
# useful for development when the mesh may be invalid.
# mesh.validate(verbose=True)
- add_object_data(context, mesh_data, operator=self)
+ add_object_data(context, mesh, operator=self)
class OBJECT_OT_add_object(bpy.types.Operator, AddObjectHelper):
@@ -45,10 +45,12 @@ class OBJECT_OT_add_object(bpy.types.Operator, AddObjectHelper):
bl_description = "Create a new Mesh Object"
bl_options = {'REGISTER', 'UNDO'}
- scale = FloatVectorProperty(name='scale',
- default=(1.0, 1.0, 1.0),
- subtype='TRANSLATION',
- description='scaling')
+ scale = FloatVectorProperty(
+ name='scale',
+ default=(1.0, 1.0, 1.0),
+ subtype='TRANSLATION',
+ description='scaling',
+ )
def execute(self, context):
diff --git a/release/scripts/templates/batch_export.py b/release/scripts/templates/batch_export.py
new file mode 100644
index 00000000000..45d26f4b525
--- /dev/null
+++ b/release/scripts/templates/batch_export.py
@@ -0,0 +1,33 @@
+# exports each selected object into its own file
+
+import bpy
+import os
+
+# export to blend file location
+basedir = os.path.dirname(bpy.data.filepath)
+
+if not basedir:
+ raise Exception("Blend file is not saved")
+
+selection = bpy.context.selected_objects
+
+bpy.ops.object.select_all(action='DESELECT')
+
+for obj in selection:
+
+ obj.select = True
+
+ name = bpy.path.clean_name(obj.name)
+ fn = os.path.join(basedir, name)
+
+ bpy.ops.export_scene.fbx(filepath=fn + ".fbx", use_selection=True)
+
+ ## Can be used for multiple formats
+ # bpy.ops.export_scene.x3d(filepath=fn + ".x3d", use_selection=True)
+
+ obj.select = False
+
+ print("written:", fn)
+
+for obj in selection:
+ obj.select = True
diff --git a/release/scripts/templates/operator_export.py b/release/scripts/templates/operator_export.py
index 4cf943a53b7..b1d53e6ee0c 100644
--- a/release/scripts/templates/operator_export.py
+++ b/release/scripts/templates/operator_export.py
@@ -24,22 +24,30 @@ class ExportSomeData(bpy.types.Operator, ExportHelper):
# ExportHelper mixin class uses this
filename_ext = ".txt"
- filter_glob = StringProperty(default="*.txt", options={'HIDDEN'})
+ filter_glob = StringProperty(
+ default="*.txt",
+ options={'HIDDEN'},
+ )
# List of operator properties, the attributes will be assigned
# to the class instance from the operator settings before calling.
- use_setting = BoolProperty(name="Example Boolean", description="Example Tooltip", default=True)
-
- type = EnumProperty(items=(('OPT_A', "First Option", "Description one"),
- ('OPT_B', "Second Option", "Description two."),
- ),
- name="Example Enum",
- description="Choose between two items",
- default='OPT_A')
+ use_setting = BoolProperty(
+ name="Example Boolean",
+ description="Example Tooltip",
+ default=True,
+ )
+
+ type = EnumProperty(
+ name="Example Enum",
+ description="Choose between two items",
+ items=(('OPT_A', "First Option", "Description one"),
+ ('OPT_B', "Second Option", "Description two.")),
+ default='OPT_A',
+ )
@classmethod
def poll(cls, context):
- return context.active_object != None
+ return context.active_object is not None
def execute(self, context):
return write_some_data(context, self.filepath, self.use_setting)
diff --git a/release/scripts/templates/operator_mesh_add.py b/release/scripts/templates/operator_mesh_add.py
index 10d23a6712d..d89b7e82f77 100644
--- a/release/scripts/templates/operator_mesh_add.py
+++ b/release/scripts/templates/operator_mesh_add.py
@@ -43,25 +43,38 @@ class AddBox(bpy.types.Operator):
bl_label = "Add Box"
bl_options = {'REGISTER', 'UNDO'}
- width = FloatProperty(name="Width",
+ width = FloatProperty(
+ name="Width",
description="Box Width",
- default=1.0, min=0.01, max=100.0)
-
- height = FloatProperty(name="Height",
+ min=0.01, max=100.0,
+ default=1.0,
+ )
+ height = FloatProperty(
+ name="Height",
description="Box Height",
- default=1.0, min=0.01, max=100.0)
-
- depth = FloatProperty(name="Depth",
+ min=0.01, max=100.0,
+ default=1.0,
+ )
+ depth = FloatProperty(
+ name="Depth",
description="Box Depth",
- default=1.0, min=0.01, max=100.0)
+ min=0.01, max=100.0,
+ default=1.0,
+ )
# generic transform props
- view_align = BoolProperty(name="Align to View",
- default=False)
- location = FloatVectorProperty(name="Location",
- subtype='TRANSLATION')
- rotation = FloatVectorProperty(name="Rotation",
- subtype='EULER')
+ view_align = BoolProperty(
+ name="Align to View",
+ default=False,
+ )
+ location = FloatVectorProperty(
+ name="Location",
+ subtype='TRANSLATION',
+ )
+ rotation = FloatVectorProperty(
+ name="Rotation",
+ subtype='EULER',
+ )
def execute(self, context):
diff --git a/release/scripts/templates/operator_modal.py b/release/scripts/templates/operator_modal.py
index 78dbd4c6b43..a428b097f82 100644
--- a/release/scripts/templates/operator_modal.py
+++ b/release/scripts/templates/operator_modal.py
@@ -18,7 +18,7 @@ class ModalOperator(bpy.types.Operator):
elif event.type == 'LEFTMOUSE':
return {'FINISHED'}
- elif event.type in ('RIGHTMOUSE', 'ESC'):
+ elif event.type in {'RIGHTMOUSE', 'ESC'}:
context.object.location.x = self.first_value
return {'CANCELLED'}
@@ -47,4 +47,4 @@ if __name__ == "__main__":
register()
# test call
- bpy.ops.object.modal_operator()
+ bpy.ops.object.modal_operator('INVOKE_DEFAULT')
diff --git a/release/scripts/templates/operator_modal_draw.py b/release/scripts/templates/operator_modal_draw.py
index e7a1f6e4ffe..b3d525a59bf 100644
--- a/release/scripts/templates/operator_modal_draw.py
+++ b/release/scripts/templates/operator_modal_draw.py
@@ -45,7 +45,7 @@ class ModalDrawOperator(bpy.types.Operator):
context.region.callback_remove(self._handle)
return {'FINISHED'}
- elif event.type in ('RIGHTMOUSE', 'ESC'):
+ elif event.type in {'RIGHTMOUSE', 'ESC'}:
context.region.callback_remove(self._handle)
return {'CANCELLED'}
diff --git a/release/scripts/templates/operator_modal_timer.py b/release/scripts/templates/operator_modal_timer.py
index d2267191cf5..ec47390da81 100644
--- a/release/scripts/templates/operator_modal_timer.py
+++ b/release/scripts/templates/operator_modal_timer.py
@@ -10,7 +10,7 @@ class ModalTimerOperator(bpy.types.Operator):
def modal(self, context, event):
if event.type == 'ESC':
- return self.cancel()
+ return self.cancel(context)
if event.type == 'TIMER':
# change theme color, silly!
diff --git a/release/scripts/templates/operator_modal_view3d.py b/release/scripts/templates/operator_modal_view3d.py
index c494f121017..263bf72f129 100644
--- a/release/scripts/templates/operator_modal_view3d.py
+++ b/release/scripts/templates/operator_modal_view3d.py
@@ -8,7 +8,10 @@ class ViewOperator(bpy.types.Operator):
bl_idname = "view3d.modal_operator"
bl_label = "Simple View Operator"
- offset = FloatVectorProperty(name="Offset", size=3)
+ offset = FloatVectorProperty(
+ name="Offset",
+ size=3,
+ )
def execute(self, context):
v3d = context.space_data
@@ -29,7 +32,7 @@ class ViewOperator(bpy.types.Operator):
context.area.header_text_set()
return {'FINISHED'}
- elif event.type in ('RIGHTMOUSE', 'ESC'):
+ elif event.type in {'RIGHTMOUSE', 'ESC'}:
rv3d.view_location = self._initial_location
context.area.header_text_set()
return {'CANCELLED'}
diff --git a/release/scripts/templates/operator_simple.py b/release/scripts/templates/operator_simple.py
index 8348c7a95b1..05d9afc0ad1 100644
--- a/release/scripts/templates/operator_simple.py
+++ b/release/scripts/templates/operator_simple.py
@@ -13,7 +13,7 @@ class SimpleOperator(bpy.types.Operator):
@classmethod
def poll(cls, context):
- return context.active_object != None
+ return context.active_object is not None
def execute(self, context):
main(context)
diff --git a/release/scripts/templates/ui_menu.py b/release/scripts/templates/ui_menu.py
new file mode 100644
index 00000000000..d3c94b86809
--- /dev/null
+++ b/release/scripts/templates/ui_menu.py
@@ -0,0 +1,49 @@
+import bpy
+
+
+class CustomMenu(bpy.types.Menu):
+ bl_label = "Custom Menu"
+ bl_idname = "OBJECT_MT_custom_menu"
+
+ def draw(self, context):
+ layout = self.layout
+
+ layout.operator("wm.open_mainfile")
+ layout.operator("wm.save_as_mainfile").copy = True
+
+ layout.operator("object.shade_smooth")
+
+ layout.label(text="Hello world!", icon='WORLD_DATA')
+
+ # use an operator enum property to populate a submenu
+ layout.operator_menu_enum("object.select_by_type",
+ property="type",
+ text="Select All by Type...",
+ )
+
+ # call another menu
+ layout.operator("wm.call_menu", text="Unwrap").name = "VIEW3D_MT_uv_map"
+
+
+def draw_item(self, context):
+ layout = self.layout
+ layout.menu(CustomMenu.bl_idname)
+
+
+def register():
+ bpy.utils.register_class(CustomMenu)
+
+ # lets add ourselves to the main header
+ bpy.types.INFO_HT_header.append(draw_item)
+
+
+def unregister():
+ bpy.utils.unregister_class(CustomMenu)
+
+ bpy.types.INFO_HT_header.remove(draw_item)
+
+if __name__ == "__main__":
+ register()
+
+ # The menu can also be called from scripts
+ bpy.ops.wm.call_menu(name=CustomMenu.bl_idname)
diff --git a/release/scripts/templates/ui_menu_simple.py b/release/scripts/templates/ui_menu_simple.py
new file mode 100644
index 00000000000..2129dfd81a4
--- /dev/null
+++ b/release/scripts/templates/ui_menu_simple.py
@@ -0,0 +1,26 @@
+import bpy
+
+
+class SimpleCustomMenu(bpy.types.Menu):
+ bl_label = "Simple Custom Menu"
+ bl_idname = "OBJECT_MT_simple_custom_menu"
+
+ def draw(self, context):
+ layout = self.layout
+
+ layout.operator("wm.open_mainfile")
+ layout.operator("wm.save_as_mainfile")
+
+
+def register():
+ bpy.utils.register_class(SimpleCustomMenu)
+
+
+def unregister():
+ bpy.utils.unregister_class(SimpleCustomMenu)
+
+if __name__ == "__main__":
+ register()
+
+ # The menu can also be called from scripts
+ bpy.ops.wm.call_menu(name=SimpleCustomMenu.bl_idname)
diff --git a/release/scripts/templates/panel_simple.py b/release/scripts/templates/ui_panel_simple.py
index e5bf70cb654..cde6126b626 100644
--- a/release/scripts/templates/panel_simple.py
+++ b/release/scripts/templates/ui_panel_simple.py
@@ -1,8 +1,9 @@
import bpy
-class OBJECT_PT_hello(bpy.types.Panel):
+class HelloWorldPanel(bpy.types.Panel):
bl_label = "Hello World Panel"
+ bl_idname = "OBJECT_PT_hello"
bl_space_type = "PROPERTIES"
bl_region_type = "WINDOW"
bl_context = "object"
@@ -22,11 +23,11 @@ class OBJECT_PT_hello(bpy.types.Panel):
def register():
- bpy.utils.register_class(OBJECT_PT_hello)
+ bpy.utils.register_class(HelloWorldPanel)
def unregister():
- bpy.utils.unregister_class(OBJECT_PT_hello)
+ bpy.utils.unregister_class(HelloWorldPanel)
if __name__ == "__main__":
diff --git a/release/text/GPL-license.txt b/release/text/GPL-license.txt
index 8860b2a8afa..e8c0353e734 100644
--- a/release/text/GPL-license.txt
+++ b/release/text/GPL-license.txt
@@ -2,7 +2,7 @@
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
diff --git a/release/text/readme.html b/release/text/readme.html
index 1014d8ef80a..95094b9c0cb 100644
--- a/release/text/readme.html
+++ b/release/text/readme.html
@@ -12,22 +12,22 @@
</style>
</head>
<body>
-<p class="title"><b>Blender 2.57</b></p>
+<p class="title"><b>Blender 2.59</b></p>
<p><br></p>
<p class="header"><b>About</b></p>
<p class="body">Welcome to Blender, the free, open source 3D application for modeling, animation, rendering, compositing, video editing and game creation. Blender is available for Linux, Mac OS X, Windows, Solaris and FreeBSD and has a large world-wide community.</p>
<p class="body">Blender can be used freely for any purpose, including commercial use and distribution. It's free and open-source software, released under the GNU GPL licence. The entire source code is available on our website.</p>
<p class="body">For more information, visit <a href="http://www.blender.org">blender.org</a>.</p>
<p><br></p>
-<p class="header"><b>2.57</b></p>
-<p class="body">The Blender Foundation and online developer community is proud to present Blender 2.57. This release is the first official stable release of the Blender 2.5 series, and represents the culmination of many years of redesign and development work. <a href="http://www.blender.org/development/release-logs/blender-256-beta/">More information about this release</a>.</p>
+<p class="header"><b>2.59</b></p>
+<p class="body">The Blender Foundation and online developer community is proud to present Blender 2.59. This release is the third official stable release of the Blender 2.5 series, and represents the culmination of many years of redesign and development work. <a href="http://www.blender.org/development/release-logs/blender-259/">More information about this release</a>.</p>
<p class="body">What to Expect:</p>
<p class="body"> • Big improvements - This is our most exciting version to date, already a significant improvement in many ways over 2.49</p>
<p class="body"> • Missing/Incomplete Features - Although most of it is there, not all functionality from pre-2.5 versions has been restored yet. Some functionality may be re-implemented a different way.</p>
<p class="body"> • Changes - If you're used to the old Blenders, Blender 2.5 may seem quite different at first, but it won't be long before it grows on you even more than before.</p>
<p><br></p>
<p class="header"><b>Bugs</b></p>
-<p class="body">Although Blender 2.57 is considered a stable release, you may encounter a bug. If you do, please help us by posting it in the bug tracker or using Help → Report a Bug from inside Blender 2.57. If it wasn’t reported yet, please log in (or register) and fill in detailed information about the error. Please post detailed instructions on how to reproduce it or post a .blend file showcasing the bug.</p>
+<p class="body">Although Blender 2.59 is considered a stable release, you may encounter a bug. If you do, please help us by posting it in the bug tracker or using Help → Report a Bug from inside Blender 2.59. If it wasn’t reported yet, please log in (or register) and fill in detailed information about the error. Please post detailed instructions on how to reproduce it or post a .blend file showcasing the bug.</p>
<p><br></p>
<p class="header"><b>Package Contents</b></p>
<p class="body">The downloaded Blender package includes:</p>
@@ -51,11 +51,11 @@
<p class="header"><b>Links</b></p>
<p class="body">Users:</p>
<p class="body"> General information <a href="http://www.blender.org">www.blender.org</a> <br>
- Full release log <a href="http://www.blender.org/development/release-logs/blender-257/">www.blender.org/development/release-logs/blender-257/</a><br>
+ Full release log <a href="http://www.blender.org/development/release-logs/blender-259/">www.blender.org/development/release-logs/blender-259/</a><br>
Tutorials <a href="http://www.blender.org/education-help/">www.blender.org/education-help/</a> <br>
Manual <a href="http://wiki.blender.org/index.php/Doc:Manual">wiki.blender.org/index.php/Doc:Manual</a><br>
User Forum <a href="http://www.blenderartists.org">www.blenderartists.org</a><br>
- IRC <a href="irc://irc.freenode.net/#blender">#blender on irc.freenode.net</a><br>
+ IRC <a href="irc://irc.freenode.net/#blenderchat">#blenderchat on irc.freenode.net</a><br>
</p>
<p class="body">Developers:</p>
<p class="body"> Development <a href="http://www.blender.org/development/">www.blender.org/development/</a><br>