1
$\begingroup$

I would like to loop through meshes in my Scene Collection to find the coordinates of Verts (single points added via Add Mesh Extra Objects addon) or the volume of a mesh (the default Cube). I have code that will do each of these things separately, but when run together, the code which returns the coordinates of the single Vert instead returns the coordinates of the Cube's vertices. I'm new to Blender and appreciate any help figuring out what the API is doing here.

Based on Batfinger's feedback (Select Meshes from Scene Collection without relying on name) this code prints the coordinates of a Vert:

import bmesh
import bpy

for i in bpy.context.scene.objects:
    if i.type == 'MESH' and len(i.data.vertices) == 1:
        print(i.name, i.type)
        # Get the active mesh
        obj = bpy.context.edit_object

        me = obj.data

        # Get a BMesh representation
        bm = bmesh.from_edit_mesh(me)

        for v in bm.verts:
            print("vert location", v.co)
        pass

This code prints the volume of the Cube (has to be selected):

import bmesh
import bpy

for i in bpy.context.scene.objects:
    if i.type == 'MESH' and len(i.data.vertices) > 1:
        print(i.name, i.type)
            
        #Get mesh data from the active object in the Scene Collection
        me = bpy.context.object.data

        #Create an empty BMesh
        bm = bmesh.new()
        #Fill Bmesh with the mesh data from the object  
        bm.from_mesh(me)

        print('Volume:', bm.calc_volume(signed=False))
        bm.free()

However, when I combine the two statements, the Vert loop now prints the coordinates of the vertices from the Cube and not the Vert:

import bmesh
import bpy

#Vert loop
for i in bpy.context.scene.objects:
    if i.type == 'MESH' and len(i.data.vertices) == 1:
        print(i.name, i.type)
        # Get the active mesh
        obj = bpy.context.edit_object

        me = obj.data

        # Get a BMesh representation
        bm = bmesh.from_edit_mesh(me)

        for v in bm.verts:
            print("vert location", v.co)
        bm.free()
        pass

#Volume loop
for i in bpy.context.scene.objects:
    if i.type == 'MESH' and len(i.data.vertices) > 1:
        print(i.name, i.type)
            
        #Get mesh data from the active object in the Scene Collection
        me = bpy.context.object.data

        #Create an empty BMesh
        bm = bmesh.new()
        #Fill Bmesh with the mesh data from the object  
        bm.from_mesh(me)

        print('Volume:', bm.calc_volume(signed=False))
        bm.free()

Results in:

Vert MESH
vert location <Vector (1.0000, 1.0000, 1.0000)>
vert location <Vector (1.0000, 1.0000, -1.0000)>
vert location <Vector (1.0000, -1.0000, 1.0000)>
vert location <Vector (1.0000, -1.0000, -1.0000)>
vert location <Vector (-1.0000, 1.0000, 1.0000)>
vert location <Vector (-1.0000, 1.0000, -1.0000)>
vert location <Vector (-1.0000, -1.0000, 1.0000)>
vert location <Vector (-1.0000, -1.0000, -1.0000)>
Cube MESH
Volume: 7.999999999999999
$\endgroup$
0
$\begingroup$

Your scripts are incorrect, you are ignoring scene objects and repeatedly printing data for the active object instead.

In both cases you are looping over scene objects with

for i in bpy.context.scene.objects:

Then you proceed to ignore them all by defining an "active object" with either obj = bpy.context.edit_object or me = bpy.context.object.data rather than iterate over i from the loops.

It should probably be something like me = i.data.

$\endgroup$
1
  • $\begingroup$ That did the trick, thank you helping out a n00b. :) $\endgroup$ – Marike Jul 27 '20 at 17:39

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.