Scripts that need to be executed twice?

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 20/02/2012 at 09:37, xxxxxxxx wrote:

User Information:
Cinema 4D Version:   12 
Platform:   Windows  ;   
Language(s) :   C.O.F.F.E.E  ;  C++  ;   PYTHON  ;

---------
Every once in a while I run across a strange scripting behavior where a piece of the code gets skipped over. And requires me to execute the script a second time.
It typically most often happens when moving objects in the hierarchy. Then trying to do something on that object.
It's almost as if C4D has a hard coded time limit to execute lines of code. And if anything takes more than a couple of cycles(like editing the OM). C4D can sometimes skip over the lines of code following that task!

I can usually hack around these kinds of problems.
But here's an example where the problem is really, really bad:

import c4d  
  
def main() :  
  for i in range(2) : #Cheats the script to work...this script dos not work in one click!!  
  op = doc.GetActiveObject()  
  points = op.GetAllPoints()  
  mtx = op.GetMg()  
  inv = mtx.__invert__()  
  
  gpoints = []              #Used to hold the points original global positions  
  for i, point in enumerate(points) :  
      lpoints = points _    #The local position of each point  
      gpnt = inv*point      #The global position of each point  
      gpoints.append(gpnt)  #Add each global point position to the list  
  
  doc.StartUndo()  
  doc.AddUndo(c4d.UNDOTYPE_CHANGE, op)  
  doc.EndUndo()  
  
  op.SetAbsPos(c4d.Vector(150,300,300)) #Move the object's axis  
  op.Message(c4d.MSG_UPDATE)            #Tell C4d the object moved  
  op.SetAllPoints(gpoints)   #Move the points back to their original positions  
  op.Message(c4d.MSG_UPDATE)  
  c4d.EventAdd()  
  
if __name__=='__main__':  
  main()

This example is in python. But it also happens in Coffee(and I assume C++) too.
All I want to do is make my script do this:
- Save an object's global point positions in an array
- Move the object someplace else in the scene
- Restore the points back to their original positions

It's acting like the object is still at 0,0,0 and never gets updated that the object has been moved.
And it's also doing that annoying thing where I have to execute it twice. Because once it reaches SetAbsPos(). It completely ignores the SetAllPoints() code that comes after it!

Why does this happen?
Is there a work around, or different approach I should use for this kind of situation that the script manager can handle better?

-ScottA
_

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 20/02/2012 at 11:08, xxxxxxxx wrote:

To me it looks as if you miss the new matrix after movement
to use as new base and your script reads the new base on the second
pass. (And the doc.EndUndo should be last after all your changes)

Cheers
Lennart

  
import c4d   
  
def main() :   
    if op is None: return False   
    oldm   = op.GetMg()   
    points = op.GetAllPoints()   
    pcount = op.GetPointCount()   
  
    doc.StartUndo()   
    doc.AddUndo(c4d.UNDOTYPE_CHANGE, op)   
    op.SetAbsPos(c4d.Vector(150,300,300))   
    op.Message(c4d.MSG_UPDATE)   
  
    newm    = op.GetMg()   
  
    for p in xrange(pcount) :   
        op.SetPoint(p,~newm*oldm*points[p])   
  
    op.Message(c4d.MSG_UPDATE)   
    c4d.EventAdd()   
    doc.EndUndo()   
  
if __name__=='__main__':   
    main()   

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 20/02/2012 at 12:24, xxxxxxxx wrote:

Thanks Lennart.🍺

I didn't realize that I needed to grab the matrix twice like that. But I think I can see why it's necessary.

-ScottA