diff options
author | Bastien Montagne <montagne29@wanadoo.fr> | 2018-06-02 20:30:26 +0300 |
---|---|---|
committer | Bastien Montagne <montagne29@wanadoo.fr> | 2018-06-03 17:35:54 +0300 |
commit | beca377c278fe7a1eedbd4491ece2686150081f0 (patch) | |
tree | 5c6196bac89c10bab926ce3f391714515b4894ea /release/scripts/startup | |
parent | 53c9fbef606f34d2a8d8da8c982448490d29d5fb (diff) | |
parent | 6de656b4f2ac66922d34bedbeb8f857bc878c5ae (diff) |
Merge branch 'blender2.8' into ui_layout_gridflow
Conflicts:
release/scripts/startup/bl_ui/properties_texture.py
source/blenderplayer/bad_level_call_stubs/stubs.c
Diffstat (limited to 'release/scripts/startup')
71 files changed, 6419 insertions, 7131 deletions
diff --git a/release/scripts/startup/bl_operators/add_mesh_torus.py b/release/scripts/startup/bl_operators/add_mesh_torus.py index cbe924dc360..53f51af430f 100644 --- a/release/scripts/startup/bl_operators/add_mesh_torus.py +++ b/release/scripts/startup/bl_operators/add_mesh_torus.py @@ -79,7 +79,7 @@ def add_torus(major_rad, minor_rad, major_seg, minor_seg): def add_uvs(mesh, minor_seg, major_seg): from math import fmod - mesh.uv_textures.new() + mesh.uv_layers.new() uv_data = mesh.uv_layers.active.data polygons = mesh.polygons u_step = 1.0 / major_seg diff --git a/release/scripts/startup/bl_operators/clip.py b/release/scripts/startup/bl_operators/clip.py index 35b8a08bf21..e67b275a3ee 100644 --- a/release/scripts/startup/bl_operators/clip.py +++ b/release/scripts/startup/bl_operators/clip.py @@ -235,7 +235,7 @@ class CLIP_OT_track_to_empty(Operator): ob = None ob = bpy.data.objects.new(name=track.name, object_data=None) - ob.select = True + ob.select_set(action='SELECT') context.scene.objects.link(ob) context.scene.objects.active = ob @@ -515,7 +515,7 @@ object's movement caused by this constraint""" # XXX, should probably use context.selected_editable_objects # since selected objects can be from a lib or in hidden layer! for ob in scene.objects: - if ob.select: + if ob.select_set(action='SELECT'): self._bake_object(scene, ob) return {'FINISHED'} @@ -612,24 +612,24 @@ class CLIP_OT_setup_tracking_scene(Operator): CLIP_set_viewport_background(context, True, sc.clip, sc.clip_user) @staticmethod - def _setupRenderLayers(context): + def _setupViewLayers(context): scene = context.scene - rlayers = scene.render.layers + view_layers = scene.view_layers - if not scene.render.layers.get("Foreground"): - if len(rlayers) == 1: - fg = rlayers[0] + if not view_layers.get("Foreground"): + if len(view_layers) == 1: + fg = view_layers[0] fg.name = 'Foreground' else: - fg = scene.render.layers.new("Foreground") + fg = view_layers.new("Foreground") fg.use_sky = True fg.layers = [True] + [False] * 19 fg.layers_zmask = [False] * 10 + [True] + [False] * 9 fg.use_pass_vector = True - if not scene.render.layers.get("Background"): - bg = scene.render.layers.new("Background") + if not view_layers.get("Background"): + bg = view_layers.new("Background") bg.use_pass_shadow = True bg.use_pass_ambient_occlusion = True bg.layers = [False] * 10 + [True] + [False] * 9 @@ -941,8 +941,8 @@ class CLIP_OT_setup_tracking_scene(Operator): def _setupObjects(self, context): scene = context.scene - fg = scene.render.layers.get("Foreground") - bg = scene.render.layers.get("Background") + fg = scene.view_layers.get("Foreground") + bg = scene.view_layers.get("Background") all_layers = self._mergeLayers(fg.layers, bg.layers) @@ -986,7 +986,7 @@ class CLIP_OT_setup_tracking_scene(Operator): self._setupWorld(context) self._setupCamera(context) self._setupViewport(context) - self._setupRenderLayers(context) + self._setupViewLayers(context) self._setupNodes(context) self._setupObjects(context) diff --git a/release/scripts/startup/bl_operators/file.py b/release/scripts/startup/bl_operators/file.py index 4ab8d59f263..8d947d19a82 100644 --- a/release/scripts/startup/bl_operators/file.py +++ b/release/scripts/startup/bl_operators/file.py @@ -65,10 +65,10 @@ class WM_OT_previews_batch_generate(Operator): name="Scenes", description="Generate scenes' previews", ) - use_groups = BoolProperty( + use_collections = BoolProperty( default=True, - name="Groups", - description="Generate groups' previews", + name="Collections", + description="Generate collections' previews", ) use_objects = BoolProperty( default=True, @@ -121,8 +121,8 @@ class WM_OT_previews_batch_generate(Operator): ]) if not self.use_scenes: cmd.append('--no_scenes') - if not self.use_groups: - cmd.append('--no_groups') + if not self.use_collections: + cmd.append('--no_collections') if not self.use_objects: cmd.append('--no_objects') if not self.use_intern_data: @@ -175,9 +175,9 @@ class WM_OT_previews_batch_clear(Operator): name="Scenes", description="Clear scenes' previews", ) - use_groups = BoolProperty(default=True, - name="Groups", - description="Clear groups' previews", + use_collections = BoolProperty(default=True, + name="Collections", + description="Clear collections' previews", ) use_objects = BoolProperty( default=True, @@ -231,8 +231,8 @@ class WM_OT_previews_batch_clear(Operator): ]) if not self.use_scenes: cmd.append('--no_scenes') - if not self.use_groups: - cmd.append('--no_groups') + if not self.use_collections: + cmd.append('--no_collections') if not self.use_objects: cmd.append('--no_objects') if not self.use_intern_data: diff --git a/release/scripts/startup/bl_operators/freestyle.py b/release/scripts/startup/bl_operators/freestyle.py index f5da7d45256..d3023f8e582 100644 --- a/release/scripts/startup/bl_operators/freestyle.py +++ b/release/scripts/startup/bl_operators/freestyle.py @@ -47,15 +47,15 @@ class SCENE_OT_freestyle_fill_range_by_selection(bpy.types.Operator): @classmethod def poll(cls, context): - rl = context.scene.render.layers.active - return rl and rl.freestyle_settings.linesets.active + view_layer = context.view_layer + return view_layer and view_layer.freestyle_settings.linesets.active def execute(self, context): import sys scene = context.scene - rl = scene.render.layers.active - lineset = rl.freestyle_settings.linesets.active + view_layer = context.view_layer + lineset = view_layer.freestyle_settings.linesets.active linestyle = lineset.linestyle # Find the modifier to work on if self.type == 'COLOR': @@ -104,7 +104,7 @@ class SCENE_OT_freestyle_fill_range_by_selection(bpy.types.Operator): m.range_max = max_dist return {'FINISHED'} # Find selected mesh objects - selection = [ob for ob in scene.objects if ob.select and ob.type == 'MESH' and ob.name != ref.name] + selection = [ob for ob in scene.objects if ob.select_get() and ob.type == 'MESH' and ob.name != source.name] if selection: # Compute the min/max distance from the reference to mesh vertices min_dist = sys.float_info.max @@ -207,8 +207,8 @@ class SCENE_OT_freestyle_module_open(bpy.types.Operator): @classmethod def poll(cls, context): - rl = context.scene.render.layers.active - return rl and rl.freestyle_settings.mode == 'SCRIPT' + view_layer = context.view_layer + return view_layer and view_layer.freestyle_settings.mode == 'SCRIPT' def invoke(self, context, event): self.freestyle_module = context.freestyle_module diff --git a/release/scripts/startup/bl_operators/mesh.py b/release/scripts/startup/bl_operators/mesh.py index 467c3df3158..c7a11c23c3f 100644 --- a/release/scripts/startup/bl_operators/mesh.py +++ b/release/scripts/startup/bl_operators/mesh.py @@ -50,7 +50,7 @@ class MeshMirrorUV(Operator): @classmethod def poll(cls, context): obj = context.active_object - return (obj and obj.type == 'MESH' and obj.data.uv_textures.active) + return (obj and obj.type == 'MESH' and obj.data.uv_layers.active) def execute(self, context): DIR = (self.direction == 'NEGATIVE') diff --git a/release/scripts/startup/bl_operators/object.py b/release/scripts/startup/bl_operators/object.py index 307764205e6..0959cbec448 100644 --- a/release/scripts/startup/bl_operators/object.py +++ b/release/scripts/startup/bl_operators/object.py @@ -81,16 +81,18 @@ class SelectPattern(Operator): # Can be pose bones or objects for item in items: if pattern_match(item.name, self.pattern): - item.select = True # hrmf, perhaps there should be a utility function for this. if is_ebone: + item.select = True item.select_head = True item.select_tail = True if item.use_connect: item_parent = item.parent if item_parent is not None: item_parent.select_tail = True + else: + item.select_set(action='SELECT') return {'FINISHED'} @@ -121,6 +123,7 @@ class SelectCamera(Operator): def execute(self, context): scene = context.scene + view_layer = context.view_layer view = context.space_data if view.type == 'VIEW_3D' and not view.lock_camera_and_layers: camera = view.camera @@ -134,9 +137,9 @@ class SelectCamera(Operator): else: if not self.extend: bpy.ops.object.select_all(action='DESELECT') - scene.objects.active = camera - camera.hide = False - camera.select = True + view_layer.objects.active = camera + # camera.hide = False # XXX TODO where is this now? + camera.select_set(action='SELECT') return {'FINISHED'} return {'CANCELLED'} @@ -169,6 +172,7 @@ class SelectHierarchy(Operator): def execute(self, context): scene = context.scene + view_layer = context.view_layer select_new = [] act_new = None @@ -202,9 +206,9 @@ class SelectHierarchy(Operator): bpy.ops.object.select_all(action='DESELECT') for obj in select_new: - obj.select = True + obj.select_set(action='SELECT') - scene.objects.active = act_new + view_layer.objects.active = act_new return {'FINISHED'} return {'CANCELLED'} @@ -513,7 +517,7 @@ class JoinUVs(Operator): if is_editmode: bpy.ops.object.mode_set(mode='OBJECT', toggle=False) - if not mesh.uv_textures: + if not mesh.uv_layers: self.report({'WARNING'}, "Object: %s, Mesh: '%s' has no UVs" % (obj.name, mesh.name)) @@ -551,7 +555,7 @@ class JoinUVs(Operator): else: uv_other = mesh_other.uv_layers.active if not uv_other: - mesh_other.uv_textures.new() + mesh_other.uv_layers.new() uv_other = mesh_other.uv_layers.active if not uv_other: self.report({'ERROR'}, "Could not add " @@ -644,8 +648,8 @@ 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 + ob_inst.select_set(action='SELECT') + ob_new.select_set(action='SELECT') def execute(self, context): self._main(context) @@ -664,7 +668,7 @@ class IsolateTypeRender(Operator): for obj in context.visible_objects: - if obj.select: + if obj.select_get(): obj.hide_render = False else: if obj.type == act_type: @@ -861,7 +865,7 @@ class TransformsToDeltasAnim(Operator): class DupliOffsetFromCursor(Operator): - """Set offset used for DupliGroup based on cursor position""" + """Set offset used for collection instances based on cursor position""" bl_idname = "object.dupli_offset_from_cursor" bl_label = "Set Offset From Cursor" bl_options = {'INTERNAL', 'UNDO'} @@ -872,166 +876,9 @@ class DupliOffsetFromCursor(Operator): def execute(self, context): scene = context.scene - group = context.group - - group.dupli_offset = scene.cursor_location - - return {'FINISHED'} - - -class LodByName(Operator): - """Add levels of detail to this object based on object names""" - bl_idname = "object.lod_by_name" - bl_label = "Setup Levels of Detail By Name" - bl_options = {'REGISTER', 'UNDO'} - - @classmethod - def poll(cls, context): - return (context.active_object is not None) - - def execute(self, context): - ob = context.active_object - - prefix = "" - suffix = "" - name = "" - if ob.name.lower().startswith("lod0"): - prefix = ob.name[:4] - name = ob.name[4:] - elif ob.name.lower().endswith("lod0"): - name = ob.name[:-4] - suffix = ob.name[-4:] - else: - return {'CANCELLED'} - - level = 0 - while True: - level += 1 - - if prefix: - prefix = prefix[:3] + str(level) - if suffix: - suffix = suffix[:3] + str(level) - - lod = None - try: - lod = bpy.data.objects[prefix + name + suffix] - except KeyError: - break - - try: - ob.lod_levels[level] - except IndexError: - bpy.ops.object.lod_add() - - ob.lod_levels[level].object = lod - - return {'FINISHED'} - - -class LodClearAll(Operator): - """Remove all levels of detail from this object""" - bl_idname = "object.lod_clear_all" - bl_label = "Clear All Levels of Detail" - bl_options = {'REGISTER', 'UNDO'} - - @classmethod - def poll(cls, context): - return (context.active_object is not None) - - def execute(self, context): - ob = context.active_object - - if ob.lod_levels: - while 'CANCELLED' not in bpy.ops.object.lod_remove(): - pass - - return {'FINISHED'} - - -class LodGenerate(Operator): - """Generate levels of detail using the decimate modifier""" - bl_idname = "object.lod_generate" - bl_label = "Generate Levels of Detail" - bl_options = {'REGISTER', 'UNDO'} - - count = IntProperty( - name="Count", - default=3, - ) - target = FloatProperty( - name="Target Size", - min=0.0, max=1.0, - default=0.1, - ) - package = BoolProperty( - name="Package into Group", - default=False, - ) - - @classmethod - def poll(cls, context): - return (context.active_object is not None) - - def execute(self, context): - scene = context.scene - ob = scene.objects.active - - lod_name = ob.name - lod_suffix = "lod" - lod_prefix = "" - if lod_name.lower().endswith("lod0"): - lod_suffix = lod_name[-3:-1] - lod_name = lod_name[:-3] - elif lod_name.lower().startswith("lod0"): - lod_suffix = "" - lod_prefix = lod_name[:3] - lod_name = lod_name[4:] - - group_name = lod_name.strip(' ._') - if self.package: - try: - bpy.ops.object.group_link(group=group_name) - except TypeError: - bpy.ops.group.create(name=group_name) - - step = (1.0 - self.target) / (self.count - 1) - for i in range(1, self.count): - scene.objects.active = ob - bpy.ops.object.duplicate() - lod = context.selected_objects[0] - - scene.objects.active = ob - bpy.ops.object.lod_add() - scene.objects.active = lod - - if lod_prefix: - lod.name = lod_prefix + str(i) + lod_name - else: - lod.name = lod_name + lod_suffix + str(i) - - lod.location.y = ob.location.y + 3.0 * i - - if i == 1: - modifier = lod.modifiers.new("lod_decimate", 'DECIMATE') - else: - modifier = lod.modifiers[-1] - - modifier.ratio = 1.0 - step * i - - ob.lod_levels[i].object = lod - - if self.package: - bpy.ops.object.group_link(group=group_name) - lod.parent = ob - - if self.package: - for level in ob.lod_levels[1:]: - level.object.hide = level.object.hide_render = True + collection = context.collection - lod.select = False - ob.select = True - scene.objects.active = ob + collection.dupli_offset = scene.cursor_location return {'FINISHED'} @@ -1041,9 +888,6 @@ classes = ( DupliOffsetFromCursor, IsolateTypeRender, JoinUVs, - LodByName, - LodClearAll, - LodGenerate, MakeDupliFace, SelectCamera, SelectHierarchy, diff --git a/release/scripts/startup/bl_operators/object_quick_effects.py b/release/scripts/startup/bl_operators/object_quick_effects.py index 4c2a9e76dc7..70334fb0f23 100644 --- a/release/scripts/startup/bl_operators/object_quick_effects.py +++ b/release/scripts/startup/bl_operators/object_quick_effects.py @@ -222,7 +222,7 @@ class QuickExplode(Operator): if self.fade: explode.show_dead = False - uv = obj.data.uv_textures.new("Explode fade") + uv = obj.data.uv_layers.new("Explode fade") explode.particle_uv = uv.name mat = object_ensure_material(obj, "Explode Fade") @@ -364,88 +364,38 @@ class QuickSmoke(Operator): # Setup material - # Cycles - if context.scene.render.use_shading_nodes: - bpy.ops.object.material_slot_add() - - mat = bpy.data.materials.new("Smoke Domain Material") - obj.material_slots[0].material = mat - - # Make sure we use nodes - mat.use_nodes = True - - # Set node variables and clear the default nodes - tree = mat.node_tree - nodes = tree.nodes - links = tree.links - - nodes.clear() + # Cycles and Eevee + bpy.ops.object.material_slot_add() - # Create shader nodes + mat = bpy.data.materials.new("Smoke Domain Material") + obj.material_slots[0].material = mat - # Material output - node_out = nodes.new(type='ShaderNodeOutputMaterial') - node_out.location = grid_location(6, 1) + # Make sure we use nodes + mat.use_nodes = True - # Add Principled Volume - node_principled = nodes.new(type='ShaderNodeVolumePrincipled') - node_principled.location = grid_location(4, 1) - links.new(node_principled.outputs["Volume"], - node_out.inputs["Volume"]) + # Set node variables and clear the default nodes + tree = mat.node_tree + nodes = tree.nodes + links = tree.links - node_principled.inputs["Density"].default_value = 5.0 + nodes.clear() - if self.style in {'FIRE', 'BOTH'}: - node_principled.inputs["Blackbody Intensity"].default_value = 1.0 + # Create shader nodes - # Blender Internal - else: - # create a volume material with a voxel data texture for the domain - bpy.ops.object.material_slot_add() - - mat = bpy.data.materials.new("Smoke Domain Material") - obj.material_slots[0].material = mat - mat.type = 'VOLUME' - mat.volume.density = 0 - mat.volume.density_scale = 5 - mat.volume.step_size = 0.1 - - tex = bpy.data.textures.new("Smoke Density", 'VOXEL_DATA') - tex.voxel_data.domain_object = obj - tex.voxel_data.interpolation = 'TRICUBIC_BSPLINE' - - tex_slot = mat.texture_slots.add() - tex_slot.texture = tex - tex_slot.texture_coords = 'ORCO' - tex_slot.use_map_color_emission = False - tex_slot.use_map_density = True - tex_slot.use_map_color_reflection = True - - # for fire add a second texture for flame emission - mat.volume.emission_color = Vector((0.0, 0.0, 0.0)) - tex = bpy.data.textures.new("Flame", 'VOXEL_DATA') - tex.voxel_data.domain_object = obj - tex.voxel_data.smoke_data_type = 'SMOKEFLAME' - tex.voxel_data.interpolation = 'TRICUBIC_BSPLINE' - tex.use_color_ramp = True + # Material output + node_out = nodes.new(type='ShaderNodeOutputMaterial') + node_out.location = grid_location(6, 1) - tex_slot = mat.texture_slots.add() - tex_slot.texture = tex - tex_slot.texture_coords = 'ORCO' + # Add Principled Volume + node_principled = nodes.new(type='ShaderNodeVolumePrincipled') + node_principled.location = grid_location(4, 1) + links.new(node_principled.outputs["Volume"], + node_out.inputs["Volume"]) - # add color ramp for flame color - ramp = tex.color_ramp - # dark orange - elem = ramp.elements.new(0.333) - elem.color = (0.2, 0.03, 0.0, 1.0) + node_principled.inputs["Density"].default_value = 5.0 - # yellow glow - elem = ramp.elements.new(0.666) - elem.color = (1, 0.65, 0.25, 1.0) - - mat.texture_slots[1].use_map_density = True - mat.texture_slots[1].use_map_emission = True - mat.texture_slots[1].emission_factor = 5 + if self.style in {'FIRE', 'BOTH'}: + node_principled.inputs["Blackbody Intensity"].default_value = 1.0 return {'FINISHED'} @@ -547,13 +497,33 @@ class QuickFluid(Operator): mat = bpy.data.materials.new("Fluid Domain Material") obj.material_slots[0].material = mat - mat.specular_intensity = 1 - mat.specular_hardness = 100 - mat.use_transparency = True - mat.alpha = 0.0 - mat.transparency_method = 'RAYTRACE' - mat.raytrace_transparency.ior = 1.33 - mat.raytrace_transparency.depth = 4 + # Make sure we use nodes + mat.use_nodes = True + + # Set node variables and clear the default nodes + tree = mat.node_tree + nodes = tree.nodes + links = tree.links + + nodes.clear() + + # Create shader nodes + + # Material output + node_out = nodes.new(type='ShaderNodeOutputMaterial') + node_out.location = grid_location(6, 1) + + # Add Glass + node_glass = nodes.new(type='ShaderNodeBsdfGlass') + node_glass.location = grid_location(4, 1) + links.new(node_glass.outputs["BSDF"], node_out.inputs["Surface"]) + node_glass.inputs["IOR"].default_value = 1.33 + + # Add Absorption + node_absorption = nodes.new(type='ShaderNodeVolumeAbsorption') + node_absorption.location = grid_location(4, 2) + links.new(node_absorption.outputs["Volume"], node_out.inputs["Volume"]) + node_absorption.inputs["Color"].default_value = (0.8, 0.9, 1.0, 1.0) if self.start_baking: bpy.ops.fluid.bake('INVOKE_DEFAULT') diff --git a/release/scripts/startup/bl_operators/presets.py b/release/scripts/startup/bl_operators/presets.py index c696c38dac6..deca40909ae 100644 --- a/release/scripts/startup/bl_operators/presets.py +++ b/release/scripts/startup/bl_operators/presets.py @@ -252,7 +252,6 @@ class AddPresetRender(AddPresetBase, Operator): ] preset_values = [ - "scene.render.field_order", "scene.render.fps", "scene.render.fps_base", "scene.render.pixel_aspect_x", @@ -260,8 +259,6 @@ class AddPresetRender(AddPresetBase, Operator): "scene.render.resolution_percentage", "scene.render.resolution_x", "scene.render.resolution_y", - "scene.render.use_fields", - "scene.render.use_fields_still", ] preset_subdir = "render" @@ -318,34 +315,6 @@ class AddPresetSafeAreas(AddPresetBase, Operator): preset_subdir = "safe_areas" -class AddPresetSSS(AddPresetBase, Operator): - """Add or remove a Subsurface Scattering Preset""" - bl_idname = "material.sss_preset_add" - bl_label = "Add SSS Preset" - preset_menu = "MATERIAL_MT_sss_presets" - - preset_defines = [ - ("material = " - "bpy.context.material.active_node_material " - "if bpy.context.material.active_node_material " - "else bpy.context.material") - ] - - preset_values = [ - "material.subsurface_scattering.back", - "material.subsurface_scattering.color", - "material.subsurface_scattering.color_factor", - "material.subsurface_scattering.error_threshold", - "material.subsurface_scattering.front", - "material.subsurface_scattering.ior", - "material.subsurface_scattering.radius", - "material.subsurface_scattering.scale", - "material.subsurface_scattering.texture_factor", - ] - - preset_subdir = "sss" - - class AddPresetCloth(AddPresetBase, Operator): """Add or remove a Cloth Preset""" bl_idname = "cloth.preset_add" @@ -695,7 +664,6 @@ classes = ( AddPresetNodeColor, AddPresetOperator, AddPresetRender, - AddPresetSSS, AddPresetSafeAreas, AddPresetSunSky, AddPresetTrackingCamera, diff --git a/release/scripts/startup/bl_operators/rigidbody.py b/release/scripts/startup/bl_operators/rigidbody.py index 6792d525683..e10a2a2915e 100644 --- a/release/scripts/startup/bl_operators/rigidbody.py +++ b/release/scripts/startup/bl_operators/rigidbody.py @@ -65,7 +65,7 @@ class CopyRigidbodySettings(Operator): # deselect all but mesh objects for o in context.selected_objects: if o.type != 'MESH': - o.select = False + o.select_set(action='DESELECT') elif o.rigid_body is None: # Add rigidbody to object! scene.objects.active = o @@ -127,7 +127,7 @@ class BakeToKeyframes(Operator): # filter objects selection for obj in context.selected_objects: if not obj.rigid_body or obj.rigid_body.type != 'ACTIVE': - obj.select = False + obj.select_set(action='DESELECT') objects = context.selected_objects @@ -260,7 +260,7 @@ class ConnectRigidBodies(Operator): ob.location = loc context.scene.objects.link(ob) context.scene.objects.active = ob - ob.select = True + ob.select_set(action='SELECT') bpy.ops.rigidbody.constraint_add() con_obj = context.active_object @@ -305,7 +305,7 @@ class ConnectRigidBodies(Operator): # restore selection bpy.ops.object.select_all(action='DESELECT') for obj in objects: - obj.select = True + obj.select_set(action='SELECT') scene.objects.active = obj_act return {'FINISHED'} else: diff --git a/release/scripts/startup/bl_operators/uvcalc_follow_active.py b/release/scripts/startup/bl_operators/uvcalc_follow_active.py index 25ee5cafe81..29cefd83328 100644 --- a/release/scripts/startup/bl_operators/uvcalc_follow_active.py +++ b/release/scripts/startup/bl_operators/uvcalc_follow_active.py @@ -30,8 +30,8 @@ def extend(obj, operator, EXTEND_MODE): import bmesh me = obj.data # script will fail without UVs - if not me.uv_textures: - me.uv_textures.new() + if not me.uv_layers: + me.uv_layers.new() bm = bmesh.from_edit_mesh(me) @@ -252,4 +252,4 @@ class FollowActiveQuads(Operator): classes = ( FollowActiveQuads, -)
\ No newline at end of file +) diff --git a/release/scripts/startup/bl_operators/uvcalc_lightmap.py b/release/scripts/startup/bl_operators/uvcalc_lightmap.py index 8ee29d15d1b..61ceb3c04c4 100644 --- a/release/scripts/startup/bl_operators/uvcalc_lightmap.py +++ b/release/scripts/startup/bl_operators/uvcalc_lightmap.py @@ -275,12 +275,12 @@ def lightmap_uvpack(meshes, face_groups.append(faces) if PREF_NEW_UVLAYER: - me.uv_textures.new() + me.uv_layers.new() # Add face UV if it does not exist. # All new faces are selected. - if not me.uv_textures: - me.uv_textures.new() + if not me.uv_layers: + me.uv_layers.new() for face_sel in face_groups: print("\nStarting unwrap") @@ -538,6 +538,9 @@ def lightmap_uvpack(meshes, print("done") if PREF_APPLY_IMAGE: + pass + # removed with texface + ''' if not PREF_PACK_IN_ONE: image = bpy.data.images.new(name="lightmap", width=PREF_IMG_PX_SIZE, @@ -545,8 +548,8 @@ def lightmap_uvpack(meshes, ) for f in face_sel: - # f.image = image - f.id_data.uv_textures.active.data[f.index].image = image # XXX25 + f.image = image + ''' for me in meshes: me.update() @@ -672,4 +675,4 @@ class LightMapPack(Operator): classes = ( LightMapPack, -)
\ No newline at end of file +) diff --git a/release/scripts/startup/bl_operators/uvcalc_smart_project.py b/release/scripts/startup/bl_operators/uvcalc_smart_project.py index 12c56a18897..25783653414 100644 --- a/release/scripts/startup/bl_operators/uvcalc_smart_project.py +++ b/release/scripts/startup/bl_operators/uvcalc_smart_project.py @@ -810,8 +810,8 @@ def main(context, # Tag as used me.tag = True - if not me.uv_textures: # Mesh has no UV Coords, don't bother. - me.uv_textures.new() + if not me.uv_layers: # Mesh has no UV Coords, don't bother. + me.uv_layers.new() uv_layer = me.uv_layers.active.data me_verts = list(me.vertices) diff --git a/release/scripts/startup/bl_operators/wm.py b/release/scripts/startup/bl_operators/wm.py index 022ee1576d8..ee101bb3cc6 100644 --- a/release/scripts/startup/bl_operators/wm.py +++ b/release/scripts/startup/bl_operators/wm.py @@ -55,6 +55,15 @@ rna_relative_prop = BoolProperty( default=False, ) +rna_space_type_prop = EnumProperty( + name="Type", + items=tuple( + (e.identifier, e.name, "", e. value) + for e in bpy.types.Space.bl_rna.properties["type"].enum_items + ), + default='EMPTY', + ) + def context_path_validate(context, data_path): try: @@ -1089,6 +1098,11 @@ rna_use_soft_limits = BoolProperty( name="Use Soft Limits", ) +rna_is_overridable_static = BoolProperty( + name="Is Statically Overridable", + default=False, + ) + class WM_OT_properties_edit(Operator): bl_idname = "wm.properties_edit" @@ -1102,6 +1116,7 @@ class WM_OT_properties_edit(Operator): min = rna_min max = rna_max use_soft_limits = rna_use_soft_limits + is_overridable_static = rna_is_overridable_static soft_min = rna_min soft_max = rna_max description = StringProperty( @@ -1154,6 +1169,9 @@ class WM_OT_properties_edit(Operator): # print(exec_str) exec(exec_str) + exec_str = "item.property_overridable_static_set('[\"%s\"]', %s)" % (prop, self.is_overridable_static) + exec(exec_str) + rna_idprop_ui_prop_update(item, prop) self._last_prop[:] = [prop] @@ -1281,7 +1299,9 @@ class WM_OT_properties_edit(Operator): row.prop(self, "min") row.prop(self, "max") - layout.prop(self, "use_soft_limits") + row = layout.row() + row.prop(self, "use_soft_limits") + row.prop(self, "is_overridable_static") row = layout.row(align=True) row.enabled = self.use_soft_limits @@ -1492,54 +1512,6 @@ class WM_OT_copy_prev_settings(Operator): return {'CANCELLED'} -class WM_OT_blenderplayer_start(Operator): - """Launch the blender-player with the current blend-file""" - bl_idname = "wm.blenderplayer_start" - bl_label = "Start Game In Player" - - def execute(self, context): - import os - import sys - import subprocess - - gs = context.scene.game_settings - - # these remain the same every execution - blender_bin_path = bpy.app.binary_path - blender_bin_dir = os.path.dirname(blender_bin_path) - ext = os.path.splitext(blender_bin_path)[-1] - player_path = os.path.join(blender_bin_dir, "blenderplayer" + ext) - # done static vars - - if sys.platform == "darwin": - player_path = os.path.join(blender_bin_dir, "../../../blenderplayer.app/Contents/MacOS/blenderplayer") - - if not os.path.exists(player_path): - self.report({'ERROR'}, "Player path: %r not found" % player_path) - return {'CANCELLED'} - - filepath = bpy.data.filepath + '~' if bpy.data.is_saved else os.path.join(bpy.app.tempdir, "game.blend") - bpy.ops.wm.save_as_mainfile('EXEC_DEFAULT', filepath=filepath, copy=True) - - # start the command line call with the player path - args = [player_path] - - # handle some UI options as command line arguments - args.extend([ - "-g", "show_framerate", "=", "%d" % gs.show_framerate_profile, - "-g", "show_profile", "=", "%d" % gs.show_framerate_profile, - "-g", "show_properties", "=", "%d" % gs.show_debug_properties, - "-g", "ignore_deprecation_warnings", "=", "%d" % (not gs.use_deprecation_warnings), - ]) - - # finish the call with the path to the blend file - args.append(filepath) - - subprocess.call(args) - os.remove(filepath) - return {'FINISHED'} - - class WM_OT_keyconfig_test(Operator): """Test key-config for conflicts""" bl_idname = "wm.keyconfig_test" @@ -1887,6 +1859,37 @@ class WM_OT_addon_disable(Operator): return {'FINISHED'} +class WM_OT_owner_enable(Operator): + """Enable workspace owner ID""" + bl_idname = "wm.owner_enable" + bl_label = "Enable Add-on" + + owner_id = StringProperty( + name="UI Tag", + ) + + def execute(self, context): + workspace = context.workspace + workspace.owner_ids.new(self.owner_id) + return {'FINISHED'} + + +class WM_OT_owner_disable(Operator): + """Enable workspace owner ID""" + bl_idname = "wm.owner_disable" + bl_label = "Disable UI Tag" + + owner_id = StringProperty( + name="UI Tag", + ) + + def execute(self, context): + workspace = context.workspace + owner_id = workspace.owner_ids[self.owner_id] + workspace.owner_ids.remove(owner_id) + return {'FINISHED'} + + class WM_OT_theme_install(Operator): """Load and apply a Blender XML theme file""" bl_idname = "wm.theme_install" @@ -2332,6 +2335,71 @@ class WM_OT_app_template_install(Operator): return {'RUNNING_MODAL'} +class WM_OT_tool_set_by_name(Operator): + """Set the tool by name (for keymaps)""" + bl_idname = "wm.tool_set_by_name" + bl_label = "Set Tool By Name" + + name = StringProperty( + name="Text", + description="Display name of the tool", + ) + + cycle = BoolProperty( + name="Cycle", + description="Cycle through tools in this group", + default=False, + options={'SKIP_SAVE'}, + ) + + space_type = rna_space_type_prop + + def execute(self, context): + from bl_ui.space_toolsystem_common import ( + activate_by_name, + activate_by_name_or_cycle, + ) + + if self.properties.is_property_set("space_type"): + space_type = self.space_type + else: + space_type = context.space_data.type + + fn = activate_by_name_or_cycle if self.cycle else activate_by_name + if fn(context, space_type, self.name): + return {'FINISHED'} + else: + self.report({'WARNING'}, f"Tool {self.name!r} not found.") + return {'CANCELLED'} + + +class WM_OT_toolbar(Operator): + bl_idname = "wm.toolbar" + bl_label = "Toolbar" + + def execute(self, context): + from bl_ui.space_toolsystem_common import ( + ToolSelectPanelHelper, + keymap_from_context, + ) + space_type = context.space_data.type + + cls = ToolSelectPanelHelper._tool_class_from_space_type(space_type) + if cls is None: + self.report({'WARNING'}, f"Toolbar not found for {space_type!r}") + return {'CANCELLED'} + + wm = context.window_manager + keymap = keymap_from_context(context, space_type) + + def draw_menu(popover, context): + layout = popover.layout + cls.draw_cls(layout, context, detect_layout=False) + + wm.popover(draw_menu, keymap=keymap) + return {'FINISHED'} + + classes = ( BRUSH_OT_active_index_set, WM_OT_addon_disable, @@ -2344,7 +2412,6 @@ classes = ( WM_OT_app_template_install, WM_OT_appconfig_activate, WM_OT_appconfig_default, - WM_OT_blenderplayer_start, WM_OT_context_collection_boolean_set, WM_OT_context_cycle_array, WM_OT_context_cycle_enum, @@ -2384,5 +2451,9 @@ classes = ( WM_OT_properties_remove, WM_OT_sysinfo, WM_OT_theme_install, + WM_OT_owner_disable, + WM_OT_owner_enable, WM_OT_url_open, + WM_OT_tool_set_by_name, + WM_OT_toolbar, ) diff --git a/release/scripts/startup/bl_ui/__init__.py b/release/scripts/startup/bl_ui/__init__.py index 0a7b2cd2e8b..dd99195f12a 100644 --- a/release/scripts/startup/bl_ui/__init__.py +++ b/release/scripts/startup/bl_ui/__init__.py @@ -39,8 +39,9 @@ _modules = [ "properties_data_mesh", "properties_data_metaball", "properties_data_modifier", + "properties_data_lightprobe", "properties_data_speaker", - "properties_game", + "properties_data_workspace", "properties_mask_common", "properties_material", "properties_object", @@ -57,10 +58,17 @@ _modules = [ "properties_physics_smoke", "properties_physics_softbody", "properties_render", - "properties_render_layer", + "properties_view_layer", "properties_scene", "properties_texture", "properties_world", + + # Generic Space Modules + # + # Depends on DNA_WORKSPACE_TOOL (C define). + "space_toolsystem_common", + "space_toolsystem_toolbar", + "space_clip", "space_console", "space_dopesheet", @@ -68,14 +76,15 @@ _modules = [ "space_graph", "space_image", "space_info", - "space_logic", "space_nla", "space_node", "space_outliner", "space_properties", "space_sequencer", + "space_statusbar", "space_text", "space_time", + "space_topbar", "space_userpref", "space_view3d", "space_view3d_toolbar", diff --git a/release/scripts/startup/bl_ui/properties_data_armature.py b/release/scripts/startup/bl_ui/properties_data_armature.py index 411d64e2b94..e58b4f56ffe 100644 --- a/release/scripts/startup/bl_ui/properties_data_armature.py +++ b/release/scripts/startup/bl_ui/properties_data_armature.py @@ -65,11 +65,6 @@ class DATA_PT_skeleton(ArmatureButtonsPanel, Panel): col.label(text="Protected Layers:") col.prop(arm, "layers_protected", text="") - if context.scene.render.engine == 'BLENDER_GAME': - col = layout.column() - col.label(text="Deform:") - col.prop(arm, "deform_method", expand=True) - class DATA_PT_display(ArmatureButtonsPanel, Panel): bl_label = "Display" @@ -82,15 +77,13 @@ class DATA_PT_display(ArmatureButtonsPanel, Panel): layout.row().prop(arm, "draw_type", expand=True) - split = layout.split() + layout.use_property_split = True - col = split.column() + col = layout.column() col.prop(arm, "show_names", text="Names") col.prop(arm, "show_axes", text="Axes") col.prop(arm, "show_bone_custom_shapes", text="Shapes") - - col = split.column() - col.prop(arm, "show_group_colors", text="Colors") + col.prop(arm, "show_group_colors", text="Group Colors") if ob: col.prop(ob, "show_x_ray", text="X-Ray") col.prop(arm, "use_deform_delay", text="Delay Refresh") @@ -154,7 +147,8 @@ class DATA_PT_bone_groups(ArmatureButtonsPanel, Panel): sub = row.row(align=True) sub.operator("pose.group_assign", text="Assign") - sub.operator("pose.group_unassign", text="Remove") # row.operator("pose.bone_group_remove_from", text="Remove") + # row.operator("pose.bone_group_remove_from", text="Remove") + sub.operator("pose.group_unassign", text="Remove") sub = row.row(align=True) sub.operator("pose.group_select", text="Select") @@ -201,7 +195,11 @@ class DATA_PT_pose_library(ArmatureButtonsPanel, Panel): if pose_marker_active is not None: col.operator("poselib.pose_remove", icon='ZOOMOUT', text="") - col.operator("poselib.apply_pose", icon='ZOOM_SELECTED', text="").pose_index = poselib.pose_markers.active_index + col.operator( + "poselib.apply_pose", + icon='ZOOM_SELECTED', + text="", + ).pose_index = poselib.pose_markers.active_index col.operator("poselib.action_sanitize", icon='HELP', text="") # XXX: put in menu? @@ -221,21 +219,19 @@ class DATA_PT_ghost(ArmatureButtonsPanel, Panel): layout.row().prop(arm, "ghost_type", expand=True) - split = layout.split() + layout.use_property_split = True - col = split.column(align=True) + col = layout.column(align=True) if arm.ghost_type == 'RANGE': - col.prop(arm, "ghost_frame_start", text="Start") + col.prop(arm, "ghost_frame_start", text="Frame Start") col.prop(arm, "ghost_frame_end", text="End") col.prop(arm, "ghost_size", text="Step") elif arm.ghost_type == 'CURRENT_FRAME': - col.prop(arm, "ghost_step", text="Range") + col.prop(arm, "ghost_step", text="Frame Range") col.prop(arm, "ghost_size", text="Step") - col = split.column() - col.label(text="Display:") - col.prop(arm, "show_only_ghost_selected", text="Selected Only") + col.prop(arm, "show_only_ghost_selected", text="Display Selected Only") class DATA_PT_iksolver_itasc(ArmatureButtonsPanel, Panel): @@ -249,6 +245,7 @@ class DATA_PT_iksolver_itasc(ArmatureButtonsPanel, Panel): def draw(self, context): layout = self.layout + layout.use_property_split = True ob = context.object itasc = ob.pose.ik_param @@ -256,34 +253,37 @@ class DATA_PT_iksolver_itasc(ArmatureButtonsPanel, Panel): layout.prop(ob.pose, "ik_solver") if itasc: + layout.use_property_split = False layout.row().prop(itasc, "mode", expand=True) + layout.use_property_split = True simulation = (itasc.mode == 'SIMULATION') if simulation: - layout.label(text="Reiteration:") - layout.row().prop(itasc, "reiteration_method", expand=True) + layout.prop(itasc, "reiteration_method", expand=False) - row = layout.row() - row.active = not simulation or itasc.reiteration_method != 'NEVER' - row.prop(itasc, "precision") - row.prop(itasc, "iterations") + col = layout.column() + col.active = not simulation or itasc.reiteration_method != 'NEVER' + col.prop(itasc, "precision") + col.prop(itasc, "iterations") if simulation: layout.prop(itasc, "use_auto_step") - row = layout.row() + col = layout.column(align=True) if itasc.use_auto_step: - row.prop(itasc, "step_min", text="Min") - row.prop(itasc, "step_max", text="Max") + col.prop(itasc, "step_min", text="Steps Min") + col.prop(itasc, "step_max", text="Max") else: - row.prop(itasc, "step_count") + col.prop(itasc, "step_count", text="Steps") layout.prop(itasc, "solver") if simulation: layout.prop(itasc, "feedback") layout.prop(itasc, "velocity_max") if itasc.solver == 'DLS': - row = layout.row() - row.prop(itasc, "damping_max", text="Damp", slider=True) - row.prop(itasc, "damping_epsilon", text="Eps", slider=True) + col = layout.column() + col.separator() + col.prop(itasc, "damping_max", text="Damping Max", slider=True) + col.prop(itasc, "damping_epsilon", text="Damping Epsilon", slider=True) + from .properties_animviz import ( MotionPathButtonsPanel, @@ -328,7 +328,7 @@ class DATA_PT_onion_skinning(OnionSkinButtonsPanel): # , Panel): # inherit from class DATA_PT_custom_props_arm(ArmatureButtonsPanel, PropertyPanel, Panel): - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'} _context_path = "object.data" _property_type = bpy.types.Armature diff --git a/release/scripts/startup/bl_ui/properties_data_bone.py b/release/scripts/startup/bl_ui/properties_data_bone.py index 9fbb28c0f31..079669dbd02 100644 --- a/release/scripts/startup/bl_ui/properties_data_bone.py +++ b/release/scripts/startup/bl_ui/properties_data_bone.py @@ -62,88 +62,63 @@ class BONE_PT_transform(BoneButtonsPanel, Panel): def draw(self, context): layout = self.layout + layout.use_property_split = True ob = context.object bone = context.bone + col = layout.column() + if bone and ob: pchan = ob.pose.bones[bone.name] - - row = layout.row() - col = row.column() - col.prop(pchan, "location") col.active = not (bone.parent and bone.use_connect) - col = row.column() + sub = col.row(align=True) + sub.prop(pchan, "location") + sub.prop(pchan, "lock_location", text="") + + col = layout.column() if pchan.rotation_mode == 'QUATERNION': - col.prop(pchan, "rotation_quaternion", text="Rotation") + sub = col.row(align=True) + sub.prop(pchan, "rotation_quaternion", text="Rotation") + subsub = sub.column(align=True) + subsub.prop(pchan, "lock_rotation_w", text="") + subsub.prop(pchan, "lock_rotation", text="") elif pchan.rotation_mode == 'AXIS_ANGLE': - #col.label(text="Rotation") + # col.label(text="Rotation") #col.prop(pchan, "rotation_angle", text="Angle") #col.prop(pchan, "rotation_axis", text="Axis") - col.prop(pchan, "rotation_axis_angle", text="Rotation") + sub = col.row(align=True) + sub.prop(pchan, "rotation_axis_angle", text="Rotation") + subsub = sub.column(align=True) + subsub.prop(pchan, "lock_rotation_w", text="") + subsub.prop(pchan, "lock_rotation", text="") else: - col.prop(pchan, "rotation_euler", text="Rotation") + sub = col.row(align=True) + sub.prop(pchan, "rotation_euler", text="Rotation") + sub.prop(pchan, "lock_rotation", text="") - row.column().prop(pchan, "scale") + col = layout.column() + sub = col.row(align=True) + sub.prop(pchan, "scale") + sub.prop(pchan, "lock_scale", text="") - layout.prop(pchan, "rotation_mode") + col = layout.column() + col.prop(pchan, "rotation_mode") elif context.edit_bone: bone = context.edit_bone - row = layout.row() - row.column().prop(bone, "head") - row.column().prop(bone, "tail") - - col = row.column() - sub = col.column(align=True) - sub.label(text="Roll:") - sub.prop(bone, "roll", text="") - sub.label() - sub.prop(bone, "lock") - - -class BONE_PT_transform_locks(BoneButtonsPanel, Panel): - bl_label = "Transform Locks" - bl_options = {'DEFAULT_CLOSED'} - - @classmethod - def poll(cls, context): - ob = context.object - return ob and ob.mode == 'POSE' and context.bone - - def draw(self, context): - layout = self.layout - - ob = context.object - bone = context.bone - pchan = ob.pose.bones[bone.name] - - split = layout.split(percentage=0.1) - - col = split.column(align=True) - col.label(text="") - col.label(text="X:") - col.label(text="Y:") - col.label(text="Z:") - - col = split.column() - col.active = not (bone.parent and bone.use_connect) - col.prop(pchan, "lock_location", text="Location") - - col = split.column() - col.prop(pchan, "lock_rotation", text="Rotation") - - col = split.column() - col.prop(pchan, "lock_scale", text="Scale") + col = layout.column() + col.prop(bone, "head") + col.prop(bone, "tail") - if pchan.rotation_mode in {'QUATERNION', 'AXIS_ANGLE'}: - row = layout.row() - row.prop(pchan, "lock_rotations_4d", text="Lock Rotation") + col = layout.column() + col.prop(bone, "roll") + col.prop(bone, "lock") - sub = row.row() - sub.active = pchan.lock_rotations_4d - sub.prop(pchan, "lock_rotation_w", text="W") + col = layout.column() + col.prop(bone, "tail_radius") + col.prop(bone, "envelope_distance") class BONE_PT_curved(BoneButtonsPanel, Panel): @@ -166,54 +141,52 @@ class BONE_PT_curved(BoneButtonsPanel, Panel): bbone = bone layout = self.layout + layout.use_property_split = True + layout.prop(bone, "bbone_segments", text="Segments") col = layout.column() col.active = bone.bbone_segments > 1 - row = col.row() - sub = row.column(align=True) - sub.label(text="Curve XY Offsets:") - sub.prop(bbone, "bbone_curveinx", text="In X") - sub.prop(bbone, "bbone_curveoutx", text="Out X") - sub.prop(bbone, "bbone_curveiny", text="In Y") - sub.prop(bbone, "bbone_curveouty", text="Out Y") - - sub = row.column(align=True) - sub.label("Roll:") - sub.prop(bbone, "bbone_rollin", text="In") - sub.prop(bbone, "bbone_rollout", text="Out") - sub.prop(bone, "use_endroll_as_inroll") - - row = col.row() - sub = row.column(align=True) - sub.label(text="Scale:") - sub.prop(bbone, "bbone_scalein", text="In") - sub.prop(bbone, "bbone_scaleout", text="Out") - - sub = row.column(align=True) - sub.label("Easing:") - sub.prop(bbone, "bbone_easein", text="In") - sub.prop(bbone, "bbone_easeout", text="Out") + col = layout.column(align=True) + col.prop(bbone, "bbone_curveinx", text="Curve In X") + col.prop(bbone, "bbone_curveiny", text="In Y") + + col = layout.column(align=True) + col.prop(bbone, "bbone_curveoutx", text="Curve Out X") + col.prop(bbone, "bbone_curveouty", text="Out Y") + + col = layout.column(align=True) + col.prop(bbone, "bbone_rollin", text="Roll In") + col.prop(bbone, "bbone_rollout", text="Out") + col.prop(bone, "use_endroll_as_inroll") + + col = layout.column(align=True) + col.prop(bbone, "bbone_scalein", text="Scale In") + col.prop(bbone, "bbone_scaleout", text="Out") + + col = layout.column(align=True) + col.prop(bbone, "bbone_easein", text="Ease In") + col.prop(bbone, "bbone_easeout", text="Out") if pchan: layout.separator() col = layout.column() + col.use_property_split = False col.prop(pchan, "use_bbone_custom_handles") - row = col.row() - row.active = pchan.use_bbone_custom_handles + col = layout.column(align=True) + col.active = pchan.use_bbone_custom_handles + col.use_property_split = True - sub = row.column(align=True) - sub.label(text="In:") - sub.prop_search(pchan, "bbone_custom_handle_start", ob.pose, "bones", text="") - sub.prop(pchan, "use_bbone_relative_start_handle", text="Relative") + sub = col.column() + sub.prop_search(pchan, "bbone_custom_handle_start", ob.pose, "bones", text="Custom Handle Start") + sub.prop_search(pchan, "bbone_custom_handle_end", ob.pose, "bones", text="End") - sub = row.column(align=True) - sub.label(text="Out:") - sub.prop_search(pchan, "bbone_custom_handle_end", ob.pose, "bones", text="") - sub.prop(pchan, "use_bbone_relative_end_handle", text="Relative") + sub = col.column(align=True) + sub.prop(pchan, "use_bbone_relative_start_handle", text="Relative Handle Start") + sub.prop(pchan, "use_bbone_relative_end_handle", text="End") class BONE_PT_relations(BoneButtonsPanel, Panel): @@ -221,6 +194,7 @@ class BONE_PT_relations(BoneButtonsPanel, Panel): def draw(self, context): layout = self.layout + layout.use_property_split = True ob = context.object bone = context.bone @@ -232,26 +206,22 @@ class BONE_PT_relations(BoneButtonsPanel, Panel): elif bone is None: bone = context.edit_bone - split = layout.split() - - col = split.column() - col.label(text="Layers:") + col = layout.column() + col.use_property_split = False col.prop(bone, "layers", text="") + col.use_property_split = True + col = layout.column() col.separator() - if ob and pchan: - col.label(text="Bone Group:") - col.prop_search(pchan, "bone_group", ob.pose, "bone_groups", text="") - col.label(text="Object Children:") - col.prop(bone, "use_relative_parent") - - col = split.column() - col.label(text="Parent:") if context.bone: - col.prop(bone, "parent", text="") + col.prop(bone, "parent") else: - col.prop_search(bone, "parent", arm, "edit_bones", text="") + col.prop_search(bone, "parent", arm, "edit_bones") + + if ob and pchan: + col.prop(bone, "use_relative_parent") + col.prop_search(pchan, "bone_group", ob.pose, "bone_groups", text="Bone Group") sub = col.column() sub.active = (bone.parent is not None) @@ -274,6 +244,7 @@ class BONE_PT_display(BoneButtonsPanel, Panel): # note. this works ok in edit-mode but isn't # all that useful so disabling for now. layout = self.layout + layout.use_property_split = True ob = context.object bone = context.bone @@ -285,23 +256,20 @@ class BONE_PT_display(BoneButtonsPanel, Panel): bone = context.edit_bone if bone: - split = layout.split() - col = split.column() + col = layout.column() col.prop(bone, "hide", text="Hide") sub = col.column() sub.active = bool(pchan and pchan.custom_shape) sub.prop(bone, "show_wire", text="Wireframe") if pchan: - col = split.column() - - col.label(text="Custom Shape:") - col.prop(pchan, "custom_shape", text="") + col = layout.column() + col.prop(pchan, "custom_shape") if pchan.custom_shape: col.prop(pchan, "use_custom_shape_bone_size", text="Bone Size") col.prop(pchan, "custom_shape_scale", text="Scale") - col.prop_search(pchan, "custom_shape_transform", ob.pose, "bones", text="At") + col.prop_search(pchan, "custom_shape_transform", ob.pose, "bones") class BONE_PT_inverse_kinematics(BoneButtonsPanel, Panel): @@ -315,80 +283,82 @@ class BONE_PT_inverse_kinematics(BoneButtonsPanel, Panel): def draw(self, context): layout = self.layout + layout.use_property_split = True ob = context.object bone = context.bone pchan = ob.pose.bones[bone.name] - row = layout.row() - active = pchan.is_in_ik_chain - split = layout.split(percentage=0.25) - split.prop(pchan, "lock_ik_x", text="X") - split.active = active - row = split.row() - row.prop(pchan, "ik_stiffness_x", text="Stiffness", slider=True) - row.active = pchan.lock_ik_x is False and active + col = layout.column() + col.prop(pchan, "ik_stretch", slider=True) + col.active = active + + layout.separator() + + col = layout.column(align=True) - split = layout.split(percentage=0.25) - sub = split.row() + col.prop(pchan, "lock_ik_x", text="Lock IK X") + col.prop(pchan, "lock_ik_y", text="Y") + col.prop(pchan, "lock_ik_z", text="Z") - sub.prop(pchan, "use_ik_limit_x", text="Limit") + col = layout.column(align=True) + + sub = col.column(align=True) sub.active = pchan.lock_ik_x is False and active - sub = split.row(align=True) - sub.prop(pchan, "ik_min_x", text="") - sub.prop(pchan, "ik_max_x", text="") - sub.active = pchan.lock_ik_x is False and pchan.use_ik_limit_x and active + sub.prop(pchan, "ik_stiffness_x", text="Stiffness X", slider=True) + sub = col.column(align=True) + sub.active = pchan.lock_ik_y is False and active + sub.prop(pchan, "ik_stiffness_y", text="Y", slider=True) + sub = col.column(align=True) + sub.active = pchan.lock_ik_z is False and active + sub.prop(pchan, "ik_stiffness_z", text="Z", slider=True) + + col = layout.column(align=True) - split = layout.split(percentage=0.25) - split.prop(pchan, "lock_ik_y", text="Y") - split.active = active - row = split.row() - row.prop(pchan, "ik_stiffness_y", text="Stiffness", slider=True) - row.active = pchan.lock_ik_y is False and active + sub = col.column() + sub.active = pchan.lock_ik_x is False and active + sub.prop(pchan, "use_ik_limit_x", text="Limit X") - split = layout.split(percentage=0.25) - sub = split.row() + sub = col.column(align=True) + sub.active = pchan.lock_ik_x is False and pchan.use_ik_limit_x and active + sub.prop(pchan, "ik_min_x", text="Min") + sub.prop(pchan, "ik_max_x", text="Max") + + col.separator() - sub.prop(pchan, "use_ik_limit_y", text="Limit") + sub = col.column() sub.active = pchan.lock_ik_y is False and active + sub.prop(pchan, "use_ik_limit_y", text="Limit Y") - sub = split.row(align=True) - sub.prop(pchan, "ik_min_y", text="") - sub.prop(pchan, "ik_max_y", text="") + sub = col.column(align=True) sub.active = pchan.lock_ik_y is False and pchan.use_ik_limit_y and active + sub.prop(pchan, "ik_min_y", text="Min") + sub.prop(pchan, "ik_max_y", text="Max") - split = layout.split(percentage=0.25) - split.prop(pchan, "lock_ik_z", text="Z") - split.active = active - sub = split.row() - sub.prop(pchan, "ik_stiffness_z", text="Stiffness", slider=True) - sub.active = pchan.lock_ik_z is False and active - - split = layout.split(percentage=0.25) - sub = split.row() + col.separator() - sub.prop(pchan, "use_ik_limit_z", text="Limit") + sub = col.column() sub.active = pchan.lock_ik_z is False and active - sub = split.row(align=True) - sub.prop(pchan, "ik_min_z", text="") - sub.prop(pchan, "ik_max_z", text="") + sub.prop(pchan, "use_ik_limit_z", text="Limit Z") + + sub = col.column(align=True) sub.active = pchan.lock_ik_z is False and pchan.use_ik_limit_z and active + sub.prop(pchan, "ik_min_z", text="Min") + sub.prop(pchan, "ik_max_z", text="Max") - split = layout.split(percentage=0.25) - split.label(text="Stretch:") - sub = split.row() - sub.prop(pchan, "ik_stretch", text="", slider=True) - sub.active = active + col.separator() if ob.pose.ik_solver == 'ITASC': - split = layout.split() - col = split.column() + + col = layout.column() col.prop(pchan, "use_ik_rotation_control", text="Control Rotation") col.active = active - col = split.column() - col.prop(pchan, "ik_rotation_weight", text="Weight", slider=True) + + col = layout.column() + + col.prop(pchan, "ik_rotation_weight", text="IK Rotation Weight", slider=True) col.active = active # not supported yet #row = layout.row() @@ -410,6 +380,7 @@ class BONE_PT_deform(BoneButtonsPanel, Panel): def draw(self, context): layout = self.layout + layout.use_property_split = True bone = context.bone @@ -418,22 +389,20 @@ class BONE_PT_deform(BoneButtonsPanel, Panel): layout.active = bone.use_deform - row = layout.row() + col = layout.column() + col.prop(bone, "envelope_distance", text="Envelope Distance") + col.prop(bone, "envelope_weight", text="Envelope Weight") + col.prop(bone, "use_envelope_multiply", text="Envelope Multiply") - col = row.column(align=True) - col.label(text="Envelope:") - col.prop(bone, "envelope_distance", text="Distance") - col.prop(bone, "envelope_weight", text="Weight") - col.prop(bone, "use_envelope_multiply", text="Multiply") + col.separator() - col = row.column(align=True) - col.label(text="Envelope Radius:") - col.prop(bone, "head_radius", text="Head") + col = layout.column(align=True) + col.prop(bone, "head_radius", text="Radius Head") col.prop(bone, "tail_radius", text="Tail") class BONE_PT_custom_props(BoneButtonsPanel, PropertyPanel, Panel): - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'} _property_type = bpy.types.Bone, bpy.types.EditBone, bpy.types.PoseBone @property @@ -448,7 +417,6 @@ class BONE_PT_custom_props(BoneButtonsPanel, PropertyPanel, Panel): classes = ( BONE_PT_context_bone, BONE_PT_transform, - BONE_PT_transform_locks, BONE_PT_curved, BONE_PT_relations, BONE_PT_display, diff --git a/release/scripts/startup/bl_ui/properties_data_camera.py b/release/scripts/startup/bl_ui/properties_data_camera.py index 14286045704..f82512b2fde 100644 --- a/release/scripts/startup/bl_ui/properties_data_camera.py +++ b/release/scripts/startup/bl_ui/properties_data_camera.py @@ -29,7 +29,7 @@ class CameraButtonsPanel: @classmethod def poll(cls, context): - engine = context.scene.render.engine + engine = context.engine return context.camera and (engine in cls.COMPAT_ENGINES) @@ -37,7 +37,7 @@ class CAMERA_MT_presets(Menu): bl_label = "Camera Presets" preset_subdir = "camera" preset_operator = "script.execute_preset" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'} draw = Menu.draw_preset @@ -45,14 +45,14 @@ class SAFE_AREAS_MT_presets(Menu): bl_label = "Camera Presets" preset_subdir = "safe_areas" preset_operator = "script.execute_preset" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'} draw = Menu.draw_preset class DATA_PT_context_camera(CameraButtonsPanel, Panel): bl_label = "" bl_options = {'HIDE_HEADER'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'} def draw(self, context): layout = self.layout @@ -72,72 +72,70 @@ class DATA_PT_context_camera(CameraButtonsPanel, Panel): class DATA_PT_lens(CameraButtonsPanel, Panel): bl_label = "Lens" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'} def draw(self, context): layout = self.layout + layout.use_property_split = True cam = context.camera - layout.row().prop(cam, "type", expand=True) + layout.prop(cam, "type") - split = layout.split() + col = layout.column() + col.separator() - col = split.column() if cam.type == 'PERSP': - row = col.row() + col = layout.column() if cam.lens_unit == 'MILLIMETERS': - row.prop(cam, "lens") + col.prop(cam, "lens") elif cam.lens_unit == 'FOV': row.prop(cam, "angle") - row.prop(cam, "lens_unit", text="") + col.prop(cam, "lens_unit") elif cam.type == 'ORTHO': col.prop(cam, "ortho_scale") elif cam.type == 'PANO': - engine = context.scene.render.engine + engine = context.engine if engine == 'CYCLES': ccam = cam.cycles - col.prop(ccam, "panorama_type", text="Type") + col.prop(ccam, "panorama_type") if ccam.panorama_type == 'FISHEYE_EQUIDISTANT': col.prop(ccam, "fisheye_fov") elif ccam.panorama_type == 'FISHEYE_EQUISOLID': - row = layout.row() - row.prop(ccam, "fisheye_lens", text="Lens") - row.prop(ccam, "fisheye_fov") + col.prop(ccam, "fisheye_lens", text="Lens") + col.prop(ccam, "fisheye_fov") elif ccam.panorama_type == 'EQUIRECTANGULAR': - row = layout.row() - sub = row.column(align=True) - sub.prop(ccam, "latitude_min") - sub.prop(ccam, "latitude_max") - sub = row.column(align=True) - sub.prop(ccam, "longitude_min") - sub.prop(ccam, "longitude_max") - elif engine == 'BLENDER_RENDER': - row = col.row() + sub = col.column(align=True) + sub.prop(ccam, "latitude_min", text="Latitute Min") + sub.prop(ccam, "latitude_max", text="Max") + sub = col.column(align=True) + sub.prop(ccam, "longitude_min", text="Longiture Min") + sub.prop(ccam, "longitude_max", text="Max") + elif engine in {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'}: if cam.lens_unit == 'MILLIMETERS': - row.prop(cam, "lens") + col.prop(cam, "lens") elif cam.lens_unit == 'FOV': - row.prop(cam, "angle") - row.prop(cam, "lens_unit", text="") + col.prop(cam, "angle") + col.prop(cam, "lens_unit") - split = layout.split() + col = layout.column() + col.separator() - col = split.column(align=True) - col.label(text="Shift:") - col.prop(cam, "shift_x", text="X") - col.prop(cam, "shift_y", text="Y") + sub = col.column(align=True) + sub.prop(cam, "shift_x", text="Shift X") + sub.prop(cam, "shift_y", text="Y") - col = split.column(align=True) - col.label(text="Clipping:") - col.prop(cam, "clip_start", text="Start") - col.prop(cam, "clip_end", text="End") + col.separator() + sub = col.column(align=True) + sub.prop(cam, "clip_start", text="Clip Start") + sub.prop(cam, "clip_end", text="End") class DATA_PT_camera_stereoscopy(CameraButtonsPanel, Panel): bl_label = "Stereoscopy" - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'} @classmethod def poll(cls, context): @@ -147,6 +145,8 @@ class DATA_PT_camera_stereoscopy(CameraButtonsPanel, Panel): def draw(self, context): layout = self.layout + layout.use_property_split = True + render = context.scene.render st = context.camera.stereo cam = context.camera @@ -154,9 +154,9 @@ class DATA_PT_camera_stereoscopy(CameraButtonsPanel, Panel): is_spherical_stereo = cam.type != 'ORTHO' and render.use_spherical_stereo use_spherical_stereo = is_spherical_stereo and st.use_spherical_stereo - col = layout.column() - col.row().prop(st, "convergence_mode", expand=True) + layout.prop(st, "convergence_mode") + col = layout.column() sub = col.column() sub.active = st.convergence_mode != 'PARALLEL' sub.prop(st, "convergence_distance") @@ -165,25 +165,25 @@ class DATA_PT_camera_stereoscopy(CameraButtonsPanel, Panel): if is_spherical_stereo: col.separator() - row = col.row() - row.prop(st, "use_spherical_stereo") - sub = row.row() + col.prop(st, "use_spherical_stereo") + sub = col.column() sub.active = st.use_spherical_stereo sub.prop(st, "use_pole_merge") - row = col.row(align=True) - row.active = st.use_pole_merge - row.prop(st, "pole_merge_angle_from") - row.prop(st, "pole_merge_angle_to") - col.label(text="Pivot:") - row = col.row() - row.active = not use_spherical_stereo - row.prop(st, "pivot", expand=True) + sub = col.column(align=True) + sub.active = st.use_pole_merge + sub.prop(st, "pole_merge_angle_from", text="Pole Merge Angle Start") + sub.prop(st, "pole_merge_angle_to", text="End") + + col = layout.column() + col.active = not use_spherical_stereo + col.separator() + col.prop(st, "pivot") class DATA_PT_camera(CameraButtonsPanel, Panel): bl_label = "Camera" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'} def draw(self, context): layout = self.layout @@ -196,75 +196,181 @@ class DATA_PT_camera(CameraButtonsPanel, Panel): row.operator("camera.preset_add", text="", icon='ZOOMIN') row.operator("camera.preset_add", text="", icon='ZOOMOUT').remove_active = True - layout.label(text="Sensor:") + layout.use_property_split = True - split = layout.split() + col = layout.column() + col.prop(cam, "sensor_fit") - col = split.column(align=True) if cam.sensor_fit == 'AUTO': - col.prop(cam, "sensor_width", text="Size") + col.prop(cam, "sensor_width") else: sub = col.column(align=True) sub.active = cam.sensor_fit == 'HORIZONTAL' sub.prop(cam, "sensor_width", text="Width") + sub = col.column(align=True) sub.active = cam.sensor_fit == 'VERTICAL' sub.prop(cam, "sensor_height", text="Height") - col = split.column(align=True) - col.prop(cam, "sensor_fit", text="") - class DATA_PT_camera_dof(CameraButtonsPanel, Panel): bl_label = "Depth of Field" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} + bl_options = {'DEFAULT_CLOSED'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'} def draw(self, context): layout = self.layout + layout.use_property_split = True cam = context.camera dof_options = cam.gpu_dof - split = layout.split() - - col = split.column() - col.label(text="Focus:") - col.prop(cam, "dof_object", text="") + col = layout.column() + col.prop(cam, "dof_object", text="Focus on Object") sub = col.column() sub.active = (cam.dof_object is None) - sub.prop(cam, "dof_distance", text="Distance") + sub.prop(cam, "dof_distance", text="Focus Distance") - 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.separator() + + if context.engine == 'BLENDER_EEVEE': + col = layout.column() + col.label("Aperture") + engine = context.engine + col.prop(dof_options, "fstop") col.prop(dof_options, "blades") + col.prop(dof_options, "rotation") + col.prop(dof_options, "ratio") + else: + hq_support = dof_options.is_hq_supported + col = layout.column() + col.label("Viewport") + sub = col.column() + sub.active = hq_support + sub.prop(dof_options, "use_high_quality") + col.prop(dof_options, "fstop") + if dof_options.use_high_quality and hq_support: + col.prop(dof_options, "blades") + + +class DATA_PT_camera_background_image(CameraButtonsPanel, Panel): + bl_label = "Background Images" + bl_options = {'DEFAULT_CLOSED'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'} + + def draw_header(self, context): + cam = context.camera + + self.layout.prop(cam, "show_background_images", text="") + + def draw(self, context): + layout = self.layout + + cam = context.camera + use_multiview = context.scene.render.use_multiview + + col = layout.column() + col.operator("view3d.background_image_add", text="Add Image") + + for i, bg in enumerate(cam.background_images): + layout.active = cam.show_background_images + box = layout.box() + row = box.row(align=True) + row.prop(bg, "show_expanded", text="", emboss=False) + if bg.source == 'IMAGE' and bg.image: + row.prop(bg.image, "name", text="", emboss=False) + elif bg.source == 'MOVIE_CLIP' and bg.clip: + row.prop(bg.clip, "name", text="", emboss=False) + else: + row.label(text="Not Set") + + if bg.show_background_image: + row.prop(bg, "show_background_image", text="", emboss=False, icon='RESTRICT_VIEW_OFF') + else: + row.prop(bg, "show_background_image", text="", emboss=False, icon='RESTRICT_VIEW_ON') + + row.operator("view3d.background_image_remove", text="", emboss=False, icon='X').index = i + + if bg.show_expanded: + row = box.row() + row.prop(bg, "source", expand=True) + + has_bg = False + if bg.source == 'IMAGE': + row = box.row() + row.template_ID(bg, "image", open="image.open") + if bg.image is not None: + box.template_image(bg, "image", bg.image_user, compact=True) + has_bg = True + + if use_multiview and bg.view_axis in {'CAMERA', 'ALL'}: + box.prop(bg.image, "use_multiview") + + column = box.column() + column.active = bg.image.use_multiview + + column.label(text="Views Format:") + column.row().prop(bg.image, "views_format", expand=True) + + sub = column.box() + sub.active = bg.image.views_format == 'STEREO_3D' + sub.template_image_stereo_3d(bg.image.stereo_3d_format) + + elif bg.source == 'MOVIE_CLIP': + box.prop(bg, "use_camera_clip") + + column = box.column() + column.active = not bg.use_camera_clip + column.template_ID(bg, "clip", open="clip.open") + + if bg.clip: + column.template_movieclip(bg, "clip", compact=True) + + if bg.use_camera_clip or bg.clip: + has_bg = True + + column = box.column() + column.active = has_bg + column.prop(bg.clip_user, "proxy_render_size", text="") + column.prop(bg.clip_user, "use_render_undistorted") + + if has_bg: + col = box.column() + col.prop(bg, "alpha", slider=True) + col.row().prop(bg, "draw_depth", expand=True) + + col.row().prop(bg, "frame_method", expand=True) + + box = col.box() + row = box.row() + row.prop(bg, "offset") + + row = box.row() + row.prop(bg, "use_flip_x") + row.prop(bg, "use_flip_y") + + row = box.row() + row.prop(bg, "rotation") + row.prop(bg, "scale") class DATA_PT_camera_display(CameraButtonsPanel, Panel): bl_label = "Display" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} + bl_options = {'DEFAULT_CLOSED'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'} def draw(self, context): layout = self.layout + layout.use_property_split = True cam = context.camera split = layout.split() + split.label() + split.prop_menu_enum(cam, "show_guide") - col = split.column() - col.prop(cam, "show_limits", text="Limits") - col.prop(cam, "show_mist", text="Mist") - - col.prop(cam, "show_sensor", text="Sensor") - col.prop(cam, "show_name", text="Name") + col = layout.column(align=True) - col = split.column() - col.prop_menu_enum(cam, "show_guide") col.separator() col.prop(cam, "draw_size", text="Size") col.separator() @@ -273,11 +379,18 @@ class DATA_PT_camera_display(CameraButtonsPanel, Panel): sub.active = cam.show_passepartout sub.prop(cam, "passepartout_alpha", text="Alpha", slider=True) + col.separator() + + col.prop(cam, "show_limits", text="Limits") + col.prop(cam, "show_mist", text="Mist") + col.prop(cam, "show_sensor", text="Sensor") + col.prop(cam, "show_name", text="Name") + class DATA_PT_camera_safe_areas(CameraButtonsPanel, Panel): bl_label = "Safe Areas" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'} def draw_header(self, context): cam = context.camera @@ -293,7 +406,7 @@ class DATA_PT_camera_safe_areas(CameraButtonsPanel, Panel): class DATA_PT_custom_props_camera(CameraButtonsPanel, PropertyPanel, Panel): - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'} _context_path = "object.data" _property_type = bpy.types.Camera @@ -302,27 +415,30 @@ def draw_display_safe_settings(layout, safe_data, settings): show_safe_areas = settings.show_safe_areas show_safe_center = settings.show_safe_center - split = layout.split() + layout.use_property_split = True - col = split.column() - row = col.row(align=True) + row = layout.row(align=True) row.menu("SAFE_AREAS_MT_presets", text=bpy.types.SAFE_AREAS_MT_presets.bl_label) row.operator("safe_areas.preset_add", text="", icon='ZOOMIN') row.operator("safe_areas.preset_add", text="", icon='ZOOMOUT').remove_active = True - col = split.column() - col.prop(settings, "show_safe_center", text="Center-Cut Safe Areas") + layout.separator() - split = layout.split() - col = split.column() + col = layout.column() col.active = show_safe_areas - col.prop(safe_data, "title", slider=True) - col.prop(safe_data, "action", slider=True) - col = split.column() - col.active = show_safe_areas and show_safe_center - col.prop(safe_data, "title_center", slider=True) - col.prop(safe_data, "action_center", slider=True) + sub = col.column() + sub.prop(safe_data, "title", slider=True) + sub.prop(safe_data, "action", slider=True) + + col.separator() + + col.prop(settings, "show_safe_center", text="Center-Cut Safe Areas") + + sub = col.column() + sub.active = show_safe_areas and show_safe_center + sub.prop(safe_data, "title_center", slider=True) + sub.prop(safe_data, "action_center", slider=True) classes = ( @@ -335,6 +451,7 @@ classes = ( DATA_PT_camera_dof, DATA_PT_camera_display, DATA_PT_camera_safe_areas, + DATA_PT_camera_background_image, DATA_PT_custom_props_camera, ) diff --git a/release/scripts/startup/bl_ui/properties_data_curve.py b/release/scripts/startup/bl_ui/properties_data_curve.py index 3a3ad31a8ef..79a18d743a1 100644 --- a/release/scripts/startup/bl_ui/properties_data_curve.py +++ b/release/scripts/startup/bl_ui/properties_data_curve.py @@ -93,63 +93,63 @@ class DATA_PT_shape_curve(CurveButtonsPanel, Panel): row = layout.row() row.prop(curve, "dimensions", expand=True) - split = layout.split() + layout.use_property_split = True + + col = layout.column() + sub = col.column(align=True) + sub.prop(curve, "resolution_u", text="Resolution Preview U") + if is_surf: + sub.prop(curve, "resolution_v", text="V") - col = split.column() - col.label(text="Resolution:") sub = col.column(align=True) - sub.prop(curve, "resolution_u", text="Preview U") sub.prop(curve, "render_resolution_u", text="Render U") + if is_surf: + sub.prop(curve, "render_resolution_v", text="V") + col.separator() + if is_curve: - col.label(text="Twisting:") - col.prop(curve, "twist_mode", text="") + col.prop(curve, "twist_mode") col.prop(curve, "twist_smooth", text="Smooth") elif is_text: - col.label(text="Display:") col.prop(curve, "use_fast_edit", text="Fast Editing") - col = split.column() - - if is_surf: - sub = col.column() - sub.label(text="") - sub = col.column(align=True) - sub.prop(curve, "resolution_v", text="Preview V") - sub.prop(curve, "render_resolution_v", text="Render V") - if is_curve or is_text: - col.label(text="Fill:") + col = layout.column() + col.separator() + sub = col.column() sub.active = (curve.dimensions == '2D' or (curve.bevel_object is None and curve.dimensions == '3D')) - sub.prop(curve, "fill_mode", text="") + sub.prop(curve, "fill_mode") col.prop(curve, "use_fill_deform") if is_curve: - col.label(text="Path/Curve-Deform:") + col = layout.column() + col.separator() + sub = col.column() - subsub = sub.row() - subsub.prop(curve, "use_radius") - subsub.prop(curve, "use_stretch") + sub.prop(curve, "use_radius") + sub.prop(curve, "use_stretch") sub.prop(curve, "use_deform_bounds") class DATA_PT_curve_texture_space(CurveButtonsPanel, Panel): bl_label = "Texture Space" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'} def draw(self, context): layout = self.layout + layout.use_property_split = True curve = context.curve - row = layout.row() - row.prop(curve, "use_auto_texspace") - row.prop(curve, "use_uv_as_generated") + col = layout.column() + col.prop(curve, "use_uv_as_generated") + col.prop(curve, "use_auto_texspace") - row = layout.row() - row.column().prop(curve, "texspace_location", text="Location") - row.column().prop(curve, "texspace_size", text="Size") + col = layout.column() + col.prop(curve, "texspace_location") + col.prop(curve, "texspace_size") layout.operator("curve.match_texture_space") @@ -163,49 +163,54 @@ class DATA_PT_geometry_curve(CurveButtonsPanelCurve, Panel): def draw(self, context): layout = self.layout + layout.use_property_split = True curve = context.curve - split = layout.split() - - col = split.column() - col.label(text="Modification:") + col = layout.column() col.prop(curve, "offset") - col.prop(curve, "extrude") - col.label(text="Taper Object:") - col.prop(curve, "taper_object", text="") - col = split.column() - col.label(text="Bevel:") - col.prop(curve, "bevel_depth", text="Depth") - col.prop(curve, "bevel_resolution", text="Resolution") - col.label(text="Bevel Object:") - col.prop(curve, "bevel_object", text="") + sub = col.column() + sub.active = (curve.bevel_object is None) + sub.prop(curve, "extrude") + + col.prop(curve, "taper_object") + + sub = col.column() + sub.active = curve.taper_object is not None + sub.prop(curve, "use_map_taper") + + col.separator() + + layout.label(text="Bevel") + + col = layout.column() + sub = col.column() + sub.active = (curve.bevel_object is None) + sub.prop(curve, "bevel_depth", text="Depth") + sub.prop(curve, "bevel_resolution", text="Resolution") + + col.prop(curve, "bevel_object", text="Object") + + sub = col.column() + sub.active = curve.bevel_object is not None + sub.prop(curve, "use_fill_caps") if type(curve) is not TextCurve: - col = layout.column(align=True) - row = col.row() - row.label(text="Bevel Factor:") col = layout.column() col.active = ( - (curve.bevel_depth > 0.0) or - (curve.extrude > 0.0) or - (curve.bevel_object is not None)) - row = col.row(align=True) - row.prop(curve, "bevel_factor_mapping_start", text="") - row.prop(curve, "bevel_factor_start", text="Start") - row = col.row(align=True) - row.prop(curve, "bevel_factor_mapping_end", text="") - row.prop(curve, "bevel_factor_end", text="End") + (curve.bevel_depth > 0.0) or + (curve.extrude > 0.0) or + (curve.bevel_object is not None) + ) + sub = col.column(align=True) + sub.prop(curve, "bevel_factor_start", text="Bevel Start") + sub.prop(curve, "bevel_factor_end", text="End") - row = layout.row() - sub = row.row() - sub.active = curve.taper_object is not None - sub.prop(curve, "use_map_taper") - sub = row.row() - sub.active = curve.bevel_object is not None - sub.prop(curve, "use_fill_caps") + sub = col.column(align=True) + sub.prop(curve, "bevel_factor_mapping_start", text="Bevel Mapping Start") + sub.prop(curve, "bevel_factor_mapping_end", text="End") class DATA_PT_pathanim(CurveButtonsPanelCurve, Panel): @@ -218,6 +223,7 @@ class DATA_PT_pathanim(CurveButtonsPanelCurve, Panel): def draw(self, context): layout = self.layout + layout.use_property_split = True curve = context.curve @@ -228,8 +234,9 @@ class DATA_PT_pathanim(CurveButtonsPanelCurve, Panel): col.prop(curve, "eval_time") # these are for paths only - row = layout.row() - row.prop(curve, "use_path_follow") + col.separator() + + col.prop(curve, "use_path_follow") class DATA_PT_active_spline(CurveButtonsPanelActive, Panel): @@ -237,65 +244,64 @@ class DATA_PT_active_spline(CurveButtonsPanelActive, Panel): def draw(self, context): layout = self.layout + layout.use_property_split = True curve = context.curve act_spline = curve.splines.active is_surf = type(curve) is SurfaceCurve is_poly = (act_spline.type == 'POLY') - split = layout.split() + col = layout.column() if is_poly: # These settings are below but its easier to have # polys set aside since they use so few settings - row = layout.row() - row.label(text="Cyclic:") - row.prop(act_spline, "use_cyclic_u", text="U") - layout.prop(act_spline, "use_smooth") + col.prop(act_spline, "use_cyclic_u") + col.prop(act_spline, "use_smooth") else: - col = split.column() - col.label(text="Cyclic:") - if act_spline.type == 'NURBS': - col.label(text="Bezier:") - col.label(text="Endpoint:") - col.label(text="Order:") - col.label(text="Resolution:") - - col = split.column() - col.prop(act_spline, "use_cyclic_u", text="U") + sub = col.column(align=True) + sub.prop(act_spline, "use_cyclic_u") + if is_surf: + sub.prop(act_spline, "use_cyclic_v", text="V") if act_spline.type == 'NURBS': - sub = col.column() + sub = col.column(align=True) # sub.active = (not act_spline.use_cyclic_u) - sub.prop(act_spline, "use_bezier_u", text="U") - sub.prop(act_spline, "use_endpoint_u", text="U") + sub.prop(act_spline, "use_bezier_u", text="Bezier U") - sub = col.column() - sub.prop(act_spline, "order_u", text="U") - col.prop(act_spline, "resolution_u", text="U") + if is_surf: + subsub = sub.column() + subsub.active = (not act_spline.use_cyclic_v) + subsub.prop(act_spline, "use_bezier_v", text="V") - if is_surf: - col = split.column() - col.prop(act_spline, "use_cyclic_v", text="V") + sub = col.column(align=True) + sub.prop(act_spline, "use_endpoint_u", text="Endpoint U") - # its a surface, assume its a nurbs - sub = col.column() - sub.active = (not act_spline.use_cyclic_v) - sub.prop(act_spline, "use_bezier_v", text="V") - sub.prop(act_spline, "use_endpoint_v", text="V") - sub = col.column() - sub.prop(act_spline, "order_v", text="V") + if is_surf: + subsub = sub.column() + subsub.active = (not act_spline.use_cyclic_v) + subsub.prop(act_spline, "use_endpoint_v", text="V") + + sub = col.column(align=True) + sub.prop(act_spline, "order_u", text="Order U") + + if is_surf: + sub.prop(act_spline, "order_v", text="V") + + sub = col.column(align=True) + sub.prop(act_spline, "resolution_u", text="Resolution U") + if is_surf: sub.prop(act_spline, "resolution_v", text="V") if act_spline.type == 'BEZIER': - col = layout.column() - col.label(text="Interpolation:") + + col.separator() sub = col.column() sub.active = (curve.dimensions == '3D') - sub.prop(act_spline, "tilt_interpolation", text="Tilt") + sub.prop(act_spline, "tilt_interpolation", text="Interpolation Tilt") col.prop(act_spline, "radius_interpolation", text="Radius") @@ -324,42 +330,36 @@ 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.separator() + + row = layout.row(align=True) + row.prop(char, "use_bold", toggle=True) + row.prop(char, "use_italic", toggle=True) + row.prop(char, "use_underline", toggle=True) + row.prop(char, "use_small_caps", toggle=True) + + layout.use_property_split = True # layout.prop(text, "font") - split = layout.split() + col = layout.column() + + col.separator() - col = split.column() col.prop(text, "size", text="Size") - col = split.column() col.prop(text, "shear") - split = layout.split() - - col = split.column() - col.label(text="Object Font:") - col.prop(text, "family", text="") + col.separator() - col = split.column() - col.label(text="Text on Curve:") - col.prop(text, "follow_curve", text="") + col.prop(text, "family") + col.prop(text, "follow_curve") - split = layout.split() + col.separator() - col = split.column() sub = col.column(align=True) - sub.label(text="Underline:") - sub.prop(text, "underline_position", text="Position") - sub.prop(text, "underline_height", text="Thickness") + sub.prop(text, "underline_position", text="Underline Position") + sub.prop(text, "underline_height", text="Underline Thickness") - col = split.column() - col.label(text="Character:") - col.prop(char, "use_bold") - col.prop(char, "use_italic") - col.prop(char, "use_underline") - - row = layout.row() - row.prop(text, "small_caps_scale", text="Small Caps") - row.prop(char, "use_small_caps") + col.prop(text, "small_caps_scale", text="Small Caps Scale") class DATA_PT_paragraph(CurveButtonsPanelText, Panel): @@ -370,23 +370,21 @@ class DATA_PT_paragraph(CurveButtonsPanelText, Panel): text = context.curve - layout.label(text="Horizontal Alignment:") + layout.label(text="Alignment") layout.row().prop(text, "align_x", expand=True) - - layout.label(text="Vertical Alignment:") layout.row().prop(text, "align_y", expand=True) - split = layout.split() + layout.use_property_split = True - col = split.column(align=True) - col.label(text="Spacing:") - col.prop(text, "space_character", text="Letter") - col.prop(text, "space_word", text="Word") - col.prop(text, "space_line", text="Line") + col = layout.column(align=True) + col.prop(text, "space_character", text="Character Spacing") + col.prop(text, "space_word", text="Word Spacing") + col.prop(text, "space_line", text="Line Spacing") - col = split.column(align=True) - col.label(text="Offset:") - col.prop(text, "offset_x", text="X") + layout.separator() + + col = layout.column(align=True) + col.prop(text, "offset_x", text="Offset X") col.prop(text, "offset_y", text="Y") @@ -398,10 +396,7 @@ class DATA_PT_text_boxes(CurveButtonsPanelText, Panel): text = context.curve - split = layout.split() - col = split.column() - col.operator("font.textbox_add", icon='ZOOMIN') - col = split.column() + layout.operator("font.textbox_add", icon='ZOOMIN') for i, box in enumerate(text.text_boxes): @@ -409,25 +404,22 @@ class DATA_PT_text_boxes(CurveButtonsPanelText, Panel): row = boxy.row() - split = row.split() - - col = split.column(align=True) + col = row.column() + col.use_property_split = True - col.label(text="Dimensions:") - col.prop(box, "width", text="Width") - col.prop(box, "height", text="Height") - - col = split.column(align=True) + sub = col.column(align=True) + sub.prop(box, "width", text="Size X") + sub.prop(box, "height", text="Y") - col.label(text="Offset:") - col.prop(box, "x", text="X") - col.prop(box, "y", text="Y") + sub = col.column(align=True) + sub.prop(box, "x", text="Offset X") + sub.prop(box, "y", text="Y") row.operator("font.textbox_remove", text="", icon='X', emboss=False).index = i class DATA_PT_custom_props_curve(CurveButtonsPanel, PropertyPanel, Panel): - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'} _context_path = "object.data" _property_type = bpy.types.Curve diff --git a/release/scripts/startup/bl_ui/properties_data_empty.py b/release/scripts/startup/bl_ui/properties_data_empty.py index c66ff87ecbd..1da3d9621aa 100644 --- a/release/scripts/startup/bl_ui/properties_data_empty.py +++ b/release/scripts/startup/bl_ui/properties_data_empty.py @@ -36,10 +36,11 @@ class DATA_PT_empty(DataButtonsPanel, Panel): def draw(self, context): layout = self.layout + layout.use_property_split = True ob = context.object - layout.prop(ob, "empty_draw_type", text="Display") + layout.prop(ob, "empty_draw_type", text="Display As") if ob.empty_draw_type == 'IMAGE': layout.template_ID(ob, "data", open="image.open", unlink="object.unlink_data") @@ -49,9 +50,11 @@ class DATA_PT_empty(DataButtonsPanel, Panel): row = layout.row(align=True) layout.prop(ob, "color", text="Transparency", index=3, slider=True) - row = layout.row(align=True) - row.prop(ob, "empty_image_offset", text="Offset X", index=0) - row.prop(ob, "empty_image_offset", text="Offset Y", index=1) + col = layout.col(align=True) + col.prop(ob, "empty_image_offset", text="Offset X", index=0) + col.prop(ob, "empty_image_offset", text="Y", index=1) + + layout.separator() layout.prop(ob, "empty_draw_size", text="Size") diff --git a/release/scripts/startup/bl_ui/properties_data_lamp.py b/release/scripts/startup/bl_ui/properties_data_lamp.py index f9394139b42..d47160de8a0 100644 --- a/release/scripts/startup/bl_ui/properties_data_lamp.py +++ b/release/scripts/startup/bl_ui/properties_data_lamp.py @@ -26,7 +26,7 @@ class LAMP_MT_sunsky_presets(Menu): bl_label = "Sun & Sky Presets" preset_subdir = "sunsky" preset_operator = "script.execute_preset" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'} draw = Menu.draw_preset @@ -37,14 +37,14 @@ class DataButtonsPanel: @classmethod def poll(cls, context): - engine = context.scene.render.engine + engine = context.engine return context.lamp and (engine in cls.COMPAT_ENGINES) class DATA_PT_context_lamp(DataButtonsPanel, Panel): bl_label = "" bl_options = {'HIDE_HEADER'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'} def draw(self, context): layout = self.layout @@ -55,20 +55,15 @@ class DATA_PT_context_lamp(DataButtonsPanel, Panel): split = layout.split(percentage=0.65) - texture_count = len(lamp.texture_slots.keys()) - if ob: split.template_ID(ob, "data") elif lamp: split.template_ID(space, "pin_id") - if texture_count != 0: - split.label(text=str(texture_count), icon='TEXTURE') - class DATA_PT_preview(DataButtonsPanel, Panel): bl_label = "Preview" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'} def draw(self, context): self.layout.template_preview(context.lamp) @@ -76,7 +71,7 @@ class DATA_PT_preview(DataButtonsPanel, Panel): class DATA_PT_lamp(DataButtonsPanel, Panel): bl_label = "Lamp" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY'} def draw(self, context): layout = self.layout @@ -85,239 +80,139 @@ class DATA_PT_lamp(DataButtonsPanel, Panel): layout.row().prop(lamp, "type", expand=True) - split = layout.split() + layout.use_property_split = True - col = split.column() - sub = col.column() - sub.prop(lamp, "color", text="") - sub.prop(lamp, "energy") + col = col.column() + col.prop(lamp, "color") + col.prop(lamp, "energy") if lamp.type in {'POINT', 'SPOT'}: - sub.label(text="Falloff:") - sub.prop(lamp, "falloff_type", text="") - sub.prop(lamp, "distance") + + col = col.column() + col.label(text="Falloff") + col.prop(lamp, "falloff_type") + col.prop(lamp, "distance") + col.prop(lamp, "shadow_soft_size") if lamp.falloff_type == 'LINEAR_QUADRATIC_WEIGHTED': - col.label(text="Attenuation Factors:") sub = col.column(align=True) sub.prop(lamp, "linear_attenuation", slider=True, text="Linear") sub.prop(lamp, "quadratic_attenuation", slider=True, text="Quadratic") elif lamp.falloff_type == 'INVERSE_COEFFICIENTS': - col.label(text="Inverse Coefficients:") + col.label(text="Inverse Coefficients") sub = col.column(align=True) sub.prop(lamp, "constant_coefficient", text="Constant") sub.prop(lamp, "linear_coefficient", text="Linear") sub.prop(lamp, "quadratic_coefficient", text="Quadratic") - col.prop(lamp, "use_sphere") - if lamp.type == 'AREA': col.prop(lamp, "distance") - col.prop(lamp, "gamma") col = split.column() - col.prop(lamp, "use_negative") - col.prop(lamp, "use_own_layer", text="This Layer Only") - col.prop(lamp, "use_specular") - col.prop(lamp, "use_diffuse") + col.label() -class DATA_PT_sunsky(DataButtonsPanel, Panel): - bl_label = "Sky & Atmosphere" - COMPAT_ENGINES = {'BLENDER_RENDER'} - - @classmethod - def poll(cls, context): - lamp = context.lamp - engine = context.scene.render.engine - return (lamp and lamp.type == 'SUN') and (engine in cls.COMPAT_ENGINES) +class DATA_PT_EEVEE_lamp(DataButtonsPanel, Panel): + bl_label = "Lamp" + COMPAT_ENGINES = {'BLENDER_EEVEE'} def draw(self, context): layout = self.layout + lamp = context.lamp - lamp = context.lamp.sky - - row = layout.row(align=True) - row.prop(lamp, "use_sky") - row.menu("LAMP_MT_sunsky_presets", text=bpy.types.LAMP_MT_sunsky_presets.bl_label) - row.operator("lamp.sunsky_preset_add", text="", icon='ZOOMIN') - row.operator("lamp.sunsky_preset_add", text="", icon='ZOOMOUT').remove_active = True - - row = layout.row() - row.active = lamp.use_sky or lamp.use_atmosphere - row.prop(lamp, "atmosphere_turbidity", text="Turbidity") - - split = layout.split() - - col = split.column() - col.active = lamp.use_sky - col.label(text="Blending:") - sub = col.column() - sub.prop(lamp, "sky_blend_type", text="") - sub.prop(lamp, "sky_blend", text="Factor") - - col.label(text="Color Space:") - sub = col.column() - sub.row().prop(lamp, "sky_color_space", expand=True) - sub.prop(lamp, "sky_exposure", text="Exposure") - - col = split.column() - col.active = lamp.use_sky - col.label(text="Horizon:") - sub = col.column() - sub.prop(lamp, "horizon_brightness", text="Brightness") - sub.prop(lamp, "spread", text="Spread") + layout.row().prop(lamp, "type", expand=True) - col.label(text="Sun:") - sub = col.column() - sub.prop(lamp, "sun_brightness", text="Brightness") - sub.prop(lamp, "sun_size", text="Size") - sub.prop(lamp, "backscattered_light", slider=True, text="Back Light") + layout.use_property_split = True - layout.separator() + col = layout.column() + col.prop(lamp, "color") + col.prop(lamp, "energy") + col.prop(lamp, "specular_factor", text="Specular") - layout.prop(lamp, "use_atmosphere") + col.separator() - split = layout.split() + if lamp.type in {'POINT', 'SPOT', 'SUN'}: + col.prop(lamp, "shadow_soft_size", text="Radius") + elif lamp.type == 'AREA': + col.prop(lamp, "shape") - col = split.column() - col.active = lamp.use_atmosphere - col.label(text="Intensity:") - col.prop(lamp, "sun_intensity", text="Sun") - col.prop(lamp, "atmosphere_distance_factor", text="Distance") + sub = col.column(align=True) - col = split.column() - col.active = lamp.use_atmosphere - col.label(text="Scattering:") - sub = col.column(align=True) - sub.prop(lamp, "atmosphere_inscattering", slider=True, text="Inscattering") - sub.prop(lamp, "atmosphere_extinction", slider=True, text="Extinction") + if lamp.shape in {'SQUARE', 'DISK'}: + sub.prop(lamp, "size") + elif lamp.shape in {'RECTANGLE', 'ELLIPSE'}: + sub.prop(lamp, "size", text="Size X") + sub.prop(lamp, "size_y", text="Y") -class DATA_PT_shadow(DataButtonsPanel, Panel): +class DATA_PT_EEVEE_shadow(DataButtonsPanel, Panel): bl_label = "Shadow" - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_EEVEE'} @classmethod def poll(cls, context): lamp = context.lamp - engine = context.scene.render.engine + engine = context.engine return (lamp and lamp.type in {'POINT', 'SUN', 'SPOT', 'AREA'}) and (engine in cls.COMPAT_ENGINES) + def draw_header(self, context): + lamp = context.lamp + self.layout.prop(lamp, "use_shadow", text="") + def draw(self, context): layout = self.layout + layout.use_property_split = True lamp = context.lamp - layout.row().prop(lamp, "shadow_method", expand=True) - - if lamp.shadow_method == 'NOSHADOW' and lamp.type == 'AREA': - split = layout.split() + layout.active = lamp.use_shadow - col = split.column() - col.label(text="Form Factor Sampling:") - - sub = col.row(align=True) - - if lamp.shape == 'SQUARE': - sub.prop(lamp, "shadow_ray_samples_x", text="Samples") - elif lamp.shape == 'RECTANGLE': - sub.prop(lamp, "shadow_ray_samples_x", text="Samples X") - sub.prop(lamp, "shadow_ray_samples_y", text="Samples Y") - - if lamp.shadow_method != 'NOSHADOW': - split = layout.split() - - col = split.column() - col.prop(lamp, "shadow_color", text="") - - col = split.column() - col.prop(lamp, "use_shadow_layer", text="This Layer Only") - col.prop(lamp, "use_only_shadow") - - if lamp.shadow_method == 'RAY_SHADOW': - split = layout.split() - - col = split.column() - col.label(text="Sampling:") - - if lamp.type in {'POINT', 'SUN', 'SPOT'}: - sub = col.row() - - sub.prop(lamp, "shadow_ray_samples", text="Samples") - sub.prop(lamp, "shadow_soft_size", text="Soft Size") + col = layout.column() + sub = col.column(align=True) + sub.prop(lamp, "shadow_buffer_clip_start", text="Clip Start") + sub.prop(lamp, "shadow_buffer_clip_end", text="End") - elif lamp.type == 'AREA': - sub = col.row(align=True) + col.prop(lamp, "shadow_buffer_soft", text="Softness") - if lamp.shape == 'SQUARE': - sub.prop(lamp, "shadow_ray_samples_x", text="Samples") - elif lamp.shape == 'RECTANGLE': - sub.prop(lamp, "shadow_ray_samples_x", text="Samples X") - sub.prop(lamp, "shadow_ray_samples_y", text="Samples Y") + col.separator() - col.row().prop(lamp, "shadow_ray_sample_method", expand=True) + col.prop(lamp, "shadow_buffer_bias", text="Bias") + col.prop(lamp, "shadow_buffer_exp", text="Exponent") + col.prop(lamp, "shadow_buffer_bleed_bias", text="Bleed Bias") - if lamp.shadow_ray_sample_method == 'ADAPTIVE_QMC': - layout.prop(lamp, "shadow_adaptive_threshold", text="Threshold") + col.separator() - if lamp.type == 'AREA' and lamp.shadow_ray_sample_method == 'CONSTANT_JITTERED': - row = layout.row() - row.prop(lamp, "use_umbra") - row.prop(lamp, "use_dither") - row.prop(lamp, "use_jitter") + if lamp.type == 'SUN': + col.label("Cascaded Shadow Map") - elif lamp.shadow_method == 'BUFFER_SHADOW': - col = layout.column() - col.label(text="Buffer Type:") - col.row().prop(lamp, "shadow_buffer_type", expand=True) + col.prop(lamp, "shadow_cascade_count", text="Count") + col.prop(lamp, "shadow_cascade_fade", text="Fade") - if lamp.shadow_buffer_type in {'REGULAR', 'HALFWAY', 'DEEP'}: - split = layout.split() + col.prop(lamp, "shadow_cascade_max_distance", text="Max Distance") + col.prop(lamp, "shadow_cascade_exponent", text="Distribution") - col = split.column() - col.label(text="Filter Type:") - col.prop(lamp, "shadow_filter_type", text="") - sub = col.column(align=True) - sub.prop(lamp, "shadow_buffer_soft", text="Soft") - sub.prop(lamp, "shadow_buffer_bias", text="Bias") - - col = split.column() - col.label(text="Sample Buffers:") - col.prop(lamp, "shadow_sample_buffers", text="") - sub = col.column(align=True) - sub.prop(lamp, "shadow_buffer_size", text="Size") - sub.prop(lamp, "shadow_buffer_samples", text="Samples") - if lamp.shadow_buffer_type == 'DEEP': - col.prop(lamp, "compression_threshold") - - elif lamp.shadow_buffer_type == 'IRREGULAR': - layout.prop(lamp, "shadow_buffer_bias", text="Bias") + layout.separator() - split = layout.split() + layout.prop(lamp, "use_contact_shadow") - col = split.column() - col.prop(lamp, "use_auto_clip_start", text="Autoclip Start") - sub = col.column() - sub.active = not lamp.use_auto_clip_start - sub.prop(lamp, "shadow_buffer_clip_start", text="Clip Start") + col = layout.column() + col.active = lamp.use_contact_shadow - col = split.column() - col.prop(lamp, "use_auto_clip_end", text="Autoclip End") - sub = col.column() - sub.active = not lamp.use_auto_clip_end - sub.prop(lamp, "shadow_buffer_clip_end", text=" Clip End") + col.prop(lamp, "contact_shadow_distance", text="Distance") + col.prop(lamp, "contact_shadow_soft_size", text="Softness") + col.prop(lamp, "contact_shadow_bias", text="Bias") + col.prop(lamp, "contact_shadow_thickness", text="Thickness") class DATA_PT_area(DataButtonsPanel, Panel): bl_label = "Area Shape" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY'} @classmethod def poll(cls, context): lamp = context.lamp - engine = context.scene.render.engine + engine = context.engine return (lamp and lamp.type == 'AREA') and (engine in cls.COMPAT_ENGINES) def draw(self, context): @@ -329,21 +224,21 @@ class DATA_PT_area(DataButtonsPanel, Panel): col.row().prop(lamp, "shape", expand=True) sub = col.row(align=True) - if lamp.shape == 'SQUARE': + if lamp.shape in {'SQUARE', 'DISK'}: sub.prop(lamp, "size") - elif lamp.shape == 'RECTANGLE': + elif lamp.shape in {'RECTANGLE', 'ELLIPSE'}: sub.prop(lamp, "size", text="Size X") sub.prop(lamp, "size_y", text="Size Y") class DATA_PT_spot(DataButtonsPanel, Panel): bl_label = "Spot Shape" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY'} @classmethod def poll(cls, context): lamp = context.lamp - engine = context.scene.render.engine + engine = context.engine return (lamp and lamp.type == 'SPOT') and (engine in cls.COMPAT_ENGINES) def draw(self, context): @@ -371,15 +266,39 @@ class DATA_PT_spot(DataButtonsPanel, Panel): sub.prop(lamp, "halo_step", text="Step") +class DATA_PT_spot(DataButtonsPanel, Panel): + bl_label = "Spot Shape" + COMPAT_ENGINES = {'BLENDER_EEVEE'} + + @classmethod + def poll(cls, context): + lamp = context.lamp + engine = context.engine + return (lamp and lamp.type == 'SPOT') and (engine in cls.COMPAT_ENGINES) + + def draw(self, context): + layout = self.layout + layout.use_property_split = True + + lamp = context.lamp + + col = layout.column() + + col.prop(lamp, "spot_size", text="Size") + col.prop(lamp, "spot_blend", text="Blend", slider=True) + + col.prop(lamp, "show_cone") + + class DATA_PT_falloff_curve(DataButtonsPanel, Panel): bl_label = "Falloff Curve" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'} @classmethod def poll(cls, context): lamp = context.lamp - engine = context.scene.render.engine + engine = context.engine return (lamp and lamp.type in {'POINT', 'SPOT'} and lamp.falloff_type == 'CUSTOM_CURVE') and (engine in cls.COMPAT_ENGINES) @@ -390,7 +309,7 @@ class DATA_PT_falloff_curve(DataButtonsPanel, Panel): class DATA_PT_custom_props_lamp(DataButtonsPanel, PropertyPanel, Panel): - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'} _context_path = "object.data" _property_type = bpy.types.Lamp @@ -400,8 +319,8 @@ classes = ( DATA_PT_context_lamp, DATA_PT_preview, DATA_PT_lamp, - DATA_PT_sunsky, - DATA_PT_shadow, + DATA_PT_EEVEE_lamp, + DATA_PT_EEVEE_shadow, DATA_PT_area, DATA_PT_spot, DATA_PT_falloff_curve, diff --git a/release/scripts/startup/bl_ui/properties_data_lattice.py b/release/scripts/startup/bl_ui/properties_data_lattice.py index 4b3fd48c195..b584e433cb9 100644 --- a/release/scripts/startup/bl_ui/properties_data_lattice.py +++ b/release/scripts/startup/bl_ui/properties_data_lattice.py @@ -57,28 +57,35 @@ class DATA_PT_lattice(DataButtonsPanel, Panel): def draw(self, context): layout = self.layout + layout.use_property_split = True lat = context.lattice - row = layout.row() - row.prop(lat, "points_u") - row.prop(lat, "interpolation_type_u", text="") + col = layout.column() - row = layout.row() - row.prop(lat, "points_v") - row.prop(lat, "interpolation_type_v", text="") + sub = col.column(align=True) + sub.prop(lat, "points_u", text="Resolution U") + sub.prop(lat, "points_v", text="V") + sub.prop(lat, "points_w", text="W") - row = layout.row() - row.prop(lat, "points_w") - row.prop(lat, "interpolation_type_w", text="") + col.separator() - row = layout.row() - row.prop(lat, "use_outside") - row.prop_search(lat, "vertex_group", context.object, "vertex_groups", text="") + sub = col.column(align=True) + sub.prop(lat, "interpolation_type_u", text="Interpolation U") + sub.prop(lat, "interpolation_type_v", text="V") + sub.prop(lat, "interpolation_type_w", text="W") + + col.separator() + + col.prop(lat, "use_outside") + + col.separator() + + col.prop_search(lat, "vertex_group", context.object, "vertex_groups") class DATA_PT_custom_props_lattice(DataButtonsPanel, PropertyPanel, Panel): - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'} _context_path = "object.data" _property_type = bpy.types.Lattice diff --git a/release/scripts/startup/bl_ui/properties_data_lightprobe.py b/release/scripts/startup/bl_ui/properties_data_lightprobe.py new file mode 100644 index 00000000000..00c6c205530 --- /dev/null +++ b/release/scripts/startup/bl_ui/properties_data_lightprobe.py @@ -0,0 +1,185 @@ +# ##### BEGIN GPL LICENSE BLOCK ##### +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# ##### END GPL LICENSE BLOCK ##### + +# <pep8 compliant> +import bpy +from bpy.types import Panel + + +class DataButtonsPanel: + bl_space_type = 'PROPERTIES' + bl_region_type = 'WINDOW' + bl_context = "data" + + @classmethod + def poll(cls, context): + engine = context.engine + return context.lightprobe and (engine in cls.COMPAT_ENGINES) + + +class DATA_PT_context_lightprobe(DataButtonsPanel, Panel): + bl_label = "" + bl_options = {'HIDE_HEADER'} + COMPAT_ENGINES = {'BLENDER_CLAY', 'BLENDER_EEVEE'} + + def draw(self, context): + layout = self.layout + + ob = context.object + probe = context.lightprobe + space = context.space_data + + if ob: + layout.template_ID(ob, "data") + elif probe: + layout.template_ID(space, "pin_id") + + +class DATA_PT_lightprobe(DataButtonsPanel, Panel): + bl_label = "Probe" + COMPAT_ENGINES = {'BLENDER_CLAY', 'BLENDER_EEVEE'} + + def draw(self, context): + layout = self.layout + layout.use_property_split = True + + ob = context.object + probe = context.lightprobe + +# layout.prop(probe, "type") + + if probe.type == 'GRID': + col = layout.column() + col.prop(probe, "influence_distance", "Distance") + col.prop(probe, "falloff") + col.prop(probe, "intensity") + + col.separator() + + col.prop(probe, "grid_resolution_x", text="Resolution X") + col.prop(probe, "grid_resolution_y", text="Y") + col.prop(probe, "grid_resolution_z", text="Z") + + elif probe.type == 'PLANAR': + col = layout.column() + col.prop(probe, "influence_distance", "Distance") + col.prop(probe, "falloff") + else: + col = layout.column() + col.prop(probe, "influence_type") + + if probe.influence_type == 'ELIPSOID': + col.prop(probe, "influence_distance", "Radius") + else: + col.prop(probe, "influence_distance", "Size") + + col.prop(probe, "falloff") + col.prop(probe, "intensity") + + col = layout.column() + sub = col.column() + sub.prop(probe, "clip_start", text="Clipping Start") + + if probe.type != "PLANAR": + sub.prop(probe, "clip_end", text="End") + + if probe.type == 'GRID': + col.separator() + col.label("Visibility") + col.prop(probe, "visibility_buffer_bias", "Bias") + col.prop(probe, "visibility_bleed_bias", "Bleed Bias") + col.prop(probe, "visibility_blur", "Blur") + + col.separator() + + row = col.row(align=True) + row.prop(probe, "visibility_collection") + row.prop(probe, "invert_visibility_collection", text="", icon='ARROW_LEFTRIGHT') + + +class DATA_PT_lightprobe_parallax(DataButtonsPanel, Panel): + bl_label = "Custom Parallax" + COMPAT_ENGINES = {'BLENDER_CLAY', 'BLENDER_EEVEE'} + + @classmethod + def poll(cls, context): + engine = context.engine + return context.lightprobe and context.lightprobe.type == 'CUBEMAP' and (engine in cls.COMPAT_ENGINES) + + def draw_header(self, context): + probe = context.lightprobe + self.layout.prop(probe, "use_custom_parallax", text="") + + def draw(self, context): + layout = self.layout + layout.use_property_split = True + + probe = context.lightprobe + + col = layout.column() + col.active = probe.use_custom_parallax + + col.prop(probe, "parallax_type") + + if probe.parallax_type == 'ELIPSOID': + col.prop(probe, "parallax_distance", "Radius") + else: + col.prop(probe, "parallax_distance", "Size") + + +class DATA_PT_lightprobe_display(DataButtonsPanel, Panel): + bl_label = "Display" + COMPAT_ENGINES = {'BLENDER_CLAY', 'BLENDER_EEVEE'} + + def draw(self, context): + layout = self.layout + layout.use_property_split = True + + ob = context.object + probe = context.lightprobe + + col = layout.column() + + if probe.type != "PLANAR": + col.prop(probe, "data_draw_size", text="Size") + else: + col.prop(ob, "empty_draw_size", text="Arrow Size") + + col.prop(probe, "show_data") + + if probe.type in {'GRID', 'CUBEMAP'}: + col.prop(probe, "show_influence") + col.prop(probe, "show_clip") + + if probe.type == 'CUBEMAP': + sub = col.column() + sub.active = probe.use_custom_parallax + sub.prop(probe, "show_parallax") + + +classes = ( + DATA_PT_context_lightprobe, + DATA_PT_lightprobe, + DATA_PT_lightprobe_parallax, + DATA_PT_lightprobe_display, +) + +if __name__ == "__main__": # only for live edit. + from bpy.utils import register_class + for cls in classes: + register_class(cls) diff --git a/release/scripts/startup/bl_ui/properties_data_mesh.py b/release/scripts/startup/bl_ui/properties_data_mesh.py index 1a091dac764..69ac7754ec4 100644 --- a/release/scripts/startup/bl_ui/properties_data_mesh.py +++ b/release/scripts/startup/bl_ui/properties_data_mesh.py @@ -24,7 +24,7 @@ from rna_prop_ui import PropertyPanel class MESH_MT_vertex_group_specials(Menu): bl_label = "Vertex Group Specials" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'} def draw(self, context): layout = self.layout @@ -48,7 +48,7 @@ class MESH_MT_vertex_group_specials(Menu): class MESH_MT_shape_key_specials(Menu): bl_label = "Shape Key Specials" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'} def draw(self, context): layout = self.layout @@ -76,6 +76,17 @@ class MESH_UL_vgroups(UIList): layout.label(text="", icon_value=icon) +class MESH_UL_fmaps(UIList): + def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index): + # assert(isinstance(item, bpy.types.FaceMap)) + fmap = item + if self.layout_type in {'DEFAULT', 'COMPACT'}: + layout.prop(fmap, "name", text="", emboss=False, icon_value=icon) + elif self.layout_type in {'GRID'}: + layout.alignment = 'CENTER' + layout.label(text="", icon_value=icon) + + class MESH_UL_shape_keys(UIList): def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index): # assert(isinstance(item, bpy.types.ShapeKey)) @@ -119,14 +130,14 @@ class MeshButtonsPanel: @classmethod def poll(cls, context): - engine = context.scene.render.engine + engine = context.engine return context.mesh and (engine in cls.COMPAT_ENGINES) class DATA_PT_context_mesh(MeshButtonsPanel, Panel): bl_label = "" bl_options = {'HIDE_HEADER'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'} def draw(self, context): layout = self.layout @@ -143,31 +154,31 @@ class DATA_PT_context_mesh(MeshButtonsPanel, Panel): class DATA_PT_normals(MeshButtonsPanel, Panel): bl_label = "Normals" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'} def draw(self, context): layout = self.layout + layout.use_property_split = True mesh = context.mesh - split = layout.split() + col = layout.column() + col.prop(mesh, "show_double_sided") - col = split.column() col.prop(mesh, "use_auto_smooth") sub = col.column() sub.active = mesh.use_auto_smooth and not mesh.has_custom_normals sub.prop(mesh, "auto_smooth_angle", text="Angle") - split.prop(mesh, "show_double_sided") - class DATA_PT_texture_space(MeshButtonsPanel, Panel): bl_label = "Texture Space" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'} def draw(self, context): layout = self.layout + layout.use_property_split = True mesh = context.mesh @@ -176,18 +187,18 @@ class DATA_PT_texture_space(MeshButtonsPanel, Panel): layout.separator() layout.prop(mesh, "use_auto_texspace") - row = layout.row() - row.column().prop(mesh, "texspace_location", text="Location") - row.column().prop(mesh, "texspace_size", text="Size") + + layout.prop(mesh, "texspace_location", text="Location") + layout.prop(mesh, "texspace_size", text="Size") class DATA_PT_vertex_groups(MeshButtonsPanel, Panel): bl_label = "Vertex Groups" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'} @classmethod def poll(cls, context): - engine = context.scene.render.engine + engine = context.engine obj = context.object return (obj and obj.type in {'MESH', 'LATTICE'} and (engine in cls.COMPAT_ENGINES)) @@ -256,13 +267,55 @@ class DATA_PT_vertex_groups(MeshButtonsPanel, Panel): layout.prop(context.tool_settings, "vertex_group_weight", text="Weight") +class DATA_PT_face_maps(MeshButtonsPanel, Panel): + bl_label = "Face Maps" + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + + @classmethod + def poll(cls, context): + obj = context.object + return (obj and obj.type == 'MESH') + + def draw(self, context): + layout = self.layout + + ob = context.object + facemap = ob.face_maps.active + + rows = 2 + if facemap: + rows = 4 + + row = layout.row() + row.template_list("MESH_UL_fmaps", "", ob, "face_maps", ob.face_maps, "active_index", rows=rows) + + col = row.column(align=True) + col.operator("object.face_map_add", icon='ZOOMIN', text="") + col.operator("object.face_map_remove", icon='ZOOMOUT', text="") + if facemap: + col.separator() + col.operator("object.face_map_move", icon='TRIA_UP', text="").direction = 'UP' + col.operator("object.face_map_move", icon='TRIA_DOWN', text="").direction = 'DOWN' + + if ob.face_maps and (ob.mode == 'EDIT' and ob.type == 'MESH'): + row = layout.row() + + sub = row.row(align=True) + sub.operator("object.face_map_assign", text="Assign") + sub.operator("object.face_map_remove_from", text="Remove") + + sub = row.row(align=True) + sub.operator("object.face_map_select", text="Select") + sub.operator("object.face_map_deselect", text="Deselect") + + class DATA_PT_shape_keys(MeshButtonsPanel, Panel): bl_label = "Shape Keys" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'} @classmethod def poll(cls, context): - engine = context.scene.render.engine + engine = context.engine obj = context.object return (obj and obj.type in {'MESH', 'LATTICE', 'CURVE', 'SURFACE'} and (engine in cls.COMPAT_ENGINES)) @@ -351,7 +404,7 @@ class DATA_PT_shape_keys(MeshButtonsPanel, Panel): class DATA_PT_uv_texture(MeshButtonsPanel, Panel): bl_label = "UV Maps" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'} def draw(self, context): layout = self.layout @@ -361,7 +414,7 @@ class DATA_PT_uv_texture(MeshButtonsPanel, Panel): row = layout.row() col = row.column() - col.template_list("MESH_UL_uvmaps_vcols", "uvmaps", me, "uv_textures", me.uv_textures, "active_index", rows=1) + col.template_list("MESH_UL_uvmaps_vcols", "uvmaps", me, "uv_layers", me.uv_layers, "active_index", rows=1) col = row.column(align=True) col.operator("mesh.uv_texture_add", icon='ZOOMIN', text="") @@ -370,7 +423,7 @@ class DATA_PT_uv_texture(MeshButtonsPanel, Panel): class DATA_PT_vertex_colors(MeshButtonsPanel, Panel): bl_label = "Vertex Colors" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'} def draw(self, context): layout = self.layout @@ -390,7 +443,7 @@ class DATA_PT_vertex_colors(MeshButtonsPanel, Panel): class DATA_PT_customdata(MeshButtonsPanel, Panel): bl_label = "Geometry Data" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'} def draw(self, context): layout = self.layout @@ -416,7 +469,7 @@ class DATA_PT_customdata(MeshButtonsPanel, Panel): class DATA_PT_custom_props_mesh(MeshButtonsPanel, PropertyPanel, Panel): - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'} _context_path = "object.data" _property_type = bpy.types.Mesh @@ -425,12 +478,14 @@ classes = ( MESH_MT_vertex_group_specials, MESH_MT_shape_key_specials, MESH_UL_vgroups, + MESH_UL_fmaps, MESH_UL_shape_keys, MESH_UL_uvmaps_vcols, DATA_PT_context_mesh, DATA_PT_normals, DATA_PT_texture_space, DATA_PT_vertex_groups, + DATA_PT_face_maps, DATA_PT_shape_keys, DATA_PT_uv_texture, DATA_PT_vertex_colors, diff --git a/release/scripts/startup/bl_ui/properties_data_metaball.py b/release/scripts/startup/bl_ui/properties_data_metaball.py index dd62c4523b1..c796c8af141 100644 --- a/release/scripts/startup/bl_ui/properties_data_metaball.py +++ b/release/scripts/startup/bl_ui/properties_data_metaball.py @@ -54,40 +54,36 @@ class DATA_PT_metaball(DataButtonsPanel, Panel): def draw(self, context): layout = self.layout + layout.use_property_split = True mball = context.meta_ball - split = layout.split() - - col = split.column() + col = layout.column() col.label(text="Resolution:") sub = col.column(align=True) - sub.prop(mball, "resolution", text="View") + sub.prop(mball, "resolution", text="Resolution View") sub.prop(mball, "render_resolution", text="Render") - col = split.column() - col.label(text="Settings:") col.prop(mball, "threshold", text="Threshold") - - layout.label(text="Update:") - layout.row().prop(mball, "update_method", expand=True) + col.prop(mball, "update_method") class DATA_PT_mball_texture_space(DataButtonsPanel, Panel): bl_label = "Texture Space" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'} def draw(self, context): layout = self.layout + layout.use_property_split = True mball = context.meta_ball layout.prop(mball, "use_auto_texspace") - row = layout.row() - row.column().prop(mball, "texspace_location", text="Location") - row.column().prop(mball, "texspace_size", text="Size") + col = layout.column() + col.prop(mball, "texspace_location") + col.prop(mball, "texspace_size") class DATA_PT_metaball_element(DataButtonsPanel, Panel): @@ -99,39 +95,37 @@ class DATA_PT_metaball_element(DataButtonsPanel, Panel): def draw(self, context): layout = self.layout + layout.use_property_split = True metaelem = context.meta_ball.elements.active - layout.prop(metaelem, "type") + col = layout.column() - split = layout.split() + col.prop(metaelem, "type") + + col.separator() - col = split.column(align=True) - col.label(text="Settings:") col.prop(metaelem, "stiffness", text="Stiffness") col.prop(metaelem, "use_negative", text="Negative") col.prop(metaelem, "hide", text="Hide") - col = split.column(align=True) + sub = col.column(align=True) if metaelem.type in {'CUBE', 'ELLIPSOID'}: - col.label(text="Size:") - col.prop(metaelem, "size_x", text="X") - col.prop(metaelem, "size_y", text="Y") - col.prop(metaelem, "size_z", text="Z") + sub.prop(metaelem, "size_x", text="Size X") + sub.prop(metaelem, "size_y", text="Y") + sub.prop(metaelem, "size_z", text="Z") elif metaelem.type == 'TUBE': - col.label(text="Size:") - col.prop(metaelem, "size_x", text="X") + sub.prop(metaelem, "size_x", text="Size X") elif metaelem.type == 'PLANE': - col.label(text="Size:") - col.prop(metaelem, "size_x", text="X") - col.prop(metaelem, "size_y", text="Y") + sub.prop(metaelem, "size_x", text="Size X") + sub.prop(metaelem, "size_y", text="Y") class DATA_PT_custom_props_metaball(DataButtonsPanel, PropertyPanel, Panel): - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'} _context_path = "object.data" _property_type = bpy.types.MetaBall diff --git a/release/scripts/startup/bl_ui/properties_data_modifier.py b/release/scripts/startup/bl_ui/properties_data_modifier.py index 5bcf188c683..685d69ceacc 100644 --- a/release/scripts/startup/bl_ui/properties_data_modifier.py +++ b/release/scripts/startup/bl_ui/properties_data_modifier.py @@ -168,7 +168,6 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel): if bpy.app.debug: layout.prop(md, "debug_options") - def BUILD(self, layout, ob, md): split = layout.split() @@ -328,8 +327,10 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel): row.prop(md, "delimit") layout_info = layout - layout_info.label(text=iface_("Face Count: {:,}".format(md.face_count)), - translate=False) + layout_info.label( + text=iface_("Face Count: {:,}".format(md.face_count)), + translate=False, + ) def DISPLACE(self, layout, ob, md): has_texture = (md.texture is not None) @@ -358,7 +359,7 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel): col.prop(md, "texture_coords_object", text="") elif md.texture_coords == 'UV' and ob.type == 'MESH': col.label(text="UV Map:") - col.prop_search(md, "uv_layer", ob.data, "uv_textures", text="") + col.prop_search(md, "uv_layer", ob.data, "uv_layers", text="") layout.separator() @@ -390,7 +391,7 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel): sub.active = bool(md.vertex_group) sub.prop(md, "protect") col.label(text="Particle UV") - col.prop_search(md, "particle_uv", ob.data, "uv_textures", text="") + col.prop_search(md, "particle_uv", ob.data, "uv_layers", text="") col = split.column() col.prop(md, "use_edge_cut") @@ -952,7 +953,7 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel): col = split.column() scene = context.scene - engine = scene.render.engine + engine = context.engine show_adaptive_options = ( engine == 'CYCLES' and md == ob.modifiers[-1] and scene.cycles.feature_set == 'EXPERIMENTAL' @@ -1015,18 +1016,10 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel): def UV_PROJECT(self, layout, ob, md): split = layout.split() - - col = split.column() - col.label(text="Image:") - col.prop(md, "image", text="") - col = split.column() - col.label(text="UV Map:") - col.prop_search(md, "uv_layer", ob.data, "uv_textures", text="") + col.prop_search(md, "uv_layer", ob.data, "uv_layers") + col.separator() - split = layout.split() - col = split.column() - col.prop(md, "use_image_override") col.prop(md, "projector_count", text="Projectors") for proj in md.projectors: col.prop(proj, "object", text="") @@ -1080,7 +1073,7 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel): if md.texture_coords == 'OBJECT': layout.prop(md, "texture_coords_object", text="Object") elif md.texture_coords == 'UV' and ob.type == 'MESH': - layout.prop_search(md, "uv_layer", ob.data, "uv_textures") + layout.prop_search(md, "uv_layer", ob.data, "uv_layers") def WAVE(self, layout, ob, md): split = layout.split() @@ -1126,7 +1119,7 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel): col.template_ID(md, "texture", new="texture.new") layout.prop(md, "texture_coords") if md.texture_coords == 'UV' and ob.type == 'MESH': - layout.prop_search(md, "uv_layer", ob.data, "uv_textures") + layout.prop_search(md, "uv_layer", ob.data, "uv_layers") elif md.texture_coords == 'OBJECT': layout.prop(md, "texture_coords_object") @@ -1193,7 +1186,7 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel): if md.mask_tex_mapping == 'OBJECT': layout.prop(md, "mask_tex_map_object", text="Object") elif md.mask_tex_mapping == 'UV' and ob.type == 'MESH': - layout.prop_search(md, "mask_tex_uv_layer", ob.data, "uv_textures") + layout.prop_search(md, "mask_tex_uv_layer", ob.data, "uv_layers") def VERTEX_WEIGHT_EDIT(self, layout, ob, md): split = layout.split() @@ -1362,7 +1355,7 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel): col = split.column() col.label(text="UV Map:") - col.prop_search(md, "uv_layer", ob.data, "uv_textures", text="") + col.prop_search(md, "uv_layer", ob.data, "uv_layers", text="") def WIREFRAME(self, layout, ob, md): has_vgroup = bool(md.vertex_group) diff --git a/release/scripts/startup/bl_ui/properties_data_speaker.py b/release/scripts/startup/bl_ui/properties_data_speaker.py index eecb2690302..e43da31b5e8 100644 --- a/release/scripts/startup/bl_ui/properties_data_speaker.py +++ b/release/scripts/startup/bl_ui/properties_data_speaker.py @@ -29,14 +29,14 @@ class DataButtonsPanel: @classmethod def poll(cls, context): - engine = context.scene.render.engine + engine = context.engine return context.speaker and (engine in cls.COMPAT_ENGINES) class DATA_PT_context_speaker(DataButtonsPanel, Panel): bl_label = "" bl_options = {'HIDE_HEADER'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'} def draw(self, context): layout = self.layout @@ -55,69 +55,73 @@ class DATA_PT_context_speaker(DataButtonsPanel, Panel): class DATA_PT_speaker(DataButtonsPanel, Panel): bl_label = "Sound" - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'} def draw(self, context): layout = self.layout speaker = context.speaker - split = layout.split(percentage=0.75) + layout.template_ID(speaker, "sound", open="sound.open_mono") - split.template_ID(speaker, "sound", open="sound.open_mono") - split.prop(speaker, "muted") + layout.use_property_split = True - row = layout.row() - row.prop(speaker, "volume") - row.prop(speaker, "pitch") + layout.prop(speaker, "muted") + + col = layout.column() + col.active = not speaker.muted + col.prop(speaker, "volume", slider=True) + col.prop(speaker, "pitch") class DATA_PT_distance(DataButtonsPanel, Panel): bl_label = "Distance" - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'} def draw(self, context): layout = self.layout - speaker = context.speaker + layout.use_property_split = True - split = layout.split() + speaker = context.speaker + layout.active = not speaker.muted - col = split.column() - col.label("Volume:") - col.prop(speaker, "volume_min", text="Minimum") - col.prop(speaker, "volume_max", text="Maximum") + col = layout.column() + sub = col.column(align=True) + sub.prop(speaker, "volume_min", slider=True, text="Volume Min") + sub.prop(speaker, "volume_max", slider=True, text="Max") col.prop(speaker, "attenuation") - col = split.column() - col.label("Distance:") - col.prop(speaker, "distance_max", text="Maximum") - col.prop(speaker, "distance_reference", text="Reference") + col.separator() + col.prop(speaker, "distance_max", text="Max Distance") + col.prop(speaker, "distance_reference", text="Distance Reference") class DATA_PT_cone(DataButtonsPanel, Panel): bl_label = "Cone" - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'} def draw(self, context): layout = self.layout + layout.use_property_split = True + speaker = context.speaker + layout.active = not speaker.muted + + col = layout.column() - split = layout.split() + sub = col.column(align=True) + sub.prop(speaker, "cone_angle_outer", text="Angle Outer") + sub.prop(speaker, "cone_angle_inner", text="Inner") - col = split.column() - col.label("Angle:") - col.prop(speaker, "cone_angle_outer", text="Outer") - col.prop(speaker, "cone_angle_inner", text="Inner") + col.separator() - col = split.column() - col.label("Volume:") - col.prop(speaker, "cone_volume_outer", text="Outer") + col.prop(speaker, "cone_volume_outer", slider=True) class DATA_PT_custom_props_speaker(DataButtonsPanel, PropertyPanel, Panel): - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'} _context_path = "object.data" _property_type = bpy.types.Speaker diff --git a/release/scripts/startup/bl_ui/properties_data_workspace.py b/release/scripts/startup/bl_ui/properties_data_workspace.py new file mode 100644 index 00000000000..3cda3dd0abd --- /dev/null +++ b/release/scripts/startup/bl_ui/properties_data_workspace.py @@ -0,0 +1,101 @@ +# ##### BEGIN GPL LICENSE BLOCK ##### +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# ##### END GPL LICENSE BLOCK ##### + +# <pep8 compliant> +import bpy +from bpy.types import ( + Panel, +) + +from rna_prop_ui import PropertyPanel + + +class WorkSpaceButtonsPanel: + bl_space_type = 'PROPERTIES' + bl_region_type = 'WINDOW' + bl_context = "workspace" + + +class WORKSPACE_PT_owner_ids(WorkSpaceButtonsPanel, Panel): + bl_label = "Workspace Add-ons" + bl_options = {'DEFAULT_CLOSED'} + + def draw_header(self, context): + workspace = context.workspace + self.layout.prop(workspace, "use_filter_by_owner", text="") + + def draw(self, context): + layout = self.layout + # align just to pack more tightly + col = layout.box().column(align=True) + + workspace = context.workspace + userpref = context.user_preferences + + col.active = workspace.use_filter_by_owner + + import addon_utils + addon_map = {mod.__name__: mod for mod in addon_utils.modules()} + owner_ids = {owner_id.name for owner_id in workspace.owner_ids} + + for addon in userpref.addons: + module_name = addon.module + info = addon_utils.module_bl_info(addon_map[module_name]) + if not info["use_owner"]: + continue + is_enabled = module_name in owner_ids + row = col.row() + row.operator( + "wm.owner_disable" if is_enabled else "wm.owner_enable", + icon='CHECKBOX_HLT' if is_enabled else 'CHECKBOX_DEHLT', + text="", + emboss=False, + ).owner_id = module_name + row.label("%s: %s" % (info["category"], info["name"])) + if is_enabled: + owner_ids.remove(module_name) + + # Detect unused + if owner_ids: + layout.label(text="Unknown add-ons", icon='ERROR') + col = layout.box().column(align=True) + for module_name in sorted(owner_ids): + row = col.row() + row.operator( + "wm.owner_disable", + icon='CHECKBOX_HLT', + text="", + emboss=False, + ).owner_id = module_name + row.label(module_name) + + +class WORKSPACE_PT_custom_props(WorkSpaceButtonsPanel, PropertyPanel, Panel): + _context_path = "workspace" + _property_type = bpy.types.WorkSpace + + +classes = ( + WORKSPACE_PT_owner_ids, + WORKSPACE_PT_custom_props, +) + +if __name__ == "__main__": # only for live edit. + from bpy.utils import register_class + for cls in classes: + register_class(cls) diff --git a/release/scripts/startup/bl_ui/properties_freestyle.py b/release/scripts/startup/bl_ui/properties_freestyle.py index 3d105934bf8..a9c9d512335 100644 --- a/release/scripts/startup/bl_ui/properties_freestyle.py +++ b/release/scripts/startup/bl_ui/properties_freestyle.py @@ -33,13 +33,13 @@ class RenderFreestyleButtonsPanel: def poll(cls, context): scene = context.scene with_freestyle = bpy.app.build_options.freestyle - return scene and with_freestyle and(scene.render.engine in cls.COMPAT_ENGINES) + return scene and with_freestyle and(context.engine in cls.COMPAT_ENGINES) class RENDER_PT_freestyle(RenderFreestyleButtonsPanel, Panel): bl_label = "Freestyle" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} def draw_header(self, context): rd = context.scene.render @@ -62,34 +62,34 @@ class RENDER_PT_freestyle(RenderFreestyleButtonsPanel, Panel): # Render layer properties -class RenderLayerFreestyleButtonsPanel: +class ViewLayerFreestyleButtonsPanel: bl_space_type = 'PROPERTIES' bl_region_type = 'WINDOW' - bl_context = "render_layer" + bl_context = "view_layer" # COMPAT_ENGINES must be defined in each subclass, external engines can add themselves here @classmethod def poll(cls, context): scene = context.scene - rd = context.scene.render + rd = 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)) + (context.engine in cls.COMPAT_ENGINES)) -class RenderLayerFreestyleEditorButtonsPanel(RenderLayerFreestyleButtonsPanel): +class ViewLayerFreestyleEditorButtonsPanel(ViewLayerFreestyleButtonsPanel): # COMPAT_ENGINES must be defined in each subclass, external engines can add themselves here @classmethod def poll(cls, context): if not super().poll(context): return False - rl = context.scene.render.layers.active - return rl and rl.freestyle_settings.mode == 'EDITOR' + view_layer = context.view_layer + return view_layer and view_layer.freestyle_settings.mode == 'EDITOR' -class RENDERLAYER_UL_linesets(UIList): +class VIEWLAYER_UL_linesets(UIList): def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index): lineset = item if self.layout_type in {'DEFAULT', 'COMPACT'}: @@ -109,18 +109,18 @@ class RENDER_MT_lineset_specials(Menu): layout.operator("scene.freestyle_lineset_paste", icon='PASTEDOWN') -class RENDERLAYER_PT_freestyle(RenderLayerFreestyleButtonsPanel, Panel): +class VIEWLAYER_PT_freestyle(ViewLayerFreestyleButtonsPanel, Panel): bl_label = "Freestyle" - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} def draw(self, context): layout = self.layout - rd = context.scene.render - rl = rd.layers.active - freestyle = rl.freestyle_settings + scene = context.scene + view_layer = context.view_layer + freestyle = view_layer.freestyle_settings - layout.active = rl.use_freestyle + layout.active = view_layer.use_freestyle row = layout.row() layout.prop(freestyle, "mode", text="Control Mode") @@ -165,9 +165,9 @@ class RENDERLAYER_PT_freestyle(RenderLayerFreestyleButtonsPanel, Panel): row.operator("scene.freestyle_module_move", icon='TRIA_DOWN', text="").direction = 'DOWN' -class RENDERLAYER_PT_freestyle_lineset(RenderLayerFreestyleEditorButtonsPanel, Panel): +class VIEWLAYER_PT_freestyle_lineset(ViewLayerFreestyleEditorButtonsPanel, Panel): bl_label = "Freestyle Line Set" - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} def draw_edge_type_buttons(self, box, lineset, edge_type): # property names @@ -183,16 +183,18 @@ class RENDERLAYER_PT_freestyle_lineset(RenderLayerFreestyleEditorButtonsPanel, P def draw(self, context): layout = self.layout - rd = context.scene.render - rl = rd.layers.active - freestyle = rl.freestyle_settings + scene = context.scene + rd = scene.render + + view_layer = context.view_layer + freestyle = view_layer.freestyle_settings lineset = freestyle.linesets.active - layout.active = rl.use_freestyle + layout.active = view_layer.use_freestyle row = layout.row() rows = 4 if lineset else 2 - row.template_list("RENDERLAYER_UL_linesets", "", freestyle, "linesets", freestyle.linesets, "active_index", rows=rows) + row.template_list("VIEWLAYER_UL_linesets", "", freestyle, "linesets", freestyle.linesets, "active_index", rows=rows) sub = row.column(align=True) sub.operator("scene.freestyle_lineset_add", icon='ZOOMIN', text="") @@ -256,10 +258,10 @@ class RENDERLAYER_PT_freestyle_lineset(RenderLayerFreestyleEditorButtonsPanel, P row.prop(lineset, "group_negation", expand=True) -class RENDERLAYER_PT_freestyle_linestyle(RenderLayerFreestyleEditorButtonsPanel, Panel): +class VIEWLAYER_PT_freestyle_linestyle(ViewLayerFreestyleEditorButtonsPanel, Panel): bl_label = "Freestyle Line Style" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} def draw_modifier_box_header(self, box, modifier): row = box.row() @@ -376,7 +378,7 @@ class RENDERLAYER_PT_freestyle_linestyle(RenderLayerFreestyleEditorButtonsPanel, row = box.row(align=True) row.prop(modifier, "curvature_min") row.prop(modifier, "curvature_max") - freestyle = context.scene.render.layers.active.freestyle_settings + freestyle = context.view_layer.freestyle_settings if not freestyle.use_smoothness: message = "Enable Face Smoothness to use this modifier" self.draw_modifier_box_error(col.box(), modifier, message) @@ -431,7 +433,7 @@ class RENDERLAYER_PT_freestyle_linestyle(RenderLayerFreestyleEditorButtonsPanel, row = box.row(align=True) row.prop(modifier, "curvature_min") row.prop(modifier, "curvature_max") - freestyle = context.scene.render.layers.active.freestyle_settings + freestyle = context.view_layer.freestyle_settings if not freestyle.use_smoothness: message = "Enable Face Smoothness to use this modifier" self.draw_modifier_box_error(col.box(), modifier, message) @@ -503,7 +505,7 @@ class RENDERLAYER_PT_freestyle_linestyle(RenderLayerFreestyleEditorButtonsPanel, row = box.row(align=True) row.prop(modifier, "curvature_min") row.prop(modifier, "curvature_max") - freestyle = context.scene.render.layers.active.freestyle_settings + freestyle = context.view_layer.freestyle_settings if not freestyle.use_smoothness: message = "Enable Face Smoothness to use this modifier" self.draw_modifier_box_error(col.box(), modifier, message) @@ -611,11 +613,11 @@ class RENDERLAYER_PT_freestyle_linestyle(RenderLayerFreestyleEditorButtonsPanel, def draw(self, context): layout = self.layout - rd = context.scene.render - rl = rd.layers.active - lineset = rl.freestyle_settings.linesets.active + scene = context.scene + view_layer = context.view_layer + lineset = view_layer.freestyle_settings.linesets.active - layout.active = rl.use_freestyle + layout.active = view_layer.use_freestyle if lineset is None: return @@ -779,10 +781,7 @@ class RENDERLAYER_PT_freestyle_linestyle(RenderLayerFreestyleEditorButtonsPanel, layout.separator() row = layout.row() - if rd.use_shading_nodes: - row.prop(linestyle, "use_nodes") - else: - row.prop(linestyle, "use_texture") + row.prop(linestyle, "use_nodes") row.prop(linestyle, "texture_spacing", text="Spacing Along Stroke") row = layout.row() @@ -810,13 +809,13 @@ class MaterialFreestyleButtonsPanel: material = context.material with_freestyle = bpy.app.build_options.freestyle return with_freestyle and material and scene and scene.render.use_freestyle and \ - (scene.render.engine in cls.COMPAT_ENGINES) + (context.engine in cls.COMPAT_ENGINES) class MATERIAL_PT_freestyle_line(MaterialFreestyleButtonsPanel, Panel): bl_label = "Freestyle Line" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} def draw(self, context): layout = self.layout @@ -830,11 +829,11 @@ class MATERIAL_PT_freestyle_line(MaterialFreestyleButtonsPanel, Panel): classes = ( RENDER_PT_freestyle, - RENDERLAYER_UL_linesets, + VIEWLAYER_UL_linesets, RENDER_MT_lineset_specials, - RENDERLAYER_PT_freestyle, - RENDERLAYER_PT_freestyle_lineset, - RENDERLAYER_PT_freestyle_linestyle, + VIEWLAYER_PT_freestyle, + VIEWLAYER_PT_freestyle_lineset, + VIEWLAYER_PT_freestyle_linestyle, MATERIAL_PT_freestyle_line, ) diff --git a/release/scripts/startup/bl_ui/properties_game.py b/release/scripts/startup/bl_ui/properties_game.py deleted file mode 100644 index 277b0842b3d..00000000000 --- a/release/scripts/startup/bl_ui/properties_game.py +++ /dev/null @@ -1,881 +0,0 @@ -# ##### BEGIN GPL LICENSE BLOCK ##### -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -# -# ##### END GPL LICENSE BLOCK ##### - -# <pep8 compliant> -import bpy -from bpy.types import Panel, Menu - - -class PhysicsButtonsPanel: - bl_space_type = 'PROPERTIES' - bl_region_type = 'WINDOW' - bl_context = "physics" - - -class PHYSICS_PT_game_physics(PhysicsButtonsPanel, Panel): - bl_label = "Physics" - COMPAT_ENGINES = {'BLENDER_GAME'} - - @classmethod - def poll(cls, context): - ob = context.active_object - rd = context.scene.render - return ob and ob.game and (rd.engine in cls.COMPAT_ENGINES) - - def draw(self, context): - layout = self.layout - - ob = context.active_object - game = ob.game - soft = ob.game.soft_body - - layout.prop(game, "physics_type") - layout.separator() - - physics_type = game.physics_type - - if physics_type == 'CHARACTER': - layout.prop(game, "use_actor") - layout.prop(ob, "hide_render", text="Invisible") # out of place but useful - layout.prop(game, "step_height", slider=True) - layout.prop(game, "jump_speed") - layout.prop(game, "fall_speed") - layout.prop(game, "jump_max") - - elif physics_type in {'DYNAMIC', 'RIGID_BODY'}: - split = layout.split() - - col = split.column() - col.prop(game, "use_actor") - col.prop(game, "use_ghost") - col.prop(ob, "hide_render", text="Invisible") # out of place but useful - - col = split.column() - col.prop(game, "use_material_physics_fh") - col.prop(game, "use_rotate_from_normal") - col.prop(game, "use_sleep") - - layout.separator() - - split = layout.split() - - col = split.column() - col.label(text="Attributes:") - col.prop(game, "mass") - col.prop(game, "radius") - col.prop(game, "form_factor") - - col = split.column() - sub = col.column() - sub.prop(game, "use_anisotropic_friction") - subsub = sub.column() - subsub.active = game.use_anisotropic_friction - subsub.prop(game, "friction_coefficients", text="", slider=True) - - split = layout.split() - - col = split.column() - col.label(text="Linear Velocity:") - sub = col.column(align=True) - sub.prop(game, "velocity_min", text="Minimum") - sub.prop(game, "velocity_max", text="Maximum") - col.label(text="Angular Velocity:") - sub = col.column(align=True) - sub.prop(game, "angular_velocity_min", text="Minimum") - sub.prop(game, "angular_velocity_max", text="Maximum") - - col = split.column() - col.label(text="Damping:") - sub = col.column(align=True) - sub.prop(game, "damping", text="Translation", slider=True) - sub.prop(game, "rotation_damping", text="Rotation", slider=True) - - layout.separator() - - split = layout.split() - - col = split.column() - col.label(text="Lock Translation:") - col.prop(game, "lock_location_x", text="X") - 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") - col.prop(game, "lock_rotation_y", text="Y") - col.prop(game, "lock_rotation_z", text="Z") - - elif physics_type == 'SOFT_BODY': - col = layout.column() - col.prop(game, "use_actor") - col.prop(game, "use_ghost") - col.prop(ob, "hide_render", text="Invisible") - - layout.separator() - - split = layout.split() - - col = split.column() - col.label(text="Attributes:") - col.prop(game, "mass") - # disabled in the code - # col.prop(soft, "weld_threshold") - col.prop(soft, "location_iterations") - col.prop(soft, "linear_stiffness", slider=True) - col.prop(soft, "dynamic_friction", slider=True) - col.prop(soft, "collision_margin", slider=True) - col.prop(soft, "use_bending_constraints", text="Bending Constraints") - - col = split.column() - col.prop(soft, "use_shape_match") - sub = col.column() - sub.active = soft.use_shape_match - sub.prop(soft, "shape_threshold", slider=True) - - col.separator() - - col.label(text="Cluster Collision:") - col.prop(soft, "use_cluster_rigid_to_softbody") - col.prop(soft, "use_cluster_soft_to_softbody") - sub = col.column() - sub.active = (soft.use_cluster_rigid_to_softbody or soft.use_cluster_soft_to_softbody) - sub.prop(soft, "cluster_iterations", text="Iterations") - - elif physics_type == 'STATIC': - col = layout.column() - col.prop(game, "use_actor") - col.prop(game, "use_ghost") - col.prop(game, "use_record_animation") - col.prop(ob, "hide_render", text="Invisible") - - layout.separator() - - split = layout.split() - - col = split.column() - col.label(text="Attributes:") - col.prop(game, "radius") - - col = split.column() - sub = col.column() - sub.prop(game, "use_anisotropic_friction") - subsub = sub.column() - subsub.active = game.use_anisotropic_friction - subsub.prop(game, "friction_coefficients", text="", slider=True) - - elif physics_type == 'SENSOR': - col = layout.column() - col.prop(game, "use_actor", text="Detect Actors") - col.prop(ob, "hide_render", text="Invisible") - - elif physics_type in {'INVISIBLE', 'NO_COLLISION', 'OCCLUDER'}: - layout.prop(ob, "hide_render", text="Invisible") - - elif physics_type == 'NAVMESH': - layout.operator("mesh.navmesh_face_copy") - layout.operator("mesh.navmesh_face_add") - - layout.separator() - - layout.operator("mesh.navmesh_reset") - layout.operator("mesh.navmesh_clear") - - -class PHYSICS_PT_game_collision_bounds(PhysicsButtonsPanel, Panel): - bl_label = "Collision Bounds" - COMPAT_ENGINES = {'BLENDER_GAME'} - - @classmethod - def poll(cls, context): - game = context.object.game - rd = context.scene.render - return (rd.engine in cls.COMPAT_ENGINES) \ - and (game.physics_type in {'SENSOR', 'STATIC', 'DYNAMIC', 'RIGID_BODY', 'CHARACTER', 'SOFT_BODY'}) - - def draw_header(self, context): - game = context.active_object.game - - self.layout.prop(game, "use_collision_bounds", text="") - - def draw(self, context): - layout = self.layout - - game = context.active_object.game - split = layout.split() - split.active = game.use_collision_bounds - - col = split.column() - col.prop(game, "collision_bounds_type", text="Bounds") - - 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.prop(game, "use_collision_compound", text="Compound") - - layout.separator() - split = layout.split() - col = split.column() - col.prop(game, "collision_group") - col = split.column() - col.prop(game, "collision_mask") - - -class PHYSICS_PT_game_obstacles(PhysicsButtonsPanel, Panel): - bl_label = "Create Obstacle" - COMPAT_ENGINES = {'BLENDER_GAME'} - - @classmethod - def poll(cls, context): - game = context.object.game - rd = context.scene.render - return (rd.engine in cls.COMPAT_ENGINES) \ - and (game.physics_type in {'SENSOR', 'STATIC', 'DYNAMIC', 'RIGID_BODY', 'SOFT_BODY', 'CHARACTER', 'NO_COLLISION'}) - - def draw_header(self, context): - game = context.active_object.game - - self.layout.prop(game, "use_obstacle_create", text="") - - def draw(self, context): - layout = self.layout - - game = context.active_object.game - - layout.active = game.use_obstacle_create - - row = layout.row() - row.prop(game, "obstacle_radius", text="Radius") - row.label() - - -class RenderButtonsPanel: - bl_space_type = 'PROPERTIES' - bl_region_type = 'WINDOW' - bl_context = "render" - - @classmethod - def poll(cls, context): - rd = context.scene.render - return (rd.engine in cls.COMPAT_ENGINES) - - -class RENDER_PT_embedded(RenderButtonsPanel, Panel): - bl_label = "Embedded Player" - COMPAT_ENGINES = {'BLENDER_GAME'} - - def draw(self, context): - layout = self.layout - - rd = context.scene.render - - row = layout.row() - row.operator("view3d.game_start", text="Start") - row = layout.row() - row.label(text="Resolution:") - row = layout.row(align=True) - row.prop(rd, "resolution_x", slider=False, text="X") - row.prop(rd, "resolution_y", slider=False, text="Y") - - -class RENDER_PT_game_player(RenderButtonsPanel, Panel): - bl_label = "Standalone Player" - COMPAT_ENGINES = {'BLENDER_GAME'} - - def draw(self, context): - import sys - layout = self.layout - not_osx = sys.platform != "darwin" - - gs = context.scene.game_settings - - row = layout.row() - row.operator("wm.blenderplayer_start", text="Start") - row = layout.row() - row.label(text="Resolution:") - row = layout.row(align=True) - row.active = not_osx or not gs.show_fullscreen - row.prop(gs, "resolution_x", slider=False, text="X") - row.prop(gs, "resolution_y", slider=False, text="Y") - row = layout.row() - col = row.column() - col.prop(gs, "show_fullscreen") - - if not_osx: - col = row.column() - col.prop(gs, "use_desktop") - col.active = gs.show_fullscreen - - col = layout.column() - col.label(text="Quality:") - col.prop(gs, "samples") - col = layout.column(align=True) - col.prop(gs, "depth", text="Bit Depth", slider=False) - col.prop(gs, "frequency", text="Refresh Rate", slider=False) - - -class RENDER_PT_game_stereo(RenderButtonsPanel, Panel): - bl_label = "Stereo" - COMPAT_ENGINES = {'BLENDER_GAME'} - - def draw(self, context): - layout = self.layout - - gs = context.scene.game_settings - stereo_mode = gs.stereo - - # stereo options: - layout.row().prop(gs, "stereo", expand=True) - - # stereo: - if stereo_mode == 'STEREO': - layout.prop(gs, "stereo_mode") - layout.prop(gs, "stereo_eye_separation") - - # dome: - elif stereo_mode == 'DOME': - layout.prop(gs, "dome_mode", text="Dome Type") - - dome_type = gs.dome_mode - - split = layout.split() - - if dome_type in {'FISHEYE', 'TRUNCATED_REAR', 'TRUNCATED_FRONT'}: - col = split.column() - col.prop(gs, "dome_buffer_resolution", text="Resolution", slider=True) - col.prop(gs, "dome_angle", slider=True) - - col = split.column() - col.prop(gs, "dome_tessellation", text="Tessellation") - col.prop(gs, "dome_tilt") - - elif dome_type == 'PANORAM_SPH': - col = split.column() - col.prop(gs, "dome_buffer_resolution", text="Resolution", slider=True) - - col = split.column() - col.prop(gs, "dome_tessellation", text="Tessellation") - - else: # cube map - col = split.column() - col.prop(gs, "dome_buffer_resolution", text="Resolution", slider=True) - - col = split.column() - - layout.prop(gs, "dome_text") - - -class RENDER_PT_game_shading(RenderButtonsPanel, Panel): - bl_label = "Shading" - COMPAT_ENGINES = {'BLENDER_GAME'} - - def draw(self, context): - layout = self.layout - - gs = context.scene.game_settings - - layout.row().prop(gs, "material_mode", expand=True) - - if gs.material_mode == 'GLSL': - split = layout.split() - - col = split.column() - 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_environment_lighting", text="Environment Lighting") - - col = split.column() - col.prop(gs, "use_glsl_ramps", text="Ramps") - col.prop(gs, "use_glsl_nodes", text="Nodes") - col.prop(gs, "use_glsl_extra_textures", text="Extra Textures") - - -class RENDER_PT_game_system(RenderButtonsPanel, Panel): - bl_label = "System" - COMPAT_ENGINES = {'BLENDER_GAME'} - - def draw(self, context): - layout = self.layout - - gs = context.scene.game_settings - col = layout.column() - row = col.row() - col = row.column() - col.prop(gs, "use_frame_rate") - col.prop(gs, "use_restrict_animation_updates") - col.prop(gs, "use_material_caching") - col = row.column() - col.prop(gs, "use_display_lists") - col.active = gs.raster_storage != 'VERTEX_BUFFER_OBJECT' - - row = layout.row() - row.prop(gs, "vsync") - - row = layout.row() - row.prop(gs, "raster_storage") - - row = layout.row() - row.label("Exit Key") - row.prop(gs, "exit_key", text="", event=True) - - -class RENDER_PT_game_display(RenderButtonsPanel, Panel): - bl_label = "Display" - COMPAT_ENGINES = {'BLENDER_GAME'} - - def draw(self, context): - layout = self.layout - - gs = context.scene.game_settings - - layout.prop(context.scene.render, "fps", text="Animation Frame Rate", slider=False) - - flow = layout.column_flow() - flow.prop(gs, "show_debug_properties", text="Debug Properties") - flow.prop(gs, "show_framerate_profile", text="Framerate and Profile") - flow.prop(gs, "show_physics_visualization", text="Physics Visualization") - flow.prop(gs, "use_deprecation_warnings") - flow.prop(gs, "show_mouse", text="Mouse Cursor") - - col = layout.column() - col.label(text="Framing:") - col.row().prop(gs, "frame_type", expand=True) - if gs.frame_type == 'LETTERBOX': - col.prop(gs, "frame_color", text="") - - -class SceneButtonsPanel: - bl_space_type = 'PROPERTIES' - bl_region_type = 'WINDOW' - bl_context = "scene" - - -class SCENE_PT_game_physics(SceneButtonsPanel, Panel): - bl_label = "Physics" - COMPAT_ENGINES = {'BLENDER_GAME'} - - @classmethod - def poll(cls, context): - scene = context.scene - return (scene.render.engine in cls.COMPAT_ENGINES) - - def draw(self, context): - layout = self.layout - - gs = context.scene.game_settings - - layout.prop(gs, "physics_engine", text="Engine") - if gs.physics_engine != 'NONE': - layout.prop(gs, "physics_gravity", text="Gravity") - - split = layout.split() - - col = split.column() - col.label(text="Physics Steps:") - sub = col.column(align=True) - sub.prop(gs, "physics_step_max", text="Max") - sub.prop(gs, "physics_step_sub", text="Substeps") - col.prop(gs, "fps", text="FPS") - - col = split.column() - col.label(text="Logic Steps:") - col.prop(gs, "logic_step_max", text="Max") - - col = layout.column() - col.label(text="Physics Deactivation:") - sub = col.row(align=True) - sub.prop(gs, "deactivation_linear_threshold", text="Linear Threshold") - sub.prop(gs, "deactivation_angular_threshold", text="Angular Threshold") - sub = col.row() - sub.prop(gs, "deactivation_time", text="Time") - - col = layout.column() - col.prop(gs, "use_occlusion_culling", text="Occlusion Culling") - sub = col.column() - sub.active = gs.use_occlusion_culling - sub.prop(gs, "occlusion_culling_resolution", text="Resolution") - - else: - split = layout.split() - - col = split.column() - col.label(text="Physics Steps:") - col.prop(gs, "fps", text="FPS") - - col = split.column() - col.label(text="Logic Steps:") - col.prop(gs, "logic_step_max", text="Max") - - -class SCENE_PT_game_physics_obstacles(SceneButtonsPanel, Panel): - bl_label = "Obstacle Simulation" - bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_GAME'} - - @classmethod - def poll(cls, context): - scene = context.scene - return (scene.render.engine in cls.COMPAT_ENGINES) - - def draw(self, context): - layout = self.layout - - gs = context.scene.game_settings - - layout.prop(gs, "obstacle_simulation", text="Type") - if gs.obstacle_simulation != 'NONE': - layout.prop(gs, "level_height") - layout.prop(gs, "show_obstacle_simulation") - - -class SCENE_PT_game_navmesh(SceneButtonsPanel, Panel): - bl_label = "Navigation Mesh" - bl_options = {'DEFAULT_CLOSED'} - 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 - - rd = context.scene.game_settings.recast_data - - layout.operator("mesh.navmesh_make", text="Build Navigation Mesh") - - col = layout.column() - col.label(text="Rasterization:") - row = col.row() - row.prop(rd, "cell_size") - row.prop(rd, "cell_height") - - col = layout.column() - col.label(text="Agent:") - split = col.split() - - col = split.column() - col.prop(rd, "agent_height", text="Height") - col.prop(rd, "agent_radius", text="Radius") - - col = split.column() - col.prop(rd, "slope_max") - col.prop(rd, "climb_max") - - col = layout.column() - col.label(text="Region:") - row = col.row() - row.prop(rd, "region_min_size") - if rd.partitioning != 'LAYERS': - row.prop(rd, "region_merge_size") - - col = layout.column() - col.prop(rd, "partitioning") - - col = layout.column() - col.label(text="Polygonization:") - split = col.split() - - col = split.column() - col.prop(rd, "edge_max_len") - col.prop(rd, "edge_max_error") - - split.prop(rd, "verts_per_poly") - - col = layout.column() - col.label(text="Detail Mesh:") - row = col.row() - row.prop(rd, "sample_dist") - 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' - bl_context = "world" - - -class WORLD_PT_game_context_world(WorldButtonsPanel, Panel): - bl_label = "" - bl_options = {'HIDE_HEADER'} - COMPAT_ENGINES = {'BLENDER_GAME'} - - @classmethod - def poll(cls, context): - rd = context.scene.render - return (context.scene) and (rd.engine in cls.COMPAT_ENGINES) - - def draw(self, context): - layout = self.layout - - scene = context.scene - world = context.world - space = context.space_data - - split = layout.split(percentage=0.65) - if scene: - split.template_ID(scene, "world", new="world.new") - elif world: - split.template_ID(space, "pin_id") - - -class WORLD_PT_game_world(WorldButtonsPanel, Panel): - bl_label = "World" - COMPAT_ENGINES = {'BLENDER_GAME'} - - @classmethod - def poll(cls, context): - scene = context.scene - return (scene.world and scene.render.engine in cls.COMPAT_ENGINES) - - def draw(self, context): - layout = self.layout - - world = context.world - - row = layout.row() - row.column().prop(world, "horizon_color") - row.column().prop(world, "zenith_color") - row.column().prop(world, "ambient_color") - - -class WORLD_PT_game_environment_lighting(WorldButtonsPanel, Panel): - bl_label = "Environment Lighting" - COMPAT_ENGINES = {'BLENDER_GAME'} - - @classmethod - def poll(cls, context): - scene = context.scene - return (scene.world and scene.render.engine in cls.COMPAT_ENGINES) - - def draw_header(self, context): - light = context.world.light_settings - self.layout.prop(light, "use_environment_light", text="") - - def draw(self, context): - layout = self.layout - - light = context.world.light_settings - - layout.active = light.use_environment_light - - split = layout.split() - split.prop(light, "environment_energy", text="Energy") - split.prop(light, "environment_color", text="") - - -class WORLD_PT_game_mist(WorldButtonsPanel, Panel): - bl_label = "Mist" - COMPAT_ENGINES = {'BLENDER_GAME'} - - @classmethod - def poll(cls, context): - scene = context.scene - return (scene.world and scene.render.engine in cls.COMPAT_ENGINES) - - def draw_header(self, context): - world = context.world - - self.layout.prop(world.mist_settings, "use_mist", text="") - - def draw(self, context): - layout = self.layout - - world = context.world - - layout.active = world.mist_settings.use_mist - - layout.prop(world.mist_settings, "falloff") - - row = layout.row(align=True) - row.prop(world.mist_settings, "start") - row.prop(world.mist_settings, "depth") - - layout.prop(world.mist_settings, "intensity", text="Minimum Intensity") - - -class DataButtonsPanel: - bl_space_type = 'PROPERTIES' - bl_region_type = 'WINDOW' - bl_context = "data" - - -class DATA_PT_shadow_game(DataButtonsPanel, Panel): - bl_label = "Shadow" - COMPAT_ENGINES = {'BLENDER_GAME'} - - @classmethod - def poll(cls, context): - COMPAT_LIGHTS = {'SPOT', 'SUN'} - lamp = context.lamp - engine = context.scene.render.engine - return (lamp and lamp.type in COMPAT_LIGHTS) and (engine in cls.COMPAT_ENGINES) - - def draw_header(self, context): - lamp = context.lamp - - self.layout.prop(lamp, "use_shadow", text="") - - def draw(self, context): - layout = self.layout - - lamp = context.lamp - - layout.active = lamp.use_shadow - - split = layout.split() - - 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") - col.prop(lamp, "use_only_shadow") - - col = layout.column() - col.label("Buffer Type:") - col.prop(lamp, "ge_shadow_buffer_type", text="", toggle=True) - col.label("Quality:") - col = layout.column(align=True) - col.prop(lamp, "shadow_buffer_size", text="Size") - col.prop(lamp, "shadow_buffer_bias", text="Bias") - col.prop(lamp, "shadow_buffer_bleed_bias", text="Bleed Bias") - - row = layout.row() - row.label("Clipping:") - row = layout.row(align=True) - row.prop(lamp, "shadow_buffer_clip_start", text="Clip Start") - row.prop(lamp, "shadow_buffer_clip_end", text="Clip End") - - if lamp.type == 'SUN': - row = layout.row() - row.prop(lamp, "shadow_frustum_size", text="Frustum Size") - - -class ObjectButtonsPanel: - bl_space_type = 'PROPERTIES' - bl_region_type = 'WINDOW' - bl_context = "object" - - -class OBJECT_MT_lod_tools(Menu): - bl_label = "Level Of Detail Tools" - - def draw(self, context): - layout = self.layout - - layout.operator("object.lod_by_name", text="Set By Name") - layout.operator("object.lod_generate", text="Generate") - layout.operator("object.lod_clear_all", text="Clear All", icon='PANEL_CLOSE') - - -class OBJECT_PT_levels_of_detail(ObjectButtonsPanel, Panel): - bl_label = "Levels of Detail" - COMPAT_ENGINES = {'BLENDER_GAME'} - - @classmethod - def poll(cls, context): - return context.scene.render.engine in cls.COMPAT_ENGINES - - def draw(self, context): - layout = self.layout - ob = context.object - gs = context.scene.game_settings - - col = layout.column() - - for i, level in enumerate(ob.lod_levels): - if i == 0: - continue - box = col.box() - row = box.row() - row.prop(level, "object", text="") - row.operator("object.lod_remove", text="", icon='PANEL_CLOSE').index = i - - row = box.row() - row.prop(level, "distance") - row = row.row(align=True) - 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') - - -classes = ( - PHYSICS_PT_game_physics, - PHYSICS_PT_game_collision_bounds, - PHYSICS_PT_game_obstacles, - RENDER_PT_embedded, - RENDER_PT_game_player, - RENDER_PT_game_stereo, - RENDER_PT_game_shading, - RENDER_PT_game_system, - RENDER_PT_game_display, - SCENE_PT_game_physics, - SCENE_PT_game_physics_obstacles, - SCENE_PT_game_navmesh, - SCENE_PT_game_hysteresis, - WORLD_PT_game_context_world, - WORLD_PT_game_world, - WORLD_PT_game_environment_lighting, - WORLD_PT_game_mist, - DATA_PT_shadow_game, - OBJECT_MT_lod_tools, - OBJECT_PT_levels_of_detail, -) - -if __name__ == "__main__": # only for live edit. - from bpy.utils import register_class - for cls in classes: - register_class(cls) diff --git a/release/scripts/startup/bl_ui/properties_grease_pencil_common.py b/release/scripts/startup/bl_ui/properties_grease_pencil_common.py index 2aa978a51d8..decbbff5d60 100644 --- a/release/scripts/startup/bl_ui/properties_grease_pencil_common.py +++ b/release/scripts/startup/bl_ui/properties_grease_pencil_common.py @@ -97,6 +97,11 @@ class GreasePencilDrawingToolsPanel: bl_category = "Grease Pencil" bl_region_type = 'TOOLS' + @classmethod + def poll(cls, context): + # XXX - disabled in 2.8 branch. + return False + @staticmethod def draw(self, context): layout = self.layout @@ -171,6 +176,9 @@ class GreasePencilStrokeEditPanel: @classmethod def poll(cls, context): + # XXX - disabled in 2.8 branch. + return False + if context.gpencil_data is None: return False @@ -260,6 +268,9 @@ class GreasePencilInterpolatePanel: @classmethod def poll(cls, context): + # XXX - disabled in 2.8 branch. + return False + if context.gpencil_data is None: return False elif context.space_data.type != 'VIEW_3D': @@ -308,6 +319,11 @@ class GreasePencilBrushPanel: bl_category = "Grease Pencil" bl_region_type = 'TOOLS' + @classmethod + def poll(cls, context): + # XXX - disabled in 2.8 branch. + return False + @staticmethod def draw(self, context): layout = self.layout @@ -377,6 +393,9 @@ class GreasePencilStrokeSculptPanel: @classmethod def poll(cls, context): + # XXX - disabled in 2.8 branch. + return False + if context.gpencil_data is None: return False @@ -437,6 +456,9 @@ class GreasePencilBrushCurvesPanel: @classmethod def poll(cls, context): + # XXX - disabled in 2.8 branch. + return False + if context.active_gpencil_brush is None: return False @@ -1027,6 +1049,9 @@ class GreasePencilPaletteColorPanel: @classmethod def poll(cls, context): + # XXX - disabled in 2.8 branch. + return False + if context.gpencil_data is None: return False @@ -1129,6 +1154,9 @@ class GreasePencilToolsPanel: @classmethod def poll(cls, context): + # XXX - disabled in 2.8 branch. + return False + return (context.gpencil_data is not None) @staticmethod diff --git a/release/scripts/startup/bl_ui/properties_material.py b/release/scripts/startup/bl_ui/properties_material.py index 73740df37e8..369772f7258 100644 --- a/release/scripts/startup/bl_ui/properties_material.py +++ b/release/scripts/startup/bl_ui/properties_material.py @@ -21,43 +21,7 @@ import bpy from bpy.types import Menu, Panel, UIList from rna_prop_ui import PropertyPanel from bpy.app.translations import pgettext_iface as iface_ - - -def active_node_mat(mat): - # TODO, 2.4x has a pipeline section, for 2.5 we need to communicate - # which settings from node-materials are used - if mat is not None: - mat_node = mat.active_node_material - if mat_node: - return mat_node - else: - return mat - - return None - - -def check_material(mat): - if mat is not None: - if mat.use_nodes: - if mat.active_node_material is not None: - return True - return False - return True - return False - - -def simple_material(mat): - if (mat is not None) and (not mat.use_nodes): - return True - return False - - -class MATERIAL_MT_sss_presets(Menu): - bl_label = "SSS Presets" - preset_subdir = "sss" - preset_operator = "script.execute_preset" - draw = Menu.draw_preset - +from bpy_extras.node_utils import find_node_input, find_output_node class MATERIAL_MT_specials(Menu): bl_label = "Material Specials" @@ -82,12 +46,6 @@ class MATERIAL_UL_matslots(UIList): layout.prop(ma, "name", text="", emboss=False, icon_value=icon) else: layout.label(text="", icon_value=icon) - if ma and not context.scene.render.use_shading_nodes: - manode = ma.active_node_material - if manode: - 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 == 'GRID': layout.alignment = 'CENTER' layout.label(text="", icon_value=icon) @@ -101,20 +59,32 @@ class MaterialButtonsPanel: @classmethod def poll(cls, context): - return context.material and (context.scene.render.engine in cls.COMPAT_ENGINES) + return context.material and (context.engine in cls.COMPAT_ENGINES) + + +class MATERIAL_PT_preview(MaterialButtonsPanel, Panel): + bl_label = "Preview" + COMPAT_ENGINES = {'BLENDER_EEVEE'} + + def draw(self, context): + self.layout.template_preview(context.material) + + +class MATERIAL_PT_custom_props(MaterialButtonsPanel, PropertyPanel, Panel): + COMPAT_ENGINES = {'BLENDER_EEVEE'} + _context_path = "material" + _property_type = bpy.types.Material -class MATERIAL_PT_context_material(MaterialButtonsPanel, Panel): +class EEVEE_MATERIAL_PT_context_material(MaterialButtonsPanel, Panel): bl_label = "" + bl_context = "material" bl_options = {'HIDE_HEADER'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} + COMPAT_ENGINES = {'BLENDER_EEVEE'} @classmethod def poll(cls, context): - # An exception, don't call the parent poll func because - # this manages materials for all engine types - - engine = context.scene.render.engine + engine = context.engine return (context.material or context.object) and (engine in cls.COMPAT_ENGINES) def draw(self, context): @@ -126,10 +96,9 @@ class MATERIAL_PT_context_material(MaterialButtonsPanel, Panel): space = context.space_data if ob: - is_sortable = (len(ob.material_slots) > 1) - + is_sortable = len(ob.material_slots) > 1 rows = 1 - if is_sortable: + if (is_sortable): rows = 4 row = layout.row() @@ -159,8 +128,6 @@ class MATERIAL_PT_context_material(MaterialButtonsPanel, Panel): if ob: split.template_ID(ob, "active_material", new="material.new") row = split.row() - if mat: - row.prop(mat, "use_nodes", icon='NODETREE', text="") if slot: row.prop(slot, "link", text="") @@ -170,921 +137,116 @@ class MATERIAL_PT_context_material(MaterialButtonsPanel, Panel): split.template_ID(space, "pin_id") split.separator() - if mat: - layout.row().prop(mat, "type", expand=True) - if mat.use_nodes: - row = layout.row() - row.label(text="", icon='NODETREE') - if mat.active_node_material: - row.prop(mat.active_node_material, "name", text="") - else: - row.label(text="No material node selected") - - -class MATERIAL_PT_preview(MaterialButtonsPanel, Panel): - bl_label = "Preview" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} - - def draw(self, context): - self.layout.template_preview(context.material) - - -class MATERIAL_PT_pipeline(MaterialButtonsPanel, Panel): - bl_label = "Render Pipeline Options" - bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} - - @classmethod - def poll(cls, context): - mat = context.material - engine = context.scene.render.engine - return mat and (not simple_material(mat)) and (mat.type in {'SURFACE', 'WIRE', 'VOLUME'}) and (engine in cls.COMPAT_ENGINES) - - def draw(self, context): - layout = self. layout - - mat = context.material - mat_type = mat.type in {'SURFACE', 'WIRE'} - - row = layout.row() - row.active = mat_type - row.prop(mat, "use_transparency") - sub = row.column() - sub.prop(mat, "offset_z") - - sub.active = mat_type and mat.use_transparency and mat.transparency_method == 'Z_TRANSPARENCY' - - row = layout.row() - row.active = mat.use_transparency or not mat_type - row.prop(mat, "transparency_method", expand=True) - - layout.separator() - - split = layout.split() - col = split.column() - - col.prop(mat, "use_raytrace") - col.prop(mat, "use_full_oversampling") - sub = col.column() - sub.active = mat_type - sub.prop(mat, "use_sky") - sub.prop(mat, "invert_z") - col.prop(mat, "pass_index") - - col = split.column() - col.active = mat_type - - col.prop(mat, "use_cast_shadows", text="Cast") - col.prop(mat, "use_cast_shadows_only", text="Cast Only") - col.prop(mat, "use_cast_buffer_shadows") - sub = col.column() - sub.active = mat.use_cast_buffer_shadows - sub.prop(mat, "shadow_cast_alpha", text="Casting Alpha") - col.prop(mat, "use_cast_approximate") - - -class MATERIAL_PT_diffuse(MaterialButtonsPanel, Panel): - bl_label = "Diffuse" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} - - @classmethod - def poll(cls, context): - mat = context.material - engine = context.scene.render.engine - return check_material(mat) and (mat.type in {'SURFACE', 'WIRE'}) and (engine in cls.COMPAT_ENGINES) - - def draw(self, context): - layout = self.layout - - mat = active_node_mat(context.material) - - split = layout.split() - - col = split.column() - col.prop(mat, "diffuse_color", text="") - sub = col.column() - sub.active = (not mat.use_shadeless) - sub.prop(mat, "diffuse_intensity", text="Intensity") - - col = split.column() - col.active = (not mat.use_shadeless) - col.prop(mat, "diffuse_shader", text="") - col.prop(mat, "use_diffuse_ramp", text="Ramp") - - col = layout.column() - col.active = (not mat.use_shadeless) - if mat.diffuse_shader == 'OREN_NAYAR': - col.prop(mat, "roughness") - elif mat.diffuse_shader == 'MINNAERT': - col.prop(mat, "darkness") - elif mat.diffuse_shader == 'TOON': - row = col.row() - row.prop(mat, "diffuse_toon_size", text="Size") - row.prop(mat, "diffuse_toon_smooth", text="Smooth") - elif mat.diffuse_shader == 'FRESNEL': - row = col.row() - row.prop(mat, "diffuse_fresnel", text="Fresnel") - row.prop(mat, "diffuse_fresnel_factor", text="Factor") - - if mat.use_diffuse_ramp: - col = layout.column() - col.active = (not mat.use_shadeless) - col.separator() - col.template_color_ramp(mat, "diffuse_ramp", expand=True) - col.separator() - - row = col.row() - row.prop(mat, "diffuse_ramp_input", text="Input") - row.prop(mat, "diffuse_ramp_blend", text="Blend") - - col.prop(mat, "diffuse_ramp_factor", text="Factor") - - -class MATERIAL_PT_specular(MaterialButtonsPanel, Panel): - bl_label = "Specular" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} - - @classmethod - def poll(cls, context): - mat = context.material - engine = context.scene.render.engine - return check_material(mat) and (mat.type in {'SURFACE', 'WIRE'}) and (engine in cls.COMPAT_ENGINES) - - def draw(self, context): - layout = self.layout - - mat = active_node_mat(context.material) - - layout.active = (not mat.use_shadeless) - - split = layout.split() - - col = split.column() - col.prop(mat, "specular_color", text="") - col.prop(mat, "specular_intensity", text="Intensity") - - col = split.column() - col.prop(mat, "specular_shader", text="") - col.prop(mat, "use_specular_ramp", text="Ramp") - - col = layout.column() - if mat.specular_shader in {'COOKTORR', 'PHONG'}: - col.prop(mat, "specular_hardness", text="Hardness") - elif mat.specular_shader == 'BLINN': - row = col.row() - row.prop(mat, "specular_hardness", text="Hardness") - row.prop(mat, "specular_ior", text="IOR") - elif mat.specular_shader == 'WARDISO': - col.prop(mat, "specular_slope", text="Slope") - elif mat.specular_shader == 'TOON': - row = col.row() - row.prop(mat, "specular_toon_size", text="Size") - row.prop(mat, "specular_toon_smooth", text="Smooth") - - if mat.use_specular_ramp: - layout.separator() - layout.template_color_ramp(mat, "specular_ramp", expand=True) - layout.separator() - - row = layout.row() - row.prop(mat, "specular_ramp_input", text="Input") - row.prop(mat, "specular_ramp_blend", text="Blend") - - layout.prop(mat, "specular_ramp_factor", text="Factor") - - -class MATERIAL_PT_shading(MaterialButtonsPanel, Panel): - bl_label = "Shading" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} - - @classmethod - def poll(cls, context): - mat = context.material - engine = context.scene.render.engine - return check_material(mat) and (mat.type in {'SURFACE', 'WIRE'}) and (engine in cls.COMPAT_ENGINES) - - def draw(self, context): - layout = self.layout - - mat = active_node_mat(context.material) - - if mat.type in {'SURFACE', 'WIRE'}: - split = layout.split() - - col = split.column() - sub = col.column() - sub.active = not mat.use_shadeless - sub.prop(mat, "emit") - sub.prop(mat, "ambient") - sub = col.column() - sub.prop(mat, "translucency") - - col = split.column() - col.prop(mat, "use_shadeless") - sub = col.column() - sub.active = not mat.use_shadeless - sub.prop(mat, "use_tangent_shading") - sub.prop(mat, "use_cubic") - - -class MATERIAL_PT_transp(MaterialButtonsPanel, Panel): - bl_label = "Transparency" - COMPAT_ENGINES = {'BLENDER_RENDER'} - - @classmethod - def poll(cls, context): - mat = context.material - engine = context.scene.render.engine - return check_material(mat) and (mat.type in {'SURFACE', 'WIRE'}) and (engine in cls.COMPAT_ENGINES) - - def draw_header(self, context): - mat = context.material - - if simple_material(mat): - self.layout.prop(mat, "use_transparency", text="") - - def draw(self, context): - layout = self.layout - - base_mat = context.material - mat = active_node_mat(context.material) - rayt = mat.raytrace_transparency - - if simple_material(base_mat): - row = layout.row() - row.active = mat.use_transparency - row.prop(mat, "transparency_method", expand=True) - - split = layout.split() - split.active = base_mat.use_transparency - - col = split.column() - col.prop(mat, "alpha") - row = col.row() - row.active = (base_mat.transparency_method != 'MASK') and (not mat.use_shadeless) - row.prop(mat, "specular_alpha", text="Specular") - - col = split.column() - col.active = (not mat.use_shadeless) - col.prop(rayt, "fresnel") - sub = col.column() - sub.active = (rayt.fresnel > 0.0) - sub.prop(rayt, "fresnel_factor", text="Blend") - - if base_mat.transparency_method == 'RAYTRACE': - layout.separator() - split = layout.split() - split.active = base_mat.use_transparency - - col = split.column() - col.prop(rayt, "ior") - col.prop(rayt, "filter") - col.prop(rayt, "falloff") - col.prop(rayt, "depth_max") - col.prop(rayt, "depth") - - col = split.column() - col.label(text="Gloss:") - col.prop(rayt, "gloss_factor", text="Amount") - sub = col.column() - sub.active = rayt.gloss_factor < 1.0 - sub.prop(rayt, "gloss_threshold", text="Threshold") - sub.prop(rayt, "gloss_samples", text="Samples") - - -class MATERIAL_PT_mirror(MaterialButtonsPanel, Panel): - bl_label = "Mirror" - bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER'} - - @classmethod - def poll(cls, context): - mat = context.material - engine = context.scene.render.engine - return check_material(mat) and (mat.type in {'SURFACE', 'WIRE'}) and (engine in cls.COMPAT_ENGINES) - - def draw_header(self, context): - raym = active_node_mat(context.material).raytrace_mirror - - self.layout.prop(raym, "use", text="") - - def draw(self, context): - layout = self.layout - - mat = active_node_mat(context.material) - raym = mat.raytrace_mirror - - layout.active = raym.use - - split = layout.split() - - col = split.column() - col.prop(raym, "reflect_factor") - col.prop(mat, "mirror_color", text="") - - col = split.column() - col.prop(raym, "fresnel") - sub = col.column() - sub.active = (raym.fresnel > 0.0) - sub.prop(raym, "fresnel_factor", text="Blend") - - split = layout.split() - - col = split.column() - col.separator() - col.prop(raym, "depth") - col.prop(raym, "distance", text="Max Dist") - col.separator() - sub = col.split(percentage=0.4) - sub.active = (raym.distance > 0.0) - sub.label(text="Fade To:") - sub.prop(raym, "fade_to", text="") - - col = split.column() - col.label(text="Gloss:") - col.prop(raym, "gloss_factor", text="Amount") - sub = col.column() - sub.active = (raym.gloss_factor < 1.0) - sub.prop(raym, "gloss_threshold", text="Threshold") - sub.prop(raym, "gloss_samples", text="Samples") - sub.prop(raym, "gloss_anisotropic", text="Anisotropic") - - -class MATERIAL_PT_sss(MaterialButtonsPanel, Panel): - bl_label = "Subsurface Scattering" - bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER'} - - @classmethod - def poll(cls, context): - mat = context.material - engine = context.scene.render.engine - return check_material(mat) and (mat.type in {'SURFACE', 'WIRE'}) and (engine in cls.COMPAT_ENGINES) - - def draw_header(self, context): - mat = active_node_mat(context.material) - sss = mat.subsurface_scattering - - self.layout.active = (not mat.use_shadeless) - self.layout.prop(sss, "use", text="") - - def draw(self, context): - layout = self.layout - - mat = active_node_mat(context.material) - sss = mat.subsurface_scattering - - layout.active = (sss.use) and (not mat.use_shadeless) - - row = layout.row().split() - sub = row.row(align=True).split(align=True, percentage=0.75) - sub.menu("MATERIAL_MT_sss_presets", text=bpy.types.MATERIAL_MT_sss_presets.bl_label) - sub.operator("material.sss_preset_add", text="", icon='ZOOMIN') - sub.operator("material.sss_preset_add", text="", icon='ZOOMOUT').remove_active = True - - split = layout.split() - - col = split.column() - col.prop(sss, "ior") - col.prop(sss, "scale") - col.prop(sss, "color", text="") - col.prop(sss, "radius", text="RGB Radius", expand=True) - - col = split.column() - sub = col.column(align=True) - sub.label(text="Blend:") - sub.prop(sss, "color_factor", text="Color") - sub.prop(sss, "texture_factor", text="Texture") - sub.label(text="Scattering Weight:") - sub.prop(sss, "front") - sub.prop(sss, "back") - col.separator() - col.prop(sss, "error_threshold", text="Error") - -class MATERIAL_PT_halo(MaterialButtonsPanel, Panel): - bl_label = "Halo" - COMPAT_ENGINES = {'BLENDER_RENDER'} - - @classmethod - def poll(cls, context): - mat = context.material - engine = context.scene.render.engine - return mat and (mat.type == 'HALO') and (engine in cls.COMPAT_ENGINES) - - def draw(self, context): - layout = self.layout - - mat = context.material # don't use node material - halo = mat.halo - - def number_but(layout, toggle, number, name, color): - row = layout.row(align=True) - row.prop(halo, toggle, text="") - sub = row.column(align=True) - sub.active = getattr(halo, toggle) - sub.prop(halo, number, text=name, translate=False) - if not color == "": - sub.prop(mat, color, text="") - - split = layout.split() - - col = split.column() - col.prop(mat, "alpha") - col.prop(mat, "diffuse_color", text="") - col.prop(halo, "seed") - - col = split.column() - col.prop(halo, "size") - col.prop(halo, "hardness") - col.prop(halo, "add") - - layout.label(text="Options:") - - split = layout.split() - col = split.column() - col.prop(halo, "use_texture") - col.prop(halo, "use_vertex_normal") - col.prop(halo, "use_extreme_alpha") - col.prop(halo, "use_shaded") - col.prop(halo, "use_soft") - - col = split.column() - number_but(col, "use_ring", "ring_count", iface_("Rings"), "mirror_color") - number_but(col, "use_lines", "line_count", iface_("Lines"), "specular_color") - number_but(col, "use_star", "star_tip_count", iface_("Star Tips"), "") - - -class MATERIAL_PT_flare(MaterialButtonsPanel, Panel): - bl_label = "Flare" - COMPAT_ENGINES = {'BLENDER_RENDER'} - - @classmethod - def poll(cls, context): - mat = context.material - engine = context.scene.render.engine - return mat and (mat.type == 'HALO') and (engine in cls.COMPAT_ENGINES) - - def draw_header(self, context): - halo = context.material.halo - - self.layout.prop(halo, "use_flare_mode", text="") - - def draw(self, context): - layout = self.layout - - mat = context.material # don't use node material - halo = mat.halo - - layout.active = halo.use_flare_mode - - split = layout.split() - - col = split.column() - col.prop(halo, "flare_size", text="Size") - col.prop(halo, "flare_boost", text="Boost") - col.prop(halo, "flare_seed", text="Seed") - - col = split.column() - col.prop(halo, "flare_subflare_count", text="Subflares") - col.prop(halo, "flare_subflare_size", text="Subsize") - - -class MATERIAL_PT_game_settings(MaterialButtonsPanel, Panel): - bl_label = "Game Settings" - COMPAT_ENGINES = {'BLENDER_GAME'} - - @classmethod - def poll(cls, context): - return context.material and (context.scene.render.engine in cls.COMPAT_ENGINES) - - def draw(self, context): - layout = self.layout - game = context.material.game_settings # don't use node material - - row = layout.row() - row.prop(game, "use_backface_culling") - row.prop(game, "invisible") - row.prop(game, "text") - - row = layout.row() - row.label(text="Alpha Blend:") - row.label(text="Face Orientation:") - row = layout.row() - row.prop(game, "alpha_blend", text="") - row.prop(game, "face_orientation", text="") +def panel_node_draw(layout, ntree, output_type): + node = find_output_node(ntree, output_type) + if node: + input = find_node_input(node, 'Surface') + if input: + layout.template_node_view(ntree, node, input) + else: + layout.label(text="Incompatible output node") + else: + layout.label(text="No output node") -class MATERIAL_PT_physics(MaterialButtonsPanel, Panel): - bl_label = "Physics" - COMPAT_ENGINES = {'BLENDER_GAME'} - def draw_header(self, context): - game = context.material.game_settings - self.layout.prop(game, "physics", text="") +class EEVEE_MATERIAL_PT_surface(MaterialButtonsPanel, Panel): + bl_label = "Surface" + bl_context = "material" + COMPAT_ENGINES = {'BLENDER_EEVEE'} @classmethod def poll(cls, context): - return context.material and (context.scene.render.engine in cls.COMPAT_ENGINES) + engine = context.engine + return context.material and (engine in cls.COMPAT_ENGINES) def draw(self, context): layout = self.layout - layout.active = context.material.game_settings.physics - - phys = context.material.physics # don't use node material - - split = layout.split() - row = split.row() - row.prop(phys, "friction") - row.prop(phys, "elasticity", slider=True) - row = layout.row() - row.label(text="Force Field:") - - row = layout.row() - row.prop(phys, "fh_force") - row.prop(phys, "fh_damping", slider=True) - - row = layout.row() - row.prop(phys, "fh_distance") - row.prop(phys, "use_fh_normal") - - -class MATERIAL_PT_strand(MaterialButtonsPanel, Panel): - bl_label = "Strand" - bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER'} - - @classmethod - def poll(cls, context): mat = context.material - engine = context.scene.render.engine - return mat and (mat.type in {'SURFACE', 'WIRE', 'HALO'}) and (engine in cls.COMPAT_ENGINES) - - def draw(self, context): - layout = self.layout - - mat = context.material # don't use node material - tan = mat.strand - split = layout.split() - - col = split.column() - sub = col.column(align=True) - sub.label(text="Size:") - sub.prop(tan, "root_size", text="Root") - sub.prop(tan, "tip_size", text="Tip") - sub.prop(tan, "size_min", text="Minimum") - sub.prop(tan, "use_blender_units") - sub = col.column() - sub.active = (not mat.use_shadeless) - sub.prop(tan, "use_tangent_shading") - col.prop(tan, "shape") + layout.prop(mat, "use_nodes", icon='NODETREE') + layout.separator() - col = split.column() - col.label(text="Shading:") - col.prop(tan, "width_fade") - ob = context.object - if ob and ob.type == 'MESH': - col.prop_search(tan, "uv_layer", ob.data, "uv_textures", text="") + if mat.use_nodes: + panel_node_draw(layout, mat.node_tree, ('OUTPUT_EEVEE_MATERIAL', 'OUTPUT_MATERIAL')) else: - col.prop(tan, "uv_layer", text="") - col.separator() - sub = col.column() - sub.active = (not mat.use_shadeless) - sub.label("Surface diffuse:") - sub = col.column() - sub.prop(tan, "blend_distance", text="Distance") + layout.prop(mat, "diffuse_color", text="Base Color") + layout.prop(mat, "metallic") + layout.prop(mat, "specular_intensity", text="Specular") + layout.prop(mat, "roughness") -class MATERIAL_PT_options(MaterialButtonsPanel, Panel): +class EEVEE_MATERIAL_PT_options(MaterialButtonsPanel, Panel): bl_label = "Options" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} + bl_context = "material" + COMPAT_ENGINES = {'BLENDER_EEVEE'} @classmethod def poll(cls, context): - mat = context.material - engine = context.scene.render.engine - return check_material(mat) and (mat.type in {'SURFACE', 'WIRE'}) and (engine in cls.COMPAT_ENGINES) + engine = context.engine + return context.material and (engine in cls.COMPAT_ENGINES) def draw(self, context): layout = self.layout - base_mat = context.material - mat = active_node_mat(base_mat) - - split = layout.split() - - col = split.column() - if simple_material(base_mat): - col.prop(mat, "use_raytrace") - col.prop(mat, "use_full_oversampling") - col.prop(mat, "use_sky") - col.prop(mat, "use_mist") - if simple_material(base_mat): - col.prop(mat, "invert_z") - sub = col.row() - sub.prop(mat, "offset_z") - sub.active = mat.use_transparency and mat.transparency_method == 'Z_TRANSPARENCY' - sub = col.column(align=True) - sub.label(text="Light Group:") - sub.prop(mat, "light_group", text="") - row = sub.row(align=True) - row.active = bool(mat.light_group) - row.prop(mat, "use_light_group_exclusive", text="Exclusive") - row.prop(mat, "use_light_group_local", text="Local") - - col = split.column() - col.prop(mat, "use_face_texture") - sub = col.column() - sub.active = mat.use_face_texture - sub.prop(mat, "use_face_texture_alpha") - col.separator() - col.prop(mat, "use_vertex_color_paint") - col.prop(mat, "use_vertex_color_light") - col.prop(mat, "use_object_color") - col.prop(mat, "use_uv_project") - if simple_material(base_mat): - col.prop(mat, "pass_index") - - -class MATERIAL_PT_shadow(MaterialButtonsPanel, Panel): - bl_label = "Shadow" - bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} - - @classmethod - def poll(cls, context): mat = context.material - engine = context.scene.render.engine - return check_material(mat) and (mat.type in {'SURFACE', 'WIRE'}) and (engine in cls.COMPAT_ENGINES) - - def draw(self, context): - layout = self.layout - - base_mat = context.material - mat = active_node_mat(base_mat) - - split = layout.split() - - col = split.column() - col.prop(mat, "use_shadows", text="Receive") - col.prop(mat, "use_transparent_shadows", text="Receive Transparent") - col.prop(mat, "use_only_shadow", text="Shadows Only") - sub = col.column() - sub.active = mat.use_only_shadow - sub.prop(mat, "shadow_only_type", text="") - if not simple_material(base_mat): - col = split.column() + layout.prop(mat, "blend_method") - col.prop(mat, "use_ray_shadow_bias", text="Auto Ray Bias") - sub = col.column() - sub.active = (not mat.use_ray_shadow_bias) - sub.prop(mat, "shadow_ray_bias", text="Ray Bias") + if mat.blend_method != "OPAQUE": + layout.prop(mat, "transparent_shadow_method") - if simple_material(base_mat): - col = split.column() - - col.prop(mat, "use_cast_shadows", text="Cast") - col.prop(mat, "use_cast_shadows_only", text="Cast Only") - col.prop(mat, "use_cast_buffer_shadows") - sub = col.column() - sub.active = mat.use_cast_buffer_shadows - if simple_material(base_mat): - sub.prop(mat, "shadow_cast_alpha", text="Casting Alpha") - sub.prop(mat, "shadow_buffer_bias", text="Buffer Bias") - if simple_material(base_mat): - col.prop(mat, "use_cast_approximate") - - -class MATERIAL_PT_transp_game(MaterialButtonsPanel, Panel): - bl_label = "Transparency" - bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_GAME'} - - @classmethod - def poll(cls, context): - mat = context.material - engine = context.scene.render.engine - return check_material(mat) and (engine in cls.COMPAT_ENGINES) - - def draw_header(self, context): - mat = context.material - - if simple_material(mat): - self.layout.prop(mat, "use_transparency", text="") - - def draw(self, context): - layout = self.layout - base_mat = context.material - mat = active_node_mat(base_mat) - - layout.active = mat.use_transparency - - if simple_material(base_mat): row = layout.row() - row.prop(mat, "transparency_method", expand=True) - - layout.prop(mat, "alpha") - layout.prop(mat, "specular_alpha", text="Specular") - - -class VolumeButtonsPanel: - bl_space_type = 'PROPERTIES' - bl_region_type = 'WINDOW' - bl_context = "material" - COMPAT_ENGINES = {'BLENDER_RENDER'} - - @classmethod - def poll(cls, context): - mat = context.material - engine = context.scene.render.engine - return mat and (mat.type == 'VOLUME') and (engine in cls.COMPAT_ENGINES) + row.active = ((mat.blend_method == "CLIP") or (mat.transparent_shadow_method == "CLIP")) + row.prop(mat, "alpha_threshold") + if mat.blend_method not in {"OPAQUE", "CLIP", "HASHED"}: + layout.prop(mat, "show_transparent_backside") -class MATERIAL_PT_volume_density(VolumeButtonsPanel, Panel): - bl_label = "Density" - COMPAT_ENGINES = {'BLENDER_RENDER'} - - def draw(self, context): - layout = self.layout - - vol = context.material.volume # don't use node material + layout.prop(mat, "use_screen_refraction") + layout.prop(mat, "refraction_depth") + layout.prop(mat, "use_screen_subsurface") row = layout.row() - row.prop(vol, "density") - row.prop(vol, "density_scale") + row.active = mat.use_screen_subsurface + row.prop(mat, "use_sss_translucency") -class MATERIAL_PT_volume_shading(VolumeButtonsPanel, Panel): - bl_label = "Shading" - COMPAT_ENGINES = {'BLENDER_RENDER'} - - def draw(self, context): - layout = self.layout - - vol = context.material.volume # don't use node material - - split = layout.split() - - col = split.column() - col.prop(vol, "scattering") - col.prop(vol, "asymmetry") - col.prop(vol, "transmission_color") - - col = split.column() - sub = col.column(align=True) - sub.prop(vol, "emission") - sub.prop(vol, "emission_color", text="") - sub = col.column(align=True) - sub.prop(vol, "reflection") - sub.prop(vol, "reflection_color", text="") - - -class MATERIAL_PT_volume_lighting(VolumeButtonsPanel, Panel): - bl_label = "Lighting" - COMPAT_ENGINES = {'BLENDER_RENDER'} - - def draw(self, context): - layout = self.layout - - vol = context.material.volume # don't use node material - - split = layout.split() - - col = split.column() - col.prop(vol, "light_method", text="") - - col = split.column() - - if vol.light_method == 'SHADED': - col.prop(vol, "use_external_shadows") - col.prop(vol, "use_light_cache") - sub = col.column() - sub.active = vol.use_light_cache - sub.prop(vol, "cache_resolution") - elif vol.light_method in {'MULTIPLE_SCATTERING', 'SHADED_PLUS_MULTIPLE_SCATTERING'}: - sub = col.column() - sub.enabled = True - sub.active = False - sub.label("Light Cache Enabled") - col.prop(vol, "cache_resolution") - - sub = col.column(align=True) - sub.prop(vol, "ms_diffusion") - sub.prop(vol, "ms_spread") - sub.prop(vol, "ms_intensity") - - -class MATERIAL_PT_volume_transp(VolumeButtonsPanel, Panel): - bl_label = "Transparency" - COMPAT_ENGINES = {'BLENDER_RENDER'} +class MATERIAL_PT_viewport(MaterialButtonsPanel, Panel): + bl_label = "Viewport Display" + bl_context = "material" + bl_options = {'DEFAULT_CLOSED'} @classmethod def poll(cls, context): - mat = context.material - engine = context.scene.render.engine - return mat and simple_material(mat) and (mat.type == 'VOLUME') and (engine in cls.COMPAT_ENGINES) + return context.material def draw(self, context): - layout = self.layout - - mat = context.material # don't use node material - - layout.row().prop(mat, "transparency_method", expand=True) - - -class MATERIAL_PT_volume_integration(VolumeButtonsPanel, Panel): - bl_label = "Integration" - COMPAT_ENGINES = {'BLENDER_RENDER'} - - def draw(self, context): - layout = self.layout - - vol = context.material.volume # don't use node material - - split = layout.split() - - col = split.column() - col.label(text="Step Calculation:") - col.prop(vol, "step_method", text="") - col = col.column(align=True) - col.prop(vol, "step_size") - - col = split.column() - col.label() - col.prop(vol, "depth_threshold") - - -class MATERIAL_PT_volume_options(VolumeButtonsPanel, Panel): - bl_label = "Options" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} - bl_options = {'DEFAULT_CLOSED'} - - @classmethod - def poll(cls, context): mat = context.material - engine = context.scene.render.engine - return check_material(mat) and (mat.type == 'VOLUME') and (engine in cls.COMPAT_ENGINES) - def draw(self, context): layout = self.layout + layout.use_property_split = True - mat = active_node_mat(context.material) - - split = layout.split() - - col = split.column() - if simple_material(context.material): - col.prop(mat, "use_raytrace") - col.prop(mat, "use_full_oversampling") - col.prop(mat, "use_mist") - - col = split.column() - col.label(text="Light Group:") - col.prop(mat, "light_group", text="") - row = col.row() - row.active = bool(mat.light_group) - row.prop(mat, "use_light_group_exclusive", text="Exclusive") - - -class MATERIAL_PT_custom_props(MaterialButtonsPanel, PropertyPanel, Panel): - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} - _context_path = "material" - _property_type = bpy.types.Material + col = layout.column() + col.prop(mat, "diffuse_color") + col.prop(mat, "specular_color") + col.prop(mat, "roughness") classes = ( - MATERIAL_MT_sss_presets, MATERIAL_MT_specials, MATERIAL_UL_matslots, - MATERIAL_PT_context_material, MATERIAL_PT_preview, - MATERIAL_PT_pipeline, - MATERIAL_PT_diffuse, - MATERIAL_PT_specular, - MATERIAL_PT_shading, - MATERIAL_PT_transp, - MATERIAL_PT_mirror, - MATERIAL_PT_sss, - MATERIAL_PT_halo, - MATERIAL_PT_flare, - MATERIAL_PT_game_settings, - MATERIAL_PT_physics, - MATERIAL_PT_strand, - MATERIAL_PT_options, - MATERIAL_PT_shadow, - MATERIAL_PT_transp_game, - MATERIAL_PT_volume_density, - MATERIAL_PT_volume_shading, - MATERIAL_PT_volume_lighting, - MATERIAL_PT_volume_transp, - MATERIAL_PT_volume_integration, - MATERIAL_PT_volume_options, MATERIAL_PT_custom_props, + EEVEE_MATERIAL_PT_context_material, + EEVEE_MATERIAL_PT_surface, + EEVEE_MATERIAL_PT_options, + MATERIAL_PT_viewport, ) + if __name__ == "__main__": # only for live edit. from bpy.utils import register_class for cls in classes: diff --git a/release/scripts/startup/bl_ui/properties_object.py b/release/scripts/startup/bl_ui/properties_object.py index 5e7f1b068e2..6486fbf0d63 100644 --- a/release/scripts/startup/bl_ui/properties_object.py +++ b/release/scripts/startup/bl_ui/properties_object.py @@ -40,7 +40,7 @@ class OBJECT_PT_context_object(ObjectButtonsPanel, Panel): layout.template_ID(space, "pin_id") else: row = layout.row() - row.template_ID(context.scene.objects, "active", filter='AVAILABLE') + row.template_ID(context.view_layer.objects, "active", filter='AVAILABLE') class OBJECT_PT_transform(ObjectButtonsPanel, Panel): @@ -48,25 +48,40 @@ class OBJECT_PT_transform(ObjectButtonsPanel, Panel): def draw(self, context): layout = self.layout + layout.use_property_split = True + col = layout.column() ob = context.object - row = layout.row() + sub = col.row(align=True) + sub.prop(ob, "location") + sub.prop(ob, "lock_location", text="") - row.column().prop(ob, "location") if ob.rotation_mode == 'QUATERNION': - row.column().prop(ob, "rotation_quaternion", text="Rotation") + sub = col.row(align=True) + sub.prop(ob, "rotation_quaternion", text="Rotation") + subsub = sub.column(align=True) + subsub.prop(ob, "lock_rotation_w", text="") + subsub.prop(ob, "lock_rotation", text="") elif ob.rotation_mode == 'AXIS_ANGLE': - #row.column().label(text="Rotation") + # row.column().label(text="Rotation") #row.column().prop(pchan, "rotation_angle", text="Angle") #row.column().prop(pchan, "rotation_axis", text="Axis") - row.column().prop(ob, "rotation_axis_angle", text="Rotation") + sub = col.row(align=True) + sub.prop(ob, "rotation_axis_angle", text="Rotation") + subsub = sub.column(align=True) + subsub.prop(ob, "lock_rotation_w", text="") + subsub.prop(ob, "lock_rotation", text="") else: - row.column().prop(ob, "rotation_euler", text="Rotation") + sub = col.row(align=True) + sub.prop(ob, "rotation_euler", text="Rotation") + sub.prop(ob, "lock_rotation", text="") - row.column().prop(ob, "scale") + sub = col.row(align=True) + sub.prop(ob, "scale") + sub.prop(ob, "lock_scale", text="") - layout.prop(ob, "rotation_mode") + col.prop(ob, "rotation_mode") class OBJECT_PT_delta_transform(ObjectButtonsPanel, Panel): @@ -75,123 +90,81 @@ class OBJECT_PT_delta_transform(ObjectButtonsPanel, Panel): def draw(self, context): layout = self.layout + layout.use_property_split = True ob = context.object - row = layout.row() + col = layout.column() - row.column().prop(ob, "delta_location") + col.column().prop(ob, "delta_location") if ob.rotation_mode == 'QUATERNION': - row.column().prop(ob, "delta_rotation_quaternion", text="Rotation") + col.column().prop(ob, "delta_rotation_quaternion", text="Rotation") elif ob.rotation_mode == 'AXIS_ANGLE': - #row.column().label(text="Rotation") + # row.column().label(text="Rotation") #row.column().prop(pchan, "delta_rotation_angle", text="Angle") #row.column().prop(pchan, "delta_rotation_axis", text="Axis") #row.column().prop(ob, "delta_rotation_axis_angle", text="Rotation") - row.column().label(text="Not for Axis-Angle") + col.column().label(text="Not for Axis-Angle") else: - row.column().prop(ob, "delta_rotation_euler", text="Delta Rotation") + col.column().prop(ob, "delta_rotation_euler", text="Delta Rotation") - row.column().prop(ob, "delta_scale") - - -class OBJECT_PT_transform_locks(ObjectButtonsPanel, Panel): - bl_label = "Transform Locks" - bl_options = {'DEFAULT_CLOSED'} - - def draw(self, context): - layout = self.layout - - ob = context.object - - split = layout.split(percentage=0.1) - - col = split.column(align=True) - col.label(text="") - col.label(text="X:") - col.label(text="Y:") - col.label(text="Z:") - - split.column().prop(ob, "lock_location", text="Location") - split.column().prop(ob, "lock_rotation", text="Rotation") - split.column().prop(ob, "lock_scale", text="Scale") - - if ob.rotation_mode in {'QUATERNION', 'AXIS_ANGLE'}: - row = layout.row() - row.prop(ob, "lock_rotations_4d", text="Lock Rotation") - - sub = row.row() - sub.active = ob.lock_rotations_4d - sub.prop(ob, "lock_rotation_w", text="W") + col.column().prop(ob, "delta_scale") class OBJECT_PT_relations(ObjectButtonsPanel, Panel): bl_label = "Relations" + bl_options = {'DEFAULT_CLOSED'} def draw(self, context): layout = self.layout + layout.use_property_split = True ob = context.object - split = layout.split() + col = layout.column() - col = split.column() - col.prop(ob, "layers") - col.separator() - col.prop(ob, "pass_index") - - col = split.column() - col.label(text="Parent:") - col.prop(ob, "parent", text="") + col.prop(ob, "parent") sub = col.column() - sub.prop(ob, "parent_type", text="") + sub.prop(ob, "parent_type") parent = ob.parent if parent and ob.parent_type == 'BONE' and parent.type == 'ARMATURE': - sub.prop_search(ob, "parent_bone", parent.data, "bones", text="") + sub.prop_search(ob, "parent_bone", parent.data, "bones") sub.active = (parent is not None) + col = col.column() + col.active = (ob.parent is not None) + col.prop(ob, "use_slow_parent") + sub = col.column() + sub.active = (ob.use_slow_parent) + sub.prop(ob, "slow_parent_offset", text="Offset") -class OBJECT_PT_relations_extras(ObjectButtonsPanel, Panel): - bl_label = "Relations Extras" - bl_options = {'DEFAULT_CLOSED'} - - def draw(self, context): - layout = self.layout - - ob = context.object + col.separator() - split = layout.split() + col = layout.column() - if context.scene.render.engine != 'BLENDER_GAME': - col = split.column() - col.label(text="Tracking Axes:") - col.prop(ob, "track_axis", text="Axis") - col.prop(ob, "up_axis", text="Up Axis") + col.prop(ob, "track_axis", text="Tracking Axis") + col.prop(ob, "up_axis", text="Up Axis") - col = split.column() - col.prop(ob, "use_slow_parent") - row = col.row() - row.active = ((ob.parent is not None) and (ob.use_slow_parent)) - row.prop(ob, "slow_parent_offset", text="Offset") + col.separator() - layout.prop(ob, "use_extra_recalc_object") - layout.prop(ob, "use_extra_recalc_data") + col.prop(ob, "pass_index") -class GROUP_MT_specials(Menu): - bl_label = "Group Specials" +class COLLECTION_MT_specials(Menu): + bl_label = "Collection Specials" def draw(self, context): layout = self.layout - layout.operator("object.group_unlink", icon='X') - layout.operator("object.grouped_select") + layout.operator("object.collection_unlink", icon='X') + layout.operator("object.collection_objects_select") layout.operator("object.dupli_offset_from_cursor") -class OBJECT_PT_groups(ObjectButtonsPanel, Panel): - bl_label = "Groups" +class OBJECT_PT_collections(ObjectButtonsPanel, Panel): + bl_label = "Collections" + bl_options = {'DEFAULT_CLOSED'} def draw(self, context): layout = self.layout @@ -199,42 +172,39 @@ class OBJECT_PT_groups(ObjectButtonsPanel, Panel): obj = context.object row = layout.row(align=True) - if bpy.data.groups: - row.operator("object.group_link", text="Add to Group") + if bpy.data.collections: + row.operator("object.collection_link", text="Add to Collection") else: - row.operator("object.group_add", text="Add to Group") - row.operator("object.group_add", text="", icon='ZOOMIN') + row.operator("object.collection_add", text="Add to Collection") + row.operator("object.collection_add", text="", icon='ZOOMIN') obj_name = obj.name - for group in bpy.data.groups: + for collection in bpy.data.collections: # XXX this is slow and stupid!, we need 2 checks, one thats fast # and another that we can be sure its not a name collision # from linked library data - group_objects = group.objects - if obj_name in group.objects and obj in group_objects[:]: + collection_objects = collection.objects + if obj_name in collection.objects and obj in collection_objects[:]: col = layout.column(align=True) - col.context_pointer_set("group", group) + col.context_pointer_set("collection", collection) row = col.box().row() - row.prop(group, "name", text="") - row.operator("object.group_remove", text="", icon='X', emboss=False) - row.menu("GROUP_MT_specials", icon='DOWNARROW_HLT', text="") - - split = col.box().split() - - col = split.column() - col.prop(group, "layers", text="Dupli Visibility") + row.prop(collection, "name", text="") + row.operator("object.collection_remove", text="", icon='X', emboss=False) + row.menu("COLLECTION_MT_specials", icon='DOWNARROW_HLT', text="") - col = split.column() - col.prop(group, "dupli_offset", text="") + row = col.box().row() + row.prop(collection, "dupli_offset", text="") class OBJECT_PT_display(ObjectButtonsPanel, Panel): - bl_label = "Display" + bl_label = "Viewport Display" + bl_options = {'DEFAULT_CLOSED'} def draw(self, context): layout = self.layout + layout.use_property_split = True obj = context.object obj_type = obj.type @@ -243,9 +213,7 @@ class OBJECT_PT_display(ObjectButtonsPanel, Panel): is_empty_image = (obj_type == 'EMPTY' and obj.empty_draw_type == 'IMAGE') is_dupli = (obj.dupli_type != 'NONE') - split = layout.split() - - col = split.column() + col = layout.column(align=True) col.prop(obj, "show_name", text="Name") col.prop(obj, "show_axis", text="Axis") # Makes no sense for cameras, armatures, etc.! @@ -255,39 +223,39 @@ class OBJECT_PT_display(ObjectButtonsPanel, Panel): if obj_type == 'MESH' or is_dupli: col.prop(obj, "show_all_edges") - col = split.column() - row = col.row() - row.prop(obj, "show_bounds", text="Bounds") - sub = row.row() - sub.active = obj.show_bounds - sub.prop(obj, "draw_bounds_type", text="") + col = layout.column() + col.prop(obj, "show_bounds", text="Bounds") + col = layout.column() + col.active = obj.show_bounds + col.prop(obj, "draw_bounds_type") + col = layout.column() if is_geometry: col.prop(obj, "show_texture_space", text="Texture Space") - col.prop(obj, "show_x_ray", text="X-Ray") - if obj_type == 'MESH' or is_empty_image: - col.prop(obj, "show_transparent", text="Transparency") + col.prop(obj.display, "show_shadows", text="Shadow") - split = layout.split() + col.prop(obj, "show_x_ray", text="X-Ray") +# if obj_type == 'MESH' or is_empty_image: + # col.prop(obj, "show_transparent", text="Transparency") - col = split.column() + col = layout.column() if is_wire: # wire objects only use the max. draw type for duplis col.active = is_dupli - col.label(text="Maximum Dupli Draw Type:") - else: - col.label(text="Maximum Draw Type:") - col.prop(obj, "draw_type", text="") + col.prop( + obj, "draw_type", + text="Maximum Dupli Draw Type" if is_wire else "Maximum Dupli Draw Type", + ) - col = split.column() + col = layout.column() if is_geometry or is_empty_image: # Only useful with object having faces/materials... - col.label(text="Object Color:") - col.prop(obj, "color", text="") + col.prop(obj, "color") class OBJECT_PT_duplication(ObjectButtonsPanel, Panel): bl_label = "Duplication" + bl_options = {'DEFAULT_CLOSED'} def draw(self, context): layout = self.layout @@ -296,14 +264,15 @@ class OBJECT_PT_duplication(ObjectButtonsPanel, Panel): layout.row().prop(ob, "dupli_type", expand=True) + layout.use_property_split = True + if ob.dupli_type == 'FRAMES': - split = layout.split() - col = split.column(align=True) + col = layout.column(align=True) col.prop(ob, "dupli_frames_start", text="Start") col.prop(ob, "dupli_frames_end", text="End") - col = split.column(align=True) + col = layout.column(align=True) col.prop(ob, "dupli_frames_on", text="On") col.prop(ob, "dupli_frames_off", text="Off") @@ -313,14 +282,21 @@ class OBJECT_PT_duplication(ObjectButtonsPanel, Panel): layout.prop(ob, "use_dupli_vertices_rotation", text="Rotation") elif ob.dupli_type == 'FACES': - row = layout.row() - row.prop(ob, "use_dupli_faces_scale", text="Scale") - sub = row.row() + col = layout.column() + col.prop(ob, "use_dupli_faces_scale", text="Scale") + sub = col.column() sub.active = ob.use_dupli_faces_scale sub.prop(ob, "dupli_faces_scale", text="Inherit Scale") - elif ob.dupli_type == 'GROUP': - layout.prop(ob, "dupli_group", text="Group") + elif ob.dupli_type == 'COLLECTION': + layout.prop(ob, "dupli_group", text="Collection") + + if ob.dupli_type != 'NONE' or len(ob.particle_systems): + layout.separator() + + col = layout.column(align=True) + col.prop(ob, "show_duplicator_for_viewport") + col.prop(ob, "show_duplicator_for_render") from .properties_animviz import ( @@ -362,7 +338,7 @@ class OBJECT_PT_onion_skinning(OnionSkinButtonsPanel): # , Panel): # inherit fr class OBJECT_PT_custom_props(ObjectButtonsPanel, PropertyPanel, Panel): - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'} _context_path = "object" _property_type = bpy.types.Object @@ -371,11 +347,9 @@ classes = ( OBJECT_PT_context_object, OBJECT_PT_transform, OBJECT_PT_delta_transform, - OBJECT_PT_transform_locks, OBJECT_PT_relations, - OBJECT_PT_relations_extras, - GROUP_MT_specials, - OBJECT_PT_groups, + COLLECTION_MT_specials, + OBJECT_PT_collections, OBJECT_PT_display, OBJECT_PT_duplication, OBJECT_PT_motion_paths, diff --git a/release/scripts/startup/bl_ui/properties_paint_common.py b/release/scripts/startup/bl_ui/properties_paint_common.py index b79f8263e39..bc8bc523e12 100644 --- a/release/scripts/startup/bl_ui/properties_paint_common.py +++ b/release/scripts/startup/bl_ui/properties_paint_common.py @@ -96,8 +96,8 @@ class VIEW3D_MT_tools_projectpaint_clone(Menu): def draw(self, context): layout = self.layout - for i, tex in enumerate(context.active_object.data.uv_textures): - props = layout.operator("wm.context_set_int", text=tex.name, translate=False) + for i, uv_layer in enumerate(context.active_object.data.uv_layers): + props = layout.operator("wm.context_set_int", text=uv_layer.name, translate=False) props.data_path = "active_object.data.uv_texture_clone_index" props.value = i diff --git a/release/scripts/startup/bl_ui/properties_particle.py b/release/scripts/startup/bl_ui/properties_particle.py index 27a19d5636e..f470a81dca1 100644 --- a/release/scripts/startup/bl_ui/properties_particle.py +++ b/release/scripts/startup/bl_ui/properties_particle.py @@ -42,7 +42,7 @@ def particle_panel_enabled(context, psys): def particle_panel_poll(cls, context): psys = context.particle_system - engine = context.scene.render.engine + engine = context.engine settings = 0 if psys: @@ -66,7 +66,7 @@ def particle_get_settings(context): class PARTICLE_MT_specials(Menu): bl_label = "Particle Specials" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'} def draw(self, context): layout = self.layout @@ -86,7 +86,7 @@ class PARTICLE_MT_hair_dynamics_presets(Menu): bl_label = "Hair Dynamics Presets" preset_subdir = "hair_dynamics" preset_operator = "script.execute_preset" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'} draw = Menu.draw_preset @@ -131,20 +131,16 @@ class PARTICLE_UL_particle_systems(bpy.types.UIList): class PARTICLE_PT_context_particles(ParticleButtonsPanel, Panel): bl_label = "" bl_options = {'HIDE_HEADER'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'} @classmethod def poll(cls, context): - engine = context.scene.render.engine + engine = context.engine return (context.particle_system or context.object or context.space_data.pin_id) and (engine in cls.COMPAT_ENGINES) def draw(self, context): layout = self.layout - if context.scene.render.engine == 'BLENDER_GAME': - layout.label("Not available in the Game Engine") - return - ob = context.object psys = context.particle_system part = 0 @@ -238,7 +234,7 @@ class PARTICLE_PT_context_particles(ParticleButtonsPanel, Panel): class PARTICLE_PT_emission(ParticleButtonsPanel, Panel): bl_label = "Emission" - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'} @classmethod def poll(cls, context): @@ -314,12 +310,12 @@ class PARTICLE_PT_emission(ParticleButtonsPanel, Panel): class PARTICLE_PT_hair_dynamics(ParticleButtonsPanel, Panel): bl_label = "Hair Dynamics" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'} @classmethod def poll(cls, context): psys = context.particle_system - engine = context.scene.render.engine + engine = context.engine if psys is None: return False if psys.settings is None: @@ -412,12 +408,12 @@ class PARTICLE_PT_hair_dynamics(ParticleButtonsPanel, Panel): class PARTICLE_PT_cache(ParticleButtonsPanel, Panel): bl_label = "Cache" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'} @classmethod def poll(cls, context): psys = context.particle_system - engine = context.scene.render.engine + engine = context.engine if psys is None: return False if psys.settings is None: @@ -442,7 +438,7 @@ class PARTICLE_PT_cache(ParticleButtonsPanel, Panel): class PARTICLE_PT_velocity(ParticleButtonsPanel, Panel): bl_label = "Velocity" - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'} @classmethod def poll(cls, context): @@ -493,7 +489,7 @@ class PARTICLE_PT_velocity(ParticleButtonsPanel, Panel): class PARTICLE_PT_rotation(ParticleButtonsPanel, Panel): bl_label = "Rotation" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'} @classmethod def poll(cls, context): @@ -556,7 +552,7 @@ class PARTICLE_PT_rotation(ParticleButtonsPanel, Panel): class PARTICLE_PT_physics(ParticleButtonsPanel, Panel): bl_label = "Physics" - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'} @classmethod def poll(cls, context): @@ -792,13 +788,13 @@ class PARTICLE_PT_physics(ParticleButtonsPanel, Panel): class PARTICLE_PT_boidbrain(ParticleButtonsPanel, Panel): bl_label = "Boid Brain" - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'} @classmethod def poll(cls, context): psys = context.particle_system settings = particle_get_settings(context) - engine = context.scene.render.engine + engine = context.engine if settings is None: return False @@ -895,12 +891,12 @@ class PARTICLE_PT_boidbrain(ParticleButtonsPanel, Panel): class PARTICLE_PT_render(ParticleButtonsPanel, Panel): bl_label = "Render" - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'} @classmethod def poll(cls, context): settings = particle_get_settings(context) - engine = context.scene.render.engine + engine = context.engine if settings is None: return False @@ -922,7 +918,6 @@ class PARTICLE_PT_render(ParticleButtonsPanel, Panel): split = layout.split() col = split.column() - col.prop(part, "use_render_emitter") col.prop(part, "use_parent_particles") col = split.column() @@ -966,22 +961,6 @@ class PARTICLE_PT_render(ParticleButtonsPanel, Panel): col.prop(part, "path_end", text="End", slider=not part.use_absolute_path_time) col.prop(part, "length_random", text="Random", slider=True) - row = layout.row() - col = row.column() - - if part.type == 'HAIR' and part.use_strand_primitive is True and part.child_type == 'INTERPOLATED': - layout.prop(part, "use_simplify") - if part.use_simplify is True: - row = layout.row() - row.prop(part, "simplify_refsize") - row.prop(part, "simplify_rate") - row.prop(part, "simplify_transition") - row = layout.row() - row.prop(part, "use_simplify_viewport") - sub = row.row() - sub.active = part.use_simplify_viewport is True - sub.prop(part, "simplify_viewport") - elif part.render_type == 'OBJECT': col.prop(part, "dupli_object") sub = col.row() @@ -1054,8 +1033,8 @@ class PARTICLE_PT_render(ParticleButtonsPanel, Panel): if psys: col = layout.column() - col.prop_search(psys, "billboard_normal_uv", ob.data, "uv_textures") - col.prop_search(psys, "billboard_time_index_uv", ob.data, "uv_textures") + col.prop_search(psys, "billboard_normal_uv", ob.data, "uv_layers") + col.prop_search(psys, "billboard_time_index_uv", ob.data, "uv_layers") split = layout.split(percentage=0.33) split.label(text="Split UVs:") @@ -1064,7 +1043,7 @@ class PARTICLE_PT_render(ParticleButtonsPanel, Panel): if psys: col = layout.column() col.active = part.billboard_uv_split > 1 - col.prop_search(psys, "billboard_split_uv", ob.data, "uv_textures") + col.prop_search(psys, "billboard_split_uv", ob.data, "uv_layers") row = col.row() row.label(text="Animate:") @@ -1095,12 +1074,12 @@ class PARTICLE_PT_render(ParticleButtonsPanel, Panel): class PARTICLE_PT_draw(ParticleButtonsPanel, Panel): bl_label = "Display" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'} @classmethod def poll(cls, context): settings = particle_get_settings(context) - engine = context.scene.render.engine + engine = context.engine if settings is None: return False return engine in cls.COMPAT_ENGINES @@ -1158,7 +1137,7 @@ class PARTICLE_PT_draw(ParticleButtonsPanel, Panel): class PARTICLE_PT_children(ParticleButtonsPanel, Panel): bl_label = "Children" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'} @classmethod def poll(cls, context): @@ -1293,7 +1272,7 @@ class PARTICLE_PT_children(ParticleButtonsPanel, Panel): class PARTICLE_PT_field_weights(ParticleButtonsPanel, Panel): bl_label = "Field Weights" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'} @classmethod def poll(cls, context): @@ -1314,7 +1293,7 @@ class PARTICLE_PT_field_weights(ParticleButtonsPanel, Panel): class PARTICLE_PT_force_fields(ParticleButtonsPanel, Panel): bl_label = "Force Field Settings" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'} def draw(self, context): layout = self.layout @@ -1348,7 +1327,7 @@ class PARTICLE_PT_force_fields(ParticleButtonsPanel, Panel): class PARTICLE_PT_vertexgroups(ParticleButtonsPanel, Panel): bl_label = "Vertex Groups" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'} @classmethod def poll(cls, context): @@ -1417,8 +1396,70 @@ class PARTICLE_PT_vertexgroups(ParticleButtonsPanel, Panel): # row.prop(psys, "invert_vertex_group_field", text="") +class PARTICLE_PT_textures(ParticleButtonsPanel, Panel): + bl_label = "Textures" + bl_options = {'DEFAULT_CLOSED'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'} + + @classmethod + def poll(cls, context): + if context.particle_system is None: + return False + return particle_panel_poll(cls, context) + + def draw(self, context): + layout = self.layout + + psys = context.particle_system + part = psys.settings + + row = layout.row() + row.template_list("TEXTURE_UL_texslots", "", part, "texture_slots", part, "active_texture_index", rows=2) + + col = row.column(align=True) + col.operator("texture.slot_move", text="", icon='TRIA_UP').type = 'UP' + col.operator("texture.slot_move", text="", icon='TRIA_DOWN').type = 'DOWN' + col.menu("TEXTURE_MT_specials", icon='DOWNARROW_HLT', text="") + + if not part.active_texture: + layout.template_ID(part, "active_texture", new="texture.new") + else: + slot = part.texture_slots[part.active_texture_index] + layout.template_ID(slot, "texture", new="texture.new") + + +class PARTICLE_PT_hair_shape(ParticleButtonsPanel, Panel): + bl_label = "Hair Shape" + bl_options = {'DEFAULT_CLOSED'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'} + + @classmethod + def poll(cls, context): + if context.particle_system is None: + return False + return particle_panel_poll(cls, context) + + def draw(self, context): + layout = self.layout + + psys = context.particle_system + part = psys.settings + + row = layout.row() + row.prop(part, "shape", text="Shape") + + layout.label(text="Thickness:") + row = layout.row() + row.prop(part, "root_radius", text="Root") + row.prop(part, "tip_radius", text="Tip") + + row = layout.row() + row.prop(part, "radius_scale", text="Scaling") + row.prop(part, "use_close_tip") + + class PARTICLE_PT_custom_props(ParticleButtonsPanel, PropertyPanel, Panel): - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'} _context_path = "particle_system.settings" _property_type = bpy.types.ParticleSettings @@ -1438,9 +1479,11 @@ classes = ( PARTICLE_PT_render, PARTICLE_PT_draw, PARTICLE_PT_children, + PARTICLE_PT_hair_shape, PARTICLE_PT_field_weights, PARTICLE_PT_force_fields, PARTICLE_PT_vertexgroups, + PARTICLE_PT_textures, PARTICLE_PT_custom_props, ) diff --git a/release/scripts/startup/bl_ui/properties_physics_cloth.py b/release/scripts/startup/bl_ui/properties_physics_cloth.py index bcbb44b2cb3..e0d0327324b 100644 --- a/release/scripts/startup/bl_ui/properties_physics_cloth.py +++ b/release/scripts/startup/bl_ui/properties_physics_cloth.py @@ -45,13 +45,12 @@ class PhysicButtonsPanel: @classmethod def poll(cls, context): ob = context.object - rd = context.scene.render - return (ob and ob.type == 'MESH') and (rd.engine in cls.COMPAT_ENGINES) and (context.cloth) + return (ob and ob.type == 'MESH') and (context.engine in cls.COMPAT_ENGINES) and (context.cloth) class PHYSICS_PT_cloth(PhysicButtonsPanel, Panel): bl_label = "Cloth" - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} def draw(self, context): layout = self.layout @@ -64,6 +63,8 @@ class PHYSICS_PT_cloth(PhysicButtonsPanel, Panel): split = layout.split(percentage=0.25) + col = split.column() + split.label(text="Presets:") sub = split.row(align=True) sub.menu("CLOTH_MT_presets", text=bpy.types.CLOTH_MT_presets.bl_label) @@ -133,7 +134,7 @@ class PHYSICS_PT_cloth(PhysicButtonsPanel, Panel): class PHYSICS_PT_cloth_cache(PhysicButtonsPanel, Panel): bl_label = "Cloth Cache" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} def draw(self, context): md = context.cloth @@ -143,7 +144,7 @@ class PHYSICS_PT_cloth_cache(PhysicButtonsPanel, Panel): class PHYSICS_PT_cloth_collision(PhysicButtonsPanel, Panel): bl_label = "Cloth Collision" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} def draw_header(self, context): cloth = context.cloth.collision_settings @@ -183,7 +184,7 @@ class PHYSICS_PT_cloth_collision(PhysicButtonsPanel, Panel): class PHYSICS_PT_cloth_stiffness(PhysicButtonsPanel, Panel): bl_label = "Cloth Stiffness Scaling" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} def draw_header(self, context): cloth = context.cloth.settings @@ -216,7 +217,7 @@ class PHYSICS_PT_cloth_stiffness(PhysicButtonsPanel, Panel): class PHYSICS_PT_cloth_sewing(PhysicButtonsPanel, Panel): bl_label = "Cloth Sewing Springs" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} def draw_header(self, context): cloth = context.cloth.settings @@ -250,7 +251,7 @@ class PHYSICS_PT_cloth_sewing(PhysicButtonsPanel, Panel): class PHYSICS_PT_cloth_field_weights(PhysicButtonsPanel, Panel): bl_label = "Cloth Field Weights" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} def draw(self, context): cloth = context.cloth.settings diff --git a/release/scripts/startup/bl_ui/properties_physics_common.py b/release/scripts/startup/bl_ui/properties_physics_common.py index 73d3d5fc755..3615f8be48c 100644 --- a/release/scripts/startup/bl_ui/properties_physics_common.py +++ b/release/scripts/startup/bl_ui/properties_physics_common.py @@ -30,8 +30,7 @@ class PhysicButtonsPanel: @classmethod def poll(cls, context): - rd = context.scene.render - return (context.object) and rd.engine in cls.COMPAT_ENGINES + return (context.object) and context.engine in cls.COMPAT_ENGINES def physics_add(self, layout, md, name, type, typeicon, toggles): @@ -57,7 +56,7 @@ def physics_add_special(self, layout, data, name, addop, removeop, typeicon): class PHYSICS_PT_add(PhysicButtonsPanel, Panel): bl_label = "" bl_options = {'HIDE_HEADER'} - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} def draw(self, context): obj = context.object diff --git a/release/scripts/startup/bl_ui/properties_physics_dynamicpaint.py b/release/scripts/startup/bl_ui/properties_physics_dynamicpaint.py index ef426253a69..476a448f978 100644 --- a/release/scripts/startup/bl_ui/properties_physics_dynamicpaint.py +++ b/release/scripts/startup/bl_ui/properties_physics_dynamicpaint.py @@ -55,13 +55,12 @@ class PhysicButtonsPanel: @classmethod def poll(cls, context): ob = context.object - rd = context.scene.render - return (ob and ob.type == 'MESH') and rd.engine in cls.COMPAT_ENGINES and context.dynamic_paint + return (ob and ob.type == 'MESH') and context.engine in cls.COMPAT_ENGINES and context.dynamic_paint class PHYSICS_PT_dynamic_paint(PhysicButtonsPanel, Panel): bl_label = "Dynamic Paint" - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} def draw(self, context): layout = self.layout @@ -109,7 +108,6 @@ class PHYSICS_PT_dynamic_paint(PhysicButtonsPanel, Panel): elif md.ui_type == 'BRUSH': brush = md.brush_settings - use_shading_nodes = context.scene.render.use_shading_nodes if brush is None: layout.operator("dpaint.type_toggle", text="Add Brush").type = 'BRUSH' @@ -124,27 +122,18 @@ class PHYSICS_PT_dynamic_paint(PhysicButtonsPanel, Panel): col.prop(brush, "paint_wetness", text="Wetness") col = split.column() - if not use_shading_nodes: - sub = col.column() - sub.active = (brush.paint_source != 'PARTICLE_SYSTEM') - sub.prop(brush, "use_material") - if brush.use_material and brush.paint_source != 'PARTICLE_SYSTEM' and not use_shading_nodes: - col.prop(brush, "material", text="") - col.prop(brush, "paint_alpha", text="Alpha Factor") - else: - col.prop(brush, "paint_color", text="") - col.prop(brush, "paint_alpha", text="Alpha") + col.prop(brush, "paint_color", text="") + col.prop(brush, "paint_alpha", text="Alpha") class PHYSICS_PT_dp_advanced_canvas(PhysicButtonsPanel, Panel): bl_label = "Dynamic Paint Advanced" - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} @classmethod def poll(cls, context): md = context.dynamic_paint - rd = context.scene.render - return md and md.ui_type == 'CANVAS' and md.canvas_settings and md.canvas_settings.canvas_surfaces.active and rd.engine in cls.COMPAT_ENGINES + return md and md.ui_type == 'CANVAS' and md.canvas_settings and md.canvas_settings.canvas_surfaces.active and context.engine in cls.COMPAT_ENGINES def draw(self, context): layout = self.layout @@ -215,18 +204,17 @@ class PHYSICS_PT_dp_advanced_canvas(PhysicButtonsPanel, Panel): class PHYSICS_PT_dp_canvas_output(PhysicButtonsPanel, Panel): bl_label = "Dynamic Paint Output" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} @classmethod def poll(cls, context): md = context.dynamic_paint - rd = context.scene.render if not (md and md.ui_type == 'CANVAS' and md.canvas_settings): return 0 surface = context.dynamic_paint.canvas_settings.canvas_surfaces.active return (surface and (not (surface.surface_format == 'VERTEX' and (surface.surface_type in {'DISPLACE', 'WAVE'}))) and - (rd.engine in cls.COMPAT_ENGINES)) + (context.engine in cls.COMPAT_ENGINES)) def draw(self, context): layout = self.layout @@ -276,7 +264,7 @@ class PHYSICS_PT_dp_canvas_output(PhysicButtonsPanel, Panel): # image format outputs if surface.surface_format == 'IMAGE': layout.operator("dpaint.bake", text="Bake Image Sequence", icon='MOD_DYNAMICPAINT') - layout.prop_search(surface, "uv_layer", ob.data, "uv_textures", text="UV Map") + layout.prop_search(surface, "uv_layer", ob.data, "uv_layers", text="UV Map") layout.separator() layout.prop(surface, "image_output_path", text="") @@ -309,16 +297,15 @@ class PHYSICS_PT_dp_canvas_output(PhysicButtonsPanel, Panel): class PHYSICS_PT_dp_canvas_initial_color(PhysicButtonsPanel, Panel): bl_label = "Dynamic Paint Initial Color" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} @classmethod def poll(cls, context): md = context.dynamic_paint - rd = context.scene.render if not (md and md.ui_type == 'CANVAS' and md.canvas_settings): return 0 surface = context.dynamic_paint.canvas_settings.canvas_surfaces.active - return (surface and surface.surface_type == 'PAINT') and (rd.engine in cls.COMPAT_ENGINES) + return (surface and surface.surface_type == 'PAINT') and (context.engine in cls.COMPAT_ENGINES) def draw(self, context): layout = self.layout @@ -337,7 +324,7 @@ class PHYSICS_PT_dp_canvas_initial_color(PhysicButtonsPanel, Panel): elif surface.init_color_type == 'TEXTURE': layout.prop(surface, "init_texture") - layout.prop_search(surface, "init_layername", ob.data, "uv_textures", text="UV Map") + layout.prop_search(surface, "init_layername", ob.data, "uv_layers", text="UV Map") elif surface.init_color_type == 'VERTEX_COLOR': layout.prop_search(surface, "init_layername", ob.data, "vertex_colors", text="Color Layer") @@ -346,16 +333,15 @@ class PHYSICS_PT_dp_canvas_initial_color(PhysicButtonsPanel, Panel): class PHYSICS_PT_dp_effects(PhysicButtonsPanel, Panel): bl_label = "Dynamic Paint Effects" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} @classmethod def poll(cls, context): md = context.dynamic_paint - rd = context.scene.render if not (md and md.ui_type == 'CANVAS' and md.canvas_settings): return False surface = context.dynamic_paint.canvas_settings.canvas_surfaces.active - return (surface and surface.surface_type == 'PAINT') and (rd.engine in cls.COMPAT_ENGINES) + return (surface and surface.surface_type == 'PAINT') and (context.engine in cls.COMPAT_ENGINES) def draw(self, context): layout = self.layout @@ -396,18 +382,17 @@ class PHYSICS_PT_dp_effects(PhysicButtonsPanel, Panel): class PHYSICS_PT_dp_cache(PhysicButtonsPanel, Panel): bl_label = "Dynamic Paint Cache" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} @classmethod def poll(cls, context): md = context.dynamic_paint - rd = context.scene.render return (md and md.ui_type == 'CANVAS' and md.canvas_settings and md.canvas_settings.canvas_surfaces.active and md.canvas_settings.canvas_surfaces.active.is_cache_user and - (rd.engine in cls.COMPAT_ENGINES)) + (context.engine in cls.COMPAT_ENGINES)) def draw(self, context): surface = context.dynamic_paint.canvas_settings.canvas_surfaces.active @@ -418,13 +403,12 @@ class PHYSICS_PT_dp_cache(PhysicButtonsPanel, Panel): class PHYSICS_PT_dp_brush_source(PhysicButtonsPanel, Panel): bl_label = "Dynamic Paint Source" - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} @classmethod def poll(cls, context): md = context.dynamic_paint - rd = context.scene.render - return md and md.ui_type == 'BRUSH' and md.brush_settings and (rd.engine in cls.COMPAT_ENGINES) + return md and md.ui_type == 'BRUSH' and md.brush_settings and (context.engine in cls.COMPAT_ENGINES) def draw(self, context): layout = self.layout @@ -472,13 +456,12 @@ class PHYSICS_PT_dp_brush_source(PhysicButtonsPanel, Panel): class PHYSICS_PT_dp_brush_velocity(PhysicButtonsPanel, Panel): bl_label = "Dynamic Paint Velocity" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} @classmethod def poll(cls, context): md = context.dynamic_paint - rd = context.scene.render - return md and md.ui_type == 'BRUSH' and md.brush_settings and (rd.engine in cls.COMPAT_ENGINES) + return md and md.ui_type == 'BRUSH' and md.brush_settings and (context.engine in cls.COMPAT_ENGINES) def draw(self, context): layout = self.layout @@ -509,13 +492,12 @@ class PHYSICS_PT_dp_brush_velocity(PhysicButtonsPanel, Panel): class PHYSICS_PT_dp_brush_wave(PhysicButtonsPanel, Panel): bl_label = "Dynamic Paint Waves" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} @classmethod def poll(cls, context): md = context.dynamic_paint - rd = context.scene.render - return md and md.ui_type == 'BRUSH' and md.brush_settings and (rd.engine in cls.COMPAT_ENGINES) + return md and md.ui_type == 'BRUSH' and md.brush_settings and (context.engine in cls.COMPAT_ENGINES) def draw(self, context): layout = self.layout diff --git a/release/scripts/startup/bl_ui/properties_physics_field.py b/release/scripts/startup/bl_ui/properties_physics_field.py index fb3d1631377..3e3a2145682 100644 --- a/release/scripts/startup/bl_ui/properties_physics_field.py +++ b/release/scripts/startup/bl_ui/properties_physics_field.py @@ -33,19 +33,17 @@ class PhysicButtonsPanel: @classmethod def poll(cls, context): - rd = context.scene.render - return (context.object) and (rd.engine in cls.COMPAT_ENGINES) + return (context.object) and (context.engine in cls.COMPAT_ENGINES) class PHYSICS_PT_field(PhysicButtonsPanel, Panel): bl_label = "Force Fields" - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'} @classmethod def poll(cls, context): ob = context.object - rd = context.scene.render - return (rd.engine in cls.COMPAT_ENGINES) and (ob.field) and (ob.field.type != 'NONE') + return (context.engine in cls.COMPAT_ENGINES) and (ob.field) and (ob.field.type != 'NONE') def draw(self, context): layout = self.layout @@ -177,13 +175,12 @@ class PHYSICS_PT_field(PhysicButtonsPanel, Panel): class PHYSICS_PT_collision(PhysicButtonsPanel, Panel): bl_label = "Collision" - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'} @classmethod def poll(cls, context): ob = context.object - rd = context.scene.render - return (ob and ob.type == 'MESH') and (rd.engine in cls.COMPAT_ENGINES) and (context.collision) + return (ob and ob.type == 'MESH') and (context.engine in cls.COMPAT_ENGINES) and (context.collision) def draw(self, context): layout = self.layout diff --git a/release/scripts/startup/bl_ui/properties_physics_fluid.py b/release/scripts/startup/bl_ui/properties_physics_fluid.py index ab92370f9ae..93f1d28e536 100644 --- a/release/scripts/startup/bl_ui/properties_physics_fluid.py +++ b/release/scripts/startup/bl_ui/properties_physics_fluid.py @@ -37,13 +37,12 @@ class PhysicButtonsPanel: @classmethod def poll(cls, context): ob = context.object - rd = context.scene.render - return (ob and ob.type == 'MESH') and rd.engine in cls.COMPAT_ENGINES and (context.fluid) + return (ob and ob.type == 'MESH') and context.engine in cls.COMPAT_ENGINES and (context.fluid) class PHYSICS_PT_fluid(PhysicButtonsPanel, Panel): bl_label = "Fluid" - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} def draw(self, context): layout = self.layout @@ -206,13 +205,12 @@ class PHYSICS_PT_fluid(PhysicButtonsPanel, Panel): class PHYSICS_PT_domain_gravity(PhysicButtonsPanel, Panel): bl_label = "Fluid World" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} @classmethod def poll(cls, context): md = context.fluid - rd = context.scene.render - return md and md.settings and (md.settings.type == 'DOMAIN') and rd.engine in cls.COMPAT_ENGINES + return md and md.settings and (md.settings.type == 'DOMAIN') and context.engine in cls.COMPAT_ENGINES def draw(self, context): layout = self.layout @@ -260,13 +258,12 @@ class PHYSICS_PT_domain_gravity(PhysicButtonsPanel, Panel): class PHYSICS_PT_domain_boundary(PhysicButtonsPanel, Panel): bl_label = "Fluid Boundary" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} @classmethod def poll(cls, context): md = context.fluid - rd = context.scene.render - return md and md.settings and (md.settings.type == 'DOMAIN') and rd.engine in cls.COMPAT_ENGINES + return md and md.settings and (md.settings.type == 'DOMAIN') and context.engine in cls.COMPAT_ENGINES def draw(self, context): layout = self.layout @@ -291,13 +288,12 @@ class PHYSICS_PT_domain_boundary(PhysicButtonsPanel, Panel): class PHYSICS_PT_domain_particles(PhysicButtonsPanel, Panel): bl_label = "Fluid Particles" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} @classmethod def poll(cls, context): md = context.fluid - rd = context.scene.render - return md and md.settings and (md.settings.type == 'DOMAIN') and rd.engine in cls.COMPAT_ENGINES + return md and md.settings and (md.settings.type == 'DOMAIN') and context.engine in cls.COMPAT_ENGINES def draw(self, context): layout = self.layout diff --git a/release/scripts/startup/bl_ui/properties_physics_rigidbody.py b/release/scripts/startup/bl_ui/properties_physics_rigidbody.py index 6afdd800b88..817b0ab76ed 100644 --- a/release/scripts/startup/bl_ui/properties_physics_rigidbody.py +++ b/release/scripts/startup/bl_ui/properties_physics_rigidbody.py @@ -29,13 +29,13 @@ class PHYSICS_PT_rigidbody_panel: class PHYSICS_PT_rigid_body(PHYSICS_PT_rigidbody_panel, Panel): bl_label = "Rigid Body" - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} @classmethod def poll(cls, context): obj = context.object return (obj and obj.rigid_body and - (context.scene.render.engine in cls.COMPAT_ENGINES)) + (context.engine in cls.COMPAT_ENGINES)) def draw(self, context): layout = self.layout @@ -56,13 +56,13 @@ class PHYSICS_PT_rigid_body(PHYSICS_PT_rigidbody_panel, Panel): class PHYSICS_PT_rigid_body_collisions(PHYSICS_PT_rigidbody_panel, Panel): bl_label = "Rigid Body Collisions" - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} @classmethod def poll(cls, context): obj = context.object return (obj and obj.rigid_body and - (context.scene.render.engine in cls.COMPAT_ENGINES)) + (context.engine in cls.COMPAT_ENGINES)) def draw(self, context): layout = self.layout @@ -101,14 +101,14 @@ class PHYSICS_PT_rigid_body_collisions(PHYSICS_PT_rigidbody_panel, Panel): class PHYSICS_PT_rigid_body_dynamics(PHYSICS_PT_rigidbody_panel, Panel): bl_label = "Rigid Body Dynamics" bl_default_closed = True - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} @classmethod def poll(cls, context): obj = context.object return (obj and obj.rigid_body and obj.rigid_body.type == 'ACTIVE' and - (context.scene.render.engine in cls.COMPAT_ENGINES)) + (context.engine in cls.COMPAT_ENGINES)) def draw(self, context): layout = self.layout diff --git a/release/scripts/startup/bl_ui/properties_physics_rigidbody_constraint.py b/release/scripts/startup/bl_ui/properties_physics_rigidbody_constraint.py index 84a4cbb4b68..aca989fd0ba 100644 --- a/release/scripts/startup/bl_ui/properties_physics_rigidbody_constraint.py +++ b/release/scripts/startup/bl_ui/properties_physics_rigidbody_constraint.py @@ -29,13 +29,12 @@ class PHYSICS_PT_rigidbody_constraint_panel: class PHYSICS_PT_rigid_body_constraint(PHYSICS_PT_rigidbody_constraint_panel, Panel): bl_label = "Rigid Body Constraint" - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} @classmethod def poll(cls, context): ob = context.object - rd = context.scene.render - return (ob and ob.rigid_body_constraint and rd.engine in cls.COMPAT_ENGINES) + return (ob and ob.rigid_body_constraint and context.engine in cls.COMPAT_ENGINES) def draw(self, context): layout = self.layout diff --git a/release/scripts/startup/bl_ui/properties_physics_smoke.py b/release/scripts/startup/bl_ui/properties_physics_smoke.py index 9489fb71e15..ddb898c7881 100644 --- a/release/scripts/startup/bl_ui/properties_physics_smoke.py +++ b/release/scripts/startup/bl_ui/properties_physics_smoke.py @@ -34,13 +34,12 @@ class PhysicButtonsPanel: @classmethod def poll(cls, context): ob = context.object - rd = context.scene.render - return (ob and ob.type == 'MESH') and (rd.engine in cls.COMPAT_ENGINES) and (context.smoke) + return (ob and ob.type == 'MESH') and (context.engine in cls.COMPAT_ENGINES) and (context.smoke) class PHYSICS_PT_smoke(PhysicButtonsPanel, Panel): bl_label = "Smoke" - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} def draw(self, context): layout = self.layout @@ -138,7 +137,7 @@ class PHYSICS_PT_smoke(PhysicButtonsPanel, Panel): class PHYSICS_PT_smoke_flow_advanced(PhysicButtonsPanel, Panel): bl_label = "Smoke Flow Advanced" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} @classmethod def poll(cls, context): @@ -160,7 +159,7 @@ class PHYSICS_PT_smoke_flow_advanced(PhysicButtonsPanel, Panel): sub.label(text="Mapping:") sub.prop(flow, "texture_map_type", expand=False, text="") if flow.texture_map_type == 'UV': - sub.prop_search(flow, "uv_layer", ob.data, "uv_textures", text="") + sub.prop_search(flow, "uv_layer", ob.data, "uv_layers", text="") if flow.texture_map_type == 'AUTO': sub.prop(flow, "texture_size") sub.prop(flow, "texture_offset") @@ -173,7 +172,7 @@ class PHYSICS_PT_smoke_flow_advanced(PhysicButtonsPanel, Panel): class PHYSICS_PT_smoke_fire(PhysicButtonsPanel, Panel): bl_label = "Smoke Flames" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} @classmethod def poll(cls, context): @@ -203,7 +202,7 @@ class PHYSICS_PT_smoke_fire(PhysicButtonsPanel, Panel): class PHYSICS_PT_smoke_adaptive_domain(PhysicButtonsPanel, Panel): bl_label = "Smoke Adaptive Domain" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} @classmethod def poll(cls, context): @@ -237,13 +236,12 @@ class PHYSICS_PT_smoke_adaptive_domain(PhysicButtonsPanel, Panel): class PHYSICS_PT_smoke_highres(PhysicButtonsPanel, Panel): bl_label = "Smoke High Resolution" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} @classmethod def poll(cls, context): md = context.smoke - rd = context.scene.render - return md and (md.smoke_type == 'DOMAIN') and (rd.engine in cls.COMPAT_ENGINES) + return md and (md.smoke_type == 'DOMAIN') and (context.engine in cls.COMPAT_ENGINES) def draw_header(self, context): md = context.smoke.domain_settings @@ -277,13 +275,12 @@ class PHYSICS_PT_smoke_highres(PhysicButtonsPanel, Panel): class PHYSICS_PT_smoke_groups(PhysicButtonsPanel, Panel): bl_label = "Smoke Groups" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} @classmethod def poll(cls, context): md = context.smoke - rd = context.scene.render - return md and (md.smoke_type == 'DOMAIN') and (rd.engine in cls.COMPAT_ENGINES) + return md and (md.smoke_type == 'DOMAIN') and (context.engine in cls.COMPAT_ENGINES) def draw(self, context): layout = self.layout @@ -306,13 +303,12 @@ class PHYSICS_PT_smoke_groups(PhysicButtonsPanel, Panel): class PHYSICS_PT_smoke_cache(PhysicButtonsPanel, Panel): bl_label = "Smoke Cache" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} @classmethod def poll(cls, context): md = context.smoke - rd = context.scene.render - return md and (md.smoke_type == 'DOMAIN') and (rd.engine in cls.COMPAT_ENGINES) + return md and (md.smoke_type == 'DOMAIN') and (context.engine in cls.COMPAT_ENGINES) def draw(self, context): layout = self.layout @@ -343,13 +339,12 @@ class PHYSICS_PT_smoke_cache(PhysicButtonsPanel, Panel): class PHYSICS_PT_smoke_field_weights(PhysicButtonsPanel, Panel): bl_label = "Smoke Field Weights" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} @classmethod def poll(cls, context): md = context.smoke - rd = context.scene.render - return md and (md.smoke_type == 'DOMAIN') and (rd.engine in cls.COMPAT_ENGINES) + return md and (md.smoke_type == 'DOMAIN') and (context.engine in cls.COMPAT_ENGINES) def draw(self, context): domain = context.smoke.domain_settings @@ -363,8 +358,7 @@ class PHYSICS_PT_smoke_display_settings(PhysicButtonsPanel, Panel): @classmethod def poll(cls, context): md = context.smoke - rd = context.scene.render - return md and (md.smoke_type == 'DOMAIN') and (not rd.use_game_engine) + return md and (md.smoke_type == 'DOMAIN') def draw(self, context): domain = context.smoke.domain_settings diff --git a/release/scripts/startup/bl_ui/properties_physics_softbody.py b/release/scripts/startup/bl_ui/properties_physics_softbody.py index 8f193427441..86b9a95e294 100644 --- a/release/scripts/startup/bl_ui/properties_physics_softbody.py +++ b/release/scripts/startup/bl_ui/properties_physics_softbody.py @@ -41,13 +41,12 @@ class PhysicButtonsPanel: @classmethod def poll(cls, context): ob = context.object - rd = context.scene.render - return ob and ob.type in COMPAT_OB_TYPES and rd.engine in cls.COMPAT_ENGINES and context.soft_body + return ob and ob.type in COMPAT_OB_TYPES and context.engine in cls.COMPAT_ENGINES and context.soft_body class PHYSICS_PT_softbody(PhysicButtonsPanel, Panel): bl_label = "Soft Body" - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} def draw(self, context): layout = self.layout @@ -77,7 +76,7 @@ class PHYSICS_PT_softbody(PhysicButtonsPanel, Panel): class PHYSICS_PT_softbody_cache(PhysicButtonsPanel, Panel): bl_label = "Soft Body Cache" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} def draw(self, context): md = context.soft_body @@ -87,7 +86,7 @@ class PHYSICS_PT_softbody_cache(PhysicButtonsPanel, Panel): class PHYSICS_PT_softbody_goal(PhysicButtonsPanel, Panel): bl_label = "Soft Body Goal" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} def draw_header(self, context): softbody = context.soft_body.settings @@ -127,7 +126,7 @@ class PHYSICS_PT_softbody_goal(PhysicButtonsPanel, Panel): class PHYSICS_PT_softbody_edge(PhysicButtonsPanel, Panel): bl_label = "Soft Body Edges" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} def draw_header(self, context): softbody = context.soft_body.settings @@ -177,7 +176,7 @@ class PHYSICS_PT_softbody_edge(PhysicButtonsPanel, Panel): class PHYSICS_PT_softbody_collision(PhysicButtonsPanel, Panel): bl_label = "Soft Body Self Collision" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} def draw_header(self, context): softbody = context.soft_body.settings @@ -206,7 +205,7 @@ class PHYSICS_PT_softbody_collision(PhysicButtonsPanel, Panel): class PHYSICS_PT_softbody_solver(PhysicButtonsPanel, Panel): bl_label = "Soft Body Solver" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} def draw(self, context): layout = self.layout @@ -239,7 +238,7 @@ class PHYSICS_PT_softbody_solver(PhysicButtonsPanel, Panel): class PHYSICS_PT_softbody_field_weights(PhysicButtonsPanel, Panel): bl_label = "Soft Body Field Weights" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} def draw(self, context): md = context.soft_body diff --git a/release/scripts/startup/bl_ui/properties_render.py b/release/scripts/startup/bl_ui/properties_render.py index a5ce345a93c..f1f5ec425e4 100644 --- a/release/scripts/startup/bl_ui/properties_render.py +++ b/release/scripts/startup/bl_ui/properties_render.py @@ -19,7 +19,7 @@ # <pep8 compliant> import bpy -from bpy.types import Menu, Panel +from bpy.types import Menu, Panel, UIList class RENDER_MT_presets(Menu): @@ -51,35 +51,34 @@ class RenderButtonsPanel: @classmethod def poll(cls, context): - scene = context.scene - return scene and (scene.render.engine in cls.COMPAT_ENGINES) + return (context.engine in cls.COMPAT_ENGINES) -class RENDER_PT_render(RenderButtonsPanel, Panel): - bl_label = "Render" - COMPAT_ENGINES = {'BLENDER_RENDER'} +class RENDER_PT_context(Panel): + bl_space_type = 'PROPERTIES' + bl_region_type = 'WINDOW' + bl_context = "render" + bl_options = {'HIDE_HEADER'} + bl_label = "" + + @classmethod + def poll(cls, context): + return context.scene def draw(self, context): layout = self.layout + layout.use_property_split = True - rd = context.scene.render - - row = layout.row(align=True) - row.operator("render.render", text="Render", icon='RENDER_STILL') - row.operator("render.render", text="Animation", icon='RENDER_ANIMATION').animation = True - row.operator("sound.mixdown", text="Audio", icon='PLAY_AUDIO') - - split = layout.split(percentage=0.33) + scene = context.scene + rd = scene.render - split.label(text="Display:") - row = split.row(align=True) - row.prop(rd, "display_mode", text="") - row.prop(rd, "use_lock_interface", icon_only=True) + if rd.has_multiple_engines: + layout.prop(rd, "engine", text="Render Engine") class RENDER_PT_dimensions(RenderButtonsPanel, Panel): bl_label = "Dimensions" - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} _frame_rate_args_prev = None _preset_class = None @@ -127,6 +126,7 @@ class RENDER_PT_dimensions(RenderButtonsPanel, Panel): def draw(self, context): layout = self.layout + layout.use_property_split = True scene = context.scene rd = scene.render @@ -136,228 +136,68 @@ class RENDER_PT_dimensions(RenderButtonsPanel, Panel): row.operator("render.preset_add", text="", icon='ZOOMIN') row.operator("render.preset_add", text="", icon='ZOOMOUT').remove_active = True - split = layout.split() - - col = split.column() - sub = col.column(align=True) - sub.label(text="Resolution:") - sub.prop(rd, "resolution_x", text="X") - sub.prop(rd, "resolution_y", text="Y") - sub.prop(rd, "resolution_percentage", text="") + col = layout.column(align=True) + col.prop(rd, "resolution_x", text="Resolution X") + col.prop(rd, "resolution_y", text="Y") + col.prop(rd, "resolution_percentage", text="%") - sub.label(text="Aspect Ratio:") - sub.prop(rd, "pixel_aspect_x", text="X") - sub.prop(rd, "pixel_aspect_y", text="Y") + col = layout.column(align=True) + col.prop(rd, "pixel_aspect_x", text="Aspect X") + col.prop(rd, "pixel_aspect_y", text="Y") - row = col.row() - row.prop(rd, "use_border", text="Border") - sub = row.row() + col = layout.column(align=True) + col.prop(rd, "use_border", text="Border") + sub = col.column(align=True) sub.active = rd.use_border sub.prop(rd, "use_crop_to_border", text="Crop") - col = split.column() - sub = col.column(align=True) - sub.label(text="Frame Range:") - sub.prop(scene, "frame_start") - sub.prop(scene, "frame_end") - sub.prop(scene, "frame_step") - - sub.label(text="Frame Rate:") - - self.draw_framerate(sub, rd) + col = layout.column(align=True) + col.prop(scene, "frame_start", text="Frame Range Start") + col.prop(scene, "frame_end", text="End") + col.prop(scene, "frame_step", text="Step") - subrow = sub.row(align=True) - subrow.label(text="Time Remapping:") - subrow = sub.row(align=True) - subrow.prop(rd, "frame_map_old", text="Old") - subrow.prop(rd, "frame_map_new", text="New") + col = layout.split(percentage=0.5) + col.alignment = 'RIGHT' + col.label(text="Frame Rate") + self.draw_framerate(col, rd) - -class RENDER_PT_antialiasing(RenderButtonsPanel, Panel): - bl_label = "Anti-Aliasing" - COMPAT_ENGINES = {'BLENDER_RENDER'} - - def draw_header(self, context): - rd = context.scene.render - - self.layout.prop(rd, "use_antialiasing", text="") - - def draw(self, context): - layout = self.layout - - rd = context.scene.render - layout.active = rd.use_antialiasing - - split = layout.split() - - col = split.column() - col.row().prop(rd, "antialiasing_samples", expand=True) - sub = col.row() - sub.prop(rd, "use_full_sample") - - col = split.column() - col.prop(rd, "pixel_filter_type", text="") - col.prop(rd, "filter_size", text="Size") - - -class RENDER_PT_motion_blur(RenderButtonsPanel, Panel): - bl_label = "Sampled Motion Blur" - bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER'} - - @classmethod - def poll(cls, context): - rd = context.scene.render - return not rd.use_full_sample and (rd.engine in cls.COMPAT_ENGINES) - - def draw_header(self, context): - rd = context.scene.render - - self.layout.prop(rd, "use_motion_blur", text="") - - def draw(self, context): - layout = self.layout - - rd = context.scene.render - layout.active = rd.use_motion_blur - - row = layout.row() - row.prop(rd, "motion_blur_samples") - row.prop(rd, "motion_blur_shutter") - - -class RENDER_PT_shading(RenderButtonsPanel, Panel): - bl_label = "Shading" - bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER'} - - def draw(self, context): - layout = self.layout - - rd = context.scene.render - - split = layout.split() - - col = split.column() - col.prop(rd, "use_textures", text="Textures") - col.prop(rd, "use_shadows", text="Shadows") - col.prop(rd, "use_sss", text="Subsurface Scattering") - col.prop(rd, "use_envmaps", text="Environment Map") - - col = split.column() - col.prop(rd, "use_raytrace", text="Ray Tracing") - col.prop(rd, "alpha_mode", text="Alpha") - col.prop(rd, "use_world_space_shading", text="World Space Shading") - - -class RENDER_PT_performance(RenderButtonsPanel, Panel): - bl_label = "Performance" - bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER'} - - def draw(self, context): - layout = self.layout - - rd = context.scene.render - - split = layout.split() - - col = split.column(align=True) - col.label(text="Threads:") - col.row(align=True).prop(rd, "threads_mode", expand=True) - sub = col.column(align=True) - sub.enabled = rd.threads_mode == 'FIXED' - sub.prop(rd, "threads") - - col.label(text="Tile Size:") - col.prop(rd, "tile_x", text="X") - col.prop(rd, "tile_y", text="Y") - - col.separator() - col.prop(rd, "preview_start_resolution") - col.prop(rd, "preview_pixel_size", text="") - - col = split.column() - col.label(text="Memory:") - sub = col.column() - sub.enabled = not rd.use_full_sample - sub.prop(rd, "use_save_buffers") - sub = col.column() - sub.active = rd.use_compositing - sub.prop(rd, "use_free_image_textures") - sub = col.column() - sub.active = rd.use_raytrace - sub.label(text="Acceleration Structure:") - sub.prop(rd, "raytrace_method", text="") - if rd.raytrace_method == 'OCTREE': - sub.prop(rd, "octree_resolution", text="Resolution") - else: - sub.prop(rd, "use_instances", text="Instances") - sub.prop(rd, "use_local_coords", text="Local Coordinates") + col = layout.column(align=True) + col.prop(rd, "frame_map_old", text="Time Remapping Old") + col.prop(rd, "frame_map_new", text="New") class RENDER_PT_post_processing(RenderButtonsPanel, Panel): bl_label = "Post Processing" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} def draw(self, context): layout = self.layout + layout.use_property_split = True rd = context.scene.render - split = layout.split() - - col = split.column() + col = layout.column(align=True) col.prop(rd, "use_compositing") col.prop(rd, "use_sequencer") - split.prop(rd, "dither_intensity", text="Dither", slider=True) - - layout.separator() - - split = layout.split() - - col = split.column() - col.prop(rd, "use_fields", text="Fields") - sub = col.column() - sub.active = rd.use_fields - sub.row().prop(rd, "field_order", expand=True) - sub.prop(rd, "use_fields_still", text="Still") - - col = split.column() - col.prop(rd, "use_edge_enhance") - sub = col.column() - sub.active = rd.use_edge_enhance - sub.prop(rd, "edge_threshold", text="Threshold", slider=True) - sub.prop(rd, "edge_color", text="") + col.prop(rd, "dither_intensity", text="Dither", slider=True) class RENDER_PT_stamp(RenderButtonsPanel, Panel): bl_label = "Metadata" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} def draw(self, context): layout = self.layout + layout.use_property_split = False rd = context.scene.render - layout.prop(rd, "use_stamp") - col = layout.column() - col.active = rd.use_stamp - row = col.row() - row.prop(rd, "stamp_font_size", text="Font Size") - row.prop(rd, "use_stamp_labels", text="Draw Labels") - - 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() + col = split.column(align=True) col.prop(rd, "use_stamp_time", text="Time") col.prop(rd, "use_stamp_date", text="Date") col.prop(rd, "use_stamp_render_time", text="RenderTime") @@ -365,7 +205,7 @@ class RENDER_PT_stamp(RenderButtonsPanel, Panel): col.prop(rd, "use_stamp_scene", text="Scene") col.prop(rd, "use_stamp_memory", text="Memory") - col = split.column() + col = split.column(align=True) col.prop(rd, "use_stamp_camera", text="Camera") col.prop(rd, "use_stamp_lens", text="Lens") col.prop(rd, "use_stamp_filename", text="Filename") @@ -373,22 +213,35 @@ class RENDER_PT_stamp(RenderButtonsPanel, Panel): col.prop(rd, "use_stamp_marker", text="Marker") col.prop(rd, "use_stamp_sequencer_strip", text="Seq. Strip") - row = layout.split(percentage=0.2) + if rd.use_sequencer: + col.prop(rd, "use_stamp_strip_meta", text="Sequence Strip") + + row = layout.split(percentage=0.3) row.prop(rd, "use_stamp_note", text="Note") sub = row.row() sub.active = rd.use_stamp_note sub.prop(rd, "stamp_note_text", text="") - if rd.use_sequencer: - layout.label("Sequencer:") - layout.prop(rd, "use_stamp_strip_meta") + + layout.use_property_split = True + + layout.separator() + + layout.prop(rd, "use_stamp", text="Burn Into Image") + col = layout.column() + col.active = rd.use_stamp + col.prop(rd, "stamp_font_size", text="Font Size") + col.prop(rd, "use_stamp_labels", text="Draw Labels") + col.column().prop(rd, "stamp_foreground", slider=True) + col.column().prop(rd, "stamp_background", slider=True) class RENDER_PT_output(RenderButtonsPanel, Panel): bl_label = "Output" - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} def draw(self, context): layout = self.layout + layout.use_property_split = False rd = context.scene.render image_settings = rd.image_settings @@ -396,17 +249,17 @@ class RENDER_PT_output(RenderButtonsPanel, Panel): layout.prop(rd, "filepath", text="") - split = layout.split() - - col = split.column() - col.active = not rd.is_movie_format - col.prop(rd, "use_overwrite") - col.prop(rd, "use_placeholder") + layout.use_property_split = True - col = split.column() + col = layout.column(align=True) + sub = col.column(align=True) + sub.active = not rd.is_movie_format + sub.prop(rd, "use_overwrite") + sub.prop(rd, "use_placeholder") col.prop(rd, "use_file_extension") col.prop(rd, "use_render_cache") + layout.use_property_split = False layout.template_image_settings(image_settings, color_management=False) if rd.use_multiview: layout.template_image_views(image_settings) @@ -415,7 +268,7 @@ class RENDER_PT_output(RenderButtonsPanel, Panel): class RENDER_PT_encoding(RenderButtonsPanel, Panel): bl_label = "Encoding" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} @classmethod def poll(cls, context): @@ -494,92 +347,437 @@ class RENDER_PT_encoding(RenderButtonsPanel, Panel): col.prop(ffmpeg, "packetsize", text="Packet Size") -class RENDER_PT_bake(RenderButtonsPanel, Panel): - bl_label = "Bake" +class RENDER_UL_renderviews(UIList): + def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index): + 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 RENDER_PT_stereoscopy(RenderButtonsPanel, Panel): + bl_label = "Stereoscopy" + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'} bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} + + def draw_header(self, context): + rd = context.scene.render + self.layout.prop(rd, "use_multiview", text="") def draw(self, context): layout = self.layout - rd = context.scene.render + scene = context.scene + rd = scene.render + rv = rd.views.active - layout.operator("object.bake_image", icon='RENDER_STILL') + layout.active = rd.use_multiview + basic_stereo = rd.views_format == 'STEREO_3D' - layout.prop(rd, "bake_type") + row = layout.row() + row.prop(rd, "views_format", expand=True) - multires_bake = False - if rd.bake_type in ['NORMALS', 'DISPLACEMENT', 'DERIVATIVE', 'AO']: - layout.prop(rd, "use_bake_multires") - multires_bake = rd.use_bake_multires + if basic_stereo: + row = layout.row() + row.template_list("RENDER_UL_renderviews", "name", rd, "stereo_views", rd.views, "active_index", rows=2) - if not multires_bake: - if rd.bake_type == 'NORMALS': - layout.prop(rd, "bake_normal_space") - elif rd.bake_type in {'DISPLACEMENT', 'AO'}: - layout.prop(rd, "use_bake_normalize") + row = layout.row() + row.label(text="File Suffix:") + row.prop(rv, "file_suffix", text="") - # col.prop(rd, "bake_aa_mode") - # col.prop(rd, "use_bake_antialiasing") + else: + row = layout.row() + row.template_list("RENDER_UL_renderviews", "name", rd, "views", rd.views, "active_index", rows=2) - layout.separator() + col = row.column(align=True) + col.operator("scene.render_view_add", icon='ZOOMIN', text="") + col.operator("scene.render_view_remove", icon='ZOOMOUT', text="") - split = layout.split() + row = layout.row() + row.label(text="Camera Suffix:") + row.prop(rv, "camera_suffix", text="") - col = split.column() - col.prop(rd, "use_bake_to_vertex_color") - sub = col.column() - sub.active = not rd.use_bake_to_vertex_color - sub.prop(rd, "use_bake_clear") - sub.prop(rd, "bake_margin") - sub.prop(rd, "bake_quad_split", text="Split") - col = split.column() - col.prop(rd, "use_bake_selected_to_active") - sub = col.column() - sub.active = rd.use_bake_selected_to_active - sub.prop(rd, "bake_distance") - sub.prop(rd, "bake_bias") - else: - split = layout.split() +class RENDER_PT_clay_settings(RenderButtonsPanel, Panel): + bl_label = "Clay Settings" + COMPAT_ENGINES = {'BLENDER_CLAY'} - col = split.column() - col.prop(rd, "use_bake_clear") - col.prop(rd, "bake_margin") + def draw(self, context): + layout = self.layout + props = context.scene.display + + col = layout.column() + col.template_icon_view(props, "matcap_icon") + col.prop(props, "matcap_rotation") + col.prop(props, "matcap_hue") + col.prop(props, "matcap_saturation") + col.prop(props, "matcap_value") + col.prop(props, "matcap_ssao_samples") + col.prop(props, "matcap_ssao_factor_cavity") + col.prop(props, "matcap_ssao_factor_edge") + col.prop(props, "matcap_ssao_distance") + col.prop(props, "matcap_ssao_attenuation") + col.prop(props, "matcap_hair_brightness_randomness") + + +class RENDER_PT_eevee_ambient_occlusion(RenderButtonsPanel, Panel): + bl_label = "Ambient Occlusion" + bl_options = {'DEFAULT_CLOSED'} + COMPAT_ENGINES = {'BLENDER_EEVEE'} - if rd.bake_type == 'DISPLACEMENT': - col = split.column() - col.prop(rd, "use_bake_lores_mesh") + @classmethod + def poll(cls, context): + return (context.engine in cls.COMPAT_ENGINES) - if rd.bake_type == 'AO': - col = split.column() - col.prop(rd, "bake_bias") - col.prop(rd, "bake_samples") + def draw_header(self, context): + scene = context.scene + props = scene.eevee + self.layout.prop(props, "use_gtao", text="") - if rd.bake_type == 'DERIVATIVE': - row = layout.row() - row.prop(rd, "use_bake_user_scale", text="") + def draw(self, context): + layout = self.layout + layout.use_property_split = True + scene = context.scene + props = scene.eevee + + layout.active = props.use_gtao + col = layout.column() + col.prop(props, "use_gtao_bent_normals") + col.prop(props, "use_gtao_bounce") + col.prop(props, "gtao_distance") + col.prop(props, "gtao_factor") + col.prop(props, "gtao_quality") - sub = row.column() - sub.active = rd.use_bake_user_scale - sub.prop(rd, "bake_user_scale", text="User Scale") + +class RENDER_PT_eevee_motion_blur(RenderButtonsPanel, Panel): + bl_label = "Motion Blur" + bl_options = {'DEFAULT_CLOSED'} + COMPAT_ENGINES = {'BLENDER_EEVEE'} + + @classmethod + def poll(cls, context): + return (context.engine in cls.COMPAT_ENGINES) + + def draw_header(self, context): + scene = context.scene + props = scene.eevee + self.layout.prop(props, "use_motion_blur", text="") + + def draw(self, context): + layout = self.layout + layout.use_property_split = True + scene = context.scene + props = scene.eevee + + layout.active = props.use_motion_blur + col = layout.column() + col.prop(props, "motion_blur_samples") + col.prop(props, "motion_blur_shutter") + + +class RENDER_PT_eevee_depth_of_field(RenderButtonsPanel, Panel): + bl_label = "Depth of Field" + bl_options = {'DEFAULT_CLOSED'} + COMPAT_ENGINES = {'BLENDER_EEVEE'} + + @classmethod + def poll(cls, context): + return (context.engine in cls.COMPAT_ENGINES) + + def draw_header(self, context): + scene = context.scene + props = scene.eevee + self.layout.prop(props, "use_dof", text="") + + def draw(self, context): + layout = self.layout + layout.use_property_split = True + scene = context.scene + props = scene.eevee + + layout.active = props.use_dof + col = layout.column() + col.prop(props, "bokeh_max_size") + col.prop(props, "bokeh_threshold") + + +class RENDER_PT_eevee_bloom(RenderButtonsPanel, Panel): + bl_label = "Bloom" + bl_options = {'DEFAULT_CLOSED'} + COMPAT_ENGINES = {'BLENDER_EEVEE'} + + @classmethod + def poll(cls, context): + return (context.engine in cls.COMPAT_ENGINES) + + def draw_header(self, context): + scene = context.scene + props = scene.eevee + self.layout.prop(props, "use_bloom", text="") + + def draw(self, context): + layout = self.layout + layout.use_property_split = True + + scene = context.scene + props = scene.eevee + + layout.active = props.use_bloom + col = layout.column() + col.prop(props, "bloom_threshold") + col.prop(props, "bloom_knee") + col.prop(props, "bloom_radius") + col.prop(props, "bloom_color") + col.prop(props, "bloom_intensity") + col.prop(props, "bloom_clamp") + + +class RENDER_PT_eevee_volumetric(RenderButtonsPanel, Panel): + bl_label = "Volumetric" + bl_options = {'DEFAULT_CLOSED'} + COMPAT_ENGINES = {'BLENDER_EEVEE'} + + @classmethod + def poll(cls, context): + return (context.engine in cls.COMPAT_ENGINES) + + def draw_header(self, context): + scene = context.scene + props = scene.eevee + self.layout.prop(props, "use_volumetric", text="") + + def draw(self, context): + layout = self.layout + layout.use_property_split = True + + scene = context.scene + props = scene.eevee + + layout.active = props.use_volumetric + col = layout.column() + sub = col.column(align=True) + sub.prop(props, "volumetric_start") + sub.prop(props, "volumetric_end") + col.prop(props, "volumetric_tile_size") + col.separator() + col.prop(props, "volumetric_samples") + sub.prop(props, "volumetric_sample_distribution") + col.separator() + col.prop(props, "use_volumetric_lights") + + sub = col.column() + sub.active = props.use_volumetric_lights + sub.prop(props, "volumetric_light_clamp", text="Light Clamping") + col.separator() + col.prop(props, "use_volumetric_shadows") + sub = col.column() + sub.active = props.use_volumetric_shadows + sub.prop(props, "volumetric_shadow_samples", text="Shadow Samples") + col.separator() + col.prop(props, "use_volumetric_colored_transmittance") + + +class RENDER_PT_eevee_subsurface_scattering(RenderButtonsPanel, Panel): + bl_label = "Subsurface Scattering" + bl_options = {'DEFAULT_CLOSED'} + COMPAT_ENGINES = {'BLENDER_EEVEE'} + + @classmethod + def poll(cls, context): + return (context.engine in cls.COMPAT_ENGINES) + + def draw_header(self, context): + scene = context.scene + props = scene.eevee + self.layout.prop(props, "use_sss", text="") + + def draw(self, context): + layout = self.layout + layout.use_property_split = True + + scene = context.scene + props = scene.eevee + + layout.active = props.use_sss + + col = layout.column() + col.prop(props, "sss_samples") + col.prop(props, "sss_jitter_threshold") + col.prop(props, "use_sss_separate_albedo") + + +class RENDER_PT_eevee_screen_space_reflections(RenderButtonsPanel, Panel): + bl_label = "Screen Space Reflections" + bl_options = {'DEFAULT_CLOSED'} + COMPAT_ENGINES = {'BLENDER_EEVEE'} + + @classmethod + def poll(cls, context): + return (context.engine in cls.COMPAT_ENGINES) + + def draw_header(self, context): + scene = context.scene + props = scene.eevee + self.layout.prop(props, "use_ssr", text="") + + def draw(self, context): + layout = self.layout + layout.use_property_split = True + + scene = context.scene + props = scene.eevee + + col = layout.column() + col.active = props.use_ssr + col.prop(props, "use_ssr_refraction", text="Refraction") + col.prop(props, "use_ssr_halfres") + col.prop(props, "ssr_quality") + col.prop(props, "ssr_max_roughness") + col.prop(props, "ssr_thickness") + col.prop(props, "ssr_border_fade") + col.prop(props, "ssr_firefly_fac") + + +class RENDER_PT_eevee_shadows(RenderButtonsPanel, Panel): + bl_label = "Shadows" + bl_options = {'DEFAULT_CLOSED'} + COMPAT_ENGINES = {'BLENDER_EEVEE'} + + @classmethod + def poll(cls, context): + return (context.engine in cls.COMPAT_ENGINES) + + def draw(self, context): + layout = self.layout + layout.use_property_split = True + + scene = context.scene + props = scene.eevee + + col = layout.column() + col.prop(props, "shadow_method") + col.prop(props, "shadow_cube_size") + col.prop(props, "shadow_cascade_size") + col.prop(props, "use_shadow_high_bitdepth") + + +class RENDER_PT_eevee_sampling(RenderButtonsPanel, Panel): + bl_label = "Sampling" + bl_options = {'DEFAULT_CLOSED'} + COMPAT_ENGINES = {'BLENDER_EEVEE'} + + @classmethod + def poll(cls, context): + return (context.engine in cls.COMPAT_ENGINES) + + def draw(self, context): + layout = self.layout + layout.use_property_split = True + + scene = context.scene + props = scene.eevee + + col = layout.column() + col.prop(props, "taa_samples") + col.prop(props, "taa_render_samples") + col.prop(props, "use_taa_reprojection") + + +class RENDER_PT_eevee_indirect_lighting(RenderButtonsPanel, Panel): + bl_label = "Indirect Lighting" + bl_options = {'DEFAULT_CLOSED'} + COMPAT_ENGINES = {'BLENDER_EEVEE'} + + @classmethod + def poll(cls, context): + return (context.engine in cls.COMPAT_ENGINES) + + def draw(self, context): + layout = self.layout + layout.use_property_split = True + + scene = context.scene + props = scene.eevee + + col = layout.column() + col.prop(props, "gi_diffuse_bounces") + col.prop(props, "gi_cubemap_resolution") + col.prop(props, "gi_visibility_resolution") + + +class RENDER_PT_eevee_film(RenderButtonsPanel, Panel): + bl_label = "Film" + bl_options = {'DEFAULT_CLOSED'} + COMPAT_ENGINES = {'BLENDER_EEVEE'} + + @classmethod + def poll(cls, context): + return (context.engine in cls.COMPAT_ENGINES) + + def draw(self, context): + layout = self.layout + layout.use_property_split = True + + scene = context.scene + rd = scene.render + + col = layout.column() + col.prop(rd, "filter_size") + col.prop(rd, "alpha_mode", text="Alpha") + + +class RENDER_PT_hair(RenderButtonsPanel, Panel): + bl_label = "Hair" + bl_options = {'DEFAULT_CLOSED'} + COMPAT_ENGINES = {'BLENDER_EEVEE'} + + @classmethod + def poll(cls, context): + return (context.engine in cls.COMPAT_ENGINES) + + def draw(self, context): + layout = self.layout + scene = context.scene + rd = scene.render + + row = layout.row() + row.prop(rd, "hair_type", expand=True) + + layout.prop(rd, "hair_subdiv") classes = ( RENDER_MT_presets, RENDER_MT_ffmpeg_presets, RENDER_MT_framerate_presets, - RENDER_PT_render, + RENDER_PT_context, RENDER_PT_dimensions, - RENDER_PT_antialiasing, - RENDER_PT_motion_blur, - RENDER_PT_shading, - RENDER_PT_performance, RENDER_PT_post_processing, - RENDER_PT_stamp, RENDER_PT_output, RENDER_PT_encoding, - RENDER_PT_bake, + RENDER_PT_stamp, + RENDER_UL_renderviews, + RENDER_PT_stereoscopy, + RENDER_PT_hair, + RENDER_PT_clay_settings, + RENDER_PT_eevee_sampling, + RENDER_PT_eevee_film, + RENDER_PT_eevee_shadows, + RENDER_PT_eevee_indirect_lighting, + RENDER_PT_eevee_subsurface_scattering, + RENDER_PT_eevee_screen_space_reflections, + RENDER_PT_eevee_ambient_occlusion, + RENDER_PT_eevee_volumetric, + RENDER_PT_eevee_motion_blur, + RENDER_PT_eevee_depth_of_field, + RENDER_PT_eevee_bloom, ) if __name__ == "__main__": # only for live edit. diff --git a/release/scripts/startup/bl_ui/properties_render_layer.py b/release/scripts/startup/bl_ui/properties_render_layer.py deleted file mode 100644 index 084bc387822..00000000000 --- a/release/scripts/startup/bl_ui/properties_render_layer.py +++ /dev/null @@ -1,242 +0,0 @@ -# ##### BEGIN GPL LICENSE BLOCK ##### -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -# -# ##### END GPL LICENSE BLOCK ##### - -# <pep8 compliant> -import bpy -from bpy.types import Panel, UIList - - -class RenderLayerButtonsPanel: - bl_space_type = 'PROPERTIES' - bl_region_type = 'WINDOW' - bl_context = "render_layer" - # COMPAT_ENGINES must be defined in each subclass, external engines can add themselves here - - @classmethod - def poll(cls, context): - scene = context.scene - return scene and (scene.render.engine in cls.COMPAT_ENGINES) - - -class RENDERLAYER_UL_renderlayers(UIList): - def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index): - # assert(isinstance(item, bpy.types.SceneRenderLayer) - layer = item - 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 == 'GRID': - layout.alignment = 'CENTER' - layout.label("", icon_value=icon) - - -class RENDERLAYER_PT_layers(RenderLayerButtonsPanel, Panel): - bl_label = "Layer List" - bl_options = {'HIDE_HEADER'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} - - def draw(self, context): - layout = self.layout - - scene = context.scene - rd = scene.render - - if rd.engine == 'BLENDER_GAME': - layout.label("Not available in the Game Engine") - return - - row = layout.row() - col = row.column() - col.template_list("RENDERLAYER_UL_renderlayers", "", rd, "layers", rd.layers, "active_index", rows=2) - - col = row.column() - sub = col.column(align=True) - sub.operator("scene.render_layer_add", icon='ZOOMIN', text="") - sub.operator("scene.render_layer_remove", icon='ZOOMOUT', text="") - col.prop(rd, "use_single_layer", icon_only=True) - - -class RENDERLAYER_PT_layer_options(RenderLayerButtonsPanel, Panel): - bl_label = "Layer" - COMPAT_ENGINES = {'BLENDER_RENDER'} - - def draw(self, context): - layout = self.layout - - scene = context.scene - rd = scene.render - rl = rd.layers.active - - split = layout.split() - - col = split.column() - col.prop(scene, "layers", text="Scene") - col.label(text="") - col.prop(rl, "light_override", text="Lights") - col.prop(rl, "material_override", text="Material") - - col = split.column() - col.prop(rl, "layers", text="Layer") - col.prop(rl, "layers_zmask", text="Mask Layer") - - layout.separator() - layout.label(text="Include:") - - split = layout.split() - - col = split.column() - col.prop(rl, "use_zmask") - row = col.row() - row.prop(rl, "invert_zmask", text="Negate") - row.active = rl.use_zmask - col.prop(rl, "use_all_z") - - col = split.column() - col.prop(rl, "use_solid") - col.prop(rl, "use_halo") - col.prop(rl, "use_ztransp") - - col = split.column() - col.prop(rl, "use_sky") - col.prop(rl, "use_edge_enhance") - col.prop(rl, "use_strand") - if bpy.app.build_options.freestyle: - row = col.row() - row.prop(rl, "use_freestyle") - row.active = rd.use_freestyle - - -class RENDERLAYER_PT_layer_passes(RenderLayerButtonsPanel, Panel): - bl_label = "Passes" - bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER'} - - @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 - # draw pass type buttons - row = box.row() - row.prop(rl, use_pass_type) - row.prop(rl, exclude_pass_type, text="") - - def draw(self, context): - layout = self.layout - - scene = context.scene - rd = scene.render - rl = rd.layers.active - - split = layout.split() - - col = split.column() - col.prop(rl, "use_pass_combined") - col.prop(rl, "use_pass_z") - col.prop(rl, "use_pass_vector") - col.prop(rl, "use_pass_normal") - col.prop(rl, "use_pass_uv") - col.prop(rl, "use_pass_mist") - col.prop(rl, "use_pass_object_index") - col.prop(rl, "use_pass_material_index") - col.prop(rl, "use_pass_color") - - col = split.column() - col.prop(rl, "use_pass_diffuse") - self.draw_pass_type_buttons(col, rl, "specular") - self.draw_pass_type_buttons(col, rl, "shadow") - self.draw_pass_type_buttons(col, rl, "emit") - self.draw_pass_type_buttons(col, rl, "ambient_occlusion") - self.draw_pass_type_buttons(col, rl, "environment") - self.draw_pass_type_buttons(col, rl, "indirect") - self.draw_pass_type_buttons(col, rl, "reflection") - 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'} - bl_options = {'DEFAULT_CLOSED'} - - 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="") - - -classes = ( - RENDERLAYER_UL_renderlayers, - RENDERLAYER_PT_layers, - RENDERLAYER_PT_layer_options, - RENDERLAYER_PT_layer_passes, - RENDERLAYER_UL_renderviews, - RENDERLAYER_PT_views, -) - -if __name__ == "__main__": # only for live edit. - from bpy.utils import register_class - for cls in classes: - register_class(cls) diff --git a/release/scripts/startup/bl_ui/properties_scene.py b/release/scripts/startup/bl_ui/properties_scene.py index db7fd998d4e..731a4586e42 100644 --- a/release/scripts/startup/bl_ui/properties_scene.py +++ b/release/scripts/startup/bl_ui/properties_scene.py @@ -19,10 +19,10 @@ # <pep8 compliant> import bpy from bpy.types import ( - Menu, - Panel, - UIList, - ) + Menu, + Panel, + UIList, +) from rna_prop_ui import PropertyPanel @@ -60,28 +60,26 @@ class SceneButtonsPanel: @classmethod def poll(cls, context): - rd = context.scene.render - return context.scene and (rd.engine in cls.COMPAT_ENGINES) + return (context.engine in cls.COMPAT_ENGINES) class SCENE_PT_scene(SceneButtonsPanel, Panel): bl_label = "Scene" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'} def draw(self, context): layout = self.layout - + layout.use_property_split = True scene = context.scene layout.prop(scene, "camera") - layout.prop(scene, "background_set", text="Background") - if context.scene.render.engine != 'BLENDER_GAME': - layout.prop(scene, "active_clip", text="Active Clip") + layout.prop(scene, "background_set") + layout.prop(scene, "active_clip") class SCENE_PT_unit(SceneButtonsPanel, Panel): bl_label = "Units" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'} def draw(self, context): layout = self.layout @@ -93,23 +91,18 @@ class SCENE_PT_unit(SceneButtonsPanel, Panel): row.operator("scene.units_length_preset_add", text="", icon='ZOOMIN') row.operator("scene.units_length_preset_add", text="", icon='ZOOMOUT').remove_active = True - layout.separator() + layout.use_property_split = True + + col = layout.column() + col.prop(unit, "system") - split = layout.split(percentage=0.35) - split.label("Length:") - split.prop(unit, "system", text="") - split = layout.split(percentage=0.35) - split.label("Angle:") - split.prop(unit, "system_rotation", text="") + col = layout.column() + col.prop(unit, "system_rotation") col = layout.column() col.enabled = unit.system != 'NONE' - split = col.split(percentage=0.35) - split.label("Unit Scale:") - split.prop(unit, "scale_length", text="") - split = col.split(percentage=0.35) - split.row() - split.prop(unit, "use_separate") + col.prop(unit, "scale_length") + col.prop(unit, "use_separate") class SceneKeyingSetsPanel: @@ -117,18 +110,19 @@ class SceneKeyingSetsPanel: @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") - + context, layout, ks, ksp, "Needed", + "use_insertkey_override_needed", "use_insertkey_needed", + userpref_fallback="use_keyframe_insert_needed", + ) SceneKeyingSetsPanel._draw_keyframing_setting( - context, layout, ks, ksp, "Visual", - "use_insertkey_override_visual", "use_insertkey_visual", - userpref_fallback="use_visual_keying") - + context, layout, ks, ksp, "Visual", + "use_insertkey_override_visual", "use_insertkey_visual", + userpref_fallback="use_visual_keying", + ) SceneKeyingSetsPanel._draw_keyframing_setting( - context, layout, ks, ksp, "XYZ to RGB", - "use_insertkey_override_xyz_to_rgb", "use_insertkey_xyz_to_rgb") + 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): @@ -166,7 +160,7 @@ class SceneKeyingSetsPanel: class SCENE_PT_keying_sets(SceneButtonsPanel, SceneKeyingSetsPanel, Panel): bl_label = "Keying Sets" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'} def draw(self, context): layout = self.layout @@ -199,7 +193,8 @@ class SCENE_PT_keying_sets(SceneButtonsPanel, SceneKeyingSetsPanel, Panel): class SCENE_PT_keying_set_paths(SceneButtonsPanel, SceneKeyingSetsPanel, Panel): bl_label = "Active Keying Set" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} + bl_options = {'DEFAULT_CLOSED'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'} @classmethod def poll(cls, context): @@ -256,84 +251,85 @@ class SCENE_PT_keying_set_paths(SceneButtonsPanel, SceneKeyingSetsPanel, Panel): class SCENE_PT_color_management(SceneButtonsPanel, Panel): bl_label = "Color Management" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'} def draw(self, context): layout = self.layout + layout.use_property_split = True scene = context.scene col = layout.column() - col.label(text="Display:") col.prop(scene.display_settings, "display_device") - col = layout.column() col.separator() - col.label(text="Render:") - col.template_colormanaged_view_settings(scene, "view_settings") col = layout.column() + col.template_colormanaged_view_settings(scene, "view_settings") + col.separator() - col.label(text="Sequencer:") - col.prop(scene.sequencer_colorspace_settings, "name") + col = layout.column() + col.prop(scene.sequencer_colorspace_settings, "name", text="Sequencer Color Space") class SCENE_PT_audio(SceneButtonsPanel, Panel): bl_label = "Audio" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'} def draw(self, context): layout = self.layout + layout.use_property_split = True scene = context.scene rd = context.scene.render ffmpeg = rd.ffmpeg layout.prop(scene, "audio_volume") - layout.operator("sound.bake_animation") - split = layout.split() + col = layout.column() + col.prop(scene, "audio_distance_model") + + col.prop(ffmpeg, "audio_channels") + col.prop(ffmpeg, "audio_mixrate", text="Sample Rate") + + layout.separator() + + col = layout.column(align=True) + col.prop(scene, "audio_doppler_speed", text="Doppler Speed") + col.prop(scene, "audio_doppler_factor", text="Doppler Factor") - col = split.column() - col.label("Distance Model:") - col.prop(scene, "audio_distance_model", text="") - sub = col.column(align=True) - sub.prop(scene, "audio_doppler_speed", text="Speed") - sub.prop(scene, "audio_doppler_factor", text="Doppler") + layout.separator() - col = split.column() - col.label("Format:") - col.prop(ffmpeg, "audio_channels", text="") - col.prop(ffmpeg, "audio_mixrate", text="Rate") + layout.operator("sound.bake_animation") class SCENE_PT_physics(SceneButtonsPanel, Panel): bl_label = "Gravity" - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} def draw_header(self, context): self.layout.prop(context.scene, "use_gravity", text="") def draw(self, context): layout = self.layout + layout.use_property_split = True scene = context.scene layout.active = scene.use_gravity - layout.prop(scene, "gravity", text="") + layout.prop(scene, "gravity") class SCENE_PT_rigid_body_world(SceneButtonsPanel, Panel): bl_label = "Rigid Body World" - COMPAT_ENGINES = {'BLENDER_RENDER'} + bl_options = {'DEFAULT_CLOSED'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} @classmethod def poll(cls, context): - scene = context.scene - rd = scene.render - return scene and (rd.engine in cls.COMPAT_ENGINES) + return (context.engine in cls.COMPAT_ENGINES) def draw_header(self, context): scene = context.scene @@ -374,13 +370,12 @@ class SCENE_PT_rigid_body_world(SceneButtonsPanel, Panel): class SCENE_PT_rigid_body_cache(SceneButtonsPanel, Panel): bl_label = "Rigid Body Cache" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} @classmethod def poll(cls, context): - rd = context.scene.render scene = context.scene - return scene and scene.rigidbody_world and (rd.engine in cls.COMPAT_ENGINES) + return scene and scene.rigidbody_world and (context.engine in cls.COMPAT_ENGINES) def draw(self, context): scene = context.scene @@ -392,13 +387,12 @@ class SCENE_PT_rigid_body_cache(SceneButtonsPanel, Panel): class SCENE_PT_rigid_body_field_weights(SceneButtonsPanel, Panel): bl_label = "Rigid Body Field Weights" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} @classmethod def poll(cls, context): - rd = context.scene.render scene = context.scene - return scene and scene.rigidbody_world and (rd.engine in cls.COMPAT_ENGINES) + return scene and scene.rigidbody_world and (context.engine in cls.COMPAT_ENGINES) def draw(self, context): scene = context.scene @@ -409,7 +403,8 @@ class SCENE_PT_rigid_body_field_weights(SceneButtonsPanel, Panel): class SCENE_PT_simplify(SceneButtonsPanel, Panel): bl_label = "Simplify" - COMPAT_ENGINES = {'BLENDER_RENDER'} + bl_options = {'DEFAULT_CLOSED'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'} def draw_header(self, context): rd = context.scene.render @@ -417,29 +412,42 @@ class SCENE_PT_simplify(SceneButtonsPanel, Panel): def draw(self, context): layout = self.layout + layout.use_property_split = True rd = context.scene.render layout.active = rd.use_simplify - split = layout.split() + col = layout.column() + col.prop(rd, "simplify_subdivision", text="Max Viewport Subdivision") + col.prop(rd, "simplify_child_particles", text="Max Child Particles") - col = split.column() - col.label(text="Viewport:") - col.prop(rd, "simplify_subdivision", text="Subdivision") - col.prop(rd, "simplify_child_particles", text="Child Particles") + col.separator() - 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") + col = layout.column() + col.prop(rd, "simplify_subdivision_render", text="Max Render Subdivision") + col.prop(rd, "simplify_child_particles_render", text="Max Child Particles") + + +class SCENE_PT_viewport_display(SceneButtonsPanel, Panel): + bl_label = "Viewport Display" + bl_options = {'DEFAULT_CLOSED'} + + @classmethod + def poll(cls, context): + return True + + def draw(self, context): + layout = self.layout + layout.use_property_split = True + scene = context.scene + col = layout.column() + col.prop(scene.display, "light_direction") + col.prop(scene.display, "shadow_shift") class SCENE_PT_custom_props(SceneButtonsPanel, PropertyPanel, Panel): - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'} _context_path = "scene" _property_type = bpy.types.Scene @@ -452,6 +460,7 @@ classes = ( SCENE_PT_keying_sets, SCENE_PT_keying_set_paths, SCENE_PT_color_management, + SCENE_PT_viewport_display, SCENE_PT_audio, SCENE_PT_physics, SCENE_PT_rigid_body_world, diff --git a/release/scripts/startup/bl_ui/properties_texture.py b/release/scripts/startup/bl_ui/properties_texture.py index 2f977088ad7..b7dc8ec9d4e 100644 --- a/release/scripts/startup/bl_ui/properties_texture.py +++ b/release/scripts/startup/bl_ui/properties_texture.py @@ -23,12 +23,9 @@ from bpy.types import Menu, Panel, UIList from bpy.types import ( Brush, FreestyleLineStyle, - Lamp, - Material, Object, ParticleSettings, Texture, - World, ) from rna_prop_ui import PropertyPanel @@ -38,7 +35,7 @@ from .properties_paint_common import brush_texture_settings class TEXTURE_MT_specials(Menu): bl_label = "Texture Specials" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} + COMPAT_ENGINES = {'BLENDER_RENDER'} def draw(self, context): layout = self.layout @@ -47,22 +44,9 @@ class TEXTURE_MT_specials(Menu): layout.operator("texture.slot_paste", icon='PASTEDOWN') -class TEXTURE_MT_envmap_specials(Menu): - bl_label = "Environment Map Specials" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} - - def draw(self, context): - layout = self.layout - - layout.operator("texture.envmap_save", icon='IMAGEFILE') - layout.operator("texture.envmap_clear", icon='FILE_REFRESH') - layout.operator("texture.envmap_clear_all", icon='FILE_REFRESH') - - class TEXTURE_UL_texslots(UIList): def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index): - # assert(isinstance(item, bpy.types.MaterialTextureSlot) ma = data slot = item tex = slot.texture if slot else None @@ -71,29 +55,11 @@ class TEXTURE_UL_texslots(UIList): layout.prop(tex, "name", text="", emboss=False, icon_value=icon) else: 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 == 'GRID': layout.alignment = 'CENTER' layout.label(text="", icon_value=icon) - -from .properties_material import active_node_mat - - def context_tex_datablock(context): - idblock = context.material - if idblock: - return active_node_mat(idblock) - - idblock = context.lamp - if idblock: - return idblock - - idblock = context.world - if idblock: - return idblock - idblock = context.brush if idblock: return idblock @@ -108,151 +74,138 @@ def context_tex_datablock(context): return idblock -def id_tex_datablock(bid): - if isinstance(bid, Object): - if bid.type == 'LAMP': - return bid.data - return bid.active_material - - return bid - - class TextureButtonsPanel: bl_space_type = 'PROPERTIES' bl_region_type = 'WINDOW' bl_context = "texture" + +class TEXTURE_PT_preview(TextureButtonsPanel, Panel): + bl_label = "Preview" + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + @classmethod def poll(cls, context): tex = context.texture - return tex and (tex.type != 'NONE' or tex.use_nodes) and (context.scene.render.engine in cls.COMPAT_ENGINES) + return tex and (tex.type != 'NONE' or tex.use_nodes) and (context.engine in cls.COMPAT_ENGINES) + + def draw(self, context): + layout = self.layout + + tex = context.texture + slot = getattr(context, "texture_slot", None) + idblock = context_tex_datablock(context) + + if idblock: + layout.template_preview(tex, parent=idblock, slot=slot) + else: + layout.template_preview(tex, slot=slot) + # Show Alpha Button for Brush Textures, see #29502 + idblock = context_tex_datablock(context) + if isinstance(idblock, Brush): + layout.prop(tex, "use_preview_alpha") -class TEXTURE_PT_context_texture(TextureButtonsPanel, Panel): +class TEXTURE_PT_context(TextureButtonsPanel, Panel): bl_label = "" + bl_context = "texture" bl_options = {'HIDE_HEADER'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} - - @classmethod - def poll(cls, context): - engine = context.scene.render.engine - # if not (hasattr(context, "texture_slot") or hasattr(context, "texture_node")): - # return False - return ((context.material or - context.world or - context.lamp or - context.texture or - context.line_style or - context.particle_system or - isinstance(context.space_data.pin_id, ParticleSettings) or - context.texture_user) and - (engine in cls.COMPAT_ENGINES)) + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} def draw(self, context): layout = self.layout - slot = getattr(context, "texture_slot", None) - node = getattr(context, "texture_node", None) - space = context.space_data tex = context.texture - idblock = context_tex_datablock(context) + space = context.space_data pin_id = space.pin_id + use_pin_id = space.use_pin_id + user = context.texture_user - space.use_limited_texture_context = True - - if space.use_pin_id and not isinstance(pin_id, Texture): - idblock = id_tex_datablock(pin_id) - pin_id = None - - if not space.use_pin_id: - layout.row().prop(space, "texture_context", expand=True) + if not (use_pin_id and isinstance(pin_id, bpy.types.Texture)): pin_id = None - if space.texture_context == 'OTHER': - if not pin_id: - layout.template_texture_user() - user = context.texture_user - if user or pin_id: - layout.separator() + if not pin_id: + layout.template_texture_user() - row = layout.row() + if user or pin_id: + layout.separator() - if pin_id: - row.template_ID(space, "pin_id") - else: - propname = context.texture_user_property.identifier - row.template_ID(user, propname, new="texture.new") - - if tex: - split = layout.split(percentage=0.2) - if tex.use_nodes: - if slot: - split.label(text="Output:") - split.prop(slot, "output_node", text="") - else: - split.label(text="Type:") - split.prop(tex, "type", text="") - return - - tex_collection = (pin_id is None) and (node is None) and (not isinstance(idblock, Brush)) - - if tex_collection: - row = layout.row() + split = layout.split(percentage=0.65) + col = split.column() - row.template_list("TEXTURE_UL_texslots", "", idblock, "texture_slots", - idblock, "active_texture_index", rows=2) - - col = row.column(align=True) - col.operator("texture.slot_move", text="", icon='TRIA_UP').type = 'UP' - col.operator("texture.slot_move", text="", icon='TRIA_DOWN').type = 'DOWN' - col.menu("TEXTURE_MT_specials", icon='DOWNARROW_HLT', text="") - - if tex_collection: - layout.template_ID(idblock, "active_texture", new="texture.new") - elif node: - layout.template_ID(node, "texture", new="texture.new") - elif idblock: - layout.template_ID(idblock, "texture", new="texture.new") - - if pin_id: - layout.template_ID(space, "pin_id") - - if tex: - split = layout.split(percentage=0.2) - if tex.use_nodes: - if slot: - split.label(text="Output:") - split.prop(slot, "output_node", text="") + if pin_id: + col.template_ID(space, "pin_id") else: + propname = context.texture_user_property.identifier + col.template_ID(user, propname, new="texture.new") + + if tex: + split = layout.split(percentage=0.2) split.label(text="Type:") split.prop(tex, "type", text="") -class TEXTURE_PT_preview(TextureButtonsPanel, Panel): - bl_label = "Preview" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} +class TEXTURE_PT_node(TextureButtonsPanel, Panel): + bl_label = "Node" + bl_context = "texture" + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + + @classmethod + def poll(cls, context): + node = context.texture_node + return node and (context.engine in cls.COMPAT_ENGINES) def draw(self, context): layout = self.layout - tex = context.texture - slot = getattr(context, "texture_slot", None) - idblock = context_tex_datablock(context) + node = context.texture_node + ntree = node.id_data + layout.template_node_view(ntree, node, None) - if idblock: - layout.template_preview(tex, parent=idblock, slot=slot) - else: - layout.template_preview(tex, slot=slot) - # Show Alpha Button for Brush Textures, see #29502 - if context.space_data.texture_context == 'BRUSH': - layout.prop(tex, "use_preview_alpha") +class TEXTURE_PT_node_mapping(TextureButtonsPanel, Panel): + bl_label = "Mapping" + bl_context = "texture" + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + + @classmethod + def poll(cls, context): + node = context.texture_node + # TODO(sergey): perform a faster/nicer check? + return node and hasattr(node, 'texture_mapping') and (context.engine in cls.COMPAT_ENGINES) + + def draw(self, context): + layout = self.layout + + node = context.texture_node + + mapping = node.texture_mapping + + layout.prop(mapping, "vector_type", expand=True) + + row = layout.row() + + row.column().prop(mapping, "translation") + row.column().prop(mapping, "rotation") + row.column().prop(mapping, "scale") + + layout.label(text="Projection:") + + row = layout.row() + row.prop(mapping, "mapping_x", text="") + row.prop(mapping, "mapping_y", text="") + row.prop(mapping, "mapping_z", text="") class TEXTURE_PT_colors(TextureButtonsPanel, Panel): bl_label = "Colors" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + + @classmethod + def poll(cls, context): + tex = context.texture + return tex and (tex.type != 'NONE' or tex.use_nodes) and (context.engine in cls.COMPAT_ENGINES) def draw(self, context): layout = self.layout @@ -281,37 +234,20 @@ class TEXTURE_PT_colors(TextureButtonsPanel, Panel): col = layout.column() col.prop(tex, "use_clamp", text="Clamp") -# Texture Slot Panels # - - -class TextureSlotPanel(TextureButtonsPanel): - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} - - @classmethod - def poll(cls, context): - if not hasattr(context, "texture_slot"): - return False - - engine = context.scene.render.engine - return TextureButtonsPanel.poll(cls, context) and (engine in cls.COMPAT_ENGINES) - - -# Texture Type Panels # - class TextureTypePanel(TextureButtonsPanel): @classmethod def poll(cls, context): tex = context.texture - engine = context.scene.render.engine + engine = context.engine return tex and ((tex.type == cls.tex_type and not tex.use_nodes) and (engine in cls.COMPAT_ENGINES)) class TEXTURE_PT_clouds(TextureTypePanel, Panel): bl_label = "Clouds" tex_type = 'CLOUDS' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} def draw(self, context): layout = self.layout @@ -335,7 +271,7 @@ class TEXTURE_PT_clouds(TextureTypePanel, Panel): class TEXTURE_PT_wood(TextureTypePanel, Panel): bl_label = "Wood" tex_type = 'WOOD' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} def draw(self, context): layout = self.layout @@ -364,7 +300,7 @@ class TEXTURE_PT_wood(TextureTypePanel, Panel): class TEXTURE_PT_marble(TextureTypePanel, Panel): bl_label = "Marble" tex_type = 'MARBLE' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} def draw(self, context): layout = self.layout @@ -391,7 +327,7 @@ class TEXTURE_PT_marble(TextureTypePanel, Panel): class TEXTURE_PT_magic(TextureTypePanel, Panel): bl_label = "Magic" tex_type = 'MAGIC' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} def draw(self, context): layout = self.layout @@ -406,7 +342,7 @@ class TEXTURE_PT_magic(TextureTypePanel, Panel): class TEXTURE_PT_blend(TextureTypePanel, Panel): bl_label = "Blend" tex_type = 'BLEND' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} def draw(self, context): layout = self.layout @@ -424,7 +360,7 @@ class TEXTURE_PT_blend(TextureTypePanel, Panel): class TEXTURE_PT_stucci(TextureTypePanel, Panel): bl_label = "Stucci" tex_type = 'STUCCI' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} def draw(self, context): layout = self.layout @@ -444,7 +380,7 @@ class TEXTURE_PT_stucci(TextureTypePanel, Panel): class TEXTURE_PT_image(TextureTypePanel, Panel): bl_label = "Image" tex_type = 'IMAGE' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} def draw(self, context): layout = self.layout @@ -459,7 +395,7 @@ def texture_filter_common(tex, layout): layout.prop(tex, "filter_type", text="") if tex.use_mipmap and tex.filter_type in {'AREA', 'EWA', 'FELINE'}: if tex.filter_type == 'FELINE': - layout.prop(tex, "filter_probes", text="Probes") + layout.prop(tex, "filter_lightprobes", text="Light Probes") else: layout.prop(tex, "filter_eccentricity", text="Eccentricity") @@ -471,15 +407,9 @@ class TEXTURE_PT_image_sampling(TextureTypePanel, Panel): bl_label = "Image Sampling" bl_options = {'DEFAULT_CLOSED'} tex_type = 'IMAGE' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} def draw(self, context): - if context.scene.render.engine == 'BLENDER_GAME': - self.draw_bge(context) - else: - self.draw_bi(context) - - def draw_bi(self, context): layout = self.layout idblock = context_tex_datablock(context) @@ -500,17 +430,6 @@ class TEXTURE_PT_image_sampling(TextureTypePanel, Panel): col = split.column() - # Only for Material based textures, not for Lamp/World... - if slot and isinstance(idblock, Material): - col.prop(tex, "use_normal_map") - row = col.row() - row.active = tex.use_normal_map - row.prop(slot, "normal_map_space", text="") - - row = col.row() - row.active = not tex.use_normal_map - row.prop(tex, "use_derivative_map") - col.prop(tex, "use_mipmap") row = col.row() row.active = tex.use_mipmap @@ -519,39 +438,12 @@ class TEXTURE_PT_image_sampling(TextureTypePanel, Panel): texture_filter_common(tex, col) - def draw_bge(self, context): - layout = self.layout - - idblock = context_tex_datablock(context) - tex = context.texture - slot = getattr(context, "texture_slot", None) - - split = layout.split() - - col = split.column() - col.label(text="Alpha:") - col.prop(tex, "use_calculate_alpha", text="Calculate") - col.prop(tex, "invert_alpha", text="Invert") - - col = split.column() - - # Only for Material based textures, not for Lamp/World... - if slot and isinstance(idblock, Material): - col.prop(tex, "use_normal_map") - row = col.row() - row.active = tex.use_normal_map - row.prop(slot, "normal_map_space", text="") - - row = col.row() - row.active = not tex.use_normal_map - row.prop(tex, "use_derivative_map") - class TEXTURE_PT_image_mapping(TextureTypePanel, Panel): bl_label = "Image Mapping" bl_options = {'DEFAULT_CLOSED'} tex_type = 'IMAGE' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} def draw(self, context): layout = self.layout @@ -603,62 +495,10 @@ class TEXTURE_PT_image_mapping(TextureTypePanel, Panel): col.prop(tex, "crop_max_y", text="Y") -class TEXTURE_PT_envmap(TextureTypePanel, Panel): - bl_label = "Environment Map" - tex_type = 'ENVIRONMENT_MAP' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} - - def draw(self, context): - layout = self.layout - - tex = context.texture - env = tex.environment_map - - row = layout.row() - row.prop(env, "source", expand=True) - row.menu("TEXTURE_MT_envmap_specials", icon='DOWNARROW_HLT', text="") - - if env.source == 'IMAGE_FILE': - layout.template_ID(tex, "image", open="image.open") - layout.template_image(tex, "image", tex.image_user, compact=True) - else: - layout.prop(env, "mapping") - if env.mapping == 'PLANE': - layout.prop(env, "zoom") - layout.prop(env, "viewpoint_object") - - split = layout.split() - - col = split.column() - col.prop(env, "layers_ignore") - col.prop(env, "resolution") - col.prop(env, "depth") - - col = split.column(align=True) - - col.label(text="Clipping:") - col.prop(env, "clip_start", text="Start") - col.prop(env, "clip_end", text="End") - - -class TEXTURE_PT_envmap_sampling(TextureTypePanel, Panel): - bl_label = "Environment Map Sampling" - bl_options = {'DEFAULT_CLOSED'} - tex_type = 'ENVIRONMENT_MAP' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} - - def draw(self, context): - layout = self.layout - - tex = context.texture - - texture_filter_common(tex, layout) - - class TEXTURE_PT_musgrave(TextureTypePanel, Panel): bl_label = "Musgrave" tex_type = 'MUSGRAVE' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} def draw(self, context): layout = self.layout @@ -694,7 +534,7 @@ class TEXTURE_PT_musgrave(TextureTypePanel, Panel): class TEXTURE_PT_voronoi(TextureTypePanel, Panel): bl_label = "Voronoi" tex_type = 'VORONOI' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} def draw(self, context): layout = self.layout @@ -730,7 +570,7 @@ class TEXTURE_PT_voronoi(TextureTypePanel, Panel): class TEXTURE_PT_distortednoise(TextureTypePanel, Panel): bl_label = "Distorted Noise" tex_type = 'DISTORTED_NOISE' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} def draw(self, context): layout = self.layout @@ -749,180 +589,20 @@ class TEXTURE_PT_distortednoise(TextureTypePanel, Panel): split.prop(tex, "nabla") -class TEXTURE_PT_voxeldata(TextureButtonsPanel, Panel): - bl_label = "Voxel Data" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} - - @classmethod - def poll(cls, context): - tex = context.texture - engine = context.scene.render.engine - return tex and (tex.type == 'VOXEL_DATA' and (engine in cls.COMPAT_ENGINES)) - - def draw(self, context): - layout = self.layout - - tex = context.texture - vd = tex.voxel_data - - layout.prop(vd, "file_format") - if vd.file_format in {'BLENDER_VOXEL', 'RAW_8BIT'}: - layout.prop(vd, "filepath") - if vd.file_format == 'RAW_8BIT': - layout.prop(vd, "resolution") - elif vd.file_format == 'SMOKE': - layout.prop(vd, "domain_object") - layout.prop(vd, "smoke_data_type") - elif vd.file_format == 'HAIR': - layout.prop(vd, "domain_object") - layout.prop(vd, "hair_data_type") - elif vd.file_format == 'IMAGE_SEQUENCE': - layout.template_ID(tex, "image", open="image.open") - layout.template_image(tex, "image", tex.image_user, compact=True) - # layout.prop(vd, "frame_duration") - - if vd.file_format in {'BLENDER_VOXEL', 'RAW_8BIT'}: - layout.prop(vd, "use_still_frame") - row = layout.row() - row.active = vd.use_still_frame - row.prop(vd, "still_frame") - - layout.prop(vd, "interpolation") - layout.prop(vd, "extension") - layout.prop(vd, "intensity") - - -class TEXTURE_PT_pointdensity(TextureButtonsPanel, Panel): - bl_label = "Point Density" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} - - @classmethod - def poll(cls, context): - tex = context.texture - engine = context.scene.render.engine - return tex and (tex.type == 'POINT_DENSITY' and (engine in cls.COMPAT_ENGINES)) - - def draw(self, context): - layout = self.layout - - tex = context.texture - pd = tex.point_density - - layout.row().prop(pd, "point_source", expand=True) - - split = layout.split() - - col = split.column() - if pd.point_source == 'PARTICLE_SYSTEM': - col.label(text="Object:") - col.prop(pd, "object", text="") - - sub = col.column() - sub.enabled = bool(pd.object) - if pd.object: - sub.label(text="System:") - sub.prop_search(pd, "particle_system", pd.object, "particle_systems", text="") - sub.label(text="Cache:") - sub.prop(pd, "particle_cache_space", text="") - else: - col.label(text="Object:") - col.prop(pd, "object", text="") - col.label(text="Cache:") - col.prop(pd, "vertex_cache_space", text="") - - col.separator() - - col.label(text="Color Source:") - if pd.point_source == 'PARTICLE_SYSTEM': - col.prop(pd, "particle_color_source", text="") - if pd.particle_color_source in {'PARTICLE_SPEED', 'PARTICLE_VELOCITY'}: - col.prop(pd, "speed_scale") - if pd.particle_color_source in {'PARTICLE_SPEED', 'PARTICLE_AGE'}: - layout.template_color_ramp(pd, "color_ramp", expand=True) - else: - col.prop(pd, "vertex_color_source", text="") - if pd.vertex_color_source == 'VERTEX_COLOR': - if pd.object and pd.object.data: - col.prop_search(pd, "vertex_attribute_name", pd.object.data, "vertex_colors", text="") - if pd.vertex_color_source == 'VERTEX_WEIGHT': - if pd.object: - col.prop_search(pd, "vertex_attribute_name", pd.object, "vertex_groups", text="") - layout.template_color_ramp(pd, "color_ramp", expand=True) - - col = split.column() - col.label() - col.prop(pd, "radius") - col.label(text="Falloff:") - col.prop(pd, "falloff", text="") - if pd.falloff == 'SOFT': - col.prop(pd, "falloff_soft") - if pd.falloff == 'PARTICLE_VELOCITY': - col.prop(pd, "falloff_speed_scale") - - col.prop(pd, "use_falloff_curve") - - if pd.use_falloff_curve: - col = layout.column() - col.label(text="Falloff Curve") - col.template_curve_mapping(pd, "falloff_curve", brush=False) - - -class TEXTURE_PT_pointdensity_turbulence(TextureButtonsPanel, Panel): - bl_label = "Turbulence" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} +class TextureSlotPanel(TextureButtonsPanel): + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} @classmethod def poll(cls, context): - tex = context.texture - engine = context.scene.render.engine - return tex and (tex.type == 'POINT_DENSITY' and (engine in cls.COMPAT_ENGINES)) - - def draw_header(self, context): - pd = context.texture.point_density - - self.layout.prop(pd, "use_turbulence", text="") - - def draw(self, context): - layout = self.layout - - tex = context.texture - pd = tex.point_density - layout.active = pd.use_turbulence - - split = layout.split() - - col = split.column() - col.label(text="Influence:") - col.prop(pd, "turbulence_influence", text="") - col.label(text="Noise Basis:") - col.prop(pd, "noise_basis", text="") - - col = split.column() - col.label() - col.prop(pd, "turbulence_scale") - col.prop(pd, "turbulence_depth") - col.prop(pd, "turbulence_strength") - - -class TEXTURE_PT_ocean(TextureTypePanel, Panel): - bl_label = "Ocean" - tex_type = 'OCEAN' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} - - def draw(self, context): - layout = self.layout - - tex = context.texture - ot = tex.ocean + if not hasattr(context, "texture_slot"): + return False - col = layout.column() - col.prop(ot, "ocean_object") - col.prop(ot, "output") + return (context.engine in cls.COMPAT_ENGINES) class TEXTURE_PT_mapping(TextureSlotPanel, Panel): bl_label = "Mapping" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} @classmethod def poll(cls, context): @@ -933,7 +613,7 @@ class TEXTURE_PT_mapping(TextureSlotPanel, Panel): if not getattr(context, "texture_slot", None): return False - engine = context.scene.render.engine + engine = context.engine return (engine in cls.COMPAT_ENGINES) def draw(self, context): @@ -963,7 +643,7 @@ class TEXTURE_PT_mapping(TextureSlotPanel, Panel): split.label(text="Map:") ob = context.object if ob and ob.type == 'MESH': - split.prop_search(tex, "uv_layer", ob.data, "uv_textures", text="") + split.prop_search(tex, "uv_layer", ob.data, "uv_layers", text="") else: split.prop(tex, "uv_layer", text="") @@ -993,31 +673,6 @@ class TEXTURE_PT_mapping(TextureSlotPanel, Panel): row.prop(tex, "mapping_y", text="") row.prop(tex, "mapping_z", text="") - elif isinstance(idblock, Material): - split = layout.split(percentage=0.3) - split.label(text="Projection:") - split.prop(tex, "mapping", text="") - - split = layout.split() - - col = split.column() - if tex.texture_coords in {'ORCO', 'UV'}: - col.prop(tex, "use_from_dupli") - if (idblock.type == 'VOLUME' and tex.texture_coords == 'ORCO'): - col.prop(tex, "use_map_to_bounds") - elif tex.texture_coords == 'OBJECT': - col.prop(tex, "use_from_original") - if (idblock.type == 'VOLUME'): - col.prop(tex, "use_map_to_bounds") - else: - col.label() - - col = split.column() - row = col.row() - row.prop(tex, "mapping_x", text="") - row.prop(tex, "mapping_y", text="") - row.prop(tex, "mapping_z", text="") - row = layout.row() row.column().prop(tex, "offset") row.column().prop(tex, "scale") @@ -1025,7 +680,7 @@ class TEXTURE_PT_mapping(TextureSlotPanel, Panel): class TEXTURE_PT_influence(TextureSlotPanel, Panel): bl_label = "Influence" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} @classmethod def poll(cls, context): @@ -1036,7 +691,7 @@ class TEXTURE_PT_influence(TextureSlotPanel, Panel): if not getattr(context, "texture_slot", None): return False - engine = context.scene.render.engine + engine = context.engine return (engine in cls.COMPAT_ENGINES) def draw(self, context): @@ -1055,168 +710,66 @@ class TEXTURE_PT_influence(TextureSlotPanel, Panel): sub.prop(tex, factor, text=name, slider=True) return sub # XXX, temp. use_map_normal needs to override. - if isinstance(idblock, Material): - if idblock.type in {'SURFACE', 'WIRE'}: - box = layout.box() - box.label(text="¡OLD LAYOUT!") - - split = box.split() - - col = split.column() - col.label(text="Diffuse:") - factor_but(col, "use_map_diffuse", "diffuse_factor", "Intensity") - factor_but(col, "use_map_color_diffuse", "diffuse_color_factor", "Color") - factor_but(col, "use_map_alpha", "alpha_factor", "Alpha") - factor_but(col, "use_map_translucency", "translucency_factor", "Translucency") - - col.label(text="Specular:") - factor_but(col, "use_map_specular", "specular_factor", "Intensity") - factor_but(col, "use_map_color_spec", "specular_color_factor", "Color") - factor_but(col, "use_map_hardness", "hardness_factor", "Hardness") - - col = split.column() - col.label(text="Shading:") - factor_but(col, "use_map_ambient", "ambient_factor", "Ambient") - factor_but(col, "use_map_emit", "emit_factor", "Emit") - factor_but(col, "use_map_mirror", "mirror_factor", "Mirror") - factor_but(col, "use_map_raymir", "raymir_factor", "Ray Mirror") - - col.label(text="Geometry:") - # XXX replace 'or' when displacement is fixed to not rely on normal influence value. - sub_tmp = factor_but(col, "use_map_normal", "normal_factor", "Normal") - sub_tmp.active = (tex.use_map_normal or tex.use_map_displacement) - # END XXX - - factor_but(col, "use_map_warp", "warp_factor", "Warp") - factor_but(col, "use_map_displacement", "displacement_factor", "Displace") - - #~ sub = col.column() - #~ sub.active = tex.use_map_translucency or tex.map_emit or tex.map_alpha or tex.map_raymir or tex.map_hardness or tex.map_ambient or tex.map_specularity or tex.map_reflection or tex.map_mirror - #~ sub.prop(tex, "default_value", text="Amount", slider=True) - - layout.separator() - box = layout.box() - box.label(text="¡GRID FLOW LAYOUT!") - - gflow = box.grid_flow(row_major=True, num_columns=0, even_columns=True, even_rows=False, align=False) - - col = gflow.column() - col.label(text="Diffuse:") - factor_but(col, "use_map_diffuse", "diffuse_factor", "Intensity") - factor_but(col, "use_map_color_diffuse", "diffuse_color_factor", "Color") - factor_but(col, "use_map_alpha", "alpha_factor", "Alpha") - factor_but(col, "use_map_translucency", "translucency_factor", "Translucency") - - col = gflow.column() - col.label(text="Shading:") - factor_but(col, "use_map_ambient", "ambient_factor", "Ambient") - factor_but(col, "use_map_emit", "emit_factor", "Emit") - factor_but(col, "use_map_mirror", "mirror_factor", "Mirror") - factor_but(col, "use_map_raymir", "raymir_factor", "Ray Mirror") - - col = gflow.column() - col.label(text="Specular:") - factor_but(col, "use_map_specular", "specular_factor", "Intensity") - factor_but(col, "use_map_color_spec", "specular_color_factor", "Color") - factor_but(col, "use_map_hardness", "hardness_factor", "Hardness") - - col = gflow.column() - col.label(text="Geometry:") - # XXX replace 'or' when displacement is fixed to not rely on normal influence value. - sub_tmp = factor_but(col, "use_map_normal", "normal_factor", "Normal") - sub_tmp.active = (tex.use_map_normal or tex.use_map_displacement) - # END XXX - factor_but(col, "use_map_warp", "warp_factor", "Warp") - factor_but(col, "use_map_displacement", "displacement_factor", "Displace") - - - - elif idblock.type == 'HALO': - layout.label(text="Halo:") - - split = layout.split() - - col = split.column() - factor_but(col, "use_map_color_diffuse", "diffuse_color_factor", "Color") - factor_but(col, "use_map_alpha", "alpha_factor", "Alpha") - - col = split.column() - factor_but(col, "use_map_raymir", "raymir_factor", "Size") - factor_but(col, "use_map_hardness", "hardness_factor", "Hardness") - factor_but(col, "use_map_translucency", "translucency_factor", "Add") - elif idblock.type == 'VOLUME': - layout.label(text="Volume:") - - split = layout.split() - - col = split.column() - factor_but(col, "use_map_density", "density_factor", "Density") - factor_but(col, "use_map_emission", "emission_factor", "Emission") - factor_but(col, "use_map_scatter", "scattering_factor", "Scattering") - factor_but(col, "use_map_reflect", "reflection_factor", "Reflection") - - col = split.column() - col.label(text=" ") - factor_but(col, "use_map_color_emission", "emission_color_factor", "Emission Color") - factor_but(col, "use_map_color_transmission", "transmission_color_factor", "Transmission Color") - factor_but(col, "use_map_color_reflection", "reflection_color_factor", "Reflection Color") - - layout.label(text="Geometry:") - - split = layout.split() - - col = split.column() - factor_but(col, "use_map_warp", "warp_factor", "Warp") - - col = split.column() - factor_but(col, "use_map_displacement", "displacement_factor", "Displace") - - elif isinstance(idblock, Lamp): - split = layout.split() + if isinstance(idblock, ParticleSettings): + box = layout.box() + box.label(text="¡OLD LAYOUT!") + + split = box.split() col = split.column() - factor_but(col, "use_map_color", "color_factor", "Color") + col.label(text="General:") + factor_but(col, "use_map_time", "time_factor", "Time") + factor_but(col, "use_map_life", "life_factor", "Lifetime") + factor_but(col, "use_map_density", "density_factor", "Density") + factor_but(col, "use_map_size", "size_factor", "Size") col = split.column() - factor_but(col, "use_map_shadow", "shadow_factor", "Shadow") + col.label(text="Physics:") + factor_but(col, "use_map_velocity", "velocity_factor", "Velocity") + factor_but(col, "use_map_damp", "damp_factor", "Damp") + factor_but(col, "use_map_gravity", "gravity_factor", "Gravity") + factor_but(col, "use_map_field", "field_factor", "Force Fields") - elif isinstance(idblock, World): - split = layout.split() + box.label(text="Hair:") - col = split.column() - factor_but(col, "use_map_blend", "blend_factor", "Blend") - factor_but(col, "use_map_horizon", "horizon_factor", "Horizon") + split = box.split() col = split.column() - factor_but(col, "use_map_zenith_up", "zenith_up_factor", "Zenith Up") - factor_but(col, "use_map_zenith_down", "zenith_down_factor", "Zenith Down") - elif isinstance(idblock, ParticleSettings): - split = layout.split() + factor_but(col, "use_map_length", "length_factor", "Length") + factor_but(col, "use_map_clump", "clump_factor", "Clump") + factor_but(col, "use_map_twist", "twist_factor", "Twist") col = split.column() + factor_but(col, "use_map_kink_amp", "kink_amp_factor", "Kink Amplitude") + factor_but(col, "use_map_kink_freq", "kink_freq_factor", "Kink Frequency") + factor_but(col, "use_map_rough", "rough_factor", "Rough") + + + layout.separator() + box = layout.box() + box.label(text="¡GRID FLOW LAYOUT!") + + gflow = box.grid_flow(row_major=True, num_columns=0, even_columns=True, even_rows=False, align=False) + + col = gflow.column() col.label(text="General:") factor_but(col, "use_map_time", "time_factor", "Time") factor_but(col, "use_map_life", "life_factor", "Lifetime") factor_but(col, "use_map_density", "density_factor", "Density") factor_but(col, "use_map_size", "size_factor", "Size") - col = split.column() + col = gflow.column() col.label(text="Physics:") factor_but(col, "use_map_velocity", "velocity_factor", "Velocity") factor_but(col, "use_map_damp", "damp_factor", "Damp") factor_but(col, "use_map_gravity", "gravity_factor", "Gravity") factor_but(col, "use_map_field", "field_factor", "Force Fields") - layout.label(text="Hair:") - - split = layout.split() - - col = split.column() + col = gflow.column() + col.label(text="Hair:") factor_but(col, "use_map_length", "length_factor", "Length") factor_but(col, "use_map_clump", "clump_factor", "Clump") factor_but(col, "use_map_twist", "twist_factor", "Twist") - - col = split.column() factor_but(col, "use_map_kink_amp", "kink_amp_factor", "Kink Amplitude") factor_but(col, "use_map_kink_freq", "kink_freq_factor", "Kink Frequency") factor_but(col, "use_map_rough", "rough_factor", "Rough") @@ -1244,47 +797,26 @@ class TEXTURE_PT_influence(TextureSlotPanel, Panel): col.prop(tex, "invert", text="Negative") col.prop(tex, "use_stencil") - if isinstance(idblock, Material) or isinstance(idblock, World): - col.prop(tex, "default_value", text="DVar", slider=True) - - if isinstance(idblock, Material): - layout.label(text="Bump Mapping:") - - # only show bump settings if activated but not for normal-map images - row = layout.row() - - sub = row.row() - sub.active = ( - (tex.use_map_normal or tex.use_map_warp) and - not (tex.texture.type == 'IMAGE' and - (tex.texture.use_normal_map or tex.texture.use_derivative_map)) - ) - sub.prop(tex, "bump_method", text="Method") - - # the space setting is supported for: derivative-maps + bump-maps - # (DEFAULT,BEST_QUALITY), not for normal-maps - sub = row.row() - sub.active = ( - (tex.use_map_normal or tex.use_map_warp) and - not (tex.texture.type == 'IMAGE' and tex.texture.use_normal_map) and - ((tex.bump_method in {'BUMP_LOW_QUALITY', 'BUMP_MEDIUM_QUALITY', 'BUMP_BEST_QUALITY'}) or - (tex.texture.type == 'IMAGE' and tex.texture.use_derivative_map)) - ) - sub.prop(tex, "bump_objectspace", text="Space") - class TEXTURE_PT_custom_props(TextureButtonsPanel, PropertyPanel, Panel): - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} _context_path = "texture" _property_type = Texture + @classmethod + def poll(cls, context): + return context.texture and (context.engine in cls.COMPAT_ENGINES) + classes = ( TEXTURE_MT_specials, - TEXTURE_MT_envmap_specials, TEXTURE_UL_texslots, - TEXTURE_PT_context_texture, TEXTURE_PT_preview, + TEXTURE_PT_context, + TEXTURE_PT_node, + TEXTURE_PT_node_mapping, + TEXTURE_PT_mapping, + TEXTURE_PT_influence, TEXTURE_PT_colors, TEXTURE_PT_clouds, TEXTURE_PT_wood, @@ -1295,17 +827,9 @@ classes = ( TEXTURE_PT_image, TEXTURE_PT_image_sampling, TEXTURE_PT_image_mapping, - TEXTURE_PT_envmap, - TEXTURE_PT_envmap_sampling, TEXTURE_PT_musgrave, TEXTURE_PT_voronoi, TEXTURE_PT_distortednoise, - TEXTURE_PT_voxeldata, - TEXTURE_PT_pointdensity, - TEXTURE_PT_pointdensity_turbulence, - TEXTURE_PT_ocean, - TEXTURE_PT_mapping, - TEXTURE_PT_influence, TEXTURE_PT_custom_props, ) diff --git a/release/scripts/startup/bl_ui/properties_view_layer.py b/release/scripts/startup/bl_ui/properties_view_layer.py new file mode 100644 index 00000000000..3c8552c3407 --- /dev/null +++ b/release/scripts/startup/bl_ui/properties_view_layer.py @@ -0,0 +1,87 @@ +# ##### BEGIN GPL LICENSE BLOCK ##### +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# ##### END GPL LICENSE BLOCK ##### + +# <pep8 compliant> +import bpy +from bpy.types import Panel, UIList + + +class ViewLayerButtonsPanel: + bl_space_type = 'PROPERTIES' + bl_region_type = 'WINDOW' + bl_context = "view_layer" + # COMPAT_ENGINES must be defined in each subclass, external engines can add themselves here + + @classmethod + def poll(cls, context): + return (context.engine in cls.COMPAT_ENGINES) + + +class VIEWLAYER_PT_layer(ViewLayerButtonsPanel, Panel): + bl_label = "View Layer" + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'} + + def draw(self, context): + layout = self.layout + + scene = context.scene + rd = scene.render + layer = bpy.context.view_layer + + layout.prop(layer, "use", text="Use for Rendering"); + layout.prop(rd, "use_single_layer", text="Render Single Layer") + + +class VIEWLAYER_PT_eevee_layer_passes(ViewLayerButtonsPanel, Panel): + bl_label = "Passes" + bl_options = {'DEFAULT_CLOSED'} + COMPAT_ENGINES = {'BLENDER_EEVEE'} + + def draw(self, context): + layout = self.layout + + scene = context.scene + rd = scene.render + view_layer = context.view_layer + + split = layout.split() + + col = split.column() + col.prop(view_layer, "use_pass_combined") + col.prop(view_layer, "use_pass_z") + col.prop(view_layer, "use_pass_mist") + col.prop(view_layer, "use_pass_normal") + col.separator() + col.prop(view_layer, "use_pass_ambient_occlusion") + + col = split.column() + col.label(text="Subsurface:") + row = col.row(align=True) + row.prop(view_layer, "use_pass_subsurface_direct", text="Direct", toggle=True) + row.prop(view_layer, "use_pass_subsurface_color", text="Color", toggle=True) + + +classes = ( + VIEWLAYER_PT_layer, + VIEWLAYER_PT_eevee_layer_passes, +) + +if __name__ == "__main__": # only for live edit. + from bpy.utils import register_class + for cls in classes: + register_class(cls) diff --git a/release/scripts/startup/bl_ui/properties_world.py b/release/scripts/startup/bl_ui/properties_world.py index 107c31567b3..1ec2d4774e8 100644 --- a/release/scripts/startup/bl_ui/properties_world.py +++ b/release/scripts/startup/bl_ui/properties_world.py @@ -20,6 +20,7 @@ import bpy from bpy.types import Panel from rna_prop_ui import PropertyPanel +from bpy_extras.node_utils import find_node_input, find_output_node class WorldButtonsPanel: @@ -30,18 +31,17 @@ class WorldButtonsPanel: @classmethod def poll(cls, context): - return (context.world and context.scene.render.engine in cls.COMPAT_ENGINES) + return (context.world and context.engine in cls.COMPAT_ENGINES) class WORLD_PT_context_world(WorldButtonsPanel, Panel): bl_label = "" bl_options = {'HIDE_HEADER'} - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} @classmethod def poll(cls, context): - rd = context.scene.render - return rd.engine in cls.COMPAT_ENGINES + return (context.engine in cls.COMPAT_ENGINES) def draw(self, context): layout = self.layout @@ -50,215 +50,85 @@ class WORLD_PT_context_world(WorldButtonsPanel, Panel): world = context.world space = context.space_data - texture_count = world and len(world.texture_slots.keys()) - split = layout.split(percentage=0.85) if scene: split.template_ID(scene, "world", new="world.new") elif world: split.template_ID(space, "pin_id") - if texture_count: - split.label(text=str(texture_count), icon='TEXTURE') - -class WORLD_PT_preview(WorldButtonsPanel, Panel): - bl_label = "Preview" - COMPAT_ENGINES = {'BLENDER_RENDER'} +class EEVEE_WORLD_PT_mist(WorldButtonsPanel, Panel): + bl_label = "Mist Pass" + bl_options = {'DEFAULT_CLOSED'} + COMPAT_ENGINES = {'BLENDER_EEVEE'} @classmethod def poll(cls, context): - rd = context.scene.render - return (context.world) and (rd.engine in cls.COMPAT_ENGINES) - - def draw(self, context): - self.layout.template_preview(context.world) + engine = context.engine + if context.world and (engine in cls.COMPAT_ENGINES): + for view_layer in context.scene.view_layers: + if view_layer.use_pass_mist: + return True - -class WORLD_PT_world(WorldButtonsPanel, Panel): - bl_label = "World" - COMPAT_ENGINES = {'BLENDER_RENDER'} + return False def draw(self, context): layout = self.layout world = context.world - row = layout.row() - row.prop(world, "use_sky_paper") - row.prop(world, "use_sky_blend") - row.prop(world, "use_sky_real") - - row = layout.row() - row.column().prop(world, "horizon_color") - col = row.column() - col.prop(world, "zenith_color") - col.active = world.use_sky_blend - row.column().prop(world, "ambient_color") - - row = layout.row() - row.prop(world, "exposure") - row.prop(world, "color_range") - - -class WORLD_PT_ambient_occlusion(WorldButtonsPanel, Panel): - bl_label = "Ambient Occlusion" - COMPAT_ENGINES = {'BLENDER_RENDER'} - - def draw_header(self, context): - light = context.world.light_settings - self.layout.prop(light, "use_ambient_occlusion", text="") - - def draw(self, context): - layout = self.layout - - light = context.world.light_settings - - layout.active = light.use_ambient_occlusion - - split = layout.split() - split.prop(light, "ao_factor", text="Factor") - split.prop(light, "ao_blend_type", text="") - - -class WORLD_PT_environment_lighting(WorldButtonsPanel, Panel): - bl_label = "Environment Lighting" - COMPAT_ENGINES = {'BLENDER_RENDER'} - - def draw_header(self, context): - light = context.world.light_settings - self.layout.prop(light, "use_environment_light", text="") - - def draw(self, context): - layout = self.layout - - light = context.world.light_settings - - layout.active = light.use_environment_light - - split = layout.split() - split.prop(light, "environment_energy", text="Energy") - split.prop(light, "environment_color", text="") - - -class WORLD_PT_indirect_lighting(WorldButtonsPanel, Panel): - bl_label = "Indirect Lighting" - COMPAT_ENGINES = {'BLENDER_RENDER'} - - def draw_header(self, context): - light = context.world.light_settings - self.layout.prop(light, "use_indirect_light", text="") - - def draw(self, context): - layout = self.layout - - light = context.world.light_settings - - layout.active = light.use_indirect_light and light.gather_method == 'APPROXIMATE' + split = layout.split(align=True) + split.prop(world.mist_settings, "start") + split.prop(world.mist_settings, "depth") - split = layout.split() - split.prop(light, "indirect_factor", text="Factor") - split.prop(light, "indirect_bounces", text="Bounces") - - if light.gather_method == 'RAYTRACE': - layout.label(text="Only works with Approximate gather method") - - -class WORLD_PT_gather(WorldButtonsPanel, Panel): - bl_label = "Gather" - COMPAT_ENGINES = {'BLENDER_RENDER'} - - def draw(self, context): - layout = self.layout - - light = context.world.light_settings - - layout.active = light.use_ambient_occlusion or light.use_environment_light or light.use_indirect_light - - layout.row().prop(light, "gather_method", expand=True) - - split = layout.split() - - col = split.column() - col.label(text="Attenuation:") - if light.gather_method == 'RAYTRACE': - col.prop(light, "distance") - col.prop(light, "use_falloff") - sub = col.row() - sub.active = light.use_falloff - sub.prop(light, "falloff_strength", text="Strength") - - if light.gather_method == 'RAYTRACE': - col = split.column() - - col.label(text="Sampling:") - col.prop(light, "sample_method", text="") - - sub = col.column() - sub.prop(light, "samples") - - if light.sample_method == 'ADAPTIVE_QMC': - sub.prop(light, "threshold") - sub.prop(light, "adapt_to_speed", slider=True) - elif light.sample_method == 'CONSTANT_JITTERED': - sub.prop(light, "bias") - - if light.gather_method == 'APPROXIMATE': - col = split.column() + layout.prop(world.mist_settings, "falloff") - col.label(text="Sampling:") - col.prop(light, "passes") - col.prop(light, "error_threshold", text="Error") - col.prop(light, "use_cache") - col.prop(light, "correction") +class WORLD_PT_custom_props(WorldButtonsPanel, PropertyPanel, Panel): + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + _context_path = "world" + _property_type = bpy.types.World -class WORLD_PT_mist(WorldButtonsPanel, Panel): - bl_label = "Mist" - bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER'} - def draw_header(self, context): - world = context.world +class EEVEE_WORLD_PT_surface(WorldButtonsPanel, Panel): + bl_label = "Surface" + bl_context = "world" + COMPAT_ENGINES = {'BLENDER_EEVEE'} - self.layout.prop(world.mist_settings, "use_mist", text="") + @classmethod + def poll(cls, context): + engine = context.engine + return context.world and (engine in cls.COMPAT_ENGINES) def draw(self, context): layout = self.layout world = context.world - layout.active = world.mist_settings.use_mist + layout.prop(world, "use_nodes", icon='NODETREE') + layout.separator() - split = layout.split() + if world.use_nodes: + ntree = world.node_tree + node = find_output_node(ntree, ('OUTPUT_WORLD',)) - col = split.column() - col.prop(world.mist_settings, "intensity") - col.prop(world.mist_settings, "start") - - col = split.column() - col.prop(world.mist_settings, "depth") - col.prop(world.mist_settings, "height") - - layout.prop(world.mist_settings, "falloff") - - -class WORLD_PT_custom_props(WorldButtonsPanel, PropertyPanel, Panel): - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} - _context_path = "world" - _property_type = bpy.types.World + if node: + input = find_node_input(node, 'Surface') + if input: + layout.template_node_view(ntree, node, input) + else: + layout.label(text="Incompatible output node") + else: + layout.label(text="No output node") + else: + layout.prop(world, "horizon_color", text="Color") classes = ( WORLD_PT_context_world, - WORLD_PT_preview, - WORLD_PT_world, - WORLD_PT_ambient_occlusion, - WORLD_PT_environment_lighting, - WORLD_PT_indirect_lighting, - WORLD_PT_gather, - WORLD_PT_mist, WORLD_PT_custom_props, + EEVEE_WORLD_PT_surface, + EEVEE_WORLD_PT_mist, ) if __name__ == "__main__": # only for live edit. diff --git a/release/scripts/startup/bl_ui/space_clip.py b/release/scripts/startup/bl_ui/space_clip.py index 1cb2275a86f..a3dc401b484 100644 --- a/release/scripts/startup/bl_ui/space_clip.py +++ b/release/scripts/startup/bl_ui/space_clip.py @@ -57,9 +57,6 @@ class CLIP_HT_header(Header): sc = context.space_data clip = sc.clip - row = layout.row(align=True) - row.template_header() - CLIP_MT_tracking_editor_menus.draw_collapsible(context, layout) row = layout.row() @@ -70,8 +67,6 @@ class CLIP_HT_header(Header): active_object = tracking.objects.active if sc.view == 'CLIP': - layout.prop(sc, "mode", text="") - layout.prop(sc, "view", text="", expand=True) layout.prop(sc, "pivot_point", text="", icon_only=True) r = active_object.reconstruction @@ -80,8 +75,6 @@ class CLIP_HT_header(Header): layout.label(text="Solve error: %.4f" % (r.average_error)) elif sc.view == 'GRAPH': - layout.prop(sc, "view", text="", expand=True) - row = layout.row(align=True) row.prop(sc, "show_graph_only_selected", text="") row.prop(sc, "show_graph_hidden", text="") @@ -103,7 +96,6 @@ class CLIP_HT_header(Header): text="Filters") elif sc.view == 'DOPESHEET': dopesheet = tracking.dopesheet - layout.prop(sc, "view", text="", expand=True) row = layout.row(align=True) row.prop(dopesheet, "show_only_selected", text="") @@ -113,8 +105,6 @@ class CLIP_HT_header(Header): row.prop(dopesheet, "sort_method", text="") row.prop(dopesheet, "use_invert_sort", text="Invert", toggle=True) - else: - layout.prop(sc, "view", text="", expand=True) def _draw_masking(self, context): layout = self.layout @@ -123,17 +113,12 @@ class CLIP_HT_header(Header): sc = context.space_data clip = sc.clip - row = layout.row(align=True) - row.template_header() - CLIP_MT_masking_editor_menus.draw_collapsible(context, layout) row = layout.row() row.template_ID(sc, "clip", open="clip.open") if clip: - layout.prop(sc, "mode", text="") - row = layout.row() row.template_ID(sc, "mask", new="mask.new") @@ -151,7 +136,12 @@ class CLIP_HT_header(Header): sc = context.space_data + row = layout.row(align=True) + row.template_header() + + layout.prop(sc, "mode", text="") if sc.mode == 'TRACKING': + layout.prop(sc, "view", text="", icon_only=True) self._draw_tracking(context) else: self._draw_masking(context) @@ -1242,9 +1232,8 @@ class CLIP_MT_view(Menu): layout.prop(sc, "show_locked_time") layout.separator() - layout.operator("screen.area_dupli") - layout.operator("screen.screen_full_area") - layout.operator("screen.screen_full_area", text="Toggle Fullscreen Area").use_hide_panels = True + + layout.menu("INFO_MT_area") class CLIP_MT_clip(Menu): diff --git a/release/scripts/startup/bl_ui/space_console.py b/release/scripts/startup/bl_ui/space_console.py index e6f96d989c7..dd5ab03fcba 100644 --- a/release/scripts/startup/bl_ui/space_console.py +++ b/release/scripts/startup/bl_ui/space_console.py @@ -69,9 +69,7 @@ class CONSOLE_MT_console(Menu): layout.separator() - layout.operator("screen.area_dupli") - layout.operator("screen.screen_full_area") - layout.operator("screen.screen_full_area", text="Toggle Fullscreen Area").use_hide_panels = True + layout.menu("INFO_MT_area") class CONSOLE_MT_language(Menu): diff --git a/release/scripts/startup/bl_ui/space_dopesheet.py b/release/scripts/startup/bl_ui/space_dopesheet.py index 371ab088190..f3841de3ba4 100644 --- a/release/scripts/startup/bl_ui/space_dopesheet.py +++ b/release/scripts/startup/bl_ui/space_dopesheet.py @@ -20,6 +20,7 @@ import bpy from bpy.types import Header, Menu +from .space_time import * ####################################### @@ -40,11 +41,11 @@ def dopesheet_filter(layout, context, genericFiltersOnly=False): row.prop(dopesheet, "show_only_errors", text="") if not genericFiltersOnly: - if bpy.data.groups: + if bpy.data.collections: row = layout.row(align=True) - row.prop(dopesheet, "show_only_group_objects", text="") - if dopesheet.show_only_group_objects: - row.prop(dopesheet, "filter_group", text="") + row.prop(dopesheet, "show_only_collection_objects", text="") + if dopesheet.show_only_collection_objects: + row.prop(dopesheet, "filter_collection", text="") if not is_nla: row = layout.row(align=True) @@ -114,14 +115,35 @@ class DOPESHEET_HT_header(Header): layout = self.layout st = context.space_data - toolsettings = context.tool_settings row = layout.row(align=True) row.template_header() + + # XXX: perhaps our mode menu can be retired eventually when we get editor submodes in the main menu? + layout.prop(st, "mode", text="") - DOPESHEET_MT_editor_menus.draw_collapsible(context, layout) + if st.mode == 'TIMELINE': + TIME_MT_editor_menus.draw_collapsible(context, layout) + TIME_HT_editor_buttons.draw_header(context, layout) + else: + DOPESHEET_MT_editor_menus.draw_collapsible(context, layout) + DOPESHEET_HT_editor_buttons.draw_header(context, layout) - layout.prop(st, "mode", text="") + +# Header for "normal" dopesheet editor modes (e.g. Dope Sheet, Action, Shape Keys, etc.) +# XXX: Temporary, until we have editor submodes in the actual editors menu +class DOPESHEET_HT_editor_buttons(Header): + bl_idname = "DOPESHEET_HT_editor_buttons" + bl_space_type = 'DOPESHEET_EDITOR' + bl_label = "" + + def draw(self, context): + pass + + @staticmethod + def draw_header(context, layout): + st = context.space_data + toolsettings = context.tool_settings if st.mode in {'ACTION', 'SHAPEKEY'}: row = layout.row(align=True) @@ -233,9 +255,7 @@ class DOPESHEET_MT_view(Menu): layout.operator("action.view_frame") layout.separator() - layout.operator("screen.area_dupli") - layout.operator("screen.screen_full_area") - layout.operator("screen.screen_full_area", text="Toggle Fullscreen Area").use_hide_panels = True + layout.menu("INFO_MT_area") class DOPESHEET_MT_select(Menu): @@ -451,6 +471,7 @@ class DOPESHEET_MT_delete(Menu): classes = ( DOPESHEET_HT_header, + DOPESHEET_HT_editor_buttons, DOPESHEET_MT_editor_menus, DOPESHEET_MT_view, DOPESHEET_MT_select, diff --git a/release/scripts/startup/bl_ui/space_graph.py b/release/scripts/startup/bl_ui/space_graph.py index e2407f1f2b2..7e927bb6385 100644 --- a/release/scripts/startup/bl_ui/space_graph.py +++ b/release/scripts/startup/bl_ui/space_graph.py @@ -36,10 +36,10 @@ class GRAPH_HT_header(Header): row = layout.row(align=True) row.template_header() - GRAPH_MT_editor_menus.draw_collapsible(context, layout) - layout.prop(st, "mode", text="") + GRAPH_MT_editor_menus.draw_collapsible(context, layout) + dopesheet_filter(layout, context) row = layout.row(align=True) @@ -129,9 +129,7 @@ class GRAPH_MT_view(Menu): layout.operator("graph.view_frame") layout.separator() - layout.operator("screen.area_dupli") - layout.operator("screen.screen_full_area") - layout.operator("screen.screen_full_area", text="Toggle Fullscreen Area").use_hide_panels = True + layout.menu("INFO_MT_area") class GRAPH_MT_select(Menu): diff --git a/release/scripts/startup/bl_ui/space_image.py b/release/scripts/startup/bl_ui/space_image.py index 0f3583d2832..b1ff1618d09 100644 --- a/release/scripts/startup/bl_ui/space_image.py +++ b/release/scripts/startup/bl_ui/space_image.py @@ -126,9 +126,7 @@ class IMAGE_MT_view(Menu): layout.operator("image.cycle_render_slot", text="Render Slot Cycle Previous").reverse = True layout.separator() - layout.operator("screen.area_dupli") - layout.operator("screen.screen_full_area") - layout.operator("screen.screen_full_area", text="Toggle Fullscreen Area").use_hide_panels = True + layout.menu("INFO_MT_area") class IMAGE_MT_select(Menu): @@ -194,7 +192,7 @@ class IMAGE_MT_image(Menu): show_render = sima.show_render - layout.operator("image.read_renderlayers") + layout.operator("image.read_viewlayers") layout.operator("image.save_dirty", text="Save All Images") @@ -443,14 +441,14 @@ class IMAGE_HT_header(Header): row = layout.row(align=True) row.template_header() + layout.prop(sima, "mode", text="") + MASK_MT_editor_menus.draw_collapsible(context, layout) layout.template_ID(sima, "image", new="image.new", open="image.open") if not show_render: layout.prop(sima, "use_image_pin", text="") - layout.prop(sima, "mode", text="") - if show_maskedit: row = layout.row() row.template_ID(sima, "mask", new="mask.new") @@ -481,7 +479,7 @@ class IMAGE_HT_header(Header): row.prop(toolsettings, "snap_target", text="") mesh = context.edit_object.data - layout.prop_search(mesh.uv_textures, "active", mesh, "uv_textures", text="") + layout.prop_search(mesh.uv_layers, "active", mesh, "uv_layers", text="") if ima: if ima.is_stereo_3d: @@ -614,50 +612,6 @@ class IMAGE_PT_image_properties(Panel): layout.template_image(sima, "image", iuser, multiview=True) -class IMAGE_PT_game_properties(Panel): - bl_space_type = 'IMAGE_EDITOR' - bl_region_type = 'UI' - bl_label = "Game Properties" - - @classmethod - def poll(cls, context): - sima = context.space_data - # display even when not in game mode because these settings effect the 3d view - return (sima and sima.image and not sima.show_maskedit) # and (rd.engine == 'BLENDER_GAME') - - def draw(self, context): - layout = self.layout - - sima = context.space_data - ima = sima.image - - split = layout.split() - col = split.column() - col.prop(ima, "use_animation") - sub = col.column(align=True) - sub.active = ima.use_animation - sub.prop(ima, "frame_start", text="Start") - sub.prop(ima, "frame_end", text="End") - sub.prop(ima, "fps", text="Speed") - - col = split.column() - col.prop(ima, "use_tiles") - sub = col.column(align=True) - sub.active = ima.use_tiles or ima.use_animation - sub.prop(ima, "tiles_x", text="X") - sub.prop(ima, "tiles_y", text="Y") - - split = layout.split() - col = split.column() - col.label(text="Clamp:") - col.prop(ima, "use_clamp_x", text="X") - col.prop(ima, "use_clamp_y", text="Y") - - col = split.column() - col.label(text="Mapping:") - col.prop(ima, "mapping", expand=True) - - class IMAGE_PT_view_properties(Panel): bl_space_type = 'IMAGE_EDITOR' bl_region_type = 'UI' @@ -689,11 +643,11 @@ class IMAGE_PT_view_properties(Panel): col.label(text="Coordinates:") col.prop(sima, "show_repeat", text="Repeat") if show_uvedit: - col.prop(uvedit, "show_normalized_coords", text="Normalized") + col.prop(uvedit, "show_pixel_coords", text="Pixel") elif show_uvedit: col.label(text="Coordinates:") - col.prop(uvedit, "show_normalized_coords", text="Normalized") + col.prop(uvedit, "show_pixel_coords", text="Pixel") if show_uvedit or show_maskedit: col = layout.column() @@ -1363,7 +1317,6 @@ classes = ( IMAGE_PT_active_mask_spline, IMAGE_PT_active_mask_point, IMAGE_PT_image_properties, - IMAGE_PT_game_properties, IMAGE_PT_view_properties, IMAGE_PT_tools_transform_uvs, IMAGE_PT_tools_align_uvs, diff --git a/release/scripts/startup/bl_ui/space_info.py b/release/scripts/startup/bl_ui/space_info.py index 180e48af386..e5ef5f9a0da 100644 --- a/release/scripts/startup/bl_ui/space_info.py +++ b/release/scripts/startup/bl_ui/space_info.py @@ -26,347 +26,29 @@ class INFO_HT_header(Header): def draw(self, context): layout = self.layout + layout.template_header() - window = context.window - scene = context.scene - rd = scene.render + # Empty for now until info editor gets turned into log editor + pass - row = layout.row(align=True) - row.template_header() - INFO_MT_editor_menus.draw_collapsible(context, layout) - - if window.screen.show_fullscreen: - layout.operator("screen.back_to_previous", icon='SCREEN_BACK', text="Back to Previous") - layout.separator() - else: - layout.template_ID(context.window, "screen", new="screen.new", unlink="screen.delete") - layout.template_ID(context.screen, "scene", new="scene.new", unlink="scene.delete") - - layout.separator() - - if rd.has_multiple_engines: - layout.prop(rd, "engine", text="") - - layout.separator() - - layout.template_running_jobs() - - layout.template_reports_banner() - - row = layout.row(align=True) - - if bpy.app.autoexec_fail is True and bpy.app.autoexec_fail_quiet is False: - row.label("Auto-run disabled", icon='ERROR') - if bpy.data.is_saved: - props = row.operator("wm.revert_mainfile", icon='SCREEN_BACK', text="Reload Trusted") - props.use_scripts = True - - row.operator("script.autoexec_warn_clear", text="Ignore") - - # include last so text doesn't push buttons out of the header - row.label(bpy.app.autoexec_fail_message) - return - - row.operator("wm.splash", text="", icon='BLENDER', emboss=False) - row.label(text=scene.statistics(), translate=False) - - -class INFO_MT_editor_menus(Menu): - bl_idname = "INFO_MT_editor_menus" - bl_label = "" - - def draw(self, context): - self.draw_menus(self.layout, context) - - @staticmethod - def draw_menus(layout, context): - scene = context.scene - rd = scene.render - - layout.menu("INFO_MT_file") - - if rd.use_game_engine: - layout.menu("INFO_MT_game") - else: - layout.menu("INFO_MT_render") - - layout.menu("INFO_MT_window") - layout.menu("INFO_MT_help") - - -class INFO_MT_file(Menu): - bl_label = "File" - - def draw(self, context): - layout = self.layout - - layout.operator_context = 'INVOKE_AREA' - layout.operator("wm.read_homefile", text="New", icon='NEW') - layout.operator("wm.open_mainfile", text="Open...", icon='FILE_FOLDER') - layout.menu("INFO_MT_file_open_recent", icon='OPEN_RECENT') - layout.operator("wm.revert_mainfile", icon='FILE_REFRESH') - layout.operator("wm.recover_last_session", icon='RECOVER_LAST') - layout.operator("wm.recover_auto_save", text="Recover Auto Save...", icon='RECOVER_AUTO') - - layout.separator() - - layout.operator_context = 'EXEC_AREA' if context.blend_data.is_saved else 'INVOKE_AREA' - layout.operator("wm.save_mainfile", text="Save", icon='FILE_TICK') - - layout.operator_context = 'INVOKE_AREA' - layout.operator("wm.save_as_mainfile", text="Save As...", icon='SAVE_AS') - layout.operator_context = 'INVOKE_AREA' - layout.operator("wm.save_as_mainfile", text="Save Copy...", icon='SAVE_COPY').copy = True - - layout.separator() - - layout.operator("screen.userpref_show", text="User Preferences...", icon='PREFERENCES') - - layout.operator_context = 'INVOKE_AREA' - layout.operator("wm.save_homefile", icon='SAVE_PREFS') - layout.operator("wm.read_factory_settings", icon='LOAD_FACTORY') - - if any(bpy.utils.app_template_paths()): - app_template = context.user_preferences.app_template - if app_template: - layout.operator( - "wm.read_factory_settings", - text="Load Factory Template Settings", - icon='LOAD_FACTORY', - ).app_template = app_template - del app_template - - layout.menu("USERPREF_MT_app_templates", icon='FILE_BLEND') - - layout.separator() - - layout.operator_context = 'INVOKE_AREA' - layout.operator("wm.link", text="Link", icon='LINK_BLEND') - layout.operator("wm.append", text="Append", icon='APPEND_BLEND') - layout.menu("INFO_MT_file_previews") - - layout.separator() - - layout.menu("INFO_MT_file_import", icon='IMPORT') - layout.menu("INFO_MT_file_export", icon='EXPORT') - - layout.separator() - - layout.menu("INFO_MT_file_external_data", icon='EXTERNAL_DATA') - layout.operator("wm.blend_strings_utf8_validate", icon='FILE_BLEND') - - layout.separator() - - layout.operator_context = 'EXEC_AREA' - if bpy.data.is_dirty and context.user_preferences.view.use_quit_dialog: - layout.operator_context = 'INVOKE_SCREEN' # quit dialog - layout.operator("wm.quit_blender", text="Quit", icon='QUIT') - - -class INFO_MT_file_import(Menu): - bl_idname = "INFO_MT_file_import" - bl_label = "Import" - - def draw(self, context): - if bpy.app.build_options.collada: - self.layout.operator("wm.collada_import", text="Collada (Default) (.dae)") - if bpy.app.build_options.alembic: - self.layout.operator("wm.alembic_import", text="Alembic (.abc)") - - -class INFO_MT_file_export(Menu): - bl_idname = "INFO_MT_file_export" - bl_label = "Export" - - def draw(self, context): - if bpy.app.build_options.collada: - self.layout.operator("wm.collada_export", text="Collada (Default) (.dae)") - if bpy.app.build_options.alembic: - self.layout.operator("wm.alembic_export", text="Alembic (.abc)") - - -class INFO_MT_file_external_data(Menu): - bl_label = "External Data" +# Not really info, just add to re-usable location. +class INFO_MT_area(Menu): + bl_label = "Area" def draw(self, context): layout = self.layout - icon = 'CHECKBOX_HLT' if bpy.data.use_autopack else 'CHECKBOX_DEHLT' - layout.operator("file.autopack_toggle", icon=icon) - - layout.separator() - - pack_all = layout.row() - pack_all.operator("file.pack_all") - pack_all.active = not bpy.data.use_autopack - - unpack_all = layout.row() - unpack_all.operator("file.unpack_all") - unpack_all.active = not bpy.data.use_autopack - - layout.separator() - - layout.operator("file.make_paths_relative") - layout.operator("file.make_paths_absolute") - layout.operator("file.report_missing_files") - layout.operator("file.find_missing_files") - - -class INFO_MT_file_previews(Menu): - bl_label = "Data Previews" - - def draw(self, context): - layout = self.layout - - layout.operator("wm.previews_ensure") - layout.operator("wm.previews_batch_generate") - - layout.separator() - - layout.operator("wm.previews_clear") - layout.operator("wm.previews_batch_clear") - - -class INFO_MT_game(Menu): - bl_label = "Game" - - def draw(self, context): - layout = self.layout - - gs = context.scene.game_settings - - layout.operator("view3d.game_start") - - layout.separator() - - layout.prop(gs, "show_debug_properties") - layout.prop(gs, "show_framerate_profile") - layout.prop(gs, "show_physics_visualization") - layout.prop(gs, "use_deprecation_warnings") - layout.prop(gs, "use_animation_record") - layout.separator() - layout.prop(gs, "use_auto_start") - - -class INFO_MT_render(Menu): - bl_label = "Render" - - def draw(self, context): - layout = self.layout - - layout.operator("render.render", text="Render Image", icon='RENDER_STILL').use_viewport = True - props = layout.operator("render.render", text="Render Animation", icon='RENDER_ANIMATION') - props.animation = True - props.use_viewport = True - - layout.separator() - - layout.operator("render.opengl", text="OpenGL Render Image") - layout.operator("render.opengl", text="OpenGL Render Animation").animation = True - layout.menu("INFO_MT_opengl_render") - - layout.separator() - - layout.operator("render.view_show") - layout.operator("render.play_rendered_anim", icon='PLAY') - - -class INFO_MT_opengl_render(Menu): - bl_label = "OpenGL Render Options" - - def draw(self, context): - layout = self.layout - - rd = context.scene.render - layout.prop(rd, "use_antialiasing") - layout.prop(rd, "use_full_sample") - - layout.prop_menu_enum(rd, "antialiasing_samples") - layout.prop_menu_enum(rd, "alpha_mode") - - -class INFO_MT_window(Menu): - bl_label = "Window" - - def draw(self, context): - import sys - - layout = self.layout - - layout.operator("wm.window_duplicate") - layout.operator("wm.window_fullscreen_toggle", icon='FULLSCREEN_ENTER') - - layout.separator() - - layout.operator("screen.screenshot") - layout.operator("screen.screencast") - - if sys.platform[:3] == "win": - 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" - - def draw(self, context): - layout = self.layout - - layout.operator( - "wm.url_open", text="Manual", icon='HELP', - ).url = "https://docs.blender.org/manual/en/dev/" - layout.operator( - "wm.url_open", text="Release Log", icon='URL', - ).url = "http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/%d.%d" % bpy.app.version[:2] - layout.separator() - - layout.operator( - "wm.url_open", text="Blender Website", icon='URL', - ).url = "https://www.blender.org" - layout.operator( - "wm.url_open", text="Blender Store", icon='URL', - ).url = "https://store.blender.org" - layout.operator( - "wm.url_open", text="Developer Community", icon='URL', - ).url = "https://www.blender.org/get-involved/" - layout.operator( - "wm.url_open", text="User Community", icon='URL', - ).url = "https://www.blender.org/support/user-community" - layout.separator() - layout.operator( - "wm.url_open", text="Report a Bug", icon='URL', - ).url = "https://developer.blender.org/maniphest/task/edit/form/1" - layout.separator() - - layout.operator( - "wm.url_open", text="Python API Reference", icon='URL', - ).url = bpy.types.WM_OT_doc_view._prefix - - layout.operator("wm.operator_cheat_sheet", icon='TEXT') - layout.operator("wm.sysinfo", icon='TEXT') - layout.separator() - - layout.operator("wm.splash", icon='BLENDER') + layout.operator("screen.area_dupli") + if context.space_data.type == 'VIEW_3D': + layout.operator("screen.region_quadview") + layout.operator("screen.screen_full_area") + layout.operator("screen.screen_full_area", text="Toggle Fullscreen Area").use_hide_panels = True classes = ( INFO_HT_header, - INFO_MT_editor_menus, - INFO_MT_file, - INFO_MT_file_import, - INFO_MT_file_export, - INFO_MT_file_external_data, - INFO_MT_file_previews, - INFO_MT_game, - INFO_MT_render, - INFO_MT_opengl_render, - INFO_MT_window, - INFO_MT_help, + INFO_MT_area, ) if __name__ == "__main__": # only for live edit. diff --git a/release/scripts/startup/bl_ui/space_logic.py b/release/scripts/startup/bl_ui/space_logic.py deleted file mode 100644 index b552181f491..00000000000 --- a/release/scripts/startup/bl_ui/space_logic.py +++ /dev/null @@ -1,145 +0,0 @@ -# ##### BEGIN GPL LICENSE BLOCK ##### -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -# -# ##### END GPL LICENSE BLOCK ##### - -# <pep8 compliant> -import bpy -from bpy.types import Header, Menu, Panel - - -class LOGIC_PT_properties(Panel): - bl_space_type = 'LOGIC_EDITOR' - bl_region_type = 'UI' - bl_label = "Properties" - - @classmethod - def poll(cls, context): - ob = context.active_object - return ob and ob.game - - def draw(self, context): - layout = self.layout - - ob = context.active_object - game = ob.game - is_font = (ob.type == 'FONT') - - if is_font: - prop_index = game.properties.find("Text") - if prop_index != -1: - layout.operator("object.game_property_remove", text="Remove Text Game Property", icon='X').index = prop_index - row = layout.row() - sub = row.row() - sub.enabled = 0 - prop = game.properties[prop_index] - sub.prop(prop, "name", text="") - row.prop(prop, "type", text="") - # get the property from the body, not the game property - # note, don't do this - it's too slow and body can potentially be a really long string. - #~ row.prop(ob.data, "body", text="") - row.label("See Text Object") - else: - props = layout.operator("object.game_property_new", text="Add Text Game Property", icon='ZOOMIN') - props.name = "Text" - props.type = 'STRING' - - props = layout.operator("object.game_property_new", text="Add Game Property", icon='ZOOMIN') - props.name = "" - - for i, prop in enumerate(game.properties): - - if is_font and i == prop_index: - continue - - box = layout.box() - row = box.row() - row.prop(prop, "name", text="") - 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 - - -class LOGIC_MT_logicbricks_add(Menu): - bl_label = "Add" - - def draw(self, context): - layout = self.layout - - layout.operator_menu_enum("logic.sensor_add", "type", text="Sensor") - layout.operator_menu_enum("logic.controller_add", "type", text="Controller") - layout.operator_menu_enum("logic.actuator_add", "type", text="Actuator") - - -class LOGIC_HT_header(Header): - bl_space_type = 'LOGIC_EDITOR' - - def draw(self, context): - layout = self.layout.row(align=True) - - layout.template_header() - - LOGIC_MT_editor_menus.draw_collapsible(context, layout) - - -class LOGIC_MT_editor_menus(Menu): - bl_idname = "LOGIC_MT_editor_menus" - bl_label = "" - - def draw(self, context): - self.draw_menus(self.layout, context) - - @staticmethod - def draw_menus(layout, context): - layout.menu("LOGIC_MT_view") - layout.menu("LOGIC_MT_logicbricks_add") - - -class LOGIC_MT_view(Menu): - bl_label = "View" - - def draw(self, context): - layout = self.layout - - layout.operator("logic.properties", icon='MENU_PANEL') - - layout.separator() - - layout.operator("screen.area_dupli") - layout.operator("screen.screen_full_area") - layout.operator("screen.screen_full_area", text="Toggle Fullscreen Area").use_hide_panels = True - - -classes = ( - LOGIC_PT_properties, - LOGIC_MT_logicbricks_add, - LOGIC_HT_header, - LOGIC_MT_editor_menus, - LOGIC_MT_view, -) - -if __name__ == "__main__": # only for live edit. - from bpy.utils import register_class - for cls in classes: - register_class(cls) diff --git a/release/scripts/startup/bl_ui/space_nla.py b/release/scripts/startup/bl_ui/space_nla.py index 8a933570c5e..2f1c1d8325e 100644 --- a/release/scripts/startup/bl_ui/space_nla.py +++ b/release/scripts/startup/bl_ui/space_nla.py @@ -90,9 +90,7 @@ class NLA_MT_view(Menu): layout.operator("nla.view_frame") layout.separator() - layout.operator("screen.area_dupli") - layout.operator("screen.screen_full_area") - layout.operator("screen.screen_full_area", text="Toggle Fullscreen Area").use_hide_panels = True + layout.menu("INFO_MT_area") class NLA_MT_select(Menu): diff --git a/release/scripts/startup/bl_ui/space_node.py b/release/scripts/startup/bl_ui/space_node.py index 8f7d8f7555a..0963613af5c 100644 --- a/release/scripts/startup/bl_ui/space_node.py +++ b/release/scripts/startup/bl_ui/space_node.py @@ -48,16 +48,16 @@ class NODE_HT_header(Header): row = layout.row(align=True) row.template_header() - NODE_MT_editor_menus.draw_collapsible(context, layout) + # Now expanded via the 'ui_type' + # layout.prop(snode, "tree_type", text="") - layout.prop(snode, "tree_type", text="", expand=True) + NODE_MT_editor_menus.draw_collapsible(context, layout) if snode.tree_type == 'ShaderNodeTree': - if scene.render.use_shading_nodes: - layout.prop(snode, "shader_type", text="", expand=True) + layout.prop(snode, "shader_type", text="", expand=True) ob = context.object - if (not scene.render.use_shading_nodes or snode.shader_type == 'OBJECT') and ob: + if snode.shader_type == 'OBJECT' and ob: row = layout.row() # disable material slot buttons when pinned, cannot find correct slot within id_from (#36589) row.enabled = not snode.pin @@ -68,20 +68,20 @@ class NODE_HT_header(Header): if id_from and ob.type != 'LAMP': row.template_ID(id_from, "active_material", new="material.new") - # Don't show "Use Nodes" Button when Engine is BI for Lamps - if snode_id and not (scene.render.use_shading_nodes == 0 and ob.type == 'LAMP'): + # No shader nodes for Eevee lamps + if snode_id and not (context.engine == 'BLENDER_EEVEE' and ob.type == 'LAMP'): layout.prop(snode_id, "use_nodes") - if scene.render.use_shading_nodes and snode.shader_type == 'WORLD': + if snode.shader_type == 'WORLD': row = layout.row() row.enabled = not snode.pin row.template_ID(scene, "world", new="world.new") if snode_id: row.prop(snode_id, "use_nodes") - if scene.render.use_shading_nodes and snode.shader_type == 'LINESTYLE': - rl = context.scene.render.layers.active - lineset = rl.freestyle_settings.linesets.active + if snode.shader_type == 'LINESTYLE': + view_layer = context.view_layer + lineset = view_layer.freestyle_settings.linesets.active if lineset is not None: row = layout.row() row.enabled = not snode.pin @@ -194,9 +194,7 @@ class NODE_MT_view(Menu): layout.separator() - layout.operator("screen.area_dupli") - layout.operator("screen.screen_full_area") - layout.operator("screen.screen_full_area", text="Toggle Fullscreen Area").use_hide_panels = True + layout.menu("INFO_MT_area") class NODE_MT_select(Menu): @@ -271,7 +269,7 @@ class NODE_MT_node(Menu): layout.separator() - layout.operator("node.read_renderlayers") + layout.operator("node.read_viewlayers") layout.operator("node.read_fullsamplelayers") @@ -395,8 +393,7 @@ class NODE_PT_backdrop(Panel): col = layout.column(align=True) col.label(text="Offset:") - col.prop(snode, "backdrop_x", text="X") - col.prop(snode, "backdrop_y", text="Y") + col.prop(snode, "backdrop_offset", text="") col.operator("node.backimage_move", text="Move") layout.operator("node.backimage_fit", text="Fit") diff --git a/release/scripts/startup/bl_ui/space_outliner.py b/release/scripts/startup/bl_ui/space_outliner.py index 4951ef83ad0..8b8526cf9f2 100644 --- a/release/scripts/startup/bl_ui/space_outliner.py +++ b/release/scripts/startup/bl_ui/space_outliner.py @@ -18,7 +18,7 @@ # <pep8 compliant> import bpy -from bpy.types import Header, Menu +from bpy.types import Header, Menu, Panel class OUTLINER_HT_header(Header): @@ -28,21 +28,33 @@ class OUTLINER_HT_header(Header): layout = self.layout space = context.space_data + display_mode = space.display_mode scene = context.scene ks = context.scene.keying_sets.active row = layout.row(align=True) row.template_header() - OUTLINER_MT_editor_menus.draw_collapsible(context, layout) - layout.prop(space, "display_mode", text="") - layout.prop(space, "filter_text", icon='VIEWZOOM', text="") + row = layout.row(align=True) + if display_mode in {'VIEW_LAYER'}: + row.popover(space_type='OUTLINER', + region_type='HEADER', + panel_type="OUTLINER_PT_filter", + text="", + icon='FILTER') + elif display_mode in {'LIBRARIES', 'ORPHAN_DATA'}: + row.prop(space, "use_filter_id_type", text="", icon='FILTER') + sub = row.row(align=True) + sub.active = space.use_filter_id_type + sub.prop(space, "filter_id_type", text="", icon_only=True) + + OUTLINER_MT_editor_menus.draw_collapsible(context, layout) - layout.separator() + if space.display_mode == 'DATA_API': + layout.separator() - if space.display_mode == 'DATABLOCKS': row = layout.row(align=True) row.operator("outliner.keyingset_add_selected", icon='ZOOMIN', text="") row.operator("outliner.keyingset_remove_selected", icon='ZOOMOUT', text="") @@ -57,8 +69,13 @@ class OUTLINER_HT_header(Header): else: row = layout.row() row.label(text="No Keying Set Active") - elif space.display_mode == 'ORPHAN_DATA': - layout.operator("outliner.orphans_purge") + + row = layout.row(align=True) + row.prop(space, "use_filter_search", text="") + if space.use_filter_search: + row.prop(space, "filter_text", text="") + row.prop(space, "use_filter_complete", text="") + row.prop(space, "use_filter_case_sensitive", text="") class OUTLINER_MT_editor_menus(Menu): @@ -73,11 +90,13 @@ class OUTLINER_MT_editor_menus(Menu): space = context.space_data layout.menu("OUTLINER_MT_view") - layout.menu("OUTLINER_MT_search") - if space.display_mode == 'DATABLOCKS': + if space.display_mode == 'DATA_API': layout.menu("OUTLINER_MT_edit_datablocks") + elif space.display_mode == 'ORPHAN_DATA': + layout.menu("OUTLINER_MT_edit_orphan_data") + class OUTLINER_MT_view(Menu): bl_label = "View" @@ -87,7 +106,7 @@ class OUTLINER_MT_view(Menu): space = context.space_data - if space.display_mode not in {'DATABLOCKS', 'USER_PREFERENCES'}: + if space.display_mode != 'DATA_API': layout.prop(space, "use_sort_alpha") layout.prop(space, "show_restrict_columns") layout.separator() @@ -99,44 +118,173 @@ class OUTLINER_MT_view(Menu): layout.separator() - layout.operator("screen.area_dupli") - layout.operator("screen.screen_full_area") - layout.operator("screen.screen_full_area", text="Toggle Fullscreen Area").use_hide_panels = True + layout.menu("INFO_MT_area") -class OUTLINER_MT_search(Menu): - bl_label = "Search" +class OUTLINER_MT_edit_datablocks(Menu): + bl_label = "Edit" def draw(self, context): layout = self.layout - space = context.space_data + layout.operator("outliner.keyingset_add_selected") + layout.operator("outliner.keyingset_remove_selected") - layout.prop(space, "use_filter_case_sensitive") - layout.prop(space, "use_filter_complete") + layout.separator() + layout.operator("outliner.drivers_add_selected") + layout.operator("outliner.drivers_delete_selected") -class OUTLINER_MT_edit_datablocks(Menu): + +class OUTLINER_MT_edit_orphan_data(Menu): bl_label = "Edit" def draw(self, context): layout = self.layout + layout.operator("outliner.orphans_purge") - layout.operator("outliner.keyingset_add_selected") - layout.operator("outliner.keyingset_remove_selected") + +class OUTLINER_MT_collection_view_layer(Menu): + bl_label = "View Layer" + + def draw(self, context): + layout = self.layout + + space = context.space_data + + layout.operator("outliner.collection_exclude_set", text="Exclude") + layout.operator("outliner.collection_include_set", text="Include") + + +class OUTLINER_MT_collection(Menu): + bl_label = "Collection" + + def draw(self, context): + layout = self.layout + + space = context.space_data + + layout.operator("outliner.collection_new", text="New").nested = True + layout.operator("outliner.collection_duplicate", text="Duplicate") + layout.operator("outliner.collection_delete", text="Delete").hierarchy = False + layout.operator("outliner.collection_delete", text="Delete Hierarchy").hierarchy = True layout.separator() - layout.operator("outliner.drivers_add_selected") - layout.operator("outliner.drivers_delete_selected") + layout.operator("outliner.collection_objects_select", text="Select Objects") + layout.operator("outliner.collection_objects_deselect", text="Deselect Objects") + + layout.separator() + + layout.operator("outliner.collection_instance", text="Instance to Scene") + if space.display_mode != 'VIEW_LAYER': + layout.operator("outliner.collection_link", text="Link to Scene") + layout.operator("outliner.id_operation", text="Unlink").type='UNLINK' + + if space.display_mode == 'VIEW_LAYER': + layout.separator() + layout.menu("OUTLINER_MT_collection_view_layer") + + layout.separator() + layout.operator_menu_enum("outliner.id_operation", 'type', text="ID Data") + + +class OUTLINER_MT_collection_new(Menu): + bl_label = "Collection" + + def draw(self, context): + layout = self.layout + + layout.operator("outliner.collection_new", text="New").nested = False + + +class OUTLINER_MT_object(Menu): + bl_label = "Object" + + def draw(self, context): + layout = self.layout + + space = context.space_data + + layout.operator("outliner.object_operation", text="Delete").type='DELETE' + if space.display_mode == 'VIEW_LAYER' and not space.use_filter_collection: + layout.operator("outliner.object_operation", text="Delete Hierarchy").type='DELETE_HIERARCHY' + + layout.separator() + + layout.operator("outliner.object_operation", text="Select").type='SELECT' + layout.operator("outliner.object_operation", text="Select Hierarchy").type='SELECT_HIERARCHY' + layout.operator("outliner.object_operation", text="Deselect").type='DESELECT' + + layout.separator() + + if not (space.display_mode == 'VIEW_LAYER' and not space.use_filter_collection): + layout.operator("outliner.id_operation", text="Unlink").type='UNLINK' + layout.separator() + + layout.operator_menu_enum("outliner.id_operation", 'type', text="ID Data") + + +class OUTLINER_PT_filter(Panel): + bl_space_type = 'OUTLINER' + bl_region_type = 'HEADER' + bl_label = "Filter" + + def draw(self, context): + layout = self.layout + + space = context.space_data + display_mode = space.display_mode + + layout.prop(space, "use_filter_collection", text="Collections") + + layout.separator() + + col = layout.column() + col.prop(space, "use_filter_object", text="Objects") + active = space.use_filter_object + + sub = col.column(align=True) + sub.active = active + sub.prop(space, "filter_state", text="") + sub.prop(space, "use_filter_object_content", text="Object Contents") + sub.prop(space, "use_filter_children", text="Object Children") + + layout.separator() + + col = layout.column_flow(align=True) + col.active = active + + if bpy.data.meshes: + col.prop(space, "use_filter_object_mesh", text="Meshes") + if bpy.data.armatures: + col.prop(space, "use_filter_object_armature", text="Armatures") + if bpy.data.lamps: + col.prop(space, "use_filter_object_lamp", text="Lamps") + if bpy.data.cameras: + col.prop(space, "use_filter_object_camera", text="Cameras") + + col.prop(space, "use_filter_object_empty", text="Empties") + + if bpy.data.curves or \ + bpy.data.metaballs or \ + bpy.data.lightprobes or \ + bpy.data.lattices or \ + bpy.data.fonts or bpy.data.speakers: + col.prop(space, "use_filter_object_others", text="Others") classes = ( OUTLINER_HT_header, OUTLINER_MT_editor_menus, OUTLINER_MT_view, - OUTLINER_MT_search, OUTLINER_MT_edit_datablocks, + OUTLINER_MT_edit_orphan_data, + OUTLINER_MT_collection, + OUTLINER_MT_collection_new, + OUTLINER_MT_collection_view_layer, + OUTLINER_MT_object, + OUTLINER_PT_filter, ) if __name__ == "__main__": # only for live edit. diff --git a/release/scripts/startup/bl_ui/space_properties.py b/release/scripts/startup/bl_ui/space_properties.py index 20cb5719e20..cd7137e0254 100644 --- a/release/scripts/startup/bl_ui/space_properties.py +++ b/release/scripts/startup/bl_ui/space_properties.py @@ -31,7 +31,9 @@ class PROPERTIES_HT_header(Header): row = layout.row() row.template_header() - row.prop(view, "context", expand=True, icon_only=True) + + if view.mode == 'DATA_PROPERTIES': + row.prop(view, "context", expand=True, icon_only=True) classes = ( diff --git a/release/scripts/startup/bl_ui/space_sequencer.py b/release/scripts/startup/bl_ui/space_sequencer.py index 0697cf8e56b..ce1d1da038c 100644 --- a/release/scripts/startup/bl_ui/space_sequencer.py +++ b/release/scripts/startup/bl_ui/space_sequencer.py @@ -79,14 +79,14 @@ class SEQUENCER_HT_header(Header): row = layout.row(align=True) row.template_header() + layout.prop(st, "view_type", text="") + SEQUENCER_MT_editor_menus.draw_collapsible(context, layout) row = layout.row(align=True) row.prop(scene, "use_preview_range", text="", toggle=True) row.prop(scene, "lock_frame_selection_to_range", text="", toggle=True) - layout.prop(st, "view_type", expand=True, text="") - if st.view_type in {'PREVIEW', 'SEQUENCER_PREVIEW'}: layout.prop(st, "display_mode", expand=True, text="") @@ -237,9 +237,7 @@ class SEQUENCER_MT_view(Menu): layout.prop(st, "use_marker_sync") layout.separator() - layout.operator("screen.area_dupli") - layout.operator("screen.screen_full_area") - layout.operator("screen.screen_full_area", text="Toggle Fullscreen Area").use_hide_panels = True + layout.menu("INFO_MT_area") class SEQUENCER_MT_select(Menu): @@ -431,10 +429,6 @@ class SEQUENCER_MT_strip(Menu): layout.operator_context = 'INVOKE_REGION_WIN' - layout.operator("ed.undo") - layout.operator("ed.redo") - layout.operator("ed.undo_history") - layout.separator() layout.menu("SEQUENCER_MT_strip_transform") layout.operator("sequencer.snap") @@ -1288,7 +1282,7 @@ class SEQUENCER_PT_grease_pencil_tools(GreasePencilToolsPanel, SequencerButtonsP class SEQUENCER_PT_custom_props(SequencerButtonsPanel, PropertyPanel, Panel): - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} _context_path = "scene.sequence_editor.active_strip" _property_type = (bpy.types.Sequence,) bl_category = "Strip" diff --git a/release/scripts/startup/bl_ui/space_statusbar.py b/release/scripts/startup/bl_ui/space_statusbar.py new file mode 100644 index 00000000000..983b474d18b --- /dev/null +++ b/release/scripts/startup/bl_ui/space_statusbar.py @@ -0,0 +1,84 @@ +# ##### BEGIN GPL LICENSE BLOCK ##### +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# ##### END GPL LICENSE BLOCK ##### + +# <pep8 compliant> +import bpy +from bpy.types import Header + + +class STATUSBAR_HT_header(Header): + bl_space_type = 'STATUSBAR' + + def draw(self, context): + area = context.area + region = context.region + + if region.alignment == 'RIGHT': + if region == area.regions[0]: + self.draw_right(context) + else: + self.draw_center(context) + else: + self.draw_left(context) + + def draw_left(self, context): + layout = self.layout + + row = layout.row(align=True) + if (bpy.data.filepath): + row.label(text=bpy.data.filepath, translate=False) + if bpy.data.is_dirty: + row.label("(Modified)") + + def draw_center(self, context): + layout = self.layout + + scene = context.scene + view_layer = context.view_layer + + layout.label(text=scene.statistics(view_layer), translate=False) + + def draw_right(self, context): + layout = self.layout + + layout.template_running_jobs() + layout.template_reports_banner() + + row = layout.row(align=True) + if bpy.app.autoexec_fail is True and bpy.app.autoexec_fail_quiet is False: + row.label("Auto-run disabled", icon='ERROR') + if bpy.data.is_saved: + props = row.operator("wm.revert_mainfile", icon='SCREEN_BACK', text="Reload Trusted") + props.use_scripts = True + + row.operator("script.autoexec_warn_clear", text="Ignore") + + # include last so text doesn't push buttons out of the header + row.label(bpy.app.autoexec_fail_message) + return + + + +classes = ( + STATUSBAR_HT_header, +) + +if __name__ == "__main__": # only for live edit. + from bpy.utils import register_class + for cls in classes: + register_class(cls) diff --git a/release/scripts/startup/bl_ui/space_text.py b/release/scripts/startup/bl_ui/space_text.py index 98a7da855ca..b1af82c95fe 100644 --- a/release/scripts/startup/bl_ui/space_text.py +++ b/release/scripts/startup/bl_ui/space_text.py @@ -180,9 +180,7 @@ class TEXT_MT_view(Menu): layout.separator() - layout.operator("screen.area_dupli") - layout.operator("screen.screen_full_area") - layout.operator("screen.screen_full_area", text="Toggle Fullscreen Area").use_hide_panels = True + layout.menu("INFO_MT_area") class TEXT_MT_text(Menu): diff --git a/release/scripts/startup/bl_ui/space_time.py b/release/scripts/startup/bl_ui/space_time.py index 9026a93aa99..48ac85f0d0e 100644 --- a/release/scripts/startup/bl_ui/space_time.py +++ b/release/scripts/startup/bl_ui/space_time.py @@ -18,45 +18,35 @@ # <pep8 compliant> import bpy -from bpy.types import Header, Menu +from bpy.types import Header, Menu, Panel -class TIME_HT_header(Header): - bl_space_type = 'TIMELINE' +# Header buttons for timeline header (play, etc.) +class TIME_HT_editor_buttons(Header): + bl_idname = "TIME_HT_editor_buttons" + bl_space_type = 'DOPESHEET_EDITOR' + bl_label = "" def draw(self, context): - layout = self.layout + pass + @staticmethod + def draw_header(context, layout): scene = context.scene toolsettings = context.tool_settings screen = context.screen - userprefs = context.user_preferences - - row = layout.row(align=True) - row.template_header() - - TIME_MT_editor_menus.draw_collapsible(context, layout) - - row = layout.row(align=True) - row.prop(scene, "use_preview_range", text="", toggle=True) - row.prop(scene, "lock_frame_selection_to_range", text="", toggle=True) - - row = layout.row(align=True) - if not scene.use_preview_range: - row.prop(scene, "frame_start", text="Start") - row.prop(scene, "frame_end", text="End") - else: - row.prop(scene, "frame_preview_start", text="Start") - row.prop(scene, "frame_preview_end", text="End") - - if scene.show_subframe: - layout.prop(scene, "frame_float", text="") - else: - layout.prop(scene, "frame_current", text="") + layout.separator() # XXX: This should be dynamic (e.g. layout.separator(stretch=1.0)) + layout.separator() + layout.separator() + layout.separator() + layout.separator() + layout.separator() layout.separator() row = layout.row(align=True) + row.prop(toolsettings, "use_keyframe_insert_auto", text="", toggle=True) + row.operator("screen.frame_jump", text="", icon='REW').end = False row.operator("screen.keyframe_jump", text="", icon='PREV_KEYFRAME').next = False if not screen.is_animation_playing: @@ -65,37 +55,46 @@ class TIME_HT_header(Header): # since JACK transport doesn't support reversed playback if scene.sync_mode == 'AUDIO_SYNC' and context.user_preferences.system.audio_device == 'JACK': sub = row.row(align=True) - sub.scale_x = 2.0 + sub.scale_x = 1.4 sub.operator("screen.animation_play", text="", icon='PLAY') else: row.operator("screen.animation_play", text="", icon='PLAY_REVERSE').reverse = True row.operator("screen.animation_play", text="", icon='PLAY') else: sub = row.row(align=True) - sub.scale_x = 2.0 + sub.scale_x = 1.4 sub.operator("screen.animation_play", text="", icon='PAUSE') row.operator("screen.keyframe_jump", text="", icon='NEXT_KEYFRAME').next = True row.operator("screen.frame_jump", text="", icon='FF').end = True - layout.prop(scene, "sync_mode", text="") - + layout.separator() # XXX: This should be dynamic (e.g. layout.separator(stretch=1.0)) + layout.separator() + layout.separator() + layout.separator() + layout.separator() + layout.separator() layout.separator() - row = layout.row(align=True) - row.prop(toolsettings, "use_keyframe_insert_auto", text="", toggle=True) - if toolsettings.use_keyframe_insert_auto: - row.prop(toolsettings, "use_keyframe_insert_keyingset", text="", toggle=True) - - 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) + row = layout.row() + row.scale_x = 0.95 + if scene.show_subframe: + row.prop(scene, "frame_float", text="") + else: + row.prop(scene, "frame_current", text="") - layout.prop(toolsettings, "keyframe_type", text="", icon_only=True) + layout.separator() + layout.separator() row = layout.row(align=True) - row.prop_search(scene.keying_sets_all, "active", scene, "keying_sets_all", text="") - row.operator("anim.keyframe_insert", text="", icon='KEY_HLT') - row.operator("anim.keyframe_delete", text="", icon='KEY_DEHLT') + row.prop(scene, "use_preview_range", text="", toggle=True) + sub = row.row(align=True) + sub.scale_x = 0.8 + if not scene.use_preview_range: + sub.prop(scene, "frame_start", text="Start") + sub.prop(scene, "frame_end", text="End") + else: + sub.prop(scene, "frame_preview_start", text="Start") + sub.prop(scene, "frame_preview_end", text="End") class TIME_MT_editor_menus(Menu): @@ -109,9 +108,14 @@ class TIME_MT_editor_menus(Menu): def draw_menus(layout, context): layout.menu("TIME_MT_view") layout.menu("TIME_MT_marker") - layout.menu("TIME_MT_frame") - layout.menu("TIME_MT_playback") - + layout.popover(space_type='DOPESHEET_EDITOR', + region_type='HEADER', + panel_type="TIME_PT_playback", + text="Playback") + layout.popover(space_type='DOPESHEET_EDITOR', + region_type='HEADER', + panel_type="TIME_PT_keyframing_settings", + text="Keying") class TIME_MT_marker(Menu): bl_label = "Marker" @@ -138,7 +142,6 @@ class TIME_MT_view(Menu): layout.prop(st, "show_frame_indicator") layout.prop(scene, "show_keys_from_selected_only") - layout.prop(scene, "show_subframe") layout.separator() @@ -146,18 +149,13 @@ class TIME_MT_view(Menu): layout.separator() - layout.operator("time.view_all") - layout.operator("time.view_frame") - - layout.separator() - - layout.operator("marker.camera_bind") + # NOTE: "action" now, since timeline is in the dopesheet editor, instead of as own editor + layout.operator("action.view_all") + layout.operator("action.view_frame") layout.separator() - layout.operator("screen.area_dupli") - layout.operator("screen.screen_full_area") - layout.operator("screen.screen_full_area", text="Toggle Fullscreen Area").use_hide_panels = True + layout.menu("INFO_MT_area") class TIME_MT_cache(Menu): @@ -182,25 +180,55 @@ class TIME_MT_cache(Menu): col.prop(st, "cache_rigidbody") -class TIME_MT_frame(Menu): - bl_label = "Frame" +def marker_menu_generic(layout): + from bpy import context - def draw(self, context): - layout = self.layout + # layout.operator_context = 'EXEC_REGION_WIN' - layout.operator("anim.previewrange_clear") - layout.operator("anim.previewrange_set") - layout.separator() - layout.operator("time.end_frame_set") - layout.operator("time.start_frame_set") + layout.column() + layout.operator("marker.add", "Add Marker") + layout.operator("marker.duplicate", text="Duplicate Marker") - layout.separator() + if len(bpy.data.scenes) > 10: + layout.operator_context = 'INVOKE_DEFAULT' + layout.operator("marker.make_links_scene", text="Duplicate Marker to Scene...", icon='OUTLINER_OB_EMPTY') + else: + layout.operator_menu_enum("marker.make_links_scene", "scene", text="Duplicate Marker to Scene") - layout.menu("TIME_MT_autokey") + layout.operator("marker.delete", text="Delete Marker") + layout.separator() -class TIME_MT_playback(Menu): + layout.operator("marker.rename", text="Rename Marker") + layout.operator("marker.move", text="Grab/Move Marker") + + layout.separator() + + layout.operator("marker.camera_bind") + + layout.separator() + + 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 = context.tool_settings + layout.prop(ts, "lock_markers") + +################################### + +class TimelinePanelButtons: + bl_space_type = 'DOPESHEET_EDITOR' + bl_region_type = 'UI' + + @staticmethod + def has_timeline(context): + return context.space_data.mode == 'TIMELINE' + + +class TIME_PT_playback(TimelinePanelButtons, Panel): bl_label = "Playback" + bl_region_type = 'HEADER' def draw(self, context): layout = self.layout @@ -208,7 +236,20 @@ class TIME_MT_playback(Menu): screen = context.screen scene = context.scene - layout.prop(screen, "use_play_top_left_3d_editor") + layout.prop(scene, "sync_mode", text="") + layout.prop(scene, "use_audio_scrub") + layout.prop(scene, "use_audio", text="Mute Audio") + + layout.prop(scene, "show_subframe", text="Subframes") + + layout.prop(scene, "lock_frame_selection_to_range", text="Limit Playhead to Frame Range") + layout.prop(screen, "use_follow", text="Follow Playhead") + + layout.separator() + + col = layout.column() + col.label("Play Animation In:") + layout.prop(screen, "use_play_top_left_3d_editor", text="Active Editor Only") layout.prop(screen, "use_play_3d_editors") layout.prop(screen, "use_play_animation_editors") layout.prop(screen, "use_play_properties_editors") @@ -218,67 +259,59 @@ class TIME_MT_playback(Menu): layout.prop(screen, "use_play_clip_editors") layout.separator() - layout.prop(screen, "use_follow") - layout.separator() - layout.prop(scene, "use_frame_drop", text="Frame Dropping") - layout.prop(scene, "use_audio_sync", text="AV-sync", icon='SPEAKER') - layout.prop(scene, "use_audio") - layout.prop(scene, "use_audio_scrub") + row = layout.row(align=True) + row.operator("anim.start_frame_set") + row.operator("anim.end_frame_set") -class TIME_MT_autokey(Menu): - bl_label = "Auto-Keyframing Mode" +class TIME_PT_keyframing_settings(TimelinePanelButtons, Panel): + bl_label = "Keyframing Settings" + bl_options = {'HIDE_HEADER'} + bl_region_type = 'HEADER' + + @classmethod + def poll(cls, context): + # only for timeline editor + return cls.has_timeline(context) def draw(self, context): layout = self.layout - toolsettings = context.tool_settings - - layout.prop_enum(toolsettings, "auto_keying_mode", 'ADD_REPLACE_KEYS') - layout.prop_enum(toolsettings, "auto_keying_mode", 'REPLACE_KEYS') - -def marker_menu_generic(layout): - from bpy import context - - # layout.operator_context = 'EXEC_REGION_WIN' - - layout.column() - layout.operator("marker.add", "Add Marker") - layout.operator("marker.duplicate", text="Duplicate Marker") - - if len(bpy.data.scenes) > 10: - layout.operator_context = 'INVOKE_DEFAULT' - layout.operator("marker.make_links_scene", text="Duplicate Marker to Scene...", icon='OUTLINER_OB_EMPTY') - else: - layout.operator_menu_enum("marker.make_links_scene", "scene", text="Duplicate Marker to Scene") - - layout.operator("marker.delete", text="Delete Marker") - - layout.separator() - - layout.operator("marker.rename", text="Rename Marker") - layout.operator("marker.move", text="Grab/Move Marker") + scene = context.scene + toolsettings = context.tool_settings + userprefs = context.user_preferences - layout.separator() + col = layout.column(align=True) + col.label("Active Keying Set:") + row = col.row(align=True) + row.prop_search(scene.keying_sets_all, "active", scene, "keying_sets_all", text="") + row.operator("anim.keyframe_insert", text="", icon='KEY_HLT') + row.operator("anim.keyframe_delete", text="", icon='KEY_DEHLT') - layout.operator("screen.marker_jump", text="Jump to Next Marker").next = True - layout.operator("screen.marker_jump", text="Jump to Previous Marker").next = False + col = layout.column(align=True) + col.label("New Keyframe Type:") + col.prop(toolsettings, "keyframe_type", text="") + + col = layout.column(align=True) + col.label("Auto Keyframing:") + row = col.row() + row.prop(toolsettings, "auto_keying_mode", text="") + row.prop(toolsettings, "use_keyframe_insert_keyingset", text="") + if not userprefs.edit.use_keyframe_insert_available: + col.prop(toolsettings, "use_record_with_nla", text="Layered Recording") - layout.separator() - ts = context.tool_settings - layout.prop(ts, "lock_markers") +################################### classes = ( - TIME_HT_header, + TIME_HT_editor_buttons, TIME_MT_editor_menus, TIME_MT_marker, TIME_MT_view, TIME_MT_cache, - TIME_MT_frame, - TIME_MT_playback, - TIME_MT_autokey, + TIME_PT_playback, + TIME_PT_keyframing_settings, ) if __name__ == "__main__": # only for live edit. diff --git a/release/scripts/startup/bl_ui/space_toolsystem_common.py b/release/scripts/startup/bl_ui/space_toolsystem_common.py new file mode 100644 index 00000000000..cb6d3851d02 --- /dev/null +++ b/release/scripts/startup/bl_ui/space_toolsystem_common.py @@ -0,0 +1,686 @@ +# ##### BEGIN GPL LICENSE BLOCK ##### +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# ##### END GPL LICENSE BLOCK ##### + +# <pep8 compliant> +import bpy +from bpy.types import ( + Menu, +) + +__all__ = ( + "ToolSelectPanelHelper", + "ToolDef", +) + +# Support reloading icons. +if "_icon_cache" in locals(): + release = bpy.app.icons.release + for icon_value in _icon_cache.values(): + if icon_value != 0: + release(icon_value) + del release + + +# (filename -> icon_value) map +_icon_cache = {} + + +def _keymap_fn_from_seq(keymap_data): + + # standalone + def _props_assign_recursive(rna_props, py_props): + for prop_id, value in py_props.items(): + if isinstance(value, dict): + _props_assign_recursive(getattr(rna_props, prop_id), value) + else: + setattr(rna_props, prop_id, value) + + def keymap_fn(km): + for op_idname, op_props_dict, kmi_kwargs in keymap_fn.keymap_data: + kmi = km.keymap_items.new(op_idname, **kmi_kwargs) + kmi_props = kmi.properties + if op_props_dict: + _props_assign_recursive(kmi.properties, op_props_dict) + keymap_fn.keymap_data = keymap_data + return keymap_fn + + +def _item_is_fn(item): + return (not (type(item) is ToolDef) and callable(item)) + + +from collections import namedtuple +ToolDef = namedtuple( + "ToolDef", + ( + # The name to display in the interface. + "text", + # The name of the icon to use (found in ``release/datafiles/icons``) or None for no icon. + "icon", + # An optional cursor to use when this tool is active. + "cursor", + # An optional manipulator group to activate when the tool is set or None for no widget. + "widget", + # Optional keymap for tool, either: + # - A function that populates a keymaps passed in as an argument. + # - A tuple filled with triple's of: + # ``(operator_id, operator_properties, keymap_item_args)``. + # + # Warning: currently 'from_dict' this is a list of one item, + # so internally we can swap the keymap function for the keymap it's self. + # This isn't very nice and may change, tool definitions shouldn't care about this. + "keymap", + # Optional data-block assosiated with this tool. + # (Typically brush name, usage depends on mode, we could use for non-brush ID's in other modes). + "data_block", + # Optional draw settings (operator options, toolsettings). + "draw_settings", + ) +) +del namedtuple + + +def from_dict(kw_args): + """ + Use so each tool can avoid defining all members of the named tuple. + Also convert the keymap from a tuple into a function + (since keymap is a callback). + """ + kw = { + "icon": None, + "cursor": None, + "widget": None, + "keymap": None, + "data_block": None, + "draw_settings": None, + } + kw.update(kw_args) + + keymap = kw["keymap"] + if kw["keymap"] is None: + pass + elif type(keymap) is tuple: + keymap = [_keymap_fn_from_seq(keymap)] + else: + keymap = [keymap] + kw["keymap"] = keymap + return ToolDef(**kw) + + +def from_fn(fn): + """ + Use as decorator so we can define functions. + """ + return ToolDef.from_dict(fn()) + + +ToolDef.from_dict = from_dict +ToolDef.from_fn = from_fn +del from_dict +del from_fn + + +class ToolSelectPanelHelper: + """ + Generic Class, can be used for any toolbar. + + - keymap_prefix: + The text prefix for each key-map for this spaces tools. + - tools_all(): + Returns (context_mode, tools) tuple pair for all tools defined. + - tools_from_context(context, mode=None): + Returns tools available in this context. + + Each tool is a 'ToolDef' or None for a separator in the toolbar, use ``None``. + """ + + @staticmethod + def _tool_class_from_space_type(space_type): + return next( + (cls for cls in ToolSelectPanelHelper.__subclasses__() + if cls.bl_space_type == space_type), + None + ) + + @staticmethod + def _icon_value_from_icon_handle(icon_name): + import os + if icon_name is not None: + assert(type(icon_name) is str) + icon_value = _icon_cache.get(icon_name) + if icon_value is None: + dirname = bpy.utils.resource_path('LOCAL') + if not os.path.exists(dirname): + # TODO(campbell): use a better way of finding datafiles. + dirname = bpy.utils.resource_path('SYSTEM') + filename = os.path.join(dirname, "datafiles", "icons", icon_name + ".dat") + try: + icon_value = bpy.app.icons.new_triangles_from_file(filename) + except Exception as ex: + if not os.path.exists(filename): + print("Missing icons:", filename, ex) + else: + print("Corrupt icon:", filename, ex) + # Use none as a fallback (avoids layout issues). + if icon_name != "none": + icon_value = ToolSelectPanelHelper._icon_value_from_icon_handle("none") + else: + icon_value = 0 + _icon_cache[icon_name] = icon_value + return icon_value + else: + return 0 + + @staticmethod + def _tools_flatten(tools): + """ + Flattens, skips None and calls generators. + """ + for item in tools: + if item is None: + yield None + elif type(item) is tuple: + for sub_item in item: + if sub_item is None: + yield None + elif _item_is_fn(sub_item): + yield from sub_item(context) + else: + yield sub_item + else: + if _item_is_fn(item): + yield from item(context) + else: + yield item + + @staticmethod + def _tools_flatten_with_tool_index(tools): + for item in tools: + if item is None: + yield None, -1 + elif type(item) is tuple: + i = 0 + for sub_item in item: + if sub_item is None: + yield None + elif _item_is_fn(sub_item): + for item_dyn in sub_item(context): + yield item_dyn, i + i += 1 + else: + yield sub_item, i + i += 1 + else: + if _item_is_fn(item): + for item_dyn in item(context): + yield item_dyn, -1 + else: + yield item, -1 + + @staticmethod + def _tool_get_active(context, space_type, mode, with_icon=False): + """ + Return the active Python tool definition and icon name. + """ + workspace = context.workspace + cls = ToolSelectPanelHelper._tool_class_from_space_type(space_type) + if cls is not None: + tool_active = ToolSelectPanelHelper._tool_active_from_context(context, space_type, mode) + tool_active_text = getattr(tool_active, "name", None) + for item in ToolSelectPanelHelper._tools_flatten(cls.tools_from_context(context, mode)): + if item is not None: + if item.text == tool_active_text: + if with_icon: + icon_value = ToolSelectPanelHelper._icon_value_from_icon_handle(item.icon) + else: + icon_value = 0 + return (item, tool_active, icon_value) + return None, None, 0 + + @staticmethod + def _tool_get_by_name(context, space_type, text): + """ + Return the active Python tool definition and index (if in sub-group, else -1). + """ + cls = ToolSelectPanelHelper._tool_class_from_space_type(space_type) + if cls is not None: + for item, index in ToolSelectPanelHelper._tools_flatten_with_tool_index(cls.tools_from_context(context)): + if item is not None: + if item.text == text: + return (cls, item, index) + return None, None, -1 + + @staticmethod + def _tool_active_from_context(context, space_type, mode=None, create=False): + if space_type == 'VIEW_3D': + if mode is None: + mode = context.mode + tool = context.workspace.tools.from_space_view3d_mode(mode, create) + if tool is not None: + return tool + elif space_type == 'IMAGE_EDITOR': + space_data = context.space_data + if mode is None: + mode = space_data.mode + tool = context.workspace.tools.from_space_image_mode(mode, create) + if tool is not None: + return tool + return None + + @staticmethod + def _tool_text_from_button(context): + return context.button_operator.name + + @classmethod + def _km_action_simple(cls, kc, context_mode, text, keymap_fn): + if context_mode is None: + context_mode = "All" + km_idname = f"{cls.keymap_prefix} {context_mode}, {text}" + km = kc.keymaps.get(km_idname) + if km is None: + km = kc.keymaps.new(km_idname, space_type=cls.bl_space_type, region_type='WINDOW') + keymap_fn[0](km) + keymap_fn[0] = km + + @classmethod + def register(cls): + wm = bpy.context.window_manager + + # XXX, should we be manipulating the user-keyconfig on load? + # Perhaps this should only add when keymap items don't already exist. + # + # This needs some careful consideration. + kc = wm.keyconfigs.user + + # Track which tool-group was last used for non-active groups. + # Blender stores the active tool-group index. + # + # {tool_name_first: index_in_group, ...} + cls._tool_group_active = {} + + # ignore in background mode + if kc is None: + return + + for context_mode, tools in cls.tools_all(): + for item_parent in tools: + if item_parent is None: + continue + for item in item_parent if (type(item_parent) is tuple) else (item_parent,): + # skip None or generator function + if item is None or _item_is_fn(item): + continue + keymap_data = item.keymap + if keymap_data is not None and callable(keymap_data[0]): + text = item.text + icon_name = item.icon + cls._km_action_simple(kc, context_mode, text, keymap_data) + + # ------------------------------------------------------------------------- + # Layout Generators + # + # Meaning of recieved values: + # - Bool: True for a separator, otherwise False for regular tools. + # - None: Signal to finish (complete any final operations, e.g. add padding). + + @staticmethod + def _layout_generator_single_column(layout): + scale_y = 2.0 + + col = layout.column(align=True) + col.scale_y = scale_y + is_sep = False + while True: + if is_sep is True: + col = layout.column(align=True) + col.scale_y = scale_y + elif is_sep is None: + yield None + return + is_sep = yield col + + @staticmethod + def _layout_generator_multi_columns(layout, column_count): + scale_y = 2.0 + scale_x = 2.2 + column_last = column_count - 1 + + col = layout.column(align=True) + + row = col.row(align=True) + + row.scale_x = scale_x + row.scale_y = scale_y + + is_sep = False + column_index = 0 + while True: + if is_sep is True: + if column_index != column_last: + row.label("") + col = layout.column(align=True) + row = col.row(align=True) + row.scale_x = scale_x + row.scale_y = scale_y + column_index = 0 + + is_sep = yield row + if is_sep is None: + if column_index == column_last: + row.label("") + yield None + return + + if column_index == column_count: + column_index = 0 + row = col.row(align=True) + row.scale_x = scale_x + row.scale_y = scale_y + column_index += 1 + + @staticmethod + def _layout_generator_detect_from_region(layout, region): + """ + Choose an appropriate layout for the toolbar. + """ + # Currently this just checks the width, + # we could have different layouts as preferences too. + system = bpy.context.user_preferences.system + view2d = region.view2d + view2d_scale = ( + view2d.region_to_view(1.0, 0.0)[0] - + view2d.region_to_view(0.0, 0.0)[0] + ) + width_scale = region.width * view2d_scale / system.ui_scale + + if width_scale > 120.0: + show_text = True + column_count = 1 + else: + show_text = False + # 2 column layout, disabled + if width_scale > 80.0: + column_count = 2 + use_columns = True + else: + column_count = 1 + + if column_count == 1: + ui_gen = ToolSelectPanelHelper._layout_generator_single_column(layout) + else: + ui_gen = ToolSelectPanelHelper._layout_generator_multi_columns(layout, column_count=column_count) + + return ui_gen, show_text + + + @classmethod + def draw_cls(cls, layout, context, detect_layout=True): + # Use a classmethod so it can be called outside of a panel context. + + # XXX, this UI isn't very nice. + # We might need to create new button types for this. + # Since we probably want: + # - tool-tips that include multiple key shortcuts. + # - ability to click and hold to expose sub-tools. + + space_type = context.space_data.type + tool_active_text = getattr( + ToolSelectPanelHelper._tool_active_from_context(context, space_type), + "name", None, + ) + + if detect_layout: + ui_gen, show_text = cls._layout_generator_detect_from_region(layout, context.region) + else: + ui_gen = ToolSelectPanelHelper._layout_generator_single_column(layout) + show_text = True + + # Start iteration + ui_gen.send(None) + + for item in cls.tools_from_context(context): + if item is None: + ui_gen.send(True) + continue + + if type(item) is tuple: + is_active = False + i = 0 + for i, sub_item in enumerate(item): + if sub_item is None: + continue + is_active = (sub_item.text == tool_active_text) + if is_active: + index = i + break + del i, sub_item + + if is_active: + # not ideal, write this every time :S + cls._tool_group_active[item[0].text] = index + else: + index = cls._tool_group_active.get(item[0].text, 0) + + item = item[index] + use_menu = True + else: + index = -1 + use_menu = False + + is_active = (item.text == tool_active_text) + icon_value = ToolSelectPanelHelper._icon_value_from_icon_handle(item.icon) + + sub = ui_gen.send(False) + + if use_menu: + sub.operator_menu_hold( + "wm.tool_set_by_name", + text=item.text if show_text else "", + depress=is_active, + menu="WM_MT_toolsystem_submenu", + icon_value=icon_value, + ).name = item.text + else: + sub.operator( + "wm.tool_set_by_name", + text=item.text if show_text else "", + depress=is_active, + icon_value=icon_value, + ).name = item.text + # Signal to finish any remaining layout edits. + ui_gen.send(None) + + def draw(self, context): + self.draw_cls(self.layout, context) + + @staticmethod + def draw_active_tool_header(context, layout): + # BAD DESIGN WARNING: last used tool + workspace = context.workspace + space_type = workspace.tools_space_type + mode = workspace.tools_mode + item, tool, icon_value = ToolSelectPanelHelper._tool_get_active(context, space_type, mode, with_icon=True) + if item is None: + return + # Note: we could show 'item.text' here but it makes the layout jitter when switcuing tools. + layout.label(" ", icon_value=icon_value) + draw_settings = item.draw_settings + if draw_settings is not None: + draw_settings(context, layout, tool) + + +# The purpose of this menu is to be a generic popup to select between tools +# in cases when a single tool allows to select alternative tools. +class WM_MT_toolsystem_submenu(Menu): + bl_label = "" + + @staticmethod + def _tool_group_from_button(context): + # Lookup the tool definitions based on the space-type. + cls = ToolSelectPanelHelper._tool_class_from_space_type(context.space_data.type) + if cls is not None: + button_text = ToolSelectPanelHelper._tool_text_from_button(context) + for item_group in cls.tools_from_context(context): + if type(item_group) is tuple: + for sub_item in item_group: + if sub_item.text == button_text: + return cls, item_group + return None, None + + def draw(self, context): + layout = self.layout + layout.scale_y = 2.0 + + cls, item_group = self._tool_group_from_button(context) + if item_group is None: + # Should never happen, just in case + layout.label("Unable to find toolbar group") + return + + for item in item_group: + if item is None: + layout.separator() + continue + icon_value = ToolSelectPanelHelper._icon_value_from_icon_handle(item.icon) + layout.operator( + "wm.tool_set_by_name", + text=item.text, + icon_value=icon_value, + ).name = item.text + + +def _activate_by_item(context, space_type, item, index): + tool = ToolSelectPanelHelper._tool_active_from_context(context, space_type, create=True) + tool.setup( + name=item.text, + keymap=item.keymap[0].name if item.keymap is not None else "", + cursor=item.cursor or 'DEFAULT', + manipulator_group=item.widget or "", + data_block=item.data_block or "", + index=index, + ) + + +def activate_by_name(context, space_type, text): + cls, item, index = ToolSelectPanelHelper._tool_get_by_name(context, space_type, text) + if item is None: + return False + _activate_by_item(context, space_type, item, index) + return True + + +def activate_by_name_or_cycle(context, space_type, text, offset=1): + + # Only cycle when the active tool is activated again. + cls, item, index = ToolSelectPanelHelper._tool_get_by_name(context, space_type, text) + if item is None: + return False + + tool_active = ToolSelectPanelHelper._tool_active_from_context(context, space_type) + text_active = getattr(tool_active, "name", None) + + text_current = "" + for item_group in cls.tools_from_context(context): + if type(item_group) is tuple: + index_current = cls._tool_group_active.get(item_group[0].text, 0) + ok = False + for i, sub_item in enumerate(item_group): + if sub_item.text == text: + text_current = item_group[index_current].text + break + if text_current: + break + + if text_current == "": + return activate_by_name(context, space_type, text) + if text_active != text_current: + return activate_by_name(context, space_type, text_current) + + index_found = (tool_active.index + offset) % len(item_group) + + cls._tool_group_active[item_group[0].text] = index_found + + item_found = item_group[index_found] + _activate_by_item(context, space_type, item_found, index_found) + return True + + +def keymap_from_context(context, space_type): + """ + Keymap for popup toolbar, currently generated each time. + """ + use_simple_keymap = False + km_name = "Toolbar Popup" + wm = context.window_manager + keyconf = wm.keyconfigs.active + keymap = keyconf.keymaps.get(km_name) + if keymap is None: + keymap = keyconf.keymaps.new(km_name, space_type='EMPTY', region_type='TEMPORARY') + for kmi in keymap.keymap_items: + keymap.keymap_items.remove(kmi) + + items = [] + cls = ToolSelectPanelHelper._tool_class_from_space_type(space_type) + for i, item in enumerate( + ToolSelectPanelHelper._tools_flatten(cls.tools_from_context(context)) + ): + if item is not None: + if use_simple_keymap: + # Simply assign a key from A-Z + items.append(((chr(ord('A') + i)), item.text)) + kmi = keymap.keymap_items.new("wm.tool_set_by_name", key, 'PRESS') + kmi.properties.name = item.text + continue + + if not item.keymap: + continue + + # Only check the first item in the tools key-map (a little arbitrary). + kmi_first = item.keymap[0].keymap_items[0] + kmi_found = wm.keyconfigs.find_item_from_operator( + idname=kmi_first.idname, + # properties=kmi_first.properties, # prevents matches, don't use. + )[1] + if kmi_found is not None: + kmi_found_type = kmi_found.type + # Only for single keys. + if len(kmi_found_type) == 1: + kmi = keymap.keymap_items.new( + idname="wm.tool_set_by_name", + type=kmi_found_type, + value='PRESS', + any=kmi_found.any, + shift=kmi_found.shift, + ctrl=kmi_found.ctrl, + alt=kmi_found.alt, + oskey=kmi_found.oskey, + key_modifier=kmi_found.key_modifier, + ) + kmi.properties.name = item.text + + wm.keyconfigs.update() + return keymap + +classes = ( + WM_MT_toolsystem_submenu, +) + +if __name__ == "__main__": # only for live edit. + from bpy.utils import register_class + for cls in classes: + register_class(cls) diff --git a/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py b/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py new file mode 100644 index 00000000000..42fac9e03a4 --- /dev/null +++ b/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py @@ -0,0 +1,1071 @@ +# ##### BEGIN GPL LICENSE BLOCK ##### +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# ##### END GPL LICENSE BLOCK ##### + +# <pep8 compliant> + +# For now group all tools together +# we may want to move these into per space-type files. +# +# For now keep this in a single file since it's an area that may change, +# so avoid making changes all over the place. + +from bpy.types import Panel + +from .space_toolsystem_common import ( + ToolSelectPanelHelper, + ToolDef, +) + + +def generate_from_brushes_ex( + context, *, + icon_prefix, + brush_test_attr, + brush_category_attr, + brush_category_layout, +): + # Categories + brush_categories = {} + for brush in context.blend_data.brushes: + if getattr(brush, brush_test_attr): + category = getattr(brush, brush_category_attr) + name = brush.name + brush_categories.setdefault(category, []).append( + ToolDef.from_dict( + dict( + text=name, + icon=icon_prefix + category.lower(), + data_block=name, + ) + ) + ) + + def tools_from_brush_group(groups): + assert(type(groups) is tuple) + if len(groups) == 1: + tool_defs = tuple(brush_categories.pop(groups[0], ())) + else: + tool_defs = tuple(item for g in groups for item in brush_categories.pop(g, ())) + if len(tool_defs) > 1: + return (tool_defs,) + else: + return tool_defs + + # Each item below is a single toolbar entry: + # Grouped for multiple or none if no brushes are found. + tool_defs = tuple( + tool_def + for category in brush_category_layout + for tool_def in tools_from_brush_group(category) + ) + # Ensure we use all types. + if brush_categories: + print(brush_categories) + assert(len(brush_categories) == 0) + return tool_defs + + +class _defs_view3d_generic: + @ToolDef.from_fn + def cursor(): + return dict( + text="Cursor", + icon="ops.generic.cursor", + keymap=( + ("view3d.cursor3d", dict(), dict(type='ACTIONMOUSE', value='PRESS')), + ("transform.translate", + dict(release_confirm=True, cursor_transform=True), + dict(type='EVT_TWEAK_A', value='ANY'), + ), + ), + ) + + @ToolDef.from_fn + def cursor_click(): + return dict( + text="Cursor Click", + icon="ops.generic.cursor", + keymap=( + ("view3d.cursor3d", dict(), dict(type='ACTIONMOUSE', value='CLICK')), + ), + ) + + @ToolDef.from_fn + def ruler(): + return dict( + text="Ruler/Protractor", + icon="ops.view3d.ruler", + widget="VIEW3D_WGT_ruler", + keymap=( + ("view3d.ruler_add", dict(), dict(type='EVT_TWEAK_A', value='ANY')), + ), + ) + + +class _defs_transform: + + @ToolDef.from_fn + def translate(): + return dict( + text="Move", + cursor='SCROLL_XY', + icon="ops.transform.translate", + widget="TRANSFORM_WGT_manipulator", + keymap=( + ("transform.translate", dict(release_confirm=True), dict(type='EVT_TWEAK_A', value='ANY')), + ), + ) + + @ToolDef.from_fn + def rotate(): + return dict( + text="Rotate", + cursor='SCROLL_XY', + icon="ops.transform.rotate", + widget="TRANSFORM_WGT_manipulator", + keymap=( + ("transform.rotate", dict(release_confirm=True), dict(type='EVT_TWEAK_A', value='ANY')), + ), + ) + + @ToolDef.from_fn + def scale(): + return dict( + text="Scale", + cursor='SCROLL_XY', + icon="ops.transform.resize", + widget="TRANSFORM_WGT_manipulator", + keymap=( + ("transform.resize", dict(release_confirm=True), dict(type='EVT_TWEAK_A', value='ANY')), + ), + ) + + @ToolDef.from_fn + def scale_cage(): + return dict( + text="Scale Cage", + icon="ops.transform.resize.cage", + widget="VIEW3D_WGT_xform_cage", + ) + + @ToolDef.from_fn + def transform(): + return dict( + text="Transform", + icon="ops.transform.transform", + widget="TRANSFORM_WGT_manipulator", + # No keymap default action, only for manipulators! + ) + + +class _defs_view3d_select: + + @ToolDef.from_fn + def border(): + return dict( + text="Select Border", + icon="ops.generic.select_border", + widget=None, + keymap=( + ("view3d.select_border", + dict(deselect=False), + dict(type='EVT_TWEAK_A', value='ANY')), + ("view3d.select_border", + dict(deselect=True), + dict(type='EVT_TWEAK_A', value='ANY', ctrl=True)), + ), + ) + + @ToolDef.from_fn + def circle(): + return dict( + text="Select Circle", + icon="ops.generic.select_circle", + widget=None, + keymap=( + ("view3d.select_circle", + dict(deselect=False), + dict(type='ACTIONMOUSE', value='PRESS')), + ("view3d.select_circle", + dict(deselect=True), + dict(type='ACTIONMOUSE', value='PRESS', ctrl=True)), + ), + ) + + @ToolDef.from_fn + def lasso(): + return dict( + text="Select Lasso", + icon="ops.generic.select_lasso", + widget=None, + keymap=( + ("view3d.select_lasso", + dict(deselect=False), + dict(type='EVT_TWEAK_A', value='ANY')), + ("view3d.select_lasso", + dict(deselect=True), + dict(type='EVT_TWEAK_A', value='ANY', ctrl=True)), + ), + ) +# ----------------------------------------------------------------------------- +# Object Modes (named based on context.mode) + + +class _defs_edit_armature: + + @ToolDef.from_fn + def roll(): + return dict( + text="Roll", + icon="ops.armature.bone.roll", + widget=None, + keymap=( + ("transform.transform", + dict(release_confirm=True, mode='BONE_ROLL'), + dict(type='EVT_TWEAK_A', value='ANY'),), + ), + ) + + @ToolDef.from_fn + def bone_envelope(): + return dict( + text="Bone Envelope", + icon="ops.transform.bone_envelope", + widget=None, + keymap=( + ("transform.transform", + dict(release_confirm=True, mode='BONE_ENVELOPE'), + dict(type='ACTIONMOUSE', value='PRESS')), + ), + ) + + @ToolDef.from_fn + def bone_size(): + return dict( + text="Bone Size", + icon="ops.transform.bone_size", + widget=None, + keymap=( + ("transform.transform", + dict(release_confirm=True, mode='BONE_SIZE'), + dict(type='ACTIONMOUSE', value='PRESS')), + ), + ) + + @ToolDef.from_fn + def extrude(): + return dict( + text="Extrude", + icon="ops.armature.extrude_move", + widget=None, + keymap=( + ("armature.click_extrude", dict(), dict(type='ACTIONMOUSE', value='PRESS')), + ), + ) + + @ToolDef.from_fn + def extrude_cursor(): + return dict( + text="Extrude to Cursor", + icon="ops.armature.extrude_cursor", + widget=None, + keymap=( + ("armature.click_extrude", dict(), dict(type='ACTIONMOUSE', value='PRESS')), + ), + ) + + +class _defs_edit_mesh: + + + @ToolDef.from_fn + def cube_add(): + return dict( + text="Add Cube", + icon="ops.mesh.primitive_cube_add_manipulator", + widget=None, + keymap=( + ("view3d.cursor3d", dict(), dict(type='ACTIONMOUSE', value='CLICK')), + ("mesh.primitive_cube_add_manipulator", dict(), dict(type='EVT_TWEAK_A', value='ANY')), + ), + ) + + @ToolDef.from_fn + def rip_region(): + def draw_settings(context, layout, tool): + wm = context.window_manager + props = tool.operator_properties("mesh.rip_move") + props_macro = props.MESH_OT_rip + layout.prop(props_macro, "use_fill") + + return dict( + text="Rip Region", + icon="ops.mesh.rip", + widget=None, + keymap=( + ("mesh.rip_move", + dict(TRANSFORM_OT_translate=dict(release_confirm=True)), + dict(type='ACTIONMOUSE', value='PRESS')), + ), + draw_settings=draw_settings, + ) + + @ToolDef.from_fn + def rip_edge(): + return dict( + text="Rip Edge", + icon="ops.mesh.rip_edge", + widget=None, + keymap=( + ("mesh.rip_edge_edge_move", dict(), + dict(type='ACTIONMOUSE', value='PRESS')), + ), + ) + + @ToolDef.from_fn + def poly_build(): + return dict( + text="Poly Build", + icon="ops.mesh.polybuild_hover", + widget=None, + keymap=( + ("mesh.polybuild_face_at_cursor_move", + dict(TRANSFORM_OT_translate=dict(release_confirm=True)), + dict(type='ACTIONMOUSE', value='PRESS')), + ("mesh.polybuild_split_at_cursor_move", + dict(TRANSFORM_OT_translate=dict(release_confirm=True)), + dict(type='ACTIONMOUSE', value='PRESS', ctrl=True)), + ("mesh.polybuild_dissolve_at_cursor", dict(), dict(type='ACTIONMOUSE', value='CLICK', alt=True)), + ("mesh.polybuild_hover", dict(use_boundary=False), dict(type='MOUSEMOVE', value='ANY', alt=True)), + ("mesh.polybuild_hover", dict(use_boundary=True), dict(type='MOUSEMOVE', value='ANY', any=True)), + ), + ) + + @ToolDef.from_fn + def edge_slide(): + return dict( + text="Edge Slide", + icon="ops.transform.edge_slide", + widget=None, + keymap=( + ("transform.edge_slide", dict(release_confirm=True), + dict(type='ACTIONMOUSE', value='PRESS') + ), + ), + ) + + @ToolDef.from_fn + def vert_slide(): + return dict( + text="Vertex Slide", + icon="ops.transform.vert_slide", + widget=None, + keymap=( + ("transform.vert_slide", dict(release_confirm=True), + dict(type='ACTIONMOUSE', value='PRESS')), + ), + ) + + @ToolDef.from_fn + def spin(): + return dict( + text="Spin", + icon="ops.mesh.spin", + widget=None, + keymap=( + ("mesh.spin", dict(), + dict(type='ACTIONMOUSE', value='PRESS')), + ), + ) + + @ToolDef.from_fn + def spin_duplicate(): + return dict( + text="Spin (Duplicate)", + icon="ops.mesh.spin.duplicate", + widget=None, + keymap=( + ("mesh.spin", dict(dupli=True), + dict(type='ACTIONMOUSE', value='PRESS')), + ), + ) + + @ToolDef.from_fn + def inset(): + def draw_settings(context, layout, tool): + wm = context.window_manager + props = tool.operator_properties("mesh.inset") + layout.prop(props, "use_outset") + layout.prop(props, "use_individual") + layout.prop(props, "use_even_offset") + layout.prop(props, "use_relative_offset") + + return dict( + text="Inset Faces", + icon="ops.mesh.inset", + widget=None, + keymap=( + ("mesh.inset", dict(release_confirm=True), + dict(type='ACTIONMOUSE', value='PRESS')), + ), + draw_settings=draw_settings, + ) + + @ToolDef.from_fn + def bevel(): + return dict( + text="Bevel", + icon="ops.mesh.bevel", + widget=None, + keymap=( + ("mesh.bevel", dict(), + dict(type='ACTIONMOUSE', value='PRESS')), + ), + ) + + @ToolDef.from_fn + def extrude(): + return dict( + text="Extrude Region", + icon="ops.mesh.extrude_region_move", + widget="MESH_WGT_extrude", + keymap=( + ("mesh.extrude_context_move", dict(TRANSFORM_OT_translate=dict(release_confirm=True)), + dict(type='EVT_TWEAK_A', value='ANY')), + ), + ) + + @ToolDef.from_fn + def extrude_individual(): + return dict( + text="Extrude Individual", + icon="ops.mesh.extrude_faces_move", + widget=None, + keymap=( + ("mesh.extrude_faces_move", dict(TRANSFORM_OT_shrink_fatten=dict(release_confirm=True)), + dict(type='EVT_TWEAK_A', value='ANY')), + ), + ) + + @ToolDef.from_fn + def extrude_cursor(): + return dict( + text="Extrude to Cursor", + icon="ops.mesh.dupli_extrude_cursor", + widget=None, + keymap=( + ("mesh.dupli_extrude_cursor", dict(), dict(type='ACTIONMOUSE', value='PRESS')), + ), + ) + + @ToolDef.from_fn + def loopcut_slide(): + return dict( + text="Loop Cut", + icon="ops.mesh.loopcut_slide", + widget=None, + keymap=( + ("mesh.loopcut_slide", dict(), dict(type='ACTIONMOUSE', value='PRESS')), + ), + ) + + @ToolDef.from_fn + def offset_edge_loops_slide(): + return dict( + text="Offset Edge Loop Cut", + icon="ops.mesh.offset_edge_loops_slide", + widget=None, + keymap=( + ("mesh.offset_edge_loops_slide", dict(), dict(type='ACTIONMOUSE', value='PRESS')), + ), + ) + + @ToolDef.from_fn + def vertex_smooth(): + return dict( + text="Smooth", + icon="ops.mesh.vertices_smooth", + widget=None, + keymap=( + ("mesh.vertices_smooth", dict(), + dict(type='ACTIONMOUSE', value='PRESS')), + ), + ) + + @ToolDef.from_fn + def vertex_randomize(): + return dict( + text="Randomize", + icon="ops.transform.vertex_random", + widget=None, + keymap=( + ("transform.vertex_random", dict(), + dict(type='ACTIONMOUSE', value='PRESS')), + ), + ) + + @ToolDef.from_fn + def shrink_fatten(): + def draw_settings(context, layout, tool): + wm = context.window_manager + props = tool.operator_properties("transform.shrink_fatten") + layout.prop(props, "use_even_offset") + + return dict( + text="Shrink/Fatten", + icon="ops.transform.shrink_fatten", + widget=None, + keymap=( + ("transform.shrink_fatten", dict(release_confirm=True), + dict(type='ACTIONMOUSE', value='PRESS')), + ), + draw_settings=draw_settings, + ) + + @ToolDef.from_fn + def push_pull(): + return dict( + text="Push/Pull", + icon="ops.transform.push_pull", + widget=None, + keymap=( + ("transform.push_pull", dict(release_confirm=True), + dict(type='ACTIONMOUSE', value='PRESS')), + ), + ) + + @ToolDef.from_fn + def knife(): + def draw_settings(context, layout, tool): + wm = context.window_manager + props = tool.operator_properties("mesh.knife_tool") + layout.prop(props, "use_occlude_geometry") + layout.prop(props, "only_selected") + + return dict( + text="Knife", + icon="ops.mesh.knife_tool", + widget=None, + keymap=( + ("mesh.knife_tool", + dict(wait_for_input=False), + dict(type='ACTIONMOUSE', value='PRESS')), + ), + draw_settings=draw_settings, + ) + + @ToolDef.from_fn + def bisect(): + return dict( + text="Bisect", + icon="ops.mesh.bisect", + widget=None, + keymap=( + ("mesh.bisect", + dict(), + dict(type='EVT_TWEAK_A', value='ANY')), + ), + ) + + +class _defs_edit_curve: + + @ToolDef.from_fn + def draw(): + def draw_settings(context, layout, tool): + # Tool settings initialize operator options. + tool_settings = context.tool_settings + cps = tool_settings.curve_paint_settings + + col = layout.row() + + col.prop(cps, "curve_type") + + if cps.curve_type == 'BEZIER': + col.prop(cps, "error_threshold") + col.prop(cps, "fit_method") + col.prop(cps, "use_corners_detect") + + col = layout.row() + col.active = cps.use_corners_detect + col.prop(cps, "corner_angle") + + return dict( + text="Draw", + cursor='PAINT_BRUSH', + icon=None, + widget=None, + keymap=( + ("curve.draw", dict(wait_for_input=False), dict(type='ACTIONMOUSE', value='PRESS')), + ), + draw_settings=draw_settings, + ) + + @ToolDef.from_fn + def extrude_cursor(): + return dict( + text="Extrude Cursor", + icon=None, + widget=None, + keymap=( + ("curve.vertex_add", dict(), dict(type='ACTIONMOUSE', value='PRESS')), + ), + ) + + +class _defs_pose: + + @ToolDef.from_fn + def breakdown(): + return dict( + text="Breakdowner", + icon="ops.pose.breakdowner", + widget=None, + keymap=( + ("pose.breakdown", dict(), dict(type='ACTIONMOUSE', value='PRESS')), + ), + ) + + @ToolDef.from_fn + def push(): + return dict( + text="Push", + icon="ops.pose.push", + widget=None, + keymap=( + ("pose.push", dict(), dict(type='ACTIONMOUSE', value='PRESS')), + ), + ) + + @ToolDef.from_fn + def relax(): + return dict( + text="Relax", + icon="ops.pose.relax", + widget=None, + keymap=( + ("pose.relax", dict(), dict(type='ACTIONMOUSE', value='PRESS')), + ), + ) + + +class _defs_sculpt: + + @staticmethod + def generate_from_brushes(context): + return generate_from_brushes_ex( + context, + icon_prefix="brush.sculpt.", + brush_test_attr="use_paint_sculpt", + brush_category_attr="sculpt_tool", + brush_category_layout=( + ('DRAW',), + ('GRAB', 'THUMB'), + ('SNAKE_HOOK',), + ('BLOB', 'INFLATE'), + ('SMOOTH', 'SCRAPE', 'FLATTEN'), + ('CREASE', 'PINCH'), + ('CLAY', 'CLAY_STRIPS'), + ('LAYER',), + ('NUDGE', 'ROTATE'), + ('FILL',), + ('SIMPLIFY',), + ('MASK',), + ) + ) + + +class _defs_vertex_paint: + + @staticmethod + def generate_from_brushes(context): + return generate_from_brushes_ex( + context, + icon_prefix="brush.paint_vertex.", + brush_test_attr="use_paint_vertex", + brush_category_attr="vertex_tool", + brush_category_layout=( + ('MIX',), + ('BLUR', 'AVERAGE'), + ('SMEAR',), + ( + 'ADD', 'SUB', 'MUL', 'LIGHTEN', 'DARKEN', + 'COLORDODGE', 'DIFFERENCE', 'SCREEN', 'HARDLIGHT', + 'OVERLAY', 'SOFTLIGHT', 'EXCLUSION', 'LUMINOCITY', + 'SATURATION', 'HUE', 'ERASE_ALPHA', 'ADD_ALPHA', + ), + ) + ) + + +class _defs_texture_paint: + + @staticmethod + def generate_from_brushes(context): + return generate_from_brushes_ex( + context, + icon_prefix="brush.paint_texture.", + brush_test_attr="use_paint_image", + brush_category_attr="image_tool", + brush_category_layout=( + ('DRAW',), + ('SOFTEN',), + ('SMEAR',), + ('CLONE',), + ('FILL',), + ('MASK',), + ) + ) + + +class _defs_weight_paint: + + @staticmethod + def generate_from_brushes(context): + return generate_from_brushes_ex( + context, + icon_prefix="brush.paint_weight.", + brush_test_attr="use_paint_weight", + brush_category_attr="vertex_tool", + brush_category_layout=( + ('MIX',), + ('BLUR', 'AVERAGE'), + ('SMEAR',), + ( + 'ADD', 'SUB', 'MUL', 'LIGHTEN', 'DARKEN', + 'COLORDODGE', 'DIFFERENCE', 'SCREEN', 'HARDLIGHT', + 'OVERLAY', 'SOFTLIGHT', 'EXCLUSION', 'LUMINOCITY', + 'SATURATION', 'HUE', + ), + ) + ) + + @ToolDef.from_fn + def sample_weight(): + return dict( + text="Sample Weight", + icon="ops.paint.weight_sample", + widget=None, + keymap=( + ("paint.weight_sample", dict(), dict(type='ACTIONMOUSE', value='PRESS')), + ), + ) + + @ToolDef.from_fn + def sample_weight_group(): + return dict( + text="Sample Vertex Group", + icon="ops.paint.weight_sample_group", + widget=None, + keymap=( + ("paint.weight_sample_group", dict(), dict(type='ACTIONMOUSE', value='PRESS')), + ), + ) + + @ToolDef.from_fn + def gradient(): + def draw_settings(context, layout, tool): + wm = context.window_manager + props = tool.operator_properties("paint.weight_gradient") + layout.prop(props, "type") + + return dict( + text="Gradient", + icon="ops.paint.weight_gradient", + widget=None, + keymap=( + ("paint.weight_gradient", dict(), dict(type='EVT_TWEAK_A', value='ANY')), + ), + draw_settings=draw_settings, + ) + + +class _defs_uv_select: + + @ToolDef.from_fn + def border(): + return dict( + text="Select Border", + icon="ops.generic.select_border", + widget=None, + keymap=( + ("uv.select_border", + dict(deselect=False), + dict(type='EVT_TWEAK_A', value='ANY')), + # ("uv.select_border", + # dict(deselect=True), + # dict(type='EVT_TWEAK_A', value='ANY', ctrl=True)), + ), + ) + + @ToolDef.from_fn + def circle(): + return dict( + text="Select Circle", + icon="ops.generic.select_circle", + widget=None, + keymap=( + ("uv.select_circle", + dict(), # dict(deselect=False), + dict(type='ACTIONMOUSE', value='PRESS')), + # ("uv.select_circle", + # dict(deselect=True), + # dict(type='ACTIONMOUSE', value='PRESS', ctrl=True)), + ), + ) + + @ToolDef.from_fn + def lasso(): + return dict( + text="Select Lasso", + icon="ops.generic.select_lasso", + widget=None, + keymap=( + ("uv.select_lasso", + dict(deselect=False), + dict(type='EVT_TWEAK_A', value='ANY')), + # ("uv.select_lasso", + # dict(deselect=True), + # dict(type='EVT_TWEAK_A', value='ANY', ctrl=True)), + ), + ) + + +class IMAGE_PT_tools_active(ToolSelectPanelHelper, Panel): + bl_space_type = 'IMAGE_EDITOR' + bl_region_type = 'TOOLS' + bl_category = "Tools" + bl_label = "Tools" # not visible + bl_options = {'HIDE_HEADER'} + + # Satisfy the 'ToolSelectPanelHelper' API. + keymap_prefix = "Image Editor Tool: " + + @classmethod + def tools_from_context(cls, context, mode=None): + if mode is None: + mode = context.space_data.mode + for tools in (cls._tools[None], cls._tools.get(mode, ())): + for item in tools: + if not (type(item) is ToolDef) and callable(item): + yield from item(context) + else: + yield item + + @classmethod + def tools_all(cls): + yield from cls._tools.items() + + # for reuse + _tools_select = ( + ( + _defs_uv_select.border, + _defs_uv_select.circle, + _defs_uv_select.lasso, + ), + ) + + _tools = { + None: [ + # for all modes + ], + 'VIEW': [ + *_tools_select, + + ], + 'MASK': [ + None, + ], + 'PAINT': [ + _defs_texture_paint.generate_from_brushes, + ], + } + + +class VIEW3D_PT_tools_active(ToolSelectPanelHelper, Panel): + bl_space_type = 'VIEW_3D' + bl_region_type = 'TOOLS' + bl_category = "Tools" + bl_label = "Tools" # not visible + bl_options = {'HIDE_HEADER'} + + # Satisfy the 'ToolSelectPanelHelper' API. + keymap_prefix = "3D View Tool: " + + @classmethod + def tools_from_context(cls, context, mode=None): + if mode is None: + mode = context.mode + for tools in (cls._tools[None], cls._tools.get(mode, ())): + for item in tools: + if not (type(item) is ToolDef) and callable(item): + yield from item(context) + else: + yield item + + @classmethod + def tools_all(cls): + yield from cls._tools.items() + + # for reuse + _tools_transform = ( + ( + _defs_transform.translate, + _defs_transform.transform, + ), + _defs_transform.rotate, + ( + _defs_transform.scale, + _defs_transform.scale_cage, + ), + None, + _defs_view3d_generic.ruler, + ) + + _tools_select = ( + ( + _defs_view3d_select.border, + _defs_view3d_select.circle, + _defs_view3d_select.lasso, + ), + ) + + _tools = { + None: [ + _defs_view3d_generic.cursor, + # End group. + ], + 'OBJECT': [ + *_tools_select, + None, + *_tools_transform, + ], + 'POSE': [ + *_tools_select, + *_tools_transform, + None, + ( + _defs_pose.breakdown, + _defs_pose.push, + _defs_pose.relax, + ) + ], + 'EDIT_ARMATURE': [ + *_tools_select, + None, + *_tools_transform, + _defs_edit_armature.roll, + ( + _defs_edit_armature.bone_size, + _defs_edit_armature.bone_envelope, + ), + None, + ( + _defs_edit_armature.extrude, + _defs_edit_armature.extrude_cursor, + ) + ], + 'EDIT_MESH': [ + *_tools_select, + None, + *_tools_transform, + None, + _defs_edit_mesh.cube_add, + None, + ( + _defs_edit_mesh.extrude, + _defs_edit_mesh.extrude_individual, + _defs_edit_mesh.extrude_cursor, + ), + _defs_edit_mesh.inset, + _defs_edit_mesh.bevel, + ( + _defs_edit_mesh.loopcut_slide, + _defs_edit_mesh.offset_edge_loops_slide, + ), + ( + _defs_edit_mesh.knife, + _defs_edit_mesh.bisect, + ), + _defs_edit_mesh.poly_build, + ( + _defs_edit_mesh.spin, + _defs_edit_mesh.spin_duplicate, + ), + ( + _defs_edit_mesh.vertex_smooth, + _defs_edit_mesh.vertex_randomize, + ), + ( + _defs_edit_mesh.edge_slide, + _defs_edit_mesh.vert_slide, + ), + ( + _defs_edit_mesh.shrink_fatten, + _defs_edit_mesh.push_pull, + ), + ( + _defs_edit_mesh.rip_region, + _defs_edit_mesh.rip_edge, + ), + ], + 'EDIT_CURVE': [ + *_tools_select, + None, + *_tools_transform, + None, + _defs_edit_curve.draw, + _defs_edit_curve.extrude_cursor, + ], + 'PARTICLE': [ + # TODO(campbell): use cursor click tool to allow paint tools to run, + # we need to integrate particle system tools properly. + _defs_view3d_generic.cursor_click, + ], + 'SCULPT': [ + _defs_sculpt.generate_from_brushes, + ], + 'PAINT_TEXTURE': [ + _defs_texture_paint.generate_from_brushes, + ], + 'PAINT_VERTEX': [ + _defs_vertex_paint.generate_from_brushes, + ], + 'PAINT_WEIGHT': [ + _defs_weight_paint.generate_from_brushes, + None, + _defs_weight_paint.sample_weight, + _defs_weight_paint.sample_weight_group, + None, + # TODO, override brush events + *_tools_select, + None, + _defs_weight_paint.gradient, + ], + } + + +classes = ( + IMAGE_PT_tools_active, + VIEW3D_PT_tools_active, +) + +if __name__ == "__main__": # only for live edit. + from bpy.utils import register_class + for cls in classes: + register_class(cls) diff --git a/release/scripts/startup/bl_ui/space_topbar.py b/release/scripts/startup/bl_ui/space_topbar.py new file mode 100644 index 00000000000..243b36bdeb7 --- /dev/null +++ b/release/scripts/startup/bl_ui/space_topbar.py @@ -0,0 +1,706 @@ +# ##### BEGIN GPL LICENSE BLOCK ##### +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# ##### END GPL LICENSE BLOCK ##### + +# <pep8 compliant> +import bpy +from bpy.types import Header, Menu, Panel + + +class TOPBAR_HT_upper_bar(Header): + bl_space_type = 'TOPBAR' + + def draw(self, context): + region = context.region + + if region.alignment == 'RIGHT': + self.draw_right(context) + else: + self.draw_left(context) + + def draw_left(self, context): + layout = self.layout + + window = context.window + screen = context.screen + + layout.operator("wm.splash", text="", icon='BLENDER', emboss=False) + + INFO_MT_editor_menus.draw_collapsible(context, layout) + + layout.separator() + + if not screen.show_fullscreen: + layout.template_ID_tabs( + window, "workspace", + new="workspace.workspace_add_menu", + unlink="workspace.workspace_delete", + ) + else: + layout.operator( + "screen.back_to_previous", + icon='SCREEN_BACK', + text="Back to Previous", + ) + + def draw_right(self, context): + layout = self.layout + + window = context.window + scene = window.scene + + # Active workspace view-layer is retrieved through window, not through workspace. + layout.template_ID(window, "scene", new="scene.new", unlink="scene.delete") + + row = layout.row(align=True) + row.template_search( + window, "view_layer", + scene, "view_layers", + new="scene.view_layer_add", + unlink="scene.view_layer_remove") + + +class TOPBAR_HT_lower_bar(Header): + bl_space_type = 'TOPBAR' + bl_region_type = 'WINDOW' + + def draw(self, context): + layout = self.layout + region = context.region + + if region.alignment == 'LEFT': + self.draw_left(context) + elif region.alignment == 'RIGHT': + self.draw_right(context) + else: + self.draw_center(context) + + def draw_left(self, context): + layout = self.layout + layer = context.view_layer + object = layer.objects.active + + # Object Mode + # ----------- + object_mode = 'OBJECT' if object is None else object.mode + act_mode_item = bpy.types.Object.bl_rna.properties['mode'].enum_items[object_mode] + + layout.operator_menu_enum("object.mode_set", "mode", text=act_mode_item.name, icon=act_mode_item.icon) + + layout.template_header_3D_mode() + + def draw_center(self, context): + layout = self.layout + mode = context.mode + + # Active Tool + # ----------- + from .space_toolsystem_common import ToolSelectPanelHelper + ToolSelectPanelHelper.draw_active_tool_header(context, layout) + + # Object Mode Options + # ------------------- + + # Example of how toolsettings can be accessed as pop-overs. + + # TODO(campbell): editing options should be after active tool options + # (obviously separated for from the users POV) + draw_fn = getattr(_draw_left_context_mode, mode, None) + if draw_fn is not None: + draw_fn(context, layout) + + # Note: general mode options should be added to 'draw_right'. + if mode == 'SCULPT': + layout.popover_group(space_type='PROPERTIES', region_type='WINDOW', context=".paint_common", category="") + elif mode == 'PAINT_VERTEX': + layout.popover_group(space_type='PROPERTIES', region_type='WINDOW', context=".paint_common", category="") + elif mode == 'PAINT_WEIGHT': + layout.popover_group(space_type='PROPERTIES', region_type='WINDOW', context=".paint_common", category="") + elif mode == 'PAINT_TEXTURE': + layout.popover_group(space_type='PROPERTIES', region_type='WINDOW', context=".paint_common", category="") + elif mode == 'EDIT_ARMATURE': + pass + elif mode == 'EDIT_CURVE': + pass + elif mode == 'EDIT_MESH': + pass + elif mode == 'POSE': + pass + elif mode == 'PARTICLE': + pass + + def draw_right(self, context): + layout = self.layout + + # General options, note, these _could_ display at the RHS of the draw_left callback. + # we just want them not to be confused with tool options. + mode = context.mode + + if mode == 'SCULPT': + layout.popover_group(space_type='PROPERTIES', region_type='WINDOW', context=".sculpt_mode", category="") + elif mode == 'PAINT_VERTEX': + layout.popover_group(space_type='PROPERTIES', region_type='WINDOW', context=".vertexpaint", category="") + elif mode == 'PAINT_WEIGHT': + layout.popover_group(space_type='PROPERTIES', region_type='WINDOW', context=".weightpaint", category="") + elif mode == 'PAINT_TEXTURE': + layout.popover_group(space_type='PROPERTIES', region_type='WINDOW', context=".imagepaint", category="") + elif mode == 'EDIT_ARMATURE': + layout.popover_group(space_type='PROPERTIES', region_type='WINDOW', context=".armature_edit", category="") + elif mode == 'EDIT_CURVE': + layout.popover_group(space_type='PROPERTIES', region_type='WINDOW', context=".curve_edit", category="") + elif mode == 'EDIT_MESH': + layout.popover_group(space_type='PROPERTIES', region_type='WINDOW', context=".mesh_edit", category="") + elif mode == 'POSE': + layout.popover_group(space_type='PROPERTIES', region_type='WINDOW', context=".posemode", category="") + elif mode == 'PARTICLE': + layout.popover_group(space_type='PROPERTIES', region_type='WINDOW', context=".particlemode", category="") + + # 3D View Options, tsk. maybe users aren't always using 3D view? + toolsettings = context.tool_settings + scene = context.scene + obj = context.active_object + + object_mode = 'OBJECT' if obj is None else obj.mode + + # Pivot & Orientation + pivot_point = context.tool_settings.transform_pivot_point + act_pivot_point = bpy.types.ToolSettings.bl_rna.properties['transform_pivot_point'].enum_items[pivot_point] + + row = layout.row(align=True) + row.popover( + space_type='TOPBAR', + region_type='HEADER', + panel_type="TOPBAR_PT_pivot_point", + icon=act_pivot_point.icon, + text="", + ) + + if obj: + # Proportional editing + if context.gpencil_data and context.gpencil_data.use_stroke_edit_mode: + row = layout.row(align=True) + row.prop(toolsettings, "proportional_edit", icon_only=True) + + sub = row.row(align=True) + sub.active = toolsettings.proportional_edit != 'DISABLED' + sub.prop(toolsettings, "proportional_edit_falloff", icon_only=True) + + elif object_mode in {'EDIT', 'PARTICLE_EDIT'}: + row = layout.row(align=True) + row.prop(toolsettings, "proportional_edit", icon_only=True) + sub = row.row(align=True) + sub.active = toolsettings.proportional_edit != 'DISABLED' + sub.prop(toolsettings, "proportional_edit_falloff", icon_only=True) + + elif object_mode == 'OBJECT': + row = layout.row(align=True) + row.prop(toolsettings, "use_proportional_edit_objects", icon_only=True) + sub = row.row(align=True) + sub.active = toolsettings.use_proportional_edit_objects + sub.prop(toolsettings, "proportional_edit_falloff", icon_only=True) + else: + # Proportional editing + if context.gpencil_data and context.gpencil_data.use_stroke_edit_mode: + row = layout.row(align=True) + row.prop(toolsettings, "proportional_edit", icon_only=True) + sub = row.row(align=True) + sub.active = toolsettings.proportional_edit != 'DISABLED' + sub.prop(toolsettings, "proportional_edit_falloff", icon_only=True) + + # Snap + show_snap = False + if obj is None: + show_snap = True + else: + if object_mode not in {'SCULPT', 'VERTEX_PAINT', 'WEIGHT_PAINT', 'TEXTURE_PAINT'}: + show_snap = True + else: + + from .properties_paint_common import UnifiedPaintPanel + paint_settings = UnifiedPaintPanel.paint_settings(context) + + if paint_settings: + brush = paint_settings.brush + if brush and brush.stroke_method == 'CURVE': + show_snap = True + + if show_snap: + snap_items = bpy.types.ToolSettings.bl_rna.properties['snap_elements'].enum_items + for elem in toolsettings.snap_elements: + # TODO: Display multiple icons. + # (Currently only one of the enabled modes icons is displayed) + icon = snap_items[elem].icon + break + else: + icon = 'NONE' + + row = layout.row(align=True) + row.prop(toolsettings, "use_snap", text="") + + sub = row.row(align=True) + sub.popover( + space_type='TOPBAR', + region_type='HEADER', + panel_type="TOPBAR_PT_snapping", + icon=icon, + text="" + ) + + layout.prop(scene, "transform_orientation", text="") + + # Command Settings (redo) + op = context.active_operator + row = layout.row() + row.enabled = op is not None + row.popover( + space_type='TOPBAR', + region_type='HEADER', + panel_type="TOPBAR_PT_redo", + text=op.name + " Settings" if op else "Command Settings", + ) + + +class _draw_left_context_mode: + @staticmethod + def SCULPT(context, layout): + brush = context.tool_settings.sculpt.brush + if brush is None: + return + + from .properties_paint_common import UnifiedPaintPanel + + UnifiedPaintPanel.prop_unified_size(layout, context, brush, "size", slider=True, text="Radius") + UnifiedPaintPanel.prop_unified_strength(layout, context, brush, "strength", slider=True, text="Strength") + layout.prop(brush, "direction", text="", expand=True) + + def PAINT_TEXTURE(context, layout): + brush = context.tool_settings.vertex_paint.brush + if brush is None: + return + + from .properties_paint_common import UnifiedPaintPanel + + layout.prop(brush, "color", text="") + UnifiedPaintPanel.prop_unified_size(layout, context, brush, "size", slider=True, text="Radius") + UnifiedPaintPanel.prop_unified_strength(layout, context, brush, "strength", slider=True, text="Strength") + + def PAINT_VERTEX(context, layout): + brush = context.tool_settings.vertex_paint.brush + if brush is None: + return + + from .properties_paint_common import UnifiedPaintPanel + + layout.prop(brush, "color", text="") + UnifiedPaintPanel.prop_unified_size(layout, context, brush, "size", slider=True, text="Radius") + UnifiedPaintPanel.prop_unified_strength(layout, context, brush, "strength", slider=True, text="Strength") + + def PAINT_WEIGHT(context, layout): + brush = context.tool_settings.weight_paint.brush + if brush is None: + return + + from .properties_paint_common import UnifiedPaintPanel + + UnifiedPaintPanel.prop_unified_weight(layout, context, brush, "weight", slider=True, text="Weight") + UnifiedPaintPanel.prop_unified_size(layout, context, brush, "size", slider=True, text="Radius") + UnifiedPaintPanel.prop_unified_strength(layout, context, brush, "strength", slider=True, text="Strength") + + +class TOPBAR_PT_pivot_point(Panel): + bl_space_type = 'TOPBAR' + bl_region_type = 'HEADER' + bl_label = "Pivot Point" + + def draw(self, context): + toolsettings = context.tool_settings + obj = context.active_object + mode = context.mode + + layout = self.layout + col = layout.column() + col.label("Pivot Point") + col.prop(toolsettings, "transform_pivot_point", expand=True) + + col.separator() + + if (obj is None) or (mode in {'OBJECT', 'POSE', 'WEIGHT_PAINT'}): + col.prop( + toolsettings, + "use_transform_pivot_point_align", + text="Center Points Only", + ) + + +class TOPBAR_PT_snapping(Panel): + bl_space_type = 'TOPBAR' + bl_region_type = 'HEADER' + bl_label = "Snapping" + + def draw(self, context): + toolsettings = context.tool_settings + snap_elements = toolsettings.snap_elements + obj = context.active_object + mode = context.mode + object_mode = 'OBJECT' if obj is None else obj.mode + + layout = self.layout + col = layout.column() + col.label("Snapping") + col.prop(toolsettings, "snap_elements", expand=True) + + col.separator() + if 'INCREMENT' in snap_elements: + col.prop(toolsettings, "use_snap_grid_absolute") + + if snap_elements != {'INCREMENT'}: + col.label("Target") + row = col.row(align=True) + row.prop(toolsettings, "snap_target", expand=True) + + if obj: + if object_mode == 'EDIT': + col.prop(toolsettings, "use_snap_self") + if object_mode in {'OBJECT', 'POSE', 'EDIT'}: + col.prop(toolsettings, "use_snap_align_rotation", text="Align Rotation") + + if 'FACE' in snap_elements: + col.prop(toolsettings, "use_snap_project", text="Project Elements") + + if 'VOLUME' in snap_elements: + col.prop(toolsettings, "use_snap_peel_object") + + # Auto-Merge Editing + if obj: + if (object_mode == 'EDIT' and obj.type == 'MESH'): + col.prop(toolsettings, "use_mesh_automerge", icon='AUTOMERGE_ON') + + +class INFO_MT_editor_menus(Menu): + bl_idname = "INFO_MT_editor_menus" + bl_label = "" + + def draw(self, context): + self.draw_menus(self.layout, context) + + @staticmethod + def draw_menus(layout, context): + layout.menu("INFO_MT_file") + layout.menu("INFO_MT_edit") + + layout.menu("INFO_MT_render") + + layout.menu("INFO_MT_window") + layout.menu("INFO_MT_help") + + +class INFO_MT_file(Menu): + bl_label = "File" + + def draw(self, context): + layout = self.layout + + layout.operator_context = 'INVOKE_AREA' + layout.operator("wm.read_homefile", text="New", icon='NEW') + layout.operator("wm.open_mainfile", text="Open...", icon='FILE_FOLDER') + layout.menu("INFO_MT_file_open_recent", icon='OPEN_RECENT') + layout.operator("wm.revert_mainfile", icon='FILE_REFRESH') + layout.operator("wm.recover_last_session", icon='RECOVER_LAST') + layout.operator("wm.recover_auto_save", text="Recover Auto Save...", icon='RECOVER_AUTO') + + layout.separator() + + layout.operator_context = 'EXEC_AREA' if context.blend_data.is_saved else 'INVOKE_AREA' + layout.operator("wm.save_mainfile", text="Save", icon='FILE_TICK') + + layout.operator_context = 'INVOKE_AREA' + layout.operator("wm.save_as_mainfile", text="Save As...", icon='SAVE_AS') + layout.operator_context = 'INVOKE_AREA' + layout.operator("wm.save_as_mainfile", text="Save Copy...", icon='SAVE_COPY').copy = True + + layout.separator() + + layout.operator_context = 'INVOKE_AREA' + layout.operator("wm.save_homefile", icon='SAVE_PREFS') + layout.operator("wm.read_factory_settings", icon='LOAD_FACTORY') + + layout.separator() + + layout.operator_context = 'INVOKE_AREA' + layout.operator("wm.link", text="Link", icon='LINK_BLEND') + layout.operator("wm.append", text="Append", icon='APPEND_BLEND') + layout.menu("INFO_MT_file_previews") + + layout.separator() + + layout.menu("INFO_MT_file_import", icon='IMPORT') + layout.menu("INFO_MT_file_export", icon='EXPORT') + + layout.separator() + + layout.menu("INFO_MT_file_external_data", icon='EXTERNAL_DATA') + + layout.separator() + + layout.operator_context = 'EXEC_AREA' + if bpy.data.is_dirty and context.user_preferences.view.use_quit_dialog: + layout.operator_context = 'INVOKE_SCREEN' # quit dialog + layout.operator("wm.quit_blender", text="Quit", icon='QUIT') + + +class INFO_MT_file_import(Menu): + bl_idname = "INFO_MT_file_import" + bl_label = "Import" + + def draw(self, context): + if bpy.app.build_options.collada: + self.layout.operator("wm.collada_import", text="Collada (Default) (.dae)") + if bpy.app.build_options.alembic: + self.layout.operator("wm.alembic_import", text="Alembic (.abc)") + + +class INFO_MT_file_export(Menu): + bl_idname = "INFO_MT_file_export" + bl_label = "Export" + + def draw(self, context): + if bpy.app.build_options.collada: + self.layout.operator("wm.collada_export", text="Collada (Default) (.dae)") + if bpy.app.build_options.alembic: + self.layout.operator("wm.alembic_export", text="Alembic (.abc)") + + +class INFO_MT_file_external_data(Menu): + bl_label = "External Data" + + def draw(self, context): + layout = self.layout + + icon = 'CHECKBOX_HLT' if bpy.data.use_autopack else 'CHECKBOX_DEHLT' + layout.operator("file.autopack_toggle", icon=icon) + + layout.separator() + + pack_all = layout.row() + pack_all.operator("file.pack_all") + pack_all.active = not bpy.data.use_autopack + + unpack_all = layout.row() + unpack_all.operator("file.unpack_all") + unpack_all.active = not bpy.data.use_autopack + + layout.separator() + + layout.operator("file.make_paths_relative") + layout.operator("file.make_paths_absolute") + layout.operator("file.report_missing_files") + layout.operator("file.find_missing_files") + + +class INFO_MT_file_previews(Menu): + bl_label = "Data Previews" + + def draw(self, context): + layout = self.layout + + layout.operator("wm.previews_ensure") + layout.operator("wm.previews_batch_generate") + + layout.separator() + + layout.operator("wm.previews_clear") + layout.operator("wm.previews_batch_clear") + + +class INFO_MT_game(Menu): + bl_label = "Game" + + def draw(self, context): + layout = self.layout + + gs = context.scene.game_settings + + layout.operator("view3d.game_start") + + layout.separator() + + layout.prop(gs, "show_debug_properties") + layout.prop(gs, "show_framerate_profile") + layout.prop(gs, "show_physics_visualization") + layout.prop(gs, "use_deprecation_warnings") + layout.prop(gs, "use_animation_record") + layout.separator() + layout.prop(gs, "use_auto_start") + + +class INFO_MT_render(Menu): + bl_label = "Render" + + def draw(self, context): + layout = self.layout + + rd = context.scene.render + + layout.operator("render.render", text="Render Image", icon='RENDER_STILL').use_viewport = True + props = layout.operator("render.render", text="Render Animation", icon='RENDER_ANIMATION') + props.animation = True + props.use_viewport = True + layout.operator("sound.mixdown", text="Render Audio", icon='PLAY_AUDIO') + + layout.separator() + + layout.prop_menu_enum(rd, "display_mode", text="Display Mode", icon='IMAGE_COL') + layout.prop(rd, "use_lock_interface", text="Lock Interface") + + layout.separator() + + props = layout.operator("render.opengl", text="OpenGL Render Image", icon='RENDER_STILL') + props.view_context = False + props = layout.operator("render.opengl", text="OpenGL Render Animation", icon='RENDER_ANIMATION') + props.view_context = False + props.animation = True + layout.menu("INFO_MT_opengl_render", icon='SETTINGS') + + layout.separator() + + layout.operator("render.view_show") + layout.operator("render.play_rendered_anim", icon='PLAY') + + +class INFO_MT_opengl_render(Menu): + bl_label = "OpenGL Render Options" + + def draw(self, context): + layout = self.layout + + rd = context.scene.render + layout.prop(rd, "use_antialiasing") + layout.prop(rd, "use_full_sample") + + layout.prop_menu_enum(rd, "antialiasing_samples") + layout.prop_menu_enum(rd, "alpha_mode") + + +class INFO_MT_edit(Menu): + bl_label = "Edit" + + def draw(self, context): + layout = self.layout + + layout.operator("ed.undo") + layout.operator("ed.redo") + + layout.separator() + + layout.operator("ed.undo_history") + + layout.separator() + + layout.operator("screen.userpref_show", text="User Preferences...", icon='PREFERENCES') + + +class INFO_MT_window(Menu): + bl_label = "Window" + + def draw(self, context): + import sys + + layout = self.layout + + layout.operator("wm.window_new") + layout.operator("wm.window_fullscreen_toggle", icon='FULLSCREEN_ENTER') + + layout.separator() + + layout.operator("screen.screenshot") + layout.operator("screen.screencast") + + if sys.platform[:3] == "win": + 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" + + def draw(self, context): + layout = self.layout + + layout.operator( + "wm.url_open", text="Manual", icon='HELP', + ).url = "https://docs.blender.org/manual/en/dev/" + layout.operator( + "wm.url_open", text="Release Log", icon='URL', + ).url = "http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/%d.%d" % bpy.app.version[:2] + layout.separator() + + layout.operator( + "wm.url_open", text="Blender Website", icon='URL', + ).url = "https://www.blender.org" + layout.operator( + "wm.url_open", text="Blender Store", icon='URL', + ).url = "https://store.blender.org" + layout.operator( + "wm.url_open", text="Developer Community", icon='URL', + ).url = "https://www.blender.org/get-involved/" + layout.operator( + "wm.url_open", text="User Community", icon='URL', + ).url = "https://www.blender.org/support/user-community" + layout.separator() + layout.operator( + "wm.url_open", text="Report a Bug", icon='URL', + ).url = "https://developer.blender.org/maniphest/task/edit/form/1" + layout.separator() + + layout.operator( + "wm.url_open", text="Python API Reference", icon='URL', + ).url = bpy.types.WM_OT_doc_view._prefix + + layout.operator("wm.operator_cheat_sheet", icon='TEXT') + layout.operator("wm.sysinfo", icon='TEXT') + layout.separator() + + layout.operator("wm.splash", icon='BLENDER') + + +classes = ( + TOPBAR_HT_upper_bar, + TOPBAR_HT_lower_bar, + TOPBAR_PT_pivot_point, + TOPBAR_PT_snapping, + INFO_MT_editor_menus, + INFO_MT_file, + INFO_MT_file_import, + INFO_MT_file_export, + INFO_MT_file_external_data, + INFO_MT_file_previews, + INFO_MT_edit, + INFO_MT_game, + INFO_MT_render, + INFO_MT_opengl_render, + INFO_MT_window, + INFO_MT_help, +) + +if __name__ == "__main__": # only for live edit. + from bpy.utils import register_class + for cls in classes: + register_class(cls) diff --git a/release/scripts/startup/bl_ui/space_userpref.py b/release/scripts/startup/bl_ui/space_userpref.py index 7e7e6ccca2d..1e090884fd1 100644 --- a/release/scripts/startup/bl_ui/space_userpref.py +++ b/release/scripts/startup/bl_ui/space_userpref.py @@ -52,7 +52,8 @@ class USERPREF_HT_header(Header): def draw(self, context): layout = self.layout - layout.template_header() + # No need to show type selector. + # layout.template_header() userpref = context.user_preferences @@ -61,7 +62,9 @@ class USERPREF_HT_header(Header): layout.operator_context = 'INVOKE_DEFAULT' - if userpref.active_section == 'INPUT': + if userpref.active_section == 'INTERFACE': + layout.operator("wm.save_workspace_file") + elif userpref.active_section == 'INPUT': layout.operator("wm.keyconfig_import") layout.operator("wm.keyconfig_export") elif userpref.active_section == 'ADDONS': @@ -228,7 +231,6 @@ class USERPREF_PT_interface(Panel): col.prop(view, "show_large_cursors") col.prop(view, "show_view_name", text="View Name") col.prop(view, "show_playback_fps", text="Playback FPS") - col.prop(view, "use_global_scene") col.prop(view, "object_origin_size") col.separator() @@ -256,7 +258,6 @@ class USERPREF_PT_interface(Panel): col.prop(view, "use_mouse_depth_navigate") col.prop(view, "use_zoom_to_mouse") col.prop(view, "use_rotate_around_active") - col.prop(view, "use_global_pivot") col.prop(view, "use_camera_lock_parent") col.separator() @@ -288,11 +289,13 @@ class USERPREF_PT_interface(Panel): #col.prop(view, "open_left_mouse_delay", text="Hold LMB") #col.prop(view, "open_right_mouse_delay", text="Hold RMB") col.prop(view, "show_manipulator") + ## Currently not working + # col.prop(view, "show_manipulator_shaded") sub = col.column() sub.active = view.show_manipulator sub.prop(view, "manipulator_size", text="Size") - sub.prop(view, "manipulator_handle_size", text="Handle Size") - sub.prop(view, "manipulator_hotspot", text="Hotspot") + + col.prop(view, "show_manipulator_navigate") col.separator() col.separator() @@ -478,7 +481,6 @@ class USERPREF_PT_system(Panel): col = colsplit.column() col.label(text="General:") - col.prop(system, "frame_server_port") col.prop(system, "scrollback", text="Console Scrollback") col.separator() @@ -518,7 +520,6 @@ class USERPREF_PT_system(Panel): col = colsplit.column() col.label(text="OpenGL:") col.prop(system, "gl_clip_alpha", slider=True) - col.prop(system, "use_mipmaps") col.prop(system, "use_gpu_mipmap") col.prop(system, "use_16bit_textures") @@ -534,8 +535,6 @@ class USERPREF_PT_system(Panel): col.separator() - col.label(text="Window Draw Method:") - col.prop(system, "window_draw_method", text="") col.prop(system, "multi_sample", text="") if sys.platform == "linux" and system.multi_sample != 'NONE': col.label(text="Might fail for Mesh editing selection!") @@ -725,6 +724,7 @@ class USERPREF_PT_theme(Panel): colsub.row().prop(widget_style, "item", slider=True) colsub.row().prop(widget_style, "inner", slider=True) colsub.row().prop(widget_style, "inner_sel", slider=True) + colsub.row().prop(widget_style, "roundness") subsplit = row.split(percentage=0.85) @@ -804,6 +804,9 @@ class USERPREF_PT_theme(Panel): col.label(text="Tool:") self._theme_widget_style(col, ui.wcol_tool) + col.label(text="Toolbar Item:") + self._theme_widget_style(col, ui.wcol_toolbar_item) + col.label(text="Radio Buttons:") self._theme_widget_style(col, ui.wcol_radio) @@ -852,6 +855,9 @@ class USERPREF_PT_theme(Panel): col.label(text="List Item:") self._theme_widget_style(col, ui.wcol_list_item) + col.label(text="Tab:") + self._theme_widget_style(col, ui.wcol_tab) + ui_state = theme.user_interface.wcol_state col.label(text="State:") @@ -866,6 +872,7 @@ class USERPREF_PT_theme(Panel): colsub.row().prop(ui_state, "inner_anim_sel") colsub.row().prop(ui_state, "inner_driven") colsub.row().prop(ui_state, "inner_driven_sel") + colsub.row().prop(ui_state, "blend") subsplit = row.split(percentage=0.85) @@ -874,7 +881,8 @@ class USERPREF_PT_theme(Panel): colsub = padding.column() colsub.row().prop(ui_state, "inner_key") colsub.row().prop(ui_state, "inner_key_sel") - colsub.row().prop(ui_state, "blend") + colsub.row().prop(ui_state, "inner_overridden") + colsub.row().prop(ui_state, "inner_overridden_sel") col.separator() col.separator() @@ -889,34 +897,22 @@ class USERPREF_PT_theme(Panel): colsub = padding.column() colsub = padding.column() colsub.row().prop(ui, "menu_shadow_fac") - - subsplit = row.split(percentage=0.85) - - padding = subsplit.split(percentage=0.15) - colsub = padding.column() - colsub = padding.column() - colsub.row().prop(ui, "menu_shadow_width") - - row = col.row() - - subsplit = row.split(percentage=0.95) - - padding = subsplit.split(percentage=0.15) - colsub = padding.column() - colsub = padding.column() colsub.row().prop(ui, "icon_alpha") + colsub.row().prop(ui, "icon_saturation") + colsub.row().prop(ui, "editor_outline") subsplit = row.split(percentage=0.85) padding = subsplit.split(percentage=0.15) colsub = padding.column() colsub = padding.column() + colsub.row().prop(ui, "menu_shadow_width") colsub.row().prop(ui, "widget_emboss") col.separator() col.separator() - col.label("Axis Colors:") + col.label("Axis & Manipulator Colors:") row = col.row() @@ -934,9 +930,13 @@ class USERPREF_PT_theme(Panel): padding = subsplit.split(percentage=0.15) colsub = padding.column() colsub = padding.column() + colsub.row().prop(ui, "manipulator_primary") + colsub.row().prop(ui, "manipulator_secondary") + colsub.row().prop(ui, "manipulator_a") + colsub.row().prop(ui, "manipulator_b") - layout.separator() - layout.separator() + col.separator() + col.separator() elif theme.theme_area == 'BONE_COLOR_SETS': col = split.column() diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index 6334a2ee87e..4f3396c9ed8 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -34,98 +34,59 @@ class VIEW3D_HT_header(Header): layout = self.layout view = context.space_data + shading = view.shading # mode_string = context.mode obj = context.active_object + overlay = view.overlay toolsettings = context.tool_settings row = layout.row(align=True) row.template_header() - VIEW3D_MT_editor_menus.draw_collapsible(context, layout) + mode = 'OBJECT' if obj is None else obj.mode + + # Testing move mode to topbar. + ''' + act_mode_item = bpy.types.Object.bl_rna.properties['mode'].enum_items[mode] + layout.operator_menu_enum("object.mode_set", "mode", text=act_mode_item.name, icon=act_mode_item.icon) + del act_mode_item + + layout.template_header_3D_mode() + ''' # Contains buttons like Mode, Pivot, Manipulator, Layer, Mesh Select Mode... - row = layout - layout.template_header_3D() + shading_type = view.shading.type + shading_item = bpy.types.View3DShading.bl_rna.properties['type'].enum_items[shading_type] + + row = layout.row(align=True) + row.prop(shading, "type", text="", expand=True) + + sub = row.row(align=True) + sub.enabled = shading.type != 'RENDERED' + sub.popover(space_type='VIEW_3D', region_type='HEADER', panel_type="VIEW3D_PT_shading") + + row = layout.row(align=True) + row.prop(overlay, "show_overlays", icon="WIRE", text="") + + sub = row.row(align=True) + sub.active = overlay.show_overlays + sub.popover(space_type='VIEW_3D', region_type='HEADER', panel_type="VIEW3D_PT_overlay") if obj: - mode = obj.mode + # Set above: + # mode = obj.mode + # Particle edit if mode == 'PARTICLE_EDIT': + row = layout.row() row.prop(toolsettings.particle_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 + if ((shading.type not in {'BOUNDBOX', 'WIREFRAME'} and (mode == 'PARTICLE_EDIT' or (mode == 'EDIT' and obj.type == 'MESH'))) or (mode in {'WEIGHT_PAINT', 'VERTEX_PAINT'})): + row = layout.row() row.prop(view, "use_occlude_geometry", text="") - # Proportional editing - if context.gpencil_data and context.gpencil_data.use_stroke_edit_mode: - row = layout.row(align=True) - row.prop(toolsettings, "proportional_edit", icon_only=True) - if toolsettings.proportional_edit != 'DISABLED': - row.prop(toolsettings, "proportional_edit_falloff", icon_only=True) - elif mode in {'EDIT', 'PARTICLE_EDIT'}: - row = layout.row(align=True) - row.prop(toolsettings, "proportional_edit", icon_only=True) - if toolsettings.proportional_edit != 'DISABLED': - row.prop(toolsettings, "proportional_edit_falloff", icon_only=True) - elif mode == 'OBJECT': - row = layout.row(align=True) - row.prop(toolsettings, "use_proportional_edit_objects", icon_only=True) - if toolsettings.use_proportional_edit_objects: - row.prop(toolsettings, "proportional_edit_falloff", icon_only=True) - else: - # Proportional editing - if context.gpencil_data and context.gpencil_data.use_stroke_edit_mode: - row = layout.row(align=True) - row.prop(toolsettings, "proportional_edit", icon_only=True) - if toolsettings.proportional_edit != 'DISABLED': - row.prop(toolsettings, "proportional_edit_falloff", icon_only=True) - - # Snap - show_snap = False - if obj is None: - show_snap = True - else: - if mode not in {'SCULPT', 'VERTEX_PAINT', 'WEIGHT_PAINT', 'TEXTURE_PAINT'}: - show_snap = True - else: - paint_settings = UnifiedPaintPanel.paint_settings(context) - if paint_settings: - brush = paint_settings.brush - if brush and brush.stroke_method == 'CURVE': - show_snap = True - - if show_snap: - snap_element = toolsettings.snap_element - row = layout.row(align=True) - row.prop(toolsettings, "use_snap", text="") - row.prop(toolsettings, "snap_element", icon_only=True) - if snap_element == 'INCREMENT': - row.prop(toolsettings, "use_snap_grid_absolute", text="") - else: - row.prop(toolsettings, "snap_target", text="") - if obj: - if mode == 'EDIT': - row.prop(toolsettings, "use_snap_self", text="") - if mode in {'OBJECT', 'POSE', 'EDIT'} and snap_element != 'VOLUME': - row.prop(toolsettings, "use_snap_align_rotation", text="") - - if snap_element == 'VOLUME': - row.prop(toolsettings, "use_snap_peel_object", text="") - elif snap_element == 'FACE': - row.prop(toolsettings, "use_snap_project", text="") - - # AutoMerge editing - if obj: - if (mode == 'EDIT' and obj.type == 'MESH'): - layout.prop(toolsettings, "use_mesh_automerge", text="", icon='AUTOMERGE_ON') - - # OpenGL render - row = layout.row(align=True) - row.operator("render.opengl", text="", icon='RENDER_STILL') - row.operator("render.opengl", text="", icon='RENDER_ANIMATION').animation = True - # Pose if obj and mode == 'POSE': row = layout.row(align=True) @@ -146,6 +107,8 @@ class VIEW3D_HT_header(Header): row.prop(context.tool_settings.gpencil_sculpt, "use_select_mask") row.prop(context.tool_settings.gpencil_sculpt, "selection_alpha", slider=True) + VIEW3D_MT_editor_menus.draw_collapsible(context, layout) + class VIEW3D_MT_editor_menus(Menu): bl_space_type = 'VIEW3D_MT_editor_menus' @@ -194,6 +157,12 @@ class VIEW3D_MT_editor_menus(Menu): layout.menu("VIEW3D_MT_edit_gpencil") elif edit_object: layout.menu("VIEW3D_MT_edit_%s" % edit_object.type.lower()) + + if mode_string == 'EDIT_MESH': + layout.menu("VIEW3D_MT_edit_mesh_vertices") + layout.menu("VIEW3D_MT_edit_mesh_edges") + layout.menu("VIEW3D_MT_edit_mesh_faces") + elif obj: if mode_string != 'PAINT_TEXTURE': layout.menu("VIEW3D_MT_%s" % mode_string.lower()) @@ -232,15 +201,6 @@ class VIEW3D_MT_transform_base(Menu): def draw(self, context): layout = self.layout - layout.operator("transform.translate", text="Grab/Move") - # TODO: sub-menu for grab per axis - layout.operator("transform.rotate", text="Rotate") - # TODO: sub-menu for rot per axis - layout.operator("transform.resize", text="Scale") - # TODO: sub-menu for scale per axis - - layout.separator() - layout.operator("transform.tosphere", text="To Sphere") layout.operator("transform.shear", text="Shear") layout.operator("transform.bend", text="Bend") @@ -301,6 +261,12 @@ class VIEW3D_MT_transform_object(VIEW3D_MT_transform_base): layout.operator("object.randomize_transform") layout.operator("object.align") + # TODO: there is a strange context bug here. + """ + layout.operator_context = 'INVOKE_REGION_WIN' + layout.operator("object.transform_axis_target") + """ + # Armature EditMode extensions to Transform menu class VIEW3D_MT_transform_armature(VIEW3D_MT_transform_base): @@ -416,6 +382,11 @@ class VIEW3D_MT_uv_map(Menu): layout.operator("uv.reset") + layout.separator() + + layout.operator("mesh.uvs_rotate") + layout.operator("mesh.uvs_reverse") + class VIEW3D_MT_edit_proportional(Menu): bl_label = "Proportional Editing" @@ -441,18 +412,17 @@ class VIEW3D_MT_view(Menu): layout = self.layout view = context.space_data - layout.operator("view3d.properties", icon='MENU_PANEL') - layout.operator("view3d.toolshelf", icon='MENU_PANEL') + layout.operator("view3d.toolshelf", icon='MENU_PANEL', text="Show Toolbar") + layout.operator("view3d.properties", icon='MENU_PANEL', text="Show Sidebar") layout.separator() - layout.operator("view3d.view_selected").use_all_regions = False + layout.operator("view3d.view_selected", text="Frame Selected").use_all_regions = False if view.region_quadviews: - layout.operator("view3d.view_selected", text="View Selected (Quad View)").use_all_regions = True + layout.operator("view3d.view_selected", text="Frame Selected (Quad View)").use_all_regions = True - layout.operator("view3d.view_all").center = False - layout.operator("view3d.localview", text="View Global/Local") - layout.operator("view3d.view_persportho") + layout.operator("view3d.view_all", text="Frame All").center = False + layout.operator("view3d.view_persportho", text="Perspective/Orthographic") layout.separator() @@ -470,18 +440,16 @@ class VIEW3D_MT_view(Menu): layout.separator() - layout.operator("view3d.layers", text="Show All Layers").nr = 0 + layout.operator("screen.animation_play", text="Play Animation") layout.separator() - layout.operator("screen.animation_play", text="Playback Animation") + layout.operator("render.opengl", icon='RENDER_STILL') + layout.operator("render.opengl", text="OpenGL Render Animation", icon='RENDER_ANIMATION').animation = True layout.separator() - layout.operator("screen.area_dupli") - layout.operator("screen.region_quadview") - layout.operator("screen.screen_full_area") - layout.operator("screen.screen_full_area", text="Toggle Fullscreen Area").use_hide_panels = True + layout.menu("INFO_MT_area") class VIEW3D_MT_view_cameras(Menu): @@ -662,16 +630,12 @@ class VIEW3D_MT_select_object(Menu): layout.separator() - layout.operator("object.select_all").action = 'TOGGLE' - layout.operator("object.select_all", text="Inverse").action = 'INVERT' - - layout.separator() - - layout.operator("object.select_random", text="Random") - layout.operator("object.select_mirror", text="Mirror") - layout.operator("object.select_by_layer", text="Select All by Layer") + layout.operator("object.select_all", text="Select/Deselect All").action = 'TOGGLE' layout.operator_menu_enum("object.select_by_type", "type", text="Select All by Type...") - layout.operator("object.select_camera", text="Select Camera") + layout.operator("object.select_camera", text="Select Active Camera") + layout.operator("object.select_all", text="Inverse Selection").action = 'INVERT' + layout.operator("object.select_mirror", text="Mirror Selection") + layout.operator("object.select_random", text="Select Random") layout.separator() @@ -679,8 +643,8 @@ class VIEW3D_MT_select_object(Menu): layout.separator() - layout.operator_menu_enum("object.select_grouped", "type", text="Grouped") - layout.operator_menu_enum("object.select_linked", "type", text="Linked") + layout.operator_menu_enum("object.select_grouped", "type", text="Select Grouped") + layout.operator_menu_enum("object.select_linked", "type", text="Select Linked") layout.operator("object.select_pattern", text="Select Pattern...") @@ -853,19 +817,19 @@ class VIEW3D_MT_select_edit_mesh(Menu): layout.separator() # primitive - layout.operator("mesh.select_all").action = 'TOGGLE' - layout.operator("mesh.select_all", text="Inverse").action = 'INVERT' + layout.operator("mesh.select_all", text="Select/Deselect All").action = 'TOGGLE' + layout.operator("mesh.select_all", text="Inverse Selection").action = 'INVERT' layout.separator() # numeric - layout.operator("mesh.select_random", text="Random") + layout.operator("mesh.select_random", text="Select Random") layout.operator("mesh.select_nth") layout.separator() # geometric - layout.operator("mesh.edges_select_sharp", text="Sharp Edges") + layout.operator("mesh.edges_select_sharp", text="Select Sharp Edges") layout.separator() @@ -891,7 +855,7 @@ class VIEW3D_MT_select_edit_mesh(Menu): layout.separator() layout.operator("mesh.select_axis", text="Side of Active") - layout.operator("mesh.select_mirror", text="Mirror") + layout.operator("mesh.select_mirror", text="Mirror Selection") class VIEW3D_MT_select_edit_curve(Menu): @@ -967,10 +931,6 @@ class VIEW3D_MT_select_edit_text(Menu): def draw(self, context): layout = self.layout - layout.menu("VIEW3D_MT_undo_redo") - - layout.separator() - layout.operator("font.text_paste", text="Paste") layout.operator("font.text_cut", text="Cut") layout.operator("font.text_copy", text="Copy") @@ -1183,13 +1143,23 @@ class INFO_MT_mesh_add(Menu): bl_label = "Mesh" def draw(self, context): - from .space_view3d_toolbar import VIEW3D_PT_tools_add_object - layout = self.layout layout.operator_context = 'INVOKE_REGION_WIN' - VIEW3D_PT_tools_add_object.draw_add_mesh(layout) + layout.operator("mesh.primitive_plane_add", text="Plane", icon='MESH_PLANE') + layout.operator("mesh.primitive_cube_add", text="Cube", icon='MESH_CUBE') + layout.operator("mesh.primitive_circle_add", text="Circle", icon='MESH_CIRCLE') + layout.operator("mesh.primitive_uv_sphere_add", text="UV Sphere", icon='MESH_UVSPHERE') + layout.operator("mesh.primitive_ico_sphere_add", text="Ico Sphere", icon='MESH_ICOSPHERE') + layout.operator("mesh.primitive_cylinder_add", text="Cylinder", icon='MESH_CYLINDER') + layout.operator("mesh.primitive_cone_add", text="Cone", icon='MESH_CONE') + layout.operator("mesh.primitive_torus_add", text="Torus", icon='MESH_TORUS') + + layout.separator() + + layout.operator("mesh.primitive_grid_add", text="Grid", icon='MESH_GRID') + layout.operator("mesh.primitive_monkey_add", text="Monkey", icon='MESH_MONKEY') class INFO_MT_curve_add(Menu): @@ -1197,12 +1167,22 @@ class INFO_MT_curve_add(Menu): bl_label = "Curve" def draw(self, context): - from .space_view3d_toolbar import VIEW3D_PT_tools_add_object layout = self.layout layout.operator_context = 'INVOKE_REGION_WIN' - VIEW3D_PT_tools_add_object.draw_add_curve(layout) + layout.operator("curve.primitive_bezier_curve_add", text="Bezier", icon='CURVE_BEZCURVE') + layout.operator("curve.primitive_bezier_circle_add", text="Circle", icon='CURVE_BEZCIRCLE') + + layout.separator() + + layout.operator("curve.primitive_nurbs_curve_add", text="Nurbs Curve", icon='CURVE_NCURVE') + layout.operator("curve.primitive_nurbs_circle_add", text="Nurbs Circle", icon='CURVE_NCIRCLE') + layout.operator("curve.primitive_nurbs_path_add", text="Path", icon='CURVE_PATH') + + layout.separator() + + layout.operator("curve.draw", icon='LINE_DATA') class INFO_MT_surface_add(Menu): @@ -1210,12 +1190,17 @@ class INFO_MT_surface_add(Menu): bl_label = "Surface" def draw(self, context): - from .space_view3d_toolbar import VIEW3D_PT_tools_add_object layout = self.layout layout.operator_context = 'INVOKE_REGION_WIN' - VIEW3D_PT_tools_add_object.draw_add_surface(layout) + layout.operator("surface.primitive_nurbs_surface_curve_add", text="Nurbs Curve", icon='SURFACE_NCURVE') + layout.operator("surface.primitive_nurbs_surface_circle_add", text="Nurbs Circle", icon='SURFACE_NCIRCLE') + layout.operator("surface.primitive_nurbs_surface_surface_add", text="Nurbs Surface", icon='SURFACE_NSURFACE') + layout.operator("surface.primitive_nurbs_surface_cylinder_add", + text="Nurbs Cylinder", icon='SURFACE_NCYLINDER') + layout.operator("surface.primitive_nurbs_surface_sphere_add", text="Nurbs Sphere", icon='SURFACE_NSPHERE') + layout.operator("surface.primitive_nurbs_surface_torus_add", text="Nurbs Torus", icon='SURFACE_NTORUS') class INFO_MT_metaball_add(Menu): @@ -1278,6 +1263,17 @@ class INFO_MT_lamp_add(Menu): layout.operator_enum("object.lamp_add", "type") +class INFO_MT_lightprobe_add(Menu): + bl_idname = "INFO_MT_lightprobe_add" + bl_label = "Light Probe" + + def draw(self, context): + layout = self.layout + + layout.operator_context = 'INVOKE_REGION_WIN' + layout.operator_enum("object.lightprobe_add", "type") + + class INFO_MT_camera_add(Menu): bl_idname = "INFO_MT_camera_add" bl_label = "Camera" @@ -1326,37 +1322,32 @@ class INFO_MT_add(Menu): layout.menu("INFO_MT_lamp_add", icon='OUTLINER_OB_LAMP') layout.separator() + layout.menu("INFO_MT_lightprobe_add", icon='OUTLINER_OB_LIGHTPROBE') + layout.separator() layout.operator_menu_enum("object.effector_add", "type", text="Force Field", icon='OUTLINER_OB_FORCE_FIELD') layout.separator() - if len(bpy.data.groups) > 10: - layout.operator_context = 'INVOKE_REGION_WIN' - layout.operator("object.group_instance_add", text="Group Instance...", icon='OUTLINER_OB_GROUP_INSTANCE') + has_collections = bool(bpy.data.collections) + col = layout.column() + col.enabled = has_collections + + if not has_collections or len(bpy.data.collections) > 10: + col.operator_context = 'INVOKE_REGION_WIN' + col.operator( + "object.collection_instance_add", + text="Collection Instance..." if has_collections else "No Collections to Instance", + icon='OUTLINER_OB_GROUP_INSTANCE', + ) else: - layout.operator_menu_enum( - "object.group_instance_add", - "group", - text="Group Instance", + col.operator_menu_enum( + "object.collection_instance_add", + "collection", + text="Collection Instance", icon='OUTLINER_OB_GROUP_INSTANCE', ) -class VIEW3D_MT_undo_redo(Menu): - bl_label = "Undo/Redo" - _operator_name = "" - - def draw(self, context): - layout = self.layout - - layout.operator("ed.undo") - layout.operator("ed.redo") - - layout.separator() - - layout.operator("ed.undo_history") - - class VIEW3D_MT_object_relations(Menu): bl_label = "Relations" @@ -1384,26 +1375,11 @@ class VIEW3D_MT_object(Menu): def draw(self, context): layout = self.layout - view = context.space_data - is_local_view = (view.local_view is not None) - - layout.menu("VIEW3D_MT_undo_redo") - - layout.separator() - - layout.operator("object.delete", text="Delete...").use_global = False - - layout.separator() layout.menu("VIEW3D_MT_transform_object") layout.menu("VIEW3D_MT_mirror") layout.menu("VIEW3D_MT_object_clear") layout.menu("VIEW3D_MT_object_apply") - - layout.separator() - - layout.menu("VIEW3D_MT_object_parent") - layout.menu("VIEW3D_MT_object_group") layout.menu("VIEW3D_MT_snap") layout.separator() @@ -1411,22 +1387,30 @@ class VIEW3D_MT_object(Menu): layout.operator("object.duplicate_move") layout.operator("object.duplicate_move_linked") layout.operator("object.join") - if is_local_view: - layout.operator_context = 'EXEC_REGION_WIN' - layout.operator("object.move_to_layer", text="Move out of Local View") - layout.operator_context = 'INVOKE_REGION_WIN' - else: - layout.operator("object.move_to_layer", text="Move to Layer...") layout.separator() - layout.menu("VIEW3D_MT_make_links", text="Make Links...") + + layout.operator("view3d.copybuffer", text="Copy Objects") + layout.operator("view3d.pastebuffer", text="Paste Objects") + + layout.separator() + + layout.menu("VIEW3D_MT_object_parent") + layout.menu("VIEW3D_MT_object_collection") layout.menu("VIEW3D_MT_object_relations") layout.menu("VIEW3D_MT_object_constraints") layout.menu("VIEW3D_MT_object_track") + layout.menu("VIEW3D_MT_make_links", text="Make Links...") + + layout.separator() + + layout.operator("object.shade_smooth", text="Smooth Shading") + layout.operator("object.shade_flat", text="Flat Shading") layout.separator() layout.menu("VIEW3D_MT_object_animation") + layout.menu("VIEW3D_MT_object_rigid_body") layout.separator() @@ -1434,13 +1418,11 @@ class VIEW3D_MT_object(Menu): layout.separator() - layout.menu("VIEW3D_MT_object_game") + layout.operator_menu_enum("object.convert", "target") layout.separator() - layout.menu("VIEW3D_MT_object_showhide") - - layout.operator_menu_enum("object.convert", "target") + layout.operator("object.delete", text="Delete...").use_global = False class VIEW3D_MT_object_animation(Menu): @@ -1459,6 +1441,32 @@ class VIEW3D_MT_object_animation(Menu): layout.operator("nla.bake", text="Bake Action...") +class VIEW3D_MT_object_rigid_body(Menu): + bl_label = "Rigid Body" + + def draw(self, context): + layout = self.layout + + layout.operator("rigidbody.objects_add", text="Add Active").type = 'ACTIVE' + layout.operator("rigidbody.objects_add", text="Add Passive").type = 'PASSIVE' + + layout.separator() + + layout.operator("rigidbody.objects_remove", text="Remove") + + layout.separator() + + layout.operator("rigidbody.shape_change", text="Change Shape") + layout.operator("rigidbody.mass_calculate", text="Calculate Mass") + layout.operator("rigidbody.object_settings_copy", text="Copy from Active") + layout.operator("object.visual_transform_apply", text="Apply Transformation") + layout.operator("rigidbody.bake_to_keyframes", text="Bake To Keyframes") + + layout.separator() + + layout.operator("rigidbody.connect", text="Connect") + + class VIEW3D_MT_object_clear(Menu): bl_label = "Clear" @@ -1475,7 +1483,7 @@ class VIEW3D_MT_object_clear(Menu): class VIEW3D_MT_object_specials(Menu): - bl_label = "Specials" + bl_label = "Context Menu" @classmethod def poll(cls, context): @@ -1488,6 +1496,42 @@ class VIEW3D_MT_object_specials(Menu): scene = context.scene obj = context.object + layout.operator("view3d.copybuffer", text="Copy Objects", icon='COPYDOWN') + layout.operator("view3d.pastebuffer", text="Paste Objects", icon='PASTEDOWN') + + layout.separator() + + layout.operator("object.duplicate_move") + layout.operator("object.duplicate_move_linked") + + layout.separator() + + layout.menu("VIEW3D_MT_snap") + layout.menu("VIEW3D_MT_object_parent") + layout.operator_context = 'INVOKE_REGION_WIN' + layout.operator("object.move_to_collection") + + layout.separator() + + layout.operator("anim.keyframe_insert_menu", text="Insert Keyframe...") + + layout.separator() + + layout.operator("object.delete", text="Delete...").use_global = False + + if obj.type == 'MESH': + + layout.separator() + + layout.operator("object.shade_smooth", text="Smooth Shading") + layout.operator("object.shade_flat", text="Flat Shading") + + layout.separator() + + layout.operator("object.origin_set") + layout.operator("object.join") + layout.operator_menu_enum("object.convert", "target") + if obj.type == 'CAMERA': layout.operator_context = 'INVOKE_REGION_WIN' @@ -1549,52 +1593,39 @@ class VIEW3D_MT_object_specials(Menu): layout.operator_context = 'INVOKE_REGION_WIN' - if scene.render.use_shading_nodes: - emission_node = None - if lamp.node_tree: - for node in lamp.node_tree.nodes: - if getattr(node, "type", None) == 'EMISSION': - emission_node = node - break - - if emission_node is not None: - props = layout.operator("wm.context_modal_mouse", text="Strength") - props.data_path_iter = "selected_editable_objects" - props.data_path_item = "data.node_tree" \ - ".nodes[\"" + emission_node.name + "\"]" \ - ".inputs[\"Strength\"].default_value" - props.header_text = "Lamp Strength: %.3f" - props.input_scale = 0.1 - - if lamp.type == 'AREA': - props = layout.operator("wm.context_modal_mouse", text="Size X") - props.data_path_iter = "selected_editable_objects" - props.data_path_item = "data.size" - props.header_text = "Lamp Size X: %.3f" + emission_node = None + if lamp.node_tree: + for node in lamp.node_tree.nodes: + if getattr(node, "type", None) == 'EMISSION': + emission_node = node + break - if lamp.shape == 'RECTANGLE': - props = layout.operator("wm.context_modal_mouse", text="Size Y") - props.data_path_iter = "selected_editable_objects" - props.data_path_item = "data.size_y" - props.header_text = "Lamp Size Y: %.3f" + if emission_node is not None: + props = layout.operator("wm.context_modal_mouse", text="Strength") + props.data_path_iter = "selected_editable_objects" + props.data_path_item = "data.node_tree" \ + ".nodes[\"" + emission_node.name + "\"]" \ + ".inputs[\"Strength\"].default_value" + props.header_text = "Lamp Strength: %.3f" + props.input_scale = 0.1 - elif lamp.type in {'SPOT', 'POINT', 'SUN'}: - props = layout.operator("wm.context_modal_mouse", text="Size") - props.data_path_iter = "selected_editable_objects" - props.data_path_item = "data.shadow_soft_size" - props.header_text = "Lamp Size: %.3f" - else: - props = layout.operator("wm.context_modal_mouse", text="Energy") + if lamp.type == 'AREA': + props = layout.operator("wm.context_modal_mouse", text="Size X") props.data_path_iter = "selected_editable_objects" - props.data_path_item = "data.energy" - props.header_text = "Lamp Energy: %.3f" + props.data_path_item = "data.size" + props.header_text = "Lamp Size X: %.3f" - if lamp.type in {'SPOT', 'AREA', 'POINT'}: - props = layout.operator("wm.context_modal_mouse", text="Falloff Distance") + if lamp.shape in {'RECTANGLE', 'ELLIPSE'}: + props = layout.operator("wm.context_modal_mouse", text="Size Y") props.data_path_iter = "selected_editable_objects" - props.data_path_item = "data.distance" - props.input_scale = 0.1 - props.header_text = "Lamp Falloff Distance: %.1f" + props.data_path_item = "data.size_y" + props.header_text = "Lamp Size Y: %.3f" + + elif lamp.type in {'SPOT', 'POINT', 'SUN'}: + props = layout.operator("wm.context_modal_mouse", text="Size") + props.data_path_iter = "selected_editable_objects" + props.data_path_item = "data.shadow_soft_size" + props.header_text = "Lamp Size: %.3f" if lamp.type == 'SPOT': layout.separator() @@ -1610,23 +1641,15 @@ class VIEW3D_MT_object_specials(Menu): props.input_scale = -0.01 props.header_text = "Spot Blend: %.2f" - if not scene.render.use_shading_nodes: - props = layout.operator("wm.context_modal_mouse", text="Clip Start") - props.data_path_iter = "selected_editable_objects" - props.data_path_item = "data.shadow_buffer_clip_start" - props.input_scale = 0.05 - props.header_text = "Clip Start: %.2f" - props = layout.operator("wm.context_modal_mouse", text="Clip End") - props.data_path_iter = "selected_editable_objects" - props.data_path_item = "data.shadow_buffer_clip_end" - props.input_scale = 0.05 - props.header_text = "Clip End: %.2f" - - layout.separator() +class VIEW3D_MT_object_shading(Menu): + # XXX, this menu is a place to store shading operator in object mode + bl_label = "Shading" - props = layout.operator("object.isolate_type_render") - props = layout.operator("object.hide_render_clear_all") + def draw(self, context): + layout = self.layout + layout.operator("object.shade_smooth", text="Smooth") + layout.operator("object.shade_flat", text="Flat") class VIEW3D_MT_object_apply(Menu): @@ -1712,21 +1735,21 @@ class VIEW3D_MT_object_track(Menu): layout.operator_enum("object.track_clear", "type") -class VIEW3D_MT_object_group(Menu): - bl_label = "Group" +class VIEW3D_MT_object_collection(Menu): + bl_label = "Collection" def draw(self, context): layout = self.layout - layout.operator("group.create") - # layout.operator_menu_enum("group.objects_remove", "group") # BUGGY - layout.operator("group.objects_remove") - layout.operator("group.objects_remove_all") + layout.operator("collection.create") + # layout.operator_menu_enum("collection.objects_remove", "collection") # BUGGY + layout.operator("collection.objects_remove") + layout.operator("collection.objects_remove_all") layout.separator() - layout.operator("group.objects_add_active") - layout.operator("group.objects_remove_active") + layout.operator("collection.objects_add_active") + layout.operator("collection.objects_remove_active") class VIEW3D_MT_object_constraints(Menu): @@ -1755,20 +1778,6 @@ class VIEW3D_MT_object_quick_effects(Menu): layout.operator("object.quick_fluid") -class VIEW3D_MT_object_showhide(Menu): - bl_label = "Show/Hide" - - def draw(self, context): - layout = self.layout - - layout.operator("object.hide_view_clear", text="Show Hidden") - - layout.separator() - - layout.operator("object.hide_view_set", text="Hide Selected").unselected = False - layout.operator("object.hide_view_set", text="Hide Unselected").unselected = True - - class VIEW3D_MT_make_single_user(Menu): bl_label = "Make Single User" @@ -1777,23 +1786,23 @@ class VIEW3D_MT_make_single_user(Menu): props = layout.operator("object.make_single_user", text="Object") props.object = True - props.obdata = props.material = props.texture = props.animation = False + props.obdata = props.material = props.animation = False props = layout.operator("object.make_single_user", text="Object & Data") props.object = props.obdata = True - props.material = props.texture = props.animation = False + props.material = props.animation = False - props = layout.operator("object.make_single_user", text="Object & Data & Materials+Tex") - props.object = props.obdata = props.material = props.texture = True + props = layout.operator("object.make_single_user", text="Object & Data & Materials") + props.object = props.obdata = props.material = True props.animation = False - props = layout.operator("object.make_single_user", text="Materials+Tex") - props.material = props.texture = True + props = layout.operator("object.make_single_user", text="Materials") + props.material = True props.object = props.obdata = props.animation = False props = layout.operator("object.make_single_user", text="Object Animation") props.animation = True - props.object = props.obdata = props.material = props.texture = False + props.object = props.obdata = props.material = False class VIEW3D_MT_make_links(Menu): @@ -1819,26 +1828,6 @@ class VIEW3D_MT_make_links(Menu): layout.operator("object.join_uvs") # stupid place to add this! -class VIEW3D_MT_object_game(Menu): - bl_label = "Game" - - def draw(self, context): - layout = self.layout - - layout.operator("object.logic_bricks_copy", text="Copy Logic Bricks") - layout.operator("object.game_physics_copy", text="Copy Physics Properties") - - layout.separator() - - layout.operator("object.game_property_copy", text="Replace Properties").operation = 'REPLACE' - layout.operator("object.game_property_copy", text="Merge Properties").operation = 'MERGE' - layout.operator_menu_enum("object.game_property_copy", "property", text="Copy Properties...") - - layout.separator() - - layout.operator("object.game_property_clear") - - class VIEW3D_MT_brush(Menu): bl_label = "Brush" @@ -1915,10 +1904,6 @@ class VIEW3D_MT_paint_vertex(Menu): def draw(self, context): layout = self.layout - layout.menu("VIEW3D_MT_undo_redo") - - layout.separator() - layout.operator("paint.vertex_color_set") layout.operator("paint.vertex_color_smooth") layout.operator("paint.vertex_color_dirt") @@ -1987,17 +1972,15 @@ class VIEW3D_MT_vertex_group(Menu): class VIEW3D_MT_paint_weight(Menu): bl_label = "Weights" - def draw(self, context): - layout = self.layout - - layout.menu("VIEW3D_MT_undo_redo") + @staticmethod + def draw_generic(layout, is_editmode=False): - layout.separator() + if not is_editmode: - layout.operator("paint.weight_from_bones", text="Assign Automatic From Bones").type = 'AUTOMATIC' - layout.operator("paint.weight_from_bones", text="Assign From Bone Envelopes").type = 'ENVELOPES' + layout.operator("paint.weight_from_bones", text="Assign Automatic From Bones").type = 'AUTOMATIC' + layout.operator("paint.weight_from_bones", text="Assign From Bone Envelopes").type = 'ENVELOPES' - layout.separator() + layout.separator() layout.operator("object.vertex_group_normalize_all", text="Normalize All") layout.operator("object.vertex_group_normalize", text="Normalize") @@ -2014,16 +1997,21 @@ class VIEW3D_MT_paint_weight(Menu): layout.operator("object.vertex_group_levels", text="Levels") layout.operator("object.vertex_group_smooth", text="Smooth") - props = layout.operator("object.data_transfer", text="Transfer Weights") - props.use_reverse_transfer = True - props.data_type = 'VGROUP_WEIGHTS' + if not is_editmode: + 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") - layout.separator() + if not is_editmode: + layout.separator() + + layout.operator("paint.weight_set") - layout.operator("paint.weight_set") + def draw(self, context): + self.draw_generic(self.layout, is_editmode=False) class VIEW3D_MT_sculpt(Menu): @@ -2035,10 +2023,6 @@ class VIEW3D_MT_sculpt(Menu): toolsettings = context.tool_settings sculpt = toolsettings.sculpt - layout.menu("VIEW3D_MT_undo_redo") - - layout.separator() - layout.prop(sculpt, "use_symmetry_x") layout.prop(sculpt, "use_symmetry_y") layout.prop(sculpt, "use_symmetry_z") @@ -2106,14 +2090,6 @@ class VIEW3D_MT_particle(Menu): particle_edit = context.tool_settings.particle_edit - layout.menu("VIEW3D_MT_undo_redo") - - layout.separator() - - layout.operator("particle.delete") - - layout.separator() - layout.operator("particle.mirror") layout.operator("particle.remove_doubles") @@ -2131,9 +2107,13 @@ class VIEW3D_MT_particle(Menu): layout.menu("VIEW3D_MT_particle_showhide") + layout.separator() + + layout.operator("particle.delete") + class VIEW3D_MT_particle_specials(Menu): - bl_label = "Specials" + bl_label = "Context Menu" def draw(self, context): layout = self.layout @@ -2191,10 +2171,6 @@ class VIEW3D_MT_pose(Menu): def draw(self, context): layout = self.layout - layout.menu("VIEW3D_MT_undo_redo") - - layout.separator() - layout.menu("VIEW3D_MT_transform_armature") layout.menu("VIEW3D_MT_pose_transform") @@ -2387,30 +2363,41 @@ class VIEW3D_MT_pose_apply(Menu): class VIEW3D_MT_pose_specials(Menu): - bl_label = "Specials" + bl_label = "Context Menu" def draw(self, context): layout = self.layout - layout.operator("paint.weight_from_bones", text="Assign Automatic from Bones").type = 'AUTOMATIC' - layout.operator("paint.weight_from_bones", text="Assign from Bone Envelopes").type = 'ENVELOPES' + layout.operator("anim.keyframe_insert_menu", text="Insert Keyframe...") + + layout.separator() + + layout.operator("pose.copy") + layout.operator("pose.paste").flipped = False + layout.operator("pose.paste", text="Paste X-Flipped Pose").flipped = True layout.separator() layout.operator("pose.select_constraint_target") - layout.operator("pose.flip_names") + + layout.separator() + + layout.operator("pose.paths_calculate", text="Calculate") + layout.operator("pose.paths_clear", text="Clear") layout.separator() layout.operator("pose.paths_calculate") layout.operator("pose.paths_clear") - layout.operator("pose.user_transforms_clear") - layout.operator("pose.user_transforms_clear", text="Clear User Transforms (All)").only_selected = False - layout.operator("pose.relax") layout.separator() - layout.operator_menu_enum("pose.autoside_names", "axis") + layout.operator("pose.hide").unselected = False + layout.operator("pose.reveal") + + layout.separator() + + layout.operator("pose.user_transforms_clear") class BoneOptions: @@ -2467,16 +2454,9 @@ class VIEW3D_MT_edit_mesh(Menu): def draw(self, context): layout = self.layout + with_bullet = bpy.app.build_options.bullet toolsettings = context.tool_settings - layout.menu("VIEW3D_MT_undo_redo") - - layout.separator() - - layout.menu("VIEW3D_MT_edit_mesh_delete") - - layout.separator() - layout.menu("VIEW3D_MT_transform") layout.menu("VIEW3D_MT_mirror") layout.menu("VIEW3D_MT_snap") @@ -2487,85 +2467,124 @@ class VIEW3D_MT_edit_mesh(Menu): layout.separator() - layout.operator("mesh.duplicate_move") + layout.operator("mesh.duplicate_move", text="Duplicate") layout.menu("VIEW3D_MT_edit_mesh_extrude") + layout.operator("mesh.split") + layout.operator("mesh.bisect") - layout.separator() - - layout.menu("VIEW3D_MT_edit_mesh_vertices") - layout.menu("VIEW3D_MT_edit_mesh_edges") - layout.menu("VIEW3D_MT_edit_mesh_faces") - - layout.separator() - - layout.menu("VIEW3D_MT_edit_mesh_normals") - layout.menu("VIEW3D_MT_edit_mesh_clean") + if with_bullet: + layout.operator("mesh.convex_hull") layout.separator() layout.operator("mesh.symmetrize") layout.operator("mesh.symmetry_snap") - layout.operator("mesh.bisect") - layout.operator_menu_enum("mesh.sort_elements", "type", text="Sort Elements...") layout.separator() - layout.prop(toolsettings, "use_mesh_automerge") - layout.menu("VIEW3D_MT_edit_proportional") + layout.menu("VIEW3D_MT_edit_mesh_normals") + layout.menu("VIEW3D_MT_edit_mesh_shading") + layout.menu("VIEW3D_MT_edit_mesh_weights") + layout.operator_menu_enum("mesh.sort_elements", "type", text="Sort Elements...") layout.separator() layout.menu("VIEW3D_MT_edit_mesh_showhide") + layout.operator_menu_enum("mesh.separate", "type") + layout.menu("VIEW3D_MT_edit_mesh_clean") + layout.menu("VIEW3D_MT_edit_mesh_delete") class VIEW3D_MT_edit_mesh_specials(Menu): - bl_label = "Specials" + bl_label = "Context Menu" def draw(self, context): layout = self.layout + select_mode = context.tool_settings.mesh_select_mode + layout.operator_context = 'INVOKE_REGION_WIN' - layout.operator("mesh.subdivide", text="Subdivide").smoothness = 0.0 - layout.operator("mesh.subdivide", text="Subdivide Smooth").smoothness = 1.0 + layout.operator("mesh.subdivide", text="Subdivide") layout.separator() - layout.operator("mesh.merge", text="Merge...") - layout.operator("mesh.remove_doubles") + layout.operator("mesh.duplicate_move", text="Duplicate") - layout.separator() + # Vertex Select Commands + if select_mode[0]: + layout.separator() - layout.operator("mesh.hide", text="Hide").unselected = False - layout.operator("mesh.reveal", text="Reveal") - layout.operator("mesh.select_all", text="Select Inverse").action = 'INVERT' + layout.operator("mesh.edge_face_add", text="New Edge/Face from Vertices") + layout.operator("mesh.vert_connect_path", text="Connect Vertex Path") + layout.operator("mesh.vert_connect", text="Connect Vertex Pairs") - layout.separator() + layout.separator() - layout.operator("mesh.flip_normals") - layout.operator("mesh.vertices_smooth", text="Smooth") - layout.operator("mesh.vertices_smooth_laplacian", text="Laplacian Smooth") + layout.operator("mesh.vertices_smooth", text="Smooth") + layout.operator("mesh.vertices_smooth_laplacian", text="Smooth Laplacian") - layout.separator() + layout.separator() + layout.operator("mesh.merge", text="Merge Vertices...") + layout.operator("mesh.remove_doubles", text="Remove Double Vertices") + layout.operator("mesh.dissolve_verts") + layout.operator("mesh.delete", text="Delete Vertices").type = "VERT" - layout.operator("mesh.inset") - layout.operator("mesh.bevel", text="Bevel") - layout.operator("mesh.bridge_edge_loops") + # Edge Select Commands + if select_mode[1]: + layout.separator() - layout.separator() + layout.operator("mesh.bridge_edge_loops", text="Bridge Edge Loops") - layout.operator("mesh.faces_shade_smooth") - layout.operator("mesh.faces_shade_flat") + layout.separator() + + layout.operator("mesh.dissolve_edges") + layout.operator("mesh.delete", text="Delete Edges").type = "EDGE" + + # Face Select Commands + if select_mode[2]: + layout.separator() + + layout.operator("mesh.faces_shade_smooth") + layout.operator("mesh.faces_shade_flat") + + layout.separator() + + layout.operator("mesh.bridge_edge_loops", text="Bridge Faces") + + layout.separator() + + layout.operator("mesh.poke") + + layout.separator() + + props = layout.operator("mesh.quads_convert_to_tris") + props.quad_method = props.ngon_method = 'BEAUTY' + layout.operator("mesh.tris_convert_to_quads") + + layout.separator() + + layout.menu("VIEW3D_MT_uv_map", text="UV Unwrap Faces...") + + layout.separator() + + layout.operator("mesh.dissolve_faces") + layout.operator("mesh.delete", text="Delete Faces").type = "FACE" + + # General Mesh Commands layout.separator() - layout.operator("mesh.blend_from_shape") - layout.operator("mesh.shape_propagate_to_all") - layout.operator("mesh.shortest_path_select") - layout.operator("mesh.sort_elements") + layout.menu("VIEW3D_MT_snap", text="Snap...") + layout.operator("transform.mirror", text="Mirror") layout.operator("mesh.symmetrize") layout.operator("mesh.symmetry_snap") + layout.separator() + + layout.operator("mesh.hide", text="Hide").unselected = False + layout.operator("mesh.reveal", text="Reveal") + class VIEW3D_MT_edit_mesh_select_mode(Menu): bl_label = "Mesh Select Mode" @@ -2584,15 +2603,15 @@ class VIEW3D_MT_edit_mesh_extrude(Menu): _extrude_funcs = { 'VERT': lambda layout: - layout.operator("mesh.extrude_vertices_move", text="Vertices Only"), + layout.operator("mesh.extrude_vertices_move", text="Extrude Vertices"), 'EDGE': lambda layout: - layout.operator("mesh.extrude_edges_move", text="Edges Only"), - 'FACE': lambda layout: - layout.operator("mesh.extrude_faces_move", text="Individual Faces"), + layout.operator("mesh.extrude_edges_move", text="Extrude Edges"), 'REGION': lambda layout: - layout.operator("view3d.edit_mesh_extrude_move_normal", text="Region"), + layout.operator("view3d.edit_mesh_extrude_move_normal", text="Extrude Faces"), 'REGION_VERT_NORMAL': lambda layout: - layout.operator("view3d.edit_mesh_extrude_move_shrink_fatten", text="Region (Vertex Normals)"), + layout.operator("view3d.edit_mesh_extrude_move_shrink_fatten", text="Extrude Faces Along Normals"), + 'FACE': lambda layout: + layout.operator("mesh.extrude_faces_move", text="Extrude Individual Faces"), } @staticmethod @@ -2620,45 +2639,43 @@ class VIEW3D_MT_edit_mesh_extrude(Menu): class VIEW3D_MT_edit_mesh_vertices(Menu): - bl_label = "Vertices" + bl_label = "Vertex" def draw(self, context): layout = self.layout layout.operator_context = 'INVOKE_REGION_WIN' - with_bullet = bpy.app.build_options.bullet + layout.operator("mesh.extrude_vertices_move", text="Extrude Vertices"), + layout.operator("mesh.bevel", text="Bevel Vertices").vertex_only = True - layout.operator("mesh.merge") - layout.operator("mesh.remove_doubles") - props = layout.operator("mesh.rip_move") - props.MESH_OT_rip.use_fill = False - props = layout.operator("mesh.rip_move", text="Rip Fill") - props.MESH_OT_rip.use_fill = True - layout.operator("mesh.rip_edge_move") - layout.operator("mesh.split") - layout.operator_menu_enum("mesh.separate", "type") + layout.separator() + + layout.operator("mesh.edge_face_add", text="New Edge/Face from Vertices") layout.operator("mesh.vert_connect_path", text="Connect Vertex Path") - layout.operator("mesh.vert_connect", text="Connect Vertices") - layout.operator("transform.vert_slide", text="Slide") + layout.operator("mesh.vert_connect", text="Connect Vertex Pairs") layout.separator() - layout.operator("mesh.mark_sharp", text="Mark Sharp Edges").use_verts = True - props = layout.operator("mesh.mark_sharp", text="Clear Sharp Edges") - props.use_verts = True - props.clear = True + props = layout.operator("mesh.rip_move", text="Rip Vertices") + props.MESH_OT_rip.use_fill = False + props = layout.operator("mesh.rip_move", text="Rip Vertices and Fill") + props.MESH_OT_rip.use_fill = True + layout.operator("mesh.rip_edge_move", text="Rip Vertices and Extend") layout.separator() - layout.operator("mesh.bevel").vertex_only = True - if with_bullet: - layout.operator("mesh.convex_hull") - layout.operator("mesh.vertices_smooth") + layout.operator("transform.vert_slide", text="Slide Vertices") + layout.operator("mesh.vertices_smooth", text="Smooth Vertices") + + layout.separator() layout.operator("mesh.blend_from_shape") + layout.operator("mesh.shape_propagate_to_all", text="Propagate to Shapes") + + layout.separator() - layout.operator("object.vertex_group_smooth") - layout.operator("mesh.shape_propagate_to_all") + layout.operator("mesh.merge", text="Merge Vertices") + layout.operator("mesh.remove_doubles", text="Remove Double Vertices") layout.separator() @@ -2693,6 +2710,13 @@ class VIEW3D_MT_edit_mesh_edges_data(Menu): layout.operator("mesh.mark_sharp") layout.operator("mesh.mark_sharp", text="Clear Sharp").clear = True + layout.operator("mesh.mark_sharp", text="Mark Sharp from Vertices").use_verts = True + props = layout.operator("mesh.mark_sharp", text="Clear Sharp from Vertices") + props.use_verts = True + props.clear = True + + layout.separator() + layout.separator() if with_freestyle: @@ -2702,21 +2726,22 @@ class VIEW3D_MT_edit_mesh_edges_data(Menu): class VIEW3D_MT_edit_mesh_edges(Menu): - bl_label = "Edges" + bl_label = "Edge" def draw(self, context): layout = self.layout layout.operator_context = 'INVOKE_REGION_WIN' - layout.operator("mesh.edge_face_add") - layout.operator("mesh.subdivide") - layout.operator("mesh.subdivide_edgering") - layout.operator("mesh.unsubdivide") + layout.operator("mesh.extrude_edges_move", text="Extrude Edges"), + layout.operator("mesh.bevel", text="Bevel Edges").vertex_only = False + layout.operator("mesh.bridge_edge_loops") layout.separator() - layout.menu("VIEW3D_MT_edit_mesh_edges_data") + layout.operator("mesh.subdivide") + layout.operator("mesh.subdivide_edgering") + layout.operator("mesh.unsubdivide") layout.separator() @@ -2725,22 +2750,16 @@ class VIEW3D_MT_edit_mesh_edges(Menu): layout.separator() - layout.operator("mesh.bevel").vertex_only = False + layout.operator("transform.edge_slide") layout.operator("mesh.edge_split") - layout.operator("mesh.bridge_edge_loops") layout.separator() - layout.operator("transform.edge_slide") - layout.operator("mesh.loop_multi_select", text="Edge Loops").ring = False - layout.operator("mesh.loop_multi_select", text="Edge Rings").ring = True - layout.operator("mesh.loop_to_region") - layout.operator("mesh.region_to_loop") + layout.menu("VIEW3D_MT_edit_mesh_edges_data") -class VIEW3D_MT_edit_mesh_faces(Menu): - bl_label = "Faces" - bl_idname = "VIEW3D_MT_edit_mesh_faces" +class VIEW3D_MT_edit_mesh_faces_data(Menu): + bl_label = "Face Data" def draw(self, context): layout = self.layout @@ -2749,48 +2768,69 @@ class VIEW3D_MT_edit_mesh_faces(Menu): layout.operator_context = 'INVOKE_REGION_WIN' - layout.operator("mesh.flip_normals") - layout.operator("mesh.edge_face_add") - layout.operator("mesh.fill") - layout.operator("mesh.fill_grid") - layout.operator("mesh.beautify_fill") - layout.operator("mesh.inset") - layout.operator("mesh.bevel").vertex_only = False - layout.operator("mesh.solidify") - layout.operator("mesh.intersect") - layout.operator("mesh.intersect_boolean") - layout.operator("mesh.wireframe") + layout.operator("mesh.colors_rotate") + layout.operator("mesh.colors_reverse") + + layout.separator() + + layout.operator("mesh.uvs_rotate") + layout.operator("mesh.uvs_reverse") layout.separator() if with_freestyle: layout.operator("mesh.mark_freestyle_face").clear = False layout.operator("mesh.mark_freestyle_face", text="Clear Freestyle Face").clear = True - layout.separator() + +class VIEW3D_MT_edit_mesh_faces(Menu): + bl_label = "Face" + bl_idname = "VIEW3D_MT_edit_mesh_faces" + + def draw(self, context): + layout = self.layout + + with_freestyle = bpy.app.build_options.freestyle + + layout.operator_context = 'INVOKE_REGION_WIN' + + layout.operator("view3d.edit_mesh_extrude_move_normal", text="Extrude Faces"), + layout.operator("view3d.edit_mesh_extrude_move_shrink_fatten", text="Extrude Faces Along Normals"), + layout.operator("mesh.extrude_faces_move", text="Extrude Individual Faces"), + + layout.separator() + + layout.operator("mesh.inset") layout.operator("mesh.poke") props = layout.operator("mesh.quads_convert_to_tris") props.quad_method = props.ngon_method = 'BEAUTY' layout.operator("mesh.tris_convert_to_quads") - layout.operator("mesh.face_split_by_edges") + layout.operator("mesh.solidify", text="Solidify Faces") + layout.operator("mesh.wireframe") layout.separator() - layout.operator("mesh.faces_shade_smooth") - layout.operator("mesh.faces_shade_flat") + layout.operator("mesh.fill") + layout.operator("mesh.fill_grid") + layout.operator("mesh.beautify_fill") + + layout.separator() - layout.operator("mesh.normals_make_consistent", text="Recalculate Normals").inside = False + layout.operator("mesh.intersect") + layout.operator("mesh.intersect_boolean") layout.separator() - layout.operator("mesh.edge_rotate", text="Rotate Edge CW").use_ccw = False + layout.operator("mesh.face_split_by_edges") layout.separator() - layout.operator("mesh.uvs_rotate") - layout.operator("mesh.uvs_reverse") - layout.operator("mesh.colors_rotate") - layout.operator("mesh.colors_reverse") + layout.operator("mesh.faces_shade_smooth") + layout.operator("mesh.faces_shade_flat") + + layout.separator() + + layout.menu("VIEW3D_MT_edit_mesh_faces_data") class VIEW3D_MT_edit_mesh_normals(Menu): @@ -2805,6 +2845,33 @@ class VIEW3D_MT_edit_mesh_normals(Menu): layout.separator() layout.operator("mesh.flip_normals") + layout.operator("mesh.set_normals_from_faces", text="Set From Faces") + + +class VIEW3D_MT_edit_mesh_shading(Menu): + bl_label = "Shading" + + def draw(self, context): + layout = self.layout + + layout.label(text="Faces:") + layout.operator("mesh.faces_shade_smooth", text="Smooth") + layout.operator("mesh.faces_shade_flat", text="Flat") + layout.label(text="Edges:") + layout.operator("mesh.mark_sharp", text="Smooth").clear = True + layout.operator("mesh.mark_sharp", text="Sharp") + layout.label(text="Vertices:") + props = layout.operator("mesh.mark_sharp", text="Smooth") + props.use_verts = True + props.clear = True + layout.operator("mesh.mark_sharp", text="Sharp").use_verts = True + + +class VIEW3D_MT_edit_mesh_weights(Menu): + bl_label = "Weights" + + def draw(self, context): + VIEW3D_MT_paint_weight.draw_generic(self.layout, is_editmode=True) class VIEW3D_MT_edit_mesh_clean(Menu): @@ -2882,14 +2949,6 @@ class VIEW3D_MT_edit_gpencil_delete(Menu): def draw_curve(self, context): layout = self.layout - layout.menu("VIEW3D_MT_undo_redo") - - layout.separator() - - layout.menu("VIEW3D_MT_edit_curve_delete") - - layout.separator() - layout.menu("VIEW3D_MT_transform") layout.menu("VIEW3D_MT_mirror") layout.menu("VIEW3D_MT_snap") @@ -2914,15 +2973,9 @@ def draw_curve(self, context): layout.separator() - layout.menu("VIEW3D_MT_edit_curve_clean") - - layout.separator() - - layout.menu("VIEW3D_MT_edit_proportional") - - layout.separator() - layout.menu("VIEW3D_MT_edit_curve_showhide") + layout.menu("VIEW3D_MT_edit_curve_clean") + layout.menu("VIEW3D_MT_edit_curve_delete") class VIEW3D_MT_edit_curve(Menu): @@ -2966,6 +3019,7 @@ class VIEW3D_MT_edit_curve_segments(Menu): layout.operator("curve.subdivide") layout.operator("curve.switch_direction") + class VIEW3D_MT_edit_curve_clean(Menu): bl_label = "Clean Up" @@ -2976,7 +3030,7 @@ class VIEW3D_MT_edit_curve_clean(Menu): class VIEW3D_MT_edit_curve_specials(Menu): - bl_label = "Specials" + bl_label = "Context Menu" def draw(self, context): layout = self.layout @@ -3023,9 +3077,6 @@ class VIEW3D_MT_edit_font(Menu): def draw(self, context): layout = self.layout - # Break convention of having undo menu here, - # instead place in "Edit" menu, matching the text menu. - layout.menu("VIEW3D_MT_edit_text_chars") layout.separator() @@ -3085,14 +3136,6 @@ class VIEW3D_MT_edit_meta(Menu): def draw(self, context): layout = self.layout - layout.menu("VIEW3D_MT_undo_redo") - - layout.separator() - - layout.operator("mball.delete_metaelems", text="Delete...") - - layout.separator() - layout.menu("VIEW3D_MT_transform") layout.menu("VIEW3D_MT_mirror") layout.menu("VIEW3D_MT_snap") @@ -3103,11 +3146,8 @@ class VIEW3D_MT_edit_meta(Menu): layout.separator() - layout.menu("VIEW3D_MT_edit_proportional") - - layout.separator() - layout.menu("VIEW3D_MT_edit_meta_showhide") + layout.operator("mball.delete_metaelems", text="Delete...") class VIEW3D_MT_edit_meta_showhide(Menu): @@ -3127,8 +3167,6 @@ class VIEW3D_MT_edit_lattice(Menu): def draw(self, context): layout = self.layout - layout.menu("VIEW3D_MT_undo_redo") - layout.separator() layout.menu("VIEW3D_MT_transform") @@ -3144,10 +3182,6 @@ class VIEW3D_MT_edit_lattice(Menu): layout.operator("object.vertex_parent_set") - layout.separator() - - layout.menu("VIEW3D_MT_edit_proportional") - class VIEW3D_MT_edit_armature(Menu): bl_label = "Armature" @@ -3158,14 +3192,6 @@ class VIEW3D_MT_edit_armature(Menu): edit_object = context.edit_object arm = edit_object.data - layout.menu("VIEW3D_MT_undo_redo") - - layout.separator() - - layout.operator("armature.delete") - - layout.separator() - layout.menu("VIEW3D_MT_transform_armature") layout.menu("VIEW3D_MT_mirror") layout.menu("VIEW3D_MT_snap") @@ -3212,9 +3238,13 @@ class VIEW3D_MT_edit_armature(Menu): layout.menu("VIEW3D_MT_bone_options_toggle", text="Bone Settings") + layout.separator() + + layout.operator("armature.delete") + class VIEW3D_MT_armature_specials(Menu): - bl_label = "Specials" + bl_label = "Context Menu" def draw(self, context): layout = self.layout @@ -3282,14 +3312,6 @@ class VIEW3D_MT_edit_gpencil(Menu): layout = self.layout - layout.menu("VIEW3D_MT_undo_redo") - - layout.separator() - - layout.menu("VIEW3D_MT_edit_gpencil_delete") - - layout.separator() - layout.menu("VIEW3D_MT_edit_gpencil_transform") layout.operator("transform.mirror", text="Mirror") layout.menu("GPENCIL_MT_snap") @@ -3321,10 +3343,6 @@ class VIEW3D_MT_edit_gpencil(Menu): layout.separator() - layout.menu("VIEW3D_MT_edit_proportional") - - layout.separator() - layout.operator("gpencil.reveal") layout.operator("gpencil.hide", text="Show Active Layer Only").unselected = True layout.operator("gpencil.hide", text="Hide Active Layer").unselected = False @@ -3339,6 +3357,10 @@ class VIEW3D_MT_edit_gpencil(Menu): layout.operator_menu_enum("gpencil.convert", "type", text="Convert to Geometry...") + layout.separator() + + layout.menu("VIEW3D_MT_edit_gpencil_delete") + class VIEW3D_MT_edit_gpencil_transform(Menu): bl_label = "Transform" @@ -3479,68 +3501,197 @@ class VIEW3D_PT_view3d_name(Panel): row.prop(bone, "name", text="") -class VIEW3D_PT_view3d_display(Panel): +class VIEW3D_PT_shading(Panel): bl_space_type = 'VIEW_3D' - bl_region_type = 'UI' - bl_label = "Display" - bl_options = {'DEFAULT_CLOSED'} + bl_region_type = 'HEADER' + bl_label = "Shading" @classmethod def poll(cls, context): - view = context.space_data - return (view) + return True def draw(self, context): layout = self.layout view = context.space_data - scene = context.scene + shading = view.shading col = layout.column() - col.prop(view, "show_only_render") - col.prop(view, "show_world") + + if shading.type == 'SOLID': + col.row().prop(shading, "color_type", expand=True) + + if shading.color_type == 'SINGLE': + col.row().prop(shading, "single_color", text="") + + if shading.type in ('SOLID', 'TEXTURED'): + col.row().prop(shading, "light", expand=True) + if shading.light == 'STUDIO': + col.row().template_icon_view(shading, "studio_light") + if shading.studio_light_orientation == 'WORLD': + col.row().prop(shading, "studiolight_rot_z") + + row = col.row() + row.prop(shading, "show_specular_highlight") + + col.separator() + + row = col.row() + row.prop(shading, "show_xray") + sub = row.row() + sub.active = shading.show_xray + sub.prop(shading, "xray_alpha", text="") + + row = col.row() + row.active = not shading.show_xray + row.prop(shading, "show_shadows") + sub = row.row() + sub.active = shading.show_shadows and not shading.show_xray + sub.prop(shading, "shadow_intensity", text="") + + row = col.row() + row.prop(shading, "show_object_outline") + sub = row.row() + sub.active = shading.show_object_outline + sub.prop(shading, "object_outline_color", text="") + + col.prop(view, "show_world") + + elif shading.type in ('MATERIAL'): + col.row().template_icon_view(shading, "studio_light") + if shading.studio_light_orientation == 'WORLD': + col.row().prop(shading, "studiolight_rot_z") + col.row().prop(shading, "studiolight_background") + col.prop(shading, "use_scene_light") + + +class VIEW3D_PT_overlay(Panel): + bl_space_type = 'VIEW_3D' + bl_region_type = 'HEADER' + bl_label = "Overlays" + + @classmethod + def poll(cls, context): + return True + + def draw(self, context): + layout = self.layout + + view = context.space_data + shading = view.shading + overlay = view.overlay + scene = context.scene + toolsettings = context.tool_settings + display_all = overlay.show_overlays col = layout.column() - display_all = not view.show_only_render col.active = display_all - col.prop(view, "show_outline_selected") - col.prop(view, "show_all_objects_origin") - col.prop(view, "show_relationship_lines") + + col.prop(view, "show_manipulator", text="Manipulators") + + col.prop(overlay, "show_text", text="Text") + col.prop(overlay, "show_cursor", text="3D Cursor") + col.prop(overlay, "show_outline_selected") + col.prop(overlay, "show_all_objects_origin") + col.prop(overlay, "show_relationship_lines") + col.prop(overlay, "show_motion_paths") + col.prop(overlay, "show_face_orientation") + col.prop(overlay, "show_wireframes") + col.prop(overlay, "show_backface_culling") + + if shading.type == "MATERIAL": + col.prop(overlay, "show_look_dev") col = layout.column() col.active = display_all split = col.split(percentage=0.55) - split.prop(view, "show_floor", text="Grid Floor") + split.prop(overlay, "show_floor", text="Grid Floor") row = split.row(align=True) - row.prop(view, "show_axis_x", text="X", toggle=True) - row.prop(view, "show_axis_y", text="Y", toggle=True) - row.prop(view, "show_axis_z", text="Z", toggle=True) + row.prop(overlay, "show_axis_x", text="X", toggle=True) + row.prop(overlay, "show_axis_y", text="Y", toggle=True) + row.prop(overlay, "show_axis_z", text="Z", toggle=True) sub = col.column(align=True) - sub.active = bool(view.show_floor or view.region_quadviews or not view.region_3d.is_perspective) - subsub = sub.column(align=True) - subsub.active = view.show_floor - subsub.prop(view, "grid_lines", text="Lines") - sub.prop(view, "grid_scale", text="Scale") + sub.active = bool(overlay.show_floor or view.region_quadviews or not view.region_3d.is_perspective) subsub = sub.column(align=True) - subsub.active = scene.unit_settings.system == 'NONE' - subsub.prop(view, "grid_subdivisions", text="Subdivisions") + subsub.active = overlay.show_floor + sub.prop(overlay, "grid_scale", text="Scale") + sub.prop(overlay, "grid_subdivisions", text="Subdivisions") - layout.separator() + if context.mode == 'EDIT_MESH': + col.separator() + col.label(text="Edit Mode:") - layout.operator("screen.region_quadview", text="Toggle Quad View") + col.prop(overlay, "show_occlude_wire") + + col.prop(overlay, "show_weight") + col.label("Show Zero Weights:") + col.row().prop(toolsettings, "vertex_group_user", expand=True) + + col.label(text="Normals:") + row = col.row(align=True) + + row.prop(overlay, "show_vertex_normals", text="", icon='VERTEXSEL') + row.prop(overlay, "show_split_normals", text="", icon='LOOPSEL') + row.prop(overlay, "show_face_normals", text="", icon='FACESEL') + + sub = row.row(align=True) + sub.active = overlay.show_vertex_normals or overlay.show_face_normals or overlay.show_split_normals + sub.prop(overlay, "normals_length", text="Size") + + elif context.mode == 'POSE': + col.separator() + col.label(text="Pose Mode:") - if view.region_quadviews: - region = view.region_quadviews[2] col = layout.column() - col.prop(region, "lock_rotation") - row = col.row() - row.enabled = region.lock_rotation - row.prop(region, "show_sync_view") - row = col.row() - row.enabled = region.lock_rotation and region.show_sync_view - row.prop(region, "use_box_clip") + col.active = display_all + col.prop(overlay, "show_transparent_bones") + col.prop(overlay, "show_bone_selection") + + elif context.mode == 'EDIT_ARMATURE': + col.separator() + col.label(text="Edit Armature:") + + col = layout.column() + col.active = display_all + col.prop(overlay, "show_transparent_bones") + + elif context.mode in {'PAINT_WEIGHT', 'PAINT_VERTEX', 'PAINT_TEXTURE'}: + col.separator() + col.label(text="Paint Mode:") + + if context.mode in {'PAINT_WEIGHT', 'PAINT_VERTEX'}: + col.prop(overlay, "show_paint_wire") + + col.prop(view, "show_mode_shade_override") + + +class VIEW3D_PT_quad_view(Panel): + bl_space_type = 'VIEW_3D' + bl_region_type = 'UI' + bl_label = "Quad View" + bl_options = {'DEFAULT_CLOSED'} + + @classmethod + def poll(cls, context): + view = context.space_data + return view.region_quadviews + + def draw(self, context): + layout = self.layout + + view = context.space_data + + region = view.region_quadviews[2] + col = layout.column() + col.prop(region, "lock_rotation") + row = col.row() + row.enabled = region.lock_rotation + row.prop(region, "show_sync_view") + row = col.row() + row.enabled = region.lock_rotation and region.show_sync_view + row.prop(region, "use_box_clip") class VIEW3D_PT_view3d_stereo(Panel): @@ -3583,56 +3734,6 @@ class VIEW3D_PT_view3d_stereo(Panel): 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 - - view = context.space_data - scene = context.scene - gs = scene.game_settings - obj = context.object - - col = layout.column() - - if not scene.render.use_shading_nodes: - col.prop(gs, "material_mode", text="") - - if view.viewport_shade == 'SOLID': - col.prop(view, "show_textured_solid") - col.prop(view, "use_matcap") - if view.use_matcap: - col.template_icon_view(view, "matcap_icon") - if view.viewport_shade == 'TEXTURED' or context.mode == 'PAINT_TEXTURE': - if scene.render.use_shading_nodes or gs.material_mode != 'GLSL': - col.prop(view, "show_textured_shadeless") - - col.prop(view, "show_backface_culling") - - if view.viewport_shade not in {'BOUNDBOX', 'WIREFRAME'}: - if obj and obj.mode == 'EDIT': - col.prop(view, "show_occlude_wire") - - 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 - subcol = col.column(align=True) - subcol.prop(ssao_settings, "factor") - subcol.prop(ssao_settings, "distance_max") - subcol.prop(ssao_settings, "attenuation") - subcol.prop(ssao_settings, "samples") - subcol.prop(ssao_settings, "color") - - class VIEW3D_PT_view3d_motion_tracking(Panel): bl_space_type = 'VIEW_3D' bl_region_type = 'UI' @@ -3691,8 +3792,6 @@ class VIEW3D_PT_view3d_meshdisplay(Panel): if with_freestyle: col.prop(mesh, "show_edge_seams", text="Seams") - layout.prop(mesh, "show_weight") - col = split.column() col.label() if not with_freestyle: @@ -3706,18 +3805,6 @@ class VIEW3D_PT_view3d_meshdisplay(Panel): col = layout.column() col.separator() - col.label(text="Normals:") - row = col.row(align=True) - - row.prop(mesh, "show_normal_vertex", text="", icon='VERTEXSEL') - row.prop(mesh, "show_normal_loop", text="", icon='LOOPSEL') - row.prop(mesh, "show_normal_face", text="", icon='FACESEL') - - sub = row.row(align=True) - sub.active = mesh.show_normal_vertex or mesh.show_normal_face or mesh.show_normal_loop - sub.prop(scene.tool_settings, "normal_size", text="Size") - - col.separator() split = layout.split() col = split.column() col.label(text="Edge Info:") @@ -3728,7 +3815,7 @@ class VIEW3D_PT_view3d_meshdisplay(Panel): col.prop(mesh, "show_extra_face_area", text="Area") col.prop(mesh, "show_extra_face_angle", text="Angle") if bpy.app.debug: - layout.prop(mesh, "show_extra_indices") + layout.prop(mesh, "show_extra_indices", text="Indices") class VIEW3D_PT_view3d_meshstatvis(Panel): @@ -3796,114 +3883,6 @@ class VIEW3D_PT_view3d_curvedisplay(Panel): row = col.row() row.prop(curve, "show_handles", text="Handles") row.prop(curve, "show_normal_face", text="Normals") - col.prop(context.scene.tool_settings, "normal_size", text="Normal Size") - - -class VIEW3D_PT_background_image(Panel): - bl_space_type = 'VIEW_3D' - bl_region_type = 'UI' - bl_label = "Background Images" - bl_options = {'DEFAULT_CLOSED'} - - def draw_header(self, context): - view = context.space_data - - self.layout.prop(view, "show_background_images", text="") - - def draw(self, context): - layout = self.layout - - view = context.space_data - use_multiview = context.scene.render.use_multiview - - col = layout.column() - col.operator("view3d.background_image_add", text="Add Image") - - for i, bg in enumerate(view.background_images): - layout.active = view.show_background_images - box = layout.box() - row = box.row(align=True) - row.prop(bg, "show_expanded", text="", emboss=False) - if bg.source == 'IMAGE' and bg.image: - row.prop(bg.image, "name", text="", emboss=False) - elif bg.source == 'MOVIE_CLIP' and bg.clip: - row.prop(bg.clip, "name", text="", emboss=False) - else: - row.label(text="Not Set") - - if bg.show_background_image: - row.prop(bg, "show_background_image", text="", emboss=False, icon='RESTRICT_VIEW_OFF') - else: - row.prop(bg, "show_background_image", text="", emboss=False, icon='RESTRICT_VIEW_ON') - - row.operator("view3d.background_image_remove", text="", emboss=False, icon='X').index = i - - box.prop(bg, "view_axis", text="Axis") - - if bg.show_expanded: - row = box.row() - row.prop(bg, "source", expand=True) - - has_bg = False - if bg.source == 'IMAGE': - row = box.row() - row.template_ID(bg, "image", open="image.open") - if bg.image is not None: - box.template_image(bg, "image", bg.image_user, compact=True) - has_bg = True - - if use_multiview and bg.view_axis in {'CAMERA', 'ALL'}: - box.prop(bg.image, "use_multiview") - - column = box.column() - column.active = bg.image.use_multiview - - column.label(text="Views Format:") - column.row().prop(bg.image, "views_format", expand=True) - - sub = column.box() - sub.active = bg.image.views_format == 'STEREO_3D' - sub.template_image_stereo_3d(bg.image.stereo_3d_format) - - elif bg.source == 'MOVIE_CLIP': - box.prop(bg, "use_camera_clip") - - column = box.column() - column.active = not bg.use_camera_clip - column.template_ID(bg, "clip", open="clip.open") - - if bg.clip: - column.template_movieclip(bg, "clip", compact=True) - - if bg.use_camera_clip or bg.clip: - has_bg = True - - column = box.column() - column.active = has_bg - column.prop(bg.clip_user, "proxy_render_size", text="") - column.prop(bg.clip_user, "use_render_undistorted") - - if has_bg: - col = box.column() - col.prop(bg, "opacity", slider=True) - col.row().prop(bg, "draw_depth", expand=True) - - if bg.view_axis in {'CAMERA', 'ALL'}: - col.row().prop(bg, "frame_method", expand=True) - - box = col.box() - row = box.row() - row.prop(bg, "offset_x", text="X") - row.prop(bg, "offset_y", text="Y") - - row = box.row() - row.prop(bg, "use_flip_x") - row.prop(bg, "use_flip_y") - - row = box.row() - if bg.view_axis != 'CAMERA': - row.prop(bg, "rotation") - row.prop(bg, "size") class VIEW3D_PT_transform_orientations(Panel): @@ -3920,11 +3899,11 @@ class VIEW3D_PT_transform_orientations(Panel): def draw(self, context): layout = self.layout - view = context.space_data - orientation = view.current_orientation + scene = context.scene + orientation = scene.current_orientation row = layout.row(align=True) - row.prop(view, "transform_orientation", text="") + row.prop(scene, "transform_orientation", text="") row.operator("transform.create_orientation", text="", icon='ZOOMIN') if orientation: @@ -3933,63 +3912,6 @@ class VIEW3D_PT_transform_orientations(Panel): row.operator("transform.delete_orientation", text="", icon='X') -class VIEW3D_PT_etch_a_ton(Panel): - bl_space_type = 'VIEW_3D' - bl_region_type = 'UI' - bl_label = "Skeleton Sketching" - bl_options = {'DEFAULT_CLOSED'} - - @classmethod - def poll(cls, context): - scene = context.space_data - ob = context.active_object - return scene and ob and ob.type == 'ARMATURE' and ob.mode == 'EDIT' - - def draw_header(self, context): - layout = self.layout - toolsettings = context.scene.tool_settings - - layout.prop(toolsettings, "use_bone_sketching", text="") - - def draw(self, context): - layout = self.layout - - toolsettings = context.scene.tool_settings - - col = layout.column() - - col.prop(toolsettings, "use_etch_quick") - col.prop(toolsettings, "use_etch_overdraw") - - col.separator() - - col.prop(toolsettings, "etch_convert_mode") - - if toolsettings.etch_convert_mode == 'LENGTH': - col.prop(toolsettings, "etch_length_limit") - elif toolsettings.etch_convert_mode == 'ADAPTIVE': - col.prop(toolsettings, "etch_adaptive_limit") - elif toolsettings.etch_convert_mode == 'FIXED': - col.prop(toolsettings, "etch_subdivision_number") - elif toolsettings.etch_convert_mode == 'RETARGET': - col.prop(toolsettings, "etch_template") - col.prop(toolsettings, "etch_roll_mode") - - col.separator() - - colsub = col.column(align=True) - colsub.prop(toolsettings, "use_etch_autoname") - sub = colsub.column(align=True) - sub.enabled = not toolsettings.use_etch_autoname - sub.prop(toolsettings, "etch_number") - sub.prop(toolsettings, "etch_side") - - col.separator() - - col.operator("sketch.convert", text="Convert to Bones") - col.operator("sketch.delete", text="Delete Strokes") - - class VIEW3D_PT_context_properties(Panel): bl_space_type = 'VIEW_3D' bl_region_type = 'UI' @@ -4075,24 +3997,24 @@ classes = ( INFO_MT_edit_armature_add, INFO_MT_armature_add, INFO_MT_lamp_add, + INFO_MT_lightprobe_add, INFO_MT_camera_add, INFO_MT_add, - VIEW3D_MT_undo_redo, - VIEW3D_MT_object_relations, VIEW3D_MT_object, VIEW3D_MT_object_animation, + VIEW3D_MT_object_rigid_body, VIEW3D_MT_object_clear, VIEW3D_MT_object_specials, + VIEW3D_MT_object_shading, VIEW3D_MT_object_apply, + VIEW3D_MT_object_relations, VIEW3D_MT_object_parent, VIEW3D_MT_object_track, - VIEW3D_MT_object_group, + VIEW3D_MT_object_collection, VIEW3D_MT_object_constraints, VIEW3D_MT_object_quick_effects, - VIEW3D_MT_object_showhide, VIEW3D_MT_make_single_user, VIEW3D_MT_make_links, - VIEW3D_MT_object_game, VIEW3D_MT_brush, VIEW3D_MT_brush_paint_modes, VIEW3D_MT_paint_vertex, @@ -4128,7 +4050,10 @@ classes = ( VIEW3D_MT_edit_mesh_edges, VIEW3D_MT_edit_mesh_edges_data, VIEW3D_MT_edit_mesh_faces, + VIEW3D_MT_edit_mesh_faces_data, VIEW3D_MT_edit_mesh_normals, + VIEW3D_MT_edit_mesh_shading, + VIEW3D_MT_edit_mesh_weights, VIEW3D_MT_edit_mesh_clean, VIEW3D_MT_edit_mesh_delete, VIEW3D_MT_edit_mesh_showhide, @@ -4159,16 +4084,15 @@ classes = ( VIEW3D_PT_view3d_properties, VIEW3D_PT_view3d_cursor, VIEW3D_PT_view3d_name, - VIEW3D_PT_view3d_display, + VIEW3D_PT_quad_view, VIEW3D_PT_view3d_stereo, - VIEW3D_PT_view3d_shading, VIEW3D_PT_view3d_motion_tracking, VIEW3D_PT_view3d_meshdisplay, VIEW3D_PT_view3d_meshstatvis, VIEW3D_PT_view3d_curvedisplay, - VIEW3D_PT_background_image, + VIEW3D_PT_shading, + VIEW3D_PT_overlay, VIEW3D_PT_transform_orientations, - VIEW3D_PT_etch_a_ton, VIEW3D_PT_context_properties, ) diff --git a/release/scripts/startup/bl_ui/space_view3d_toolbar.py b/release/scripts/startup/bl_ui/space_view3d_toolbar.py index 19cba5af4ee..f6dc64c7df7 100644 --- a/release/scripts/startup/bl_ui/space_view3d_toolbar.py +++ b/release/scripts/startup/bl_ui/space_view3d_toolbar.py @@ -36,8 +36,8 @@ from .properties_paint_common import ( class View3DPanel: - bl_space_type = 'VIEW_3D' - bl_region_type = 'TOOLS' + bl_space_type = 'PROPERTIES' + bl_region_type = 'WINDOW' # **************** standard tool clusters ****************** @@ -64,408 +64,13 @@ def draw_vpaint_symmetry(layout, vpaint): col = layout.column() col.prop(vpaint, "radial_symmetry", text="Radial") -# ********** default tools for object-mode **************** - - -class VIEW3D_PT_tools_transform(View3DPanel, Panel): - bl_category = "Tools" - bl_context = "objectmode" - bl_label = "Transform" - - def draw(self, context): - layout = self.layout - - col = layout.column(align=True) - col.operator("transform.translate") - col.operator("transform.rotate") - col.operator("transform.resize", text="Scale") - - col = layout.column(align=True) - col.operator("transform.mirror", text="Mirror") - - -class VIEW3D_PT_tools_object(View3DPanel, Panel): - bl_category = "Tools" - bl_context = "objectmode" - bl_label = "Edit" - - def draw(self, context): - layout = self.layout - - col = layout.column(align=True) - col.operator("object.duplicate_move", text="Duplicate") - col.operator("object.duplicate_move_linked", text="Duplicate Linked") - - col.operator("object.delete") - - obj = context.active_object - if obj: - obj_type = obj.type - - if obj_type in {'MESH', 'CURVE', 'SURFACE', 'ARMATURE'}: - col = layout.column(align=True) - col.operator("object.join") - - if obj_type in {'MESH', 'CURVE', 'SURFACE', 'ARMATURE', 'FONT', 'LATTICE'}: - col = layout.column(align=True) - col.operator_menu_enum("object.origin_set", "type", text="Set Origin") - - if obj_type in {'MESH', 'CURVE', 'SURFACE'}: - col = layout.column(align=True) - col.label(text="Shading:") - row = col.row(align=True) - row.operator("object.shade_smooth", text="Smooth") - row.operator("object.shade_flat", text="Flat") - - if obj_type == 'MESH': - col = layout.column(align=True) - col.label(text="Data Transfer:") - row = col.row(align=True) - row.operator("object.data_transfer", text="Data") - row.operator("object.datalayout_transfer", text="Data Layout") - - -class VIEW3D_PT_tools_add_object(View3DPanel, Panel): - bl_category = "Create" - bl_context = "objectmode" - bl_label = "Add Primitive" - - @staticmethod - def draw_add_mesh(layout, label=False): - if label: - layout.label(text="Primitives:") - layout.operator("mesh.primitive_plane_add", text="Plane", icon='MESH_PLANE') - layout.operator("mesh.primitive_cube_add", text="Cube", icon='MESH_CUBE') - layout.operator("mesh.primitive_circle_add", text="Circle", icon='MESH_CIRCLE') - layout.operator("mesh.primitive_uv_sphere_add", text="UV Sphere", icon='MESH_UVSPHERE') - layout.operator("mesh.primitive_ico_sphere_add", text="Ico Sphere", icon='MESH_ICOSPHERE') - layout.operator("mesh.primitive_cylinder_add", text="Cylinder", icon='MESH_CYLINDER') - layout.operator("mesh.primitive_cone_add", text="Cone", icon='MESH_CONE') - layout.operator("mesh.primitive_torus_add", text="Torus", icon='MESH_TORUS') - - if label: - layout.label(text="Special:") - else: - layout.separator() - layout.operator("mesh.primitive_grid_add", text="Grid", icon='MESH_GRID') - layout.operator("mesh.primitive_monkey_add", text="Monkey", icon='MESH_MONKEY') - - @staticmethod - def draw_add_curve(layout, label=False): - - if label: - layout.label(text="Bezier:") - layout.operator("curve.primitive_bezier_curve_add", text="Bezier", icon='CURVE_BEZCURVE') - layout.operator("curve.primitive_bezier_circle_add", text="Circle", icon='CURVE_BEZCIRCLE') - - if label: - layout.label(text="Nurbs:") - else: - layout.separator() - layout.operator("curve.primitive_nurbs_curve_add", text="Nurbs Curve", icon='CURVE_NCURVE') - layout.operator("curve.primitive_nurbs_circle_add", text="Nurbs Circle", icon='CURVE_NCIRCLE') - layout.operator("curve.primitive_nurbs_path_add", text="Path", icon='CURVE_PATH') - - layout.separator() - - layout.operator("curve.draw", icon='LINE_DATA') - - @staticmethod - def draw_add_surface(layout): - layout.operator("surface.primitive_nurbs_surface_curve_add", text="Nurbs Curve", icon='SURFACE_NCURVE') - layout.operator("surface.primitive_nurbs_surface_circle_add", text="Nurbs Circle", icon='SURFACE_NCIRCLE') - layout.operator("surface.primitive_nurbs_surface_surface_add", text="Nurbs Surface", icon='SURFACE_NSURFACE') - layout.operator("surface.primitive_nurbs_surface_cylinder_add", text="Nurbs Cylinder", icon='SURFACE_NCYLINDER') - layout.operator("surface.primitive_nurbs_surface_sphere_add", text="Nurbs Sphere", icon='SURFACE_NSPHERE') - layout.operator("surface.primitive_nurbs_surface_torus_add", text="Nurbs Torus", icon='SURFACE_NTORUS') - - @staticmethod - def draw_add_mball(layout): - layout.operator_enum("object.metaball_add", "type") - - @staticmethod - def draw_add_lamp(layout): - layout.operator_enum("object.lamp_add", "type") - - @staticmethod - def draw_add_other(layout): - layout.operator("object.text_add", text="Text", icon='OUTLINER_OB_FONT') - layout.operator("object.armature_add", text="Armature", icon='OUTLINER_OB_ARMATURE') - layout.operator("object.add", text="Lattice", icon='OUTLINER_OB_LATTICE').type = 'LATTICE' - layout.operator("object.empty_add", text="Empty", icon='OUTLINER_OB_EMPTY').type = 'PLAIN_AXES' - layout.operator("object.speaker_add", text="Speaker", icon='OUTLINER_OB_SPEAKER') - layout.operator("object.camera_add", text="Camera", icon='OUTLINER_OB_CAMERA') - - def draw(self, context): - layout = self.layout - - col = layout.column(align=True) - col.label(text="Mesh:") - self.draw_add_mesh(col) - - col = layout.column(align=True) - col.label(text="Curve:") - self.draw_add_curve(col) - - # not used here: - # draw_add_surface - # draw_add_mball - - col = layout.column(align=True) - col.label(text="Lamp:") - self.draw_add_lamp(col) - - col = layout.column(align=True) - col.label(text="Other:") - self.draw_add_other(col) - - -class VIEW3D_PT_tools_relations(View3DPanel, Panel): - bl_category = "Relations" - bl_context = "objectmode" - bl_label = "Relations" - - def draw(self, context): - layout = self.layout - - col = layout.column(align=True) - - col.label(text="Group:") - col.operator("group.create", text="New Group") - col.operator("group.objects_add_active", text="Add to Active") - col.operator("group.objects_remove", text="Remove from Group") - - col.separator() - - col.label(text="Parent:") - row = col.row(align=True) - row.operator("object.parent_set", text="Set") - row.operator("object.parent_clear", text="Clear") - - col.separator() - - col.label(text="Object Data:") - col.operator("object.make_links_data") - col.operator("object.make_single_user") - - col.separator() - - col.label(text="Linked Objects:") - col.operator("object.make_local") - col.operator("object.proxy_make") - - -class VIEW3D_PT_tools_animation(View3DPanel, Panel): - bl_category = "Animation" - bl_context = "objectmode" - bl_label = "Animation" - - def draw(self, context): - layout = self.layout - - ob = context.active_object - mpath = ob.motion_path if ob else None - - draw_keyframing_tools(context, layout) - - col = layout.column(align=True) - col.label(text="Motion Paths:") - if mpath: - row = col.row(align=True) - row.operator("object.paths_update", text="Update") - row.operator("object.paths_clear", text="", icon='X') - else: - col.operator("object.paths_calculate", text="Calculate") - - col.separator() - - col.label(text="Action:") - col.operator("nla.bake", text="Bake Action") - - -class VIEW3D_PT_tools_rigid_body(View3DPanel, Panel): - bl_category = "Physics" - bl_context = "objectmode" - bl_label = "Rigid Body Tools" - - def draw(self, context): - layout = self.layout - - col = layout.column(align=True) - col.label(text="Add/Remove:") - row = col.row(align=True) - row.operator("rigidbody.objects_add", text="Add Active").type = 'ACTIVE' - row.operator("rigidbody.objects_add", text="Add Passive").type = 'PASSIVE' - row = col.row(align=True) - row.operator("rigidbody.objects_remove", text="Remove") - - col = layout.column(align=True) - col.label(text="Object Tools:") - col.operator("rigidbody.shape_change", text="Change Shape") - col.operator("rigidbody.mass_calculate", text="Calculate Mass") - col.operator("rigidbody.object_settings_copy", text="Copy from Active") - col.operator("object.visual_transform_apply", text="Apply Transformation") - col.operator("rigidbody.bake_to_keyframes", text="Bake To Keyframes") - col.label(text="Constraints:") - col.operator("rigidbody.connect", text="Connect") - # ********** default tools for editmode_mesh **************** -class VIEW3D_PT_tools_transform_mesh(View3DPanel, Panel): - bl_category = "Tools" - bl_context = "mesh_edit" - bl_label = "Transform" - - def draw(self, context): - layout = self.layout - - col = layout.column(align=True) - col.operator("transform.translate") - col.operator("transform.rotate") - col.operator("transform.resize", text="Scale") - col.operator("transform.shrink_fatten", text="Shrink/Fatten") - col.operator("transform.push_pull", text="Push/Pull") - - -class VIEW3D_PT_tools_meshedit(View3DPanel, Panel): - bl_category = "Tools" - bl_context = "mesh_edit" - bl_label = "Mesh Tools" - - def draw(self, context): - layout = self.layout - - col = layout.column(align=True) - col.label(text="Deform:") - row = col.row(align=True) - row.operator("transform.edge_slide", text="Slide Edge") - row.operator("transform.vert_slide", text="Vertex") - col.operator("mesh.noise") - col.operator("mesh.vertices_smooth") - col.operator("transform.vertex_random") - - col = layout.column(align=True) - col.label(text="Add:") - - col.menu("VIEW3D_MT_edit_mesh_extrude") - col.operator("view3d.edit_mesh_extrude_move_normal", text="Extrude Region") - col.operator("view3d.edit_mesh_extrude_individual_move", text="Extrude Individual") - col.operator("mesh.inset", text="Inset Faces") - col.operator("mesh.edge_face_add") - col.operator("mesh.subdivide") - col.operator("mesh.loopcut_slide") - col.operator("mesh.offset_edge_loops_slide") - col.operator("mesh.duplicate_move", text="Duplicate") - row = col.row(align=True) - row.operator("mesh.spin") - row.operator("mesh.screw") - - row = col.row(align=True) - props = row.operator("mesh.knife_tool", text="Knife") - props.use_occlude_geometry = True - props.only_selected = False - props = row.operator("mesh.knife_tool", text="Select") - props.use_occlude_geometry = False - props.only_selected = True - col.operator("mesh.knife_project") - col.operator("mesh.bisect") - - col = layout.column(align=True) - col.label(text="Remove:") - col.menu("VIEW3D_MT_edit_mesh_delete") - col.operator_menu_enum("mesh.merge", "type") - col.operator("mesh.remove_doubles") - - -class VIEW3D_PT_tools_meshweight(View3DPanel, Panel): - bl_category = "Tools" - bl_context = "mesh_edit" - bl_label = "Weight Tools" - bl_options = {'DEFAULT_CLOSED'} - - # Used for Weight-Paint mode and Edit-Mode - @staticmethod - def draw_generic(layout): - col = layout.column() - col.operator("object.vertex_group_normalize_all", text="Normalize All") - col.operator("object.vertex_group_normalize", text="Normalize") - col.operator("object.vertex_group_mirror", text="Mirror") - col.operator("object.vertex_group_invert", text="Invert") - col.operator("object.vertex_group_clean", text="Clean") - col.operator("object.vertex_group_quantize", text="Quantize") - col.operator("object.vertex_group_levels", text="Levels") - col.operator("object.vertex_group_smooth", text="Smooth") - col.operator("object.vertex_group_limit_total", text="Limit Total") - col.operator("object.vertex_group_fix", text="Fix Deforms") - - def draw(self, context): - layout = self.layout - self.draw_generic(layout) - - -class VIEW3D_PT_tools_add_mesh_edit(View3DPanel, Panel): - bl_category = "Create" - bl_context = "mesh_edit" - bl_label = "Add Meshes" - - def draw(self, context): - layout = self.layout - - col = layout.column(align=True) - - VIEW3D_PT_tools_add_object.draw_add_mesh(col, label=True) - - -class VIEW3D_PT_tools_shading(View3DPanel, Panel): - bl_category = "Shading / UVs" - bl_context = "mesh_edit" - bl_label = "Shading" - - def draw(self, context): - layout = self.layout - - col = layout.column(align=True) - col.label(text="Faces:") - row = col.row(align=True) - row.operator("mesh.faces_shade_smooth", text="Smooth") - row.operator("mesh.faces_shade_flat", text="Flat") - col.label(text="Edges:") - row = col.row(align=True) - row.operator("mesh.mark_sharp", text="Smooth").clear = True - row.operator("mesh.mark_sharp", text="Sharp") - col.label(text="Vertices:") - row = col.row(align=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) - col.label(text="Normals:") - col.operator("mesh.normals_make_consistent", text="Recalculate") - col.operator("mesh.flip_normals", text="Flip Direction") - col.operator("mesh.set_normals_from_faces", text="Set From Faces") - - -class VIEW3D_PT_tools_uvs(View3DPanel, Panel): - bl_category = "Shading / UVs" - bl_context = "mesh_edit" - bl_label = "UVs" - - def draw(self, context): - layout = self.layout - - col = layout.column(align=True) - col.label(text="UV Mapping:") - col.menu("VIEW3D_MT_uv_map", text="Unwrap") - col.operator("mesh.mark_seam").clear = False - col.operator("mesh.mark_seam", text="Clear Seam").clear = True - class VIEW3D_PT_tools_meshedit_options(View3DPanel, Panel): bl_category = "Options" - bl_context = "mesh_edit" + bl_context = ".mesh_edit" # dot on purpose (access from topbar) bl_label = "Mesh Options" @classmethod @@ -494,84 +99,11 @@ class VIEW3D_PT_tools_meshedit_options(View3DPanel, Panel): col.label("Double Threshold:") col.prop(tool_settings, "double_threshold", text="") - if mesh.show_weight: - col.label("Show Zero Weights:") - col.row().prop(tool_settings, "vertex_group_user", expand=True) - # ********** default tools for editmode_curve **************** - -class VIEW3D_PT_tools_transform_curve(View3DPanel, Panel): - bl_category = "Tools" - bl_context = "curve_edit" - bl_label = "Transform" - - def draw(self, context): - layout = self.layout - - col = layout.column(align=True) - col.operator("transform.translate") - col.operator("transform.rotate") - col.operator("transform.resize", text="Scale") - - col = layout.column(align=True) - col.operator("transform.tilt", text="Tilt") - col.operator("transform.transform", text="Shrink/Fatten").mode = 'CURVE_SHRINKFATTEN' - - -class VIEW3D_PT_tools_curveedit(View3DPanel, Panel): - bl_category = "Tools" - bl_context = "curve_edit" - bl_label = "Curve Tools" - - def draw(self, context): - layout = self.layout - - col = layout.column(align=True) - col.label(text="Curve:") - col.operator("curve.duplicate_move", text="Duplicate") - col.operator("curve.delete") - col.operator("curve.cyclic_toggle") - col.operator("curve.switch_direction") - col.operator("curve.spline_type_set") - col.operator("curve.radius_set") - - col = layout.column(align=True) - col.label(text="Handles:") - row = col.row(align=True) - row.operator("curve.handle_type_set", text="Auto").type = 'AUTOMATIC' - row.operator("curve.handle_type_set", text="Vector").type = 'VECTOR' - row = col.row(align=True) - row.operator("curve.handle_type_set", text="Align").type = 'ALIGNED' - row.operator("curve.handle_type_set", text="Free").type = 'FREE_ALIGN' - - col = layout.column(align=True) - col.operator("curve.normals_make_consistent") - - col = layout.column(align=True) - col.label(text="Modeling:") - col.operator("curve.extrude_move", text="Extrude") - col.operator("curve.subdivide") - col.operator("curve.smooth") - col.operator("transform.vertex_random") - - -class VIEW3D_PT_tools_add_curve_edit(View3DPanel, Panel): - bl_category = "Create" - bl_context = "curve_edit" - bl_label = "Add Curves" - - def draw(self, context): - layout = self.layout - - col = layout.column(align=True) - - VIEW3D_PT_tools_add_object.draw_add_curve(col, label=True) - - class VIEW3D_PT_tools_curveedit_options_stroke(View3DPanel, Panel): bl_category = "Options" - bl_context = "curve_edit" + bl_context = ".curve_edit" # dot on purpose (access from topbar) bl_label = "Curve Stroke" def draw(self, context): @@ -623,128 +155,14 @@ class VIEW3D_PT_tools_curveedit_options_stroke(View3DPanel, Panel): colsub.prop(cps, "surface_plane", expand=True) -# ********** default tools for editmode_surface **************** - -class VIEW3D_PT_tools_transform_surface(View3DPanel, Panel): - bl_category = "Tools" - bl_context = "surface_edit" - bl_label = "Transform" - - def draw(self, context): - layout = self.layout - - col = layout.column(align=True) - col.operator("transform.translate") - col.operator("transform.rotate") - col.operator("transform.resize", text="Scale") - - -class VIEW3D_PT_tools_surfaceedit(View3DPanel, Panel): - bl_category = "Tools" - bl_context = "surface_edit" - bl_label = "Surface Tools" - - def draw(self, context): - layout = self.layout - - col = layout.column(align=True) - col.label(text="Curve:") - col.operator("curve.duplicate_move", text="Duplicate") - col.operator("curve.delete") - col.operator("curve.cyclic_toggle") - col.operator("curve.switch_direction") - - 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("transform.vertex_random") - - -class VIEW3D_PT_tools_add_surface_edit(View3DPanel, Panel): - bl_category = "Create" - bl_context = "surface_edit" - bl_label = "Add Surfaces" - - def draw(self, context): - layout = self.layout - - col = layout.column(align=True) - - VIEW3D_PT_tools_add_object.draw_add_surface(col) - - -# ********** default tools for editmode_text **************** - - -class VIEW3D_PT_tools_textedit(View3DPanel, Panel): - bl_category = "Tools" - bl_context = "text_edit" - bl_label = "Text Tools" - - def draw(self, context): - layout = self.layout - - col = layout.column(align=True) - col.label(text="Set Case:") - col.operator("font.case_set", text="To Upper").case = 'UPPER' - col.operator("font.case_set", text="To Lower").case = 'LOWER' - - col = layout.column(align=True) - col.label(text="Style:") - col.operator("font.style_toggle", text="Bold").style = 'BOLD' - col.operator("font.style_toggle", text="Italic").style = 'ITALIC' - col.operator("font.style_toggle", text="Underline").style = 'UNDERLINE' # ********** default tools for editmode_armature **************** -class VIEW3D_PT_tools_armatureedit_transform(View3DPanel, Panel): - bl_category = "Tools" - bl_context = "armature_edit" - bl_label = "Transform" - - def draw(self, context): - layout = self.layout - - col = layout.column(align=True) - col.operator("transform.translate") - col.operator("transform.rotate") - col.operator("transform.resize", text="Scale") - - -class VIEW3D_PT_tools_armatureedit(View3DPanel, Panel): - bl_category = "Tools" - bl_context = "armature_edit" - bl_label = "Armature Tools" - - def draw(self, context): - layout = self.layout - - col = layout.column(align=True) - col.label(text="Bones:") - col.operator("armature.bone_primitive_add", text="Add") - col.operator("armature.duplicate_move", text="Duplicate") - col.operator("armature.delete", text="Delete") - - col = layout.column(align=True) - col.label(text="Modeling:") - col.operator("armature.extrude_move") - col.operator("armature.subdivide", text="Subdivide") - - col = layout.column(align=True) - col.label(text="Deform:") - col.operator("transform.vertex_random") - - class VIEW3D_PT_tools_armatureedit_options(View3DPanel, Panel): bl_category = "Options" - bl_context = "armature_edit" + bl_context = ".armature_edit" # dot on purpose (access from topbar) bl_label = "Armature Options" def draw(self, context): @@ -753,138 +171,30 @@ class VIEW3D_PT_tools_armatureedit_options(View3DPanel, Panel): self.layout.prop(arm, "use_mirror_x") -# ********** default tools for editmode_mball **************** - - -class VIEW3D_PT_tools_mballedit(View3DPanel, Panel): - bl_category = "Tools" - bl_context = "mball_edit" - bl_label = "Meta Tools" - - def draw(self, context): - layout = self.layout - - col = layout.column(align=True) - col.label(text="Transform:") - col.operator("transform.translate") - col.operator("transform.rotate") - col.operator("transform.resize", text="Scale") - - col = layout.column(align=True) - col.label(text="Deform:") - col.operator("transform.vertex_random") - - -class VIEW3D_PT_tools_add_mball_edit(View3DPanel, Panel): - bl_category = "Create" - bl_context = "mball_edit" - bl_label = "Add Metaball" - - def draw(self, context): - layout = self.layout - - col = layout.column(align=True) - - VIEW3D_PT_tools_add_object.draw_add_mball(col) - - -# ********** default tools for editmode_lattice **************** - - -class VIEW3D_PT_tools_latticeedit(View3DPanel, Panel): - bl_category = "Tools" - bl_context = "lattice_edit" - bl_label = "Lattice Tools" - - def draw(self, context): - layout = self.layout - - col = layout.column(align=True) - col.label(text="Transform:") - col.operator("transform.translate") - col.operator("transform.rotate") - col.operator("transform.resize", text="Scale") - - col = layout.column(align=True) - col.operator("lattice.make_regular") - - col = layout.column(align=True) - col.label(text="Deform:") - col.operator("transform.vertex_random") - - # ********** default tools for pose-mode **************** - -class VIEW3D_PT_tools_posemode(View3DPanel, Panel): - bl_category = "Tools" - bl_context = "posemode" - bl_label = "Pose Tools" - - def draw(self, context): - layout = self.layout - - col = layout.column(align=True) - col.label(text="Transform:") - col.operator("transform.translate") - col.operator("transform.rotate") - col.operator("transform.resize", text="Scale") - - col = layout.column(align=True) - col.label(text="In-Between:") - row = col.row(align=True) - row.operator("pose.push", text="Push") - row.operator("pose.relax", text="Relax") - col.operator("pose.breakdown", text="Breakdowner") - - col = layout.column(align=True) - col.label(text="Pose:") - row = col.row(align=True) - 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") - - draw_keyframing_tools(context, layout) - - ob = context.object - avs = ob.pose.animation_visualization - - col = layout.column(align=True) - col.label(text="Motion Paths:") - if avs.motion_path.has_motion_paths: - row = col.row(align=True) - row.operator("pose.paths_update", text="Update") - row.operator("pose.paths_clear", text="", icon='X') - else: - col.operator("pose.paths_calculate", text="Calculate") - - class VIEW3D_PT_tools_posemode_options(View3DPanel, Panel): bl_category = "Options" - bl_context = "posemode" + bl_context = ".posemode" # dot on purpose (access from topbar) bl_label = "Pose Options" def draw(self, context): arm = context.active_object.data self.layout.prop(arm, "use_auto_ik") + self.layout.prop(arm, "use_mirror_x") # ********** default tools for paint modes **************** class View3DPaintPanel(UnifiedPaintPanel): - bl_space_type = 'VIEW_3D' - bl_region_type = 'TOOLS' + bl_space_type = 'PROPERTIES' + bl_region_type = 'WINDOW' class VIEW3D_PT_imapaint_tools_missing(Panel, View3DPaintPanel): bl_category = "Tools" + bl_context = ".imagepaint" # dot on purpose (access from topbar) bl_label = "Missing Data" @classmethod @@ -946,6 +256,7 @@ class VIEW3D_PT_imapaint_tools_missing(Panel, View3DPaintPanel): class VIEW3D_PT_tools_brush(Panel, View3DPaintPanel): bl_category = "Tools" + bl_context = ".paint_common" # dot on purpose (access from topbar) bl_label = "Brush" @classmethod @@ -1199,9 +510,6 @@ class TEXTURE_UL_texpaintslots(UIList): if self.layout_type in {'DEFAULT', 'COMPACT'}: layout.prop(item, "name", text="", emboss=False, icon_value=icon) - 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 == 'GRID': layout.alignment = 'CENTER' layout.label(text="") @@ -1213,14 +521,14 @@ class VIEW3D_MT_tools_projectpaint_uvlayer(Menu): def draw(self, context): layout = self.layout - for i, tex in enumerate(context.active_object.data.uv_textures): - props = layout.operator("wm.context_set_int", text=tex.name, translate=False) - props.data_path = "active_object.data.uv_textures.active_index" + for i, uv_layer in enumerate(context.active_object.data.uv_layers): + props = layout.operator("wm.context_set_int", text=uv_layer.name, translate=False) + props.data_path = "active_object.data.uv_layers.active_index" props.value = i class VIEW3D_PT_slots_projectpaint(View3DPanel, Panel): - bl_context = "imagepaint" + bl_context = ".imagepaint" # dot on purpose (access from topbar) bl_label = "Slots" bl_category = "Slots" @@ -1262,22 +570,13 @@ class VIEW3D_PT_slots_projectpaint(View3DPanel, Panel): else: slot = None - if (not mat.use_nodes) and context.scene.render.engine in {'BLENDER_RENDER', 'BLENDER_GAME'}: - row = col.row(align=True) - row.operator_menu_enum("paint.add_texture_paint_slot", "type") - row.operator("paint.delete_texture_paint_slot", text="", icon='X') - - if slot: - col.prop(mat.texture_slots[slot.index], "blend_type") - col.separator() - - if slot and slot.index != -1: + if slot and slot.is_valid: col.label("UV Map:") - col.prop_search(slot, "uv_layer", ob.data, "uv_textures", text="") + col.prop_search(slot, "uv_layer", ob.data, "uv_layers", text="") elif settings.mode == 'IMAGE': mesh = ob.data - uv_text = mesh.uv_textures.active.name if mesh.uv_textures.active else "" + uv_text = mesh.uv_layers.active.name if mesh.uv_layers.active else "" col.label("Canvas Image:") # todo this should be combinded into a single row col.template_ID(settings, "canvas", open="image.open") @@ -1290,7 +589,7 @@ class VIEW3D_PT_slots_projectpaint(View3DPanel, Panel): class VIEW3D_PT_stencil_projectpaint(View3DPanel, Panel): - bl_context = "imagepaint" + bl_context = ".imagepaint" # dot on purpose (access from topbar) bl_label = "Mask" bl_category = "Slots" @@ -1315,8 +614,8 @@ class VIEW3D_PT_stencil_projectpaint(View3DPanel, Panel): col = layout.column() col.active = ipaint.use_stencil_layer - stencil_text = mesh.uv_texture_stencil.name if mesh.uv_texture_stencil else "" - col.label("UV Map:") + stencil_text = mesh.uv_layer_stencil.name if mesh.uv_layer_stencil else "" + col.label("UV Map") col.menu("VIEW3D_MT_tools_projectpaint_stencil", text=stencil_text, translate=False) col.label("Stencil Image:") @@ -1332,6 +631,7 @@ class VIEW3D_PT_stencil_projectpaint(View3DPanel, Panel): class VIEW3D_PT_tools_brush_overlay(Panel, View3DPaintPanel): bl_category = "Options" + bl_context = ".paint_common" # dot on purpose (access from topbar) bl_label = "Overlay" @classmethod @@ -1398,6 +698,7 @@ class VIEW3D_PT_tools_brush_overlay(Panel, View3DPaintPanel): class VIEW3D_PT_tools_brush_texture(Panel, View3DPaintPanel): bl_category = "Tools" + bl_context = ".paint_common" # dot on purpose (access from topbar) bl_label = "Texture" bl_options = {'DEFAULT_CLOSED'} @@ -1422,7 +723,7 @@ class VIEW3D_PT_tools_brush_texture(Panel, View3DPaintPanel): class VIEW3D_PT_tools_mask_texture(Panel, View3DPaintPanel): bl_category = "Tools" - bl_context = "imagepaint" + bl_context = ".imagepaint" # dot on purpose (access from topbar) bl_label = "Texture Mask" bl_options = {'DEFAULT_CLOSED'} @@ -1445,6 +746,7 @@ class VIEW3D_PT_tools_mask_texture(Panel, View3DPaintPanel): class VIEW3D_PT_tools_brush_stroke(Panel, View3DPaintPanel): bl_category = "Tools" + bl_context = ".paint_common" # dot on purpose (access from topbar) bl_label = "Stroke" bl_options = {'DEFAULT_CLOSED'} @@ -1543,6 +845,7 @@ class VIEW3D_PT_tools_brush_stroke(Panel, View3DPaintPanel): class VIEW3D_PT_tools_brush_curve(Panel, View3DPaintPanel): bl_category = "Tools" + bl_context = ".paint_common" # dot on purpose (access from topbar) bl_label = "Curve" bl_options = {'DEFAULT_CLOSED'} @@ -1572,6 +875,7 @@ class VIEW3D_PT_tools_brush_curve(Panel, View3DPaintPanel): class VIEW3D_PT_sculpt_dyntopo(Panel, View3DPaintPanel): bl_category = "Tools" + bl_context = ".sculpt_mode" # dot on purpose (access from topbar) bl_label = "Dyntopo" bl_options = {'DEFAULT_CLOSED'} @@ -1622,6 +926,7 @@ class VIEW3D_PT_sculpt_dyntopo(Panel, View3DPaintPanel): class VIEW3D_PT_sculpt_options(Panel, View3DPaintPanel): bl_category = "Options" + bl_context = ".sculpt_mode" # dot on purpose (access from topbar) bl_label = "Options" bl_options = {'DEFAULT_CLOSED'} @@ -1655,6 +960,7 @@ class VIEW3D_PT_sculpt_options(Panel, View3DPaintPanel): class VIEW3D_PT_sculpt_symmetry(Panel, View3DPaintPanel): bl_category = "Tools" + bl_context = ".sculpt_mode" # dot on purpose (access from topbar) bl_label = "Symmetry/Lock" bl_options = {'DEFAULT_CLOSED'} @@ -1696,6 +1002,7 @@ class VIEW3D_PT_sculpt_symmetry(Panel, View3DPaintPanel): class VIEW3D_PT_tools_brush_appearance(Panel, View3DPaintPanel): bl_category = "Options" + bl_context = ".paint_common" # dot on purpose (access from topbar) bl_label = "Appearance" @classmethod @@ -1739,25 +1046,9 @@ class VIEW3D_PT_tools_brush_appearance(Panel, View3DPaintPanel): # ********** default tools for weight-paint **************** -class VIEW3D_PT_tools_weightpaint(View3DPanel, Panel): - bl_category = "Tools" - bl_context = "weightpaint" - bl_label = "Weight Tools" - - def draw(self, context): - layout = self.layout - VIEW3D_PT_tools_meshweight.draw_generic(layout) - - col = layout.column() - col.operator("paint.weight_gradient") - props = col.operator("object.data_transfer", text="Transfer Weights") - props.use_reverse_transfer = True - props.data_type = 'VGROUP_WEIGHTS' - - class VIEW3D_PT_tools_weightpaint_symmetry(Panel, View3DPaintPanel): bl_category = "Tools" - bl_context = "weightpaint" + bl_context = ".weightpaint" bl_options = {'DEFAULT_CLOSED'} bl_label = "Symmetry" @@ -1770,7 +1061,7 @@ class VIEW3D_PT_tools_weightpaint_symmetry(Panel, View3DPaintPanel): class VIEW3D_PT_tools_weightpaint_options(Panel, View3DPaintPanel): bl_category = "Options" - bl_context = "weightpaint" + bl_context = ".weightpaint" bl_label = "Options" def draw(self, context): @@ -1801,7 +1092,7 @@ class VIEW3D_PT_tools_weightpaint_options(Panel, View3DPaintPanel): class VIEW3D_PT_tools_vertexpaint(Panel, View3DPaintPanel): bl_category = "Options" - bl_context = "vertexpaint" + bl_context = ".vertexpaint" # dot on purpose (access from topbar) bl_label = "Options" def draw(self, context): @@ -1817,7 +1108,7 @@ class VIEW3D_PT_tools_vertexpaint(Panel, View3DPaintPanel): class VIEW3D_PT_tools_vertexpaint_symmetry(Panel, View3DPaintPanel): bl_category = "Tools" - bl_context = "vertexpaint" + bl_context = ".vertexpaint" # dot on purpose (access from topbar) bl_options = {'DEFAULT_CLOSED'} bl_label = "Symmetry" @@ -1833,7 +1124,7 @@ class VIEW3D_PT_tools_vertexpaint_symmetry(Panel, View3DPaintPanel): class VIEW3D_PT_tools_imagepaint_external(Panel, View3DPaintPanel): bl_category = "Tools" - bl_context = "imagepaint" + bl_context = ".imagepaint" # dot on purpose (access from topbar) bl_label = "External" bl_options = {'DEFAULT_CLOSED'} @@ -1855,7 +1146,7 @@ class VIEW3D_PT_tools_imagepaint_external(Panel, View3DPaintPanel): class VIEW3D_PT_tools_imagepaint_symmetry(Panel, View3DPaintPanel): bl_category = "Tools" - bl_context = "imagepaint" + bl_context = ".imagepaint" # dot on purpose (access from topbar) bl_label = "Symmetry" bl_options = {'DEFAULT_CLOSED'} @@ -1874,7 +1165,7 @@ class VIEW3D_PT_tools_imagepaint_symmetry(Panel, View3DPaintPanel): class VIEW3D_PT_tools_projectpaint(View3DPaintPanel, Panel): bl_category = "Options" - bl_context = "imagepaint" + bl_context = ".imagepaint" # dot on purpose (access from topbar) bl_label = "Project Paint" @classmethod @@ -1929,15 +1220,15 @@ class VIEW3D_MT_tools_projectpaint_stencil(Menu): def draw(self, context): layout = self.layout - for i, tex in enumerate(context.active_object.data.uv_textures): - props = layout.operator("wm.context_set_int", text=tex.name, translate=False) - props.data_path = "active_object.data.uv_texture_stencil_index" + for i, uv_layer in enumerate(context.active_object.data.uv_layers): + props = layout.operator("wm.context_set_int", text=uv_layer.name, translate=False) + props.data_path = "active_object.data.uv_layer_stencil_index" props.value = i class VIEW3D_PT_tools_particlemode(View3DPanel, Panel): """Default tools for particle mode""" - bl_context = "particlemode" + bl_context = ".particlemode" bl_label = "Options" bl_category = "Tools" @@ -2036,60 +1327,10 @@ class VIEW3D_PT_tools_grease_pencil_brushcurves(GreasePencilBrushCurvesPanel, Pa bl_space_type = 'VIEW_3D' -# Note: moved here so that it's always in last position in 'Tools' panels! -class VIEW3D_PT_tools_history(View3DPanel, Panel): - bl_category = "Tools" - # No bl_context, we are always available! - bl_label = "History" - bl_options = {'DEFAULT_CLOSED'} - - def draw(self, context): - layout = self.layout - obj = context.object - - col = layout.column(align=True) - row = col.row(align=True) - row.operator("ed.undo") - row.operator("ed.redo") - if obj is None or obj.mode != 'SCULPT': - # Sculpt mode does not generate an undo menu it seems... - col.operator("ed.undo_history") - - col = layout.column(align=True) - col.label(text="Repeat:") - col.operator("screen.repeat_last") - col.operator("screen.repeat_history", text="History...") - - classes = ( - VIEW3D_PT_tools_transform, - VIEW3D_PT_tools_object, - VIEW3D_PT_tools_add_object, - VIEW3D_PT_tools_relations, - VIEW3D_PT_tools_animation, - VIEW3D_PT_tools_rigid_body, - VIEW3D_PT_tools_transform_mesh, - VIEW3D_PT_tools_meshedit, - VIEW3D_PT_tools_meshweight, - VIEW3D_PT_tools_add_mesh_edit, - VIEW3D_PT_tools_shading, - VIEW3D_PT_tools_uvs, VIEW3D_PT_tools_meshedit_options, - VIEW3D_PT_tools_transform_curve, - VIEW3D_PT_tools_curveedit, - VIEW3D_PT_tools_add_curve_edit, VIEW3D_PT_tools_curveedit_options_stroke, - VIEW3D_PT_tools_transform_surface, - VIEW3D_PT_tools_surfaceedit, - VIEW3D_PT_tools_add_surface_edit, - VIEW3D_PT_tools_textedit, - VIEW3D_PT_tools_armatureedit, - VIEW3D_PT_tools_armatureedit_transform, VIEW3D_PT_tools_armatureedit_options, - VIEW3D_PT_tools_mballedit, - VIEW3D_PT_tools_add_mball_edit, - VIEW3D_PT_tools_latticeedit, - VIEW3D_PT_tools_posemode, VIEW3D_PT_tools_posemode_options, VIEW3D_PT_imapaint_tools_missing, VIEW3D_PT_tools_brush, @@ -2106,7 +1347,6 @@ classes = ( VIEW3D_PT_sculpt_options, VIEW3D_PT_sculpt_symmetry, VIEW3D_PT_tools_brush_appearance, - VIEW3D_PT_tools_weightpaint, VIEW3D_PT_tools_weightpaint_symmetry, VIEW3D_PT_tools_weightpaint_options, VIEW3D_PT_tools_vertexpaint, @@ -2122,7 +1362,6 @@ classes = ( VIEW3D_PT_tools_grease_pencil_sculpt, VIEW3D_PT_tools_grease_pencil_brush, VIEW3D_PT_tools_grease_pencil_brushcurves, - VIEW3D_PT_tools_history, ) if __name__ == "__main__": # only for live edit. diff --git a/release/scripts/startup/nodeitems_builtins.py b/release/scripts/startup/nodeitems_builtins.py index 60a8471ca3b..d60710db4aa 100644 --- a/release/scripts/startup/nodeitems_builtins.py +++ b/release/scripts/startup/nodeitems_builtins.py @@ -43,18 +43,10 @@ class CompositorNodeCategory(SortedNodeCategory): return (context.space_data.tree_type == 'CompositorNodeTree') -class ShaderNewNodeCategory(SortedNodeCategory): +class ShaderNodeCategory(SortedNodeCategory): @classmethod def poll(cls, context): - return (context.space_data.tree_type == 'ShaderNodeTree' and - context.scene.render.use_shading_nodes) - - -class ShaderOldNodeCategory(SortedNodeCategory): - @classmethod - def poll(cls, context): - return (context.space_data.tree_type == 'ShaderNodeTree' and - not context.scene.render.use_shading_nodes) + return (context.space_data.tree_type == 'ShaderNodeTree') class TextureNodeCategory(SortedNodeCategory): @@ -141,62 +133,39 @@ def object_shader_nodes_poll(context): snode.shader_type == 'OBJECT') +def cycles_shader_nodes_poll(context): + return context.engine == 'CYCLES' + + +def eevee_shader_nodes_poll(context): + return context.engine == 'BLENDER_EEVEE' + + +def eevee_cycles_shader_nodes_poll(context): + return (cycles_shader_nodes_poll(context) or + eevee_shader_nodes_poll(context)) + + +def object_cycles_shader_nodes_poll(context): + return (object_shader_nodes_poll(context) and + cycles_shader_nodes_poll(context)) + + +def object_eevee_shader_nodes_poll(context): + return (object_shader_nodes_poll(context) and + eevee_shader_nodes_poll(context)) + + +def object_eevee_cycles_shader_nodes_poll(context): + return (object_shader_nodes_poll(context) and + eevee_cycles_shader_nodes_poll(context)) + + # All standard node categories currently used in nodes. shader_node_categories = [ - # Shader Nodes - ShaderOldNodeCategory("SH_INPUT", "Input", items=[ - NodeItem("ShaderNodeMaterial"), - NodeItem("ShaderNodeCameraData"), - NodeItem("ShaderNodeFresnel"), - NodeItem("ShaderNodeLayerWeight"), - NodeItem("ShaderNodeLampData"), - NodeItem("ShaderNodeValue"), - NodeItem("ShaderNodeRGB"), - NodeItem("ShaderNodeTexture"), - NodeItem("ShaderNodeGeometry"), - NodeItem("ShaderNodeExtendedMaterial"), - NodeItem("ShaderNodeParticleInfo"), - NodeItem("ShaderNodeObjectInfo"), - NodeItem("NodeGroupInput", poll=group_input_output_item_poll), - ]), - ShaderOldNodeCategory("SH_OUTPUT", "Output", items=[ - NodeItem("ShaderNodeOutput"), - NodeItem("NodeGroupOutput", poll=group_input_output_item_poll), - ]), - ShaderOldNodeCategory("SH_OP_COLOR", "Color", items=[ - NodeItem("ShaderNodeMixRGB"), - NodeItem("ShaderNodeRGBCurve"), - NodeItem("ShaderNodeInvert"), - NodeItem("ShaderNodeHueSaturation"), - NodeItem("ShaderNodeGamma"), - ]), - ShaderOldNodeCategory("SH_OP_VECTOR", "Vector", items=[ - NodeItem("ShaderNodeNormal"), - NodeItem("ShaderNodeMapping"), - NodeItem("ShaderNodeVectorCurve"), - NodeItem("ShaderNodeVectorTransform"), - NodeItem("ShaderNodeNormalMap"), - ]), - ShaderOldNodeCategory("SH_CONVERTOR", "Converter", items=[ - NodeItem("ShaderNodeValToRGB"), - NodeItem("ShaderNodeRGBToBW"), - NodeItem("ShaderNodeMath"), - NodeItem("ShaderNodeVectorMath"), - NodeItem("ShaderNodeSqueeze"), - NodeItem("ShaderNodeSeparateRGB"), - NodeItem("ShaderNodeCombineRGB"), - NodeItem("ShaderNodeSeparateHSV"), - NodeItem("ShaderNodeCombineHSV"), - ]), - ShaderOldNodeCategory("SH_GROUP", "Group", items=node_group_items), - ShaderOldNodeCategory("SH_LAYOUT", "Layout", items=[ - NodeItem("NodeFrame"), - NodeItem("NodeReroute"), - ]), - - # New Shader Nodes (Cycles) - ShaderNewNodeCategory("SH_NEW_INPUT", "Input", items=[ + # Shader Nodes (Cycles and Eevee) + ShaderNodeCategory("SH_NEW_INPUT", "Input", items=[ NodeItem("ShaderNodeTexCoord"), NodeItem("ShaderNodeAttribute"), NodeItem("ShaderNodeLightPath"), @@ -216,37 +185,38 @@ shader_node_categories = [ NodeItem("ShaderNodeUVAlongStroke", poll=line_style_shader_nodes_poll), NodeItem("NodeGroupInput", poll=group_input_output_item_poll), ]), - ShaderNewNodeCategory("SH_NEW_OUTPUT", "Output", items=[ - NodeItem("ShaderNodeOutputMaterial", poll=object_shader_nodes_poll), - NodeItem("ShaderNodeOutputLamp", poll=object_shader_nodes_poll), + ShaderNodeCategory("SH_NEW_OUTPUT", "Output", items=[ + NodeItem("ShaderNodeOutputMaterial", poll=object_eevee_cycles_shader_nodes_poll), + NodeItem("ShaderNodeOutputLamp", poll=object_cycles_shader_nodes_poll), NodeItem("ShaderNodeOutputWorld", poll=world_shader_nodes_poll), NodeItem("ShaderNodeOutputLineStyle", poll=line_style_shader_nodes_poll), NodeItem("NodeGroupOutput", poll=group_input_output_item_poll), ]), - ShaderNewNodeCategory("SH_NEW_SHADER", "Shader", items=[ - NodeItem("ShaderNodeMixShader"), - NodeItem("ShaderNodeAddShader"), - NodeItem("ShaderNodeBsdfDiffuse", poll=object_shader_nodes_poll), - NodeItem("ShaderNodeBsdfPrincipled", poll=object_shader_nodes_poll), - NodeItem("ShaderNodeBsdfGlossy", poll=object_shader_nodes_poll), - NodeItem("ShaderNodeBsdfTransparent", poll=object_shader_nodes_poll), - NodeItem("ShaderNodeBsdfRefraction", poll=object_shader_nodes_poll), - NodeItem("ShaderNodeBsdfGlass", poll=object_shader_nodes_poll), - NodeItem("ShaderNodeBsdfTranslucent", poll=object_shader_nodes_poll), - NodeItem("ShaderNodeBsdfAnisotropic", poll=object_shader_nodes_poll), - NodeItem("ShaderNodeBsdfVelvet", poll=object_shader_nodes_poll), - NodeItem("ShaderNodeBsdfToon", poll=object_shader_nodes_poll), - NodeItem("ShaderNodeSubsurfaceScattering", poll=object_shader_nodes_poll), - NodeItem("ShaderNodeEmission", poll=object_shader_nodes_poll), - NodeItem("ShaderNodeBsdfHair", poll=object_shader_nodes_poll), + ShaderNodeCategory("SH_NEW_SHADER", "Shader", items=[ + NodeItem("ShaderNodeMixShader", poll=eevee_cycles_shader_nodes_poll), + NodeItem("ShaderNodeAddShader", poll=eevee_cycles_shader_nodes_poll), + NodeItem("ShaderNodeBsdfDiffuse", poll=object_eevee_cycles_shader_nodes_poll), + NodeItem("ShaderNodeBsdfPrincipled", poll=object_eevee_cycles_shader_nodes_poll), + NodeItem("ShaderNodeBsdfGlossy", poll=object_eevee_cycles_shader_nodes_poll), + NodeItem("ShaderNodeBsdfTransparent", poll=object_eevee_cycles_shader_nodes_poll), + NodeItem("ShaderNodeBsdfRefraction", poll=object_eevee_cycles_shader_nodes_poll), + NodeItem("ShaderNodeBsdfGlass", poll=object_eevee_cycles_shader_nodes_poll), + NodeItem("ShaderNodeBsdfTranslucent", poll=object_cycles_shader_nodes_poll), + NodeItem("ShaderNodeBsdfAnisotropic", poll=object_cycles_shader_nodes_poll), + NodeItem("ShaderNodeBsdfVelvet", poll=object_cycles_shader_nodes_poll), + NodeItem("ShaderNodeBsdfToon", poll=object_cycles_shader_nodes_poll), + NodeItem("ShaderNodeSubsurfaceScattering", poll=object_eevee_cycles_shader_nodes_poll), + NodeItem("ShaderNodeEmission", poll=object_eevee_cycles_shader_nodes_poll), + NodeItem("ShaderNodeBsdfHair", poll=object_cycles_shader_nodes_poll), NodeItem("ShaderNodeBackground", poll=world_shader_nodes_poll), - NodeItem("ShaderNodeAmbientOcclusion", poll=object_shader_nodes_poll), - NodeItem("ShaderNodeHoldout", poll=object_shader_nodes_poll), - NodeItem("ShaderNodeVolumeAbsorption"), - NodeItem("ShaderNodeVolumeScatter"), + NodeItem("ShaderNodeAmbientOcclusion", poll=object_eevee_cycles_shader_nodes_poll), + NodeItem("ShaderNodeHoldout", poll=object_cycles_shader_nodes_poll), + NodeItem("ShaderNodeVolumeAbsorption", poll=eevee_cycles_shader_nodes_poll), + NodeItem("ShaderNodeVolumeScatter", poll=eevee_cycles_shader_nodes_poll), NodeItem("ShaderNodeVolumePrincipled"), + NodeItem("ShaderNodeEeveeSpecular", poll=object_eevee_shader_nodes_poll), ]), - ShaderNewNodeCategory("SH_NEW_TEXTURE", "Texture", items=[ + ShaderNodeCategory("SH_NEW_TEXTURE", "Texture", items=[ NodeItem("ShaderNodeTexImage"), NodeItem("ShaderNodeTexEnvironment"), NodeItem("ShaderNodeTexSky"), @@ -261,7 +231,7 @@ shader_node_categories = [ NodeItem("ShaderNodeTexPointDensity"), NodeItem("ShaderNodeTexIES"), ]), - ShaderNewNodeCategory("SH_NEW_OP_COLOR", "Color", items=[ + ShaderNodeCategory("SH_NEW_OP_COLOR", "Color", items=[ NodeItem("ShaderNodeMixRGB"), NodeItem("ShaderNodeRGBCurve"), NodeItem("ShaderNodeInvert"), @@ -270,7 +240,7 @@ shader_node_categories = [ NodeItem("ShaderNodeGamma"), NodeItem("ShaderNodeBrightContrast"), ]), - ShaderNewNodeCategory("SH_NEW_OP_VECTOR", "Vector", items=[ + ShaderNodeCategory("SH_NEW_OP_VECTOR", "Vector", items=[ NodeItem("ShaderNodeMapping"), NodeItem("ShaderNodeBump"), NodeItem("ShaderNodeDisplacement"), @@ -280,10 +250,11 @@ shader_node_categories = [ NodeItem("ShaderNodeVectorCurve"), NodeItem("ShaderNodeVectorTransform"), ]), - ShaderNewNodeCategory("SH_NEW_CONVERTOR", "Converter", items=[ + ShaderNodeCategory("SH_NEW_CONVERTOR", "Converter", items=[ NodeItem("ShaderNodeMath"), NodeItem("ShaderNodeValToRGB"), NodeItem("ShaderNodeRGBToBW"), + NodeItem("ShaderNodeShaderToRGB", poll=object_eevee_shader_nodes_poll), NodeItem("ShaderNodeVectorMath"), NodeItem("ShaderNodeSeparateRGB"), NodeItem("ShaderNodeCombineRGB"), @@ -294,11 +265,11 @@ shader_node_categories = [ NodeItem("ShaderNodeWavelength"), NodeItem("ShaderNodeBlackbody"), ]), - ShaderNewNodeCategory("SH_NEW_SCRIPT", "Script", items=[ + ShaderNodeCategory("SH_NEW_SCRIPT", "Script", items=[ NodeItem("ShaderNodeScript"), ]), - ShaderNewNodeCategory("SH_NEW_GROUP", "Group", items=node_group_items), - ShaderNewNodeCategory("SH_NEW_LAYOUT", "Layout", items=[ + ShaderNodeCategory("SH_NEW_GROUP", "Group", items=node_group_items), + ShaderNodeCategory("SH_NEW_LAYOUT", "Layout", items=[ NodeItem("NodeFrame"), NodeItem("NodeReroute"), ]), |