HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
CVEX_Context.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: CVEX_Context.h ( CVEX Library, C++)
7  *
8  * COMMENTS: C++ interface to VEX. This class defines a parameter to the
9  * VEX function.
10  */
11 
12 #ifndef __CVEX_Context__
13 #define __CVEX_Context__
14 
15 #include "CVEX_API.h"
16 #include "CVEX_Function.h"
17 #include "CVEX_ValueList.h"
18 #include "CVEX_Transform.h"
19 #include "CVEX_Function.h"
20 #include <VEX/VEX_PodTypes.h>
21 #include <UT/UT_NonCopyable.h>
22 #include <UT/UT_UniquePtr.h>
23 
24 class cvex_RunData;
25 class UT_OpCaller;
26 template <VEX_Precision PREC> class VEX_Instance;
27 class VEX_GeoInputs;
29 class VEX_ChannelCache;
30 class VEX_FileCache;
31 
32 /// @brief Per-run data for CVEX execution
33 ///
34 /// This class is used to set and retrieve data specific to an individual
35 /// execution run using CVEX_Context::run().
37 {
38 public:
39  CVEX_RunData();
40  ~CVEX_RunData();
41 
42  /// Resets the run data for re-use.
43  void clear();
44 
45  /// Set the evaluation time. This is what will be used by op: references
46  /// triggered by VEX commands like volumesample. If not set, the current
47  /// channel time is used instead (if an OP_Director is available).
48  void setTime(fpreal time)
49  {
50  myTimeSpecified = true;
51  myTransform.setTime(time);
52  }
53 
54  /// Sets the operator working directory. This is used by ch()
55  /// style vex functions to determine where the relative path for
56  /// path resolution should be.
57  /// Use OP_Node::getUniqueId() to pass this in.
58  void setCWDNodeId(int id)
59  {
60  myTransform.setCwdId(id);
61  }
62  /// The world id is the node which defines the transform space for the CWD.
63  /// If it's not defined the object containing the CWD will be used (or the
64  /// CWD if it's not part of an object network)
65  void setWorldNodeId(int id)
66  {
67  myTransform.setWorldId(id);
68  }
69 
70  /// Sets the OP callback. This is used to setup dependencies on any
71  /// referenced op: expressions. Can be applied to the context at any time.
72  void setOpCaller(UT_OpCaller *caller)
73  {
74  myTransform.setOpCaller(caller);
75  }
76 
77  /// Access to the OP_Caller
78  UT_OpCaller *getOpCaller() const { return myTransform.opCaller(); }
79 
80  /// Returns true when, after running the CVEX_Context, a ch() function
81  /// reported that it was time dependent.
82  bool isTimeDependent() const { return myTimeDependent; }
83 
84  /// Sets the geo input callback for controlling how opinput: references
85  /// are handled
86  void setGeoInputs(const VEX_GeoInputs *geo)
87  {
88  myGeoInputs = geo;
89  }
90  const VEX_GeoInputs *getGeoInputs() const { return myGeoInputs; }
91 
92  /// Sets the proc id array. Owned by the caller. Must be at least
93  /// the length of your size.
94  void setProcId(exint *procid)
95  {
96  myProcId = procid;
97  }
98  const exint *getProcId() const { return myProcId; }
99 
100  /// Sets the command queue for this context
102  {
103  myGeoCommandQueue = geocmd;
104  }
105  VEX_GeoCommandQueue *getGeoCommandQueue() const { return myGeoCommandQueue; }
106 
107  VEX_ChannelCache *getChannelCache() { return myChannelCache; }
108 
109  VEX_FileCache* getFileCache() { return myFileCache; }
110 
111  /// Every VEX function has a transform context associated with it. This
112  /// transform context is used by VEX functions like ptransform() to provide
113  /// ways to transform to other spaces (like "space:world" or
114  /// "space:object"). This method allows you to modify the transform
115  /// context of this shader.
116  CVEX_Transform &getTransform() { return myTransform; }
117 
118  /// @{
119  /// Accessors
120  bool timeSpecified() const { return myTimeSpecified; }
121  bool timeDependent() const { return myTimeDependent; }
122  int cwdId() const { return myTransform.cwdId(); }
123  int worldId() const { return myTransform.worldId();}
124  fpreal time() const { return myTransform.time(); }
125  /// @}
126  /// Set as time dependent flag
127  void setTimeDependent(bool v) { myTimeDependent = v; }
128 
129 private:
130  CVEX_Transform myTransform;
131  const VEX_GeoInputs *myGeoInputs;
132  VEX_GeoCommandQueue *myGeoCommandQueue;
133  exint *myProcId;
134  bool myTimeSpecified;
135  bool myTimeDependent;
136  VEX_ChannelCache *myChannelCache;
137  VEX_FileCache *myFileCache;
138 };
139 
140 /// @brief Call VEX from C++
141 ///
142 /// The CVEX_Context class provides the main interface to let C++ code call VEX
143 /// to perform computations. This allows users to modify algorithms by
144 /// performing computations in VEX.
145 /// - VEX automatically takes advantage of SSE
146 /// - VEX can perform run-time optimization
148 {
149 public:
150  CVEX_Context();
151  ~CVEX_Context();
152 
153  /// clearing the context will allow you to set up the input and output
154  /// parameters again.
155  /// @note load() must be called again before you can run the VEX code.
156  void clear();
157 
158  /// calling clearAllFunctions() will force all CVEX object code to be
159  /// flushed out of memory and to be reloaded. Be cautioned that this may
160  /// have side-effects, and should only be called at a safe time.
161  /// @note This will also cause *all* functions to be cleared (see clear()).
162  static void clearAllFunctions();
163 
164  /// Add possible input parameters to the function. These are parameters
165  /// whose values are overridden by values you pass in. If the user's VEX
166  /// function has these parameters the C++ code should assign the values
167  /// after calling load(), but before calling run().
168  ///
169  /// Calling this version of addInput() allows you to defer computing the
170  /// value of the variable until you know whether it will actually be used
171  /// by the VEX function.
172  bool addInput(const UT_StringHolder &name, CVEX_Type type, bool varying);
173 
174  /// If you know the value beforehand, you can add the symbol and it's
175  /// value at the same time.
176  /// Note: The data is referenced, not copied, so keep it live until after
177  /// run() has been called.
178  bool addInput(const UT_StringHolder &name, CVEX_Type type,
179  void *data, int array_size);
180 
181  /// Adds a constant input. You should still maintain the referenc,e
182  /// but the data may be constant folded into the assemble, so the
183  /// values *must* be set ahead of time and possibly will not update
184  /// if you change the original.
185  bool addConstantInput(const UT_StringHolder &name, CVEX_Type type,
186  void *data, int array_size);
187  bool addConstantInput(const UT_StringHolder &name, CVEX_StringArray &strings);
188 
189  /// Add an "string <name>" input. An array length of 1 makes the variable
190  /// uniform.
191  /// Note: The strings are referenced, not copied, so keep it live until
192  /// after run() has been called.
193  bool addInput(const UT_StringHolder &name, CVEX_StringArray &strings);
194 
195  /// Add a required output. If no required output is specified, all
196  /// exports/outputs are computed.
197  /// Note: Due to the varying/uniform state of an output depending
198  /// significantly on the inputs' varying/uniform state -- and operations
199  /// performed -- then, unlike addInput, no storage can be allocated until
200  /// after load.
201  /// Note: If no storage is allocated, the output is still computed but
202  /// the result is thrown away.
203  bool addRequiredOutput(const UT_StringHolder &name, CVEX_Type type);
204 
205  /// Checks if the VEX function by the given name already exists.
206  bool hasFunction(const UT_StringRef &name) const;
207 
208  /// Load the definition of the VEX function.
209  /// Usually VEX functions are loaded from compiled VEX code stored
210  /// in files on the search path. But, callers can use this method to
211  /// define a VEX function from the stream.
212  /// The module name can be optionally overriden with a name argument (if
213  /// it's NULL, the name in the stream is used implicitly).
214  /// The final name of the module is returned in actual_name (if not NULL).
215  /// If override_old is true, if the old function by that name is found,
216  /// then it will be overriden and updated with the new one.
217  bool preloadFile(UT_IStream &is, const char *name,
218  UT_String *actual_name, bool override_old);
219 
220  /// Loads the given file. Instead of registering the loaded
221  /// function in the global function table, returns it as a CVEX_Function
222  CVEX_Function preloadFunction(UT_IStream &is);
223 
224  /// Loads the functin form the global function table.
225  CVEX_Function preloadGlobalFunction(const char *funcname);
226 
227  /// Load the VEX function.
228  /// Inputs must be specified @b before this function is called. After
229  /// loading, the input list will have flags set telling you whether the
230  /// input parameter is used. At this point, you should set the data for
231  /// all used inputs.
232  ///
233  /// The list of outputs will also be defined, meaning that you can figure
234  /// out what's going to be written by the VEX function.
235  bool load(int argc, const char *const argv[]);
236 
237  /// With load function we already have pre-loaded the CVEX_Function
238  /// so the argv[0] is ignored.
239  bool loadFunction(CVEX_Function function, int argc, const char *const argv[]);
240 
241  /// Quick test to see if the function has been loaded.
242  bool isLoaded() const;
243 
244  /// The list of input parameters to the function. It's possible that
245  /// these values may be shared between the input and output lists.
246  CVEX_ValueList &getInputList() { return myInputs; }
247  const CVEX_ValueList &getInputList() const { return myInputs; }
248 
249  /// Find an input by name/type.
250  const CVEX_Value *findInput(const UT_StringRef &name, CVEX_Type type) const
251  { return myInputs.getValue(name, type); }
253  { return myInputs.getValue(name, type); }
254 
255  /// Find an input by name.
256  const CVEX_Value *findInput(const UT_StringRef &name) const
257  { return myInputs.getValue(name, CVEX_TYPE_INVALID); }
259  { return myInputs.getValue(name, CVEX_TYPE_INVALID); }
260 
261  /// The list of output parameters from the function. After the function
262  /// has been run, the output parameters will have their values written to
263  /// by VEX.
264  ///
265  /// If the output has not had CVEX_Value::setData() called, then the data
266  /// will have been written to internal storage and can be retrieved calling
267  /// CVEX_Value::getData().
268  const CVEX_ValueList &getOutputList() const { return myOutputs; }
269  CVEX_ValueList &getOutputList() { return myOutputs; }
270 
271  /// Find an output by name/type.
272  const CVEX_Value *findOutput(const UT_StringRef &name, CVEX_Type type) const
273  { return myOutputs.getValue(name, type); }
275  { return myOutputs.getValue(name, type); }
276 
277  /// Find and output by name.
278  const CVEX_Value *findOutput(const UT_StringRef &name) const
279  { return myOutputs.getValue(name, CVEX_TYPE_INVALID); }
281  { return myOutputs.getValue(name, CVEX_TYPE_INVALID); }
282 
283  /// Initializes the values array with the defaults of the given parameter.
284  /// Leaves values empty if it can't find the parameter.
285  void getParameterDefaults(const UT_StringRef &name,
286  CVEX_Type ctype,
287  UT_DoubleArray &values) const;
288 
289  /// Run the VEX function given a list of input variables and a list of
290  /// output parameters. Each input/output parameter under your control
291  /// should have an array size of either 1 or at least the array_size given
292  /// to the run() method. It's possible to run on fewer array elements
293  /// than have been allocated, but an error will be returned if there are
294  /// input parameters which don't have enough allocation.
295  ///
296  /// Pass in true for interruptable when running from within Houdini.
297  ///
298  /// The run() function may be called multiple times, provided that the
299  /// input parameters don't change. So, if you need to evaluate the data
300  /// in chunks, you can do this by re-initializing the input parameter data
301  /// between calls to run(). However, you should not change the
302  /// uniform/varying state of any input parameters without doing a re-load
303  /// of the VEX function.
304  /// @param array_size The size of varying arrays. All varying arrays must
305  /// be this size.
306  /// @param interruptable If true, VEX will check the state of the
307  /// UT_Interrupt. This should be enabled when called from within
308  /// Houdini. If interruptable is false, then the user will @b not be
309  /// able to break out of endless loops in VEX. It's better to leave it
310  /// true if you are unsure.
311  bool run(int array_size, bool interruptable,
312  CVEX_RunData *rundata = nullptr);
313 
314  /// If load() or run() return false, this will return the error that
315  /// triggered the CVEX failure. Note that this is distinct from errors
316  // and warnings occurring when running VEX.
317  const char *getLastError() const { return myError; }
318 
319  /// If load() or run() failed or reported warnings, these methods will
320  /// return the errors reported by VEX.
321  /// {
322  const UT_String &getVexErrors() const;
323  const UT_String &getVexWarnings() const;
324  /// }
325 
326  /// Clear the errors reported by getVexErrors() / getVexWarnings().
327  void clearVexErrors();
328 
329 private:
330  struct cvex_BoundValue
331  {
332  cvex_BoundValue()
333  : myValue(nullptr)
334  , myBindPtr(nullptr)
335  , myStoragePtr(nullptr)
336  {}
337  CVEX_Value *myValue;
338  void *myBindPtr;
339  void *myStoragePtr;
340  };
341 
342  bool validateValue(const CVEX_Value &value,
343  VEX_Instance<VEX_32> &state, int nproc);
344  void copyBoundData(cvex_BoundValue &bound,
345  VEX_Instance<VEX_32> &state,
346  int start, int nproc);
347  bool bindValues(UT_Array<cvex_BoundValue> &bound_vals,
348  VEX_Instance<VEX_32> &state, int nproc);
349  void extractStrings(CVEX_Value &value,
350  VEX_Instance<VEX_32> &state,
351  int start, int nproc);
352  void extractArrays(CVEX_Value &value,
353  VEX_Instance<VEX_32> &state,
354  int start, int nproc);
355  void extractUniform(CVEX_Value &value,
356  VEX_Instance<VEX_32> &state);
357 
358  bool loadPrivate(const VEX_AssemblePtr &as,
359  int argc, const char *const argv[]);
360 
361  CVEX_ValueList myInputs;
362  CVEX_ValueList myOutputs;
363  UT_UniquePtr<cvex_RunData> myRunData;
364  UT_String myError;
365 };
366 
367 #endif
const CVEX_ValueList & getOutputList() const
Definition: CVEX_Context.h:268
bool timeDependent() const
Definition: CVEX_Context.h:121
bool isTimeDependent() const
Definition: CVEX_Context.h:82
void setCWDNodeId(int id)
Definition: CVEX_Context.h:58
int worldId() const
Definition: CVEX_Context.h:123
void setTime(fpreal time)
Definition: CVEX_Context.h:48
const GLdouble * v
Definition: glcorearb.h:836
void setOpCaller(UT_OpCaller *caller)
Definition: CVEX_Context.h:72
GLuint start
Definition: glcorearb.h:474
const CVEX_ValueList & getInputList() const
Definition: CVEX_Context.h:247
CVEX_Value * findInput(const UT_StringRef &name)
Definition: CVEX_Context.h:258
const exint * getProcId() const
Definition: CVEX_Context.h:98
List of input or output values for a CVEX_Context.
CVEX_Transform & getTransform()
Definition: CVEX_Context.h:116
fpreal time() const
Definition: CVEX_Context.h:124
CVEX_Value * findInput(const UT_StringRef &name, CVEX_Type type)
Definition: CVEX_Context.h:252
Call VEX from C++.
Definition: CVEX_Context.h:147
const CVEX_Value * findOutput(const UT_StringRef &name) const
Find and output by name.
Definition: CVEX_Context.h:278
UT_OpCaller * getOpCaller() const
Access to the OP_Caller.
Definition: CVEX_Context.h:78
const CVEX_Value * findOutput(const UT_StringRef &name, CVEX_Type type) const
Find an output by name/type.
Definition: CVEX_Context.h:272
int64 exint
Definition: SYS_Types.h:109
const CVEX_Value * findInput(const UT_StringRef &name) const
Find an input by name.
Definition: CVEX_Context.h:256
GLenum GLsizei GLsizei GLint * values
Definition: glcorearb.h:1601
int cwdId() const
Definition: CVEX_Context.h:122
GLboolean * data
Definition: glcorearb.h:130
void setGeoInputs(const VEX_GeoInputs *geo)
Definition: CVEX_Context.h:86
GLuint const GLchar * name
Definition: glcorearb.h:785
GLsizei const GLchar *const * strings
Definition: glcorearb.h:1932
CVEX_Type
The CVEX_Type enum defines the VEX types available to CVEX.
Definition: CVEX_Value.h:23
bool timeSpecified() const
Definition: CVEX_Context.h:120
A class representing a VEX value.
Definition: CVEX_Value.h:50
Per-run data for CVEX execution.
Definition: CVEX_Context.h:36
CVEX_Value * findOutput(const UT_StringRef &name)
Definition: CVEX_Context.h:280
void setGeoCommandQueue(VEX_GeoCommandQueue *geocmd)
Sets the command queue for this context.
Definition: CVEX_Context.h:101
const char * getLastError() const
Definition: CVEX_Context.h:317
void setTimeDependent(bool v)
Definition: CVEX_Context.h:127
GLsizei const GLfloat * value
Definition: glcorearb.h:823
double fpreal
Definition: SYS_Types.h:263
A class holding a VEX function.
Definition: CVEX_Function.h:26
const CVEX_Value * findInput(const UT_StringRef &name, CVEX_Type type) const
Find an input by name/type.
Definition: CVEX_Context.h:250
CVEX_ValueList & getInputList()
Definition: CVEX_Context.h:246
VEX_ChannelCache * getChannelCache()
Definition: CVEX_Context.h:107
const VEX_GeoInputs * getGeoInputs() const
Definition: CVEX_Context.h:90
#define CVEX_API
Definition: CVEX_API.h:10
VEX_FileCache * getFileCache()
Definition: CVEX_Context.h:109
GLint GLint GLsizei GLint GLenum GLenum type
Definition: glcorearb.h:107
CVEX_Value * findOutput(const UT_StringRef &name, CVEX_Type type)
Definition: CVEX_Context.h:274
VEX_GeoCommandQueue * getGeoCommandQueue() const
Definition: CVEX_Context.h:105
void setProcId(exint *procid)
Definition: CVEX_Context.h:94
void setWorldNodeId(int id)
Definition: CVEX_Context.h:65
CVEX_ValueList & getOutputList()
Definition: CVEX_Context.h:269