1

I just want to add custom addon to this path Edit Mode > Mesh > Sort Elements

enter image description here

I tried to use all bpytypes but it seems there is no access to this menu!

bl_info = {
    "name": "New Object",
    "author": "Your Name Here",
    "version": (1, 0),
    "blender": (2, 80, 0),
    "location": "Edit Mode > Mesh > Sort Elements",
    "description": "Adds a new Mesh Object",
    "warning": "",
    "doc_url": "",
    "category": "Add Mesh",
}

import bpy from bpy.types import Operator from bpy.props import FloatVectorProperty from bpy_extras.object_utils import AddObjectHelper, object_data_add from mathutils import Vector

def add_object(self, context): scale_x = self.scale.x scale_y = self.scale.y

verts = [
    Vector((-1 * scale_x, 1 * scale_y, 0)),
    Vector((1 * scale_x, 1 * scale_y, 0)),
    Vector((1 * scale_x, -1 * scale_y, 0)),
    Vector((-1 * scale_x, -1 * scale_y, 0)),
]

edges = []
faces = [[0, 1, 2, 3]]

mesh = bpy.data.meshes.new(name="New Object Mesh")
mesh.from_pydata(verts, edges, faces)
# useful for development when the mesh may be invalid.
# mesh.validate(verbose=True)
object_data_add(context, mesh, operator=self)


class OBJECT_OT_add_object(Operator, AddObjectHelper): """Create a new Mesh Object""" bl_idname = "mesh.add_object" bl_label = "Add Mesh Object" bl_options = {'REGISTER', 'UNDO'}

scale: FloatVectorProperty(
    name="scale",
    default=(1.0, 1.0, 1.0),
    subtype='TRANSLATION',
    description="scaling",
)

def execute(self, context):

    add_object(self, context)

    return {'FINISHED'}


Registration

def add_object_button(self, context): self.layout.operator( OBJECT_OT_add_object.bl_idname, text="Add Object", icon='PLUGIN')

This allows you to right click on a button and link to documentation

def add_object_manual_map(): url_manual_prefix = "https://docs.blender.org/manual/en/latest/" url_manual_mapping = ( ("bpy.ops.mesh.add_object", "scene_layout/object/types.html"), ) return url_manual_prefix, url_manual_mapping

def register(): bpy.utils.register_class(OBJECT_OT_add_object) bpy.utils.register_manual_map(add_object_manual_map)

# all edit_mesh types
bpy.types.VIEW3D_MT_edit_mesh.append(add_object_button)
bpy.types.VIEW3D_MT_edit_mesh_clean.append(add_object_button)
bpy.types.VIEW3D_MT_edit_mesh_context_menu.append(add_object_button)
bpy.types.VIEW3D_MT_edit_mesh_delete.append(add_object_button)
bpy.types.VIEW3D_MT_edit_mesh_edges.append(add_object_button)
bpy.types.VIEW3D_MT_edit_mesh_edges_data.append(add_object_button)
bpy.types.VIEW3D_MT_edit_mesh_extrude.append(add_object_button)
bpy.types.VIEW3D_MT_edit_mesh_faces.append(add_object_button)
bpy.types.VIEW3D_MT_edit_mesh_faces.append(add_object_button)
bpy.types.VIEW3D_MT_edit_mesh_merge.append(add_object_button)
bpy.types.VIEW3D_MT_edit_mesh_normals.append(add_object_button)
bpy.types.VIEW3D_MT_edit_mesh_normals_average.append(add_object_button)
bpy.types.VIEW3D_MT_edit_mesh_normals_select_strength.append(add_object_button)
bpy.types.VIEW3D_MT_edit_mesh_normals_set_strength.append(add_object_button)
bpy.types.VIEW3D_MT_edit_mesh_select_by_trait.append(add_object_button)
bpy.types.VIEW3D_MT_edit_mesh_select_linked.append(add_object_button)
bpy.types.VIEW3D_MT_edit_mesh_select_loops.append(add_object_button)
bpy.types.VIEW3D_MT_edit_mesh_select_mode.append(add_object_button)
bpy.types.VIEW3D_MT_edit_mesh_select_more_less.append(add_object_button)
bpy.types.VIEW3D_MT_edit_mesh_select_similar.append(add_object_button)
bpy.types.VIEW3D_MT_edit_mesh_shading.append(add_object_button)
bpy.types.VIEW3D_MT_edit_mesh_showhide.append(add_object_button)
bpy.types.VIEW3D_MT_edit_mesh_split.append(add_object_button)
bpy.types.VIEW3D_MT_edit_mesh_vertices.append(add_object_button)
bpy.types.VIEW3D_MT_edit_mesh_weights.append(add_object_button)


def unregister(): bpy.utils.unregister_class(OBJECT_OT_add_object) bpy.utils.unregister_manual_map(add_object_manual_map) bpy.types.VIEW3D_MT_edit_mesh_context_menu.remove(add_object_button) #bpy.ops.mesh.sort_elements(type='RANDOMIZE', elements={'VERT'})

if name == "main": register()

there is no bpy.types as VIEW3D_MT_edit_mesh_SortElements

  • 2
    https://blender.stackexchange.com/questions/182063/how-to-add-a-submenu-to-object-set-origin-in-blender-2-83/182082#182082 – batFINGER Aug 21 '20 at 10:12

2 Answers2

0

TL;DR: There is no such a menu. Append it into VIEW3D_MT_edit_mesh.


The sort element itself is an enumerated submenu, which are written in space_view3D.py at lines:: 3620 as following:

layout.operator_menu_enum("mesh.sort_elements", "type", text="Sort Elements...")

enter image description here

This will make a sub-menu to enumerate all possible type that "mesh.sort_elements" will contain, which is an EnumProperties. And since it is written in VIEW3D_MT_edit_mesh draw method, it's hard to inject any other menu into it. Especially it is a property from built-in operator.

You might need to directly deal with bpy.ops.mesh.sort_elements logic, or you will need to use the hacky method provided above to rewrite the enum submenu part of it. Both are not a good practice IMO and will make your addon looks dangerous.

HikariTW
  • 7,821
  • 2
  • 18
  • 37
0

this answer and this basic menu example helped me to add a custom sort to Sort Elements

import bpy
from bpy.props import EnumProperty
from mathutils import Vector, Matrix
import bmesh

def sequential_sort(): ob = bpy.context.object assert ob.type == "MESH" me = ob.data

bm = bmesh.from_edit_mesh(me)
v0 = bm.select_history.active
f = bmesh.ops.contextual_create(
        bm,
        geom=bm.verts[:] + bm.edges[:],
        )["faces"][0]

fverts = f.verts[:]

if f.normal.dot((0, 0, 1)) < 0:
    fverts.reverse()

for i, v in enumerate(fverts):
    v.index = i
    if v is v0:
        iv0 = i

for v in fverts:
    v.index = (v.index - iv0) % len(fverts) 

bm.verts.sort()

bm.faces.remove(f)

bmesh.update_edit_mesh(me) 



class SimpleOperator(bpy.types.Operator): """Tooltip""" bl_idname = "mesh.sort_elements" bl_label = "Simple Object Operator"

def items():
    items = []
    rna = bpy.ops.object.origin_set.get_rna_type()
    for i in rna.properties['type'].enum_items:
        items.append((i.identifier, i.name, i.description))
    items.append(('SEQUENTIAL_SORT', "Sequential Sort", "Sort Elements Sequentially"))
    return items

type : EnumProperty(items=items(), default='GEOMETRY_ORIGIN')

@classmethod
def poll(cls, context):
    return context.active_object is not None

def execute(self, context):
    sequential_sort()
    return {'FINISHED'}

def draw_menu(self, context): self.layout.operator_menu_enum("mesh.sort_elements", "type", text="Sort Elements...")

def register(): #bpy.types.VIEW3D_MT_object.prepend(draw_menu) bpy.utils.register_class(SimpleOperator)

def unregister(): bpy.utils.unregister_class(SimpleOperator)

if name == "main": register()

  • @batFINGER I could add custom sort to SortElements menu but I couldn't add default enums. I tried to use this method rna = bpy.ops.mesh.sort_elements.get_rna_type() but it didn't work – Seyed Morteza Kamali Aug 21 '20 at 11:36
  • It "didn't work" because it requires a default that is in the list. Not 'GEOMETRY_ORIGIN`, which is the default for set origin op. Have made change to other to use the default as set in original operator. As commented in other answer: Will need to code for other options. – batFINGER Aug 22 '20 at 14:45