Advertisement
gr4ph0s

c4d python TexturePath handling

Apr 19th, 2018
384
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 18.87 KB | None | 0 0
  1. # -*- coding: utf-8 -*-
  2. import os
  3. import c4d
  4. import operator
  5.  
  6.  
  7. class Utility(object):
  8.     @staticmethod
  9.     def __is_texture_relative(texture_path):
  10.         if not len(os.path.split(texture_path)[0]):
  11.             return False
  12.  
  13.         else:
  14.             if texture_path[:1] == "." or texture_path[:1] == os.path.sep or texture_path[:1] == "/":
  15.                 return True
  16.  
  17.             return False
  18.  
  19.     def __get_all_texture(self):
  20.         doc = c4d.documents.GetActiveDocument()
  21.         all_texture = []
  22.         mat = doc.GetFirstMaterial()
  23.         while mat:
  24.             sha = mat.GetFirstShader()
  25.             all_texture += self.__recurse_find_bitmap(sha)
  26.             mat = mat.GetNext()
  27.  
  28.         return all_texture
  29.  
  30.     def __get_tex_path_from_bmp_shader(self, sha):
  31.         doc = c4d.documents.GetActiveDocument()
  32.         path_tex = sha[c4d.BITMAPSHADER_FILENAME]
  33.         if path_tex:
  34.             if len(path_tex):
  35.                 if self.__is_texture_relative(path_tex):
  36.                     return os.path.join(doc.GetDocumentPath(), path_tex)
  37.  
  38.                 else:
  39.                     if len(os.path.split(path_tex)):
  40.                         return path_tex.decode('utf8')
  41.  
  42.         return None
  43.  
  44.     def __recurse_find_bitmap(self, sha):
  45.         tex = []
  46.         while sha:
  47.             if sha.CheckType(c4d.Xbitmap):
  48.                 buffer_path = self.__get_tex_path_from_bmp_shader(sha)
  49.                 if buffer_path:
  50.                     buffer_tex = {}
  51.                     buffer_tex["path"] = buffer_path
  52.                     buffer_tex["material"] = sha.GetMain()
  53.                     buffer_tex["shader"] = sha
  54.                     buffer_tex["channel"] = self.__get_channel_from_shader(sha)
  55.  
  56.                     tex.append(buffer_tex)
  57.             tex += self.__recurse_find_bitmap(sha.GetDown())
  58.             sha = sha.GetNext()
  59.         return tex
  60.  
  61.     def __test_valid_picture(self, picture_path):
  62.         if not picture_path:
  63.             return False
  64.  
  65.         if not os.path.exists(picture_path) and not os.path.isabs(picture_path):
  66.             return False
  67.  
  68.         bmp = c4d.bitmaps.BaseBitmap()
  69.         result = bmp.InitWith(picture_path.encode('utf8'))
  70.         if result[0] == c4d.IMAGERESULT_OK:
  71.             return True
  72.         else:
  73.             return False
  74.  
  75.     def __add_texture_to_list(self, texture_list, real_path, texture_name, sha_path, mat, sha, channel):
  76.         buffer_tex = {}
  77.         buffer_tex["absolute_path"] = real_path
  78.         buffer_tex["tex_name"] = texture_name
  79.         buffer_tex["relative_path"] = sha_path
  80.         buffer_tex["material"] = mat
  81.         buffer_tex["shader"] = sha
  82.         buffer_tex["channel"] = channel
  83.  
  84.         texture_list.append(buffer_tex)
  85.  
  86.     def test_esc(self):
  87.         state = c4d.BaseContainer()
  88.         if c4d.gui.GetInputState(c4d.BFM_INPUT_KEYBOARD, c4d.KEY_ESC, state):
  89.             if state[c4d.BFM_INPUT_VALUE]:
  90.                 return True
  91.         return False
  92.  
  93.     def get_texture_data(self):
  94.         debug = False
  95.         all_tex = self.__get_all_texture()
  96.         c4d.StatusClear()
  97.  
  98.         texture_found = list()
  99.         texture_to_relocate = list()
  100.         texture_not_found = list()
  101.  
  102.         doc = c4d.documents.GetActiveDocument()
  103.         docpath = doc.GetDocumentPath()
  104.         suggestedfolder = str()
  105.         for tex in all_tex:
  106.             if self.test_esc():
  107.                 break
  108.             current_id = all_tex.index(tex)
  109.             percent = current_id * 100 / len(all_tex)
  110.             color = c4d.utils.MixVec(c4d.Vector(0.79, 0, 0), c4d.Vector(0.297, 0.72, 0.13), percent/100.00)
  111.             c4d.StatusSetNetBar(percent, color)
  112.  
  113.             texture = c4d.GenerateTexturePath(docpath, tex["path"], suggestedfolder)
  114.  
  115.             if texture:
  116.                 c4d.StatusSetText(texture)
  117.                 texture = texture.decode('utf8')
  118.             else:
  119.                 c4d.StatusSetText(tex["path"].encode('utf8'))
  120.  
  121.             # If file path from GenerateTexturePath is the same than than the one in the shader
  122.             if texture and texture == tex["path"]:
  123.                 if debug: print "identical Generate"
  124.  
  125.                 # Is in tex folder
  126.                 if os.path.split(texture)[1] in os.listdir(os.path.join(docpath, "tex")):
  127.                     if debug: print os.listdir(os.path.join(docpath, "tex"))
  128.                     self.__add_texture_to_list(texture_to_relocate,
  129.                                                os.path.join(docpath, "tex", os.path.split(texture)[1]),
  130.                                                os.path.split(tex["path"])[1],
  131.                                                tex["path"], tex["material"],
  132.                                                tex["shader"],
  133.                                                tex["channel"])
  134.  
  135.                 elif texture[:6] == "preset":
  136.                     if debug:  print "Is_preset"
  137.                     if self.__test_valid_picture(texture):
  138.                         if debug: print "valid picture"
  139.                         self.__add_texture_to_list(texture_found, texture, os.path.split(texture)[1],
  140.                                                  tex["path"], tex["material"], tex["shader"], tex["channel"])
  141.  
  142.                     else:
  143.                         if debug: print "picture corrupted"
  144.                         self.__add_texture_to_list(texture_not_found, None, os.path.split(tex["path"])[1],
  145.                                                  tex["path"], tex["material"], tex["shader"], tex["channel"])
  146.  
  147.                 #if it's not a preset
  148.                 else:
  149.                     if os.path.exists(texture):
  150.                         self.__add_texture_to_list(texture_found, texture, os.path.split(texture)[1],
  151.                                                  tex["path"], tex["material"], tex["shader"], tex["channel"])
  152.  
  153.                     #If file didn't exist
  154.                     else:
  155.                         self.__add_texture_to_list(texture_not_found, None, os.path.split(tex["path"])[1],
  156.                                                  tex["path"], tex["material"], tex["shader"], tex["channel"])
  157.  
  158.             # If file path from GenerateTexturePath is not the same than the one in the shader, but GenerateTexturePath return a file
  159.             elif texture and texture != tex["path"]:
  160.                 if debug: print "no identical"
  161.  
  162.                 #If picture from shader is valid
  163.                 if self.__test_valid_picture(tex["path"]):
  164.                     if debug:  print "shader_picture_valid"
  165.                     self.__add_texture_to_list(texture_found, tex["path"], os.path.split(tex["path"])[1],
  166.                                                tex["path"], tex["material"], tex["shader"], tex["channel"])
  167.  
  168.                 # If picture from GenerateTexturePath is valid and exist (absolute)
  169.                 elif self.__test_valid_picture(texture):
  170.                     if debug: print "generate_picture_valid"
  171.                     if not os.path.isabs(tex["path"]) and self.__test_valid_picture(tex["path"]):
  172.                         if debug:  print "No Absolute path"
  173.                         self.__add_texture_to_list(texture_found, tex["path"], os.path.split(tex["path"])[1],
  174.                                                    tex["path"], tex["material"], tex["shader"], tex["channel"])
  175.                     else:
  176.                         if debug: print "Absolute path"
  177.                         self.__add_texture_to_list(texture_found, texture, os.path.split(tex["path"])[1],
  178.                                                    tex["path"], tex["material"], tex["shader"], tex["channel"])
  179.  
  180.  
  181.                 # If picture is relative we test if it's in the search path
  182.                 elif c4d.IsInSearchPath(os.path.split(tex["path"])[1], docpath) and self.__test_valid_picture(texture):
  183.                     if debug: print "In search path and valid generate"
  184.                     self.__add_texture_to_list(texture_to_relocate, texture, os.path.split(tex["path"])[1],
  185.                                                tex["path"], tex["material"], tex["shader"], tex["channel"])
  186.  
  187.                 #If picture is not valid
  188.                 else:
  189.                     if debug: print "generate picture not in search path or not valid"
  190.                     #Si l'image est dans les search path on relocate
  191.                     if c4d.IsInSearchPath(tex["path"], docpath) or os.path.exists(texture):
  192.                         if debug: print "generate picture not in search path"
  193.                         self.__add_texture_to_list(texture_to_relocate, texture, os.path.split(tex["path"])[1],
  194.                                                    tex["path"], tex["material"], tex["shader"], tex["channel"])
  195.  
  196.                     #If we are here, picture is not found
  197.                     else:
  198.                         if debug: print "generate picture not valid"
  199.                         self.__add_texture_to_list(texture_not_found, None, os.path.split(tex["path"])[1],
  200.                                                    tex["path"], tex["material"], tex["shader"], tex["channel"])
  201.  
  202.             # If path is different and we didn't found a texture
  203.             else:
  204.                 self.__add_texture_to_list(texture_not_found, None, os.path.split(tex["path"])[1],
  205.                                            tex["path"], tex["material"], tex["shader"], tex["channel"])
  206.  
  207.         texture_found.sort(key=operator.itemgetter('tex_name'))
  208.         texture_to_relocate.sort(key=operator.itemgetter('tex_name'))
  209.         texture_not_found.sort(key=operator.itemgetter('tex_name'))
  210.         c4d.StatusNetClear()
  211.         return texture_found, texture_to_relocate, texture_not_found
  212.  
  213.     def __get_first_parent_shader(self, shader, mat):
  214.         while mat:
  215.             buffer_sha = shader.GetUp()
  216.             if buffer_sha:
  217.                 shader = buffer_sha
  218.             else:
  219.                 break
  220.  
  221.         return shader
  222.  
  223.     def __get_linked_shader(self, shader, all_shader_list=list()):
  224.         linkedData = self.__get_linked_data(shader)
  225.         all_shader_list += linkedData
  226.  
  227.         for sha in linkedData:
  228.             linkedData = self.__get_linked_shader(sha, all_shader_list)
  229.             for linked_sha in linkedData:
  230.                 if linked_sha not in all_shader_list:
  231.                     all_shader_list.append(linked_sha)
  232.  
  233.         return all_shader_list
  234.  
  235.     def __get_linked_data(self, shader):
  236.         buffer = list()
  237.         doc = c4d.documents.GetActiveDocument()
  238.  
  239.         bc = shader.GetDataInstance()
  240.         for i in xrange(len(bc)):
  241.             index = bc.GetIndexId(i)
  242.  
  243.             linked = bc.GetLink(index, doc, c4d.Xbase)
  244.             if linked:
  245.                 buffer.append(linked)
  246.  
  247.         return buffer
  248.  
  249.     def __get_channel_from_shader(self, shader):
  250.         mat = shader.GetMain()
  251.         parent_shader = self.__get_first_parent_shader(shader, mat)
  252.         text = "Unknown"
  253.         data = list()
  254.         if mat.CheckType(1020295):
  255.             text = "VrayMat::"
  256.             data = [
  257.                 {"link_id": [
  258.                     c4d.VRAYMATERIAL_SSS_OVERALLCOLORSHADER,
  259.                     c4d.VRAYMATERIAL_SSS_SSSCOLORSHADER,
  260.                     c4d.VRAYMATERIAL_SSS_SCATTERSHADER,
  261.                     c4d.VRAYMATERIAL_SSS_SCATTERMULTSHADER],
  262.                     "value": "SSS"},
  263.  
  264.                 {"link_id": [
  265.                     c4d.VRAYMATERIAL_COLOR2_SHADER,
  266.                     c4d.VRAYMATERIAL_COLOR2_TRANSPSHADER,
  267.                     c4d.VRAYMATERIAL_COLOR2_ROUGHNESSTEX],
  268.                     "value": "Color2"},
  269.  
  270.                 {"link_id": [
  271.                     c4d.VRAYMATERIAL_COLOR1_SHADER,
  272.                     c4d.VRAYMATERIAL_COLOR1_TRANSPSHADER,
  273.                     c4d.VRAYMATERIAL_COLOR1_ROUGHNESSTEX],
  274.                     "value": "Color1"},
  275.  
  276.                 {"link_id": [
  277.                     c4d.VRAYMATERIAL_SPECULAR1_SHADER,
  278.                     c4d.VRAYMATERIAL_SPECULAR1_TRANSPSHADER,
  279.                     c4d.VRAYMATERIAL_SPECULAR1_FRESNELREFLSHADER,
  280.                     c4d.VRAYMATERIAL_SPECULAR1_FRESNELREFRSHADER,
  281.                     c4d.VRAYMATERIAL_SPECULAR1_REFLECTIONGLOSSSHADER,
  282.                     c4d.VRAYMATERIAL_SPECULAR1_HIGHLIGHTGLOSSSHADER,
  283.                     c4d.VRAYMATERIAL_SPECULAR1_ANISOTROPYSHADER,
  284.                     c4d.VRAYMATERIAL_SPECULAR1_ANISOTROPYROTSHADER],
  285.                     "value": "Specular1"},
  286.  
  287.                 {"link_id": [
  288.                     c4d.VRAYMATERIAL_SPECULAR2_SHADER,
  289.                     c4d.VRAYMATERIAL_SPECULAR2_TRANSPSHADER,
  290.                     c4d.VRAYMATERIAL_SPECULAR2_FRESNELREFLSHADER,
  291.                     c4d.VRAYMATERIAL_SPECULAR2_FRESNELREFRSHADER,
  292.                     c4d.VRAYMATERIAL_SPECULAR2_REFLECTIONGLOSSSHADER,
  293.                     c4d.VRAYMATERIAL_SPECULAR2_HIGHLIGHTGLOSSSHADER,
  294.                     c4d.VRAYMATERIAL_SPECULAR2_ANISOTROPYSHADER,
  295.                     c4d.VRAYMATERIAL_SPECULAR2_ANISOTROPYROTSHADER],
  296.                     "value": "Specular2"},
  297.  
  298.                 {"link_id": [
  299.                     c4d.VRAYMATERIAL_SPECULAR3_SHADER,
  300.                     c4d.VRAYMATERIAL_SPECULAR3_TRANSPSHADER,
  301.                     c4d.VRAYMATERIAL_SPECULAR3_FRESNELREFLSHADER,
  302.                     c4d.VRAYMATERIAL_SPECULAR3_FRESNELREFRSHADER,
  303.                     c4d.VRAYMATERIAL_SPECULAR3_REFLECTIONGLOSSSHADER,
  304.                     c4d.VRAYMATERIAL_SPECULAR3_HIGHLIGHTGLOSSSHADER,
  305.                     c4d.VRAYMATERIAL_SPECULAR3_ANISOTROPYSHADER,
  306.                     c4d.VRAYMATERIAL_SPECULAR3_ANISOTROPYROTSHADER],
  307.                     "value": "Specular3"},
  308.  
  309.                 {"link_id": [
  310.                     c4d.VRAYMATERIAL_SPECULAR4_SHADER,
  311.                     c4d.VRAYMATERIAL_SPECULAR4_TRANSPSHADER,
  312.                     c4d.VRAYMATERIAL_SPECULAR4_FRESNELREFLSHADER,
  313.                     c4d.VRAYMATERIAL_SPECULAR4_FRESNELREFRSHADER,
  314.                     c4d.VRAYMATERIAL_SPECULAR4_REFLECTIONGLOSSSHADER,
  315.                     c4d.VRAYMATERIAL_SPECULAR4_HIGHLIGHTGLOSSSHADER,
  316.                     c4d.VRAYMATERIAL_SPECULAR4_ANISOTROPYSHADER,
  317.                     c4d.VRAYMATERIAL_SPECULAR4_ANISOTROPYROTSHADER],
  318.                     "value": "Specular4"},
  319.  
  320.                 {"link_id": [
  321.                     c4d.VRAYMATERIAL_SPECULAR5_SHADER,
  322.                     c4d.VRAYMATERIAL_SPECULAR5_TRANSPSHADER,
  323.                     c4d.VRAYMATERIAL_SPECULAR5_FRESNELREFLSHADER,
  324.                     c4d.VRAYMATERIAL_SPECULAR5_FRESNELREFRSHADER,
  325.                     c4d.VRAYMATERIAL_SPECULAR5_REFLECTIONGLOSSSHADER,
  326.                     c4d.VRAYMATERIAL_SPECULAR5_HIGHLIGHTGLOSSSHADER,
  327.                     c4d.VRAYMATERIAL_SPECULAR5_ANISOTROPYSHADER,
  328.                     c4d.VRAYMATERIAL_SPECULAR5_ANISOTROPYROTSHADER],
  329.                     "value": "Specular5"},
  330.  
  331.                 {"link_id": [
  332.                     c4d.VRAYMATERIAL_FLAKES_COLORSHADER,
  333.                     c4d.VRAYMATERIAL_FLAKES_GLOSSINESSSHADER,
  334.                     c4d.VRAYMATERIAL_FLAKES_ORIENTATIONSHADER],
  335.                     "value": "Flakes"},
  336.  
  337.                 {"link_id": [
  338.                     c4d.VRAYMATERIAL_LUMINANCE_SHADER,
  339.                     c4d.VRAYMATERIAL_LUMINANCE_TRANSPSHADER],
  340.                     "value": "Luminance"},
  341.  
  342.                 {"link_id": [
  343.                     c4d.VRAYMATERIAL_BUMP_SHADER],
  344.                     "value": "Bump"},
  345.  
  346.                 {"link_id": [
  347.                     c4d.VRAYMATERIAL_MATTE_OPSHADER,
  348.                     c4d.VRAYMATERIAL_MATTE_ALPHASHADER,
  349.                     c4d.VRAYMATERIAL_WEIGHT_SHADER],
  350.                     "value": "Matte"}
  351.             ]
  352.  
  353.             #Vray 1.9
  354.             try:
  355.                 data.append(
  356.                      {"link_id": [
  357.                         c4d.VRAYMATERIAL_TRANSPARENCY_SHADER,
  358.                         c4d.VRAYMATERIAL_TRANSPARENCY_GLOSSINESSSHADER,
  359.                         c4d.VRAYMATERIAL_VOLUME_COLORTEX,
  360.                         c4d.VRAYMATERIAL_COLOR1_SSSBACKSHADER],
  361.                         "value": "Refraction"}
  362.                 )
  363.                 data.append(
  364.                     {"link_id": [
  365.                         c4d.VRAYMATERIAL_TRANSP_SHADER],
  366.                         "value": "Transparency"}
  367.                 )
  368.             except:
  369.                 pass
  370.  
  371.             #Vray 3.4
  372.             try:
  373.                 data.append(
  374.                     {"link_id": [
  375.                         c4d.VRAYMATERIAL_REFRACT_SHADER,
  376.                         c4d.VRAYMATERIAL_REFRACT_IORTEX,
  377.                         c4d.VRAYMATERIAL_REFRACT_GLOSSINESSSHADER,
  378.                         c4d.VRAYMATERIAL_VOLUME_COLORTEX,
  379.                         c4d.VRAYMATERIAL_COLOR1_SSSBACKSHADER],
  380.                         "value": "Refraction"})
  381.             except:
  382.                 pass
  383.  
  384.         elif mat.CheckType(1022593):
  385.             text = "VrayDisplace::"
  386.             data = [
  387.                 {"link_id": [
  388.                     c4d.VRAYDISPLACEMATERIAL_TEXTURE],
  389.                     "value": "Displace"}
  390.             ]
  391.  
  392.         elif mat.CheckType(c4d.Mmaterial):
  393.             text = "c4dMat::"
  394.             data = [
  395.                 {"link_id": [
  396.                     c4d.MATERIAL_COLOR_SHADER],
  397.                     "value": "Color"},
  398.  
  399.                 {"link_id": [
  400.                     c4d.MATERIAL_DIFFUSION_SHADER],
  401.                     "value": "Diffusion"},
  402.  
  403.                 {"link_id": [
  404.                     c4d.MATERIAL_LUMINANCE_SHADER],
  405.                     "value": "Luminance"},
  406.  
  407.                 {"link_id": [
  408.                     c4d.MATERIAL_TRANSPARENCY_SHADER],
  409.                     "value": "Transparency"},
  410.  
  411.                 {"link_id": [
  412.                     c4d.REFLECTION_LAYER_COLOR_TEXTURE,
  413.                     c4d.REFLECTION_LAYER_TRANS_TEXTURE],
  414.                     "value": "Reflexion"},
  415.  
  416.                 {"link_id": [
  417.                     c4d.MATERIAL_ENVIRONMENT_SHADER],
  418.                     "value": "Environment"},
  419.  
  420.                 {"link_id": [
  421.                     c4d.MATERIAL_BUMP_SHADER],
  422.                     "value": "Bump"},
  423.  
  424.                 {"link_id": [
  425.                     c4d.MATERIAL_NORMAL_SHADER],
  426.                     "value": "Normal"},
  427.  
  428.                 {"link_id": [
  429.                     c4d.MATERIAL_ALPHA_SHADER],
  430.                     "value": "Alpha"},
  431.  
  432.                 {"link_id": [
  433.                     c4d.MATERIAL_DISPLACEMENT_SHADER],
  434.                     "value": "Displace"}
  435.             ]
  436.  
  437.         leave = False
  438.         for x in data:
  439.             for link in x["link_id"]:
  440.                 if mat[link]:
  441.                     list_linked = self.__get_linked_shader(mat[link])
  442.                     if not parent_shader.IsAlive():
  443.                         continue
  444.                     if parent_shader in list_linked or parent_shader == mat[link]:
  445.                         text += str(x["value"])
  446.                         leave = True
  447.                         break
  448.             if leave:
  449.                 break
  450.  
  451.         return text
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement