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:
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.
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
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")
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
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.
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)
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])