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  /// This method will return true if the code referenced by the context has
165  /// been deleted (see @clearAllFunctions()). If you've cached a
166  /// CVEX_Context, then this can be used to see if it's still valid.
167  bool isValid() const;
168 
169  /// Add possible input parameters to the function. These are parameters
170  /// whose values are overridden by values you pass in. If the user's VEX
171  /// function has these parameters the C++ code should assign the values
172  /// after calling load(), but before calling run().
173  ///
174  /// Calling this version of addInput() allows you to defer computing the
175  /// value of the variable until you know whether it will actually be used
176  /// by the VEX function.
177  bool addInput(const UT_StringHolder &name, CVEX_Type type, bool varying);
178 
179  /// If you know the value beforehand, you can add the symbol and it's
180  /// value at the same time.
181  /// Note: The data is referenced, not copied, so keep it live until after
182  /// run() has been called.
183  bool addInput(const UT_StringHolder &name, CVEX_Type type,
184  void *data, int array_size);
185 
186  /// Adds a constant input. You should still maintain the referenc,e
187  /// but the data may be constant folded into the assemble, so the
188  /// values *must* be set ahead of time and possibly will not update
189  /// if you change the original.
190  bool addConstantInput(const UT_StringHolder &name, CVEX_Type type,
191  void *data, int array_size);
192  bool addConstantInput(const UT_StringHolder &name, CVEX_StringArray &strings);
193 
194  /// Add an "string <name>" input. An array length of 1 makes the variable
195  /// uniform.
196  /// Note: The strings are referenced, not copied, so keep it live until
197  /// after run() has been called.
198  bool addInput(const UT_StringHolder &name, CVEX_StringArray &strings);
199 
200  /// Add a required output. If no required output is specified, all
201  /// exports/outputs are computed.
202  /// Note: Due to the varying/uniform state of an output depending
203  /// significantly on the inputs' varying/uniform state -- and operations
204  /// performed -- then, unlike addInput, no storage can be allocated until
205  /// after load.
206  /// Note: If no storage is allocated, the output is still computed but
207  /// the result is thrown away.
208  bool addRequiredOutput(const UT_StringHolder &name, CVEX_Type type);
209 
210  /// Checks if the VEX function by the given name already exists.
211  bool hasFunction(const UT_StringRef &name) const;
212 
213  /// Load the definition of the VEX function.
214  /// Usually VEX functions are loaded from compiled VEX code stored
215  /// in files on the search path. But, callers can use this method to
216  /// define a VEX function from the stream.
217  /// The module name can be optionally overriden with a name argument (if
218  /// it's NULL, the name in the stream is used implicitly).
219  /// The final name of the module is returned in actual_name (if not NULL).
220  /// If override_old is true, if the old function by that name is found,
221  /// then it will be overriden and updated with the new one.
222  bool preloadFile(UT_IStream &is, const char *name,
223  UT_String *actual_name, bool override_old);
224 
225  /// Loads the given file. Instead of registering the loaded
226  /// function in the global function table, returns it as a CVEX_Function
227  CVEX_Function preloadFunction(UT_IStream &is);
228 
229  /// Loads the functin form the global function table.
230  CVEX_Function preloadGlobalFunction(const char *funcname);
231 
232  /// Load the VEX function.
233  /// Inputs must be specified @b before this function is called. After
234  /// loading, the input list will have flags set telling you whether the
235  /// input parameter is used. At this point, you should set the data for
236  /// all used inputs.
237  ///
238  /// The list of outputs will also be defined, meaning that you can figure
239  /// out what's going to be written by the VEX function.
240  bool load(int argc, const char *const argv[]);
241 
242  /// With load function we already have pre-loaded the CVEX_Function
243  /// so the argv[0] is ignored.
244  bool loadFunction(CVEX_Function function, int argc, const char *const argv[]);
245 
246  /// Quick test to see if the function has been loaded.
247  bool isLoaded() const;
248 
249  /// The list of input parameters to the function. It's possible that
250  /// these values may be shared between the input and output lists.
251  CVEX_ValueList &getInputList() { return myInputs; }
252  const CVEX_ValueList &getInputList() const { return myInputs; }
253 
254  /// Find an input by name/type.
255  const CVEX_Value *findInput(const UT_StringRef &name, CVEX_Type type) const
256  { return myInputs.getValue(name, type); }
258  { return myInputs.getValue(name, type); }
259 
260  /// Find an input by name.
261  const CVEX_Value *findInput(const UT_StringRef &name) const
262  { return myInputs.getValue(name, CVEX_TYPE_INVALID); }
264  { return myInputs.getValue(name, CVEX_TYPE_INVALID); }
265 
266  /// The list of output parameters from the function. After the function
267  /// has been run, the output parameters will have their values written to
268  /// by VEX.
269  ///
270  /// If the output has not had CVEX_Value::setData() called, then the data
271  /// will have been written to internal storage and can be retrieved calling
272  /// CVEX_Value::getData().
273  const CVEX_ValueList &getOutputList() const { return myOutputs; }
274  CVEX_ValueList &getOutputList() { return myOutputs; }
275 
276  /// Find an output by name/type.
277  const CVEX_Value *findOutput(const UT_StringRef &name, CVEX_Type type) const
278  { return myOutputs.getValue(name, type); }
280  { return myOutputs.getValue(name, type); }
281 
282  /// Find and output by name.
283  const CVEX_Value *findOutput(const UT_StringRef &name) const
284  { return myOutputs.getValue(name, CVEX_TYPE_INVALID); }
286  { return myOutputs.getValue(name, CVEX_TYPE_INVALID); }
287 
288  /// Initializes the values array with the defaults of the given parameter.
289  /// Leaves values empty if it can't find the parameter.
290  void getParameterDefaults(const UT_StringRef &name,
291  CVEX_Type ctype,
292  UT_DoubleArray &values) const;
293 
294  /// Run the VEX function given a list of input variables and a list of
295  /// output parameters. Each input/output parameter under your control
296  /// should have an array size of either 1 or at least the array_size given
297  /// to the run() method. It's possible to run on fewer array elements
298  /// than have been allocated, but an error will be returned if there are
299  /// input parameters which don't have enough allocation.
300  ///
301  /// Pass in true for interruptable when running from within Houdini.
302  ///
303  /// The run() function may be called multiple times, provided that the
304  /// input parameters don't change. So, if you need to evaluate the data
305  /// in chunks, you can do this by re-initializing the input parameter data
306  /// between calls to run(). However, you should not change the
307  /// uniform/varying state of any input parameters without doing a re-load
308  /// of the VEX function.
309  /// @param array_size The size of varying arrays. All varying arrays must
310  /// be this size.
311  /// @param interruptable If true, VEX will check the state of the
312  /// UT_Interrupt. This should be enabled when called from within
313  /// Houdini. If interruptable is false, then the user will @b not be
314  /// able to break out of endless loops in VEX. It's better to leave it
315  /// true if you are unsure.
316  bool run(int array_size, bool interruptable,
317  CVEX_RunData *rundata = nullptr);
318 
319  /// If load() or run() return false, this will return the error that
320  /// triggered the CVEX failure. Note that this is distinct from errors
321  // and warnings occurring when running VEX.
322  const char *getLastError() const { return myError; }
323 
324  /// If load() or run() failed or reported warnings, these methods will
325  /// return the errors reported by VEX.
326  /// {
327  const UT_String &getVexErrors() const;
328  const UT_String &getVexWarnings() const;
329  /// }
330 
331  /// Clear the errors reported by getVexErrors() / getVexWarnings().
332  void clearVexErrors();
333 
334 private:
335  struct cvex_BoundValue
336  {
337  cvex_BoundValue()
338  : myValue(nullptr)
339  , myBindPtr(nullptr)
340  , myStoragePtr(nullptr)
341  {}
342  CVEX_Value *myValue;
343  void *myBindPtr;
344  void *myStoragePtr;
345  };
346 
347  bool validateValue(const CVEX_Value &value,
348  VEX_Instance<VEX_32> &state, int nproc);
349  void copyBoundData(cvex_BoundValue &bound,
350  VEX_Instance<VEX_32> &state,
351  int start, int nproc);
352  bool bindValues(UT_Array<cvex_BoundValue> &bound_vals,
353  VEX_Instance<VEX_32> &state, int nproc);
354  void extractStrings(CVEX_Value &value,
355  VEX_Instance<VEX_32> &state,
356  int start, int nproc);
357  void extractArrays(CVEX_Value &value,
358  VEX_Instance<VEX_32> &state,
359  int start, int nproc);
360  void extractUniform(CVEX_Value &value,
361  VEX_Instance<VEX_32> &state);
362 
363  bool loadPrivate(const VEX_AssemblePtr &as,
364  int argc, const char *const argv[]);
365 
366  CVEX_ValueList myInputs;
367  CVEX_ValueList myOutputs;
368  UT_UniquePtr<cvex_RunData> myRunData;
369  UT_String myError;
370 };
371 
372 #endif
const CVEX_ValueList & getOutputList() const
Definition: CVEX_Context.h:273
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:252
CVEX_Value * findInput(const UT_StringRef &name)
Definition: CVEX_Context.h:263
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:257
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:283
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:277
int64 exint
Definition: SYS_Types.h:115
const CVEX_Value * findInput(const UT_StringRef &name) const
Find an input by name.
Definition: CVEX_Context.h:261
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:285
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:322
void setTimeDependent(bool v)
Definition: CVEX_Context.h:127
GLsizei const GLfloat * value
Definition: glcorearb.h:823
double fpreal
Definition: SYS_Types.h:269
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:255
CVEX_ValueList & getInputList()
Definition: CVEX_Context.h:251
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:279
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:274