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