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