Compare commits

...

3 Commits

Author SHA1 Message Date
359cb4292d Update README.md 2025-01-15 04:03:12 +08:00
127f67de73 Update 2025-01-15 03:37:57 +08:00
685ecd1980 Update README.md 2025-01-15 03:36:07 +08:00
4 changed files with 385 additions and 51 deletions

169
BuildBodyFree.py Normal file
View File

@ -0,0 +1,169 @@
#All Rights Belongs to Uzay CALISKAN
#Artstation Marketplace Standart License
import os
import maya.cmds as cmds
def fixbody():
#
#
# Transfer Body original skeleton to the new head Skeleton
CD = 15
lower_CD = -1
minCD = 0
# Define the joint names and namespaces
head_joint = "DHIhead:spine_04"
body_joint = "spine_04_drv"
# Split the joint names into their respective namespaces and joint names
head_namespace, head_joint_name = head_joint.split(":")
# Get the list of child joints for the head joint
head_child_joints = cmds.listRelatives(head_joint, children=True, allDescendents=True,type="joint")
body_child_joints = cmds.listRelatives(body_joint, children=True, allDescendents=True, type="joint")
def move2target_joint(moving_joint, target_joint):
lower_lip_rotation_pos = cmds.xform(moving_joint, query=True, worldSpace=True, rotatePivot=True)
jaw_pos = cmds.xform(target_joint, query=True, worldSpace=True, rotatePivot=True)
# Get the child joints
child_joints = cmds.listRelatives(moving_joint, c=True, type="joint")
# Store the initial positions of the child joints
child_positions = []
if child_joints:
for child_joint in child_joints:
child_positions.append(cmds.xform(child_joint, q=True, ws=True, t=True))
# Set the translate and rotate pivot attributes of the "FACIAL_C_LowerLipRotation" joint to match those of "FACIAL_C_MouthUpper"
cmds.xform(moving_joint, translation=jaw_pos, rotatePivot=lower_lip_rotation_pos, worldSpace=True)
if child_joints:
# Move each child joint back to its original position
for i, child_joint in enumerate(child_joints):
cmds.xform(child_joint, ws=True, t=child_positions[i])
moving_joint = body_joint
target_joint = head_joint
move2target_joint(moving_joint, target_joint)
while CD >= minCD:
joint_CD = [joint for joint in body_child_joints if cmds.getAttr(joint + ".chainDepth") == CD]
for joint_name in joint_CD:
drvname = joint_name.replace("_drv", "")
# Build the joint names for the current joint
head_current_joint = "{}:{}".format(head_namespace, drvname)
if cmds.objExists(head_current_joint):
if joint_name[-5] == "r":
offnamer = joint_name.replace("_r_drv", "Off_r_drv")
if cmds.objExists(offnamer):
joint_name = offnamer
if joint_name[-5] == "l":
offnamel = joint_name.replace("_l_drv", "Off_l_drv")
if cmds.objExists(offnamel):
joint_name = offnamel
moving_joint = joint_name
target_joint = head_current_joint
move2target_joint(moving_joint, target_joint)
lower_CD -= 1
CD -= 1
def bind_skin(gender_mesh):
# Body
mesh_obj = cmds.ls(gender_mesh)[0]
# Duplicate the mesh
duplicated_mesh_obj = cmds.duplicate(mesh_obj)[0]
cmds.select([duplicated_mesh_obj, "DHIbody:root"])
# Bind skin to the mesh
skin_cluster = cmds.skinCluster("DHIbody:root", duplicated_mesh_obj)[0]
cmds.select([mesh_obj, duplicated_mesh_obj])
cmds.copySkinWeights(noMirror=True, surfaceAssociation="closestPoint", influenceAssociation=["name", "oneToOne"])
cmds.delete(mesh_obj)
cmds.rename(duplicated_mesh_obj, gender_mesh)
gender=0
gender_mesh = "m_med_nrw_body_lod0_mesh"
def build_body(ROOT_DIR):
Body_DRV = f"{ROOT_DIR}/data/Body_Drv.mb"
if not os.path.isfile(Body_DRV):
raise ValueError("Please prepare the body file first. Body_Drv file is not found")
skeleton_file_path = f"{ROOT_DIR}/data/Body_Drv.mb"
# Import the FBX file
cmds.file(skeleton_file_path, i=True, ignoreVersion=True, mergeNamespacesOnClash=False)
def add_chain_depth_attribute(joints):
for joint in joints:
if not cmds.attributeQuery('chainDepth', node=joint, exists=True):
cmds.addAttr(joint, longName='chainDepth', attributeType='long', defaultValue=0)
cmds.setAttr(joint + '.chainDepth', keyable=True)
def set_chain_depth_value(joints, value):
for joint in joints:
cmds.setAttr(joint + '.chainDepth', value)
# Get all joints in the scene
all_joints = cmds.ls(type="joint")
# Remove joints in the "DHIhead:spine_04" hierarchy (Avoid HEAD)
exclude_joints = cmds.ls("DHIhead:spine_04", dag=True, type="joint")
all_joints = cmds.ls("root_drv", dag=True, type="joint")
add_chain_depth_attribute(all_joints)
# Filter end joints (joints with no child joints)
end_joints = [joint for joint in all_joints if not cmds.listRelatives(joint, children=True, type='joint')]
# Set chainDepth attribute to 0 for all end joints
set_chain_depth_value(all_joints, 100)
set_chain_depth_value(end_joints, 0)
parents1 = []
for joint_name in end_joints:
p_joint = cmds.listRelatives(joint_name, parent=True, type="joint")
if p_joint:
children = cmds.listRelatives(p_joint, children=True, type="joint") or []
if all(cmds.getAttr(child + ".chainDepth") == 0 for child in children):
parents1.append(p_joint[0])
set_chain_depth_value(parents1, 1)
#Chaindepth add Attr Loop
chainDepth = 1
while parents1:
chainDepth += 1
new_parents = []
for joint_name in parents1:
p_joint = cmds.listRelatives(joint_name, parent=True, type="joint")
if p_joint:
children = cmds.listRelatives(p_joint, children=True, type="joint") or []
if all(cmds.getAttr(child + ".chainDepth") < chainDepth for child in children):
new_parents.append(p_joint[0])
if new_parents:
set_chain_depth_value(new_parents, chainDepth)
parents1 = new_parents
else:
break
DHIBODY_name = 'DHIbody:root'
bind_skin(gender_mesh)
def connect_body():
bodyNS = "DHIbody:"
headNS = "DHIhead:"
for i in cmds.ls(type="joint"):
if headNS in i:
if i.replace(headNS,bodyNS) in cmds.ls(type="joint"):
cmds.parentConstraint(i.replace(headNS,bodyNS),i,mo=True)
cmds.scaleConstraint(i.replace(headNS,bodyNS),i,mo=True)
#build_body()

BIN
MetaPipe.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 MiB

174
MetaPipeFree.py Normal file
View File

@ -0,0 +1,174 @@
import maya.cmds as cmds
import os
import os.path as ospathe
from os import environ
from sys import path as syspath
from sys import platform
import sys
import logging
import maya.OpenMaya as om
from maya import cmds
from os import environ, makedirs
from os import path as ospath
import BuildBodyFree
import dna_viewer
maya_version = int(cmds.about(version=True))
if maya_version == 2023:
if sys.version_info < (3, 9, 7):
raise ValueError("Python 3.9.7 or above is required. Please download correct Python Version!")
if maya_version == 2022:
if sys.version_info < (3, 7, 0):
raise ValueError("Python 3.9.7 or above is required. Please download correct Python Version!")
auto_keyframe_toggle = cmds.autoKeyframe(q=True, state=True)
if auto_keyframe_toggle:
raise ValueError("Auto Keyframe Toggle is On! Turn it of and try again.")
def OpenDNA(ROOT_DIR):
calib_check = f"{ROOT_DIR}/dna_calibration.mod"
if not os.path.isfile(calib_check):
raise ValueError("Please download Epic Games Dna Calibration 1.1.0 Version. Files not found!")
metapipe_vcheck = f"{ROOT_DIR}/Metapipe_Free.py"
if os.path.isfile(metapipe_vcheck):
raise ValueError("Old Version file found. Please delete Metapipe_Free.py file in your dna_calibration path!")
root_check = f"{ROOT_DIR}/examples/dna_viewer_grab_changes_from_scene_and_propagate_to_dna.py"
if not os.path.isfile(root_check):
raise ValueError("Please check ROOT_DIR path for the dna_calibration files! Files are not in ROOT_DIR")
dna_datas = f"{ROOT_DIR}/examples/datas_dna.py"
if not os.path.isfile(dna_datas):
raise ValueError("Please press Update button first")
import dna_viewer_run_in_maya
dna_viewer_run_in_maya.dna_viewer.show()
def codeblock (dnaPath, ROOT_DIR, CHARACTER_NAME):
output_file_path = os.path.join(f"{ROOT_DIR}/examples", "datas_dna.py")
# Open the Python file and read the lines
with open(f"{ROOT_DIR}/examples/dna_viewer_grab_changes_from_scene_and_propagate_to_dna.py") as file:
lines_all = file.readlines()
lines = lines_all[43:204]
lineslists = lines_all[211:214]
linesload = lines_all[214:220]
lines2 = lines_all[226:242]
defload = ["def load_dna_data():\n"]
defsave = ["def save_dna_data():\n"]
lines = [line.replace('f"{ospath.dirname(ospath.abspath(__file__))}/..".replace("\\\\", "/")','"'+ROOT_DIR+'"') for line in lines]
lines = [line.replace('f"{DNA_DIR}/{CHARACTER_NAME}.dna"', '"'+dnaPath+'"') for line in lines]
lines = [line.replace('"Ada"','"'+CHARACTER_NAME+'"') for line in lines]
linesload = [" " + line for line in linesload]
lines2 = [" " + line for line in lines2]
code_block = ''.join(lines + lineslists + defload + linesload + defsave + lines2)
with open(output_file_path, "w") as output_file:
output_file.write(code_block)
dnaCalibPath=ROOT_DIR
def update_dna_dir(text_dna, ROOT_DIR):
character_dna = cmds.textField(text_dna, q=True, text=True)
CHARACTER_DNA = ospathe.abspath(character_dna)
CHARACTER_DNA = CHARACTER_DNA.replace("\\", "/")
CHARACTER_NAME = os.path.basename(CHARACTER_DNA).split(".")[0]
print(f"New DNA_DIR: {CHARACTER_DNA}")
print(f"New DNA_Name: {CHARACTER_NAME}")
codeblock (CHARACTER_DNA, ROOT_DIR, CHARACTER_NAME)
return CHARACTER_DNA, CHARACTER_NAME
# Create a function that will be called when the button is clicked
def button_callback(text_field, *args):
path = cmds.textField(text_field, query=True, text=True)
run_dna_viewer(path, text_field)
cmds.scriptEditorInfo(suppressWarnings=True, echoAllCommands=False)
def prepare_export():
# Detach spine_04 from head_grp and move it to the top level of the Outliner
cmds.parent('spine_04', w=True, r=True)
if not cmds.namespace(exists="DHIhead"):
cmds.namespace(add="DHIhead", parent=":")
cmds.namespace(set="DHIhead")
cmds.namespace(set=":")
# Get a list of all the joints in the scene
joints = cmds.ls(type="joint")
# Add every joint to the "DHIhead" namespace and print a message if it already has the "DHIhead" prefix
for joint in joints:
if joint.startswith("DHIhead:"):
print(joint + " is already in the DHIhead namespace")
else:
cmds.rename(joint, "DHIhead:" + joint)
print("Ready")
def loadimport(ROOT_DIR):
dna_datas = f"{ROOT_DIR}/examples/datas_dna.py"
if not os.path.isfile(dna_datas):
raise ValueError("Please press Update button first")
sys.path.append(f"{ROOT_DIR}/examples")
import datas_dna
datas_dna.load_dna_data()
cmds.warning("Loaded Succesfully!")
def saveimport(ROOT_DIR):
sys.path.append(f"{ROOT_DIR}/examples")
import datas_dna
datas_dna.save_dna_data()
dnaPath=""
dnaCalibPath=""
def show_dna_edit_window(dnaPath, ROOT_DIR):
# Create window
window_name = "MetaPipe"
if cmds.window(window_name, exists=True):
cmds.deleteUI(window_name)
cmds.window(window_name, title=window_name, width=300, height=380, sizeable=False, resizeToFitChildren=True)
# Create layout
color = (0.164, 0.384, 0) # RGB values for #0077c2
colorbuttons = (.2, 0.2, 0.2) # RGB values for #0077c2
layout = cmds.rowColumnLayout(numberOfColumns=1, columnWidth=[(1, 150)], columnSpacing=[(1,75)], backgroundColor=(0.1, 0.1, 0.1))
cmds.text(label="", height=15)
cmds.text(label="METAPIPE DNA CALIB UI 1.3.0", height=20, font="boldLabelFont")
cmds.text(label="(Free Edition)", height=20, font="boldLabelFont")
cmds.text(label="", height=15)
cmds.text(label="Metahuman DNA:",height=20)
text_dna = cmds.textField(text=dnaPath)
cmds.text(label="", height=5)
cmds.button(label="Update", command=lambda x: update_dna_dir(text_dna, ROOT_DIR), backgroundColor=color, height=20)
cmds.text(label="", height=20)
cmds.button(label="Open DNA Viewer", command=lambda x: dna_viewer.show(), backgroundColor=colorbuttons, height=40)
cmds.text(label="", height=5)
cmds.button(label="Load Dna", command=lambda x: loadimport(ROOT_DIR), backgroundColor=colorbuttons, height=40)
cmds.text(label="", height=5)
cmds.button(label="Save Dna", command=lambda x: saveimport(ROOT_DIR), backgroundColor=colorbuttons, height=40)
cmds.text(label="", height=5)
cmds.button(label="Prepare to Export", command=lambda x: prepare_export(), backgroundColor=colorbuttons, height=40)
cmds.text(label="", height=5)
cmds.button(label="Load Body", command=lambda x: BuildBodyFree.build_body(ROOT_DIR), backgroundColor=colorbuttons, height=40)
cmds.text(label="", height=5)
cmds.button(label="Fix Body", command=lambda x: BuildBodyFree.fixbody(), backgroundColor=colorbuttons, height=40)
cmds.text(label="", height=5)
cmds.button(label="Connect Body", command=lambda x: BuildBodyFree.connect_body(), backgroundColor=colorbuttons, height=40)
cmds.text(label="", height=5)
#cmds.image(image='C:/Arts and Spells/pps.png', w=64, h=64)
cmds.text(label="ARTS AND SPELLS",height=40, font="boldLabelFont")
# Show window
cmds.showWindow()
# Show window
#show_dna_edit_window(dnaPath)

View File

@ -1,61 +1,52 @@
#### 1 如果你有之前的版本,请将文件移至其他位置
### 1 - 从 "github.com/EpicGames/MetaHuman-DNA-Calibration" 下载 Epic Game's DNA Calibration "版本" 1.1.0
#### 2 现在 Maya 2022 和 2023 使用相同的 DNA Calibration
### 2 - 将文件路径设置为 C:\dna_calibration (推荐) 或其他位置。请记住该路径。
安装 DNA_Calibration 1.1.0 (https://github.com/EpicGames/MetaHuman-DNA-Calibration/archive/refs/tags/1.1.0.zip) 将文件解压到 C 盘并将主文件夹重命名为 dna_calibration。
#### 3 进入下载的文件夹并在文本框中输入"cmd"。控制面板将会弹出
输入 "python metapipe.py"
或者如果上述方法不起作用,可以选择其他解决方案
- 复制所有 python 文件并粘贴到 "c:/Arts and Spells/Scripts" (推荐)。
- 打开 "MetaPipeStudioSource.py" 并修改以下版本信息
* ROOT_DIR
* MAYA_VERSION
* dnaPath
* body_type
- 修改完成后将文件另存为 "dat.py" 并保存在 "c:/Arts and Spells/Scripts" 中
#### 4 - 复制插件
前往此路径 "Documents\Megascans Library\support\plugins\maya\7.0\MSLiveLink\DHI\plugins\Windows\2023" (7.0 是当前 MSLiveLink 版本,可能会变更) 并复制 embeddedRL4.mll 文件
#### 5 - 在 "Documents/Megascans Library/support/plugins/maya/7.0/MSLiveLink/" 中创建名为 "plug-ins" 的文件夹,并将文件粘贴其中。
#### 6 - 按照教程使用
#### 7 - 如果你有任何问题,欢迎在 Discord 或 Artstation 上询问!祝使用愉快!
身体构建自动代码:
### 3 - 复制所有 python 文件并粘贴到 "c:/Arts and Spells/Scripts" (推荐)。
### 4 - 将以下代码复制粘贴到架构编辑器命令行或通过脚本编辑器运行(选择 Python 选项卡)
```
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import importlib
import sys
import maya.cmds as cmds
import os
from os import path as ospath
from sys import path as syspath
from sys import platform
sys.path.append("c:/Arts and Spells/Scripts")
import Body_Prep
Body_Prep.run()
ROOT_DIR = "G:/DNA_Calibration_1.1.0"
MAIN_PATH = "C:/Arts and Spells/Metapipe Free 1.3.0"
MAYA_VERSION = "2023"
ROOT_LIB_DIR = f"{ROOT_DIR}/lib/Maya{MAYA_VERSION}"
if platform == "win32":
LIB_DIR = f"{ROOT_LIB_DIR}/windows"
elif platform == "linux":
LIB_DIR = f"{ROOT_LIB_DIR}/linux"
else:
raise OSError(
"不支持操作系统,请编译依赖项并为 LIB_DIR"
)
# Adds directories to path
syspath.insert(0, ROOT_DIR)
syspath.insert(0, LIB_DIR)
sys.path.append(MAIN_PATH)
import MetaPipeFree
importlib.reload(MetaPipeFree)
# Dna Path
dnaPath = "G:/DNA_Calibration_1.1.0/data/dna_files/Ada.dna"
CHARACTER_NAME = os.path.basename(dnaPath).split(".")[0]
MetaPipeFree.codeblock(dnaPath, ROOT_DIR, CHARACTER_NAME)
MetaPipeFree.show_dna_edit_window(dnaPath, ROOT_DIR)
```
#### Metapipe 架构编辑器代码:
```
import sys
sys.path.append("c:/Arts and Spells/Scripts")
import MetaPipeStudio
MetaPipeStudio.show_dna_edit_window()
```
修正混合变形安装:
* 1 - 复制 extractDerltas.py 并粘贴到 Maya 插件文件夹 --> documents/maya/"""2023/2022"""/plug-ins
* 2 - 复制 correctiveBlendshape.txt 文件中的文本并粘贴到 Maya 架构编辑器的 "MEL SCRIPT TAB" 中
* 3 - 在 Maya 中启用 extractDeltas 插件 - Windows - Settings and Preferences - Plugin Manager
* 4 - 将 bsIndex.py 文件复制粘贴到 C:/Arts and Spells/Scripts (推荐) 或修改架构编辑器中的 correctiveBlendshape 代码并设置你的路径。
### 5 - 前往路径 "G:\BridgeLibrary\support\plugins\maya\7.0\MSLiveLink\DHI\plugins\Windows\2023" (7.0 是当前 MSLiveLink 版本,可能会变更) 并复制 embeddedRL4.mll 文件
### 6 - 在 "Documents/Megascans Library/support/plugins/maya/7.0/MSLiveLink/" 中创建名为 "plug-ins" 的文件夹,并将文件粘贴其中。
### 7 - 运行代码!祝使用愉快!如有任何问题,请在 Artstation 或 Discord 上询问...