Hello guys, it it possible to detect button states using python?
What I’m looking for in particular is the state of bpy.ops.mesh.select_mode whether its (type=‘VERT’)/ (type=‘EDGE’)/ (type=‘FACE’). I’m new to scripting in blender using python but I do understand maxscript for 3ds max.
What I did typically in maxscript would be checking subobjectlevel == 1(vertex)/ 2(edge)/ 4(face), but in blender it seems like it working slightly different, since there is no states of sub-object level in blender that I’m aware of, it even possible to activate all 3 of them (but I want to check the state either 1 of the 3 is active).
You can read the mesh select mode from bpy.context.tool_settings.mesh_select_mode (tuple of 3 booleans) and also set it. Not sure what you wanna do with the operator.
Hi man, thanks for the reply. Yeah, it kinda works if I assign the 3 tupples into that, but I can’t seems to be able to check the state with if-statement. Running this simply always return false.
if bpy.context.tool_settings.mesh_select_mode == (True, False, False):
print("OK")
What I want to do with this is I’m trying to write a smart function that combine few hotkeys into one depends on what mode I’m in. So what’s wrong with the above statement?
Alright! I think I figure it out, after more search on google and I come out with this toolSettings.mesh_select_mode[]
A small example of what I had in mind:
So this kind of smart function that I try to adapt in blender from my maxscript setup. Basically using similar hotkey to perform similar task based on what mode we are working right now. So in my case I will map the script into “C”, so when I press C on vertex mode, it’ll connect verts, C on edge mode it’ll subdivide the edges (in 3ds max it’s still called connect edges, instead of subdivide edges), C on face mode it’ll bridge those faces. So for me “C” key is for all creation (create a new edge by connecting face/ edge, create new face by bridging faces/etc).
…ok, so now I need to find a way where should I place the script and how to assign to a hotkey, haha!
Hey man thanks for the link! after reading few documents, I’ve manage to assing a hotkey to my script.
So here it is what I got so far, pretty much complete in what i initially wanted it to do.
bl_info = \
{
"name": "Create Smart",
"description": "Smart Function: Create",
"author": "Wahyu Nugraha (Revel)",
"category": "_Smart"
}
import bpy
import bmesh
class create_smart(bpy.types.Operator):
"""Smart Function: Create"""
bl_idname = "_smart.create_smart"
bl_label = "Create Smart"
bl_options = {'REGISTER', 'UNDO'}
def execute(self, context):
# ---------------------- #
# --- INIT VARIABLES --- #
# ---------------------- #
obj = bpy.context.active_object
bm = bmesh.from_edit_mesh(obj.data)
toolSettings = bpy.context.tool_settings
toolOps = bpy.ops
if bpy.context.mode == 'EDIT_MESH':
verts = [v.index for v in bm.verts if v.select == True]
edges = [e.index for e in bm.edges if e.select == True]
faces = [f.index for f in bm.faces if f.select == True]
# ----------------------- #
# --- SMART FUNCTIONS --- #
# ----------------------- #
# vertex mode
if toolSettings.mesh_select_mode[0]:
if len(verts) <= 1:
toolOps.mesh.dupli_extrude_cursor('INVOKE_DEFAULT')
else:
vSel = verts
vFloating = False
fElm = []
# check whether it's a floating verts or not
toolOps.mesh.select_linked()
for f in [f.index for f in bm.faces if f.select == True]:
fElm.append(f)
if len(fElm) == 0:
vFloating = True
else:
vFloating = False
toolOps.mesh.select_all(action='DESELECT')
for v in vSel:
bm.verts[v].select = True
# operation
if vFloating == True:
toolOps.mesh.edge_face_add()
else:
toolOps.mesh.vert_connect()
# edge mode
elif toolSettings.mesh_select_mode[1]:
if len(edges) == 0:
toolOps.mesh.loopcut_slide('INVOKE_DEFAULT')
else:
eSel = edges
eBound = []
selBound = []
# get edge boundary
toolOps.mesh.select_all(action='DESELECT')
toolOps.mesh.select_non_manifold(use_boundary=True)
for e in [e.index for e in bm.edges if e.select == True]:
eBound.append(e)
for e in set(eSel).intersection(set(eBound)):
selBound.append(e)
toolOps.mesh.select_all(action='DESELECT')
for e in eSel:
bm.edges[e].select = True
# sorted index
eSel = sorted(eSel)
eBound = sorted(eBound)
selBound = sorted(selBound)
# operation
if eSel == selBound:
try:
toolOps.mesh.bridge_edge_loops()
except RuntimeError:
toolOps.mesh.edge_face_add()
else:
toolOps.mesh.subdivide()
# face mode
elif toolSettings.mesh_select_mode[2]:
if len(faces) == 0:
toolOps.mesh.knife_tool('INVOKE_DEFAULT')
else:
try:
toolOps.mesh.bridge_edge_loops()
except RuntimeError:
pass
return {'FINISHED'}
def register():
bpy.utils.register_class(create_smart)
def unregister():
bpy.utils.unregister_class(create_smart)
if __name__ == "__main__":
register()
@CoDEmanX - I had abit of trouble getting loop cut and knife tool to work properly and keep on giving me “wm_operator_invoke” error for some reason, till I found your post to someone else’s thread suggesting to pu (‘INVOKE_DEFAULT’), and it did fix my problem as well. What does it do actually? Does it run the scrpt with all the default parameters? if so when do we need to use it? since some of the script with a blank () will run just fine.