Compare commits
No commits in common. "568fc449e818da3e06e799c9789dff7f8c2eaf36" and "e1f11f6d681e0529d7797247c9fd9ab2c5786197" have entirely different histories.
568fc449e8
...
e1f11f6d68
14
TODO.md
14
TODO.md
|
@ -504,13 +504,13 @@ Unreported:
|
||||||
- We found the translation callback! https://projects.blender.org/blender/blender/commit/8564e03cdf59fb2a71d545e81871411b82f561d9
|
- We found the translation callback! https://projects.blender.org/blender/blender/commit/8564e03cdf59fb2a71d545e81871411b82f561d9
|
||||||
- This can update the node center!!
|
- This can update the node center!!
|
||||||
|
|
||||||
- [x] Optimize the `DataChanged` invalidator.
|
- [ ] Optimize the `DataChanged` invalidator.
|
||||||
- [ ] Optimize unit stripping.
|
- [ ] Optimize unit stripping.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Keyed Cache
|
## Keyed Cache
|
||||||
- [x] Implement `bl_cache.KeyedCache` for, especially, abstracting the caches underlying the input and output sockets.
|
- [ ] Implement `bl_cache.KeyedCache` for, especially, abstracting the caches underlying the input and output sockets.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -546,12 +546,12 @@ We need support for arbitrary objects, but still backed by the persistance seman
|
||||||
- [ ] Similarly, a field method that gets the 'blfield__' prop data as a dictionary.
|
- [ ] Similarly, a field method that gets the 'blfield__' prop data as a dictionary.
|
||||||
|
|
||||||
### Parallel Features
|
### Parallel Features
|
||||||
- [x] Move serialization work to a `utils`.
|
- [ ] Move serialization work to a `utils`.
|
||||||
- [x] Also make ENCODER a function that can shortcut the easy cases.
|
- [ ] Also make ENCODER a function that can shortcut the easy cases.
|
||||||
- [x] For serializeability, let the encoder/decoder be able to make use of an optional `.msgspec_encodable()` and similar decoder respectively, and add support for these in the ENCODER/DECODER functions.
|
- [ ] For serializeability, let the encoder/decoder be able to make use of an optional `.msgspec_encodable()` and similar decoder respectively, and add support for these in the ENCODER/DECODER functions.
|
||||||
- [x] Define a superclass for `SocketDef` and make everyone inherit from it
|
- [ ] Define a superclass for `SocketDef` and make everyone inherit from it
|
||||||
- [ ] Collect with a `BL_SOCKET_DEFS` object, instead of manually from `__init__.py`s
|
- [ ] Collect with a `BL_SOCKET_DEFS` object, instead of manually from `__init__.py`s
|
||||||
- [x] Add support for `.msgspec_*()` methods, so that we remove the dependency on sockets from the serialization module.
|
- [ ] Add support for `.msgspec_*()` methods, so that we remove the dependency on sockets from the serialization module.
|
||||||
|
|
||||||
### Sweeping Features
|
### Sweeping Features
|
||||||
- [ ] Replace all raw Blender properties with `BLField`.
|
- [ ] Replace all raw Blender properties with `BLField`.
|
||||||
|
|
|
@ -5,8 +5,14 @@ import inspect
|
||||||
import typing as typ
|
import typing as typ
|
||||||
|
|
||||||
import bpy
|
import bpy
|
||||||
|
import msgspec
|
||||||
|
import sympy as sp
|
||||||
|
import sympy.physics.units as spu
|
||||||
|
|
||||||
from ...utils import logger, serialize
|
from ...utils import extra_sympy_units as spux
|
||||||
|
from ...utils import logger
|
||||||
|
from . import contracts as ct
|
||||||
|
from . import managed_objs, sockets
|
||||||
|
|
||||||
log = logger.get(__name__)
|
log = logger.get(__name__)
|
||||||
|
|
||||||
|
@ -33,12 +39,149 @@ class BLInstance(typ.Protocol):
|
||||||
) -> None: ...
|
) -> None: ...
|
||||||
|
|
||||||
|
|
||||||
PropGetMethod: typ.TypeAlias = typ.Callable[
|
EncodableValue: typ.TypeAlias = typ.Any ## msgspec-compatible
|
||||||
[BLInstance], serialize.NaivelyEncodableType
|
PropGetMethod: typ.TypeAlias = typ.Callable[[BLInstance], EncodableValue]
|
||||||
]
|
PropSetMethod: typ.TypeAlias = typ.Callable[[BLInstance, EncodableValue], None]
|
||||||
PropSetMethod: typ.TypeAlias = typ.Callable[
|
|
||||||
[BLInstance, serialize.NaivelyEncodableType], None
|
####################
|
||||||
]
|
# - (De)Serialization
|
||||||
|
####################
|
||||||
|
EncodedComplex: typ.TypeAlias = tuple[float, float] | list[float, float]
|
||||||
|
EncodedSympy: typ.TypeAlias = str
|
||||||
|
EncodedManagedObj: typ.TypeAlias = tuple[str, str] | list[str, str]
|
||||||
|
EncodedPydanticModel: typ.TypeAlias = tuple[str, str] | list[str, str]
|
||||||
|
|
||||||
|
|
||||||
|
def _enc_hook(obj: typ.Any) -> EncodableValue:
|
||||||
|
"""Translates types not natively supported by `msgspec`, to an encodable form supported by `msgspec`.
|
||||||
|
|
||||||
|
Parameters:
|
||||||
|
obj: The object of arbitrary type to transform into an encodable value.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
A value encodable by `msgspec`.
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
NotImplementedError: When the type transformation hasn't been implemented.
|
||||||
|
"""
|
||||||
|
if isinstance(obj, complex):
|
||||||
|
return (obj.real, obj.imag)
|
||||||
|
if isinstance(obj, sp.Basic | sp.MatrixBase | sp.Expr | spu.Quantity):
|
||||||
|
return sp.srepr(obj)
|
||||||
|
if isinstance(obj, managed_objs.ManagedObj):
|
||||||
|
return (obj.name, obj.__class__.__name__)
|
||||||
|
if isinstance(obj, ct.schemas.SocketDef):
|
||||||
|
return (obj.model_dump(), obj.__class__.__name__)
|
||||||
|
|
||||||
|
msg = f'Can\'t encode "{obj}" of type {type(obj)}'
|
||||||
|
raise NotImplementedError(msg)
|
||||||
|
|
||||||
|
|
||||||
|
def _dec_hook(_type: type, obj: EncodableValue) -> typ.Any:
|
||||||
|
"""Translates the `msgspec`-encoded form of an object back to its true form.
|
||||||
|
|
||||||
|
Parameters:
|
||||||
|
_type: The type to transform the `msgspec`-encoded object back into.
|
||||||
|
obj: The encoded object of to transform back into an encodable value.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
A value encodable by `msgspec`.
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
NotImplementedError: When the type transformation hasn't been implemented.
|
||||||
|
"""
|
||||||
|
if _type is complex and isinstance(obj, EncodedComplex):
|
||||||
|
return complex(obj[0], obj[1])
|
||||||
|
if (
|
||||||
|
_type is sp.Basic
|
||||||
|
and isinstance(obj, EncodedSympy)
|
||||||
|
or _type is sp.Expr
|
||||||
|
and isinstance(obj, EncodedSympy)
|
||||||
|
or _type is sp.MatrixBase
|
||||||
|
and isinstance(obj, EncodedSympy)
|
||||||
|
or _type is spu.Quantity
|
||||||
|
and isinstance(obj, EncodedSympy)
|
||||||
|
):
|
||||||
|
return sp.sympify(obj).subs(spux.ALL_UNIT_SYMBOLS)
|
||||||
|
if (
|
||||||
|
_type is managed_objs.ManagedBLMesh
|
||||||
|
and isinstance(obj, EncodedManagedObj)
|
||||||
|
or _type is managed_objs.ManagedBLImage
|
||||||
|
and isinstance(obj, EncodedManagedObj)
|
||||||
|
or _type is managed_objs.ManagedBLModifier
|
||||||
|
and isinstance(obj, EncodedManagedObj)
|
||||||
|
):
|
||||||
|
return {
|
||||||
|
'ManagedBLMesh': managed_objs.ManagedBLMesh,
|
||||||
|
'ManagedBLImage': managed_objs.ManagedBLImage,
|
||||||
|
'ManagedBLModifier': managed_objs.ManagedBLModifier,
|
||||||
|
}[obj[1]](obj[0])
|
||||||
|
if _type is ct.schemas.SocketDef:
|
||||||
|
return getattr(sockets, obj[1])(**obj[0])
|
||||||
|
|
||||||
|
msg = f'Can\'t decode "{obj}" to type {type(obj)}'
|
||||||
|
raise NotImplementedError(msg)
|
||||||
|
|
||||||
|
|
||||||
|
ENCODER = msgspec.json.Encoder(enc_hook=_enc_hook, order='deterministic')
|
||||||
|
|
||||||
|
_DECODERS: dict[type, msgspec.json.Decoder] = {
|
||||||
|
complex: msgspec.json.Decoder(type=complex, dec_hook=_dec_hook),
|
||||||
|
sp.Basic: msgspec.json.Decoder(type=sp.Basic, dec_hook=_dec_hook),
|
||||||
|
sp.Expr: msgspec.json.Decoder(type=sp.Expr, dec_hook=_dec_hook),
|
||||||
|
sp.MatrixBase: msgspec.json.Decoder(type=sp.MatrixBase, dec_hook=_dec_hook),
|
||||||
|
spu.Quantity: msgspec.json.Decoder(type=spu.Quantity, dec_hook=_dec_hook),
|
||||||
|
managed_objs.ManagedBLMesh: msgspec.json.Decoder(
|
||||||
|
type=managed_objs.ManagedBLMesh,
|
||||||
|
dec_hook=_dec_hook,
|
||||||
|
),
|
||||||
|
managed_objs.ManagedBLImage: msgspec.json.Decoder(
|
||||||
|
type=managed_objs.ManagedBLImage,
|
||||||
|
dec_hook=_dec_hook,
|
||||||
|
),
|
||||||
|
managed_objs.ManagedBLModifier: msgspec.json.Decoder(
|
||||||
|
type=managed_objs.ManagedBLModifier,
|
||||||
|
dec_hook=_dec_hook,
|
||||||
|
),
|
||||||
|
# managed_objs.ManagedObj: msgspec.json.Decoder(
|
||||||
|
# type=managed_objs.ManagedObj, dec_hook=_dec_hook
|
||||||
|
# ), ## Doesn't work b/c unions are not explicit
|
||||||
|
ct.schemas.SocketDef: msgspec.json.Decoder(
|
||||||
|
type=ct.schemas.SocketDef,
|
||||||
|
dec_hook=_dec_hook,
|
||||||
|
),
|
||||||
|
}
|
||||||
|
_DECODER_FALLBACK: msgspec.json.Decoder = msgspec.json.Decoder(dec_hook=_dec_hook)
|
||||||
|
|
||||||
|
|
||||||
|
@functools.cache
|
||||||
|
def DECODER(_type: type) -> msgspec.json.Decoder: # noqa: N802
|
||||||
|
"""Retrieve a suitable `msgspec.json.Decoder` by-type.
|
||||||
|
|
||||||
|
Parameters:
|
||||||
|
_type: The type to retrieve a decoder for.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
A suitable decoder.
|
||||||
|
"""
|
||||||
|
if (decoder := _DECODERS.get(_type)) is not None:
|
||||||
|
return decoder
|
||||||
|
|
||||||
|
return _DECODER_FALLBACK
|
||||||
|
|
||||||
|
|
||||||
|
def decode_any(_type: type, obj: str) -> typ.Any:
|
||||||
|
naive_decode = DECODER(_type).decode(obj)
|
||||||
|
if _type == dict[str, ct.schemas.SocketDef]:
|
||||||
|
return {
|
||||||
|
socket_name: getattr(sockets, socket_def_list[1])(**socket_def_list[0])
|
||||||
|
for socket_name, socket_def_list in naive_decode.items()
|
||||||
|
}
|
||||||
|
|
||||||
|
log.critical(
|
||||||
|
'Naive Decode of "%s" to "%s" (%s)', str(obj), str(naive_decode), str(_type)
|
||||||
|
)
|
||||||
|
return naive_decode
|
||||||
|
|
||||||
|
|
||||||
####################
|
####################
|
||||||
|
@ -67,7 +210,7 @@ class KeyedCache:
|
||||||
self,
|
self,
|
||||||
func: typ.Callable,
|
func: typ.Callable,
|
||||||
exclude: set[str],
|
exclude: set[str],
|
||||||
encode: set[str],
|
serialize: set[str],
|
||||||
):
|
):
|
||||||
# Function Information
|
# Function Information
|
||||||
self.func: typ.Callable = func
|
self.func: typ.Callable = func
|
||||||
|
@ -76,7 +219,7 @@ class KeyedCache:
|
||||||
# Arg -> Key Information
|
# Arg -> Key Information
|
||||||
self.exclude: set[str] = exclude
|
self.exclude: set[str] = exclude
|
||||||
self.include: set[str] = set(self.func_sig.parameters.keys()) - exclude
|
self.include: set[str] = set(self.func_sig.parameters.keys()) - exclude
|
||||||
self.encode: set[str] = encode
|
self.serialize: set[str] = serialize
|
||||||
|
|
||||||
# Cache Information
|
# Cache Information
|
||||||
self.key_schema: tuple[str, ...] = tuple(
|
self.key_schema: tuple[str, ...] = tuple(
|
||||||
|
@ -104,8 +247,8 @@ class KeyedCache:
|
||||||
[
|
[
|
||||||
(
|
(
|
||||||
arg_value
|
arg_value
|
||||||
if arg_name not in self.encode
|
if arg_name not in self.serialize
|
||||||
else serialize.encode(arg_value)
|
else ENCODER.encode(arg_value)
|
||||||
)
|
)
|
||||||
for arg_name, arg_value in arguments.items()
|
for arg_name, arg_value in arguments.items()
|
||||||
if arg_name in self.include
|
if arg_name in self.include
|
||||||
|
@ -155,8 +298,8 @@ class KeyedCache:
|
||||||
|
|
||||||
# Compute Keys to Invalidate
|
# Compute Keys to Invalidate
|
||||||
arguments_hashable = {
|
arguments_hashable = {
|
||||||
arg_name: serialize.encode(arg_value)
|
arg_name: ENCODER.encode(arg_value)
|
||||||
if arg_name in self.encode and arg_name not in wildcard_arguments
|
if arg_name in self.serialize and arg_name not in wildcard_arguments
|
||||||
else arg_value
|
else arg_value
|
||||||
for arg_name, arg_value in arguments.items()
|
for arg_name, arg_value in arguments.items()
|
||||||
}
|
}
|
||||||
|
@ -170,12 +313,12 @@ class KeyedCache:
|
||||||
cache.pop(key)
|
cache.pop(key)
|
||||||
|
|
||||||
|
|
||||||
def keyed_cache(exclude: set[str], encode: set[str] = frozenset()) -> typ.Callable:
|
def keyed_cache(exclude: set[str], serialize: set[str] = frozenset()) -> typ.Callable:
|
||||||
def decorator(func: typ.Callable) -> typ.Callable:
|
def decorator(func: typ.Callable) -> typ.Callable:
|
||||||
return KeyedCache(
|
return KeyedCache(
|
||||||
func,
|
func,
|
||||||
exclude=exclude,
|
exclude=exclude,
|
||||||
encode=encode,
|
serialize=serialize,
|
||||||
)
|
)
|
||||||
|
|
||||||
return decorator
|
return decorator
|
||||||
|
@ -221,6 +364,9 @@ class CachedBLProperty:
|
||||||
inspect.signature(getter_method).return_annotation if persist else None
|
inspect.signature(getter_method).return_annotation if persist else None
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Check Non-Empty Type Annotation
|
||||||
|
## For now, just presume that all types can be encoded/decoded.
|
||||||
|
|
||||||
# Check Non-Empty Type Annotation
|
# Check Non-Empty Type Annotation
|
||||||
## For now, just presume that all types can be encoded/decoded.
|
## For now, just presume that all types can be encoded/decoded.
|
||||||
if self._type is not None and self._type is inspect.Signature.empty:
|
if self._type is not None and self._type is inspect.Signature.empty:
|
||||||
|
@ -282,7 +428,7 @@ class CachedBLProperty:
|
||||||
self._persist
|
self._persist
|
||||||
and (encoded_value := getattr(bl_instance, self._bl_prop_name)) != ''
|
and (encoded_value := getattr(bl_instance, self._bl_prop_name)) != ''
|
||||||
):
|
):
|
||||||
value = serialize.decode(self._type, encoded_value)
|
value = decode_any(self._type, encoded_value)
|
||||||
cache_nopersist[self._bl_prop_name] = value
|
cache_nopersist[self._bl_prop_name] = value
|
||||||
return value
|
return value
|
||||||
|
|
||||||
|
@ -293,7 +439,7 @@ class CachedBLProperty:
|
||||||
cache_nopersist[self._bl_prop_name] = value
|
cache_nopersist[self._bl_prop_name] = value
|
||||||
if self._persist:
|
if self._persist:
|
||||||
setattr(
|
setattr(
|
||||||
bl_instance, self._bl_prop_name, serialize.encode(value).decode('utf-8')
|
bl_instance, self._bl_prop_name, ENCODER.encode(value).decode('utf-8')
|
||||||
)
|
)
|
||||||
return value
|
return value
|
||||||
|
|
||||||
|
@ -465,7 +611,7 @@ class BLField:
|
||||||
raise TypeError(msg)
|
raise TypeError(msg)
|
||||||
|
|
||||||
# Define Blender Property (w/Update Sync)
|
# Define Blender Property (w/Update Sync)
|
||||||
encoded_default_value = serialize.encode(self._default_value).decode('utf-8')
|
encoded_default_value = ENCODER.encode(self._default_value).decode('utf-8')
|
||||||
log.debug(
|
log.debug(
|
||||||
'%s set to StringProperty w/default "%s" and no_update="%s"',
|
'%s set to StringProperty w/default "%s" and no_update="%s"',
|
||||||
bl_attr_name,
|
bl_attr_name,
|
||||||
|
@ -486,14 +632,14 @@ class BLField:
|
||||||
## 2. Retrieve bpy.props.StringProperty string.
|
## 2. Retrieve bpy.props.StringProperty string.
|
||||||
## 3. Decode using annotated type.
|
## 3. Decode using annotated type.
|
||||||
def getter(_self: BLInstance) -> AttrType:
|
def getter(_self: BLInstance) -> AttrType:
|
||||||
return serialize.decode(AttrType, getattr(_self, bl_attr_name))
|
return decode_any(AttrType, getattr(_self, bl_attr_name))
|
||||||
|
|
||||||
## Setter:
|
## Setter:
|
||||||
## 1. Initialize bpy.props.StringProperty to Default (if undefined).
|
## 1. Initialize bpy.props.StringProperty to Default (if undefined).
|
||||||
## 3. Encode value (implicitly using the annotated type).
|
## 3. Encode value (implicitly using the annotated type).
|
||||||
## 2. Set bpy.props.StringProperty string.
|
## 2. Set bpy.props.StringProperty string.
|
||||||
def setter(_self: BLInstance, value: AttrType) -> None:
|
def setter(_self: BLInstance, value: AttrType) -> None:
|
||||||
encoded_value = serialize.encode(value).decode('utf-8')
|
encoded_value = ENCODER.encode(value).decode('utf-8')
|
||||||
log.debug(
|
log.debug(
|
||||||
'Writing BLField attr "%s" w/encoded value: %s',
|
'Writing BLField attr "%s" w/encoded value: %s',
|
||||||
bl_attr_name,
|
bl_attr_name,
|
||||||
|
|
|
@ -132,7 +132,7 @@ def _socket_def_from_bl_socket(
|
||||||
|
|
||||||
def socket_def_from_bl_socket(
|
def socket_def_from_bl_socket(
|
||||||
bl_interface_socket: bpy.types.NodeTreeInterfaceSocket,
|
bl_interface_socket: bpy.types.NodeTreeInterfaceSocket,
|
||||||
) -> sockets.base.SocketDef:
|
) -> ct.schemas.SocketDef:
|
||||||
"""Computes an appropriate (no-arg) SocketDef from the given `bl_interface_socket`, by parsing it."""
|
"""Computes an appropriate (no-arg) SocketDef from the given `bl_interface_socket`, by parsing it."""
|
||||||
return _socket_def_from_bl_socket(
|
return _socket_def_from_bl_socket(
|
||||||
bl_interface_socket.description, bl_interface_socket.bl_socket_idname
|
bl_interface_socket.description, bl_interface_socket.bl_socket_idname
|
||||||
|
|
|
@ -65,6 +65,11 @@ from .data_flows import (
|
||||||
)
|
)
|
||||||
from .data_flow_actions import DataFlowAction
|
from .data_flow_actions import DataFlowAction
|
||||||
|
|
||||||
|
####################
|
||||||
|
# - Schemas
|
||||||
|
####################
|
||||||
|
from . import schemas
|
||||||
|
|
||||||
####################
|
####################
|
||||||
# - Export
|
# - Export
|
||||||
####################
|
####################
|
||||||
|
@ -98,4 +103,5 @@ __all__ = [
|
||||||
'LazyDataValueRange',
|
'LazyDataValueRange',
|
||||||
'LazyDataValueSpectrum',
|
'LazyDataValueSpectrum',
|
||||||
'DataFlowAction',
|
'DataFlowAction',
|
||||||
|
'schemas',
|
||||||
]
|
]
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import enum
|
||||||
import pydantic as pyd
|
import pydantic as pyd
|
||||||
import typing_extensions as pytypes_ext
|
import typing_extensions as pytypes_ext
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
from .managed_obj import ManagedObj
|
||||||
|
from .managed_obj_def import ManagedObjDef
|
||||||
|
from .preset_def import PresetDef
|
||||||
|
from .socket_def import SocketDef
|
||||||
|
|
||||||
|
__all__ = [
|
||||||
|
'SocketDef',
|
||||||
|
'ManagedObj',
|
||||||
|
'ManagedObjDef',
|
||||||
|
'PresetDef',
|
||||||
|
]
|
|
@ -0,0 +1,22 @@
|
||||||
|
import typing as typ
|
||||||
|
|
||||||
|
from ..bl import ManagedObjName
|
||||||
|
from ..managed_obj_type import ManagedObjType
|
||||||
|
|
||||||
|
|
||||||
|
class ManagedObj(typ.Protocol):
|
||||||
|
managed_obj_type: ManagedObjType
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
name: ManagedObjName,
|
||||||
|
): ...
|
||||||
|
|
||||||
|
@property
|
||||||
|
def name(self) -> str: ...
|
||||||
|
@name.setter
|
||||||
|
def name(self, value: str): ...
|
||||||
|
|
||||||
|
def free(self): ...
|
||||||
|
|
||||||
|
def bl_select(self): ...
|
|
@ -0,0 +1,10 @@
|
||||||
|
import typing as typ
|
||||||
|
|
||||||
|
import pydantic as pyd
|
||||||
|
|
||||||
|
from .managed_obj import ManagedObj
|
||||||
|
|
||||||
|
|
||||||
|
class ManagedObjDef(pyd.BaseModel):
|
||||||
|
mk: typ.Callable[[str], ManagedObj]
|
||||||
|
name_prefix: str = ''
|
|
@ -2,10 +2,10 @@ import typing as typ
|
||||||
|
|
||||||
import pydantic as pyd
|
import pydantic as pyd
|
||||||
|
|
||||||
from .. import contracts as ct
|
from ..bl import PresetName, SocketName
|
||||||
|
|
||||||
|
|
||||||
class PresetDef(pyd.BaseModel):
|
class PresetDef(pyd.BaseModel):
|
||||||
label: ct.PresetName
|
label: PresetName
|
||||||
description: str
|
description: str
|
||||||
values: dict[ct.SocketName, typ.Any]
|
values: dict[SocketName, typ.Any]
|
|
@ -0,0 +1,12 @@
|
||||||
|
import typing as typ
|
||||||
|
|
||||||
|
import bpy
|
||||||
|
|
||||||
|
from ..socket_types import SocketType
|
||||||
|
|
||||||
|
|
||||||
|
@typ.runtime_checkable
|
||||||
|
class SocketDef(typ.Protocol):
|
||||||
|
socket_type: SocketType
|
||||||
|
|
||||||
|
def init(self, bl_socket: bpy.types.NodeSocket) -> None: ...
|
|
@ -1,5 +1,4 @@
|
||||||
|
import typing as typ
|
||||||
from .base import ManagedObj
|
|
||||||
|
|
||||||
# from .managed_bl_empty import ManagedBLEmpty
|
# from .managed_bl_empty import ManagedBLEmpty
|
||||||
from .managed_bl_image import ManagedBLImage
|
from .managed_bl_image import ManagedBLImage
|
||||||
|
@ -11,8 +10,9 @@ from .managed_bl_mesh import ManagedBLMesh
|
||||||
# from .managed_bl_volume import ManagedBLVolume
|
# from .managed_bl_volume import ManagedBLVolume
|
||||||
from .managed_bl_modifier import ManagedBLModifier
|
from .managed_bl_modifier import ManagedBLModifier
|
||||||
|
|
||||||
|
ManagedObj: typ.TypeAlias = ManagedBLImage | ManagedBLMesh | ManagedBLModifier
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
'ManagedObj',
|
|
||||||
#'ManagedBLEmpty',
|
#'ManagedBLEmpty',
|
||||||
'ManagedBLImage',
|
'ManagedBLImage',
|
||||||
#'ManagedBLCollection',
|
#'ManagedBLCollection',
|
||||||
|
|
|
@ -1,65 +0,0 @@
|
||||||
import abc
|
|
||||||
import typing as typ
|
|
||||||
|
|
||||||
from blender_maxwell.utils import logger, serialize
|
|
||||||
|
|
||||||
from .. import contracts as ct
|
|
||||||
|
|
||||||
log = logger.get(__name__)
|
|
||||||
|
|
||||||
|
|
||||||
class ManagedObj(abc.ABC):
|
|
||||||
managed_obj_type: ct.ManagedObjType
|
|
||||||
|
|
||||||
@abc.abstractmethod
|
|
||||||
def __init__(
|
|
||||||
self,
|
|
||||||
name: ct.ManagedObjName,
|
|
||||||
):
|
|
||||||
"""Initializes the managed object with a unique 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 bl_select(self) -> None:
|
|
||||||
"""Select the managed object in Blender, if such an operation makes sense."""
|
|
||||||
|
|
||||||
@abc.abstractmethod
|
|
||||||
def hide_preview(self) -> None:
|
|
||||||
"""Select the managed object in Blender, if such an operation makes sense."""
|
|
||||||
|
|
||||||
####################
|
|
||||||
# - Serialization
|
|
||||||
####################
|
|
||||||
def dump_as_msgspec(self) -> serialize.NaiveRepresentation:
|
|
||||||
return [
|
|
||||||
serialize.TypeID.ManagedObj,
|
|
||||||
self.__class__.__name__,
|
|
||||||
self.name,
|
|
||||||
]
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def parse_as_msgspec(obj: serialize.NaiveRepresentation) -> typ.Self:
|
|
||||||
return next(
|
|
||||||
subclass(obj[2])
|
|
||||||
for subclass in ManagedObj.__subclasses__()
|
|
||||||
if subclass.__name__ == obj[1]
|
|
||||||
)
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import functools
|
||||||
|
|
||||||
import bpy
|
import bpy
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import io
|
import io
|
||||||
|
import time
|
||||||
import typing as typ
|
import typing as typ
|
||||||
|
|
||||||
import bpy
|
import bpy
|
||||||
|
@ -11,7 +12,6 @@ import typing_extensions as typx
|
||||||
|
|
||||||
from ....utils import logger
|
from ....utils import logger
|
||||||
from .. import contracts as ct
|
from .. import contracts as ct
|
||||||
from . import base
|
|
||||||
|
|
||||||
log = logger.get(__name__)
|
log = logger.get(__name__)
|
||||||
|
|
||||||
|
@ -76,7 +76,7 @@ def rgba_image_from_xyzf(xyz_freq, colormap: str | None = None):
|
||||||
return rgba_image_from_xyzf__grayscale(xyz_freq)
|
return rgba_image_from_xyzf__grayscale(xyz_freq)
|
||||||
|
|
||||||
|
|
||||||
class ManagedBLImage(base.ManagedObj):
|
class ManagedBLImage(ct.schemas.ManagedObj):
|
||||||
managed_obj_type = ct.ManagedObjType.ManagedBLImage
|
managed_obj_type = ct.ManagedObjType.ManagedBLImage
|
||||||
_bl_image_name: str
|
_bl_image_name: str
|
||||||
|
|
||||||
|
@ -181,9 +181,6 @@ class ManagedBLImage(base.ManagedObj):
|
||||||
if bl_image := bpy.data.images.get(self.name):
|
if bl_image := bpy.data.images.get(self.name):
|
||||||
self.preview_space.image = bl_image
|
self.preview_space.image = bl_image
|
||||||
|
|
||||||
def hide_preview(self) -> None:
|
|
||||||
self.preview_space.image = None
|
|
||||||
|
|
||||||
####################
|
####################
|
||||||
# - Image Geometry
|
# - Image Geometry
|
||||||
####################
|
####################
|
||||||
|
@ -272,12 +269,12 @@ class ManagedBLImage(base.ManagedObj):
|
||||||
)
|
)
|
||||||
# log.debug('Computed MPL Geometry (%f)', time.perf_counter() - time_start)
|
# log.debug('Computed MPL Geometry (%f)', time.perf_counter() - time_start)
|
||||||
|
|
||||||
# log.debug(
|
#log.debug(
|
||||||
# 'Creating MPL Axes (aspect=%f, width=%f, height=%f)',
|
# 'Creating MPL Axes (aspect=%f, width=%f, height=%f)',
|
||||||
# aspect_ratio,
|
# aspect_ratio,
|
||||||
# _width_inches,
|
# _width_inches,
|
||||||
# _height_inches,
|
# _height_inches,
|
||||||
# )
|
#)
|
||||||
# Create MPL Figure, Axes, and Compute Figure Geometry
|
# Create MPL Figure, Axes, and Compute Figure Geometry
|
||||||
fig, ax = plt.subplots(
|
fig, ax = plt.subplots(
|
||||||
figsize=[_width_inches, _height_inches],
|
figsize=[_width_inches, _height_inches],
|
||||||
|
|
|
@ -6,7 +6,6 @@ import numpy as np
|
||||||
|
|
||||||
from ....utils import logger
|
from ....utils import logger
|
||||||
from .. import contracts as ct
|
from .. import contracts as ct
|
||||||
from . import base
|
|
||||||
from .managed_bl_collection import managed_collection, preview_collection
|
from .managed_bl_collection import managed_collection, preview_collection
|
||||||
|
|
||||||
log = logger.get(__name__)
|
log = logger.get(__name__)
|
||||||
|
@ -15,7 +14,7 @@ log = logger.get(__name__)
|
||||||
####################
|
####################
|
||||||
# - BLMesh
|
# - BLMesh
|
||||||
####################
|
####################
|
||||||
class ManagedBLMesh(base.ManagedObj):
|
class ManagedBLMesh(ct.schemas.ManagedObj):
|
||||||
managed_obj_type = ct.ManagedObjType.ManagedBLMesh
|
managed_obj_type = ct.ManagedObjType.ManagedBLMesh
|
||||||
_bl_object_name: str | None = None
|
_bl_object_name: str | None = None
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,6 @@ import typing_extensions as typx
|
||||||
from ....utils import analyze_geonodes, logger
|
from ....utils import analyze_geonodes, logger
|
||||||
from .. import bl_socket_map
|
from .. import bl_socket_map
|
||||||
from .. import contracts as ct
|
from .. import contracts as ct
|
||||||
from . import base
|
|
||||||
|
|
||||||
log = logger.get(__name__)
|
log = logger.get(__name__)
|
||||||
|
|
||||||
|
@ -161,7 +160,7 @@ def write_modifier(
|
||||||
####################
|
####################
|
||||||
# - ManagedObj
|
# - ManagedObj
|
||||||
####################
|
####################
|
||||||
class ManagedBLModifier(base.ManagedObj):
|
class ManagedBLModifier(ct.schemas.ManagedObj):
|
||||||
managed_obj_type = ct.ManagedObjType.ManagedBLModifier
|
managed_obj_type = ct.ManagedObjType.ManagedBLModifier
|
||||||
_modifier_name: str | None = None
|
_modifier_name: str | None = None
|
||||||
|
|
||||||
|
@ -186,9 +185,6 @@ class ManagedBLModifier(base.ManagedObj):
|
||||||
def __init__(self, name: str):
|
def __init__(self, name: str):
|
||||||
self.name = name
|
self.name = name
|
||||||
|
|
||||||
def bl_select(self) -> None: pass
|
|
||||||
def hide_preview(self) -> None: pass
|
|
||||||
|
|
||||||
####################
|
####################
|
||||||
# - Deallocation
|
# - Deallocation
|
||||||
####################
|
####################
|
||||||
|
|
|
@ -5,6 +5,7 @@ import bpy
|
||||||
|
|
||||||
from ...utils import logger
|
from ...utils import logger
|
||||||
from . import contracts as ct
|
from . import contracts as ct
|
||||||
|
from .managed_objs.managed_bl_collection import preview_collection
|
||||||
|
|
||||||
log = logger.get(__name__)
|
log = logger.get(__name__)
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ import bpy
|
||||||
|
|
||||||
from .....utils import logger
|
from .....utils import logger
|
||||||
from ... import contracts as ct
|
from ... import contracts as ct
|
||||||
from ... import sockets
|
from ... import managed_objs, sockets
|
||||||
from .. import base, events
|
from .. import base, events
|
||||||
|
|
||||||
log = logger.get(__name__)
|
log = logger.get(__name__)
|
||||||
|
@ -245,9 +245,9 @@ class ExtractDataNode(base.MaxwellSimNode):
|
||||||
field_data = self._compute_input('Field Data')
|
field_data = self._compute_input('Field Data')
|
||||||
return getattr(field_data, props['field_data__component'])
|
return getattr(field_data, props['field_data__component'])
|
||||||
|
|
||||||
elif self.active_socket_set == 'Flux Data':
|
elif self.active_socket_set == 'Flux Data': # noqa: RET505
|
||||||
flux_data = self._compute_input('Flux Data')
|
flux_data = self._compute_input('Flux Data')
|
||||||
return flux_data.flux
|
return getattr(flux_data, 'flux')
|
||||||
|
|
||||||
msg = f'Tried to get data from unknown output socket in "{self.bl_label}"'
|
msg = f'Tried to get data from unknown output socket in "{self.bl_label}"'
|
||||||
raise RuntimeError(msg)
|
raise RuntimeError(msg)
|
||||||
|
|
|
@ -24,12 +24,23 @@ class VizNode(base.MaxwellSimNode):
|
||||||
'Data': sockets.AnySocketDef(),
|
'Data': sockets.AnySocketDef(),
|
||||||
'Freq': sockets.PhysicalFreqSocketDef(),
|
'Freq': sockets.PhysicalFreqSocketDef(),
|
||||||
}
|
}
|
||||||
|
# input_sockets_sets: typ.ClassVar = {
|
||||||
|
# '2D Freq': {
|
||||||
|
# 'Data': sockets.AnySocketDef(),
|
||||||
|
# 'Freq': sockets.PhysicalFreqSocketDef(),
|
||||||
|
# },
|
||||||
|
# }
|
||||||
output_sockets: typ.ClassVar = {
|
output_sockets: typ.ClassVar = {
|
||||||
'Preview': sockets.AnySocketDef(),
|
'Preview': sockets.AnySocketDef(),
|
||||||
}
|
}
|
||||||
|
|
||||||
managed_obj_types: typ.ClassVar = {
|
managed_obj_defs: typ.ClassVar = {
|
||||||
'plot': managed_objs.ManagedBLImage,
|
'plot': ct.schemas.ManagedObjDef(
|
||||||
|
mk=lambda name: managed_objs.ManagedBLImage(name),
|
||||||
|
),
|
||||||
|
#'empty': ct.schemas.ManagedObjDef(
|
||||||
|
# mk=lambda name: managed_objs.ManagedBLEmpty(name),
|
||||||
|
# ),
|
||||||
}
|
}
|
||||||
|
|
||||||
#####################
|
#####################
|
||||||
|
@ -67,7 +78,7 @@ class VizNode(base.MaxwellSimNode):
|
||||||
)
|
)
|
||||||
def on_show_plot(
|
def on_show_plot(
|
||||||
self,
|
self,
|
||||||
managed_objs: dict,
|
managed_objs: dict[str, ct.schemas.ManagedObj],
|
||||||
input_sockets: dict,
|
input_sockets: dict,
|
||||||
props: dict,
|
props: dict,
|
||||||
unit_systems: dict,
|
unit_systems: dict,
|
||||||
|
|
|
@ -12,13 +12,11 @@ import bpy
|
||||||
import sympy as sp
|
import sympy as sp
|
||||||
import typing_extensions as typx
|
import typing_extensions as typx
|
||||||
|
|
||||||
from blender_maxwell.utils import logger
|
from ....utils import logger
|
||||||
|
from .. import bl_cache
|
||||||
from .. import bl_cache, sockets
|
|
||||||
from .. import contracts as ct
|
from .. import contracts as ct
|
||||||
from .. import managed_objs as _managed_objs
|
from .. import managed_objs as _managed_objs
|
||||||
from . import events
|
from . import events
|
||||||
from . import presets as _presets
|
|
||||||
|
|
||||||
log = logger.get(__name__)
|
log = logger.get(__name__)
|
||||||
|
|
||||||
|
@ -44,27 +42,21 @@ class MaxwellSimNode(bpy.types.Node):
|
||||||
## TODO: bl_description from first line of __doc__?
|
## TODO: bl_description from first line of __doc__?
|
||||||
|
|
||||||
# Sockets
|
# Sockets
|
||||||
input_sockets: typ.ClassVar[dict[str, sockets.base.SocketDef]] = MappingProxyType(
|
input_sockets: typ.ClassVar[dict[str, ct.schemas.SocketDef]] = MappingProxyType({})
|
||||||
{}
|
output_sockets: typ.ClassVar[dict[str, ct.schemas.SocketDef]] = MappingProxyType({})
|
||||||
)
|
input_socket_sets: typ.ClassVar[dict[str, dict[str, ct.schemas.SocketDef]]] = (
|
||||||
output_sockets: typ.ClassVar[dict[str, sockets.base.SocketDef]] = MappingProxyType(
|
|
||||||
{}
|
|
||||||
)
|
|
||||||
input_socket_sets: typ.ClassVar[dict[str, dict[str, sockets.base.SocketDef]]] = (
|
|
||||||
MappingProxyType({})
|
MappingProxyType({})
|
||||||
)
|
)
|
||||||
output_socket_sets: typ.ClassVar[dict[str, dict[str, sockets.base.SocketDef]]] = (
|
output_socket_sets: typ.ClassVar[dict[str, dict[str, ct.schemas.SocketDef]]] = (
|
||||||
MappingProxyType({})
|
MappingProxyType({})
|
||||||
)
|
)
|
||||||
|
|
||||||
# Presets
|
# Presets
|
||||||
presets: typ.ClassVar[dict[str, dict[str, _presets.PresetDef]]] = MappingProxyType(
|
presets: typ.ClassVar = MappingProxyType({})
|
||||||
{}
|
|
||||||
)
|
|
||||||
|
|
||||||
# Managed Objects
|
# Managed Objects
|
||||||
managed_obj_types: typ.ClassVar[
|
managed_obj_defs: typ.ClassVar[
|
||||||
dict[ct.ManagedObjName, type[_managed_objs.ManagedObj]]
|
dict[ct.ManagedObjName, ct.schemas.ManagedObjDef]
|
||||||
] = MappingProxyType({})
|
] = MappingProxyType({})
|
||||||
|
|
||||||
####################
|
####################
|
||||||
|
@ -230,7 +222,7 @@ class MaxwellSimNode(bpy.types.Node):
|
||||||
####################
|
####################
|
||||||
@events.on_value_changed(
|
@events.on_value_changed(
|
||||||
prop_name='sim_node_name',
|
prop_name='sim_node_name',
|
||||||
props={'sim_node_name', 'managed_objs', 'managed_obj_types'},
|
props={'sim_node_name', 'managed_objs', 'managed_obj_defs'},
|
||||||
)
|
)
|
||||||
def _on_sim_node_name_changed(self, props: dict):
|
def _on_sim_node_name_changed(self, props: dict):
|
||||||
log.info(
|
log.info(
|
||||||
|
@ -241,8 +233,9 @@ class MaxwellSimNode(bpy.types.Node):
|
||||||
)
|
)
|
||||||
|
|
||||||
# Set Name of Managed Objects
|
# Set Name of Managed Objects
|
||||||
for mobj in props['managed_objs'].values():
|
for mobj_id, mobj in props['managed_objs'].items():
|
||||||
mobj.name = props['sim_node_name']
|
mobj_def = props['managed_obj_defs'][mobj_id]
|
||||||
|
mobj.name = mobj_def.name_prefix + props['sim_node_name']
|
||||||
|
|
||||||
@events.on_value_changed(prop_name='active_socket_set')
|
@events.on_value_changed(prop_name='active_socket_set')
|
||||||
def _on_socket_set_changed(self):
|
def _on_socket_set_changed(self):
|
||||||
|
@ -289,6 +282,8 @@ class MaxwellSimNode(bpy.types.Node):
|
||||||
def _on_preview_changed(self, props):
|
def _on_preview_changed(self, props):
|
||||||
if not props['preview_active']:
|
if not props['preview_active']:
|
||||||
for mobj in self.managed_objs.values():
|
for mobj in self.managed_objs.values():
|
||||||
|
if isinstance(mobj, _managed_objs.ManagedBLMesh):
|
||||||
|
## TODO: This is a Workaround
|
||||||
mobj.hide_preview()
|
mobj.hide_preview()
|
||||||
|
|
||||||
@events.on_enable_lock()
|
@events.on_enable_lock()
|
||||||
|
@ -308,8 +303,8 @@ class MaxwellSimNode(bpy.types.Node):
|
||||||
####################
|
####################
|
||||||
# - Loose Sockets w/Events
|
# - Loose Sockets w/Events
|
||||||
####################
|
####################
|
||||||
loose_input_sockets: dict[str, sockets.base.SocketDef] = bl_cache.BLField({})
|
loose_input_sockets: dict[str, ct.schemas.SocketDef] = bl_cache.BLField({})
|
||||||
loose_output_sockets: dict[str, sockets.base.SocketDef] = bl_cache.BLField({})
|
loose_output_sockets: dict[str, ct.schemas.SocketDef] = bl_cache.BLField({})
|
||||||
|
|
||||||
@events.on_value_changed(prop_name={'loose_input_sockets', 'loose_output_sockets'})
|
@events.on_value_changed(prop_name={'loose_input_sockets', 'loose_output_sockets'})
|
||||||
def _on_loose_sockets_changed(self):
|
def _on_loose_sockets_changed(self):
|
||||||
|
@ -339,7 +334,7 @@ class MaxwellSimNode(bpy.types.Node):
|
||||||
def _active_socket_set_socket_defs(
|
def _active_socket_set_socket_defs(
|
||||||
self,
|
self,
|
||||||
direc: typx.Literal['input', 'output'],
|
direc: typx.Literal['input', 'output'],
|
||||||
) -> dict[ct.SocketName, sockets.base.SocketDef]:
|
) -> dict[ct.SocketName, ct.schemas.SocketDef]:
|
||||||
"""Retrieve all socket definitions for sockets that should be defined, according to the `self.active_socket_set`.
|
"""Retrieve all socket definitions for sockets that should be defined, according to the `self.active_socket_set`.
|
||||||
|
|
||||||
Notes:
|
Notes:
|
||||||
|
@ -349,7 +344,7 @@ class MaxwellSimNode(bpy.types.Node):
|
||||||
direc: The direction to load Blender sockets from.
|
direc: The direction to load Blender sockets from.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Mapping from socket names to corresponding `sockets.base.SocketDef`s.
|
Mapping from socket names to corresponding `ct.schemas.SocketDef`s.
|
||||||
|
|
||||||
If `self.active_socket_set` is None, the empty dict is returned.
|
If `self.active_socket_set` is None, the empty dict is returned.
|
||||||
"""
|
"""
|
||||||
|
@ -365,14 +360,14 @@ class MaxwellSimNode(bpy.types.Node):
|
||||||
|
|
||||||
def active_socket_defs(
|
def active_socket_defs(
|
||||||
self, direc: typx.Literal['input', 'output']
|
self, direc: typx.Literal['input', 'output']
|
||||||
) -> dict[ct.SocketName, sockets.base.SocketDef]:
|
) -> dict[ct.SocketName, ct.schemas.SocketDef]:
|
||||||
"""Retrieve all socket definitions for sockets that should be defined.
|
"""Retrieve all socket definitions for sockets that should be defined.
|
||||||
|
|
||||||
Parameters:
|
Parameters:
|
||||||
direc: The direction to load Blender sockets from.
|
direc: The direction to load Blender sockets from.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Mapping from socket names to corresponding `sockets.base.SocketDef`s.
|
Mapping from socket names to corresponding `ct.schemas.SocketDef`s.
|
||||||
"""
|
"""
|
||||||
static_sockets = self.input_sockets if direc == 'input' else self.output_sockets
|
static_sockets = self.input_sockets if direc == 'input' else self.output_sockets
|
||||||
loose_sockets = (
|
loose_sockets = (
|
||||||
|
@ -465,17 +460,33 @@ class MaxwellSimNode(bpy.types.Node):
|
||||||
####################
|
####################
|
||||||
# - Managed Objects
|
# - Managed Objects
|
||||||
####################
|
####################
|
||||||
@bl_cache.cached_bl_property(persist=True)
|
managed_bl_meshes: dict[str, _managed_objs.ManagedBLMesh] = bl_cache.BLField({})
|
||||||
|
managed_bl_images: dict[str, _managed_objs.ManagedBLImage] = bl_cache.BLField({})
|
||||||
|
managed_bl_modifiers: dict[str, _managed_objs.ManagedBLModifier] = bl_cache.BLField(
|
||||||
|
{}
|
||||||
|
)
|
||||||
|
|
||||||
|
@bl_cache.cached_bl_property(
|
||||||
|
persist=False
|
||||||
|
) ## Disable broken ManagedObj union DECODER
|
||||||
def managed_objs(self) -> dict[str, _managed_objs.ManagedObj]:
|
def managed_objs(self) -> dict[str, _managed_objs.ManagedObj]:
|
||||||
"""Access the managed objects defined on this node.
|
"""Access the managed objects defined on this node.
|
||||||
|
|
||||||
Persistent cache ensures that the managed objects are only created on first access, even across file reloads.
|
Persistent cache ensures that the managed objects are only created on first access, even across file reloads.
|
||||||
"""
|
"""
|
||||||
if self.managed_obj_types:
|
if self.managed_obj_defs:
|
||||||
|
if not (
|
||||||
|
managed_objs := (
|
||||||
|
self.managed_bl_meshes
|
||||||
|
| self.managed_bl_images
|
||||||
|
| self.managed_bl_modifiers
|
||||||
|
)
|
||||||
|
):
|
||||||
return {
|
return {
|
||||||
mobj_name: mobj_type(self.sim_node_name)
|
mobj_name: mobj_def.mk(mobj_def.name_prefix + self.sim_node_name)
|
||||||
for mobj_name, mobj_type in self.managed_obj_types.items()
|
for mobj_name, mobj_def in self.managed_obj_defs.items()
|
||||||
}
|
}
|
||||||
|
return managed_objs
|
||||||
|
|
||||||
return {}
|
return {}
|
||||||
|
|
||||||
|
@ -553,7 +564,7 @@ class MaxwellSimNode(bpy.types.Node):
|
||||||
####################
|
####################
|
||||||
@bl_cache.keyed_cache(
|
@bl_cache.keyed_cache(
|
||||||
exclude={'self', 'optional'},
|
exclude={'self', 'optional'},
|
||||||
encode={'unit_system'},
|
serialize={'unit_system'},
|
||||||
)
|
)
|
||||||
def _compute_input(
|
def _compute_input(
|
||||||
self,
|
self,
|
||||||
|
@ -708,6 +719,13 @@ class MaxwellSimNode(bpy.types.Node):
|
||||||
stop_propagation |= event_method.stop_propagation
|
stop_propagation |= event_method.stop_propagation
|
||||||
event_method(self)
|
event_method(self)
|
||||||
|
|
||||||
|
# Stop Propagation (maybe)
|
||||||
|
if (
|
||||||
|
ct.DataFlowAction.stop_if_no_event_methods(action)
|
||||||
|
and len(triggered_event_methods) == 0
|
||||||
|
):
|
||||||
|
return
|
||||||
|
|
||||||
# Propagate Action to All Sockets in "Trigger Direction"
|
# Propagate Action to All Sockets in "Trigger Direction"
|
||||||
## The trigger chain goes node/socket/node/socket/...
|
## The trigger chain goes node/socket/node/socket/...
|
||||||
if not stop_propagation:
|
if not stop_propagation:
|
||||||
|
|
|
@ -47,8 +47,11 @@ class Tidy3DFileImporterNode(base.MaxwellSimNode):
|
||||||
input_sockets: typ.ClassVar = {
|
input_sockets: typ.ClassVar = {
|
||||||
'File Path': sockets.FilePathSocketDef(),
|
'File Path': sockets.FilePathSocketDef(),
|
||||||
}
|
}
|
||||||
managed_obj_types: typ.ClassVar = {
|
managed_obj_defs: typ.ClassVar = {
|
||||||
'plot': managed_objs.ManagedBLImage,
|
'plot': ct.schemas.ManagedObjDef(
|
||||||
|
mk=lambda name: managed_objs.ManagedBLImage(name),
|
||||||
|
name_prefix='',
|
||||||
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
####################
|
####################
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
import typing as typ
|
import typing as typ
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
|
import tidy3d as td
|
||||||
|
|
||||||
from ...... import info
|
from ...... import info
|
||||||
from ......services import tdcloud
|
from ......services import tdcloud
|
||||||
from ......utils import logger
|
from ......utils import logger
|
||||||
|
|
|
@ -26,8 +26,11 @@ class LibraryMediumNode(base.MaxwellSimNode):
|
||||||
'Medium': sockets.MaxwellMediumSocketDef(),
|
'Medium': sockets.MaxwellMediumSocketDef(),
|
||||||
}
|
}
|
||||||
|
|
||||||
managed_obj_types = {
|
managed_obj_defs = {
|
||||||
'nk_plot': managed_objs.ManagedBLImage,
|
'nk_plot': ct.schemas.ManagedObjDef(
|
||||||
|
mk=lambda name: managed_objs.ManagedBLImage(name),
|
||||||
|
name_prefix='',
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
####################
|
####################
|
||||||
|
@ -122,8 +125,8 @@ class LibraryMediumNode(base.MaxwellSimNode):
|
||||||
)
|
)
|
||||||
def on_show_plot(
|
def on_show_plot(
|
||||||
self,
|
self,
|
||||||
managed_objs: dict,
|
managed_objs: dict[str, ct.schemas.ManagedObj],
|
||||||
props: dict,
|
props: dict[str, typ.Any],
|
||||||
):
|
):
|
||||||
medium = td.material_library[props['material']].medium
|
medium = td.material_library[props['material']].medium
|
||||||
freq_range = [
|
freq_range = [
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import typing as typ
|
import typing as typ
|
||||||
|
|
||||||
import sympy as sp
|
import sympy as sp
|
||||||
|
import sympy.physics.units as spu
|
||||||
import tidy3d as td
|
import tidy3d as td
|
||||||
|
|
||||||
from .....assets.import_geonodes import GeoNodes, import_geonodes
|
from .....assets.import_geonodes import GeoNodes, import_geonodes
|
||||||
|
@ -49,9 +50,13 @@ class EHFieldMonitorNode(base.MaxwellSimNode):
|
||||||
'Time Domain': {'Time Monitor': sockets.MaxwellMonitorSocketDef()},
|
'Time Domain': {'Time Monitor': sockets.MaxwellMonitorSocketDef()},
|
||||||
}
|
}
|
||||||
|
|
||||||
managed_obj_types: typ.ClassVar = {
|
managed_obj_defs: typ.ClassVar = {
|
||||||
'mesh': managed_objs.ManagedBLMesh,
|
'mesh': ct.schemas.ManagedObjDef(
|
||||||
'modifier': managed_objs.ManagedBLModifier,
|
mk=lambda name: managed_objs.ManagedBLMesh(name),
|
||||||
|
),
|
||||||
|
'modifier': ct.schemas.ManagedObjDef(
|
||||||
|
mk=lambda name: managed_objs.ManagedBLModifier(name),
|
||||||
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
####################
|
####################
|
||||||
|
@ -113,7 +118,7 @@ class EHFieldMonitorNode(base.MaxwellSimNode):
|
||||||
def on_inputs_changed(
|
def on_inputs_changed(
|
||||||
self,
|
self,
|
||||||
props: dict,
|
props: dict,
|
||||||
managed_objs: dict,
|
managed_objs: dict[str, ct.schemas.ManagedObj],
|
||||||
input_sockets: dict,
|
input_sockets: dict,
|
||||||
unit_systems: dict,
|
unit_systems: dict,
|
||||||
):
|
):
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
import typing as typ
|
import typing as typ
|
||||||
|
|
||||||
|
import bpy
|
||||||
import sympy as sp
|
import sympy as sp
|
||||||
|
import sympy.physics.units as spu
|
||||||
import tidy3d as td
|
import tidy3d as td
|
||||||
|
|
||||||
from .....assets.import_geonodes import GeoNodes, import_geonodes
|
from .....assets.import_geonodes import GeoNodes, import_geonodes
|
||||||
|
@ -48,9 +50,13 @@ class PowerFluxMonitorNode(base.MaxwellSimNode):
|
||||||
'Time Domain': {'Time Monitor': sockets.MaxwellMonitorSocketDef()},
|
'Time Domain': {'Time Monitor': sockets.MaxwellMonitorSocketDef()},
|
||||||
}
|
}
|
||||||
|
|
||||||
managed_obj_types: typ.ClassVar = {
|
managed_obj_defs: typ.ClassVar = {
|
||||||
'mesh': managed_objs.ManagedBLMesh,
|
'mesh': ct.schemas.ManagedObjDef(
|
||||||
'modifier': managed_objs.ManagedBLModifier,
|
mk=lambda name: managed_objs.ManagedBLMesh(name),
|
||||||
|
),
|
||||||
|
'modifier': ct.schemas.ManagedObjDef(
|
||||||
|
mk=lambda name: managed_objs.ManagedBLModifier(name),
|
||||||
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
####################
|
####################
|
||||||
|
@ -92,7 +98,7 @@ class PowerFluxMonitorNode(base.MaxwellSimNode):
|
||||||
center=input_sockets['Center'],
|
center=input_sockets['Center'],
|
||||||
size=input_sockets['Size'],
|
size=input_sockets['Size'],
|
||||||
name=props['sim_node_name'],
|
name=props['sim_node_name'],
|
||||||
interval_space=(1, 1, 1),
|
interval_space=(1,1,1),
|
||||||
freqs=input_sockets['Freqs'].realize().values,
|
freqs=input_sockets['Freqs'].realize().values,
|
||||||
normal_dir='+' if input_sockets['Direction'] else '-',
|
normal_dir='+' if input_sockets['Direction'] else '-',
|
||||||
)
|
)
|
||||||
|
@ -114,7 +120,7 @@ class PowerFluxMonitorNode(base.MaxwellSimNode):
|
||||||
def on_inputs_changed(
|
def on_inputs_changed(
|
||||||
self,
|
self,
|
||||||
props: dict,
|
props: dict,
|
||||||
managed_objs: dict,
|
managed_objs: dict[str, ct.schemas.ManagedObj],
|
||||||
input_sockets: dict,
|
input_sockets: dict,
|
||||||
unit_systems: dict,
|
unit_systems: dict,
|
||||||
):
|
):
|
||||||
|
|
|
@ -6,6 +6,7 @@ import sympy as sp
|
||||||
from .....utils import logger
|
from .....utils import logger
|
||||||
from ... import contracts as ct
|
from ... import contracts as ct
|
||||||
from ... import sockets
|
from ... import sockets
|
||||||
|
from ...managed_objs.managed_bl_collection import preview_collection
|
||||||
from .. import base, events
|
from .. import base, events
|
||||||
|
|
||||||
log = logger.get(__name__)
|
log = logger.get(__name__)
|
||||||
|
|
|
@ -28,9 +28,14 @@ class SimDomainNode(base.MaxwellSimNode):
|
||||||
'Domain': sockets.MaxwellSimDomainSocketDef(),
|
'Domain': sockets.MaxwellSimDomainSocketDef(),
|
||||||
}
|
}
|
||||||
|
|
||||||
managed_obj_types: typ.ClassVar = {
|
managed_obj_defs: typ.ClassVar = {
|
||||||
'mesh': managed_objs.ManagedBLMesh,
|
'mesh': ct.schemas.ManagedObjDef(
|
||||||
'modifier': managed_objs.ManagedBLModifier,
|
mk=lambda name: managed_objs.ManagedBLMesh(name),
|
||||||
|
name_prefix='',
|
||||||
|
),
|
||||||
|
'modifier': ct.schemas.ManagedObjDef(
|
||||||
|
mk=lambda name: managed_objs.ManagedBLModifier(name),
|
||||||
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
####################
|
####################
|
||||||
|
@ -70,7 +75,7 @@ class SimDomainNode(base.MaxwellSimNode):
|
||||||
def on_input_changed(
|
def on_input_changed(
|
||||||
self,
|
self,
|
||||||
props: dict,
|
props: dict,
|
||||||
managed_objs: dict,
|
managed_objs: dict[str, ct.schemas.ManagedObj],
|
||||||
input_sockets: dict,
|
input_sockets: dict,
|
||||||
unit_systems: dict,
|
unit_systems: dict,
|
||||||
):
|
):
|
||||||
|
|
|
@ -56,8 +56,11 @@ class PlaneWaveSourceNode(base.MaxwellSimNode):
|
||||||
'Source': sockets.MaxwellSourceSocketDef(),
|
'Source': sockets.MaxwellSourceSocketDef(),
|
||||||
}
|
}
|
||||||
|
|
||||||
managed_obj_types: typ.ClassVar = {
|
managed_obj_defs: typ.ClassVar = {
|
||||||
'plane_wave_source': managed_objs.ManagedBLMesh,
|
'plane_wave_source': ct.schemas.ManagedObjDef(
|
||||||
|
mk=lambda name: managed_objs.ManagedBLObject(name),
|
||||||
|
name_prefix='',
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
####################
|
####################
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import typing as typ
|
import typing as typ
|
||||||
|
|
||||||
import bpy
|
import bpy
|
||||||
|
import sympy.physics.units as spu
|
||||||
import tidy3d as td
|
import tidy3d as td
|
||||||
|
|
||||||
from ... import contracts as ct
|
from ... import contracts as ct
|
||||||
|
@ -26,8 +27,11 @@ class PointDipoleSourceNode(base.MaxwellSimNode):
|
||||||
'Source': sockets.MaxwellSourceSocketDef(),
|
'Source': sockets.MaxwellSourceSocketDef(),
|
||||||
}
|
}
|
||||||
|
|
||||||
managed_obj_types = {
|
managed_obj_defs = {
|
||||||
'mesh': managed_objs.ManagedBLMesh,
|
'sphere_empty': ct.schemas.ManagedObjDef(
|
||||||
|
mk=lambda name: managed_objs.ManagedBLObject(name),
|
||||||
|
name_prefix='',
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
####################
|
####################
|
||||||
|
|
|
@ -41,8 +41,11 @@ class GaussianPulseTemporalShapeNode(base.MaxwellSimNode):
|
||||||
'Temporal Shape': sockets.MaxwellTemporalShapeSocketDef(),
|
'Temporal Shape': sockets.MaxwellTemporalShapeSocketDef(),
|
||||||
}
|
}
|
||||||
|
|
||||||
managed_obj_types = {
|
managed_obj_defs = {
|
||||||
'amp_time': managed_objs.ManagedBLImage,
|
'amp_time': ct.schemas.ManagedObjDef(
|
||||||
|
mk=lambda name: managed_objs.ManagedBLImage(name),
|
||||||
|
name_prefix='amp_time_',
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
####################
|
####################
|
||||||
|
@ -120,9 +123,9 @@ class GaussianPulseTemporalShapeNode(base.MaxwellSimNode):
|
||||||
)
|
)
|
||||||
def on_show_plot(
|
def on_show_plot(
|
||||||
self,
|
self,
|
||||||
managed_objs: dict,
|
managed_objs: dict[str, ct.schemas.ManagedObj],
|
||||||
output_sockets: dict,
|
output_sockets: dict[str, typ.Any],
|
||||||
props: dict,
|
props: dict[str, typ.Any],
|
||||||
):
|
):
|
||||||
temporal_shape = output_sockets['Temporal Shape']
|
temporal_shape = output_sockets['Temporal Shape']
|
||||||
plot_time_start = props['plot_time_start'] * 1e-15
|
plot_time_start = props['plot_time_start'] * 1e-15
|
||||||
|
|
|
@ -27,9 +27,13 @@ class GeoNodesStructureNode(base.MaxwellSimNode):
|
||||||
'Structure': sockets.MaxwellStructureSocketDef(),
|
'Structure': sockets.MaxwellStructureSocketDef(),
|
||||||
}
|
}
|
||||||
|
|
||||||
managed_obj_types: typ.ClassVar = {
|
managed_obj_defs: typ.ClassVar = {
|
||||||
'mesh': managed_objs.ManagedBLMesh,
|
'mesh': ct.schemas.ManagedObjDef(
|
||||||
'modifier': managed_objs.ManagedBLModifier,
|
mk=lambda name: managed_objs.ManagedBLMesh(name),
|
||||||
|
),
|
||||||
|
'modifier': ct.schemas.ManagedObjDef(
|
||||||
|
mk=lambda name: managed_objs.ManagedBLModifier(name),
|
||||||
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
####################
|
####################
|
||||||
|
@ -42,8 +46,8 @@ class GeoNodesStructureNode(base.MaxwellSimNode):
|
||||||
)
|
)
|
||||||
def compute_structure(
|
def compute_structure(
|
||||||
self,
|
self,
|
||||||
input_sockets: dict,
|
input_sockets: dict[str, typ.Any],
|
||||||
managed_objs: dict,
|
managed_objs: dict[str, ct.schemas.ManagedObj],
|
||||||
) -> td.Structure:
|
) -> td.Structure:
|
||||||
# Simulate Input Value Change
|
# Simulate Input Value Change
|
||||||
## This ensures that the mesh has been re-computed.
|
## This ensures that the mesh has been re-computed.
|
||||||
|
@ -64,7 +68,7 @@ class GeoNodesStructureNode(base.MaxwellSimNode):
|
||||||
# - Event Methods
|
# - Event Methods
|
||||||
####################
|
####################
|
||||||
@events.on_value_changed(
|
@events.on_value_changed(
|
||||||
socket_name={'GeoNodes', 'Center'},
|
socket_name='GeoNodes',
|
||||||
prop_name='preview_active',
|
prop_name='preview_active',
|
||||||
any_loose_input_socket=True,
|
any_loose_input_socket=True,
|
||||||
run_on_init=True,
|
run_on_init=True,
|
||||||
|
@ -79,7 +83,7 @@ class GeoNodesStructureNode(base.MaxwellSimNode):
|
||||||
def on_input_changed(
|
def on_input_changed(
|
||||||
self,
|
self,
|
||||||
props: dict,
|
props: dict,
|
||||||
managed_objs: dict,
|
managed_objs: dict[str, ct.schemas.ManagedObj],
|
||||||
input_sockets: dict,
|
input_sockets: dict,
|
||||||
loose_input_sockets: dict,
|
loose_input_sockets: dict,
|
||||||
unit_systems: dict,
|
unit_systems: dict,
|
||||||
|
|
|
@ -29,9 +29,13 @@ class BoxStructureNode(base.MaxwellSimNode):
|
||||||
'Structure': sockets.MaxwellStructureSocketDef(),
|
'Structure': sockets.MaxwellStructureSocketDef(),
|
||||||
}
|
}
|
||||||
|
|
||||||
managed_obj_types: typ.ClassVar = {
|
managed_obj_defs: typ.ClassVar = {
|
||||||
'mesh': managed_objs.ManagedBLMesh,
|
'mesh': ct.schemas.ManagedObjDef(
|
||||||
'modifier': managed_objs.ManagedBLModifier,
|
mk=lambda name: managed_objs.ManagedBLMesh(name),
|
||||||
|
),
|
||||||
|
'modifier': ct.schemas.ManagedObjDef(
|
||||||
|
mk=lambda name: managed_objs.ManagedBLModifier(name),
|
||||||
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
####################
|
####################
|
||||||
|
@ -70,7 +74,7 @@ class BoxStructureNode(base.MaxwellSimNode):
|
||||||
def on_inputs_changed(
|
def on_inputs_changed(
|
||||||
self,
|
self,
|
||||||
props: dict,
|
props: dict,
|
||||||
managed_objs: dict,
|
managed_objs: dict[str, ct.schemas.ManagedObj],
|
||||||
input_sockets: dict,
|
input_sockets: dict,
|
||||||
unit_systems: dict,
|
unit_systems: dict,
|
||||||
):
|
):
|
||||||
|
|
|
@ -28,9 +28,13 @@ class SphereStructureNode(base.MaxwellSimNode):
|
||||||
'Structure': sockets.MaxwellStructureSocketDef(),
|
'Structure': sockets.MaxwellStructureSocketDef(),
|
||||||
}
|
}
|
||||||
|
|
||||||
managed_obj_types: typ.ClassVar = {
|
managed_obj_defs: typ.ClassVar = {
|
||||||
'mesh': managed_objs.ManagedBLMesh,
|
'mesh': ct.schemas.ManagedObjDef(
|
||||||
'modifier': managed_objs.ManagedBLModifier,
|
mk=lambda name: managed_objs.ManagedBLMesh(name),
|
||||||
|
),
|
||||||
|
'modifier': ct.schemas.ManagedObjDef(
|
||||||
|
mk=lambda name: managed_objs.ManagedBLModifier(name),
|
||||||
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
####################
|
####################
|
||||||
|
@ -73,7 +77,7 @@ class SphereStructureNode(base.MaxwellSimNode):
|
||||||
def on_inputs_changed(
|
def on_inputs_changed(
|
||||||
self,
|
self,
|
||||||
props: dict,
|
props: dict,
|
||||||
managed_objs: dict,
|
managed_objs: dict[str, ct.schemas.ManagedObj],
|
||||||
input_sockets: dict,
|
input_sockets: dict,
|
||||||
unit_systems: dict,
|
unit_systems: dict,
|
||||||
):
|
):
|
||||||
|
|
|
@ -1,46 +1,17 @@
|
||||||
import abc
|
|
||||||
import functools
|
import functools
|
||||||
import typing as typ
|
import typing as typ
|
||||||
|
|
||||||
import bpy
|
import bpy
|
||||||
import pydantic as pyd
|
|
||||||
import sympy as sp
|
import sympy as sp
|
||||||
|
import sympy.physics.units as spu
|
||||||
import typing_extensions as typx
|
import typing_extensions as typx
|
||||||
|
|
||||||
from ....utils import logger, serialize
|
from ....utils import logger
|
||||||
from .. import contracts as ct
|
from .. import contracts as ct
|
||||||
|
|
||||||
log = logger.get(__name__)
|
log = logger.get(__name__)
|
||||||
|
|
||||||
|
|
||||||
####################
|
|
||||||
# - SocketDef
|
|
||||||
####################
|
|
||||||
class SocketDef(pyd.BaseModel, abc.ABC):
|
|
||||||
socket_type: ct.SocketType
|
|
||||||
|
|
||||||
@abc.abstractmethod
|
|
||||||
def init(self, bl_socket: bpy.types.NodeSocket) -> None:
|
|
||||||
"""Initializes a real Blender node socket from this socket definition."""
|
|
||||||
|
|
||||||
####################
|
|
||||||
# - Serialization
|
|
||||||
####################
|
|
||||||
def dump_as_msgspec(self) -> serialize.NaiveRepresentation:
|
|
||||||
return [serialize.TypeID.SocketDef, self.__class__.__name__, self.model_dump()]
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def parse_as_msgspec(obj: serialize.NaiveRepresentation) -> typ.Self:
|
|
||||||
return next(
|
|
||||||
subclass(**obj[2])
|
|
||||||
for subclass in SocketDef.__subclasses__()
|
|
||||||
if subclass.__name__ == obj[1]
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
####################
|
|
||||||
# - SocketDef
|
|
||||||
####################
|
|
||||||
class MaxwellSimSocket(bpy.types.NodeSocket):
|
class MaxwellSimSocket(bpy.types.NodeSocket):
|
||||||
# Fundamentals
|
# Fundamentals
|
||||||
socket_type: ct.SocketType
|
socket_type: ct.SocketType
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import pydantic as pyd
|
||||||
|
|
||||||
from ... import contracts as ct
|
from ... import contracts as ct
|
||||||
from .. import base
|
from .. import base
|
||||||
|
@ -22,7 +23,7 @@ class AnyBLSocket(base.MaxwellSimSocket):
|
||||||
####################
|
####################
|
||||||
# - Socket Configuration
|
# - Socket Configuration
|
||||||
####################
|
####################
|
||||||
class AnySocketDef(base.SocketDef):
|
class AnySocketDef(pyd.BaseModel):
|
||||||
socket_type: ct.SocketType = ct.SocketType.Any
|
socket_type: ct.SocketType = ct.SocketType.Any
|
||||||
|
|
||||||
def init(self, bl_socket: AnyBLSocket) -> None:
|
def init(self, bl_socket: AnyBLSocket) -> None:
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import bpy
|
import bpy
|
||||||
|
import pydantic as pyd
|
||||||
|
|
||||||
from ... import contracts as ct
|
from ... import contracts as ct
|
||||||
from .. import base
|
from .. import base
|
||||||
|
@ -43,7 +44,7 @@ class BoolBLSocket(base.MaxwellSimSocket):
|
||||||
####################
|
####################
|
||||||
# - Socket Configuration
|
# - Socket Configuration
|
||||||
####################
|
####################
|
||||||
class BoolSocketDef(base.SocketDef):
|
class BoolSocketDef(pyd.BaseModel):
|
||||||
socket_type: ct.SocketType = ct.SocketType.Bool
|
socket_type: ct.SocketType = ct.SocketType.Bool
|
||||||
|
|
||||||
default_value: bool = False
|
default_value: bool = False
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
import bpy
|
import bpy
|
||||||
|
import pydantic as pyd
|
||||||
|
|
||||||
from ... import contracts as ct
|
from ... import contracts as ct
|
||||||
from .. import base
|
from .. import base
|
||||||
|
@ -45,7 +46,7 @@ class FilePathBLSocket(base.MaxwellSimSocket):
|
||||||
####################
|
####################
|
||||||
# - Socket Configuration
|
# - Socket Configuration
|
||||||
####################
|
####################
|
||||||
class FilePathSocketDef(base.SocketDef):
|
class FilePathSocketDef(pyd.BaseModel):
|
||||||
socket_type: ct.SocketType = ct.SocketType.FilePath
|
socket_type: ct.SocketType = ct.SocketType.FilePath
|
||||||
|
|
||||||
default_path: Path = Path()
|
default_path: Path = Path()
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import bpy
|
import bpy
|
||||||
|
import pydantic as pyd
|
||||||
|
|
||||||
from ... import contracts as ct
|
from ... import contracts as ct
|
||||||
from .. import base
|
from .. import base
|
||||||
|
@ -42,7 +43,7 @@ class StringBLSocket(base.MaxwellSimSocket):
|
||||||
####################
|
####################
|
||||||
# - Socket Configuration
|
# - Socket Configuration
|
||||||
####################
|
####################
|
||||||
class StringSocketDef(base.SocketDef):
|
class StringSocketDef(pyd.BaseModel):
|
||||||
socket_type: ct.SocketType = ct.SocketType.String
|
socket_type: ct.SocketType = ct.SocketType.String
|
||||||
|
|
||||||
default_text: str = ''
|
default_text: str = ''
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import bpy
|
import bpy
|
||||||
|
import pydantic as pyd
|
||||||
|
|
||||||
from ... import contracts as ct
|
from ... import contracts as ct
|
||||||
from .. import base
|
from .. import base
|
||||||
|
@ -42,7 +43,7 @@ class BlenderCollectionBLSocket(base.MaxwellSimSocket):
|
||||||
####################
|
####################
|
||||||
# - Socket Configuration
|
# - Socket Configuration
|
||||||
####################
|
####################
|
||||||
class BlenderCollectionSocketDef(base.SocketDef):
|
class BlenderCollectionSocketDef(pyd.BaseModel):
|
||||||
socket_type: ct.SocketType = ct.SocketType.BlenderCollection
|
socket_type: ct.SocketType = ct.SocketType.BlenderCollection
|
||||||
|
|
||||||
def init(self, bl_socket: BlenderCollectionBLSocket) -> None:
|
def init(self, bl_socket: BlenderCollectionBLSocket) -> None:
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import bpy
|
import bpy
|
||||||
|
import pydantic as pyd
|
||||||
|
|
||||||
from ... import contracts as ct
|
from ... import contracts as ct
|
||||||
from .. import base
|
from .. import base
|
||||||
|
@ -81,7 +82,7 @@ class BlenderGeoNodesBLSocket(base.MaxwellSimSocket):
|
||||||
####################
|
####################
|
||||||
# - Socket Configuration
|
# - Socket Configuration
|
||||||
####################
|
####################
|
||||||
class BlenderGeoNodesSocketDef(base.SocketDef):
|
class BlenderGeoNodesSocketDef(pyd.BaseModel):
|
||||||
socket_type: ct.SocketType = ct.SocketType.BlenderGeoNodes
|
socket_type: ct.SocketType = ct.SocketType.BlenderGeoNodes
|
||||||
|
|
||||||
def init(self, bl_socket: BlenderGeoNodesBLSocket) -> None:
|
def init(self, bl_socket: BlenderGeoNodesBLSocket) -> None:
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import bpy
|
import bpy
|
||||||
|
import pydantic as pyd
|
||||||
|
|
||||||
from ... import contracts as ct
|
from ... import contracts as ct
|
||||||
from .. import base
|
from .. import base
|
||||||
|
@ -42,7 +43,7 @@ class BlenderImageBLSocket(base.MaxwellSimSocket):
|
||||||
####################
|
####################
|
||||||
# - Socket Configuration
|
# - Socket Configuration
|
||||||
####################
|
####################
|
||||||
class BlenderImageSocketDef(base.SocketDef):
|
class BlenderImageSocketDef(pyd.BaseModel):
|
||||||
socket_type: ct.SocketType = ct.SocketType.BlenderImage
|
socket_type: ct.SocketType = ct.SocketType.BlenderImage
|
||||||
|
|
||||||
def init(self, bl_socket: BlenderImageBLSocket) -> None:
|
def init(self, bl_socket: BlenderImageBLSocket) -> None:
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import bpy
|
import bpy
|
||||||
|
import pydantic as pyd
|
||||||
|
|
||||||
from ... import contracts as ct
|
from ... import contracts as ct
|
||||||
from .. import base
|
from .. import base
|
||||||
|
@ -39,7 +40,7 @@ class BlenderMaterialBLSocket(base.MaxwellSimSocket):
|
||||||
####################
|
####################
|
||||||
# - Socket Configuration
|
# - Socket Configuration
|
||||||
####################
|
####################
|
||||||
class BlenderMaterialSocketDef(base.SocketDef):
|
class BlenderMaterialSocketDef(pyd.BaseModel):
|
||||||
socket_type: ct.SocketType = ct.SocketType.BlenderMaterial
|
socket_type: ct.SocketType = ct.SocketType.BlenderMaterial
|
||||||
|
|
||||||
def init(self, bl_socket: BlenderMaterialBLSocket) -> None:
|
def init(self, bl_socket: BlenderMaterialBLSocket) -> None:
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import bpy
|
import bpy
|
||||||
|
import pydantic as pyd
|
||||||
|
|
||||||
from ... import contracts as ct
|
from ... import contracts as ct
|
||||||
from .. import base
|
from .. import base
|
||||||
|
@ -87,7 +88,7 @@ class BlenderObjectBLSocket(base.MaxwellSimSocket):
|
||||||
####################
|
####################
|
||||||
# - Socket Configuration
|
# - Socket Configuration
|
||||||
####################
|
####################
|
||||||
class BlenderObjectSocketDef(base.SocketDef):
|
class BlenderObjectSocketDef(pyd.BaseModel):
|
||||||
socket_type: ct.SocketType = ct.SocketType.BlenderObject
|
socket_type: ct.SocketType = ct.SocketType.BlenderObject
|
||||||
|
|
||||||
def init(self, bl_socket: BlenderObjectBLSocket) -> None:
|
def init(self, bl_socket: BlenderObjectBLSocket) -> None:
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import bpy
|
import bpy
|
||||||
|
import pydantic as pyd
|
||||||
|
|
||||||
from ... import contracts as ct
|
from ... import contracts as ct
|
||||||
from .. import base
|
from .. import base
|
||||||
|
@ -42,7 +43,7 @@ class BlenderTextBLSocket(base.MaxwellSimSocket):
|
||||||
####################
|
####################
|
||||||
# - Socket Configuration
|
# - Socket Configuration
|
||||||
####################
|
####################
|
||||||
class BlenderTextSocketDef(base.SocketDef):
|
class BlenderTextSocketDef(pyd.BaseModel):
|
||||||
socket_type: ct.SocketType = ct.SocketType.BlenderText
|
socket_type: ct.SocketType = ct.SocketType.BlenderText
|
||||||
|
|
||||||
def init(self, bl_socket: BlenderTextBLSocket) -> None:
|
def init(self, bl_socket: BlenderTextBLSocket) -> None:
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import bpy
|
import bpy
|
||||||
|
import pydantic as pyd
|
||||||
import tidy3d as td
|
import tidy3d as td
|
||||||
import typing_extensions as typx
|
import typing_extensions as typx
|
||||||
|
|
||||||
|
@ -52,7 +53,7 @@ class MaxwellBoundCondBLSocket(base.MaxwellSimSocket):
|
||||||
####################
|
####################
|
||||||
# - Socket Configuration
|
# - Socket Configuration
|
||||||
####################
|
####################
|
||||||
class MaxwellBoundCondSocketDef(base.SocketDef):
|
class MaxwellBoundCondSocketDef(pyd.BaseModel):
|
||||||
socket_type: ct.SocketType = ct.SocketType.MaxwellBoundCond
|
socket_type: ct.SocketType = ct.SocketType.MaxwellBoundCond
|
||||||
|
|
||||||
default_choice: typx.Literal['PML', 'PEC', 'PMC', 'PERIODIC'] = 'PML'
|
default_choice: typx.Literal['PML', 'PEC', 'PMC', 'PERIODIC'] = 'PML'
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import bpy
|
import bpy
|
||||||
|
import pydantic as pyd
|
||||||
import tidy3d as td
|
import tidy3d as td
|
||||||
|
|
||||||
from ... import contracts as ct
|
from ... import contracts as ct
|
||||||
|
@ -123,7 +124,7 @@ class MaxwellBoundCondsBLSocket(base.MaxwellSimSocket):
|
||||||
####################
|
####################
|
||||||
# - Socket Configuration
|
# - Socket Configuration
|
||||||
####################
|
####################
|
||||||
class MaxwellBoundCondsSocketDef(base.SocketDef):
|
class MaxwellBoundCondsSocketDef(pyd.BaseModel):
|
||||||
socket_type: ct.SocketType = ct.SocketType.MaxwellBoundConds
|
socket_type: ct.SocketType = ct.SocketType.MaxwellBoundConds
|
||||||
|
|
||||||
def init(self, bl_socket: MaxwellBoundCondsBLSocket) -> None:
|
def init(self, bl_socket: MaxwellBoundCondsBLSocket) -> None:
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import pydantic as pyd
|
||||||
|
|
||||||
from ... import contracts as ct
|
from ... import contracts as ct
|
||||||
from .. import base
|
from .. import base
|
||||||
|
@ -15,7 +16,7 @@ class MaxwellFDTDSimBLSocket(base.MaxwellSimSocket):
|
||||||
####################
|
####################
|
||||||
# - Socket Configuration
|
# - Socket Configuration
|
||||||
####################
|
####################
|
||||||
class MaxwellFDTDSimSocketDef(base.SocketDef):
|
class MaxwellFDTDSimSocketDef(pyd.BaseModel):
|
||||||
socket_type: ct.SocketType = ct.SocketType.MaxwellFDTDSim
|
socket_type: ct.SocketType = ct.SocketType.MaxwellFDTDSim
|
||||||
|
|
||||||
def init(self, bl_socket: MaxwellFDTDSimBLSocket) -> None:
|
def init(self, bl_socket: MaxwellFDTDSimBLSocket) -> None:
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import pydantic as pyd
|
||||||
|
|
||||||
from ... import contracts as ct
|
from ... import contracts as ct
|
||||||
from .. import base
|
from .. import base
|
||||||
|
@ -15,7 +16,7 @@ class MaxwellFDTDSimDataBLSocket(base.MaxwellSimSocket):
|
||||||
####################
|
####################
|
||||||
# - Socket Configuration
|
# - Socket Configuration
|
||||||
####################
|
####################
|
||||||
class MaxwellFDTDSimDataSocketDef(base.SocketDef):
|
class MaxwellFDTDSimDataSocketDef(pyd.BaseModel):
|
||||||
socket_type: ct.SocketType = ct.SocketType.MaxwellFDTDSimData
|
socket_type: ct.SocketType = ct.SocketType.MaxwellFDTDSimData
|
||||||
|
|
||||||
def init(self, bl_socket: MaxwellFDTDSimDataBLSocket) -> None:
|
def init(self, bl_socket: MaxwellFDTDSimDataBLSocket) -> None:
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import bpy
|
import bpy
|
||||||
|
import pydantic as pyd
|
||||||
import scipy as sc
|
import scipy as sc
|
||||||
import sympy.physics.units as spu
|
import sympy.physics.units as spu
|
||||||
import tidy3d as td
|
import tidy3d as td
|
||||||
|
@ -97,7 +98,7 @@ class MaxwellMediumBLSocket(base.MaxwellSimSocket):
|
||||||
####################
|
####################
|
||||||
# - Socket Configuration
|
# - Socket Configuration
|
||||||
####################
|
####################
|
||||||
class MaxwellMediumSocketDef(base.SocketDef):
|
class MaxwellMediumSocketDef(pyd.BaseModel):
|
||||||
socket_type: ct.SocketType = ct.SocketType.MaxwellMedium
|
socket_type: ct.SocketType = ct.SocketType.MaxwellMedium
|
||||||
|
|
||||||
default_permittivity_real: float = 1.0
|
default_permittivity_real: float = 1.0
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import pydantic as pyd
|
||||||
|
|
||||||
from ... import contracts as ct
|
from ... import contracts as ct
|
||||||
from .. import base
|
from .. import base
|
||||||
|
@ -11,7 +12,7 @@ class MaxwellMediumNonLinearityBLSocket(base.MaxwellSimSocket):
|
||||||
####################
|
####################
|
||||||
# - Socket Configuration
|
# - Socket Configuration
|
||||||
####################
|
####################
|
||||||
class MaxwellMediumNonLinearitySocketDef(base.SocketDef):
|
class MaxwellMediumNonLinearitySocketDef(pyd.BaseModel):
|
||||||
socket_type: ct.SocketType = ct.SocketType.MaxwellMediumNonLinearity
|
socket_type: ct.SocketType = ct.SocketType.MaxwellMediumNonLinearity
|
||||||
|
|
||||||
def init(self, bl_socket: MaxwellMediumNonLinearityBLSocket) -> None:
|
def init(self, bl_socket: MaxwellMediumNonLinearityBLSocket) -> None:
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import pydantic as pyd
|
||||||
|
|
||||||
from ... import contracts as ct
|
from ... import contracts as ct
|
||||||
from .. import base
|
from .. import base
|
||||||
|
@ -11,7 +12,7 @@ class MaxwellMonitorBLSocket(base.MaxwellSimSocket):
|
||||||
####################
|
####################
|
||||||
# - Socket Configuration
|
# - Socket Configuration
|
||||||
####################
|
####################
|
||||||
class MaxwellMonitorSocketDef(base.SocketDef):
|
class MaxwellMonitorSocketDef(pyd.BaseModel):
|
||||||
socket_type: ct.SocketType = ct.SocketType.MaxwellMonitor
|
socket_type: ct.SocketType = ct.SocketType.MaxwellMonitor
|
||||||
|
|
||||||
is_list: bool = False
|
is_list: bool = False
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import pydantic as pyd
|
||||||
|
|
||||||
from ... import contracts as ct
|
from ... import contracts as ct
|
||||||
from .. import base
|
from .. import base
|
||||||
|
@ -11,7 +12,7 @@ class MaxwellSimDomainBLSocket(base.MaxwellSimSocket):
|
||||||
####################
|
####################
|
||||||
# - Socket Configuration
|
# - Socket Configuration
|
||||||
####################
|
####################
|
||||||
class MaxwellSimDomainSocketDef(base.SocketDef):
|
class MaxwellSimDomainSocketDef(pyd.BaseModel):
|
||||||
socket_type: ct.SocketType = ct.SocketType.MaxwellSimDomain
|
socket_type: ct.SocketType = ct.SocketType.MaxwellSimDomain
|
||||||
|
|
||||||
def init(self, bl_socket: MaxwellSimDomainBLSocket) -> None:
|
def init(self, bl_socket: MaxwellSimDomainBLSocket) -> None:
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import bpy
|
import bpy
|
||||||
|
import pydantic as pyd
|
||||||
import tidy3d as td
|
import tidy3d as td
|
||||||
|
|
||||||
from ... import contracts as ct
|
from ... import contracts as ct
|
||||||
|
@ -47,7 +48,7 @@ class MaxwellSimGridBLSocket(base.MaxwellSimSocket):
|
||||||
####################
|
####################
|
||||||
# - Socket Configuration
|
# - Socket Configuration
|
||||||
####################
|
####################
|
||||||
class MaxwellSimGridSocketDef(base.SocketDef):
|
class MaxwellSimGridSocketDef(pyd.BaseModel):
|
||||||
socket_type: ct.SocketType = ct.SocketType.MaxwellSimGrid
|
socket_type: ct.SocketType = ct.SocketType.MaxwellSimGrid
|
||||||
|
|
||||||
min_steps_per_wl: float = 10.0
|
min_steps_per_wl: float = 10.0
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import pydantic as pyd
|
||||||
|
|
||||||
from ... import contracts as ct
|
from ... import contracts as ct
|
||||||
from .. import base
|
from .. import base
|
||||||
|
@ -11,7 +12,7 @@ class MaxwellSimGridAxisBLSocket(base.MaxwellSimSocket):
|
||||||
####################
|
####################
|
||||||
# - Socket Configuration
|
# - Socket Configuration
|
||||||
####################
|
####################
|
||||||
class MaxwellSimGridAxisSocketDef(base.SocketDef):
|
class MaxwellSimGridAxisSocketDef(pyd.BaseModel):
|
||||||
socket_type: ct.SocketType = ct.SocketType.MaxwellSimGridAxis
|
socket_type: ct.SocketType = ct.SocketType.MaxwellSimGridAxis
|
||||||
|
|
||||||
def init(self, bl_socket: MaxwellSimGridAxisBLSocket) -> None:
|
def init(self, bl_socket: MaxwellSimGridAxisBLSocket) -> None:
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import pydantic as pyd
|
||||||
|
|
||||||
from ... import contracts as ct
|
from ... import contracts as ct
|
||||||
from .. import base
|
from .. import base
|
||||||
|
@ -11,7 +12,7 @@ class MaxwellSourceBLSocket(base.MaxwellSimSocket):
|
||||||
####################
|
####################
|
||||||
# - Socket Configuration
|
# - Socket Configuration
|
||||||
####################
|
####################
|
||||||
class MaxwellSourceSocketDef(base.SocketDef):
|
class MaxwellSourceSocketDef(pyd.BaseModel):
|
||||||
socket_type: ct.SocketType = ct.SocketType.MaxwellSource
|
socket_type: ct.SocketType = ct.SocketType.MaxwellSource
|
||||||
|
|
||||||
is_list: bool = False
|
is_list: bool = False
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import pydantic as pyd
|
||||||
|
|
||||||
from ... import contracts as ct
|
from ... import contracts as ct
|
||||||
from .. import base
|
from .. import base
|
||||||
|
@ -11,7 +12,7 @@ class MaxwellStructureBLSocket(base.MaxwellSimSocket):
|
||||||
####################
|
####################
|
||||||
# - Socket Configuration
|
# - Socket Configuration
|
||||||
####################
|
####################
|
||||||
class MaxwellStructureSocketDef(base.SocketDef):
|
class MaxwellStructureSocketDef(pyd.BaseModel):
|
||||||
socket_type: ct.SocketType = ct.SocketType.MaxwellStructure
|
socket_type: ct.SocketType = ct.SocketType.MaxwellStructure
|
||||||
|
|
||||||
is_list: bool = False
|
is_list: bool = False
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import pydantic as pyd
|
||||||
|
|
||||||
from ... import contracts as ct
|
from ... import contracts as ct
|
||||||
from .. import base
|
from .. import base
|
||||||
|
@ -11,7 +12,7 @@ class MaxwellTemporalShapeBLSocket(base.MaxwellSimSocket):
|
||||||
####################
|
####################
|
||||||
# - Socket Configuration
|
# - Socket Configuration
|
||||||
####################
|
####################
|
||||||
class MaxwellTemporalShapeSocketDef(base.SocketDef):
|
class MaxwellTemporalShapeSocketDef(pyd.BaseModel):
|
||||||
socket_type: ct.SocketType = ct.SocketType.MaxwellTemporalShape
|
socket_type: ct.SocketType = ct.SocketType.MaxwellTemporalShape
|
||||||
|
|
||||||
def init(self, bl_socket: MaxwellTemporalShapeBLSocket) -> None:
|
def init(self, bl_socket: MaxwellTemporalShapeBLSocket) -> None:
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import typing as typ
|
import typing as typ
|
||||||
|
|
||||||
import bpy
|
import bpy
|
||||||
|
import pydantic as pyd
|
||||||
import sympy as sp
|
import sympy as sp
|
||||||
|
|
||||||
from .....utils.pydantic_sympy import SympyExpr
|
from .....utils.pydantic_sympy import SympyExpr
|
||||||
|
@ -118,7 +119,7 @@ class ComplexNumberBLSocket(base.MaxwellSimSocket):
|
||||||
####################
|
####################
|
||||||
# - Socket Configuration
|
# - Socket Configuration
|
||||||
####################
|
####################
|
||||||
class ComplexNumberSocketDef(base.SocketDef):
|
class ComplexNumberSocketDef(pyd.BaseModel):
|
||||||
socket_type: ct.SocketType = ct.SocketType.ComplexNumber
|
socket_type: ct.SocketType = ct.SocketType.ComplexNumber
|
||||||
|
|
||||||
default_value: SympyExpr = sp.S(0 + 0j)
|
default_value: SympyExpr = sp.S(0 + 0j)
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import bpy
|
import bpy
|
||||||
|
import pydantic as pyd
|
||||||
|
|
||||||
from ... import contracts as ct
|
from ... import contracts as ct
|
||||||
from .. import base
|
from .. import base
|
||||||
|
@ -43,7 +44,7 @@ class IntegerNumberBLSocket(base.MaxwellSimSocket):
|
||||||
####################
|
####################
|
||||||
# - Socket Configuration
|
# - Socket Configuration
|
||||||
####################
|
####################
|
||||||
class IntegerNumberSocketDef(base.SocketDef):
|
class IntegerNumberSocketDef(pyd.BaseModel):
|
||||||
socket_type: ct.SocketType = ct.SocketType.IntegerNumber
|
socket_type: ct.SocketType = ct.SocketType.IntegerNumber
|
||||||
|
|
||||||
default_value: int = 0
|
default_value: int = 0
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import bpy
|
import bpy
|
||||||
|
import pydantic as pyd
|
||||||
import sympy as sp
|
import sympy as sp
|
||||||
|
|
||||||
from .....utils.pydantic_sympy import SympyExpr
|
from .....utils.pydantic_sympy import SympyExpr
|
||||||
|
@ -54,7 +55,7 @@ class RationalNumberBLSocket(base.MaxwellSimSocket):
|
||||||
####################
|
####################
|
||||||
# - Socket Configuration
|
# - Socket Configuration
|
||||||
####################
|
####################
|
||||||
class RationalNumberSocketDef(base.SocketDef):
|
class RationalNumberSocketDef(pyd.BaseModel):
|
||||||
socket_type: ct.SocketType = ct.SocketType.RationalNumber
|
socket_type: ct.SocketType = ct.SocketType.RationalNumber
|
||||||
|
|
||||||
default_value: SympyExpr = sp.Rational(0, 1)
|
default_value: SympyExpr = sp.Rational(0, 1)
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import bpy
|
import bpy
|
||||||
|
import pydantic as pyd
|
||||||
|
|
||||||
from .....utils.pydantic_sympy import SympyExpr
|
from .....utils.pydantic_sympy import SympyExpr
|
||||||
from ... import contracts as ct
|
from ... import contracts as ct
|
||||||
|
@ -48,7 +49,7 @@ class RealNumberBLSocket(base.MaxwellSimSocket):
|
||||||
####################
|
####################
|
||||||
# - Socket Configuration
|
# - Socket Configuration
|
||||||
####################
|
####################
|
||||||
class RealNumberSocketDef(base.SocketDef):
|
class RealNumberSocketDef(pyd.BaseModel):
|
||||||
socket_type: ct.SocketType = ct.SocketType.RealNumber
|
socket_type: ct.SocketType = ct.SocketType.RealNumber
|
||||||
|
|
||||||
default_value: float = 0.0
|
default_value: float = 0.0
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import bpy
|
import bpy
|
||||||
|
import pydantic as pyd
|
||||||
import sympy.physics.units as spu
|
import sympy.physics.units as spu
|
||||||
|
|
||||||
from .....utils.pydantic_sympy import SympyExpr
|
from .....utils.pydantic_sympy import SympyExpr
|
||||||
|
@ -46,7 +47,7 @@ class PhysicalAccelScalarBLSocket(base.MaxwellSimSocket):
|
||||||
####################
|
####################
|
||||||
# - Socket Configuration
|
# - Socket Configuration
|
||||||
####################
|
####################
|
||||||
class PhysicalAccelScalarSocketDef(base.SocketDef):
|
class PhysicalAccelScalarSocketDef(pyd.BaseModel):
|
||||||
socket_type: ct.SocketType = ct.SocketType.PhysicalAccelScalar
|
socket_type: ct.SocketType = ct.SocketType.PhysicalAccelScalar
|
||||||
|
|
||||||
default_unit: SympyExpr | None = None
|
default_unit: SympyExpr | None = None
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import bpy
|
import bpy
|
||||||
|
import pydantic as pyd
|
||||||
import sympy.physics.units as spu
|
import sympy.physics.units as spu
|
||||||
|
|
||||||
from .....utils.pydantic_sympy import SympyExpr
|
from .....utils.pydantic_sympy import SympyExpr
|
||||||
|
@ -46,7 +47,7 @@ class PhysicalAngleBLSocket(base.MaxwellSimSocket):
|
||||||
####################
|
####################
|
||||||
# - Socket Configuration
|
# - Socket Configuration
|
||||||
####################
|
####################
|
||||||
class PhysicalAngleSocketDef(base.SocketDef):
|
class PhysicalAngleSocketDef(pyd.BaseModel):
|
||||||
socket_type: ct.SocketType = ct.SocketType.PhysicalAngle
|
socket_type: ct.SocketType = ct.SocketType.PhysicalAngle
|
||||||
|
|
||||||
default_unit: SympyExpr | None = None
|
default_unit: SympyExpr | None = None
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import typing as typ
|
import typing as typ
|
||||||
|
|
||||||
import bpy
|
import bpy
|
||||||
|
import pydantic as pyd
|
||||||
import sympy as sp
|
import sympy as sp
|
||||||
|
|
||||||
from ... import contracts as ct
|
from ... import contracts as ct
|
||||||
|
@ -54,7 +55,7 @@ class PhysicalAreaBLSocket(base.MaxwellSimSocket):
|
||||||
####################
|
####################
|
||||||
# - Socket Configuration
|
# - Socket Configuration
|
||||||
####################
|
####################
|
||||||
class PhysicalAreaSocketDef(base.SocketDef):
|
class PhysicalAreaSocketDef(pyd.BaseModel):
|
||||||
socket_type: ct.SocketType = ct.SocketType.PhysicalArea
|
socket_type: ct.SocketType = ct.SocketType.PhysicalArea
|
||||||
|
|
||||||
default_unit: typ.Any | None = None
|
default_unit: typ.Any | None = None
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import bpy
|
import bpy
|
||||||
|
import pydantic as pyd
|
||||||
import sympy.physics.units as spu
|
import sympy.physics.units as spu
|
||||||
|
|
||||||
from .....utils.pydantic_sympy import SympyExpr
|
from .....utils.pydantic_sympy import SympyExpr
|
||||||
|
@ -46,7 +47,7 @@ class PhysicalForceScalarBLSocket(base.MaxwellSimSocket):
|
||||||
####################
|
####################
|
||||||
# - Socket Configuration
|
# - Socket Configuration
|
||||||
####################
|
####################
|
||||||
class PhysicalForceScalarSocketDef(base.SocketDef):
|
class PhysicalForceScalarSocketDef(pyd.BaseModel):
|
||||||
socket_type: ct.SocketType = ct.SocketType.PhysicalForceScalar
|
socket_type: ct.SocketType = ct.SocketType.PhysicalForceScalar
|
||||||
|
|
||||||
default_unit: SympyExpr | None = None
|
default_unit: SympyExpr | None = None
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
import bpy
|
import bpy
|
||||||
|
import pydantic as pyd
|
||||||
import sympy as sp
|
import sympy as sp
|
||||||
|
import sympy.physics.units as spu
|
||||||
|
|
||||||
from .....utils import extra_sympy_units as spux
|
from .....utils import extra_sympy_units as spux
|
||||||
from .....utils import logger
|
from .....utils import logger
|
||||||
|
@ -95,7 +97,7 @@ class PhysicalFreqBLSocket(base.MaxwellSimSocket):
|
||||||
####################
|
####################
|
||||||
# - Socket Configuration
|
# - Socket Configuration
|
||||||
####################
|
####################
|
||||||
class PhysicalFreqSocketDef(base.SocketDef):
|
class PhysicalFreqSocketDef(pyd.BaseModel):
|
||||||
socket_type: ct.SocketType = ct.SocketType.PhysicalFreq
|
socket_type: ct.SocketType = ct.SocketType.PhysicalFreq
|
||||||
is_array: bool = False
|
is_array: bool = False
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import bpy
|
import bpy
|
||||||
|
import pydantic as pyd
|
||||||
import sympy as sp
|
import sympy as sp
|
||||||
import sympy.physics.units as spu
|
import sympy.physics.units as spu
|
||||||
|
|
||||||
|
@ -95,7 +96,7 @@ class PhysicalLengthBLSocket(base.MaxwellSimSocket):
|
||||||
####################
|
####################
|
||||||
# - Socket Configuration
|
# - Socket Configuration
|
||||||
####################
|
####################
|
||||||
class PhysicalLengthSocketDef(base.SocketDef):
|
class PhysicalLengthSocketDef(pyd.BaseModel):
|
||||||
socket_type: ct.SocketType = ct.SocketType.PhysicalLength
|
socket_type: ct.SocketType = ct.SocketType.PhysicalLength
|
||||||
is_array: bool = False
|
is_array: bool = False
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import bpy
|
import bpy
|
||||||
|
import pydantic as pyd
|
||||||
import sympy.physics.units as spu
|
import sympy.physics.units as spu
|
||||||
|
|
||||||
from .....utils.pydantic_sympy import SympyExpr
|
from .....utils.pydantic_sympy import SympyExpr
|
||||||
|
@ -46,7 +47,7 @@ class PhysicalMassBLSocket(base.MaxwellSimSocket):
|
||||||
####################
|
####################
|
||||||
# - Socket Configuration
|
# - Socket Configuration
|
||||||
####################
|
####################
|
||||||
class PhysicalMassSocketDef(base.SocketDef):
|
class PhysicalMassSocketDef(pyd.BaseModel):
|
||||||
socket_type: ct.SocketType = ct.SocketType.PhysicalMass
|
socket_type: ct.SocketType = ct.SocketType.PhysicalMass
|
||||||
|
|
||||||
default_unit: SympyExpr | None = None
|
default_unit: SympyExpr | None = None
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import typing as typ
|
import typing as typ
|
||||||
|
|
||||||
import bpy
|
import bpy
|
||||||
|
import pydantic as pyd
|
||||||
import sympy as sp
|
import sympy as sp
|
||||||
import sympy.physics.units as spu
|
import sympy.physics.units as spu
|
||||||
|
|
||||||
|
@ -47,7 +48,7 @@ class PhysicalPoint3DBLSocket(base.MaxwellSimSocket):
|
||||||
####################
|
####################
|
||||||
# - Socket Configuration
|
# - Socket Configuration
|
||||||
####################
|
####################
|
||||||
class PhysicalPoint3DSocketDef(base.SocketDef):
|
class PhysicalPoint3DSocketDef(pyd.BaseModel):
|
||||||
socket_type: ct.SocketType = ct.SocketType.PhysicalPoint3D
|
socket_type: ct.SocketType = ct.SocketType.PhysicalPoint3D
|
||||||
|
|
||||||
default_unit: typ.Any | None = None
|
default_unit: typ.Any | None = None
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import bpy
|
import bpy
|
||||||
|
import pydantic as pyd
|
||||||
import sympy as sp
|
import sympy as sp
|
||||||
import sympy.physics.optics.polarization as spo_pol
|
import sympy.physics.optics.polarization as spo_pol
|
||||||
import sympy.physics.units as spu
|
import sympy.physics.units as spu
|
||||||
|
@ -236,7 +237,7 @@ class PhysicalPolBLSocket(base.MaxwellSimSocket):
|
||||||
####################
|
####################
|
||||||
# - Socket Configuration
|
# - Socket Configuration
|
||||||
####################
|
####################
|
||||||
class PhysicalPolSocketDef(base.SocketDef):
|
class PhysicalPolSocketDef(pyd.BaseModel):
|
||||||
socket_type: ct.SocketType = ct.SocketType.PhysicalPol
|
socket_type: ct.SocketType = ct.SocketType.PhysicalPol
|
||||||
|
|
||||||
def init(self, bl_socket: PhysicalPolBLSocket) -> None:
|
def init(self, bl_socket: PhysicalPolBLSocket) -> None:
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import bpy
|
import bpy
|
||||||
|
import pydantic as pyd
|
||||||
import sympy as sp
|
import sympy as sp
|
||||||
import sympy.physics.units as spu
|
import sympy.physics.units as spu
|
||||||
|
|
||||||
|
@ -45,7 +46,7 @@ class PhysicalSize3DBLSocket(base.MaxwellSimSocket):
|
||||||
####################
|
####################
|
||||||
# - Socket Configuration
|
# - Socket Configuration
|
||||||
####################
|
####################
|
||||||
class PhysicalSize3DSocketDef(base.SocketDef):
|
class PhysicalSize3DSocketDef(pyd.BaseModel):
|
||||||
socket_type: ct.SocketType = ct.SocketType.PhysicalSize3D
|
socket_type: ct.SocketType = ct.SocketType.PhysicalSize3D
|
||||||
|
|
||||||
default_value: SympyExpr = sp.Matrix([1, 1, 1]) * spu.um
|
default_value: SympyExpr = sp.Matrix([1, 1, 1]) * spu.um
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import bpy
|
import bpy
|
||||||
|
import pydantic as pyd
|
||||||
import sympy.physics.units as spu
|
import sympy.physics.units as spu
|
||||||
|
|
||||||
from .....utils.pydantic_sympy import SympyExpr
|
from .....utils.pydantic_sympy import SympyExpr
|
||||||
|
@ -46,7 +47,7 @@ class PhysicalSpeedBLSocket(base.MaxwellSimSocket):
|
||||||
####################
|
####################
|
||||||
# - Socket Configuration
|
# - Socket Configuration
|
||||||
####################
|
####################
|
||||||
class PhysicalSpeedSocketDef(base.SocketDef):
|
class PhysicalSpeedSocketDef(pyd.BaseModel):
|
||||||
socket_type: ct.SocketType = ct.SocketType.PhysicalSpeed
|
socket_type: ct.SocketType = ct.SocketType.PhysicalSpeed
|
||||||
|
|
||||||
default_unit: SympyExpr | None = None
|
default_unit: SympyExpr | None = None
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import typing as typ
|
import typing as typ
|
||||||
|
|
||||||
import bpy
|
import bpy
|
||||||
|
import pydantic as pyd
|
||||||
import sympy.physics.units as spu
|
import sympy.physics.units as spu
|
||||||
|
|
||||||
from .....utils.pydantic_sympy import SympyExpr
|
from .....utils.pydantic_sympy import SympyExpr
|
||||||
|
@ -48,7 +49,7 @@ class PhysicalTimeBLSocket(base.MaxwellSimSocket):
|
||||||
####################
|
####################
|
||||||
# - Socket Configuration
|
# - Socket Configuration
|
||||||
####################
|
####################
|
||||||
class PhysicalTimeSocketDef(base.SocketDef):
|
class PhysicalTimeSocketDef(pyd.BaseModel):
|
||||||
socket_type: ct.SocketType = ct.SocketType.PhysicalTime
|
socket_type: ct.SocketType = ct.SocketType.PhysicalTime
|
||||||
|
|
||||||
default_value: SympyExpr | None = None
|
default_value: SympyExpr | None = None
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import bpy
|
import bpy
|
||||||
|
import pydantic as pyd
|
||||||
|
|
||||||
from .....utils.pydantic_sympy import SympyExpr
|
from .....utils.pydantic_sympy import SympyExpr
|
||||||
from ... import contracts as ct
|
from ... import contracts as ct
|
||||||
|
@ -272,7 +273,7 @@ class PhysicalUnitSystemBLSocket(base.MaxwellSimSocket):
|
||||||
####################
|
####################
|
||||||
# - Socket Configuration
|
# - Socket Configuration
|
||||||
####################
|
####################
|
||||||
class PhysicalUnitSystemSocketDef(base.SocketDef):
|
class PhysicalUnitSystemSocketDef(pyd.BaseModel):
|
||||||
socket_type: ST = ST.PhysicalUnitSystem
|
socket_type: ST = ST.PhysicalUnitSystem
|
||||||
|
|
||||||
show_by_default: bool = False
|
show_by_default: bool = False
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import bpy
|
import bpy
|
||||||
|
import pydantic as pyd
|
||||||
import sympy.physics.units as spu
|
import sympy.physics.units as spu
|
||||||
|
|
||||||
from .....utils.pydantic_sympy import SympyExpr
|
from .....utils.pydantic_sympy import SympyExpr
|
||||||
|
@ -43,7 +44,7 @@ class PhysicalVolumeBLSocket(base.MaxwellSimSocket):
|
||||||
####################
|
####################
|
||||||
# - Socket Configuration
|
# - Socket Configuration
|
||||||
####################
|
####################
|
||||||
class PhysicalVolumeSocketDef(base.SocketDef):
|
class PhysicalVolumeSocketDef(pyd.BaseModel):
|
||||||
socket_type: ct.SocketType = ct.SocketType.PhysicalVolume
|
socket_type: ct.SocketType = ct.SocketType.PhysicalVolume
|
||||||
|
|
||||||
default_unit: SympyExpr | None = None
|
default_unit: SympyExpr | None = None
|
||||||
|
|
|
@ -3,10 +3,9 @@ import types
|
||||||
from .. import contracts as ct
|
from .. import contracts as ct
|
||||||
|
|
||||||
|
|
||||||
## TODO: Replace with BL_SOCKET_DEFS export from each module, a little like BL_NODES.
|
|
||||||
def scan_for_socket_defs(
|
def scan_for_socket_defs(
|
||||||
sockets_module: types.ModuleType,
|
sockets_module: types.ModuleType,
|
||||||
) -> dict:
|
) -> dict[ct.SocketType, type[ct.schemas.SocketDef]]:
|
||||||
return {
|
return {
|
||||||
socket_type: getattr(
|
socket_type: getattr(
|
||||||
sockets_module,
|
sockets_module,
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import bpy
|
import bpy
|
||||||
|
import pydantic as pyd
|
||||||
|
|
||||||
from .....services import tdcloud
|
from .....services import tdcloud
|
||||||
from ... import contracts as ct
|
from ... import contracts as ct
|
||||||
|
@ -318,7 +319,7 @@ class Tidy3DCloudTaskBLSocket(base.MaxwellSimSocket):
|
||||||
####################
|
####################
|
||||||
# - Socket Configuration
|
# - Socket Configuration
|
||||||
####################
|
####################
|
||||||
class Tidy3DCloudTaskSocketDef(base.SocketDef):
|
class Tidy3DCloudTaskSocketDef(pyd.BaseModel):
|
||||||
socket_type: ct.SocketType = ct.SocketType.Tidy3DCloudTask
|
socket_type: ct.SocketType = ct.SocketType.Tidy3DCloudTask
|
||||||
|
|
||||||
should_exist: bool
|
should_exist: bool
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import pydantic as pyd
|
||||||
|
|
||||||
from ... import contracts as ct
|
from ... import contracts as ct
|
||||||
from .. import base
|
from .. import base
|
||||||
|
@ -14,7 +15,7 @@ class Complex2DVectorBLSocket(base.MaxwellSimSocket):
|
||||||
####################
|
####################
|
||||||
# - Socket Configuration
|
# - Socket Configuration
|
||||||
####################
|
####################
|
||||||
class Complex2DVectorSocketDef(base.SocketDef):
|
class Complex2DVectorSocketDef(pyd.BaseModel):
|
||||||
socket_type: ct.SocketType = ct.SocketType.Complex2DVector
|
socket_type: ct.SocketType = ct.SocketType.Complex2DVector
|
||||||
|
|
||||||
def init(self, bl_socket: Complex2DVectorBLSocket) -> None:
|
def init(self, bl_socket: Complex2DVectorBLSocket) -> None:
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import pydantic as pyd
|
||||||
|
|
||||||
from ... import contracts as ct
|
from ... import contracts as ct
|
||||||
from .. import base
|
from .. import base
|
||||||
|
@ -14,7 +15,7 @@ class Complex3DVectorBLSocket(base.MaxwellSimSocket):
|
||||||
####################
|
####################
|
||||||
# - Socket Configuration
|
# - Socket Configuration
|
||||||
####################
|
####################
|
||||||
class Complex3DVectorSocketDef(base.SocketDef):
|
class Complex3DVectorSocketDef(pyd.BaseModel):
|
||||||
socket_type: ct.SocketType = ct.SocketType.Complex3DVector
|
socket_type: ct.SocketType = ct.SocketType.Complex3DVector
|
||||||
|
|
||||||
def init(self, bl_socket: Complex3DVectorBLSocket) -> None:
|
def init(self, bl_socket: Complex3DVectorBLSocket) -> None:
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import bpy
|
import bpy
|
||||||
|
import pydantic as pyd
|
||||||
import sympy as sp
|
import sympy as sp
|
||||||
|
|
||||||
from .....utils.pydantic_sympy import ConstrSympyExpr
|
from .....utils.pydantic_sympy import ConstrSympyExpr
|
||||||
|
@ -53,7 +54,7 @@ class Integer3DVectorBLSocket(base.MaxwellSimSocket):
|
||||||
####################
|
####################
|
||||||
# - Socket Configuration
|
# - Socket Configuration
|
||||||
####################
|
####################
|
||||||
class Integer3DVectorSocketDef(base.SocketDef):
|
class Integer3DVectorSocketDef(pyd.BaseModel):
|
||||||
socket_type: ct.SocketType = ct.SocketType.Integer3DVector
|
socket_type: ct.SocketType = ct.SocketType.Integer3DVector
|
||||||
|
|
||||||
default_value: Integer3DVector = sp.Matrix([0, 0, 0])
|
default_value: Integer3DVector = sp.Matrix([0, 0, 0])
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import bpy
|
import bpy
|
||||||
|
import pydantic as pyd
|
||||||
import sympy as sp
|
import sympy as sp
|
||||||
|
|
||||||
from .....utils.pydantic_sympy import ConstrSympyExpr
|
from .....utils.pydantic_sympy import ConstrSympyExpr
|
||||||
|
@ -54,7 +55,7 @@ class Real2DVectorBLSocket(base.MaxwellSimSocket):
|
||||||
####################
|
####################
|
||||||
# - Socket Configuration
|
# - Socket Configuration
|
||||||
####################
|
####################
|
||||||
class Real2DVectorSocketDef(base.SocketDef):
|
class Real2DVectorSocketDef(pyd.BaseModel):
|
||||||
socket_type: ct.SocketType = ct.SocketType.Real2DVector
|
socket_type: ct.SocketType = ct.SocketType.Real2DVector
|
||||||
|
|
||||||
default_value: Real2DVector = sp.Matrix([0.0, 0.0])
|
default_value: Real2DVector = sp.Matrix([0.0, 0.0])
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import bpy
|
import bpy
|
||||||
|
import pydantic as pyd
|
||||||
import sympy as sp
|
import sympy as sp
|
||||||
|
|
||||||
from .....utils.pydantic_sympy import ConstrSympyExpr
|
from .....utils.pydantic_sympy import ConstrSympyExpr
|
||||||
|
@ -54,7 +55,7 @@ class Real3DVectorBLSocket(base.MaxwellSimSocket):
|
||||||
####################
|
####################
|
||||||
# - Socket Configuration
|
# - Socket Configuration
|
||||||
####################
|
####################
|
||||||
class Real3DVectorSocketDef(base.SocketDef):
|
class Real3DVectorSocketDef(pyd.BaseModel):
|
||||||
socket_type: ct.SocketType = ct.SocketType.Real3DVector
|
socket_type: ct.SocketType = ct.SocketType.Real3DVector
|
||||||
|
|
||||||
default_value: Real3DVector = sp.Matrix([0.0, 0.0, 0.0])
|
default_value: Real3DVector = sp.Matrix([0.0, 0.0, 0.0])
|
||||||
|
|
|
@ -5,8 +5,6 @@ import typing as typ
|
||||||
import sympy as sp
|
import sympy as sp
|
||||||
import sympy.physics.units as spu
|
import sympy.physics.units as spu
|
||||||
|
|
||||||
SympyType = sp.Basic | sp.Expr | sp.MatrixBase | spu.Quantity
|
|
||||||
|
|
||||||
|
|
||||||
####################
|
####################
|
||||||
# - Useful Methods
|
# - Useful Methods
|
||||||
|
|
|
@ -1,182 +0,0 @@
|
||||||
"""Robust serialization tool for use in the addon.
|
|
||||||
|
|
||||||
Attributes:
|
|
||||||
NaiveEncodableType: See <https://jcristharif.com/msgspec/supported-types.html> for details.
|
|
||||||
"""
|
|
||||||
|
|
||||||
import dataclasses
|
|
||||||
import datetime as dt
|
|
||||||
import decimal
|
|
||||||
import enum
|
|
||||||
import functools
|
|
||||||
import typing as typ
|
|
||||||
import uuid
|
|
||||||
|
|
||||||
import msgspec
|
|
||||||
import sympy as sp
|
|
||||||
|
|
||||||
from . import extra_sympy_units as spux
|
|
||||||
from . import logger
|
|
||||||
|
|
||||||
log = logger.get(__name__)
|
|
||||||
|
|
||||||
####################
|
|
||||||
# - Serialization Types
|
|
||||||
####################
|
|
||||||
NaivelyEncodableType: typ.TypeAlias = (
|
|
||||||
None
|
|
||||||
| bool
|
|
||||||
| int
|
|
||||||
| float
|
|
||||||
| str
|
|
||||||
| bytes
|
|
||||||
| bytearray
|
|
||||||
## NO SUPPORT:
|
|
||||||
# | memoryview
|
|
||||||
| tuple
|
|
||||||
| list
|
|
||||||
| dict
|
|
||||||
| set
|
|
||||||
| frozenset
|
|
||||||
## NO SUPPORT:
|
|
||||||
# | typ.Literal
|
|
||||||
| typ.Collection
|
|
||||||
## NO SUPPORT:
|
|
||||||
# | typ.Sequence ## -> list
|
|
||||||
# | typ.MutableSequence ## -> list
|
|
||||||
# | typ.AbstractSet ## -> set
|
|
||||||
# | typ.MutableSet ## -> set
|
|
||||||
# | typ.Mapping ## -> dict
|
|
||||||
# | typ.MutableMapping ## -> dict
|
|
||||||
| typ.TypedDict
|
|
||||||
| typ.NamedTuple
|
|
||||||
| dt.datetime
|
|
||||||
| dt.date
|
|
||||||
| dt.time
|
|
||||||
| dt.timedelta
|
|
||||||
| uuid.UUID
|
|
||||||
| decimal.Decimal
|
|
||||||
## NO SUPPORT:
|
|
||||||
# | enum.Enum
|
|
||||||
| enum.IntEnum
|
|
||||||
| enum.Flag
|
|
||||||
| enum.IntFlag
|
|
||||||
| dataclasses.dataclass
|
|
||||||
| typ.Optional[typ.Any] # noqa: UP007
|
|
||||||
| typ.Union[typ.Any, ...] # noqa: UP007
|
|
||||||
| typ.NewType
|
|
||||||
| typ.TypeAlias
|
|
||||||
## SUPPORT:
|
|
||||||
# | typ.Generic[typ.Any]
|
|
||||||
# | typ.TypeVar
|
|
||||||
# | typ.Final
|
|
||||||
| msgspec.Raw
|
|
||||||
## NO SUPPORT:
|
|
||||||
# | msgspec.UNSET
|
|
||||||
)
|
|
||||||
_NaivelyEncodableTypeSet = frozenset(typ.get_args(NaivelyEncodableType))
|
|
||||||
## TODO: Use for runtime type check? Beartype?
|
|
||||||
|
|
||||||
|
|
||||||
class TypeID(enum.StrEnum):
|
|
||||||
Complex: str = '!type=complex'
|
|
||||||
SympyType: str = '!type=sympytype'
|
|
||||||
SocketDef: str = '!type=socketdef'
|
|
||||||
ManagedObj: str = '!type=managedobj'
|
|
||||||
|
|
||||||
|
|
||||||
NaiveRepresentation: typ.TypeAlias = list[TypeID, str | None, typ.Any]
|
|
||||||
|
|
||||||
|
|
||||||
def is_representation(obj: NaivelyEncodableType) -> bool:
|
|
||||||
return isinstance(obj, list) and len(obj) == 3 and obj[0] in set(TypeID) # noqa: PLR2004
|
|
||||||
|
|
||||||
|
|
||||||
####################
|
|
||||||
# - Serialization Hooks
|
|
||||||
####################
|
|
||||||
def _enc_hook(obj: typ.Any) -> NaivelyEncodableType:
|
|
||||||
"""Translates types not natively supported by `msgspec`, to an encodable form supported by `msgspec`.
|
|
||||||
|
|
||||||
Parameters:
|
|
||||||
obj: The object of arbitrary type to transform into an encodable value.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
A value encodable by `msgspec`.
|
|
||||||
|
|
||||||
Raises:
|
|
||||||
NotImplementedError: When the type transformation hasn't been implemented.
|
|
||||||
"""
|
|
||||||
if isinstance(obj, complex):
|
|
||||||
return ['!type=complex', None, (obj.real, obj.imag)]
|
|
||||||
|
|
||||||
if isinstance(obj, spux.SympyType):
|
|
||||||
return ['!type=sympytype', None, sp.srepr(obj)]
|
|
||||||
|
|
||||||
if hasattr(obj, 'dump_as_msgspec'):
|
|
||||||
return obj.dump_as_msgspec()
|
|
||||||
|
|
||||||
msg = f'Can\'t encode "{obj}" of type {type(obj)}'
|
|
||||||
raise NotImplementedError(msg)
|
|
||||||
|
|
||||||
|
|
||||||
def _dec_hook(_type: type, obj: NaivelyEncodableType) -> typ.Any:
|
|
||||||
"""Translates the `msgspec`-encoded form of an object back to its true form.
|
|
||||||
|
|
||||||
Parameters:
|
|
||||||
_type: The type to transform the `msgspec`-encoded object back into.
|
|
||||||
obj: The naively decoded object to transform back into its actual type.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
A value encodable by `msgspec`.
|
|
||||||
|
|
||||||
Raises:
|
|
||||||
NotImplementedError: When the type transformation hasn't been implemented.
|
|
||||||
"""
|
|
||||||
if _type is complex or (is_representation(obj) and obj[0] == TypeID.Complex):
|
|
||||||
obj_value = obj[2]
|
|
||||||
return complex(obj_value[0], obj_value[1])
|
|
||||||
|
|
||||||
if _type in typ.get_args(spux.SympyType) or (
|
|
||||||
is_representation(obj) and obj[0] == TypeID.SympyType
|
|
||||||
):
|
|
||||||
obj_value = obj[2]
|
|
||||||
return sp.sympify(obj_value).subs(spux.ALL_UNIT_SYMBOLS)
|
|
||||||
|
|
||||||
if hasattr(_type, 'parse_as_msgspec') and (
|
|
||||||
is_representation(obj) and obj[0] in [TypeID.SocketDef, TypeID.ManagedObj]
|
|
||||||
):
|
|
||||||
return _type.parse_as_msgspec(obj)
|
|
||||||
|
|
||||||
msg = f'Can\'t decode "{obj}" to type {type(obj)}'
|
|
||||||
raise NotImplementedError(msg)
|
|
||||||
|
|
||||||
|
|
||||||
####################
|
|
||||||
# - Global Encoders / Decoders
|
|
||||||
####################
|
|
||||||
_ENCODER = msgspec.json.Encoder(enc_hook=_enc_hook, order='deterministic')
|
|
||||||
|
|
||||||
|
|
||||||
@functools.cache
|
|
||||||
def _DECODER(_type: type) -> msgspec.json.Decoder: # noqa: N802
|
|
||||||
"""Retrieve a suitable `msgspec.json.Decoder` by-type.
|
|
||||||
|
|
||||||
Parameters:
|
|
||||||
_type: The type to retrieve a decoder for.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
A suitable decoder.
|
|
||||||
"""
|
|
||||||
return msgspec.json.Decoder(type=_type, dec_hook=_dec_hook)
|
|
||||||
|
|
||||||
|
|
||||||
####################
|
|
||||||
# - Encoder / Decoder Functions
|
|
||||||
####################
|
|
||||||
def encode(obj: typ.Any) -> bytes:
|
|
||||||
return _ENCODER.encode(obj)
|
|
||||||
|
|
||||||
|
|
||||||
def decode(_type: type, obj: str | bytes) -> typ.Any:
|
|
||||||
return _DECODER(_type).decode(obj)
|
|
|
@ -9,6 +9,7 @@ import bpy
|
||||||
PATH_SCRIPT = str(Path(__file__).resolve().parent)
|
PATH_SCRIPT = str(Path(__file__).resolve().parent)
|
||||||
sys.path.insert(0, str(PATH_SCRIPT))
|
sys.path.insert(0, str(PATH_SCRIPT))
|
||||||
import info # noqa: E402
|
import info # noqa: E402
|
||||||
|
import pack # noqa: E402
|
||||||
|
|
||||||
sys.path.remove(str(PATH_SCRIPT))
|
sys.path.remove(str(PATH_SCRIPT))
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue