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

Not the answer you're looking for? Browse other questions tagged .