Loading...
Searching...
No Matches
composeTimeSampleSeries.h
1//
2// Copyright 2026 Pixar
3//
4// Licensed under the terms set forth in the LICENSE.txt file available at
5// https://openusd.org/license.
6//
7#ifndef PXR_USD_SDF_COMPOSE_TIME_SAMPLE_SERIES_H
8#define PXR_USD_SDF_COMPOSE_TIME_SAMPLE_SERIES_H
9
10#include "pxr/pxr.h"
11#include "pxr/usd/sdf/api.h"
12#include "pxr/base/gf/math.h"
13
14PXR_NAMESPACE_OPEN_SCOPE
15
16// The default `timesEqual` function for SdfComposeTimeSampleSeries.
17inline auto Sdf_timesEqualDefaultFn = [](double t1, double t2) {
18 return GfIsClose(t1, t2, 1e-6);
19};
20
42template <class Iter,
43 class GetTimeFn, class GetValueFn,
44 class ComposeFn, class OutputFn,
45 class TimesEqualFn = decltype(Sdf_timesEqualDefaultFn)>
46void
47SdfComposeTimeSampleSeries(
48 Iter strongBegin, Iter strongEnd,
49 Iter weakBegin, Iter weakEnd,
50 GetTimeFn const &getTime,
51 GetValueFn const &getValue,
52 ComposeFn const &composeFn,
53 OutputFn const &outputFn,
54 TimesEqualFn const &timesEqual = Sdf_timesEqualDefaultFn)
55{
56 // If either series is empty, just copy the other.
57 if (weakBegin == weakEnd) {
58 while (strongBegin != strongEnd) {
59 outputFn(getValue(strongBegin), getTime(strongBegin));
60 ++strongBegin;
61 }
62 return;
63 }
64 if (strongBegin == strongEnd) {
65 while (weakBegin != weakEnd) {
66 outputFn(getValue(weakBegin), getTime(weakBegin));
67 ++weakBegin;
68 }
69 return;
70 }
71
72 auto held = [&getTime, &timesEqual](Iter iter, Iter begin, Iter end,
73 double time) {
74 return iter == end || (!timesEqual(
75 getTime(iter), time) && iter != begin)
76 ? std::prev(iter)
77 : iter;
78 };
79
80 constexpr double inf = std::numeric_limits<double>::infinity();
81
82 Iter strongIter = strongBegin;
83 Iter weakIter = weakBegin;
84
85 while (strongIter != strongEnd || weakIter != weakEnd) {
86 const double strongTime =
87 strongIter == strongEnd ? inf : getTime(strongIter);
88 const double weakTime =
89 weakIter == weakEnd ? inf : getTime(weakIter);
90 if (strongTime <= weakTime) {
91 if (auto composed = composeFn(
92 getValue(strongIter),
93 getValue(held(weakIter, weakBegin, weakEnd,
94 strongTime)))) {
95 outputFn(std::move(*composed), strongTime);
96 }
97 else {
98 outputFn(getValue(strongIter), strongTime);
99 }
100 }
101 else {
102 if (auto composed = composeFn(
103 getValue(held(strongIter, strongBegin, strongEnd,
104 weakTime)),
105 getValue(weakIter))) {
106 outputFn(std::move(*composed), weakTime);
107 }
108 else {
109 // Do nothing -- a non-composing stronger sample hides weaker
110 // samples.
111 }
112 }
113
114 // Advance the iterator whose next time is less, or the one that has
115 // samples remaining. If they are both at the same time advance both.
116 if (strongIter == strongEnd) {
117 ++weakIter;
118 }
119 else if (weakIter == weakEnd) {
120 ++strongIter;
121 }
122 else {
123 if (timesEqual(strongTime, weakTime)) {
124 ++strongIter, ++weakIter;
125 }
126 else if (strongTime < weakTime) {
127 ++strongIter;
128 }
129 else {
130 ++weakIter;
131 }
132 }
133 }
134}
135
136PXR_NAMESPACE_CLOSE_SCOPE
137
138#endif // PXR_USD_SDF_COMPOSE_TIME_SAMPLE_SERIES_H
bool GfIsClose(GfColor const &c1, GfColor const &c2, double tolerance)
Tests for equality of the RGB tuple in a color with a given tolerance, returning true if the length o...
Definition: color.h:114
Assorted mathematical utility functions.