1 /*=========================================================================
2 
3   Program:   Visualization Toolkit
4   Module:    vtkFunctionParser.h
5 
6   Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
7   All rights reserved.
8   See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
9 
10      This software is distributed WITHOUT ANY WARRANTY; without even
11      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12      PURPOSE.  See the above copyright notice for more information.
13 
14 =========================================================================*/
15 /**
16  * @class   vtkFunctionParser
17  * @brief   Parse and evaluate a mathematical expression
18  *
19  * vtkFunctionParser is a class that takes in a mathematical expression as
20  * a char string, parses it, and evaluates it at the specified values of
21  * the variables in the input string.
22  *
23  * You can use the "if" operator to create conditional expressions
24  * such as if ( test, trueresult, falseresult). These evaluate the boolean
25  * valued test expression and then evaluate either the trueresult or the
26  * falseresult expression to produce a final (scalar or vector valued) value.
27  * "test" may contain <,>,=,|,&, and () and all three subexpressions can
28  * evaluate arbitrary function operators (ln, cos, +, if, etc)
29  *
30  * @par Thanks:
31  * Juha Nieminen (juha.nieminen@gmail.com) for relicensing this branch of the
32  * function parser code that this class is based upon under the new BSD license
33  * so that it could be used in VTK. Note, the BSD license applies to this
34  * version of the function parser only (by permission of the author), and not
35  * the original library.
36  *
37  * @par Thanks:
38  * Thomas Dunne (thomas.dunne@iwr.uni-heidelberg.de) for adding code for
39  * two-parameter-parsing and a few functions (sign, min, max).
40  *
41  * @par Thanks:
42  * Sid Sydoriak (sxs@lanl.gov) for adding boolean operations and
43  * conditional expressions and for fixing a variety of bugs.
44 */
45 
46 #ifndef vtkFunctionParser_h
47 #define vtkFunctionParser_h
48 
49 #include "vtkCommonMiscModule.h" // For export macro
50 #include "vtkObject.h"
51 #include "vtkTuple.h" // needed for vtkTuple
52 #include <vector> // needed for vector
53 #include <string> // needed for string.
54 
55 #define VTK_PARSER_IMMEDIATE 1
56 #define VTK_PARSER_UNARY_MINUS 2
57 #define VTK_PARSER_UNARY_PLUS 3
58 
59 // supported math functions
60 #define VTK_PARSER_ADD 4
61 #define VTK_PARSER_SUBTRACT 5
62 #define VTK_PARSER_MULTIPLY 6
63 #define VTK_PARSER_DIVIDE 7
64 #define VTK_PARSER_POWER 8
65 #define VTK_PARSER_ABSOLUTE_VALUE 9
66 #define VTK_PARSER_EXPONENT 10
67 #define VTK_PARSER_CEILING 11
68 #define VTK_PARSER_FLOOR 12
69 #define VTK_PARSER_LOGARITHM 13
70 #define VTK_PARSER_LOGARITHME 14
71 #define VTK_PARSER_LOGARITHM10 15
72 #define VTK_PARSER_SQUARE_ROOT 16
73 #define VTK_PARSER_SINE 17
74 #define VTK_PARSER_COSINE 18
75 #define VTK_PARSER_TANGENT 19
76 #define VTK_PARSER_ARCSINE 20
77 #define VTK_PARSER_ARCCOSINE 21
78 #define VTK_PARSER_ARCTANGENT 22
79 #define VTK_PARSER_HYPERBOLIC_SINE 23
80 #define VTK_PARSER_HYPERBOLIC_COSINE 24
81 #define VTK_PARSER_HYPERBOLIC_TANGENT 25
82 #define VTK_PARSER_MIN 26
83 #define VTK_PARSER_MAX 27
84 #define VTK_PARSER_SIGN 29
85 
86 // functions involving vectors
87 #define VTK_PARSER_CROSS 28
88 #define VTK_PARSER_VECTOR_UNARY_MINUS 30
89 #define VTK_PARSER_VECTOR_UNARY_PLUS 31
90 #define VTK_PARSER_DOT_PRODUCT 32
91 #define VTK_PARSER_VECTOR_ADD 33
92 #define VTK_PARSER_VECTOR_SUBTRACT 34
93 #define VTK_PARSER_SCALAR_TIMES_VECTOR 35
94 #define VTK_PARSER_VECTOR_TIMES_SCALAR 36
95 #define VTK_PARSER_VECTOR_OVER_SCALAR 37
96 #define VTK_PARSER_MAGNITUDE 38
97 #define VTK_PARSER_NORMALIZE 39
98 
99 // constants involving vectors
100 #define VTK_PARSER_IHAT 40
101 #define VTK_PARSER_JHAT 41
102 #define VTK_PARSER_KHAT 42
103 
104 // code for if(bool, trueval, falseval) resulting in a scalar
105 #define VTK_PARSER_IF 43
106 
107 // code for if(bool, truevec, falsevec) resulting in a vector
108 #define VTK_PARSER_VECTOR_IF 44
109 
110 // codes for boolean expressions
111 #define VTK_PARSER_LESS_THAN 45
112 
113 // codes for boolean expressions
114 #define VTK_PARSER_GREATER_THAN 46
115 
116 // codes for boolean expressions
117 #define VTK_PARSER_EQUAL_TO 47
118 
119 // codes for boolean expressions
120 #define VTK_PARSER_AND 48
121 
122 // codes for boolean expressions
123 #define VTK_PARSER_OR 49
124 
125 // codes for scalar variables come before those for vectors. Do not define
126 // values for VTK_PARSER_BEGIN_VARIABLES+1, VTK_PARSER_BEGIN_VARIABLES+2, ...,
127 // because they are used to look up variables numbered 1, 2, ...
128 #define VTK_PARSER_BEGIN_VARIABLES 50
129 
130 // the value that is returned as a result if there is an error
131 #define VTK_PARSER_ERROR_RESULT VTK_FLOAT_MAX
132 
133 class VTKCOMMONMISC_EXPORT vtkFunctionParser : public vtkObject
134 {
135 public:
136   static vtkFunctionParser *New();
137   vtkTypeMacro(vtkFunctionParser, vtkObject);
138   void PrintSelf(ostream& os, vtkIndent indent) override;
139 
140   /**
141    * Return parser's MTime
142    */
143   vtkMTimeType GetMTime() override;
144 
145   //@{
146   /**
147    * Set/Get input string to evaluate.
148    */
149   void SetFunction(const char *function);
150   vtkGetStringMacro(Function);
151   //@}
152 
153   /**
154    * Check whether the result is a scalar result.  If it isn't, then
155    * either the result is a vector or an error has occurred.
156    */
157   int IsScalarResult();
158 
159   /**
160    * Check whether the result is a vector result.  If it isn't, then
161    * either the result is scalar or an error has occurred.
162    */
163   int IsVectorResult();
164 
165   /**
166    * Get a scalar result from evaluating the input function.
167    */
168   double GetScalarResult();
169 
170   //@{
171   /**
172    * Get a vector result from evaluating the input function.
173    */
174   double* GetVectorResult() VTK_SIZEHINT(3);
GetVectorResult(double result[3])175   void GetVectorResult(double result[3]) {
176     double *r = this->GetVectorResult();
177     result[0] = r[0]; result[1] = r[1]; result[2] = r[2]; };
178   //@}
179 
180   //@{
181   /**
182    * Set the value of a scalar variable.  If a variable with this name
183    * exists, then its value will be set to the new value.  If there is not
184    * already a variable with this name, variableName will be added to the
185    * list of variables, and its value will be set to the new value.
186    */
187   void SetScalarVariableValue(const char* variableName, double value);
188   void SetScalarVariableValue(int i, double value);
189   //@}
190 
191   //@{
192   /**
193    * Get the value of a scalar variable.
194    */
195   double GetScalarVariableValue(const char* variableName);
196   double GetScalarVariableValue(int i);
197   //@}
198 
199   //@{
200   /**
201    * Set the value of a vector variable.  If a variable with this name
202    * exists, then its value will be set to the new value.  If there is not
203    * already a variable with this name, variableName will be added to the
204    * list of variables, and its value will be set to the new value.
205    */
206   void SetVectorVariableValue(const char* variableName, double xValue,
207                               double yValue, double zValue);
SetVectorVariableValue(const char * variableName,const double values[3])208   void SetVectorVariableValue(const char* variableName,
209                               const double values[3]) {
210     this->SetVectorVariableValue(variableName,values[0],values[1],values[2]);};
211   void SetVectorVariableValue(int i, double xValue, double yValue,
212                               double zValue);
SetVectorVariableValue(int i,const double values[3])213   void SetVectorVariableValue(int i, const double values[3]) {
214     this->SetVectorVariableValue(i,values[0],values[1],values[2]);};
215   //@}
216 
217   //@{
218   /**
219    * Get the value of a vector variable.
220    */
221   double* GetVectorVariableValue(const char* variableName) VTK_SIZEHINT(3);
GetVectorVariableValue(const char * variableName,double value[3])222   void GetVectorVariableValue(const char* variableName, double value[3]) {
223     double *r = this->GetVectorVariableValue(variableName);
224     value[0] = r[0]; value[1] = r[1]; value[2] = r[2]; };
225   double* GetVectorVariableValue(int i) VTK_SIZEHINT(3);
GetVectorVariableValue(int i,double value[3])226   void GetVectorVariableValue(int i, double value[3]) {
227     double *r = this->GetVectorVariableValue(i);
228     value[0] = r[0]; value[1] = r[1]; value[2] = r[2]; };
229   //@}
230 
231   /**
232    * Get the number of scalar variables.
233    */
GetNumberOfScalarVariables()234   int GetNumberOfScalarVariables()
235     { return static_cast<int>(this->ScalarVariableNames.size()); }
236 
237   /**
238    * Get scalar variable index or -1 if not found
239    */
240   int GetScalarVariableIndex(const char *name);
241 
242   /**
243    * Get the number of vector variables.
244    */
GetNumberOfVectorVariables()245   int GetNumberOfVectorVariables()
246     { return static_cast<int>(this->VectorVariableNames.size()); }
247 
248   /**
249    * Get scalar variable index or -1 if not found
250    */
251   int GetVectorVariableIndex(const char *name);
252 
253   /**
254    * Get the ith scalar variable name.
255    */
256   const char* GetScalarVariableName(int i);
257 
258   /**
259    * Get the ith vector variable name.
260    */
261   const char* GetVectorVariableName(int i);
262 
263   //@{
264   /**
265    * Returns whether a scalar variable is needed for the function evaluation.
266    * This is only valid after a successful Parse(). Thus, call GetScalarResult()
267    * or IsScalarResult() or similar method before calling this.
268    */
269   bool GetScalarVariableNeeded(int i);
270   bool GetScalarVariableNeeded(const char* variableName);
271   //@}
272 
273   //@{
274   /**
275    * Returns whether a vector variable is needed for the function evaluation.
276    * This is only valid after a successful Parse(). Thus, call GetVectorResult()
277    * or IsVectorResult() or similar method before calling this.
278    */
279   bool GetVectorVariableNeeded(int i);
280   bool GetVectorVariableNeeded(const char* variableName);
281   //@}
282 
283   /**
284    * Remove all the current variables.
285    */
286   void RemoveAllVariables();
287 
288   /**
289    * Remove all the scalar variables.
290    */
291   void RemoveScalarVariables();
292 
293   /**
294    * Remove all the vector variables.
295    */
296   void RemoveVectorVariables();
297 
298   //@{
299   /**
300    * When ReplaceInvalidValues is on, all invalid values (such as
301    * sqrt(-2), note that function parser does not handle complex
302    * numbers) will be replaced by ReplacementValue. Otherwise an
303    * error will be reported
304    */
305   vtkSetMacro(ReplaceInvalidValues,vtkTypeBool);
306   vtkGetMacro(ReplaceInvalidValues,vtkTypeBool);
307   vtkBooleanMacro(ReplaceInvalidValues,vtkTypeBool);
308   vtkSetMacro(ReplacementValue,double);
309   vtkGetMacro(ReplacementValue,double);
310   //@}
311 
312   /**
313    * Check the validity of the function expression.
314    */
315   void CheckExpression(int &pos, char **error);
316 
317   /**
318    * Allow the user to force the function to be re-parsed
319    */
320   void InvalidateFunction();
321 
322 protected:
323   vtkFunctionParser();
324   ~vtkFunctionParser() override;
325 
326   int Parse();
327 
328   /**
329    * Evaluate the function, returning true on success, false on failure.
330    */
331   bool Evaluate();
332 
333   int CheckSyntax();
334 
335   void CopyParseError(int &position, char **error);
336 
337   void RemoveSpaces();
338   char* RemoveSpacesFrom(const char* variableName);
339   int OperatorWithinVariable(int idx);
340 
341   int BuildInternalFunctionStructure();
342   void BuildInternalSubstringStructure(int beginIndex, int endIndex);
343   void AddInternalByte(unsigned char newByte);
344 
345   int IsSubstringCompletelyEnclosed(int beginIndex, int endIndex);
346   int FindEndOfMathFunction(int beginIndex);
347   int FindEndOfMathConstant(int beginIndex);
348 
349   int IsVariableName(int currentIndex);
350   int IsElementaryOperator(int op);
351 
352   int GetMathFunctionNumber(int currentIndex);
353   int GetMathFunctionNumberByCheckingParenthesis( int currentIndex );
354   int GetMathFunctionStringLength(int mathFunctionNumber);
355   int GetMathConstantNumber(int currentIndex);
356   int GetMathConstantStringLength(int mathConstantNumber);
357   unsigned char GetElementaryOperatorNumber(char op);
358   unsigned int GetOperandNumber(int currentIndex);
359   int GetVariableNameLength(int variableNumber);
360 
361   int DisambiguateOperators();
362 
363   /**
364    * Collects meta-data about which variables are needed by the current
365    * function. This is called only after a successful call to this->Parse().
366    */
367   void UpdateNeededVariables();
368 
369   vtkSetStringMacro(ParseError);
370 
371   int FindPositionInOriginalFunction(const int& pos);
372 
373   char* Function;
374   char* FunctionWithSpaces;
375 
376   int FunctionLength;
377   std::vector<std::string> ScalarVariableNames;
378   std::vector<std::string> VectorVariableNames;
379   std::vector<double> ScalarVariableValues;
380   std::vector<vtkTuple<double, 3> >  VectorVariableValues;
381   std::vector<bool> ScalarVariableNeeded;
382   std::vector<bool> VectorVariableNeeded;
383 
384   unsigned char *ByteCode;
385   int ByteCodeSize;
386   double *Immediates;
387   int ImmediatesSize;
388   double *Stack;
389   int StackSize;
390   int StackPointer;
391 
392   vtkTimeStamp FunctionMTime;
393   vtkTimeStamp ParseMTime;
394   vtkTimeStamp VariableMTime;
395   vtkTimeStamp EvaluateMTime;
396   vtkTimeStamp CheckMTime;
397 
398   vtkTypeBool ReplaceInvalidValues;
399   double ReplacementValue;
400 
401   int   ParseErrorPositon;
402   char* ParseError;
403 
404 private:
405   vtkFunctionParser(const vtkFunctionParser&) = delete;
406   void operator=(const vtkFunctionParser&) = delete;
407 };
408 
409 #endif
410