Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

"Replace Shape" not working, mgear5, Maya 2025 #441

Open
jobomat opened this issue Dec 20, 2024 · 1 comment
Open

"Replace Shape" not working, mgear5, Maya 2025 #441

jobomat opened this issue Dec 20, 2024 · 1 comment

Comments

@jobomat
Copy link

jobomat commented Dec 20, 2024

If you try to replace a NURBS-Shape via the "mgear > Rigbits > Replace Shape" menu item, you are presented with the following error:

# Error: More than one object matches name: ['whateverNurbsCurveShapeName']
# # Traceback (most recent call last):
# #   File "<maya console>", line 3, in <module>
# #   File "C:\Users\Anwender\Documents\maya\2025\modules\scripts\mgear\rigbits\__init__.py", line 422, in replaceShape
# #     pm.parent(source2.getShapes(), target, r=True, s=True)
# #   File "C:\Users\Anwender\Documents\maya\2025\modules\scripts\mgear\pymaya\cmd.py", line 231, in wrapper
# #     res = func(*args, **kwargs)
# # ValueError: More than one object matches name: ['whateverNurbsCurveShapeName']

I tried various renamings of the Shape-Node and the Transform. I also tried to fix it in the code, but ran out of time.

I think the issue is, that pymaya.getShapes internally calls pymaya.cmd.listRelatives which itself seems to just wrap maya.cmds.listRelatives. Therefore only a list of strings is returned which contains the short names of the shape nodes. And these are not unique. I suspect if pymaya.cmd.listRelatives would not just wrap cmds.listRelatives the issue could easily be fixed.

@jobomat
Copy link
Author

jobomat commented Dec 20, 2024

Fixed by acting on names and not pymaya-objects. Replace the function replaceShape in mgear/rigbits/__init__.py with this one:

def replaceShape(source=None, targets=None, *args):
    """Replace the shape of one object by another.

    Args:
        source (None, PyNode): Source object with the original shape.
        targets (None, list of pyNode): Targets object to apply the
            source shape.
        *args: Maya's dummy

    Returns:

        None: Return non if nothing is selected or the source and targets
        are none

    """
    if not source and not targets:
        oSel = pm.selected()
        if len(oSel) < 2:
            pm.displayWarning("At less 2 objects must be selected")
            return None
        else:
            source = oSel[0]
            targets = oSel[1:]

    for target in targets:
        print(target)
        source2 = pm.duplicate(source)[0]
        print(type(source2))
        shape = target.getShapes()
        cnx = []
        if shape:
            cnx = shape[0].listConnections(plugs=True, c=True)
            cnx = [[c[1], c[0].shortName()] for c in cnx]
            # Disconnect the conexion before delete the old shape
            for s in shape:
                for c in s.listConnections(plugs=True, c=True):
                    pm.disconnectAttr(c[0])
                pm.delete(s.longName())
        
        # getShapes is returning strings only... therefore using this slightly ugly fix:
        # adding the kwarg "fullPath"=True to fix the "not unique" problem
        # and parenting by name
        shape_names = [s for s in source2.getShapes(fullPath=True)]
        for s in shape_names:
            pm.parent(s, target, r=True, s=True)
        
        # fix here is the same as above...
        for i, sh in enumerate(target.getShapes(fullPath=True)):
            # Restore shapes connections
            for c in cnx:
                pm.connectAttr(c[0], f"{sh}.{c[1]}")
            pm.rename(sh, target.name() + "_%s_Shape" % str(i))

        pm.delete(source2)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant