1
$\begingroup$

I am recently learning to extend blender and trying to create a custom utilities panel.

I'm trying to add a "merge vertices" button on a panel but I keep getting errors saying;

enum 'FIRST' not found in ('CENTER', 'CURSOR', 'COLLAPSE')

Any solutions to this?

Also, any tips regarding convention and styling is welcome :)

Thanks in advance

enter image description here


Many thanks to batFINGERS answer, I ended up going with the try/ except method. I then changed the code and now it works like a charm

row = layout.row(align=True)            
for k in ['FIRST', 'LAST']:                
    try:
        row.operator("mesh.merge", text=k.title(), icon="GROUP_VERTEX").type = k
    except TypeError:
        row.enabled = False
row = layout.row()
row.operator('mesh.remove_doubles', text='Distance', icon='DRIVER_DISTANCE').threshold = 0.01

which ends up like this and is exactly what I wanted.

enter image description here

$\endgroup$
1
$\begingroup$

The type enum property items for the operator is populated based on selection.

enter image description here

The type enum is an example of a dynamic enum that is populated dependant on selection.

As mentioned in my answer to this related question Add shortcut for Merge Last, and Merge First if you use col.operator_enum("mesh.merge", "type") you get the available options.

import bpy

class MESH_PT_merge2(bpy.types.Panel):
    """Merge Panel in Mesh Tools"""
    bl_label = "Merge"
    bl_idname = "MESH_PT_merge2"
    bl_space_type = 'VIEW_3D'
    bl_region_type = 'UI'
    #bl_category = "Tools"

    @classmethod
    def poll(self, context):
        return context.mode == 'EDIT_MESH'

    def draw(self, context):
        layout = self.layout
        col = layout.column()
        col.operator_enum("mesh.merge", "type")

def register():
    bpy.utils.register_class(MESH_PT_merge2)

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

if __name__ == "__main__":
    register()

I would like only the "At First, At Last, and Distance" buttons to be visible

Speculatively it looks like first and last options require vertex select mode and at least one vertex selected. An edit bmesh could be used to test, depending on your use case. this is probably overkill.

A try and except clause, except I generally recommend try to avoid these if possible. In this case the error is thrown after the UI draws the button before the type property is assigned, hence I've disabled.

    for k in ['FIRST', 'LAST']:
        row = col.row()
        try:
            row.operator("mesh.merge", text=k.title()).type = k
        except TypeError:
            row.enabled = False

Lastly, to get all the items possible in an operator enum

>>> rna = bpy.ops.mesh.merge.get_rna_type()
>>> rna.properties['type'].enum_items.keys()
['FIRST', 'LAST', 'CENTER', 'CURSOR', 'COLLAPSE']
| improve this answer | |
$\endgroup$
  • $\begingroup$ Thanks a lot, I ended up going with this solution for now. Is there a possibility of excluding the collapse button? I would like only the "At First, At Last, and Distance" buttons to be visible. $\endgroup$ – Ian Dela Cruz Dec 1 '19 at 9:41
  • $\begingroup$ Edited answer. I believe distance is mesh.remove_doubles $\endgroup$ – batFINGER Dec 1 '19 at 10:53
0
$\begingroup$

Make sure you are using the right version of Blender that has those options.

You can see the options in the error below.

bpy.ops.mesh.merge(type='PRINT_ERROR')

TypeError: Converting py args to operator properties:  enum "PRINT_ERROR" not found in ('FIRST', 'LAST', 'CENTER', 'CURSOR', 'COLLAPSE')

Your error shows only 'CENTER', 'CURSOR' and 'COLLAPSE' for the merge type. That's why you get that error when you try to use the FIRST and LAST options.

| improve this answer | |
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.