【问题标题】:Running background code in Maya as a Daemon, scriptJob在 Maya 中作为守护进程运行后台代码,scriptJob
【发布时间】:2020-09-08 02:27:57
【问题描述】:

我想要一个 Maya 相机绕网格运行,而用户在我自己的脚本界面上选择如何处理该网格。

所以我有一段时间绕着相机转,但在发生这种情况时无法与用户界面进行交互。

无论如何要“分享”,或者将焦点放在秒的十进制中以便能够与用户界面进行交互? 我尝试使用 cmds.evaldeferred(),但没有运气...

从技术上讲,Maya 小部件界面在脚本完成工作后立即可用...

我正在尝试用一个相机小轨道完成这项工作,并通过鼠标移动事件重新启动它...时间变化事件...但是没有办法做到这一点...就像一个守护进程正在运行在后台......不知道我怎么能达到这样的目的......

一些代码:

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))

有什么方法可以在相机绕行时按下按钮并与小部件交互?

【问题讨论】:

  • 这里似乎有一些解决方案,也许,我必须深入了解一下:stackoverflow.com/questions/21164697/…
  • 您有什么特别的理由需要让相机实时绕行吗?这听起来像是为了看起来“酷”,但没有实际目的。
  • 重要的是要知道您正在处理的确切几何形状。场景可以有数百个相似的部分,并且遮阳板可以帮助识别您正在处理的确切几何形状,轨道目的是确保当视图聚焦在对象上时网格不被其他部分包含。

标签: python daemon maya execution interactive


【解决方案1】:

好吧,根据我在问题下发布的链接中 mhlester 提供的解决方案(并且考虑到 theodox 的一个很好的答案,作为一个很好的选择,谢谢你们,伙计们),我将提出我自己的问题和提供另一个新的详细解释也许可以帮助将来的人。

首先,Maya 的“scriptjob”命令实用程序将脚本(或函数)放入内存中,具有开始执行该函数的触发器,并且一旦注册和触发,Maya 执行该函数的条件是 Maya必须完全什么都不做,所以,玛雅必须是空闲的。 这样一来,Maya 永远不会崩溃、崩溃或被 scriptJob 挂起。 ScriptJob 基本上是一种……在后台工作的“守护进程”。

好消息是可以限制每秒的最大次数,因此如果您想关心它,您甚至可以保持系统的新鲜和正常工作。

一旦启动了一个 scriptJob(或在 Maya 内存中注册),它可以被终止以不再运行,显然,如果我们想重新开始工作,可以再次注册。

在 Maya 内部存在一个内部 scriptJobs 列表,如果您忘记将该 scriptJob 存储在变量中,您可以在其中找到该 scriptJob,您可以在其中找到“scriptJob ID”,只是一个整数,您可以使用它来杀死工作。

在第一个理论之后,我们现在来看一些代码:

这一行将注册一个新的守护进程(maya scriptjob),它的引用将存储在“activeDaemon”变量中,它将调用一个名为“camDaemon”的函数并带有一些参数:

activeDaemon = registerDaemon(0.04, BackgroundFunction, ArgumentsForBackgroundFunction)

这里的重点不仅仅是启动有条件的守护进程,此外,存储守护进程ID以便能够杀死它:

cmds.scriptJob(kill=activeDaemon)

如果我们忘记存储守护进程 (scriptjob) id,我们可以使用此命令查看包含 Maya 的所有 scriptJobs 的列表:

cmds.scriptJob(listJobs=True)

我们需要找到列表中包含事件“idle”的最后一个 id,并且可能我们可以命中并停止我们的守护进程杀死它。

现在让我们看看“registerDaemon”函数(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 定义了一个内部函数 (updateNow),它在我们作为参数传递的 backgroundFunction 中“自动”调用,包括这个“backgroundFunction”参数。只是。一个函数 A 定义了一个调用函数 C 的函数 B。它在我们使用第一个参数注册守护进程时指定的每一秒调用它,所以如果我们希望它每秒执行 25 次,1seg/25fps = 0.04 将是正确的价值。

要让这个功能正常工作,我们必须在脚本中导入模块时间:

import time

最后它返回 scriptJob id,同时它在 Maya 内存中注册它,注册事件“空闲”和调用我们真正希望在后台执行的函数 (C) 的函数 (B)。这样我们就可以控制机器的温度,而不会不必要地压倒 cpu。最后一行非常完整,至少对我来说很棒。

此时,我们只需要在 Maya 内存中注册我们想要在后台运行的函数(在后台获取您想要的代码,放入一个函数并在脚本编辑器中执行一次)

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

当然,文档 (Maya scriptJob documentation) 中还有更多内容,作为事件或条件的列表,但基础是这样的。

【讨论】:

  • 不要将此答案标记为求解器答案,因为这只是对 MhLester 在其他帖子中提供的解决方案的详细解释。解决信用应该是他的。
猜你喜欢
  • 2023-03-02
  • 1970-01-01
  • 1970-01-01
  • 2017-03-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-04
  • 1970-01-01
相关资源
最近更新 更多