Key Table - The Inner Secrets of Nodebox

john's Avatar

john

01 Sep, 2024 02:51 AM

NOTE: The version of the key table demo attached to this note causes an error when you try to open it. I have attached a corrected version below. Thanks to Gottfried for finding this.

Attached is another new node intended only for advanced Nodebox users. Beginners will have little use for it, but it has helped me explore the more technical side of Nodebox and solve various mysteries.

The Keys node was one of the very first things I ever wished for as a Nodebox Newbie. In 2015 it was added as a standard node and I have used it regularly ever since:

http://support.nodebox.net/discussions/nodebox-2-3/5390-extract-col...

You can use Keys to find the headers of a CSV file, but you can also point it at standard Nodebox objects to discover their hidden properties. It is tedious to inspect these properties (and properties of those properties) one at a time, so I soon developed a node to create a table of keys and their values. This took some doing because many keys of Nodebox objects return nothing - which throws off the rest of the table, and other keys return values that trigger errors if you so much as touch them.

In order to fully understand the keys that different objects return, you need to learn a little about data types or "classes". Nodebox was designed for artists, not developers, so it tries to hide this complexity, but sometimes these classes matter.

It turns out there are 9 different types of objects in Nodebox, plus 2 other underlying types that can be easily accessed. In screenshot 1 you can see that I have combined these types and fed them into a summary table (the top table):

  • Path (black nodes). Includes lines, rects, ellipses, arcs, curves, polygons, text paths and pretty much anything you draw in Nodebox.
  • Geometry (black nodes). Groups of paths.
  • Point (light blue nodes). Individual x,y points.
  • String (dark gray nodes). Text.
  • Color (purple nodes). Hex color codes. There is also a Java Color class, but it is not usable in Nodebox.
  • Int (light gray nodes). Whole numbers produced by an Integer node. Technically these are in class "Long".
  • Float (light gray nodes). Floating point numbers produced by a number node. Technically these are in class "Double".
  • Boolean (dark gray nodes). True or false values produced by checkboxes. Treated as 1s and 0s by math nodes.
  • Data (dark blue nodes). Results of lookup or table nodes. NOT SHOWN IN SUMMARY TABLE because they are containers which only return keys for their contents, not for themselves.
  • Integer (returned by data nodes). A JAVA integer used by certain properties. Must be converted to a Nodebox int by feeding into an integer node to be used by Nodebox math nodes.
  • ArrayList (returned by data nodes). An array of objects like the paths in a group, the points in a path, or the contours in a compound path. These require a modified lookup node to be used within Nodebox (see below).

The lower table in screenshot 1 shows a subset of the recoverable key properties from all these objects. My key_table node has three checkboxes which filter the output:

  • Usable only. Only show key values that can actually be accessed within Nodebox. If you uncheck this box you will see many more strange properties with underlying Java-based values that cannot even be touched in Nodebox. In fact, the draw_table node will generate an error if you try to draw the key table in this mode.
  • Exclude class. Exclude classes and subclasses which have limited use and tend to clutter the table.
  • Exclude color. Exclude secondary color properties of paths which have been colorized (e.g. fillColor, fillColor.alpha, fillColor.blue, etc.). There are a lot of these which tend to clutter the table. Checking this box will NOT exclude the primary properties of a color node.

Notice that the key table includes both keys and sub.keys (e.g. pointCount and bounds.width). I show two sub.sub.keys, bounds.rectangle2D.maxX, and bounds.rectangle2D.maxY, because they are particularly useful, but other than that stop at two levels. If you want you can use the keys node to explore even deeper, into keys of keys of keys of keys, but these are rabbit holes that rarely lead anywhere useful.

Here are some of the most useful properties I've found using key table:

  • bounds.width. The width of a rect or the bounding box of an ellipse or other shape
  • bounds.height. The height of a rect or bounding box
  • bounds.position. The upper left corner of a bounding box. Can also use bounds.x and bounds.y
  • bounds.rectangle2D.maxX and Y. The lower right corner of a bounding box.
  • brightness. The brightness of a color. You can also lookup hue, saturation, red, blue, green, and alpha.
  • contours. I use this lookup in my contours node to recover the separate contours in textpath.
  • length. The length of a path, as opposed to the length node, which returns the length of a string.
  • pointCount. The number of points in a path. Saves having to convert to points then using a count node.
  • type. Points come in three types: 1 for straight lines, 2 for the endpoints of curves, and 3 for bezier control points. Invaluable when mucking with paths.
  • x and y. The x,y coordinates of a point. Invaluable.

All of these properties can be accessed by simply passing these key names into a lookup node.

As I mentioned above, the two non-native classes, Integer and arrayList require an extra step and may cause baffling errors without that extra step. For examples, see the four nodes hanging off the right side of the subtree in the screenshot. You can open the demo to follow along.

The first node, compare1, is attached to a simple lookup of a point type. If you render lookup6 you will see this is a standard type 1 point. That 1 looks like a Nodebox int, but it's actually a Java integer. The compare1 node does a simple test to see if it is type 1. If you try rendering this node you will get a surprise: an error message full of gobbledegook. I found this very puzzling the first time it happened to me. But now I know the solution: just feed the lookup node into a Nodebox integer node to convert it before feeding it into a compare node or most any other math node. Problem solved, as you can see by rendering compare2.

The next two nodes, count1 and count2, are both connected to lookup nodes that appear to be identical. Both return the points in a 32-sided polygon. But when you count them, count1 returns 1 and count2 returns 32! If you render both lookups in viewer mode, they will both show 32 points; if you check the Point Numbers checkbox on lookup 2 you will see their numbers, but if you try the same thing on lookup 1 you will get an error message. What is going on here?

A clue will come if you look at both lookup nodes in data mode: lookup2 will show a list of 32 points, but lookup1 shows a single item with square brackets enclosing a comma-separated list. That single item is an arrayList. And that's what you get if you use the normal lookup node.

The only difference between lookup1 and lookup2 is revealed by selecting them and opening the Metadata dialog. Choose Node/Settings, then look at the Output Range. Lookup1 has an Output Range set to Value, which is the normal setting for this node. Lookup2 is the same node, but with Output Range manually changed to List. Normally mucking with things like this in standard nodes will cause problems, but in this case it is safe to do and tells the lookup node to return a list of points instead of a single arrayList. This is the trick I used to recover individual contours from text paths.

The Keys node can also be used, as it was originally intended, to find the column headers of CSV files and Nodebox tables. But looking at the key values of individual cells in such tables can also be useful, as I show in screenshot 2.

The upper table in screenshot 2 is a simple 3 row table showing fruits and prices. My recently improved draw_table node displays it with no issues. Now, suppose we wanted to calculate the sum of the prices. On the right you can see lookup3 which, if you render it, displays a list of those 3 prices: 11.45, 20, and 105.12. When we feed that into the sum1 node, we would expect to see the sum of those three values. But instead we get another strange error. What is going on?

Key table to the rescue! As you can see in the lower table, when you look at the class of all six cells you can see that all three fruits are strings, but not all three prices are the same type; two are Doubles (floating point numbers), but one is a Long (an integer).

It turns out that Nodebox doesn't like to sum (or max or average) a list of numbers of different types. It wants either all integers or all floating point numbers. Hence the inscrutable error message. As I show with sum2, you can fix this by feeding the list through a number node.

This example is contrived. I made it by purposely inserting an integer between two floating point numbers. But similar things do happen when you import CSV files. Sometimes, when you try to work with the values in such a file, you get errors like this. When you look at the numbers in Nodebox or Excel, they appear perfectly normal and indistinguishable. But for odd reasons, sometimes a subset of numbers will be of a different class than the rest, as revealed by my key_table node.

Congratulations to anyone who actually made it this far. I realize this post is arcane, but it does illuminate some otherwise undocumented Nodebox secrets that I have uncovered with much pain and effort over many years. Key_table is a gem within my toolbox and I am happy to finally share it.

John

  1. 1 Posted by lastvector on 02 Sep, 2024 10:23 AM

    lastvector's Avatar

    John

    That fits together perfectly.
    Well, I don't consider myself an advanced user. But I don't shy away
    from experimenting with Nodes that aren't intended for Beginners :)

    I've often looked at nodes with the Key Node to see which Parameters
    could be addressed via the Lookup Node. So that compilation will be
    pretty useful

    Thank you very much for this Compilation.
    gottfried

  2. 2 Posted by lastvector on 03 Sep, 2024 06:27 AM

    lastvector's Avatar

    John

    Unfortunately I get this error message when I open
    the file "key_table.ndbx".
    Any Solution for this ?

    See picture

    gottfried

  3. Support Staff 3 Posted by john on 03 Sep, 2024 07:16 AM

    john's Avatar

    Gottfried,

    OOPS! My mistake. I accidentally left in a code module reference that I used while developing this.

    I have attached an updated version which should solve the problem. Could you please try downloading it and verify that it now works for you?

    Thanks for alerting me to this issue!

    John

  4. 4 Posted by lastvector on 03 Sep, 2024 10:07 AM

    lastvector's Avatar

    John

    Thank you John
    is working now

    gottfried

Reply to this discussion

Internal reply

Formatting help / Preview (switch to plain text) No formatting (switch to Markdown)

Attaching KB article:

»

Already uploaded files

  • key_table_1_screenshot.png 858 KB
  • key_table_2_screenshot.png 556 KB
  • key_table.ndbx.zip 214 KB

Attached Files

You can attach files up to 10MB

If you don't have an account yet, we need to confirm you're human and not a machine trying to post spam.

Keyboard shortcuts

Generic

? Show this help
ESC Blurs the current field

Comment Form

r Focus the comment reply box
^ + ↩ Submit the comment

You can use Command ⌘ instead of Control ^ on Mac

Recent Discussions

01 Oct, 2024 07:59 AM
30 Sep, 2024 11:37 PM
30 Sep, 2024 11:11 AM
30 Sep, 2024 02:37 AM
28 Sep, 2024 10:33 AM

 

26 Sep, 2024 06:41 AM
24 Sep, 2024 12:32 AM
24 Sep, 2024 12:27 AM
13 Sep, 2024 12:07 AM
12 Sep, 2024 11:54 PM
07 Sep, 2024 05:16 AM