OpenVDB  11.0.0
SOP_NodeVDB.h
Go to the documentation of this file.
1 // Copyright Contributors to the OpenVDB Project
2 // SPDX-License-Identifier: MPL-2.0
3 //
4 /// @file SOP_NodeVDB.h
5 /// @author FX R&D OpenVDB team
6 /// @brief Base class for OpenVDB plugins
7 
8 #ifndef OPENVDB_HOUDINI_SOP_NODEVDB_HAS_BEEN_INCLUDED
9 #define OPENVDB_HOUDINI_SOP_NODEVDB_HAS_BEEN_INCLUDED
10 
11 #include <houdini_utils/ParmFactory.h>
12 #include <openvdb/openvdb.h>
13 #include <openvdb/Platform.h>
14 #include <SOP/SOP_Node.h>
15 #ifndef SESI_OPENVDB
16 #include <UT/UT_DSOVersion.h>
17 #endif
18 #include "SOP_VDBVerbUtils.h"
19 #include <iosfwd>
20 #include <string>
21 
22 
23 class GU_Detail;
24 
25 namespace openvdb_houdini {
26 
27 /// @brief Use this class to register a new OpenVDB operator (SOP, POP, etc.)
28 /// @details This class ensures that the operator uses the appropriate OpPolicy.
29 /// @sa houdini_utils::OpFactory, houdini_utils::OpPolicy
31 {
32 public:
33  /// Construct an OpFactory that on destruction registers a new OpenVDB operator type.
34  OpenVDBOpFactory(const std::string& english, OP_Constructor, houdini_utils::ParmList&,
35  OP_OperatorTable&, houdini_utils::OpFactory::OpFlavor = SOP);
36 
37  /// @brief Set the name of the equivalent native operator as shipped with Houdini.
38  /// @details This is only needed where the native name policy doesn't provide the correct name.
39  /// Pass an empty string to indicate that there is no equivalent native operator.
40  OpenVDBOpFactory& setNativeName(const std::string& name);
41 
42 private:
43  std::string mNativeName;
44 };
45 
46 
47 ////////////////////////////////////////
48 
49 
50 /// @brief Base class from which to derive OpenVDB-related Houdini SOPs
51 class OPENVDB_HOUDINI_API SOP_NodeVDB: public SOP_Node
52 {
53 public:
54  SOP_NodeVDB(OP_Network*, const char*, OP_Operator*);
55  ~SOP_NodeVDB() override = default;
56 
57  void fillInfoTreeNodeSpecific(UT_InfoTree&, const OP_NodeInfoTreeParms&) override;
58  void getNodeSpecificInfoText(OP_Context&, OP_NodeInfoParms&) override;
59 
60  /// @brief Return this node's registered verb.
61  const SOP_NodeVerb* cookVerb() const override;
62 
63  /// @brief Retrieve a group from a geometry detail by parsing a pattern
64  /// (typically, the value of a Group parameter belonging to this node).
65  /// @throw std::runtime_error if the pattern is nonempty but doesn't match any group.
66  /// @todo This is a wrapper for SOP_Node::parsePrimitiveGroups(), so it needs access
67  /// to a SOP_Node instance. But it probably doesn't need to be a SOP_NodeVDB method.
68  /// @{
69  const GA_PrimitiveGroup* matchGroup(GU_Detail&, const std::string& pattern);
70  const GA_PrimitiveGroup* matchGroup(const GU_Detail&, const std::string& pattern);
71  /// @}
72 
73  /// @name Parameter evaluation
74  /// @{
75 
76  /// @brief Evaluate a vector-valued parameter.
77  openvdb::Vec3f evalVec3f(const char* name, fpreal time) const;
78  /// @brief Evaluate a vector-valued parameter.
79  openvdb::Vec3R evalVec3R(const char* name, fpreal time) const;
80  /// @brief Evaluate a vector-valued parameter.
81  openvdb::Vec3i evalVec3i(const char* name, fpreal time) const;
82  /// @brief Evaluate a vector-valued parameter.
83  openvdb::Vec2R evalVec2R(const char* name, fpreal time) const;
84  /// @brief Evaluate a vector-valued parameter.
85  openvdb::Vec2i evalVec2i(const char* name, fpreal time) const;
86 
87  /// @brief Evaluate a string-valued parameter as an STL string.
88  /// @details This method facilitates string parameter evaluation in expressions.
89  /// For example,
90  /// @code
91  /// matchGroup(*gdp, evalStdString("group", time));
92  /// @endcode
93  std::string evalStdString(const char* name, fpreal time, int index = 0) const;
94 
95  /// @}
96 
97 protected:
98  /// @{
99  /// @brief To facilitate compilable SOPs, cookMySop() is now final.
100  /// Instead, either override SOP_NodeVDB::cookVDBSop() (for a non-compilable SOP)
101  /// or override SOP_VDBCacheOptions::cookVDBSop() (for a compilable SOP).
102  OP_ERROR cookMySop(OP_Context&) override final;
103 
104  virtual OP_ERROR cookVDBSop(OP_Context&) { return UT_ERROR_NONE; }
105  /// @}
106 
107  OP_ERROR cookMyGuide1(OP_Context&) override;
108  //OP_ERROR cookMyGuide2(OP_Context&) override;
109 
110  /// @brief Transfer the value of an obsolete parameter that was renamed
111  /// to the parameter with the new name.
112  /// @details This convenience method is intended to be called from
113  /// @c resolveObsoleteParms(), when that function is implemented.
114  void resolveRenamedParm(PRM_ParmList& obsoleteParms,
115  const char* oldName, const char* newName);
116 
117  /// @name Input stealing
118  /// @{
119 
120  /// @brief Steal the geometry on the specified input if possible, instead of copying the data.
121  ///
122  /// @details In certain cases where a node's input geometry isn't being shared with
123  /// other nodes, it is safe for the node to directly modify the geometry.
124  /// Normally, input geometry is shared with the upstream node's output cache,
125  /// so for stealing to be possible, the "unload" flag must be set on the upstream node
126  /// to inhibit caching. In addition, reference counting of GEO_PrimVDB shared pointers
127  /// ensures we cannot steal data that is in use elsewhere. When stealing is not possible,
128  /// this method falls back to copying the shared pointer, effectively performing
129  /// a duplicateSource().
130  ///
131  /// @param index the index of the input from which to perform this operation
132  /// @param context the current SOP context is used for cook time for network traversal
133  /// @param pgdp pointer to the SOP's gdp
134  /// @param gdh handle to manage input locking
135  /// @param clean (forwarded to duplicateSource())
136  ///
137  /// @note Prior to Houdini 13.0, this method peforms a duplicateSource() and unlocks the
138  /// inputs to the SOP. From Houdini 13.0 on, this method will insert the existing data
139  /// into the detail and update the detail handle in the SOP.
140  ///
141  /// @warning No attempt to call duplicateSource() or inputGeo() should be made after
142  /// calling this method, as there will be no data on the input stream if isSourceStealable()
143  /// returns @c true.
144  /// @deprecated verbification renders this redundant
145  [[deprecated]]
146  OP_ERROR duplicateSourceStealable(const unsigned index,
147  OP_Context& context, GU_Detail **pgdp, GU_DetailHandle& gdh, bool clean = true);
148 
149  /// @brief Steal the geometry on the specified input if possible, instead of copying the data.
150  ///
151  /// @details In certain cases where a node's input geometry isn't being shared with
152  /// other nodes, it is safe for the node to directly modify the geometry.
153  /// Normally, input geometry is shared with the upstream node's output cache,
154  /// so for stealing to be possible, the "unload" flag must be set on the upstream node
155  /// to inhibit caching. In addition, reference counting of GEO_PrimVDB shared pointers
156  /// ensures we cannot steal data that is in use elsewhere. When stealing is not possible,
157  /// this method falls back to copying the shared pointer, effectively performing
158  /// a duplicateSource().
159  ///
160  /// @note Prior to Houdini 13.0, this method peforms a duplicateSource() and unlocks the
161  /// inputs to the SOP. From Houdini 13.0 on, this method will insert the existing data
162  /// into the detail and update the detail handle in the SOP.
163  ///
164  /// @param index the index of the input from which to perform this operation
165  /// @param context the current SOP context is used for cook time for network traversal
166  /// @deprecated verbification renders this redundant
167  [[deprecated]]
168  OP_ERROR duplicateSourceStealable(const unsigned index, OP_Context& context);
169 
170  /// @}
171 
172 private:
173  /// @brief Traverse the upstream network to determine if the source input can be stolen.
174  ///
175  /// An upstream SOP cannot be stolen if it is implicitly caching the data (no "unload" flag)
176  /// or explictly caching the data (using a Cache SOP)
177  ///
178  /// The traversal ignores pass through nodes such as null SOPs and bypassing.
179  ///
180  /// @param index the index of the input from which to perform this operation
181  /// @param context the current SOP context is used for cook time for network traversal
182  /// @deprecated verbification renders this redundant
183  [[deprecated]]
184  bool isSourceStealable(const unsigned index, OP_Context& context) const;
185 }; // class SOP_NodeVDB
186 
187 
188 ////////////////////////////////////////
189 
190 
191 /// @brief Namespace to hold functionality for registering info text callbacks. Whenever
192 /// getNodeSpecificInfoText() is called, the default info text is added to MMB output unless
193 /// a valid callback has been registered for the grid type.
194 ///
195 /// @details Use node_info_text::registerGridSpecificInfoText<> to register a grid type to
196 /// a function pointer which matches the ApplyGridSpecificInfoText signature.
197 ///
198 /// void floatGridText(std::ostream&, const openvdb::GridBase&);
199 ///
200 /// node_info_text::registerGridSpecificInfoText<openvdb::FloatGrid>(&floatGridText);
201 ///
202 namespace node_info_text
203 {
204  // The function pointer signature expected when registering an grid type text
205  // callback. The grid is passed untyped but is guaranteed to match the registered
206  // type.
207  using ApplyGridSpecificInfoText = void (*)(std::ostream&, const openvdb::GridBase&);
208 
209  /// @brief Register an info text callback to a specific grid type.
210  /// @note Does not add the callback if the grid type already has a registered callback.
211  /// @param gridType the grid type as a unique string (see templated
212  /// registerGridSpecificInfoText<>)
213  /// @param callback a pointer to the callback function to execute
214  void registerGridSpecificInfoText(const std::string& gridType,
215  ApplyGridSpecificInfoText callback);
216 
217  /// @brief Register an info text callback to a templated grid type.
218  /// @note Does not add the callback if the grid type already has a registered callback.
219  /// @param callback a pointer to the callback function to execute
220  template<typename GridType>
222  {
223  registerGridSpecificInfoText(GridType::gridType(), callback);
224  }
225 
226 } // namespace node_info_text
227 
228 
229 } // namespace openvdb_houdini
230 
231 #endif // OPENVDB_HOUDINI_SOP_NODEVDB_HAS_BEEN_INCLUDED
OpFlavor
Definition: ParmFactory.h:379
void registerGridSpecificInfoText(ApplyGridSpecificInfoText callback)
Register an info text callback to a templated grid type.
Definition: SOP_NodeVDB.h:221
#define OPENVDB_HOUDINI_API
Definition: Platform.h:282
Definition: Mat.h:165
Parameter template list that is always terminated.
Definition: ParmFactory.h:73
Definition: Vec2.h:23
virtual OP_ERROR cookVDBSop(OP_Context &)
To facilitate compilable SOPs, cookMySop() is now final. Instead, either override SOP_NodeVDB::cookVD...
Definition: SOP_NodeVDB.h:104
Vec2< int32_t > Vec2i
Definition: Vec2.h:530
Base class from which to derive OpenVDB-related Houdini SOPs.
Definition: SOP_NodeVDB.h:51
void(*)(std::ostream &, const openvdb::GridBase &) ApplyGridSpecificInfoText
Definition: SOP_NodeVDB.h:207
Helper class to simplify operator registration.
Definition: ParmFactory.h:376
Definition: AttributeTransferUtil.h:34
Use this class to register a new OpenVDB operator (SOP, POP, etc.)
Definition: SOP_NodeVDB.h:30
Vec3< int32_t > Vec3i
Definition: Vec3.h:661
Abstract base class for typed grids.
Definition: Grid.h:77