- [x] Implement dropdown to choose which monitor in the SimulationData should be visualized (based on which are available in the SimulationData), and implement visualization based on every kind of monitor-adjascent output data type (<https://docs.flexcompute.com/projects/tidy3d/en/latest/api/output_data.html>)
- [ ] Project field values onto a plane object (managed)
- Spatial+frequency feature monitoring. An EM field can be decomposed into using a specially configured solver, which can be used to look for very particular kinds of effects by constraining investigations of a solver result to filter out everything that isn't these particular modes aka. features. Kind of a fourier-based redimensionalization, almost).
- [ ] Toggleable option to push-sync the simulation time duration to the scene end time (how to handle FPS vs time-step? Should we adjust the FPS such that there is one time step per frame, while keeping the definition of "second" aligned to the Blender unit system?)
- [ ] Implement switcher for API-key-having config filconfig file vs. direct entry of API key. It should be auto-filled with the config file when such a thing exists.
- [ ] Socket "guarding" - let nodes influence the dynamic capabilities of sockets to prevent links (with a `self.report` explanation) to an output socket that won't yet produce a value.
- [ ] Prevents some uses of loose sockets (we want less loose sockets!)
- [ ]`log.error` should invoke `self.report` in some Blender operator - used for errors that are due to usage error (which can't simply be prevented with UX design, like text file formatting of import), not due to error in the program.
- [x] Document the node tree cache semantics thoroughly; it's a VERY nuanced piece of logic, and its invariants may not survive Blender versions / the author's working memory
- Perhaps keep node / socket versions in a property, so that trying to load an incompatible major version hop can error w/indicator of where to find a compatible `blender_maxwell` version.
## Documentation
- [ ] Make all modules available
- [ ] Publish documentation site.
- [ ] Initial user guides w/pictures.
- [ ] Comb through and finish `__doc__`s.
## Performance
- [ ] The GN value pushing currently does an expensive from-sympy conversion for all GN attributes, making it very slow.
- Generally, the issue is that we can't compare the pushed value to the existing value without a conversion.
- Also, sympy expressions can't be hashed (by default), and `str()` may be just as slow, so a simple `@lru_cache` is no good.
- **One approach** is a `HashableSympyExpr` class, which would use ex. atoms and values in `SympyExpr` to let us `@lru_cache` the sympy conversion.
- **Another approach** is to "just" make the `scale_to_unit` function faster (we should profile).
- Presumably, the scaling factors between units could be eagerly cached, then the numerical part of the expression could be used to avoid `convert_to` calls.
- Without the list format of `(np.array, spu.Quantity)`, `sp.Matrix` can't be performantly handled like this.
- [ ] Implement image-based empty connected to an image (which is managed by a different ManagedImage owned by the same node instance)
- [ ] Implement ManagedVol
- [ ] Implement loading the xarray-defined voxels into OpenVDB, saving it, and loading it as a managed BL object with the volume setting.
- [ ] Implement basic jax-driven volume voxel processing, especially cube based slicing.
- [ ] Implement jax-driven linear interpolation of volume voxels to an image texture, whose pixels are sized according to the dimensions of another managed plane object (perhaps a uniquely described Managed BL object itself).
- [ ] Implement a new socket type for preview-only parameters
- [ ] When used, the node base class should expose a toggle
- [ ] Instead of mangling props, we can instead reuse all of the socket-based code, while also enabling composability of previews.
- [ ] Custom `@cache`/`@lru_cache`/`@cached_property` which caches by instance ID (possibly based on `beartype` or `pydantic`).
- The problem to solve is performance vs. persistence.
- [ ]
- [ ] Implement by-category sorting of loose sockets with 'move' method on `node.inputs`/`node.outputs`.
- Currently order is not guaranteed
- [ ] When presets are used, if a preset is selected and the user alters a preset setting, then dynamically switch the preset indicator back to "Custom" to indicate that there is no active preset
- [ ] ModeSpec, for use by ModeSource, ModeMonitor, ModeSolverMonitor. Data includes ModeSolverData, ModeData, ScalarModeFieldDataArray, ModeAmpsDataArray, ModeIndexDataArray, ModeSolver.
## Many Sockets
- [ ] Implement constrained SympyExpr checks all over the place.
- PR has been merged: <https://projects.blender.org/blender/blender/commit/14106150797a6ce35e006ffde18e78ea7ae67598> (for now, just use the "Combine" node and have seperate socket types for both).
- The `Combine` node has its own benefits, including previewability of "only structures". Multi-input would mainly be a kind of shorthand in specific cases (like input to the `Combine` node?)
- [ ] Popup to install dependencies after UI is available (possibly with the help of the `draw()` function of the `InstallPyDeps` operator)
- [ ] Use a Modal and multiline-text-like construction to print `pip install` as we install dependencies, so that the user has an idea that something is happening.
- [ ] Test lockfile platform-agnosticism on Windows
- [ ] Slow changing of socket sets / range on wave constant.
- [ ] API auth shouldn't show if everything is fine in Cloud Task socket
- [ ] Cloud task socket loads folders before its node shows, which can be slow (and error prone if offline)
- [ ] Dispersive fit is slow, which means lag on normal operations that rely on the fit result - fit computation should be integrated into the node, and the output socket should only appear when the fit is available.
- [ ] Numerical, Physical Constant is missing entries
- Directly running `SimulationTask.get()` is missing fields - it doesn't return some fields, including `created_at`. Listing tasks by folder is not broken.
We need Python properties to work together with Blender properties.
- Blender Pros: Altered via UI. Options control UI usage. `update()` is a perfect inflection point for callback logic.
- Blender Cons: Extremely limited supported types. A lot of manual labor that duplicates work done elsewhere in a Python program
`BLField` seeks to bridge the two worlds in an elegant way.
### Type Support
We need support for arbitrary objects, but still backed by the persistance semantics of native Blender properties.
- [ ] Add logic that matches appropriate types to native IntProperty, FloatProperty, IntVectorProperty, FloatVectorProperty.
- We want absolute minimal overhead for types that actually already do work in Blender.
- **REMEMBER8* they can do matrices too! https://developer.blender.org/docs/release_notes/3.0/python_api/#other-additions
- [ ] Add logic that matches any bpy.types.ID subclass to a PointerProperty.
- This is important for certain kinds of properties ex. "select a Blender object".
- [ ] Implement Enum property, (also see <https://developer.blender.org/docs/release_notes/4.1/python_api/#enum-id-properties>)
- Use this to bridge the enum UI to actual StrEnum objects.
- This also maybe enables some very interesting use cases when it comes to ex. static verifiability of data provided to event callbacks.
- [ ] Ensure certain options, namely `name` (as `ui_name`), `default`, `subtype`, (numeric) `min`, `max`, `step`, `precision`, (string) `maxlen`, `search`, and `search_options`, can be passed down via the `BLField()` constructor.
- [ ] Make a class method that parses the docstring.
- [ ]`description`: Use the docstring parser to extract the first description sentence of the attribute name from the subclass docstring, so we are both encouraged to document our nodes/sockets, and so we're not documenting twice.
### Niceness
- [ ] Rename the internal property to 'blfield__'.
- [ ] Add a method that extracts the internal property name, for places where we need the Blender property name.
- **Key use case**: `draw.prop(self, self.field_name._bl_prop_name)`, which is also nice b/c no implicit string-based reference.
- The work done above with types makes this as fast and useful as internal props. Just make sure we validate that the type can be usefully accessed like this.
- [ ] Add a field method (called w/instance) that updates min/max/etc. on the 'blfield__' prop, in a native property type compatible manner: https://developer.blender.org/docs/release_notes/3.0/python_api/#idproperty-ui-data-api
- Should also throw appropriate errors for invalid access from Python, while Blender handles access from the inside.
- This allows us
- [ ] Similarly, a field method that gets the 'blfield__' prop data as a dictionary.
- [x] Also make ENCODER a function that can shortcut the easy cases.
- [x] For serializeability, let the encoder/decoder be able to make use of an optional `.msgspec_encodable()` and similar decoder respectively, and add support for these in the ENCODER/DECODER functions.
- [x] Define a superclass for `SocketDef` and make everyone inherit from it