algorithmic modeling for Rhino



Welcome to Metahopper - a tool for controlling Grasshopper with Grasshopper :)

This library contains a number of components and commands for querying and manipulating Grasshopper components dynamically. You can retrieve components and objects based on their type, their library, the group they're in, or by selecting them directly - or even get all the objects in a document at once. You can then retrieve information about these components + parameters, the libraries they belong to. You can also manipulate objects directly: enabling/disabling, turning preview on and off, changing the color of groups, the text and size of scribbles, and the shape of sketch objects.

MetaHopper also adds a new menu to the Grasshopper document editor, that wraps up several functions:

BestPracticize Selection lets you pick a group and auto-insert params for all the inputs and outputs coming into/out of the group. This makes for nice, tidy functional groupings that make your Grasshopper code easier to read. 

Save Snippet improves on an earlier script I released - it lets you select any group of components + objects and save them as a single user object - without needing to cluster them. This is useful when you want things saved that have internal UI elements - like a graph mapper or slider for instance - that you want to be able to manipulate with the reusable chunk of code you're saving.

Bottleneck Navigator opens up a window that lets you see all the components in your definition, sorted by their "Runtime" - how long it took them to execute. You can click on any item in the list and zoom to it instantly - so that you can find opportunities for optimization in your definition.

Download it here!

Members: 151
Latest Activity: Dec 14, 2016

Component Listing


Set Group Properties

Set the name, color, and style of a group.

Control Wire Display

Control the display of wires for parameters and components.

Set Scribble Properties

Set the text, size, and font of a Scribble.

Hide/Show Object Preview

Programmatically control the preview visibility of specified objects

Rename Object

Programmatically set the nickname of specified objects

Enable/Disable Object

Programmatically enable/disable solving for specified objects

Set Sketch

Modify the form of an existing sketch object.

Bake Object

Programmatically bake the geometry of specified objects

Wire Display Toggle

Switch all document wires between hidden and faint.



Converts a standard GH Slider into a variable input to the Batch Driver

Batch Animator

Saves a screenshot of every state of the model in the batch to a folder.

Batch Variable from List

Converts a list of values such as a series or range into a variable input to the Batch Driver


Run a batch analysis across a range of variable parameters


Param Info

Gets information about param objects

Object Info

Gets basic information from any DocumentObject

Assembly Info

Gets information about an assembly

Component Info

Get information about a component object. Retrieve components with Document Info, Get Attached Component, or Get Selected Component.

Document Info

Get information about the GH document and its components

Object Retrieval

Get Groups

Get all groups in the document

Get Connected Objects

Gets all components and params connected to this component

Get Objects of Same Library

Gets all components and params that are from the same library as the attached.

Get Selected Objects

Get the objects currently selected on the canvas

Get Scribbles

Get all Scribbles in the document

Get Objects of Same Type

Gets all components and params that are of the same type as the attached.

Get Objects in Group

Gets all components and params in the same group as this component (or the specified group if supplied)


Best Practicizer

Takes a selected group and inserts input and output params at both edges for any data that goes outside the group.

Highlight Objects

Highlight objects by adding them a new group

Set Object Value

Tries to set the value of an object. What value it sets varies by type - it sets a slider’s numeric value, a panel or scribble’s text contents, etc

Relative Path

Appends the directory this definition is saved in to a file path. Auto-converts the contents of a text panel containing an absolute path

Discussion Forum

ParamInfo for points from slider knots 4 Replies

Hey,I was wondering if it's possible to use ParamInfo to get the position of the knob on a slider as a point or if this feature could be added. I was hoping to be able to use it to visualize a…Continue

Tags: point, knot, slider, paraminfo

Started by Ferdinand List. Last reply by Ferdinand List Dec 6, 2016.

Export to Excel the BottleNexkNavigator table with component name and run time

Do you plan to add an Excel export / Csv export to the BottleNexkNavigator.It can help users to analyse run time in second or millisecond when there are many component in the definition.Continue

Started by DE VILLE D'AVRAY Dec 6, 2016.

Save snippet crashes Rhino

Hi Andrew,when I try to create a snippet with components received from a snippet itself my Rhino will crash.Best,phillipContinue

Tags: crash, snippet, save, metahopper

Started by phillip Oct 19, 2016.

"best practice" button crashes 1 Reply

hi,ive tried to click the best practice button in the menu bar in always crashes for me on empty rhino/gh files.Continue

Started by Mathias s n. Last reply by Mathias s n Oct 19, 2016.

Comment Wall


You need to be a member of MetaHopper to add comments!

Comment by Frans Magnusson on December 14, 2016 at 2:29am

Well, I trying out ways to document the development of definitions in a diary of sorts by using text panels. It works really well to place them in a context on the canvas, but I would also like to gather them in a chronological order. Right now I have built a kluge that uses record-components - but it would save so much hassle with timing of events to add some kind of time stamp to each grasshopper object. Do you know if they have IDs you can key with a time value?

Comment by Andrew Heumann on December 13, 2016 at 1:35pm

Hi Frans - as far as I know the time a component/object is created is not stored by grasshopper. What exactly do you have in mind to accomplish with this logging? maybe there's a way to hack it in as a special "mode" that listens while things are added? 

Comment by Frans Magnusson on December 13, 2016 at 11:47am

Thank you Andrew, for taking grasshopper to the meta-level! Does gh store the time of creation for objects and parameters? In that case that would be super useful to access with your tools - trying to build a log functionality. 


Comment by Martin Siegrist on October 11, 2016 at 7:28am

AJ, you need to group the button with another grasshopper component/s

Comment by AJ on October 10, 2016 at 2:16am

hi Andrew, how do you use the enable / disable button (like in the gif) ? thnx

Comment by Xavier AM on September 15, 2016 at 4:22am

Damn, MetaHopper is absolutely AWESOME! I wish I had known it from the time I started writing complex definitions, it would have saved days of work.

I am just figuring out component by component what are their purposes,  I feel like a child on Christmas day :-) A special big up for the "Label Groups" and the "Bottleneck analyzer".

Thanks Andrew for this really good job!

Comment by Vongsawat Wongkijjalerd on August 9, 2016 at 10:59pm

Huh, weird things when you try to circumvent core grasshopper design I guess..

Throttling by Data Dam with boolean trigger is exactly what I'm trying for. (huh, setObjVal as opposed to expireObj threw me for a loop there) Thanks for the suggestion though!

Would you know why, when I connect a Data Recorder to this, the first time triggering will always double-trigger?.. subsequent triggers act as expected, if I clear the Recorder, the first value triggers twice again. Whether the behaviour's coming from the Dam or the Recorder ..

Comment by Andrew Heumann on August 9, 2016 at 7:00am

I should also mention that the Data Dam has an in-built "timer" of its own, that allows you to "throttle" your data as I think you're attempting to do.

Comment by Andrew Heumann on August 9, 2016 at 6:57am

Well Vongsawat, this one had me really puzzled. Every time I opened YOUR definition, it didn't work, and every time I reconstructed your definition, it worked without fail. Here is what I think is happening:

Grasshopper can only be computing one "Solution" at a time. In every solution, it only calculates "Expired" components - so that it avoids recalculating stuff which hasn't changed. The timer handles "expiring" the counter and scheduling a new solution - and so does the "Expire objects" component. Within a given solution, normal GH logic dictates that "upstream" components calculate first, and then passes that data long to other components further downstream. Now, since your metahopper rig does not involve conventional "wired" connections, there is nothing to tell grasshopper that the chunk of components with the counter needs to solve prior to the "param data" component retrieving the contents of the param downstream. Here is the really strange bit: In the absence of wired chains of dependency, Grasshopper decides which components should solve first BASED ON THEIR DRAW ORDER on the canvas. This means that, if you take your group of components with the counter and "Send to back" - everything works as expected. If you "Bring to front" you will consistently get an empty list from the param.

I think the reason your lower set occasionally returns proper values is that you click the "expire" at just the right time to insert a complete solution IN BETWEEN the solutions triggered by the counter/timer combo. With the upper configuration + faster timer, this is next to impossible.

So - all this is to say - by messing with the draw order, you may be able to cause this rig to work predictably - make sure you "bring to front" on all the metahopper components and "send to back" on the stuff you are listening to, in order to force it to compute first during any given solution. If this does not work, some sort of custom script may be necessary... but this strikes me as highly difficult.

I'd also like to suggest an alternative approach: you may find that using the data dam set to "Never" in a situation like this is preferable. It will circumvent solution logic such that even as the upstream components expire, the data is only passed through (and the downstream components expired) when you hit the "play" button. If you need to control this with a boolean value instead of the ui element itself, you can use metahopper "Set object value" on a data dam to cause it to recompute programmatically.

Thanks for a truly interesting puzzle - hope one of these solutions will get you where you need to be!


Comment by Vongsawat Wongkijjalerd on August 8, 2016 at 9:47pm

two versions: The top one runs at 20ms, apparently too fast at least for my pc. The bottom one runs haphazardly as every 4th or so result is a null-result, sometimes more.


Members (151)



Search Grasshopper


  • Add Photos
  • View All

© 2017   Created by Scott Davidson.   Powered by

Badges  |  Report an Issue  |  Terms of Service