diff --git a/src/blender_maxwell/assets/internal/structure/_structure_primitive_cylinder.blend b/src/blender_maxwell/assets/internal/structure/_structure_primitive_cylinder.blend new file mode 100644 index 0000000..19d9c81 --- /dev/null +++ b/src/blender_maxwell/assets/internal/structure/_structure_primitive_cylinder.blend @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bd146c4c54a323f047d597034d3e3624ef47ce3334b055af4a526264c6880f16 +size 857695 diff --git a/src/blender_maxwell/node_trees/maxwell_sim_nodes/nodes/analysis/extract_data.py b/src/blender_maxwell/node_trees/maxwell_sim_nodes/nodes/analysis/extract_data.py index 196e3b4..60dcfa8 100644 --- a/src/blender_maxwell/node_trees/maxwell_sim_nodes/nodes/analysis/extract_data.py +++ b/src/blender_maxwell/node_trees/maxwell_sim_nodes/nodes/analysis/extract_data.py @@ -61,7 +61,9 @@ class ExtractDataNode(base.MaxwellSimNode): } output_socket_sets: typ.ClassVar = { 'Sim Data': {'Monitor Data': sockets.MaxwellMonitorDataSocketDef()}, - 'Monitor Data': {'Expr': sockets.ExprSocketDef(active_kind=ct.FlowKind.Array)}, + 'Monitor Data': { + 'Expr': sockets.ExprSocketDef(active_kind=ct.FlowKind.LazyArrayRange) + }, } #################### diff --git a/src/blender_maxwell/node_trees/maxwell_sim_nodes/nodes/monitors/eh_field_monitor.py b/src/blender_maxwell/node_trees/maxwell_sim_nodes/nodes/monitors/eh_field_monitor.py index b3d27cc..e96ed9a 100644 --- a/src/blender_maxwell/node_trees/maxwell_sim_nodes/nodes/monitors/eh_field_monitor.py +++ b/src/blender_maxwell/node_trees/maxwell_sim_nodes/nodes/monitors/eh_field_monitor.py @@ -222,9 +222,9 @@ class EHFieldMonitorNode(base.MaxwellSimNode): ) def on_inputs_changed( self, - managed_objs: dict, - input_sockets: dict, - unit_systems: dict, + managed_objs, + input_sockets, + unit_systems, ): # Push Input Values to GeoNodes Modifier managed_objs['modifier'].bl_modifier( diff --git a/src/blender_maxwell/node_trees/maxwell_sim_nodes/nodes/simulations/sim_domain.py b/src/blender_maxwell/node_trees/maxwell_sim_nodes/nodes/simulations/sim_domain.py index 1c060c6..d8aa1a2 100644 --- a/src/blender_maxwell/node_trees/maxwell_sim_nodes/nodes/simulations/sim_domain.py +++ b/src/blender_maxwell/node_trees/maxwell_sim_nodes/nodes/simulations/sim_domain.py @@ -65,7 +65,6 @@ class SimDomainNode(base.MaxwellSimNode): } managed_obj_types: typ.ClassVar = { - 'mesh': managed_objs.ManagedBLMesh, 'modifier': managed_objs.ManagedBLModifier, } @@ -95,19 +94,17 @@ class SimDomainNode(base.MaxwellSimNode): # - Preview #################### @events.on_value_changed( + # Trigger prop_name='preview_active', - run_on_init=True, + # Loaded + managed_objs={'modifier'}, props={'preview_active'}, - managed_objs={'mesh'}, ) - def on_preview_changed(self, props, managed_objs) -> None: - mesh = managed_objs['mesh'] - - # Push Preview State to Managed Mesh + def on_preview_changed(self, managed_objs, props): if props['preview_active']: - mesh.show_preview() + managed_objs['modifier'].show_preview() else: - mesh.hide_preview() + managed_objs['modifier'].hide_preview() @events.on_value_changed( ## Trigger @@ -115,7 +112,7 @@ class SimDomainNode(base.MaxwellSimNode): run_on_init=True, # Loaded input_sockets={'Center', 'Size'}, - managed_objs={'mesh', 'modifier'}, + managed_objs={'modifier'}, unit_systems={'BlenderUnits': ct.UNITS_BLENDER}, scale_input_sockets={ 'Center': 'BlenderUnits', @@ -127,21 +124,17 @@ class SimDomainNode(base.MaxwellSimNode): input_sockets, unit_systems, ): - mesh = managed_objs['mesh'] - modifier = managed_objs['modifier'] - center = input_sockets['Center'] - size = input_sockets['Size'] - unit_system = unit_systems['BlenderUnits'] - # Push Loose Input Values to GeoNodes Modifier - modifier.bl_modifier( - mesh.bl_object(location=center), + managed_objs['modifier'].bl_modifier( 'NODES', { 'node_group': import_geonodes(GeoNodes.SimulationSimDomain), - 'inputs': {'Size': size}, - 'unit_system': unit_system, + 'unit_system': unit_systems['BlenderUnits'], + 'inputs': { + 'Size': input_sockets['Size'], + }, }, + location=input_sockets['Center'], ) diff --git a/src/blender_maxwell/node_trees/maxwell_sim_nodes/nodes/sources/gaussian_beam_source.py b/src/blender_maxwell/node_trees/maxwell_sim_nodes/nodes/sources/gaussian_beam_source.py index cc584f1..d3c246a 100644 --- a/src/blender_maxwell/node_trees/maxwell_sim_nodes/nodes/sources/gaussian_beam_source.py +++ b/src/blender_maxwell/node_trees/maxwell_sim_nodes/nodes/sources/gaussian_beam_source.py @@ -92,7 +92,6 @@ class GaussianBeamSourceNode(base.MaxwellSimNode): } managed_obj_types: typ.ClassVar = { - 'mesh': managed_objs.ManagedBLMesh, 'modifier': managed_objs.ManagedBLModifier, } @@ -170,18 +169,14 @@ class GaussianBeamSourceNode(base.MaxwellSimNode): # Trigger prop_name='preview_active', # Loaded - managed_objs={'mesh'}, + managed_objs={'modifier'}, props={'preview_active'}, ) def on_preview_changed(self, managed_objs, props): - """Enables/disables previewing of the GeoNodes-driven mesh, regardless of whether a particular GeoNodes tree is chosen.""" - mesh = managed_objs['mesh'] - - # Push Preview State to Managed Mesh if props['preview_active']: - mesh.show_preview() + managed_objs['modifier'].show_preview() else: - mesh.hide_preview() + managed_objs['modifier'].hide_preview() @events.on_value_changed( # Trigger @@ -196,7 +191,7 @@ class GaussianBeamSourceNode(base.MaxwellSimNode): prop_name={'injection_axis', 'injection_direction'}, run_on_init=True, # Loaded - managed_objs={'mesh', 'modifier'}, + managed_objs={'modifier'}, props={'injection_axis', 'injection_direction'}, input_sockets={ 'Temporal Shape', @@ -222,7 +217,6 @@ class GaussianBeamSourceNode(base.MaxwellSimNode): # Push Input Values to GeoNodes Modifier managed_objs['modifier'].bl_modifier( - managed_objs['mesh'].bl_object(location=input_sockets['Center']), 'NODES', { 'node_group': import_geonodes(GeoNodes.SourceGaussianBeam), @@ -240,6 +234,7 @@ class GaussianBeamSourceNode(base.MaxwellSimNode): 'Waist Radius': input_sockets['Waist Radius'], }, }, + location=input_sockets['Center'], ) diff --git a/src/blender_maxwell/node_trees/maxwell_sim_nodes/nodes/sources/point_dipole_source.py b/src/blender_maxwell/node_trees/maxwell_sim_nodes/nodes/sources/point_dipole_source.py index 6ef0582..6dfe144 100644 --- a/src/blender_maxwell/node_trees/maxwell_sim_nodes/nodes/sources/point_dipole_source.py +++ b/src/blender_maxwell/node_trees/maxwell_sim_nodes/nodes/sources/point_dipole_source.py @@ -56,7 +56,6 @@ class PointDipoleSourceNode(base.MaxwellSimNode): } managed_obj_types: typ.ClassVar = { - 'mesh': managed_objs.ManagedBLMesh, 'modifier': managed_objs.ManagedBLModifier, } @@ -106,27 +105,24 @@ class PointDipoleSourceNode(base.MaxwellSimNode): # - Preview #################### @events.on_value_changed( + # Trigger prop_name='preview_active', - run_on_init=True, + # Loaded + managed_objs={'modifier'}, props={'preview_active'}, - managed_objs={'mesh'}, ) - def on_preview_changed(self, props, managed_objs) -> None: - """Enables/disables previewing of the GeoNodes-driven mesh, regardless of whether a particular GeoNodes tree is chosen.""" - mesh = managed_objs['mesh'] - - # Push Preview State to Managed Mesh + def on_preview_changed(self, managed_objs, props): if props['preview_active']: - mesh.show_preview() + managed_objs['modifier'].show_preview() else: - mesh.hide_preview() + managed_objs['modifier'].hide_preview() @events.on_value_changed( socket_name={'Center'}, prop_name='pol_axis', run_on_init=True, # Pass Data - managed_objs={'mesh', 'modifier'}, + managed_objs={'modifier'}, props={'pol_axis'}, input_sockets={'Center'}, unit_systems={'BlenderUnits': ct.UNITS_BLENDER}, @@ -135,9 +131,7 @@ class PointDipoleSourceNode(base.MaxwellSimNode): def on_inputs_changed( self, managed_objs, props, input_sockets, unit_systems ) -> None: - mesh = managed_objs['mesh'] modifier = managed_objs['modifier'] - center = input_sockets['Center'] unit_system = unit_systems['BlenderUnits'] axis = { ct.SimSpaceAxis.X: 0, @@ -147,13 +141,13 @@ class PointDipoleSourceNode(base.MaxwellSimNode): # Push Loose Input Values to GeoNodes Modifier modifier.bl_modifier( - mesh.bl_object(location=center), 'NODES', { 'node_group': import_geonodes(GeoNodes.SourcePointDipole), 'inputs': {'Axis': axis}, 'unit_system': unit_system, }, + location=input_sockets['Center'], ) diff --git a/src/blender_maxwell/node_trees/maxwell_sim_nodes/nodes/structures/primitives/__init__.py b/src/blender_maxwell/node_trees/maxwell_sim_nodes/nodes/structures/primitives/__init__.py index 22859ab..3c648d3 100644 --- a/src/blender_maxwell/node_trees/maxwell_sim_nodes/nodes/structures/primitives/__init__.py +++ b/src/blender_maxwell/node_trees/maxwell_sim_nodes/nodes/structures/primitives/__init__.py @@ -14,16 +14,15 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . -# from . import cylinder_structure -from . import box_structure, sphere_structure +from . import box_structure, cylinder_structure, sphere_structure BL_REGISTER = [ *box_structure.BL_REGISTER, - # *cylinder_structure.BL_REGISTER, + *cylinder_structure.BL_REGISTER, *sphere_structure.BL_REGISTER, ] BL_NODES = { **box_structure.BL_NODES, - # **cylinder_structure.BL_NODES, + **cylinder_structure.BL_NODES, **sphere_structure.BL_NODES, } diff --git a/src/blender_maxwell/node_trees/maxwell_sim_nodes/nodes/structures/primitives/box_structure.py b/src/blender_maxwell/node_trees/maxwell_sim_nodes/nodes/structures/primitives/box_structure.py index 8ae14f8..b728465 100644 --- a/src/blender_maxwell/node_trees/maxwell_sim_nodes/nodes/structures/primitives/box_structure.py +++ b/src/blender_maxwell/node_trees/maxwell_sim_nodes/nodes/structures/primitives/box_structure.py @@ -43,15 +43,11 @@ class BoxStructureNode(base.MaxwellSimNode): 'Medium': sockets.MaxwellMediumSocketDef(), 'Center': sockets.ExprSocketDef( size=spux.NumberSize1D.Vec3, - mathtype=spux.MathType.Real, - physical_type=spux.PhysicalType.Length, default_unit=spu.micrometer, default_value=sp.Matrix([0, 0, 0]), ), 'Size': sockets.ExprSocketDef( size=spux.NumberSize1D.Vec3, - mathtype=spux.MathType.Real, - physical_type=spux.PhysicalType.Length, default_unit=spu.nanometer, default_value=sp.Matrix([500, 500, 500]), abs_min=0.001, @@ -62,7 +58,6 @@ class BoxStructureNode(base.MaxwellSimNode): } managed_obj_types: typ.ClassVar = { - 'mesh': managed_objs.ManagedBLMesh, 'modifier': managed_objs.ManagedBLModifier, } @@ -91,25 +86,25 @@ class BoxStructureNode(base.MaxwellSimNode): # - Preview #################### @events.on_value_changed( + # Trigger prop_name='preview_active', - run_on_init=True, + # Loaded + managed_objs={'modifier'}, props={'preview_active'}, - managed_objs={'mesh'}, ) - def on_preview_changed(self, props, managed_objs) -> None: - mesh = managed_objs['mesh'] - - # Push Preview State to Managed Mesh + def on_preview_changed(self, managed_objs, props): if props['preview_active']: - mesh.show_preview() + managed_objs['modifier'].show_preview() else: - mesh.hide_preview() + managed_objs['modifier'].hide_preview() @events.on_value_changed( + # Trigger socket_name={'Center', 'Size'}, run_on_init=True, + # Loaded input_sockets={'Center', 'Size'}, - managed_objs={'mesh', 'modifier'}, + managed_objs={'modifier'}, unit_systems={'BlenderUnits': ct.UNITS_BLENDER}, scale_input_sockets={ 'Center': 'BlenderUnits', @@ -121,21 +116,17 @@ class BoxStructureNode(base.MaxwellSimNode): input_sockets, unit_systems, ): - mesh = managed_objs['mesh'] - modifier = managed_objs['modifier'] - center = input_sockets['Center'] - size = input_sockets['Size'] - unit_system = unit_systems['BlenderUnits'] - # Push Loose Input Values to GeoNodes Modifier - modifier.bl_modifier( - mesh.bl_object(location=center), + managed_objs['modifier'].bl_modifier( 'NODES', { 'node_group': import_geonodes(GeoNodes.StructurePrimitiveBox), - 'inputs': {'Size': size}, - 'unit_system': unit_system, + 'unit_system': unit_systems['BlenderUnits'], + 'inputs': { + 'Size': input_sockets['Size'], + }, }, + location=input_sockets['Center'], ) diff --git a/src/blender_maxwell/node_trees/maxwell_sim_nodes/nodes/structures/primitives/cylinder_structure.py b/src/blender_maxwell/node_trees/maxwell_sim_nodes/nodes/structures/primitives/cylinder_structure.py index 659831f..a89ef06 100644 --- a/src/blender_maxwell/node_trees/maxwell_sim_nodes/nodes/structures/primitives/cylinder_structure.py +++ b/src/blender_maxwell/node_trees/maxwell_sim_nodes/nodes/structures/primitives/cylinder_structure.py @@ -14,62 +14,127 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . +import typing as typ + +import sympy as sp import sympy.physics.units as spu import tidy3d as td -from .... import contracts, sockets +from blender_maxwell.assets.geonodes import GeoNodes, import_geonodes +from blender_maxwell.utils import extra_sympy_units as spux +from blender_maxwell.utils import logger + +from .... import contracts as ct +from .... import managed_objs, sockets from ... import base, events +log = logger.get(__name__) -class CylinderStructureNode(base.MaxwellSimTreeNode): - node_type = contracts.NodeType.CylinderStructure + +class CylinderStructureNode(base.MaxwellSimNode): + node_type = ct.NodeType.CylinderStructure bl_label = 'Cylinder Structure' - # bl_icon = ... + use_sim_node_name = True #################### # - Sockets #################### - input_sockets = { - 'medium': sockets.MaxwellMediumSocketDef( - label='Medium', + input_sockets: typ.ClassVar = { + 'Medium': sockets.MaxwellMediumSocketDef(), + 'Center': sockets.ExprSocketDef( + size=spux.NumberSize1D.Vec3, + default_unit=spu.micrometer, + default_value=sp.Matrix([0, 0, 0]), ), - 'center': sockets.PhysicalPoint3DSocketDef( - label='Center', + 'Radius': sockets.ExprSocketDef( + default_unit=spu.nanometer, + default_value=150, ), - 'radius': sockets.PhysicalLengthSocketDef( - label='Radius', - ), - 'height': sockets.PhysicalLengthSocketDef( - label='Height', + 'Height': sockets.ExprSocketDef( + default_unit=spu.nanometer, + default_value=500, ), } - output_sockets = { - 'structure': sockets.MaxwellStructureSocketDef( - label='Structure', - ), + output_sockets: typ.ClassVar = { + 'Structure': sockets.MaxwellStructureSocketDef(), + } + + managed_obj_types: typ.ClassVar = { + 'modifier': managed_objs.ManagedBLModifier, } #################### # - Output Socket Computation #################### - @events.computes_output_socket('structure') - def compute_simulation(self: contracts.NodeTypeProtocol) -> td.Box: - medium = self.compute_input('medium') - _center = self.compute_input('center') - _radius = self.compute_input('radius') - _height = self.compute_input('height') - - center = tuple(spu.convert_to(_center, spu.um) / spu.um) - radius = spu.convert_to(_radius, spu.um) / spu.um - height = spu.convert_to(_height, spu.um) / spu.um - + @events.computes_output_socket( + 'Structure', + input_sockets={'Center', 'Radius', 'Medium', 'Height'}, + unit_systems={'Tidy3DUnits': ct.UNITS_TIDY3D}, + scale_input_sockets={ + 'Center': 'Tidy3DUnits', + 'Radius': 'Tidy3DUnits', + 'Height': 'Tidy3DUnits', + }, + ) + def compute_structure(self, input_sockets, unit_systems) -> td.Box: return td.Structure( geometry=td.Cylinder( - radius=radius, - center=center, - length=height, + radius=input_sockets['Radius'], + center=input_sockets['Center'], + length=input_sockets['Height'], ), - medium=medium, + medium=input_sockets['Medium'], + ) + + #################### + # - Preview + #################### + @events.on_value_changed( + # Trigger + prop_name='preview_active', + # Loaded + managed_objs={'modifier'}, + props={'preview_active'}, + ) + def on_preview_changed(self, managed_objs, props): + if props['preview_active']: + managed_objs['modifier'].show_preview() + else: + managed_objs['modifier'].hide_preview() + + @events.on_value_changed( + # Trigger + socket_name={'Center', 'Radius', 'Medium', 'Height'}, + run_on_init=True, + # Loaded + input_sockets={'Center', 'Radius', 'Medium', 'Height'}, + managed_objs={'modifier'}, + unit_systems={'BlenderUnits': ct.UNITS_BLENDER}, + scale_input_sockets={ + 'Center': 'BlenderUnits', + }, + ) + def on_inputs_changed( + self, + managed_objs, + input_sockets, + unit_systems, + ): + modifier = managed_objs['modifier'] + unit_system = unit_systems['BlenderUnits'] + + # Push Loose Input Values to GeoNodes Modifier + modifier.bl_modifier( + 'NODES', + { + 'node_group': import_geonodes(GeoNodes.StructurePrimitiveCylinder), + 'inputs': { + 'Radius': input_sockets['Radius'], + 'Height': input_sockets['Height'], + }, + 'unit_system': unit_system, + }, + location=input_sockets['Center'], ) @@ -80,7 +145,5 @@ BL_REGISTER = [ CylinderStructureNode, ] BL_NODES = { - contracts.NodeType.CylinderStructure: ( - contracts.NodeCategory.MAXWELLSIM_STRUCTURES_PRIMITIVES - ) + ct.NodeType.CylinderStructure: (ct.NodeCategory.MAXWELLSIM_STRUCTURES_PRIMITIVES) } diff --git a/src/blender_maxwell/node_trees/maxwell_sim_nodes/nodes/structures/primitives/sphere_structure.py b/src/blender_maxwell/node_trees/maxwell_sim_nodes/nodes/structures/primitives/sphere_structure.py index 2b18598..1b4bca3 100644 --- a/src/blender_maxwell/node_trees/maxwell_sim_nodes/nodes/structures/primitives/sphere_structure.py +++ b/src/blender_maxwell/node_trees/maxwell_sim_nodes/nodes/structures/primitives/sphere_structure.py @@ -56,7 +56,6 @@ class SphereStructureNode(base.MaxwellSimNode): } managed_obj_types: typ.ClassVar = { - 'mesh': managed_objs.ManagedBLMesh, 'modifier': managed_objs.ManagedBLModifier, } @@ -85,25 +84,25 @@ class SphereStructureNode(base.MaxwellSimNode): # - Preview #################### @events.on_value_changed( + # Trigger prop_name='preview_active', - run_on_init=True, + # Loaded + managed_objs={'modifier'}, props={'preview_active'}, - managed_objs={'mesh'}, ) - def on_preview_changed(self, props, managed_objs) -> None: - mesh = managed_objs['mesh'] - - # Push Preview State to Managed Mesh + def on_preview_changed(self, managed_objs, props): if props['preview_active']: - mesh.show_preview() + managed_objs['modifier'].show_preview() else: - mesh.hide_preview() + managed_objs['modifier'].hide_preview() @events.on_value_changed( + # Trigger socket_name={'Center', 'Radius'}, run_on_init=True, + # Loaded input_sockets={'Center', 'Radius'}, - managed_objs={'mesh', 'modifier'}, + managed_objs={'modifier'}, unit_systems={'BlenderUnits': ct.UNITS_BLENDER}, scale_input_sockets={ 'Center': 'BlenderUnits', @@ -115,21 +114,20 @@ class SphereStructureNode(base.MaxwellSimNode): input_sockets, unit_systems, ): - mesh = managed_objs['mesh'] modifier = managed_objs['modifier'] - center = input_sockets['Center'] - radius = input_sockets['Radius'] unit_system = unit_systems['BlenderUnits'] # Push Loose Input Values to GeoNodes Modifier modifier.bl_modifier( - mesh.bl_object(location=center), 'NODES', { 'node_group': import_geonodes(GeoNodes.StructurePrimitiveSphere), - 'inputs': {'Radius': radius}, + 'inputs': { + 'Radius': input_sockets['Radius'], + }, 'unit_system': unit_system, }, + location=input_sockets['Center'], ) diff --git a/src/blender_maxwell/node_trees/maxwell_sim_nodes/sockets/maxwell/sim_grid.py b/src/blender_maxwell/node_trees/maxwell_sim_nodes/sockets/maxwell/sim_grid.py index b35bedc..3267fa6 100644 --- a/src/blender_maxwell/node_trees/maxwell_sim_nodes/sockets/maxwell/sim_grid.py +++ b/src/blender_maxwell/node_trees/maxwell_sim_nodes/sockets/maxwell/sim_grid.py @@ -17,9 +17,13 @@ import bpy import tidy3d as td +from blender_maxwell.utils import bl_cache, logger + from ... import contracts as ct from .. import base +log = logger.get(__name__) + class MaxwellSimGridBLSocket(base.MaxwellSimSocket): socket_type = ct.SocketType.MaxwellSimGrid @@ -28,17 +32,7 @@ class MaxwellSimGridBLSocket(base.MaxwellSimSocket): #################### # - Properties #################### - min_steps_per_wl: bpy.props.FloatProperty( - name='Minimum Steps per Wavelength', - description='How many grid steps to ensure per wavelength', - default=10.0, - min=0.01, - # step=10, - precision=2, - update=( - lambda self, context: self.on_prop_changed('min_steps_per_wl', context) - ), - ) + min_steps_per_wl: float = bl_cache.BLField(10.0, abs_min=0.01, float_prec=2) #################### # - Socket UI @@ -50,7 +44,7 @@ class MaxwellSimGridBLSocket(base.MaxwellSimSocket): col.label(text='min. stp/λ') col = split.column(align=True) - col.prop(self, 'min_steps_per_wl', text='') + col.prop(self, self.blfields['min_steps_per_wl'], text='') #################### # - Computation of Default Value