SourceForge.net Logomayasvn

This is a Maya Subversion integration system to make it easier for your team to use subversion to manage Maya assets

Important:

This is current only compiled for Maya 6.5 and 7.0. If you have another version you'll have to download the source and re-compile. It's also currently Windows only. I don't use Maya on a OS X or under Linux, sorry.

usage:

Usage is straight forward. Once installed if you attempt to open a maya file that is under subversion control you will be asked if you want to get a lock on the file. If you answer yes mayasvn will attempt to lock the file. If you answer no or if you choose not to lock the file you will be warned that you are not allowed to edit the file.

When saving mayasvn will check if the file you are saving is under subversion control. If it is you will be asked if you want to commit the file. If it is not, mayasvn will check if the folder you are saving to is under subversion control. If so you will be asked of you want to add the file to subversion. In either case if you answer yes you are given the option to enter a comment and to then to optionally get the lock again if you want to continue to edit the file.

installation:

Simple (non production) installation for testing

  1. Make sure the subversion client files are installed and in your path. (ie, you should be able to type "svn help" from the command line

  2. Copy the mayaSvn.mll (6.5) or to the mayaSvn.mll (7.0) X:\Program Files\Alias\Maya<ver>\bin\plug-ins

  3. Copy SVNSetup.mel My Documents\Maya\<ver>\scripts

  4. Run Maya, Go to Window->Settings/Preferences->Plug-in Manager..., find mayaSvn.mll and check both "loaded" and "auto load"

  5. Next you need to add some code to your userSetup.mel file to enable it. userSetup.mel is usually found in My Documents\Maya\<ver>\scripts. If it does not exist just create it. Here is the simplest version

    // -- userSetup.mel
    SVNSetup(1);
    

    That's it. If you now try to open or save a file that happens to be in a subversion controlled folder you should get asked the appropriate subversion related questions

Production Installation (for team settings)

The point of this type of installation is so you can update things and your whole team can be brought up to date.

  1. Install the subversion client files somewhere inside your subverison controlled project tree. They do NOT have to be in your path. This way you can update the team with a new version of the client if/when you need to. For this example I'm going to assume e:\work\projectx\tools\svn where e:\work\projectx is the root of the subversion controlled tree for this project. Add it to subversion

  2. Copy the mayaSvn.mll (6.5) or to the mayaSvn.mll (7.0) to a subversion based folder somwhere inside your subversion controlled project tree. In this example e:\work\projectx\tools\maya\7.0\plugins\mayasvn.dll. Add it to subversion

  3. Copy SVNSetup.mel in there as well. In this example e:\work\projectx\tools\maya\7.0\scripts. Add it to subversion

  4. Set an environment variable (right click My Computer, pick the "Settings" tab and click on "Environment Variables". Click "Add" and type "PROJECTX_BASE" for the name and "E:\work\projectx" for the value. Click "OK", "OK", "OK.

  5. Edit your Maya.env file found in My Documents\Maya\<ver>. If it doesn't exist create it and put this code inside

    MAYA_SCRIPT_PATH = %PROJECTX_BASE%\tools\maya\7.0\scripts\
    

    that way Maya will look to our subversion controlled folder for scripts.

  6. add code like this to your userSetup.mel file. userSetup.mel is usually found in My Documents\Maya\<ver>\scripts. If it does not exist just create it.

    // -- userSetup.mel
    ProjectXSetup;
    

    we do it this way because userSetup.mel is a local file and can't be easily managed from subversion but ProjectXSetup.mel can so lets have that do our real work and make that subversion controlled.

  7. create ProjectXSetup.mel in e:\work\projectx\tools\maya\7.0\scripts. Here's the contents

    // ProjectXSetup.mel
    global proc ProjectXSetup()
    {
        // don't enable it if we are in batch mode
        if (!(`about -batch`))
        {
            string $base = `getenv "PROJECTX_BASE"`;
            string $temp = `getenv "TMP"`;
            string $localCopy = $temp + "/mayaSvn.mll";
            string $svnCopy   = $base + "/tools/maya/7.0/plugins/mayaSvn.mll";
    
            // we copy it local and use it there otherwise it will be locked
            // and in use while maya is running making it impossible to update.
    
            sysFile -copy $localCopy $svnCopy;
    
            loadPlugin($localCopy);
    
            SVNSetup(1);
    
            // set the path to the svn client tools so it doesn't have to
            // be in our OS "path".  Note: we assume the typical svn setup
            //
            // svn
            //  +- bin
            //  +- iconv
            //  +- share
            //
            // and that you are passing in the path to the bin folder so we
            // can find the iconv and share folders if needed
    
            SVNSetPath($base + "/tools/svn/bin");
        }
    }
    
  8. Configure subversion to make .mb files need locks by default. To do this edit the file c:\documents and settings\<user>\Application Data\Subversion\config.

    Uncomment or add a line under the [miscellany] section

    enable-auto-props = yes

    in the [auto-props] section add this line

    *.mb = svn:needs-lock=*

    these lines make subversion actually make maya files read-only if you don't have the lock on them as well as require you to lock the file before you are allowed to commit. In otherwords they make .mb files use the checkout-modify-checkin method of version control which is pretty much required for binary files.

Notes - Comments:

At first I thought it would be good enough if mayasvn worked as follows

  1. When Loading a file
    1. check if it's under subversion control
    2. if it is check the lock status
      1. if it's already locked say: "it's locked by --- do NOT edit!"
      2. if it's not locked ask if they want to lock it
        1. if yes, get lock
        2. if not print "do NOT edit!"
      3. if they already have the lock just proceed
    3. load the file
  2. When Saving
    1. check if it's under subversion control
    2. if yes ask if they want to commit
    3. if no check if the folder they are saving to is under subversion control
    4. if yes, ask if they want to add (and commit)
    5. if they commited, ask if they want the lock again if no, print "don't EDIT!"

So, I implemented that with the intention that the artists would edit pretty much only subversion controlled files with the svn:needs-lock property set. The svn:needs-lock property makes files use the lock-modify-unlock mode instead of the default edit-update-commit mode.

Well, I ran it by my artists and they hated it

Sooooooooooooooooooooooooooooooooooooooooooooooooooo.....

The solution I am currently using is this.

We have a project folder tree managed by subversion. In that tree there is a folder for stages and folder for objects(characters/etc). Something like this

  project
  +-data
    +-stages
      +-stage icelevel01
      | +-scenes
      | | +-stage icelevel01.mb
      | +-sourceimages
      |   +-background.tga
      |   +-flower.tga
      +-st_lavalevel23
        +-scenes
        | +-st_lavalevel23
        +-sourceimages
          +-lava.tga
          +-hotlavaanim001.tga
          +-hotlavaanim002.tga

etc..

the artists currently edit their levels outside of that tree somewhere else local on their HD. The plans is, when they open a file in maya e:\myworkspace\folder\scenes\stage_icelevel01_tgs_images.mb

mayasvn will figure out the basename, in this case "stage_icelevel01" and search for a corresponding file in the project folder. If found then we check if they have the lock, if not they are asked if they want it. If yes we attept to get it which includes getting the current version. We also update the folder tree, in this case "svn update project\data\stages\stage_icelevel01" to make sure we have the current textures. Then, we check if the mb file they clicked on (the one not in svn) matches the file in svn. If the files don't match they are asked to select a place to save the the svn file locally (because it's the most recent file). After they pick a place to save it (they could just save on top of the file they original clicked on if they want) then we copy the svn file there AND copy all the textures in project\data\stages\stage_icelevel01\sourceimages to whereever they saved the svn file in the corresponding soruceimages folder. In otherwords, if they saved the svn file to e:\myworkspace\folder\scenes\stage_icelevel01_most_recent.mb then textures would get copied to e:\myworkspace\folder\sourcefiles. The textures, like the .mb file are checked and are only copied if they are different and after warning the artist and giving them a chance to abort.

Checking in follows a similar procedure. They are editing e:\myworkspace\folder\scenes\stage_icelevel01_tgs_images.mb They click "check in level" (an icon to a custom script in Maya) and knowing the file is a level it knows to put it in project\data\stages\stage_icelevel01\scenes and the textures in project\data\stages\stage_icelevel01\sourceimages.

After checking in they get the option to keep the lock.

This basically lets them work as they always have but hopefully still does content management.

So far there are a few problems

Any thoughts. Should I have just forced my artist to use the first solution?

75% of this solution is already checked in. Instead of calling SVNSetup(1); like above you do it more like this

// ProjectXSetup.mel
global proc ProjectXSetup()
{
    // don't enable it if we are in batch mode
    if (!(`about -batch`))
    {
        string $base = `getenv "PROJECTX_BASE"`;
        string $temp = `getenv "TMP"`;
        string $localCopy = $temp + "/mayaSvn.mll";
        string $svnCopy   = $base + "/tools/maya/7.0/plugins/mayaSvn.mll";

        // we copy it local and use it there otherwise it will be locked
        // and in use while maya is running making it impossible to update.
        sysFile -copy $localCopy $svnCopy;

        loadPlugin($localCopy);

        SVNSetup(2); // 2 = solution/mode #2 :-p

        // set the path to the svn client tools so it doesn't have to
        // be in our OS "path"
        SVNSetPath($base + "/tools/svn/bin");

        // pass in a string array of scene paths
        // when a local file is opened these paths
        // will be checked for a matching file
        SVNSetProjectPaths({ $base + "/stages" });

        // pass in a string array texture path gmatch patterns
        // any texture path that matches one of these patterns
        // will be assumed to be shared.  We are using Alias's
        // leveltools package and we keep shared stuff in
        // a folder called leveltools somewhere in the project
        SVNSetTexpathExclusions({ "*leveltools*" });
    }
}

What's missing is the checkin part. It's half written but I already had a separate custom checkin script that's not part of this package so I haven't gotten around to re-writing it here.

note that, for any file opened that does NOT match a file in the defined project paths the original rules apply, ie, check if the file is controlled by subversion directly and if so ask if they want the lock

Localization

Maya sucks at localization. Clearly something they didn't consider when starting Maya. I happen to work on a Japanese team which makes it even worse because basically Maya can't even display Japanese at all which forced me to write a plugin just so I could display dialogs in Japanese. Maybe I can post that later.

If you want to localize the messages supply a callback function that takes an int msgid and returns a string. Basically, copy the SVNGetEnglishMsg function from SVNSetup.mel and put it in your ProjectXSetup.mel. Rename it. Put "global" in front of "proc" and changes the messsages. Finally add this line where you init the stuff.

        SVNSetMessageCallback("MyCustomMessageFunc");

of course change "MyCustomMessageFunc" to whatever name you named your function.

Note that it turns out the subversion svn command needs the APR_ICONV_PATH environment variable set in order to handle languages other than English. If you have svn in your path and you used the installer to install it supposedly it sets that environment variable for you. If it's not set and you are NOT calling SVNSetPath in your initalization then you'll need to set it. If you are calling SVNSetPath then mayasvn will deal with it.

Username translation

There is another callback provided for username translation. The issue was at my company our Windows user accounts are just employee numbers which is not very fun when mayasvn says user "s00321" has the lock on this file. If you have such a system at your company you can provide a callback translation function something like this

// ProjectXSetup.mel
global proc string TranslateUserID (string $userid)
{
    if ($userid == "s00321") { return "gman"; }
    if ($userid == "s00412") { return "boomer"; }

    return $userid;
}

in the setup section add this line

        SVNSetUserIDCallback("TranslateUserID");

Bonus!

mayasvn is nearly 100% mel. The only Maya API part is the mayasvn.mll plugin. All it does is allow you to connect mel scripts to certain events in maya. BeforeSave, AfterOpen, etc. So here is a script that came in useful FixTexturePaths.mel. You can attach it to the AfterOpen event with the following line

eval mayaSvn -ae "\"AfterOpen\"" -sn "\"myAfterOpenScript\"" -m "\"eval FixTexturePaths\"";

What it does is just after a maya loads a scene file it sets the Maya Project to the folder above the folder the scenefile is in. In other words, if you keep your files organzied the maya way with a base folder and inside a scenes and sourceimages folder then instead of having to set the project before you open the file you can just open the file and your project will be set automatically. (that should probably happen in BeforeOpen but for now it's in AfterOpen).

After that it goes through every file texture and checks to see if it exists in <currentproject>/sourceimages. If it does it sets the path for that texture to the new path including making it project relative if possible.

I suppose for completely organized teams this is not important but for my team it seemed like every time I tried to open a file the textures would not come up. I used Crow Yeh's excellent FileTextureManager to manually fix all the paths but with this that fix is now automated.

Sourceforge Project Page

The sourceforge project page is here for source code and other participation