Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware API
      • ZBrush GoZ API
      • Code Examples on Github
    • Forum
    • Downloads
    • Support
      • Support Procedures
      • Registered Developer Program
      • Plugin IDs
      • Contact Us
    • Categories
      • Overview
      • News & Information
      • Cinema 4D SDK Support
      • Cineware SDK Support
      • ZBrush 4D SDK Support
      • Bugs
      • General Talk
    • Unread
    • Recent
    • Tags
    • Users
    • Login

    Sorting cloner each n frame

    General Talk
    3
    7
    1.0k
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • J
      Jengo
      last edited by

      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...

      1. What do I actually need to change in that code to fit Python3
      2. Are there any updated ways to approach this that are cleaner, more efficient, etc?

      Thanks!

      1 Reply Last reply Reply Quote 0
      • M
        m_adam
        last edited by

        Replace xrange by range, you can also follow Python 3 Migration Guideline.

        Cheers,
        Maxime.

        MAXON SDK Specialist

        Development Blog, MAXON Registered Developer

        1 Reply Last reply Reply Quote 0
        • J
          Jengo
          last edited by

          @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 using

          import 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!

          1 Reply Last reply Reply Quote 0
          • M
            m_adam
            last edited by

            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.

            MAXON SDK Specialist

            Development Blog, MAXON Registered Developer

            1 Reply Last reply Reply Quote 0
            • J
              Jengo
              last edited by

              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?

              1 Reply Last reply Reply Quote 0
              • M
                m_adam
                last edited by m_adam

                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.

                MAXON SDK Specialist

                Development Blog, MAXON Registered Developer

                1 Reply Last reply Reply Quote 0
                • ferdinandF
                  ferdinand
                  last edited by

                  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

                  MAXON SDK Specialist
                  developers.maxon.net

                  1 Reply Last reply Reply Quote 0
                  • First post
                    Last post