# -*- 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