Issue:"ValueError:does not exist in ObjectTable" at InstanceDefTableEvent

Hi there,

I use the script below to check difference between Oldstate and NewState at Rhino.RhinoDoc.InstanceDefinitionTableEvent. When I first open the model and then run the script, everything works as expected.

When I first run the script an then open the model, I get below error:
ValueError: d51b7a42-ff67-4799-ac0f-31bf221d4e62 does not exist in ObjectTable

It is as if the objects are not loaded in the objectTable properly yet. However, I expect that even the first time the event is triggered, there is an object associated with all items in the list returned by e.OldState.GetObjectIds().

is there possibly some method to refresh the object table?

I hope you can help me out.
best regards,
Tim

steps to reproduce error:

  1. open rhino, no template
  2. run script to add event handler
  3. go to ‘file>open’ to load testfile2.3dm (388.3 KB)
  4. double click the block to open the block editor and close agiain => error is raised

steps to reproduce normal behavior

  1. open rhino
  2. open the model
  3. run the script to add event handler
  4. double click the block to open the block editor and close agiain to see if block objects have changed
import Rhino
import rhinoscriptsyntax as rs
import scriptcontext as sc
import traceback as tb

def group_by_type(items):
    grouped = {}
    for item in items:
        type = rs.ObjectType(item)
        if not type in grouped:
            grouped[type] = []
        grouped[type].append(item)
    return grouped


def find_equal(item, type, grouped_old):
    # go over old items and try to find a duplicate
    for itemB in list(grouped_old[type]):
        if rs.CompareGeometry(item, itemB):
            # remove item from old items to check, no need to check it again
            grouped_old[type].remove(itemB)
            return itemB

def has_changed(old, new):
    
    if len(old) == 0:
        print 'block loaded'
        return False
    
    if len(old) != len(new):
        print 'number of block objects has changed'
        return True
    
    # for each old object, check if an equal object exist in 'new' and vise versa
    grouped_old = group_by_type(old)
    
    new_types = {}
    for item in new:
        new_types[item] = rs.ObjectType(item)
    
    new_items_not_in_old = []
    old_with_equal = []
    for item, type in new_types.items():
        equal = find_equal(item, type, grouped_old)
        if equal:
            old_with_equal.append(equal)
            continue
                
        new_items_not_in_old.append(item)
        
    old_items_not_in_new = set(old) - set(old_with_equal)
    
    if len(new_items_not_in_old)>0 or len(old_items_not_in_new)>0:
        print 'block objects are different. %s in old but not in new, %s in new but not in old' % (len(new_items_not_in_old), len(old_items_not_in_new))
        return True
    
    
    return False
        

def AutoUpdateEvent(sender, e):
    try:
        # only change at 'Modified' event. Not at 'Added' event,
        if e.EventType == Rhino.DocObjects.Tables.InstanceDefinitionTableEventType.Modified:
            
            old = e.OldState.GetObjectIds()
            new = e.NewState.GetObjectIds()
            
            print has_changed(old, new)
                
    except Exception as exc:
        print 'error', exc
        print tb.format_exc()

if __name__ == '__main__':
    
    if sc.sticky.has_key('handler'):
        AutoUpdateEvent = sc.sticky['handler']
        Rhino.RhinoDoc.InstanceDefinitionTableEvent -= AutoUpdateEvent
        sc.sticky.Remove('handler')
        print 'handler removed'
    else:
        
        Rhino.RhinoDoc.InstanceDefinitionTableEvent += AutoUpdateEvent
        sc.sticky['handler'] = AutoUpdateEvent
        print 'handler added'