Search - User list
Full Version: Custom HDAs Not Supported in LOPS?
Root » Solaris and Karma » Custom HDAs Not Supported in LOPS?
jlapre
Hello,
in our planetarium production pipeline, we have a number of HDAs we developed. They work in our /obj context using Mantra.
For e.g. we have a globe (planet) HDA that uses DEM and satellite visual data.

We want to be able to add LOPS/Karma to our Houdini workflow.

However, when I try to Scene Import (All) our custom HDAs from /obj into /stage, we get the warning: Skipped Object "..." because its type isn't supported.

I have attached a simplified example.

In my example, I created a geo node in /obj with a torus sop. Then converted this into a simple HDA called my_torus.
When I create a Scene Import (All) LOP, I get the above warning.

As a workaround, I try to import my HDA using an SOP Import LOP. Which works, but then it loses the transform inherited by the null hierarchy in the source /obj context.

What am I missing?

Thanks
tamte
For custom object types you may have to create your own translator plugin

https://www.sidefx.com/docs/houdini/hom/sceneimport_object_translator.html [www.sidefx.com]
jsmack
jlapre
What am I missing?

Custom nodes require object processor scripts. You can look at the base examples in the houdini/husdplugins/objtranslators folder.
If they map to standard geo/subnet nodes, then you can probably just register the existing translators under the hda names.
jlapre
Thanks jsmack.
I'm having trouble finding documentation or an example of how to add object processor scripts.
Could you point me to documentation or an example of registering the existing translators under the hda names?
Thanks again.
jsmack
jlapre
Thanks jsmack.
I'm having trouble finding documentation or an example of how to add object processor scripts.
Could you point me to documentation or an example of registering the existing translators under the hda names?
Thanks again.

The article Tomas posted is the only documentation I know of, but you can open the base.py object translator in the Houdini directory for example code.
jlapre
Ah. I overlooked Tomas' documentation link. I'll check it out.
Thanks @jsmack and @tamte!
robp_sidefx
If there's anything in that documentation link that you find confusing/missing, please let us know!

I appreciate that we've simultaneously increased both the flexibility and the cost of dealing with custom object types via SceneImport in Houdini 19.0.
jlapre
Hi Rob. No worries. I understand that with great power comes great responsibilities.

What would be helpful is if you took my simplified my_torus HDA and provided a specific python example.
As Pixar’s USD Python APIs are a steep learning curve.
https://graphics.pixar.com/usd/release/api/index.html [graphics.pixar.com]

It would also be helpful if your Houdini 19.0 Python scripting documentation:
https://www.sidefx.com/docs/houdini/hom/sceneimport_object_translator.html [www.sidefx.com]
...had a link to the above and these tutorials.
https://graphics.pixar.com/usd/release/tut_usd_tutorials.html [graphics.pixar.com]

Thanks
jlapre
robp_sidefx
If there's anything in that documentation link that you find confusing/missing, please let us know!

I appreciate that we've simultaneously increased both the flexibility and the cost of dealing with custom object types via SceneImport in Houdini 19.0.

What would also be helpful is if the warning in the Scene Import LOP included "if you want your HDA to import into LOPS then you need to implement a Scene Import LOP object translator plugin". With a link to:
https://www.sidefx.com/docs/houdini/hom/sceneimport_object_translator.html [www.sidefx.com]

The warning gave me the false impression that custom HDAs are not supported by LOPS. Hence the name of this thread.

Thanks
jsmack
Hey Rob, thanks for replying. I'm trying to follow along and figure out the object translators as well. At the end each module, they define a registerTranslators function and call registerTranslator with what looks like a node type name as the first argument. This seems straightforward. In base.py, I see a translator registered for 'xform', but there is no such object node type. What is this for?
robp_sidefx
jlapre
What would be helpful is if you took my simplified my_torus HDA and provided a specific python example.

Here's the simplest translator:
import husd

class TorusTranslator(husd.objtranslator.Translator):
    def shouldTranslateNode(self):
        return True
    def primType(self):
        return 'Xform'

def registerTranslators(manager):
    manager.registerTranslator('my_torus', TorusTranslator)

You can rapidly increase the complexity if you want to start handling custom attributes, visibility, etc. Specifically regarding visibility, it's on my todo list to add an additional translator base class (something like husd.objtranslator.VisibleTranslator) so that the logic for handling the obj-level visibility flag can be more centralised.

What would also be helpful is if the warning in the Scene Import LOP included "if you want your HDA to import into LOPS then you need to implement a Scene Import LOP object translator plugin".

Yes, that's an excellent suggestion. RFE made!
robp_sidefx
jsmack
I see a translator registered for 'xform', but there is no such object node type. What is this for?

That's an excellent question, and the short (and embarrassing) answer is: it serves no point whatsoever. At one point in the development history I was using the XformTranslator as an internal base class, but then I undid that and I think I just blindly registered it as its own translator even though, as you rightly note, there is no xform Object node.
jlapre
robp_sidefx
jlapre
What would be helpful is if you took my simplified my_torus HDA and provided a specific python example.

Here's the simplest translator:
import husd

class TorusTranslator(husd.objtranslator.Translator):
    def shouldTranslateNode(self):
        return True
    def primType(self):
        return 'Xform'

def registerTranslators(manager):
    manager.registerTranslator('my_torus', TorusTranslator)

You can rapidly increase the complexity if you want to start handling custom attributes, visibility, etc. Specifically regarding visibility, it's on my todo list to add an additional translator base class (something like husd.objtranslator.VisibleTranslator) so that the logic for handling the obj-level visibility flag can be more centralised.

What would also be helpful is if the warning in the Scene Import LOP included "if you want your HDA to import into LOPS then you need to implement a Scene Import LOP object translator plugin".

Yes, that's an excellent suggestion. RFE made!

Hi Rob,
thanks for the simplest implementation example. I'll give that a try.
Also thanks for adding my suggestion to the warning details.
jlapre
Hi Rob,

I created a file called my_torus.py with the bare-bones code you provided.

See attached.

I'm currently testing on macOS BigSur, so I put this file here:

/Applications/Houdini/Houdini19.0.561/Frameworks/Houdini.framework/Versions/Current/Resources/houdini/husdplugins/objtranslators/

That worked!

Thanks again.
jlapre
jlapre
Hi Rob,

I created a file called my_torus.py with the bare-bones code you provided.

See attached.

I'm currently testing on macOS BigSur, so I put this file here:

/Applications/Houdini/Houdini19.0.561/Frameworks/Houdini.framework/Versions/Current/Resources/houdini/husdplugins/objtranslators/

That worked!

Thanks again.

One caveat is that if I version up using the new Houdini 19 version up minor version mechanism, then the Scene Import LOP breaks again.

I tried duplicating my_torus.py to
my_torus.1.0.py
my_torus__1.0.py
my_torus__1_0.py

But non of the above worked.
Do I need to register each version in the python file itself?

e.g.

def registerTranslators(manager):
manager.registerTranslator('my_torus::1.0', TorusTranslator)
jlapre
I answered my own question. I added:

def registerTranslators(manager):
manager.registerTranslator('my_torus::1.0', TorusTranslator)

..to my_torus.py

And now it works!

Thanks again, Rob et al.
robp_sidefx
jlapre
I answered my own question.

My favourite kind

Yes, SceneImport is very strict about naming (versions, namespaces, etc) ... for better or worse.

As you've found, you can share a single translator across many different node-types, just adding new registerTranslator() calls for each.
jsmack
robp_sidefx
As you've found, you can share a single translator across many different node-types, just adding new registerTranslator() calls for each.

Where/when do register translator calls have to happen? Can they happen in the 456.py? Especially how to deal with Studio HDA libraries that are installed from a DB using 456 hooks.
jlapre
robp_sidefx
jlapre
I answered my own question.

My favourite kind

Yes, SceneImport is very strict about naming (versions, namespaces, etc) ... for better or worse.

As you've found, you can share a single translator across many different node-types, just adding new registerTranslator() calls for each.

Hi Rob,

I tried to increment my_torus::1.0 again to my_torus::1.1, and updated my_torus.py accordingly.
my_torus::1.1 works, but when I switch back to my_torus::1.0, it breaks in LOPS again.
Even if I save, quit out of Houdini, then re-launch.
It now only appears to recognize the newest version of the HDA.
What am I missing?

Thanks
robp_sidefx
Ah, sorry for any confusion. Where you currently have:
def registerTranslators(manager):
    manager.registerTranslator('my_torus', TorusTranslator)

def registerTranslators(manager):
    manager.registerTranslator('my_torus::1.0', TorusTranslator)

def registerTranslators(manager):
    manager.registerTranslator('my_torus::1.1', TorusTranslator)

You should have:
def registerTranslators(manager):
    manager.registerTranslator('my_torus', TorusTranslator)
    manager.registerTranslator('my_torus::1.0', TorusTranslator)
    manager.registerTranslator('my_torus::1.1', TorusTranslator)
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB