Home Technical Talk

Zbrush - hide subtool under mouse cursor

polycounter lvl 12
Offline / Send Message
MrOneTwo polycounter lvl 12
Since I spend most of my time in Zbrush I started eliminating parts of the workflow that annoys me. I really don't like hiding specific subtools since it requires looking into subtools palette. I tried to find a Zscript that could hid subtool under mouse cursor. I found this thread:

http://www.zbrushcentral.com/showthread.php?162766-Hide-subtool-under-mouse

Below you can find a code those guys wrote. It's slightly modified by me. I commented out the lines that toggle 'Auto Select Subtool' option. You don't need it if you have it turned on by default. The problem is that this script works once! After you trigger it through hotkey you have to change the hotkey to be able to trigger it again... I don't have experience in Zbrush scripting. Even though I tried to decode this code I can't figure out why the hot key stops working. Also sometimes it hides more than the subtool the mouse pointer hovers above. I also need a script that unhides all of the hidden subtools.

Any help would be appreciated.

[IButton,Toggle,"Toggle subtool visibility",
[IConfig,4.6]
//store the scrollbar position
[VarSet,tmpScrollPos,[IGetSecondary,Tool:Sub Tool:SubTool ScrollBar]]
//find the selected subtool
[VarSet,totalSubTools,[StrExtract,[IGetTitle,Preferences:Misc:SubTools Count],10,256]]
[If,totalSubTools>8,
[VarSet,i,1]
[VarSet,subToolPath,"Tool:Sub Tool:SubTool 0"]
[Loop,totalSubTools,
[VarSet,scrollPos,(totalSubTools-i)]
[ISet,Tool:Sub Tool:SubTool ScrollBar,0,scrollPos]
[If,[IGetFlags,#subToolPath]>=9,
[VarSet,activeSubT,[IGetTitle, Tool:Current Tool]]
[LoopExit]
]
[VarInc,i]
]
,
[VarSet,scrollPos,tmpScrollPos]
[Loop,totalSubTools,
[VarSet,subToolPath,[StrMerge,"Tool:Sub Tool:SubTool ",[Val,n]]]
[If,[IGetFlags,#subToolPath]>=9,
[VarSet,activeSubT,[IGetTitle, Tool:Current Tool]]
[LoopExit]
]
,n]
]

//do select. . . ( marcus civis )
//[IPress,Preferences:Edit:Auto Select SubTool]
[IKeyPress,1064,[CanvasClick,[MouseHPos],[MouseVPos]]]
//[IUnPress,Preferences:Edit:Auto Select SubTool]
//
//and then set var1 to that selection
[VarSet,hideSubT,[IGetTitle, Tool:Current Tool]]
//hide var1

[If,([StrLength,hideSubT]==[StrLength,activeSubT])&&([StrFind,hideSubT,activeSubT]>-1),
//active subtool - do nothing
,//if it's not the active subtool
[IModSet,[StrMerge,"Tool:SubTool:",hideSubT],1]
]

//switch back to selected subtool
//set the scrollbar so subtool shows
[ISet,Tool:Sub Tool:SubTool ScrollBar,0,scrollPos]
//select subtool
[IPress,#subToolPath]
//reset scrollbar
[ISet,Tool:Sub Tool:SubTool ScrollBar,0,tmpScrollPos]
]

Replies

  • nyx702
    How are you running the script? Scripts loaded thru Zscript>Load have the issue with the hotkeys you described. I use this as a macro and it works fine with hotkeys. Place the file in Zstartup>Macros and it will be in your Macros menu when you re-launch Zbrush. 

    Hiding more than one subtool I think is an issue with the accuracy of the CanvasClick command. I'm not sure if there is anything that can be done about it. This Macro is pretty old now I will think if there is a better way to do it but I doubt it. 
  • MrOneTwo
    Offline / Send Message
    MrOneTwo polycounter lvl 12
    I actually got it working. It's definately not perfect. There is a bug which is based on Alt + LMB subtool changing. I hacked a solution by changing a subtool to a one above on the list and then back to the one that is selected = it does nothing. It only fixes the Alt + LMB issue. Also because of this hack when you use it while first subtool is the active one it doesn't select it after hiding the other one. It selects the one below.

    The one time triggering is described in Zbrush scripting docs. It's intentional (if you are loading script through z scripting palette). I compiled it into a button and threw it into ZStartup folder and now it works ok. Here is the code (unhiding doesn't work for now):

    [ISubPalette,"ZPlugin:Hide"]

    [IButton,"ZPlugin:Hide:Toggle Vis","Toggle subtool visibility",
    [IConfig,4.6]
    [IPress,Tool:SubTool:SelectUp]
    [IPress,Tool:SubTool:SelectDown]
    //store the scrollbar position
    [VarSet,tmpScrollPos,[IGetSecondary,Tool:Sub Tool:SubTool ScrollBar]]
    //find the selected subtool
    [VarSet,totalSubTools,[StrExtract,[IGetTitle,Preferences:Misc:SubTools Count],10,256]]
    [If,totalSubTools>8,
    [VarSet,i,1]
    [VarSet,subToolPath,"Tool:Sub Tool:SubTool 0"]
    [Loop,totalSubTools,
    [VarSet,scrollPos,(totalSubTools-i)]
    [ISet,Tool:Sub Tool:SubTool ScrollBar,0,scrollPos]
    [If,[IGetFlags,#subToolPath]>=9,
    [VarSet,activeSubT,[IGetTitle, Tool:Current Tool]]
    [LoopExit]
    ]
    [VarInc,i]
    ]
    ,
    [VarSet,scrollPos,tmpScrollPos]
    [Loop,totalSubTools,
    [VarSet,subToolPath,[StrMerge,"Tool:Sub Tool:SubTool ",[Val,n]]]
    [If,[IGetFlags,#subToolPath]>=9,
    [VarSet,activeSubT,[IGetTitle, Tool:Current Tool]]
    [LoopExit]
    ]
    ,n]
    ]
    //do select. . . ( marcus civis )
    //[IPress,Preferences:Edit:Auto Select SubTool]
    [IKeyPress,1064,[CanvasClick,[MouseHPos],[MouseVPos]]]
    //[IUnPress,Preferences:Edit:Auto Select SubTool]
    //
    //and then set var1 to that selection
    [VarSet,hideSubT,[IGetTitle, Tool:Current Tool]]
    //hide var1

    [If,([StrLength,hideSubT]==[StrLength,activeSubT])&&([StrFind,hideSubT,activeSubT]>-1),
    //active subtool - do nothing
    ,//if it's not the active subtool
    [IModSet,[StrMerge,"Tool:SubTool:",hideSubT],1]
    ]

    //switch back to selected subtool
    //set the scrollbar so subtool shows
    [ISet,Tool:Sub Tool:SubTool ScrollBar,0,scrollPos]
    //select subtool
    [IPress,#subToolPath]
    //reset scrollbar
    [ISet,Tool:Sub Tool:SubTool ScrollBar,0,tmpScrollPos]
    ]


    // unhide all
    [IButton,"ZPlugin:Hide:Unhide All","Unhide all subtools.",
    [IConfig,4.6]
        [VarSet,tmpScrollPos,[IGetSecondary,Tool:Sub Tool:SubTool ScrollBar]]
        [VarDef, SubToolNumber,0] //variable to store number of subtools
        [VarDef, CurrentSubtoolName,""]


        [VarSet, SubToolNumber,[SubToolGetCount]] // Get number of subtool and assign it to SubToolNumber var

        [Loop, SubToolNumber, //loop through each subtool

            [subToolSelect, n]

            [VarSet, CurrentSubtoolName,[IGetTitle, Tool:ItemInfo]] // assign name of currentsubT to CurrentSubtoolName

            [IModSet,[StrMerge,"Tool:SubTool:",CurrentSubtoolName],17]
            [ISet,Tool:Sub Tool:SubTool ScrollBar,0,tmpScrollPos]


        ,n]

    ]

    Zscript syntax blows... at least for some one who codes in C/C++ and Python...


  • wyldwulf
    My coworker and I have been wanting this for some time. Pardon me for being a little thick...even looking over some of the zbrush docs I am unsure of what to do with the above code to actually utilize it. However reading your description, is it possible something like a dummy subtool can be added to the tool list, selected when the hovered-over-tool is hidden, and the listed scrolled back to roughly the last hidden tool's location? You don't want to unhide an adjacent tool just hidden. Obviously you have to select something as part and parcel to zbrush's lack of subtool infrastructure, but wondering if something can be tacked on, and named to select for the purpose of the hider? When it comes to this operation for the purpose of file export we have often literally been hand deleting things we might otherwise hide...it is crazy to think it is easier to remove it than have it unhide.
  • MrOneTwo
    Offline / Send Message
    MrOneTwo polycounter lvl 12
    Yeah it took me awhile to figure out how to script in Zbrush... I did it only for this idea and forgot most of it by now... Would have to open Zbrush to remind myself how did it all work. You need to google basics of zscripting. If you want I can send you the *.zsc file which you need to put in the ZStartup/Zplugs. You will find the button under ZPlugins/Hide palette then. (pm me if you want the file)

    I abandoned this idea because I really can't learn Zscripting properly right now. To may things on my plate. Also my script sometimes doesn't work at all. Sometimes it does but not properly. It's just too unreliable and I lack the skills to make it better. I posted the code so if anyone who wants to improve it could.

    Right now I don't think I can add anything constructive to this script. Also what I wrote is a hack with parts of someone else's code.

  • wyldwulf
    to clarify the Dummy could be user created and named as such, rather than created within the script itself to be appended each time it is run. If this worked, I'd be more than willing to append a sphere to the list called dummy to get this thing to work.
  • airbrush
    Offline / Send Message
    airbrush polycounter lvl 13
    used to use this all the time...r8 kicks up an error now :(...anyone else have a similar script or can fix this one to work in r8?

    SCRIPT: HideSubtoolUnderMouse.txt

    ERROR: #subToolPath
    IN: [IPress,#subToolPath]


    MrOneTwo said:
    I actually got it working. It's definately not perfect. There is a bug which is based on Alt + LMB subtool changing. I hacked a solution by changing a subtool to a one above on the list and then back to the one that is selected = it does nothing. It only fixes the Alt + LMB issue. Also because of this hack when you use it while first subtool is the active one it doesn't select it after hiding the other one. It selects the one below.

    The one time triggering is described in Zbrush scripting docs. It's intentional (if you are loading script through z scripting palette). I compiled it into a button and threw it into ZStartup folder and now it works ok. Here is the code (unhiding doesn't work for now):

    [ISubPalette,"ZPlugin:Hide"]

    [IButton,"ZPlugin:Hide:Toggle Vis","Toggle subtool visibility",
    [IConfig,4.6]
    [IPress,Tool:SubTool:SelectUp]
    [IPress,Tool:SubTool:SelectDown]
    //store the scrollbar position
    [VarSet,tmpScrollPos,[IGetSecondary,Tool:Sub Tool:SubTool ScrollBar]]
    //find the selected subtool
    [VarSet,totalSubTools,[StrExtract,[IGetTitle,Preferences:Misc:SubTools Count],10,256]]
    [If,totalSubTools>8,
    [VarSet,i,1]
    [VarSet,subToolPath,"Tool:Sub Tool:SubTool 0"]
    [Loop,totalSubTools,
    [VarSet,scrollPos,(totalSubTools-i)]
    [ISet,Tool:Sub Tool:SubTool ScrollBar,0,scrollPos]
    [If,[IGetFlags,#subToolPath]>=9,
    [VarSet,activeSubT,[IGetTitle, Tool:Current Tool]]
    [LoopExit]
    ]
    [VarInc,i]
    ]
    ,
    [VarSet,scrollPos,tmpScrollPos]
    [Loop,totalSubTools,
    [VarSet,subToolPath,[StrMerge,"Tool:Sub Tool:SubTool ",[Val,n]]]
    [If,[IGetFlags,#subToolPath]>=9,
    [VarSet,activeSubT,[IGetTitle, Tool:Current Tool]]
    [LoopExit]
    ]
    ,n]
    ]
    //do select. . . ( marcus civis )
    //[IPress,Preferences:Edit:Auto Select SubTool]
    [IKeyPress,1064,[CanvasClick,[MouseHPos],[MouseVPos]]]
    //[IUnPress,Preferences:Edit:Auto Select SubTool]
    //
    //and then set var1 to that selection
    [VarSet,hideSubT,[IGetTitle, Tool:Current Tool]]
    //hide var1

    [If,([StrLength,hideSubT]==[StrLength,activeSubT])&&([StrFind,hideSubT,activeSubT]>-1),
    //active subtool - do nothing
    ,//if it's not the active subtool
    [IModSet,[StrMerge,"Tool:SubTool:",hideSubT],1]
    ]

    //switch back to selected subtool
    //set the scrollbar so subtool shows
    [ISet,Tool:Sub Tool:SubTool ScrollBar,0,scrollPos]
    //select subtool
    [IPress,#subToolPath]
    //reset scrollbar
    [ISet,Tool:Sub Tool:SubTool ScrollBar,0,tmpScrollPos]
    ]


    // unhide all
    [IButton,"ZPlugin:Hide:Unhide All","Unhide all subtools.",
    [IConfig,4.6]
        [VarSet,tmpScrollPos,[IGetSecondary,Tool:Sub Tool:SubTool ScrollBar]]
        [VarDef, SubToolNumber,0] //variable to store number of subtools
        [VarDef, CurrentSubtoolName,""]


        [VarSet, SubToolNumber,[SubToolGetCount]] // Get number of subtool and assign it to SubToolNumber var

        [Loop, SubToolNumber, //loop through each subtool

            [subToolSelect, n]

            [VarSet, CurrentSubtoolName,[IGetTitle, Tool:ItemInfo]] // assign name of currentsubT to CurrentSubtoolName

            [IModSet,[StrMerge,"Tool:SubTool:",CurrentSubtoolName],17]
            [ISet,Tool:Sub Tool:SubTool ScrollBar,0,tmpScrollPos]


        ,n]

    ]

    Zscript syntax blows... at least for some one who codes in C/C++ and Python...



  • nyx702
    I updated/optimized this for 4r8. If you are using a non-English keyboard you might have to change the which ID is used for ALT in:
    	[IKeyPress,1024,[CanvasClick,[MouseHPos],[MouseVPos]]]

    You can find the keypress ID of the pressed key in Preferences>Utilities> Value of 2nd Slider


  • airbrush
  • MrOneTwo
    Offline / Send Message
    MrOneTwo polycounter lvl 12
    Hey guys I've updated this scsript for Zbrush 2018. It's way simpler now... and works pretty well. It needs to be put into `Zbrush 2018\ZStartup\Macros\Misc\macro_name.txt`. Then you can bind a hotkey to it and it will hide a subtool under the cursor every time you press the hotkey (I've pasted the code and attached it as file):

    // ZBRUSH 2018 - 25.08.2018
    // Written by MrOneTwo - Michal Ciesielski

    [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

    [IButton, ???,"Hide subtool under the cursor",
        [RoutineCall,CheckVersion]
        [RoutineCall,CheckSubTool]
        [VarSet,activST,[SubToolGetActiveIndex]]

        [IKeyPress, ALT, [CanvasClick,[MouseHPos],[MouseVPos]]]
        [VarSet,hidingST,[SubToolGetActiveIndex]]
        [ISet,Tool:Sub Tool:SubTool ScrollBar,0,([SubToolGetCount]-(hidingST+1))]
        [If,([IModGet,"Tool:Subtool 0"]&32 == 32),
            [Note,"Is visible\n",,-1]
            [IModSet, "Tool:Subtool 0", 18]
        ]

        //positions scrollbar so subtool at top of list
        [ISet,Tool:Sub Tool:SubTool ScrollBar,0,([SubToolGetCount]-(activST+1))]
        [SubToolSelect, activST]
    ]//end button

  • MrOneTwo
    Offline / Send Message
    MrOneTwo polycounter lvl 12
    I know it's an old thread but I've made a video and that might be useful to actually get what this thread is about and how to use this script:

    https://youtu.be/pVVLO7PG7aQ


Sign In or Register to comment.