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