# How to set "extent" attribute of custom prim?

**URL:** <https://forum.aousd.org/t/how-to-set-extent-attribute-of-custom-prim/1405>\
**Category:** USD\
**Tags:** cpp\
**Created:** [April 1, 2024, 9:23pm UTC](https://forum.aousd.org/t/how-to-set-extent-attribute-of-custom-prim/1405 "2024-04-01T21:23:19Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![JerryK](https://avatars.discourse-cdn.com/v4/letter/j/b4bc9f/32.png) [@JerryK](https://forum.aousd.org/u/JerryK)\
**Post date:** [April 1, 2024, 9:23pm UTC](https://forum.aousd.org/t/how-to-set-extent-attribute-of-custom-prim/1405/1 "2024-04-01T21:23:19Z")

</div>

Hi, guys  
I created a custom primadapter inherirted from UsdImagingPrimAdapter. I generated some curves in my custom prim. But canot set the extent of the prim. I overrided the GetExtent() method like below. But the extent in usdviewer is still empty. Anyone any idea?

```auto
GfRange3d myPrimAdapter::GetExtent(UsdPrim const& usdPrim, 
                                     SdfPath const& cachePath, 
                                     UsdTimeCode time) const
{
auto myextent=computeMyExtent();
// I print variable myextent here and see the right value.
return myextent;
}

```

I also overrided ComputeExtent method of UsdGeomGprim.

What is the difference of GetExtent in primAdapter and ComputeExtent in UsdGeomGprim?

---

<div class="post-metadata">

**Author:** ![spiff](https://sea2.discourse-cdn.com/flex016/user_avatar/forum.aousd.org/spiff/32/22_2.png) [@spiff](https://forum.aousd.org/u/spiff)\
**Post date:** [April 2, 2024, 10:26pm UTC](https://forum.aousd.org/t/how-to-set-extent-attribute-of-custom-prim/1405/2 "2024-04-02T22:26:12Z")

</div>

The extents displayed by `usdview` have nothing to do with Hydra - they come from the intrinsic notion of extent defined by the UsdGeomBoundable schema class. You’re in uncharted waters trying to add a new geometry type _just_ to usdImaging without basing it on a new “custom” USD schema that you create. If you **do** create a new USD schema, then you can provision your extent computation into your schema’s .cpp file, using [UsdGeomRegisterComputeExtentFunction](https://openusd.org/release/api/boundable_compute_extent_8h.html) - you’ll find examples of how it’s used in the UsdGeom source files.

If you do this, then you won’t need to override the primAdapter’s GetExtent() at all, and clients that use UsdGeomBBoxCache (like usdview) will bound your prims properly.

---

<div class="post-metadata">

**Author:** ![JerryK](https://avatars.discourse-cdn.com/v4/letter/j/b4bc9f/32.png) [@JerryK](https://forum.aousd.org/u/JerryK)\
**Post date:** [April 3, 2024, 8:16pm UTC](https://forum.aousd.org/t/how-to-set-extent-attribute-of-custom-prim/1405/3 "2024-04-03T20:16:21Z")

</div>

Hi Thanks, Sebastian  
I added the ComputeExtent like below. Basically following the cube.cpp in usd source. And I see the “World Bounding Box” has the right value “Min[-1,-1,-1] Max[2,2,2]”. But the “extent” attribute is still empty, why?

```auto
bool
MySchema::ComputeExtent(VtVec3fArray* extent)
{
   extent->resize(2);
   (*extent)[0]=GfVec3f(-1);
   (*extent)[1]=GfVec3f(2);
   std::cout<<"-----------Copmute Non Transform extent..."<<std::endl;
   return true;
}

bool
MySchema::ComputeExtent(const GfMatrix4d& transform,
   VtVec3fArray* extent)
{
   extent->resize(2);
   (*extent)[0]=GfVec3f(-1);
   (*extent)[1]=GfVec3f(2);
   std::cout<<"-----------Copmute Transform extent..."<<std::endl;
   return true;
}

static bool
_ComputeExtent(
   const UsdGeomBoundable& boundable,
   const UsdTimeCode& time,
   const GfMatrix4d* transform,
   VtVec3fArray* extent)
{   
   const MySchema testSchema(boundable);
   if (!TF_VERIFY(testSchema)) {
       return false;
   }

   if (transform) {
       return MySchema::ComputeExtent(*transform, extent);
   } else {
       return MySchema::ComputeExtent(extent);
   }
}

TF_REGISTRY_FUNCTION(UsdGeomBoundable)
{
   UsdGeomRegisterComputeExtentFunction<MySchema>(
       _ComputeExtent);
}

```

---

<div class="post-metadata">

**Author:** ![spiff](https://sea2.discourse-cdn.com/flex016/user_avatar/forum.aousd.org/spiff/32/22_2.png) [@spiff](https://forum.aousd.org/u/spiff)\
**Post date:** [April 3, 2024, 9:00pm UTC](https://forum.aousd.org/t/how-to-set-extent-attribute-of-custom-prim/1405/4 "2024-04-03T21:00:49Z")

</div>

In order to be fast and scalable, USD currently takes the position that “resolving the value of an attribute” (i.e. `UsdAttribute::Get()`) involves no computation other than walking through the “composition graph” of sites that contribute opinions to the property to find the strongest **authored** opinion. Attributes defined by a USD schema can optionally provide a “fallback opinion” that Get() will return when there are no authored opinions (such as a Sphere.radius fallback of 1.0).

But there is no mechanism for attaching general/custom computations to an attribute’s value resolution. As such, the `ComputeExtent()` mechanism that you plugged into is bespoke, and only clients that know about it and opt-in to using it will benefit from it. The UsdGeomBBoxCache and Hydra/UsdImaging both do.

Our nascent OpenExec project will provide us with a way to attach computations to attributes, but we will be very deliberate about where and how we use it in the existing USD schemas, to ensure we retain scalability.

---

<div class="post-metadata">

**Author:** ![JerryK](https://avatars.discourse-cdn.com/v4/letter/j/b4bc9f/32.png) [@JerryK](https://forum.aousd.org/u/JerryK)\
**Post date:** [April 4, 2024, 12:31am UTC](https://forum.aousd.org/t/how-to-set-extent-attribute-of-custom-prim/1405/5 "2024-04-04T00:31:16Z")

</div>

Thank you so much,Sebastian.  
So do you mean currently i cannot set “extent”?  
For the prim type “cube”, I can see the “extent” attribute updates when changing “height”,“radius”. Want to know how it works.

---

<div class="post-metadata">

**Author:** ![spiff](https://sea2.discourse-cdn.com/flex016/user_avatar/forum.aousd.org/spiff/32/22_2.png) [@spiff](https://forum.aousd.org/u/spiff)\
**Post date:** [April 4, 2024, 5:50pm UTC](https://forum.aousd.org/t/how-to-set-extent-attribute-of-custom-prim/1405/6 "2024-04-04T17:50:42Z")

</div>

You can absolutely set extent! And use your computation to do it! So, for a non-time-varying scene you are constructing, once you have added your custom prim and configured the attributes that govern its size, in python you can:

```auto
myPrim.CreateExtentAttr(UsdGeom.Boundable.ComputeExtentFromPlugins(myPrim, Usd.TimeCode.Default()))

```

There is a non-static ComputeExtent() method, but it would be tricky to use if your prim were animated and you needed to cache out extent at multiple timeSamples. The static computation will always give you the accurate result.

---

<div class="post-metadata">

**Author:** ![JerryK](https://avatars.discourse-cdn.com/v4/letter/j/b4bc9f/32.png) [@JerryK](https://forum.aousd.org/u/JerryK)\
**Post date:** [April 5, 2024, 2:33am UTC](https://forum.aousd.org/t/how-to-set-extent-attribute-of-custom-prim/1405/7 "2024-04-05T02:33:25Z")

</div>

Hi Sebastian, maybe I misdescribed my question . By “set extent”, I mean how to make the “extent” attribute in usdviewer non-empty.  
With the static ComputeExtent function, i can set the “World Bounding Box” correctly and the bouding box was also drew correctly in the viewer, but the “extent” attribute is empty. Think they should be the same.  
Below is the screenshot.

 ![extent](https://us1.discourse-cdn.com/flex016/uploads/aousd/original/1X/7ea65446508d7bec292de57019c4658f9ecc5ea6.png)

---

<div class="post-metadata">

**Author:** ![spiff](https://sea2.discourse-cdn.com/flex016/user_avatar/forum.aousd.org/spiff/32/22_2.png) [@spiff](https://forum.aousd.org/u/spiff)\
**Post date:** [April 5, 2024, 6:21am UTC](https://forum.aousd.org/t/how-to-set-extent-attribute-of-custom-prim/1405/8 "2024-04-05T06:21:17Z")

</div>

I understand. The only way to have a non-empty extent attribute in today’s OpenUSD is to explicitly author it in the scene, as I described in my last post (though how your software actually computes it is up to it… you don’t _need_ to use the ComputeExtentFromPlugins method)

---

<div class="post-metadata">

**Author:** ![JerryK](https://avatars.discourse-cdn.com/v4/letter/j/b4bc9f/32.png) [@JerryK](https://forum.aousd.org/u/JerryK)\
**Post date:** [April 5, 2024, 1:08pm UTC](https://forum.aousd.org/t/how-to-set-extent-attribute-of-custom-prim/1405/9 "2024-04-05T13:08:47Z")

</div>

Really appreciate it Sebastian.  
Got a last question. Is it possible to use GetExtent() method in UsdImagingGprimAdapter to compute the extent and make it display in the “World Bounding Box” attribute instead of what I am using now?

---

<div class="post-metadata">

**Author:** ![spiff](https://sea2.discourse-cdn.com/flex016/user_avatar/forum.aousd.org/spiff/32/22_2.png) [@spiff](https://forum.aousd.org/u/spiff)\
**Post date:** [April 5, 2024, 11:01pm UTC](https://forum.aousd.org/t/how-to-set-extent-attribute-of-custom-prim/1405/10 "2024-04-05T23:01:44Z")

</div>

If you’re willing to modify USD source code, you can change [the python computation in usdviewq](https://github.com/PixarAnimationStudios/OpenUSD/blob/dev/pxr/usdImaging/usdviewq/customAttributes.py#L89) that produces the “World Bounding Box” to do whatever you want. I don’t really recommend that, though, and I don’t think Hydra allows you to grab a UsdPrim’s adapter from outside…

---

<div class="post-metadata">

**Author:** ![JerryK](https://avatars.discourse-cdn.com/v4/letter/j/b4bc9f/32.png) [@JerryK](https://forum.aousd.org/u/JerryK)\
**Post date:** [April 6, 2024, 12:08am UTC](https://forum.aousd.org/t/how-to-set-extent-attribute-of-custom-prim/1405/11 "2024-04-06T00:08:02Z")

</div>

Ok, Thank you Sebastian. You are always helpful.

---

<div class="post-metadata">

**Author:** ![JerryK](https://avatars.discourse-cdn.com/v4/letter/j/b4bc9f/32.png) [@JerryK](https://forum.aousd.org/u/JerryK)\
**Post date:** [April 30, 2024, 1:48pm UTC](https://forum.aousd.org/t/how-to-set-extent-attribute-of-custom-prim/1405/12 "2024-04-30T13:48:13Z")

</div>

Hi Spiff  
I got a new question.  
Currently the only way for us to set the World Bounding Box is to provide the bbox data in UsdGeomRegisterComputeExtentFunction in the Schema. But we are generating our points data in Adapter, meanwhile we can get the right bounding box from the points. The question is what is the best way to pass the bounding box data in Adapter to Schema? What we are doing now is save the bouding box data in a global variable like unordered\_map whose key is the prim path and get the data in Schema. The reason for this is I dont want to do the computation(which is expensive) again in Schema just for the bounding box. Do you have any suggestions?

---

<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:** [April 30, 2024, 1:58pm UTC](https://forum.aousd.org/t/how-to-set-extent-attribute-of-custom-prim/1405/13 "2024-04-30T13:58:21Z")

</div>

Hi @JerryK. It’s not uncommon for primitives in OpenUSD to have different granularities of bounding computations with the schema being the “coarsest”. For example, `Mesh` doesn’t apply subdivision surface refinement when computing bounds even though it would likely make the bounds tighter.

Is there a faster / coarser algorithm that could be used for the schema?

---

<div class="post-metadata">

**Author:** ![JerryK](https://avatars.discourse-cdn.com/v4/letter/j/b4bc9f/32.png) [@JerryK](https://forum.aousd.org/u/JerryK)\
**Post date:** [April 30, 2024, 7:51pm UTC](https://forum.aousd.org/t/how-to-set-extent-attribute-of-custom-prim/1405/14 "2024-04-30T19:51:05Z")

</div>

Thank you Matthew, got your point. Will think about it.
