Skip to content

Commit

Permalink
Add alias import/export, minor fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
sowwic committed Jul 12, 2020
1 parent ff46a4a commit 376c323
Show file tree
Hide file tree
Showing 7 changed files with 137 additions and 19 deletions.
22 changes: 21 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,36 @@
# dsRenamingTool
Simple renaming tool
![Renaming](docs/images/renamingAction.gif)

## Key features:
- Optional prefix, suffix fields
- Auto indexing
- Auto suffixing
- Customizable object type suffix aliases
- import/export aliases

## Instalation
A) **Module approach** <br>
1) Place repo folder anywhere on your PC <br>
2) In your documents/maya/modules directory create "dsRenamingTool.mod" file with the following code:
```
+ dsRenamingTool 1.0 YourPathHere/dsRenamingTool
scripts: YourPathHere/dsRenamingTool
```

B) **Normal scripts approach**<br>
1) Copy dsRenamingTool folder with py in it (not main repo) to your documents/maya/scripts directory

## Usage
A) Run mainDialog.py<br>
B) Import dsRenamingTool, dsRenamingTool.Dialog.display()

## Dialogs
**Main dialog**:

![Preview](docs/images/mainDialog.png)



**Alias editor**:

![Suffix aliases editor](docs/images/aliasesDialog.png)
Binary file modified docs/images/aliasesDialog.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/renamingAction.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
67 changes: 56 additions & 11 deletions dsRenamingTool/aliasesDialog.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
import pymel.core as pm
import logging
import json
from PySide2 import QtWidgets, QtCore
from dsRenamingTool import dialogBase


LOGGER = logging.getLogger(__name__)


class AliasDialog(dialogBase._modalDialog):

DEFAULT_SUFFIX_ALIASES = {
"transform": "GRP",
"joint": "JNT",
"mesh": "PLY",
"nurbsCurve": "CRV",
"nurbsSurface": "NURB",
Expand All @@ -18,27 +23,38 @@ class AliasDialog(dialogBase._modalDialog):
"camera": "CAM",
}

@classmethod
def checkOptionVar(cls):
pm.optionVar.get("dsRenamingToolSuffixAliases", json.dumps(cls.DEFAULT_SUFFIX_ALIASES, sort_keys=True))

def __init__(self, parent=None, title="Edit aliases"):
super(AliasDialog, self).__init__(parent=parent)

# Setup UI
self.setWindowTitle(title)
self.setMinimumSize(300, 200)
self.setMinimumSize(300, 400)

# Update table
self.updateAliasTable()

def createActions(self):
# Menubar
self.menuBar = QtWidgets.QMenuBar(self)
fileMenu = self.menuBar.addMenu("&File")
editMenu = self.menuBar.addMenu("&Edit")

# Actions
self.exportAliasesAction = QtWidgets.QAction("Export aliases", self)
self.importAliasesAction = QtWidgets.QAction("Import aliases", self)
self.addAliasesAction = QtWidgets.QAction("Add new alias", self)
self.deleteAliasAction = QtWidgets.QAction("Delete selected", self)
self.resetAliasesAction = QtWidgets.QAction("Reset to defaults", self)

# Populate menubar
# File menu
fileMenu.addAction(self.exportAliasesAction)
fileMenu.addAction(self.importAliasesAction)
# Edit menu
editMenu.addAction(self.addAliasesAction)
editMenu.addAction(self.deleteAliasAction)
editMenu.addAction(self.resetAliasesAction)
Expand All @@ -53,7 +69,6 @@ def createWidgets(self):

# Dialog buttons
self.confirmButton = QtWidgets.QPushButton("Confirm")
self.saveButton = QtWidgets.QPushButton("Save")
self.cancelButton = QtWidgets.QPushButton("Cancel")

def createLayouts(self):
Expand All @@ -68,7 +83,6 @@ def createLayouts(self):
buttonsLayout = QtWidgets.QHBoxLayout()
buttonsLayout.addStretch()
buttonsLayout.addWidget(self.confirmButton)
buttonsLayout.addWidget(self.saveButton)
buttonsLayout.addWidget(self.cancelButton)

# Populate main
Expand All @@ -78,10 +92,13 @@ def createLayouts(self):
def createConnections(self):
# Buttons
self.confirmButton.clicked.connect(self.confirmAndClose)
self.saveButton.clicked.connect(self.saveAliases)
self.cancelButton.clicked.connect(self.close)

# Actions
# MenuBar
# File menu
self.exportAliasesAction.triggered.connect(self.exportAliases)
self.importAliasesAction.triggered.connect(self.importAliases)

self.addAliasesAction.triggered.connect(self.aliasesTable.addNewEntry)
self.deleteAliasAction.triggered.connect(self.aliasesTable.deleteSelectedRow)
self.resetAliasesAction.triggered.connect(self.resetToDefault)
Expand Down Expand Up @@ -123,15 +140,43 @@ def showEvent(self, e):
self.checkOptionVar()

def resetToDefault(self):
self.loadFromDict(self.DEFAULT_SUFFIX_ALIASES)

def loadFromDict(self, aliasDict):
self.aliasesTable.setRowCount(0)
for i, k in enumerate(self.DEFAULT_SUFFIX_ALIASES.keys()):
for i, k in enumerate(aliasDict.keys()):
self.aliasesTable.insertRow(i)
self.insertItem(i, 0, text=k)
self.insertItem(i, 1, text=self.DEFAULT_SUFFIX_ALIASES[k])

@classmethod
def checkOptionVar(cls):
pm.optionVar.get("dsRenamingToolSuffixAliases", json.dumps(cls.DEFAULT_SUFFIX_ALIASES, sort_keys=True))
self.insertItem(i, 1, text=aliasDict[k])

def exportAliases(self):
exportPath = QtWidgets.QFileDialog.getSaveFileName(self, "Export aliases", "/home/namingAliases.json", "JSON files (*.json)")[0]
if not exportPath:
return

try:
with open(exportPath, "w") as exportFile:
json.dump(self.getAliasTableData(), exportFile, indent=4, separators=(",", ":"))
LOGGER.info("Exported aliases to: {0}".format(exportPath))
except IOError:
LOGGER.error("Failed to export aliases", exc_info=1)

def importAliases(self):
importPath = QtWidgets.QFileDialog.getOpenFileName(self, "Import aliases", "/home/", "JSON files (*.json)")[0]
if not importPath:
return

with open(importPath, "r") as importFile:
importedData = json.load(importFile)
if not importedData:
LOGGER.error("No aliases found in {0}".format(importPath))
return

try:
self.loadFromDict(importedData)
LOGGER.info("Succesfully loaded aliases from {0}".format(importPath))
except Exception:
LOGGER.error("Failed to load aliases from {0}".format(importPath), exc_info=1)


class AliasTable(QtWidgets.QTableWidget):
Expand Down
40 changes: 40 additions & 0 deletions dsRenamingTool/config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@

LOGGING_CONFIG = {
"version": 1,
"disable_existing_loggers": False,
"formatters": {
"brief": {
"class": "logging.Formatter",
"datefmt": "%d-%m-%Y %I:%M:%S",
"format": "// %(name)s %(asctime)s %(levelname)s| %(message)s //"
},

"detailed": {
"class": "logging.Formatter",
"datefmt": "%d-%m-%Y %I:%M:%S",
"format": " %(message)s Call: %(name)s.%(funcName)s;"
}
},
"handlers": {
"console":{
"level": "DEBUG",
"class": "logging.StreamHandler",
"formatter": "brief",
"stream" : "ext://sys.stdout"
},

"file_handler": {
"level": "DEBUG",
"class": "logging.FileHandler",
"formatter": "detailed",
"filename": "",
"mode": "a",
"encoding": "utf-8"
}
},
"loggers": { },
"root": {
"handlers": ["console", "file_handler"],
"level": "DEBUG"
}
}
10 changes: 10 additions & 0 deletions dsRenamingTool/mainDialog.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,21 @@
import pymel.core as pm
import pymel.api as pma
import logging
import logging.config
import json
from PySide2 import QtWidgets

from dsRenamingTool import renameFn
from dsRenamingTool import aliasesDialog
from dsRenamingTool import config
from maya.app.general.mayaMixin import MayaQWidgetDockableMixin
from shiboken2 import getCppPointer


# Setup logging
LOGGER = logging.getLogger(__name__)


class Dialog(MayaQWidgetDockableMixin, QtWidgets.QWidget):

WINDOW_TITLE = "dsRenaming Tool"
Expand Down Expand Up @@ -138,9 +145,11 @@ def createConnections(self):
def rename(self):
sel = pm.ls(sl=1, r=1)
tempList = []
aliasesDict = json.loads(pm.optionVar.get("dsRenamingToolSuffixAliases", json.dumps(aliasesDialog.AliasDialog.DEFAULT_SUFFIX_ALIASES, sort_keys=True)))
for each in sel:
tempList.append(renameFn.RenameUtils.rename(each,
"tempName",
aliasesDict,
prefix="NULL",
suffix="NULL",
autoSuffix=False,
Expand All @@ -150,6 +159,7 @@ def rename(self):
for each in tempList:
renameFn.RenameUtils.rename(each,
self.baseNameLineEdit.text(),
aliasesDict,
prefix=self.prefixLineEdit.text(),
suffix=self.suffixLineEdit.text(),
autoSuffix=self.autoSuffixCheckBox.isChecked(),
Expand Down
17 changes: 10 additions & 7 deletions dsRenamingTool/renameFn.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
import pymel.core as pm
import json
import logging

LOGGER = logging.getLogger(__name__)


class RenameUtils:

@classmethod
def rename(cls, obj, newName, prefix=None, suffix=None, autoSuffix=False, indexing=True, indexPadding=1, startIndex=0):
def rename(cls, obj, newName, aliasesDict, prefix=None, suffix=None, autoSuffix=False, indexing=True, indexPadding=1, startIndex=0):
if not newName:
pm.warning("No name was specified")
LOGGER.warning("No name was specified")
return

if prefix:
Expand All @@ -16,7 +19,7 @@ def rename(cls, obj, newName, prefix=None, suffix=None, autoSuffix=False, indexi
baseName = newName

if autoSuffix:
suffix = cls.getSuffix(obj)
suffix = cls.getSuffix(obj, aliasesDict)

fullName = cls.genName(obj, baseName, suffix, padding=indexPadding + 1, start=startIndex, indexing=indexing)
pm.rename(obj, fullName)
Expand Down Expand Up @@ -52,18 +55,18 @@ def genName(cls, obj, name, suffix=None, indexing=True, padding=2, start=0):
return testName

@classmethod
def getSuffix(cls, obj):
def getSuffix(cls, obj, aliasesDict):
objType = pm.objectType(obj)
objectSuffixes = json.loads(pm.optionVar["dsRiggingRenamingToolSuffixAliases"])
aliasesDict = json.loads(pm.optionVar["dsRenamingToolSuffixAliases"])
if objType == "transform":
dependNodes = pm.listRelatives(obj, c=1)
if dependNodes:
objType = pm.objectType(dependNodes[0])

try:
suffix = objectSuffixes[objType]
suffix = aliasesDict[objType]
except KeyError:
pm.warning("No suffix recorded for type: {0}.\nUpdate aliases using suffix alias editor.".format(objType))
LOGGER.warning("No suffix recorded for type: {0}.\nUpdate aliases using suffix alias editor.".format(objType))
suffix = "OBJ"

return suffix

0 comments on commit 376c323

Please sign in to comment.