A Student's approach to Rhino for Architecture

Greetings,

I’ve been developing a personal tool to allow me to only use Rhino to designing architecture. This post is both to ask for feedback on the idea/approach and the possibility to help someone that is facing the same problem.

Background

I’m an architecture student who has worked with Rhino since my very first year of university. In the beginning it was mostly for modeling but more and more I’ve been trying to break out of Autodesk’s chains for a Rhino-only workflow. Last two years I took a break to work at studios in Belgium/Switzerland where the work was mainly done in Archicad (sometimes I managed to squeeze Rhino into the projects just because it was easier to model/iterate).

Problem

All this to say that I’ve been trying to take the good parts about these products and pour them into Rhino, not only because it’s a wonderful program for some usecases, but McNeel seems like a proper company to support (very few exist like this one these days). I know there are things like VisualARQ and RhinoLands but I prefer a generalized approach to problems (also one of the grips I have with Archicad, sometime efficient but too specific and self involved).

Some features that I miss from other software:

  • Layouting (Archicad)
  • Status Filter (Archicad)
  • Plot Styles (Autocad/Archicad)
  • Style Overrides (Archicad)

Solution

To solve some of my needs, I’ve created a layer structure that incorporates some of the metadata needed. (I wish we could have Custom Properties or a Tag system to handle Status/Authority instead of a one dimensional category system (Layers), I know UserStrings exist but I would have to query every object with X tag in Python).

Schema

+-- $authority [aux, design, context]
    \-- $status [proposed, existing, demolished]
        \-- $category
            \-- $layer

Actual Layers

+-- aux
|   |-- guideline
|   +-- section planes
|   +-- temp
|   \-- underlay
+-- design
|   |-- proposed
|   |   |-- draw [#2d]
|   |   +-- core [#3d]
|   |   +-- extra [#3d] 
|   |   +-- landscape [#3d]
|   |   \-- documentation [#2d]
|   +-- existing
|   \-- demolished
\-- context
    |-- draw [#2d]
    \-- documentation [#2d]

This is a short description and I’m still adjusting it, but just wanted to illustrate how I solved the missing metadata problem.

The layer structure alone would do no good for me, since I needed it to be extensible and to allow me to mess with it’s style on the fly, also creating the layers by hand was getting annoying.

Onto to the script then. It’s packaged in a RHI file and it contains the following:

.
+-- user
|   +-- overrides
|   |   \-- rennovation.json
|   +-- schema.json
|   \-- style.json
+-- SetupLayers_cmd.py
+-- _layers.py
\-- __plugin__.py
  • schema.json: is a dictionary of classes (layers) that have children, it starts off with the root class and they can get referred to multiple times. supported attributes:
    • name: explicit name, otherwise it uses the class name
    • prefix:
    • tags: list of enums, with the syntax #$tag.$option (eg. #status.proposed, it means it has the “proposed” value to the “status” key). Tags automatically appear as command options to be toggled.
    • group: if true it treats the class as a virtual class, generating its children inplace and passing on its attributes to them
    • children: list of children to be created identified by their name
  • style.json: is css-esk dictionary that hold style rules, it only supports a small number of identifiers:
    • layer: the layer itself (however many exist with that “class”)
    • layer *: any children
    • #tag.option: any layer that has the tag
  • overrides: directory that holds styles, exposes an option to toggle them [WIP]

Feel free to drop any suggestion below.

That’s it for now, I’m looking forward to develop this further while I still can — before I finish my Masters — and fully dive into the working world of architecture or perhaps trying my luck starting out my own studio with friends.

Cheers!

5 Likes

Thank you so much for your files. I installed the .rhi file but what do I do now? I am sorry that I am maybe too much a newbie. If you are interested in developing custom scripts or other means to automate 2d documentation for specific purposes or if you have resources to learn what you are developing so I can contribute better, please let me know.

Hey Fritz,

Since then I’ve been working on these and forgot to update the post, here is the latest version.

That’s a good point, I also forgot to explain what it exactly does from a user’s point of view (the post was intended for the tech savy). But alas, here are the commands that this plugin adds:

  • SetupLayers: Creates layers based on some options that are dependent on your JSON configuration. It creates a layer state for each scale and override, here’s an example with 1:100, 1:200 and 1:500 for scales; Renovation and OverrideB for overrides:
    • Default::100
    • Default::200
    • Default::500
    • Renovation::100
    • Renovation::200
    • Renovation::500
    • OverrideB::100
    • OverrideB::200
    • OverrideB::500
  • OpenLayersConfig: Opens the configuation folder used for customizing your layer structure/styles/overrides.
  • OrderLayers: It sets all object’s display order based on their layer style (it uses the display_order attribute in styles.json)
  • MergeLayers: Merges multiple layers into one, this is more of utilty command and I stole from Karim’s script.

For the actual configuration you have three files/directories:

  • schema.json: where you declare the tree structure (it has an schema entry where you can see all the available attributes)
  • styles.json: where you define the styles of each layers in css-esk manner (it also has a schema entry)
  • overrides: each json file in these directory becomes an override, it has the same syntax as styles.json but it’s toggleable in the SetupLayers command and it’s associated with different Layer State(s).

If you have any more questions I would be happy to assist you over Discord,

Good luck

Thank you very much for your rapid answer and sorry for delay in my answering. I showed your posting to others and it gave us good suggestions. We design film sets so our workflow is different, but this gave us a good suggestion on where to go. Thanks again.

1 Like

(There’s a video below showcasing the shiny new additions)

Changelog: Comparing ac30e9d225...02837e755c - oeykmiih/rh_ark - Codeberg.org

Notable Changes:

  • Added GraphicStyle command, per object style based on metadata
  • Added SetObjectTag commad, read tags list from file and present them in command line
  • Rename SetupLayers to CreateLayers,
  • Removed OrderLayers and support for DisplayOrder in layers/styles.json
  • config structure modified to easily accommodate more commands settings
    • layers/styles.json properties are all CamelCase now to better fit Rhino’s coding style
    • config files/folders are to stay snake-case

Latest release: 0.2.1.20241214 - oeykmiih/rh_ark - Codeberg.org
Download it: ark_0.2.1.20241214.rhi

If you installed it before, please go to %AppData%\McNeel\Rhinoceros\8.0\Plug-ins\PythonPlugins\ark (146e099d-760d-4a6c-8662-96119f3fd62f) and delete the earlier version. Rhino does not handle update in Python Plugins unforinately.

Please keep in mind you will lose your configuration of it --I’ll get around to split user/default configs one day so it doesn’t happen

A New Solution

The new command is called GraphicStyle if you wish to try it out without reading furhter

Using a single layers structure was quite tedious, tried it with a couple of projects and although the styles worked perfectly, having to mentally keep track of what the numbers mean was hard at 3 am.

Since then I’ve tried what was my first gut solution: use object UserStrings with key/value pairs and style objects based on that.

I had discarded dubbing it too inneficient without even writing a single line of code, turns out while it still ugly to cycle through all the objects
Rhino.DocObjects.EnumeratorSettings does not have a FindUserStringKey / FindUserStringKey – it was also surprisingly fast (mind you my finally only contain a couple thousand lines).

So this essentially cycles through all the objects (block objects included) and styles them based on a stylesheet. This stylesheet is not longer a css-eske (too complex for very little gains) and instead is order based, the last property value prevails.

The stylesheet is a json array that contains mappings (which I call Rule) with two keys: “Filter” and “Style”. The Filter, well filters out the objects irrelevant objects, the Style sets how the object is going to look. Available propperties – so far – are (please notice the quotation marks, some values need them to work properly):

  • DisplayOrder:
    • values have to be strings, aka envolopped in quotation marks (")
    • "105", can be any number, adds to the existing value (more on that later)
    • "=99", if the number is preceded by a “=” it sets the value to exactly that
    • "%10", if the number is preceded by a “%” it modulos the value
  • DisplayColor
    • #00ff0000, it handles transparency
    • "FromLayer"
    • "FromMaterial"
    • "FromParent"
  • PlotColor
    • #00ff0000, it handles transparency
    • "FromLayer"
    • "FromDisplay"
    • "FromParent"
  • PlotWeight
    • 1.0
    • 0.0 for Default
    • -1.0 for NoPrint
    • "FromLayer"
    • "FromParent"
  • Linetype
    • "Dash", linetype name

Making it easier

So, now that I can style based on metadata I need an easy way to set such data. For that I’ve create the SetObjectTag command that read from /config/tags.json and prompts the user to choose a key first then a value.

I’ve create keyboard shortcuts from Ctrl+1 to Ctrl+7 to run SetObjectTag, set the Visibility key and then run the GraphicStyle command. It works!!!

Here’s a video showcasing it:

There’s more I’d like to explain, but that’s it for now. If you have any feedback please feel free to leave it here!

Cheers