algorithmic modeling for Rhino

Dear Users,

I've been working on data tree selection rules this weekend and when 0.9.0063 is released (hopefully tomorrow, 4th November) the [Path Compare], [Tree Split] and [Replace Path] components will work slightly different from before. Sorry about breaking this, but it proved impossible to improve the selection logic with the fairly ambiguous notation that was implemented already.

Not every change is breaking though and I hope that most simple matching rules will work as before. There will be a McNeel webinar on Wednesday the 6th of November where I discuss the new selection rules (as well as path mapping syntax and relative offsets within one or more data trees). This will be a pretty hard-core webinar aimed at expert users. The event will be recorded so you can always go and watch it later. I figured I'd briefly explain the new selection rules on Ning before I release the update though.


Imagine we have the following data tree, containing a bunch of textual characters:

{0;0} = [a,e,i,o,u,y]
{0;1} = [ä,ë,ê,ï,î,ö,ô,õ,ü,û,ÿ,ý]
{1;0} = [b,c,d,f,g,h,j,k,l,m,n,p,q,r,s,t,v,w,x,z]
{1;1} = [ç,ĉ,č,ĝ,ř,š,ş,ž]

There are a total of four branches {0;0}, {0;1}, {1;0} and {1;1}. The first branch contains all the vowels that are part of the standard English alphabet. The second branch contains all non-standard vowels and branches three and four contain the standard and non-standard consonants respectively.

So what if we want to select from this tree only the standard vowels? Basically include everything in the first branch and disregard everything else. We can use the [Tree Split] component with a selection rule to achieve this:


This selection rule hard-codes the number zero in both tree path locations. It doesn't define an item index rule, so all items in {0;0} will be selected.

If we want all the vowels (both standard and non-standard), then we have several options:

{0;?}         = select all branches that start with 0

{0;(0,1)}    = select all branches that start with 0 and end in either 0 or 1

{0;(0 to 1)} =    ......................................... and end in the range 0 to 1.

Conversely, selecting all standard vowels and consonants while disregarding all non-standard character can be achieved with rules as follows:



{(0 to 1);0}

It is also possible to select items from each branch in addition to limiting the selection to specific branches. In this case another rule stated in square brackets needs to be appended:

{0;?}[0 to 2]

The above rule will select the first three vowels from the standard and the non-standard lists.

Basically, rules work in a very consistent way, but there are some syntax conventions you need to know. The first thing to realize is that every individual piece of data in a data-tree can be uniquely and unambiguously identified by a collection of integers. One integer describes its index within the branch and the others are used to identify the branch within the tree. As a result a rule for selection items always looks the same:

{A;B;C;...;Z}[i]              where A, B, C, Z and i represent rules.

It's very similar to the Path Mapper syntax except it uses square brackets instead of parenthesis for the index (the Path Mapper will follow suit soon, but that won't be a breaking change). You always have to define the path selector rule in between curly brackets. You can supply any number of rules as long as you separate them with semi-colons.

The index rule is optional, but -when provided- it has to be encased in square brackets after the path selection rule(s).

The following rule notations are allowed:

*  Any number of integers in a path

?  Any single integer

6  Any specific integer

!6  Anything except a specific integer

(2,6,7)  Any one of the specific integers in this group.

!(2,6,7)  Anything except one of the integers in this group.

(2 to 20)  Any integer in this range (including both 2 and 20).

!(2 to 20) Any integer outside this range.

(0,2,...)  Any integer part of this infinite sequence. Sequences have to be at least two integers long, and every subsequent integer has to be bigger than the previous one (sorry, that may be a temporary limitation, don't know yet).

(0,2,...,48)  Any integer part of this finite sequence. You can optionally provide a single sequence limit after the three dots.

!(3,5,...)  Any integer not part of this infinite sequence. The sequence doesn't extend to the left, only towards the right. So this rule would select the numbers 0, 1, 2, 4, 6, 8, 10, 12 and all remaining even numbers.

!(7,10,21,...,425)  Any integer not part of this finite sequence.

Furthermore, it is possible to combine two or more rules using the boolean and/or operators. If you want to select the first five items in every list of a datatree and also the items 7, 12 and 42, then the selection rule would look as follows:

{*}[(0 to 4) or (6,11,41)]

The asterisk allows you to include all branches, no matter what their paths looks like.

It is at present not possible to use the parenthesis to define rule precedence, rules are always evaluated from left to right. It is at present also not possible to use negative integers to identify items from the end of a list.

If you want to know more, join the Webinar on Wednesday!


David Rutten

Seattle, WA

Views: 74647

Replies to This Discussion

Well if you want to use Split Tree then yes, you'll have to make the mask through logic. However you don't need Split Tree for getting the first and last items out of a list. You need the [List Item] component with the indices 0 and -1.

Could you cast all dbl to int inside a selection rule? Or give an option to output an integer domain from [domain]?

While trying to use a [domain] output as selection rule to create a subtree, I only got to this.

Hi Philip,

yes I can support floating point numbers in addition to pure integers, but you'd still have to add the {, }, [, and ] brackets to make it valid notation.

I added support for floating point values in rule notation to GH1 for Rhino WIP:

Cool, thanks David!

I still do not quite get the formating though. How do I get a mask with the inputs as the domain bounds?

Derived from the above using {{0}}to{{1}} will result in a static output and "{"{0}to{1}"}" is not accepted.

Curly braces indicate placeholders. The number inside curly braces indicates which input value should be inserted at that location. If you want to use curly braces just as curly braces, you need to 'escape' them by using two curly braces.

If you want to achieve this: {A to B} where A and B are numbers stored in indices 0 and 1 respectively, the format you need is: {{{0} to {1}}}   where the bold braces indicate placeholders and the regular braces indicate just braces, but they're doubled up because they need to be escaped.

This is one (of many) online resources talking about how format works:


Hi David, 

I am struggling to find a solution related to data tree management. I am trying to find the closest wall to each window in a room (see picture below) but I cannot manage get the resulting data tree that I would like.

It would be really useful to be able to solve this because I often have similar problems.

Thanks in advance, 



Hi gang, 

What am I doing wrong?

Is it possible to select items with the same index from every branch? And then therefore have the items with the same index create their own branch

Flip Matrix or Path Mapper will let you do this. 

Sometimes Path Mapper will be a little restrictive, as if you change your tree structure up stream of it the rule will no longer be valid. Have a little search on the Forum though; there's plenty of tricks and advice hidden on these pages.

Hi David,

How do you get the last item in the tree? I know in "list item" we can choose (-1), but that does not work in split tree.







© 2024   Created by Scott Davidson.   Powered by

Badges  |  Report an Issue  |  Terms of Service