editableStage() does not work in Expression context

   2799   14   1
User Avatar
Member
75 posts
Joined: Dec. 2017
Offline
editableStage() does not work in Expression context, its return value is None.

Or maybe there are other ways to read the attributes of LOPs USD primitive in Expression?

Attachments:
Expression_bug.jpg (94.3 KB)

User Avatar
Member
75 posts
Joined: Dec. 2017
Offline
I found it doesn't work in python shell either, am I doing something wrong?

Attachments:
Expression_bug_2.jpg (10.7 KB)

User Avatar
Member
7771 posts
Joined: Sept. 2011
Offline
only the python lop has an editable stage. I think you just want stage?
User Avatar
Member
75 posts
Joined: Dec. 2017
Offline
jsmack
only the python lop has an editable stage. I think you just want stage?
I want to read a attribute on a certain usd primitive to use in a channel,how should I do?
Looking through the API documentation, using editableStage() seems to be the only way.
Edited by ysysimon - July 18, 2022 21:36:07
User Avatar
Member
8555 posts
Joined: July 2007
Offline
there are 2 issues with your expression

1. you are trying to get stage of the current node, which would cause a recursion since the expression needs to cook to get that stage and the expression needs the stage to cook
(it's the same issue as if you tried to evaluate current node's geometry in SOPs)

2. as mentioned before, you can't use .editableStage() and there is no need to as you can't and don't want to edit it
use .stage()

so your expression would be something like this:
lopNode = hou.pwd().inputs()[0]
stage = lopNode.stage()
print(stage)
Tomas Slancik
FX Supervisor
Method Studios, NY
User Avatar
Member
7771 posts
Joined: Sept. 2011
Offline
ysysimon
jsmack
only the python lop has an editable stage. I think you just want stage?
I want to read a attribute on a certain usd primitive to use in a channel,how should I do?
Looking through the API documentation, using editableStage() seems to be the only way.

I would say don't. The USD python api is so opaque and arcane that simply getting an attribute value is an exercise in frustration. The objects that represent attributes and primvars don't themselves have methods for evaluation. The only way I've found to even evaluate a property is to use Sidefx' husd module for 'GetValue'. I still haven't found the Pixar way to get an attribute value. Keep in mind that referencing an attribute value could mean introducing a time dependency.
User Avatar
Member
273 posts
Joined: Nov. 2013
Offline
Apologies if I'm misunderstanding, but the generic way to read an attribute is

prim.GetAttribute("primvars:displayColor").Get(timecode)

and when possible, the recommended way is to utilize the schema that owns the attribute e.g

from pxr import UsdGeom
UsdGeom.Gprim(prim).GetDisplayColorAttr().Get(timecode)
Edited by antc - July 19, 2022 05:59:19
User Avatar
Member
240 posts
Joined: Oct. 2014
Offline
Yeah that's what I do (antc)... we have expressions that query attributes on USD prims this way and it's fine.

(Well technically the expression is triggering a python module on an HDA, but the same code works directly in an expression)
Edited by Tim Crowson - July 19, 2022 12:58:30
- Tim Crowson
Technical/CG Supervisor
User Avatar
Member
75 posts
Joined: Dec. 2017
Offline
antc
Apologies if I'm misunderstanding, but the generic way to read an attribute is

prim.GetAttribute("primvars:displayColor").Get(timecode)

and when possible, the recommended way is to utilize the schema that owns the attribute e.g

from pxr import UsdGeom
UsdGeom.Gprim(prim).GetDisplayColorAttr().Get(timecode)

sorry I don't get it, how should I get the prim object?

And actually I want to get the local Transform, it's a Computed Value as I know, so I checked the USD API doc, but didn't find any way to get prim's GfTransform object.
User Avatar
Member
75 posts
Joined: Dec. 2017
Offline
Tim Crowson
Yeah that's what I do (antc)... we have expressions that query attributes on USD prims this way and it's fine.

(Well technically the expression is triggering a python module on an HDA, but the same code works directly in an expression)

that's means I don't need to get the stage to read the attribute?
User Avatar
Member
75 posts
Joined: Dec. 2017
Offline
tamte
there are 2 issues with your expression

1. you are trying to get stage of the current node, which would cause a recursion since the expression needs to cook to get that stage and the expression needs the stage to cook
(it's the same issue as if you tried to evaluate current node's geometry in SOPs)

2. as mentioned before, you can't use .editableStage() and there is no need to as you can't and don't want to edit it
use .stage()

so your expression would be something like this:
lopNode = hou.pwd().inputs()[0]
stage = lopNode.stage()
print(stage)

ok, it worked, thank u, but is stage() means the stage it get from is read only?
User Avatar
Member
75 posts
Joined: Dec. 2017
Offline
jsmack
ysysimon
jsmack
only the python lop has an editable stage. I think you just want stage?
I want to read a attribute on a certain usd primitive to use in a channel,how should I do?
Looking through the API documentation, using editableStage() seems to be the only way.

I would say don't. The USD python api is so opaque and arcane that simply getting an attribute value is an exercise in frustration. The objects that represent attributes and primvars don't themselves have methods for evaluation. The only way I've found to even evaluate a property is to use Sidefx' husd module for 'GetValue'. I still haven't found the Pixar way to get an attribute value. Keep in mind that referencing an attribute value could mean introducing a time dependency.

Yeah, true, it's a new things just come out, not too much information about USD, but I think that's why we need to dive into it to give more information to the later.

Thanks for the reminder about time dependency, I've thought about it.
User Avatar
Member
8555 posts
Joined: July 2007
Offline
ysysimon
ok, it worked, thank u, but is stage() means the stage it get from is read only?
correct, you can't edit the stage using python unless you are in Python Script LOP
if every expression tried to edit the stage of any LOP node it would be a dependency nightmare

I thought you just need to sample the input stage for values or whatever that you want to compute your final expression value from
there is no other reason to use it in expression usually

if you need to directly modify the stage use Python Script LOP or Attribute Wrangle LOP or something similar
Edited by tamte - July 19, 2022 17:15:48
Tomas Slancik
FX Supervisor
Method Studios, NY
User Avatar
Member
75 posts
Joined: Dec. 2017
Offline
Thanks guys, I think I have the answer, in the ocean deep USD API documentation I found PrimvarsAPI for reading Primvar and XformCommonAPI for reading Xform
User Avatar
Member
273 posts
Joined: Nov. 2013
Offline
Use stage.GetPrimAtPath(primPath) to get the UsdPrim you need.
  • Quick Links