7 #ifndef PXR_USD_SDF_PREDICATE_PROGRAM_H
8 #define PXR_USD_SDF_PREDICATE_PROGRAM_H
20 #include <initializer_list>
28 template <
class DomainType>
32 template <
class DomainType>
49 template <
class DomainType>
57 SdfLinkPredicateExpression<DomainType>(
62 explicit operator bool()
const {
72 auto funcIter = _funcs.cbegin();
73 auto opIter = _ops.cbegin(), opEnd = _ops.cend();
95 auto shortCircuit = [&]() {
96 const int origNest = nest;
97 for (; opIter != opEnd; ++opIter) {
99 case Call: ++funcIter;
break;
100 case Not:
case And:
case Or:
break;
101 case Open: ++nest;
break;
103 if (--nest == origNest) {
113 for (; opIter != opEnd; ++opIter) {
118 case Not: result = !
result;
break;
120 const bool decidingValue = *opIter != And;
123 if (result == decidingValue) {
128 case Open: ++nest;
break;
129 case Close: --nest;
break;
136 enum _Op { Call, Not, Open, Close, And, Or };
137 std::vector<_Op> _ops;
138 std::vector<PredicateFunction> _funcs;
145 template <
class DomainType>
160 case Expr::Call:
return Program::Call;
161 case Expr::Not:
return Program::Not;
162 case Expr::ImpliedAnd:
case Expr::And:
return Program::And;
163 case Expr::Or:
return Program::Or;
165 return static_cast<typename Program::_Op
>(-1);
168 auto translateLogic = [&](
Expr::Op op,
int argIndex) {
172 prog._ops.push_back(Program::Not);
175 case Expr::ImpliedAnd:
179 prog._ops.push_back(exprToProgramOp(op));
180 prog._ops.push_back(Program::Open);
182 else if (argIndex == 2) {
183 prog._ops.push_back(Program::Close);
191 auto translateCall = [&](Expr::FnCall
const &call) {
194 if (
auto fn = lib._BindCall(call.funcName, call.args)) {
195 prog._funcs.push_back(std::move(fn));
196 prog._ops.push_back(Program::Call);
202 errs +=
"Failed to bind call of " + call.funcName;
207 expr.
Walk(translateLogic, translateCall);
218 #endif // PXR_USD_SDF_PREDICATE_PROGRAM_H
typename SdfPredicateLibrary< DomainType >::PredicateFunction PredicateFunction
SDF_API void Walk(TfFunctionRef< void(Op, int)> logic, TfFunctionRef< void(FnCall const &)> call) const
**But if you need a result
void SetAndPropagateConstancy(SdfPredicateFunctionResult other)
static SdfPredicateFunctionResult MakeConstant(bool value)
Create with value and 'ConstantOverDescendants'.
SdfPredicateProgram< DomainType > SdfLinkPredicateExpression(SdfPredicateExpression const &expr, SdfPredicateLibrary< DomainType > const &lib)
std::function< SdfPredicateFunctionResult(DomainType const &)> PredicateFunction
The type of a bound function, the result of binding passed arguments.
SdfPredicateFunctionResult operator()(DomainType const &obj) const
Run the predicate program on obj, and return the result.
PXR_NAMESPACE_CLOSE_SCOPE PXR_NAMESPACE_OPEN_SCOPE
#define PXR_NAMESPACE_CLOSE_SCOPE