HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
functions.C
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2018
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  */
27 
28 #include <string.h>
29 #include <malloc.h>
30 #include <math.h>
31 #include <UT/UT_DSOVersion.h>
32 #include <EXPR/EXPR.h>
33 #include <EXPR/EX_Vector.h>
34 #include <OP/OP_Director.h>
35 #include <OP/OP_Operator.h>
36 #include <OP/OP_Channels.h>
37 #include <PRM/PRM_RefId.h>
38 #include <CH/CH_Support.h>
39 #include <CMD/CMD_Manager.h>
40 
41 
42 //
43 // Helpers for handling operator path dependencies
44 //
45 
46 // Add name dependency for first argument
47 static void
48 fn_addOpNameDepend1(EV_FUNCTION *func, EV_SYMBOL **argv, void *ref_id)
49 {
51 
52  if( argv[0] == NULL )
53  return; // The argument is an lvalue (non-const)
54 
55  if (func->getUserFlags() & CH_EXPRDATA)
56  type = OP_INTEREST_NAMEDATA;
57  else
58  type = OP_INTEREST_NAME;
59 
60  OP_Node::addExprOpDependency(argv[0]->value.sval, *((PRM_RefId *)ref_id),
61  type);
62 }
63 
64 static void
65 fn_changeOpRef1(EV_FUNCTION *func, EV_SYMBOL **argv, char **new_args,
66  const char *new_fullpath, const char *old_fullpath,
67  const char *old_cwd, const char * /*chan_name*/,
68  const char * /*old_chan_name*/)
69 {
70  if( argv[0] == NULL )
71  return; // The argument is an lvalue (non-const)
72 
73  OP_Node::changeExprOpRef(argv[0]->value.sval, new_args[0], new_fullpath,
74  old_fullpath, old_cwd);
75 }
76 
77 //
78 // This is a function which will find a node from our current node's
79 // location.
80 //
81 static OP_Node *
82 findOp(int thread,
83  const char *object, OP_InterestType interest_type = OP_INTEREST_DATA)
84 {
86  OP_Node *cwd; // Where to search from
87  OP_Node *here; // Where I currently am
88  OP_Node *src;
89 
90  // Find our current evaluation node
91  here = eval_ref.node();
92  if (!here) return 0;
93 
94  // If there's a full path specification, search from the top
95  cwd = (*object == '/') ? OPgetDirector() : here;
96 
97  if (*object == '\0' || !strcmp(object, "."))
98  src = (OP_Node *)cwd;
99  else src = (OP_Node *)cwd->findNode(object);
100 
101  // Check to make sure we found the node.
102  if (!src) return 0;
103 
104  // We need to be told when certain things happen to the node we just found.
105  // For example, if the node gets re-named, we need to be told so that the
106  // expression can fix itself. As well, in many cases, we'll also want to
107  // be notified when the data changes. These types of interests can be
108  // found in OP/OP_DataTypes.h
109  OP_Node::addExtraInput(eval_ref, OP_InterestRef(*src, interest_type));
110 
111  return src;
112 }
113 
114 #ifndef EV_START_FN
115 #define EV_START_FN(name) \
116  static void name(EV_FUNCTION *, EV_SYMBOL *result,\
117  EV_SYMBOL **argv, int thread)
118 #endif // EV_START_FN
119 
120 // Callback function to evaluate the max of two numbers
121 EV_START_FN(fn_max)
122 {
123  if (argv[0]->value.fval > argv[1]->value.fval)
124  result->value.fval = argv[0]->value.fval;
125  else result->value.fval = argv[1]->value.fval;
126 }
127 
128 // Callback function to evaluate the minimum of two numbers
129 EV_START_FN(fn_min)
130 {
131  if (argv[0]->value.fval > argv[1]->value.fval)
132  result->value.fval = argv[1]->value.fval;
133  else result->value.fval = argv[0]->value.fval;
134 }
135 
136 // This callback is a little more tricky, it evaluates the type of the
137 // operator specified. Note that we call it optype_proto() because there's
138 // already a optype() expression function in Houdini proper.
139 EV_START_FN(fn_optype_proto)
140 {
141  OP_Node *node; // Node specified
142  const OP_Operator *opdef; // The operator definition
143 
144  if ((node = findOp(thread, argv[0]->value.sval)))
145  {
146  // Get the operator table definition which stores the type of operator
147  opdef = node->getOperator();
148 
149  // Set the result to be a duplication of the operator table. Make
150  // to allocate memory for a string result.
151  result->value.sval = strdup(opdef->getName());
152  }
153  else result->value.sval = 0; // An empty string
154 }
155 
156 EV_START_FN(fn_vectorsum)
157 {
158  ev_Vector *v0 = (ev_Vector *)argv[0]->value.data;
159  ev_Vector *v1 = (ev_Vector *)argv[1]->value.data;
160  ev_Vector *sum = (ev_Vector *)result->value.data;
161 
162  sum->copy(*v0);
163  sum->add(*v1);
164 }
165 
166 // A couple of defines to make life a lot easier for us
167 #define EVF EV_TYPEFLOAT
168 #define EVS EV_TYPESTRING
169 #define EVV EV_TYPEVECTOR
170 
171 static int floatArgs[] = { EVF, EVF };
172 static int stringArgs[] = { EVS };
173 static int vectorArgs[] = { EVV, EVV };
174 
175 static EV_FUNCTION funcTable[] = {
176  EV_FUNCTION(0, "max", 2, EVF, floatArgs, fn_max),
177  EV_FUNCTION(0, "min", 2, EVF, floatArgs, fn_min),
178  EV_FUNCTION(0, "optype_proto", 1, EVS, stringArgs, fn_optype_proto),
179  EV_FUNCTION(0, "vectorsum", 2, EVV, vectorArgs, fn_vectorsum),
180  EV_FUNCTION(),
181 };
182 
183 void
185 {
186  int i;
187 
188  for (i = 0; funcTable[i].getName(); i++)
189  ev_AddFunction(&funcTable[i]);
190 
191  // optype_proto() needs special hooks in order to handle operator path name
192  // dependencies
193  ev_SetFunctionDependencyCallbacks("optype_proto", fn_addOpNameDepend1,
194  fn_changeOpRef1);
195 }
OP_Node * findNode(const char *path) const
Uses the path (eg. "/obj/geo1") to find a node in our heirarchy.
const char * getName() const
Definition: EXPR.h:249
#define EVF
Definition: functions.C:167
png_uint_32 i
Definition: png.h:2877
EV_TOKENVALUE value
Token data.
Definition: EXPR.h:170
fpreal fval
Definition: EXPR.h:151
void add(const ev_Vector &src)
OP_InterestType
Definition: OP_DataTypes.h:44
static void changeExprOpRef(const char *arg_str, char *&new_arg, const char *new_fullpath, const char *old_fullpath, const char *old_cwd)
void * data
Definition: EXPR.h:153
EXPR_API void ev_AddFunction(EV_FUNCTION *func)
static void addExprOpDependency(const char *arg_str, const PRM_RefId &ref_id, OP_InterestType interest_type)
class representing a symbol operated upon by expressions
Definition: EXPR.h:157
GLfloat v0
Definition: glcorearb.h:815
static EvalChannelTag EvalChannel
GLsizei const GLfloat * value
Definition: glcorearb.h:823
GLenum func
Definition: glcorearb.h:782
const UT_String & getName() const
Definition: OP_Operator.h:202
virtual void addExtraInput(OP_Node *op, OP_InterestType type)
Definition: OP_Node.h:1573
OP_API OP_Director * OPgetDirector()
GLfloat GLfloat v1
Definition: glcorearb.h:816
GLint GLint GLsizei GLint GLenum GLenum type
Definition: glcorearb.h:107
#define EVS
Definition: functions.C:168
unsigned getUserFlags() const
Definition: EXPR.h:248
OP_Operator * getOperator() const
#define CH_EXPRDATA
Definition: CH_Support.h:37
void CMDextendLibrary(CMD_Manager *)
Definition: functions.C:184
#define EVV
Definition: functions.C:169
#define EV_START_FN(name)
Definition: functions.C:115
void copy(const ev_Vector &src)
GLenum src
Definition: glcorearb.h:1792
EXPR_API void ev_SetFunctionDependencyCallbacks(const char *func, EXPRopDependencyCallback depend_cb, EXPRopChangeRefCallback changeref_cb)