Script to search for specific geometry in rhino document

Hello dearest RhinoGrasshopper community,

Currently working on an “instant LCA calculator” to get live results as we model in rhino.
The first part of such a development requires me to extract quantity data, as explained below:

I need a C# script or Python script for Grasshopper that searches for specific geometry across the entire Rhino document, including inside block instances and nested block instances at any depth. The script should:

1. Accept a text input parameter (TI) like “Slabs” that’s used as a search term
2. Find all geometry that:
** * Exists on layers containing the TI text (case-insensitive)**
** * OR has the TI text in its object name (case-insensitive)**
3. Separate the results by geometry type with dedicated outputs for:
** * Breps**
** * Extrusions**
** * Curves**
** * Surfaces**
** * Meshes**
4. Handle recursion properly to reach geometry inside nested block instances at any depth

In other words, find any geometry in Rhino that is either on the layer “Slabs”, or has the name “Slabs”. Also check inside block instances.

Now, ive scripted in grasshopper a solution that essentially does this - see screenshot - and works (although my script doesnt yet work with nested blocks).

My issue is that I want it to be a) as computationally efficient as possible, and b) use this as a case study to learn more about C# or python scripting withing rhinoGH.
My ambition was to write a C# component that would do the above, but Im having trouble with it. Im using ClaudeAI for help, but I still can’t quite get it to work.
Ive attached my .gh file, and have left in it all the different C# or Py3 scripts Ive tried in case you want to have a look.

Any help would be much appreciated :slight_smile:

Thanks you beautiful hoomans

R&D_VroomVroomLCA_1.gh (26.4 KB)
LCA_Rhino Template_1.3dm (2.9 MB)

Here you go.
find_objects.gh (11.4 KB)

#! python 3
import Rhino
import rhinoscriptsyntax as rs
import scriptcontext as sc

def check_object(obj):
	name = rs.ObjectName(obj) if rs.ObjectName(obj) else ""
	layer = rs.ObjectLayer(obj)
	test = S
	if not C:
		test = test.lower()
		name = name.lower()
		layer = layer.lower()
	if N and E and test == name: return True
	if N and not E and test in name: return True
	if L and E and test == layer: return True
	if L and not E and test in layer: return True
	return False

def sort_objects(objects):
	breps = []
	curves = []
	extrusions = []
	meshes = []
	other = []
	for obj in objects:
		obj_type = obj.ObjectType
		if obj_type == Rhino.DocObjects.ObjectType.Brep: breps.append(obj)
		elif obj_type == Rhino.DocObjects.ObjectType.Curve: curves.append(obj)
		elif obj_type == Rhino.DocObjects.ObjectType.Extrusion: extrusions.append(obj)
		elif obj_type == Rhino.DocObjects.ObjectType.Mesh: meshes.append(obj)
		else: other.append(obj)
	return breps, curves, extrusions, meshes, other

def find_objects(objects=None):
	if not objects: objects = rs.AllObjects()
	found = []
	for obj in objects:
		if check_object(obj):
			found.append(sc.doc.Objects.Find(obj).Geometry)
		if rs.IsBlockInstance(obj):
			block_name = rs.BlockInstanceName(obj)
			block_objects = rs.BlockObjects(block_name)
			xform = rs.BlockInstanceXform(obj)
			new_objects = rs.TransformObjects(block_objects, xform, copy=True)
			found += find_objects(new_objects) # recursive search in block instances
			rs.DeleteObjects(new_objects) # cleanup
	return found

sc.doc = Rhino.RhinoDoc.ActiveDoc
rs.EnableRedraw(False)
objects = find_objects() # start recursive search
rs.EnableRedraw(True)
B, C, E, M, O = sort_objects(objects)
sc.doc = ghdoc