MetaFusion/Reference/MSLiveLink/DHI/core/util.py
2025-02-03 22:58:41 +08:00

229 lines
8.3 KiB
Python

import os
import maya.mel as mel
from maya import cmds
from DHI.core.maya.adapter import AdditionalAdapterBuilder
class MayaUtil:
ATTRIBUTE_NAMES = ["tx", "ty", "tz", "rx", "ry", "rz", "sx", "sy", "sz"]
@staticmethod
def create_workspace(maya_project_path):
if os.path.exists(maya_project_path):
cmd = 'setProject "' + maya_project_path + '";'
mel.eval(cmd)
@staticmethod
def delete_history(mesh_names):
for meshName in mesh_names:
if cmds.objExists(meshName):
cmds.select(clear=True)
cmds.select(meshName)
mel.eval('doBakeNonDefHistory( 1, {"prePost" });')
@staticmethod
def import_shader(shader_scene_path, mesh_shader_mapping):
print("Shader scene imported")
cmds.file(shader_scene_path, options="v=0", type="mayaAscii", i=True)
try:
items = mesh_shader_mapping.iteritems()
except:
items = mesh_shader_mapping.items()
for meshName, shaderName in items:
for lodLvl in range(0, 8):
try:
# Apply shader to all meshes based on LOD level
resolved_mesh_name = meshName + str(lodLvl) + "_mesh"
shader = "shader_" + shaderName
cmds.select(resolved_mesh_name, replace=True)
mel.eval("sets -e -forceElement " + shader + "SG")
except:
print("Skipped adding shader for mesh %s." % meshName)
@staticmethod
def set_map_textures(map_infos, folder_name):
for mapInfo in map_infos:
node_name = "mapFile_" + mapInfo[0]
if mapInfo[1]:
node_name = "baseMapFile_" + mapInfo[0]
if not cmds.objExists(node_name):
continue
file_texture_name = cmds.getAttr(node_name + ".fileTextureName")
texture_folder_name, texture_file_name = os.path.split(file_texture_name)
texture_folder_name = folder_name
cmds.setAttr(
node_name + ".fileTextureName",
texture_folder_name + "/" + texture_file_name,
type="string",
)
@staticmethod
def set_mask_textures(masks, folder_name):
for mask in masks:
node_name = "maskFile_" + mask
if not cmds.objExists(node_name):
continue
file_texture_name = cmds.getAttr(node_name + ".fileTextureName")
texture_folder_name, texture_file_name = os.path.split(file_texture_name)
texture_folder_name = folder_name
cmds.setAttr(
node_name + ".fileTextureName",
texture_folder_name + "/" + texture_file_name,
type="string",
)
@staticmethod
def resolve_scene_shader_paths(shaders, folder_name):
for shader in shaders:
node_name = "shader_" + shader
if not cmds.objExists(node_name):
continue
file_shader_name = cmds.getAttr(node_name + ".shader")
shader_folder_name, shader_file_name = os.path.split(file_shader_name)
shader_folder_name = folder_name
cmds.setAttr(
node_name + ".shader",
shader_folder_name + "/" + shader_file_name,
type="string",
)
@staticmethod
def create_lights(lights_file_path, orient):
print("Creating lights...")
cmds.file(lights_file_path, defaultNamespace=True, i=True)
# Set viewport 2.0 properties needed:
model_panel_list = []
model_editor_list = cmds.lsUI(editors=True)
for my_model_panel in model_editor_list:
if my_model_panel.find("modelPanel") != -1:
model_panel_list.append(my_model_panel)
try:
for modelPanel in model_panel_list:
cmds.modelEditor(modelPanel=modelPanel, lights=True, displayAppearance='smoothShaded',
nurbsCurves=True, joints=False, nurbsSurfaces=True, polymeshes=True,
textures=True, dl="all", useDefaultMaterial=False, backfaceCulling=False,
displayTextures=True, grid=False)
except:
print("An error has occured importing lights scene!.\n")
cmds.xform("Lights", ro=orient)
cmds.makeIdentity("Lights", apply=True)
@staticmethod
def save_maya_scene(file_path, file_type="mayaAscii"):
print(f"Saving maya scene to {file_path}.")
cmds.file(rename=file_path)
cmds.file(save=True, type=file_type)
@staticmethod
def load_plugin(name, path, platform, forced_extension=None):
"""
Loads plugin for given name.
@param name: Plugin name. (string)
@param path: Path to plugin. (string)
@param platform: OS platform. (string)
@param forced_extension: Forced extension. (string)
"""
print(f"Loading plugin {name}.")
is_loaded = False
extension = ".so" if platform == "Linux" else ".mll"
if forced_extension:
extension = forced_extension
if not (cmds.pluginInfo(name, query=True, loaded=True)):
try:
print(f"Loading plugin: {path} / {name}{extension}")
cmds.loadPlugin(path + "/" + name + extension)
is_loaded = True
except:
print(f"Error loading plugin {name}")
pass
else:
print(f"Plugin {name} already loaded")
is_loaded = True
return is_loaded
@staticmethod
def connect_attributes_to_shader(shader_attributes_mapping):
print("Connecting attributes to shader...")
try:
items = shader_attributes_mapping.iteritems()
except Exception as ex:
print(f"Error: {ex}")
items = shader_attributes_mapping.items()
for frm_attribute, shaderAttribute in items:
if cmds.objExists(frm_attribute) and cmds.objExists(shaderAttribute):
cmds.connectAttr(frm_attribute, shaderAttribute, force=True)
@staticmethod
def get_objects(name, type=None, root=False):
"""
Gets scene objects by name and type.
@param name: Object name. (string)
@param type: Object type. (string)
@param root: Indicates if object is root object. (boolean)
@return List of object node instances. (DagNode[])
"""
obj_name = "|" + name if root else name
obj_nodes = []
if type:
obj_nodes = cmds.ls(obj_name, type=type)
else:
obj_nodes = cmds.ls(obj_name)
return obj_nodes
@staticmethod
def remove_geometry_from_dna(dna_file_path):
import dna
try:
file_stream = dna.FileStream(
str(dna_file_path),
dna.FileStream.AccessMode_Read,
dna.FileStream.OpenMode_Binary,
)
reader = dna.StreamReader(file_stream, dna.DataLayer_Behavior)
reader.read()
stream = dna.FileStream(
str(dna_file_path),
dna.FileStream.AccessMode_Write,
dna.FileStream.OpenMode_Binary,
)
writer = dna.StreamWriter(stream)
writer.setFrom(reader)
writer.write()
except Exception as ex:
print(ex)
@staticmethod
def _adapt_meshes(scale, scale_pivot, orient, mesh_names, translate):
mesh_adapter = AdditionalAdapterBuilder.buildMeshAA(scale, scale_pivot, orient, translate)
for mesh_name in mesh_names:
try:
for attr_name in MayaUtil.ATTRIBUTE_NAMES:
cmds.setAttr(mesh_name + "." + attr_name, lock=0)
mesh_adapter.adapt(mesh_name)
for attr_name in MayaUtil.ATTRIBUTE_NAMES:
cmds.setAttr(mesh_name + "." + attr_name, lock=1)
cmds.select(mesh_name, replace=True)
mel.eval('doBakeNonDefHistory( 1, {"pre" });')
cmds.polySoftEdge(mesh_name, a=180, ch=False)
except Exception as ex:
print(ex)
print("Mesh %s adaptation skipped." % mesh_name)
cmds.select(clear=True)