Skip to content

Commit

Permalink
release <- dev (2.2.0)
Browse files Browse the repository at this point in the history
release <- dev (2.2.0)
  • Loading branch information
TrevisanGMW authored Jul 24, 2022
2 parents 2a08ce9 + aaf72fb commit 5b1afd2
Show file tree
Hide file tree
Showing 12 changed files with 1,595 additions and 844 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ In case you need/want to manually install the scripts. It's also a pretty straig
<ul>
<li><b>How do I update GT Tools to a new version?</b> <br>A: Simply uninstall and install it again.</li>
<li><b>What do I do if I have multiple "userSetup.mel" files?</b> One inside "maya/####/scripts" and another one inside "maya/scripts"<br>A: The "userSetup.mel" file gets executed when you open Maya, but Maya supports only one file. In case you have two files it will give priority to the file located inside "maya/####/scripts", so manage your initialization commands there.</li>
<li><b>Where are the other scripts you had in this repository?</b> <br> A: I moved all other scripts that are not part of GT Tools to another reposity. Here is the link: <a href="https://github.com/TrevisanGMW/maya-scripts">TrevisanGMW/maya-scripts</a> </li>
<li><b>Where are the other scripts you had in this repository?</b> <br> A: I moved all other scripts that are not part of GT Tools to another repository. Here is the link: <a href="https://github.com/TrevisanGMW/maya-scripts">TrevisanGMW/maya-scripts</a> </li>
</ul>

<h1> Contributors </h1>
Expand Down
19 changes: 17 additions & 2 deletions mel-scripts/gt_tools_menu.mel
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,10 @@
// 2.1.0 - 2022-07-19
// Added Render Calculator
//
// 2.2.0 - 2022-07-19
// Added "Attributes to Python"
// Added "Morphing Attributes"
//
//----------------------------------------------------------------------------

// Globals
Expand Down Expand Up @@ -253,13 +257,18 @@ menuItem -l "Tools" -sm true -to true -image "toolSettings.png";
-ann ("Script for getting and setting translate and rotate world space data.")
-image "buttonManip.svg" ;

menuItem
-l ("Attributes to Python")
-c ("python(\"gt_tools.execute_script('gt_attributes_to_python', 'build_gui_attr_to_python')\");")
-ann ("Converts attributes into Python code. TRS Channels or User-defined.")
-image "attributes.png" ;

menuItem
-l ("Render Checklist")
-c ("python(\"gt_tools.execute_script('gt_render_checklist', 'build_gui_gt_render_checklist')\");")
-ann ("Performs a series of checks to detect common issues that are often accidently ignored/unnoticed.")
-image "checkboxOn.png" ;


setParent -menu ".." ;


Expand Down Expand Up @@ -396,6 +405,12 @@ menuItem -l "Rigging" -sm true -to true -image "kinReroot.png";
-ann ("Automated solution for connecting multiple attributes.")
-image "hsRearrange.png";

menuItem
-l ("Morphing Attributes")
-c ("python(\"gt_tools.execute_script('gt_morphing_attributes', 'build_gui_morphing_attributes')\");")
-ann ("Creates attributes to drive selected blend shapes.")
-image "blendShape.png";

menuItem
-l ("Mirror Cluster Tool")
-c ("python(\"gt_tools.execute_script('gt_mirror_cluster_tool', 'build_gui_mirror_cluster_tool')\");")
Expand Down Expand Up @@ -428,7 +443,7 @@ menuItem -l "Rigging" -sm true -to true -image "kinReroot.png";

menuItem
-l ("Add Sine Attributes")
-c ("python(\"gt_tools.execute_script('gt_add_sine_attributes', 'build_gui_add_sine_attr')\");")
-c ("python(\"gt_tools.execute_script('gt_sine_attributes', 'build_gui_add_sine_attr')\");")
-ann ("Create Sine function without using third-party plugins or expressions.")
-image "sineCurveProfile.png" ;

Expand Down
2 changes: 1 addition & 1 deletion python-scripts/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import os

# Global Vars
PACKAGE_VERSION = "2.1.3"
PACKAGE_VERSION = "2.2.0"

# Initial Setup - Add path and initialize logger
if __name__ != '__main__':
Expand Down
262 changes: 256 additions & 6 deletions python-scripts/gt_attributes_to_python.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,22 +9,52 @@
Added option to strip zeroes
Added auto conversion of "-0"s into "0"s for clarity
Todo:
Create GUI
Add Logger
0.0.4 - 2022-07-22
Added GUI
Added logger
0.0.5 - 2022-07-22
Increased the size of the UI
Added "Extract User-Defined Attributes" function
TODO:
Add options
"""
from maya import OpenMayaUI as OpenMayaUI
import maya.cmds as cmds
import logging
import sys

try:
from shiboken2 import wrapInstance
except ImportError:
from shiboken import wrapInstance

try:
from PySide2.QtGui import QIcon
from PySide2.QtWidgets import QWidget
except ImportError:
from PySide.QtGui import QIcon, QWidget

# Logging Setup
logging.basicConfig()
logger = logging.getLogger("gt_shape_extract_state")
logger.setLevel(logging.INFO)

# Script Name
script_name = 'GT Attributes to Python'

# Version:
script_version = "0.0.3"
script_version = "0.0.5"

DIMENSIONS = ['x', 'y', 'z']
DEFAULT_CHANNELS = ['t', 'r', 's']

# if __name__ == '__main__':
# # default_attr_to_python(None, use_loop=True)
# attr_to_list(None, separate_channels=False)


def attr_to_list(obj_list, printing=True, decimal_place=2, separate_channels=False, strip_zeroes=True):
"""
Expand Down Expand Up @@ -156,6 +186,226 @@ def default_attr_to_python(obj_list, printing=True, use_loop=False, decimal_plac
return output


def user_attr_to_python(obj_list, printing=True, decimal_place=2, strip_zeroes=True):
"""
Returns a string
Args:
obj_list (list, none): List objects to extract the transform from (if empty, it will try to use selection)
printing (optional, bool): If active, the function will print the values to the script editor
decimal_place (optional, int): How precise you want the extracted values to be (formats the float it gets)
strip_zeroes (optional, bool): If active, it will remove unnecessary zeroes (e.g. 0.0 -> 0)
Returns:
Python code with extracted transform values
"""
if not obj_list:
obj_list = cmds.ls(selection=True)
if not obj_list:
return

output = ''
if printing:
output += ('#' * 80)

for obj in obj_list:
output += '\n# User-Defined Attribute Data for "' + obj + '":\n'
data = {}
attributes = cmds.listAttr(obj, userDefined=True) or []
if not attributes:
output += '# No user-defined attributes found on this object.\n'
else:
for attr in attributes: # TRS
# not cmds.getAttr(obj + '.' + attr, lock=True) # TODO Check if locked
attr_type = cmds.getAttr(obj + '.' + attr, typ=True)
value = cmds.getAttr(obj + '.' + attr)
if attr_type == 'double3':
pass
elif attr_type == 'string':
output += 'cmds.setAttr("' + obj + '.' + attr + '", "' + str(value) + '", typ="string")\n'
else:
output += 'cmds.setAttr("' + obj + '.' + attr + '", ' + str(value) + ')\n'

# Return / Print
if printing:
output += ('#' * 80)
if output.replace('#', ''):
print(output)
return output
else:
print('No data found. Make sure your selection at least one object with user-defined attributes.')
return None
else:
return output


# Function for the "Run Code" button
def run_output_code(out):
try:
exec(out)
except Exception as e:
cmds.warning("Something is wrong with your code!")
cmds.warning(e)


# Main Form ============================================================================
def build_gui_attr_to_python():
window_name = "build_gui_attr_to_python"
if cmds.window(window_name, exists=True):
cmds.deleteUI(window_name)

# Main GUI Start Here =================================================================================
window_gui_attr_to_python = cmds.window(window_name, title=script_name + ' (v' + script_version + ')',
titleBar=True, mnb=False, mxb=False, sizeable=True)

cmds.window(window_name, e=True, s=True, wh=[1, 1])

content_main = cmds.columnLayout(adj=True)

# Title
title_bgc_color = (.4, .4, .4)
cmds.separator(h=10, style='none') # Empty Space
cmds.rowColumnLayout(nc=1, cw=[(1, 500)], cs=[(1, 10)], p=content_main) # Window Size Adjustment
cmds.rowColumnLayout(nc=3, cw=[(1, 10), (2, 430), (3, 50)], cs=[(1, 10), (2, 0), (3, 0)],
p=content_main) # Title Column
cmds.text(" ", bgc=title_bgc_color) # Tiny Empty Green Space
cmds.text(script_name, bgc=title_bgc_color, fn="boldLabelFont", align="left")
cmds.button(l="Help", bgc=title_bgc_color, c=lambda x: build_gui_help_attr_to_python())
cmds.separator(h=10, style='none', p=content_main) # Empty Space

# Body ====================
cmds.rowColumnLayout(nc=1, cw=[(1, 500)], cs=[(1, 10)], p=content_main)

default_attr_button_cw = 243
cmds.rowColumnLayout(nc=2, cw=[(1, default_attr_button_cw), (2, default_attr_button_cw)],
cs=[(1, 10), (2, 5)], p=content_main)

cmds.button(l="Extract Default Attributes to \"setAttr\"", bgc=(.6, .6, .6),
c=lambda x: _btn_extract_attr(attr_type='default'))
cmds.button(l="Extract Default Attributes to List", bgc=(.6, .6, .6),
c=lambda x: _btn_extract_attr(attr_type='list'))
cmds.separator(h=5, style='none') # Empty Space
cmds.rowColumnLayout(nc=1, cw=[(1, 490)], cs=[(1, 10)], p=content_main)
cmds.button(l="Extract User-Defined Attributes", bgc=(.6, .6, .6),
c=lambda x: _btn_extract_attr(attr_type='user'))
cmds.separator(h=10, style='none') # Empty Space
cmds.separator(h=10, style='none', p=content_main) # Empty Space
cmds.separator(h=10, p=content_main)

# Bottom ====================
cmds.rowColumnLayout(nc=1, cw=[(1, 490)], cs=[(1, 10)], p=content_main)
cmds.text(label='Output Python Code')
output_python = cmds.scrollField(editable=True, wordWrap=True, height=200)
cmds.separator(h=10, style='none') # Empty Space
cmds.button(l="Run Code", c=lambda x: run_output_code(cmds.scrollField(output_python, query=True, text=True)))
cmds.separator(h=10, style='none') # Empty Space

def _btn_extract_attr(attr_type='default'):
selection = cmds.ls(selection=True) or []

if len(selection) == 0:
cmds.warning('Make sure you selected at least one object and try again.')
return

if attr_type == 'list':
output_python_command = attr_to_list(selection, printing=False, decimal_place=2,
separate_channels=False, strip_zeroes=True)
elif attr_type == 'user':
output_python_command = user_attr_to_python(selection, printing=False,
decimal_place=2, strip_zeroes=True)
else:
output_python_command = default_attr_to_python(selection, printing=False, use_loop=False,
decimal_place=2, strip_zeroes=True)
if len(output_python_command) == 0:
cmds.warning('Make sure you selected at least one object and try again.')
return

if output_python_command.startswith('\n'):
output_python_command = output_python_command[1:]

print(output_python_command)
if len(selection) == 1:
sys.stdout.write('Attributes for "' + str(selection[0] + '" extracted. '
'(Output to Script Editor and GUI)'))
else:
sys.stdout.write('Attributes extracted for ' + str(len(selection)) + ' objects. '
'(Output to Script Editor and GUI)')
cmds.scrollField(output_python, e=True, ip=1, it='') # Bring Back to the Top
cmds.scrollField(output_python, edit=True, wordWrap=True, text='', sl=True)
cmds.scrollField(output_python, edit=True, wordWrap=True, text=output_python_command, sl=True)
cmds.setFocus(output_python)

# Show and Lock Window
cmds.showWindow(window_gui_attr_to_python)
cmds.window(window_name, e=True, s=False)

# Set Window Icon
qw = OpenMayaUI.MQtUtil.findWindow(window_name)
widget = wrapInstance(int(qw), QWidget)
icon = QIcon(':/attributes.png')
widget.setWindowIcon(icon)

# Main GUI Ends Here =================================================================================


# Creates Help GUI
def build_gui_help_attr_to_python():
window_name = "build_gui_help_attr_to_python"
if cmds.window(window_name, exists=True):
cmds.deleteUI(window_name, window=True)

cmds.window(window_name, title=script_name + " Help", mnb=False, mxb=False, s=True)
cmds.window(window_name, e=True, s=True, wh=[1, 1])

cmds.columnLayout("main_column", p=window_name)

# Title Text
cmds.separator(h=12, style='none') # Empty Space
cmds.rowColumnLayout(nc=1, cw=[(1, 310)], cs=[(1, 10)], p="main_column") # Window Size Adjustment
cmds.rowColumnLayout(nc=1, cw=[(1, 300)], cs=[(1, 10)], p="main_column") # Title Column
cmds.text(script_name + " Help", bgc=[.4, .4, .4], fn="boldLabelFont", align="center")
cmds.separator(h=10, style='none', p="main_column") # Empty Space

# Body ====================
cmds.rowColumnLayout(nc=1, cw=[(1, 300)], cs=[(1, 10)], p="main_column")
cmds.text(l='This script generates the Python code necessary to recreate\na curve shape state', align="left")
cmds.separator(h=10, style='none') # Empty Space
cmds.text(l='"Extract Default Attributes to \"setAttr\"" button:', align="left", fn="boldLabelFont")
cmds.text(l='Outputs the python code necessary to set the TRS \n(Translate, Rotate, and Scale) attributes '
'back to their\ncurrent value.', align="left")
cmds.separator(h=10, style='none') # Empty Space
cmds.text(l='Run Code:', align="left", fn="boldLabelFont")
cmds.text(l='Attempts to run the code (or anything written) inside ', align="left")
cmds.text(l='"Output Python Curve" box', align="left")
cmds.separator(h=15, style='none') # Empty Space
cmds.rowColumnLayout(nc=2, cw=[(1, 140), (2, 140)], cs=[(1, 10), (2, 0)], p="main_column")
cmds.text('Guilherme Trevisan ')
cmds.text(l='<a href="mailto:[email protected]">[email protected]</a>', hl=True, highlightColor=[1, 1, 1])
cmds.rowColumnLayout(nc=2, cw=[(1, 140), (2, 140)], cs=[(1, 10), (2, 0)], p="main_column")
cmds.separator(h=15, style='none') # Empty Space
cmds.text(l='<a href="https://github.com/TrevisanGMW">Github</a>', hl=True, highlightColor=[1, 1, 1])
cmds.separator(h=7, style='none') # Empty Space

# Close Button
cmds.rowColumnLayout(nc=1, cw=[(1, 300)], cs=[(1, 10)], p="main_column")
cmds.separator(h=10, style='none')
cmds.button(l='OK', h=30, c=lambda args: close_help_gui())
cmds.separator(h=8, style='none')

# Show and Lock Window
cmds.showWindow(window_name)
cmds.window(window_name, e=True, s=False)

# Set Window Icon
qw = OpenMayaUI.MQtUtil.findWindow(window_name)
widget = wrapInstance(int(qw), QWidget)
icon = QIcon(':/question.png')
widget.setWindowIcon(icon)

def close_help_gui():
if cmds.window(window_name, exists=True):
cmds.deleteUI(window_name, window=True)


if __name__ == '__main__':
# default_attr_to_python(None, use_loop=True)
attr_to_list(None, separate_channels=False)
build_gui_attr_to_python()
Loading

0 comments on commit 5b1afd2

Please sign in to comment.