0
votes

I want a Maya camera orbiting a mesh while user chooses what to do with that mesh on my own script interface.

So i have a while orbiting the camera, but no way to interact with user interface while this happens.

There is anyway to "share", or part the focus in second's decims to be able to interact with user interface? I tried with cmds.evaldeferred(), but no luck...

Technically, Maya widgets interface is immediately available when script finishes the job...

I'm trying to finish the job with one single camera little orbit, and relaunch it with mouse movement event... Time changing event... But no way how to do that... Would be like a daemon running in the background... No idea how I could reach something like that....

Some code:

import maya.cmds as cmds

#declares global variable
global orbitCam

#just something to see in the scene
cmds.polyCube()

#function to stop camera orbit
def stopOrbiting():
    global orbitCam
    orbitCam = False

#simplest ui
cmds.window("testWindow")
cmds.formlayout("flo", parent="testWindow")
#button that calls stopOrbit function
cmds.button("pushMeIfYouCan", parent="flo", label="pushMeIfYouCan", c="stopOrbiting()")
cmds.showWindow("testWindow")

#condition for the while
orbitCam=True

#while itself
while orbitCam:
    cmds.orbit("persp", ra=(0.2,0.1))

Any way to be able to push the button -and interact with widgets- while camera orbits?

1
Here appears to be some solutions, perhaps, must I see it deeper: stackoverflow.com/questions/21164697/…Reaversword
Is there any particular reason you need to have the camera orbiting in real time? This sounds like it's being done for the sake of looking 'cool' but for no practical purpose.Green Cell
It's a matter to know what exactly geometry you're working on. Scene can have hundreds of similar pieces and visor could help to discern which exact geometry you are working on, orbiting purpose is to ensure mesh is not included by other when the view is focused en the object.Reaversword

1 Answers

0
votes

Well, based on solution provided by mhlester in the link I posted under the question (and considering a great answer too by theodox, as a wonderful alternative, thank you both, guys), I'm gonna aswer my own question and provide another new detailed explanation perhaps can help somebody in the future.

First of all, Maya's "scriptjob" command utility puts in memory a script (or a function), haves a trigger to start executing that function, and the condition to Maya to execute that function once registered and triggered, is that Maya must to be doing exactly nothing, so, Maya must be idle. Being that way, Maya never collapses or crashes or hangs by a scriptJob. ScriptJob is basically a... kind of "daemon" working in the background.

The good thing, is that is possible to limit the maximum number of times per second, so you can even maintain your system fresh and working if you want to care it about.

Once a scriptJob is launched (or registered in Maya memory), it can be killed to never runs again, and obviously, can be registered again if we want to start working again.

Exists an internal scriptJobs list inside of Maya, where you can find the scriptjob if you have forgotten to store that scriptJob in a variable, where you can find the "scriptJob ID", just an integer number you can use to kill the job.

After the first theory, let's see some code now:

This line will register a new daemon (maya scriptjob), its reference will be stored in "activeDaemon" variable, it will call a function called "camDaemon" with some arguments:

activeDaemon = registerDaemon(0.04, BackgroundFunction, ArgumentsForBackgroundFunction)

The point here is not just launch the daemon with conditions, besides, to store the daemon id to be able to kill it with:

cmds.scriptJob(kill=activeDaemon)

If we forgotten to store the daemon (scriptjob) id, we can use this command to watch a list with all scriptJobs of Maya:

cmds.scriptJob(listJobs=True)

We would need to find the last ids in the list with the event "idle", and probably we could hit and finished stopping our daemon killing it.

Now let's see "registerDaemon" function (all the absolute credit for MhLester):

def registerDaemon(seconds, backgroundFunction, *args, **kwargs):
    def updateNow():
        now = time.time()
        if now - updateNow.then > seconds:
           updateNow.then = now
            backgroundFunction(*args, **kwargs)
        
    updateNow.then = time.time()
    return cmds.scriptJob(event=("idle", updateNow))

registerDaemon defines an internal function (updateNow) that calls "automatically" at the backgroundFunction we pass as argument, including this "backgroundFunction" arguments. Just that. A function A that defines a function B that calls a function C. And it calls it every quantity of seconds we specify at register the daemon with the first argument, so if we want it executed 25 times per second, 1seg/25fps = 0.04 would be the right value.

To have this function working, we must import the module time in our script with:

import time

Finally it returns the scriptJob id at the same time it registers it in Maya memory, registering with the event "idle" and with the function (B) that calls the function (C) we really want executed in the background. This way we can control the temperatures of the machine not overwhelming the cpu unnecessary. Very complete last line, brilliant, at least, for me.

At this point no other thing left than just register the function we want to have running the background in the Maya memory (take the code you want in the background, put inside a function and execute it one time in Script Editor)

def backgroundFunction():
    print "this message shows in idle time by a daemon (Maya scriptjob)"

Of course there are much more in the documentation (Maya scriptJob documentation), as a list of events or conditions, but the base is this.