HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
SOP_NodeVerb.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: SOP_NodeVerb.h ( SOP Library, C++)
7  *
8  * COMMENTS:
9  * Verb-based API for SOP cooking mechanisms. SOPs can return
10  * one of these objects to describe how they cook, allowing the
11  * cook engine to perform additional optimizations.
12  */
13 
14 #ifndef __SOP_NodeVerb_h__
15 #define __SOP_NodeVerb_h__
16 
17 #include "SOP_API.h"
18 #include "SOP_Node.h"
19 #include <OP/OP_Director.h>
20 #include <OP/OP_NodeParms.h>
21 #include <OP/OP_NodeVerb.h>
22 #include <PRM/PRM_Parm.h>
23 #include <UT/UT_Array.h>
24 #include <UT/UT_Assert.h>
25 #include <SYS/SYS_Types.h>
26 
27 #include <initializer_list>
28 
29 #include <VEX/VEX_PodTypes.h>
30 template <VEX_Precision PREC> class CVEX_ContextT;
32 class CVEX_Function;
33 class DEP_MicroNode;
34 class SOP_GraphProxy;
35 
37 {
38 public:
39  int64 getMemoryUsage(bool inclusive) const
40  {
41  int64 mem = inclusive ? sizeof(*this) : 0;
42  mem += UTarrayDeepMemoryUsage(stringdata, false);
43  return mem;
44  }
45 
46 public:
47  fpreal32 floatdata[16];
50 };
51 
53 {
54 protected:
55  friend class SOP_NodeParms;
56 };
57 
59 {
60 public:
62 
63  /// Overloads all the parameters according to matching attributes
64  /// in provided geometry.
65  bool applyGeometryOverride(GU_ConstDetailHandle gdh);
66 
67  /// Detects specially named parameters, cooks required inputs using
68  /// the traditional cook engine.
69  bool applyGeometryOverrideFromNode(
70  SOP_Node *node, OP_Context &context,
71  SOP_NodeCache *cache);
72  /// Returns if the node has the specially named parameters that
73  /// may require a parameter override. This will disable traditional
74  /// cooking.
75  static bool nodeHasGeometryOverride(SOP_Node *node, OP_Context &context);
76 
77 protected:
78 };
79 
80 
81 ///
82 /// SOP_NodeVerb
83 ///
84 /// This should be a singleton class. Build it with the Register
85 /// template to allow it to be discoverable by name.
86 ///
88 {
89 public:
91 
92  virtual SOP_NodeCache *allocCache() const
93  { return new SOP_NodeCache; }
94  virtual SOP_NodeParms *allocParms() const = 0;
95 
96  OP_NodeCache *baseAllocCache() const override final
97  { return allocCache(); }
98  OP_NodeParms *baseAllocParms() const override final
99  { return allocParms(); }
100 
101  // UT_StringHolder name() override const = 0;
102 
103  OP_OpTypeId category() const override
104  { return SOP_OPTYPE_ID; }
105 
106  /// Finds a verb which matches the given name
107  static const SOP_NodeVerb *lookupVerb(const UT_StringRef &name);
108  static void listVerbs(UT_StringArray &verbnames);
109 
111  {
112  public:
113  void clear()
114  {
115  myExprInputs.clear();
116  myTimeDeps.clear();
117  }
119  const UT_IntArray &timedeps)
120  {
121  myExprInputs = inputs;
122  myTimeDeps = timedeps;
123  }
124  const UT_Array<GU_ConstDetailHandle> &exprinputs() const { return myExprInputs; }
125  const UT_IntArray &timedeps() const { return myTimeDeps; }
126 
127  protected:
130  };
131 
133 
134  /// During execution of a verb chain you may wish to disable
135  /// the traditional cooking of nodes. This provides a set of
136  /// nodes you do not want recursed into during the verb cook.
137  /// It will be NULL if there are none or this thread isn't in
138  /// a compiled execution path.
139  static const ForbiddenNodeMap *forbiddenNodes();
140  static const ForbiddenNodeMap *forbiddenNodes(int thread);
141 
142  /// This scope class will push the given list of nodes marking
143  /// them as inelligible for cooking in the traditional path.
144  /// Needless to say, the invoker needs to ensure the set's lifetime
145  /// persists.
147  {
148  public:
149  ScopeForbiddenNodes(const ForbiddenNodeMap *forbiddennodes);
151 
152  ScopeForbiddenNodes(const ScopeForbiddenNodes &) = delete;
153  ScopeForbiddenNodes &operator=(const ScopeForbiddenNodes &) = delete;
154  protected:
156  };
157 
158  enum CookMode
159  {
160  // With in place the destination gdp will be the first input or
161  // a copy.
162  // The first input will be null.
164  // With duplicate, the destination gdp will be a copy of the
165  // first input. All inputs will be valid.
167  // With generator, the destination gdp is empty, possibly
168  // a stashAll(). All inputs will be valid.
170  // With instance, the destination gdp is invalid. All inputs
171  // will be valid.
173  // There will be a destination gdp, but its contents are unspecified
174  // It may contain the results of the last cook. All inputs are
175  // valid.
177  // If cookMode is pass through, the cook method will not be
178  // invoked at all. Instead, the first input will be passed through
179  // unchanged. If there is no first input, an empty gdp is
180  // created.
182  };
183 
185  {
186  public:
188  virtual ~NodeInputs() {}
189 
190  NodeInputs(const NodeInputs &) = delete;
191  NodeInputs &operator=(const NodeInputs &) = delete;
192 
193  virtual exint nInputs() const = 0;
194  /// Returns if the input is wired.
195  virtual bool hasInput(exint idx) const = 0;
196 
197  /// Demands the input be cooked. After this, the inputGeo()
198  /// will return the contents.
199  /// Returns false if the cook failed for some reason.
200  virtual bool cookInput(exint idx) = 0;
201 
202  /// Returns an invalid handle if the input isn't wired or not yet
203  /// cooked.
204  virtual GU_DetailHandle inputGeo(exint idx) = 0;
205 
206  /// Unlocks/forgets the given input. Returns an invalid handle if
207  /// not wired or not cooked.
208  virtual GU_DetailHandle unloadInput(exint idx, bool flushce) = 0;
209 
210  /// Marks the given input used. Needed if the input isn't cooked,
211  /// as unload will not mark it unused (as it must be marked such
212  /// ASAP to free up earlier nodes)
213  virtual void markInputUnused(exint idx) = 0;
214  };
215 
217  {
218  public:
220  : myGdps(gdps)
221  { }
222 
223  exint nInputs() const override { return myGdps.entries(); }
224  bool hasInput(exint idx) const override
225  {
226  if (idx < 0 || idx >= nInputs())
227  return false;
228  return myGdps(idx).gdp() != nullptr;
229  }
230 
231  bool cookInput(exint idx) override
232  {
233  // Precooked, so if we have it it successfully cooked.
234  return hasInput(idx);
235  }
236 
238  {
239  if (!hasInput(idx))
240  return GU_DetailHandle();
241  return myGdps(idx).castAwayConst();
242  }
243 
244  GU_DetailHandle unloadInput(exint idx, bool flushce) override
245  {
246  // It would make sense to clear out the gdp at this point,
247  // but we don't have ownership of the array.
248  return inputGeo(idx);
249  }
250 
251  void markInputUnused(exint idx) override {}
252  protected:
254  };
255 
257  {
258  public:
259  InputParms(NodeInputs &inputs, NodeInputs &exprinputs,
260  const OP_Context &context,
261  const SOP_NodeParms *parms,
262  SOP_NodeCache *cache,
264  : myInputs(inputs)
265  , myExprInputs(exprinputs)
266  , myContext(context)
267  , myParms(parms)
268  , myCache(cache)
269  , myError(error)
270  , myDepNode(depnode)
271  {
272  }
273 
274  virtual ~InputParms() {}
275 
276  InputParms(const InputParms &) = delete;
277  InputParms &operator=(const InputParms &) = delete;
278 
279  NodeInputs &inputs() const { return myInputs; }
280 
281  NodeInputs &exprinputs() const { return myExprInputs; }
282 
283  template <typename T>
284  const T &parms() const
285  { return *UTverify_cast<const T*>(myParms); }
286 
287  template <typename T>
288  T *cache() const
289  { return UTverify_cast<T *>(myCache); }
290 
291  UT_ErrorManager *error() const { return myError; }
292 
293  DEP_MicroNode *depnode() const { return myDepNode; }
294 
295  const OP_Context &getContext() const
296  { return myContext; }
298  { return myContext.getTime(); }
299 
300  protected:
308  };
309 
311  {
312  public:
314  const UT_Array<GU_ConstDetailHandle> &inputs,
315  OP_CookEngine cookengine,
316  OP_Node *node,
317  const OP_Context &context,
318  const SOP_NodeParms *parms,
319  SOP_NodeCache *cache,
321  DEP_MicroNode *depnode)
322  : myDestGdh(destgdh)
323  , myInputs(inputs)
324  , myExprInputs(nullptr)
325  , myCookEngine(cookengine)
326  , myNode(CAST_SOPNODE(node))
327  , myOpNode(node)
328  , myContext(context)
329  , myParms(parms)
330  , myCache(cache)
331  , myError(error)
332  , myDepNode(depnode)
333  {}
334  void setPseudoPath(const UT_StringHolder &path) { myPseudoPath = path; }
335  void setExprInputs(const UT_Array<GU_ConstDetailHandle> &exprinputs) { myExprInputs = & exprinputs; }
336 
337  virtual ~CookParms() {}
338 
339 
340  /// The initial state of gdh depends on the cookMode()
341  GU_DetailHandle &gdh() const { return myDestGdh; }
342 
343  /// The currently cooking SOP. This is only non-null if in
344  /// the old cook path. When executing compiled nodes it will
345  /// be null as the verb is supposed to operate independently
346  /// of the original SOP.
347  SOP_Node *getNode() const { return (myCookEngine == OP_COOK_TRADITIONAL) ? myNode : 0; }
348 
349  template <typename T>
350  T *getCookNode() const
351  { if (myCookEngine != OP_COOK_TRADITIONAL)
352  return 0;
353  return UTverify_cast<T *>(myNode); }
354 
355  /// The node that generated this verb, if any...
356  SOP_Node *getSrcNode() const { return myNode; }
357  /// The getCwd() should be used to evaluate relative paths.
358  OP_Node *getCwd() const { if (myOpNode) return myOpNode; return OPgetDirector(); }
359  const OP_Context &getContext() const
360  { return myContext; }
362  { return myContext.getTime(); }
363 
364  /// Accessors designed to simplify porting from old cook code.
365  /// Just becaues you have nInputs does not mean all are wired or
366  /// cooked. But, the number demanded by your OP_Operator shall
367  /// be present.
368  /// Inputs have been locked & preserve request set
369  exint nInputs() const { return myInputs.size(); }
370  bool hasInput(exint idx) const
371  {
372  if (idx < 0 || idx >= myInputs.size())
373  return false;
374  return myInputs(idx).isValid();
375  }
376  const GU_Detail *inputGeo(exint idx) const
377  {
378  if (!hasInput(idx)) return 0;
379  return myInputs(idx).gdp();
380  }
382  {
383  if (!hasInput(idx)) return GU_ConstDetailHandle();
384  return myInputs(idx);
385  }
386 
387  /// Accessors to get to the expression, ie, spare, inputs
388  /// index is the positive index for the spare input.
390  {
391  if (!myExprInputs) return 0;
392  return myExprInputs->size();
393  }
394  bool hasSpareInput(exint idx) const
395  {
396  if (!myExprInputs) return false;
397  if (idx < 0 || idx > myExprInputs->size()) return false;
398  return (*myExprInputs)(idx).isValid();
399  }
400  const GU_Detail *spareInputGeo(exint idx) const
401  {
402  if (!hasSpareInput(idx)) return nullptr;
403  return (*myExprInputs)(idx).gdp();
404  }
406  {
407  if (!hasSpareInput(idx)) return GU_ConstDetailHandle();
408  return (*myExprInputs)(idx);
409  }
410 
411  template <typename T>
412  const T &parms() const
413  { return *UTverify_cast<const T*>(myParms); }
414 
415  /// Cache may, or may not, persist between cooks. But it is
416  /// guaranteed this is the only thread using the cache.
417  SOP_NodeCache *cache() const { return myCache; }
418 
419  /// Error managers are not locked, so do not pass this to
420  /// something that forks.
421  UT_ErrorManager *error() const { return myError; }
422  DEP_MicroNode *depnode() const { return myDepNode; }
423 
424  // NOTE: Do not hold onto the ptr object longer than necessary!
427  {
429  *myError, myErrorLock);
430  }
431 
432  /// Methods to wire directly to the optional depnode.
433  void addExplicitInput(DEP_MicroNode &inp, bool check_dup=true) const
434  { if (myDepNode) myDepNode->addExplicitInput(inp, check_dup); }
435 
436  /// Methods to add directly to any present error manager.
437  UT_ErrorSeverity addMessage (const char *type, int code, const char *msg=0,
438  const UT_SourceLocation *loc=0) const
439  { if (myError) return getLockedErrorManager()->addMessage(type, code, formatError(msg), loc);
440  return UT_ERROR_MESSAGE; }
441  UT_ErrorSeverity addWarning (const char *type, int code, const char *msg=0,
442  const UT_SourceLocation *loc=0) const
443  { if (myError) return getLockedErrorManager()->addWarning(type, code, formatError(msg), loc);
444  return UT_ERROR_WARNING; }
445  UT_ErrorSeverity addError (const char *type, int code, const char *msg=0,
446  const UT_SourceLocation *loc=0) const
447  { if (myError) return getLockedErrorManager()->addError(type, code, formatError(msg), loc);
448  return UT_ERROR_ABORT; }
449 
450 
451  UT_ErrorSeverity addMessageFmt(const char *fmt) const
452  { return addMessage("SOP", SOP_MESSAGE, fmt); }
453  UT_ErrorSeverity addMessageFmt(const char *fmt, std::initializer_list<UT::Format::ArgValue> args) const
454  {
455  UT_WorkBuffer work;
456  work.appendFormat(fmt, args);
457  return addMessageFmt(work.buffer());
458  }
459  template<typename... Args>
460  UT_ErrorSeverity addMessageFmt(const char *fmt, const Args &...args) const
461  { return addMessageFmt(fmt, {args...}); }
462 
463  UT_ErrorSeverity addWarningFmt(const char *fmt) const
464  { return addWarning("SOP", SOP_MESSAGE, fmt); }
465  UT_ErrorSeverity addWarningFmt( const char *fmt, std::initializer_list<UT::Format::ArgValue> args) const
466  {
467  UT_WorkBuffer work;
468  work.appendFormat(fmt, args);
469  return addWarningFmt(work.buffer());
470  }
471  template<typename... Args>
472  UT_ErrorSeverity addWarningFmt(const char *fmt, const Args &...args) const
473  { return addWarningFmt(fmt, {args...}); }
474 
475  UT_ErrorSeverity addErrorFmt(const char *fmt) const
476  { return addError("SOP", SOP_MESSAGE, fmt); }
477  UT_ErrorSeverity addErrorFmt(const char *fmt, std::initializer_list<UT::Format::ArgValue> args) const
478  {
479  UT_WorkBuffer work;
480  work.appendFormat(fmt, args);
481  return addErrorFmt(work.buffer());
482  }
483  template<typename... Args>
484  UT_ErrorSeverity addErrorFmt(const char *fmt, const Args &...args) const
485  { return addErrorFmt(fmt, {args...}); }
486 
487  // Note that these methods first expand the error message using the
488  // provided `code` & `msg`, then pass along the expanded result using
489  // the `SOP_MESSAGE` code, so that the message can be properly prefixed
490  // using the name of the associated node.
491  UT_ErrorSeverity sopAddMessage (int code, const char *msg=0,
492  const UT_SourceLocation *loc=0) const
493  {
494  UT_WorkBuffer errbuf;
495  UT_Error("SOP", code, msg).getErrorFormattedString(errbuf);
496  return addMessage("SOP", SOP_MESSAGE, errbuf.buffer(), loc);
497  }
498  UT_ErrorSeverity sopAddWarning (int code, const char *msg=0,
499  const UT_SourceLocation *loc=0) const
500  {
501  UT_WorkBuffer errbuf;
502  UT_Error("SOP", code, msg).getErrorFormattedString(errbuf);
503  return addWarning("SOP", SOP_MESSAGE, errbuf.buffer(), loc);
504  }
505  UT_ErrorSeverity sopAddError (int code, const char *msg=0,
506  const UT_SourceLocation *loc=0) const
507  {
508  UT_WorkBuffer errbuf;
509  UT_Error("SOP", code, msg).getErrorFormattedString(errbuf);
510  return addError("SOP", SOP_MESSAGE, errbuf.buffer(), loc);
511  }
512 
513  void addTransformError(const OP_Node &node, const char *label=0) const
514  {
515  UT_String path;
516  node.getFullPath(path);
517  if (UTisstring(label))
518  {
519  path += "(as "; path += label; path += ")";
520  }
521  addError("OP", OP_ERR_TRANSFORM, path);
522  }
523 
525  bool borrow_only = false) const
526  { if (myError) getLockedErrorManager()->stealErrors(src,0, -1, UT_ERROR_NONE, borrow_only); }
527 
529  { if (getNode())
530  getNode()->select(gtype); }
531 
533  bool add_to_sel = false) const
534  { if (getNode())
535  getNode()->select(selection, add_to_sel); }
536 
537  // Select the group. opt use its type as sel type
538  void select(const GA_Group &group, bool use_gtype = true,
539  bool add_to_sel = false) const
540  { if (getNode())
541  getNode()->select(group, use_gtype, add_to_sel); }
542 
543  void select(const GEO_Primitive &prim, bool sel_prim = true,
544  bool add_to_sel = false) const
545  { if (getNode())
546  getNode()->select(prim, sel_prim, add_to_sel); }
547  void selectPrimitive(GA_Offset primoff, bool prim_sel = true,
548  bool add_to_sel = false) const
549  { if (getNode())
550  getNode()->selectPrimitive(primoff, prim_sel, add_to_sel); }
551  void selectPoint(GA_Offset ptoff, bool point_sel = true,
552  bool add_to_sel = false) const
553  { if (getNode())
554  getNode()->selectPoint(ptoff, point_sel, add_to_sel); }
555  void selectFrom(const GEO_Primitive &prim, bool sel_prim = true,
556  bool add_to_sel = false) const
557  { if (getNode())
558  getNode()->selectFrom(prim, sel_prim, add_to_sel); }
559  void selectPointsFrom(GA_Offset ptoff, bool point_sel = true,
560  bool add_to_sel = false) const
561  { if (getNode())
562  getNode()->selectPointsFrom(ptoff, point_sel, add_to_sel); }
563  void select(const GA_Range &range, bool use_rtype = true,
564  bool add_to_sel = false) const
565  { if (getNode())
566  getNode()->select(range, use_rtype, add_to_sel); }
567 
568  // Selects input based on the group supplied and the group type. If
569  // group is not null, then it's type is used, otherwise the group type
570  // is used.
571  void selectInputGroup(const GA_Group *group,
572  GA_GroupType grouptype) const
573  { if (getNode())
574  getNode()->selectInputGroup(group, grouptype); }
575 
576  // If no selection is present, then create a new empty primitive cook
577  // selection group. Otherwise, clear the selection.
578  void clearSelection() const
579  { if (getNode())
580  getNode()->clearSelection(); }
581 
582  /// If the cook selection group is not of the given type, create an empty
583  /// cook selection group of that type. Otherwise, clear the existing cook
584  /// selection group.
585  void clearSelection(GA_GroupType gtype) const
586  { if (getNode())
587  getNode()->clearSelection(gtype); }
588 
589  // Blow away the selection and reinitialize it to 0. Much more radical
590  // than clearSelection(), which leaves behind a clean, empty selection.
591  // This method returns 1 if it had anything to destroy, else 0.
592  bool destroySelection() const
593  { if (getNode())
594  return getNode()->destroySelection();
595  return false;
596  }
597 
598  // Return 1 if selection is enabled, 0 if false.
599  bool selectionEnabled() const
600  {
601  if (!getNode())
602  return false;
603  return getNode()->getHighlight();
604  }
605 
606  /// Shims for local variables
607  bool setupLocalVars() const
608  { if (getNode()) return getNode()->setupLocalVars(); return false; }
609  void resetLocalVarRefs() const
610  { if (getNode()) getNode()->resetLocalVarRefs(); }
611  void setCurGdh(int index, const GU_DetailHandle &gdh) const
612  { if (getNode()) getNode()->setCurGdh(index, gdh); }
613  void clearCurGdh(int index) const
614  { if (getNode()) getNode()->clearCurGdh(index); }
615  void setCurPoint(int index, GA_Offset off) const
616  { if (getNode()) getNode()->setCurPoint(index, off); }
617  void clearCurPoint(int index) const
618  { if (getNode()) getNode()->clearCurPoint(index); }
619  void setCurVertex(int index, GA_Offset off) const
620  { if (getNode()) getNode()->setCurVertex(index, off); }
621  void clearCurVertex(int index) const
622  { if (getNode()) getNode()->clearCurVertex(index); }
623  void setCurPrim(int index, GA_Offset off) const
624  { if (getNode()) getNode()->setCurPrim(index, off); }
625  void clearCurPrim(int index) const
626  { if (getNode()) getNode()->clearCurPrim(index); }
627  void setCurVertexNum(int index, exint num) const
628  { if (getNode()) getNode()->setCurVertexNum(index, num); }
629  void clearCurVertexNum(int index) const
630  { if (getNode()) getNode()->clearCurVertexNum(index); }
631  void setVariableOrder(int detail, int prim,
632  int pt, int vtx) const
633  { if (getNode()) getNode()->setVariableOrder(detail, prim, pt, vtx); }
634 
635  /// Tracks if any local variables were accessed by op functions.
637  { if (getNode()) getNode()->myUsesSOPLocalVar = false; }
639  { if (!getNode()) return false;
640  return getNode()->myUsesSOPLocalVar; }
641 
642 
643  protected:
644  /// Prefix errors so we can get sensible results.
645  UT_StringHolder formatError(const char *msg) const
646  {
647  // Do not prefix with the path in traditional cook
648  // as it is properly assigned.
649  if (myCookEngine == OP_COOK_TRADITIONAL)
650  return msg;
652  if (!msg || !*msg)
653  return result;
655  UT_String fullpath;
656  // We prefer to report messages as being linked to an actual node.
657  // In the absence of an associated node we'll report a user-provided
658  // path or, in the absence of that, fall back to "<internal>"
659  if (myNode)
660  myNode->getFullPath(fullpath);
661  else if (myPseudoPath.isstring())
662  fullpath.sprintf("<%s>", myPseudoPath.c_str());
663  else
664  fullpath = "<internal>";
665  buf.sprintf("%s: %s", (const char *) fullpath, msg);
666  result = buf;
667  return result;
668  }
669 
683  };
684 
685  /// If doPartialInputCook is false, we do assume cookInputs() will
686  /// apply to all inputs regardless of node parameters. If local
687  /// variables require the inputs, it is required for this to be false
688  /// for the inputs to be available when parameters are evaluated.
689  virtual bool doPartialInputCook() const { return false; }
690 
691  /// If doExprInputCook is true, we will also cook all expression inputs
692  /// in cookInputs using the default method.
693  virtual bool doExprInputCook() const { return false ; }
694 
695  virtual bool cookInputs(const InputParms &parms) const
696  {
697  for (exint i = 0; i < parms.inputs().nInputs(); i++)
698  if (parms.inputs().hasInput(i))
699  {
700  if (!parms.inputs().cookInput(i))
701  return false;
702  }
703  for (exint i = 0; i < parms.exprinputs().nInputs(); i++)
704  if (parms.exprinputs().hasInput(i))
705  {
706  if (!parms.exprinputs().cookInput(i))
707  return false;
708  }
709  return true;
710  }
711 
712  /// These are for the old-cook path to allow nodes to store relevant
713  /// local variable information inside the SOP for callbacks. The
714  /// evalVariableValue() should be guarded to ensure it doesn't
715  /// run from a forbidden node.
716  /// These can be used if the local variables depend only on the inputs
717  /// and are not change for every parameter. If they change for
718  /// every parameter, traditional cook paths will need to setup &
719  /// evaluate explicitly in the cook method.
720  virtual void setupLocalVariables(SOP_Node *sop, const UT_Array<GU_ConstDetailHandle> &inputs) const {}
721  virtual void resetLocalVariables(SOP_Node *sop) const {}
722 
723  /// Traditional nodes may evaluate parameters while cooking, this is
724  /// required for dynamic local variables. If this is true, no pre-cooking
725  /// of the parameter struture will be done in the traditional cook
726  /// path avoiding double cooking parameters. Remember other cook paths
727  /// will not have access to the sop so should use the parameter structure!
728  virtual bool evaluatesParametersDuringCook() const { return false; }
729 
730  virtual CookMode cookMode(const SOP_NodeParms *parms) const { return COOK_DUPLICATE; }
731 
732  /// Attributes can end up cached on the GPU. Some SOPs are able
733  /// to handle this. Some are ambivalent (such as switch or null)
734  /// And some expect all GPU buffers to be flushed prior to
735  /// operating. If a node requires a CE flush, all inputs
736  /// will be clean.
737  virtual bool requiresCEFlush() const { return true; }
738  virtual bool usesCE() const { return false; }
739 
740  /// Compute the output geometry.
741  virtual void cook(const CookParms &cookparms) const = 0;
742 
743  /// This is used to update handles, it only has an effect
744  /// if oldsop is non-null, ie, we are in the old cook path.
745  /// Neither the group nor the gdp have to persist beyond this call.
746  /// Pass -1 for the grouptype if there is no grouptype parameter.
747  void notifyGroupParmListeners(SOP_Node *oldsop,
748  int groupparm_idx,
749  int grouptype_idx,
750  const GU_Detail *gdp,
751  const GA_Group *group) const;
752 
753 protected:
754 };
755 
756 #endif
OP_CookEngine
Definition: OP_NodeParms.h:42
OP_OpTypeId category() const override
Definition: SOP_NodeVerb.h:103
const T & parms() const
Definition: SOP_NodeVerb.h:284
exint nInputs() const override
Definition: SOP_NodeVerb.h:223
GT_API const UT_StringHolder selection
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glcorearb.h:2540
virtual GU_DetailHandle inputGeo(exint idx)=0
DEP_MicroNode * depnode() const
Definition: SOP_NodeVerb.h:293
UT_ErrorSeverity addWarningFmt(const char *fmt, const Args &...args) const
Definition: SOP_NodeVerb.h:472
const UT_Array< GU_ConstDetailHandle > & exprinputs() const
Definition: SOP_NodeVerb.h:124
void setCurGdh(int index, const GU_DetailHandle &gdh) const
Definition: SOP_NodeVerb.h:611
int int32
Definition: SYS_Types.h:39
GLenum GLint * range
Definition: glcorearb.h:1925
SOP_Node * getNode() const
Definition: SOP_NodeVerb.h:347
GLuint GLsizei const GLchar * label
Definition: glcorearb.h:2545
const ForbiddenNodeMap * myPrevNodes
Definition: SOP_NodeVerb.h:155
DEP_MicroNode * depnode() const
Definition: SOP_NodeVerb.h:422
PreCookedNodeInputs(const UT_Array< GU_ConstDetailHandle > &gdps)
Definition: SOP_NodeVerb.h:219
void setPseudoPath(const UT_StringHolder &path)
Definition: SOP_NodeVerb.h:334
Unsorted map container.
Definition: UT_Map.h:107
UT_ErrorSeverity sopAddMessage(int code, const char *msg=0, const UT_SourceLocation *loc=0) const
Definition: SOP_NodeVerb.h:491
void addTransformError(const OP_Node &node, const char *label=0) const
Definition: SOP_NodeVerb.h:513
UT_ErrorSeverity sopAddWarning(int code, const char *msg=0, const UT_SourceLocation *loc=0) const
Definition: SOP_NodeVerb.h:498
SOP_NodeCache * myCache
Definition: SOP_NodeVerb.h:679
bool cookInput(exint idx) override
Definition: SOP_NodeVerb.h:231
void clearCurGdh(int index) const
Definition: SOP_NodeVerb.h:613
bool hasSpareInput(exint idx) const
Definition: SOP_NodeVerb.h:394
GLsizei const GLchar *const * path
Definition: glcorearb.h:3341
UT_ErrorSeverity addMessageFmt(const char *fmt, std::initializer_list< UT::Format::ArgValue > args) const
Definition: SOP_NodeVerb.h:453
void selectPoint(GA_Offset ptoff, bool point_sel=true, bool add_to_sel=false) const
Definition: SOP_NodeVerb.h:551
UT_ErrorSeverity addMessage(const char *type, int code, const char *msg=0, const UT_SourceLocation *loc=0) const
Methods to add directly to any present error manager.
Definition: SOP_NodeVerb.h:437
const OP_Context & getContext() const
Definition: SOP_NodeVerb.h:295
void clearCurVertexNum(int index) const
Definition: SOP_NodeVerb.h:629
int64 exint
Definition: SYS_Types.h:125
void resetLocalVarRefs() const
Definition: SOP_NodeVerb.h:609
SYS_FORCE_INLINE const char * buffer() const
GU_ConstDetailHandle spareInputGeoHandle(exint idx) const
Definition: SOP_NodeVerb.h:405
UT_ErrorSeverity
Definition: UT_Error.h:25
UT_Array< GU_ConstDetailHandle > myExprInputs
Definition: SOP_NodeVerb.h:128
UT_ErrorSeverity addMessageFmt(const char *fmt) const
Definition: SOP_NodeVerb.h:451
void stealErrors(UT_ErrorManager &src, bool borrow_only=false) const
Definition: SOP_NodeVerb.h:524
const GU_Detail * spareInputGeo(exint idx) const
Definition: SOP_NodeVerb.h:400
OP_Node * getCwd() const
The getCwd() should be used to evaluate relative paths.
Definition: SOP_NodeVerb.h:358
void select(const GA_Range &range, bool use_rtype=true, bool add_to_sel=false) const
Definition: SOP_NodeVerb.h:563
const UT_Array< GU_ConstDetailHandle > & myInputs
Definition: SOP_NodeVerb.h:672
SYS_FORCE_INLINE TO_T UTverify_cast(FROM_T from)
Definition: UT_Assert.h:229
void setExprInputs(const UT_Array< GU_ConstDetailHandle > &exprinputs)
Definition: SOP_NodeVerb.h:335
**But if you need a result
Definition: thread.h:613
const UT_Array< GU_ConstDetailHandle > * myExprInputs
Definition: SOP_NodeVerb.h:673
bool setupLocalVars() const
Shims for local variables.
Definition: SOP_NodeVerb.h:607
float fpreal32
Definition: SYS_Types.h:200
UT_ErrorSeverity addWarningFmt(const char *fmt, std::initializer_list< UT::Format::ArgValue > args) const
Definition: SOP_NodeVerb.h:465
fpreal getCookTime() const
Definition: SOP_NodeVerb.h:297
GU_DetailHandle & myDestGdh
Definition: SOP_NodeVerb.h:671
virtual bool doPartialInputCook() const
Definition: SOP_NodeVerb.h:689
NodeInputs & exprinputs() const
Definition: SOP_NodeVerb.h:281
UT_ErrorManager * error() const
Definition: SOP_NodeVerb.h:291
virtual void resetLocalVariables(SOP_Node *sop) const
Definition: SOP_NodeVerb.h:721
void clearCurPoint(int index) const
Definition: SOP_NodeVerb.h:617
UT_ErrorSeverity sopAddError(int code, const char *msg=0, const UT_SourceLocation *loc=0) const
Definition: SOP_NodeVerb.h:505
const UT_Array< GU_ConstDetailHandle > & myGdps
Definition: SOP_NodeVerb.h:253
A range of elements in an index-map.
Definition: GA_Range.h:42
< returns > If no error
Definition: snippets.dox:2
DEP_MicroNode * myDepNode
Definition: SOP_NodeVerb.h:681
virtual void getErrorFormattedString(UT_WorkBuffer &error_str) const
const SOP_NodeParms * myParms
Definition: SOP_NodeVerb.h:303
GA_Size GA_Offset
Definition: GA_Types.h:641
exint numSpareInputs() const
Definition: SOP_NodeVerb.h:389
GU_DetailHandle unloadInput(exint idx, bool flushce) override
Definition: SOP_NodeVerb.h:244
UT_ErrorSeverity addErrorFmt(const char *fmt) const
Definition: SOP_NodeVerb.h:475
GU_ConstDetailHandle inputGeoHandle(exint idx) const
Definition: SOP_NodeVerb.h:381
const char * getFullPath(UT_String &str) const
Definition: PRM_ParmOwner.h:52
const T & parms() const
Definition: SOP_NodeVerb.h:412
const SOP_NodeParms * myParms
Definition: SOP_NodeVerb.h:678
virtual void setupLocalVariables(SOP_Node *sop, const UT_Array< GU_ConstDetailHandle > &inputs) const
Definition: SOP_NodeVerb.h:720
size_t appendFormat(const char *fmt, const Args &...args)
T * getCookNode() const
Definition: SOP_NodeVerb.h:350
void addExplicitInput(DEP_MicroNode &inp, bool check_dup=true) const
Methods to wire directly to the optional depnode.
Definition: SOP_NodeVerb.h:433
void selectPrimitive(GA_Offset primoff, bool prim_sel=true, bool add_to_sel=false) const
Definition: SOP_NodeVerb.h:547
void setCurPrim(int index, GA_Offset off) const
Definition: SOP_NodeVerb.h:623
UT_ErrorManager * myError
Definition: SOP_NodeVerb.h:305
UT_ErrorSeverity addErrorFmt(const char *fmt, const Args &...args) const
Definition: SOP_NodeVerb.h:484
bool destroySelection() const
Definition: SOP_NodeVerb.h:592
UT_Array< UT_StringHolder > stringdata
Definition: SOP_NodeVerb.h:49
void select(GU_SelectionHandle selection, bool add_to_sel=false) const
Definition: SOP_NodeVerb.h:532
virtual bool doExprInputCook() const
Definition: SOP_NodeVerb.h:693
virtual exint nInputs() const =0
void selectFrom(const GEO_Primitive &prim, bool sel_prim=true, bool add_to_sel=false) const
Definition: SOP_NodeVerb.h:555
int hasInput() override
void clearSelection() const
Definition: SOP_NodeVerb.h:578
virtual bool usesCE() const
Definition: SOP_NodeVerb.h:738
SOP_Node * getSrcNode() const
The node that generated this verb, if any...
Definition: SOP_NodeVerb.h:356
bool hasInput(exint idx) const override
Returns if the input is wired.
Definition: SOP_NodeVerb.h:224
void setCurPoint(int index, GA_Offset off) const
Definition: SOP_NodeVerb.h:615
void selectInputGroup(const GA_Group *group, GA_GroupType grouptype) const
Definition: SOP_NodeVerb.h:571
const UT_IntArray & timedeps() const
Definition: SOP_NodeVerb.h:125
void setExprInputs(const UT_Array< GU_ConstDetailHandle > &inputs, const UT_IntArray &timedeps)
Definition: SOP_NodeVerb.h:118
virtual bool hasInput(exint idx) const =0
Returns if the input is wired.
virtual SOP_NodeCache * allocCache() const
Definition: SOP_NodeVerb.h:92
void selectPointsFrom(GA_Offset ptoff, bool point_sel=true, bool add_to_sel=false) const
Definition: SOP_NodeVerb.h:559
long long int64
Definition: SYS_Types.h:116
void markInputUnused(exint idx) override
Definition: SOP_NodeVerb.h:251
OP_OpTypeId
Definition: OP_OpTypeId.h:18
const OP_Context & getContext() const
Definition: SOP_NodeVerb.h:359
void clearCurPrim(int index) const
Definition: SOP_NodeVerb.h:625
GLuint const GLchar * name
Definition: glcorearb.h:786
OP_NodeCache * baseAllocCache() const overridefinal
Definition: SOP_NodeVerb.h:96
virtual bool evaluatesParametersDuringCook() const
Definition: SOP_NodeVerb.h:728
void setCurVertexNum(int index, exint num) const
Definition: SOP_NodeVerb.h:627
void select(GA_GroupType gtype=GA_GROUP_PRIMITIVE) const
Definition: SOP_NodeVerb.h:528
UT_SharedPtr< GU_Selection > GU_SelectionHandle
virtual bool cookInputs(const InputParms &parms) const
Definition: SOP_NodeVerb.h:695
UT_ErrorManager * error() const
Definition: SOP_NodeVerb.h:421
bool hasInput(exint idx) const
Definition: SOP_NodeVerb.h:370
const OP_Context & myContext
Definition: SOP_NodeVerb.h:677
int sprintf(const char *fmt,...) SYS_PRINTF_CHECK_ATTRIBUTE(2
GU_DetailHandle inputGeo(exint idx) override
Definition: SOP_NodeVerb.h:237
void select(const GEO_Primitive &prim, bool sel_prim=true, bool add_to_sel=false) const
Definition: SOP_NodeVerb.h:543
UT_ErrorSeverity addWarning(const char *type, int code, const char *msg=0, const UT_SourceLocation *loc=0) const
Definition: SOP_NodeVerb.h:441
**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
UT_LockedRawPtr< UT_ErrorManager, OP_Lock > getLockedErrorManager() const
Definition: SOP_NodeVerb.h:426
InputParms(NodeInputs &inputs, NodeInputs &exprinputs, const OP_Context &context, const SOP_NodeParms *parms, SOP_NodeCache *cache, UT_ErrorManager *error, DEP_MicroNode *depnode)
Definition: SOP_NodeVerb.h:259
void setCurVertex(int index, GA_Offset off) const
Definition: SOP_NodeVerb.h:619
void select(const GA_Group &group, bool use_gtype=true, bool add_to_sel=false) const
Definition: SOP_NodeVerb.h:538
A class holding a VEX function.
Definition: CVEX_Function.h:30
UT_ErrorSeverity addWarningFmt(const char *fmt) const
Definition: SOP_NodeVerb.h:463
fpreal64 fpreal
Definition: SYS_Types.h:277
OP_API OP_Director * OPgetDirector()
bool selectionEnabled() const
Definition: SOP_NodeVerb.h:599
DEP_MicroNode * myDepNode
Definition: SOP_NodeVerb.h:306
UT_ErrorSeverity addError(const char *type, int code, const char *msg=0, const UT_SourceLocation *loc=0) const
Definition: SOP_NodeVerb.h:445
GA_GroupType
An ordinal enum for the different types of groups in GA.
Definition: GA_Types.h:160
GLuint index
Definition: glcorearb.h:786
UT_Map< const OP_Node *, NodeExecuteInfo > ForbiddenNodeMap
Definition: SOP_NodeVerb.h:132
SYS_FORCE_INLINE bool UTisstring(const char *s)
UT_StringHolder formatError(const char *msg) const
Prefix errors so we can get sensible results.
Definition: SOP_NodeVerb.h:645
int64 getMemoryUsage(bool inclusive) const
Definition: SOP_NodeVerb.h:39
A global error manager scope.
void resetLocalVariableAccessed() const
Tracks if any local variables were accessed by op functions.
Definition: SOP_NodeVerb.h:636
#define SOP_API
Definition: SOP_API.h:10
const GU_Detail * inputGeo(exint idx) const
Definition: SOP_NodeVerb.h:376
void setVariableOrder(int detail, int prim, int pt, int vtx) const
Definition: SOP_NodeVerb.h:631
void clearCurVertex(int index) const
Definition: SOP_NodeVerb.h:621
virtual bool cookInput(exint idx)=0
UT_StringHolder myPseudoPath
Definition: SOP_NodeVerb.h:676
**If you just want to fire and args
Definition: thread.h:609
SOP_NodeCache * cache() const
Definition: SOP_NodeVerb.h:417
fpreal getCookTime() const
Definition: SOP_NodeVerb.h:361
CookParms(GU_DetailHandle &destgdh, const UT_Array< GU_ConstDetailHandle > &inputs, OP_CookEngine cookengine, OP_Node *node, const OP_Context &context, const SOP_NodeParms *parms, SOP_NodeCache *cache, UT_ErrorManager *error, DEP_MicroNode *depnode)
Definition: SOP_NodeVerb.h:313
void clearSelection(GA_GroupType gtype) const
Definition: SOP_NodeVerb.h:585
UT_ErrorSeverity addErrorFmt(const char *fmt, std::initializer_list< UT::Format::ArgValue > args) const
Definition: SOP_NodeVerb.h:477
NodeInputs & inputs() const
Definition: SOP_NodeVerb.h:279
bool wasLocalVariableAccessed() const
Definition: SOP_NodeVerb.h:638
UT_ErrorSeverity addMessageFmt(const char *fmt, const Args &...args) const
Definition: SOP_NodeVerb.h:460
#define const
Definition: zconf.h:214
virtual bool requiresCEFlush() const
Definition: SOP_NodeVerb.h:737
int sprintf(const char *fmt,...) SYS_PRINTF_CHECK_ATTRIBUTE(2
Call VEX from C++.
Definition: CVEX_Context.h:203
type
Definition: core.h:1059
exint nInputs() const
Definition: SOP_NodeVerb.h:369
const OP_Context & myContext
Definition: SOP_NodeVerb.h:307
virtual CookMode cookMode(const SOP_NodeParms *parms) const
Definition: SOP_NodeVerb.h:730
GU_DetailHandle & gdh() const
The initial state of gdh depends on the cookMode()
Definition: SOP_NodeVerb.h:341
UT_ErrorManager * myError
Definition: SOP_NodeVerb.h:680
GLenum src
Definition: glcorearb.h:1793
OP_NodeParms * baseAllocParms() const overridefinal
Definition: SOP_NodeVerb.h:98
SOP_NodeCache * myCache
Definition: SOP_NodeVerb.h:304