# Applying transforms to the model - SLOW

**URL:** https://forum.aousd.org/t/applying-transforms-to-the-model-slow/1964
**Category:** USD
**Tags:** cpp
**Created:** [November 3, 2024, 9:40pm UTC](https://forum.aousd.org/t/applying-transforms-to-the-model-slow/1964 "2024-11-03T21:40:05Z")
**Posts on this page:** 7
**Page:** 1

<div class="post-metadata">

### Author: ![hateom](https://sea2.discourse-cdn.com/flex016/user_avatar/forum.aousd.org/hateom/32/596_2.png) [@hateom](https://forum.aousd.org/u/hateom)
#### Post date: [November 3, 2024, 9:40pm UTC](https://forum.aousd.org/t/applying-transforms-to-the-model-slow/1964/1 "2024-11-03T21:40:06Z")

</div>

Hello,

I am trying to build an interactive application to render USD models and I have translate/rotate parameters that I want to update in real time.  
I apply the transformations to the model like this:

```auto
auto modelPrim = m_model->GetDefaultPrim();
// Create rotation matrices using GfRotation and GfMatrix4d
GfRotation rotX(GfVec3d(1.0, 0.0, 0.0), orx);
GfRotation rotY(GfVec3d(0.0, 1.0, 0.0), ory);
GfRotation rotZ(GfVec3d(0.0, 0.0, 1.0), orz);

// Initialize transformation matrices
GfMatrix4d rotXMat;
rotXMat.SetRotate(rotX);

GfMatrix4d rotYMat;
rotYMat.SetRotate(rotY);

GfMatrix4d rotZMat;
rotZMat.SetRotate(rotZ);

// Create translation matrix
GfMatrix4d translateMat;
translateMat.SetTranslate(GfVec3d(opx, opy, opz));

GfMatrix4d lt = rotZMat * rotYMat * rotXMat * translateMat;

UsdGeomXformable xf(modelPrim);

// Clear existing transform ops if necessary
xf.ClearXformOpOrder();

// Add a Transform op
UsdGeomXformOp transformOp = xf.AddTransformOp(UsdGeomXformOp::PrecisionDouble);
transformOp.Set(lt);

m_engine->Render(m_model->GetPseudoRoot(), params);

```

The problem is that for an average size model this takes **SECONDS**! It’s super slow and I am not sure why… What’s the correct way of doing this?

---

<div class="post-metadata">

### Author: ![denglesson](https://sea2.discourse-cdn.com/flex016/user_avatar/forum.aousd.org/denglesson/32/600_2.png) [@denglesson](https://forum.aousd.org/u/denglesson)
#### Post date: [November 4, 2024, 7:40am UTC](https://forum.aousd.org/t/applying-transforms-to-the-model-slow/1964/2 "2024-11-04T07:40:48Z")

</div>

Hi @hateom That sounds odd. It should update very fast to set transforms.  
I have found that this is invaluable to use the trace api to investigate slowdowns. [Universal Scene Description: Trace: Performance tracking](https://openusd.org/release/api/trace_page_front.html)

I might be wrong here but Isn’t the Render call just suppose to be setup once in the initialisation face of your program? Perhaps that is the reason it is slow?

---

<div class="post-metadata">

### Author: ![dhruvgovil](https://sea2.discourse-cdn.com/flex016/user_avatar/forum.aousd.org/dhruvgovil/32/3_2.png) [@dhruvgovil](https://forum.aousd.org/u/dhruvgovil)
#### Post date: [November 4, 2024, 8:59am UTC](https://forum.aousd.org/t/applying-transforms-to-the-model-slow/1964/3 "2024-11-04T08:59:32Z")

</div>

Have you tried profiling it to see where the performance impact is greatest? Also just to confirm that you’re using a release/O2 build?

---

<div class="post-metadata">

### Author: ![asluk](https://sea2.discourse-cdn.com/flex016/user_avatar/forum.aousd.org/asluk/32/771_2.png) [@asluk](https://forum.aousd.org/u/asluk)
#### Post date: [November 4, 2024, 5:47pm UTC](https://forum.aousd.org/t/applying-transforms-to-the-model-slow/1964/4 "2024-11-04T17:47:58Z")

</div>

I would not recommend calling ClearXformOpOrder and AddTransformOp on every frame update-- that is probably triggering prim resyncs and blowing various caches. Would set up the transformOp once and update just its value.

If you’re updating multiple transforms per frame, you’ll want to use an SdfChangeBlock to batch the change notifications for all of them - [USD-Cookbook/features/sdf\_change\_block at master · ColinKennedy/USD-Cookbook · GitHub](https://github.com/ColinKennedy/USD-Cookbook/tree/master/features/sdf_change_block)

---

<div class="post-metadata">

### Author: ![nvmkuruc](https://avatars.discourse-cdn.com/v4/letter/n/76d3ee/32.png) [@nvmkuruc](https://forum.aousd.org/u/nvmkuruc)
#### Post date: [November 4, 2024, 6:05pm UTC](https://forum.aousd.org/t/applying-transforms-to-the-model-slow/1964/5 "2024-11-04T18:05:18Z")

</div>

To build on Aaron’s suggestion, you can pay attention to the notices that your edits are triggering.

[Resync](https://openusd.org/dev/api/class_usd_notice_1_1_objects_changed.html#a793e3d781e6e01889a0ba8d789c09102) notices indicate a topology change to the scene.

[Changed Info Only](https://openusd.org/dev/api/class_usd_notice_1_1_objects_changed.html#ab939047696102fb8ff522b5bbcaeb274) notices generally indicate a simple value change and listeners can take a more optimal path.

---

<div class="post-metadata">

### Author: ![nporcino](https://avatars.discourse-cdn.com/v4/letter/n/3d9bf3/32.png) [@nporcino](https://forum.aousd.org/u/nporcino)
#### Post date: [November 4, 2024, 6:36pm UTC](https://forum.aousd.org/t/applying-transforms-to-the-model-slow/1964/6 "2024-11-04T18:36:48Z")

</div>

A simple check to see if you’ve already got a transform op that can be overwritten might also be helpful.

```auto
    auto op = geom.GetTransformOp();
    if (op.GetOpType() != UsdGeomXformOp::TypeTransform) {
        geom.ClearXformOpOrder(); // clear the local transform stack
        geom.AddTransformOp().Set(localOffset);
    }
    else {
        op.Set(localOffset, tc);
    }

```

---

<div class="post-metadata">

### Author: ![hateom](https://sea2.discourse-cdn.com/flex016/user_avatar/forum.aousd.org/hateom/32/596_2.png) [@hateom](https://forum.aousd.org/u/hateom)
#### Post date: [November 4, 2024, 9:12pm UTC](https://forum.aousd.org/t/applying-transforms-to-the-model-slow/1964/7 "2024-11-04T21:12:21Z")

</div>

Thanks @nporcino - your code helps a little, but still, when I call op.Set(…), the next m\_engine-\>Render(…) takes ~600ms, where it takes less than 1ms otherwise.  
I am testing with the Kitchen Set model.  
So I guess it invalidates the cache anyway and some recalculation is happening. Will try to check what happens exactly… but will probably need a different way of doing this.

The main reason I am doing this is that I manually add child prim to the model which is a X/Z plane grid. When I apply transforms to the model I want to be able to translate/rotate the model and keep the X/Z grid in place.

Without the grid I could simply modify the camera matrix passed as argument to the Render function.

Perhaps I need to create a separate grid model and render twice with different camera matrices?

Below the result where grid stays in original position/rotation and the Kitchen scene rotated/translated by some arbitrary values.

 ![CleanShot 2024-11-04 at 22.13.55@2x](https://us1.discourse-cdn.com/flex016/uploads/aousd/original/1X/1cdd9a61d9054c949635b39c4e0adeab2fe58ca1.jpeg)
