Working with Expressions
The Key Concept: Expressions Can Refer To Other Attributes
The ability to compose and alter an attribute's expression is what gives Smart Objects their flexibility and power. Expressions are simple. They can contain:
- A numerical expression.
- A reference to another attribute.
- An algebraic expression containing at most one numerical expression and as many attribute references as you like.
For example, Design Intuition bases the Left position of an object on some percentage of its containing group's Width -- offset from the group's Left position. This is logical: the object has it's origin somewhere between the containing groups beginning or end, and this can be expressed as the Width, of the group, multiplied by some number between zero and one, inclusive.
How to Enter Expressions
- Select the attribute for which you want to edit an expression, using one of the following methods (if you want to edit an authored attribute, only the first method will work):
- Expand your object in the Details View and select the attribute.
- Use the drill down key in the document view to select the face of your object.
- Select a dimension of your object in the document view.
- Open the Attribute Inspector. Your attribute and all of its pieces will be waiting for you.
- In the Expression field, enter an algebraic expression. Use the * key (shift-8) for multiplication and the / key for division.
- Press return to let Design Intuition know you are done.
Design Intuition has Type-Ahead
In an expression, as you type in each letter for a reference, Design Intuition looks for an attribute whose name begins with what you've typed so far. It uses the same context that it uses when you are done entering it (described immediately below). This will help you troubleshoot your expressions as you type them, rather than trying to figure out which reference is mistyped, and is yet another example of immediacy working hard for you, so you don't have to!
Occasionally, though, Design Intuition types the wrong thing for you. Simply keep typing.
How Design Intuition Evaluates Expressions
When you are done entering an expression, Design Intuition evaluates it. To do so, Design Intuition looks up each reference within the attribute's context. The context is an object, and all the parents of that object. Which object? It could be the attribute's object, but usually it isn't. Usually the context object is the parent of the attribute's object.
The context is the parent? Why?
Well, the reason has to do with making things easy and not tedious. By making the parent the normal or usual context, all expressions are evaluated based on the values of the parent. This creates a "scaling effect," one in which objects inside a group scale with the group. This seems like a good behavior for objects to start out with. This behavior and the parent context, makes expressions easy to write -- they're short and to the point. Why write more than you have to? The more you have to type to accomplish a task, the more tedious, and the more error-prone.
So, when you first create an object and look in the Object inspector, you'll see that the expressions are all fairly short:
|
Attribute
|
Expression
|
|
|
Left
|
Left + (Width * 0) | |
|
Front
|
Front + (Depth * 0) | |
|
Bottom
|
Bottom - (Height * 0) | |
|
Width
|
Width * 1 | |
|
Depth
|
Depth * 1 | |
|
Height
|
Height * 1 | |
|
Right
|
Left + Width | |
|
Back
|
Front + Depth | |
|
Top
|
Bottom + Height |
Back to Evaluating...
Each reference is resolved to an attribute whose name matches. So, it looks in the context object. If the name of the reference matches an attribute in the context, the reference is considered resolved, and Design Intuition moves on with the rest of the attribute's expression. However, if no match for the reference is found in that context object, Design Intuition will look in the parent, and then in the parent's parent and keep going until it finds a match.
What if the reference never matches?
If Design Intuition doesn't find a match, it display an error message "unknown attribute." If you see this error, look carefully at your expression for spelling errors or think about the context maybe being the wrong object.
What is the checkbox labeled Refers to Attributes in Object?
The usual context is an attribute's object's parent. The ONLY alternative is to select the attribute's object as the context. That's what the Refers to Attributes in Object checkbox allows you to select.
This control may seem minor but it's important. It comes in very handy when you add authored attributes to your design or to a particular object or group in your design. The only reason to add an authored attribute is for other attributes to refer to them. If an attribute in an object refers to an authored attribute in the same object, you need to check this box, or Design Intuition won't find it.
Be careful that once you check this box on an attribute, that the expression for that attribute not refer to itself. Otherwise, Design Intuition will display an error message "self-referential attribute."
In general, other than the depend form (explained below), there are very few occasions in which the Refers to Attributes in Object checkbox needs to be checked. Very few that I know of.
Example: A Smart Cube
You might use Search Object First, for instance, to create a Smart Cube. For this, you first create an object. Then add an attribute to that object, called Common, giving it an expression of 1' (one foot). Then, for each of the dimensional attributes of your object (ie, Width, Depth and Height), check the Refers to Attributes in Object checkbox and set each of their expressions to Common. Voila! Your cube is done. Summarized below, the first two columns are what you will see in the document inspector:
Name Value Refers to Attributes in Object Width Common checked Depth Common checked Height Common checked Common 1' (doesn't matter)
Try it and then try resizing it in the document view by selecting it and then grabbing and dragging one of the resize handles.
What are those Value, Name, Scale and Depend buttons?
Dangerous, in a word. These are what we call forms, as in "the forms that an expression can take." Let's look at the table again, and this time, let's show it with the form of the expression:
|
Attribute
|
Forms
|
Expression
|
|
|
||
|
Left
|
scale
|
Left + (Width * 0) |
|
Front
|
scale
|
Front + (Depth * 0) |
|
Bottom
|
scale
|
Bottom - (Height * 0) |
|
Width
|
scale
|
Width * 1 |
|
Depth
|
scale
|
Depth * 1 |
|
Height
|
scale
|
Height * 1 |
|
Right
|
depend
|
Left + Width |
|
Back
|
depend
|
Front + Depth |
|
Top
|
depend
|
Bottom + Height |
Why are those buttons dangerous? Well, the Name button is dangerous. If you click on it in an attribute, what your doing is telling Design Intuition that the attribute should take on the same value as the corresponding one (the one that has the same name) in the parent. This is rarely a good idea. Here is what these buttons do:
|
Form
|
What it does
|
Consequences
|
|
Value
|
Copies the Value of the attribute into the expression, making the attribute numerical | Resizing the group containing this object will not affect the object. Resizing the object, will cause the attribute's value AND expression to be updated |
|
Name
|
Copies the name of the attribute into the expression. This object will exactly match the parent in this position or dimension. | Resizing the group containing this object will alter the object so that it will exactly match the parent in this position or dimension |
|
Scale
|
Copies the name of the attribute into the expression and then adds a multiply and a factor such that the expression will compute the the attribute's current value | Responsible for the normal "scaling effect" in which, when you resize a group, the contained object scales accordingly |
|
Depend
|
Check the box labeled Refers to Attributes in Object. Creates an expression referring to the other two attributes on the same axis. Eg, see the three depend expressions in the table above | Relies on other components in the object for it's value. |
Here's something very important: In each axial triad (see below), exactly one attribute must have a depend form. In the above table, the Right attribute has the depend form, the others have scale form. You'll notice that each of the depend formed attributes have expressions with two references in them. For example, Right refers to both Left and Width. These are the other two attributes on that axis. If either of these other two attributes has a depend form, they will refer back to this one, which refers to that one -- bad things will happen, don't go there.
What if I want something different than these forms?
That's easy -- simply enter the expression that you want. Design Intuition will examine it and decide if it fits one of the four forms. If it does, the corresponding form button will highlight. If your expression doesn't correspond to any of those four forms, none of the buttons will highlight. What that's the case, Design Intuition will treat it as a customized expression, and leave it alone (except for any numbers included in it, see below).
Axial Triads
Consider the table from the previous web page, again.
| Axis | Axial Triad of Attributes | ||
| X | Left, Right, Width | ||
| Y | Front, Back, Depth | ||
| Z | Top, Bottom, Height | ||
For each of the three axes, Design Intuition provides three attributes, constituting an axial triad. For example, Left, Width and Right are on the same axis. Every object has exactly three axes and exactly three axial triads.
Here's something very important: Within every axial triad, exactly one attribute must have "depend" form.
Another thing to consider about axial triads: When you alter the expression of an attribute, you probably will want to alter one or both expressions of the other two attributes in that axial triad. So, I recommend at least thinking about those other two expressions.
Design Intuition altered the number in my expression! Why?
Any and all numbers in expressions are likely to be altered by Design Intuition. This is part of the magic of Design Intuition, though the explanation is challenging. Let's begin with an example:
Beginning with a fresh, empty design, create two objects. Then, in the inspector window, check the box labeled Expressions, located near the top of the window. Now, move one of the objects around, and as you do so, look at the expressions in the Object inspector. Notice that four of the expressions are rapidly changing.
Here's what would happen if these expressions didn't change: the object wouldn't move!
As the object is moved, the size of the containing group changes. Consider the Width, for a moment, both of the moving object and of the containing group. As the value of the Width attribute of the group increases, the value of the Width attribute of the moving object does NOT change. In order to make this happen, the expression of the Width attribute of the moving object has to change such that the expression evaluates to the current (unchanging) value. Design Intuition does this for you. We call it Reverse Parsing.
Egads! I need to include numbers! What do I do?
So, if you want an expression to include a number (say, to divide by two), create an authored attribute, enter a value in the Value field, type return, click on the Value form button and then lock it's value. Then, in your attribute, refer to this authored expression.
Guidelines for Creating Expressions
Design Intuition has its own mathematical universe that has certain "best practices" to follow when creating expressions. If you don't, your Smart Objects may have bizarre and unpredictable behaviors. And while such behaviors can be amusing, they more likely will frustrate you. Typically, the object containing your unruly attribute will simply disappear from view, jetting off hundreds of units away.
These guidelines also exist because the order in which attributes are evaluated is somewhat arbitrary, and may change in future releases. What we can guarantee is that, if these guidelines are followed, your Smart Objects will still work in future releases. We may even build into Design Intuition a feedback mechanism to alert you when a guideline is overstepped.
For now, here are the guidelines for creating an expression:
- Avoid including numbers in your expressions. Instead, create authored attributes with locked values, and refer to them in your expressions.
- In elements (non-authored attributes), restrict your references to either authored attributes or elements in the same axial triad.
- In each axial triad of attributes, exactly one must have depend form.
- When you alter the expression of an attribute, I recommend at least thinking about the expressions of the other two attributes in its axial triad -- one or both may need to be altered, as well.
- The value of an expression must never compute to a location outside the object's containing group. For example, things will get ugly if you write an expression for an object's Left position as Left - 1". That expression yields a value to the left of the group's left edge! Design Intuition will do its best to manage the spacial anomaly, but the results are unpredictable. Don't go there.
- An expression must never be self-referential. If, by accident or design, you do create such an expression, Design Intuition will report an error. To fix this, either uncheck Refers to Attributes in Object or remove self-references (eg, if your attribute's key is Left and your expression refers to Left). It's allowed, for example, to define Left as "Right - PlywoodThickness."
- Other than the depend form, there are very few occasions in which the Refers to Attributes in Object checkbox needs to be checked. Very few that I know of.
