HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
OP_Utils.h
Go to the documentation of this file.
1 /*
2  * PROPRIETARY INFORMATION. This software is proprietary to
3  * Side Effects Software Inc., and is not to be reproduced,
4  * transmitted, or disclosed in any way without written permission.
5  *
6  * NAME: OP Library (C++)
7  *
8  * COMMENTS: Some utility functions for operators.
9  *
10  */
11 
12 #ifndef __OP_Utils_h__
13 #define __OP_Utils_h__
14 
15 #include "OP_API.h"
16 #include "OP_Node.h"
17 #include <UT/UT_Error.h>
18 #include <UT/UT_Matrix2.h>
19 #include <UT/UT_Matrix3.h>
20 #include <UT/UT_Matrix4.h>
21 #include <UT/UT_Ramp.h>
22 #include <UT/UT_Vector2.h>
23 #include <UT/UT_Vector3.h>
24 #include <UT/UT_Vector4.h>
25 #include <UT/UT_WeakPtr.h>
26 
27 class OP_NetworkBoxItem;
28 class PY_Result;
29 class UT_BitArray;
30 class UT_WorkBuffer;
31 class UT_StringArray;
32 
34  const UT_StringArray &badrefs);
36  bool checktoplevelnode,
37  UT_WorkBuffer &err);
39  bool checktoplevelnode,
40  UT_WorkBuffer &err);
41 
42 /// Looks for any nodes inside the specified operator that are defined by
43 /// VOP Networks outside the provided node. REtrns true if no such nodes
44 /// are found. Otherwise it puts an error message in the err buffer and
45 /// returns false.
47  UT_WorkBuffer &err);
49  UT_String &vopnetmask);
50 /// Adds a new vopnet mask string to the list of known vopnet context types.
51 /// This list is used to generate a VopNet Mask value when creating an HDA
52 /// from an existing subnet VOP.
54 
55 /// @{ Functions for testing whether a node parameter is used as a shader
56 /// parameter, when the node represents a shader. Some node parameters may
57 /// belong to only certain contexts (eg, surface shader), while other ones
58 /// may be just true spare parameters that are not shader parameters at all.
60 OP_API bool OPisStandInShaderParm(const PRM_Template &parm);
62  const char *context_name);
63 OP_API bool OPisLegacyShaderParm(const PRM_Template &parm, OP_Node *owner);
64 OP_API bool OPhasShaderContextTag(const PRM_Template *list,
65  int start = 0, int end = -1);
66 /// @}
67 
68 /// Display UI message dialog only when inside graphical Houdini.
69 /// This is provided to avoid link dependencies against HOM.
71  const char *message,
73  bool print_when_non_graphical = true);
74 
75 OP_API OP_Node *OPfindOpInput(OP_Node *op, const char *find_op_type,
76  bool include_me = true);
77 OP_API OP_Node *OPfindOpInput(OP_Node *op, const char **find_op_types,
78  bool include_me = true);
79 
80 /// Returns coordinates specifying the smallest possible bounding box
81 /// around the items in 'items'. Takes each item's height and width into
82 /// consideration.
84  const OP_NetworkBoxItemList &items);
85 
86 /// Looks for any VOP Networks inside the specified node which define operator
87 /// types that are instantiated outside the node. If it returns false, the
88 /// badvopnets array will be filled with the VOP Networks that are used
89 /// outside the root node.
91  OP_NodeList *badvopnets);
92 
93 /// Creates a sticky note about the lack of vops inside synced HDAs, since the
94 /// children have been removed because the subnet is using cached code.
96 
97 /// Given a set of unique nodes, compute a topological ordering using only the
98 /// connectivity amongst the given nodes. If the roots are not known, then it
99 /// will be internally computed using OPmarkNodeRoots(only_picked=false).
100 /// Otherwise, the nodes will only be sorted by traversing from the given root
101 /// nodes.
104  const OP_NodeList &nodes,
105  const UT_BitArray *roots = nullptr);
106 
107 /// Given a set of nodes return a bit array indicating the nodes which are
108 /// roots WITHIN THE SET. If assume_picked is true, then it's assumed that the
109 /// node is in the set if and only if it's in the set.
111  UT_BitArray &roots,
112  const OP_NodeList &nodes,
113  bool assume_picked);
114 
115 namespace OP_Utils
116 {
117  // Boiler plate to load individual types from op.
118  static inline void evalOpParm(
119  int64 &v, const OP_Node *node, const char *parmname, fpreal time,
120  DEP_MicroNode *depnode)
121  {
122  if (depnode) depnode->addExplicitInput(SYSconst_cast(node)->getParm(parmname).microNode(0));
123  v = node->evalInt(parmname, 0, time);
124  }
125  static inline void evalOpParm(
126  bool &v, const OP_Node *node, const char *parmname, fpreal time,
127  DEP_MicroNode *depnode)
128  {
129  if (depnode) depnode->addExplicitInput(SYSconst_cast(node)->getParm(parmname).microNode(0));
130  v = node->evalInt(parmname, 0, time);
131  }
132  static inline void evalOpParm(
133  fpreal64 &v, const OP_Node *node, const char *parmname, fpreal time,
134  DEP_MicroNode *depnode)
135  {
136  if (depnode) depnode->addExplicitInput(SYSconst_cast(node)->getParm(parmname).microNode(0));
137  v = node->evalFloat(parmname, 0, time);
138  }
139  static inline void evalOpParm(
140  UT_Vector2D &v, const OP_Node *node, const char *parmname, fpreal time,
141  DEP_MicroNode *depnode)
142  {
143  if (depnode) depnode->addExplicitInput(SYSconst_cast(node)->getParm(parmname).microNode(0));
144  if (depnode) depnode->addExplicitInput(SYSconst_cast(node)->getParm(parmname).microNode(1));
145  v.x() = node->evalFloat(parmname, 0, time);
146  v.y() = node->evalFloat(parmname, 1, time);
147  }
148  static inline void evalOpParm(
149  UT_Vector3D &v, const OP_Node *node, const char *parmname, fpreal time,
150  DEP_MicroNode *depnode)
151  {
152  if (depnode) depnode->addExplicitInput(SYSconst_cast(node)->getParm(parmname).microNode(0));
153  if (depnode) depnode->addExplicitInput(SYSconst_cast(node)->getParm(parmname).microNode(1));
154  if (depnode) depnode->addExplicitInput(SYSconst_cast(node)->getParm(parmname).microNode(2));
155  v.x() = node->evalFloat(parmname, 0, time);
156  v.y() = node->evalFloat(parmname, 1, time);
157  v.z() = node->evalFloat(parmname, 2, time);
158  }
159  static inline void evalOpParm(
160  UT_Vector4D &v, const OP_Node *node, const char *parmname, fpreal time,
161  DEP_MicroNode *depnode)
162  {
163  if (depnode) depnode->addExplicitInput(SYSconst_cast(node)->getParm(parmname).microNode(0));
164  if (depnode) depnode->addExplicitInput(SYSconst_cast(node)->getParm(parmname).microNode(1));
165  if (depnode) depnode->addExplicitInput(SYSconst_cast(node)->getParm(parmname).microNode(2));
166  if (depnode) depnode->addExplicitInput(SYSconst_cast(node)->getParm(parmname).microNode(3));
167  v.x() = node->evalFloat(parmname, 0, time);
168  v.y() = node->evalFloat(parmname, 1, time);
169  v.z() = node->evalFloat(parmname, 2, time);
170  v.w() = node->evalFloat(parmname, 3, time);
171  }
172 
173  static inline void evalOpParm(
174  UT_Matrix2D &v, const OP_Node *node, const char *parmname, fpreal time,
175  DEP_MicroNode *depnode)
176  { for (int r = 0; r < 2; r++)
177  {
178  for (int c = 0; c < 2; c++)
179  {
180  if (depnode) depnode->addExplicitInput(SYSconst_cast(node)->getParm(parmname).microNode(r * 2 + c));
181  v(r, c) = node->evalFloat(parmname, r * 2 + c, time);
182  }
183  }
184  }
185  static inline void evalOpParm(
186  UT_Matrix3D &v, const OP_Node *node, const char *parmname, fpreal time,
187  DEP_MicroNode *depnode)
188  { for (int r = 0; r < 3; r++)
189  {
190  for (int c = 0; c < 3; c++)
191  {
192  if (depnode) depnode->addExplicitInput(SYSconst_cast(node)->getParm(parmname).microNode(r * 3 + c));
193  v(r, c) = node->evalFloat(parmname, r * 3 + c, time);
194  }
195  }
196  }
197  static inline void evalOpParm(
198  UT_Matrix4D &v, const OP_Node *node, const char *parmname, fpreal time,
199  DEP_MicroNode *depnode)
200  { for (int r = 0; r < 4; r++)
201  {
202  for (int c = 0; c < 4; c++)
203  {
204  if (depnode) depnode->addExplicitInput(SYSconst_cast(node)->getParm(parmname).microNode(r * 4 + c));
205  v(r, c) = node->evalFloat(parmname, r * 4 + c, time);
206  }
207  }
208  }
209 
210  static void inline evalOpParm(
211  UT_Vector2I &v, const OP_Node *node, const char *parmname, fpreal time,
212  DEP_MicroNode *depnode)
213  {
214  if (depnode) depnode->addExplicitInput(SYSconst_cast(node)->getParm(parmname).microNode(0));
215  if (depnode) depnode->addExplicitInput(SYSconst_cast(node)->getParm(parmname).microNode(1));
216  v.x() = node->evalInt(parmname, 0, time);
217  v.y() = node->evalInt(parmname, 1, time);
218  }
219  static void inline evalOpParm(
220  UT_Vector3I &v, const OP_Node *node, const char *parmname, fpreal time,
221  DEP_MicroNode *depnode)
222  {
223  if (depnode) depnode->addExplicitInput(SYSconst_cast(node)->getParm(parmname).microNode(0));
224  if (depnode) depnode->addExplicitInput(SYSconst_cast(node)->getParm(parmname).microNode(1));
225  if (depnode) depnode->addExplicitInput(SYSconst_cast(node)->getParm(parmname).microNode(2));
226  v.x() = node->evalInt(parmname, 0, time);
227  v.y() = node->evalInt(parmname, 1, time);
228  v.z() = node->evalInt(parmname, 2, time);
229  }
230  static void inline evalOpParm(
231  UT_Vector4I &v, const OP_Node *node, const char *parmname, fpreal time,
232  DEP_MicroNode *depnode)
233  {
234  if (depnode) depnode->addExplicitInput(SYSconst_cast(node)->getParm(parmname).microNode(0));
235  if (depnode) depnode->addExplicitInput(SYSconst_cast(node)->getParm(parmname).microNode(1));
236  if (depnode) depnode->addExplicitInput(SYSconst_cast(node)->getParm(parmname).microNode(2));
237  if (depnode) depnode->addExplicitInput(SYSconst_cast(node)->getParm(parmname).microNode(3));
238  v.x() = node->evalInt(parmname, 0, time);
239  v.y() = node->evalInt(parmname, 1, time);
240  v.z() = node->evalInt(parmname, 2, time);
241  v.w() = node->evalInt(parmname, 3, time);
242  }
243  static void inline evalOpParm(
244  UT_StringHolder &v, const OP_Node *node, const char *parmname, fpreal time,
245  DEP_MicroNode *depnode)
246  {
247  if (depnode) depnode->addExplicitInput(SYSconst_cast(node)->getParm(parmname).microNode(0));
248  UT_String result; node->evalString(result, parmname, 0, time); v.adoptFromString(result);
249  }
250  static void inline evalOpParmRaw(
251  UT_StringHolder &v, const OP_Node *node, const char *parmname, fpreal time,
252  DEP_MicroNode *depnode)
253  {
254  if (depnode) depnode->addExplicitInput(SYSconst_cast(node)->getParm(parmname).microNode(0));
255  UT_String result; node->evalStringRaw(result, parmname, 0, time); v.adoptFromString(result);
256  }
257  static void inline evalOpParm(
258  UT_SharedPtr<UT_Ramp> &v, const OP_Node *node, const char *parmname, fpreal time,
259  DEP_MicroNode *depnode)
260  {
261  v.reset(new UT_Ramp());
262 
263  if (node->hasParm(parmname))
264  node->updateRampFromMultiParm(time, node->getParm(parmname), *v, 0, depnode);
265  }
266  static void inline evalOpParm(
267  PRM_DataItemHandle &v, const OP_Node *node, const char *parmname, fpreal time,
268  DEP_MicroNode *depnode)
269  {
270  if (depnode) depnode->addExplicitInput(SYSconst_cast(node)->getParm(parmname).microNode(0));
271  v = node->evalData(parmname, 0, time);
272  }
273 
274 
275  static void inline evalOpParmInst(
276  int64 &v, const OP_Node *node, const char *parmname,
277  const int *inst, fpreal time,
278  DEP_MicroNode *depnode,
279  int nestlevel=1)
280  {
281  if (depnode) depnode->addExplicitInput(SYSconst_cast(node)->getParmPtrInst(parmname, inst, nestlevel)->microNode(0));
282  v = node->evalIntInst(parmname, inst, 0, time, nestlevel);
283  }
284  static void inline evalOpParmInst(
285  bool &v, const OP_Node *node, const char *parmname,
286  const int *inst, fpreal time,
287  DEP_MicroNode *depnode,
288  int nestlevel=1)
289  {
290  if (depnode) depnode->addExplicitInput(SYSconst_cast(node)->getParmPtrInst(parmname, inst, nestlevel)->microNode(0));
291  v = node->evalIntInst(parmname, inst, 0, time, nestlevel);
292  }
293  static void inline evalOpParmInst(
294  fpreal64 &v, const OP_Node *node, const char *parmname,
295  const int *inst, fpreal time,
296  DEP_MicroNode *depnode,
297  int nestlevel=1)
298  {
299  if (depnode) depnode->addExplicitInput(SYSconst_cast(node)->getParmPtrInst(parmname, inst, nestlevel)->microNode(0));
300  v = node->evalFloatInst(parmname, inst, 0, time, nestlevel);
301  }
302  static void inline evalOpParmInst(
303  UT_Vector2D &v, const OP_Node *node, const char *parmname,
304  const int *inst, fpreal time,
305  DEP_MicroNode *depnode,
306  int nestlevel=1)
307  {
308  if (depnode) depnode->addExplicitInput(SYSconst_cast(node)->getParmPtrInst(parmname, inst, nestlevel)->microNode(0));
309  if (depnode) depnode->addExplicitInput(SYSconst_cast(node)->getParmPtrInst(parmname, inst, nestlevel)->microNode(1));
310  v.x() = node->evalFloatInst(parmname, inst, 0, time, nestlevel);
311  v.y() = node->evalFloatInst(parmname, inst, 1, time, nestlevel);
312  }
313  static void inline evalOpParmInst(
314  UT_Vector3D &v, const OP_Node *node, const char *parmname,
315  const int *inst, fpreal time,
316  DEP_MicroNode *depnode,
317  int nestlevel=1)
318  {
319  if (depnode) depnode->addExplicitInput(SYSconst_cast(node)->getParmPtrInst(parmname, inst, nestlevel)->microNode(0));
320  if (depnode) depnode->addExplicitInput(SYSconst_cast(node)->getParmPtrInst(parmname, inst, nestlevel)->microNode(1));
321  if (depnode) depnode->addExplicitInput(SYSconst_cast(node)->getParmPtrInst(parmname, inst, nestlevel)->microNode(2));
322  v.x() = node->evalFloatInst(parmname, inst, 0, time, nestlevel);
323  v.y() = node->evalFloatInst(parmname, inst, 1, time, nestlevel);
324  v.z() = node->evalFloatInst(parmname, inst, 2, time, nestlevel);
325  }
326  static void inline evalOpParmInst(
327  UT_Vector4D &v, const OP_Node *node, const char *parmname,
328  const int *inst, fpreal time,
329  DEP_MicroNode *depnode,
330  int nestlevel=1)
331  {
332  if (depnode) depnode->addExplicitInput(SYSconst_cast(node)->getParmPtrInst(parmname, inst, nestlevel)->microNode(0));
333  if (depnode) depnode->addExplicitInput(SYSconst_cast(node)->getParmPtrInst(parmname, inst, nestlevel)->microNode(1));
334  if (depnode) depnode->addExplicitInput(SYSconst_cast(node)->getParmPtrInst(parmname, inst, nestlevel)->microNode(2));
335  if (depnode) depnode->addExplicitInput(SYSconst_cast(node)->getParmPtrInst(parmname, inst, nestlevel)->microNode(3));
336  v.x() = node->evalFloatInst(parmname, inst, 0, time, nestlevel);
337  v.y() = node->evalFloatInst(parmname, inst, 1, time, nestlevel);
338  v.z() = node->evalFloatInst(parmname, inst, 2, time, nestlevel);
339  v.w() = node->evalFloatInst(parmname, inst, 3, time, nestlevel);
340  }
341 
342  static void inline evalOpParmInst(
343  UT_Matrix2D &v, const OP_Node *node, const char *parmname,
344  const int *inst, fpreal time,
345  DEP_MicroNode *depnode,
346  int nestlevel=1)
347  { for (int r = 0; r < 2; r++)
348  {
349  for (int c = 0; c < 2; c++)
350  {
351  if (depnode) depnode->addExplicitInput(SYSconst_cast(node)->getParmPtrInst(parmname, inst, nestlevel)->microNode(r * 2 + c));
352  v(r, c) = node->evalFloatInst(parmname, inst, r * 2 + c, time, nestlevel);
353  }
354  }
355  }
356  static void inline evalOpParmInst(
357  UT_Matrix3D &v, const OP_Node *node, const char *parmname,
358  const int *inst, fpreal time,
359  DEP_MicroNode *depnode,
360  int nestlevel=1)
361  { for (int r = 0; r < 3; r++)
362  {
363  for (int c = 0; c < 3; c++)
364  {
365  if (depnode) depnode->addExplicitInput(SYSconst_cast(node)->getParmPtrInst(parmname, inst, nestlevel)->microNode(r * 3 + c));
366  v(r, c) = node->evalFloatInst(parmname, inst, r * 3 + c, time, nestlevel);
367  }
368  }
369  }
370  static void inline evalOpParmInst(
371  UT_Matrix4D &v, const OP_Node *node, const char *parmname,
372  const int *inst, fpreal time,
373  DEP_MicroNode *depnode,
374  int nestlevel=1)
375  { for (int r = 0; r < 4; r++)
376  {
377  for (int c = 0; c < 4; c++)
378  {
379  if (depnode) depnode->addExplicitInput(SYSconst_cast(node)->getParmPtrInst(parmname, inst, nestlevel)->microNode(r * 4 + c));
380  v(r, c) = node->evalFloatInst(parmname, inst, r * 4 + c, time, nestlevel);
381  }
382  }
383  }
384 
385  static void inline evalOpParmInst(
386  UT_Vector2I &v, const OP_Node *node, const char *parmname,
387  const int *inst, fpreal time,
388  DEP_MicroNode *depnode,
389  int nestlevel=1)
390  {
391  if (depnode) depnode->addExplicitInput(SYSconst_cast(node)->getParmPtrInst(parmname, inst, nestlevel)->microNode(0));
392  if (depnode) depnode->addExplicitInput(SYSconst_cast(node)->getParmPtrInst(parmname, inst, nestlevel)->microNode(1));
393  v.x() = node->evalIntInst(parmname, inst, 0, time, nestlevel);
394  v.y() = node->evalIntInst(parmname, inst, 1, time, nestlevel);
395  }
396  static void inline evalOpParmInst(
397  UT_Vector3I &v, const OP_Node *node, const char *parmname,
398  const int *inst, fpreal time,
399  DEP_MicroNode *depnode,
400  int nestlevel=1)
401  {
402  if (depnode) depnode->addExplicitInput(SYSconst_cast(node)->getParmPtrInst(parmname, inst, nestlevel)->microNode(0));
403  if (depnode) depnode->addExplicitInput(SYSconst_cast(node)->getParmPtrInst(parmname, inst, nestlevel)->microNode(1));
404  if (depnode) depnode->addExplicitInput(SYSconst_cast(node)->getParmPtrInst(parmname, inst, nestlevel)->microNode(2));
405  v.x() = node->evalIntInst(parmname, inst, 0, time, nestlevel);
406  v.y() = node->evalIntInst(parmname, inst, 1, time, nestlevel);
407  v.z() = node->evalIntInst(parmname, inst, 2, time, nestlevel);
408  }
409  static void inline evalOpParmInst(
410  UT_Vector4I &v, const OP_Node *node, const char *parmname,
411  const int *inst, fpreal time,
412  DEP_MicroNode *depnode,
413  int nestlevel=1)
414  {
415  if (depnode) depnode->addExplicitInput(SYSconst_cast(node)->getParmPtrInst(parmname, inst, nestlevel)->microNode(0));
416  if (depnode) depnode->addExplicitInput(SYSconst_cast(node)->getParmPtrInst(parmname, inst, nestlevel)->microNode(1));
417  if (depnode) depnode->addExplicitInput(SYSconst_cast(node)->getParmPtrInst(parmname, inst, nestlevel)->microNode(2));
418  if (depnode) depnode->addExplicitInput(SYSconst_cast(node)->getParmPtrInst(parmname, inst, nestlevel)->microNode(3));
419  v.x() = node->evalIntInst(parmname, inst, 0, time, nestlevel);
420  v.y() = node->evalIntInst(parmname, inst, 1, time, nestlevel);
421  v.z() = node->evalIntInst(parmname, inst, 2, time, nestlevel);
422  v.w() = node->evalIntInst(parmname, inst, 3, time, nestlevel);
423  }
424 
425  static void inline evalOpParmInst(
426  UT_StringHolder &v, const OP_Node *node, const char *parmname,
427  const int *inst, fpreal time,
428  DEP_MicroNode *depnode,
429  int nestlevel=1)
430  {
431  UT_String result; node->evalStringInst(parmname, inst, result, 0, time, nestlevel); v.adoptFromString(result);
432  if (depnode) depnode->addExplicitInput(SYSconst_cast(node)->getParmPtrInst(parmname, inst, nestlevel)->microNode(0));
433  }
434  static void inline evalOpParmInst(
435  UT_SharedPtr<UT_Ramp> &v, const OP_Node *node, const char *parmname,
436  const int *inst, fpreal time,
437  DEP_MicroNode *depnode,
438  int nestlevel=1)
439  {
440  v.reset(new UT_Ramp());
441 
442  const PRM_Parm *rampparm = node->getParmList()->getParmPtrInst(parmname, inst, nestlevel);
443  if (rampparm)
444  node->updateRampFromMultiParm(time, *rampparm, *v, 0, depnode);
445  }
446  static void inline evalOpParmInst(
447  PRM_DataItemHandle &v, const OP_Node *node, const char *parmname,
448  const int *inst, fpreal time,
449  DEP_MicroNode *depnode,
450  int nestlevel=1)
451  {
452  if (depnode) depnode->addExplicitInput(SYSconst_cast(node)->getParmPtrInst(parmname, inst, nestlevel)->microNode(0));
453  v = node->evalDataInst(parmname, inst, 0, time, nestlevel);
454  }
455 
456  // Callback class to receive the results of an OP python callback
457  // or script evaluation. Clients must implement this interface and
458  // register with registerPythonResultClient to be notified.
459  // See registerPythonResultClient, notifyPythonResultClients
461  {
462  public:
464 
465  PythonResultClient() = default;
466  virtual ~PythonResultClient() = default;
467 
468  // results: Python result structure.
469  // script_source: The script source e.g. OpInstall
470  // script_path: The script file path or a reference to the
471  // embedded node e.g. opdef:/Object/mynode?OnInstall
472  virtual void onNotifyOPPythonResult(PY_Result const & result, char const * script_source, char const * script_path) = 0;
473  };
474 
475  // Registers a client interested in the OP python script evaluation results.
477 
478  // Notifies registered PythonResultClient objects about the result of a
479  // OP python script evaluation.
480  OP_API void notifyPythonResultClients(PY_Result const & result, char const * script_source, char const * script_path);
481 }
482 
483 // Templated function to follow channel references using parameter names
484 // and call an fn() lambda on the new parameter, or the original one.
485 // Unlike OP_Parameters::followChannelReferences, the arguments owner and pn
486 // are read-only.
487 // Returns true if a channel was followed or false if it wasn't.
488 // fn(bool followed, T* newowner, const UT_StringHolder &pn)
489 template <typename FN, typename T>
490 bool
492  T *owner, const UT_StringHolder &pn, FN &&fn)
493 {
494  auto op = dynamic_cast<OP_Node*>(owner);
495 
496  // Not an OP_Node, can't have channel references.
497  if (!op)
498  {
499  fn(false, owner, pn);
500  return false;
501  }
502 
503  PRM_ParmList *plist = op->getParmList();
504  int vi = -1;
505  int pi = plist->getParmIndex(pn, vi);
506  UT_ASSERT(pi>=0 && vi>=0);
507  PRM_Parm *parm = plist->getParmPtr(pi);
508  if (!parm)
509  {
510  fn(false, owner, pn);
511  return false;
512  }
513 
514  OP_Node *newop = op;
515  PRM_Parm *newparm = parm;
516  int newvecidx = vi;
517  OP_Parameters::followChannelReferences(opt, newop, newparm, newvecidx);
518  if (newop==op && newparm==parm && newvecidx==vi)
519  {
520  fn(false, owner, pn);
521  return false;
522  }
523 
524  UT_StringHolder newpn = newparm->getChannelToken(newvecidx);
525  T *newowner = (T*)newop;
526  fn(true, newowner, newpn);
527  return true;
528 }
529 
530 #endif
GLuint GLsizei const GLchar * message
Definition: glcorearb.h:2543
void adoptFromString(UT_String &str)
OP_API void OPmarkRootNodes(UT_BitArray &roots, const OP_NodeList &nodes, bool assume_picked)
PRM_Parm * getParmPtr(const UT_StringRef &theparmname, int &theparmidx)
OP_API bool OPconvertOrWarnExternalReferences(OP_Node *node, bool checktoplevelnode, UT_WorkBuffer &err)
OP_API OP_Node * OPfindOpInput(OP_Node *op, const char *find_op_type, bool include_me=true)
OP_API void OPaddVopSubnetMask(const UT_StringRef &name)
GT_API const UT_StringHolder time
constexpr SYS_FORCE_INLINE T & y() noexcept
Definition: UT_Vector4.h:493
const GLdouble * v
Definition: glcorearb.h:837
void addExplicitInput(DEP_MicroNode &inp, bool check_dup)
Methods for manipulating explicit edges.
GLuint start
Definition: glcorearb.h:475
SYS_FORCE_INLINE T * SYSconst_cast(const T *foo)
Definition: SYS_Types.h:136
constexpr SYS_FORCE_INLINE T & z() noexcept
Definition: UT_Vector3.h:667
fpreal evalFloat(int pi, int vi, fpreal t) const
UT_ErrorSeverity
Definition: UT_Error.h:25
void getChannelToken(UT_String &thestrref, int index=0) const
**But if you need a result
Definition: thread.h:622
OP_API void OPdisplayUIMessage(const char *message, UT_ErrorSeverity severity=UT_ERROR_MESSAGE, bool print_when_non_graphical=true)
bool OPfollowChannelRefFn(const OP_FollowChanRefsOptions &opt, T *owner, const UT_StringHolder &pn, FN &&fn)
Definition: OP_Utils.h:491
OP_API bool OPconvertOrWarnExternalOverrides(OP_Node *node, bool checktoplevelnode, UT_WorkBuffer &err)
GLdouble GLdouble x2
Definition: glad.h:2349
constexpr SYS_FORCE_INLINE T & x() noexcept
Definition: UT_Vector4.h:491
OP_API bool OPisStandInShaderParm(const PRM_Template &parm)
double fpreal64
Definition: SYS_Types.h:201
UT_SharedPtr< const PRM_DataItem > PRM_DataItemHandle
Definition: APEX_Include.h:55
constexpr SYS_FORCE_INLINE T & x() noexcept
Definition: UT_Vector2.h:423
PRM_Parm & getParm(int i)
OP_API bool OPmatchesShaderContextTag(const PRM_Template &parm, const char *context_name)
std::shared_ptr< T > UT_SharedPtr
Wrapper around std::shared_ptr.
Definition: UT_SharedPtr.h:36
constexpr SYS_FORCE_INLINE T & z() noexcept
Definition: UT_Vector4.h:495
void evalString(UT_String &val, int pi, int vi, fpreal t) const
OP_API void OPgetVopSubnetMask(OP_Node *node, UT_String &vopnetmask)
PRM_DataItemHandle evalDataInst(const UT_StringRef &name, const int *inst, int vi, fpreal t, int nestlevel=1) const
GLuint GLuint end
Definition: glcorearb.h:475
OP_API void OPtopologicalSort(UT_IntArray &order, const OP_NodeList &nodes, const UT_BitArray *roots=nullptr)
GLdouble y1
Definition: glad.h:2349
GLdouble GLdouble GLint GLint order
Definition: glad.h:2676
long long int64
Definition: SYS_Types.h:116
OP_API bool OPhasShaderContextTag(const PRM_Template *list, int start=0, int end=-1)
OP_API bool OPisPotentialShaderParm(const PRM_Template &parm)
OP_API void notifyPythonResultClients(PY_Result const &result, char const *script_source, char const *script_path)
fpreal evalFloatInst(const UT_StringRef &name, const int *inst, int vi, fpreal t, int nestlevel=1) const
GLenum GLenum severity
Definition: glcorearb.h:2539
GLuint const GLchar * name
Definition: glcorearb.h:786
PRM_DataItemHandle evalData(int pi, int vi, fpreal t) const
OP_API bool OPcheckForVopnetDefinedNodes(OP_Node *node, UT_WorkBuffer &err)
void evalStringRaw(UT_String &val, int pi, int vi, fpreal t) const
static void followChannelReferences(const OP_FollowChanRefsOptions &opt, OP_Node *&newop, PRM_Parm *&newparm, int &newvecidx)
OP_API void OPcreateStickyNoteAboutCachedCode(OP_Network *subnet)
void evalStringInst(const UT_StringRef &name, const int *inst, UT_String &val, int vi, fpreal t, int nestlevel=1) const
OP_API bool OPisLegacyShaderParm(const PRM_Template &parm, OP_Node *owner)
__hostdev__ constexpr T pi()
Pi constant taken from Boost to match old behaviour.
Definition: NanoVDB.h:976
fpreal64 fpreal
Definition: SYS_Types.h:278
Utility class for containing a color ramp.
Definition: UT_Ramp.h:96
#define OP_API
Definition: OP_API.h:10
void updateRampFromMultiParm(fpreal t, const PRM_Parm &m, UT_Ramp &ramp, bool *time_dep=nullptr, DEP_MicroNode *depnode=nullptr) const
constexpr SYS_FORCE_INLINE T & w() noexcept
Definition: UT_Vector4.h:497
OP_API void OPwarnBadRefs(UT_WorkBuffer &msg, const UT_StringArray &badrefs)
UT_WeakPtr< PythonResultClient > WPtr
Definition: OP_Utils.h:463
OP_API void registerPythonResultClient(PythonResultClient::WPtr result_client)
#define UT_ASSERT(ZZ)
Definition: UT_Assert.h:156
exint evalInt(int pi, int vi, fpreal t) const
GLboolean r
Definition: glcorearb.h:1222
exint evalIntInst(const UT_StringRef &name, const int *inst, int vi, fpreal t, int nestlevel=1) const
int getParmIndex(const PRM_Parm *parm) const
GLdouble GLdouble GLdouble y2
Definition: glad.h:2349
PRM_Parm * getParmPtrInst(const UT_StringRef &parm_name, const int *instance, int nest_level)
Definition: PRM_ParmList.h:479
constexpr SYS_FORCE_INLINE T & y() noexcept
Definition: UT_Vector3.h:665
SYS_FORCE_INLINE PRM_ParmList * getParmList()
Definition: PRM_ParmOwner.h:73
OP_API void OPgetItemBounds(fpreal &x1, fpreal &y1, fpreal &x2, fpreal &y2, const OP_NetworkBoxItemList &items)
OP_API bool OPcheckForVopnetsUsedOutside(OP_Node *node, OP_NodeList *badvopnets)
std::weak_ptr< T > UT_WeakPtr
Definition: UT_SharedPtr.h:49
constexpr SYS_FORCE_INLINE T & y() noexcept
Definition: UT_Vector2.h:425
bool hasParm(const UT_StringRef &name) const
constexpr SYS_FORCE_INLINE T & x() noexcept
Definition: UT_Vector3.h:663