Python effector get clones previous position



  • On 13/07/2018 at 09:53, xxxxxxxx wrote:

    I'm writing a python effector for a cloner and I need the clones velocity, which I could get from subtracting the clones last offset from it's current offset, however modata.GetArray(c4d.MODATA_LASTMAT) seems to always return a default matrix. How do I get the clones position on the previous frame?

    Any help or clues are greatly appreciated.



  • On 13/07/2018 at 15:29, xxxxxxxx wrote:

    I ended up writing the data to a hyperfile and reading it back in on the next frame. It seems a bit heavy handed, but it works. Let me know if you think of any better ways!



  • On 15/07/2018 at 04:01, xxxxxxxx wrote:

    can't test it right now but this should work:

      
    import c4d
    from c4d.modules import mograph as mo
      
    preMarr = []
      
    def main() :
        
        
        md = mo.GeGetMoData(op)
      
        if md is None: return False
        
        cnt = md.GetCount()
        marr = md.GetArray(c4d.MODATA_MATRIX)
      
        
        for i in reversed(xrange(0, cnt)) :
            if len(preMarr) == len(marr) :
                #DO WHAT YOUT WANT
                pass
                
            marr[i].off = marr[i].off+fall[cnt-i-1]*100.0
        
        md.SetArray(c4d.MODATA_MATRIX, marr, True)
        
        preMarr = list(marr)
        
        return True
      
    
    


  • On 16/07/2018 at 10:08, xxxxxxxx wrote:

    Nice! I have no idea why I didn't just put it into a global variable...

    For future readers the only tweak needed is to declare "global preMarr" in the main() function so that you can access and set the variable without getting an error.



  • On 17/07/2018 at 02:07, xxxxxxxx wrote:

    Hi CodySorgenfry.

    Sorry for the delay, first of all, I'm glad you found a workaround about it. But I would like to introduce you two more options.
    The first one, probably the cleanest one is to add a custom array with the previous data to mograph generator itself. It's better than using a global variable since, you can have multiple cloners using the same python effector, while the global variable will be global for each python effector.
    Here an example code.

    import c4d
    from c4d.modules import mograph as mo
    #Welcome to the world of Python
      
    def main() :
        MY_ARR_ID = 123456 # have a unique ID from Plugin Cafe
        md = mo.GeGetMoData(op)
        if md is None: return False
      
        # A proper DescID is needed for AddArray()
        # Especially set the correct data type here!
        did = c4d.DescID(c4d.DescLevel(MY_ARR_ID, c4d.DTYPE_MATRIX, 0))
      
        myArr = md.GetArray(MY_ARR_ID)
        if myArr is None: # check, if the array has already been added earlier on
            idxArr = md.AddArray(did, "my array", 0)
            if idxArr == c4d.NOTOK:
                print "Error" # handle error here
                return False
            
            # Finally fill the array with the current matrice
            marr = md.GetArray(c4d.MODATA_MATRIX)
            md.SetArray(MY_ARR_ID, marr, True)
            
        else:
            previousMarr = md.GetArray(MY_ARR_ID)
            marr = md.GetArray(c4d.MODATA_MATRIX)
            copyMarr = marr #copy the list in order tosave data before we do any move
            
            # Do your calculation
            fall = md.GetFalloffs()
            cnt = md.GetCount()
            for i in reversed(xrange(0, cnt)) :
                marr[i].off = marr[i].off+fall[cnt-i-1]*100.0
        
            # Set the array with the initial state + the new matrice
            md.SetArray(c4d.MODATA_MATRIX, marr, True)
            md.SetArray(MY_ARR_ID, copyMarr, True)
            
        return True
    

    Second one using HyperFile but also MemoryFileStruct which allow you to save the file in the memory which will be way more efficient than to save/read from the disk.

    And a final note all this technique only check for the previous execution, so most of the time the mograph is executed only once per frame, but is not always true.

    If you have any other question please let me know.
    Cheers,
    Maxime.



  • On 17/07/2018 at 11:15, xxxxxxxx wrote:

    Thanks Maxime, this is exactly what i'm looking for.

    I tried to implement this with your sample code, and md.GetArray(MY_ARR_ID) always returns none, how come it never gets set?



  • On 18/07/2018 at 02:02, xxxxxxxx wrote:

    Hi,

    What's your version of C4D and could you please share your full code, because here the script I posted is working nicely on R19.054

    Cheers,
    Maxime



  • On 18/07/2018 at 10:07, xxxxxxxx wrote:

    I'm using the exact code you posted (except with my plugin ID) for simplicity's sake.

    I restarted my computer and now the matrix exists, but doesn't get updated each time it runs, it's just stuck with the values it first got set with.

    I'm on R18.057, Windows 10.



  • On 23/07/2018 at 13:05, xxxxxxxx wrote:

    Hi Cody,

    Sorry for the delay, it appears there is a bug, which reset the custom array for each new frame, which shouldn't be the case. So your two workarounds are ok until it will be fixed.

    Cheers,
    Maxime



  • On 23/07/2018 at 13:11, xxxxxxxx wrote:

    No worries Maxime,
    Do you know, is there a plan to release a bug fix for R18 at some point? Or will it just stay broken since Maxon is already onto R19?



  • On 24/07/2018 at 01:12, xxxxxxxx wrote:

    Hi,

    unfortunately, bugfixes are only done for next versions. So you can't expect to have it for R18.



  • On 24/07/2018 at 09:57, xxxxxxxx wrote:

    That's reasonable, is this bug only in the python implementation for R18, or is it in the c++ too?



  • On 25/07/2018 at 02:03, xxxxxxxx wrote:

    I'm afraid the bug also impact C++.


Log in to reply