OpenVDB  7.2.1
OP_NodeChain.h
Go to the documentation of this file.
1 // Copyright Contributors to the OpenVDB Project
2 // SPDX-License-Identifier: MPL-2.0
3 //
5 //
7 //
12 
13 #ifndef HOUDINI_UTILS_OP_NODECHAIN_HAS_BEEN_INCLUDED
14 #define HOUDINI_UTILS_OP_NODECHAIN_HAS_BEEN_INCLUDED
15 
16 #include <OP/OP_Context.h>
17 #include <OP/OP_Channels.h> // for CH_AutoEvaluateTime
18 #include <OP/OP_Director.h>
19 #include <OP/OP_Node.h>
20 #include <SYS/SYS_Types.h> // for fpreal
21 #include <UT/UT_String.h>
22 #include <UT/UT_Thread.h>
23 #include <algorithm>
24 #include <string>
25 #include <vector>
26 #if defined(PRODDEV_BUILD) || defined(DWREAL_IS_DOUBLE)
27  // OPENVDB_HOUDINI_API, which has no meaning in a DWA build environment but
28  // must at least exist, is normally defined by including openvdb/Platform.h.
29  // For DWA builds (i.e., if either PRODDEV_BUILD or DWREAL_IS_DOUBLE exists),
30  // that introduces an unwanted and unnecessary library dependency.
31  #ifndef OPENVDB_HOUDINI_API
32  #define OPENVDB_HOUDINI_API
33  #endif
34 #else
35  #include <openvdb/Platform.h>
36 #endif
37 
38 
39 namespace houdini_utils {
40 
50 template<typename NodeType>
52 inline std::vector<NodeType*>
53 getNodeChain(OP_Context& context, NodeType* startNode, bool addInterest = true)
54 {
55  struct Local {
58  static inline OP_Node* nextInput(
59  fpreal now,
60  OP_Node* node)
61  {
62  OP_Node* input = node->getInput(0, /*mark_used=*/true);
63  while (input) {
64  OP_Node* passThrough = input->getPassThroughNode(now, /*mark_used=*/true);
65  if (!passThrough) break;
66  input = passThrough;
67  }
68  return input;
69  }
70  }; // struct Local
71 
72  const fpreal now = context.getTime();
73 
74  std::vector<NodeType*> nodes;
75  for (OP_Node* node = startNode; node != NULL; node = Local::nextInput(now, node)) {
76  // Stop if the node does not need to cook.
77  if (!node->needToCook(context, /*query_only=*/true)) break;
78 
79  if (NodeType* candidate = dynamic_cast<NodeType*>(node)) {
80  nodes.push_back(candidate);
81  } else {
82  // Stop if the node is not of the requested type, unless it is a SOP_NULL.
83  std::string opname = node->getName().toStdString().substr(0, 4);
84  if (opname == "null") continue;
85  break; // stop for all other node types
86  }
87  }
88  std::reverse(nodes.begin(), nodes.end());
89 
90  if (addInterest && startNode != nodes[0] && nodes[0]->getInput(0)) {
91  startNode->addExtraInput(nodes[0]->getInput(0), OP_INTEREST_DATA);
92  }
93 
94  return nodes;
95 }
96 
97 
99 
100 
110 {
111 public:
113  OP_EvalScope(OP_Node& node, OP_Context& context):
114  mAutoEvaluator(
115  *OPgetDirector()->getCommandManager(),
116  context.getThread(),
117  context.getTime(),
118  node.getChannels()),
119  mDirector(OPgetDirector()),
120  mThread(context.getThread())
121  {
122  mDirector->pushCwd(mThread, &node);
123  }
124 
126  ~OP_EvalScope() { mDirector->popCwd(mThread); }
127 
128 private:
129  CH_AutoEvaluateTime mAutoEvaluator;
130  OP_Director* mDirector;
131  int mThread;
132 };
133 
134 } // namespace houdini_utils
135 
136 #endif // HOUDINI_UTILS_OP_NODECHAIN_HAS_BEEN_INCLUDED
houdini_utils::getNodeChain
OPENVDB_DEPRECATED std::vector< NodeType * > getNodeChain(OP_Context &context, NodeType *startNode, bool addInterest=true)
Return a list of adjacent, uncooked nodes of the given NodeType, starting from startNode and traversi...
Definition: OP_NodeChain.h:53
houdini_utils::OP_EvalScope
Constructing an OP_EvalScope object allows one to temporarily (for the duration of the current scope)...
Definition: OP_NodeChain.h:110
houdini_utils
Utilities to collect a chain of adjacent nodes of a particular type so that they can be cooked in a s...
Definition: OP_NodeChain.h:39
Platform.h
OPENVDB_DEPRECATED
#define OPENVDB_DEPRECATED
Definition: Platform.h:42
houdini_utils::OP_EvalScope::~OP_EvalScope
OPENVDB_DEPRECATED ~OP_EvalScope()
Definition: OP_NodeChain.h:126
houdini_utils::OP_EvalScope::OP_EvalScope
OPENVDB_DEPRECATED OP_EvalScope(OP_Node &node, OP_Context &context)
Definition: OP_NodeChain.h:113