Loading...
Searching...
No Matches
computationBuilders.h
Go to the documentation of this file.
1//
2// Copyright 2025 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_EXEC_EXEC_COMPUTATION_BUILDERS_H
8#define PXR_EXEC_EXEC_COMPUTATION_BUILDERS_H
9
18
19#include "pxr/pxr.h"
20
21#include "pxr/exec/exec/api.h"
22#include "pxr/exec/exec/builtinComputations.h"
25#include "pxr/exec/exec/types.h"
26
27#include "pxr/base/tf/token.h"
28#include "pxr/base/tf/type.h"
29#include "pxr/base/vt/traits.h"
30#include "pxr/base/vt/value.h"
32#include "pxr/exec/vdf/traits.h"
33#include "pxr/usd/sdf/path.h"
34
35#include <memory>
36#include <string>
37#include <type_traits>
38#include <utility>
39
40PXR_NAMESPACE_OPEN_SCOPE
41
42struct Exec_InputKey;
43
44
114
123
144
161
175
185
194
195
200{
201 Prim = 1 << 0,
202 Attribute = 1 << 1,
203 Any = 0xff
204};
205
206constexpr bool operator&(
209{
210 return static_cast<unsigned char>(a) & static_cast<unsigned char>(b);
211}
212
213template <Exec_ComputationBuilderProviderTypes allowed>
214struct Exec_ComputationBuilderComputationValueSpecifier;
215
216// Common base class for value specifiers and object accessors.
217class Exec_ComputationBuilderCommonBase
218{
219protected:
220 // Returns a value specifier for computing a metadata value.
221 template <Exec_ComputationBuilderProviderTypes allowed>
222 EXEC_API
223 static Exec_ComputationBuilderComputationValueSpecifier<allowed>
224 _GetMetadataValueSpecifier(
225 const TfType resultType,
226 const SdfPath &localTraversal,
227 const TfToken &metadataKey);
228};
229
230// Untemplated value specifier base class.
231//
232// This class builds up an Exec_InputKey that specifies how to source an input
233// value at exec compilation time.
234//
235class Exec_ComputationBuilderValueSpecifierBase
236 : public Exec_ComputationBuilderCommonBase
237{
238public:
239 EXEC_API
240 Exec_ComputationBuilderValueSpecifierBase(
241 const TfToken &computationName,
242 TfType resultType,
243 ExecProviderResolution &&providerResolution,
244 const TfToken &inputName,
245 const TfToken &disambiguatingId);
246
247 EXEC_API
248 Exec_ComputationBuilderValueSpecifierBase(
249 const Exec_ComputationBuilderValueSpecifierBase&);
250
251 EXEC_API
252 ~Exec_ComputationBuilderValueSpecifierBase();
253
254protected:
255 EXEC_API
256 void _SetInputName(const TfToken &inputName);
257
258 EXEC_API
259 void _SetOptional (const bool optional);
260
261 EXEC_API
262 void _SetFallsBackToDispatched(bool fallsBackToDispatched);
263
264private:
265 // Only computation builders can get the input key.
266 friend class Exec_ComputationBuilderBase;
267
268 EXEC_API
269 void _GetInputKey(Exec_InputKey *inputKey) const;
270
271private:
272 // We PIMPL the data for this class to avoid exposing more private details
273 // in this public header.
274 struct _Data;
275 const std::unique_ptr<_Data> _data;
276};
277
278// A value specifier that requests a constant value, valid on a prim or
279// attribute computation
280//
281struct Exec_ComputationBuilderConstantValueSpecifier final
282 : public Exec_ComputationBuilderValueSpecifierBase
283{
284 static constexpr Exec_ComputationBuilderProviderTypes allowedProviders =
285 Exec_ComputationBuilderProviderTypes::Any;
286
287 EXEC_API
288 Exec_ComputationBuilderConstantValueSpecifier(
289 const TfType resultType,
290 const SdfPath &localTraversal,
291 const TfToken &inputName,
292 VtValue &&constantValue);
293};
294
295// A value specifier that requests the value of a computation.
296//
297// The template parameter determines which types of providers the input
298// registration is allowed to be used on.
299//
300template <Exec_ComputationBuilderProviderTypes allowed>
301struct Exec_ComputationBuilderComputationValueSpecifier
302 : public Exec_ComputationBuilderValueSpecifierBase
303{
304 Exec_ComputationBuilderComputationValueSpecifier(
305 const TfToken &computationName,
306 const TfType resultType,
307 ExecProviderResolution &&providerResolution,
308 const TfToken &disambiguatingId = TfToken())
309 : Exec_ComputationBuilderValueSpecifierBase(
310 computationName, resultType,
311 std::move(providerResolution),
312 computationName /* inputName */,
313 disambiguatingId)
314 {
315 }
316
317 using This = Exec_ComputationBuilderComputationValueSpecifier<allowed>;
318
319 static constexpr Exec_ComputationBuilderProviderTypes allowedProviders =
320 allowed;
321
324
346 This&
347 InputName(const TfToken &inputName)
348 {
349 _SetInputName(inputName);
350 return *this;
351 }
352
375 This&
377 {
378 _SetOptional(false);
379 return *this;
380 }
381
414 This&
416 {
417 _SetFallsBackToDispatched(true);
418 return *this;
419 }
420
422};
423
424
425// Untemplated object accessor base class.
426struct Exec_ComputationBuilderAccessorBase
427 : public Exec_ComputationBuilderCommonBase
428{
429
430 Exec_ComputationBuilderAccessorBase(const SdfPath &localTraversal)
431 : _localTraversal(localTraversal)
432 {
433 }
434
435protected:
436 const SdfPath &_GetLocalTraversal() const {
437 return _localTraversal;
438 }
439
440private:
441 // The relative path used for the first phase of provider resolution.
442 SdfPath _localTraversal;
443};
444
445// Untemplated base class for accessors used to provide constant values as
446// computation inputs.
447//
448struct Exec_ComputationBuilderConstantAccessorBase
449 : public Exec_ComputationBuilderAccessorBase
450{
451 // We specialize the InputName() accessor because it is required for
452 // constant values. I.e., Constant() returns an accessor, and the
453 // InputName() option must be used to generate a value specifier.
454 //
455 Exec_ComputationBuilderConstantValueSpecifier
456 InputName(const TfToken &inputName) &&
457 {
458 return Exec_ComputationBuilderConstantValueSpecifier(
459 _valueType,
460 _GetLocalTraversal(),
461 inputName,
462 std::move(_constantValue));
463 }
464
465protected:
466 EXEC_API
467 Exec_ComputationBuilderConstantAccessorBase(
468 VtValue &&constantValue,
469 TfType valueType);
470
471private:
472 VtValue _constantValue;
473 const TfType _valueType;
474};
475
482template <Exec_ComputationBuilderProviderTypes allowed>
484 : public Exec_ComputationBuilderAccessorBase
485{
486 Exec_ComputationBuilderAccessor(const SdfPath &localTraversal)
487 : Exec_ComputationBuilderAccessorBase(localTraversal)
488 {
489 }
490
491 using ValueSpecifier =
492 Exec_ComputationBuilderComputationValueSpecifier<allowed>;
493
496
498 template <typename ResultType>
499 ValueSpecifier
500 Computation(const TfToken &computationName)
501 {
502 static_assert(!VtIsArray<ResultType>::value,
503 "VtArray is not a supported result type.");
504
505 return ValueSpecifier(
506 computationName,
507 ExecTypeRegistry::GetInstance().CheckForRegistration<ResultType>(),
508 {_GetLocalTraversal(),
510 }
511
513 template <typename ResultType>
514 ValueSpecifier
515 IncomingConnections(const TfToken &computationName)
516 {
517 return ValueSpecifier(
518 computationName,
519 ExecTypeRegistry::GetInstance().CheckForRegistration<ResultType>(),
520 {Exec_ComputationBuilderAccessorBase::_GetLocalTraversal(),
521 ExecProviderResolution::DynamicTraversal::
522 IncomingConnectionOwningAttributes});
523 }
524
526 template <typename ResultType>
527 ValueSpecifier
528 Metadata(const TfToken &metadataKey)
529 {
530 static_assert(!VtIsArray<ResultType>::value,
531 "VtArray is not a supported result type.");
532
533 return _GetMetadataValueSpecifier<allowed>(
534 ExecTypeRegistry::GetInstance().CheckForRegistration<ResultType>(),
535 _GetLocalTraversal(),
536 metadataKey);
537 }
538
540};
541
543template <Exec_ComputationBuilderProviderTypes allowed>
552
554template <Exec_ComputationBuilderProviderTypes allowed>
557{
560 {
561 }
562
563 using ValueSpecifier =
564 Exec_ComputationBuilderComputationValueSpecifier<allowed>;
565
568
570 template <typename ResultType>
571 ValueSpecifier
572 Connections(const TfToken &computationName)
573 {
574 return ValueSpecifier(
575 computationName,
576 ExecTypeRegistry::GetInstance().CheckForRegistration<ResultType>(),
577 {Exec_ComputationBuilderAccessorBase::_GetLocalTraversal(),
578 ExecProviderResolution::DynamicTraversal::
579 ConnectionTargetedObjects});
580 }
581
583
584 // XXX:TODO
585 // Accessors for AnimSpline, etc.
586};
587
589template <Exec_ComputationBuilderProviderTypes allowed>
592{
595 {
596 }
597
598 using ValueSpecifier =
599 Exec_ComputationBuilderComputationValueSpecifier<allowed>;
600
603
634 template <typename ResultType>
635 ValueSpecifier
636 TargetedObjects(const TfToken &computationName)
637 {
638 return ValueSpecifier(
639 computationName,
640 ExecTypeRegistry::GetInstance().CheckForRegistration<ResultType>(),
641 {Exec_ComputationBuilderAccessorBase::_GetLocalTraversal(),
642 ExecProviderResolution::DynamicTraversal::
643 RelationshipTargetedObjects});
644 }
645
647};
648
649
650// The following registrations are in the exec_registration namespace so that
651// the registration macro can make them available (without the namespace) as
652// arguments to registrations methods (i.e., Inputs()).
653namespace exec_registration {
654
655
657struct Attribute final
659 Exec_ComputationBuilderProviderTypes::Prim>
660{
663
686 Attribute(const TfToken &attributeName)
689 SdfPath::ReflexiveRelativePath().AppendProperty(attributeName))
690 {
691 }
692
694};
695
696
698struct Relationship final
700 Exec_ComputationBuilderProviderTypes::Prim>
701{
704
711 Relationship(const TfToken &relationshipName)
714 SdfPath::ReflexiveRelativePath().AppendProperty(
715 relationshipName))
716 {
717 }
718
720};
721
722
724struct Prim final
726 Exec_ComputationBuilderProviderTypes::Attribute>
727{
730
758
761 Exec_ComputationBuilderProviderTypes::Attribute>
762 Attribute(const TfToken &attributeName)
763 {
765 Exec_ComputationBuilderProviderTypes::Attribute>(
766 SdfPath("..").AppendProperty(attributeName));
767 }
768
771 Exec_ComputationBuilderProviderTypes::Attribute>
772 Relationship(const TfToken &relationshipName)
773 {
775 Exec_ComputationBuilderProviderTypes::Attribute>(
776 SdfPath("..").AppendProperty(relationshipName));
777 }
778
780
783
785 template <typename ValueType>
786 auto
787 AttributeValue(const TfToken &attributeName)
788 {
789 return Attribute(attributeName)
790 .Computation<ValueType>(ExecBuiltinComputations->computeValue)
791 .InputName(attributeName);
792 }
793
795};
796
797
799struct Stage final
801 Exec_ComputationBuilderProviderTypes::Any>
802{
805
833 SdfPath::AbsoluteRootPath())
834 {
835 }
836
838};
839
840// XXX:TODO
841// Property, NamespaceParent, NamespaceChildren, etc.
842
843
845template <typename ResultType>
846struct Computation final
847 : public Exec_ComputationBuilderComputationValueSpecifier<
848 Exec_ComputationBuilderProviderTypes::Any>
849{
852
877 Computation(const TfToken &computationName)
878 : Exec_ComputationBuilderComputationValueSpecifier<
880 computationName,
881 ExecTypeRegistry::GetInstance().
882 CheckForRegistration<ResultType>(),
885 {
886 }
887
889};
890
892template <typename ValueType>
893struct Metadata final
894 : public Exec_ComputationBuilderComputationValueSpecifier<
895 Exec_ComputationBuilderProviderTypes::Any>
896{
899
919 Metadata(const TfToken &metadataKey)
920 : Exec_ComputationBuilderComputationValueSpecifier<
922 _GetMetadataValueSpecifier<allowedProviders>(
923 ExecTypeRegistry::GetInstance()
924 .CheckForRegistration<ValueType>(),
925 SdfPath::ReflexiveRelativePath(),
926 metadataKey))
927 {
928 static_assert(!VtIsArray<ValueType>::value,
929 "VtArray is not a supported result type.");
930
931 InputName(metadataKey);
932 }
933
935};
936
937// Constant accessor
938template <typename ValueType>
939struct Constant final
940 : public Exec_ComputationBuilderConstantAccessorBase
941{
944
1044 ValueType &&constantValue)
1045 : Exec_ComputationBuilderConstantAccessorBase(
1046 VtValue(std::move(constantValue)),
1047 ExecTypeRegistry::GetInstance().
1048 CheckForRegistration<ValueType>())
1049 {
1050 static_assert(
1051 !std::is_same_v<std::decay_t<ValueType>, char*> &&
1052 !std::is_same_v<std::decay_t<ValueType>, const char*>,
1053 "Must use std::string to represent string literal types.");
1054 static_assert(
1056 "Types used to provide constant input values must be hashable.");
1057 }
1058
1059 Constant(
1060 const ValueType &constantValue)
1061 : Exec_ComputationBuilderConstantAccessorBase(
1062 VtValue(constantValue),
1063 ExecTypeRegistry::GetInstance().
1064 CheckForRegistration<ValueType>())
1065 {
1066 static_assert(
1067 !std::is_same_v<std::decay_t<ValueType>, char*> &&
1068 !std::is_same_v<std::decay_t<ValueType>, const char*>,
1069 "Must use std::string to represent string literal types.");
1070 static_assert(
1072 "Types used to provide constant input values must be hashable.");
1073 }
1074
1076};
1077
1078// Deduction guides that ensure std::string is the value type used to store
1079// character string literals.
1080Constant(const char *) -> Constant<std::string>;
1081Constant(char *) -> Constant<std::string>;
1082
1083
1084// XXX:TODO
1085// This should be implemented as an alias for an accessor that takes a predicate
1086// plus .Compute(), but that requires implementing predicates plus having a way
1087// to express the computation name and result type as computation parameters.
1088// Therefore, for now, this is implemented as a value specifier.
1089template <typename ResultType>
1090struct NamespaceAncestor final
1091 : public Exec_ComputationBuilderComputationValueSpecifier<
1092 Exec_ComputationBuilderProviderTypes::Prim>
1093{
1096
1124 NamespaceAncestor(const TfToken &computationName)
1125 : Exec_ComputationBuilderComputationValueSpecifier<
1127 computationName,
1128 ExecTypeRegistry::GetInstance().
1129 CheckForRegistration<ResultType>(),
1132 {
1133 }
1134
1136};
1137
1138// XXX:TODO
1139// AnimSpline
1140
1141
1144
1145// Note:
1146// Aliases are implemented as generator functions, rather than as structs,
1147// because that way they can simply be expressed as registrations.
1148
1184template <typename ValueType>
1185auto
1186AttributeValue(const TfToken &attributeName)
1187{
1188 return Attribute(attributeName)
1189 .Computation<ValueType>(ExecBuiltinComputations->computeValue)
1190 .InputName(attributeName);
1191}
1192
1194
1197
1233template <typename ResultType>
1234auto
1235Connections(const TfToken &computationName)
1236{
1237 return Exec_ComputationBuilderComputationValueSpecifier<
1238 Exec_ComputationBuilderProviderTypes::Attribute>(
1239 computationName,
1242 ExecProviderResolution::DynamicTraversal::
1243 ConnectionTargetedObjects});
1244}
1245
1284template <typename ResultType>
1285auto
1286IncomingConnections(const TfToken &computationName)
1287{
1288 return Exec_ComputationBuilderComputationValueSpecifier<
1289 Exec_ComputationBuilderProviderTypes::Any>(
1290 computationName,
1293 ExecProviderResolution::DynamicTraversal::
1294 IncomingConnectionOwningAttributes});
1295}
1296
1298
1299} // namespace exec_registration
1300
1301
1302// We forward declare these classes so the generated documentation for
1303// PrimComputation(), AttributeComputation(), and AttributeExpression() comes
1304// before the Callback() and Inputs() docs.
1305//
1309
1314{
1315 EXEC_API
1316 ExecComputationBuilder(TfType schemaType);
1317
1318public:
1319 EXEC_API
1321
1322 // Allows access to the constructor.
1323 //
1324 // Only schema computation registration functions should create computation
1325 // builders.
1326 struct ConstructionAccess {
1327 EXEC_API
1329 Construct(const std::string &schemaTypeName);
1330 };
1331
1334
1348 EXEC_API
1350 PrimComputation(const TfToken &computationName);
1351
1368 EXEC_API
1371 const TfToken &attributeName,
1372 const TfToken &computationName);
1373
1415 EXEC_API
1417 AttributeExpression(const TfToken &attributeName);
1418
1468 template <class... DispatchedOntoSchemaTypes>
1471 const TfToken &computationName,
1472 DispatchedOntoSchemaTypes &&...schemaTypes);
1473
1474 // overload that takes a vector of TfTypes
1475 EXEC_API
1478 const TfToken &computationName,
1479 ExecDispatchesOntoSchemas &&ontoSchemas);
1480
1513 template <class... DispatchedOntoSchemaTypes>
1516 const TfToken &computationName,
1517 DispatchedOntoSchemaTypes &&...schemaTypes);
1518
1519 // overload that takes a vector of TfTypes
1520 EXEC_API
1523 const TfToken &computationName,
1524 ExecDispatchesOntoSchemas &&ontoSchemas);
1525
1527
1528private:
1529 // The type of the schema for which this builder defines computations.
1530 TfType _schemaType;
1531};
1532
1533
1534// Untemplated base class for classes used to build computation definitions.
1535class Exec_ComputationBuilderBase
1536{
1537protected:
1538 EXEC_API
1539 Exec_ComputationBuilderBase(
1540 const TfToken &attributeName,
1541 TfType schemaType,
1542 const TfToken &computationName,
1543 bool dispatched,
1544 ExecDispatchesOntoSchemas &&dispatchesOntoSchemas);
1545
1546 ~Exec_ComputationBuilderBase();
1547
1548 // Adds the callback with result type.
1549 EXEC_API
1550 void _AddCallback(ExecCallbackFn &&calback, TfType resultType);
1551
1552 // Validates that all inputs are allowed to be registered on computations of
1553 // the \p allowed provider types.
1554 //
1555 template <Exec_ComputationBuilderProviderTypes allowed, typename T>
1556 static void _ValidateInputs();
1557
1558 // Adds an input key from the given value specifier.
1559 //
1560 // This extra level of indirection helps keep Exec_InputKey out of the
1561 // header so that type can remain private.
1562 //
1563 EXEC_API
1564 void _AddInputKey(
1565 const Exec_ComputationBuilderValueSpecifierBase *valueSpecifier);
1566
1567 // Returns a pointer to the dispatches-onto schemas if the computation is
1568 // dispatched, or a null pointer, otherwise.
1569 //
1570 std::unique_ptr<ExecDispatchesOntoSchemas>
1571 _GetDispatchesOntoSchemas();
1572
1573 // We PIMPL the data for this class to avoid exposing more private details
1574 // in this public header.
1575 //
1576 struct _Data;
1577 _Data &_GetData();
1578
1579private:
1580 const std::unique_ptr<_Data> _data;
1581};
1582
1583
1584// CRTP base class for classes used to build computation definitions.
1585template <typename Derived>
1586class Exec_ComputationBuilderCRTPBase : public Exec_ComputationBuilderBase
1587{
1588 // Type used as a default template parameter type for metaprogramming.
1589 struct _UnspecifiedType {};
1590
1591protected:
1592 EXEC_API
1593 Exec_ComputationBuilderCRTPBase(
1594 const TfToken &attributeName,
1595 TfType schemaType,
1596 const TfToken &computationName,
1597 bool dispatched,
1598 ExecDispatchesOntoSchemas &&dispatchesOntoSchemas);
1599
1600 EXEC_API
1601 ~Exec_ComputationBuilderCRTPBase();
1602
1603public:
1669 template<
1670 typename ResultType = _UnspecifiedType,
1671 typename ReturnType = _UnspecifiedType>
1672 Derived&
1673 Callback(ReturnType (*callback)(const VdfContext &));
1674
1731 template<typename ResultType, typename FuncType>
1732 Derived&
1733 Callback(FuncType &&callback);
1734};
1735
1736
1739 : public Exec_ComputationBuilderCRTPBase<ExecPrimComputationBuilder>
1740{
1741 // Only ExecComputationBuilder can create instances.
1742 friend class ExecComputationBuilder;
1743
1744 EXEC_API
1746 TfType schemaType,
1747 const TfToken &computationName,
1748 bool dispatched = false,
1749 ExecDispatchesOntoSchemas &&dispatchesOntoSchemas = {});
1750
1751public:
1752 EXEC_API
1754
1779 template <typename... Args>
1781 Inputs(Args && ... args);
1782};
1783
1784
1787 : public Exec_ComputationBuilderCRTPBase<ExecAttributeComputationBuilder>
1788{
1789 // Only ExecComputationBuilder can create instances.
1790 friend class ExecComputationBuilder;
1791
1792 EXEC_API
1794 const TfToken &attributeName,
1795 TfType schemaType,
1796 const TfToken &computationName,
1797 bool dispatched = false,
1798 ExecDispatchesOntoSchemas &&dispatchesOntoSchemas = {});
1799
1800public:
1801 EXEC_API
1803
1832 template <typename... Args>
1834 Inputs(Args && ... args);
1835};
1836
1839 : public Exec_ComputationBuilderCRTPBase<ExecAttributeExpressionBuilder>
1840{
1841 // Only ExecComputationBuilder can create instances.
1842 friend class ExecComputationBuilder;
1843
1844 EXEC_API
1846 const TfToken &attributeName,
1847 TfType schemaType);
1848
1849public:
1850 EXEC_API
1852
1880 template <typename... Args>
1882 Inputs(Args && ... args);
1883};
1884
1885
1886//
1887// Exec_ComputationBuilderBase
1888//
1889
1890template <Exec_ComputationBuilderProviderTypes allowed, typename T>
1891void
1892Exec_ComputationBuilderBase::_ValidateInputs() {
1893 using regType = std::decay_t<T>;
1894 static_assert(
1895 !std::is_base_of_v<Exec_ComputationBuilderAccessorBase, regType>,
1896 "Accessor can't provide an input value.");
1897 static_assert(
1898 !std::is_same_v<Exec_ComputationBuilderConstantAccessorBase, regType>,
1899 "Constant(value) must be followed by .InputName(inputNameToken)");
1900 static_assert(
1901 std::is_base_of_v<Exec_ComputationBuilderValueSpecifierBase, regType>,
1902 "Invalid type used as an input registration.");
1903 static_assert(
1904 regType::allowedProviders & allowed,
1905 "This input registration is not allowed on a provider of this type.");
1906 static_assert(
1907 (regType::allowedProviders & allowed) ||
1908 (allowed ==
1909 Exec_ComputationBuilderProviderTypes::Attribute),
1910 "This input registration is only allowed on a provider attribute; "
1911 "there may be a missing Attribute(attributeName) registration.");
1912 static_assert(
1913 (regType::allowedProviders & allowed) ||
1914 (allowed ==
1915 Exec_ComputationBuilderProviderTypes::Prim),
1916 "This input registration is only allowed on a provider prim; "
1917 "there may be a missing Prim() registration.");
1918}
1919
1920//
1921// Exec_ComputationBuilderCRTPBase
1922//
1923
1924template <typename Derived>
1925template <typename InputResultType, typename ReturnType>
1926Derived&
1928 ReturnType (*callback)(const VdfContext &))
1929{
1930 // In order to allow the return type of the callback to be different from
1931 // the computation result type in some cases AND be able to deduce the
1932 // result type from the return type in others, we have to default both
1933 // template parameters to _UnspecifiedType and use metaprogramming to get
1934 // the actual result type.
1935 using ResultType =
1936 std::conditional_t<
1937 std::is_same_v<InputResultType, _UnspecifiedType>,
1938 ReturnType,
1939 InputResultType>;
1940
1941 static_assert(
1942 !std::is_void_v<ResultType> ||
1943 std::is_convertible_v<ReturnType, ResultType>,
1944 "Callback return type must be convertible to the computation result "
1945 "type.");
1946 static_assert(
1947 !std::is_reference_v<ResultType>,
1948 "Callback functions must return by value.");
1949 static_assert(
1951 "VtArray is not a supported result type.");
1952
1953 const TfType resultType =
1955
1956 // If the return type is void, the callback is on the hook to call
1957 // VdfContext::SetOutput; otherwise, we wrap it in a lambda that passes
1958 // the callback return value to SetOutput.
1959 if constexpr (std::is_void_v<ReturnType>) {
1960 _AddCallback(callback, resultType);
1961 } else {
1962 _AddCallback(
1963 [callback](const VdfContext& ctx) {
1964 ctx.SetOutput<ResultType>(callback(ctx));
1965 },
1966 resultType);
1967 }
1968
1969 return *static_cast<Derived*>(this);
1970}
1971
1972template <typename Derived>
1973template<typename ResultType, typename FuncType>
1974Derived&
1976 FuncType &&callback)
1977{
1978 // This condition will also be caught by the check for void return below,
1979 // but this produces a much clearer compile error, and therefore we do this
1980 // check first.
1981 static_assert(
1982 std::is_invocable_v<
1983 const std::remove_reference_t<FuncType>, const VdfContext&>,
1984 "Callback function object must have const function call operator.");
1985
1986 static_assert(
1987 !std::is_void_v<ResultType>,
1988 "The ResultType template parameter cannot be void, as this indicates "
1989 "the value type of the result produced by the computation.");
1990
1991 // The callback's return type must be void because any returned value
1992 // will be ignored.
1993 static_assert(
1994 std::is_void_v<std::invoke_result_t<const FuncType, const VdfContext&>>,
1995 "Callback return type must be void. Use VdfContext::SetOutput to "
1996 "set a result value.");
1997
1998 static_assert(
1999 !std::is_reference_v<ResultType>,
2000 "Callback function must return by value.");
2001 static_assert(
2003 "VtArray is not a supported result type.");
2004
2005 const TfType resultType =
2007
2008 _AddCallback(callback, resultType);
2009
2010 return *static_cast<Derived*>(this);
2011}
2012
2013//
2014// ExecPrimComputationBuilder
2015//
2016
2017template <typename... Args>
2020 Args && ... args)
2021{
2022 // Validate inputs
2023 (_ValidateInputs<
2024 Exec_ComputationBuilderProviderTypes::Prim, Args>(), ...);
2025
2026 // Add inputs
2027 (_AddInputKey(&args), ...);
2028
2029 return *this;
2030}
2031
2032//
2033// ExecAttributeComputationBuilder
2034//
2035
2036template <typename... Args>
2039 Args && ... args)
2040{
2041 // Validate inputs
2042 (_ValidateInputs<
2043 Exec_ComputationBuilderProviderTypes::Attribute, Args>(), ...);
2044
2045 // Add inputs
2046 (_AddInputKey(&args), ...);
2047
2048 return *this;
2049}
2050
2051//
2052// ExecAttributeExpressionBuilder
2053//
2054
2055template <typename... Args>
2058 Args && ... args)
2059{
2060 // Validate inputs
2061 (_ValidateInputs<
2062 Exec_ComputationBuilderProviderTypes::Attribute, Args>(), ...);
2063
2064 // Add inputs
2065 (_AddInputKey(&args), ...);
2066
2067 return *this;
2068}
2069
2070//
2071// ExecComputationBuilder
2072//
2073
2074template <class... DispatchedOntoSchemaTypes>
2077 const TfToken &computationName,
2078 DispatchedOntoSchemaTypes &&...schemaTypes)
2079{
2080 static_assert(
2081 (std::is_same_v<
2082 std::decay_t<DispatchedOntoSchemaTypes>, TfType> && ...));
2083
2085 computationName,
2086 {std::forward<DispatchedOntoSchemaTypes>(schemaTypes)...});
2087}
2088
2089template <class... DispatchedOntoSchemaTypes>
2092 const TfToken &computationName,
2093 DispatchedOntoSchemaTypes &&...schemaTypes)
2094{
2095 static_assert(
2096 (std::is_same_v<
2097 std::decay_t<DispatchedOntoSchemaTypes>, TfType> && ...));
2098
2100 computationName,
2101 {std::forward<DispatchedOntoSchemaTypes>(schemaTypes)...});
2102}
2103
2104PXR_NAMESPACE_CLOSE_SCOPE
2105
2106#endif
Class used to build attribute computation definitions.
Class used to build attribute expression definitions.
The top-level builder object (aka, the self variable generated by EXEC_REGISTER_COMPUTATIONS_FOR_SCHE...
Class used to build prim computation definitions.
Singleton used to register and access value types used by exec computations.
TfType CheckForRegistration() const
Confirms that ValueType has been registered.
static EXEC_API const ExecTypeRegistry & GetInstance()
Provides access to the singleton instance, first ensuring it is constructed.
A path value used to locate objects in layers or scenegraphs.
Definition path.h:281
static SDF_API const SdfPath & ReflexiveRelativePath()
The relative path representing "self".
SDF_API SdfPath AppendProperty(TfToken const &propName) const
Creates a path by appending an element for propName to this path.
This is a small-vector class with local storage optimization, the local storage can be specified via ...
Token for efficient comparison, assignment, and hashing of known strings.
Definition token.h:71
TfType represents a dynamic runtime type.
Definition type.h:48
A context is the parameter bundle passed to callbacks of computations.
Definition context.h:40
void SetOutput(const TfToken &outputName, const T &value) const
Sets the value of the output named outputName to value.
Definition context.h:375
Provides a container which may hold any type, and provides introspection and iteration over array typ...
Definition value.h:90
Exec_ComputationBuilderProviderTypes
An enum that is used as a template parameter to specify which kinds of providers a given input regist...
This file contains definitions for trivial types, including type aliases, so that source files that r...
std::function< void(const class VdfContext &context)> ExecCallbackFn
Function type used for computation callbacks.
Definition types.h:28
Exec_ComputationBuilderRelationshipAccessor< Exec_ComputationBuilderProviderTypes::Attribute > Relationship(const TfToken &relationshipName)
See Relationship().
Stage()
On any computation, provides access to the stage.
Attribute(const TfToken &attributeName)
On a prim computation, provides access to the attribute named attributeName.
Prim()
On an attribute computation, provides access to the owning prim.
Relationship(const TfToken &relationshipName)
On a prim computation, provides access to the relationship named relationshipName.
Exec_ComputationBuilderAttributeAccessor< Exec_ComputationBuilderProviderTypes::Attribute > Attribute(const TfToken &attributeName)
See Attribute().
auto AttributeValue(const TfToken &attributeName)
See AttributeValue().
Derived & Callback(ReturnType(*callback)(const VdfContext &))
Registers a callback function that implements the evaluation logic for a computation.
ExecAttributeExpressionBuilder & Inputs(Args &&... args)
Takes one or more input registrations that specify how to source input values for an attribute expres...
ExecPrimComputationBuilder & Inputs(Args &&... args)
Takes one or more input registrations that specify how to source input values for a prim computation.
ExecAttributeComputationBuilder & Inputs(Args &&... args)
Takes one or more input registrations that specify how to source input values for an attribute comput...
EXEC_API ExecAttributeExpressionBuilder AttributeExpression(const TfToken &attributeName)
Registers an attribute expression for attributes named attributeName.
ExecPrimComputationBuilder DispatchedPrimComputation(const TfToken &computationName, DispatchedOntoSchemaTypes &&...schemaTypes)
Registers a dispatched prim computation named computationName.
EXEC_API ExecAttributeComputationBuilder AttributeComputation(const TfToken &attributeName, const TfToken &computationName)
Registers an attribute computation named computationName on attributes named attributeName.
ExecAttributeComputationBuilder DispatchedAttributeComputation(const TfToken &computationName, DispatchedOntoSchemaTypes &&...schemaTypes)
Registers a dispatched attribute computation named computationName.
EXEC_API ExecPrimComputationBuilder PrimComputation(const TfToken &computationName)
Registers a prim computation named computationName.
This & InputName(const TfToken &inputName)
Overrides the default input name, setting it to inputName.
This & FallsBackToDispatched()
Declares the input can find dispatched computations if the requested computation name doesn't match a...
This & Required()
Declares the input is required, i.e., that the computation expects an input value always to be provid...
ValueSpecifier Metadata(const TfToken &metadataKey)
See Metadata().
Metadata(const TfToken &metadataKey)
Requests an input value from the metadata field indicated by metadataKey, of type ResultType.
ValueSpecifier IncomingConnections(const TfToken &computationName)
See IncomingConnections().
Constant(ValueType &&constantValue)
Requests a constant input value of type ValueType.
NamespaceAncestor(const TfToken &computationName)
On a prim computation, requests an input value from the computation computationName of type ResultTyp...
auto Connections(const TfToken &computationName)
As a direct input to an attribute computation or after an Attribute() accessor, requests input values...
ValueSpecifier TargetedObjects(const TfToken &computationName)
After a Relationship() accessor, requests input values from the computation computationName of type R...
auto IncomingConnections(const TfToken &computationName)
On any provider, requests input values from the computation computationName of type ResultType on the...
Computation(const TfToken &computationName)
Requests an input value from the computation computationName of type ResultType.
ValueSpecifier Connections(const TfToken &computationName)
See Connections().
ValueSpecifier Computation(const TfToken &computationName)
See Computation().
STL namespace.
Accessor common to all scene object types that support requesting computations on the object.
Data used to find computation providers during exec compilation.
@ Local
The localTraversal path directly indicates the computation provider.
@ NamespaceAncestor
Find the provider by traversing upward in namespace.
A trait to detect instantiations of VtArray, specialized in array.h.
Definition traits.h:22
Attribute accessor, valid for providing input to a prim computation.
Computation value specifier, valid for providing input to any computation.
Metadata value specifier, valid on a prim or attribute computation.
Prim accessor, valid for providing input to an attribute computation.
Relationship accessor, valid for providing input to a prim computation.
Provides access to the stage, valid for providing input to any computation.
TfToken class for efficient string referencing and hashing, plus conversions to and from stl string c...
constexpr bool VtIsHashable()
A constexpr function that returns true if T is hashable via VtHashValue(), false otherwise.
Definition hash.h:59