Iterate through selected Materials
-
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()
-
Hello @moko,
thank you for reaching out to us. There are in principle two ways to do this.
BaseDocument
contains a handful of methods to retrieve the 'active', i.e., selected, entities of some type, e.g., objects, tags, and also materials. The method in question would beBaseDocument.GetActiveMaterials()
.There is also a more general-purpose approach via
BaseList2D.GetBit()
for retrieving the selection state of a node, which will also work for node types that that do not have such special purpose methods. For details, please see the example at the end of this posting.Cheers,
Ferdinand"""Example for determining the selection state of BaseList2D nodes via GetBit(). To be run as a Script Manger script. Will print out the names of the selected materials. As discussed in: https://developers.maxon.net/forum/topic/13446/ """ import c4d def main(): """ """ # We can get the active Materials with BaseDocument.GetActiveMaterials() for activeMaterial in doc.GetActiveMaterials(): print (f"{activeMaterial.GetName()} is a selected Material.") print ("\n", "-" * 100, "\n") # Or we can iterate over the materials and use the bit flags of the nodes # to determine their selection state. The advantage here is that this will # work for any BaseList2D and not only the ones (objects, tags, materials, # etc.) where specific methods exist to retrieve the selected/active ones. # The relevant method is BaseList2D.GetBit() and the relevant bit mask is # BIT_ACTIVE - which indicates the selection state of the BaseList2D. # Get the first material like you did. material = doc.GetFirstMaterial() if not material: return while material: # Print out only materials that are selected. if material.GetBit(c4d.BIT_ACTIVE): print (f"{material.GetName()} is a selected Material.") material = material.GetNext() # Execute main() if __name__=='__main__': main()
-
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()