Your browser does not seem to support JavaScript. As a result, your viewing experience will be diminished, and you have been placed in read-only mode.
Please download a browser that supports JavaScript, or enable it if it's disabled (i.e. NoScript).
Thank you very much, right now i am quite happy how it works. only thing is the dialog box opens for each shader because its in the "changeshader" function wich repeats. I d' like to have one gui-call at the start in the main function, but if i do that theni cant transport the "prefix" argument to the changeTexture(shader) function.
about the time investement i agree, but for this script was more an out of desperation approach in how cinema4d lacks in organizing textures, then a new grind in passion. the script helps me with a hack, to organize them on OS side, for team projects like for instance unity.
Best Moko
import c4d from c4d import gui import os #GUI GROUP = 1000 TEXT = 1001 PREFIX = 1002 BTN_OK = 1010 BTN_CANCEL = 1020 class userDialog(gui.GeDialog): def CreateLayout(self): self.SetTitle("Add Prefix") self.GroupBegin(GROUP, c4d.BFH_SCALEFIT, 3,5, title = "Adds a prefix to the texturename") self.GroupBorder(c4d.BORDER_GROUP_IN) self.GroupBorderSpace(20, 5, 20 , 5) self.AddStaticText(TEXT, c4d.BFH_SCALEFIT, name="Prefix") self.AddEditText(PREFIX, c4d.BFH_SCALEFIT) self.AddButton(BTN_OK, c4d.BFH_SCALE, name="Ok") self.AddButton(BTN_CANCEL, c4d.BFH_SCALE, name="Cancel") self.GroupEnd() return True def InitValues(self): #initiate the gadgets with values self.SetString(PREFIX, "Tex_") return True def Command(self, id, msg): #handle user input if id==BTN_CANCEL: self.Close() elif id==BTN_OK: self.TexturPrefix = self.GetString(PREFIX) self.Close() return True # Adds a prefix to the texturename def changeTexture(shader) : dialog = userDialog() dialog.Open(c4d.DLG_TYPE_MODAL, defaultw=200, defaulth=50) prefix = dialog.TexturPrefix print (prefix) # shader ID texturePath = shader[c4d.BITMAPSHADER_FILENAME] # split aboslute path oldTexturename = os.path.split(texturePath) # add prefix newTexturename = prefix + oldTexturename[1] doc = shader.GetDocument() doc.AddUndo(c4d.UNDOTYPE_CHANGE, shader) # Assign the new value shader[c4d.BITMAPSHADER_FILENAME] = os.path.join(oldTexturename[0], newTexturename) shader.Message(c4d.MSG_UPDATE) # Iterate a hierarchy def recurse_hierarchy(shader) : while shader: # Test if the current node is a bitmap shader. if shader.CheckType(c4d.Xbitmap) : changeTexture(shader) recurse_hierarchy(shader.GetDown()) shader = shader.GetNext() # Main function def main() : mats = doc.GetActiveMaterials() doc.StartUndo() # Iterate over selected material for mat in mats: recurse_hierarchy(mat.GetFirstShader()) doc.EndUndo() # Execute main() if __name__=='__main__': main()
Now it works as intended. You can select the materials for which you want to change the prefix of the texturename. The actual name of the texture is not changed. You need to do this with a renaming-tool at the OS level.
thanks to everyone
import c4d from c4d import gui import os #GUI GROUP = 1000 TEXT = 1001 PREFIX = 1002 BTN_OK = 1010 BTN_CANCEL = 1020 prefix = "placeholder" class userDialog(gui.GeDialog): def CreateLayout(self): self.SetTitle("Add Prefix") self.GroupBegin(GROUP, c4d.BFH_SCALEFIT, 3,5, title = "Adds a prefix to the texturename") self.GroupBorder(c4d.BORDER_GROUP_IN) self.GroupBorderSpace(20, 5, 20 , 5) self.AddStaticText(TEXT, c4d.BFH_SCALEFIT, name="Prefix") self.AddEditText(PREFIX, c4d.BFH_SCALEFIT) self.AddButton(BTN_OK, c4d.BFH_SCALE, name="Ok") self.AddButton(BTN_CANCEL, c4d.BFH_SCALE, name="Cancel") self.GroupEnd() return True def InitValues(self): #initiate the gadgets with values self.SetString(PREFIX, "Tex_") return True def Command(self, id, msg): #handle user input if id==BTN_CANCEL: self.Close() elif id==BTN_OK: self.TexturPrefix = self.GetString(PREFIX) self.Close() return True # Adds a prefix to the texturename def changeTexture(shader) : print (prefix) # shader ID texturePath = shader[c4d.BITMAPSHADER_FILENAME] # split aboslute path oldTexturename = os.path.split(texturePath) # add prefix newTexturename = prefix + oldTexturename[1] doc = shader.GetDocument() doc.AddUndo(c4d.UNDOTYPE_CHANGE, shader) # Assign the new value shader[c4d.BITMAPSHADER_FILENAME] = os.path.join(oldTexturename[0], newTexturename) shader.Message(c4d.MSG_UPDATE) # Iterate a hierarchy def recurse_hierarchy(shader) : while shader: # Test if the current node is a bitmap shader. if shader.CheckType(c4d.Xbitmap) : changeTexture(shader) recurse_hierarchy(shader.GetDown()) shader = shader.GetNext() # Main function def main() : mats = doc.GetActiveMaterials() dialog = userDialog() dialog.Open(c4d.DLG_TYPE_MODAL, defaultw=200, defaulth=50) global prefix prefix = dialog.TexturPrefix doc.StartUndo() # Iterate over selected material for mat in mats: recurse_hierarchy(mat.GetFirstShader()) doc.EndUndo() # Execute main() if __name__=='__main__': main()
@ferdinand
Thank you very much! The second way works great. I didnt get the first approach to work, but the second does well
Here is the script if someone needs it. It is probably messy I am not a programmer, but it does write the names of the selected materials into the texturname
import c4d from c4d import gui from c4d import storage import os #Welcome to the world of Python def changeTexture(shader): # shader ID texturePath = shader[c4d.BITMAPSHADER_FILENAME] # split aboslute path oldTexturename = os.path.split(texturePath) fileExtension = os.path.splitext(texturePath) # add prefix to newTexturename = matName + fileExtension[1] print (newTexturename) newTexturePath = os.path.join(oldTexturename[0], newTexturename) print (newTexturePath) # rename texture try : os.rename(texturePath, newTexturePath) print("Source path renamed to destination path successfully.") except OSError as error: print(error) # Assign the new value shader[c4d.BITMAPSHADER_FILENAME] = newTexturePath shader.Message(c4d.MSG_UPDATE) # Main function def main() : c4d.CallCommand(1029486) # Project Asset Inspector... c4d.CallCommand(1029816) # Select Assets of Active Elements c4d.CallCommand(1029820) # Globalize Filenames # Iterate over selected material material = doc.GetFirstMaterial() if not material: return while material: if material.GetBit(c4d.BIT_ACTIVE): shader = material.GetFirstShader() global matName matName = material.GetName() while shader: # Test if the current node is a bitmap shader. if shader.CheckType(c4d.Xbitmap) : changeTexture(shader) shader (shader.GetDown()) shader = shader.GetNext() material = material.GetNext() c4d.CallCommand(200000273) # Reload All Textures # Execute main() if __name__=='__main__': main()
Is it possible to make an iteration through a selection of Materials. I'd like to rename the texture after the material. It works but only on all materials in the doc. how do i specify it on to a selection of materials?
import c4d from c4d import gui from c4d import storage import os #Welcome to the world of Python def changeTexture(shader): # shader ID texturePath = shader[c4d.BITMAPSHADER_FILENAME] # split aboslute path oldTexturename = os.path.split(texturePath) fileExtension = os.path.splitext(texturePath) # add prefix to newTexturename = matName + fileExtension[1] print (newTexturename) newTexturePath = os.path.join(oldTexturename[0], newTexturename) print (newTexturePath) # rename texture try : os.rename(texturePath, newTexturePath) print("Source path renamed to destination path successfully.") except OSError as error: print(error) # Assign the new value shader[c4d.BITMAPSHADER_FILENAME] = newTexturePath shader.Message(c4d.MSG_UPDATE) # Main function def main() : c4d.CallCommand(1029486) # Project Asset Inspector... c4d.CallCommand(1029813) # Select All c4d.CallCommand(1029820) # Globalize Filenames # Iterate over selected material mat = doc.GetFirstMaterial() while mat: shader = mat.GetFirstShader() global matName matName = mat.GetName() while shader: # Test if the current node is a bitmap shader. if shader.CheckType(c4d.Xbitmap) : changeTexture(shader) shader (shader.GetDown()) shader = shader.GetNext() mat = mat.GetNext() # c4d.CallCommand(200000273) # Reload All Textures # Execute main() if __name__=='__main__': main()
@zipit
hm yes this sounds too complicated overall, particularly point 3 there could so much happen on the os side. A gui with more options like renaming the hole texturename or a replace option of certain words could be the way forward. Instead of undo it would be easy then to rename the texture with he old name etc. for now im happy how this works and let this solved.
Much Thanks! Cheers, moko
@zipit Thank you! That was exactly i was looking for
here the new Version: I throw out the undo function because i dont know if it can adress the os part. Is this possible to have an undo on os.rename?
import c4d from c4d import gui import os, sys prefix="placeholder" # Adds a prefix to the texturename def changeTexture(shader): # shader ID texturePath = shader[c4d.BITMAPSHADER_FILENAME] # split aboslute path oldTexturename = os.path.split(texturePath) # add prefix to newTexturename = prefix + oldTexturename[1] print (newTexturename) newTexturePath = os.path.join(oldTexturename[0], newTexturename) print (newTexturePath) # rename texture try : os.rename(texturePath, newTexturePath) print("Source path renamed to destination path successfully.") except OSError as error: print(error) # Assign the new value shader[c4d.BITMAPSHADER_FILENAME] = newTexturePath shader.Message(c4d.MSG_UPDATE) # Iterate a hierarchy def recurse_hierarchy(shader) : while shader: # Test if the current node is a bitmap shader. if shader.CheckType(c4d.Xbitmap) : changeTexture(shader) recurse_hierarchy(shader.GetDown()) shader = shader.GetNext() # Main function def main() : mats = doc.GetActiveMaterials() global prefix prefix = c4d.gui.RenameDialog("Prefix_") print (prefix) # Iterate over selected material for mat in mats: recurse_hierarchy(mat.GetFirstShader()) # Execute main() if __name__=='__main__': main()
Cheers, moko
Thank you for both inputs. Im not used to programming and copy and paste the lines. Thanks for the help!
Thanks it works like expected, now i would like to add a smal GUI but i get stuck, how do i bring the name from the GUI in as prefix.
import c4d from c4d import gui import os #GUI GROUP = 1000 TEXT = 1001 NAME = 1010 class userDialog(gui.GeDialog): def CreateLayout(self): self.SetTitle("Add Prefix") self.GroupBegin(GROUP, c4d.BFH_SCALEFIT, 3,5, title = "AAdds a prefix to the texturename") self.GroupBorder(c4d.BORDER_GROUP_IN) self.GroupBorderSpace(20, 5, 20 , 5) self.AddStaticText(TEXT, c4d.BFH_SCALEFIT, name="Prefix") self.AddEditText(NAME, c4d.BFH_RIGHT, 200, 0, 0) # Adds a prefix to the texturename def changeTexture(shader) : prefix = "Tex_" # shader ID texturePath = shader[c4d.BITMAPSHADER_FILENAME] # split aboslute path oldTexturename = os.path.split(texturePath) # add prefix newTexturename = prefix + oldTexturename[1] doc = shader.GetDocument() doc.AddUndo(c4d.UNDOTYPE_CHANGE, shader) # Assign the new value shader[c4d.BITMAPSHADER_FILENAME] = os.path.join(oldTexturename[0], newTexturename) shader.Message(c4d.MSG_UPDATE) # Iterate a hierarchy def recurse_hierarchy(shader) : while shader: # Check if it's a c4d shader if c4d.BaseShader() : changeTexture(shader) recurse_hierarchy(shader.GetDown()) shader = shader.GetNext() # Main function def main() : mats = doc.GetActiveMaterials() doc.StartUndo() # Iterate over selected material for mat in mats: recurse_hierarchy(mat.GetFirstShader()) doc.EndUndo() def main(): dialog = userDialog() dialog.Open(c4d.DLG_TYPE_MODAL, defaultw=200, defaulth=50) c4d.EventAdd() # Execute main() if __name__=='__main__': main()
thx for help mok
Thanks alot it works! but the material iteration posts an error def main() : mats = doc.GetActiveMaterials()
doc.StartUndo() # Iterate over selected material for mat in mats: recurse_hierarchy(mat.GetFirstShader()) doc.Endndo()
it didnt find doc.Endndo() is there a way to iterate over the materials?
my second question: now the script replaces A with B. Is it possible to "add" like a prefix? I have alot of textures and would like to add a "Tex_" as a prefix, so its easier to sort/find them. Like "TrainStation.jpg" to "Tex_TrainStation.jpg"
I found this but it need the name of a object or material: http://www.plugincafe.com/forum/forum_posts.asp?TID=6265
Thanks for any suggestions and maybe someone need this aswell cheers moko
Hi, i am looking for Texture renaming scripts and found this old topic https://plugincafe.maxon.net/topic/10897/14346_textures-renamer-script unforgently i have no knowledge in code.. my question, has someone the time to modify it, so it works with a normal cinema4d bitmapshader instead of vray? thanks alot, mk