Select similar objects by number of vertices?

Does a script or add-on exist that can select objects based on number of vertices in the selected object? I’ve got a snippet that does volume but it fails on flat objects. My scene is made up of many leaves and flower parts all sharing the same material.

All my searching turns up solutions for edit mode, on the same object. I’m looking for something that will work in object mode.

Do you really need to go to edit mode?
You can see how many vertices an object has by:

len(bpy.data.objects[‘Your_Object’].data.vertices)

then is just a matter of comparing it between objects.

I’d like to avoid edit mode.

Since I have lots of objects I need to organize I was looking for something to save lots and lots of clicking to select different objects. For example, all leaves have 5 or 6 vertices, but they’re different scales/sizes so area wouldn’t work so well.

you can get the area in object mode…

area = sum([poly.area for poly in bpy.data.objects[‘Your_Object’].data.polygons])

:wink:

Is it possible to select objects that have N number of vertices?

This should work off of active object.

import bpy


active_object = bpy.context.active_object
active_verts = len(active_object.data.vertices)


for all_objects in bpy.context.scene.objects:
    if all_objects.type == 'MESH':
        all_objects_verts = len(all_objects.data.vertices)           
        if all_objects_verts == active_verts:
            all_objects.select = True
1 Like

That’s perfect, thanks!

Can you please update this one for 2.8? Thanks

1 Like
2 Likes

Thanks! I was sure I missed it.

Updated for 2.80:

import bpy

active_object = bpy.context.view_layer.objects.active
active_verts = len(active_object.data.vertices)

for all_objects in  bpy.context.view_layer.objects:
    if all_objects.type == 'MESH':
        all_objects_verts = len(all_objects.data.vertices)           
        if all_objects_verts == active_verts:
            all_objects.select_set(state = True)```
3 Likes

You need to remove the ``` at the end for it to work.

Thanks Jakro!

1 Like

Thanks, I made a mistake with the code snippet :slight_smile:

Thank you for the nice code snippet. Is it possible to add additional paramenters like object dimensions? In this way you could make the selection more accurate.

import bpy

active_object = bpy.context.active_object
active_verts = len(active_object.data.vertices)
active_dimensions = active_object.dimensions

for obj in bpy.context.view_layer.objects:
    if obj.type == 'MESH':
        obj_verts = len(obj.data.vertices)           
        if obj_verts == active_verts and obj.dimensions == active_dimensions:
           obj.select_set(state = True)
1 Like

Thank you.

I’m not that good in python. How would you implement a “dimensions tolerance factor” value to your code?

So you could search for all objects that are inbetween a plus/minus range value of the active one.

Thank you!

Sure it should be pretty straightfoward. Let’s say we have an epsilon of 0.05 (+/- 5 %).
Now we could do it different ways, either calculating the volume of the bounding box of the object :

epsilon = 0.05
active_bbox_volume = active_object.dimensions[0] * active_object.dimensions[1] * active_object.dimensions[2]
current_bbox_volume = obj.dimensions[0] * obj.dimensions[1] *  obj.dimensions[2]
is_volume_in_range = abs((current_bbox_volume - active_bbox_volume) / active_bbox_volume ) < epsilon

or checking each individual dimension axis against the starting dimensions :

is_each_dimension_in_range = all(
    abs((obj.dimensions[i] - active_object.dimensions[i]) / active_object.dimensions[i]) < epsilon
    for i in range(3)
)

So injected in the script : (pick the one condition you want or mix them together)

import bpy

epsilon = 0.05
active_object = bpy.context.active_object
active_verts = len(active_object.data.vertices)
dim_x, dim_y, dim_z = active_dimensions = active_object.dimensions
active_bbox_volume = dim_x * dim_y * dim_z

for obj in bpy.context.view_layer.objects:
    if obj.type == 'MESH':
        obj_verts = len(obj.data.vertices)           
        if obj_verts == active_verts:
            if obj.dimensions == active_dimensions: # Dimensions are exactly the same
                obj.select_set(True)
            current_bbox_volume = obj.dimensions[0] * obj.dimensions[1] *  obj.dimensions[2]
            if  abs((current_bbox_volume - active_bbox_volume) / active_bbox_volume ) < epsilon: # Volumes are within (epsilon / 100) % range
                obj.select_set(True)
            if  all(
                abs((obj.dimensions[i] - active_object.dimensions[i]) / active_object.dimensions[i]) < epsilon
                for i in range(3)
            ): # Each individual dimension is within (epsilon / 100) % range
                obj.select_set(True)
1 Like

hello all… just found out this “select similar” thing and i think it is related to my question here couples years ago here when i’m looking for how to “select similar” in Blender like i usually do in max.

problem is i’m noob still in blender i dunno how to do it :sweat_smile:
would anyone care to explain to me how to execute (or applied to a button maybe) this script in Blender to get the result as we wanted?

========
edit:
Let’s say: if want to incorporate it into my right click object menu so each time i need it i just have to select them from popped up menu after i right click my mouse, but i have no coding skill for that to happen.
Is there anybody can tell me how to do that in a very clear step by step instruction?
update:
nevermid, if you follow this video from chochofur here carefully you might end up be able to adapt it to your own need making your own script… cudos chochofur!

Check this free Addon. You can assign scripts to a button and execute them by a click.