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.


        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  
                # 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):
            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!")
            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
        if __name__=='__main__':

    Error in the Console:
    alt text

    TypeError: 'NoneType' object has no attribute 'getitem'

    tips on this would be great.

  • 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):

    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!

  • 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. "
                        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,
    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 )

Log in to reply