Maya 2018 breaks detach seperate scripts?


#1

Hi I’ve noticed all the detach seperate scripts on Highend 3d and here are now broken with Maya 2018.

https://www.highend3d.com/maya/script/detach-and-separate-multiple-objects-for-maya
http://forums.cgsociety.org/showthread.php?t=1033241

Does anyone know what Autodesk changed and how to fix these scripts? The default extract faces tool in Maya is very poor.


#2

Looks like a bug. I took the code from the final post in that cgsociety post. I commented everything from the InvertSelection onward and everything looks correct at this point. The second you uncomment InvertSelection, you’ll find that Inverting the selection of the selected faces on the duplicate object results in the selection pointing back to the original objects as though the InvertSelection is based on the selection prior to your script running.

A workaround to this would be to write your own explicit InvertSelection. I’ve written a short Python script that works in 2018. It’s limited to detaching mesh faces.

import maya.cmds as cmds
import maya.mel as mel
import maya.api.OpenMaya as om

def get_selection():
    sel_list = om.MGlobal.getActiveSelectionList()
    sel = []
    for i in range(sel_list.length()):
        (path,comp) = sel_list.getComponent(i)
        shape_path = path
        shape_path.extendToShape()
        # Only support meshes and face component selection
        if not shape_path.apiType() == om.MFn.kMesh:
            continue
        if not comp.apiType() == om.MFn.kMeshPolygonComponent:
            continue
        sel.append( (path,comp) )
    return sel
    
def inverse_comp(path, comp):
    # Return the inverse of this component selection
    mesh_fn = om.MFnMesh(path)
    comp_fn = om.MFnSingleIndexedComponent(comp)
    num_faces = mesh_fn.numPolygons
    comp_ids = comp_fn.getElements()
    inv_comp_ids = [i for i in range(mesh_fn.numPolygons) if i not in comp_ids]
    inv_comp_fn = om.MFnSingleIndexedComponent()
    inv_comp = inv_comp_fn.create(om.MFn.kMeshPolygonComponent)
    inv_comp_fn.addElements(inv_comp_ids)
    return inv_comp
    
def convert_str_to_path(strpath):
    sel = om.MSelectionList()
    sel.add(strpath)
    return sel.getDagPath(0)
        
def extract_faces(path, comp):
    dup_path_str = maya.cmds.duplicate(path.fullPathName(), rr=True)
    assert(len(dup_path_str) == 1)
    dup_path = convert_str_to_path(dup_path_str[0])
    inv_comp = inverse_comp(path, comp)
    
    comp_ids = om.MFnSingleIndexedComponent(comp).getElements()
    inv_comp_ids = om.MFnSingleIndexedComponent(inv_comp).getElements()
    
    # Delete comp from path
    path_str = path.partialPathName()
    comp_str = [ path_str + '.f[' + str(i) + ']' for i in comp_ids]
    del_cmd = r'delete ' + ' '.join(comp_str)
    print del_cmd
    mel.eval(del_cmd)
    
    # Delete inv_comp from dup_path
    dup_path_str = dup_path.partialPathName()
    inv_comp_str = [ dup_path_str + '.f[' + str(i) + ']' for i in inv_comp_ids]
    inv_del_cmd = r'delete ' + ' '.join(inv_comp_str)
    print inv_del_cmd
    mel.eval(inv_del_cmd)
    
    return (dup_path,comp)
    
def main():
    sel = get_selection()
    
    dups = []
    for (path, comp) in sel:
        dup_path = extract_faces(path, comp)
        dups.append(dup_path)
    
    dup_sel = om.MSelectionList()
    for (path,_) in dups:
        dup_sel.add( path )
    om.MGlobal.setActiveSelectionList(dup_sel)

main()

Hope this helps. It’s probably still worth reporting that InvertSelection fails in script usage.


#3

:bowdown:

Thank you so much, it’s one of the most used tools I do in Maya. I was sure it was a bug too but couldn’t figure out where it was going wrong. Thanks for the help and I’ll send in a bug report.


#4

Yeah right It’s look like bug, you should discuss with your website developer. I remember my friend told me that is living around family dentist saint paul he also faced the same issue with his website. That time he discuss with their website developer and he solved that issue.