ZBrushCentral

Writing batch obj script, need to set file path on run.

Hello!
I’m trying to write/modify a Zscript to batch export all subtools with subtool names intact. I currently have a working script that goes through every subtool, exports, and has me choose a location/name for the obj. The issue is that I would like to automate this so that I only have to choose the folder location once on run, and then the script would export every obj to the location of the selected folder with the subtool name set up.

Here is what I have so far.

[VarDef,activST,0]
[VarDef,filePath,""]
[RoutineDef,CheckVersion,//check that version is 4R8
[If,([ZBrushInfo,0]< 4.8),
[Note,“This script is not for this version of ZBrush”]
[Exit]
]
]//end of routine

[RoutineDef,CheckSubTool,//check that we have a subtool
[If,[IExists,Tool:SubTool:Select Down],
//do nothing - all OK
,//else not a subtool
[Exit]
]
]//end of routine

[RoutineDef,DoItGRP,//start of routine
[IKeypress, 13]
[IUnPress,Tool:Export:Grp]
]//end of routine

[RoutineDef,DoItExp,//start of routine
[IPress,Tool:Export]
]

[IButton,“Export HIGHS”,“exports objs”,
[RoutineCall,CheckVersion]
[RoutineCall,CheckSubTool]
[VarSet,activST,[SubToolGetActiveIndex]]//store active subtool
[Loop,[SubToolGetCount],//loop through all subtools
[SubToolSelect,[Val,n]]
//check visibility
[If,([IModGet,“Tool:Subtool 0”]&32 == 32),
//code for visible subtool
[RoutineCall, DoItGRP]
[RoutineCall,DoItExp]
]
,n]//end loop
[SubToolSelect,activST]//reselect active subtool
]//end button

You need to ask for a file location using [FileNameAsk] then use just the path from that and combine it with the subtool name to make each full file name. Using [FileNameSetNext] makes sure the file name is used when the Tool:Export button is pressed, instead of a file dialog appearing:

[IButton,“Export HIGHS”,“exports objs”,
[RoutineCall,CheckVersion]
[RoutineCall,CheckSubTool]

//ask for a file name and location (name is ignored)
[VarSet,filePath,[FileNameAsk,“OBJ(.obj)|.obj||”,Default.obj ,“Please Save File…”]]
[If,[StrLength,filePath],
//extract the path only
[VarSet,filePath,[FileNameExtract,filePath,1]]
,//else dialog cancelled, exit script
[Exit]
]

[VarSet,activST,[SubToolGetActiveIndex]]//store active subtool
[Loop,[SubToolGetCount],//loop through all subtools
[SubToolSelect,[Val,n]]
//check visibility
[If,([IModGet,“Tool:Subtool 0”]&32 == 32),
//code for visible subtool

//get subtool name
[VarSet,subtoolName,[IGetTitle,Tool:Item Info]]//this has a period at the end so don’t need to add below
//make full path & file name
[VarSet,fileName,[StrMerge,filePath,subtoolName,“obj”]]
//set to be next used file name
[FileNameSetNext,fileName]

[RoutineCall, DoItGRP]
[RoutineCall,DoItExp]
]
,n]//end loop
[SubToolSelect,activST]//reselect active subtool
]//end button

The subtool name is got from the Tool:Item Info slider - that’s the slider at the top of the tool palette. It displays the name of the selected tool, or subtool, so changes as you loop through the subtools. You get the name using [IGetTitle] and because the name using this method has a period at the end you don’t need to add it for the extension when merging the names using [StrMerge].

HTH,

Thank you! That helped a lot. Also thanks for the break down! I am new to coding in zscript so the assistance is much appreciated!

One more question, is there a way to store this script so that it runs on launch so that i can put it on the UI and not have to load it everytime i start zbrush?

Yes, the best way is to make it into a plugin. To do that you need to create a new sub-palette, and make sure the button is named correctly with the sub-palette path. So, for example, you could create a new sub-palette called “My Plugin” in the Zplugin palette. This is how you do it (the rest of you zscript remains the same):

[ISubPalette,“Zplugin:My Plugin”]//creates new sub-palette

[IButton,“Zplugin:My Plugin:Export HIGHS”,“exports objs”,
[RoutineCall,CheckVersion]
[RoutineCall,CheckSubTool]

//ask for a file name and location (name is ignored)
[VarSet,filePath,[FileNameAsk,“OBJ(.obj)|.obj||”,Default.obj ,“Please Save File…”]]
[If,[StrLength,filePath],
//extract the path only
[VarSet,filePath,[FileNameExtract,filePath,1]]
,//else dialog cancelled, exit script
[Exit]
]

[VarSet,activST,[SubToolGetActiveIndex]]//store active subtool
[Loop,[SubToolGetCount],//loop through all subtools
[SubToolSelect,[Val,n]]
//check visibility
[If,([IModGet,“Tool:Subtool 0”]&32 == 32),
//code for visible subtool

//get subtool name
[VarSet,subtoolName,[IGetTitle,Tool:Item Info]]//this has a period at the end so don’t need to add below
//make full path & file name
[VarSet,fileName,[StrMerge,filePath,subtoolName,“obj”]]
//set to be next used file name
[FileNameSetNext,fileName]

[RoutineCall, DoItGRP]
[RoutineCall,DoItExp]
]
,n]//end loop
[SubToolSelect,activST]//reselect active subtool
,1]//end button

I’ve also added a button width of 1 at the end of the button code - that’s a full palette width. If you want you can change that to 0.5 which would be half a palette width, etc.

When you first load a zscript into ZBrush a ZSC file is created in the same location as the TXT file. For plugins, if you put this ZSC file in the ZStartup\Zplugs64 folder then it will be automatically loaded by ZBrush on start up.