Zscript execution..

When does the ZScript execute.(one that loads at startup)

I can see it connect to all fileExecute dll's on load,

But it seems to not actualy run the rest of the script if there is a button in it. Except that my variable all get set correctly. I am most interested in global routine calls.

I am kind of confused. I have made scripts that run everything when ZBrush loads, setting imageSize and buttons visible and whatnot. So Is my script executing all global calls (anything not in a button) twice if there is a button there. It appears it runs everything when I click the button again.

How would you make it not re-run the script (mainly global routine calls). I am probably missing something simple here. I will try to post an example of what I am talking about if no-one understands me.

edited: added example file =======================================================>> Place both the TXT and ZSC files in zbrushRoot.../ZStartup/ZPlugs/ If you don't have a ZPlugs Folder Create one. WARNING: Any .ZSC file in this folder will load at startup. Once files are in the folder, Restart ZBrush and in the ZScript tab, you will find the button [TestInitButtonFunc] Press it and you will see the NoteBar at the top of the ZBrush window.

Now, this was a global routine and called globally,so why is it called when I press the button?

 [RoutineDef,MyFunc,			//** Define Routine/Function
           	[VarSet,t1,"Only Should Be Called On Load"]		
 	[NoteBar,t1,.5]			//** Set Notebar on load
           [RoutineCall,MyFunc,v1]		//** Call Routine/Function
 [IButton,		 		//** Just Clicking here will make the Notebar Show Up 
           	"Test Global Commands",
 		 		 	//** I would think this shouldn't run global Routines/Funcs
           	[If,v1>1,[NoteBar,"",0]]//** clear notebar
Attached are the two files in the zip;

Hi Chris

Not exactly sure about your particuliar problem and forgive me if you already know this but this is how I control initialization of globals and memory when a script is loaded, reloaded, or called again during a Zbrush session.

It makes sense that code is not executed on load when it is enclosed in a IButton since that is handled as an event when the user presses a button, but it is curious if you are seeing that other code is not executing when one is present.

//rest of zscript here
// -
[if,Initial == 0,
//Initial = zero then not created yet

[If,Initial == 0, //create memory space will set initial to non zero [VarSet,Initial,[MemCreate,GlobalMemName,8]] //write something to it [MemWrite,GlobalMemName,ToolID,0,0] //Create Memory Blocks [MVarDef,"MarkTool",11] [Note,"Welcome to this script first time it is loaded",,2] ,//else Initial is not zero things have already been initialize and loaded [VarSet,Initial,1] //read back data [MemRead, GlobalMemName, ToolID, 0 , 0 ] ]


Thanks Digits,

Let me clear up what I am asking.

Why are global commands executed when I press a button. I would think only commands in the buttons command args would be executed?

In my example, you can see that the Global command:


should be called when it loads. And not when the button is pressed.
If you ommit all commands from inside the button, [RoutineCall,MyFunc,v1] is still called when the button is pressed. I find this a bit odd.

this only happens if you load the plugin at startup. If you load it while ZBrush is running it will not preform like this. Then it runs as expected.

Marcus_Civis has suggested a devilishly clever way to trap the problem you are having. I can’t remember the link where he suggested it right now, but I think what he does is use the ZBrushInfo command to test the Runtime (infotype 2): time elapsed since startup.

If the Runtime is below a certain value, the script knows that ZBrush just started up. If Runtime is higher, then it knows all of the commands inside the If test have already been executed and skips them.

When the sun comes up again on the east side of the Atlantic, he’ll probably be able to clarify his method.


I think I am making this seem more complicated then it is.

I don’t need to test anything here. I was wondering why zbrush does something. Everything in the first post is just so that someone can reproduce the problem.

My Concern:
the reason is that I have the script run a lengthy (.25 seconds) one time scan when you start ZBrush. I was hoping to have this run when ZBrush starts up instead of the first time the user presses the button. It isn’t really a big deal, but you do notice it the first press compared to the others.

That is a great Idea on marcus’s part, but it won’t help me here.

This effect Only happens on zscripts that load at startup, it doesn’t happen on ones you load through the interface. Go ahead and try it.

Sorry to be so confusing…
I shouldn’t try to explain so much in the first post… its kind of scary anyways.:evil:

Chris Reid

It’s my understanding (and granted, that’s limited :slight_smile: ) that plugins load one after another on launch, then finally the defaultzscript loads. When one plugin (or zscript) loads it always replaces the previous one, so that variables are lost. So pressing a plugin button reloads it; it’s not constantly loaded.

I think you need to distinguish between Zscripts and Zplugins.

If your script was a Zscript, i.e displayed in the Tutorial Window, you would not have any problems with your code. The script is loaded and parsed once as ZBrush knows this is now the active Zscript.

A Zplugin will always reload itself when one of its interface items is pressed. Zbrush apperantly does not check to see if the Zplugin was active. I guess you could say the Zplugin generated interface items do not contain the script code but only a reference # to the full script.

I am not sure why manually loading the zplugin works. I guess Zscript > Load Zscript is only meant for zscripts. If you load a Zplugin that way Zbrush will treat it as a Zscript.

You obviously need to use a Zplugin so try this method instead to execute global code once only. By using a mem block you can easily check if this is the first time a zplugin is activated during the current session. The [MemCreate ,…] command will return an error message if the memblock already exists. You can test against that and thus only execute code once. This of course works for both zplugins and zscripts.

I just remembered. Your code in zscript form would not really work. Resizing the tutorial window or opening/closing the left/right containers will cause a reload of the zscript. This is needed to format any UI items/text to the new size of the tutorial window.

Edit: As marcus said, Zplugins are loaded one after the other according to their filename. The defaultzscript is loaded last. That means your Notebar message will not appear upon startup as it is cleared upon each Zplugin/Zscript load (as far as I know).


Although, as TVeyes states, you can use memory blocks to see whether your plugin has loaded (and you’d need to use memory blocks anyway to retain the data from your initial routine), it IS possible to get your code to work as you wish without. To check that this does actually work, save as defaultzscript.txt to your ZScripts folder. That way you’ll see the notebar message.


	"Test Global Commands",
	[If,v1>1,[NoteBar,"",0]]//** clear notebar

         [VarSet,t1,"Only Should Be Called On Load"]		

Obviously using this method you might need to adjust the session time amount; there has to be enough time for the plugin script to load but not so much that a user would re-initialize by pressing the button.

(Sven, thanks for the enthusiastic post above - as you’ll see I had to adapt the method to get it to work. :slight_smile: EDIT: actually, it does work as before, not sure why I thought it didn’t! )

Funny how I don’t know the difference beween zscripts and zplugs.:o
I always thought the zplug was the zsc. and the zscript is the txt ? I guess there is more to it than that… I still don’t totally understand the difference.

Thanks for the help guys,
the code I posted is a mockup for the problem, it is not actualy something I am using. I know the notebar will be overwritten, I was just using it to point out that the global command is executed with the button. Well, I will test what you guys have given me when I get back to my computer in a few hours… gotta pick up the wife at one airport and drop off the parents at another…what a trip.

Thanks all,

Chris Reid

It took me a while to get my head around the ZScript/ZPlugin difference. It is a subtle difference but important. The difference between a compiled ZScript and a compiled ZPlugin is non existant in most cases.

Any .txt zscript loaded into Zbrush will result in a compiled .zsc. This .zsc can be either a regular ZScript (as known from 1.55b) or a ZPlugin (as introduced in 2.0). In either case the .zsc code generated is the same and the execution of the compiled code is 100% the same.

If you take a step back to ZBrush 1.55b, .txt files could be compiled thus not allowing a second party to view the code. That is the extent of the .zsc compilation apart from the optional thumbnail imbedding.

In Zbrush 2.0 the same applies but if the .txt code places all its interface items in the ZBrush UI the script code becomes eligible for Zplugin status. The compiled .txt can then be added to the /ZStartup/ZPlugs folder in order to be loaded automatically upon startup.

A .zsc can be either a regular ZScript or ZPlugin, not both , but they are both compiled versions of a .txt file. The compiled code is the same but the way ZBrush “stores” the code differs.

:large_orange_diamond: ZScript :small_orange_diamond:
Zscripts are per definition loaded manually, through a helper ZScript or through a seperate ZPlugin button.

ZScripts are loaded once and remain active until the user or code changes to another ZScript.

Zscripts are reloaded when the Tutorial Window size changes.

ZScripts are NOT reloaded when a ZScript interface item is activated.

:large_orange_diamond: ZPlugin :small_orange_diamond:
ZPlugins are loaded automatically if they are placed in the /ZStartup/ZPlugs folder.

Zplugins are reloaded each time one of its interface items is pressed.

A manually loaded ZPlugin will act like a regular ZScript (I think).

I know this will not explain all your questions but it should show you why some things work in your code and some do not. I am not 100% of everything I have written but up until now they have proved true.

Makes sense to me.;)<:+1:
Thank you very much.
I think this should be documented in the ZCommand Ref.
Very important to know.:bulb:

:question:One more question about plugins/scripts :
Is it important to use IConfig in your plugin/script?
It states 1.5 for v1.5 & Newer. I assume this could change later and they could put a 2.5 for 2.5 & Newer. I am new to ZBrush so I havn’t even seen the older versions.

whoops,got carried away,:smiley:

Chris Reid

Pixolator has professed the value of using [IConfig,…] some time ago. I am always trying to remember to include it in my Zscripts. Thanks for the reminder :wink:

Basically it will ensure a future version(s) of Zbrush will know what your Zscript is talking about, even if your zscript utilises UI items that have since moved to another palette. The next version of ZBrush will know where all the interface items in Zbrush 2 were stored for example.

If you use an [IConfig,…] your script should have no problem accessing ZBrush UI items in ZBbrush 3 or ZBrush 3.5, providing they still exist in that version.

Thanks For Everything, Everyone!


I found a little problem with [IConfig,1.232 or 1.5], My Bitmap Icons Are Read By ZBrush as inverted, they are read from topDown instead of bottom up. Oh well, I will just skip it this time.

That is right, Zbrush 2 changed a bitmaps (.bmp) read order. In 1.55b and below the read order of bitmap pixels was from the end of the file and inwards.

You should supply [IConfig,…] with the zbrush version your zscript/zplugin was written on.

If you check my 360 turntable zscript the background is reversed. I believe if I was to insert an [Iconfig, 1.5] then the bitmap would show up the right way when run in zbrush 2.

Edit: I am at work right now but I have the source code available at the above link. You can test it yourself with that. If you do, let me know if it works :slight_smile:

I thought there were only the “1.232” & “1.5 and above” option, 2.0 works like a charm.

Thanks again

Chris Reid