Skip to content

Commit

Permalink
Merge pull request #183 from TrevisanGMW/dev
Browse files Browse the repository at this point in the history
release <- dev (3.1.10)
  • Loading branch information
TrevisanGMW authored Aug 31, 2023
2 parents a888128 + abce89a commit fe7b8f0
Show file tree
Hide file tree
Showing 22 changed files with 1,027 additions and 160 deletions.
2 changes: 1 addition & 1 deletion gt/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import sys

# Package Variables
__version_tuple__ = (3, 1, 9)
__version_tuple__ = (3, 1, 10)
__version_suffix__ = ''
__version__ = '.'.join(str(n) for n in __version_tuple__) + __version_suffix__
__authors__ = ['Guilherme Trevisan']
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@
Todo:
Add Transfer functions
"""
from gt.tools.extract_influence_joints import extract_influence_controller
from gt.tools.extract_influence_joints import extract_influence_view
from gt.tools.influences_to_python import influences_python_controller
from gt.tools.influences_to_python import influences_python_view
from gt.ui import qt_utils


Expand All @@ -37,8 +37,8 @@ def launch_tool():
Creates Model, View and Controller and uses QtApplicationContext to determine context (inside of Maya or not?)
"""
with qt_utils.QtApplicationContext() as context:
_view = extract_influence_view.ExtractInfluenceView(parent=context.get_parent(), version=__version__)
_controller = extract_influence_controller.ExtractInfluenceController(view=_view)
_view = influences_python_view.InfluencesPythonView(parent=context.get_parent(), version=__version__)
_controller = influences_python_controller.InfluencesPythonController(view=_view)


if __name__ == "__main__":
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
"""
Extract Influence Controller
Extract Influence to Python Controller
"""
from gt.utils.skin_utils import selected_get_python_influences_code, selected_add_influences_to_set
from gt.utils.system_utils import execute_python_code
from gt.utils.misc_utils import create_shelf_button
from gt.utils.feedback_utils import FeedbackMessage
from gt.utils.skin_utils import get_bound_joints
import logging

# Logging Setup
Expand All @@ -13,10 +13,10 @@
logger.setLevel(logging.INFO)


class ExtractInfluenceController:
class InfluencesPythonController:
def __init__(self, view, model=None):
"""
Initialize the ExtractInfluenceController object.
Initialize the InfluencesPythonController object.
Args:
view: The view object to interact with the user interface.
Expand Down Expand Up @@ -45,82 +45,30 @@ def open_help():
from gt.utils.request_utils import open_package_docs_url_in_browser
open_package_docs_url_in_browser()

def __extract_influence_with_validation(self, operation_target='python'):
"""
Validation before extracting python or set out of the bound mesh
Args:
operation_target (optional, string): "python" will output python code into the python output box,
"set" will create selection sets
Returns:
str or None: Returns the code to select influence joints or None there was an issue or creating a set.
"""
import maya.cmds as cmds
selection = cmds.ls(selection=True) or []

if len(selection) == 0:
cmds.warning('Nothing selected. Please select a bound mesh and try again.')
return

valid_nodes = []
for sel in selection:
shapes = cmds.listRelatives(sel, shapes=True, children=False) or []
if shapes:
if cmds.objectType(shapes[0]) == 'mesh' or cmds.objectType(shapes[0]) == 'nurbsSurface':
valid_nodes.append(sel)

if operation_target == 'python':
commands = []
for transform in valid_nodes:
message = '# Joint influences found in "' + transform + '":'
message += '\nbound_list = '
bound_joints = get_bound_joints(transform)

if not bound_joints:
cmds.warning('Unable to find skinCluster for "' + transform + '".')
continue

if self.view.include_mesh_chk.isChecked():
bound_joints.insert(0, transform)

message += str(bound_joints)

if self.view.non_existent_chk.isChecked():
message += '\nbound_list = [jnt for jnt in bound_list if cmds.objExists(jnt)]'

message += '\ncmds.select(bound_list)'

commands.append(message)

_code = ''
for cmd in commands:
_code += cmd + '\n\n'
if _code.endswith('\n\n'): # Removes unnecessary spaces at the end
_code = _code[:-2]
return _code

if operation_target == 'set':
for transform in valid_nodes:
bound_joints = get_bound_joints(transform)
if self.view.include_mesh_chk.isChecked():
bound_joints.insert(0, transform)
new_set = cmds.sets(name=transform + "_influenceSet", empty=True)
for jnt in bound_joints:
cmds.sets(jnt, add=new_set)

def extract_influence_python(self):
"""
Extracts the TRS channels as setAttr commands and populates the python output box with the extracted content.
"""
include_bound_mesh = self.view.include_mesh_chk.isChecked()
include_existing_filter = self.view.non_existent_chk.isChecked()
_code = "import maya.cmds as cmds\n\n"
_code += self.__extract_influence_with_validation(operation_target='python')
_code += selected_get_python_influences_code(include_bound_mesh=include_bound_mesh,
include_existing_filter=include_existing_filter)
self.view.clear_python_output()
self.view.set_python_output_text(text=_code)

def extract_influence_set(self):
@staticmethod
def extract_influence_set():
"""
Extracts the TRS channels as lists and populates the python output box with the extracted content.
"""
self.__extract_influence_with_validation(operation_target='set')
created_sets = selected_add_influences_to_set() or []
feedback = FeedbackMessage(quantity=len(created_sets),
singular="selection set was",
plural="selection sets were",
conclusion="created.",
zero_overwrite_message='No selection set was created.')
feedback.print_inview_message()

def run_python_code(self):
"""
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
"""
Extract Influence View/Window
Extract Influence to Python View/Window
"""
from PySide2.QtWidgets import QPushButton, QLabel, QVBoxLayout, QFrame, QCheckBox
from gt.ui.syntax_highlighter import PythonSyntaxHighlighter
Expand All @@ -12,15 +12,15 @@
from PySide2.QtCore import Qt


class ExtractInfluenceView(metaclass=MayaWindowMeta):
class InfluencesPythonView(metaclass=MayaWindowMeta):
def __init__(self, parent=None, controller=None, version=None):
"""
Initialize the ExtractInfluenceView.
Initialize the InfluencesPythonView.
This window represents the main GUI window of the tool.
Args:
parent (str): Parent for this window
controller (ExtractInfluenceViewController): ExtractInfluenceViewController, not to be used, here so
controller (InfluencesPythonViewController): InfluencesPythonViewController, not to be used, here so
it's not deleted by the garbage collector. Defaults to None.
version (str, optional): If provided, it will be used to determine the window title. e.g. Title - (v1.2.3)
"""
Expand All @@ -29,7 +29,7 @@ def __init__(self, parent=None, controller=None, version=None):
self.controller = controller # Only here so it doesn't get deleted by the garbage collectors

# Window Title
self.window_title = "GT Extract Influence Joints"
self.window_title = "GT Influence Joints to Python"
_window_title = self.window_title
if version:
_window_title += f' - (v{str(version)})'
Expand Down Expand Up @@ -202,6 +202,6 @@ def close_window(self):
import sys

with qt_utils.QtApplicationContext():
window = ExtractInfluenceView(version="1.2.3") # View
window = InfluencesPythonView(version="1.2.3") # View
window.set_python_output_text(text=inspect.getsource(sys.modules[__name__]))
window.show()
19 changes: 10 additions & 9 deletions gt/tools/package_setup/gt_tools_maya_menu.py
Original file line number Diff line number Diff line change
Expand Up @@ -197,8 +197,8 @@ def load_menu(*args):
command=IMPORT_TOOL + 'initialize_tool("create_testing_keys")',
tooltip='Automated solution for creating testing keyframes.',
icon=resource_library.Icon.tool_testing_keys)
menu.add_menu_item(label='Extract Influence Joints',
command=IMPORT_TOOL + 'initialize_tool("extract_influence_joints")',
menu.add_menu_item(label='Influences to Python',
command=IMPORT_TOOL + 'initialize_tool("influences_to_python")',
tooltip='Generate Python code used to select influence (bound) joints.',
icon=resource_library.Icon.tool_influence_joints)
menu.add_menu_item(label='Make IK Stretchy',
Expand Down Expand Up @@ -392,10 +392,10 @@ def load_menu(*args):
'write_curve_files_from_selection()\n',
tooltip="Write curve data attributes to a desktop folder.",
icon=resource_library.Icon.dev_binary)
menu.add_menu_item(label='Print Package CRV files to Python',
menu.add_menu_item(label='Get Package CRV files to Python',
command='from gt.utils.curve_utils import print_code_for_crv_files\n'
'print_code_for_crv_files()\n',
tooltip='Prints Python Lines used to call curves from "Curves" class.',
'print_code_for_crv_files(use_output_window=True)\n',
tooltip='Get Python Lines used to call curves from "Curves" class.',
icon=resource_library.Icon.dev_binary)
menu.add_menu_item(label='Render Package Curves Thumbnails',
command='from gt.utils.curve_utils import generate_package_curves_thumbnails\n'
Expand All @@ -404,10 +404,11 @@ def load_menu(*args):
icon=resource_library.Icon.dev_picker)
menu.add_divider(divider_label="General") # Misc Section +++++++++++++++++++++++++++++++++
menu.add_menu_item(label='Take Viewport Snapshot',
command='from gt.utils.playblast_utils import render_viewport_snapshot\n'
'from gt.utils.system_utils import get_desktop_path, get_formatted_time\n'
'render_viewport_snapshot(get_formatted_time(format_str="Snapshot %Y-%m-%d %H%M%S"),'
' get_desktop_path())',
command='from gt.utils.system_utils import get_desktop_path, get_formatted_time\n'
'from gt.utils.playblast_utils import render_viewport_snapshot\nimport sys\n'
'file_path = render_viewport_snapshot(get_formatted_time(format_str='
'"Snapshot %Y-%m-%d %H%M%S"), get_desktop_path())\nif file_path:\n\t'
'sys.stdout.write(f\'\\nSnapshot written to: "{file_path}"\')',
tooltip="Saves a viewport snapshot to the desktop.",
icon=resource_library.Icon.dev_picker)
menu.add_menu_item(label='Silently Check for Updates',
Expand Down
4 changes: 3 additions & 1 deletion gt/tools/resource_library/resource_library_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,9 @@ def import_maya_icons(self):
"""
Imports all control curves found in "control_utils.Controls" to the ResourceLibraryModel controls list
"""
undesired_resources = ["ce2_icons", "ce2_python", "ce2_scripts", "qgradient", "qpdf", "qt-project.org", "qtwebchannel", "sows"]
undesired_resources = ["ce2_icons", "ce2_python", "ce2_scripts", "qgradient", "qpdf", "qt-project.org",
"qtwebchannel", "sows", "UsdLayerEditor", "images", "ImportDialog",
"characterizationtool"]
try:
import maya.cmds as cmds
for icon in cmds.resourceManager(nameFilter="*"):
Expand Down
112 changes: 112 additions & 0 deletions gt/ui/python_output_view.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
from gt.ui.syntax_highlighter import PythonSyntaxHighlighter
from gt.ui.line_text_widget import LineTextWidget
from gt.ui.qt_utils import MayaWindowMeta
from PySide2.QtWidgets import QVBoxLayout
from PySide2 import QtCore, QtWidgets
from gt.ui import resource_library
from PySide2.QtGui import QIcon
from gt.ui import qt_utils
import logging

# Logging Setup

logging.basicConfig()
logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)


class PythonOutputView(metaclass=MayaWindowMeta):
def __init__(self, parent=None):
"""
Initialize the AttributesToPythonView.
This window represents the main GUI window of the tool.
Args:
parent (str): Parent for this window
"""
super().__init__(parent=parent)

# Window Title
self.window_title = "Python Output"
self.setWindowTitle(self.window_title)

# Misc
self.output_python_box = None

self.create_widgets()
self.create_layout()

self.setWindowFlags(self.windowFlags() |
QtCore.Qt.WindowMaximizeButtonHint |
QtCore.Qt.WindowMinimizeButtonHint)
self.setWindowIcon(QIcon(resource_library.Icon.dev_code))

stylesheet = resource_library.Stylesheet.scroll_bar_dark
stylesheet += resource_library.Stylesheet.maya_basic_dialog
stylesheet += resource_library.Stylesheet.list_widget_dark
self.setStyleSheet(stylesheet)
qt_utils.resize_to_screen(self, percentage=40, width_percentage=55)
qt_utils.center_window(self)

def create_widgets(self):
"""Create the widgets for the window."""

self.output_python_box = LineTextWidget(self)

self.output_python_box.setMinimumHeight(150)
PythonSyntaxHighlighter(self.output_python_box.get_text_edit().document())

self.output_python_box.setSizePolicy(self.output_python_box.sizePolicy().Expanding,
self.output_python_box.sizePolicy().Expanding)

def create_layout(self):
"""Create the layout for the window."""
mid_layout = QVBoxLayout()
mid_layout.addWidget(self.output_python_box)
mid_layout.setContentsMargins(0, 5, 0, 5) # L-T-R-B

main_layout = QtWidgets.QVBoxLayout(self)
main_layout.setContentsMargins(0, 0, 0, 0)
top_layout = QtWidgets.QVBoxLayout()
bottom_layout = QtWidgets.QVBoxLayout()

top_layout.setContentsMargins(15, 0, 15, 15) # L-T-R-B
main_layout.addLayout(top_layout)
bottom_layout.addLayout(mid_layout)
bottom_layout.setContentsMargins(15, 0, 15, 15) # L-T-R-B
main_layout.addLayout(bottom_layout)

def clear_python_output(self):
""" Removes all text from the changelog box """
self.output_python_box.get_text_edit().clear()

def set_python_output_text(self, text):
"""
Add text to the python output box.
Args:
text (str): The text to set.
"""
self.output_python_box.get_text_edit().setText(text)

def get_python_output_text(self):
"""
Gets the plain text found in the python output box.
Returns:
str: Text found inside the python output text edit box.
"""
return self.output_python_box.get_text_edit().toPlainText()

def close_window(self):
""" Closes this window """
self.close()


if __name__ == "__main__":
import inspect
import sys
with qt_utils.QtApplicationContext():
window = PythonOutputView() # View
window.set_python_output_text(text=inspect.getsource(sys.modules[__name__]))
window.show()
Loading

0 comments on commit fe7b8f0

Please sign in to comment.