Get all texture tags & show texture paths,but reflection channel throw error? :(
-
Hello guys,
It's been a while guys hope y'all okay.I working on a small script, on getting all texture tags on object & show texture paths by printing out to the c4d console.
But the reflection channel throw error when I enable the code to run, It's like it don't want me to get the texture path.CODE:
import c4d, os, shutil from c4d import plugins, gui, bitmaps, documents, storage from os import path as p #Welcome to the world of Python def CopyPath_To_Path(path, tex_path, pastefolder): if ":\\" not in path: # Is in tex. Tex_path = tex_path + "\\tex\\" + path shutil.copy2(Tex_path, pastefolder) print Tex_path else: # Not in tex. shutil.copy2(path, pastefolder) print path return True def main(): desk_folder = storage.GeGetC4DPath(c4d.C4D_PATH_DESKTOP) folder = os.path.join(desk_folder, "CopyTextures") if not p.exists(folder): os.mkdir(folder) doc = c4d.documents.GetActiveDocument() if doc == None: return False # Get Objects form the Object Manager list_objs = doc.GetActiveObjects(1) if not list_objs: gui.MessageDialog("Select an Object!") return for E in list_objs: doc = c4d.documents.GetActiveDocument() ProjectTexPath = doc.GetDocumentPath() object_Tags = E.GetTags() for each_c4d_tag in object_Tags: if each_c4d_tag.CheckType(c4d.Ttexture): get_t = each_c4d_tag[c4d.TEXTURETAG_MATERIAL] makstr = str(get_t) # Get string by spliting a long string up. str_1 = makstr.split("'")[1] finalstr = str_1.split('/')[0] # Material Name MatName = finalstr # Find Material GetMat = doc.SearchMaterial(MatName) # Get Material userMat = doc.GetActiveMaterial() # Get Material Shaders Texture Paths. m_color = userMat[c4d.MATERIAL_COLOR_SHADER] show_loc_path_Diff = m_color[c4d.BITMAPSHADER_FILENAME] CopyPath_To_Path(path=show_loc_path_Diff, tex_path=ProjectTexPath, pastefolder=folder) m_alpha = userMat[c4d.MATERIAL_ALPHA_SHADER] show_loc_path_Alpha = m_alpha[c4d.BITMAPSHADER_FILENAME] CopyPath_To_Path(path=show_loc_path_Alpha, tex_path=ProjectTexPath, pastefolder=folder) m_diffusion = userMat[c4d.MATERIAL_DIFFUSION_SHADER] show_loc_path_diff = m_diffusion[c4d.BITMAPSHADER_FILENAME] CopyPath_To_Path(path=show_loc_path_diff, tex_path=ProjectTexPath, pastefolder=folder) m_lum = userMat[c4d.MATERIAL_LUMINANCE_SHADER] show_loc_path_LM = m_lum[c4d.BITMAPSHADER_FILENAME] CopyPath_To_Path(path=show_loc_path_LM, tex_path=ProjectTexPath, pastefolder=folder) m_nor = userMat[c4d.MATERIAL_NORMAL_SHADER] show_loc_path_Nor = m_nor[c4d.BITMAPSHADER_FILENAME] CopyPath_To_Path(path=show_loc_path_Nor, tex_path=ProjectTexPath, pastefolder=folder) m_trans = userMat[c4d.MATERIAL_TRANSPARENCY_SHADER] show_loc_path_Trans = m_trans[c4d.BITMAPSHADER_FILENAME] CopyPath_To_Path(path=show_loc_path_Trans, tex_path=ProjectTexPath, pastefolder=folder) m_enviro = userMat[c4d.MATERIAL_ENVIRONMENT_SHADER] show_loc_path_enviro = m_enviro[c4d.BITMAPSHADER_FILENAME] CopyPath_To_Path(path=show_loc_path_enviro, tex_path=ProjectTexPath, pastefolder=folder) m_bump = userMat[c4d.MATERIAL_BUMP_SHADER] show_loc_path_bump = m_bump[c4d.BITMAPSHADER_FILENAME] CopyPath_To_Path(path=show_loc_path_bump, tex_path=ProjectTexPath, pastefolder=folder) #----------------------------------------------------------------# # THE PROBLEM HERE WHEN I ENABLE IT. #m_spec = userMat[c4d.MATERIAL_REFLECTION_SHADER] #show_loc_path_Spec = m_spec[c4d.BITMAPSHADER_FILENAME] #print show_loc_path_Spec #----------------------------------------------------------------# c4d.EventAdd() if __name__=='__main__': main()
Error in the Console:
TypeError: 'NoneType' object has no attribute 'getitem'
tips on this would be great.
cheers,
Ashton -
Hi @Ashton_FCS_PluginDev, we are glad to see you back in the new plugincafe community!
No worries at all since it's your first post here, but please make sure to read and apply the rules defined on the following topics:Regarding your issue, you read m_spec, but you never check if there is a bitmashader in it or not. And in your case, there is no, so m_spec is set to None, and you are then trying to access value.
So please always check for None.
Then since you directly read the BITMAPSHADER_FILENAME parameter from this shader, please also consider to check the shader type you retrieve, maybe a user used a noise and not a bitmap.m_spec = userMat[c4d.MATERIAL_REFLECTION_SHADER] if not m_spec or m_spec.CheckType(c4d.Xbitmap): continue
Finally, as you may already be aware, reflection gets multiple layers. You get some information in this thread, how to deal with it.
If you have any others question, please let me know!
Cheers,
Maxime. -
Thank you m_adam! And for the advice.
Everything works fine, and no error.
But Maxon needs to add some of the C++ api sdk to the python api sdk. Cause I had to research for the (REFLECTION_LAYER types ) and they was in c++ sdk so I hope maxon think about this, cause it a lot of up and down lol.The fix and working code:
# Get Reflection or Spec map texture from the Reflectance Channel. m_spec = userMat.GetReflectionLayerCount() for each_layer in xrange(0, m_spec): getlayer = userMat.GetReflectionLayerIndex(each_layer) get_spec = userMat[getlayer.GetDataID() + c4d.REFLECTION_LAYER_COLOR_TEXTURE] if not get_spec or get_spec.CheckType(c4d.Xbitmap): print " No bitmap apply in this channel. " pass else: show_loc_path_Spec = get_spec[c4d.BITMAPSHADER_FILENAME] print show_loc_path_Spec
For anyone who would like to use or learn from the script. You can download full script from github. ( Get And Copy Textures From Texture Tags )
Thanks again and Cheers,
Ashton,
Love new plugincafe forum! -
For anyone who would like to use or learn from the script. You can download full script from github. ( Get And Copy Textures From Texture Tags )