---
name: "SoCalculator"
section: "3iv"
platform: "linux"
package: "inventor-doc"
version: "2.1.6+ds-2"
release: "Debian 13 (Trixie)"
platforms: ["linux"]
url: "https://new.carta.tech/SoCalculator/3iv"
---

# SoCalculator(3iv)

a general-purpose calculator

## NAME

SoCalculator — a general-purpose calculator

## INHERITS FROM

SoBase \> SoFieldContainer \> SoEngine \> SoCalculator

## SYNOPSIS

**#include \<Inventor/engines/SoCalculator.h\>**

Inputs from class SoCalculator:

**SoMFFloat**	**a**\
 **SoMFFloat**	**b**\
 **SoMFFloat**	**c**\
 **SoMFFloat**	**d**\
 **SoMFFloat**	**e**\
 **SoMFFloat**	**f**\
 **SoMFFloat**	**g**\
 **SoMFFloat**	**h**\
 **SoMFVec3f**	**A**\
 **SoMFVec3f**	**B**\
 **SoMFVec3f**	**C**\
 **SoMFVec3f**	**D**\
 **SoMFVec3f**	**E**\
 **SoMFVec3f**	**F**\
 **SoMFVec3f**	**G**\
 **SoMFVec3f**	**H**\
 **SoMFString**	**expression**

Outputs from class SoCalculator:

**(SoMFFloat)**	**oa**\
 **(SoMFFloat)**	**ob**\
 **(SoMFFloat)**	**oc**\
 **(SoMFFloat)**	**od**\
 **(SoMFVec3f)**	**oA**\
 **(SoMFVec3f)**	**oB**\
 **(SoMFVec3f)**	**oC**\
 **(SoMFVec3f)**	**oD**

Methods from class SoCalculator:

	**SoCalculator()**

Methods from class SoEngine:

**static SoType**	**getClassTypeId()**\
 **virtual int**	**getOutputs(SoEngineOutputList &list) const**\
 **SoEngineOutput \***	**getOutput(const SbName &outputName) const**\
 **SbBool**	**getOutputName(const SoEngineOutput \*output, SbName &outputName) const**\
 **SoEngine \***	**copy() const**\
 **static SoEngine \***	**getByName(const SbName &name)**\
 **static int**	**getByName(const SbName &name, SoEngineList &list)**

Methods from class SoFieldContainer:

**void**	**setToDefaults()**\
 **SbBool**	**hasDefaultValues() const**\
 **SbBool**	**fieldsAreEqual(const SoFieldContainer \*fc) const**\
 **void**	**copyFieldValues(const SoFieldContainer \*fc, SbBool copyConnections = FALSE)**\
 **SbBool**	**set(const char \*fieldDataString)**\
 **void**	**get(SbString &fieldDataString)**\
 **virtual int**	**getFields(SoFieldList &resultList) const**\
 **virtual SoField \***	**getField(const SbName &fieldName) const**\
 **SbBool**	**getFieldName(const SoField \*field, SbName &fieldName) const**\
 **SbBool**	**isNotifyEnabled() const**\
 **SbBool**	**enableNotify(SbBool flag)**

Methods from class SoBase:

**void**	**ref()**\
 **void**	**unref() const**\
 **void**	**unrefNoDelete() const**\
 **void**	**touch()**\
 **virtual SoType**	**getTypeId() const**\
 **SbBool**	**isOfType(SoType type) const**\
 **virtual void**	**setName(const SbName &name)**\
 **virtual SbName**	**getName() const**

## DESCRIPTION

**This engine is a general-purpose calculator. The calculator operates on floating-point values and 3D floating-point vectors. The engine takes up to eight inputs of each type (SoMFFloat** and **SoMFVec3f**), and produces up to four outputs of each type.

Each input field (**a**-**h**, **A**-**H**) can have multiple values, allowing the engine to evaluate the expression with different values in parallel. Some inputs may have more values than others. In such cases, the last value of the shorter inputs will be repeated as necessary.

The **expression** input string specifies the expression to be evaluated. An expression can consist of multiple subexpressions. Several subexpressions can be specified in one string, separated by semicolons (;). Alternatively, the subexpressions can be stored in separate strings in the multiple-valued input field.

Each subexpression is of the form:

```
<lhs> = <rhs>
```

The **\<lhs\>** can be any one of the outputs or a temporary variable. The engine provides 8 temporary floating-point variables (ta, tb, tc, td, te, tf, tg, and th), and 8 temporary vector variables (tA, tB, tC, tD, tE, tF, tG, and tH). You can assign a value to one component of a vector output (**A**-**H**) or a vector variable (**tA**-**tH**) by using the \[\] operator. For example, oA\[0\] = \<rhs\>, will evaluate the right hand side and assign the value to the first component of the output vector **oA**.

The **\<rhs\>** supports arithmetic, logical and conditional operators. They are:

```
(unary)   !, -
(binary)  +, -, *, /, %, <, > <=, >=, ==, !=, &&, ||
(ternary) ? :
```

The ternary operator is a conditional operator. For example, **a ? b : c** evaluates to b if a != 0, and to c if a==0.

Valid operands for the **\<rhs\>** include the inputs, outputs, temporary variables, and their components (e.g. oA\[0\]). Operands can also be numeric constants (e.g. 1.0), pre-defined named constants, or pre-defined functions.

The named constants are:

```
MAXFLOAT
MINFLOAT
M_E
M_LOG2E
M_LOG10E
M_LN2
M_LN10
M_PI
M_SQRT2  = sqrt(2)
M_SQRT1_2 = sqrt(1/2)
```

Most of the pre-defined functions come from the math library:

```
cos, sin, tan,
acos, asin, atan, atan2,
cosh, sinh, tanh,
sqrt, pow, exp, log, log10,
ceil, floor, fabs, fmod.
```

Other functions are defined by **SoCalculator**. They are:

```
rand(f) - Random number generator
cross(v1, v2) - Vector cross product
dot(v1, v2) - Vector dot product
length(v) - Vector length
normalize(v) - Normalize vector
vec3f(f1, f2, f3) - Generate a vector from 3 floats
```

The subexpressions are evaluated in order, so a variable set in the \<lhs\> of an earlier expression may be used in the \<rhs\> of a later expression.

Note, when the input has multiple values, all the subexpressions specified in the **expression** are applied to all the multiple input values. This is unlike the **SoBoolOperation** engine, where each operation is applied only to the corresponding entries of the input data. Note also, that even though the inputs and outputs can have multiple values the \[\] operator is only for indexing into the values of a single vector. It does not index into the multiple values of a field. For example, if the floating-point input field **a** has two values: 1.0, and 2.0, then the expression

```
"oA[0]=a; oA[1]=a; oA[2]=0.0"
```

will produce two output vectors in **oA**: (1.0, 1.0, 0.0) and (2.0, 2.0, 0.0).

Examples of expressions:

```
"ta = oA[0]*floor(a)"
"tb = (a+b)*sin(M_PI)"
"oA = vec3f(ta, tb, ta+tb)"
"oB = normalize(oA)"
"ta = a; tb = sin(ta); oA = vec3f(ta, tb, 0)"
```

## INPUTS

**SoMFFloat**	**a**\
 **SoMFFloat**	**b**\
 **SoMFFloat**	**c**\
 **SoMFFloat**	**d**\
 **SoMFFloat**	**e**\
 **SoMFFloat**	**f**\
 **SoMFFloat**	**g**\
 **SoMFFloat**	**h**\
 Inputs a-h are the floating-point values.

**SoMFVec3f**	**A**\
 **SoMFVec3f**	**B**\
 **SoMFVec3f**	**C**\
 **SoMFVec3f**	**D**\
 **SoMFVec3f**	**E**\
 **SoMFVec3f**	**F**\
 **SoMFVec3f**	**G**\
 **SoMFVec3f**	**H**\
 Inputs A-H are the vectors.

**SoMFString**	**expression**\
 The expression to be evaluated.

## OUTPUTS

**(SoMFFloat)**	**oa**\
 **(SoMFFloat)**	**ob**\
 **(SoMFFloat)**	**oc**\
 **(SoMFFloat)**	**od**\
 Outputs oa-od are the floating-point values.

**(SoMFVec3f)**	**oA**\
 **(SoMFVec3f)**	**oB**\
 **(SoMFVec3f)**	**oC**\
 **(SoMFVec3f)**	**oD**\
 Outputs oA-oD are the vectors.

## METHODS

	**SoCalculator()**\
 Constructor

## FILE FORMAT/DEFAULTS

```
Calculator {
a	0
b	0
c	0
d	0
e	0
f	0
g	0
h	0
A	0 0 0
B	0 0 0
C	0 0 0
D	0 0 0
E	0 0 0
F	0 0 0
G	0 0 0
H	0 0 0
expression	""
}
```

## SEE ALSO

**SoEngineOutput, SoBoolOperation**
