Unique List of Components in Code

Hi @DavidRutten,

I am in the process of making some teaching examples and was wondering if there was a way to list all unique components used in the definition. This is not for teaching more for me to keep track of what I have used and what else needs to be added.

I have been able to print a list of nicknames using a python script but this includes sliders groups scribbles the work is it possible to just print a list of the full names of the unique ones no including sliders etc. I tried name instead of using nickname but that did not return anything.

import Grasshopper as gh

def ComponentList():
ghObjects = ghenv.Component.OnPingDocument().Objects
for obj in ghObjects:
    name = obj.NickName
    print name

if x == True:
ComponentList()

Cheers
Matt

You could check the type of the canvas object (using type()) or its inheritance (using isinstance()), and only get the names if it’s the exact type you’re looking for, or it inherits from a parent class. To get the unique names after the loop, I’d simple make a set() of the gathered names.

Edit: Here’s a method that checks the namespace of the object, probably easier than crawling inheritance trees and such (note that there’s also probably a less hacky way than the string check):

compNames = []
for obj in ghenv.Component.OnPingDocument().Objects:
    if obj.GetType().Namespace == "Grasshopper.Kernel.Components":
        compNames.append(obj.Name)

uniquecompNames = list(set(compNames))
print uniquecompNames
2 Likes

That’s a great start thanks, though interestingly if you put

if obj.GetType().Namespace == "Grasshopper.Kernel.Components"

You get only 4 of 5 components

Custom Preview, Shift Paths, Stream Gate, Unflatten Tree

But if you put

if obj.GetType().Namespace != "Grasshopper.Kernel.Components"

You get all the rest of the components on the canvas and not the first few listed above which is odd as I don’t see how it decided which should be in which list.

Yes that’ll get you any object that is not in the Grasshopper.Kernel.Components namespace. You’ll need to come up with your series of checks to get the exact name spaces you’re looking for (which will probably require some digging in the Grasshopper API). Alternatively, figure out which top-level parent class the component inherits from, and use isinstance() instead.

Edit: Just tested out the latter suggestion, think that’s probably the better way to go (compared to the hacky namespace/string check):

import Grasshopper as gh

UniqueCompNames = []
UniqueCompTypes = []
for obj in ghenv.Component.OnPingDocument().Objects:
    if isinstance(obj,gh.Kernel.GH_Component):
        objName = obj.Name 
        objString = obj.ToString()
        if objName not in UniqueCompNames:
            UniqueCompNames.append(objName)
            UniqueCompTypes.append(objString)
2 Likes

I had written something similar a little while back. Some of it was based on examples shared by others, (credited in the link). Maybe you could refine this?

1 Like

Sorry for the delayed reply got pulled onto another project so this when on the backburner.

Thanks @AndersDeleuran and @chanley both great answers and super useful.

Cheers
Matt

Ps Love the Component Type Names : SquishyXMorphs.Component_CreateSurfaceBox Does exactly as it says on the tin.

1 Like