Skip to content

Instantly share code, notes, and snippets.

@Onefabis
Last active May 10, 2018 17:06
Show Gist options
  • Save Onefabis/b511034cbf4a38cbda1461c6edbefbd6 to your computer and use it in GitHub Desktop.
Save Onefabis/b511034cbf4a38cbda1461c6edbefbd6 to your computer and use it in GitHub Desktop.
duplicate selected components
import maya.api.OpenMaya as om2
import maya.cmds as mc
try:
# get selected components
sel = om2.MGlobal.getActiveSelectionList()
for s in xrange( sel.length() ):
dp, comp = sel.getComponent( s )
# get parent transform node from selected polygons
parentNode = om2.MFnDagNode(dp).parent(0)
parentNodeDag = om2.MDagPath().getAPathTo(parentNode)
# store inclusive matrix from transform node
parentNodeMatrix = parentNodeDag.inclusiveMatrix()
# get all faces indexes
compFn = om2.MFnSingleIndexedComponent(comp)
ids = compFn.getElements()
# get all points from the original mesh
originalPoints = om2.MFnMesh( dp ).getPoints()
#get all vertives that included in selected olygons
outVertConnects = [ x for p in ids for x in om2.MFnMesh( dp ).getPolygonVertices(p) ]
outVertSorted = list( set( outVertConnects ) )
# create new empty transform node
mdag = om2.MDagModifier()
transformNode = mdag.createNode('transform')
# rename it to the name of the original transform node
mdag.renameNode(transformNode, parentNodeDag.partialPathName()+'_dupliacated' )
mdag.doIt()
# move empty transform node with the stored MMatrix
om2.MFnTransform(transformNode).setTransformation( om2.MTransformationMatrix( parentNodeMatrix ) )
# generate sequental indices list
listSequental = range(len(outVertSorted))
# reassign vertices indexes that appearen in outVertSorted but including the length of outVertSorted, so even if original
# vertex has maximum index 240, and overall count of selected polygon vertices is 160, this vertex should be remapped like
# 240=>160 and that should be done without changing the original position in list
outVertConectsOrdered = [ x + ( listSequental[outVertSorted.index(x)] - outVertSorted[outVertSorted.index(x)] ) for x in outVertConnects]
# number of vertices that included in each polygon
outVertCounts = [ om2.MFnMesh( dp ).getPolygonVertices(p).__len__() for p in ids]
# cteate empty UV values, the new mesh will be created without UVs
vValues = [ 0.0 ] * len(ids)
# create empty MFnMesh
outFnMesh = om2.MFnMesh()
# get filtered points from the original points list
outPoints = [ originalPoints[k] for k in set(outVertConnects) ]
# create the new mesh under the empty transform node
shapeNode = outFnMesh.create( outPoints, outVertCounts, outVertConectsOrdered, vValues, vValues, transformNode)
# rename created shape
mShapeDag = om2.MDagModifier()
mShapeDag.renameNode( shapeNode, parentNodeDag.partialPathName()+'Shape_dupliacated' )
mShapeDag.doIt()
# get all shaders IDs assigned to original mesh polygons
shaders, indices = om2.MFnMesh( dp ).getConnectedShaders(0)
# sort materials indexes
sharedFaceIDs = [ indices[o] for o in ids ]
# iterate through each shader
newShapeIt = om2.MItMeshPolygon( shapeNode )
for s in xrange( len( shaders ) ):
# create new Set from current shader
shaderSet = om2.MFnSet( shaders[s] )
selComponent = om2.MSelectionList()
# iterate through each polygon of the new mesh
for k in xrange(newShapeIt.count()):
newShapeIt.setIndex(k)
if sharedFaceIDs[k] == s:
# add filtered components to the empty MSelectionList
selComponent.add( (om2.MDagPath().getAPathTo(shapeNode), newShapeIt.currentItem() ) )
# assign MSelectionList of the components to the current shader Set
shaderSet.addMembers( selComponent )
om2.MGlobal.setSelectionMode( 0 )
om2.MGlobal.setActiveSelectionList( om2.MSelectionList().add( om2.MDagPath().getAPathTo(transformNode) ), 0 )
except:
mc.warning( 'Select mesh faces or vertices' )
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment