Wish: Select objects by polygon count

I have some big Rhino files with countless of objects that heavily affect the viewport performance. Sometimes certain types of geometry add an excessive amount of polygons for the rendering mesh, such like balls etc. Quite often I figure out that certain smaller balls have a much more dense polygon count that large ones. The same goes to threaded bolts, too.
It would be nice to be able to select objects based on a user-set minimum value. It will be even better to implement both, a minimum and a maximum polygon count values. That will let the user select and inspect all the objects whose render mesh polygon count falls within the target minimum and maximum values. It’s an easy way to fix the excessive amount of polygons by assigning a custom mesh to those objects.

1 Like

Hi,
There you go buddy, If you have any problems just tag :stuck_out_tongue:

import rhinoscriptsyntax as rs
threshold = rs.GetInteger("Enter polygon count threshold", minimum=1)
objects = rs.AllObjects()
for obj in objects:
  if rs.IsMesh(obj):
    mesh = rs.coercemesh(obj)
    # Check if the mesh has more polygons than the threshold
    if mesh.Faces.Count > threshold:
      rs.SelectObject(obj)


print("Obj selected")

selectbypoly.py (425 Bytes)

1 Like

This only works for meshes. Can you change it so it checks the render mesh?

1 Like

Sure, upload an example file please with 2 rendering mesh with different polygon counts please

Also, there seems to be a BUG in the Rhino’s default mesh settings, because those two spheres result into the following polygon count:

Jagged and faster: 18 ďž 752 polygons for the small sphere, and 18ďž  752 polygons for the big sphere (37 ďž 504 polygons total for both spheres).

Smooth and slower: 3ďž  968 polygons for the small sphere, and 16ďž  128 polygons for the big sphere (20ďž  096 polygons total for both spheres).

Turns out that the “Smooth and slower” is actually much faster than “Jagged and faster”. Note that spheres originally built in “Jagged and faster” have exactly the same dense rendering mesh (18 ᅠ752 polygons), no matter their size, even if they are tiny 1 mm balls. In my opinion, this is a total waste of resources and smaller spheres (and other objects in general) should be displayed by a less dense mesh that correspond to the “Smooth and slower” name which suggests simplified models and better performance.

There is a funny thing, though. Changing from “Jagged and faster” to “Smooth and slower”, then reverting to “Jagged and faster” again simplifies the rendering mesh that was originally way too dense. Not sure why “Jagged and faster” fails with spheres and other objects that are supposed to be optimized by Rhino.

Two spheres built with Smooth and slower mesh setting.3dm (567.4 KB)

1 Like

You can try this one out…

import rhinoscriptsyntax as rs
import scriptcontext as sc
import Rhino

def SelLargeRenderMeshes():
    if "SLRM_MinCount" in sc.sticky: prev_min = sc.sticky["SLRM_MinCount"]
    else: prev_min = 100
    min_count=rs.GetInteger("Min. RM polygon count to select", prev_min,1)
    if min_count is None: return
    obj_ids=rs.ObjectsByType(8+16)
    if obj_ids:
        to_sel=[]
        rhobjs=[rs.coercerhinoobject(obj_id) for obj_id in obj_ids]
        rm=Rhino.Geometry.MeshType.Any
        for i,rhobj in enumerate(rhobjs):
            meshes=rhobj.GetMeshes(rm)
            if meshes:
                for mesh in meshes:
                    if mesh.Faces.Count > min_count:
                        to_sel.append(obj_ids[i])
                        break
        if to_sel:
            rs.UnselectAllObjects()
            rs.SelectObjects(to_sel)
        sc.sticky["SLRM_MinCount"] = min_count
SelLargeRenderMeshes()

Note that it is looking for any mesh (Preview, Render, Analysis) attached to a surface or polysurface object. It does not look at actual meshes. Previously used threshold is sticky within a session.

How do I use this? It returns the following warning message:


Exception Occured

Message: global name ‘sc’ is not defined

Traceback:

line 2, in SelLargeRenderMeshes, “D:\PROGRAMI\Rhinoceros 7\Добавки\Select large render meshes\SelLargeRenderMeshes.py”

line 22, in , “D:\PROGRAMI\Rhinoceros 7\Добавки\Select large render meshes\SelLargeRenderMeshes.py”


OK

Oops, forgot to copy the three lines at the top… sorry. Fixed above.

Thanks for the edit, but it still does not work or maybe I do something wrong. It says: “Min. RM polygon count to select <5000>: 5000” and then nothing happens.

Are you sure there are selectable objects with render meshes with more than 5000 polys? If so, post a sample file and I will look tomorrow. I tested it on a few objects here and it worked. However it only looks at surfaces and polysurfaces, it doesn’t take into account objects in blocks nor sub-d’s… I guess those could be added, for block instances, the whole block instance would get selected.

Yes, I tried the script with several files consisting surfaces and polysurfaces with more than 50 000-100 000 polygons each, and none of the was selected. I also tried to select with 100 polygons, but still not working. It selects basic spheres, though. Looks like that the scrips has problems with selecting anything with 5 digits or more. For example, it’s capable to select anything with up to 9999 polygons, but will fail at 10000 or any greater number.

P.S. Just tried to select anything with 5000 polygons and it only selected one spring consisting 6ďž 208 polygons, despite that nearly every other object in the scene has a render mesh with much more polygons. However, when I tried to select objects with more than 6000 polygons, the script failed to select the aforementioned object consisting 6208 polygons.

Well, I tested it with something that had 25k polys on a single surface and it worked. However, I think I know what the problem is - it probably works correctly with single surfaces, but now that I think about it, the mesh counts for polysurfaces are reported per face. I think I will need to add them together to get the total. If you have a single surface that does not work with the script, post it here.

Sure, here is a single object to try it out:
Single surface.3dm (178.2 KB)

Well, that one works here as a single surface. It selects with a number up to 3104 (its poly count).

But, as I surmised yesterday, the meshes on a polysurface are returned per-face, I had to add the face mesh counts together. I also fixed a couple of other things.

I also re-set this up to look for the different types of meshes an object can have including both analysis and render. If any of those exceed the count, the object should select. Below is your original torus that I divided into 8 surfaces. It has a combined render mesh of 3069 polys, but each segment has less than 1000 polys. I also added an analysis mesh which has 8481 polys. With the old script it would not select, with this one it does, right up to 8481. Try this one out and let me know it works.

It still does not do blocks (could be added later), and I’m not sure how it should work with sub-d’s.

SelLargeRenderMeshes.py (1.5 KB)

1 Like

Interestingly, the same torus consists 6ᅠ208 polygons in my Rhino 7. I have to mention that my Rhino 7 is set to “Large objects - Millimeters” and Units are Millimeters, Absolute tolerance is 0,001 mm and Angle tolerance is 0,1 degrees. It’s possible a Rhino set to inches and/or different tolerances to affect the rendering mesh count.

I just tried the new version of the script and it was not able to select the same torus with 6208 polygons (scene is set to “Jagged and faster”) when I entered a minimum target polygon count of 4000, 6000, 6200, 6207 and 6208. It did, however, select the object with a target of 3104 polygons but refuses to do so with anything above 3105 polygons. Quite strange…

Then I set the scene to “Smooth and lower” and it converted the render mesh to 8ᅠ320 polygons. This time, the script selects the torus with a target count set up to 4160 polygons, but will not select it with a target count above 4161 polygons.

In theory it should select at all of those. The poly count needs to be greater than or equal to the target number. In my tests here that works correctly.

That doesn’t make any sense to me but I’ll check…

Yeah, something seems to cause those differences, at least in my Rhino 7 it’s not working as expected.

It will probably have to do with different ways of counting. Rhino gives count “after forced triangulation”
edit: that wasn’t it

I’m wondering why the polygon count is different, considering that both, the “Smooth and slower” and the “Jagged and faster” options are native settings across every Rhino 7 program. Also, when I use the polygon count tool in Rhino and then try to select exactly the same object with the script written by @Helvetosaur by entering a lesser value than the polygon count, it still can’t do it.

I believe something weird is going on at your end. Do you get the same behavior in a fresh file, original template?