• Mason Smigel

Project structure

Updated: Mar 22

Setting up an organized project structure is essential for maintaining and collaborating on large-scale projects. RIGAMJIG2 is designed to be simple, flexible, and logical so it makes sense to not only me but other TDs.


Maya environment

I used Maya's Module system to keep track of data within Maya's environment variables. This allows me to use a single .mod file to add all the icons, scripts, and plugins into Maya's environment variables on startup.


Using modules also makes it simple to install rigamajig2. Using the techniques from Christian Akesson's tutorial I wrote a simple drag and drop installer to create the .mod file and load in the scripts and plugins.


""" Drag and Drop installer for rigamajig2"""
import os
import sys

import pymel.util
import maya.cmds as cmds

def onMayaDroppedPythonFile(*args):
    # Get the location of the installer
    installer_path = __file__.replace('\\', '/')

    # from the installer path build other important paths.
    module_root = os.path.dirname(installer_path)
    python_path = os.path.join(module_root, 'scripts')
    plugin_path = os.path.join(module_root, 'plug-ins')
    lib_path = os.path.join(module_root, 'scripts', 'lib')

    # Check if the modules directory exists in the user preference directory (if it doesn't, create it)
    maya_moddir_path = '{}/modules'.format(pymel.util.getEnv('MAYA_APP_DIR'))
    if not os.path.exists(maya_moddir_path):
        os.makedirs(maya_moddir_path)

    # Define the module file path
    maya_mod_file = '{}/rigamajig2.mod'.format(maya_moddir_path)

    # Write our module file
    with open(maya_mod_file, 'w') as moduleFile:

        output = '+ rigamajig2 1.0 {}'.format(module_root)
        output += '\r\nPYTHONPATH += {}'.format(lib_path)
        # Add the path to plugin path on first use
        if plugin_path not in pymel.util.getEnv("MAYA_PLUG_IN_PATH"):
            pymel.util.putEnv("MAYA_PLUG_IN_PATH", [pymel.util.getEnv("MAYA_PLUG_IN_PATH"), plugin_path])

        moduleFile.write(output)

    # add the python path on first use
    if python_path not in sys.path:
        sys.path.append(python_path)
    if lib_path not in sys.path:
        sys.path.append(lib_path)

Project structure

rigamajig2/
|-- archetypes/
|   |-- base/
|   |-- biped/
|   |-- quadruped/
|-- bin/
|-- icons/
|-- misc/
|-- plug-ins/
|-- scripts/
|   |-- lib/
|   |-- rigamajig2/
|   |   |-- maya/
|   |   |   |-- anim/
|   |   |   |-- cmpts/
|   |   |   |-- data/
|   |   |   |-- rig/
|   |   |   |-- test/
|   |   |-- shared/
|   |   |-- ui/
|-- tests/
|-- .gitignore
|-- drag_into_maya.py
|-- README.md

archetypes: rig archetypes or presets. Each archetype contains data to act as a starting point when constructing a rig.


bin: executable files. This should be added to a system path to run from the terminal.


icons: icons used within UI or shelves. This is added to the XBMLANGPATH environment variable.


misc: random assets or files. (ex. poly modeled axis marker file)


plug-ins: plugins. This is added to the MAYA_PLUG_IN_PATH environment variable.


scripts: python and Mel scripts. This is added to the PYTHONPATH and MAYA_SCRIPT_PATH environment variables.


lib: external python libraries. For this project we only need NumPy.


rigamajig2: python module for rigamajig2


maya: scripts for Maya. At the root level, the scripts should be largely independent of other modules and are combined together later.

(ex. matrix constrain, match transform, create nodes, cleanup mesh).


anim: scripts for animation. (ex. mirror pose, ikfk matching)


cmpts: components used in rig build. Components are python classes with specific methods and parameters used in the rig builder.

(ex. arm, leg, cog, lookAt)


data: scripts to manage saving and loading data from Maya to JSON.

(ex. hierarchy data, skin data, joint data, blendshape data, curve data)


rig: scripts for building rigs, but not whole components. (ex. controls, rig builder, ikfk setups, ik spline setup, space switching)


test: contains Maya unit test runner


shared: scripts not related to Maya or another DCC.


ui: python scripts for UIs and custom PySide widgets


tests: python files for unit testing. All files here are run when using the 'runmayaunittest' executable.


.gitignore: git file to specify files not under VCS


drag_into_maya.py: drag and drop installer


README.md: markdown document containing basic documentation about rigamajig2