I finally made some time to update the Pip tool download link based on some folks kindly reaching out regarding a broken download link. A new link is listed below and I also took a little time to fix a few more bugs as well! :)
- PySide2 Support for Maya 2018+
- Fixed a bug with the tutorial throwing errors in niche cases where the tool was excited at specific times.
- Minor code cleanup and refactor.
Download Pip 2023 Link
Showing posts with label Animation. Show all posts
Showing posts with label Animation. Show all posts
Monday, February 20, 2023
Sunday, July 3, 2016
Maya Picture in Picture Tool (PiP) Development Part 2
I haven't had too much time to devote to getting PiP fully complete in a while - I am to a point now where I would like to put up a beta download and see what kind of feedback I get for improvements.
pip_tool.zip
Just unzip the pip_tool folder to your Maya python path (example, your documents/maya/scripts/ folder). The code to launch the tool, from a Python tab in the Maya script Editor...
This can be dragged to a shelf for later use.
I recently posted about my exploration with unit tests, I wanted to also post some of my early work with unit testing for PiP. I feel like most folks who are early on in their learning path with unit tests would benefit from seeing examples of what kinds of things to test for. This isn't my most current test library for PiP but it should get the point across...
From these examples, you can see I started with testing the results of early development stages such as moving files from my development path to the Maya script path, or just a simple import check, UI loading checks, etc. Kind of a neat thing to note here is my unit tests are being ran from the windows command line to launch a standalone Maya session (no UI). The problem with this is PiP is a UI based tool, so as I kept developing more tests I realized I could run some tests in command line but to run some specific tests I would need a normal Maya session.
The current beta release seems to have a few graphical glitches on certain computer setups - that and a few other "nice to haves" are the known issues that I am wanting to polish before I consider it complete. Anyway, that's all for now!
pip_tool.zip
Just unzip the pip_tool folder to your Maya python path (example, your documents/maya/scripts/ folder). The code to launch the tool, from a Python tab in the Maya script Editor...
1 2 | import pip_tool.pip as PiP PiP.jbPiP_UI() |
This can be dragged to a shelf for later use.
I recently posted about my exploration with unit tests, I wanted to also post some of my early work with unit testing for PiP. I feel like most folks who are early on in their learning path with unit tests would benefit from seeing examples of what kinds of things to test for. This isn't my most current test library for PiP but it should get the point across...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 | """ Jason Breneman unittest_pip.py This file contains the unit test library for the Picture in Picture tool. Some unit tests do not pass specifically due to launching Maya through a standalone session. """ # maya libraries import maya.standalone import maya.cmds as cmds try: maya.standalone.initialize() except: pass # python libraries import unittest import os import uuid import shutil import logging logging.basicConfig( level=logging.INFO ) logger = logging.getLogger( __name__ ) logger.info( "PiP Unit Test starting...\n" ) MAYA_VERSION = cmds.about( version=True ) MAYA_APP_DIR = os.environ["MAYA_APP_DIR"] ROOT_DEV_DIR = sys.path[0].replace( "\\", "/" ).replace( "/pip_tool/tests", "" ) ROOT_TOOL_PATH = MAYA_APP_DIR + "/scripts" logger.info( "'Maya Version' : " + MAYA_VERSION + "\n" ) logger.info( "'MAYA_APP_DIR' : " + MAYA_APP_DIR + "\n" ) class TestLibrary( unittest.TestCase ): """ Test Library unit test class for Picture in Picture tool """ def setUp( self ): """ Method to provide any standard setup instructions for a test case function Args: self (object) : reference to the TestLibrary class instance Returns: None """ pass def tearDown( self ): """ Method to provide any standard tear down instructions for a test case function Args: self (object) : reference to the TestLibrary class instance Returns: None """ pass def test_files_installed_check( self ): """ Test method for copying files from the development environment to the MAYA_APP_DIR path Args: self (object) : reference to the TestLibrary class instance Returns: None """ logger.info( "*** TestCase *** Remove existing install, and apply a fresh install\n" ) if os.path.exists( ROOT_TOOL_PATH + "/pip_tool" ): shutil.rmtree( ROOT_TOOL_PATH + "/pip_tool" ) shutil.copytree( ROOT_DEV_DIR + "/pip_tool", ROOT_TOOL_PATH + "/pip_tool" ) def test_import_check( self ): """ Test method to check for a successful module import Args: self (object) : reference to the TestLibrary class instance Returns: None """ logger.info( "*** TestCase *** Import pip_tool module\n" ) import_success = False error_message = "TestCase Failure, PiP module did not import correctly.\n" try: import pip_tool.pip as PiP import_success = True except: pass self.assertTrue( import_success, error_message ) def test_pip_instance( self ): """ Test method to check a successful instantiation of PiP Args: self (object) : reference to the TestLibrary class instance Returns: None """ logger.info( "*** TestCase *** Load a PiP instance\n" ) import pip_tool.pip as PiP reload( PiP ) loadout = PiP.jbPiP_UI() loadout_exists = cmds.modelEditor( loadout.name_instance + "__ME", query=True, exists=True ) error_message = "TestCase Failure, PiP loadout does not exist. Maya UI required for successful TestCase\n" self.assertTrue( loadout_exists, error_message ) def test_pip_callback_newscene( self ): """ Test method to check if the new scene callback gets properly deleted when a new scene event occurs Args: self (object) : reference to the TestLibrary class instance Returns: None """ logger.info( "*** TestCase *** Delete PiP on New Scene Callback\n" ) import pip_tool.pip as PiP reload( PiP ) loadout = PiP.jbPiP_UI() cmds.file( new=True, force=True ) self.assertEquals( loadout.newscene_callbackid, None ) # if starting from a command prompt, load unit test class instance if __name__ == "__main__": unittest.main() |
From these examples, you can see I started with testing the results of early development stages such as moving files from my development path to the Maya script path, or just a simple import check, UI loading checks, etc. Kind of a neat thing to note here is my unit tests are being ran from the windows command line to launch a standalone Maya session (no UI). The problem with this is PiP is a UI based tool, so as I kept developing more tests I realized I could run some tests in command line but to run some specific tests I would need a normal Maya session.
The current beta release seems to have a few graphical glitches on certain computer setups - that and a few other "nice to haves" are the known issues that I am wanting to polish before I consider it complete. Anyway, that's all for now!
Wednesday, March 30, 2016
Maya Picture in Picture Tool (PiP) Development Part 1
It's been a while since I last posted but I wanted to write about a tool I had been planning for a while and finally found some time to start developing. For now, I would consider this tool in an alpha state and I do plan on having it available for download in the near future once it's fully vetted.
And here is snippet of code used to make a new model editor nested to the main model editor. Nothing super crazy, the main idea here is using maya's ui api to get the main view port - wrap it to a QWidget. Then using Maya's cmds engine, create a new modelEditor, wrap it also to a QWidget - then parent them together.
This process was a little different for the older versions of Maya that used PyQt - the Maya view port ui is constructed a little differently which forced me to make a window with a layout containing the new modelEditor then parent the window into the main view port QWidget.
Well, that's mostly all I wanted to cover for now. It's been fun trying to think of cool ways to keep the users focused in the view port rather than spreading their gaze over more desktop space. If someone else was looking for something similar hopefully this post has helped. My part 2 will hopefully include a download link!
This is PiP, it is a tool within Maya to create view port within a view port (picture in picture) setup. The original idea came from watching a lot of animators at work creating tear off model panels with a camera setup in the game camera's angle to see how their animation was reading visually. Most of our animators have at least 2 monitors, their main monitor is typically where they animate on their primary view port, but they also tear off a copy of the model panel with the game camera ( along with the graph editor and other tools) thrown onto the secondary monitor. This may not get to some people - but I have taken it as a personal goal to try to keep folks centered and focused in the same monitor space as much as possible - which led to the idea "can you nest a model panel into the existing model panel?" Which leads to other crazy ideas such as "can graph splines be represented in the view port?" and "can we view silhouette and textures and animate at the same time?"
PiP allows the artist to view multiple cameras at once within the context of their main work and thought process - rather than diverting their gaze to a second monitor to see how things look, and later returning back to work. You can make as many PiP window instances as you desire, resize them to your liking, and even play back animations in all view ports at once to really get a good idea of how things are working together.
Throughout the initial brain storming of this I started focusing on the other practices for multiple model panels and cameras such as a face camera or a face rig osipa-style slider control camera - seeing the multiple disciplinary uses for PiP really made me think twice about how useful it could be if I ever found time to develop it!
Well I found some time, it really isn't a large tool - I have parented ui objects to the view port in the past, it was more of figuring out the intricacies of doing it with model editor widgets. I wanted the interface to be super simple for anyone to use, I also wanted to make sure older versions of Maya could use the tool. I am using maya.cmds instead of pymel.core for a lot of the work just to help with speed although it's not really a very "procedurally heavy" tool, the speed differences are something I am lot more aware of in the past few years of working with pymel. Any version of Maya that is older than 2014 will utilize PyQt for it's UI setup, and newer versions will utilize PySide. This is just some of the code I used to configure which UI library to use based on the maya version.
# Maya libraries import maya.OpenMaya as om import maya.OpenMayaUI as omUI import maya.cmds as cmds # Find module file path used for icon relative path finding module_file_path = __file__.replace( "\\", "/" ).rpartition( "/" )[0] mayaMainWindowPtr = omUI.MQtUtil.mainWindow() MAYA_VERSION = cmds.about( version=True ).replace( " x64", "" ) MAYA_UI_LIBRARY = "PyQt" # PyQt if int( MAYA_VERSION ) < 2014: from PyQt4 import QtGui from PyQt4 import QtCore import sip wrapInstance = sip.wrapinstance # PySide else: from PySide import QtCore from PySide import QtGui from shiboken import wrapInstance MAYA_UI_LIBRARY = "PySide" QString = str mayaMainWindow = wrapInstance( long( mayaMainWindowPtr ), QtGui.QWidget )
And here is snippet of code used to make a new model editor nested to the main model editor. Nothing super crazy, the main idea here is using maya's ui api to get the main view port - wrap it to a QWidget. Then using Maya's cmds engine, create a new modelEditor, wrap it also to a QWidget - then parent them together.
This process was a little different for the older versions of Maya that used PyQt - the Maya view port ui is constructed a little differently which forced me to make a window with a layout containing the new modelEditor then parent the window into the main view port QWidget.
# cache the main viewport widget self.main_m3dView = omUI.M3dView() omUI.M3dView.getM3dViewFromModelPanel( self.defaultModelPanel, self.main_m3dView ) viewWidget = wrapInstance( long( self.main_m3dView.widget() ), QtGui.QWidget ) # Create modelEditor editor = cmds.modelEditor( self.nameInstance + "__ME" ) cmds.modelEditor( editor, edit=True, camera=self.defaultCameraStart, interactive=False, displayAppearance='smoothShaded', displayTextures=True, headsUpDisplay=False, shadows=True ) # parent the modelEditor to the viewport ptr_me = omUI.MQtUtil.findControl( editor ) wrap_me = wrapInstance( long( ptr_me ), QtGui.QWidget ) wrap_me.setParent( viewWidget ) self.window = wrap_me self.window.move( self.startingPos[0], self.startingPos[1] ) self.window.setFixedSize( QtCore.QSize( self.windowSize[0], self.windowSize[1] ) )
Well, that's mostly all I wanted to cover for now. It's been fun trying to think of cool ways to keep the users focused in the view port rather than spreading their gaze over more desktop space. If someone else was looking for something similar hopefully this post has helped. My part 2 will hopefully include a download link!
Subscribe to:
Posts (Atom)