Python Tools - Session 14A

Mini Exporter Tool

2020.04.14 - Session 14A

Session Navigation

Overview

The Mini Exporter tool demonstrates file export workflows in Maya. It creates collision meshes by duplicating and reducing all scene meshes with a "UCX_" prefix, then exports everything to a user-specified path. The tool features a file browser dialog, path persistence using Maya's optionVar system, and a slider for controlling polygon reduction percentage.

Key Concepts

  • File export - Use pm.exportAll to export entire scenes to a target path
  • Collision mesh generation - Duplicate meshes with "UCX_" prefix and reduce polygon count
  • File browser dialogs - Use pm.fileDialog2 to let users pick export paths
  • optionVar persistence - Store and retrieve user preferences across Maya sessions
  • Transform listing - Use pm.listTransforms(type='mesh') to find all mesh objects
Note

This session uses a companion mini_exporter.ui file created in Qt Designer for the path input, browse button, reduction slider, and export button.

Source Code - mini_exporter.py

"""
#############################################################################
filename    mini_exporter.py
author      [author]
course      [course]
Brief Description:
    Covering exporting a file
    To be used in conjunction with "mini_exporter.ui" - place them next to each other
    Session 14A - Apr 14 2020
#############################################################################
"""

import pymel.core as pm
import os

from PySide2 import QtCore
from PySide2 import QtWidgets
from PySide2 import QtUiTools

from shiboken2 import wrapInstance

import maya.OpenMayaUI as omui

OV_PREVIOUS_PATH = "MINIEXPORTER_PREVIOUS_PATH"

def get_maya_window():
    """Return the main Maya window
    """
    main_window_ptr = omui.MQtUtil.mainWindow()
    return wrapInstance(long(main_window_ptr), QtWidgets.QWidget)

def get_script_dir():
    """Returns the directory where the current script lives
    """
    script_file = os.path.abspath(__file__)
    return os.path.dirname(script_file)

class MiniExporterUI(QtWidgets.QDialog):

    def __init__(self, parent=get_maya_window()):
        super(MiniExporterUI, self).__init__(parent)

        self.setWindowTitle('Mini Exporter')

        ui_file_path = os.path.join(get_script_dir(), 'mini_exporter.ui')

        qfile_object = QtCore.QFile(ui_file_path)
        qfile_object.open(QtCore.QFile.ReadOnly)

        loader = QtUiTools.QUiLoader()
        self.ui = loader.load(qfile_object, parentWidget=self)

        self.ui.btnBrowse.clicked.connect(self.browse)
        self.ui.btnExport.clicked.connect(self.export)

        qfile_object.close()
        self.show()

        previous_path = pm.optionVar.get(OV_PREVIOUS_PATH, "")
        self.ui.linePath.setText(previous_path)

    def export(self):
        # Find all meshes in the scene
        all_meshes = pm.listTransforms(type='mesh')

        for each_mesh in all_meshes:
            # Duplicate each one with collision prefix
            new_name = 'UCX_' + each_mesh.name() + '_collision'
            dupe = pm.duplicate(each_mesh, name=new_name)[0]
            # Reduce it
            reduction = self.ui.sldReduction.value()
            pm.polyReduce(dupe, percentage=reduction)

        # Export everything to the target file
        target_file = self.ui.linePath.text()
        print ('Exporting to %s' %target_file)
        pm.exportAll(target_file, force=True)

    def browse(self):
        results = pm.fileDialog2(fileMode=0)
        if results is None:
            return

        self.ui.linePath.setText(results[0])
        pm.optionVar[OV_PREVIOUS_PATH] = results[0]

def run():
    """Checks to see if the UI exists, and closes it
    """
    for ui_item in QtWidgets.qApp.allWidgets():
        if type(ui_item).__name__ == 'MiniExporterUI':
            ui_item.close()
    MiniExporterUI()
← Prev Next ->