Results 1 to 12 of 12

Thread: Getting vertices of a vertex group from within Python

  1. #1
    Member
    Join Date
    Jul 2006
    Location
    California, USA
    Posts
    233

    Getting vertices of a vertex group from within Python

    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:

    Code:
    >>> 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?



  2. #2
    Member
    Join Date
    Dec 2011
    Location
    Germany
    Posts
    3,991
    you can either access vertex groups via

    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)



  3. #3
    Member
    Join Date
    Jul 2006
    Location
    California, USA
    Posts
    233
    Originally Posted by CoDEmanX View Post
    you can either access vertex groups via

    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)
    Thanks for the help, but this seems to just get the group itself. I want a list of the vertices in the group.



  4. #4
    Member
    Join Date
    Jul 2006
    Location
    California, USA
    Posts
    233
    I suppose I could do something like the following:

    Code:
    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.



  5. #5
    Member
    Join Date
    Dec 2011
    Location
    Germany
    Posts
    3,991
    maybe like this?
    Code:
    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)



  6. #6
    Member PKHG's Avatar
    Join Date
    Sep 2009
    Location
    NL
    Posts
    1,928
    Originally Posted by CoDEmanX View Post
    maybe like this?
    Code:
    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) ???



  7. #7
    Member
    Join Date
    Dec 2011
    Location
    Germany
    Posts
    3,991
    Well, you could do:

    Code:
    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.
    Last edited by CoDEmanX; 13-Dec-14 at 07:45.



  8. #8
    Member PKHG's Avatar
    Join Date
    Sep 2009
    Location
    NL
    Posts
    1,928
    Thanks CoDEmanX,

    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?

    Yes this gives me the solution!

    VERY BIG THANKS.
    Peter
    Last edited by PKHG; 07-Dec-14 at 05:29. Reason: WORKS!



  9. #9
    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?Blender Question.PNG This first image shows what I'd like to select.
    Blender Question Current Script Result.PNG This second picture is what I'm currently seeing after running the script.
    Thanks so much in advance for any help that will follow.



  10. #10
    Member PKHG's Avatar
    Join Date
    Sep 2009
    Location
    NL
    Posts
    1,928
    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



  11. #11
    Member
    Join Date
    Dec 2011
    Location
    Germany
    Posts
    3,991
    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.



  12. #12
    A lot of work was put into this answer here:

    http://blender.stackexchange.com/a/75240/28015

    You may be interested...I even added some performance graphs comparing the three methods in the answer.
    "Through wisdom is an house builded; and by understanding it is established:"
    - Proverbs 24:3



Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •