Skip to content

Instantly share code, notes, and snippets.

@Eterea
Created August 16, 2014 14:57
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Eterea/1b02a9023799530726c9 to your computer and use it in GitHub Desktop.
Save Eterea/1b02a9023799530726c9 to your computer and use it in GitHub Desktop.
Modo script to toggle between normal Shading Styles and a 'XRay-hacked' one.
#python
#----------------------------------------------------------------------------------------------------------------
# NAME: etr_xraymat_toggle.py
# VERS: beta4
# DATE: March 11, 2014
#
# MADE: Cristobal Vila, etereaestudios.com
#
# USES: To toggle between normal Shading Styles and a 'XRay-hacked' one.
#
# RECOMENDATION AND GUIDE TO USE:
#
# First of all, assign this script to a keymap, ie 'numeric-8'.
#
# When pressing '8' you will enter in a 'new of shading style', shaded, transparent,
# and with 100% opaque wireframes that you can see through surfaces.
# This is in fact a 'dirty hack' based on Advanced OpenGL, creating a semitransparent
# temporal Material with a custom color and properties.
#
# Press '8' again to 'exit' from this XRay state and you will return to standard
# 'Shade' style (I choose to go back to 'Shade' because 90% of times
# when you want or need to use XRay, you will be at Modeling stages).
#
# If you forgot to press '8' to 'exit' from XRay-state and press '4' to return back
# to standard Shade, or any other shading style (something that will occurs for sure),
# you will see that the 'soft-blue-greyed' material remains there. Don't worry: press '8'
# again and you will disable XRay, removing the temporal Material (*)
#
# (*) There is one exception: if you change directly from 'XRay' to standard 'Wireframe',
# forgeting to disable XRay, all seems to be fine (but XRay material is here anyway).
# If you press again '8' on this case, you will return to XRay, and not disable it.
#
# There is a complementary script 'eterea_xraymat_modTrans.py' to change level
# of Transparency on the fly, and a 'eterea_xraymat_toggle_keymaps.CFG' where you can
# modify your preferred keymaps for all.
#----------------------------------------------------------------------------------------------------------------
myActualShading = lx.eval('view3d.shadingStyle ?')
#----------------------------------------------------------------------------------------------------------------
# This script will create a new 'XRAYMAT' custom Material, placing it at top of Shader Tree.
# This means that we would loose all Shader Tree SELECTIONS (bad if we are working on ST).
# We will (1) Store all selections in a List, (2) Deselect all, and (3) Recover that selection at end.
# There is an exception: if we already have a 'XRAYMAT' AND is selected, we need to deselect it to avoid errors.
#----------------------------------------------------------------------------------------------------------------
# Attempts to query if a material called 'XRAYMAT' is selected.
# If it doesn't exist and/or is not selected, a silent error will occurs:
try:
xraySelected = lx.eval('query sceneservice txLayer.isSelected ? {XRAYMAT}')
# We've got here so the material 'XRAYMAT' exists AND is selected. Let's deselect it:
if xraySelected == 1:
lx.eval('select.subItem {XRAYMAT} remove')
except:
pass
# Now lets create a LIST with other selected elements in ShaderTree (if any):
myPrevSelected = []
n = lx.eval( "query sceneservice txLayer.N ?" )
for i in xrange(n): # xrange is faster than range(0,n) and you don't have to specify a lower bound of 0. It will default to 0
if lx.eval1("query sceneservice txLayer.isSelected ? %s" % i):
myID = lx.eval1("query sceneservice txLayer.id ? %s" % i)
myPrevSelected.append (myID) # Store the ID here, as the index may not point to the same thing if you've made changes
lx.eval("select.subItem %s remove" % myID)
#----------------------------------------------------------------------------------------------------------------
# Next step is to check if a Material named 'XRAYMAT' exists of not
#----------------------------------------------------------------------------------------------------------------
# Attempts to get the ID of a material named 'XRAYMAT'. If it doesn't exist, a silent error will occurs:
try:
lx.eval('query sceneservice advancedMaterial.ID ? {XRAYMAT}')
# We've got here so the material 'XRAYMAT' exists.
xrayExistence = 'yes'
# If the silent error occurs, the material 'XRAYMAT' doesn't exist:
except:
xrayExistence = 'nope'
# Lets define a Function to Remove XRAYMAT:
def remove_XRAYMAT():
lx.eval('select.item {XRAYMAT} set :advancedMaterial')
lx.eval("texture.delete")
lx.eval('select.drop item polyRender')
#----------------------------------------------------------------------------------------------------------------
# OPTION A. We HAVE a previously created 'XRAYMAT' material.
# This means that we are in 'XRay Mode' OR we passed from XRay to Standard Styles without disabling XRay:
#----------------------------------------------------------------------------------------------------------------
if xrayExistence == 'yes':
# If we are in Advanced OpenGL this means that:
# 1. We are in XRay mode and we want 'toggle' to exit from it. Or...
# 2. ...we passed directly from XRay to simple AdvOGL, and nothing occurs (because in fact, XRay = AdvOGL)
if myActualShading == 'advgl':
remove_XRAYMAT()
lx.eval('view3d.wireframeAlpha 0.1 active')
lx.eval('view3d.shadingStyle shade')
# There is an exception for Wireframe. If we didn't toggle XRay (to exit) and passed directly to Wireframe,
# then we will return again to XRay, since this is more straightforward:
elif myActualShading == 'wire':
lx.eval('view3d.shadingStyle advgl')
# For all other case, remove XRAYMAT, pass to Shade and return back to default 0.1 wire transparency:
else:
remove_XRAYMAT()
lx.eval('view3d.wireframeAlpha 0.1 active')
#----------------------------------------------------------------------------------------------------------------
# OPTION B. We DON'T HAVE a previously created 'XRAYMAT' material.
#----------------------------------------------------------------------------------------------------------------
# This is where we created the semitransparent material. Change these parameters to create a custom one:
else:
renderitem = lx.eval('query sceneservice render.id ? 0')
lx.eval('shader.create advancedMaterial')
lx.eval('item.name "XRAYMAT" advancedMaterial')
lx.eval('texture.parent %s -1' %renderitem)
lx.eval('item.channel advancedMaterial$diffAmt 1.0') # Diffuse Amount
lx.eval('item.channel advancedMaterial$diffCol {0.60 0.65 0.70}') # Diffuse Color
lx.eval('item.channel advancedMaterial$specAmt 0.3') # Specular Amount
lx.eval('item.channel advancedMaterial$rough 1.0') # Diffuse Roughness
lx.eval('item.channel advancedMaterial$tranAmt 0.2') # Transparency
lx.eval('view3d.shadingStyle advgl') # Important to make wires visible through surfaces
lx.eval('view3d.wireframeAlpha 1 active') # Important to make wires visible through surfaces
lx.eval('select.drop item advancedMaterial')
lx.eval('select.drop item polyRender')
#----------------------------------------------------------------------------------------------------------------
# We recover all that was previously selected in Shader Tree from our 'myPrevSelected' List.
#----------------------------------------------------------------------------------------------------------------
for id in myPrevSelected:
lx.eval("select.subItem %s add" % id) # Better to use "add" since "set" would replace the current selection with this thing alone.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment