diff options
author | Julian Eisel <eiseljulian@gmail.com> | 2019-09-02 16:57:33 +0300 |
---|---|---|
committer | Julian Eisel <eiseljulian@gmail.com> | 2019-09-02 16:57:33 +0300 |
commit | 8f976022ffec50a595c147f83e7c31b1b922266a (patch) | |
tree | 21307afdd0e50acc515603365048d147de34a5ae | |
parent | e653d29b9a2e8c2e143a34e556101012e88fe927 (diff) | |
parent | f4128711758e92a755001e51a88d3d4f67100974 (diff) |
Merge commit 'f4128711758e92a755001e51a88d3d4f67100974' into filebrowser_redesign
29 files changed, 2736 insertions, 1873 deletions
diff --git a/io_import_images_as_planes.py b/io_import_images_as_planes.py index 742623cb..c707c0af 100644 --- a/io_import_images_as_planes.py +++ b/io_import_images_as_planes.py @@ -21,7 +21,7 @@ bl_info = { "name": "Import Images as Planes", "author": "Florian Meyer (tstscr), mont29, matali, Ted Schundler (SpkyElctrc)", - "version": (3, 3, 0), + "version": (3, 3, 1), "blender": (2, 80, 0), "location": "File > Import > Images as Planes or Add > Mesh > Images as Planes", "description": "Imports images and creates planes with the appropriate aspect ratio. " @@ -1021,7 +1021,16 @@ class IMPORT_IMAGE_OT_to_plane(Operator, AddObjectHelper): node_tree.links.new(core_shader.inputs[0], tex_image.outputs[0]) if self.use_transparency: - node_tree.links.new(core_shader.inputs[18], tex_image.outputs[1]) + if self.shader == 'PRINCIPLED': + node_tree.links.new(core_shader.inputs[18], tex_image.outputs[1]) + else: + bsdf_transparent = node_tree.nodes.new('ShaderNodeBsdfTransparent') + + mix_shader = node_tree.nodes.new('ShaderNodeMixShader') + node_tree.links.new(mix_shader.inputs[0], tex_image.outputs[1]) + node_tree.links.new(mix_shader.inputs[1], bsdf_transparent.outputs[0]) + node_tree.links.new(mix_shader.inputs[2], core_shader.outputs[0]) + core_shader = mix_shader node_tree.links.new(out_node.inputs[0], core_shader.outputs[0]) diff --git a/io_scene_fbx/__init__.py b/io_scene_fbx/__init__.py index 249cb0d2..df43f68b 100644 --- a/io_scene_fbx/__init__.py +++ b/io_scene_fbx/__init__.py @@ -21,7 +21,7 @@ bl_info = { "name": "FBX format", "author": "Campbell Barton, Bastien Montagne, Jens Restemeier", - "version": (4, 15, 0), + "version": (4, 15, 1), "blender": (2, 80, 0), "location": "File > Import-Export", "description": "FBX IO meshes, UV's, vertex colors, materials, textures, cameras, lamps and actions", diff --git a/io_scene_fbx/import_fbx.py b/io_scene_fbx/import_fbx.py index 90c27e5b..c63cc0db 100644 --- a/io_scene_fbx/import_fbx.py +++ b/io_scene_fbx/import_fbx.py @@ -649,7 +649,9 @@ def blen_read_animations_action_item(action, item, cnodes, fps, anim_offset): bl_obj = item.bl_obj transform_data = item.fbx_transform_data - rot_prev = bl_obj.rotation_euler.copy() + rot_eul_prev = bl_obj.rotation_euler.copy() + rot_quat_prev = bl_obj.rotation_quaternion.copy() + # Pre-compute inverted local rest matrix of the bone, if relevant. restmat_inv = item.get_bind_matrix().inverted_safe() if item.is_bone else None @@ -683,13 +685,15 @@ def blen_read_animations_action_item(action, item, cnodes, fps, anim_offset): # Now we have a virtual matrix of transform from AnimCurves, we can insert keyframes! loc, rot, sca = mat.decompose() if rot_mode == 'QUATERNION': - pass # nothing to do! + if rot_quat_prev.dot(rot) < 0.0: + rot = -rot + rot_quat_prev = rot elif rot_mode == 'AXIS_ANGLE': vec, ang = rot.to_axis_angle() rot = ang, vec.x, vec.y, vec.z else: # Euler - rot = rot.to_euler(rot_mode, rot_prev) - rot_prev = rot + rot = rot.to_euler(rot_mode, rot_eul_prev) + rot_eul_prev = rot for fc, value in zip(blen_curves, chain(loc, rot, sca)): fc.keyframe_points.insert(frame, value, options={'NEEDED', 'FAST'}).interpolation = 'LINEAR' diff --git a/io_scene_gltf2/__init__.py b/io_scene_gltf2/__init__.py index 66d09a44..0ad64def 100755 --- a/io_scene_gltf2/__init__.py +++ b/io_scene_gltf2/__init__.py @@ -15,7 +15,7 @@ bl_info = { 'name': 'glTF 2.0 format', 'author': 'Julien Duroure, Norbert Nopper, Urs Hanselmann, Moritz Becher, Benjamin Schmithüsen, Jim Eckerlein, and many external contributors', - "version": (0, 9, 53), + "version": (0, 9, 54), 'blender': (2, 80, 0), 'location': 'File > Import-Export', 'description': 'Import-Export as glTF 2.0', diff --git a/io_scene_gltf2/blender/exp/gltf2_blender_gather_animation_channels.py b/io_scene_gltf2/blender/exp/gltf2_blender_gather_animation_channels.py index 45a75717..8eefafd4 100755 --- a/io_scene_gltf2/blender/exp/gltf2_blender_gather_animation_channels.py +++ b/io_scene_gltf2/blender/exp/gltf2_blender_gather_animation_channels.py @@ -187,10 +187,11 @@ def __get_channel_groups(blender_action: bpy.types.Action, blender_object: bpy.t else: try: target = gltf2_blender_get.get_object_from_datapath(blender_object, object_path) - if blender_object.type == "MESH": + if blender_object.type == "MESH" and object_path.startswith("key_blocks"): shape_key = blender_object.data.shape_keys.path_resolve(object_path) if shape_key.mute is True: continue + target = blender_object.data.shape_keys except ValueError as e: # if the object is a mesh and the action target path can not be resolved, we know that this is a morph # animation. diff --git a/render_povray/__init__.py b/render_povray/__init__.py index 0551e2eb..82f96470 100644 --- a/render_povray/__init__.py +++ b/render_povray/__init__.py @@ -529,7 +529,7 @@ class RenderPovSettingsScene(PropertyGroup): name="Nearest Count", description="Number of old ambient values blended together to " "create a new interpolated value", - min=1, max=20, default=5) + min=1, max=20, default=1) radio_normal: BoolProperty( name="Normals", description="Radiosity estimation can be affected by normals", @@ -990,6 +990,11 @@ class RenderPovSettingsMaterial(PropertyGroup): name="Alpha", description="Alpha transparency of the material", min=0.0, max=1.0, soft_min=0.0, soft_max=1.0, default=1.0, precision=3) + + specular_alpha: FloatProperty( + name="Specular alpha", + description="Alpha transparency for specular areas", + min=0.0, max=1.0, soft_min=0.0, soft_max=1.0, default=1.0, precision=3) ambient: FloatProperty( name="Ambient", @@ -1409,8 +1414,8 @@ class RenderPovSettingsMaterial(PropertyGroup): refraction_type: EnumProperty( items=[ - ("1", "Fake Caustics", "use fake caustics"), - ("2", "Photons Caustics", "use photons for refractive caustics")], + ("1", "Z Transparency Fake Caustics", "use fake caustics"), + ("2", "Raytrace Photons Caustics", "use photons for refractive caustics")], name="Refraction Type:", description="use fake caustics (fast) or true photons for refractive Caustics", default="1") @@ -1709,15 +1714,66 @@ class MaterialSubsurfaceScattering(PropertyGroup): name="Texture", description="Texture scattering blend factor", min=0.0, max=1.0, soft_min=0.0, soft_max=1.0, default=0.0, precision=3) - + +class MaterialStrandSettings(PropertyGroup): + bl_description = "Strand settings for the material", + + blend_distance: FloatProperty( + name="Distance", + description="Worldspace distance over which to blend in the surface normal", + min=0.0, max=10.0, soft_min=0.0, soft_max=10.0, default=0.0, precision=3) + + root_size: FloatProperty( + name="Root", + description="Start size of strands in pixels or Blender units", + min=0.25, default=1.0, precision=5) + + shape: FloatProperty( + name="Shape", + description="Positive values make strands rounder, negative ones make strands spiky", + min=-0.9, max=0.9, default=0.0, precision=3) + + size_min: FloatProperty( + name="Minimum", + description="Minimum size of strands in pixels", + min=0.001, max=10.0, default=1.0, precision=3) + + tip_size: FloatProperty( + name="Tip", + description="End size of strands in pixels or Blender units", + min=0.0, default=1.0, precision=5) + + use_blender_units: BoolProperty( + name="Blender Units", + description="Use Blender units for widths instead of pixels", + default=False) + + use_surface_diffuse: BoolProperty( + name="Surface diffuse", + description="Make diffuse shading more similar to shading the surface", + default=False) + + use_tangent_shading: BoolProperty( + name="Tangent Shading", + description="Use direction of strands as normal for tangent-shading", + default=True) + + uv_layer: StringProperty( + name="UV Layer", + #icon="GROUP_UVS", + description="Name of UV map to override", + default="") + + width_fade: FloatProperty( + name="Width Fade", + description="Transparency along the width of the strand", + min=0.0, max=2.0, default=0.0, precision=3) + + # halo # Halo settings for the material # Type: MaterialHalo, (readonly, never None) - # alpha¶ - - # Alpha transparency of the material - # Type: float in [0, 1], default 0.0 # ambient @@ -1912,10 +1968,6 @@ class MaterialSubsurfaceScattering(PropertyGroup): # Shadow raytracing bias to prevent terminator problems on shadow boundary # Type: float in [0, 0.25], default 0.0 - # specular_alpha - - # Alpha transparency for specular areas - # Type: float in [0, 1], default 0.0 # specular_color @@ -4298,6 +4350,7 @@ classes = ( MaterialRaytraceTransparency, MaterialRaytraceMirror, MaterialSubsurfaceScattering, + MaterialStrandSettings, RenderPovSettingsObject, RenderPovSettingsScene, RenderPovSettingsText, @@ -4337,6 +4390,7 @@ def register(): bpy.types.Material.pov_raytrace_transparency = PointerProperty(type=MaterialRaytraceTransparency) bpy.types.Material.pov = PointerProperty(type=RenderPovSettingsMaterial) bpy.types.Material.pov_subsurface_scattering = PointerProperty(type=MaterialSubsurfaceScattering) + bpy.types.Material.strand = PointerProperty(type= MaterialStrandSettings) bpy.types.Material.pov_raytrace_mirror = PointerProperty(type=MaterialRaytraceMirror) bpy.types.Texture.pov = PointerProperty(type=RenderPovSettingsTexture) bpy.types.Object.pov = PointerProperty(type=RenderPovSettingsObject) @@ -4353,6 +4407,7 @@ def unregister(): del bpy.types.Scene.pov del bpy.types.Material.pov del bpy.types.Material.pov_subsurface_scattering + del bpy.types.Material.strand del bpy.types.Material.pov_raytrace_mirror del bpy.types.Material.pov_raytrace_transparency #del bpy.types.Modifier.pov diff --git a/render_povray/render.py b/render_povray/render.py index 69a6b56a..0c212fb5 100644 --- a/render_povray/render.py +++ b/render_povray/render.py @@ -1697,10 +1697,10 @@ def write_pov(filename, scene=None, info_callback=None): material = None if material: diffuse_color = material.diffuse_color - trans = 1.0 - material.alpha + trans = 1.0 - material.pov.alpha if material.use_transparency and material.transparency_method == 'RAYTRACE': povFilter = material.pov_raytrace_transparency.filter * (1.0 - material.alpha) - trans = (1.0 - material.alpha) - povFilter + trans = (1.0 - material.pov.alpha) - povFilter else: povFilter = 0.0 material_finish = materialNames[material.name] @@ -1762,10 +1762,10 @@ def write_pov(filename, scene=None, info_callback=None): if material: diffuse_color = material.diffuse_color - trans = 1.0 - material.alpha + trans = 1.0 - material.pov.alpha if material.use_transparency and material.transparency_method == 'RAYTRACE': povFilter = material.pov_raytrace_transparency.filter * (1.0 - material.alpha) - trans = (1.0 - material.alpha) - povFilter + trans = (1.0 - material.pov.alpha) - povFilter else: povFilter = 0.0 @@ -2085,9 +2085,9 @@ def write_pov(filename, scene=None, info_callback=None): renderEmitter = True if hasattr(ob, 'particle_systems'): renderEmitter = False + if ob.show_instancer_for_render: + renderEmitter = True for pSys in ob.particle_systems: - if pSys.settings.use_render_emitter: - renderEmitter = True for mod in [m for m in ob.modifiers if (m is not None) and (m.type == 'PARTICLE_SYSTEM')]: if (pSys.settings.render_type == 'PATH') and mod.show_render and (pSys.name == mod.particle_system.name): tstart = time.time() @@ -2113,11 +2113,16 @@ def write_pov(filename, scene=None, info_callback=None): strandEnd = 0.01 strandShape = 0.0 # Set the number of particles to render count rather than 3d view display - pSys.set_resolution(scene, ob, 'RENDER') + #pSys.set_resolution(scene, ob, 'RENDER') # DEPRECATED + # When you render, the entire dependency graph will be + # evaluated at render resolution, including the particles. + # In the viewport it will be at viewport resolution. + # So there is no need fo render engines to use this function anymore, + # it's automatic now. steps = pSys.settings.display_step steps = 3 ** steps # or (power of 2 rather than 3) + 1 # Formerly : len(particle.hair_keys) - totalNumberOfHairs = ( len(pSys.particles) + len(pSys.child_particles) ) + totalNumberOfHairs = ( pSys.settings.count + pSys.settings.rendered_child_count ) #hairCounter = 0 file.write('#declare HairArray = array[%i] {\n' % totalNumberOfHairs) for pindex in range(0, totalNumberOfHairs): @@ -2135,7 +2140,7 @@ def write_pov(filename, scene=None, info_callback=None): file.write('linear_spline ') file.write('%i,\n' % (steps)) #changing world coordinates to object local coordinates by multiplying with inverted matrix - initCo = ob.matrix_world.inverted()*(pSys.co_hair(ob, pindex, 0)) + initCo = ob.matrix_world.inverted() @ (pSys.co_hair(ob, particle_no = pindex, step = 0)) if ob.material_slots[pSys.settings.material - 1].material and ob.active_material is not None: pmaterial = ob.material_slots[pSys.settings.material-1].material for th in pmaterial.texture_slots: @@ -2159,7 +2164,7 @@ def write_pov(filename, scene=None, info_callback=None): #only overwrite variable for each competing texture for now initColor=th.texture.evaluate((initCo[0],initCo[1],initCo[2])) for step in range(0, steps): - co = ob.matrix_world.inverted()*(pSys.co_hair(ob, pindex, step)) + co = ob.matrix_world.inverted() @ (pSys.co_hair(ob, particle_no = pindex, step = step)) #for controlPoint in particle.hair_keys: if pSys.settings.clump_factor != 0: hDiameter = pSys.settings.clump_factor / 200.0 * random.uniform(0.5, 1) @@ -2256,8 +2261,12 @@ def write_pov(filename, scene=None, info_callback=None): print('Number of tufts (particle systems)', len(ob.particle_systems)) # Set back the displayed number of particles to preview count - pSys.set_resolution(scene, ob, 'PREVIEW') - + # pSys.set_resolution(scene, ob, 'PREVIEW') #DEPRECATED + # When you render, the entire dependency graph will be + # evaluated at render resolution, including the particles. + # In the viewport it will be at viewport resolution. + # So there is no need fo render engines to use this function anymore, + # it's automatic now. if renderEmitter == False: continue #don't render mesh, skip to next object. diff --git a/render_povray/shading.py b/render_povray/shading.py index 8bffda6f..07e867b7 100644 --- a/render_povray/shading.py +++ b/render_povray/shading.py @@ -745,7 +745,7 @@ def writeTextureInfluence(mater, materialNames, LocalMaterialNames, path_image, string_strip_hyphen, safety, col, os, preview_dir, unpacked_images): material_finish = materialNames[mater.name] if mater.pov.use_transparency: - trans = 1.0 - mater.alpha + trans = 1.0 - mater.pov.alpha else: trans = 0.0 if ((mater.specular_color.s == 0.0) or (mater.pov.diffuse_shader == 'MINNAERT')): @@ -754,9 +754,9 @@ def writeTextureInfluence(mater, materialNames, LocalMaterialNames, path_image, else: colored_specular_found = True - if mater.pov.use_transparency and mater.transparency_method == 'RAYTRACE': - povFilter = mater.raytrace_transparency.filter * (1.0 - mater.alpha) - trans = (1.0 - mater.alpha) - povFilter + if mater.pov.use_transparency and mater.pov.transparency_method == 'RAYTRACE': + povFilter = mater.pov_raytrace_transparency.filter * (1.0 - mater.pov.alpha) + trans = (1.0 - mater.pov.alpha) - povFilter else: povFilter = 0.0 diff --git a/render_povray/ui.py b/render_povray/ui.py index 1ffb0140..2a31fd36 100644 --- a/render_povray/ui.py +++ b/render_povray/ui.py @@ -265,6 +265,11 @@ def check_material(mat): return True return False +def simple_material(mat): + if (mat is not None) and (not mat.use_nodes): + return True + return False + def check_add_mesh_extra_objects(): if "add_mesh_extra_objects" in bpy.context.preferences.addons.keys(): return True @@ -1385,7 +1390,7 @@ class MATERIAL_PT_POV_sss(MaterialButtonsPanel, Panel): sub.prop(sss, "back") col.separator() col.prop(sss, "error_threshold", text="Error") - + class MATERIAL_PT_povray_activate_node(MaterialButtonsPanel, Panel): bl_label = "Activate Node Settings" bl_context = "material" @@ -1517,6 +1522,70 @@ class MATERIAL_PT_POV_mirror(MaterialButtonsPanel, Panel): sub.prop(raym, "gloss_threshold", text="Threshold") sub.prop(raym, "gloss_samples", text="Samples") sub.prop(raym, "gloss_anisotropic", text="Anisotropic") + +class MATERIAL_PT_POV_transp(MaterialButtonsPanel, Panel): + bl_label = "Transparency" + COMPAT_ENGINES = {'POVRAY_RENDER'} + + @classmethod + def poll(cls, context): + mat = context.material + engine = context.scene.render.engine + return check_material(mat) and (mat.pov.type in {'SURFACE', 'WIRE'}) and (engine in cls.COMPAT_ENGINES) + + def draw_header(self, context): + mat = context.material + + if simple_material(mat): + self.layout.prop(mat.pov, "use_transparency", text="") + + def draw(self, context): + layout = self.layout + + base_mat = context.material + mat = context.material#FORMERLY active_node_mat(context.material) + rayt = mat.pov_raytrace_transparency + + if simple_material(base_mat): + row = layout.row() + row.active = mat.pov.use_transparency + row.prop(mat.pov, "transparency_method", expand=True) + + split = layout.split() + split.active = base_mat.pov.use_transparency + + col = split.column() + col.prop(mat.pov, "alpha") + row = col.row() + row.active = (base_mat.pov.transparency_method != 'MASK') and (not mat.pov.use_shadeless) + row.prop(mat.pov, "specular_alpha", text="Specular") + + col = split.column() + col.active = (not mat.pov.use_shadeless) + col.prop(rayt, "fresnel") + sub = col.column() + sub.active = (rayt.fresnel > 0.0) + sub.prop(rayt, "fresnel_factor", text="Blend") + + if base_mat.pov.transparency_method == 'RAYTRACE': + layout.separator() + split = layout.split() + split.active = base_mat.pov.use_transparency + + col = split.column() + col.prop(rayt, "ior") + col.prop(rayt, "filter") + col.prop(rayt, "falloff") + col.prop(rayt, "depth_max") + col.prop(rayt, "depth") + + col = split.column() + col.label(text="Gloss:") + col.prop(rayt, "gloss_factor", text="Amount") + sub = col.column() + sub.active = rayt.gloss_factor < 1.0 + sub.prop(rayt, "gloss_threshold", text="Threshold") + sub.prop(rayt, "gloss_samples", text="Samples") class MATERIAL_PT_povray_reflection(MaterialButtonsPanel, Panel): bl_label = "POV-Ray Reflection" @@ -1646,7 +1715,52 @@ class MATERIAL_PT_povray_caustics(MaterialButtonsPanel, Panel): col.label(text="Caustics override is on, ") col.label(text="but you didn't chose any !") +class MATERIAL_PT_strand(MaterialButtonsPanel, Panel): + bl_label = "Strand" + bl_options = {'DEFAULT_CLOSED'} + COMPAT_ENGINES = {'POVRAY_RENDER'} + + @classmethod + def poll(cls, context): + mat = context.material + engine = context.scene.render.engine + return mat and (mat.type in {'SURFACE', 'WIRE', 'HALO'}) and (engine in cls.COMPAT_ENGINES) + + def draw(self, context): + layout = self.layout + + mat = context.material # don't use node material + tan = mat.strand + + split = layout.split() + + col = split.column() + sub = col.column(align=True) + sub.label(text="Size:") + sub.prop(tan, "root_size", text="Root") + sub.prop(tan, "tip_size", text="Tip") + sub.prop(tan, "size_min", text="Minimum") + sub.prop(tan, "use_blender_units") + sub = col.column() + sub.active = (not mat.pov.use_shadeless) + sub.prop(tan, "use_tangent_shading") + col.prop(tan, "shape") + col = split.column() + col.label(text="Shading:") + col.prop(tan, "width_fade") + ob = context.object + if ob and ob.type == 'MESH': + col.prop_search(tan, "uv_layer", ob.data, "uv_textures", text="") + else: + col.prop(tan, "uv_layer", text="") + col.separator() + sub = col.column() + sub.active = (not mat.pov.use_shadeless) + sub.label("Surface diffuse:") + sub = col.column() + sub.prop(tan, "blend_distance", text="Distance") + class MATERIAL_PT_povray_replacement_text(MaterialButtonsPanel, Panel): bl_label = "Custom POV Code" COMPAT_ENGINES = {'POVRAY_RENDER'} @@ -3085,9 +3199,11 @@ classes = ( MATERIAL_PT_POV_sss, MATERIAL_MT_POV_sss_presets, AddPresetSSS, + MATERIAL_PT_strand, MATERIAL_PT_povray_activate_node, MATERIAL_PT_povray_active_node, MATERIAL_PT_POV_mirror, + MATERIAL_PT_POV_transp, MATERIAL_PT_povray_reflection, #MATERIAL_PT_POV_interior, MATERIAL_PT_povray_fade_color, diff --git a/space_view3d_brush_menus/__init__.py b/space_view3d_brush_menus/__init__.py new file mode 100644 index 00000000..5381d14c --- /dev/null +++ b/space_view3d_brush_menus/__init__.py @@ -0,0 +1,135 @@ +# ##### 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 ##### +# Modified by Meta-Androcto + +""" Copyright 2011 GPL licence applies""" + +bl_info = { + "name": "Dynamic Brush Menus", + "description": "Fast access to brushes & tools in Sculpt and Paint Modes", + "author": "Ryan Inch (Imaginer)", + "version": (1, 1, 7), + "blender": (2, 80, 0), + "location": "Spacebar in Sculpt/Paint Modes", + "warning": '', + "wiki_url": "https://wiki.blender.org/index.php/Extensions:2.6/Py/" + "Scripts/3D_interaction/Advanced_UI_Menus", + "category": "3D View"} + + +if "bpy" in locals(): + import importlib + importlib.reload(utils_core) + importlib.reload(brush_menu) + importlib.reload(brushes) + importlib.reload(curve_menu) + importlib.reload(dyntopo_menu) + importlib.reload(stroke_menu) + importlib.reload(symmetry_menu) + importlib.reload(texture_menu) +else: + from . import utils_core + from . import brush_menu + from . import brushes + from . import curve_menu + from . import dyntopo_menu + from . import stroke_menu + from . import symmetry_menu + from . import texture_menu + + +import bpy +from bpy.types import AddonPreferences +from bpy.props import ( + EnumProperty, + IntProperty, + ) + + +addon_files = ( + brush_menu, + brushes, + curve_menu, + dyntopo_menu, + stroke_menu, + symmetry_menu, + texture_menu, + ) + + + +class VIEW3D_MT_Brushes_Pref(AddonPreferences): + bl_idname = __name__ + + column_set: IntProperty( + name="Number of Columns", + description="Number of columns used for the brushes menu", + default=2, + min=1, + max=10 + ) + + def draw(self, context): + layout = self.layout + + col = layout.column(align=True) + col.prop(self, "column_set", slider=True) + + +# New hotkeys and registration + +addon_keymaps = [] + + +def register(): + # register all files + for addon_file in addon_files: + addon_file.register() + + # set the add-on name variable to access the preferences + utils_core.get_addon_name = __name__ + + # register preferences + bpy.utils.register_class(VIEW3D_MT_Brushes_Pref) + + # register hotkeys + wm = bpy.context.window_manager + modes = ('Sculpt', 'Vertex Paint', 'Weight Paint', 'Image Paint', 'Particle') + + for mode in modes: + km = wm.keyconfigs.addon.keymaps.new(name=mode) + kmi = km.keymap_items.new('wm.call_menu', 'SPACE', 'PRESS') + kmi.properties.name = "VIEW3D_MT_sv3_brush_options" + addon_keymaps.append((km, kmi)) + + +def unregister(): + # unregister all files + for addon_file in addon_files: + addon_file.unregister() + + # unregister preferences + bpy.utils.unregister_class(VIEW3D_MT_Brushes_Pref) + + for km, kmi in addon_keymaps: + km.keymap_items.remove(kmi) + addon_keymaps.clear() + + +if __name__ == "__main__": + register() diff --git a/space_view3d_brush_menus/brush_menu.py b/space_view3d_brush_menus/brush_menu.py new file mode 100644 index 00000000..28caf747 --- /dev/null +++ b/space_view3d_brush_menus/brush_menu.py @@ -0,0 +1,630 @@ +# gpl author: Ryan Inch (Imaginer) + +import bpy +from bpy.types import ( + Operator, + Menu, + ) +from bpy.props import BoolProperty +from . import utils_core +from . import brushes +from bl_ui.properties_paint_common import UnifiedPaintPanel + +class BrushOptionsMenu(Menu): + bl_label = "Brush Options" + bl_idname = "VIEW3D_MT_sv3_brush_options" + + @classmethod + def poll(self, context): + return utils_core.get_mode() in ( + 'SCULPT', 'VERTEX_PAINT', + 'WEIGHT_PAINT', 'TEXTURE_PAINT', + 'PARTICLE_EDIT' + ) + + def draw(self, context): + mode = utils_core.get_mode() + layout = self.layout + + if mode == 'SCULPT': + self.sculpt(mode, layout, context) + + elif mode in ('VERTEX_PAINT', 'WEIGHT_PAINT'): + self.vw_paint(mode, layout, context) + + elif mode == 'TEXTURE_PAINT': + self.texpaint(mode, layout, context) + + else: + self.particle(layout, context) + + def sculpt(self, mode, layout, context): + has_brush = utils_core.get_brush_link(context, types="brush") + icons = brushes.brush_icon[mode][has_brush.sculpt_tool] if \ + has_brush else "BRUSH_DATA" + layout.operator("wm.toolbar", text="Tools", icon='TOOL_SETTINGS') + layout.row().menu("VIEW3D_MT_sv3_brushes_menu", + icon=icons) + + layout.row().menu(BrushRadiusMenu.bl_idname) + + if has_brush: + # if the active brush is unlinked these menus don't do anything + layout.row().menu(BrushStrengthMenu.bl_idname) + layout.row().menu(BrushAutosmoothMenu.bl_idname) + layout.row().menu(BrushModeMenu.bl_idname) + layout.row().menu("VIEW3D_MT_sv3_texture_menu") + layout.row().menu("VIEW3D_MT_sv3_stroke_options") + layout.row().menu("VIEW3D_MT_sv3_brush_curve_menu") + + layout.row().menu("VIEW3D_MT_sv3_dyntopo") + layout.row().menu("VIEW3D_MT_sv3_master_symmetry_menu") + + def vw_paint(self, mode, layout, context): + has_brush = utils_core.get_brush_link(context, types="brush") + icons = brushes.brush_icon[mode][has_brush.vertex_tool] if \ + has_brush else "BRUSH_DATA" + + layout.operator("wm.toolbar", text="Tools", icon='TOOL_SETTINGS') + + if mode == 'VERTEX_PAINT': + layout.row().operator(ColorPickerPopup.bl_idname, icon="COLOR") + layout.row().separator() + + layout.row().menu("VIEW3D_MT_sv3_brushes_menu", + icon=icons) + + if mode == 'VERTEX_PAINT': + layout.row().menu(BrushRadiusMenu.bl_idname) + + if has_brush: + # if the active brush is unlinked these menus don't do anything + layout.row().menu(BrushStrengthMenu.bl_idname) + layout.row().menu(BrushModeMenu.bl_idname) + layout.row().menu("VIEW3D_MT_sv3_texture_menu") + layout.row().menu("VIEW3D_MT_sv3_stroke_options") + layout.row().menu("VIEW3D_MT_sv3_brush_curve_menu") + + if mode == 'WEIGHT_PAINT': + layout.row().menu(BrushWeightMenu.bl_idname) + layout.row().menu(BrushRadiusMenu.bl_idname) + + if has_brush: + # if the active brush is unlinked these menus don't do anything + layout.row().menu(BrushStrengthMenu.bl_idname) + layout.row().menu(BrushModeMenu.bl_idname) + layout.row().menu("VIEW3D_MT_sv3_stroke_options") + layout.row().menu("VIEW3D_MT_sv3_brush_curve_menu") + + def texpaint(self, mode, layout, context): + toolsettings = context.tool_settings.image_paint + + has_brush = utils_core.get_brush_link(context, types="brush") + icons = brushes.brush_icon[mode][has_brush.image_tool] if \ + has_brush else "BRUSH_DATA" + + if context.image_paint_object and not toolsettings.detect_data(): + if toolsettings.missing_uvs or toolsettings.missing_materials or \ + toolsettings.missing_texture: + layout.row().label(text="Missing Data", icon='ERROR') + layout.row().operator_menu_enum("paint.add_texture_paint_slot", \ + "type", \ + icon='ADD', \ + text="Add Texture Paint Slot") + + return + + elif toolsettings.missing_stencil: + layout.row().label(text="Missing Data", icon='ERROR') + layout.row().label(text="See Mask Properties", icon='FORWARD') + layout.row().separator() + layout.operator("wm.toolbar", text="Tools", icon='TOOL_SETTINGS') + layout.row().menu("VIEW3D_MT_sv3_brushes_menu", + icon=icons) + + return + + else: + layout.row().label(text="Missing Data", icon="INFO") + + else: + layout.operator("wm.toolbar", text="Tools", icon='TOOL_SETTINGS') + + if has_brush and has_brush.image_tool in {'DRAW', 'FILL'} and \ + has_brush.blend not in {'ERASE_ALPHA', 'ADD_ALPHA'}: + layout.row().operator(ColorPickerPopup.bl_idname, icon="COLOR") + layout.row().separator() + + layout.row().menu("VIEW3D_MT_sv3_brushes_menu", + icon=icons) + + if has_brush: + # if the active brush is unlinked these menus don't do anything + if has_brush and has_brush.image_tool in {'MASK'}: + layout.row().menu(BrushWeightMenu.bl_idname, text="Mask Value") + + if has_brush and has_brush.image_tool not in {'FILL'}: + layout.row().menu(BrushRadiusMenu.bl_idname) + + layout.row().menu(BrushStrengthMenu.bl_idname) + + if has_brush and has_brush.image_tool in {'DRAW'}: + layout.row().menu(BrushModeMenu.bl_idname) + + layout.row().menu("VIEW3D_MT_sv3_texture_menu") + layout.row().menu("VIEW3D_MT_sv3_stroke_options") + layout.row().menu("VIEW3D_MT_sv3_brush_curve_menu") + + layout.row().menu("VIEW3D_MT_sv3_master_symmetry_menu") + + def particle(self, layout, context): + particle_edit = context.tool_settings.particle_edit + + layout.operator("wm.toolbar", text="Tools", icon='TOOL_SETTINGS') + + layout.row().menu("VIEW3D_MT_sv3_brushes_menu", + icon="BRUSH_DATA") + layout.row().menu(BrushRadiusMenu.bl_idname) + + if particle_edit.tool != 'ADD': + layout.row().menu(BrushStrengthMenu.bl_idname) + else: + layout.row().menu(ParticleCountMenu.bl_idname) + layout.row().separator() + layout.row().prop(particle_edit, "use_default_interpolate", toggle=True) + + layout.row().prop(particle_edit.brush, "steps", slider=True) + layout.row().prop(particle_edit, "default_key_count", slider=True) + + if particle_edit.tool == 'LENGTH': + layout.row().separator() + layout.row().menu(ParticleLengthMenu.bl_idname) + + if particle_edit.tool == 'PUFF': + layout.row().separator() + layout.row().menu(ParticlePuffMenu.bl_idname) + layout.row().prop(particle_edit.brush, "use_puff_volume", toggle=True) + + +class BrushRadiusMenu(Menu): + bl_label = "Radius" + bl_idname = "VIEW3D_MT_sv3_brush_radius_menu" + bl_description = "Change the size of the brushes" + + def init(self): + if utils_core.get_mode() == 'PARTICLE_EDIT': + settings = (("100", 100), + ("70", 70), + ("50", 50), + ("30", 30), + ("20", 20), + ("10", 10)) + + datapath = "tool_settings.particle_edit.brush.size" + proppath = bpy.context.tool_settings.particle_edit.brush + + else: + settings = (("200", 200), + ("150", 150), + ("100", 100), + ("50", 50), + ("35", 35), + ("10", 10)) + + datapath = "tool_settings.unified_paint_settings.size" + proppath = bpy.context.tool_settings.unified_paint_settings + + return settings, datapath, proppath + + def draw(self, context): + settings, datapath, proppath = self.init() + layout = self.layout + + # add the top slider + layout.row().prop(proppath, "size", slider=True) + layout.row().separator() + + # add the rest of the menu items + for i in range(len(settings)): + utils_core.menuprop( + layout.row(), settings[i][0], settings[i][1], + datapath, icon='RADIOBUT_OFF', disable=True, + disable_icon='RADIOBUT_ON' + ) + + +class BrushStrengthMenu(Menu): + bl_label = "Strength" + bl_idname = "VIEW3D_MT_sv3_brush_strength_menu" + + def init(self): + mode = utils_core.get_mode() + settings = (("1.0", 1.0), + ("0.7", 0.7), + ("0.5", 0.5), + ("0.3", 0.3), + ("0.2", 0.2), + ("0.1", 0.1)) + + proppath = utils_core.get_brush_link(bpy.context, types="brush") + + if mode == 'SCULPT': + datapath = "tool_settings.sculpt.brush.strength" + + elif mode == 'VERTEX_PAINT': + datapath = "tool_settings.vertex_paint.brush.strength" + + elif mode == 'WEIGHT_PAINT': + datapath = "tool_settings.weight_paint.brush.strength" + + elif mode == 'TEXTURE_PAINT': + datapath = "tool_settings.image_paint.brush.strength" + + else: + datapath = "tool_settings.particle_edit.brush.strength" + proppath = bpy.context.tool_settings.particle_edit.brush + + return settings, datapath, proppath + + def draw(self, context): + settings, datapath, proppath = self.init() + layout = self.layout + + # add the top slider + if proppath: + layout.row().prop(proppath, "strength", slider=True) + layout.row().separator() + + # add the rest of the menu items + for i in range(len(settings)): + utils_core.menuprop( + layout.row(), settings[i][0], settings[i][1], + datapath, icon='RADIOBUT_OFF', disable=True, + disable_icon='RADIOBUT_ON' + ) + else: + layout.row().label(text="No brushes available", icon="INFO") + + +class BrushModeMenu(Menu): + bl_label = "Brush Mode" + bl_idname = "VIEW3D_MT_sv3_brush_mode_menu" + + def init(self): + mode = utils_core.get_mode() + has_brush = utils_core.get_brush_link(bpy.context, types="brush") + + if mode == 'SCULPT': + enum = has_brush.bl_rna.properties['sculpt_plane'].enum_items if \ + has_brush else None + path = "tool_settings.sculpt.brush.sculpt_plane" + + elif mode == 'VERTEX_PAINT': + enum = has_brush.bl_rna.properties['blend'].enum_items if \ + has_brush else None + path = "tool_settings.vertex_paint.brush.blend" + + elif mode == 'WEIGHT_PAINT': + enum = has_brush.bl_rna.properties['blend'].enum_items if \ + has_brush else None + path = "tool_settings.weight_paint.brush.blend" + + elif mode == 'TEXTURE_PAINT': + enum = has_brush.bl_rna.properties['blend'].enum_items if \ + has_brush else None + path = "tool_settings.image_paint.brush.blend" + + else: + enum = None + path = "" + + return enum, path + + def draw(self, context): + enum, path = self.init() + layout = self.layout + colum_n = utils_core.addon_settings() + + layout.row().label(text="Brush Mode") + layout.row().separator() + + if enum: + if utils_core.get_mode() != 'SCULPT': + column_flow = layout.column_flow(columns=colum_n) + + # add all the brush modes to the menu + for brush in enum: + utils_core.menuprop( + column_flow.row(), brush.name, + brush.identifier, path, icon='RADIOBUT_OFF', + disable=True, disable_icon='RADIOBUT_ON' + ) + else: + # add all the brush modes to the menu + for brush in enum: + utils_core.menuprop( + layout.row(), brush.name, + brush.identifier, path, icon='RADIOBUT_OFF', + disable=True, disable_icon='RADIOBUT_ON' + ) + else: + layout.row().label(text="No brushes available", icon="INFO") + + +class BrushAutosmoothMenu(Menu): + bl_label = "Autosmooth" + bl_idname = "VIEW3D_MT_sv3_brush_autosmooth_menu" + + def init(self): + settings = (("1.0", 1.0), + ("0.7", 0.7), + ("0.5", 0.5), + ("0.3", 0.3), + ("0.2", 0.2), + ("0.1", 0.1)) + + return settings + + def draw(self, context): + settings = self.init() + layout = self.layout + has_brush = utils_core.get_brush_link(context, types="brush") + + if has_brush: + # add the top slider + layout.row().prop(has_brush, "auto_smooth_factor", slider=True) + layout.row().separator() + + # add the rest of the menu items + for i in range(len(settings)): + utils_core.menuprop( + layout.row(), settings[i][0], settings[i][1], + "tool_settings.sculpt.brush.auto_smooth_factor", + icon='RADIOBUT_OFF', disable=True, + disable_icon='RADIOBUT_ON' + ) + else: + layout.row().label(text="No Smooth options available", icon="INFO") + + +class BrushWeightMenu(Menu): + bl_label = "Weight" + bl_idname = "VIEW3D_MT_sv3_brush_weight_menu" + + def init(self): + settings = (("1.0", 1.0), + ("0.7", 0.7), + ("0.5", 0.5), + ("0.3", 0.3), + ("0.2", 0.2), + ("0.1", 0.1)) + + if utils_core.get_mode() == 'WEIGHT_PAINT': + brush = bpy.context.tool_settings.unified_paint_settings + brushstr = "tool_settings.unified_paint_settings.weight" + name = "Weight" + + else: + brush = bpy.context.tool_settings.image_paint.brush + brushstr = "tool_settings.image_paint.brush.weight" + name = "Mask Value" + + return settings, brush, brushstr, name + + def draw(self, context): + settings, brush, brushstr, name = self.init() + layout = self.layout + + if brush: + # add the top slider + layout.row().prop(brush, "weight", text=name, slider=True) + layout.row().separator() + + # add the rest of the menu items + for i in range(len(settings)): + utils_core.menuprop( + layout.row(), settings[i][0], settings[i][1], + brushstr, + icon='RADIOBUT_OFF', disable=True, + disable_icon='RADIOBUT_ON' + ) + else: + layout.row().label(text="No brush available", icon="INFO") + + +class ParticleCountMenu(Menu): + bl_label = "Count" + bl_idname = "VIEW3D_MT_sv3_particle_count_menu" + + def init(self): + settings = (("50", 50), + ("25", 25), + ("10", 10), + ("5", 5), + ("3", 3), + ("1", 1)) + + return settings + + def draw(self, context): + settings = self.init() + layout = self.layout + + # add the top slider + layout.row().prop(context.tool_settings.particle_edit.brush, + "count", slider=True) + layout.row().separator() + + # add the rest of the menu items + for i in range(len(settings)): + utils_core.menuprop( + layout.row(), settings[i][0], settings[i][1], + "tool_settings.particle_edit.brush.count", + icon='RADIOBUT_OFF', disable=True, + disable_icon='RADIOBUT_ON' + ) + + +class ParticleLengthMenu(Menu): + bl_label = "Length Mode" + bl_idname = "VIEW3D_MT_sv3_particle_length_menu" + + def draw(self, context): + layout = self.layout + path = "tool_settings.particle_edit.brush.length_mode" + + # add the menu items + for item in context.tool_settings.particle_edit.brush. \ + bl_rna.properties['length_mode'].enum_items: + utils_core.menuprop( + layout.row(), item.name, item.identifier, path, + icon='RADIOBUT_OFF', + disable=True, + disable_icon='RADIOBUT_ON' + ) + + +class ParticlePuffMenu(Menu): + bl_label = "Puff Mode" + bl_idname = "VIEW3D_MT_sv3_particle_puff_menu" + + def draw(self, context): + layout = self.layout + path = "tool_settings.particle_edit.brush.puff_mode" + + # add the menu items + for item in context.tool_settings.particle_edit.brush. \ + bl_rna.properties['puff_mode'].enum_items: + utils_core.menuprop( + layout.row(), item.name, item.identifier, path, + icon='RADIOBUT_OFF', + disable=True, + disable_icon='RADIOBUT_ON' + ) + + +class FlipColorsAll(Operator): + """Switch between Foreground and Background colors""" + bl_label = "Flip Colors" + bl_idname = "view3d.sv3_flip_colors_all" + bl_description = "Switch between Foreground and Background colors" + + is_tex: BoolProperty( + default=False, + options={'HIDDEN'} + ) + + def execute(self, context): + try: + if self.is_tex is False: + color = context.tool_settings.vertex_paint.brush.color + secondary_color = context.tool_settings.vertex_paint.brush.secondary_color + + orig_prim = color.hsv + orig_sec = secondary_color.hsv + + color.hsv = orig_sec + secondary_color.hsv = orig_prim + else: + color = context.tool_settings.image_paint.brush.color + secondary_color = context.tool_settings.image_paint.brush.secondary_color + + orig_prim = color.hsv + orig_sec = secondary_color.hsv + + color.hsv = orig_sec + secondary_color.hsv = orig_prim + + return {'FINISHED'} + + except Exception as e: + utils_core.error_handlers(self, "view3d.sv3_flip_colors_all", e, + "Flip Colors could not be completed") + + return {'CANCELLED'} + + +class ColorPickerPopup(Operator): + """Open Color Picker""" + bl_label = "Color" + bl_idname = "view3d.sv3_color_picker_popup" + bl_description = "Open Color Picker" + bl_options = {'REGISTER'} + + @classmethod + def poll(self, context): + return utils_core.get_mode() in ( + 'VERTEX_PAINT', + 'TEXTURE_PAINT' + ) + + def check(self, context): + return True + + def init(self): + if utils_core.get_mode() == 'TEXTURE_PAINT': + settings = bpy.context.tool_settings.image_paint + brush = getattr(settings, "brush", None) + else: + settings = bpy.context.tool_settings.vertex_paint + brush = settings.brush + brush = getattr(settings, "brush", None) + + return settings, brush + + def draw(self, context): + layout = self.layout + settings, brush = self.init() + + + if brush: + layout.row().template_color_picker(brush, "color", value_slider=True) + prim_sec_row = layout.row(align=True) + prim_sec_row.prop(brush, "color", text="") + prim_sec_row.prop(brush, "secondary_color", text="") + + if utils_core.get_mode() == 'VERTEX_PAINT': + prim_sec_row.operator( + FlipColorsAll.bl_idname, + icon='FILE_REFRESH', text="" + ).is_tex = False + else: + prim_sec_row.operator( + FlipColorsAll.bl_idname, + icon='FILE_REFRESH', text="" + ).is_tex = True + + if settings.palette: + layout.column().template_palette(settings, "palette", color=True) + + layout.row().template_ID(settings, "palette", new="palette.new") + else: + layout.row().label(text="No brushes currently available", icon="INFO") + + return + + def execute(self, context): + return context.window_manager.invoke_popup(self, width=180) + + +classes = ( + BrushOptionsMenu, + BrushRadiusMenu, + BrushStrengthMenu, + BrushModeMenu, + BrushAutosmoothMenu, + BrushWeightMenu, + ParticleCountMenu, + ParticleLengthMenu, + ParticlePuffMenu, + FlipColorsAll, + ColorPickerPopup + ) + +def register(): + for cls in classes: + bpy.utils.register_class(cls) + +def unregister(): + for cls in classes: + bpy.utils.unregister_class(cls) diff --git a/space_view3d_brush_menus/brushes.py b/space_view3d_brush_menus/brushes.py new file mode 100644 index 00000000..3478d575 --- /dev/null +++ b/space_view3d_brush_menus/brushes.py @@ -0,0 +1,163 @@ +# gpl author: Ryan Inch (Imaginer) + +import bpy +from bpy.types import Menu +from . import utils_core +from bl_ui.properties_paint_common import UnifiedPaintPanel + +# Particle Tools + +particle_tools = ( + ("Comb", 'COMB'), + ("Smooth", 'SMOOTH'), + ("Add", 'ADD'), + ("Length", 'LENGTH'), + ("Puff", 'PUFF'), + ("Cut", 'CUT'), + ("Weight", 'WEIGHT') +) + +# Brush Datapaths + +brush_datapath = { + 'SCULPT': "tool_settings.sculpt.brush", + 'VERTEX_PAINT': "tool_settings.vertex_paint.brush", + 'WEIGHT_PAINT': "tool_settings.weight_paint.brush", + 'TEXTURE_PAINT': "tool_settings.image_paint.brush", + 'PARTICLE_EDIT': "tool_settings.particle_edit.tool" +} + +# Brush Icons + +brush_icon = { + 'SCULPT': { + "BLOB": 'BRUSH_BLOB', + "CLAY": 'BRUSH_CLAY', + "CLAY_STRIPS": 'BRUSH_CLAY_STRIPS', + "CREASE": 'BRUSH_CREASE', + "DRAW": 'BRUSH_SCULPT_DRAW', + "FILL": 'BRUSH_FILL', + "FLATTEN": 'BRUSH_FLATTEN', + "GRAB": 'BRUSH_GRAB', + "INFLATE": 'BRUSH_INFLATE', + "LAYER": 'BRUSH_LAYER', + "MASK": 'BRUSH_MASK', + "NUDGE": 'BRUSH_NUDGE', + "PINCH": 'BRUSH_PINCH', + "ROTATE": 'BRUSH_ROTATE', + "SCRAPE": 'BRUSH_SCRAPE', + "SIMPLIFY": 'BRUSH_DATA', + "SMOOTH": 'BRUSH_SMOOTH', + "SNAKE_HOOK": 'BRUSH_SNAKE_HOOK', + "THUMB": 'BRUSH_THUMB' + }, + + 'VERTEX_PAINT': { + "AVERAGE": 'BRUSH_BLUR', + "BLUR": 'BRUSH_BLUR', + "DRAW": 'BRUSH_MIX', + "SMEAR": 'BRUSH_BLUR' + }, + + 'WEIGHT_PAINT': { + "AVERAGE": 'BRUSH_BLUR', + "BLUR": 'BRUSH_BLUR', + "DRAW": 'BRUSH_MIX', + "SMEAR": 'BRUSH_BLUR' + }, + + 'TEXTURE_PAINT': { + "CLONE": 'BRUSH_CLONE', + "DRAW": 'BRUSH_TEXDRAW', + "FILL": 'BRUSH_TEXFILL', + "MASK": 'BRUSH_TEXMASK', + "SMEAR": 'BRUSH_SMEAR', + "SOFTEN": 'BRUSH_SOFTEN' + } +} + + +class BrushesMenu(Menu): + bl_label = "Brush" + bl_idname = "VIEW3D_MT_sv3_brushes_menu" + + def draw(self, context): + mode = utils_core.get_mode() + layout = self.layout + settings = UnifiedPaintPanel.paint_settings(context) + colum_n = utils_core.addon_settings() + + layout.row().label(text="Brush") + layout.row().separator() + + has_brush = utils_core.get_brush_link(context, types="brush") + current_brush = eval("bpy.context.{}".format(brush_datapath[mode])) if has_brush else None + + # get the current brush's name + if current_brush and utils_core.get_mode() != 'PARTICLE_EDIT': + current_brush = current_brush.name + + if mode == 'PARTICLE_EDIT': + # if you are in particle edit mode add the menu items for particle mode + for tool in particle_tools: + utils_core.menuprop( + layout.row(), tool[0], tool[1], brush_datapath[mode], + icon='RADIOBUT_OFF', disable=True, + disable_icon='RADIOBUT_ON' + ) + else: + column_flow = layout.column_flow(columns=colum_n) + + # iterate over all the brushes + for item in bpy.data.brushes: + if mode == 'SCULPT': + if item.use_paint_sculpt: + # if you are in sculpt mode and the brush + # is a sculpt brush add the brush to the menu + utils_core.menuprop( + column_flow.row(), item.name, + 'bpy.data.brushes["%s"]' % item.name, + brush_datapath[mode], icon=brush_icon[mode][item.sculpt_tool], + disable=True, custom_disable_exp=(item.name, current_brush), + path=True + ) + if mode == 'VERTEX_PAINT': + if item.use_paint_vertex: + # if you are in vertex paint mode and the brush + # is a vertex paint brush add the brush to the menu + utils_core.menuprop( + column_flow.row(), item.name, + 'bpy.data.brushes["%s"]' % item.name, + brush_datapath[mode], icon=brush_icon[mode][item.vertex_tool], + disable=True, custom_disable_exp=(item.name, current_brush), + path=True + ) + if mode == 'WEIGHT_PAINT': + if item.use_paint_weight: + # if you are in weight paint mode and the brush + # is a weight paint brush add the brush to the menu + utils_core.menuprop( + column_flow.row(), item.name, + 'bpy.data.brushes["%s"]' % item.name, + brush_datapath[mode], icon=brush_icon[mode][item.vertex_tool], + disable=True, custom_disable_exp=(item.name, current_brush), + path=True + ) + if utils_core.get_mode() == 'TEXTURE_PAINT': + if item.use_paint_image: + # if you are in texture paint mode and the brush + # is a texture paint brush add the brush to the menu + utils_core.menuprop( + column_flow.row(), item.name, + 'bpy.data.brushes["%s"]' % item.name, + brush_datapath[mode], icon=brush_icon[mode][item.image_tool], + disable=True, custom_disable_exp=(item.name, current_brush), + path=True + ) + + +def register(): + bpy.utils.register_class(BrushesMenu) + +def unregister(): + bpy.utils.unregister_class(BrushesMenu) diff --git a/space_view3d_brush_menus/curve_menu.py b/space_view3d_brush_menus/curve_menu.py new file mode 100644 index 00000000..5a836031 --- /dev/null +++ b/space_view3d_brush_menus/curve_menu.py @@ -0,0 +1,88 @@ +# gpl author: Ryan Inch (Imaginer) + +import bpy +from bpy.types import ( + Operator, + Menu, + ) +from . import utils_core + + +class BrushCurveMenu(Menu): + bl_label = "Curve" + bl_idname = "VIEW3D_MT_sv3_brush_curve_menu" + + @classmethod + def poll(self, context): + return utils_core.get_mode() in ( + 'SCULPT', 'VERTEX_PAINT', + 'WEIGHT_PAINT', 'TEXTURE_PAINT', + 'PARTICLE_EDIT' + ) + + def draw(self, context): + layout = self.layout + curves = (("Smooth", "SMOOTH", "SMOOTHCURVE"), + ("Sphere", "ROUND", "SPHERECURVE"), + ("Root", "ROOT", "ROOTCURVE"), + ("Sharp", "SHARP", "SHARPCURVE"), + ("Linear", "LINE", "LINCURVE"), + ("Constant", "MAX", "NOCURVE")) + + # add the top slider + layout.row().operator(CurvePopup.bl_idname, icon="RNDCURVE") + layout.row().separator() + + # add the rest of the menu items + for curve in curves: + item = layout.row().operator("brush.curve_preset", + text=curve[0], icon=curve[2]) + item.shape = curve[1] + + +class CurvePopup(Operator): + """Edit Falloff Curve""" + bl_label = "Adjust Curve" + bl_idname = "view3d.sv3_curve_popup" + bl_description = "Edit Falloff Curve" + bl_options = {'REGISTER'} + + @classmethod + def poll(self, context): + return utils_core.get_mode() in ( + 'SCULPT', 'VERTEX_PAINT', + 'WEIGHT_PAINT', 'TEXTURE_PAINT' + ) + + def draw(self, context): + layout = self.layout + has_brush = utils_core.get_brush_link(context, types="brush") + + if utils_core.get_mode() == 'SCULPT' or \ + utils_core.get_mode() == 'VERTEX_PAINT' or \ + utils_core.get_mode() == 'WEIGHT_PAINT' or \ + utils_core.get_mode() == 'TEXTURE_PAINT': + if has_brush: + layout.column().template_curve_mapping(has_brush, + "curve", brush=True) + else: + layout.row().label(text="No brushes available", icon="INFO") + else: + layout.row().label(text="No brushes available", icon="INFO") + + def execute(self, context): + return context.window_manager.invoke_popup(self, width=180) + + +classes = ( + BrushCurveMenu, + CurvePopup + ) + +def register(): + for cls in classes: + bpy.utils.register_class(cls) + +def unregister(): + for cls in classes: + bpy.utils.unregister_class(cls) diff --git a/space_view3d_brush_menus/dyntopo_menu.py b/space_view3d_brush_menus/dyntopo_menu.py new file mode 100644 index 00000000..1a569787 --- /dev/null +++ b/space_view3d_brush_menus/dyntopo_menu.py @@ -0,0 +1,172 @@ +# gpl author: Ryan Inch (Imaginer) + +import bpy +from bpy.types import Menu +from . import utils_core + + +class DynTopoMenu(Menu): + bl_label = "Dyntopo" + bl_idname = "VIEW3D_MT_sv3_dyntopo" + + @classmethod + def poll(self, context): + return utils_core.get_mode() == 'SCULPT' + + def draw(self, context): + layout = self.layout + + if context.object.use_dynamic_topology_sculpting: + layout.row().operator("sculpt.dynamic_topology_toggle", + text="Disable Dynamic Topology") + + layout.row().separator() + + layout.row().menu(DynDetailMenu.bl_idname) + layout.row().menu(DetailMethodMenu.bl_idname) + + layout.row().separator() + + layout.row().operator("sculpt.optimize") + if context.tool_settings.sculpt.detail_type_method == 'CONSTANT': + layout.row().operator("sculpt.detail_flood_fill") + + layout.row().menu(SymmetrizeMenu.bl_idname) + layout.row().prop(context.tool_settings.sculpt, + "use_smooth_shading", toggle=True) + + else: + row = layout.row() + row.operator_context = 'INVOKE_DEFAULT' + row.operator("sculpt.dynamic_topology_toggle", + text="Enable Dynamic Topology") + + +class DynDetailMenu(Menu): + bl_label = "Detail Size" + bl_idname = "VIEW3D_MT_sv3_dyn_detail" + + def init(self): + settings = (("40", 40), + ("30", 30), + ("20", 20), + ("10", 10), + ("5", 5), + ("1", 1)) + + if bpy.context.tool_settings.sculpt.detail_type_method == 'RELATIVE': + datapath = "tool_settings.sculpt.detail_size" + slider_setting = "detail_size" + + elif bpy.context.tool_settings.sculpt.detail_type_method == 'CONSTANT': + datapath = "tool_settings.sculpt.constant_detail_resolution" + slider_setting = "constant_detail_resolution" + else: + datapath = "tool_settings.sculpt.detail_percent" + slider_setting = "detail_percent" + settings = (("100", 100), + ("75", 75), + ("50", 50), + ("25", 25), + ("10", 10), + ("5", 5)) + + return settings, datapath, slider_setting + + def draw(self, context): + settings, datapath, slider_setting = self.init() + layout = self.layout + + # add the top slider + layout.row().prop(context.tool_settings.sculpt, + slider_setting, slider=True) + layout.row().separator() + + # add the rest of the menu items + for i in range(len(settings)): + utils_core.menuprop( + layout.row(), settings[i][0], settings[i][1], datapath, + icon='RADIOBUT_OFF', disable=True, + disable_icon='RADIOBUT_ON' + ) + + +class DetailMethodMenu(Menu): + bl_label = "Detail Method" + bl_idname = "VIEW3D_MT_sv3_detail_method_menu" + + def draw(self, context): + layout = self.layout + refine_path = "tool_settings.sculpt.detail_refine_method" + type_path = "tool_settings.sculpt.detail_type_method" + + refine_items = (("Subdivide Edges", 'SUBDIVIDE'), + ("Collapse Edges", 'COLLAPSE'), + ("Subdivide Collapse", 'SUBDIVIDE_COLLAPSE')) + + type_items = (("Relative Detail", 'RELATIVE'), + ("Constant Detail", 'CONSTANT'), + ("Brush Detail", 'BRUSH')) + + layout.row().label(text="Refine") + layout.row().separator() + + # add the refine menu items + for item in refine_items: + utils_core.menuprop( + layout.row(), item[0], item[1], + refine_path, disable=True, + icon='RADIOBUT_OFF', + disable_icon='RADIOBUT_ON' + ) + + layout.row().label(text="") + + layout.row().label(text="Type") + layout.row().separator() + + # add the type menu items + for item in type_items: + utils_core.menuprop( + layout.row(), item[0], item[1], + type_path, disable=True, + icon='RADIOBUT_OFF', disable_icon='RADIOBUT_ON' + ) + + +class SymmetrizeMenu(Menu): + bl_label = "Symmetrize" + bl_idname = "VIEW3D_MT_sv3_symmetrize_menu" + + def draw(self, context): + layout = self.layout + path = "tool_settings.sculpt.symmetrize_direction" + + # add the the symmetrize operator to the menu + layout.row().operator("sculpt.symmetrize") + layout.row().separator() + + # add the rest of the menu items + for item in context.tool_settings.sculpt. \ + bl_rna.properties['symmetrize_direction'].enum_items: + utils_core.menuprop( + layout.row(), item.name, item.identifier, + path, disable=True, + icon='RADIOBUT_OFF', disable_icon='RADIOBUT_ON' + ) + + +classes = ( + DynTopoMenu, + DynDetailMenu, + DetailMethodMenu, + SymmetrizeMenu + ) + +def register(): + for cls in classes: + bpy.utils.register_class(cls) + +def unregister(): + for cls in classes: + bpy.utils.unregister_class(cls) diff --git a/space_view3d_brush_menus/stroke_menu.py b/space_view3d_brush_menus/stroke_menu.py new file mode 100644 index 00000000..8c5b0407 --- /dev/null +++ b/space_view3d_brush_menus/stroke_menu.py @@ -0,0 +1,200 @@ +# gpl author: Ryan Inch (Imaginer) + +import bpy +from bpy.types import Menu +from . import utils_core +from .brushes import brush_datapath + +# stroke methods: 'AIRBRUSH' 'ANCHORED' 'SPACE' 'DRAG_DOT' 'DOTS' 'LINE' 'CURVE' + +class PaintCurvesMenu(Menu): + bl_label = "Paint Curves" + bl_idname = "VIEW3D_MT_sv3_paint_curves_menu" + + def draw(self, context): + mode = utils_core.get_mode() + layout = self.layout + colum_n = utils_core.addon_settings() + + layout.row().label(text="Paint Curves") + layout.row().separator() + + has_brush = utils_core.get_brush_link(context, types="brush") + + has_current_curve = has_brush.paint_curve if has_brush else None + current_curve = has_current_curve.name if has_current_curve else '' + + column_flow = layout.column_flow(columns=colum_n) + + if len(bpy.data.paint_curves) != 0: + for x, item in enumerate(bpy.data.paint_curves): + utils_core.menuprop( + column_flow.row(), + item.name, + 'bpy.data.paint_curves["%s"]' % item.name, + brush_datapath[mode] + ".paint_curve", + icon='RADIOBUT_OFF', + disable=True, + disable_icon='RADIOBUT_ON', + custom_disable_exp=(item.name, current_curve), + path=True + ) + + else: + layout.row().label(text="No Paint Curves Available", icon="INFO") + +class StrokeOptionsMenu(Menu): + bl_label = "Stroke Options" + bl_idname = "VIEW3D_MT_sv3_stroke_options" + + @classmethod + def poll(self, context): + return utils_core.get_mode() in ( + 'SCULPT', 'VERTEX_PAINT', + 'WEIGHT_PAINT', 'TEXTURE_PAINT', + 'PARTICLE_EDIT' + ) + + def init(self): + has_brush = utils_core.get_brush_link(bpy.context, types="brush") + if utils_core.get_mode() == 'SCULPT': + settings = bpy.context.tool_settings.sculpt + + elif utils_core.get_mode() == 'VERTEX_PAINT': + settings = bpy.context.tool_settings.vertex_paint + + elif utils_core.get_mode() == 'WEIGHT_PAINT': + settings = bpy.context.tool_settings.weight_paint + + elif utils_core.get_mode() == 'TEXTURE_PAINT': + settings = bpy.context.tool_settings.image_paint + + else: + settings = None + + stroke_method = has_brush.stroke_method if has_brush else None + + return settings, has_brush, stroke_method + + def draw(self, context): + settings, brush, stroke_method = self.init() + layout = self.layout + + layout.row().menu(StrokeMethodMenu.bl_idname) + layout.row().separator() + + if stroke_method: + + if stroke_method in ('SPACE', 'LINE') and brush: + layout.row().prop(brush, "spacing", + text=utils_core.PIW + "Spacing", slider=True) + + elif stroke_method == 'AIRBRUSH' and brush: + layout.row().prop(brush, "rate", + text=utils_core.PIW + "Rate", slider=True) + + elif stroke_method == 'ANCHORED' and brush: + layout.row().prop(brush, "use_edge_to_edge") + + elif stroke_method == 'CURVE' and brush: + has_current_curve = brush.paint_curve if brush else None + current_curve = has_current_curve.name if has_current_curve else 'No Curve Selected' + + layout.row().menu(PaintCurvesMenu.bl_idname, text=current_curve, + icon='CURVE_BEZCURVE') + layout.row().operator("paintcurve.new", icon='ADD') + layout.row().operator("paintcurve.draw") + + layout.row().separator() + + layout.row().prop(brush, "spacing", + text=utils_core.PIW + "Spacing", + slider=True) + + else: + pass + + if utils_core.get_mode() == 'SCULPT' and stroke_method in ('DRAG_DOT', 'ANCHORED'): + pass + else: + if brush: + layout.row().prop(brush, "jitter", + text=utils_core.PIW + "Jitter", slider=True) + + layout.row().prop(settings, "input_samples", + text=utils_core.PIW + "Input Samples", slider=True) + + if stroke_method in ('DOTS', 'SPACE', 'AIRBRUSH') and brush: + layout.row().separator() + + layout.row().prop(brush, "use_smooth_stroke", toggle=True) + + if brush.use_smooth_stroke: + layout.row().prop(brush, "smooth_stroke_radius", + text=utils_core.PIW + "Radius", slider=True) + layout.row().prop(brush, "smooth_stroke_factor", + text=utils_core.PIW + "Factor", slider=True) + else: + layout.row().label(text="No Stroke Options available", icon="INFO") + + +class StrokeMethodMenu(Menu): + bl_label = "Stroke Method" + bl_idname = "VIEW3D_MT_sv3_stroke_method" + + def init(self): + has_brush = utils_core.get_brush_link(bpy.context, types="brush") + if utils_core.get_mode() == 'SCULPT': + path = "tool_settings.sculpt.brush.stroke_method" + + elif utils_core.get_mode() == 'VERTEX_PAINT': + path = "tool_settings.vertex_paint.brush.stroke_method" + + elif utils_core.get_mode() == 'WEIGHT_PAINT': + path = "tool_settings.weight_paint.brush.stroke_method" + + elif utils_core.get_mode() == 'TEXTURE_PAINT': + path = "tool_settings.image_paint.brush.stroke_method" + + else: + path = "" + + return has_brush, path + + def draw(self, context): + brush, path = self.init() + layout = self.layout + + layout.row().label(text="Stroke Method") + layout.row().separator() + + if brush: + # add the menu items dynamically based on values in enum property + for tool in brush.bl_rna.properties['stroke_method'].enum_items: + if tool.identifier in ('ANCHORED', 'DRAG_DOT') and \ + utils_core.get_mode() in ('VERTEX_PAINT', + 'WEIGHT_PAINT'): + continue + + utils_core.menuprop( + layout.row(), tool.name, tool.identifier, path, + icon='RADIOBUT_OFF', disable=True, + disable_icon='RADIOBUT_ON' + ) + else: + layout.row().label(text="No Stroke Method available", icon="INFO") + + +classes = ( + PaintCurvesMenu, + StrokeOptionsMenu, + StrokeMethodMenu + ) + +def register(): + for cls in classes: + bpy.utils.register_class(cls) + +def unregister(): + for cls in classes: + bpy.utils.unregister_class(cls) diff --git a/space_view3d_brush_menus/symmetry_menu.py b/space_view3d_brush_menus/symmetry_menu.py new file mode 100644 index 00000000..21e566d4 --- /dev/null +++ b/space_view3d_brush_menus/symmetry_menu.py @@ -0,0 +1,80 @@ +# gpl author: Ryan Inch (Imaginer) + +import bpy +from bpy.types import Menu +from . import utils_core + + +class MasterSymmetryMenu(Menu): + bl_label = "Symmetry Options" + bl_idname = "VIEW3D_MT_sv3_master_symmetry_menu" + + @classmethod + def poll(self, context): + return utils_core.get_mode() in ( + 'SCULPT', + 'TEXTURE_PAINT' + ) + + def draw(self, context): + layout = self.layout + + if utils_core.get_mode() == 'TEXTURE_PAINT': + layout.row().prop(context.tool_settings.image_paint, + "use_symmetry_x", toggle=True) + layout.row().prop(context.tool_settings.image_paint, + "use_symmetry_y", toggle=True) + layout.row().prop(context.tool_settings.image_paint, + "use_symmetry_z", toggle=True) + else: + layout.row().menu(SymmetryMenu.bl_idname) + layout.row().menu(SymmetryRadialMenu.bl_idname) + layout.row().prop(context.tool_settings.sculpt, + "use_symmetry_feather", toggle=True) + + +class SymmetryMenu(Menu): + bl_label = "Symmetry" + bl_idname = "VIEW3D_MT_sv3_symmetry_menu" + + def draw(self, context): + layout = self.layout + + layout.row().label(text="Symmetry") + layout.row().separator() + + layout.row().prop(context.tool_settings.sculpt, + "use_symmetry_x", toggle=True) + layout.row().prop(context.tool_settings.sculpt, + "use_symmetry_y", toggle=True) + layout.row().prop(context.tool_settings.sculpt, + "use_symmetry_z", toggle=True) + + +class SymmetryRadialMenu(Menu): + bl_label = "Radial" + bl_idname = "VIEW3D_MT_sv3_symmetry_radial_menu" + + def draw(self, context): + layout = self.layout + + layout.row().label(text="Radial") + layout.row().separator() + + layout.column().prop(context.tool_settings.sculpt, + "radial_symmetry", text="", slider=True) + + +classes = ( + MasterSymmetryMenu, + SymmetryMenu, + SymmetryRadialMenu + ) + +def register(): + for cls in classes: + bpy.utils.register_class(cls) + +def unregister(): + for cls in classes: + bpy.utils.unregister_class(cls) diff --git a/space_view3d_brush_menus/texture_menu.py b/space_view3d_brush_menus/texture_menu.py new file mode 100644 index 00000000..94484538 --- /dev/null +++ b/space_view3d_brush_menus/texture_menu.py @@ -0,0 +1,415 @@ +# gpl author: Ryan Inch (Imaginer) + +import bpy +from bpy.types import Menu +from . import utils_core + + +class TextureMenu(Menu): + bl_label = "Texture Options" + bl_idname = "VIEW3D_MT_sv3_texture_menu" + + @classmethod + def poll(self, context): + return utils_core.get_mode() in ( + 'SCULPT', + 'VERTEX_PAINT', + 'TEXTURE_PAINT' + ) + + def draw(self, context): + layout = self.layout + + if utils_core.get_mode() == 'SCULPT': + self.sculpt(layout, context) + + elif utils_core.get_mode() == 'VERTEX_PAINT': + self.vertpaint(layout, context) + + else: + self.texpaint(layout, context) + + def sculpt(self, layout, context): + has_brush = utils_core.get_brush_link(context, types="brush") + tex_slot = has_brush.texture_slot if has_brush else None + + # Menus + layout.row().menu(Textures.bl_idname) + layout.row().menu(TextureMapMode.bl_idname) + layout.row().separator() + + # Checkboxes + if tex_slot: + if tex_slot.map_mode != '3D': + if tex_slot.map_mode in ('RANDOM', 'VIEW_PLANE', 'AREA_PLANE'): + layout.row().prop(tex_slot, "use_rake", toggle=True) + layout.row().prop(tex_slot, "use_random", toggle=True) + + # Sliders + layout.row().prop(tex_slot, "angle", + text=utils_core.PIW + "Angle", slider=True) + + if tex_slot.tex_paint_map_mode in ('RANDOM', 'VIEW_PLANE') and tex_slot.use_random: + layout.row().prop(tex_slot, "random_angle", + text=utils_core.PIW + "Random Angle", slider=True) + + # Operator + if tex_slot.tex_paint_map_mode == 'STENCIL': + if has_brush.texture and has_brush.texture.type == 'IMAGE': + layout.row().operator("brush.stencil_fit_image_aspect") + + layout.row().operator("brush.stencil_reset_transform") + + else: + layout.row().label(text="No Texture Slot available", icon="INFO") + + def vertpaint(self, layout, context): + has_brush = utils_core.get_brush_link(context, types="brush") + tex_slot = has_brush.texture_slot if has_brush else None + + # Menus + layout.row().menu(Textures.bl_idname) + layout.row().menu(TextureMapMode.bl_idname) + + # Checkboxes + if tex_slot: + if tex_slot.tex_paint_map_mode != '3D': + if tex_slot.tex_paint_map_mode in ('RANDOM', 'VIEW_PLANE'): + layout.row().prop(tex_slot, "use_rake", toggle=True) + layout.row().prop(tex_slot, "use_random", toggle=True) + + # Sliders + layout.row().prop(tex_slot, "angle", + text=utils_core.PIW + "Angle", slider=True) + + if tex_slot.tex_paint_map_mode in ('RANDOM', 'VIEW_PLANE') and tex_slot.use_random: + layout.row().prop(tex_slot, "random_angle", + text=utils_core.PIW + "Random Angle", slider=True) + + # Operator + if tex_slot.tex_paint_map_mode == 'STENCIL': + if has_brush.texture and has_brush.texture.type == 'IMAGE': + layout.row().operator("brush.stencil_fit_image_aspect") + + layout.row().operator("brush.stencil_reset_transform") + + else: + layout.row().label(text="No Texture Slot available", icon="INFO") + + def texpaint(self, layout, context): + has_brush = utils_core.get_brush_link(context, types="brush") + tex_slot = has_brush.texture_slot if has_brush else None + mask_tex_slot = has_brush.mask_texture_slot if has_brush else None + + # Texture Section + layout.row().label(text="Texture", icon='TEXTURE') + + # Menus + layout.row().menu(Textures.bl_idname) + layout.row().menu(TextureMapMode.bl_idname) + + # Checkboxes + if tex_slot: + if tex_slot.tex_paint_map_mode != '3D': + if tex_slot.tex_paint_map_mode in ('RANDOM', 'VIEW_PLANE'): + layout.row().prop(tex_slot, "use_rake", toggle=True) + layout.row().prop(tex_slot, "use_random", toggle=True) + + # Sliders + layout.row().prop(tex_slot, "angle", + text=utils_core.PIW + "Angle", slider=True) + + if tex_slot.tex_paint_map_mode in ('RANDOM', 'VIEW_PLANE') and tex_slot.use_random: + layout.row().prop(tex_slot, "random_angle", + text=utils_core.PIW + "Random Angle", slider=True) + + # Operator + if tex_slot.tex_paint_map_mode == 'STENCIL': + if has_brush.texture and has_brush.texture.type == 'IMAGE': + layout.row().operator("brush.stencil_fit_image_aspect") + + layout.row().operator("brush.stencil_reset_transform") + + else: + layout.row().label(text="No Texture Slot available", icon="INFO") + + layout.row().separator() + + # Texture Mask Section + layout.row().label(text="Texture Mask", icon='MOD_MASK') + + # Menus + layout.row().menu(MaskTextures.bl_idname) + layout.row().menu(MaskMapMode.bl_idname) + layout.row().menu(MaskPressureModeMenu.bl_idname) + + # Checkboxes + if mask_tex_slot: + if mask_tex_slot.mask_map_mode in ('RANDOM', 'VIEW_PLANE'): + layout.row().prop(mask_tex_slot, "use_rake", toggle=True) + layout.row().prop(mask_tex_slot, "use_random", toggle=True) + + # Sliders + layout.row().prop(mask_tex_slot, "angle", + text=utils_core.PIW + "Angle", icon_value=5, slider=True) + + if mask_tex_slot.mask_map_mode in ('RANDOM', 'VIEW_PLANE') and mask_tex_slot.use_random: + layout.row().prop(mask_tex_slot, "random_angle", + text=utils_core.PIW + "Random Angle", slider=True) + + # Operator + if mask_tex_slot.mask_map_mode == 'STENCIL': + if has_brush.mask_texture and has_brush.mask_texture.type == 'IMAGE': + layout.row().operator("brush.stencil_fit_image_aspect") + + prop = layout.row().operator("brush.stencil_reset_transform") + prop.mask = True + + else: + layout.row().label(text="Mask Texture not available", icon="INFO") + + +class Textures(Menu): + bl_label = "Brush Texture" + bl_idname = "VIEW3D_MT_sv3_texture_list" + + def init(self): + if utils_core.get_mode() == 'SCULPT': + datapath = "tool_settings.sculpt.brush.texture" + + elif utils_core.get_mode() == 'VERTEX_PAINT': + datapath = "tool_settings.vertex_paint.brush.texture" + + elif utils_core.get_mode() == 'TEXTURE_PAINT': + datapath = "tool_settings.image_paint.brush.texture" + + else: + datapath = "" + + return datapath + + def draw(self, context): + datapath = self.init() + has_brush = utils_core.get_brush_link(context, types="brush") + current_texture = eval("bpy.context.{}".format(datapath)) if \ + has_brush else None + layout = self.layout + + # get the current texture's name + if current_texture: + current_texture = current_texture.name + + layout.row().label(text="Brush Texture") + layout.row().separator() + + # add an item to set the texture to None + utils_core.menuprop(layout.row(), "None", "None", + datapath, icon='RADIOBUT_OFF', disable=True, + disable_icon='RADIOBUT_ON', + custom_disable_exp=(None, current_texture), + path=True) + + # add the menu items + for item in bpy.data.textures: + utils_core.menuprop(layout.row(), item.name, + 'bpy.data.textures["%s"]' % item.name, + datapath, icon='RADIOBUT_OFF', + disable=True, + disable_icon='RADIOBUT_ON', + custom_disable_exp=(item.name, current_texture), + path=True) + + +class TextureMapMode(Menu): + bl_label = "Brush Mapping" + bl_idname = "VIEW3D_MT_sv3_texture_map_mode" + + def draw(self, context): + layout = self.layout + has_brush = utils_core.get_brush_link(context, types="brush") + + layout.row().label(text="Brush Mapping") + layout.row().separator() + + if has_brush: + if utils_core.get_mode() == 'SCULPT': + path = "tool_settings.sculpt.brush.texture_slot.map_mode" + + # add the menu items + for item in has_brush. \ + texture_slot.bl_rna.properties['map_mode'].enum_items: + utils_core.menuprop( + layout.row(), item.name, item.identifier, path, + icon='RADIOBUT_OFF', + disable=True, + disable_icon='RADIOBUT_ON' + ) + elif utils_core.get_mode() == 'VERTEX_PAINT': + path = "tool_settings.vertex_paint.brush.texture_slot.tex_paint_map_mode" + + # add the menu items + for item in has_brush. \ + texture_slot.bl_rna.properties['tex_paint_map_mode'].enum_items: + utils_core.menuprop( + layout.row(), item.name, item.identifier, path, + icon='RADIOBUT_OFF', + disable=True, + disable_icon='RADIOBUT_ON' + ) + else: + path = "tool_settings.image_paint.brush.texture_slot.tex_paint_map_mode" + + # add the menu items + for item in has_brush. \ + texture_slot.bl_rna.properties['tex_paint_map_mode'].enum_items: + utils_core.menuprop( + layout.row(), item.name, item.identifier, path, + icon='RADIOBUT_OFF', + disable=True, + disable_icon='RADIOBUT_ON' + ) + else: + layout.row().label(text="No brushes available", icon="INFO") + + +class MaskTextures(Menu): + bl_label = "Mask Texture" + bl_idname = "VIEW3D_MT_sv3_mask_texture_list" + + def draw(self, context): + layout = self.layout + datapath = "tool_settings.image_paint.brush.mask_texture" + has_brush = utils_core.get_brush_link(context, types="brush") + current_texture = eval("bpy.context.{}".format(datapath)) if \ + has_brush else None + + layout.row().label(text="Mask Texture") + layout.row().separator() + + if has_brush: + # get the current texture's name + if current_texture: + current_texture = current_texture.name + + # add an item to set the texture to None + utils_core.menuprop( + layout.row(), "None", "None", + datapath, icon='RADIOBUT_OFF', disable=True, + disable_icon='RADIOBUT_ON', + custom_disable_exp=(None, current_texture), + path=True + ) + + # add the menu items + for item in bpy.data.textures: + utils_core.menuprop( + layout.row(), item.name, 'bpy.data.textures["%s"]' % item.name, + datapath, icon='RADIOBUT_OFF', disable=True, + disable_icon='RADIOBUT_ON', + custom_disable_exp=(item.name, current_texture), + path=True + ) + else: + layout.row().label(text="No brushes available", icon="INFO") + + +class MaskMapMode(Menu): + bl_label = "Mask Mapping" + bl_idname = "VIEW3D_MT_sv3_mask_map_mode" + + def draw(self, context): + layout = self.layout + path = "tool_settings.image_paint.brush.mask_texture_slot.mask_map_mode" + has_brush = utils_core.get_brush_link(context, types="brush") + + layout.row().label(text="Mask Mapping") + layout.row().separator() + if has_brush: + items = has_brush. \ + mask_texture_slot.bl_rna.properties['mask_map_mode'].enum_items + # add the menu items + for item in items: + utils_core.menuprop( + layout.row(), item.name, item.identifier, path, + icon='RADIOBUT_OFF', + disable=True, + disable_icon='RADIOBUT_ON' + ) + else: + layout.row().label(text="No brushes available", icon="INFO") + + +class TextureAngleSource(Menu): + bl_label = "Texture Angle Source" + bl_idname = "VIEW3D_MT_sv3_texture_angle_source" + + def draw(self, context): + layout = self.layout + has_brush = utils_core.get_brush_link(context, types="brush") + + if has_brush: + if utils_core.get_mode() == 'SCULPT': + items = has_brush. \ + bl_rna.properties['texture_angle_source_random'].enum_items + path = "tool_settings.sculpt.brush.texture_angle_source_random" + + elif utils_core.get_mode() == 'VERTEX_PAINT': + items = has_brush. \ + bl_rna.properties['texture_angle_source_random'].enum_items + path = "tool_settings.vertex_paint.brush.texture_angle_source_random" + + else: + items = has_brush. \ + bl_rna.properties['texture_angle_source_random'].enum_items + path = "tool_settings.image_paint.brush.texture_angle_source_random" + + # add the menu items + for item in items: + utils_core.menuprop( + layout.row(), item[0], item[1], path, + icon='RADIOBUT_OFF', + disable=True, + disable_icon='RADIOBUT_ON' + ) + else: + layout.row().label(text="No brushes available", icon="INFO") + +class MaskPressureModeMenu(Menu): + bl_label = "Mask Pressure Mode" + bl_idname = "VIEW3D_MT_sv3_mask_pressure_mode_menu" + + def draw(self, context): + layout = self.layout + path = "tool_settings.image_paint.brush.use_pressure_masking" + + layout.row().label(text="Mask Pressure Mode") + layout.row().separator() + + # add the menu items + for item in context.tool_settings.image_paint.brush. \ + bl_rna.properties['use_pressure_masking'].enum_items: + utils_core.menuprop( + layout.row(), item.name, item.identifier, path, + icon='RADIOBUT_OFF', + disable=True, + disable_icon='RADIOBUT_ON' + ) + + +classes = ( + TextureMenu, + Textures, + TextureMapMode, + MaskTextures, + MaskMapMode, + TextureAngleSource, + MaskPressureModeMenu + ) + +def register(): + for cls in classes: + bpy.utils.register_class(cls) + +def unregister(): + for cls in classes: + bpy.utils.unregister_class(cls) diff --git a/space_view3d_brush_menus/utils_core.py b/space_view3d_brush_menus/utils_core.py new file mode 100644 index 00000000..dc99ba0b --- /dev/null +++ b/space_view3d_brush_menus/utils_core.py @@ -0,0 +1,105 @@ +# gpl author: Ryan Inch (Imaginer) + +import bpy + +get_addon_name = 'space_view3d_brush_menus' + +# Property Icon Width +PIW = ' ' + + +# check for (currently) brushes being linked +def get_brush_link(context, types="brush"): + tool_settings = context.tool_settings + has_brush = None + + if get_mode() == 'SCULPT': + datapath = tool_settings.sculpt + + elif get_mode() == 'VERTEX_PAINT': + datapath = tool_settings.vertex_paint + + elif get_mode() == 'WEIGHT_PAINT': + datapath = tool_settings.weight_paint + + elif get_mode() == 'TEXTURE_PAINT': + datapath = tool_settings.image_paint + else: + datapath = None + + if types == "brush": + has_brush = getattr(datapath, "brush", None) + + return has_brush + + +# Addon settings +def addon_settings(): + # separate function just for more convenience + addon = bpy.context.preferences.addons[get_addon_name] + colum_n = addon.preferences.column_set if addon else 1 + + return colum_n + + +def error_handlers(self, op_name, error, reports="ERROR", func=False): + if self and reports: + self.report({'WARNING'}, reports + " (See Console for more info)") + + is_func = "Function" if func else "Operator" + print("\n[Sculpt/Paint Brush Menus]\n{}: {}\nError: {}\n".format(is_func, op_name, error)) + + +# Object modes: +# 'OBJECT' 'EDIT' 'SCULPT' +# 'VERTEX_PAINT' 'WEIGHT_PAINT' 'TEXTURE_PAINT' +# 'PARTICLE_EDIT' 'POSE' 'GPENCIL_EDIT' +def get_mode(): + return bpy.context.object.mode + +def menuprop(item, name, value, data_path, + icon='NONE', disable=False, disable_icon=None, + custom_disable_exp=None, method=None, path=False): + + # disable the ui + if disable: + disabled = False + + # used if you need a custom expression to disable the ui + if custom_disable_exp: + if custom_disable_exp[0] == custom_disable_exp[1]: + item.enabled = False + disabled = True + + # check if the ui should be disabled for numbers + elif isinstance(eval("bpy.context.{}".format(data_path)), float): + if round(eval("bpy.context.{}".format(data_path)), 2) == value: + item.enabled = False + disabled = True + + # check if the ui should be disabled for anything else + else: + if eval("bpy.context.{}".format(data_path)) == value: + item.enabled = False + disabled = True + + # change the icon to the disable_icon if the ui has been disabled + if disable_icon and disabled: + icon = disable_icon + + # creates the menu item + prop = item.operator("wm.context_set_value", text=name, icon=icon) + + # sets what the menu item changes + if path: + prop.value = value + value = eval(value) + + elif type(value) == str: + prop.value = "'{}'".format(value) + + else: + prop.value = '{}'.format(value) + + # sets the path to what is changed + prop.data_path = data_path diff --git a/space_view3d_pie_menus/pie_modes_menu.py b/space_view3d_pie_menus/pie_modes_menu.py index bcaf4af6..1f4f15a1 100644 --- a/space_view3d_pie_menus/pie_modes_menu.py +++ b/space_view3d_pie_menus/pie_modes_menu.py @@ -196,25 +196,6 @@ class PIE_OT_VertsEdgesFaces(Operator): return {'FINISHED'} -# Grease Pencil Interactive Mode -class PIE_OT_InteractiveModeGreasePencil(Operator): - bl_idname = "view3d.pie_interactive_mode_grease_pencil" - bl_label = "Edit Strokes" - bl_description = "Toggle Edit Strokes for Grease Pencil" - - @classmethod - def poll(cls, context): - return (context.gpencil_data is not None) - - def execute(self, context): - try: - bpy.ops.gpencil.editmode_toggle() - except: - self.report({'WARNING'}, - "It is not possible to enter into the interactive mode") - return {'FINISHED'} - - # Menus class PIE_MT_ObjectEditotherModes(Menu): """Edit/Object Others modes""" @@ -267,13 +248,12 @@ class PIE_MT_ObjectEditMode(Menu): # 9 - TOP - RIGHT pie.operator("class.pievertexpaint", text="Vertex Paint", icon='VPAINT_HLT') # 1 - BOTTOM - LEFT + pie.separator() + # 3 - BOTTOM - RIGHT if context.object.particle_systems: pie.operator("class.pieparticleedit", text="Particle Edit", icon='PARTICLEMODE') else: pie.separator() - # 3 - BOTTOM - RIGHT - if context.gpencil_data: - pie.operator("view3d.pie_interactive_mode_grease_pencil", icon="GREASEPENCIL") elif ob and ob.type == 'MESH' and ob.mode in {'EDIT'}: pie = layout.menu_pie() @@ -290,13 +270,12 @@ class PIE_MT_ObjectEditMode(Menu): # 9 - TOP - RIGHT pie.operator("class.pievertexpaint", text="Vertex Paint", icon='VPAINT_HLT') # 1 - BOTTOM - LEFT + pie.separator() + # 3 - BOTTOM - RIGHT if context.object.particle_systems: pie.operator("class.pieparticleedit", text="Particle Edit", icon='PARTICLEMODE') else: pie.separator() - # 3 - BOTTOM - RIGHT - if context.gpencil_data: - pie.operator("view3d.pie_interactive_mode_grease_pencil", icon="GREASEPENCIL") elif ob and ob.type == 'CURVE': pie = layout.menu_pie() @@ -315,8 +294,7 @@ class PIE_MT_ObjectEditMode(Menu): # 1 - BOTTOM - LEFT pie.separator() # 3 - BOTTOM - RIGHT - if context.gpencil_data: - pie.operator("view3d.pie_interactive_mode_grease_pencil", icon="GREASEPENCIL") + pie.separator() elif ob and ob.type == 'ARMATURE': pie = layout.menu_pie() @@ -335,8 +313,7 @@ class PIE_MT_ObjectEditMode(Menu): # 1 - BOTTOM - LEFT pie.separator() # 3 - BOTTOM - RIGHT - if context.gpencil_data: - pie.operator("view3d.pie_interactive_mode_grease_pencil", icon="GREASEPENCIL") + pie.separator() elif ob and ob.type == 'FONT': pie = layout.menu_pie() @@ -348,8 +325,7 @@ class PIE_MT_ObjectEditMode(Menu): pie.separator() pie.separator() # 3 - BOTTOM - RIGHT - if context.gpencil_data: - pie.operator("view3d.pie_interactive_mode_grease_pencil", icon="GREASEPENCIL") + pie.separator() elif ob and ob.type == 'SURFACE': pie = layout.menu_pie() @@ -361,8 +337,7 @@ class PIE_MT_ObjectEditMode(Menu): pie.separator() pie.separator() # 3 - BOTTOM - RIGHT - if context.gpencil_data: - pie.operator("view3d.pie_interactive_mode_grease_pencil", icon="GREASEPENCIL") + pie.separator() elif ob and ob.type == 'META': pie = layout.menu_pie() @@ -374,8 +349,7 @@ class PIE_MT_ObjectEditMode(Menu): pie.separator() pie.separator() # 3 - BOTTOM - RIGHT - if context.gpencil_data: - pie.operator("view3d.pie_interactive_mode_grease_pencil", icon="GREASEPENCIL") + pie.separator() elif ob and ob.type == 'LATTICE': pie = layout.menu_pie() @@ -429,7 +403,6 @@ classes = ( PIE_OT_ClassWeightPaint, PIE_OT_ClassVertexPaint, PIE_OT_ClassParticleEdit, - PIE_OT_InteractiveModeGreasePencil, PIE_OT_VertsEdgesFaces, PIE_OT_SetObjectModePie, ) diff --git a/space_view3d_spacebar_menu/__init__.py b/space_view3d_spacebar_menu/__init__.py index 2cf797ef..201b9506 100644 --- a/space_view3d_spacebar_menu/__init__.py +++ b/space_view3d_spacebar_menu/__init__.py @@ -35,26 +35,23 @@ if "bpy" in locals(): importlib.reload(object_menus) importlib.reload(edit_mesh) importlib.reload(transform_menus) - importlib.reload(select_menus) importlib.reload(view_menus) importlib.reload(armature_menus) importlib.reload(curve_menus) importlib.reload(snap_origin_cursor) - importlib.reload(sculpt_brush_paint) importlib.reload(animation_menus) else: from . import object_menus from . import edit_mesh from . import transform_menus - from . import select_menus from . import view_menus from . import armature_menus from . import curve_menus from . import snap_origin_cursor - from . import sculpt_brush_paint from . import animation_menus + import bpy from bpy.types import ( Operator, @@ -66,8 +63,6 @@ from bpy.props import ( StringProperty, ) -from bl_ui.properties_paint_common import UnifiedPaintPanel - # Dynamic Context Sensitive Menu # # Main Menu based on Object Type & 3d View Editor Mode # @@ -81,6 +76,7 @@ class VIEW3D_MT_Space_Dynamic_Menu(Menu): layout.operator_context = 'INVOKE_REGION_WIN' obj = context.active_object view = context.space_data + # No Object Selected # ob = bpy.context.object if not ob or not ob.select_get(): @@ -95,8 +91,9 @@ class VIEW3D_MT_Space_Dynamic_Menu(Menu): layout.menu("INFO_MT_area", icon='WORKSPACE') layout.menu("VIEW3D_MT_view_viewpoint", icon='ZOOM_ALL') layout.menu("VIEW3D_MT_view_navigation", icon='PIVOT_BOUNDBOX') + layout.menu("VIEW3D_MT_select_object", icon='RESTRICT_SELECT_OFF') UseSeparator(self, context) - layout.menu("VIEW3D_MT_AddMenu", icon='OBJECT_DATAMODE') + layout.menu("VIEW3D_MT_add", icon='MESH_CUBE') UseSeparator(self, context) layout.operator("view3d.snap_cursor_to_center", text="Cursor to World Origin") @@ -118,34 +115,26 @@ class VIEW3D_MT_Space_Dynamic_Menu(Menu): layout.menu("VIEW3D_MT_Animation_Player", text="Animation", icon='PLAY') layout.menu("SCREEN_MT_user_menu", text="Quick Favorites", icon='HEART') + layout.menu("VIEW3D_MT_InteractiveMode", icon='VIEW3D') UseSeparator(self, context) - layout.menu("VIEW3D_MT_InteractiveMode", icon='EDITMODE_HLT') - layout.menu("VIEW3D_MT_view", icon='ZOOM_ALL') - layout.menu("VIEW3D_MT_Select_Object", icon='RESTRICT_SELECT_OFF') - UseSeparator(self, context) - layout.menu("VIEW3D_MT_AddMenu", icon='OBJECT_DATAMODE') - layout.menu("VIEW3D_MT_Object", icon='VIEW3D') + layout.menu("VIEW3D_MT_View_Menu", icon='ZOOM_ALL') + layout.menu("VIEW3D_MT_select_object", icon='RESTRICT_SELECT_OFF') + layout.menu("VIEW3D_MT_add", icon='MESH_CUBE') + layout.menu("VIEW3D_MT_Camera_Options", icon='CAMERA_DATA') UseSeparator(self, context) + layout.menu("VIEW3D_MT_Object", icon='OBJECT_DATAMODE') layout.menu("VIEW3D_MT_TransformMenu", icon='EMPTY_ARROWS') - layout.menu("VIEW3D_MT_MirrorMenu", icon='MOD_MIRROR') layout.menu("VIEW3D_MT_CursorMenu", icon='PIVOT_CURSOR') UseSeparator(self, context) - layout.menu("VIEW3D_MT_ParentMenu", icon='PIVOT_ACTIVE') - layout.menu("VIEW3D_MT_GroupMenu", icon='GROUP') + layout.menu("VIEW3D_MT_object_collection", text = "Collections", icon='GROUP') UseSeparator(self, context) - layout.menu("VIEW3D_MT_object_context_menu", text="Specials", icon='SOLO_OFF') -# if context.gpencil_data and context.gpencil_data.use_stroke_edit_mode: -# layout.menu("VIEW3D_MT_Edit_Gpencil", icon='GREASEPENCIL') - layout.menu("VIEW3D_MT_Camera_Options", icon='OUTLINER_OB_CAMERA') layout.operator_menu_enum("object.modifier_add", "type", icon='MODIFIER') - layout.operator_menu_enum("object.constraint_add", - "type", text="Add Constraint", icon='CONSTRAINT') UseSeparator(self, context) layout.operator("object.delete", text="Delete Object", icon='X') UseSeparator(self, context) layout.menu("VIEW3D_MT_UndoS", icon='ARROW_LEFTRIGHT') - # Mesh Edit Mode # +# Mesh Edit Mode # if obj and obj.type == 'MESH' and obj.mode in {'EDIT'}: layout.operator("wm.search_menu", text="Search", icon='VIEWZOOM') @@ -153,32 +142,29 @@ class VIEW3D_MT_Space_Dynamic_Menu(Menu): layout.menu("VIEW3D_MT_Animation_Player", text="Animation", icon='PLAY') layout.menu("SCREEN_MT_user_menu", text="Quick Favorites", icon='HEART') - UseSeparator(self, context) layout.menu("VIEW3D_MT_InteractiveMode", icon='EDITMODE_HLT') - layout.menu("VIEW3D_MT_view", icon='ZOOM_ALL') - layout.menu("VIEW3D_MT_Select_Edit_Mesh", icon='RESTRICT_SELECT_OFF') layout.menu("VIEW3D_MT_Edit_Multi", icon='VERTEXSEL') UseSeparator(self, context) - layout.menu("VIEW3D_MT_mesh_add", text="Add Mesh", icon='OUTLINER_OB_MESH') - layout.menu("VIEW3D_MT_Edit_Mesh", text="Mesh", icon='MESH_DATA') + layout.menu("VIEW3D_MT_View_Menu", icon='ZOOM_ALL') + layout.menu("VIEW3D_MT_select_edit_mesh", icon='RESTRICT_SELECT_OFF') + layout.menu("VIEW3D_MT_mesh_add", text="Add Mesh", icon='MESH_CUBE') + layout.menu("VIEW3D_MT_edit_mesh", text="Mesh", icon='MESH_DATA') UseSeparator(self, context) - layout.menu("VIEW3D_MT_TransformMenuEdit", icon='EMPTY_ARROWS') - layout.menu("VIEW3D_MT_MirrorMenuEM", icon='MOD_MIRROR') - layout.menu("VIEW3D_MT_EditCursorMenu", icon='PIVOT_CURSOR') + layout.menu("VIEW3D_MT_edit_mesh_vertices", icon='VERTEXSEL') + layout.menu("VIEW3D_MT_edit_mesh_edges", icon='EDGESEL') + layout.menu("VIEW3D_MT_edit_mesh_faces", icon='FACESEL') UseSeparator(self, context) - layout.menu("VIEW3D_MT_UV_Map", icon='MOD_UVPROJECT') - layout.menu("VIEW3D_MT_edit_mesh_context_menu", text="Specials", icon='SOLO_OFF') - layout.menu("VIEW3D_MT_edit_mesh_extrude", icon='XRAY') + layout.menu("VIEW3D_MT_uv_map", icon='MOD_UVPROJECT') + UseSeparator(self, context) + layout.menu("VIEW3D_MT_EditCursorMenu", icon='PIVOT_CURSOR') UseSeparator(self, context) layout.operator_menu_enum("object.modifier_add", "type", icon='MODIFIER') - layout.operator_menu_enum("object.constraint_add", - "type", text="Add Constraint", icon='CONSTRAINT') UseSeparator(self, context) layout.menu("VIEW3D_MT_edit_mesh_delete", icon='X') UseSeparator(self, context) layout.menu("VIEW3D_MT_UndoS", icon='ARROW_LEFTRIGHT') - # Sculpt Mode # +# Sculpt Mode # if obj and obj.type == 'MESH' and obj.mode in {'SCULPT'}: layout.operator("wm.search_menu", text="Search", icon='VIEWZOOM') @@ -186,20 +172,13 @@ class VIEW3D_MT_Space_Dynamic_Menu(Menu): layout.menu("VIEW3D_MT_Animation_Player", text="Animation", icon='PLAY') layout.menu("SCREEN_MT_user_menu", text="Quick Favorites", icon='HEART') - UseSeparator(self, context) layout.menu("VIEW3D_MT_InteractiveMode", icon='EDITMODE_HLT') - layout.menu("VIEW3D_MT_view", icon='ZOOM_ALL') - UseSeparator(self, context) - layout.menu("VIEW3D_MT_Sculpts", icon='SCULPTMODE_HLT') - layout.menu("VIEW3D_MT_Angle_Control", text="Angle Control", icon='BRUSH_SCULPT_DRAW') - layout.menu("VIEW3D_MT_Brush_Settings", icon='BRUSH_DATA') - layout.menu("VIEW3D_MT_Hide_Masks", icon='RESTRICT_VIEW_OFF') - UseSeparator(self, context) - layout.menu("VIEW3D_MT_Sculpt_Specials", icon='SOLO_OFF') UseSeparator(self, context) + layout.menu("VIEW3D_MT_view", icon='ZOOM_ALL') + layout.menu("VIEW3D_MT_sculpt", icon='SCULPTMODE_HLT') layout.menu("VIEW3D_MT_UndoS", icon='ARROW_LEFTRIGHT') - # Vertex Paint # +# Vertex Paint # if obj and obj.type == 'MESH' and obj.mode in {'VERTEX_PAINT'}: layout.operator("wm.search_menu", text="Search", icon='VIEWZOOM') @@ -207,18 +186,13 @@ class VIEW3D_MT_Space_Dynamic_Menu(Menu): text="Animation", icon='PLAY') layout.operator("wm.toolbar", text="Tools", icon='TOOL_SETTINGS') layout.menu("SCREEN_MT_user_menu", text="Quick Favorites", icon='HEART') - UseSeparator(self, context) layout.menu("VIEW3D_MT_InteractiveMode", icon='EDITMODE_HLT') - layout.menu("VIEW3D_MT_view", icon='ZOOM_ALL') - UseSeparator(self, context) - # layout.menu("VIEW3D_MT_Brush_Settings", icon='BRUSH_DATA') - layout.menu("VIEW3D_MT_Brush_Selection", - text="Vertex Paint Tool") - layout.menu("VIEW3D_MT_Vertex_Colors", icon='GROUP_VCOL') UseSeparator(self, context) + layout.menu("VIEW3D_MT_view", icon='ZOOM_ALL') + layout.menu("VIEW3D_MT_paint_vertex", icon='VPAINT_HLT') layout.menu("VIEW3D_MT_UndoS", icon='ARROW_LEFTRIGHT') - # Weight Paint Menu # +# Weight Paint Menu # if obj and obj.type == 'MESH' and obj.mode in {'WEIGHT_PAINT'}: layout.operator("wm.search_menu", text="Search", icon='VIEWZOOM') @@ -226,18 +200,13 @@ class VIEW3D_MT_Space_Dynamic_Menu(Menu): text="Animation", icon='PLAY') layout.operator("wm.toolbar", text="Tools", icon='TOOL_SETTINGS') layout.menu("SCREEN_MT_user_menu", text="Quick Favorites", icon='HEART') - UseSeparator(self, context) layout.menu("VIEW3D_MT_InteractiveMode", icon='EDITMODE_HLT') - layout.menu("VIEW3D_MT_view", icon='ZOOM_ALL') - UseSeparator(self, context) - layout.menu("VIEW3D_MT_Paint_Weights", icon='WPAINT_HLT') - # layout.menu("VIEW3D_MT_Brush_Settings", icon='BRUSH_DATA') - layout.menu("VIEW3D_MT_Brush_Selection", - text="Weight Paint Tool", icon='BRUSH_TEXMASK') UseSeparator(self, context) + layout.menu("VIEW3D_MT_view", icon='ZOOM_ALL') + layout.menu("VIEW3D_MT_paint_weight", icon='WPAINT_HLT') layout.menu("VIEW3D_MT_UndoS", icon='ARROW_LEFTRIGHT') - # Texture Paint # +# Texture Paint # if obj and obj.type == 'MESH' and obj.mode in {'TEXTURE_PAINT'}: layout.operator("wm.search_menu", text="Search", icon='VIEWZOOM') @@ -245,16 +214,12 @@ class VIEW3D_MT_Space_Dynamic_Menu(Menu): text="Animation", icon='PLAY') layout.operator("wm.toolbar", text="Tools", icon='TOOL_SETTINGS') layout.menu("SCREEN_MT_user_menu", text="Quick Favorites", icon='HEART') - UseSeparator(self, context) layout.menu("VIEW3D_MT_InteractiveMode", icon='EDITMODE_HLT') - layout.menu("VIEW3D_MT_view", icon='ZOOM_ALL') - # layout.menu("VIEW3D_MT_Brush_Settings", icon='BRUSH_DATA') - layout.menu("VIEW3D_MT_Brush_Selection", - text="Texture Paint Tool", icon='SCULPTMODE_HLT') UseSeparator(self, context) + layout.menu("VIEW3D_MT_view", icon='ZOOM_ALL') layout.menu("VIEW3D_MT_UndoS", icon='ARROW_LEFTRIGHT') - # Curve Object Mode # +# Curve Object Mode # if obj and obj.type == 'CURVE' and obj.mode in {'OBJECT'}: layout.operator_context = 'INVOKE_REGION_WIN' @@ -263,33 +228,26 @@ class VIEW3D_MT_Space_Dynamic_Menu(Menu): layout.menu("VIEW3D_MT_Animation_Player", text="Animation", icon='PLAY') layout.menu("SCREEN_MT_user_menu", text="Quick Favorites", icon='HEART') - UseSeparator(self, context) layout.menu("VIEW3D_MT_Object_Interactive_Other", icon='OBJECT_DATA') - layout.menu("VIEW3D_MT_view", icon='ZOOM_ALL') - layout.menu("VIEW3D_MT_Select_Object", icon='RESTRICT_SELECT_OFF') UseSeparator(self, context) - layout.menu("VIEW3D_MT_AddMenu", icon='OBJECT_DATAMODE') - layout.menu("VIEW3D_MT_Object", icon='VIEW3D') + layout.menu("VIEW3D_MT_View_Menu", icon='ZOOM_ALL') + layout.menu("VIEW3D_MT_select_object", icon='RESTRICT_SELECT_OFF') + layout.menu("VIEW3D_MT_add", icon='MESH_CUBE') + layout.menu("VIEW3D_MT_Camera_Options", icon='CAMERA_DATA') UseSeparator(self, context) + layout.menu("VIEW3D_MT_Object", icon='OBJECT_DATAMODE') layout.menu("VIEW3D_MT_TransformMenu", icon='EMPTY_ARROWS') - layout.menu("VIEW3D_MT_MirrorMenu", icon='MOD_MIRROR') layout.menu("VIEW3D_MT_CursorMenu", icon='PIVOT_CURSOR') UseSeparator(self, context) - layout.menu("VIEW3D_MT_ParentMenu", icon='PIVOT_ACTIVE') - layout.menu("VIEW3D_MT_GroupMenu", icon='GROUP') - UseSeparator(self, context) - layout.menu("VIEW3D_MT_object_context_menu", text="Specials", icon='SOLO_OFF') - layout.menu("VIEW3D_MT_Camera_Options", icon='OUTLINER_OB_CAMERA') + layout.menu("VIEW3D_MT_object_collection", text = "Collections", icon='GROUP') UseSeparator(self, context) layout.operator_menu_enum("object.modifier_add", "type", icon='MODIFIER') - layout.operator_menu_enum("object.constraint_add", - "type", text="Add Constraint", icon='CONSTRAINT') UseSeparator(self, context) layout.operator("object.delete", text="Delete Object", icon='X') UseSeparator(self, context) layout.menu("VIEW3D_MT_UndoS", icon='ARROW_LEFTRIGHT') - # Edit Curve # +# Edit Curve # if obj and obj.type == 'CURVE' and obj.mode in {'EDIT'}: layout.operator("wm.search_menu", text="Search", icon='VIEWZOOM') @@ -297,64 +255,54 @@ class VIEW3D_MT_Space_Dynamic_Menu(Menu): text="Animation", icon='PLAY') layout.operator("wm.toolbar", text="Tools", icon='TOOL_SETTINGS') layout.menu("SCREEN_MT_user_menu", text="Quick Favorites", icon='HEART') - UseSeparator(self, context) layout.menu("VIEW3D_MT_Object_Interactive_Other", icon='OBJECT_DATA') - layout.menu("VIEW3D_MT_view", icon='ZOOM_ALL') - layout.menu("VIEW3D_MT_Select_Edit_Curve", - icon='RESTRICT_SELECT_OFF') UseSeparator(self, context) + layout.menu("VIEW3D_MT_View_Menu", icon='ZOOM_ALL') + layout.menu("VIEW3D_MT_select_edit_curve", + icon='RESTRICT_SELECT_OFF') layout.menu("VIEW3D_MT_curve_add", text="Add Curve", icon='OUTLINER_OB_CURVE') - layout.menu("VIEW3D_MT_Edit_Curve", icon='CURVE_DATA') UseSeparator(self, context) - layout.menu("VIEW3D_MT_TransformMenu", icon='EMPTY_ARROWS') - layout.menu("VIEW3D_MT_MirrorMenu", icon='MOD_MIRROR') + layout.menu("VIEW3D_MT_Edit_Curve", icon='CURVE_DATA') + layout.menu("VIEW3D_MT_transform", icon='EMPTY_ARROWS') layout.menu("VIEW3D_MT_CursorMenu", icon='PIVOT_CURSOR') - layout.menu("VIEW3D_MT_EditCurveCtrlpoints", + layout.menu("VIEW3D_MT_edit_curve_ctrlpoints", icon='CURVE_BEZCURVE') - layout.menu("VIEW3D_MT_EditCurveSpecials", - icon='SOLO_OFF') UseSeparator(self, context) - layout.operator("curve.delete", text="Delete Object", + layout.menu("VIEW3D_MT_edit_curve_delete", text="Delete", icon='X') UseSeparator(self, context) layout.menu("VIEW3D_MT_UndoS", icon='ARROW_LEFTRIGHT') - # Surface Object Mode # +# Surface Object Mode # if obj and obj.type == 'SURFACE' and obj.mode in {'OBJECT'}: layout.operator_context = 'INVOKE_REGION_WIN' layout.operator("wm.search_menu", text="Search", icon='VIEWZOOM') + layout.operator("wm.toolbar", text="Tools", icon='TOOL_SETTINGS') layout.menu("VIEW3D_MT_Animation_Player", text="Animation", icon='PLAY') - layout.operator("wm.toolbar", text="Tools", icon='TOOL_SETTINGS') layout.menu("SCREEN_MT_user_menu", text="Quick Favorites", icon='HEART') - UseSeparator(self, context) layout.menu("VIEW3D_MT_Object_Interactive_Other", icon='OBJECT_DATA') - layout.menu("VIEW3D_MT_view", icon='ZOOM_ALL') - layout.menu("VIEW3D_MT_Select_Object", icon='RESTRICT_SELECT_OFF') UseSeparator(self, context) - layout.menu("VIEW3D_MT_AddMenu", icon='OBJECT_DATAMODE') - layout.menu("VIEW3D_MT_Object", icon='VIEW3D') + layout.menu("VIEW3D_MT_View_Menu", icon='ZOOM_ALL') + layout.menu("VIEW3D_MT_select_object", icon='RESTRICT_SELECT_OFF') + layout.menu("VIEW3D_MT_add", icon='MESH_CUBE') + layout.menu("VIEW3D_MT_Camera_Options", icon='CAMERA_DATA') UseSeparator(self, context) + layout.menu("VIEW3D_MT_Object", icon='OBJECT_DATAMODE') layout.menu("VIEW3D_MT_TransformMenu", icon='EMPTY_ARROWS') - layout.menu("VIEW3D_MT_MirrorMenu", icon='MOD_MIRROR') layout.menu("VIEW3D_MT_CursorMenu", icon='PIVOT_CURSOR') UseSeparator(self, context) - layout.menu("VIEW3D_MT_ParentMenu", icon='PIVOT_ACTIVE') - layout.menu("VIEW3D_MT_GroupMenu", icon='GROUP') + layout.menu("VIEW3D_MT_object_collection", text = "Collections", icon='GROUP') UseSeparator(self, context) - layout.menu("VIEW3D_MT_object_context_menu", text="Specials", icon='SOLO_OFF') - layout.menu("VIEW3D_MT_Camera_Options", icon='OUTLINER_OB_CAMERA') layout.operator_menu_enum("object.modifier_add", "type", icon='MODIFIER') - layout.operator_menu_enum("object.constraint_add", - "type", text="Add Constraint", icon='CONSTRAINT') UseSeparator(self, context) layout.operator("object.delete", text="Delete Object", icon='X') UseSeparator(self, context) layout.menu("VIEW3D_MT_UndoS", icon='ARROW_LEFTRIGHT') - # Edit Surface # +# Edit Surface # if obj and obj.type == 'SURFACE' and obj.mode in {'EDIT'}: layout.operator("wm.search_menu", text="Search", icon='VIEWZOOM') @@ -362,63 +310,54 @@ class VIEW3D_MT_Space_Dynamic_Menu(Menu): text="Animation", icon='PLAY') layout.operator("wm.toolbar", text="Tools", icon='TOOL_SETTINGS') layout.menu("SCREEN_MT_user_menu", text="Quick Favorites", icon='HEART') - UseSeparator(self, context) layout.menu("VIEW3D_MT_Object_Interactive_Other", icon='OBJECT_DATA') - layout.menu("VIEW3D_MT_view", icon='ZOOM_ALL') - layout.menu("VIEW3D_MT_Select_Edit_Surface", icon='RESTRICT_SELECT_OFF') UseSeparator(self, context) + layout.menu("VIEW3D_MT_View_Menu", icon='ZOOM_ALL') + layout.menu("VIEW3D_MT_select_edit_surface", icon='RESTRICT_SELECT_OFF') layout.menu("VIEW3D_MT_surface_add", text="Add Surface", icon='OUTLINER_OB_SURFACE') - layout.menu("VIEW3D_MT_TransformMenu", icon='EMPTY_ARROWS') - layout.menu("VIEW3D_MT_MirrorMenu", icon='MOD_MIRROR') - layout.menu("VIEW3D_MT_CursorMenu", icon='PIVOT_CURSOR') UseSeparator(self, context) - layout.prop_menu_enum(settings, "proportional_edit", - icon="PROP_CON") - layout.prop_menu_enum(settings, "proportional_edit_falloff", - icon="SMOOTHCURVE") - layout.menu("VIEW3D_MT_EditCurveSpecials", - icon='SOLO_OFF') + layout.menu("VIEW3D_MT_Edit_Curve", icon='CURVE_DATA') + layout.menu("VIEW3D_MT_transform", icon='EMPTY_ARROWS') + layout.menu("VIEW3D_MT_CursorMenu", icon='PIVOT_CURSOR') + layout.menu("VIEW3D_MT_edit_curve_ctrlpoints", + icon='CURVE_BEZCURVE') UseSeparator(self, context) - layout.operator("curve.delete", text="Delete Object", - icon='CANCEL') + layout.menu("VIEW3D_MT_edit_curve_delete", text="Delete", + icon='X') UseSeparator(self, context) layout.menu("VIEW3D_MT_UndoS", icon='ARROW_LEFTRIGHT') - # Metaball Object Mode # + +# Metaball Object Mode # if obj and obj.type == 'META' and obj.mode in {'OBJECT'}: layout.operator_context = 'INVOKE_REGION_WIN' layout.operator("wm.search_menu", text="Search", icon='VIEWZOOM') + layout.operator("wm.toolbar", text="Tools", icon='TOOL_SETTINGS') layout.menu("VIEW3D_MT_Animation_Player", text="Animation", icon='PLAY') - layout.operator("wm.toolbar", text="Tools", icon='TOOL_SETTINGS') layout.menu("SCREEN_MT_user_menu", text="Quick Favorites", icon='HEART') - UseSeparator(self, context) layout.menu("VIEW3D_MT_Object_Interactive_Other", icon='OBJECT_DATA') - layout.menu("VIEW3D_MT_view", icon='ZOOM_ALL') - layout.menu("VIEW3D_MT_Select_Object", icon='RESTRICT_SELECT_OFF') UseSeparator(self, context) - layout.menu("VIEW3D_MT_AddMenu", icon='OBJECT_DATAMODE') - layout.menu("VIEW3D_MT_Object", icon='VIEW3D') + layout.menu("VIEW3D_MT_View_Menu", icon='ZOOM_ALL') + layout.menu("VIEW3D_MT_select_object", icon='RESTRICT_SELECT_OFF') + layout.menu("VIEW3D_MT_add", icon='MESH_CUBE') + layout.menu("VIEW3D_MT_Camera_Options", icon='CAMERA_DATA') UseSeparator(self, context) + layout.menu("VIEW3D_MT_Object", icon='OBJECT_DATAMODE') layout.menu("VIEW3D_MT_TransformMenu", icon='EMPTY_ARROWS') - layout.menu("VIEW3D_MT_MirrorMenu", icon='MOD_MIRROR') layout.menu("VIEW3D_MT_CursorMenu", icon='PIVOT_CURSOR') UseSeparator(self, context) - layout.menu("VIEW3D_MT_ParentMenu", icon='PIVOT_ACTIVE') - layout.menu("VIEW3D_MT_GroupMenu", icon='GROUP') + layout.menu("VIEW3D_MT_object_collection", text = "Collections", icon='GROUP') UseSeparator(self, context) - layout.menu("VIEW3D_MT_object_context_menu", text="Specials", icon='SOLO_OFF') - layout.menu("VIEW3D_MT_Camera_Options", icon='OUTLINER_OB_CAMERA') + layout.operator_menu_enum("object.modifier_add", "type", icon='MODIFIER') UseSeparator(self, context) - layout.operator_menu_enum("object.constraint_add", - "type", text="Add Constraint", icon='CONSTRAINT') layout.operator("object.delete", text="Delete Object", icon='X') UseSeparator(self, context) layout.menu("VIEW3D_MT_UndoS", icon='ARROW_LEFTRIGHT') - # Edit Metaball # +# Edit Metaball # if obj and obj.type == 'META' and obj.mode in {'EDIT'}: layout.operator("wm.search_menu", text="Search", icon='VIEWZOOM') @@ -426,181 +365,107 @@ class VIEW3D_MT_Space_Dynamic_Menu(Menu): text="Animation", icon='PLAY') layout.operator("wm.toolbar", text="Tools", icon='TOOL_SETTINGS') layout.menu("SCREEN_MT_user_menu", text="Quick Favorites", icon='HEART') - UseSeparator(self, context) layout.menu("VIEW3D_MT_Object_Interactive_Other", icon='OBJECT_DATA') - layout.menu("VIEW3D_MT_view", icon='ZOOM_ALL') - layout.menu("VIEW3D_MT_SelectMetaball", icon='RESTRICT_SELECT_OFF') UseSeparator(self, context) + layout.menu("VIEW3D_MT_View_Menu", icon='ZOOM_ALL') + layout.menu("VIEW3D_MT_select_edit_metaball", icon='RESTRICT_SELECT_OFF') layout.operator_menu_enum("object.metaball_add", "type", text="Add Metaball", icon='OUTLINER_OB_META') - layout.menu("VIEW3D_MT_TransformMenu", icon='EMPTY_ARROWS') - layout.menu("VIEW3D_MT_MirrorMenu", icon='MOD_MIRROR') - layout.menu("VIEW3D_MT_CursorMenu", icon='PIVOT_CURSOR') - UseSeparator(self, context) - layout.prop_menu_enum(settings, "proportional_edit", - icon="PROP_CON") - layout.prop_menu_enum(settings, "proportional_edit_falloff", - icon="SMOOTHCURVE") - UseSeparator(self, context) - layout.operator("mball.delete_metaelems", text="Delete Object", - icon='CANCEL') - UseSeparator(self, context) - layout.menu("VIEW3D_MT_UndoS", icon='ARROW_LEFTRIGHT') - - # Text Object Mode # - if obj and obj.type == 'FONT' and obj.mode in {'OBJECT'}: - - layout.operator_context = 'INVOKE_REGION_WIN' - layout.operator("wm.search_menu", text="Search", icon='VIEWZOOM') - layout.menu("VIEW3D_MT_Animation_Player", - text="Animation", icon='PLAY') - layout.operator("wm.toolbar", text="Tools", icon='TOOL_SETTINGS') - layout.menu("SCREEN_MT_user_menu", text="Quick Favorites", icon='HEART') - UseSeparator(self, context) - layout.operator("view3d.interactive_mode_text", icon='VIEW3D') - layout.menu("VIEW3D_MT_view", icon='ZOOM_ALL') - layout.menu("VIEW3D_MT_Select_Object", icon='RESTRICT_SELECT_OFF') UseSeparator(self, context) - layout.menu("VIEW3D_MT_AddMenu", icon='OBJECT_DATAMODE') - layout.menu("VIEW3D_MT_Object", icon='VIEW3D') - UseSeparator(self, context) - layout.menu("VIEW3D_MT_TransformMenu", icon='EMPTY_ARROWS') - layout.menu("VIEW3D_MT_MirrorMenu", icon='MOD_MIRROR') - layout.menu("VIEW3D_MT_CursorMenu", icon='PIVOT_CURSOR') - UseSeparator(self, context) - layout.menu("VIEW3D_MT_ParentMenu", icon='PIVOT_ACTIVE') - layout.menu("VIEW3D_MT_GroupMenu", icon='GROUP') - UseSeparator(self, context) - layout.menu("VIEW3D_MT_object_context_menu", text="Specials", icon='SOLO_OFF') - layout.menu("VIEW3D_MT_Camera_Options", icon='OUTLINER_OB_CAMERA') - UseSeparator(self, context) - layout.operator_menu_enum("object.modifier_add", "type", icon='MODIFIER') - layout.operator_menu_enum("object.constraint_add", - "type", text="Add Constraint", icon='CONSTRAINT') - UseSeparator(self, context) - layout.operator("object.delete", text="Delete Object", icon='X') - UseSeparator(self, context) - layout.menu("VIEW3D_MT_UndoS", icon='ARROW_LEFTRIGHT') - - # Text Edit Mode # - # To Do: Space is already reserved for the typing tool - if obj and obj.type == 'FONT' and obj.mode in {'EDIT'}: - - layout.operator_context = 'INVOKE_REGION_WIN' - layout.operator("wm.search_menu", text="Search", icon='VIEWZOOM') - layout.menu("VIEW3D_MT_Animation_Player", - text="Animation", icon='PLAY') - layout.operator("wm.toolbar", text="Tools", icon='TOOL_SETTINGS') - layout.menu("SCREEN_MT_user_menu", text="Quick Favorites", icon='HEART') + layout.menu("VIEW3D_MT_transform", icon='EMPTY_ARROWS') + layout.menu("VIEW3D_MT_mirror", icon='MOD_MIRROR') + layout.menu("VIEW3D_MT_CursorMenuLite", icon='PIVOT_CURSOR') + layout.operator("mball.duplicate_metaelems", icon='OUTLINER_DATA_META') + layout.menu("VIEW3D_MT_edit_meta_showhide", icon='HIDE_OFF') UseSeparator(self, context) - layout.operator("object.editmode_toggle", text="Enter Object Mode", - icon='OBJECT_DATA') - layout.menu("VIEW3D_MT_view", icon='ZOOM_ALL') - layout.menu("VIEW3D_MT_select_edit_text", icon='VIEW3D') - layout.menu("VIEW3D_MT_edit_font", icon='RESTRICT_SELECT_OFF') + layout.operator("mball.delete_metaelems", text="Delete", icon='X') UseSeparator(self, context) layout.menu("VIEW3D_MT_UndoS", icon='ARROW_LEFTRIGHT') - # Camera Object Mode # +# Camera Object Mode # if obj and obj.type == 'CAMERA' and obj.mode in {'OBJECT'}: layout.operator_context = 'INVOKE_REGION_WIN' layout.operator("wm.search_menu", text="Search", icon='VIEWZOOM') + layout.operator("wm.toolbar", text="Tools", icon='TOOL_SETTINGS') layout.menu("VIEW3D_MT_Animation_Player", text="Animation", icon='PLAY') - layout.operator("wm.toolbar", text="Tools", icon='TOOL_SETTINGS') layout.menu("SCREEN_MT_user_menu", text="Quick Favorites", icon='HEART') UseSeparator(self, context) - layout.menu("VIEW3D_MT_view", icon='ZOOM_ALL') - layout.menu("VIEW3D_MT_Select_Object", icon='RESTRICT_SELECT_OFF') - UseSeparator(self, context) - layout.menu("VIEW3D_MT_AddMenu", icon='OBJECT_DATAMODE') - layout.menu("VIEW3D_MT_Object", icon='VIEW3D') + layout.menu("VIEW3D_MT_View_Menu", icon='ZOOM_ALL') + layout.menu("VIEW3D_MT_select_object", icon='RESTRICT_SELECT_OFF') + layout.menu("VIEW3D_MT_add", icon='MESH_CUBE') + layout.menu("VIEW3D_MT_Camera_Options", icon='CAMERA_DATA') UseSeparator(self, context) - layout.menu("VIEW3D_MT_TransformMenu", icon='EMPTY_ARROWS') + layout.menu("VIEW3D_MT_Object", icon='OBJECT_DATAMODE') + layout.menu("VIEW3D_MT_TransformMenuCamera", icon='EMPTY_ARROWS') layout.menu("VIEW3D_MT_CursorMenuLite", icon='PIVOT_CURSOR') UseSeparator(self, context) - layout.menu("VIEW3D_MT_ParentMenu", icon='PIVOT_ACTIVE') - layout.menu("VIEW3D_MT_GroupMenu", icon='GROUP') - UseSeparator(self, context) - layout.menu("VIEW3D_MT_object_context_menu", text="Specials", icon='SOLO_OFF') - layout.menu("VIEW3D_MT_Camera_Options", icon='OUTLINER_OB_CAMERA') + layout.menu("VIEW3D_MT_object_collection", text = "Collections", icon='GROUP') UseSeparator(self, context) - layout.operator_menu_enum("object.constraint_add", - "type", text="Add Constraint", icon='CONSTRAINT') + layout.operator_menu_enum("object.modifier_add", "type", icon='MODIFIER') UseSeparator(self, context) layout.operator("object.delete", text="Delete Object", icon='X') UseSeparator(self, context) layout.menu("VIEW3D_MT_UndoS", icon='ARROW_LEFTRIGHT') - # Lamp Object Mode # +# Lamp Object Mode # if obj and obj.type == 'LIGHT' and obj.mode in {'OBJECT'}: layout.operator_context = 'INVOKE_REGION_WIN' layout.operator("wm.search_menu", text="Search", icon='VIEWZOOM') + layout.operator("wm.toolbar", text="Tools", icon='TOOL_SETTINGS') layout.menu("VIEW3D_MT_Animation_Player", text="Animation", icon='PLAY') - layout.operator("wm.toolbar", text="Tools", icon='TOOL_SETTINGS') layout.menu("SCREEN_MT_user_menu", text="Quick Favorites", icon='HEART') UseSeparator(self, context) - layout.menu("VIEW3D_MT_view", icon='ZOOM_ALL') - layout.menu("VIEW3D_MT_Select_Object", icon='RESTRICT_SELECT_OFF') - UseSeparator(self, context) - layout.menu("VIEW3D_MT_AddMenu", icon='OBJECT_DATAMODE') - layout.menu("VIEW3D_MT_Object", icon='VIEW3D') + layout.menu("VIEW3D_MT_View_Menu", icon='ZOOM_ALL') + layout.menu("VIEW3D_MT_select_object", icon='RESTRICT_SELECT_OFF') + layout.menu("VIEW3D_MT_add", icon='MESH_CUBE') + layout.menu("VIEW3D_MT_Camera_Options", icon='CAMERA_DATA') UseSeparator(self, context) + layout.menu("VIEW3D_MT_Object", icon='OBJECT_DATAMODE') layout.menu("VIEW3D_MT_TransformMenuLite", icon='EMPTY_ARROWS') layout.menu("VIEW3D_MT_CursorMenuLite", icon='PIVOT_CURSOR') UseSeparator(self, context) - layout.menu("VIEW3D_MT_ParentMenu", icon='PIVOT_ACTIVE') - layout.menu("VIEW3D_MT_GroupMenu", icon='GROUP') - UseSeparator(self, context) - layout.menu("VIEW3D_MT_object_context_menu", text="Specials", icon='SOLO_OFF') - layout.menu("VIEW3D_MT_Camera_Options", icon='OUTLINER_OB_CAMERA') + layout.menu("VIEW3D_MT_object_collection", text = "Collections", icon='GROUP') UseSeparator(self, context) - layout.operator_menu_enum("object.constraint_add", - "type", text="Add Constraint", icon='CONSTRAINT') + layout.operator_menu_enum("object.modifier_add", "type", icon='MODIFIER') UseSeparator(self, context) layout.operator("object.delete", text="Delete Object", icon='X') UseSeparator(self, context) layout.menu("VIEW3D_MT_UndoS", icon='ARROW_LEFTRIGHT') - # Armature Object Mode # +# Armature Object Mode # if obj and obj.type == 'ARMATURE' and obj.mode in {'OBJECT'}: layout.operator_context = 'INVOKE_REGION_WIN' layout.operator("wm.search_menu", text="Search", icon='VIEWZOOM') + layout.operator("wm.toolbar", text="Tools", icon='TOOL_SETTINGS') layout.menu("VIEW3D_MT_Animation_Player", text="Animation", icon='PLAY') - layout.operator("wm.toolbar", text="Tools", icon='TOOL_SETTINGS') layout.menu("SCREEN_MT_user_menu", text="Quick Favorites", icon='HEART') - UseSeparator(self, context) layout.menu("VIEW3D_MT_Object_Interactive_Armature", icon='VIEW3D') - layout.menu("VIEW3D_MT_view", icon='ZOOM_ALL') - layout.menu("VIEW3D_MT_Select_Object", icon='RESTRICT_SELECT_OFF') UseSeparator(self, context) - layout.menu("VIEW3D_MT_AddMenu", icon='OBJECT_DATAMODE') - layout.menu("VIEW3D_MT_Object", icon='VIEW3D') - UseSeparator(self, context) - layout.menu("VIEW3D_MT_TransformMenuArmature", icon='EMPTY_ARROWS') - layout.menu("VIEW3D_MT_MirrorMenu", icon='MOD_MIRROR') - layout.menu("VIEW3D_MT_CursorMenuLite", icon='PIVOT_CURSOR') + layout.menu("VIEW3D_MT_View_Menu", icon='ZOOM_ALL') + layout.menu("VIEW3D_MT_select_object", icon='RESTRICT_SELECT_OFF') + layout.menu("VIEW3D_MT_add", icon='MESH_CUBE') + layout.menu("VIEW3D_MT_Camera_Options", icon='CAMERA_DATA') UseSeparator(self, context) - layout.menu("VIEW3D_MT_ParentMenu", icon='PIVOT_ACTIVE') - layout.menu("VIEW3D_MT_GroupMenu", icon='GROUP') + layout.menu("VIEW3D_MT_Object", icon='OBJECT_DATAMODE') + layout.menu("VIEW3D_MT_TransformMenu", icon='EMPTY_ARROWS') + layout.menu("VIEW3D_MT_CursorMenu", icon='PIVOT_CURSOR') UseSeparator(self, context) - layout.menu("VIEW3D_MT_object_context_menu", text="Specials", icon='SOLO_OFF') - layout.menu("VIEW3D_MT_Camera_Options", icon='OUTLINER_OB_CAMERA') + layout.menu("VIEW3D_MT_object_collection", text = "Collections", icon='GROUP') UseSeparator(self, context) - layout.operator_menu_enum("object.constraint_add", - "type", text="Add Constraint", icon='CONSTRAINT') + layout.operator_menu_enum("object.modifier_add", "type", icon='MODIFIER') UseSeparator(self, context) layout.operator("object.delete", text="Delete Object", icon='X') UseSeparator(self, context) layout.menu("VIEW3D_MT_UndoS", icon='ARROW_LEFTRIGHT') - # Armature Edit # +# Armature Edit # if obj and obj.type == 'ARMATURE' and obj.mode in {'EDIT'}: layout.operator("wm.search_menu", text="Search", icon='VIEWZOOM') @@ -608,10 +473,10 @@ class VIEW3D_MT_Space_Dynamic_Menu(Menu): text="Animation", icon='PLAY') layout.operator("wm.toolbar", text="Tools", icon='TOOL_SETTINGS') layout.menu("SCREEN_MT_user_menu", text="Quick Favorites", icon='HEART') - UseSeparator(self, context) layout.menu("VIEW3D_MT_Object_Interactive_Armature", icon='VIEW3D') - layout.menu("VIEW3D_MT_view", icon='ZOOM_ALL') - layout.menu("VIEW3D_MT_Select_Edit_Armature", + UseSeparator(self, context) + layout.menu("VIEW3D_MT_View_Menu", icon='ZOOM_ALL') + layout.menu("VIEW3D_MT_select_edit_armature", icon='RESTRICT_SELECT_OFF') UseSeparator(self, context) layout.menu("VIEW3D_MT_armature_add", text="Add Armature", @@ -621,11 +486,10 @@ class VIEW3D_MT_Space_Dynamic_Menu(Menu): layout.menu("VIEW3D_MT_EditArmatureTK", icon='ARMATURE_DATA') UseSeparator(self, context) - layout.menu("VIEW3D_MT_TransformMenuArmatureEdit", icon='EMPTY_ARROWS') - layout.menu("VIEW3D_MT_MirrorMenu", icon='MOD_MIRROR') + layout.menu("VIEW3D_MT_transform_armature", icon='EMPTY_ARROWS') + layout.menu("VIEW3D_MT_mirror", icon='MOD_MIRROR') layout.menu("VIEW3D_MT_CursorMenuLite", icon='PIVOT_CURSOR') - layout.menu("VIEW3D_MT_ParentMenu", icon='PIVOT_ACTIVE') - layout.menu("VIEW3D_MT_armature_context_menu", icon='SOLO_OFF') + layout.menu("VIEW3D_MT_object_parent") layout.menu("VIEW3D_MT_edit_armature_roll", icon='BONE_DATA') UseSeparator(self, context) @@ -634,7 +498,7 @@ class VIEW3D_MT_Space_Dynamic_Menu(Menu): UseSeparator(self, context) layout.menu("VIEW3D_MT_UndoS", icon='ARROW_LEFTRIGHT') - # Armature Pose # +# Armature Pose # if obj and obj.type == 'ARMATURE' and obj.mode in {'POSE'}: arm = context.active_object.data @@ -644,13 +508,13 @@ class VIEW3D_MT_Space_Dynamic_Menu(Menu): text="Animation", icon='PLAY') layout.operator("wm.toolbar", text="Tools", icon='TOOL_SETTINGS') layout.menu("SCREEN_MT_user_menu", text="Quick Favorites", icon='HEART') - UseSeparator(self, context) layout.menu("VIEW3D_MT_Object_Interactive_Armature", icon='VIEW3D') - layout.menu("VIEW3D_MT_view", icon='ZOOM_ALL') - layout.menu("VIEW3D_MT_Select_Pose", icon='RESTRICT_SELECT_OFF') + UseSeparator(self, context) + layout.menu("VIEW3D_MT_View_Menu", icon='ZOOM_ALL') + layout.menu("VIEW3D_MT_select_pose", icon='RESTRICT_SELECT_OFF') UseSeparator(self, context) layout.menu("VIEW3D_MT_Pose", icon='ARMATURE_DATA') - layout.menu("VIEW3D_MT_TransformMenuArmaturePose", icon='EMPTY_ARROWS') + layout.menu("VIEW3D_MT_transform_armature", icon='EMPTY_ARROWS') layout.menu("VIEW3D_MT_pose_transform", icon='EMPTY_DATA') UseSeparator(self, context) layout.menu("VIEW3D_MT_CursorMenuLite", icon='PIVOT_CURSOR') @@ -662,8 +526,6 @@ class VIEW3D_MT_Space_Dynamic_Menu(Menu): layout.menu("VIEW3D_MT_pose_apply", icon='AUTO') layout.operator("pose.relax", icon='ARMATURE_DATA') - layout.menu("VIEW3D_MT_KeyframeMenu", icon='KEY_HLT') - layout.menu("VIEW3D_MT_pose_context_menu", icon='SOLO_OFF') layout.menu("VIEW3D_MT_pose_group", icon='GROUP_BONE') UseSeparator(self, context) layout.operator_menu_enum("pose.constraint_add", @@ -671,42 +533,35 @@ class VIEW3D_MT_Space_Dynamic_Menu(Menu): UseSeparator(self, context) layout.menu("VIEW3D_MT_UndoS", icon='ARROW_LEFTRIGHT') - # Lattice Object Mode # +# Lattice Object Mode # if obj and obj.type == 'LATTICE' and obj.mode in {'OBJECT'}: layout.operator_context = 'INVOKE_REGION_WIN' layout.operator("wm.search_menu", text="Search", icon='VIEWZOOM') + layout.operator("wm.toolbar", text="Tools", icon='TOOL_SETTINGS') layout.menu("VIEW3D_MT_Animation_Player", text="Animation", icon='PLAY') - layout.operator("wm.toolbar", text="Tools", icon='TOOL_SETTINGS') layout.menu("SCREEN_MT_user_menu", text="Quick Favorites", icon='HEART') - UseSeparator(self, context) layout.menu("VIEW3D_MT_Object_Interactive_Other", icon='OBJECT_DATA') - layout.menu("VIEW3D_MT_view", icon='ZOOM_ALL') - layout.menu("VIEW3D_MT_Select_Object", icon='RESTRICT_SELECT_OFF') UseSeparator(self, context) - layout.menu("VIEW3D_MT_AddMenu", icon='OBJECT_DATAMODE') - layout.menu("VIEW3D_MT_Object", icon='VIEW3D') + layout.menu("VIEW3D_MT_View_Menu", icon='ZOOM_ALL') + layout.menu("VIEW3D_MT_select_object", icon='RESTRICT_SELECT_OFF') + layout.menu("VIEW3D_MT_add", icon='MESH_CUBE') + layout.menu("VIEW3D_MT_Camera_Options", icon='CAMERA_DATA') UseSeparator(self, context) - layout.menu("VIEW3D_MT_TransformMenu", icon='EMPTY_ARROWS') - layout.menu("VIEW3D_MT_MirrorMenu", icon='MOD_MIRROR') - layout.menu("VIEW3D_MT_CursorMenu", icon='PIVOT_CURSOR') - UseSeparator(self, context) - layout.menu("VIEW3D_MT_ParentMenu", icon='PIVOT_ACTIVE') - layout.menu("VIEW3D_MT_GroupMenu", icon='GROUP') + layout.menu("VIEW3D_MT_Object", icon='OBJECT_DATAMODE') + layout.menu("VIEW3D_MT_TransformMenuLite", icon='EMPTY_ARROWS') + layout.menu("VIEW3D_MT_CursorMenuLite", icon='PIVOT_CURSOR') UseSeparator(self, context) - layout.menu("VIEW3D_MT_object_context_menu", text="Specials", icon='SOLO_OFF') - layout.menu("VIEW3D_MT_Camera_Options", icon='OUTLINER_OB_CAMERA') + layout.menu("VIEW3D_MT_object_collection", text = "Collections", icon='GROUP') UseSeparator(self, context) layout.operator_menu_enum("object.modifier_add", "type", icon='MODIFIER') - layout.operator_menu_enum("object.constraint_add", - "type", text="Add Constraint", icon='CONSTRAINT') UseSeparator(self, context) layout.operator("object.delete", text="Delete Object", icon='X') UseSeparator(self, context) layout.menu("VIEW3D_MT_UndoS", icon='ARROW_LEFTRIGHT') - # Edit Lattice # +# Edit Lattice # if obj and obj.type == 'LATTICE' and obj.mode in {'EDIT'}: layout.operator("wm.search_menu", text="Search", icon='VIEWZOOM') @@ -714,59 +569,48 @@ class VIEW3D_MT_Space_Dynamic_Menu(Menu): text="Animation", icon='PLAY') layout.operator("wm.toolbar", text="Tools", icon='TOOL_SETTINGS') layout.menu("SCREEN_MT_user_menu", text="Quick Favorites", icon='HEART') - UseSeparator(self, context) layout.menu("VIEW3D_MT_Object_Interactive_Other", icon='OBJECT_DATA') - layout.menu("VIEW3D_MT_view", icon='ZOOM_ALL') - layout.menu("VIEW3D_MT_Select_Edit_Lattice", - icon='RESTRICT_SELECT_OFF') UseSeparator(self, context) - layout.menu("VIEW3D_MT_TransformMenu", icon='EMPTY_ARROWS') - layout.menu("VIEW3D_MT_MirrorMenu", icon='MOD_MIRROR') - layout.menu("VIEW3D_MT_CursorMenu", icon='PIVOT_CURSOR') + layout.menu("VIEW3D_MT_View_Menu", icon='ZOOM_ALL') + layout.menu("VIEW3D_MT_select_edit_lattice", + icon='RESTRICT_SELECT_OFF') UseSeparator(self, context) - layout.prop_menu_enum(settings, "proportional_edit", - icon="PROP_CON") - layout.prop_menu_enum(settings, "proportional_edit_falloff", - icon="SMOOTHCURVE") + layout.menu("VIEW3D_MT_TransformMenuLite", icon='EMPTY_ARROWS') + layout.menu("VIEW3D_MT_mirror", icon='MOD_MIRROR') + layout.menu("VIEW3D_MT_CursorMenuLite", icon='PIVOT_CURSOR') UseSeparator(self, context) layout.operator("lattice.make_regular") UseSeparator(self, context) layout.menu("VIEW3D_MT_UndoS", icon='ARROW_LEFTRIGHT') - # Empty Object Mode # +# Empty Object Mode # if obj and obj.type == 'EMPTY' and obj.mode in {'OBJECT'}: layout.operator_context = 'INVOKE_REGION_WIN' layout.operator("wm.search_menu", text="Search", icon='VIEWZOOM') + layout.operator("wm.toolbar", text="Tools", icon='TOOL_SETTINGS') layout.menu("VIEW3D_MT_Animation_Player", text="Animation", icon='PLAY') - layout.operator("wm.toolbar", text="Tools", icon='TOOL_SETTINGS') layout.menu("SCREEN_MT_user_menu", text="Quick Favorites", icon='HEART') UseSeparator(self, context) - layout.menu("VIEW3D_MT_view", icon='ZOOM_ALL') - layout.menu("VIEW3D_MT_Select_Object", icon='RESTRICT_SELECT_OFF') - UseSeparator(self, context) - layout.menu("VIEW3D_MT_AddMenu", icon='OBJECT_DATAMODE') - layout.menu("VIEW3D_MT_Object", icon='VIEW3D') + layout.menu("VIEW3D_MT_View_Menu", icon='ZOOM_ALL') + layout.menu("VIEW3D_MT_select_object", icon='RESTRICT_SELECT_OFF') + layout.menu("VIEW3D_MT_add", icon='MESH_CUBE') + layout.menu("VIEW3D_MT_Camera_Options", icon='CAMERA_DATA') UseSeparator(self, context) + layout.menu("VIEW3D_MT_Object", icon='OBJECT_DATAMODE') layout.menu("VIEW3D_MT_TransformMenuLite", icon='EMPTY_ARROWS') - layout.menu("VIEW3D_MT_MirrorMenu", icon='MOD_MIRROR') layout.menu("VIEW3D_MT_CursorMenuLite", icon='PIVOT_CURSOR') UseSeparator(self, context) - layout.menu("VIEW3D_MT_ParentMenu", icon='PIVOT_ACTIVE') - layout.menu("VIEW3D_MT_GroupMenu", icon='GROUP') - UseSeparator(self, context) - layout.menu("VIEW3D_MT_object_context_menu", text="Specials", icon='SOLO_OFF') - layout.menu("VIEW3D_MT_Camera_Options", icon='OUTLINER_OB_CAMERA') + layout.menu("VIEW3D_MT_object_collection", text = "Collections", icon='GROUP') UseSeparator(self, context) - layout.operator_menu_enum("object.constraint_add", - "type", text="Add Constraint", icon='CONSTRAINT') + layout.operator_menu_enum("object.modifier_add", "type", icon='MODIFIER') UseSeparator(self, context) layout.operator("object.delete", text="Delete Object", icon='X') UseSeparator(self, context) layout.menu("VIEW3D_MT_UndoS", icon='ARROW_LEFTRIGHT') - # Speaker Object Mode # +# Speaker Object Mode # if obj and obj.type == 'SPEAKER' and obj.mode in {'OBJECT'}: layout.operator_context = 'INVOKE_REGION_WIN' @@ -776,26 +620,21 @@ class VIEW3D_MT_Space_Dynamic_Menu(Menu): layout.operator("wm.toolbar", text="Tools", icon='TOOL_SETTINGS') layout.menu("SCREEN_MT_user_menu", text="Quick Favorites", icon='HEART') UseSeparator(self, context) - layout.menu("VIEW3D_MT_view", icon='ZOOM_ALL') - layout.menu("VIEW3D_MT_Select_Object", icon='RESTRICT_SELECT_OFF') + layout.menu("VIEW3D_MT_View_Menu", icon='ZOOM_ALL') + layout.menu("VIEW3D_MT_select_object", icon='RESTRICT_SELECT_OFF') + layout.menu("VIEW3D_MT_add", icon='MESH_CUBE') UseSeparator(self, context) - layout.menu("VIEW3D_MT_AddMenu", icon='OBJECT_DATAMODE') layout.menu("VIEW3D_MT_Object", icon='VIEW3D') - UseSeparator(self, context) layout.menu("VIEW3D_MT_TransformMenuLite", icon='EMPTY_ARROWS') layout.menu("VIEW3D_MT_CursorMenuLite", icon='PIVOT_CURSOR') UseSeparator(self, context) - layout.menu("VIEW3D_MT_ParentMenu", icon='PIVOT_ACTIVE') - layout.menu("VIEW3D_MT_GroupMenu", icon='GROUP') - UseSeparator(self, context) - layout.operator_menu_enum("object.constraint_add", - "type", text="Add Constraint", icon='CONSTRAINT') + layout.menu("VIEW3D_MT_object_collection", text = "Collections", icon='GROUP') UseSeparator(self, context) layout.operator("object.delete", text="Delete Object", icon='X') UseSeparator(self, context) layout.menu("VIEW3D_MT_UndoS", icon='ARROW_LEFTRIGHT') - # Particle Menu # +# Particle Menu # if obj and context.mode == 'PARTICLE': layout.operator("wm.search_menu", text="Search", icon='VIEWZOOM') @@ -803,16 +642,16 @@ class VIEW3D_MT_Space_Dynamic_Menu(Menu): text="Animation", icon='PLAY') layout.operator("wm.toolbar", text="Tools", icon='TOOL_SETTINGS') layout.menu("SCREEN_MT_user_menu", text="Quick Favorites", icon='HEART') - UseSeparator(self, context) layout.menu("VIEW3D_MT_InteractiveMode", icon='VIEW3D') - layout.menu("VIEW3D_MT_view", icon='ZOOM_ALL') + UseSeparator(self, context) + layout.menu("VIEW3D_MT_View_Menu", icon='ZOOM_ALL') layout.menu("VIEW3D_MT_Select_Particle", icon='RESTRICT_SELECT_OFF') - layout.menu("VIEW3D_MT_Selection_Mode_Particle", + layout.menu("VIEW3D_MT_select_particle", text="Select and Display Mode", icon='PARTICLE_PATH') UseSeparator(self, context) layout.menu("VIEW3D_MT_TransformMenu", icon='EMPTY_ARROWS') - layout.menu("VIEW3D_MT_MirrorMenu", icon='MOD_MIRROR') + layout.menu("VIEW3D_MT_mirror", icon='MOD_MIRROR') layout.menu("VIEW3D_MT_CursorMenuLite", icon='PIVOT_CURSOR') UseSeparator(self, context) # layout.prop_menu_enum(settings, "proportional_edit", @@ -827,42 +666,35 @@ class VIEW3D_MT_Space_Dynamic_Menu(Menu): UseSeparator(self, context) layout.menu("VIEW3D_MT_UndoS", icon='ARROW_LEFTRIGHT') - # Grease Pencil Object Mode # +# Grease Pencil Object Mode # if obj and obj.type == 'GPENCIL' and obj.mode in {'OBJECT'}: + layout.operator_context = 'INVOKE_REGION_WIN' layout.operator("wm.search_menu", text="Search", icon='VIEWZOOM') + layout.operator("wm.toolbar", text="Tools", icon='TOOL_SETTINGS') layout.menu("VIEW3D_MT_Animation_Player", text="Animation", icon='PLAY') - layout.operator("wm.toolbar", text="Tools", icon='TOOL_SETTINGS') layout.menu("SCREEN_MT_user_menu", text="Quick Favorites", icon='HEART') - UseSeparator(self, context) layout.menu("VIEW3D_MT_interactive_mode_gpencil", icon='EDITMODE_HLT') - layout.menu("VIEW3D_MT_view", icon='ZOOM_ALL') - layout.menu("VIEW3D_MT_Select_Object", icon='RESTRICT_SELECT_OFF') UseSeparator(self, context) - layout.menu("VIEW3D_MT_AddMenu", icon='OBJECT_DATAMODE') - layout.menu("VIEW3D_MT_Object", icon='VIEW3D') + layout.menu("VIEW3D_MT_View_Menu", icon='ZOOM_ALL') + layout.menu("VIEW3D_MT_select_object", icon='RESTRICT_SELECT_OFF') + layout.menu("VIEW3D_MT_add", icon='MESH_CUBE') + layout.menu("VIEW3D_MT_Camera_Options", icon='CAMERA_DATA') UseSeparator(self, context) + layout.menu("VIEW3D_MT_Object", icon='OBJECT_DATAMODE') layout.menu("VIEW3D_MT_TransformMenu", icon='EMPTY_ARROWS') - layout.menu("VIEW3D_MT_MirrorMenu", icon='MOD_MIRROR') layout.menu("VIEW3D_MT_CursorMenu", icon='PIVOT_CURSOR') UseSeparator(self, context) - layout.menu("VIEW3D_MT_ParentMenu", icon='PIVOT_ACTIVE') - layout.menu("VIEW3D_MT_GroupMenu", icon='GROUP') - UseSeparator(self, context) - layout.menu("VIEW3D_MT_object_context_menu", text="Specials", icon='SOLO_OFF') - layout.menu("VIEW3D_MT_Camera_Options", icon='OUTLINER_OB_CAMERA') + layout.menu("VIEW3D_MT_object_collection", text = "Collections", icon='GROUP') UseSeparator(self, context) - layout.operator_menu_enum("object.gpencil_modifier_add", "type", icon='MODIFIER') - layout.operator_menu_enum("object.shaderfx_add", "type", icon ='SHADERFX') - layout.operator_menu_enum("object.constraint_add", - "type", text="Add Constraint", icon='CONSTRAINT') + layout.operator_menu_enum("object.modifier_add", "type", icon='MODIFIER') UseSeparator(self, context) layout.operator("object.delete", text="Delete Object", icon='X') UseSeparator(self, context) layout.menu("VIEW3D_MT_UndoS", icon='ARROW_LEFTRIGHT') - # Grease Pencil Edit Mode # +# Grease Pencil Edit Mode # if obj and obj.type == 'GPENCIL' and obj.mode in {'EDIT_GPENCIL'}: layout.operator_context = 'INVOKE_REGION_WIN' @@ -873,12 +705,10 @@ class VIEW3D_MT_Space_Dynamic_Menu(Menu): layout.menu("SCREEN_MT_user_menu", text="Quick Favorites", icon='HEART') UseSeparator(self, context) layout.menu("VIEW3D_MT_interactive_mode_gpencil", icon='EDITMODE_HLT') - layout.menu("VIEW3D_MT_view", icon='ZOOM_ALL') + layout.menu("VIEW3D_MT_View_Menu", icon='ZOOM_ALL') layout.menu("VIEW3D_MT_select_gpencil", icon='RESTRICT_SELECT_OFF') layout.menu("VIEW3D_MT_edit_gpencil", icon='GREASEPENCIL') UseSeparator(self, context) - layout.menu("VIEW3D_MT_AddMenu", icon='OBJECT_DATAMODE') - UseSeparator(self, context) layout.operator("view3d.snap_cursor_to_center", text="Cursor to World Origin", icon='CURSOR') layout.operator("view3d.snap_cursor_to_grid", @@ -886,7 +716,7 @@ class VIEW3D_MT_Space_Dynamic_Menu(Menu): UseSeparator(self, context) layout.menu("VIEW3D_MT_UndoS", icon='ARROW_LEFTRIGHT') - # Grease Pencil Sculpt Mode # +# Grease Pencil Sculpt Mode # if obj and obj.type == 'GPENCIL' and obj.mode in {'SCULPT_GPENCIL'}: layout.operator_context = 'INVOKE_REGION_WIN' @@ -897,10 +727,7 @@ class VIEW3D_MT_Space_Dynamic_Menu(Menu): layout.menu("SCREEN_MT_user_menu", text="Quick Favorites", icon='HEART') UseSeparator(self, context) layout.menu("VIEW3D_MT_interactive_mode_gpencil", icon='EDITMODE_HLT') - layout.menu("VIEW3D_MT_view", icon='ZOOM_ALL') - layout.menu("VIEW3D_MT_select_gpencil", icon='RESTRICT_SELECT_OFF') - UseSeparator(self, context) - layout.menu("VIEW3D_MT_AddMenu", icon='OBJECT_DATAMODE') + layout.menu("VIEW3D_MT_View_Menu", icon='ZOOM_ALL') UseSeparator(self, context) layout.operator("view3d.snap_cursor_to_center", text="Cursor to World Origin", icon='CURSOR') @@ -909,7 +736,7 @@ class VIEW3D_MT_Space_Dynamic_Menu(Menu): UseSeparator(self, context) layout.menu("VIEW3D_MT_UndoS", icon='ARROW_LEFTRIGHT') - # Grease Pencil Paint Mode # +# Grease Pencil Paint Mode # if obj and obj.type == 'GPENCIL' and obj.mode in {'PAINT_GPENCIL'}: layout.operator_context = 'INVOKE_REGION_WIN' @@ -920,11 +747,9 @@ class VIEW3D_MT_Space_Dynamic_Menu(Menu): layout.menu("SCREEN_MT_user_menu", text="Quick Favorites", icon='HEART') UseSeparator(self, context) layout.menu("VIEW3D_MT_interactive_mode_gpencil", icon='EDITMODE_HLT') - layout.menu("VIEW3D_MT_view", icon='ZOOM_ALL') + layout.menu("VIEW3D_MT_View_Menu", icon='ZOOM_ALL') layout.menu("VIEW3D_MT_paint_gpencil", icon='RESTRICT_SELECT_OFF') UseSeparator(self, context) - layout.menu("VIEW3D_MT_AddMenu", icon='OBJECT_DATAMODE') - UseSeparator(self, context) layout.operator("view3d.snap_cursor_to_center", text="Cursor to World Origin", icon='CURSOR') layout.operator("view3d.snap_cursor_to_grid", @@ -932,7 +757,7 @@ class VIEW3D_MT_Space_Dynamic_Menu(Menu): UseSeparator(self, context) layout.menu("VIEW3D_MT_UndoS", icon='ARROW_LEFTRIGHT') - # Grease Pencil Weight Mode # +# Grease Pencil Weight Mode # if obj and obj.type == 'GPENCIL' and obj.mode in {'WEIGHT_GPENCIL'}: layout.operator_context = 'INVOKE_REGION_WIN' @@ -943,14 +768,12 @@ class VIEW3D_MT_Space_Dynamic_Menu(Menu): layout.menu("SCREEN_MT_user_menu", text="Quick Favorites", icon='HEART') UseSeparator(self, context) layout.menu("VIEW3D_MT_interactive_mode_gpencil", icon='EDITMODE_HLT') - layout.menu("VIEW3D_MT_view", icon='ZOOM_ALL') + layout.menu("VIEW3D_MT_View_Menu", icon='ZOOM_ALL') layout.menu("VIEW3D_MT_weight_gpencil", icon="GPBRUSH_WEIGHT") UseSeparator(self, context) - layout.menu("VIEW3D_MT_AddMenu", icon='OBJECT_DATAMODE') - UseSeparator(self, context) layout.menu("VIEW3D_MT_UndoS", icon='ARROW_LEFTRIGHT') - # Light Probe Menu # +# Light Probe Menu # if obj and obj.type == 'LIGHT_PROBE': layout.operator_context = 'INVOKE_REGION_WIN' @@ -960,22 +783,67 @@ class VIEW3D_MT_Space_Dynamic_Menu(Menu): layout.operator("wm.toolbar", text="Tools", icon='TOOL_SETTINGS') layout.menu("SCREEN_MT_user_menu", text="Quick Favorites", icon='HEART') UseSeparator(self, context) - layout.menu("INFO_MT_area", icon='WORKSPACE') - layout.menu("VIEW3D_MT_view_viewpoint", icon='ZOOM_ALL') - layout.menu("VIEW3D_MT_view_navigation", icon='PIVOT_BOUNDBOX') + layout.menu("VIEW3D_MT_View_Menu", icon='ZOOM_ALL') + layout.menu("VIEW3D_MT_select_object", icon='RESTRICT_SELECT_OFF') + layout.menu("VIEW3D_MT_add", icon='MESH_CUBE') UseSeparator(self, context) - layout.menu("VIEW3D_MT_AddMenu", icon='OBJECT_DATAMODE') + layout.menu("VIEW3D_MT_Object", icon='OBJECT_DATAMODE') + layout.menu("VIEW3D_MT_TransformMenuLite", icon='EMPTY_ARROWS') + layout.menu("VIEW3D_MT_CursorMenuLite", icon='PIVOT_CURSOR') UseSeparator(self, context) - layout.operator("view3d.snap_cursor_to_center", - text="Cursor to World Origin", icon='CURSOR') - layout.operator("view3d.snap_cursor_to_grid", - text="Cursor to Grid", icon='SNAP_GRID') + layout.menu("VIEW3D_MT_object_collection", text = "Collections", icon='GROUP') UseSeparator(self, context) layout.menu("VIEW3D_MT_UndoS", icon='ARROW_LEFTRIGHT') UseSeparator(self, context) layout.prop(view, "show_region_toolbar", icon='MENU_PANEL') layout.prop(view, "show_region_ui", icon='MENU_PANEL') +# Text Object Mode # + if obj and obj.type == 'FONT' and obj.mode in {'OBJECT'}: + + layout.operator_context = 'INVOKE_REGION_WIN' + layout.operator("wm.search_menu", text="Search", icon='VIEWZOOM') + layout.operator("wm.toolbar", text="Tools", icon='TOOL_SETTINGS') + layout.menu("VIEW3D_MT_Animation_Player", + text="Animation", icon='PLAY') + layout.menu("SCREEN_MT_user_menu", text="Quick Favorites", icon='HEART') + layout.menu("VIEW3D_MT_Object_Interactive_Other", icon='OBJECT_DATA') + UseSeparator(self, context) + layout.menu("VIEW3D_MT_View_Menu", icon='ZOOM_ALL') + layout.menu("VIEW3D_MT_select_object", icon='RESTRICT_SELECT_OFF') + layout.menu("VIEW3D_MT_add", icon='MESH_CUBE') + layout.menu("VIEW3D_MT_Camera_Options", icon='CAMERA_DATA') + UseSeparator(self, context) + layout.menu("VIEW3D_MT_Object", icon='OBJECT_DATAMODE') + layout.menu("VIEW3D_MT_TransformMenu", icon='EMPTY_ARROWS') + layout.menu("VIEW3D_MT_CursorMenu", icon='PIVOT_CURSOR') + UseSeparator(self, context) + layout.menu("VIEW3D_MT_object_collection", text = "Collections", icon='GROUP') + UseSeparator(self, context) + layout.operator_menu_enum("object.modifier_add", "type", icon='MODIFIER') + UseSeparator(self, context) + layout.operator("object.delete", text="Delete Object", icon='X') + UseSeparator(self, context) + layout.menu("VIEW3D_MT_UndoS", icon='ARROW_LEFTRIGHT') + + +# Text Edit Mode +def menu_func(self, context): + layout = self.layout + + layout.menu("VIEW3D_MT_View_Menu", icon='ZOOM_ALL') + layout.menu("VIEW3D_MT_select_edit_text", icon='VIEW3D') + layout.separator() + layout.operator_context = 'INVOKE_REGION_WIN' + layout.operator("wm.search_menu", text="Search", icon='VIEWZOOM') + layout.menu("VIEW3D_MT_Animation_Player", + text="Animation", icon='PLAY') + layout.menu("SCREEN_MT_user_menu", text="Quick Favorites", icon='HEART') + layout.operator("object.editmode_toggle", text="Enter Object Mode", + icon='OBJECT_DATA') + layout.separator() + layout.menu("VIEW3D_MT_UndoS", icon='ARROW_LEFTRIGHT') + # Preferences utility functions @@ -1017,6 +885,7 @@ class VIEW3D_MT_Space_Dynamic_Menu_Pref(AddonPreferences): row.prop(self, "use_separators", toggle=True) row.prop(self, "use_brushes_lists", toggle=True) + # List The Classes # classes = ( @@ -1031,17 +900,18 @@ def register(): for cls in classes: bpy.utils.register_class(cls) + bpy.types.VIEW3D_MT_edit_text_context_menu.append(menu_func) + object_menus.register() edit_mesh.register() transform_menus.register() - select_menus.register() view_menus.register() armature_menus.register() curve_menus.register() snap_origin_cursor.register() - sculpt_brush_paint.register() animation_menus.register() + wm = bpy.context.window_manager kc = wm.keyconfigs.addon if kc: @@ -1065,17 +935,17 @@ def unregister(): object_menus.unregister() edit_mesh.unregister() transform_menus.unregister() - select_menus.unregister() view_menus.unregister() armature_menus.unregister() curve_menus.unregister() snap_origin_cursor.unregister() - sculpt_brush_paint.unregister() animation_menus.unregister() + for cls in reversed(classes): bpy.utils.unregister_class(cls) + bpy.types.VIEW3D_MT_edit_text_context_menu.remove(menu_func) if __name__ == "__main__": register() diff --git a/space_view3d_spacebar_menu/animation_menus.py b/space_view3d_spacebar_menu/animation_menus.py index ece261f7..7dadffc6 100644 --- a/space_view3d_spacebar_menu/animation_menus.py +++ b/space_view3d_spacebar_menu/animation_menus.py @@ -31,20 +31,6 @@ from bpy.props import ( from bl_ui.properties_paint_common import UnifiedPaintPanel -# Animation Menus -class VIEW3D_MT_KeyframeMenu(Menu): - bl_label = "Keyframe" - - def draw(self, context): - layout = self.layout - layout.operator("anim.keyframe_insert_menu", - text="Insert Keyframe...") - layout.operator("anim.keyframe_delete_v3d", - text="Delete Keyframe...") - layout.operator("anim.keying_set_active_set", - text="Change Keying Set...") - - # Animation Player (Thanks to marvin.k.breuer) # class VIEW3D_MT_Animation_Player(Menu): @@ -67,14 +53,13 @@ class VIEW3D_MT_Animation_Player(Menu): layout.operator("screen.frame_jump", text="Jump REW", icon='REW').end = False layout.separator() - layout.menu("VIEW3D_MT_KeyframeMenu", text="Keyframes", icon='DECORATE_ANIMATE') + layout.menu("VIEW3D_MT_object_animation", text="Keyframes", icon='DECORATE_ANIMATE') # List The Classes # classes = ( - VIEW3D_MT_KeyframeMenu, VIEW3D_MT_Animation_Player, ) diff --git a/space_view3d_spacebar_menu/curve_menus.py b/space_view3d_spacebar_menu/curve_menus.py index d06d7bb5..c9e72ff0 100644 --- a/space_view3d_spacebar_menu/curve_menus.py +++ b/space_view3d_spacebar_menu/curve_menus.py @@ -27,6 +27,7 @@ from bpy.props import ( BoolProperty, StringProperty, ) + from .object_menus import * @@ -39,73 +40,33 @@ class VIEW3D_MT_Edit_Curve(Menu): toolsettings = context.tool_settings - layout.operator("curve.extrude_move") - layout.operator("curve.spin") + layout.operator_menu_enum("curve.spline_type_set", "type") + layout.menu("VIEW3D_MT_mirror") + layout.operator("curve.make_segment") + layout.menu("VIEW3D_MT_edit_curve_segments") + layout.separator() + layout.operator("curve.duplicate_move") layout.operator("curve.split") layout.operator("curve.separate") - layout.operator("curve.make_segment") layout.operator("curve.cyclic_toggle") + layout.operator("curve.spin") layout.separator() - layout.operator("curve.delete", text="Delete...") + + layout.menu("VIEW3D_MT_edit_curve_showhide") + layout.menu("VIEW3D_MT_edit_curve_clean") layout.separator() - layout.menu("VIEW3D_MT_edit_curve_segments") + # layout.prop_menu_enum(toolsettings, "proportional_edit", # icon="PROP_CON") layout.prop_menu_enum(toolsettings, "proportional_edit_falloff", icon="SMOOTHCURVE") - layout.menu("VIEW3D_MT_edit_curve_showhide") - - -class VIEW3D_MT_EditCurveCtrlpoints(Menu): - bl_label = "Control Points" - - def draw(self, context): - layout = self.layout - - edit_object = context.edit_object - - if edit_object.type == 'CURVE': - layout.operator("transform.transform").mode = 'TILT' - layout.operator("curve.tilt_clear") - layout.operator("curve.separate") - layout.operator_menu_enum("curve.handle_type_set", "type") - layout.menu("VIEW3D_MT_hook") - - -class VIEW3D_MT_EditCurveSegments(Menu): - bl_label = "Curve Segments" - - def draw(self, context): - layout = self.layout - layout.operator("curve.subdivide") - layout.operator("curve.switch_direction") - - -class VIEW3D_MT_EditCurveSpecials(Menu): - bl_label = "Specials" - - def draw(self, context): - layout = self.layout - layout.operator("curve.subdivide") - layout.separator() - layout.operator("curve.switch_direction") - layout.operator("curve.spline_weight_set") - layout.operator("curve.radius_set") - layout.separator() - layout.operator("curve.smooth") - layout.operator("curve.smooth_weight") - layout.operator("curve.smooth_radius") - layout.operator("curve.smooth_tilt") # List The Classes # classes = ( VIEW3D_MT_Edit_Curve, - VIEW3D_MT_EditCurveCtrlpoints, - VIEW3D_MT_EditCurveSegments, - VIEW3D_MT_EditCurveSpecials, ) diff --git a/space_view3d_spacebar_menu/edit_mesh.py b/space_view3d_spacebar_menu/edit_mesh.py index 9847f63d..eff16c0d 100644 --- a/space_view3d_spacebar_menu/edit_mesh.py +++ b/space_view3d_spacebar_menu/edit_mesh.py @@ -32,95 +32,8 @@ from .object_menus import * from .snap_origin_cursor import * -# ********** Edit Mirror ********** -class VIEW3D_MT_MirrorMenuEM(Menu): - bl_label = "Mirror" - - def draw(self, context): - layout = self.layout - - props = layout.operator("transform.mirror", text="X Local") - props.constraint_axis = (True, False, False) - props.orient_type = 'LOCAL' - props = layout.operator("transform.mirror", text="Y Local") - props.constraint_axis = (False, True, False) - props.orient_type = 'LOCAL' - props = layout.operator("transform.mirror", text="Z Local") - props.constraint_axis = (False, False, True) - props.orient_type = 'LOCAL' - layout.separator() - layout.operator("object.vertex_group_mirror") - - -# ********** Normals / Auto Smooth Menu ********** -# Thanks to marvin.k.breuer for the Autosmooth part of the menu -class VIEW3D_MT_AutoSmooth(Menu): - bl_label = "Normals / Auto Smooth" - - def draw(self, context): - layout = self.layout - obj = context.object - obj_data = context.active_object.data - - # moved the VIEW3D_MT_edit_mesh_normals contents here under an Edit mode check - if obj and obj.type == 'MESH' and obj.mode in {'EDIT'}: - layout.operator("mesh.normals_make_consistent", - text="Recalculate Outside").inside = False - layout.operator("mesh.normals_make_consistent", - text="Recalculate Inside").inside = True - layout.operator("mesh.flip_normals") - layout.separator() - - layout.separator() - layout.prop(obj_data, "use_auto_smooth", text="Normals: Auto Smooth") - - # Auto Smooth Angle - two tab spaces to align it with the rest of the menu - layout.prop(obj_data, "auto_smooth_angle", - text=" Auto Smooth Angle") - - # Edit Mode Menu's # -# ********** Edit Mesh ********** -class VIEW3D_MT_Edit_Mesh(Menu): - bl_label = "Mesh" - - def draw(self, context): - layout = self.layout - toolsettings = context.tool_settings - view = context.space_data - - layout.menu("VIEW3D_MT_edit_mesh_vertices", icon='VERTEXSEL') - layout.menu("VIEW3D_MT_edit_mesh_edges", icon='EDGESEL') - layout.menu("VIEW3D_MT_edit_mesh_faces", icon='FACESEL') - layout.separator() - layout.operator("mesh.duplicate_move") - layout.separator() - layout.menu("VIEW3D_MT_edit_mesh_clean", icon='AUTO') -# layout.prop(view, "use_occlude_geometry") - layout.separator() - layout.menu("VIEW3D_MT_AutoSmooth", icon='META_DATA') - layout.operator("mesh.loopcut_slide", - text="Loopcut", icon='UV_EDGESEL') - layout.separator() - layout.operator("mesh.symmetrize") - layout.operator("mesh.symmetry_snap") - layout.separator() - layout.operator("mesh.bisect") - layout.operator_menu_enum("mesh.sort_elements", "type", text="Sort Elements...") - layout.separator() -# layout.prop_menu_enum(toolsettings, "proportional_edit") - layout.prop_menu_enum(toolsettings, "proportional_edit_falloff") - layout.separator() - - layout.prop(toolsettings, "use_mesh_automerge") - # Double Threshold - two tab spaces to align it with the rest of the menu - layout.prop(toolsettings, "double_threshold", text="Double Threshold") - - layout.separator() - layout.menu("VIEW3D_MT_edit_mesh_showhide") - - # ********** Edit Multiselect ********** class VIEW3D_MT_Edit_Multi(Menu): bl_label = "Mode Select" @@ -167,156 +80,6 @@ class VIEW3D_MT_EditM_Edge(Menu): layout.operator("mesh.region_to_loop") -# ********** Edit Mesh Cursor ********** -class VIEW3D_MT_EditCursorMenu(Menu): - bl_label = "Snap Cursor" - - def draw(self, context): - layout = self.layout - layout.operator_context = 'INVOKE_REGION_WIN' - layout.operator("object.setorigintoselected", - text="Origin to Selected V/F/E") - layout.separator() - layout.menu("VIEW3D_MT_Snap_Origin") - layout.menu("VIEW3D_MT_Snap_Context") - layout.separator() - layout.operator("view3d.snap_cursor_to_selected", - text="Cursor to Selected") - layout.operator("view3d.snap_cursor_to_center", - text="Cursor to World Origin") - layout.operator("view3d.snap_cursor_to_grid", - text="Cursor to Grid") - layout.operator("view3d.snap_cursor_to_active", - text="Cursor to Active") - layout.operator("view3d.snap_cursor_to_edge_intersection", - text="Cursor to Edge Intersection") - layout.separator() - layout.operator("view3d.snap_selected_to_cursor", - text="Selection to Cursor").use_offset = False - layout.operator("view3d.snap_selected_to_cursor", - text="Selection to Cursor (Keep Offset)").use_offset = True - layout.operator("view3d.snap_selected_to_grid", - text="Selection to Grid") - - -# ********** Edit Mesh UV ********** -class VIEW3D_MT_UV_Map(Menu): - bl_label = "UV Mapping" - - def draw(self, context): - layout = self.layout - layout.operator("uv.unwrap") - layout.separator() - layout.operator_context = 'INVOKE_DEFAULT' - layout.operator("uv.smart_project") - layout.operator("uv.lightmap_pack") - layout.operator("uv.follow_active_quads") - layout.operator_context = 'EXEC_REGION_WIN' - layout.operator("uv.cube_project") - layout.operator("uv.cylinder_project") - layout.operator("uv.sphere_project") - layout.operator_context = 'INVOKE_REGION_WIN' - layout.separator() - layout.operator("uv.project_from_view").scale_to_bounds = False - layout.operator("uv.project_from_view", text="Project from View (Bounds)").scale_to_bounds = True - layout.separator() - layout.operator("uv.reset") - - -# ********** Edit Mesh Transform ********** -class VIEW3D_MT_TransformMenuEdit(Menu): - bl_label = "Transform" - - def draw(self, context): - layout = self.layout - layout.operator("transform.translate", text="Move") - layout.operator("transform.rotate", text="Rotate") - layout.operator("transform.resize", text="Scale") - layout.separator() - layout.operator("transform.tosphere", text="To Sphere") - layout.operator("transform.shear", text="Shear") - layout.operator("transform.bend", text="Bend") - layout.operator("transform.push_pull", text="Push/Pull") - layout.operator("transform.vertex_warp", text="Warp") - layout.operator("transform.vertex_random", text="Randomize") - layout.separator() - layout.operator("transform.translate", text="Move Texture Space").texture_space = True - layout.operator("transform.resize", text="Scale Texture Space").texture_space = True - layout.separator() - layout.operator_context = 'EXEC_REGION_WIN' - layout.operator("transform.transform", - text="Align to Transform Orientation").mode = 'ALIGN' - layout.operator_context = 'EXEC_AREA' - layout.operator("object.origin_set", - text="Geometry to Origin").type = 'GEOMETRY_ORIGIN' - - -# Edit Select # -class VIEW3D_MT_Select_Edit_Mesh(Menu): - bl_label = "Select" - - def draw(self, context): - layout = self.layout - layout.operator("view3d.select_box") - layout.operator("view3d.select_circle") - layout.separator() - layout.operator("mesh.select_all").action = 'TOGGLE' - layout.operator("mesh.select_all", text="Inverse").action = 'INVERT' - layout.operator("mesh.select_linked", text="Linked") - layout.operator("mesh.faces_select_linked_flat", - text="Linked Flat Faces") - layout.operator("mesh.select_random", text="Random") - layout.operator("mesh.select_nth", text="Every N Number of Verts") - layout.separator() - layout.menu("VIEW3D_MT_Edit_Mesh_Select_Trait") - layout.menu("VIEW3D_MT_Edit_Mesh_Select_Similar") - layout.menu("VIEW3D_MT_Edit_Mesh_Select_More_Less") - layout.separator() - layout.operator("mesh.select_mirror", text="Mirror") - layout.operator("mesh.edges_select_sharp", text="Sharp Edges") - layout.operator("mesh.select_axis", text="Side of Active") - layout.operator("mesh.shortest_path_select", text="Shortest Path") - layout.separator() - layout.operator("mesh.loop_multi_select", text="Edge Loops").ring = False - layout.operator("mesh.loop_multi_select", text="Edge Rings").ring = True - layout.operator("mesh.loop_to_region") - layout.operator("mesh.region_to_loop") - - -class VIEW3D_MT_Edit_Mesh_Select_Similar(Menu): - bl_label = "Select Similar" - - def draw(self, context): - layout = self.layout - layout.operator_enum("mesh.select_similar", "type") - layout.operator("mesh.select_similar_region", text="Face Regions") - - -class VIEW3D_MT_Edit_Mesh_Select_Trait(Menu): - bl_label = "Select All by Trait" - - def draw(self, context): - layout = self.layout - if context.scene.tool_settings.mesh_select_mode[2] is False: - layout.operator("mesh.select_non_manifold", text="Non Manifold") - layout.operator("mesh.select_loose", text="Loose Geometry") - layout.operator("mesh.select_interior_faces", text="Interior Faces") - layout.operator("mesh.select_face_by_sides", text="By Number of Verts") - layout.operator("mesh.select_ungrouped", text="Ungrouped Verts") - - -class VIEW3D_MT_Edit_Mesh_Select_More_Less(Menu): - bl_label = "Select More/Less" - - def draw(self, context): - layout = self.layout - layout.operator("mesh.select_more", text="More") - layout.operator("mesh.select_less", text="Less") - layout.separator() - layout.operator("mesh.select_next_item", text="Next Active") - layout.operator("mesh.select_prev_item", text="Previous Active") - - # multiple edit select modes. class VIEW3D_OT_selecteditVertex(Operator): bl_idname = "selectedit.vertex" @@ -433,21 +196,26 @@ class VIEW3D_OT_selecteditVertsEdgesFaces(Operator): return {'FINISHED'} +# ********** Normals / Auto Smooth Menu ********** +# Thanks to marvin.k.breuer for the Autosmooth part of the menu + +def menu_func(self, context): + layout = self.layout + obj = context.object + obj_data = context.active_object.data + layout.separator() + layout.prop(obj_data, "use_auto_smooth", text="Normals: Auto Smooth") + + # Auto Smooth Angle - two tab spaces to align it with the rest of the menu + layout.prop(obj_data, "auto_smooth_angle", + text=" Auto Smooth Angle") + + # List The Classes # classes = ( - VIEW3D_MT_MirrorMenuEM, - VIEW3D_MT_AutoSmooth, - VIEW3D_MT_Edit_Mesh, VIEW3D_MT_Edit_Multi, VIEW3D_MT_EditM_Edge, - VIEW3D_MT_EditCursorMenu, - VIEW3D_MT_UV_Map, - VIEW3D_MT_TransformMenuEdit, - VIEW3D_MT_Select_Edit_Mesh, - VIEW3D_MT_Edit_Mesh_Select_Similar, - VIEW3D_MT_Edit_Mesh_Select_Trait, - VIEW3D_MT_Edit_Mesh_Select_More_Less, VIEW3D_OT_selecteditVertex, VIEW3D_OT_selecteditEdge, VIEW3D_OT_selecteditFace, @@ -463,6 +231,7 @@ def register(): for cls in classes: bpy.utils.register_class(cls) + bpy.types.VIEW3D_MT_edit_mesh_normals.append(menu_func) # Unregister Classes & Hotkeys # def unregister(): @@ -470,6 +239,7 @@ def unregister(): for cls in reversed(classes): bpy.utils.unregister_class(cls) + bpy.types.VIEW3D_MT_edit_mesh_normals.remove(menu_func) if __name__ == "__main__": register() diff --git a/space_view3d_spacebar_menu/object_menus.py b/space_view3d_spacebar_menu/object_menus.py index 5c3ef0ac..f6b0ba29 100644 --- a/space_view3d_spacebar_menu/object_menus.py +++ b/space_view3d_spacebar_menu/object_menus.py @@ -30,7 +30,8 @@ from bpy.props import ( from bl_ui.properties_paint_common import UnifiedPaintPanel - +from . edit_mesh import * +from . view_menus import * # Object Menus # # ********** Object Menu ********** @@ -41,119 +42,39 @@ 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.operator("object.delete", text="Delete...").use_global = False - layout.separator() + layout.menu("VIEW3D_MT_mirror") layout.menu("VIEW3D_MT_object_parent") layout.menu("VIEW3D_MT_Duplicate") 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' - - layout.menu("VIEW3D_MT_make_links", text="Make Links...") - layout.menu("VIEW3D_MT_Object_Data_Link") - layout.separator() - layout.menu("VIEW3D_MT_AutoSmooth", icon='ALIASED') - layout.separator() - layout.menu("VIEW3D_MT_object_constraints") - layout.menu("VIEW3D_MT_object_track") - layout.menu("VIEW3D_MT_object_animation") + layout.menu("VIEW3D_MT_make_links", text="Make Links") + layout.menu("VIEW3D_MT_object_relations") layout.separator() - layout.menu("VIEW3D_MT_object_showhide") - layout.separator() - layout.operator_menu_enum("object.convert", "target") - - -# ********** Add Menu ********** -class VIEW3D_MT_AddMenu(Menu): - bl_label = "Add Object" - - def draw(self, context): - layout = self.layout - layout.operator_context = 'EXEC_REGION_WIN' - layout.menu("VIEW3D_MT_mesh_add", text="Add Mesh", - icon='OUTLINER_OB_MESH') - layout.menu("VIEW3D_MT_curve_add", text="Add Curve", - icon='OUTLINER_OB_CURVE') - layout.menu("VIEW3D_MT_surface_add", text="Add Surface", - icon='OUTLINER_OB_SURFACE') - layout.operator_menu_enum("object.metaball_add", "type", - icon='OUTLINER_OB_META') - layout.operator("object.text_add", text="Add Text", - icon='OUTLINER_OB_FONT') - layout.operator_menu_enum("object.gpencil_add", "type", text="Grease Pencil", icon='OUTLINER_OB_GREASEPENCIL') - layout.separator() - layout.menu("VIEW3D_MT_armature_add", text="Add Armature", - icon='OUTLINER_OB_ARMATURE') - layout.operator("object.add", text="Lattice", - icon='OUTLINER_OB_LATTICE').type = 'LATTICE' - layout.separator() + ob = context.active_object + if ob and ob.type == 'GPENCIL' and context.gpencil_data: + layout.operator_menu_enum("gpencil.convert", "type", text="Convert to") + else: + layout.operator_menu_enum("object.convert", "target") - layout.operator_menu_enum("object.empty_add", "type", text="Empty", icon='OUTLINER_OB_EMPTY') - layout.menu("VIEW3D_MT_image_add", text="Image", icon='OUTLINER_OB_IMAGE') + layout.menu("VIEW3D_MT_object_showhide") layout.separator() - layout.operator_menu_enum("object.light_add", "type", - icon="OUTLINER_OB_LIGHT") - layout.menu("VIEW3D_MT_lightprobe_add", icon='OUTLINER_OB_LIGHTPROBE') - layout.separator() - - layout.operator("object.camera_add", text="Camera", - icon='OUTLINER_OB_CAMERA') + layout.menu("VIEW3D_MT_object_constraints") + layout.menu("VIEW3D_MT_object_track") layout.separator() - layout.operator("object.speaker_add", text="Speaker", icon='OUTLINER_OB_SPEAKER') + layout.menu("VIEW3D_MT_object_rigid_body") + layout.menu("VIEW3D_MT_object_quick_effects") layout.separator() - layout.operator_menu_enum("object.effector_add", "type", - text="Force Field", - icon='FORCE_FORCE') - layout.menu("VIEW3D_MT_object_quick_effects", text="Quick Effects", icon='PARTICLES') + layout.operator("view3d.copybuffer", text="Copy Objects", icon='COPYDOWN') + layout.operator("view3d.pastebuffer", text="Paste Objects", icon='PASTEDOWN') layout.separator() - has_collections = bool(bpy.data.collections) - col = layout.column() - col.enabled = has_collections - - if not has_collections or len(bpy.data.collections) > 10: - col.operator_context = 'INVOKE_REGION_WIN' - col.operator( - "object.collection_instance_add", - text="Collection Instance..." if has_collections else "No Collections to Instance", - icon='OUTLINER_OB_GROUP_INSTANCE', - ) - else: - col.operator_menu_enum( - "object.collection_instance_add", - "collection", - text="Collection Instance", - icon='OUTLINER_OB_GROUP_INSTANCE', - ) - - -# ********** Object Mirror ********** -class VIEW3D_MT_MirrorMenu(Menu): - bl_label = "Mirror" - - def draw(self, context): - layout = self.layout - layout.operator("transform.mirror", text="Interactive Mirror") - layout.separator() - layout.operator_context = 'INVOKE_REGION_WIN' - props = layout.operator("transform.mirror", text="X Global") - props.constraint_axis = (True, False, False) - props.orient_type = 'GLOBAL' - props = layout.operator("transform.mirror", text="Y Global") - props.constraint_axis = (False, True, False) - props.orient_type = 'GLOBAL' - props = layout.operator("transform.mirror", text="Z Global") - props.constraint_axis = (False, False, True) - props.orient_type = 'GLOBAL' + layout.operator_context = 'EXEC_DEFAULT' + layout.operator("object.delete", text="Delete").use_global = False + layout.operator("object.delete", text="Delete Global").use_global = True # ********** Object Interactive Mode ********** @@ -223,41 +144,6 @@ class VIEW3D_MT_Interactive_Mode_GPencil(Menu): layout.operator(VIEW3D_OT_SetObjectMode.bl_idname, text="Draw", icon="GREASEPENCIL").mode = "PAINT_GPENCIL" layout.operator(VIEW3D_OT_SetObjectMode.bl_idname, text="Weight Paint", icon="WPAINT_HLT").mode = "WEIGHT_GPENCIL" -# currently unused -class VIEW3D_MT_Edit_Gpencil(Menu): - bl_label = "GPencil" - - def draw(self, context): - toolsettings = context.tool_settings - layout = self.layout - - layout.operator("gpencil.brush_paint", text="Sculpt Strokes").wait_for_input = True - layout.prop_menu_enum(toolsettings.gpencil_sculpt, "tool", text="Sculpt Brush") - layout.separator() - layout.menu("VIEW3D_MT_edit_gpencil_transform") - layout.operator("transform.mirror", text="Mirror") - layout.menu("GPENCIL_MT_snap") - layout.separator() - layout.menu("VIEW3D_MT_object_animation") # NOTE: provides keyingset access... - layout.separator() - layout.menu("VIEW3D_MT_edit_gpencil_delete") - layout.operator("gpencil.duplicate_move", text="Duplicate") - layout.separator() - layout.menu("VIEW3D_MT_select_gpencil") - layout.separator() - layout.operator("gpencil.copy", text="Copy") - layout.operator("gpencil.paste", text="Paste") - layout.separator() - layout.prop_menu_enum(toolsettings, "proportional_edit") - layout.prop_menu_enum(toolsettings, "proportional_edit_falloff") - layout.separator() - layout.operator("gpencil.reveal") - layout.operator("gpencil.hide", text="Show Active Layer Only").unselected = True - layout.operator("gpencil.hide", text="Hide Active Layer").unselected = False - layout.separator() - layout.operator_menu_enum("gpencil.move_to_layer", "layer", text="Move to Layer") - layout.operator_menu_enum("gpencil.convert", "type", text="Convert to Geometry...") - # ********** Text Interactive Mode ********** class VIEW3D_OT_Interactive_Mode_Text(Operator): @@ -275,31 +161,6 @@ class VIEW3D_OT_Interactive_Mode_Text(Operator): return {'FINISHED'} -# ********** Object Parent ********** -class VIEW3D_MT_ParentMenu(Menu): - bl_label = "Parent" - - def draw(self, context): - layout = self.layout - - layout.operator("object.parent_set", text="Set") - layout.operator("object.parent_clear", text="Clear") - - -# ********** Object Group ********** -class VIEW3D_MT_GroupMenu(Menu): - bl_label = "Group" - - def draw(self, context): - layout = self.layout - layout.operator("collection.create") - layout.operator("collection.objects_add_active") - layout.separator() - layout.operator("collection.objects_remove") - layout.operator("collection.objects_remove_all") - layout.operator("collection.objects_remove_active") - - # ********** Object Camera Options ********** class VIEW3D_MT_Camera_Options(Menu): bl_label = "Camera" @@ -307,22 +168,12 @@ class VIEW3D_MT_Camera_Options(Menu): def draw(self, context): layout = self.layout layout.operator_context = 'EXEC_REGION_WIN' - layout.operator("object.camera_add", text="Add Camera", icon='OUTLINER_OB_CAMERA') - layout.operator("view3d.object_as_camera", text="Object As Camera", icon='OUTLINER_OB_CAMERA') - -class VIEW3D_MT_Object_Data_Link(Menu): - bl_label = "Object Data" - - def draw(self, context): - layout = self.layout - - layout.operator_menu_enum("object.make_local", "type", text="Make Local...") - layout.menu("VIEW3D_MT_make_single_user") - layout.operator("object.proxy_make", text="Make Proxy...") - layout.operator("object.make_dupli_face") - layout.separator() - layout.operator("object.data_transfer") - layout.operator("object.datalayout_transfer") + layout.operator("object.select_camera", text="Select Camera") + layout.operator("object.camera_add", text="Add Camera") + layout.operator("view3d.view_camera", text="View Camera") + layout.operator("view3d.camera_to_view", text="Camera to View") + layout.operator("view3d.camera_to_view_selected", text="Camera to Selected") + layout.operator("view3d.object_as_camera", text="Object As Camera") class VIEW3D_MT_Duplicate(Menu): @@ -371,21 +222,51 @@ class VIEW3D_OT_SetObjectMode(Operator): return {'FINISHED'} +# currently unused +class VIEW3D_MT_Edit_Gpencil(Menu): + bl_label = "GPencil" + + def draw(self, context): + toolsettings = context.tool_settings + layout = self.layout + + layout.operator("gpencil.brush_paint", text="Sculpt Strokes").wait_for_input = True + layout.prop_menu_enum(toolsettings.gpencil_sculpt, "tool", text="Sculpt Brush") + layout.separator() + layout.menu("VIEW3D_MT_edit_gpencil_transform") + layout.operator("transform.mirror", text="Mirror") + layout.menu("GPENCIL_MT_snap") + layout.separator() + layout.menu("VIEW3D_MT_object_animation") # NOTE: provides keyingset access... + layout.separator() + layout.menu("VIEW3D_MT_edit_gpencil_delete") + layout.operator("gpencil.duplicate_move", text="Duplicate") + layout.separator() + layout.menu("VIEW3D_MT_select_gpencil") + layout.separator() + layout.operator("gpencil.copy", text="Copy") + layout.operator("gpencil.paste", text="Paste") + layout.separator() + layout.prop_menu_enum(toolsettings, "proportional_edit") + layout.prop_menu_enum(toolsettings, "proportional_edit_falloff") + layout.separator() + layout.operator("gpencil.reveal") + layout.operator("gpencil.hide", text="Show Active Layer Only").unselected = True + layout.operator("gpencil.hide", text="Hide Active Layer").unselected = False + layout.separator() + layout.operator_menu_enum("gpencil.move_to_layer", "layer", text="Move to Layer") + layout.operator_menu_enum("gpencil.convert", "type", text="Convert to Geometry...") + # List The Classes # classes = ( - VIEW3D_MT_AddMenu, VIEW3D_MT_Object, - VIEW3D_MT_MirrorMenu, - VIEW3D_MT_ParentMenu, - VIEW3D_MT_GroupMenu, VIEW3D_MT_UndoS, VIEW3D_MT_Camera_Options, VIEW3D_MT_InteractiveMode, VIEW3D_MT_InteractiveModeOther, VIEW3D_OT_SetObjectMode, - VIEW3D_MT_Object_Data_Link, VIEW3D_MT_Duplicate, VIEW3D_OT_Interactive_Mode_Text, VIEW3D_OT_Interactive_Mode_Grease_Pencil, diff --git a/space_view3d_spacebar_menu/sculpt_brush_paint.py b/space_view3d_spacebar_menu/sculpt_brush_paint.py deleted file mode 100644 index 002a7f9c..00000000 --- a/space_view3d_spacebar_menu/sculpt_brush_paint.py +++ /dev/null @@ -1,339 +0,0 @@ -# ##### BEGIN GPL LICENSE BLOCK ##### -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -# -# ##### END GPL LICENSE BLOCK ##### -# Contributed to by: meta-androcto, JayDez, sim88, sam, lijenstina, mkb, wisaac, CoDEmanX # - - -import bpy -from bpy.types import ( - Operator, - Menu, - ) -from bpy.props import ( - BoolProperty, - StringProperty, - ) - -from bl_ui.properties_paint_common import UnifiedPaintPanel -from .object_menus import * - -# Brushes Menu's # -# Thanks to CoDEmanX for the code -class VIEW3D_MT_Brush_Selection(Menu): - bl_label = "Brush Tool" - - def draw(self, context): - layout = self.layout - settings = UnifiedPaintPanel.paint_settings(context) - - # check if brush exists (for instance, in paint mode before adding a slot) - if hasattr(settings, 'brush'): - brush = settings.brush - else: - brush = None - - if not brush: - layout.label(text="No Brushes currently available", icon="INFO") - return - - if not context.particle_edit_object: - if UseBrushesLists(): - flow = layout.column_flow(columns=3) - - for brsh in bpy.data.brushes: - if (context.sculpt_object and brsh.use_paint_sculpt): - props = flow.operator("wm.context_set_id", text=brsh.name, - icon_value=layout.icon(brsh)) - props.data_path = "tool_settings.sculpt.brush" - props.value = brsh.name - elif (context.image_paint_object and brsh.use_paint_image): - props = flow.operator("wm.context_set_id", text=brsh.name, - icon_value=layout.icon(brsh)) - props.data_path = "tool_settings.image_paint.brush" - props.value = brsh.name - elif (context.vertex_paint_object and brsh.use_paint_vertex): - props = flow.operator("wm.context_set_id", text=brsh.name, - icon_value=layout.icon(brsh)) - props.data_path = "tool_settings.vertex_paint.brush" - props.value = brsh.name - elif (context.weight_paint_object and brsh.use_paint_weight): - props = flow.operator("wm.context_set_id", text=brsh.name, - icon_value=layout.icon(brsh)) - props.data_path = "tool_settings.weight_paint.brush" - props.value = brsh.name - else: - layout.template_ID_preview(settings, "brush", new="brush.add", rows=3, cols=8) - - -class VIEW3D_MT_Brush_Settings(Menu): - bl_label = "Brush Settings" - - def draw(self, context): - layout = self.layout - settings = UnifiedPaintPanel.paint_settings(context) - brush = getattr(settings, "brush", None) - - ups = context.tool_settings.unified_paint_settings - layout.prop(ups, "use_unified_size", text="Unified Size") - layout.prop(ups, "use_unified_strength", text="Unified Strength") - if context.image_paint_object or context.vertex_paint_object: - layout.prop(ups, "use_unified_color", text="Unified Color") - layout.separator() - - if not brush: - layout.label(text="No Brushes currently available", icon="INFO") - return - - layout.menu("VIEW3D_MT_brush_paint_modes") - - if context.sculpt_object: - sculpt_tool = brush.sculpt_tool - - layout.separator() - layout.operator_menu_enum("brush.curve_preset", "shape", text="Curve Preset") - layout.separator() - - if sculpt_tool != 'GRAB': - layout.prop_menu_enum(brush, "stroke_method") - - if sculpt_tool in {'DRAW', 'PINCH', 'INFLATE', 'LAYER', 'CLAY'}: - layout.prop_menu_enum(brush, "direction") - - if sculpt_tool == 'LAYER': - layout.prop(brush, "use_persistent") - layout.operator("sculpt.set_persistent_base") - - -# Sculpt Menu's # -class VIEW3D_MT_Sculpts(Menu): - bl_label = "Sculpt" - - def draw(self, context): - layout = self.layout - toolsettings = context.tool_settings - sculpt = toolsettings.sculpt - - layout.prop(sculpt, "use_symmetry_x") - layout.prop(sculpt, "use_symmetry_y") - layout.prop(sculpt, "use_symmetry_z") - - layout.separator() - layout.prop(sculpt, "lock_x") - layout.prop(sculpt, "lock_y") - layout.prop(sculpt, "lock_z") - - layout.separator() - layout.prop(sculpt, "use_threaded", text="Threaded Sculpt") - layout.prop(sculpt, "show_low_resolution") - layout.prop(sculpt, "use_deform_only") - - layout.separator() - layout.prop(sculpt, "show_brush") - - -class VIEW3D_MT_Hide_Masks(Menu): - bl_label = "Hide/Mask" - - def draw(self, context): - layout = self.layout - - props = layout.operator("paint.mask_lasso_gesture", text="Lasso Mask") - layout.separator() - props = layout.operator("view3d.select_box", text="Box Mask") - props = layout.operator("paint.hide_show", text="Box Hide") - props.action = 'HIDE' - props.area = 'INSIDE' - - props = layout.operator("paint.hide_show", text="Box Show") - props.action = 'SHOW' - props.area = 'INSIDE' - layout.separator() - - props = layout.operator("paint.mask_flood_fill", text="Fill Mask") - props.mode = 'VALUE' - props.value = 1 - - props = layout.operator("paint.mask_flood_fill", text="Clear Mask") - props.mode = 'VALUE' - props.value = 0 - - layout.operator("paint.mask_flood_fill", text="Invert Mask").mode = 'INVERT' - layout.separator() - - props = layout.operator("paint.hide_show", text="Show All", icon="RESTRICT_VIEW_OFF") - props.action = 'SHOW' - props.area = 'ALL' - - props = layout.operator("paint.hide_show", text="Hide Masked", icon="RESTRICT_VIEW_ON") - props.area = 'MASKED' - props.action = 'HIDE' - - -# Sculpt Specials Menu (Thanks to marvin.k.breuer) # -class VIEW3D_MT_Sculpt_Specials(Menu): - bl_label = "Sculpt Specials" - - def draw(self, context): - layout = self.layout - settings = context.tool_settings - - if context.sculpt_object.use_dynamic_topology_sculpting: - layout.operator("sculpt.dynamic_topology_toggle", - icon='X', text="Disable Dyntopo") - layout.separator() - - if (settings.sculpt.detail_type_method == 'CONSTANT'): - layout.prop(settings.sculpt, "constant_detail", text="Const.") - layout.operator("sculpt.sample_detail_size", text="", icon='EYEDROPPER') - else: - layout.prop(settings.sculpt, "detail_size", text="Detail") - layout.separator() - - layout.operator("sculpt.symmetrize", icon='ARROW_LEFTRIGHT') - layout.prop(settings.sculpt, "symmetrize_direction", "") - layout.separator() - - layout.operator("sculpt.optimize") - if (settings.sculpt.detail_type_method == 'CONSTANT'): - layout.operator("sculpt.detail_flood_fill") - layout.separator() - - layout.prop(settings.sculpt, "detail_refine_method", text="") - layout.prop(settings.sculpt, "detail_type_method", text="") - layout.separator() - layout.prop(settings.sculpt, "use_smooth_shading", "Smooth") - else: - layout.operator("sculpt.dynamic_topology_toggle", text="Enable Dyntopo") - - -# Vertex Color Menu # -class VIEW3D_MT_Vertex_Colors(Menu): - bl_label = "Vertex Colors" - - def draw(self, context): - layout = self.layout - layout.operator("paint.vertex_color_set") - layout.separator() - - layout.operator("paint.vertex_color_smooth") - layout.operator("paint.vertex_color_dirt") - - -# Weight Paint Menu # -class VIEW3D_MT_Paint_Weights(Menu): - bl_label = "Weights" - - def draw(self, context): - layout = self.layout - - layout.operator("paint.weight_from_bones", - text="Assign Automatic From Bones").type = 'AUTOMATIC' - layout.operator("paint.weight_from_bones", - text="Assign From Bone Envelopes").type = 'ENVELOPES' - layout.separator() - - layout.operator("object.vertex_group_normalize_all", text="Normalize All") - layout.operator("object.vertex_group_normalize", text="Normalize") - layout.separator() - - layout.operator("object.vertex_group_mirror", text="Mirror") - layout.operator("object.vertex_group_invert", text="Invert") - layout.separator() - - layout.operator("object.vertex_group_clean", text="Clean") - layout.operator("object.vertex_group_quantize", text="Quantize") - layout.separator() - - layout.operator("object.vertex_group_levels", text="Levels") - layout.operator("object.vertex_group_smooth", text="Smooth") - layout.separator() - - props = layout.operator("object.data_transfer", text="Transfer Weights") - props.use_reverse_transfer = True - props.data_type = 'VGROUP_WEIGHTS' - layout.separator() - - layout.operator("object.vertex_group_limit_total", text="Limit Total") - layout.operator("object.vertex_group_fix", text="Fix Deforms") - layout.separator() - - layout.operator("paint.weight_set") - - -class VIEW3D_MT_Angle_Control(Menu): - bl_label = "Angle Control" - - @classmethod - def poll(cls, context): - settings = UnifiedPaintPanel.paint_settings(context) - if not settings: - return False - - brush = settings.brush - tex_slot = brush.texture_slot - - return tex_slot.has_texture_angle and tex_slot.has_texture_angle_source - - def draw(self, context): - layout = self.layout - - settings = UnifiedPaintPanel.paint_settings(context) - brush = settings.brush - - sculpt = (context.sculpt_object is not None) - - tex_slot = brush.texture_slot - - layout.prop(tex_slot, "use_rake", text="Rake") - - if brush.brush_capabilities.has_random_texture_angle and tex_slot.has_random_texture_angle: - if sculpt: - if brush.sculpt_capabilities.has_random_texture_angle: - layout.prop(tex_slot, "use_random", text="Random") - else: - layout.prop(tex_slot, "use_random", text="Random") - - -# List The Classes # - -classes = ( - VIEW3D_MT_Angle_Control, - VIEW3D_MT_Sculpt_Specials, - VIEW3D_MT_Brush_Settings, - VIEW3D_MT_Brush_Selection, - VIEW3D_MT_Sculpts, - VIEW3D_MT_Hide_Masks, - VIEW3D_MT_Vertex_Colors, - VIEW3D_MT_Paint_Weights, -) - - -# Register Classes & Hotkeys # -def register(): - for cls in classes: - bpy.utils.register_class(cls) - - -# Unregister Classes & Hotkeys # -def unregister(): - - for cls in reversed(classes): - bpy.utils.unregister_class(cls) - - -if __name__ == "__main__": - register() diff --git a/space_view3d_spacebar_menu/select_menus.py b/space_view3d_spacebar_menu/select_menus.py deleted file mode 100644 index 3b1dbc9b..00000000 --- a/space_view3d_spacebar_menu/select_menus.py +++ /dev/null @@ -1,440 +0,0 @@ -# ##### BEGIN GPL LICENSE BLOCK ##### -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -# -# ##### END GPL LICENSE BLOCK ##### -# Contributed to by: meta-androcto, JayDez, sim88, sam, lijenstina, mkb, wisaac, CoDEmanX # - - -import bpy -from bpy.types import ( - Operator, - Menu, - ) -from bpy.props import ( - BoolProperty, - StringProperty, - ) - -from bl_ui.properties_paint_common import UnifiedPaintPanel -from .object_menus import * - -# Select Menu's # - -# Object Select # -class VIEW3D_MT_Select_Object(Menu): - bl_label = "Select" - - def draw(self, context): - layout = self.layout - layout.operator_context = 'INVOKE_REGION_WIN' - layout.operator("view3d.select_box") - layout.operator("view3d.select_circle") - layout.separator() - layout.operator("object.select_all", text="All").action = 'SELECT' - layout.operator("object.select_all", text="None").action = 'DESELECT' - layout.operator("object.select_all", text="Invert").action = 'INVERT' - layout.separator() - layout.operator("object.select_camera", text="Select Active Camera") - layout.operator("object.select_mirror", text="Mirror Selection") - layout.operator("object.select_random", text="Select Random") - layout.separator() - layout.operator_menu_enum("object.select_by_type", "type", text="Select All by Type...") - layout.operator_menu_enum("object.select_grouped", "type", text="Select Grouped") - layout.operator_menu_enum("object.select_linked", "type", text="Select Linked") - layout.separator() - layout.menu("VIEW3D_MT_Select_Object_More_Less", text="More/Less") - layout.operator("object.select_pattern", text="Select Pattern...") - - -class VIEW3D_MT_Select_Object_More_Less(Menu): - bl_label = "Select More/Less" - - def draw(self, context): - layout = self.layout - layout.operator("object.select_more", text="More") - layout.operator("object.select_less", text="Less") - layout.separator() - props = layout.operator("object.select_hierarchy", text="Parent") - props.extend = False - props.direction = 'PARENT' - props = layout.operator("object.select_hierarchy", text="Child") - props.extend = False - props.direction = 'CHILD' - layout.separator() - props = layout.operator("object.select_hierarchy", text="Extend Parent") - props.extend = True - props.direction = 'PARENT' - props = layout.operator("object.select_hierarchy", text="Extend Child") - props.extend = True - props.direction = 'CHILD' - - -# Edit Curve Select # -class VIEW3D_MT_Select_Edit_Curve(Menu): - bl_label = "Select" - - def draw(self, context): - layout = self.layout - layout.operator("view3d.select_box") - layout.operator("view3d.select_circle") - layout.separator() - layout.operator("curve.select_all").action = 'TOGGLE' - layout.operator("curve.select_all", text="Inverse").action = 'INVERT' - layout.operator("curve.select_nth") - layout.separator() - layout.operator("curve.select_random") - layout.operator("curve.select_linked", text="Select Linked") - layout.operator("curve.select_similar", text="Select Similar") - layout.operator("curve.de_select_first") - layout.operator("curve.de_select_last") - layout.operator("curve.select_next") - layout.operator("curve.select_previous") - layout.separator() - layout.operator("curve.select_more") - layout.operator("curve.select_less") - - -# Armature Select # -class VIEW3D_MT_SelectArmatureMenu(Menu): - bl_label = "Select" - - def draw(self, context): - layout = self.layout - layout.operator("view3d.select_box") - layout.operator("armature.select_all") - layout.operator("armature.select_inverse", text="Inverse") - layout.operator("armature.select_hierarchy", - text="Parent").direction = 'PARENT' - layout.operator("armature.select_hierarchy", - text="Child").direction = 'CHILD' - props = layout.operator("armature.select_hierarchy", - text="Extend Parent") - props.extend = True - props.direction = 'PARENT' - props = layout.operator("armature.select_hierarchy", - text="Extend Child") - props.extend = True - props.direction = 'CHILD' - layout.operator("object.select_pattern", text="Select Pattern...") - - -class VIEW3D_MT_Select_Edit_Armature(Menu): - bl_label = "Select" - - def draw(self, context): - layout = self.layout - - layout.operator("view3d.select_box") - layout.operator("view3d.select_circle") - - layout.separator() - - layout.operator("armature.select_all").action = 'TOGGLE' - layout.operator("armature.select_all", text="Inverse").action = 'INVERT' - layout.operator("armature.select_mirror", text="Mirror").extend = False - - layout.separator() - - layout.operator("armature.select_more", text="More") - layout.operator("armature.select_less", text="Less") - - layout.separator() - - props = layout.operator("armature.select_hierarchy", text="Parent") - props.extend = False - props.direction = 'PARENT' - - props = layout.operator("armature.select_hierarchy", text="Child") - props.extend = False - props.direction = 'CHILD' - - layout.separator() - - props = layout.operator("armature.select_hierarchy", text="Extend Parent") - props.extend = True - props.direction = 'PARENT' - - props = layout.operator("armature.select_hierarchy", text="Extend Child") - props.extend = True - props.direction = 'CHILD' - - layout.operator_menu_enum("armature.select_similar", "type", text="Similar") - layout.operator("object.select_pattern", text="Select Pattern...") - - -class VIEW3D_MT_Select_Pose(Menu): - bl_label = "Select" - - def draw(self, context): - layout = self.layout - layout.operator("view3d.select_box") - layout.operator("view3d.select_circle") - layout.separator() - layout.operator("pose.select_all").action = 'TOGGLE' - layout.operator("pose.select_all", text="Inverse").action = 'INVERT' - layout.operator("pose.select_mirror", text="Flip Active") - layout.operator("pose.select_constraint_target", - text="Constraint Target") - layout.separator() - layout.operator("pose.select_linked", text="Linked") - layout.operator("pose.select_hierarchy", - text="Parent").direction = 'PARENT' - layout.operator("pose.select_hierarchy", - text="Child").direction = 'CHILD' - props = layout.operator("pose.select_hierarchy", text="Extend Parent") - props.extend = True - props.direction = 'PARENT' - props = layout.operator("pose.select_hierarchy", text="Extend Child") - props.extend = True - props.direction = 'CHILD' - layout.operator_menu_enum("pose.select_grouped", "type", - text="Grouped") - layout.separator() - layout.operator("object.select_pattern", text="Select Pattern...") - layout.menu("VIEW3D_MT_select_pose_more_less") - - -class VIEW3D_MT_Select_Pose_More_Less(Menu): - bl_label = "Select More/Less" - - def draw(self, context): - layout = self.layout - props = layout.operator("pose.select_hierarchy", text="Parent") - props.extend = False - props.direction = 'PARENT' - - props = layout.operator("pose.select_hierarchy", text="Child") - props.extend = False - props.direction = 'CHILD' - - props = layout.operator("pose.select_hierarchy", text="Extend Parent") - props.extend = True - props.direction = 'PARENT' - - props = layout.operator("pose.select_hierarchy", text="Extend Child") - props.extend = True - props.direction = 'CHILD' - - - -# Surface Select # -class VIEW3D_MT_Select_Edit_Surface(Menu): - bl_label = "Select" - - def draw(self, context): - layout = self.layout - layout.operator("view3d.select_box") - layout.operator("view3d.select_circle") - layout.separator() - layout.operator("curve.select_all").action = 'TOGGLE' - layout.operator("curve.select_all", text="Inverse").action = 'INVERT' - layout.operator("curve.select_random") - layout.operator("curve.select_nth") - layout.operator("curve.select_linked", text="Select Linked") - layout.operator("curve.select_similar", text="Select Similar") - layout.operator("curve.select_row") - layout.separator() - layout.operator("curve.select_more") - layout.operator("curve.select_less") - - -# Metaball Select # -class VIEW3D_MT_SelectMetaball(Menu): - bl_label = "Select" - - def draw(self, context): - layout = self.layout - layout.operator("view3d.select_box") - layout.operator("view3d.select_circle") - layout.separator() - layout.operator("mball.select_all").action = 'TOGGLE' - layout.operator("mball.select_all").action = 'INVERT' - layout.operator("mball.select_random_metaelems") - - -class VIEW3D_MT_Select_Edit_Metaball(Menu): - bl_label = "Select" - - def draw(self, context): - layout = self.layout - layout.operator("view3d.select_box") - layout.operator("view3d.select_circle") - layout.operator("mball.select_all").action = 'TOGGLE' - layout.operator("mball.select_all", text="Inverse").action = 'INVERT' - layout.operator("mball.select_random_metaelems") - layout.operator_menu_enum("mball.select_similar", "type", text="Similar") - - -# Particle Select # -class VIEW3D_MT_Selection_Mode_Particle(Menu): - bl_label = "Particle Select and Display Mode" - - def draw(self, context): - layout = self.layout - toolsettings = context.tool_settings - - layout.prop(toolsettings.particle_edit, "select_mode", expand=True) - - -class VIEW3D_MT_Select_Particle(Menu): - bl_label = "Select" - - def draw(self, context): - layout = self.layout - - layout.operator("view3d.select_box") - layout.operator("view3d.select_circle") - layout.separator() - - layout.operator("particle.select_all").action = 'TOGGLE' - layout.operator("particle.select_linked") - layout.operator("particle.select_all", text="Inverse").action = 'INVERT' - - layout.separator() - layout.operator("particle.select_more") - layout.operator("particle.select_less") - - layout.separator() - layout.operator("particle.select_random") - - layout.separator() - layout.operator("particle.select_roots", text="Roots") - layout.operator("particle.select_tips", text="Tips") - - -# Lattice Edit Select # -class VIEW3D_MT_Select_Edit_Lattice(Menu): - bl_label = "Select" - - def draw(self, context): - layout = self.layout - - layout.operator("view3d.select_box") - layout.operator("view3d.select_circle") - layout.separator() - layout.operator("lattice.select_mirror") - layout.operator("lattice.select_random") - layout.operator("lattice.select_all").action = 'TOGGLE' - layout.operator("lattice.select_all", text="Inverse").action = 'INVERT' - layout.separator() - layout.operator("lattice.select_ungrouped", text="Ungrouped Verts") - - -# Grease Pencil Select # -class VIEW3D_MT_Select_Gpencil(Menu): - # To Do: used in 3dview header might work if mapped to mouse - # Not in Class List yet - bl_label = "Select" - - def draw(self, context): - layout = self.layout - - layout.operator("gpencil.select_box") - layout.operator("gpencil.select_circle") - - layout.separator() - - layout.operator("gpencil.select_all", text="(De)select All").action = 'TOGGLE' - layout.operator("gpencil.select_all", text="Inverse").action = 'INVERT' - layout.operator("gpencil.select_linked", text="Linked") - # layout.operator_menu_enum("gpencil.select_grouped", "type", text="Grouped") - layout.operator("gpencil.select_grouped", text="Grouped") - - layout.separator() - - layout.operator("gpencil.select_more") - layout.operator("gpencil.select_less") - - -# Text Select # -class VIEW3D_MT_Select_Edit_Text(Menu): - # To Do: used in 3dview header might work if mapped to mouse - # Not in Class List yet - bl_label = "Edit" - - def draw(self, context): - layout = self.layout - layout.operator("font.text_copy", text="Copy") - layout.operator("font.text_cut", text="Cut") - layout.operator("font.text_paste", text="Paste") - layout.operator("font.text_paste_from_file") - layout.operator("font.select_all") - - -# Paint Mode Menus # -class VIEW3D_MT_Select_Paint_Mask(Menu): - bl_label = "Select" - - def draw(self, context): - layout = self.layout - layout.operator("view3d.select_box") - layout.operator("view3d.select_circle") - layout.operator("paint.face_select_all").action = 'TOGGLE' - layout.operator("paint.face_select_all", text="Inverse").action = 'INVERT' - layout.operator("paint.face_select_linked", text="Linked") - - -class VIEW3D_MT_Select_Paint_Mask_Vertex(Menu): - bl_label = "Select" - - def draw(self, context): - layout = self.layout - layout.operator("view3d.select_box") - layout.operator("view3d.select_circle") - layout.operator("paint.vert_select_all").action = 'TOGGLE' - layout.operator("paint.vert_select_all", text="Inverse").action = 'INVERT' - layout.operator("paint.vert_select_ungrouped", text="Ungrouped Verts") - - - -# List The Classes # - -classes = ( - VIEW3D_MT_Select_Object, - VIEW3D_MT_Select_Object_More_Less, - VIEW3D_MT_Select_Edit_Curve, - VIEW3D_MT_SelectArmatureMenu, - VIEW3D_MT_Select_Edit_Armature, - VIEW3D_MT_Select_Pose, - VIEW3D_MT_Select_Pose_More_Less, - VIEW3D_MT_Select_Edit_Surface, - VIEW3D_MT_SelectMetaball, - VIEW3D_MT_Select_Edit_Metaball, - VIEW3D_MT_Select_Particle, - VIEW3D_MT_Select_Edit_Lattice, - VIEW3D_MT_Select_Paint_Mask, - VIEW3D_MT_Select_Paint_Mask_Vertex, - VIEW3D_MT_Selection_Mode_Particle, - VIEW3D_MT_Select_Gpencil, - VIEW3D_MT_Select_Edit_Text, -) - - -# Register Classes & Hotkeys # -def register(): - for cls in classes: - bpy.utils.register_class(cls) - - -# Unregister Classes & Hotkeys # -def unregister(): - - for cls in reversed(classes): - bpy.utils.unregister_class(cls) - - -if __name__ == "__main__": - register() diff --git a/space_view3d_spacebar_menu/snap_origin_cursor.py b/space_view3d_spacebar_menu/snap_origin_cursor.py index 886f5546..b35bd976 100644 --- a/space_view3d_spacebar_menu/snap_origin_cursor.py +++ b/space_view3d_spacebar_menu/snap_origin_cursor.py @@ -20,114 +20,114 @@ import bpy from bpy.types import ( - Operator, - Menu, - ) + Operator, + Menu, + ) from bpy.props import ( - BoolProperty, - StringProperty, - ) + BoolProperty, + StringProperty, + ) from .object_menus import * # ********** Object Snap Cursor ********** class VIEW3D_MT_Snap_Context(Menu): - bl_label = "Snapping" + bl_label = "Snapping" - def draw(self, context): - layout = self.layout - toolsettings = context.tool_settings - layout.prop(toolsettings, "use_snap") - layout.prop(toolsettings, "snap_elements", expand=True) + def draw(self, context): + layout = self.layout + toolsettings = context.tool_settings + layout.prop(toolsettings, "use_snap") + layout.prop(toolsettings, "snap_elements", expand=True) class VIEW3D_MT_Snap_Origin(Menu): - bl_label = "Snap Origin" - - def draw(self, context): - layout = self.layout - layout.operator_context = 'EXEC_AREA' - layout.operator("object.origin_set", - text="Geometry to Origin").type = 'GEOMETRY_ORIGIN' - layout.separator() - layout.operator("object.origin_set", - text="Origin to Geometry").type = 'ORIGIN_GEOMETRY' - layout.operator("object.origin_set", - text="Origin to 3D Cursor").type = 'ORIGIN_CURSOR' - layout.operator("object.origin_set", - text="Origin to Center of Mass").type = 'ORIGIN_CENTER_OF_MASS' + bl_label = "Snap Origin" + + def draw(self, context): + layout = self.layout + layout.operator_context = 'EXEC_AREA' + layout.operator("object.origin_set", + text="Geometry to Origin").type = 'GEOMETRY_ORIGIN' + layout.separator() + layout.operator("object.origin_set", + text="Origin to Geometry").type = 'ORIGIN_GEOMETRY' + layout.operator("object.origin_set", + text="Origin to 3D Cursor").type = 'ORIGIN_CURSOR' + layout.operator("object.origin_set", + text="Origin to Center of Mass").type = 'ORIGIN_CENTER_OF_MASS' class VIEW3D_MT_CursorMenu(Menu): - bl_label = "Snap" - - def draw(self, context): - layout = self.layout - layout.operator_context = 'INVOKE_REGION_WIN' - layout.menu("VIEW3D_MT_Snap_Origin") - layout.menu("VIEW3D_MT_Snap_Context") - layout.separator() - layout.operator("view3d.snap_cursor_to_selected", - text="Cursor to Selected") - layout.operator("view3d.snap_cursor_to_center", - text="Cursor to World Origin") - layout.operator("view3d.snap_cursor_to_grid", - text="Cursor to Grid") - layout.operator("view3d.snap_cursor_to_active", - text="Cursor to Active") - layout.separator() - layout.operator("view3d.snap_selected_to_cursor", - text="Selection to Cursor").use_offset = False - layout.operator("view3d.snap_selected_to_cursor", - text="Selection to Cursor (Keep Offset)").use_offset = True - layout.operator("view3d.snap_selected_to_grid", - text="Selection to Grid") - layout.operator("view3d.snap_cursor_selected_to_center", - text="Selection and Cursor to World Origin") + bl_label = "Snap To" + + def draw(self, context): + layout = self.layout + layout.operator_context = 'INVOKE_REGION_WIN' + layout.menu("VIEW3D_MT_Snap_Origin") + layout.menu("VIEW3D_MT_Snap_Context") + layout.separator() + layout.operator("view3d.snap_cursor_to_selected", + text="Cursor to Selected") + layout.operator("view3d.snap_cursor_to_center", + text="Cursor to World Origin") + layout.operator("view3d.snap_cursor_to_grid", + text="Cursor to Grid") + layout.operator("view3d.snap_cursor_to_active", + text="Cursor to Active") + layout.separator() + layout.operator("view3d.snap_selected_to_cursor", + text="Selection to Cursor").use_offset = False + layout.operator("view3d.snap_selected_to_cursor", + text="Selection to Cursor (Keep Offset)").use_offset = True + layout.operator("view3d.snap_selected_to_grid", + text="Selection to Grid") + layout.operator("view3d.snap_cursor_selected_to_center", + text="Selection and Cursor to World Origin") class VIEW3D_MT_CursorMenuLite(Menu): - bl_label = "Snap Cursor" - - def draw(self, context): - layout = self.layout - layout.operator_context = 'INVOKE_REGION_WIN' - layout.menu("VIEW3D_MT_Snap_Origin") - layout.separator() - layout.operator("view3d.snap_cursor_to_selected", - text="Cursor to Selected") - layout.operator("view3d.snap_cursor_to_center", - text="Cursor to World Origin") - layout.operator("view3d.snap_cursor_to_grid", - text="Cursor to Grid") - layout.operator("view3d.snap_cursor_to_active", - text="Cursor to Active") - layout.separator() - layout.operator("view3d.snap_selected_to_cursor", - text="Selection to Cursor").use_offset = False - layout.operator("view3d.snap_selected_to_cursor", - text="Selection to Cursor (Keep Offset)").use_offset = True - layout.operator("view3d.snap_selected_to_grid", - text="Selection to Grid") - layout.operator("view3d.snap_cursor_selected_to_center", - text="Selection and Cursor to World Origin") + bl_label = "Snap to" + + def draw(self, context): + layout = self.layout + layout.operator_context = 'INVOKE_REGION_WIN' + layout.menu("VIEW3D_MT_Snap_Origin") + layout.separator() + layout.operator("view3d.snap_cursor_to_selected", + text="Cursor to Selected") + layout.operator("view3d.snap_cursor_to_center", + text="Cursor to World Origin") + layout.operator("view3d.snap_cursor_to_grid", + text="Cursor to Grid") + layout.operator("view3d.snap_cursor_to_active", + text="Cursor to Active") + layout.separator() + layout.operator("view3d.snap_selected_to_cursor", + text="Selection to Cursor").use_offset = False + layout.operator("view3d.snap_selected_to_cursor", + text="Selection to Cursor (Keep Offset)").use_offset = True + layout.operator("view3d.snap_selected_to_grid", + text="Selection to Grid") + layout.operator("view3d.snap_cursor_selected_to_center", + text="Selection and Cursor to World Origin") # Code thanks to Isaac Weaver (wisaac) D1963 class VIEW3D_OT_SnapCursSelToCenter(Operator): - bl_idname = "view3d.snap_cursor_selected_to_center" - bl_label = "Snap Cursor & Selection to World Origin" - bl_description = ("Snap 3D cursor and selected objects to the center \n" - "Works only in Object Mode") + bl_idname = "view3d.snap_cursor_selected_to_center" + bl_label = "Snap Cursor & Selection to World Origin" + bl_description = ("Snap 3D cursor and selected objects to the center \n" + "Works only in Object Mode") - @classmethod - def poll(cls, context): - return (context.area.type == "VIEW_3D" and context.mode == "OBJECT") + @classmethod + def poll(cls, context): + return (context.area.type == "VIEW_3D" and context.mode == "OBJECT") - def execute(self, context): - context.scene.cursor.location = (0, 0, 0) - for obj in context.selected_objects: - obj.location = (0, 0, 0) - return {'FINISHED'} + def execute(self, context): + context.scene.cursor.location = (0, 0, 0) + for obj in context.selected_objects: + obj.location = (0, 0, 0) + return {'FINISHED'} # Cursor Edge Intersection Defs # @@ -239,32 +239,64 @@ class VIEW3D_OT_SetOriginToSelected(Operator): return {'FINISHED'} +# ********** Edit Mesh Cursor ********** +class VIEW3D_MT_EditCursorMenu(Menu): + bl_label = "Snap To" + + def draw(self, context): + layout = self.layout + layout.operator_context = 'INVOKE_REGION_WIN' + layout.operator("object.setorigintoselected", + text="Origin to Selected V/F/E") + layout.separator() + layout.menu("VIEW3D_MT_Snap_Origin") + layout.menu("VIEW3D_MT_Snap_Context") + layout.separator() + layout.operator("view3d.snap_cursor_to_selected", + text="Cursor to Selected") + layout.operator("view3d.snap_cursor_to_center", + text="Cursor to World Origin") + layout.operator("view3d.snap_cursor_to_grid", + text="Cursor to Grid") + layout.operator("view3d.snap_cursor_to_active", + text="Cursor to Active") + layout.operator("view3d.snap_cursor_to_edge_intersection", + text="Cursor to Edge Intersection") + layout.separator() + layout.operator("view3d.snap_selected_to_cursor", + text="Selection to Cursor").use_offset = False + layout.operator("view3d.snap_selected_to_cursor", + text="Selection to Cursor (Keep Offset)").use_offset = True + layout.operator("view3d.snap_selected_to_grid", + text="Selection to Grid") + # List The Classes # classes = ( - VIEW3D_MT_CursorMenu, - VIEW3D_MT_CursorMenuLite, - VIEW3D_MT_Snap_Context, - VIEW3D_MT_Snap_Origin, - VIEW3D_OT_SnapCursSelToCenter, - VIEW3D_OT_CursorToEdgeIntersection, - VIEW3D_OT_SetOriginToSelected, + VIEW3D_MT_CursorMenu, + VIEW3D_MT_CursorMenuLite, + VIEW3D_MT_Snap_Context, + VIEW3D_MT_Snap_Origin, + VIEW3D_OT_SnapCursSelToCenter, + VIEW3D_OT_CursorToEdgeIntersection, + VIEW3D_OT_SetOriginToSelected, + VIEW3D_MT_EditCursorMenu, ) # Register Classes & Hotkeys # def register(): - for cls in classes: - bpy.utils.register_class(cls) + for cls in classes: + bpy.utils.register_class(cls) # Unregister Classes & Hotkeys # def unregister(): - for cls in reversed(classes): - bpy.utils.unregister_class(cls) + for cls in reversed(classes): + bpy.utils.unregister_class(cls) if __name__ == "__main__": - register() + register() diff --git a/space_view3d_spacebar_menu/transform_menus.py b/space_view3d_spacebar_menu/transform_menus.py index 914bdf4c..a6438bd9 100644 --- a/space_view3d_spacebar_menu/transform_menus.py +++ b/space_view3d_spacebar_menu/transform_menus.py @@ -74,7 +74,11 @@ class VIEW3D_MT_TransformMenuLite(Menu): layout.separator() layout.operator("transform.transform", text="Align to Transform Orientation").mode = 'ALIGN' - + layout.separator() + layout.operator("object.align") + layout.operator_context = 'EXEC_REGION_WIN' + layout.operator("transform.transform", + text="Align to Transform Orientation").mode = 'ALIGN' # ********** Transform Camera ********** class VIEW3D_MT_TransformMenuCamera(Menu): @@ -118,61 +122,11 @@ class VIEW3D_MT_TransformMenuArmature(Menu): text="Origin to Center of Mass").type = 'ORIGIN_CENTER_OF_MASS' -# ********** Transform Armature Edit ********** -class VIEW3D_MT_TransformMenuArmatureEdit(Menu): - bl_label = "Transform" - - def draw(self, context): - layout = self.layout - layout.operator("transform.translate", text="Move") - layout.operator("transform.rotate", text="Rotate") - layout.operator("transform.resize", text="Scale") - layout.separator() - layout.operator("transform.tosphere", text="To Sphere") - layout.operator("transform.shear", text="Shear") - layout.operator("transform.bend", text="Bend") - layout.operator("transform.push_pull", text="Push/Pull") - layout.operator("transform.vertex_warp", text="Warp") - layout.separator() - layout.operator("transform.vertex_random", text="Randomize") - layout.operator("armature.align") - layout.operator_context = 'EXEC_AREA' - - -# ********** Transform Armature Pose ********** -class VIEW3D_MT_TransformMenuArmaturePose(Menu): - bl_label = "Transform" - - def draw(self, context): - layout = self.layout - layout.operator("transform.translate", text="Move") - layout.operator("transform.rotate", text="Rotate") - layout.operator("transform.resize", text="Scale") - layout.separator() - layout.operator("pose.transforms_clear", text="Clear All") - layout.operator("pose.loc_clear", text="Location") - layout.operator("pose.rot_clear", text="Rotation") - layout.operator("pose.scale_clear", text="Scale") - - layout.separator() - - layout.operator("pose.user_transforms_clear", text="Reset unkeyed") - obj = context.object - if obj.type == 'ARMATURE' and obj.mode in {'EDIT', 'POSE'}: - if obj.data.display_type == 'BBONE': - layout.operator("transform.transform", text="Scale BBone").mode = 'BONE_SIZE' - elif obj.data.display_type == 'ENVELOPE': - layout.operator("transform.transform", text="Scale Envelope Distance").mode = 'BONE_SIZE' - layout.operator("transform.transform", text="Scale Radius").mode = 'BONE_ENVELOPE' - - # List The Classes # classes = ( VIEW3D_MT_TransformMenu, VIEW3D_MT_TransformMenuArmature, - VIEW3D_MT_TransformMenuArmatureEdit, - VIEW3D_MT_TransformMenuArmaturePose, VIEW3D_MT_TransformMenuLite, VIEW3D_MT_TransformMenuCamera, ) diff --git a/space_view3d_spacebar_menu/view_menus.py b/space_view3d_spacebar_menu/view_menus.py index 107d6da3..fa959f04 100644 --- a/space_view3d_spacebar_menu/view_menus.py +++ b/space_view3d_spacebar_menu/view_menus.py @@ -28,8 +28,46 @@ from bpy.props import ( StringProperty, ) +from . edit_mesh import * # View Menu's # +class VIEW3D_MT_View_Menu(Menu): + bl_label = "View" + + def draw(self, context): + layout = self.layout + view = context.space_data + + layout.menu("VIEW3D_MT_view_viewpoint") + layout.menu("VIEW3D_MT_view_align") + layout.menu("VIEW3D_MT_view_navigation") + layout.menu("INFO_MT_area") + layout.operator_context = 'INVOKE_REGION_WIN' + layout.menu("VIEW3D_MT_view_regions", text="View Regions") + layout.menu("VIEW3D_MT_Shade") + layout.separator() + + layout.operator("view3d.view_selected", text="Frame Selected").use_all_regions = False + if view.region_quadviews: + layout.operator("view3d.view_selected", text="Frame Selected (Quad View)").use_all_regions = True + layout.operator("view3d.view_all", text="Frame All").center = False + layout.separator() + + layout.operator("view3d.view_persportho", text="Perspective/Orthographic") + layout.menu("VIEW3D_MT_view_local") + layout.separator() + + layout.operator("render.opengl", text="Viewport Render Image", icon='RENDER_STILL') + layout.operator("render.opengl", text="Viewport Render Animation", icon='RENDER_ANIMATION').animation = True + layout.separator() + + layout.prop(view, "show_region_toolbar") + layout.prop(view, "show_region_ui") + layout.prop(view, "show_region_tool_header") + layout.prop(view, "show_region_hud") + + + # Display Wire (Thanks to marvin.k.breuer) # class VIEW3D_OT_Display_Wire_All(Operator): bl_label = "Wire on All Objects" @@ -81,9 +119,6 @@ class VIEW3D_MT_Shade(Menu): layout.separator() layout.operator("view3d.display_wire_all", text="Wire all", icon='SHADING_WIRE') - layout.separator() - layout.prop(context.space_data.fx_settings, "use_ssao", - text="Ambient Occlusion", icon="GROUP") # layout.prop(context.space_data, "use_matcap", icon="MATCAP_01") # if context.space_data.use_matcap: @@ -100,6 +135,7 @@ def menu_func(self, context): classes = ( VIEW3D_MT_Shade, VIEW3D_OT_Display_Wire_All, + VIEW3D_MT_View_Menu ) @@ -108,14 +144,12 @@ def register(): for cls in classes: bpy.utils.register_class(cls) - bpy.types.VIEW3D_MT_view.append(menu_func) # Unregister Classes & Hotkeys # def unregister(): for cls in reversed(classes): bpy.utils.unregister_class(cls) - bpy.types.VIEW3D_MT_view.remove(menu_func) if __name__ == "__main__": register() |