diff options
Diffstat (limited to 'release/scripts')
70 files changed, 2923 insertions, 737 deletions
diff --git a/release/scripts/freestyle/modules/parameter_editor.py b/release/scripts/freestyle/modules/parameter_editor.py index b093920a4cb..7e8d87bb465 100644 --- a/release/scripts/freestyle/modules/parameter_editor.py +++ b/release/scripts/freestyle/modules/parameter_editor.py @@ -1538,7 +1538,7 @@ def process(layer_name, lineset_name): raise RuntimeError("No Thickness modifier with type", type(m), m) # -- Textures -- # has_tex = False - if scene.render.use_shading_nodes: + if scene.view_render.use_shading_nodes: if linestyle.use_nodes and linestyle.node_tree: shaders_list.append(BlenderTextureShader(linestyle.node_tree)) has_tex = True diff --git a/release/scripts/modules/bpy_extras/__init__.py b/release/scripts/modules/bpy_extras/__init__.py index c8d12070de8..cd176e77aed 100644 --- a/release/scripts/modules/bpy_extras/__init__.py +++ b/release/scripts/modules/bpy_extras/__init__.py @@ -29,5 +29,6 @@ __all__ = ( "image_utils", "keyconfig_utils", "mesh_utils", + "node_utils", "view3d_utils", ) diff --git a/release/scripts/modules/bpy_extras/node_utils.py b/release/scripts/modules/bpy_extras/node_utils.py new file mode 100644 index 00000000000..9a2be5b9f68 --- /dev/null +++ b/release/scripts/modules/bpy_extras/node_utils.py @@ -0,0 +1,50 @@ +# ##### 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-80 compliant> + +__all__ = ( + "find_node_input", + "find_output_node", + ) + + +# XXX Names are not unique. Returns the first match. +def find_node_input(node, name): + for input in node.inputs: + if input.name == name: + return input + + return None + +# Return the output node to display in the UI. In case multiple node types are +# specified, node types earlier in the list get priority. +def find_output_node(ntree, nodetypes): + if ntree: + output_node = None + for nodetype in nodetypes: + for node in ntree.nodes: + if getattr(node, "type", None) == nodetype: + if getattr(node, "is_active_output", True): + return node + if not output_node: + output_node = node + if output_node: + return output_node + + return None diff --git a/release/scripts/modules/bpy_extras/object_utils.py b/release/scripts/modules/bpy_extras/object_utils.py index c48f03c133d..8f2e69313fc 100644 --- a/release/scripts/modules/bpy_extras/object_utils.py +++ b/release/scripts/modules/bpy_extras/object_utils.py @@ -103,9 +103,9 @@ def add_object_align_init(context, operator): return location * rotation -def object_data_add(context, obdata, operator=None, use_active_layer=True, name=None): +def object_data_add(context, obdata, operator=None, name=None): """ - Add an object using the view context and preference to to initialize the + Add an object using the view context and preference to initialize the location, rotation and layer. :arg context: The context to use. @@ -117,53 +117,31 @@ def object_data_add(context, obdata, operator=None, use_active_layer=True, name= :arg name: Optional name :type name: string :return: the newly created object in the scene. - :rtype: :class:`bpy.types.ObjectBase` + :rtype: :class:`bpy.types.Object` """ scene = context.scene + layer = context.render_layer + layer_collection = context.layer_collection - # ugh, could be made nicer - for ob in scene.objects: - ob.select = False + for ob in layer.objects: + ob.select_set(action='DESELECT') + + if not layer_collection: + # when there is no collection linked to this render_layer create one + scene_collection = scene.master_collection.collections.new("") + layer_collection = layer.collections.link(scene_collection) + else: + scene_collection = layer_collection.collection if name is None: name = "Object" if obdata is None else obdata.name + obj_act = layer.objects.active obj_new = bpy.data.objects.new(name, obdata) - - base = scene.objects.link(obj_new) - base.select = True - - v3d = None - if context.space_data and context.space_data.type == 'VIEW_3D': - v3d = context.space_data - - if v3d and v3d.local_view: - base.layers_from_view(context.space_data) - - if operator is not None and any(operator.layers): - base.layers = operator.layers - else: - if use_active_layer: - if v3d and v3d.local_view: - base.layers[scene.active_layer] = True - else: - if v3d and not v3d.lock_camera_and_layers: - base.layers = [True if i == v3d.active_layer - else False for i in range(len(v3d.layers))] - else: - base.layers = [True if i == scene.active_layer - else False for i in range(len(scene.layers))] - else: - if v3d: - base.layers_from_view(context.space_data) - - if operator is not None: - operator.layers = base.layers - + scene_collection.objects.link(obj_new) + obj_new.select_set(action='SELECT') obj_new.matrix_world = add_object_align_init(context, operator) - obj_act = scene.objects.active - # XXX # caused because entering edit-mode does not add a empty undo slot! if context.user_preferences.edit.use_enter_edit_mode: @@ -174,8 +152,8 @@ def object_data_add(context, obdata, operator=None, use_active_layer=True, name= _obdata = bpy.data.meshes.new(name) obj_act = bpy.data.objects.new(_obdata.name, _obdata) obj_act.matrix_world = obj_new.matrix_world - scene.objects.link(obj_act) - scene.objects.active = obj_act + scene_collection.objects.link(obj_act) + layer.objects.active = obj_act bpy.ops.object.mode_set(mode='EDIT') # need empty undo step bpy.ops.ed.undo_push(message="Enter Editmode") @@ -183,9 +161,10 @@ def object_data_add(context, obdata, operator=None, use_active_layer=True, name= if obj_act and obj_act.mode == 'EDIT' and obj_act.type == obj_new.type: bpy.ops.mesh.select_all(action='DESELECT') + obj_act.select_set(action='SELECT') bpy.ops.object.mode_set(mode='OBJECT') - obj_act.select = True + obj_act.select_set(action='SELECT') scene.update() # apply location # scene.objects.active = obj_new @@ -200,16 +179,14 @@ def object_data_add(context, obdata, operator=None, use_active_layer=True, name= bpy.ops.object.join() # join into the active. if obdata: bpy.data.meshes.remove(obdata) - # base is freed, set to active object - base = scene.object_bases.active bpy.ops.object.mode_set(mode='EDIT') else: - scene.objects.active = obj_new + layer.objects.active = obj_new if context.user_preferences.edit.use_enter_edit_mode: bpy.ops.object.mode_set(mode='EDIT') - return base + return obj_new class AddObjectHelper: @@ -230,12 +207,6 @@ class AddObjectHelper: name="Rotation", subtype='EULER', ) - layers = BoolVectorProperty( - name="Layers", - size=20, - subtype='LAYER', - options={'HIDDEN', 'SKIP_SAVE'}, - ) @classmethod def poll(self, context): diff --git a/release/scripts/modules/bpy_types.py b/release/scripts/modules/bpy_types.py index 600b29a6b2b..78c70225a04 100644 --- a/release/scripts/modules/bpy_types.py +++ b/release/scripts/modules/bpy_types.py @@ -592,6 +592,102 @@ class OrderedMeta(RNAMeta): return OrderedDictMini() # collections.OrderedDict() +# Same as 'Operator' +# only without 'as_keywords' +class Manipulator(StructRNA, metaclass=OrderedMeta): + __slots__ = () + + def __getattribute__(self, attr): + properties = StructRNA.path_resolve(self, "properties") + bl_rna = getattr(properties, "bl_rna", None) + if (bl_rna is not None) and (attr in bl_rna.properties): + return getattr(properties, attr) + return super().__getattribute__(attr) + + def __setattr__(self, attr, value): + properties = StructRNA.path_resolve(self, "properties") + bl_rna = getattr(properties, "bl_rna", None) + if (bl_rna is not None) and (attr in bl_rna.properties): + return setattr(properties, attr, value) + return super().__setattr__(attr, value) + + def __delattr__(self, attr): + properties = StructRNA.path_resolve(self, "properties") + bl_rna = getattr(properties, "bl_rna", None) + if (bl_rna is not None) and (attr in bl_rna.properties): + return delattr(properties, attr) + return super().__delattr__(attr) + + from _bpy import ( + _rna_manipulator_target_set_handler as target_set_handler, + _rna_manipulator_target_get_value as target_get_value, + _rna_manipulator_target_set_value as target_set_value, + _rna_manipulator_target_get_range as target_get_range, + ) + + # Convenience wrappers around private `_gawain` module. + def draw_custom_shape(self, shape, *, matrix=None, select_id=None): + """ + Draw a shape created form :class:`bpy.types.Manipulator.draw_custom_shape`. + + :arg shape: The cached shape to draw. + :type shape: Undefined. + :arg matrix: 4x4 matrix, when not given + :class:`bpy.types.Manipulator.matrix_world` is used. + :type matrix: :class:`mathutils.Matrix` + :arg select_id: The selection id. + Only use when drawing within :class:`bpy.types.Manipulator.draw_select`. + :type select_it: int + """ + import gpu + + if matrix is None: + matrix = self.matrix_world + + if select_id is not None: + gpu.select.load_id(select_id) + else: + if self.is_highlight: + color = (*self.color_highlight, self.alpha_highlight) + else: + color = (*self.color, self.alpha) + shape.uniform_f32("color", *color) + + with gpu.matrix.push_pop(): + gpu.matrix.multiply_matrix(matrix) + shape.draw() + + @staticmethod + def new_custom_shape(type, verts): + """ + Create a new shape that can be passed to :class:`bpy.types.Manipulator.draw_custom_shape`. + + :arg type: The type of shape to create in (POINTS, LINES, TRIS, LINE_STRIP). + :type type: string + :arg verts: Coordinates. + :type verts: sequence of of 2D or 3D coordinates. + :arg display_name: Optional callback that takes the full path, returns the name to display. + :type display_name: Callable that takes a string and returns a string. + :return: The newly created shape. + :rtype: Undefined (it may change). + """ + from _gawain.types import ( + Gwn_Batch, + Gwn_VertBuf, + Gwn_VertFormat, + ) + dims = len(verts[0]) + if dims not in {2, 3}: + raise ValueError("Expected 2D or 3D vertex") + fmt = Gwn_VertFormat() + pos_id = fmt.attr_add(id="pos", comp_type='F32', len=dims, fetch_mode='FLOAT') + vbo = Gwn_VertBuf(len=len(verts), format=fmt) + vbo.fill(id=pos_id, data=verts) + batch = Gwn_Batch(type=type, buf=vbo) + batch.program_set_builtin('3D_UNIFORM_COLOR' if dims == 3 else '2D_UNIFORM_COLOR') + return batch + + # Only defined so operators members can be used by accessing self.order # with doc generation 'self.properties.bl_rna.properties' can fail class Operator(StructRNA, metaclass=OrderedMeta): diff --git a/release/scripts/modules/sys_info.py b/release/scripts/modules/sys_info.py index e447d8a4dc5..53b3197fca3 100644 --- a/release/scripts/modules/sys_info.py +++ b/release/scripts/modules/sys_info.py @@ -185,14 +185,19 @@ def write_sysinfo(filepath): output.write("version:\t%r\n" % (bgl.glGetString(bgl.GL_VERSION))) output.write("extensions:\n") - glext = sorted(bgl.glGetString(bgl.GL_EXTENSIONS).split()) + limit = bgl.Buffer(bgl.GL_INT, 1) + bgl.glGetIntegerv(bgl.GL_NUM_EXTENSIONS, limit) + + glext = [] + for i in range(limit[0]): + glext.append(bgl.glGetStringi(bgl.GL_EXTENSIONS, i)) + + glext = sorted(glext) + for l in glext: output.write("\t%s\n" % l) output.write(title("Implementation Dependent OpenGL Limits")) - limit = bgl.Buffer(bgl.GL_INT, 1) - bgl.glGetIntegerv(bgl.GL_MAX_TEXTURE_UNITS, limit) - output.write("Maximum Fixed Function Texture Units:\t%d\n" % limit[0]) bgl.glGetIntegerv(bgl.GL_MAX_ELEMENTS_VERTICES, limit) output.write("Maximum DrawElements Vertices:\t%d\n" % limit[0]) bgl.glGetIntegerv(bgl.GL_MAX_ELEMENTS_INDICES, limit) diff --git a/release/scripts/presets/keyconfig/3dsmax.py b/release/scripts/presets/keyconfig/3dsmax.py index 6d05ff6982c..09c6704df1f 100644 --- a/release/scripts/presets/keyconfig/3dsmax.py +++ b/release/scripts/presets/keyconfig/3dsmax.py @@ -7,7 +7,7 @@ kc = wm.keyconfigs.new('3dsmax') # Map Window km = kc.keymaps.new('Window', space_type='EMPTY', region_type='WINDOW', modal=False) -kmi = km.keymap_items.new('wm.window_duplicate', 'W', 'PRESS', ctrl=True, alt=True) +kmi = km.keymap_items.new('wm.window_new', 'W', 'PRESS', ctrl=True, alt=True) kmi = km.keymap_items.new('wm.read_homefile', 'N', 'PRESS', ctrl=True) kmi = km.keymap_items.new('wm.save_homefile', 'U', 'PRESS', ctrl=True) kmi = km.keymap_items.new('wm.call_menu', 'O', 'PRESS', shift=True, ctrl=True) @@ -330,7 +330,6 @@ kmi = km.keymap_items.new('object.hide_view_set', 'H', 'PRESS', shift=True) kmi.properties.unselected = True kmi = km.keymap_items.new('object.hide_render_clear', 'H', 'PRESS', ctrl=True, alt=True) kmi = km.keymap_items.new('object.hide_render_set', 'H', 'PRESS', ctrl=True) -kmi = km.keymap_items.new('object.move_to_layer', 'M', 'PRESS') kmi = km.keymap_items.new('object.delete', 'X', 'PRESS') kmi.properties.use_global = False kmi = km.keymap_items.new('object.delete', 'X', 'PRESS', shift=True) diff --git a/release/scripts/presets/keyconfig/maya.py b/release/scripts/presets/keyconfig/maya.py index 53129593a59..194b9b3c283 100644 --- a/release/scripts/presets/keyconfig/maya.py +++ b/release/scripts/presets/keyconfig/maya.py @@ -8,7 +8,7 @@ kc = wm.keyconfigs.new(os.path.splitext(os.path.basename(__file__))[0]) # Map Window km = kc.keymaps.new('Window', space_type='EMPTY', region_type='WINDOW', modal=False) -kmi = km.keymap_items.new('wm.window_duplicate', 'W', 'PRESS', ctrl=True, alt=True) +kmi = km.keymap_items.new('wm.window_new', 'W', 'PRESS', ctrl=True, alt=True) kmi = km.keymap_items.new('wm.read_homefile', 'N', 'PRESS', ctrl=True) kmi = km.keymap_items.new('wm.save_homefile', 'U', 'PRESS', ctrl=True) kmi = km.keymap_items.new('wm.call_menu', 'O', 'PRESS', shift=True, ctrl=True) @@ -384,7 +384,6 @@ kmi = km.keymap_items.new('object.hide_view_clear', 'H', 'PRESS', shift=True, ct kmi = km.keymap_items.new('object.hide_view_set', 'H', 'PRESS', ctrl=True) kmi = km.keymap_items.new('object.hide_view_set', 'H', 'PRESS', alt=True) kmi.properties.unselected = True -kmi = km.keymap_items.new('object.move_to_layer', 'M', 'PRESS') kmi = km.keymap_items.new('object.delete', 'BACK_SPACE', 'PRESS') kmi = km.keymap_items.new('object.delete', 'DEL', 'PRESS') kmi = km.keymap_items.new('wm.call_menu', 'A', 'PRESS', shift=True) diff --git a/release/scripts/presets/operator/wm.collada_export/sl_plus_open_sim_rigged.py b/release/scripts/presets/operator/wm.collada_export/sl_plus_open_sim_rigged.py index deb23d76d91..7825a4d0f32 100644 --- a/release/scripts/presets/operator/wm.collada_export/sl_plus_open_sim_rigged.py +++ b/release/scripts/presets/operator/wm.collada_export/sl_plus_open_sim_rigged.py @@ -10,7 +10,7 @@ op.include_armatures = True op.include_shapekeys = False op.deform_bones_only = True op.active_uv_only = True -op.export_texture_type_selection = 'uv' +op.include_uv_textures = True op.use_texture_copies = True op.triangulate = True op.use_object_instantiation = False diff --git a/release/scripts/presets/operator/wm.collada_export/sl_plus_open_sim_static.py b/release/scripts/presets/operator/wm.collada_export/sl_plus_open_sim_static.py index ca9de8bf005..a13ba5c4ccc 100644 --- a/release/scripts/presets/operator/wm.collada_export/sl_plus_open_sim_static.py +++ b/release/scripts/presets/operator/wm.collada_export/sl_plus_open_sim_static.py @@ -10,7 +10,6 @@ op.include_armatures = False op.include_shapekeys = False op.deform_bones_only = False op.active_uv_only = True -op.export_texture_type_selection = 'uv' op.use_texture_copies = True op.triangulate = True op.use_object_instantiation = False diff --git a/release/scripts/startup/bl_operators/add_mesh_torus.py b/release/scripts/startup/bl_operators/add_mesh_torus.py index 0e5acea94f9..c7152c8a22f 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 @@ -286,4 +286,4 @@ class AddTorus(Operator, object_utils.AddObjectHelper): classes = ( AddTorus, -)
\ No newline at end of file +) diff --git a/release/scripts/startup/bl_operators/clip.py b/release/scripts/startup/bl_operators/clip.py index 6356121cffd..d648ec83b7c 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 @@ -514,7 +514,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'} diff --git a/release/scripts/startup/bl_operators/freestyle.py b/release/scripts/startup/bl_operators/freestyle.py index 2e46160aeeb..4cee1abf15f 100644 --- a/release/scripts/startup/bl_operators/freestyle.py +++ b/release/scripts/startup/bl_operators/freestyle.py @@ -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 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..566487d9d0e 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'} @@ -136,7 +138,7 @@ class SelectCamera(Operator): bpy.ops.object.select_all(action='DESELECT') scene.objects.active = camera camera.hide = False - camera.select = True + camera.select_set(action='SELECT') return {'FINISHED'} return {'CANCELLED'} @@ -202,7 +204,7 @@ 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 return {'FINISHED'} @@ -513,7 +515,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 +553,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 +646,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 +666,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: @@ -1029,8 +1031,8 @@ class LodGenerate(Operator): for level in ob.lod_levels[1:]: level.object.hide = level.object.hide_render = True - lod.select = False - ob.select = True + lod.select_set(action='DESELECT') + ob.select_set(action='SELECT') scene.objects.active = ob return {'FINISHED'} diff --git a/release/scripts/startup/bl_operators/object_quick_effects.py b/release/scripts/startup/bl_operators/object_quick_effects.py index 16f29c77bb9..39191a896c9 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") 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 cc590ac9502..411c318643b 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_ui/__init__.py b/release/scripts/startup/bl_ui/__init__.py index 5b609605cee..a12fd6352ea 100644 --- a/release/scripts/startup/bl_ui/__init__.py +++ b/release/scripts/startup/bl_ui/__init__.py @@ -28,6 +28,7 @@ if "bpy" in locals(): _modules = [ "properties_animviz", + "properties_collection", "properties_constraint", "properties_data_armature", "properties_data_bone", @@ -39,7 +40,9 @@ _modules = [ "properties_data_mesh", "properties_data_metaball", "properties_data_modifier", + "properties_data_lightprobe", "properties_data_speaker", + "properties_data_workspace", "properties_game", "properties_mask_common", "properties_material", @@ -61,6 +64,12 @@ _modules = [ "properties_scene", "properties_texture", "properties_world", + + # Generic Space Modules + # + # Depends on DNA_WORKSPACE_TOOL (C define). + "space_toolsystem_toolbar", + "space_clip", "space_console", "space_dopesheet", diff --git a/release/scripts/startup/bl_ui/properties_collection.py b/release/scripts/startup/bl_ui/properties_collection.py new file mode 100644 index 00000000000..dab9def37f4 --- /dev/null +++ b/release/scripts/startup/bl_ui/properties_collection.py @@ -0,0 +1,166 @@ +# ##### 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 CollectionButtonsPanel: + bl_space_type = 'PROPERTIES' + bl_region_type = 'WINDOW' + bl_context = "collection" + + +class COLLECTION_PT_context_collection(CollectionButtonsPanel, Panel): + bl_label = "" + bl_options = {'HIDE_HEADER'} + + def draw(self, context): + layout = self.layout + space = context.space_data + + collection = context.layer_collection + name = collection.name + if name == 'Master Collection': + layout.label(text=name, icon='COLLAPSEMENU') + else: + layout.prop(collection, "name", text="", icon='COLLAPSEMENU') + + +class COLLECTION_PT_clay_settings(CollectionButtonsPanel, Panel): + bl_label = "Render Settings" + COMPAT_ENGINES = {'BLENDER_CLAY'} + + @classmethod + def poll(cls, context): + return context.view_render.engine in cls.COMPAT_ENGINES + + def draw(self, context): + layout = self.layout + scene_props = context.scene.collection_properties['BLENDER_CLAY'] + collection = context.layer_collection + collection_props = collection.engine_overrides['BLENDER_CLAY'] + + col = layout.column() + col.template_override_property(collection_props, scene_props, "matcap_icon", custom_template="icon_view") + col.template_override_property(collection_props, scene_props, "matcap_rotation") + col.template_override_property(collection_props, scene_props, "matcap_hue") + col.template_override_property(collection_props, scene_props, "matcap_saturation") + col.template_override_property(collection_props, scene_props, "matcap_value") + col.template_override_property(collection_props, scene_props, "ssao_factor_cavity") + col.template_override_property(collection_props, scene_props, "ssao_factor_edge") + col.template_override_property(collection_props, scene_props, "ssao_distance") + col.template_override_property(collection_props, scene_props, "ssao_attenuation") + col.template_override_property(collection_props, scene_props, "hair_brightness_randomness") + + +class COLLECTION_PT_object_mode_settings(CollectionButtonsPanel, Panel): + bl_label = "Object Mode Settings" + + @classmethod + def poll(cls, context): + workspace = context.workspace + return workspace and hasattr(workspace, 'object_mode') and (workspace.object_mode == 'OBJECT') + + def draw(self, context): + layout = self.layout + scene_props = context.scene.collection_properties['ObjectMode'] + collection = context.layer_collection + collection_props = collection.engine_overrides['ObjectMode'] + + col = layout.column() + col.template_override_property(collection_props, scene_props, "show_wire") + col.template_override_property(collection_props, scene_props, "show_backface_culling") + + +class COLLECTION_PT_edit_mode_settings(CollectionButtonsPanel, Panel): + bl_label = "Edit Mode Settings" + + @classmethod + def poll(cls, context): + workspace = context.workspace + return workspace and hasattr(workspace, 'object_mode') and (workspace.object_mode == 'EDIT') + + def draw(self, context): + layout = self.layout + scene_props = context.scene.collection_properties['EditMode'] + collection = context.layer_collection + collection_props = collection.engine_overrides['EditMode'] + + col = layout.column() + col.template_override_property(collection_props, scene_props, "show_occlude_wire") + col.template_override_property(collection_props, scene_props, "backwire_opacity") + col.template_override_property(collection_props, scene_props, "face_normals_show") + col.template_override_property(collection_props, scene_props, "vert_normals_show") + col.template_override_property(collection_props, scene_props, "loop_normals_show") + col.template_override_property(collection_props, scene_props, "normals_length") + col.template_override_property(collection_props, scene_props, "show_weight") + + +class COLLECTION_PT_paint_weight_mode_settings(CollectionButtonsPanel, Panel): + bl_label = "Weight Paint Mode Settings" + + @classmethod + def poll(cls, context): + workspace = context.workspace + return workspace and hasattr(workspace, 'object_mode') and (workspace.object_mode == 'WEIGHT_PAINT') + + def draw(self, context): + layout = self.layout + scene_props = context.scene.collection_properties['WeightPaintMode'] + collection = context.layer_collection + collection_props = collection.engine_overrides['WeightPaintMode'] + + col = layout.column() + col.template_override_property(collection_props, scene_props, "use_shading") + col.template_override_property(collection_props, scene_props, "use_wire") + + +class COLLECTION_PT_paint_vertex_mode_settings(CollectionButtonsPanel, Panel): + bl_label = "Vertex Paint Mode Settings" + + @classmethod + def poll(cls, context): + workspace = context.workspace + return workspace and hasattr(workspace, 'object_mode') and (workspace.object_mode == 'VERTEX_PAINT') + + def draw(self, context): + layout = self.layout + scene_props = context.scene.collection_properties['VertexPaintMode'] + collection = context.layer_collection + collection_props = collection.engine_overrides['VertexPaintMode'] + + col = layout.column() + col.template_override_property(collection_props, scene_props, "use_shading") + col.template_override_property(collection_props, scene_props, "use_wire") + + +classes = ( + COLLECTION_PT_context_collection, + COLLECTION_PT_clay_settings, + COLLECTION_PT_object_mode_settings, + COLLECTION_PT_edit_mode_settings, + COLLECTION_PT_paint_weight_mode_settings, + COLLECTION_PT_paint_vertex_mode_settings, +) + +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_armature.py b/release/scripts/startup/bl_ui/properties_data_armature.py index 411d64e2b94..413636d005b 100644 --- a/release/scripts/startup/bl_ui/properties_data_armature.py +++ b/release/scripts/startup/bl_ui/properties_data_armature.py @@ -65,7 +65,7 @@ class DATA_PT_skeleton(ArmatureButtonsPanel, Panel): col.label(text="Protected Layers:") col.prop(arm, "layers_protected", text="") - if context.scene.render.engine == 'BLENDER_GAME': + if context.engine == 'BLENDER_GAME': col = layout.column() col.label(text="Deform:") col.prop(arm, "deform_method", expand=True) @@ -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_GAME', '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 5e0ef5058dd..e0e46e4a266 100644 --- a/release/scripts/startup/bl_ui/properties_data_bone.py +++ b/release/scripts/startup/bl_ui/properties_data_bone.py @@ -433,7 +433,7 @@ class BONE_PT_deform(BoneButtonsPanel, Panel): class BONE_PT_custom_props(BoneButtonsPanel, PropertyPanel, Panel): - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME', 'BLENDER_CLAY', 'BLENDER_EEVEE'} _property_type = bpy.types.Bone, bpy.types.EditBone, bpy.types.PoseBone @property diff --git a/release/scripts/startup/bl_ui/properties_data_camera.py b/release/scripts/startup/bl_ui/properties_data_camera.py index 14286045704..0d0fc96550d 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_GAME', '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_GAME', '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_GAME', 'BLENDER_CLAY', 'BLENDER_EEVEE'} def draw(self, context): layout = self.layout @@ -72,7 +72,7 @@ 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_GAME', 'BLENDER_CLAY', 'BLENDER_EEVEE'} def draw(self, context): layout = self.layout @@ -96,7 +96,7 @@ class DATA_PT_lens(CameraButtonsPanel, Panel): 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") @@ -114,7 +114,7 @@ class DATA_PT_lens(CameraButtonsPanel, Panel): sub = row.column(align=True) sub.prop(ccam, "longitude_min") sub.prop(ccam, "longitude_max") - elif engine == 'BLENDER_RENDER': + elif engine in {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'}: row = col.row() if cam.lens_unit == 'MILLIMETERS': row.prop(cam, "lens") @@ -137,7 +137,7 @@ class DATA_PT_lens(CameraButtonsPanel, Panel): 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,11 +147,11 @@ class DATA_PT_camera_stereoscopy(CameraButtonsPanel, Panel): def draw(self, context): layout = self.layout - render = context.scene.render + view_render = context.scene.view_render st = context.camera.stereo cam = context.camera - is_spherical_stereo = cam.type != 'ORTHO' and render.use_spherical_stereo + is_spherical_stereo = cam.type != 'ORTHO' and view_render.use_spherical_stereo use_spherical_stereo = is_spherical_stereo and st.use_spherical_stereo col = layout.column() @@ -183,7 +183,7 @@ class DATA_PT_camera_stereoscopy(CameraButtonsPanel, Panel): class DATA_PT_camera(CameraButtonsPanel, Panel): bl_label = "Camera" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME', 'BLENDER_CLAY', 'BLENDER_EEVEE'} def draw(self, context): layout = self.layout @@ -217,7 +217,7 @@ class DATA_PT_camera(CameraButtonsPanel, Panel): class DATA_PT_camera_dof(CameraButtonsPanel, Panel): bl_label = "Depth of Field" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME', 'BLENDER_CLAY', 'BLENDER_EEVEE'} def draw(self, context): layout = self.layout @@ -234,20 +234,131 @@ class DATA_PT_camera_dof(CameraButtonsPanel, Panel): sub.active = (cam.dof_object is None) sub.prop(cam, "dof_distance", text="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.prop(dof_options, "blades") + if context.engine == 'BLENDER_EEVEE': + col = split.column(align=True) + col.label("Aperture:") + engine = context.engine + sub = col.column(align=True) + sub.prop(dof_options, "fstop") + sub.prop(dof_options, "blades") + sub.prop(dof_options, "rotation") + sub.prop(dof_options, "ratio") + else: + hq_support = dof_options.is_hq_supported + col = split.column(align=True) + col.label("Viewport:") + sub = col.column() + sub.active = hq_support + sub.prop(dof_options, "use_high_quality") + col.prop(dof_options, "fstop") + if dof_options.use_high_quality and hq_support: + col.prop(dof_options, "blades") + + +class DATA_PT_camera_background_image(CameraButtonsPanel, Panel): + bl_label = "Background Images" + bl_options = {'DEFAULT_CLOSED'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME', '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'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME', 'BLENDER_CLAY', 'BLENDER_EEVEE'} def draw(self, context): layout = self.layout @@ -277,7 +388,7 @@ class DATA_PT_camera_display(CameraButtonsPanel, Panel): 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_GAME', 'BLENDER_CLAY', 'BLENDER_EEVEE'} def draw_header(self, context): cam = context.camera @@ -293,7 +404,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_GAME', 'BLENDER_CLAY', 'BLENDER_EEVEE'} _context_path = "object.data" _property_type = bpy.types.Camera @@ -334,6 +445,7 @@ classes = ( DATA_PT_camera_stereoscopy, DATA_PT_camera_dof, DATA_PT_camera_display, + DATA_PT_camera_background_image, DATA_PT_camera_safe_areas, 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..6fb147007e6 100644 --- a/release/scripts/startup/bl_ui/properties_data_curve.py +++ b/release/scripts/startup/bl_ui/properties_data_curve.py @@ -136,7 +136,7 @@ class DATA_PT_shape_curve(CurveButtonsPanel, Panel): 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_GAME', 'BLENDER_CLAY', 'BLENDER_EEVEE'} def draw(self, context): layout = self.layout @@ -427,7 +427,7 @@ class DATA_PT_text_boxes(CurveButtonsPanelText, Panel): class DATA_PT_custom_props_curve(CurveButtonsPanel, PropertyPanel, Panel): - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME', 'BLENDER_CLAY', 'BLENDER_EEVEE'} _context_path = "object.data" _property_type = bpy.types.Curve diff --git a/release/scripts/startup/bl_ui/properties_data_lamp.py b/release/scripts/startup/bl_ui/properties_data_lamp.py index f9394139b42..9ee17d808cf 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_GAME', '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_GAME', 'BLENDER_CLAY', 'BLENDER_EEVEE'} def draw(self, context): layout = self.layout @@ -68,7 +68,7 @@ class DATA_PT_context_lamp(DataButtonsPanel, Panel): class DATA_PT_preview(DataButtonsPanel, Panel): bl_label = "Preview" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME', 'BLENDER_CLAY', 'BLENDER_EEVEE'} def draw(self, context): self.layout.template_preview(context.lamp) @@ -76,7 +76,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_GAME', 'BLENDER_CLAY'} def draw(self, context): layout = self.layout @@ -96,6 +96,7 @@ class DATA_PT_lamp(DataButtonsPanel, Panel): sub.label(text="Falloff:") sub.prop(lamp, "falloff_type", text="") sub.prop(lamp, "distance") + sub.prop(lamp, "shadow_soft_size", text="Radius") if lamp.falloff_type == 'LINEAR_QUADRATIC_WEIGHTED': col.label(text="Attenuation Factors:") @@ -123,6 +124,47 @@ class DATA_PT_lamp(DataButtonsPanel, Panel): col.prop(lamp, "use_diffuse") +class DATA_PT_EEVEE_lamp(DataButtonsPanel, Panel): + bl_label = "Lamp" + COMPAT_ENGINES = {'BLENDER_EEVEE'} + + def draw(self, context): + layout = self.layout + + lamp = context.lamp + + layout.row().prop(lamp, "type", expand=True) + + split = layout.split() + + col = split.column() + sub = col.column() + sub.prop(lamp, "color", text="") + sub.prop(lamp, "energy") + + if lamp.type in {'POINT', 'SPOT', 'SUN'}: + sub.prop(lamp, "shadow_soft_size", text="Radius") + elif lamp.type == 'AREA': + sub = sub.column(align=True) + sub.prop(lamp, "shape", text="") + if lamp.shape == 'SQUARE': + sub.prop(lamp, "size") + elif lamp.shape == 'RECTANGLE': + sub.prop(lamp, "size", text="Size X") + sub.prop(lamp, "size_y", text="Size Y") + + col = split.column() + col.prop(lamp, "use_specular") + col.prop(lamp, "use_diffuse") + col.separator() + + if lamp.type in {'POINT', 'SPOT', 'AREA'}: + col.prop(lamp, "use_sphere") + col = col.column() + col.active = lamp.use_sphere + col.prop(lamp, "distance") + + class DATA_PT_sunsky(DataButtonsPanel, Panel): bl_label = "Sky & Atmosphere" COMPAT_ENGINES = {'BLENDER_RENDER'} @@ -130,7 +172,7 @@ class DATA_PT_sunsky(DataButtonsPanel, Panel): @classmethod def poll(cls, context): lamp = context.lamp - engine = context.scene.render.engine + engine = context.engine return (lamp and lamp.type == 'SUN') and (engine in cls.COMPAT_ENGINES) def draw(self, context): @@ -202,7 +244,7 @@ class DATA_PT_shadow(DataButtonsPanel, Panel): @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(self, context): @@ -307,17 +349,80 @@ class DATA_PT_shadow(DataButtonsPanel, Panel): 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") + sub.prop(lamp, "shadow_buffer_clip_end", text="Clip End") + + +class DATA_PT_EEVEE_shadow(DataButtonsPanel, Panel): + bl_label = "Shadow" + COMPAT_ENGINES = {'BLENDER_EEVEE'} + + @classmethod + def poll(cls, context): + lamp = context.lamp + 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 + + lamp = context.lamp + + split = layout.split() + split.active = lamp.use_shadow + + sub = split.column() + col = sub.column(align=True) + col.prop(lamp, "shadow_buffer_clip_start", text="Clip Start") + col.prop(lamp, "shadow_buffer_clip_end", text="Clip End") + col = sub.column() + col.prop(lamp, "shadow_buffer_soft", text="Soft") + + col = split.column(align=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.type == 'SUN': + col = layout.column() + col.active = lamp.use_shadow + col.label("Cascaded Shadow Map:") + + split = col.split() + + sub = split.column() + sub.prop(lamp, "shadow_cascade_count", text="Count") + sub.prop(lamp, "shadow_cascade_fade", text="Fade") + + sub = split.column() + sub.prop(lamp, "shadow_cascade_max_distance", text="Max Distance") + sub.prop(lamp, "shadow_cascade_exponent", text="Distribution") + + layout.separator() + + layout.prop(lamp, "use_contact_shadow") + split = layout.split() + split.active = lamp.use_contact_shadow + col = split.column() + col.prop(lamp, "contact_shadow_distance", text="Distance") + col.prop(lamp, "contact_shadow_soft_size", text="Soft") + + col = split.column() + 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_GAME', '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): @@ -338,12 +443,12 @@ class DATA_PT_area(DataButtonsPanel, Panel): class DATA_PT_spot(DataButtonsPanel, Panel): bl_label = "Spot Shape" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME', '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 +476,40 @@ 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 + + lamp = context.lamp + + split = layout.split() + + col = split.column() + sub = col.column() + sub.prop(lamp, "spot_size", text="Size") + sub.prop(lamp, "spot_blend", text="Blend", slider=True) + col = split.column() + 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_GAME', '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 +520,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_GAME', 'BLENDER_CLAY', 'BLENDER_EEVEE'} _context_path = "object.data" _property_type = bpy.types.Lamp @@ -400,8 +530,10 @@ classes = ( DATA_PT_context_lamp, DATA_PT_preview, DATA_PT_lamp, + DATA_PT_EEVEE_lamp, DATA_PT_sunsky, DATA_PT_shadow, + 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..34cb323a8cb 100644 --- a/release/scripts/startup/bl_ui/properties_data_lattice.py +++ b/release/scripts/startup/bl_ui/properties_data_lattice.py @@ -78,7 +78,7 @@ class DATA_PT_lattice(DataButtonsPanel, Panel): class DATA_PT_custom_props_lattice(DataButtonsPanel, PropertyPanel, Panel): - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME', '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..b1deacb3051 --- /dev/null +++ b/release/scripts/startup/bl_ui/properties_data_lightprobe.py @@ -0,0 +1,176 @@ +# ##### 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 + + ob = context.object + probe = context.lightprobe + + split = layout.split() + + if probe.type == 'GRID': + col = split.column(align=True) + col.label("Resolution:") + col.prop(probe, "grid_resolution_x", text="X") + col.prop(probe, "grid_resolution_y", text="Y") + col.prop(probe, "grid_resolution_z", text="Z") + + col.separator() + + col.label("Influence:") + col.prop(probe, "influence_distance", "Distance") + col.prop(probe, "falloff") + + elif probe.type == 'PLANAR': + col = split.column(align=True) + col.label("Influence:") + col.prop(probe, "influence_distance", "Distance") + col.prop(probe, "falloff") + + else: + col = split.column(align=True) + col.label("Influence:") + col.prop(probe, "influence_type", text="") + + if probe.influence_type == 'ELIPSOID': + col.prop(probe, "influence_distance", "Radius") + else: + col.prop(probe, "influence_distance", "Size") + + col.prop(probe, "falloff") + + col = split.column(align=True) + col.label("Clipping:") + col.prop(probe, "clip_start", text="Start") + + if probe.type != "PLANAR": + col.prop(probe, "clip_end", text="End") + + +class DATA_PT_lightprobe_parallax(DataButtonsPanel, Panel): + bl_label = "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(self, context): + layout = self.layout + + ob = context.object + probe = context.lightprobe + + layout.prop(probe, "use_custom_parallax") + + col = layout.column() + col.active = probe.use_custom_parallax + + row = col.row() + row.prop(probe, "parallax_type", expand=True) + + 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 + + ob = context.object + probe = context.lightprobe + + row = layout.row() + row.prop(probe, "show_data") + + if probe.type != "PLANAR": + row.prop(probe, "data_draw_size", text="Size") + else: + row.prop(ob, "empty_draw_size", text="Arrow Size") + + split = layout.split() + + if probe.type in {'GRID', 'CUBEMAP'}: + col = split.column() + col.prop(probe, "show_influence") + + col = split.column() + col.prop(probe, "show_clip") + + if probe.type == 'CUBEMAP': + col = split.column() + col.active = probe.use_custom_parallax + col.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 de55b4152ba..d98e3f00e7d 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_GAME', '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_GAME', '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_GAME', 'BLENDER_CLAY', 'BLENDER_EEVEE'} def draw(self, context): layout = self.layout @@ -143,7 +154,7 @@ 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_GAME', 'BLENDER_CLAY', 'BLENDER_EEVEE'} def draw(self, context): layout = self.layout @@ -164,7 +175,7 @@ class DATA_PT_normals(MeshButtonsPanel, Panel): 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_GAME', 'BLENDER_CLAY', 'BLENDER_EEVEE'} def draw(self, context): layout = self.layout @@ -183,11 +194,11 @@ class DATA_PT_texture_space(MeshButtonsPanel, Panel): class DATA_PT_vertex_groups(MeshButtonsPanel, Panel): bl_label = "Vertex Groups" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME', '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)) @@ -227,13 +238,54 @@ 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_GAME'} + + @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_GAME', '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)) @@ -322,7 +374,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_GAME', 'BLENDER_CLAY', 'BLENDER_EEVEE'} def draw(self, context): layout = self.layout @@ -332,7 +384,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="") @@ -341,7 +393,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_GAME', 'BLENDER_CLAY', 'BLENDER_EEVEE'} def draw(self, context): layout = self.layout @@ -361,7 +413,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_GAME', 'BLENDER_CLAY', 'BLENDER_EEVEE'} def draw(self, context): layout = self.layout @@ -387,7 +439,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_GAME', 'BLENDER_CLAY', 'BLENDER_EEVEE'} _context_path = "object.data" _property_type = bpy.types.Mesh @@ -396,12 +448,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..e771caf49e3 100644 --- a/release/scripts/startup/bl_ui/properties_data_metaball.py +++ b/release/scripts/startup/bl_ui/properties_data_metaball.py @@ -76,7 +76,7 @@ class DATA_PT_metaball(DataButtonsPanel, Panel): 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_GAME', 'BLENDER_CLAY', 'BLENDER_EEVEE'} def draw(self, context): layout = self.layout @@ -131,7 +131,7 @@ class DATA_PT_metaball_element(DataButtonsPanel, Panel): class DATA_PT_custom_props_metaball(DataButtonsPanel, PropertyPanel, Panel): - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME', '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 8f6e5f2df39..d886b2f20bc 100644 --- a/release/scripts/startup/bl_ui/properties_data_modifier.py +++ b/release/scripts/startup/bl_ui/properties_data_modifier.py @@ -360,7 +360,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() @@ -392,7 +392,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") @@ -929,7 +929,7 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel): col = split.column() scene = bpy.context.scene - engine = scene.render.engine + engine = scene.view_render.engine show_adaptive_options = ( engine == 'CYCLES' and md == ob.modifiers[-1] and scene.cycles.feature_set == 'EXPERIMENTAL' @@ -999,11 +999,10 @@ 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="") 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="") @@ -1057,7 +1056,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() @@ -1103,7 +1102,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") @@ -1170,7 +1169,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() @@ -1339,7 +1338,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..769efb96b38 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_GAME', 'BLENDER_CLAY', 'BLENDER_EEVEE'} def draw(self, context): layout = self.layout @@ -55,7 +55,7 @@ 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 @@ -74,7 +74,7 @@ class DATA_PT_speaker(DataButtonsPanel, Panel): 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 @@ -97,7 +97,7 @@ class DATA_PT_distance(DataButtonsPanel, Panel): 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 @@ -117,7 +117,7 @@ class DATA_PT_cone(DataButtonsPanel, Panel): class DATA_PT_custom_props_speaker(DataButtonsPanel, PropertyPanel, Panel): - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME', '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..42a5406d1c8 --- /dev/null +++ b/release/scripts/startup/bl_ui/properties_data_workspace.py @@ -0,0 +1,78 @@ +# ##### 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_context(WorkSpaceButtonsPanel, Panel): + bl_label = "" + bl_options = {'HIDE_HEADER'} + + def draw(self, context): + layout = self.layout + + workspace = context.workspace + layout.prop(workspace, "use_scene_settings", icon='SCENE') + + +class WORKSPACE_PT_workspace(WorkSpaceButtonsPanel, Panel): + bl_label = "Workspace" + + def draw(self, context): + layout = self.layout + + workspace = context.workspace + scene = context.scene + view_render = workspace.view_render + + layout.enabled = not workspace.use_scene_settings + + layout.template_search(workspace, "render_layer", scene, "render_layers") + + if view_render.has_multiple_engines: + layout.prop(view_render, "engine", text="") + + +class WORKSPACE_PT_custom_props(WorkSpaceButtonsPanel, PropertyPanel, Panel): + _context_path = "workspace" + _property_type = bpy.types.WorkSpace + + +classes = ( + WORKSPACE_PT_context, + WORKSPACE_PT_workspace, + 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..ddc5c1643d0 100644 --- a/release/scripts/startup/bl_ui/properties_freestyle.py +++ b/release/scripts/startup/bl_ui/properties_freestyle.py @@ -33,7 +33,7 @@ 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(scene.view_render.engine in cls.COMPAT_ENGINES) class RENDER_PT_freestyle(RenderFreestyleButtonsPanel, Panel): @@ -75,7 +75,7 @@ class RenderLayerFreestyleButtonsPanel: 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)) + rd.layers.active and(scene.view_render.engine in cls.COMPAT_ENGINES)) class RenderLayerFreestyleEditorButtonsPanel(RenderLayerFreestyleButtonsPanel): @@ -183,7 +183,10 @@ class RENDERLAYER_PT_freestyle_lineset(RenderLayerFreestyleEditorButtonsPanel, P def draw(self, context): layout = self.layout - rd = context.scene.render + scene = context.scene + rd = scene.render + view_render = scene.view_render + rl = rd.layers.active freestyle = rl.freestyle_settings lineset = freestyle.linesets.active @@ -779,7 +782,7 @@ class RENDERLAYER_PT_freestyle_linestyle(RenderLayerFreestyleEditorButtonsPanel, layout.separator() row = layout.row() - if rd.use_shading_nodes: + if view_render.use_shading_nodes: row.prop(linestyle, "use_nodes") else: row.prop(linestyle, "use_texture") @@ -810,7 +813,7 @@ 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) + (scene.view_render.engine in cls.COMPAT_ENGINES) class MATERIAL_PT_freestyle_line(MaterialFreestyleButtonsPanel, Panel): diff --git a/release/scripts/startup/bl_ui/properties_game.py b/release/scripts/startup/bl_ui/properties_game.py index 277b0842b3d..eb2d3d49e61 100644 --- a/release/scripts/startup/bl_ui/properties_game.py +++ b/release/scripts/startup/bl_ui/properties_game.py @@ -34,8 +34,8 @@ class PHYSICS_PT_game_physics(PhysicsButtonsPanel, Panel): @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) + view_render = context.scene.view_render + return ob and ob.game and (view_render.engine in cls.COMPAT_ENGINES) def draw(self, context): layout = self.layout @@ -205,8 +205,8 @@ class PHYSICS_PT_game_collision_bounds(PhysicsButtonsPanel, Panel): @classmethod def poll(cls, context): game = context.object.game - rd = context.scene.render - return (rd.engine in cls.COMPAT_ENGINES) \ + view_render = context.scene.view_render + return (view_render.engine in cls.COMPAT_ENGINES) \ and (game.physics_type in {'SENSOR', 'STATIC', 'DYNAMIC', 'RIGID_BODY', 'CHARACTER', 'SOFT_BODY'}) def draw_header(self, context): @@ -246,8 +246,8 @@ class PHYSICS_PT_game_obstacles(PhysicsButtonsPanel, Panel): @classmethod def poll(cls, context): game = context.object.game - rd = context.scene.render - return (rd.engine in cls.COMPAT_ENGINES) \ + view_render = context.scene.view_render + return (view_render.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): @@ -274,8 +274,8 @@ class RenderButtonsPanel: @classmethod def poll(cls, context): - rd = context.scene.render - return (rd.engine in cls.COMPAT_ENGINES) + view_render = context.scene.view_render + return (view_render.engine in cls.COMPAT_ENGINES) class RENDER_PT_embedded(RenderButtonsPanel, Panel): @@ -285,7 +285,7 @@ class RENDER_PT_embedded(RenderButtonsPanel, Panel): def draw(self, context): layout = self.layout - rd = context.scene.render + view_render = context.scene.view_render row = layout.row() row.operator("view3d.game_start", text="Start") @@ -422,10 +422,8 @@ class RENDER_PT_game_system(RenderButtonsPanel, Panel): 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' + col.prop(gs, "use_material_caching") row = layout.row() row.prop(gs, "vsync") @@ -476,7 +474,7 @@ class SCENE_PT_game_physics(SceneButtonsPanel, Panel): @classmethod def poll(cls, context): scene = context.scene - return (scene.render.engine in cls.COMPAT_ENGINES) + return (scene.view_render.engine in cls.COMPAT_ENGINES) def draw(self, context): layout = self.layout @@ -534,7 +532,7 @@ class SCENE_PT_game_physics_obstacles(SceneButtonsPanel, Panel): @classmethod def poll(cls, context): scene = context.scene - return (scene.render.engine in cls.COMPAT_ENGINES) + return (scene.view_render.engine in cls.COMPAT_ENGINES) def draw(self, context): layout = self.layout @@ -555,7 +553,7 @@ class SCENE_PT_game_navmesh(SceneButtonsPanel, Panel): @classmethod def poll(cls, context): scene = context.scene - return (scene and scene.render.engine in cls.COMPAT_ENGINES) + return (scene and scene.view_render.engine in cls.COMPAT_ENGINES) def draw(self, context): layout = self.layout @@ -616,7 +614,7 @@ class SCENE_PT_game_hysteresis(SceneButtonsPanel, Panel): @classmethod def poll(cls, context): scene = context.scene - return (scene and scene.render.engine in cls.COMPAT_ENGINES) + return (scene and scene.view_render.engine in cls.COMPAT_ENGINES) def draw(self, context): layout = self.layout @@ -642,8 +640,8 @@ class WORLD_PT_game_context_world(WorldButtonsPanel, Panel): @classmethod def poll(cls, context): - rd = context.scene.render - return (context.scene) and (rd.engine in cls.COMPAT_ENGINES) + view_render = context.scene.view_render + return (context.scene) and (view_render.engine in cls.COMPAT_ENGINES) def draw(self, context): layout = self.layout @@ -666,7 +664,7 @@ class WORLD_PT_game_world(WorldButtonsPanel, Panel): @classmethod def poll(cls, context): scene = context.scene - return (scene.world and scene.render.engine in cls.COMPAT_ENGINES) + return (scene.world and scene.view_render.engine in cls.COMPAT_ENGINES) def draw(self, context): layout = self.layout @@ -686,7 +684,7 @@ class WORLD_PT_game_environment_lighting(WorldButtonsPanel, Panel): @classmethod def poll(cls, context): scene = context.scene - return (scene.world and scene.render.engine in cls.COMPAT_ENGINES) + return (scene.world and scene.view_render.engine in cls.COMPAT_ENGINES) def draw_header(self, context): light = context.world.light_settings @@ -711,7 +709,7 @@ class WORLD_PT_game_mist(WorldButtonsPanel, Panel): @classmethod def poll(cls, context): scene = context.scene - return (scene.world and scene.render.engine in cls.COMPAT_ENGINES) + return (scene.world and scene.view_render.engine in cls.COMPAT_ENGINES) def draw_header(self, context): world = context.world @@ -748,7 +746,7 @@ class DATA_PT_shadow_game(DataButtonsPanel, Panel): def poll(cls, context): COMPAT_LIGHTS = {'SPOT', 'SUN'} lamp = context.lamp - engine = context.scene.render.engine + engine = context.engine return (lamp and lamp.type in COMPAT_LIGHTS) and (engine in cls.COMPAT_ENGINES) def draw_header(self, context): @@ -817,7 +815,7 @@ class OBJECT_PT_levels_of_detail(ObjectButtonsPanel, Panel): @classmethod def poll(cls, context): - return context.scene.render.engine in cls.COMPAT_ENGINES + return context.engine in cls.COMPAT_ENGINES def draw(self, context): layout = self.layout diff --git a/release/scripts/startup/bl_ui/properties_material.py b/release/scripts/startup/bl_ui/properties_material.py index 73740df37e8..42a132004d4 100644 --- a/release/scripts/startup/bl_ui/properties_material.py +++ b/release/scripts/startup/bl_ui/properties_material.py @@ -21,7 +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_ - +from bpy_extras.node_utils import find_node_input, find_output_node def active_node_mat(mat): # TODO, 2.4x has a pipeline section, for 2.5 we need to communicate @@ -82,7 +82,7 @@ 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: + if ma and not context.view_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)) @@ -101,7 +101,7 @@ 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_context_material(MaterialButtonsPanel, Panel): @@ -114,7 +114,7 @@ class MATERIAL_PT_context_material(MaterialButtonsPanel, Panel): # 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): @@ -197,7 +197,7 @@ class MATERIAL_PT_pipeline(MaterialButtonsPanel, Panel): @classmethod def poll(cls, context): mat = context.material - engine = context.scene.render.engine + engine = context.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): @@ -250,7 +250,7 @@ class MATERIAL_PT_diffuse(MaterialButtonsPanel, Panel): @classmethod def poll(cls, context): mat = context.material - engine = context.scene.render.engine + engine = context.engine return check_material(mat) and (mat.type in {'SURFACE', 'WIRE'}) and (engine in cls.COMPAT_ENGINES) def draw(self, context): @@ -307,7 +307,7 @@ class MATERIAL_PT_specular(MaterialButtonsPanel, Panel): @classmethod def poll(cls, context): mat = context.material - engine = context.scene.render.engine + engine = context.engine return check_material(mat) and (mat.type in {'SURFACE', 'WIRE'}) and (engine in cls.COMPAT_ENGINES) def draw(self, context): @@ -360,7 +360,7 @@ class MATERIAL_PT_shading(MaterialButtonsPanel, Panel): @classmethod def poll(cls, context): mat = context.material - engine = context.scene.render.engine + engine = context.engine return check_material(mat) and (mat.type in {'SURFACE', 'WIRE'}) and (engine in cls.COMPAT_ENGINES) def draw(self, context): @@ -394,7 +394,7 @@ class MATERIAL_PT_transp(MaterialButtonsPanel, Panel): @classmethod def poll(cls, context): mat = context.material - engine = context.scene.render.engine + engine = context.engine return check_material(mat) and (mat.type in {'SURFACE', 'WIRE'}) and (engine in cls.COMPAT_ENGINES) def draw_header(self, context): @@ -460,7 +460,7 @@ class MATERIAL_PT_mirror(MaterialButtonsPanel, Panel): @classmethod def poll(cls, context): mat = context.material - engine = context.scene.render.engine + engine = context.engine return check_material(mat) and (mat.type in {'SURFACE', 'WIRE'}) and (engine in cls.COMPAT_ENGINES) def draw_header(self, context): @@ -518,7 +518,7 @@ class MATERIAL_PT_sss(MaterialButtonsPanel, Panel): @classmethod def poll(cls, context): mat = context.material - engine = context.scene.render.engine + engine = context.engine return check_material(mat) and (mat.type in {'SURFACE', 'WIRE'}) and (engine in cls.COMPAT_ENGINES) def draw_header(self, context): @@ -569,7 +569,7 @@ class MATERIAL_PT_halo(MaterialButtonsPanel, Panel): @classmethod def poll(cls, context): mat = context.material - engine = context.scene.render.engine + engine = context.engine return mat and (mat.type == 'HALO') and (engine in cls.COMPAT_ENGINES) def draw(self, context): @@ -622,7 +622,7 @@ class MATERIAL_PT_flare(MaterialButtonsPanel, Panel): @classmethod def poll(cls, context): mat = context.material - engine = context.scene.render.engine + engine = context.engine return mat and (mat.type == 'HALO') and (engine in cls.COMPAT_ENGINES) def draw_header(self, context): @@ -656,7 +656,7 @@ class MATERIAL_PT_game_settings(MaterialButtonsPanel, Panel): @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) def draw(self, context): layout = self.layout @@ -685,7 +685,7 @@ class MATERIAL_PT_physics(MaterialButtonsPanel, Panel): @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) def draw(self, context): layout = self.layout @@ -718,7 +718,7 @@ class MATERIAL_PT_strand(MaterialButtonsPanel, Panel): @classmethod def poll(cls, context): mat = context.material - engine = context.scene.render.engine + engine = context.engine return mat and (mat.type in {'SURFACE', 'WIRE', 'HALO'}) and (engine in cls.COMPAT_ENGINES) def draw(self, context): @@ -746,7 +746,7 @@ class MATERIAL_PT_strand(MaterialButtonsPanel, Panel): 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="") + col.prop_search(tan, "uv_layer", ob.data, "uv_layers", text="") else: col.prop(tan, "uv_layer", text="") col.separator() @@ -764,7 +764,7 @@ class MATERIAL_PT_options(MaterialButtonsPanel, Panel): @classmethod def poll(cls, context): mat = context.material - engine = context.scene.render.engine + engine = context.engine return check_material(mat) and (mat.type in {'SURFACE', 'WIRE'}) and (engine in cls.COMPAT_ENGINES) def draw(self, context): @@ -795,11 +795,6 @@ class MATERIAL_PT_options(MaterialButtonsPanel, Panel): 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") @@ -807,6 +802,9 @@ class MATERIAL_PT_options(MaterialButtonsPanel, Panel): if simple_material(base_mat): col.prop(mat, "pass_index") + col.label("Edit Image") + col.template_ID(mat, "edit_image") + class MATERIAL_PT_shadow(MaterialButtonsPanel, Panel): bl_label = "Shadow" @@ -816,7 +814,7 @@ class MATERIAL_PT_shadow(MaterialButtonsPanel, Panel): @classmethod def poll(cls, context): mat = context.material - engine = context.scene.render.engine + engine = context.engine return check_material(mat) and (mat.type in {'SURFACE', 'WIRE'}) and (engine in cls.COMPAT_ENGINES) def draw(self, context): @@ -866,7 +864,7 @@ class MATERIAL_PT_transp_game(MaterialButtonsPanel, Panel): @classmethod def poll(cls, context): mat = context.material - engine = context.scene.render.engine + engine = context.engine return check_material(mat) and (engine in cls.COMPAT_ENGINES) def draw_header(self, context): @@ -899,7 +897,7 @@ class VolumeButtonsPanel: @classmethod def poll(cls, context): mat = context.material - engine = context.scene.render.engine + engine = context.engine return mat and (mat.type == 'VOLUME') and (engine in cls.COMPAT_ENGINES) @@ -984,7 +982,7 @@ class MATERIAL_PT_volume_transp(VolumeButtonsPanel, Panel): @classmethod def poll(cls, context): mat = context.material - engine = context.scene.render.engine + engine = context.engine return mat and simple_material(mat) and (mat.type == 'VOLUME') and (engine in cls.COMPAT_ENGINES) def draw(self, context): @@ -1025,7 +1023,7 @@ class MATERIAL_PT_volume_options(VolumeButtonsPanel, Panel): @classmethod def poll(cls, context): mat = context.material - engine = context.scene.render.engine + engine = context.engine return check_material(mat) and (mat.type == 'VOLUME') and (engine in cls.COMPAT_ENGINES) def draw(self, context): @@ -1055,6 +1053,140 @@ class MATERIAL_PT_custom_props(MaterialButtonsPanel, PropertyPanel, Panel): _property_type = bpy.types.Material +class EEVEE_MATERIAL_PT_context_material(MaterialButtonsPanel, Panel): + bl_label = "" + bl_context = "material" + bl_options = {'HIDE_HEADER'} + COMPAT_ENGINES = {'BLENDER_EEVEE'} + + @classmethod + def poll(cls, context): + engine = context.engine + return (context.material or context.object) and (engine in cls.COMPAT_ENGINES) + + def draw(self, context): + layout = self.layout + + mat = context.material + ob = context.object + slot = context.material_slot + space = context.space_data + + if ob: + is_sortable = len(ob.material_slots) > 1 + rows = 1 + if (is_sortable): + rows = 4 + + row = layout.row() + + row.template_list("MATERIAL_UL_matslots", "", ob, "material_slots", ob, "active_material_index", rows=rows) + + col = row.column(align=True) + col.operator("object.material_slot_add", icon='ZOOMIN', text="") + col.operator("object.material_slot_remove", icon='ZOOMOUT', text="") + + col.menu("MATERIAL_MT_specials", icon='DOWNARROW_HLT', text="") + + if is_sortable: + col.separator() + + col.operator("object.material_slot_move", icon='TRIA_UP', text="").direction = 'UP' + col.operator("object.material_slot_move", icon='TRIA_DOWN', text="").direction = 'DOWN' + + if ob.mode == 'EDIT': + row = layout.row(align=True) + row.operator("object.material_slot_assign", text="Assign") + row.operator("object.material_slot_select", text="Select") + row.operator("object.material_slot_deselect", text="Deselect") + + split = layout.split(percentage=0.65) + + if ob: + split.template_ID(ob, "active_material", new="material.new") + row = split.row() + + if slot: + row.prop(slot, "link", text="") + else: + row.label() + elif mat: + split.template_ID(space, "pin_id") + split.separator() + + +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 EEVEE_MATERIAL_PT_surface(MaterialButtonsPanel, Panel): + bl_label = "Surface" + bl_context = "material" + COMPAT_ENGINES = {'BLENDER_EEVEE'} + + @classmethod + def poll(cls, context): + engine = context.engine + return context.material and (engine in cls.COMPAT_ENGINES) + + def draw(self, context): + layout = self.layout + + mat = context.material + + layout.prop(mat, "use_nodes", icon='NODETREE') + layout.separator() + + if mat.use_nodes: + panel_node_draw(layout, mat.node_tree, ('OUTPUT_EEVEE_MATERIAL', 'OUTPUT_MATERIAL')) + else: + raym = mat.raytrace_mirror + layout.prop(mat, "diffuse_color", text="Base Color") + layout.prop(raym, "reflect_factor", text="Metallic") + layout.prop(mat, "specular_intensity", text="Specular") + layout.prop(raym, "gloss_factor", text="Roughness") + + +class EEVEE_MATERIAL_PT_options(MaterialButtonsPanel, Panel): + bl_label = "Options" + bl_context = "material" + COMPAT_ENGINES = {'BLENDER_EEVEE'} + + @classmethod + def poll(cls, context): + engine = context.engine + return context.material and (engine in cls.COMPAT_ENGINES) + + def draw(self, context): + layout = self.layout + + mat = context.material + + layout.prop(mat, "blend_method") + + if mat.blend_method != "OPAQUE": + layout.prop(mat, "transparent_shadow_method") + + row = layout.row() + row.active = ((mat.blend_method == "CLIP") or (mat.transparent_shadow_method == "CLIP")) + layout.prop(mat, "alpha_threshold") + + if mat.blend_method not in {"OPAQUE", "CLIP", "HASHED"}: + layout.prop(mat, "transparent_hide_backside") + + layout.prop(mat, "use_screen_refraction") + layout.prop(mat, "refraction_depth") + + classes = ( MATERIAL_MT_sss_presets, MATERIAL_MT_specials, @@ -1083,6 +1215,9 @@ classes = ( 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, ) if __name__ == "__main__": # only for live edit. diff --git a/release/scripts/startup/bl_ui/properties_object.py b/release/scripts/startup/bl_ui/properties_object.py index f7c0617f525..a77dad506f1 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") + row.template_ID(context.render_layer.objects, "active") class OBJECT_PT_transform(ObjectButtonsPanel, Panel): @@ -163,7 +163,7 @@ class OBJECT_PT_relations_extras(ObjectButtonsPanel, Panel): split = layout.split() - if context.scene.render.engine != 'BLENDER_GAME': + if context.engine != 'BLENDER_GAME': col = split.column() col.label(text="Tracking Axes:") col.prop(ob, "track_axis", text="Axis") @@ -362,7 +362,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_GAME', 'BLENDER_CLAY', 'BLENDER_EEVEE'} _context_path = "object" _property_type = bpy.types.Object 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 0352c4e6e09..a5793e6d9a9 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_GAME', '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_GAME', 'BLENDER_CLAY', 'BLENDER_EEVEE'} draw = Menu.draw_preset @@ -131,17 +131,17 @@ 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_GAME', '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': + if context.engine == 'BLENDER_GAME': layout.label("Not available in the Game Engine") return @@ -238,7 +238,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 +314,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 +412,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 +442,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 +493,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 +556,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): @@ -796,13 +796,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 @@ -899,12 +899,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 @@ -1058,8 +1058,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:") @@ -1068,7 +1068,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:") @@ -1098,12 +1098,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 @@ -1161,7 +1161,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): @@ -1290,7 +1290,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): @@ -1311,7 +1311,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 @@ -1345,7 +1345,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): @@ -1411,7 +1411,7 @@ class PARTICLE_PT_vertexgroups(ParticleButtonsPanel, Panel): 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 diff --git a/release/scripts/startup/bl_ui/properties_physics_cloth.py b/release/scripts/startup/bl_ui/properties_physics_cloth.py index bcbb44b2cb3..351418c9d23 100644 --- a/release/scripts/startup/bl_ui/properties_physics_cloth.py +++ b/release/scripts/startup/bl_ui/properties_physics_cloth.py @@ -45,8 +45,8 @@ 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) + view_render = context.scene.view_render + return (ob and ob.type == 'MESH') and (view_render.engine in cls.COMPAT_ENGINES) and (context.cloth) class PHYSICS_PT_cloth(PhysicButtonsPanel, Panel): @@ -64,6 +64,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) diff --git a/release/scripts/startup/bl_ui/properties_physics_common.py b/release/scripts/startup/bl_ui/properties_physics_common.py index 73d3d5fc755..15c8bd68d10 100644 --- a/release/scripts/startup/bl_ui/properties_physics_common.py +++ b/release/scripts/startup/bl_ui/properties_physics_common.py @@ -30,8 +30,8 @@ class PhysicButtonsPanel: @classmethod def poll(cls, context): - rd = context.scene.render - return (context.object) and rd.engine in cls.COMPAT_ENGINES + view_render = context.scene.view_render + return (context.object) and view_render.engine in cls.COMPAT_ENGINES def physics_add(self, layout, md, name, type, typeicon, toggles): @@ -57,7 +57,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..7fc1c01279d 100644 --- a/release/scripts/startup/bl_ui/properties_physics_dynamicpaint.py +++ b/release/scripts/startup/bl_ui/properties_physics_dynamicpaint.py @@ -55,8 +55,8 @@ 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 + view_render = context.scene.view_render + return (ob and ob.type == 'MESH') and view_render.engine in cls.COMPAT_ENGINES and context.dynamic_paint class PHYSICS_PT_dynamic_paint(PhysicButtonsPanel, Panel): @@ -109,7 +109,7 @@ 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 + use_shading_nodes = context.view_render.use_shading_nodes if brush is None: layout.operator("dpaint.type_toggle", text="Add Brush").type = 'BRUSH' @@ -143,8 +143,8 @@ class PHYSICS_PT_dp_advanced_canvas(PhysicButtonsPanel, Panel): @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 + view_render = context.scene.view_render + return md and md.ui_type == 'CANVAS' and md.canvas_settings and md.canvas_settings.canvas_surfaces.active and view_render.engine in cls.COMPAT_ENGINES def draw(self, context): layout = self.layout @@ -220,13 +220,13 @@ class PHYSICS_PT_dp_canvas_output(PhysicButtonsPanel, Panel): @classmethod def poll(cls, context): md = context.dynamic_paint - rd = context.scene.render + view_render = context.scene.view_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)) + (view_render.engine in cls.COMPAT_ENGINES)) def draw(self, context): layout = self.layout @@ -276,7 +276,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="") @@ -314,11 +314,11 @@ class PHYSICS_PT_dp_canvas_initial_color(PhysicButtonsPanel, Panel): @classmethod def poll(cls, context): md = context.dynamic_paint - rd = context.scene.render + view_render = context.scene.view_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 (view_render.engine in cls.COMPAT_ENGINES) def draw(self, context): layout = self.layout @@ -337,7 +337,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") @@ -351,11 +351,11 @@ class PHYSICS_PT_dp_effects(PhysicButtonsPanel, Panel): @classmethod def poll(cls, context): md = context.dynamic_paint - rd = context.scene.render + view_render = context.scene.view_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 (view_render.engine in cls.COMPAT_ENGINES) def draw(self, context): layout = self.layout @@ -401,13 +401,13 @@ class PHYSICS_PT_dp_cache(PhysicButtonsPanel, Panel): @classmethod def poll(cls, context): md = context.dynamic_paint - rd = context.scene.render + view_render = context.scene.view_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)) + (view_render.engine in cls.COMPAT_ENGINES)) def draw(self, context): surface = context.dynamic_paint.canvas_settings.canvas_surfaces.active @@ -423,8 +423,8 @@ class PHYSICS_PT_dp_brush_source(PhysicButtonsPanel, Panel): @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) + view_render = context.scene.view_render + return md and md.ui_type == 'BRUSH' and md.brush_settings and (view_render.engine in cls.COMPAT_ENGINES) def draw(self, context): layout = self.layout @@ -477,8 +477,8 @@ class PHYSICS_PT_dp_brush_velocity(PhysicButtonsPanel, Panel): @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) + view_render = context.scene.view_render + return md and md.ui_type == 'BRUSH' and md.brush_settings and (view_render.engine in cls.COMPAT_ENGINES) def draw(self, context): layout = self.layout @@ -514,8 +514,8 @@ class PHYSICS_PT_dp_brush_wave(PhysicButtonsPanel, Panel): @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) + view_render = context.scene.view_render + return md and md.ui_type == 'BRUSH' and md.brush_settings and (view_render.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..aee93f840be 100644 --- a/release/scripts/startup/bl_ui/properties_physics_field.py +++ b/release/scripts/startup/bl_ui/properties_physics_field.py @@ -33,19 +33,19 @@ class PhysicButtonsPanel: @classmethod def poll(cls, context): - rd = context.scene.render - return (context.object) and (rd.engine in cls.COMPAT_ENGINES) + view_render = context.scene.view_render + return (context.object) and (view_render.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') + view_render = context.scene.view_render + return (view_render.engine in cls.COMPAT_ENGINES) and (ob.field) and (ob.field.type != 'NONE') def draw(self, context): layout = self.layout @@ -177,13 +177,13 @@ 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) + view_render = context.scene.view_render + return (ob and ob.type == 'MESH') and (view_render.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..61ca23be4bc 100644 --- a/release/scripts/startup/bl_ui/properties_physics_fluid.py +++ b/release/scripts/startup/bl_ui/properties_physics_fluid.py @@ -37,8 +37,8 @@ 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) + view_render = context.scene.view_render + return (ob and ob.type == 'MESH') and view_render.engine in cls.COMPAT_ENGINES and (context.fluid) class PHYSICS_PT_fluid(PhysicButtonsPanel, Panel): @@ -211,8 +211,8 @@ class PHYSICS_PT_domain_gravity(PhysicButtonsPanel, Panel): @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 + view_render = context.scene.view_render + return md and md.settings and (md.settings.type == 'DOMAIN') and view_render.engine in cls.COMPAT_ENGINES def draw(self, context): layout = self.layout @@ -265,8 +265,8 @@ class PHYSICS_PT_domain_boundary(PhysicButtonsPanel, Panel): @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 + view_render = context.scene.view_render + return md and md.settings and (md.settings.type == 'DOMAIN') and view_render.engine in cls.COMPAT_ENGINES def draw(self, context): layout = self.layout @@ -296,8 +296,8 @@ class PHYSICS_PT_domain_particles(PhysicButtonsPanel, Panel): @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 + view_render = context.scene.view_render + return md and md.settings and (md.settings.type == 'DOMAIN') and view_render.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..21453ff3642 100644 --- a/release/scripts/startup/bl_ui/properties_physics_rigidbody.py +++ b/release/scripts/startup/bl_ui/properties_physics_rigidbody.py @@ -35,7 +35,7 @@ class PHYSICS_PT_rigid_body(PHYSICS_PT_rigidbody_panel, Panel): 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 @@ -62,7 +62,7 @@ class PHYSICS_PT_rigid_body_collisions(PHYSICS_PT_rigidbody_panel, Panel): 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 @@ -108,7 +108,7 @@ class PHYSICS_PT_rigid_body_dynamics(PHYSICS_PT_rigidbody_panel, Panel): 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..a9b30c3b388 100644 --- a/release/scripts/startup/bl_ui/properties_physics_rigidbody_constraint.py +++ b/release/scripts/startup/bl_ui/properties_physics_rigidbody_constraint.py @@ -34,8 +34,8 @@ class PHYSICS_PT_rigid_body_constraint(PHYSICS_PT_rigidbody_constraint_panel, Pa @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) + view_render = context.scene.view_render + return (ob and ob.rigid_body_constraint and view_render.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 01144fa9307..5cf89df63ab 100644 --- a/release/scripts/startup/bl_ui/properties_physics_smoke.py +++ b/release/scripts/startup/bl_ui/properties_physics_smoke.py @@ -34,13 +34,13 @@ 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) + view_render = context.scene.view_render + return (ob and ob.type == 'MESH') and (view_render.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 @@ -136,7 +136,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): @@ -158,7 +158,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") @@ -171,7 +171,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): @@ -201,7 +201,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): @@ -235,13 +235,13 @@ 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) + view_render = context.scene.view_render + return md and (md.smoke_type == 'DOMAIN') and (view_render.engine in cls.COMPAT_ENGINES) def draw_header(self, context): md = context.smoke.domain_settings @@ -275,13 +275,13 @@ 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) + view_render = context.scene.view_render + return md and (md.smoke_type == 'DOMAIN') and (view_render.engine in cls.COMPAT_ENGINES) def draw(self, context): layout = self.layout @@ -304,13 +304,13 @@ 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) + view_render = context.scene.view_render + return md and (md.smoke_type == 'DOMAIN') and (view_render.engine in cls.COMPAT_ENGINES) def draw(self, context): layout = self.layout @@ -341,13 +341,13 @@ 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) + view_render = context.scene.view_render + return md and (md.smoke_type == 'DOMAIN') and (view_render.engine in cls.COMPAT_ENGINES) def draw(self, context): domain = context.smoke.domain_settings @@ -361,8 +361,8 @@ 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) + view_render = context.scene.view_render + return md and (md.smoke_type == 'DOMAIN') and (not view_render.use_game_engine) 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..718f552cf33 100644 --- a/release/scripts/startup/bl_ui/properties_physics_softbody.py +++ b/release/scripts/startup/bl_ui/properties_physics_softbody.py @@ -41,8 +41,8 @@ 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 + view_render = context.scene.view_render + return ob and ob.type in COMPAT_OB_TYPES and view_render.engine in cls.COMPAT_ENGINES and context.soft_body class PHYSICS_PT_softbody(PhysicButtonsPanel, Panel): diff --git a/release/scripts/startup/bl_ui/properties_render.py b/release/scripts/startup/bl_ui/properties_render.py index 2f3adf546b8..6be6bea5a52 100644 --- a/release/scripts/startup/bl_ui/properties_render.py +++ b/release/scripts/startup/bl_ui/properties_render.py @@ -52,7 +52,28 @@ class RenderButtonsPanel: @classmethod def poll(cls, context): scene = context.scene - return scene and (scene.render.engine in cls.COMPAT_ENGINES) + return scene and (scene.view_render.engine in cls.COMPAT_ENGINES) + + +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 + + scene = context.scene + view_render = scene.view_render + + if view_render.has_multiple_engines: + layout.prop(view_render, "engine", text="") class RENDER_PT_render(RenderButtonsPanel, Panel): @@ -79,7 +100,7 @@ class RENDER_PT_render(RenderButtonsPanel, Panel): 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 @@ -207,8 +228,10 @@ class RENDER_PT_motion_blur(RenderButtonsPanel, Panel): @classmethod def poll(cls, context): - rd = context.scene.render - return not rd.use_full_sample and (rd.engine in cls.COMPAT_ENGINES) + scene = context.scene + rd = scene.render + view_render = scene.view_render + return not rd.use_full_sample and (view_render.engine in cls.COMPAT_ENGINES) def draw_header(self, context): rd = context.scene.render @@ -336,7 +359,7 @@ class RENDER_PT_post_processing(RenderButtonsPanel, Panel): 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 @@ -384,7 +407,7 @@ class RENDER_PT_stamp(RenderButtonsPanel, Panel): 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 @@ -554,10 +577,283 @@ class RENDER_PT_bake(RenderButtonsPanel, Panel): sub.prop(rd, "bake_user_scale", text="User Scale") +class RENDER_PT_clay_layer_settings(RenderButtonsPanel, Panel): + bl_label = "Clay Layer Settings" + COMPAT_ENGINES = {'BLENDER_CLAY'} + + def draw(self, context): + layout = self.layout + props = context.scene.layer_properties['BLENDER_CLAY'] + + col = layout.column() + col.prop(props, "ssao_samples") + + +class RENDER_PT_clay_collection_settings(RenderButtonsPanel, Panel): + bl_label = "Clay Collection Settings" + COMPAT_ENGINES = {'BLENDER_CLAY'} + + def draw(self, context): + layout = self.layout + props = context.scene.collection_properties['BLENDER_CLAY'] + + 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, "ssao_factor_cavity") + col.prop(props, "ssao_factor_edge") + col.prop(props, "ssao_distance") + col.prop(props, "ssao_attenuation") + col.prop(props, "hair_brightness_randomness") + + +class RENDER_PT_eevee_ambient_occlusion(RenderButtonsPanel, Panel): + bl_label = "Ambient Occlusion" + bl_options = {'DEFAULT_CLOSED'} + COMPAT_ENGINES = {'BLENDER_EEVEE'} + + @classmethod + def poll(cls, context): + scene = context.scene + return scene and (scene.view_render.engine in cls.COMPAT_ENGINES) + + def draw_header(self, context): + scene = context.scene + props = scene.layer_properties['BLENDER_EEVEE'] + self.layout.prop(props, "gtao_enable", text="") + + def draw(self, context): + layout = self.layout + scene = context.scene + props = scene.layer_properties['BLENDER_EEVEE'] + + layout.active = props.gtao_enable + col = layout.column() + col.prop(props, "gtao_use_bent_normals") + col.prop(props, "gtao_denoise") + col.prop(props, "gtao_bounce") + col.prop(props, "gtao_samples") + col.prop(props, "gtao_distance") + col.prop(props, "gtao_factor") + col.prop(props, "gtao_quality") + + +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): + scene = context.scene + return scene and (scene.view_render.engine in cls.COMPAT_ENGINES) + + def draw_header(self, context): + scene = context.scene + props = scene.layer_properties['BLENDER_EEVEE'] + self.layout.prop(props, "motion_blur_enable", text="") + + def draw(self, context): + layout = self.layout + scene = context.scene + props = scene.layer_properties['BLENDER_EEVEE'] + + layout.active = props.motion_blur_enable + 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): + scene = context.scene + return scene and (scene.view_render.engine in cls.COMPAT_ENGINES) + + def draw_header(self, context): + scene = context.scene + props = scene.layer_properties['BLENDER_EEVEE'] + self.layout.prop(props, "dof_enable", text="") + + def draw(self, context): + layout = self.layout + scene = context.scene + props = scene.layer_properties['BLENDER_EEVEE'] + + layout.active = props.dof_enable + 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): + scene = context.scene + return scene and (scene.view_render.engine in cls.COMPAT_ENGINES) + + def draw_header(self, context): + scene = context.scene + props = scene.layer_properties['BLENDER_EEVEE'] + self.layout.prop(props, "bloom_enable", text="") + + def draw(self, context): + layout = self.layout + scene = context.scene + props = scene.layer_properties['BLENDER_EEVEE'] + + layout.active = props.bloom_enable + 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): + scene = context.scene + return scene and (scene.view_render.engine in cls.COMPAT_ENGINES) + + def draw_header(self, context): + scene = context.scene + props = scene.layer_properties['BLENDER_EEVEE'] + self.layout.prop(props, "volumetric_enable", text="") + + def draw(self, context): + layout = self.layout + scene = context.scene + props = scene.layer_properties['BLENDER_EEVEE'] + + layout.active = props.volumetric_enable + col = layout.column() + col.prop(props, "volumetric_start") + col.prop(props, "volumetric_end") + col.prop(props, "volumetric_tile_size") + col.prop(props, "volumetric_samples") + col.prop(props, "volumetric_sample_distribution") + col.prop(props, "volumetric_lights") + col.prop(props, "volumetric_light_clamp") + col.prop(props, "volumetric_shadows") + col.prop(props, "volumetric_shadow_samples") + col.prop(props, "volumetric_colored_transmittance") + + +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): + scene = context.scene + return scene and (scene.view_render.engine in cls.COMPAT_ENGINES) + + def draw_header(self, context): + scene = context.scene + props = scene.layer_properties['BLENDER_EEVEE'] + self.layout.prop(props, "ssr_enable", text="") + + def draw(self, context): + layout = self.layout + scene = context.scene + props = scene.layer_properties['BLENDER_EEVEE'] + + col = layout.column() + col.active = props.ssr_enable + col.prop(props, "ssr_refraction") + col.prop(props, "ssr_halfres") + col.prop(props, "ssr_ray_count") + 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): + scene = context.scene + return scene and (scene.view_render.engine in cls.COMPAT_ENGINES) + + def draw(self, context): + layout = self.layout + scene = context.scene + props = scene.layer_properties['BLENDER_EEVEE'] + + col = layout.column() + col.prop(props, "shadow_method") + col.prop(props, "shadow_size") + col.prop(props, "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): + scene = context.scene + return scene and (scene.view_render.engine in cls.COMPAT_ENGINES) + + def draw(self, context): + layout = self.layout + scene = context.scene + props = scene.layer_properties['BLENDER_EEVEE'] + + col = layout.column() + col.prop(props, "taa_samples") + + +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): + scene = context.scene + return scene and (scene.view_render.engine in cls.COMPAT_ENGINES) + + def draw(self, context): + layout = self.layout + scene = context.scene + props = scene.layer_properties['BLENDER_EEVEE'] + + col = layout.column() + col.prop(props, "gi_diffuse_bounces") + col.prop(props, "gi_cubemap_resolution") + + classes = ( RENDER_MT_presets, RENDER_MT_ffmpeg_presets, RENDER_MT_framerate_presets, + RENDER_PT_context, RENDER_PT_render, RENDER_PT_dimensions, RENDER_PT_antialiasing, @@ -569,6 +865,17 @@ classes = ( RENDER_PT_output, RENDER_PT_encoding, RENDER_PT_bake, + RENDER_PT_clay_layer_settings, + RENDER_PT_clay_collection_settings, + RENDER_PT_eevee_sampling, + RENDER_PT_eevee_shadows, + RENDER_PT_eevee_indirect_lighting, + 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 index 084bc387822..270902ea54a 100644 --- a/release/scripts/startup/bl_ui/properties_render_layer.py +++ b/release/scripts/startup/bl_ui/properties_render_layer.py @@ -30,12 +30,12 @@ class RenderLayerButtonsPanel: @classmethod def poll(cls, context): scene = context.scene - return scene and (scene.render.engine in cls.COMPAT_ENGINES) + return scene and (scene.view_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) + # assert(isinstance(item, bpy.types.SceneLayer) layer = item if self.layout_type in {'DEFAULT', 'COMPACT'}: layout.prop(layer, "name", text="", icon_value=icon, emboss=False) @@ -48,21 +48,22 @@ class RENDERLAYER_UL_renderlayers(UIList): class RENDERLAYER_PT_layers(RenderLayerButtonsPanel, Panel): bl_label = "Layer List" bl_options = {'HIDE_HEADER'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME', 'BLENDER_CLAY', 'BLENDER_EEVEE'} def draw(self, context): layout = self.layout scene = context.scene rd = scene.render + view_render = scene.view_render - if rd.engine == 'BLENDER_GAME': + if view_render.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.template_list("RENDERLAYER_UL_renderlayers", "", scene, "render_layers", scene.render_layers, "active_index", rows=2) col = row.column() sub = col.column(align=True) @@ -71,103 +72,6 @@ class RENDERLAYER_PT_layers(RenderLayerButtonsPanel, Panel): 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) @@ -186,7 +90,7 @@ class RENDERLAYER_UL_renderviews(UIList): class RENDERLAYER_PT_views(RenderLayerButtonsPanel, Panel): bl_label = "Views" - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'} bl_options = {'DEFAULT_CLOSED'} def draw_header(self, context): @@ -227,13 +131,309 @@ class RENDERLAYER_PT_views(RenderLayerButtonsPanel, Panel): row.prop(rv, "camera_suffix", text="") +class RENDERLAYER_PT_clay_settings(RenderLayerButtonsPanel, Panel): + bl_label = "Render Settings" + COMPAT_ENGINES = {'BLENDER_CLAY'} + + @classmethod + def poll(cls, context): + scene = context.scene + return scene and (scene.view_render.engine in cls.COMPAT_ENGINES) + + def draw(self, context): + layout = self.layout + scene = context.scene + scene_props = scene.layer_properties['BLENDER_CLAY'] + layer = bpy.context.render_layer + layer_props = layer.engine_overrides['BLENDER_CLAY'] + + col = layout.column() + col.template_override_property(layer_props, scene_props, "ssao_samples") + + +class RENDERLAYER_PT_eevee_ambient_occlusion(RenderLayerButtonsPanel, Panel): + bl_label = "Ambient Occlusion" + bl_options = {'DEFAULT_CLOSED'} + COMPAT_ENGINES = {'BLENDER_EEVEE'} + + @classmethod + def poll(cls, context): + scene = context.scene + return scene and (scene.view_render.engine in cls.COMPAT_ENGINES) + + def draw_header(self, context): + scene = context.scene + scene_props = scene.layer_properties['BLENDER_EEVEE'] + layer = bpy.context.render_layer + layer_props = layer.engine_overrides['BLENDER_EEVEE'] + + self.layout.template_override_property(layer_props, scene_props, "gtao_enable", text="") + + def draw(self, context): + layout = self.layout + scene = context.scene + scene_props = scene.layer_properties['BLENDER_EEVEE'] + layer = bpy.context.render_layer + layer_props = layer.engine_overrides['BLENDER_EEVEE'] + + col = layout.column() + col.template_override_property(layer_props, scene_props, "gtao_use_bent_normals") + col.template_override_property(layer_props, scene_props, "gtao_denoise") + col.template_override_property(layer_props, scene_props, "gtao_bounce") + col.template_override_property(layer_props, scene_props, "gtao_samples") + col.template_override_property(layer_props, scene_props, "gtao_distance") + col.template_override_property(layer_props, scene_props, "gtao_factor") + col.template_override_property(layer_props, scene_props, "gtao_quality") + + +class RENDERLAYER_PT_eevee_motion_blur(RenderLayerButtonsPanel, Panel): + bl_label = "Motion Blur" + bl_options = {'DEFAULT_CLOSED'} + COMPAT_ENGINES = {'BLENDER_EEVEE'} + + @classmethod + def poll(cls, context): + scene = context.scene + return scene and (scene.view_render.engine in cls.COMPAT_ENGINES) + + def draw_header(self, context): + scene = context.scene + scene_props = scene.layer_properties['BLENDER_EEVEE'] + layer = bpy.context.render_layer + layer_props = layer.engine_overrides['BLENDER_EEVEE'] + + self.layout.template_override_property(layer_props, scene_props, "motion_blur_enable", text="") + + def draw(self, context): + layout = self.layout + scene = context.scene + scene_props = scene.layer_properties['BLENDER_EEVEE'] + layer = bpy.context.render_layer + layer_props = layer.engine_overrides['BLENDER_EEVEE'] + + col = layout.column() + col.template_override_property(layer_props, scene_props, "motion_blur_samples") + col.template_override_property(layer_props, scene_props, "motion_blur_shutter") + + +class RENDERLAYER_PT_eevee_depth_of_field(RenderLayerButtonsPanel, Panel): + bl_label = "Depth Of Field" + bl_options = {'DEFAULT_CLOSED'} + COMPAT_ENGINES = {'BLENDER_EEVEE'} + + @classmethod + def poll(cls, context): + scene = context.scene + return scene and (scene.view_render.engine in cls.COMPAT_ENGINES) + + def draw_header(self, context): + scene = context.scene + scene_props = scene.layer_properties['BLENDER_EEVEE'] + layer = bpy.context.render_layer + layer_props = layer.engine_overrides['BLENDER_EEVEE'] + + self.layout.template_override_property(layer_props, scene_props, "dof_enable", text="") + + def draw(self, context): + layout = self.layout + scene = context.scene + scene_props = scene.layer_properties['BLENDER_EEVEE'] + layer = bpy.context.render_layer + layer_props = layer.engine_overrides['BLENDER_EEVEE'] + + col = layout.column() + col.template_override_property(layer_props, scene_props, "bokeh_max_size") + col.template_override_property(layer_props, scene_props, "bokeh_threshold") + + +class RENDERLAYER_PT_eevee_bloom(RenderLayerButtonsPanel, Panel): + bl_label = "Bloom" + bl_options = {'DEFAULT_CLOSED'} + COMPAT_ENGINES = {'BLENDER_EEVEE'} + + @classmethod + def poll(cls, context): + scene = context.scene + return scene and (scene.view_render.engine in cls.COMPAT_ENGINES) + + def draw_header(self, context): + scene = context.scene + scene_props = scene.layer_properties['BLENDER_EEVEE'] + layer = bpy.context.render_layer + layer_props = layer.engine_overrides['BLENDER_EEVEE'] + + self.layout.template_override_property(layer_props, scene_props, "bloom_enable", text="") + + def draw(self, context): + layout = self.layout + scene = context.scene + scene_props = scene.layer_properties['BLENDER_EEVEE'] + layer = bpy.context.render_layer + layer_props = layer.engine_overrides['BLENDER_EEVEE'] + + col = layout.column() + col.template_override_property(layer_props, scene_props, "bloom_threshold") + col.template_override_property(layer_props, scene_props, "bloom_knee") + col.template_override_property(layer_props, scene_props, "bloom_radius") + col.template_override_property(layer_props, scene_props, "bloom_color") + col.template_override_property(layer_props, scene_props, "bloom_intensity") + col.template_override_property(layer_props, scene_props, "bloom_clamp") + + +class RENDERLAYER_PT_eevee_volumetric(RenderLayerButtonsPanel, Panel): + bl_label = "Volumetric" + bl_options = {'DEFAULT_CLOSED'} + COMPAT_ENGINES = {'BLENDER_EEVEE'} + + @classmethod + def poll(cls, context): + scene = context.scene + return scene and (scene.view_render.engine in cls.COMPAT_ENGINES) + + def draw_header(self, context): + scene = context.scene + scene_props = scene.layer_properties['BLENDER_EEVEE'] + layer = bpy.context.render_layer + layer_props = layer.engine_overrides['BLENDER_EEVEE'] + + self.layout.template_override_property(layer_props, scene_props, "volumetric_enable", text="") + + def draw(self, context): + layout = self.layout + scene = context.scene + scene_props = scene.layer_properties['BLENDER_EEVEE'] + layer = bpy.context.render_layer + layer_props = layer.engine_overrides['BLENDER_EEVEE'] + + col = layout.column() + col.template_override_property(layer_props, scene_props, "volumetric_start") + col.template_override_property(layer_props, scene_props, "volumetric_end") + col.template_override_property(layer_props, scene_props, "volumetric_tile_size") + col.template_override_property(layer_props, scene_props, "volumetric_samples") + col.template_override_property(layer_props, scene_props, "volumetric_sample_distribution") + col.template_override_property(layer_props, scene_props, "volumetric_lights") + col.template_override_property(layer_props, scene_props, "volumetric_light_clamp") + col.template_override_property(layer_props, scene_props, "volumetric_shadows") + col.template_override_property(layer_props, scene_props, "volumetric_shadow_samples") + col.template_override_property(layer_props, scene_props, "volumetric_colored_transmittance") + + +class RENDERLAYER_PT_eevee_screen_space_reflections(RenderLayerButtonsPanel, Panel): + bl_label = "Screen Space Reflections" + bl_options = {'DEFAULT_CLOSED'} + COMPAT_ENGINES = {'BLENDER_EEVEE'} + + @classmethod + def poll(cls, context): + scene = context.scene + return scene and (scene.view_render.engine in cls.COMPAT_ENGINES) + + def draw_header(self, context): + scene = context.scene + scene_props = scene.layer_properties['BLENDER_EEVEE'] + layer = bpy.context.render_layer + layer_props = layer.engine_overrides['BLENDER_EEVEE'] + + self.layout.template_override_property(layer_props, scene_props, "ssr_enable", text="") + + def draw(self, context): + layout = self.layout + scene = context.scene + scene_props = scene.layer_properties['BLENDER_EEVEE'] + layer = bpy.context.render_layer + layer_props = layer.engine_overrides['BLENDER_EEVEE'] + + col = layout.column() + col.template_override_property(layer_props, scene_props, "ssr_halfres") + col.template_override_property(layer_props, scene_props, "ssr_refraction") + col.template_override_property(layer_props, scene_props, "ssr_ray_count") + col.template_override_property(layer_props, scene_props, "ssr_quality") + col.template_override_property(layer_props, scene_props, "ssr_max_roughness") + col.template_override_property(layer_props, scene_props, "ssr_thickness") + col.template_override_property(layer_props, scene_props, "ssr_border_fade") + col.template_override_property(layer_props, scene_props, "ssr_firefly_fac") + + +class RENDERLAYER_PT_eevee_shadows(RenderLayerButtonsPanel, Panel): + bl_label = "Shadows" + bl_options = {'DEFAULT_CLOSED'} + COMPAT_ENGINES = {'BLENDER_EEVEE'} + + @classmethod + def poll(cls, context): + scene = context.scene + return scene and (scene.view_render.engine in cls.COMPAT_ENGINES) + + def draw(self, context): + layout = self.layout + scene = context.scene + scene_props = scene.layer_properties['BLENDER_EEVEE'] + layer = bpy.context.render_layer + layer_props = layer.engine_overrides['BLENDER_EEVEE'] + + col = layout.column() + col.template_override_property(layer_props, scene_props, "shadow_method") + col.template_override_property(layer_props, scene_props, "shadow_size") + col.template_override_property(layer_props, scene_props, "shadow_high_bitdepth") + + +class RENDERLAYER_PT_eevee_sampling(RenderLayerButtonsPanel, Panel): + bl_label = "Sampling" + bl_options = {'DEFAULT_CLOSED'} + COMPAT_ENGINES = {'BLENDER_EEVEE'} + + @classmethod + def poll(cls, context): + scene = context.scene + return scene and (scene.view_render.engine in cls.COMPAT_ENGINES) + + def draw(self, context): + layout = self.layout + scene = context.scene + scene_props = scene.layer_properties['BLENDER_EEVEE'] + layer = bpy.context.render_layer + layer_props = layer.engine_overrides['BLENDER_EEVEE'] + + col = layout.column() + col.template_override_property(layer_props, scene_props, "taa_samples") + + +class RENDERLAYER_PT_eevee_indirect_lighting(RenderLayerButtonsPanel, Panel): + bl_label = "Indirect Lighting" + bl_options = {'DEFAULT_CLOSED'} + COMPAT_ENGINES = {'BLENDER_EEVEE'} + + @classmethod + def poll(cls, context): + scene = context.scene + return scene and (scene.view_render.engine in cls.COMPAT_ENGINES) + + def draw(self, context): + layout = self.layout + scene = context.scene + scene_props = scene.layer_properties['BLENDER_EEVEE'] + layer = bpy.context.render_layer + layer_props = layer.engine_overrides['BLENDER_EEVEE'] + + col = layout.column() + col.template_override_property(layer_props, scene_props, "gi_diffuse_bounces") + + classes = ( RENDERLAYER_UL_renderlayers, RENDERLAYER_PT_layers, - RENDERLAYER_PT_layer_options, - RENDERLAYER_PT_layer_passes, RENDERLAYER_UL_renderviews, RENDERLAYER_PT_views, + RENDERLAYER_PT_clay_settings, + RENDERLAYER_PT_eevee_sampling, + RENDERLAYER_PT_eevee_shadows, + RENDERLAYER_PT_eevee_indirect_lighting, + RENDERLAYER_PT_eevee_screen_space_reflections, + RENDERLAYER_PT_eevee_ambient_occlusion, + RENDERLAYER_PT_eevee_volumetric, + RENDERLAYER_PT_eevee_motion_blur, + RENDERLAYER_PT_eevee_depth_of_field, + RENDERLAYER_PT_eevee_bloom, ) if __name__ == "__main__": # only for live edit. diff --git a/release/scripts/startup/bl_ui/properties_scene.py b/release/scripts/startup/bl_ui/properties_scene.py index db7fd998d4e..e8f25ea891b 100644 --- a/release/scripts/startup/bl_ui/properties_scene.py +++ b/release/scripts/startup/bl_ui/properties_scene.py @@ -60,13 +60,13 @@ class SceneButtonsPanel: @classmethod def poll(cls, context): - rd = context.scene.render - return context.scene and (rd.engine in cls.COMPAT_ENGINES) + view_render = context.scene.view_render + return context.scene and (view_render.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_GAME', 'BLENDER_CLAY', 'BLENDER_EEVEE'} def draw(self, context): layout = self.layout @@ -75,13 +75,13 @@ class SCENE_PT_scene(SceneButtonsPanel, Panel): layout.prop(scene, "camera") layout.prop(scene, "background_set", text="Background") - if context.scene.render.engine != 'BLENDER_GAME': + if context.engine != 'BLENDER_GAME': layout.prop(scene, "active_clip", text="Active Clip") class SCENE_PT_unit(SceneButtonsPanel, Panel): bl_label = "Units" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME', 'BLENDER_CLAY', 'BLENDER_EEVEE'} def draw(self, context): layout = self.layout @@ -166,7 +166,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_GAME', 'BLENDER_CLAY', 'BLENDER_EEVEE'} def draw(self, context): layout = self.layout @@ -199,7 +199,7 @@ 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'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME', 'BLENDER_CLAY', 'BLENDER_EEVEE'} @classmethod def poll(cls, context): @@ -256,7 +256,7 @@ 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_GAME', 'BLENDER_CLAY', 'BLENDER_EEVEE'} def draw(self, context): layout = self.layout @@ -281,7 +281,7 @@ class SCENE_PT_color_management(SceneButtonsPanel, Panel): class SCENE_PT_audio(SceneButtonsPanel, Panel): bl_label = "Audio" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME', 'BLENDER_CLAY', 'BLENDER_EEVEE'} def draw(self, context): layout = self.layout @@ -332,8 +332,7 @@ class SCENE_PT_rigid_body_world(SceneButtonsPanel, Panel): @classmethod def poll(cls, context): scene = context.scene - rd = scene.render - return scene and (rd.engine in cls.COMPAT_ENGINES) + return scene and (scene.view_render.engine in cls.COMPAT_ENGINES) def draw_header(self, context): scene = context.scene @@ -378,9 +377,9 @@ class SCENE_PT_rigid_body_cache(SceneButtonsPanel, Panel): @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) + view_render = scene.view_render + return scene and scene.rigidbody_world and (view_render.engine in cls.COMPAT_ENGINES) def draw(self, context): scene = context.scene @@ -396,9 +395,9 @@ class SCENE_PT_rigid_body_field_weights(SceneButtonsPanel, Panel): @classmethod def poll(cls, context): - rd = context.scene.render + view_render = context.scene.view_render scene = context.scene - return scene and scene.rigidbody_world and (rd.engine in cls.COMPAT_ENGINES) + return scene and scene.rigidbody_world and (view_render.engine in cls.COMPAT_ENGINES) def draw(self, context): scene = context.scene @@ -409,7 +408,7 @@ class SCENE_PT_rigid_body_field_weights(SceneButtonsPanel, Panel): class SCENE_PT_simplify(SceneButtonsPanel, Panel): bl_label = "Simplify" - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'} def draw_header(self, context): rd = context.scene.render @@ -439,7 +438,7 @@ class SCENE_PT_simplify(SceneButtonsPanel, Panel): class SCENE_PT_custom_props(SceneButtonsPanel, PropertyPanel, Panel): - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME', 'BLENDER_CLAY', 'BLENDER_EEVEE'} _context_path = "scene" _property_type = bpy.types.Scene diff --git a/release/scripts/startup/bl_ui/properties_texture.py b/release/scripts/startup/bl_ui/properties_texture.py index 25e9ef3ee73..01c36347b56 100644 --- a/release/scripts/startup/bl_ui/properties_texture.py +++ b/release/scripts/startup/bl_ui/properties_texture.py @@ -125,7 +125,7 @@ class TextureButtonsPanel: @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) class TEXTURE_PT_context_texture(TextureButtonsPanel, Panel): @@ -135,7 +135,7 @@ class TEXTURE_PT_context_texture(TextureButtonsPanel, Panel): @classmethod def poll(cls, context): - engine = context.scene.render.engine + engine = context.engine # if not (hasattr(context, "texture_slot") or hasattr(context, "texture_node")): # return False return ((context.material or @@ -292,7 +292,7 @@ class TextureSlotPanel(TextureButtonsPanel): if not hasattr(context, "texture_slot"): return False - engine = context.scene.render.engine + engine = context.engine return TextureButtonsPanel.poll(cls, context) and (engine in cls.COMPAT_ENGINES) @@ -304,7 +304,7 @@ 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)) @@ -459,7 +459,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") @@ -474,7 +474,7 @@ class TEXTURE_PT_image_sampling(TextureTypePanel, Panel): COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} def draw(self, context): - if context.scene.render.engine == 'BLENDER_GAME': + if context.engine == 'BLENDER_GAME': self.draw_bge(context) else: self.draw_bi(context) @@ -756,7 +756,7 @@ class TEXTURE_PT_voxeldata(TextureButtonsPanel, Panel): @classmethod def poll(cls, context): tex = context.texture - engine = context.scene.render.engine + engine = context.engine return tex and (tex.type == 'VOXEL_DATA' and (engine in cls.COMPAT_ENGINES)) def draw(self, context): @@ -799,7 +799,7 @@ class TEXTURE_PT_pointdensity(TextureButtonsPanel, Panel): @classmethod def poll(cls, context): tex = context.texture - engine = context.scene.render.engine + engine = context.engine return tex and (tex.type == 'POINT_DENSITY' and (engine in cls.COMPAT_ENGINES)) def draw(self, context): @@ -874,7 +874,7 @@ class TEXTURE_PT_pointdensity_turbulence(TextureButtonsPanel, Panel): @classmethod def poll(cls, context): tex = context.texture - engine = context.scene.render.engine + engine = context.engine return tex and (tex.type == 'POINT_DENSITY' and (engine in cls.COMPAT_ENGINES)) def draw_header(self, context): @@ -933,7 +933,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 +963,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="") @@ -1036,7 +1036,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): diff --git a/release/scripts/startup/bl_ui/properties_world.py b/release/scripts/startup/bl_ui/properties_world.py index 107c31567b3..e56a7977791 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,18 @@ 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 + view_render = context.scene.view_render + return view_render.engine in cls.COMPAT_ENGINES def draw(self, context): layout = self.layout @@ -68,8 +69,7 @@ class WORLD_PT_preview(WorldButtonsPanel, Panel): @classmethod def poll(cls, context): - rd = context.scene.render - return (context.world) and (rd.engine in cls.COMPAT_ENGINES) + return (context.world) and (context.engine in cls.COMPAT_ENGINES) def draw(self, context): self.layout.template_preview(context.world) @@ -244,11 +244,45 @@ class WORLD_PT_mist(WorldButtonsPanel, Panel): class WORLD_PT_custom_props(WorldButtonsPanel, PropertyPanel, Panel): - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME', 'BLENDER_EEVEE'} _context_path = "world" _property_type = bpy.types.World +class EEVEE_WORLD_PT_surface(WorldButtonsPanel, Panel): + bl_label = "Surface" + bl_context = "world" + COMPAT_ENGINES = {'BLENDER_EEVEE'} + + @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.prop(world, "use_nodes", icon='NODETREE') + layout.separator() + + if world.use_nodes: + ntree = world.node_tree + node = find_output_node(ntree, ('OUTPUT_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, @@ -259,6 +293,7 @@ classes = ( WORLD_PT_gather, WORLD_PT_mist, WORLD_PT_custom_props, + EEVEE_WORLD_PT_surface, ) if __name__ == "__main__": # only for live edit. diff --git a/release/scripts/startup/bl_ui/space_image.py b/release/scripts/startup/bl_ui/space_image.py index dbfbbad77b9..24d3ed5a0bf 100644 --- a/release/scripts/startup/bl_ui/space_image.py +++ b/release/scripts/startup/bl_ui/space_image.py @@ -481,7 +481,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: @@ -608,7 +608,7 @@ class IMAGE_PT_game_properties(Panel): 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') + return (sima and sima.image and not sima.show_maskedit) # and (view_render.engine == 'BLENDER_GAME') def draw(self, context): layout = self.layout diff --git a/release/scripts/startup/bl_ui/space_info.py b/release/scripts/startup/bl_ui/space_info.py index a7b518dfd2e..aa999e72f7d 100644 --- a/release/scripts/startup/bl_ui/space_info.py +++ b/release/scripts/startup/bl_ui/space_info.py @@ -28,25 +28,42 @@ class INFO_HT_header(Header): layout = self.layout window = context.window + workspace = context.workspace + screen = context.screen scene = context.scene - rd = scene.render + layer = context.render_layer + view_render = workspace.view_render row = layout.row(align=True) row.template_header() INFO_MT_editor_menus.draw_collapsible(context, layout) - if window.screen.show_fullscreen: + layout.separator() + + if 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.template_ID(window, "workspace", new="workspace.workspace_add_menu", unlink="workspace.workspace_delete") + layout.template_search_preview(window, "screen", workspace, "screens", new="screen.new", unlink="screen.delete", rows=2, cols=6) + + if hasattr(workspace, 'object_mode'): + act_mode_item = bpy.types.Object.bl_rna.properties['mode'].enum_items[workspace.object_mode] + else: + act_mode_item = bpy.types.Object.bl_rna.properties['mode'].enum_items[layer.objects.active.mode] + layout.operator_menu_enum("object.mode_set", "mode", text=act_mode_item.name, icon=act_mode_item.icon) + + row = layout.row() + row.active = not workspace.use_scene_settings + row.template_search(workspace, "render_layer", scene, "render_layers") + + if view_render.has_multiple_engines: + row.prop(view_render, "engine", text="") layout.separator() - if rd.has_multiple_engines: - layout.prop(rd, "engine", text="") + layout.template_ID(window, "scene", new="scene.new", unlink="scene.delete") layout.separator() @@ -69,7 +86,7 @@ class INFO_HT_header(Header): return row.operator("wm.splash", text="", icon='BLENDER', emboss=False) - row.label(text=scene.statistics(), translate=False) + row.label(text=scene.statistics(context.render_layer), translate=False) class INFO_MT_editor_menus(Menu): @@ -81,12 +98,11 @@ class INFO_MT_editor_menus(Menu): @staticmethod def draw_menus(layout, context): - scene = context.scene - rd = scene.render + view_render = context.view_render layout.menu("INFO_MT_file") - if rd.use_game_engine: + if view_render.use_game_engine: layout.menu("INFO_MT_game") else: layout.menu("INFO_MT_render") @@ -293,7 +309,7 @@ class INFO_MT_window(Menu): layout = self.layout - layout.operator("wm.window_duplicate") + layout.operator("wm.window_new") layout.operator("wm.window_fullscreen_toggle", icon='FULLSCREEN_ENTER') layout.separator() diff --git a/release/scripts/startup/bl_ui/space_node.py b/release/scripts/startup/bl_ui/space_node.py index 8f7d8f7555a..200fc415f8a 100644 --- a/release/scripts/startup/bl_ui/space_node.py +++ b/release/scripts/startup/bl_ui/space_node.py @@ -51,13 +51,14 @@ class NODE_HT_header(Header): NODE_MT_editor_menus.draw_collapsible(context, layout) layout.prop(snode, "tree_type", text="", expand=True) + use_shading_nodes = scene.view_render.use_shading_nodes or context.view_render.use_shading_nodes if snode.tree_type == 'ShaderNodeTree': - if scene.render.use_shading_nodes: + if use_shading_nodes: 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 (not use_shading_nodes or 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 @@ -69,17 +70,17 @@ class NODE_HT_header(Header): 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'): + if snode_id and not (use_shading_nodes == 0 and ob.type == 'LAMP'): layout.prop(snode_id, "use_nodes") - if scene.render.use_shading_nodes and snode.shader_type == 'WORLD': + if use_shading_nodes and 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': + if use_shading_nodes and snode.shader_type == 'LINESTYLE': rl = context.scene.render.layers.active lineset = rl.freestyle_settings.linesets.active if lineset is not None: @@ -395,8 +396,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 731ab3d4b14..dbd436b72c3 100644 --- a/release/scripts/startup/bl_ui/space_outliner.py +++ b/release/scripts/startup/bl_ui/space_outliner.py @@ -60,6 +60,16 @@ class OUTLINER_HT_header(Header): elif space.display_mode == 'ORPHAN_DATA': layout.operator("outliner.orphans_purge") + elif space.display_mode in {'ACT_LAYER', 'MASTER_COLLECTION'}: + row = layout.row(align=True) + + row.operator("outliner.collection_new", text="", icon='NEW') + if space.display_mode == 'ACT_LAYER': + row.operator("outliner.collection_override_new", text="", icon='LINK_AREA') + row.operator("outliner.collection_link", text="", icon='LINKED') + row.operator("outliner.collection_unlink", text="", icon='UNLINKED') + row.operator("outliner.collections_delete", text="", icon='X') + class OUTLINER_MT_editor_menus(Menu): bl_idname = "OUTLINER_MT_editor_menus" @@ -88,7 +98,8 @@ class OUTLINER_MT_view(Menu): space = context.space_data if space.display_mode not in {'DATABLOCKS', 'USER_PREFERENCES', 'KEYMAPS'}: - layout.prop(space, "use_sort_alpha") + if space.display_mode not in {'ACT_LAYER', 'MASTER_COLLECTION'}: + layout.prop(space, "use_sort_alpha") layout.prop(space, "show_restrict_columns") layout.separator() layout.operator("outliner.show_active") 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..bab25c3450b --- /dev/null +++ b/release/scripts/startup/bl_ui/space_toolsystem_common.py @@ -0,0 +1,131 @@ +# ##### 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 + +__all__ = ( + "ToolSelectPanelHelper", +) + + +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 all tools defined. + - tools_from_context(context): + Returns tools available in this context. + + Each tool is a triplet: + ``(tool_name, manipulator_group_idname, keymap_actions)`` + For a separator in the toolbar, use ``None``. + + Where: + ``tool_name`` + is the name to display in the interface. + ``manipulator_group_idname`` + is an optional manipulator group to activate when the tool is set. + ``keymap_actions`` + an optional triple of: ``(operator_id, operator_properties, keymap_item_args)`` + """ + + @classmethod + def _km_actionmouse_simple(cls, kc, text, actions): + + # 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) + + km_idname = cls.keymap_prefix + text + km = kc.keymaps.new(km_idname, space_type=cls.bl_space_type, region_type='WINDOW') + for op_idname, op_props_dict, kmi_kwargs in actions: + 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) + return km, km_idname + + @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 + + # {tool_name: (keymap, keymap_idname, manipulator_group_idname), ...} + cls._tool_keymap = {} + + # ignore in background mode + if kc is None: + return + + for t in cls.tools_all(): + text, mp_idname, actions = t + if actions is not None: + km, km_idname = cls._km_actionmouse_simple(kc, text, actions) + cls._tool_keymap[text] = km, km_idname + + def draw(self, 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. + + workspace = context.workspace + km_idname_active = workspace.tool_keymap or None + mp_idname_active = workspace.tool_manipulator_group or None + layout = self.layout + + for tool_items in self.tools_from_context(context): + if tool_items: + col = layout.box().column() + for item in tool_items: + if item is None: + col = layout.box().column() + continue + text, mp_idname, actions = item + + if actions is not None: + km, km_idname = self._tool_keymap[text] + else: + km = None + km_idname = None + + props = col.operator( + "wm.tool_set", + text=text, + emboss=( + km_idname_active == km_idname and + mp_idname_active == mp_idname + ), + ) + + props.keymap = km_idname or "" + props.manipulator_group = mp_idname or "" 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..71e41850a51 --- /dev/null +++ b/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py @@ -0,0 +1,148 @@ +# ##### 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, +) + + +class VIEW3D_PT_tools_active(ToolSelectPanelHelper, Panel): + bl_space_type = 'VIEW_3D' + bl_region_type = 'TOOLS' + bl_category = "Tools" + bl_label = "Active Tool (Test)" + bl_options = {'DEFAULT_CLOSED'} + + # Satisfy the 'ToolSelectPanelHelper' API. + keymap_prefix = "3D View Tool: " + + @classmethod + def tools_from_context(cls, context): + return (cls._tools[None], cls._tools.get(context.mode, ())) + + @classmethod + def tools_all(cls): + return [t for t_list in cls._tools.values() for t in t_list if t is not None] + + # Internal Data + + # for reuse + _tools_transform = ( + ("Translate", None, + (("transform.translate", dict(release_confirm=True), dict(type='EVT_TWEAK_A', value='ANY')),)), + ("Rotate", None, + (("transform.rotate", dict(release_confirm=True), dict(type='EVT_TWEAK_A', value='ANY')),)), + ("Scale", None, + (("transform.resize", dict(release_confirm=True), dict(type='EVT_TWEAK_A', value='ANY')),)), + ("Scale Cage", "VIEW3D_WGT_xform_cage", None), + ) + + _tools = { + None: [ + ("Cursor", None, + (("view3d.cursor3d", dict(), dict(type='ACTIONMOUSE', value='CLICK')),)), + ("Select Border", None, ( + ("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)), + )), + ("Select Circle", None, ( + ("view3d.select_circle", dict(deselect=False), dict(type='ACTIONMOUSE', value='PRESS')), + ("view3d.select_circle", dict(deselect=True), dict(type='ACTIONMOUSE', value='PRESS', ctrl=True)), + )), + ("Select Lasso", None, ( + ("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': [ + *_tools_transform, + ], + 'POSE': [ + *_tools_transform, + ], + 'EDIT_ARMATURE': [ + *_tools_transform, + ("Roll", None, ( + ("transform.transform", + dict(release_confirm=True, mode='BONE_ROLL'), + dict(type='EVT_TWEAK_A', value='ANY')), + )), + None, + ("Extrude Cursor", None, + (("armature.click_extrude", dict(), dict(type='ACTIONMOUSE', value='PRESS')),)), + ], + 'EDIT_MESH': [ + *_tools_transform, + None, + ("Rip Region", None, ( + ("mesh.rip_move", dict(TRANSFORM_OT_translate=dict(release_confirm=True)), + dict(type='ACTIONMOUSE', value='PRESS')), + )), + ("Rip Edge", None, ( + ("mesh.rip_edge_move", dict(TRANSFORM_OT_translate=dict(release_confirm=True)), + dict(type='ACTIONMOUSE', value='PRESS')), + )), + + ("Poly Build", None, ( + ("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)), + )), + + ("Knife", None, (("mesh.knife_tool", dict(wait_for_input=False), dict(type='ACTIONMOUSE', value='PRESS')),)), + ("Bisect", None, (("mesh.bisect", dict(), dict(type='EVT_TWEAK_A', value='ANY')),)), + ("Extrude Cursor", None, + (("mesh.dupli_extrude_cursor", dict(), dict(type='ACTIONMOUSE', value='PRESS')),)), + ], + 'EDIT_CURVE': [ + *_tools_transform, + None, + ("Draw", None, + (("curve.draw", dict(wait_for_input=False), dict(type='ACTIONMOUSE', value='PRESS')),)), + ("Extrude Cursor", None, + (("curve.vertex_add", dict(), dict(type='ACTIONMOUSE', value='PRESS')),)), + ], + } + + +classes = ( + 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_userpref.py b/release/scripts/startup/bl_ui/space_userpref.py index 5ba1f0b8dcb..571e924b4eb 100644 --- a/release/scripts/startup/bl_ui/space_userpref.py +++ b/release/scripts/startup/bl_ui/space_userpref.py @@ -57,7 +57,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': @@ -225,7 +227,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() @@ -286,11 +287,11 @@ 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.separator() col.separator() @@ -909,7 +910,7 @@ class USERPREF_PT_theme(Panel): col.separator() col.separator() - col.label("Axis Colors:") + col.label("Axis & Manipulator Colors:") row = col.row() @@ -927,9 +928,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 c7e05a4173e..d449dd20c3e 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -301,6 +301,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): @@ -451,7 +457,6 @@ class VIEW3D_MT_view(Menu): layout.operator("view3d.view_selected", text="View 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.separator() @@ -664,12 +669,8 @@ class VIEW3D_MT_select_object(Menu): 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_menu_enum("object.select_by_type", "type", text="Select All by Type...") layout.operator("object.select_camera", text="Select Camera") @@ -1278,6 +1279,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,6 +1338,8 @@ class INFO_MT_add(Menu): layout.menu("INFO_MT_lamp_add", icon='OUTLINER_OB_LAMP') layout.separator() + layout.menu("INFO_MT_lightprobe_add") + layout.separator() layout.operator_menu_enum("object.effector_add", "type", text="Force Field", icon='OUTLINER_OB_FORCE_FIELD') layout.separator() @@ -1384,8 +1398,6 @@ 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") @@ -1411,13 +1423,6 @@ 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.menu("VIEW3D_MT_object_relations") @@ -1438,8 +1443,6 @@ class VIEW3D_MT_object(Menu): layout.separator() - layout.menu("VIEW3D_MT_object_showhide") - layout.operator_menu_enum("object.convert", "target") @@ -1548,8 +1551,9 @@ class VIEW3D_MT_object_specials(Menu): lamp = obj.data layout.operator_context = 'INVOKE_REGION_WIN' + use_shading_nodes = context.view_render.use_shading_nodes - if scene.render.use_shading_nodes: + if use_shading_nodes: try: value = lamp.node_tree.nodes["Emission"].inputs["Strength"].default_value except AttributeError: @@ -1607,7 +1611,7 @@ class VIEW3D_MT_object_specials(Menu): props.input_scale = -0.01 props.header_text = "Spot Blend: %.2f" - if not scene.render.use_shading_nodes: + if not 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" @@ -1752,20 +1756,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" @@ -3481,6 +3471,9 @@ class VIEW3D_PT_view3d_display(Panel): col.prop(view, "show_only_render") col.prop(view, "show_world") + if context.mode in {'PAINT_WEIGHT', 'PAINT_VERTEX', 'PAINT_TEXTURE'}: + col.prop(view, "show_mode_shade_override") + col = layout.column() display_all = not view.show_only_render col.active = display_all @@ -3564,56 +3557,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' @@ -3780,113 +3723,6 @@ class VIEW3D_PT_view3d_curvedisplay(Panel): 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): bl_space_type = 'VIEW_3D' bl_region_type = 'UI' @@ -4056,6 +3892,7 @@ 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, @@ -4070,7 +3907,6 @@ classes = ( VIEW3D_MT_object_group, 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, @@ -4141,12 +3977,10 @@ classes = ( VIEW3D_PT_view3d_name, VIEW3D_PT_view3d_display, 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_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 12f15b8b90e..134a91a8c1f 100644 --- a/release/scripts/startup/bl_ui/space_view3d_toolbar.py +++ b/release/scripts/startup/bl_ui/space_view3d_toolbar.py @@ -1199,7 +1199,7 @@ 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'}: + if (not mat.use_nodes) and context.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': @@ -1213,9 +1213,9 @@ 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 @@ -1262,7 +1262,7 @@ 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'}: + if (not mat.use_nodes) and context.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') @@ -1273,11 +1273,11 @@ class VIEW3D_PT_slots_projectpaint(View3DPanel, Panel): if slot and slot.index != -1: 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") @@ -1315,8 +1315,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:") @@ -1934,9 +1934,9 @@ 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 diff --git a/release/scripts/startup/nodeitems_builtins.py b/release/scripts/startup/nodeitems_builtins.py index bee6ae80590..45a9db8f951 100644 --- a/release/scripts/startup/nodeitems_builtins.py +++ b/release/scripts/startup/nodeitems_builtins.py @@ -47,14 +47,14 @@ class ShaderNewNodeCategory(SortedNodeCategory): @classmethod def poll(cls, context): return (context.space_data.tree_type == 'ShaderNodeTree' and - context.scene.render.use_shading_nodes) + context.view_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) + not context.view_render.use_shading_nodes) class TextureNodeCategory(SortedNodeCategory): @@ -141,6 +141,34 @@ def object_shader_nodes_poll(context): snode.shader_type == 'OBJECT') +def cycles_shader_nodes_poll(context): + return context.view_render.engine == 'CYCLES' + + +def eevee_shader_nodes_poll(context): + return context.view_render.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 = [ @@ -216,33 +244,34 @@ shader_node_categories = [ 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), + 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), + 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_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_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("ShaderNodeEeveeSpecular", poll=object_eevee_shader_nodes_poll), ]), ShaderNewNodeCategory("SH_NEW_TEXTURE", "Texture", items=[ NodeItem("ShaderNodeTexImage"), diff --git a/release/scripts/templates_py/batch_export.py b/release/scripts/templates_py/batch_export.py index 6c77c5d6a1a..8de7a5e2903 100644 --- a/release/scripts/templates_py/batch_export.py +++ b/release/scripts/templates_py/batch_export.py @@ -18,7 +18,7 @@ bpy.ops.object.select_all(action='DESELECT') for obj in selection: - obj.select = True + obj.select_set(action='SELECT') # some exporters only use the active object scene.objects.active = obj @@ -31,7 +31,7 @@ for obj in selection: ## Can be used for multiple formats # bpy.ops.export_scene.x3d(filepath=fn + ".x3d", use_selection=True) - obj.select = False + obj.select_set(action='DESELECT') print("written:", fn) @@ -39,4 +39,4 @@ for obj in selection: scene.objects.active = obj_active for obj in selection: - obj.select = True + obj.select_set(action='SELECT') diff --git a/release/scripts/templates_py/manipulator_custom_geometry.py b/release/scripts/templates_py/manipulator_custom_geometry.py new file mode 100644 index 00000000000..0f1ab72f9ef --- /dev/null +++ b/release/scripts/templates_py/manipulator_custom_geometry.py @@ -0,0 +1,158 @@ +# Example of a custom widget that defines it's own geometry. +# +# Usage: Select a lamp in the 3D view and drag the arrow at it's rear +# to change it's energy value. +# +import bpy +from bpy.types import ( + Manipulator, + ManipulatorGroup, +) + +# Coordinates (each one is a triangle). +custom_shape_verts = ( + (3.0, 1.0, -1.0), (2.0, 2.0, -1.0), (3.0, 3.0, -1.0), + (1.0, 3.0, 1.0), (3.0, 3.0, -1.0), (1.0, 3.0, -1.0), + (3.0, 3.0, 1.0), (3.0, 1.0, -1.0), (3.0, 3.0, -1.0), + (2.0, 0.0, 1.0), (3.0, 1.0, -1.0), (3.0, 1.0, 1.0), + (2.0, 0.0, -1.0), (2.0, 2.0, 1.0), (2.0, 2.0, -1.0), + (2.0, 2.0, -1.0), (0.0, 2.0, 1.0), (0.0, 2.0, -1.0), + (1.0, 3.0, 1.0), (2.0, 2.0, 1.0), (3.0, 3.0, 1.0), + (0.0, 2.0, -1.0), (1.0, 3.0, 1.0), (1.0, 3.0, -1.0), + (2.0, 2.0, 1.0), (3.0, 1.0, 1.0), (3.0, 3.0, 1.0), + (2.0, 2.0, -1.0), (1.0, 3.0, -1.0), (3.0, 3.0, -1.0), + (-3.0, -1.0, -1.0), (-2.0, -2.0, -1.0), (-3.0, -3.0, -1.0), + (-1.0, -3.0, 1.0), (-3.0, -3.0, -1.0), (-1.0, -3.0, -1.0), + (-3.0, -3.0, 1.0), (-3.0, -1.0, -1.0), (-3.0, -3.0, -1.0), + (-2.0, 0.0, 1.0), (-3.0, -1.0, -1.0), (-3.0, -1.0, 1.0), + (-2.0, 0.0, -1.0), (-2.0, -2.0, 1.0), (-2.0, -2.0, -1.0), + (-2.0, -2.0, -1.0), (0.0, -2.0, 1.0), (0.0, -2.0, -1.0), + (-1.0, -3.0, 1.0), (-2.0, -2.0, 1.0), (-3.0, -3.0, 1.0), + (0.0, -2.0, -1.0), (-1.0, -3.0, 1.0), (-1.0, -3.0, -1.0), + (-2.0, -2.0, 1.0), (-3.0, -1.0, 1.0), (-3.0, -3.0, 1.0), + (-2.0, -2.0, -1.0), (-1.0, -3.0, -1.0), (-3.0, -3.0, -1.0), + (1.0, -1.0, 0.0), (-1.0, -1.0, 0.0), (0.0, 0.0, -5.0), + (-1.0, -1.0, 0.0), (1.0, -1.0, 0.0), (0.0, 0.0, 5.0), + (1.0, -1.0, 0.0), (1.0, 1.0, 0.0), (0.0, 0.0, 5.0), + (1.0, 1.0, 0.0), (-1.0, 1.0, 0.0), (0.0, 0.0, 5.0), + (-1.0, 1.0, 0.0), (-1.0, -1.0, 0.0), (0.0, 0.0, 5.0), + (-1.0, -1.0, 0.0), (-1.0, 1.0, 0.0), (0.0, 0.0, -5.0), + (-1.0, 1.0, 0.0), (1.0, 1.0, 0.0), (0.0, 0.0, -5.0), + (1.0, 1.0, 0.0), (1.0, -1.0, 0.0), (0.0, 0.0, -5.0), + (3.0, 1.0, -1.0), (2.0, 0.0, -1.0), (2.0, 2.0, -1.0), + (1.0, 3.0, 1.0), (3.0, 3.0, 1.0), (3.0, 3.0, -1.0), + (3.0, 3.0, 1.0), (3.0, 1.0, 1.0), (3.0, 1.0, -1.0), + (2.0, 0.0, 1.0), (2.0, 0.0, -1.0), (3.0, 1.0, -1.0), + (2.0, 0.0, -1.0), (2.0, 0.0, 1.0), (2.0, 2.0, 1.0), + (2.0, 2.0, -1.0), (2.0, 2.0, 1.0), (0.0, 2.0, 1.0), + (1.0, 3.0, 1.0), (0.0, 2.0, 1.0), (2.0, 2.0, 1.0), + (0.0, 2.0, -1.0), (0.0, 2.0, 1.0), (1.0, 3.0, 1.0), + (2.0, 2.0, 1.0), (2.0, 0.0, 1.0), (3.0, 1.0, 1.0), + (2.0, 2.0, -1.0), (0.0, 2.0, -1.0), (1.0, 3.0, -1.0), + (-3.0, -1.0, -1.0), (-2.0, 0.0, -1.0), (-2.0, -2.0, -1.0), + (-1.0, -3.0, 1.0), (-3.0, -3.0, 1.0), (-3.0, -3.0, -1.0), + (-3.0, -3.0, 1.0), (-3.0, -1.0, 1.0), (-3.0, -1.0, -1.0), + (-2.0, 0.0, 1.0), (-2.0, 0.0, -1.0), (-3.0, -1.0, -1.0), + (-2.0, 0.0, -1.0), (-2.0, 0.0, 1.0), (-2.0, -2.0, 1.0), + (-2.0, -2.0, -1.0), (-2.0, -2.0, 1.0), (0.0, -2.0, 1.0), + (-1.0, -3.0, 1.0), (0.0, -2.0, 1.0), (-2.0, -2.0, 1.0), + (0.0, -2.0, -1.0), (0.0, -2.0, 1.0), (-1.0, -3.0, 1.0), + (-2.0, -2.0, 1.0), (-2.0, 0.0, 1.0), (-3.0, -1.0, 1.0), + (-2.0, -2.0, -1.0), (0.0, -2.0, -1.0), (-1.0, -3.0, -1.0), +) + + +class MyCustomShapeWidget(Manipulator): + bl_idname = "VIEW3D_WT_auto_facemap" + bl_target_properties = ( + {"id": "offset", "type": 'FLOAT', "array_length": 1}, + ) + + __slots__ = ( + "custom_shape", + "init_mouse_y", + "init_value", + ) + + def _update_offset_matrix(self): + # offset behind the lamp + self.matrix_offset.col[3][2] = self.target_get_value("offset") / -10.0 + + def draw(self, context): + self._update_offset_matrix() + self.draw_custom_shape(self.custom_shape) + + def draw_select(self, context, select_id): + self._update_offset_matrix() + self.draw_custom_shape(self.custom_shape, select_id=select_id) + + def setup(self): + if not hasattr(self, "custom_shape"): + self.custom_shape = self.new_custom_shape('TRIS', custom_shape_verts) + + def invoke(self, context, event): + self.init_mouse_y = event.mouse_y + self.init_value = self.target_get_value("offset") + return {'RUNNING_MODAL'} + + def exit(self, context, cancel): + context.area.header_text_set() + if cancel: + self.target_set_value("offset", self.init_value) + + def modal(self, context, event, tweak): + delta = (event.mouse_y - self.init_mouse_y) / 10.0 + if 'SNAP' in tweak: + delta = round(delta) + if 'PRECISE' in tweak: + delta /= 10.0 + value = self.init_value + delta + self.target_set_value("offset", value) + context.area.header_text_set("My Manipulator: %.4f" % value) + return {'RUNNING_MODAL'} + + +class MyCustomShapeWidgetGroup(ManipulatorGroup): + bl_idname = "OBJECT_WGT_lamp_test" + bl_label = "Test Lamp Widget" + bl_space_type = 'VIEW_3D' + bl_region_type = 'WINDOW' + bl_options = {'3D', 'PERSISTENT'} + + @classmethod + def poll(cls, context): + ob = context.object + return (ob and ob.type == 'LAMP') + + def setup(self, context): + # Assign the 'offset' target property to the lamp energy. + ob = context.object + mpr = self.manipulators.new(MyCustomShapeWidget.bl_idname) + mpr.target_set_prop("offset", ob.data, "energy") + mpr.matrix_basis = ob.matrix_world.normalized() + + mpr.color = 1.0, 0.5, 1.0 + mpr.alpha = 0.5 + + mpr.color_highlight = 1.0, 0.5, 1.0 + mpr.alpha_highlight = 0.5 + + # units are large, so shrink to something more reasonable. + mpr.scale_basis = 0.1 + mpr.use_draw_modal = True + + self.energy_widget = mpr + + def refresh(self, context): + ob = context.object + mpr = self.energy_widget + mpr.matrix_basis = ob.matrix_world.normalized() + + +classes = ( + MyCustomShapeWidget, + MyCustomShapeWidgetGroup, +) + +for cls in classes: + bpy.utils.register_class(cls) diff --git a/release/scripts/templates_py/manipulator_operator.py b/release/scripts/templates_py/manipulator_operator.py new file mode 100644 index 00000000000..00b24736b8e --- /dev/null +++ b/release/scripts/templates_py/manipulator_operator.py @@ -0,0 +1,231 @@ +# Example of an operator which uses manipulators to control its properties. +# +# Usage: Run this script, then in mesh edit-mode press Spacebar +# to activate the operator "Select Side of Plane" +# The manipulators can then be used to adjust the plane in the 3D view. +# +import bpy +import bmesh + +from bpy.types import ( + Operator, + ManipulatorGroup, +) + +from bpy.props import ( + FloatVectorProperty, +) + +def main(context, plane_co, plane_no): + obj = context.active_object + matrix = obj.matrix_world.copy() + me = obj.data + bm = bmesh.from_edit_mesh(me) + + plane_dot = plane_no.dot(plane_co) + + for v in bm.verts: + co = matrix * v.co + v.select = (plane_no.dot(co) > plane_dot) + bm.select_flush_mode() + + bmesh.update_edit_mesh(me) + + +class SelectSideOfPlane(Operator): + """UV Operator description""" + bl_idname = "mesh.select_side_of_plane" + bl_label = "Select Side of Plane" + bl_options = {'REGISTER', 'UNDO'} + + plane_co = FloatVectorProperty( + size=3, + default=(0, 0, 0), + ) + plane_no = FloatVectorProperty( + size=3, + default=(0, 0, 1), + ) + + @classmethod + def poll(cls, context): + return (context.mode == 'EDIT_MESH') + + def invoke(self, context, event): + + if not self.properties.is_property_set("plane_co"): + self.plane_co = context.scene.cursor_location + + if not self.properties.is_property_set("plane_no"): + if context.space_data.type == 'VIEW_3D': + rv3d = context.space_data.region_3d + view_inv = rv3d.view_matrix.to_3x3() + # view y axis + self.plane_no = view_inv[1].normalized() + + self.execute(context) + + if context.space_data.type == 'VIEW_3D': + wm = context.window_manager + wm.manipulator_group_type_add(SelectSideOfPlaneManipulatorGroup.bl_idname) + + return {'FINISHED'} + + def execute(self, context): + from mathutils import Vector + main(context, Vector(self.plane_co), Vector(self.plane_no)) + return {'FINISHED'} + + +# Manipulators for plane_co, plane_no +class SelectSideOfPlaneManipulatorGroup(ManipulatorGroup): + bl_idname = "MESH_WGT_select_side_of_plane" + bl_label = "Side of Plane Manipulator" + bl_space_type = 'VIEW_3D' + bl_region_type = 'WINDOW' + bl_options = {'3D'} + + # Helper functions + @staticmethod + def my_target_operator(context): + wm = context.window_manager + op = wm.operators[-1] if wm.operators else None + if isinstance(op, SelectSideOfPlane): + return op + return None + + @staticmethod + def my_view_orientation(context): + rv3d = context.space_data.region_3d + view_inv = rv3d.view_matrix.to_3x3() + return view_inv.normalized() + + @classmethod + def poll(cls, context): + op = cls.my_target_operator(context) + if op is None: + wm = context.window_manager + wm.manipulator_group_type_remove(SelectSideOfPlaneManipulatorGroup.bl_idname) + return False + return True + + def setup(self, context): + from mathutils import Matrix, Vector + + # ---- + # Grab + + def grab_get_cb(): + op = SelectSideOfPlaneManipulatorGroup.my_target_operator(context) + return op.plane_co + + def grab_set_cb(value): + op = SelectSideOfPlaneManipulatorGroup.my_target_operator(context) + op.plane_co = value + # XXX, this may change! + op.execute(context) + + mpr = self.manipulators.new("MANIPULATOR_WT_grab_3d") + mpr.target_set_handler("offset", get=grab_get_cb, set=grab_set_cb) + + mpr.use_draw_value = True + + mpr.color = 0.8, 0.8, 0.8 + mpr.alpha = 0.5 + + mpr.color_highlight = 1.0, 1.0, 1.0 + mpr.alpha_highlight = 1.0 + + mpr.scale_basis = 0.2 + + self.widget_grab = mpr + + # ---- + # Dial + + def direction_get_cb(): + op = SelectSideOfPlaneManipulatorGroup.my_target_operator(context) + + no_a = self.widget_dial.matrix_basis.col[1].xyz + no_b = Vector(op.plane_no) + + no_a = (no_a * self.view_inv).xy.normalized() + no_b = (no_b * self.view_inv).xy.normalized() + return no_a.angle_signed(no_b) + + def direction_set_cb(value): + op = SelectSideOfPlaneManipulatorGroup.my_target_operator(context) + matrix_rotate = Matrix.Rotation(-value, 3, self.rotate_axis) + no = matrix_rotate * self.widget_dial.matrix_basis.col[1].xyz + op.plane_no = no + op.execute(context) + + mpr = self.manipulators.new("MANIPULATOR_WT_dial_3d") + mpr.target_set_handler("offset", get=direction_get_cb, set=direction_set_cb) + mpr.draw_options = {'ANGLE_START_Y'} + + mpr.use_draw_value = True + + mpr.color = 0.8, 0.8, 0.8 + mpr.alpha = 0.5 + + mpr.color_highlight = 1.0, 1.0, 1.0, 1.0 + mpr.alpha_highlight = 1.0 + + self.widget_dial = mpr + + def draw_prepare(self, context): + from mathutils import Vector + + view_inv = self.my_view_orientation(context) + + self.view_inv = view_inv + self.rotate_axis = view_inv[2].xyz + self.rotate_up = view_inv[1].xyz + + op = self.my_target_operator(context) + + co = Vector(op.plane_co) + no = Vector(op.plane_no).normalized() + + # Grab + no_z = no + no_y = no_z.orthogonal() + no_x = no_z.cross(no_y) + + matrix = self.widget_grab.matrix_basis + matrix.identity() + matrix.col[0].xyz = no_x + matrix.col[1].xyz = no_y + matrix.col[2].xyz = no_z + matrix.col[3].xyz = co + + # Dial + no_z = self.rotate_axis + no_y = (no - (no.project(no_z))).normalized() + no_x = self.rotate_axis.cross(no_y) + + matrix = self.widget_dial.matrix_basis + matrix.identity() + matrix.col[0].xyz = no_x + matrix.col[1].xyz = no_y + matrix.col[2].xyz = no_z + matrix.col[3].xyz = co + + +classes = ( + SelectSideOfPlane, + SelectSideOfPlaneManipulatorGroup, +) + +def register(): + for cls in classes: + bpy.utils.register_class(cls) + + +def unregister(): + for cls in reversed(classes): + bpy.utils.unregister_class(cls) + +if __name__ == "__main__": + register() diff --git a/release/scripts/templates_py/manipulator_operator_target.py b/release/scripts/templates_py/manipulator_operator_target.py new file mode 100644 index 00000000000..0abf6f2f654 --- /dev/null +++ b/release/scripts/templates_py/manipulator_operator_target.py @@ -0,0 +1,48 @@ +# Example of a manipulator that activates an operator +# using the predefined dial manipulator to change the camera roll. +# +# Usage: Run this script and select a camera in the 3D view. +# +import bpy +from bpy.types import ( + ManipulatorGroup, +) + +class MyCameraWidgetGroup(ManipulatorGroup): + bl_idname = "OBJECT_WGT_test_camera" + bl_label = "Object Camera Test Widget" + bl_space_type = 'VIEW_3D' + bl_region_type = 'WINDOW' + bl_options = {'3D', 'PERSISTENT'} + + @classmethod + def poll(cls, context): + ob = context.object + return (ob and ob.type == 'CAMERA') + + def setup(self, context): + # Run an operator using the dial manipulator + ob = context.object + mpr = self.manipulators.new("MANIPULATOR_WT_dial_3d") + props = mpr.target_set_operator("transform.rotate") + props.constraint_axis = False, False, True + props.constraint_orientation = 'LOCAL' + props.release_confirm = True + + mpr.matrix_basis = ob.matrix_world.normalized() + mpr.line_width = 3 + + mpr.color = 0.8, 0.8, 0.8 + mpr.alpha = 0.5 + + mpr.color_highlight = 1.0, 1.0, 1.0 + mpr.alpha_highlight = 1.0 + + self.roll_widget = mpr + + def refresh(self, context): + ob = context.object + mpr = self.roll_widget + mpr.matrix_basis = ob.matrix_world.normalized() + +bpy.utils.register_class(MyCameraWidgetGroup) diff --git a/release/scripts/templates_py/manipulator_simple.py b/release/scripts/templates_py/manipulator_simple.py new file mode 100644 index 00000000000..7e02940d527 --- /dev/null +++ b/release/scripts/templates_py/manipulator_simple.py @@ -0,0 +1,45 @@ +# Example of a group that edits a single property +# using the predefined manipulator arrow. +# +# Usage: Select a lamp in the 3D view and drag the arrow at it's rear +# to change it's energy value. +# +import bpy +from bpy.types import ( + ManipulatorGroup, +) + +class MyLampWidgetGroup(ManipulatorGroup): + bl_idname = "OBJECT_WGT_lamp_test" + bl_label = "Test Lamp Widget" + bl_space_type = 'VIEW_3D' + bl_region_type = 'WINDOW' + bl_options = {'3D', 'PERSISTENT'} + + @classmethod + def poll(cls, context): + ob = context.object + return (ob and ob.type == 'LAMP') + + def setup(self, context): + # Arrow manipulator has one 'offset' property we can assign to the lamp energy. + ob = context.object + mpr = self.manipulators.new("MANIPULATOR_WT_arrow_3d") + mpr.target_set_prop("offset", ob.data, "energy") + mpr.matrix_basis = ob.matrix_world.normalized() + mpr.draw_style = 'BOX' + + mpr.color = 1.0, 0.5, 0.0 + mpr.alpha = 0.5 + + mpr.color_highlight = 1.0, 0.5, 1.0 + mpr.alpha_highlight = 0.5 + + self.energy_widget = mpr + + def refresh(self, context): + ob = context.object + mpr = self.energy_widget + mpr.matrix_basis = ob.matrix_world.normalized() + +bpy.utils.register_class(MyLampWidgetGroup) diff --git a/release/scripts/templates_py/operator_modal_view3d_raycast.py b/release/scripts/templates_py/operator_modal_view3d_raycast.py index c4d661b4c1f..e3b63813fc4 100644 --- a/release/scripts/templates_py/operator_modal_view3d_raycast.py +++ b/release/scripts/templates_py/operator_modal_view3d_raycast.py @@ -67,7 +67,7 @@ def main(context, event): # now we have the object under the mouse cursor, # we could do lots of stuff but for the example just select. if best_obj is not None: - best_obj.select = True + best_obj.select_set(action='SELECT') context.scene.objects.active = best_obj |