Sorting cloner each n frame
-
Yup it's a subject that comes up every few years. I've read this post https://developers.maxon.net/forum/topic/343
The last code by supergeordie seems to do what I need (change the sorting every 72 frames - I have about 100k unique combinations of the cloner I need to have which has to be done autoamtically)The problem with that code is that it's written in Python2 so it doesn't work with the new versions of c4d. As I'm completely ignorant when it comes to Python (never touched it) but need to solve this issue, I wonder...
- What do I actually need to change in that code to fit Python3
- Are there any updated ways to approach this that are cleaner, more efficient, etc?
Thanks!
-
Replace xrange by range, you can also follow Python 3 Migration Guideline.
Cheers,
Maxime. -
@m_adam thanks !
So I changed xrange to range but there's still some issues I can't seem to figure out
Here's the code I'm usingimport c4d, math, random, pip._internal.utils.misc from c4d.modules import mograph as mo from c4d import Vector as v, utils as u, Matrix as m from pip._internal.utils.misc import * from math import * TWOPI = pi*2 def my_shuffle(array): random.shuffle(array) return array def main(): md = mo.GeGetMoData(op) if md is None: return False cnt = md.GetCount() indarr = md.GetArray(c4d.MODATA_ALT_INDEX) marr = md.GetArray(c4d.MODATA_MATRIX) fall = md.GetFalloffs() frame = doc.GetTime().GetFrame(doc.GetFps()) if frame == 0 or -1 in indarr : indarr = range(cnt) if frame % 30 == 0: my_shuffle(indarr) md.SetArray(c4d.MODATA_ALT_INDEX, indarr, True) positions = [] for i in range(cnt): index = indarr[i] positions.append(marr[index].off) for i in range(cnt): marr[i].off = positions[i] print (indarr) md.SetArray(c4d.MODATA_MATRIX, marr, True) return True
Nothing happens when I execute and hit play, and this is what the console says:
Traceback (most recent call last): File "<Python>", line 29, in main File "<Python>", line 11, in my_shuffle File "C:\Program Files\Maxon Cinema 4D R24\resource\modules\python\libs\python39.win64.framework\lib\random.py", line 362, in shuffle x[i], x[j] = x[j], x[i] TypeError: 'range' object does not support item assignment
it also types "range(0, 4)" a whole bunch of times
I know it might be the easiest or most obvious thing but I really feel like I'm so ignorant when it comes to anything code.
Hopefully there's an easy fix I'm missing.
Thanks! -
Here the adapted code
import c4d, math, random from c4d.modules import mograph as mo from c4d import Vector as v, utils as u, Matrix as m from math import * TWOPI = pi*2 def my_shuffle(array): random.shuffle(array) return array def main(): md = mo.GeGetMoData(op) if md is None: return False cnt = md.GetCount() indarr = md.GetArray(c4d.MODATA_ALT_INDEX) marr = md.GetArray(c4d.MODATA_MATRIX) fall = md.GetFalloffs() frame = doc.GetTime().GetFrame(doc.GetFps()) if frame == 0 or -1 in indarr : indarr = list(range(cnt)) if frame % 30 == 0: my_shuffle(indarr) md.SetArray(c4d.MODATA_ALT_INDEX, indarr, True) positions = [] for i in range(cnt): index = indarr[i] positions.append(marr[index].off) for i in range(cnt): marr[i].off = positions[i] md.SetArray(c4d.MODATA_MATRIX, marr, True) return True
Cheers,
Maxime. -
Thank you so much for going over it adam
I tried this code but it doesnt seem to work, i added the "print (indarr)" line and the console just says "[0, 1, 2, 3]" over and over so it doesnt seem to randomize the order.Is there a reason you took down the PIP_utils line? It doesn't help with randomziing the order in anyway?
-
Hi sorry the code need to be adapted to support properly fields.
And I removed pip._internal.utils.misc because it's an external package (so not there by default) and is not used in the script.
import c4d, math, random from c4d.modules import mograph as mo from c4d import Vector as v, utils as u, Matrix as m from math import * TWOPI = pi*2 def my_shuffle(array): random.shuffle(array) return array def main(): md = mo.GeGetMoData(op) if md is None: return False cnt = md.GetCount() indarr = md.GetArray(c4d.MODATA_ALT_INDEX) marr = md.GetArray(c4d.MODATA_MATRIX) hasField = op[c4d.FIELDS].HasContent() frame = doc.GetTime().GetFrame(doc.GetFps()) if frame == 0 or -1 in indarr : indarr = list(range(cnt)) if frame % 30 == 0: my_shuffle(indarr) md.SetArray(c4d.MODATA_ALT_INDEX, indarr, hasField) positions = [] for i in range(cnt): index = indarr[i] positions.append(marr[index].off) for i in range(cnt): marr[i].off = positions[i] md.SetArray(c4d.MODATA_MATRIX, marr, hasField) return True
Cheers,
Maxime. -
Hello @Jengo,
without any further questions or replies, we will consider this thread as solved by Monday the 20th and flag it accordingly.
Thank you for your understanding,
Ferdinand