I’ve been trying to get all the verices from vertex groups from within the Python API. I created a vertex group for the default Cube in 3D view and then entered the following code in the Python console:
>>> a = bpy.data.objects["Cube"]
>>> a
bpy.data.objects['Cube']
>>> a.vertex_groups
bpy.data.objects['Cube'].vertex_groups
>>> a.vertex_groups["Group"]
bpy.data.objects['Cube']...VertexGroup
>>> a.vertex_groups.keys()
['Group']
>>> a.vertex_groups["Group"]
bpy.data.objects['Cube']...VertexGroup
>>> a.vertex_groups["Group"][0]
Traceback (most recent call last):
File "<blender_console>", line 1, in <module>
TypeError: this type doesn't support IDProperties
>>> a.vertex_groups["Group"].keys()
Traceback (most recent call last):
File "<blender_console>", line 1, in <module>
TypeError: bpy_struct.keys(): this type doesn't support IDProperties
>>> a.vertex_groups["Group"].keys
<built-in method keys of VertexGroup object at 0x000000000AF6CF08>
>>> a.vertex_groups["Group"].keys(0)
Traceback (most recent call last):
File "<blender_console>", line 1, in <module>
TypeError: keys() takes no arguments (1 given)
I don’t understand why a.vertex_groups.keys returns a message saying that it is a built in method, but when I actually call keys(), I get an error. How do I get a list of vertices of a vertex group from within Python?
bpy.context.object.data.vertices[#].groups (use groups[#].group to get the vertex_group[index!])
or via
bpy.context.object.vertex_groups (vertex_groups[0].name for instance, weight can only be looked via the method weight(), which may result in a RuntimeError if the requested vertex isn’t in the group)
I suppose I could do something like the following:
def get_vertices_in_group(a,index):
# a is a Blender object
# index is an integer representing the index of the vertex group in a
vlist = []
for v in a.data.vertices:
for g in v.groups:
if g.group == index:
vlist.append(v.index)
return vlist
but it would be more convenient if there was already a function that would get all the vertices of a vertex group.
ob = bpy.context.object
group_lookup = {g.index: g.name for g in ob.vertex_groups}
verts = {name: [] for name in group_lookup.values()}
for v in ob.data.vertices:
for g in v.groups:
verts[group_lookup[g.group]].append(v.index)
CoDEmanX , this I should have known yesterday … very nice way accessing vertex_groups
With respect to this I have a question:
I have an object with a group op vertices selected and want to assign these to a vertex_group of the object.
The vertex_group is already set to active
(e.g. object.vertex_groups.active_index = to_list.index(to_groep_name) and in edit mode that group is indeed selected)
BUT I can not assign it via Python : bpy.ops.object.vertex_group_assign() seems not to be possible ???
Forgotten by the implementors?
Select and Deselect commands are schown (bpy.ops.object.vertex_group_select()
bpy.ops.object.vertex_group_deselect() )
but presseing Assign or Remove are done but not shown (in the … window of Blender, opened above the View3D) ???
import bpy
ob = bpy.context.object
me = ob.data
is_editmode = me.is_editmode
vgroup = ob.vertex_groups["Group"]
if is_editmode:
ctx = bpy.context.copy()
ctx["object"] = ob
bpy.ops.object.editmode_toggle(ctx)
vgroup.add([v.index for v in me.vertices if v.select], 1.0, 'REPLACE')
if is_editmode:
bpy.ops.object.editmode_toggle(ctx)
It’s unfortunately not possible without mode switching.
Hmm, I see only one mesh: ob. I have two meshes, identical vertices, edges, faces, both with vertex_groups, one filled one yet not filled
Say mesh one has group Head, with assigned vertices, and now I want the same vertices assigned in the other mesh with group say
MyHead …
Have to see if your suggestion will help me, in the ‘vgroup.add’ the list could be computed from mesh one and the vgroup be a vertex_group of the second mesh , named MyHead …
Will try
Thanks! The hint is the line vgroup.add … with its parameters, am I right?
Thank you for directing me here PKHG. I’m new to blender and I think I’m doing something wrong here. When I run this script it’s flipping to object mode and selecting the entire object. Is there a way to use this code to select a given vertex group (Top Group) and have it remain selected in edit mode so that I can modify it? Then along those same lines, select Bottom Group as a secondary command after the Top Group’s modification is complete?
Hm … in my attempts to use vgroup.add all works like I want.
So put the code you use in code and /code with [ ] around them to see what is not as expected using YOUR code, will have a look at that and trying to …
Greets
PETER
My bad, if you start in edit mode me.is_editmode will be True and script toggles to object mode in order to assign weights. The toggling back at the end of the script won’t work however, because me.is_editmode is checked again, but of course is now False and thus skipped. Updated my script to store initial is_editmode state.