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:
- open rhino, no template
- run script to add event handler
- go to ‘file>open’ to load testfile2.3dm (388.3 KB)
- double click the block to open the block editor and close agiain => error is raised
steps to reproduce normal behavior
- open rhino
- open the model
- run the script to add event handler
- 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'