24 #ifndef PXR_USD_SDF_PREDICATE_PROGRAM_H
25 #define PXR_USD_SDF_PREDICATE_PROGRAM_H
38 #include <initializer_list>
46 template <
class DomainType>
50 template <
class DomainType>
67 template <
class DomainType>
75 SdfLinkPredicateExpression<DomainType>(
80 explicit operator bool()
const {
90 auto funcIter = _funcs.cbegin();
91 auto opIter = _ops.cbegin(), opEnd = _ops.cend();
113 auto shortCircuit = [&]() {
114 const int origNest = nest;
115 for (; opIter != opEnd; ++opIter) {
117 case Call: ++funcIter;
break;
118 case Not:
case And:
case Or:
break;
119 case Open: ++nest;
break;
121 if (--nest == origNest) {
131 for (; opIter != opEnd; ++opIter) {
136 case Not: result = !
result;
break;
138 const bool decidingValue = *opIter != And;
141 if (result == decidingValue) {
146 case Open: ++nest;
break;
147 case Close: --nest;
break;
154 enum _Op { Call, Not, Open, Close, And, Or };
155 std::vector<_Op> _ops;
156 std::vector<PredicateFunction> _funcs;
163 template <
class DomainType>
176 auto exprToProgramOp = [](
Expr::Op op) {
178 case Expr::Call:
return Program::Call;
179 case Expr::Not:
return Program::Not;
180 case Expr::ImpliedAnd:
case Expr::And:
return Program::And;
181 case Expr::Or:
return Program::Or;
183 return static_cast<typename Program::_Op
>(-1);
186 auto translateLogic = [&](
Expr::Op op,
int argIndex) {
190 prog._ops.push_back(Program::Not);
193 case Expr::ImpliedAnd:
197 prog._ops.push_back(exprToProgramOp(op));
198 prog._ops.push_back(Program::Open);
200 else if (argIndex == 2) {
201 prog._ops.push_back(Program::Close);
209 auto translateCall = [&](Expr::FnCall
const &call) {
212 if (
auto fn = lib._BindCall(call.funcName, call.args)) {
213 prog._funcs.push_back(std::move(fn));
214 prog._ops.push_back(Program::Call);
220 errs +=
"Failed to bind call of " + call.funcName;
225 expr.
Walk(translateLogic, translateCall);
236 #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
GLsizei const GLchar *const * string
**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