Skip to content

Commit

Permalink
Add option to enable interpolation for missing clip values
Browse files Browse the repository at this point in the history
to UsdUtilsStitchClips and UsdUtilsStitchClipsTemplate as
well as usdstitchclips utility.

(Internal change: 2082024)
  • Loading branch information
sunyab authored and pixar-oss committed Jul 7, 2020
1 parent e06f999 commit 92ca995
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 12 deletions.
6 changes: 6 additions & 0 deletions pxr/usd/bin/usdstitchclips/usdstitchclips.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,10 @@
help='specify a named clipSet in which to author clip metadata, so that multiple sets of clips can be applied on the same prim.')
parser.add_argument('--activeOffset', action='store', required=False,
help='specify an offset for template-based clips, offsetting the frame number of each clip file.')
parser.add_argument('--interpolateMissingClipValues', action='store_true',
help=('specify whether values for clips without authored '
'samples are interpolated from surrounding clips '
'if no default value is authored in any clip.'))
# useful for debugging with diffs
parser.add_argument('-n', '--noComment', action='store_true',
help='do not write a comment specifying how the usd file was generated')
Expand Down Expand Up @@ -120,6 +124,7 @@ def _checkMissingTemplateArg(argName, argValue):
results.endTimeCode,
results.stride,
results.activeOffset,
results.interpolateMissingClipValues,
results.clipSet)
else:
if results.templatePath:
Expand All @@ -134,6 +139,7 @@ def _checkMissingTemplateArg(argName, argValue):

UsdUtils.StitchClips(outLayer, results.usdFiles, results.clipPath,
results.startTimeCode, results.endTimeCode,
results.interpolateMissingClipValues,
results.clipSet)


Expand Down
13 changes: 13 additions & 0 deletions pxr/usd/usdUtils/stitchClips.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -727,6 +727,7 @@ namespace {
const SdfPath& clipPath,
const double startTimeCode,
const double endTimeCode,
const bool interpolateMissingClipValues,
const TfToken& clipSet)
{
TfErrorMark errorMark;
Expand All @@ -736,6 +737,12 @@ namespace {
_SetTimeCodeRange(resultLayer, clipPath,
startTimeCode, endTimeCode, clipSet);

if (interpolateMissingClipValues) {
_SetValue(resultLayer, clipPath,
UsdClipsAPIInfoKeys->interpolateMissingClipValues,
interpolateMissingClipValues, clipSet);
}

return errorMark.IsClean();
}

Expand Down Expand Up @@ -831,6 +838,7 @@ UsdUtilsStitchClips(const SdfLayerHandle& resultLayer,
const SdfPath& clipPath,
const double startTimeCode,
const double endTimeCode,
const bool interpolateMissingClipValues,
const TfToken& clipSet)
{
// XXX: See comment in UsdUtilsStitchClipsTopology above.
Expand Down Expand Up @@ -868,6 +876,7 @@ UsdUtilsStitchClips(const SdfLayerHandle& resultLayer,
|| !_UsdUtilsStitchClipsImpl(resultLayer, topologyLayer,
clipLayers, clipPath,
startTimeCode, endTimeCode,
interpolateMissingClipValues,
clipSet)) {
if (!topologyPreExisting) {
TfDeleteFile(topologyLayer->GetIdentifier());
Expand Down Expand Up @@ -906,6 +915,7 @@ UsdUtilsStitchClipsTemplate(const SdfLayerHandle& resultLayer,
const double endTime,
const double stride,
const double activeOffset,
const bool interpolateMissingClipValues,
const TfToken& clipSet)
{
// XXX: See comment in UsdUtilsStitchClipsTopology above.
Expand Down Expand Up @@ -940,6 +950,9 @@ UsdUtilsStitchClipsTemplate(const SdfLayerHandle& resultLayer,
if (activeOffset != std::numeric_limits<double>::max()) {
clipSetDict[UsdClipsAPIInfoKeys->templateActiveOffset] = activeOffset;
}
if (interpolateMissingClipValues) {
clipSetDict[UsdClipsAPIInfoKeys->interpolateMissingClipValues] = true;
}

VtDictionary clips;
clips[clipSet] = clipSetDict;
Expand Down
18 changes: 17 additions & 1 deletion pxr/usd/usdUtils/stitchClips.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,13 @@ SDF_DECLARE_HANDLES(SdfLayer);
/// highest endTimeCode authored from the
/// \p clipLayers.
///
/// \p clipSet The name of the clipSet in which the
/// \p interpolateMissingClipValues
/// Whether values for clips without samples are
/// interpolated from surrounding clips. See
/// UsdClipsAPI::GetInterpolateMissingClipValues
/// for more details.
///
/// \p clipSet The name of the clipSet in which the
/// aforementioned metadata will be authored.
/// \note If this parameter is omitted, the default
/// clipSet name will be authored.
Expand Down Expand Up @@ -114,6 +120,8 @@ UsdUtilsStitchClips(const SdfLayerHandle& resultLayer,
= std::numeric_limits<double>::max(),
const double endTimeCode
= std::numeric_limits<double>::max(),
const bool interpolateMissingClipValues
= false,
const TfToken& clipSet
= UsdClipsAPISetNames->default_);

Expand Down Expand Up @@ -164,6 +172,12 @@ UsdUtilsStitchClipsTopology(const SdfLayerHandle& topologyLayer,
/// \note If this parameter is omitted, no value
/// will be authored as the metadata is optional.
///
/// \p interpolateMissingClipValues
/// Whether values for clips without samples are
/// interpolated from surrounding clips. See
/// UsdClipsAPI::GetInterpolateMissingClipValues
/// for more details.
///
/// \p clipSet The name of the clipSet in which the
/// aforementioned metadata will be authored.
/// \note If this parameter is omitted, the default
Expand All @@ -182,6 +196,8 @@ UsdUtilsStitchClipsTemplate(const SdfLayerHandle& resultLayer,
const double stride,
const double activeOffset
= std::numeric_limits<double>::max(),
const bool interpolateMissingClipValues
= false,
const TfToken& clipSet
= UsdClipsAPISetNames->default_);

Expand Down
13 changes: 9 additions & 4 deletions pxr/usd/usdUtils/testenv/testUsdUtilsStitchClips.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,8 @@ def setUp(self):
rootLayer = Sdf.Layer.FindOrOpen(self.baseName)
self.rootLayer = rootLayer if rootLayer else Sdf.Layer.CreateNew(self.baseName)
UsdUtils.StitchClips(self.rootLayer, self.layerFileNames[0:7],
self.clipPath, self.startTimeCode, self.endTimeCode)
self.clipPath, self.startTimeCode, self.endTimeCode,
interpolateMissingClipValues=True)

self.setupComplete = True

Expand All @@ -83,7 +84,8 @@ def test_ValidClipMetadata(self):
set(['default']))
self.assertEqual(set(clipPrim.GetInfo('clips')['default'].keys()),
set(['times', 'assetPaths', 'primPath',
'manifestAssetPath', 'active']))
'manifestAssetPath', 'active',
'interpolateMissingClipValues']))

def test_ValidUsdLayerGeneration(self):
self.assertTrue(self.rootLayer)
Expand Down Expand Up @@ -192,7 +194,9 @@ def test_CustomSetName(self):
resultLayer = Sdf.Layer.CreateNew('customSetName.usd')
topLayer = Sdf.Layer.CreateNew('customSetName.topology.usd')
UsdUtils.StitchClipsTemplate(resultLayer, topLayer, self.clipPath,
'asset.#.usd', 101, 120, 1, 0.3, 'bob')
'asset.#.usd', 101, 120, 1, 0.3,
interpolateMissingClipValues=True,
clipSet='bob')
self.assertEqual(list(resultLayer.subLayerPaths),
['./customSetName.topology.usd'])
self.assertEqual(resultLayer.endTimeCode, 120)
Expand All @@ -205,7 +209,8 @@ def test_CustomSetName(self):
'templateActiveOffset': 0.3,
'primPath': '/World/fx/Particles_Splash',
'templateAssetPath': 'asset.#.usd',
'templateEndTime': 120.0}
'templateEndTime': 120.0,
'interpolateMissingClipValues': True}

# Ensure that our custom set name applied
actualValues = prim.GetInfo('clips')['bob']
Expand Down
23 changes: 16 additions & 7 deletions pxr/usd/usdUtils/wrapStitchClips.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,15 +55,18 @@ _ConvertStitchClips(const SdfLayerHandle& resultLayer,
const SdfPath& clipPath,
const object pyStartFrame,
const object pyEndFrame,
const object pyInterpolateMissingClipValues,
const object pyClipSet)
{
const auto clipSet
= _ConvertWithDefault(pyClipSet, UsdClipsAPISetNames->default_);
constexpr double dmax = std::numeric_limits<double>::max();
return UsdUtilsStitchClips(resultLayer, clipLayerFiles, clipPath,
_ConvertWithDefault(pyStartFrame, dmax),
_ConvertWithDefault(pyEndFrame, dmax),
clipSet);
return UsdUtilsStitchClips(
resultLayer, clipLayerFiles, clipPath,
_ConvertWithDefault(pyStartFrame, dmax),
_ConvertWithDefault(pyEndFrame, dmax),
_ConvertWithDefault(pyInterpolateMissingClipValues, false),
clipSet);
}

bool
Expand All @@ -88,16 +91,20 @@ _ConvertStitchClipTemplate(const SdfLayerHandle& resultLayer,
const double endFrame,
const double stride,
const object pyActiveOffset,
const object pyInterpolateMissingClipValues,
const object pyClipSet)
{
const auto clipSet
= _ConvertWithDefault(pyClipSet, UsdClipsAPISetNames->default_);
const auto activeOffset
= _ConvertWithDefault(pyActiveOffset,
std::numeric_limits<double>::max());
return UsdUtilsStitchClipsTemplate(resultLayer, topologyLayer,
clipPath, templatePath, startFrame,
endFrame, stride, activeOffset, clipSet);
const auto interpolateMissingClipValues
= _ConvertWithDefault(pyInterpolateMissingClipValues, false);
return UsdUtilsStitchClipsTemplate(
resultLayer, topologyLayer,
clipPath, templatePath, startFrame,
endFrame, stride, activeOffset, interpolateMissingClipValues, clipSet);
}

} // anonymous namespace
Expand All @@ -111,6 +118,7 @@ void wrapStitchClips()
arg("clipPath"),
arg("startFrame")=object(),
arg("endFrame")=object(),
arg("interpolateMissingClipValues")=object(),
arg("clipSet")=object()));

def("StitchClipsTopology",
Expand All @@ -128,6 +136,7 @@ void wrapStitchClips()
arg("endTimeCode"),
arg("stride"),
arg("activeOffset")=object(),
arg("interpolateMissingClipValues")=object(),
arg("clipSet")=object()));

def("GenerateClipTopologyName",
Expand Down

0 comments on commit 92ca995

Please sign in to comment.