python module sharing between HDAs

   2816   4   3
User Avatar
Member
39 posts
Joined: July 2005
Offline
Hi, there. I have some HDAs that use an external python module to implement some non-houdini specific functionality. I'd like to package the module into the HDAs so that external files are not necessary to use them. Currently I am embedding the python module using the “Custom Script” event handler, but there are a couple problems with this approach

- The python module has to be embedded within each of the HDAs that use it, wasting space.
- The embedding process is a little cumbersome. When there are changes to the module, I have to manually remove the old copy and embed the new one anew.

I suppose I could make a script to remove the old module from the HDAs and replace it with the new one, but I was hoping to avoid something like that…

Is there a better way to do this? Is there some way to embed the module into the OTL itself instead of the HDAs within it so that it can be shared?

Thanks!

Peter.
User Avatar
Member
183 posts
Joined: Nov. 2008
Offline
You can do the following:
1. Make a separate definition(for example with name “pysource”) in your otl, for holding Python code only. You can hide this definition from Tab Menu if you want.
2. Put this code in PythonModule of any other definition. This will pull all code from PythonModule section of “pysource” definition into this PythonModule global namespace:

source = hou.readFile(“opdefSop/pysource?PythonModule”)
exec(source, globals())

If you need to get it in different namespace(module), you can make one with imp python module:

import imp
source = hou.readFile(“opdefSop/pysource?PythonModule”)
mymodule = imp.new_module('mymodule')
exec(source, mymodule.__dict__)

Now all your code from “pysource” definition will be available in mymodule namespace.

Now you can share one otl file and easily make tweaks just in one place.
Aleksei Rusev
Sr. Graphics Tools Engineer @ Nvidia
User Avatar
Member
39 posts
Joined: July 2005
Offline
That seems like a better way to do it, thanks! I had actually considered this option, but I was trying to use importlib to do it which wouldn't work with the opdef syntax. I guess I was kind of hoping SESI had overridden the underlying file reading functions to understand opdef, but no such luck.

This also works:


import toolutils
mymodule = toolutils.createModuleFromSection(“mymodule”, hou.nodeType(hou.objNodeTypeCategory(), “pysource”), “mymodule_PythonModule”)


(I put my module in a python Object type into a custom script section “mymodule_PythonModule”)

Anyway, thanks for the help!

Peter.
User Avatar
Member
1907 posts
Joined: Nov. 2006
Online
If you have code stored in a PythonModule section of “pysource” operator you can just access it directly from the node type, even without an instance of the asset.

# Assuming pysource is a object
hou.nodeType(hou.objNodeTypeCategory(), “pysource”).hm().foo()

As you mentioned, if it is not in the PythonModule you should ideally use the toolutils.createModuleFromSection() function.
Graham Thompson, Technical Artist @ Rockstar Games
User Avatar
Member
617 posts
Joined: Aug. 2008
Offline
uhhh nice trick,
we usually keep the python code in a folder as a .py file. and reference to it, just in case something horrible happen with the otl, we still have the code in another place.
  • Quick Links