Skip to content

Commit fe7b8f0

Browse files
authored
Merge pull request #183 from TrevisanGMW/dev
release <- dev (3.1.10)
2 parents a888128 + abce89a commit fe7b8f0

22 files changed

+1027
-160
lines changed

gt/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import sys
22

33
# Package Variables
4-
__version_tuple__ = (3, 1, 9)
4+
__version_tuple__ = (3, 1, 10)
55
__version_suffix__ = ''
66
__version__ = '.'.join(str(n) for n in __version_tuple__) + __version_suffix__
77
__authors__ = ['Guilherme Trevisan']

gt/tools/extract_influence_joints/__init__.py renamed to gt/tools/influences_to_python/__init__.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@
1919
Todo:
2020
Add Transfer functions
2121
"""
22-
from gt.tools.extract_influence_joints import extract_influence_controller
23-
from gt.tools.extract_influence_joints import extract_influence_view
22+
from gt.tools.influences_to_python import influences_python_controller
23+
from gt.tools.influences_to_python import influences_python_view
2424
from gt.ui import qt_utils
2525

2626

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

4343

4444
if __name__ == "__main__":

gt/tools/extract_influence_joints/extract_influence_controller.py renamed to gt/tools/influences_to_python/influences_python_controller.py

Lines changed: 17 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
"""
2-
Extract Influence Controller
2+
Extract Influence to Python Controller
33
"""
4+
from gt.utils.skin_utils import selected_get_python_influences_code, selected_add_influences_to_set
45
from gt.utils.system_utils import execute_python_code
56
from gt.utils.misc_utils import create_shelf_button
67
from gt.utils.feedback_utils import FeedbackMessage
7-
from gt.utils.skin_utils import get_bound_joints
88
import logging
99

1010
# Logging Setup
@@ -13,10 +13,10 @@
1313
logger.setLevel(logging.INFO)
1414

1515

16-
class ExtractInfluenceController:
16+
class InfluencesPythonController:
1717
def __init__(self, view, model=None):
1818
"""
19-
Initialize the ExtractInfluenceController object.
19+
Initialize the InfluencesPythonController object.
2020
2121
Args:
2222
view: The view object to interact with the user interface.
@@ -45,82 +45,30 @@ def open_help():
4545
from gt.utils.request_utils import open_package_docs_url_in_browser
4646
open_package_docs_url_in_browser()
4747

48-
def __extract_influence_with_validation(self, operation_target='python'):
49-
"""
50-
Validation before extracting python or set out of the bound mesh
51-
Args:
52-
operation_target (optional, string): "python" will output python code into the python output box,
53-
"set" will create selection sets
54-
Returns:
55-
str or None: Returns the code to select influence joints or None there was an issue or creating a set.
56-
"""
57-
import maya.cmds as cmds
58-
selection = cmds.ls(selection=True) or []
59-
60-
if len(selection) == 0:
61-
cmds.warning('Nothing selected. Please select a bound mesh and try again.')
62-
return
63-
64-
valid_nodes = []
65-
for sel in selection:
66-
shapes = cmds.listRelatives(sel, shapes=True, children=False) or []
67-
if shapes:
68-
if cmds.objectType(shapes[0]) == 'mesh' or cmds.objectType(shapes[0]) == 'nurbsSurface':
69-
valid_nodes.append(sel)
70-
71-
if operation_target == 'python':
72-
commands = []
73-
for transform in valid_nodes:
74-
message = '# Joint influences found in "' + transform + '":'
75-
message += '\nbound_list = '
76-
bound_joints = get_bound_joints(transform)
77-
78-
if not bound_joints:
79-
cmds.warning('Unable to find skinCluster for "' + transform + '".')
80-
continue
81-
82-
if self.view.include_mesh_chk.isChecked():
83-
bound_joints.insert(0, transform)
84-
85-
message += str(bound_joints)
86-
87-
if self.view.non_existent_chk.isChecked():
88-
message += '\nbound_list = [jnt for jnt in bound_list if cmds.objExists(jnt)]'
89-
90-
message += '\ncmds.select(bound_list)'
91-
92-
commands.append(message)
93-
94-
_code = ''
95-
for cmd in commands:
96-
_code += cmd + '\n\n'
97-
if _code.endswith('\n\n'): # Removes unnecessary spaces at the end
98-
_code = _code[:-2]
99-
return _code
100-
101-
if operation_target == 'set':
102-
for transform in valid_nodes:
103-
bound_joints = get_bound_joints(transform)
104-
if self.view.include_mesh_chk.isChecked():
105-
bound_joints.insert(0, transform)
106-
new_set = cmds.sets(name=transform + "_influenceSet", empty=True)
107-
for jnt in bound_joints:
108-
cmds.sets(jnt, add=new_set)
109-
11048
def extract_influence_python(self):
11149
"""
11250
Extracts the TRS channels as setAttr commands and populates the python output box with the extracted content.
11351
"""
52+
include_bound_mesh = self.view.include_mesh_chk.isChecked()
53+
include_existing_filter = self.view.non_existent_chk.isChecked()
11454
_code = "import maya.cmds as cmds\n\n"
115-
_code += self.__extract_influence_with_validation(operation_target='python')
55+
_code += selected_get_python_influences_code(include_bound_mesh=include_bound_mesh,
56+
include_existing_filter=include_existing_filter)
11657
self.view.clear_python_output()
11758
self.view.set_python_output_text(text=_code)
11859

119-
def extract_influence_set(self):
60+
@staticmethod
61+
def extract_influence_set():
12062
"""
12163
Extracts the TRS channels as lists and populates the python output box with the extracted content.
12264
"""
123-
self.__extract_influence_with_validation(operation_target='set')
65+
created_sets = selected_add_influences_to_set() or []
66+
feedback = FeedbackMessage(quantity=len(created_sets),
67+
singular="selection set was",
68+
plural="selection sets were",
69+
conclusion="created.",
70+
zero_overwrite_message='No selection set was created.')
71+
feedback.print_inview_message()
12472

12573
def run_python_code(self):
12674
"""

gt/tools/extract_influence_joints/extract_influence_view.py renamed to gt/tools/influences_to_python/influences_python_view.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
"""
2-
Extract Influence View/Window
2+
Extract Influence to Python View/Window
33
"""
44
from PySide2.QtWidgets import QPushButton, QLabel, QVBoxLayout, QFrame, QCheckBox
55
from gt.ui.syntax_highlighter import PythonSyntaxHighlighter
@@ -12,15 +12,15 @@
1212
from PySide2.QtCore import Qt
1313

1414

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

3131
# Window Title
32-
self.window_title = "GT Extract Influence Joints"
32+
self.window_title = "GT Influence Joints to Python"
3333
_window_title = self.window_title
3434
if version:
3535
_window_title += f' - (v{str(version)})'
@@ -202,6 +202,6 @@ def close_window(self):
202202
import sys
203203

204204
with qt_utils.QtApplicationContext():
205-
window = ExtractInfluenceView(version="1.2.3") # View
205+
window = InfluencesPythonView(version="1.2.3") # View
206206
window.set_python_output_text(text=inspect.getsource(sys.modules[__name__]))
207207
window.show()

gt/tools/package_setup/gt_tools_maya_menu.py

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -197,8 +197,8 @@ def load_menu(*args):
197197
command=IMPORT_TOOL + 'initialize_tool("create_testing_keys")',
198198
tooltip='Automated solution for creating testing keyframes.',
199199
icon=resource_library.Icon.tool_testing_keys)
200-
menu.add_menu_item(label='Extract Influence Joints',
201-
command=IMPORT_TOOL + 'initialize_tool("extract_influence_joints")',
200+
menu.add_menu_item(label='Influences to Python',
201+
command=IMPORT_TOOL + 'initialize_tool("influences_to_python")',
202202
tooltip='Generate Python code used to select influence (bound) joints.',
203203
icon=resource_library.Icon.tool_influence_joints)
204204
menu.add_menu_item(label='Make IK Stretchy',
@@ -392,10 +392,10 @@ def load_menu(*args):
392392
'write_curve_files_from_selection()\n',
393393
tooltip="Write curve data attributes to a desktop folder.",
394394
icon=resource_library.Icon.dev_binary)
395-
menu.add_menu_item(label='Print Package CRV files to Python',
395+
menu.add_menu_item(label='Get Package CRV files to Python',
396396
command='from gt.utils.curve_utils import print_code_for_crv_files\n'
397-
'print_code_for_crv_files()\n',
398-
tooltip='Prints Python Lines used to call curves from "Curves" class.',
397+
'print_code_for_crv_files(use_output_window=True)\n',
398+
tooltip='Get Python Lines used to call curves from "Curves" class.',
399399
icon=resource_library.Icon.dev_binary)
400400
menu.add_menu_item(label='Render Package Curves Thumbnails',
401401
command='from gt.utils.curve_utils import generate_package_curves_thumbnails\n'
@@ -404,10 +404,11 @@ def load_menu(*args):
404404
icon=resource_library.Icon.dev_picker)
405405
menu.add_divider(divider_label="General") # Misc Section +++++++++++++++++++++++++++++++++
406406
menu.add_menu_item(label='Take Viewport Snapshot',
407-
command='from gt.utils.playblast_utils import render_viewport_snapshot\n'
408-
'from gt.utils.system_utils import get_desktop_path, get_formatted_time\n'
409-
'render_viewport_snapshot(get_formatted_time(format_str="Snapshot %Y-%m-%d %H%M%S"),'
410-
' get_desktop_path())',
407+
command='from gt.utils.system_utils import get_desktop_path, get_formatted_time\n'
408+
'from gt.utils.playblast_utils import render_viewport_snapshot\nimport sys\n'
409+
'file_path = render_viewport_snapshot(get_formatted_time(format_str='
410+
'"Snapshot %Y-%m-%d %H%M%S"), get_desktop_path())\nif file_path:\n\t'
411+
'sys.stdout.write(f\'\\nSnapshot written to: "{file_path}"\')',
411412
tooltip="Saves a viewport snapshot to the desktop.",
412413
icon=resource_library.Icon.dev_picker)
413414
menu.add_menu_item(label='Silently Check for Updates',

gt/tools/resource_library/resource_library_model.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,9 @@ def import_maya_icons(self):
135135
"""
136136
Imports all control curves found in "control_utils.Controls" to the ResourceLibraryModel controls list
137137
"""
138-
undesired_resources = ["ce2_icons", "ce2_python", "ce2_scripts", "qgradient", "qpdf", "qt-project.org", "qtwebchannel", "sows"]
138+
undesired_resources = ["ce2_icons", "ce2_python", "ce2_scripts", "qgradient", "qpdf", "qt-project.org",
139+
"qtwebchannel", "sows", "UsdLayerEditor", "images", "ImportDialog",
140+
"characterizationtool"]
139141
try:
140142
import maya.cmds as cmds
141143
for icon in cmds.resourceManager(nameFilter="*"):

gt/ui/python_output_view.py

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
from gt.ui.syntax_highlighter import PythonSyntaxHighlighter
2+
from gt.ui.line_text_widget import LineTextWidget
3+
from gt.ui.qt_utils import MayaWindowMeta
4+
from PySide2.QtWidgets import QVBoxLayout
5+
from PySide2 import QtCore, QtWidgets
6+
from gt.ui import resource_library
7+
from PySide2.QtGui import QIcon
8+
from gt.ui import qt_utils
9+
import logging
10+
11+
# Logging Setup
12+
13+
logging.basicConfig()
14+
logger = logging.getLogger(__name__)
15+
logger.setLevel(logging.INFO)
16+
17+
18+
class PythonOutputView(metaclass=MayaWindowMeta):
19+
def __init__(self, parent=None):
20+
"""
21+
Initialize the AttributesToPythonView.
22+
This window represents the main GUI window of the tool.
23+
24+
Args:
25+
parent (str): Parent for this window
26+
"""
27+
super().__init__(parent=parent)
28+
29+
# Window Title
30+
self.window_title = "Python Output"
31+
self.setWindowTitle(self.window_title)
32+
33+
# Misc
34+
self.output_python_box = None
35+
36+
self.create_widgets()
37+
self.create_layout()
38+
39+
self.setWindowFlags(self.windowFlags() |
40+
QtCore.Qt.WindowMaximizeButtonHint |
41+
QtCore.Qt.WindowMinimizeButtonHint)
42+
self.setWindowIcon(QIcon(resource_library.Icon.dev_code))
43+
44+
stylesheet = resource_library.Stylesheet.scroll_bar_dark
45+
stylesheet += resource_library.Stylesheet.maya_basic_dialog
46+
stylesheet += resource_library.Stylesheet.list_widget_dark
47+
self.setStyleSheet(stylesheet)
48+
qt_utils.resize_to_screen(self, percentage=40, width_percentage=55)
49+
qt_utils.center_window(self)
50+
51+
def create_widgets(self):
52+
"""Create the widgets for the window."""
53+
54+
self.output_python_box = LineTextWidget(self)
55+
56+
self.output_python_box.setMinimumHeight(150)
57+
PythonSyntaxHighlighter(self.output_python_box.get_text_edit().document())
58+
59+
self.output_python_box.setSizePolicy(self.output_python_box.sizePolicy().Expanding,
60+
self.output_python_box.sizePolicy().Expanding)
61+
62+
def create_layout(self):
63+
"""Create the layout for the window."""
64+
mid_layout = QVBoxLayout()
65+
mid_layout.addWidget(self.output_python_box)
66+
mid_layout.setContentsMargins(0, 5, 0, 5) # L-T-R-B
67+
68+
main_layout = QtWidgets.QVBoxLayout(self)
69+
main_layout.setContentsMargins(0, 0, 0, 0)
70+
top_layout = QtWidgets.QVBoxLayout()
71+
bottom_layout = QtWidgets.QVBoxLayout()
72+
73+
top_layout.setContentsMargins(15, 0, 15, 15) # L-T-R-B
74+
main_layout.addLayout(top_layout)
75+
bottom_layout.addLayout(mid_layout)
76+
bottom_layout.setContentsMargins(15, 0, 15, 15) # L-T-R-B
77+
main_layout.addLayout(bottom_layout)
78+
79+
def clear_python_output(self):
80+
""" Removes all text from the changelog box """
81+
self.output_python_box.get_text_edit().clear()
82+
83+
def set_python_output_text(self, text):
84+
"""
85+
Add text to the python output box.
86+
87+
Args:
88+
text (str): The text to set.
89+
"""
90+
self.output_python_box.get_text_edit().setText(text)
91+
92+
def get_python_output_text(self):
93+
"""
94+
Gets the plain text found in the python output box.
95+
96+
Returns:
97+
str: Text found inside the python output text edit box.
98+
"""
99+
return self.output_python_box.get_text_edit().toPlainText()
100+
101+
def close_window(self):
102+
""" Closes this window """
103+
self.close()
104+
105+
106+
if __name__ == "__main__":
107+
import inspect
108+
import sys
109+
with qt_utils.QtApplicationContext():
110+
window = PythonOutputView() # View
111+
window.set_python_output_text(text=inspect.getsource(sys.modules[__name__]))
112+
window.show()

0 commit comments

Comments
 (0)