Skip to content

Commit 7f5e519

Browse files
tallytalwarpixar-oss
authored andcommitted
ValueMightBeTimeVarying now takes splines into account
- Updated UsdStage::_ValueMightBeTimeVaryingFromResolveInfo, which determines if the resolveInfo's source is UsdResolveInfoSourceSpline, in which case it returns true. Do note that we do not inspect the spline itself here to determine if the spline represents a constant in time function, as doing so will be expensive. Our aim is to give the clients a hint that the attribute you are dealing with, "might" be time varying. This is similar to what is done with TimeSamples, where we don't go and inspect every time samples on an attribute to determine if its constant across time or not. - Note that UsdAttributeQuery's ValueMightBeTimeVarying will automatically work since it relies on the UsdStage::_ValueMightBeTimeVaryingFromResolveInfo itself. - Updated testUsdSplines* to test the modified API. (Internal change: 2357151)
1 parent 1e087b6 commit 7f5e519

File tree

4 files changed

+43
-11
lines changed

4 files changed

+43
-11
lines changed

pxr/usd/usd/attribute.h

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ typedef std::vector<UsdAttribute> UsdAttributeVector;
3535
/// \class UsdAttribute
3636
///
3737
/// Scenegraph object for authoring and retrieving numeric, string, and array
38-
/// valued data, sampled over time.
38+
/// valued data, sampled over time, or animated by a spline
3939
///
4040
/// The allowed value types for UsdAttribute are dictated by the Sdf
4141
/// ("Scene Description Foundations") core's data model, which we summarize in
@@ -46,15 +46,15 @@ typedef std::vector<UsdAttribute> UsdAttributeVector;
4646
/// In addition to its value type, an Attribute has two other defining
4747
/// qualities:
4848
/// \li <b>Variability</b> Expresses whether an attribute is intended to
49-
/// have time samples (GetVariability() == \c SdfVariabilityVarying), or only
50-
/// a default (GetVariability() == \c SdfVariabilityUniform). For more on
51-
/// reasoning about time samples,
49+
/// have time samples or a spline (GetVariability() == \c SdfVariabilityVarying),
50+
/// or only a default (GetVariability() == \c SdfVariabilityUniform). For more
51+
/// on reasoning about time samples,
5252
/// see \ref Usd_AttributeValueMethods "Value & Time-Sample Accessors".
5353
///
5454
/// \li <b>Custom</b> Determines whether an attribute belongs to a
5555
/// schema (IsCustom() == \c false), or is a user-defined, custom attribute.
5656
/// schema attributes will always be defined on a prim of the schema type,
57-
/// ans may possess fallback values from the schema, whereas custom
57+
/// and may possess fallback values from the schema, whereas custom
5858
/// attributes must always first be authored in order to be defined. Note
5959
/// that \em custom is actually an aspect of UsdProperty, as UsdRelationship
6060
/// can also be custom or provided by a schema.
@@ -90,6 +90,10 @@ typedef std::vector<UsdAttribute> UsdAttributeVector;
9090
/// The desired behavior may be specified via UsdStage::SetInterpolationType.
9191
/// That behavior will be used for all calls to UsdAttribute::Get.
9292
///
93+
/// Note that for attributes with spline value sources, the interpolation
94+
/// behavior is determined by the spline itself, and the interpolation type
95+
/// set on the stage is ignored.
96+
///
9397
/// The supported interpolation types are:
9498
///
9599
/// \li <b>Held</b> Attribute values are held constant between authored
@@ -169,8 +173,8 @@ class UsdAttribute : public UsdProperty {
169173
/// @{
170174

171175
/// An attribute's variability expresses whether it is intended to have
172-
/// time-samples (\c SdfVariabilityVarying), or only a single default
173-
/// value (\c SdfVariabilityUniform).
176+
/// time-samples or splines (\c SdfVariabilityVarying), or only a single
177+
/// default value (\c SdfVariabilityUniform).
174178
///
175179
/// Variability is required meta-data of all attributes, and its fallback
176180
/// value is SdfVariabilityVarying.
@@ -374,9 +378,10 @@ class UsdAttribute : public UsdProperty {
374378
/// If this function returns false, it is certain that this attribute's
375379
/// value remains constant over time.
376380
///
377-
/// This function is equivalent to checking if GetNumTimeSamples() > 1,
378-
/// but may be more efficient since it does not actually need to get a
379-
/// full count of all time samples.
381+
/// This function checks if the attribute either has more than 1 time
382+
/// samples or is spline valued. Which is more efficient than actually
383+
/// counting the time samples or evaluating the spline, both of which
384+
/// are potentially expensive operations.
380385
USD_API
381386
bool ValueMightBeTimeVarying() const;
382387

pxr/usd/usd/stage.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9397,6 +9397,13 @@ bool
93979397
UsdStage::_ValueMightBeTimeVaryingFromResolveInfo(const UsdResolveInfo &info,
93989398
const UsdAttribute &attr) const
93999399
{
9400+
if (info._source == UsdResolveInfoSourceSpline) {
9401+
// Although a spline could represent a constant function, determining
9402+
// this would require analyzing the spline, which is potentially
9403+
// expensive. Hence, all splines are deemed as possibly time varying.
9404+
return true;
9405+
}
9406+
94009407
if (info._source == UsdResolveInfoSourceValueClips) {
94019408
// Do a specialized check for value clips instead of falling through
94029409
// to calling _GetNumTimeSamplesFromResolveInfo, which requires opening

pxr/usd/usd/testenv/testUsdSplines.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,10 @@ def _DoSerializationTest(
5353
prim = stage.DefinePrim(Sdf.Path("/MyPrim"))
5454
attr = prim.CreateAttribute("myAttr", attrType)
5555
self.assertFalse(attr.HasSpline())
56+
self.assertFalse(attr.ValueMightBeTimeVarying())
5657
attr.SetSpline(spline)
5758
self.assertTrue(attr.HasSpline())
59+
self.assertTrue(attr.ValueMightBeTimeVarying())
5860
print(f"Original spline, {case}, {format}:")
5961
print(spline)
6062

@@ -230,7 +232,11 @@ def _DoLayerOffsetTest(self, case, attrType, timeValued, scale):
230232

231233
prim = stage.DefinePrim(Sdf.Path("/MyPrim"))
232234
attr = prim.CreateAttribute("myAttr", attrType)
235+
self.assertFalse(attr.HasSpline())
236+
self.assertFalse(attr.ValueMightBeTimeVarying())
233237
attr.SetSpline(spline)
238+
self.assertTrue(attr.HasSpline())
239+
self.assertTrue(attr.ValueMightBeTimeVarying())
234240

235241
sdfAttr = deepLayer.GetAttributeAtPath("/MyPrim.myAttr")
236242
sdfSpline = sdfAttr.GetInfo("spline")
@@ -283,6 +289,8 @@ def test_InvalidType(self):
283289
spline = self._GetTestSpline()
284290

285291
gotException = False
292+
self.assertFalse(attr.HasSpline())
293+
self.assertFalse(attr.ValueMightBeTimeVarying())
286294
try:
287295
attr.SetSpline(spline)
288296
except Tf.ErrorException as e:
@@ -291,8 +299,9 @@ def test_InvalidType(self):
291299
print(e)
292300
except:
293301
pass
294-
295302
self.assertTrue(gotException)
303+
self.assertFalse(attr.HasSpline())
304+
self.assertFalse(attr.ValueMightBeTimeVarying())
296305

297306

298307
if __name__ == "__main__":

pxr/usd/usd/testenv/testUsdSplinesCpp.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,8 +114,11 @@ _DoSerializationTest(
114114
const UsdPrim prim = stage->DefinePrim(SdfPath("/MyPrim"));
115115
UsdAttribute attr = prim.CreateAttribute(TfToken("myAttr"), attrType);
116116
TF_AXIOM(!attr.HasSpline());
117+
TF_AXIOM(!attr.ValueMightBeTimeVarying());
117118
attr.SetSpline(spline);
118119
TF_AXIOM(attr.HasSpline());
120+
// Having a spline makes this attr might be time varying.
121+
TF_AXIOM(attr.ValueMightBeTimeVarying());
119122

120123
stage->Save();
121124
stage->GetRootLayer()->Export(filename2);
@@ -158,7 +161,11 @@ _DoLayerOffsetTest(
158161

159162
const UsdPrim prim = stage->DefinePrim(SdfPath("/MyPrim"));
160163
UsdAttribute attr = prim.CreateAttribute(TfToken("myAttr"), attrType);
164+
TF_AXIOM(!attr.HasSpline());
165+
TF_AXIOM(!attr.ValueMightBeTimeVarying());
161166
attr.SetSpline(spline);
167+
TF_AXIOM(attr.HasSpline());
168+
TF_AXIOM(attr.ValueMightBeTimeVarying());
162169

163170
_TestSplineAndAttr(spline, attr);
164171

@@ -362,10 +369,14 @@ TestInvalidType()
362369
const TsSpline spline = _GetTestSpline();
363370

364371
TfErrorMark m;
372+
TF_AXIOM(!attr.HasSpline());
365373
attr.SetSpline(spline);
374+
366375
// A coding error should have been posted as String value splines are not
367376
// allowed. Only double, float or GfHalf!
368377
TF_AXIOM(!m.IsClean());
378+
TF_AXIOM(!attr.HasSpline());
379+
TF_AXIOM(!attr.ValueMightBeTimeVarying());
369380
}
370381

371382
int main()

0 commit comments

Comments
 (0)