Rhino WIP Feature: Drag, Rotate, Create: Interactive Viewport Widgets

Have you ever wanted to control a widget directly in the viewport and have it drive your Grasshopper model?

The Rhino Work-In-Progress includes two new components in the Transform tab:

  • Curve Widget
  • Angular Widget
    OffsetCurve_01

What are these widgets?

Curve Widget

The new Curve Widget component lets you turn any curve into a numeric slider. It creates a slider directly in the viewport that stays in sync with the component. If you move the slider in the viewport, the value in the component updates automatically and vice-versa.
Linear Widget
The component works with any input curve and includes dynamic precision. As you zoom in, the numerical accuracy increases, giving you finer control over adjustments to your model.
DynamicZoom2
A single widget component can also manage lists of input curves, helping keep your Grasshopper model concise and organized.
WidgetBox_04

Angular Widget

The new Angular Widget component lets you create an in-viewport control for setting a specific angle. You set the widget’s angle range and radius in the Grasshopper component, and the viewport control updates automatically. This gives you an interactive way to fine-tune angles directly in your model.
AnglularWidget5
You can also choose from four different angle modes: 1) Degrees, 2) Degrees Minutes & Seconds, 3) Radians, and 4) Gradians.


Why would you use these?

  • Creating interactive workflows and controls.
  • Bridging the gap between Grasshopper and Rhino.
  • Sharing definitions with non-Grasshopper users.

Example

Here is an example of linking different widgets together to make a parametric tower.

WidgetTower
WidgetTower.gh (26.4 KB)

As always, we welcome your feedback—please let us know what works well and what could use further refinement.

Download Rhino WIP…

42 Likes

This is super useful. How about snaps?

There are some snaps (midpoint/endpoint). And you can hold shift + double click (LMB) (or alternatively right-click on the component and select “Edit Slider”) and it will bring up the Slider properties dialog where you can set the slider accuracy to using 1) Floating Point, 2) Integer, 3) Even, or 4) Odd numbers only. The slider/widget will then snap to those restricted values. You can also double click on the grip (either the slider on the component or the in-viewport widget) and it will give you a numeric input to specify an exact number. Does that help?

1 Like

I looked at the settings already and it works for most things of course. I was just wondering if the widget slider is going to have the exact same settings like the normal slider. I think the component could even be a separate component and a standard slider input instead of a custom slider inside a component. When the slider is connected to the widget component, it would show up as a slider in the viewport…

Maybe I’m misunderstanding but the widget does basically have the same settings as a number slider. If I hold shift + double click (LMB) on the slider on the component, the numeric slider popup dialog appears and lets me set the same settings as a regular number slider. These properties are then applied to the widget. Each slider stores it’s own information so if you have multiple sliders on a single widget component, you can have one which is set to integers, and another with floating point decimals with a rounding accuracy of 4. Does that make sense?

The same options except snapping.

Ok. I understand the request now.

Very nice idea! The possibility to attach a fitting UI directly in 3D space is just great.
And it fuels ideas for future development in the same direction :slight_smile: - so I have to ask:
Do you plan to widgetify other inputs like Toggle/Button, Panel/Text, Color Swatch and maybe even Value Picker as well? That would enable us to prepare models where clients could switch between style variations on the fly and directly in 3D space (eg. select a surface color of their liking or choose from a predefined set of textures)..
Great work! Thank you!

1 Like

I do have some ideas about a class of HUD elements that could be displayed… but that’s a much bigger topic and not something we plan to focus on for this WIP. It could definitely be added to the wish list for future WIPs though.

3 Likes

Exiting stuff!

Double widget
I have once made a script for tree placement along a curve and I have wanted these widgets to indicate the start and end of the curve for tree placement. It would look like this:


There would be two dimensions along the same curve in opposing directions, causing them to overlap. Because I think this would be a common case (e.g. you adjust the ends of a loft between two curves on either end using the widget), it would be nice to support either:
A) One dimension above the curve and one below
B) Drop only display one set of dimensions when you hover over one of the two widget points.

As a sidenote, the fact that this uses two sliders makes it impossible to have one domain of [0—X] and the other [X—0], this always has to be[-X—0].

Instancing widgets
Continuing on with the tree placement example, it would be cool if I could instance widgets. In a row of trees, each tree would have the same size. So if the angular widgets in this example were all linked, that would be handy.

Store and recall widget settings
Lastly, I can see myself using this with selections a lot. In that case, I would draw the widget on the last selected item and store its settings with User Text Attributes.In that case, I would like to have inputs to feed the User Text Attributes into so I can get the widget to appear just like I left it. In the example below, one curve is shorter than the others, which means that the widget will be clipped to the shortest curve.


Widgets testing.3dm (3.4 MB)
Widgets testing.gh (23.2 KB)

Super exited to see this! Reminds me of this Grasshopper Player thread where I learned that you can use Kangaroo to create makeshift sliders - Grasshopper Player (custom tools & wish list) - #6 by yelenaye

I actually use this functionailty a lot but the bloat of kangaroo components in the script becomes annoying. I’m glad to see official support for this kind of in-Rhino interactivity!

3 Likes

This is not only very useful, but also has a lot of the charm that, for me, characterizes Rhino. Thank you very much.

One small thing that caught my eye while testing the widgets is that it would be nice if the Angle Widget could also accept a list of values ​​(maybe not necessarily a list of curves, like the Curve Widget). In this case, the relative angles between individual elements would be displayed. We would probably still simply control the angle within a given domain, but displaying the angle between subsequent elements would be nice.

1 Like

Holy shit this is wild Andy! From a very quick test this feels like a substantial addition to how we interface our design models. Thanks so much for pushing things further and thinking outside the box here. I’ve certainly become quite stuck in my ways, but this feels like something myself and our design teams can greatly benefit from. I use gene pools a whole lot, but something like the curve widget feels like it can pretty much replace those directly in pipelines like this current one I’m working on. And really connect the 3D geometry space with the parameter space much more intuitively:

First little fiddle test:

Massive :clap:

Edit: This just gets better and better. One can edit sliders individually and publish to the RCP:

I’ve wanted an RCP genepool since forever. Praise the lord :raising_hands:

6 Likes

Maybe I’m missing something. Can you make it so the slider value can be fed into the component? This way a slider value could be saved with a curve as attribute user text.

I had to give this a quick go. Apologies if this sounds polemic, but I can’t recall being this excited about a new feature for well over a decade! Total game changer IMO:

Some quick feedback/ideas for things to add:

  1. Names (i.e. draw on hover to identify sliders in the viewport).
  2. Galapagos support (i.e. like a normal slider and the genepool).
  3. Cluster support (i.e. they don’t draw/work clustered, I think).
  4. Screenspace mode (i.e. use XY components and draw in 2D screen space).
10 Likes

Just to elaborate on this. For definitions with many sliders/genepools (e.g. the one above), one could effectively hide all those away in clusters and really clean up the canvas. Going from this:

To this (which doesn’t work with Preview Contents on):

Edit: Also, being able to turn off the sliders on the canvas might also be useful.

I’ve added a YT item (RH-91033) to track this request. Thanks.

You can actually store all of the states of the sliders on a widget component using the Save State/Restore State functionality. Look under the Solutions menu for Grasshopper and you should see those items there. Let me know if you have trouble. That should make storing the values as a user attribute superfluous.

This would be tricky (in it’s current configuration). In it’s current setup, these widgets work much like a slider and a slider only ever has a single value. So, enabling a feature to allow for multiple grips on a single widget (ie. angular or curve widgets) could be tricky. That said, @kike once made a prototype that was somewhat similar to the angular widget. It was more a “compass” or “protractor” which could measure angles and in this prototype you could pass in any number of points to get their angles back to a center point and a known start angle… so it’s possible that this request might be better suited for something like that.

Could you add the user attribute text to the input curve down-stream of the widget component? I realize that it’s adding more components, but it seems like it should work, right?