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 positionsIt'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
Lennartimport 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