Skip to content

Vex and Lops and USD

Sidefx packed a secret weapon into lops, and that's the lops wrangle node. Vex is able to treat the scene graph as a bunch of data with attributes, just like sops points/prims.

In theory you can modify pretty much anything in lops this way. In practice you'd be mad to do so, but it's a cool trick. More usefully it can save you the cost of an expensive lops -> sops -> lops conversion that you could suffer with a sopmodify, in some cases keeping everything native lops+vex can be dramatically faster.

Like my line elsewhere about 'lops brings houdini to usd, not the other way round', you can't just go setting @P and @Cd, it won't work. You use native usd attributes, some usd specific vex functions, but it's not too much of a changeover.

The lops wrangle has a few (*cough not enough cough*) examples in its presets dropdown, it gives a flavour of how to lopsvex:

  • most attributes can be accessed as you're used to with type-at-symbol; @foo, v@myvec, s[]@stringarray etc
  • while the syntax is familiar, the attribute names are not. @P, @Cd, @N, @v, none of that works here
  • the full list of builtin vex attribs for arrays is here (but also copied below cos I'm lazy like you're lazy) https://www.sidefx.com/docs/houdini/solaris/vex.html#overview
  • the same page lists all the usd helper vex functions sidefx provide. There's loads!
  • A lot of those functions have a slightly confusing syntax. Like vex in mantra, or cvex, these functions can't assume where or how they're being run, so require more info. Often this is a path to a particular node within the lops node network, and also a path a prim in the scene graph tree. The node path might also require an op: prefix, careful now.
  • usd stores 'point' data as arrays, so you need to iterate through them in wrangles, boo
  • the lops wrangle has a 'oh, you have arrays? click this toggle, I'll pretend they're regular attribs', yay
  • for meshes @P is the v@position array, uv's are u@st as an array, color is v@displayColor as an array
  • attribs that are NOT arrays are what you'd probably call detail attributes, stuff that belongs to the 'whole' prim
  • transforms are handled differently, needs more than a bullet point:

If you're manipulating transforms/xforms, usd is using layered matrices and vectors for this. You name the the matrix or vector that represents your modification, and then append it to the xformOpOrder array attribute. Easier to see with an example (ripped from the main Lops page):

float y = sin(@Frame*0.2+@elemnum*0.2);v@xformOp:translate.y = y;append(s[]@xformOpOrder,'xformOp:translate');

Here's the builtin vex attribs. Note the bias towards primpaths, kind of things, rendering, the stuff you'd expect to do for scene graph related operations:

@primpath - Path of the prim, on the stage .@elemnum - Current element number, whether prim or array element.@numelem - Total number of prims or array elements.@primtype - The prim type name.@primkind - A prim’s kind if set.@primname - The name of a primitive.@primpurpose - The display purpose of the current prim.@primdrawmode - The draw mode of the prim.@primactive - Returns whether the current prim is active or deactivated.@primvisible - Returns the visibility of the prim.

Also note that while @Frame is supported, @Time is not. Caught me out!

In terms of doing work, here's how I get things done:

  • Open both a scene graph tree and a scene graph details panel side by side.
  • Select prims, look at the details.
  • Identify which attributes you want to modify.
  • Drag the primpath from the scene graph tree into the primpattern of a wrangle
  • Use the names of attributes directly in the wrangle with the type@ prefix
  • Swear lots when stuff doesn't work
  • If setting array attributes, either use a foreach() loop, or enable the 'array attributes halp' toggle
  • Sometimes attributes have a prefix:label naming format. Sometimes the lops wrangle lets you ignore the prefix, other times it won't. Luckily you can just drop it in, and it'll work, eg @model:applyDrawMode = 1;

You can find more examples on the main lops page: HoudiniLops#Vex

prev: UsdGuide18 this: UsdGuide19 next: main menu: UsdGuide