I am currently experimenting with a simple constraint implementation using OpenExec. My goal is to create a MyConstraintAPI that can be applied to xformable prims. This API has a relationship with a target xformable prim and ensures that the prim applied with the API moves to the position of the target.
I have successfully retrieved the computed values in an executable file following the USD tutorials. My next step is to ensure these computed values affect renders, specifically within usdview.
I am considering two approaches and would appreciate your guidance.
Building an OpenExec request for the constraints when the scene opens and writing the computed values into the session layer somehow.
Calling ExecUsdRequest::Compute within a UsdImaging adapter to retrieve values and modify transforms directly.
Could you let me know which of these patterns is recommended, or if there is a better alternative?
Option 2 is definitely the preferred direction. In fact, we are going to natively provide that functionality in UsdImaging in the future. You are welcome to experiment on your own until then. Let us know how it goes, and what you learn along the way.
We are also going to deliver a modified version of your option 1 as a core mechanism to enable caching (and cached) workflows: We will eventually allow you to “bake” computed values to USD authored values which can persist across sessions, and then provide the option to switch between baked and live computed results. We are still working out the details of how this should work in practice.
Thank you for the response that sounds like a great direction. I’m looking forward to those updates.
In the meantime, I’ve been implementing the constraint feature using the adapter approach in my current experiment. However, I’m having a difficulty regarding world-flattened transformations during computation. Specifically, I need to process transform attributes according to the xformOpOrder differently from the tutorial computeLocalToWorldTransform, but I’m unsure of the best practice for handling this dynamically. Currently, I am relying on hardcoded default names (e.g., xformOp:translate), which isn’t a good solution.
Do you have any insights or recommended patterns for correctly retrieving these transformations?
Can you help us understand how you’d like to process transform attributes differently from what is provided by the computeLocalToWorldTransform computation?
I’m looking to use OpenExec to process transform attributes (translation, scale, rotation, etc.) in the same way UsdGeomImageable::ComputeLocalToWorldTransform does.
You can see that with the early state that OpenExec is in, we are only registering an input dependency on the xformOp:transform attribute at the moment. We are also not resolving the xformOpOrder.
We are working on a new type of input that will allow you to register an input dependency on all the attributes within a specified namespace prefix (e.g., xformOp:). You will then be able to access those input values in the callback and combine them according to .AttributeValue<TfToken>(_tokens->xformOpOrder)
Once that work has been completed, we will also update the exec computations on UsdGeomXformable and this should just automatically start working for you - assuming you’re computing ExecGeomXformableTokens->computeLocalToWorldTransform through OpenExec to get at the world space transform value for the constraint target, before baking it into xform3.
If you want to continue playing with this, one thing you can do in the meantime is hardcode a superset of potential xform op attribute input values into the computation registration and augment the callback code to access those values as specified in the xformOpOrder input value:
Thank you for the detailed explanation; that clears thigs up for me.
I’m glad to see my understanding of OpenExec was on the right track.
Also, I’m looking forward to the update regarding input dependency resolution, as well as the USD integration you mentioned earlier.
Thanks again!