This commit is contained in:
2025-04-17 04:52:48 +08:00
commit 9985b73dc1
3708 changed files with 2387532 additions and 0 deletions

View File

@ -0,0 +1,68 @@
# Copyright Epic Games, Inc. All Rights Reserved.
from epic_pose_wrangler.v2.model import base_action
class ExportSelectedAction(base_action.BaseAction):
__display_name__ = "Export Selected Solvers"
__tooltip__ = "Exports the currently selected solver nodes in the scene to a JSON file"
__category__ = "IO"
@classmethod
def validate(cls, ui_context):
return bool(ui_context.current_solvers)
def execute(self, ui_context=None, **kwargs):
from Qt import QtWidgets
if not ui_context:
ui_context = self.api.get_ui_context()
if not ui_context:
return
file_path = QtWidgets.QFileDialog.getSaveFileName(None, "Pose Wrangler File", "", "*.json")[0]
# If no path is specified, exit early
if file_path == "":
return
self.api.serialize_to_file(file_path, ui_context.current_solvers)
class ExportAllAction(base_action.BaseAction):
__display_name__ = "Export All Solvers"
__tooltip__ = "Exports all solver nodes in the scene to a JSON file"
__category__ = "IO"
@classmethod
def validate(cls, ui_context):
return bool(ui_context.current_solvers)
def execute(self, ui_context=None, **kwargs):
from Qt import QtWidgets
if not ui_context:
ui_context = self.api.get_ui_context()
if not ui_context:
return
file_path = QtWidgets.QFileDialog.getSaveFileName(None, "Pose Wrangler File", "", "*.json")[0]
# If no path is specified, exit early
if file_path == "":
return
self.api.serialize_to_file(file_path, None)
class ImportFromFileAction(base_action.BaseAction):
__display_name__ = "Import Solvers"
__tooltip__ = "Imports solver nodes into the scene from a JSON file"
__category__ = "IO"
@classmethod
def validate(cls, ui_context):
return bool(ui_context.current_solvers)
def execute(self, ui_context=None, **kwargs):
from Qt import QtWidgets
if not ui_context:
ui_context = self.api.get_ui_context()
if not ui_context:
return
file_path = QtWidgets.QFileDialog.getOpenFileName(None, "Pose Wrangler File", "", "*.json")[0]
# If no path is specified, exit early
if file_path == "":
return
self.api.deserialize_from_file(file_path)

View File

@ -0,0 +1,52 @@
# Copyright Epic Games, Inc. All Rights Reserved.
from maya import cmds
from epic_pose_wrangler.v2.model import base_action
class SelectSolverAction(base_action.BaseAction):
__display_name__ = "Select Solver Node(s)"
__tooltip__ = "Selects the currently selected solver nodes in the scene"
__category__ = "Select"
@classmethod
def validate(cls, ui_context):
return bool(ui_context.current_solvers)
def execute(self, ui_context=None, **kwargs):
if not ui_context:
ui_context = self.api.get_ui_context()
if not ui_context:
return
cmds.select(ui_context.current_solvers, replace=True)
class SelectDriverAction(base_action.BaseAction):
__display_name__ = "Select Driver Node(s)"
__tooltip__ = "Selects the driver nodes in the scene"
__category__ = "Select"
@classmethod
def validate(cls, ui_context):
return bool(ui_context.drivers)
def execute(self, ui_context=None, **kwargs):
if not ui_context:
ui_context = self.api.get_ui_context()
if not ui_context:
return
cmds.select(ui_context.drivers, replace=True)
class SelectDrivenAction(base_action.BaseAction):
__display_name__ = "Select Driven Node(s)"
__tooltip__ = "Selects the driven nodes in the scene"
__category__ = "Select"
@classmethod
def validate(cls, ui_context):
return bool(ui_context.driven)
def execute(self, ui_context=None, **kwargs):
if not ui_context:
ui_context = self.api.get_ui_context()
if not ui_context:
return
cmds.select(ui_context.driven, replace=True)

View File

@ -0,0 +1,41 @@
# Copyright Epic Games, Inc. All Rights Reserved.
from maya import cmds
from epic_pose_wrangler.v2.model import base_action, pose_blender
class ZeroDefaultPoseAction(base_action.BaseAction):
__display_name__ = "Zero Default Pose Transforms"
__tooltip__ = ""
__category__ = "Utilities"
@classmethod
def validate(cls, ui_context):
return bool(ui_context.current_solvers)
def execute(self, ui_context=None, solver=None, **kwargs):
from Qt import QtWidgets
if not ui_context:
ui_context = self.api.get_ui_context()
if ui_context:
solver = self.api.get_rbf_solver_by_name(ui_context.current_solvers[-1])
if not solver:
solver = self.api.current_solver
# Go to the default pose
solver.go_to_pose('default')
# Assume edit is enabled
edit = True
if not self.api.get_solver_edit_status(solver):
# If edit isn't enabled, store the current enabled state and enable editing
edit = False
self.api.edit_solver(edit=True, solver=solver)
# Reset the driven transforms
for node in solver.driven_nodes(type=pose_blender.UEPoseBlenderNode.node_type):
cmds.setAttr('{node}.translate'.format(node=node), 0.0, 0.0, 0.0)
cmds.setAttr('{node}.rotate'.format(node=node), 0.0, 0.0, 0.0)
cmds.setAttr('{node}.scale'.format(node=node), 1.0, 1.0, 1.0)
# Update the pose
self.api.update_pose(pose_name='default', solver=solver)
# Restore edit status
self.api.edit_solver(edit=edit, solver=solver)