Skip to main content

list_materials_in_a_scene_3DS_max

ss

import pymxs
import logging
import json

rt = pymxs.runtime
logging.basicConfig(level=logging.WARNING, format='%(asctime)s - %(levelname)s - %(message)s')

vray_sss_param = ['scale', 'IOR', 'overall_color', 'sub_surface_color','scatter_color',
'scatter_radius', 'phase_function', 'specular_amount', 'specular_glossiness',
'texmap_bump', 'texmap_bump_multiplier',
'texmap_specular_amount', 'texmap_specular_amount_multiplier',
'texmap_sss_color', 'texmap_sss_color_multiplier',
'texmap_scatter_color']

vray_mtl_param = ['reflection_glossiness', 'reflection_ior',
'texmap_diffuse', 'texmap_diffuse_multiplier', 'texmap_bump', 'texmap_bump_multiplier', 'Diffuse', 'Reflection', 'texmap_opacity']

standard_mtl_param = ['ior', 'bumpMap', 'bumpMapAmount', 'diffuseMap', 'diffuseMapAmount', 'opacityMap', 'Diffuse', 'Specular']

vray_alsurface_mtl_param = ['displacement_texture', 'diffuse_color_texture', 'diffuse_color', 'sss_mix', 'opacity_texture', 'opacity', 'diffuse_bump', 'refl1_strength', 'bump_texture', 'diffuse_strength', 'sss_mix', 'reflect1_ior', 'reflect1_roughness', 'reflect1_roughness_texture']

physical_mat_param = ['base_color', 'base_color_map', 'roughness', 'Roughness_Map', 'transparency', 'transparency_map', 'trans_ior', 'bump_map', 'bump_map_amt']

texmap = ['texmap_bump', 'texmap_sss_color', 'texmap_diffuse', 'texmap_bump', 'bumpMap']


def list_objects_with_material(material_name):
rt = pymxs.runtime

# Get the material by name
material = None
for m in rt.sceneMaterials:
if m.name == material_name:
material = m
break

if material is None:
#print(f"Material '{material_name}' not found in the scene.")
return []

# List all objects with the specified material
objects_with_material = []
for obj in rt.geometry:
if obj.material == material:
objects_with_material.append(obj.name)

return objects_with_material


def list_all_materials():
rt = pymxs.runtime

# List to store all unique materials
all_materials = set()

# Function to recursively collect materials from a material tree
def collect_materials(material):
if not material:
return
if material not in all_materials:
#all_materials.add(material)
# Check for sub-materials if it's a Multi/Sub-Object material
if rt.isKindOf(material, rt.MultiSubMaterial):
#print (material)
for mat in material.materialList:
if mat == None:
continue
all_materials.add(mat)
# print (mat, type(mat))

#print ("=======")
#print (material.name)
#print (material.name)
# for i in range(1, material.numsubs + 1):
# sub_material = material[i]
# if sub_material:
# collect_materials(sub_material)
# Check for other types of sub-materials
elif rt.isKindOf(material, rt.Material):
all_materials.add(material)

#print (material, rt.classOf(material).__str__())

#print (material.name)
# for i in range(material.numSubs):
# sub_material = material.getSubMtl(i + 1)
# if sub_material:
# collect_materials(sub_material)
else:
print ("what is this?", material)

# Iterate through all nodes in the scene and collect materials
for node in rt.objects:
if hasattr(node, "material") and node.material:
collect_materials(node.material)

#Print all unique materials
# for material in all_materials:
# print(material.name)

return all_materials

# Run the function
mat_list = list_all_materials()
mat_conversion = {}
#print (mat_list)


for mat in mat_list:

mat_param = {}

if mat is None:
continue

mat_name = mat.name
# if mat_name != "Parotid":
# continue

# prop_list = rt.getPropNames(mat)
# for p in prop_list:
# print (p, getattr(mat, p.__str__()))

mat_type = rt.classOf(mat).__str__()
logging.debug(f"Material type: {mat_type}")

if mat_type == "VRayFastSSS2":
param_list = vray_sss_param

elif mat_type == "VRayMtl":
param_list = vray_mtl_param

elif mat_type == "Standard" or mat_type == "Standardmaterial":
param_list = standard_mtl_param

elif mat_type == "VRayALSurfaceMtl":
param_list = vray_alsurface_mtl_param

elif mat_type == "PhysicalMaterial":
param_list = physical_mat_param

else:
logging.warning(f"Material: {mat_name} | Type: {mat_type} configuration not found")
continue

# m = getattr(mat, 'texmap_specular_amount')
# print ((m.filename))

obj_assigned = list_objects_with_material(mat_name)
# logging.debug(f"Objects assigned: {obj_assigned}")

for param in param_list:
# if param != "diffuse_bump":
# continue


value = getattr(mat, param)
logging.debug(f"{mat_name} --- {param} --- {value}")

#print (value, rt.classOf(value).__str__())

#print (rt.classOf(value))
#print (rt.classOf(value).__str__())
#print (rt.getPropNames(value))
#print (value.GetTileTextures(1))
#print (value.getTileTexmap(1).filename )
#print (str(value.filename))
#print (dir(value))
#print (rt.getPropNames(value))

#print (rt.classOf(value).__str__())

#print (param, rt.classOf(value).__str__())
if rt.classOf(value).__str__() == "Bitmaptexture":
mat_param[param] = str(value.filename)

elif rt.classOf(value).__str__() == "MultiTile":
#print (str(value.getTileTexmap(1).filename))
#print ("weee")
#print ()

#print (len(str(value.getTileTexmap(2).filename)))
tex_map_1 = str(value.getTileTexmap(1).filename)

if len(tex_map_1) > 3:
mat_param[param] = tex_map_1
else:
mat_param[param] = str(value.getTileTexmap(2).filename)

#print (mat_param[param])

elif rt.classOf(value).__str__() == "VRayNormalMap":

connected_node = value.normal_map


if rt.classOf(connected_node).__str__() == "Bitmaptexture":
mat_param[param] = str(connected_node.filename)

if rt.classOf(connected_node).__str__() == "MultiTile":
#mat_param[param] = str(connected_node.getTileTexmap(1).filename)

ex_map_1 = str(connected_node.getTileTexmap(1).filename)

if len(tex_map_1) > 3:
mat_param[param] = tex_map_1
else:
mat_param[param] = str(connected_node.getTileTexmap(2).filename)


# print (mat)
# print (value.normal_map.filename)

#print ("=====")
#print (str(value.getTileTexmap(1).filename))

#print (value)
#mat_param[param] = str(value.HDRIMapName)

'''
prop_list = rt.getPropNames(value)
for prop in prop_list:
#print (type(value), type(prop.__str__()))
number = getattr(value, prop.__str__())
print (prop, number)

value.normal_map.filename
'''

elif rt.classOf(value).__str__() == "VRayBitmap":
#print (str(value.getTileTexmap(1).filename))

mat_param[param] = str(value.HDRIMapName)
#print (str(value.HDRIMapName))

# prop_list = rt.getPropNames(value)
# for prop in prop_list:
# #print (type(value), type(prop.__str__()))
# number = getattr(value, prop.__str__())
# print (prop, number)

# HDRIMapName
#print (prop, prop.value)
# prop_value = rt.getUserProp(value, prop)
# print (prop, prop_value)


#break
#mat_param[param] = str(value.getTileTexmap(1).filename)
#print (mat_param[param])

# elif rt.classOf(value).__str__() == "VRayTriplanarTex":
# #print (str(value.getTileTexmap(1).filename))
# mat_param[param] = str(value.getTileTexmap(1).filename)
# #print (mat_param[param])

elif rt.classOf(value).__str__() == "VRayColor":
mat_param[param] = [value.red, value.blue, value.green]

elif rt.classOf(value).__str__() == "falloff":
mat_param[param] = [value.color1.red, value.color1.green, value.color1.blue]

else:
if "color" in str(value).lower():
data = str(value).strip("(").strip(")").split(" ")
data = data[1:] # remove the color string
data_tuple = tuple(data) # convert list to tuple
mat_param[param] = data_tuple
elif "Map #" in str(value):
mat_param[param] = None
else:
mat_param[param] = str(value)

# Changed from material centric to object centric
mat_conversion.update(
{mat_name: {"mat_type": mat_type,
"mat_param": mat_param,
"objs_assigned": obj_assigned
}
}
)



print (mat_conversion)
with open("C:/Users/BT/Desktop/TEMP_female_material_20240604c.json", "w") as write_file:
json.dump(mat_conversion, write_file, indent=4)

print ("Export success")