as I'm pretty sure I found a way to achieve what I'm after I thought I update this thread. Maybe this will help others as well.
After taking some time to make
NodeData.CopyTo() work, I ended up not getting it to work at all.
So I thought about how I could achieve what I'm after a different way. Long story short, I ended up implementing a
MessageData plugin as some kind of watchdog for a document. Since its
CoreMessage runs on the main thread I can happily insert and delete materials as much as I wish to. (At least I'm hoping so )
The idea behind this goes as follows. I have a timer running and in addition to that I listen for
c4d.EVMSG_CHANGE and do some checking to see if the scene needs to update. In my case it's comparing the amount of a specific object against the amount of "specific" materials. If there's a difference I use that difference to delete or insert materials until there's no difference. Once there's no difference I can assign the materials to the objects and let each object control its own material.
To distinguish between materials responsible for my plugin and the ones that aren't I make sure to put a unique plugin id inside the base container of the material I can then check for.
Here's a code snippet of that
PLUGIN_ID = "Use your own unique one"
PLUGIN_NAME = "A MessageData plugin."
PLUGIN_INFO = 0
self._time = 1000
def SetTimer(self, time):
self._time = time
is_mainthread = c4d.threading.GeIsMainThread()
check_running = (
is_running = any(item is True for item in check_running)
return is_mainthread and not is_running
def CoreMessage(self, mid, mdata):
if not self.should_execute:
doc = c4d.documents.GetActiveDocument()
# SceneHandler is a custom class I delegate the whole creation and comparing stuff to.
objs, mats = ..., ...
scene = SceneHandler(objs, mats)
# Check for a change and start the timer again. But only if the scene should update. Otherwise the timer would run all the time.
if mid == c4d.EVMSG_CHANGE:
# If we get a timer event we update the scene as long as it shouldn't update anymore. We can then stop the timer.
if mid == c4d.MSG_TIMER:
if not scene.should_update:
Maybe this will help others. Since I found a solution for my problem this thread can be marked solved.