algorithmic modeling for Rhino

It's been more than a year since the last release of Human - so I'm excited to share with you the latest version, packed chock-full of new functionality. See the release notes for details on the new features. A few of my favorites:

  • Ability to define / modify block definitions on the fly
  • Ability to embed user data into object attributes, and read it back out
  • Screen-oriented mesh and screen-oriented text for custom glyphs/sprites that always face the viewer
  • Custom per-vertex texture mapping
  • Absolute scale for lineweight, allowing you to set a line's thickness to a constant dimension of 2 meters, for instance - it will scale as you zoom in and out.
  • Curves and Points in "heads up display" components
  • All new example files + documentation

Download the components below! They will also be available on food4rhino as soon as they're approved.

Views: 8168


Replies to This Discussion

Hi Nik.

1. The fix was necessary because my component (and presumably fabtools as well) is tuned into object-level attributes, not layer-level attributes. For many attributes (material, color, etc) each object has a "Source" property (layer, parent, object) - my fix causes it to look at this source property in order to determine where to draw the plot width value from. I was already doing this for color and material, but had neglected to do it for plot width.

2. The "Print Preview" viewport display option is calling the "PrintDisplay" command in Rhino, which you will notice takes a "Thickness" value - this is the conversion factor between plot weights/print widths (in mm) and the number of pixels in absolute screen width. As you note, this is a relative and not an absolute width in model units, so it does not change when you zoom. In most design applications it would be quite strange to specify the print widths of your geometry in absolute units - e.g. setting your lines to be 50 ft thick. In illustrator you are always working in "Paper Space" whereas in Rhino you have to be aware of the differences between Model Space and Paper Space (or Layout Space in Rhino terminology.) 

My lineweight preview component operates on the basis of pixels - if you tell it "2" it will display a 2px-wide line irrespective of your zoom. The 4x conversion ratio you note is purely a function of the setting of your PrintDisplay command in Rhino.

3. The good news is my custom preview component ALSO supports "Absolute" lineweights in world-space units - so that they create a line that gets fatter when you zoom in and thinner when you zoom out (though it can't get thinner than a pixel, naturally.) Set the "Absolute" toggle (the 4th option" on the component - I think it will create the "Illustrator-like" behavior you're looking for, without having to create surfaces from your lines.

4. The dynamic pipeline component updates when the by-object plot weight changes. It does not update when the layer-level plot weight changes. In the end I have had to make some judgment calls about what kinds of changes should trigger a component refresh: too sensitive, and a definition could be forced to recompute unnecessarily on every little change; too insensitive, and you require too many forced refreshes.

In general I have focused on triggering updates from object-level attribute changes (Where they conceptually represent data about THIS OBJECT) and NOT from layer-level attribute changes (Where they conceptually represent data about a category). The Layer Table is the component that is designed to report changes to layer-level settings - and with "Auto Update" enabled on this component, it will in fact trigger an update on layer-level attribute changes.

With this approach, you may have to match up your geometry to the layers it belongs to, and then use the layer table component to retrieve the plot weight settings. The definition shown below is an example of how to do this. It assumes you are using layer-level plot weights. 

I found how to create line width screen graphics directly from Python, in screen sizes, not geometry sizes:

So I would then need to acquire the zoom state of the viewport in order to adjust the thickness. Ugh.

I found how to create line width screen graphics directly from Python, in screen sizes, not geometry sizes:

So I would then need to acquire the zoom state of the viewport in order to adjust the thickness. Ugh.

Yes, my "absolute" option for the line weight preview as described in my last reply does essentially that.

Fantastic. I guess I forgot absolute lineweight previews worked after I upgraded to the new version with default settings.

I'm still having to use the FabTools GetObjectAttributes component as well though, to obtain not just the layer color assigned to objects but also the Print Color.

Sounds obscure, except I want layer/assigned color to be my Illustrator-like fill color, however I might eventually preview that, say as a Python exported SVG file for the web, but then use the second color setting of Print Color ("Plot" Color) as the line color.

FabTools offers both colors. Please add this too so I can stick to your single plug-in for this overall feature!

If you can muster some sort of flat closed curve area fill custom preview, that would be rather useful. Using meshes or surfaces gives lots of moire artifacts where they overlap in 2D.

The latest build (attached here) supports reading/creating plot color attributes. 

As for flat/closed area fill - the closest equivalent to this in Rhino is a hatch. However, you will find that planar surfaces, planar meshes, and hatches all rely on the same routines - and thus are likely to result in the same moire artifacts. 


I'm also suffering the fact that colors come through both as RGB lists of three values and yet also as specific names like Black or SeaGreen that a normal user will definitely be using since those are the defaults in the color picker.

I need a converter for the named colors or my Python scripts will fail.

I see there's a system colors file for Rhino:


Found how to get rid of color names in favor of all RGB values, via the Display > Color components:

I did have to right click ARGB to switch from floating to integer input.

Hi Nik - the colors I'm passing out are of type "Color". They are no different than any other color in Grasshopper. You do not need a converter. If you want to use them in a python component merely set the type hint for that input to "color".

In fact on further investigation the type hint should not be necessary. Even the colors which render as a string name (e.g. "DarkBlue") come into python correctly with no typehint, as evidenced by the fact that you can call their properties.


Lack of a user manual keeps frustrating and then delighting me. The x.R trick is just glorious. Where is that documented?! There's no .R pop-up menu hint if I type x. in the Python editor, obviously.

I see it used when I follow a Color link in the Rhinocommon reference document, as being part of .NET:

I had only seen use of .x, .y, and .z to grab the components of a Rhino point, but saw no examples of using .R, .G and .B to get color values.

Found it! Rhinocommon includes color type Color4f meaning four floating point numbers, alpha and RGB:






  • Add Photos
  • View All


  • Add Videos
  • View All

© 2023   Created by Scott Davidson.   Powered by

Badges  |  Report an Issue  |  Terms of Service