I'm starting to work on some tools that will operate on selected component islands. But once again, im banging my head on the keyboard trying to understand how maya wants me to think. This stuff is so easy in XSI ;)
anyways, I'm passing in a component selection and returning the connected verts for each selected island. I'm using Pymel (i know what your gonna say), but I can't really figure out a good way to get the selected islands without having to do a ton of looping.
so far I'm just passing in the selection list, which kinda represents the selected islands, but not really. I guess it depends on how you selected, and in what order.
so errr, uhh what's the best way to do this? and I definitely wouldn't mind some speed suggestions on my code so far, by someone who's been through this. Aside from not using pymel ;)
==============
import pymel.core as pm
from itertools import chain
# list of component selections
selection = pm.selected()
#loop through each item of the list (selection islands)
for component in selection:
print "========================================"
print "Component ID/'s is {0}".format(component)
#make a list of connected verts
connectedVerts = [ island.connectedVertices() for island in component ]
#print it pretty
for item in set( chain(*connectedVerts) ):
print item
=============
Thanks!
Kev
This stuff is so easy in XSI ;)
That isn’t the way to introduce a question in a Maya group. :)
a little help would be much appreciated!
yes true, but I don't play those games ;)
a little help would be much appreciated!
--
You received this message because you are subscribed to the Google Groups "Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_m...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/python_inside_maya/3b03878f-ad4a-4927-9780-497750138c76%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
============================
import pymel.core as pm
from itertools import chain
def getComponentIslands( components ):
#placeholder, till I figure this out
componentIslands = components
return componentIslands
def getComponentIslandVerts( islands ):
for component in islands:
print "========================================"
print "Component Island ID/'s are {0}".format(component)
node = component.node()
if type(component) == pm.MeshFace:
verts = [ island.connectedVertices() for island in component ]
elif type(component) == pm.MeshEdge:
verts = [ island.connectedVertices() for island in component ]
elif type(component) == pm.MeshVertex:
verts = [ island.connectedVertices() for island in component ]
for item in set( chain(*verts) ):
print item
getComponentIslandVerts( getComponentIslands( pm.selected() ) )
==========================
Thanks
Kev
but if anyone is listening, I've taken a step back, and decided to work on the simpler bits for now. avoiding the islands for now, and just focusing on what I want from the components passed in.
Things would be much easier for me I think if my selection list remained objects, and not strings after converting the list to verts using pm.polyListComponentConversion(). is there a better way?
sorry for a silly question, but how could I get the objects instead or after? so that I can get the position, and normal, etc, etc.
===========
def getComponentIslands( components ):
'''
do fancy stuff here to return component islands
'''
return componentIslands
def convertToVerts( components ):
return pm.polyListComponentConversion( components, toVertex=True )
def getAvgVertTfm( components ):
avgTfm = pm.datatypes.TransformationMatrix()
verts = convertToVerts(components)
for vert in verts:
'''
do all the fancy math stuff here
'''
pass
return avgTfm
=============
Thanks
Kev
On 19/09/2014 11:20 AM, <kevco...@gmail.com> wrote:
>
> I suppose I've been put on ignore for mentioning xsi (i'm sorry, i'm sorry ;) )
>
You haven't been put on ignore for any reason. I just think it's a matter of the the right person not yet having responded with an answer.
> --
> You received this message because you are subscribed to the Google Groups "Python Programming for Autodesk Maya" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_m...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/python_inside_maya/6507d05d-8aba-4085-8637-6faf20a92f56%40googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/python_inside_maya/CAPGFgA3hPSRf-HdjrZyWz3gq-5nPGMV7VgajJ-WyZ%3DXqX5XPDw%40mail.gmail.com.
by "component islands", I mean to say - 'Groups' of connected components (edges, faces, verts) in the current selection or passed in component id's.
I'd love some help with that. I will just be creating locators at the average tfm of those component 'Groups' for now.
I've figured out my previous posts dilemma, by just instancing a pm.MeshVertex() with the string(s) that the conversion cmd was giving me. that's probably not that best way though i figure.
even so, now I have access to their positions and normals, just need to do some err, math.
import pymel.core as pm def tfmAtCentroid(vertSel=None, tfmSel=None, locator=True, name=None): """ select verts and joints. snaps a joint to the centroid position of selected verts. """ # SELECTED VERTS AND JOINTS verts = vertSel or [] tfms = tfmSel or [] sel = pm.selected() returnList=[] # NOTHING PASSED IN OR SELECTED if not vertSel and not tfmSel and not sel: return # IF NO ARGS PASSED IN GET SELECTED if sel: for item in sel: # SORT THE SELECTION if item.__class__.__name__ == "MeshVertex": verts.append(item) else: tfms.append(item) # JUST SELECTED WHOLE PIECE(s) OF GEOM if tfms != [] and verts == []: for tfm in tfms: try: pm.select("%s.vtx[:]"%tfm,r=True) newTfm = tfmAtCentroid(locator=locator,name=name)[0] returnList.append(newTfm) except: # NOT A MESH if locator: name = name or "%sNUL"%tfm loc = pm.spaceLocator(n=name) pm.delete(pm.pointConstraint(tfm,loc,mo=False)) returnList.append(loc) else: name = name or "%sJNT"%tfm pm.select(d=True) j = pm.joint(n=name) pm.select(d=True) pm.delete(pm.pointConstraint(tfm,j,mo=False)) returnList.append(j) # HAVE TO RETURN HERE OR IT WILL CONTINUE ON AND MOVE YOUR TFM TO THE ORIGIN return returnList # SELECTED SOME VERTS AND THATS IT if tfms == [] and verts != []: if locator: name = name or "%sNUL"% verts[0].node() loc = pm.spaceLocator(n=name) tfms.append(loc) returnList.append(loc) else: name = name or "%sJNT"% verts[0].node() j = pm.joint(n=name) pm.select(d=True) tfms.append(j) returnList.append(j) pm.select(verts,r=True) # CREATE A CLUSTER TEMPORARILY clsNode, clsHandle = pm.cluster() for tfm in tfms: # SNAP JOINTS TO THE CLUSTER HANDLE pm.select(d=True) pm.delete(pm.pointConstraint(clsHandle,tfm,mo=False)) #DELETE THE CLUSTER HANDLE pm.select(d=True) try: pm.delete(clsNode,clsHandle) except: pass return returnList
--
You received this message because you are subscribed to the Google Groups "Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_m...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/python_inside_maya/9c954523-f47d-4f5d-b67e-50b8bd6a13fe%40googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/python_inside_maya/CABPXW4g0KD%2Bw61MzjDZTZaiy1LhR%3Ddq4gn%2Bj1RYHL3w2%3DTjgrA%40mail.gmail.com.
I think I've been staring at this too long now, but how do I loop on something like pCube1.vtx[14:16]? or better yet, flatten that?
my vertex list looks like this:
[u'pCube1.vtx[14:16]', u'pCube1.vtx[20:22]', u'pCube1.vtx[26:27]']
so when I loops over the vertex list to get pos, I only get 3 vertex positions, instead of 23.
pCube1.vtx[14:16]
[-0.809902191162, -0.809902191162, 4.04951095581]
pCube1.vtx[20:22]
[-0.809902191162, 0.809902191162, 4.04951095581]
pCube1.vtx[26:27]
[-0.809902191162, 2.42970657349, 4.04951095581]
Thanks,
Kev
--
You received this message because you are subscribed to the Google Groups "Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_m...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/python_inside_maya/026aade1-8f24-45ee-8ee3-85b374e286dd%40googlegroups.com.
This is getting much faster. hoorayy...
Kev
I suppose I’ve been put on ignore for mentioning xsi (i’m sorry, i’m sorry ;) )
No one is bring put on ignore, it just so happens that nightfall struck Europe since my last reply. However I don’t have much to add.
Kev
--
You received this message because you are subscribed to the Google Groups "Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_m...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/python_inside_maya/67b08848-1ddd-43fa-99fe-1e2efddbb78b%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
#========================================
import pymel.core as pm
from itertools import chain
import time
def convertToVerts( components ):
return pm.ls( pm.polyListComponentConversion( components, toVertex=True ),
flatten=True)
def getAvgVertTfm( components ):
verts = convertToVerts(components)
positions = []
normals = []
for vert in verts:
positions.append( vert.getPosition() )
normals.append( vert.getNormals() )
avgPos = [ sum(pos)/len(pos) for pos in zip(*positions) ]
avgNormal = [ sum(normal)/len(normal) for normal in zip(*normals) ]
avgNormalRotation = [ sum(rotation)/len(rotation) for rotation
in zip(*pm.datatypes.degrees(avgNormal)) ]
avgTfm = pm.datatypes.TransformationMatrix()
avgTfm.setTranslation(avgPos, space="world")
avgTfm.setRotation(avgNormalRotation)
null = pm.spaceLocator()
null.setTransformation( avgTfm )
'''
still need to add object matrix multiplications
'''
startTime = time.time()
getAvgVertTfm( pm.ls(sl=True) )
print time.time()-startTime
#=======================================
def getShells(objs): '''Gets the shells for a selected list objects and returns a dict Args: objs (list of pm.PyNode): all objects to be checked Returns (dict): dictionary of mesh shells Usage: detectSeparateMeshes(pm.ls(sl=True)) ''' shells_group={} for obj in objs: verts = [pm.PyNode(obj.getShape().name() + '.vtx[%s]'%vert )for vert in range(0,obj.getShape().numVertices())] vertsLeft = verts[:] shells=[] for vert in verts: if vert in vertsLeft: shell = getShell(vert) vertsLeft = [vertex for vertex in vertsLeft if vertex not in shell] shells.append(shell) shells_group[obj.name()]=shells return shells_group def getShell(vertex, shell=[]): '''Returns the vert list of the shell connected to given vertex Args: vertex (pm.nt.MeshVertex): vertex to get shell from shell (list): internal array, not for external use Returns: (list): pm.nt.MeshVertex list of shell verts ''' if shell == []: shell=[] obj = vertex.node() shell.append(vertex) #get connected verts to current vert connected = pm.ls(vertex.connectedVertices(), fl=True) for connect in connected: #if the connected vert is not in the shell add it then run on it if connect not in shell: shell.append(connect) getShell(connect, shell=shell) return shell
from the list of selected components or components ID's, create a list of 'groups' that contain all the components that are connected to eachother.
and I paint the cow to have black spots,
return a list of vertices for black spot, in all the black spots
I wasn't doing things right at all. I ended up using the current vertex normal as my X axis, getting the next vertex position and subtracting the current vertex position, normalizing it, and using it for my Y axis, then Z was the cross product of X & Y, then set Y to be the cross of Z & X.
#=======================
import pymel.core as pm
def getVtxTfm(vtx):
pos = vtx.getPosition(space='world')
xVec = vtx.getNormal()
connectedVertNames = [ vert.name() for vert in vtx.connectedVertices() ]
nextVertName = "{0}.vtx[{1}]".format( vtx.node().name(), ( vtx.index() + 1) )
nextVert = pm.PyNode( nextVertName )
prevVertName = "{0}.vtx[{1}]".format( vtx.node().name(), ( vtx.index() - 1) )
prevVert = pm.PyNode( prevVertName )
if nextVertName in connectedVertNames:
yVec = ( nextVert.getPosition() - pos ).normal()
else:
yVec = -( prevVert.getPosition() - pos ).normal()
zVec = xVec.cross(yVec).normal()
yVec = zVec.cross(xVec)
mat = pm.datatypes.Matrix()
mat.a00 = xVec[0]
mat.a01 = xVec[1]
mat.a02 = xVec[2]
mat.a10 = yVec[0]
mat.a11 = yVec[1]
mat.a12 = yVec[2]
mat.a20 = zVec[0]
mat.a21 = zVec[1]
mat.a22 = zVec[2]
mat.a30 = pos[0]
mat.a31 = pos[1]
mat.a32 = pos[2]
tfm = pm.datatypes.TransformationMatrix( mat )
null = pm.spaceLocator()
null.setTransformation( tfm )
sel = pm.selected()
nodeName = sel[0].name()
for vtxID in sel[0].getVertices()[1]:
vertex = "{0}.vtx[{1}]".format( nodeName, vtxID )
vert = pm.PyNode(vertex)
getVtxTfm(vert)
#=======================
Thanks!
Kev