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;
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(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) ? CAST_SOPNODE(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  OP_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  /// Returns a full path for display purposes, this will
360  /// be the node path if it is presnet, otherwise the "pseudopath",
361  /// otherwise <internal>
363  {
364  if (myNode)
365  return myNode->getFullPath();
366  if (myPseudoPath.isstring())
367  return myPseudoPath;
368  return "<internal>"_UTsh;
369  }
370  const OP_Context &getContext() const
371  { return myContext; }
373  { return myContext.getTime(); }
374 
375  /// Accessors designed to simplify porting from old cook code.
376  /// Just becaues you have nInputs does not mean all are wired or
377  /// cooked. But, the number demanded by your OP_Operator shall
378  /// be present.
379  /// Inputs have been locked & preserve request set
380  exint nInputs() const { return myInputs.size(); }
381  bool hasInput(exint idx) const
382  {
383  if (idx < 0 || idx >= myInputs.size())
384  return false;
385  return myInputs(idx).isValid();
386  }
387  const GU_Detail *inputGeo(exint idx) const
388  {
389  if (!hasInput(idx)) return 0;
390  return myInputs(idx).gdp();
391  }
393  {
394  if (!hasInput(idx)) return GU_ConstDetailHandle();
395  return myInputs(idx);
396  }
397 
398  /// Accessors to get to the expression, ie, spare, inputs
399  /// index is the positive index for the spare input.
401  {
402  if (!myExprInputs) return 0;
403  return myExprInputs->size();
404  }
405  bool hasSpareInput(exint idx) const
406  {
407  if (!myExprInputs) return false;
408  if (idx < 0 || idx > myExprInputs->size()) return false;
409  return (*myExprInputs)(idx).isValid();
410  }
411  const GU_Detail *spareInputGeo(exint idx) const
412  {
413  if (!hasSpareInput(idx)) return nullptr;
414  return (*myExprInputs)(idx).gdp();
415  }
417  {
418  if (!hasSpareInput(idx)) return GU_ConstDetailHandle();
419  return (*myExprInputs)(idx);
420  }
421 
422  template <typename T>
423  const T &parms() const
424  { return *UTverify_cast<const T*>(myParms); }
425 
426  /// Cache may, or may not, persist between cooks. But it is
427  /// guaranteed this is the only thread using the cache.
428  SOP_NodeCache *cache() const { return myCache; }
429 
430  /// Error managers are not locked, so do not pass this to
431  /// something that forks.
432  UT_ErrorManager *error() const { return myError; }
433  DEP_MicroNode *depnode() const { return myDepNode; }
434 
435  // NOTE: Do not hold onto the ptr object longer than necessary!
438  {
440  *myError, myErrorLock);
441  }
442 
443  /// Methods to wire directly to the optional depnode.
444  void addExplicitInput(DEP_MicroNode &inp, bool check_dup=true) const
445  { if (myDepNode) myDepNode->addExplicitInput(inp, check_dup); }
446 
447  /// Methods to add directly to any present error manager.
448  UT_ErrorSeverity addMessage (const char *type, int code, const char *msg=0,
449  const UT_SourceLocation *loc=0) const
450  { if (myError) return getLockedErrorManager()->addMessage(type, code, formatError(msg), loc);
451  return UT_ERROR_MESSAGE; }
452  UT_ErrorSeverity addWarning (const char *type, int code, const char *msg=0,
453  const UT_SourceLocation *loc=0) const
454  { if (myError) return getLockedErrorManager()->addWarning(type, code, formatError(msg), loc);
455  return UT_ERROR_WARNING; }
456  UT_ErrorSeverity addError (const char *type, int code, const char *msg=0,
457  const UT_SourceLocation *loc=0) const
458  { if (myError) return getLockedErrorManager()->addError(type, code, formatError(msg), loc);
459  return UT_ERROR_ABORT; }
460 
461 
462  UT_ErrorSeverity addMessageFmt(const char *fmt) const
463  { return addMessage("SOP", SOP_MESSAGE, fmt); }
464  UT_ErrorSeverity addMessageFmt(const char *fmt, std::initializer_list<UT::Format::ArgValue> args) const
465  {
466  UT_WorkBuffer work;
467  work.appendFormat(fmt, args);
468  return addMessageFmt(work.buffer());
469  }
470  template<typename... Args>
471  UT_ErrorSeverity addMessageFmt(const char *fmt, const Args &...args) const
472  { return addMessageFmt(fmt, {args...}); }
473 
474  UT_ErrorSeverity addWarningFmt(const char *fmt) const
475  { return addWarning("SOP", SOP_MESSAGE, fmt); }
476  UT_ErrorSeverity addWarningFmt( const char *fmt, std::initializer_list<UT::Format::ArgValue> args) const
477  {
478  UT_WorkBuffer work;
479  work.appendFormat(fmt, args);
480  return addWarningFmt(work.buffer());
481  }
482  template<typename... Args>
483  UT_ErrorSeverity addWarningFmt(const char *fmt, const Args &...args) const
484  { return addWarningFmt(fmt, {args...}); }
485 
486  UT_ErrorSeverity addErrorFmt(const char *fmt) const
487  { return addError("SOP", SOP_MESSAGE, fmt); }
488  UT_ErrorSeverity addErrorFmt(const char *fmt, std::initializer_list<UT::Format::ArgValue> args) const
489  {
490  UT_WorkBuffer work;
491  work.appendFormat(fmt, args);
492  return addErrorFmt(work.buffer());
493  }
494  template<typename... Args>
495  UT_ErrorSeverity addErrorFmt(const char *fmt, const Args &...args) const
496  { return addErrorFmt(fmt, {args...}); }
497 
498  // Note that these methods first expand the error message using the
499  // provided `code` & `msg`, then pass along the expanded result using
500  // the `SOP_MESSAGE` code, so that the message can be properly prefixed
501  // using the name of the associated node.
502  UT_ErrorSeverity sopAddMessage (int code, const char *msg=0,
503  const UT_SourceLocation *loc=0) const
504  {
505  UT_WorkBuffer errbuf;
506  UT_Error("SOP", code, msg).getErrorFormattedString(errbuf);
507  return addMessage("SOP", SOP_MESSAGE, errbuf.buffer(), loc);
508  }
509  UT_ErrorSeverity sopAddWarning (int code, const char *msg=0,
510  const UT_SourceLocation *loc=0) const
511  {
512  UT_WorkBuffer errbuf;
513  UT_Error("SOP", code, msg).getErrorFormattedString(errbuf);
514  return addWarning("SOP", SOP_MESSAGE, errbuf.buffer(), loc);
515  }
516  UT_ErrorSeverity sopAddError (int code, const char *msg=0,
517  const UT_SourceLocation *loc=0) const
518  {
519  UT_WorkBuffer errbuf;
520  UT_Error("SOP", code, msg).getErrorFormattedString(errbuf);
521  return addError("SOP", SOP_MESSAGE, errbuf.buffer(), loc);
522  }
523 
524  void addTransformError(const OP_Node &node, const char *label=0) const
525  {
526  UT_String path;
527  node.getFullPath(path);
528  if (UTisstring(label))
529  {
530  path += "(as "; path += label; path += ")";
531  }
532  addError("OP", OP_ERR_TRANSFORM, path);
533  }
534 
536  bool borrow_only = false) const
537  { if (myError) getLockedErrorManager()->stealErrors(src,0, -1, UT_ERROR_NONE, borrow_only); }
538 
540  { if (getNode())
541  getNode()->select(gtype); }
542 
544  bool add_to_sel = false) const
545  { if (getNode())
546  getNode()->select(selection, add_to_sel); }
547 
548  // Select the group. opt use its type as sel type
549  void select(const GA_Group &group, bool use_gtype = true,
550  bool add_to_sel = false) const
551  { if (getNode())
552  getNode()->select(group, use_gtype, add_to_sel); }
553 
554  void select(const GEO_Primitive &prim, bool sel_prim = true,
555  bool add_to_sel = false) const
556  { if (getNode())
557  getNode()->select(prim, sel_prim, add_to_sel); }
558  void selectPrimitive(GA_Offset primoff, bool prim_sel = true,
559  bool add_to_sel = false) const
560  { if (getNode())
561  getNode()->selectPrimitive(primoff, prim_sel, add_to_sel); }
562  void selectPoint(GA_Offset ptoff, bool point_sel = true,
563  bool add_to_sel = false) const
564  { if (getNode())
565  getNode()->selectPoint(ptoff, point_sel, add_to_sel); }
566  void selectFrom(const GEO_Primitive &prim, bool sel_prim = true,
567  bool add_to_sel = false) const
568  { if (getNode())
569  getNode()->selectFrom(prim, sel_prim, add_to_sel); }
570  void selectPointsFrom(GA_Offset ptoff, bool point_sel = true,
571  bool add_to_sel = false) const
572  { if (getNode())
573  getNode()->selectPointsFrom(ptoff, point_sel, add_to_sel); }
574  void select(const GA_Range &range, bool use_rtype = true,
575  bool add_to_sel = false) const
576  { if (getNode())
577  getNode()->select(range, use_rtype, add_to_sel); }
578 
579  // Selects input based on the group supplied and the group type. If
580  // group is not null, then it's type is used, otherwise the group type
581  // is used.
582  void selectInputGroup(const GA_Group *group,
583  GA_GroupType grouptype) const
584  { if (getNode())
585  getNode()->selectInputGroup(group, grouptype); }
586 
587  // If no selection is present, then create a new empty primitive cook
588  // selection group. Otherwise, clear the selection.
589  void clearSelection() const
590  { if (getNode())
591  getNode()->clearSelection(); }
592 
593  /// If the cook selection group is not of the given type, create an empty
594  /// cook selection group of that type. Otherwise, clear the existing cook
595  /// selection group.
596  void clearSelection(GA_GroupType gtype) const
597  { if (getNode())
598  getNode()->clearSelection(gtype); }
599 
600  // Blow away the selection and reinitialize it to 0. Much more radical
601  // than clearSelection(), which leaves behind a clean, empty selection.
602  // This method returns 1 if it had anything to destroy, else 0.
603  bool destroySelection() const
604  { if (getNode())
605  return getNode()->destroySelection();
606  return false;
607  }
608 
609  // Return 1 if selection is enabled, 0 if false.
610  bool selectionEnabled() const
611  {
612  if (!getNode())
613  return false;
614  return getNode()->getHighlight();
615  }
616 
617  /// Shims for local variables
618  bool setupLocalVars() const
619  { if (getNode()) return getNode()->setupLocalVars(); return false; }
620  void resetLocalVarRefs() const
621  { if (getNode()) getNode()->resetLocalVarRefs(); }
622  void setCurGdh(int index, const GU_DetailHandle &gdh) const
623  { if (getNode()) getNode()->setCurGdh(index, gdh); }
624  void clearCurGdh(int index) const
625  { if (getNode()) getNode()->clearCurGdh(index); }
626  void setCurPoint(int index, GA_Offset off) const
627  { if (getNode()) getNode()->setCurPoint(index, off); }
628  void clearCurPoint(int index) const
629  { if (getNode()) getNode()->clearCurPoint(index); }
630  void setCurVertex(int index, GA_Offset off) const
631  { if (getNode()) getNode()->setCurVertex(index, off); }
632  void clearCurVertex(int index) const
633  { if (getNode()) getNode()->clearCurVertex(index); }
634  void setCurPrim(int index, GA_Offset off) const
635  { if (getNode()) getNode()->setCurPrim(index, off); }
636  void clearCurPrim(int index) const
637  { if (getNode()) getNode()->clearCurPrim(index); }
638  void setCurVertexNum(int index, exint num) const
639  { if (getNode()) getNode()->setCurVertexNum(index, num); }
640  void clearCurVertexNum(int index) const
641  { if (getNode()) getNode()->clearCurVertexNum(index); }
642  void setVariableOrder(int detail, int prim,
643  int pt, int vtx) const
644  { if (getNode()) getNode()->setVariableOrder(detail, prim, pt, vtx); }
645 
646  /// Tracks if any local variables were accessed by op functions.
648  { if (getNode()) getNode()->myUsesSOPLocalVar = false; }
650  { if (!getNode()) return false;
651  return getNode()->myUsesSOPLocalVar; }
652 
653 
654  protected:
655  /// Prefix errors so we can get sensible results.
656  UT_StringHolder formatError(const char *msg) const
657  {
658  // Do not prefix with the path in traditional cook
659  // as it is properly assigned.
660  if (myCookEngine == OP_COOK_TRADITIONAL)
661  return msg;
663  if (!msg || !*msg)
664  return result;
666  UT_StringHolder fullpath;
667  fullpath = getFullPathForDisplay();
668  buf.sprintf("%s: %s", (const char *) fullpath, msg);
669  result = buf;
670  return result;
671  }
672 
686  };
687 
688  /// If doPartialInputCook is false, we do assume cookInputs() will
689  /// apply to all inputs regardless of node parameters. If local
690  /// variables require the inputs, it is required for this to be false
691  /// for the inputs to be available when parameters are evaluated.
692  virtual bool doPartialInputCook() const { return false; }
693 
694  /// If doExprInputCook is true, we will also cook all expression inputs
695  /// in cookInputs using the default method.
696  virtual bool doExprInputCook() const { return false ; }
697 
698  virtual bool cookInputs(const InputParms &parms) const
699  {
700  for (exint i = 0; i < parms.inputs().nInputs(); i++)
701  if (parms.inputs().hasInput(i))
702  {
703  if (!parms.inputs().cookInput(i))
704  return false;
705  }
706  for (exint i = 0; i < parms.exprinputs().nInputs(); i++)
707  if (parms.exprinputs().hasInput(i))
708  {
709  if (!parms.exprinputs().cookInput(i))
710  return false;
711  }
712  return true;
713  }
714 
715  /// These are for the old-cook path to allow nodes to store relevant
716  /// local variable information inside the SOP for callbacks. The
717  /// evalVariableValue() should be guarded to ensure it doesn't
718  /// run from a forbidden node.
719  /// These can be used if the local variables depend only on the inputs
720  /// and are not change for every parameter. If they change for
721  /// every parameter, traditional cook paths will need to setup &
722  /// evaluate explicitly in the cook method.
723  virtual void setupLocalVariables(SOP_Node *sop, const UT_Array<GU_ConstDetailHandle> &inputs) const {}
724  virtual void resetLocalVariables(SOP_Node *sop) const {}
725 
726  /// Traditional nodes may evaluate parameters while cooking, this is
727  /// required for dynamic local variables. If this is true, no pre-cooking
728  /// of the parameter struture will be done in the traditional cook
729  /// path avoiding double cooking parameters. Remember other cook paths
730  /// will not have access to the sop so should use the parameter structure!
731  virtual bool evaluatesParametersDuringCook() const { return false; }
732 
733  virtual CookMode cookMode(const SOP_NodeParms *parms) const { return COOK_DUPLICATE; }
734 
735  /// Whether this verb's APEX callback will use an in-place port.
736  /// Typically verbs that use a COOK_INPLACE or a COOK_PASSTHROUGH cook mode
737  /// should use an in-place port in APEX.
738  virtual bool apexInplace() const { return false; }
739 
740  /// Geometry elements can end up cached on the GPU. Some SOPs are able
741  /// to handle this. Some are ambivalent (such as switch or null)
742  /// And some expect all GPU buffers to be flushed prior to
743  /// operating.
744  /// @{
745  /// If requiresCEFlush() is true, all inputs will be flushed from the GPU
746  /// to CPU prior to being cooked.
747  virtual bool requiresCEFlush() const { return true; }
748  /// If usesCE() is true, it says some of its output geometry will still be
749  /// on the GPU, which will require flushing to be used on the CPU.
750  virtual bool usesCE() const { return false; }
751  /// @}
752 
753  /// Compute the output geometry.
754  virtual void cook(const CookParms &cookparms) const = 0;
755 
756  /// This is used to update handles, it only has an effect
757  /// if oldsop is non-null, ie, we are in the old cook path.
758  /// Neither the group nor the gdp have to persist beyond this call.
759  /// Pass -1 for the grouptype if there is no grouptype parameter.
760  void notifyGroupParmListeners(SOP_Node *oldsop,
761  int groupparm_idx,
762  int grouptype_idx,
763  const GU_Detail *gdp,
764  const GA_Group *group) const;
765 
766 protected:
767 };
768 
769 #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:483
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:622
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:433
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:109
UT_ErrorSeverity sopAddMessage(int code, const char *msg=0, const UT_SourceLocation *loc=0) const
Definition: SOP_NodeVerb.h:502
void addTransformError(const OP_Node &node, const char *label=0) const
Definition: SOP_NodeVerb.h:524
UT_ErrorSeverity sopAddWarning(int code, const char *msg=0, const UT_SourceLocation *loc=0) const
Definition: SOP_NodeVerb.h:509
SOP_NodeCache * myCache
Definition: SOP_NodeVerb.h:682
virtual bool apexInplace() const
Definition: SOP_NodeVerb.h:738
bool cookInput(exint idx) override
Definition: SOP_NodeVerb.h:231
void clearCurGdh(int index) const
Definition: SOP_NodeVerb.h:624
bool hasSpareInput(exint idx) const
Definition: SOP_NodeVerb.h:405
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:464
void selectPoint(GA_Offset ptoff, bool point_sel=true, bool add_to_sel=false) const
Definition: SOP_NodeVerb.h:562
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:448
const OP_Context & getContext() const
Definition: SOP_NodeVerb.h:295
void clearCurVertexNum(int index) const
Definition: SOP_NodeVerb.h:640
int64 exint
Definition: SYS_Types.h:125
void resetLocalVarRefs() const
Definition: SOP_NodeVerb.h:620
SYS_FORCE_INLINE const char * buffer() const
GU_ConstDetailHandle spareInputGeoHandle(exint idx) const
Definition: SOP_NodeVerb.h:416
UT_ErrorSeverity
Definition: UT_Error.h:25
UT_StringHolder getFullPathForDisplay() const
Definition: SOP_NodeVerb.h:362
UT_Array< GU_ConstDetailHandle > myExprInputs
Definition: SOP_NodeVerb.h:128
UT_ErrorSeverity addMessageFmt(const char *fmt) const
Definition: SOP_NodeVerb.h:462
void stealErrors(UT_ErrorManager &src, bool borrow_only=false) const
Definition: SOP_NodeVerb.h:535
const GU_Detail * spareInputGeo(exint idx) const
Definition: SOP_NodeVerb.h:411
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:574
const UT_Array< GU_ConstDetailHandle > & myInputs
Definition: SOP_NodeVerb.h:675
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:622
const UT_Array< GU_ConstDetailHandle > * myExprInputs
Definition: SOP_NodeVerb.h:676
bool setupLocalVars() const
Shims for local variables.
Definition: SOP_NodeVerb.h:618
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:476
OP_Node * getSrcNode() const
The node that generated this verb, if any...
Definition: SOP_NodeVerb.h:356
fpreal getCookTime() const
Definition: SOP_NodeVerb.h:297
GU_DetailHandle & myDestGdh
Definition: SOP_NodeVerb.h:674
virtual bool doPartialInputCook() const
Definition: SOP_NodeVerb.h:692
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:724
void clearCurPoint(int index) const
Definition: SOP_NodeVerb.h:628
UT_ErrorSeverity sopAddError(int code, const char *msg=0, const UT_SourceLocation *loc=0) const
Definition: SOP_NodeVerb.h:516
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:684
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:646
exint numSpareInputs() const
Definition: SOP_NodeVerb.h:400
GU_DetailHandle unloadInput(exint idx, bool flushce) override
Definition: SOP_NodeVerb.h:244
UT_ErrorSeverity addErrorFmt(const char *fmt) const
Definition: SOP_NodeVerb.h:486
GU_ConstDetailHandle inputGeoHandle(exint idx) const
Definition: SOP_NodeVerb.h:392
const char * getFullPath(UT_String &str) const
Definition: PRM_ParmOwner.h:54
const T & parms() const
Definition: SOP_NodeVerb.h:423
const SOP_NodeParms * myParms
Definition: SOP_NodeVerb.h:681
virtual void setupLocalVariables(SOP_Node *sop, const UT_Array< GU_ConstDetailHandle > &inputs) const
Definition: SOP_NodeVerb.h:723
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:444
GLint GLint GLsizei GLint GLenum GLenum type
Definition: glcorearb.h:108
void selectPrimitive(GA_Offset primoff, bool prim_sel=true, bool add_to_sel=false) const
Definition: SOP_NodeVerb.h:558
OP_CookEngine myCookEngine
Definition: SOP_NodeVerb.h:673
void setCurPrim(int index, GA_Offset off) const
Definition: SOP_NodeVerb.h:634
UT_ErrorManager * myError
Definition: SOP_NodeVerb.h:305
UT_ErrorSeverity addErrorFmt(const char *fmt, const Args &...args) const
Definition: SOP_NodeVerb.h:495
bool destroySelection() const
Definition: SOP_NodeVerb.h:603
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:543
virtual bool doExprInputCook() const
Definition: SOP_NodeVerb.h:696
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:566
int hasInput() override
void clearSelection() const
Definition: SOP_NodeVerb.h:589
virtual bool usesCE() const
Definition: SOP_NodeVerb.h:750
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:626
void selectInputGroup(const GA_Group *group, GA_GroupType grouptype) const
Definition: SOP_NodeVerb.h:582
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:570
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:370
void clearCurPrim(int index) const
Definition: SOP_NodeVerb.h:636
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:731
void setCurVertexNum(int index, exint num) const
Definition: SOP_NodeVerb.h:638
void select(GA_GroupType gtype=GA_GROUP_PRIMITIVE) const
Definition: SOP_NodeVerb.h:539
UT_SharedPtr< GU_Selection > GU_SelectionHandle
virtual bool cookInputs(const InputParms &parms) const
Definition: SOP_NodeVerb.h:698
UT_ErrorManager * error() const
Definition: SOP_NodeVerb.h:432
bool hasInput(exint idx) const
Definition: SOP_NodeVerb.h:381
const OP_Context & myContext
Definition: SOP_NodeVerb.h:680
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:554
UT_ErrorSeverity addWarning(const char *type, int code, const char *msg=0, const UT_SourceLocation *loc=0) const
Definition: SOP_NodeVerb.h:452
**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:437
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:630
GA_API const UT_StringHolder parms
void select(const GA_Group &group, bool use_gtype=true, bool add_to_sel=false) const
Definition: SOP_NodeVerb.h:549
A class holding a VEX function.
Definition: CVEX_Function.h:30
UT_ErrorSeverity addWarningFmt(const char *fmt) const
Definition: SOP_NodeVerb.h:474
fpreal64 fpreal
Definition: SYS_Types.h:278
LeafData & operator=(const LeafData &)=delete
OP_API OP_Director * OPgetDirector()
bool selectionEnabled() const
Definition: SOP_NodeVerb.h:610
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:456
GA_GroupType
An ordinal enum for the different types of groups in GA.
Definition: GA_Types.h:161
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:656
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:647
#define SOP_API
Definition: SOP_API.h:10
const GU_Detail * inputGeo(exint idx) const
Definition: SOP_NodeVerb.h:387
void setVariableOrder(int detail, int prim, int pt, int vtx) const
Definition: SOP_NodeVerb.h:642
void clearCurVertex(int index) const
Definition: SOP_NodeVerb.h:632
virtual bool cookInput(exint idx)=0
UT_StringHolder myPseudoPath
Definition: SOP_NodeVerb.h:679
**If you just want to fire and args
Definition: thread.h:618
SOP_NodeCache * cache() const
Definition: SOP_NodeVerb.h:428
fpreal getCookTime() const
Definition: SOP_NodeVerb.h:372
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:596
UT_ErrorSeverity addErrorFmt(const char *fmt, std::initializer_list< UT::Format::ArgValue > args) const
Definition: SOP_NodeVerb.h:488
NodeInputs & inputs() const
Definition: SOP_NodeVerb.h:279
bool wasLocalVariableAccessed() const
Definition: SOP_NodeVerb.h:649
UT_ErrorSeverity addMessageFmt(const char *fmt, const Args &...args) const
Definition: SOP_NodeVerb.h:471
virtual bool requiresCEFlush() const
Definition: SOP_NodeVerb.h:747
Call VEX from C++.
Definition: CVEX_Context.h:203
exint nInputs() const
Definition: SOP_NodeVerb.h:380
const OP_Context & myContext
Definition: SOP_NodeVerb.h:307
virtual CookMode cookMode(const SOP_NodeParms *parms) const
Definition: SOP_NodeVerb.h:733
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:683
GLenum src
Definition: glcorearb.h:1793
OP_NodeParms * baseAllocParms() const overridefinal
Definition: SOP_NodeVerb.h:98
SOP_NodeCache * myCache
Definition: SOP_NodeVerb.h:304