diff --git a/src/blender_maxwell/node_trees/maxwell_sim_nodes/contracts/__init__.py b/src/blender_maxwell/node_trees/maxwell_sim_nodes/contracts/__init__.py index 188b93f..b1d9b58 100644 --- a/src/blender_maxwell/node_trees/maxwell_sim_nodes/contracts/__init__.py +++ b/src/blender_maxwell/node_trees/maxwell_sim_nodes/contracts/__init__.py @@ -48,7 +48,7 @@ from .flow_kinds import ( FlowKind, InfoFlow, RangeFlow, - LazyValueFuncFlow, + FuncFlow, ParamsFlow, ScalingMode, ValueFlow, @@ -119,7 +119,7 @@ __all__ = [ 'FlowKind', 'InfoFlow', 'RangeFlow', - 'LazyValueFuncFlow', + 'FuncFlow', 'ParamsFlow', 'ScalingMode', 'ValueFlow', diff --git a/src/blender_maxwell/node_trees/maxwell_sim_nodes/contracts/flow_kinds/__init__.py b/src/blender_maxwell/node_trees/maxwell_sim_nodes/contracts/flow_kinds/__init__.py index bf97bbb..12ac728 100644 --- a/src/blender_maxwell/node_trees/maxwell_sim_nodes/contracts/flow_kinds/__init__.py +++ b/src/blender_maxwell/node_trees/maxwell_sim_nodes/contracts/flow_kinds/__init__.py @@ -19,7 +19,7 @@ from .capabilities import CapabilitiesFlow from .flow_kinds import FlowKind from .info import InfoFlow from .lazy_range import RangeFlow, ScalingMode -from .lazy_value_func import LazyValueFuncFlow +from .lazy_func import FuncFlow from .params import ParamsFlow from .value import ValueFlow @@ -30,7 +30,7 @@ __all__ = [ 'InfoFlow', 'RangeFlow', 'ScalingMode', - 'LazyValueFuncFlow', + 'FuncFlow', 'ParamsFlow', 'ValueFlow', ] diff --git a/src/blender_maxwell/node_trees/maxwell_sim_nodes/contracts/flow_kinds/flow_kinds.py b/src/blender_maxwell/node_trees/maxwell_sim_nodes/contracts/flow_kinds/flow_kinds.py index 3c633b0..4a7b17a 100644 --- a/src/blender_maxwell/node_trees/maxwell_sim_nodes/contracts/flow_kinds/flow_kinds.py +++ b/src/blender_maxwell/node_trees/maxwell_sim_nodes/contracts/flow_kinds/flow_kinds.py @@ -40,7 +40,7 @@ class FlowKind(enum.StrEnum): Array: An object with dimensions, and possibly a unit. Whenever a `Value` is defined, a single-element `list` will also be generated by default as `Array` However, for any other array-like variants (or sockets that only represent array-like objects), `Array` should be defined manually. - LazyValueFunc: A composable function. + Func: A composable function. Can be used to represent computations for which all data is not yet known, or for which just-in-time compilation can drastically increase performance. Range: An object that generates an `Array` from range information (start/stop/step/spacing). This should be used instead of `Array` whenever possible. @@ -55,7 +55,7 @@ class FlowKind(enum.StrEnum): Array = enum.auto() # Lazy - LazyValueFunc = enum.auto() + Func = enum.auto() Range = enum.auto() # Auxiliary @@ -96,7 +96,7 @@ class FlowKind(enum.StrEnum): return { FlowKind.Value: FlowKind.Value, FlowKind.Array: FlowKind.Array, - FlowKind.LazyValueFunc: FlowKind.LazyValueFunc, + FlowKind.Func: FlowKind.Func, FlowKind.Range: FlowKind.Range, }[self] @@ -106,7 +106,7 @@ class FlowKind(enum.StrEnum): FlowKind.Value: 'CIRCLE', FlowKind.Array: 'SQUARE', FlowKind.Range: 'SQUARE', - FlowKind.LazyValueFunc: 'DIAMOND', + FlowKind.Func: 'DIAMOND', }[self] #################### @@ -119,7 +119,7 @@ class FlowKind(enum.StrEnum): FlowKind.Value: 'Value', FlowKind.Array: 'Array', FlowKind.Range: 'Range', - FlowKind.LazyValueFunc: 'Func', + FlowKind.Func: 'Func', FlowKind.Params: 'Parameters', FlowKind.Info: 'Information', }[v] diff --git a/src/blender_maxwell/node_trees/maxwell_sim_nodes/contracts/flow_kinds/lazy_value_func.py b/src/blender_maxwell/node_trees/maxwell_sim_nodes/contracts/flow_kinds/lazy_func.py similarity index 88% rename from src/blender_maxwell/node_trees/maxwell_sim_nodes/contracts/flow_kinds/lazy_value_func.py rename to src/blender_maxwell/node_trees/maxwell_sim_nodes/contracts/flow_kinds/lazy_func.py index 4115a72..5f96504 100644 --- a/src/blender_maxwell/node_trees/maxwell_sim_nodes/contracts/flow_kinds/lazy_value_func.py +++ b/src/blender_maxwell/node_trees/maxwell_sim_nodes/contracts/flow_kinds/lazy_func.py @@ -30,7 +30,7 @@ LazyFunction: typ.TypeAlias = typ.Callable[[typ.Any, ...], typ.Any] @dataclasses.dataclass(frozen=True, kw_only=True) -class LazyValueFuncFlow: +class FuncFlow: r"""Defines a flow of data as incremental function composition. For specific math system usage instructions, please consult the documentation of relevant nodes. @@ -44,9 +44,9 @@ class LazyValueFuncFlow: - **Performant**: Since no operations are happening, the UI feels fast and snappy. ## Strongly Related FlowKinds - For doing math, `LazyValueFunc` relies on two other `FlowKind`s, which must run in parallel: + For doing math, `Func` relies on two other `FlowKind`s, which must run in parallel: - - `FlowKind.Info`: Tracks the name, `spux.MathType`, unit (if any), length, and index coordinates for the raw data object produced by `LazyValueFunc`. + - `FlowKind.Info`: Tracks the name, `spux.MathType`, unit (if any), length, and index coordinates for the raw data object produced by `Func`. - `FlowKind.Params`: Tracks the particular values of input parameters to the lazy function, each of which can also be symbolic. For more, please see the documentation for each. @@ -84,12 +84,12 @@ class LazyValueFuncFlow: ## 'A0', 'KV0' are of length 'p' and 'q' def f_0(*args, **kwargs): ... - lazy_value_func_0 = LazyValueFuncFlow( + lazy_func_0 = FuncFlow( func=f_0, func_args=[(a_i, type(a_i)) for a_i in A0], func_kwargs={k: v for k,v in KV0}, ) - output_0 = lazy_value_func.func(*A0_computed, **KV0_computed) + output_0 = lazy_func.func(*A0_computed, **KV0_computed) ``` ## `depth>0`: Composition Chaining @@ -120,7 +120,7 @@ class LazyValueFuncFlow: ## 'A1', 'KV1' are therefore of length 'r' and 's' def f_1(output_0, *args, **kwargs): ... - lazy_value_func_1 = lazy_value_func_0.compose_within( + lazy_func_1 = lazy_func_0.compose_within( enclosing_func=f_1, enclosing_func_args=[(a_i, type(a_i)) for a_i in A1], enclosing_func_kwargs={k: type(v) for k,v in K1}, @@ -128,10 +128,10 @@ class LazyValueFuncFlow: A_computed = A0_computed + A1_computed KW_computed = KV0_computed + KV1_computed - output_1 = lazy_value_func_1.func(*A_computed, **KW_computed) + output_1 = lazy_func_1.func(*A_computed, **KW_computed) ``` - By using `LazyValueFunc`, we've guaranteed that even hugely deep $n$s won't ever look more complicated than this. + By using `Func`, we've guaranteed that even hugely deep $n$s won't ever look more complicated than this. ## `max depth`: "Realization" So, we've composed a bunch of functions of functions of ... @@ -142,22 +142,22 @@ class LazyValueFuncFlow: ```python # A_all and KW_all must be tracked on the side. - output_n = lazy_value_func_n.func(*A_all, **KW_all) + output_n = lazy_func_n.func(*A_all, **KW_all) ``` Of course, this comes with enormous overhead. Aside from the function calls themselves (which can be non-trivial), we must also contend with the enormous inefficiency of performing array operations sequentially. - That brings us to the killer feature of `LazyValueFuncFlow`, and the motivating reason for doing any of this at all: + That brings us to the killer feature of `FuncFlow`, and the motivating reason for doing any of this at all: ```python - output_n = lazy_value_func_n.func_jax(*A_all, **KW_all) + output_n = lazy_func_n.func_jax(*A_all, **KW_all) ``` What happened was, **the entire pipeline** was compiled, optimized, and computed with bare-metal performance on either a CPU, GPU, or TPU. With the help of the `jax` library (and its underlying OpenXLA bytecode), all of that inefficiency has been optimized based on _what we're trying to do_, not _exactly how we're doing it_, in order to maximize the use of modern massively-parallel devices. - See the documentation of `LazyValueFunc.func_jax()` for more information on this process. + See the documentation of `Func.func_jax()` for more information on this process. @@ -187,12 +187,12 @@ class LazyValueFuncFlow: As a more nuanced example, when lag occurs due to the computing an image-based plot based on live-computed math, then the visual feedback of _the plot actually changing_ seems to have a similar effect, not least because it's emotionally well-understood that detaching the `Viewer` node would also remove the lag. In short: Even if lazy evaluation didn't make any math faster, it will still _feel_ faster (to a point - raw performance obviously still matters). - Without `LazyValueFuncFlow`, the point of evaluation cannot be chosen at all, which is a huge issue for all the named reasons. - With `LazyValueFuncFlow`, better-chosen evaluation points can be chosen to cause the _user experience_ of high performance, simply because we were able to shift the exact same computation to a point in time where the user either understands or tolerates the delay better. + Without `FuncFlow`, the point of evaluation cannot be chosen at all, which is a huge issue for all the named reasons. + With `FuncFlow`, better-chosen evaluation points can be chosen to cause the _user experience_ of high performance, simply because we were able to shift the exact same computation to a point in time where the user either understands or tolerates the delay better. ## Flexibility Large-scale math is done on tensors, whether one knows (or likes!) it or not. - To this end, the indexed arrays produced by `LazyValueFuncFlow.func_jax` aren't quite sufficient for most operations we want to do: + To this end, the indexed arrays produced by `FuncFlow.func_jax` aren't quite sufficient for most operations we want to do: - **Naming**: What _is_ each axis? Unnamed index axes are sometimes easy to decode, but in general, names have an unexpectedly critical function when operating on arrays. @@ -206,13 +206,13 @@ class LazyValueFuncFlow: Not only do we endeavor to track these, but we also introduce unit-awareness to the coordinates, and design the entire math system to visually communicate the state of arrays before/after every single computation, as well as only expose operations that this tracked data indicates possible. - In practice, this happens in `FlowKind.Info`, which due to having its own `FlowKind` "lane" can be adjusted without triggering changes to (and therefore recompilation of) the `FlowKind.LazyValueFunc` chain. + In practice, this happens in `FlowKind.Info`, which due to having its own `FlowKind` "lane" can be adjusted without triggering changes to (and therefore recompilation of) the `FlowKind.Func` chain. **Please consult the `InfoFlow` documentation for more**. ## Performance All values introduced while processing are kept in a seperate `FlowKind` lane, with its own incremental caching: `FlowKind.Params`. - It's a simple mechanism, but for the cost of introducing an extra `FlowKind` "lane", all of the values used to process data can be live-adjusted without the overhead of recompiling the entire `LazyValueFunc` every time anything changes. + It's a simple mechanism, but for the cost of introducing an extra `FlowKind` "lane", all of the values used to process data can be live-adjusted without the overhead of recompiling the entire `Func` every time anything changes. Moreover, values used to process data don't even have to be numbers yet: They can be expressions of symbolic variables, complete with units, which are only realized at the very end of the chain, by the node that absolutely cannot function without the actual numerical data. See the `ParamFlow` documentation for more information. @@ -224,7 +224,7 @@ class LazyValueFuncFlow: A few teasers of what nodes can do with this system: **Auto-Differentiation**: `jax.jit` isn't even really the killer feature of `jax`. - `jax` can automatically differentiate `LazyValueFuncFlow.func_jax` with respect to any input parameter, including for fwd/bck jacobians/hessians, with robust numerical stability. + `jax` can automatically differentiate `FuncFlow.func_jax` with respect to any input parameter, including for fwd/bck jacobians/hessians, with robust numerical stability. When used in **Symbolic Interop**: Any `sympy` expression containing symbolic variables can be compiled, by `sympy`, into a `jax`-compatible function which takes We make use of this in the `Expr` socket, enabling true symbolic math to be used in high-performance lazy `jax` computations. @@ -304,7 +304,7 @@ class LazyValueFuncFlow: if self.supports_jax: return jax.jit(self.func) - msg = 'Can\'t express LazyValueFuncFlow as JAX function (using jax.jit), since "self.supports_jax" is False' + msg = 'Can\'t express FuncFlow as JAX function (using jax.jit), since "self.supports_jax" is False' raise ValueError(msg) #################### @@ -317,7 +317,7 @@ class LazyValueFuncFlow: enclosing_func_kwargs: dict[str, type] = MappingProxyType({}), supports_jax: bool = False, ) -> typ.Self: - """Compose `self.func` within the given enclosing function, which itself takes arguments, and create a new `LazyValueFuncFlow` to contain it. + """Compose `self.func` within the given enclosing function, which itself takes arguments, and create a new `FuncFlow` to contain it. This is the fundamental operation used to "chain" functions together. @@ -328,13 +328,13 @@ class LazyValueFuncFlow: C = spux.MathType.Complex x, y = sp.symbols('x y', real=True) - # Prepare "Root" LazyValueFuncFlow w/x,y args + # Prepare "Root" FuncFlow w/x,y args expr_root = 3*x + y**2 - 100 expr_root_func = sp.lambdify([x, y], expr, 'jax') - func_root = LazyValueFuncFlow(func=expr_root_func, func_args=[R,R], supports_jax=True) + func_root = FuncFlow(func=expr_root_func, func_args=[R,R], supports_jax=True) - # Compose "Enclosing" LazyValueFuncFlow w/z arg + # Compose "Enclosing" FuncFlow w/z arg r = sp.Symbol('z', real=True) z = sp.Symbol('z', complex=True) expr = 10*sp.re(z) / (z + r) @@ -351,7 +351,7 @@ class LazyValueFuncFlow: Returns: A lazy function that takes both the enclosed and enclosing arguments, and returns the value of the enclosing function (whose first argument is the output value of the enclosed function). """ - return LazyValueFuncFlow( + return FuncFlow( func=lambda *args, **kwargs: enclosing_func( self.func( *list(args[: len(self.func_args)]), @@ -373,17 +373,17 @@ class LazyValueFuncFlow: Generally, `self.func` produces a single array as output (when doing math, at least). But sometimes (as in the `OperateMathNode`), we need to perform a binary operation between two arrays, like say, $+$. - Without realizing both `LazyValueFuncFlow`s, it's not immediately obvious how one might accomplish this. + Without realizing both `FuncFlow`s, it's not immediately obvious how one might accomplish this. This overloaded function of the `|` operator (used as `left | right`) solves that problem. - A new `LazyValueFuncFlow` is created, which takes the arguments of both inputs, and which produces a single output value: A 2-tuple, where each element if the output of each function. + A new `FuncFlow` is created, which takes the arguments of both inputs, and which produces a single output value: A 2-tuple, where each element if the output of each function. Examples: Consider this illustrative (pseudocode) example: ```python # Presume a,b are values, and that A,B are their identifiers. - func_1 = LazyValueFuncFlow(func=compute_big_data_1, func_args=[A]) - func_2 = LazyValueFuncFlow(func=compute_big_data_2, func_args=[B]) + func_1 = FuncFlow(func=compute_big_data_1, func_args=[A]) + func_2 = FuncFlow(func=compute_big_data_2, func_args=[B]) f = (func_1 | func_2).compose_within(func=lambda D: D[0] + D[1]) @@ -402,7 +402,7 @@ class LazyValueFuncFlow: Returns: A lazy function that takes all arguments of both inputs, and returns a 2-tuple containing both output arguments. """ - return LazyValueFuncFlow( + return FuncFlow( func=lambda *args, **kwargs: ( self.func( *list(args[: len(self.func_args)]), diff --git a/src/blender_maxwell/node_trees/maxwell_sim_nodes/contracts/flow_kinds/lazy_range.py b/src/blender_maxwell/node_trees/maxwell_sim_nodes/contracts/flow_kinds/lazy_range.py index 226aafe..e80a528 100644 --- a/src/blender_maxwell/node_trees/maxwell_sim_nodes/contracts/flow_kinds/lazy_range.py +++ b/src/blender_maxwell/node_trees/maxwell_sim_nodes/contracts/flow_kinds/lazy_range.py @@ -29,7 +29,7 @@ from blender_maxwell.utils import logger from .array import ArrayFlow from .flow_kinds import FlowKind -from .lazy_value_func import LazyValueFuncFlow +from .lazy_func import FuncFlow log = logger.get(__name__) @@ -361,7 +361,7 @@ class RangeFlow: The ordering of the symbols is identical to `self.symbols`, which is guaranteed to be a deterministically sorted list of symbols. Returns: - A `LazyValueFuncFlow` that, given the input symbols defined in `self.symbols`, + A `FuncFlow` that, given the input symbols defined in `self.symbols`, """ # Compile JAX Functions for Start/End Expressions ## FYI, JAX-in-JAX works perfectly fine. @@ -378,18 +378,18 @@ class RangeFlow: return gen_array @functools.cached_property - def as_lazy_value_func(self) -> LazyValueFuncFlow: - """Creates a `LazyValueFuncFlow` using the output of `self.as_func`. + def as_lazy_func(self) -> FuncFlow: + """Creates a `FuncFlow` using the output of `self.as_func`. This is useful for ex. parameterizing the first array in the node graph, without binding an entire computed array. Notes: - The the function enclosed in the `LazyValueFuncFlow` is identical to the one returned by `self.as_func`. + The the function enclosed in the `FuncFlow` is identical to the one returned by `self.as_func`. Returns: - A `LazyValueFuncFlow` containing `self.as_func`, as well as appropriate supporting settings. + A `FuncFlow` containing `self.as_func`, as well as appropriate supporting settings. """ - return LazyValueFuncFlow( + return FuncFlow( func=self.as_func, func_args=[(spux.MathType.from_expr(sym)) for sym in self.symbols], supports_jax=True, @@ -401,7 +401,7 @@ class RangeFlow: def realize_start( self, symbol_values: dict[spux.Symbol, typ.Any] = MappingProxyType({}), - ) -> ArrayFlow | LazyValueFuncFlow: + ) -> ArrayFlow | FuncFlow: return spux.sympy_to_python( self.start.subs({sym: symbol_values[sym.name] for sym in self.symbols}) ) @@ -409,7 +409,7 @@ class RangeFlow: def realize_stop( self, symbol_values: dict[spux.Symbol, typ.Any] = MappingProxyType({}), - ) -> ArrayFlow | LazyValueFuncFlow: + ) -> ArrayFlow | FuncFlow: return spux.sympy_to_python( self.stop.subs({sym: symbol_values[sym.name] for sym in self.symbols}) ) @@ -417,7 +417,7 @@ class RangeFlow: def realize_step_size( self, symbol_values: dict[spux.Symbol, typ.Any] = MappingProxyType({}), - ) -> ArrayFlow | LazyValueFuncFlow: + ) -> ArrayFlow | FuncFlow: raw_step_size = (self.realize_stop() - self.realize_start() + 1) / self.steps if self.mathtype is spux.MathType.Integer and raw_step_size.is_integer(): @@ -427,8 +427,8 @@ class RangeFlow: def realize( self, symbol_values: dict[spux.Symbol, typ.Any] = MappingProxyType({}), - kind: typ.Literal[FlowKind.Array, FlowKind.LazyValueFunc] = FlowKind.Array, - ) -> ArrayFlow | LazyValueFuncFlow: + kind: typ.Literal[FlowKind.Array, FlowKind.Func] = FlowKind.Array, + ) -> ArrayFlow | FuncFlow: """Apply a function to the bounds, effectively rescaling the represented array. Notes: @@ -458,8 +458,8 @@ class RangeFlow: if kind == FlowKind.Array: return ArrayFlow(values=gen_array(), unit=self.unit, is_sorted=True) - if kind == FlowKind.LazyValueFunc: - return LazyValueFuncFlow(func=gen_array, supports_jax=True) + if kind == FlowKind.Func: + return FuncFlow(func=gen_array, supports_jax=True) msg = f'Invalid kind: {kind}' raise TypeError(msg) diff --git a/src/blender_maxwell/node_trees/maxwell_sim_nodes/contracts/flow_kinds/params.py b/src/blender_maxwell/node_trees/maxwell_sim_nodes/contracts/flow_kinds/params.py index ad96956..1fdaafc 100644 --- a/src/blender_maxwell/node_trees/maxwell_sim_nodes/contracts/flow_kinds/params.py +++ b/src/blender_maxwell/node_trees/maxwell_sim_nodes/contracts/flow_kinds/params.py @@ -69,7 +69,7 @@ class ParamsFlow: unit_system: spux.UnitSystem, symbol_values: dict[spux.Symbol, spux.SympyExpr] = MappingProxyType({}), ): - """Realize the function arguments contained in this `ParamsFlow`, making it ready for insertion into `LazyValueFunc.func()`. + """Realize the function arguments contained in this `ParamsFlow`, making it ready for insertion into `Func.func()`. For all `arg`s in `self.func_args`, the following operations are performed: - **Unit System**: If `arg` @@ -121,7 +121,7 @@ class ParamsFlow: ): """Combine two function parameter lists, such that the LHS will be concatenated with the RHS. - Just like its neighbor in `LazyValueFunc`, this effectively combines two functions with unique parameters. + Just like its neighbor in `Func`, this effectively combines two functions with unique parameters. The next composed function will receive a tuple of two arrays, instead of just one, allowing binary operations to occur. """ return ParamsFlow( diff --git a/src/blender_maxwell/node_trees/maxwell_sim_nodes/contracts/sim_types.py b/src/blender_maxwell/node_trees/maxwell_sim_nodes/contracts/sim_types.py index decac42..613f2ae 100644 --- a/src/blender_maxwell/node_trees/maxwell_sim_nodes/contracts/sim_types.py +++ b/src/blender_maxwell/node_trees/maxwell_sim_nodes/contracts/sim_types.py @@ -318,12 +318,12 @@ class DataFileFormat(enum.StrEnum): """Abstraction of a data file format, providing a regularized way of interacting with filesystem data. Import/export interacts closely with the `Expr` socket's `FlowKind` semantics: - - `FlowKind.LazyValueFunc`: Generally realized on-import/export. + - `FlowKind.Func`: Generally realized on-import/export. - **Import**: Loading data is generally eager, but memory-mapped file loading would be manageable using this interface. - **Export**: The function is realized and only the array is inserted into the file. - `FlowKind.Params`: Generally consumed. - **Import**: A new, empty `ParamsFlow` object is created. - - **Export**: The `ParamsFlow` is consumed when realizing the `LazyValueFunc`. + - **Export**: The `ParamsFlow` is consumed when realizing the `Func`. - `FlowKind.Info`: As the most important element, it is kept in an (optional) sidecar metadata file. - **Import**: The sidecar file is loaded, checked, and used, if it exists. A warning about further processing may show if it doesn't. - **Export**: The sidecar file is written next to the canonical data file, in such a manner that it can be both read and loaded. diff --git a/src/blender_maxwell/node_trees/maxwell_sim_nodes/nodes/analysis/extract_data.py b/src/blender_maxwell/node_trees/maxwell_sim_nodes/nodes/analysis/extract_data.py index 6fda087..21aecc6 100644 --- a/src/blender_maxwell/node_trees/maxwell_sim_nodes/nodes/analysis/extract_data.py +++ b/src/blender_maxwell/node_trees/maxwell_sim_nodes/nodes/analysis/extract_data.py @@ -57,9 +57,7 @@ class ExtractDataNode(base.MaxwellSimNode): } output_socket_sets: typ.ClassVar = { 'Sim Data': {'Monitor Data': sockets.MaxwellMonitorDataSocketDef()}, - 'Monitor Data': { - 'Expr': sockets.ExprSocketDef(active_kind=ct.FlowKind.LazyValueFunc) - }, + 'Monitor Data': {'Expr': sockets.ExprSocketDef(active_kind=ct.FlowKind.Func)}, } #################### @@ -349,7 +347,7 @@ class ExtractDataNode(base.MaxwellSimNode): return ct.FlowSignal.FlowPending #################### - # - FlowKind.Array|LazyValueFunc: Monitor Data -> Expr + # - FlowKind.Array|Func: Monitor Data -> Expr #################### @events.computes_output_socket( 'Expr', @@ -384,16 +382,14 @@ class ExtractDataNode(base.MaxwellSimNode): @events.computes_output_socket( # Trigger 'Expr', - kind=ct.FlowKind.LazyValueFunc, + kind=ct.FlowKind.Func, # Loaded output_sockets={'Expr'}, output_socket_kinds={'Expr': ct.FlowKind.Array}, output_sockets_optional={'Expr': True}, ) - def compute_extracted_data_lazy( - self, output_sockets: dict - ) -> ct.LazyValueFuncFlow | None: - """Declare `Expr:LazyValueFunc` by creating a simple function that directly wraps `Expr:Array`. + def compute_extracted_data_lazy(self, output_sockets: dict) -> ct.FuncFlow | None: + """Declare `Expr:Func` by creating a simple function that directly wraps `Expr:Array`. Returns: The composable function array, if available, else `ct.FlowSignal.FlowPending`. @@ -402,9 +398,7 @@ class ExtractDataNode(base.MaxwellSimNode): has_output_expr = not ct.FlowSignal.check(output_expr) if has_output_expr: - return ct.LazyValueFuncFlow( - func=lambda: output_expr.values, supports_jax=True - ) + return ct.FuncFlow(func=lambda: output_expr.values, supports_jax=True) return ct.FlowSignal.FlowPending @@ -441,7 +435,7 @@ class ExtractDataNode(base.MaxwellSimNode): """Declare `Data:Info` by manually selecting appropriate axes, units, etc. for each monitor type. Returns: - Information describing the `Data:LazyValueFunc`, if available, else `ct.FlowSignal.FlowPending`. + Information describing the `Data:Func`, if available, else `ct.FlowSignal.FlowPending`. """ monitor_data = input_sockets['Monitor Data'] monitor_data_type = props['monitor_data_type'] diff --git a/src/blender_maxwell/node_trees/maxwell_sim_nodes/nodes/analysis/math/filter_math.py b/src/blender_maxwell/node_trees/maxwell_sim_nodes/nodes/analysis/math/filter_math.py index 4d78954..4dc9be9 100644 --- a/src/blender_maxwell/node_trees/maxwell_sim_nodes/nodes/analysis/math/filter_math.py +++ b/src/blender_maxwell/node_trees/maxwell_sim_nodes/nodes/analysis/math/filter_math.py @@ -265,10 +265,10 @@ class FilterMathNode(base.MaxwellSimNode): bl_label = 'Filter Math' input_sockets: typ.ClassVar = { - 'Expr': sockets.ExprSocketDef(active_kind=ct.FlowKind.LazyValueFunc), + 'Expr': sockets.ExprSocketDef(active_kind=ct.FlowKind.Func), } output_sockets: typ.ClassVar = { - 'Expr': sockets.ExprSocketDef(active_kind=ct.FlowKind.LazyValueFunc), + 'Expr': sockets.ExprSocketDef(active_kind=ct.FlowKind.Func), } #################### @@ -518,13 +518,13 @@ class FilterMathNode(base.MaxwellSimNode): current_bl_socket = self.loose_input_sockets.get('Dim') if ( current_bl_socket is None - or current_bl_socket.active_kind != ct.FlowKind.LazyValueFunc + or current_bl_socket.active_kind != ct.FlowKind.Func or current_bl_socket.mathtype != spux.MathType.Real or current_bl_socket.physical_type != spux.PhysicalType.NonPhysical ): self.loose_input_sockets = { 'Dim': sockets.ExprSocketDef( - active_kind=ct.FlowKind.LazyValueFunc, + active_kind=ct.FlowKind.Func, mathtype=spux.MathType.Real, physical_type=spux.PhysicalType.NonPhysical, show_info_columns=True, @@ -536,28 +536,28 @@ class FilterMathNode(base.MaxwellSimNode): self.loose_input_sockets = {} #################### - # - FlowKind.Value|LazyValueFunc + # - FlowKind.Value|Func #################### @events.computes_output_socket( 'Expr', - kind=ct.FlowKind.LazyValueFunc, + kind=ct.FlowKind.Func, props={'operation', 'dim_0', 'dim_1', 'slice_tuple'}, input_sockets={'Expr'}, - input_socket_kinds={'Expr': {ct.FlowKind.LazyValueFunc, ct.FlowKind.Info}}, + input_socket_kinds={'Expr': {ct.FlowKind.Func, ct.FlowKind.Info}}, ) - def compute_lazy_value_func(self, props: dict, input_sockets: dict): + def compute_lazy_func(self, props: dict, input_sockets: dict): operation = props['operation'] - lazy_value_func = input_sockets['Expr'][ct.FlowKind.LazyValueFunc] + lazy_func = input_sockets['Expr'][ct.FlowKind.Func] info = input_sockets['Expr'][ct.FlowKind.Info] - has_lazy_value_func = not ct.FlowSignal.check(lazy_value_func) + has_lazy_func = not ct.FlowSignal.check(lazy_func) has_info = not ct.FlowSignal.check(info) # Dimension(s) dim_0 = props['dim_0'] dim_1 = props['dim_1'] if ( - has_lazy_value_func + has_lazy_func and has_info and operation is not None and operation.are_dims_valid(info, dim_0, dim_1) @@ -570,7 +570,7 @@ class FilterMathNode(base.MaxwellSimNode): else None ) - return lazy_value_func.compose_within( + return lazy_func.compose_within( operation.jax_func(axis_0, axis_1, slice_tuple), enclosing_func_args=operation.func_args, supports_jax=True, @@ -594,14 +594,14 @@ class FilterMathNode(base.MaxwellSimNode): input_sockets={'Expr', 'Dim'}, input_socket_kinds={ 'Expr': ct.FlowKind.Info, - 'Dim': {ct.FlowKind.LazyValueFunc, ct.FlowKind.Params, ct.FlowKind.Info}, + 'Dim': {ct.FlowKind.Func, ct.FlowKind.Params, ct.FlowKind.Info}, }, input_sockets_optional={'Dim': True}, ) def compute_info(self, props, input_sockets) -> ct.InfoFlow: operation = props['operation'] info = input_sockets['Expr'] - dim_coords = input_sockets['Dim'][ct.FlowKind.LazyValueFunc] + dim_coords = input_sockets['Dim'][ct.FlowKind.Func] dim_params = input_sockets['Dim'][ct.FlowKind.Params] dim_info = input_sockets['Dim'][ct.FlowKind.Info] dim_symbol = props['set_dim_symbol'] diff --git a/src/blender_maxwell/node_trees/maxwell_sim_nodes/nodes/analysis/math/map_math.py b/src/blender_maxwell/node_trees/maxwell_sim_nodes/nodes/analysis/math/map_math.py index c8b4ddf..742fe6e 100644 --- a/src/blender_maxwell/node_trees/maxwell_sim_nodes/nodes/analysis/math/map_math.py +++ b/src/blender_maxwell/node_trees/maxwell_sim_nodes/nodes/analysis/math/map_math.py @@ -401,7 +401,7 @@ class MapMathNode(base.MaxwellSimNode): The name and type of the available symbol is clearly shown, and most valid `sympy` expressions that you would expect to work, should work. Use of expressions generally imposes no performance penalty: Just like the baked-in operations, it is compiled to a high-performance `jax` function. - Thus, it participates in the `ct.FlowKind.LazyValueFunc` composition chain. + Thus, it participates in the `ct.FlowKind.Func` composition chain. Attributes: @@ -412,10 +412,10 @@ class MapMathNode(base.MaxwellSimNode): bl_label = 'Map Math' input_sockets: typ.ClassVar = { - 'Expr': sockets.ExprSocketDef(active_kind=ct.FlowKind.LazyValueFunc), + 'Expr': sockets.ExprSocketDef(active_kind=ct.FlowKind.Func), } output_sockets: typ.ClassVar = { - 'Expr': sockets.ExprSocketDef(active_kind=ct.FlowKind.LazyValueFunc), + 'Expr': sockets.ExprSocketDef(active_kind=ct.FlowKind.Func), } #################### @@ -474,7 +474,7 @@ class MapMathNode(base.MaxwellSimNode): layout.prop(self, self.blfields['operation'], text='') #################### - # - FlowKind.Value|LazyValueFunc + # - FlowKind.Value|Func #################### @events.computes_output_socket( 'Expr', @@ -497,16 +497,14 @@ class MapMathNode(base.MaxwellSimNode): @events.computes_output_socket( 'Expr', - kind=ct.FlowKind.LazyValueFunc, + kind=ct.FlowKind.Func, props={'operation'}, input_sockets={'Expr'}, input_socket_kinds={ - 'Expr': ct.FlowKind.LazyValueFunc, + 'Expr': ct.FlowKind.Func, }, ) - def compute_func( - self, props, input_sockets - ) -> ct.LazyValueFuncFlow | ct.FlowSignal: + def compute_func(self, props, input_sockets) -> ct.FuncFlow | ct.FlowSignal: operation = props['operation'] expr = input_sockets['Expr'] diff --git a/src/blender_maxwell/node_trees/maxwell_sim_nodes/nodes/analysis/math/operate_math.py b/src/blender_maxwell/node_trees/maxwell_sim_nodes/nodes/analysis/math/operate_math.py index 44f0b81..ad3aff6 100644 --- a/src/blender_maxwell/node_trees/maxwell_sim_nodes/nodes/analysis/math/operate_math.py +++ b/src/blender_maxwell/node_trees/maxwell_sim_nodes/nodes/analysis/math/operate_math.py @@ -261,12 +261,12 @@ class OperateMathNode(base.MaxwellSimNode): bl_label = 'Operate Math' input_sockets: typ.ClassVar = { - 'Expr L': sockets.ExprSocketDef(active_kind=ct.FlowKind.LazyValueFunc), - 'Expr R': sockets.ExprSocketDef(active_kind=ct.FlowKind.LazyValueFunc), + 'Expr L': sockets.ExprSocketDef(active_kind=ct.FlowKind.Func), + 'Expr R': sockets.ExprSocketDef(active_kind=ct.FlowKind.Func), } output_sockets: typ.ClassVar = { 'Expr': sockets.ExprSocketDef( - active_kind=ct.FlowKind.LazyValueFunc, show_info_columns=True + active_kind=ct.FlowKind.Func, show_info_columns=True ), } @@ -344,7 +344,7 @@ class OperateMathNode(base.MaxwellSimNode): layout.prop(self, self.blfields['operation'], text='') #################### - # - FlowKind.Value|LazyValueFunc + # - FlowKind.Value|Func #################### @events.computes_output_socket( 'Expr', @@ -373,12 +373,12 @@ class OperateMathNode(base.MaxwellSimNode): @events.computes_output_socket( 'Expr', - kind=ct.FlowKind.LazyValueFunc, + kind=ct.FlowKind.Func, props={'operation'}, input_sockets={'Expr L', 'Expr R'}, input_socket_kinds={ - 'Expr L': ct.FlowKind.LazyValueFunc, - 'Expr R': ct.FlowKind.LazyValueFunc, + 'Expr L': ct.FlowKind.Func, + 'Expr R': ct.FlowKind.Func, }, ) def compose_func(self, props: dict, input_sockets: dict): diff --git a/src/blender_maxwell/node_trees/maxwell_sim_nodes/nodes/analysis/math/reduce_math.py b/src/blender_maxwell/node_trees/maxwell_sim_nodes/nodes/analysis/math/reduce_math.py index 7bfaa50..c44e5a4 100644 --- a/src/blender_maxwell/node_trees/maxwell_sim_nodes/nodes/analysis/math/reduce_math.py +++ b/src/blender_maxwell/node_trees/maxwell_sim_nodes/nodes/analysis/math/reduce_math.py @@ -97,7 +97,7 @@ class ReduceMathNode(base.MaxwellSimNode): 'Data', props={'active_socket_set', 'operation'}, input_sockets={'Data', 'Axis', 'Reducer'}, - input_socket_kinds={'Reducer': ct.FlowKind.LazyValueFunc}, + input_socket_kinds={'Reducer': ct.FlowKind.Func}, input_sockets_optional={'Reducer': True}, ) def compute_data(self, props: dict, input_sockets: dict): diff --git a/src/blender_maxwell/node_trees/maxwell_sim_nodes/nodes/analysis/math/transform_math.py b/src/blender_maxwell/node_trees/maxwell_sim_nodes/nodes/analysis/math/transform_math.py index b4fcd2d..b6c6d60 100644 --- a/src/blender_maxwell/node_trees/maxwell_sim_nodes/nodes/analysis/math/transform_math.py +++ b/src/blender_maxwell/node_trees/maxwell_sim_nodes/nodes/analysis/math/transform_math.py @@ -258,10 +258,10 @@ class TransformMathNode(base.MaxwellSimNode): bl_label = 'Transform Math' input_sockets: typ.ClassVar = { - 'Expr': sockets.ExprSocketDef(active_kind=ct.FlowKind.LazyValueFunc), + 'Expr': sockets.ExprSocketDef(active_kind=ct.FlowKind.Func), } output_sockets: typ.ClassVar = { - 'Expr': sockets.ExprSocketDef(active_kind=ct.FlowKind.LazyValueFunc), + 'Expr': sockets.ExprSocketDef(active_kind=ct.FlowKind.Func), } #################### @@ -323,7 +323,7 @@ class TransformMathNode(base.MaxwellSimNode): layout.prop(self, self.blfields['operation'], text='') #################### - # - Compute: LazyValueFunc / Array + # - Compute: Func / Array #################### @events.computes_output_socket( 'Expr', @@ -346,16 +346,14 @@ class TransformMathNode(base.MaxwellSimNode): @events.computes_output_socket( 'Expr', - kind=ct.FlowKind.LazyValueFunc, + kind=ct.FlowKind.Func, props={'operation'}, input_sockets={'Expr'}, input_socket_kinds={ - 'Expr': ct.FlowKind.LazyValueFunc, + 'Expr': ct.FlowKind.Func, }, ) - def compute_func( - self, props, input_sockets - ) -> ct.LazyValueFuncFlow | ct.FlowSignal: + def compute_func(self, props, input_sockets) -> ct.FuncFlow | ct.FlowSignal: operation = props['operation'] expr = input_sockets['Expr'] diff --git a/src/blender_maxwell/node_trees/maxwell_sim_nodes/nodes/analysis/viz.py b/src/blender_maxwell/node_trees/maxwell_sim_nodes/nodes/analysis/viz.py index 9b4489f..60101b5 100644 --- a/src/blender_maxwell/node_trees/maxwell_sim_nodes/nodes/analysis/viz.py +++ b/src/blender_maxwell/node_trees/maxwell_sim_nodes/nodes/analysis/viz.py @@ -209,7 +209,7 @@ class VizNode(base.MaxwellSimNode): #################### input_sockets: typ.ClassVar = { 'Expr': sockets.ExprSocketDef( - active_kind=ct.FlowKind.LazyValueFunc, + active_kind=ct.FlowKind.Func, default_symbols=[sim_symbols.x], default_value=2 * sim_symbols.x.sp_symbol, ), @@ -370,7 +370,7 @@ class VizNode(base.MaxwellSimNode): props={'viz_mode', 'viz_target', 'colormap'}, input_sockets={'Expr'}, input_socket_kinds={ - 'Expr': {ct.FlowKind.LazyValueFunc, ct.FlowKind.Info, ct.FlowKind.Params} + 'Expr': {ct.FlowKind.Func, ct.FlowKind.Info, ct.FlowKind.Params} }, all_loose_input_sockets=True, ) @@ -382,7 +382,7 @@ class VizNode(base.MaxwellSimNode): props={'viz_mode', 'viz_target', 'colormap'}, input_sockets={'Expr'}, input_socket_kinds={ - 'Expr': {ct.FlowKind.LazyValueFunc, ct.FlowKind.Info, ct.FlowKind.Params} + 'Expr': {ct.FlowKind.Func, ct.FlowKind.Info, ct.FlowKind.Params} }, unit_systems={'BlenderUnits': ct.UNITS_BLENDER}, all_loose_input_sockets=True, @@ -392,7 +392,7 @@ class VizNode(base.MaxwellSimNode): self, managed_objs, props, input_sockets, loose_input_sockets, unit_systems ): # Retrieve Inputs - lazy_value_func = input_sockets['Expr'][ct.FlowKind.LazyValueFunc] + lazy_func = input_sockets['Expr'][ct.FlowKind.Func] info = input_sockets['Expr'][ct.FlowKind.Info] params = input_sockets['Expr'][ct.FlowKind.Params] @@ -422,9 +422,9 @@ class VizNode(base.MaxwellSimNode): for sym in params.sorted_symbols } - # Realize LazyValueFunc w/Symbolic Values, Unit System + # Realize Func w/Symbolic Values, Unit System ## -> This gives us the actual plot data! - data = lazy_value_func.func_jax( + data = lazy_func.func_jax( *params.scaled_func_args( unit_systems['BlenderUnits'], symbol_values=symbol_values ), diff --git a/src/blender_maxwell/node_trees/maxwell_sim_nodes/nodes/inputs/constants/expr_constant.py b/src/blender_maxwell/node_trees/maxwell_sim_nodes/nodes/inputs/constants/expr_constant.py index ac248cd..8bd6f4b 100644 --- a/src/blender_maxwell/node_trees/maxwell_sim_nodes/nodes/inputs/constants/expr_constant.py +++ b/src/blender_maxwell/node_trees/maxwell_sim_nodes/nodes/inputs/constants/expr_constant.py @@ -29,12 +29,12 @@ class ExprConstantNode(base.MaxwellSimNode): input_sockets: typ.ClassVar = { 'Expr': sockets.ExprSocketDef( - active_kind=ct.FlowKind.LazyValueFunc, + active_kind=ct.FlowKind.Func, ), } output_sockets: typ.ClassVar = { 'Expr': sockets.ExprSocketDef( - active_kind=ct.FlowKind.LazyValueFunc, + active_kind=ct.FlowKind.Func, show_info_columns=True, ), } @@ -58,12 +58,12 @@ class ExprConstantNode(base.MaxwellSimNode): @events.computes_output_socket( # Trigger 'Expr', - kind=ct.FlowKind.LazyValueFunc, + kind=ct.FlowKind.Func, # Loaded input_sockets={'Expr'}, - input_socket_kinds={'Expr': ct.FlowKind.LazyValueFunc}, + input_socket_kinds={'Expr': ct.FlowKind.Func}, ) - def compute_lazy_value_func(self, input_sockets: dict) -> typ.Any: + def compute_lazy_func(self, input_sockets: dict) -> typ.Any: return input_sockets['Expr'] #################### diff --git a/src/blender_maxwell/node_trees/maxwell_sim_nodes/nodes/inputs/file_importers/data_file_importer.py b/src/blender_maxwell/node_trees/maxwell_sim_nodes/nodes/inputs/file_importers/data_file_importer.py index cc29404..e22412a 100644 --- a/src/blender_maxwell/node_trees/maxwell_sim_nodes/nodes/inputs/file_importers/data_file_importer.py +++ b/src/blender_maxwell/node_trees/maxwell_sim_nodes/nodes/inputs/file_importers/data_file_importer.py @@ -42,7 +42,7 @@ class DataFileImporterNode(base.MaxwellSimNode): 'File Path': sockets.FilePathSocketDef(), } output_sockets: typ.ClassVar = { - 'Expr': sockets.ExprSocketDef(active_kind=ct.FlowKind.LazyValueFunc), + 'Expr': sockets.ExprSocketDef(active_kind=ct.FlowKind.Func), } #################### @@ -121,11 +121,11 @@ class DataFileImporterNode(base.MaxwellSimNode): pass #################### - # - FlowKind.Array|LazyValueFunc + # - FlowKind.Array|Func #################### @events.computes_output_socket( 'Expr', - kind=ct.FlowKind.LazyValueFunc, + kind=ct.FlowKind.Func, input_sockets={'File Path'}, ) def compute_func(self, input_sockets: dict) -> td.Simulation: @@ -144,7 +144,7 @@ class DataFileImporterNode(base.MaxwellSimNode): # Jax Compatibility: Lazy Data Loading ## -> Delay loading of data from file as long as we can. if data_file_format.loader_is_jax_compatible: - return ct.LazyValueFuncFlow( + return ct.FuncFlow( func=lambda: data_file_format.loader(file_path), supports_jax=True, ) @@ -152,7 +152,7 @@ class DataFileImporterNode(base.MaxwellSimNode): # No Jax Compatibility: Eager Data Loading ## -> Load the data now and bind it. data = data_file_format.loader(file_path) - return ct.LazyValueFuncFlow(func=lambda: data, supports_jax=True) + return ct.FuncFlow(func=lambda: data, supports_jax=True) return ct.FlowSignal.FlowPending return ct.FlowSignal.FlowPending @@ -175,7 +175,7 @@ class DataFileImporterNode(base.MaxwellSimNode): 'Expr', kind=ct.FlowKind.Info, output_sockets={'Expr'}, - output_socket_kinds={'Expr': ct.FlowKind.LazyValueFunc}, + output_socket_kinds={'Expr': ct.FlowKind.Func}, ) def compute_info(self, output_sockets) -> ct.InfoFlow: """Declare an `InfoFlow` based on the data shape. diff --git a/src/blender_maxwell/node_trees/maxwell_sim_nodes/nodes/outputs/file_exporters/data_file_exporter.py b/src/blender_maxwell/node_trees/maxwell_sim_nodes/nodes/outputs/file_exporters/data_file_exporter.py index d0bb299..892db69 100644 --- a/src/blender_maxwell/node_trees/maxwell_sim_nodes/nodes/outputs/file_exporters/data_file_exporter.py +++ b/src/blender_maxwell/node_trees/maxwell_sim_nodes/nodes/outputs/file_exporters/data_file_exporter.py @@ -66,7 +66,7 @@ class DataFileExporterNode(base.MaxwellSimNode): bl_label = 'Data File Importer' input_sockets: typ.ClassVar = { - 'Expr': sockets.ExprSocketDef(active_kind=ct.FlowKind.LazyValueFunc), + 'Expr': sockets.ExprSocketDef(active_kind=ct.FlowKind.Func), 'File Path': sockets.FilePathSocketDef(), } @@ -95,8 +95,8 @@ class DataFileExporterNode(base.MaxwellSimNode): @property def expr_data(self) -> typ.Any | None: - """Retrieve the input expression's data by evaluating its `LazyValueFunc`.""" - func = self._compute_input('Expr', kind=ct.FlowKind.LazyValueFunc) + """Retrieve the input expression's data by evaluating its `Func`.""" + func = self._compute_input('Expr', kind=ct.FlowKind.Func) params = self._compute_input('Expr', kind=ct.FlowKind.Params) has_func = not ct.FlowSignal.check(func) diff --git a/src/blender_maxwell/node_trees/maxwell_sim_nodes/nodes/sources/temporal_shape.py b/src/blender_maxwell/node_trees/maxwell_sim_nodes/nodes/sources/temporal_shape.py index 491f4f5..c9342da 100644 --- a/src/blender_maxwell/node_trees/maxwell_sim_nodes/nodes/sources/temporal_shape.py +++ b/src/blender_maxwell/node_trees/maxwell_sim_nodes/nodes/sources/temporal_shape.py @@ -133,7 +133,7 @@ class TemporalShapeNode(base.MaxwellSimNode): }, input_socket_kinds={ 't Range': ct.FlowKind.Range, - 'Envelope': ct.FlowKind.LazyValueFunc, + 'Envelope': ct.FlowKind.Func, }, input_sockets_optional={ 'max E': True, diff --git a/src/blender_maxwell/node_trees/maxwell_sim_nodes/sockets/base.py b/src/blender_maxwell/node_trees/maxwell_sim_nodes/sockets/base.py index 6a25982..7153df1 100644 --- a/src/blender_maxwell/node_trees/maxwell_sim_nodes/sockets/base.py +++ b/src/blender_maxwell/node_trees/maxwell_sim_nodes/sockets/base.py @@ -525,9 +525,9 @@ class MaxwellSimSocket(bpy.types.NodeSocket, bl_instance.BLInstance): msg = f'Socket {self.bl_label} {self.socket_type}): Tried to set "ct.FlowKind.Array", but socket does not define it' raise NotImplementedError(msg) - # LazyValueFunc + # Func @property - def lazy_value_func(self) -> ct.LazyValueFuncFlow: + def lazy_func(self) -> ct.FuncFlow: """Throws a descriptive error. Notes: @@ -538,8 +538,8 @@ class MaxwellSimSocket(bpy.types.NodeSocket, bl_instance.BLInstance): """ return ct.FlowSignal.NoFlow - @lazy_value_func.setter - def lazy_value_func(self, lazy_value_func: ct.LazyValueFuncFlow) -> None: + @lazy_func.setter + def lazy_func(self, lazy_func: ct.FuncFlow) -> None: """Throws a descriptive error. Notes: @@ -548,7 +548,7 @@ class MaxwellSimSocket(bpy.types.NodeSocket, bl_instance.BLInstance): Raises: NotImplementedError: When used without being overridden. """ - msg = f'Socket {self.bl_label} {self.socket_type}): Tried to set "ct.FlowKind.LazyValueFunc", but socket does not define it' + msg = f'Socket {self.bl_label} {self.socket_type}): Tried to set "ct.FlowKind.Func", but socket does not define it' raise NotImplementedError(msg) # Range @@ -595,7 +595,7 @@ class MaxwellSimSocket(bpy.types.NodeSocket, bl_instance.BLInstance): kind_data_map = { ct.FlowKind.Value: lambda: self.value, ct.FlowKind.Array: lambda: self.array, - ct.FlowKind.LazyValueFunc: lambda: self.lazy_value_func, + ct.FlowKind.Func: lambda: self.lazy_func, ct.FlowKind.Range: lambda: self.lazy_range, ct.FlowKind.Params: lambda: self.params, ct.FlowKind.Info: lambda: self.info, @@ -784,7 +784,7 @@ class MaxwellSimSocket(bpy.types.NodeSocket, bl_instance.BLInstance): ct.FlowKind.Value: self.draw_value, ct.FlowKind.Array: self.draw_array, ct.FlowKind.Range: self.draw_lazy_range, - ct.FlowKind.LazyValueFunc: self.draw_lazy_value_func, + ct.FlowKind.Func: self.draw_lazy_func, }[self.active_kind](col) # Info Drawing @@ -914,11 +914,11 @@ class MaxwellSimSocket(bpy.types.NodeSocket, bl_instance.BLInstance): col: Target for defining UI elements. """ - def draw_lazy_value_func(self, col: bpy.types.UILayout) -> None: + def draw_lazy_func(self, col: bpy.types.UILayout) -> None: """Draws the socket lazy value function UI on its own line. Notes: - Should be overriden by individual socket classes, if they have an editable `FlowKind.LazyValueFunc`. + Should be overriden by individual socket classes, if they have an editable `FlowKind.Func`. Parameters: col: Target for defining UI elements. diff --git a/src/blender_maxwell/node_trees/maxwell_sim_nodes/sockets/expr.py b/src/blender_maxwell/node_trees/maxwell_sim_nodes/sockets/expr.py index fa6bec7..e38dc41 100644 --- a/src/blender_maxwell/node_trees/maxwell_sim_nodes/sockets/expr.py +++ b/src/blender_maxwell/node_trees/maxwell_sim_nodes/sockets/expr.py @@ -100,7 +100,7 @@ class ExprBLSocket(base.MaxwellSimSocket): When active, `self.active_unit` can be used via the UI to select valid unit of the given `self.physical_type`, and `self.unit` works. The enum itself can be dynamically altered, ex. via its UI dropdown support. symbols: The symbolic variables valid in the context of the expression. - Various features, including `LazyValueFunc` support, become available when symbols are in use. + Various features, including `Func` support, become available when symbols are in use. The presence of symbols forces fallback to a string-based `sympy` expression UI. active_unit: The currently active unit, as a dropdown. @@ -544,20 +544,20 @@ class ExprBLSocket(base.MaxwellSimSocket): ] #################### - # - FlowKind: LazyValueFunc (w/Params if Constant) + # - FlowKind: Func (w/Params if Constant) #################### @property - def lazy_value_func(self) -> ct.LazyValueFuncFlow: + def lazy_func(self) -> ct.FuncFlow: """Returns a lazy value that computes the expression returned by `self.value`. - If `self.value` has unknown symbols (as indicated by `self.symbols`), then these will be the arguments of the `LazyValueFuncFlow`. + If `self.value` has unknown symbols (as indicated by `self.symbols`), then these will be the arguments of the `FuncFlow`. Otherwise, the returned lazy value function will be a simple excuse for `self.params` to pass the verbatim `self.value`. """ # Symbolic ## -> `self.value` is guaranteed to be an expression with unknowns. ## -> The function computes `self.value` with unknowns as arguments. if self.symbols: - return ct.LazyValueFuncFlow( + return ct.FuncFlow( func=sp.lambdify( self.sorted_symbols, spux.scale_to_unit(self.value, self.unit), @@ -572,7 +572,7 @@ class ExprBLSocket(base.MaxwellSimSocket): ## -> ("Dummy" as in returns the same argument that it takes). ## -> This is an excuse to let `ParamsFlow` pass `self.value` verbatim. ## -> Generally only useful for operations with other expressions. - return ct.LazyValueFuncFlow( + return ct.FuncFlow( func=lambda v: v, func_args=[ self.physical_type if self.physical_type is not None else self.mathtype @@ -582,7 +582,7 @@ class ExprBLSocket(base.MaxwellSimSocket): @property def params(self) -> ct.ParamsFlow: - """Returns parameter symbols/values to accompany `self.lazy_value_func`. + """Returns parameter symbols/values to accompany `self.lazy_func`. If `self.value` has unknown symbols (as indicated by `self.symbols`), then these will be passed into `ParamsFlow`, which will thus be parameterized (and require realization before use). Otherwise, `self.value` is passed verbatim as the only `ParamsFlow.func_arg`. @@ -605,13 +605,13 @@ class ExprBLSocket(base.MaxwellSimSocket): @property def info(self) -> ct.ArrayFlow: - r"""Returns parameter symbols/values to accompany `self.lazy_value_func`. + r"""Returns parameter symbols/values to accompany `self.lazy_func`. The output name/size/mathtype/unit corresponds directly the `ExprSocket`. If `self.symbols` has entries, then these will propagate as dimensions with unresolvable `RangeFlow` index descriptions. The index range will be $(-\infty,\infty)$, with $0$ steps and no unit. - The order/naming matches `self.params` and `self.lazy_value_func`. + The order/naming matches `self.params` and `self.lazy_func`. Otherwise, only the output name/size/mathtype/unit corresponding to the socket is passed along. """ @@ -835,13 +835,13 @@ class ExprBLSocket(base.MaxwellSimSocket): if self.steps != 0: col.prop(self, self.blfields['steps'], text='') - def draw_lazy_value_func(self, col: bpy.types.UILayout) -> None: + def draw_lazy_func(self, col: bpy.types.UILayout) -> None: """Draw the socket body for a single flexible value/expression, for down-chain lazy evaluation. This implements the most flexible variant of the `ExprSocket` UI, providing the user with full runtime-configuration of the exact `self.size`, `self.mathtype`, `self.physical_type`, and `self.symbols` of the expression. Notes: - Drawn when `self.active_kind == FlowKind.LazyValueFunc`. + Drawn when `self.active_kind == FlowKind.Func`. This is an ideal choice for ex. math nodes that need to accept arbitrary expressions as inputs, with an eye towards lazy evaluation of ex. symbolic terms. @@ -872,7 +872,7 @@ class ExprBLSocket(base.MaxwellSimSocket): # - UI: InfoFlow #################### def draw_info(self, info: ct.InfoFlow, col: bpy.types.UILayout) -> None: - if self.active_kind == ct.FlowKind.LazyValueFunc and self.show_info_columns: + if self.active_kind == ct.FlowKind.Func and self.show_info_columns: row = col.row() box = row.box() grid = box.grid_flow( @@ -927,7 +927,7 @@ class ExprSocketDef(base.SocketDef): ct.FlowKind.Value, ct.FlowKind.Range, ct.FlowKind.Array, - ct.FlowKind.LazyValueFunc, + ct.FlowKind.Func, ] = ct.FlowKind.Value # Socket Interface