On 20/01/2018 at 07:46, xxxxxxxx wrote:
Hey guys,
I'm currently writing a script which later on I want to turn into a Commanddata plugin.
The script is quite straightforward. I want to rename a shader only if it is in a specific material channel.
So if the user executes the script from the Script Manager a gui popup appears where the user can choose which material channel should be searched for the specific shader, e.g. the c4d color shader.
To check if the desired shader is in a material at all I use a code example from cineversity where a material gets checked recursively. So if the first shader in for example the color channel is not a color shader but let's say a layer shader or any other shader where the color shader could be potentially under, I can still access it and don't be limited to the very first level of hierarchy.
However, the problem here is that I noticed some strange behaviour with this approach.
I set up a basic scene where I have only one material with the color and the luminance channel both active and in each of these channels I loaded a color shader.
If I choose in the script that only the color channel should be searched for any color shaders and run the renaming process, the color shader in the luminance channel gets also renamed.
I did a lot of testing and tried to come up with different code approaches but all I got was an unpredictable behaviour where one time only the color shader in the color channel was renamed (like desired) and the other time it was quite off as the color shader in the luminance channel got renamed as well.
I don't know if I'm running into some kind of limitations here. And although I already created some python scripts or expressions in the past, I wouldn't consider myself a professional programmer.
It's more a skillset based on a self taught basis i guess.
Well, however, heres the code of the script.
As I don't have any ideas anymore how to tackle this, I deeply appreciate if someone can help me here.
Thanks,
Sebastian
import c4d
from c4d import gui
def popupMenu() :
# ------------------------------------------------------------
# Declare menu items ID
# ------------------------------------------------------------
IDM_MENU1 = c4d.FIRST_POPUP_ID
IDM_MENU2 = c4d.FIRST_POPUP_ID + 1
# ------------------------------------------------------------
# Main menu
# ------------------------------------------------------------
menu = c4d.BaseContainer()
menu.InsData(IDM_MENU1, 'Color') # Color channel
menu.InsData(IDM_MENU2, 'Luminance') # Luminance channel
# ------------------------------------------------------------
# Finally show popup dialog
# ------------------------------------------------------------
result = gui.ShowPopupDialog(cd=None, bc=menu, x=c4d.MOUSEPOS, y=c4d.MOUSEPOS)
return result
def renameShader(shader, shader_type) :
"""
Loop through the BaseList.
"""
testname = 'My shader'
while(shader) :
if shader.GetType() == shader_type:
name = shader[c4d.ID_BASELIST_NAME]
if name is not testname:
shader[c4d.ID_BASELIST_NAME] = '{}'.format(testname)
# Check for child shaders & recurse
if shader.GetDown() :
renameShader(shader.GetDown(), shader_type)
# Get the Next Shader
shader = shader.GetNext()
def main() :
doc.StartUndo()
bc = c4d.BaseContainer()
result = popupMenu()
if result == 0:
return
mats = doc.GetActiveMaterials()
if not mats:
gui.MessageDialog('No material selected.')
for mat in mats:
doc.AddUndo(c4d.UNDOTYPE_CHANGE, mat)
if result == 900000:
shader = mat[c4d.MATERIAL_COLOR_SHADER] # Color channel
elif result == 900001:
shader = mat[c4d.MATERIAL_LUMINANCE_SHADER] # Luminance channel
renameShader(shader, c4d.Xcolor)
mat = mat.GetNext()
doc.EndUndo()
c4d.EventAdd()
if __name__=='__main__':
main()