I have an xml file which contains a list of objects in space ("sectors") each sector has a list of more objects ("seats") which can be the same model or not. For each "sector" I create an object and for each seat in that sector I create a face (made up of 3 verts) from which a particle system will instantiate a mesh using its normal. Till here no issue, my problem arrives when I try to put each face (seat) into a vertex group which i create and which will contain all the faces "seats" representing each seat model.

I can`t manage to assign a list of vertices into a vertex group, I'been struggling with the vertex_group.add, it always returns me this error:

group.add(selected_verts, 1.0, 'ADD' )
AttributeError: 'bpy_prop_collection' object has no attribute 'add'

location: <unknown location>:-1

Here is the code, I hope it is more self explicatory than my description:

import bpy
import os
import bmesh
import math
import mathutils

from xml.etree import ElementTree
from bpy.props import StringProperty, BoolProperty
from bpy_extras.io_utils import ImportHelper
from bpy.types import Operator

def createMonkeyFromData(tree):

    for estadio in tree:
        #Create Venue parent
        O = bpy.data.objects.new('venue', None)

        for Sector in estadio.findall('Sector'):
            #Create Sector
            mesh = bpy.data.meshes.new('mesh')
            sector = bpy.data.objects.new(Sector.get('id'), mesh)
            bpy.context.scene.objects.active = sector
            bm = bmesh.new()

            total_seats = 0

            #Create Tiers
            tier = str(Sector.get('tier'))
            if bpy.data.objects.get(tier) is None:
                tier_O = bpy.data.objects.new(tier, None)
                tier_O.parent = O
                # Parent sector to venue empty
                sector.parent = tier_O

            for Seat in Sector:

                seat_type = str(Seat.get('prefab'))

                if 'px' in Seat.keys():
                    # Get Position Data
                    posX, posY, posZ = float(Seat.get('px')), float(Seat.get('py')), float(Seat.get('pz'))
                    rotX, rotY, rotZ = float(Seat.get('rx')), float(Seat.get('ry')), float(Seat.get('rz'))

                    #Total number of seats for each sector
                    total_seats = total_seats + 1
                    #Create vertex and face for each position and orient it
                    v1 = bm.verts.new((posX-0.01, posZ, posY-0.01))
                    v2 = bm.verts.new((posX+0.01, posZ, posY-0.01))
                    v3 = bm.verts.new((posX, posZ, posY+0.01))
                    f1 = bm.faces.new([v1,v2,v3])
                    vert_list = [v1,v2,v3]
                    mat_rot = mathutils.Matrix.Rotation(math.radians(-rotY), 3, 'Z')
                    bmesh.ops.rotate(bm, cent= (posX, posZ, posY), matrix = mat_rot, verts= vert_list)

                    selected_verts = [v.index for v in vert_list if v.select]


                    #Detect seat and create vertex group
                    if bpy.context.object.vertex_groups.get(seat_type) is None:
                        group = bpy.context.object.vertex_groups
                        group.add(selected_verts, 1.0, 'ADD' )


The vertex groups are created with no problems but vertices wont get assign to its corresponding group, any idea on what I'm missing?


As @sambler suggested I've tried selecting the vertices inside a loop but still not working, which is very strange because the script @sambler shared works fine. Right now the code has been updated like this:

                #Detect seat and create vertex group
                for v in f1.verts:
                  if bpy.context.object.vertex_groups.get(seat_type) is None:
                    group = bpy.context.object.vertex_groups.new(name=seat_type)
                    f1.select = True
                    group.add([v.index], 1.0, 'ADD' )

The group.add is not assigning the vertices to its vertex_group


Your group variable is the list of all groups, it needs to be a single group. Get the new group returned by groups.new() and use that.

group = bpy.context.object.vertex_groups.new(name=seat_type)

Then as you are using bmesh, the way to assign weights is different. We need to get the bmesh deform layer and use that with the group index to assign a weight to a bmesh vertex.

import bpy
import bmesh

obj = bpy.context.object

bm = bmesh.new()
dl = bm.verts.layers.deform.verify()

for x in range(4):
    for y in range(4):
        group = obj.vertex_groups.new(name=str(x)+'_'+str(y))
        v = bm.verts.new((x,y,0))
        v[dl][group.index] = 1.0

  • $\begingroup$ Just tried it and nothing happened, objects , vertex groups and vertices are created fine but vertices aren't assign to their vertex group. $\endgroup$ – Juan Manuel Lynch Sep 4 '18 at 9:49
  • $\begingroup$ Are you sure the get(seat_type) and selected_verts=... give the right results? As you create the new verts you aren't selecting them. This script creates a new group for each vertex and assigns the vertex to it. $\endgroup$ – sambler Sep 4 '18 at 15:48
  • $\begingroup$ get(seat_type) seems to me is not the problem as I tried it without it but still didn't work. I killed the selected_verts and did a loop but (which works selecting) but group.add still not working. Pleas see my edits on the question $\endgroup$ – Juan Manuel Lynch Sep 4 '18 at 17:09
  • $\begingroup$ @JuanManuelLynch I worked it out, assigning weights while using bmesh verts is different. $\endgroup$ – sambler Sep 5 '18 at 1:40
  • $\begingroup$ That was it!!!! you are my hero, thank you very much @sambler $\endgroup$ – Juan Manuel Lynch Sep 5 '18 at 17:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.