OpenVDB  12.0.0
ParmFactory.h
Go to the documentation of this file.
1 // Copyright Contributors to the OpenVDB Project
2 // SPDX-License-Identifier: Apache-2.0
3 //
4 /// @file ParmFactory.h
5 /// @author FX R&D OpenVDB team
6 ///
7 /// @brief A collection of factory methods and helper functions
8 /// to simplify Houdini plugin development and maintenance.
9 
10 #ifndef HOUDINI_UTILS_PARM_FACTORY_HAS_BEEN_INCLUDED
11 #define HOUDINI_UTILS_PARM_FACTORY_HAS_BEEN_INCLUDED
12 
13 #include <GA/GA_Attribute.h>
14 #include <OP/OP_AutoLockInputs.h>
15 #include <OP/OP_Operator.h>
16 #include <PRM/PRM_Include.h>
17 #include <PRM/PRM_SpareData.h>
18 #include <SOP/SOP_Node.h>
19 #include <SOP/SOP_NodeVerb.h>
20 #if defined(PRODDEV_BUILD) || defined(DWREAL_IS_DOUBLE)
21  // OPENVDB_HOUDINI_API, which has no meaning in a DWA build environment but
22  // must at least exist, is normally defined by including openvdb/Platform.h.
23  // For DWA builds (i.e., if either PRODDEV_BUILD or DWREAL_IS_DOUBLE exists),
24  // that introduces an unwanted and unnecessary library dependency.
25  #ifndef OPENVDB_HOUDINI_API
26  #define OPENVDB_HOUDINI_API
27  #endif
28 #else
29  #include <openvdb/version.h>
30 #endif
31 #include <exception>
32 #include <functional>
33 #include <map>
34 #include <memory>
35 #include <string>
36 #include <vector>
37 
38 
39 #ifdef SESI_OPENVDB
40  #ifdef OPENVDB_HOUDINI_API
41  #undef OPENVDB_HOUDINI_API
42  #define OPENVDB_HOUDINI_API
43  #endif
44 #endif
45 
46 
47 class GU_Detail;
48 class OP_OperatorTable;
49 class PRM_Parm;
50 
51 namespace houdini_utils {
52 
53 class ParmFactory;
54 
55 using SpareDataMap = std::map<std::string, std::string>;
56 
57 /// @brief Return the spare data associated with the given operator.
58 /// @details Only operators created with OpFactory will have spare data.
59 /// @sa @link addOperatorSpareData() addOperatorSpareData@endlink,
60 /// @link OpFactory::addSpareData() OpFactory::addSpareData@endlink
61 const SpareDataMap& getOperatorSpareData(const OP_Operator&);
62 
63 /// @brief Specify (@e key, @e value) pairs of spare data for the given operator.
64 /// @details For existing keys, the new value replaces the old one.
65 /// @throw std::runtime_error if the given operator does not support spare data
66 /// (only operators created with OpFactory will have spare data)
67 /// @sa @link getOperatorSpareData() getOperatorSpareData@endlink,
68 /// @link OpFactory::addSpareData() OpFactory::addSpareData@endlink
69 void addOperatorSpareData(OP_Operator&, const SpareDataMap&);
70 
71 
72 /// @brief Parameter template list that is always terminated.
74 {
75 public:
76  using PrmTemplateVec = std::vector<PRM_Template>;
77 
78  ParmList() {}
79 
80  /// @brief Return @c true if this list contains no parameters.
81  bool empty() const { return mParmVec.empty(); }
82  /// @brief Return the number of parameters in this list.
83  /// @note Some parameter types have parameter lists of their own.
84  /// Those nested lists are not included in this count.
85  size_t size() const { return mParmVec.size(); }
86 
87  /// @brief Remove all parameters from this list.
88  void clear() { mParmVec.clear(); mSwitchers.clear(); }
89 
90  /// @{
91  /// @brief Add a parameter to this list.
92  ParmList& add(const PRM_Template&);
93  ParmList& add(const ParmFactory&);
94  /// @}
95 
96  /// @brief Begin a collection of tabs.
97  /// @details Tabs may be nested.
98  ParmList& beginSwitcher(const std::string& token, const std::string& label = "");
99  /// @brief Begin an exclusive collection of tabs. Only one tab is "active" at a time.
100  /// @details Tabs may be nested.
101  ParmList& beginExclusiveSwitcher(const std::string& token, const std::string& label = "");
102  /// @brief End a collection of tabs.
103  /// @throw std::runtime_error if not inside a switcher or if no tabs
104  /// were added to the switcher
105  ParmList& endSwitcher();
106 
107  /// @brief Add a tab with the given label to the current tab collection.
108  /// @details Parameters subsequently added to this ParmList until the next
109  /// addFolder() or endSwitcher() call will be displayed on the tab.
110  /// @throw std::runtime_error if not inside a switcher
111  ParmList& addFolder(const std::string& label);
112 
113  /// Return a heap-allocated copy of this list's array of parameters.
114  PRM_Template* get() const;
115 
116 private:
117  struct SwitcherInfo { size_t parmIdx; std::vector<PRM_Default> folders; bool exclusive; };
118  using SwitcherStack = std::vector<SwitcherInfo>;
119 
120  void incFolderParmCount();
121  SwitcherInfo* getCurrentSwitcher();
122 
123  PrmTemplateVec mParmVec;
124  SwitcherStack mSwitchers;
125 }; // class ParmList
126 
127 
128 ////////////////////////////////////////
129 
130 
131 /// @class ParmFactory
132 /// @brief Helper class to simplify construction of PRM_Templates and
133 /// dynamic user interfaces.
134 ///
135 /// @par Example
136 /// @code
137 /// houdini_utils::ParmList parms;
138 ///
139 /// parms.add(houdini_utils::ParmFactory(PRM_STRING, "group", "Group")
140 /// .setHelpText("Specify a subset of the input VDB grids to be processed.")
141 /// .setChoiceList(&houdini_utils::PrimGroupMenu));
142 ///
143 /// parms.add(houdini_utils::ParmFactory(PRM_FLT_J, "tolerance", "Pruning Tolerance")
144 /// .setDefault(PRMzeroDefaults)
145 /// .setRange(PRM_RANGE_RESTRICTED, 0, PRM_RANGE_UI, 1));
146 /// @endcode
148 {
149 public:
150  ParmFactory(PRM_Type, const std::string& token, const std::string& label);
151  ParmFactory(PRM_MultiType, const std::string& token, const std::string& label);
152 
153  // Settings
154  ParmFactory& setCallbackFunc(const PRM_Callback&);
155 
156  /// Specify a menu of values for this parameter.
157  ParmFactory& setChoiceList(const PRM_ChoiceList*);
158  /// @brief Specify a menu type and a list of token, label, token, label,... pairs
159  /// for this parameter.
160  /// @param typ specifies the menu behavior (toggle, replace, etc.)
161  /// @param items a list of token, label, token, label,... string pairs
162  ParmFactory& setChoiceListItems(PRM_ChoiceListType typ, const std::vector<std::string>& items);
163  /// @brief Specify a menu type and a list of token, label, token, label,... pairs
164  /// for this parameter.
165  /// @param typ specifies the menu behavior (toggle, replace, etc.)
166  /// @param items a list of token, label, token, label,... string pairs
167  /// @note The @a items array must be null-terminated.
168  ParmFactory& setChoiceListItems(PRM_ChoiceListType typ, const char* const* items);
169 
170  /// @brief Specify a menu of primitive group names for this parameter.
171  ///
172  /// @param inputIndex the zero-based index of the input from which to get primitive groups
173  /// @param typ the menu behavior (toggle, replace, etc.)
174  ///
175  /// @details Calling this method with the default (toggle) behavior is equivalent
176  /// to calling @c setChoiceList(&houdini_utils::PrimGroupMenuInput1),
177  /// @c setChoiceList(&houdini_utils::PrimGroupMenuInput2), etc.
178  ///
179  /// @par Example
180  /// To limit the user to choosing a single primitive group, replace
181  /// @code
182  /// parms.add(houdini_utils::ParmFactory(PRM_STRING, "reference", "Reference")
183  /// .setChoiceList(&houdini_utils::PrimGroupMenuInput2);
184  /// @endcode
185  /// with
186  /// @code
187  /// parms.add(houdini_utils::ParmFactory(PRM_STRING, "reference", "Reference")
188  /// .setGroupChoiceList(1, PRM_CHOICELIST_REPLACE); // input index is zero based
189  /// @endcode
190  ParmFactory& setGroupChoiceList(size_t inputIndex,
191  PRM_ChoiceListType typ = PRM_CHOICELIST_TOGGLE);
192 
193  /// @brief Functor to filter a list of attributes from a SOP's input
194  /// @details Arguments to the functor are an attribute to be filtered
195  /// and the parameter and SOP for which the filter is being called.
196  /// The functor should return @c true for attributes that should be added
197  /// to the list and @c false for attributes that should be ignored.
198  using AttrFilterFunc =
199  std::function<bool (const GA_Attribute&, const PRM_Parm&, const SOP_Node&)>;
200 
201  /// @brief Specify a menu of attribute names for this parameter.
202  ///
203  /// @param inputIndex the zero-based index of the input from which to get attributes
204  /// @param attrOwner the class of attribute with which to populate the menu:
205  /// either per-vertex (@c GA_ATTRIB_VERTEX), per-point (@c GA_ATTRIB_POINT),
206  /// per-primitive (@c GA_ATTRIB_PRIMITIVE), global (@c GA_ATTRIB_GLOBAL),
207  /// or all of the above (@c GA_ATTRIB_INVALID or any other value)
208  /// @param typ the menu behavior (toggle, replace, etc.)
209  /// @param attrFilter an optional filter functor that returns @c true for each
210  /// attribute that should appear in the menu; the functor will be moved,
211  /// if possible, or else copied
212  ///
213  /// @note This method is supported only for SOPs.
214  ///
215  /// @par Example
216  /// Create a menu that allows multiple selection from among all the string attributes
217  /// on a SOP's first input:
218  /// @code
219  /// houdini_utils::ParmList parms;
220  /// parms.add(houdini_utils::ParmFactory(PRM_STRING, "stringattr", "String Attribute")
221  /// .setAttrChoiceList(/*input=*/0, GA_ATTRIB_INVALID, PRM_CHOICELIST_TOGGLE,
222  /// [](const GA_Attribute& attr, const PRM_Parm&, const SOP_Node&) {
223  /// return (attr.getStorageClass() == GA_STORECLASS_STRING);
224  /// }));
225  /// @endcode
226  ParmFactory& setAttrChoiceList(size_t inputIndex, GA_AttributeOwner attrOwner,
227  PRM_ChoiceListType typ = PRM_CHOICELIST_TOGGLE,
228  AttrFilterFunc attrFilter = AttrFilterFunc{});
229 
230 
231 #if defined(GCC3)
232  #define IS_DEPRECATED __attribute__ ((deprecated))
233 #elif defined(_MSC_VER)
234  #define IS_DEPRECATED __declspec(deprecated)
235 #else
236  #define IS_DEPRECATED
237 #endif
238 
239  /// @brief Specify a menu type and either a list of menu item labels or a list of
240  /// token, label, token, label,... pairs for this parameter.
241  /// @param typ specifies the menu behavior (toggle, replace, etc.)
242  /// @param items a list of menu item labels or token, label, token, label,... pairs
243  /// @param paired if @c false, treat all the elements of @a items as labels and assign
244  /// them numeric tokens starting from zero; otherwise, treat the elements of @a items
245  /// as token, label, token, label,... pairs
246  /// @deprecated Use setChoiceListItems() instead. Using unpaired items may mean
247  /// less typing now, but it prevents you from reordering or deleting entries later.
248  IS_DEPRECATED ParmFactory& setChoiceList(PRM_ChoiceListType typ,
249  const std::vector<std::string>& items, bool paired = false);
250  /// @brief Specify a menu type and either a list of menu item labels or a list of
251  /// token, label, token, label,... pairs for this parameter.
252  /// @param typ specifies the menu behavior (toggle, replace, etc.)
253  /// @param items a list of menu item labels or token, label, token, label,... pairs
254  /// @param paired if @c false, treat all the elements of @a items as labels and assign
255  /// them numeric tokens starting from zero; otherwise, treat the elements of @a items
256  /// as token, label, token, label,... pairs
257  /// @note The @a items array must be null-terminated.
258  /// @deprecated Use setChoiceListItems() instead. Using unpaired items may mean
259  /// less typing now, but it prevents you from reordering or deleting entries later.
260  IS_DEPRECATED ParmFactory& setChoiceList(PRM_ChoiceListType typ,
261  const char* const* items, bool paired = false);
262 
263 #undef IS_DEPRECATED
264 
265  ParmFactory& setConditional(const PRM_ConditionalBase*);
266 
267  /// @brief Specify a default value for this parameter.
268  /// @details If the string is null, the floating-point value will be used
269  /// (but rounded if this parameter is integer-valued).
270  /// @note The string pointer must not point to a temporary.
271  ParmFactory& setDefault(fpreal, const char* = nullptr, CH_StringMeaning = CH_STRING_LITERAL);
272  /// @brief Specify a default string value for this parameter.
273  ParmFactory& setDefault(const std::string&, CH_StringMeaning = CH_STRING_LITERAL);
274  /// @brief Specify default numeric values for the vector elements of this parameter
275  /// (assuming its vector size is > 1).
276  /// @details Floating-point values will be rounded if this parameter is integer-valued.
277  ParmFactory& setDefault(const std::vector<fpreal>&);
278  /// @brief Specify default values for the vector elements of this parameter
279  /// (assuming its vector size is > 1).
280  ParmFactory& setDefault(const std::vector<PRM_Default>&);
281  /// Specify a default value or values for this parameter.
282  ParmFactory& setDefault(const PRM_Default*);
283 
284  /// @brief Specify a plain text tooltip for this parameter.
285  /// @details This method is equivalent to setTooltip()
286  ParmFactory& setHelpText(const char*);
287  /// @brief Specify a plain text tooltip for this parameter.
288  /// @details This method is equivalent to setHelpText()
289  ParmFactory& setTooltip(const char*);
290  /// @brief Add documentation for this parameter.
291  /// @details Pass a null pointer or an empty string to inhibit
292  /// the generation of documentation for this parameter.
293  /// @details The text is parsed as wiki markup.
294  /// See the Houdini <A HREF="http://www.sidefx.com/docs/houdini/help/format">
295  /// Wiki Markup Reference</A> for the syntax.
296  ParmFactory& setDocumentation(const char*);
297 
298  ParmFactory& setParmGroup(int);
299 
300  /// Specify a range for this parameter's values.
301  ParmFactory& setRange(
302  PRM_RangeFlag minFlag, fpreal minVal,
303  PRM_RangeFlag maxFlag, fpreal maxVal);
304  /// @brief Specify range for the values of this parameter's vector elements
305  /// (assuming its vector size is > 1).
306  ParmFactory& setRange(const std::vector<PRM_Range>&);
307  /// Specify a range or ranges for this parameter's values.
308  ParmFactory& setRange(const PRM_Range*);
309 
310  /// Specify (@e key, @e value) pairs of spare data for this parameter.
311  ParmFactory& setSpareData(const SpareDataMap&);
312  /// Specify spare data for this parameter.
313  ParmFactory& setSpareData(const PRM_SpareData*);
314 
315  /// @brief Specify the list of parameters for each instance of a multiparm.
316  /// @note This setting is ignored for non-multiparm parameters.
317  /// @note Parameter name tokens should include a '#' character.
318  ParmFactory& setMultiparms(const ParmList&);
319 
320  /// Specify an extended type for this parameter.
321  ParmFactory& setTypeExtended(PRM_TypeExtended);
322 
323  /// @brief Specify the number of vector elements for this parameter.
324  /// @details (The default vector size is one element.)
325  ParmFactory& setVectorSize(int);
326 
327  /// @brief Mark this parameter as hidden from the UI.
328  /// @note Marking parameters as obsolete is preferable to making them invisible as changing
329  /// invisible parameter values will still trigger a re-cook, however this is not possible
330  /// when using multi-parms.
331  ParmFactory& setInvisible();
332 
333  /// Construct and return the parameter template.
334  PRM_Template get() const;
335 
336 private:
337  struct Impl;
338  std::shared_ptr<Impl> mImpl;
339 
340  // For internal use only, and soon to be removed:
341  ParmFactory& doSetChoiceList(PRM_ChoiceListType, const std::vector<std::string>&, bool);
342  ParmFactory& doSetChoiceList(PRM_ChoiceListType, const char* const* items, bool);
343 }; // class ParmFactory
344 
345 
346 ////////////////////////////////////////
347 
348 
349 class OpPolicy;
350 using OpPolicyPtr = std::shared_ptr<OpPolicy>;
351 
352 
353 /// @brief Helper class to simplify operator registration
354 ///
355 /// @par Example
356 /// @code
357 /// void
358 /// newPopOperator(OP_OperatorTable* table)
359 /// {
360 /// houdini_utils::ParmList parms;
361 ///
362 /// parms.add(houdini_utils::ParmFactory(PRM_STRING, "group", "Group")
363 /// .setHelpText("Specify a subset of the input VDB grids to be processed.")
364 /// .setChoiceList(&houdini_utils::PrimGroupMenu));
365 ///
366 /// parms.add(...);
367 ///
368 /// ...
369 ///
370 /// houdini_utils::OpFactory(MyOpPolicy(), My Node",
371 /// POP_DW_MyNode::factory, parms, *table, houdini_utils::OpFactory::POP)
372 /// .addInput("Input geometry") // input 0 (required)
373 /// .addOptionalInput("Reference geometry"); // input 1 (optional)
374 /// }
375 /// @endcode
377 {
378 public:
379  enum OpFlavor { SOP, POP, ROP, VOP, HDA };
380 
381  /// @brief Return "SOP" for the SOP flavor, "POP" for the POP flavor, etc.
382  /// @details Useful in OpPolicy classes for constructing type and icon names.
383  static std::string flavorToString(OpFlavor);
384 
385  /// @brief Construct a factory that on destruction registers a new operator type.
386  /// @param english the operator's UI name, as it should appear in menus
387  /// @param ctor a factory function that creates operators of this type
388  /// @param parms the parameter template list for operators of this type
389  /// @param table the registry to which to add this operator type
390  /// @param flavor the operator's class (SOP, POP, etc.)
391  /// @details @c OpPolicyType specifies the type of OpPolicy to be used to control
392  /// the factory's behavior. The (unused) @c OpPolicyType argument is required
393  /// to enable the compiler to infer the type of the template argument
394  /// (there is no other way to invoke a templated constructor).
395  template<typename OpPolicyType>
396  OpFactory(const OpPolicyType& /*unused*/, const std::string& english,
397  OP_Constructor ctor, ParmList& parms, OP_OperatorTable& table, OpFlavor flavor = SOP)
398  {
399  this->init(OpPolicyPtr(new OpPolicyType), english, ctor, parms, table, flavor);
400  }
401 
402  /// @note Factories initialized with this constructor use the DWAOpPolicy.
403  OpFactory(const std::string& english, OP_Constructor ctor,
404  ParmList& parms, OP_OperatorTable& table, OpFlavor flavor = SOP);
405 
406  /// Register the operator.
407  virtual ~OpFactory();
408 
409  OpFactory(const OpFactory&) = delete;
410  OpFactory& operator=(const OpFactory&) = delete;
411 
412  /// @brief Return the new operator's flavor (SOP, POP, etc.).
413  /// @details This accessor is mainly for use by OpPolicy objects.
414  OpFlavor flavor() const;
415  /// @brief Return the new operator's flavor as a string ("SOP", "POP", etc.).
416  /// @details This accessor is mainly for use by OpPolicy objects.
417  std::string flavorString() const;
418  /// @brief Return the new operator's type name.
419  /// @details This accessor is mainly for use by OpPolicy objects.
420  const std::string& name() const;
421  /// @brief Return the new operator's UI name.
422  /// @details This accessor is mainly for use by OpPolicy objects.
423  const std::string& english() const;
424  /// @brief Return the new operator's icon name.
425  /// @details This accessor is mainly for use by OpPolicy objects.
426  const std::string& iconName() const;
427  /// @brief Return the new operator's help URL.
428  /// @details This accessor is mainly for use by OpPolicy objects.
429  /// @note A help URL takes precedence over help text.
430  /// @sa helpText(), setHelpText()
431  const std::string& helpURL() const;
432  /// @brief Return the new operator's documentation.
433  /// @note If the help URL is nonempty, the URL takes precedence over any help text.
434  /// @sa helpURL(), setDocumentation()
435  const std::string& documentation() const;
436  /// @brief Return the operator table with which this factory is associated.
437  /// @details This accessor is mainly for use by OpPolicy objects.
438  const OP_OperatorTable& table() const;
439 
440  /// @brief Construct a type name for this operator from the given English name
441  /// and add it as an alias.
442  /// @details For backward compatibility when an operator needs to be renamed,
443  /// add the old name as an alias.
444  OpFactory& addAlias(const std::string& english);
445  /// @brief Add an alias for this operator.
446  /// @details For backward compatibility when an operator needs to be renamed,
447  /// add the old name as an alias.
448  /// @note This variant takes an operator type name rather than an English name.
449  OpFactory& addAliasVerbatim(const std::string& name);
450  /// @brief Add documentation for this operator.
451  /// @details The text is parsed as wiki markup.
452  /// @note If this factory's OpPolicy specifies a help URL, that URL
453  /// takes precedence over documentation supplied with this method.
454  OpFactory& setDocumentation(const std::string&);
455  /// Add a required input with the given name.
456  OpFactory& addInput(const std::string& name);
457  /// Add an optional input with the given name.
458  OpFactory& addOptionalInput(const std::string& name);
459  /// @brief Set the maximum number of inputs allowed by this operator.
460  /// @note It is only necessary to set this limit if there are inputs
461  /// that have not been named with addInput() or addOptionalInput().
462  OpFactory& setMaxInputs(unsigned = 9999);
463  /// Specify obsolete parameters to this operator.
464  OpFactory& setObsoleteParms(const ParmList&);
465  /// Add one or more local variables to this operator.
466  OpFactory& setLocalVariables(CH_LocalVariable*);
467  OpFactory& setFlags(unsigned);
468  OpFactory& setInternalName(const std::string& name);
469  OpFactory& setOperatorTable(const std::string& name);
470 
471  /// @brief Functor that returns newly-allocated node caches
472  /// for instances of this operator
473  /// @details A node cache encapsulates a SOP's cooking logic for thread safety.
474  /// Input geometry and parameter values are baked into the cache.
475  using CacheAllocFunc = std::function<SOP_NodeCache* (void)>;
476 
477  /// @brief Register this operator as a
478  /// <A HREF="http://www.sidefx.com/docs/houdini/model/compile">compilable</A>&nbsp;SOP.
479  /// @details "Verbifying" a SOP separates its input and parameter management
480  /// from its cooking logic so that cooking can be safely threaded.
481  /// @param cookMode how to initialize the output detail
482  /// @param allocator a node cache allocator for instances of this operator
483  /// @throw std::runtime_error if this operator is not a SOP
484  /// @throw std::invalid_argument if @a allocator is empty
485  OpFactory& setVerb(SOP_NodeVerb::CookMode cookMode, const CacheAllocFunc& allocator);
486 
487  /// @brief Mark this node as hidden from the UI tab menu.
488  /// @details This is equivalent to using the hscript ophide method.
489  OpFactory& setInvisible();
490 
491  /// @brief Specify (@e key, @e value) pairs of spare data for this operator.
492  /// @details If a key already exists, its corresponding value will be
493  /// overwritten with the new value.
494  /// @sa @link addOperatorSpareData() addOperatorSpareData@endlink,
495  /// @link getOperatorSpareData() getOperatorSpareData@endlink
496  OpFactory& addSpareData(const SpareDataMap&);
497 
498 protected:
499  /// @brief Return the operator table with which this factory is associated.
500  /// @details This accessor is mainly for use by derived OpFactory classes.
501  OP_OperatorTable& table();
502 
503 private:
504  void init(OpPolicyPtr, const std::string& english, OP_Constructor,
505  ParmList&, OP_OperatorTable&, OpFlavor);
506 
507  struct Impl;
508  std::shared_ptr<Impl> mImpl;
509 }; // class OpFactory
510 
511 
512 ////////////////////////////////////////
513 
514 
515 /// @brief An OpPolicy customizes the behavior of an OpFactory.
516 /// This base class specifies the required interface.
518 {
519 public:
520  OpPolicy() {}
521  virtual ~OpPolicy() {}
522 
523  /// @brief Return a type name for the operator defined by the given factory.
524  std::string getName(const OpFactory& factory) { return getName(factory, factory.english()); }
525 
526  /// @brief Convert an English name into a type name for the operator defined by
527  /// the given factory, and return the result.
528  /// @details In this base class implementation, the operator's type name is generated
529  /// by calling @c UT_String::forceValidVariableName() on the English name.
530  /// @note This function might be called (from OpFactory::addAlias(), for example)
531  /// with an English name other than the one returned by
532  /// factory.@link OpFactory::english() english()@endlink.
533  virtual std::string getName(const OpFactory& factory, const std::string& english);
534 
535  /// @brief Return an icon name for the operator defined by the given factory.
536  /// @details Return an empty string to use Houdini's default icon naming scheme.
537  virtual std::string getIconName(const OpFactory&) { return ""; }
538 
539  /// @brief Return a help URL for the operator defined by the given factory.
540  virtual std::string getHelpURL(const OpFactory&) { return ""; }
541 
542  /// @brief Return a label name for the operator defined by the given factory.
543  /// @details In this base class implementation, this method simply returns
544  /// factory.@link OpFactory::english() english()@endlink.
545  virtual std::string getLabelName(const OpFactory&);
546 
547  /// @brief Return the inital default name of the operator.
548  /// @note An empty first name will disable, reverting to the usual rules.
549  virtual std::string getFirstName(const OpFactory&) { return ""; }
550 
551  /// @brief Return the tab sub-menu path of the op.
552  /// @note An empty path will disable, reverting to the usual rules.
553  virtual std::string getTabSubMenuPath(const OpFactory&) { return ""; }
554 };
555 
556 
557 ////////////////////////////////////////
558 
559 
560 /// @brief Helper class to manage input locking.
562 {
563 public:
564  ScopedInputLock(SOP_Node& node, OP_Context& context)
565  {
566  mLock.setNode(&node);
567  if (mLock.lock(context) >= UT_ERROR_ABORT) {
568  throw std::runtime_error("failed to lock inputs");
569  }
570  }
572 
573  void markInputUnlocked(exint input) { mLock.markInputUnlocked(input); }
574 
575 private:
576  OP_AutoLockInputs mLock;
577 };
578 
579 
580 ////////////////////////////////////////
581 
582 
583 // Extended group name drop-down menu incorporating "@<attr>=<value" syntax
584 
585 OPENVDB_HOUDINI_API extern const PRM_ChoiceList PrimGroupMenuInput1;
586 OPENVDB_HOUDINI_API extern const PRM_ChoiceList PrimGroupMenuInput2;
587 OPENVDB_HOUDINI_API extern const PRM_ChoiceList PrimGroupMenuInput3;
588 OPENVDB_HOUDINI_API extern const PRM_ChoiceList PrimGroupMenuInput4;
589 
590 /// @note Use this if you have more than 4 inputs, otherwise use
591 /// the input specific menus instead which automatically
592 /// handle the appropriate spare data settings.
593 OPENVDB_HOUDINI_API extern const PRM_ChoiceList PrimGroupMenu;
594 
595 
596 } // namespace houdini_utils
597 
598 #endif // HOUDINI_UTILS_PARM_FACTORY_HAS_BEEN_INCLUDED
OPENVDB_HOUDINI_API const PRM_ChoiceList PrimGroupMenuInput3
ParmList()
Definition: ParmFactory.h:78
OPENVDB_HOUDINI_API const PRM_ChoiceList PrimGroupMenuInput1
virtual std::string getTabSubMenuPath(const OpFactory &)
Return the tab sub-menu path of the op.
Definition: ParmFactory.h:553
OpFlavor
Definition: ParmFactory.h:379
virtual std::string getFirstName(const OpFactory &)
Return the inital default name of the operator.
Definition: ParmFactory.h:549
virtual std::string getIconName(const OpFactory &)
Return an icon name for the operator defined by the given factory.
Definition: ParmFactory.h:537
Definition: ParmFactory.h:51
std::map< std::string, std::string > SpareDataMap
Definition: ParmFactory.h:55
Helper class to simplify construction of PRM_Templates and dynamic user interfaces.
Definition: ParmFactory.h:147
#define OPENVDB_HOUDINI_API
Definition: Platform.h:276
std::function< bool(const GA_Attribute &, const PRM_Parm &, const SOP_Node &)> AttrFilterFunc
Functor to filter a list of attributes from a SOP&#39;s input.
Definition: ParmFactory.h:199
const std::string & english() const
Return the new operator&#39;s UI name.
std::vector< PRM_Template > PrmTemplateVec
Definition: ParmFactory.h:76
Parameter template list that is always terminated.
Definition: ParmFactory.h:73
std::function< SOP_NodeCache *(void)> CacheAllocFunc
Functor that returns newly-allocated node caches for instances of this operator.
Definition: ParmFactory.h:475
OpPolicy()
Definition: ParmFactory.h:520
bool empty() const
Return true if this list contains no parameters.
Definition: ParmFactory.h:81
OpFactory(const OpPolicyType &, const std::string &english, OP_Constructor ctor, ParmList &parms, OP_OperatorTable &table, OpFlavor flavor=SOP)
Construct a factory that on destruction registers a new operator type.
Definition: ParmFactory.h:396
Helper class to manage input locking.
Definition: ParmFactory.h:561
std::string getName(const OpFactory &factory)
Return a type name for the operator defined by the given factory.
Definition: ParmFactory.h:524
#define IS_DEPRECATED
Definition: ParmFactory.h:236
virtual std::string getHelpURL(const OpFactory &)
Return a help URL for the operator defined by the given factory.
Definition: ParmFactory.h:540
size_t size() const
Return the number of parameters in this list.
Definition: ParmFactory.h:85
OPENVDB_HOUDINI_API const PRM_ChoiceList PrimGroupMenuInput2
void clear()
Remove all parameters from this list.
Definition: ParmFactory.h:88
void markInputUnlocked(exint input)
Definition: ParmFactory.h:573
const SpareDataMap & getOperatorSpareData(const OP_Operator &)
Return the spare data associated with the given operator.
std::shared_ptr< OpPolicy > OpPolicyPtr
Definition: ParmFactory.h:350
An OpPolicy customizes the behavior of an OpFactory. This base class specifies the required interface...
Definition: ParmFactory.h:517
void addOperatorSpareData(OP_Operator &, const SpareDataMap &)
Specify (key, value) pairs of spare data for the given operator.
~ScopedInputLock()
Definition: ParmFactory.h:571
Helper class to simplify operator registration.
Definition: ParmFactory.h:376
Definition: ParmFactory.h:379
virtual ~OpPolicy()
Definition: ParmFactory.h:521
OPENVDB_HOUDINI_API const PRM_ChoiceList PrimGroupMenuInput4
ScopedInputLock(SOP_Node &node, OP_Context &context)
Definition: ParmFactory.h:564
OPENVDB_HOUDINI_API const PRM_ChoiceList PrimGroupMenu