Skip to content

jgroeneveld92/Bedrock

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Bedrock

Canvas organisation and workflow tools for Grasshopper. Bedrock adds keyboard-driven commands, smart snapping, custom wire shapes, wire display management, and an anti-freeze system — all accessible from a single menu in the Grasshopper toolbar.

Table of Contents


Quick Start

  1. Build and install the plugin (see Building below).
  2. Open Grasshopper — the Bedrock menu appears in the toolbar.
  3. All features work out of the box with sensible defaults. Snapping is on; wire display and AntiFreeze are off until you enable them.

Menu & Shortcuts at a Glance

All keyboard shortcuts are defined in ShortcutRegistry.cs and can be changed in one place.

Command Shortcut Description
Add Param Left Ctrl+Alt+Left Insert parameters upstream of selection
Add Param Right Ctrl+Alt+Right Insert parameters downstream of selection
Remove Param Ctrl+Alt+Down Remove standalone parameters and splice wires through
Layout Selection Ctrl+Alt+L Auto-layout selected components by data flow
Merge Inputs Ctrl+Alt+X Insert Merge components on multi-source inputs
Duplicate Alt+D Duplicate selection directly below
Rename From Source Alt+S Rename parameter to match its source
Rename From Recipient Alt+R Rename parameter to match its recipient
Replace Relay → Param Alt+Shift+R Convert relays to typed parameters
Select Connected Alt+Click Select object and all direct neighbours
Delete Wire Alt+Click on wire Delete a wire without selecting the parameter
Quick Group 1–5 Alt+1Alt+5 Wrap selection in a coloured group preset
Open Test Dashboard Ctrl+Shift+T Open the testing dashboard window
Run All Tests Ctrl+Alt+T Trigger a re-solve to run all assertion components

Additional toggles and submenus in the Bedrock menu:

Setting Default
Enable Snapping ✅ On
Snap to Edges ✅ On
Snap to Centers ✅ On
Snap to Wires ✅ On
Wire Display by Length Off
AntiFreeze Off
Wire Shape Default

Features

Parameter Commands

Add Param Left — Ctrl+Alt+Left

Inserts new parameters upstream (to the left) of your selection, intercepting all existing input connections.

How it works:

  • Select one or more components or standalone parameters.
  • Press Ctrl+Alt+Left.
  • For each input on a selected component (or for a selected standalone parameter), a new Param_GenericObject is created to the left.
  • All existing sources are moved from the target input to the new parameter, and the new parameter is wired into the target.
  • The new parameter inherits its nickname from the first source (or from the target if there are no sources).

Use case: Quickly intercept incoming data with relay-like parameters for readability or debugging.

Add Param Right — Ctrl+Alt+Right

Inserts new parameters downstream (to the right) of your selection, intercepting all existing output connections.

How it works:

  • Select one or more components or standalone parameters.
  • Press Ctrl+Alt+Right.
  • For each output on a selected component (or for a selected standalone parameter), a new Param_GenericObject is created to the right.
  • The target is wired into the new parameter, and all existing recipients are rewired to read from the new parameter instead.
  • The new parameter inherits the target's nickname.

Use case: Fan out outputs through named parameters before they reach downstream consumers.

Remove Param — Ctrl+Alt+Down

Removes standalone parameters from the canvas and splices their connections through — sources are wired directly to recipients.

Requirements:

  • The selected parameter must be standalone (not an input/output slot on a component).
  • It must have both sources and recipients (otherwise there is nothing to splice).

How it works:

  • For each recipient of the parameter, all of the parameter's sources are connected directly.
  • The parameter is then removed from the document.

Use case: Clean up intermediate relay parameters that are no longer needed.


Layout & Organisation

Layout Selection — Ctrl+Alt+L

Automatically arranges selected components in a left-to-right layout following data-flow order, with wire-crossing minimisation and vertical alignment.

How it works:

  1. Topological sort — Components are assigned to columns based on their depth in the data-flow graph (rightmost outputs = level 0, walking backwards).
  2. Crossing minimisation — A median heuristic sweeps back and forth to reorder nodes within each column, reducing wire crossings.
  3. Vertical positioning — A Brandes–Köpf algorithm runs four alignment passes and takes the median, producing balanced vertical coordinates with a minimum of 20 px padding between nodes.
  4. Connection alignment — Standalone parameters are aligned to the inputs/outputs they connect to.

The layout preserves the vertical centre of your original selection.

Use case: Tidy up a messy patch — select the components you want to reorganise and press Ctrl+Alt+L.

Merge Inputs — Ctrl+Alt+X

For every component input that has two or more sources, a native Grasshopper Merge component is inserted automatically.

How it works:

  • Each original source is wired into a separate input of the new Merge component.
  • The Merge output is connected to the target input.
  • Input parameters on the Merge are named after their source.
  • The Merge is positioned to the left of the target component.

Use case: Consolidate multi-source inputs into explicit Merge nodes for clarity.

Duplicate — Alt+D

Duplicates the current selection (components and groups) directly below the originals.

How it works:

  • The bounding box of the selection is computed, and copies are placed below with 10 px padding.
  • Groups and their members are duplicated together.
  • External connections on the copies are severed — only internal wiring within the duplicated set is kept.
  • Full undo support.

Use case: Quickly create a variant of a sub-graph to experiment with.


Renaming

Rename From Source — Alt+S

Sets the nickname of each selected parameter to match its first upstream source's nickname.

Rename From Recipient — Alt+R

Sets the nickname of each selected parameter to match its first downstream recipient's nickname.

Both commands support undo/redo.

Use case: Keep relay-style parameters labelled consistently with the data they carry.


Relay Replacement

Replace Relay → Param — Alt+Shift+R

Converts Grasshopper relay objects into properly typed parameters that match the data flowing through them.

How it works:

  • If relays are selected, only those are converted. Otherwise, all relays in the document are converted.
  • For each relay, Bedrock inspects the source output type and creates the matching parameter type from Grasshopper.Kernel.Parameters (e.g. a relay carrying curves becomes a Param_Curve).
  • If the type cannot be resolved, a Param_GenericObject is used as a fallback.
  • The new parameter inherits: position, display mode, nickname (from the source), all connections, and locked state.

Use case: Replace anonymous relays with typed parameters that show meaningful icons and enable type checking.


Canvas Interactions

Select Connected — Alt+Click on a component or parameter

Selects the clicked object and all its direct neighbours (one hop in either direction via wires).

Use case: Quickly grab a component and everything wired to it for moving or inspecting.

Delete Wire — Alt+Click on a wire

Deletes the wire under the cursor directly, without needing to select the target parameter first. Works with both default and custom wire shapes.


Snapping

Bedrock adds a snap-guide system that helps you align objects as you drag them on the canvas. Visual guide lines appear when an object's edge or centre lines up with another object.

Toggle from the menu:

Option Default What it does
Enable Snapping On Master toggle for the entire snapping system
Snap to Edges On Snap to the top, bottom, left, and right edges of other objects
Snap to Centers On Snap to the centre (pivot) of other objects
Snap to Wires On Snap to wire grip points so parameters line up with their connections

Visual indicators:

  • Green solid line — edge alignment
  • Magenta dashed line — centre alignment
  • Red dashed line — wire grip alignment

Behaviour details:

  • Snapping activates during drag-move and panel-resize operations.
  • Only objects within a 600-unit radius are considered.
  • Alt+Drag (copy mode) is supported — snapping uses absolute positions instead of relative deltas.

Wire Display by Length

When enabled, this feature automatically adjusts wire visibility based on how long wires are on the canvas. Short wires remain fully visible, medium-length wires become faint, and very long wires are hidden entirely.

Enable: Check Wire Display by Length in the Bedrock menu.

Threshold Default Effect
Faint threshold 500 px Wires longer than this become faint
Hidden threshold 1000 px Wires longer than this are hidden

Wire display modes update automatically when:

  • A solution completes
  • Objects are added or removed
  • You finish dragging components

When you disable the feature, all wires return to their original display mode.

Use case: Reduce visual clutter in large definitions where long wires cross the entire canvas.


Wire Shapes

Bedrock can replace Grasshopper's default Bézier wire curves with alternative routing styles. Choose a wire shape from the Wire Shape submenu:

Shape Description
Default Grasshopper's native Bézier curves — no modification
Line Right-angle routes with rounded corners
Polyline Three-segment paths with an adjustable bend point
Electric Dual-radius corners for a kinked, circuit-board look

Each shape has parameters (extend distance, corner radius, pitch multiplier) that control its geometry. These are stored in Grasshopper's settings and persist across sessions.

Wire shapes are applied globally via Harmony patches on Grasshopper's paint system — all wires in every document use the selected shape.


AntiFreeze

AntiFreeze prevents Grasshopper from locking up during long-running solutions. When enabled, it aborts any solution that exceeds the configured timeout.

Configure from the menu: Bedrock → AntiFreeze

Option Effect
Off AntiFreeze disabled
2 seconds Abort solutions running longer than 2 s
5 seconds Abort solutions running longer than 5 s

When a solution is aborted:

  • All volatile data is cleared to prevent the UI from freezing on partial results.
  • A red warning banner fades in at the top-left of the canvas: "AntiFreeze: solution aborted after Ns timeout" (visible for ~3 seconds).
  • A message is logged to the Rhino console.

Use case: Protect against accidentally triggering expensive computations (e.g. connecting a large data set to a heavy solver).


OverSight

A canvas widget that draws floating component name labels above each object. This gives you an at-a-glance overview of what each component does without hovering.

Toggle: Click the OverSight button in the widget toolbar at the bottom of the Grasshopper canvas.

Settings (persisted in Grasshopper settings):

Setting Default Description
Enabled Off Master toggle
Label Colour Black Colour of the floating labels
Exceptions Scribble, Panel, Sketch, Button, Boolean Toggle, Number Slider Components excluded from labelling

Labels automatically hide when zoomed out past 50% of the default zoom level.


Quick Groups

Wrap selected objects in a coloured group with a single keypress. Five preset slots are available, each with a configurable name and colour.

Shortcut Action
Alt+1 Apply Quick Group slot 1
Alt+2 Apply Quick Group slot 2
Alt+3 Apply Quick Group slot 3
Alt+4 Apply Quick Group slot 4
Alt+5 Apply Quick Group slot 5

Configure slot names and colours via Bedrock → Quick Groups → Configure… in the menu.


Propagate Rename

When you rename a standalone parameter, the new nickname is automatically propagated through all connected standalone parameters in the chain. Propagation stops at component boundaries (i.e. it only flows through parameter-to-parameter connections).

This feature is always active and requires no configuration. All changes are batched into a single undo record.

Use case: Rename one parameter in a relay chain and have all linked parameters update instantly.


Proxy Replacement

Automatically replaces missing-plugin proxy objects (placeholder components that appear when a plugin is not installed) with native Grasshopper parameters on document load.

Built-in rules:

Missing Component Replacement
AutoGraph "Data Description" Param_GenericObject

The replacement preserves the original component's name, position, and all wire connections.

Extensible: Add new swap rules by subclassing ProxyReplacementRule and registering in ProxyReplacementConfig.Rules. Each rule has an independent enable/disable flag.

Note: This feature is disabled by default and is currently toggled in code via ProxyReplacementConfig.Enabled.


Testing Assertions

Bedrock includes a full set of assertion components for testing Grasshopper definitions. All components appear under the Bedrock tab in the Testing subcategory. Each assertion outputs a TestResult object and a Passed boolean, with a dynamic icon that turns green (pass), red (fail), or orange (error) after each solve.

Value Assertions

Component Nickname Inputs Description
Assert Equal AEq Actual, Expected, Tolerance Value equality with numeric tolerance (supports numbers, Point3d, Vector3d, strings)
Assert Not Equal ANEq Actual, Expected, Tolerance Asserts two values are not equal
Assert True ATru Value (bool) Asserts a boolean value is true
Assert False AFls Value (bool) Asserts a boolean value is false
Assert Null ANul Value Asserts a value is null
Assert Not Null ANNl Value Asserts a value is not null
Assert In Range ARng Value, Min, Max Asserts a number falls within an inclusive range

Tree / List Assertions

Component Nickname Inputs Description
Assert Identical AId N tree inputs (variable) Asserts inputs have identical structure and content
Assert Structure AStr N tree inputs (variable) Asserts inputs share the same tree paths
Assert Structure and Length AStL N tree inputs (variable) Asserts same tree paths and per-branch item counts
Assert List Length ALen Data (tree), Count Asserts a tree has the expected total item count
Assert Contains ACnt Data (tree), Item Asserts a data tree contains a specific item

Geometry Assertions

Component Nickname Inputs Description
Assert Geometry Valid AGeo Geometry Asserts geometry is non-null and valid (accepts Box, Brep, Curve, Mesh, etc.)
Assert Point Equal APtEq Actual, Expected, Tolerance Asserts two points are equal within a per-coordinate tolerance

Component State Assertions

Component Nickname Inputs Description
Assert No Message ANoMsg Component, Level Asserts component(s) have no runtime messages at or above a threshold (Blank/Remark/Warning/Error)
Assert Has Message AHMsg Component, Text Asserts component(s) produce a runtime message containing specific text

All assertion inputs include a Name (N) parameter for labelling the test. The variable-input tree assertions support adding/removing inputs via the ZUI (zoom-able user interface).


Testing Dashboard

A floating Eto Forms window that displays all assertion results in the current document at a glance.

Open: Ctrl+Shift+T or Bedrock → Testing → Open Dashboard

The dashboard shows a tree grid with four columns:

Column Content
Icon Pass (✓), Fail (✗), or Error (!) indicator
Test Assertion name, grouped by containing GH_Group
Status Pass / Fail / Error / Not Run
Message Failure reason or error details

A summary bar at the top shows the total pass/fail counts. The dashboard updates automatically whenever the document finishes solving and stays on top of the Grasshopper window.

Interactions:

  • Double-click a row to zoom the canvas to that assertion component.
  • Export results as JSON, JUnit XML, or Markdown via the Export button.
  • Re-run triggers a document re-solve to refresh all results.

Reporting Components

Components for collecting assertion results into reports and serializing them to standard formats. All appear under Bedrock → Testing in the component panel.

Report Collection

Component Nickname Inputs Outputs Description
Collect Report TRpt Results, Source Report Aggregates multiple TestResult objects into a single TestReport
Report Viewer RVw Report All Passed (bool) Displays a pass/fail summary as a component message with dynamic icon

Report Serialization

Component Nickname Inputs Outputs Description
Report to JUnit RJU Report XML (string) Serializes a report to JUnit XML format for CI integration
Report to JSON RJs Report JSON (string) Serializes a report to JSON format
Report to Markdown RMd Report Markdown (string) Serializes a report to a Markdown table

Test Runner

Component Nickname Inputs Outputs Description
Test Runner TRun Source, Server, API Key, Run Reports, Summary, All Passed Solves .gh files via Rhino.Compute and collects test results

The Test Runner sends Grasshopper definitions to a running Rhino.Compute instance, collects assertion results, and outputs a list of TestReport objects. It runs asynchronously — the component shows progress messages while files are being solved.


Testing CLI

Bedrock includes a standalone command-line tool (Bedrock.Testing.CLI.exe) for running Grasshopper test definitions via Rhino.Compute. It is included in the Yak package and can also be built separately.

Usage

Bedrock.Testing.CLI run <path> [options]
Option Default Description
<path> (required) Path to a .gh file or folder
--server http://localhost:6500 Rhino.Compute server URL
--apikey API key for Rhino.Compute
--format text Output format: text, junit, tap, json, markdown
--output Write report to file instead of stdout
--recurse / --no-recurse --recurse Recurse into subfolders
--timeout 60 Per-file solve timeout in seconds
--parallel 1 Number of files to solve in parallel
--verbose off Show individual results for passing files

Exit Codes

Code Meaning
0 All tests passed
1 One or more tests failed
2 Error (connection failure, invalid path, etc.)

Example: CI pipeline

Bedrock.Testing.CLI run ./tests --format junit --output results.xml --parallel 4

Building the CLI separately

cd Bedrock/Testing.CLI
dotnet build

The CLI targets net7.0 and depends on Bedrock.Testing.Goo (the shared data library).


Building

cd Bedrock
dotnet build

This produces two builds, each with a .gha file (Grasshopper's plugin format):

  • bin/Debug/net48/Bedrock.gha — for .NET Framework runtime
  • bin/Debug/net7.0-windows/Bedrock.gha — for .NET Core runtime

Requirements

  • Rhino 8 (with Grasshopper)
  • .NET SDK 7.0+ (for building)
  • .NET Framework 4.8 targeting pack (installed with Visual Studio or separately)

Installation

Option 1: RHINO_PACKAGE_DIRS (recommended)

Set the RHINO_PACKAGE_DIRS environment variable to point to the build output folder, then launch Rhino. Grasshopper will discover and load the plugin automatically.

PowerShell (one-time):

$env:RHINO_PACKAGE_DIRS = "C:\Users\<you>\path\to\Bedrock\bin\Debug\net7.0-windows\"
& "C:\Program Files\Rhino 8\System\Rhino.exe" /netcore /runscript="_Grasshopper"

Option 2: Manual install

Copy the built Bedrock.gha (and its dependencies) into Grasshopper's component folder:

%APPDATA%\Grasshopper\Libraries\

Then restart Rhino/Grasshopper.


Building the Yak Package

The repository includes Publish-Yak.ps1 to build and optionally publish a .yak package for the Rhino package manager.

Prerequisites

  • Rhino 8 installed (the script uses the Yak CLI bundled at C:\Program Files\Rhino 8\System\Yak.exe)
  • .NET SDK 7.0+

Build the package only (no push)

.\Publish-Yak.ps1 -SkipPush

This will:

  1. Run dotnet build in Release mode targeting net7.0-windows.
  2. Publish Bedrock.Testing.CLI as a single-file executable.
  3. Stage Bedrock.gha, companion DLLs, Bedrock.Testing.CLI.exe, manifest.yml, and the icon into a temporary yak-staging directory.
  4. Run yak build to produce the .yak file.
  5. Copy the resulting .yak to the repository root.

Build and push to production

.\Publish-Yak.ps1

You will be prompted to authenticate via yak login if not already logged in.

Build and push to the test server

.\Publish-Yak.ps1 -TestServer

Additional flags

Flag Effect
-Configuration Debug Build in Debug instead of Release
-SkipBuild Skip dotnet build and use existing build output
-SkipPush Create the .yak file without pushing it
-TestServer Push to https://test.yak.rhino3d.com instead of production

Sources

The following Grasshopper plugins were used as reference and inspiration during the development of Bedrock:

About

Bedrock is a Grasshopper plugin that aims to provide a comprehensive set of UI tweaks, utility functions and components.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages