0
$\begingroup$

So I have two scripts, one that goes through the name of the vertex group and prints out each of that groups weight painting influence. Another script that goes into Edit Mode, and from the selected group it prints out its Vertex ID.

Both scripts print out the respected values to the console and I wipe the console each time I run the script.

Now I have gotten to a point where I am a bit stuck, I am wanting to automate this process because at the moment I need to do each step manually and this takes so much time. I currently have 109 vertex groups and manually output both of these these.

Does anyone know how I can go through each of my scripts and make it so the script will go through each of the specific bits of code, go through each group and automatically print the respected values I need, then output that file to a .txt document in a specified folder?

Thank you.

This code snippet prints out the vertex ID

import bpy
import bmesh

from os import system
cls = lambda: system('cls')

cls() #this function call will clear the console

obj=bpy.context.object
if obj.mode == 'EDIT':
    bm=bmesh.from_edit_mesh(obj.data)
    for v in bm.verts:
        if v.select:
            print(v.index)

This code snippet prints out the weight influence of that selected group.

import bpy

from os import system
cls = lambda: system('cls')

cls() #this function call will clear the console

# Which group to find all verts in?
groupName = ' '

# Use the active object
obj = bpy.context.active_object

# Ensure all values updated
bpy.ops.object.mode_set(mode='OBJECT',toggle=True)

# Store the mesh
mesh = obj.data

# Get all the verts
selVerts = [v for v in mesh.vertices]

# Get the index of the required group
indexVal = obj.vertex_groups[groupName].index

# Store the vertex and its weight together.
weights = []
for v in selVerts:      #loop over all verts
    for n in v.groups:      #loop over all groups with each vert
        if n.group == indexVal:     #check if the group val is the same as the index value of the required vertex group
            weights.append([v,n.weight])        #store the vertex and its weight in a nested list
            print(weights[-1][1])      #print the vertex index and its weight
$\endgroup$

2 Answers 2

0
$\begingroup$

do you want this?

import bpy

from os import system
cls = lambda: system('clear')

cls() #this function call will clear the console

filepath = bpy.context.scene.render.filepath
file = bpy.path.abspath(filepath) + "weights.txt"


wheightsFile = open(file, 'w')  # use 'a' to append

print("weights")
for obj in bpy.context.scene.objects:
    if obj.type == "MESH":
        
#        print("*"*10, obj.name)
        
        for vertexGroup in obj.vertex_groups:

            # Which group to find all verts in?
            groupName = vertexGroup.name
            
#            print("*"*5, groupName)
       
            # Store the mesh
            mesh = obj.data

            # Get all the verts
            selVerts = [v for v in mesh.vertices if v.select]

            # Get the index of the required group
            indexVal = obj.vertex_groups[groupName].index

            # Store the vertex and its weight together.
            weights = []
            for v in selVerts:      #loop over all verts
                for n in v.groups:      #loop over all groups with each vert
                    if n.group == indexVal:     #check if the group val is the same as the index value of the required vertex group
                        weights.append([v,n.weight])        #store the vertex and its weight in a nested list
                        print(weights[-1][1])      #print the vertex index and its weight
                        wheightsFile.write('%.2f\n' % (weights[-1][1]))
                        
wheightsFile.close()


file2 = bpy.path.abspath(filepath) + "indices.txt"

print("file2 is", file2)


a = open(file2, 'w')  # use 'a' to append
                        
print("indexes")                     
for obj in bpy.context.scene.objects:
    if obj.type == "MESH":
        
#        print("*"*10, obj.name)
        
        for vertexGroup in obj.vertex_groups:

            # Which group to find all verts in?
            groupName = vertexGroup.name
            
#            print("*"*5, groupName)
       
            # Store the mesh
            mesh = obj.data

            # Get all the verts
            selVerts = [v for v in mesh.vertices if v.select]

            # Get the index of the required group
            indexVal = obj.vertex_groups[groupName].index

            # Store the vertex and its weight together.
            weights = []
            for v in selVerts:      #loop over all verts
                for n in v.groups:      #loop over all groups with each vert
                    if n.group == indexVal:     #check if the group val is the same as the index value of the required vertex group
                        weights.append([v,n.weight])        #store the vertex and its weight in a nested list
                        print(v.index)      #print the vertex index and its weight
                        a.write('%.2f\n' % (v.index))


a.close()

result:

enter image description here

enter image description here

$\endgroup$
2
  • $\begingroup$ Sadly not, it does to part of what I am wanting though. I am only wanting it to list the weights and indices of the selected mesh, not everything in the scene. I am also wanting the weights and vertex ID's printing out as two separate lists and being outputted as text files, not in the console. It is kind of there but something I can try and test with. $\endgroup$
    – A.cullcarr
    Commented Dec 13, 2021 at 12:50
  • $\begingroup$ i updated my answer again. Now it writes two text files in your output directory you specified in render settings $\endgroup$
    – Chris
    Commented Dec 13, 2021 at 13:18
0
$\begingroup$

You seem to be doing excessive work for what you are trying to accomplish.

Since you didn't specify how you want the file identified, I've written a function that takes the filename as an argument. It also allows you to specify which object to run the code on. Here's an example using the active object and writing to a file stored in the Windows temporary folder:

import bpy

printgroups(bpy.context.active_object)

def writegroups(object, filename):
    if not object:
        return
    if object.type != 'MESH':
        return
    file = open(filename, "w")
    vertex_count = len(object.data.vertices)
    for group in object.vertex_groups:
        file.write(f"{group.name}\n")
        for index in range(vertex_count):
            try:
                w = g.weight(index)
                file.write(f"{index}, {g.weight(index)}\n")
            except RuntimeError:
                pass
    file.close()
    return

writegroups(bpy.context.active_object, r'C:\tmp\somefile.txt')

You don't need bmesh for this, as all of the information is available in the object. Simply change the arguments to writegroups to an appropriate object and file name. You don't need the 'r' in front of the filename string on other OSes, but it makes the string "raw" so that the backslash characters aren't interpreted as string escape characters, so you can use the '\' directly in a Windows file path.

I didn't place any error handling on the open. You may want to enclose it in a try/except block in case you pass a file name that can't be created. Change the "w" to an "a" if you want to append to an existing file.

$\endgroup$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .