Vormav Posted July 2, 2010 Share Posted July 2, 2010 (edited) I want to create a swig-wrapped module that includes functions taking references/pointers to the various HOM_ object types. The goal is to create something that on the Python end interfaces nicely with all of the existing objects in the hom module. Has anyone been able to get this working? The contents of the HOM headers seems to suggest that I ought to be able to include those in my swig interface to get swig to recognise the hom types/mappings, and then it ought to be able to correctly wrap all of my functions. It looks like I'd at the very least require HOM_Defines.h, but I haven't been able yet to create an interface with that file included that will successfully compile. Problems specific to my swig version, maybe? I've tried 1.3.2 and 2.0.x. The alternative would be to figure out the PyObject*->HOM_* conversions myself; I know how to do that for swig objects, but not in a way that efficiently determines the correct hom type (I'd have to do introspection using the object description. Lame). Any pointers would be appreciated. Edited July 2, 2010 by Vormav Quote Link to comment Share on other sites More sharing options...
edward Posted July 2, 2010 Share Posted July 2, 2010 er, import hou? Quote Link to comment Share on other sites More sharing options...
Vormav Posted July 3, 2010 Author Share Posted July 3, 2010 (edited) ...I sort of suspected that I should have added a "other than doing it all in Python" qualifier to my last sentence... EDIT: So if anyone else needs to do this, here's how you can create a typemap to automatically go from PyObject to a swig wrapped object when your swig interface doesn't know anything about the original wrapped classes: %typemap(in) Foo* { PySwigObject* swigobj = SWIG_Python_GetSwigThis($input); if(swigobj) { if(strcmp(swigobj->ty->name, "_p_Foo") == 0) $1 = reinterpret_cast<Foo*>(swigobj->ptr); else SWIG_exception_fail(SWIG_ValueError, "Expected a Foo* object."); } else SWIG_exception_fail(SWIG_ValueError, "Expected a swig object."); } Similar type maps could be used to go to the original HOM_* types. I'm not thrilled with having to strcmp the class name on every single function call, and I'd still prefer to be able to use the original hom interface. But whatever; this works, and the strcmp probably isn't the bottleneck anyway. Edited July 3, 2010 by Vormav Quote Link to comment Share on other sites More sharing options...
Vormav Posted July 6, 2010 Author Share Posted July 6, 2010 (edited) Alright, so I've figured this out. It is the swig version. In swig versions < 1.3.37, swig used a PySwig naming convention on a lot of symbols. This was flipped around (with good reason) in swig 1.3.37 to be SwigPy. One of the places that this symbol was used was on the type name of the internal swig object. This becomes a problem if you attempt to use swig runtimes from before and after the change within the same python environment; 1.3.37+ can't recognize swig objects < 1.3.37, and HOM just so happens to be using some version < 1.3.37. Also, hom swig interfaces will not compile if used with swig versions as early as 1.3.24. So the short story: 1.3.36 is the magic swig version number. Works fine without any special typemaps. EDIT: for clarification, this is with h10.0.528-64 Edited July 6, 2010 by Vormav Quote Link to comment Share on other sites More sharing options...
mrice Posted July 6, 2010 Share Posted July 6, 2010 Thanks for the info Quote Link to comment Share on other sites More sharing options...
edward Posted July 7, 2010 Share Posted July 7, 2010 I still can't figure out how this isn't the hou module. Quote Link to comment Share on other sites More sharing options...
Vormav Posted July 7, 2010 Author Share Posted July 7, 2010 (edited) This is for creating new modules, in c/c++, that are compatible with the types in the hou module. I.e., take some function like // foo.h void Foo(HOM_Node* node) { // do something fancy hdk thing to the node. ... } wrap in your own swig module: // foo.i %import "HOM/HOM_Defines.h" %{ #include <HOM/HOM_Node.h> %} %module foo void Foo(HOM_Node* node); process with swig and compile: swig -c++ -python -classic foo.i g++ -shared -Wall -I/path/to/python -I/path/to/hdk foo_wrap.cxx -o _foo.so Now you have a custom module compatible with the hou module. I.e., you can do: node = hou.node("/path/to/some/node") imort foo foo.Foo(node) Edited July 7, 2010 by Vormav Quote Link to comment Share on other sites More sharing options...
edward Posted July 8, 2010 Share Posted July 8, 2010 Ah, sorry for being dense. There are some rules that you should follow for your own C++ extensions to HOM. Take a look at the HOM/ObjNode_setSelectable example if you haven't already. Quote Link to comment Share on other sites More sharing options...
mrice Posted July 8, 2010 Share Posted July 8, 2010 Wouldn't wrapping c++ with swig be a simpler way than using the python C api like in the HDK example? Especially when it comes to passing more than simple data types. Quote Link to comment Share on other sites More sharing options...
edward Posted July 8, 2010 Share Posted July 8, 2010 Yes, but I was trying point out some of the other things like HOM_AutoLock if you call anything into the HDK. Quote Link to comment Share on other sites More sharing options...
Vormav Posted July 8, 2010 Author Share Posted July 8, 2010 (edited) Edward, how familar are you with PY_CPythonAPI? I figured I'd need to throw in HOM_AutoLocks where appropriate, but I'm unsure of whether or not I need swig to spit out code with that extra PY_ prefix. It doesn't look to me like the HOM headers are actually using any of that, unless the standard swig interfaces SESI used are doing the change. For instance, HOM_Defines uses Py_DECREF instead of PY_Py_DECREF, others like PyDict_SetItemString, and so on. It seems like Houdini only ships with one version of Python anyway, so it's not clear to me that this really matters, unless the intent is to be able to create c++ python modules that are compatible with multiple versions of Houdini (which I really don't care about; the internals of my modules are version specific anyway). Edited July 8, 2010 by Vormav Quote Link to comment Share on other sites More sharing options...
edward Posted July 9, 2010 Share Posted July 9, 2010 Not really. I'm not sure about your version of PY_CPythonAPI.h, but the comments at the top of my version explain what it is for. ie. They are wrappers that are intended to support multiple versions of Python (which we will see in Houdini 11). In the places where I see PY_ omitted, it is within a SWIGPYTHON define block, which I'm guessing is some special case for swig that doesn't use the PY_ prefix wrappers? <shrugs> Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.