一半君的总结纸

听话只听一半君

#98 如何知道一个物体是不是当前可见的?

最简单办法是看看那个node的 ‘.visibility‘ 属性; 但是这不能保证你一定能在viewport里看到该物体,还需要考虑一下情形:

  • 某个物体是否可见不仅仅取决于他自身的 ‘.visibility‘ 属性, 还和他所有父物体的’ ‘.visibility‘ 有关. 如果父物体隐藏了,那么自物体显然也会被隐藏.
  • 如果一个节点是 mesh node, 并且他的 ‘.intermediateObject‘ 属性是 TRUE, 那他也不会被显示或渲染(比如你给一个物体加了skinCluster之后).
  • 如果一个物体在某显示层( displayLayer)里, 而此层隐藏了,那这个物体也是在视窗里看不到的.

下面这个例子演示了查询一个node是不是可见的一种方法:

proc int nodeIsVisible( string $node )
{
  // 如果node不存在, 返回 FALSE.
  if ( !`objExists $node` ) return false;

  // node必须是一个 DAG node, 否则根本用不着查询,因为本身就看不到.
  // 没有能查询一个node是不是DAG node的MEL命令, 但是 kDagNode class 添加了属性
  // '.visibility'到是DAG node的node上, 所以可以用有没有这个属性来判断是不是DAG node.
  if ( !`attributeQuery -node $node -exists "visibility"` ) return false;

  // 查询'.visibility' attribute 的值
  int $visible = `getAttr ( $node + ".visibility" )`;

  // 如果node是 intermediate mesh, 那他是看不到的
  if ( `attributeQuery -node $node -exists "intermediateObject"` )
  {
    $visible = $visible && !`getAttr ( $node + ".intermediateObject" )`;
  }

  // 如果物体在 displayLayer里, 并且这个displayLayer 是隐藏的,
  // 那么这个物体也是隐藏的.
  if ( `attributeQuery -node $node -exists "overrideEnabled"` &&
       `getAttr ( $node + ".overrideEnabled" )` )
  {
    $visible = $visible && `getAttr ( $node + ".overrideVisibility" )`;
  }

  // 在层级(hierarchy)向上一层,看他的父物体是不是隐藏的.
  if ( $visible )
  {
    string $parents[] = `listRelatives -parent $node`;
    if ( `size $parents` > 0 )
    {
      $visible = $visible && nodeIsVisible( $parents[0] );
    }
  }

  return $visible;
}

11 Apr 2004

加强版:

总感觉pymel省事多了… 下面是直译,不过好像没什么意义

def nodeIsVisible( node ):
    visible = False

    try:
        pyNode = pm.PyNode(node)

        if pyNode.hasAttr('visibility'):
            visible = pyNode.visibility.get()

        if pyNode.hasAttr('intermediateObject'):
            visible = visible and not pyNode.intermediateObject.get()

        if pyNode.hasAttr('overrideEnabled') and pyNode.overrideEnabled.get():
            visible = visible and pyNode.overrideEnabled.get()

        if visible:
            if pyNode.getParent():
                visible = visible and nodeIsVisible(pyNode.getParent()[0])

    except:
        pass

    return visible
Advertisements

发表评论

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / 更改 )

Twitter picture

You are commenting using your Twitter account. Log Out / 更改 )

Facebook photo

You are commenting using your Facebook account. Log Out / 更改 )

Google+ photo

You are commenting using your Google+ account. Log Out / 更改 )

Connecting to %s

%d 博主赞过: