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  /// Returns an index of the output which goes out from this node to
1612  /// the target_node, and connects to the target_node at the specified
1613  /// input index. Returns `UT_NULLOPT` if the connection doesn't exist.
1614  /// Use whichOutputIsFollowingIndirect for a more robust solution.
1615  UT_Optional<OP_OutputIdx> whichOutputIs2(
1616  const OP_Node* target_node,
1617  OP_InputIdx input_on_target_node) const;
1618 
1619  /// Computes the output, but handles the case that target_node's input
1620  /// is an indirect input. This will then follow the indirect chain
1621  /// up until a node's real input.
1622  OP_OutputIdx whichOutputIsFollowingIndirect(
1623  const OP_Node* target_node,
1624  OP_InputIdx input_on_target_node) const;
1625  /// Computes the output, but handles the case that target_node's input
1626  /// is an indirect input. This will then follow the indirect chain
1627  /// up until a node's real input.
1628  UT_Optional<OP_OutputIdx> whichOutputIsFollowingIndirect2(
1629  const OP_Node* target_node,
1630  OP_InputIdx input_on_target_node) const;
1631 
1632  /// Returns the index of an input into which source_node is connected
1633  /// on this node. counter determines the Nth such connection from
1634  /// source node to this particular node.
1635  OP_InputIdx whichInputIs(const OP_Node* source_node,
1636  int counter) const;
1637 
1638  // Compacts the inputs array, removing all null entries.
1639  void consolidateInputs();
1640  virtual void clearUnreferencedInputs();
1641  virtual bool allowConsolidatingInput(OP_InputIdx idx);
1642 
1643  // Returns a pointer to an input given an input index. If the input index
1644  // is less than nInputs() it will always return a valid input. If the grow
1645  // flag is set to true, then any inputs between nInputs and the index
1646  // given will be created, up to maxInputs().
1647  virtual OP_Input *getInputReference(OP_InputIdx idx, bool grow);
1648 
1649  // As before, except missing inputs are not created. NULL is returned for
1650  // non-existent inputs.
1651  virtual OP_Input *getInputReferenceConst(OP_InputIdx idx) const;
1652 
1653  virtual int doDeleteRewire() const { return 1; }
1654  // This moves the input at srcidx to dstidx. forcesubnet will enable
1655  // modification of subnet inputs and outputs even when inside a
1656  // blockModify().
1657  virtual void moveInput(OP_InputIdx srcidx, OP_InputIdx dstidx,
1658  bool forcesubnet = false);
1659  OP_ERROR insertInput(OP_InputIdx idx, OP_Node *op,
1660  OP_OutputIdx output_idx);
1661  OP_ERROR insertIndirectInput(OP_InputIdx idx,
1662  OP_IndirectInput *input);
1663 
1664  // For nodes with editable input names, this function is used to set the
1665  // default name for a new input.
1666  virtual UT_Options getInputDataDefault(OP_InputIdx idx) const
1667  { return UT_Options(); }
1668 
1669  /// The following methods are used for nodes that allow reordering inputs.
1670  /// Returns the number of inputs that editor should display.
1671  virtual int getInputEditorInputs();
1672  /// Returns true if editor should display parameter option menu button.
1673  virtual bool allowInputEditorInputParm();
1674  /// Returns true if editor should display delete input button.
1675  virtual bool allowInputEditorInputDelete();
1676  /// Gets the input label to display in editor and returns true. Otherwise,
1677  /// returns false if editor should use backward-compatible labeling scheme.
1678  virtual bool getInputEditorInputLabel(UT_String &label,
1679  OP_InputIdx idx);
1681  virtual const OP_DataMicroNode &
1682  dataMicroNodeConst() const
1683  { return myDataMicroNode; }
1684  OP_DataMicroNode & dataMicroNode()
1685  {
1686  return const_cast<OP_DataMicroNode &>(
1687  dataMicroNodeConst());
1688  }
1689 
1690  /// Subclasses should override this to customize the micro-node dependency
1691  /// of their parameter list. The default is just dataMicroNode().
1692  virtual const OP_DataMicroNode &
1693  parmListMicroNodeConst() const
1694  { return dataMicroNodeConst(); }
1695  OP_DataMicroNode & parmListMicroNode()
1696  {
1697  return const_cast<OP_DataMicroNode &>(
1698  parmListMicroNodeConst());
1699  }
1700 
1701  bool hasIndepParmListMicroNode() const
1702  {
1703  return (&parmListMicroNodeConst()
1704  != &dataMicroNodeConst());
1705  }
1707  /// This micronode is guaranteed to trigger when any flag changes.
1708  DEP_MicroNode & flagMicroNode()
1709  { return myFlagMicroNode; }
1710  /// This micronode is guaranteed to trigger when the specified flag changes;
1711  /// it may also trigger on unrelated flag changes.
1712  DEP_MicroNode & flagMicroNode(char flag)
1713  { return myIndividualFlagMicroNodes[flag]; }
1714  DEP_MicroNode & parmMicroNode(int parm_idx, int vi)
1715  { return getParmList()->parmMicroNode(
1716  parm_idx, vi); }
1718  /// Accessors to event micro nodes.
1719  const DEP_MicroNode &eventMicroNodeConst(OP_EventType e) const
1720  {
1721  return SYSconst_cast(this)->eventMicroNode(e);
1722  }
1723  DEP_MicroNode & eventMicroNode(OP_EventType e);
1724 
1725  bool hasEventMicroNode(OP_EventType e) const
1726  {
1727  UT_ASSERT_P(e >= 0 && e < OP_EVENT_TYPE_COUNT);
1728  if (!myEventMicroNodes)
1729  return false;
1730  return bool(myEventMicroNodes[e]);
1731  }
1732 
1733  /// Subclasses should override this provide any additional micronodes that
1734  /// they own. This list is used in places such as node deletion so that
1735  /// dependents are dirtied.
1736  virtual void getOwnedMicroNodes(
1737  DEP_MicroNodeList &micronodes);
1738 
1739  /// Explicitly propagate dirtiness for a particular micronode owned by
1740  /// some node.
1741  void propagateDirtyMicroNode(
1742  DEP_MicroNode &micronode,
1743  OP_EventType reason,
1744  void *data,
1745  bool send_root_event);
1746 
1747  /// Declares that this node's data depends on the @c op for the given
1748  /// reason (OP_INTEREST_DATA, OP_INTEREST_FLAG).
1749  /// @note There are no other acceptable values for type.
1750  virtual void addExtraInput(OP_Node *op, OP_InterestType type);
1751 
1752  /// Declares that this node's data depends on @c op channel. If vec_i is
1753  /// -1, then this node depends on all the channels of the parameter.
1754  void addExtraInput(OP_Node &op, int parm_i, int vec_i);
1755 
1756  /// Generic version of addExtraInput() which adds a dependency from an
1757  /// source ref to this node's data micronode.
1758  void addExtraInput(const OP_InterestRef &source_ref);
1759 
1760  /// Generic version of addExtraInput() which adds a dependency from an
1761  /// source micronode to this node's data micronode.
1762  void addExtraInput(DEP_MicroNode &source_micronode);
1763 
1764  /// Marks this to be dependent on all the parameters inside of the
1765  /// multiparm.
1766  void addMultiparmInterests(OP_Node *srcnode, PRM_Parm &parm);
1767 
1768 
1769  static DEP_MicroNode *getEvalChannelMicroNode(int thread);
1770 
1771  /// Declare from an expression callback that the current evaluation channel
1772  /// is dependent on the given source.
1773  // @{
1774  static void addExtraInputToEvalChannel(
1775  int thread,
1777  {
1778  addExtraInputToEvalChannel(
1779  thread,
1780  OP_InterestRef(op, type));
1781  }
1782  static void addExtraInputToEvalChannel(
1783  int thread,
1784  OP_Node &op, int parm_i, int vec_i)
1785  {
1786  addExtraInputToEvalChannel(
1787  thread,
1788  OP_InterestRef(op,parm_i,vec_i));
1789  }
1790  static void addExtraInputToEvalChannel(
1791  int thread,
1792  const OP_InterestRef &source_ref)
1793  {
1794  DEP_MicroNode *
1795  target = getEvalChannelMicroNode(thread);
1796  if (target)
1797  OP_Node::addExtraInput(*target, source_ref);
1798  }
1799  static void addExtraInputToEvalChannel(
1800  int thread,
1801  DEP_MicroNode &src_micronode)
1802  {
1803  DEP_MicroNode *
1804  target = getEvalChannelMicroNode(thread);
1805  if (target)
1806  target->addExplicitInput(src_micronode);
1807  }
1808  // @}
1809 
1810  /// Generic versions of addExtraInput() used by the others. In particular,
1811  /// the static version of addExtraInput() allows you to define channel to
1812  /// channel dependencies.
1813  // @{
1814  static void addExtraInput(
1815  const OP_InterestRef &target_ref,
1816  const OP_InterestRef &source_ref);
1817  static void addExtraInput(
1818  const OP_InterestRef &target_ref,
1819  DEP_MicroNode &source_micronode);
1820  static void addExtraInput(
1821  DEP_MicroNode &target_micronode,
1822  const OP_InterestRef &source_ref);
1823  // @}
1824 
1825  static void addMultiparmInterests(const OP_InterestRef &target_ref,
1826  OP_Node *srcnode,
1827  PRM_Parm &parm);
1828  static void addMultiparmInterests(DEP_MicroNode &target,
1829  OP_Node *srcnode,
1830  PRM_Parm &parm);
1831 
1832  void getExtraInputNodes(
1833  OP_NodeList &extras,
1834  bool remove_duplicates = true,
1835  bool data_interest = true,
1836  bool parm_interest = true,
1837  bool flag_interest = true,
1838  bool include_parmlist = true,
1839  bool follow_simulation_inputs = false) const;
1840  void getExtraOutputNodes(
1841  OP_NodeList &extras,
1842  bool remove_duplicates = true,
1843  bool data_interest = true,
1844  bool parm_interest = true,
1845  bool flag_interest = true) const;
1846 
1847  int getNumExtraInputs() const;
1848 
1849  void dumpExtraInputs(
1850  std::ostream &os,
1851  bool as_DOT,
1852  int indent_level = 0) const;
1853 
1854  /// Appends to the provided context the expected parameters
1855  /// from the containing network.
1856  /// Adds dependencies to those parameters to the provided depnode.
1857  virtual bool buildDefaultCopContext(OP_Context &context,
1858  DEP_MicroNode *depnode=nullptr);
1859 
1860  // addExprOpDependency is a helper function for building dependencies for
1861  // the expression library callback functions.
1862  static void addExprOpDependency(const char *arg_str,
1863  const PRM_RefId &ref_id,
1864  OP_InterestType interest_type);
1865  static void addExprOpDependency1From2(const char *arg_str1,
1866  const char *arg_str2,
1867  const PRM_RefId &ref_id,
1868  OP_InterestType interest_type);
1869  static void addExprOpParmDependency(const char *arg_str,
1870  const PRM_RefId &ref_id,
1871  OP_InterestType interest_type);
1872  // NB: is reponsible for freeing new_arg!
1873  static void changeExprOpRef(const char *arg_str,
1874  char *&new_arg,
1875  const char *new_fullpath,
1876  const char *old_fullpath,
1877  const char *old_cwd);
1878  // NB: is reponsible for freeing new_arg!
1879  static void changeExprOpRef1From2(const char *arg_str1,
1880  const char *arg_str2,
1881  char *&new_arg1,
1882  char *&new_arg2,
1883  const char *new_fullpath,
1884  const char *old_fullpath,
1885  const char *old_cwd);
1886  // NB: is reponsible for freeing new_arg!
1887  static void changeExprOpParmRef(const char *arg_str,
1888  char *&new_arg,
1889  const char *new_fullpath,
1890  const char *old_fullpath,
1891  const char *old_cwd,
1892  const char *chan_name,
1893  const char *old_chan_name);
1894 
1895  void addGenericOpNameReference( const UT_String &oppath );
1896  void addGenericOpNameReference( const PRM_RefId &ref_id,
1897  OP_Node *node );
1898  void addGenericOpInputReference( const PRM_RefId &ref_id,
1899  OP_Node *node );
1900 
1901  static void moveAndUpdateDependencies(
1902  const OP_NodeList &src_nodes,
1903  const OP_NodeList &dest_nodes );
1904 
1905  static void updateChannelPtrs( CH_CollectionList &parents );
1906 
1907  bool getParmBaseNodePath(
1908  UT_String &path,
1909  int parm_index,
1910  int thread) const;
1911 
1912  // Make this function public so it can be called by OPUI_EditSubnet
1913  // and possibly others. Note that it is defined in PRM_ParmOwner so
1914  // that it can be called from the PRM library.
1915  void rebuildParmDependency(int parm_index) override;
1916 
1917  // Clear op name dependencies
1918  void clearParmDependency(int parm_index) override;
1919  // decrementOpReference() should only be called by clearParmDependency()
1920  void decrementOpReference(int node_id);
1921 
1922  virtual void dumpDependencies(std::ostream &os);
1923  void dumpOpDependents(OP_Node *ref, int brief,
1924  std::ostream &os);
1925  const OP_DependencyList
1926  &getOpDependents() const { return myOpDependents; }
1927 
1928 
1929  // INTERNAL: Do NOT use outside of OP_Node! Will be made private.
1930  int countReferences(int op_id);
1931 
1932  // Get the existing node *NAME* references (eg. expr references)
1933  // NB: This function assumes that refs is sorted without duplicate entries!
1934  void getExistingOpReferences(OP_NodeList &refs,
1935  bool recurse) const;
1936 
1937  // Get the as complete list of data references as possible for this node.
1938  // This combines getExistingOpReferences() which exist without cooking, and
1939  // getExtraInputNodes() which are the current references since the last
1940  // cook of its refernces.
1941  void getFullOpReferences(OP_NodeList &refs,
1942  bool include_descendants) const;
1943 
1944  // Get the existing node *NAME* dependents (eg. expr references)
1945  // NB: This function assumes that deps is sorted without duplicate entries!
1946  void getExistingOpDependents(OP_NodeList &deps,
1947  bool include_descendants) const;
1948 
1949  // Get the as complete list of data dependents as possible for this node.
1950  // This combines getExistingOpDependents() which exist without cooking, and
1951  // getExtraOutputNodes() which are the current dependents since the last
1952  // cook.
1953  void getFullOpDependents(OP_NodeList &deps,
1954  bool include_descendants) const;
1955 
1956  // Gets a list of parms that reference one of our channels/parms.
1957  void getParmsThatReference(const char *channame,
1959  UT_IntArray &parmsubidxs);
1960 
1961  virtual void inputConnectChanged(OP_InputIdx which);
1962 
1963  // Returns the number of output entries in the output array. Note
1964  // that this done regardless of which entries have any outputs connected.
1965  unsigned nOutputEntries() const;
1966  // Get access to the raw network items connected to our outputs.
1967  // These functions can focus on a single output connector, or treat
1968  // all outputs as a flat array by passing output_idx = -1.
1969  int nOutputItems(
1970  OP_OutputIdx output_idx = -1
1971  ) const;
1972  OP_NetworkBoxItem *getOutputItem(
1973  int idx,
1974  OP_OutputIdx output_idx = -1
1975  ) const;
1976  /// Get access to the raw network items connected to our outputs.
1977  /// These functions can focus on a single output connector, or treat
1978  /// all outputs as a flat array by passing output_idx = UT_NULLOPT.
1979  /// These updated versions handle spare outputs, which use negative indices.
1980  /// @{
1981  exint nOutputItems2(
1982  UT_Optional<OP_OutputIdx> output_idx =
1983  UT_NULLOPT) const;
1984  OP_NetworkBoxItem *getOutputItem2(
1985  int idx,
1986  UT_Optional<OP_OutputIdx> output_idx =
1987  UT_NULLOPT) const;
1988  /// @}
1989  // Quick check if this node has any node outputs.
1990  bool hasAnyOutputNodes(
1991  bool through_dots = true,
1992  OP_OutputIdx output_idx = -1
1993  ) const;
1994  /// Fills a node list with all outputs from this node. This function can
1995  /// search through dots, and dive into subnets. It can also run on a
1996  /// single output connector or all of them.
1997  /// @{
1998  void getOutputNodes(
1999  UT_Array<OP_Node*> &outputs,
2000  bool into_subnets = false,
2001  bool through_dots = true,
2002  OP_OutputIdx output_idx = -1
2003  ) const;
2004  void getOutputNodes2(
2005  UT_Array<OP_Node*> &outputs,
2006  bool into_subnets = false,
2007  bool through_dots = true,
2009  output_idx = UT_NULLOPT) const;
2010  /// @}
2011  // Quick function to return the first output node, searching depth first
2012  // through dots if requested.
2013  OP_Node *getFirstOutputNode(
2014  bool through_dots = true,
2015  OP_OutputIdx output_idx = -1
2016  ) const;
2017 
2018  // obtains an output node that leads to a target node (e.g., during network
2019  // traversal). Null if target is not a descendant.
2020  OP_Node *getOutputTowardsNode(const OP_Node *target);
2021 
2022  /// Fill in 'tree' with details that are common to all node types. Then call
2023  /// fillInfoTreeNodeSpecific() to get specific details about this specific
2024  /// node (be it a SOP, CHOP, etc)
2025  void fillInfoTree(UT_InfoTree &tree,
2026  const OP_NodeInfoTreeParms &parms);
2027 
2028  /// Triggered by 'fillInfoTree()', this virtual function adds all node-
2029  /// specific info to 'tree'. All child classes must create their own
2030  /// branches under 'tree' to place their info
2031  virtual void fillInfoTreeNodeSpecific(UT_InfoTree &tree,
2032  const OP_NodeInfoTreeParms &parms);
2033 
2034  /// Optionally called on parent from fillInfoTreeNodeSpecific() to provide
2035  /// some information about node that only parent network can provide.
2036  /// @return True if parent added info specific to that child.
2037  virtual bool fillInfoTreeChildSpecific(UT_InfoTree &tree,
2038  const OP_NodeInfoTreeParms &parms,
2039  OP_Node *child);
2040 
2041  // These methods get input data for the OP. If they return an error code
2042  // >= UT_ERROR abort, then the errno should be set, and there may be a
2043  // further local error message. There is no error checking to ensure that
2044  // each locked source is only released once, so it's up to the user. The
2045  // standard method is to call lockInputs(), then call unlockInputs() on
2046  // exit. However, in some cases (i.e. switch SOP) only some sources need
2047  // to be cooked.
2048  //
2049  // lockInput() will return an error code >= UT_ERROR iff idx <
2050  // minInputs(). Otherwise, it's considered to be an optional input, so no
2051  // data will be returned. A simple rule of thumb: If lockInput() returns
2052  // ok, the source has to be unlocked, otherwise it shouldn't be unlocked!
2053  // If lockInputs() detects an error, it will automatically unlock the
2054  // inputs so that unlockInputs() should NOT be called!
2055  virtual OP_ERROR lockInput(OP_InputIdx idx, OP_Context &context);
2056  virtual void unlockInput(OP_InputIdx idx);
2057  virtual OP_ERROR lockInputs(OP_Context &context);
2058  virtual void unlockInputs();
2059 
2060  // This "serial" number refers to the number of times that the geometry
2061  // had been changed. Note, only the "modeller" should bump the cook count,
2062  // the OP cook method does this also, but has privilaged access.
2063  int getCookCount() const { return myCookCount; }
2064  void triggerOutputChanged();
2065 
2066  void triggerUIChanged(
2069  // Returns the index of cooked input to a SOP switch
2070  virtual OP_InputIdx cookedInputIndex() const { return -1; }
2071 
2072  /// For nodes which simply pass-through their data from some other node,
2073  /// this returns the node whose data will used transparently as this node's
2074  /// output. This function can give different values depending on its
2075  /// parameters. Used by node traversal algorithms.
2076  ///
2077  /// The default implementation returns the first input if it's bypassed, so
2078  /// subclasses should only do something different if this function returns
2079  /// NULL.
2080  ///
2081  /// @param t Eval time
2082  /// @param mark_used Mark this node is using the returned node (if
2083  /// non-NULL).
2084  ///
2085  virtual OP_Node *getPassThroughNode(
2086  fpreal t,
2087  bool mark_used = false);
2088 
2089  bool setMinimumCacheSize(int min_size);
2090 
2091  OP_VERSION getVersionParms() const
2092  { return dataMicroNodeConst().modVersion(); }
2093 
2094  // This will be called if the timeInterest flag is set.
2095  // This will return true if the node needs to be dirtied for cooking
2096  virtual bool handleTimeChange(fpreal /* t */) { return false; }
2097 
2098  /// Returns true if the OP depends on time at the given time. This
2099  /// is sensitive to handleTimeChange's overrides.
2100  bool isTimeDependent(const OP_Context &context);
2101 
2102  // Returns true if this node is an HDA with a dive target, or a C++ node
2103  // with a subnework, but is not an OBJ, subnet, or manager.
2104  virtual bool isDiveable() const;
2105 
2106  static int getGlobbedNodes(OP_Node *cwd, UT_String &holder,
2107  const char *pattern, UT_WorkArgs &argv,
2108  OP_GlobContext *context);
2109 
2110  static int getGlobbedNetworkBoxes(OP_Node *cwd, UT_String &holder,
2111  const char *pattern, UT_WorkArgs &argv,
2112  OP_GlobContext *context);
2113 
2114  static int getGlobbedPostIts(OP_Node *cwd, UT_String &holder,
2115  const char *pattern, UT_WorkArgs &argv,
2116  OP_GlobContext *context);
2117 
2118 
2119  /// Obtains additional nodes that should be copied or deleted when this
2120  /// node is copied or deleted. It applies to situations, such as, where
2121  /// an hidden input node feeds only to this node and serves only that
2122  /// purpose, so it should be coppied/deleted along with the master.
2123  virtual void getExtraNodesForCopyOrDelete(OP_NodeList &extras)const;
2124 
2125  // Runs the creation script (if there is one). The return value is false
2126  // if the node was deleted while running the script. In this case
2127  // obviously the node pointer becomes invalid and should not be used
2128  // any more. It returns true if the node still exists.
2129  virtual bool runCreateScript();
2130  // Go through all our parms to match the values to the current hip file
2131  // units settings.
2132  void updateParmsToMatchCurrentUnits();
2133 
2134  /// True if the otl is marked as matching, but hasn't actually been
2135  /// synced yet.
2136  bool getDelaySyncOTL() const
2137  { return myDelaySyncOTL; }
2138 
2139  /// Shallowly sets the delayed sync flag,
2140  void setDelaySyncOTL(bool isdelayed);
2141 
2142  /// Determines if this node should do delayed syncing or not.
2143  bool shouldDelaySyncOTL() const;
2145  /// Verifies this node has been synchronized in case it was delayed.
2146  void syncDelayedOTL()
2147  {
2148  if (!getDelaySyncOTL()) return;
2149  internalSyncDelayedOTL();
2150  }
2151 
2152  /// Matches the node to the current HDA definition, loading the contents
2153  /// section if ncecessary and setting the match flag.
2154  virtual void matchOTLDefinition();
2155 
2156  /// Unmatches (unlocks) the node from the current HDA definition.
2157  virtual void unmatchOTLDefinition();
2158 
2159  /// Method that is invoked when the HDA index file has been cleared
2160  /// because the underlying HDA definition has changed.
2161  virtual void handleOTLIndexFileCleared();
2162 
2163  /// Returns the error string where we keep all errors generated during
2164  /// our most recent synchronization attempt.
2165  const UT_String &getSyncErrors() const
2166  { return mySyncErrors; }
2167  /// Returns the error level generated in our last synchronization attempt.
2168  OP_ERROR getSyncErrorLevel() const
2169  { return mySyncErrorLevel; }
2170 
2171  /// Return true if any ancestor of this node is currently running the
2172  /// syncContents function (and so has mySyncDepth > 0). This is used to
2173  /// detect changes to nodes that are not currently "locked", but will
2174  /// become locked once the sync is complete.
2175  bool isAnyAncestorBeingSynced() const;
2176 
2177  /// Interface to flag that specifies whether or not we match our definition.
2178  int getMatchesOTLDefinition() const;
2179 
2180  /// Utility function for syncing/unsyncing all uncestor nodes.
2181  static void propagateMatchOTLDefinitionToAncestors(OP_Node *node,
2182  bool sync_flag);
2183 
2184  // Some extra functions for dealing with access rights as they relate
2185  // to matching the OTL definition.
2186  int getCanDeviateFromOTLDefinition() const;
2187  void setAllChildAssetPermissions(int permission);
2188  // Recompute the asset permissions because something changed like the node
2189  // was locked or unlocked.
2190  void computeAllChildAssetPermissions();
2191  // Returns true if this node is contained inside a locked HDA, but
2192  // is marked as an editable node within that HDA.
2193  bool getIsEditableAssetSubNode() const;
2194 
2195  // Turn off our export flag and the export flags of our children.
2196  void turnOffAllChildExports();
2197 
2198  // Collection of methods for working with licensed assets.
2199  bool haveLicenseToAccessContents(
2200  OP_Node* opt_specific_child = nullptr) const;
2201  bool haveLicenseToAccessParentContents() const;
2202  bool haveAncestorWithoutFullLicense(bool ignore_self) const;
2203  OP_OTLLicenseType getLicense() const;
2204  // Get the first (oldest) ancestor without a license to access contents.
2205  OP_Node *getFirstExecLicenseOnlyAncestor(
2206  bool ignore_self = true) const;
2207  // Get the last (youngest) ancestor without a license to access contents.
2208  OP_Node *getLastExecLicenseOnlyAncestor(
2209  bool ignore_self = true) const;
2210 
2211  bool isCompiled() const;
2212 
2213  // Save as a series of ASCII commands.
2214  void saveWires(std::ostream &os, const char *name,
2215  int dogeneral = 0);
2216  void saveOutputWires(std::ostream &os, const char *name,
2217  int dogeneral = 0);
2218  virtual void saveIntrinsicCommand(std::ostream &os,
2219  const char *name);
2220 
2221  /// Writes to 'os' a string of hscript commands to recreate this node.
2222  virtual OP_ERROR saveCommand(std::ostream &os,
2223  const char *name,
2224  fpreal x,
2225  fpreal y,
2226  const char *netboxname,
2227  const OP_SaveCommandOptions &options);
2228 
2229  // This method saves a chlock style command for this node's parameters.
2230  // name - the name of the node to print on the command;
2231  // command - the name of the command;
2232  // flag_method - a PRM_Parm method that can be queried for the flag to
2233  // output;
2234  // defaultstoo - prints a default "-*" or "+*" as the first parameter
2235  // reverse - normally the default is "-*" followed by the list of
2236  // parameters that result true for flag_method(). If
2237  // reverse is true, then the default is "+*" followed by
2238  // the parameters where flag_method() is false. Only useful
2239  // when defaultstoo is true.
2240  // parm_array - an optional array of parameters whose values should be
2241  // printed. If this array is NULL, then the entire node
2242  // is searched.
2243  void saveParameterFlags(std::ostream &os, const char *name,
2244  const char *command,
2245  bool (PRM_Parm::*flag_method)(int) const,
2246  bool defaultstoo, bool reverse,
2247  UT_Array<opParmData> *parm_array);
2248 
2249  void saveUserDataCommand(
2250  std::ostream &os, const char *node_name,
2251  bool omit_version = false);
2252 
2254  {
2255  RAMP_ERR_SUCCESS,
2256  RAMP_ERR_NOT_FOUND,
2257  RAMP_ERR_ONLY_KEY
2258  };
2259  virtual RampError rampCommand(bool remove, fpreal pos, float rgba[4]);
2260  RampError rampCommand(bool remove, fpreal pos, float rgba[4],
2261  UT_Ramp &ramp);
2262 
2263  virtual bool loadRamp(UT_IStream &is, const char *path=nullptr);
2264 
2265  bool loadRamp(UT_IStream &is, UT_Ramp &ramp,
2266  const char *path=nullptr);
2267  OP_ERROR saveRamp(std::ostream &os, UT_Ramp &ramp,
2268  const char *name = nullptr, int command = 0);
2269 
2270  bool getUserData(const UT_StringRef &key,
2271  UT_StringHolder &result) const;
2272  void setUserData(const UT_StringRef &key,
2273  const UT_StringHolder &data,
2274  bool save_undo);
2275  bool hasUserData(const UT_StringRef &key) const;
2276  bool deleteUserData(const UT_StringRef &key,
2277  bool save_undo);
2278  const UT_Options &userData() const
2279  { return myUserData; }
2280  bool loadUserData(UT_IStream &is, const char *path=nullptr);
2281  OP_ERROR saveUserData(std::ostream &os, const char *path);
2282  void clearUserData(bool save_undo);
2283  virtual void userDataChanged(const UT_StringHolder &key);
2285  /// Prefix to use for internally used user data.
2286  static const char *internalUserDataPrefix() { return "sidefx::"; }
2287 
2288  /// Returns a shared pointer to a previously stored blind data. If no
2289  /// blind data exists with the given key, an empty shared pointer is
2290  /// returned.
2291  UT_SharedPtr<void> getBlindData(const char *key) const;
2292 
2293  /// Return a pointer to a previously stored blind data, statically cast
2294  /// to the type given. If the cast fails, or if there's no data of that
2295  /// type, a NULL pointer is returned. To distinguish between the two cases
2296  /// call hasBlindData().
2297  template<typename T>
2298  UT_SharedPtr<T> getBlindData(const char *key) const
2299  { return UTstatic_pointer_cast<T>(getBlindData(key)); }
2300 
2301  /// Stores a blind data pointer on this OP_Node object. Any entry that
2302  /// previously existed will be erased, and, if it is the last reference,
2303  /// the object itself deleted. The \c void type can convert from any other
2304  /// shared pointer type, while storing the deleter function, allowing
2305  /// OP_Node to delete the data without knowing anything about the class.
2306  /// Blind data is *not* stored with the class.
2307  void setBlindData(const char *key, UT_SharedPtr<void> ptr);
2308 
2309  /// Returns true if this object stores a blind data with the given key.
2310  bool hasBlindData(const char *key) const;
2311 
2312  /// Remove any reference to the blind data of the given key from this
2313  /// object.
2314  bool deleteBlindData(const char *key);
2315 
2316  void getDataBlockKeys(UT_StringArray &keys,
2317  const UT_StringHolder &type =
2318  UT_StringHolder()) const;
2319  OP_DataBlockPtr getDataBlock(const char *key) const;
2320  bool setDataBlock(const char *key, OP_DataBlockPtr ptr);
2321  OP_ERROR saveDataBlocksPacket(std::ostream &os,
2322  const char *path_prefix,
2323  const UT_StringHolder &node_name);
2324  bool loadDataBlocks(UT_IStream &is, const char *path);
2325  bool clearDataBlocks();
2326  virtual void dataBlockChanged(const UT_StringHolder &key);
2327 
2328  // deleteNodeData is called when the OP_Cache wants to delete some data.
2329  // This method should return 1 if you want change events to be propagated
2330  // to the extra inputs when data is deleted from the cache.
2331  virtual int deleteNodeData(void *);
2332  void propagateNodeDataDeleted();
2333 
2334  // getCachedPythonObject returns NULL if no object exists with the given
2335  // key.
2336  PY_OpaqueObject *getCachedPythonObject(const UT_StringRef &key) const;
2337  // Call setCachedPythonObject with a PyObject * cast to a void *, not with
2338  // a PY_OpaqueObject * cast to a void *. The pointer must not be null.
2339  void setCachedPythonObject(
2340  const UT_StringHolder &key, void *opaque_py_object);
2341  // deleteCachedPythonObject returns false if no value exists with that key.
2342  bool deleteCachedPythonObject(const UT_StringRef &key);
2343  void clearCachedPythonObjects();
2344  // cachedPythonObjects returns a UT_StringMap containing pointers to
2345  // PY_OpaqueObjects. The pointers are not null.
2346  const OP_PythonObjectCache &cachedPythonObjects() const
2347  { return myCachedPythonObjects; }
2348 
2349  bool loadExtraInputs(UT_IStream &is,
2350  const char *path = nullptr);
2351 
2352  void saveOverrides(std::ostream &os);
2353  void saveOverrides(std::ostream &os, OP_Node *root,
2354  const UT_String &rootpath,
2355  bool &added);
2356  void saveChildOverrides(std::ostream &os, OP_Node *root,
2357  const UT_String &rootpath,
2358  bool &added);
2359  bool loadOverride(UT_IStream &is);
2361  fpreal t, int thread,
2362  const char *parm_name,
2363  int vec_idx) override;
2364  bool isParmPendingOverride(const char *parm_name,
2365  int vec_idx) const override;
2366  OP_ERROR cookOverrides(OP_Context &c);
2368  virtual void removeOverrideDestination(OP_Node * /*dest*/) {}
2369  virtual void removeOverrideDestination(OP_Node * /*dest*/,
2370  int /*parm_idx*/) {}
2371 
2372  // Overriding virtual function in PRM_ParmOwner to run a command.
2373  void executeCommand(const char *command,
2374  std::ostream *out,
2375  std::ostream *err) const override;
2376 
2379  pushAsPwd() const override;
2380 
2381  OP_ERROR executeHscriptScript(const char *script,
2382  const OP_Context &context);
2383  OP_ERROR executePythonScript(const char *script,
2384  const OP_Context &context);
2385 
2386  void addPythonNodeError(const PY_Result &py_result);
2387 
2388  void saveInputs(std::ostream &os, bool compile_basic);
2389  bool loadInputs(
2390  UT_IStream &is,
2391  const char *path = nullptr,
2392  bool named = false);
2393  void saveNamedInputs(std::ostream &os, bool compile_basic);
2394  void saveNamedOutputs(std::ostream &os);
2395  bool loadNamedOutputs(
2396  UT_IStream &is,
2397  const char *path = nullptr);
2398 
2399  // These methods provide access to the options that can be stored on each
2400  // input of a node, if the node type enables this feature.
2401  void getEditableInputDataKeys(OP_InputIdx idx,
2402  UT_StringArray &keys) const;
2403  const UT_OptionEntry*getEditableInputData(OP_InputIdx idx,
2404  const UT_StringRef &key) const;
2405  bool setEditableInputData(OP_InputIdx idx,
2406  const UT_StringHolder &key,
2407  const UT_OptionEntry &value);
2408  void saveEditableInputData(std::ostream &os) const;
2409  bool loadEditableInputData(UT_IStream &is,
2410  const char *path);
2411  // Special case functions for getting and setting the input "name", which
2412  // just call the generic InputData functions.
2413  UT_StringHolder getEditableInputString(OP_InputIdx idx,
2414  const UT_StringRef &key) const;
2415  bool setEditableInputString(OP_InputIdx idx,
2416  const UT_StringRef &key,
2417  const UT_StringHolder &str);
2418 
2419  /// @{ If a subclass is interested in the saved input or output names, then
2420  /// it should override this method. The array will be filled during load.
2421  virtual UT_StringArray * getArrayForLoadedInputNames();
2422  virtual UT_StringArray * getArrayForLoadedOutputNames();
2423  /// @}
2424 
2425  void checkInputs(); // this method will check the
2426  // node references in all the inputs
2427 
2428  // Saves out extra information for this node to be included in a dialog
2429  // script that defines an operator type created from this one.
2430  virtual void saveDialogScriptExtraInfo(std::ostream &os);
2431 
2432  // Fills in the supplied default gallery entry with info from this node.
2433  virtual void createGalleryEntry(OP_GalleryEntry &entry);
2434 
2435  // When a string parameter can have the syntax: 'op:/...', use these
2436  // evaulate methods to do the approprate checking and reference building.
2437  // These methods will return a reference to the OP_Node if one is
2438  // referenced. If the syntax is something like:
2439  // op:/foo/bar[32]
2440  // Then the optime will be (32-1)/$FPS rather than the evaluation time.
2441  void evalOpPathString(UT_String &val, int pi, int vi,
2442  fpreal t, int &op_id, fpreal &op_time,
2443  int expanded = 1);
2444  void evalOpPathString(UT_String &val, const char *pn,
2445  int &pi, int vi, fpreal t,
2446  int &op_id, fpreal &op_time,
2447  int expanded=1);
2448  static int findOpFramePair(const char *path, int &op_id,
2449  fpreal &frame);
2450 
2451  /// Build a UT_XformOrder out of TRS and XYZ parameter values
2452  static void buildXformOrder(int trs, int xyz,
2453  UT_XformOrder &order);
2454 
2455  static const UT_XformOrder& buildXformOrder(int trs, int xyz );
2456 
2457  /// Translate a TRS parameter menu index into the UT_XformOrder type
2458  static UT_XformOrder::rstOrder getMainOrder( int trs );
2459  /// Translate a UT_XformOrder type into a TRS parameter menu index
2460  /// (inverse of getMainOrder())
2461  static int getMainOrderMenuIndex(UT_XformOrder::rstOrder order);
2462  /// Translate a XYZ parameter menu index into the UT_XformOrder type
2463  static UT_XformOrder::xyzOrder getRotOrder( int xyz );
2464  /// Translate a UT_XformOrder type into a XYZ parameter menu index
2465  /// (inverse of getRotOrder())
2466  static int getRotOrderMenuIndex(UT_XformOrder::xyzOrder order);
2467 
2468  /// NB: None of the getXformPivot() or getPivotParmValue() methods take
2469  /// any pivot compensation transform into account. It is up to the
2470  /// caller to account for any such transform.
2471  static UT_Vector3R getXformPivot(int trs,
2472  fpreal tx, fpreal ty, fpreal tz,
2473  fpreal px, fpreal py, fpreal pz);
2474  static UT_Vector3R getXformPivot(int trs,
2475  fpreal tx, fpreal ty, fpreal tz,
2476  fpreal px, fpreal py, fpreal pz,
2477  fpreal pivot_rx, fpreal pivot_ry,
2478  fpreal pivot_rz, bool inverse = false);
2479  static UT_Vector3R getPivotParmValue(int trs,
2480  fpreal tx, fpreal ty, fpreal tz,
2481  fpreal px, fpreal py, fpreal pz);
2482  static UT_Vector3R getPivotParmValue(int trs,
2483  fpreal tx, fpreal ty, fpreal tz,
2484  fpreal px, fpreal py, fpreal pz,
2485  fpreal pivot_rx, fpreal pivot_ry,
2486  fpreal pivot_rz, bool inverse = false);
2487 
2488  static void buildXform(int trs, int xyz,
2489  float tx, float ty, float tz,
2490  float rx, float ry, float rz,
2491  float sx, float sy, float sz,
2492  float px, float py, float pz,
2493  UT_Matrix4 &mat);
2494  static void buildXform(int trs, int xyz,
2495  double tx, double ty, double tz,
2496  double rx, double ry, double rz,
2497  double sx, double sy, double sz,
2498  double px, double py, double pz,
2499  UT_DMatrix4 &mat);
2500  static void buildXform(int trs, int xyz,
2501  float tx, float ty, float tz,
2502  float rx, float ry, float rz,
2503  float sx, float sy, float sz,
2505  UT_Matrix4 &mat);
2506  static void buildXform(int trs, int xyz,
2507  double tx, double ty, double tz,
2508  double rx, double ry, double rz,
2509  double sx, double sy, double sz,
2511  UT_DMatrix4 &mat);
2512  static void buildXform(int trs, int xyz,
2513  float tx, float ty, float tz,
2514  float rx, float ry, float rz,
2515  float sx, float sy, float sz,
2516  float s_xy, float s_xz, float s_yz,
2517  float px, float py, float pz,
2518  UT_Matrix4 &mat);
2519  static void buildXform(int trs, int xyz,
2520  double tx, double ty, double tz,
2521  double rx, double ry, double rz,
2522  double sx, double sy, double sz,
2523  double s_xy, double s_xz, double s_yz,
2524  double px, double py, double pz,
2525  UT_DMatrix4 &mat);
2526  static void buildXform(int trs, int xyz,
2527  float tx, float ty, float tz,
2528  float rx, float ry, float rz,
2529  float sx, float sy, float sz,
2530  float s_xy, float s_xz, float s_yz,
2532  UT_Matrix4 &mat);
2533  static void buildXform(int trs, int xyz,
2534  double tx, double ty, double tz,
2535  double rx, double ry, double rz,
2536  double sx, double sy, double sz,
2537  double s_xy, double s_xz, double s_yz,
2539  UT_DMatrix4 &mat);
2540  static void buildXform(
2541  const UT_Matrix4F::FullTransformModel &parms,
2542  UT_Matrix4F &mat);
2543  static void buildXform(
2544  const UT_Matrix4D::FullTransformModel &parms,
2545  UT_Matrix4D &mat);
2546  static void buildXform(int trs,
2547  float tx, float ty, float rz,
2548  float sx, float sy, float px, float py,
2549  UT_Matrix3 &mat);
2550  static void buildXform(int trs,
2551  double tx, double ty, double rz,
2552  double sx, double sy, double px, double py,
2553  UT_DMatrix3 &mat);
2554  static void buildXform(int trs,
2555  float tx, float ty, float rz,
2556  float sx, float sy, float s_xy,
2557  float px, float py,
2558  UT_Matrix3 &mat);
2559  static void buildXform(int trs,
2560  double tx, double ty, double rz,
2561  double sx, double sy, double s_xy,
2562  double px, double py,
2563  UT_DMatrix3 &mat);
2564 
2565  virtual int getTranslateParmIndex();
2566 
2567  // This is done only after a load to make sure that
2568  // all inputs have been resolved correctly.
2569  void resolveInputReferences();
2570 
2571  static void clearAllPendingUndoFlags();
2572 
2573  void clearUndoFlags() override;
2574  void setAnyUndoFlag() override;
2575  void saveForUndoInput();
2576 
2577  /// When doing bulk parameter modifications, they can be sandwiched between
2578  /// blockModify(true) and blockModify(false) statements as an optimization.
2579  /// Parameters modified during blockModify(true) will have their dirtiness
2580  /// propagation to other scene entities like nodes and parameters
2581  /// suppressed until blockModify(false) is called.
2582  ///
2583  /// @note This will NOT suppress events to addOpInterest() callbacks.
2584  /// In fact, blockModify(false) currently sends out an extraneous
2585  /// OP_PARM_CHANGED with parm index of -1.
2586  void blockModify(int on_off, int propagate = 1);
2587 
2588  int isBlockModify() const;
2589  bool isModifyWaiting() const;
2590  virtual void propagateEndBlockModify();
2591 
2592  // Only returns anything in the case of chops
2593  virtual const CL_Clip *getClip(OP_Context *context = nullptr);
2594 
2595  /// Returns the a chop network path suitable for storing motion effects
2596  /// associated with this node.
2597  void getMotionEffectsNetworkPath(UT_String &path);
2598 
2599  fpreal getLastCookTime() const;
2600  /// Return the last cook time as a formatted string.
2601  void getLastCookTime(UT_String &last_cook_time) const;
2602  /// Return the cook information as a formatted string.
2603  void getCookInfo(UT_String &info) const;
2604  /// Return the cook information in a UT_InfoTree.
2605  void getCookInfoTree(UT_InfoTree &tree) const;
2606 
2607  // Those operators which need a ramp editor must define this method.
2608  virtual UT_Ramp *getRamp();
2609 
2610  virtual int isCookingRender() const { return 0; }
2611  virtual void setCookingRender(int val);
2612 
2613  virtual void clearInterrupted()
2614  { clearInterruptedImpl(/*allow_recook*/true); }
2615  bool wasInterrupted() const
2616  { return flags().getInterrupted(); }
2617 
2618  // work-around to display warning message when export src or destination
2619  // are renamed. OP_Node::cook clears the error messages when a node export
2620  // changes so we had to save the fact that a rename conflict is pending
2621  void setRenameConflict()
2622  { myRenameConflict = 1; }
2623  void setRunningCreateScript(int onoff);
2624 
2625  // Base class methods to output code to a file or a stream:
2626  virtual int outputCode(OP_OutputCodeParms &, OP_Context &);
2627 
2628  virtual fpreal getTimeTransform(int input, fpreal t);
2629  virtual void getInputRes(int input, fpreal t,
2630  const OP_Context &context,
2631  OP_Context &input_context);
2632 
2633  // Utility methods:
2634  UT_TokenString & getHashCode(OP_Context &context, int group_mask =1);
2635  virtual UT_TokenString & getParmHashCode(OP_Context &context,
2636  int group_mask = 1);
2637 
2638  virtual int getNumInputsToHash();
2639  virtual OP_Node *getInputToHash(OP_InputIdx i);
2641  void clearHashCodeFlags();
2642  bool isHashCodeBuilt() const { return myBuiltHashCode;}
2643  void builtHashCode(bool b = true) { myBuiltHashCode = b; }
2644  void buildInputHashCode(UT_TokenString &string,
2645  OP_Context &context,
2646  int group_mask,
2647  int level);
2649  // If an interactive state was used to create this node, set it here.
2650  void setCreatorState(const char *s)
2651  { myCreatorState.harden(s); }
2652  const UT_String &getCreatorState() const { return myCreatorState; }
2653  void builtExplicitly(int yn) { myBuiltExplicitly = yn; }
2654  int wasBuiltExplicitly() const{ return myBuiltExplicitly; }
2655 
2656  bool matchesState(const char *state) const;
2657 
2658  /// Some nodes (VOPs and SHOPs) represent shaders, so this method
2659  /// returns node parameters that are used as shader parameters.
2660  virtual const PRM_Template *getShaderParmTemplates();
2661 
2662  // Don't even think about calling changeParmTemplate if you aren't
2663  // OP_Operator.
2664  virtual void changeParmTemplate(PRM_Template *new_template);
2665 
2666  // Deletes any input or output connections in excess of maximum allowed.
2667  virtual void ensureInputsAndOutputsAreValid();
2668 
2669  // Connect the node to an input. If branch_off is false and the input node
2670  // currently has outputs, the node will be inserted before the outputs.
2671  void connectToInputNode(OP_Node &inputnode,
2672  OP_InputIdx input_idx,
2673  int branch_off=0);
2674 
2675  // This method should be called when the user edits an overridden channel
2676  virtual int editCallback(CL_Track *track, fpreal t,
2677  fpreal new_value);
2678 
2679  // This mechanism allows users to communicate editing changes
2680  static OP_EditCallback getEditCallback(void *&data);
2681  //static void setEditCallback(OP_EditCallback func,
2682  //void *data);
2683 
2684  // These build an xform matrix based upon the given parameters.
2685  // The axis is the axis around which to rotate by 90 degrees. If
2686  // it is lower case, it will be rotated by +90, if it is upper case,
2687  // by -90. To not rotate at all, use '-'.
2688  static void buildQuadricXform(UT_Matrix4 &mat,
2689  float tx, float ty, float tz,
2690  float sx, float sy, float sz,
2691  char axis = 'y',
2692  float rx = 0.0f, float ry = 0.0f,
2693  float rz = 0.0f);
2694 
2695  static void buildQuadricXform(UT_DMatrix4 &mat,
2696  double tx, double ty, double tz,
2697  double sx, double sy, double sz,
2698  char axis = 'y',
2699  double rx = 0.0, double ry = 0.0,
2700  double rz = 0.0);
2701 
2702  static int buildOpMenu(
2703  OP_Network *net,
2704  PRM_Name *the_menu,
2705  int the_menu_size,
2706  int (*do_add)(OP_Node *) = nullptr,
2707  int start_item = 0,
2708  const PRM_Parm *parm = nullptr,
2709  int show_subnets = 1,
2710  int expand_subnets = 1,
2711  bool recurse = false);
2712 
2713  // Build the "Predefined Rules" menu that is common to several OPs
2714  // including Event and Group POPs. This is built from the text file table
2715  // OP<name>Rules, where name is the OP type (ie Event).
2716  static void buildPreDefRulesMenu(PRM_Name *menu,
2717  OP_PreDefRules &pdr);
2718 
2719  // Allows operators to use their own local table for variables and build
2720  // structures on demand... Implement the syntax highlight version only
2721  // if you need to resolve variables for syntax highlighting that are not
2722  // normally resolved by the generic resolveVariable() method.
2723  virtual const CH_LocalVariable *resolveVariable(const char *name);
2724  virtual const CH_LocalVariable *resolveExtraVariableForSyntaxHighlight(
2725  const char *name);
2726 
2727  // This value bumps whenever nodes are created/deleted/renamed.
2728  static int getNameSerialIndex();
2729 
2730  // export mapping techniques
2731  virtual void setMapping(int idx, int type,
2732  const char *label = nullptr);
2733  virtual int getMapping(int idx, const char *&label) const;
2734 
2735  // drag-n-drop receive methods
2736  virtual int acceptDragDrop(DD_Source &src, const char *label);
2737  virtual int testDragDrop(DD_Source &src);
2738  virtual void getDragDropChoice(DD_Source &src, DD_ChoiceList &c);
2739 
2740  // These methods are used to give quick overview information about a node
2741  bool hasComment() const;
2742  bool hasParmsNotAtFactoryDefault() const;
2743  bool hasAnimatedParms() const;
2744  bool hasChopOverriddenParms() const;
2745 
2746  /// traverseInputs calls 'callback' on this node and all its inputs.
2747  /// If callback returns true for any node, it will stop and return
2748  /// true, otherwise it will return false;
2749  /// @param callback Callback function
2750  /// @param data User data passed to the callback function
2751  /// @param opts A set of flags to configure the traversal:
2752  /// TRAVERSE_INTO_SUBNETS If input is a subnet, we continue
2753  /// traversing from its display node.
2754  /// TRAVERSE_REF_INPUTS Follow inputs marked as reference inputs
2755  /// TRAVERSE_ONLY_USED_INPUTS Follow only inputs used in the last cook
2756  /// TRAVERSE_PASSTHROUGH_INPUTS Use the getPassThroughNode to traverse
2757  /// through nodes that directly steal their
2758  /// input node's data.
2759  /// TRAVERSE_EXTRA_INPUTS Follow nodes which this node implicitly
2760  /// depends on.
2761  /// TRAVERSE_SIMULATION_INPUTS For nodes that are DOP parents, grab extra
2762  /// inputs from the simulation.
2763  /// TRAVERSE_COOKED_INPUT_INDEX_INPUTS
2764  /// Uses the cookedInputIndex method to
2765  /// traverse "passthrough"-type inputs for
2766  /// nodes that might trigger a cook when
2767  /// calling getPassThroughNode, but where we
2768  /// want to avoid triggering a cook.
2769  /// @param extra_interest_mask For extra inputs, this mask allows one to
2770  /// restrict which of those dependency types
2771  /// follow.
2772  //@{
2774  TRAVERSE_DEFAULT = 0x0000,
2775  TRAVERSE_INTO_SUBNETS = 0x0001,
2776  TRAVERSE_REF_INPUTS = 0x0002,
2777  TRAVERSE_ONLY_USED_INPUTS = 0x0004,
2778  TRAVERSE_PASSTHROUGH_INPUTS = 0x0008,
2779  TRAVERSE_EXTRA_INPUTS = 0x0010,
2780  TRAVERSE_SIMULATION_INPUTS = 0x0020,
2781  TRAVERSE_COOKED_INPUT_INDEX_INPUTS = 0x0040,
2782  };
2783  bool traverseInputs(bool (*callback)(OP_Node &, void *),
2784  void *data,
2785  TraverseOptions opts,
2786  OP_InterestType extra_interest_mask =
2787  OP_INTEREST_ALL);
2788  bool traverseInputs(bool (*callback)(const OP_Node &, void*),
2789  void *data,
2790  TraverseOptions opts,
2791  OP_InterestType extra_interest_mask =
2792  OP_INTEREST_ALL) const;
2793  //@}
2794 
2795  /// Using this node as a starting point, traverse our inputs recursively
2796  /// to get our best guess of the nodes that have been cooked to generate
2797  /// the current cooked result of this node.
2798  void getCookPathNodes(OP_NodeList &nodes);
2799 
2800  /// Traverses children of this node, calling 'callback' on all children.
2801  /// If callback returns true, the traversal stops at that node.
2802  bool traverseChildren(bool (*callback)(OP_Node &, void*),
2803  void *data,
2804  bool recurse_into_subnets);
2805 
2806  // Very specialized to see if this node (and optionally, any input
2807  // ancestors are also cooking.
2808  bool isCooking(bool include_ancestors) const;
2809 
2810  // This method returns true if the OP_Node makes use of its footprint
2811  // flag and false otherwise.
2812  virtual bool usesFootprint() const { return false; }
2813 
2814  void getExternalReferences(
2815  UT_StringArray &reflist,
2816  UT_StringArray *nodelist = nullptr,
2817  bool from_children_too = true,
2818  bool collapse = false,
2819  bool check_missing = false,
2820  bool show_missing_only = false);
2821  virtual bool getSaveWithVopnets();
2822  virtual void runDelScript();
2823  /// Overriden in VOPs to remove any channel refrences we may have
2824  /// to the node being deleted.
2825  virtual void preDelete() { }
2826 
2827  // Two functions for upcasting this node to a DOP_Parent. DOP_Parent
2828  // is a class which owns a simulation and has DOP_Nodes as children.
2829  virtual DOP_Parent *castToDOPParent() { return nullptr; }
2830  virtual const DOP_Parent *castToDOPParent() const { return nullptr; }
2831 
2832  // These provide a version which you can query without being above DOP.
2833  // This will also return dop parents for non-DOPs that have cache
2834  // like interfaces.
2836  { return (OP_DopParent *) castToDOPParent(); }
2837  virtual const OP_DopParent *castToOpDopParent() const
2838  { return (const OP_DopParent *) castToDOPParent(); }
2839 
2840  // This function upcasts this node to a VOP_CodeGenerator.
2841  // VOP_CodeGenerator is a class which generates VEX code from the VOPs
2842  // contained inside the node.
2843  virtual VOP_CodeGenerator *getVopCodeGenerator() { return nullptr; }
2844  virtual VOP_CodeGenerator *getVopAutoCodeGenerator() { return nullptr; }
2845  virtual const VOP_CodeGenerator
2846  *getVopAutoCodeGenerator() const{ return nullptr; }
2847  // Some nodes will only generate vop code generators on demand, this
2848  // will ensure they are built.
2849  virtual void buildVopCodeGenerator() {}
2850 
2851  // Return the manager that handles exported parameters from contained
2852  // Parameter VOPs. Only certain kinds of VOP nodes can have such a manager
2853  // (i.e. Subnet VOPs, VOP HDAs). Note that a node cannot have both a code
2854  // generator AND a parms manager because the code generator already has its
2855  // own parms manager.
2856  virtual VOP_ExportedParmsManager *getVopExportedParmsManager(
2857  bool create_if_needed=false)
2858  { return nullptr; }
2859 
2860  /// @{
2861  /// Methods to postpone the update of the code generator until ending
2862  /// the last (level zero) update. This avoids recalculation of parameters
2863  /// and vop signatures, which can be quite costly.
2864  // TODO: remove these two virtuals in farour of getVopCodeGenerator()
2865  // returning OP_VopCodeGenerator from which VOP_CodeGenerator
2866  // derives and which has these two virtuals available at OP level.
2867  virtual int beginVopCodeGeneratorUpdate() { return 0; }
2868  virtual void endVopCodeGeneratorUpdate(int update_level) {}
2869  /// @}
2870 
2871  // Build a command line for a VEX script to be called with. This does all
2872  // the channel evaluation and string expansion required. If there is an
2873  // error, 0 is returned (otherwise 1).
2874  int buildVexCommand(UT_String &result,
2875  const PRM_Template *templatelist,
2876  fpreal now,
2877  int start_parm = 0,
2878  int end_parm = INT_MAX,
2879  bool use_parmvop_tag=true
2880  );
2881  int buildVexCommandWithDependencies(OP_Node *owner,
2882  DEP_MicroNode *depnode,
2883  UT_String &result,
2884  const PRM_Template *templatelist,
2885  fpreal now,
2886  int start_parm = 0,
2887  int end_parm = INT_MAX,
2888  bool use_parmvop_tag=true
2889  );
2890 
2891  // Builds a VEX script using standardized parameter names.
2892  // "vexsrc": int for myself, shop, or script.
2893  // "script": raw vex script
2894  // "soppath": for the shop path.
2895  static PRM_ChoiceList theVexSrcParmMenu;
2896  static PRM_Name theVexSrcParmName;
2897  static PRM_Name theVexScriptParmName;
2898  static PRM_Name theVexNodePathParmName;
2899  static PRM_Name theVexClearParmName;
2900  static PRM_Name theVexCWDName;
2901  virtual void buildVexScript(UT_String &script, fpreal t,
2902  OP_Node *owner,
2903  UT_Map<int, bool> *visitlist = nullptr);
2904  virtual void buildVexScript(UT_String &script, fpreal t,
2905  DEP_MicroNode *depnode,
2906  UT_Map<int, bool> *visitlist = nullptr);
2907 
2908 
2909  // Returns true if vex shader has parameter by a given name.
2910  virtual bool hasVexShaderParameter(const char *parm_name);
2911 
2912 
2913  /// This function returns a string that encodes all the necessary
2914  /// information about a node-based material that helps the script-based
2915  /// materials to function properly. The string usually encodes info stored
2916  /// on child nodes, such as rendering properties or procedurals. Then
2917  /// the script node can use that info to provide necessary data
2918  /// for rendering.
2919  /// Returns true if the method provides usable information.
2920  virtual bool getScriptMaterialInfo( UT_String & mat_info,
2921  VOP_ScriptMaterialCodeMapper * mapper )
2922  { return false; }
2923 
2924  /// Returns the sub type name, if the node's operator wants to be
2925  /// saved as an HDA in a special way (ie, other than the regular
2926  /// scripted operator handling). The sub type name is then used
2927  /// to distinguish how to handle the HDA creation.
2928  virtual const char *getHDASubType()
2929  { return nullptr; }
2930 
2931  // Set the channel alias for a channel (or parm subindex). Returns true
2932  // if successful and false otherwise.
2933  bool setChannelAlias(PRM_Parm &parm, int subindex,
2934  const char *alias_name);
2935 
2936  void disconnectAllInputsOutputs(
2937  bool keep_selected,
2938  bool force_disconnect_outputs = false);
2939 
2940  void disconnectAllInputs();
2941  void disconnectAllOutputs();
2942 
2943  // Notify dependents that a parm name has changed.
2944  virtual void notifyParmRenameDependents(
2945  const UT_String &chan_name,
2946  const UT_String &old_chan_name );
2947 
2948  void writeChannel(CH_Channel *channel, std::ostream &os,
2949  const char *name, bool frames);
2950  void writeAllChannels(std::ostream &os, const char *name,
2951  bool frames, bool dochblock,
2952  bool dospareparms);
2953 
2954  // Run the callback function for a particular parm, and the callbacks
2955  // of any parms linked to this parm. Returns false if the node is
2956  // deleted while running the callback.
2957  bool triggerParmCallback(
2958  PRM_Parm *parmptr,
2959  fpreal now,
2960  int value,
2961  void *data,
2962  const UT_Options *options = nullptr) override;
2963 
2964  int64 getMemoryUsage(bool inclusive) const override;
2965  int64 getExtraInputMemoryUsage() const;
2966  static void printOpMemoryUsageStats(std::ostream &os);
2967 
2968  /// This method will unscope all the channels belonging to this op.
2969  /// If the recurse flag is set it will recurse through the children
2970  /// (at this level the recurse flag is ignored).
2971  virtual void unscopeChannels(bool recurse);
2972 
2973  /// This method will undisplay all the channels belonging to this op.
2974  /// If the recurse flag is set it will recurse through the children
2975  /// (at this level the recurse flag is ignored).
2976  virtual void undisplayChannels(bool recurse);
2977 
2978  /// This method will unpin all the channels belonging to this op.
2979  /// If the recurse flag is set it will recurse through the children
2980  /// (at this level the recurse flag is ignored).
2981  virtual void unpinChannels(bool recurse);
2982 
2983  /// This method takes a pattern string and will perform the ch_scope_op
2984  /// on each of our paramaeters that match the pattern. This method
2985  /// primarily supports the chscope command.
2986  virtual void setChannelScope(const char *pattern,
2987  OP_ScopeOp scope_op,
2988  const OP_ScopeOptions &scope_opts);
2989 
2990  /// A simple wrapper around getName() to allow us to abstract its
2991  /// functionality up to OP_NetworkBoxItem.
2992  const UT_StringHolder &getItemName() const override
2993  { return getName(); };
2994  bool setItemName(const UT_StringHolder &name) override;
2995 
2996  /// Caches the descriptive name to member data, and returns that. The
2997  /// cache is automatically dirtied in opChanged.
2998  const UT_StringHolder &getCachedDescriptiveName();
2999 
3000  // This function is called when our spare parm definition is changing.
3001  bool changeSpareParms(UT_IStream &istream,
3002  UT_String &errors) override;
3003  // This function is called during the changeSpareParms operation when
3004  // one of our parameters is being removed.
3005  void spareParmRemoved(const char *parmname) override;
3006 
3007  // This is a secondary parm list where all obsolete parameters are
3008  // placed (if any)
3011  PRM_ParmList *&obsolete_parms) override;
3012 
3013  unsigned referenceAllParameters(
3014  OP_Parameters *from,
3015  bool relative_references = true) override;
3016 
3017  void clearVersionUserData();
3018  void updateVersionUserData();
3019 
3020  /// After the nodes parameter list is loaded, syncNodeVersionIfNeeded() is
3021  /// called to perform any necessary upgrades if the version number of
3022  /// the loaded node (taken from user data) is different from the node
3023  /// type's version number (getOperator()->getVersion()). Use the
3024  /// from_version parameter to override the node current version.
3025  /// If needed, this will call syncNodeVersion(). After synching, the node's
3026  /// version user data will be set to the current version if
3027  /// update_node_version is true.
3028  void syncNodeVersionIfNeeded(
3029  bool *node_deleted,
3030  const char *from_version = nullptr,
3031  bool update_node_version = false);
3032 
3033  /// Sync the node assuming that it is currently at old_version to the
3034  /// current_version. By default, this will call the corresponding
3035  /// OTL_SYNCNODEVERSION section if it exists.
3036  void syncNodeVersion(
3037  const char *old_version,
3038  const char *current_version,
3039  bool *node_deleted) override;
3040 
3041  // Sets the given stamping parameter.
3042  // Returns true if the param was changed. Note that we may return false
3043  // even if this was a valid operation as param might have already been
3044  // set to the given value.
3045  // If the warned variable is given, then we only warn if its contents
3046  // is false. Then in that case, we will set it to true when needed.
3047  bool setGlobalFloatParam(const char *param,
3048  fpreal value,
3049  bool *warned);
3050  bool setGlobalStringParam(const char *param,
3051  const char *strvalue,
3052  bool *warned);
3053 
3054  // This allows one to prevent chop cooking due to parameter modifications
3055  // until the outermost block is done.
3056  void beginPropagateModification();
3057  void endPropagateModification();
3058 
3059  // Add any OTL-defined operators used by this node to the specified table.
3060  virtual void getActiveOperatorsDefinedByOTL(
3061  UT_Set<OP_Operator *> &active_operators) const;
3062 
3063  // Returns true if we are in the middle of a call to sendBulkNotifications,
3064  // Or doing some other operation that involves sending out a whole bunch
3065  // of change notifications all at once. This allows VOP Networks to avoid
3066  // over-cooking.
3067  static bool getDoingBulkNotification();
3068  static bool isDirectorDoingBulkNotification();
3069 
3070  /// Returns whether multi-inputs on this particular op might have different
3071  /// names for each of the inputs, or if the name will always be the same for
3072  /// all the inputs.
3073  virtual bool hasDifferentMultiInputs() const;
3074 
3075 
3076  virtual bool canCreateNewOpType() const;
3077  static bool createNewOpType
3078  (OP_Node *node,
3079  UT_String &errors,
3080  const char *type_name=nullptr,
3081  const char *type_label=nullptr,
3082  const char *otl_file=nullptr,
3083  const char *meta_source=nullptr,
3084  const char *comment=nullptr,
3085  const char *version=nullptr,
3086  const char *new_name=nullptr,
3087  int minimum_inputs=-1,
3088  int maximum_inputs=-1,
3089  bool ignore_external_references=false,
3090  bool compress_contents=false,
3091  bool force=false,
3092  int *new_node_id=nullptr,
3093  bool compile_contents = false,
3094  bool change_node_type = true,
3095  bool create_backup = true);
3097  virtual UT_String *getMaterialIconFilename() { return nullptr; }
3098  virtual void setMaterialIconFilename(const char * /*icon_file*/) {}
3099  virtual IMG_Raster *getMaterialIconImage() { return nullptr; }
3100  virtual bool getMaterialIconAllowRegenerateFlag() { return true; }
3101  virtual void setMaterialIconAllowRegenerateFlag(bool) {}
3102 
3103  // Call these functions when making a lot of calls to opChanged on a
3104  // list of nodes. These functions make sure that VOP Networks only get
3105  // one change notification no matter how many child nodes are about
3106  // to send any number of change events.
3107  // @parm caller The node that starts the bulk notifications, if applicable.
3108  static void startBulkNotifications(
3109  const OP_NodeList &changed,
3110  OP_Node *caller = nullptr);
3111  static void endBulkNotifications(
3112  const OP_NodeList &changed);
3113 
3114  /// This is overriden in VOPs. It returns true if the input at input_idx
3115  /// will need *and* can perform autoconversion of its input type to the
3116  /// type it needs. If autoconversion is not needed, or is impossible,
3117  /// this will return false.
3118  virtual bool willAutoconvertInputType(OP_InputIdx input_idx);
3119 
3120  bool isDependentOn(OP_Node* other_node, PRM_Parm* parm);
3121 
3122  // Gets whether the input at idx is collapsed. Currently this is only used
3123  // in VOPs.
3124  virtual bool getIsInputVisibleDefault(OP_InputIdx idx);
3125 
3126  // Debugging function to confirm that all PRM_Template's are consistent
3127  // with their parameters.
3128  bool verifyTemplatesWithParameters() const;
3129 
3130  // Same as getInputReference, except using a named reference.
3131  OP_Input *getNamedInputReference(
3132  const OP_ConnectorId& input_name, bool grow);
3133  OP_Input *getNamedInputReferenceConst(
3134  const OP_ConnectorId& input_name) const;
3135 
3136  OP_Node *getNamedInput(const OP_ConnectorId& input_name,
3137  bool mark_used=false) const;
3138  /// Note that this function only looks through currently connected
3139  /// inputs for the name, not through all possible input names on
3140  /// this node. mapInputNameToIndex does that instead.
3141  virtual OP_InputIdx getInputFromName(const UT_String &in) const;
3142  virtual OP_OutputIdx getOutputFromName(const UT_String &out) const;
3143  virtual void getInputName(UT_String &in, OP_InputIdx idx) const;
3144  virtual void getOutputName(UT_String &out, OP_OutputIdx idx) const;
3145  static UT_StringHolder defaultInputName(OP_InputIdx idx);
3146  static UT_StringHolder defaultOutputName(OP_OutputIdx idx);
3147 
3148  OP_OutputIdx getSpareOutputFromName(const UT_StringHolder& name) const;
3149 
3150  OP_InputIdx getInputFromUniqueName(
3151  const OP_ConnectorId& id) const;
3152  UT_Optional<OP_OutputIdx> getOutputFromUniqueName(
3153  const OP_ConnectorId& id) const;
3154 
3155  // Returns the unique name of the input at index idx. Creates the input if
3156  // grow is set to true.
3157  void getUniqueInputName(OP_ConnectorId& id_out,
3158  OP_InputIdx idx, bool grow);
3159  bool getUniqueInputNameConst(
3160  OP_ConnectorId& id_out, OP_InputIdx idx) const;
3161 
3162  void getUniqueOutputName(OP_ConnectorId& id_out,
3163  OP_OutputIdx idx);
3164  bool getUniqueOutputNameConst(
3165  OP_ConnectorId& id_out, OP_OutputIdx idx) const;
3166 
3167  /// New input functions that use names instead of indices.
3168  virtual OP_ERROR setNamedInput(const OP_ConnectorId& input_name,
3169  OP_Node *op,
3170  const OP_ConnectorId* output_name = nullptr);
3171 
3172  virtual OP_ERROR setNamedIndirectInput(
3173  const OP_ConnectorId& input_name,
3174  OP_IndirectInput *input);
3175  virtual OP_ERROR setNamedInputReference(
3176  const OP_ConnectorId& input_name,
3177  const char *label, int,
3178  const OP_ConnectorId* output_name = nullptr);
3179 
3180  OP_ERROR insertNamedInput(
3181  const OP_ConnectorId& input_name, OP_Node *op,
3182  const OP_ConnectorId* output_name);
3183  OP_ERROR insertNamedIndirectInput(
3184  const OP_ConnectorId& input_name,
3185  OP_IndirectInput *input);
3187  /// Returns input for the spare parm input.
3188  virtual OP_Input *getParmInput(OP_OutputIdx idx) const
3189  { return nullptr; }
3191  /// Overriden in VOPs.
3192  virtual void onCreated() { }
3193 
3194  virtual bool isOrderedInput(const OP_ConnectorId& input_name) const;
3195 
3196  /// Returns the name of the first connection from node "who" to this node,
3197  /// or an empty string if "who" is not an input.
3198  OP_ConnectorId whichNamedInputIs(const OP_Node *who) const;
3199 
3200  /// Returns the index of the first connection of an indirect input.
3201  OP_ConnectorId whichNamedInputIs(const OP_IndirectInput *who) const;
3202  virtual bool willAutoconvertNamedInputType(
3203  const OP_ConnectorId& input_name);
3204 
3205  /// Note: Use these carefully, since they assume that no inputs are actually
3206  /// added or removed (or renamed) during the traversal.
3207  OP_ConnectorInputIter traverseInputs(OP_ConnectorInputIter* prev_iter);
3208  OP_ConnectorInputIter traverseConnectedInputs(OP_ConnectorInputIter* prev_iter);
3209  OP_ConnectorInputIter getTraverseEndIterator();
3210 
3211  unsigned getInputsArraySize()
3212  { return myInputs.entries(); }
3213  /// Deprecated in favour of getInputsArraySize()
3214  SYS_DEPRECATED(17.0) unsigned isInput(unsigned idx)
3215  { return (getInputsArraySize() > idx) ? 1 : 0; }
3216 
3217  /// Retrieve a sorted list of local variables visible to this OP_Node.
3218  void getLocalVarNames(UT_StringArray &out_vars);
3219 
3220  // Forcibly enable evaluation of local variables outside of cooking code
3221  // paths so that the last cooked value can be used for things like
3222  // pivot values for handles.
3223  bool setLocalVarActive(bool f)
3224  {
3225  bool old = myLocalVarActive;
3226  myLocalVarActive = f;
3227  return old;
3228  }
3230  /// Get the myLocalVarActive flag
3231  bool isLocalVarActive() const
3232  { return myLocalVarActive; }
3233 
3234  /// Return a UT_AttributeEvaluator for dealing with the evaluation of
3235  /// local variables designated by an "@" prefix.
3236  virtual UT_AttributeEvaluator *createAttributeEvaluator(const char *name);
3237  virtual void getAttributeEvaluatorNames(UT_StringArray &names);
3238 
3239  void recomputeCompiledHash();
3240 
3241  /// Clears the compiled hash (needed when switching from a compiled library
3242  /// definition to one that is not compiled).
3243  void clearCompiledHash()
3244  { myCompHash = DEFAULT_COMP_HASH_VALUE; }
3245 
3246  /// You should use opChanged() instead. This is only for very special
3247  /// cases. If you don't know you are a special case, you aren't.
3248  void directSendEvent(OP_EventType type, void *data=nullptr)
3249  { sendEvent(type, data); }
3250 
3251  virtual bool scopedChannelsDirty();
3252 
3253  /// This mechanism allows users to evaluate active layer contribution
3254  /// without needing to link against CHOP.
3255  virtual bool getActiveLayerContribution(const UT_String &track_name,
3256  fpreal t, fpreal &value, fpreal &weight)
3257  { return false; }
3258 
3259  /// Try to resolve exports on CHOP Channel Nodes from a value parameter
3260  /// within the array.
3261  virtual bool resolveExport(const PRM_Parm* p, int subindex,
3262  CH_ChannelRef& out_export )
3263  { return false; }
3264 
3265  /// Creates or moves an existing visualizer in this network to
3266  /// this nodes output.
3267  virtual bool addOrMoveVisualizerToOutput(int outputidx)
3268  { return false; }
3269 
3270  const PRM_Parm *traverseRef(
3271  int *sub_idx,
3272  fpreal time,
3273  int parm_idx,
3274  int vec_idx) const override;
3275 
3276  OP_Bundle * getParmBundle(const char* parm_name, int vector_index,
3277  UT_String &pattern, OP_Network *creator,
3278  const char *filter, bool subnet_inclusion);
3279 
3280  /// For node types with no other default color override, this is the
3281  /// final fallback default color for all nodes.
3282  static const UT_Color &getGlobalDefaultColor();
3283 
3284  /// The following methods are to be used to implement getW() and getH() in
3285  /// sub-classes. They are in absolute, pan-and-scale independent UI units.
3286 
3287  /// Get the width of flags.
3288  static fpreal getFlagWidth();
3289  /// Get the default node height.
3290  static fpreal getNodeHeight();
3291  /// Get the default width of the "node button" (the part of the node
3292  /// that you can drag and click on that isn't flags).
3293  static fpreal getNodeButtonWidth();
3294  /// Get the default connector height.
3295  static fpreal getConnectorHeight();
3296 
3297  /// Returns true if we are allowed to destroy the specified nodes. If
3298  /// nodes is non-null, we test those nodes. If nodes is null, we test
3299  /// the picked nodes of the src_net. The return value assumes that all
3300  /// specified nodes will be destroyed, which is important because it
3301  /// may be safe to delete node A iff node B is also going to be deleted.
3302  static bool canDestroyNodes(OP_Network *src_net,
3303  const OP_NodeList *nodes);
3304 
3305  /// Add an error to the given error manager, collapsing chains
3306  /// of invalid sources.
3307  static void addInputNodeErrorToManager(UT_ErrorManager *error,
3308  OP_Node *src);
3309 
3310  /// Must be implemented to associate this node to a viewer state.
3311  /// @parm default_state_name should be set with the viewer state type name.
3312  /// OP_Node implementation first looks for a 'viewerstate' node string
3313  /// parameter. The parameter can be added as a spare parameter to any node.
3314  /// If the node is an HDA it can define a default state section.
3315  /// Otherwise, the operator name is returned as a default state name.
3316  virtual void getDefaultState(UT_String &default_state_name);
3317 
3318  // If this node sets a context option to a specific value, we can clear
3319  // this option dependency for this node (and its outputs), because we
3320  // know that changing this option value past this node won't affect the
3321  // cooking of our input nodes, even if they use this context option. One
3322  // exception to this is if this node sets the context option as a
3323  // function of the option value handed to it. This exception is dealt with
3324  // when transferring option dependencies from our inputs to this node.
3325  //
3326  // Another exception is when the context used to cook this node has a
3327  // non-default (i.e. set by a node) value for the option. Because our
3328  // context option change may get "popped" by a node higher up the chain,
3329  // we must assume that nodes above this "pop" node depend on this option
3330  // set by one of our outputs, so we need to recook when that node changes
3331  // option value (even though we overwrite it). This isn't a problem when
3332  // the option is set to a default value because dependencies on default
3333  // values are tracked by micro nodes, so changing the default will force
3334  // a recook from the top of the chain. Testing for this case is why we
3335  // need to be passed the context passed to this nodes cook method.
3336  void clearInputContextOptionDepIfSafe(
3337  const UT_StringHolder &opt,
3338  const OP_Context &context);
3340  // CHOP Transform Tracks
3341  virtual bool hasTransformTracks() const { return false; }
3342  virtual bool evaluateTransformTracks( OP_Context &context, OP_EvaluateTransformTracksArgs &args ) { return false; }
3343  virtual bool evaluateTransformTracksTargets( OP_Context &context, OP_NodeList &nodes, OP_Node *caller) { return false; }
3344 
3345 
3346 
3347  const UT_StringHolder &getOriginalOperatorName() const;
3348  void setOriginalOperatorName(const UT_StringHolder & optype);
3349 
3350  /// Get the op table name and the op name concatenated together to get a
3351  /// unique name.
3352  /// Returns full name with table, including namespace and version tags
3353  /// if there are any, eg "artistA::table/op::2.0"
3354  void getOriginalOperatorTableAndName(UT_WorkBuffer &name) const;
3355  void getOriginalOperatorTableAndName(UT_String &name) const;
3356 
3357 
3358 protected:
3359 
3360  OP_Node(OP_Network *parent, const char *name, OP_Operator *entry);
3361  ~OP_Node() override;
3362 
3363  /// Implement the method from PRM_ParmOwner
3364  void doGetFullPath(UT_WorkBuffer &str) const override;
3365 
3366  /// Retrieve a list of the local variables visible to this OP_Node.
3367  /// This list is unsorted and may contain duplicates.
3368  virtual void buildLocalVarNames(UT_StringArray &out_vars);
3369 
3371  const UT_StringRef &function) const override;
3372 
3373  /// Resolves any inputs for which the names were not found during
3374  /// actual loading.
3375  void resolveUnresolvedLoadedInputs();
3376 
3377  /// Called when loadNetwork finishes loading the whole parent network of
3378  /// this node.
3379  void finishedLoadingParentNetwork();
3380 
3381  void setNewParent( OP_Network *new_parent );
3382 
3383  static void bumpNameSerialIndex();
3384 
3385  /// @{
3386  /// Methods to disallow node deletion during the execution of a script.
3387  void beginScriptBlockingDel()
3388  { myScriptsBlockingDelCount += 1; }
3389  void endScriptBlockingDel()
3390  { myScriptsBlockingDelCount -= 1; }
3391  /// @}
3392 
3393  void setLegacyConnectingInputIndex(OP_InputIdx index)
3394  { myLegacyConnectingInputIndex = index; }
3395 
3396  // All external references must be removed by the time this function
3397  // returns!
3398  virtual void clearAndDestroy();
3399 
3400  // invalidate any cached data
3401  virtual void clearCache();
3402 
3403  void clearInterruptedImpl(bool allow_recook);
3404 
3405  // "cookMe" is where the actual work is done.
3406  // The error is returned (OP_ERR_NONE on success).
3407  virtual OP_ERROR cookMe(OP_Context &context) = 0;
3408 
3409  // "bypassMe" is used to cook the op when the bypass flag is set.
3410  // The copied_input parameter should be set to indicate which input was
3411  // copied. Use -1 if no input was copied.
3412  // The error is returned (OP_ERR_NONE on success).
3413  virtual OP_ERROR bypassMe(OP_Context &context, int &copied_input) = 0;
3414 
3415  // The following two functions are called from evaluateAllParms() so that
3416  // subclasses may hook into it to do some work before and after evaluating
3417  // all the parameters.
3418  virtual void doOverridePreCook() { }
3419  virtual void doOverridePostCook() { }
3420 
3421  // These "serial" numbers are used for keeping track of how many sources
3422  // are accessing us. Only call getSourceCount() when locked inside
3423  // getCookLock()!
3424  int getSourceCount() const;
3425  virtual int bumpSourceCount(int d);
3426 
3427  // This is what you should override to do your own OP specific cooking.
3428  // This should not be called other than from pubCookInputGroups.
3429  virtual OP_ERROR cookInputGroups(OP_Context &context, int alone = 0);
3430 
3431  // I/O methods
3432  virtual OP_ERROR saveIntrinsic(std::ostream &os,
3433  const OP_SaveFlags &flags);
3434  virtual OP_ERROR save(std::ostream &os, const OP_SaveFlags &flags,
3435  const char *path_prefix = "",
3436  const UT_StringHolder &name_override = UT_StringHolder());
3437  OP_ERROR saveUserDataPacket(std::ostream &os,
3438  const char *path_prefix,
3439  const UT_StringHolder &node_name);
3440 
3441  bool loadIntrinsicParentUneditable(
3442  UT_IStream &is,
3443  const char *path = nullptr);
3444  bool loadIntrinsic(
3445  UT_IStream &is,
3446  const char *path = nullptr);
3447  virtual bool loadPacket(UT_IStream &is, short class_id,
3448  short sig, const char *path=nullptr);
3449  virtual bool loadPacket(UT_IStream &is, const char *token,
3450  const char *path=nullptr);
3451  virtual bool load(UT_IStream &is,
3452  const char *ext="",
3453  const char *path = nullptr);
3454 
3455  // load only things that that an uneditable parent deems uneditable, e.g.
3456  // input/output connections. This is so that it can be matched to the OTL
3457  // rather than the editable contents of a node.
3458  bool loadParentUneditable(UT_IStream &is,
3459  const char *ext="",
3460  const char *path = nullptr);
3461 
3462  // this called when the entire network is done loading
3463  virtual void loadStart();
3464  virtual void loadFinished();
3465 
3466  // Loads the OTL_CONTENTS_SECTION for our OTL definition, if it exists,
3467  // using the syncContents method.
3468  void loadContentsSection();
3469 
3470  // This is a dummy virtual that just exists to be overridden by
3471  // OP_Network. See that class for more description.
3472  virtual bool syncContents(UT_IStream &is);
3473 
3474  /// Sets the flag idicating if the node is synced (matched) to the HDA.
3475  void setMatchesOTLDefinition(int matches);
3476 
3477  virtual const char *getFileExtension(int binary) const = 0;
3478  virtual const char *getDataFileExtension(int binary) const;
3479 
3480  /// This will set the time dependent flag based on parms, inputs and/or
3481  /// extra (non-graph) inputs. This can be overridden by subclasses to have
3482  /// more control over a node's time dependent flag by forcibly calling the
3483  /// bass class method with false for these parameters.
3484  ///
3485  /// @param do_parms Controls whether this node should become time dependent
3486  /// if any of its own cooking parameters are time dependent.
3487  /// @param do_inputs Controls whether the node should become time dependent
3488  /// if any of its used inputs are time dependent
3489  /// @param do_extras Controls if this node should become time dependent if
3490  /// any of the "extra" inputs (see
3491  /// OP_Node::addExtraInput()) nodes are time dependent.
3492  /// These extra inputs typically nodes referenced by the
3493  /// expressions on this node's parameters.
3494  virtual void checkTimeDependencies(int do_parms=1,
3495  int do_inputs=1,
3496  int do_extras=1);
3497  // This will gather context option dependencies based on parms,
3498  // inputs and extra (non-graph) inputs. These dependencies are
3499  // applied to the data micro node and the node itself.
3500  virtual void checkContextOptionDependencies(int do_parms);
3501 
3502  // To allow our sub-classes to send events, we make this protected.
3503  void sendEvent(OP_EventType type, void *data=nullptr);
3504 
3505  // haveSeenDataModification() can be used by sub-classes to decide if they
3506  // need to respond to a particular modification notice.
3507  int haveSeenDataModification(exint modification_id);
3508 
3509  // If you sub-class propagateModification, then be sure to call this
3510  // OP_Node base class method *last*.
3511  //
3512  // This routine will return TRUE if the modification is a new one for this
3513  // node. FALSE will be returned if the modification has been seen before.
3514  //
3515  // Note that "by_whom" is the immediate input node that caused the
3516  // propagation to "this" node.
3517  virtual int propagateModification(OP_Node *by_whom,
3518  OP_EventType reason,
3519  int parm_index,
3520  OP_PropagateData &prop_data);
3521 
3522  // Use this to obtain the cook cache.
3523  // @pre The caller has locked myCookLock if it is currently being cooked.
3524  OP_Cache * getCookCache() { return &myCache; }
3525 
3526  static void cmd_locate(CMD_Args &);
3527 
3528  virtual void saveFlagsForUndo();
3529  void saveForUndoLayout();
3530 
3531  static void saveForUndoDelete(OP_NodeList &nodes);
3532 
3533  /// Clears all cook dependencies (i.e., items that may cause it to cook)
3534  void clearDependency();
3535 
3536  /// This function will dirty our data if the given time is different from
3537  /// our last cooked time.
3538  ///
3539  /// This function is normally called from cook() but subclasses can prevent
3540  /// this with flags().setClearDependency(false). In that case, subclasses
3541  /// are responsible for calling this function at the appropriate time. This
3542  /// is primarily for nodes which cache their data across time. In that
3543  /// case, if they did _not_ reuse their cached data, then
3544  /// dirtyForTimeChange() needs to be called.
3545  ///
3546  /// @returns true if node was dirtied, false otherwise.
3547  bool dirtyForTimeChange(fpreal t)
3548  {
3549  if (isCookedTime(t))
3550  return false;
3551 
3552  OP_DataMicroNode &dm = dataMicroNode();
3553  OP_DataMicroNode &pm = parmListMicroNode();
3554  dm.setDirty(true);
3555  if (&dm != &pm && pm.isTimeDependent())
3556  pm.setDirty(true);
3557 
3558  return true;
3559  }
3560 
3561  // clone dependencies from the proxy. proxy is no longer valid
3562  // after the clone!
3563  virtual void cloneFromProxyRefNode( OP_Network *proxy );
3564  // clone a new proxy node. this node is no longer valid after this!
3565  virtual OP_Network * cloneToProxyRefNode();
3566  void stealDependents( OP_Node *other );
3567 
3568  bool hasOpDependents()
3569  { return !myOpDependents.isEmpty(); }
3570  virtual int hasProxyRefNodes() const
3571  { return 0; }
3572  virtual void moveProxyRefNodes( OP_Network * /*dest */ ) { }
3573  void clearOpReferences();
3574  virtual void rebuildOpDependents( bool proxy_only );
3575 
3576  /// removeOpDependent() returns the number of dependents removed
3577  virtual int removeOpDependent(
3578  int op_id, const PRM_RefId &ref_id,
3580  virtual int removeOpDependent(
3581  int op_id, OP_InterestType mask = OP_INTEREST_ALL );
3582 
3583  // new method for dependencies: use the PRM_TYPE_OP_REF_*
3584  // in your parm template to add your dependency.
3585  // override this to do special cases, make sure you call the base class
3586  // first before adding your own dependencies!
3587  void buildOpDependencies() override;
3589  CH_Channel *ch,
3590  CH_CHANGE_TYPE reason) override;
3591 
3592  void notifyOpDependents( OP_InterestType interest,
3593  bool recurse );
3594  virtual void moveDependencies( OP_Node *from_node );
3595  // Two functions for notifying dependent nodes of name changes. The
3596  // non-virtual function is the one that should be called to do the
3597  // update. It calls the virtual function to do the actual updating,
3598  // and generate a list of dependent nodes that were changed. Then it
3599  // forces a recook on the changed nodes.
3600  void notifyRenameDependents( const UT_String &full_from );
3601  virtual void notifyRenameDependents( const UT_String &full_from,
3602  OP_NodeList &cook_nodes );
3603  // Two functions for notifying referencing nodes of name changes. The
3604  // non-virtual function is the one that should be called to do the
3605  // update. It calls the virtual function to do the actual updating,
3606  // and generate a list of dependent nodes that were changed. Then it
3607  // forces a recook on the changed nodes.
3608  void notifyRenameReferences( const UT_String &full_from );
3609  virtual void notifyRenameReferences( const UT_String &full_from,
3610  OP_NodeList &cook_nodes );
3611  // this method is called to alert this op that its dependency has
3612  // changed. if it's a name interest, then the old full path is given
3613  virtual void handleOpDependency( int referenced_op_id,
3614  const OP_Dependency &op_dep,
3615  OP_InterestType interest_type,
3616  bool &need_cook,
3617  const char *old_fullpath,
3618  const char *old_cwd,
3619  const char *old_chan_name );
3620  virtual void buildParmDependency( int parm_index );
3621 
3622  void addOpNameReference(
3623  const PRM_RefId &ref_id, const UT_String &op_path,
3625  // chan_name must be real channel name not an alias
3626  void addChannelNameReference(
3627  const PRM_RefId &ref_id,
3628  const UT_StringRef &op_path,
3629  const UT_StringRef &chan_name,
3631 
3632  OP_Node *getNodeOrCreateProxy(const UT_StringRef &op_path);
3633 
3634  void addOpReference( const PRM_RefId &ref_id, OP_Node *node,
3635  const PRM_RefId &source_ref_id,
3637 
3638  void removeOpReference(
3639  const PRM_RefId &ref_id,
3641  void removeOpReference(
3642  const PRM_RefId &ref_id,
3643  int op_id,
3645 
3646  /// This function takes the given parm string value containing an op path
3647  /// and does a search and replace given the old and new op paths.
3648  ///
3649  /// value_str - the old parm value to modify
3650  /// new_fullpath - the new path value to change to
3651  /// old_fullpath - the old path that needs changing
3652  /// old_cwd - the old path that the parm value was relative to
3653  /// new_cwd - the new path that the parm value is to be relative to
3654  ///
3655  /// The reason for old_cwd & new_cwd is when collapsing a node into a
3656  /// subnet. We need to figure out the new path references of the collapsed
3657  /// subnet since it has changed location. We match using the old_cwd but
3658  /// take the new path relative to new_cwd. Note that in this situation,
3659  /// old_fullpath is the same as new_fullpath.
3660  bool changeOpPathRef( UT_String &value_str,
3661  const char *new_fullpath,
3662  const char *old_fullpath,
3663  const char *old_cwd,
3664  const char *new_cwd );
3665 
3666  // handy functions for dealing with string parms that can have the
3667  // op:/path[frame] syntax
3668  static bool getStringParmOpPath(
3669  PRM_Parm &parm, int vi, UT_String &oppath,
3670  int thread );
3671  void handleStringParmOpPathDependency(
3672  int parm_index, int vi,
3673  const char *new_fullpath,
3674  const char *old_fullpath, const char *old_cwd );
3675 
3676  // Only OP_Network should call notifyNodeDeletion()
3677  void notifyNodeDeletion();
3678 
3679  // Only notifyNodeDeletion() should call nodeDeleted().
3680  // nodeDeleted() - gets called every time a node is deleted
3681  virtual void nodeDeleted(OP_Node *op, int propagate=1);
3682 
3683  void startCookTimer(const OP_Context &context);
3684  void stopCookTimer(const OP_Context &context);
3685 
3686  virtual const char *getCookTimerLabel(const OP_Context &context) const;
3687 
3688  // Overrides permission errors so that we don't have problems when cooking.
3689  void permissionError(const char *chname = nullptr) override;
3690 
3691  // Add an error for the invalid input given by input_idx
3692  void addInputError(OP_InputIdx input_idx);
3693 
3694  // Add an error for the given node having failed to load.
3695  void addInputNodeError(OP_Node *src);
3696 
3697 protected:
3698  /// This function is currently only used by VOPs. It checks if an input
3699  /// on the subnet is connected inside the subnet. The default implementation
3700  /// here simply returns false to preserve existing behaviour for all other
3701  /// contexts.
3702  virtual bool isInputConnectedInsideSubnet(
3703  OP_InputIdx input_idx) const;
3704  virtual bool isNamedInputConnectedInsideSubnet(
3705  const OP_ConnectorId& input_name) const;
3707  // notifier when this node is unlocked
3708  virtual void nodeUnlocked() { ; }
3709 
3710  // These functions must be used with care!
3711  virtual void setUniqueId(int id);
3712  void changeOpDependentUniqueId( int old_id, int new_id );
3713  void changeOpReferenceUniqueId( int old_id, int new_id );
3714  virtual void clearUniqueId();
3715 
3716  void setAllowBuildDependencies( int yesno )
3717  { myAllowBuildDependencies = yesno; }
3718  int allowBuildDependencies() const
3719  { return myAllowBuildDependencies; }
3720 
3721  /// Evaluate all parameters for this operator. This is used for scripted
3722  /// Ops to make sure that our dependencies get set up properly.
3723  void evaluateAllParms(fpreal t);
3724 
3725  /// Override and assign any external (file) references to the reflist,
3726  /// and if nodelist is non-null, the full pathname of the node with the
3727  /// reference.
3728  virtual void getMyExternalReferences(
3729  UT_StringArray &reflist,
3730  UT_StringArray *nodelist = nullptr,
3731  bool collapse = false,
3732  bool check_missing = false,
3733  bool show_missing_only=false);
3734 
3735  void getExternalFiles(UT_StringArray &files,
3736  const char *stringparm,
3737  int framestart, int frameend,
3738  bool collapse,
3739  bool check_missing,
3740  bool show_only_missing,
3741  UT_KnownPath path);
3742 
3743  /// Rather than overloading the descriptive name, you can instead
3744  /// just provide a parameter name that will be evaluated to
3745  /// become the descriptive name.
3746  virtual void getDescriptiveParmName(UT_String &str) const;
3747 
3748  /// Additional information that should be provided at the network
3749  /// level in addition to the name.
3750  /// By default will inspect the getDescriptiveParmName.
3751  virtual void getDescriptiveName(UT_String &str) const;
3752 
3753  /// Marks our cached descriptive name as dirty.
3754  void dirtyDescriptiveNameCache();
3755 
3756  /// Return true if it is safe at this time to destroy this node.
3757  virtual bool canDestroyNode();
3758 
3759  /// Override this to return true in an operator type that wants its
3760  /// cooked data to rely on all its parameter values but doesn't actually
3761  /// evaluate any parameters in its cook function (the prototypical
3762  /// example of this is SHOPs).
3763  virtual bool cookedDataUsesAllParameters() const
3764  { return false; }
3765  /// If the cook method relies on the base class cook to evaluate parameters
3766  /// (like in SHOPs), we need to trap the errors during this evaluation.
3767  virtual bool cookedDataNeedsErrors() const
3768  { return false; }
3769  /// If this node should be cooked for any output connected to it, return
3770  /// true here. Otherwise we only cook a node if something is connected to
3771  /// it's primary output. This does not let the node cook differently for
3772  /// each output, since the cook method doesn't know what output is being
3773  /// cooked for. So this should only be used if the cook is unaffected by
3774  /// the specific connected output.
3775  virtual bool cookDataForAnyOutput() const
3776  { return false; }
3777 
3778  // Returns true if we are running our creation script, or any parent
3779  // node of us is running its creation script.
3780  bool getIsRunningInCreateScript() const;
3781 
3782  /// This method is called whenever something in the network changes
3783  /// that may have an impact on the representative node this network may
3784  /// have. It is used at this level to notify parents, and at the OBJ level
3785  /// to actually refresh the representative object.
3786  virtual void refreshRepresentativeNode(OP_Node &changed_child);
3787 
3788  /// Sets up the inputs and outputs after all nodes have been loading
3789  /// from file (in case it needs its children to determine inputs/oututs).
3790  virtual void setupConnectorsAfterLoad();
3791 
3792  /// Converts opdef and oplib format paths from opdef:nodepath to
3793  /// opdef:tablename/optype.
3795  UT_String &str) const override;
3796 
3797  bool isCookedTime(fpreal t) const
3798  {
3799  return dataMicroNodeConst()
3800  .isEqualToLastUpdateTime(t);
3801  }
3802 
3803  /// Subclasses should override this to dump extra micronodes that they own
3804  /// for debugging purposes.
3805  virtual void dumpMicroNodes(
3806  std::ostream &os,
3807  bool as_DOT,
3808  int indent_level) const;
3811  UT_TokenString myHashCode; // Generates a unique
3812  UT_TokenString myParmHashCode; // parameters & inputs.
3813  int myLastGroupMask;
3814  OP_VERSION myHashVersion;
3815  fpreal myHashTime;
3816  int myParmLastGroupMask;
3817  OP_VERSION myParmHashVersion;
3818  fpreal myParmHashTime;
3819  UT_String mySyncErrors;
3820  OP_ERROR mySyncErrorLevel;
3821  int mySyncDepth;
3822 
3823  /// Deletes an input completely if it is disconnected. If the input
3824  /// is connected, does nothing.
3825  void deleteInput(OP_InputIdx idx);
3826  void deleteInput(const OP_ConnectorId& input_name);
3827 
3828  /// Performs actual removal from the member input array.
3829  virtual void doDeleteInput(OP_InputIdx idx);
3830 
3831  /// Update the error severity of this node.
3832  void updateErrorSeverity();
3834  /// Overriden in VOPs.
3835  virtual void onInputAllocated(OP_Input* new_input,
3836  OP_InputIdx index) { }
3837 
3838  /// Debug method for checking connector consistency.
3839  void checkConnectorsConsistency();
3840 
3841  /// Use these to collect all inputs/outputs in cases where they will
3842  /// need to be modified.
3843  void gatherInputs(UT_Array<OP_InputPair> &input_pairs);
3844  void gatherOutputs(UT_Array<OP_OutputPair> &output_pairs);
3845 
3846  void renameInput(OP_Input* input, int new_id);
3847 
3848  void notifyChannelOpDependents(PRM_Parm * in_parm, int vecid);
3849  // Compiled hash code
3850  uint32 myCompHash;
3851 
3852 private:
3853 
3854  void updateSpareParmTemplates(
3855  PRM_Template *newtemplates,
3856  bool leavedefaultsunchanged) override;
3857 
3858  bool doDebugConsistencyCheck();
3859  void createCollection( OP_Operator *entry );
3860 
3861  // these are extra private. only to be called from saveIntrinsic and save
3862  // respectively
3863  OP_ERROR saveIntrinsicError();
3864  OP_ERROR saveError();
3865  OP_ERROR saveGroupMemberships(std::ostream &os,
3866  const OP_SaveFlags &flags,
3867  const char *path_prefix);
3868  bool loadGroupMemberships(UT_IStream &is,
3869  const char*path = nullptr);
3870 
3871  ///Make a note of which network box we're in
3872  OP_ERROR saveNetworkBox(std::ostream &os,
3873  const OP_SaveFlags &flags,
3874  const char *path_prefix);
3875 
3876  ///Put ourselves into a network box if we saved ourselves as being in one
3877  bool loadNetworkBox(UT_IStream &is,
3878  const char *path = nullptr);
3879 
3880  bool loadNodeFlags(UT_IStream &is, const char *path);
3881 
3882  void saveForUndoComment();
3883  void saveForUndoDelScript();
3884 
3885  UT_BitArray &getGroups() { return myGroups; }
3886  const UT_BitArray &getGroups() const { return myGroups; }
3887  // Only OP_Input should call setOutput() and delOutput() functions.
3888  bool setOutput(OP_NetworkBoxItem *item,
3889  OP_OutputIdx output_idx);
3890  bool delOutput(OP_NetworkBoxItem *item,
3891  OP_OutputIdx output_idx);
3892  bool setNamedOutput(OP_NetworkBoxItem *item,
3893  const OP_ConnectorId& output_name);
3894  bool delNamedOutput(OP_NetworkBoxItem *item,
3895  const OP_ConnectorId& output_name);
3896  OP_Output *getOutput(OP_OutputIdx output_idx);
3897  const OP_Output *getOutput(OP_OutputIdx output_idx) const;
3898  bool isOutputIdxValid(OP_OutputIdx output_idx) const;
3899 
3900  void setInterrupted();
3901 
3902  int findAncestor(const OP_Node *node) const;
3903  int findDataAncestor(const OP_Node *node) const;
3904  void clearRecursionBit() const;
3905 
3906  void initializeExpressions() const;
3907  void clearInputs();
3908  void clearOutputs();
3909 
3910  PRM_ParmMicroNode *createParmMicroNodes(PRM_Parm &parm) const override;
3911 
3912  static bool getMicroNodesFromRef(
3913  const OP_InterestRef &ref,
3914  DEP_MicroNodeList &micronodes,
3915  bool data_target);
3916  static void traverseInputsAddInputs(
3917  opNodeOutput &output,
3919  UT_Set<opNodeOutput> &visited,
3920  TraverseOptions opts,
3921  OP_InterestType extra_interest_mask,
3922  bool include_parmlist);
3923 
3924  // ref_chan_name must be the real channel name and not an alias
3925  int addOpDependent( int op_id,
3926  const PRM_RefId &source_ref,
3927  const PRM_RefId &ref_id,
3929 
3930  void updateRenameDependent( OP_Node *dependent,
3931  const char *old_cwd,
3932  OP_NodeList &cook_nodes );
3933 
3934  /// Trigger notifications when the given input has changed.
3935  /// If input has no value, then it notifies as if all inputs changed.
3936  void notifyInputOpDependents(OP_InputIdx input);
3937 
3938  void getExistingOpReferencesImpl(
3939  OP_NodeList &refs, bool include_descendants) const;
3940  void getExistingOpDependentsImpl(
3941  OP_NodeList &deps, bool include_descendants) const;
3942 
3943  void buildScriptOpDependencies();
3944  void changeScriptOpRef( const char *new_fullpath,
3945  const char *old_path,
3946  const char *old_cwd );
3947  static void changeScriptCB( UT_String &str,
3948  const char *token_start,
3949  const char *&ch, void *userdata );
3950 
3951  // Go through and find all nodes which have time interest and requires
3952  // cooking. If the update_cook flag is true, then we will call force
3953  // recook on the node as long as node != this. 'interests' if non-null,
3954  // stores the path of nodes that has time interest and will set the time
3955  // interest cook flag on those nodes.
3956  bool findTimeInterests(const OP_Context &context, OP_Node *node,
3957  bool update_cook,
3958  OP_NodeCycleDetect &cycle,
3959  OP_NodeList *interests = nullptr);
3960 
3961  /// Helper method for 'completePath()'
3962  bool attemptPrefixMatch(const OP_NetworkBoxItem *item,
3963  char *childpref, int childpreflen,
3964  UT_String &maxprefix) const;
3965 
3966  /// Helper for propagateModification()
3967  void findUsedDataInterests(OP_NodeList &nodes, OP_Node *op);
3968 
3969  /// Helper function for the setGlobal*Param functions. This function
3970  /// interprets the return value from CH_Manager::setGlobal*Param.
3971  bool internalSetGlobalParam(const char *param,
3972  int setreturned,
3973  bool *warned);
3974 
3975  bool internalSetPicked(bool on_off,
3976  bool propagate_parent_event,
3977  bool edit);
3978 
3979  OP_ERROR internalCookInput(OP_Context &context,
3980  OP_InputIdx input_idx,
3981  OP_Node &input_node);
3982 
3983  virtual void removeInputFromMapping(OP_InputIdx idx);
3984  void removeOutputFromMapping(OP_OutputIdx idx);
3985 
3986  void generateConnectorUniqueId(OP_ConnectorId& id_out);
3987  OP_Output *getOrCreateOutput(OP_OutputIdx array_index, bool create,
3988  int id_to_use);
3989 
3990  uint32 computeCompiledHash() const;
3991 
3992  // Adds a warning to the current error manager if this node has been
3993  // marked as deprecated.
3994  void addDeprecationWarningsIfAny();
3995 
3996  // Find an unused connectorId to assign to the next input/output
3997  int getConnectorNextId() const;
3998 
3999  bool computeCompiledStatus() const;
4000 
4001  bool isOperatorThreadSafe() const;
4002 
4003  void internalSyncDelayedOTL();
4004 
4005 public:
4006  /// SOP, OBJ, and SOP Solver DOP nodes can be a selection owner,
4007  /// but other nodes cannot.
4008  /// This replaces the previous inheritance from SOP_SelectionOwner.
4009  virtual bool isSelectionOwnerType() const
4010  { return false; }
4011 
4012  /// Add many extra inputs in one call. See addExtraInput
4013  void addExtraInputs(const UT_Array<OP_InterestRef> &source_refs);
4014  void addExtraInputs(const DEP_MicroNodeList &deps);
4015 
4016  static void addExtraInputs(
4017  const UT_Array<OP_InterestRef> &target_refs,
4018  const UT_Array<OP_InterestRef> &source_refs);
4019 
4020  /// Optimized version of addExtraInput that doesn't create OP_InterestRef
4021  static void addExtraInput(OP_Node &source, int source_pi, int source_vi,
4022  OP_Node &target, int target_pi, int target_vi
4023  );
4024 
4025  static bool getMicroNodesFromRef(
4027  DEP_MicroNodeList &micronodes, bool data_target);
4028 
4029  static bool getMicroNodesFromRef(
4030  OP_Node &op, int parm_i, int vec_i,
4031  DEP_MicroNodeList &micronodes);
4032 
4033  void addExtraInput(OP_Node *op, OP_InterestType type, DEP_MicroNodeList &sources_cache);
4034 
4035  /// Optimized version of addExtraInput that doesn't create OP_InterestRef
4036  static void addExtraInput(OP_Node &source, PRM_Parm &source_parm, int source_vi,
4037  OP_Node &target, PRM_Parm &target_parm, int target_vi
4038  );
4039 
4040  void addExtraInputs(const UT_Array<OP_Node*> &nodes, OP_InterestType type, DEP_MicroNodeList &sources_cache);
4041 
4042  virtual bool isUsingCurrentFrameForVexTransformContext() const {return true;}
4043 private:
4044  OP_Cache myCache;
4045 
4046  OP_ERROR myLastErrorSeverity;
4047  exint myLastErrorVersion;
4048  OP_Network *myParent;
4049  OP_Network *myRootCompiledParent;
4050  UT_ValArray<OP_Input *> myInputs;
4051  // This is a map of names to inputs.
4052  OP_ConnectorInputMap myInputsMap;
4053  mutable UT_BitArray myUsedInputs;
4056  myOutputs;
4058  mySpareOutputs;
4059  /// Map from names to outputs, including spare outputs.
4060  OP_ConnectorOutputMap myOutputsMap;
4061 
4062  // Default data micro node.
4063  OP_DataMicroNode myDataMicroNode;
4064  DEP_MicroNode myFlagMicroNode;
4065  UT_Map<char, DEP_MicroNode> myIndividualFlagMicroNodes;
4066  UT_StringArray myClearInputContextOptionDeps;
4067 
4068  // Event micronodes for OP events
4069  using MicroNodePtr = UT_UniquePtr<DEP_MicroNode>;
4070  using EventMicroNodesPtr = UT_UniquePtr<MicroNodePtr[]>;
4071  EventMicroNodesPtr myEventMicroNodes;
4072 
4073  UT_String myComment;
4074  UT_String myDelScript;
4075  UT_String myCreatorState;
4076  UT_BitArray myGroups;
4077  OP_Value myEventValue;
4078  fpreal myPosX;
4079  fpreal myPosY;
4080  exint myCookCount;
4081  SYS_AtomicInt32 mySourceCount;
4082  int myBlockModify;
4083  int myScriptsBlockingDelCount;
4084  int myUniqueId;
4085  int myNextIdOverride;
4086  unsigned myActiveInputIndex;
4087  // Indicates which input is currently being connected,
4088  // -1 if none.
4089  OP_InputIdx myLegacyConnectingInputIndex;
4090 
4091  bool myAutoscope;
4092 
4093  fpreal myCookDuration; // time spent cooking
4094  unsigned int myRenameConflict : 1,
4095  myCookedForRender : 1,
4096  myModifyWaiting : 1,
4097  myBuiltExplicitly : 1,
4098  myAllowBuildDependencies : 1,
4099  myBeingDeleted : 1,
4100  myRunningCreateScript : 1,
4101  myRunningDelScript : 1,
4102  myAlreadyRunDelScript : 1,
4103  myMatchesOTLDefinition : 1,
4104  myLoadCookedDataError : 1,
4105  myBuiltHashCode : 1,
4106  myIsProxyRefNode : 1,
4107  myInhibitInputConsolidation : 1,
4108  // Tracks if we have engaged our local variables, true from the
4109  // SOP_Node::setupLocalVars() until the SOP_Node::resetLocalVarRefs(). Any
4110  // attempt to evaluate local vars outside of here will redflag. This
4111  // flag is here instead of SOP_Node so that PI_OpHandleLink has access
4112  // to temporarily enable it.
4113  myLocalVarActive : 1,
4114  myDelaySyncOTL : 1,
4115  mySyncingDelayedOTL : 1;
4116 
4117  mutable bool myRecursionFlag;
4118 
4119  // Tracks the nesting level of the modification propagation chains
4120  static int thePropagateLevel;
4121 
4122  // ops that we have a reference to
4123  OP_ReferenceList myOpReferences;
4124  // ops that depend on us
4125  OP_DependencyList myOpDependents;
4126 
4127  // bundles that we have a reference to
4128  OP_BundleReferences myBundleRefs;
4129 
4130  // Locking for cooking and adding extra inputs
4131  mutable OP_CookLock myCookLock;
4132 
4133  // Arbitrary string data that users can attach to nodes that gets saved
4134  // with the hip file.
4135  UT_Options myUserData;
4136  // Cached value for the node shape.
4137  UT_StringHolder myNodeShape;
4138 
4139  // Arbitrary blind data that users can attach to nodes. These do not get
4140  // saved with the hip file.
4141  UT_StringMap<UT_SharedPtr<void> > myBlindData;
4142 
4143  // Arbitrary data blocks that, unlike blind data, are saved with the node.
4144  // This obviously implies the data must be self contained (no pointers).
4145  UT_StringMap<OP_DataBlockPtr> myDataBlocks;
4146 
4147  // Arbitrary data (in the form of Python objects) the users can attach to
4148  // nodes that does not get saved with the hip file.
4149  OP_PythonObjectCache myCachedPythonObjects;
4150 
4151  // During load, not all of our input names are known. This stores
4152  // unresolved input names until OP_Node::loadFinished() is called,
4153  // where they are resolved.
4154  UT_Array<OP_UnresolvedConnection *> *myUnresolvedInputs;
4155 
4156  OP_NodeFlags myFlags;
4157 
4158  /// Cached evaluation of the node's descriptive name.
4159  UT_StringHolder myCachedDescriptiveName;
4160  bool myCachedDescriptiveNameDirty;
4161 
4162  /// Only used during loading. Set to false initially, it is set to true
4163  /// once we load inputsNamed intrinsic section. If we do, the regular
4164  /// inputs section will then be ignored.
4165  bool myLoadedNamedInputs;
4166 
4167  /// Used for caching the compiled status of the node. Initially undefined,
4168  /// gets set on first isCompiled() call.
4169  mutable OP_CompileStatusType myCachedCompileStatus;
4170 
4171  OP_ERROR myChildErrorSeverity;
4172  int myChildErrorSeverityTimestamp;
4173 
4174  UT_StringHolder myOverriddenOperatorName;
4175 
4176 
4177  // Maintenance of node id's
4178  static int makeUniqueId(OP_Node *node);
4179 
4180  static bool *theCheckConnectionConsistency;
4181  static int theUniqueId;
4182  static int theUniqueSize;
4183  static OP_Node **theUniqueNodes;
4184  static bool theDoingBulkNotification;
4185  static OP_Node *theBulkNotificationCaller;
4187  friend class OP_Channels;
4188  friend class OP_DataMicroNode;
4189  friend class OP_EventMicroNode;
4190  friend class OP_Group;
4191  friend class OP_IndirectInput;
4192  friend class OP_Input;
4193  friend class OP_Network;
4194  friend class OP_OperatorTable;
4195  friend class OP_ParmMicroNode;
4196  friend class OP_UndoCreate;
4197  friend class OP_UndoDelete;
4198  friend class OP_UndoInput;
4199  friend class OP_UndoSpareParm;
4200  friend class OP_UndoUserData;
4202  friend class op_MicroNodeDirtied;
4203  friend class MOT_RemoteExecMessage;
4204 };
4205 
4206 // helper function
4207 // should always return a valid pointer
4209 
4210 // Link a Node to a Channel for SOP Channels
4211 OP_API void OPlinkNodeToChannel( const OP_Node *node, const CH_Channel *chp );
4213 
4214 // Replaces CH_Manager::getUniqueCollections() as it needs access to OP.
4216  const CH_ChannelList &channels,
4217  CH_CollectionList &collections );
4218 
4219 // UTformat support.
4220 static inline size_t
4221 format(char *buffer, size_t buffer_size, const OP_Node &v)
4222 {
4223  UT_StringHolder s = v.getFullPath();
4224  if (!buffer)
4225  return s.length();
4226  else
4227  {
4228  size_t len = std::min(size_t(s.length()), buffer_size);
4229  ::memcpy(buffer, s.c_str(), len);
4230  return len;
4231  }
4233 
4235 {
4236 public:
4239 };
4240 
4241 #define CAST_INSTANTIATE(PREFIX) \
4242 inline static PREFIX##_Node *CAST_##PREFIX##NODE(OP_Node *op) \
4243 { \
4244  return ((op) ? (op)->castTo##PREFIX##Node() : 0); \
4245 } \
4246  \
4247 inline static const PREFIX##_Node *CAST_##PREFIX##NODE(const OP_Node *op) \
4248 { \
4249  return ((op) ? (op)->castTo##PREFIX##Node() : 0); \
4250 } \
4251 
4252 /// @anchor OP_Node_CAST_FOONODE
4253 /// These convenience functions let you do the cast without worrying if the
4254 /// underlying pointer is null or not. They aren't macros because this way we
4255 /// avoid double evaluating the op.
4256 /// CAST_OBJNODE()
4257 /// CAST_SOPNODE()
4258 /// CAST_CHOPNETNODE()
4259 /// CAST_CHOPNODE()
4260 /// CAST_ROPNODE()
4261 /// CAST_SHOPNODE()
4262 /// CAST_COPNODE()
4263 /// CAST_COP2NODE()
4264 /// CAST_COP2NETNODE()
4265 /// CAST_VOPNODE()
4266 /// CAST_VOPNETNODE()
4267 /// CAST_DOPNODE()
4268 /// CAST_TOPNODE()
4269 /// CAST_TOPNETNODE()
4270 /// CAST_LOPNODE()
4271 //@{
4273 //@}
4274 
4275 #undef CAST_INSTANTIATE
4276 
4277 // We don't want anyone to conflict with this..
4278 #undef INSTANTIATE_FINDNODE_FUNCTIONS
4279 #undef INSTANTIATE_CASTNODE_FUNCTIONS
4280 #undef INSTANTIATE_FOR_ALL_NODE_TYPES
4281 
4282 //___________________________________________________________________________
4284 /// Simple class that makes it easy to write loops that iterate over all the
4285 /// outputs from a node. The parameters are passed on to getOutputNodes.
4286 class OP_API OP_OutputIterator : private UT_SmallArray<OP_Node*>
4287 {
4289 
4290 public:
4292  const OP_Node &node,
4293  bool into_subnets = false,
4294  bool through_dots = true,
4295  OP_OutputIdx output_idx = -1)
4296  {
4297  node.getOutputNodes(*this, into_subnets, through_dots, output_idx);
4298  }
4299  struct Version2Tag {};
4301  Version2Tag,
4302  const OP_Node &node,
4303  bool into_subnets = false,
4304  bool through_dots = true,
4306  {
4307  node.getOutputNodes2(*this, into_subnets, through_dots, output_idx);
4308  }
4309 
4310  using Parent::begin;
4311  using Parent::end;
4312 
4313  using Parent::rbegin;
4314  using Parent::rend;
4315 
4316  using Parent::operator();
4317  using Parent::entries;
4318  using Parent::size;
4319 
4320  using Parent::sort;
4321 };
4323 /// Same as OP_OutputIterator, but with the iterators all swapped around so a
4324 /// range loop will go backwards (without having to mess with reverse adaptors)
4325 class OP_API OP_OutputReversedIterator : private UT_SmallArray<OP_Node*>
4326 {
4328 
4329 public:
4331  const OP_Node &node,
4332  bool into_subnets = false,
4333  bool through_dots = true,
4334  OP_OutputIdx output_idx = -1)
4335  {
4336  node.getOutputNodes(*this, into_subnets, through_dots, output_idx);
4337  }
4338  struct Version2Tag {};
4340  Version2Tag,
4341  const OP_Node &node,
4342  bool into_subnets = false,
4343  bool through_dots = true,
4345  {
4346  node.getOutputNodes2(*this, into_subnets, through_dots, output_idx);
4347  }
4349  const_reverse_iterator begin() const { return Parent::rbegin(); }
4350  const_reverse_iterator end() const { return Parent::rend(); }
4351  reverse_iterator begin() { return Parent::rbegin(); }
4352  reverse_iterator end() { return Parent::rend(); }
4354  const_iterator rbegin() const { return Parent::begin(); }
4355  const_iterator rend() const { return Parent::end(); }
4356  iterator rbegin() { return Parent::begin(); }
4357  iterator rend() { return Parent::end(); }
4358 
4359  using Parent::operator();
4360  using Parent::entries;
4361  using Parent::size;
4362 
4363  using Parent::sort;
4364 };
4365 
4366 /// Safe reference to an OP node
4369 public:
4370  OP_NodeId() { myId = OP_INVALID_NODE_ID; }
4371  OP_NodeId(const OP_Node *node) { *this = node; }
4372  OP_NodeId(const OP_NodeId &id) { myId = id.myId; }
4373 
4374  bool isValid() const
4375  { return (OP_Node::lookupNode(myId) != nullptr); }
4376 
4377  OP_Node *ptr() { return OP_Node::lookupNode(myId); }
4378  const OP_Node *ptr() const { return OP_Node::lookupNode(myId); }
4380  void clear() { myId = OP_INVALID_NODE_ID; }
4381 
4382  void operator=(const OP_Node *node)
4383  { myId = node ? node->getUniqueId() : OP_INVALID_NODE_ID; }
4384 
4385  bool operator==(const OP_Node *node) const
4386  {
4387  const int id = node ? node->getUniqueId() : OP_INVALID_NODE_ID;
4388  return id == myId;
4389  }
4390  bool operator!=(const OP_Node *node) const
4391  {
4392  const int id = node ? node->getUniqueId() : OP_INVALID_NODE_ID;
4393  return id != myId;
4394  }
4395  void setId(int id) { myId = id; }
4396 private:
4397  int myId;
4398 };
4399 
4400 #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:4239
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:2844
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:2771
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:2835
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
void getOutputNodes2(UT_Array< OP_Node * > &outputs, bool into_subnets=false, bool through_dots=true, UT_Optional< OP_OutputIdx > output_idx=UT_NULLOPT) const
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:84
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
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
Safe reference to an OP node.
Definition: OP_Node.h:4364
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