HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
OP_Node.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: The base class for all OP operators
9  *
10  */
11 
12 #ifndef __OP_Node_h__
13 #define __OP_Node_h__
14 
15 #include "OP_API.h"
16 #include "OP_BundleReferences.h"
17 #include "OP_Cache.h"
18 #include "OP_ConnectorId.h"
19 #include "OP_Context.h"
20 #include "OP_DataMicroNode.h"
21 #include "OP_DataTypes.h"
22 #include "OP_Dependency.h"
23 #include "OP_Error.h"
24 #include "OP_EventMicroNode.h"
25 #include "OP_InterestRef.h"
26 #include "OP_ItemId.h"
27 #include "OP_Lock.h"
28 #include "OP_NetworkBoxItem.h"
29 #include "OP_NodeFlags.h"
30 #include "OP_OpTypeId.h"
31 #include "OP_OTLLicenseType.h"
32 #include "OP_Parameters.h"
33 #include "OP_Value.h"
34 #include "OP_Version.h"
35 
36 #include <CH/CH_EventManager.h>
37 #include <CH/CH_Types.h>
38 #include <DEP/DEP_MicroNode.h>
39 #include <UT/UT_Algorithm.h>
40 #include <UT/UT_Array.h>
41 #include <UT/UT_ArrayMap.h>
42 #include <UT/UT_Assert.h>
43 #include <UT/UT_BitArray.h>
44 #include <UT/UT_BoundingBox.h>
45 #include <UT/UT_Color.h>
46 #include <UT/UT_Error.h>
47 #include <UT/UT_KnownPath.h>
48 #include <UT/UT_LockedRawPtr.h>
49 #include <UT/UT_Matrix4.h>
50 #include <UT/UT_Optional.h>
51 #include <UT/UT_Options.h>
52 #include <UT/UT_SharedPtr.h>
53 #include <UT/UT_SmallArray.h>
54 #include <UT/UT_String.h>
55 #include <UT/UT_StringHolder.h>
56 #include <UT/UT_StringMap.h>
57 #include <UT/UT_StringView.h>
58 #include <UT/UT_TokenString.h>
59 #include <UT/UT_UniquePtr.h>
60 #include <UT/UT_ValArray.h>
61 #include <UT/UT_Vector3.h>
62 #include <UT/UT_VectorTypes.h>
63 #include <UT/UT_XformOrder.h>
64 #include <SYS/SYS_AtomicInt.h>
65 #include <SYS/SYS_Deprecated.h>
66 #include <SYS/SYS_Math.h>
67 #include <SYS/SYS_Types.h>
68 
69 #include <iosfwd>
70 #include <utility>
71 #include <limits.h>
72 #include <string.h>
73 
74 class UT_CameraParms;
75 class UT_InfoTree;
76 class UT_IStream;
77 class UT_Ramp;
78 class UT_StringArray;
79 class UT_Undo;
80 class UT_WorkArgs;
81 class UT_WorkBuffer;
83 class IMG_Raster;
84 class PY_OpaqueObject;
85 class PY_Result;
86 class DD_Source;
87 class DD_ChoiceList;
88 class CL_Clip;
89 class CL_Track;
90 class CMD_Args;
91 class CH_Channel;
92 class CH_ChannelRef;
93 class CH_LocalVariable;
94 class PRM_BatchList;
95 class PRM_Name;
96 class PRM_Parm;
97 class PRM_ParmList;
98 class PRM_ParmMicroNode;
99 class PRM_RefId;
100 class PRM_Template;
101 class OP_Bundle;
102 class OP_DopParent;
103 class OP_Dot;
104 class OP_EditorContext;
105 class OP_GalleryEntry;
106 class OP_GlobContext;
107 class OP_Group;
108 class OP_IndirectInput;
109 class OP_Input;
110 class OP_Network;
111 class OP_NetworkBox;
112 class OP_Node;
113 class OP_NodeInfoParms;
115 class OP_Operator;
116 class OP_Output;
117 class OP_OutputCodeParms;
118 class OP_PostIt;
119 class OP_PreDefRules;
120 class OP_PropagateData;
121 class OP_SaveFlags;
123 class OP_UniGraphProvider;
124 class DOP_Parent;
125 class VOP_CodeGenerator;
128 
129 // avoid lengthy compilation dependency
131 
132 typedef int (*OP_EditCallback)(void *data, OP_Node *src,
133  CL_Track *track, fpreal t, fpreal value);
134 
138 
140 {
142  : myInput(p), myName(n) {}
145 };
146 
148 {
150  : myOutput(p), myName(n) {}
153 };
154 
156 {
157  OP_NodeParmRef(const OP_Node *eval_node = nullptr,
158  const PRM_Parm *parm_ref = nullptr,
159  int vi = -1)
160  : myEvalNode(eval_node)
161  , myParmRef(parm_ref)
162  , myVectorIndex(vi)
163  {
164  }
165 
166  bool operator==(const OP_NodeParmRef &other)
167  {
168  return (myEvalNode == other.myEvalNode
169  && myParmRef == other.myParmRef
170  && myVectorIndex == other.myVectorIndex);
171  }
172 
173  const OP_Node * myEvalNode; // node evaluating the given parameter
174  const PRM_Parm * myParmRef; // pointer to evaluated parameter
175  int myVectorIndex; // parameter component index
176 };
177 
179 {
182 };
183 
184 // Implement this class to change the behavior of OP_Node::notifyVarChange().
185 // It was too late in the dev cycle of 22.0 to add a virtual method to OP_Node.
187 {
188 public:
190  virtual bool opNotifyVarChange(const char *varname, OP_NodeList *changed_nodes = nullptr) = 0;
191 };
192 
193 // Callback to delay the evaluation of a transform
195 {
196 public:
198  virtual const UT_Matrix4D& eval(bool &ret) = 0;
199 };
200 
202 {
203 public:
205  const UT_StringHolder& name,
206  UT_Matrix4D *w,
207  UT_Matrix4D *l = nullptr,
208  OP_TransformCallback *parent_cb = nullptr,
209  int *timedep = nullptr)
210  : myTrackIndex(-1)
211  , myTrackCount(1)
212  , myTrackName(name)
213  , myWorldXfo(w)
214  , myLocalXfo(l)
215  , myParentXfo(parent_cb)
216  , myTimeDep(timedep)
217  {}
218 
220  int index, UT_Matrix4D *w,
221  UT_Matrix4D *l = nullptr,
222  OP_TransformCallback *parent_cb = nullptr,
223  int *timedep = nullptr)
224  : myTrackIndex(index)
225  , myTrackCount(1)
226  , myWorldXfo(w)
227  , myLocalXfo(l)
228  , myParentXfo(parent_cb)
229  , myTimeDep(timedep)
230  {}
231 
232  // Callback to delay the evaluation of a transform
236 
240  int *myTimeDep;
241 };
242 
243 // Utility for detecting cycles when traversing graphs
246 
250 typedef std::pair<const OP_Node *, OP_OutputIdx> opNodeOutput;
251 
252 // The prefix used to specify an operator where a path would normally be used.
253 #define OPREF_PREFIX "op:"
254 #define OPREF_PREFIX_LEN 3
255 
256 // This character is used to separate a node path from a string that
257 // represents some piece of data within the node's cook result.
258 #define OP_NODE_DATA_SEPARATOR ':'
259 
260 // Default value of hash for compiled code associated with this node that
261 // shouldn't conflict with the hash of any actual cached code.
262 #define DEFAULT_COMP_HASH_VALUE (17*19)
263 
264 // Please, no spaces in these table names!
265 #define INVALID_TABLE_NAME "Node"
266 #define OBJ_TABLE_NAME "Object"
267 #define SOP_TABLE_NAME "Sop"
268 #define CHOPNET_TABLE_NAME "ChopNet"
269 #define CHOP_TABLE_NAME "Chop"
270 #define ROP_TABLE_NAME "Driver"
271 #define SHOP_TABLE_NAME "Shop"
272 #define COP_TABLE_NAME "Cop"
273 #define COP2_TABLE_NAME "Cop2"
274 #define COP2NET_TABLE_NAME "CopNet"
275 #define VOP_TABLE_NAME "Vop"
276 #define VOPNET_TABLE_NAME "VopNet"
277 #define DOP_TABLE_NAME "Dop"
278 #define TOP_TABLE_NAME "Top"
279 #define TOPNET_TABLE_NAME "TopNet"
280 #define LOP_TABLE_NAME "Lop"
281 
282 // Manager and Director table names:
283 #define MGR_TABLE_NAME "Manager"
284 #define DIR_TABLE_NAME "Director"
285 #define DATA_TABLE_NAME "Data"
286 
287 // These are the "script" directories where help and initialization scripts
288 // are found.
289 #define INVALID_SCRIPT_NAME "node"
290 #define OBJ_SCRIPT_NAME "obj"
291 #define SOP_SCRIPT_NAME "sop"
292 #define CHOPNET_SCRIPT_NAME "ch"
293 #define CHOP_SCRIPT_NAME "chop"
294 #define ROP_SCRIPT_NAME "out"
295 #define SHOP_SCRIPT_NAME "shop"
296 #define COP_SCRIPT_NAME "cop"
297 #define COP2_SCRIPT_NAME "cop2"
298 #define COP2NET_SCRIPT_NAME "img"
299 #define VOP_SCRIPT_NAME "vop"
300 #define VOPNET_SCRIPT_NAME "vex"
301 #define DOP_SCRIPT_NAME "dop"
302 #define TOP_SCRIPT_NAME "top"
303 #define TOPNET_SCRIPT_NAME "tasks"
304 #define LOP_SCRIPT_NAME "lop"
305 
306 // Manager and Director scripts... I doubt these will be used.
307 #define MGR_SCRIPT_NAME "mgr"
308 #define DIR_SCRIPT_NAME "dir"
309 #define MAT_SCRIPT_NAME "mat"
310 #define DATA_SCRIPT_NAME "data"
311 
312 // These are the op type names. These are used by icons among others.
313 #define INVALID_OPTYPE_NAME "NODE"
314 #define OBJ_OPTYPE_NAME "OBJ"
315 #define SOP_OPTYPE_NAME "SOP"
316 #define CHOPNET_OPTYPE_NAME "CHOPNET"
317 #define CHOP_OPTYPE_NAME "CHOP"
318 #define ROP_OPTYPE_NAME "ROP"
319 #define SHOP_OPTYPE_NAME "SHOP"
320 #define COP_OPTYPE_NAME "COP"
321 #define COP2_OPTYPE_NAME "COP2"
322 #define COP2NET_OPTYPE_NAME "IMG"
323 #define VOP_OPTYPE_NAME "VOP"
324 #define VOPNET_OPTYPE_NAME "VOPNET"
325 #define DOP_OPTYPE_NAME "DOP"
326 #define TOP_OPTYPE_NAME "TOP"
327 #define TOPNET_OPTYPE_NAME "TOPNET"
328 #define LOP_OPTYPE_NAME "LOP"
329 
330 // These are the types of the manager nodes & director nodes.
331 // Manager nodes are things like /shop which don't have a specific
332 // type
333 // The director node is the root node which has everything inside it.
334 #define MGR_OPTYPE_NAME "MGR"
335 #define DIR_OPTYPE_NAME "DIR"
336 #define DATA_OPTYPE_NAME "DATA"
337 
338 /// Nice label names used by network view, corresponding to OP_OpTypeId
339 OP_API extern const char *OPtypeIdLabels[NUM_MANAGERS];
340 
341 // Stores the status of the node - undefined for currently
342 // uncached state,
344 {
348 };
349 
350 // These are some special defines used by VOPs. They need to be here
351 // because the OP_ConnectionMemory has to handle these operators in a
352 // special way,
353 #define OP_NAME_INPUT "input"
354 #define OP_NAME_OUTPUT "output"
355 #define OP_NAME_SUBOUTPUT "suboutput"
356 #define OP_NAME_SUBINPUT "subinput"
357 #define OP_NAME_COLLECT "collect"
358 
359 // These defines provide a common place where the names of the management
360 // operator types are defined.
361 #define SHOP_MANAGEMENT_OPTYPE "shopnet"
362 #define COP_MANAGEMENT_OPTYPE "copnet"
363 #define COP_FILTERLIST_OPTYPE "copnet_filterlist"
364 #define COP2_MANAGEMENT_OPTYPE "cop2net"
365 #define ROP_MANAGEMENT_OPTYPE "ropnet"
366 #define CHOP_MANAGEMENT_OPTYPE "chopnet"
367 #define SOP_MANAGEMENT_OPTYPE "sopnet"
368 #define OBJ_MANAGEMENT_OPTYPE "objnet"
369 #define VOP_MANAGEMENT_OPTYPE "vopnet"
370 #define DOP_MANAGEMENT_OPTYPE "dopnet"
371 #define TOP_MANAGEMENT_OPTYPE "topnet"
372 #define LOP_MANAGEMENT_OPTYPE "lopnet"
373 
374 // This class has each of the above entities filled out.
375 // You can thus convert between different types by looking up
376 // with the known key and extracting what you want from this class.
377 // Looking up by id is fast, the rest requires a scan.
379 {
380 public:
385 };
386 
387 /// Options class for use with OP_Node::saveCommand()
389 {
390  // Initialize the options to match the opscript defaults
392  ( bool values_only_ = false
393  , bool defaultstoo_ = true
394  , bool docreate_ = true
395  , bool doparms_ = true
396  , bool doflags_ = true
397  , bool dowires_ = true
398  , bool dowiresout_ = true
399  , bool frames_ = false
400  , bool dogeneral_ = false
401  , bool dochblock_ = true
402  , bool dospareparms_ = true
403  , bool omit_version_info_ = false
404  )
405  : values_only(values_only_)
406  , defaultstoo(defaultstoo_)
407  , docreate(docreate_)
408  , doparms(doparms_)
409  , doflags(doflags_)
410  , dowires(dowires_)
411  , dowiresout(dowiresout_)
412  , frames(frames_)
413  , dogeneral(dogeneral_)
414  , dochblock(dochblock_)
415  , dospareparms(dospareparms_)
416  , omit_version_info(omit_version_info_)
417  {
418  }
419 
422  bool docreate;
423  bool doparms;
424  bool doflags;
425  bool dowires;
427  bool frames;
428  bool dogeneral;
429  bool dochblock;
432 };
433 
434 //___________________________________________________________________________
435 
436 
437 //
438 // a container class to describe the instantaneous state of a parameter
439 //
441 {
442 public:
446  int myIndex;
448 
449  int operator==(const opParmData &v) const
450  {
451  return (myValue == v.myValue &&
452  myLabel == v.myLabel &&
453  myNode == v.myNode &&
454  myIndex == v.myIndex &&
455  mySubIndex == v.mySubIndex
456  );
457  }
458 };
459 
460 
461 // Blank class definitions for all our node types...
462 class OBJ_Node;
463 class SOP_Node;
464 class CHOPNET_Node;
465 class CHOP_Node;
466 class COP_Node;
467 class COP2_Node;
468 class COP2NET_Node;
469 class ROP_Node;
470 class TOP_Node;
471 class TOPNET_Node;
472 class LOP_Node;
473 class SHOP_Node;
474 class VOP_Node;
475 class VOPNET_Node;
476 class DOP_Node;
477 
478 #define INSTANTIATE_FINDNODE_FUNCTIONS(PREFIX) \
479  PREFIX##_Node *find##PREFIX##Node(const char *path) const \
480  { \
481  OP_Node *node; \
482  \
483  node = findNode(path); \
484  if (node) return node->castTo##PREFIX##Node(); \
485  return 0; \
486  }
487 #define INSTANTIATE_CASTNODE_FUNCTIONS(PREFIX) \
488  PREFIX##_Node *castTo##PREFIX##Node() const \
489  { \
490  /* If this is triggered, use CAST_FOONODE instead */ \
491  /* This is because foo->bar() should not be done with */ \
492  /* NULL foo for aesthetic reasons. */ \
493  { const void *this_local = this; \
494  UT_ASSERT(this_local); \
495  if (!this_local) return 0; } \
496  if (getOpTypeID() == PREFIX##_OPTYPE_ID) \
497  { \
498  return (PREFIX##_Node *) this; \
499  } \
500  return 0; \
501  }
502 
503 /// This macro allows us to run another macro for all node types
504 #define INSTANTIATE_FOR_ALL_NODE_TYPES(MACRO_FUNC) \
505  MACRO_FUNC(OBJ) \
506  MACRO_FUNC(SOP) \
507  MACRO_FUNC(CHOPNET) \
508  MACRO_FUNC(CHOP) \
509  MACRO_FUNC(ROP) \
510  MACRO_FUNC(SHOP) \
511  MACRO_FUNC(COP) \
512  MACRO_FUNC(COP2) \
513  MACRO_FUNC(COP2NET) \
514  MACRO_FUNC(VOP) \
515  MACRO_FUNC(VOPNET) \
516  MACRO_FUNC(DOP) \
517  MACRO_FUNC(TOP) \
518  MACRO_FUNC(TOPNET) \
519  MACRO_FUNC(LOP)
520 
527 
529 {
530 public:
531  // Methods to convert our enums and strings:
532  static const OP_TypeInfo *getOpInfoFromOpTypeID(OP_OpTypeId opid);
533  static const OP_TypeInfo *getOpInfoFromOpTypeName(const char *name);
534  static const OP_TypeInfo *getOpInfoFromTableName(const char *name);
535  static const OP_TypeInfo *getOpInfoFromScriptDir(const char *dir);
536 
538  { return myParent; }
540  { return myRootCompiledParent; }
541 
542  //Return the network this item resides in (i.e. getParent()). This method
543  //was introduced to provide a standardized way of accessing the parent
544  //network of all different network box item types.
545  OP_Network *getParentNetwork() const override;
546 
547  // This function looks up our parent tree to determine if the given node
548  // is our parent, grandparent, great-grandparent...
549  bool getIsContainedBy(const OP_Node *testparent) const;
550 
551  /// Return the name of this node's parent
552  const UT_StringHolder &getNetName() const;
553 
554  /// This returns the OP_OpTypeId which corresponds to this node type.
555  /// Management nodes will return the type they really are, which
556  /// is likely different than the network they currently reside in.
557  virtual OP_OpTypeId getOpTypeID() const
558  { return INVALID_OPTYPE_ID; }
559 
560  // This is the proper way to determine the optype.
561  // Do not assume your parents child type is your type! This will only
562  // become less true as time goes on :>
563  // The strings returned are the *_OPTYPE_NAME defined above
564  virtual const char *getOpType() const;
565 
566  OP_ItemType getItemType() const override;
567 
568  /// @anchor OP_Node_findFOONode
569  ///
570  /// FOO_Node *findFOONode(const char *path) const; @n
571  /// This function searches for the node at path relative
572  /// to this node. If not found, or if the found node is
573  /// not of type FOO_Node, it returns NULL. The result
574  /// is already cast to FOO_Node.
575  /// findOBJNode(const char *path)
576  /// findSOPNode(const char *path)
577  /// findCHOPNETNode(const char *path)
578  /// findCHOPNode(const char *path)
579  /// findROPNode(const char *path)
580  /// findSHOPNode(const char *path)
581  /// findCOPNode(const char *path)
582  /// findCOP2Node(const char *path)
583  /// findCOP2NETNode(const char *path)
584  /// findCOPNode(const char *path)
585  /// findVOPNode(const char *path)
586  /// findVOPNETNode(const char *path)
587  /// findDOPNode(const char *path)
588  /// findTOPNode(const char *path)
589  /// findTOPNETNode(const char *path)
590  /// findLOPNode(const char *path)
591  // @{
593  // @}
594 
595  /// @anchor OP_Node_castToFOONode
596  ///
597  /// FOO_Node *castToFOONode() const; @n
598  /// This type checks the current node against FOO_Node.
599  /// If the cast is legal, this is returned. Otherwise, NULL.
600  /// While it likely will do the "right" thing with this == NULL,
601  /// that case is UT_ASSERTed as it is just asking for trouble.
602  /// castToOBJNode()
603  /// castToSOPNode()
604  /// castToCHOPNETNode()
605  /// castToCHOPNode()
606  /// castToROPNode()
607  /// castToSHOPNode()
608  /// castToCOPNode()
609  /// castToCOP2Node()
610  /// castToCOP2NETNode()
611  /// castToCOPNode()
612  /// castToVOPNode()
613  /// castToVOPNETNode()
614  /// castToDOPNode()
615  /// castToTOPNode()
616  /// castToTOPNETNode()
617  /// castToLOPNode()
618  // @{
620  // @}
622  /// Obtain the node's script which is called when it is being deleted.
623  const UT_String &getDelScript() const { return myDelScript; }
624 
625  /// Set the node's deletion script. Returns true if the delete script was
626  /// set successfully.
627  bool setDelScript(const char *str);
628 
629  /// Accessors for this node's comment string.
630  // @{
631  const UT_String &getComment() const { return myComment; }
632  bool setComment(const char *str);
633  // @}
634 
635  /// Overrides the NetworkBoxItem implementations of getColor and setColor
636  /// to provide support Node-specific features like using the default color.
637  // @{
638  UT_Color getColor() const override;
639  bool setColor(const UT_Color &col) override;
640  // @}
641 
642  /// Accessors for this node's flag indicating if it should use its
643  /// operator's default color instead of its local color.
644  // @{
645  bool getColorDefault() const;
646  bool setColorDefault(bool usedefault);
647  // @}
648 
649  /// Accessors for this node's shape
650  // @{
651  const UT_StringHolder &getNodeShape() const;
652  void setNodeShape(const UT_StringHolder &shape);
653  // @}
654 
655  /// Node position/scale is used by the UI.
656  // @{
657  // These are in absolute coordinates, not the UI coordinates found in
658  // OPUI_Worksheet, though.
659  void setXY(fpreal x, fpreal y) override;
660  fpreal getX() const override { return myPosX; }
661  fpreal getY() const override { return myPosY; }
662  fpreal getW() const override;
663  fpreal getH() const override;
664  // @}
665 
666  void pickRequest(int shift);
667 
668  /// Set allow_rel_paths to true to accept "." or ".." as valid paths.
669  static bool isValidOpName(const UT_StringView &s,
670  bool allow_rel_paths = false,
671  bool ignore_node_names_env_var = false);
672  static bool isValidOpName(const char *s,
673  bool allow_rel_paths = false,
674  bool ignore_node_names_env_var = false)
675  {
676  return isValidOpName(UT_StringView(s),
677  allow_rel_paths,
678  ignore_node_names_env_var);
679  }
680  static bool isValidOpName(const UT_StringHolder &str,
681  bool allow_rel_paths = false,
682  bool ignore_node_names_env_var = false)
683  {
684  return isValidOpName(str.c_str(),
685  allow_rel_paths,
686  ignore_node_names_env_var);
687  }
688  static bool isValidOpName(const UT_String &str,
689  bool allow_rel_paths = false,
690  bool ignore_node_names_env_var = false)
691  {
692  return isValidOpName(str.c_str(),
693  allow_rel_paths,
694  ignore_node_names_env_var);
695  }
696  static bool isValidOpPath(const UT_StringRef &s);
697  static bool forceValidOpName(UT_String &name);
698 
699  /// Override these methods so that search-and-replace operations
700  /// affect our delete script as well as our parameters.
701  // @{
702  int findString(const char *str, bool fullword,
703  bool usewildcards) const override;
704  int changeString(const char *from, const char *to,
705  bool fullword) override;
706  // @}
707 
708  /// Mark this node, its descendants, and all data dependents containing
709  /// varname as being dirty. If changed_nodes is non-NULL, then it is
710  /// updated with the list of dirtied nodes which contains varname.
711  /// Returns true if at least one node was dirtied.
712  bool notifyVarChange(
713  const char *varname,
714  OP_NodeList *changed_nodes = nullptr);
715 
716  // These are no-ops for nodes but will be implemented for networks:
717  virtual int getNchildren() const;
718  virtual OP_Node *getChild(const char *name, int *hint=nullptr) const;
719  virtual OP_Node *getChild(int index) const;
720  void getPickedChildren(OP_NodeList &picked,
721  bool include_hidden=false) const;
722  void getAllChildren(OP_NodeList &children) const;
723  virtual OP_Node *matchChild(
724  const char *pattern,
725  OP_Node *prevmatch = nullptr,
726  const char *optype = nullptr,
727  int casesensitive = 0) const;
728  virtual OP_Node *matchChildBackwards(
729  const char *pattern,
730  OP_Node *prevmatch = nullptr,
731  const char *optype = nullptr,
732  int casesensitive = 0) const;
733  virtual OP_Network *createProxyRefNode( const char *path );
734 
735  // Returns the maximum error severity of ourself and all of our
736  // children. For efficiency, early-exits at ABORT (so embedded
737  // FATAL might be shadowed by an ABORT) but in practice FATAL is
738  // unused.
739  OP_ERROR getChildErrorSeverity();
740 
741  // Returns the list of nodes eligible to be considered for child
742  // errors.
743  virtual void getPotentialChildErrorNodes(OP_NodeList &nodes) const;
744 
745  /// Returns a provider object that creates and loads a uni-graph from this
746  /// op node. Returns null if this op node does not provide any uni-graph.
747  virtual OP_UniGraphProvider *getUniGraphProvider();
748 
749  /// Returns the node from which the UniGraphProvider loads its graph.
750  /// The default implementation checks for a dive target with a string of the
751  /// form "graph:graphtype:nodepath". If a dive target is not found, it is
752  /// assumed that this node should be the provider node.
753  virtual OP_Node *getUniGraphProviderNode();
754 
755  /// Without going to the expense of actually creating the UniGraphProvider
756  /// object, return a string indicating the type of provider that will be
757  /// returned if you were to call getUniGraphProvider. There is no rule
758  /// here, but by convention the returned value should be the name of the
759  /// C++ class that will be returned by getUniGraphProvider.
760  virtual UT_StringHolder getUniGraphProviderType(bool allow_cook);
762  // Returns the node with the requested unique integer identifier.
763  static OP_Node *lookupNode(int unique_id, bool include_proxy=false)
764  {
765  if( unique_id >= 0 && unique_id <= theUniqueId
766  && theUniqueNodes[unique_id] )
767  {
768  if( include_proxy || !theUniqueNodes[unique_id]
769  ->isProxyRefNode() )
770  return theUniqueNodes[unique_id];
771  }
772  return nullptr;
773  }
774  static int getNumUniqueIds()
775  { return theUniqueId + 1; }
776  // Fills the provided array with every node that currently exists.
777  static void getAllNodes(OP_NodeList &nodes);
778 
779  int getUniqueId() const
780  { return myUniqueId; }
781  int64 getItemUniqueId() const override
782  { return myUniqueId; }
783 
784  // The following function will take a standard pattern and expand
785  // all the groups out of the pattern, leaving a simple pattern
786  // in the result.
787  bool expandGroupPattern(const char *pattern,
788  UT_String &result,
789  bool expand_to_full_paths = false);
790 
791  // The following methods take a standard pattern and return whether
792  // the pattern contains the specified bundle or group.
793  bool patternContainsBundle(const char *pattern,
794  const OP_Bundle *bundle) const;
795  bool patternContainsGroup(const char *pattern,
796  const OP_Group *group) const;
797 
798  virtual int isManager() const;
799  // This differs from isManager. Managers are the old school static
800  // things which are always present in fixed directories. Management
801  // nodes are managers that are in the wrong directory.
802  virtual int isManagementNode() const;
803  // This is a bit broader than management nodes. These nodes may
804  // be in the right directory, but represent an unexpected change
805  // of directory type, so need to be tracked so our tree filter
806  // will know about them.
807  bool isEffectivelyAManagementNode() const;
808 
809  // Returns ture if this node contains material nodes.
810  virtual bool isMaterialManager() const;
811 
812  // This function checks if the node is a subnet. Now that we can have
813  // NWN subnets (object subnets, vopnet subnets), we need to explicitly
814  // specify if these types of subnets count. In some cases we want them
815  // to count (such as checking for VOPNET subnets to see if we can
816  // generate code, or SHOP subnets to see if we can save to a palette).
817  // In other cases we want to exclude these management ops (such as
818  // when deciding to show the "Create Type From" menu item or checking
819  // if we can do an opwire -i command).
820  virtual int isSubNetwork(bool includemanagementops) const;
821  virtual int isNetwork() const;
822  virtual int isInSubNetwork() const;
823 
824  bool isProxyRefNode() const
825  { return myIsProxyRefNode; }
826  void setProxyRefNode(bool f)
827  { myIsProxyRefNode = f; }
828 
829  // Used by SOPs to determine which node is the output of a subnetwork.
830  virtual bool isOutputNode() const;
831  // Returns which output this node represents.
832  virtual OP_OutputIdx whichOutputNode() const;
833 
834  // isNetworkWithKids() will return 1 if the node is a network and the
835  // operator table for the node contains children which can be added to the
836  // node.
837  int isNetworkWithKids() const;
838 
839  virtual int isVex() const;
840 
841  // methods for managing the bundles we depend on in so that any change to
842  // the bundle in which we are interested triggers bundleChange call.
843  // NB: getParmBundle methods find or create a bundle ad it to the
844  // internal list of referenced bundles
845  OP_Bundle * getParmBundle(const char* parm_name, int vector_index,
846  UT_String &pattern, OP_Network *creator,
847  const char *filter);
848  void markBundleRefsAsUnused();
849  void cleanUnusedBundleRefs();
850  void cleanAllBundleRefs();
851 
852  static void getValueAsBundlePaths(fpreal t,
853  UT_WorkBuffer &resultbuf,
854  PRM_Parm *parm, int index,
855  OP_Node *srcnode
856  );
857  static void getValueAsBundlePaths(fpreal t,
858  OP_NodeList &resultnodes,
859  PRM_Parm *parm, int index,
860  OP_Node *srcnode
861  );
862 
863  // The bundleChanged() method is called whenever a bundle referenced by the
864  // OP is changed. The bundle is passed to the OP to let the OP know that
865  // it's out of date. The function should return 1 if the event was handled
866  // properly or 0 if it failed. The return codes are used for debugging
867  // only.
868  virtual bool bundleChanged(const OP_Bundle *bundle);
869  // If a bundle changes, you should call this method to touch the parameter
870  // which the bundle affects. The name is the token of the parm.
871  void touchBundleParm(const char *name);
872  void touchBundleParm(int parm_index);
874  // Function to determine if Display and Render node ptrs are the same
875  virtual int getDandROpsEqual() { return 1; }
876  // Function to update info about whether Render and Display node ptrs
877  // are the same. Recurses tree and updates all kids values.
878  virtual int updateDandROpsEqual(int = 1) { return 1; }
879 
880  /// Check to see whether @c node is an ancestor of @c this node in the
881  /// input hierarchy. Optionally check extra inputs. This method will
882  /// recurse using @c getInputs() (and optional getExtraInputNodes()
883  /// @note This node is considered to be an ancestor of itself
884  bool isInputAncestor(const OP_Node *parent,
885  bool check_extra=true) const;
886  /// Check to see whether the @c parent node is an ancestor of @c this node
887  /// in the parent/child hierarchy. That is, this method will call
888  /// getParent()/getChild() to traverse the hierarchy.
889  /// @note This node is considered to be an ancestor of itself
890  bool isParentAncestor(const OP_Node *parent) const;
891 
892  /// Get the info text for this op. This non-virtual function does
893  /// all the stuff common to all operator types.
894  /// @warning The return value is the value of the work buffer in the
895  /// OP_NodeInfoParms. Thus, you should never do @code
896  /// str = node->getInfoText(context, OP_NodeInfoParms());
897  /// @endcode
898  /// Since the lifetime of the temporary may not be long enough to extract
899  /// the string properly.
900  const char *getInfoText(OP_Context &context,
902  // Get Info Text that is specific to this node type.
903  virtual void getNodeSpecificInfoText(OP_Context &context,
905 
906  /// Returns node-specific data about this node. This is a generic
907  /// way to pass typed data that may be unique to node type. It is
908  /// not meant for common data.
909  /// This is with respect to the last-cooked, or cached, nature of
910  /// of the node so does not take a context - the caller will be expected
911  /// to have pre-cooked the node, as it's state should not change as
912  /// a result.
913  virtual UT_OptionsHolder getNodeSpecificInfoData() const;
914 
916  {
917  OTLSYNC_DELAY = 0,
918  OTLSYNC_DOSYNC = 1,
919  };
920 
921  /// Uses the path (eg. "/obj/geo1") to find a node in our hierarchy
922  OP_Node *findNode(const char *path, OTLSyncMode syncmode = OTLSYNC_DOSYNC) const;
923 
924  /// Same as findNode() except it will return NULL if the path is to a node
925  /// that is either not a descendant of this node, or if it isn't the same
926  /// type as our children.
927  OP_Node *findSubNode(const char *path) const;
928 
929  // These are all Implemented in OP_Network, but put here as a virtual to
930  // make working / with hscript easier so that it can be called directly on
931  // an op node
932  virtual OP_NetworkBox *findNetworkBox(const char *name)
933  { return nullptr; }
934  virtual OP_PostIt *findPostItNote(const char *const_path)
935  { return nullptr; }
936  virtual OP_Dot *findDot(const char *const_path)
937  { return nullptr; }
938  virtual OP_SubnetIndirectInput *findParentInput(const char *const_path)
939  { return nullptr; }
940  virtual OP_NetworkBoxItem *findItem(const char *const_path,
941  OP_ItemTypeMask item_type =
943  { return nullptr; }
944 
945  // These functions will adhere to certain conventions, such as a reference
946  // to an object actually means a reference to the display or render
947  // guy in that object. This will also check this->isCookingRender
948  // to determine if it should auto-use the Render or Display.
949  // These will not fail if the returned node is the node itself.
950  SOP_Node *getSOPNode(const char *path, int addextra = 0,
951  bool *got_by_flag=nullptr) const;
952  // This method will use the render node of the composite network if
953  // it is a comp rather than a cop2 that is pointed to...
954  COP_Node *getCOPNode(const char *path, int addextra = 0) const;
955  COP2_Node *getCOP2Node(const char *path, int addextra = 0) const;
956 
957  // And this one will use the display node, which corresponds to the
958  // cook node in DOPs land.
959  DOP_Node *getDOPNode(const char *path, int addextra = 0) const;
960  ROP_Node *getROPNode(const char *path, int addextra = 0) const;
961  // This method will use the audio node of the chop network
962  CHOP_Node *getCHOPNode(const char *path, int addextra = 0,
963  bool *got_by_flag=nullptr) const;
964  // This method will use the display node of the top network
965  TOP_Node *getTOPNode(const char *path, int addextra = 0) const;
966  // This method will use the display node of the lop network
967  LOP_Node *getLOPNode(const char *path, int addextra = 0) const;
968  OBJ_Node *getOBJNode(const char *path, int addextra = 0) const;
969 
970  OP_Node *castToOPNode() override { return this; }
971  const OP_Node *castToOPNode() const override { return this; }
972 
973  /// Returns the path of this node relative to its getCreator()
974  virtual void getPathWithSubnet(UT_String &str) const;
975  void getPathWithSubnet(UT_StringHolder &str) const
976  { UT_String tmp; getPathWithSubnet(tmp); str.adoptFromString(tmp); }
977 
978  /// This will try to complete the path by finding the longest suffix
979  /// that will work with the given prefix. It will only complete up
980  /// to the next child. If it finds a valid child, it will append
981  /// a slash (/).
982  void completePath(const char *prefixpath,
983  UT_String &completepath) const;
984 
985  virtual CH_Channel *getTrackChannel(const char *name);
986 
987  virtual bool findParmFromTrack(const OP_FollowChanRefsOptions& opt,
988  const char *trackname,
989  OP_NodeParmRefCycle &cycle,
990  OP_Node *&node,
991  PRM_Parm *&parm, int &vecidx);
992 
993  // Batch evaluation of named parameters. This method requires extra lookup
994  // since parameters are specified by names, but it can handle generic
995  // parameter layout.
996  virtual void evaluateBatchParms(PRM_BatchList &list, fpreal now);
997 
998  // Do global expansion on a pattern - get lists of channels or nodes
999  // If expand is given, concatenated with full list of names
1000  // If list is given, appended with list of nodes.
1001  // If dependent given, addExtraInputs.
1002  void globNodes(const char *pat, UT_String *expand,
1003  UT_Array<OP_Node *> *list=nullptr,
1004  OP_GlobContext *context = nullptr,
1005  const char *prefix = " ");
1006 
1007  CH_Channel *findChannel(const char *path);
1008  void globChannels(const char *, UT_String &expand,
1009  OP_GlobContext *context = nullptr,
1010  const char *prefix = " ") const;
1011 
1012  void globChannels(const char *pattern,
1013  CH_ChannelList &clist,
1014  OP_GlobContext *context = nullptr,
1015  OP_Node *dependent = nullptr);
1016  // If use_multi_match is false, the pattern is
1017  // treated as a single pattern instead of a space
1018  // separated list of patterns. (Only applies
1019  // to direct parameter names, i.e. the pattern must not be
1020  // a path and must not contain a slash)
1021  void globChanRefs(const char *pattern,
1022  CH_ChannelRefList &list,
1023  OP_GlobContext *context = nullptr,
1024  OP_Node *dependent = nullptr,
1025  bool use_multi_match = true);
1026 
1027  int globParms(const char *pattern, fpreal t,
1028  UT_Array<opParmData> &list,
1029  OP_GlobContext *context = nullptr,
1030  OP_Node *dependent = nullptr,
1031  int calc_value = 1);
1032 
1033  // this version only globs the current node
1034  void globNodeParms(const char *pattern, fpreal t,
1035  UT_Array<opParmData> &list,
1036  OP_GlobContext *context,
1037  OP_Node *dependent,
1038  int calc_value,
1039  bool animated_only);
1040 
1041  // this version only globs the current node
1042  void globNodeChannels(const char *pattern,
1043  CH_ChannelList &list,
1044  OP_GlobContext *context,
1045  int *parm_start = nullptr,
1046  UT_IntArray *parm_indices = nullptr,
1047  UT_IntArray *parm_sub_indices = nullptr
1048  ) const;
1049 
1050  // this version only globs the current node
1051  // If use_multi_match is false, the pattern is
1052  // treated as a single pattern instead of a space
1053  // separated list of patterns
1054  void globNodeChanRefs(const char *pattern,
1055  CH_ChannelRefList &list,
1056  OP_GlobContext *context,
1057  int *parm_start = nullptr,
1058  UT_IntArray *parm_indices = nullptr,
1059  UT_IntArray *parm_sub_indices=nullptr,
1060  bool use_multi_match = true
1061  ) const;
1062 
1063  ///Same as 'globNodes', except for network boxes. This is to be implemented
1064  ///by OP_Network, but has been put here so it can be called directly on
1065  ///OP_Node like all the other "glob" methods without a cast
1066  virtual void globNetworkBoxes(const char *pat, UT_String *expand,
1067  UT_ValArray<OP_NetworkBox *> *list=nullptr,
1068  OP_GlobContext *glob_context = nullptr,
1069  const char *prefix = " ");
1070 
1071  virtual void globPostIts(const char *pat, UT_String *expand,
1072  UT_ValArray<OP_PostIt *> *list=nullptr,
1073  OP_GlobContext *glob_context = nullptr,
1074  const char *prefix = " ");
1075 
1076  // Fetch all channels from this node on down.
1077  int getAllChannels(CH_ChannelList &list, int scoped=0);
1078 
1079  // If you override opChanged() in a sub-class, you must call
1080  // the OP_Node base method from the sub-class method
1081  void opChanged(OP_EventType reason,
1082  void *data = nullptr) override;
1083 
1084  // If you override opChanged() in a subclass, you should first call
1085  // opShouldHandleChange() before taking any custom action.
1086  virtual bool opShouldHandleChange(OP_EventType reason);
1087 
1088  // This function is called whenever we have a parameter that references
1089  // another parameter, and that referenced parameter changes. The pi
1090  // value is the index of the parameter containing the reference.
1091  virtual void referencedParmChanged(int pi);
1092 
1093  /// Mark this node as needing a full recook.
1094  /// If 'evensmartcache' is true, a recook will occur even if all the
1095  /// parameters match in this node and all its inputs (only valid for
1096  /// COP2_Node).
1097  virtual void forceRecook(bool evensmartcache = true);
1098 
1099  /// This method causes any operators that load files to recook.
1100  /// By default, this searches for 'file' operators by iterating through
1101  /// inputs. Parms of type PRM_FILE are also marked dirty. Other nodes that
1102  /// load files differently may wish to override this method.
1103  virtual void reloadExternalFiles();
1104 
1105  /// Determines if this node needs to cook.
1106  ///
1107  /// The queryonly flag will not flag this as a read attempt to the
1108  /// caching mechanisms, and thus not update the touch time.
1109  virtual unsigned needToCook(OP_Context &context, bool queryonly=false);
1110 
1111  /// Cook this node's data. Returns true upon success, false otherwise.
1112  ///
1113  /// Upon failure, use OP_Parameters::error() and
1114  /// OP_Parameters::getErrorMessages() to determine reason.
1115  virtual bool cook(OP_Context &context);
1116 
1117  /// The cook lock is used to protect per node data structures during
1118  /// cooking. Subclasses should use this when calling cook(). Example:
1119  /// @code
1120  /// cookLockedExecute([&]() {
1121  /// // run code
1122  /// });
1123  /// @endcode
1124  /// @note Include OP_NodeCookLockedExecute.h to call this.
1125  template <typename F>
1126  void cookLockedExecute(const F &functor);
1127 
1128  /// The cook lock is used to protect per node data structures during
1129  /// cooking. Subclasses should use lock this to protect private data.
1130  OP_CookLock & getCookLock() { return myCookLock; }
1131 
1132  // This normally chains to cookInputGroups.
1133  // Some networks, such as SOPs, use it to be able to
1134  // properly lock their gdp pointer around the cook.
1135  virtual OP_ERROR pubCookInputGroups(OP_Context &context, int alone = 0);
1136 
1137  void bumpVersionParm()
1138  {
1139  dataMicroNode().bumpModVersion();
1140  if (hasIndepParmListMicroNode())
1141  parmListMicroNode().bumpModVersion();
1142  }
1143  int cookParmsModified() const
1144  { return parmListMicroNodeConst()
1145  .isModVersionOutdated(); }
1146 
1147  // The data class of an OP is currently used solely for networks which
1148  // contain heterogeneous node types (i.e. used in SHOP networks to
1149  // distinguish different shader types). A data class of 0 is returned by
1150  // default.
1151  // A value of 0 is returned by default.
1152  virtual int getDataClass() const;
1153 
1154  // The xform order for how to interpret the given channel. Default
1155  // is XYZ.
1156  virtual void getXformOrder(UT_XformOrder &xord,
1157  const CH_Channel *chp) const;
1158 
1159  // "getCookedData" should return a void * version of the results of
1160  // the cook. NULL if it fails with appropriate stuff in our error manager.
1161  virtual OP_DataType getCookedDataType() const = 0;
1162  virtual void *getCookedData(const OP_Context &);
1163  virtual void deleteCookedData() = 0;
1164 
1165  virtual int saveCookedData(std::ostream &os, OP_Context &,
1166  int binary = 0) = 0;
1167  virtual bool loadCookedData(UT_IStream &is,
1168  const char *path = nullptr);
1169  virtual int saveCookedData(const char *filename, OP_Context &) = 0;
1170 
1171  /// Get the transform from this node's space to the 'to' node's space.
1172  /// Returns 1 if this was possible, 0 otherwise (e.g. failure to cook).
1173  virtual int getRelativeTransform(OP_Node &to, UT_Matrix4 &xform,
1174  OP_Context &context);
1175  virtual int getRelativeTransform(OP_Node &to, UT_DMatrix4 &xform,
1176  OP_Context &context);
1177  /// overrides for OPs that can capture (right now only OBJ_Bone)
1178  virtual int getRelativeCaptureTransform(OP_Node &to,
1179  UT_Matrix4 &xform,
1180  OP_Context &context);
1181  virtual int getRelativeCaptureTransform(OP_Node &to,
1182  UT_DMatrix4 &xform,
1183  OP_Context &context);
1184  /// Based on a path, get the UT_CameraParms data and transform of the
1185  /// camera relative to some other node.
1186  static bool getCameraInfoAndRelativeTransform(
1187  const UT_StringRef &campath,
1188  const UT_StringRef &xform_relative_to_path,
1189  const OP_Node *paths_relative_to_node,
1190  bool get_inverse_xform,
1191  const OP_Context &context,
1192  DEP_MicroNode *depnode,
1193  UT_CameraParms &camparms,
1194  UT_DMatrix4 &xform,
1196  virtual bool getCameraInfo(const UT_StringRef &camid,
1197  const OP_Context &context,
1198  DEP_MicroNode *depnode,
1199  UT_StringHolder &foundcamid,
1200  UT_CameraParms &camparms);
1201  virtual bool getWorldTransformFromData(const UT_StringRef &id,
1202  const OP_Context &context,
1203  bool get_inverse_xform,
1204  DEP_MicroNode *depnode,
1206 
1208  {
1209  TRANSFORM_WORLD,
1210  TRANSFORM_IWORLD,
1211  TRANSFORM_PRE,
1212  TRANSFORM_PARENT,
1213  TRANSFORM_PARM,
1214  TRANSFORM_PRECONSTRAINT,
1215  TRANSFORM_PARENTBONE,
1216  TRANSFORM_RAWPARM,
1217  TRANSFORM_PREPARM,
1218  TRANSFORM_PRERAWPARM,
1219  };
1220 
1221  // these next 3 are the minimal overrides for subclasses that have
1222  // transforms (see OBJ_Node)
1223  virtual bool getWorldTransform(UT_Matrix4D &xform, OP_Context &);
1224  virtual bool getIWorldTransform(UT_Matrix4D &xform, OP_Context &);
1225  virtual bool getTransform( TransformMode mode, UT_Matrix4D &xform, OP_Context &);
1227  // single precision versions of the above
1228  bool getWorldTransform(UT_Matrix4F &xform, OP_Context &ctx)
1229  {
1230  UT_Matrix4D m;
1231  bool ok = getWorldTransform(m, ctx);
1232  xform = m;
1233  return ok;
1234  }
1235  bool getIWorldTransform(UT_Matrix4F &xform, OP_Context &ctx)
1236  {
1237  UT_Matrix4D m;
1238  bool ok = getIWorldTransform(m, ctx);
1239  xform = m;
1240  return ok;
1241  }
1242  bool getTransform( TransformMode mode, UT_Matrix4F &xform, OP_Context &ctx)
1243  {
1244  UT_Matrix4D m;
1245  bool ok = getTransform(mode, m, ctx);
1246  xform = m;
1247  return ok;
1248  }
1249 
1250  /// Registers an error for cooking the given node's transform. If label is
1251  /// supplied, then it will be used as a label of the transform error.
1252  void addTransformError(const OP_Node &node,
1253  const char *label = nullptr) const;
1254 
1255  // Compute the bounding box for the operator (if applicable). If the box
1256  // could be computed, return true, else return false.
1257  virtual bool getBoundingBox(UT_BoundingBox &box, OP_Context &);
1258 
1259  // This is used by VOPNETs to determine which table needs to be
1260  // refreshed when they change.
1261  virtual const char *getInternalOpTable() const
1262  { return INVALID_TABLE_NAME; }
1263  virtual OP_Operator *getInternalOperator() const
1264  { return nullptr; }
1265 
1266  virtual const char *inputLabel(OP_InputIdx idx) const;
1267  virtual const char *outputLabel(OP_OutputIdx idx) const;
1268  UT_StringHolder spareOutputLabel(OP_OutputIdx idx) const;
1269 
1270  // Here's a useful method which will return the string "Source %d", where
1271  // %d is the idx passed. Lets us check if the input label is using the
1272  // default or not.
1273  const char *inputLabelNum(OP_InputIdx idx) const;
1274  const char *outputLabelNum(OP_OutputIdx idx) const;
1275 
1276  // returns a label that is applied to the drawn connector. NULL may be
1277  // returned as 'no label'.
1278  virtual const char *inputConnectorLabel(OP_InputIdx idx);
1279 
1280  // if true, the connector to the input will be dashed rather than solid.
1281  virtual int isRefInput(OP_InputIdx idx) const;
1282 
1283  // returns the index of the auxilary input, if any (currently only used
1284  // for the mask inputs in COPs).
1285  virtual int getAuxInput() const;
1286  virtual void getAuxInputName(OP_ConnectorId& name_out);
1287 
1288  // The lock method is used to lock the OP.
1289  // Returns the previous state of the lock flag.
1290  //
1291  // Note that to mimic the behaviour of the lock button, you MUST
1292  // call setModelLock, not setLockState()/setHardLock()/setSoftLock(), or
1293  // your next unlock won't have a cached data.
1295  OP_LockTypes setLockState(OP_LockTypes state, bool saveundo = true);
1296  OP_LockTypes getLockState() const { return flags().getLockState(); }
1298  // Returns true if either hard or soft locked
1299  bool getLock() const { return flags().isLocked(); }
1301  bool getSoftLock() const {return flags().getSoftLocked();}
1302  void setSoftLock(bool on_off)
1303  {
1304  setLockState(on_off ? OP_NodeFlags::OP_SOFT_LOCKED
1306  }
1308  bool getHardLock() const {return flags().getHardLocked();}
1309  void setHardLock(bool on_off)
1310  {
1311  setLockState(on_off ? OP_NodeFlags::OP_HARD_LOCKED
1313  }
1314 
1315  // The Model lock is similar to the normal lock but will also cause
1316  // the node data to be saved.
1317  virtual OP_LockTypes setModelLock(OP_LockTypes state,
1318  void *modeler = nullptr,
1319  bool allow_softlock_promotion = false,
1320  UT_Undo *undo = nullptr);
1321 
1322  // getNetworkLock() checks to see if the OP is effectively locked by
1323  // the network, i.e., each of the OPs output branches connect to a locked
1324  // OP down the network. Returns > 0 if locked, <= 0 if unlocked.
1325  // When relaxedlockcheck is set, subnet branches that are not displayed
1326  // are ignored.
1327  int getNetworkLock(
1328  bool relaxedlockcheck = false,
1329  const OP_Node *input_node = nullptr) const;
1330 
1331  // The unload flag triggers whether we keep the ops data around
1332  // after a cook or discard it as soon as its not needed. Its currently
1333  // only implemented in CHOPs.
1334  bool setUnload(bool on_off);
1335  bool getUnload() const;
1337  // Returns whether this node has data loaded into it.
1338  virtual bool isLoaded() const { return true; }
1339 
1340  // This will explicitly delete all data associated with the OP
1341  // false is returned if no data was deleted (ie, OP is in use, etc)
1342  // Only works with SOPs now.
1343  virtual bool unloadData();
1344 
1345  // Take control for flags
1346  void takeActivateFlag(uchar flag, bool enable=true,
1347  bool send_flag_event=true);
1348  void takeDeactivateFlag(uchar flag)
1349  { takeActivateFlag(flag, false); }
1350  bool takeIsActiveFlag(uchar flag) const;
1351  void setHasTakeData(bool onoff);
1352 
1353  bool canAccessFlag(unsigned mask, uchar flag) const;
1354 
1355  // The template flag indicates that the node date should be displayed
1356  // The display & render flags indicate that the node is turned on
1357  // for display purposes or for rendering purposes, which may take
1358  // on different meanings per node type.
1359  // Setting save data only has meaning for some node types.
1360  bool setPicked(bool on_off,
1361  bool propagate_parent_event = true) override;
1362 
1363  /// The edit flag is used whenever something is picked
1364  /// from the viewport. This causes the pane paths to
1365  /// be changed to the first writable parent of the
1366  /// node being picked.
1367  bool setEditPicked(bool on_off,
1368  bool propagate_parent_event = true);
1369 
1370  // The Autoscope flag on OP_Node is used to temporary turn-off the Auto-Add to Channel List
1371  // behavior when selecting nodes.
1372  // This is used when setting selected nodes from selected channels in the channel list
1373  void setAutoscope(bool on_off) { myAutoscope = on_off; }
1374  bool isAutoscope() { return myAutoscope; }
1375 
1376  bool setCurrent(bool on_off);
1377  bool setExpose(bool on_off);
1378  bool setBypass(bool on_off);
1379  bool setTemplate(bool on_off);
1380  bool setFootprint(bool on_off);
1381  bool setXray(bool on_off);
1382  bool setDisplay(bool on_off);
1383  bool setRender(bool on_off);
1384  bool setHighlight(bool on_off);
1385  bool setModified(bool on_off);
1386  bool setSaveBypass(bool on_off);
1387  bool setSaveData(bool on_off);
1388  // these are for subclasses to implement, they do nothing by default
1389  virtual bool setPickable(bool on_off)
1390  { return false; }
1391  virtual bool setAudio(bool on_off)
1392  { return false; }
1393  virtual bool setExport(bool on_off)
1394  { return false; }
1395  virtual bool setDebug(bool on_off)
1396  { return false; }
1397  virtual bool setDisplayOrigin(bool on_off_unchanged)
1398  { return false; }
1399 
1400  /// The user has set the template flag. If we are turning on the template
1401  /// flag, we do the same as setTemplate(). If we are turning it *off*,
1402  /// we also turn off the selectable template (footprint) flag.
1403  void userSetTemplate(bool onoff);
1404 
1405  /// The user has set the selectable template flag. If we are making a node
1406  /// into a selectable template, we turn on the template flag as well.
1407  /// If we are turning off selectable template, we leave template alone.
1408  void userSetSelectableTemplate(bool onoff);
1409 
1410  // Here are the generalised versions, they add a bit of overhead to
1411  // the code because of the big switch statement.
1412  virtual void setFlag(char tag, int8 val);
1413  virtual int8 getFlag(char tag) const;
1414 
1415  bool getPicked() const override
1416  { return flags().getPicked(); }
1417  virtual bool getEditPicked() const
1418  { return flags().getEditPicked(); }
1419  bool getCurrent() const;
1420  bool getDisplay() const {return flags().getDisplay(); }
1421  /// Checks the parent's export node ptr, controlled by display & export
1422  bool getDisplay3D();
1423  bool getRender() const {return flags().getRender(); }
1424  bool getHighlight() const {return flags().getHighlight();}
1425  bool getBypass() const {return flags().getBypass(); }
1426  bool getTemplate() const {return flags().getTemplate(); }
1427  bool getFootprint() const {return flags().getFootprint(); }
1428  bool getXray() const {return flags().getXray(); }
1429  bool getExpose() const {return flags().getExpose(); }
1430  bool getModified() const {return flags().getModified(); }
1431  bool getSaveBypass() const{return flags().getSaveBypass(); }
1432  bool getSaveData() const {return flags().getSaveData(); }
1433  bool getHasTakeData() const override
1434  { return flags().getHasTakeData(); }
1435  virtual bool getPickable()
1436  { return false; }
1437  virtual bool getAudio() const
1438  { return false; }
1439  virtual bool getExport() const
1440  { return false; }
1441  virtual bool getDebug() const
1442  { return false; }
1443  virtual bool getDisplayOrigin() const
1444  { return false; }
1445  bool getItemExpose() const override
1446  { return getExpose(); }
1447  void setItemExpose(bool expose) override
1448  { setExpose(expose); }
1449  virtual bool getUseBypassLook(const OP_EditorContext &ctx) const;
1450 
1451  bool getDisplayDescriptiveName() const
1452  {return flags().getDisplayDescriptiveName();}
1453  bool setDisplayDescriptiveName(bool state);
1454  bool getDisplayComment() const
1455  {return flags().getDisplayComment();}
1456  bool setDisplayComment(bool state);
1457  int8 getOutputForView() const
1458  { return flags().getOutputForView(); }
1459  int8 setOutputForView(int8 output);
1460 
1461  OP_Node *getPickableSelfOrParent();
1462 
1463  // The compress flag indicates that the OP connector should be displayed
1464  // in a compressed UI. In ICE this means don't display the mini raster
1465  // image.
1466  bool setCompress(bool on_off);
1467  bool getCompress() const;
1468 
1469  // This method sets this node as the current and picked node and correctly
1470  // adjusts the picked states of the other sibling nodes.
1471  void setCurrentAndPicked();
1472 
1473  // setVisible() simply calls setDisplay() at this level but subclasses
1474  // override this to perform smarter behaviour. Objects for example will
1475  // try to set the display flag on parent subnets and change visible object
1476  // parameters as necessary.
1477  // Returns true if it was successful, false if there were not sufficient
1478  // permissions.
1479  virtual bool setVisible(bool onoff);
1480  virtual bool getVisible() const;
1481 
1482  const OP_NodeFlags &flags() const
1483  { return myFlags; }
1484  OP_NodeFlags &flags()
1485  { return myFlags; }
1486 
1487  virtual void getSaveFlagsString(UT_String &cmd,
1488  const char *flags,
1489  bool save_to_hip) const;
1490  virtual void getPreParmSaveFlagsString( UT_String &cmd ) const;
1491  virtual void getPostParmSaveFlagsString( UT_String &cmd ) const;
1492 
1493  /// Returns true if given notifcation callback has been added via
1494  /// addOpInterest().
1495  int hasOpInterest(void *data, OP_EventMethod m) const
1496  { return myEventValue.hasOpInterest(data, m); }
1497 
1498  /// Add a notification callback for changes to the node. See the @c
1499  /// OP_EventType enum in OP_Value.h for the list of events and data sent.
1500  void addOpInterest(void *data, OP_EventMethod m)
1501  { myEventValue.addOpInterest(data, m); }
1503  /// Remove notification callback added via addOpInterest()
1504  void removeOpInterest(void *data, OP_EventMethod m)
1505  { myEventValue.removeOpInterest(data, m); }
1506 
1507  int isBeingDeleted() const
1508  { return myBeingDeleted; }
1509  void setNodeBeingDeleted(int beingdeleted);
1510 
1511  /// Sets the flag that prevents consolidation of variable inputs.
1512  /// Returns previous value of the flag;
1513  bool setInhibitInputConsolidation(bool value);
1514 
1515  /// Move the upper-left most node in 'ops' to x-coordinate 'x' and to have
1516  /// its TOP border at y-coordinate 'y', and move all other nodes in 'ops'
1517  /// by the same amount. All netboxes in 'netboxes' will also be moved that
1518  /// amount. If a netbox's top border is higher than any node's top border,
1519  /// everything will be moved down accordingly. Note that the repositioning
1520  /// calculation does not include the nodes contained in the network boxes
1521  /// in 'netboxes'.
1522  static void repositionOpsMaxY(OP_NetworkBoxItemList &items,
1523  fpreal x, fpreal y);
1524 
1525  /// Minimum inputs that must be connected to a node for it to cook.
1526  virtual unsigned minInputs() const;
1527 
1528  /// Maximum inputs that can be connected to a node.
1529  virtual unsigned maxInputs() const;
1530 
1531  /// Number of input connectors that should be visible on a node. This is
1532  /// only used by VOPs and DOPs. All other OPs return maxInputs() here.
1533  virtual unsigned getNumVisibleInputs() const;
1534 
1535  /// Returns the number of ordered inputs on a node that remain separate
1536  /// even on nodes that have a variable number of inputs. These separate
1537  /// inputs always start at the beginning (variable input connectors are
1538  /// always last).
1539  ///
1540  /// The default implementation returns getOperator()->numOrderedInputs() so
1541  /// prefer calling OP_Operator::setNumOrderedInputs() instead of overriding
1542  /// this.
1543  virtual unsigned orderedInputs() const;
1544 
1545  /// Maximum number of output connectors on a node. Only VOPs and DOPs ever
1546  /// return a value other than 1 here.
1547  virtual unsigned maxOutputs() const;
1548 
1549  /// Maximum number of spare output connectors on a node. Only COPs returns
1550  /// a value other than 0 here for the cable of all outputs.
1551  virtual exint maxSpareOutputs() const;
1552 
1553  /// Number of output connections that should be visible on a node tile.
1554  /// Only used by VOPs and DOPs.
1555  virtual unsigned getNumVisibleOutputs() const;
1556 
1557  /// Returns true if the operator type says we have unordered inputs.
1558  bool hasUnorderedInputs() const;
1559 
1560  /// Returns the index of the last connected input incremented by one.
1561  /// If there are no inputs connected, returns 0. This means that the
1562  /// function behaves as if the lasted connected input was always the
1563  /// last entry in the inputs array. Note that other array entries up
1564  /// to the index of the one returned may contain null entries, so this
1565  /// is not necessarily the same as the number of connections. Also note
1566  /// that there may be more null entries at indices beyond the returned
1567  /// one.
1568  virtual unsigned nInputs() const;
1569 
1570  /// The number of nodes actually connected to this node. This function
1571  /// goes through the myInputs array and counts non-null entries.
1572  /// @param check_subnet_inside If true, the (vopnet) subnet node will check
1573  /// if a corresponding connector is connected inside, and count it in
1574  /// if so.
1575  unsigned nConnectedInputs(bool check_subnet_inside=true) const;
1576 
1577  unsigned getActiveInputIndex() const
1578  { return myActiveInputIndex; }
1579  void setActiveInputIndex(unsigned idx);
1580 
1581  /// Returns the node connected to a particular input (may be null).
1582  OP_Node *getInput(OP_InputIdx idx, bool mark_used=false) const;
1583 
1584  /// Returns the connected input, may be null. If it is a SOP & subnet,
1585  /// and not primary output, will chase to the child output node.
1586  /// This may induce flag dependencies, the provided micronode
1587  /// can accumulate them.
1588  OP_Node *getInputFollowingOutputs(OP_InputIdx input,
1589  DEP_MicroNode *depnode=nullptr) const;
1590 
1591  /// Returns the first non-null input beyond the specified starting index.
1592  /// This function can be used to easily loop through all connected inputs.
1593  OP_InputIdx getConnectedInputIndex(OP_InputIdx start_at = -1) const;
1594 
1595  /// Gets the index of the Nth non-null connection to this node.
1596  OP_InputIdx getNthConnectedInput(OP_InputIdx n) const;
1597 
1598  /// Override this to specify the inputs which are needed for cooking this
1599  /// node which can be executed in parallel.
1600  virtual void getParallelInputs(OP_Context &context,
1601  OP_NodeList &nodes) const;
1602 
1603  /// Forcibly clear an input. Used when deleting the input.
1604  void forceClearInput(OP_InputIdx idx);
1605 
1606  /// Sets a given input to connect to an output of a particular node.
1607  virtual OP_ERROR setInput(OP_InputIdx idx, OP_Node *op,
1608  OP_OutputIdx output_idx = 0);
1609 
1610  /// Connects an input to an indirect input of our parent subnet.
1611  virtual OP_ERROR setIndirectInput(OP_InputIdx idx,
1612  OP_IndirectInput *input);
1613 
1614  /// Connects an input to particular node by name in the network.
1615  virtual OP_ERROR setInputReference(
1616  OP_InputIdx idx,
1617  const char *label,
1618  int keeppos,
1619  OP_OutputIdx output_idx = 0);
1620 
1621  /// Returns the index of the first connection from node "who" to this node,
1622  /// or -1 if "who" is not an input.
1623  OP_InputIdx whichInputIs(const OP_Node *who) const;
1624 
1625  /// Returns the index of the first connection of an indirect input.
1626  OP_InputIdx whichInputIs(const OP_IndirectInput *who) const;
1627 
1628  /// Returns the index of the Nth connection of an indirect input.
1629  OP_InputIdx whichInputIs(const OP_IndirectInput *whoi,
1630  int cnt) const;
1631 
1632  /// Returns an index of the output which goes out from this node to
1633  /// the target_node, and connects to the target_node at the specified
1634  /// input index. Returns -1 if the connection doesn't exist.
1635  /// Use `whichOutputIsFollowingIndirect` for a more robust solution.
1636  OP_OutputIdx whichOutputIs(const OP_Node* target_node,
1637  OP_InputIdx input_on_target_node) const
1638  {
1639  OP_OutputIdx output_idx = whichOutputIsIncludeSpare(
1640  target_node, input_on_target_node).value_or(-1);
1641  if (output_idx < 0)
1642  return -1;
1643  return output_idx;
1644  }
1645  /// Returns an index of the output which goes out from this node to
1646  /// the target_node, and connects to the target_node at the specified
1647  /// input index. This version handles spare outputs and uses negative
1648  /// indices to refer to spare outputs. Returns `UT_NULLOPT` if the
1649  /// connection doesn't exist.
1650  /// Use `whichOutputIsFollowingIndirectIncludeSpare` for a more robust
1651  /// solution.
1652  UT_Optional<OP_OutputIdx> whichOutputIsIncludeSpare(
1653  const OP_Node* target_node,
1654  OP_InputIdx input_on_target_node) const;
1655 
1656  /// Computes the output, but handles the case that target_node's input
1657  /// is an indirect input. This will then follow the indirect chain
1658  /// up until a node's real input. Returns -1 on failure.
1659  OP_OutputIdx whichOutputIsFollowingIndirect(
1660  const OP_Node* target_node,
1661  OP_InputIdx input_on_target_node) const
1662  {
1663  return whichOutputIsFollowingIndirectIncludeSpare(
1664  target_node, input_on_target_node).value_or(-1);
1665  }
1666  /// Computes the output, but handles the case that target_node's input
1667  /// is an indirect input. This will then follow the indirect chain
1668  /// up until a node's real input. This version handles spare outputs and
1669  /// uses negative indices to refer to spare outputs. Returns `UT_NULLOPT`
1670  /// on failure.
1671  UT_Optional<OP_OutputIdx> whichOutputIsFollowingIndirectIncludeSpare(
1672  const OP_Node* target_node,
1673  OP_InputIdx input_on_target_node) const;
1674 
1675  /// Returns the index of an input into which source_node is connected
1676  /// on this node. counter determines the Nth such connection from
1677  /// source node to this particular node.
1678  OP_InputIdx whichInputIs(const OP_Node* source_node,
1679  int counter) const;
1680 
1681  // Compacts the inputs array, removing all null entries.
1682  void consolidateInputs();
1683  virtual void clearUnreferencedInputs();
1684  virtual bool allowConsolidatingInput(OP_InputIdx idx);
1685 
1686  // Returns a pointer to an input given an input index. If the input index
1687  // is less than nInputs() it will always return a valid input. If the grow
1688  // flag is set to true, then any inputs between nInputs and the index
1689  // given will be created, up to maxInputs().
1690  virtual OP_Input *getInputReference(OP_InputIdx idx, bool grow);
1691 
1692  // As before, except missing inputs are not created. NULL is returned for
1693  // non-existent inputs.
1694  virtual OP_Input *getInputReferenceConst(OP_InputIdx idx) const;
1695 
1696  virtual int doDeleteRewire() const { return 1; }
1697  // This moves the input at srcidx to dstidx. forcesubnet will enable
1698  // modification of subnet inputs and outputs even when inside a
1699  // blockModify().
1700  virtual void moveInput(OP_InputIdx srcidx, OP_InputIdx dstidx,
1701  bool forcesubnet = false);
1702  OP_ERROR insertInput(OP_InputIdx idx, OP_Node *op,
1703  OP_OutputIdx output_idx);
1704  OP_ERROR insertIndirectInput(OP_InputIdx idx,
1705  OP_IndirectInput *input);
1706 
1707  // For nodes with editable input names, this function is used to set the
1708  // default name for a new input.
1709  virtual UT_Options getInputDataDefault(OP_InputIdx idx) const
1710  { return UT_Options(); }
1711 
1712  /// The following methods are used for nodes that allow reordering inputs.
1713  /// Returns the number of inputs that editor should display.
1714  virtual int getInputEditorInputs();
1715  /// Returns true if editor should display parameter option menu button.
1716  virtual bool allowInputEditorInputParm();
1717  /// Returns true if editor should display delete input button.
1718  virtual bool allowInputEditorInputDelete();
1719  /// Gets the input label to display in editor and returns true. Otherwise,
1720  /// returns false if editor should use backward-compatible labeling scheme.
1721  virtual bool getInputEditorInputLabel(UT_StringHolder &label,
1722  OP_InputIdx idx);
1724  virtual const OP_DataMicroNode &
1725  dataMicroNodeConst() const
1726  { return myDataMicroNode; }
1727  OP_DataMicroNode & dataMicroNode()
1728  {
1729  return const_cast<OP_DataMicroNode &>(
1730  dataMicroNodeConst());
1731  }
1732 
1733  /// Subclasses should override this to customize the micro-node dependency
1734  /// of their parameter list. The default is just dataMicroNode().
1735  virtual const OP_DataMicroNode &
1736  parmListMicroNodeConst() const
1737  { return dataMicroNodeConst(); }
1738  OP_DataMicroNode & parmListMicroNode()
1739  {
1740  return const_cast<OP_DataMicroNode &>(
1741  parmListMicroNodeConst());
1742  }
1743 
1744  bool hasIndepParmListMicroNode() const
1745  {
1746  return (&parmListMicroNodeConst()
1747  != &dataMicroNodeConst());
1748  }
1750  /// This micronode is guaranteed to trigger when any flag changes.
1751  DEP_MicroNode & flagMicroNode()
1752  { return myFlagMicroNode; }
1753  /// This micronode is guaranteed to trigger when the specified flag changes;
1754  /// it may also trigger on unrelated flag changes.
1755  DEP_MicroNode & flagMicroNode(char flag)
1756  { return myIndividualFlagMicroNodes[flag]; }
1757  DEP_MicroNode & parmMicroNode(int parm_idx, int vi)
1758  { return getParmList()->parmMicroNode(
1759  parm_idx, vi); }
1761  /// Accessors to event micro nodes.
1762  const DEP_MicroNode &eventMicroNodeConst(OP_EventType e) const
1763  {
1764  return SYSconst_cast(this)->eventMicroNode(e);
1765  }
1766  DEP_MicroNode & eventMicroNode(OP_EventType e);
1767 
1768  bool hasEventMicroNode(OP_EventType e) const
1769  {
1770  UT_ASSERT_P(e >= 0 && e < OP_EVENT_TYPE_COUNT);
1771  if (!myEventMicroNodes)
1772  return false;
1773  return bool(myEventMicroNodes[e]);
1774  }
1775 
1776  /// Subclasses should override this provide any additional micronodes that
1777  /// they own. This list is used in places such as node deletion so that
1778  /// dependents are dirtied.
1779  virtual void getOwnedMicroNodes(
1780  DEP_MicroNodeList &micronodes);
1781 
1782  /// Explicitly propagate dirtiness for a particular micronode owned by
1783  /// some node.
1784  void propagateDirtyMicroNode(
1785  DEP_MicroNode &micronode,
1786  OP_EventType reason,
1787  void *data,
1788  bool send_root_event);
1789 
1790  /// Declares that this node's data depends on the @c op for the given
1791  /// reason (OP_INTEREST_DATA, OP_INTEREST_FLAG).
1792  /// @note There are no other acceptable values for type.
1793  virtual void addExtraInput(OP_Node *op, OP_InterestType type);
1794 
1795  /// Declares that this node's data depends on @c op channel. If vec_i is
1796  /// -1, then this node depends on all the channels of the parameter.
1797  void addExtraInput(OP_Node &op, int parm_i, int vec_i);
1798 
1799  /// Generic version of addExtraInput() which adds a dependency from an
1800  /// source ref to this node's data micronode.
1801  void addExtraInput(const OP_InterestRef &source_ref);
1802 
1803  /// Generic version of addExtraInput() which adds a dependency from an
1804  /// source micronode to this node's data micronode.
1805  void addExtraInput(DEP_MicroNode &source_micronode);
1806 
1807  /// Marks this to be dependent on all the parameters inside of the
1808  /// multiparm.
1809  void addMultiparmInterests(OP_Node *srcnode, PRM_Parm &parm);
1810 
1811 
1812  static DEP_MicroNode *getEvalChannelMicroNode(int thread);
1813 
1814  /// Declare from an expression callback that the current evaluation channel
1815  /// is dependent on the given source.
1816  // @{
1817  static void addExtraInputToEvalChannel(
1818  int thread,
1820  {
1821  addExtraInputToEvalChannel(
1822  thread,
1823  OP_InterestRef(op, type));
1824  }
1825  static void addExtraInputToEvalChannel(
1826  int thread,
1827  OP_Node &op, int parm_i, int vec_i)
1828  {
1829  addExtraInputToEvalChannel(
1830  thread,
1831  OP_InterestRef(op,parm_i,vec_i));
1832  }
1833  static void addExtraInputToEvalChannel(
1834  int thread,
1835  const OP_InterestRef &source_ref)
1836  {
1837  DEP_MicroNode *
1838  target = getEvalChannelMicroNode(thread);
1839  if (target)
1840  OP_Node::addExtraInput(*target, source_ref);
1841  }
1842  static void addExtraInputToEvalChannel(
1843  int thread,
1844  DEP_MicroNode &src_micronode)
1845  {
1846  DEP_MicroNode *
1847  target = getEvalChannelMicroNode(thread);
1848  if (target)
1849  target->addExplicitInput(src_micronode);
1850  }
1851  // @}
1852 
1853  /// Generic versions of addExtraInput() used by the others. In particular,
1854  /// the static version of addExtraInput() allows you to define channel to
1855  /// channel dependencies.
1856  // @{
1857  static void addExtraInput(
1858  const OP_InterestRef &target_ref,
1859  const OP_InterestRef &source_ref);
1860  static void addExtraInput(
1861  const OP_InterestRef &target_ref,
1862  DEP_MicroNode &source_micronode);
1863  static void addExtraInput(
1864  DEP_MicroNode &target_micronode,
1865  const OP_InterestRef &source_ref);
1866  // @}
1867 
1868  static void addMultiparmInterests(const OP_InterestRef &target_ref,
1869  OP_Node *srcnode,
1870  PRM_Parm &parm);
1871  static void addMultiparmInterests(DEP_MicroNode &target,
1872  OP_Node *srcnode,
1873  PRM_Parm &parm);
1874 
1875  void getExtraInputNodes(
1876  OP_NodeList &extras,
1877  bool remove_duplicates = true,
1878  bool data_interest = true,
1879  bool parm_interest = true,
1880  bool flag_interest = true,
1881  bool include_parmlist = true,
1882  bool follow_simulation_inputs = false) const;
1883  void getExtraOutputNodes(
1884  OP_NodeList &extras,
1885  bool remove_duplicates = true,
1886  bool data_interest = true,
1887  bool parm_interest = true,
1888  bool flag_interest = true) const;
1889 
1890  int getNumExtraInputs() const;
1891 
1892  void dumpExtraInputs(
1893  std::ostream &os,
1894  bool as_DOT,
1895  int indent_level = 0) const;
1896 
1897  /// Appends to the provided context the expected parameters
1898  /// from the containing network.
1899  /// Adds dependencies to those parameters to the provided depnode.
1900  virtual bool buildDefaultCopContext(OP_Context &context,
1901  DEP_MicroNode *depnode=nullptr);
1902 
1903  // addExprOpDependency is a helper function for building dependencies for
1904  // the expression library callback functions.
1905  static void addExprOpDependency(const char *arg_str,
1906  const PRM_RefId &ref_id,
1907  OP_InterestType interest_type);
1908  static void addExprOpDependency1From2(const char *arg_str1,
1909  const char *arg_str2,
1910  const PRM_RefId &ref_id,
1911  OP_InterestType interest_type);
1912  static void addExprOpParmDependency(const char *arg_str,
1913  const PRM_RefId &ref_id,
1914  OP_InterestType interest_type);
1915  // NB: is reponsible for freeing new_arg!
1916  static void changeExprOpRef(const char *arg_str,
1917  char *&new_arg,
1918  const char *new_fullpath,
1919  const char *old_fullpath,
1920  const char *old_cwd);
1921  // NB: is reponsible for freeing new_arg!
1922  static void changeExprOpRef1From2(const char *arg_str1,
1923  const char *arg_str2,
1924  char *&new_arg1,
1925  char *&new_arg2,
1926  const char *new_fullpath,
1927  const char *old_fullpath,
1928  const char *old_cwd);
1929  // NB: is reponsible for freeing new_arg!
1930  static void changeExprOpParmRef(const char *arg_str,
1931  char *&new_arg,
1932  const char *new_fullpath,
1933  const char *old_fullpath,
1934  const char *old_cwd,
1935  const char *chan_name,
1936  const char *old_chan_name);
1937 
1938  void addGenericOpNameReference( const UT_String &oppath );
1939  void addGenericOpNameReference( const PRM_RefId &ref_id,
1940  OP_Node *node );
1941  void addGenericOpInputReference( const PRM_RefId &ref_id,
1942  OP_Node *node );
1943 
1944  static void moveAndUpdateDependencies(
1945  const OP_NodeList &src_nodes,
1946  const OP_NodeList &dest_nodes );
1947 
1948  static void updateChannelPtrs( CH_CollectionList &parents );
1949 
1950  bool getParmBaseNodePath(
1951  UT_String &path,
1952  int parm_index,
1953  int thread) const;
1954 
1955  // Make this function public so it can be called by OPUI_EditSubnet
1956  // and possibly others. Note that it is defined in PRM_ParmOwner so
1957  // that it can be called from the PRM library.
1958  void rebuildParmDependency(int parm_index) override;
1959 
1960  // Clear op name dependencies
1961  void clearParmDependency(int parm_index) override;
1962  // decrementOpReference() should only be called by clearParmDependency()
1963  void decrementOpReference(int node_id);
1964 
1965  virtual void dumpDependencies(std::ostream &os);
1966  void dumpOpDependents(OP_Node *ref, int brief,
1967  std::ostream &os);
1968  const OP_DependencyList
1969  &getOpDependents() const { return myOpDependents; }
1970 
1971 
1972  // INTERNAL: Do NOT use outside of OP_Node! Will be made private.
1973  int countReferences(int op_id);
1974 
1975  // Get the existing node *NAME* references (eg. expr references)
1976  // NB: This function assumes that refs is sorted without duplicate entries!
1977  void getExistingOpReferences(OP_NodeList &refs,
1978  bool recurse) const;
1979 
1980  // Get the as complete list of data references as possible for this node.
1981  // This combines getExistingOpReferences() which exist without cooking, and
1982  // getExtraInputNodes() which are the current references since the last
1983  // cook of its refernces.
1984  void getFullOpReferences(OP_NodeList &refs,
1985  bool include_descendants) const;
1986 
1987  // Get the existing node *NAME* dependents (eg. expr references)
1988  // NB: This function assumes that deps is sorted without duplicate entries!
1989  void getExistingOpDependents(OP_NodeList &deps,
1990  bool include_descendants) const;
1991 
1992  // Get the as complete list of data dependents as possible for this node.
1993  // This combines getExistingOpDependents() which exist without cooking, and
1994  // getExtraOutputNodes() which are the current dependents since the last
1995  // cook.
1996  void getFullOpDependents(OP_NodeList &deps,
1997  bool include_descendants) const;
1998 
1999  // Gets a list of parms that reference one of our channels/parms.
2000  void getParmsThatReference(const char *channame,
2002  UT_IntArray &parmsubidxs);
2003 
2004  virtual void inputConnectChanged(OP_InputIdx which);
2005 
2006  // Returns the number of output entries in the output array. Note
2007  // that this done regardless of which entries have any outputs connected.
2008  unsigned nOutputEntries() const;
2009  // Get access to the raw network items connected to our outputs.
2010  // These functions can focus on a single output connector, or treat
2011  // all outputs as a flat array by passing output_idx = -1.
2012  int nOutputItems(OP_OutputIdx output_idx = -1) const
2013  {
2014  static constexpr bool include_spare = false;
2015  if (output_idx < 0)
2016  return static_cast<int>(
2017  nOutputItemsIncludeSpare(
2018  UT_NULLOPT, include_spare));
2019  else
2020  return static_cast<int>(
2021  nOutputItemsIncludeSpare(
2022  output_idx, include_spare));
2023  }
2024  OP_NetworkBoxItem *getOutputItem(int idx,
2025  OP_OutputIdx output_idx = -1) const
2026  {
2027  static constexpr bool include_spare = false;
2028  if (output_idx < 0)
2029  return getOutputItemIncludeSpare(
2030  idx, UT_NULLOPT, include_spare);
2031  else
2032  return getOutputItemIncludeSpare(
2033  idx, output_idx, include_spare);
2034  }
2035  /// Get access to the raw network items connected to our outputs.
2036  /// These functions can focus on a single output connector, or treat
2037  /// all outputs as a flat array by passing output_idx = UT_NULLOPT.
2038  /// These updated versions handle spare outputs, which use negative indices.
2039  /// @{
2040  exint nOutputItemsIncludeSpare(
2041  UT_Optional<OP_OutputIdx> output_idx =
2042  UT_NULLOPT,
2043  bool include_spare = true) const;
2044  OP_NetworkBoxItem *getOutputItemIncludeSpare(
2045  int idx,
2046  UT_Optional<OP_OutputIdx> output_idx =
2047  UT_NULLOPT,
2048  bool include_spare = true) const;
2049  /// @}
2050  // Quick check if this node has any node outputs.
2051  bool hasAnyOutputNodes(
2052  bool through_dots = true,
2053  OP_OutputIdx output_idx = -1
2054  ) const;
2055  /// Fills a node list with all outputs from this node. This function can
2056  /// search through dots, and dive into subnets. It can also run on a
2057  /// single output connector or all of them.
2058  /// @{
2059  void getOutputNodes(
2060  UT_Array<OP_Node*> &outputs,
2061  bool into_subnets = false,
2062  bool through_dots = true,
2063  OP_OutputIdx output_idx = -1) const
2064  {
2065  constexpr bool include_spare = false;
2066  if (output_idx < 0)
2067  return getOutputNodesIncludeSpare(
2068  outputs, into_subnets, through_dots,
2069  UT_NULLOPT, include_spare);
2070  else
2071  return getOutputNodesIncludeSpare(
2072  outputs, into_subnets, through_dots,
2073  output_idx, include_spare);
2074  }
2075  /// This version handles spare outputs and uses negative indices to refer
2076  /// to spare outputs.
2077  void getOutputNodesIncludeSpare(
2078  UT_Array<OP_Node*> &outputs,
2079  bool into_subnets = false,
2080  bool through_dots = true,
2082  output_idx = UT_NULLOPT,
2083  bool include_spare = true) const;
2084  /// @}
2085  // Quick function to return the first output node, searching depth first
2086  // through dots if requested.
2087  OP_Node *getFirstOutputNode(
2088  bool through_dots = true,
2089  OP_OutputIdx output_idx = -1
2090  ) const;
2091 
2092  // obtains an output node that leads to a target node (e.g., during network
2093  // traversal). Null if target is not a descendant.
2094  OP_Node *getOutputTowardsNode(const OP_Node *target);
2095 
2096  /// Fill in 'tree' with details that are common to all node types. Then call
2097  /// fillInfoTreeNodeSpecific() to get specific details about this specific
2098  /// node (be it a SOP, CHOP, etc)
2099  void fillInfoTree(UT_InfoTree &tree,
2100  const OP_NodeInfoTreeParms &parms);
2101 
2102  /// Triggered by 'fillInfoTree()', this virtual function adds all node-
2103  /// specific info to 'tree'. All child classes must create their own
2104  /// branches under 'tree' to place their info
2105  virtual void fillInfoTreeNodeSpecific(UT_InfoTree &tree,
2106  const OP_NodeInfoTreeParms &parms);
2107 
2108  /// Optionally called on parent from fillInfoTreeNodeSpecific() to provide
2109  /// some information about node that only parent network can provide.
2110  /// @return True if parent added info specific to that child.
2111  virtual bool fillInfoTreeChildSpecific(UT_InfoTree &tree,
2112  const OP_NodeInfoTreeParms &parms,
2113  OP_Node *child);
2114 
2115  // These methods get input data for the OP. If they return an error code
2116  // >= UT_ERROR abort, then the errno should be set, and there may be a
2117  // further local error message. There is no error checking to ensure that
2118  // each locked source is only released once, so it's up to the user. The
2119  // standard method is to call lockInputs(), then call unlockInputs() on
2120  // exit. However, in some cases (i.e. switch SOP) only some sources need
2121  // to be cooked.
2122  //
2123  // lockInput() will return an error code >= UT_ERROR iff idx <
2124  // minInputs(). Otherwise, it's considered to be an optional input, so no
2125  // data will be returned. A simple rule of thumb: If lockInput() returns
2126  // ok, the source has to be unlocked, otherwise it shouldn't be unlocked!
2127  // If lockInputs() detects an error, it will automatically unlock the
2128  // inputs so that unlockInputs() should NOT be called!
2129  virtual OP_ERROR lockInput(OP_InputIdx idx, OP_Context &context);
2130  virtual void unlockInput(OP_InputIdx idx);
2131  virtual OP_ERROR lockInputs(OP_Context &context);
2132  virtual void unlockInputs();
2133 
2134  // This "serial" number refers to the number of times that the geometry
2135  // had been changed. Note, only the "modeller" should bump the cook count,
2136  // the OP cook method does this also, but has privilaged access.
2137  exint getCookCount() const { return myCookCount; }
2138  /// The cache misses are when our state was "clean" but it turned
2139  /// out we didn't have any data cached. (Note: This doesn't include
2140  /// ping-ponging on context options.)
2141  exint cacheMisses() const { return myCacheMisses; }
2142  void triggerOutputChanged();
2143 
2144  void triggerUIChanged(
2147  // Returns the index of cooked input to a SOP switch
2148  virtual OP_InputIdx cookedInputIndex() const { return -1; }
2149 
2150  /// For nodes which simply pass-through their data from some other node,
2151  /// this returns the node whose data will used transparently as this node's
2152  /// output. This function can give different values depending on its
2153  /// parameters. Used by node traversal algorithms.
2154  ///
2155  /// The default implementation returns the first input if it's bypassed, so
2156  /// subclasses should only do something different if this function returns
2157  /// NULL.
2158  ///
2159  /// @param t Eval time
2160  /// @param mark_used Mark this node is using the returned node (if
2161  /// non-NULL).
2162  ///
2163  virtual OP_Node *getPassThroughNode(
2164  fpreal t,
2165  bool mark_used = false);
2166 
2167  bool setMinimumCacheSize(int min_size);
2168 
2169  OP_VERSION getVersionParms() const
2170  { return dataMicroNodeConst().modVersion(); }
2171 
2172  // This will be called if the timeInterest flag is set.
2173  // This will return true if the node needs to be dirtied for cooking
2174  virtual bool handleTimeChange(fpreal /* t */) { return false; }
2175 
2176  /// Returns true if the OP depends on time at the given time. This
2177  /// is sensitive to handleTimeChange's overrides.
2178  bool isTimeDependent(const OP_Context &context);
2179 
2180  // Returns true if this node is an HDA with a dive target, or a C++ node
2181  // with a subnework, but is not an OBJ, subnet, or manager.
2182  virtual bool isDiveable() const;
2183 
2184  static int getGlobbedNodes(OP_Node *cwd, UT_String &holder,
2185  const char *pattern, UT_WorkArgs &argv,
2186  OP_GlobContext *context);
2187 
2188  static int getGlobbedNetworkBoxes(OP_Node *cwd, UT_String &holder,
2189  const char *pattern, UT_WorkArgs &argv,
2190  OP_GlobContext *context);
2191 
2192  static int getGlobbedPostIts(OP_Node *cwd, UT_String &holder,
2193  const char *pattern, UT_WorkArgs &argv,
2194  OP_GlobContext *context);
2195 
2196 
2197  /// Obtains additional nodes that should be copied or deleted when this
2198  /// node is copied or deleted. It applies to situations, such as, where
2199  /// an hidden input node feeds only to this node and serves only that
2200  /// purpose, so it should be coppied/deleted along with the master.
2201  virtual void getExtraNodesForCopyOrDelete(OP_NodeList &extras)const;
2202 
2203  // Runs the creation script (if there is one). The return value is false
2204  // if the node was deleted while running the script. In this case
2205  // obviously the node pointer becomes invalid and should not be used
2206  // any more. It returns true if the node still exists.
2207  virtual bool runCreateScript();
2208  // Go through all our parms to match the values to the current hip file
2209  // units settings.
2210  void updateParmsToMatchCurrentUnits();
2211 
2212  /// True if the otl is marked as matching, but hasn't actually been
2213  /// synced yet.
2214  bool getDelaySyncOTL() const
2215  { return myDelaySyncOTL; }
2216 
2217  /// Shallowly sets the delayed sync flag,
2218  void setDelaySyncOTL(bool isdelayed);
2219 
2220  /// Determines if this node should do delayed syncing or not.
2221  bool shouldDelaySyncOTL() const;
2223  /// Verifies this node has been synchronized in case it was delayed.
2224  void syncDelayedOTL()
2225  {
2226  if (!getDelaySyncOTL()) return;
2227  internalSyncDelayedOTL();
2228  }
2229 
2230  /// Matches the node to the current HDA definition, loading the contents
2231  /// section if ncecessary and setting the match flag.
2232  virtual void matchOTLDefinition();
2233 
2234  /// Unmatches (unlocks) the node from the current HDA definition.
2235  virtual void unmatchOTLDefinition();
2236 
2237  /// Method that is invoked when the HDA index file has been cleared
2238  /// because the underlying HDA definition has changed.
2239  virtual void handleOTLIndexFileCleared();
2240 
2241  /// Returns the error string where we keep all errors generated during
2242  /// our most recent synchronization attempt.
2243  const UT_String &getSyncErrors() const
2244  { return mySyncErrors; }
2245  /// Returns the error level generated in our last synchronization attempt.
2246  OP_ERROR getSyncErrorLevel() const
2247  { return mySyncErrorLevel; }
2248 
2249  /// Return true if any ancestor of this node is currently running the
2250  /// syncContents function (and so has mySyncDepth > 0). This is used to
2251  /// detect changes to nodes that are not currently "locked", but will
2252  /// become locked once the sync is complete.
2253  bool isAnyAncestorBeingSynced() const;
2254 
2255  /// Interface to flag that specifies whether or not we match our definition.
2256  int getMatchesOTLDefinition() const;
2257 
2258  /// Utility function for syncing/unsyncing all uncestor nodes.
2259  static void propagateMatchOTLDefinitionToAncestors(OP_Node *node,
2260  bool sync_flag);
2261 
2262  // Some extra functions for dealing with access rights as they relate
2263  // to matching the OTL definition.
2264  int getCanDeviateFromOTLDefinition() const;
2265  void setAllChildAssetPermissions(int permission);
2266  // Recompute the asset permissions because something changed like the node
2267  // was locked or unlocked.
2268  void computeAllChildAssetPermissions();
2269  // Returns true if this node is contained inside a locked HDA, but
2270  // is marked as an editable node within that HDA.
2271  bool getIsEditableAssetSubNode() const;
2272 
2273  // Turn off our export flag and the export flags of our children.
2274  void turnOffAllChildExports();
2275 
2276  // Collection of methods for working with licensed assets.
2277  bool haveLicenseToAccessContents(
2278  OP_Node* opt_specific_child = nullptr) const;
2279  bool haveLicenseToAccessParentContents() const;
2280  bool haveAncestorWithoutFullLicense(bool ignore_self) const;
2281  OP_OTLLicenseType getLicense() const;
2282  // Get the first (oldest) ancestor without a license to access contents.
2283  OP_Node *getFirstExecLicenseOnlyAncestor(
2284  bool ignore_self = true) const;
2285  // Get the last (youngest) ancestor without a license to access contents.
2286  OP_Node *getLastExecLicenseOnlyAncestor(
2287  bool ignore_self = true) const;
2288 
2289  bool isCompiled() const;
2290 
2291  // Save as a series of ASCII commands.
2292  void saveWires(std::ostream &os, const char *name,
2293  int dogeneral = 0);
2294  void saveOutputWires(std::ostream &os, const char *name,
2295  int dogeneral = 0);
2296  virtual void saveIntrinsicCommand(std::ostream &os,
2297  const char *name);
2298 
2299  /// Writes to 'os' a string of hscript commands to recreate this node.
2300  virtual OP_ERROR saveCommand(std::ostream &os,
2301  const char *name,
2302  fpreal x,
2303  fpreal y,
2304  const char *netboxname,
2305  const OP_SaveCommandOptions &options);
2306 
2307  // This method saves a chlock style command for this node's parameters.
2308  // name - the name of the node to print on the command;
2309  // command - the name of the command;
2310  // flag_method - a PRM_Parm method that can be queried for the flag to
2311  // output;
2312  // defaultstoo - prints a default "-*" or "+*" as the first parameter
2313  // reverse - normally the default is "-*" followed by the list of
2314  // parameters that result true for flag_method(). If
2315  // reverse is true, then the default is "+*" followed by
2316  // the parameters where flag_method() is false. Only useful
2317  // when defaultstoo is true.
2318  // parm_array - an optional array of parameters whose values should be
2319  // printed. If this array is NULL, then the entire node
2320  // is searched.
2321  void saveParameterFlags(std::ostream &os, const char *name,
2322  const char *command,
2323  bool (PRM_Parm::*flag_method)(int) const,
2324  bool defaultstoo, bool reverse,
2325  UT_Array<opParmData> *parm_array);
2326 
2327  void saveUserDataCommand(
2328  std::ostream &os, const char *node_name,
2329  bool omit_version = false);
2330 
2332  {
2333  RAMP_ERR_SUCCESS,
2334  RAMP_ERR_NOT_FOUND,
2335  RAMP_ERR_ONLY_KEY
2336  };
2337  virtual RampError rampCommand(bool remove, fpreal pos, float rgba[4]);
2338  RampError rampCommand(bool remove, fpreal pos, float rgba[4],
2339  UT_Ramp &ramp);
2340 
2341  virtual bool loadRamp(UT_IStream &is, const char *path=nullptr);
2342 
2343  bool loadRamp(UT_IStream &is, UT_Ramp &ramp,
2344  const char *path=nullptr);
2345  OP_ERROR saveRamp(std::ostream &os, UT_Ramp &ramp,
2346  const char *name = nullptr, int command = 0);
2347 
2348  bool getUserData(const UT_StringRef &key,
2349  UT_StringHolder &result) const;
2350  void setUserData(const UT_StringRef &key,
2351  const UT_StringHolder &data,
2352  bool save_undo);
2353  bool hasUserData(const UT_StringRef &key) const;
2354  bool deleteUserData(const UT_StringRef &key,
2355  bool save_undo);
2356  const UT_Options &userData() const
2357  { return myUserData; }
2358  bool loadUserData(UT_IStream &is, const char *path=nullptr);
2359  OP_ERROR saveUserData(std::ostream &os, const char *path);
2360  void clearUserData(bool save_undo);
2361  virtual void userDataChanged(const UT_StringHolder &key);
2363  /// Prefix to use for internally used user data.
2364  static const char *internalUserDataPrefix() { return "sidefx::"; }
2365 
2366  /// Returns a shared pointer to a previously stored blind data. If no
2367  /// blind data exists with the given key, an empty shared pointer is
2368  /// returned.
2369  UT_SharedPtr<void> getBlindData(const char *key) const;
2370 
2371  /// Return a pointer to a previously stored blind data, statically cast
2372  /// to the type given. If the cast fails, or if there's no data of that
2373  /// type, a NULL pointer is returned. To distinguish between the two cases
2374  /// call hasBlindData().
2375  template<typename T>
2376  UT_SharedPtr<T> getBlindData(const char *key) const
2377  { return UTstatic_pointer_cast<T>(getBlindData(key)); }
2378 
2379  /// Stores a blind data pointer on this OP_Node object. Any entry that
2380  /// previously existed will be erased, and, if it is the last reference,
2381  /// the object itself deleted. The \c void type can convert from any other
2382  /// shared pointer type, while storing the deleter function, allowing
2383  /// OP_Node to delete the data without knowing anything about the class.
2384  /// Blind data is *not* stored with the class.
2385  void setBlindData(const char *key, UT_SharedPtr<void> ptr);
2386 
2387  /// Returns true if this object stores a blind data with the given key.
2388  bool hasBlindData(const char *key) const;
2389 
2390  /// Remove any reference to the blind data of the given key from this
2391  /// object.
2392  bool deleteBlindData(const char *key);
2393 
2394  void getDataBlockKeys(UT_StringArray &keys,
2395  const UT_StringHolder &type =
2396  UT_StringHolder()) const;
2397  OP_DataBlockPtr getDataBlock(const char *key) const;
2398  bool setDataBlock(const char *key, OP_DataBlockPtr ptr);
2399  OP_ERROR saveDataBlocksPacket(std::ostream &os,
2400  const char *path_prefix,
2401  const UT_StringHolder &node_name);
2402  bool loadDataBlocks(UT_IStream &is, const char *path);
2403  bool clearDataBlocks();
2404  virtual void dataBlockChanged(const UT_StringHolder &key);
2405 
2406  // deleteNodeData is called when the OP_Cache wants to delete some data.
2407  // This method should return 1 if you want change events to be propagated
2408  // to the extra inputs when data is deleted from the cache.
2409  virtual int deleteNodeData(void *);
2410  void propagateNodeDataDeleted();
2411 
2412  // getCachedPythonObject returns NULL if no object exists with the given
2413  // key.
2414  PY_OpaqueObject *getCachedPythonObject(const UT_StringRef &key) const;
2415  // Call setCachedPythonObject with a PyObject * cast to a void *, not with
2416  // a PY_OpaqueObject * cast to a void *. The pointer must not be null.
2417  void setCachedPythonObject(
2418  const UT_StringHolder &key, void *opaque_py_object);
2419  // deleteCachedPythonObject returns false if no value exists with that key.
2420  bool deleteCachedPythonObject(const UT_StringRef &key);
2421  void clearCachedPythonObjects();
2422  // cachedPythonObjects returns a UT_StringMap containing pointers to
2423  // PY_OpaqueObjects. The pointers are not null.
2424  const OP_PythonObjectCache &cachedPythonObjects() const
2425  { return myCachedPythonObjects; }
2426 
2427  bool loadExtraInputs(UT_IStream &is,
2428  const char *path = nullptr);
2429 
2430  void saveOverrides(std::ostream &os);
2431  void saveOverrides(std::ostream &os, OP_Node *root,
2432  const UT_String &rootpath,
2433  bool &added);
2434  void saveChildOverrides(std::ostream &os, OP_Node *root,
2435  const UT_String &rootpath,
2436  bool &added);
2437  bool loadOverride(UT_IStream &is);
2439  fpreal t, int thread,
2440  const char *parm_name,
2441  int vec_idx) override;
2442  bool isParmPendingOverride(const char *parm_name,
2443  int vec_idx) const override;
2444  OP_ERROR cookOverrides(OP_Context &c);
2446  virtual void removeOverrideDestination(OP_Node * /*dest*/) {}
2447  virtual void removeOverrideDestination(OP_Node * /*dest*/,
2448  int /*parm_idx*/) {}
2449 
2450  // Overriding virtual function in PRM_ParmOwner to run a command.
2451  void executeCommand(const char *command,
2452  std::ostream *out,
2453  std::ostream *err) const override;
2454 
2457  pushAsPwd() const override;
2458 
2459  OP_ERROR executeHscriptScript(const char *script,
2460  const OP_Context &context);
2461  OP_ERROR executePythonScript(const char *script,
2462  const OP_Context &context);
2463 
2464  void addPythonNodeError(const PY_Result &py_result);
2465 
2466  void saveInputs(std::ostream &os, bool compile_basic);
2467  bool loadInputs(
2468  UT_IStream &is,
2469  const char *path = nullptr,
2470  bool named = false);
2471  void saveNamedInputs(std::ostream &os, bool compile_basic);
2472  void saveNamedOutputs(std::ostream &os);
2473  bool loadNamedOutputs(
2474  UT_IStream &is,
2475  const char *path = nullptr);
2476 
2477  // These methods provide access to the options that can be stored on each
2478  // input of a node, if the node type enables this feature.
2479  void getEditableInputDataKeys(OP_InputIdx idx,
2480  UT_StringArray &keys) const;
2481  const UT_OptionEntry*getEditableInputData(OP_InputIdx idx,
2482  const UT_StringRef &key) const;
2483  bool setEditableInputData(OP_InputIdx idx,
2484  const UT_StringHolder &key,
2485  const UT_OptionEntry &value);
2486  void saveEditableInputData(std::ostream &os) const;
2487  bool loadEditableInputData(UT_IStream &is,
2488  const char *path);
2489  // Special case functions for getting and setting the input "name", which
2490  // just call the generic InputData functions.
2491  UT_StringHolder getEditableInputString(OP_InputIdx idx,
2492  const UT_StringRef &key) const;
2493  bool setEditableInputString(OP_InputIdx idx,
2494  const UT_StringRef &key,
2495  const UT_StringHolder &str);
2496 
2497  /// @{ If a subclass is interested in the saved input or output names, then
2498  /// it should override this method. The array will be filled during load.
2499  virtual UT_StringArray * getArrayForLoadedInputNames();
2500  virtual UT_StringArray * getArrayForLoadedOutputNames();
2501  /// @}
2502 
2503  void checkInputs(); // this method will check the
2504  // node references in all the inputs
2505 
2506  // Saves out extra information for this node to be included in a dialog
2507  // script that defines an operator type created from this one.
2508  virtual void saveDialogScriptExtraInfo(std::ostream &os);
2509 
2510  // Fills in the supplied default gallery entry with info from this node.
2511  virtual void createGalleryEntry(OP_GalleryEntry &entry);
2512 
2513  // When a string parameter can have the syntax: 'op:/...', use these
2514  // evaulate methods to do the approprate checking and reference building.
2515  // These methods will return a reference to the OP_Node if one is
2516  // referenced. If the syntax is something like:
2517  // op:/foo/bar[32]
2518  // Then the optime will be (32-1)/$FPS rather than the evaluation time.
2519  void evalOpPathString(UT_String &val, int pi, int vi,
2520  fpreal t, int &op_id, fpreal &op_time,
2521  int expanded = 1);
2522  void evalOpPathString(UT_String &val, const char *pn,
2523  int &pi, int vi, fpreal t,
2524  int &op_id, fpreal &op_time,
2525  int expanded=1);
2526  static int findOpFramePair(const char *path, int &op_id,
2527  fpreal &frame);
2528 
2529  /// Build a UT_XformOrder out of TRS and XYZ parameter values
2530  static void buildXformOrder(int trs, int xyz,
2531  UT_XformOrder &order);
2532 
2533  static const UT_XformOrder& buildXformOrder(int trs, int xyz );
2534 
2535  /// Translate a TRS parameter menu index into the UT_XformOrder type
2536  static UT_XformOrder::rstOrder getMainOrder( int trs );
2537  /// Translate a UT_XformOrder type into a TRS parameter menu index
2538  /// (inverse of getMainOrder())
2539  static int getMainOrderMenuIndex(UT_XformOrder::rstOrder order);
2540  /// Translate a XYZ parameter menu index into the UT_XformOrder type
2541  static UT_XformOrder::xyzOrder getRotOrder( int xyz );
2542  /// Translate a UT_XformOrder type into a XYZ parameter menu index
2543  /// (inverse of getRotOrder())
2544  static int getRotOrderMenuIndex(UT_XformOrder::xyzOrder order);
2545 
2546  /// NB: None of the getXformPivot() or getPivotParmValue() methods take
2547  /// any pivot compensation transform into account. It is up to the
2548  /// caller to account for any such transform.
2549  static UT_Vector3R getXformPivot(int trs,
2550  fpreal tx, fpreal ty, fpreal tz,
2551  fpreal px, fpreal py, fpreal pz);
2552  static UT_Vector3R getXformPivot(int trs,
2553  fpreal tx, fpreal ty, fpreal tz,
2554  fpreal px, fpreal py, fpreal pz,
2555  fpreal pivot_rx, fpreal pivot_ry,
2556  fpreal pivot_rz, bool inverse = false);
2557  static UT_Vector3R getPivotParmValue(int trs,
2558  fpreal tx, fpreal ty, fpreal tz,
2559  fpreal px, fpreal py, fpreal pz);
2560  static UT_Vector3R getPivotParmValue(int trs,
2561  fpreal tx, fpreal ty, fpreal tz,
2562  fpreal px, fpreal py, fpreal pz,
2563  fpreal pivot_rx, fpreal pivot_ry,
2564  fpreal pivot_rz, bool inverse = false);
2565 
2566  static void buildXform(int trs, int xyz,
2567  float tx, float ty, float tz,
2568  float rx, float ry, float rz,
2569  float sx, float sy, float sz,
2570  float px, float py, float pz,
2571  UT_Matrix4 &mat);
2572  static void buildXform(int trs, int xyz,
2573  double tx, double ty, double tz,
2574  double rx, double ry, double rz,
2575  double sx, double sy, double sz,
2576  double px, double py, double pz,
2577  UT_DMatrix4 &mat);
2578  static void buildXform(int trs, int xyz,
2579  float tx, float ty, float tz,
2580  float rx, float ry, float rz,
2581  float sx, float sy, float sz,
2583  UT_Matrix4 &mat);
2584  static void buildXform(int trs, int xyz,
2585  double tx, double ty, double tz,
2586  double rx, double ry, double rz,
2587  double sx, double sy, double sz,
2589  UT_DMatrix4 &mat);
2590  static void buildXform(int trs, int xyz,
2591  float tx, float ty, float tz,
2592  float rx, float ry, float rz,
2593  float sx, float sy, float sz,
2594  float s_xy, float s_xz, float s_yz,
2595  float px, float py, float pz,
2596  UT_Matrix4 &mat);
2597  static void buildXform(int trs, int xyz,
2598  double tx, double ty, double tz,
2599  double rx, double ry, double rz,
2600  double sx, double sy, double sz,
2601  double s_xy, double s_xz, double s_yz,
2602  double px, double py, double pz,
2603  UT_DMatrix4 &mat);
2604  static void buildXform(int trs, int xyz,
2605  float tx, float ty, float tz,
2606  float rx, float ry, float rz,
2607  float sx, float sy, float sz,
2608  float s_xy, float s_xz, float s_yz,
2610  UT_Matrix4 &mat);
2611  static void buildXform(int trs, int xyz,
2612  double tx, double ty, double tz,
2613  double rx, double ry, double rz,
2614  double sx, double sy, double sz,
2615  double s_xy, double s_xz, double s_yz,
2617  UT_DMatrix4 &mat);
2618  static void buildXform(
2619  const UT_Matrix4F::FullTransformModel &parms,
2620  UT_Matrix4F &mat);
2621  static void buildXform(
2622  const UT_Matrix4D::FullTransformModel &parms,
2623  UT_Matrix4D &mat);
2624  static void buildXform(int trs,
2625  float tx, float ty, float rz,
2626  float sx, float sy, float px, float py,
2627  UT_Matrix3 &mat);
2628  static void buildXform(int trs,
2629  double tx, double ty, double rz,
2630  double sx, double sy, double px, double py,
2631  UT_DMatrix3 &mat);
2632  static void buildXform(int trs,
2633  float tx, float ty, float rz,
2634  float sx, float sy, float s_xy,
2635  float px, float py,
2636  UT_Matrix3 &mat);
2637  static void buildXform(int trs,
2638  double tx, double ty, double rz,
2639  double sx, double sy, double s_xy,
2640  double px, double py,
2641  UT_DMatrix3 &mat);
2642 
2643  virtual int getTranslateParmIndex();
2644 
2645  // This is done only after a load to make sure that
2646  // all inputs have been resolved correctly.
2647  void resolveInputReferences();
2648 
2649  static void clearAllPendingUndoFlags();
2650 
2651  void clearUndoFlags() override;
2652  void setAnyUndoFlag() override;
2653  void saveForUndoInput();
2654 
2655  /// When doing bulk parameter modifications, they can be sandwiched between
2656  /// blockModify(true) and blockModify(false) statements as an optimization.
2657  /// Parameters modified during blockModify(true) will have their dirtiness
2658  /// propagation to other scene entities like nodes and parameters
2659  /// suppressed until blockModify(false) is called.
2660  ///
2661  /// @note This will NOT suppress events to addOpInterest() callbacks.
2662  /// In fact, blockModify(false) currently sends out an extraneous
2663  /// OP_PARM_CHANGED with parm index of -1.
2664  void blockModify(int on_off, int propagate = 1);
2665 
2666  int isBlockModify() const;
2667  bool isModifyWaiting() const;
2668  virtual void propagateEndBlockModify();
2669 
2670  // Only returns anything in the case of chops
2671  virtual const CL_Clip *getClip(OP_Context *context = nullptr);
2672 
2673  /// Returns the a chop network path suitable for storing motion effects
2674  /// associated with this node.
2675  void getMotionEffectsNetworkPath(UT_String &path);
2676 
2677  fpreal getLastCookTime() const;
2678  /// Return the last cook time as a formatted string.
2679  void getLastCookTime(UT_String &last_cook_time) const;
2680  /// Return the cook information as a formatted string.
2681  void getCookInfo(UT_String &info) const;
2682  /// Return the cook information in a UT_InfoTree.
2683  void getCookInfoTree(UT_InfoTree &tree) const;
2684 
2685  // Those operators which need a ramp editor must define this method.
2686  virtual UT_Ramp *getRamp();
2687 
2688  virtual int isCookingRender() const { return 0; }
2689  virtual void setCookingRender(int val);
2690 
2691  virtual void clearInterrupted()
2692  { clearInterruptedImpl(/*allow_recook*/true); }
2693  bool wasInterrupted() const
2694  { return flags().getInterrupted(); }
2695 
2696  // work-around to display warning message when export src or destination
2697  // are renamed. OP_Node::cook clears the error messages when a node export
2698  // changes so we had to save the fact that a rename conflict is pending
2699  void setRenameConflict()
2700  { myRenameConflict = 1; }
2701  void setRunningCreateScript(int onoff);
2702 
2703  // Base class methods to output code to a file or a stream:
2704  virtual int outputCode(OP_OutputCodeParms &, OP_Context &);
2705 
2706  virtual fpreal getTimeTransform(int input, fpreal t);
2707  virtual void getInputRes(int input, fpreal t,
2708  const OP_Context &context,
2709  OP_Context &input_context);
2710 
2711  // Utility methods:
2712  UT_TokenString & getHashCode(OP_Context &context, int group_mask =1);
2713  virtual UT_TokenString & getParmHashCode(OP_Context &context,
2714  int group_mask = 1);
2715 
2716  virtual int getNumInputsToHash();
2717  virtual OP_Node *getInputToHash(OP_InputIdx i);
2719  void clearHashCodeFlags();
2720  bool isHashCodeBuilt() const { return myBuiltHashCode;}
2721  void builtHashCode(bool b = true) { myBuiltHashCode = b; }
2722  void buildInputHashCode(UT_TokenString &string,
2723  OP_Context &context,
2724  int group_mask,
2725  int level);
2727  // If an interactive state was used to create this node, set it here.
2728  void setCreatorState(const char *s)
2729  { myCreatorState.harden(s); }
2730  const UT_String &getCreatorState() const { return myCreatorState; }
2731  void builtExplicitly(int yn) { myBuiltExplicitly = yn; }
2732  int wasBuiltExplicitly() const{ return myBuiltExplicitly; }
2733 
2734  bool matchesState(const char *state) const;
2735 
2736  /// Some nodes (VOPs and SHOPs) represent shaders, so this method
2737  /// returns node parameters that are used as shader parameters.
2738  virtual const PRM_Template *getShaderParmTemplates();
2739 
2740  // Don't even think about calling changeParmTemplate if you aren't
2741  // OP_Operator.
2742  virtual void changeParmTemplate(PRM_Template *new_template);
2743 
2744  // Deletes any input or output connections in excess of maximum allowed.
2745  virtual void ensureInputsAndOutputsAreValid();
2746 
2747  // Connect the node to an input. If branch_off is false and the input node
2748  // currently has outputs, the node will be inserted before the outputs.
2749  void connectToInputNode(OP_Node &inputnode,
2750  OP_InputIdx input_idx,
2751  int branch_off=0);
2752 
2753  // This method should be called when the user edits an overridden channel
2754  virtual int editCallback(CL_Track *track, fpreal t,
2755  fpreal new_value);
2756 
2757  // This mechanism allows users to communicate editing changes
2758  static OP_EditCallback getEditCallback(void *&data);
2759  //static void setEditCallback(OP_EditCallback func,
2760  //void *data);
2761 
2762  // These build an xform matrix based upon the given parameters.
2763  // The axis is the axis around which to rotate by 90 degrees. If
2764  // it is lower case, it will be rotated by +90, if it is upper case,
2765  // by -90. To not rotate at all, use '-'.
2766  static void buildQuadricXform(UT_Matrix4 &mat,
2767  float tx, float ty, float tz,
2768  float sx, float sy, float sz,
2769  char axis = 'y',
2770  float rx = 0.0f, float ry = 0.0f,
2771  float rz = 0.0f);
2772 
2773  static void buildQuadricXform(UT_DMatrix4 &mat,
2774  double tx, double ty, double tz,
2775  double sx, double sy, double sz,
2776  char axis = 'y',
2777  double rx = 0.0, double ry = 0.0,
2778  double rz = 0.0);
2779 
2780  static int buildOpMenu(
2781  OP_Network *net,
2782  PRM_Name *the_menu,
2783  int the_menu_size,
2784  int (*do_add)(OP_Node *) = nullptr,
2785  int start_item = 0,
2786  const PRM_Parm *parm = nullptr,
2787  int show_subnets = 1,
2788  int expand_subnets = 1,
2789  bool recurse = false);
2790 
2791  // Build the "Predefined Rules" menu that is common to several OPs
2792  // including Event and Group POPs. This is built from the text file table
2793  // OP<name>Rules, where name is the OP type (ie Event).
2794  static void buildPreDefRulesMenu(PRM_Name *menu,
2795  OP_PreDefRules &pdr);
2796 
2797  // Allows operators to use their own local table for variables and build
2798  // structures on demand... Implement the syntax highlight version only
2799  // if you need to resolve variables for syntax highlighting that are not
2800  // normally resolved by the generic resolveVariable() method.
2801  virtual const CH_LocalVariable *resolveVariable(const char *name);
2802  virtual const CH_LocalVariable *resolveExtraVariableForSyntaxHighlight(
2803  const char *name);
2804 
2805  // This value bumps whenever nodes are created/deleted/renamed.
2806  static int getNameSerialIndex();
2807 
2808  // export mapping techniques
2809  virtual void setMapping(int idx, int type,
2810  const char *label = nullptr);
2811  virtual int getMapping(int idx, const char *&label) const;
2812 
2813  // drag-n-drop receive methods
2814  virtual int acceptDragDrop(DD_Source &src, const char *label);
2815  virtual int testDragDrop(DD_Source &src);
2816  virtual void getDragDropChoice(DD_Source &src, DD_ChoiceList &c);
2817 
2818  // These methods are used to give quick overview information about a node
2819  bool hasComment() const;
2820  bool hasParmsNotAtFactoryDefault() const;
2821  bool hasAnimatedParms() const;
2822  bool hasChopOverriddenParms() const;
2823 
2824  /// traverseInputs calls 'callback' on this node and all its inputs.
2825  /// If callback returns true for any node, it will stop and return
2826  /// true, otherwise it will return false;
2827  /// @param callback Callback function
2828  /// @param data User data passed to the callback function
2829  /// @param opts A set of flags to configure the traversal:
2830  /// TRAVERSE_INTO_SUBNETS If input is a subnet, we continue
2831  /// traversing from its display node.
2832  /// TRAVERSE_REF_INPUTS Follow inputs marked as reference inputs
2833  /// TRAVERSE_ONLY_USED_INPUTS Follow only inputs used in the last cook
2834  /// TRAVERSE_PASSTHROUGH_INPUTS Use the getPassThroughNode to traverse
2835  /// through nodes that directly steal their
2836  /// input node's data.
2837  /// TRAVERSE_EXTRA_INPUTS Follow nodes which this node implicitly
2838  /// depends on.
2839  /// TRAVERSE_SIMULATION_INPUTS For nodes that are DOP parents, grab extra
2840  /// inputs from the simulation.
2841  /// TRAVERSE_COOKED_INPUT_INDEX_INPUTS
2842  /// Uses the cookedInputIndex method to
2843  /// traverse "passthrough"-type inputs for
2844  /// nodes that might trigger a cook when
2845  /// calling getPassThroughNode, but where we
2846  /// want to avoid triggering a cook.
2847  /// @param extra_interest_mask For extra inputs, this mask allows one to
2848  /// restrict which of those dependency types
2849  /// follow.
2850  //@{
2852  TRAVERSE_DEFAULT = 0x0000,
2853  TRAVERSE_INTO_SUBNETS = 0x0001,
2854  TRAVERSE_REF_INPUTS = 0x0002,
2855  TRAVERSE_ONLY_USED_INPUTS = 0x0004,
2856  TRAVERSE_PASSTHROUGH_INPUTS = 0x0008,
2857  TRAVERSE_EXTRA_INPUTS = 0x0010,
2858  TRAVERSE_SIMULATION_INPUTS = 0x0020,
2859  TRAVERSE_COOKED_INPUT_INDEX_INPUTS = 0x0040,
2860  };
2861  bool traverseInputs(bool (*callback)(OP_Node &, void *),
2862  void *data,
2863  TraverseOptions opts,
2864  OP_InterestType extra_interest_mask =
2865  OP_INTEREST_ALL);
2866  bool traverseInputs(bool (*callback)(const OP_Node &, void*),
2867  void *data,
2868  TraverseOptions opts,
2869  OP_InterestType extra_interest_mask =
2870  OP_INTEREST_ALL) const;
2871  //@}
2872 
2873  /// Using this node as a starting point, traverse our inputs recursively
2874  /// to get our best guess of the nodes that have been cooked to generate
2875  /// the current cooked result of this node.
2876  void getCookPathNodes(OP_NodeList &nodes);
2877 
2878  /// Traverses children of this node, calling 'callback' on all children.
2879  /// If callback returns true, the traversal stops at that node.
2880  bool traverseChildren(bool (*callback)(OP_Node &, void*),
2881  void *data,
2882  bool recurse_into_subnets);
2883 
2884  // Very specialized to see if this node (and optionally, any input
2885  // ancestors are also cooking.
2886  bool isCooking(bool include_ancestors) const;
2887 
2888  // This method returns true if the OP_Node makes use of its footprint
2889  // flag and false otherwise.
2890  virtual bool usesFootprint() const { return false; }
2891 
2892  void getExternalReferences(
2893  UT_StringArray &reflist,
2894  UT_StringArray *nodelist = nullptr,
2895  bool from_children_too = true,
2896  bool collapse = false,
2897  bool check_missing = false,
2898  bool show_missing_only = false);
2899  virtual bool getSaveWithVopnets();
2900  virtual void runDelScript();
2901  /// Overriden in VOPs to remove any channel refrences we may have
2902  /// to the node being deleted.
2903  virtual void preDelete() { }
2904 
2905  // Two functions for upcasting this node to a DOP_Parent. DOP_Parent
2906  // is a class which owns a simulation and has DOP_Nodes as children.
2907  virtual DOP_Parent *castToDOPParent() { return nullptr; }
2908  virtual const DOP_Parent *castToDOPParent() const { return nullptr; }
2909 
2910  // These provide a version which you can query without being above DOP.
2911  // This will also return dop parents for non-DOPs that have cache
2912  // like interfaces.
2914  { return (OP_DopParent *) castToDOPParent(); }
2915  virtual const OP_DopParent *castToOpDopParent() const
2916  { return (const OP_DopParent *) castToDOPParent(); }
2917 
2918  // This function upcasts this node to a VOP_CodeGenerator.
2919  // VOP_CodeGenerator is a class which generates VEX code from the VOPs
2920  // contained inside the node.
2921  virtual VOP_CodeGenerator *getVopCodeGenerator() { return nullptr; }
2922  virtual VOP_CodeGenerator *getVopAutoCodeGenerator() { return nullptr; }
2923  virtual const VOP_CodeGenerator
2924  *getVopAutoCodeGenerator() const{ return nullptr; }
2925  // Some nodes will only generate vop code generators on demand, this
2926  // will ensure they are built.
2927  virtual void buildVopCodeGenerator() {}
2928 
2929  // Return the manager that handles exported parameters from contained
2930  // Parameter VOPs. Only certain kinds of VOP nodes can have such a manager
2931  // (i.e. Subnet VOPs, VOP HDAs). Note that a node cannot have both a code
2932  // generator AND a parms manager because the code generator already has its
2933  // own parms manager.
2934  virtual VOP_ExportedParmsManager *getVopExportedParmsManager(
2935  bool create_if_needed=false)
2936  { return nullptr; }
2937 
2938  /// @{
2939  /// Methods to postpone the update of the code generator until ending
2940  /// the last (level zero) update. This avoids recalculation of parameters
2941  /// and vop signatures, which can be quite costly.
2942  // TODO: remove these two virtuals in farour of getVopCodeGenerator()
2943  // returning OP_VopCodeGenerator from which VOP_CodeGenerator
2944  // derives and which has these two virtuals available at OP level.
2945  virtual int beginVopCodeGeneratorUpdate() { return 0; }
2946  virtual void endVopCodeGeneratorUpdate(int update_level) {}
2947  /// @}
2948 
2949  // Build a command line for a VEX script to be called with. This does all
2950  // the channel evaluation and string expansion required. If there is an
2951  // error, 0 is returned (otherwise 1).
2952  int buildVexCommand(UT_String &result,
2953  const PRM_Template *templatelist,
2954  fpreal now,
2955  int start_parm = 0,
2956  int end_parm = INT_MAX,
2957  bool use_parmvop_tag=true
2958  );
2959  int buildVexCommandWithDependencies(OP_Node *owner,
2960  DEP_MicroNode *depnode,
2961  UT_String &result,
2962  const PRM_Template *templatelist,
2963  fpreal now,
2964  int start_parm = 0,
2965  int end_parm = INT_MAX,
2966  bool use_parmvop_tag=true
2967  );
2968 
2969  // Builds a VEX script using standardized parameter names.
2970  // "vexsrc": int for myself, shop, or script.
2971  // "script": raw vex script
2972  // "soppath": for the shop path.
2973  static PRM_ChoiceList theVexSrcParmMenu;
2974  static PRM_Name theVexSrcParmName;
2975  static PRM_Name theVexScriptParmName;
2976  static PRM_Name theVexNodePathParmName;
2977  static PRM_Name theVexClearParmName;
2978  static PRM_Name theVexCWDName;
2979  virtual void buildVexScript(UT_String &script, fpreal t,
2980  OP_Node *owner,
2981  UT_Map<int, bool> *visitlist = nullptr);
2982  virtual void buildVexScript(UT_String &script, fpreal t,
2983  DEP_MicroNode *depnode,
2984  UT_Map<int, bool> *visitlist = nullptr);
2985 
2986 
2987  // Returns true if vex shader has parameter by a given name.
2988  virtual bool hasVexShaderParameter(const char *parm_name);
2989 
2990 
2991  /// This function returns a string that encodes all the necessary
2992  /// information about a node-based material that helps the script-based
2993  /// materials to function properly. The string usually encodes info stored
2994  /// on child nodes, such as rendering properties or procedurals. Then
2995  /// the script node can use that info to provide necessary data
2996  /// for rendering.
2997  /// Returns true if the method provides usable information.
2998  virtual bool getScriptMaterialInfo( UT_String & mat_info,
2999  VOP_ScriptMaterialCodeMapper * mapper )
3000  { return false; }
3001 
3002  /// Returns the sub type name, if the node's operator wants to be
3003  /// saved as an HDA in a special way (ie, other than the regular
3004  /// scripted operator handling). The sub type name is then used
3005  /// to distinguish how to handle the HDA creation.
3006  virtual const char *getHDASubType()
3007  { return nullptr; }
3008 
3009  // Set the channel alias for a channel (or parm subindex). Returns true
3010  // if successful and false otherwise.
3011  bool setChannelAlias(PRM_Parm &parm, int subindex,
3012  const char *alias_name);
3013 
3014  void disconnectAllInputsOutputs(
3015  bool keep_selected,
3016  bool force_disconnect_outputs = false);
3017 
3018  void disconnectAllInputs();
3019  void disconnectAllOutputs();
3020 
3021  // Notify dependents that a parm name has changed.
3022  virtual void notifyParmRenameDependents(
3023  const UT_String &chan_name,
3024  const UT_String &old_chan_name );
3025 
3026  void writeChannel(CH_Channel *channel, std::ostream &os,
3027  const char *name, bool frames);
3028  void writeAllChannels(std::ostream &os, const char *name,
3029  bool frames, bool dochblock,
3030  bool dospareparms);
3031 
3032  // Run the callback function for a particular parm, and the callbacks
3033  // of any parms linked to this parm. Returns false if the node is
3034  // deleted while running the callback.
3035  bool triggerParmCallback(
3036  PRM_Parm *parmptr,
3037  fpreal now,
3038  int value,
3039  void *data,
3040  const UT_Options *options = nullptr) override;
3041 
3042  // Run the callback function for a particular parm only.
3043  // Returns false if the node is deleted while running the callback.
3044  bool triggerSoloParmCallback(
3045  PRM_Parm *parmptr,
3046  fpreal now,
3047  int value,
3048  void *data,
3049  const UT_Options *options = nullptr);
3050 
3051  int64 getMemoryUsage(bool inclusive) const override;
3052  int64 getExtraInputMemoryUsage() const;
3053  static void printOpMemoryUsageStats(std::ostream &os);
3054 
3055  /// This method will unscope all the channels belonging to this op.
3056  /// If the recurse flag is set it will recurse through the children
3057  /// (at this level the recurse flag is ignored).
3058  virtual void unscopeChannels(bool recurse);
3059 
3060  /// This method will undisplay all the channels belonging to this op.
3061  /// If the recurse flag is set it will recurse through the children
3062  /// (at this level the recurse flag is ignored).
3063  virtual void undisplayChannels(bool recurse);
3064 
3065  /// This method will unpin all the channels belonging to this op.
3066  /// If the recurse flag is set it will recurse through the children
3067  /// (at this level the recurse flag is ignored).
3068  virtual void unpinChannels(bool recurse);
3069 
3070  /// This method takes a pattern string and will perform the ch_scope_op
3071  /// on each of our paramaeters that match the pattern. This method
3072  /// primarily supports the chscope command.
3073  virtual void setChannelScope(const char *pattern,
3074  OP_ScopeOp scope_op,
3075  const OP_ScopeOptions &scope_opts);
3076 
3077  /// A simple wrapper around getName() to allow us to abstract its
3078  /// functionality up to OP_NetworkBoxItem.
3079  const UT_StringHolder &getItemName() const override
3080  { return getName(); };
3081  bool setItemName(const UT_StringHolder &name) override;
3082 
3083  /// Caches the descriptive name to member data, and returns that. The
3084  /// cache is automatically dirtied in opChanged.
3085  const UT_StringHolder &getCachedDescriptiveName();
3086 
3087  // This function is called when our spare parm definition is changing.
3088  bool changeSpareParms(UT_IStream &istream,
3089  UT_String &errors) override;
3090  // This function is called during the changeSpareParms operation when
3091  // one of our parameters is being removed.
3092  void spareParmRemoved(const char *parmname) override;
3093 
3094  // This is a secondary parm list where all obsolete parameters are
3095  // placed (if any)
3098  PRM_ParmList *&obsolete_parms) override;
3099 
3100  unsigned referenceAllParameters(
3101  OP_Parameters *from,
3102  bool relative_references = true) override;
3103 
3104  void clearVersionUserData();
3105  void updateVersionUserData();
3106 
3107  /// After the nodes parameter list is loaded, syncNodeVersionIfNeeded() is
3108  /// called to perform any necessary upgrades if the version number of
3109  /// the loaded node (taken from user data) is different from the node
3110  /// type's version number (getOperator()->getVersion()). Use the
3111  /// from_version parameter to override the node current version.
3112  /// If needed, this will call syncNodeVersion(). After synching, the node's
3113  /// version user data will be set to the current version if
3114  /// update_node_version is true.
3115  void syncNodeVersionIfNeeded(
3116  bool *node_deleted,
3117  const char *from_version = nullptr,
3118  bool update_node_version = false);
3119 
3120  /// Sync the node assuming that it is currently at old_version to the
3121  /// current_version. By default, this will call the corresponding
3122  /// OTL_SYNCNODEVERSION section if it exists.
3123  void syncNodeVersion(
3124  const char *old_version,
3125  const char *current_version,
3126  bool *node_deleted) override;
3127 
3128  // Sets the given stamping parameter.
3129  // Returns true if the param was changed. Note that we may return false
3130  // even if this was a valid operation as param might have already been
3131  // set to the given value.
3132  // If the warned variable is given, then we only warn if its contents
3133  // is false. Then in that case, we will set it to true when needed.
3134  bool setGlobalFloatParam(const char *param,
3135  fpreal value,
3136  bool *warned);
3137  bool setGlobalStringParam(const char *param,
3138  const char *strvalue,
3139  bool *warned);
3140 
3141  // This allows one to prevent chop cooking due to parameter modifications
3142  // until the outermost block is done.
3143  void beginPropagateModification();
3144  void endPropagateModification();
3145 
3146  // Add any OTL-defined operators used by this node to the specified table.
3147  virtual void getActiveOperatorsDefinedByOTL(
3148  UT_Set<OP_Operator *> &active_operators) const;
3149 
3150  // Returns true if we are in the middle of a call to sendBulkNotifications,
3151  // Or doing some other operation that involves sending out a whole bunch
3152  // of change notifications all at once. This allows VOP Networks to avoid
3153  // over-cooking.
3154  static bool getDoingBulkNotification();
3155  static bool isDirectorDoingBulkNotification();
3156 
3157  /// Returns whether multi-inputs on this particular op might have different
3158  /// names for each of the inputs, or if the name will always be the same for
3159  /// all the inputs.
3160  virtual bool hasDifferentMultiInputs() const;
3161 
3162 
3163  virtual bool canCreateNewOpType() const;
3164  static bool createNewOpType
3165  (OP_Node *node,
3166  UT_String &errors,
3167  const char *type_name=nullptr,
3168  const char *type_label=nullptr,
3169  const char *otl_file=nullptr,
3170  const char *meta_source=nullptr,
3171  const char *comment=nullptr,
3172  const char *version=nullptr,
3173  const char *new_name=nullptr,
3174  int minimum_inputs=-1,
3175  int maximum_inputs=-1,
3176  bool ignore_external_references=false,
3177  bool compress_contents=false,
3178  bool force=false,
3179  int *new_node_id=nullptr,
3180  bool compile_contents = false,
3181  bool change_node_type = true,
3182  bool create_backup = true);
3184  virtual UT_String *getMaterialIconFilename() { return nullptr; }
3185  virtual void setMaterialIconFilename(const char * /*icon_file*/) {}
3186  virtual IMG_Raster *getMaterialIconImage() { return nullptr; }
3187  virtual bool getMaterialIconAllowRegenerateFlag() { return true; }
3188  virtual void setMaterialIconAllowRegenerateFlag(bool) {}
3189 
3190  // Call these functions when making a lot of calls to opChanged on a
3191  // list of nodes. These functions make sure that VOP Networks only get
3192  // one change notification no matter how many child nodes are about
3193  // to send any number of change events.
3194  // @parm caller The node that starts the bulk notifications, if applicable.
3195  static void startBulkNotifications(
3196  const OP_NodeList &changed,
3197  OP_Node *caller = nullptr);
3198  static void endBulkNotifications(
3199  const OP_NodeList &changed);
3200 
3201  /// This is overriden in VOPs. It returns true if the input at input_idx
3202  /// will need *and* can perform autoconversion of its input type to the
3203  /// type it needs. If autoconversion is not needed, or is impossible,
3204  /// this will return false.
3205  virtual bool willAutoconvertInputType(OP_InputIdx input_idx);
3206 
3207  bool isDependentOn(OP_Node* other_node, PRM_Parm* parm);
3208 
3209  // Gets whether the input at idx is collapsed. Currently this is only used
3210  // in VOPs.
3211  virtual bool getIsInputVisibleDefault(OP_InputIdx idx);
3212 
3213  // Debugging function to confirm that all PRM_Template's are consistent
3214  // with their parameters.
3215  bool verifyTemplatesWithParameters() const;
3216 
3217  // Same as getInputReference, except using a named reference.
3218  OP_Input *getNamedInputReference(
3219  const OP_ConnectorId& input_name, bool grow);
3220  OP_Input *getNamedInputReferenceConst(
3221  const OP_ConnectorId& input_name) const;
3222 
3223  OP_Node *getNamedInput(const OP_ConnectorId& input_name,
3224  bool mark_used=false) const;
3225  /// Note that this function only looks through currently connected
3226  /// inputs for the name, not through all possible input names on
3227  /// this node. mapInputNameToIndex does that instead.
3228  virtual OP_InputIdx getInputFromName(const UT_String &in) const;
3229  virtual OP_OutputIdx getOutputFromName(const UT_String &out) const;
3230  virtual void getInputName(UT_String &in, OP_InputIdx idx) const;
3231  virtual void getOutputName(UT_String &out, OP_OutputIdx idx) const;
3232  static UT_StringHolder defaultInputName(OP_InputIdx idx);
3233  static UT_StringHolder defaultOutputName(OP_OutputIdx idx);
3234 
3235  OP_OutputIdx getSpareOutputFromName(const UT_StringHolder& name) const;
3236 
3237  OP_InputIdx getInputFromUniqueName(
3238  const OP_ConnectorId& id) const;
3239  UT_Optional<OP_OutputIdx> getOutputFromUniqueName(
3240  const OP_ConnectorId& id) const;
3241 
3242  // Returns the unique name of the input at index idx. Creates the input if
3243  // grow is set to true.
3244  void getUniqueInputName(OP_ConnectorId& id_out,
3245  OP_InputIdx idx, bool grow);
3246  bool getUniqueInputNameConst(
3247  OP_ConnectorId& id_out, OP_InputIdx idx) const;
3248 
3249  void getUniqueOutputName(OP_ConnectorId& id_out,
3250  OP_OutputIdx idx);
3251  bool getUniqueOutputNameConst(
3252  OP_ConnectorId& id_out, OP_OutputIdx idx) const;
3253 
3254  /// New input functions that use names instead of indices.
3255  virtual OP_ERROR setNamedInput(const OP_ConnectorId& input_name,
3256  OP_Node *op,
3257  const OP_ConnectorId* output_name = nullptr);
3258 
3259  virtual OP_ERROR setNamedIndirectInput(
3260  const OP_ConnectorId& input_name,
3261  OP_IndirectInput *input);
3262  virtual OP_ERROR setNamedInputReference(
3263  const OP_ConnectorId& input_name,
3264  const char *label, int,
3265  const OP_ConnectorId* output_name = nullptr);
3266 
3267  OP_ERROR insertNamedInput(
3268  const OP_ConnectorId& input_name, OP_Node *op,
3269  const OP_ConnectorId* output_name);
3270  OP_ERROR insertNamedIndirectInput(
3271  const OP_ConnectorId& input_name,
3272  OP_IndirectInput *input);
3274  /// Returns input for the spare parm input.
3275  virtual OP_Input *getParmInput(OP_OutputIdx idx) const
3276  { return nullptr; }
3278  /// Overriden in VOPs.
3279  virtual void onCreated() { }
3280 
3281  virtual bool isOrderedInput(const OP_ConnectorId& input_name) const;
3282 
3283  /// Returns the name of the first connection from node "who" to this node,
3284  /// or an empty string if "who" is not an input.
3285  OP_ConnectorId whichNamedInputIs(const OP_Node *who) const;
3286 
3287  /// Returns the index of the first connection of an indirect input.
3288  OP_ConnectorId whichNamedInputIs(const OP_IndirectInput *who) const;
3289  virtual bool willAutoconvertNamedInputType(
3290  const OP_ConnectorId& input_name);
3291 
3292  /// Note: Use these carefully, since they assume that no inputs are actually
3293  /// added or removed (or renamed) during the traversal.
3294  OP_ConnectorInputIter traverseInputs(OP_ConnectorInputIter* prev_iter);
3295  OP_ConnectorInputIter traverseConnectedInputs(OP_ConnectorInputIter* prev_iter);
3296  OP_ConnectorInputIter getTraverseEndIterator();
3297 
3298  unsigned getInputsArraySize()
3299  { return myInputs.entries(); }
3300  /// Deprecated in favour of getInputsArraySize()
3301  SYS_DEPRECATED(17.0) unsigned isInput(unsigned idx)
3302  { return (getInputsArraySize() > idx) ? 1 : 0; }
3303 
3304  /// Retrieve a sorted list of local variables visible to this OP_Node.
3305  void getLocalVarNames(UT_StringArray &out_vars);
3306 
3307  // Forcibly enable evaluation of local variables outside of cooking code
3308  // paths so that the last cooked value can be used for things like
3309  // pivot values for handles.
3310  bool setLocalVarActive(bool f)
3311  {
3312  bool old = myLocalVarActive;
3313  myLocalVarActive = f;
3314  return old;
3315  }
3317  /// Get the myLocalVarActive flag
3318  bool isLocalVarActive() const
3319  { return myLocalVarActive; }
3320 
3321  /// Return a UT_AttributeEvaluator for dealing with the evaluation of
3322  /// local variables designated by an "@" prefix.
3323  virtual UT_AttributeEvaluator *createAttributeEvaluator(const char *name);
3324  virtual void getAttributeEvaluatorNames(UT_StringArray &names);
3325 
3326  void recomputeCompiledHash();
3327 
3328  /// Clears the compiled hash (needed when switching from a compiled library
3329  /// definition to one that is not compiled).
3330  void clearCompiledHash()
3331  { myCompHash = DEFAULT_COMP_HASH_VALUE; }
3332 
3333  /// You should use opChanged() instead. This is only for very special
3334  /// cases. If you don't know you are a special case, you aren't.
3335  void directSendEvent(OP_EventType type, void *data=nullptr)
3336  { sendEvent(type, data); }
3337 
3338  virtual bool scopedChannelsDirty();
3339 
3340  /// This mechanism allows users to evaluate active layer contribution
3341  /// without needing to link against CHOP.
3342  virtual bool getActiveLayerContribution(const UT_String &track_name,
3343  fpreal t, fpreal &value, fpreal &weight)
3344  { return false; }
3345 
3346  /// Try to resolve exports on CHOP Channel Nodes from a value parameter
3347  /// within the array.
3348  virtual bool resolveExport(const PRM_Parm* p, int subindex,
3349  CH_ChannelRef& out_export )
3350  { return false; }
3351 
3352  /// Creates or moves an existing visualizer in this network to
3353  /// this nodes output.
3354  virtual bool addOrMoveVisualizerToOutput(int outputidx)
3355  { return false; }
3356 
3357  const PRM_Parm *traverseRef(
3358  int *sub_idx,
3359  fpreal time,
3360  int parm_idx,
3361  int vec_idx) const override;
3362 
3363  OP_Bundle * getParmBundle(const char* parm_name, int vector_index,
3364  UT_String &pattern, OP_Network *creator,
3365  const char *filter, bool subnet_inclusion);
3366 
3367  /// For node types with no other default color override, this is the
3368  /// final fallback default color for all nodes.
3369  static const UT_Color &getGlobalDefaultColor();
3370 
3371  /// The following methods are to be used to implement getW() and getH() in
3372  /// sub-classes. They are in absolute, pan-and-scale independent UI units.
3373 
3374  /// Get the width of flags.
3375  static fpreal getFlagWidth();
3376  /// Get the default node height.
3377  static fpreal getNodeHeight();
3378  /// Get the default width of the "node button" (the part of the node
3379  /// that you can drag and click on that isn't flags).
3380  static fpreal getNodeButtonWidth();
3381  /// Get the default connector height.
3382  static fpreal getConnectorHeight();
3383 
3384  /// Returns true if we are allowed to destroy the specified nodes. If
3385  /// nodes is non-null, we test those nodes. If nodes is null, we test
3386  /// the picked nodes of the src_net. The return value assumes that all
3387  /// specified nodes will be destroyed, which is important because it
3388  /// may be safe to delete node A iff node B is also going to be deleted.
3389  static bool canDestroyNodes(OP_Network *src_net,
3390  const OP_NodeList *nodes);
3391 
3392  /// Add an error to the given error manager, collapsing chains
3393  /// of invalid sources.
3394  static void addInputNodeErrorToManager(UT_ErrorManager *error,
3395  OP_Node *src);
3396 
3397  /// Must be implemented to associate this node to a viewer state.
3398  /// @parm default_state_name should be set with the viewer state type name.
3399  /// OP_Node implementation first looks for a 'viewerstate' node string
3400  /// parameter. The parameter can be added as a spare parameter to any node.
3401  /// If the node is an HDA it can define a default state section.
3402  /// Otherwise, the operator name is returned as a default state name.
3403  virtual void getDefaultState(UT_String &default_state_name);
3404 
3405  // If this node sets a context option to a specific value, we can clear
3406  // this option dependency for this node (and its outputs), because we
3407  // know that changing this option value past this node won't affect the
3408  // cooking of our input nodes, even if they use this context option. One
3409  // exception to this is if this node sets the context option as a
3410  // function of the option value handed to it. This exception is dealt with
3411  // when transferring option dependencies from our inputs to this node.
3412  //
3413  // Another exception is when the context used to cook this node has a
3414  // non-default (i.e. set by a node) value for the option. Because our
3415  // context option change may get "popped" by a node higher up the chain,
3416  // we must assume that nodes above this "pop" node depend on this option
3417  // set by one of our outputs, so we need to recook when that node changes
3418  // option value (even though we overwrite it). This isn't a problem when
3419  // the option is set to a default value because dependencies on default
3420  // values are tracked by micro nodes, so changing the default will force
3421  // a recook from the top of the chain. Testing for this case is why we
3422  // need to be passed the context passed to this nodes cook method.
3423  void clearInputContextOptionDepIfSafe(
3424  const UT_StringHolder &opt,
3425  const OP_Context &context);
3427  // CHOP Transform Tracks
3428  virtual bool hasTransformTracks() const { return false; }
3429  virtual bool evaluateTransformTracks( OP_Context &context, OP_EvaluateTransformTracksArgs &args ) { return false; }
3430  virtual bool evaluateTransformTracksTargets( OP_Context &context, OP_NodeList &nodes, OP_Node *caller) { return false; }
3431 
3432 
3433 
3434  const UT_StringHolder &getOriginalOperatorName() const;
3435  void setOriginalOperatorName(const UT_StringHolder & optype);
3436 
3437  /// Get the op table name and the op name concatenated together to get a
3438  /// unique name.
3439  /// Returns full name with table, including namespace and version tags
3440  /// if there are any, eg "artistA::table/op::2.0"
3441  void getOriginalOperatorTableAndName(UT_WorkBuffer &name) const;
3442  void getOriginalOperatorTableAndName(UT_String &name) const;
3443 
3444 
3445 protected:
3446 
3447  OP_Node(OP_Network *parent, const char *name, OP_Operator *entry);
3448  ~OP_Node() override;
3449 
3450  /// Implement the method from PRM_ParmOwner
3451  void doGetFullPath(UT_WorkBuffer &str) const override;
3452 
3453  /// Retrieve a list of the local variables visible to this OP_Node.
3454  /// This list is unsorted and may contain duplicates.
3455  virtual void buildLocalVarNames(UT_StringArray &out_vars);
3456 
3458  const UT_StringRef &function) const override;
3459 
3460  /// Resolves any inputs for which the names were not found during
3461  /// actual loading.
3462  void resolveUnresolvedLoadedInputs();
3463 
3464  /// Called when loadNetwork finishes loading the whole parent network of
3465  /// this node.
3466  void finishedLoadingParentNetwork();
3467 
3468  void setNewParent( OP_Network *new_parent );
3469 
3470  static void bumpNameSerialIndex();
3471 
3472  /// @{
3473  /// Methods to disallow node deletion during the execution of a script.
3474  void beginScriptBlockingDel()
3475  { myScriptsBlockingDelCount += 1; }
3476  void endScriptBlockingDel()
3477  { myScriptsBlockingDelCount -= 1; }
3478  /// @}
3479 
3480  void setLegacyConnectingInputIndex(OP_InputIdx index)
3481  { myLegacyConnectingInputIndex = index; }
3482 
3483  // All external references must be removed by the time this function
3484  // returns!
3485  virtual void clearAndDestroy();
3486 
3487  // invalidate any cached data
3488  virtual void clearCache();
3489 
3490  void clearInterruptedImpl(bool allow_recook);
3491 
3492  // "cookMe" is where the actual work is done.
3493  // The error is returned (OP_ERR_NONE on success).
3494  virtual OP_ERROR cookMe(OP_Context &context) = 0;
3495 
3496  // "bypassMe" is used to cook the op when the bypass flag is set.
3497  // The copied_input parameter should be set to indicate which input was
3498  // copied. Use -1 if no input was copied.
3499  // The error is returned (OP_ERR_NONE on success).
3500  virtual OP_ERROR bypassMe(OP_Context &context, int &copied_input) = 0;
3501 
3502  // The following two functions are called from evaluateAllParms() so that
3503  // subclasses may hook into it to do some work before and after evaluating
3504  // all the parameters.
3505  virtual void doOverridePreCook() { }
3506  virtual void doOverridePostCook() { }
3507 
3508  // These "serial" numbers are used for keeping track of how many sources
3509  // are accessing us. Only call getSourceCount() when locked inside
3510  // getCookLock()!
3511  int getSourceCount() const;
3512  virtual int bumpSourceCount(int d);
3513 
3514  // This is what you should override to do your own OP specific cooking.
3515  // This should not be called other than from pubCookInputGroups.
3516  virtual OP_ERROR cookInputGroups(OP_Context &context, int alone = 0);
3517 
3518  // I/O methods
3519  virtual OP_ERROR saveIntrinsic(std::ostream &os,
3520  const OP_SaveFlags &flags);
3521  virtual OP_ERROR save(std::ostream &os, const OP_SaveFlags &flags,
3522  const char *path_prefix = "",
3523  const UT_StringHolder &name_override = UT_StringHolder());
3524  OP_ERROR saveUserDataPacket(std::ostream &os,
3525  const char *path_prefix,
3526  const UT_StringHolder &node_name);
3527 
3528  bool loadIntrinsicParentUneditable(
3529  UT_IStream &is,
3530  const char *path = nullptr);
3531  bool loadIntrinsic(
3532  UT_IStream &is,
3533  const char *path = nullptr);
3534  virtual bool loadPacket(UT_IStream &is, short class_id,
3535  short sig, const char *path=nullptr);
3536  virtual bool loadPacket(UT_IStream &is, const char *token,
3537  const char *path=nullptr);
3538  virtual bool load(UT_IStream &is,
3539  const char *ext="",
3540  const char *path = nullptr);
3541 
3542  // load only things that that an uneditable parent deems uneditable, e.g.
3543  // input/output connections. This is so that it can be matched to the OTL
3544  // rather than the editable contents of a node.
3545  bool loadParentUneditable(UT_IStream &is,
3546  const char *ext="",
3547  const char *path = nullptr);
3548 
3549  // this called when the entire network is done loading
3550  virtual void loadStart();
3551  virtual void loadFinished();
3552 
3553  // Loads the OTL_CONTENTS_SECTION for our OTL definition, if it exists,
3554  // using the syncContents method.
3555  void loadContentsSection();
3556 
3557  // This is a dummy virtual that just exists to be overridden by
3558  // OP_Network. See that class for more description.
3559  virtual bool syncContents(UT_IStream &is);
3560 
3561  /// Sets the flag idicating if the node is synced (matched) to the HDA.
3562  void setMatchesOTLDefinition(int matches);
3563 
3564  virtual const char *getFileExtension(int binary) const = 0;
3565  virtual const char *getDataFileExtension(int binary) const;
3566 
3567  /// This will set the time dependent flag based on parms, inputs and/or
3568  /// extra (non-graph) inputs. This can be overridden by subclasses to have
3569  /// more control over a node's time dependent flag by forcibly calling the
3570  /// bass class method with false for these parameters.
3571  ///
3572  /// @param do_parms Controls whether this node should become time dependent
3573  /// if any of its own cooking parameters are time dependent.
3574  /// @param do_inputs Controls whether the node should become time dependent
3575  /// if any of its used inputs are time dependent
3576  /// @param do_extras Controls if this node should become time dependent if
3577  /// any of the "extra" inputs (see
3578  /// OP_Node::addExtraInput()) nodes are time dependent.
3579  /// These extra inputs typically nodes referenced by the
3580  /// expressions on this node's parameters.
3581  virtual void checkTimeDependencies(int do_parms=1,
3582  int do_inputs=1,
3583  int do_extras=1);
3584  // This will gather context option dependencies based on parms,
3585  // inputs and extra (non-graph) inputs. These dependencies are
3586  // applied to the data micro node and the node itself.
3587  virtual void checkContextOptionDependencies(int do_parms);
3588 
3589  // To allow our sub-classes to send events, we make this protected.
3590  void sendEvent(OP_EventType type, void *data=nullptr);
3591 
3592  // haveSeenDataModification() can be used by sub-classes to decide if they
3593  // need to respond to a particular modification notice.
3594  int haveSeenDataModification(exint modification_id);
3595 
3596  // If you sub-class propagateModification, then be sure to call this
3597  // OP_Node base class method *last*.
3598  //
3599  // This routine will return TRUE if the modification is a new one for this
3600  // node. FALSE will be returned if the modification has been seen before.
3601  //
3602  // Note that "by_whom" is the immediate input node that caused the
3603  // propagation to "this" node.
3604  virtual int propagateModification(OP_Node *by_whom,
3605  OP_EventType reason,
3606  int parm_index,
3607  OP_PropagateData &prop_data);
3608 
3609  // Use this to obtain the cook cache.
3610  // @pre The caller has locked myCookLock if it is currently being cooked.
3611  OP_Cache * getCookCache() { return &myCache; }
3612 
3613  static void cmd_locate(CMD_Args &);
3614 
3615  virtual void saveFlagsForUndo();
3616  void saveForUndoLayout();
3617 
3618  static void saveForUndoDelete(OP_NodeList &nodes);
3619 
3620  /// Clears all cook dependencies (i.e., items that may cause it to cook)
3621  void clearDependency();
3622 
3623  /// This function will dirty our data if the given time is different from
3624  /// our last cooked time.
3625  ///
3626  /// This function is normally called from cook() but subclasses can prevent
3627  /// this with flags().setClearDependency(false). In that case, subclasses
3628  /// are responsible for calling this function at the appropriate time. This
3629  /// is primarily for nodes which cache their data across time. In that
3630  /// case, if they did _not_ reuse their cached data, then
3631  /// dirtyForTimeChange() needs to be called.
3632  ///
3633  /// @returns true if node was dirtied, false otherwise.
3634  bool dirtyForTimeChange(fpreal t)
3635  {
3636  if (isCookedTime(t))
3637  return false;
3638 
3639  OP_DataMicroNode &dm = dataMicroNode();
3640  OP_DataMicroNode &pm = parmListMicroNode();
3641  dm.setDirty(true);
3642  if (&dm != &pm && pm.isTimeDependent())
3643  pm.setDirty(true);
3644 
3645  return true;
3646  }
3647 
3648  // clone dependencies from the proxy. proxy is no longer valid
3649  // after the clone!
3650  virtual void cloneFromProxyRefNode( OP_Network *proxy );
3651  // clone a new proxy node. this node is no longer valid after this!
3652  virtual OP_Network * cloneToProxyRefNode();
3653  void stealDependents( OP_Node *other );
3654 
3655  bool hasOpDependents()
3656  { return !myOpDependents.isEmpty(); }
3657  virtual int hasProxyRefNodes() const
3658  { return 0; }
3659  virtual void moveProxyRefNodes( OP_Network * /*dest */ ) { }
3660  void clearOpReferences();
3661  virtual void rebuildOpDependents( bool proxy_only );
3662 
3663  /// removeOpDependent() returns the number of dependents removed
3664  virtual int removeOpDependent(
3665  int op_id, const PRM_RefId &ref_id,
3667  virtual int removeOpDependent(
3668  int op_id, OP_InterestType mask = OP_INTEREST_ALL );
3669 
3670  // new method for dependencies: use the PRM_TYPE_OP_REF_*
3671  // in your parm template to add your dependency.
3672  // override this to do special cases, make sure you call the base class
3673  // first before adding your own dependencies!
3674  void buildOpDependencies() override;
3676  CH_Channel *ch,
3677  CH_CHANGE_TYPE reason) override;
3678 
3679  void notifyOpDependents( OP_InterestType interest,
3680  bool recurse );
3681  virtual void moveDependencies( OP_Node *from_node );
3682  // Two functions for notifying dependent nodes of name changes. The
3683  // non-virtual function is the one that should be called to do the
3684  // update. It calls the virtual function to do the actual updating,
3685  // and generate a list of dependent nodes that were changed. Then it
3686  // forces a recook on the changed nodes.
3687  void notifyRenameDependents( const UT_String &full_from );
3688  virtual void notifyRenameDependents( const UT_String &full_from,
3689  OP_NodeList &cook_nodes );
3690  // Two functions for notifying referencing nodes of name changes. The
3691  // non-virtual function is the one that should be called to do the
3692  // update. It calls the virtual function to do the actual updating,
3693  // and generate a list of dependent nodes that were changed. Then it
3694  // forces a recook on the changed nodes.
3695  void notifyRenameReferences( const UT_String &full_from );
3696  virtual void notifyRenameReferences( const UT_String &full_from,
3697  OP_NodeList &cook_nodes );
3698  // this method is called to alert this op that its dependency has
3699  // changed. if it's a name interest, then the old full path is given
3700  virtual void handleOpDependency( int referenced_op_id,
3701  const OP_Dependency &op_dep,
3702  OP_InterestType interest_type,
3703  bool &need_cook,
3704  const char *old_fullpath,
3705  const char *old_cwd,
3706  const char *old_chan_name );
3707  virtual void buildParmDependency( int parm_index );
3708 
3709  void addOpNameReference(
3710  const PRM_RefId &ref_id, const UT_String &op_path,
3712  // chan_name must be real channel name not an alias
3713  void addChannelNameReference(
3714  const PRM_RefId &ref_id,
3715  const UT_StringRef &op_path,
3716  const UT_StringRef &chan_name,
3718 
3719  OP_Node *getNodeOrCreateProxy(const UT_StringRef &op_path);
3720 
3721  void addOpReference( const PRM_RefId &ref_id, OP_Node *node,
3722  const PRM_RefId &source_ref_id,
3724 
3725  void removeOpReference(
3726  const PRM_RefId &ref_id,
3728  void removeOpReference(
3729  const PRM_RefId &ref_id,
3730  int op_id,
3732 
3733  /// This function takes the given parm string value containing an op path
3734  /// and does a search and replace given the old and new op paths.
3735  ///
3736  /// value_str - the old parm value to modify
3737  /// new_fullpath - the new path value to change to
3738  /// old_fullpath - the old path that needs changing
3739  /// old_cwd - the old path that the parm value was relative to
3740  /// new_cwd - the new path that the parm value is to be relative to
3741  ///
3742  /// The reason for old_cwd & new_cwd is when collapsing a node into a
3743  /// subnet. We need to figure out the new path references of the collapsed
3744  /// subnet since it has changed location. We match using the old_cwd but
3745  /// take the new path relative to new_cwd. Note that in this situation,
3746  /// old_fullpath is the same as new_fullpath.
3747  bool changeOpPathRef( UT_String &value_str,
3748  const char *new_fullpath,
3749  const char *old_fullpath,
3750  const char *old_cwd,
3751  const char *new_cwd );
3752 
3753  // handy functions for dealing with string parms that can have the
3754  // op:/path[frame] syntax
3755  static bool getStringParmOpPath(
3756  PRM_Parm &parm, int vi, UT_String &oppath,
3757  int thread );
3758  void handleStringParmOpPathDependency(
3759  int parm_index, int vi,
3760  const char *new_fullpath,
3761  const char *old_fullpath, const char *old_cwd );
3762 
3763  // Only OP_Network should call notifyNodeDeletion()
3764  void notifyNodeDeletion();
3765 
3766  // Only notifyNodeDeletion() should call nodeDeleted().
3767  // nodeDeleted() - gets called every time a node is deleted
3768  virtual void nodeDeleted(OP_Node *op, int propagate=1);
3769 
3770  void startCookTimer(const OP_Context &context);
3771  void stopCookTimer(const OP_Context &context);
3772 
3773  virtual const char *getCookTimerLabel(const OP_Context &context) const;
3774 
3775  // Overrides permission errors so that we don't have problems when cooking.
3776  void permissionError(const char *chname = nullptr) override;
3777 
3778  // Add an error for the invalid input given by input_idx
3779  void addInputError(OP_InputIdx input_idx);
3780 
3781  // Add an error for the given node having failed to load.
3782  void addInputNodeError(OP_Node *src);
3783 
3784 protected:
3785  /// This function is currently only used by VOPs. It checks if an input
3786  /// on the subnet is connected inside the subnet. The default implementation
3787  /// here simply returns false to preserve existing behaviour for all other
3788  /// contexts.
3789  virtual bool isInputConnectedInsideSubnet(
3790  OP_InputIdx input_idx) const;
3791  virtual bool isNamedInputConnectedInsideSubnet(
3792  const OP_ConnectorId& input_name) const;
3794  // notifier when this node is unlocked
3795  virtual void nodeUnlocked() { ; }
3796 
3797  // These functions must be used with care!
3798  virtual void setUniqueId(int id);
3799  void changeOpDependentUniqueId( int old_id, int new_id );
3800  void changeOpReferenceUniqueId( int old_id, int new_id );
3801  virtual void clearUniqueId();
3802 
3803  void setAllowBuildDependencies( int yesno )
3804  { myAllowBuildDependencies = yesno; }
3805  int allowBuildDependencies() const
3806  { return myAllowBuildDependencies; }
3807 
3808  /// Evaluate all parameters for this operator. This is used for scripted
3809  /// Ops to make sure that our dependencies get set up properly.
3810  void evaluateAllParms(fpreal t);
3811 
3812  /// Override and assign any external (file) references to the reflist,
3813  /// and if nodelist is non-null, the full pathname of the node with the
3814  /// reference.
3815  virtual void getMyExternalReferences(
3816  UT_StringArray &reflist,
3817  UT_StringArray *nodelist = nullptr,
3818  bool collapse = false,
3819  bool check_missing = false,
3820  bool show_missing_only=false);
3821 
3822  void getExternalFiles(UT_StringArray &files,
3823  const char *stringparm,
3824  int framestart, int frameend,
3825  bool collapse,
3826  bool check_missing,
3827  bool show_only_missing,
3828  UT_KnownPath path);
3829 
3830  /// Rather than overloading the descriptive name, you can instead
3831  /// just provide a parameter name that will be evaluated to
3832  /// become the descriptive name.
3833  virtual void getDescriptiveParmName(UT_String &str) const;
3834 
3835  /// Additional information that should be provided at the network
3836  /// level in addition to the name.
3837  /// By default will inspect the getDescriptiveParmName.
3838  virtual void getDescriptiveName(UT_String &str) const;
3839 
3840  /// Marks our cached descriptive name as dirty.
3841  void dirtyDescriptiveNameCache();
3842 
3843  /// Return true if it is safe at this time to destroy this node.
3844  virtual bool canDestroyNode();
3845 
3846  /// Override this to return true in an operator type that wants its
3847  /// cooked data to rely on all its parameter values but doesn't actually
3848  /// evaluate any parameters in its cook function (the prototypical
3849  /// example of this is SHOPs).
3850  virtual bool cookedDataUsesAllParameters() const
3851  { return false; }
3852  /// If the cook method relies on the base class cook to evaluate parameters
3853  /// (like in SHOPs), we need to trap the errors during this evaluation.
3854  virtual bool cookedDataNeedsErrors() const
3855  { return false; }
3856  /// If this node should be cooked for any output connected to it, return
3857  /// true here. Otherwise we only cook a node if something is connected to
3858  /// it's primary output. This does not let the node cook differently for
3859  /// each output, since the cook method doesn't know what output is being
3860  /// cooked for. So this should only be used if the cook is unaffected by
3861  /// the specific connected output.
3862  virtual bool cookDataForAnyOutput() const
3863  { return false; }
3864 
3865  // Returns true if we are running our creation script, or any parent
3866  // node of us is running its creation script.
3867  bool getIsRunningInCreateScript() const;
3868 
3869  /// This method is called whenever something in the network changes
3870  /// that may have an impact on the representative node this network may
3871  /// have. It is used at this level to notify parents, and at the OBJ level
3872  /// to actually refresh the representative object.
3873  virtual void refreshRepresentativeNode(OP_Node &changed_child);
3874 
3875  /// Sets up the inputs and outputs after all nodes have been loading
3876  /// from file (in case it needs its children to determine inputs/oututs).
3877  virtual void setupConnectorsAfterLoad();
3878 
3879  /// Converts opdef and oplib format paths from opdef:nodepath to
3880  /// opdef:tablename/optype.
3882  UT_String &str) const override;
3883 
3884  bool isCookedTime(fpreal t) const
3885  {
3886  return dataMicroNodeConst()
3887  .isEqualToLastUpdateTime(t);
3888  }
3889 
3890  /// Subclasses should override this to dump extra micronodes that they own
3891  /// for debugging purposes.
3892  virtual void dumpMicroNodes(
3893  std::ostream &os,
3894  bool as_DOT,
3895  int indent_level) const;
3898  UT_TokenString myHashCode; // Generates a unique
3899  UT_TokenString myParmHashCode; // parameters & inputs.
3900  int myLastGroupMask;
3901  OP_VERSION myHashVersion;
3902  fpreal myHashTime;
3903  int myParmLastGroupMask;
3904  OP_VERSION myParmHashVersion;
3905  fpreal myParmHashTime;
3906  UT_String mySyncErrors;
3907  OP_ERROR mySyncErrorLevel;
3908  int mySyncDepth;
3909 
3910  /// Deletes an input completely if it is disconnected. If the input
3911  /// is connected, does nothing.
3912  void deleteInput(OP_InputIdx idx);
3913  void deleteInput(const OP_ConnectorId& input_name);
3914 
3915  /// Performs actual removal from the member input array.
3916  virtual void doDeleteInput(OP_InputIdx idx);
3917 
3918  /// Update the error severity of this node.
3919  void updateErrorSeverity();
3921  /// Overriden in VOPs.
3922  virtual void onInputAllocated(OP_Input* new_input,
3923  OP_InputIdx index) { }
3924 
3925  /// Debug method for checking connector consistency.
3926  void checkConnectorsConsistency();
3927 
3928  /// Use these to collect all inputs/outputs in cases where they will
3929  /// need to be modified.
3930  void gatherInputs(UT_Array<OP_InputPair> &input_pairs);
3931  void gatherOutputs(UT_Array<OP_OutputPair> &output_pairs);
3932 
3933  void renameInput(OP_Input* input, int new_id);
3934 
3935  void notifyChannelOpDependents(PRM_Parm * in_parm, int vecid);
3936  // Compiled hash code
3937  uint32 myCompHash;
3938 
3939 private:
3940 
3941  void updateSpareParmTemplates(
3942  PRM_Template *newtemplates,
3943  bool leavedefaultsunchanged) override;
3944 
3945  bool doDebugConsistencyCheck();
3946  void createCollection( OP_Operator *entry );
3947 
3948  // these are extra private. only to be called from saveIntrinsic and save
3949  // respectively
3950  OP_ERROR saveIntrinsicError();
3951  OP_ERROR saveError();
3952  OP_ERROR saveGroupMemberships(std::ostream &os,
3953  const OP_SaveFlags &flags,
3954  const char *path_prefix);
3955  bool loadGroupMemberships(UT_IStream &is,
3956  const char*path = nullptr);
3957 
3958  ///Make a note of which network box we're in
3959  OP_ERROR saveNetworkBox(std::ostream &os,
3960  const OP_SaveFlags &flags,
3961  const char *path_prefix);
3962 
3963  ///Put ourselves into a network box if we saved ourselves as being in one
3964  bool loadNetworkBox(UT_IStream &is,
3965  const char *path = nullptr);
3966 
3967  bool loadNodeFlags(UT_IStream &is, const char *path);
3968 
3969  void saveForUndoComment();
3970  void saveForUndoDelScript();
3971 
3972  UT_BitArray &getGroups() { return myGroups; }
3973  const UT_BitArray &getGroups() const { return myGroups; }
3974  // Only OP_Input should call setOutput() and delOutput() functions.
3975  bool setOutput(OP_NetworkBoxItem *item,
3976  OP_OutputIdx output_idx);
3977  bool delOutput(OP_NetworkBoxItem *item,
3978  OP_OutputIdx output_idx);
3979  bool setNamedOutput(OP_NetworkBoxItem *item,
3980  const OP_ConnectorId& output_name);
3981  bool delNamedOutput(OP_NetworkBoxItem *item,
3982  const OP_ConnectorId& output_name);
3983  OP_Output *getOutput(OP_OutputIdx output_idx);
3984  const OP_Output *getOutput(OP_OutputIdx output_idx) const;
3985  bool isOutputIdxValid(OP_OutputIdx output_idx) const;
3986  bool isOutputIdxWithinMax(OP_OutputIdx output_idx) const;
3987 
3988  void setInterrupted();
3989 
3990  int findAncestor(const OP_Node *node) const;
3991  int findDataAncestor(const OP_Node *node) const;
3992  void clearRecursionBit() const;
3993 
3994  void initializeExpressions() const;
3995  void clearInputs();
3996  void clearOutputs();
3997 
3998  PRM_ParmMicroNode *createParmMicroNodes(PRM_Parm &parm) const override;
3999 
4000  static bool getMicroNodesFromRef(
4001  const OP_InterestRef &ref,
4002  DEP_MicroNodeList &micronodes,
4003  bool data_target);
4004  static void traverseInputsAddInputs(
4005  opNodeOutput &output,
4007  UT_Set<opNodeOutput> &visited,
4008  TraverseOptions opts,
4009  OP_InterestType extra_interest_mask,
4010  bool include_parmlist);
4011 
4012  // ref_chan_name must be the real channel name and not an alias
4013  int addOpDependent( int op_id,
4014  const PRM_RefId &source_ref,
4015  const PRM_RefId &ref_id,
4017 
4018  void updateRenameDependent( OP_Node *dependent,
4019  const char *old_cwd,
4020  OP_NodeList &cook_nodes );
4021 
4022  /// Trigger notifications when the given input has changed.
4023  /// If input has no value, then it notifies as if all inputs changed.
4024  void notifyInputOpDependents(OP_InputIdx input);
4025 
4026  void getExistingOpReferencesImpl(
4027  OP_NodeList &refs, bool include_descendants) const;
4028  void getExistingOpDependentsImpl(
4029  OP_NodeList &deps, bool include_descendants) const;
4030 
4031  void buildScriptOpDependencies();
4032  void changeScriptOpRef( const char *new_fullpath,
4033  const char *old_path,
4034  const char *old_cwd );
4035  static void changeScriptCB( UT_String &str,
4036  const char *token_start,
4037  const char *&ch, void *userdata );
4038 
4039  // Go through and find all nodes which have time interest and requires
4040  // cooking. If the update_cook flag is true, then we will call force
4041  // recook on the node as long as node != this. 'interests' if non-null,
4042  // stores the path of nodes that has time interest and will set the time
4043  // interest cook flag on those nodes.
4044  bool findTimeInterests(const OP_Context &context, OP_Node *node,
4045  bool update_cook,
4046  OP_NodeCycleDetect &cycle,
4047  OP_NodeList *interests = nullptr);
4048 
4049  /// Helper method for 'completePath()'
4050  bool attemptPrefixMatch(const OP_NetworkBoxItem *item,
4051  char *childpref, int childpreflen,
4052  UT_String &maxprefix) const;
4053 
4054  /// Helper for propagateModification()
4055  void findUsedDataInterests(OP_NodeList &nodes, OP_Node *op);
4056 
4057  /// Helper function for the setGlobal*Param functions. This function
4058  /// interprets the return value from CH_Manager::setGlobal*Param.
4059  bool internalSetGlobalParam(const char *param,
4060  int setreturned,
4061  bool *warned);
4062 
4063  bool internalSetPicked(bool on_off,
4064  bool propagate_parent_event,
4065  bool edit);
4066 
4067  OP_ERROR internalCookInput(OP_Context &context,
4068  OP_InputIdx input_idx,
4069  OP_Node &input_node);
4070 
4071  virtual void removeInputFromMapping(OP_InputIdx idx);
4072  void removeOutputFromMapping(OP_OutputIdx idx);
4073 
4074  void generateConnectorUniqueId(OP_ConnectorId& id_out);
4075  OP_Output *getOrCreateOutput(OP_OutputIdx array_index, bool create,
4076  int id_to_use);
4077 
4078  uint32 computeCompiledHash() const;
4079 
4080  // Adds a warning to the current error manager if this node has been
4081  // marked as deprecated.
4082  void addDeprecationWarningsIfAny();
4083 
4084  // Find an unused connectorId to assign to the next input/output
4085  int getConnectorNextId() const;
4086 
4087  bool computeCompiledStatus() const;
4088 
4089  bool isOperatorThreadSafe() const;
4090 
4091  void internalSyncDelayedOTL();
4092 
4093 public:
4094  /// SOP, OBJ, and SOP Solver DOP nodes can be a selection owner,
4095  /// but other nodes cannot.
4096  /// This replaces the previous inheritance from SOP_SelectionOwner.
4097  virtual bool isSelectionOwnerType() const
4098  { return false; }
4099 
4100  /// Add many extra inputs in one call. See addExtraInput
4101  void addExtraInputs(const UT_Array<OP_InterestRef> &source_refs);
4102  void addExtraInputs(const DEP_MicroNodeList &deps);
4103 
4104  static void addExtraInputs(
4105  const UT_Array<OP_InterestRef> &target_refs,
4106  const UT_Array<OP_InterestRef> &source_refs);
4107 
4108  /// Optimized version of addExtraInput that doesn't create OP_InterestRef
4109  static void addExtraInput(OP_Node &source, int source_pi, int source_vi,
4110  OP_Node &target, int target_pi, int target_vi
4111  );
4112 
4113  static bool getMicroNodesFromRef(
4115  DEP_MicroNodeList &micronodes, bool data_target);
4116 
4117  static bool getMicroNodesFromRef(
4118  OP_Node &op, int parm_i, int vec_i,
4119  DEP_MicroNodeList &micronodes);
4120 
4121  void addExtraInput(OP_Node *op, OP_InterestType type, DEP_MicroNodeList &sources_cache);
4122 
4123  /// Optimized version of addExtraInput that doesn't create OP_InterestRef
4124  static void addExtraInput(OP_Node &source, PRM_Parm &source_parm, int source_vi,
4125  OP_Node &target, PRM_Parm &target_parm, int target_vi
4126  );
4127 
4128  void addExtraInputs(const UT_Array<OP_Node*> &nodes, OP_InterestType type, DEP_MicroNodeList &sources_cache);
4129 
4130  virtual bool isUsingCurrentFrameForVexTransformContext() const {return true;}
4131 private:
4132  OP_Cache myCache;
4133 
4134  OP_ERROR myLastErrorSeverity;
4135  exint myLastErrorVersion;
4136  OP_Network *myParent;
4137  OP_Network *myRootCompiledParent;
4138  UT_ValArray<OP_Input *> myInputs;
4139  // This is a map of names to inputs.
4140  OP_ConnectorInputMap myInputsMap;
4141  mutable UT_BitArray myUsedInputs;
4144  myOutputs;
4146  mySpareOutputs;
4147  /// Map from names to outputs, including spare outputs.
4148  OP_ConnectorOutputMap myOutputsMap;
4149 
4150  // Default data micro node.
4151  OP_DataMicroNode myDataMicroNode;
4152  DEP_MicroNode myFlagMicroNode;
4153  UT_Map<char, DEP_MicroNode> myIndividualFlagMicroNodes;
4154  UT_StringArray myClearInputContextOptionDeps;
4155 
4156  // Event micronodes for OP events
4157  using MicroNodePtr = UT_UniquePtr<DEP_MicroNode>;
4158  using EventMicroNodesPtr = UT_UniquePtr<MicroNodePtr[]>;
4159  EventMicroNodesPtr myEventMicroNodes;
4160 
4161  UT_String myComment;
4162  UT_String myDelScript;
4163  UT_String myCreatorState;
4164  UT_BitArray myGroups;
4165  OP_Value myEventValue;
4166  fpreal myPosX;
4167  fpreal myPosY;
4168  exint myCookCount;
4169  exint myCacheMisses = 0;
4170  SYS_AtomicInt32 mySourceCount;
4171  int myBlockModify;
4172  int myScriptsBlockingDelCount;
4173  int myUniqueId;
4174  int myNextIdOverride;
4175  unsigned myActiveInputIndex;
4176  // Indicates which input is currently being connected,
4177  // -1 if none.
4178  OP_InputIdx myLegacyConnectingInputIndex;
4179 
4180  bool myAutoscope;
4181 
4182  fpreal myCookDuration; // time spent cooking
4183  unsigned int myRenameConflict : 1,
4184  myCookedForRender : 1,
4185  myModifyWaiting : 1,
4186  myBuiltExplicitly : 1,
4187  myAllowBuildDependencies : 1,
4188  myBeingDeleted : 1,
4189  myRunningCreateScript : 1,
4190  myRunningDelScript : 1,
4191  myAlreadyRunDelScript : 1,
4192  myMatchesOTLDefinition : 1,
4193  myLoadCookedDataError : 1,
4194  myBuiltHashCode : 1,
4195  myIsProxyRefNode : 1,
4196  myInhibitInputConsolidation : 1,
4197  // Tracks if we have engaged our local variables, true from the
4198  // SOP_Node::setupLocalVars() until the SOP_Node::resetLocalVarRefs(). Any
4199  // attempt to evaluate local vars outside of here will redflag. This
4200  // flag is here instead of SOP_Node so that PI_OpHandleLink has access
4201  // to temporarily enable it.
4202  myLocalVarActive : 1,
4203  myDelaySyncOTL : 1,
4204  mySyncingDelayedOTL : 1;
4205 
4206  mutable bool myRecursionFlag;
4207 
4208  // Tracks the nesting level of the modification propagation chains
4209  static int thePropagateLevel;
4210 
4211  // ops that we have a reference to
4212  OP_ReferenceList myOpReferences;
4213  // ops that depend on us
4214  OP_DependencyList myOpDependents;
4215 
4216  // bundles that we have a reference to
4217  OP_BundleReferences myBundleRefs;
4218 
4219  // Locking for cooking and adding extra inputs
4220  mutable OP_CookLock myCookLock;
4221 
4222  // Arbitrary string data that users can attach to nodes that gets saved
4223  // with the hip file.
4224  UT_Options myUserData;
4225  // Cached value for the node shape.
4226  UT_StringHolder myNodeShape;
4227 
4228  // Arbitrary blind data that users can attach to nodes. These do not get
4229  // saved with the hip file.
4230  UT_StringMap<UT_SharedPtr<void> > myBlindData;
4231 
4232  // Arbitrary data blocks that, unlike blind data, are saved with the node.
4233  // This obviously implies the data must be self contained (no pointers).
4234  UT_StringMap<OP_DataBlockPtr> myDataBlocks;
4235 
4236  // Arbitrary data (in the form of Python objects) the users can attach to
4237  // nodes that does not get saved with the hip file.
4238  OP_PythonObjectCache myCachedPythonObjects;
4239 
4240  // During load, not all of our input names are known. This stores
4241  // unresolved input names until OP_Node::loadFinished() is called,
4242  // where they are resolved.
4243  UT_Array<OP_UnresolvedConnection *> *myUnresolvedInputs;
4244 
4245  OP_NodeFlags myFlags;
4246 
4247  /// Cached evaluation of the node's descriptive name.
4248  UT_StringHolder myCachedDescriptiveName;
4249  bool myCachedDescriptiveNameDirty;
4250 
4251  /// Only used during loading. Set to false initially, it is set to true
4252  /// once we load inputsNamed intrinsic section. If we do, the regular
4253  /// inputs section will then be ignored.
4254  bool myLoadedNamedInputs;
4255 
4256  /// Used for caching the compiled status of the node. Initially undefined,
4257  /// gets set on first isCompiled() call.
4258  mutable OP_CompileStatusType myCachedCompileStatus;
4259 
4260  OP_ERROR myChildErrorSeverity;
4261  int myChildErrorSeverityTimestamp;
4262 
4263  UT_StringHolder myOverriddenOperatorName;
4264 
4265 
4266  // Maintenance of node id's
4267  static int makeUniqueId(OP_Node *node);
4268 
4269  static bool *theCheckConnectionConsistency;
4270  static int theUniqueId;
4271  static int theUniqueSize;
4272  static OP_Node **theUniqueNodes;
4273  static bool theDoingBulkNotification;
4274  static OP_Node *theBulkNotificationCaller;
4276  friend class OP_Channels;
4277  friend class OP_DataMicroNode;
4278  friend class OP_EventMicroNode;
4279  friend class OP_Group;
4280  friend class OP_IndirectInput;
4281  friend class OP_Input;
4282  friend class OP_Network;
4283  friend class OP_OperatorTable;
4284  friend class OP_ParmMicroNode;
4285  friend class OP_UndoCreate;
4286  friend class OP_UndoDelete;
4287  friend class OP_UndoInput;
4288  friend class OP_UndoSpareParm;
4289  friend class OP_UndoUserData;
4291  friend class op_MicroNodeDirtied;
4292  friend class MOT_RemoteExecMessage;
4293 };
4294 
4295 // helper function
4296 // should always return a valid pointer
4298 
4299 // Link a Node to a Channel for SOP Channels
4300 OP_API void OPlinkNodeToChannel( const OP_Node *node, const CH_Channel *chp );
4302 
4303 // Replaces CH_Manager::getUniqueCollections() as it needs access to OP.
4305  const CH_ChannelList &channels,
4306  CH_CollectionList &collections );
4307 
4308 // UTformat support.
4309 static inline size_t
4310 UTformatBuffer(char *buffer, size_t buffer_size, const OP_Node &v)
4311 {
4312  UT_StringHolder s = v.getFullPath();
4313  if (!buffer)
4314  return s.length();
4315  else
4316  {
4317  size_t len = std::min(size_t(s.length()), buffer_size);
4318  ::memcpy(buffer, s.c_str(), len);
4319  return len;
4320  }
4322 
4324 {
4325 public:
4328 };
4329 
4330 #define CAST_INSTANTIATE(PREFIX) \
4331 inline static PREFIX##_Node *CAST_##PREFIX##NODE(OP_Node *op) \
4332 { \
4333  return ((op) ? (op)->castTo##PREFIX##Node() : 0); \
4334 } \
4335  \
4336 inline static const PREFIX##_Node *CAST_##PREFIX##NODE(const OP_Node *op) \
4337 { \
4338  return ((op) ? (op)->castTo##PREFIX##Node() : 0); \
4339 } \
4340 
4341 /// @anchor OP_Node_CAST_FOONODE
4342 /// These convenience functions let you do the cast without worrying if the
4343 /// underlying pointer is null or not. They aren't macros because this way we
4344 /// avoid double evaluating the op.
4345 /// CAST_OBJNODE()
4346 /// CAST_SOPNODE()
4347 /// CAST_CHOPNETNODE()
4348 /// CAST_CHOPNODE()
4349 /// CAST_ROPNODE()
4350 /// CAST_SHOPNODE()
4351 /// CAST_COPNODE()
4352 /// CAST_COP2NODE()
4353 /// CAST_COP2NETNODE()
4354 /// CAST_VOPNODE()
4355 /// CAST_VOPNETNODE()
4356 /// CAST_DOPNODE()
4357 /// CAST_TOPNODE()
4358 /// CAST_TOPNETNODE()
4359 /// CAST_LOPNODE()
4360 //@{
4362 //@}
4363 
4364 #undef CAST_INSTANTIATE
4365 
4366 // We don't want anyone to conflict with this..
4367 #undef INSTANTIATE_FINDNODE_FUNCTIONS
4368 #undef INSTANTIATE_CASTNODE_FUNCTIONS
4369 #undef INSTANTIATE_FOR_ALL_NODE_TYPES
4370 
4371 //___________________________________________________________________________
4373 /// Simple class that makes it easy to write loops that iterate over all the
4374 /// outputs from a node. The parameters are passed on to getOutputNodes.
4375 class OP_API OP_OutputIterator : private UT_SmallArray<OP_Node*>
4376 {
4378 
4379 public:
4381  const OP_Node &node,
4382  bool into_subnets = false,
4383  bool through_dots = true,
4384  OP_OutputIdx output_idx = -1)
4385  {
4386  node.getOutputNodes(*this, into_subnets, through_dots, output_idx);
4387  }
4388  struct IncludeSpareTag {};
4390  IncludeSpareTag,
4391  const OP_Node &node,
4392  bool into_subnets = false,
4393  bool through_dots = true,
4395  {
4396  node.getOutputNodesIncludeSpare(*this, into_subnets, through_dots,
4397  output_idx);
4398  }
4399 
4400  using Parent::begin;
4401  using Parent::end;
4402 
4403  using Parent::rbegin;
4404  using Parent::rend;
4405 
4406  using Parent::operator();
4407  using Parent::entries;
4408  using Parent::size;
4409 
4410  using Parent::sort;
4411 };
4413 /// Same as OP_OutputIterator, but with the iterators all swapped around so a
4414 /// range loop will go backwards (without having to mess with reverse adaptors)
4415 class OP_API OP_OutputReversedIterator : private UT_SmallArray<OP_Node*>
4416 {
4418 
4419 public:
4421  const OP_Node &node,
4422  bool into_subnets = false,
4423  bool through_dots = true,
4424  OP_OutputIdx output_idx = -1)
4425  {
4426  node.getOutputNodes(*this, into_subnets, through_dots, output_idx);
4427  }
4428  struct IncludeSpareTag {};
4430  IncludeSpareTag,
4431  const OP_Node &node,
4432  bool into_subnets = false,
4433  bool through_dots = true,
4435  {
4436  node.getOutputNodesIncludeSpare(*this, into_subnets, through_dots,
4437  output_idx);
4438  }
4440  const_reverse_iterator begin() const { return Parent::rbegin(); }
4441  const_reverse_iterator end() const { return Parent::rend(); }
4442  reverse_iterator begin() { return Parent::rbegin(); }
4443  reverse_iterator end() { return Parent::rend(); }
4445  const_iterator rbegin() const { return Parent::begin(); }
4446  const_iterator rend() const { return Parent::end(); }
4447  iterator rbegin() { return Parent::begin(); }
4448  iterator rend() { return Parent::end(); }
4449 
4450  using Parent::operator();
4451  using Parent::entries;
4452  using Parent::size;
4453 
4454  using Parent::sort;
4455 };
4456 
4457 /// Safe reference to an OP node
4460 public:
4461  OP_NodeId() { myId = OP_INVALID_NODE_ID; }
4462  OP_NodeId(const OP_Node *node) { *this = node; }
4463  OP_NodeId(const OP_NodeId &id) { myId = id.myId; }
4464 
4465  bool isValid() const
4466  { return (OP_Node::lookupNode(myId) != nullptr); }
4467 
4468  OP_Node *ptr() { return OP_Node::lookupNode(myId); }
4469  const OP_Node *ptr() const { return OP_Node::lookupNode(myId); }
4471  void clear() { myId = OP_INVALID_NODE_ID; }
4472 
4473  void operator=(const OP_Node *node)
4474  { myId = node ? node->getUniqueId() : OP_INVALID_NODE_ID; }
4475 
4476  bool operator==(const OP_Node *node) const
4477  {
4478  const int id = node ? node->getUniqueId() : OP_INVALID_NODE_ID;
4479  return id == myId;
4480  }
4481  bool operator!=(const OP_Node *node) const
4482  {
4483  const int id = node ? node->getUniqueId() : OP_INVALID_NODE_ID;
4484  return id != myId;
4485  }
4486  void setId(int id) { myId = id; }
4487 private:
4488  int myId;
4489 };
4490 
4491 #endif
OP_API const UT_StringHolder OP_USERDATA_NODESHAPE
int getUniqueId() const
Definition: OP_Node.h:777
The change type wasn't set, so it could be any of them.
Definition: OP_DataTypes.h:241
virtual void executeCommand(const char *command, std::ostream *out, std::ostream *err) const =0
typedef int(APIENTRYP RE_PFNGLXSWAPINTERVALSGIPROC)(int)
virtual bool setColor(const UT_Color &color)
void adoptFromString(UT_String &str)
short * getInput(int size) override
shared_ptr< Output > OutputPtr
A shared pointer to an Output.
Definition: Interface.h:36
GLbitfield flags
Definition: glcorearb.h:1596
#define CAST_INSTANTIATE(PREFIX)
Definition: OP_Node.h:4328
Definition: UT_Set.h:58
OP_API void OPgetUniqueCollections(const CH_ChannelList &channels, CH_CollectionList &collections)
virtual const VOP_CodeGenerator * getVopAutoCodeGenerator() const
Definition: OP_Node.h:2922
GT_API const UT_StringHolder filename
OP_InputPair(OP_Input *p, OP_ConnectorId n)
Definition: OP_Node.h:141
const PRM_Parm * myParmRef
Definition: OP_Node.h:174
GLuint GLsizei const GLchar * label
Definition: glcorearb.h:2545
virtual UT_ErrorSeverity prmCookOverrides(fpreal, int, const char *, int)
virtual OP_ItemType getItemType() const =0
Our children should implement this and return what type of item they are.
OP_ConnectorInputMap::iterator OP_ConnectorInputIter
Definition: OP_Node.h:137
UT_KnownPath
Definition: UT_KnownPath.h:14
#define SYS_DEPRECATED(__V__)
virtual void checkChannelDependencies(CH_Channel *, CH_CHANGE_TYPE)
Unsorted map container.
Definition: UT_Map.h:114
uint64 OP_VERSION
Definition: OP_Version.h:6
int64 getMemoryUsage(bool inclusive) const
std::pair< const OP_Node *, OP_OutputIdx > opNodeOutput
Definition: OP_Node.h:250
UT_String myInputName
Definition: OP_Node.h:180
OP_CompileStatusType
Definition: OP_Node.h:343
virtual int changeString(const char *from, const char *to, bool fullword)
GLboolean * data
Definition: glcorearb.h:131
OP_API void OPlinkNodeToChannel(const OP_Node *node, const CH_Channel *chp)
UT_CycleDetect< OP_Node * > OP_NodeCycleDetect
Definition: OP_Node.h:244
GT_API const UT_StringHolder time
const GLdouble * v
Definition: glcorearb.h:837
void addExplicitInput(DEP_MicroNode &inp, bool check_dup)
Methods for manipulating explicit edges.
TraverseOptions
Definition: OP_Node.h:2849
Transformation order of scales, rotates, and translates.
Definition: UT_XformOrder.h:23
GLsizei const GLfloat * value
Definition: glcorearb.h:824
const UT_StringHolder myTableName
Definition: OP_Node.h:383
const GLuint GLenum const void * binary
Definition: glcorearb.h:1924
UT_LockedRawPtr< OP_NodeList, OP_Lock > OP_LockedNodeList
Definition: OP_Node.h:247
virtual bool setItemName(const UT_StringHolder &name)=0
GLsizei const GLchar *const * path
Definition: glcorearb.h:3341
SYS_FORCE_INLINE T * SYSconst_cast(const T *foo)
Definition: SYS_Types.h:136
int OP_InputIdx
Definition: OP_DataTypes.h:184
base_iterator< const OP_Node *, false > const_reverse_iterator
Definition: UT_Array.h:1034
#define INSTANTIATE_CASTNODE_FUNCTIONS(PREFIX)
Definition: OP_Node.h:487
virtual void setXY(fpreal x, fpreal y)=0
int64 exint
Definition: SYS_Types.h:125
GLint level
Definition: glcorearb.h:108
UT_StringMap< UT_UniquePtr< PY_OpaqueObject > > OP_PythonObjectCache
Definition: OP_Node.h:249
virtual fpreal getY() const =0
virtual bool getHasTakeData() const
GLdouble s
Definition: glad.h:3009
PUGI__FN void reverse(I begin, I end)
Definition: pugixml.cpp:7458
UT_ErrorSeverity
Definition: UT_Error.h:25
virtual fpreal getX() const =0
Parameters for OP_Node::getInfoText()/OP_Node::getNodeSpecificInfoText()
OP_API const UT_StringHolder OP_USERDATA_BGIMAGES
ImageBuf OIIO_API min(Image_or_Const A, Image_or_Const B, ROI roi={}, int nthreads=0)
PUGI__FN void sort(I begin, I end, const Pred &pred)
Definition: pugixml.cpp:7550
GLint y
Definition: glcorearb.h:103
virtual OP_Network * getParentNetwork() const =0
Returns the network that is our parent.
**But if you need a result
Definition: thread.h:622
GLdouble GLdouble GLdouble q
Definition: glad.h:2445
#define UT_NULLOPT
Definition: UT_Optional.h:23
OP_ConnectorId myName
Definition: OP_Node.h:144
#define OP_INVALID_NODE_ID
Definition: OP_ItemId.h:24
virtual void clearParmDependency(int parmidx)=0
int(* OP_EditCallback)(void *data, OP_Node *src, CL_Track *track, fpreal t, fpreal value)
Definition: OP_Node.h:132
GLuint buffer
Definition: glcorearb.h:660
const char * c_str() const
Definition: UT_String.h:524
virtual UT_StringHolder evaluateDisableExpression(const PRM_Parm &prm, const UT_StringRef &function) const
OutGridT const XformOp bool bool
constexpr auto in(type t, int set) -> bool
Definition: core.h:611
int myIndex
Definition: OP_Node.h:446
virtual int findString(const char *str, bool fullword, bool usewildcards) const
std::optional< T > UT_Optional
Definition: UT_Optional.h:26
virtual bool setPicked(bool on_off, bool propagate_parent_event=true)=0
base_iterator< OP_Node *, false > reverse_iterator
Definition: UT_Array.h:1033
const OP_Node * myEvalNode
Definition: OP_Node.h:173
std::unique_ptr< T, Deleter > UT_UniquePtr
A smart pointer for unique ownership of dynamically allocated objects.
Definition: UT_UniquePtr.h:39
void setDirty(bool flag, bool allow_clear=true)
Flag accessors.
virtual void setAnyUndoFlag()
PivotSpaceT< fpreal32 > PivotSpace
Definition: UT_Matrix4.h:858
< returns > If no error
Definition: snippets.dox:2
fpreal myValue
Definition: OP_Node.h:443
virtual int64 getItemUniqueId() const =0
Functions to get hip-file-unique ids for any item type.
OP_OutputPair(OP_Output *p, OP_ConnectorId n)
Definition: OP_Node.h:149
PRM_ParmList * createObsoleteParmList() override
bool operator==(const BaseDimensions< T > &a, const BaseDimensions< Y > &b)
Definition: Dimensions.h:137
A utility class to do read-only operations on a subset of an existing string.
Definition: UT_StringView.h:40
const char * getFullPath(UT_String &str) const
Definition: PRM_ParmOwner.h:54
virtual fpreal getW() const =0
GLdouble n
Definition: glcorearb.h:2008
GLfloat f
Definition: glcorearb.h:1926
GLint GLint GLsizei GLint GLenum GLenum type
Definition: glcorearb.h:108
const UT_StringHolder myScriptDir
Definition: OP_Node.h:384
#define INSTANTIATE_FOR_ALL_NODE_TYPES(MACRO_FUNC)
This macro allows us to run another macro for all node types.
Definition: OP_Node.h:504
int mySubIndex
Definition: OP_Node.h:447
UT_ValArray< const CL_Track * > CL_TrackListC
Definition: OP_Node.h:127
reverse_iterator rbegin()
Begin iterating over the array in reverse.
Definition: UT_Array.h:1064
virtual bool triggerParmCallback(PRM_Parm *parmptr, fpreal now, int value, void *data, const UT_Options *options=nullptr)=0
CH_CHANGE_TYPE
exint length() const
GLint ref
Definition: glcorearb.h:124
Mapper that provides an HDA section name for a given shader node.
virtual const OP_DopParent * castToOpDopParent() const
Definition: OP_Node.h:2913
OP_InterestType
Definition: OP_DataTypes.h:206
std::shared_ptr< T > UT_SharedPtr
Wrapper around std::shared_ptr.
Definition: UT_SharedPtr.h:36
OP_OpTypeId myOptypeId
Definition: OP_Node.h:381
void(* OP_EventMethod)(OP_Node *caller, void *callee, OP_EventType type, void *data)
Definition: OP_Value.h:178
PXL_API const char * getName(const ColorSpace *space)
Return the name of the color space.
#define UT_ASSERT_P(ZZ)
Definition: UT_Assert.h:164
void resolveAndDeleteObsoleteParmList(PRM_ParmList *&obsolete_parms) override
OP_API const UT_StringHolder OP_USERDATA_OPMENUFILE
constexpr std::enable_if< I< type_count_base< T >::value, int >::type tuple_type_size(){return subtype_count< typename std::tuple_element< I, T >::type >::value+tuple_type_size< T, I+1 >);}template< typename T > struct type_count< T, typename std::enable_if< is_tuple_like< T >::value >::type >{static constexpr int value{tuple_type_size< T, 0 >)};};template< typename T > struct subtype_count{static constexpr int value{is_mutable_container< T >::value?expected_max_vector_size:type_count< T >::value};};template< typename T, typename Enable=void > struct type_count_min{static const int value{0};};template< typename T >struct type_count_min< T, typename std::enable_if<!is_mutable_container< T >::value &&!is_tuple_like< T >::value &&!is_wrapper< T >::value &&!is_complex< T >::value &&!std::is_void< T >::value >::type >{static constexpr int value{type_count< T >::value};};template< typename T > struct type_count_min< T, typename std::enable_if< is_complex< T >::value >::type >{static constexpr int value{1};};template< typename T >struct type_count_min< T, typename std::enable_if< is_wrapper< T >::value &&!is_complex< T >::value &&!is_tuple_like< T >::value >::type >{static constexpr int value{subtype_count_min< typename T::value_type >::value};};template< typename T, std::size_t I >constexpr typename std::enable_if< I==type_count_base< T >::value, int >::type tuple_type_size_min(){return 0;}template< typename T, std::size_t I > constexpr typename std::enable_if< I< type_count_base< T >::value, int >::type tuple_type_size_min(){return subtype_count_min< typename std::tuple_element< I, T >::type >::value+tuple_type_size_min< T, I+1 >);}template< typename T > struct type_count_min< T, typename std::enable_if< is_tuple_like< T >::value >::type >{static constexpr int value{tuple_type_size_min< T, 0 >)};};template< typename T > struct subtype_count_min{static constexpr int value{is_mutable_container< T >::value?((type_count< T >::value< expected_max_vector_size)?type_count< T >::value:0):type_count_min< T >::value};};template< typename T, typename Enable=void > struct expected_count{static const int value{0};};template< typename T >struct expected_count< T, typename std::enable_if<!is_mutable_container< T >::value &&!is_wrapper< T >::value &&!std::is_void< T >::value >::type >{static constexpr int value{1};};template< typename T > struct expected_count< T, typename std::enable_if< is_mutable_container< T >::value >::type >{static constexpr int value{expected_max_vector_size};};template< typename T >struct expected_count< T, typename std::enable_if<!is_mutable_container< T >::value &&is_wrapper< T >::value >::type >{static constexpr int value{expected_count< typename T::value_type >::value};};enum class object_category:int{char_value=1, integral_value=2, unsigned_integral=4, enumeration=6, boolean_value=8, floating_point=10, number_constructible=12, double_constructible=14, integer_constructible=16, string_assignable=23, string_constructible=24, other=45, wrapper_value=50, complex_number=60, tuple_value=70, container_value=80,};template< typename T, typename Enable=void > struct classify_object{static constexpr object_category value{object_category::other};};template< typename T >struct classify_object< T, typename std::enable_if< std::is_integral< T >::value &&!std::is_same< T, char >::value &&std::is_signed< T >::value &&!is_bool< T >::value &&!std::is_enum< T >::value >::type >{static constexpr object_category value{object_category::integral_value};};template< typename T >struct classify_object< T, typename std::enable_if< std::is_integral< T >::value &&std::is_unsigned< T >::value &&!std::is_same< T, char >::value &&!is_bool< T >::value >::type >{static constexpr object_category value{object_category::unsigned_integral};};template< typename T >struct classify_object< T, typename std::enable_if< std::is_same< T, char >::value &&!std::is_enum< T >::value >::type >{static constexpr object_category value{object_category::char_value};};template< typename T > struct classify_object< T, typename std::enable_if< is_bool< T >::value >::type >{static constexpr object_category value{object_category::boolean_value};};template< typename T > struct classify_object< T, typename std::enable_if< std::is_floating_point< T >::value >::type >{static constexpr object_category value{object_category::floating_point};};template< typename T >struct classify_object< T, typename std::enable_if<!std::is_floating_point< T >::value &&!std::is_integral< T >::value &&std::is_assignable< T &, std::string >::value >::type >{static constexpr object_category value{object_category::string_assignable};};template< typename T >struct classify_object< T, typename std::enable_if<!std::is_floating_point< T >::value &&!std::is_integral< T >::value &&!std::is_assignable< T &, std::string >::value &&(type_count< T >::value==1)&&std::is_constructible< T, std::string >::value >::type >{static constexpr object_category value{object_category::string_constructible};};template< typename T > struct classify_object< T, typename std::enable_if< std::is_enum< T >::value >::type >{static constexpr object_category value{object_category::enumeration};};template< typename T > struct classify_object< T, typename std::enable_if< is_complex< T >::value >::type >{static constexpr object_category value{object_category::complex_number};};template< typename T > struct uncommon_type{using type=typename std::conditional<!std::is_floating_point< T >::value &&!std::is_integral< T >::value &&!std::is_assignable< T &, std::string >::value &&!std::is_constructible< T, std::string >::value &&!is_complex< T >::value &&!is_mutable_container< T >::value &&!std::is_enum< T >::value, std::true_type, std::false_type >::type;static constexpr bool value=type::value;};template< typename T >struct classify_object< T, typename std::enable_if<(!is_mutable_container< T >::value &&is_wrapper< T >::value &&!is_tuple_like< T >::value &&uncommon_type< T >::value)>::type >{static constexpr object_category value{object_category::wrapper_value};};template< typename T >struct classify_object< T, typename std::enable_if< uncommon_type< T >::value &&type_count< T >::value==1 &&!is_wrapper< T >::value &&is_direct_constructible< T, double >::value &&is_direct_constructible< T, int >::value >::type >{static constexpr object_category value{object_category::number_constructible};};template< typename T >struct classify_object< T, typename std::enable_if< uncommon_type< T >::value &&type_count< T >::value==1 &&!is_wrapper< T >::value &&!is_direct_constructible< T, double >::value &&is_direct_constructible< T, int >::value >::type >{static constexpr object_category value{object_category::integer_constructible};};template< typename T >struct classify_object< T, typename std::enable_if< uncommon_type< T >::value &&type_count< T >::value==1 &&!is_wrapper< T >::value &&is_direct_constructible< T, double >::value &&!is_direct_constructible< T, int >::value >::type >{static constexpr object_category value{object_category::double_constructible};};template< typename T >struct classify_object< T, typename std::enable_if< is_tuple_like< T >::value &&((type_count< T >::value >=2 &&!is_wrapper< T >::value)||(uncommon_type< T >::value &&!is_direct_constructible< T, double >::value &&!is_direct_constructible< T, int >::value)||(uncommon_type< T >::value &&type_count< T >::value >=2))>::type >{static constexpr object_category value{object_category::tuple_value};};template< typename T > struct classify_object< T, typename std::enable_if< is_mutable_container< T >::value >::type >{static constexpr object_category value{object_category::container_value};};template< typename T, enable_if_t< classify_object< T >::value==object_category::char_value, detail::enabler >=detail::dummy >constexpr const char *type_name(){return"CHAR";}template< typename T, enable_if_t< classify_object< T >::value==object_category::integral_value||classify_object< T >::value==object_category::integer_constructible, detail::enabler >=detail::dummy >constexpr const char *type_name(){return"INT";}template< typename T, enable_if_t< classify_object< T >::value==object_category::unsigned_integral, detail::enabler >=detail::dummy >constexpr const char *type_name(){return"UINT";}template< typename T, enable_if_t< classify_object< T >::value==object_category::floating_point||classify_object< T >::value==object_category::number_constructible||classify_object< T >::value==object_category::double_constructible, detail::enabler >=detail::dummy >constexpr const char *type_name(){return"FLOAT";}template< typename T, enable_if_t< classify_object< T >::value==object_category::enumeration, detail::enabler >=detail::dummy >constexpr const char *type_name(){return"ENUM";}template< typename T, enable_if_t< classify_object< T >::value==object_category::boolean_value, detail::enabler >=detail::dummy >constexpr const char *type_name(){return"BOOLEAN";}template< typename T, enable_if_t< classify_object< T >::value==object_category::complex_number, detail::enabler >=detail::dummy >constexpr const char *type_name(){return"COMPLEX";}template< typename T, enable_if_t< classify_object< T >::value >=object_category::string_assignable &&classify_object< T >::value<=object_category::other, detail::enabler >=detail::dummy >constexpr const char *type_name(){return"TEXT";}template< typename T, enable_if_t< classify_object< T >::value==object_category::tuple_value &&type_count_base< T >::value >=2, detail::enabler >=detail::dummy >std::string type_name();template< typename T, enable_if_t< classify_object< T >::value==object_category::container_value||classify_object< T >::value==object_category::wrapper_value, detail::enabler >=detail::dummy >std::string type_name();template< typename T, enable_if_t< classify_object< T >::value==object_category::tuple_value &&type_count_base< T >::value==1, detail::enabler >=detail::dummy >inline std::string type_name(){return type_name< typename std::decay< typename std::tuple_element< 0, T >::type >::type >);}template< typename T, std::size_t I >inline typename std::enable_if< I==type_count_base< T >::value, std::string >::type tuple_name(){return std::string{};}template< typename T, std::size_t I >inline typename std::enable_if<(I< type_count_base< T >::value), std::string >::type tuple_name(){auto str=std::string{type_name< typename std::decay< typename std::tuple_element< I, T >::type >::type >)}+ ','+tuple_name< T, I+1 >);if(str.back()== ',') str.pop_back();return str;}template< typename T, enable_if_t< classify_object< T >::value==object_category::tuple_value &&type_count_base< T >::value >=2, detail::enabler > > std::string type_name()
Recursively generate the tuple type name.
Definition: CLI11.h:1729
GLuint GLuint end
Definition: glcorearb.h:475
GLsizei GLsizei GLchar * source
Definition: glcorearb.h:803
#define INVALID_TABLE_NAME
Definition: OP_Node.h:265
GLint GLuint mask
Definition: glcorearb.h:124
OP_Network * getRootCompiledParent() const
Definition: OP_Node.h:539
virtual ~OP_TransformCallback()
Definition: OP_Node.h:197
virtual void opChanged(OP_EventType type, void *dataptr=nullptr)=0
Wrapper around hboost::intrusive_ptr.
iterator begin()
Definition: UT_Array.h:1039
GLdouble GLdouble GLint GLint order
Definition: glad.h:2676
long long int64
Definition: SYS_Types.h:116
GLenum target
Definition: glcorearb.h:1667
#define SYS_NO_DISCARD_RESULT
Definition: SYS_Compiler.h:86
GLuint id
Definition: glcorearb.h:655
DEP_MicroNode & parmMicroNode(int parm_idx, int vi)
SYS_FORCE_INLINE const char * c_str() const
SYS_FORCE_INLINE bool isTimeDependent() const
Flag accessors.
OP_OpTypeId
Definition: OP_OpTypeId.h:18
HUSD_API bool eval(VtValue &val, T &ret_val)
#define INSTANTIATE_FINDNODE_FUNCTIONS(PREFIX)
Definition: OP_Node.h:478
OTLSyncMode
Definition: OP_Node.h:913
UT_ArrayMap< OP_ConnectorId, OP_Input * > OP_ConnectorInputMap
Definition: OP_Node.h:135
OP_UIChangeType
Definition: OP_DataTypes.h:238
GLuint const GLchar * name
Definition: glcorearb.h:786
virtual void setItemExpose(bool expose)
virtual void buildOpDependencies()
Definition: OP_Dot.h:24
signed char int8
Definition: SYS_Types.h:35
GLushort pattern
Definition: glad.h:2583
GLboolean GLboolean GLboolean b
Definition: glcorearb.h:1222
GLint GLenum GLint x
Definition: glcorearb.h:409
OP_ItemType
Definition: OP_ItemId.h:28
virtual bool getItemExpose() const
UT_ArrayMap< OP_ConnectorId, OP_Output * > OP_ConnectorOutputMap
Definition: OP_Node.h:136
int myVectorIndex
Definition: OP_Node.h:175
reverse_iterator rend()
End reverse iterator.
Definition: UT_Array.h:1070
virtual OP_OpTypeId getOpTypeID() const
Definition: OP_Node.h:557
virtual bool changeSpareParms(UT_IStream &ds, UT_String &errors)
GLdouble t
Definition: glad.h:2397
OP_API void OPclearNodeToChannelLinks()
GLenum mode
Definition: glcorearb.h:99
GT_API const UT_StringHolder version
virtual ~OP_NotifyVarChange()
Definition: OP_Node.h:189
OP_TransformCallback * myParentXfo
Definition: OP_Node.h:239
IFDmantra py
Definition: HDK_Image.dox:266
void doGetFullPath(UT_WorkBuffer &str) const override
Compute the full path of the node.
virtual void rebuildParmDependency(int parmidx)=0
GLsizeiptr size
Definition: glcorearb.h:664
unsigned int OP_ItemTypeMask
Definition: OP_ItemId.h:43
**Note that the tasks the is the thread number *for the or if it s being executed by a non pool thread(this *can happen in cases where the whole pool is occupied and the calling *thread contributes to running the work load).**Thread pool.Have fun
const UT_StringHolder myOptypeName
Definition: OP_Node.h:382
OP_API const char * OPtypeIdLabels[NUM_MANAGERS]
Nice label names used by network view, corresponding to OP_OpTypeId.
A map of string to various well defined value types.
Definition: UT_Options.h:87
GA_API const UT_StringHolder parms
GLenum GLfloat param
Definition: glcorearb.h:104
Parameters for OP_Node::fillInfoTree()/OP_Node::fillInfoTreeNodeSpecific()
bool operator==(const OP_NodeParmRef &other)
Definition: OP_Node.h:166
virtual const UT_StringHolder & getItemName() const =0
SIM_API const UT_StringHolder force
virtual void addExtraInput(OP_Node *op, OP_InterestType type)
PcpNodeRef_ChildrenIterator begin(const PcpNodeRef::child_const_range &r)
Support for range-based for loops for PcpNodeRef children ranges.
Definition: node.h:587
__hostdev__ constexpr T pi()
Pi constant taken from Boost to match old behaviour.
Definition: NanoVDB.h:976
fpreal64 fpreal
Definition: SYS_Types.h:283
LeafData & operator=(const LeafData &)=delete
Utility class for containing a color ramp.
Definition: UT_Ramp.h:96
typename set_type::iterator iterator
Inherit iterator and const_iterator.
Definition: UT_ArrayMap.h:103
#define OP_API
Definition: OP_API.h:10
GLuint index
Definition: glcorearb.h:786
OP_OTLLicenseType
OP_Output * myOutput
Definition: OP_Node.h:151
virtual unsigned referenceAllParameters(OP_Parameters *from, bool relative_references=true)
auto ptr(T p) -> const void *
Definition: format.h:4331
GLuint GLfloat * val
Definition: glcorearb.h:1608
OP_NodeParmRef(const OP_Node *eval_node=nullptr, const PRM_Parm *parm_ref=nullptr, int vi=-1)
Definition: OP_Node.h:157
OP_API const UT_StringHolder OP_USERDATA_CHILDOPMENUFILE
TransformMode
Definition: OP_Node.h:1205
OP_Node * myNode
Definition: OP_Node.h:445
OP_EventType
Definition: OP_Value.h:22
A global error manager scope.
GA_API const UT_StringHolder pivot
base_iterator< const OP_Node *, true > const_iterator
Definition: UT_Array.h:1032
OP_DataType
Definition: OP_DataTypes.h:189
GU_API void xform(CE_Context &context, bool recompile, int npts, const cl::Buffer &outPos, const cl::Buffer &inPos, const cl::Buffer &surfacexform, const cl::Buffer *grp=nullptr)
int OP_OutputIdx
Definition: OP_DataTypes.h:185
**If you just want to fire and args
Definition: thread.h:618
unsigned int uint32
Definition: SYS_Types.h:40
OP_API const UT_StringHolder OP_USERDATA_WIRESTYLE
static OP_Node * lookupNode(int unique_id, bool include_proxy=false)
Definition: OP_Node.h:761
UT_CycleDetect< OP_NodeParmRef > OP_NodeParmRefCycle
Definition: OP_Node.h:245
OP_Network * getParent() const
Definition: OP_Node.h:537
virtual void clearUndoFlags()
virtual UT_Color getColor() const
Accessors for color used in the network view.
virtual bool getPicked() const =0
virtual void convertOpdefToAbsolutePath(UT_String &str) const =0
This is the base class for all DOP nodes.
Definition: DOP_Node.h:77
GLubyte GLubyte GLubyte GLubyte w
Definition: glcorearb.h:857
virtual OP_Node * castToOPNode()
Definition: PRM_ParmOwner.h:51
OP_EvaluateTransformTracksArgs(const UT_StringHolder &name, UT_Matrix4D *w, UT_Matrix4D *l=nullptr, OP_TransformCallback *parent_cb=nullptr, int *timedep=nullptr)
Definition: OP_Node.h:204
virtual void spareParmRemoved(const char *parmname)=0
virtual fpreal getH() const =0
bool operator!=(const BaseDimensions< T > &a, const BaseDimensions< Y > &b)
Definition: Dimensions.h:165
int operator==(const opParmData &v) const
Definition: OP_Node.h:449
void getOutputNodesIncludeSpare(UT_Array< OP_Node * > &outputs, bool into_subnets=false, bool through_dots=true, UT_Optional< OP_OutputIdx > output_idx=UT_NULLOPT, bool include_spare=true) const
virtual void syncNodeVersion(const char *old_version, const char *current_version, bool *node_deleted)
void getOutputNodes(UT_Array< OP_Node * > &outputs, bool into_subnets=false, bool through_dots=true, OP_OutputIdx output_idx=-1) const
Definition: OP_Node.h:2057
Safe reference to an OP node.
Definition: OP_Node.h:4455
Options class for use with OP_Node::saveCommand()
Definition: OP_Node.h:388
#define DEFAULT_COMP_HASH_VALUE
Definition: OP_Node.h:262
OP_ScopeOp
Definition: OP_Parameters.h:58
bool wasInterrupted(T *i, int percent=-1)
OP_Input * myInput
Definition: OP_Node.h:143
OP_NodeFlags & flags()
Definition: OP_Node.h:1482
SYS_FORCE_INLINE PRM_ParmList * getParmList()
Definition: PRM_ParmOwner.h:73
virtual PRM_ParmMicroNode * createParmMicroNodes(PRM_Parm &parm) const
#define UTstatic_pointer_cast
Definition: UT_SharedPtr.h:43
OP_EvaluateTransformTracksArgs(int index, UT_Matrix4D *w, UT_Matrix4D *l=nullptr, OP_TransformCallback *parent_cb=nullptr, int *timedep=nullptr)
Definition: OP_Node.h:219
state
Definition: core.h:2289
OP_API const UT_StringHolder OP_USERDATA_DESCRIPTIVE_PARM
unsigned char uchar
Definition: SYS_Types.h:42
OP_Input * mySavedInput
Definition: OP_Node.h:181
UT_LockedRawPtr< const OP_NodeList, OP_Lock > OP_LockedConstNodeList
Definition: OP_Node.h:248
Definition: format.h:1821
Definition: OP_PostIt.h:42
iterator end()
End iterator.
Definition: UT_Array.h:1044
OP_API OP_Node * OPgetNodeFromChannel(const CH_Channel *chp)
virtual bool isParmPendingOverride(const char *, int) const
ImageBuf OIIO_API channels(const ImageBuf &src, int nchannels, cspan< int > channelorder, cspan< float > channelvalues={}, cspan< std::string > newchannelnames={}, bool shuffle_channel_names=false, int nthreads=0)
OP_ConnectorId myName
Definition: OP_Node.h:152
virtual void permissionError(const char *chname=nullptr)
virtual SYS_NO_DISCARD_RESULT UT_UniquePtr< PRM_ParmOwnerContext > pushAsPwd() const =0
UT_StringHolder myTrackName
Definition: OP_Node.h:233
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
Definition: glcorearb.h:1297
GLenum src
Definition: glcorearb.h:1793
virtual const PRM_Parm * traverseRef(int *sub_idx, fpreal time, int parm_idx, int vec_idx) const =0
UT_String myLabel
Definition: OP_Node.h:444