diff options
Diffstat (limited to 'release/scripts/startup')
50 files changed, 1455 insertions, 295 deletions
diff --git a/release/scripts/startup/bl_operators/__init__.py b/release/scripts/startup/bl_operators/__init__.py index 65f7bde1809..4047505652f 100644 --- a/release/scripts/startup/bl_operators/__init__.py +++ b/release/scripts/startup/bl_operators/__init__.py @@ -54,7 +54,7 @@ if bpy.app.build_options.freestyle: _modules.append("freestyle") __import__(name=__name__, fromlist=_modules) _namespace = globals() -_modules_loaded = {name: _namespace[name] for name in _modules if name != 'bpy'} +_modules_loaded = {name: _namespace[name] for name in _modules if name != "bpy"} del _namespace diff --git a/release/scripts/startup/bl_operators/add_mesh_torus.py b/release/scripts/startup/bl_operators/add_mesh_torus.py index dfb734e9b5b..82014c87be9 100644 --- a/release/scripts/startup/bl_operators/add_mesh_torus.py +++ b/release/scripts/startup/bl_operators/add_mesh_torus.py @@ -153,40 +153,40 @@ class AddTorus(Operator, object_utils.AddObjectHelper): col = layout.column(align=True) col.label(text="Location") - col.prop(self, 'location', text="") + col.prop(self, "location", text="") col = layout.column(align=True) col.label(text="Rotation") - col.prop(self, 'rotation', text="") + col.prop(self, "rotation", text="") col = layout.column(align=True) col.label(text="Major Segments") - col.prop(self, 'major_segments', text="") + col.prop(self, "major_segments", text="") col = layout.column(align=True) col.label(text="Minor Segments") - col.prop(self, 'minor_segments', text="") + col.prop(self, "minor_segments", text="") col = layout.column(align=True) col.label(text="Torus Dimensions") - col.row().prop(self, 'mode', expand=True) + col.row().prop(self, "mode", expand=True) if self.mode == 'MAJOR_MINOR': col = layout.column(align=True) col.label(text="Major Radius") - col.prop(self, 'major_radius', text="") + col.prop(self, "major_radius", text="") col = layout.column(align=True) col.label(text="Minor Radius") - col.prop(self, 'minor_radius', text="") + col.prop(self, "minor_radius", text="") else: col = layout.column(align=True) col.label(text="Exterior Radius") - col.prop(self, 'abso_major_rad', text="") + col.prop(self, "abso_major_rad", text="") col = layout.column(align=True) col.label(text="Interior Radius") - col.prop(self, 'abso_minor_rad', text="") + col.prop(self, "abso_minor_rad", text="") def invoke(self, context, event): object_utils.object_add_grid_scale_apply_operator(self, context) diff --git a/release/scripts/startup/bl_operators/anim.py b/release/scripts/startup/bl_operators/anim.py index 1b3e719b2bd..a1b10976fe0 100644 --- a/release/scripts/startup/bl_operators/anim.py +++ b/release/scripts/startup/bl_operators/anim.py @@ -29,6 +29,7 @@ import bpy from bpy.types import Operator from bpy.props import ( IntProperty, + FloatProperty, BoolProperty, EnumProperty, StringProperty, @@ -210,6 +211,19 @@ class BakeAction(Operator): description="Bake animation onto the object then clear parents (objects only)", default=False, ) + use_current_action = BoolProperty( + name="Overwrite Current Action", + description="Bake animation into current action, instead of creating a new one " + "(useful for baking only part of bones in an armature)", + default=False, + ) + clean_threshold = FloatProperty( + name="Clean Threshold", + description="Allowed error when simplifying baked curves (set to zero to disable)", + default=0.1, + min=0.0, + max=1.0, + ) bake_types = EnumProperty( name="Bake Data", description="Which data's transformations to bake", @@ -221,9 +235,14 @@ class BakeAction(Operator): ) def execute(self, context): - from bpy_extras import anim_utils + action = None + if self.use_current_action: + obj = context.object + if obj.animation_data: + action = obj.animation_data.action + action = anim_utils.bake_action(self.frame_start, self.frame_end, frame_step=self.step, @@ -234,6 +253,8 @@ class BakeAction(Operator): do_constraint_clear=self.clear_constraints, do_parents_clear=self.clear_parents, do_clean=True, + clean_threshold=self.clean_threshold, + action=action, ) if action is None: diff --git a/release/scripts/startup/bl_operators/clip.py b/release/scripts/startup/bl_operators/clip.py index 7e4e0ea9246..0c77ea2ab7e 100644 --- a/release/scripts/startup/bl_operators/clip.py +++ b/release/scripts/startup/bl_operators/clip.py @@ -225,7 +225,8 @@ class CLIP_OT_track_to_empty(Operator): bl_label = "Link Empty to Track" bl_options = {'UNDO', 'REGISTER'} - def _link_track(self, context, clip, tracking_object, track): + @staticmethod + def _link_track(context, clip, tracking_object, track): sc = context.space_data constraint = None ob = None @@ -331,7 +332,8 @@ class CLIP_OT_delete_proxy(Operator): return wm.invoke_confirm(self, event) - def _rmproxy(self, abspath): + @staticmethod + def _rmproxy(abspath): import shutil if not os.path.exists(abspath): @@ -552,8 +554,8 @@ class CLIP_OT_setup_tracking_scene(Operator): world.light_settings.sample_method = 'ADAPTIVE_QMC' world.light_settings.samples = 7 world.light_settings.threshold = 0.005 - if hasattr(scene, 'cycles'): - world.light_settings.ao_factor = 0.05 + if hasattr(scene, "cycles"): + world.light_settings.ao_factor = 0.05 @staticmethod def _findOrCreateCamera(context): @@ -841,7 +843,7 @@ class CLIP_OT_setup_tracking_scene(Operator): self._offsetNodes(tree) scene.render.alpha_mode = 'TRANSPARENT' - if hasattr(scene, 'cycles'): + if hasattr(scene, "cycles"): scene.cycles.film_transparent = True @staticmethod diff --git a/release/scripts/startup/bl_operators/image.py b/release/scripts/startup/bl_operators/image.py index 1653459bd71..f00f5d97c5e 100644 --- a/release/scripts/startup/bl_operators/image.py +++ b/release/scripts/startup/bl_operators/image.py @@ -33,7 +33,8 @@ class EditExternally(Operator): subtype='FILE_PATH', ) - def _editor_guess(self, context): + @staticmethod + def _editor_guess(context): import sys image_editor = context.user_preferences.filepaths.image_editor diff --git a/release/scripts/startup/bl_operators/mask.py b/release/scripts/startup/bl_operators/mask.py index 60208d27338..aa984659430 100644 --- a/release/scripts/startup/bl_operators/mask.py +++ b/release/scripts/startup/bl_operators/mask.py @@ -18,7 +18,6 @@ # <pep8-80 compliant> -import bpy from bpy.types import Menu diff --git a/release/scripts/startup/bl_operators/mesh.py b/release/scripts/startup/bl_operators/mesh.py index f86c31cd9cc..ea504d48448 100644 --- a/release/scripts/startup/bl_operators/mesh.py +++ b/release/scripts/startup/bl_operators/mesh.py @@ -75,7 +75,6 @@ class MeshMirrorUV(Operator): double_warn += co in mirror_lt mirror_lt[co] = i - #for i, v in enumerate(mesh.vertices): vmap = {} for mirror_a, mirror_b in ((mirror_gt, mirror_lt), (mirror_lt, mirror_gt)): diff --git a/release/scripts/startup/bl_operators/object.py b/release/scripts/startup/bl_operators/object.py index e3ceeca8abe..b89890a223c 100644 --- a/release/scripts/startup/bl_operators/object.py +++ b/release/scripts/startup/bl_operators/object.py @@ -579,7 +579,8 @@ class MakeDupliFace(Operator): bl_label = "Make Dupli-Face" bl_options = {'REGISTER', 'UNDO'} - def _main(self, context): + @staticmethod + def _main(context): from mathutils import Vector SCALE_FAC = 0.01 @@ -643,6 +644,9 @@ class MakeDupliFace(Operator): ob_new.use_dupli_faces_scale = True ob_new.dupli_faces_scale = 1.0 / SCALE_FAC + ob_inst.select = True + ob_new.select = True + def execute(self, context): self._main(context) return {'FINISHED'} @@ -924,7 +928,7 @@ class LodGenerate(Operator): lod.location.y = ob.location.y + 3.0 * i if i == 1: - modifier = lod.modifiers.new("lod_decimate", "DECIMATE") + modifier = lod.modifiers.new("lod_decimate", 'DECIMATE') else: modifier = lod.modifiers[-1] diff --git a/release/scripts/startup/bl_operators/object_align.py b/release/scripts/startup/bl_operators/object_align.py index e843209da3c..3c84e5dc553 100644 --- a/release/scripts/startup/bl_operators/object_align.py +++ b/release/scripts/startup/bl_operators/object_align.py @@ -70,7 +70,8 @@ def GlobalBB_HQ(obj): # Initialize the variables with the last vertex - verts = obj.data.vertices + me = obj.to_mesh(scene=bpy.context.scene, apply_modifiers=True, settings='PREVIEW') + verts = me.vertices val = matrix_world * verts[-1].co @@ -111,6 +112,8 @@ def GlobalBB_HQ(obj): if val > up: up = val + bpy.data.meshes.remove(me) + return Vector((left, front, up)), Vector((right, back, down)) @@ -338,7 +341,10 @@ def align_objects(context, return True -from bpy.props import EnumProperty, BoolProperty +from bpy.props import ( + EnumProperty, + BoolProperty + ) class AlignObjects(Operator): diff --git a/release/scripts/startup/bl_operators/object_quick_effects.py b/release/scripts/startup/bl_operators/object_quick_effects.py index 24e471ecfba..414855c7e35 100644 --- a/release/scripts/startup/bl_operators/object_quick_effects.py +++ b/release/scripts/startup/bl_operators/object_quick_effects.py @@ -75,7 +75,7 @@ class QuickFur(Operator): def execute(self, context): fake_context = context.copy() mesh_objects = [obj for obj in context.selected_objects - if obj.type == 'MESH'] + if obj.type == 'MESH' and obj.mode == 'OBJECT'] if not mesh_objects: self.report({'ERROR'}, "Select at least one mesh object") diff --git a/release/scripts/startup/bl_operators/presets.py b/release/scripts/startup/bl_operators/presets.py index 7195b7819d1..ffaf1b7817b 100644 --- a/release/scripts/startup/bl_operators/presets.py +++ b/release/scripts/startup/bl_operators/presets.py @@ -45,12 +45,51 @@ class AddPresetBase: options={'HIDDEN', 'SKIP_SAVE'}, ) + # needed for mix-ins + order = [ + "name", + "remove_active", + ] + @staticmethod def as_filename(name): # could reuse for other presets for char in " !@#$%^&*(){}:\";'[]<>,.\\/?": name = name.replace(char, '_') return name.lower().strip() + def write_preset_py(self, file_preset): + def rna_recursive_attr_expand(value, rna_path_step, level): + if isinstance(value, bpy.types.PropertyGroup): + for sub_value_attr in value.bl_rna.properties.keys(): + if sub_value_attr == "rna_type": + continue + sub_value = getattr(value, sub_value_attr) + rna_recursive_attr_expand(sub_value, "%s.%s" % (rna_path_step, sub_value_attr), level) + elif type(value).__name__ == "bpy_prop_collection_idprop": # could use nicer method + file_preset.write("%s.clear()\n" % rna_path_step) + for sub_value in value: + file_preset.write("item_sub_%d = %s.add()\n" % (level, rna_path_step)) + rna_recursive_attr_expand(sub_value, "item_sub_%d" % level, level + 1) + else: + # convert thin wrapped sequences + # to simple lists to repr() + try: + value = value[:] + except: + pass + + file_preset.write("%s = %r\n" % (rna_path_step, value)) + + if hasattr(self, "preset_defines"): + for rna_path in self.preset_defines: + exec(rna_path) + file_preset.write("%s\n" % rna_path) + file_preset.write("\n") + + for rna_path in self.preset_values: + value = eval(rna_path) + rna_recursive_attr_expand(value, rna_path, 1) + def execute(self, context): import os @@ -95,41 +134,10 @@ class AddPresetBase: filepath, preset_menu_class.preset_xml_map) else: - - def rna_recursive_attr_expand(value, rna_path_step, level): - if isinstance(value, bpy.types.PropertyGroup): - for sub_value_attr in value.bl_rna.properties.keys(): - if sub_value_attr == "rna_type": - continue - sub_value = getattr(value, sub_value_attr) - rna_recursive_attr_expand(sub_value, "%s.%s" % (rna_path_step, sub_value_attr), level) - elif type(value).__name__ == "bpy_prop_collection_idprop": # could use nicer method - file_preset.write("%s.clear()\n" % rna_path_step) - for sub_value in value: - file_preset.write("item_sub_%d = %s.add()\n" % (level, rna_path_step)) - rna_recursive_attr_expand(sub_value, "item_sub_%d" % level, level + 1) - else: - # convert thin wrapped sequences - # to simple lists to repr() - try: - value = value[:] - except: - pass - - file_preset.write("%s = %r\n" % (rna_path_step, value)) - file_preset = open(filepath, 'w') file_preset.write("import bpy\n") - if hasattr(self, "preset_defines"): - for rna_path in self.preset_defines: - exec(rna_path) - file_preset.write("%s\n" % rna_path) - file_preset.write("\n") - - for rna_path in self.preset_values: - value = eval(rna_path) - rna_recursive_attr_expand(value, rna_path, 1) + self.write_preset_py(file_preset) file_preset.close() @@ -395,6 +403,93 @@ class AddPresetHairDynamics(AddPresetBase, Operator): ] +class AddPresetCacheLibraryHairSimulation(AddPresetBase, Operator): + """Add or remove a Hair Simulation Preset""" + bl_idname = "cachelibrary.hair_simulation_preset_add" + bl_label = "Add Hair Simulation Preset" + preset_menu = "CACHELIBRARY_MT_hair_simulation_presets" + + # XXX cache_modifier should be stored in the context, but using a confirm popup + # for the operator causes this to get lost + modifier_name = StringProperty(name="Modifier Name") + + ''' + preset_defines = [ + "cachelib = bpy.context.cache_library", + "md = bpy.context.cache_modifier", + ] + ''' + + @property + def preset_defines(self): + return [ + "cachelib = bpy.context.object.cache_library", + "md = cachelib.modifiers[%r]" % self.modifier_name, + "params = md.parameters", + ] + + preset_subdir = "cachelibrary_hair_simulation" + + preset_values = [ + "params.substeps", + "params.timescale", + "params.mass", + "params.drag", + "params.stretch_stiffness", + "params.stretch_damping", + "params.bend_stiffness", + "params.bend_damping", + "params.use_bend_stiffness_curve", + "params.goal_stiffness", + "params.goal_damping", + "params.use_goal_stiffness_curve", + "params.use_goal_deflect", + ] + + def write_curve_map(self, file_preset, cuma, prop): + if cuma is None: + return + + file_preset.write("from mathutils import *\n") + + file_preset.write("cuma = %s\n" % prop) + file_preset.write("if cuma:\n") + + file_preset.write(" cuma.black_level = %r\n" % cuma.black_level) + file_preset.write(" cuma.white_level = %r\n" % cuma.white_level) + + file_preset.write(" cuma.use_clip = %r\n" % cuma.use_clip) + if cuma.use_clip: + file_preset.write(" cuma.clip_min_x = %r\n" % cuma.clip_min_x) + file_preset.write(" cuma.clip_max_x = %r\n" % cuma.clip_max_x) + file_preset.write(" cuma.clip_min_y = %r\n" % cuma.clip_min_y) + file_preset.write(" cuma.clip_max_y = %r\n" % cuma.clip_max_y) + + for i, cu in enumerate(cuma.curves): + file_preset.write(" cu = cuma.curves[%d]\n" % i) + file_preset.write(" cu.extend = %r\n" % cu.extend) + file_preset.write(" for p in range(max(len(cu.points) - %d, 0)):\n" % len(cu.points)) + file_preset.write(" cu.points.remove(cu.points[0])\n") + file_preset.write(" for i in range(max(%d - len(cu.points), 0)):\n" % len(cu.points)) + file_preset.write(" cu.points.new(0, 0)\n") + for j, p in enumerate(cu.points): + file_preset.write(" cu.points[%d].handle_type = %r\n" % (j, p.handle_type)) + file_preset.write(" cu.points[%d].location = %r\n" % (j, p.location)) + file_preset.write(" cu.points[%d].select = %r\n" % (j, p.select)) + + file_preset.write(" cuma.update()\n") + + def write_preset_py(self, file_preset): + AddPresetBase.write_preset_py(self, file_preset) + + cachelib = bpy.context.object.cache_library + md = cachelib.modifiers[self.modifier_name] + params = md.parameters + + self.write_curve_map(file_preset, params.bend_stiffness_curve, "params.bend_stiffness_curve") + self.write_curve_map(file_preset, params.goal_stiffness_curve, "params.goal_stiffness_curve") + + class AddPresetSunSky(AddPresetBase, Operator): """Add or remove a Sky & Atmosphere Preset""" bl_idname = "lamp.sunsky_preset_add" diff --git a/release/scripts/startup/bl_operators/screen_play_rendered_anim.py b/release/scripts/startup/bl_operators/screen_play_rendered_anim.py index 3a7a9b99cde..a5565699364 100644 --- a/release/scripts/startup/bl_operators/screen_play_rendered_anim.py +++ b/release/scripts/startup/bl_operators/screen_play_rendered_anim.py @@ -107,11 +107,20 @@ class PlayRenderedAnim(Operator): del file_a, file_b, frame_tmp file = bpy.path.abspath(file) # expand '//' else: + path_valid = True # works for movies and images - file = rd.frame_path(frame=scene.frame_start) + file = rd.frame_path(frame=scene.frame_start, preview=scene.use_preview_range) file = bpy.path.abspath(file) # expand '//' if not os.path.exists(file): self.report({'WARNING'}, "File %r not found" % file) + path_valid = False + + #one last try for full range if we used preview range + if scene.use_preview_range and not path_valid: + file = rd.frame_path(frame=scene.frame_start, preview=False) + file = bpy.path.abspath(file) # expand '//' + if not os.path.exists(file): + self.report({'WARNING'}, "File %r not found" % file) cmd = [player_path] # extra options, fps controls etc. diff --git a/release/scripts/startup/bl_operators/wm.py b/release/scripts/startup/bl_operators/wm.py index a48415caa9b..d923c1869c9 100644 --- a/release/scripts/startup/bl_operators/wm.py +++ b/release/scripts/startup/bl_operators/wm.py @@ -143,6 +143,7 @@ class BRUSH_OT_active_index_set(Operator): "vertex_paint": "use_paint_vertex", "weight_paint": "use_paint_weight", "image_paint": "use_paint_image", + "hair_edit": "use_hair_edit", } def execute(self, context): @@ -719,7 +720,7 @@ class WM_OT_context_modal_mouse(Operator): """Adjust arbitrary values with mouse input""" bl_idname = "wm.context_modal_mouse" bl_label = "Context Modal Mouse" - bl_options = {'GRAB_POINTER', 'BLOCKING', 'UNDO', 'INTERNAL'} + bl_options = {'GRAB_CURSOR', 'BLOCKING', 'UNDO', 'INTERNAL'} data_path_iter = data_path_iter data_path_item = data_path_item @@ -974,10 +975,12 @@ class WM_OT_doc_view_manual(Operator): url = self._lookup_rna_url(rna_id) if url is None: - self.report({'WARNING'}, "No reference available %r, " - "Update info in 'rna_wiki_reference.py' " - " or callback to bpy.utils.manual_map()" % - self.doc_id) + self.report( + {'WARNING'}, + "No reference available %r, " + "Update info in 'rna_manual_reference.py' " + "or callback to bpy.utils.manual_map()" % + self.doc_id) return {'CANCELLED'} else: import webbrowser @@ -1296,9 +1299,13 @@ class WM_OT_properties_remove(Operator): property = rna_property def execute(self, context): + from rna_prop_ui import rna_idprop_ui_prop_clear data_path = self.data_path item = eval("context.%s" % data_path) - del item[self.property] + prop = self.property + del item[prop] + rna_idprop_ui_prop_clear(item, prop) + return {'FINISHED'} diff --git a/release/scripts/startup/bl_ui/__init__.py b/release/scripts/startup/bl_ui/__init__.py index 51117f68558..c110b429aad 100644 --- a/release/scripts/startup/bl_ui/__init__.py +++ b/release/scripts/startup/bl_ui/__init__.py @@ -86,7 +86,7 @@ if bpy.app.build_options.freestyle: _modules.append("properties_freestyle") __import__(name=__name__, fromlist=_modules) _namespace = globals() -_modules_loaded = {name: _namespace[name] for name in _modules if name != 'bpy'} +_modules_loaded = {name: _namespace[name] for name in _modules if name != "bpy"} del _namespace diff --git a/release/scripts/startup/bl_ui/properties_constraint.py b/release/scripts/startup/bl_ui/properties_constraint.py index 9aa67223fc4..b37feb82461 100644 --- a/release/scripts/startup/bl_ui/properties_constraint.py +++ b/release/scripts/startup/bl_ui/properties_constraint.py @@ -38,7 +38,8 @@ class ConstraintButtonsPanel: if con.type not in {'RIGID_BODY_JOINT', 'NULL'}: box.prop(con, "influence") - def space_template(self, layout, con, target=True, owner=True): + @staticmethod + def space_template(layout, con, target=True, owner=True): if target or owner: split = layout.split(percentage=0.2) @@ -55,7 +56,8 @@ class ConstraintButtonsPanel: if owner: row.prop(con, "owner_space", text="") - def target_template(self, layout, con, subtargets=True): + @staticmethod + def target_template(layout, con, subtargets=True): layout.prop(con, "target") # XXX limiting settings for only 'curves' or some type of object if con.target and subtargets: @@ -69,6 +71,7 @@ class ConstraintButtonsPanel: elif con.target.type in {'MESH', 'LATTICE'}: layout.prop_search(con, "subtarget", con.target, "vertex_groups", text="Vertex Group") + @staticmethod def ik_template(self, layout, con): # only used for iTaSC layout.prop(con, "pole_target") @@ -894,7 +897,7 @@ class OBJECT_PT_constraints(ConstraintButtonsPanel, Panel): obj = context.object - if obj.type == 'ARMATURE' and obj.mode in {'POSE'}: + if obj.type == 'ARMATURE' and obj.mode == 'POSE': box = layout.box() box.alert = True # XXX: this should apply to the box background box.label(icon='INFO', text="Constraints for active bone do not live here") diff --git a/release/scripts/startup/bl_ui/properties_data_camera.py b/release/scripts/startup/bl_ui/properties_data_camera.py index c3ed34d7e56..24a67a22c1f 100644 --- a/release/scripts/startup/bl_ui/properties_data_camera.py +++ b/release/scripts/startup/bl_ui/properties_data_camera.py @@ -135,6 +135,35 @@ class DATA_PT_lens(CameraButtonsPanel, Panel): col.prop(cam, "clip_end", text="End") +class DATA_PT_camera_stereoscopy(CameraButtonsPanel, Panel): + bl_label = "Stereoscopy" + COMPAT_ENGINES = {'BLENDER_RENDER'} + + @classmethod + def poll(cls, context): + render = context.scene.render + return (super().poll(context) and render.use_multiview and + render.views_format == 'STEREO_3D') + + def draw(self, context): + layout = self.layout + # render = context.scene.render + st = context.camera.stereo + + col = layout.column() + col.row().prop(st, "convergence_mode", expand=True) + + if st.convergence_mode == 'PARALLEL': + col.prop(st, "viewport_convergence") + else: + col.prop(st, "convergence_distance") + + col.prop(st, "interocular_distance") + + col.label(text="Pivot:") + col.row().prop(st, "pivot", expand=True) + + class DATA_PT_camera(CameraButtonsPanel, Panel): bl_label = "Camera" COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} @@ -184,35 +213,19 @@ class DATA_PT_camera_dof(CameraButtonsPanel, Panel): col = split.column() col.label(text="Focus:") col.prop(cam, "dof_object", text="") - - col = split.column() - col.prop(dof_options, "fstop") sub = col.column() - sub.active = cam.dof_object is None + sub.active = (cam.dof_object is None) sub.prop(cam, "dof_distance", text="Distance") - -class DATA_PT_camera_gpu_dof(Panel): - bl_label = "GPU Depth of Field" - bl_space_type = 'PROPERTIES' - bl_region_type = 'WINDOW' - bl_context = "data" - - def draw(self, context): - layout = self.layout - - cam = context.camera - - dof_options = cam.gpu_dof - col = layout.column(align=True) - col.label("Focus object or distance is set in Depth Of Field Panel") - col.prop(dof_options, "dof_fstop") - col.prop(dof_options, "dof_focal_length") - col.prop(dof_options, "dof_sensor") - - @classmethod - def poll(cls, context): - return context.camera + hq_support = dof_options.is_hq_supported + col = split.column(align=True) + col.label("Viewport:") + sub = col.column() + sub.active = hq_support + sub.prop(dof_options, "use_high_quality") + col.prop(dof_options, "fstop") + if dof_options.use_high_quality and hq_support: + col.prop(dof_options, "blades") class DATA_PT_camera_display(CameraButtonsPanel, Panel): diff --git a/release/scripts/startup/bl_ui/properties_data_curve.py b/release/scripts/startup/bl_ui/properties_data_curve.py index 9277bbe20f9..eb8ffa1fb60 100644 --- a/release/scripts/startup/bl_ui/properties_data_curve.py +++ b/release/scripts/startup/bl_ui/properties_data_curve.py @@ -321,7 +321,7 @@ class DATA_PT_font(CurveButtonsPanelText, Panel): row.label(text="Bold & Italic") row.template_ID(text, "font_bold_italic", open="font.open", unlink="font.unlink") - #layout.prop(text, "font") + # layout.prop(text, "font") split = layout.split() diff --git a/release/scripts/startup/bl_ui/properties_data_lamp.py b/release/scripts/startup/bl_ui/properties_data_lamp.py index 6fef30fa3e6..0121ad46c86 100644 --- a/release/scripts/startup/bl_ui/properties_data_lamp.py +++ b/release/scripts/startup/bl_ui/properties_data_lamp.py @@ -355,6 +355,7 @@ class DATA_PT_spot(DataButtonsPanel, Panel): col = split.column() + col.active = (lamp.shadow_method != 'BUFFER_SHADOW' or lamp.shadow_buffer_type != 'DEEP') col.prop(lamp, "use_halo") sub = col.column(align=True) sub.active = lamp.use_halo diff --git a/release/scripts/startup/bl_ui/properties_data_mesh.py b/release/scripts/startup/bl_ui/properties_data_mesh.py index b2d3b1ff647..6004c294a23 100644 --- a/release/scripts/startup/bl_ui/properties_data_mesh.py +++ b/release/scripts/startup/bl_ui/properties_data_mesh.py @@ -29,8 +29,8 @@ class MESH_MT_vertex_group_specials(Menu): def draw(self, context): layout = self.layout - layout.operator("object.vertex_group_sort", icon='SORTALPHA', text="Sort by Name").sort_type = "NAME" - layout.operator("object.vertex_group_sort", icon='ARMATURE_DATA', text="Sort by Bone Hierarchy").sort_type = "BONE_HIERARCHY" + layout.operator("object.vertex_group_sort", icon='SORTALPHA', text="Sort by Name").sort_type = 'NAME' + layout.operator("object.vertex_group_sort", icon='ARMATURE_DATA', text="Sort by Bone Hierarchy").sort_type = 'BONE_HIERARCHY' layout.operator("object.vertex_group_copy", icon='COPY_ID') layout.operator("object.vertex_group_copy_to_linked", icon='LINK_AREA') layout.operator("object.vertex_group_copy_to_selected", icon='LINK_AREA') @@ -70,7 +70,7 @@ class MESH_UL_vgroups(UIList): layout.prop(vgroup, "name", text="", emboss=False, icon_value=icon) icon = 'LOCKED' if vgroup.lock_weight else 'UNLOCKED' layout.prop(vgroup, "lock_weight", text="", icon=icon, emboss=False) - elif self.layout_type in {'GRID'}: + elif self.layout_type == 'GRID': layout.alignment = 'CENTER' layout.label(text="", icon_value=icon) @@ -105,7 +105,7 @@ class MESH_UL_shape_keys(UIList): else: row.label(text="") row.prop(key_block, "mute", text="", emboss=False) - elif self.layout_type in {'GRID'}: + elif self.layout_type == 'GRID': layout.alignment = 'CENTER' layout.label(text="", icon_value=icon) @@ -117,7 +117,7 @@ class MESH_UL_uvmaps_vcols(UIList): layout.prop(item, "name", text="", emboss=False, icon_value=icon) icon = 'RESTRICT_RENDER_OFF' if item.active_render else 'RESTRICT_RENDER_ON' layout.prop(item, "active_render", text="", icon=icon, emboss=False) - elif self.layout_type in {'GRID'}: + elif self.layout_type == 'GRID': layout.alignment = 'CENTER' layout.label(text="", icon_value=icon) @@ -422,8 +422,8 @@ class DATA_PT_customdata(MeshButtonsPanel, Panel): me = context.mesh col = layout.column() - col.operator("mesh.customdata_clear_mask", icon='X') - col.operator("mesh.customdata_clear_skin", icon='X') + col.operator("mesh.customdata_mask_clear", icon='X') + col.operator("mesh.customdata_skin_clear", icon='X') if me.has_custom_normals: col.operator("mesh.customdata_custom_splitnormals_clear", icon='X') diff --git a/release/scripts/startup/bl_ui/properties_data_modifier.py b/release/scripts/startup/bl_ui/properties_data_modifier.py index 9c9c42b4045..e692a2fdf13 100644 --- a/release/scripts/startup/bl_ui/properties_data_modifier.py +++ b/release/scripts/startup/bl_ui/properties_data_modifier.py @@ -40,12 +40,10 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel): layout.operator_menu_enum("object.modifier_add", "type") for md in ob.modifiers: - layout.subblock_begin(md.name) box = layout.template_modifier(md) if box: # match enum type to our functions, avoids a lookup table. getattr(self, md.type)(box, ob, md) - layout.subblock_end() # the mt.type enum is (ab)used for a lookup on function names # ...to avoid lengthy if statements @@ -265,24 +263,37 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel): row.prop(md, "decimate_type", expand=True) if decimate_type == 'COLLAPSE': + has_vgroup = bool(md.vertex_group) layout.prop(md, "ratio") split = layout.split() - row = split.row(align=True) + + col = split.column() + row = col.row(align=True) row.prop_search(md, "vertex_group", ob, "vertex_groups", text="") row.prop(md, "invert_vertex_group", text="", icon='ARROW_LEFTRIGHT') - split.prop(md, "use_collapse_triangulate") + layout_info = col + + col = split.column() + row = col.row() + row.active = has_vgroup + row.prop(md, "vertex_group_factor") + + col.prop(md, "use_collapse_triangulate") + elif decimate_type == 'UNSUBDIV': layout.prop(md, "iterations") + layout_info = layout else: # decimate_type == 'DISSOLVE': layout.prop(md, "angle_limit") layout.prop(md, "use_dissolve_boundaries") layout.label("Delimit:") row = layout.row() row.prop(md, "delimit") + layout_info = layout - layout.label(text=iface_("Face Count: %d") % md.face_count, translate=False) + layout_info.label(text=iface_("Faces: %d") % md.face_count, translate=False) def DISPLACE(self, layout, ob, md): has_texture = (md.texture is not None) @@ -684,8 +695,12 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel): col.prop(md, "use_preserve_shape") col = split.column() - col.prop(md, "position", slider=True) - col.prop(md, "random_position", text="Random", slider=True) + col2 = col.column(align=True) + col2.prop(md, "position", slider=True) + col2.prop(md, "random_position", text="Random", slider=True) + col2 = col.column(align=True) + col2.prop(md, "rotation", slider=True) + col2.prop(md, "random_rotation", text="Random", slider=True) col = layout.column(align=True) col.prop(md, "index_layer_name", text="Index Layer") @@ -1146,13 +1161,15 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel): self.vertex_weight_mask(layout, ob, md) def SKIN(self, layout, ob, md): - layout.operator("object.skin_armature_create", text="Create Armature") + row = layout.row() + row.operator("object.skin_armature_create", text="Create Armature") + row.operator("mesh.customdata_skin_add") layout.separator() - col = layout.column(align=True) - col.prop(md, "branch_smoothing") - col.prop(md, "use_smooth_shade") + row = layout.row(align=True) + row.prop(md, "branch_smoothing") + row.prop(md, "use_smooth_shade") split = layout.split() @@ -1399,7 +1416,32 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel): row.prop_search(md, "vertex_group", ob, "vertex_groups", text="") sub = row.row(align=True) sub.active = has_vgroup - sub.prop(md, "use_invert_vertex_group", text="", icon='ARROW_LEFTRIGHT') + sub.prop(md, "invert_vertex_group", text="", icon='ARROW_LEFTRIGHT') + + def CORRECTIVE_SMOOTH(self, layout, ob, md): + is_bind = md.is_bind + + layout.prop(md, "factor", text="Factor") + layout.prop(md, "iterations") + + row = layout.row() + row.prop(md, "smooth_type") + + split = layout.split() + + col = split.column() + col.label(text="Vertex Group:") + row = col.row(align=True) + row.prop_search(md, "vertex_group", ob, "vertex_groups", text="") + row.prop(md, "invert_vertex_group", text="", icon='ARROW_LEFTRIGHT') + + col = split.column() + col.prop(md, "use_only_smooth") + col.prop(md, "use_pin_boundary") + + layout.prop(md, "rest_source") + if md.rest_source == 'BIND': + layout.operator("object.correctivesmooth_bind", text="Unbind" if is_bind else "Bind") if __name__ == "__main__": # only for live edit. diff --git a/release/scripts/startup/bl_ui/properties_freestyle.py b/release/scripts/startup/bl_ui/properties_freestyle.py index 2d91c998007..995136b0d97 100644 --- a/release/scripts/startup/bl_ui/properties_freestyle.py +++ b/release/scripts/startup/bl_ui/properties_freestyle.py @@ -74,8 +74,8 @@ class RenderLayerFreestyleButtonsPanel: rd = context.scene.render with_freestyle = bpy.app.build_options.freestyle - return (scene and with_freestyle and rd.use_freestyle - and rd.layers.active and(scene.render.engine in cls.COMPAT_ENGINES)) + return (scene and with_freestyle and rd.use_freestyle and + rd.layers.active and(scene.render.engine in cls.COMPAT_ENGINES)) class RenderLayerFreestyleEditorButtonsPanel(RenderLayerFreestyleButtonsPanel): @@ -95,7 +95,7 @@ class RENDERLAYER_UL_linesets(UIList): if self.layout_type in {'DEFAULT', 'COMPACT'}: layout.prop(lineset, "name", text="", emboss=False, icon_value=icon) layout.prop(lineset, "show_render", text="", index=index) - elif self.layout_type in {'GRID'}: + elif self.layout_type == 'GRID': layout.alignment = 'CENTER' layout.label("", icon_value=icon) @@ -690,10 +690,11 @@ class RENDERLAYER_PT_freestyle_linestyle(RenderLayerFreestyleEditorButtonsPanel, row.prop(linestyle, "texture_spacing", text="Spacing Along Stroke") row = layout.row() - op = row.operator("wm.properties_context_change", - text="Go to Linestyle Textures Properties", - icon='TEXTURE') - op.context = 'TEXTURE' + props = row.operator( + "wm.properties_context_change", + text="Go to Linestyle Textures Properties", + icon='TEXTURE') + props.context = 'TEXTURE' elif linestyle.panel == 'MISC': pass diff --git a/release/scripts/startup/bl_ui/properties_game.py b/release/scripts/startup/bl_ui/properties_game.py index 32a8e734ab6..ceeb45ac485 100644 --- a/release/scripts/startup/bl_ui/properties_game.py +++ b/release/scripts/startup/bl_ui/properties_game.py @@ -100,7 +100,6 @@ class PHYSICS_PT_game_physics(PhysicsButtonsPanel, Panel): sub.prop(game, "damping", text="Translation", slider=True) sub.prop(game, "rotation_damping", text="Rotation", slider=True) - if physics_type == 'RIGID_BODY': layout.separator() split = layout.split() @@ -111,6 +110,7 @@ class PHYSICS_PT_game_physics(PhysicsButtonsPanel, Panel): col.prop(game, "lock_location_y", text="Y") col.prop(game, "lock_location_z", text="Z") + if physics_type == 'RIGID_BODY': col = split.column() col.label(text="Lock Rotation:") col.prop(game, "lock_rotation_x", text="X") @@ -213,15 +213,17 @@ class PHYSICS_PT_game_collision_bounds(PhysicsButtonsPanel, Panel): layout = self.layout game = context.active_object.game - layout.active = game.use_collision_bounds + split = layout.split() + split.active = game.use_collision_bounds - layout.prop(game, "collision_bounds_type", text="Bounds") + col = split.column() + col.prop(game, "collision_bounds_type", text="Bounds") - row = layout.row() + row = col.row() row.prop(game, "collision_margin", text="Margin", slider=True) sub = row.row() - sub.active = game.physics_type not in {'SOFT_BODY', 'CHARACTER'} + sub.active = game.physics_type not in {'SOFT_BODY', 'CHARACTER'} sub.prop(game, "use_collision_compound", text="Compound") layout.separator() @@ -397,7 +399,6 @@ class RENDER_PT_game_shading(RenderButtonsPanel, Panel): col.prop(gs, "use_glsl_lights", text="Lights") col.prop(gs, "use_glsl_shaders", text="Shaders") col.prop(gs, "use_glsl_shadows", text="Shadows") - col.prop(gs, "use_glsl_color_management", text="Color Management") col = split.column() col.prop(gs, "use_glsl_ramps", text="Ramps") @@ -523,6 +524,26 @@ class SCENE_PT_game_navmesh(SceneButtonsPanel, Panel): row.prop(rd, "sample_max_error") +class SCENE_PT_game_hysteresis(SceneButtonsPanel, Panel): + bl_label = "Level of Detail" + COMPAT_ENGINES = {'BLENDER_GAME'} + + @classmethod + def poll(cls, context): + scene = context.scene + return (scene and scene.render.engine in cls.COMPAT_ENGINES) + + def draw(self, context): + layout = self.layout + gs = context.scene.game_settings + + row = layout.row() + row.prop(gs, "use_scene_hysteresis", text="Hysteresis") + row = layout.row() + row.active = gs.use_scene_hysteresis + row.prop(gs, "scene_hysteresis_percentage", text="") + + class WorldButtonsPanel: bl_space_type = 'PROPERTIES' bl_region_type = 'WINDOW' @@ -712,6 +733,8 @@ class DATA_PT_shadow_game(DataButtonsPanel, Panel): col = split.column() col.prop(lamp, "shadow_color", text="") + if lamp.type == 'SUN': + col.prop(lamp, "show_shadow_box") col = split.column() col.prop(lamp, "use_shadow_layer", text="This Layer Only") @@ -765,6 +788,7 @@ class OBJECT_PT_levels_of_detail(ObjectButtonsPanel, Panel): def draw(self, context): layout = self.layout ob = context.object + gs = context.scene.game_settings col = layout.column() @@ -782,6 +806,13 @@ class OBJECT_PT_levels_of_detail(ObjectButtonsPanel, Panel): row.prop(level, "use_mesh", text="") row.prop(level, "use_material", text="") + row = box.row() + row.active = gs.use_scene_hysteresis + row.prop(level, "use_object_hysteresis", text="Hysteresis Override") + row = box.row() + row.active = gs.use_scene_hysteresis and level.use_object_hysteresis + row.prop(level, "object_hysteresis_percentage", text="") + row = col.row(align=True) row.operator("object.lod_add", text="Add", icon='ZOOMIN') row.menu("OBJECT_MT_lod_tools", text="", icon='TRIA_DOWN') diff --git a/release/scripts/startup/bl_ui/properties_grease_pencil_common.py b/release/scripts/startup/bl_ui/properties_grease_pencil_common.py index 5b5a7648d83..e86fc79e343 100644 --- a/release/scripts/startup/bl_ui/properties_grease_pencil_common.py +++ b/release/scripts/startup/bl_ui/properties_grease_pencil_common.py @@ -321,7 +321,7 @@ class GPENCIL_UL_layer(UIList): row = layout.row(align=True) row.prop(gpl, "lock", text="", emboss=False) row.prop(gpl, "hide", text="", emboss=False) - elif self.layout_type in {'GRID'}: + elif self.layout_type == 'GRID': layout.alignment = 'CENTER' layout.label(text="", icon_value=icon) @@ -414,9 +414,7 @@ class GreasePencilDataPanel: col = split.column(align=True) col.prop(gpl, "show_x_ray") - - # if debug: - # layout.prop(gpl, "show_points") + col.prop(gpl, "show_points", text="Points") layout.separator() diff --git a/release/scripts/startup/bl_ui/properties_mask_common.py b/release/scripts/startup/bl_ui/properties_mask_common.py index cb4a0f5bb85..f4836da50bc 100644 --- a/release/scripts/startup/bl_ui/properties_mask_common.py +++ b/release/scripts/startup/bl_ui/properties_mask_common.py @@ -36,7 +36,7 @@ class MASK_UL_layers(UIList): row.prop(mask, "hide", text="", emboss=False) row.prop(mask, "hide_select", text="", emboss=False) row.prop(mask, "hide_render", text="", emboss=False) - elif self.layout_type in {'GRID'}: + elif self.layout_type == 'GRID': layout.alignment = 'CENTER' layout.label(text="", icon_value=icon) @@ -190,7 +190,7 @@ class MASK_PT_point: col.prop_search(parent, "parent", tracking, "objects", icon='OBJECT_DATA', text="Object:") - tracks_list = "tracks" if parent.type == 'POINT_TRACK' else 'plane_tracks' + tracks_list = "tracks" if parent.type == 'POINT_TRACK' else "plane_tracks" if parent.parent in tracking.objects: object = tracking.objects[parent.parent] diff --git a/release/scripts/startup/bl_ui/properties_material.py b/release/scripts/startup/bl_ui/properties_material.py index 20143b81d14..d916007ea41 100644 --- a/release/scripts/startup/bl_ui/properties_material.py +++ b/release/scripts/startup/bl_ui/properties_material.py @@ -87,7 +87,7 @@ class MATERIAL_UL_matslots(UIList): layout.label(text=iface_("Node %s") % manode.name, translate=False, icon_value=layout.icon(manode)) elif ma.use_nodes: layout.label(text="Node <none>") - elif self.layout_type in {'GRID'}: + elif self.layout_type == 'GRID': layout.alignment = 'CENTER' layout.label(text="", icon_value=icon) @@ -123,11 +123,16 @@ class MATERIAL_PT_context_material(MaterialButtonsPanel, Panel): ob = context.object slot = context.material_slot space = context.space_data + is_sortable = (len(ob.material_slots) > 1) if ob: + rows = 1 + if is_sortable: + rows = 4 + row = layout.row() - row.template_list("MATERIAL_UL_matslots", "", ob, "material_slots", ob, "active_material_index", rows=1) + row.template_list("MATERIAL_UL_matslots", "", ob, "material_slots", ob, "active_material_index", rows=rows) col = row.column(align=True) col.operator("object.material_slot_add", icon='ZOOMIN', text="") @@ -135,6 +140,12 @@ class MATERIAL_PT_context_material(MaterialButtonsPanel, Panel): col.menu("MATERIAL_MT_specials", icon='DOWNARROW_HLT', text="") + if is_sortable: + col.separator() + + col.operator("object.material_slot_move", icon='TRIA_UP', text="").direction = 'UP' + col.operator("object.material_slot_move", icon='TRIA_DOWN', text="").direction = 'DOWN' + if ob.mode == 'EDIT': row = layout.row(align=True) row.operator("object.material_slot_assign", text="Assign") @@ -867,12 +878,14 @@ class MATERIAL_PT_transp_game(MaterialButtonsPanel, Panel): base_mat = context.material mat = active_node_mat(base_mat) + layout.active = mat.use_transparency + if simple_material(base_mat): row = layout.row() - row.active = mat.use_transparency row.prop(mat, "transparency_method", expand=True) layout.prop(mat, "alpha") + layout.prop(mat, "specular_alpha", text="Specular") class VolumeButtonsPanel: diff --git a/release/scripts/startup/bl_ui/properties_object.py b/release/scripts/startup/bl_ui/properties_object.py index b6a2792acd4..cba1454086c 100644 --- a/release/scripts/startup/bl_ui/properties_object.py +++ b/release/scripts/startup/bl_ui/properties_object.py @@ -18,8 +18,9 @@ # <pep8 compliant> import bpy -from bpy.types import Panel, Menu +from bpy.types import Panel, Menu, UIList from rna_prop_ui import PropertyPanel +from bl_ui.properties_physics_common import effector_weights_ui class ObjectButtonsPanel: @@ -261,6 +262,62 @@ class OBJECT_PT_display(ObjectButtonsPanel, Panel): row.prop(obj, "show_wire_color", text="", toggle=True, icon='WIRE') +# XXX temporary solution +bpy.types.CacheLibrary.filter_string = \ + bpy.props.StringProperty( + name="Filter Object Name", + description="Filter cache library objects by name", + ) +bpy.types.CacheLibrary.show_metadata = \ + bpy.props.BoolProperty( + name="Show Metadata", + description="Show metadata for the input archive", + default=False, + ) + + +def cachelib_objects(cachelib, group): + if not cachelib or not group: + return [] + + filter_string = cachelib.filter_string.lower() + if filter_string: + return filter(lambda ob: filter_string in ob.name.lower(), group.objects) + else: + return group.objects + +# Yields (type, index, enabled) +def cachelib_object_items(cachelib, ob): + filter_types = cachelib.data_types + + def items_desc(): + yield 'OBJECT', -1 + + if (ob.type == 'MESH'): + yield 'DERIVED_MESH', -1 + + for index, psys in enumerate(ob.particle_systems): + if psys.settings.type == 'EMITTER': + yield 'PARTICLES', index + if psys.settings.type == 'HAIR': + yield 'HAIR', index + yield 'HAIR_PATHS', index + + for datatype, index in items_desc(): + show = False + enable = False + # always show selected types + if datatype in filter_types: + show = True + enable = True + # special case: OBJECT type used as top level, show but disable + elif datatype == 'OBJECT': + show = True + enable = False + + if show: + yield datatype, index, enable + class OBJECT_PT_duplication(ObjectButtonsPanel, Panel): bl_label = "Duplication" @@ -298,6 +355,470 @@ class OBJECT_PT_duplication(ObjectButtonsPanel, Panel): layout.prop(ob, "dupli_group", text="Group") + +class CACHELIB_MT_shape_key_specials(Menu): + bl_label = "Shape Key Specials" + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} + + def draw(self, context): + layout = self.layout + + #layout.operator("object.shape_key_transfer", icon='COPY_ID') # icon is not ideal + #layout.operator("object.join_shapes", icon='COPY_ID') # icon is not ideal + layout.operator("cachelibrary.shape_key_add", icon='ZOOMIN', text="New Shape From Mix").from_mix = True + layout.operator("cachelibrary.shape_key_remove", icon='X', text="Delete All Shapes").all = True + layout.operator("cachelibrary.shape_key_move", icon='TRIA_UP_BAR', text="Move To Top").type = 'TOP' + layout.operator("cachelibrary.shape_key_move", icon='TRIA_DOWN_BAR', text="Move To Bottom").type = 'BOTTOM' + + +class CACHELIB_UL_shape_keys(UIList): + def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index): + # assert(isinstance(item, bpy.types.ShapeKey)) + md = active_data + # key = data + key_block = item + if self.layout_type in {'DEFAULT', 'COMPACT'}: + split = layout.split(0.66, False) + split.prop(key_block, "name", text="", emboss=False, icon_value=icon) + row = split.row(align=True) + if key_block.mute: + row.active = False + if not item.id_data.use_relative: + row.prop(key_block, "frame", text="", emboss=False) + elif index > 0: + row.prop(key_block, "value", text="", emboss=False) + else: + row.label(text="") + row.prop(key_block, "mute", text="", emboss=False) + elif self.layout_type == 'GRID': + layout.alignment = 'CENTER' + layout.label(text="", icon_value=icon) + + +class CACHELIBRARY_MT_hair_simulation_presets(Menu): + bl_label = "Hair Simulation Presets" + preset_subdir = "cachelibrary_hair_simulation" + preset_operator = "script.execute_preset" + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} + draw = Menu.draw_preset + + +class CacheArchiveInfoPanel(): + def draw_node_structure(self, context, layout, node, indent): + row = layout.row() + for i in range(indent): + row.label(text="", icon='BLANK1') + + if not node.child_nodes: + row.label(text="", icon='DOT') + elif not node.expand: + row.prop(node, "expand", text="", icon='DISCLOSURE_TRI_RIGHT', icon_only=True, emboss=False) + else: + row.prop(node, "expand", text="", icon='DISCLOSURE_TRI_DOWN', icon_only=True, emboss=False) + + for child in node.child_nodes: + self.draw_node_structure(context, layout, child, indent + 1) + + + info_columns = ['Name', 'Node', 'Samples', 'Size', 'Data', '', 'Array Size'] + + def draw_node_info(self, context, layout, node, column): + if column == 0: + layout.prop(node, "name", text="") + if column == 1: + layout.prop(node, "type", text="") + if column == 2: + if node.type in {'SCALAR_PROPERTY', 'ARRAY_PROPERTY'}: + layout.prop(node, "samples", text="") + else: + layout.label(" ") + if column == 3: + size = int(node.bytes_size) + layout.label(sizeof_fmt(size) if size >= 0 else "-") + if column == 4: + if node.type in {'SCALAR_PROPERTY', 'ARRAY_PROPERTY'}: + layout.prop(node, "datatype", text="") + else: + layout.label(" ") + if column == 5: + if node.type in {'SCALAR_PROPERTY', 'ARRAY_PROPERTY'}: + layout.prop(node, "datatype_extent", text="") + else: + layout.label(" ") + if column == 6: + if node.type in {'ARRAY_PROPERTY'}: + layout.label(node.array_size if node.array_size >= 0 else "-") + else: + layout.label(" ") + + if node.expand: + for child in node.child_nodes: + self.draw_node_info(context, layout, child, column) + + def draw_info(self, context, layout, info, metadata=None): + row = layout.row(align=True) + row.label("Created by: {} | {}".format(info.app_name if info.app_name else "-", info.date_written if info.date_written else "-")) + if info.description: + layout.label(info.description) + + if metadata: + row = layout.row(align=True) + col_key = row.column() + col_value = row.column() + for key, value in metadata.items(): + col_key.label(key) + col_value.label(str(value)) + + if info.root_node: + row = layout.row() + + col = row.column() + col.label(" ") + self.draw_node_structure(context, col, info.root_node, 0) + + for i, column in enumerate(self.info_columns): + col = row.column() + col.label(column) + self.draw_node_info(context, col, info.root_node, i) + + +class OBJECT_PT_cache_library(CacheArchiveInfoPanel, ObjectButtonsPanel, Panel): + bl_label = "Cache" + + @classmethod + def poll(cls, context): + ob = context.object + return (ob and ob.dupli_type == 'GROUP' and ob.dupli_group) + + def draw_cache_modifier(self, context, layout, cachelib, md): + layout.context_pointer_set("cache_library", cachelib) + layout.context_pointer_set("cache_modifier", md) + + row = layout.row(align=True) + row.context_pointer_set("cache_modifier", md) + row.prop(md, "name", text="") + row.operator("cachelibrary.remove_modifier", icon='X', text="", emboss=False) + + # match enum type to our functions, avoids a lookup table. + getattr(self, md.type)(context, layout, cachelib, md) + + def draw_cachelib(self, context, layout, ob, cachelib, objects): + box = layout.box() + row = box.row() + row.label("Source:") + row.prop(cachelib, "source_mode", text="Source", expand=True) + row = box.row(align=True) + row.enabled = (cachelib.source_mode == 'CACHE') + row.prop(cachelib, "input_filepath", text="") + row.prop(cachelib, "show_metadata", text="", icon='QUESTION', toggle=True) + if cachelib.show_metadata and cachelib.archive_info: + self.draw_info(context, box, cachelib.archive_info, cachelib['input_metadata']) + + layout.separator() + + layout.prop(cachelib, "display_mode", expand=True) + row = layout.row() + split = row.split() + col = split.column() + col.label("Display:") + col.prop(cachelib, "display_motion", text="Motion") + col.prop(cachelib, "display_children", text="Children") + + layout.separator() + + row = layout.row(align=True) + row.enabled = (cachelib.display_mode == 'RESULT') + row.prop(cachelib, "output_filepath", text="") + + box = layout.box() + row = box.row() + + col = row.column() + row2 = col.row() + row2.alignment = 'LEFT' + row2.prop(cachelib, "data_types", icon_only=True, toggle=True) + row2.template_ID(cachelib, "filter_group") + col.prop(cachelib, "description") + col = row.column() + props = col.operator("cachelibrary.bake", text="Bake Preview", icon='RESTRICT_VIEW_OFF') + props.eval_mode = {'PREVIEW'} + if context.scene.use_preview_range: + props.start_frame = context.scene.frame_preview_start + props.end_frame = context.scene.frame_preview_end + else: + props.start_frame = context.scene.frame_start + props.end_frame = context.scene.frame_end + props = col.operator("cachelibrary.bake", text="Bake Render", icon='RESTRICT_RENDER_OFF') + props.eval_mode = {'RENDER'} + props.start_frame = context.scene.frame_start + props.end_frame = context.scene.frame_end + + ''' + row = layout.row(align=True) + row.label("Filter:") + row.prop(cachelib, "filter_string", icon='VIEWZOOM', text="") + + first = True + for ob in objects: + if not any(cachelib_object_items(cachelib, ob)): + continue + + if first: + layout.separator() + first = False + + for datatype, index, enable in cachelib_object_items(cachelib, ob): + row = layout.row(align=True) + row.alignment = 'LEFT' + row.template_cache_library_item(cachelib, ob, datatype, index, enable) + ''' + + layout.operator_menu_enum("cachelibrary.add_modifier", "type") + + for md in cachelib.modifiers: + box = layout.box() + self.draw_cache_modifier(context, box, cachelib, md) + + def draw(self, context): + ob = context.object + + layout = self.layout + row = layout.row(align=True) + row.template_ID(ob, "cache_library", new="cachelibrary.new") + + if ob.cache_library: + cache_objects = cachelib_objects(ob.cache_library, ob.dupli_group) + self.draw_cachelib(context, layout, ob, ob.cache_library, cache_objects) + + def HAIR_SIMULATION(self, context, layout, cachelib, md): + params = md.parameters + + col = layout.column(align=True) + col.prop_search(md, "object", context.blend_data, "objects", icon='OBJECT_DATA') + sub = col.column() + if (md.object): + sub.prop_search(md, "hair_system", md.object, "particle_systems") + else: + sub.enabled = False + sub.prop(md, "hair_system") + + layout = layout.column() + layout.active = md.hair_system is not None + + row = layout.row(align=True) + row.menu("CACHELIBRARY_MT_hair_simulation_presets", text=bpy.types.CACHELIBRARY_MT_hair_simulation_presets.bl_label) + props = row.operator("cachelibrary.hair_simulation_preset_add", text="", icon='ZOOMIN') + props.modifier_name = md.name + props = row.operator("cachelibrary.hair_simulation_preset_add", text="", icon='ZOOMOUT') + props.modifier_name = md.name + props.remove_active = True + + col = layout.column() + col.prop(params, "substeps") + col.prop(params, "timescale") + col.prop(params, "mass") + col.prop(params, "drag") + + row = col.row(align=True) + row.prop(params, "stretch_stiffness") + row.prop(params, "stretch_damping") + + row = col.row(align=True) + row.prop(params, "bend_stiffness") + row.prop(params, "bend_damping") + row.prop(params, "use_bend_stiffness_curve") + if params.use_bend_stiffness_curve: + sub = col.column() + sub.template_curve_mapping(params, "bend_stiffness_curve") + + row = col.row(align=True) + row.prop(params, "goal_stiffness") + row.prop(params, "goal_damping") + row = col.row(align=True) + row.prop(params, "use_goal_stiffness_curve") + row.prop(params, "use_goal_deflect") + if params.use_goal_stiffness_curve: + sub = col.column() + sub.template_curve_mapping(params, "goal_stiffness_curve") + + layout.separator() + + effector_weights_ui(self, context, params.effector_weights, 'HAIR') + + def FORCE_FIELD(self, context, layout, cachelib, md): + layout.prop_search(md, "object", context.blend_data, "objects", icon='OBJECT_DATA') + + layout.prop(md, "force_type", text="") + + row = layout.row(align=True) + row.prop(md, "strength") + row.prop(md, "falloff") + + col = layout.column(align=True) + row = layout.row(align=True) + row.prop(md, "min_distance") + row.prop(md, "max_distance") + col.prop(md, "use_double_sided") + + def HAIRCUT(self, context, layout, cachelib, md): + col = layout.column(align=True) + col.prop_search(md, "object", context.blend_data, "objects", icon='OBJECT_DATA') + sub = col.column() + if (md.object): + sub.prop_search(md, "hair_system", md.object, "particle_systems") + else: + sub.enabled = False + sub.prop(md, "hair_system") + + row = layout.row() + row.prop_search(md, "target", context.blend_data, "objects", icon='OBJECT_DATA') + row.prop(md, "use_internal_target", text="Internal") + layout.prop(md, "cut_mode", toggle=True, expand=True) + + layout = layout.column() + layout.active = md.hair_system is not None + + def SHRINK_WRAP(self, context, layout, cachelib, md): + col = layout.column(align=True) + col.prop_search(md, "object", context.blend_data, "objects", icon='OBJECT_DATA') + sub = col.column() + if (md.object): + sub.prop_search(md, "hair_system", md.object, "particle_systems") + else: + sub.enabled = False + sub.prop(md, "hair_system") + + row = layout.row() + row.prop_search(md, "target", context.blend_data, "objects", icon='OBJECT_DATA') + row.prop(md, "use_internal_target", text="Internal") + + layout = layout.column() + layout.active = md.hair_system is not None + + def STRANDS_KEY(self, context, layout, cachelib, md): + col = layout.column(align=True) + col.prop_search(md, "object", context.blend_data, "objects", icon='OBJECT_DATA') + sub = col.column() + if (md.object): + sub.prop_search(md, "hair_system", md.object, "particle_systems") + else: + sub.enabled = False + sub.prop(md, "hair_system") + + key = md.shape_keys + kb = md.active_shape_key + kb_index = md.active_shape_key_index + + row = layout.row() + + rows = 2 + if kb: + rows = 4 + row.template_list("CACHELIB_UL_shape_keys", "", key, "key_blocks", md, "active_shape_key_index", rows=rows) + + col = row.column() + + sub = col.column(align=True) + #sub.operator("object.shape_key_add", icon='ZOOMIN', text="").from_mix = False + #sub.operator("object.shape_key_remove", icon='ZOOMOUT', text="").all = False + sub.menu("CACHELIB_MT_shape_key_specials", icon='DOWNARROW_HLT', text="") + + col.prop(md, "use_motion_state") + + if kb: + col.separator() + + sub = col.column(align=True) + #sub.operator("object.shape_key_move", icon='TRIA_UP', text="").type = 'UP' + #sub.operator("object.shape_key_move", icon='TRIA_DOWN', text="").type = 'DOWN' + + split = layout.split(percentage=0.4) + row = split.row() + row.prop(key, "use_relative") + + row = split.row() + row.alignment = 'RIGHT' + + sub = row.row(align=True) + sub.label() # XXX, for alignment only + subsub = sub.row(align=True) + subsub.prop(md, "show_only_shape_key", text="") + + sub = row.row() + #if key.use_relative: + # sub.operator("object.shape_key_clear", icon='X', text="") + #else: + # sub.operator("object.shape_key_retime", icon='RECOVER_LAST', text="") + + if key.use_relative: + if kb_index != 0: + row = layout.row() + row.prop(kb, "value") + + split = layout.split() + + col = split.column(align=True) + col.label(text="Range:") + col.prop(kb, "slider_min", text="Min") + col.prop(kb, "slider_max", text="Max") + + col = split.column(align=True) + col.label(text="Blend:") + #col.prop_search(kb, "vertex_group", ob, "vertex_groups", text="") + col.prop_search(kb, "relative_key", key, "key_blocks", text="") + + else: + layout.prop(kb, "interpolation") + row = layout.column() + row.prop(key, "eval_time") + + +# Simple human-readable size (based on http://stackoverflow.com/a/1094933) +def sizeof_fmt(num, suffix='B'): + for unit in ['','K','M','G','T','P','E','Z']: + if abs(num) < 1024.0: + return "%3.1f%s%s" % (num, unit, suffix) + num /= 1024.0 + return "%.1f%s%s" % (num, 'Y', suffix) + +class OBJECT_PT_cache_archive_info(CacheArchiveInfoPanel, ObjectButtonsPanel, Panel): + bl_label = "Cache Archive Info" + bl_options = {'DEFAULT_CLOSED'} + + @classmethod + def poll(cls, context): + ob = context.object + return (ob and ob.dupli_type == 'GROUP' and ob.dupli_group and ob.cache_library) + + def draw(self, context): + ob = context.object + cachelib = ob.cache_library + info = cachelib.archive_info + + layout = self.layout + + row = layout.row() + props = row.operator("cachelibrary.archive_info", text="Input", icon='QUESTION') + props.filepath = cachelib.input_filepath + props.use_cache_info = True + props = row.operator("cachelibrary.archive_info", text="Output", icon='QUESTION') + props.filepath = cachelib.output_filepath + props.use_cache_info = True + + if info: + row = layout.row() + row.enabled = bool(info.filepath) + props = layout.operator("cachelibrary.archive_info", text="Calculate Size", icon='FILE_REFRESH') + props.filepath = info.filepath + props.use_cache_info = True + props.calc_bytes_size = True + + layout.separator() + + layout.prop(info, "filepath", text="File") + self.draw_info(context, layout, info) + + class OBJECT_PT_relations_extras(ObjectButtonsPanel, Panel): bl_label = "Relations Extras" bl_options = {'DEFAULT_CLOSED'} diff --git a/release/scripts/startup/bl_ui/properties_paint_common.py b/release/scripts/startup/bl_ui/properties_paint_common.py index b0da65063d1..d1f7c0f5e40 100644 --- a/release/scripts/startup/bl_ui/properties_paint_common.py +++ b/release/scripts/startup/bl_ui/properties_paint_common.py @@ -38,10 +38,10 @@ class UnifiedPaintPanel: elif context.image_paint_object: if (toolsettings.image_paint and toolsettings.image_paint.detect_data()): return toolsettings.image_paint - - return None elif context.particle_edit_object: return toolsettings.particle_edit + elif context.hair_edit_object: + return toolsettings.hair_edit return None @@ -133,7 +133,7 @@ def brush_texpaint_common(panel, context, layout, brush, settings, projpaint=Fal else: row = col.row(align=True) panel.prop_unified_color(row, context, brush, "color", text="") - if brush.image_tool == 'FILL': + if brush.image_tool == 'FILL' and not projpaint: col.prop(brush, "fill_threshold") else: panel.prop_unified_color(row, context, brush, "secondary_color", text="") @@ -216,7 +216,9 @@ def brush_texpaint_common(panel, context, layout, brush, settings, projpaint=Fal col = layout.column(align=True) col.prop(brush, "use_accumulate") - col.prop(brush, "use_alpha") + if projpaint: + col.prop(brush, "use_alpha") + col.prop(brush, "use_gradient") col.separator() diff --git a/release/scripts/startup/bl_ui/properties_particle.py b/release/scripts/startup/bl_ui/properties_particle.py index 2247092c976..c948658f433 100644 --- a/release/scripts/startup/bl_ui/properties_particle.py +++ b/release/scripts/startup/bl_ui/properties_particle.py @@ -123,7 +123,7 @@ class PARTICLE_UL_particle_systems(bpy.types.UIList): layout.prop(md, "show_render", emboss=False, icon_only=True, icon='RESTRICT_RENDER_OFF' if md.show_render else 'RESTRICT_RENDER_ON') layout.prop(md, "show_viewport", emboss=False, icon_only=True, icon='RESTRICT_VIEW_OFF' if md.show_viewport else 'RESTRICT_VIEW_ON') - elif self.layout_type in {'GRID'}: + elif self.layout_type == 'GRID': layout.alignment = 'CENTER' layout.label(text="", icon_value=icon) @@ -1389,7 +1389,7 @@ class PARTICLE_PT_children(ParticleButtonsPanel, Panel): split = layout.split() split.active = part.kink != 'NO' - if part.kink in {'SPIRAL'}: + if part.kink == 'SPIRAL': col = split.column() sub = col.column(align=True) sub.prop(part, "kink_amplitude", text="Radius") diff --git a/release/scripts/startup/bl_ui/properties_physics_common.py b/release/scripts/startup/bl_ui/properties_physics_common.py index 19533d2185f..61091f3ec21 100644 --- a/release/scripts/startup/bl_ui/properties_physics_common.py +++ b/release/scripts/startup/bl_ui/properties_physics_common.py @@ -191,7 +191,7 @@ def point_cache_ui(self, context, cache, enabled, cachetype): col.operator("ptcache.bake", text="Bake").bake = True sub = col.row() - sub.enabled = (cache.frames_skipped or cache.is_outdated) and enabled + sub.enabled = (cache.is_frame_skip or cache.is_outdated) and enabled sub.operator("ptcache.bake", text="Calculate To Frame").bake = False sub = col.column() diff --git a/release/scripts/startup/bl_ui/properties_physics_dynamicpaint.py b/release/scripts/startup/bl_ui/properties_physics_dynamicpaint.py index 01dcf837546..269ffa6d371 100644 --- a/release/scripts/startup/bl_ui/properties_physics_dynamicpaint.py +++ b/release/scripts/startup/bl_ui/properties_physics_dynamicpaint.py @@ -40,7 +40,7 @@ class PHYSICS_UL_dynapaint_surfaces(UIList): row.prop(surf, "show_preview", text="", emboss=False, icon='RESTRICT_VIEW_OFF' if surf.show_preview else 'RESTRICT_VIEW_ON') row.prop(surf, "is_active", text="") - elif self.layout_type in {'GRID'}: + elif self.layout_type == 'GRID': layout.alignment = 'CENTER' row = layout.row(align=True) row.label(text="", icon_value=icon) diff --git a/release/scripts/startup/bl_ui/properties_physics_smoke.py b/release/scripts/startup/bl_ui/properties_physics_smoke.py index 63268bc6672..624f36ea942 100644 --- a/release/scripts/startup/bl_ui/properties_physics_smoke.py +++ b/release/scripts/startup/bl_ui/properties_physics_smoke.py @@ -81,15 +81,21 @@ class PHYSICS_PT_smoke(PhysicButtonsPanel, Panel): layout.prop(flow, "smoke_flow_type", expand=False) - if flow.smoke_flow_type != "OUTFLOW": + if flow.smoke_flow_type != 'OUTFLOW': + use_const_color = False + split = layout.split() col = split.column() col.label(text="Flow Source:") col.prop(flow, "smoke_flow_source", expand=False, text="") - if flow.smoke_flow_source == "PARTICLES": + if flow.smoke_flow_source == 'PARTICLES': col.label(text="Particle System:") col.prop_search(flow, "particle_system", ob, "particle_systems", text="") col.prop(flow, "use_particle_size", text="Set Size") + col.prop(flow, "use_particle_texture_color", text="Set Color") + # disable const color button when using particle color + use_const_color = not flow.use_particle_texture_color + sub = col.column() sub.active = flow.use_particle_size sub.prop(flow, "particle_size") @@ -103,7 +109,7 @@ class PHYSICS_PT_smoke(PhysicButtonsPanel, Panel): sub = sub.column() sub.active = flow.use_initial_velocity sub.prop(flow, "velocity_factor") - if flow.smoke_flow_source == "MESH": + if flow.smoke_flow_source == 'MESH': sub.prop(flow, "velocity_normal") #sub.prop(flow, "velocity_random") @@ -113,7 +119,9 @@ class PHYSICS_PT_smoke(PhysicButtonsPanel, Panel): if flow.smoke_flow_type in {'SMOKE', 'BOTH'}: sub.prop(flow, "density") sub.prop(flow, "temperature") - sub.prop(flow, "smoke_color") + subsub = sub.column() + subsub.active = use_const_color + subsub.prop(flow, "smoke_color") if flow.smoke_flow_type in {'FIRE', 'BOTH'}: sub.prop(flow, "fuel_amount") sub.label(text="Sampling:") @@ -128,6 +136,25 @@ class PHYSICS_PT_smoke(PhysicButtonsPanel, Panel): col.prop(coll, "collision_type") +class PHYSICS_PT_smoke_display(PhysicButtonsPanel, Panel): + bl_label = "Smoke Display" + bl_options = {'DEFAULT_CLOSED'} + + @classmethod + def poll(cls, context): + md = context.smoke + return md and (md.smoke_type == 'DOMAIN') + + def draw(self, context): + layout = self.layout + domain = context.smoke.domain_settings + + split = layout.split() + + col = split.column(align=True) + col.prop(domain, "display_thickness") + + class PHYSICS_PT_smoke_flow_advanced(PhysicButtonsPanel, Panel): bl_label = "Smoke Flow Advanced" bl_options = {'DEFAULT_CLOSED'} @@ -135,7 +162,7 @@ class PHYSICS_PT_smoke_flow_advanced(PhysicButtonsPanel, Panel): @classmethod def poll(cls, context): md = context.smoke - return md and (md.smoke_type == 'FLOW') and (md.flow_settings.smoke_flow_source == "MESH") + return md and (md.smoke_type == 'FLOW') and (md.flow_settings.smoke_flow_source == 'MESH') def draw(self, context): layout = self.layout @@ -151,9 +178,9 @@ class PHYSICS_PT_smoke_flow_advanced(PhysicButtonsPanel, Panel): sub.prop(flow, "noise_texture", text="") sub.label(text="Mapping:") sub.prop(flow, "texture_map_type", expand=False, text="") - if flow.texture_map_type == "UV": + if flow.texture_map_type == 'UV': sub.prop_search(flow, "uv_layer", ob.data, "uv_textures", text="") - if flow.texture_map_type == "AUTO": + if flow.texture_map_type == 'AUTO': sub.prop(flow, "texture_size") sub.prop(flow, "texture_offset") @@ -309,6 +336,7 @@ class PHYSICS_PT_smoke_cache(PhysicButtonsPanel, Panel): layout.label(text="Compression:") layout.prop(md, "point_cache_compress_type", expand=True) + layout.prop(md, "point_cache_offset", text="Start Frame") point_cache_ui(self, context, cache, (cache.is_baked is False), 'SMOKE') diff --git a/release/scripts/startup/bl_ui/properties_render.py b/release/scripts/startup/bl_ui/properties_render.py index b596fe48b49..0c68d98a8e1 100644 --- a/release/scripts/startup/bl_ui/properties_render.py +++ b/release/scripts/startup/bl_ui/properties_render.py @@ -274,7 +274,7 @@ class RENDER_PT_performance(RenderButtonsPanel, Panel): col.prop(rd, "tile_y", text="Y") col.separator() - col.prop(rd, 'preview_start_resolution') + col.prop(rd, "preview_start_resolution") col = split.column() col.label(text="Memory:") @@ -334,28 +334,25 @@ class RENDER_PT_post_processing(RenderButtonsPanel, Panel): class RENDER_PT_stamp(RenderButtonsPanel, Panel): - bl_label = "Stamp" + bl_label = "Metadata" bl_options = {'DEFAULT_CLOSED'} COMPAT_ENGINES = {'BLENDER_RENDER'} - def draw_header(self, context): - rd = context.scene.render - - self.layout.prop(rd, "use_stamp", text="") - def draw(self, context): layout = self.layout rd = context.scene.render - layout.active = rd.use_stamp + layout.prop(rd, "use_stamp", text="Stamp Output") + col = layout.column() + col.active = rd.use_stamp + col.prop(rd, "stamp_font_size", text="Font Size") - layout.prop(rd, "stamp_font_size", text="Font Size") - - row = layout.row() + row = col.row() row.column().prop(rd, "stamp_foreground", slider=True) row.column().prop(rd, "stamp_background", slider=True) + layout.label("Enabled Metadata") split = layout.split() col = split.column() @@ -404,6 +401,8 @@ class RENDER_PT_output(RenderButtonsPanel, Panel): col.prop(rd, "use_render_cache") layout.template_image_settings(image_settings, color_management=False) + if rd.use_multiview: + layout.template_image_views(image_settings) if file_format == 'QUICKTIME': quicktime = rd.quicktime diff --git a/release/scripts/startup/bl_ui/properties_render_layer.py b/release/scripts/startup/bl_ui/properties_render_layer.py index 35032d38933..8a3e33f1936 100644 --- a/release/scripts/startup/bl_ui/properties_render_layer.py +++ b/release/scripts/startup/bl_ui/properties_render_layer.py @@ -40,7 +40,7 @@ class RENDERLAYER_UL_renderlayers(UIList): if self.layout_type in {'DEFAULT', 'COMPACT'}: layout.prop(layer, "name", text="", icon_value=icon, emboss=False) layout.prop(layer, "use", text="", index=index) - elif self.layout_type in {'GRID'}: + elif self.layout_type == 'GRID': layout.alignment = 'CENTER' layout.label("", icon_value=icon) @@ -87,7 +87,7 @@ class RENDERLAYER_PT_layer_options(RenderLayerButtonsPanel, Panel): col = split.column() col.prop(scene, "layers", text="Scene") col.label(text="") - col.prop(rl, "light_override", text="Light") + col.prop(rl, "light_override", text="Lights") col.prop(rl, "material_override", text="Material") col = split.column() @@ -126,7 +126,8 @@ class RENDERLAYER_PT_layer_passes(RenderLayerButtonsPanel, Panel): bl_options = {'DEFAULT_CLOSED'} COMPAT_ENGINES = {'BLENDER_RENDER'} - def draw_pass_type_buttons(self, box, rl, pass_type): + @staticmethod + def draw_pass_type_buttons(box, rl, pass_type): # property names use_pass_type = "use_pass_" + pass_type exclude_pass_type = "exclude_" + pass_type @@ -167,5 +168,63 @@ class RENDERLAYER_PT_layer_passes(RenderLayerButtonsPanel, Panel): self.draw_pass_type_buttons(col, rl, "refraction") +class RENDERLAYER_UL_renderviews(UIList): + def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index): + # assert(isinstance(item, bpy.types.SceneRenderView) + view = item + if self.layout_type in {'DEFAULT', 'COMPACT'}: + if view.name in {'left', 'right'}: + layout.label(view.name, icon_value=icon + (not view.use)) + else: + layout.prop(view, "name", text="", index=index, icon_value=icon, emboss=False) + layout.prop(view, "use", text="", index=index) + + elif self.layout_type == 'GRID': + layout.alignment = 'CENTER' + layout.label("", icon_value=icon + (not view.use)) + + +class RENDERLAYER_PT_views(RenderLayerButtonsPanel, Panel): + bl_label = "Views" + COMPAT_ENGINES = {'BLENDER_RENDER'} + + def draw_header(self, context): + rd = context.scene.render + self.layout.prop(rd, "use_multiview", text="") + + def draw(self, context): + layout = self.layout + + scene = context.scene + rd = scene.render + rv = rd.views.active + + layout.active = rd.use_multiview + basic_stereo = rd.views_format == 'STEREO_3D' + + row = layout.row() + row.prop(rd, "views_format", expand=True) + + if basic_stereo: + row = layout.row() + row.template_list("RENDERLAYER_UL_renderviews", "name", rd, "stereo_views", rd.views, "active_index", rows=2) + + row = layout.row() + row.label(text="File Suffix:") + row.prop(rv, "file_suffix", text="") + + else: + row = layout.row() + row.template_list("RENDERLAYER_UL_renderviews", "name", rd, "views", rd.views, "active_index", rows=2) + + col = row.column(align=True) + col.operator("scene.render_view_add", icon='ZOOMIN', text="") + col.operator("scene.render_view_remove", icon='ZOOMOUT', text="") + + row = layout.row() + row.label(text="Camera Suffix:") + row.prop(rv, "camera_suffix", text="") + + if __name__ == "__main__": # only for live edit. bpy.utils.register_module(__name__) diff --git a/release/scripts/startup/bl_ui/properties_scene.py b/release/scripts/startup/bl_ui/properties_scene.py index facf54d358a..bbf11abe6d9 100644 --- a/release/scripts/startup/bl_ui/properties_scene.py +++ b/release/scripts/startup/bl_ui/properties_scene.py @@ -35,7 +35,7 @@ class SCENE_UL_keying_set_paths(UIList): if self.layout_type in {'DEFAULT', 'COMPACT'}: # Do not make this one editable in uiList for now... layout.label(text=kspath.data_path, translate=False, icon_value=icon) - elif self.layout_type in {'GRID'}: + elif self.layout_type == 'GRID': layout.alignment = 'CENTER' layout.label(text="", icon_value=icon) @@ -86,19 +86,25 @@ class SCENE_PT_unit(SceneButtonsPanel, Panel): class SceneKeyingSetsPanel: - def draw_keyframing_settings(self, context, layout, ks, ksp): - self.draw_keyframing_setting(context, layout, ks, ksp, "Needed", - "use_insertkey_override_needed", "use_insertkey_needed", - userpref_fallback="use_keyframe_insert_needed") - self.draw_keyframing_setting(context, layout, ks, ksp, "Visual", - "use_insertkey_override_visual", "use_insertkey_visual", - userpref_fallback="use_visual_keying") + @staticmethod + def draw_keyframing_settings(context, layout, ks, ksp): + SceneKeyingSetsPanel._draw_keyframing_setting( + context, layout, ks, ksp, "Needed", + "use_insertkey_override_needed", "use_insertkey_needed", + userpref_fallback="use_keyframe_insert_needed") - self.draw_keyframing_setting(context, layout, ks, ksp, "XYZ to RGB", - "use_insertkey_override_xyz_to_rgb", "use_insertkey_xyz_to_rgb") + SceneKeyingSetsPanel._draw_keyframing_setting( + context, layout, ks, ksp, "Visual", + "use_insertkey_override_visual", "use_insertkey_visual", + userpref_fallback="use_visual_keying") - def draw_keyframing_setting(self, context, layout, ks, ksp, label, toggle_prop, prop, userpref_fallback=None): + SceneKeyingSetsPanel._draw_keyframing_setting( + context, layout, ks, ksp, "XYZ to RGB", + "use_insertkey_override_xyz_to_rgb", "use_insertkey_xyz_to_rgb") + + @staticmethod + def _draw_keyframing_setting(context, layout, ks, ksp, label, toggle_prop, prop, userpref_fallback=None): if ksp: item = ksp @@ -392,14 +398,17 @@ class SCENE_PT_simplify(SceneButtonsPanel, Panel): split = layout.split() col = split.column() + col.label(text="Viewport:") col.prop(rd, "simplify_subdivision", text="Subdivision") col.prop(rd, "simplify_child_particles", text="Child Particles") - col.prop(rd, "use_simplify_triangulate") - col = split.column() + col.label(text="Render:") + col.prop(rd, "simplify_subdivision_render", text="Subdivision") + col.prop(rd, "simplify_child_particles_render", text="Child Particles") col.prop(rd, "simplify_shadow_samples", text="Shadow Samples") col.prop(rd, "simplify_ao_sss", text="AO and SSS") + col.prop(rd, "use_simplify_triangulate") class SCENE_PT_custom_props(SceneButtonsPanel, PropertyPanel, Panel): diff --git a/release/scripts/startup/bl_ui/properties_texture.py b/release/scripts/startup/bl_ui/properties_texture.py index 11729df05e2..5a4937d2509 100644 --- a/release/scripts/startup/bl_ui/properties_texture.py +++ b/release/scripts/startup/bl_ui/properties_texture.py @@ -72,7 +72,7 @@ class TEXTURE_UL_texslots(UIList): layout.label(text="", icon_value=icon) if tex and isinstance(item, bpy.types.MaterialTextureSlot): layout.prop(ma, "use_textures", text="", index=index) - elif self.layout_type in {'GRID'}: + elif self.layout_type == 'GRID': layout.alignment = 'CENTER' layout.label(text="", icon_value=icon) @@ -676,8 +676,7 @@ class TEXTURE_PT_musgrave(TextureTypePanel, Panel): col = split.column() if musgrave_type in {'HETERO_TERRAIN', 'RIDGED_MULTIFRACTAL', 'HYBRID_MULTIFRACTAL'}: col.prop(tex, "offset") - if musgrave_type in {'MULTIFRACTAL', 'RIDGED_MULTIFRACTAL', 'HYBRID_MULTIFRACTAL'}: - col.prop(tex, "noise_intensity", text="Intensity") + col.prop(tex, "noise_intensity", text="Intensity") if musgrave_type in {'RIDGED_MULTIFRACTAL', 'HYBRID_MULTIFRACTAL'}: col.prop(tex, "gain") @@ -1148,6 +1147,7 @@ class TEXTURE_PT_influence(TextureSlotPanel, Panel): factor_but(col, "use_map_life", "life_factor", "Lifetime") factor_but(col, "use_map_density", "density_factor", "Density") factor_but(col, "use_map_size", "size_factor", "Size") + factor_but(col, "use_map_particle_color", "particle_color_factor", "Color") col = split.column() col.label(text="Physics:") @@ -1182,7 +1182,8 @@ class TEXTURE_PT_influence(TextureSlotPanel, Panel): layout.separator() - if not isinstance(idblock, ParticleSettings): + show_blend_settings = (not isinstance(idblock, ParticleSettings)) or tex.use_map_particle_color + if show_blend_settings: split = layout.split() col = split.column() diff --git a/release/scripts/startup/bl_ui/space_clip.py b/release/scripts/startup/bl_ui/space_clip.py index a9fcdea35c7..33943aff0f3 100644 --- a/release/scripts/startup/bl_ui/space_clip.py +++ b/release/scripts/startup/bl_ui/space_clip.py @@ -37,7 +37,7 @@ class CLIP_UL_tracking_objects(UIList): layout.prop(tobj, "name", text="", emboss=False, icon='CAMERA_DATA' if tobj.is_camera else 'OBJECT_DATA') - elif self.layout_type in {'GRID'}: + elif self.layout_type == 'GRID': layout.alignment = 'CENTER' layout.label(text="", icon='CAMERA_DATA' if tobj.is_camera @@ -147,7 +147,7 @@ class CLIP_HT_header(Header): sc = context.space_data - if sc.mode in {'TRACKING'}: + if sc.mode == 'TRACKING': self._draw_tracking(context) else: self._draw_masking(context) @@ -716,7 +716,7 @@ class CLIP_PT_tracking_camera(Panel): if CLIP_PT_clip_view_panel.poll(context): sc = context.space_data - return sc.mode in {'TRACKING'} and sc.clip + return sc.mode == 'TRACKING' and sc.clip return False @@ -756,7 +756,7 @@ class CLIP_PT_tracking_lens(Panel): if CLIP_PT_clip_view_panel.poll(context): sc = context.space_data - return sc.mode in {'TRACKING'} and sc.clip + return sc.mode == 'TRACKING' and sc.clip return False @@ -893,7 +893,7 @@ class CLIP_PT_stabilization(CLIP_PT_reconstruction_panel, Panel): if CLIP_PT_clip_view_panel.poll(context): sc = context.space_data - return sc.mode in {'TRACKING'} and sc.clip + return sc.mode == 'TRACKING' and sc.clip return False @@ -987,7 +987,9 @@ class CLIP_PT_proxy(CLIP_PT_clip_view_panel, Panel): if clip.use_proxy_custom_directory: col.prop(clip.proxy, "directory") - col.operator("clip.rebuild_proxy", text="Build Proxy") + col.operator("clip.rebuild_proxy", + text="Build Proxy / Timecode" if clip.source == 'MOVIE' + else "Build Proxy") if clip.source == 'MOVIE': col2 = col.column() @@ -1147,6 +1149,7 @@ class CLIP_MT_view(Menu): layout.operator("clip.view_selected") layout.operator("clip.view_all") + layout.operator("clip.view_all", text="View Fit").fit_view = True layout.separator() layout.operator("clip.view_zoom_in") @@ -1277,8 +1280,8 @@ class CLIP_MT_reconstruction(Menu): layout.operator("clip.set_plane", text="Set Floor").plane = 'FLOOR' layout.operator("clip.set_plane", text="Set Wall").plane = 'WALL' - layout.operator("clip.set_axis", text="Set X Axis").axis = "X" - layout.operator("clip.set_axis", text="Set Y Axis").axis = "Y" + layout.operator("clip.set_axis", text="Set X Axis").axis = 'X' + layout.operator("clip.set_axis", text="Set Y Axis").axis = 'Y' layout.operator("clip.set_scale") diff --git a/release/scripts/startup/bl_ui/space_dopesheet.py b/release/scripts/startup/bl_ui/space_dopesheet.py index 5358670c2f2..7fd9719a6e3 100644 --- a/release/scripts/startup/bl_ui/space_dopesheet.py +++ b/release/scripts/startup/bl_ui/space_dopesheet.py @@ -51,6 +51,11 @@ def dopesheet_filter(layout, context, genericFiltersOnly=False): row.prop(dopesheet, "show_only_matching_fcurves", text="") if dopesheet.show_only_matching_fcurves: row.prop(dopesheet, "filter_fcurve_name", text="") + else: + row = layout.row(align=True) + row.prop(dopesheet, "use_filter_text", text="") + if dopesheet.use_filter_text: + row.prop(dopesheet, "filter_text", text="") if not genericFiltersOnly: row = layout.row(align=True) @@ -105,6 +110,7 @@ class DOPESHEET_HT_header(Header): layout = self.layout st = context.space_data + toolsettings = context.tool_settings row = layout.row(align=True) row.template_header() @@ -112,6 +118,18 @@ class DOPESHEET_HT_header(Header): DOPESHEET_MT_editor_menus.draw_collapsible(context, layout) layout.prop(st, "mode", text="") + + if st.mode in {'ACTION', 'SHAPEKEY'}: + row = layout.row(align=True) + row.operator("action.layer_prev", text="", icon='TRIA_DOWN') + row.operator("action.layer_next", text="", icon='TRIA_UP') + + layout.template_ID(st, "action", new="action.new", unlink="action.unlink") + + row = layout.row(align=True) + row.operator("action.push_down", text="Push Down", icon='NLA_PUSHDOWN') + row.operator("action.stash", text="Stash", icon='FREEZE') + layout.prop(st.dopesheet, "show_summary", text="Summary") if st.mode == 'DOPESHEET': @@ -121,12 +139,12 @@ class DOPESHEET_HT_header(Header): # filters which will work here and are useful (especially for character animation) dopesheet_filter(layout, context, genericFiltersOnly=True) - if st.mode in {'ACTION', 'SHAPEKEY'}: - layout.template_ID(st, "action", new="action.new") - - row = layout.row(align=True) - row.operator("action.push_down", text="Push Down", icon='NLA_PUSHDOWN') - row.operator("action.stash", text="Stash", icon='FREEZE') + row = layout.row(align=True) + row.prop(toolsettings, "use_proportional_action", + text="", icon_only=True) + if toolsettings.use_proportional_action: + row.prop(toolsettings, "proportional_edit_falloff", + text="", icon_only=True) # Grease Pencil mode doesn't need snapping, as it's frame-aligned only if st.mode != 'GPENCIL': @@ -190,6 +208,7 @@ class DOPESHEET_MT_view(Menu): layout.separator() layout.operator("action.view_all") layout.operator("action.view_selected") + layout.operator("action.view_frame") layout.separator() layout.operator("screen.area_dupli") @@ -320,6 +339,7 @@ class DOPESHEET_MT_key(Menu): layout.separator() layout.operator("action.clean") + layout.operator("action.clean", text="Clean Channels").channels = True layout.operator("action.sample") layout.separator() @@ -390,5 +410,20 @@ class DOPESHEET_MT_gpencil_frame(Menu): #layout.operator("action.copy") #layout.operator("action.paste") + +class DOPESHEET_MT_delete(Menu): + bl_label = "Delete" + + def draw(self, context): + layout = self.layout + + layout.operator("action.delete") + + layout.separator() + + layout.operator("action.clean") + layout.operator("action.clean", text="Clean Channels").channels = True + + if __name__ == "__main__": # only for live edit. bpy.utils.register_module(__name__) diff --git a/release/scripts/startup/bl_ui/space_filebrowser.py b/release/scripts/startup/bl_ui/space_filebrowser.py index 841e169b080..12ea0977b58 100644 --- a/release/scripts/startup/bl_ui/space_filebrowser.py +++ b/release/scripts/startup/bl_ui/space_filebrowser.py @@ -44,18 +44,26 @@ class FILEBROWSER_HT_header(Header): row.separator() row = layout.row(align=True) - layout.operator_context = "EXEC_DEFAULT" + layout.operator_context = 'EXEC_DEFAULT' row.operator("file.directory_new", icon='NEWFOLDER') - layout.operator_context = "INVOKE_DEFAULT" + layout.operator_context = 'INVOKE_DEFAULT' params = st.params # can be None when save/reload with a file selector open if params: layout.prop(params, "display_type", expand=True, text="") + + if params.display_type == 'FILE_IMGDISPLAY': + layout.prop(params, "thumbnail_size", text="") + layout.prop(params, "sort_method", expand=True, text="") layout.prop(params, "show_hidden", text="", icon='FILE_HIDDEN') + if params.collapse_seq: + layout.prop(params, "collapse_seq", text="", icon='FULLSCREEN_EXIT') + else: + layout.prop(params, "collapse_seq", text="", icon='FULLSCREEN_ENTER') layout.prop(params, "use_filter", text="", icon='FILTER') row = layout.row(align=True) @@ -84,7 +92,7 @@ class FILEBROWSER_HT_header(Header): class FILEBROWSER_UL_dir(bpy.types.UIList): def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index): direntry = item - space = context.space_data + # space = context.space_data icon = 'NONE' if active_propname == "system_folders_active": icon = 'DISK_DRIVE' @@ -99,12 +107,12 @@ class FILEBROWSER_UL_dir(bpy.types.UIList): row = layout.row(align=True) row.enabled = direntry.is_valid # Non-editable entries would show grayed-out, which is bad in this specific case, so switch to mere label. - if direntry.is_property_readonly('name'): + if direntry.is_property_readonly("name"): row.label(text=direntry.name, icon=icon) else: row.prop(direntry, "name", text="", emboss=False, icon=icon) - elif self.layout_type in {'GRID'}: + elif self.layout_type == 'GRID': layout.alignment = 'CENTER' layout.prop(direntry, "path", text="") @@ -124,6 +132,7 @@ class FILEBROWSER_PT_system_folders(Panel): row.template_list("FILEBROWSER_UL_dir", "system_folders", space, "system_folders", space, "system_folders_active", item_dyntip_propname="path", rows=1, maxrows=10) + class FILEBROWSER_PT_system_bookmarks(Panel): bl_space_type = 'FILE_BROWSER' bl_region_type = 'TOOLS' diff --git a/release/scripts/startup/bl_ui/space_graph.py b/release/scripts/startup/bl_ui/space_graph.py index d3e1a866e43..104fd14797e 100644 --- a/release/scripts/startup/bl_ui/space_graph.py +++ b/release/scripts/startup/bl_ui/space_graph.py @@ -29,6 +29,7 @@ class GRAPH_HT_header(Header): from bl_ui.space_dopesheet import dopesheet_filter layout = self.layout + toolsettings = context.tool_settings st = context.space_data @@ -46,6 +47,14 @@ class GRAPH_HT_header(Header): row.active = st.use_normalization row.prop(st, "use_auto_normalization", text="Auto") + row = layout.row(align=True) + + row.prop(toolsettings, "use_proportional_fcurve", + text="", icon_only=True) + if toolsettings.use_proportional_fcurve: + row.prop(toolsettings, "proportional_edit_falloff", + text="", icon_only=True) + layout.prop(st, "auto_snap", text="") layout.prop(st, "pivot_point", icon_only=True) @@ -116,6 +125,7 @@ class GRAPH_MT_view(Menu): layout.separator() layout.operator("graph.view_all") layout.operator("graph.view_selected") + layout.operator("graph.view_frame") layout.separator() layout.operator("screen.area_dupli") @@ -248,6 +258,7 @@ class GRAPH_MT_key(Menu): layout.separator() layout.operator("graph.clean") + layout.operator("graph.clean", text="Clean Channels").channels = True layout.operator("graph.smooth") layout.operator("graph.sample") layout.operator("graph.bake") @@ -271,5 +282,20 @@ class GRAPH_MT_key_transform(Menu): layout.operator("transform.rotate", text="Rotate") layout.operator("transform.resize", text="Scale") + +class GRAPH_MT_delete(Menu): + bl_label = "Delete" + + def draw(self, context): + layout = self.layout + + layout.operator("graph.delete") + + layout.separator() + + layout.operator("graph.clean") + layout.operator("graph.clean", text="Clean Channels").channels = True + + if __name__ == "__main__": # only for live edit. bpy.utils.register_module(__name__) diff --git a/release/scripts/startup/bl_ui/space_image.py b/release/scripts/startup/bl_ui/space_image.py index a75e0916c09..4c6966b31d2 100644 --- a/release/scripts/startup/bl_ui/space_image.py +++ b/release/scripts/startup/bl_ui/space_image.py @@ -84,6 +84,7 @@ class IMAGE_MT_view(Menu): layout.prop(toolsettings, "show_uv_local_view") layout.prop(uv, "show_other_objects") + layout.prop(uv, "show_metadata") if paint.brush and (context.image_paint_object or sima.mode == 'PAINT'): layout.prop(uv, "show_texpaint") layout.prop(toolsettings, "show_uv_local_view", text="Show same material") @@ -106,6 +107,7 @@ class IMAGE_MT_view(Menu): layout.operator("image.view_selected") layout.operator("image.view_all") + layout.operator("image.view_all", text="View Fit").fit_view = True layout.separator() @@ -127,6 +129,7 @@ class IMAGE_MT_select(Menu): layout.operator("uv.select_border").pinned = False layout.operator("uv.select_border", text="Border Select Pinned").pinned = True + layout.operator("uv.circle_select") layout.separator() @@ -335,7 +338,8 @@ class IMAGE_MT_uvs(Menu): layout.operator("uv.average_islands_scale") layout.operator("uv.minimize_stretch") layout.operator("uv.stitch") - layout.operator("uv.mark_seam") + layout.operator("uv.mark_seam").clear = False + layout.operator("uv.mark_seam", text="Clear Seam").clear = True layout.operator("uv.seams_from_islands") layout.operator("mesh.faces_mirror_uv") @@ -458,6 +462,10 @@ class IMAGE_HT_header(Header): layout.prop_search(mesh.uv_textures, "active", mesh, "uv_textures", text="") if ima: + if ima.is_stereo_3d: + row = layout.row() + row.prop(sima, "show_stereo_3d", text="") + # layers layout.template_image_layers(ima, iuser) @@ -625,6 +633,8 @@ class IMAGE_PT_view_properties(Panel): sima = context.space_data ima = sima.image + + show_render = sima.show_render show_uvedit = sima.show_uvedit show_maskedit = sima.show_maskedit uvedit = sima.uv_editor @@ -669,7 +679,7 @@ class IMAGE_PT_view_properties(Panel): sub.active = uvedit.show_stretch sub.row().prop(uvedit, "draw_stretch_type", expand=True) - if ima: + if show_render and ima: layout.separator() render_slot = ima.render_slots.active layout.prop(render_slot, "name", text="Slot Name") @@ -1051,10 +1061,10 @@ class ImageScopesPanel: if not (sima and sima.image): return False # scopes are not updated in paint modes, hide - if sima.mode in {'PAINT'}: + if sima.mode == 'PAINT': return False ob = context.active_object - if ob and ob.mode in {'TEXTURE_PAINT'}: + if ob and ob.mode in {'TEXTURE_PAINT', 'EDIT'}: return False return True diff --git a/release/scripts/startup/bl_ui/space_info.py b/release/scripts/startup/bl_ui/space_info.py index 927967c8bc6..48a1b28289e 100644 --- a/release/scripts/startup/bl_ui/space_info.py +++ b/release/scripts/startup/bl_ui/space_info.py @@ -282,6 +282,10 @@ class INFO_MT_window(Menu): layout.separator() layout.operator("wm.console_toggle", icon='CONSOLE') + if context.scene.render.use_multiview: + layout.separator() + layout.operator("wm.set_stereo_3d", icon='CAMERA_STEREO') + class INFO_MT_help(Menu): bl_label = "Help" diff --git a/release/scripts/startup/bl_ui/space_logic.py b/release/scripts/startup/bl_ui/space_logic.py index 16182da1018..48b54feba17 100644 --- a/release/scripts/startup/bl_ui/space_logic.py +++ b/release/scripts/startup/bl_ui/space_logic.py @@ -54,11 +54,11 @@ class LOGIC_PT_properties(Panel): row.label("See Text Object") else: props = layout.operator("object.game_property_new", text="Add Text Game Property", icon='ZOOMIN') - props.name = 'Text' + props.name = "Text" props.type = 'STRING' props = layout.operator("object.game_property_new", text="Add Game Property", icon='ZOOMIN') - props.name = '' + props.name = "" for i, prop in enumerate(game.properties): @@ -71,6 +71,13 @@ class LOGIC_PT_properties(Panel): row.prop(prop, "type", text="") row.prop(prop, "value", text="") row.prop(prop, "show_debug", text="", toggle=True, icon='INFO') + sub = row.row(align=True) + props = sub.operator("object.game_property_move", text="", icon='TRIA_UP') + props.index = i + props.direction = 'UP' + props = sub.operator("object.game_property_move", text="", icon='TRIA_DOWN') + props.index = i + props.direction = 'DOWN' row.operator("object.game_property_remove", text="", icon='X', emboss=False).index = i diff --git a/release/scripts/startup/bl_ui/space_nla.py b/release/scripts/startup/bl_ui/space_nla.py index ae432c44bf6..c083907f017 100644 --- a/release/scripts/startup/bl_ui/space_nla.py +++ b/release/scripts/startup/bl_ui/space_nla.py @@ -168,8 +168,10 @@ class NLA_MT_edit(Menu): layout.separator() # TODO: names of these tools for 'tweak-mode' need changing? if scene.is_nla_tweakmode: + layout.operator("nla.tweakmode_exit", text="Stop Editing Stashed Action").isolate_action = True layout.operator("nla.tweakmode_exit", text="Stop Tweaking Strip Actions") else: + layout.operator("nla.tweakmode_enter", text="Start Editing Stashed Action").isolate_action = True layout.operator("nla.tweakmode_enter", text="Start Tweaking Strip Actions") diff --git a/release/scripts/startup/bl_ui/space_node.py b/release/scripts/startup/bl_ui/space_node.py index f229e4293a6..d50e1253970 100644 --- a/release/scripts/startup/bl_ui/space_node.py +++ b/release/scripts/startup/bl_ui/space_node.py @@ -19,6 +19,7 @@ # <pep8 compliant> import bpy from bpy.types import Header, Menu, Panel +from bpy.app.translations import pgettext_iface as iface_ from bl_ui.properties_grease_pencil_common import ( GreasePencilDrawingToolsPanel, GreasePencilStrokeEditPanel, @@ -66,7 +67,7 @@ class NODE_HT_header(Header): if snode_id and not (scene.render.use_shading_nodes == 0 and ob.type == 'LAMP'): layout.prop(snode_id, "use_nodes") - if snode.shader_type == 'WORLD': + if scene.render.use_shading_nodes and snode.shader_type == 'WORLD': row = layout.row() row.enabled = not snode.pin row.template_ID(scene, "world", new="world.new") @@ -208,8 +209,8 @@ class NODE_MT_select(Menu): layout.separator() layout.operator("node.select_grouped").extend = False - layout.operator("node.select_same_type_step").prev = True - layout.operator("node.select_same_type_step").prev = False + layout.operator("node.select_same_type_step", text="Activate Same Type Previous").prev = True + layout.operator("node.select_same_type_step", text="Activate Same Type Next").prev = False layout.separator() @@ -358,7 +359,7 @@ class NODE_PT_active_node_properties(Panel): layout.label("Inputs:") for socket in value_inputs: row = layout.row() - socket.draw(context, row, node, socket.name) + socket.draw(context, row, node, iface_(socket.name, socket.bl_rna.translation_context)) # Node Backdrop options @@ -439,7 +440,7 @@ class NODE_UL_interface_sockets(bpy.types.UIList): if socket.is_output: row.template_node_socket(color) - elif self.layout_type in {'GRID'}: + elif self.layout_type == 'GRID': layout.alignment = 'CENTER' layout.template_node_socket(color) diff --git a/release/scripts/startup/bl_ui/space_sequencer.py b/release/scripts/startup/bl_ui/space_sequencer.py index 95e3eb8b416..ed04983cb29 100644 --- a/release/scripts/startup/bl_ui/space_sequencer.py +++ b/release/scripts/startup/bl_ui/space_sequencer.py @@ -19,6 +19,7 @@ # <pep8 compliant> import bpy from bpy.types import Header, Menu, Panel +from rna_prop_ui import PropertyPanel from bl_ui.properties_grease_pencil_common import GreasePencilDataPanel, GreasePencilToolsPanel from bpy.app.translations import pgettext_iface as iface_ @@ -200,15 +201,17 @@ class SEQUENCER_MT_view(Menu): layout.prop(st, "show_seconds") layout.prop(st, "show_frame_indicator") layout.prop(st, "show_strip_offset") + layout.prop(st, "show_info") layout.prop_menu_enum(st, "waveform_draw_type") if is_preview: - if st.display_mode == 'IMAGE': - layout.prop(st, "show_safe_areas") - elif st.display_mode == 'WAVEFORM': + if st.display_mode == 'WAVEFORM': layout.prop(st, "show_separate_color") + layout.prop(st, "show_metadata") + + layout.separator() if is_sequencer_view: @@ -228,12 +231,12 @@ class SEQUENCER_MT_select(Menu): layout.operator("sequencer.select_active_side", text="Strips to the Left").side = 'LEFT' layout.operator("sequencer.select_active_side", text="Strips to the Right").side = 'RIGHT' - op = layout.operator("sequencer.select", text="All strips to the Left") - op.left_right = 'LEFT' - op.linked_time = True - op = layout.operator("sequencer.select", text="All strips to the Right") - op.left_right = 'RIGHT' - op.linked_time = True + props = layout.operator("sequencer.select", text="All strips to the Left") + props.left_right = 'LEFT' + props.linked_time = True + props = layout.operator("sequencer.select", text="All strips to the Right") + props.left_right = 'RIGHT' + props.linked_time = True layout.separator() layout.operator("sequencer.select_handles", text="Surrounding Handles").side = 'BOTH' @@ -306,6 +309,7 @@ class SEQUENCER_MT_add(Menu): layout.operator_menu_enum("sequencer.mask_strip_add", "mask", text="Mask...") layout.operator("sequencer.movie_strip_add", text="Movie") + layout.operator("sequencer.image_sequence_add", text="Image Sequence") layout.operator("sequencer.image_strip_add", text="Image") layout.operator("sequencer.sound_strip_add", text="Sound") @@ -472,7 +476,7 @@ class SEQUENCER_PT_edit(SequencerButtonsPanel, Panel): split.label(text="Type:") split.prop(strip, "type", text="") - if strip.type not in {'SOUND'}: + if strip.type != 'SOUND': split = layout.split(percentage=0.3) split.label(text="Blend:") split.prop(strip, "blend_type", text="") @@ -658,6 +662,7 @@ class SEQUENCER_PT_input(SequencerButtonsPanel, Panel): def draw(self, context): layout = self.layout + scene = context.scene strip = act_strip(context) @@ -671,7 +676,7 @@ class SEQUENCER_PT_input(SequencerButtonsPanel, Panel): # Current element for the filename - elem = strip.strip_elem_from_frame(context.scene.frame_current) + elem = strip.strip_elem_from_frame(scene.frame_current) if elem: split = layout.split(percentage=0.2) split.label(text="File:") @@ -717,6 +722,19 @@ class SEQUENCER_PT_input(SequencerButtonsPanel, Panel): col.prop(strip, "frame_offset_start", text="Start") col.prop(strip, "frame_offset_end", text="End") + if scene.render.use_multiview and seq_type in {'IMAGE', 'MOVIE'}: + layout.prop(strip, "use_multiview") + + col = layout.column() + col.active = strip.use_multiview + + col.label(text="Views Format:") + col.row().prop(strip, "views_format", expand=True) + + box = col.box() + box.active = strip.views_format == 'STEREO_3D' + box.template_image_stereo_3d(strip.stereo_3d_format) + class SEQUENCER_PT_sound(SequencerButtonsPanel, Panel): bl_label = "Sound" @@ -915,44 +933,43 @@ class SEQUENCER_PT_proxy(SequencerButtonsPanel, Panel): def draw(self, context): layout = self.layout + sequencer = context.scene.sequence_editor + strip = act_strip(context) - flow = layout.column_flow() - flow.prop(strip, "use_proxy_custom_directory") - flow.prop(strip, "use_proxy_custom_file") if strip.proxy: - if strip.use_proxy_custom_directory and not strip.use_proxy_custom_file: - flow.prop(strip.proxy, "directory") - if strip.use_proxy_custom_file: - flow.prop(strip.proxy, "filepath") + proxy = strip.proxy - layout.label("Enabled Proxies:") - enabled = "" - row = layout.row() - if (strip.proxy.build_25): - enabled += "25% " - if (strip.proxy.build_50): - enabled += "50% " - if (strip.proxy.build_75): - enabled += "75% " - if (strip.proxy.build_100): - enabled += "100% " - - row.label(enabled) - if (strip.proxy.use_overwrite): - layout.label("Overwrite On") + flow = layout.column_flow() + flow.prop(sequencer, "proxy_storage") + if sequencer.proxy_storage == 'PROJECT': + flow.prop(sequencer, "proxy_dir") else: - layout.label("Overwrite Off") + flow.prop(proxy, "use_proxy_custom_directory") + flow.prop(proxy, "use_proxy_custom_file") + + if proxy.use_proxy_custom_directory and not proxy.use_proxy_custom_file: + flow.prop(proxy, "directory") + if proxy.use_proxy_custom_file: + flow.prop(proxy, "filepath") + + row = layout.row() + row.prop(strip.proxy, "build_25") + row.prop(strip.proxy, "build_50") + row.prop(strip.proxy, "build_75") + row.prop(strip.proxy, "build_100") + + layout.prop(proxy, "use_overwrite") col = layout.column() col.label(text="Build JPEG quality") - col.prop(strip.proxy, "quality") + col.prop(proxy, "quality") if strip.type == 'MOVIE': col = layout.column() col.label(text="Use timecode index:") - col.prop(strip.proxy, "timecode") + col.prop(proxy, "timecode") col = layout.column() col.operator("sequencer.enable_proxies") @@ -1100,5 +1117,11 @@ class SEQUENCER_PT_grease_pencil_tools(GreasePencilToolsPanel, SequencerButtonsP # toolbar, which doesn't exist here... +class SEQUENCER_PT_custom_props(SequencerButtonsPanel, PropertyPanel, Panel): + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} + _context_path = "scene.sequence_editor.active_strip" + _property_type = (bpy.types.Sequence,) + + if __name__ == "__main__": # only for live edit. bpy.utils.register_module(__name__) diff --git a/release/scripts/startup/bl_ui/space_time.py b/release/scripts/startup/bl_ui/space_time.py index 27fcf94666a..c4c4097315c 100644 --- a/release/scripts/startup/bl_ui/space_time.py +++ b/release/scripts/startup/bl_ui/space_time.py @@ -30,6 +30,7 @@ class TIME_HT_header(Header): scene = context.scene toolsettings = context.tool_settings screen = context.screen + userprefs = context.user_preferences row = layout.row(align=True) row.template_header() @@ -82,7 +83,7 @@ class TIME_HT_header(Header): if toolsettings.use_keyframe_insert_auto: row.prop(toolsettings, "use_keyframe_insert_keyingset", text="", toggle=True) - if screen.is_animation_playing: + if screen.is_animation_playing and not userprefs.edit.use_keyframe_insert_available: subsub = row.row(align=True) subsub.prop(toolsettings, "use_record_with_nla", toggle=True) @@ -253,6 +254,10 @@ def marker_menu_generic(layout): layout.operator("screen.marker_jump", text="Jump to Next Marker").next = True layout.operator("screen.marker_jump", text="Jump to Previous Marker").next = False + layout.separator() + ts = bpy.context.tool_settings + layout.prop(ts, "lock_markers") + if __name__ == "__main__": # only for live edit. bpy.utils.register_module(__name__) diff --git a/release/scripts/startup/bl_ui/space_userpref.py b/release/scripts/startup/bl_ui/space_userpref.py index 91f77804d95..2316d7000a7 100644 --- a/release/scripts/startup/bl_ui/space_userpref.py +++ b/release/scripts/startup/bl_ui/space_userpref.py @@ -200,6 +200,11 @@ class USERPREF_PT_interface(Panel): col.label(text="2D Viewports:") col.prop(view, "view2d_grid_spacing_min", text="Minimum Grid Spacing") col.prop(view, "timecode_style") + col.prop(view, "view_frame_type") + if (view.view_frame_type == 'SECONDS'): + col.prop(view, "view_frame_seconds") + elif (view.view_frame_type == 'KEYFRAMES'): + col.prop(view, "view_frame_keyframes") row.separator() row.separator() @@ -1046,7 +1051,8 @@ class USERPREF_PT_input(Panel): userpref = context.user_preferences return (userpref.active_section == 'INPUT') - def draw_input_prefs(self, inputs, layout): + @staticmethod + def draw_input_prefs(inputs, layout): import sys # General settings diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index e2af544a317..d005b84f59d 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -50,6 +50,8 @@ class VIEW3D_HT_header(Header): # Particle edit if mode == 'PARTICLE_EDIT': row.prop(toolsettings.particle_edit, "select_mode", text="", expand=True) + elif mode == 'HAIR_EDIT': + row.prop(toolsettings.hair_edit, "select_mode", text="", expand=True) # Occlude geometry if ((view.viewport_shade not in {'BOUNDBOX', 'WIREFRAME'} and (mode == 'PARTICLE_EDIT' or (mode == 'EDIT' and obj.type == 'MESH'))) or @@ -142,7 +144,7 @@ class VIEW3D_MT_editor_menus(Menu): layout.menu("VIEW3D_MT_select_paint_mask") elif mesh.use_paint_mask_vertex and mode_string == 'PAINT_WEIGHT': layout.menu("VIEW3D_MT_select_paint_mask_vertex") - elif mode_string != 'SCULPT': + elif mode_string not in {'SCULPT'}: layout.menu("VIEW3D_MT_select_%s" % mode_string.lower()) if mode_string == 'OBJECT': @@ -161,9 +163,9 @@ class VIEW3D_MT_editor_menus(Menu): if edit_object: layout.menu("VIEW3D_MT_edit_%s" % edit_object.type.lower()) elif obj: - if mode_string not in {'PAINT_TEXTURE'}: + if mode_string != 'PAINT_TEXTURE': layout.menu("VIEW3D_MT_%s" % mode_string.lower()) - if mode_string in {'SCULPT', 'PAINT_VERTEX', 'PAINT_WEIGHT', 'PAINT_TEXTURE'}: + if mode_string in {'SCULPT', 'PAINT_VERTEX', 'PAINT_WEIGHT', 'PAINT_TEXTURE', 'HAIR'}: layout.menu("VIEW3D_MT_brush") if mode_string == 'SCULPT': layout.menu("VIEW3D_MT_hide_mask") @@ -211,8 +213,10 @@ class VIEW3D_MT_transform_base(Menu): layout.operator("transform.shear", text="Shear") layout.operator("transform.bend", text="Bend") layout.operator("transform.push_pull", text="Push/Pull") - layout.operator("object.vertex_warp", text="Warp") - layout.operator("object.vertex_random", text="Randomize") + + if context.mode != 'OBJECT': + layout.operator("transform.vertex_warp", text="Warp") + layout.operator("transform.vertex_random", text="Randomize") # Generic transform menu - geometry types @@ -449,6 +453,9 @@ class VIEW3D_MT_view_navigation(Menu): layout = self.layout layout.operator_enum("view3d.view_orbit", "type") + props = layout.operator("view3d.view_orbit", "Orbit Opposite") + props.type = 'ORBITRIGHT' + props.angle = pi layout.separator() @@ -915,6 +922,13 @@ class VIEW3D_MT_select_paint_mask_vertex(Menu): layout.operator("paint.vert_select_ungrouped", text="Ungrouped Verts") +class VIEW3D_MT_select_hair(Menu): + bl_label = "Select" + + def draw(self, context): + layout = self.layout + + class VIEW3D_MT_angle_control(Menu): bl_label = "Angle Control" @@ -935,7 +949,7 @@ class VIEW3D_MT_angle_control(Menu): settings = UnifiedPaintPanel.paint_settings(context) brush = settings.brush - sculpt = (context.sculpt_object != None) + sculpt = (context.sculpt_object is not None) tex_slot = brush.texture_slot @@ -1043,6 +1057,17 @@ class INFO_MT_armature_add(Menu): layout.operator("object.armature_add", text="Single Bone", icon='BONE_DATA') +class INFO_MT_lamp_add(Menu): + bl_idname = "INFO_MT_lamp_add" + bl_label = "Lamp" + + def draw(self, context): + layout = self.layout + + layout.operator_context = 'INVOKE_REGION_WIN' + layout.operator_enum("object.lamp_add", "type") + + class INFO_MT_add(Menu): bl_label = "Add" @@ -1075,7 +1100,7 @@ class INFO_MT_add(Menu): layout.separator() layout.operator("object.camera_add", text="Camera", icon='OUTLINER_OB_CAMERA') - layout.operator_menu_enum("object.lamp_add", "type", text="Lamp", icon='OUTLINER_OB_LAMP') + layout.menu("INFO_MT_lamp_add", icon='OUTLINER_OB_LAMP') layout.separator() layout.operator_menu_enum("object.effector_add", "type", text="Force Field", icon='OUTLINER_OB_EMPTY') @@ -1130,6 +1155,7 @@ class VIEW3D_MT_object(Menu): layout.menu("VIEW3D_MT_object_parent") layout.menu("VIEW3D_MT_object_track") layout.menu("VIEW3D_MT_object_group") + layout.menu("VIEW3D_MT_object_cachelib") layout.menu("VIEW3D_MT_object_constraints") layout.separator() @@ -1396,6 +1422,29 @@ class VIEW3D_MT_object_group(Menu): layout.operator("group.objects_remove_active") +class VIEW3D_MT_object_cachelib(Menu): + bl_label = "Cache Library" + + @classmethod + def poll(cls, context): + ob = context.active_object + if not (ob and ob.cache_library): + return False + return True + + def draw(self, context): + layout = self.layout + scene = context.scene + ob = context.active_object + cachelib = ob.cache_library + + layout.operator("cachelibrary.bake", text="Bake") + props = layout.operator("cachelibrary.archive_slice", text="Slice") + props.input_filepath = cachelib.input_filepath + props.start_frame = scene.frame_start + props.end_frame = scene.frame_end + + class VIEW3D_MT_object_constraints(Menu): bl_label = "Constraints" @@ -1514,7 +1563,7 @@ class VIEW3D_MT_brush(Menu): layout.separator() # brush paint modes - layout.menu("VIEW3D_MT_brush_paint_modes") + layout.menu("VIEW3D_MT_brush_object_modes") # brush tool if context.sculpt_object: @@ -1524,6 +1573,8 @@ class VIEW3D_MT_brush(Menu): layout.prop_menu_enum(brush, "image_tool") elif context.vertex_paint_object or context.weight_paint_object: layout.prop_menu_enum(brush, "vertex_tool") + elif context.hair_edit_object: + layout.prop_menu_enum(brush, "hair_tool") # skip if no active brush if not brush: @@ -1551,7 +1602,7 @@ class VIEW3D_MT_brush(Menu): layout.operator("sculpt.set_persistent_base") -class VIEW3D_MT_brush_paint_modes(Menu): +class VIEW3D_MT_brush_object_modes(Menu): bl_label = "Enabled Modes" def draw(self, context): @@ -1564,6 +1615,7 @@ class VIEW3D_MT_brush_paint_modes(Menu): 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") + layout.prop(brush, "use_hair_edit", text="Hair Edit") # ********** Vertex paint menu ********** @@ -1655,9 +1707,9 @@ class VIEW3D_MT_paint_weight(Menu): layout.operator("object.vertex_group_quantize", text="Quantize") layout.operator("object.vertex_group_levels", text="Levels") layout.operator("object.vertex_group_blend", text="Blend") - prop = layout.operator("object.data_transfer", text="Transfer Weights") - prop.use_reverse_transfer = True - prop.data_type = 'VGROUP_WEIGHTS' + props = layout.operator("object.data_transfer", text="Transfer Weights") + props.use_reverse_transfer = True + props.data_type = 'VGROUP_WEIGHTS' layout.operator("object.vertex_group_limit_total", text="Limit Total") layout.operator("object.vertex_group_fix", text="Fix Deforms") @@ -1791,6 +1843,9 @@ class VIEW3D_MT_particle_specials(Menu): layout.separator() layout.operator("particle.mirror") + layout.separator() + + layout.operator("particle.shape_propagate_to_all") if particle_edit.select_mode == 'POINT': layout.separator() @@ -1816,6 +1871,14 @@ class VIEW3D_MT_particle_specials(Menu): class VIEW3D_MT_particle_showhide(ShowHideMenu, Menu): _operator_name = "particle" +# ********** Hair menu ********** + +class VIEW3D_MT_hair(Menu): + bl_label = "Hair" + + def draw(self, context): + layout = self.layout + # ********** Pose Menu ********** @@ -1933,6 +1996,10 @@ class VIEW3D_MT_pose_propagate(Menu): layout.separator() + layout.operator("pose.propagate", text="On Selected Keyframes").mode = 'SELECTED_KEYS' + + layout.separator() + layout.operator("pose.propagate", text="On Selected Markers").mode = 'SELECTED_MARKERS' @@ -2262,13 +2329,6 @@ class VIEW3D_MT_edit_mesh_vertices(Menu): layout.separator() - op = layout.operator("mesh.mark_sharp", text="Shade Smooth") - op.use_verts = True - op.clear = True - layout.operator("mesh.mark_sharp", text="Shade Sharp").use_verts = True - - layout.separator() - layout.operator("mesh.bevel").vertex_only = True layout.operator("mesh.convex_hull") layout.operator("mesh.vertices_smooth") @@ -2291,6 +2351,8 @@ class VIEW3D_MT_edit_mesh_edges(Menu): def draw(self, context): layout = self.layout + toolsettings = context.tool_settings + with_freestyle = bpy.app.build_options.freestyle layout.operator_context = 'INVOKE_REGION_WIN' @@ -2311,8 +2373,16 @@ class VIEW3D_MT_edit_mesh_edges(Menu): layout.separator() - layout.operator("mesh.mark_sharp") - layout.operator("mesh.mark_sharp", text="Clear Sharp").clear = True + if not toolsettings.mesh_select_mode[0]: + # edge mode + layout.operator("mesh.mark_sharp") + layout.operator("mesh.mark_sharp", text="Clear Sharp").clear = True + else: + # vert mode + layout.operator("mesh.mark_sharp").use_verts = True + props = layout.operator("mesh.mark_sharp", text="Clear Sharp") + props.use_verts = True + props.clear = True layout.separator() @@ -2467,6 +2537,7 @@ def draw_curve(self, context): layout.separator() layout.operator("curve.extrude_move") + layout.operator("curve.spin") layout.operator("curve.duplicate_move") layout.operator("curve.split") layout.operator("curve.separate") @@ -2568,10 +2639,6 @@ class VIEW3D_MT_edit_font(Menu): layout.operator("font.style_toggle", text="Toggle Underline").style = 'UNDERLINE' layout.operator("font.style_toggle", text="Toggle Small Caps").style = 'SMALL_CAPS' - layout.separator() - - layout.operator("font.insert_lorem") - class VIEW3D_MT_edit_text_chars(Menu): bl_label = "Special Characters" @@ -2710,6 +2777,7 @@ class VIEW3D_MT_edit_armature(Menu): layout.separator() layout.operator_context = 'EXEC_AREA' + layout.operator("armature.symmetrize") layout.operator("armature.autoside_names", text="AutoName Left/Right").type = 'XAXIS' layout.operator("armature.autoside_names", text="AutoName Front/Back").type = 'YAXIS' layout.operator("armature.autoside_names", text="AutoName Top/Bottom").type = 'ZAXIS' @@ -2748,6 +2816,7 @@ class VIEW3D_MT_armature_specials(Menu): layout.operator("armature.autoside_names", text="AutoName Front/Back").type = 'YAXIS' layout.operator("armature.autoside_names", text="AutoName Top/Bottom").type = 'ZAXIS' layout.operator("armature.flip_names", text="Flip Names") + layout.operator("armature.symmetrize") class VIEW3D_MT_edit_armature_parent(Menu): @@ -2941,16 +3010,50 @@ class VIEW3D_PT_view3d_display(Panel): row.prop(region, "use_box_clip") -class VIEW3D_PT_view3d_shading(Panel): +class VIEW3D_PT_view3d_stereo(Panel): bl_space_type = 'VIEW_3D' bl_region_type = 'UI' - bl_label = "Shading" + bl_label = "Stereoscopy" bl_options = {'DEFAULT_CLOSED'} @classmethod def poll(cls, context): + scene = context.scene + + multiview = scene.render.use_multiview + return context.space_data and multiview + + def draw(self, context): + layout = self.layout view = context.space_data - return (view) + + basic_stereo = context.scene.render.views_format == 'STEREO_3D' + + col = layout.column() + col.row().prop(view, "stereo_3d_camera", expand=True) + + col.label(text="Display:") + row = col.row() + row.active = basic_stereo + row.prop(view, "show_stereo_3d_cameras") + row = col.row() + row.active = basic_stereo + split = row.split() + split.prop(view, "show_stereo_3d_convergence_plane") + split = row.split() + split.prop(view, "stereo_3d_convergence_plane_alpha", text="Alpha") + split.active = view.show_stereo_3d_convergence_plane + row = col.row() + split = row.split() + split.prop(view, "show_stereo_3d_volume") + split = row.split() + split.prop(view, "stereo_3d_volume_alpha", text="Alpha") + + +class VIEW3D_PT_view3d_shading(Panel): + bl_space_type = 'VIEW_3D' + bl_region_type = 'UI' + bl_label = "Shading" def draw(self, context): layout = self.layout @@ -2983,12 +3086,12 @@ class VIEW3D_PT_view3d_shading(Panel): if obj and obj.mode == 'EDIT': col.prop(view, "show_occlude_wire") - fx_settings = view.fx_settings + fx_settings = view.fx_settings + if view.viewport_shade not in {'BOUNDBOX', 'WIREFRAME'}: sub = col.column() sub.active = view.region_3d.view_perspective == 'CAMERA' sub.prop(fx_settings, "use_dof") - col.prop(fx_settings, "use_ssao", text="Ambient Occlusion") if fx_settings.use_ssao: ssao_settings = fx_settings.ssao diff --git a/release/scripts/startup/bl_ui/space_view3d_toolbar.py b/release/scripts/startup/bl_ui/space_view3d_toolbar.py index a45892cc25d..1fba3978e67 100644 --- a/release/scripts/startup/bl_ui/space_view3d_toolbar.py +++ b/release/scripts/startup/bl_ui/space_view3d_toolbar.py @@ -100,7 +100,7 @@ class VIEW3D_PT_tools_object(View3DPanel, Panel): row.operator("object.shade_smooth", text="Smooth") row.operator("object.shade_flat", text="Flat") - if obj_type in {'MESH'}: + if obj_type == 'MESH': col = layout.column(align=True) col.label(text="Data Transfer:") row = col.row(align=True) @@ -315,7 +315,7 @@ class VIEW3D_PT_tools_meshedit(View3DPanel, Panel): row.operator("transform.vert_slide", text="Vertex") col.operator("mesh.noise") col.operator("mesh.vertices_smooth") - col.operator("object.vertex_random") + col.operator("transform.vertex_random") col = layout.column(align=True) col.label(text="Add:") @@ -407,9 +407,9 @@ class VIEW3D_PT_tools_shading(View3DPanel, Panel): row.operator("mesh.mark_sharp", text="Sharp") col.label(text="Vertices:") row = col.row(align=True) - op = row.operator("mesh.mark_sharp", text="Smooth") - op.use_verts = True - op.clear = True + props = row.operator("mesh.mark_sharp", text="Smooth") + props.use_verts = True + props.clear = True row.operator("mesh.mark_sharp", text="Sharp").use_verts = True col = layout.column(align=True) @@ -523,7 +523,7 @@ class VIEW3D_PT_tools_curveedit(View3DPanel, Panel): col.operator("curve.extrude_move", text="Extrude") col.operator("curve.subdivide") col.operator("curve.smooth") - col.operator("object.vertex_random") + col.operator("transform.vertex_random") class VIEW3D_PT_tools_add_curve_edit(View3DPanel, Panel): @@ -573,11 +573,12 @@ class VIEW3D_PT_tools_surfaceedit(View3DPanel, Panel): col = layout.column(align=True) col.label(text="Modeling:") col.operator("curve.extrude", text="Extrude") + col.operator("curve.spin") col.operator("curve.subdivide") col = layout.column(align=True) col.label(text="Deform:") - col.operator("object.vertex_random") + col.operator("transform.vertex_random") class VIEW3D_PT_tools_add_surface_edit(View3DPanel, Panel): @@ -654,7 +655,7 @@ class VIEW3D_PT_tools_armatureedit(View3DPanel, Panel): col = layout.column(align=True) col.label(text="Deform:") - col.operator("object.vertex_random") + col.operator("transform.vertex_random") class VIEW3D_PT_tools_armatureedit_options(View3DPanel, Panel): @@ -687,7 +688,7 @@ class VIEW3D_PT_tools_mballedit(View3DPanel, Panel): col = layout.column(align=True) col.label(text="Deform:") - col.operator("object.vertex_random") + col.operator("transform.vertex_random") class VIEW3D_PT_tools_add_mball_edit(View3DPanel, Panel): @@ -725,7 +726,7 @@ class VIEW3D_PT_tools_latticeedit(View3DPanel, Panel): col = layout.column(align=True) col.label(text="Deform:") - col.operator("object.vertex_random") + col.operator("transform.vertex_random") # ********** default tools for pose-mode **************** @@ -758,6 +759,10 @@ class VIEW3D_PT_tools_posemode(View3DPanel, Panel): row.operator("pose.copy", text="Copy") row.operator("pose.paste", text="Paste") + row = layout.row(align=True) + row.operator("pose.propagate", text="Propagate") + row.menu("VIEW3D_MT_pose_propagate", icon='TRIA_RIGHT', text="") + col = layout.column(align=True) col.operator("poselib.pose_add", text="Add To Library") @@ -894,6 +899,21 @@ class VIEW3D_PT_tools_brush(Panel, View3DPaintPanel): layout.prop(brush, "puff_mode", expand=True) layout.prop(brush, "use_puff_volume") + # Hair Mode # + + elif context.hair_edit_object and brush: + col = layout.column() + + row = col.row(align=True) + self.prop_unified_size(row, context, brush, "size", slider=True, text="Radius") + self.prop_unified_size(row, context, brush, "use_pressure_size") + + 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") + + col.prop(brush, "hair_tool", text="Tool") + # Sculpt Mode # elif context.sculpt_object and brush: @@ -1075,7 +1095,7 @@ class TEXTURE_UL_texpaintslots(UIList): if (not mat.use_nodes) and context.scene.render.engine in {'BLENDER_RENDER', 'BLENDER_GAME'}: mtex_index = mat.texture_paint_slots[index].index layout.prop(mat, "use_textures", text="", index=mtex_index) - elif self.layout_type in {'GRID'}: + elif self.layout_type == 'GRID': layout.alignment = 'CENTER' layout.label(text="") @@ -1471,6 +1491,8 @@ class VIEW3D_PT_sculpt_dyntopo(Panel, View3DPaintPanel): row = sub.row(align=True) row.prop(sculpt, "constant_detail") row.operator("sculpt.sample_detail_size", text="", icon='EYEDROPPER') + elif (sculpt.detail_type_method == 'BRUSH'): + sub.prop(sculpt, "detail_percent") else: sub.prop(sculpt, "detail_size") sub.prop(sculpt, "detail_refine_method", text="") @@ -1605,9 +1627,9 @@ class VIEW3D_PT_tools_weightpaint(View3DPanel, Panel): col = layout.column() col.operator("paint.weight_gradient") - prop = col.operator("object.data_transfer", text="Transfer Weights") - prop.use_reverse_transfer = True - prop.data_type = 'VGROUP_WEIGHTS' + props = col.operator("object.data_transfer", text="Transfer Weights") + props.use_reverse_transfer = True + props.data_type = 'VGROUP_WEIGHTS' class VIEW3D_PT_tools_weightpaint_options(Panel, View3DPaintPanel): @@ -1698,6 +1720,25 @@ class VIEW3D_PT_tools_imagepaint_external(Panel, View3DPaintPanel): col.operator("paint.project_image", text="Apply Camera Image") +class VIEW3D_PT_tools_imagepaint_symmetry(Panel, View3DPaintPanel): + bl_category = "Tools" + bl_context = "imagepaint" + bl_label = "Symmetry" + bl_options = {'DEFAULT_CLOSED'} + + def draw(self, context): + layout = self.layout + + toolsettings = context.tool_settings + ipaint = toolsettings.image_paint + + col = layout.column(align=True) + row = col.row(align=True) + row.prop(ipaint, "use_symmetry_x", text="X", toggle=True) + row.prop(ipaint, "use_symmetry_y", text="Y", toggle=True) + row.prop(ipaint, "use_symmetry_z", text="Z", toggle=True) + + class VIEW3D_PT_tools_projectpaint(View3DPaintPanel, Panel): bl_category = "Options" bl_context = "imagepaint" @@ -1833,6 +1874,23 @@ class VIEW3D_PT_tools_particlemode(View3DPanel, Panel): sub.prop(pe, "fade_frames", slider=True) +class VIEW3D_PT_tools_hairmode(View3DPanel, Panel): + """Tools for hair mode""" + bl_context = "hairmode" + bl_label = "Options" + bl_category = "Tools" + + def draw(self, context): + layout = self.layout + + settings = context.tool_settings.hair_edit + ob = context.active_object + + if ob.data: + col = layout.column(align=True) + col.prop(ob.data, "use_mirror_x") + + # Grease Pencil drawing tools class VIEW3D_PT_tools_grease_pencil_draw(GreasePencilDrawingToolsPanel, Panel): bl_space_type = 'VIEW_3D' @@ -1858,7 +1916,7 @@ class VIEW3D_PT_tools_history(View3DPanel, Panel): row = col.row(align=True) row.operator("ed.undo") row.operator("ed.redo") - if obj is None or obj.mode not in {'SCULPT'}: + if obj is None or obj.mode != 'SCULPT': # Sculpt mode does not generate an undo menu it seems... col.operator("ed.undo_history") diff --git a/release/scripts/startup/nodeitems_builtins.py b/release/scripts/startup/nodeitems_builtins.py index 1590bd49763..e056719e4cc 100644 --- a/release/scripts/startup/nodeitems_builtins.py +++ b/release/scripts/startup/nodeitems_builtins.py @@ -66,6 +66,8 @@ node_tree_group_type = { # generic node group items generator for shader, compositor and texture node groups def node_group_items(context): + if context is None: + return space = context.space_data if not space: return @@ -234,6 +236,7 @@ shader_node_categories = [ NodeItem("ShaderNodeTexMagic"), NodeItem("ShaderNodeTexChecker"), NodeItem("ShaderNodeTexBrick"), + NodeItem("ShaderNodeTexPointDensity"), ]), ShaderNewNodeCategory("SH_NEW_OP_COLOR", "Color", items=[ NodeItem("ShaderNodeMixRGB"), @@ -328,6 +331,7 @@ compositor_node_categories = [ NodeItem("CompositorNodeCombYUVA"), NodeItem("CompositorNodeSepYCCA"), NodeItem("CompositorNodeCombYCCA"), + NodeItem("CompositorNodeSwitchView"), ]), CompositorNodeCategory("CMP_OP_FILTER", "Filter", items=[ NodeItem("CompositorNodeBlur"), |