`ExpressionMath` (Python) ========================= .. module:: ExpressionMath ExpressionMath is a C++/Python Library that provides access to commonly used graphics functions. All functions listed below are pre-imported in the context of parameter expressions, so you can use them directly, for example: ``lerp(0.5, 1, 12)`` In a Python tab or shelf script, the functions are available from the ExpressionMath module, for example: ``ExpressionMath.lerp(0.5, 1, 12)`` Utilities --------- .. function:: ifelse(expression, a, b) If *expression* evaluates to True, return object *a*. Otherwise, return object *b*. .. warning:: BOTH inputs (*a* and *b*) are evaluated, no matter what the expression evaluates to. Unfortunately. this is inherent to Python argument handling and is not fixable. .. function:: clamp(value, a, b) Return value, clamped between the extremes *a* and *b*. It is not necessary for ``b > a``. Mixed scalar / vector inputs are supported for all arguments. >>> clamp(-0.5, 0.1, 0.9) 0.1 >>> clamp(-0.5, 0.9, 0.1) 0.1 >>> clamp((-0.5,0.0,0.5,1.0), 0.1, 0.9) (0.1, 0.1, 0.5, 0.9) .. function:: lerp(mix, a, b) Return a linear interpolation between *a* and *b*, combined using the fraction *mix*. *mix* is not clamped between [0,1]. A *mix* value of 0.0 returns *a*. Mixed scalar / vector inputs are supported for all arguments. >>> lerp(0.0, 10, 20) 10.0 >>> lerp(0.5, 10, 20) 15.0 >>> lerp(1.5, 10, 20) 25.0 >>> lerp((0.0,0.5,1.5), 10, 20) (10.0, 15.0, 25.0) >>> lerp(0.5, 10, (20,30,40)) (15.0, 20.0, 25.0) .. function:: smoothstep(t) Compute a smoothstep (ease in, ease out) version of *t*: [0,1]. This will clamp the output to [0,1]. Both scalar and vector input is supported. .. note:: This is the 'classic' smoothstep: ``3t**2 - 2t**3``, rather Perlin [02] modified smoothstep: ``6t**5 - 15t**4 + 10t**3``. The two are quite similar, the differences being that Perlin's smoothstep has zero 1st and 2nd derivatives at ``t=0`` and ``t=1``, and is thus generally preferred for general use. :: >>> smoothstep(0.2) 0.05792 >>> smoothstep((-0.5, 0.0, 0.25, 0.5, 0.75, 1.0, 1.5)) (0.0, 0.0, 0.103515625, 0.5, 0.896484375, 1.0, 1.0) .. function:: fit(value, oldmin, oldmax, newmin, newmax) Returns a number between *newmin* and *newmax*, which is relative to *value* in the range between *oldmin* and *oldmax*. Mixed scalar / vector inputs are supported for all arguments. >>> fit(0, -1, 1, 10, 20) 15.0 >>> fit(2, -1, 1, 10, 20) 25.0 >>> fit((-1,0.5,0.5,1), -1, 1, 10, 20) (10.0, 17.5, 17.5, 20.0) .. function:: cfit(value, oldmin, oldmax, newmin, newmax) Same as fit, but the result is clamped to [*newmin*, *newmax*]. Mixed scalar / vector inputs are supported for all arguments. >>> cfit(0, -1, 1, 10, 20) 15.0 >>> cfit(2, -1, 1, 10, 20) 20.0 >>> cfit((-1,0.5,0.5,1), -1, 1, 10, 20) (10.0, 17.5, 17.5, 20.0) .. function:: softcfit(value, oldmin, oldmax, newmin, newmax) Same as cfit, but value is interpolates between *oldmin* and *oldmax* using :func:`smoothstep`. Mixed scalar / vector inputs are supported for all arguments. >>> softcfit(0, -1, 1, 10, 20) 15.0 >>> softcfit(2, -1, 1, 10, 20) 20.0 >>> softcfit((-1,0.5,0.5,1), -1, 1, 10, 20) (10.0, 18.96484375, 18.96484375, 20.0) .. function:: retime(frame, start, end, inMode, outMode) Performs frame interpolation using specified hold mode: 'freeze', 'repeat', or 'mirror'. freeze Hold the first/last frame of the sequence: ``1111 1234 4444`` repeat Repeat the sequence: ``1234 1234 1234`` mirror Mirror the sequence, end points are only used once: ``3432 1234 3212`` .. note:: Repeat mode may generate values outside of [*start*, *end*] at non-integer time samples (due to extrapolation). Supports float input for {*frame*, *start*, *end*}. It is not necessary for ``start < end`` (though ``start != end``). >>> retime(110, 101, 110, 'repeat', 'repeat') 110.0 >>> retime(111, 101, 110, 'repeat', 'repeat') 101.0 >>> retime(112, 101, 110, 'repeat', 'repeat') 102.0 >>> retime(111, 101, 110, 'repeat', 'freeze') 110.0 >>> retime(112, 101, 110, 'repeat', 'freeze') 110.0 >>> retime(111, 101, 110, 'repeat', 'mirror') 109.0 >>> retime(112, 101, 110, 'repeat', 'mirror') 108.0 Noise ----- .. function:: noise(x [,y [,z [,w]]]]) Improved Perlin noise [02], contained within the range [0,1]. The noise is generated by smoothing interpolating a set a pseudo-random gradients at regularly spaced points in space (integer lattice locations). The statistical characteristics of this call closely approximates that of PRman's noise operator. One, two, three, and four-dimensional interpolants are provided. >>> noise(0.0) 0.5 >>> noise(0.5) 0.40600001811981201 >>> noise(1.0) 0.5 >>> noise(0.5,0.5) 0.6901249885559082 >>> noise(0.5) 0.6901249885559082 .. function:: snoise(x [,y [,z [,w]]]]) Signed equivalent of :func:`noise`. >>> snoise(0.0) 0.0 >>> snoise(0.5) -0.18799999356269836 >>> snoise(1.0) 0.0 >>> snoise(0.5,0.5) 0.38025002181529999 .. function:: randval(min, max, seedInt) Return a random value between [*min*, *max*] using the specified seed integer. The distribution is identical to Splat's randVal3 function. >>> randval(0,1,0) 0.22541344799693055 >>> randval(0,1,1) 0.16124458358652066 >>> randval(0,2,1) 0.32248916717304132 >>> [randval(0,1,frame) for frame in xrange(101,103)] [0.77299156360630683, 0.83146012384245638, 0.099642227194188679] Hashing ------- .. function:: stablehash(string) Return a 32-bit signed integer hash of the specified string. This result is stable across architectures (i.e., you get the same answer on both 32- and 64-bit platforms.) This result is often useful for turning strings (such as scenegraph locations) into seedIntegers for use in randval (see above). >>> stablehash('') 2118318316 >>> stablehash('/root/world/lights/rig/key1') -847711557 >>> stablehash('/root/world/lights/rig/key2') 652177629 Floating Point -------------- .. function:: isinf(number) Return whether the argument value is an infinity (positive or negative). >>> isinf(1.0) False >>> isinf(float('inf')) True .. function:: isnan(number) Return whether the argument value is a NaN. >>> isnan(1.0) False >>> isinf(float('nan')) True .. function:: isfinite(number) Return whether the argument value is a finite value (zero, subnormal, or normal, and not infinite or NaN). >>> isfinite(1.0) True >>> isfinite(float('nan')) False >>> isfinite(float('inf')) False >>> isfinite(float('-inf')) False