Frequent updates on Posemorph tag
-
I try to move the eyeball step by step, but it only moves one step, suddenly moves to the last position. The middle course doesn't show up, and the 'for' loop seems not to be effective and becomes a big step seemingly.
import c4d from c4d import gui import time # Welcome to the world of Python # Main function def main(): tag = doc.GetActiveTag() tag.ExitEdit(doc,True) rightleft = tag.GetMorphID(2) updown = tag.GetMorphID(1) for i in range(15): tag[rightleft]+=0.05 tag[updown]+=0.06 print(tag[rightleft]) time.sleep(0.3) tag.UpdateMorphs() c4d.EventAdd() # Execute main() if __name__=='__main__': main()
EDIT: (Ilia) forked from here and formatted the code
-
Hi @matrixloong,
I've forked your question in a separate thread as it diverged from the original question too much.
In your next postings please follow our guidelines in this regard:A topic must cover a singular subject; the initial posting must be a singular question.
Also please use the code formatting when inserting code snippets, which is also cleanly explained in our guidelines section Markup and Uploading Content.
Regarding your question. You're running this code on a main thread (because it's a script), hence calling
time.sleep()
function simply freezes cinema.What I assume you're trying to achieve is to control the object states (pose morph strength sliders) from the code with some determenistic frequency (i.e. every N ms). In general it is not an easy task to achieve due to Cinema being an event driven app (check the Scene Execution Pipeline). The same scenario was already extensively explained by @ferdinand in the thread: How to increase the number of calculations in a Python tag?
Depending on the major goal you're trying to achieve, there could be different better ways to make this work. For example, I would recommend calculating values and creating corresponding keyframes into the animation timeline as the most preferable one.
Cheers,
Ilia -
Hi, Ilia:
Thanks a lot for your assistance. I have already thought if using key frames can do it? However my task is to control a model object in real-time interactively. The key frames must be preset in advance. -
Hi, Ilia:
I prefer to control an object in real-time, could you give some examples for doing it?
best regards
Taucher -
Hi @matrixloong ,
Please excuse the delayed answer.
The real-time scenario is one of those that might not go very smoothly in cinema (check the links in my previous message). It was already discussed in the thread: Is it possible to control Camera with keyboard WASD like a FPS game?
Ferdinand showed there one of the possible solutions to achieve live interactions on the scene using interaction dialog. You can use the simplified version of it below.
Cheers,
IliaRun this code from the script manager and select an object in the object manager.
import c4d, time, math doc: c4d.documents.BaseDocument # The active document class InteractionDialog(c4d.gui.GeDialog): TIMER_DELAY = 40 def CreateLayout(self): return True def InitValues(self): self._doc: c4d.BaseDocument = doc self.SetTimer(InteractionDialog.TIMER_DELAY) self._time = None self._lastTime = None self._angle = 0 return True def Timer(self, msg): # Initialize the time for the first frame a key is being pressed. if self._lastTime is None: self._lastTime = time.time() return None # The delta between now and the last evaluation dt = time.time() - self._lastTime self.DoSomething(dt) self._lastTime = time.time() def DoSomething(self, dt): op: c4d.BaseObject = self._doc.GetActiveObject() if not op: return PI2 = 2 * math.pi angleIncrement = dt * PI2 / 2 self._angle += angleIncrement if self._angle >= PI2: self._angle -= PI2 ml: c4d.Matrix = op.GetMl() bb: c4d.Vector = op.GetRad() pos: c4d.Vector = ml.off pos.x = bb.x * math.sin(self._angle) ml.off = pos op.SetMl(ml) c4d.EventAdd() if __name__ == '__main__': global dialog dialog = InteractionDialog(doc) dialog.Open(c4d.DLG_TYPE_ASYNC)