Pause whole script until after evalDeferred

2,298 views
Skip to first unread message

Michael Boon

unread,
Aug 4, 2014, 2:38:11 AM8/4/14
to python_in...@googlegroups.com


Hi all,

I'm trying to load a DX11 shader. In the process I have to make sure VP2.0 is on and the renderer is set to DX11.
    editor = panel.getModelEditor()
    pm
.evalDeferred("pm.runtime.ActivateViewport20()")
    renderer
= pm.modelEditor(editor, q=True, rendererDeviceName=1)
ActivateViewport20 only works if deferrred, probably because I just created the panel.
As it is, renderer gets set to an empty string. If I wait a moment (eg if I run it line by line in the script editor), renderer returns 'VirtualDeviceDx11' as appropriate.

So basically, I think I need to defer twice. Once before ActivateViewwport20, and again between that and getting the rendererDeviceName. I've tried this:
    editor = panel.getModelEditor()
    pm.evalDeferred("pm.runtime.ActivateViewport20()")
    pm
.refresh(force=True)
    renderer
= pm.modelEditor(editor, q=True, rendererDeviceName=1)
with no luck. I've also tried time.sleep(), but that halts Maya's main thread, which doesn't help at all.

Is there a way to give control back to Maya's event loop until it's idle, with writing a state machine?

(This is in Maya 2015.)

Thanks,

Boon

Justin Israel

unread,
Aug 4, 2014, 3:38:26 AM8/4/14
to python_in...@googlegroups.com

Untested, but have you checked if the refresh command helps to flush the event queue?
http://download.autodesk.com/global/docs/maya2012/en_us/CommandsPython/refresh.html

Otherwise I am pretty sure using the qt processEvents() call would work:

from PySide import QtGui
QtGui.qApp.processEvents()

--
You received this message because you are subscribed to the Google Groups "Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_m...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/python_inside_maya/221422dd-df4e-40ae-9f98-cef8cc501f1c%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Paul Molodowitch

unread,
Aug 4, 2014, 1:21:28 PM8/4/14
to python_inside_maya
I think it might be easier to run EVERYTHING deferred, so that you can be SURE that things execute in the order you want them to - ie, do something like this:

def doMyThang():
    pm.runtime.ActivateViewport20()
    renderer = pm.modelEditor(editor, q=True, rendererDeviceName=1)
editor = panel.getModelEditor()
pm.evalDeferred(doMyThang)
If that doesn't work, you can try breaking it up into two parts:

def
part1(): pm.runtime.ActivateViewport20() pm.evalDeferred(part2) def part2():
    renderer = pm.modelEditor(editor, q=True, rendererDeviceName=1)
    

editor = panel.getModelEditor()
pm.evalDeferred(part1)
Of course, this means you won't back the answer to what the renderer is in the original context - but if processing of idle events is required first, it might make sense to design things so that it puts things in an intermediate state, and then "updates" once it can get access to the "right" answer.

If you absolutely need it in the original context, though, you could also try maya.utils.processIdleEvents()...

- Paul

Michael Boon

unread,
Aug 4, 2014, 6:58:53 PM8/4/14
to python_in...@googlegroups.com
Thank you both.

In the case of a simple example script, such as
pm.evalDeferred("print 'this should print first'")
maya
.utils.processIdleEvents()
print 'this should print second'
It turns out that only processIdleEvents works. Qt's processEvents and Maya's (well, pymel's) refresh() have no effect.

In my case none of them work though. Even moving 
renderer = pm.modelEditor(editor, q=True, rendererDeviceName=1)
into its own function and calling that with evalDeferred (actually I switched executeDeferred because it takes a function instead of a string), and putting processIdleEvents() between the two executeDeferred calls, doesn't work.

Paul - your method of calling a function via executeDeferred and calling the second function via executeDeferred inside the first works! I didn't expect that after all the trouble I'd had making ActivateViewport20 work at all!

Thanks again :)


>> To view this discussion on the web visit
>> https://groups.google.com/d/msgid/python_inside_maya/221422dd-df4e-40ae-9f98-cef8cc501f1c%40googlegroups.com.
>> For more options, visit https://groups.google.com/d/optout.
>
> --
> You received this message because you are subscribed to the Google Groups
> "Python Programming for Autodesk Maya" group.
> To unsubscribe from this group and stop receiving emails from it, send an

Michael Boon

unread,
Aug 4, 2014, 8:00:25 PM8/4/14
to python_in...@googlegroups.com
I take that back.

pm.runtime.ActivateViewport20() apparently only works if it's run deferred, on its own. So I have to do
maya.utils.executeDeferred(pm.runtime.ActivateViewport20)

At this point I'm going to stop worrying about this, and just check that pm.optionVar['vp2RenderingEngine'] == 1
It's not as correct as the other way might have been, but at least it works!

Michael Boon

unread,
Aug 4, 2014, 9:25:39 PM8/4/14
to python_in...@googlegroups.com
Ha, I take that back too. I hadn't realized I needed to do 
    pm.modelEditor(editor, e=True, rendererName="vp2Renderer")
I guess the apparent need for evalDeferred was a red herring due to something changing when I ran my script multiple times yesterday.

So, this works:
    editor = panel.getModelEditor()
    pm
.runtime.ActivateViewport20()
    pm
.modelEditor(editor, e=True, rendererName="vp2Renderer")
    pm
.refresh()

    renderer
= pm.modelEditor(editor, q=True, rendererDeviceName=1)

   
if renderer != 'VirtualDeviceDx11':
       
# Complain...


Reply all
Reply to author
Forward
0 new messages