For the generator bit, this can be somehow done via
import c4d
def message(msgType, data):
if msgType == c4d.MSG_NOTIFY_EVENT:
if data["event_data"]["msg_id"] == c4d.MSG_DEFORMMODECHANGED:
print(data)
def main():
obj = doc.GetFirstObject()
if not obj.FindEventNotification(doc, op, c4d.NOTIFY_EVENT_MESSAGE):
obj.AddEventNotification(op, c4d.NOTIFY_EVENT_MESSAGE , 0, c4d.BaseContainer())
if __name__=='__main__':
main()
The main issue is it's triggered only after an EventAdd so this means most of the time you will not get the change immediately.
Regarding the visibility, this is unfortunately not possible, since SetEditorMode/SetRenderMode only do a SetDirty(DIRTYFLAGS::MATRIX) internally. And the dirty state is not monitored by the Event Notification system.
One side note it's possible to use MSG_DESCRIPTION_POSTSETPARAMETER
like in the snippet bellow, but this message is sent by the Attribute Manager when a parameter is set, so that means if you change the value within the Attribute Manager of the Editor display mode, the change will be monitored, but if you change the mode via the Object Manager, which directly use SetEditorMode, then the message is not sent.
import c4d
def message(msgType, data):
if msgType == c4d.MSG_NOTIFY_EVENT:
if data["event_data"]["msg_id"] == c4d.MSG_DESCRIPTION_POSTSETPARAMETER:
if data["event_data"]["msg_data"]["descid"] == c4d.DescID(c4d.ID_BASEOBJECT_VISIBILITY_EDITOR):
print("changed editor")
elif data["event_data"]["msg_data"]["descid"] == c4d.DescID(c4d.ID_BASEOBJECT_VISIBILITY_RENDER):
print("changed render")
elif data["event_data"]["msg_data"]["descid"] == c4d.DescID(c4d.ID_BASEOBJECT_GENERATOR_FLAG):
print("changed generator")
def main():
obj = doc.GetFirstObject()
if not obj.FindEventNotification(doc, op, c4d.NOTIFY_EVENT_MESSAGE):
obj.AddEventNotification(op, c4d.NOTIFY_EVENT_MESSAGE , 0, c4d.BaseContainer())
if __name__=='__main__':
main()
Cheers,
Maxime.