Skip to content

Commit

Permalink
Merge pull request #180 from TrevisanGMW/dev
Browse files Browse the repository at this point in the history
release <- dev (3.1.9)
  • Loading branch information
TrevisanGMW authored Aug 30, 2023
2 parents 2fa2b35 + 27803d4 commit a888128
Show file tree
Hide file tree
Showing 12 changed files with 423 additions and 367 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, 8)
__version_tuple__ = (3, 1, 9)
__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
@@ -1,5 +1,5 @@
"""
Package Updater Controller
Attributes To Python Controller
"""
from gt.utils.attr_utils import get_user_attr_to_python, get_trs_attr_as_python, get_trs_attr_as_formatted_string
from gt.utils.system_utils import execute_python_code
Expand Down Expand Up @@ -51,7 +51,7 @@ def __get_selection():
import maya.cmds as cmds
selection = cmds.ls(selection=True) or []
if len(selection) == 0:
cmds.warning(f'Please select at least one object an try again.')
cmds.warning(f'Please select at least one object and try again.')
return []
return selection

Expand Down
2 changes: 1 addition & 1 deletion gt/tools/attributes_to_python/attributes_to_python_view.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
"""
AttributesToPythonView View/Window
Attributes To PythonView View/Window
"""
from PySide2.QtWidgets import QPushButton, QLabel, QVBoxLayout, QFrame
from gt.ui.syntax_highlighter import PythonSyntaxHighlighter
Expand Down
8 changes: 4 additions & 4 deletions gt/tools/curve_to_python/curve_to_python_controller.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
"""
Package Updater Controller
Curve To Python Controller
"""
from gt.utils.curve_utils import get_python_shape_code, get_python_curve_code
from gt.utils.system_utils import execute_python_code
Expand All @@ -20,15 +20,15 @@ def __init__(self, view, model=None):
Args:
view: The view object to interact with the user interface.
model: The AttributesToPythonModel object used for data manipulation.
model: The CurveToPythonModel object used for data manipulation.
"""
self.model = model
self.view = view
self.view.controller = self

# # Connections
self.view.help_btn.clicked.connect(self.open_help)
self.view.extract_crv_python_brn.clicked.connect(self.extract_crv_python)
self.view.extract_crv_python_btn.clicked.connect(self.extract_crv_python)
self.view.extract_shape_state_btn.clicked.connect(self.extract_crv_state)
self.view.run_code_btn.clicked.connect(self.run_python_code)
self.view.save_to_shelf_btn.clicked.connect(self.save_python_to_shelf)
Expand All @@ -50,7 +50,7 @@ def __get_selection():
import maya.cmds as cmds
selection = cmds.ls(selection=True) or []
if len(selection) == 0:
cmds.warning(f'Please select at least one curve an try again.')
cmds.warning(f'Please select at least one curve and try again.')
return []
return selection

Expand Down
10 changes: 5 additions & 5 deletions gt/tools/curve_to_python/curve_to_python_view.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ def __init__(self, parent=None, controller=None, version=None):
self.output_python_label = None
# Buttons
self.help_btn = None
self.extract_crv_python_brn = None
self.extract_crv_python_btn = None
self.extract_shape_state_btn = None
self.run_code_btn = None
self.save_to_shelf_btn = None
Expand All @@ -58,7 +58,7 @@ def __init__(self, parent=None, controller=None, version=None):
stylesheet += resource_library.Stylesheet.maya_basic_dialog
stylesheet += resource_library.Stylesheet.list_widget_dark
self.setStyleSheet(stylesheet)
self.extract_crv_python_brn.setStyleSheet(resource_library.Stylesheet.push_button_bright)
self.extract_crv_python_btn.setStyleSheet(resource_library.Stylesheet.push_button_bright)
self.extract_shape_state_btn.setStyleSheet(resource_library.Stylesheet.push_button_bright)
qt_utils.resize_to_screen(self, percentage=40, width_percentage=55)
qt_utils.center_window(self)
Expand Down Expand Up @@ -90,8 +90,8 @@ def create_widgets(self):
self.output_python_box.setSizePolicy(self.output_python_box.sizePolicy().Expanding,
self.output_python_box.sizePolicy().Expanding)

self.extract_crv_python_brn = QPushButton('Extract Curve to Python')
self.extract_crv_python_brn.setToolTip("Extracts curves as python code. (New Curve)")
self.extract_crv_python_btn = QPushButton('Extract Curve to Python')
self.extract_crv_python_btn.setToolTip("Extracts curves as python code. (New Curve)")
self.extract_shape_state_btn = QPushButton("Extract Shape State to Python")
self.extract_shape_state_btn.setToolTip('Extracts curve shape state. '
'(Snapshot of the shape)')
Expand All @@ -105,7 +105,7 @@ def create_layout(self):

top_buttons_layout = QtWidgets.QVBoxLayout()
two_horizontal_btn_layout = QtWidgets.QHBoxLayout()
two_horizontal_btn_layout.addWidget(self.extract_crv_python_brn)
two_horizontal_btn_layout.addWidget(self.extract_crv_python_btn)
two_horizontal_btn_layout.addWidget(self.extract_shape_state_btn)
top_buttons_layout.addLayout(two_horizontal_btn_layout)

Expand Down
45 changes: 19 additions & 26 deletions gt/tools/extract_influence_joints/__init__.py
Original file line number Diff line number Diff line change
@@ -1,51 +1,44 @@
"""
GT Extract Bound Joints - Extract or Transfer bound joints
GT Extract Influence Joints
github.com/TrevisanGMW/gt-tools - 2022-06-22
ATTENTION!!: This is a legacy tool. It was created before version "3.0.0" and it should NOT be used as an example of
how to create new tools. As a legacy tool, its code and structure may not align with the current package standards.
Please read the "CONTRIBUTING.md" file for more details and examples on how to create new tools.
0.0.1 to 0.0.3 - 2022-06-22 to 2022-07-20
0.0.1 to 1.1.4 - 2022-06-22 to 2022-09-12
Created main function
Added GUI
Added skinCluster check
1.0.0 to 1.0.2 - 2022-07-20 to 2022-07-22
Added Filter non-existent and include mesh checkboxes
Updated help menu
Increased the size of the output window
1.1.0 to 1.1.4 - 2022-07-26 to 2022-09-12
Added "Save to Shelf" button
Added "Extract Bound Joints to Selection Sets" button
Updated help
Tweaked the UI spacing
Fixed a typo
Removed unnecessary parameter
Changed "Include Bound Mesh" to be be inactive by default
Added option to run bind/unbind skin functions
Centered Checkbox options a bit better
Fixed a few issues caused by the latest changes
2.0.0
Updated to VMC model using QT for the view.
Added code highlighter
Added line numbers
Made view dockable
Todo:
Add Transfer functions
Add option to include maya.cmds
"""
from gt.tools.extract_influence_joints import extract_influence_controller
from gt.tools.extract_influence_joints import extract_influence_view
from gt.ui import qt_utils


# Tool Version
__version_tuple__ = (1, 1, 5)
__version_tuple__ = (2, 0, 0)
__version_suffix__ = ''
__version__ = '.'.join(str(n) for n in __version_tuple__) + __version_suffix__


def launch_tool():
"""
Launch user interface and create any necessary connections for the tool to function.
Entry point for when using the tool GT Extract Bound Joints.
Entry point for when using this tool.
Creates Model, View and Controller and uses QtApplicationContext to determine context (inside of Maya or not?)
"""
from gt.tools.extract_influence_joints import extract_influence_joints
extract_influence_joints.script_version = __version__
extract_influence_joints.build_gui_extract_influence_joints()
with qt_utils.QtApplicationContext() as context:
_view = extract_influence_view.ExtractInfluenceView(parent=context.get_parent(), version=__version__)
_controller = extract_influence_controller.ExtractInfluenceController(view=_view)


if __name__ == "__main__":
Expand Down
167 changes: 167 additions & 0 deletions gt/tools/extract_influence_joints/extract_influence_controller.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
"""
Extract Influence Controller
"""
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
logging.basicConfig()
logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)


class ExtractInfluenceController:
def __init__(self, view, model=None):
"""
Initialize the ExtractInfluenceController object.
Args:
view: The view object to interact with the user interface.
model: The ExtractInfluenceModel object used for data manipulation.
"""
self.model = model
self.view = view
self.view.controller = self

# # Connections
self.view.help_btn.clicked.connect(self.open_help)
self.view.extract_influence_python_btn.clicked.connect(self.extract_influence_python)
self.view.extract_influence_set_btn.clicked.connect(self.extract_influence_set)
self.view.run_code_btn.clicked.connect(self.run_python_code)
self.view.save_to_shelf_btn.clicked.connect(self.save_python_to_shelf)
self.view.bind_skin_btn.clicked.connect(self.open_bind_skin_options)
self.view.unbind_skin_btn.clicked.connect(self.run_unbind_skin)
# Initial State
self.view.non_existent_chk.setChecked(True)

self.view.show()

@staticmethod
def open_help():
""" Opens package docs """
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.
"""
_code = "import maya.cmds as cmds\n\n"
_code += self.__extract_influence_with_validation(operation_target='python')
self.view.clear_python_output()
self.view.set_python_output_text(text=_code)

def extract_influence_set(self):
"""
Extracts the TRS channels as lists and populates the python output box with the extracted content.
"""
self.__extract_influence_with_validation(operation_target='set')

def run_python_code(self):
"""
Attempts to run the code found in the "Python Output" box.
"""
_code = self.view.get_python_output_text()
execute_python_code(code=_code, user_maya_warning=True)

def save_python_to_shelf(self):
"""
Saves the content of the python output box to a shelf button.
"""
import maya.cmds as cmds
_code = self.view.get_python_output_text()
if _code:
create_shelf_button(_code,
label='setAttr',
tooltip='Extracted Attributes',
image="editRenderPass.png",
label_color=(0, .84, .81))

highlight_style = "color:#FF0000;text-decoration:underline;"
feedback = FeedbackMessage(prefix='Python code',
style_prefix=highlight_style,
conclusion='was added as a button to your current shelf.')
feedback.print_inview_message()
else:
cmds.warning('Unable to save to shelf. "Output Python Code" is empty.')

@staticmethod
def open_bind_skin_options():
""" Runs the mel command to open the bind skin options """
import maya.mel as mel
mel.eval('SmoothBindSkinOptions;')

@staticmethod
def run_unbind_skin():
""" Runs the mel command unbind skins """
import maya.mel as mel
mel.eval('DetachSkin;')


if __name__ == "__main__":
print('Run it from "__init__.py".')
Loading

0 comments on commit a888128

Please sign in to comment.