1
$\begingroup$

I'm using Blender for an unusual purpose (research) so my issue is probably a bit unusual, and Blender was likely not designed with the flexibility that I may need.

I need to calculate the volume of a bunch of segments of an object. Unfortunately, the only way I have come up with that allows me to do this involves an insane amount of operators, and I need to calculate the volume of ~18 segments in each of a few thousand similar objects. Because the operators will make the loop run very slowly, I would like to know how to replace as many of the operators in the below code with their bmesh equivalences. Although I'm using cylinders here, the models for my actual work are much more detailed, and so a simple equation cannot be used to calculate their volumes. I do not need to keep the model around, so once the volume estimates are calculated from the models, the object is deleted. The below is just an example for one model; you can understand why doing this thousands of times would be terribly slow.


# these are the vertex groups corresponding to the circles in a cylinder with 4 different segments
VGs =['Group', 'Group.001', 'Group.002', 'Group.003', 'Group.004']


for i in range(4):
    bpy.data.objects['Cylinder'].select_set(True) # select the original object
    bpy.context.view_layer.objects.active = bpy.data.objects['Cylinder']        
    bpy.ops.object.mode_set(mode='EDIT')
    bpy.ops.mesh.select_all(action='DESELECT') # deselect any other VGs
    bpy.ops.object.vertex_group_set_active(group=VGs[i]) # make the VG at one end of the segment active
    bpy.ops.object.vertex_group_select() 
    bpy.ops.object.vertex_group_set_active(group=VGs[i+1]) # make the VG at the other end of the segment active
    bpy.ops.object.vertex_group_select() 
    bpy.ops.mesh.duplicate() # copy the new smaller cylinder
    bpy.ops.mesh.separate(type='SELECTED') # make it its own object
    bpy.ops.object.mode_set(mode='OBJECT') 
    bpy.ops.object.select_all(action='DESELECT')
    bpy.context.view_layer.objects.active=bpy.context.window.scene.objects[-1] # select the most recently added cylinder
    bpy.context.active_object.select_set(state=True) 
    bpy.ops.object.mode_set(mode='EDIT')
    bpy.ops.mesh.select_all(action='SELECT')
    bpy.ops.mesh.edge_face_add() # filling in missing face necessary to calculate volume correctly
    bpy.ops.mesh.remove_doubles() # remove extra vertices to calculate volume correctly
    bpy.ops.object.mode_set(mode='OBJECT')
    bm=bmesh.new() 
    depsgraph1=bpy.context.evaluated_depsgraph_get() 
    bm.from_object(bpy.context.active_object, depsgraph1) # make a mesh from the object
    bm.calc_volume() # get volume
    bm.free()
    bpy.context.active_object.select_set(state=False) # deselect object for next loop

I believe that some of these operators have no lower-level analogs, but I know that there must be a way to convert many of them using bmesh functions; I simply cannot figure out how to do it from the helpfiles and other similar questions.

Any help would be greatly appreciated.

$\endgroup$

Your Answer

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

Browse other questions tagged or ask your own question.