Python Modules like XSI Plugins

March 8th, 2007 by Daniele Niero - Viewed 16594 times -




Starting from my last post I’d like to show you how I use Python modules in XSI instead of normal self installing plugins.

You know that XSI automatically recognizes plugins when a proper file is putted under a folder like this: [workgroup or user]\Application\Plugins. We don’t need to specify anything else. Very clever and very useful especially for sharing plugins with all your colleagues.

You also know that Python can find modules and other Python scripts when they are in the same path as the file which is importing them or in a folder specified in the pythonpath. This means that if we set the pythonpath from within XSI and add to it some specific folders from our workgroups, we’ll be able to import Python files or modules in XSI (if it is connected with the workgroups) in every computer in our company, just like the XSI plugins do.

The First Step: Create An OnStartup Event

The first thing we need is create an event, a siOnStartup event, and set properly the pythonpath when XSI start.

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
# Purpose:
# Scanning all the Workgroups installed and put in the Python Path all the ...\Application\Plugins\PythonModules folders we will find.
 
import win32com.client
from win32com.client import constants
 
null = None
false = 0
true = 1
 
def XSILoadPlugin( in_reg ):
in_reg.Author = "Daniele Niero"
in_reg.Name = "Set Python Path Plug-in"
in_reg.Email = ""
in_reg.URL = ""
in_reg.Major = 1
in_reg.Minor = 0
 
in_reg.RegisterEvent("SetPythonPath", constants.siOnStartup)
#RegistrationInsertionPoint - do not remove this line
 
return true
 
def XSIUnloadPlugin( in_reg ):
	return true
 
def SetPythonPath_OnEvent( ctxt ):
	import sys
	wkgrLocations = Application.WorkGroups;
	for wkgr in wkgrLocations:
		workgroupLibFolder = XSIUtils.BuildPath( wkgr, "Application\\Plugins\\PythonModules" )
		if workgroupLibFolder not in sys.path :
			sys.path.append( workgroupLibFolder )
	userLocation = Application.InstallationPath( constants.siUserPath )
	userLibFolder = XSIUtils.BuildPath(userLocation, "Application\\Plugins\\PythonModules" )
	if userLibFolder not in sys.path :
		sys.path.append( userLibFolder )
	Application.LogMessage( sys.path, constants.siVerbose )
 
	# Return value is ignored as this event can not be aborted.
	return true

So, what did we do exactly? We have just scanned all the workgroups installed (and the user folder as well), built a path like this WorkGroup\Application\Plugins\PythonModules and appended it to the pythonpath list.

The good thing is that all the paths added to the sys.path will be removed when XSI is closed. Helping us to keep the pythonpath clean.

At this point, if we have a PythonModules folder in the Plugins folder in one of the workgroups connected with XSI, we are able to just import every file or modules saved in this PythonModules folder. Since in your company everyone have the workgroups correctly connected, they are able to import a python file or module written by someone else, without specifying or doing anything, just like standard XSI plugins!

The first test and utility python file

The first test we can do is create a file that exposes, once imported, some common and useful stuff we need when we use Python in XSI.
This file could be something like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import win32com as win
import win32com.server as winServer
 
from win32com.client import constants
from win32com.client.dynamic import Dispatch
from win32com.client import Dispatch as ComObject
from win32com.server.util import wrap
 
App = Dispatch( 'XSI.Application' ).Application
XSIFactory = Dispatch( 'XSI.Factory' )
XSIMath = Dispatch( 'XSI.Math' )
 
null = None
false = 0
true = 1

Save it as MyGlobals.py and put it in a PythonModules folder. Open XSI and just test if everything work writing just this few lines in the script editor:

1
2
3
4
from MyGlobals import *
 
App.LogMessage("note that App works, it is a global variable now!")
anXSICollection = ComObject("XSI.Collection")

If you don’t have errors form this simple testing code it means we are ready to move on the next step and create a complete class that can help us to handle a GenericProperty.

7 Responses to “Python Modules like XSI Plugins”

  1. Hi Dan,

    Thanks for taking the time to do this. It’s helped me import my 1st Python Module in minutes. I had spent some time trying to do this last night but to no avail. I’m going to read all you other scripting posts now.

    Thanks again
    All the best,

    Dave

  2. eric says:

    Thanks for sharing your knowledge.
    I’m kind of new in scripting in xsi and your help is great!

  3. Brian says:

    How would one get to XSIUtils inside? Inside one of my modules I am trying to check if a Partition is a light or object.

    1
    2
    3
    4
    5
    6
    7
    
    oDatabase = XSIUtils.DataRepository
    if (oDatabase.getidentifier(oPart, c.siObjectCLSID) == '{7A1BB9D6-58A3-49D6-84BA-39429EDAD489}'):
        partElem.setAttribute('type', 'Lights_Partition')
        LOG("Light")
    else:
        partElem.setAttribute('type', 'Object_Partition')
        LOG("Object")
  4. [...] Softimage Blog » Blog Archive » Python Modules like XSI Plugins [...]

  5. anuj says:

    thanks for such nice post
    regards
    Anuj
    http://www.winservers.co.in/

  6. Cegreepsy says:

    treba zkontrolovat:)

  7. Antonieo says:

    Great post ! Really helpful !

    But how could I make it work with other plugins ?
    I made some plugins importing some modules I built in workgroup folder , every time I start XSI , they failed to find modules , and after I open their scripts , re-save without changing the code , it works again .
    That means those plugins are loaded before this event . So python module paths haven’t been added when loading those plugins .

    Is there anyway to do the trick ? I mean make it work without force other team members execute any scripts or doing anything else , but only connect to the workgroup :
    maybe some way to changge plugin oreder , or change the scripts of plugins to make them being loaded after certain events .