Getting render camera

   2635   10   1
User Avatar
Member
20 posts
Joined: Sept. 2015
Offline
Hi,

I'm struggling with obtaining active camera in my LOP tree using Python (not Python LOP)

My idea was start traversing from my Usdrender LOP to the Rendersettings LOP where I'll read camera parameter.
Problem happens when rendersetting parameter is using primpath name instead LOP path (eg. /Render/rendersettings vs /stage/rendersettings1).

In that case I don't know how to traverse to rendersettings LOP.

What is the easiest approach of getting render camera?

Thank you

A.
User Avatar
Member
179 posts
Joined: Nov. 2013
Offline
ancestors = hou.node('/stage/rendersettings1').inputAncestors()
for a in ancestors:
    if a.type().name() == 'camera':
        print(a.path())
User Avatar
Member
179 posts
Joined: Nov. 2013
Offline
Or seeing as you know cameras are stored in /cameras and your stage location is most likely /stage, you could just string replace the first part of the camera primpath with /stage to get the node path.

ancestors = hou.node('/stage/usdrender_rop1').inputAncestors()
for a in ancestors:
    if a.type().name() == 'rendersettings':
        nodepath = a.path()
        rendercam = hou.node(str(nodepath)).parm('camera').eval()
        mycam = rendercam.replace("cameras", "stage")
        print(mycam)
User Avatar
Member
20 posts
Joined: Sept. 2015
Offline
Thank you Hamilton,

my intention is validate scene before sending to the farm, so solution must be bulletproof.

First code presumes that I know name of rendersettings LOP what I don't. It is also possible that rendersettings won't be present
in actual tree at all and will be referenced from other USD file. In that case neither second code would help. I'm sorry I wasn't clear enough.

I really appreciate your help.
User Avatar
Member
240 posts
Joined: Oct. 2014
Offline
Cameras are treated as "Relationships" on the settings prims. You have a couple of options:

Using the standard pxr API:

# in a python LOP
stage = hou.pwd().editableStage()
settings_prim = stage.GetPrimAtPath('/path/to/render/settings/prim')
camera_relationship = settings_prim.GetRelationship('camera')
relationship_targets = camera_relationship.GetTargets()
camera_sdfpath = relationship_targets[0]
camera_path = camera_sdfpath.pathString


Or by leveraging the auto-collection "%rendercamera" that SideFX added in H19:

# in a python LOP
node = hou.pwd()
stage = node.editableStage()
ls = hou.LopSelectionRule()
ls.setPathPattern('%rendercamera:/path/to/render/settings/prim')
resolved_paths = ls.expandedPaths(node.inputs()[0])
camera_path = resolved_paths[0] # there can only be one camera relationship anyway, as far as I know
Edited by Tim Crowson - Dec. 27, 2022 12:36:42
- Tim Crowson
Technical/CG Supervisor
User Avatar
Member
20 posts
Joined: Sept. 2015
Offline
thanks Tim, I'll try it.

Merry Christmas to you guys!

Ales
User Avatar
Member
179 posts
Joined: Nov. 2013
Offline
In my second code above, you could change the first line to this, if you don't know what the rendersettings is (I just had a random render settings node as the current node to traverse from)
ancestors = hou.pwd().inputAncestors()
User Avatar
Member
240 posts
Joined: Oct. 2014
Offline
Oh oops, I did that wrong, sorry... I have edited my first example to fix that.
- Tim Crowson
Technical/CG Supervisor
User Avatar
Member
20 posts
Joined: Sept. 2015
Offline
Now both versions works, thank you very much!

Is there easy way how to get LOP node from USD stage primitive? Let's say I wanna find LOP which created /Cameras/camera1 ??

Ales
User Avatar
Member
240 posts
Joined: Oct. 2014
Offline
I don't know, that's a good question. It's entirely possible that there is no camera LOP in the scene, and the camera is loaded from a usd file on disk, via Reference or Sublayer LOP perhaps.

That's the trick with USD and Solaris: Solaris is really a platform for authoring USD content. Sure, you can do other things on top of that, but fundamentally you have two kinds of things to deal with: nodes and prims. Since USD emphasizes loading from disk, the source node that created a prim (as opposed to loading it) may not even exist in the hip file. If you develop a prim-centric workflow, you'll likely be in a safer place, as you won't be dependent on source nodes as much (unless your particular workflow demands it). You'll also be in a better position to ingest USD files from someone else.


EDIT: one thing I miss from Katana is the ability to inspect the history of a given property on a prim. Katana provides a little pop-up on properties that show which nodes have modified them since the top of the graph.... extremely useful... wish we had that.
Edited by Tim Crowson - Dec. 23, 2022 20:01:19
- Tim Crowson
Technical/CG Supervisor
User Avatar
Member
20 posts
Joined: Sept. 2015
Offline
Thanks to Tim's suggestion of using LopSelectionRule() I've discovered this page https://www.sidefx.com/docs/houdini/solaris/pattern.html#syntax [www.sidefx.com] with lots of examples how to use this powerful technique.

It makes really easy to find default camera, rendersettings or renderproduct even without stage object

node = hou.pwd()
ls = hou.LopSelectionRule()

ls.setPathPattern('%rendercamera')
resolved_paths = ls.expandedPaths(node.inputs()[0])
prim_path = resolved_paths[0]
print(prim_path)

ls.setPathPattern('%rendersettings')
resolved_paths = ls.expandedPaths(node.inputs()[0])
prim_path = resolved_paths[0]
print(prim_path)

ls.setPathPattern('%renderproducts')
resolved_paths = ls.expandedPaths(node.inputs()[0])
prim_path = resolved_paths[0]
print(prim_path)
Edited by adlabac - Jan. 2, 2023 06:26:32
  • Quick Links