2
$\begingroup$

The enum function allows a button to toggle between two states. Is there a way to do that in code with a normal single button whose state is momentary? For example, I am trying to select faces of a model, then deselect with a standard button, not a toggle button.

I've only gotten a theoretical function:

for f in bm.faces: 
    if bm.faces[f.index].select == True:
        bm.faces[f.index].select = False
    else:
        bm.faces[f.index].select = True

This will test the first state, then the second which will make them both true. Is there a way to stop at the first state?

$\endgroup$
1
$\begingroup$

Pick the state to use before the loop.

set_state = bm.faces[0].select
for f in bm.faces:
    f.select = set_state

Note that within your loop f is the same as bm.faces[f.index]

Or if you want to loop through until you find the first selected, use break to stop the loop.

for f in bm.faces:
    print(f.index)
    if f.select:
        break

In blender's UI, pressing a button executes an operator. You can give an operator properties and set different values to be used when clicking each button in the UI. This also means you can have one button and choose which value it uses.

An operator with a boolean property -

class MySelector(bpy.types.Operator):
    bl_idname = 'mesh.my_select'
    bl_label = 'sample selecting'

    state = bpy.props.BoolProperty()

    def execute(self, context):
        obj = context.edit_object
        bm = bmesh.from_edit_mesh(obj.data)
        for f in bm.faces:
            f.select = self.state
        bmesh.update_edit_mesh(obj.data, True)

        return {'FINISHED'}

A panel to show the buttons -

class MySelectPanel(bpy.types.Panel):
    bl_idname = "OBJECT_PT_MySelector"
    bl_label = "Selecting"
    bl_space_type = 'VIEW_3D'
    bl_region_type = 'TOOLS'

    def draw(self, context):
        row = self.layout.row()
        row.operator(MySelector.bl_idname, text='Deselect').state = False
        row.operator(MySelector.bl_idname, text='Select').state = True

It is also possible to set multiple properties for one button

    b = row.operator(MySelector.bl_idname, text='Deselect')
    b.state = False
    b.value2 = 'Use this value'
$\endgroup$
1
  • $\begingroup$ OK sambler... you're a genius. $\endgroup$
    – ACopeLan
    May 1 '17 at 1:55

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.