I'll admit, dictionaries are not my strong point, and I could use a little help ;)
I'm looping through a dictionaries values, to find a particular value. If it doesn't find the value, okay fine. But if it does find the value, I need the key the value belongs to.
#=============================
import pymel.core as pm
from itertools import chain
sel = pm.ls(sl=1, fl=True)
connectedVertGroups = {}
vertGroups = {}
for i, vtx in enumerate(sel):
if vtx not in chain( *connectedVertGroups.values() ):
connectedVerts = [ vert for vert in vtx.connectedVertices() ]
connectedVerts.append(vtx)
connectedVertGroups["group_{0}".format(i)] = connectedVerts
vertGroups["group_{0}".format(i)] = vtx
else:
'''
TODO - Get the Key in connectedVertGroups that vtx belongs to, and add connected verts to it if they're not already in it. verify it's also in the correct vertGroup key.
'''
connectedVerts = [ vert for vert in vtx.connectedVertices() if vert not in connectedVertGroups.values() ]
#===========================
Thx
Kev
I think this works for me:
vtxKey = next((key for key, value in connectedVertGroups.iteritems() if value == vtx), None)
The only problem I'm having is that my dictionary values are a list of vertices, and I need to check for a vertex within those lists.
Do you have any suggestions for getting passed that? I was able to use chain(*) when checking the dictionary values directly, but it doesn't seem to work when I'm using dict.iteritems(). chain(*dict.iteritems()) or chain(*dict.items()) - too many items to unpack.
Kev
How about a loop?
awesome_verts = list()
for name, group in connectedVertGroups.iteritems():
for vertex in group:
if vertex is 'Awesome':
awesome_verts.append(vertex)
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/7246e089-a231-4297-9e81-27e676b1dfb6%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
import pymel.core as pm
sel = pm.ls(sl=1, fl=True)
connectedVertGroups = {}
vertGroups = {}
for i, vtx in enumerate(sel):
vtxKey = next((key for key, vtx_list in connectedVertGroups.iteritems() if vtx in vtx_list), None)
if vtxKey is None:
connectedVerts = [ vert for vert in vtx.connectedVertices() ]
connectedVerts.append(vtx)
connectedVertGroups["group_{0}".format(i)] = connectedVerts
vertGroups["group_{0}".format(i)] = vtx
--
You received this message because you are subscribed to a topic in the Google Groups "Python Programming for Autodesk Maya" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/python_inside_maya/_K5kHFAEXjo/unsubscribe.
To unsubscribe from this group and all its topics, 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/CAFRtmOAXxCMuYbPfbvX_%3D0BM-pKVciXSXr51V5qqenU2cKDNKA%40mail.gmail.com.
I feel so useless, but this is really helping me understand dictionaries. I was figuring those loops could be reduced.
I'll admit I'm kinda lost now in the code. It seems that "vtxKey" is returning a vertex, and not the dictionary key.
What i'll need to do is if that vtx does exist in the list of vertices that are my values in the keys of connectedVertGroups. append the vtx to the the same dictionary key, value list in vertGroups.
in the end, the keys for vertGroups, will contain all the vertices in my selection that are connected to eachother.
i.e If I select verts 1,2,3,4,5,50,51,52,53,54
vertGroups will have two keys. the first key's value would be [1,2,3,4,5] and the second key's value woud be [50,51,52,53,54]
import pymel.core as pm
sel = pm.ls(sl=1, fl=True)
connectedVertGroups = {}
vertGroups = {}
for i, vtx in enumerate(sel):
vtxKey = next((key for key, vtx_list in connectedVertGroups.iteritems() if vtx in vtx_list), None)
connectedVerts = [ vert for vert in vtx.connectedVertices() ]
connectedVerts.append(vtx)
if vtxKey is None:
connectedVertGroups["group_{0}".format(i)] = connectedVerts
vertGroups["group_{0}".format(i)] = vtx
else:
connectedVertGroups[vtxKey] = connectedVertGroups[vtxKey].append( connectedVerts )
vertGroups[vtxKey] = vertGroups[vtxKey].append( vtx )
--
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/239e371c-bfef-4fe0-afcb-9880c64f639f%40googlegroups.com.
#==============================
import pymel.core as pm
sel = pm.ls(sl=1, fl=True)
connectedVertGroups = {}
vertGroups = {}
for i, vtx in enumerate(sel):
vtxKey = next((key for key, vtx_list in connectedVertGroups.iteritems() if vtx in vtx_list), None)
connectedVerts = [ vert for vert in vtx.connectedVertices() ]
connectedVerts.append(vtx)
if vtxKey is None:
connectedVertGroups["group_{0}".format(i)] = connectedVerts
vertGroups["group_{0}".format(i)] = vtx
else:
connectedVertList = connectedVertGroups.get(vtxKey)
connectedVertList.append( connectedVerts )
vertList = list(vertGroups.get(vtxKey))
vertList.append( vtx )
connectedVertGroups[vtxKey] = connectedVertList
vertGroups[vtxKey] = vertList
#=============================
I'm gonna have to think about that one for a while. I can't say I fully understand what chain does. All I know is that sometimes, when I have nested lists or what not, it works for me. haha. I guess it's time to get smarter. You can laugh ;)
Cheers!
I still need to test it a bit, but I think this gets me what I'm after. Thanks guys for holding my hand through it.
btw, how are you guys nicely formatting your code? are there no <code> tags?
#=================================
import pymel.core as pm
from itertools import chain
sel = pm.ls(sl=1, fl=True)
connectedVertGroups = {}
vertGroups = {}
for i, vtx in enumerate(sel):
vtxKey = next((key for key, vtx_list in connectedVertGroups.iteritems() if vtx in vtx_list), None)
connectedVerts = [ vert for vert in vtx.connectedVertices() ]
connectedVerts.append(vtx)
if vtxKey is None:
connectedVertGroups["group_{0}".format(i)] = connectedVerts
vertGroups["group_{0}".format(i)] = vtx
else:
connectedVertList = list( set( connectedVertGroups.get(vtxKey) ) )
connectedVertList = connectedVertList + [ vert for vert in connectedVerts ]
vertList = list(vertGroups.get(vtxKey))
vertList.append( vtx )
connectedVertGroups[vtxKey] = connectedVertList
vertGroups[vtxKey] = vertList
#===============================
Kev
Ah-ha. I was appending a list to the list of connectedVerts.
I still need to test it a bit, but I think this gets me what I'm after. Thanks guys for holding my hand through it.
btw, how are you guys nicely formatting your code? are there no <code> tags?
#=================================
import pymel.core as pm
from itertools import chain
sel = pm.ls(sl=1, fl=True)
connectedVertGroups = {}
vertGroups = {}
for i, vtx in enumerate(sel):
vtxKey = next((key for key, vtx_list in connectedVertGroups.iteritems() if vtx in vtx_list), None)
connectedVerts = [ vert for vert in vtx.connectedVertices() ]
connectedVerts.append(vtx)
if vtxKey is None:
connectedVertGroups["group_{0}".format(i)] = connectedVerts
vertGroups["group_{0}".format(i)] = vtx
else:
connectedVertList = list( set( connectedVertGroups.get(vtxKey) ) )
connectedVertList = connectedVertList + [ vert for vert in connectedVerts ]
vertList = list(vertGroups.get(vtxKey))
vertList.append( vtx )
connectedVertGroups[vtxKey] = connectedVertList
vertGroups[vtxKey] = vertList
#===============================
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/6cf4e066-9ca3-46fd-a734-7253d8876834%40googlegroups.com.
I now understand what you are trying to achieve. You want to group selections of vertices that are connected.
The approach you were using had the caveat that you would need to select the verts in connected order otherwise it was possible to have orphaned ones that should be grouped (I fixed your code, tried it out and found this).
Here is another way of doing it, I basically grab a single selected vert, look if any of the verts around it are in our selection list, if they are, add it to the group and add its connected verts to a list of verts surrounding the group, growing the group one vert at a time. If there aren’t any verts in the selection list that are on the edge of the group we can make a new group.
import pymel.core as pm
unmatched_vtxs = pm.ls(sl=1, fl=True)
vtx_grps = []
while len(unmatched_vtxs) > 0:
# grab a vertex
vtx = unmatched_vtxs.pop()
vtx_grps.append([vtx])
# create a list that will contain all of the vertices around the edge of the group, starting with all of the connected verts for the start vert
edge_vtxs = [v for v in vtx.connectedVertices()]
matched_vtx = vtx
# continue to try to find more verts to add to the group if we add a new vert, if not we can loop to the creating the next group
while matched_vtx is not None:
matched_vtx = None
for unmatched_vtx in unmatched_vtxs:
if unmatched_vtx in edge_vtxs:
matched_vtx = unmatched_vtx
# if one of the unmatched verts is on the edge of our group add it to the group
vtx_grps[-1].append(matched_vtx)
# remove it from the edge list
edge_vtxs.remove(matched_vtx)
# add all of the new matched verts connected verts if they aren't already in the list
for added_conn_vtx in matched_vtx.connectedVertices():
if added_conn_vtx not in edge_vtxs:
edge_vtxs.append(added_conn_vtx)
break
# remove the matched vert from our list of unmatched ones
if matched_vtx is not None:
unmatched_vtxs.remove(matched_vtx)
print vtx_grps
This is pretty slow in python for big selections as it runs in polynomial time, it might be more useful as a command C++ plugin.
I bet this will see a substantial performance increase if done using maya.cmds. Iterating over large sets isn’t a task well suited for PyMEL.
--
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/CAOz4VE1_eYp1_Jz21tZSsysD7ApjAZ_cX_adWGXYmfhHO2CDTw%40mail.gmail.com.
I noticed that yesterday when playing around with it a bit. In certain cases, it would give me some extra groups, depending on how I selected the verts. It makes sense.
I'm gonna have to pick apart your code to understand it a bit better. I had a feeling this stuff was gonna be fairly slow. It will lend itself to a rigging workflow, where someone can select whatever components, and build nulls and whatnot at the computed transform of those vert groups. It shouldn't ever really receive that many components, and the component selections can be simplified to speed it up a bit.
I'd love to see the speed of something similar written with maya.cmds. or even mel. I guess I veered towards pymel, since coming from softimage. Can't say i'd get very far with cmds ;)
Thanks for all your help
Kev
def test4():
unmatched_vtxs = cmds.ls(sl=True, fl=True)
vtx_grps = []
while len(unmatched_vtxs) > 0:
# grab a vertex
vtx = unmatched_vtxs.pop()
grp = [vtx]
vtx_grps.append(grp)
# create a list that will contain all of the vertices around
# the edge of the group, starting with all of the connected
# verts for the start vert
edge_vtxs = set(connectedVertices(vtx))
matched_vtx = vtx
# continue to try to find more verts to add to the group if we
# add a new vert, if not we can loop to the creating the next group
while matched_vtx is not None:
matched_vtx = None
for unmatched_vtx in unmatched_vtxs:
if unmatched_vtx in edge_vtxs:
matched_vtx = unmatched_vtx
# if one of the unmatched verts is on the edge of
# our group add it to the group
grp.append(matched_vtx)
# remove it from the edge list
edge_vtxs.remove(matched_vtx)
# add all of the new matched verts connected verts if
# they aren't already in the list
for added_conn_vtx in connectedVertices(matched_vtx):
if added_conn_vtx not in edge_vtxs:
edge_vtxs.add(added_conn_vtx)
break
# remove the matched vert from our list of unmatched ones
if matched_vtx is not None:
unmatched_vtxs.remove(matched_vtx)
return vtx_grps
def connectedVertices(vtx):
edges = cmds.polyListComponentConversion(vtx, fv=True, te=True)
vtxs = cmds.polyListComponentConversion(edges, fe=True, tv=True)
return cmds.ls(vtxs, fl=True)
--
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/67a6844f-8682-4ac4-b895-fa5c25e60ab3%40googlegroups.com.
Kev
Fo' sho'
Anytime you see a for/while loop in there with many inner PyMel calls, it probably could benefit from testing a cmds or api variation