pep8 cleanup

This commit is contained in:
Campbell Barton 2011-02-04 09:27:25 +00:00
parent f0eb3b56de
commit 736a7b7a22
21 changed files with 328 additions and 234 deletions

@ -21,6 +21,8 @@
#
# ***** END GPL LICENSE BLOCK *****
# <pep8 compliant>
IGNORE = \
"/test/",\
"/decimate_glut_test/",\
@ -45,6 +47,8 @@ global_c = set()
import os
from os.path import splitext
def source_list(path, filename_check=None):
for dirpath, dirnames, filenames in os.walk(path):
@ -56,31 +60,37 @@ def source_list(path, filename_check=None):
if filename_check is None or filename_check(filename):
yield os.path.join(dirpath, filename)
# extension checking
def is_c_header(filename):
ext = splitext(filename)[1]
return (ext in (".h", ".hpp", ".hxx"))
def is_cmake(filename):
ext = splitext(filename)[1]
return (ext == ".cmake") or (filename == "CMakeLists.txt")
def is_c_header(filename):
ext = splitext(filename)[1]
return (ext in (".h", ".hpp", ".hxx"))
def is_c(filename):
ext = splitext(filename)[1]
return (ext in (".c", ".cpp", ".cxx", ".m", ".mm", ".rc"))
def is_c_any(filename):
return is_c(filename) or is_c_header(filename)
def cmake_get_src(f):
sources_h = []
sources_c = []
filen = open(f, "r", encoding="utf8")
it = iter(filen)
found = False
@ -101,7 +111,7 @@ def cmake_get_src(f):
raise Exception("strict formatting not kept 'set(SRC*' %s:%d" % (f, i))
found = True
break
if "list(APPEND SRC" in l:
if l.endswith(")"):
raise Exception("strict formatting not kept 'list(APPEND SRC...)' on 1 line %s:%d" % (f, i))
@ -118,11 +128,11 @@ def cmake_get_src(f):
except StopIteration:
it = None
break
l = l.strip()
if not l.startswith("#"):
if ")" in l:
if l.strip() != ")":
raise Exception("strict formatting not kept '*)' %s:%d" % (f, i))
@ -130,7 +140,6 @@ def cmake_get_src(f):
# replace dirs
l = l.replace("${CMAKE_CURRENT_SOURCE_DIR}", cmake_base)
if not l:
pass
@ -140,7 +149,7 @@ def cmake_get_src(f):
raise Exception("Multi-line define '%s' %s:%d" % (l, f, i))
else:
new_file = normpath(join(cmake_base, l))
if is_c_header(new_file):
sources_h.append(new_file)
elif is_c(new_file):
@ -168,19 +177,20 @@ def cmake_get_src(f):
if ff not in sources_c:
print(" missing: " + ff)
'''
filen.close()
for cmake in source_list(base, is_cmake):
cmake_get_src(cmake)
def is_ignore(f):
for ig in IGNORE:
if ig in f:
return True
return False
# First do stupid check, do these files exist?
for f in (global_h | global_c):
if f.endswith("dna.c"):
@ -189,7 +199,7 @@ for f in (global_h | global_c):
if not os.path.exists(f):
raise Exception("CMake referenced file missing: " + f)
# now check on files not accounted for.
print("\nC/C++ Files CMake doesnt know about...")
for cf in sorted(source_list(base, is_c)):

@ -21,6 +21,8 @@
#
# ***** END GPL LICENSE BLOCK *****
# <pep8 compliant>
import os
from os.path import join, dirname, normpath, abspath, splitext, relpath, exists
@ -28,6 +30,7 @@ base = join(os.path.dirname(__file__), "..", "..")
base = normpath(base)
base = abspath(base)
def source_list(path, filename_check=None):
for dirpath, dirnames, filenames in os.walk(path):
@ -40,33 +43,40 @@ def source_list(path, filename_check=None):
if filename_check is None or filename_check(filepath):
yield filepath
# extension checking
def is_c_header(filename):
ext = splitext(filename)[1]
return (ext in (".h", ".hpp", ".hxx"))
def is_cmake(filename):
ext = splitext(filename)[1]
return (ext == ".cmake") or (filename == "CMakeLists.txt")
def is_c_header(filename):
ext = splitext(filename)[1]
return (ext in (".h", ".hpp", ".hxx"))
def is_c(filename):
ext = splitext(filename)[1]
return (ext in (".c", ".cpp", ".cxx", ".m", ".mm", ".rc"))
def is_c_any(filename):
return is_c(filename) or is_c_header(filename)
def is_svn_file(filename):
dn, fn = os.path.split(filename)
filename_svn = join(dn, ".svn", "text-base", "%s.svn-base" % fn)
return exists(filename_svn)
dn, fn = os.path.split(filename)
filename_svn = join(dn, ".svn", "text-base", "%s.svn-base" % fn)
return exists(filename_svn)
def is_project_file(filename):
return (is_c_any(filename) or is_cmake(filename)) and is_svn_file(filename)
return (is_c_any(filename) or is_cmake(filename)) and is_svn_file(filename)
files = list(source_list(base, filename_check=is_project_file))
files_rel = [relpath(f, start=base) for f in files]
@ -87,8 +97,8 @@ f.write("[General]\n")
qtc_cfg = join(base, "%s.config" % PROJECT_NAME)
if not exists(qtc_cfg):
f = open(qtc_cfg, 'w')
f.write("// ADD PREDEFINED MACROS HERE!\n")
f = open(qtc_cfg, 'w')
f.write("// ADD PREDEFINED MACROS HERE!\n")
print("Project file written to: %s" % qtc_prj)
# --- end

@ -18,6 +18,8 @@
#
# #**** END GPL LICENSE BLOCK #****
# <pep8 compliant>
script_help_msg = '''
Usage:
@ -31,11 +33,11 @@ For HTML generation
assuming that ./blender.bin is or links to the blender executable
- Generate html docs by running...
sphinx-build doc/python_api/sphinx-in doc/python_api/sphinx-out
assuming that you have sphinx 0.6.7 installed
For PDF generation
------------------
- After you have built doc/python_api/sphinx-in (see above), run:
@ -81,10 +83,12 @@ def range_str(val):
Converts values to strings for the range directive.
(unused function it seems)
'''
if val < -10000000: return '-inf'
if val > 10000000: return 'inf'
if type(val)==float:
return '%g' % val
if val < -10000000:
return '-inf'
elif val > 10000000:
return 'inf'
elif type(val) == float:
return '%g' % val
else:
return str(val)
@ -139,7 +143,7 @@ def pyfunc2sphinx(ident, fw, identifier, py_func, is_class=True):
if not is_class:
func_type = "function"
# ther rest are class methods
elif arg_str.startswith("(self, "):
arg_str = "(" + arg_str[7:]
@ -156,14 +160,14 @@ def pyfunc2sphinx(ident, fw, identifier, py_func, is_class=True):
fw("\n")
def py_descr2sphinx(ident, fw, descr, module_name, type_name, identifier):
def py_descr2sphinx(ident, fw, descr, module_name, type_name, identifier):
if identifier.startswith("_"):
return
doc = descr.__doc__
if not doc:
doc = undocumented_message(module_name, type_name, identifier)
if type(descr) == GetSetDescriptorType:
fw(ident + ".. attribute:: %s\n\n" % identifier)
write_indented_lines(ident + " ", fw, doc, False)
@ -180,7 +184,7 @@ def py_c_func2sphinx(ident, fw, module_name, type_name, identifier, py_func, is_
'''
c defined function to sphinx.
'''
# dump the docstring, assume its formatted correctly
if py_func.__doc__:
write_indented_lines(ident, fw, py_func.__doc__, False)
@ -208,30 +212,30 @@ def pymodule2sphinx(BASEPATH, module_name, module, title):
import types
attribute_set = set()
filepath = os.path.join(BASEPATH, module_name + ".rst")
file = open(filepath, "w")
fw = file.write
fw(title + "\n")
fw(("=" * len(title)) + "\n\n")
fw(".. module:: %s\n\n" % module_name)
if module.__doc__:
# Note, may contain sphinx syntax, dont mangle!
fw(module.__doc__.strip())
fw("\n\n")
write_example_ref("", fw, module_name)
# write members of the module
# only tested with PyStructs which are not exactly modules
for key, descr in sorted(type(module).__dict__.items()):
if key.startswith("__"):
continue
# naughty, we also add getset's into PyStructs, this is not typical py but also not incorrect.
if type(descr) == types.GetSetDescriptorType: # 'bpy_app_type' name is only used for examples and messages
if type(descr) == types.GetSetDescriptorType: # 'bpy_app_type' name is only used for examples and messages
py_descr2sphinx("", fw, descr, module_name, "bpy_app_type", key)
attribute_set.add(key)
for key, descr in sorted(type(module).__dict__.items()):
@ -245,7 +249,7 @@ def pymodule2sphinx(BASEPATH, module_name, module, title):
attribute_set.add(key)
fw("\n")
del key, descr
classes = []
for attribute in sorted(dir(module)):
@ -254,16 +258,16 @@ def pymodule2sphinx(BASEPATH, module_name, module, title):
if attribute in attribute_set:
continue
if attribute.startswith("n_"): # annoying exception, needed for bpy.app
if attribute.startswith("n_"): # annoying exception, needed for bpy.app
continue
value = getattr(module, attribute)
value_type = type(value)
if value_type == types.FunctionType:
pyfunc2sphinx("", fw, attribute, value, is_class=False)
elif value_type in (types.BuiltinMethodType, types.BuiltinFunctionType): # both the same at the moment but to be future proof
elif value_type in (types.BuiltinMethodType, types.BuiltinFunctionType): # both the same at the moment but to be future proof
# note: can't get args from these, so dump the string as is
# this means any module used like this must have fully formatted docstrings.
py_c_func2sphinx("", fw, module_name, module, attribute, value, is_class=False)
@ -310,7 +314,6 @@ def pymodule2sphinx(BASEPATH, module_name, module, title):
file.close()
def rna2sphinx(BASEPATH):
structs, funcs, ops, props = rna_info.BuildRNAInfo()
@ -325,14 +328,13 @@ def rna2sphinx(BASEPATH):
file = open(filepath, "w")
fw = file.write
version_string = bpy.app.version_string.split("(")[0]
if bpy.app.build_revision != "Unknown":
version_string = version_string + " r" + bpy.app.build_revision
# for use with files
version_string_fp = "_".join(str(v) for v in bpy.app.version)
fw("project = 'Blender'\n")
# fw("master_doc = 'index'\n")
fw("copyright = u'Blender Foundation'\n")
@ -349,11 +351,11 @@ def rna2sphinx(BASEPATH):
fw("latex_paper_size = 'a4paper'\n")
file.close()
# main page needed for sphinx (index.html)
filepath = os.path.join(BASEPATH, "contents.rst")
file = open(filepath, "w")
fw = file.write
fw("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n")
fw(" Blender Documentation contents\n")
fw("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n")
@ -388,15 +390,15 @@ def rna2sphinx(BASEPATH):
fw("\n")
fw(".. toctree::\n")
fw(" :maxdepth: 1\n\n")
fw(" bpy.data.rst\n\n") # note: not actually a module
fw(" bpy.data.rst\n\n") # note: not actually a module
fw(" bpy.ops.rst\n\n")
fw(" bpy.types.rst\n\n")
# py modules
fw(" bpy.utils.rst\n\n")
fw(" bpy.path.rst\n\n")
fw(" bpy.app.rst\n\n")
# C modules
fw(" bpy.props.rst\n\n")
@ -407,14 +409,13 @@ def rna2sphinx(BASEPATH):
fw(".. toctree::\n")
fw(" :maxdepth: 1\n\n")
fw(" mathutils.rst\n\n")
fw(" mathutils.geometry.rst\n\n")
# XXX TODO
#fw(" bgl.rst\n\n")
fw(" blf.rst\n\n")
fw(" aud.rst\n\n")
# game engine
fw("===================\n")
fw("Game Engine Modules\n")
@ -429,7 +430,6 @@ def rna2sphinx(BASEPATH):
file.close()
# internal modules
filepath = os.path.join(BASEPATH, "bpy.ops.rst")
file = open(filepath, "w")
@ -451,7 +451,6 @@ def rna2sphinx(BASEPATH):
fw(" bpy.types.*\n\n")
file.close()
# not actually a module, only write this file so we
# can reference in the TOC
filepath = os.path.join(BASEPATH, "bpy.data.rst")
@ -474,7 +473,6 @@ def rna2sphinx(BASEPATH):
EXAMPLE_SET_USED.add("bpy.data")
# python modules
from bpy import utils as module
pymodule2sphinx(BASEPATH, "bpy.utils", module, "Utilities (bpy.utils)")
@ -488,11 +486,11 @@ def rna2sphinx(BASEPATH):
from bpy import props as module
pymodule2sphinx(BASEPATH, "bpy.props", module, "Property Definitions (bpy.props)")
import mathutils as module
pymodule2sphinx(BASEPATH, "mathutils", module, "Math Types & Utilities (mathutils)")
del module
import mathutils.geometry as module
pymodule2sphinx(BASEPATH, "mathutils.geometry", module, "Geometry Utilities (mathutils.geometry)")
del module
@ -500,7 +498,7 @@ def rna2sphinx(BASEPATH):
import blf as module
pymodule2sphinx(BASEPATH, "blf", module, "Font Drawing (blf)")
del module
# XXX TODO
#import bgl as module
#pymodule2sphinx(BASEPATH, "bgl", module, "Blender OpenGl wrapper (bgl)")
@ -513,17 +511,16 @@ def rna2sphinx(BASEPATH):
## game engine
import shutil
# copy2 keeps time/date stamps
shutil.copy2(os.path.join(BASEPATH,"..","rst","bge.types.rst"), BASEPATH)
shutil.copy2(os.path.join(BASEPATH,"..","rst","bge.logic.rst"), BASEPATH)
shutil.copy2(os.path.join(BASEPATH,"..","rst","bge.render.rst"), BASEPATH)
shutil.copy2(os.path.join(BASEPATH,"..","rst","bge.events.rst"), BASEPATH)
shutil.copy2(os.path.join(BASEPATH, "..", "rst", "bge.types.rst"), BASEPATH)
shutil.copy2(os.path.join(BASEPATH, "..", "rst", "bge.logic.rst"), BASEPATH)
shutil.copy2(os.path.join(BASEPATH, "..", "rst", "bge.render.rst"), BASEPATH)
shutil.copy2(os.path.join(BASEPATH, "..", "rst", "bge.events.rst"), BASEPATH)
if 0:
filepath = os.path.join(BASEPATH, "bpy.rst")
file = open(filepath, "w")
fw = file.write
fw("\n")
title = ":mod:`bpy` --- Blender Python Module"
@ -558,7 +555,7 @@ def rna2sphinx(BASEPATH):
filepath = os.path.join(BASEPATH, "bpy.types.%s.rst" % struct.identifier)
file = open(filepath, "w")
fw = file.write
base_id = getattr(struct.base, "identifier", "")
if _BPY_STRUCT_FAKE:
@ -571,16 +568,16 @@ def rna2sphinx(BASEPATH):
title = struct.identifier
fw("%s\n%s\n\n" % (title, "=" * len(title)))
fw(".. module:: bpy.types\n\n")
base_ids = [base.identifier for base in struct.get_bases()]
if _BPY_STRUCT_FAKE:
base_ids.append(_BPY_STRUCT_FAKE)
base_ids.reverse()
if base_ids:
if len(base_ids) > 1:
fw("base classes --- ")
@ -589,13 +586,13 @@ def rna2sphinx(BASEPATH):
fw(", ".join((":class:`%s`" % base_id) for base_id in base_ids))
fw("\n\n")
subclass_ids = [s.identifier for s in structs.values() if s.base is struct if not rna_info.rna_id_ignore(s.identifier)]
if subclass_ids:
fw("subclasses --- \n" + ", ".join((":class:`%s`" % s) for s in subclass_ids) + "\n\n")
base_id = getattr(struct.base, "identifier", "")
if _BPY_STRUCT_FAKE:
if not base_id:
base_id = _BPY_STRUCT_FAKE
@ -606,7 +603,7 @@ def rna2sphinx(BASEPATH):
fw(".. class:: %s\n\n" % struct.identifier)
fw(" %s\n\n" % struct.description)
# properties sorted in alphabetical order
sorted_struct_properties = struct.properties[:]
sorted_struct_properties.sort(key=lambda prop: prop.identifier)
@ -621,7 +618,7 @@ def rna2sphinx(BASEPATH):
if prop.description:
fw(" %s\n\n" % prop.description)
fw(" :type: %s\n\n" % type_descr)
# python attributes
py_properties = struct.get_py_properties()
py_prop = None
@ -634,13 +631,13 @@ def rna2sphinx(BASEPATH):
fw(" .. %s:: %s(%s)\n\n" % ("classmethod" if func.is_classmethod else "method", func.identifier, args_str))
fw(" %s\n\n" % func.description)
for prop in func.args:
write_param(" ", fw, prop)
if len(func.return_values) == 1:
write_param(" ", fw, func.return_values[0], is_return=True)
elif func.return_values: # multiple return values
elif func.return_values: # multiple return values
fw(" :return (%s):\n" % ", ".join(prop.identifier for prop in func.return_values))
for prop in func.return_values:
type_descr = prop.get_type_description(as_ret=True, class_fmt=":class:`%s`")
@ -651,11 +648,10 @@ def rna2sphinx(BASEPATH):
fw("\n")
# python methods
py_funcs = struct.get_py_functions()
py_func = None
for identifier, py_func in py_funcs:
pyfunc2sphinx(" ", fw, identifier, py_func, is_class=True)
del py_funcs, py_func
@ -667,10 +663,10 @@ def rna2sphinx(BASEPATH):
# props
lines[:] = []
if _BPY_STRUCT_FAKE:
descr_items = [(key, descr) for key, descr in sorted(bpy.types.Struct.__bases__[0].__dict__.items()) if not key.startswith("__")]
if _BPY_STRUCT_FAKE:
for key, descr in descr_items:
if type(descr) == GetSetDescriptorType:
@ -682,10 +678,10 @@ def rna2sphinx(BASEPATH):
for identifier, py_prop in base.get_py_properties():
lines.append(" * :class:`%s.%s`\n" % (base.identifier, identifier))
for identifier, py_prop in base.get_py_properties():
lines.append(" * :class:`%s.%s`\n" % (base.identifier, identifier))
if lines:
fw(".. rubric:: Inherited Properties\n\n")
@ -696,7 +692,6 @@ def rna2sphinx(BASEPATH):
fw(line)
fw("\n")
# funcs
lines[:] = []
@ -720,9 +715,8 @@ def rna2sphinx(BASEPATH):
for line in lines:
fw(line)
fw("\n")
lines[:] = []
lines[:] = []
if struct.references:
# use this otherwise it gets in the index for a normal heading.
@ -738,13 +732,12 @@ def rna2sphinx(BASEPATH):
fw(" * :class:`%s`\n" % ref)
fw("\n")
for struct in structs.values():
# TODO, rna_info should filter these out!
if "_OT_" in struct.identifier:
continue
write_struct(struct)
# special case, bpy_struct
if _BPY_STRUCT_FAKE:
filepath = os.path.join(BASEPATH, "bpy.types.%s.rst" % _BPY_STRUCT_FAKE)
@ -769,41 +762,40 @@ def rna2sphinx(BASEPATH):
descr_items = [(key, descr) for key, descr in sorted(bpy.types.Struct.__bases__[0].__dict__.items()) if not key.startswith("__")]
for key, descr in descr_items:
if type(descr) == MethodDescriptorType: # GetSetDescriptorType, GetSetDescriptorType's are not documented yet
if type(descr) == MethodDescriptorType: # GetSetDescriptorType, GetSetDescriptorType's are not documented yet
py_descr2sphinx(" ", fw, descr, "bpy.types", _BPY_STRUCT_FAKE, key)
for key, descr in descr_items:
if type(descr) == GetSetDescriptorType:
py_descr2sphinx(" ", fw, descr, "bpy.types", _BPY_STRUCT_FAKE, key)
# operators
def write_ops():
API_BASEURL='https://svn.blender.org/svnroot/bf-blender/trunk/blender/release/scripts'
API_BASEURL = "https://svn.blender.org/svnroot/bf-blender/trunk/blender/release/scripts"
fw = None
last_mod = ''
for op_key in sorted(ops.keys()):
op = ops[op_key]
if last_mod != op.module_name:
filepath = os.path.join(BASEPATH, "bpy.ops.%s.rst" % op.module_name)
file = open(filepath, "w")
fw = file.write
title = "%s Operators" % (op.module_name[0].upper() + op.module_name[1:])
title = "%s Operators" % (op.module_name[0].upper() + op.module_name[1:])
fw("%s\n%s\n\n" % (title, "=" * len(title)))
fw(".. module:: bpy.ops.%s\n\n" % op.module_name)
last_mod = op.module_name
args_str = ", ".join(prop.get_arg_default(force=True) for prop in op.args)
fw(".. function:: %s(%s)\n\n" % (op.func_name, args_str))
# if the description isn't valid, we output the standard warning
# if the description isn't valid, we output the standard warning
# with a link to the wiki so that people can help
if not op.description or op.description == "(undocumented operator)":
operator_description = undocumented_message('bpy.ops',op.module_name,op.func_name)
operator_description = undocumented_message('bpy.ops', op.module_name, op.func_name)
else:
operator_description = op.description
@ -815,12 +807,13 @@ def rna2sphinx(BASEPATH):
location = op.get_location()
if location != (None, None):
fw(" :file: `%s <%s/%s>`_:%d\n\n" % (location[0],API_BASEURL,location[0],location[1]))
fw(" :file: `%s <%s/%s>`_:%d\n\n" % (location[0], API_BASEURL, location[0], location[1]))
write_ops()
file.close()
def main():
import bpy
if 'bpy' not in dir():
@ -830,9 +823,9 @@ def main():
import shutil
script_dir = os.path.dirname(__file__)
path_in = os.path.join(script_dir,'sphinx-in')
path_out = os.path.join(script_dir,'sphinx-out')
path_examples = os.path.join(script_dir,'examples')
path_in = os.path.join(script_dir, "sphinx-in")
path_out = os.path.join(script_dir, "sphinx-out")
path_examples = os.path.join(script_dir, "examples")
# only for partial updates
path_in_tmp = path_in + "-tmp"
@ -843,7 +836,6 @@ def main():
if f.endswith(".py"):
EXAMPLE_SET.add(os.path.splitext(f)[0])
# only for full updates
if _BPY_FULL_REBUILD:
shutil.rmtree(path_in, True)
@ -860,7 +852,7 @@ def main():
# now move changed files from 'path_in_tmp' --> 'path_in'
file_list_path_in = set(os.listdir(path_in))
file_list_path_in_tmp = set(os.listdir(path_in_tmp))
# remove deprecated files that have been removed.
for f in sorted(file_list_path_in):
if f not in file_list_path_in_tmp:
@ -876,14 +868,13 @@ def main():
if f in file_list_path_in:
if filecmp.cmp(f_from, f_to):
do_copy = False
if do_copy:
print("\tupdating: %s" % f)
shutil.copy(f_from, f_to)
'''else:
print("\tkeeping: %s" % f) # eh, not that useful'''
EXAMPLE_SET_UNUSED = EXAMPLE_SET - EXAMPLE_SET_USED
if EXAMPLE_SET_UNUSED:
print("\nUnused examples found in '%s'..." % path_examples)

@ -18,6 +18,8 @@
#
# ##### END GPL LICENSE BLOCK #####
# <pep8 compliant>
"""
Thumbnailer runs with python 2.6 and 3.x.
To run automatically with nautilus:

@ -1,7 +1,29 @@
# Built-In Keying Sets
# None of these Keying Sets should be removed, as these
# are needed by various parts of Blender in order for them
# to work correctly.
# ##### 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>
"""
Built-In Keying Sets
None of these Keying Sets should be removed, as these
are needed by various parts of Blender in order for them
to work correctly.
"""
import bpy
from keyingsets_utils import *
@ -9,6 +31,7 @@ from keyingsets_utils import *
###############################
# Built-In KeyingSets
# Location
class BUILTIN_KSI_Location(bpy.types.KeyingSetInfo):
bl_label = "Location"
@ -19,9 +42,10 @@ class BUILTIN_KSI_Location(bpy.types.KeyingSetInfo):
# iterator - use callback for selected bones/objects
iterator = RKS_ITER_selected_item
# generator - use callback for location
# generator - use callback for location
generate = RKS_GEN_location
# Rotation
class BUILTIN_KSI_Rotation(bpy.types.KeyingSetInfo):
bl_label = "Rotation"
@ -32,9 +56,10 @@ class BUILTIN_KSI_Rotation(bpy.types.KeyingSetInfo):
# iterator - use callback for selected bones/objects
iterator = RKS_ITER_selected_item
# generator - use callback for location
# generator - use callback for location
generate = RKS_GEN_rotation
# Scale
class BUILTIN_KSI_Scaling(bpy.types.KeyingSetInfo):
bl_label = "Scaling"
@ -45,11 +70,12 @@ class BUILTIN_KSI_Scaling(bpy.types.KeyingSetInfo):
# iterator - use callback for selected bones/objects
iterator = RKS_ITER_selected_item
# generator - use callback for location
# generator - use callback for location
generate = RKS_GEN_scaling
# ------------
# LocRot
class BUILTIN_KSI_LocRot(bpy.types.KeyingSetInfo):
bl_label = "LocRot"
@ -60,13 +86,14 @@ class BUILTIN_KSI_LocRot(bpy.types.KeyingSetInfo):
# iterator - use callback for selected bones/objects
iterator = RKS_ITER_selected_item
# generator
# generator
def generate(self, context, ks, data):
# location
RKS_GEN_location(self, context, ks, data)
# rotation
RKS_GEN_rotation(self, context, ks, data)
# LocScale
class BUILTIN_KSI_LocScale(bpy.types.KeyingSetInfo):
bl_label = "LocScale"
@ -77,13 +104,14 @@ class BUILTIN_KSI_LocScale(bpy.types.KeyingSetInfo):
# iterator - use callback for selected bones/objects
iterator = RKS_ITER_selected_item
# generator
# generator
def generate(self, context, ks, data):
# location
RKS_GEN_location(self, context, ks, data)
# scale
RKS_GEN_scaling(self, context, ks, data)
# LocRotScale
class BUILTIN_KSI_LocRotScale(bpy.types.KeyingSetInfo):
bl_label = "LocRotScale"
@ -94,7 +122,7 @@ class BUILTIN_KSI_LocRotScale(bpy.types.KeyingSetInfo):
# iterator - use callback for selected bones/objects
iterator = RKS_ITER_selected_item
# generator
# generator
def generate(self, context, ks, data):
# location
RKS_GEN_location(self, context, ks, data)
@ -103,6 +131,7 @@ class BUILTIN_KSI_LocRotScale(bpy.types.KeyingSetInfo):
# scale
RKS_GEN_scaling(self, context, ks, data)
# RotScale
class BUILTIN_KSI_RotScale(bpy.types.KeyingSetInfo):
bl_label = "RotScale"
@ -113,15 +142,16 @@ class BUILTIN_KSI_RotScale(bpy.types.KeyingSetInfo):
# iterator - use callback for selected bones/objects
iterator = RKS_ITER_selected_item
# generator
# generator
def generate(self, context, ks, data):
# rotation
RKS_GEN_rotation(self, context, ks, data)
# scaling
RKS_GEN_scaling(self, context, ks, data)
# ------------
# Location
class BUILTIN_KSI_VisualLoc(bpy.types.KeyingSetInfo):
bl_label = "Visual Location"
@ -134,9 +164,10 @@ class BUILTIN_KSI_VisualLoc(bpy.types.KeyingSetInfo):
# iterator - use callback for selected bones/objects
iterator = RKS_ITER_selected_item
# generator - use callback for location
# generator - use callback for location
generate = RKS_GEN_location
# Rotation
class BUILTIN_KSI_VisualRot(bpy.types.KeyingSetInfo):
bl_label = "Visual Rotation"
@ -149,9 +180,10 @@ class BUILTIN_KSI_VisualRot(bpy.types.KeyingSetInfo):
# iterator - use callback for selected bones/objects
iterator = RKS_ITER_selected_item
# generator - use callback for rotation
# generator - use callback for rotation
generate = RKS_GEN_rotation
# VisualLocRot
class BUILTIN_KSI_VisualLocRot(bpy.types.KeyingSetInfo):
bl_label = "Visual LocRot"
@ -164,7 +196,7 @@ class BUILTIN_KSI_VisualLocRot(bpy.types.KeyingSetInfo):
# iterator - use callback for selected bones/objects
iterator = RKS_ITER_selected_item
# generator
# generator
def generate(self, context, ks, data):
# location
RKS_GEN_location(self, context, ks, data)
@ -173,39 +205,41 @@ class BUILTIN_KSI_VisualLocRot(bpy.types.KeyingSetInfo):
# ------------
# Available
class BUILTIN_KSI_Available(bpy.types.KeyingSetInfo):
bl_label = "Available"
# poll - use predefined callback for selected objects
# TODO: this should really check whether the selected object (or datablock)
# TODO: this should really check whether the selected object (or datablock)
# has any animation data defined yet
poll = RKS_POLL_selected_objects
# iterator - use callback for selected bones/objects
iterator = RKS_ITER_selected_item
# generator - use callback for doing this
# generator - use callback for doing this
generate = RKS_GEN_available
###############################
###############################
# All properties that are likely to get animated in a character rig
class BUILTIN_KSI_WholeCharacter(bpy.types.KeyingSetInfo):
bl_label = "Whole Character"
# these prefixes should be avoided, as they are not really bones
# that animators should be touching (or need to touch)
badBonePrefixes = (
'DEF',
'GEO',
'MCH',
'DEF',
'GEO',
'MCH',
'ORG',
'COR',
'VIS',
# ... more can be added here as you need in your own rigs ...
)
# poll - pose-mode on active object only
def poll(ksi, context):
return ((context.active_object) and (context.active_object.pose) and
@ -221,39 +255,39 @@ class BUILTIN_KSI_WholeCharacter(bpy.types.KeyingSetInfo):
def generate(ksi, context, ks, bone):
# loc, rot, scale - only include unlocked ones
ksi.doLoc(ks, bone)
if bone.rotation_mode in ('QUATERNION', 'AXIS_ANGLE'):
ksi.doRot4d(ks, bone)
else:
ksi.doRot3d(ks, bone)
ksi.doScale(ks, bone)
# custom props?
ksi.doCustomProps(ks, bone)
# ----------------
# helper to add some bone's property to the Keying Set
def addProp(ksi, ks, bone, prop, index=-1, use_groups=True):
def addProp(ksi, ks, bone, prop, index=-1, use_groups=True):
# add the property name to the base path
id_path = bone.path_from_id()
id_block = bone.id_data
if prop.startswith('['):
if prop.startswith('['):
# custom properties
path = id_path + prop
else:
else:
# standard transforms/properties
path = path_add_property(id_path, prop)
# add Keying Set entry for this...
if use_groups:
ks.paths.add(id_block, path, index, group_method='NAMED', group_name=bone.name)
else:
ks.paths.add(id_block, path, index)
# ----------------
# location properties
def doLoc(ksi, ks, bone):
if bone.lock_location == (False, False, False):
@ -262,7 +296,7 @@ class BUILTIN_KSI_WholeCharacter(bpy.types.KeyingSetInfo):
for i in range(3):
if not bone.lock_location[i]:
ksi.addProp(ks, bone, "location", i)
# rotation properties
def doRot4d(ksi, ks, bone):
# rotation mode affects the property used
@ -270,7 +304,7 @@ class BUILTIN_KSI_WholeCharacter(bpy.types.KeyingSetInfo):
prop = "rotation_quaternion"
elif bone.rotation_mode == 'AXIS_ANGLE':
prop = "rotation_axis_angle"
# add rotation properties if they will
if bone.lock_rotations_4d:
# can check individually
@ -278,16 +312,16 @@ class BUILTIN_KSI_WholeCharacter(bpy.types.KeyingSetInfo):
ksi.addProp(ks, bone, prop)
else:
if bone.lock_rotation_w == False:
ksi.addProp(ks, bone, prop, 0) # w = 0
ksi.addProp(ks, bone, prop, 0) # w = 0
for i in range(3):
if not bone.lock_rotation[i]:
ksi.addProp(ks, bone, prop, i+1) # i+1, since here x,y,z = 1,2,3, and w=0
ksi.addProp(ks, bone, prop, i + 1) # i + 1, since here x,y,z = 1,2,3, and w=0
elif True not in bone.lock_rotation:
# if axis-angle rotations get locked as eulers, then it's too messy to allow anything
# if axis-angle rotations get locked as eulers, then it's too messy to allow anything
# other than all open unless we keyframe the whole lot
ksi.addProp(ks, bone, prop)
def doRot3d(ksi, ks, bone):
if bone.lock_rotation == (False, False, False):
ksi.addProp(ks, bone, "rotation_euler")
@ -295,30 +329,30 @@ class BUILTIN_KSI_WholeCharacter(bpy.types.KeyingSetInfo):
for i in range(3):
if not bone.lock_rotation[i]:
ksi.addProp(ks, bone, "rotation_euler", i)
# scale properties
def doScale(ksi, ks, bone):
if bone.lock_scale == (0,0,0):
if bone.lock_scale == (0, 0, 0):
ksi.addProp(ks, bone, "scale")
else:
for i in range(3):
if not bone.lock_scale[i]:
ksi.addProp(ks, bone, "scale", i)
# ----------------
# custom properties
def doCustomProps(ksi, ks, bone):
# go over all custom properties for bone
for prop,val in bone.items():
for prop, val in bone.items():
# ignore special "_RNA_UI" used for UI editing
if prop == "_RNA_UI":
continue
# for now, just add all of 'em
ksi.addProp(ks, bone, '["%s"]' % (prop))
###############################
###############################
classes = [
BUILTIN_KSI_Location,
@ -329,7 +363,7 @@ classes = [
BUILTIN_KSI_LocScale,
BUILTIN_KSI_LocRotScale,
BUILTIN_KSI_RotScale,
BUILTIN_KSI_WholeCharacter,
BUILTIN_KSI_VisualLoc,
@ -354,4 +388,4 @@ def unregister():
if __name__ == "__main__":
register()
###############################
###############################

@ -1,45 +1,51 @@
# This file defines a set of methods that are useful for various
# 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.
# for polling, iterator callbacks, and also generate callbacks.
# All of these can be used in conjunction with the others.
# <pep8 compliant>
import bpy
###########################
# General Utilities
# Append the specified property name on the the existing path
def path_add_property(path, prop):
if len(path):
return path + "." + prop;
return path + "." + prop
else:
return prop;
return prop
###########################
# Poll Callbacks
# selected objects
def RKS_POLL_selected_objects(ksi, context):
return context.active_object or len(context.selected_objects);
return context.active_object or len(context.selected_objects)
# selected bones
def RKS_POLL_selected_bones(ksi, context):
# we must be in Pose Mode, and there must be some bones selected
# we must be in Pose Mode, and there must be some bones selected
if (context.active_object) and (context.active_object.mode == 'POSE'):
if context.active_pose_bone or len(context.selected_pose_bones):
return True;
# nothing selected
return False;
return True
# nothing selected
return False
# 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
# all selected objects or pose bones, depending on which we've got
def RKS_ITER_selected_item(ksi, context, ks):
if (context.active_object) and (context.active_object.mode == 'POSE'):
@ -52,25 +58,26 @@ def RKS_ITER_selected_item(ksi, context, ks):
###########################
# Generate Callbacks
# 'Available' F-Curves
def RKS_GEN_available(ksi, context, ks, data):
# try to get the animation data associated with the closest
# try to get the animation data associated with the closest
# ID-block to the data (neither of which may exist/be easy to find)
id_block = data.id_data
adt = getattr(id_block, "animation_data", None)
# there must also be an active action...
if adt is None or adt.action is None:
return;
# if we haven't got an ID-block as 'data', try to restrict
return
# if we haven't got an ID-block as 'data', try to restrict
# paths added to only those which branch off from here
# i.e. for bones
if id_block != data:
basePath = data.path_from_id()
else:
basePath = None; # this is not needed...
basePath = None # this is not needed...
# for each F-Curve, include a path to key it
# NOTE: we don't need to set the group settings here
for fcu in adt.action.fcurves:
@ -79,19 +86,20 @@ def RKS_GEN_available(ksi, context, ks, data):
ks.paths.add(id_block, fcu.data_path, index=fcu.array_index)
else:
ks.paths.add(id_block, fcu.data_path, index=fcu.array_index)
# ------
# get ID block and based ID path for transform generators
def get_transform_generators_base_info(data):
# ID-block for the data
# ID-block for the data
id_block = data.id_data
# get base path and grouping method/name
if isinstance(data, bpy.types.ID):
# no path in this case
path = ""
# data on ID-blocks directly should get grouped by the KeyingSet
grouping = None
else:
@ -101,29 +109,31 @@ def get_transform_generators_base_info(data):
# try to use the name of the data element to group the F-Curve
# else fallback on the KeyingSet name
grouping = getattr(data, "name", None)
# return the ID-block and the path
return id_block, path, grouping
# Location
# Location
def RKS_GEN_location(ksi, context, ks, data):
# get id-block and path info
id_block, base_path, grouping = get_transform_generators_base_info(data)
# add the property name to the base path
path = path_add_property(base_path, "location")
# add Keying Set entry for this...
if grouping:
ks.paths.add(id_block, path, group_method='NAMED', group_name=grouping)
else:
ks.paths.add(id_block, path)
# Rotation
# Rotation
def RKS_GEN_rotation(ksi, context, ks, data):
# get id-block and path info
id_block, base_path, grouping= get_transform_generators_base_info(data)
id_block, base_path, grouping = get_transform_generators_base_info(data)
# add the property name to the base path
# rotation mode affects the property used
if data.rotation_mode == 'QUATERNION':
@ -132,21 +142,22 @@ def RKS_GEN_rotation(ksi, context, ks, data):
path = path_add_property(base_path, "rotation_axis_angle")
else:
path = path_add_property(base_path, "rotation_euler")
# add Keying Set entry for this...
if grouping:
ks.paths.add(id_block, path, group_method='NAMED', group_name=grouping)
else:
ks.paths.add(id_block, path)
# Scaling
# Scaling
def RKS_GEN_scaling(ksi, context, ks, data):
# get id-block and path info
id_block, base_path, grouping= get_transform_generators_base_info(data)
id_block, base_path, grouping = get_transform_generators_base_info(data)
# add the property name to the base path
path = path_add_property(base_path, "scale")
# add Keying Set entry for this...
if grouping:
ks.paths.add(id_block, path, group_method='NAMED', group_name=grouping)
@ -158,6 +169,7 @@ def RKS_GEN_scaling(ksi, context, ks, data):
classes = []
def register():
pass

@ -1,7 +1,28 @@
# ##### 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>
from math import *
import bpy
from mathutils import *
def main(context):
def cleanupEulCurve(fcv):
keys = []
@ -12,37 +33,38 @@ def main(context):
for i in range(len(keys)):
cur = keys[i]
prev = keys[i-1] if i > 0 else None
next = keys[i+1] if i < len(keys)-1 else None
prev = keys[i - 1] if i > 0 else None
next = keys[i + 1] if i < len(keys) - 1 else None
if prev is None:
continue
th = pi
if abs(prev[1][1] - cur[1][1]) >= th: # more than 180 degree jump
fac = pi*2
if abs(prev[1][1] - cur[1][1]) >= th: # more than 180 degree jump
fac = pi * 2.0
if prev[1][1] > cur[1][1]:
while abs(cur[1][1]-prev[1][1]) >= th: # < prev[1][1]:
while abs(cur[1][1] - prev[1][1]) >= th: # < prev[1][1]:
cur[0][1] += fac
cur[1][1] += fac
cur[2][1] += fac
elif prev[1][1] < cur[1][1]:
while abs(cur[1][1]-prev[1][1]) >= th:
while abs(cur[1][1] - prev[1][1]) >= th:
cur[0][1] -= fac
cur[1][1] -= fac
cur[2][1] -= fac
for i in range(len(keys)):
for x in range(2):
fcv.keyframe_points[i].handle_left[x] = keys[i][0][x]
fcv.keyframe_points[i].co[x] = keys[i][1][x]
fcv.keyframe_points[i].handle_right[x] = keys[i][2][x]
fcv.keyframe_points[i].handle_left[x] = keys[i][0][x]
fcv.keyframe_points[i].co[x] = keys[i][1][x]
fcv.keyframe_points[i].handle_right[x] = keys[i][2][x]
flist = bpy.context.active_object.animation_data.action.fcurves
for f in flist:
if f.select and f.data_path.endswith("rotation_euler"):
cleanupEulCurve(f)
class DiscontFilterOp(bpy.types.Operator):
"""Fixes the most common causes of gimbal lock in the fcurves of the active bone"""
bl_idname = "graph.euler_filter"
@ -56,9 +78,11 @@ class DiscontFilterOp(bpy.types.Operator):
main(context)
return {'FINISHED'}
def register():
pass
def unregister():
pass

@ -14,7 +14,7 @@ else:
bpy.context.scene.render.ffmpeg_video_bitrate = 6000
bpy.context.scene.render.ffmpeg_maxrate = 9000
bpy.context.scene.render.ffmpeg_minrate = 0
bpy.context.scene.render.ffmpeg_buffersize = 224*8
bpy.context.scene.render.ffmpeg_buffersize = 224 * 8
bpy.context.scene.render.ffmpeg_packetsize = 2048
bpy.context.scene.render.ffmpeg_muxrate = 10080000

@ -14,7 +14,7 @@ else:
bpy.context.scene.render.ffmpeg_video_bitrate = 2040
bpy.context.scene.render.ffmpeg_maxrate = 2516
bpy.context.scene.render.ffmpeg_minrate = 0
bpy.context.scene.render.ffmpeg_buffersize = 224*8
bpy.context.scene.render.ffmpeg_buffersize = 224 * 8
bpy.context.scene.render.ffmpeg_packetsize = 2324
bpy.context.scene.render.ffmpeg_muxrate = 0

@ -14,7 +14,7 @@ else:
bpy.context.scene.render.ffmpeg_video_bitrate = 1150
bpy.context.scene.render.ffmpeg_maxrate = 1150
bpy.context.scene.render.ffmpeg_minrate = 1150
bpy.context.scene.render.ffmpeg_buffersize = 40*8
bpy.context.scene.render.ffmpeg_buffersize = 40 * 8
bpy.context.scene.render.ffmpeg_packetsize = 2324
bpy.context.scene.render.ffmpeg_muxrate = 2352 * 75 * 8

@ -12,6 +12,6 @@ else:
bpy.context.scene.render.ffmpeg_video_bitrate = 6000
bpy.context.scene.render.ffmpeg_maxrate = 9000
bpy.context.scene.render.ffmpeg_minrate = 0
bpy.context.scene.render.ffmpeg_buffersize = 224*8
bpy.context.scene.render.ffmpeg_buffersize = 224 * 8
bpy.context.scene.render.ffmpeg_packetsize = 2048
bpy.context.scene.render.ffmpeg_muxrate = 10080000

@ -12,6 +12,6 @@ else:
bpy.context.scene.render.ffmpeg_video_bitrate = 6000
bpy.context.scene.render.ffmpeg_maxrate = 9000
bpy.context.scene.render.ffmpeg_minrate = 0
bpy.context.scene.render.ffmpeg_buffersize = 224*8
bpy.context.scene.render.ffmpeg_buffersize = 224 * 8
bpy.context.scene.render.ffmpeg_packetsize = 2048
bpy.context.scene.render.ffmpeg_muxrate = 10080000

@ -12,6 +12,6 @@ else:
bpy.context.scene.render.ffmpeg_video_bitrate = 6000
bpy.context.scene.render.ffmpeg_maxrate = 9000
bpy.context.scene.render.ffmpeg_minrate = 0
bpy.context.scene.render.ffmpeg_buffersize = 224*8
bpy.context.scene.render.ffmpeg_buffersize = 224 * 8
bpy.context.scene.render.ffmpeg_packetsize = 2048
bpy.context.scene.render.ffmpeg_muxrate = 10080000

@ -1,5 +1,5 @@
import bpy
material = (bpy.context.material.active_node_material if bpy.context.material.active_node_material else bpy.context.material)
material.subsurface_scattering.radius = 11.605, 3.884, 1.754
material.subsurface_scattering.color = 0.430, 0.210, 0.168

@ -20,6 +20,7 @@
import bpy
class PhysicButtonsPanel():
bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW'
@ -29,7 +30,8 @@ class PhysicButtonsPanel():
def poll(cls, context):
rd = context.scene.render
return (context.object) and (not rd.use_game_engine)
def physics_add(self, layout, md, name, type, typeicon, toggles):
sub = layout.row(align=True)
if md:
@ -41,35 +43,36 @@ def physics_add(self, layout, md, name, type, typeicon, toggles):
else:
sub.operator("object.modifier_add", text=name, icon=typeicon).type = type
class PHYSICS_PT_add(PhysicButtonsPanel, bpy.types.Panel):
bl_label = ""
bl_options = {'HIDE_HEADER'}
def draw(self, context):
ob = context.object
layout = self.layout
layout.label("Enable physics for:")
split = layout.split()
col = split.column()
if(context.object.field.type == 'NONE'):
col.operator("object.forcefield_toggle", text="Force Field", icon='FORCE_FORCE')
else:
col.operator("object.forcefield_toggle", text="Force Field", icon='X')
if(ob.type == 'MESH'):
physics_add(self, col, context.collision, "Collision", 'COLLISION', 'MOD_PHYSICS', False);
physics_add(self, col, context.cloth, "Cloth", 'CLOTH', 'MOD_CLOTH', True);
physics_add(self, col, context.collision, "Collision", 'COLLISION', 'MOD_PHYSICS', False)
physics_add(self, col, context.cloth, "Cloth", 'CLOTH', 'MOD_CLOTH', True)
col = split.column()
if(ob.type == 'MESH' or ob.type == 'LATTICE'or ob.type == 'CURVE'):
physics_add(self, col, context.soft_body, "Soft Body", 'SOFT_BODY', 'MOD_SOFT', True);
physics_add(self, col, context.soft_body, "Soft Body", 'SOFT_BODY', 'MOD_SOFT', True)
if(ob.type == 'MESH'):
physics_add(self, col, context.fluid, "Fluid", 'FLUID_SIMULATION', 'MOD_FLUIDSIM', True);
physics_add(self, col, context.smoke, "Smoke", 'SMOKE', 'MOD_SMOKE', True);
physics_add(self, col, context.fluid, "Fluid", 'FLUID_SIMULATION', 'MOD_FLUIDSIM', True)
physics_add(self, col, context.smoke, "Smoke", 'SMOKE', 'MOD_SMOKE', True)
#cachetype can be 'PSYS' 'HAIR' 'SMOKE' etc

@ -37,7 +37,7 @@ class PhysicButtonsPanel():
class PHYSICS_PT_field(PhysicButtonsPanel, bpy.types.Panel):
bl_label = "Force Fields"
@classmethod
def poll(cls, context):
ob = context.object

@ -39,8 +39,8 @@ class RENDER_MT_framerate_presets(bpy.types.Menu):
preset_subdir = "framerate"
preset_operator = "script.execute_preset"
draw = bpy.types.Menu.draw_preset
class RenderButtonsPanel():
bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW'
@ -566,20 +566,20 @@ class RENDER_PT_dimensions(RenderButtonsPanel, bpy.types.Panel):
fps_rate = round(rd.fps / rd.fps_base)
else:
fps_rate = round(rd.fps / rd.fps_base, 2)
# TODO: Change the following to iterate over existing presets
if (fps_rate in (23.98, 24, 25, 29.97, 30, 50, 59.94, 60)):
custom_framerate = False
else:
custom_framerate = True
if custom_framerate == True:
fps_label_text = "Custom (" + str(fps_rate) + " fps)"
else:
fps_label_text = str(fps_rate) + " fps"
sub.menu("RENDER_MT_framerate_presets", text=fps_label_text)
if (bpy.types.RENDER_MT_framerate_presets.bl_label == "Custom") or (custom_framerate == True):
sub.prop(rd, "fps")
sub.prop(rd, "fps_base", text="/")

@ -32,10 +32,10 @@ def dopesheet_filter(layout, context, genericFiltersOnly=False):
row = layout.row(align=True)
row.prop(dopesheet, "show_only_selected", text="")
row.prop(dopesheet, "show_hidden", text="")
if genericFiltersOnly:
return
return
row = layout.row(align=True)
row.prop(dopesheet, "show_transforms", text="")
@ -114,8 +114,8 @@ class DOPESHEET_HT_header(bpy.types.Header):
if st.mode == 'DOPESHEET':
dopesheet_filter(layout, context)
elif st.mode == 'ACTION':
# 'genericFiltersOnly' limits the options to only the relevant 'generic' subset of
# filters which will work here and are useful (especially for character animation)
# 'genericFiltersOnly' limits the options to only the relevant 'generic' subset of
# filters which will work here and are useful (especially for character animation)
dopesheet_filter(layout, context, genericFiltersOnly=True)
if st.mode in ('ACTION', 'SHAPEKEY'):

@ -163,8 +163,8 @@ class NODE_MT_node(bpy.types.Menu):
layout.operator("node.show_cyclic_dependencies")
layout.operator("node.read_renderlayers")
layout.operator("node.read_fullsamplelayers")
# Node Backdrop options
class NODE_PT_properties(bpy.types.Panel):
bl_space_type = 'NODE_EDITOR'
@ -175,7 +175,7 @@ class NODE_PT_properties(bpy.types.Panel):
def poll(cls, context):
snode = context.space_data
return snode.tree_type == 'COMPOSITING'
def draw_header(self, context):
snode = context.space_data
self.layout.prop(snode, "show_backdrop", text="")

@ -34,6 +34,7 @@ def draw_repeat_tools(context, layout):
col.operator("screen.repeat_last")
col.operator("screen.repeat_history", text="History...")
# Keyframing tools
def draw_keyframing_tools(context, layout):
col = layout.column(align=True)
@ -42,6 +43,7 @@ def draw_keyframing_tools(context, layout):
row.operator("anim.keyframe_insert_menu", text="Insert")
row.operator("anim.keyframe_delete_v3d", text="Remove")
# Grease Pencil tools
def draw_gpencil_tools(context, layout):
col = layout.column(align=True)
@ -88,9 +90,9 @@ class VIEW3D_PT_tools_objectmode(View3DPanel, bpy.types.Panel):
col.label(text="Shading:")
col.operator("object.shade_smooth", text="Smooth")
col.operator("object.shade_flat", text="Flat")
draw_keyframing_tools(context, layout)
col = layout.column(align=True)
col.label(text="Motion Paths:")
col.operator("object.paths_calculate", text="Calculate Paths")
@ -406,7 +408,7 @@ class VIEW3D_PT_tools_posemode(View3DPanel, bpy.types.Panel):
col.operator("poselib.pose_add", text="Add To Library")
draw_keyframing_tools(context, layout)
col = layout.column(align=True)
col.label(text="Motion Paths:")
col.operator("pose.paths_calculate", text="Calculate Paths")

@ -50,6 +50,12 @@ def is_pep8(path):
print(path)
if open(path, 'rb').read(3) == b'\xef\xbb\xbf':
print("\nfile contains BOM, remove first 3 bytes: %r\n" % path)
# templates dont have a header but should be pep8
for d in ("presets", "templates", "examples"):
if ("%s%s%s" % (os.sep, d, os.sep)) in path:
return 1
f = open(path, 'r', encoding="utf8")
for i in range(PEP8_SEEK_COMMENT):
line = f.readline()