Python Code to export scene data to .TXT

Total noob here…

I need to write a python script that exports the object data, mesh data, and qty into a .txt file. This would need to capture every object in the scene. So for a scene with 3 cubes and 2 torus, something like this format:

(Quantity), (Object Name), (Mesh Data)
3, Cube, CubeMeshxx
2, Torus, TorusMesh569

Is this easy? Any suggestions on how to accomplish this?

Why do you need it in a txt? if you aren’t a dev I imagine something you are using is expecting a specific txt format?

Also what exactly is “Mesh Data”

1 Like

Mesh name is what i meant to say.

The goal is to index this information so it can be plugged into an order and expense sheet. With this information in .txt format we can automate from design(Blender file) to ordering.

What QTY mean ?

import bpy

for ob in bpy.context.scene.objects :
   if ob.type != "MESH" : continue
   print(ob.name, ob.data.name)

this will help you to get started and print the information in the console.
You can look for information about writing to text files with python, it shouldn’t be too complicated

Qty is quantity

Thank you!

Quantity of what ?
Do you mean objects sharing the same mesh data ?

1 Like

Yeah im not certain either, here is another take on the code that might help them piece it together.

import bpy

objects = {}
identifiers = set([obj.name.split('.')[0] for obj in bpy.context.scene.objects if obj.type == 'MESH'])

for identifier in identifiers:
    objects[identifier] = len([obj for obj in bpy.context.scene.objects if identifier in obj.name])
    
with open('/tmp/test.txt', 'w+') as f:
    for name, count in objects.items():
        f.write(f"{name} {count}\n")

Turns this
892DRNKzRy

in to this
notepad_G0IKckHx6I

2 Likes

Very correct, sorry for not being specific. Quantity would reflect the number of objects sharing the same mesh data/name.

Your example is perfect, it would just need to include the mesh name in addition.

@LordOdin

Unfortunately your solution is based on a faulty assumption:

Object names are not required to be remotely similar to eachother while sharing the same mesh data block. In the below image each different colored object is a unique mesh data but the same objects are linked data. Notice the 3rd pink cube object name does not contain “cube” at all.

Furthermore just because an object name is similar “cube.001” and “cube.002” does not mean they share the same mesh data

More accurate base data can be achieved by:

import bpy

list_names = [[ob.name, ob.data.name] for ob in bpy.data.objects]

values = set(map(lambda mesh:mesh[1], list_names))
newlist = [[ob[0] for ob in list_names if ob[1]==mesh] for mesh in values]

for x, m_name in enumerate(values):
    print(f'Mesh data name: {m_name}')
    print(f'Linked to object qty: {len(newlist[x])}')
    for ob_name in newlist[x]:
        print(f'\t Object name: {ob_name}')

Providing the following output to console:

Mesh data name: Sphere
Linked to object qty: 4
         Object name: Sphere
         Object name: Sphere.001
         Object name: Sphere.002
         Object name: Sphere.003
Mesh data name: Cube.001
Linked to object qty: 3
         Object name: Cube.002
         Object name: Cube.003
         Object name: me
Mesh data name: Sphere.001
Linked to object qty: 1
         Object name: Sphere.004
Mesh data name: Cube
Linked to object qty: 2
         Object name: Cube
         Object name: Cube.001

Given the limited detail regarding output format in the original post I won’t bother setting up a text file output function as yours seems fine.

1 Like

After re-reading original post output format was provided and as such script would look more like:

import bpy
from string import Template

list_names = [[ob.name, ob.data.name] for ob in bpy.data.objects]
values = set(map(lambda mesh:mesh[1], list_names))
newlist = [[ob[0] for ob in list_names if ob[1]==mesh] for mesh in values]
filename = "C:\\tmp\\test.txt"

def output(fname, to_file=False):
    s = Template("${qty}, ${o_names}, ${m_name}")
    if not to_file:
        print(s.substitute(qty="Qty", o_names="Object Names", m_name="Mesh Name"))
        for x, m_name in enumerate(values):
            print(s.substitute(qty=f'{len(newlist[x])}', o_names=f'{newlist[x]}', m_name=f'{m_name}'))
    else:
        with open(fname, 'w+') as f:
            f.write(s.substitute(qty="Qty", o_names="Object Names", m_name="Mesh Name") + "\n")
            for x, m_name in enumerate(values):
                f.write(s.substitute(qty=f'{len(newlist[x])}', o_names=f'{newlist[x]}', m_name=f'{m_name}') + "\n")

output(filename, to_file=True)

providing output of:

Qty, Object Names, Mesh Name
2, [‘Cube’, ‘Cube.001’], Cube
1, [‘Sphere.004’], Sphere.001
4, [‘Sphere’, ‘Sphere.001’, ‘Sphere.002’, ‘Sphere.003’], Sphere
3, [‘Cube.002’, ‘Cube.003’, ‘me’], Cube.001

1 Like

Instead of looping over all objects you can loop over all meshes :

import bpy

mesh_map = {
    mesh: [o for o in bpy.data.objects if o.data == mesh] 
    for mesh in bpy.data.meshes
}

for mesh, objects in mesh_map.items():
    print(len(objects), mesh.name, [o.name for o in objects])

Output :

3 Cube ['Cube', 'Cube.001', 'Cube.002']
2 Icosphere ['Icosphere', 'Icosphere.001']
2 Suzanne ['Suzanne', 'Suzanne.001']
1 Like