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