Compare commits

..

No commits in common. "uv-refactor" and "main" have entirely different histories.

331 changed files with 5631 additions and 7926 deletions

View File

@ -20,7 +20,7 @@ repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
# Ruff version.
rev: v0.6.8
rev: v0.4.3
hooks:
# ruff lint
#- id: ruff
@ -29,18 +29,8 @@ repos:
- id: ruff-format
- repo: https://github.com/commitizen-tools/commitizen
rev: v3.29.1
rev: master
hooks:
- id: commitizen
- id: commitizen-branch
stages: [push]
- repo: local
hooks:
- id: pytest
name: pytest
entry: ./.venv/bin/pytest tests
language: system
types: [python]
pass_filenames: false
always_run: true

52
FUTURE.md 100644
View File

@ -0,0 +1,52 @@
# Projects / Plugins
## Larger Architectural Changes
[ ] Dedicated way of generating properties for sockets and nodes, incl. helping make better (less boilerplatey) use of callbacks
- Perhaps, we should also go 100% custom `PropertyGroup`, to the point that we have `nodes`, `sockets` and `props`.
- This would allow far simplified sockets (the more complex kinds), and help standardize use of ex. units in node properties.
- Having a dedicated base class for custom props would help avoid issues like forgetting to run `self.sync_prop` on every goddamn update method in every goddamn socket.
[ ] Dedicated way of handling node-specific operators without all the boilerplate.
## Field Data
[ ] Directly dealing with field data, instead of having field manipulations be baked into viz node(s).
[ ] Yee Cell Data as Attributes on By-Cell Point Cloud w/GeoNodes Integrations
- In effect, when we have xarray data defined based on Yee Cells ex. Poynting vector coordinates, let's import this to Blender as a simple point cloud centered at each cell and grant each an attribute corresponding to the data.
- What we can then do is use vanilla GeoNodes to ex. read the vector attribute, and draw small arrow meshes (maybe resampled which auto-interpolates the field values) from each point, thus effectively visualizing . vector fields and many other fun things.
- Of course, this is no good for volume cell data - but we can just overlay the raw volume cell data as we please. We can also, if we're sneaky, deal with our volume data as points as far as we can, and then finally do a "points to volume" type deal to make it sufficiently "fluffy/cloudy".
- I wonder if we could use the Attribute node in the shader editor to project interpolated values from points, onto a ex. plane mesh, in a way that would also be visualizable in the viewport.
## Tidy3D Features
[ ] Symmetry for Performance
- [ ] Implement <https://docs.flexcompute.com/projects/tidy3d/en/latest/notebooks/Symmetry.html>
[ ] Dispersive Model Fitting
[ ] Scattering Matrix Calculator
[ ] Resonance Finder
[ ] Adjoint Optimization
[ ] Design Space Exploration / Parameterization
## Preview Semantics
[ ] Node tree header toggle that toggles a modal operator on and off, which constantly checks the context of the selected nodes, and tries to `bl_select` them (which in turn, should cause the node base class to `bl_select` shit inside).
- Shouldn't survive a file save; always startup with this thing off.
[ ] Custom gizmos attached to preview toggles!
- There is a WIP for GN-driven gizmos: <https://projects.blender.org/blender/blender/pulls/112677>
- Probably best to wait for that, then just add gizmos to existing driven GN trees, as opposed to unholy OGL spaghetti.
[ ] Node-ManagedObj Selection binding
- BL to Node:
- Trigger: The post-depsgraph handler seems appropriate.
- Input: Read the object location (origin), using a unit system.
- Output: Write the input socket value.
- Condition: Input socket is unlinked. (If it's linked, then lock the object's position. Use sync_link_added() for that)
- Node to BL:
- Trigger: "Report" event on an input socket that the managed object declares reliance on.
- Input: The input socket value (linked or unlinked)
- Output: The object location (origin), using a unit system.
## Parametric Geometry UX
[ ] Consider allowing a mesh attribute (set in ex. geometry node) to specify the name of a medium.
- This allows assembling complex multi-medium structures in one geonodes tree.
- This should result in the spawning of several Medium input sockets in the GeoNodes structure node, named as the attributes are.
- The GeoNodes structure node should then output as array-like TriMeshes, for which mediums are correctly defined.
## Alternative Engines
[ ] Heat Solver
[ ] MEEP integration (<https://meep.readthedocs.io/en/latest/>)
- The main boost would be if we could setup a MEEP simulation entirely from a td.Simulation object.

View File

@ -1,5 +1,5 @@
oscillode
Copyright (C) 2024 oscillode Project Contributors
blender_maxwell
Copyright (C) 2024 blender_maxwell Project Contributors
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by

0
TODO.md 100644
View File

View File

@ -1,101 +0,0 @@
# oscillode
# Copyright (C) 2024 oscillode Project Contributors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
"""A visual DSL for electromagnetic simulation design and analysis implemented as a Blender node editor."""
from functools import reduce
from . import contracts as ct
# from . import node_trees
from . import operators, preferences, registration
from .utils import logger
log = logger.get(__name__)
####################
# - Load and Register Addon
####################
BL_REGISTER: list[ct.BLClass] = [
*operators.BL_REGISTER,
# *node_trees.BL_REGISTER,
]
BL_HANDLERS: ct.BLHandlers = reduce(
lambda a, b: a + b,
[
operators.BL_HANDLERS,
# node_trees.BL_HANDLERS,
],
ct.BLHandlers(),
)
BL_KEYMAP_ITEMS: list[ct.BLKeymapItem] = [
*operators.BL_KEYMAP_ITEMS,
# node_trees.BL_KEYMAP_ITEMS,
]
####################
# - Registration
####################
def register() -> None:
"""Implements addon registration in a way that respects the availability of addon preferences and loggers.
Notes:
Called by Blender when enabling the addon.
Raises:
RuntimeError: If addon preferences fail to register.
"""
log.info('Registering Addon Preferences: %s', ct.addon.NAME)
registration.register_classes(preferences.BL_REGISTER)
addon_prefs = ct.addon.prefs()
if addon_prefs is not None:
# Update Loggers
# - This updates existing loggers to use settings defined by preferences.
addon_prefs.on_addon_logging_changed()
log.info('Registering Addon: %s', ct.addon.NAME)
registration.register_classes(BL_REGISTER)
registration.register_handlers(BL_HANDLERS)
registration.register_keymaps(BL_KEYMAP_ITEMS)
log.info('Finished Registration of Addon: %s', ct.addon.NAME)
else:
msg = 'Addon preferences did not register for addon {ct.addon.NAME} - something is very wrong!'
raise RuntimeError(msg)
def unregister() -> None:
"""Unregisters anything that was registered by the addon.
Notes:
Run by Blender when disabling and/or uninstalling the addon.
This doesn't clean `sys.modules`.
We rely on the hope that Blender has extension-extension module isolation.
"""
log.info('Starting %s Unregister', ct.addon.NAME)
registration.unregister_keymaps()
registration.unregister_handlers()
registration.unregister_classes()
log.info('Finished %s Unregister', ct.addon.NAME)

Binary file not shown.

BIN
oscillode/assets/primitives/arrow.blend (Stored with Git LFS)

Binary file not shown.

View File

@ -1,102 +0,0 @@
# oscillode
# Copyright (C) 2024 oscillode Project Contributors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
"""Basic 'single-source-of-truth' static and dynamic information about this addon.
Information is mined both from `bpy`, and from the addon's bundled manifest file.
"""
import os
import tomllib
import typing as typ
from pathlib import Path
import bpy
PATH_ADDON_ROOT = Path(__file__).resolve().parent.parent
PATH_MANIFEST = PATH_ADDON_ROOT / 'blender_manifest.toml'
with PATH_MANIFEST.open('rb') as f:
MANIFEST = tomllib.load(f)
NAME: str = MANIFEST['id']
VERSION: str = MANIFEST['version']
####################
# - Assets
####################
PATH_ASSETS: Path = PATH_ADDON_ROOT / 'assets'
if 'RUNNING_BLEXT_TESTS' in os.environ:
PATH_CACHE: Path = (
PATH_ADDON_ROOT.parent / 'dev' / 'local'
) ## TODO: Consult init_settings
else:
PATH_CACHE: Path = Path(bpy.utils.extension_path_user(__package__, create=True)) # type: ignore[no-redef]
####################
# - Dynamic Addon Information
####################
def operator(
name: str, *operator_args: list[typ.Any], **operator_kwargs: dict[str, typ.Any]
) -> None:
"""Convenienve method to call an operator from this addon.
This avoids having to use `bpy.ops.<addon_name>.operator_name`, which isn't generic.
Only operators from this addon may be called using this method.
Raises:
ValueError: If an addon from outside this operator is attempted to be used.
"""
# Parse Operator Name
operator_namespace, operator_name = name.split('.')
if operator_namespace != NAME:
msg = f'Tried to call operator {operator_name}, but addon operators may only use the addon operator namespace "{operator_namespace}.<name>"'
raise ValueError(msg)
# Run Operator
bl_operator = getattr(getattr(bpy.ops, NAME), operator_name)
bl_operator(*operator_args, **operator_kwargs)
## TODO: Can't we constrain 'name' to be an OperatorType somehow?
def prefs() -> bpy.types.AddonPreferences | None:
"""Retrieve the preferences of this addon, if they are available yet.
Notes:
While registering the addon, one may wish to use the addon preferences.
This isn't possible - not even for default values.
Either a bad idea is at work, or `oscillode.utils.init_settings` should be consulted until the preferences are available.
Returns:
The addon preferences, if the addon is registered and loaded - otherwise None.
"""
addon = bpy.context.preferences.addons.get(NAME)
if addon is None:
return None
return addon.preferences
####################
# - Logging Info
####################
DEFAULT_LOG_PATH = PATH_ADDON_ROOT / 'addon.log'
## By default, the addon file log writes to the addon dir.
## The initial .log_level contents are written when packing the .zip.
## Subsequent changes are managed by nodeps.utils.simple_logger.py.

View File

@ -1,125 +0,0 @@
# oscillode
# Copyright (C) 2024 oscillode Project Contributors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
"""Declares types for working with `bpy.app.handlers` callbacks."""
import typing as typ
import bpy
import pydantic as pyd
from oscillode.utils.staticproperty import staticproperty
BLHandler = typ.Callable[[], None]
BLHandlerWithFile = typ.Callable[[str], None]
BLHandlerWithRenderStats = typ.Callable[[typ.Any], None]
class BLHandlers(pyd.BaseModel):
"""Contains lists of handlers associated with this addon."""
animation_playback_post: tuple[BLHandler, ...] = ()
animation_playback_pre: tuple[BLHandler, ...] = ()
annotation_post: tuple[BLHandler, ...] = ()
annotation_pre: tuple[BLHandler, ...] = ()
composite_cancel: tuple[BLHandler, ...] = ()
composite_post: tuple[BLHandler, ...] = ()
composite_pre: tuple[BLHandler, ...] = ()
depsgraph_update_post: tuple[BLHandler, ...] = ()
depsgraph_update_pre: tuple[BLHandler, ...] = ()
frame_change_post: tuple[BLHandler, ...] = ()
frame_change_pre: tuple[BLHandler, ...] = ()
load_factory_preferences_post: tuple[BLHandler, ...] = ()
load_factory_startup_post: tuple[BLHandler, ...] = ()
load_post: tuple[BLHandlerWithFile, ...] = ()
load_post_fail: tuple[BLHandlerWithFile, ...] = ()
load_pre: tuple[BLHandlerWithFile, ...] = ()
object_bake_cancel: tuple[BLHandler, ...] = ()
object_bake_complete: tuple[BLHandler, ...] = ()
object_bake_pre: tuple[BLHandler, ...] = ()
redo_post: tuple[BLHandler, ...] = ()
redo_pre: tuple[BLHandler, ...] = ()
render_cancel: tuple[BLHandler, ...] = ()
render_complete: tuple[BLHandler, ...] = ()
render_init: tuple[BLHandler, ...] = ()
render_post: tuple[BLHandler, ...] = ()
render_pre: tuple[BLHandler, ...] = ()
render_stats: tuple[BLHandler, ...] = ()
## TODO: Verify these type signatures.
## TODO: A validator to check that all handlers are decorated with bpy.app.handlers.persistent
####################
# - Properties
####################
@staticproperty # type: ignore[arg-type]
def handler_categories() -> tuple[str, ...]: # type: ignore[misc]
"""Returns an immutable string sequence of handler categories."""
return (
'animation_playback_post',
'animation_playback_pre',
'annotation_post',
'annotation_pre',
'composite_cancel',
'composite_post',
'composite_pre',
'depsgraph_update_post',
'depsgraph_update_pre',
'frame_change_post',
'frame_change_pre',
'load_factory_preferences_post',
'load_factory_startup_post',
'load_post',
'load_post_fail',
'load_pre',
'object_bake_cancel',
'object_bake_complete',
'object_bake_pre',
'redo_post',
'redo_pre',
'render_cancel',
'render_complete',
'render_init',
'render_post',
'render_pre',
'render_stats',
)
####################
# - Merging
####################
def __add__(self, other: typ.Self) -> typ.Self:
"""Concatenate the handlers of two `BLHandlers` objects."""
return BLHandlers(
**{
hndl_cat: getattr(self, hndl_cat) + getattr(self, hndl_cat)
for hndl_cat in self.handler_categories
}
)
def register(self) -> None:
"""Registers all handlers declared by-category."""
for handler_category in BLHandlers.handler_categories:
for handler in getattr(self, handler_category):
getattr(bpy.app.handlers, handler_category).append(handler)
def unregister(self) -> None:
"""Unregisters only this addon's handlers from bpy.app.handlers."""
for handler_category in BLHandlers.handler_categories:
for handler in getattr(self, handler_category):
bpy_handlers = getattr(bpy.app.handlers, handler_category)
if handler in bpy_handlers:
bpy_handlers.remove(handler)

View File

@ -1,60 +0,0 @@
# oscillode
# Copyright (C) 2024 oscillode Project Contributors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
"""Declares types for working with `bpy.types.KeyMap`s."""
import bpy
import pydantic as pyd
from .bl import BLEventType, BLEventValue, BLSpaceType
from .operator_types import OperatorType
class BLKeymapItem(pyd.BaseModel):
"""Contains lists of handlers associated with this addon."""
operator: OperatorType
event_type: BLEventType
event_value: BLEventValue
shift: bool = False
ctrl: bool = False
alt: bool = False
key_modifier: BLEventType = 'NONE'
space_type: BLSpaceType = 'EMPTY'
def register(self, addon_keymap: bpy.types.KeyMap) -> bpy.types.KeyMapItem:
"""Registers this hotkey with an addon keymap.
Raises:
ValueError: If the `space_type` constraint of the addon keymap does not match the `space_type` constraint of this `BLKeymapItem`.
"""
if self.space_type == addon_keymap.space_type:
addon_keymap.keymap_items.new(
self.operator,
self.event_type,
self.event_value,
shift=self.shift,
ctrl=self.ctrl,
alt=self.alt,
key_modifier=self.key_modifier,
)
msg = f'Addon keymap space type {addon_keymap.space_type} does not match space_type of BLKeymapItem to register: {self}'
raise ValueError(msg)
## TODO: Check if space_type matches?

View File

@ -1,125 +0,0 @@
# oscillode
# Copyright (C) 2024 oscillode Project Contributors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
"""Provides the base protocol on which all ManagedObjs are derived, as well as explicit protocols describing common features supported by some `ManagedObjs`."""
import abc
import typing as typ
from blender_maxwell.utils import logger, serialize
from .. import contracts as ct
log = logger.get(__name__)
class ManagedObj(typ.Protocol):
"""A weak name-based reference to some kind of object external to this software.
While the object doesn't have to come from Blender's `bpy.types`, that is the driving motivation for this class: To encapsulate access to the powerful visual tools granted by Blender's 3D viewport, image editor, and UI.
Through extensive trial-and-error, this transparently-cached immediate-mode interface has emerged as the best compromise.
While not suited to all use cases, the `ManagedObj` paradigm is ideal for the common situation of 'node ownership of external logic'.
For example, a plotting node needs access to its own image buffer; however, for it to be displayable, that image buffer must be owned by Blender.
This is where `ManagedObj` provides the ability of the plotting node to "loosely own" a particular Blender image, which both allows the user to see/interact with the image as a typical Blender image, but also allows the node to drive ex. lifecycle (like removing the image plot when the node is deleted).
This approach of loose name-coupling is not perfect. To name a few examples:
- A particular challenge is that of identifying and namespacing managed datablocks. The user may, for example, change the name of an object - and what do we do then? Is generating new data under the now-vacant name a feature? Or is it a systematic memory leak backed by dangling fake-owned datablocks?
- The precise definition of "loose ownership" is itself a matter of taste. Stronger ownership presumptions allow for stronger guarantees and simpler caching - but at the cost of more brittle breaks when the underlying objects are manipulated in ways we don't expect.
- `.blend` persistance is not the default when it comes to certain Blender objects, which raises deeper UX questions about how opinionated we should be about where users put data.
- Solving this doesn't help actually deal with data. There's a lot of very specific nuance in every single data pipeline, and that complexity is only added to watever this approach incurs.
This abstract base class serves to provide a few of the most basic of commonly-available operations.
In particular, implementations of `dump_as_msgspec`/`parse_as_msgspec` are enforced, for use with `oscillode.utils.serialize`.
This way, ex. opening a `.blend` file will allow a newly-deserialized `ManagedObj` to re-attach transparently to the also-persisted underlying datablock.
Parameters:
managed_obj_type: Enum identifier indicating which of the `ct.ManagedObjType` the instance should declare itself as.
"""
managed_obj_type: ct.ManagedObjType
@abc.abstractmethod
def __init__(self, name: ct.ManagedObjName, prev_name: str | None = None):
"""Initializes the managed object with a unique name.
Use `prev_name` to indicate that the managed object will initially be avaiable under `prev_name`, but that it should be renamed to `name`.
"""
####################
# - Properties
####################
@property
@abc.abstractmethod
def name(self) -> str:
"""Retrieve the name of the managed object."""
@name.setter
@abc.abstractmethod
def name(self, value: str) -> None:
"""Retrieve the name of the managed object."""
####################
# - Methods
####################
@abc.abstractmethod
def free(self) -> None:
"""Cleanup the resources managed by the managed object."""
@abc.abstractmethod
def hide_preview(self) -> None:
"""Hide any active preview of the managed object, if it exists, and if such an operation makes sense."""
####################
# - Serialization
####################
def dump_as_msgspec(self) -> serialize.NaiveRepresentation:
"""Bijectively transform this managed object into a 'naive representation' that uses only basic Python types, which may be serialized cleanly."""
return [
serialize.TypeID.ManagedObj,
self.__class__.__name__,
self.name,
]
@staticmethod
def parse_as_msgspec(obj: serialize.NaiveRepresentation) -> typ.Self:
"""Bijectively construct an instance of this managed object from the 'naive representation', which may have been deserialized into."""
return next(
subclass(obj[2])
for subclass in ManagedObj.__subclasses__()
if subclass.__name__ == obj[1]
)
####################
# - Support Flags
####################
class SupportsBlenderSelect(typ.Protocol):
"""Protocol guaranteeing the ability to select the object in Blender."""
def bl_select(self) -> None:
"""Select the managed object in Blender."""
class Supportsreview(typ.Protocol):
"""Protocol guaranteeing support for previewing the object."""
def show_preview(self) -> None:
"""Shows a preview of the managed object."""
def hide_preview(self) -> None:
"""Hide any active preview of the managed object, if it exists."""

View File

@ -1,37 +0,0 @@
# oscillode
# Copyright (C) 2024 oscillode Project Contributors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# blender_maxwell
# Copyright (C) 2024 blender_maxwell Project Contributors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from . import maxwell_sim_nodes
BL_REGISTER = [
*maxwell_sim_nodes.BL_REGISTER,
]

View File

@ -1,40 +0,0 @@
# oscillode
# Copyright (C) 2024 oscillode Project Contributors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# blender_maxwell
# Copyright (C) 2024 blender_maxwell Project Contributors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from . import categories, node_tree, nodes, sockets
BL_REGISTER = [
*sockets.BL_REGISTER,
*node_tree.BL_REGISTER,
*nodes.BL_REGISTER,
*categories.BL_REGISTER,
]

View File

@ -1,44 +0,0 @@
# oscillode
# Copyright (C) 2024 oscillode Project Contributors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# blender_maxwell
# Copyright (C) 2024 blender_maxwell Project Contributors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from . import extract_data, math, viz
BL_REGISTER = [
*extract_data.BL_REGISTER,
*viz.BL_REGISTER,
*math.BL_REGISTER,
]
BL_NODES = {
**extract_data.BL_NODES,
**viz.BL_NODES,
**math.BL_NODES,
}

View File

@ -1,51 +0,0 @@
# oscillode
# Copyright (C) 2024 oscillode Project Contributors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# blender_maxwell
# Copyright (C) 2024 blender_maxwell Project Contributors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from . import (
constants,
file_importers,
scene,
web_importers,
)
BL_REGISTER = [
*constants.BL_REGISTER,
*web_importers.BL_REGISTER,
*file_importers.BL_REGISTER,
*scene.BL_REGISTER,
]
BL_NODES = {
**scene.BL_NODES,
**constants.BL_NODES,
**web_importers.BL_NODES,
**file_importers.BL_NODES,
}

View File

@ -1,42 +0,0 @@
# oscillode
# Copyright (C) 2024 oscillode Project Contributors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# blender_maxwell
# Copyright (C) 2024 blender_maxwell Project Contributors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from . import data_file_importer, tidy_3d_file_importer
BL_REGISTER = [
*data_file_importer.BL_REGISTER,
*tidy_3d_file_importer.BL_REGISTER,
]
BL_NODES = {
**data_file_importer.BL_NODES,
**tidy_3d_file_importer.BL_NODES,
}

View File

@ -1,40 +0,0 @@
# oscillode
# Copyright (C) 2024 oscillode Project Contributors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# blender_maxwell
# Copyright (C) 2024 blender_maxwell Project Contributors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from . import tidy3d_web_importer
BL_REGISTER = [
*tidy3d_web_importer.BL_REGISTER,
]
BL_NODES = {
**tidy3d_web_importer.BL_NODES,
}

View File

@ -1,37 +0,0 @@
# oscillode
# Copyright (C) 2024 oscillode Project Contributors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# blender_maxwell
# Copyright (C) 2024 blender_maxwell Project Contributors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
####################
# - Blender Registration
####################
BL_REGISTER = []
BL_NODES = {}

View File

@ -1,37 +0,0 @@
# oscillode
# Copyright (C) 2024 oscillode Project Contributors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# blender_maxwell
# Copyright (C) 2024 blender_maxwell Project Contributors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
####################
# - Blender Registration
####################
BL_REGISTER = []
BL_NODES = {}

View File

@ -1,37 +0,0 @@
# oscillode
# Copyright (C) 2024 oscillode Project Contributors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# blender_maxwell
# Copyright (C) 2024 blender_maxwell Project Contributors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
####################
# - Blender Registration
####################
BL_REGISTER = []
BL_NODES = {}

View File

@ -1,37 +0,0 @@
# oscillode
# Copyright (C) 2024 oscillode Project Contributors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# blender_maxwell
# Copyright (C) 2024 blender_maxwell Project Contributors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
####################
# - Blender Registration
####################
BL_REGISTER = []
BL_NODES = {}

View File

@ -1,37 +0,0 @@
# oscillode
# Copyright (C) 2024 oscillode Project Contributors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# blender_maxwell
# Copyright (C) 2024 blender_maxwell Project Contributors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
####################
# - Blender Registration
####################
BL_REGISTER = []
BL_NODES = {}

View File

@ -1,37 +0,0 @@
# oscillode
# Copyright (C) 2024 oscillode Project Contributors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# blender_maxwell
# Copyright (C) 2024 blender_maxwell Project Contributors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
####################
# - Blender Registration
####################
BL_REGISTER = []
BL_NODES = {}

View File

@ -1,37 +0,0 @@
# oscillode
# Copyright (C) 2024 oscillode Project Contributors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# blender_maxwell
# Copyright (C) 2024 blender_maxwell Project Contributors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
####################
# - Blender Registration
####################
BL_REGISTER = []
BL_NODES = {}

View File

@ -1,37 +0,0 @@
# oscillode
# Copyright (C) 2024 oscillode Project Contributors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# blender_maxwell
# Copyright (C) 2024 blender_maxwell Project Contributors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
####################
# - Blender Registration
####################
BL_REGISTER = []
BL_NODES = {}

View File

@ -1,44 +0,0 @@
# oscillode
# Copyright (C) 2024 oscillode Project Contributors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# blender_maxwell
# Copyright (C) 2024 blender_maxwell Project Contributors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from . import file_exporters, viewer, web_exporters
BL_REGISTER = [
*viewer.BL_REGISTER,
*file_exporters.BL_REGISTER,
*web_exporters.BL_REGISTER,
]
BL_NODES = {
**viewer.BL_NODES,
**file_exporters.BL_NODES,
**web_exporters.BL_NODES,
}

View File

@ -1,44 +0,0 @@
# oscillode
# Copyright (C) 2024 oscillode Project Contributors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# blender_maxwell
# Copyright (C) 2024 blender_maxwell Project Contributors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from . import data_file_exporter
# from . import json_file_exporter
BL_REGISTER = [
*data_file_exporter.BL_REGISTER,
# *json_file_exporter.BL_REGISTER,
]
BL_NODES = {
**data_file_exporter.BL_NODES,
# **json_file_exporter.BL_NODES,
}

View File

@ -1,40 +0,0 @@
# oscillode
# Copyright (C) 2024 oscillode Project Contributors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# blender_maxwell
# Copyright (C) 2024 blender_maxwell Project Contributors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from . import tidy3d_web_exporter
BL_REGISTER = [
*tidy3d_web_exporter.BL_REGISTER,
]
BL_NODES = {
**tidy3d_web_exporter.BL_NODES,
}

View File

@ -1,43 +0,0 @@
# oscillode
# Copyright (C) 2024 oscillode Project Contributors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# blender_maxwell
# Copyright (C) 2024 blender_maxwell Project Contributors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import typing as typ
import pydantic as pyd
from .. import contracts as ct
class PresetDef(pyd.BaseModel):
label: ct.PresetName
description: str
values: dict[ct.SocketName, typ.Any]

View File

@ -1,48 +0,0 @@
# oscillode
# Copyright (C) 2024 oscillode Project Contributors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# blender_maxwell
# Copyright (C) 2024 blender_maxwell Project Contributors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from . import (
absorbing_bound_cond,
bloch_bound_cond,
pml_bound_cond,
)
BL_REGISTER = [
*pml_bound_cond.BL_REGISTER,
*bloch_bound_cond.BL_REGISTER,
*absorbing_bound_cond.BL_REGISTER,
]
BL_NODES = {
**pml_bound_cond.BL_NODES,
**bloch_bound_cond.BL_NODES,
**absorbing_bound_cond.BL_NODES,
}

View File

@ -1,37 +0,0 @@
# oscillode
# Copyright (C) 2024 oscillode Project Contributors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# blender_maxwell
# Copyright (C) 2024 blender_maxwell Project Contributors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
####################
# - Blender Registration
####################
BL_REGISTER = []
BL_NODES = {}

View File

@ -1,37 +0,0 @@
# oscillode
# Copyright (C) 2024 oscillode Project Contributors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# blender_maxwell
# Copyright (C) 2024 blender_maxwell Project Contributors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
####################
# - Blender Registration
####################
BL_REGISTER = []
BL_NODES = {}

View File

@ -1,48 +0,0 @@
# oscillode
# Copyright (C) 2024 oscillode Project Contributors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# blender_maxwell
# Copyright (C) 2024 blender_maxwell Project Contributors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from . import (
eme_solver,
fdtd_solver,
mode_solver,
)
BL_REGISTER = [
*fdtd_solver.BL_REGISTER,
*mode_solver.BL_REGISTER,
*eme_solver.BL_REGISTER,
]
BL_NODES = {
**fdtd_solver.BL_NODES,
**mode_solver.BL_NODES,
**eme_solver.BL_NODES,
}

View File

@ -1,34 +0,0 @@
# oscillode
# Copyright (C) 2024 oscillode Project Contributors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# blender_maxwell
# Copyright (C) 2024 blender_maxwell Project Contributors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
BL_REGISTER = []
BL_NODES = {}

View File

@ -1,37 +0,0 @@
# oscillode
# Copyright (C) 2024 oscillode Project Contributors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# blender_maxwell
# Copyright (C) 2024 blender_maxwell Project Contributors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
####################
# - Blender Registration
####################
BL_REGISTER = []
BL_NODES = {}

View File

@ -1,37 +0,0 @@
# oscillode
# Copyright (C) 2024 oscillode Project Contributors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# blender_maxwell
# Copyright (C) 2024 blender_maxwell Project Contributors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
####################
# - Blender Registration
####################
BL_REGISTER = []
BL_NODES = {}

View File

@ -1,37 +0,0 @@
# oscillode
# Copyright (C) 2024 oscillode Project Contributors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# blender_maxwell
# Copyright (C) 2024 blender_maxwell Project Contributors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
####################
# - Blender Registration
####################
BL_REGISTER = []
BL_NODES = {}

View File

@ -1,37 +0,0 @@
# oscillode
# Copyright (C) 2024 oscillode Project Contributors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# blender_maxwell
# Copyright (C) 2024 blender_maxwell Project Contributors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
####################
# - Blender Registration
####################
BL_REGISTER = []
BL_NODES = {}

View File

@ -1,37 +0,0 @@
# oscillode
# Copyright (C) 2024 oscillode Project Contributors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# blender_maxwell
# Copyright (C) 2024 blender_maxwell Project Contributors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
####################
# - Blender Registration
####################
BL_REGISTER = []
BL_NODES = {}

View File

@ -1,45 +0,0 @@
# oscillode
# Copyright (C) 2024 oscillode Project Contributors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# blender_maxwell
# Copyright (C) 2024 blender_maxwell Project Contributors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# from . import object_structure
from . import geonodes_structure, primitives
BL_REGISTER = [
# *object_structure.BL_REGISTER,
*geonodes_structure.BL_REGISTER,
*primitives.BL_REGISTER,
]
BL_NODES = {
# **object_structure.BL_NODES,
**geonodes_structure.BL_NODES,
**primitives.BL_NODES,
}

View File

@ -1,44 +0,0 @@
# oscillode
# Copyright (C) 2024 oscillode Project Contributors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# blender_maxwell
# Copyright (C) 2024 blender_maxwell Project Contributors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from . import box_structure, cylinder_structure, sphere_structure
BL_REGISTER = [
*box_structure.BL_REGISTER,
*cylinder_structure.BL_REGISTER,
*sphere_structure.BL_REGISTER,
]
BL_NODES = {
**box_structure.BL_NODES,
**cylinder_structure.BL_NODES,
**sphere_structure.BL_NODES,
}

View File

@ -1,37 +0,0 @@
# oscillode
# Copyright (C) 2024 oscillode Project Contributors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# blender_maxwell
# Copyright (C) 2024 blender_maxwell Project Contributors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
####################
# - Blender Registration
####################
BL_REGISTER = []
BL_NODES = {}

View File

@ -1,44 +0,0 @@
# oscillode
# Copyright (C) 2024 oscillode Project Contributors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# blender_maxwell
# Copyright (C) 2024 blender_maxwell Project Contributors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from . import combine, view_text, wave_constant
BL_REGISTER = [
*wave_constant.BL_REGISTER,
*combine.BL_REGISTER,
*view_text.BL_REGISTER,
]
BL_NODES = {
**wave_constant.BL_NODES,
**combine.BL_NODES,
**view_text.BL_NODES,
}

View File

@ -1,41 +0,0 @@
# oscillode
# Copyright (C) 2024 oscillode Project Contributors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# blender_maxwell
# Copyright (C) 2024 blender_maxwell Project Contributors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from . import pol # , unit_system
PhysicalPolSocketDef = pol.PhysicalPolSocketDef
BL_REGISTER = [
# *unit_system.BL_REGISTER,
*pol.BL_REGISTER,
]

View File

@ -1,40 +0,0 @@
# oscillode
# Copyright (C) 2024 oscillode Project Contributors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# blender_maxwell
# Copyright (C) 2024 blender_maxwell Project Contributors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from . import cloud_task
Tidy3DCloudTaskSocketDef = cloud_task.Tidy3DCloudTaskSocketDef
BL_REGISTER = [
*cloud_task.BL_REGISTER,
]

View File

@ -1,37 +0,0 @@
# oscillode
# Copyright (C) 2024 oscillode Project Contributors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
"""Blender operators that ship with Oscillode."""
from functools import reduce
from oscillode import contracts as ct
from . import connect_viewer
BL_REGISTER: list[ct.BLClass] = [
*connect_viewer.BL_REGISTER,
]
BL_HANDLERS: ct.BLHandlers = reduce(
lambda a, b: a + b,
[
*connect_viewer.BL_HANDLERS,
],
ct.BLHandlers(),
)
BL_KEYMAP_ITEMS: list[ct.BLKeymapItem] = [
*connect_viewer.BL_KEYMAP_ITEMS,
]

View File

@ -1,130 +0,0 @@
# oscillode
# Copyright (C) 2024 oscillode Project Contributors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
"""Operator allowing the user to use the conventional CTRL+SHIFT+LMB to connect arbitrary node outputs to either an existing, or a new, viewer node."""
import bpy
from oscillode import contracts as ct
from oscillode.utils import logger
log = logger.get(__name__)
class ConnectViewerNode(bpy.types.Operator):
"""Connecting the viewer node to the active node in a Maxwell Sim node tree, as defined by selection and mouse-cursor location.
If there is no active viewer node, then one is created.
"""
bl_idname = ct.OperatorType.ConnectViewerNode
bl_label = 'Connect Viewer to Active'
bl_description = 'Connect active node to Viewer Node'
bl_options = frozenset({'REGISTER', 'UNDO'})
@classmethod
def poll(cls, context: bpy.types.Context) -> bool:
"""Require the active space to be a Maxwell Sim node tree defined by this addon.
Notes:
Run by Blender when determining whether the operator can run.
Returns:
Whether the operator can run.
"""
space = context.space_data
return (
space.type == 'NODE_EDITOR'
and space.node_tree is not None
and space.node_tree.bl_idname == ct.NodeTreeType.MaxwellSim
)
def invoke(
self, context: bpy.types.Context, event: bpy.types.Event
) -> ct.BLOperatorStatus:
"""Require the active space to be a particular node tree defined by this addon.
Notes:
Run by Blender when determining whether the operator can run.
Returns:
Whether the operator can run.
"""
node_tree = context.space_data.node_tree
# Retrieve Mouse Location
mlocx = event.mouse_region_x
mlocy = event.mouse_region_y
# Select Node at Location
## - Deselect all other nodes.
bpy.ops.node.select(
extend=False,
location=(mlocx, mlocy),
)
selected_node = context.selected_nodes[0]
# Find Viewer Node...
viewer_node_type = node_tree.viewer_node_type
for node in node_tree.nodes:
# TODO: Support multiple viewer nodes.
if hasattr(node, 'node_type') and node.node_type is viewer_node_type:
viewer_node = node
break
# ...OR: Create Viewer Node
else:
# TODO: Place viewer where it doesn't overlap other nodes.
viewer_node = node_tree.nodes.new(viewer_node_type)
viewer_node.location.x = selected_node.location.x + 250
viewer_node.location.y = selected_node.location.y
selected_node.select = False
# Remove Input Links from Viewer
## - Unless the selected node is already linked to the viewer.
should_create_new_link = True
for link in viewer_node.inputs[0].links:
if link.from_node.name == selected_node.name:
should_create_new_link = False
continue
node_tree.links.remove(link)
# Create Link from Selected Node to Viewer
if should_create_new_link:
node_tree.links.new(selected_node.outputs[0], viewer_node.inputs[0])
return {'FINISHED'}
####################
# - Blender Registration
####################
BL_REGISTER: list[ct.BLClass] = [
ConnectViewerNode,
]
BL_HANDLERS: ct.BLHandlers = ct.BLHandlers()
BL_KEYMAP_ITEMS: list[ct.BLKeymapItem] = [
ct.BLKeymapItem(
operator=ct.OperatorType.ConnectViewerNode,
event_type='LEFTMOUSE',
event_value='PRESS',
ctrl=True,
shift=True,
space_type='NODE_EDITOR',
)
]

View File

@ -1,210 +0,0 @@
# oscillode
# Copyright (C) 2024 oscillode Project Contributors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
"""Addon preferences, encapsulating the various global modifications that the user may make to how this addon functions."""
import logging
from pathlib import Path
import bpy
from . import contracts as ct
from .utils import logger
log = logger.get(__name__)
####################
# - Constants
####################
LOG_LEVEL_MAP: dict[str, logger.LogLevel] = {
'DEBUG': logging.DEBUG,
'INFO': logging.INFO,
'WARNING': logging.WARNING,
'ERROR': logging.ERROR,
'CRITICAL': logging.CRITICAL,
}
####################
# - Preferences
####################
class BLMaxwellAddonPrefs(bpy.types.AddonPreferences):
"""Manages user preferences and settings for the Blender Maxwell addon.
Unfortunately, many of the niceities based on dependencies (ex. `bl_cache.BLField`) aren't available here.
Attributes:
bl_idname: Matches `ct.addon.NAME`.
use_default_pydeps_path: Whether to use the default PyDeps path
"""
bl_idname = ct.addon.NAME
####################
# - Properties
####################
# Logging
## File Logging
use_log_file: bpy.props.BoolProperty( # type: ignore
name='Log to File',
description='Whether to use a file for addon logging',
default=True,
update=lambda self, _: self.on_addon_logging_changed(),
)
log_level_file: bpy.props.EnumProperty( # type: ignore
name='File Log Level',
description='Level of addon logging to expose in the file',
items=[
('DEBUG', 'Debug', 'Debug'),
('INFO', 'Info', 'Info'),
('WARNING', 'Warning', 'Warning'),
('ERROR', 'Error', 'Error'),
('CRITICAL', 'Critical', 'Critical'),
],
default='DEBUG',
update=lambda self, _: self.on_addon_logging_changed(),
)
bl__log_file_path: bpy.props.StringProperty( # type: ignore
name='Log Path',
description='Path to the Addon Log File',
subtype='FILE_PATH',
default=str(ct.addon.DEFAULT_LOG_PATH),
update=lambda self, _: self.on_addon_logging_changed(),
)
@property
def log_file_path(self) -> Path:
"""Retrieve the configured file-logging path as a `pathlib.Path`."""
return Path(bpy.path.abspath(self.bl__log_file_path))
@log_file_path.setter
def log_file_path(self, path: Path) -> None:
"""Set the configured file-logging path as a `pathlib.Path`."""
self.bl__log_file_path = str(path.resolve())
## Console Logging
use_log_console: bpy.props.BoolProperty( # type: ignore
name='Log to Console',
description='Whether to use the console for addon logging',
default=True,
update=lambda self, _: self.on_addon_logging_changed(),
)
log_level_console: bpy.props.EnumProperty( # type: ignore
name='Console Log Level',
description='Level of addon logging to expose in the console',
items=[
('DEBUG', 'Debug', 'Debug'),
('INFO', 'Info', 'Info'),
('WARNING', 'Warning', 'Warning'),
('ERROR', 'Error', 'Error'),
('CRITICAL', 'Critical', 'Critical'),
],
default='DEBUG',
update=lambda self, _: self.on_addon_logging_changed(),
)
## TODO: Derive default from INIT_SETTINGS
####################
# - Events: Properties Changed
####################
def setup_logger(self, _logger: logging.Logger) -> None:
"""Setup a logger using the settings declared in the addon preferences.
Args:
_logger: The logger to configure using settings in the addon preferences.
"""
logger.update_logger(
logger.console_handler,
logger.file_handler,
_logger,
file_path=self.log_file_path if self.use_log_file else None,
file_level=LOG_LEVEL_MAP[self.log_level_file],
console_level=LOG_LEVEL_MAP[self.log_level_console]
if self.use_console_level
else None,
)
def on_addon_logging_changed(self) -> None:
"""Called to reconfigure all loggers to match newly-altered addon preferences.
This causes ex. changes to desired console log level to immediately be applied, but only the this addon's loggers.
Parameters:
single_logger_to_setup: When set, only this logger will be setup.
Otherwise, **all addon loggers will be setup**.
"""
log.info('Reconfiguring Loggers')
for _logger in logger.all_addon_loggers():
self.setup_logger(_logger)
log.info('Loggers Reconfigured')
####################
# - UI
####################
def draw(self, _: bpy.types.Context) -> None:
"""Draw the addon preferences within its panel in Blender's preferences.
Notes:
Run by Blender when this addon's preferences need to be displayed.
Parameters:
context: The Blender context object.
"""
layout = self.layout
####################
# - Logging
####################
# Box w/Split: Log Level
box = layout.box()
row = box.row()
row.alignment = 'CENTER'
row.label(text='Logging')
split = box.split(factor=0.5)
## Split Col: Console Logging
col = split.column()
row = col.row()
row.prop(self, 'use_log_console', toggle=True)
row = col.row()
row.enabled = self.use_log_console
row.prop(self, 'log_level_console')
## Split Col: File Logging
col = split.column()
row = col.row()
row.prop(self, 'use_log_file', toggle=True)
row = col.row()
row.enabled = self.use_log_file
row.prop(self, 'bl__log_file_path')
row = col.row()
row.enabled = self.use_log_file
row.prop(self, 'log_level_file')
####################
# - Blender Registration
####################
BL_REGISTER = [
BLMaxwellAddonPrefs,
]

View File

@ -1,159 +0,0 @@
# oscillode
# Copyright (C) 2024 oscillode Project Contributors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
"""Manages the registration of Blender classes, including delayed registrations that require access to Python dependencies.
Attributes:
_REGISTERED_CLASSES: Blender classes currently registered by this addon.
_REGISTERED_KEYMAPS: Addon keymaps currently registered by this addon.
Each addon keymap is constrained to a single `space_type`, which is the key.
_REGISTERED_KEYMAP_ITEMS: Addon keymap items currently registered by this addon.
Each keymap item is paired to the keymap within which it is registered.
_Each keymap is guaranteed to also be found in `_REGISTERED_KEYMAPS`._
_REGISTERED_HANDLERS: Addon handlers currently registered by this addon.
"""
import bpy
from . import contracts as ct
from .utils import logger
log = logger.get(__name__)
####################
# - Globals
####################
_REGISTERED_CLASSES: list[ct.BLClass] = []
_REGISTERED_KEYMAPS: dict[ct.BLSpaceType, bpy.types.KeyMap] = {}
_REGISTERED_KEYMAP_ITEMS: list[tuple[bpy.types.KeyMap, bpy.types.KeyMapItem]] = []
_REGISTERED_HANDLERS: ct.BLHandlers | None = None
####################
# - Class Registration
####################
def register_classes(bl_register: list[ct.BLClass]) -> None:
"""Registers a list of Blender classes.
Parameters:
bl_register: List of Blender classes to register.
"""
log.info('Registering %s Classes', len(bl_register))
for cls in bl_register:
if cls.bl_idname in _REGISTERED_CLASSES:
msg = f'Skipping register of {cls.bl_idname}'
log.info(msg)
continue
log.debug(
'Registering Class %s',
repr(cls),
)
bpy.utils.register_class(cls)
_REGISTERED_CLASSES.append(cls)
def unregister_classes() -> None:
"""Unregisters all previously registered Blender classes."""
log.info('Unregistering %s Classes', len(_REGISTERED_CLASSES))
for cls in reversed(_REGISTERED_CLASSES):
log.debug(
'Unregistering Class %s',
repr(cls),
)
bpy.utils.unregister_class(cls)
_REGISTERED_CLASSES.clear()
####################
# - Handler Registration
####################
def register_handlers(bl_handlers: ct.BLHandlers) -> None:
"""Register the given Blender handlers."""
global _REGISTERED_HANDLERS # noqa: PLW0603
log.info('Registering BLHandlers') ## TODO: More information
if _REGISTERED_HANDLERS is None:
bl_handlers.register()
_REGISTERED_HANDLERS = bl_handlers
msg = 'There are already BLHandlers registered; they must be unregistered before a new set can be registered.'
raise ValueError(msg)
def unregister_handlers() -> None:
"""Unregister this addon's registered Blender handlers."""
global _REGISTERED_HANDLERS # noqa: PLW0603
log.info('Unregistering BLHandlers') ## TODO: More information
if _REGISTERED_HANDLERS is not None:
_REGISTERED_HANDLERS.register()
_REGISTERED_HANDLERS = None
msg = 'There are no BLHandlers registered; therefore, there is nothing to register.'
raise ValueError(msg)
####################
# - Keymap Registration
####################
def register_keymaps(keymap_items: list[ct.BLKeymapItem]) -> None:
"""Registers a list of Blender hotkey definitions.
Parameters:
bl_keymap_items: List of Blender hotkey definitions to register.
"""
# Aggregate Requested Spaces of All Keymap Items
keymap_space_types: set[ct.BLSpaceType] = {
keymap_item.space_type for keymap_item in keymap_items
}
# Create Addon Keymap per Requested Space
for keymap_space_type in keymap_space_types:
log.info('Registering %s Keymap', keymap_space_type)
bl_keymap = bpy.context.window_manager.keyconfigs.addon.keymaps.new(
name=f'{ct.addon.NAME} - {keymap_space_type}',
space_type=keymap_space_type,
)
_REGISTERED_KEYMAPS[keymap_space_type] = bl_keymap
# Register Keymap Items in Correct Addon Keymap
for keymap_item in keymap_items:
log.info('Registering %s Keymap Item', keymap_item)
bl_keymap = _REGISTERED_KEYMAPS[keymap_item.space_type]
bl_keymap_item = keymap_item.register(bl_keymap)
_REGISTERED_KEYMAP_ITEMS.append((bl_keymap, bl_keymap_item))
def unregister_keymaps() -> None:
"""Unregisters all Blender keymaps associated with the addon."""
# Unregister Keymap Items from Correct Addon Keymap
for bl_keymap, bl_keymap_item in reversed(_REGISTERED_KEYMAP_ITEMS):
log.info('Unregistering %s BL Keymap Item', bl_keymap_item)
bl_keymap.keymap_items.remove(bl_keymap_item)
_REGISTERED_KEYMAP_ITEMS.clear()
# Delete Addon Keymaps
for bl_keymap in reversed(_REGISTERED_KEYMAPS.values()):
log.info('Unregistering %s Keymap', bl_keymap)
bpy.context.window_manager.keyconfigs.addon.keymaps.remove(bl_keymap)
_REGISTERED_KEYMAPS.clear()

View File

@ -1,59 +0,0 @@
# oscillode
# Copyright (C) 2024 oscillode Project Contributors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
"""Authoritative definition and storage of "Initialization Settings", which provide out-of-the-box defaults for settings relevant for ex. debugging.
These settings are transported via a special TOML file that is packed into the extension zip-file when packaging for release.
"""
import tomllib
import typing as typ
from pathlib import Path
import pydantic as pyd
####################
# - Constants
####################
PATH_ROOT = Path(__file__).resolve().parent.parent
INIT_SETTINGS_FILENAME = 'init_settings.toml'
####################
# - Types
####################
LogLevel: typ.TypeAlias = int
class InitSettings(pyd.BaseModel):
"""Model describing addon initialization settings, describing default settings baked into the release.
Each parameter
"""
use_log_file: bool
log_file_path: Path
log_file_level: LogLevel
use_log_console: bool
log_console_level: LogLevel
####################
# - Init Settings Management
####################
with (PATH_ROOT / INIT_SETTINGS_FILENAME).open('rb') as f:
INIT_SETTINGS: InitSettings = InitSettings(**tomllib.load(f))

View File

@ -1,35 +0,0 @@
# oscillode
# Copyright (C) 2024 oscillode Project Contributors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# blender_maxwell
# Copyright (C) 2024 blender_maxwell Project Contributors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import typing as typ
ValueFlow: typ.TypeAlias = typ.Any

View File

@ -1,213 +0,0 @@
# oscillode
# Copyright (C) 2024 oscillode Project Contributors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
"""A lightweight, `rich`-based approach to logging that is isolated from other extensions that may used the Python stdlib `logging` module."""
import logging
import typing as typ
from pathlib import Path
import rich.console
import rich.logging
import rich.traceback
from oscillode import contracts as ct
from ..services import init_settings
LogLevel: typ.TypeAlias = int
####################
# - Configuration
####################
STREAM_LOG_FORMAT = 11 * ' ' + '%(levelname)-8s %(message)s (%(name)s)'
FILE_LOG_FORMAT = STREAM_LOG_FORMAT
OUTPUT_CONSOLE = rich.console.Console(
color_system='truecolor',
)
ERROR_CONSOLE = rich.console.Console(
color_system='truecolor',
stderr=True,
)
ADDON_LOGGER_NAME = f'blext-{ct.addon.NAME}'
ADDON_LOGGER: logging.Logger = logging.getLogger(ADDON_LOGGER_NAME)
rich.traceback.install(show_locals=True, console=ERROR_CONSOLE)
####################
# - Logger Access
####################
def all_addon_loggers() -> set[logging.Logger]:
"""Retrieve all loggers currently declared by this addon.
These loggers are all children of `ADDON_LOGGER`, essentially.
This allows for name-isolation from other Blender extensions, as well as easy cleanup.
Returns:
Set of all loggers declared by this addon.
"""
return {
logging.getLogger(name)
for name in logging.root.manager.loggerDict
if name.startswith(ADDON_LOGGER_NAME)
}
## TODO: Python 3.12 has a .getChildren() method that also returns sets.
####################
# - Logging Handlers
####################
def console_handler(level: LogLevel) -> rich.logging.RichHandler:
"""A logging handler that prints messages to the console.
Parameters:
level: The log levels (debug, info, etc.) to print.
Returns:
The logging handler, which can be added to a logger.
"""
rich_formatter = logging.Formatter(
'%(message)s',
datefmt='[%X]',
)
rich_handler = rich.logging.RichHandler(
level=level,
console=ERROR_CONSOLE,
rich_tracebacks=True,
)
rich_handler.setFormatter(rich_formatter)
return rich_handler
def file_handler(path_log_file: Path, level: LogLevel) -> rich.logging.RichHandler:
"""A logging handler that prints messages to a file.
Parameters:
path_log_file: The path to the log file.
level: The log levels (debug, info, etc.) to append to the file.
Returns:
The logging handler, which can be added to a logger.
"""
file_formatter = logging.Formatter(FILE_LOG_FORMAT)
file_handler = logging.FileHandler(path_log_file)
file_handler.setFormatter(file_formatter)
file_handler.setLevel(level)
return file_handler
####################
# - Logger Setup
####################
def get(module_name: str) -> logging.Logger:
"""Retrieve and/or create a logger corresponding to a module name.
Warnings:
MUST be used as `logger.get(__name__)`.
Parameters:
module_name: The `__name__` of the module to return a logger for.
"""
log = ADDON_LOGGER.getChild(module_name)
# Setup Logger from Init Settings or Addon Preferences
## - We prefer addon preferences, but they may not be setup yet.
## - Once setup, the preferences may decide to re-configure all the loggers.
addon_prefs = ct.addon.prefs()
if addon_prefs is None:
use_log_file = init_settings.INIT_SETTINGS.use_log_file
log_file_path = init_settings.INIT_SETTINGS.log_file_path
log_file_level = init_settings.INIT_SETTINGS.log_file_level
use_log_console = init_settings.INIT_SETTINGS.use_log_console
log_console_level = init_settings.INIT_SETTINGS.log_console_level
update_logger(
console_handler,
file_handler,
log,
file_path=log_file_path if use_log_file else None,
file_level=log_file_level,
console_level=log_console_level if use_log_console else None,
)
else:
addon_prefs.setup_logger(log)
return log
####################
# - Logger Update
####################
def _init_logger(logger: logging.Logger) -> None:
"""Prepare a logger for handlers to be added, ensuring normalized semantics for all loggers.
- Messages should not propagate to the root logger, causing double-messages.
- Mesages should not filter by level; this is the job of the handlers.
- No handlers must be set.
Args:
logger: The logger to prepare.
"""
# DO NOT Propagate to Root Logger
## - This looks like 'double messages'
## - See SO/6729268/log-messages-appearing-twice-with-python-logging
logger.propagate = False
# Let All Messages Through
## - The individual handlers perform appropriate filtering.
logger.setLevel(logging.NOTSET)
if logger.handlers:
logger.handlers.clear()
def update_logger(
cb_console_handler: typ.Callable[[LogLevel], logging.Handler],
cb_file_handler: typ.Callable[[Path, LogLevel], logging.Handler],
logger: logging.Logger,
console_level: LogLevel | None,
file_path: Path | None,
file_level: LogLevel,
) -> None:
"""Configures a single logger with given console and file handlers, individualizing the log level that triggers it.
This is a lower-level function - generally, modules that want to use a well-configured logger will use the `get()` function, which retrieves the parameters for this function from the addon preferences.
This function is used by the higher-level log setup.
Parameters:
cb_console_handler: A function that takes a log level threshold (inclusive), and returns a logging handler to a console-printer.
cb_file_handler: A function that takes a log level threshold (inclusive), and returns a logging handler to a file-printer.
logger: The logger to configure.
console_level: The log level threshold to print to the console.
None deactivates file logging.
path_log_file: The path to the log file.
None deactivates file logging.
file_level: The log level threshold to print to the log file.
"""
# Initialize Logger
_init_logger(logger)
# Add Console Logging Handler
if console_level is not None:
logger.addHandler(cb_console_handler(console_level))
# Add File Logging Handler
if file_path is not None:
logger.addHandler(cb_file_handler(file_path, file_level))

View File

@ -1,45 +0,0 @@
# oscillode
# Copyright (C) 2024 oscillode Project Contributors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# blender_maxwell
# Copyright (C) 2024 blender_maxwell Project Contributors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from .filter import FilterOperation
from .map import MapOperation
from .operate import BinaryOperation
from .reduce import ReduceOperation
from .transform import TransformOperation
__all__ = [
'FilterOperation',
'MapOperation',
'BinaryOperation',
'ReduceOperation',
'TransformOperation',
]

View File

@ -1,39 +0,0 @@
# oscillode
# Copyright (C) 2024 oscillode Project Contributors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# blender_maxwell
# Copyright (C) 2024 blender_maxwell Project Contributors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import sympy as sp
import sympy.physics.units as spu
####################
# - Underlying "Sympy Type"
####################
SympyType = sp.Basic | sp.MatrixBase | spu.Quantity | spu.Dimension

View File

@ -1,122 +1,65 @@
[project]
name = "oscillode"
version = "0.2.0"
name = "blender_maxwell"
version = "0.1.0"
description = "Real-time design and visualization of Maxwell simulations in Blender 3D, with deep Tidy3D integration. "
authors = [
{ name = "Sofus Albert Høgsbro Rose", email = "oscillode@sofusrose.com" }
]
maintainers = [
{ name = "Sofus Albert Høgsbro Rose", email = "oscillode@sofusrose.com" }
{ name = "Sofus Albert Høgsbro Rose", email = "blender-maxwell@sofusrose.com" }
]
dependencies = [
"tidy3d==2.7.*",
"pydantic==2.9.*",
"sympy==1.13.*",
"scipy==1.14.*",
"trimesh==4.4.*",
"networkx==3.3.*",
"rich>=13.8.*",
"rtree==1.3.*",
"jax[cpu]==0.4.33",
"msgspec[toml]==0.18.*",
"numba==0.60.*",
"jaxtyping==0.2.*",
"polars==1.8.*",
"seaborn[stats]>=0.13.*",
"frozendict>=2.4.*",
"pydantic-tensor>=0.2",
"tidy3d==2.7.0rc2",
"pydantic>=2.7.1",
"sympy==1.12",
"scipy==1.12.*",
"trimesh==4.2.*",
"networkx==3.2.*",
"rich>=13.7.1",
"rtree==1.2.*",
"jax[cpu]==0.4.26",
"msgspec[toml]==0.18.6",
"numba==0.59.1",
"jaxtyping==0.2.28",
# Pin Blender 4.1.0-Compatible Versions
## The dependency resolver will report if anything is wonky.
"urllib3==1.26.8",
#"requests==2.27.1", ## Conflict with dev-dep commitizen
"numpy==1.24.3",
"idna==3.3",
#"charset-normalizer==2.0.10", ## Conflict with dev-dep commitizen
"certifi==2021.10.8",
"polars>=0.20.26",
"seaborn[stats]>=0.13.2",
"frozendict>=2.4.4",
"pydantic-tensor>=0.2.0",
]
## When it comes to dev-dep conflicts:
## -> It's okay to leave Blender-pinned deps out of prod; Blender still has them.
## -> In edge cases, other deps might grab newer versions and Blender will complain.
## -> Let's wait and see if this is more than a theoretical issue.
readme = "README.md"
requires-python = "~= 3.11"
license = { text = "AGPL-3.0-or-later" }
[project.urls]
Homepage = "https://oscillode.io"
####################
# - Blender Extension
# - Tooling: Rye
####################
[tool.bl_ext]
pretty_name = "Oscillode"
blender_version_min = '4.2.0'
blender_version_max = '4.2.2'
permissions = ["files", "network"]
bl_tags = ["Node", "Scene", "Import-Export"]
copyright = ["2024 Oscillode Contributors"]
# Platform Support
## Map Valid Blender Platforms -> Required PyPi Platform Tags
## Include as few PyPi tags as works on ~everything.
[tool.bl_ext.platforms]
#windows-amd64 = ['win_amd64']
#macos-arm64 = ['macosx_11_0_arm64', 'macosx_12_0_arm64', 'macosx_14_0_arm64']
linux-x86_64 = ['manylinux1_x86_64', 'manylinux2014_x86_64', 'manylinux_2_17_x86_64']
#macos-x86_64 = ['macosx_10_10_x86_64'] ##TODO: Broken
# Packaging
## Path is from the directory containing this file.
[tool.bl_ext.packaging]
path_builds = 'dev/build'
path_wheels = 'dev/wheels'
path_local = 'dev/local'
init_settings_filename = 'init_settings.toml'
# "Profiles" -> Affects Initialization Settings
## This sets the default extension preferences for different situations.
[tool.bl_ext.profiles.test]
use_path_local = true
use_log_file = true
log_file_path = 'oscillode.log'
log_file_level = 'debug'
use_log_console = true
log_console_level = 'info'
[tool.bl_ext.profiles.dev]
use_path_local = true
use_log_file = true
log_file_path = 'oscillode.log'
log_file_level = 'debug'
use_log_console = true
log_console_level = 'info'
[tool.bl_ext.profiles.release]
use_path_local = false
use_log_file = true
log_file_path = 'oscillode.log'
log_file_level = 'info'
use_log_console = true
log_console_level = 'warning'
[tool.bl_ext.profiles.release-debug]
use_path_local = false
use_log_file = true
log_file_path = 'oscillode.log'
log_file_level = 'debug'
use_log_console = true
log_console_level = 'warning'
####################
# - Tooling: uv
####################
[tool.uv]
[tool.rye]
managed = true
virtual = true
dev-dependencies = [
"ruff>=0.6.8",
"ruff>=0.4.3",
"fake-bpy-module-4-0>=20231118",
"pre-commit>=3.7.0",
"commitizen>=3.25.0",
"pip>=24.2",
"pytest>=8.3.3",
"fake-bpy-module-4-1>=20240604",
"bpy==4.2",
"pytest-cov>=5.0.0",
## Requires charset-normalizer>=2.1.0
# Required by Commitizen
## -> It's okay to have different dev/prod versions in our use case.
#"charset-normalizer==2.1.*",
"charset-normalizer==2.1.*",
## Manually scanned CHANGELOG; seems compatible.
]
package = false
[tool.rye.scripts]
dev = "python ./src/scripts/dev.py"
pack = "python ./src/scripts/pack.py"
####################
@ -125,6 +68,7 @@ package = false
[tool.ruff]
target-version = "py311"
line-length = 88
pycodestyle.max-doc-length = 120
[tool.ruff.lint]
task-tags = ["TODO"]
@ -181,7 +125,6 @@ ignore = [
"F722", # jaxtyping uses type annotations that ruff sees as "syntax error"
"N806", # Sometimes we like using types w/uppercase in functions, sue me
"RUF001", # We use a lot of unicode, yes, on purpose!
#"RUF012", # ruff misunderstands which ClassVars are actually mutable.
# Line Length - Controversy Incoming
## Hot Take: Let the Formatter Worry about Line Length
@ -193,12 +136,6 @@ ignore = [
"E501", # Let Formatter Worry about Line Length
]
[tool.ruff.lint.per-file-ignores]
"tests/*" = [
"D100", # It's okay to not have module-level docstrings in test modules.
"D104", # Same for packages.
]
####################
# - Tooling: Ruff Sublinters
####################
@ -206,7 +143,6 @@ ignore = [
extend-immutable-calls = []
[tool.ruff.lint.pycodestyle]
max-doc-length = 120
ignore-overlong-task-comments = true
[tool.ruff.lint.pydocstyle]
@ -223,25 +159,6 @@ quote-style = "single"
indent-style = "tab"
docstring-code-format = false
####################
# - Tooling: MyPy
####################
[tool.mypy]
python_version = '3.11'
ignore_missing_imports = true
strict_optional = true
disallow_subclassing_any = false
disallow_any_generics = true
disallow_untyped_calls = true
disallow_incomplete_defs = true
check_untyped_defs = true
disallow_untyped_decorators = true
no_implicit_optional = true
warn_redundant_casts = true
warn_unused_ignores = true
warn_return_any = true
####################
# - Tooling: Commits
####################
@ -260,9 +177,3 @@ update_changelog_on_bump = true
# Annotations / Signature
gpg_sign = true
annotated_tag = true
####################
# - Tooling: Pytest
####################
[tool.pytest.ini_options]
testpaths = ["tests"]

View File

@ -0,0 +1,287 @@
# generated by rye
# use `rye lock` or `rye sync` to update this lockfile
#
# last locked with the following flags:
# pre: false
# features: []
# all-features: false
# with-sources: false
# generate-hashes: false
# universal: false
absl-py==2.1.0
# via chex
# via optax
# via orbax-checkpoint
annotated-types==0.6.0
# via pydantic
argcomplete==3.3.0
# via commitizen
boto3==1.34.123
# via tidy3d
botocore==1.34.123
# via boto3
# via s3transfer
certifi==2021.10.8
# via requests
cfgv==3.4.0
# via pre-commit
charset-normalizer==2.1.1
# via commitizen
# via requests
chex==0.1.86
# via optax
click==8.1.7
# via dask
# via tidy3d
cloudpickle==3.0.0
# via dask
colorama==0.4.6
# via commitizen
commitizen==3.25.0
contourpy==1.2.0
# via matplotlib
cycler==0.12.1
# via matplotlib
dask==2023.10.1
# via tidy3d
decli==0.6.2
# via commitizen
distlib==0.3.8
# via virtualenv
etils==1.9.1
# via orbax-checkpoint
fake-bpy-module-4-0==20231118
filelock==3.14.0
# via virtualenv
flax==0.8.4
# via tidy3d
fonttools==4.49.0
# via matplotlib
frozendict==2.4.4
fsspec==2024.2.0
# via dask
# via etils
h5netcdf==1.0.2
# via tidy3d
h5py==3.10.0
# via h5netcdf
# via tidy3d
identify==2.5.36
# via pre-commit
idna==3.3
# via requests
importlib-metadata==6.11.0
# via commitizen
# via dask
# via tidy3d
importlib-resources==6.4.0
# via etils
jax==0.4.26
# via chex
# via flax
# via optax
# via orbax-checkpoint
jaxlib==0.4.26
# via chex
# via jax
# via optax
# via orbax-checkpoint
jaxtyping==0.2.28
jinja2==3.1.3
# via commitizen
jmespath==1.0.1
# via boto3
# via botocore
joblib==1.4.2
# via tidy3d
kiwisolver==1.4.5
# via matplotlib
llvmlite==0.42.0
# via numba
locket==1.0.0
# via partd
markdown-it-py==3.0.0
# via rich
markupsafe==2.1.5
# via jinja2
matplotlib==3.8.3
# via seaborn
# via tidy3d
mdurl==0.1.2
# via markdown-it-py
ml-dtypes==0.4.0
# via jax
# via jaxlib
# via tensorstore
mpmath==1.3.0
# via sympy
msgpack==1.0.8
# via flax
# via orbax-checkpoint
msgspec==0.18.6
nest-asyncio==1.6.0
# via orbax-checkpoint
networkx==3.2
nodeenv==1.8.0
# via pre-commit
numba==0.59.1
numpy==1.24.3
# via chex
# via contourpy
# via flax
# via h5py
# via jax
# via jaxlib
# via jaxtyping
# via matplotlib
# via ml-dtypes
# via numba
# via opt-einsum
# via optax
# via orbax-checkpoint
# via pandas
# via patsy
# via pydantic-tensor
# via scipy
# via seaborn
# via shapely
# via statsmodels
# via tensorstore
# via tidy3d
# via trimesh
# via xarray
opt-einsum==3.3.0
# via jax
optax==0.2.2
# via flax
orbax-checkpoint==0.5.15
# via flax
packaging==24.0
# via commitizen
# via dask
# via h5netcdf
# via matplotlib
# via statsmodels
# via xarray
pandas==2.2.1
# via seaborn
# via statsmodels
# via tidy3d
# via xarray
partd==1.4.1
# via dask
patsy==0.5.6
# via statsmodels
pillow==10.2.0
# via matplotlib
platformdirs==4.2.1
# via virtualenv
polars==0.20.26
pre-commit==3.7.0
prompt-toolkit==3.0.36
# via questionary
protobuf==5.27.1
# via orbax-checkpoint
pydantic==2.7.1
# via pydantic-tensor
# via tidy3d
pydantic-core==2.18.2
# via pydantic
pydantic-tensor==0.2.0
pygments==2.17.2
# via rich
pyjwt==2.8.0
# via tidy3d
pyparsing==3.1.2
# via matplotlib
pyroots==0.5.0
# via tidy3d
python-dateutil==2.9.0.post0
# via botocore
# via matplotlib
# via pandas
pytz==2024.1
# via pandas
pyyaml==6.0.1
# via commitizen
# via dask
# via flax
# via orbax-checkpoint
# via pre-commit
# via responses
# via tidy3d
questionary==2.0.1
# via commitizen
requests==2.31.0
# via responses
# via tidy3d
responses==0.23.1
# via tidy3d
rich==13.7.1
# via flax
# via tidy3d
rtree==1.2.0
ruff==0.4.3
s3transfer==0.10.1
# via boto3
scipy==1.12.0
# via jax
# via jaxlib
# via seaborn
# via statsmodels
# via tidy3d
seaborn==0.13.2
setuptools==69.5.1
# via nodeenv
shapely==2.0.3
# via tidy3d
six==1.16.0
# via patsy
# via python-dateutil
statsmodels==0.14.2
# via seaborn
sympy==1.12
tensorstore==0.1.61
# via flax
# via orbax-checkpoint
termcolor==2.4.0
# via commitizen
tidy3d==2.7.0rc2
toml==0.10.2
# via tidy3d
tomli-w==1.0.0
# via msgspec
tomlkit==0.12.4
# via commitizen
toolz==0.12.1
# via chex
# via dask
# via partd
trimesh==4.2.0
typeguard==2.13.3
# via jaxtyping
types-pyyaml==6.0.12.20240311
# via responses
typing-extensions==4.10.0
# via chex
# via etils
# via flax
# via orbax-checkpoint
# via pydantic
# via pydantic-core
tzdata==2024.1
# via pandas
urllib3==1.26.8
# via botocore
# via requests
# via responses
virtualenv==20.26.1
# via pre-commit
wcwidth==0.2.13
# via prompt-toolkit
xarray==2024.2.0
# via tidy3d
zipp==3.18.0
# via etils
# via importlib-metadata

242
requirements.lock 100644
View File

@ -0,0 +1,242 @@
# generated by rye
# use `rye lock` or `rye sync` to update this lockfile
#
# last locked with the following flags:
# pre: false
# features: []
# all-features: false
# with-sources: false
# generate-hashes: false
# universal: false
absl-py==2.1.0
# via chex
# via optax
# via orbax-checkpoint
annotated-types==0.6.0
# via pydantic
boto3==1.34.123
# via tidy3d
botocore==1.34.123
# via boto3
# via s3transfer
certifi==2021.10.8
# via requests
charset-normalizer==2.0.10
# via requests
chex==0.1.86
# via optax
click==8.1.7
# via dask
# via tidy3d
cloudpickle==3.0.0
# via dask
contourpy==1.2.0
# via matplotlib
cycler==0.12.1
# via matplotlib
dask==2023.10.1
# via tidy3d
etils==1.9.1
# via orbax-checkpoint
flax==0.8.4
# via tidy3d
fonttools==4.49.0
# via matplotlib
frozendict==2.4.4
fsspec==2024.2.0
# via dask
# via etils
h5netcdf==1.0.2
# via tidy3d
h5py==3.10.0
# via h5netcdf
# via tidy3d
idna==3.3
# via requests
importlib-metadata==6.11.0
# via dask
# via tidy3d
importlib-resources==6.4.0
# via etils
jax==0.4.26
# via chex
# via flax
# via optax
# via orbax-checkpoint
jaxlib==0.4.26
# via chex
# via jax
# via optax
# via orbax-checkpoint
jaxtyping==0.2.28
jmespath==1.0.1
# via boto3
# via botocore
joblib==1.4.2
# via tidy3d
kiwisolver==1.4.5
# via matplotlib
llvmlite==0.42.0
# via numba
locket==1.0.0
# via partd
markdown-it-py==3.0.0
# via rich
matplotlib==3.8.3
# via seaborn
# via tidy3d
mdurl==0.1.2
# via markdown-it-py
ml-dtypes==0.4.0
# via jax
# via jaxlib
# via tensorstore
mpmath==1.3.0
# via sympy
msgpack==1.0.8
# via flax
# via orbax-checkpoint
msgspec==0.18.6
nest-asyncio==1.6.0
# via orbax-checkpoint
networkx==3.2
numba==0.59.1
numpy==1.24.3
# via chex
# via contourpy
# via flax
# via h5py
# via jax
# via jaxlib
# via jaxtyping
# via matplotlib
# via ml-dtypes
# via numba
# via opt-einsum
# via optax
# via orbax-checkpoint
# via pandas
# via patsy
# via pydantic-tensor
# via scipy
# via seaborn
# via shapely
# via statsmodels
# via tensorstore
# via tidy3d
# via trimesh
# via xarray
opt-einsum==3.3.0
# via jax
optax==0.2.2
# via flax
orbax-checkpoint==0.5.15
# via flax
packaging==24.0
# via dask
# via h5netcdf
# via matplotlib
# via statsmodels
# via xarray
pandas==2.2.1
# via seaborn
# via statsmodels
# via tidy3d
# via xarray
partd==1.4.1
# via dask
patsy==0.5.6
# via statsmodels
pillow==10.2.0
# via matplotlib
polars==0.20.26
protobuf==5.27.1
# via orbax-checkpoint
pydantic==2.7.1
# via pydantic-tensor
# via tidy3d
pydantic-core==2.18.2
# via pydantic
pydantic-tensor==0.2.0
pygments==2.17.2
# via rich
pyjwt==2.8.0
# via tidy3d
pyparsing==3.1.2
# via matplotlib
pyroots==0.5.0
# via tidy3d
python-dateutil==2.9.0.post0
# via botocore
# via matplotlib
# via pandas
pytz==2024.1
# via pandas
pyyaml==6.0.1
# via dask
# via flax
# via orbax-checkpoint
# via responses
# via tidy3d
requests==2.32.3
# via responses
# via tidy3d
responses==0.23.1
# via tidy3d
rich==13.7.1
# via flax
# via tidy3d
rtree==1.2.0
s3transfer==0.10.1
# via boto3
scipy==1.12.0
# via jax
# via jaxlib
# via seaborn
# via statsmodels
# via tidy3d
seaborn==0.13.2
shapely==2.0.3
# via tidy3d
six==1.16.0
# via patsy
# via python-dateutil
statsmodels==0.14.2
# via seaborn
sympy==1.12
tensorstore==0.1.61
# via flax
# via orbax-checkpoint
tidy3d==2.7.0rc2
toml==0.10.2
# via tidy3d
tomli-w==1.0.0
# via msgspec
toolz==0.12.1
# via chex
# via dask
# via partd
trimesh==4.2.0
typeguard==2.13.3
# via jaxtyping
types-pyyaml==6.0.12.20240311
# via responses
typing-extensions==4.10.0
# via chex
# via etils
# via flax
# via orbax-checkpoint
# via pydantic
# via pydantic-core
tzdata==2024.1
# via pandas
urllib3==1.26.8
# via botocore
# via requests
# via responses
xarray==2024.2.0
# via tidy3d
zipp==3.18.0
# via etils
# via importlib-metadata

View File

@ -1,67 +0,0 @@
# oscillode
# Copyright (C) 2024 oscillode Project Contributors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# blender_maxwell
# Copyright (C) 2024 blender_maxwell Project Contributors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import sys
from pathlib import Path
import bpy
PATH_SCRIPT = str(Path(__file__).resolve().parent)
sys.path.insert(0, str(PATH_SCRIPT))
import info # noqa: E402
import pack # noqa: E402
sys.path.remove(str(PATH_SCRIPT))
####################
# - Main
####################
if __name__ == '__main__':
pass
# Uninstall Old Extension
# if any(addon_name.endwith(info.ADDON_NAME) and addon_name.startswith('bl_ext.') for addon_name in bpy.context.preferences.addons.keys()):
# bpy.ops.extensions.package_uninstall(pkg_id=info.ADDON_NAME)
# Install New Extension
# with pack.zipped_addon(
# info.PATH_ADDON_PKG,
# info.PATH_ADDON_ZIP,
# info.PATH_ROOT / 'pyproject.toml',
# info.PATH_ROOT / 'requirements.lock',
# initial_log_level=info.BOOTSTRAP_LOG_LEVEL,
# ) as path_zipped:
# bpy.ops.extensions.package_install_files(
# filepath=path_zipped,
# enable_on_install=True,
#
# )

View File

@ -1,117 +0,0 @@
# oscillode
# Copyright (C) 2024 oscillode Project Contributors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# blender_maxwell
# Copyright (C) 2024 blender_maxwell Project Contributors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
"""Informational constants and variables that ease the implementation of scripts external to oscillode.
In general, user-relevant information available here should be mined from `pyproject.toml`, unless it is purely structural.
"""
import tomllib
import typing as typ
from pathlib import Path
import pydantic as pyd
from rich.console import Console
console = Console()
####################
# - Basic
####################
PATH_ROOT = Path(__file__).resolve().parent.parent
with (PATH_ROOT / 'pyproject.toml').open('rb') as f:
PROJ_SPEC = tomllib.load(f)
REQ_PYTHON_VERSION: str = PROJ_SPEC['project']['requires-python'].replace('~= ', '')
####################
# - Paths
####################
def normalize_path(p_str: str) -> Path:
"""Convert a project-root-relative '/'-delimited string path to an absolute path.
This allows for cross-platform path specification, while retaining normalized use of '/' in configuration.
Args:
p_str: The '/'-delimited string denoting a path relative to the project root.
Returns:
The full absolute path to use when ex. packaging.
"""
return PATH_ROOT / Path(*p_str.split('/'))
PATH_PKG = PATH_ROOT / PROJ_SPEC['project']['name']
PATH_DEV = PATH_ROOT / 'dev'
PATH_DEV.mkdir(exist_ok=True)
# Retrieve Build Path
## Extension ZIP files will be placed here after packaging.
PATH_BUILD = normalize_path(PROJ_SPEC['tool']['bl_ext']['packaging']['path_builds'])
PATH_BUILD.mkdir(exist_ok=True)
# Retrieve Wheels Path
## Dependency wheels will be downloaded to here, then copied into the extension packages.
PATH_WHEELS = normalize_path(PROJ_SPEC['tool']['bl_ext']['packaging']['path_wheels'])
PATH_WHEELS.mkdir(exist_ok=True)
# Retrieve Local Cache Path
## During development, files such as logs will be placed here instead of in the extension's user path.
## This is essentially a debugging convenience.
PATH_LOCAL = normalize_path(PROJ_SPEC['tool']['bl_ext']['packaging']['path_local'])
PATH_LOCAL.mkdir(exist_ok=True)
####################
# - Computed Paths
####################
# Compute Current ZIP to Build
## The concrete path to the file that will be packed and installed.
PATH_ZIP = PATH_BUILD / (
PROJ_SPEC['project']['name'] + '__' + PROJ_SPEC['project']['version'] + '.zip'
)
####################
# - Computed Paths
####################
LogLevel: typ.TypeAlias = int
class InitSettings(pyd.BaseModel):
"""Model describing addon initialization settings, describing default settings baked into the release."""
use_log_file: bool
log_file_path: Path
log_file_level: LogLevel
use_log_console: bool
log_console_level: LogLevel

View File

@ -1,296 +0,0 @@
# oscillode
# Copyright (C) 2024 oscillode Project Contributors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
"""Contains tools and procedures that deterministically and reliably package the Blender extension.
This involves parsing and validating the plugin configuration from `pyproject.toml`, generating the extension manifest, downloading the correct platform-specific binary wheels for distribution, and zipping it all up together.
"""
import itertools
import json
import logging
import subprocess
import sys
import tempfile
import typing as typ
import zipfile
from pathlib import Path
import rich
import rich.progress
import rich.prompt
import tomli_w
from . import info
LogLevel: typ.TypeAlias = int
BL_EXT__MANIFEST_FILENAME = 'blender_manifest.toml'
BL_EXT__SCHEMA_VERSION = '1.0.0'
BL_EXT__TYPE = 'add-on'
####################
# - Generate Manifest
####################
# See https://docs.blender.org/manual/en/4.2/extensions/getting_started.html
# See https://packaging.python.org/en/latest/guides/writing-pyproject-toml
_FIRST_MAINTAINER = info.PROJ_SPEC['project']['maintainers'][0]
_SPDX_LICENSE_NAME = info.PROJ_SPEC['project']['license']['text']
## TODO: pydantic model w/validation
BL_EXT_MANIFEST = {
'schema_version': BL_EXT__SCHEMA_VERSION,
# Basics
'id': info.PROJ_SPEC['project']['name'],
'name': info.PROJ_SPEC['tool']['bl_ext']['pretty_name'],
'version': info.PROJ_SPEC['project']['version'],
'tagline': info.PROJ_SPEC['project']['description'],
'maintainer': f'{_FIRST_MAINTAINER["name"]} <{_FIRST_MAINTAINER["email"]}>',
# Blender Compatibility
'type': BL_EXT__TYPE,
'blender_version_min': info.PROJ_SPEC['tool']['bl_ext']['blender_version_min'],
'blender_version_max': info.PROJ_SPEC['tool']['bl_ext']['blender_version_max'],
'platforms': list(info.PROJ_SPEC['tool']['bl_ext']['platforms'].keys()),
# OS/Arch Compatibility
## See https://docs.blender.org/manual/en/dev/extensions/python_wheels.html
'wheels': [
f'./wheels/{wheel_path.name}' for wheel_path in info.PATH_WHEELS.iterdir()
],
# Permissions
## * "files" (for access of any filesystem operations)
## * "network" (for internet access)
## * "clipboard" (to read and/or write the system clipboard)
## * "camera" (to capture photos and videos)
## * "microphone" (to capture audio)
'permissions': info.PROJ_SPEC['tool']['bl_ext']['permissions'],
# Addon Tags
'tags': info.PROJ_SPEC['tool']['bl_ext']['bl_tags'],
'license': [f'SPDX:{_SPDX_LICENSE_NAME}'],
'copyright': info.PROJ_SPEC['tool']['bl_ext']['copyright'],
'website': info.PROJ_SPEC['project']['urls']['Homepage'],
}
####################
# - Generate Init Settings
####################
## TODO: Use an enum for 'profile'.
def generate_init_settings_dict(profile: str) -> info.InitSettings:
"""Generate initialization settings from a particular `profile` configured in `pyproject.toml`.
Args:
profile: The string identifier corresponding to an entry in `pyproject.toml`.
Returns:
The `info.InitSettings` structure to be bundled into the addon.
"""
profile_settings = info.PROJ_SPEC['tool']['bl_ext']['profiles'][profile]
base_path = info.PATH_LOCAL if profile_settings['use_path_local'] else Path('USER')
log_levels = {
None: logging.NOTSET,
'debug': logging.DEBUG,
'info': logging.INFO,
'warning': logging.WARNING,
'error': logging.ERROR,
'critical': logging.CRITICAL,
}
return info.InitSettings(
use_log_file=profile_settings['use_log_file'],
log_file_path=base_path
/ info.normalize_path(profile_settings['log_file_path']),
log_file_level=log_levels[profile_settings['log_file_level']],
use_log_console=profile_settings['use_log_console'],
log_console_level=log_levels[profile_settings['log_console_level']],
)
####################
# - Wheel Downloader
####################
def download_wheels(delete_existing_wheels: bool = True) -> None:
"""Download universal and binary wheels for all platforms defined in `pyproject.toml`.
Each blender-supported platform requires specifying a valid list of PyPi platform constraints.
These will be used as an allow-list when deciding which binary wheels may be selected for ex. 'mac'.
It is recommended to start with the most compatible platform tags, then work one's way up to the newest.
Depending on how old the compatibility should stretch, one may have to omit / manually compile some wheels.
There is no exhaustive list of valid platform tags - though this should get you started:
- https://stackoverflow.com/questions/49672621/what-are-the-valid-values-for-platform-abi-and-implementation-for-pip-do
- Examine https://pypi.org/project/pillow/#files for some widely-supported tags.
Args:
delete_existing_wheels: Whether to delete all wheels already in the directory.
This doesn't generally require re-downloading; the pip-cache will generally be hit first.
"""
if delete_existing_wheels and rich.prompt.Confirm.ask(
f'OK to delete "*.whl" in {info.PATH_WHEELS}?'
):
info.console.log(f'[bold] Deleting Existing Wheels in {info.PATH_WHEELS}')
for existing_wheel in info.PATH_WHEELS.rglob('*.whl'):
existing_wheel.unlink()
with tempfile.NamedTemporaryFile(delete=False) as f_reqlock:
reqlock_str = subprocess.check_output(['uv', 'export', '--no-dev', '--locked'])
f_reqlock.write(reqlock_str)
reqlock_path = Path(f_reqlock.name)
## TODO: Use-after-close may not work on Windows.
for platform, pypi_platform_tags in info.PROJ_SPEC['tool']['bl_ext'][
'platforms'
].items():
info.console.rule(f'[bold] Downloading Wheels for {platform}')
platform_constraints = list(
itertools.chain.from_iterable(
[
['--platform', pypi_platform_tag]
for pypi_platform_tag in pypi_platform_tags
]
)
)
cmd = [
sys.executable,
'-m',
'pip',
'download',
'--requirement',
str(reqlock_path),
'--dest',
str(info.PATH_WHEELS),
'--require-hashes',
'--only-binary',
':all:',
'--python-version',
info.REQ_PYTHON_VERSION,
*platform_constraints,
]
progress = rich.progress.Progress()
progress_task_id = progress.add_task(' '.join(cmd))
with (
rich.progress.Live(progress, console=info.console, transient=False) as live,
subprocess.Popen(cmd, stdout=subprocess.PIPE) as process,
):
for line in process.stdout if process.stdout is not None else []:
progress.update(progress_task_id, description=line.decode())
live.refresh()
# Cleanup the Temporary File
reqlock_path.unlink()
####################
# - Pack Extension to ZIP
####################
def pack_bl_extension(
profile: str,
replace_if_exists: bool = False,
) -> None:
"""Package a Blender extension, using a particular given `profile` of init settings.
Configuration data is sourced from `info`, which in turns sources much of its user-facing configuration from `pyproject.toml`.
Parameters:
profile: Identifier matching `pyproject.toml`, which select a predefined set of init settings.
replace_if_exists: Replace the zip file if it already exists.
"""
# Delete Existing ZIP (maybe)
if info.PATH_ZIP.is_file():
if replace_if_exists:
msg = 'File already exists where extension ZIP would be generated ({info.PATH_ZIP})'
raise ValueError(msg)
info.PATH_ZIP.unlink()
init_settings: info.InitSettings = generate_init_settings_dict(profile)
# Create New ZIP file of the addon directory
info.console.rule(f'[bold] Creating zipfile @ {info.PATH_ZIP}')
with zipfile.ZipFile(info.PATH_ZIP, 'w', zipfile.ZIP_DEFLATED) as f_zip:
# Write Blender Extension Manifest
with info.console.status('Writing Extension Manifest...'):
f_zip.writestr(BL_EXT__MANIFEST_FILENAME, tomli_w.dumps(BL_EXT_MANIFEST))
info.console.log('Wrote Extension Manifest.')
# Write Init Settings
with info.console.status('Writing Init Settings...'):
f_zip.writestr(
info.PROJ_SPEC['tool']['bl_ext']['packaging']['init_settings_filename'],
tomli_w.dumps(json.loads(init_settings.model_dump_json())),
)
info.console.log('Wrote Init Settings.')
# Install Addon Files @ /*
with info.console.status('Writing Addon Files...'):
for file_to_zip in info.PATH_PKG.rglob('*'):
f_zip.write(file_to_zip, file_to_zip.relative_to(info.PATH_PKG.parent))
info.console.log('Wrote Addon Files.')
# Install Wheels @ /wheels/*
# with info.console.status('Writing Wheels...'):
# for wheel_to_zip in info.PATH_WHEELS.rglob('*'):
# f_zip.write(wheel_to_zip, Path('wheels') / wheel_to_zip.name)
# info.console.log('Wrote Wheels.')
total_wheel_size = sum(
f.stat().st_size for f in info.PATH_WHEELS.rglob('*') if f.is_file()
)
progress = rich.progress.Progress(
rich.progress.TextColumn(
'Writing Wheel: {task.description}...',
table_column=rich.progress.Column(ratio=2),
),
rich.progress.BarColumn(
bar_width=None,
table_column=rich.progress.Column(ratio=2),
),
expand=True,
)
progress_task = progress.add_task('Writing Wheels...', total=total_wheel_size)
with rich.progress.Live(progress, console=info.console, transient=True) as live:
for wheel_to_zip in info.PATH_WHEELS.rglob('*.whl'):
f_zip.write(wheel_to_zip, Path('wheels') / wheel_to_zip.name)
progress.update(
progress_task,
description=wheel_to_zip.name,
advance=wheel_to_zip.stat().st_size,
)
live.refresh()
info.console.log('Wrote Wheels.')
# Delete the ZIP
info.console.rule(f'[bold green] Extension Packed to {info.PATH_ZIP}!')
####################
# - Run Blender w/Clean Addon Reinstall
####################
if __name__ == '__main__':
profile = sys.argv[1]
if sys.argv[1] in ['dev', 'release', 'release-debug']:
if not list(info.PATH_WHEELS.iterdir()) or '--download-wheels' in sys.argv:
download_wheels()
pack_bl_extension(profile)
else:
msg = f'Packaging profile "{profile}" is invalid. Refer to source of pack.py for more information'
raise ValueError(msg)

View File

@ -0,0 +1,232 @@
# blender_maxwell
# Copyright (C) 2024 blender_maxwell Project Contributors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
"""A Blender-based system for electromagnetic simulation design and analysis, with deep Tidy3D integration.
# `bl_info`
`bl_info` declares information about the addon to Blender.
However, it is not _dynamically_ read: Blender traverses it using `ast.parse`.
This makes it difficult to synchronize `bl_info` with the project's `pyproject.toml`.
As a workaround, **the addon zip-packer will replace `bl_info` entries**.
The following `bl_info` entries are currently replaced when the ZIP is built:
- `description`: To match the description in `pyproject.toml`.
- `version`: To match the version in `pyproject.toml`.
For more information, see `scripts.pack.BL_INFO_REPLACEMENTS`.
**NOTE**: The find/replace procedure is "dumb" (aka. no regex, no `ast` traversal, etc.).
This is surprisingly robust, so long as use of the deterministic code-formatter `ruff fmt` is enforced.
Still. Be careful around `bl_info`.
Attributes:
bl_info: Information about the addon declared to Blender.
BL_REGISTER_BEFORE_DEPS: Blender classes to register before dependencies are verified as installed.
BL_HOTKEYS: Blender keymap item defs to register before dependencies are verified as installed.
"""
from pathlib import Path
from .nodeps.utils import simple_logger
# Initialize Logging Defaults
## Initial logger settings (ex. log level) must be set somehow.
## The Addon ZIP-packer makes this decision, and packs it into files.
## AddonPreferences will, once loaded, override this.
_PATH_ADDON_ROOT = Path(__file__).resolve().parent
_PATH_BOOTSTRAP_LOG_LEVEL = _PATH_ADDON_ROOT / '.bootstrap_log_level'
with _PATH_BOOTSTRAP_LOG_LEVEL.open('r') as f:
_BOOTSTRAP_LOG_LEVEL = int(f.read().strip())
simple_logger.init_simple_logger_defaults(console_level=_BOOTSTRAP_LOG_LEVEL)
# Import Statements
import bpy # noqa: E402
from . import contracts as ct # noqa: E402
from . import preferences, registration # noqa: E402
from .nodeps import operators as nodeps_operators # noqa: E402
from .nodeps.utils import pydeps # noqa: E402
log = simple_logger.get(__name__)
####################
# - Addon Information
####################
bl_info = {
'name': 'Maxwell PDE Sim and Viz',
'blender': (4, 1, 0),
'category': 'Node',
'description': 'Placeholder',
'author': 'Sofus Albert Høgsbro Rose',
'version': (0, 0, 0),
'wiki_url': 'https://git.sofus.io/dtu-courses/bsc_thesis',
'tracker_url': 'https://git.sofus.io/dtu-courses/bsc_thesis/issues',
}
####################
# - Load and Register Addon
####################
BL_REGISTER_BEFORE_DEPS: list[ct.BLClass] = [
*nodeps_operators.BL_REGISTER,
*preferences.BL_REGISTER,
]
## TODO: BL_HANDLERS and BL_SOCKET_DEFS
BL_HOTKEYS_BEFORE_DEPS: list[ct.KeymapItemDef] = [
*nodeps_operators.BL_HOTKEYS,
]
def load_main_blclasses(path_pydeps: Path) -> list[ct.BLClass]:
"""Imports all addon classes that rely on Python dependencies.
Notes:
`sys.path` is modified while executing this function.
Parameters:
path_pydeps: The path to the Python dependencies.
Returns:
An ordered list of Blender classes to register.
"""
with pydeps.importable_addon_deps(path_pydeps):
from . import assets, node_trees, operators
return [
*operators.BL_REGISTER,
*assets.BL_REGISTER,
*node_trees.BL_REGISTER,
]
def load_main_blhotkeys(path_deps: Path) -> list[ct.KeymapItemDef]:
"""Imports all keymap item defs that rely on Python dependencies.
Notes:
`sys.path` is modified while executing this function.
Parameters:
path_pydeps: The path to the Python dependencies.
Returns:
An ordered list of Blender keymap item defs to register.
"""
with pydeps.importable_addon_deps(path_deps):
from . import assets, operators
return [
*operators.BL_HOTKEYS,
*assets.BL_HOTKEYS,
]
####################
# - Registration
####################
@bpy.app.handlers.persistent
def manage_pydeps(*_):
# ct.addon.operator(
# ct.OperatorType.ManagePyDeps,
# 'INVOKE_DEFAULT',
# path_addon_pydeps='',
# path_addon_reqs='',
# )
log.debug('PyDeps: Analyzing Post-File Load')
ct.addon.prefs().on_addon_pydeps_changed(show_popup_if_deps_invalid=True)
def register() -> None:
"""Implements a multi-stage addon registration, which accounts for Python dependency management.
# Multi-Stage Registration
The trouble is that many classes in our addon might require Python dependencies.
## Stage 1: Barebones Addon
Many classes in our addon might require Python dependencies.
However, they may not yet be installed.
To solve this bootstrapping problem in a streamlined manner, we only **guarantee** the registration of a few key classes, including:
- `AddonPreferences`: The addon preferences provide an interface for the user to fix Python dependency problems, thereby triggering subsequent stages.
- `InstallPyDeps`: An operator that installs missing Python dependencies, using Blender's embeded `pip`.
- `UninstallPyDeps`: An operator that uninstalls Python dependencies.
**These classes provide just enough interface to help the user install the missing Python dependencies**.
## Stage 2: Declare Delayed Registration
We may not be able to register any classes that rely on Python dependencies.
However, we can use `registration.delay_registration()` to **delay the registration until it is determined that the Python dependencies are satisfied**.`
For now, we just pass a callback that will import + return a list of classes to register (`load_main_blclasses()`) when the time comes.
## Stage 3: Trigger "PyDeps Changed"
The addon preferences is responsible for storing (and exposing to the user) the path to the Python dependencies.
Thus, the addon preferences method `on_addon_pydeps_changed()` has the responsibility for checking when the dependencies are valid, and running the delayed registrations (and any other delayed setup) in response.
In general, `on_addon_pydeps_changed()` runs whenever the PyDeps path is changed, but it can also be run manually.
As the last part of this process, that's exactly what `register()` does: Runs `on_addon_pydeps_changed()` manually.
Depending on the addon preferences (which persist), one of two things can happen:
1. **Deps Satisfied**: The addon will load without issue: The just-declared "delayed registrations" will run immediately, and all is well.
2. **Deps Not Satisfied**: The user must take action to fix the conflicts due to Python dependencies, before the addon can load. **A popup will show to help the user do so.
Notes:
Called by Blender when enabling the addon.
"""
log.info('Commencing Registration of Addon: %s', ct.addon.NAME)
bpy.app.handlers.load_post.append(manage_pydeps)
# Register Barebones Addon
## Contains all no-dependency BLClasses:
## - Contains AddonPreferences.
## Contains all BLClasses from 'nodeps'.
registration.register_classes(BL_REGISTER_BEFORE_DEPS)
registration.register_hotkeys(BL_HOTKEYS_BEFORE_DEPS)
# Delay Complete Registration until DEPS_SATISFIED
registration.delay_registration_until(
registration.BLRegisterEvent.DepsSatisfied,
then_register_classes=load_main_blclasses,
then_register_hotkeys=load_main_blhotkeys,
)
# Trigger PyDeps Check
## Deps ARE OK: Delayed registration will trigger.
## Deps NOT OK: User must fix the pydeps, then trigger this method.
ct.addon.prefs().on_addon_pydeps_changed()
def unregister() -> None:
"""Unregisters anything that was registered by the addon.
Notes:
Run by Blender when disabling the addon.
This doesn't clean `sys.modules`.
To fully revert to Blender's state before the addon was in use (especially various import-related caches in the Python process), Blender must be restarted.
"""
log.info('Starting %s Unregister', ct.addon.NAME)
registration.unregister_classes()
registration.unregister_hotkeys()
registration.clear_delayed_registrations()
log.info('Finished %s Unregister', ct.addon.NAME)

View File

@ -0,0 +1,30 @@
# blender_maxwell
# Copyright (C) 2024 blender_maxwell Project Contributors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from . import geonodes
BL_REGISTER = [
*geonodes.BL_REGISTER,
]
BL_HOTKEYS = [
*geonodes.BL_HOTKEYS,
]
__all__ = [
'BL_REGISTER',
'BL_HOTKEYS',
]

View File

@ -1,5 +1,5 @@
# oscillode
# Copyright (C) 2024 oscillode Project Contributors
# blender_maxwell
# Copyright (C) 2024 blender_maxwell Project Contributors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
@ -21,8 +21,8 @@ from pathlib import Path
import bpy
from oscillode import contracts as ct
from oscillode.utils import logger
from blender_maxwell import contracts as ct
from blender_maxwell.utils import logger
log = logger.get(__name__)
@ -32,17 +32,17 @@ log = logger.get(__name__)
####################
# GeoNodes Paths
## Internal
GN_INTERNAL_PATH: Path = ct.addon.PATH_ASSETS / 'internal'
GN_INTERNAL_INPUTS_PATH: Path = GN_INTERNAL_PATH / 'input'
GN_INTERNAL_SOURCES_PATH: Path = GN_INTERNAL_PATH / 'source'
GN_INTERNAL_STRUCTURES_PATH: Path = GN_INTERNAL_PATH / 'structure'
GN_INTERNAL_MONITORS_PATH: Path = GN_INTERNAL_PATH / 'monitor'
GN_INTERNAL_SIMULATIONS_PATH: Path = GN_INTERNAL_PATH / 'simulation'
GN_INTERNAL_PATH = ct.addon.PATH_ASSETS / 'internal'
GN_INTERNAL_INPUTS_PATH = GN_INTERNAL_PATH / 'input'
GN_INTERNAL_SOURCES_PATH = GN_INTERNAL_PATH / 'source'
GN_INTERNAL_STRUCTURES_PATH = GN_INTERNAL_PATH / 'structure'
GN_INTERNAL_MONITORS_PATH = GN_INTERNAL_PATH / 'monitor'
GN_INTERNAL_SIMULATIONS_PATH = GN_INTERNAL_PATH / 'simulation'
## Structures
GN_STRUCTURES_PATH: Path = ct.addon.PATH_ASSETS / 'structures'
GN_STRUCTURES_PRIMITIVES_PATH: Path = GN_STRUCTURES_PATH / 'primitives'
GN_STRUCTURES_ARRAYS_PATH: Path = GN_STRUCTURES_PATH / 'arrays'
GN_STRUCTURES_PATH = ct.addon.PATH_ASSETS / 'structures'
GN_STRUCTURES_PRIMITIVES_PATH = GN_STRUCTURES_PATH / 'primitives'
GN_STRUCTURES_ARRAYS_PATH = GN_STRUCTURES_PATH / 'arrays'
class GeoNodes(enum.StrEnum):
@ -105,7 +105,7 @@ class GeoNodes(enum.StrEnum):
ArrayRing = 'array_ring'
@property
def dedicated_node_type(self) -> str: ## TODO: How to correlate to node_tree?
def dedicated_node_type(self) -> ct.BLImportMethod:
"""Deduces the denode type that implements a vendored GeoNodes tree (usually just "GeoNodes Structure").
Generally, "GeoNodes Structure' is the generic triangle-mesh node that can do everything.
@ -385,7 +385,7 @@ class GeoNodesToStructureNode(bpy.types.Operator):
####################
def invoke(
self, context: bpy.types.Context, _: bpy.types.Event
) -> ct.BLOperatorStatus:
) -> set[ct.BLOperatorStatus]:
"""Commences the drag-and-drop of a GeoNodes asset.
- Starts the modal timer, which listens for a mouse-release event.
@ -474,10 +474,10 @@ class GeoNodesToStructureNode(bpy.types.Operator):
## 3. We compute it manually, to avoid the jank.
node_location = get_view_location(
editor_region,
(
[
event.mouse_x - editor_region.x,
event.mouse_y - editor_region.y,
),
],
context.preferences.system.ui_scale,
)
@ -526,8 +526,8 @@ ASSET_LIB_SPECS: dict[str, Path] = {
}
@bpy.app.handlers.persistent # type: ignore[misc]
def initialize_asset_libraries(_: bpy.types.Scene) -> None:
@bpy.app.handlers.persistent
def initialize_asset_libraries(_: bpy.types.Scene):
"""Before loading a `.blend` file, ensure that the WindowManager properties relied on by NodeAssetPanel are available.
- Several asset libraries, defined under the global `ASSET_LIB_SPECS`, are added/replaced such that the name:path map is respected.
@ -580,11 +580,11 @@ def initialize_asset_libraries(_: bpy.types.Scene) -> None:
)
bpy.app.handlers.load_pre.append(initialize_asset_libraries)
BL_REGISTER = [
NodeAssetPanel,
GeoNodesToStructureNode,
]
BL_HANDLERS: ct.BLHandlers = ct.BLHandlers(load_pre=(initialize_asset_libraries,))
BL_KEYMAP_ITEMS: list[ct.BLKeymapItem] = []
BL_HOTKEYS = []

View File

@ -1,5 +1,5 @@
# oscillode
# Copyright (C) 2024 oscillode Project Contributors
# blender_maxwell
# Copyright (C) 2024 blender_maxwell Project Contributors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
@ -14,38 +14,30 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
"""Independent constants and types, which represent a kind of 'social contract' governing communication between all components of the addon."""
from . import addon
from .bl import (
BLClass,
BLColorRGBA,
BLEnumElement,
BLEnumID,
BLEventType,
BLEventValue,
BLIcon,
BLIconSet,
BLIDStruct,
BLImportMethod,
BLKeymapItem,
BLModifierType,
BLNodeTreeInterfaceID,
BLOperatorStatus,
BLPropFlag,
BLRegionType,
BLSpaceType,
KeymapItemDef,
ManagedObjName,
PresetName,
PropName,
SocketName,
)
from .bl_handlers import BLHandlers
from .bl_keymap import BLKeymapItem
from .icons import Icon
from .mobj_types import ManagedObjType
from .node_tree_types import (
NodeTreeType,
)
from .bl_types import BLEnumStrEnum
from .operator_types import (
OperatorType,
)
@ -59,8 +51,6 @@ __all__ = [
'BLColorRGBA',
'BLEnumElement',
'BLEnumID',
'BLEventType',
'BLEventValue',
'BLIcon',
'BLIconSet',
'BLIDStruct',
@ -74,15 +64,12 @@ __all__ = [
'BLSpaceType',
'KeymapItemDef',
'ManagedObjName',
'ManagedObjType',
'PresetName',
'PropName',
'SocketName',
'BLHandlers',
'Icon',
'BLEnumStrEnum',
'BLInstance',
'InstanceID',
'NodeTreeType',
'OperatorType',
'PanelType',
]

View File

@ -0,0 +1,109 @@
# blender_maxwell
# Copyright (C) 2024 blender_maxwell Project Contributors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import sys
import tomllib
from pathlib import Path
import bpy
import bpy_restrict_state
PATH_ADDON_ROOT = Path(__file__).resolve().parent.parent
with (PATH_ADDON_ROOT / 'pyproject.toml').open('rb') as f:
PROJ_SPEC = tomllib.load(f)
## bl_info is filled with PROJ_SPEC when packing the .zip.
NAME = PROJ_SPEC['project']['name']
VERSION = PROJ_SPEC['project']['version']
####################
# - Assets
####################
PATH_ASSETS = PATH_ADDON_ROOT / 'assets'
####################
# - PyDeps Info
####################
PATH_REQS = PATH_ADDON_ROOT / 'requirements.lock'
DEFAULT_PATH_DEPS = PATH_ADDON_ROOT / '.addon_dependencies'
DEFAULT_PATH_DEPS.mkdir(exist_ok=True)
## requirements.lock is written when packing the .zip.
## By default, the addon pydeps are kept in the addon dir.
ORIGINAL_SYS_PATH = sys.path.copy()
####################
# - Local Addon Cache
####################
DEFAULT_ADDON_CACHE = PATH_ADDON_ROOT / '.addon_cache'
DEFAULT_ADDON_CACHE.mkdir(exist_ok=True)
PIP_INSTALL_LOG = DEFAULT_ADDON_CACHE / 'pip_install.log'
####################
# - Dynamic Addon Information
####################
def is_loading() -> bool:
"""Checks whether the addon is currently loading.
While an addon is loading, `bpy.context` is temporarily very limited.
For example, operators can't run while the addon is loading.
By checking whether `bpy.context` is limited like this, we can determine whether the addon is currently loading.
Notes:
Since `bpy_restrict_state._RestrictContext` is a very internal thing, this function may be prone to breakage on Blender updates.
**Keep an eye out**!
Returns:
Whether the addon has been fully loaded, such that `bpy.context` is fully accessible.
"""
return isinstance(bpy.context, bpy_restrict_state._RestrictContext)
def operator(name: str, *operator_args, **operator_kwargs) -> None:
# Parse Operator Name
operator_namespace, operator_name = name.split('.')
if operator_namespace != NAME:
msg = f'Tried to call operator {operator_name}, but addon operators may only use the addon operator namespace "{operator_namespace}.<name>"'
raise RuntimeError(msg)
# Addon Not Loading: Run Operator
if not is_loading():
operator = getattr(getattr(bpy.ops, NAME), operator_name)
operator(*operator_args, **operator_kwargs)
else:
msg = f'Tried to call operator "{operator_name}" while addon is loading'
raise RuntimeError(msg)
def prefs() -> bpy.types.AddonPreferences | None:
if (addon := bpy.context.preferences.addons.get(NAME)) is None:
msg = 'Addon is not installed'
raise RuntimeError(msg)
return addon.preferences
####################
# - Logging Info
####################
DEFAULT_LOG_PATH = PATH_ADDON_ROOT / 'addon.log'
## By default, the addon file log writes to the addon dir.
## The initial .log_level contents are written when packing the .zip.
## Subsequent changes are managed by nodeps.utils.simple_logger.py.

View File

@ -1,5 +1,5 @@
# oscillode
# Copyright (C) 2024 oscillode Project Contributors
# blender_maxwell
# Copyright (C) 2024 blender_maxwell Project Contributors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
@ -14,8 +14,6 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
"""Explicit type annotations for Blender objects, making it easier to guarantee correctness in communications with Blender."""
import typing as typ
import bpy
@ -95,6 +93,7 @@ BLIDStruct: typ.TypeAlias = (
| bpy.types.WorkSpace
| bpy.types.World
)
BLKeymapItem: typ.TypeAlias = typ.Any ## TODO: Better Type
BLPropFlag: typ.TypeAlias = typ.Literal[
'HIDDEN',
'SKIP_SAVE',
@ -111,24 +110,6 @@ BLColorRGBA = tuple[float, float, float, float]
####################
# - Operators
####################
BLRegionType: typ.TypeAlias = typ.Literal[
'WINDOW',
'HEADER',
'CHANNELS',
'TEMPORARY',
'UI',
'TOOLS',
'TOOL_PROPS',
'ASSET_SHELF',
'ASSET_SHELF_HEADER',
'PREVIEW',
'HUD',
'NAVIGATION_BAR',
'EXECUTE',
'FOOTER',
'TOOL_HEADER',
'XR',
]
BLSpaceType: typ.TypeAlias = typ.Literal[
'EMPTY',
'VIEW_3D',
@ -150,151 +131,32 @@ BLSpaceType: typ.TypeAlias = typ.Literal[
'SPREADSHEET',
'PREFERENCES',
]
BLRegionType: typ.TypeAlias = typ.Literal[
'WINDOW',
'HEADER',
'CHANNELS',
'TEMPORARY',
'UI',
'TOOLS',
'TOOL_PROPS',
'ASSET_SHELF',
'ASSET_SHELF_HEADER',
'PREVIEW',
'HUD',
'NAVIGATION_BAR',
'EXECUTE',
'FOOTER',
'TOOL_HEADER',
'XR',
]
BLOperatorStatus: typ.TypeAlias = set[
typ.Literal['RUNNING_MODAL', 'CANCELLED', 'FINISHED', 'PASS_THROUGH', 'INTERFACE']
]
####################
# - Operators
####################
## TODO: Write the rest in.
BLEventType: typ.TypeAlias = typ.Literal[
'NONE',
'LEFTMOUSE',
'MIDDLEMOUSE',
'RIGHTMOUSE',
'BUTTON4MOUSE',
'BUTTON5MOUSE',
'BUTTON6MOUSE',
'BUTTON7MOUSE',
'PEN',
'ERASOR',
'MOUSEMOVE',
'INBETWEEN_MOUSEMOVE',
'TRACKPADPAN',
'TRACKPADZOOM',
'MOUSEROTATE',
'MOUSESMARTZOOM',
'WHEELUPMOUSE',
'WHEELDOWNMOUSE',
'WHEELINMOUSE',
'WHEELOUTMOUSE',
'A',
'B',
'C',
'D',
'E',
'F',
'G',
'H',
'I',
'J',
'K',
'L',
'M',
'N',
'O',
'P',
'Q',
'R',
'S',
'T',
'U',
'V',
'W',
'X',
'Y',
'Z',
'ZERO',
'ONE',
'TWO',
'THREE',
'FOUR',
'FIVE',
'SIX',
'SEVEN',
'EIGHT',
'NINE',
'LEFT_CTRL',
'LEFT_ALT',
'LEFT_SHIFT',
'RIGHT_ALT',
'RIGHT_CTRL',
'RIGHT_SHIFT',
'ESC',
'TAB',
'RET', ## Enter
'SPACE',
'LINE_FEED',
'BACK_SPACE',
'DEL',
'SEMI_COLON',
'PERIOD',
'COMMA',
'QUOTE',
'ACCENT_GRAVE',
'MINUS',
'PLUS',
'SLASH',
'BACK_SLASH',
'EQUAL',
'LEFT_BRACKET',
'RIGHT_BRACKET',
'LEFT_ARROW',
'DOWN_ARROW',
'RIGHT_ARROW',
'UP_ARROW',
'NUMPAD_0',
'NUMPAD_1',
'NUMPAD_2',
'NUMPAD_3',
'NUMPAD_4',
'NUMPAD_5',
'NUMPAD_6',
'NUMPAD_7',
'NUMPAD_8',
'NUMPAD_9',
'NUMPAD_PERIOD',
'NUMPAD_SLASH',
'NUMPAD_ASTERIX',
'NUMPAD_MINUS',
'NUMPAD_PLUS',
'NUMPAD_ENTER',
'F1',
'F2',
'F3',
'F4',
'F5',
'F6',
'F7',
'F8',
'F9',
'F10',
'F11',
'F12',
'PAUSE',
'INSERT',
'HOME',
'PAGE_UP',
'PAGE_DOWN',
'END',
'MEDIA_PLAY',
'MEDIA_STOP',
'MEDIA_FIRST',
'MEDIA_LAST',
]
BLEventValue: typ.TypeAlias = typ.Literal[
'ANY',
'PRESS',
'RELEASE',
'CLICK',
'DOUBLE_CLICK',
'CLICK_DRAG',
'NOTHING',
]
####################
# - Addon Types
####################
KeymapItemDef: typ.TypeAlias = typ.Any
ManagedObjName = str
####################

View File

@ -0,0 +1,28 @@
# blender_maxwell
# Copyright (C) 2024 blender_maxwell Project Contributors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import typing as typ
####################
# - Blender Enum (w/EnumProperty support)
####################
class BLEnumStrEnum(typ.Protocol):
@staticmethod
def to_name(value: typ.Self) -> str: ...
@staticmethod
def to_icon(value: typ.Self) -> str: ...

View File

@ -1,5 +1,5 @@
# oscillode
# Copyright (C) 2024 oscillode Project Contributors
# blender_maxwell
# Copyright (C) 2024 blender_maxwell Project Contributors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
@ -14,12 +14,11 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
"""Provides identifiers for Blender operators defined by this addon."""
"""Defines Operator Types as an enum, making it easy for any part of the addon to refer to any operator."""
import enum
from oscillode.utils import blender_type_enum
from ..nodeps.utils import blender_type_enum
from .addon import NAME as ADDON_NAME

View File

@ -1,5 +1,5 @@
# oscillode
# Copyright (C) 2024 oscillode Project Contributors
# blender_maxwell
# Copyright (C) 2024 blender_maxwell Project Contributors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
@ -18,7 +18,7 @@
import enum
from oscillode.utils import blender_type_enum
from blender_maxwell.nodeps.utils import blender_type_enum
from .addon import NAME as ADDON_NAME

View File

@ -0,0 +1,21 @@
# blender_maxwell
# Copyright (C) 2024 blender_maxwell Project Contributors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from . import maxwell_sim_nodes
BL_REGISTER = [
*maxwell_sim_nodes.BL_REGISTER,
]

View File

@ -0,0 +1,24 @@
# blender_maxwell
# Copyright (C) 2024 blender_maxwell Project Contributors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from . import categories, node_tree, nodes, sockets
BL_REGISTER = [
*sockets.BL_REGISTER,
*node_tree.BL_REGISTER,
*nodes.BL_REGISTER,
*categories.BL_REGISTER,
]

View File

@ -1,19 +1,3 @@
# oscillode
# Copyright (C) 2024 oscillode Project Contributors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# blender_maxwell
# Copyright (C) 2024 blender_maxwell Project Contributors
#
@ -38,6 +22,7 @@ Attributes:
"""
import bpy
from blender_maxwell.utils import logger as _logger
from . import contracts as ct
@ -45,8 +30,6 @@ from . import sockets
log = _logger.get(__name__)
## TODO: Coordinate w/refactor of managed modifiers; for example, the contents of this file would be ideally specified as the implementation of a Protocol, for the particular case of this node tree.
####################
# - Blender -> Socket Def(s)

View File

@ -1,19 +1,3 @@
# oscillode
# Copyright (C) 2024 oscillode Project Contributors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# blender_maxwell
# Copyright (C) 2024 blender_maxwell Project Contributors
#
@ -38,9 +22,6 @@ import nodeitems_utils
from . import contracts as ct
from .nodes import BL_NODES
## TODO: Completely refactor this file, and rename it to reflect that it doesn't define or implement any categories - it simply, dumbly, implements the menu.
## - Actually; we could delete this file by refactoring it, implementing the logic in a utils/ module, then running the dangling registration as a rote-registration matter in __init__.py.
DYNAMIC_SUBMENU_REGISTRATIONS = []
@ -120,7 +101,7 @@ BL_REGISTER = [*DYNAMIC_SUBMENU_REGISTRATIONS] ## Must be run after, right now.
def menu_draw(self, context):
if context.space_data.tree_type == ct.NodeTreeType.MaxwellSim.value:
if context.space_data.tree_type == ct.TreeType.MaxwellSim.value:
for nodeitem_or_submenu in BL_NODE_CATEGORIES:
if isinstance(nodeitem_or_submenu, str):
submenu_id = nodeitem_or_submenu

View File

@ -1,19 +1,3 @@
# oscillode
# Copyright (C) 2024 oscillode Project Contributors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# blender_maxwell
# Copyright (C) 2024 blender_maxwell Project Contributors
#
@ -31,8 +15,6 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from blender_maxwell.contracts import (
UNITS_BLENDER,
UNITS_TIDY3D,
BLClass,
BLColorRGBA,
BLEnumElement,
@ -47,11 +29,8 @@ from blender_maxwell.contracts import (
BLPropFlag,
BLRegionType,
BLSpaceType,
Icon,
KeymapItemDef,
ManagedObjName,
ManagedObjType,
NodeTreeType,
OperatorType,
PanelType,
PresetName,
@ -77,6 +56,8 @@ from .flow_kinds import (
ValueFlow,
)
from .flow_signals import FlowSignal
from .icons import Icon
from .mobj_types import ManagedObjType
from .node_types import NodeType
from .sim_types import (
BoundCondType,
@ -93,6 +74,8 @@ from .sim_types import (
)
from .socket_colors import SOCKET_COLORS
from .socket_types import SocketType
from .tree_types import TreeType
from .unit_systems import UNITS_BLENDER, UNITS_TIDY3D
__all__ = [
'BLClass',
@ -109,17 +92,16 @@ __all__ = [
'BLPropFlag',
'BLRegionType',
'BLSpaceType',
'Icon',
'KeymapItemDef',
'ManagedObjName',
'ManagedObjType',
'NodeTreeType',
'OperatorType',
'PanelType',
'PresetName',
'PropName',
'SocketName',
'addon',
'Icon',
'TreeType',
'SocketType',
'SOCKET_COLORS',
'SOCKET_SHAPES',
@ -141,6 +123,7 @@ __all__ = [
'manual_amp_time',
'NodeCategory',
'NODE_CAT_LABELS',
'ManagedObjType',
'FlowEvent',
'ArrayFlow',
'CapabilitiesFlow',

View File

@ -1,5 +1,5 @@
# oscillode
# Copyright (C) 2024 oscillode Project Contributors
# blender_maxwell
# Copyright (C) 2024 blender_maxwell Project Contributors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
@ -14,7 +14,6 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import enum
import functools
import typing as typ
@ -24,6 +23,8 @@ import bpy
import jax
import numpy as np
import pydantic as pyd
import sympy as sp
from blender_maxwell.utils import logger
from blender_maxwell.utils import sympy_extra as spux

View File

@ -1,19 +1,3 @@
# oscillode
# Copyright (C) 2024 oscillode Project Contributors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# blender_maxwell
# Copyright (C) 2024 blender_maxwell Project Contributors
#
@ -30,8 +14,6 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
## TODO: Unify w/category_types.py
from .category_types import NodeCategory as NC # noqa: N817
NODE_CAT_LABELS = {

View File

@ -1,19 +1,3 @@
# oscillode
# Copyright (C) 2024 oscillode Project Contributors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# blender_maxwell
# Copyright (C) 2024 blender_maxwell Project Contributors
#

View File

@ -1,5 +1,5 @@
# oscillode
# Copyright (C) 2024 oscillode Project Contributors
# blender_maxwell
# Copyright (C) 2024 blender_maxwell Project Contributors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by

View File

@ -1,5 +1,5 @@
# oscillode
# Copyright (C) 2024 oscillode Project Contributors
# blender_maxwell
# Copyright (C) 2024 blender_maxwell Project Contributors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by

View File

@ -1,5 +1,5 @@
# oscillode
# Copyright (C) 2024 oscillode Project Contributors
# blender_maxwell
# Copyright (C) 2024 blender_maxwell Project Contributors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
@ -22,13 +22,14 @@ import typing as typ
import jax
import jax.numpy as jnp
import jaxtyping as jtyp
import numpy as np
import pydantic as pyd
import sympy as sp
from oscillode.utils import logger
from oscillode.utils import sympy_extra as spux
from oscillode.utils.jaxarray import JaxArrayBytes
from oscillode.utils.lru_method import method_lru
from blender_maxwell.utils import logger
from blender_maxwell.utils import sympy_extra as spux
from blender_maxwell.utils.jaxarray import JaxArrayBytes
from blender_maxwell.utils.lru_method import method_lru
log = logger.get(__name__)

Some files were not shown because too many files have changed in this diff Show More