fix: @base event callbacks now use @events

main
Sofus Albert Høgsbro Rose 2024-04-02 20:49:57 +02:00
parent 01cfc61094
commit a282d1e7ef
Signed by: so-rose
GPG Key ID: AD901CB0F3701434
88 changed files with 219 additions and 420 deletions

View File

@ -59,10 +59,7 @@ def import_geonodes(
- Retrieve the node group and return it. - Retrieve the node group and return it.
""" """
if geonodes in bpy.data.node_groups and not force_import: if geonodes in bpy.data.node_groups and not force_import:
log.info( log.info('Found Existing GeoNodes Tree (name=%s)', geonodes)
'Found Existing GeoNodes Tree (name=%s)',
geonodes
)
return bpy.data.node_groups[geonodes] return bpy.data.node_groups[geonodes]
filename = geonodes filename = geonodes
@ -72,7 +69,7 @@ def import_geonodes(
directory = filepath.removesuffix(geonodes) directory = filepath.removesuffix(geonodes)
log.info( log.info(
'%s GeoNodes (filename=%s, directory=%s, filepath=%s)', '%s GeoNodes (filename=%s, directory=%s, filepath=%s)',
"Linking" if import_method == 'link' else "Appending", 'Linking' if import_method == 'link' else 'Appending',
filename, filename,
directory, directory,
filepath, filepath,

View File

@ -82,9 +82,7 @@ BL_NODE_CATEGORIES = mk_node_categories(
syllable_prefix=['MAXWELLSIM'], syllable_prefix=['MAXWELLSIM'],
) )
## TODO: refactor, this has a big code smell ## TODO: refactor, this has a big code smell
BL_REGISTER = [ BL_REGISTER = [*DYNAMIC_SUBMENU_REGISTRATIONS] ## Must be run after, right now.
*DYNAMIC_SUBMENU_REGISTRATIONS
] ## Must be run after, right now.
## TEST - TODO this is a big code smell ## TEST - TODO this is a big code smell

View File

@ -1,4 +1,3 @@
from .socket_types import SocketType as ST from .socket_types import SocketType as ST
## TODO: Don't just presume sRGB. ## TODO: Don't just presume sRGB.

View File

@ -6,11 +6,9 @@ BL_SOCKET_DIRECT_TYPE_MAP = {
('NodeSocketImage', 1): ST.BlenderImage, ('NodeSocketImage', 1): ST.BlenderImage,
('NodeSocketObject', 1): ST.BlenderObject, ('NodeSocketObject', 1): ST.BlenderObject,
('NodeSocketMaterial', 1): ST.BlenderMaterial, ('NodeSocketMaterial', 1): ST.BlenderMaterial,
# Basic # Basic
('NodeSocketString', 1): ST.String, ('NodeSocketString', 1): ST.String,
('NodeSocketBool', 1): ST.Bool, ('NodeSocketBool', 1): ST.Bool,
# Float # Float
('NodeSocketFloat', 1): ST.RealNumber, ('NodeSocketFloat', 1): ST.RealNumber,
# ("NodeSocketFloatAngle", 1): ST.PhysicalAngle, # ("NodeSocketFloatAngle", 1): ST.PhysicalAngle,
@ -19,17 +17,14 @@ BL_SOCKET_DIRECT_TYPE_MAP = {
('NodeSocketFloatPercentage', 1): ST.RealNumber, ('NodeSocketFloatPercentage', 1): ST.RealNumber,
# ("NodeSocketFloatTime", 1): ST.PhysicalTime, # ("NodeSocketFloatTime", 1): ST.PhysicalTime,
# ("NodeSocketFloatTimeAbsolute", 1): ST.PhysicalTime, # ("NodeSocketFloatTimeAbsolute", 1): ST.PhysicalTime,
# Int # Int
('NodeSocketInt', 1): ST.IntegerNumber, ('NodeSocketInt', 1): ST.IntegerNumber,
('NodeSocketIntFactor', 1): ST.IntegerNumber, ('NodeSocketIntFactor', 1): ST.IntegerNumber,
('NodeSocketIntPercentage', 1): ST.IntegerNumber, ('NodeSocketIntPercentage', 1): ST.IntegerNumber,
('NodeSocketIntUnsigned', 1): ST.IntegerNumber, ('NodeSocketIntUnsigned', 1): ST.IntegerNumber,
# Array-Like # Array-Like
('NodeSocketColor', 3): ST.Color, ('NodeSocketColor', 3): ST.Color,
('NodeSocketRotation', 2): ST.PhysicalRot2D, ('NodeSocketRotation', 2): ST.PhysicalRot2D,
('NodeSocketVector', 2): ST.Real2DVector, ('NodeSocketVector', 2): ST.Real2DVector,
('NodeSocketVector', 3): ST.Real3DVector, ('NodeSocketVector', 3): ST.Real3DVector,
# ("NodeSocketVectorAcceleration", 2): ST.PhysicalAccel2D, # ("NodeSocketVectorAcceleration", 2): ST.PhysicalAccel2D,

View File

@ -1,11 +1,11 @@
from .managed_bl_empty import ManagedBLEmpty from .managed_bl_empty import ManagedBLEmpty
from .managed_bl_image import ManagedBLImage from .managed_bl_image import ManagedBLImage
#from .managed_bl_collection import ManagedBLCollection # from .managed_bl_collection import ManagedBLCollection
#from .managed_bl_object import ManagedBLObject # from .managed_bl_object import ManagedBLObject
from .managed_bl_mesh import ManagedBLMesh 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
__all__ = [ __all__ = [

View File

@ -107,9 +107,7 @@ class ManagedBLImage(ct.schemas.ManagedObj):
""" """
if preview_area := self.preview_area: if preview_area := self.preview_area:
return next( return next(
space space for space in preview_area.spaces if space.type == SPACE_TYPE
for space in preview_area.spaces
if space.type == SPACE_TYPE
) )
#################### ####################

View File

@ -2,15 +2,15 @@
# from . import bounds # from . import bounds
from . import ( from . import (
inputs, inputs,
mediums, mediums,
monitors, monitors,
outputs, outputs,
simulations, simulations,
sources, sources,
structures, structures,
utilities, utilities,
viz, viz,
) )
BL_REGISTER = [ BL_REGISTER = [

View File

@ -2,7 +2,7 @@ import tidy3d as td
from ... import contracts as ct from ... import contracts as ct
from ... import sockets from ... import sockets
from .. import base from .. import base, events
class BoundCondsNode(base.MaxwellSimNode): class BoundCondsNode(base.MaxwellSimNode):
@ -28,7 +28,7 @@ class BoundCondsNode(base.MaxwellSimNode):
#################### ####################
# - Output Socket Computation # - Output Socket Computation
#################### ####################
@base.computes_output_socket( @events.computes_output_socket(
'BCs', input_sockets={'+X', '-X', '+Y', '-Y', '+Z', '-Z'} 'BCs', input_sockets={'+X', '-X', '+Y', '-Y', '+Z', '-Z'}
) )
def compute_simulation(self, input_sockets) -> td.BoundarySpec: def compute_simulation(self, input_sockets) -> td.BoundarySpec:

View File

@ -1,10 +1,10 @@
from . import ( from . import (
absorbing_bound_face, absorbing_bound_face,
bloch_bound_face, bloch_bound_face,
pec_bound_face, pec_bound_face,
periodic_bound_face, periodic_bound_face,
pmc_bound_face, pmc_bound_face,
pml_bound_face, pml_bound_face,
) )
BL_REGISTER = [ BL_REGISTER = [

View File

@ -1,8 +1,8 @@
from . import ( from . import (
constants, constants,
unit_system, unit_system,
wave_constant, wave_constant,
web_importers, web_importers,
) )
# from . import file_importers # from . import file_importers

View File

@ -2,7 +2,7 @@ import typing as typ
from .... import contracts as ct from .... import contracts as ct
from .... import sockets from .... import sockets
from ... import base from ... import base, events
class BlenderConstantNode(base.MaxwellSimNode): class BlenderConstantNode(base.MaxwellSimNode):
@ -31,7 +31,7 @@ class BlenderConstantNode(base.MaxwellSimNode):
#################### ####################
# - Callbacks # - Callbacks
#################### ####################
@base.computes_output_socket('Value', input_sockets={'Value'}) @events.computes_output_socket('Value', input_sockets={'Value'})
def compute_value(self, input_sockets) -> typ.Any: def compute_value(self, input_sockets) -> typ.Any:
return input_sockets['Value'] return input_sockets['Value']

View File

@ -2,7 +2,7 @@ import typing as typ
from .... import contracts as ct from .... import contracts as ct
from .... import sockets from .... import sockets
from ... import base from ... import base, events
class NumberConstantNode(base.MaxwellSimNode): class NumberConstantNode(base.MaxwellSimNode):
@ -28,7 +28,7 @@ class NumberConstantNode(base.MaxwellSimNode):
#################### ####################
# - Callbacks # - Callbacks
#################### ####################
@base.computes_output_socket('Value', input_sockets={'Value'}) @events.computes_output_socket('Value', input_sockets={'Value'})
def compute_value(self, input_sockets) -> typ.Any: def compute_value(self, input_sockets) -> typ.Any:
return input_sockets['Value'] return input_sockets['Value']
@ -39,6 +39,4 @@ class NumberConstantNode(base.MaxwellSimNode):
BL_REGISTER = [ BL_REGISTER = [
NumberConstantNode, NumberConstantNode,
] ]
BL_NODES = { BL_NODES = {ct.NodeType.NumberConstant: (ct.NodeCategory.MAXWELLSIM_INPUTS_CONSTANTS)}
ct.NodeType.NumberConstant: (ct.NodeCategory.MAXWELLSIM_INPUTS_CONSTANTS)
}

View File

@ -1,6 +1,6 @@
from ... import contracts as ct from ... import contracts as ct
from ... import sockets from ... import sockets
from .. import base from .. import base, events
class PhysicalUnitSystemNode(base.MaxwellSimNode): class PhysicalUnitSystemNode(base.MaxwellSimNode):
@ -19,7 +19,7 @@ class PhysicalUnitSystemNode(base.MaxwellSimNode):
#################### ####################
# - Callbacks # - Callbacks
#################### ####################
@base.computes_output_socket( @events.computes_output_socket(
'Unit System', 'Unit System',
input_sockets={'Unit System'}, input_sockets={'Unit System'},
) )

View File

@ -7,7 +7,7 @@ from .....utils import extra_sympy_units as spux
from .....utils import sci_constants as constants from .....utils import sci_constants as constants
from ... import contracts as ct from ... import contracts as ct
from ... import sockets from ... import sockets
from .. import base from .. import base, events
class WaveConstantNode(base.MaxwellSimNode): class WaveConstantNode(base.MaxwellSimNode):
@ -44,7 +44,7 @@ class WaveConstantNode(base.MaxwellSimNode):
#################### ####################
# - Event Methods: Listy Output # - Event Methods: Listy Output
#################### ####################
@base.computes_output_socket( @events.computes_output_socket(
'WL', 'WL',
input_sockets={'WL', 'Freq'}, input_sockets={'WL', 'Freq'},
) )
@ -57,7 +57,7 @@ class WaveConstantNode(base.MaxwellSimNode):
msg = 'Vac WL and Freq are both None' msg = 'Vac WL and Freq are both None'
raise RuntimeError(msg) raise RuntimeError(msg)
@base.computes_output_socket( @events.computes_output_socket(
'Freq', 'Freq',
input_sockets={'WL', 'Freq'}, input_sockets={'WL', 'Freq'},
) )
@ -73,7 +73,7 @@ class WaveConstantNode(base.MaxwellSimNode):
#################### ####################
# - Event Methods: Listy Output # - Event Methods: Listy Output
#################### ####################
@base.computes_output_socket( @events.computes_output_socket(
'WLs', 'WLs',
input_sockets={'WLs', 'Freqs'}, input_sockets={'WLs', 'Freqs'},
) )
@ -86,7 +86,7 @@ class WaveConstantNode(base.MaxwellSimNode):
msg = 'Vac WL and Freq are both None' msg = 'Vac WL and Freq are both None'
raise RuntimeError(msg) raise RuntimeError(msg)
@base.computes_output_socket( @events.computes_output_socket(
'Freqs', 'Freqs',
input_sockets={'WLs', 'Freqs'}, input_sockets={'WLs', 'Freqs'},
) )
@ -102,7 +102,7 @@ class WaveConstantNode(base.MaxwellSimNode):
#################### ####################
# - Event Methods # - Event Methods
#################### ####################
@base.on_value_changed(prop_name='active_socket_set', props={'active_socket_set'}) @events.on_value_changed(prop_name='active_socket_set', props={'active_socket_set'})
def on_active_socket_set_changed(self, props: dict): def on_active_socket_set_changed(self, props: dict):
# Singular: Normal Output Sockets # Singular: Normal Output Sockets
if props['active_socket_set'] in {'Vacuum WL', 'Frequency'}: if props['active_socket_set'] in {'Vacuum WL', 'Frequency'}:
@ -124,7 +124,7 @@ class WaveConstantNode(base.MaxwellSimNode):
msg = f"Active socket set invalid for wave constant: {props['active_socket_set']}" msg = f"Active socket set invalid for wave constant: {props['active_socket_set']}"
raise RuntimeError(msg) raise RuntimeError(msg)
@base.on_init() @events.on_init()
def on_init(self): def on_init(self):
self.on_active_socket_set_changed() self.on_active_socket_set_changed()

View File

@ -1,14 +1,11 @@
import tempfile
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 .... import contracts as ct from .... import contracts as ct
from .... import sockets from .... import sockets
from ... import base from ... import base, events
def _sim_data_cache_path(task_id: str) -> Path: def _sim_data_cache_path(task_id: str) -> Path:
@ -36,7 +33,7 @@ class Tidy3DWebImporterNode(base.MaxwellSimNode):
#################### ####################
# - Event Methods # - Event Methods
#################### ####################
@base.computes_output_socket( @events.computes_output_socket(
'FDTD Sim Data', 'FDTD Sim Data',
input_sockets={'Cloud Task'}, input_sockets={'Cloud Task'},
) )
@ -61,7 +58,7 @@ class Tidy3DWebImporterNode(base.MaxwellSimNode):
cloud_task, _sim_data_cache_path(cloud_task.task_id) cloud_task, _sim_data_cache_path(cloud_task.task_id)
) )
@base.on_value_changed(socket_name='Cloud Task', input_sockets={'Cloud Task'}) @events.on_value_changed(socket_name='Cloud Task', input_sockets={'Cloud Task'})
def on_cloud_task_changed(self, input_sockets: dict): def on_cloud_task_changed(self, input_sockets: dict):
if ( if (
(cloud_task := input_sockets['Cloud Task']) is not None (cloud_task := input_sockets['Cloud Task']) is not None
@ -74,7 +71,7 @@ class Tidy3DWebImporterNode(base.MaxwellSimNode):
else: else:
self.loose_output_sockets = {} self.loose_output_sockets = {}
@base.on_init() @events.on_init()
def on_init(self): def on_init(self):
self.on_cloud_task_changed() self.on_cloud_task_changed()

View File

@ -1,4 +1,3 @@
import sympy as sp import sympy as sp
from .. import contracts as ct from .. import contracts as ct

View File

@ -2,7 +2,7 @@ import sympy.physics.units as spu
import tidy3d as td import tidy3d as td
from ... import contracts, sockets from ... import contracts, sockets
from .. import base from .. import base, events
class DrudeLorentzMediumNode(base.MaxwellSimTreeNode): class DrudeLorentzMediumNode(base.MaxwellSimTreeNode):
@ -46,7 +46,7 @@ class DrudeLorentzMediumNode(base.MaxwellSimTreeNode):
#################### ####################
# - Output Socket Computation # - Output Socket Computation
#################### ####################
@base.computes_output_socket('medium') @events.computes_output_socket('medium')
def compute_medium(self: contracts.NodeTypeProtocol) -> td.Sellmeier: def compute_medium(self: contracts.NodeTypeProtocol) -> td.Sellmeier:
## Retrieval ## Retrieval
return td.Lorentz( return td.Lorentz(
@ -77,7 +77,5 @@ BL_REGISTER = [
DrudeLorentzMediumNode, DrudeLorentzMediumNode,
] ]
BL_NODES = { BL_NODES = {
contracts.NodeType.DrudeLorentzMedium: ( contracts.NodeType.DrudeLorentzMedium: (contracts.NodeCategory.MAXWELLSIM_MEDIUMS)
contracts.NodeCategory.MAXWELLSIM_MEDIUMS
)
} }

View File

@ -9,7 +9,7 @@ import tidy3d as td
from .....utils import extra_sympy_units as spuex from .....utils import extra_sympy_units as spuex
from ... import contracts as ct from ... import contracts as ct
from ... import managed_objs, sockets from ... import managed_objs, sockets
from .. import base from .. import base, events
VAC_SPEED_OF_LIGHT = sc.constants.speed_of_light * spu.meter / spu.second VAC_SPEED_OF_LIGHT = sc.constants.speed_of_light * spu.meter / spu.second
@ -72,9 +72,7 @@ class LibraryMediumNode(base.MaxwellSimNode):
/ spuex.terahertz / spuex.terahertz
for val in mat.medium.frequency_range for val in mat.medium.frequency_range
] ]
return sp.pretty( return sp.pretty([freq_range[0].n(4), freq_range[1].n(4)], use_unicode=True)
[freq_range[0].n(4), freq_range[1].n(4)], use_unicode=True
)
@property @property
def nm_range_str(self) -> str: def nm_range_str(self) -> str:
@ -88,9 +86,7 @@ class LibraryMediumNode(base.MaxwellSimNode):
/ spu.nanometer / spu.nanometer
for val in reversed(mat.medium.frequency_range) for val in reversed(mat.medium.frequency_range)
] ]
return sp.pretty( return sp.pretty([nm_range[0].n(4), nm_range[1].n(4)], use_unicode=True)
[nm_range[0].n(4), nm_range[1].n(4)], use_unicode=True
)
#################### ####################
# - UI # - UI
@ -115,14 +111,14 @@ class LibraryMediumNode(base.MaxwellSimNode):
#################### ####################
# - Output Sockets # - Output Sockets
#################### ####################
@base.computes_output_socket('Medium') @events.computes_output_socket('Medium')
def compute_vac_wl(self) -> sp.Expr: def compute_vac_wl(self) -> sp.Expr:
return td.material_library[self.material].medium return td.material_library[self.material].medium
#################### ####################
# - Event Callbacks # - Event Callbacks
#################### ####################
@base.on_show_plot( @events.on_show_plot(
managed_objs={'nk_plot'}, managed_objs={'nk_plot'},
props={'material'}, props={'material'},
stop_propagation=True, ## Plot only the first plottable node stop_propagation=True, ## Plot only the first plottable node

View File

@ -1,8 +1,8 @@
from . import ( from . import (
add_non_linearity, add_non_linearity,
chi_3_susceptibility_non_linearity, chi_3_susceptibility_non_linearity,
kerr_non_linearity, kerr_non_linearity,
two_photon_absorption_non_linearity, two_photon_absorption_non_linearity,
) )
BL_REGISTER = [ BL_REGISTER = [

View File

@ -2,7 +2,7 @@ import sympy.physics.units as spu
import tidy3d as td import tidy3d as td
from ... import contracts, sockets from ... import contracts, sockets
from .. import base from .. import base, events
class TripleSellmeierMediumNode(base.MaxwellSimTreeNode): class TripleSellmeierMediumNode(base.MaxwellSimTreeNode):
@ -20,9 +20,7 @@ class TripleSellmeierMediumNode(base.MaxwellSimTreeNode):
) )
for i in [1, 2, 3] for i in [1, 2, 3]
} | { } | {
f'C{i}': sockets.PhysicalAreaSocketDef( f'C{i}': sockets.PhysicalAreaSocketDef(label=f'C{i}', default_unit=spu.um**2)
label=f'C{i}', default_unit=spu.um**2
)
for i in [1, 2, 3] for i in [1, 2, 3]
} }
output_sockets = { output_sockets = {
@ -62,7 +60,7 @@ class TripleSellmeierMediumNode(base.MaxwellSimTreeNode):
#################### ####################
# - Output Socket Computation # - Output Socket Computation
#################### ####################
@base.computes_output_socket('medium') @events.computes_output_socket('medium')
def compute_medium(self: contracts.NodeTypeProtocol) -> td.Sellmeier: def compute_medium(self: contracts.NodeTypeProtocol) -> td.Sellmeier:
## Retrieval ## Retrieval
# B1 = self.compute_input("B1") # B1 = self.compute_input("B1")

View File

@ -7,7 +7,7 @@ from .....utils import analyze_geonodes, logger
from .....utils import extra_sympy_units as spux from .....utils import extra_sympy_units as spux
from ... import contracts as ct from ... import contracts as ct
from ... import managed_objs, sockets from ... import managed_objs, sockets
from .. import base from .. import base, events
log = logger.get(__name__) log = logger.get(__name__)
@ -59,7 +59,7 @@ class EHFieldMonitorNode(base.MaxwellSimNode):
#################### ####################
# - Output Sockets # - Output Sockets
#################### ####################
@base.computes_output_socket( @events.computes_output_socket(
'Monitor', 'Monitor',
input_sockets={ input_sockets={
'Rec Start', 'Rec Start',
@ -129,7 +129,7 @@ class EHFieldMonitorNode(base.MaxwellSimNode):
#################### ####################
# - Preview - Changes to Input Sockets # - Preview - Changes to Input Sockets
#################### ####################
@base.on_value_changed( @events.on_value_changed(
socket_name={'Center', 'Size'}, socket_name={'Center', 'Size'},
input_sockets={'Center', 'Size'}, input_sockets={'Center', 'Size'},
managed_objs={'monitor_box'}, managed_objs={'monitor_box'},
@ -164,7 +164,7 @@ class EHFieldMonitorNode(base.MaxwellSimNode):
#################### ####################
# - Preview - Show Preview # - Preview - Show Preview
#################### ####################
@base.on_show_preview( @events.on_show_preview(
managed_objs={'monitor_box'}, managed_objs={'monitor_box'},
) )
def on_show_preview( def on_show_preview(

View File

@ -1,4 +1,3 @@
import bpy import bpy
import sympy as sp import sympy as sp
import sympy.physics.units as spu import sympy.physics.units as spu
@ -8,7 +7,7 @@ from .....utils import analyze_geonodes
from .....utils import extra_sympy_units as spux from .....utils import extra_sympy_units as spux
from ... import contracts as ct from ... import contracts as ct
from ... import managed_objs, sockets from ... import managed_objs, sockets
from .. import base from .. import base, events
GEONODES_MONITOR_BOX = 'monitor_flux_box' GEONODES_MONITOR_BOX = 'monitor_flux_box'
@ -37,9 +36,7 @@ class FieldPowerFluxMonitorNode(base.MaxwellSimNode):
}, },
'Time Domain': { 'Time Domain': {
'Rec Start': sockets.PhysicalTimeSocketDef(), 'Rec Start': sockets.PhysicalTimeSocketDef(),
'Rec Stop': sockets.PhysicalTimeSocketDef( 'Rec Stop': sockets.PhysicalTimeSocketDef(default_value=200 * spux.fs),
default_value=200 * spux.fs
),
'Samples/Time': sockets.IntegerNumberSocketDef( 'Samples/Time': sockets.IntegerNumberSocketDef(
default_value=100, default_value=100,
), ),
@ -72,7 +69,7 @@ class FieldPowerFluxMonitorNode(base.MaxwellSimNode):
#################### ####################
# - Output Sockets # - Output Sockets
#################### ####################
@base.computes_output_socket( @events.computes_output_socket(
'Monitor', 'Monitor',
input_sockets={ input_sockets={
'Rec Start', 'Rec Start',
@ -86,9 +83,7 @@ class FieldPowerFluxMonitorNode(base.MaxwellSimNode):
}, },
props={'active_socket_set', 'sim_node_name'}, props={'active_socket_set', 'sim_node_name'},
) )
def compute_monitor( def compute_monitor(self, input_sockets: dict, props: dict) -> td.FieldTimeMonitor:
self, input_sockets: dict, props: dict
) -> td.FieldTimeMonitor:
_center = input_sockets['Center'] _center = input_sockets['Center']
_size = input_sockets['Size'] _size = input_sockets['Size']
_samples_space = input_sockets['Samples/Space'] _samples_space = input_sockets['Samples/Space']
@ -108,8 +103,7 @@ class FieldPowerFluxMonitorNode(base.MaxwellSimNode):
name=props['sim_node_name'], name=props['sim_node_name'],
interval_space=samples_space, interval_space=samples_space,
freqs=[ freqs=[
float(spu.convert_to(freq, spu.hertz) / spu.hertz) float(spu.convert_to(freq, spu.hertz) / spu.hertz) for freq in freqs
for freq in freqs
], ],
normal_dir=direction, normal_dir=direction,
) )
@ -134,7 +128,7 @@ class FieldPowerFluxMonitorNode(base.MaxwellSimNode):
#################### ####################
# - Preview - Changes to Input Sockets # - Preview - Changes to Input Sockets
#################### ####################
@base.on_value_changed( @events.on_value_changed(
socket_name={'Center', 'Size'}, socket_name={'Center', 'Size'},
input_sockets={'Center', 'Size', 'Direction'}, input_sockets={'Center', 'Size', 'Direction'},
managed_objs={'monitor_box'}, managed_objs={'monitor_box'},
@ -145,30 +139,22 @@ class FieldPowerFluxMonitorNode(base.MaxwellSimNode):
managed_objs: dict[str, ct.schemas.ManagedObj], managed_objs: dict[str, ct.schemas.ManagedObj],
): ):
_center = input_sockets['Center'] _center = input_sockets['Center']
center = tuple( center = tuple([float(el) for el in spu.convert_to(_center, spu.um) / spu.um])
[float(el) for el in spu.convert_to(_center, spu.um) / spu.um]
)
_size = input_sockets['Size'] _size = input_sockets['Size']
size = tuple( size = tuple([float(el) for el in spu.convert_to(_size, spu.um) / spu.um])
[float(el) for el in spu.convert_to(_size, spu.um) / spu.um]
)
## TODO: Preview unit system?? Presume um for now ## TODO: Preview unit system?? Presume um for now
# Retrieve Hard-Coded GeoNodes and Analyze Input # Retrieve Hard-Coded GeoNodes and Analyze Input
geo_nodes = bpy.data.node_groups[GEONODES_MONITOR_BOX] geo_nodes = bpy.data.node_groups[GEONODES_MONITOR_BOX]
geonodes_interface = analyze_geonodes.interface( geonodes_interface = analyze_geonodes.interface(geo_nodes, direc='INPUT')
geo_nodes, direc='INPUT'
)
# Sync Modifier Inputs # Sync Modifier Inputs
managed_objs['monitor_box'].sync_geonodes_modifier( managed_objs['monitor_box'].sync_geonodes_modifier(
geonodes_node_group=geo_nodes, geonodes_node_group=geo_nodes,
geonodes_identifier_to_value={ geonodes_identifier_to_value={
geonodes_interface['Size'].identifier: size, geonodes_interface['Size'].identifier: size,
geonodes_interface['Direction'].identifier: input_sockets[ geonodes_interface['Direction'].identifier: input_sockets['Direction'],
'Direction'
],
## TODO: Use 'bl_socket_map.value_to_bl`! ## TODO: Use 'bl_socket_map.value_to_bl`!
## - This accounts for auto-conversion, unit systems, etc. . ## - This accounts for auto-conversion, unit systems, etc. .
## - We could keep it in the node base class... ## - We could keep it in the node base class...
@ -182,7 +168,7 @@ class FieldPowerFluxMonitorNode(base.MaxwellSimNode):
#################### ####################
# - Preview - Show Preview # - Preview - Show Preview
#################### ####################
@base.on_show_preview( @events.on_show_preview(
managed_objs={'monitor_box'}, managed_objs={'monitor_box'},
) )
def on_show_preview( def on_show_preview(
@ -199,6 +185,4 @@ class FieldPowerFluxMonitorNode(base.MaxwellSimNode):
BL_REGISTER = [ BL_REGISTER = [
FieldPowerFluxMonitorNode, FieldPowerFluxMonitorNode,
] ]
BL_NODES = { BL_NODES = {ct.NodeType.FieldPowerFluxMonitor: (ct.NodeCategory.MAXWELLSIM_MONITORS)}
ct.NodeType.FieldPowerFluxMonitor: (ct.NodeCategory.MAXWELLSIM_MONITORS)
}

View File

@ -7,7 +7,7 @@ import pydantic as pyd
from .... import contracts as ct from .... import contracts as ct
from .... import sockets from .... import sockets
from ... import base from ... import base, events
#################### ####################
@ -38,9 +38,7 @@ class JSONFileExporterNode(base.MaxwellSimNode):
input_sockets = { input_sockets = {
'Data': sockets.AnySocketDef(), 'Data': sockets.AnySocketDef(),
'JSON Path': sockets.FilePathSocketDef( 'JSON Path': sockets.FilePathSocketDef(default_path=Path('simulation.json')),
default_path=Path('simulation.json')
),
'JSON Indent': sockets.IntegerNumberSocketDef( 'JSON Indent': sockets.IntegerNumberSocketDef(
default_value=4, default_value=4,
), ),
@ -72,13 +70,11 @@ class JSONFileExporterNode(base.MaxwellSimNode):
#################### ####################
# - Output Sockets # - Output Sockets
#################### ####################
@base.computes_output_socket( @events.computes_output_socket(
'JSON String', 'JSON String',
input_sockets={'Data'}, input_sockets={'Data'},
) )
def compute_json_string( def compute_json_string(self, input_sockets: dict[str, typ.Any]) -> str | None:
self, input_sockets: dict[str, typ.Any]
) -> str | None:
if not (data := input_sockets['Data']): if not (data := input_sockets['Data']):
return None return None
@ -102,7 +98,5 @@ BL_REGISTER = [
JSONFileExporterNode, JSONFileExporterNode,
] ]
BL_NODES = { BL_NODES = {
ct.NodeType.JSONFileExporter: ( ct.NodeType.JSONFileExporter: (ct.NodeCategory.MAXWELLSIM_OUTPUTS_EXPORTERS)
ct.NodeCategory.MAXWELLSIM_OUTPUTS_EXPORTERS
)
} }

View File

@ -3,7 +3,7 @@ import bpy
from ......services import tdcloud from ......services import tdcloud
from .... import contracts as ct from .... import contracts as ct
from .... import sockets from .... import sockets
from ... import base from ... import base, events
#################### ####################
@ -77,9 +77,7 @@ class ReloadTrackedTask(bpy.types.Operator):
def execute(self, context): def execute(self, context):
node = context.node node = context.node
if ( if (cloud_task := tdcloud.TidyCloudTasks.task(node.tracked_task_id)) is None:
cloud_task := tdcloud.TidyCloudTasks.task(node.tracked_task_id)
) is None:
msg = "Tried to reload tracked task, but it doesn't exist" msg = "Tried to reload tracked task, but it doesn't exist"
raise RuntimeError(msg) raise RuntimeError(msg)
@ -105,13 +103,9 @@ class EstCostTrackedTask(bpy.types.Operator):
def execute(self, context): def execute(self, context):
node = context.node node = context.node
if ( if (
task_info := tdcloud.TidyCloudTasks.task_info( task_info := tdcloud.TidyCloudTasks.task_info(context.node.tracked_task_id)
context.node.tracked_task_id
)
) is None: ) is None:
msg = ( msg = "Tried to estimate cost of tracked task, but it doesn't exist"
"Tried to estimate cost of tracked task, but it doesn't exist"
)
raise RuntimeError(msg) raise RuntimeError(msg)
node.cache_est_cost = task_info.cost_est() node.cache_est_cost = task_info.cost_est()
@ -235,13 +229,13 @@ class Tidy3DWebExporterNode(base.MaxwellSimNode):
msg = 'Tried to upload simulation, but none is attached' msg = 'Tried to upload simulation, but none is attached'
raise ValueError(msg) raise ValueError(msg)
if ( if (new_task := self._compute_input('Cloud Task')) is None or isinstance(
new_task := self._compute_input('Cloud Task')
) is None or isinstance(
new_task, new_task,
tdcloud.CloudTask, tdcloud.CloudTask,
): ):
msg = 'Tried to upload simulation to new task, but existing task was selected' msg = (
'Tried to upload simulation to new task, but existing task was selected'
)
raise ValueError(msg) raise ValueError(msg)
# Create Cloud Task # Create Cloud Task
@ -262,9 +256,7 @@ class Tidy3DWebExporterNode(base.MaxwellSimNode):
self.tracked_task_id = cloud_task.task_id self.tracked_task_id = cloud_task.task_id
def run_tracked_task(self): def run_tracked_task(self):
if ( if (cloud_task := tdcloud.TidyCloudTasks.task(self.tracked_task_id)) is None:
cloud_task := tdcloud.TidyCloudTasks.task(self.tracked_task_id)
) is None:
msg = "Tried to run tracked task, but it doesn't exist" msg = "Tried to run tracked task, but it doesn't exist"
raise RuntimeError(msg) raise RuntimeError(msg)
@ -302,9 +294,7 @@ class Tidy3DWebExporterNode(base.MaxwellSimNode):
def draw_info(self, context, layout): def draw_info(self, context, layout):
# Connection Info # Connection Info
auth_icon = ( auth_icon = 'CHECKBOX_HLT' if tdcloud.IS_AUTHENTICATED else 'CHECKBOX_DEHLT'
'CHECKBOX_HLT' if tdcloud.IS_AUTHENTICATED else 'CHECKBOX_DEHLT'
)
conn_icon = 'CHECKBOX_HLT' if tdcloud.IS_ONLINE else 'CHECKBOX_DEHLT' conn_icon = 'CHECKBOX_HLT' if tdcloud.IS_ONLINE else 'CHECKBOX_DEHLT'
row = layout.row() row = layout.row()
@ -338,9 +328,7 @@ class Tidy3DWebExporterNode(base.MaxwellSimNode):
## Split: Right Column ## Split: Right Column
col = split.column(align=False) col = split.column(align=False)
col.alignment = 'RIGHT' col.alignment = 'RIGHT'
col.label( col.label(text=f'{self.cache_total_monitor_data / 1_000_000:.2f}MB')
text=f'{self.cache_total_monitor_data / 1_000_000:.2f}MB'
)
# Cloud Task Info # Cloud Task Info
if self.tracked_task_id and tdcloud.IS_AUTHENTICATED: if self.tracked_task_id and tdcloud.IS_AUTHENTICATED:
@ -383,9 +371,7 @@ class Tidy3DWebExporterNode(base.MaxwellSimNode):
## Split: Right Column ## Split: Right Column
cost_est = ( cost_est = (
f'{self.cache_est_cost:.2f}' f'{self.cache_est_cost:.2f}' if self.cache_est_cost >= 0 else 'TBD'
if self.cache_est_cost >= 0
else 'TBD'
) )
cost_real = ( cost_real = (
f'{task_info.cost_real:.2f}' f'{task_info.cost_real:.2f}'
@ -404,16 +390,12 @@ class Tidy3DWebExporterNode(base.MaxwellSimNode):
#################### ####################
# - Output Methods # - Output Methods
#################### ####################
@base.computes_output_socket( @events.computes_output_socket(
'Cloud Task', 'Cloud Task',
input_sockets={'Cloud Task'}, input_sockets={'Cloud Task'},
) )
def compute_cloud_task( def compute_cloud_task(self, input_sockets: dict) -> tdcloud.CloudTask | None:
self, input_sockets: dict if isinstance(cloud_task := input_sockets['Cloud Task'], tdcloud.CloudTask):
) -> tdcloud.CloudTask | None:
if isinstance(
cloud_task := input_sockets['Cloud Task'], tdcloud.CloudTask
):
return cloud_task return cloud_task
return None return None
@ -421,7 +403,7 @@ class Tidy3DWebExporterNode(base.MaxwellSimNode):
#################### ####################
# - Output Methods # - Output Methods
#################### ####################
@base.on_value_changed( @events.on_value_changed(
socket_name='FDTD Sim', socket_name='FDTD Sim',
input_sockets={'FDTD Sim'}, input_sockets={'FDTD Sim'},
) )
@ -446,7 +428,5 @@ BL_REGISTER = [
Tidy3DWebExporterNode, Tidy3DWebExporterNode,
] ]
BL_NODES = { BL_NODES = {
ct.NodeType.Tidy3DWebExporter: ( ct.NodeType.Tidy3DWebExporter: (ct.NodeCategory.MAXWELLSIM_OUTPUTS_EXPORTERS)
ct.NodeCategory.MAXWELLSIM_OUTPUTS_EXPORTERS
)
} }

View File

@ -5,7 +5,7 @@ from .....utils import logger
from ... import contracts as ct from ... import contracts as ct
from ... import sockets from ... import sockets
from ...managed_objs import managed_bl_object from ...managed_objs import managed_bl_object
from .. import base from .. import base, events
log = logger.get(__name__) log = logger.get(__name__)
console = logger.OUTPUT_CONSOLE console = logger.OUTPUT_CONSOLE
@ -113,7 +113,7 @@ class ViewerNode(base.MaxwellSimNode):
#################### ####################
# - Updates # - Updates
#################### ####################
@base.on_value_changed( @events.on_value_changed(
socket_name='Data', socket_name='Data',
props={'auto_3d_preview'}, props={'auto_3d_preview'},
) )
@ -135,7 +135,7 @@ class ViewerNode(base.MaxwellSimNode):
if props['auto_3d_preview']: if props['auto_3d_preview']:
self.trigger_action('show_preview') self.trigger_action('show_preview')
@base.on_value_changed( @events.on_value_changed(
prop_name='auto_3d_preview', prop_name='auto_3d_preview',
props={'auto_3d_preview'}, props={'auto_3d_preview'},
) )

View File

@ -3,7 +3,7 @@ import tidy3d as td
from ... import contracts as ct from ... import contracts as ct
from ... import sockets from ... import sockets
from .. import base from .. import base, events
class FDTDSimNode(base.MaxwellSimNode): class FDTDSimNode(base.MaxwellSimNode):
@ -33,7 +33,7 @@ class FDTDSimNode(base.MaxwellSimNode):
#################### ####################
# - Output Socket Computation # - Output Socket Computation
#################### ####################
@base.computes_output_socket( @events.computes_output_socket(
'FDTD Sim', 'FDTD Sim',
kind=ct.DataFlowKind.Value, kind=ct.DataFlowKind.Value,
input_sockets={'Sources', 'Structures', 'Domain', 'BCs', 'Monitors'}, input_sockets={'Sources', 'Structures', 'Domain', 'BCs', 'Monitors'},

View File

@ -5,7 +5,7 @@ import sympy.physics.units as spu
from .....utils import analyze_geonodes from .....utils import analyze_geonodes
from ... import contracts as ct from ... import contracts as ct
from ... import managed_objs, sockets from ... import managed_objs, sockets
from .. import base from .. import base, events
GEONODES_DOMAIN_BOX = 'simdomain_box' GEONODES_DOMAIN_BOX = 'simdomain_box'
@ -38,7 +38,7 @@ class SimDomainNode(base.MaxwellSimNode):
#################### ####################
# - Callbacks # - Callbacks
#################### ####################
@base.computes_output_socket( @events.computes_output_socket(
'Domain', 'Domain',
input_sockets={'Duration', 'Center', 'Size', 'Grid', 'Ambient Medium'}, input_sockets={'Duration', 'Center', 'Size', 'Grid', 'Ambient Medium'},
) )
@ -66,7 +66,7 @@ class SimDomainNode(base.MaxwellSimNode):
#################### ####################
# - Preview # - Preview
#################### ####################
@base.on_value_changed( @events.on_value_changed(
socket_name={'Center', 'Size'}, socket_name={'Center', 'Size'},
input_sockets={'Center', 'Size'}, input_sockets={'Center', 'Size'},
managed_objs={'domain_box'}, managed_objs={'domain_box'},
@ -77,21 +77,15 @@ class SimDomainNode(base.MaxwellSimNode):
managed_objs: dict[str, ct.schemas.ManagedObj], managed_objs: dict[str, ct.schemas.ManagedObj],
): ):
_center = input_sockets['Center'] _center = input_sockets['Center']
center = tuple( center = tuple([float(el) for el in spu.convert_to(_center, spu.um) / spu.um])
[float(el) for el in spu.convert_to(_center, spu.um) / spu.um]
)
_size = input_sockets['Size'] _size = input_sockets['Size']
size = tuple( size = tuple([float(el) for el in spu.convert_to(_size, spu.um) / spu.um])
[float(el) for el in spu.convert_to(_size, spu.um) / spu.um]
)
## TODO: Preview unit system?? Presume um for now ## TODO: Preview unit system?? Presume um for now
# Retrieve Hard-Coded GeoNodes and Analyze Input # Retrieve Hard-Coded GeoNodes and Analyze Input
geo_nodes = bpy.data.node_groups[GEONODES_DOMAIN_BOX] geo_nodes = bpy.data.node_groups[GEONODES_DOMAIN_BOX]
geonodes_interface = analyze_geonodes.interface( geonodes_interface = analyze_geonodes.interface(geo_nodes, direc='INPUT')
geo_nodes, direc='INPUT'
)
# Sync Modifier Inputs # Sync Modifier Inputs
managed_objs['domain_box'].sync_geonodes_modifier( managed_objs['domain_box'].sync_geonodes_modifier(
@ -108,7 +102,7 @@ class SimDomainNode(base.MaxwellSimNode):
# Sync Object Position # Sync Object Position
managed_objs['domain_box'].bl_object('MESH').location = center managed_objs['domain_box'].bl_object('MESH').location = center
@base.on_show_preview( @events.on_show_preview(
managed_objs={'domain_box'}, managed_objs={'domain_box'},
) )
def on_show_preview( def on_show_preview(

View File

@ -1,8 +1,8 @@
from . import ( from . import (
array_sim_grid_axis, array_sim_grid_axis,
automatic_sim_grid_axis, automatic_sim_grid_axis,
manual_sim_grid_axis, manual_sim_grid_axis,
uniform_sim_grid_axis, uniform_sim_grid_axis,
) )
BL_REGISTER = [ BL_REGISTER = [

View File

@ -8,7 +8,7 @@ import tidy3d as td
from .....utils import analyze_geonodes from .....utils import analyze_geonodes
from ... import contracts as ct from ... import contracts as ct
from ... import managed_objs, sockets from ... import managed_objs, sockets
from .. import base from .. import base, events
GEONODES_PLANE_WAVE = 'source_plane_wave' GEONODES_PLANE_WAVE = 'source_plane_wave'
@ -53,9 +53,7 @@ class PlaneWaveSourceNode(base.MaxwellSimNode):
input_sockets = { input_sockets = {
'Temporal Shape': sockets.MaxwellTemporalShapeSocketDef(), 'Temporal Shape': sockets.MaxwellTemporalShapeSocketDef(),
'Center': sockets.PhysicalPoint3DSocketDef(), 'Center': sockets.PhysicalPoint3DSocketDef(),
'Direction': sockets.Real3DVectorSocketDef( 'Direction': sockets.Real3DVectorSocketDef(default_value=sp.Matrix([0, 0, -1])),
default_value=sp.Matrix([0, 0, -1])
),
'Pol Angle': sockets.PhysicalAngleSocketDef(), 'Pol Angle': sockets.PhysicalAngleSocketDef(),
} }
output_sockets = { output_sockets = {
@ -72,7 +70,7 @@ class PlaneWaveSourceNode(base.MaxwellSimNode):
#################### ####################
# - Output Socket Computation # - Output Socket Computation
#################### ####################
@base.computes_output_socket( @events.computes_output_socket(
'Source', 'Source',
input_sockets={'Temporal Shape', 'Center', 'Direction', 'Pol Angle'}, input_sockets={'Temporal Shape', 'Center', 'Direction', 'Pol Angle'},
) )
@ -82,9 +80,7 @@ class PlaneWaveSourceNode(base.MaxwellSimNode):
direction = input_sockets['Direction'] direction = input_sockets['Direction']
pol_angle = input_sockets['Pol Angle'] pol_angle = input_sockets['Pol Angle']
injection_axis, dir_sgn, theta, phi = convert_vector_to_spherical( injection_axis, dir_sgn, theta, phi = convert_vector_to_spherical(direction)
direction
)
size = { size = {
'x': (0, math.inf, math.inf), 'x': (0, math.inf, math.inf),
@ -107,7 +103,7 @@ class PlaneWaveSourceNode(base.MaxwellSimNode):
#################### ####################
# - Preview # - Preview
#################### ####################
@base.on_value_changed( @events.on_value_changed(
socket_name={'Center', 'Direction'}, socket_name={'Center', 'Direction'},
input_sockets={'Center', 'Direction'}, input_sockets={'Center', 'Direction'},
managed_objs={'plane_wave_source'}, managed_objs={'plane_wave_source'},
@ -118,9 +114,7 @@ class PlaneWaveSourceNode(base.MaxwellSimNode):
managed_objs: dict[str, ct.schemas.ManagedObj], managed_objs: dict[str, ct.schemas.ManagedObj],
): ):
_center = input_sockets['Center'] _center = input_sockets['Center']
center = tuple( center = tuple([float(el) for el in spu.convert_to(_center, spu.um) / spu.um])
[float(el) for el in spu.convert_to(_center, spu.um) / spu.um]
)
_direction = input_sockets['Direction'] _direction = input_sockets['Direction']
direction = tuple([float(el) for el in _direction]) direction = tuple([float(el) for el in _direction])
@ -128,9 +122,7 @@ class PlaneWaveSourceNode(base.MaxwellSimNode):
# Retrieve Hard-Coded GeoNodes and Analyze Input # Retrieve Hard-Coded GeoNodes and Analyze Input
geo_nodes = bpy.data.node_groups[GEONODES_PLANE_WAVE] geo_nodes = bpy.data.node_groups[GEONODES_PLANE_WAVE]
geonodes_interface = analyze_geonodes.interface( geonodes_interface = analyze_geonodes.interface(geo_nodes, direc='INPUT')
geo_nodes, direc='INPUT'
)
# Sync Modifier Inputs # Sync Modifier Inputs
managed_objs['plane_wave_source'].sync_geonodes_modifier( managed_objs['plane_wave_source'].sync_geonodes_modifier(
@ -147,7 +139,7 @@ class PlaneWaveSourceNode(base.MaxwellSimNode):
# Sync Object Position # Sync Object Position
managed_objs['plane_wave_source'].bl_object('MESH').location = center managed_objs['plane_wave_source'].bl_object('MESH').location = center
@base.on_show_preview( @events.on_show_preview(
managed_objs={'plane_wave_source'}, managed_objs={'plane_wave_source'},
) )
def on_show_preview( def on_show_preview(

View File

@ -6,7 +6,7 @@ import tidy3d as td
from ... import contracts as ct from ... import contracts as ct
from ... import managed_objs, sockets from ... import managed_objs, sockets
from .. import base from .. import base, events
class PointDipoleSourceNode(base.MaxwellSimNode): class PointDipoleSourceNode(base.MaxwellSimNode):
@ -64,7 +64,7 @@ class PointDipoleSourceNode(base.MaxwellSimNode):
#################### ####################
# - Output Socket Computation # - Output Socket Computation
#################### ####################
@base.computes_output_socket( @events.computes_output_socket(
'Source', 'Source',
input_sockets={'Temporal Shape', 'Center', 'Interpolate'}, input_sockets={'Temporal Shape', 'Center', 'Interpolate'},
props={'pol_axis'}, props={'pol_axis'},
@ -95,7 +95,7 @@ class PointDipoleSourceNode(base.MaxwellSimNode):
#################### ####################
# - Preview # - Preview
#################### ####################
@base.on_value_changed( @events.on_value_changed(
socket_name='Center', socket_name='Center',
input_sockets={'Center'}, input_sockets={'Center'},
managed_objs={'sphere_empty'}, managed_objs={'sphere_empty'},
@ -113,7 +113,7 @@ class PointDipoleSourceNode(base.MaxwellSimNode):
bl_object = mobj.bl_object('EMPTY') bl_object = mobj.bl_object('EMPTY')
bl_object.location = center # tuple([float(el) for el in center]) bl_object.location = center # tuple([float(el) for el in center])
@base.on_show_preview( @events.on_show_preview(
managed_objs={'sphere_empty'}, managed_objs={'sphere_empty'},
) )
def on_show_preview( def on_show_preview(
@ -124,9 +124,7 @@ class PointDipoleSourceNode(base.MaxwellSimNode):
'EMPTY', 'EMPTY',
empty_display_type='SPHERE', empty_display_type='SPHERE',
) )
managed_objs['sphere_empty'].bl_object( managed_objs['sphere_empty'].bl_object('EMPTY').empty_display_size = 0.2
'EMPTY'
).empty_display_size = 0.2
#################### ####################
@ -135,6 +133,4 @@ class PointDipoleSourceNode(base.MaxwellSimNode):
BL_REGISTER = [ BL_REGISTER = [
PointDipoleSourceNode, PointDipoleSourceNode,
] ]
BL_NODES = { BL_NODES = {ct.NodeType.PointDipoleSource: (ct.NodeCategory.MAXWELLSIM_SOURCES)}
ct.NodeType.PointDipoleSource: (ct.NodeCategory.MAXWELLSIM_SOURCES)
}

View File

@ -2,7 +2,7 @@ import sympy.physics.units as spu
import tidy3d as td import tidy3d as td
from .... import contracts, sockets from .... import contracts, sockets
from ... import base from ... import base, events
class ContinuousWaveTemporalShapeNode(base.MaxwellSimTreeNode): class ContinuousWaveTemporalShapeNode(base.MaxwellSimTreeNode):
@ -41,7 +41,7 @@ class ContinuousWaveTemporalShapeNode(base.MaxwellSimTreeNode):
#################### ####################
# - Output Socket Computation # - Output Socket Computation
#################### ####################
@base.computes_output_socket('temporal_shape') @events.computes_output_socket('temporal_shape')
def compute_source(self: contracts.NodeTypeProtocol) -> td.PointDipole: def compute_source(self: contracts.NodeTypeProtocol) -> td.PointDipole:
_phase = self.compute_input('phase') _phase = self.compute_input('phase')
_freq_center = self.compute_input('freq_center') _freq_center = self.compute_input('freq_center')

View File

@ -8,7 +8,7 @@ import tidy3d as td
from ......utils import extra_sympy_units as spuex from ......utils import extra_sympy_units as spuex
from .... import contracts as ct from .... import contracts as ct
from .... import managed_objs, sockets from .... import managed_objs, sockets
from ... import base from ... import base, events
class GaussianPulseTemporalShapeNode(base.MaxwellSimNode): class GaussianPulseTemporalShapeNode(base.MaxwellSimNode):
@ -55,17 +55,13 @@ class GaussianPulseTemporalShapeNode(base.MaxwellSimNode):
name='Plot Time Start (ps)', name='Plot Time Start (ps)',
description='The instance ID of a particular MaxwellSimNode instance, used to index caches', description='The instance ID of a particular MaxwellSimNode instance, used to index caches',
default=0.0, default=0.0,
update=( update=(lambda self, context: self.sync_prop('plot_time_start', context)),
lambda self, context: self.sync_prop('plot_time_start', context)
),
) )
plot_time_end: bpy.props.FloatProperty( plot_time_end: bpy.props.FloatProperty(
name='Plot Time End (ps)', name='Plot Time End (ps)',
description='The instance ID of a particular MaxwellSimNode instance, used to index caches', description='The instance ID of a particular MaxwellSimNode instance, used to index caches',
default=5, default=5,
update=( update=(lambda self, context: self.sync_prop('plot_time_start', context)),
lambda self, context: self.sync_prop('plot_time_start', context)
),
) )
#################### ####################
@ -85,7 +81,7 @@ class GaussianPulseTemporalShapeNode(base.MaxwellSimNode):
#################### ####################
# - Output Socket Computation # - Output Socket Computation
#################### ####################
@base.computes_output_socket( @events.computes_output_socket(
'Temporal Shape', 'Temporal Shape',
input_sockets={ input_sockets={
'Freq Center', 'Freq Center',
@ -100,8 +96,7 @@ class GaussianPulseTemporalShapeNode(base.MaxwellSimNode):
(_freq_center := input_sockets['Freq Center']) is None (_freq_center := input_sockets['Freq Center']) is None
or (_freq_std := input_sockets['Freq Std.']) is None or (_freq_std := input_sockets['Freq Std.']) is None
or (_phase := input_sockets['Phase']) is None or (_phase := input_sockets['Phase']) is None
or (time_delay_rel_ang_freq := input_sockets['Delay rel. AngFreq']) or (time_delay_rel_ang_freq := input_sockets['Delay rel. AngFreq']) is None
is None
or (remove_dc_component := input_sockets['Remove DC']) is None or (remove_dc_component := input_sockets['Remove DC']) is None
): ):
raise ValueError('Inputs not defined') raise ValueError('Inputs not defined')
@ -120,7 +115,7 @@ class GaussianPulseTemporalShapeNode(base.MaxwellSimNode):
remove_dc_component=remove_dc_component, remove_dc_component=remove_dc_component,
) )
@base.on_show_plot( @events.on_show_plot(
managed_objs={'amp_time'}, managed_objs={'amp_time'},
props={'plot_time_start', 'plot_time_end'}, props={'plot_time_start', 'plot_time_end'},
output_sockets={'Temporal Shape'}, output_sockets={'Temporal Shape'},

View File

@ -5,7 +5,7 @@ import tidy3d as td
from .....utils import analyze_geonodes, logger from .....utils import analyze_geonodes, logger
from ... import bl_socket_map, managed_objs, sockets from ... import bl_socket_map, managed_objs, sockets
from ... import contracts as ct from ... import contracts as ct
from .. import base from .. import base, events
log = logger.get(__name__) log = logger.get(__name__)
@ -39,7 +39,7 @@ class GeoNodesStructureNode(base.MaxwellSimNode):
#################### ####################
# - Event Methods # - Event Methods
#################### ####################
@base.computes_output_socket( @events.computes_output_socket(
'Structure', 'Structure',
input_sockets={'Medium'}, input_sockets={'Medium'},
managed_objs={'geometry'}, managed_objs={'geometry'},
@ -67,7 +67,7 @@ class GeoNodesStructureNode(base.MaxwellSimNode):
#################### ####################
# - Event Methods # - Event Methods
#################### ####################
@base.on_value_changed( @events.on_value_changed(
socket_name='GeoNodes', socket_name='GeoNodes',
prop_name='preview_active', prop_name='preview_active',
any_loose_input_socket=True, any_loose_input_socket=True,

View File

@ -4,7 +4,7 @@ import numpy as np
import tidy3d as td import tidy3d as td
from ... import contracts, sockets from ... import contracts, sockets
from .. import base from .. import base, events
class ObjectStructureNode(base.MaxwellSimTreeNode): class ObjectStructureNode(base.MaxwellSimTreeNode):
@ -32,7 +32,7 @@ class ObjectStructureNode(base.MaxwellSimTreeNode):
#################### ####################
# - Output Socket Computation # - Output Socket Computation
#################### ####################
@base.computes_output_socket('structure') @events.computes_output_socket('structure')
def compute_structure(self: contracts.NodeTypeProtocol) -> td.Structure: def compute_structure(self: contracts.NodeTypeProtocol) -> td.Structure:
# Extract the Blender Object # Extract the Blender Object
bl_object = self.compute_input('object') bl_object = self.compute_input('object')
@ -54,9 +54,7 @@ class ObjectStructureNode(base.MaxwellSimTreeNode):
# Extract Vertices and Faces # Extract Vertices and Faces
vertices = np.array([vert.co for vert in mesh.vertices]) vertices = np.array([vert.co for vert in mesh.vertices])
faces = np.array( faces = np.array([[vert for vert in poly.vertices] for poly in mesh.polygons])
[[vert for vert in poly.vertices] for poly in mesh.polygons]
)
# Remove Temporary Mesh # Remove Temporary Mesh
bpy.data.meshes.remove(mesh) bpy.data.meshes.remove(mesh)
@ -74,7 +72,5 @@ BL_REGISTER = [
ObjectStructureNode, ObjectStructureNode,
] ]
BL_NODES = { BL_NODES = {
contracts.NodeType.ObjectStructure: ( contracts.NodeType.ObjectStructure: (contracts.NodeCategory.MAXWELLSIM_STRUCTURES)
contracts.NodeCategory.MAXWELLSIM_STRUCTURES
)
} }

View File

@ -7,7 +7,7 @@ import tidy3d as td
from .....assets.import_geonodes import import_geonodes from .....assets.import_geonodes import import_geonodes
from .... import contracts as ct from .... import contracts as ct
from .... import managed_objs, sockets from .... import managed_objs, sockets
from ... import base from ... import base, events
GEONODES_BOX = 'box' GEONODES_BOX = 'box'
@ -43,7 +43,7 @@ class BoxStructureNode(base.MaxwellSimNode):
#################### ####################
# - Event Methods # - Event Methods
#################### ####################
@base.computes_output_socket( @events.computes_output_socket(
'Structure', 'Structure',
input_sockets={'Medium', 'Center', 'Size'}, input_sockets={'Medium', 'Center', 'Size'},
unit_systems={'Tidy3DUnits': ct.UNITS_TIDY3D}, unit_systems={'Tidy3DUnits': ct.UNITS_TIDY3D},
@ -61,7 +61,7 @@ class BoxStructureNode(base.MaxwellSimNode):
medium=input_sockets['Medium'], medium=input_sockets['Medium'],
) )
@base.on_value_changed( @events.on_value_changed(
socket_name={'Center', 'Size'}, socket_name={'Center', 'Size'},
prop_name='preview_active', prop_name='preview_active',
# Method Data # Method Data
@ -96,7 +96,7 @@ class BoxStructureNode(base.MaxwellSimNode):
if props['preview_active']: if props['preview_active']:
managed_objs['mesh'].show_preview() managed_objs['mesh'].show_preview()
@base.on_init() @events.on_init()
def on_init(self): def on_init(self):
self.on_input_change() self.on_input_change()

View File

@ -2,7 +2,7 @@ import sympy.physics.units as spu
import tidy3d as td import tidy3d as td
from .... import contracts, sockets from .... import contracts, sockets
from ... import base from ... import base, events
class CylinderStructureNode(base.MaxwellSimTreeNode): class CylinderStructureNode(base.MaxwellSimTreeNode):
@ -36,7 +36,7 @@ class CylinderStructureNode(base.MaxwellSimTreeNode):
#################### ####################
# - Output Socket Computation # - Output Socket Computation
#################### ####################
@base.computes_output_socket('structure') @events.computes_output_socket('structure')
def compute_simulation(self: contracts.NodeTypeProtocol) -> td.Box: def compute_simulation(self: contracts.NodeTypeProtocol) -> td.Box:
medium = self.compute_input('medium') medium = self.compute_input('medium')
_center = self.compute_input('center') _center = self.compute_input('center')

View File

@ -5,7 +5,7 @@ import tidy3d as td
from ......utils import analyze_geonodes from ......utils import analyze_geonodes
from .... import contracts as ct from .... import contracts as ct
from .... import managed_objs, sockets from .... import managed_objs, sockets
from ... import base from ... import base, events
GEONODES_STRUCTURE_SPHERE = 'structure_sphere' GEONODES_STRUCTURE_SPHERE = 'structure_sphere'
@ -38,7 +38,7 @@ class SphereStructureNode(base.MaxwellSimNode):
#################### ####################
# - Output Socket Computation # - Output Socket Computation
#################### ####################
@base.computes_output_socket( @events.computes_output_socket(
'Structure', 'Structure',
input_sockets={'Center', 'Radius', 'Medium'}, input_sockets={'Center', 'Radius', 'Medium'},
) )
@ -61,7 +61,7 @@ class SphereStructureNode(base.MaxwellSimNode):
#################### ####################
# - Preview - Changes to Input Sockets # - Preview - Changes to Input Sockets
#################### ####################
@base.on_value_changed( @events.on_value_changed(
socket_name={'Center', 'Radius'}, socket_name={'Center', 'Radius'},
input_sockets={'Center', 'Radius'}, input_sockets={'Center', 'Radius'},
managed_objs={'structure_sphere'}, managed_objs={'structure_sphere'},
@ -72,9 +72,7 @@ class SphereStructureNode(base.MaxwellSimNode):
managed_objs: dict[str, ct.schemas.ManagedObj], managed_objs: dict[str, ct.schemas.ManagedObj],
): ):
_center = input_sockets['Center'] _center = input_sockets['Center']
center = tuple( center = tuple([float(el) for el in spu.convert_to(_center, spu.um) / spu.um])
[float(el) for el in spu.convert_to(_center, spu.um) / spu.um]
)
_radius = input_sockets['Radius'] _radius = input_sockets['Radius']
radius = float(spu.convert_to(_radius, spu.um) / spu.um) radius = float(spu.convert_to(_radius, spu.um) / spu.um)
@ -82,9 +80,7 @@ class SphereStructureNode(base.MaxwellSimNode):
# Retrieve Hard-Coded GeoNodes and Analyze Input # Retrieve Hard-Coded GeoNodes and Analyze Input
geo_nodes = bpy.data.node_groups[GEONODES_STRUCTURE_SPHERE] geo_nodes = bpy.data.node_groups[GEONODES_STRUCTURE_SPHERE]
geonodes_interface = analyze_geonodes.interface( geonodes_interface = analyze_geonodes.interface(geo_nodes, direc='INPUT')
geo_nodes, direc='INPUT'
)
# Sync Modifier Inputs # Sync Modifier Inputs
managed_objs['structure_sphere'].sync_geonodes_modifier( managed_objs['structure_sphere'].sync_geonodes_modifier(
@ -104,7 +100,7 @@ class SphereStructureNode(base.MaxwellSimNode):
#################### ####################
# - Preview - Show Preview # - Preview - Show Preview
#################### ####################
@base.on_show_preview( @events.on_show_preview(
managed_objs={'structure_sphere'}, managed_objs={'structure_sphere'},
) )
def on_show_preview( def on_show_preview(
@ -122,7 +118,5 @@ BL_REGISTER = [
SphereStructureNode, SphereStructureNode,
] ]
BL_NODES = { BL_NODES = {
ct.NodeType.SphereStructure: ( ct.NodeType.SphereStructure: (ct.NodeCategory.MAXWELLSIM_STRUCTURES_PRIMITIVES)
ct.NodeCategory.MAXWELLSIM_STRUCTURES_PRIMITIVES
)
} }

View File

@ -3,7 +3,7 @@ import sympy as sp
from ... import contracts as ct from ... import contracts as ct
from ... import sockets from ... import sockets
from .. import base from .. import base, events
MAX_AMOUNT = 20 MAX_AMOUNT = 20
@ -20,9 +20,7 @@ class CombineNode(base.MaxwellSimNode):
'Maxwell Sources': {}, 'Maxwell Sources': {},
'Maxwell Structures': {}, 'Maxwell Structures': {},
'Maxwell Monitors': {}, 'Maxwell Monitors': {},
'Real 3D Vector': { 'Real 3D Vector': {f'x_{i}': sockets.RealNumberSocketDef() for i in range(3)},
f'x_{i}': sockets.RealNumberSocketDef() for i in range(3)
},
# "Point 3D": { # "Point 3D": {
# axis: sockets.PhysicalLengthSocketDef() # axis: sockets.PhysicalLengthSocketDef()
# for i, axis in zip( # for i, axis in zip(
@ -84,13 +82,13 @@ class CombineNode(base.MaxwellSimNode):
#################### ####################
# - Output Socket Computation # - Output Socket Computation
#################### ####################
@base.computes_output_socket( @events.computes_output_socket(
'Real 3D Vector', input_sockets={'x_0', 'x_1', 'x_2'} 'Real 3D Vector', input_sockets={'x_0', 'x_1', 'x_2'}
) )
def compute_real_3d_vector(self, input_sockets) -> sp.Expr: def compute_real_3d_vector(self, input_sockets) -> sp.Expr:
return sp.Matrix([input_sockets[f'x_{i}'] for i in range(3)]) return sp.Matrix([input_sockets[f'x_{i}'] for i in range(3)])
@base.computes_output_socket( @events.computes_output_socket(
'Sources', 'Sources',
input_sockets={f'Source #{i}' for i in range(MAX_AMOUNT)}, input_sockets={f'Source #{i}' for i in range(MAX_AMOUNT)},
props={'amount'}, props={'amount'},
@ -98,17 +96,15 @@ class CombineNode(base.MaxwellSimNode):
def compute_sources(self, input_sockets, props) -> sp.Expr: def compute_sources(self, input_sockets, props) -> sp.Expr:
return [input_sockets[f'Source #{i}'] for i in range(props['amount'])] return [input_sockets[f'Source #{i}'] for i in range(props['amount'])]
@base.computes_output_socket( @events.computes_output_socket(
'Structures', 'Structures',
input_sockets={f'Structure #{i}' for i in range(MAX_AMOUNT)}, input_sockets={f'Structure #{i}' for i in range(MAX_AMOUNT)},
props={'amount'}, props={'amount'},
) )
def compute_structures(self, input_sockets, props) -> sp.Expr: def compute_structures(self, input_sockets, props) -> sp.Expr:
return [ return [input_sockets[f'Structure #{i}'] for i in range(props['amount'])]
input_sockets[f'Structure #{i}'] for i in range(props['amount'])
]
@base.computes_output_socket( @events.computes_output_socket(
'Monitors', 'Monitors',
input_sockets={f'Monitor #{i}' for i in range(MAX_AMOUNT)}, input_sockets={f'Monitor #{i}' for i in range(MAX_AMOUNT)},
props={'amount'}, props={'amount'},
@ -119,7 +115,7 @@ class CombineNode(base.MaxwellSimNode):
#################### ####################
# - Input Socket Compilation # - Input Socket Compilation
#################### ####################
@base.on_value_changed( @events.on_value_changed(
prop_name='active_socket_set', prop_name='active_socket_set',
props={'active_socket_set', 'amount'}, props={'active_socket_set', 'amount'},
) )
@ -142,13 +138,13 @@ class CombineNode(base.MaxwellSimNode):
else: else:
self.loose_input_sockets = {} self.loose_input_sockets = {}
@base.on_value_changed( @events.on_value_changed(
prop_name='amount', prop_name='amount',
) )
def on_value_changed__amount(self): def on_value_changed__amount(self):
self.on_value_changed__active_socket_set() self.on_value_changed__active_socket_set()
@base.on_init() @events.on_init()
def on_init(self): def on_init(self):
self.on_value_changed__active_socket_set() self.on_value_changed__active_socket_set()

View File

@ -3,7 +3,7 @@ import sympy as sp
import sympy.physics.units as spu import sympy.physics.units as spu
from .... import contracts, sockets from .... import contracts, sockets
from ... import base from ... import base, events
class WaveConverterNode(base.MaxwellSimTreeNode): class WaveConverterNode(base.MaxwellSimTreeNode):
@ -44,11 +44,9 @@ class WaveConverterNode(base.MaxwellSimTreeNode):
#################### ####################
# - Output Socket Computation # - Output Socket Computation
#################### ####################
@base.computes_output_socket('freq') @events.computes_output_socket('freq')
def compute_freq(self: contracts.NodeTypeProtocol) -> sp.Expr: def compute_freq(self: contracts.NodeTypeProtocol) -> sp.Expr:
vac_speed_of_light = ( vac_speed_of_light = sc.constants.speed_of_light * spu.meter / spu.second
sc.constants.speed_of_light * spu.meter / spu.second
)
vacwl = self.compute_input('vacwl') vacwl = self.compute_input('vacwl')
@ -57,11 +55,9 @@ class WaveConverterNode(base.MaxwellSimTreeNode):
spu.hertz, spu.hertz,
) )
@base.computes_output_socket('vacwl') @events.computes_output_socket('vacwl')
def compute_vacwl(self: contracts.NodeTypeProtocol) -> sp.Expr: def compute_vacwl(self: contracts.NodeTypeProtocol) -> sp.Expr:
vac_speed_of_light = ( vac_speed_of_light = sc.constants.speed_of_light * spu.meter / spu.second
sc.constants.speed_of_light * spu.meter / spu.second
)
freq = self.compute_input('freq') freq = self.compute_input('freq')

View File

@ -16,12 +16,12 @@ class FDTDSimDataVizNode(base.MaxwellSimNode):
#################### ####################
# - Sockets # - Sockets
#################### ####################
input_sockets = { input_sockets: typ.ClassVar = {
'FDTD Sim Data': sockets.MaxwellFDTDSimDataSocketDef(), 'FDTD Sim Data': sockets.MaxwellFDTDSimDataSocketDef(),
} }
output_sockets = {'Preview': sockets.AnySocketDef()} output_sockets: typ.ClassVar = {'Preview': sockets.AnySocketDef()}
managed_obj_defs = { managed_obj_defs: typ.ClassVar = {
'viz_plot': ct.schemas.ManagedObjDef( 'viz_plot': ct.schemas.ManagedObjDef(
mk=lambda name: managed_objs.ManagedBLImage(name), mk=lambda name: managed_objs.ManagedBLImage(name),
name_prefix='', name_prefix='',
@ -63,9 +63,7 @@ class FDTDSimDataVizNode(base.MaxwellSimNode):
# ("Hz", "Hz", "Hz"), # ("Hz", "Hz", "Hz"),
], ],
default='E', default='E',
update=lambda self, context: self.sync_prop( update=lambda self, context: self.sync_prop('field_viz_component', context),
'field_viz_component', context
),
) )
field_viz_part: bpy.props.EnumProperty( field_viz_part: bpy.props.EnumProperty(
name='Field Part', name='Field Part',
@ -88,9 +86,7 @@ class FDTDSimDataVizNode(base.MaxwellSimNode):
('dB', 'Log (dB)', 'Logarithmic (dB) Scale'), ('dB', 'Log (dB)', 'Logarithmic (dB) Scale'),
], ],
default='lin', default='lin',
update=lambda self, context: self.sync_prop( update=lambda self, context: self.sync_prop('field_viz_scale', context),
'field_viz_scale', context
),
) )
field_viz_structure_visibility: bpy.props.FloatProperty( field_viz_structure_visibility: bpy.props.FloatProperty(
name='Field Viz Plot: Structure Visibility', name='Field Viz Plot: Structure Visibility',
@ -98,75 +94,57 @@ class FDTDSimDataVizNode(base.MaxwellSimNode):
default=0.2, default=0.2,
min=0.0, min=0.0,
max=1.0, max=1.0,
update=lambda self, context: self.sync_prop( update=lambda self, context: self.sync_prop('field_viz_plot_fixed_f', context),
'field_viz_plot_fixed_f', context
),
) )
field_viz_plot_fix_x: bpy.props.BoolProperty( field_viz_plot_fix_x: bpy.props.BoolProperty(
name='Field Viz Plot: Fix X', name='Field Viz Plot: Fix X',
description='Fix the x-coordinate on the plot', description='Fix the x-coordinate on the plot',
default=False, default=False,
update=lambda self, context: self.sync_prop( update=lambda self, context: self.sync_prop('field_viz_plot_fix_x', context),
'field_viz_plot_fix_x', context
),
) )
field_viz_plot_fix_y: bpy.props.BoolProperty( field_viz_plot_fix_y: bpy.props.BoolProperty(
name='Field Viz Plot: Fix Y', name='Field Viz Plot: Fix Y',
description='Fix the y coordinate on the plot', description='Fix the y coordinate on the plot',
default=False, default=False,
update=lambda self, context: self.sync_prop( update=lambda self, context: self.sync_prop('field_viz_plot_fix_y', context),
'field_viz_plot_fix_y', context
),
) )
field_viz_plot_fix_z: bpy.props.BoolProperty( field_viz_plot_fix_z: bpy.props.BoolProperty(
name='Field Viz Plot: Fix Z', name='Field Viz Plot: Fix Z',
description='Fix the z coordinate on the plot', description='Fix the z coordinate on the plot',
default=False, default=False,
update=lambda self, context: self.sync_prop( update=lambda self, context: self.sync_prop('field_viz_plot_fix_z', context),
'field_viz_plot_fix_z', context
),
) )
field_viz_plot_fix_f: bpy.props.BoolProperty( field_viz_plot_fix_f: bpy.props.BoolProperty(
name='Field Viz Plot: Fix Freq', name='Field Viz Plot: Fix Freq',
description='Fix the frequency coordinate on the plot', description='Fix the frequency coordinate on the plot',
default=False, default=False,
update=lambda self, context: self.sync_prop( update=lambda self, context: self.sync_prop('field_viz_plot_fix_f', context),
'field_viz_plot_fix_f', context
),
) )
field_viz_plot_fixed_x: bpy.props.FloatProperty( field_viz_plot_fixed_x: bpy.props.FloatProperty(
name='Field Viz Plot: Fix X', name='Field Viz Plot: Fix X',
description='Fix the x-coordinate on the plot', description='Fix the x-coordinate on the plot',
default=0.0, default=0.0,
update=lambda self, context: self.sync_prop( update=lambda self, context: self.sync_prop('field_viz_plot_fixed_x', context),
'field_viz_plot_fixed_x', context
),
) )
field_viz_plot_fixed_y: bpy.props.FloatProperty( field_viz_plot_fixed_y: bpy.props.FloatProperty(
name='Field Viz Plot: Fixed Y', name='Field Viz Plot: Fixed Y',
description='Fix the y coordinate on the plot', description='Fix the y coordinate on the plot',
default=0.0, default=0.0,
update=lambda self, context: self.sync_prop( update=lambda self, context: self.sync_prop('field_viz_plot_fixed_y', context),
'field_viz_plot_fixed_y', context
),
) )
field_viz_plot_fixed_z: bpy.props.FloatProperty( field_viz_plot_fixed_z: bpy.props.FloatProperty(
name='Field Viz Plot: Fixed Z', name='Field Viz Plot: Fixed Z',
description='Fix the z coordinate on the plot', description='Fix the z coordinate on the plot',
default=0.0, default=0.0,
update=lambda self, context: self.sync_prop( update=lambda self, context: self.sync_prop('field_viz_plot_fixed_z', context),
'field_viz_plot_fixed_z', context
),
) )
field_viz_plot_fixed_f: bpy.props.FloatProperty( field_viz_plot_fixed_f: bpy.props.FloatProperty(
name='Field Viz Plot: Fixed Freq (Thz)', name='Field Viz Plot: Fixed Freq (Thz)',
description='Fix the frequency coordinate on the plot', description='Fix the frequency coordinate on the plot',
default=0.0, default=0.0,
update=lambda self, context: self.sync_prop( update=lambda self, context: self.sync_prop('field_viz_plot_fixed_f', context),
'field_viz_plot_fixed_f', context
),
) )
#################### ####################
@ -176,9 +154,7 @@ class FDTDSimDataVizNode(base.MaxwellSimNode):
if (sim_data := self._compute_input('FDTD Sim Data')) is None: if (sim_data := self._compute_input('FDTD Sim Data')) is None:
return return
self.cache_viz_monitor_type = sim_data.monitor_data[ self.cache_viz_monitor_type = sim_data.monitor_data[self.viz_monitor_name].type
self.viz_monitor_name
].type
self.sync_prop('viz_monitor_name', context) self.sync_prop('viz_monitor_name', context)
def retrieve_monitors(self, context) -> list[tuple]: def retrieve_monitors(self, context) -> list[tuple]:
@ -260,9 +236,7 @@ class FDTDSimDataVizNode(base.MaxwellSimNode):
CACHE.pop(self.instance_id, None) CACHE.pop(self.instance_id, None)
return return
CACHE[self.instance_id] = { CACHE[self.instance_id] = {'monitors': list(sim_data.monitor_data.keys())}
'monitors': list(sim_data.monitor_data.keys())
}
#################### ####################
# - Plotting # - Plotting

View File

@ -1,4 +1,3 @@
import pydantic as pyd import pydantic as pyd
from ... import contracts as ct from ... import contracts as ct

View File

@ -1,4 +1,3 @@
import bpy import bpy
import pydantic as pyd import pydantic as pyd
@ -26,9 +25,7 @@ class BoolBLSocket(base.MaxwellSimSocket):
#################### ####################
# - Socket UI # - Socket UI
#################### ####################
def draw_label_row( def draw_label_row(self, label_col_row: bpy.types.UILayout, text: str) -> None:
self, label_col_row: bpy.types.UILayout, text: str
) -> None:
label_col_row.label(text=text) label_col_row.label(text=text)
label_col_row.prop(self, 'raw_value', text='') label_col_row.prop(self, 'raw_value', text='')

View File

@ -1,4 +1,3 @@
import bpy import bpy
import pydantic as pyd import pydantic as pyd
@ -26,9 +25,7 @@ class StringBLSocket(base.MaxwellSimSocket):
#################### ####################
# - Socket UI # - Socket UI
#################### ####################
def draw_label_row( def draw_label_row(self, label_col_row: bpy.types.UILayout, text: str) -> None:
self, label_col_row: bpy.types.UILayout, text: str
) -> None:
label_col_row.prop(self, 'raw_value', text=text) label_col_row.prop(self, 'raw_value', text=text)
#################### ####################

View File

@ -1,4 +1,3 @@
import bpy import bpy
import pydantic as pyd import pydantic as pyd

View File

@ -1,4 +1,3 @@
import bpy import bpy
import pydantic as pyd import pydantic as pyd

View File

@ -1,4 +1,3 @@
import bpy import bpy
import pydantic as pyd import pydantic as pyd

View File

@ -24,9 +24,7 @@ class MaxwellBoundCondBLSocket(base.MaxwellSimSocket):
('PERIODIC', 'Periodic', 'Infinitely periodic layer'), ('PERIODIC', 'Periodic', 'Infinitely periodic layer'),
], ],
default='PML', default='PML',
update=( update=(lambda self, context: self.sync_prop('default_choice', context)),
lambda self, context: self.sync_prop('default_choice', context)
),
) )
#################### ####################
@ -48,9 +46,7 @@ class MaxwellBoundCondBLSocket(base.MaxwellSimSocket):
}[self.default_choice] }[self.default_choice]
@value.setter @value.setter
def value( def value(self, value: typx.Literal['PML', 'PEC', 'PMC', 'PERIODIC']) -> None:
self, value: typx.Literal['PML', 'PEC', 'PMC', 'PERIODIC']
) -> None:
self.default_choice = value self.default_choice = value

View File

@ -1,4 +1,3 @@
import bpy import bpy
import pydantic as pyd import pydantic as pyd
import tidy3d as td import tidy3d as td
@ -31,9 +30,7 @@ class MaxwellBoundCondsBLSocket(base.MaxwellSimSocket):
name='Show Bounds Definition', name='Show Bounds Definition',
description='Toggle to show bound faces', description='Toggle to show bound faces',
default=False, default=False,
update=( update=(lambda self, context: self.sync_prop('show_definition', context)),
lambda self, context: self.sync_prop('show_definition', context)
),
) )
x_pos: bpy.props.EnumProperty( x_pos: bpy.props.EnumProperty(
@ -84,9 +81,7 @@ class MaxwellBoundCondsBLSocket(base.MaxwellSimSocket):
#################### ####################
def draw_label_row(self, row: bpy.types.UILayout, text) -> None: def draw_label_row(self, row: bpy.types.UILayout, text) -> None:
row.label(text=text) row.label(text=text)
row.prop( row.prop(self, 'show_definition', toggle=True, text='', icon='MOD_LENGTH')
self, 'show_definition', toggle=True, text='', icon='MOD_LENGTH'
)
def draw_value(self, col: bpy.types.UILayout) -> None: def draw_value(self, col: bpy.types.UILayout) -> None:
if not self.show_definition: if not self.show_definition:

View File

@ -1,4 +1,3 @@
import pydantic as pyd import pydantic as pyd
from ... import contracts as ct from ... import contracts as ct

View File

@ -1,4 +1,3 @@
import pydantic as pyd import pydantic as pyd
from ... import contracts as ct from ... import contracts as ct

View File

@ -1,4 +1,3 @@
import bpy import bpy
import pydantic as pyd import pydantic as pyd
import scipy as sc import scipy as sc
@ -35,9 +34,7 @@ class MaxwellMediumBLSocket(base.MaxwellSimSocket):
size=2, size=2,
default=(1.0, 0.0), default=(1.0, 0.0),
precision=2, precision=2,
update=( update=(lambda self, context: self.sync_prop('rel_permittivity', context)),
lambda self, context: self.sync_prop('rel_permittivity', context)
),
) )
#################### ####################

View File

@ -1,4 +1,3 @@
import pydantic as pyd import pydantic as pyd
from ... import contracts as ct from ... import contracts as ct

View File

@ -1,4 +1,3 @@
import pydantic as pyd import pydantic as pyd
from ... import contracts as ct from ... import contracts as ct

View File

@ -1,4 +1,3 @@
import pydantic as pyd import pydantic as pyd
from ... import contracts as ct from ... import contracts as ct

View File

@ -1,4 +1,3 @@
import bpy import bpy
import pydantic as pyd import pydantic as pyd
import tidy3d as td import tidy3d as td
@ -21,9 +20,7 @@ class MaxwellSimGridBLSocket(base.MaxwellSimSocket):
min=0.01, min=0.01,
# step=10, # step=10,
precision=2, precision=2,
update=( update=(lambda self, context: self.sync_prop('min_steps_per_wl', context)),
lambda self, context: self.sync_prop('min_steps_per_wl', context)
),
) )
#################### ####################

View File

@ -1,4 +1,3 @@
import pydantic as pyd import pydantic as pyd
from ... import contracts as ct from ... import contracts as ct

View File

@ -1,4 +1,3 @@
import pydantic as pyd import pydantic as pyd
from ... import contracts as ct from ... import contracts as ct

View File

@ -1,4 +1,3 @@
import pydantic as pyd import pydantic as pyd
from ... import contracts as ct from ... import contracts as ct

View File

@ -1,4 +1,3 @@
import pydantic as pyd import pydantic as pyd
from ... import contracts as ct from ... import contracts as ct

View File

@ -1,4 +1,3 @@
import bpy import bpy
import pydantic as pyd import pydantic as pyd

View File

@ -1,4 +1,3 @@
import bpy import bpy
import pydantic as pyd import pydantic as pyd
import sympy as sp import sympy as sp

View File

@ -1,4 +1,3 @@
import bpy import bpy
import pydantic as pyd import pydantic as pyd

View File

@ -1,4 +1,3 @@
import bpy import bpy
import pydantic as pyd import pydantic as pyd
import sympy.physics.units as spu import sympy.physics.units as spu

View File

@ -1,4 +1,3 @@
import bpy import bpy
import pydantic as pyd import pydantic as pyd
import sympy.physics.units as spu import sympy.physics.units as spu

View File

@ -1,4 +1,3 @@
import bpy import bpy
import pydantic as pyd import pydantic as pyd
import sympy.physics.units as spu import sympy.physics.units as spu

View File

@ -1,4 +1,3 @@
import bpy import bpy
import numpy as np import numpy as np
import pydantic as pyd import pydantic as pyd

View File

@ -1,4 +1,3 @@
import bpy import bpy
import numpy as np import numpy as np
import pydantic as pyd import pydantic as pyd
@ -74,8 +73,7 @@ class PhysicalLengthBLSocket(base.MaxwellSimSocket):
@property @property
def value_list(self) -> list[SympyExpr]: def value_list(self) -> list[SympyExpr]:
return [ return [
el * self.unit el * self.unit for el in np.linspace(self.min_len, self.max_len, self.steps)
for el in np.linspace(self.min_len, self.max_len, self.steps)
] ]
@value_list.setter @value_list.setter

View File

@ -1,4 +1,3 @@
import bpy import bpy
import pydantic as pyd import pydantic as pyd
import sympy.physics.units as spu import sympy.physics.units as spu

View File

@ -1,4 +1,3 @@
import bpy import bpy
import pydantic as pyd import pydantic as pyd
import sympy as sp import sympy as sp

View File

@ -1,4 +1,3 @@
import bpy import bpy
import pydantic as pyd import pydantic as pyd
import sympy as sp import sympy as sp

View File

@ -1,4 +1,3 @@
import bpy import bpy
import pydantic as pyd import pydantic as pyd
import sympy.physics.units as spu import sympy.physics.units as spu

View File

@ -1,4 +1,3 @@
import bpy import bpy
import pydantic as pyd import pydantic as pyd
import sympy.physics.units as spu import sympy.physics.units as spu

View File

@ -1,12 +1,11 @@
import types import types
import typing as typ
from .. import contracts as ct from .. import contracts as ct
def scan_for_socket_defs( def scan_for_socket_defs(
sockets_module: types.ModuleType, sockets_module: types.ModuleType,
) -> dict[ct.SocketType, typ.Type[ct.schemas.SocketDef]]: ) -> dict[ct.SocketType, type[ct.schemas.SocketDef]]:
return { return {
socket_type: getattr( socket_type: getattr(
sockets_module, sockets_module,
@ -18,4 +17,5 @@ def scan_for_socket_defs(
) )
} }
## TODO: Function for globals() filling too. ## TODO: Function for globals() filling too.

View File

@ -1,4 +1,3 @@
import pydantic as pyd import pydantic as pyd
from ... import contracts as ct from ... import contracts as ct

View File

@ -1,4 +1,3 @@
import pydantic as pyd import pydantic as pyd
from ... import contracts as ct from ... import contracts as ct

View File

@ -1,4 +1,3 @@
import bpy import bpy
import pydantic as pyd import pydantic as pyd
import sympy as sp import sympy as sp

View File

@ -1,4 +1,3 @@
import bpy import bpy
import pydantic as pyd import pydantic as pyd
import sympy as sp import sympy as sp

View File

@ -1,4 +1,3 @@
import bpy import bpy
import pydantic as pyd import pydantic as pyd
import sympy as sp import sympy as sp

View File

@ -18,7 +18,7 @@ LOG_LEVEL_MAP: dict[str, LogLevel] = {
SIMPLE_LOGGER_PREFIX = 'simple::' SIMPLE_LOGGER_PREFIX = 'simple::'
STREAM_LOG_FORMAT = 11*' ' + '%(levelname)-8s %(message)s (%(name)s)' STREAM_LOG_FORMAT = 11 * ' ' + '%(levelname)-8s %(message)s (%(name)s)'
FILE_LOG_FORMAT = STREAM_LOG_FORMAT FILE_LOG_FORMAT = STREAM_LOG_FORMAT
#################### ####################
@ -122,7 +122,7 @@ def sync_bootstrap_logging(
file_path=file_path, file_path=file_path,
file_level=file_level, file_level=file_level,
) )
logger_logger.info("Bootstrapped Logging w/Settings %s", str(CACHE)) logger_logger.info('Bootstrapped Logging w/Settings %s', str(CACHE))
def sync_loggers( def sync_loggers(
@ -153,9 +153,7 @@ def sync_loggers(
# - Logger Iteration # - Logger Iteration
#################### ####################
def loggers(): def loggers():
return [ return [logging.getLogger(name) for name in logging.root.manager.loggerDict]
logging.getLogger(name) for name in logging.root.manager.loggerDict
]
def simple_loggers(): def simple_loggers():

View File

@ -9,8 +9,7 @@ class BlenderTypeEnum(str, enum.Enum):
def append_cls_name_to_values(cls): def append_cls_name_to_values(cls):
# Construct Set w/Modified Member Names # Construct Set w/Modified Member Names
new_members = { new_members = {
name: f'{name}{cls.__name__}' name: f'{name}{cls.__name__}' for name, member in cls.__members__.items()
for name, member in cls.__members__.items()
} }
# Dynamically Declare New Enum Class w/Modified Members # Dynamically Declare New Enum Class w/Modified Members
@ -24,8 +23,7 @@ def append_cls_name_to_values(cls):
def wrap_values_in_MT(cls): def wrap_values_in_MT(cls):
# Construct Set w/Modified Member Names # Construct Set w/Modified Member Names
new_members = { new_members = {
name: f'BLENDER_MAXWELL_MT_{name}' name: f'BLENDER_MAXWELL_MT_{name}' for name, member in cls.__members__.items()
for name, member in cls.__members__.items()
} }
# Dynamically Declare New Enum Class w/Modified Members # Dynamically Declare New Enum Class w/Modified Members

View File

@ -104,6 +104,7 @@ def scale_to_unit(expr: sp.Expr, unit: spu.Quantity) -> typ.Any:
msg = f'Expression "{expr}" was scaled to the unit "{unit}" with the expectation that the result would be unitless, but the result "{unitless_expr}" has units "{get_units(unitless_expr)}"' msg = f'Expression "{expr}" was scaled to the unit "{unit}" with the expectation that the result would be unitless, but the result "{unitless_expr}" has units "{get_units(unitless_expr)}"'
raise ValueError(msg) raise ValueError(msg)
#################### ####################
# - Sympy <-> Scalars # - Sympy <-> Scalars
#################### ####################

View File

@ -21,7 +21,8 @@ OUTPUT_CONSOLE = rich.console.Console(
## TODO: color_system should be 'auto'; bl_run.py hijinks are interfering ## TODO: color_system should be 'auto'; bl_run.py hijinks are interfering
) )
ERROR_CONSOLE = rich.console.Console( ERROR_CONSOLE = rich.console.Console(
color_system='truecolor', stderr=True color_system='truecolor',
stderr=True,
## TODO: color_system should be 'auto'; bl_run.py hijinks are interfering ## TODO: color_system should be 'auto'; bl_run.py hijinks are interfering
) )
rich.traceback.install(show_locals=True, console=ERROR_CONSOLE) rich.traceback.install(show_locals=True, console=ERROR_CONSOLE)

View File

@ -51,12 +51,8 @@ class _SympyExpr:
sympy_expr_schema = pyd_core_schema.chain_schema( sympy_expr_schema = pyd_core_schema.chain_schema(
[ [
pyd_core_schema.no_info_plain_validator_function( pyd_core_schema.no_info_plain_validator_function(validate_from_str),
validate_from_str pyd_core_schema.no_info_plain_validator_function(validate_from_expr),
),
pyd_core_schema.no_info_plain_validator_function(
validate_from_expr
),
pyd_core_schema.is_instance_schema(AllowedSympyExprs), pyd_core_schema.is_instance_schema(AllowedSympyExprs),
] ]
) )
@ -108,9 +104,7 @@ def ConstrSympyExpr(
f'allow_variables={allow_variables} does not match expression {expr}.' f'allow_variables={allow_variables} does not match expression {expr}.'
) )
if (not allow_units) and spux.uses_units(expr): if (not allow_units) and spux.uses_units(expr):
msgs.add( msgs.add(f'allow_units={allow_units} does not match expression {expr}.')
f'allow_units={allow_units} does not match expression {expr}.'
)
# Validate Structure Class # Validate Structure Class
if ( if (
@ -150,9 +144,7 @@ def ConstrSympyExpr(
f'allowed_symbols={allowed_symbols} does not match expression {expr}' f'allowed_symbols={allowed_symbols} does not match expression {expr}'
) )
if allowed_units and spux.get_units(expr).issubset(allowed_units): if allowed_units and spux.get_units(expr).issubset(allowed_units):
msgs.add( msgs.add(f'allowed_units={allowed_units} does not match expression {expr}')
f'allowed_units={allowed_units} does not match expression {expr}'
)
# Validate Shape Class # Validate Shape Class
if ( if (

View File

@ -1,6 +1,6 @@
import scipy as sc import scipy as sc
import sympy.physics.units as spu import sympy.physics.units as spu
#from . import extra_sympy_units as spux # from . import extra_sympy_units as spux
vac_speed_of_light = sc.constants.speed_of_light * spu.meter / spu.second vac_speed_of_light = sc.constants.speed_of_light * spu.meter / spu.second

View File

@ -161,7 +161,7 @@ def main():
# Setup Addon for Development Use # Setup Addon for Development Use
setup_for_development(info.ADDON_NAME, info.PATH_ADDON_DEV_DEPS) setup_for_development(info.ADDON_NAME, info.PATH_ADDON_DEV_DEPS)
# Load Development .blend # Load Development .blend
## TODO: We need a better (also final-deployed-compatible) solution for what happens when a user opened a .blend file without installing dependencies! ## TODO: We need a better (also final-deployed-compatible) solution for what happens when a user opened a .blend file without installing dependencies!
if not install_failed: if not install_failed:

View File

@ -54,5 +54,6 @@ def main():
elif return_code != 0: elif return_code != 0:
print(''.join(output)) # noqa: T201 print(''.join(output)) # noqa: T201
if __name__ == "__main__":
if __name__ == '__main__':
main() main()

View File

@ -35,9 +35,7 @@ ADDON_VERSION = PROJ_SPEC['project']['version']
# - Packaging Information # - Packaging Information
#################### ####################
PATH_ADDON_PKG = PATH_ROOT / 'src' / ADDON_NAME PATH_ADDON_PKG = PATH_ROOT / 'src' / ADDON_NAME
PATH_ADDON_ZIP = ( PATH_ADDON_ZIP = PATH_ROOT / 'build' / (ADDON_NAME + '__' + ADDON_VERSION + '.zip')
PATH_ROOT / 'build' / (ADDON_NAME + '__' + ADDON_VERSION + '.zip')
)
PATH_ADDON_BLEND_STARTER = PATH_ADDON_PKG / 'blenders' / 'starter.blend' PATH_ADDON_BLEND_STARTER = PATH_ADDON_PKG / 'blenders' / 'starter.blend'

View File

@ -69,9 +69,7 @@ def zipped_addon( # noqa: PLR0913
# Write File to Zip # Write File to Zip
else: else:
f_zip.write( f_zip.write(file_to_zip, file_to_zip.relative_to(path_addon_pkg.parent))
file_to_zip, file_to_zip.relative_to(path_addon_pkg.parent)
)
# Install pyproject.toml @ /pyproject.toml of Addon # Install pyproject.toml @ /pyproject.toml of Addon
f_zip.write( f_zip.write(
@ -114,5 +112,6 @@ def main():
# TODO: GPG signature for distribution # TODO: GPG signature for distribution
pass pass
if __name__ == "__main__":
if __name__ == '__main__':
main() main()