diff options
author | Sergey Sharybin <sergey.vfx@gmail.com> | 2012-04-14 14:46:47 +0400 |
---|---|---|
committer | Sergey Sharybin <sergey.vfx@gmail.com> | 2012-04-14 14:46:47 +0400 |
commit | bfca79a6577c7e4ab3d0dcae585abcf2a17fe710 (patch) | |
tree | 00804e29d009c81406892159233d372aee12e500 /release/scripts | |
parent | 69ee17f0b6121ab63f0a7712c9563295eda88d39 (diff) | |
parent | 9a79bd38ade00fc663c27ffda9892629ef5ca755 (diff) |
Merging r44227 through r45619 from trunk into soc-2011-tomato
Diffstat (limited to 'release/scripts')
67 files changed, 1109 insertions, 769 deletions
diff --git a/release/scripts/modules/addon_utils.py b/release/scripts/modules/addon_utils.py index 2b1616a0022..588c10eea54 100644 --- a/release/scripts/modules/addon_utils.py +++ b/release/scripts/modules/addon_utils.py @@ -65,7 +65,7 @@ def modules(module_cache): def fake_module(mod_name, mod_path, speedy=True, force_support=None): global error_encoding - if _bpy.app.debug: + if _bpy.app.debug_python: print("fake_module", mod_path, mod_name) import ast ModuleType = type(ast) @@ -284,7 +284,7 @@ def enable(module_name, default_set=True): mod.__addon_enabled__ = True - if _bpy.app.debug: + if _bpy.app.debug_python: print("\taddon_utils.enable", mod.__name__) return mod @@ -323,7 +323,7 @@ def disable(module_name, default_set=True): if addon: addons.remove(addon) - if _bpy.app.debug: + if _bpy.app.debug_python: print("\taddon_utils.disable", module_name) diff --git a/release/scripts/modules/bpy/__init__.py b/release/scripts/modules/bpy/__init__.py index 75572a6294e..621484fc896 100644 --- a/release/scripts/modules/bpy/__init__.py +++ b/release/scripts/modules/bpy/__init__.py @@ -50,7 +50,9 @@ def main(): # Possibly temp. addons path from os.path import join, dirname, normpath sys.path.append(normpath(join(dirname(__file__), - "..", "..", "addons", "modules"))) + "..", "..", "addons", "modules"))) + sys.path.append(join(utils.user_resource('SCRIPTS'), + "addons", "modules")) # fake module to allow: # from bpy.types import Panel diff --git a/release/scripts/modules/bpy/path.py b/release/scripts/modules/bpy/path.py index 98a3c81d65a..7b54af944ad 100644 --- a/release/scripts/modules/bpy/path.py +++ b/release/scripts/modules/bpy/path.py @@ -118,6 +118,14 @@ def clean_name(name, replace="_"): return name +def _clean_utf8(name): + name = _os.path.splitext(basename(name))[0] + if type(name) == bytes: + return name.decode("utf8", "replace") + else: + return name.encode("utf8", "replace").decode("utf8") + + def display_name(name): """ Creates a display string from name to be used menus and the user interface. @@ -126,17 +134,18 @@ def display_name(name): filenames and module names. """ - name_base = _os.path.splitext(name)[0] + name = _os.path.splitext(name)[0] # string replacements - name_base = name_base.replace("_colon_", ":") + name = name.replace("_colon_", ":") - name_base = name_base.replace("_", " ") + name = name.replace("_", " ") - if name_base.islower(): - return name_base.lower().title() - else: - return name_base + if name.islower(): + name = name.lower().title() + + name = _clean_utf8(name) + return name def display_name_from_filepath(name): @@ -144,8 +153,10 @@ def display_name_from_filepath(name): Returns the path stripped of directory and extension, ensured to be utf8 compatible. """ + name = _os.path.splitext(basename(name))[0] - return name.encode("utf8", "replace").decode("utf8") + name = _clean_utf8(name) + return name def resolve_ncase(path): diff --git a/release/scripts/modules/bpy/utils.py b/release/scripts/modules/bpy/utils.py index 63ba213f9b1..2824d6245e5 100644 --- a/release/scripts/modules/bpy/utils.py +++ b/release/scripts/modules/bpy/utils.py @@ -57,7 +57,7 @@ _script_module_dirs = "startup", "modules" def _test_import(module_name, loaded_modules): - use_time = _bpy.app.debug + use_time = _bpy.app.debug_python if module_name in loaded_modules: return None @@ -126,7 +126,7 @@ def load_scripts(reload_scripts=False, refresh_scripts=False): as modules. :type refresh_scripts: bool """ - use_time = _bpy.app.debug + use_time = _bpy.app.debug_python prefs = _bpy.context.user_preferences @@ -426,7 +426,7 @@ def preset_find(name, preset_path, display_name=False, ext=".py"): def keyconfig_set(filepath): from os.path import basename, splitext - if _bpy.app.debug: + if _bpy.app.debug_python: print("loading preset:", filepath) keyconfigs = _bpy.context.window_manager.keyconfigs diff --git a/release/scripts/modules/bpy_extras/io_utils.py b/release/scripts/modules/bpy_extras/io_utils.py index 38fdb8f5fec..593fc85e9cb 100644 --- a/release/scripts/modules/bpy_extras/io_utils.py +++ b/release/scripts/modules/bpy_extras/io_utils.py @@ -335,7 +335,7 @@ path_reference_mode = EnumProperty( ('MATCH', "Match", "Match Absolute/Relative " "setting with input path"), ('STRIP', "Strip Path", "Filename only"), - ('COPY', "Copy", "copy the file to the destination path " + ('COPY', "Copy", "Copy the file to the destination path " "(or subdirectory)"), ), default='AUTO' diff --git a/release/scripts/modules/bpy_extras/mesh_utils.py b/release/scripts/modules/bpy_extras/mesh_utils.py index 601ffae4796..3ce45154765 100644 --- a/release/scripts/modules/bpy_extras/mesh_utils.py +++ b/release/scripts/modules/bpy_extras/mesh_utils.py @@ -19,17 +19,17 @@ # <pep8-80 compliant> __all__ = ( - "mesh_linked_faces", + "mesh_linked_tessfaces", "edge_face_count_dict", "edge_face_count", - "edge_loops_from_faces", + "edge_loops_from_tessfaces", "edge_loops_from_edges", - "ngon_tesselate", + "ngon_tessellate", "face_random_points", ) -def mesh_linked_faces(mesh): +def mesh_linked_tessfaces(mesh): """ Splits the mesh into connected faces, use this for seperating cubes from other mesh elements within 1 mesh datablock. @@ -42,20 +42,21 @@ def mesh_linked_faces(mesh): # Build vert face connectivity vert_faces = [[] for i in range(len(mesh.vertices))] - for f in mesh.faces: + for f in mesh.tessfaces: for v in f.vertices: vert_faces[v].append(f) # sort faces into connectivity groups - face_groups = [[f] for f in mesh.faces] - face_mapping = list(range(len(mesh.faces))) # map old, new face location + face_groups = [[f] for f in mesh.tessfaces] + # map old, new face location + face_mapping = list(range(len(mesh.tessfaces))) # Now clump faces iteratively ok = True while ok: ok = False - for i, f in enumerate(mesh.faces): + for i, f in enumerate(mesh.tessfaces): mapped_index = face_mapping[f.index] mapped_group = face_groups[mapped_index] @@ -90,7 +91,7 @@ def edge_face_count_dict(mesh): faces using each edge. :rtype: dict """ - face_edge_keys = [face.edge_keys for face in mesh.faces] + face_edge_keys = [face.edge_keys for face in mesh.tessfaces] face_edge_count = {} for face_keys in face_edge_keys: for key in face_keys: @@ -112,11 +113,11 @@ def edge_face_count(mesh): return [get(edge_face_count, ed.key, 0) for ed in mesh.edges] -def edge_loops_from_faces(mesh, faces=None, seams=()): +def edge_loops_from_tessfaces(mesh, tessfaces=None, seams=()): """ Edge loops defined by faces - Takes me.faces or a list of faces and returns the edge loops + Takes me.tessfaces or a list of faces and returns the edge loops These edge loops are the edges that sit between quads, so they dont touch 1 quad, note: not connected will make 2 edge loops, both only containing 2 edges. @@ -126,22 +127,21 @@ def edge_loops_from_faces(mesh, faces=None, seams=()): :arg mesh: the mesh used to get edge loops from. :type mesh: :class:`bpy.types.Mesh` - :arg faces: optional face list to only use some of the meshes faces. - :type faces: :class:`bpy.types.MeshFaces`, sequence or or NoneType + :arg tessfaces: optional face list to only use some of the meshes faces. + :type tessfaces: :class:`bpy.types.MeshTessFace`, sequence or or NoneType :return: return a list of edge vertex index lists. :rtype: list """ OTHER_INDEX = 2, 3, 0, 1 # opposite face index - if faces is None: - faces = mesh.faces + if tessfaces is None: + tessfaces = mesh.tessfaces edges = {} - for f in faces: -# if len(f) == 4: - if f.vertices_raw[3] != 0: + for f in tessfaces: + if len(f.vertices) == 4: edge_keys = f.edge_keys for i, edkey in enumerate(f.edge_keys): edges.setdefault(edkey, []).append(edge_keys[OTHER_INDEX[i]]) @@ -257,7 +257,7 @@ def edge_loops_from_edges(mesh, edges=None): return line_polys -def ngon_tesselate(from_data, indices, fix_loops=True): +def ngon_tessellate(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 @@ -270,7 +270,7 @@ def ngon_tesselate(from_data, indices, fix_loops=True): polylines are delt with correctly. ''' - from mathutils.geometry import tesselate_polygon + from mathutils.geometry import tessellate_polygon from mathutils import Vector vector_to_tuple = Vector.to_tuple @@ -304,7 +304,7 @@ def ngon_tesselate(from_data, indices, fix_loops=True): if verts[i][1] == verts[i - 1][0]: verts.pop(i - 1) - fill = tesselate_polygon([verts]) + fill = tessellate_polygon([verts]) else: ''' @@ -412,7 +412,7 @@ def ngon_tesselate(from_data, indices, fix_loops=True): vert_map[i + ii] = vert[2] ii += len(verts) - fill = tesselate_polygon([[v[0] for v in loop] for loop in loop_list]) + fill = tessellate_polygon([[v[0] for v in loop] for loop in loop_list]) #draw_loops(loop_list) #raise 'done loop' # map to original indices @@ -443,14 +443,14 @@ def ngon_tesselate(from_data, indices, fix_loops=True): return fill -def face_random_points(num_points, faces): +def face_random_points(num_points, tessfaces): """ - Generates a list of random points over mesh faces. + Generates a list of random points over mesh tessfaces. :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 + :arg tessfaces: list of the faces to generate points on. + :type tessfaces: :class:`bpy.types.MeshTessFace`, sequence :return: list of random points over all faces. :rtype: list """ @@ -460,7 +460,7 @@ def face_random_points(num_points, faces): # Split all quads into 2 tris, tris remain unchanged tri_faces = [] - for f in faces: + for f in tessfaces: tris = [] verts = f.id_data.vertices fv = f.vertices[:] @@ -476,7 +476,7 @@ def face_random_points(num_points, faces): tri_faces.append(tris) # For each face, generate the required number of random points - sampled_points = [None] * (num_points * len(faces)) + sampled_points = [None] * (num_points * len(tessfaces)) 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 diff --git a/release/scripts/modules/bpy_extras/object_utils.py b/release/scripts/modules/bpy_extras/object_utils.py index 66b774e6301..b1de1fd47a4 100644 --- a/release/scripts/modules/bpy_extras/object_utils.py +++ b/release/scripts/modules/bpy_extras/object_utils.py @@ -21,12 +21,15 @@ __all__ = ( "add_object_align_init", "object_data_add", + "AddObjectHelper", ) import bpy import mathutils +from bpy.props import BoolProperty, FloatVectorProperty + def add_object_align_init(context, operator): """ @@ -86,7 +89,7 @@ def add_object_align_init(context, operator): return location * rotation -def object_data_add(context, obdata, operator=None): +def object_data_add(context, obdata, operator=None, use_active_layer=True): """ Add an object using the view context and preference to to initialize the location, rotation and layer. @@ -111,7 +114,18 @@ def object_data_add(context, obdata, operator=None): base = scene.objects.link(obj_new) base.select = True + v3d = None if context.space_data and context.space_data.type == 'VIEW_3D': + v3d = context.space_data + + if use_active_layer: + if v3d and v3d.local_view: + base.layers_from_view(context.space_data) + base.layers[scene.active_layer] = True + else: + base.layers = [True if i == scene.active_layer + else False for i in range(len(scene.layers))] + if v3d: base.layers_from_view(context.space_data) obj_new.matrix_world = add_object_align_init(context, operator) @@ -153,3 +167,23 @@ def object_data_add(context, obdata, operator=None): bpy.ops.object.mode_set(mode='EDIT') return base + + +class AddObjectHelper: + def view_align_update_callback(self, context): + if not self.view_align: + self.rotation.zero() + + view_align = BoolProperty( + name="Align to View", + default=False, + update=view_align_update_callback, + ) + location = FloatVectorProperty( + name="Location", + subtype='TRANSLATION', + ) + rotation = FloatVectorProperty( + name="Rotation", + subtype='EULER', + ) diff --git a/release/scripts/modules/bpy_types.py b/release/scripts/modules/bpy_types.py index 088e239e9a5..91d8f1b3467 100644 --- a/release/scripts/modules/bpy_types.py +++ b/release/scripts/modules/bpy_types.py @@ -366,14 +366,15 @@ class Mesh(bpy_types.ID): :type edges: iterable object :arg faces: - iterator of faces, each faces contains three or four indices to + iterator of faces, each faces contains three or more indices to the *vertices* argument. eg: [(5, 6, 8, 9), (1, 2, 3), ...] :type faces: iterable object """ self.vertices.add(len(vertices)) self.edges.add(len(edges)) - self.faces.add(len(faces)) + self.loops.add(sum((len(f) for f in faces))) + self.polygons.add(len(faces)) vertices_flat = [f for v in vertices for f in v] self.vertices.foreach_set("co", vertices_flat) @@ -383,19 +384,19 @@ class Mesh(bpy_types.ID): self.edges.foreach_set("vertices", edges_flat) del edges_flat - def treat_face(f): - if len(f) == 3: - if f[2] == 0: - return f[2], f[0], f[1], 0 - else: - return f[0], f[1], f[2], 0 - elif f[2] == 0 or f[3] == 0: - return f[2], f[3], f[0], f[1] - return f + # this is different in bmesh + loop_index = 0 + for i, p in enumerate(self.polygons): + f = faces[i] + loop_len = len(f) + p.loop_start = loop_index + p.loop_total = loop_len + p.vertices = f + loop_index += loop_len - faces_flat = [v for f in faces for v in treat_face(f)] - self.faces.foreach_set("vertices_raw", faces_flat) - del faces_flat + # if no edges - calculae them + if faces and (not edges): + self.update(calc_edges=True) @property def edge_keys(self): @@ -410,7 +411,7 @@ class MeshEdge(StructRNA): return ord_ind(*tuple(self.vertices)) -class MeshFace(StructRNA): +class MeshTessFace(StructRNA): __slots__ = () @property @@ -446,6 +447,22 @@ class MeshFace(StructRNA): ) +class MeshPolygon(StructRNA): + __slots__ = () + + @property + def edge_keys(self): + verts = self.vertices[:] + vlen = len(self.vertices) + return [ord_ind(verts[i], verts[(i + 1) % vlen]) for i in range(vlen)] + + @property + def loop_indices(self): + start = self.loop_start + end = start + self.loop_total + return range(start, end) + + class Text(bpy_types.ID): __slots__ = () @@ -654,7 +671,9 @@ class Header(StructRNA, _GenericUI, metaclass=RNAMeta): class Menu(StructRNA, _GenericUI, metaclass=RNAMeta): __slots__ = () - def path_menu(self, searchpaths, operator, props_default={}): + def path_menu(self, searchpaths, operator, + props_default={}, filter_ext=None): + layout = self.layout # hard coded to set the operators 'filepath' to the filename. @@ -670,17 +689,16 @@ class Menu(StructRNA, _GenericUI, metaclass=RNAMeta): files = [] for directory in searchpaths: files.extend([(f, os.path.join(directory, f)) - for f in os.listdir(directory)]) + for f in os.listdir(directory) + if (not f.startswith(".")) + if ((filter_ext is None) or + (filter_ext(os.path.splitext(f)[1]))) + ]) files.sort() for f, filepath in files: - - if f.startswith("."): - continue - - preset_name = bpy.path.display_name(f) - props = layout.operator(operator, text=preset_name) + props = layout.operator(operator, text=bpy.path.display_name(f)) for attr, value in props_default.items(): setattr(props, attr, value) @@ -697,4 +715,5 @@ class Menu(StructRNA, _GenericUI, metaclass=RNAMeta): """ import bpy self.path_menu(bpy.utils.preset_paths(self.preset_subdir), - self.preset_operator) + self.preset_operator, + filter_ext=lambda ext: ext.lower() in {".py", ".xml"}) diff --git a/release/scripts/modules/console_python.py b/release/scripts/modules/console_python.py index 6c49283b3e1..4ddde0de17c 100644 --- a/release/scripts/modules/console_python.py +++ b/release/scripts/modules/console_python.py @@ -246,7 +246,7 @@ def autocomplete(context): line=line, cursor=current_line.current_character, namespace=console.locals, - private=bpy.app.debug) + private=bpy.app.debug_python) line_new = result[0] current_line.body, current_line.current_character, scrollback = result @@ -306,9 +306,6 @@ def banner(context): add_scrollback("Convenience Imports: from mathutils import *; " "from math import *", 'OUTPUT') add_scrollback("", 'OUTPUT') - # add_scrollback(" WARNING!!! Blender 2.5 API is subject to change, " - # "see API reference for more info", 'ERROR') - # add_scrollback("", 'OUTPUT') sc.prompt = PROMPT return {'FINISHED'} diff --git a/release/scripts/modules/rna_xml.py b/release/scripts/modules/rna_xml.py index eae7840b69b..710035dc29f 100644 --- a/release/scripts/modules/rna_xml.py +++ b/release/scripts/modules/rna_xml.py @@ -346,7 +346,7 @@ def xml_file_run(context, filepath, rna_map): value = _get_context_val(context, rna_path) if value is not Ellipsis and value is not None: - print(" loading XML: %r" % rna_path) + print(" loading XML: %r -> %r" % (filepath, rna_path)) xml2rna(xml_node, root_rna=value) diff --git a/release/scripts/modules/sys_info.py b/release/scripts/modules/sys_info.py index 10aba96afd0..0fa80a8f855 100644 --- a/release/scripts/modules/sys_info.py +++ b/release/scripts/modules/sys_info.py @@ -57,66 +57,66 @@ def write_sysinfo(op): else: output = bpy.data.texts.new(name=output_filename) - header = '= Blender {} System Information =\n'.format(bpy.app.version_string) - lilies = '{}\n\n'.format(len(header) * '=') - firstlilies = '{}\n'.format(len(header) * '=') + header = "= Blender %s System Information =\n" % bpy.app.version_string + lilies = "%s\n\n" % (len(header) * "=") + firstlilies = "%s\n" % (len(header) * "=") output.write(firstlilies) output.write(header) output.write(lilies) # build info - output.write('\nBlender:\n') + output.write("\nBlender:\n") output.write(lilies) - output.write('version {}, revision {}. {}\n'.format(bpy.app.version_string, bpy.app.build_revision, bpy.app.build_type)) - output.write('build date: {}, {}\n'.format(bpy.app.build_date, bpy.app.build_time)) - output.write('platform: {}\n'.format(bpy.app.build_platform)) - output.write('binary path: {}\n'.format(bpy.app.binary_path)) - output.write('build cflags: {}\n'.format(bpy.app.build_cflags)) - output.write('build cxxflags: {}\n'.format(bpy.app.build_cxxflags)) - output.write('build linkflags: {}\n'.format(bpy.app.build_linkflags)) - output.write('build system: {}\n'.format(bpy.app.build_system)) + output.write("version %s, revision %r. %r\n" % (bpy.app.version_string, bpy.app.build_revision, bpy.app.build_type)) + output.write("build date: %r, %r\n" % (bpy.app.build_date, bpy.app.build_time)) + output.write("platform: %r\n" % (bpy.app.build_platform)) + output.write("binary path: %r\n" % (bpy.app.binary_path)) + output.write("build cflags: %r\n" % (bpy.app.build_cflags)) + output.write("build cxxflags: %r\n" % (bpy.app.build_cxxflags)) + output.write("build linkflags: %r\n" % (bpy.app.build_linkflags)) + output.write("build system: %r\n" % (bpy.app.build_system)) # python info - output.write('\nPython:\n') + output.write("\nPython:\n") output.write(lilies) - output.write('version: {}\n'.format(sys.version)) - output.write('paths:\n') + output.write("version: %s\n" % (sys.version)) + output.write("paths:\n") for p in sys.path: - output.write('\t{}\n'.format(p)) + output.write("\t%r\n" % (p)) - output.write('\nDirectories:\n') + output.write("\nDirectories:\n") output.write(lilies) - output.write('scripts: {}\n'.format(bpy.utils.script_paths())) - output.write('user scripts: {}\n'.format(bpy.utils.user_script_path())) - output.write('datafiles: {}\n'.format(bpy.utils.user_resource('DATAFILES'))) - output.write('config: {}\n'.format(bpy.utils.user_resource('CONFIG'))) - output.write('scripts : {}\n'.format(bpy.utils.user_resource('SCRIPTS'))) - output.write('autosave: {}\n'.format(bpy.utils.user_resource('AUTOSAVE'))) - output.write('tempdir: {}\n'.format(bpy.app.tempdir)) - - output.write('\nFFmpeg:\n') + output.write("scripts: %r\n" % (bpy.utils.script_paths())) + output.write("user scripts: %r\n" % (bpy.utils.user_script_path())) + output.write("datafiles: %r\n" % (bpy.utils.user_resource('DATAFILES'))) + output.write("config: %r\n" % (bpy.utils.user_resource('CONFIG'))) + output.write("scripts : %r\n" % (bpy.utils.user_resource('SCRIPTS'))) + output.write("autosave: %r\n" % (bpy.utils.user_resource('AUTOSAVE'))) + output.write("tempdir: %r\n" % (bpy.app.tempdir)) + + output.write("\nFFmpeg:\n") output.write(lilies) ffmpeg = bpy.app.ffmpeg if ffmpeg.supported: for lib in ['avcodec', 'avdevice', 'avformat', 'avutil', 'swscale']: - output.write('{}:{}{}\n'.format(lib, " " * (10 - len(lib)), - getattr(ffmpeg, lib + '_version_string'))) + output.write("%r:%r%r\n" % (lib, " " * (10 - len(lib)), + getattr(ffmpeg, lib + "_version_string"))) else: - output.write('Blender was built without FFmpeg support\n') + output.write("Blender was built without FFmpeg support\n") if bpy.app.background: - output.write('\nOpenGL: missing, background mode\n') + output.write("\nOpenGL: missing, background mode\n") else: - output.write('\nOpenGL\n') + output.write("\nOpenGL\n") output.write(lilies) - output.write('renderer:\t{}\n'.format(bgl.glGetString(bgl.GL_RENDERER))) - output.write('vendor:\t\t{}\n'.format(bgl.glGetString(bgl.GL_VENDOR))) - output.write('version:\t{}\n'.format(bgl.glGetString(bgl.GL_VERSION))) - output.write('extensions:\n') + output.write("renderer:\t%r\n" % (bgl.glGetString(bgl.GL_RENDERER))) + output.write("vendor:\t\t%r\n" % (bgl.glGetString(bgl.GL_VENDOR))) + output.write("version:\t%r\n" % (bgl.glGetString(bgl.GL_VERSION))) + output.write("extensions:\n") glext = bgl.glGetString(bgl.GL_EXTENSIONS) glext = textWrap(glext, 70) for l in glext: - output.write('\t\t{}\n'.format(l)) + output.write("\t\t%r\n" % (l)) op.report({'INFO'}, "System information generated in 'system-info.txt'") diff --git a/release/scripts/presets/interface_theme/back_to_black.xml b/release/scripts/presets/interface_theme/back_to_black.xml index 76c30bb293b..66a2ae54ade 100644 --- a/release/scripts/presets/interface_theme/back_to_black.xml +++ b/release/scripts/presets/interface_theme/back_to_black.xml @@ -11,6 +11,7 @@ bone_pose="#50c8ff" bone_solid="#c8c8c8" bundle_solid="#c8c8c8" + camera="#000000" camera_path="#5a5a5a" frame_current="#60c040" edge_crease="#cc0099" @@ -19,6 +20,7 @@ edge_select="#ffa000" edge_sharp="#ff2020" edge_facesel="#6b6b6b" + empty="#000000" face="#73828f12" extra_face_angle="#00c900" extra_face_area="#fff000" @@ -404,6 +406,7 @@ </properties> <sequence_editor> <ThemeSequenceEditor audio_strip="#2e8f8f" + movieclip_strip="#20208f" frame_current="#2f5f23" draw_action="#50c8ff" effect_strip="#a9547c" @@ -413,6 +416,7 @@ meta_strip="#6d9183" movie_strip="#516987" plugin_strip="#7e7e50" + preview_back="#000000" scene_strip="#4e983e" transition_strip="#a25f6f" window_sliders="#a0a0a0"> @@ -434,13 +438,12 @@ </sequence_editor> <text_editor> <ThemeTextEditor cursor="#ff0000" + syntax_special="#969629" line_numbers_background="#191919" - scroll_bar="#acacac" selected_text="#ffffff" syntax_builtin="#cf3d99" syntax_comment="#249d60" syntax_numbers="#3c68ff" - syntax_special="#969629" syntax_string="#cc3535"> <space> <ThemeSpaceGeneric header="#000000" @@ -687,6 +690,18 @@ text_sel="#ffffff"> </ThemeWidgetColors> </wcol_tool> + <wcol_tooltip> + <ThemeWidgetColors inner="#191919e6" + inner_sel="#2d2d2de6" + item="#646464ff" + outline="#000000" + shadedown="-20" + shadetop="25" + show_shaded="FALSE" + text="#ffffff" + text_sel="#ffffff"> + </ThemeWidgetColors> + </wcol_tooltip> </ThemeUserInterface> </user_interface> <user_preferences> diff --git a/release/scripts/presets/interface_theme/blender_24x.xml b/release/scripts/presets/interface_theme/blender_24x.xml index 046a05982cf..d36e54262ba 100644 --- a/release/scripts/presets/interface_theme/blender_24x.xml +++ b/release/scripts/presets/interface_theme/blender_24x.xml @@ -11,6 +11,7 @@ bone_pose="#50c8ff" bone_solid="#c8c8c8" bundle_solid="#c8c8c8" + camera="#000000" camera_path="#000000" frame_current="#60c040" edge_crease="#cc0099" @@ -19,6 +20,7 @@ edge_select="#cece38" edge_sharp="#ff2020" edge_facesel="#4b4b4b" + empty="#000000" face="#0032961e" extra_face_angle="#000080" extra_face_area="#002000" @@ -155,10 +157,10 @@ </dopesheet_editor> <file_browser> <ThemeFileBrowser active_file="#828282" - active_file_text="#fafafa" + active_file_text="#ffffff" scroll_handle="#7f7070" scrollbar="#a0a0a0" - selected_file="#7f7f7f" + selected_file="#a0a0d0" tiles="#b4b4b4"> <space> <ThemeSpaceGeneric header="#b4b4b4" @@ -171,7 +173,7 @@ text="#000000" text_hi="#0f0f0f" title="#000000" - back="#b4b4b4"> + back="#808080"> </ThemeSpaceGeneric> </space> <space_list> @@ -260,7 +262,7 @@ text="#000000" text_hi="#ffffff" title="#000000" - back="#757575"> + back="#353535"> </ThemeSpaceGeneric> </space> </ThemeImageEditor> @@ -379,7 +381,7 @@ text="#000000" text_hi="#ffffff" title="#000000" - back="#b4b4b4"> + back="#999999"> </ThemeSpaceGeneric> </space> </ThemeOutliner> @@ -404,6 +406,7 @@ </properties> <sequence_editor> <ThemeSequenceEditor audio_strip="#2e8f8f" + movieclip_strip="#20208f" frame_current="#60c040" draw_action="#50c8ff" effect_strip="#a9547c" @@ -413,6 +416,7 @@ meta_strip="#6d9183" movie_strip="#516987" plugin_strip="#7e7e50" + preview_back="#000000" scene_strip="#4e983e" transition_strip="#a25f6f" window_sliders="#a0a0a0"> @@ -434,13 +438,12 @@ </sequence_editor> <text_editor> <ThemeTextEditor cursor="#ff0000" + syntax_special="#5f5f00" line_numbers_background="#818181" - scroll_bar="#8f8f8f" selected_text="#c67777" syntax_builtin="#800050" syntax_comment="#006432" syntax_numbers="#0000c8" - syntax_special="#5f5f00" syntax_string="#640000"> <space> <ThemeSpaceGeneric header="#b4b4b4" @@ -687,6 +690,18 @@ text_sel="#ffffff"> </ThemeWidgetColors> </wcol_tool> + <wcol_tooltip> + <ThemeWidgetColors inner="#ffffddff" + inner_sel="#2d2d2de6" + item="#646464ff" + outline="#000000" + shadedown="-20" + shadetop="25" + show_shaded="FALSE" + text="#000000" + text_sel="#ffffff"> + </ThemeWidgetColors> + </wcol_tooltip> </ThemeUserInterface> </user_interface> <user_preferences> diff --git a/release/scripts/presets/interface_theme/elsyiun.xml b/release/scripts/presets/interface_theme/elsyiun.xml index cce51d6de38..9e4c17a1715 100644 --- a/release/scripts/presets/interface_theme/elsyiun.xml +++ b/release/scripts/presets/interface_theme/elsyiun.xml @@ -1,7 +1,7 @@ <bpy> <Theme> <view_3d> - <ThemeView3D object_active="#ff7c00" + <ThemeView3D object_active="#ffc280" editmesh_active="#ffffff80" act_spline="#db2512" handle_align="#803060" @@ -11,6 +11,7 @@ bone_pose="#50c8ff" bone_solid="#c8c8c8" bundle_solid="#c8c8c8" + camera="#000000" camera_path="#000000" frame_current="#60c040" edge_crease="#cc0099" @@ -19,11 +20,12 @@ edge_select="#cb7027" edge_sharp="#00ffff" edge_facesel="#4b4b4b" + empty="#000000" face="#00000036" extra_face_angle="#000080" extra_face_area="#002000" face_dot="#be6925" - facedot_size="2" + facedot_size="3" normal="#22dddd" face_select="#a47c5b73" handle_free="#000000" @@ -37,16 +39,16 @@ nurb_sel_vline="#f090a0" object_grouped="#083008" object_grouped_active="#55bb55" - object_selected="#ffffff" + object_selected="#ff8500" outline_width="1" panel="#a5a5a57f" speaker="#000000" transform="#ffffff" handle_vect="#409030" handle_sel_vect="#40c030" - vertex="#93b2c2" + vertex="#657780" vertex_normal="#2361dd" - vertex_select="#be6925" + vertex_select="#ff7c00" vertex_size="3" wire="#000000"> <space> @@ -404,6 +406,7 @@ </properties> <sequence_editor> <ThemeSequenceEditor audio_strip="#2e8f8f" + movieclip_strip="#20208f" frame_current="#60c040" draw_action="#50c8ff" effect_strip="#a9547c" @@ -413,6 +416,7 @@ meta_strip="#6d9183" movie_strip="#516987" plugin_strip="#7e7e50" + preview_back="#000000" scene_strip="#4e983e" transition_strip="#a25f6f" window_sliders="#a0a0a0"> @@ -434,13 +438,12 @@ </sequence_editor> <text_editor> <ThemeTextEditor cursor="#8b8bff" + syntax_special="#c080d0" line_numbers_background="#2e2e2e" - scroll_bar="#8f8f8f" selected_text="#4e4e8f" syntax_builtin="#808bed" syntax_comment="#cd8b00" syntax_numbers="#f0ad6d" - syntax_special="#c080d0" syntax_string="#ffcd8b"> <space> <ThemeSpaceGeneric header="#3b3b3b" @@ -687,6 +690,18 @@ text_sel="#ffffff"> </ThemeWidgetColors> </wcol_tool> + <wcol_tooltip> + <ThemeWidgetColors inner="#191919e6" + inner_sel="#2d2d2de6" + item="#646464ff" + outline="#000000" + shadedown="-20" + shadetop="25" + show_shaded="FALSE" + text="#ffffff" + text_sel="#ffffff"> + </ThemeWidgetColors> + </wcol_tooltip> </ThemeUserInterface> </user_interface> <user_preferences> diff --git a/release/scripts/presets/interface_theme/hexagon.xml b/release/scripts/presets/interface_theme/hexagon.xml index 07c05656c26..4f6dbb376e2 100644 --- a/release/scripts/presets/interface_theme/hexagon.xml +++ b/release/scripts/presets/interface_theme/hexagon.xml @@ -11,6 +11,7 @@ bone_pose="#50c8ff" bone_solid="#c8c8c8" bundle_solid="#c8c8c8" + camera="#000000" camera_path="#000000" frame_current="#60c040" edge_crease="#cc0099" @@ -19,6 +20,7 @@ edge_select="#1151ce" edge_sharp="#ff2020" edge_facesel="#4b4b4b" + empty="#000000" face="#affff418" extra_face_angle="#00008a" extra_face_area="#002000" @@ -404,6 +406,7 @@ </properties> <sequence_editor> <ThemeSequenceEditor audio_strip="#2e8f8f" + movieclip_strip="#20208f" frame_current="#60c040" draw_action="#50c8ff" effect_strip="#a9547c" @@ -413,6 +416,7 @@ meta_strip="#6d9183" movie_strip="#516987" plugin_strip="#7e7e50" + preview_back="#000000" scene_strip="#4e983e" transition_strip="#a25f6f" window_sliders="#a0a0a0"> @@ -434,13 +438,12 @@ </sequence_editor> <text_editor> <ThemeTextEditor cursor="#ff0000" + syntax_special="#5f5f00" line_numbers_background="#5a5e6a" - scroll_bar="#8f8f8f" selected_text="#c67777" syntax_builtin="#800050" syntax_comment="#006432" syntax_numbers="#0000c8" - syntax_special="#5f5f00" syntax_string="#640000"> <space> <ThemeSpaceGeneric header="#5c606c" @@ -687,6 +690,18 @@ text_sel="#ffffff"> </ThemeWidgetColors> </wcol_tool> + <wcol_tooltip> + <ThemeWidgetColors inner="#191919e6" + inner_sel="#2d2d2de6" + item="#646464ff" + outline="#000000" + shadedown="-20" + shadetop="25" + show_shaded="FALSE" + text="#ffffff" + text_sel="#ffffff"> + </ThemeWidgetColors> + </wcol_tooltip> </ThemeUserInterface> </user_interface> <user_preferences> diff --git a/release/scripts/presets/interface_theme/ubuntu_ambiance.xml b/release/scripts/presets/interface_theme/ubuntu_ambiance.xml index 40e311c552f..3897c41f808 100644 --- a/release/scripts/presets/interface_theme/ubuntu_ambiance.xml +++ b/release/scripts/presets/interface_theme/ubuntu_ambiance.xml @@ -11,6 +11,7 @@ bone_pose="#50c8ff" bone_solid="#c8c8c8" bundle_solid="#c8c8c8" + camera="#000000" camera_path="#000000" frame_current="#60c040" edge_crease="#ce33b8" @@ -19,6 +20,7 @@ edge_select="#f68d46" edge_sharp="#ff4c00" edge_facesel="#4b4b4b" + empty="#000000" face="#75757512" extra_face_angle="#002000" extra_face_area="#0059ee" @@ -404,6 +406,7 @@ </properties> <sequence_editor> <ThemeSequenceEditor audio_strip="#2e8f8f" + movieclip_strip="#20208f" frame_current="#c06e11" draw_action="#50c8ff" effect_strip="#a9547c" @@ -413,6 +416,7 @@ meta_strip="#6d9183" movie_strip="#516987" plugin_strip="#7e7e50" + preview_back="#000000" scene_strip="#4e983e" transition_strip="#a25f6f" window_sliders="#a0a0a0"> @@ -434,13 +438,12 @@ </sequence_editor> <text_editor> <ThemeTextEditor cursor="#df5106" + syntax_special="#8c8c28" line_numbers_background="#3c3b37" - scroll_bar="#696965" selected_text="#ffffff" syntax_builtin="#df3ac2" syntax_comment="#249d60" syntax_numbers="#3c68ff" - syntax_special="#8c8c28" syntax_string="#aa2694"> <space> <ThemeSpaceGeneric header="#464541" @@ -687,6 +690,18 @@ text_sel="#f47421"> </ThemeWidgetColors> </wcol_tool> + <wcol_tooltip> + <ThemeWidgetColors inner="#191919e6" + inner_sel="#2d2d2de6" + item="#646464ff" + outline="#000000" + shadedown="-20" + shadetop="25" + show_shaded="FALSE" + text="#ffffff" + text_sel="#ffffff"> + </ThemeWidgetColors> + </wcol_tooltip> </ThemeUserInterface> </user_interface> <user_preferences> diff --git a/release/scripts/presets/keyconfig/maya.py b/release/scripts/presets/keyconfig/maya.py index 5e1e5d0d778..fe011a51e22 100644 --- a/release/scripts/presets/keyconfig/maya.py +++ b/release/scripts/presets/keyconfig/maya.py @@ -134,25 +134,45 @@ kmi.properties.data_path = 'space_data.viewport_shade' kmi.properties.value_1 = 'TEXTURED' kmi.properties.value_2 = 'SOLID' kmi = km.keymap_items.new('view3d.select', 'SELECTMOUSE', 'PRESS') +kmi.properties.extend = False +kmi.properties.center = False +kmi.properties.object = False +kmi.properties.enumerate = False kmi = km.keymap_items.new('view3d.select', 'SELECTMOUSE', 'PRESS', shift=True) kmi.properties.extend = True +kmi.properties.center = False +kmi.properties.object = False +kmi.properties.enumerate = False kmi = km.keymap_items.new('view3d.select', 'SELECTMOUSE', 'PRESS', ctrl=True) +kmi.properties.extend = False kmi.properties.center = True +kmi.properties.object = False +kmi.properties.enumerate = False kmi = km.keymap_items.new('view3d.select', 'SELECTMOUSE', 'PRESS', alt=True) +kmi.properties.extend = False +kmi.properties.center = False +kmi.properties.object = False kmi.properties.enumerate = True kmi = km.keymap_items.new('view3d.select', 'SELECTMOUSE', 'PRESS', shift=True, ctrl=True) -kmi.properties.center = True kmi.properties.extend = True +kmi.properties.center = True +kmi.properties.object = False +kmi.properties.enumerate = False kmi = km.keymap_items.new('view3d.select', 'SELECTMOUSE', 'PRESS', ctrl=True, alt=True) +kmi.properties.extend = False kmi.properties.center = True +kmi.properties.object = False kmi.properties.enumerate = True kmi = km.keymap_items.new('view3d.select', 'SELECTMOUSE', 'PRESS', shift=True, alt=True) -kmi.properties.enumerate = True kmi.properties.extend = True +kmi.properties.center = False +kmi.properties.object = False +kmi.properties.enumerate = True kmi = km.keymap_items.new('view3d.select', 'SELECTMOUSE', 'PRESS', shift=True, ctrl=True, alt=True) +kmi.properties.extend = True kmi.properties.center = True +kmi.properties.object = False kmi.properties.enumerate = True -kmi.properties.extend = True kmi = km.keymap_items.new('view3d.select_border', 'EVT_TWEAK_S', 'ANY') kmi.properties.extend = False kmi = km.keymap_items.new('view3d.select_lasso', 'EVT_TWEAK_A', 'ANY', ctrl=True) @@ -164,7 +184,7 @@ kmi = km.keymap_items.new('view3d.zoom_border', 'B', 'PRESS', shift=True) kmi = km.keymap_items.new('view3d.render_border', 'B', 'PRESS', shift=True) kmi = km.keymap_items.new('view3d.camera_to_view', 'NUMPAD_0', 'PRESS', ctrl=True, alt=True) kmi = km.keymap_items.new('view3d.object_as_camera', 'NUMPAD_0', 'PRESS', ctrl=True) -kmi = km.keymap_items.new('wm.call_menu', 'S', 'PRESS', shift=True) +kmi = km.keymap_items.new('wm.call_menu', 'S', 'PRESS', shift=True, ctrl=True) kmi.properties.name = 'VIEW3D_MT_snap' kmi = km.keymap_items.new('wm.context_set_enum', 'COMMA', 'PRESS') kmi.properties.data_path = 'space_data.pivot_point' @@ -333,7 +353,7 @@ kmi = km.keymap_items.new('mesh.fill', 'F', 'PRESS', alt=True) kmi = km.keymap_items.new('mesh.beautify_fill', 'F', 'PRESS', shift=True, alt=True) kmi = km.keymap_items.new('mesh.quads_convert_to_tris', 'T', 'PRESS', ctrl=True) kmi = km.keymap_items.new('mesh.tris_convert_to_quads', 'J', 'PRESS', alt=True) -kmi = km.keymap_items.new('mesh.edge_flip', 'F', 'PRESS', shift=True, ctrl=True) +# kmi = km.keymap_items.new('mesh.edge_flip', 'F', 'PRESS', shift=True, ctrl=True) # removed since bmesh, can be made into something else? kmi = km.keymap_items.new('mesh.rip_move', 'V', 'PRESS') kmi = km.keymap_items.new('mesh.merge', 'M', 'PRESS', alt=True) kmi = km.keymap_items.new('transform.shrink_fatten', 'S', 'PRESS', ctrl=True, alt=True) @@ -346,9 +366,10 @@ kmi = km.keymap_items.new('mesh.split', 'Y', 'PRESS') kmi = km.keymap_items.new('mesh.dupli_extrude_cursor', 'ACTIONMOUSE', 'CLICK', ctrl=True) kmi = km.keymap_items.new('mesh.delete', 'X', 'PRESS') kmi = km.keymap_items.new('mesh.delete', 'DEL', 'PRESS') -kmi = km.keymap_items.new('mesh.knife_cut', 'LEFTMOUSE', 'PRESS', key_modifier='K') -kmi = km.keymap_items.new('mesh.knife_cut', 'LEFTMOUSE', 'PRESS', shift=True, key_modifier='K') -kmi.properties.type = 'MIDPOINTS' +kmi = km.keymap_items.new('mesh.knifetool', 'LEFTMOUSE', 'PRESS', key_modifier='K') +# BMESH_TODO: midpoints for knife were moved to modal keymap +#kmi = km.keymap_items.new('mesh.knifetool', 'LEFTMOUSE', 'PRESS', shift=True, key_modifier='K') +#kmi.properties.type = 'MIDPOINTS' kmi = km.keymap_items.new('object.vertex_parent_set', 'P', 'PRESS', ctrl=True) kmi = km.keymap_items.new('wm.call_menu', 'W', 'PRESS', ctrl=True) kmi.properties.name = 'VIEW3D_MT_edit_mesh_specials' @@ -376,5 +397,17 @@ kmi.properties.value_1 = 'DISABLED' kmi.properties.value_2 = 'CONNECTED' kmi = km.keymap_items.new('mesh.select_all', 'SELECTMOUSE', 'CLICK') kmi.properties.action = 'DESELECT' +kmi = km.keymap_items.new('object.subdivision_set', 'ZERO', 'PRESS', ctrl=True) +kmi.properties.level = 0 +kmi = km.keymap_items.new('object.subdivision_set', 'ONE', 'PRESS', ctrl=True) +kmi.properties.level = 1 +kmi = km.keymap_items.new('object.subdivision_set', 'TWO', 'PRESS', ctrl=True) +kmi.properties.level = 2 +kmi = km.keymap_items.new('object.subdivision_set', 'THREE', 'PRESS', ctrl=True) +kmi.properties.level = 3 +kmi = km.keymap_items.new('object.subdivision_set', 'FOUR', 'PRESS', ctrl=True) +kmi.properties.level = 4 +kmi = km.keymap_items.new('object.subdivision_set', 'FIVE', 'PRESS', ctrl=True) +kmi.properties.level = 5 wm.keyconfigs.active = kc diff --git a/release/scripts/startup/bl_operators/add_mesh_torus.py b/release/scripts/startup/bl_operators/add_mesh_torus.py index 5b28cdf44ae..75a6cd73d64 100644 --- a/release/scripts/startup/bl_operators/add_mesh_torus.py +++ b/release/scripts/startup/bl_operators/add_mesh_torus.py @@ -21,6 +21,13 @@ import bpy from bpy.types import Operator import mathutils +from bpy.props import (FloatProperty, + IntProperty, + BoolProperty, + ) + +from bpy_extras import object_utils + def add_torus(major_rad, minor_rad, major_seg, minor_seg): from math import cos, sin, pi @@ -75,14 +82,8 @@ def add_torus(major_rad, minor_rad, major_seg, minor_seg): return verts, faces -from bpy.props import (FloatProperty, - IntProperty, - BoolProperty, - FloatVectorProperty, - ) - -class AddTorus(Operator): +class AddTorus(Operator, object_utils.AddObjectHelper): '''Add a torus mesh''' bl_idname = "mesh.primitive_torus_add" bl_label = "Add Torus" @@ -131,42 +132,32 @@ class AddTorus(Operator): 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', - ) - def execute(self, context): - if self.use_abso == True: extra_helper = (self.abso_major_rad - self.abso_minor_rad) * 0.5 self.major_radius = self.abso_minor_rad + extra_helper self.minor_radius = extra_helper verts_loc, faces = add_torus(self.major_radius, - self.minor_radius, - self.major_segments, - self.minor_segments) + self.minor_radius, + self.major_segments, + self.minor_segments) mesh = bpy.data.meshes.new("Torus") mesh.vertices.add(len(verts_loc) // 3) - mesh.faces.add(len(faces) // 4) + + nbr_loops = len(faces) + nbr_polys = nbr_loops // 4 + mesh.loops.add(nbr_loops) + mesh.polygons.add(nbr_polys) mesh.vertices.foreach_set("co", verts_loc) - mesh.faces.foreach_set("vertices_raw", faces) + mesh.polygons.foreach_set("loop_start", range(0, nbr_loops, 4)) + mesh.polygons.foreach_set("loop_total", (4,) * nbr_polys) + mesh.loops.foreach_set("vertex_index", faces) mesh.update() - from bpy_extras import object_utils object_utils.object_data_add(context, mesh, operator=self) return {'FINISHED'} diff --git a/release/scripts/startup/bl_operators/anim.py b/release/scripts/startup/bl_operators/anim.py index d26a7728af1..2689cfda8eb 100644 --- a/release/scripts/startup/bl_operators/anim.py +++ b/release/scripts/startup/bl_operators/anim.py @@ -67,15 +67,16 @@ class ANIM_OT_keying_set_export(Operator): scene = context.scene ks = scene.keying_sets.active - f.write("# Keying Set: %s\n" % ks.name) + f.write("# Keying Set: %s\n" % ks.bl_idname) f.write("import bpy\n\n") - # XXX, why not current scene? - f.write("scene= bpy.data.scenes[0]\n\n") + f.write("scene = bpy.context.scene\n\n") # Add KeyingSet and set general settings f.write("# Keying Set Level declarations\n") - f.write("ks= scene.keying_sets.new(name=\"%s\")\n" % ks.name) + f.write("ks = scene.keying_sets.new(idname=\"%s\", name=\"%s\")\n" + "" % (ks.bl_idname, ks.bl_label)) + f.write("ks.bl_description = \"%s\"\n" % ks.bl_description) if not ks.is_path_absolute: f.write("ks.is_path_absolute = False\n") diff --git a/release/scripts/startup/bl_operators/clip.py b/release/scripts/startup/bl_operators/clip.py index 7a80b432c3a..ffa66274f12 100644 --- a/release/scripts/startup/bl_operators/clip.py +++ b/release/scripts/startup/bl_operators/clip.py @@ -99,11 +99,11 @@ def CLIP_default_settings_from_track(clip, track): pattern = track.pattern_max - track.pattern_min search = track.search_max - track.search_min - pattern[0] = pattern[0] * clip.size[0] - pattern[1] = pattern[1] * clip.size[1] + pattern[0] = pattern[0] * width + pattern[1] = pattern[1] * height - search[0] = search[0] * clip.size[0] - search[1] = search[1] * clip.size[1] + search[0] = search[0] * width + search[1] = search[1] * height settings.default_tracker = track.tracker settings.default_pyramid_levels = track.pyramid_levels @@ -709,17 +709,23 @@ class CLIP_OT_setup_tracking_scene(Operator): @staticmethod def _createMesh(scene, name, vertices, faces): - from bpy_extras.io_utils import unpack_list, unpack_face_list + from bpy_extras.io_utils import unpack_list mesh = bpy.data.meshes.new(name=name) mesh.vertices.add(len(vertices)) mesh.vertices.foreach_set("co", unpack_list(vertices)) - mesh.faces.add(len(faces)) - mesh.faces.foreach_set("vertices_raw", unpack_face_list(faces)) + nbr_loops = len(faces) + nbr_polys = nbr_loops // 4 + mesh.loops.add(nbr_loops) + mesh.polygons.add(nbr_polys) + + mesh.polygons.foreach_set("loop_start", range(0, nbr_loops, 4)) + mesh.polygons.foreach_set("loop_total", (4,) * nbr_polys) + mesh.loops.foreach_set("vertex_index", faces) - mesh.update(calc_edges=True) + mesh.update() ob = bpy.data.objects.new(name=name, object_data=mesh) @@ -737,7 +743,7 @@ class CLIP_OT_setup_tracking_scene(Operator): def _createGround(self, scene): vertices = self._getPlaneVertices(4.0, 0.0) - faces = [(0, 1, 2, 3)] + faces = [0, 1, 2, 3] ob = self._createMesh(scene, "Ground", vertices, faces) ob["is_ground"] = True @@ -775,12 +781,12 @@ class CLIP_OT_setup_tracking_scene(Operator): def _createSampleObject(self, scene): vertices = self._getPlaneVertices(1.0, -1.0) + \ self._getPlaneVertices(1.0, 1.0) - faces = ((0, 1, 2, 3), - (4, 7, 6, 5), - (0, 4, 5, 1), - (1, 5, 6, 2), - (2, 6, 7, 3), - (3, 7, 4, 0)) + faces = (0, 1, 2, 3, + 4, 7, 6, 5, + 0, 4, 5, 1, + 1, 5, 6, 2, + 2, 6, 7, 3, + 3, 7, 4, 0) return self._createMesh(scene, "Cube", vertices, faces) diff --git a/release/scripts/startup/bl_operators/image.py b/release/scripts/startup/bl_operators/image.py index 4c04aa3b7f3..1b7d5e3a40d 100644 --- a/release/scripts/startup/bl_operators/image.py +++ b/release/scripts/startup/bl_operators/image.py @@ -67,7 +67,7 @@ class EditExternally(Operator): self.report({'ERROR'}, "Image path not set") return {'CANCELLED'} - if not os.path.exists(filepath): + if not os.path.exists(filepath) or not os.path.isfile(filepath): self.report({'ERROR'}, "Image path %r not found, image may be packed or " "unsaved" % filepath) @@ -96,6 +96,10 @@ class EditExternally(Operator): self.report({'ERROR'}, "Context incorrect, image not found") return {'CANCELLED'} + if image.packed_file: + self.report({'ERROR'}, "Image is packed, unpack before editing") + return {'CANCELLED'} + filepath = bpy.path.abspath(image.filepath, library=image.library) self.filepath = os.path.normpath(filepath) diff --git a/release/scripts/startup/bl_operators/mesh.py b/release/scripts/startup/bl_operators/mesh.py index 3e206017238..2d4c703dbf2 100644 --- a/release/scripts/startup/bl_operators/mesh.py +++ b/release/scripts/startup/bl_operators/mesh.py @@ -24,50 +24,6 @@ from bpy.types import Operator from bpy.props import EnumProperty -class MeshSelectInteriorFaces(Operator): - '''Select faces where all edges have more than 2 face users''' - - bl_idname = "mesh.faces_select_interior" - bl_label = "Select Interior Faces" - bl_options = {'REGISTER', 'UNDO'} - - @classmethod - def poll(cls, context): - ob = context.active_object - return (ob and ob.type == 'MESH') - - def execute(self, context): - from bpy_extras import mesh_utils - ob = context.active_object - context.tool_settings.mesh_select_mode = False, False, True - is_editmode = (ob.mode == 'EDIT') - if is_editmode: - bpy.ops.object.mode_set(mode='OBJECT', toggle=False) - - mesh = ob.data - - face_list = mesh.faces[:] - face_edge_keys = [face.edge_keys for face in face_list] - - edge_face_count = mesh_utils.edge_face_count_dict(mesh) - - def test_interior(index): - for key in face_edge_keys[index]: - if edge_face_count[key] < 3: - return False - return True - - for index, face in enumerate(face_list): - if(test_interior(index)): - face.select = True - else: - face.select = False - - if is_editmode: - bpy.ops.object.mode_set(mode='EDIT', toggle=False) - return {'FINISHED'} - - class MeshMirrorUV(Operator): '''Copy mirror UV coordinates on the X axis based on a mirrored mesh''' bl_idname = "mesh.faces_mirror_uv" @@ -99,7 +55,7 @@ class MeshMirrorUV(Operator): mirror_gt = {} mirror_lt = {} - vcos = [v.co.to_tuple(5) for v in mesh.vertices] + vcos = (v.co.to_tuple(5) for v in mesh.vertices) for i, co in enumerate(vcos): if co[0] > 0.0: @@ -120,50 +76,60 @@ class MeshMirrorUV(Operator): if j is not None: vmap[i] = j - 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] - - # as a list - faces = mesh.faces[:] - - fuvsel = [(False not in uv.select_uv) for uv in active_uv_layer] - fcents = [f.center for f in faces] - - # find mirror faces - mirror_fm = {} - for i, f in enumerate(faces): - verts = list(f.vertices) - verts.sort() - verts = tuple(verts) - mirror_fm[verts] = i - - fmap = {} - for i, f in enumerate(faces): - verts = [vmap.get(j) for j in f.vertices] - if None not in verts: - verts.sort() - j = mirror_fm.get(tuple(verts)) + polys = mesh.polygons + loops = mesh.loops + verts = mesh.vertices + uv_loops = mesh.uv_loop_layers.active.data + nbr_polys = len(polys) + + mirror_pm = {} + pmap = {} + puvs = [None] * nbr_polys + puvs_cpy = [None] * nbr_polys + puvsel = [None] * nbr_polys + pcents = [None] * nbr_polys + vidxs = [None] * nbr_polys + for i, p in enumerate(polys): + lstart = lend = p.loop_start + lend += p.loop_total + puvs[i] = tuple(uv.uv for uv in uv_loops[lstart:lend]) + puvs_cpy[i] = tuple(uv.copy() for uv in puvs[i]) + puvsel[i] = (False not in + (uv.select for uv in uv_loops[lstart:lend])) + # Vert idx of the poly. + vidxs[i] = tuple(sorted(l.vertex_index + for l in loops[lstart:lend])) + # As we have no poly.center yet... + pcents[i] = tuple(map(lambda x : x / p.loop_total, + map(sum, zip(*(verts[idx].co + for idx in vidxs[i]))))) + # Preparing next step finding matching polys. + mirror_pm[vidxs[i]] = i + + for i in range(nbr_polys): + # Find matching mirror poly. + tvidxs = [vmap.get(j) for j in vidxs[i]] + if None not in tvidxs: + tvidxs.sort() + j = mirror_pm.get(tuple(tvidxs)) if j is not None: - fmap[i] = j - - for i, j in fmap.items(): + pmap[i] = j - if not fuvsel[i] or not fuvsel[j]: + for i, j in pmap.items(): + if not puvsel[i] or not puvsel[j]: continue - elif DIR == 0 and fcents[i][0] < 0.0: + elif DIR == 0 and pcents[i][0] < 0.0: continue - elif DIR == 1 and fcents[i][0] > 0.0: + elif DIR == 1 and pcents[i][0] > 0.0: continue # copy UVs - uv1 = fuvs[i] - uv2 = fuvs_cpy[j] + uv1 = puvs[i] + uv2 = puvs_cpy[j] # get the correct rotation - v1 = faces[j].vertices[:] - v2 = [vmap[k] for k in faces[i].vertices[:]] + v1 = vidxs[j] + v2 = tuple(vmap[k] for k in vidxs[i]) if len(v1) == len(v2): for k in range(len(v1)): diff --git a/release/scripts/startup/bl_operators/object.py b/release/scripts/startup/bl_operators/object.py index 019cd37066c..4ade55c0af6 100644 --- a/release/scripts/startup/bl_operators/object.py +++ b/release/scripts/startup/bl_operators/object.py @@ -27,7 +27,7 @@ from bpy.props import (StringProperty, class SelectPattern(Operator): - '''Select object matching a naming pattern''' + '''Select objects matching a naming pattern''' bl_idname = "object.select_pattern" bl_label = "Select Pattern" bl_options = {'REGISTER', 'UNDO'} @@ -125,7 +125,7 @@ class SelectCamera(Operator): class SelectHierarchy(Operator): - '''Select object relative to the active object's position''' \ + '''Select object relative to the active object's position ''' \ '''in the hierarchy''' bl_idname = "object.select_hierarchy" bl_label = "Select Hierarchy" @@ -367,79 +367,25 @@ class ShapeTransfer(Operator): (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], - ) - 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], - ) - 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], - ) - 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], - ) - 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], - ) - 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], - ) - 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], + loops_vidxs = me.loops.foreach_get("vert_index") + for poly in me.polygons: + l_start = l_stop = poly.loop_start + l_stop += poly.loop_total + idxs = loops_vidxs[l_start:l_stop] + v_before = idxs[-2] + v = idxs[-1] + for v_after in idxs: + pt = barycentric_transform(orig_shape_coords[v], + orig_coords[v_before], + orig_coords[v], + orig_coords[v_after], + target_coords[v_before], + target_coords[v], + target_coords[v_after], ) - median_coords[i3].append(pt) + median_coords[v].append(pt) + v_before = v + v = v_after elif mode == 'RELATIVE_EDGE': for ed in me.edges: @@ -539,11 +485,11 @@ class JoinUVs(Operator): "Object: %s, Mesh: '%s' has no UVs" % (obj.name, mesh.name)) else: - len_faces = len(mesh.faces) + nbr_loops = len(mesh.loops) # 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) + uv_array = array.array('f', [0.0] * 2) * nbr_loops + mesh.uv_loop_layers.active.data.foreach_get("uv", uv_array) objects = context.selected_editable_objects[:] @@ -558,22 +504,33 @@ class JoinUVs(Operator): if mesh_other.tag == False: mesh_other.tag = True - if len(mesh_other.faces) != len_faces: + if len(mesh_other.loops) != nbr_loops: self.report({'WARNING'}, "Object: %s, Mesh: " - "'%s' has %d faces, expected %d\n" + "'%s' has %d loops (for %d faces)," + " expected %d\n" % (obj_other.name, mesh_other.name, - len(mesh_other.faces), - len_faces), - ) + len(mesh_other.loops), + len(mesh_other.polygons), + nbr_loops, + ), + ) else: - uv_other = mesh_other.uv_textures.active + uv_other = mesh_other.uv_loop_layers.active if not uv_other: - # should return the texture it adds - uv_other = mesh_other.uv_textures.new() + mesh_other.uv_textures.new() + uv_other = mesh_other.uv_loop_layers.active + if not uv_other: + self.report({'ERROR'}, "Could not add " + "a new UV map tp object " + "'%s' (Mesh '%s')\n" + % (obj_other.name, + mesh_other.name, + ), + ) # finally do the copy - uv_other.data.foreach_set("uv_raw", uv_array) + uv_other.data.foreach_set("uv", uv_array) if is_editmode: bpy.ops.object.mode_set(mode='EDIT', toggle=False) @@ -616,16 +573,21 @@ class MakeDupliFace(Operator): face_verts = [axis for obj in objects for v in matrix_to_quad(obj.matrix_world) for axis in v] + nbr_verts = len(face_verts) // 3 + nbr_faces = nbr_verts // 4 - faces = list(range(len(face_verts) // 3)) + faces = list(range(nbr_verts)) mesh = bpy.data.meshes.new(data.name + "_dupli") - mesh.vertices.add(len(face_verts) // 3) - mesh.faces.add(len(face_verts) // 12) + mesh.vertices.add(nbr_verts) + mesh.loops.add(nbr_faces * 4) # Safer than nbr_verts. + mesh.polygons.add(nbr_faces) mesh.vertices.foreach_set("co", face_verts) - mesh.faces.foreach_set("vertices_raw", faces) + mesh.loops.foreach_set("vertex_index", faces) + mesh.polygons.foreach_set("loop_start", range(0, nbr_faces * 4, 4)) + mesh.polygons.foreach_set("loop_total", (4,) * nbr_faces) mesh.update() # generates edge data # pick an object to use @@ -729,3 +691,29 @@ class TransformsToDeltasAnim(Operator): context.scene.frame_set(context.scene.frame_current) return {'FINISHED'} + + +class DupliOffsetFromCursor(Operator): + '''Set offset used for DupliGroup based on cursor position''' + bl_idname = "object.dupli_offset_from_cursor" + bl_label = "Set Offset From Cursor" + bl_options = {'REGISTER', 'UNDO'} + + group = IntProperty( + name="Group", + description="Group index to set offset for", + default=0, + ) + + @classmethod + def poll(cls, context): + return context.active_object is not None + + def execute(self, context): + scene = context.scene + ob = context.active_object + group = self.group + + ob.users_group[group].dupli_offset = scene.cursor_location + + return {'FINISHED'} diff --git a/release/scripts/startup/bl_operators/object_randomize_transform.py b/release/scripts/startup/bl_operators/object_randomize_transform.py index d3d70f892b8..834df04fe01 100644 --- a/release/scripts/startup/bl_operators/object_randomize_transform.py +++ b/release/scripts/startup/bl_operators/object_randomize_transform.py @@ -92,7 +92,6 @@ def randomize_selected(seed, delta, loc, rot, scale, scale_even, scale_min): from bpy.props import (IntProperty, BoolProperty, FloatVectorProperty) -from math import pi class RandomizeLocRotSize(Operator): @@ -136,8 +135,8 @@ class RandomizeLocRotSize(Operator): rot = FloatVectorProperty( name="Rotation", description="Maximun rotation over each axis", - min=-pi, - max=pi, + min=-3.141592, # math.pi + max=+3.141592, default=(0.0, 0.0, 0.0), subtype='EULER', ) diff --git a/release/scripts/startup/bl_operators/presets.py b/release/scripts/startup/bl_operators/presets.py index 1a17cd9f000..da6ef7483f2 100644 --- a/release/scripts/startup/bl_operators/presets.py +++ b/release/scripts/startup/bl_operators/presets.py @@ -20,6 +20,7 @@ import bpy from bpy.types import Menu, Operator +from bpy.props import StringProperty, BoolProperty class AddPresetBase(): @@ -31,13 +32,13 @@ class AddPresetBase(): # bl_label = "Add a Python Preset" bl_options = {'REGISTER'} # only because invoke_props_popup requires. - name = bpy.props.StringProperty( + name = StringProperty( name="Name", description="Name of the preset, used to make the path name", maxlen=64, options={'SKIP_SAVE'}, ) - remove_active = bpy.props.BoolProperty( + remove_active = BoolProperty( default=False, options={'HIDDEN', 'SKIP_SAVE'}, ) @@ -166,12 +167,10 @@ class ExecutePreset(Operator): 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, + filepath = StringProperty( + subtype='FILE_PATH', ) - menu_idname = bpy.props.StringProperty( + menu_idname = StringProperty( name="Menu ID Name", description="ID name of the menu this was called from", ) @@ -456,7 +455,7 @@ class AddPresetOperator(AddPresetBase, Operator): bl_label = "Operator Preset" preset_menu = "WM_MT_operator_presets" - operator = bpy.props.StringProperty( + operator = StringProperty( name="Operator", maxlen=64, options={'HIDDEN'}, diff --git a/release/scripts/startup/bl_operators/uvcalc_follow_active.py b/release/scripts/startup/bl_operators/uvcalc_follow_active.py index 748255671dd..99ae5a3e436 100644 --- a/release/scripts/startup/bl_operators/uvcalc_follow_active.py +++ b/release/scripts/startup/bl_operators/uvcalc_follow_active.py @@ -30,6 +30,7 @@ def extend(obj, operator, EXTEND_MODE): me = obj.data me_verts = me.vertices + # script will fail without UVs if not me.uv_textures: me.uv_textures.new() @@ -52,17 +53,15 @@ def extend(obj, operator, EXTEND_MODE): ''' def face_edge_vs(vi): - # assume a quad - return [(vi[0], vi[1]), (vi[1], vi[2]), (vi[2], vi[3]), (vi[3], vi[0])] + vlen = len(vi) + return [(vi[i], vi[(i + 1) % vlen]) for i in range(vlen)] vidx_source = face_source.vertices vidx_target = face_target.vertices - faceUVsource = me.uv_textures.active.data[face_source.index] - uvs_source = [faceUVsource.uv1, faceUVsource.uv2, faceUVsource.uv3, faceUVsource.uv4] - - faceUVtarget = me.uv_textures.active.data[face_target.index] - uvs_target = [faceUVtarget.uv1, faceUVtarget.uv2, faceUVtarget.uv3, faceUVtarget.uv4] + uv_layer = me.uv_loop_layers.active.data + uvs_source = [uv_layer[i].uv for i in face_source.loop_indices] + uvs_target = [uv_layer[i].uv for i in face_target.loop_indices] # vertex index is the key, uv is the value @@ -135,15 +134,12 @@ def extend(obj, operator, EXTEND_MODE): uvs_vhash_target[edgepair_outer_target[iB]][:] = uvs_vhash_source[edgepair_inner_source[0]] + (uvs_vhash_source[edgepair_inner_source[0]] - uvs_vhash_source[edgepair_outer_source[1]]) uvs_vhash_target[edgepair_outer_target[iA]][:] = uvs_vhash_source[edgepair_inner_source[1]] + (uvs_vhash_source[edgepair_inner_source[1]] - uvs_vhash_source[edgepair_outer_source[0]]) - if not me.uv_textures: - me.uv_textures.new() - - face_act = me.faces.active + face_act = me.polygons.active if face_act == -1: operator.report({'ERROR'}, "No active face") return - face_sel = [f for f in me.faces if len(f.vertices) == 4 and f.select] + face_sel = [f for f in me.polygons if len(f.vertices) == 4 and f.select] face_act_local_index = -1 for i, f in enumerate(face_sel): @@ -172,7 +168,7 @@ def extend(obj, operator, EXTEND_MODE): edge_faces[edkey] = [i] if EXTEND_MODE == 'LENGTH': - edge_loops = mesh_utils.edge_loops_from_faces(me, face_sel, [ed.key for ed in me.edges if ed.use_seam]) + edge_loops = mesh_utils.edge_loops_from_tessfaces(me, face_sel, [ed.key for ed in me.edges if ed.use_seam]) me_verts = me.vertices for loop in edge_loops: looplen = [0.0] diff --git a/release/scripts/startup/bl_operators/uvcalc_lightmap.py b/release/scripts/startup/bl_operators/uvcalc_lightmap.py index 3159466c5ca..08f471e9022 100644 --- a/release/scripts/startup/bl_operators/uvcalc_lightmap.py +++ b/release/scripts/startup/bl_operators/uvcalc_lightmap.py @@ -88,8 +88,8 @@ class prettyface(object): self.children = [] else: # blender face - # self.uv = data.uv - self.uv = data.id_data.uv_textures.active.data[data.index].uv # XXX25 + uv_layer = data.id_data.uv_loop_layers.active.data + self.uv = [uv_layer[i].uv for i in data.loops] # cos = [v.co for v in data] cos = [data.id_data.vertices[v].co for v in data.vertices] # XXX25 @@ -158,7 +158,8 @@ class prettyface(object): I = [i for a, i in angles_co] #~ fuv = f.uv - fuv = f.id_data.uv_textures.active.data[f.index].uv # XXX25 + uv_layer = f.id_data.uv_loop_layers.active.data + fuv = [uv_layer[i].uv for i in f.loops] # XXX25 if self.rot: fuv[I[2]] = p1 @@ -219,15 +220,10 @@ def lightmap_uvpack(meshes, face_groups = [] for me in meshes: - # Add face UV if it does not exist. - # All new faces are selected. - if not me.uv_textures: - me.uv_textures.new() - if PREF_SEL_ONLY: - faces = [f for f in me.faces if f.select] + faces = [f for f in me.polygons if f.select] else: - faces = me.faces[:] + faces = me.polygons[:] if PREF_PACK_IN_ONE: face_groups[0].extend(faces) @@ -237,6 +233,11 @@ def lightmap_uvpack(meshes, if PREF_NEW_UVLAYER: me.uv_textures.new() + # Add face UV if it does not exist. + # All new faces are selected. + if not me.uv_textures: + me.uv_textures.new() + for face_sel in face_groups: print("\nStarting unwrap") @@ -528,7 +529,7 @@ def unwrap(operator, context, **kwargs): if obj and obj.type == 'MESH': meshes = [obj.data] else: - 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}) + meshes = list({me for obj in context.selected_objects if obj.type == 'MESH' for me in (obj.data,) if me.polygons and me.library is None}) if not meshes: operator.report({'ERROR'}, "No mesh object") diff --git a/release/scripts/startup/bl_operators/uvcalc_smart_project.py b/release/scripts/startup/bl_operators/uvcalc_smart_project.py index 622d19a0cfa..bb3086f711b 100644 --- a/release/scripts/startup/bl_operators/uvcalc_smart_project.py +++ b/release/scripts/startup/bl_operators/uvcalc_smart_project.py @@ -757,12 +757,9 @@ def VectoQuat(vec): class thickface(object): __slost__= "v", "uv", "no", "area", "edge_keys" - def __init__(self, face, uvface, mesh_verts): + def __init__(self, face, uv_layer, mesh_verts): self.v = [mesh_verts[i] for i in face.vertices] - if len(self.v)==4: - self.uv = uvface.uv1, uvface.uv2, uvface.uv3, uvface.uv4 - else: - self.uv = uvface.uv1, uvface.uv2, uvface.uv3 + self.uv = [uv_layer[i].uv for i in face.loop_indices] self.no = face.normal self.area = face.area @@ -892,13 +889,13 @@ def main(context, if not me.uv_textures: # Mesh has no UV Coords, don't bother. me.uv_textures.new() - uv_layer = me.uv_textures.active.data + uv_layer = me.uv_loop_layers.active.data me_verts = list(me.vertices) if USER_ONLY_SELECTED_FACES: - meshFaces = [thickface(f, uv_layer[i], me_verts) for i, f in enumerate(me.faces) if f.select] + meshFaces = [thickface(f, uv_layer, me_verts) for i, f in enumerate(me.polygons) if f.select] else: - meshFaces = [thickface(f, uv_layer[i], me_verts) for i, f in enumerate(me.faces)] + meshFaces = [thickface(f, uv_layer, me_verts) for i, f in enumerate(me.polygons)] if not meshFaces: continue @@ -1117,7 +1114,7 @@ class SmartProject(Operator): angle_limit = FloatProperty( name="Angle Limit", - description="lower for more projection groups, higher for less distortion", + description="Lower for more projection groups, higher for less distortion", min=1.0, max=89.0, default=66.0, ) diff --git a/release/scripts/startup/bl_operators/vertexpaint_dirt.py b/release/scripts/startup/bl_operators/vertexpaint_dirt.py index 85be72b48d8..bfbde2f4b07 100644 --- a/release/scripts/startup/bl_operators/vertexpaint_dirt.py +++ b/release/scripts/startup/bl_operators/vertexpaint_dirt.py @@ -26,8 +26,6 @@ def applyVertexDirt(me, blur_iterations, blur_strength, clamp_dirt, clamp_clean, from mathutils import Vector from math import acos - #BPyMesh.meshCalcNormals(me) - vert_tone = [0.0] * len(me.vertices) min_tone = 180.0 @@ -95,7 +93,7 @@ def applyVertexDirt(me, blur_iterations, blur_strength, clamp_dirt, clamp_clean, tone_range = max_tone - min_tone if not tone_range: - return + return {'CANCELLED'} active_col_layer = None @@ -109,18 +107,17 @@ def applyVertexDirt(me, blur_iterations, blur_strength, clamp_dirt, clamp_clean, active_col_layer = me.vertex_colors[0].data if not active_col_layer: - return('CANCELLED', ) - - for i, f in enumerate(me.faces): - if not me.use_paint_mask or f.select: - - f_col = active_col_layer[i] + return - f_col = [f_col.color1, f_col.color2, f_col.color3, f_col.color4] + use_paint_mask = me.use_paint_mask - for j, v in enumerate(f.vertices): - col = f_col[j] - tone = vert_tone[me.vertices[v].index] + for i, p in enumerate(me.polygons): + if not use_paint_mask or p.select: + for loop_index in p.loop_indices: + loop = me.loops[loop_index] + v = loop.vertex_index + col = active_col_layer[loop_index].color + tone = vert_tone[v] tone = (tone - min_tone) / tone_range if dirt_only: @@ -131,6 +128,8 @@ def applyVertexDirt(me, blur_iterations, blur_strength, clamp_dirt, clamp_clean, col[1] = tone * col[1] col[2] = tone * col[2] + return {'FINISHED'} + import bpy from bpy.types import Operator @@ -156,19 +155,19 @@ class VertexPaintDirt(Operator): ) clean_angle = FloatProperty( name="Highlight Angle", - description="Less then 90 limits the angle used in the tonal range", + description="Less than 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", + description="Less than 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", + description="Don't calculate cleans for convex areas", default=False, ) @@ -185,8 +184,8 @@ class VertexPaintDirt(Operator): t = time.time() - applyVertexDirt(mesh, self.blur_iterations, self.blur_strength, radians(self.dirt_angle), radians(self.clean_angle), self.dirt_only) + ret = applyVertexDirt(mesh, self.blur_iterations, self.blur_strength, radians(self.dirt_angle), radians(self.clean_angle), self.dirt_only) print('Dirt calculated in %.6f' % (time.time() - t)) - return {'FINISHED'} + return ret diff --git a/release/scripts/startup/bl_operators/view3d.py b/release/scripts/startup/bl_operators/view3d.py index 315b7e5c4fc..9b1bf256308 100644 --- a/release/scripts/startup/bl_operators/view3d.py +++ b/release/scripts/startup/bl_operators/view3d.py @@ -76,7 +76,9 @@ class VIEW3D_OT_edit_mesh_extrude_move(Operator): bpy.ops.mesh.extrude_region_move('INVOKE_REGION_WIN', TRANSFORM_OT_translate={ "constraint_orientation": 'NORMAL', - "constraint_axis": (True, True, False)}) + # not a popular choice, too restrictive for retopo. + #~ "constraint_axis": (True, True, False)}) + "constraint_axis": (False, False, False)}) else: bpy.ops.mesh.extrude_region_move('INVOKE_REGION_WIN') diff --git a/release/scripts/startup/bl_operators/wm.py b/release/scripts/startup/bl_operators/wm.py index 61840829900..78f14137ad1 100644 --- a/release/scripts/startup/bl_operators/wm.py +++ b/release/scripts/startup/bl_operators/wm.py @@ -29,9 +29,6 @@ from bpy.props import (StringProperty, from rna_prop_ui import rna_idprop_ui_prop_get, rna_idprop_ui_prop_clear -import subprocess -import os - class MESH_OT_delete_edgeloop(Operator): '''Delete an edge loop by merging the faces on each side to a single face loop''' @@ -146,12 +143,12 @@ class BRUSH_OT_active_index_set(Operator): bl_label = "Set Brush Number" mode = StringProperty( - name="mode", + name="Mode", description="Paint mode to set brush for", maxlen=1024, ) index = IntProperty( - name="number", + name="Number", description="Brush number", ) @@ -644,6 +641,10 @@ class WM_OT_context_modal_mouse(Operator): data_path_iter = data_path_iter data_path_item = data_path_item + header_text = StringProperty( + name="Header Text", + description="Text to display in header during scale", + ) input_scale = FloatProperty( description="Scale the mouse movement by this value before applying the delta", @@ -703,14 +704,24 @@ class WM_OT_context_modal_mouse(Operator): if event_type == 'MOUSEMOVE': delta = event.mouse_x - self.initial_x self._values_delta(delta) + header_text = self.header_text + if header_text: + if len(self._values) == 1: + (item, ) = self._values.keys() + header_text = header_text % eval("item.%s" % self.data_path_item) + else: + header_text = (self.header_text % delta) + " (delta)" + context.area.header_text_set(header_text) elif 'LEFTMOUSE' == event_type: item = next(iter(self._values.keys())) self._values_clear() + context.area.header_text_set() return operator_value_undo_return(item) elif event_type in {'RIGHTMOUSE', 'ESC'}: self._values_restore() + context.area.header_text_set() return {'CANCELLED'} return {'RUNNING_MODAL'} @@ -1028,6 +1039,7 @@ class WM_OT_properties_add(Operator): '''Internal use (edit a property data_path)''' bl_idname = "wm.properties_add" bl_label = "Add Property" + bl_options = {'UNDO'} data_path = rna_path @@ -1070,6 +1082,7 @@ class WM_OT_properties_remove(Operator): '''Internal use (edit a property data_path)''' bl_idname = "wm.properties_remove" bl_label = "Remove Property" + bl_options = {'UNDO'} data_path = rna_path property = rna_property @@ -1184,20 +1197,24 @@ class WM_OT_blenderplayer_start(Operator): bl_idname = "wm.blenderplayer_start" bl_label = "Start" - blender_bin_path = bpy.app.binary_path - blender_bin_dir = os.path.dirname(blender_bin_path) - ext = os.path.splitext(blender_bin_path)[-1] - player_path = os.path.join(blender_bin_dir, "blenderplayer" + ext) - def execute(self, context): + import os import sys + import subprocess + + # these remain the same every execution + blender_bin_path = bpy.app.binary_path + blender_bin_dir = os.path.dirname(blender_bin_path) + ext = os.path.splitext(blender_bin_path)[-1] + player_path = os.path.join(blender_bin_dir, "blenderplayer" + ext) + # done static vars if sys.platform == "darwin": - self.player_path = os.path.join(self.blender_bin_dir, "../../../blenderplayer.app/Contents/MacOS/blenderplayer") + player_path = os.path.join(blender_bin_dir, "../../../blenderplayer.app/Contents/MacOS/blenderplayer") - filepath = bpy.app.tempdir + "game.blend" + filepath = os.path.join(bpy.app.tempdir, "game.blend") bpy.ops.wm.save_as_mainfile(filepath=filepath, check_existing=False, copy=True) - subprocess.call([self.player_path, filepath]) + subprocess.call([player_path, filepath]) return {'FINISHED'} diff --git a/release/scripts/startup/bl_ui/properties_data_armature.py b/release/scripts/startup/bl_ui/properties_data_armature.py index d1bc0694a89..b94af13af7e 100644 --- a/release/scripts/startup/bl_ui/properties_data_armature.py +++ b/release/scripts/startup/bl_ui/properties_data_armature.py @@ -289,7 +289,7 @@ class DATA_PT_iksolver_itasc(ArmatureButtonsPanel, Panel): row.prop(itasc, "damping_max", text="Damp", slider=True) row.prop(itasc, "damping_epsilon", text="Eps", slider=True) -from .properties_animviz import ( +from bl_ui.properties_animviz import ( MotionPathButtonsPanel, OnionSkinButtonsPanel, ) diff --git a/release/scripts/startup/bl_ui/properties_data_bone.py b/release/scripts/startup/bl_ui/properties_data_bone.py index 807e5e63bc5..10c4c1fdd04 100644 --- a/release/scripts/startup/bl_ui/properties_data_bone.py +++ b/release/scripts/startup/bl_ui/properties_data_bone.py @@ -206,8 +206,10 @@ class BONE_PT_display(BoneButtonsPanel, Panel): split = layout.split() col = split.column() - col.prop(bone, "show_wire", text="Wireframe") col.prop(bone, "hide", text="Hide") + sub = col.column() + sub.active = bool(pchan.custom_shape) + sub.prop(bone, "show_wire", text="Wireframe") if pchan: col = split.column() diff --git a/release/scripts/startup/bl_ui/properties_data_camera.py b/release/scripts/startup/bl_ui/properties_data_camera.py index 1d7559b2ceb..5da41a668f6 100644 --- a/release/scripts/startup/bl_ui/properties_data_camera.py +++ b/release/scripts/startup/bl_ui/properties_data_camera.py @@ -88,11 +88,7 @@ class DATA_PT_lens(CameraButtonsPanel, Panel): col.prop(cam, "ortho_scale") col = layout.column() - if cam.type == 'ORTHO': - if cam.use_panorama: - col.alert = True - else: - col.enabled = False + col.enabled = cam.type == 'PERSP' col.prop(cam, "use_panorama") diff --git a/release/scripts/startup/bl_ui/properties_data_curve.py b/release/scripts/startup/bl_ui/properties_data_curve.py index 91230c9dc89..b8a37e38a17 100644 --- a/release/scripts/startup/bl_ui/properties_data_curve.py +++ b/release/scripts/startup/bl_ui/properties_data_curve.py @@ -93,7 +93,7 @@ class DATA_PT_shape_curve(CurveButtonsPanel, Panel): col.label(text="Twisting:") col.prop(curve, "twist_mode", text="") col.prop(curve, "twist_smooth", text="Smooth") - if is_text: + elif is_text: col.label(text="Display:") col.prop(curve, "use_fast_edit", text="Fast Editing") @@ -113,6 +113,14 @@ class DATA_PT_shape_curve(CurveButtonsPanel, Panel): sub.prop(curve, "fill_mode", text="") col.prop(curve, "use_fill_deform") + if is_curve: + col.label(text="Path / Curve-Deform:") + sub = col.column() + subsub = sub.row() + subsub.prop(curve, "use_radius") + subsub.prop(curve, "use_stretch") + sub.prop(curve, "use_deform_bounds") + class DATA_PT_curve_texture_space(CurveButtonsPanel, Panel): bl_label = "Texture Space" @@ -186,19 +194,13 @@ class DATA_PT_pathanim(CurveButtonsPanelCurve, Panel): layout.active = curve.use_path col = layout.column() - layout.prop(curve, "path_duration", text="Frames") - layout.prop(curve, "eval_time") - - split = layout.split() + col.prop(curve, "path_duration", text="Frames") + col.prop(curve, "eval_time") - col = split.column() - col.prop(curve, "use_path_follow") - col.prop(curve, "use_stretch") - col.prop(curve, "use_deform_bounds") - - col = split.column() - col.prop(curve, "use_radius") - col.prop(curve, "use_time_offset", text="Offset Children") + # these are for paths only + row = layout.row() + row.prop(curve, "use_path_follow") + row.prop(curve, "use_time_offset", text="Offset Children") class DATA_PT_active_spline(CurveButtonsPanelActive, Panel): @@ -320,10 +322,10 @@ class DATA_PT_font(CurveButtonsPanel, Panel): split = layout.split() col = split.column() - colsub = col.column(align=True) - colsub.label(text="Underline:") - colsub.prop(text, "underline_position", text="Position") - colsub.prop(text, "underline_height", text="Thickness") + sub = col.column(align=True) + sub.label(text="Underline:") + sub.prop(text, "underline_position", text="Position") + sub.prop(text, "underline_height", text="Thickness") col = split.column() col.label(text="Character:") diff --git a/release/scripts/startup/bl_ui/properties_data_mesh.py b/release/scripts/startup/bl_ui/properties_data_mesh.py index 7828d90b39d..fd96fa4a0ce 100644 --- a/release/scripts/startup/bl_ui/properties_data_mesh.py +++ b/release/scripts/startup/bl_ui/properties_data_mesh.py @@ -162,7 +162,7 @@ class DATA_PT_vertex_groups(MeshButtonsPanel, Panel): row = layout.row() sub = row.row(align=True) - sub.operator("object.vertex_group_assign", text="Assign") + sub.operator("object.vertex_group_assign", text="Assign").new = False sub.operator("object.vertex_group_remove_from", text="Remove") sub = row.row(align=True) @@ -233,7 +233,10 @@ class DATA_PT_shape_keys(MeshButtonsPanel, Panel): sub.prop(ob, "use_shape_key_edit_mode", text="") sub = row.row() - sub.operator("object.shape_key_clear", icon='X', text="") + if key.use_relative: + sub.operator("object.shape_key_clear", icon='X', text="") + else: + sub.operator("object.shape_key_retime", icon='RECOVER_LAST', text="") row = layout.row() row.prop(kb, "name") @@ -259,8 +262,9 @@ class DATA_PT_shape_keys(MeshButtonsPanel, Panel): col.prop_search(kb, "relative_key", key, "key_blocks", text="") else: - row = layout.row() + row = layout.column() row.active = enable_edit_value + row.prop(key, "eval_time") row.prop(key, "slurph") diff --git a/release/scripts/startup/bl_ui/properties_data_modifier.py b/release/scripts/startup/bl_ui/properties_data_modifier.py index 354b70c19c2..a4e7d107099 100644 --- a/release/scripts/startup/bl_ui/properties_data_modifier.py +++ b/release/scripts/startup/bl_ui/properties_data_modifier.py @@ -25,6 +25,7 @@ class ModifierButtonsPanel(): bl_space_type = 'PROPERTIES' bl_region_type = 'WINDOW' bl_context = "modifier" + bl_options = {'HIDE_HEADER'} class DATA_PT_modifiers(ModifierButtonsPanel, Panel): @@ -122,6 +123,14 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel): split.prop(md, "width") split.prop(md, "use_only_vertices") + # -- new modifier only, this may be reverted in favor of 2.62 mod. + ''' + split = layout.split() + split.prop(md, "use_even_offset") + split.prop(md, "use_distance_offset") + ''' + # -- end + layout.label(text="Limit Method:") layout.row().prop(md, "limit_method", expand=True) if md.limit_method == 'ANGLE': @@ -310,6 +319,9 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel): col.label(text="Vertex Group:") col.prop_search(md, "vertex_group", ob, "vertex_groups", text="") + layout.separator() + layout.prop(md, "strength", slider=True) + def MASK(self, layout, ob, md): split = layout.split() diff --git a/release/scripts/startup/bl_ui/properties_game.py b/release/scripts/startup/bl_ui/properties_game.py index ee5702e324e..cc3e8a8e57d 100644 --- a/release/scripts/startup/bl_ui/properties_game.py +++ b/release/scripts/startup/bl_ui/properties_game.py @@ -122,7 +122,8 @@ class PHYSICS_PT_game_physics(PhysicsButtonsPanel, Panel): col = split.column() col.label(text="Attributes:") col.prop(game, "mass") - col.prop(soft, "weld_threshold") + # disabled in the code + # col.prop(soft, "weld_threshold") col.prop(soft, "location_iterations") col.prop(soft, "linear_stiffness", slider=True) col.prop(soft, "dynamic_friction", slider=True) @@ -329,7 +330,7 @@ class RENDER_PT_game_stereo(RenderButtonsPanel, Panel): col.prop(gs, "dome_angle", slider=True) col = split.column() - col.prop(gs, "dome_tesselation", text="Tesselation") + col.prop(gs, "dome_tessellation", text="Tessellation") col.prop(gs, "dome_tilt") elif dome_type == 'PANORAM_SPH': @@ -337,7 +338,7 @@ class RENDER_PT_game_stereo(RenderButtonsPanel, Panel): col.prop(gs, "dome_buffer_resolution", text="Resolution", slider=True) col = split.column() - col.prop(gs, "dome_tesselation", text="Tesselation") + col.prop(gs, "dome_tessellation", text="Tessellation") else: # cube map col = split.column() diff --git a/release/scripts/startup/bl_ui/properties_object.py b/release/scripts/startup/bl_ui/properties_object.py index f01c2ba45e0..d7b4b1a2b44 100644 --- a/release/scripts/startup/bl_ui/properties_object.py +++ b/release/scripts/startup/bl_ui/properties_object.py @@ -90,7 +90,7 @@ class OBJECT_PT_delta_transform(ObjectButtonsPanel, Panel): #row.column().prop(ob, "delta_rotation_axis_angle", text="Rotation") row.column().label(text="Not for Axis-Angle") else: - row.column().prop(ob, "delta_rotation_euler", text="Rotation") + row.column().prop(ob, "delta_rotation_euler", text="Delta Rotation") row.column().prop(ob, "delta_scale") @@ -162,7 +162,6 @@ class OBJECT_PT_groups(ObjectButtonsPanel, Panel): # XXX, this is bad practice, yes, I wrote it :( - campbell index = 0 - value = str(tuple(context.scene.cursor_location)) for group in bpy.data.groups: if ob.name in group.objects: col = layout.column(align=True) @@ -181,9 +180,8 @@ class OBJECT_PT_groups(ObjectButtonsPanel, Panel): col = split.column() col.prop(group, "dupli_offset", text="") - props = col.operator("wm.context_set_value", text="From Cursor") - props.data_path = "object.users_group[%d].dupli_offset" % index - props.value = value + props = col.operator("object.dupli_offset_from_cursor", text="From Cursor") + props.group = index index += 1 @@ -211,8 +209,11 @@ class OBJECT_PT_display(ObjectButtonsPanel, Panel): col = split.column() col.prop(ob, "show_name", text="Name") col.prop(ob, "show_axis", text="Axis") - col.prop(ob, "show_wire", text="Wire") - col.prop(ob, "color", text="Object Color") + if ob.type in {"MESH", "CURVE", "SURFACE", "META", "FONT"}: + # Makes no sense for cameras, armtures, etc.! + col.prop(ob, "show_wire", text="Wire") + # Only useful with object having faces/materials... + col.prop(ob, "color", text="Object Color") col = split.column() col.prop(ob, "show_texture_space", text="Texture Space") @@ -280,7 +281,7 @@ class OBJECT_PT_relations_extras(ObjectButtonsPanel, Panel): row.prop(ob, "slow_parent_offset", text="Offset") -from .properties_animviz import ( +from bl_ui.properties_animviz import ( MotionPathButtonsPanel, OnionSkinButtonsPanel, ) diff --git a/release/scripts/startup/bl_ui/properties_object_constraint.py b/release/scripts/startup/bl_ui/properties_object_constraint.py index 68c00691122..bfa2b4f60ef 100644 --- a/release/scripts/startup/bl_ui/properties_object_constraint.py +++ b/release/scripts/startup/bl_ui/properties_object_constraint.py @@ -796,7 +796,6 @@ class ConstraintButtonsPanel(): layout.operator("clip.constraint_to_fcurve") def OBJECT_SOLVER(self, context, layout, con): - scene = context.scene clip = self._getConstraintClip(context, con) layout.prop(con, "use_active_clip") @@ -816,12 +815,13 @@ class ConstraintButtonsPanel(): layout.operator("clip.constraint_to_fcurve") def SCRIPT(self, context, layout, con): - layout.label("Blender 2.5 has no py-constraints") + layout.label("Blender 2.6 doesn't support python constraints yet.") class OBJECT_PT_constraints(ConstraintButtonsPanel, Panel): bl_label = "Object Constraints" bl_context = "constraint" + bl_options = {'HIDE_HEADER'} @classmethod def poll(cls, context): @@ -846,6 +846,7 @@ class OBJECT_PT_constraints(ConstraintButtonsPanel, Panel): class BONE_PT_constraints(ConstraintButtonsPanel, Panel): bl_label = "Bone Constraints" bl_context = "bone_constraint" + bl_options = {'HIDE_HEADER'} @classmethod def poll(cls, context): diff --git a/release/scripts/startup/bl_ui/properties_particle.py b/release/scripts/startup/bl_ui/properties_particle.py index 4e511f18cd4..74abc8fe559 100644 --- a/release/scripts/startup/bl_ui/properties_particle.py +++ b/release/scripts/startup/bl_ui/properties_particle.py @@ -21,7 +21,7 @@ import bpy from bpy.types import Panel from rna_prop_ui import PropertyPanel -from .properties_physics_common import ( +from bl_ui.properties_physics_common import ( point_cache_ui, effector_weights_ui, basic_force_field_settings_ui, @@ -380,6 +380,7 @@ class PARTICLE_PT_velocity(ParticleButtonsPanel, Panel): class PARTICLE_PT_rotation(ParticleButtonsPanel, Panel): bl_label = "Rotation" + bl_options = {'DEFAULT_CLOSED'} COMPAT_ENGINES = {'BLENDER_RENDER'} @classmethod @@ -394,6 +395,15 @@ class PARTICLE_PT_rotation(ParticleButtonsPanel, Panel): else: return False + def draw_header(self, context): + psys = context.particle_system + if psys: + part = psys.settings + else: + part = context.space_data.pin_id + + self.layout.prop(part, "use_rotations", text="") + def draw(self, context): layout = self.layout @@ -403,14 +413,9 @@ class PARTICLE_PT_rotation(ParticleButtonsPanel, Panel): else: part = context.space_data.pin_id - layout.enabled = particle_panel_enabled(context, psys) + layout.enabled = particle_panel_enabled(context, psys) and part.use_rotations - layout.prop(part, "use_dynamic_rotation") - - if part.use_dynamic_rotation: - layout.label(text="Initial Rotation Axis:") - else: - layout.label(text="Rotation Axis:") + layout.label(text="Initial Orientation:") split = layout.split() @@ -423,16 +428,17 @@ class PARTICLE_PT_rotation(ParticleButtonsPanel, Panel): col.prop(part, "phase_factor_random", text="Random", slider=True) if part.type != 'HAIR': - col = layout.column() - if part.use_dynamic_rotation: - col.label(text="Initial Angular Velocity:") - else: - col.label(text="Angular Velocity:") - sub = col.row(align=True) - sub.prop(part, "angular_velocity_mode", text="") - subsub = sub.column() - subsub.active = part.angular_velocity_mode != 'NONE' - subsub.prop(part, "angular_velocity_factor", text="") + layout.label(text="Angular Velocity:") + + split = layout.split() + col = split.column(align=True) + col.prop(part, "angular_velocity_mode", text="") + sub = col.column() + sub.active = part.angular_velocity_mode != 'NONE' + sub.prop(part, "angular_velocity_factor", text="") + + col = split.column() + col.prop(part, "use_dynamic_rotation") class PARTICLE_PT_physics(ParticleButtonsPanel, Panel): @@ -1178,43 +1184,34 @@ class PARTICLE_PT_vertexgroups(ParticleButtonsPanel, Panel): ob = context.object psys = context.particle_system - row = layout.row() - row.label(text="Vertex Group") - row.label(text="Negate") - - row = layout.row() - row.prop_search(psys, "vertex_group_density", ob, "vertex_groups", text="Density") - row.prop(psys, "invert_vertex_group_density", text="") - + split = layout.split(percentage=0.85) + + col = split.column() + col.label(text="Vertex Group:") + col.prop_search(psys, "vertex_group_density", ob, "vertex_groups", text="Density") + col.prop_search(psys, "vertex_group_length", ob, "vertex_groups", text="Length") + col.prop_search(psys, "vertex_group_clump", ob, "vertex_groups", text="Clump") + col.prop_search(psys, "vertex_group_kink", ob, "vertex_groups", text="Kink") + col.prop_search(psys, "vertex_group_roughness_1", ob, "vertex_groups", text="Roughness 1") + col.prop_search(psys, "vertex_group_roughness_2", ob, "vertex_groups", text="Roughness 2") + col.prop_search(psys, "vertex_group_roughness_end", ob, "vertex_groups", text="Roughness End") + + col = split.column() + col.label(text="Negate:") + col.alignment = 'RIGHT' + col.prop(psys, "invert_vertex_group_density", text="") + col.prop(psys, "invert_vertex_group_length", text="") + col.prop(psys, "invert_vertex_group_clump", text="") + col.prop(psys, "invert_vertex_group_kink", text="") + col.prop(psys, "invert_vertex_group_roughness_1", text="") + col.prop(psys, "invert_vertex_group_roughness_2", text="") + col.prop(psys, "invert_vertex_group_roughness_end", text="") + # Commented out vertex groups don't work and are still waiting for better implementation # row = layout.row() # row.prop_search(psys, "vertex_group_velocity", ob, "vertex_groups", text="Velocity") # row.prop(psys, "invert_vertex_group_velocity", text="") - row = layout.row() - row.prop_search(psys, "vertex_group_length", ob, "vertex_groups", text="Length") - row.prop(psys, "invert_vertex_group_length", text="") - - row = layout.row() - row.prop_search(psys, "vertex_group_clump", ob, "vertex_groups", text="Clump") - row.prop(psys, "invert_vertex_group_clump", text="") - - row = layout.row() - row.prop_search(psys, "vertex_group_kink", ob, "vertex_groups", text="Kink") - row.prop(psys, "invert_vertex_group_kink", text="") - - row = layout.row() - row.prop_search(psys, "vertex_group_roughness_1", ob, "vertex_groups", text="Roughness 1") - row.prop(psys, "invert_vertex_group_roughness_1", text="") - - row = layout.row() - row.prop_search(psys, "vertex_group_roughness_2", ob, "vertex_groups", text="Roughness 2") - row.prop(psys, "invert_vertex_group_roughness_2", text="") - - row = layout.row() - row.prop_search(psys, "vertex_group_roughness_end", ob, "vertex_groups", text="Roughness End") - row.prop(psys, "invert_vertex_group_roughness_end", text="") - # row = layout.row() # row.prop_search(psys, "vertex_group_size", ob, "vertex_groups", text="Size") # row.prop(psys, "invert_vertex_group_size", text="") diff --git a/release/scripts/startup/bl_ui/properties_physics_cloth.py b/release/scripts/startup/bl_ui/properties_physics_cloth.py index dc64aacf043..14c7b381ee7 100644 --- a/release/scripts/startup/bl_ui/properties_physics_cloth.py +++ b/release/scripts/startup/bl_ui/properties_physics_cloth.py @@ -20,7 +20,7 @@ import bpy from bpy.types import Menu, Panel -from .properties_physics_common import ( +from bl_ui.properties_physics_common import ( point_cache_ui, effector_weights_ui, ) diff --git a/release/scripts/startup/bl_ui/properties_physics_dynamicpaint.py b/release/scripts/startup/bl_ui/properties_physics_dynamicpaint.py index d6aeea8ece7..04696c793a6 100644 --- a/release/scripts/startup/bl_ui/properties_physics_dynamicpaint.py +++ b/release/scripts/startup/bl_ui/properties_physics_dynamicpaint.py @@ -17,11 +17,10 @@ # ##### END GPL LICENSE BLOCK ##### # <pep8 compliant> - import bpy from bpy.types import Panel -from .properties_physics_common import ( +from bl_ui.properties_physics_common import ( point_cache_ui, effector_weights_ui, ) @@ -217,7 +216,7 @@ class PHYSICS_PT_dp_canvas_output(PhysicButtonsPanel, Panel): # paint-map output row = layout.row() - row.prop_search(surface, "output_name_a", ob.data, "vertex_colors", text="Paintmap layer: ") + row.prop_search(surface, "output_name_a", ob.data, "vertex_colors", text="Paintmap layer:") if surface.output_exists(object=ob, index=0): ic = 'ZOOMOUT' else: @@ -227,7 +226,7 @@ class PHYSICS_PT_dp_canvas_output(PhysicButtonsPanel, Panel): # wet-map output row = layout.row() - row.prop_search(surface, "output_name_b", ob.data, "vertex_colors", text="Wetmap layer: ") + row.prop_search(surface, "output_name_b", ob.data, "vertex_colors", text="Wetmap layer:") if surface.output_exists(object=ob, index=1): ic = 'ZOOMOUT' else: @@ -237,7 +236,7 @@ class PHYSICS_PT_dp_canvas_output(PhysicButtonsPanel, Panel): elif surface_type == 'WEIGHT': row = layout.row() - row.prop_search(surface, "output_name_a", ob, "vertex_groups", text="Vertex Group: ") + row.prop_search(surface, "output_name_a", ob, "vertex_groups", text="Vertex Group:") if surface.output_exists(object=ob, index=0): ic = 'ZOOMOUT' else: @@ -270,7 +269,7 @@ class PHYSICS_PT_dp_canvas_output(PhysicButtonsPanel, Panel): sub.prop(surface, "output_name_b", text="") else: col = layout.column() - col.prop(surface, "output_name_a", text="Filename: ") + col.prop(surface, "output_name_a", text="Filename:") if surface_type == 'DISPLACE': col.prop(surface, "displace_type", text="Displace Type") col.prop(surface, "depth_clamp") @@ -309,7 +308,7 @@ class PHYSICS_PT_dp_canvas_initial_color(PhysicButtonsPanel, Panel): layout.prop_search(surface, "init_layername", ob.data, "uv_textures", text="UV Map:") elif surface.init_color_type == 'VERTEX_COLOR': - layout.prop_search(surface, "init_layername", ob.data, "vertex_colors", text="Color Layer: ") + layout.prop_search(surface, "init_layername", ob.data, "vertex_colors", text="Color Layer:") class PHYSICS_PT_dp_effects(PhysicButtonsPanel, Panel): diff --git a/release/scripts/startup/bl_ui/properties_physics_field.py b/release/scripts/startup/bl_ui/properties_physics_field.py index bc7f330a546..2229b9dc3da 100644 --- a/release/scripts/startup/bl_ui/properties_physics_field.py +++ b/release/scripts/startup/bl_ui/properties_physics_field.py @@ -20,7 +20,7 @@ import bpy from bpy.types import Panel -from .properties_physics_common import ( +from bl_ui.properties_physics_common import ( basic_force_field_settings_ui, basic_force_field_falloff_ui, ) diff --git a/release/scripts/startup/bl_ui/properties_physics_fluid.py b/release/scripts/startup/bl_ui/properties_physics_fluid.py index 363b0f20428..d334671292a 100644 --- a/release/scripts/startup/bl_ui/properties_physics_fluid.py +++ b/release/scripts/startup/bl_ui/properties_physics_fluid.py @@ -42,14 +42,14 @@ class PHYSICS_PT_fluid(PhysicButtonsPanel, Panel): md = context.fluid fluid = md.settings - row = layout.row() + col = layout.column() if fluid is None: - row.label("Built without fluids") + col.label("Built without fluids") return - row.prop(fluid, "type") + col.prop(fluid, "type") if fluid.type not in {'NONE', 'DOMAIN', 'PARTICLE', 'FLUID'}: - row.prop(fluid, "use", text="") + col.prop(fluid, "use") layout = layout.column() if fluid.type not in {'NONE', 'DOMAIN', 'PARTICLE', 'FLUID'}: @@ -134,15 +134,11 @@ class PHYSICS_PT_fluid(PhysicButtonsPanel, Panel): col.prop(fluid, "inflow_velocity", text="") elif fluid.type == 'OUTFLOW': - split = layout.split() - - col = split.column() + col = layout.column() col.label(text="Volume Initialization:") col.prop(fluid, "volume_initialization", text="") col.prop(fluid, "use_animated_mesh") - split.column() - elif fluid.type == 'PARTICLE': split = layout.split() diff --git a/release/scripts/startup/bl_ui/properties_physics_smoke.py b/release/scripts/startup/bl_ui/properties_physics_smoke.py index 4c413647210..9f760f2f024 100644 --- a/release/scripts/startup/bl_ui/properties_physics_smoke.py +++ b/release/scripts/startup/bl_ui/properties_physics_smoke.py @@ -20,7 +20,7 @@ import bpy from bpy.types import Panel -from .properties_physics_common import ( +from bl_ui.properties_physics_common import ( point_cache_ui, effector_weights_ui, ) diff --git a/release/scripts/startup/bl_ui/properties_physics_softbody.py b/release/scripts/startup/bl_ui/properties_physics_softbody.py index 78c74a7e1d3..ea4180c891f 100644 --- a/release/scripts/startup/bl_ui/properties_physics_softbody.py +++ b/release/scripts/startup/bl_ui/properties_physics_softbody.py @@ -20,7 +20,7 @@ import bpy from bpy.types import Panel -from .properties_physics_common import ( +from bl_ui.properties_physics_common import ( point_cache_ui, effector_weights_ui, ) diff --git a/release/scripts/startup/bl_ui/properties_scene.py b/release/scripts/startup/bl_ui/properties_scene.py index 7879f15270a..1c78549c086 100644 --- a/release/scripts/startup/bl_ui/properties_scene.py +++ b/release/scripts/startup/bl_ui/properties_scene.py @@ -115,7 +115,8 @@ class SCENE_PT_keying_sets(SceneButtonsPanel, Panel): row = layout.row() col = row.column() - col.prop(ks, "name") + col.prop(ks, "bl_label") + col.prop(ks, "bl_description") subcol = col.column() subcol.operator_context = 'INVOKE_DEFAULT' diff --git a/release/scripts/startup/bl_ui/properties_texture.py b/release/scripts/startup/bl_ui/properties_texture.py index 13d25e6ac8d..32047581550 100644 --- a/release/scripts/startup/bl_ui/properties_texture.py +++ b/release/scripts/startup/bl_ui/properties_texture.py @@ -52,7 +52,7 @@ class TEXTURE_MT_envmap_specials(Menu): layout.operator("texture.envmap_clear", icon='FILE_REFRESH') layout.operator("texture.envmap_clear_all", icon='FILE_REFRESH') -from .properties_material import active_node_mat +from bl_ui.properties_material import active_node_mat def context_tex_datablock(context): diff --git a/release/scripts/startup/bl_ui/properties_world.py b/release/scripts/startup/bl_ui/properties_world.py index 23f35d6d1e9..76d70aafc2e 100644 --- a/release/scripts/startup/bl_ui/properties_world.py +++ b/release/scripts/startup/bl_ui/properties_world.py @@ -49,16 +49,17 @@ class WORLD_PT_context_world(WorldButtonsPanel, Panel): scene = context.scene world = context.world space = context.space_data + rd = context.scene.render texture_count = world and len(world.texture_slots.keys()) - split = layout.split(percentage=0.65) + split = layout.split(percentage=0.85) if scene: split.template_ID(scene, "world", new="world.new") elif world: split.template_ID(space, "pin_id") - if texture_count: + if texture_count and rd.engine != 'CYCLES': split.label(text=str(texture_count), icon='TEXTURE') diff --git a/release/scripts/startup/bl_ui/space_clip.py b/release/scripts/startup/bl_ui/space_clip.py index d9116165a0f..c7ab9de72ac 100644 --- a/release/scripts/startup/bl_ui/space_clip.py +++ b/release/scripts/startup/bl_ui/space_clip.py @@ -298,7 +298,11 @@ class CLIP_PT_tools_orientation(Panel): settings = sc.clip.tracking.settings col = layout.column(align=True) - col.operator("clip.set_floor") + row = col.row() + props = row.operator("clip.set_plane", text="Floor") + props.plane = 'FLOOR' + props = row.operator("clip.set_plane", text="Wall") + props.plane = 'WALL' col.operator("clip.set_origin") row = col.row() @@ -474,6 +478,41 @@ class CLIP_PT_track(Panel): layout.label(text=label_text) +class CLIP_PT_track_settings(Panel): + bl_space_type = 'CLIP_EDITOR' + bl_region_type = 'UI' + bl_label = "Tracking Settings" + bl_options = {'DEFAULT_CLOSED'} + + @classmethod + def poll(cls, context): + sc = context.space_data + + return sc.mode == 'TRACKING' and sc.clip + + def draw(self, context): + layout = self.layout + clip = context.space_data.clip + settings = clip.tracking.settings + + col = layout.column() + + active = clip.tracking.tracks.active + if active: + col.prop(active, "tracker") + + if active.tracker == 'KLT': + col.prop(active, "pyramid_levels") + col.prop(active, "correlation_min") + + col.separator() + col.prop(active, "frames_limit") + col.prop(active, "margin") + col.prop(active, "pattern_match", text="Match") + + col.prop(settings, "speed") + + class CLIP_PT_tracking_camera(Panel): bl_space_type = 'CLIP_EDITOR' bl_region_type = 'UI' @@ -595,41 +634,6 @@ class CLIP_PT_marker_display(Panel): row.prop(sc, "path_length", text="Length") -class CLIP_PT_track_settings(Panel): - bl_space_type = 'CLIP_EDITOR' - bl_region_type = 'UI' - bl_label = "Tracking Settings" - bl_options = {'DEFAULT_CLOSED'} - - @classmethod - def poll(cls, context): - sc = context.space_data - - return sc.mode == 'TRACKING' and sc.clip - - def draw(self, context): - layout = self.layout - clip = context.space_data.clip - settings = clip.tracking.settings - - col = layout.column() - - active = clip.tracking.tracks.active - if active: - col.prop(active, "tracker") - - if active.tracker == 'KLT': - col.prop(active, "pyramid_levels") - col.prop(active, "correlation_min") - - col.separator() - col.prop(active, "frames_limit") - col.prop(active, "margin") - col.prop(active, "pattern_match", text="Match") - - col.prop(settings, "speed") - - class CLIP_PT_stabilization(Panel): bl_space_type = 'CLIP_EDITOR' bl_region_type = 'UI' @@ -936,7 +940,10 @@ class CLIP_MT_reconstruction(Menu): layout = self.layout layout.operator("clip.set_origin") - layout.operator("clip.set_floor") + props = layout.operator("clip.set_plane", text="Set Floor") + props.plane = 'FLOOR' + props = layout.operator("clip.set_plane", text="Set Wall") + props.plane = 'WALL' layout.operator("clip.set_axis", text="Set X Axis").axis = "X" layout.operator("clip.set_axis", text="Set Y Axis").axis = "Y" @@ -983,8 +990,7 @@ class CLIP_MT_select(Menu): layout.separator() - props = layout.operator("clip.select_all", text="Select/Deselect all") - props.action = 'TOGGLE' + layout.operator("clip.select_all").action = 'TOGGLE' layout.operator("clip.select_all", text="Inverse").action = 'INVERT' layout.menu("CLIP_MT_select_grouped") diff --git a/release/scripts/startup/bl_ui/space_dopesheet.py b/release/scripts/startup/bl_ui/space_dopesheet.py index b7d69fb38b3..e39ed4ec326 100644 --- a/release/scripts/startup/bl_ui/space_dopesheet.py +++ b/release/scripts/startup/bl_ui/space_dopesheet.py @@ -210,7 +210,7 @@ class DOPESHEET_MT_marker(Menu): def draw(self, context): layout = self.layout - from .space_time import marker_menu_generic + from bl_ui.space_time import marker_menu_generic marker_menu_generic(layout) st = context.space_data diff --git a/release/scripts/startup/bl_ui/space_graph.py b/release/scripts/startup/bl_ui/space_graph.py index 36ba5eeb92e..8c28835fa99 100644 --- a/release/scripts/startup/bl_ui/space_graph.py +++ b/release/scripts/startup/bl_ui/space_graph.py @@ -26,7 +26,7 @@ class GRAPH_HT_header(Header): bl_space_type = 'GRAPH_EDITOR' def draw(self, context): - from .space_dopesheet import dopesheet_filter + from bl_ui.space_dopesheet import dopesheet_filter layout = self.layout @@ -144,7 +144,7 @@ class GRAPH_MT_marker(Menu): def draw(self, context): layout = self.layout - from .space_time import marker_menu_generic + from bl_ui.space_time import marker_menu_generic marker_menu_generic(layout) # TODO: pose markers for action edit mode only? diff --git a/release/scripts/startup/bl_ui/space_image.py b/release/scripts/startup/bl_ui/space_image.py index c0cc692f2f1..861a5670393 100644 --- a/release/scripts/startup/bl_ui/space_image.py +++ b/release/scripts/startup/bl_ui/space_image.py @@ -19,7 +19,7 @@ # <pep8 compliant> import bpy from bpy.types import Header, Menu, Panel -from .properties_paint_common import UnifiedPaintPanel +from bl_ui.properties_paint_common import UnifiedPaintPanel class ImagePaintPanel(UnifiedPaintPanel): @@ -97,7 +97,7 @@ class IMAGE_MT_select(Menu): layout.separator() - layout.operator("uv.select_all") + layout.operator("uv.select_all").action = 'TOGGLE' layout.operator("uv.select_all", text="Inverse").action = 'INVERT' layout.operator("uv.unlink_selected") diff --git a/release/scripts/startup/bl_ui/space_info.py b/release/scripts/startup/bl_ui/space_info.py index b6a450e1a02..66d18fc6f19 100644 --- a/release/scripts/startup/bl_ui/space_info.py +++ b/release/scripts/startup/bl_ui/space_info.py @@ -105,47 +105,46 @@ class INFO_MT_file(Menu): def draw(self, context): layout = self.layout - layout.operator_context = 'EXEC_AREA' - layout.operator("wm.read_homefile", text="New", icon='NEW') layout.operator_context = 'INVOKE_AREA' + layout.operator("wm.read_homefile", text="New", icon='NEW') layout.operator("wm.open_mainfile", text="Open...", icon='FILE_FOLDER') - layout.menu("INFO_MT_file_open_recent") + layout.menu("INFO_MT_file_open_recent", icon='OPEN_RECENT') layout.operator("wm.recover_last_session", icon='RECOVER_LAST') - layout.operator("wm.recover_auto_save", text="Recover Auto Save...") + layout.operator("wm.recover_auto_save", text="Recover Auto Save...", icon='RECOVER_AUTO') layout.separator() layout.operator_context = 'INVOKE_AREA' layout.operator("wm.save_mainfile", text="Save", icon='FILE_TICK').check_existing = False layout.operator_context = 'INVOKE_AREA' - layout.operator("wm.save_as_mainfile", text="Save As...") + layout.operator("wm.save_as_mainfile", text="Save As...", icon='SAVE_AS') layout.operator_context = 'INVOKE_AREA' - layout.operator("wm.save_as_mainfile", text="Save Copy...").copy = True + layout.operator("wm.save_as_mainfile", text="Save Copy...", icon='SAVE_COPY').copy = True layout.separator() layout.operator("screen.userpref_show", text="User Preferences...", icon='PREFERENCES') layout.operator_context = 'EXEC_AREA' - layout.operator("wm.save_homefile") - layout.operator("wm.read_factory_settings") + layout.operator("wm.save_homefile", icon='SAVE_PREFS') + layout.operator("wm.read_factory_settings", icon='LOAD_FACTORY') layout.separator() layout.operator_context = 'INVOKE_AREA' - layout.operator("wm.link_append", text="Link") - props = layout.operator("wm.link_append", text="Append") + layout.operator("wm.link_append", text="Link", icon='LINK_BLEND') + props = layout.operator("wm.link_append", text="Append", icon='APPEND_BLEND') props.link = False props.instance_groups = False layout.separator() - layout.menu("INFO_MT_file_import") - layout.menu("INFO_MT_file_export") + layout.menu("INFO_MT_file_import", icon='IMPORT') + layout.menu("INFO_MT_file_export", icon='EXPORT') layout.separator() - layout.menu("INFO_MT_file_external_data") + layout.menu("INFO_MT_file_external_data", icon='EXTERNAL_DATA') layout.separator() @@ -362,7 +361,7 @@ class INFO_MT_help(Menu): layout = self.layout layout.operator("wm.url_open", text="Manual", icon='HELP').url = 'http://wiki.blender.org/index.php/Doc:2.6/Manual' - layout.operator("wm.url_open", text="Release Log", icon='URL').url = 'http://www.blender.org/development/release-logs/blender-262/' + layout.operator("wm.url_open", text="Release Log", icon='URL').url = 'http://www.blender.org/development/release-logs/blender-263/' layout.separator() diff --git a/release/scripts/startup/bl_ui/space_nla.py b/release/scripts/startup/bl_ui/space_nla.py index 33610f3ba33..b15dcb3d07c 100644 --- a/release/scripts/startup/bl_ui/space_nla.py +++ b/release/scripts/startup/bl_ui/space_nla.py @@ -26,7 +26,7 @@ class NLA_HT_header(Header): bl_space_type = 'NLA_EDITOR' def draw(self, context): - from .space_dopesheet import dopesheet_filter + from bl_ui.space_dopesheet import dopesheet_filter layout = self.layout @@ -104,7 +104,7 @@ class NLA_MT_marker(Menu): def draw(self, context): layout = self.layout - from .space_time import marker_menu_generic + from bl_ui.space_time import marker_menu_generic marker_menu_generic(layout) diff --git a/release/scripts/startup/bl_ui/space_sequencer.py b/release/scripts/startup/bl_ui/space_sequencer.py index 09af7af0819..aae950519a4 100644 --- a/release/scripts/startup/bl_ui/space_sequencer.py +++ b/release/scripts/startup/bl_ui/space_sequencer.py @@ -75,6 +75,13 @@ class SEQUENCER_HT_header(Header): row.prop(ed, "overlay_frame", text="") row.prop(ed, "overlay_lock", text="", icon='LOCKED') + row = layout.row(align=True) + props = row.operator("render.opengl", text="", icon='RENDER_STILL') + props.sequencer = True + props = row.operator("render.opengl", text="", icon='RENDER_ANIMATION') + props.animation = True + props.sequencer = True + layout.template_running_jobs() @@ -143,7 +150,7 @@ class SEQUENCER_MT_select(Menu): layout.operator("sequencer.select_handles", text="Left Handle").side = 'LEFT' layout.operator("sequencer.select_handles", text="Right Handle").side = 'RIGHT' layout.separator() - layout.operator_menu_enum("object.select_grouped", "type", text="Grouped") + layout.operator_menu_enum("sequencer.select_grouped", "type", text="Grouped") layout.operator("sequencer.select_linked") layout.operator("sequencer.select_all").action = 'TOGGLE' layout.operator("sequencer.select_all").action = 'INVERT' @@ -155,7 +162,7 @@ class SEQUENCER_MT_marker(Menu): def draw(self, context): layout = self.layout - from .space_time import marker_menu_generic + from bl_ui.space_time import marker_menu_generic marker_menu_generic(layout) @@ -185,6 +192,12 @@ class SEQUENCER_MT_add(Menu): else: layout.operator_menu_enum("sequencer.scene_strip_add", "scene", text="Scene...") + if len(bpy.data.movieclips) > 10: + layout.operator_context = 'INVOKE_DEFAULT' + layout.operator("sequencer.movieclip_strip_add", text="Clips...") + else: + layout.operator_menu_enum("sequencer.movieclip_strip_add", "clip", text="Clip...") + layout.operator("sequencer.movie_strip_add", text="Movie") layout.operator("sequencer.image_strip_add", text="Image") layout.operator("sequencer.sound_strip_add", text="Sound") @@ -264,6 +277,9 @@ class SEQUENCER_MT_strip(Menu): layout.separator() # layout.operator("sequencer.movie_change") layout.operator("sequencer.rendersize") + elif stype == 'SOUND': + layout.separator() + layout.operator("sequencer.crossfade_sounds") layout.separator() @@ -276,7 +292,10 @@ class SEQUENCER_MT_strip(Menu): #} layout.separator() - layout.operator("sequencer.reload") + props = layout.operator("sequencer.reload", text="Reload Strips") + props.adjust_length = False + props = layout.operator("sequencer.reload", text="Reload Strips and Adjust Length") + props.adjust_length = True layout.operator("sequencer.reassign_inputs") layout.operator("sequencer.swap_inputs") layout.separator() @@ -531,7 +550,7 @@ class SEQUENCER_PT_input(SequencerButtonsPanel, Panel): if not strip: return False - return strip.type in {'MOVIE', 'IMAGE', 'SCENE', 'META', + return strip.type in {'MOVIE', 'IMAGE', 'SCENE', 'MOVIECLIP', 'META', 'ADD', 'SUBTRACT', 'ALPHA_OVER', 'ALPHA_UNDER', 'CROSS', 'GAMMA_CROSS', 'MULTIPLY', 'OVER_DROP', 'PLUGIN', @@ -694,7 +713,7 @@ class SEQUENCER_PT_filter(SequencerButtonsPanel, Panel): if not strip: return False - return strip.type in {'MOVIE', 'IMAGE', 'SCENE', 'META', + return strip.type in {'MOVIE', 'IMAGE', 'SCENE', 'MOVIECLIP', 'META', 'ADD', 'SUBTRACT', 'ALPHA_OVER', 'ALPHA_UNDER', 'CROSS', 'GAMMA_CROSS', 'MULTIPLY', 'OVER_DROP', 'PLUGIN', @@ -710,6 +729,15 @@ class SEQUENCER_PT_filter(SequencerButtonsPanel, Panel): col.label(text="Video:") col.prop(strip, "strobe") + if strip.type == 'MOVIECLIP': + col = layout.column() + col.label(text="Tracker:") + col.prop(strip, "stabilize2d") + + col = layout.column() + col.label(text="Distortion:") + col.prop(strip, "undistort") + row = layout.row() row.label(text="Flip:") row.prop(strip, "use_flip_x", text="X") diff --git a/release/scripts/startup/bl_ui/space_userpref.py b/release/scripts/startup/bl_ui/space_userpref.py index 2efeff0e079..7010c4f07cf 100644 --- a/release/scripts/startup/bl_ui/space_userpref.py +++ b/release/scripts/startup/bl_ui/space_userpref.py @@ -244,6 +244,9 @@ class USERPREF_PT_interface(Panel): col.prop(view, "show_splash") + if os.name == 'nt': + col.prop(view, "quit_dialog") + class USERPREF_PT_edit(Panel): bl_space_type = 'USER_PREFERENCES' @@ -301,6 +304,11 @@ class USERPREF_PT_edit(Panel): col.separator() col.label(text="Playback:") col.prop(edit, "use_negative_frames") + col.separator() + col.separator() + col.separator() + col.label(text="Animation Editors:") + col.prop(edit, "fcurve_unselected_alpha", text="F-Curve Visibility") row.separator() row.separator() @@ -625,6 +633,14 @@ class USERPREF_PT_theme(Panel): col.label(text="Menu Back:") ui_items_general(col, ui) + ui = theme.user_interface.wcol_tooltip + col.label(text="Tooltip:") + ui_items_general(col, ui) + + ui = theme.user_interface.wcol_tooltip + col.label(text="Tooltip:") + ui_items_general(col, ui) + ui = theme.user_interface.wcol_menu_item col.label(text="Menu Item:") ui_items_general(col, ui) @@ -829,7 +845,7 @@ class USERPREF_PT_file(Panel): col.prop(system, "use_tabs_as_spaces") -from .space_userpref_keymap import InputKeyMapPanel +from bl_ui.space_userpref_keymap import InputKeyMapPanel class USERPREF_MT_ndof_settings(Menu): @@ -899,6 +915,7 @@ class USERPREF_PT_input(Panel, InputKeyMapPanel): sub1.prop(inputs, "use_mouse_emulate_3_button") sub.prop(inputs, "use_mouse_continuous") sub.prop(inputs, "drag_threshold") + sub.prop(inputs, "tweak_threshold") sub.label(text="Select With:") sub.row().prop(inputs, "select_mouse", expand=True) @@ -936,8 +953,6 @@ class USERPREF_PT_input(Panel, InputKeyMapPanel): sub.label(text="NDOF Device:") sub.prop(inputs, "ndof_sensitivity", text="NDOF Sensitivity") - col.prop(inputs, "tweak_threshold") - row.separator() def draw(self, context): @@ -1107,6 +1122,10 @@ class USERPREF_PT_addons(Panel): split = colsub.row().split(percentage=0.15) split.label(text="Location:") split.label(text=info["location"]) + if mod: + split = colsub.row().split(percentage=0.15) + split.label(text="File:") + split.label(text=mod.__file__) if info["author"]: split = colsub.row().split(percentage=0.15) split.label(text="Author:") diff --git a/release/scripts/startup/bl_ui/space_userpref_keymap.py b/release/scripts/startup/bl_ui/space_userpref_keymap.py index 030e1ee0f6d..58697225811 100644 --- a/release/scripts/startup/bl_ui/space_userpref_keymap.py +++ b/release/scripts/startup/bl_ui/space_userpref_keymap.py @@ -18,7 +18,7 @@ # <pep8 compliant> import bpy -from bpy.types import Menu, OperatorProperties +from bpy.types import Menu class USERPREF_MT_keyconfigs(Menu): diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index 87e4738b70e..20f5b471784 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -19,7 +19,7 @@ # <pep8 compliant> import bpy from bpy.types import Header, Menu, Panel -from .properties_paint_common import UnifiedPaintPanel +from bl_ui.properties_paint_common import UnifiedPaintPanel class VIEW3D_HT_header(Header): @@ -54,6 +54,8 @@ class VIEW3D_HT_header(Header): sub.menu("VIEW3D_MT_%s" % mode_string.lower()) if mode_string in {'SCULPT', 'PAINT_VERTEX', 'PAINT_WEIGHT', 'PAINT_TEXTURE'}: sub.menu("VIEW3D_MT_brush") + if mode_string == 'SCULPT': + sub.menu("VIEW3D_MT_hide") else: sub.menu("VIEW3D_MT_object") @@ -91,7 +93,7 @@ class VIEW3D_HT_header(Header): if snap_element != 'INCREMENT': row.prop(toolsettings, "snap_target", text="") if obj: - if obj.mode == 'OBJECT': + if obj.mode == 'OBJECT' and snap_element != 'VOLUME': row.prop(toolsettings, "use_snap_align_rotation", text="") elif obj.mode == 'EDIT': row.prop(toolsettings, "use_snap_self", text="") @@ -425,7 +427,7 @@ class VIEW3D_MT_select_object(Menu): layout.separator() - layout.operator("object.select_all", text="Select/Deselect All").action = 'TOGGLE' + layout.operator("object.select_all").action = 'TOGGLE' layout.operator("object.select_all", text="Inverse").action = 'INVERT' layout.operator("object.select_random", text="Random") layout.operator("object.select_mirror", text="Mirror") @@ -450,7 +452,7 @@ class VIEW3D_MT_select_pose(Menu): layout.separator() - layout.operator("pose.select_all", text="Select/Deselect All").action = 'TOGGLE' + layout.operator("pose.select_all").action = 'TOGGLE' layout.operator("pose.select_all", text="Inverse").action = 'INVERT' layout.operator("pose.select_flip_active", text="Flip Active") layout.operator("pose.select_constraint_target", text="Constraint Target") @@ -487,9 +489,9 @@ class VIEW3D_MT_select_particle(Menu): layout.separator() - layout.operator("particle.select_all", text="Select/Deselect All").action = 'TOGGLE' + layout.operator("particle.select_all").action = 'TOGGLE' layout.operator("particle.select_linked") - layout.operator("particle.select_all").action = 'INVERT' + layout.operator("particle.select_all", text="Inverse").action = 'INVERT' layout.separator() @@ -513,7 +515,7 @@ class VIEW3D_MT_select_edit_mesh(Menu): layout.separator() - layout.operator("mesh.select_all", text="Select/Deselect All").action = 'TOGGLE' + layout.operator("mesh.select_all").action = 'TOGGLE' layout.operator("mesh.select_all", text="Inverse").action = 'INVERT' layout.separator() @@ -522,16 +524,15 @@ class VIEW3D_MT_select_edit_mesh(Menu): layout.operator("mesh.select_nth", text="Every N Number of Verts") layout.operator("mesh.edges_select_sharp", text="Sharp Edges") layout.operator("mesh.faces_select_linked_flat", text="Linked Flat Faces") - layout.operator("mesh.faces_select_interior", text="Interior Faces") + layout.operator("mesh.select_interior_faces", text="Interior Faces") layout.operator("mesh.select_axis", text="Side of Active") layout.separator() - layout.operator("mesh.select_by_number_vertices", text="Triangles").type = 'TRIANGLES' - layout.operator("mesh.select_by_number_vertices", text="Quads").type = 'QUADS' + layout.operator("mesh.select_by_number_vertices", text="By Number of Verts") if context.scene.tool_settings.mesh_select_mode[2] == False: layout.operator("mesh.select_non_manifold", text="Non Manifold") - layout.operator("mesh.select_by_number_vertices", text="Loose Verts/Edges").type = 'OTHER' + layout.operator("mesh.select_loose_verts", text="Loose Verts/Edges") layout.operator("mesh.select_similar", text="Similar") layout.separator() @@ -565,7 +566,7 @@ class VIEW3D_MT_select_edit_curve(Menu): layout.separator() - layout.operator("curve.select_all", text="Select/Deselect All").action = 'TOGGLE' + layout.operator("curve.select_all").action = 'TOGGLE' layout.operator("curve.select_all", text="Inverse").action = 'INVERT' layout.operator("curve.select_random") layout.operator("curve.select_nth", text="Every Nth Number of Points") @@ -594,7 +595,7 @@ class VIEW3D_MT_select_edit_surface(Menu): layout.separator() - layout.operator("curve.select_all", text="Select/Deselect All").action = 'TOGGLE' + layout.operator("curve.select_all").action = 'TOGGLE' layout.operator("curve.select_all", text="Inverse").action = 'INVERT' layout.operator("curve.select_random") layout.operator("curve.select_nth", text="Every Nth Number of Points") @@ -620,7 +621,7 @@ class VIEW3D_MT_select_edit_metaball(Menu): layout.separator() layout.operator("mball.select_all").action = 'TOGGLE' - layout.operator("mball.select_all").action = 'INVERT' + layout.operator("mball.select_all", text="Inverse").action = 'INVERT' layout.separator() @@ -637,7 +638,8 @@ class VIEW3D_MT_select_edit_lattice(Menu): layout.separator() - layout.operator("lattice.select_all", text="Select/Deselect All") + layout.operator("lattice.select_all").action = 'TOGGLE' + layout.operator("lattice.select_all", text="Inverse").action = 'INVERT' class VIEW3D_MT_select_edit_armature(Menu): @@ -650,7 +652,7 @@ class VIEW3D_MT_select_edit_armature(Menu): layout.separator() - layout.operator("armature.select_all", text="Select/Deselect All").action = 'TOGGLE' + layout.operator("armature.select_all").action = 'TOGGLE' layout.operator("armature.select_all", text="Inverse").action = 'INVERT' layout.separator() @@ -792,11 +794,17 @@ class VIEW3D_MT_object_specials(Menu): props.data_path_iter = "selected_editable_objects" props.data_path_item = "data.lens" props.input_scale = 0.1 + if obj.data.lens_unit == 'MILLIMETERS': + props.header_text = "Camera Lens Angle: %.1fmm" + else: + props.header_text = "Camera Lens Angle: %.1f\u00B0" + 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 + props.header_text = "Camera Lens Scale: %.3f" if not obj.data.dof_object: #layout.label(text="Test Has DOF obj"); @@ -804,6 +812,7 @@ class VIEW3D_MT_object_specials(Menu): props.data_path_iter = "selected_editable_objects" props.data_path_item = "data.dof_distance" props.input_scale = 0.02 + props.header_text = "DOF Distance: %.3f" if obj.type in {'CURVE', 'FONT'}: layout.operator_context = 'INVOKE_REGION_WIN' @@ -812,11 +821,13 @@ class VIEW3D_MT_object_specials(Menu): props.data_path_iter = "selected_editable_objects" props.data_path_item = "data.extrude" props.input_scale = 0.01 + props.header_text = "Extrude Size: %.3f" props = layout.operator("wm.context_modal_mouse", text="Width Size") props.data_path_iter = "selected_editable_objects" props.data_path_item = "data.offset" props.input_scale = 0.01 + props.header_text = "Width Size: %.3f" if obj.type == 'EMPTY': layout.operator_context = 'INVOKE_REGION_WIN' @@ -825,6 +836,7 @@ class VIEW3D_MT_object_specials(Menu): props.data_path_iter = "selected_editable_objects" props.data_path_item = "empty_draw_size" props.input_scale = 0.01 + props.header_text = "Empty Draw Size: %.3f" if obj.type == 'LAMP': layout.operator_context = 'INVOKE_REGION_WIN' @@ -832,12 +844,14 @@ class VIEW3D_MT_object_specials(Menu): props = layout.operator("wm.context_modal_mouse", text="Energy") props.data_path_iter = "selected_editable_objects" props.data_path_item = "data.energy" + props.header_text = "Lamp Energy: %.3f" if obj.data.type in {'SPOT', 'AREA', 'POINT'}: props = layout.operator("wm.context_modal_mouse", text="Falloff Distance") props.data_path_iter = "selected_editable_objects" props.data_path_item = "data.distance" props.input_scale = 0.1 + props.header_text = "Lamp Falloff Distance: %.1f" if obj.data.type == 'SPOT': layout.separator() @@ -845,21 +859,25 @@ class VIEW3D_MT_object_specials(Menu): props.data_path_iter = "selected_editable_objects" props.data_path_item = "data.spot_size" props.input_scale = 0.01 + props.header_text = "Spot Size: %.2f" props = layout.operator("wm.context_modal_mouse", text="Spot Blend") props.data_path_iter = "selected_editable_objects" props.data_path_item = "data.spot_blend" props.input_scale = -0.01 + props.header_text = "Spot Blend: %.2f" props = layout.operator("wm.context_modal_mouse", text="Clip Start") props.data_path_iter = "selected_editable_objects" props.data_path_item = "data.shadow_buffer_clip_start" props.input_scale = 0.05 + props.header_text = "Clip Start: %.2f" props = layout.operator("wm.context_modal_mouse", text="Clip End") props.data_path_iter = "selected_editable_objects" props.data_path_item = "data.shadow_buffer_clip_end" props.input_scale = 0.05 + props.header_text = "Clip End: %.2f" layout.separator() @@ -1017,7 +1035,7 @@ class VIEW3D_MT_object_game(Menu): layout.operator("object.game_property_clear") - + # ********** Brush menu ********** class VIEW3D_MT_brush(Menu): bl_label = "Brush" @@ -1031,6 +1049,19 @@ class VIEW3D_MT_brush(Menu): ups = context.tool_settings.unified_paint_settings layout.prop(ups, "use_unified_size", text="Unified Size") layout.prop(ups, "use_unified_strength", text="Unified Strength") + layout.separator() + + # brush paint modes + layout.menu("VIEW3D_MT_brush_paint_modes") + + # brush tool + if context.sculpt_object: + layout.operator("brush.reset") + layout.prop_menu_enum(brush, "sculpt_tool") + elif context.image_paint_object: + layout.prop_menu_enum(brush, "image_tool") + elif context.vertex_paint_object or context.weight_paint_object: + layout.prop_menu_enum(brush, "vertex_tool") # skip if no active brush if not brush: @@ -1057,6 +1088,21 @@ class VIEW3D_MT_brush(Menu): layout.prop(brush, "use_persistent") layout.operator("sculpt.set_persistent_base") + +class VIEW3D_MT_brush_paint_modes(Menu): + bl_label = "Enabled Modes" + + def draw(self, context): + layout = self.layout + + settings = UnifiedPaintPanel.paint_settings(context) + brush = settings.brush + + layout.prop(brush, "use_paint_sculpt", text="Sculpt") + layout.prop(brush, "use_paint_vertex", text="Vertex Paint") + layout.prop(brush, "use_paint_weight", text="Weight Paint") + layout.prop(brush, "use_paint_image", text="Texture Paint") + # ********** Vertex paint menu ********** @@ -1142,6 +1188,7 @@ class VIEW3D_MT_paint_weight(Menu): layout.operator("object.vertex_group_invert", text="Invert") layout.operator("object.vertex_group_clean", text="Clean") layout.operator("object.vertex_group_levels", text="Levels") + layout.operator("object.vertex_group_blend", text="Blend") layout.operator("object.vertex_group_fix", text="Fix Deforms") layout.separator() @@ -1180,6 +1227,25 @@ class VIEW3D_MT_sculpt(Menu): layout.prop(sculpt, "use_deform_only") +class VIEW3D_MT_hide(Menu): + bl_label = "Hide" + + def draw(self, context): + layout = self.layout + + op = layout.operator("paint.hide_show", text="Show All") + op.action = 'SHOW' + op.area = 'ALL' + + op = layout.operator("paint.hide_show", text="Hide Bounding Box") + op.action = 'HIDE' + op.area = 'INSIDE' + + op = layout.operator("paint.hide_show", text="Show Bounding Box") + op.action = 'SHOW' + op.area = 'INSIDE' + + # ********** Particle menu ********** @@ -1503,7 +1569,8 @@ class VIEW3D_MT_edit_mesh(Menu): layout.operator("view3d.edit_mesh_extrude_move_normal", text="Extrude Region") layout.operator("view3d.edit_mesh_extrude_individual_move", text="Extrude Individual") layout.operator("mesh.duplicate_move") - layout.operator("mesh.delete", text="Delete...") + layout.menu("VIEW3D_MT_edit_mesh_delete") + layout.menu("VIEW3D_MT_edit_mesh_dissolve") layout.separator() @@ -1537,10 +1604,10 @@ class VIEW3D_MT_edit_mesh_specials(Menu): layout.operator("mesh.remove_doubles") layout.operator("mesh.hide", text="Hide") layout.operator("mesh.reveal", text="Reveal") - layout.operator("mesh.select_all").action = 'INVERT' + layout.operator("mesh.select_all", text="Select Inverse").action = 'INVERT' layout.operator("mesh.flip_normals") layout.operator("mesh.vertices_smooth", text="Smooth") - # layout.operator("mesh.bevel", text="Bevel") + layout.operator("mesh.bevel", text="Bevel") layout.operator("mesh.faces_shade_smooth") layout.operator("mesh.faces_shade_flat") layout.operator("mesh.blend_from_shape") @@ -1614,6 +1681,8 @@ class VIEW3D_MT_edit_mesh_vertices(Menu): layout.operator("mesh.rip_move") layout.operator("mesh.split") layout.operator("mesh.separate") + layout.operator("mesh.vert_connect") + layout.operator("mesh.vert_slide") layout.separator() @@ -1662,6 +1731,12 @@ class VIEW3D_MT_edit_mesh_edges(Menu): layout.separator() + layout.operator("mesh.bevel") + layout.operator("mesh.edge_split") + layout.operator("mesh.bridge_edge_loops") + + layout.separator() + layout.operator("TRANSFORM_OT_edge_slide") layout.operator("TRANSFORM_OT_edge_crease") layout.operator("mesh.loop_multi_select", text="Edge Loop").ring = False @@ -1684,24 +1759,18 @@ class VIEW3D_MT_edit_mesh_faces(Menu): layout.operator_context = 'INVOKE_REGION_WIN' layout.operator("mesh.flip_normals") - # layout.operator("mesh.bevel") - # layout.operator("mesh.bevel") layout.operator("mesh.edge_face_add") layout.operator("mesh.fill") layout.operator("mesh.beautify_fill") + layout.operator("mesh.inset") + layout.operator("mesh.bevel") layout.operator("mesh.solidify") layout.operator("mesh.sort_faces") layout.separator() - layout.operator("mesh.fgon_make") - layout.operator("mesh.fgon_clear") - - layout.separator() - layout.operator("mesh.quads_convert_to_tris") layout.operator("mesh.tris_convert_to_quads") - layout.operator("mesh.edge_flip") layout.separator() @@ -1718,9 +1787,9 @@ class VIEW3D_MT_edit_mesh_faces(Menu): layout.separator() layout.operator_menu_enum("mesh.uvs_rotate", "direction") - layout.operator_menu_enum("mesh.uvs_mirror", "axis") + layout.operator("mesh.uvs_reverse") layout.operator_menu_enum("mesh.colors_rotate", "direction") - layout.operator_menu_enum("mesh.colors_mirror", "axis") + layout.operator("mesh.colors_reverse") class VIEW3D_MT_edit_mesh_normals(Menu): @@ -1737,6 +1806,38 @@ class VIEW3D_MT_edit_mesh_normals(Menu): layout.operator("mesh.flip_normals") +class VIEW3D_MT_edit_mesh_delete(Menu): + bl_label = "Delete" + + def draw(self, context): + layout = self.layout + + layout.operator_enum("mesh.delete", "type") + + layout.separator() + + layout.operator("mesh.dissolve") + layout.operator("mesh.edge_collapse") + layout.operator("mesh.delete_edgeloop") + + +class VIEW3D_MT_edit_mesh_dissolve(Menu): + bl_label = "Dissolve" + + def draw(self, context): + layout = self.layout + + layout.operator("mesh.dissolve") + + layout.separator() + + layout.operator_enum("mesh.dissolve", "type") + + layout.separator() + + layout.operator("mesh.dissolve_limited") + + class VIEW3D_MT_edit_mesh_showhide(ShowHideMenu, Menu): _operator_name = "mesh" @@ -2075,14 +2176,18 @@ class VIEW3D_PT_view3d_properties(Panel): view = context.space_data col = layout.column() - col.active = view.region_3d.view_perspective != 'CAMERA' + col.active = bool(view.region_3d.view_perspective != 'CAMERA' or + view.region_quadview) col.prop(view, "lens") col.label(text="Lock to Object:") col.prop(view, "lock_object", text="") 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="") + 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") @@ -2271,9 +2376,10 @@ class VIEW3D_PT_view3d_meshdisplay(Panel): col.separator() col.label(text="Normals:") - col.prop(mesh, "show_normal_face", text="Face") - col.prop(mesh, "show_normal_vertex", text="Vertex") - col.prop(context.scene.tool_settings, "normal_size", text="Normal Size") + row = col.row(align=True) + row.prop(mesh, "show_normal_vertex", text="", icon='VERTEXSEL') + row.prop(mesh, "show_normal_face", text="", icon='FACESEL') + row.prop(context.scene.tool_settings, "normal_size", text="Size") col.separator() col.label(text="Numerics:") @@ -2377,10 +2483,12 @@ class VIEW3D_PT_background_image(Panel): column.prop(bg.clip_user, "use_render_undistorted") if has_bg: - box.prop(bg, "opacity", slider=True) + col = box.column() + col.prop(bg, "show_on_foreground") + col.prop(bg, "opacity", slider=True) if bg.view_axis != 'CAMERA': - box.prop(bg, "size") - row = box.row(align=True) + col.prop(bg, "size") + row = col.row(align=True) row.prop(bg, "offset_x", text="X") row.prop(bg, "offset_y", text="Y") diff --git a/release/scripts/startup/bl_ui/space_view3d_toolbar.py b/release/scripts/startup/bl_ui/space_view3d_toolbar.py index 5171a6dd47d..52658411fb0 100644 --- a/release/scripts/startup/bl_ui/space_view3d_toolbar.py +++ b/release/scripts/startup/bl_ui/space_view3d_toolbar.py @@ -19,7 +19,7 @@ # <pep8 compliant> import bpy from bpy.types import Menu, Panel -from .properties_paint_common import UnifiedPaintPanel +from bl_ui.properties_paint_common import UnifiedPaintPanel class View3DPanel(): @@ -144,7 +144,7 @@ class VIEW3D_PT_tools_meshedit(View3DPanel, Panel): col = layout.column(align=True) col.label(text="Remove:") - col.operator("mesh.delete") + col.menu("VIEW3D_MT_edit_mesh_delete") col.operator("mesh.merge") col.operator("mesh.remove_doubles") @@ -198,6 +198,8 @@ class VIEW3D_PT_tools_meshedit_options(View3DPanel, Panel): col.label("Edge Select Mode:") col.prop(tool_settings, "edge_path_mode", text="") col.prop(tool_settings, "edge_path_live_unwrap") + col.label("Double Threshold:") + col.prop(tool_settings, "double_threshold", text="") # ********** default tools for editmode_curve **************** @@ -500,7 +502,7 @@ class VIEW3D_PT_tools_brush(Panel, View3DPaintPanel): # Sculpt Mode # elif context.sculpt_object and brush: - tool = brush.sculpt_tool + capabilities = brush.sculpt_capabilities col = layout.column() @@ -519,47 +521,43 @@ class VIEW3D_PT_tools_brush(Panel, View3DPaintPanel): self.prop_unified_size(row, context, brush, "use_pressure_size") - if tool not in {'SNAKE_HOOK', 'GRAB', 'ROTATE'}: + # strength, use_strength_pressure, and use_strength_attenuation + if capabilities.has_strength: col.separator() - row = col.row(align=True) - if brush.use_space and tool != 'SMOOTH': - if brush.use_space_atten: - row.prop(brush, "use_space_atten", toggle=True, text="", icon='LOCKED') + if capabilities.has_space_attenuation: + if brush.use_space_attenuation: + row.prop(brush, "use_space_attenuation", toggle=True, text="", icon='LOCKED') else: - row.prop(brush, "use_space_atten", toggle=True, text="", icon='UNLOCKED') - - self.prop_unified_strength(row, context, brush, "strength", text="Strength") - self.prop_unified_strength(row, context, brush, "use_pressure_strength") + row.prop(brush, "use_space_attenuation", toggle=True, text="", icon='UNLOCKED') - if tool == 'ROTATE': - row = col.row(align=True) self.prop_unified_strength(row, context, brush, "strength", text="Strength") self.prop_unified_strength(row, context, brush, "use_pressure_strength") - if tool != 'SMOOTH': + # auto_smooth_factor and use_inverse_smooth_pressure + if capabilities.has_auto_smooth: col.separator() row = col.row(align=True) row.prop(brush, "auto_smooth_factor", slider=True) row.prop(brush, "use_inverse_smooth_pressure", toggle=True, text="") - if tool in {'GRAB', 'SNAKE_HOOK'}: + # normal_weight + if capabilities.has_normal_weight: col.separator() - row = col.row(align=True) row.prop(brush, "normal_weight", slider=True) - if tool in {'CREASE', 'BLOB'}: + # crease_pinch_factor + if capabilities.has_pinch_factor: col.separator() - row = col.row(align=True) row.prop(brush, "crease_pinch_factor", slider=True, text="Pinch") - if tool not in {'PINCH', 'INFLATE', 'SMOOTH'}: + # use_original_normal and sculpt_plane + if capabilities.has_sculpt_plane: row = col.row(align=True) - col.separator() if brush.use_original_normal: @@ -569,8 +567,8 @@ class VIEW3D_PT_tools_brush(Panel, View3DPaintPanel): row.prop(brush, "sculpt_plane", text="") - #if tool in {'CLAY', 'CLAY_TUBES', 'FLATTEN', 'FILL', 'SCRAPE'}: - if tool in {'CLAY', 'FLATTEN', 'FILL', 'SCRAPE'}: + # plane_offset, use_offset_pressure, use_plane_trim, plane_trim + if capabilities.has_plane_offset: row = col.row(align=True) row.prop(brush, "plane_offset", slider=True) row.prop(brush, "use_offset_pressure", text="") @@ -583,24 +581,28 @@ class VIEW3D_PT_tools_brush(Panel, View3DPaintPanel): row.active = brush.use_plane_trim row.prop(brush, "plane_trim", slider=True, text="Distance") - if tool == 'LAYER': + # height + if capabilities.has_height: row = col.row() row.prop(brush, "height", slider=True, text="Height") + # use_frontface col.separator() - row = col.row() row.prop(brush, "use_frontface", text="Front Faces Only") + # direction col.separator() col.row().prop(brush, "direction", expand=True) - if tool in {'DRAW', 'CREASE', 'BLOB', 'INFLATE', 'LAYER', 'CLAY'}: + # use_accumulate + if capabilities.has_accumulate: col.separator() col.prop(brush, "use_accumulate") - if tool == 'LAYER': + # use_persistent, set_persistent_base + if capabilities.has_persistence: col.separator() ob = context.sculpt_object @@ -714,7 +716,7 @@ class VIEW3D_PT_tools_brush_texture(Panel, View3DPaintPanel): col = layout.column() col.active = tex_slot.map_mode in {'FIXED'} col.label(text="Angle:") - if not brush.use_anchor and brush.sculpt_tool not in {'GRAB', 'SNAKE_HOOK', 'THUMB', 'ROTATE'} and tex_slot.map_mode in {'FIXED'}: + if brush.sculpt_capabilities.has_random_texture_angle: col.prop(brush, "texture_angle_source_random", text="") else: col.prop(brush, "texture_angle_source_no_random", text="") @@ -733,10 +735,6 @@ class VIEW3D_PT_tools_brush_texture(Panel, View3DPaintPanel): col.active = tex_slot.map_mode in {'FIXED', 'TILED'} col.prop(tex_slot, "angle", text="") - #col = layout.column() - #col.prop(brush, "use_random_rotation") - #col.active = (not brush.use_rake) and (not brush.use_anchor) and (brush.sculpt_tool not in {'GRAB', 'SNAKE_HOOK', 'THUMB', 'ROTATE'}) and tex_slot.map_mode in {'FIXED'} - split = layout.split() split.prop(tex_slot, "offset") split.prop(tex_slot, "scale") @@ -759,40 +757,6 @@ class VIEW3D_PT_tools_brush_texture(Panel, View3DPaintPanel): sub.prop(brush, "texture_overlay_alpha", text="Alpha") -class VIEW3D_PT_tools_brush_tool(Panel, View3DPaintPanel): - bl_label = "Tool" - bl_options = {'DEFAULT_CLOSED'} - - @classmethod - def poll(cls, context): - settings = cls.paint_settings(context) - return (settings and settings.brush and - (context.sculpt_object or context.image_paint_object or - context.vertex_paint_object or context.weight_paint_object)) - - def draw(self, context): - layout = self.layout - - settings = self.paint_settings(context) - brush = settings.brush - - col = layout.column(align=True) - - if context.sculpt_object: - col.prop(brush, "sculpt_tool", expand=False, text="") - col.operator("brush.reset") - elif context.image_paint_object: - col.prop(brush, "image_tool", expand=False, text="") - elif context.vertex_paint_object or context.weight_paint_object: - col.prop(brush, "vertex_tool", expand=False, text="") - - row = layout.row(align=True) - row.prop(brush, "use_paint_sculpt", text="", icon='SCULPTMODE_HLT') - row.prop(brush, "use_paint_vertex", text="", icon='VPAINT_HLT') - row.prop(brush, "use_paint_weight", text="", icon='WPAINT_HLT') - row.prop(brush, "use_paint_image", text="", icon='TPAINT_HLT') - - class VIEW3D_PT_tools_brush_stroke(Panel, View3DPaintPanel): bl_label = "Stroke" bl_options = {'DEFAULT_CLOSED'} @@ -832,7 +796,7 @@ class VIEW3D_PT_tools_brush_stroke(Panel, View3DPaintPanel): row.active = brush.use_space row.prop(brush, "spacing", text="Spacing") - if (brush.sculpt_tool not in {'GRAB', 'THUMB', 'SNAKE_HOOK', 'ROTATE'}) and (not brush.use_anchor) and (not brush.use_restore_mesh): + if brush.sculpt_capabilities.has_smooth_stroke: col = layout.column() col.separator() @@ -843,6 +807,7 @@ class VIEW3D_PT_tools_brush_stroke(Panel, View3DPaintPanel): sub.prop(brush, "smooth_stroke_radius", text="Radius", slider=True) sub.prop(brush, "smooth_stroke_factor", text="Factor", slider=True) + if brush.sculpt_capabilities.has_jitter: col.separator() row = col.row(align=True) @@ -869,21 +834,13 @@ class VIEW3D_PT_tools_brush_stroke(Panel, View3DPaintPanel): col.separator() col = layout.column() - col.active = (not brush.use_anchor) and (brush.sculpt_tool not in {'GRAB', 'THUMB', 'ROTATE', 'SNAKE_HOOK'}) + col.active = brush.sculpt_capabilities.has_spacing col.prop(brush, "use_space") row = col.row() row.active = brush.use_space row.prop(brush, "spacing", text="Spacing") - #col.prop(brush, "use_space_atten", text="Adaptive Strength") - #col.prop(brush, "use_adaptive_space", text="Adaptive Spacing") - - #col.separator() - - #if image_paint: - # row.prop(brush, "use_pressure_spacing", toggle=True, text="") - class VIEW3D_PT_tools_brush_curve(Panel, View3DPaintPanel): bl_label = "Curve" @@ -989,8 +946,7 @@ class VIEW3D_PT_tools_brush_appearance(Panel, View3DPaintPanel): col = layout.column() if context.sculpt_object and context.tool_settings.sculpt: - #if brush.sculpt_tool in {'DRAW', 'INFLATE', 'CLAY', 'PINCH', 'CREASE', 'BLOB', 'FLATTEN', 'FILL', 'SCRAPE', 'CLAY_TUBES'}: - if brush.sculpt_tool in {'DRAW', 'INFLATE', 'CLAY', 'PINCH', 'CREASE', 'BLOB', 'FLATTEN', 'FILL', 'SCRAPE'}: + if brush.sculpt_capabilities.has_secondary_color: col.prop(brush, "cursor_color_add", text="Add Color") col.prop(brush, "cursor_color_subtract", text="Subtract Color") else: @@ -1023,6 +979,7 @@ class VIEW3D_PT_tools_weightpaint(View3DPanel, Panel): col.operator("object.vertex_group_invert", text="Invert") col.operator("object.vertex_group_clean", text="Clean") col.operator("object.vertex_group_levels", text="Levels") + col.operator("object.vertex_group_blend", text="Blend") col.operator("object.vertex_group_fix", text="Fix Deforms") @@ -1133,13 +1090,15 @@ class VIEW3D_PT_tools_projectpaint(View3DPanel, Panel): row = split.row() row.active = (ipaint.use_stencil_layer) - row.menu("VIEW3D_MT_tools_projectpaint_stencil", text=mesh.uv_texture_stencil.name) + stencil_text = mesh.uv_texture_stencil.name if mesh.uv_texture_stencil else "" + row.menu("VIEW3D_MT_tools_projectpaint_stencil", text=stencil_text) row.prop(ipaint, "invert_stencil", text="", icon='IMAGE_ALPHA') row = layout.row() row.active = (settings.brush.image_tool == 'CLONE') - row.prop(ipaint, "use_clone_layer", text="Layer") - row.menu("VIEW3D_MT_tools_projectpaint_clone", text=mesh.uv_texture_clone.name) + row.prop(ipaint, "use_clone_layer", text="Clone") + clone_text = mesh.uv_texture_clone.name if mesh.uv_texture_clone else "" + row.menu("VIEW3D_MT_tools_projectpaint_clone", text=clone_text) layout.prop(ipaint, "seam_bleed") diff --git a/release/scripts/startup/keyingsets_builtins.py b/release/scripts/startup/keyingsets_builtins.py index 1caf7c43983..3527ece2bd3 100644 --- a/release/scripts/startup/keyingsets_builtins.py +++ b/release/scripts/startup/keyingsets_builtins.py @@ -38,8 +38,20 @@ from bpy.types import KeyingSetInfo # Built-In KeyingSets +# "Defines" +# Keep these in sync with those in ED_keyframing.h! +ANIM_KS_LOCATION_ID = "Location" +ANIM_KS_ROTATION_ID = "Rotation" +ANIM_KS_SCALING_ID = "Scaling" +ANIM_KS_LOC_ROT_SCALE_ID = "LocRotScale" +ANIM_KS_AVAILABLE_ID = "Available" +ANIM_KS_WHOLE_CHARACTER_ID = "Whole Character" + + # Location class BUILTIN_KSI_Location(KeyingSetInfo): + """Insert a keyframe on each of the location channels""" + bl_idname = ANIM_KS_LOCATION_ID bl_label = "Location" # poll - use predefined callback for selected bones/objects @@ -54,6 +66,8 @@ class BUILTIN_KSI_Location(KeyingSetInfo): # Rotation class BUILTIN_KSI_Rotation(KeyingSetInfo): + """Insert a keyframe on each of the rotation channels""" + bl_idname = ANIM_KS_ROTATION_ID bl_label = "Rotation" # poll - use predefined callback for selected bones/objects @@ -62,12 +76,14 @@ class BUILTIN_KSI_Rotation(KeyingSetInfo): # iterator - use callback for selected bones/objects iterator = keyingsets_utils.RKS_ITER_selected_item - # generator - use callback for location + # generator - use callback for rotation generate = keyingsets_utils.RKS_GEN_rotation # Scale class BUILTIN_KSI_Scaling(KeyingSetInfo): + """Insert a keyframe on each of the scale channels""" + bl_idname = ANIM_KS_SCALING_ID bl_label = "Scaling" # poll - use predefined callback for selected bones/objects @@ -76,7 +92,7 @@ class BUILTIN_KSI_Scaling(KeyingSetInfo): # iterator - use callback for selected bones/objects iterator = keyingsets_utils.RKS_ITER_selected_item - # generator - use callback for location + # generator - use callback for scaling generate = keyingsets_utils.RKS_GEN_scaling # ------------ @@ -84,6 +100,7 @@ class BUILTIN_KSI_Scaling(KeyingSetInfo): # LocRot class BUILTIN_KSI_LocRot(KeyingSetInfo): + """Insert a keyframe on each of the location and rotation channels""" bl_label = "LocRot" # poll - use predefined callback for selected bones/objects @@ -102,6 +119,7 @@ class BUILTIN_KSI_LocRot(KeyingSetInfo): # LocScale class BUILTIN_KSI_LocScale(KeyingSetInfo): + """Insert a keyframe on each of the location and scale channels""" bl_label = "LocScale" # poll - use predefined callback for selected bones/objects @@ -120,6 +138,10 @@ class BUILTIN_KSI_LocScale(KeyingSetInfo): # LocRotScale class BUILTIN_KSI_LocRotScale(KeyingSetInfo): + """ + Insert a keyframe on each of the location, rotation, and scale channels + """ + bl_idname = ANIM_KS_LOC_ROT_SCALE_ID bl_label = "LocRotScale" # poll - use predefined callback for selected bones/objects @@ -140,6 +162,7 @@ class BUILTIN_KSI_LocRotScale(KeyingSetInfo): # RotScale class BUILTIN_KSI_RotScale(KeyingSetInfo): + """Insert a keyframe on each of the rotation and scale channels""" bl_label = "RotScale" # poll - use predefined callback for selected bones/objects @@ -160,6 +183,10 @@ class BUILTIN_KSI_RotScale(KeyingSetInfo): # Location class BUILTIN_KSI_VisualLoc(KeyingSetInfo): + """ + Insert a keyframe on each of the location channels, taking into account + effects of constraints and relationships + """ bl_label = "Visual Location" bl_options = {'INSERTKEY_VISUAL'} @@ -176,6 +203,10 @@ class BUILTIN_KSI_VisualLoc(KeyingSetInfo): # Rotation class BUILTIN_KSI_VisualRot(KeyingSetInfo): + """ + Insert a keyframe on each of the rotation channels, taking into account + effects of constraints and relationships + """ bl_label = "Visual Rotation" bl_options = {'INSERTKEY_VISUAL'} @@ -192,6 +223,10 @@ class BUILTIN_KSI_VisualRot(KeyingSetInfo): # VisualLocRot class BUILTIN_KSI_VisualLocRot(KeyingSetInfo): + """ + Insert a keyframe on each of the location and rotation channels, + taking into account effects of constraints and relationships + """ bl_label = "Visual LocRot" bl_options = {'INSERTKEY_VISUAL'} @@ -214,6 +249,8 @@ class BUILTIN_KSI_VisualLocRot(KeyingSetInfo): # Available class BUILTIN_KSI_Available(KeyingSetInfo): + """Insert a keyframe on each of the already existing F-Curves""" + bl_idname = ANIM_KS_AVAILABLE_ID bl_label = "Available" # poll - selected objects or selected object with animation data @@ -236,6 +273,11 @@ class BUILTIN_KSI_Available(KeyingSetInfo): # All properties that are likely to get animated in a character rig class BUILTIN_KSI_WholeCharacter(KeyingSetInfo): + """ + Insert a keyframe for all properties that are likely to get animated in a + character rig (useful when blocking out a shot) + """ + bl_idname = ANIM_KS_WHOLE_CHARACTER_ID bl_label = "Whole Character" # these prefixes should be avoided, as they are not really bones @@ -379,6 +421,7 @@ class BUILTIN_KSI_WholeCharacter(KeyingSetInfo): # Delta Location class BUILTIN_KSI_DeltaLocation(KeyingSetInfo): + """Insert keyframes for additional location offset""" bl_label = "Delta Location" # poll - selected objects only (and only if active object in object mode) @@ -404,6 +447,7 @@ class BUILTIN_KSI_DeltaLocation(KeyingSetInfo): # Delta Rotation class BUILTIN_KSI_DeltaRotation(KeyingSetInfo): + """Insert keyframes for additional rotation offset""" bl_label = "Delta Rotation" # poll - selected objects only (and only if active object in object mode) @@ -437,6 +481,7 @@ class BUILTIN_KSI_DeltaRotation(KeyingSetInfo): # Delta Scale class BUILTIN_KSI_DeltaScale(KeyingSetInfo): + """Insert keyframes for additional scaling factor""" 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 1fc74ff7348..3900f595584 100644 --- a/release/scripts/templates/addon_add_object.py +++ b/release/scripts/templates/addon_add_object.py @@ -1,6 +1,6 @@ bl_info = { "name": "New Object", - "author": "YourNameHere", + "author": "Your Name Here", "version": (1, 0), "blender": (2, 5, 5), "location": "View3D > Add > Mesh > New Object", @@ -12,8 +12,9 @@ bl_info = { import bpy +from bpy.types import Operator from bpy.props import FloatVectorProperty -from add_utils import AddObjectHelper, add_object_data +from bpy_extras.object_utils import AddObjectHelper, object_data_add from mathutils import Vector @@ -30,14 +31,14 @@ def add_object(self, context): edges = [] faces = [[0, 1, 2, 3]] - mesh = bpy.data.meshes.new(name='New Object Mesh') + mesh = bpy.data.meshes.new(name="New Object Mesh") mesh.from_pydata(verts, edges, faces) # useful for development when the mesh may be invalid. # mesh.validate(verbose=True) - add_object_data(context, mesh, operator=self) + object_data_add(context, mesh, operator=self) -class OBJECT_OT_add_object(bpy.types.Operator, AddObjectHelper): +class OBJECT_OT_add_object(Operator, AddObjectHelper): """Add a Mesh Object""" bl_idname = "mesh.add_object" bl_label = "Add Mesh Object" @@ -45,10 +46,10 @@ class OBJECT_OT_add_object(bpy.types.Operator, AddObjectHelper): bl_options = {'REGISTER', 'UNDO'} scale = FloatVectorProperty( - name='scale', + name="scale", default=(1.0, 1.0, 1.0), subtype='TRANSLATION', - description='scaling', + description="scaling", ) def execute(self, context): @@ -77,5 +78,5 @@ def unregister(): bpy.types.INFO_MT_mesh_add.remove(add_object_button) -if __name__ == '__main__': +if __name__ == "__main__": register() diff --git a/release/scripts/templates/bmesh_simple.py b/release/scripts/templates/bmesh_simple.py new file mode 100644 index 00000000000..656febf4918 --- /dev/null +++ b/release/scripts/templates/bmesh_simple.py @@ -0,0 +1,21 @@ +# This example assumes we have a mesh object selected + +import bpy +import bmesh + +# Get the active mesh +me = bpy.context.object.data + + +# Get a BMesh representation +bm = bmesh.new() # create an empty BMesh +bm.from_mesh(me) # fill it in from a Mesh + + +# Modify the BMesh, can do anything here... +for v in bm.verts: + v.co.x += 1.0 + + +# Finish up, write the bmesh back to the mesh +bm.to_mesh(me) diff --git a/release/scripts/templates/gamelogic_basic.py b/release/scripts/templates/gamelogic_simple.py index dbfcf948b18..dbfcf948b18 100644 --- a/release/scripts/templates/gamelogic_basic.py +++ b/release/scripts/templates/gamelogic_simple.py diff --git a/release/scripts/templates/operator_mesh_add.py b/release/scripts/templates/operator_mesh_add.py index d89b7e82f77..3228e3c4d62 100644 --- a/release/scripts/templates/operator_mesh_add.py +++ b/release/scripts/templates/operator_mesh_add.py @@ -1,4 +1,5 @@ import bpy +import bmesh def add_box(width, height, depth): @@ -7,31 +8,29 @@ def add_box(width, height, depth): no actual mesh data creation is done here. """ - vertices = [1.0, 1.0, -1.0, - 1.0, -1.0, -1.0, - -1.0, -1.0, -1.0, - -1.0, 1.0, -1.0, - 1.0, 1.0, 1.0, - 1.0, -1.0, 1.0, - -1.0, -1.0, 1.0, - -1.0, 1.0, 1.0, - ] - - faces = [0, 1, 2, 3, - 4, 7, 6, 5, - 0, 4, 5, 1, - 1, 5, 6, 2, - 2, 6, 7, 3, - 4, 0, 3, 7, + verts = [(+1.0, +1.0, -1.0), + (+1.0, -1.0, -1.0), + (-1.0, -1.0, -1.0), + (-1.0, +1.0, -1.0), + (+1.0, +1.0, +1.0), + (+1.0, -1.0, +1.0), + (-1.0, -1.0, +1.0), + (-1.0, +1.0, +1.0), + ] + + faces = [(0, 1, 2, 3), + (4, 7, 6, 5), + (0, 4, 5, 1), + (1, 5, 6, 2), + (2, 6, 7, 3), + (4, 0, 3, 7), ] # apply size - for i in range(0, len(vertices), 3): - vertices[i] *= width - vertices[i + 1] *= depth - vertices[i + 2] *= height + for i, v in enumerate(verts): + verts[i] = v[0] * width, v[1] * depth, v[2] * height - return vertices, faces + return verts, faces from bpy.props import FloatProperty, BoolProperty, FloatVectorProperty @@ -85,11 +84,15 @@ class AddBox(bpy.types.Operator): mesh = bpy.data.meshes.new("Box") - mesh.vertices.add(len(verts_loc) // 3) - mesh.faces.add(len(faces) // 4) + bm = bmesh.new() - mesh.vertices.foreach_set("co", verts_loc) - mesh.faces.foreach_set("vertices_raw", faces) + for v_co in verts_loc: + bm.verts.new(v_co) + + for f_idx in faces: + bm.faces.new([bm.verts[i] for i in f_idx]) + + bm.to_mesh(mesh) mesh.update() # add the mesh as an object into the scene with this utility module diff --git a/release/scripts/templates/ui_panel_simple.py b/release/scripts/templates/ui_panel_simple.py index cde6126b626..6226240ff87 100644 --- a/release/scripts/templates/ui_panel_simple.py +++ b/release/scripts/templates/ui_panel_simple.py @@ -2,6 +2,7 @@ import bpy class HelloWorldPanel(bpy.types.Panel): + """Creates a Panel in the Object properties window""" bl_label = "Hello World Panel" bl_idname = "OBJECT_PT_hello" bl_space_type = "PROPERTIES" |