I'm working on an addon changing selected verticies per keyboard. It collects data:
import bpy
import numpy as np
import bmesh
################ update scene ####################
bpy.context.view_layer.update()
layer = bpy.context.view_layer
layer.update()
oa = bpy.context.active_object
bm = bmesh.from_edit_mesh(oa.data) ## get active...
me = bpy.context.edit_object.data
bpy.ops.object.mode_set(mode='EDIT')
############### active vtx idx ###################
def bmesh_vert_active(bm):
if bm.select_history:
elem = bm.select_history[-1]
if isinstance(elem, bmesh.types.BMVert):
return elem
return None
avtidx = bmesh_vert_active(bm)
if avtidx != None:
avtidx = bmesh_vert_active(bm).index
#######################################################
bpy.ops.object.mode_set(mode='OBJECT') ## update selection
#######################################################
def get_co(oa):
count = len(oa.data.vertices)
co = np.empty(count * 3, dtype=np.float32)
oa.data.vertices.foreach_get("co", co)
co.shape = (count, 3)
return co
def get_ix(oa):
count = len(oa.data.vertices)
ix = np.empty(count, dtype=np.int32) # check dtype!!!
oa.data.vertices.foreach_get("index", ix)
return ix
...then it calculates new selection from collected data:
def calc_north(ixT):
...
...finally the operator:
## deselect all components first
def dslct_all(oa):
setF = np.zeros(len(oa.data.polygons), dtype=np.bool)
setE = np.zeros(len(oa.data.edges), dtype=np.bool)
setV = np.zeros(len(oa.data.vertices), dtype=np.bool)
oa.data.polygons.foreach_set("select", setF.ravel())
oa.data.edges.foreach_set("select", setE.ravel())
oa.data.vertices.foreach_set("select", setV.ravel())
oa.data.update()
bpy.ops.object.mode_set(mode='EDIT')
### select activeVtx
def bmesh_actvvtx_set(me):
bm = bmesh.from_edit_mesh(me)
if hasattr(bm.verts, "ensure_lookup_table"):
bm.verts.ensure_lookup_table()
bm.select_history.add(bm.verts[avtx])
################### keymap #######################
## switch selected verts
class nKey(bpy.types.Operator):
'''up Arrow Key'''
bl_idname = "view_3d.print_uarrow"
bl_label = "print up arrow"
bl_options = {'REGISTER', 'UNDO'}
def execute(self, context):
return self.invoke(context, None)
def invoke(self, context, event):
bpy.ops.object.mode_set(mode='OBJECT')
jmpX = calc_north(ixT)
setSl = np.zeros(len(oa.data.vertices), dtype=np.bool)
setSl[jmpX] = 1
dslct_all(oa)
oa.data.vertices.foreach_set("select", setSl.ravel())
oa.data.update()
bpy.ops.object.mode_set(mode='EDIT')
if avtidx != None:
avtx = jmpX[avtidx][0] ## idx of activeVtx
bmesh_actvvtx_set(me)
return {'FINISHED'}
...
Everything works as expected but, only once! Surely it holds on to all variables, which leads to reselecting the same verticies ever and ever again. How can I feed the operator with updated input? I googled around for days. I couldn't find a solution, despite many attempts. The "update scene" part is one of them. How can I make this work repeatetly?