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$ Commented May 11, 2021 at 1:57

1 Answer 1

0
$\begingroup$

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

$\endgroup$

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.