1
$\begingroup$

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?

$\endgroup$
1
  • $\begingroup$ Try bpy.context as a storage location. Say, bpy.context.mydata={} I’m not sure if this still works but afaik it did in blender game engine as of 2.79. $\endgroup$
    – TheLabCat
    May 11 at 1:57
0
$\begingroup$

The right answer is, that all tho code outside the OP stays "static". Running everything inside the OP solves the problem.

$\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.