导出FBX修改namespace

在公司给游戏部门弄一个导出fbx的插件,导出的时候需要将namespace去掉,这样方便他们导入UE里面,以前的操作是将Maya里的reference全部解除掉,变成导出的模式,这样去掉namespace后再导出fbx,但是这样呢有个问题,就是当一个文件里有相同的rig的时候,那么变成导入的时候就会多个后缀1,2之类的;而且另一方面将源文件也给破坏了,动画师如果再修改的话还得重新开文件,于是寻找下在Maya里有没有在不解除reference的情况下,去掉namespace,最后找到了,就是API了,借助API就可以实现了,下面是具体的代码,自己略加注解:



import maya.cmds as cmds
import maya.OpenMaya as om


class StripNamespace(object):
    """
    Context manager use to temporarily strip a namespace from all dependency nodes within a namespace.
    Sometimes also can be used to unparent some specific groups temporarily

    This allows nodes to masquerade as if they never had namespace, including those considered read-only
    due to file referencing.

    Usage:

        with StripNamespace('someNamespace') as stripped_nodes:
            print cmds.ls(stripped_nodes)

        or

        with StripNamespace('someNamespace', unparent=['grp1', 'grp2']) as stripped_nodes:
            print stripped_nodes
    """

    @classmethod
    def as_name(cls, uuid):
        """
        Convenience method to extract the name from uuid

        :type uuid: basestring
        :rtype: unicode|None
        """
        names = cmds.ls(uuid)
        if names:
            for name in names:
                if ':' not in name:
                    return name
        else:
            return None

    def __init__(self, namespace, unparent=[]):
        if cmds.namespace(exists=namespace):
            self.original_names = {}  # (UUID, name_within_namespace)
            self.parent = {}
            self.namespace = cmds.namespaceInfo(namespace, fn=True)
            self.unparent = unparent
        else:
            raise ValueError('Could not locate supplied namespace, "{0}"'.format(namespace))

    def toMObject(self, node):
        selList = om.MSelectionList()
        selList.add(str(node))
        mObject = om.MObject()
        selList.getDependNode(0, mObject)
        return mObject

    def __enter__(self):
        if self.unparent:
            for item in self.unparent:
                selList = om.MSelectionList()
                api_obj = om.MObject()
                om.MGlobal.getSelectionListByName(item, selList)
                selList.getDependNode(0, api_obj)
                dag_parent = cmds.listRelatives(item, p=1)
                self.parent[item] = dag_parent[0]

                dag_modi = om.MDagModifier()
                dag_modi.reparentNode(api_obj)
                dag_modi.doIt()

        for absolute_name in cmds.namespaceInfo(self.namespace, listOnlyDependencyNodes=True, fullName=True):
            # Ensure node was *not* auto-renamed (IE: shape nodes)
            if cmds.objExists(absolute_name):
                # get an api handle to the node
                try:
                    selList = om.MSelectionList()
                    api_obj = om.MObject()
                    om.MGlobal.getSelectionListByName(absolute_name, selList)
                    selList.getDependNode(0, api_obj)
                    api_node = om.MFnDependencyNode(api_obj)

                    # remember the original name to return upon exit
                    uuid = api_node.uuid().asString()
                    self.original_names[uuid] = api_node.name()

                    # strip namespace by renaming via api, bypassing read-only restrictions
                    without_namespace = api_node.name().replace(self.namespace, '', 1)
                    api_node.setName(without_namespace)
                except:
                    pass

        return [self.as_name(uuid) for uuid in self.original_names]

    def __exit__(self, exc_type, exc_val, exc_tb):
        for uuid, original_name in self.original_names.iteritems():
            try:
                current_name = self.as_name(uuid)
                selList = om.MSelectionList()
                api_obj = om.MObject()
                om.MGlobal.getSelectionListByName(current_name, selList)
                selList.getDependNode(0, api_obj)
                api_node = om.MFnDependencyNode(api_obj)
                api_node.setName(original_name)
            except:
                pass

        if self.parent:
            for absolute_name, parent in self.parent.iteritems():
                dag_modi = om.MDagModifier()
                absolute_name_mobject = self.toMObject(absolute_name)
                parent_mobject = self.toMObject(parent)
                dag_modi.reparentNode(absolute_name_mobject, parent_mobject)
                dag_modi.doIt()

里面有unparent的操作,为了是可以将某个组P出来再导出,也是满足游戏那边他们对FBX的层即结构的要求;最后补充一点的是,在Maya里如果一个物体被复制出来,那么他们uuid是相同的,所以在使用as_name的方法的时候,我们只需要获取不带namespace的物体,而带有namespace的物体是未被我们修改的。
这样以来,导出完FBX,文件未被破坏,动画师如果修改的话,也不用重开文件,也不会有对于的后缀了,方便动画这边出FBX了。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值