ZBrushCentral

ZScript Tips II

Here’s a follow-up to my last post, where I introduced the idea of placing often-used ZScript buttons in the ZScript window accessible through keyboard shortcuts.

To introduce two useful ZScript concepts, we’ll create two buttons, one which refers to another file, and one which calls a routine.

Routines are segments of code which can be called on and executed using a single command. There are many reasons to place code segments within callable routines. For one thing, you can execute them numerous times; for another, you can make your ZScripts more readable by separating the “guts” from the ordinary text.

Remember that you can use any text editor or word processor to create ZScripts (Mac users: file name must end in .txt).

Let’s start with the routine. This’ll be a helpful function that shows you an object’s location, size and orientation in a single note.

Here’s the code, followed by a line-by-line explanation:

[RoutineDef,GetObjectInfo,
[if,[isEnabled,transform:move],
[TransformGet,zbsMX,zbsMY,zbsMZ,zbsEX,zbsEY,zbsEZ,zbsRX,zbsRY,zbsRZ]
[Note,"\Cffa000Position:
\Cc0c0c0",-1]
[Note,zbsMX,-1][Note,",",-1]
[Note,zbsMY,-1][Note,",",-1]
[Note,zbsMZ,-1][Note,"

“,-1]
[Note,”\Cffa000Size:
\Cc0c0c0",-1]
[Note,zbsEX,-1][Note,",",-1]
[Note,zbsEY,-1][Note,",",-1]
[Note,zbsEZ,-1][Note,"

“,-1]
[Note,”\Cffa000Orientation:
\Cc0c0c0",-1]
[Note,zbsRX,-1][Note,",",-1]
[Note,zbsRY,-1][Note,",",-1]
[Note,zbsRZ,-1][Note,"

",0]
, // else (Move button is not enabled)
[Note,“Cannot determine transformation values for most-recently-drawn object”]
] // closing bracket for “if”
] // final closing bracket for routine

Explanation:

Note that, in each line, the double-slashes and everything that follows them are not necessary; they’re comments added by me to make the code a little more readable.

<BLOCKQUOTE>quote:</font><HR>[RoutineDef,GetObjectInfo,<HR></BLOCKQUOTE>

The beginning of the routine definition. “GetObjectInfo” is the name I’ll use to refer to this whole block of code. Don’t forget that last comma.

<BLOCKQUOTE>quote:</font><HR>[if,[isEnabled,transform:move],<HR></BLOCKQUOTE>

First, determine if the Move button is enabled (or if it’s grayed out). We do this because the Move button is only enabled when you draw a 3D object or when you use a 2D brush with the Drag-Rect stroke.

<BLOCKQUOTE>quote:</font><HR>[TransformGet,zbsMX,zbsMY,zbsMZ,zbsEX,zbsEY,zbsEZ,zbsRX,zbsRY,zbsRZ]<HR></BLOCKQUOTE>

The simple command which reads the most-recently-draw object and gets all the info. BTW you could read this yourself by entering Move mode, reading the Info sliders in the Transform palette, then entering Scale Mode, then entering Rotate mode.

Following the command are nine variables; these can have any name you like. The only danger with choosing a varable name is possibly using a name already in use. That’s why I’ve chosen unusual names unlikely to be duplicated.

<BLOCKQUOTE>quote:</font><HR>[Note,"\Cffa000Position:
\Cc0c0c0",-1]
<HR></BLOCKQUOTE>

The single note which appears is really several small notes linked together. The information between the quote marks is the text that appears. \Cffa000 is a shorthand way to specify text color. “ffa000” is a particular yellow corresponding to 255 red, 160 green, 0 blue. “c0c0c0” is the standard gray corresponding to 160 red, 160 green, 160 blue. (BTW this method of specifying colors is the same as in HTML coding.)

The
is ZScript Note-ese for “return character”.

Between the two commas which appear next you could type any interface item, and the note would “point” to it.

The -1 means link this note to the next note. A value of 0 would mean wait until the mouse is clicked (or spacebar is pressed), and any number higher than 0 would mean pause for that number of seconds.

<BLOCKQUOTE>quote:</font><HR> [Note,zbsMX,-1][Note,",",-1]
[Note,zbsMY,-1][Note,",",-1]
[Note,zbsMZ,-1][Note,"

“,-1]
[Note,”\Cffa000Size:
\Cc0c0c0",-1]
[Note,zbsEX,-1][Note,",",-1]
[Note,zbsEY,-1][Note,",",-1]
[Note,zbsEZ,-1][Note,"

“,-1]
[Note,”\Cffa000Orientation:
\Cc0c0c0",-1]
[Note,zbsRX,-1][Note,",",-1]
[Note,zbsRY,-1][Note,",",-1]
[Note,zbsRZ,0]
<HR></BLOCKQUOTE>

The rest of the notes. You can’t mix plain text with variables, so we put each in a separate note. The final note ends in 0, which means wait for a mouse click or spacebar press.

<BLOCKQUOTE>quote:</font><HR>, // else (Move button is not enabled)<HR></BLOCKQUOTE>

Remember the “if” statement earlier? This comma finishes the “if true” portion and starts the “or else” portion.

<BLOCKQUOTE>quote:</font><HR>[Note,“Cannot determine transformation values for most-recently-drawn object”]<HR></BLOCKQUOTE>

In truth, ZScript could determine transformation values, but they wouldn’t be meaningful.

<BLOCKQUOTE>quote:</font><HR>] // closing bracket for “if”
] // final closing bracket for routine
<HR></BLOCKQUOTE>

The end.

Our routine is done. Now let’s make a button to call it from.

[IButton,“Get Info”,“Get Transformation Values”,
[RoutineCall,GetObjectInfo]
] // closing bracket (we’ll get back to this later)

Place this at the beginning of your ZScript document, with the routine at the end.

Feel free to save this text file, load it within ZBrush and test it. We’ll add the keyboard shortcut later.

Now for the second button, the one which refers to another file.

For the sake of tutorial, let’s take the “Save” button I posted in my earlier post, and save it as a separate file. Here’s that code again:

[iButton,Save,“Save As”,
[if,[isEnabled,document:save],
[iPress,document:saveas]
, // else
[Note,“Document has not changed since last save”,1.5]
] // end if
,CTRL+‘S’ // hotkey
] // end iButton

Save this file as anything-you-like.txt, let’s say “SaveTest.txt”.

In our first ZScript, all we have to do is type:

<zscriptinsert,“SaveTest.txt”>

Make sure SaveTest.txt is either in your ZScripts folder, or else in the same folder as your first ZScript (Mac users: the two text files must be in the same folder).

BTW, this is the ONLY command which uses the pointy HTML-style brackets instead of the square ones.

When ZBrush loads this ZScript, it immediately opens the file “SaveTest.txt” and replaces this command with that file’s contents.

Unlike the [RoutineCall command, this text will appear in the text of the ZScript as many times as it’s called. A tiny file with lots of <zscriptinsert’s will take up lots of space and require lots of scrolling when you view it using the ‘TXT’ button within ZBrush.

So you’ve got two buttons in your ZScript. Feel free to test them now.

All that’s left is to add a keyboard shortcut to the first button.

As I mentioned in my first post, you could assign a key using single quotes (‘H’), or key combination using a plus sign (ALT+‘H’). BTW take care your word processor doesn’t convert to “curly quotes”.

Let’s take a look at another method:

I want to use the keyboard shortcut Alt plus the ‘9’ on my 10-key pad. ZBrush provides a way to find the numeric “code” for that key – it’s in the Preferences:Utilities sub-palette. Open it, watch the second slider from the top, and press your key combination. This slider tells you the numeric code.

On my keyboard, ZBrush shows me the code is 1081 (your results may vary). So I replace the closing bracket for my [IButton command above with

,1081]

Save the ZScript, you’re done.

For the curious, here’s an explanation of the three commas in the above line:

Between the first two commas, you could place a number (or variable containing a number). If the number is zero, this button is enabled – typing nothing, as we’ve done, is the same as typing zero because it’s the default value. If it’s any number other than zero, this button is disabled, and remains so until another button enables it using [IEnable.

Between the second and third comma, you could place a number of pixels; this button will be that wide. This helps you lay out a neat-looking ZScript, with all your buttons the same width. Also, you can use the command [TextCalcWidth to get the width of some text, and make your buttons exactly that width.

All for now,
dave

Thanks Davey for your Zscript insights, especially on the Note function and the extra options of the Button function. I am still learning something everyday with my piddling around. It is an extremely powerful little language. Hopefully as time progresses we will see some people writing some awesome doodahs.

If I may, inject a couple of things that I have found and wished for so far.

When entering a number with digits after the decimal point in a Slider control, you can no longer use the period key in the Keypad. Not a biggie, but it is a hassle to search around to find the period on the normal keys and then get back to the numbers.

Any thought to being able to write/read files from the harddrive? Would be nice to be able to populate variables and arrays with data read from the hard drive and to save them.

A function that could read normal Zbrush Markers would be cool, such as tool, material, color etc…

A X to the Power math function would be cool. i.e. 5 to the power of 8 etc…

A Log Math Function

One thing I have not been able to figure out is how to progressively rotate an object about its xyz axis. At some point the object “Flips?” and has different angles for xyz properties. Example: increase XRot incremently by 1. At some point 180 degrees? Y becomes a number and X becomes another neg number. (Sorry I don’t have the data with me) At that point, adding another postive 1 flips it back and you start going back and forth Pos/Neg.

Digits, I bow to your programming expertise.

Thanks for your insights, and requests. The one thing I can help you with immediately is the X to the Power function (sounds like an old Hanna-Barbera cartoon). Use a double-caret:

x^^n

2^^4 gives you 16. Is this what you were looking for?

As for the X, Y and Z values of rotation, I’ll dig through my notes and see if I can shed some light on them.

dave

Thanks Davey, I gots the POWER now heheh

One thing I want to be able to do, once I understand Rotation Coordinates is to be able to point any axis of a object toward a point in space given the angle to that point. I have all the rest of it figured out except the Rotation thingy. I appreciate any help ya got.

Good news, Digits. I’ve got that very ZScript archived; I’ll clean it up a bit and post it in a new thread later today.

dave