Named Structure Tools

Excluding Children

Since we have seen that children "inherit" the Named Structures of their parents - which is necessary if you don't want to swamp your scene with NS tags -, the question arises how we can exclude a child from that inheritance. If that option would not be available, kinematic requirements (the object tree structure) would determine a good part of our Named Structures.

The solution is simple. If the parent defines a NS "red", the child can use the anti-NS "!red" - same name, with an exclamation mark in front. (Programmers of current languages like C++ or Java will recognize that symbol as a logical "Not" - let's call it Not flag in this context.) This excludes the child, and all its children, from that Named Structure. Of course, a child of that child may have a NS name "red" of its own again.

Don't try to be smart and define "red !red" in the NS tags of the same object. The result of that trick is undefined, and depends on both the sequence of the names, and the function that is internally executed.

Note: If you use the NS Visibility functionality, children that use anti-NS names are explicitly excluded from the NS, and their visibility will be set appropriately. However, if you use the NS Selection functionality, children will be indirectly selected through their parents even if they bear an anti-NS name. You can not select a parent but not its children. This limitation is due to Cinema's selection model.

Another note: Look closely, and you can see how similar the NS names are to the visibility flags. A NS name in a tag is the equivalent of the "Visible" flag set. The same name as anti-NS name (with the Not flag) is the equivalent of the "Invisible" flag set. And not having that NS name is the equivalent of "Undefined" (or better, "Inherited"). Each NS name yields such a flag, and since you can define Named Structures on your own, you can get an arbitrary number of these flags.

In the example, you will find an anti-NS in the red pyramid at the end of the object tree. The five spheres that cover the corners of the pyramid are not pyramids themselves, but they would inherit the Named Structures "pyramid" and "pointy" from its parent. Therefore, the NS tag of that group uses the anti-NS construction !pyramid !pointy to exclude these geometries.

Try to set "Only these" visibility on "pyramid", and verify that the red pyramid is still visible, but its children are not.

Named Structure Expressions

The final and maybe most powerful feature in Named Structure Control are the NS expressions. After all these examples, you might have wondered: Okay, I can now make all pyramids visible, and all green objects, but can I make all objects visible which are green and pyramids?

Yes, you can.

Type "pyramid & green" in the input field.

In fact, the input field is not just an input field for names, it is a full parser for logical expressions that involve Named Structures. You can combine NS names with or, and or not. You can use brackets to set priorities, too.

The symbols are:

The symbols are all taken from programming languages. Always use the symbols - the words and, or, or not will be recognized as named structure names, not as operators!

Note that the Not flag symbol "!" is used for both anti-NS and the not in expressions. In both cases, it inverts the meaning of the name. But don't make the mistake to think "!green" in an expression means "objects where the anti-NS !green is set". The latter does not exist - anti-NS are not set! They just exclude the object from a Named Structure, but do not define a Named Structure of their own. An object where "!green" is set, is no different from an object where "green" was never set in the first place.

With that knowledge, you can now construct your own expressions. Try "pyramid & green | cube & !red" to select all green pyramids and all not-red cubes at the same time (& binds more strongly than |). When in doubt, use brackets: "cylinder & (green | cube) & blue" will yield no object at all (find out why...).

Using Wildcards

The expressions are already a powerful tool, but they can do even more. They support wildcards in names. You may know wildcards from command lines already, or from search-and-replace methods in more complex text processors, or you may even know the more powerful "big brother" of wildcards, the Regular Expression.

What is a wildcard? In short, it's a special character that stands for "any character" or "any sequence of characters". In our case, the first is a question mark (?) and the second is a hash mark (#).

That means: If you write color#, this pattern will match colorRed, colorBlue, colorTag, colorization, and so on. It also matches color, since the hash mark may also stand for an empty sequence of characters. If you write color?, this pattern will match color1, colorA, colors, or colore (but not colored or colorBlue, since the question mark only symbolizes one single character).

You can use ? and # anywhere in any name, as often as you want to. Setting a # at the end of a name would represent "any Named Structure that starts with ...". Setting a # at the beginning of a name would represent "any Named Structure that ends with ...". Setting a # at the beginning and end of a name would represent "any Named Structure that contains ...". A single # denotes any Named Structure.

Question marks may be aggregated: c???r represents any Named Structure that starts with a c, ends with an r, and has exactly three arbitrary letters inbetween. (With hash marks, this makes no sense since any hash mark already represents a character sequence with any length, so c#r is the same as c###r.)

Now, what is the practical use of wildcards? Very simple. By using strict name conventions for your Named Structures, you can afterwards select certain subsets of a name without having to assign separate Named Structures that mark those subsets. For example, if you use Named Structures like red, blue, white, you will see little use in wildcards. But if you use names color_bright_yellow, color_greyscale_mediumgrey, color_primary_blue, then you can select all color tags by color#, all greyscales by #greyscale#, or all primary colors by #primary#.

Is this necessary? You may as well define the separate tags color, bright, greyscale, primary, blue and so on, and assign multiple Named Structures to each object. This requires just the same level of scrutiny in choosing the Named Structures, and is always an option. However, a naming convention like the one above would ensure that each object that has a color also has a color modifier like bright or primary, and a color name like blue or mediumgrey, but never two or more color modifiers. Putting these name parts together in one Named Structure pattern makes the schema behind your idea more visible, and constantly reminds you to keep up the good engineering ;-)

But, as I said, there are always several ways to do things, and whether you use wildcards, patterns, or Named Structures at all is up to you.

(As a sidenote, you may ask, if I use the question mark like a DOS command prompt, why don't I use a asterisk sign (*) instead of the hash mark since that's the usual way under DOS? Well, the asterisk is already the multiplication operator in the expression parser - which is designed for more complicated things than just Named Structure Expressions -, and I wanted to avoid conflicts. Multiplication may not be used here in the Named Structure Expressions, but they may become important in the course of future extensions.)

Setting and removing NS tags by dialog

The fourth section in the dialog shows three buttons: "Set (in first)", "Set (in new)", and "Remove". These are helper functions that allow setting NS tags in multiple objects.

You can set all NS tags manually since you can generate this tag type through the object's right mouse menu. You can manipulate the names contained in a tag directly by editing the name string You can copy such a tag by drag and drop to all the elements you want to equip with it. But that's sometimes awkward.

The button functionality allows you to manipulate the Named Structures of all selected objects at the same time. Enter an NS name, or a list of NS names, in the dialog's input field (a list in the same form as they are entered in the tag itself, not an expression as in the previous functions!) and press a button. The names may have an anti-tag symbol.

Some notes are in order here:

First, you will observe that these functions work with some intelligence. If a name already exists within the tag itself, it will not be added (Set (in new) may not create a tag then). If the name exists but with the opposite anti-tag (!red exists, and red is set, or red exists, and !red is set), then no new name will be added, but the existing name will switch its anti-tag to reflect the new state. The functions take all existing Named Structure tags into account which are attached to the current object, and try to restore the same order of names and tags after finishing. After removing a name, a tag may be empty; these unused tags are automatically deleted.

Second, the functions will not take inheritance of Named Structures into account. If the NS name red is to be set, the functions will not look into the parent's tags to check whether this named structure is set there. The name is added to the object, even if it would not be strictly necessary. The functions will assume that you want the current object to be explicitly equipped with that Named Structure, and follow your order. Likewise, removing a tag does not mean removing the Named Structure because the parent may also define the same structure, and the child will still inherit it even if the own tag is removed.

Third, for that reason setting and removing a tag is not quite the equivalent of adding and removing objects to/from a layer. You can see the layer concept as a simplified metaphor for Named Structures, if you like. Not counting inheritance of Named Structures and anti-NS tags, yes, setting an NS name means adding the object to a layer, and removing the NS name means removing the object from a layer. However, with the inheritance and the anti-NS names things get a bit more complicated. When you set or remove a tag, and don't get the desired results, think about it for a moment and check the inherited Named Structures, and you will quickly get a reason for the failure.


Back to Main Manual Page