# -*- coding: UTF-8 -*-
from ngSkinTools2 import api, cleanup, signal
from ngSkinTools2.api import VertexTransferMode
from ngSkinTools2.api.pyside import QtCore, QtWidgets
from ngSkinTools2.api.session import session
from ngSkinTools2.api.transfer import LayersTransfer
from ngSkinTools2.decorators import undoable
from ngSkinTools2.ui import influenceMappingUI, qt, widgets
from ngSkinTools2.ui.layout import createTitledRow, scale_multiplier
class UiModel:
def __init__(self):
self.transfer = LayersTransfer()
def destination_has_layers(self):
l = api.Layers(self.transfer.target)
return l.is_enabled() and len(l.list()) > 0
@undoable
def do_apply(self):
self.transfer.complete_execution()
from maya import cmds
cmds.select(self.transfer.target)
if session.active():
session.events.targetChanged.emitIfChanged()
single_transfer_dialog_policy = qt.SingleWindowPolicy()
def open(parent, model):
"""
:type model: UiModel
"""
def buttonRow(window):
def apply():
model.do_apply()
session.events.layerListChanged.emitIfChanged()
window.close()
return widgets.button_row(
[
("传递", apply),
("取消", window.close),
]
)
def view_influences_settings():
tabs.setCurrentIndex(1)
def build_settings():
result = QtWidgets.QVBoxLayout()
vertexMappingMode = QtWidgets.QComboBox()
vertexMappingMode.addItem("表面上最近的点", VertexTransferMode.closestPoint)
vertexMappingMode.addItem("UV空间", VertexTransferMode.uvSpace)
vertexMappingMode.addItem("按顶点ID(源和目标顶点数必须匹配)", VertexTransferMode.vertexId)
g = QtWidgets.QGroupBox("选择")
layout = QtWidgets.QVBoxLayout()
g.setLayout(layout)
sourceLabel = QtWidgets.QLabel()
layout.addLayout(createTitledRow("来源:", sourceLabel))
destinationLabel = QtWidgets.QLabel()
layout.addLayout(createTitledRow("目标:", destinationLabel))
result.addWidget(g)
g = QtWidgets.QGroupBox("顶点映射")
layout = QtWidgets.QVBoxLayout()
layout.addLayout(createTitledRow("映射模式:", vertexMappingMode))
g.setLayout(layout)
result.addWidget(g)
g = QtWidgets.QGroupBox("影响物映射")
layout = QtWidgets.QVBoxLayout()
g.setLayout(layout)
edit = QtWidgets.QPushButton("配置")
qt.on(edit.clicked)(view_influences_settings)
button_row = QtWidgets.QHBoxLayout()
button_row.addWidget(edit)
button_row.addStretch()
layout.addLayout(button_row)
result.addWidget(g)
g = QtWidgets.QGroupBox("其他选项")
layout = QtWidgets.QVBoxLayout()
g.setLayout(layout)
keep_layers = QtWidgets.QCheckBox("保留目标网格的已有图层")
keep_layers_row = qt.wrap_layout_into_widget(createTitledRow("目标图层:", keep_layers))
layout.addWidget(keep_layers_row)
@qt.on(keep_layers.stateChanged)
def checked():
model.transfer.keep_existing_layers = keep_layers.isChecked()
result.addWidget(g)
result.addStretch()
def update_settings_to_model():
keep_layers.setChecked(model.transfer.keep_existing_layers)
qt.select_data(vertexMappingMode, model.transfer.vertex_transfer_mode)
source_title = model.transfer.source
if model.transfer.source_file is not None:
source_title = 'file ' + model.transfer.source_file
sourceLabel.setText("" + source_title + "")
destinationLabel.setText("" + model.transfer.target + "")
keep_layers_row.setEnabled(model.destination_has_layers())
@qt.on(vertexMappingMode.currentIndexChanged)
def vertex_mapping_mode_changed():
model.transfer.vertex_transfer_mode = vertexMappingMode.currentData()
update_settings_to_model()
return result
def build_influenes_tab():
infl_ui, _, recalcMatches = influenceMappingUI.build_ui(parent, model.transfer.influences_mapping)
padding = QtWidgets.QVBoxLayout()
padding.setContentsMargins(0, 20 * scale_multiplier, 0, 0)
padding.addWidget(infl_ui)
recalcMatches()
return padding
tabs = QtWidgets.QTabWidget()
tabs.addTab(qt.wrap_layout_into_widget(build_settings()), "设置")
tabs.addTab(qt.wrap_layout_into_widget(build_influenes_tab()), "影响物映射")
window = QtWidgets.QDialog(parent)
cleanup.registerCleanupHandler(window.close)
window.setWindowTitle("传递")
window.setAttribute(QtCore.Qt.WA_DeleteOnClose)
window.resize(720 * scale_multiplier, 500 * scale_multiplier)
window.setLayout(QtWidgets.QVBoxLayout())
window.layout().addWidget(tabs)
window.layout().addLayout(buttonRow(window))
if session.active():
session.addQtWidgetReference(window)
single_transfer_dialog_policy.setCurrent(window)
window.show()
def build_transfer_action(session, parent):
from maya import cmds
from .actions import define_action
targets = []
def detect_targets():
targets[:] = []
selection = cmds.ls(sl=True)
if len(selection) != 2:
return False
if not api.Layers(selection[0]).is_enabled():
return False
targets[:] = selection
return True
def transfer_dialog(transfer):
"""
:type transfer: LayersTransfer
"""
model = UiModel()
model.transfer = transfer
open(parent, model)
def handler():
if not targets:
return
t = LayersTransfer()
t.source = targets[0]
t.target = targets[1]
t.customize_callback = transfer_dialog
t.execute()
result = define_action(parent, "传递图层...", callback=handler)
@signal.on(session.events.nodeSelectionChanged)
def on_selection_changed():
result.setEnabled(detect_targets())
on_selection_changed()
return result