HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
VOP_CustomContext.C
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2024
3  * Side Effects Software Inc. All rights reserved.
4  *
5  * Redistribution and use of Houdini Development Kit samples in source and
6  * binary forms, with or without modification, are permitted provided that the
7  * following conditions are met:
8  * 1. Redistributions of source code must retain the above copyright notice,
9  * this list of conditions and the following disclaimer.
10  * 2. The name of Side Effects Software may not be used to endorse or
11  * promote products derived from this software without specific prior
12  * written permission.
13  *
14  * THIS SOFTWARE IS PROVIDED BY SIDE EFFECTS SOFTWARE `AS IS' AND ANY EXPRESS
15  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
17  * NO EVENT SHALL SIDE EFFECTS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
18  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
19  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
20  * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
21  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
22  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
23  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25 
26 #include <UT/UT_DSOVersion.h>
27 #include "VOP_CustomContext.h"
28 
29 #include <VOP/VOP_Operator.h>
30 #include <OP/OP_OperatorTable.h>
31 #include <OP/OP_Input.h>
32 #include <PRM/PRM_Include.h>
33 #include <PRM/PRM_SpareData.h>
34 #include <CH/CH_Manager.h>
35 #include <UT/UT_Assert.h>
36 #include <UT/UT_WorkBuffer.h>
37 #include <SYS/SYS_Types.h>
38 
39 #include <stdint.h>
40 #include <stdlib.h>
41 #include <string.h>
42 
43 
44 using namespace HDK_Sample;
45 
46 
47 //////////////////////////////////////////////////////////////////////////////
48 //
49 // SOP_CustomVop Node Registration
50 //
51 
52 void
54 {
55  OP_Operator * op;
56 
57  op = new OP_Operator(
58  "hdk_customvop", // internal name
59  "Custom VOP", // UI label
60  SOP_CustomVop::myConstructor, // class factory
61  SOP_CustomVop::myTemplateList, // parm definitions
63  0, // min # of inputs
64  0 // max # of inputs
65  );
66  table->addOperator(op);
67 }
68 
70 
71 ///////////////////////////////////////////////////////////////////////////////
72 //
73 // SOP_CustomVop Implementation
74 //
75 
76 OP_Node *
78  OP_Network *net, const char *name, OP_Operator *entry)
79 {
80  return new SOP_CustomVop(net, name, entry);
81 }
82 
85 {
86  PRM_Template() // List terminator
87 };
88 
90  OP_Network *net, const char *name, OP_Operator *entry)
91  : SOP_Node(net, name, entry)
92 {
93  createAndGetOperatorTable();
94 }
95 
97 {
98 }
99 
100 const char *
102 {
103  return VOP_OPTYPE_NAME;
104 }
105 
108 {
109  return VOP_OPTYPE_ID;
110 }
111 
112 // Create dummy VOP_Operator subclass so that we can tag it as operators
113 // created by us by type. We also take this chance to conveniently simplify
114 // it's construction as well. Notice that besides the large range of inputs
115 // that we give it, we also give it an "invalid" vopnet mask so that it won't
116 // appear in any of the other VOP context networks.
118 {
119 public:
120  sop_CustomVopOperator(const char *name, const char *label)
121  : VOP_Operator(
122  name, // internal name
123  label, // UI label
124  VOP_CustomVop::myConstructor, // How to create one
125  VOP_CustomVop::myTemplateList, // parm definitions
126  SOP_CustomVop::theChildTableName,
127  0, // Min # of inputs
128  VOP_VARIABLE_INOUT_MAX, // Max # of inputs
129  "invalid", // vopnet mask
130  NULL, // Local variables
131  OP_FLAG_GENERATOR, // Special flags
132  VOP_VARIABLE_INOUT_MAX) // # of outputs
133  {
134  }
135 };
136 
138 SOP_CustomVop::createAndGetOperatorTable()
139 {
140  // We chain our custom VOP operators onto the default VOP operator table.
142 
143  // Procedurally create some simple operator types for illustrative purposes.
144  table.addOperator(new sop_CustomVopOperator("hdk_inout11_", "In-Out 1-1"));
145  table.addOperator(new sop_CustomVopOperator("hdk_inout21_", "In-Out 2-1"));
146  table.addOperator(new sop_CustomVopOperator("hdk_inout12_", "In-Out 1-2"));
147  table.addOperator(new sop_CustomVopOperator("hdk_inout22_", "In-Out 2-2"));
148 
149  // Notify observers of the operator table that it has been changed.
151 
152  return &table;
153 }
154 
155 OP_ERROR
157 {
158  // Do evaluation of the custom VOP network here.
159  return error();
160 }
161 
162 ///////////////////////////////////////////////////////////////////////////////
163 //
164 // VOP_CustomVop
165 //
166 
167 OP_Node *
169  OP_Network *net, const char *name, OP_Operator *entry)
170 {
171  return new VOP_CustomVop(net, name, entry);
172 }
173 
174 static PRM_Name vopPlugInputs("inputs", "Inputs");
175 static PRM_Name vopPlugInpName("inpplug#", "Input Name #");
176 static PRM_Default vopPlugInpDefault(0, "input1");
177 static PRM_Name vopPlugOutputs("outputs", "Outputs");
178 static PRM_Name vopPlugOutName("outplug#", "Output Name #");
179 static PRM_Default vopPlugOutDefault(0, "output1");
180 
181 static PRM_Template
182 vopPlugInpTemplate[] =
183 {
184  PRM_Template(PRM_ALPHASTRING, 1, &vopPlugInpName, &vopPlugInpDefault),
185  PRM_Template() // List terminator
186 };
187 static PRM_Template
188 vopPlugOutTemplate[] =
189 {
190  PRM_Template(PRM_ALPHASTRING, 1, &vopPlugOutName, &vopPlugOutDefault),
191  PRM_Template() // List terminator
192 };
193 
196 {
197  PRM_Template(PRM_MULTITYPE_LIST, vopPlugInpTemplate, 0, &vopPlugInputs,
199 
200  PRM_Template(PRM_MULTITYPE_LIST, vopPlugOutTemplate, 0, &vopPlugOutputs,
202 
203  PRM_Template() // List terminator
204 };
205 
207  OP_Network *parent, const char *name, OP_Operator *entry)
208  : VOP_Node(parent, name, entry)
209 {
210  // Add our event handler.
211  addOpInterest(this, &VOP_CustomVop::nodeEventHandler);
212 }
213 
215 {
216  // Failing to remove our event handler can cause Houdini to crash so make
217  // sure we do it.
218  removeOpInterest(this, &VOP_CustomVop::nodeEventHandler);
219 }
220 
221 // This function is called to run the creation script (if there is one).
222 // The return value is false if the node was deleted while running the
223 // script. In this case obviously the node pointer becomes invalid and
224 // should not be used any more. It returns true if the node still exists.
225 //
226 // We override this in order to perform initial creation we are created
227 // created for the first time in a .hip file. This function is NOT called
228 // when being loaded from .hip files.
229 bool
231 {
233  return false;
234 
235  fpreal t = CHgetEvalTime();
236  UT_WorkBuffer plugname;
237 
238  // For simplicity, we just initialize our number of inputs/outputs based
239  // upon our node type name.
241  int n = type_name.c_str()[type_name.length() - 3] - '0';
242  setInt(vopPlugInputs.getToken(), 0, t, n);
243  for (int i = 0; i < n; i++)
244  {
245  plugname.sprintf("input%d", i + 1);
247  vopPlugInpName.getToken(), &i, 0, t);
248  }
249 
250  n = type_name.c_str()[type_name.length() - 2] - '0';
251  setInt(vopPlugOutputs.getToken(), 0, t, n);
252  for (int i = 0; i < n; i++)
253  {
254  plugname.sprintf("output%d", i + 1);
256  vopPlugOutName.getToken(), &i, 0, t);
257  }
258 
259  return true;
260 }
261 
262 const char *
263 VOP_CustomVop::inputLabel(unsigned idx) const
264 {
265  static UT_WorkBuffer theLabel;
266  fpreal t = CHgetEvalTime();
267  int i = idx;
269 
270  // Evaluate our label from the corresponding parameter.
271  evalStringInst(vopPlugInpName, &i, label, 0, t);
272  if (label.isstring())
273  theLabel.strcpy(label);
274  else
275  theLabel.strcpy("<unnamed>");
276 
277  return theLabel.buffer();
278 }
279 
280 const char *
281 VOP_CustomVop::outputLabel(unsigned idx) const
282 {
283  static UT_WorkBuffer theLabel;
284  fpreal t = CHgetEvalTime();
285  int i = idx;
287 
288  // Evaluate our label from the corresponding parameter.
289  evalStringInst(vopPlugOutName, &i, label, 0, t);
290  if (label.isstring())
291  theLabel.strcpy(label);
292  else
293  theLabel.strcpy("<unnamed>");
294 
295  return theLabel.buffer();
296 }
297 
298 unsigned
300 {
301  /// For simplicity, we just use the user specified parameter.
302  return evalInt("inputs", 0, CHgetEvalTime());
303 }
304 
305 unsigned
307 {
308  /// For simplicity, we just use the user specified parameter.
309  return evalInt("outputs", 0, CHgetEvalTime());
310 }
311 
312 void
314 {
315  // For simplicity, we just do the same thing as our input/output labels.
316  name.harden(inputLabel(idx));
317 }
318 
319 int
321 {
322  // There are more efficient ways to do this, but just do a dumb reverse
323  // lookup here.
324  for (int i = 0; i < getNumVisibleInputs(); i++)
325  {
326  if (name == inputLabel(i))
327  return i;
328  }
329  return -1;
330 }
331 
332 void
334 {
335  // For simplicity, just assume everything is a float
336  type_info.setType(VOP_TYPE_FLOAT);
337 }
338 
339 void
341  VOP_VopTypeInfoArray &type_infos)
342 {
343  // For simplicity, just assume everything is a float
344  type_infos.append( VOP_TypeInfo( VOP_TYPE_FLOAT ));
345 }
346 
347 void
349 {
350  // For simplicity, we just do the same thing as our input/output labels.
351  name.harden(outputLabel(idx));
352 }
353 
354 void
356 {
357  // For simplicity, just assume everything is a float
358  type_info.setType(VOP_TYPE_FLOAT);
359 }
360 
361 void
362 VOP_CustomVop::nodeEventHandler(
363  OP_Node *caller, void *callee, OP_EventType type, void *data)
364 {
365  switch (type)
366  {
367  case OP_PARM_CHANGED:
368  static_cast<VOP_CustomVop*>(callee)->handleParmChanged((int)(intptr_t)data);
369  break;
370  default:
371  break;
372  }
373 }
374 
375 void
376 VOP_CustomVop::handleParmChanged(int parm_index)
377 {
378  // On any parameter change for us, trigger a notification that the node's
379  // UI needs to update so that the Network Pane will redraw with the changed
380  // inputs/outputs.
382 }
383 
384 
385 ///////////////////////////////////////////////////////////////////////////////
386 //
387 // SOP_CustomVopOperatorFilter Implementation
388 //
389 
390 bool
392 {
393  return (dynamic_cast<sop_CustomVopOperator *>(op) != NULL);
394 }
395 
396 
SYS_FORCE_INLINE OP_Operator * getOperator() const
static const char * theChildTableName
sop_CustomVopOperator(const char *name, const char *label)
GLuint GLsizei const GLchar * label
Definition: glcorearb.h:2545
virtual OP_ERROR error()
The input/output connections have changed.
Definition: OP_DataTypes.h:100
void triggerUIChanged(OP_UIChangeType type=OP_UICHANGE_ANY)
OP_OperatorTable * getOperatorTable() const
Definition: OP_Network.h:651
#define VOP_VARIABLE_INOUT_MAX
Definition: VOP_Node.h:59
SYS_FORCE_INLINE const char * buffer() const
#define OP_FLAG_GENERATOR
Definition: OP_Operator.h:82
UT_ErrorSeverity
Definition: UT_Error.h:25
SYS_FORCE_INLINE void strcpy(const char *src)
void setType(VOP_Type type, VOP_Type raw_type=VOP_TYPE_UNDEF, const char *type_name=NULL)
void getInputTypeInfoSubclass(VOP_TypeInfo &type_info, int idx) override
Fills in the info about the vop type connected to the idx-th input.
bool addOperator(OP_Operator *op, std::ostream *err=nullptr)
bool allowOperatorAsChild(OP_Operator *op) override
C++ VOP node to select one of its inputs and feed it into the output.
static OP_Node * myConstructor(OP_Network *net, const char *name, OP_Operator *entry)
void getAllowedInputTypeInfosSubclass(unsigned idx, VOP_VopTypeInfoArray &type_infos) override
const UT_StringHolder & getName() const
Definition: OP_Operator.h:220
void addOpInterest(void *data, OP_EventMethod m)
Definition: OP_Node.h:1418
void notifyUpdateTableSinksOfUpdate()
GLdouble n
Definition: glcorearb.h:2008
static OP_Node * myConstructor(OP_Network *net, const char *name, OP_Operator *entry)
bool runCreateScript() override
exint length() const
const char * inputLabel(unsigned idx) const override
Provides the labels to appear on input and output buttons.
static PRM_Template myTemplateList[]
Our parameter templates.
constexpr std::enable_if< I< type_count_base< T >::value, int >::type tuple_type_size(){return subtype_count< typename std::tuple_element< I, T >::type >::value+tuple_type_size< T, I+1 >);}template< typename T > struct type_count< T, typename std::enable_if< is_tuple_like< T >::value >::type >{static constexpr int value{tuple_type_size< T, 0 >)};};template< typename T > struct subtype_count{static constexpr int value{is_mutable_container< T >::value?expected_max_vector_size:type_count< T >::value};};template< typename T, typename Enable=void > struct type_count_min{static const int value{0};};template< typename T >struct type_count_min< T, typename std::enable_if<!is_mutable_container< T >::value &&!is_tuple_like< T >::value &&!is_wrapper< T >::value &&!is_complex< T >::value &&!std::is_void< T >::value >::type >{static constexpr int value{type_count< T >::value};};template< typename T > struct type_count_min< T, typename std::enable_if< is_complex< T >::value >::type >{static constexpr int value{1};};template< typename T >struct type_count_min< T, typename std::enable_if< is_wrapper< T >::value &&!is_complex< T >::value &&!is_tuple_like< T >::value >::type >{static constexpr int value{subtype_count_min< typename T::value_type >::value};};template< typename T, std::size_t I >constexpr typename std::enable_if< I==type_count_base< T >::value, int >::type tuple_type_size_min(){return 0;}template< typename T, std::size_t I > constexpr typename std::enable_if< I< type_count_base< T >::value, int >::type tuple_type_size_min(){return subtype_count_min< typename std::tuple_element< I, T >::type >::value+tuple_type_size_min< T, I+1 >);}template< typename T > struct type_count_min< T, typename std::enable_if< is_tuple_like< T >::value >::type >{static constexpr int value{tuple_type_size_min< T, 0 >)};};template< typename T > struct subtype_count_min{static constexpr int value{is_mutable_container< T >::value?((type_count< T >::value< expected_max_vector_size)?type_count< T >::value:0):type_count_min< T >::value};};template< typename T, typename Enable=void > struct expected_count{static const int value{0};};template< typename T >struct expected_count< T, typename std::enable_if<!is_mutable_container< T >::value &&!is_wrapper< T >::value &&!std::is_void< T >::value >::type >{static constexpr int value{1};};template< typename T > struct expected_count< T, typename std::enable_if< is_mutable_container< T >::value >::type >{static constexpr int value{expected_max_vector_size};};template< typename T >struct expected_count< T, typename std::enable_if<!is_mutable_container< T >::value &&is_wrapper< T >::value >::type >{static constexpr int value{expected_count< typename T::value_type >::value};};enum class object_category:int{char_value=1, integral_value=2, unsigned_integral=4, enumeration=6, boolean_value=8, floating_point=10, number_constructible=12, double_constructible=14, integer_constructible=16, string_assignable=23, string_constructible=24, other=45, wrapper_value=50, complex_number=60, tuple_value=70, container_value=80,};template< typename T, typename Enable=void > struct classify_object{static constexpr object_category value{object_category::other};};template< typename T >struct classify_object< T, typename std::enable_if< std::is_integral< T >::value &&!std::is_same< T, char >::value &&std::is_signed< T >::value &&!is_bool< T >::value &&!std::is_enum< T >::value >::type >{static constexpr object_category value{object_category::integral_value};};template< typename T >struct classify_object< T, typename std::enable_if< std::is_integral< T >::value &&std::is_unsigned< T >::value &&!std::is_same< T, char >::value &&!is_bool< T >::value >::type >{static constexpr object_category value{object_category::unsigned_integral};};template< typename T >struct classify_object< T, typename std::enable_if< std::is_same< T, char >::value &&!std::is_enum< T >::value >::type >{static constexpr object_category value{object_category::char_value};};template< typename T > struct classify_object< T, typename std::enable_if< is_bool< T >::value >::type >{static constexpr object_category value{object_category::boolean_value};};template< typename T > struct classify_object< T, typename std::enable_if< std::is_floating_point< T >::value >::type >{static constexpr object_category value{object_category::floating_point};};template< typename T >struct classify_object< T, typename std::enable_if<!std::is_floating_point< T >::value &&!std::is_integral< T >::value &&std::is_assignable< T &, std::string >::value >::type >{static constexpr object_category value{object_category::string_assignable};};template< typename T >struct classify_object< T, typename std::enable_if<!std::is_floating_point< T >::value &&!std::is_integral< T >::value &&!std::is_assignable< T &, std::string >::value &&(type_count< T >::value==1)&&std::is_constructible< T, std::string >::value >::type >{static constexpr object_category value{object_category::string_constructible};};template< typename T > struct classify_object< T, typename std::enable_if< std::is_enum< T >::value >::type >{static constexpr object_category value{object_category::enumeration};};template< typename T > struct classify_object< T, typename std::enable_if< is_complex< T >::value >::type >{static constexpr object_category value{object_category::complex_number};};template< typename T > struct uncommon_type{using type=typename std::conditional<!std::is_floating_point< T >::value &&!std::is_integral< T >::value &&!std::is_assignable< T &, std::string >::value &&!std::is_constructible< T, std::string >::value &&!is_complex< T >::value &&!is_mutable_container< T >::value &&!std::is_enum< T >::value, std::true_type, std::false_type >::type;static constexpr bool value=type::value;};template< typename T >struct classify_object< T, typename std::enable_if<(!is_mutable_container< T >::value &&is_wrapper< T >::value &&!is_tuple_like< T >::value &&uncommon_type< T >::value)>::type >{static constexpr object_category value{object_category::wrapper_value};};template< typename T >struct classify_object< T, typename std::enable_if< uncommon_type< T >::value &&type_count< T >::value==1 &&!is_wrapper< T >::value &&is_direct_constructible< T, double >::value &&is_direct_constructible< T, int >::value >::type >{static constexpr object_category value{object_category::number_constructible};};template< typename T >struct classify_object< T, typename std::enable_if< uncommon_type< T >::value &&type_count< T >::value==1 &&!is_wrapper< T >::value &&!is_direct_constructible< T, double >::value &&is_direct_constructible< T, int >::value >::type >{static constexpr object_category value{object_category::integer_constructible};};template< typename T >struct classify_object< T, typename std::enable_if< uncommon_type< T >::value &&type_count< T >::value==1 &&!is_wrapper< T >::value &&is_direct_constructible< T, double >::value &&!is_direct_constructible< T, int >::value >::type >{static constexpr object_category value{object_category::double_constructible};};template< typename T >struct classify_object< T, typename std::enable_if< is_tuple_like< T >::value &&((type_count< T >::value >=2 &&!is_wrapper< T >::value)||(uncommon_type< T >::value &&!is_direct_constructible< T, double >::value &&!is_direct_constructible< T, int >::value)||(uncommon_type< T >::value &&type_count< T >::value >=2))>::type >{static constexpr object_category value{object_category::tuple_value};};template< typename T > struct classify_object< T, typename std::enable_if< is_mutable_container< T >::value >::type >{static constexpr object_category value{object_category::container_value};};template< typename T, enable_if_t< classify_object< T >::value==object_category::char_value, detail::enabler >=detail::dummy >constexpr const char *type_name(){return"CHAR";}template< typename T, enable_if_t< classify_object< T >::value==object_category::integral_value||classify_object< T >::value==object_category::integer_constructible, detail::enabler >=detail::dummy >constexpr const char *type_name(){return"INT";}template< typename T, enable_if_t< classify_object< T >::value==object_category::unsigned_integral, detail::enabler >=detail::dummy >constexpr const char *type_name(){return"UINT";}template< typename T, enable_if_t< classify_object< T >::value==object_category::floating_point||classify_object< T >::value==object_category::number_constructible||classify_object< T >::value==object_category::double_constructible, detail::enabler >=detail::dummy >constexpr const char *type_name(){return"FLOAT";}template< typename T, enable_if_t< classify_object< T >::value==object_category::enumeration, detail::enabler >=detail::dummy >constexpr const char *type_name(){return"ENUM";}template< typename T, enable_if_t< classify_object< T >::value==object_category::boolean_value, detail::enabler >=detail::dummy >constexpr const char *type_name(){return"BOOLEAN";}template< typename T, enable_if_t< classify_object< T >::value==object_category::complex_number, detail::enabler >=detail::dummy >constexpr const char *type_name(){return"COMPLEX";}template< typename T, enable_if_t< classify_object< T >::value >=object_category::string_assignable &&classify_object< T >::value<=object_category::other, detail::enabler >=detail::dummy >constexpr const char *type_name(){return"TEXT";}template< typename T, enable_if_t< classify_object< T >::value==object_category::tuple_value &&type_count_base< T >::value >=2, detail::enabler >=detail::dummy >std::string type_name();template< typename T, enable_if_t< classify_object< T >::value==object_category::container_value||classify_object< T >::value==object_category::wrapper_value, detail::enabler >=detail::dummy >std::string type_name();template< typename T, enable_if_t< classify_object< T >::value==object_category::tuple_value &&type_count_base< T >::value==1, detail::enabler >=detail::dummy >inline std::string type_name(){return type_name< typename std::decay< typename std::tuple_element< 0, T >::type >::type >);}template< typename T, std::size_t I >inline typename std::enable_if< I==type_count_base< T >::value, std::string >::type tuple_name(){return std::string{};}template< typename T, std::size_t I >inline typename std::enable_if<(I< type_count_base< T >::value), std::string >::type tuple_name(){auto str=std::string{type_name< typename std::decay< typename std::tuple_element< I, T >::type >::type >)}+ ','+tuple_name< T, I+1 >);if(str.back()== ',') str.pop_back();return str;}template< typename T, enable_if_t< classify_object< T >::value==object_category::tuple_value &&type_count_base< T >::value >=2, detail::enabler > > std::string type_name()
Recursively generate the tuple type name.
Definition: CLI11.h:1729
VOP_CustomVop(OP_Network *net, const char *name, OP_Operator *entry)
void harden()
Take shallow copy and make it deep.
Definition: UT_String.h:215
const char * getChildType() const override
We override these to specify that our child network type is VOPs.
OP_OpTypeId getChildTypeID() const override
We override these to specify that our child network type is VOPs.
SYS_FORCE_INLINE const char * c_str() const
OP_OpTypeId
Definition: OP_OpTypeId.h:18
fpreal CHgetEvalTime()
Definition: CH_Manager.h:2129
GLuint const GLchar * name
Definition: glcorearb.h:786
const char * outputLabel(unsigned idx) const override
Provides the labels to appear on input and output buttons.
static PRM_SpareData multiStartOffsetZero
unsigned getNumVisibleInputs() const override
Controls the number of input/output buttons visible on the node tile.
GLenum GLenum GLsizei void * table
Definition: glad.h:5129
exint append()
Definition: UT_Array.h:142
GLdouble t
Definition: glad.h:2397
PRM_API const PRM_Type PRM_ALPHASTRING
int sprintf(const char *fmt,...) SYS_PRINTF_CHECK_ATTRIBUTE(2
void newSopOperator(OP_OperatorTable *table)
void evalStringInst(const UT_StringRef &name, const int *inst, UT_String &val, int vi, fpreal t, int nestlevel=1) const
#define VOP_TABLE_NAME
Definition: OP_Node.h:251
void getOutputTypeInfoSubclass(VOP_TypeInfo &type_info, int idx) override
Fills out the info about data type of each output connector.
fpreal64 fpreal
Definition: SYS_Types.h:277
void setInt(int parmi, int vectori, fpreal t, exint value)
#define VOP_OPTYPE_NAME
Definition: OP_Node.h:299
static PRM_Template myTemplateList[]
Our parameter templates.
SOP_CustomVop(OP_Network *net, const char *name, OP_Operator *entry)
OP_EventType
Definition: OP_Value.h:22
void setStringInst(const UT_StringRef &value, CH_StringMeaning meaning, const char *parmname, const int *inst, int vectori, fpreal t, int nestlevel=1)
bool isstring() const
Definition: UT_String.h:691
C++ SOP node to provide the custom VOP context.
exint evalInt(int pi, int vi, fpreal t) const
void getInputNameSubclass(UT_String &name, int idx) const override
int getInputFromNameSubclass(const UT_String &name) const override
Reverse mapping of internal input names to an input index.
PRM_API PRM_Default PRMzeroDefaults[]
type
Definition: core.h:1059
void getOutputNameSubclass(UT_String &out, int idx) const override
void removeOpInterest(void *data, OP_EventMethod m)
Remove notification callback added via addOpInterest()
Definition: OP_Node.h:1422
Definition: format.h:895
unsigned getNumVisibleOutputs() const override
OP_ERROR cookMySop(OP_Context &context) override
Override this to do VOP network evaluation.
const char * getToken() const
Definition: PRM_Name.h:79