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