Compare commits

..

No commits in common. "7344913c0ea92374de4bbad64bbf2e110e5ffd0b" and "de8d64b5b3951860f8a62f8a6282ddfa19922fdb" have entirely different histories.

32 changed files with 232 additions and 802 deletions

View File

@ -79,7 +79,6 @@ class TreeType(BlenderTypeEnum):
class SocketType(BlenderTypeEnum):
# Base
Any = enum.auto()
Bool = enum.auto()
Text = enum.auto()
FilePath = enum.auto()
@ -105,19 +104,11 @@ class SocketType(BlenderTypeEnum):
PhysicalArea = enum.auto()
PhysicalVolume = enum.auto()
PhysicalPoint2D = enum.auto()
PhysicalPoint3D = enum.auto()
PhysicalSize2D = enum.auto()
PhysicalSize3D = enum.auto()
PhysicalMass = enum.auto()
PhysicalSpeed = enum.auto()
PhysicalAccelScalar = enum.auto()
PhysicalForceScalar = enum.auto()
PhysicalAccel3DVector = enum.auto()
PhysicalForce3DVector = enum.auto()
PhysicalAccel = enum.auto()
PhysicalForce = enum.auto()
PhysicalPol = enum.auto()
@ -229,74 +220,8 @@ SocketType_to_units = {
},
},
SocketType.PhysicalPoint2D: {
"default": "UM",
"values": {
"PM": spu.picometer,
"A": spu.angstrom,
"NM": spu.nanometer,
"UM": spu.micrometer,
"MM": spu.millimeter,
"CM": spu.centimeter,
"M": spu.meter,
"INCH": spu.inch,
"FOOT": spu.foot,
"YARD": spu.yard,
"MILE": spu.mile,
},
},
SocketType.PhysicalPoint3D: {
"default": "UM",
"values": {
"PM": spu.picometer,
"A": spu.angstrom,
"NM": spu.nanometer,
"UM": spu.micrometer,
"MM": spu.millimeter,
"CM": spu.centimeter,
"M": spu.meter,
"INCH": spu.inch,
"FOOT": spu.foot,
"YARD": spu.yard,
"MILE": spu.mile,
},
},
SocketType.PhysicalSize2D: {
"default": "UM",
"values": {
"PM": spu.picometer,
"A": spu.angstrom,
"NM": spu.nanometer,
"UM": spu.micrometer,
"MM": spu.millimeter,
"CM": spu.centimeter,
"M": spu.meter,
"INCH": spu.inch,
"FOOT": spu.foot,
"YARD": spu.yard,
"MILE": spu.mile,
},
},
SocketType.PhysicalSize3D: {
"default": "UM",
"values": {
"PM": spu.picometer,
"A": spu.angstrom,
"NM": spu.nanometer,
"UM": spu.micrometer,
"MM": spu.millimeter,
"CM": spu.centimeter,
"M": spu.meter,
"INCH": spu.inch,
"FOOT": spu.foot,
"YARD": spu.yard,
"MILE": spu.mile,
},
},
SocketType.PhysicalMass: {
"default": "UG",
"default": "UM",
"values": {
"E_REST": spu.electron_rest_mass,
"DAL": spu.dalton,
@ -309,7 +234,7 @@ SocketType_to_units = {
},
SocketType.PhysicalSpeed: {
"default": "UM_S",
"default": "UM",
"values": {
"PM_S": spu.picometer / spu.second,
"NM_S": spu.nanometer / spu.second,
@ -322,8 +247,8 @@ SocketType_to_units = {
"MI_H": spu.mile / spu.hour,
},
},
SocketType.PhysicalAccelScalar: {
"default": "UM_S_SQ",
SocketType.PhysicalAccel: {
"default": "UM",
"values": {
"PM_S_SQ": spu.picometer / spu.second**2,
"NM_S_SQ": spu.nanometer / spu.second**2,
@ -334,29 +259,7 @@ SocketType_to_units = {
"FT_S_SQ": spu.feet / spu.second**2,
},
},
SocketType.PhysicalForceScalar: {
"default": "UNEWT",
"values": {
"KG_M_S_SQ": spu.kg * spu.m/spu.second**2,
"NNEWT": spuex.nanonewton,
"UNEWT": spuex.micronewton,
"MNEWT": spuex.millinewton,
"NEWT": spu.newton,
},
},
SocketType.PhysicalAccel3DVector: {
"default": "UM_S_SQ",
"values": {
"PM_S_SQ": spu.picometer / spu.second**2,
"NM_S_SQ": spu.nanometer / spu.second**2,
"UM_S_SQ": spu.micrometer / spu.second**2,
"MM_S_SQ": spu.millimeter / spu.second**2,
"M_S_SQ": spu.meter / spu.second**2,
"KM_S_SQ": spu.kilometer / spu.second**2,
"FT_S_SQ": spu.feet / spu.second**2,
},
},
SocketType.PhysicalForce3DVector: {
SocketType.PhysicalForce: {
"default": "UNEWT",
"values": {
"KG_M_S_SQ": spu.kg * spu.m/spu.second**2,
@ -391,7 +294,6 @@ SocketType_to_units = {
SocketType_to_color = {
# Basic
SocketType.Any: (0.8, 0.8, 0.8, 1.0), # Light Grey
SocketType.Bool: (0.7, 0.7, 0.7, 1.0), # Medium Light Grey
SocketType.Text: (0.7, 0.7, 0.7, 1.0), # Medium Light Grey
SocketType.FilePath: (0.6, 0.6, 0.6, 1.0), # Medium Grey
@ -413,16 +315,10 @@ SocketType_to_color = {
SocketType.PhysicalLength: (0.8, 0.4, 0.4, 1.0), # Medium Red
SocketType.PhysicalArea: (0.7, 0.35, 0.35, 1.0), # Medium Dark Red
SocketType.PhysicalVolume: (0.6, 0.3, 0.3, 1.0), # Dark Red
SocketType.PhysicalPoint2D: (0.7, 0.35, 0.35, 1.0), # Medium Dark Red
SocketType.PhysicalPoint3D: (0.6, 0.3, 0.3, 1.0), # Dark Red
SocketType.PhysicalSize2D: (0.7, 0.35, 0.35, 1.0), # Medium Dark Red
SocketType.PhysicalSize3D: (0.6, 0.3, 0.3, 1.0), # Dark Red
SocketType.PhysicalMass: (0.9, 0.6, 0.4, 1.0), # Light Orange
SocketType.PhysicalSpeed: (0.8, 0.55, 0.35, 1.0), # Medium Light Orange
SocketType.PhysicalAccelScalar: (0.7, 0.5, 0.3, 1.0), # Medium Orange
SocketType.PhysicalForceScalar: (0.6, 0.45, 0.25, 1.0), # Medium Dark Orange
SocketType.PhysicalAccel3DVector: (0.7, 0.5, 0.3, 1.0), # Medium Orange
SocketType.PhysicalForce3DVector: (0.6, 0.45, 0.25, 1.0), # Medium Dark Orange
SocketType.PhysicalAccel: (0.7, 0.5, 0.3, 1.0), # Medium Orange
SocketType.PhysicalForce: (0.6, 0.45, 0.25, 1.0), # Medium Dark Orange
SocketType.PhysicalPol: (0.5, 0.4, 0.2, 1.0), # Dark Orange
SocketType.PhysicalFreq: (1.0, 0.7, 0.5, 1.0), # Light Peach
SocketType.PhysicalSpecPowerDist: (0.9, 0.65, 0.45, 1.0), # Medium Light Peach

View File

@ -371,24 +371,13 @@ class MaxwellSimTreeNode(bpy.types.Node):
Blender's own node socket object.
"""
if input_socket_name in self.input_sockets:
# Check Nicely that it Exists
# (Guard) Socket Exists
if input_socket_name not in self.input_sockets:
msg = f"Input socket with name {input_socket_name} does not exist"
raise ValueError(msg)
return self.inputs[self.input_sockets[input_socket_name].label]
elif hasattr(self, "input_socket_sets"):
# You're on your own, chump
return self.inputs[next(
socket_def.label
for socket_set, socket_dict in self.input_socket_sets.items()
for socket_name, socket_def in socket_dict.items()
if socket_name == input_socket_name
)]
def g_output_bl_socket(
self,
output_socket_name: contracts.SocketName,
@ -403,8 +392,6 @@ class MaxwellSimTreeNode(bpy.types.Node):
Blender's own node socket object.
"""
if output_socket_name in self.output_sockets:
# (Guard) Socket Exists
if output_socket_name not in self.output_sockets:
msg = f"Input socket with name {output_socket_name} does not exist"
@ -412,26 +399,10 @@ class MaxwellSimTreeNode(bpy.types.Node):
return self.outputs[self.output_sockets[output_socket_name].label]
elif hasattr(self, "input_socket_sets"):
return self.outputs[next(
socket_def.label
for socket_set, socket_dict in self.input_socket_sets.items()
for socket_name, socket_def in socket_dict.items()
if socket_name == output_socket_name
)]
def g_output_socket_name(
self,
output_bl_socket_name: contracts.BLSocketName,
) -> contracts.SocketName:
if hasattr(self, "output_socket_sets"):
return next(
socket_name
for socket_set, socket_dict in self.output_socket_sets.items()
for socket_name, socket_def in socket_dict.items()
if socket_def.label == output_bl_socket_name
)
else:
return next(
output_socket_name
for output_socket_name in self.output_sockets.keys()

View File

@ -11,21 +11,16 @@ class NumberConstantNode(base.MaxwellSimTreeNode):
bl_label = "Numerical Constant"
#bl_icon = constants.ICON_SIM_INPUT
input_sockets = {}
input_socket_sets = {
"real": {
"value": sockets.RealNumberSocketDef(
label="Real",
),
},
"complex": {
input_sockets = {
"value": sockets.ComplexNumberSocketDef(
label="Complex",
),
},
), ## TODO: Dynamic number socket!
}
output_sockets = {
"value": sockets.ComplexNumberSocketDef(
label="Complex",
), ## TODO: Dynamic number socket!
}
output_sockets = {}
output_socket_sets = input_socket_sets
####################
# - Callbacks

View File

@ -1,75 +1,5 @@
import bpy
import sympy as sp
from .... import contracts
from .... import sockets
from ... import base
class PhysicalConstantNode(base.MaxwellSimTreeNode):
node_type = contracts.NodeType.PhysicalConstant
bl_label = "Physical Constant"
#bl_icon = constants.ICON_SIM_INPUT
input_sockets = {}
input_socket_sets = {
"time": {
"value": sockets.PhysicalTimeSocketDef(
label="Time",
),
},
"angle": {
"value": sockets.PhysicalAngleSocketDef(
label="Angle",
),
},
"length": {
"value": sockets.PhysicalLengthSocketDef(
label="Length",
),
},
"area": {
"value": sockets.PhysicalAreaSocketDef(
label="Area",
),
},
"volume": {
"value": sockets.PhysicalVolumeSocketDef(
label="Volume",
),
},
"point_3d": {
"value": sockets.PhysicalPoint3DSocketDef(
label="3D Point",
),
},
"size_3d": {
"value": sockets.PhysicalSize3DSocketDef(
label="3D Size",
),
},
## I got bored so maybe the rest later
}
output_sockets = {}
output_socket_sets = input_socket_sets
####################
# - Callbacks
####################
@base.computes_output_socket("value")
def compute_value(self: contracts.NodeTypeProtocol) -> sp.Expr:
return self.compute_input("value")
####################
# - Blender Registration
####################
BL_REGISTER = [
PhysicalConstantNode,
]
BL_NODES = {
contracts.NodeType.PhysicalConstant: (
contracts.NodeCategory.MAXWELLSIM_INPUTS_CONSTANTS
)
}
BL_REGISTER = []
BL_NODES = {}

View File

@ -19,7 +19,6 @@ class KitchenSinkNode(base.MaxwellSimTreeNode):
input_socket_sets = {
"basic": {
"basic_any": sockets.AnySocketDef(label="Any"),
"basic_bool": sockets.BoolSocketDef(label="Bool"),
"basic_filepath": sockets.FilePathSocketDef(label="FilePath"),
"basic_text": sockets.TextSocketDef(label="Text"),
},
@ -37,20 +36,14 @@ class KitchenSinkNode(base.MaxwellSimTreeNode):
},
"physical": {
"physical_time": sockets.PhysicalTimeSocketDef(label="PhysicalTime"),
#"physical_point_2d": sockets.PhysicalPoint2DSocketDef(label="PhysicalPoint2D"),
"physical_angle": sockets.PhysicalAngleSocketDef(label="PhysicalAngle"),
"physical_length": sockets.PhysicalLengthSocketDef(label="PhysicalLength"),
"physical_area": sockets.PhysicalAreaSocketDef(label="PhysicalArea"),
"physical_volume": sockets.PhysicalVolumeSocketDef(label="PhysicalVolume"),
"physical_point_3d": sockets.PhysicalPoint3DSocketDef(label="PhysicalPoint3D"),
#"physical_size_2d": sockets.PhysicalSize2DSocketDef(label="PhysicalSize2D"),
"physical_size_3d": sockets.PhysicalSize3DSocketDef(label="PhysicalSize3D"),
"physical_mass": sockets.PhysicalMassSocketDef(label="PhysicalMass"),
"physical_speed": sockets.PhysicalSpeedSocketDef(label="PhysicalSpeed"),
"physical_accel_scalar": sockets.PhysicalAccelScalarSocketDef(label="PhysicalAccelScalar"),
"physical_force_scalar": sockets.PhysicalForceScalarSocketDef(label="PhysicalForceScalar"),
#"physical_accel_3dvector": sockets.PhysicalAccel3DVectorSocketDef(label="PhysicalAccel3DVector"),
#"physical_force_3dvector": sockets.PhysicalForce3DVectorSocketDef(label="PhysicalForce3DVector"),
"physical_accel": sockets.PhysicalAccelSocketDef(label="PhysicalAccel"),
"physical_force": sockets.PhysicalForceSocketDef(label="PhysicalForce"),
"physical_pol": sockets.PhysicalPolSocketDef(label="PhysicalPol"),
"physical_freq": sockets.PhysicalFreqSocketDef(label="PhysicalFreq"),
"physical_spec_power_dist": sockets.PhysicalSpecPowerDistSocketDef(label="PhysicalSpecPowerDist"),
@ -69,21 +62,18 @@ class KitchenSinkNode(base.MaxwellSimTreeNode):
"maxwell_temporal_shape": sockets.MaxwellTemporalShapeSocketDef(label="MaxwellTemporalShape"),
"maxwell_medium": sockets.MaxwellMediumSocketDef(label="MaxwellMedium"),
#"maxwell_medium_nonlinearity": sockets.MaxwellMediumNonLinearitySocketDef(label="MaxwellMediumNonLinearity"),
"maxwell_structure": sockets.MaxwellStructureSocketDef(label="MaxwellMedium"),
"maxwell_structure": sockets.MaxwellMediumSocketDef(label="MaxwellMedium"),
"maxwell_bound_box": sockets.MaxwellBoundBoxSocketDef(label="MaxwellBoundBox"),
"maxwell_bound_face": sockets.MaxwellBoundFaceSocketDef(label="MaxwellBoundFace"),
"maxwell_monitor": sockets.MaxwellMonitorSocketDef(label="MaxwellMonitor"),
"maxwell_fdtd_sim": sockets.MaxwellFDTDSimSocketDef(label="MaxwellFDTDSim"),
"maxwell_sim_grid": sockets.MaxwellSimGridSocketDef(label="MaxwellSimGrid"),
"maxwell_sim_grid_axis": sockets.MaxwellSimGridAxisSocketDef(label="MaxwellSimGridAxis"),
"maxwell_monitor": sockets.MaxwellFDTDSimSocketDef(label="MaxwellFDTDSim"),
"maxwell_monitor": sockets.MaxwellSimGridSocketDef(label="MaxwellSimGrid"),
"maxwell_monitor": sockets.MaxwellSimGridAxisSocketDef(label="MaxwellSimGridAxis"),
},
}
output_sockets = {}
output_socket_sets = {
k + " Output": v
for k, v in input_socket_sets.items()
}
output_socket_sets = input_socket_sets

View File

@ -16,11 +16,21 @@ class FDTDSimNode(base.MaxwellSimTreeNode):
# - Sockets
####################
input_sockets = {
"run_time": sockets.PhysicalTimeSocketDef(
"run_time": sockets.RealNumberSocketDef(
label="Run Time",
default_value=1.0,
),
"size": sockets.PhysicalSize3DSocketDef(
label="Size",
"size_x": sockets.RealNumberSocketDef(
label="Size X",
default_value=1.0,
),
"size_y": sockets.RealNumberSocketDef(
label="Size Y",
default_value=1.0,
),
"size_z": sockets.RealNumberSocketDef(
label="Size Z",
default_value=1.0,
),
"ambient_medium": sockets.MaxwellMediumSocketDef(
label="Ambient Medium",
@ -46,15 +56,17 @@ class FDTDSimNode(base.MaxwellSimTreeNode):
####################
@base.computes_output_socket("fdtd_sim")
def compute_simulation(self: contracts.NodeTypeProtocol) -> td.Simulation:
_run_time = self.compute_input("run_time")
_size = self.compute_input("size")
run_time = self.compute_input("run_time")
ambient_medium = self.compute_input("ambient_medium")
structures = [self.compute_input("structure")]
sources = [self.compute_input("source")]
bound = self.compute_input("bound")
run_time = spu.convert_to(_run_time, spu.second) / spu.second
size = tuple(spu.convert_to(_size, spu.um) / spu.um)
size = (
self.compute_input("size_x"),
self.compute_input("size_y"),
self.compute_input("size_z"),
)
return td.Simulation(
size=size,

View File

@ -16,14 +16,17 @@ class PointDipoleSourceNode(base.MaxwellSimTreeNode):
# - Sockets
####################
input_sockets = {
#"polarization": sockets.PhysicalPolSocketDef(
# label="Polarization",
#), ## TODO: Exactly how to go about this...
"temporal_shape": sockets.MaxwellTemporalShapeSocketDef(
label="Temporal Shape",
"center_x": sockets.RealNumberSocketDef(
label="Center X",
default_value=0.0,
),
"center": sockets.PhysicalPoint3DSocketDef(
label="Center",
"center_y": sockets.RealNumberSocketDef(
label="Center Y",
default_value=0.0,
),
"center_z": sockets.RealNumberSocketDef(
label="Center Z",
default_value=0.0,
),
}
output_sockets = {
@ -37,19 +40,19 @@ class PointDipoleSourceNode(base.MaxwellSimTreeNode):
####################
@base.computes_output_socket("source")
def compute_source(self: contracts.NodeTypeProtocol) -> td.PointDipole:
temporal_shape = self.compute_input("temporal_shape")
center = (
self.compute_input("center_x"),
self.compute_input("center_y"),
self.compute_input("center_z"),
)
_center = self.compute_input("center")
center = tuple(spu.convert_to(_center, spu.um) / spu.um)
cheating_pol = "Ex"
## TODO: Fix
cheating_pulse = td.GaussianPulse(freq0=200e12, fwidth=20e12)
return td.PointDipole(
center=center,
source_time=temporal_shape,
source_time=cheating_pulse,
interpolate=True,
polarization=cheating_pol,
polarization="Ex",
)

View File

@ -1,82 +1,6 @@
import tidy3d as td
import sympy as sp
import sympy.physics.units as spu
from .... import contracts
from .... import sockets
from ... import base
class GaussianPulseTemporalShapeNode(base.MaxwellSimTreeNode):
node_type = contracts.NodeType.GaussianPulseTemporalShape
bl_label = "Gaussian Pulse Temporal Shape"
#bl_icon = ...
####################
# - Sockets
####################
input_sockets = {
#"amplitude": sockets.RealNumberSocketDef(
# label="Temporal Shape",
#), ## Should have a unit of some kind...
"phase": sockets.PhysicalAngleSocketDef(
label="Phase",
),
"freq_center": sockets.PhysicalFreqSocketDef(
label="Freq Center",
),
"freq_std": sockets.PhysicalFreqSocketDef(
label="Freq STD",
),
"time_delay_rel_ang_freq": sockets.RealNumberSocketDef(
label="Time Delay rel. Ang. Freq",
),
"remove_dc_component": sockets.BoolSocketDef(
label="Remove DC",
default_value=True,
),
}
output_sockets = {
"temporal_shape": sockets.MaxwellTemporalShapeSocketDef(
label="Temporal Shape",
),
}
####################
# - Output Socket Computation
####################
@base.computes_output_socket("temporal_shape")
def compute_source(self: contracts.NodeTypeProtocol) -> td.PointDipole:
_phase = self.compute_input("phase")
_freq_center = self.compute_input("freq_center")
_freq_std = self.compute_input("freq_std")
time_delay_rel_ang_freq = self.compute_input("time_delay_rel_ang_freq")
remove_dc_component = self.compute_input("remove_dc_component")
cheating_amplitude = 1.0
phase = spu.convert_to(_phase, spu.radian) / spu.radian
freq_center = spu.convert_to(_freq_center, spu.hertz) / spu.hertz
freq_std = spu.convert_to(_freq_std, spu.hertz) / spu.hertz
return td.GaussianPulse(
amplitude=cheating_amplitude,
phase=phase,
freq0=freq_center,
fwidth=freq_std,
offset=time_delay_rel_ang_freq,
remove_dc_component=remove_dc_component,
)
####################
# - Blender Registration
####################
BL_REGISTER = [
GaussianPulseTemporalShapeNode,
]
BL_NODES = {
contracts.NodeType.GaussianPulseTemporalShape: (
contracts.NodeCategory.MAXWELLSIM_SOURCES_TEMPORALSHAPES
)
}
BL_REGISTER = []
BL_NODES = {}

View File

@ -18,11 +18,29 @@ class BoxStructureNode(base.MaxwellSimTreeNode):
"medium": sockets.MaxwellMediumSocketDef(
label="Medium",
),
"center": sockets.PhysicalPoint3DSocketDef(
label="Center",
"center_x": sockets.RealNumberSocketDef(
label="Center X",
default_value=0.0,
),
"size": sockets.PhysicalSize3DSocketDef(
label="Size",
"center_y": sockets.RealNumberSocketDef(
label="Center Y",
default_value=0.0,
),
"center_z": sockets.RealNumberSocketDef(
label="Center Z",
default_value=0.0,
),
"size_x": sockets.RealNumberSocketDef(
label="Size X",
default_value=1.0,
),
"size_y": sockets.RealNumberSocketDef(
label="Size Y",
default_value=1.0,
),
"size_z": sockets.RealNumberSocketDef(
label="Size Z",
default_value=1.0,
),
}
output_sockets = {
@ -37,11 +55,16 @@ class BoxStructureNode(base.MaxwellSimTreeNode):
@base.computes_output_socket("structure")
def compute_simulation(self: contracts.NodeTypeProtocol) -> td.Box:
medium = self.compute_input("medium")
_center = self.compute_input("center")
_size = self.compute_input("size")
center = tuple(spu.convert_to(_center, spu.um) / spu.um)
size = tuple(spu.convert_to(_size, spu.um) / spu.um)
center = (
self.compute_input("center_x"),
self.compute_input("center_y"),
self.compute_input("center_z"),
)
size = (
self.compute_input("size_x"),
self.compute_input("size_y"),
self.compute_input("size_z"),
)
return td.Structure(
geometry=td.Box(

View File

@ -1,6 +1,5 @@
from . import basic
AnySocketDef = basic.AnySocketDef
BoolSocketDef = basic.BoolSocketDef
TextSocketDef = basic.TextSocketDef
FilePathSocketDef = basic.FilePathSocketDef
@ -22,12 +21,10 @@ PhysicalAngleSocketDef = physical.PhysicalAngleSocketDef
PhysicalLengthSocketDef = physical.PhysicalLengthSocketDef
PhysicalAreaSocketDef = physical.PhysicalAreaSocketDef
PhysicalVolumeSocketDef = physical.PhysicalVolumeSocketDef
PhysicalPoint3DSocketDef = physical.PhysicalPoint3DSocketDef
PhysicalSize3DSocketDef = physical.PhysicalSize3DSocketDef
PhysicalMassSocketDef = physical.PhysicalMassSocketDef
PhysicalSpeedSocketDef = physical.PhysicalSpeedSocketDef
PhysicalAccelScalarSocketDef = physical.PhysicalAccelScalarSocketDef
PhysicalForceScalarSocketDef = physical.PhysicalForceScalarSocketDef
PhysicalAccelSocketDef = physical.PhysicalAccelSocketDef
PhysicalForceSocketDef = physical.PhysicalForceSocketDef
PhysicalPolSocketDef = physical.PhysicalPolSocketDef
PhysicalFreqSocketDef = physical.PhysicalFreqSocketDef
PhysicalSpecRelPermDistSocketDef = physical.PhysicalSpecRelPermDistSocketDef

View File

@ -127,12 +127,6 @@ class BLSocket(bpy.types.NodeSocket):
the value with the new unit.
"""
if hasattr(self, "raw_value") and hasattr(self, "unit"):
if hasattr(self.raw_value, "__getitem__"):
self.raw_value = tuple(spu.convert_to(
sp.Matrix(tuple(self.raw_value)) * self._unit_previous,
self.unit,
) / self.unit)
else:
self.raw_value = spu.convert_to(
self.raw_value * self._unit_previous,
self.unit,
@ -193,9 +187,6 @@ class BLSocket(bpy.types.NodeSocket):
label_col_row = col.row(align=True)
if hasattr(self, "draw_label_row"):
self.draw_label_row(label_col_row, text)
elif hasattr(self, "raw_unit"):
label_col_row.label(text=text)
label_col_row.prop(self, "raw_unit", text="")
else:
label_col_row.label(text=text)
@ -217,9 +208,6 @@ class BLSocket(bpy.types.NodeSocket):
# Row(s): Value
if hasattr(self, "draw_value"):
self.draw_value(col)
elif hasattr(self, "raw_value"):
#col_row = col.row(align=True)
col.prop(self, "raw_value", text="")
def draw_output(
self,

View File

@ -1,9 +1,6 @@
from . import any_socket
AnySocketDef = any_socket.AnySocketDef
from . import bool_socket
BoolSocketDef = bool_socket.BoolSocketDef
from . import text_socket
TextSocketDef = text_socket.TextSocketDef
@ -13,7 +10,6 @@ FilePathSocketDef = file_path_socket.FilePathSocketDef
BL_REGISTER = [
*any_socket.BL_REGISTER,
*bool_socket.BL_REGISTER,
*text_socket.BL_REGISTER,
*file_path_socket.BL_REGISTER,
]

View File

@ -1,73 +0,0 @@
import typing as typ
import bpy
import sympy as sp
import pydantic as pyd
from .. import base
from ... import contracts
####################
# - Blender Socket
####################
class BoolBLSocket(base.BLSocket):
socket_type = contracts.SocketType.Bool
bl_label = "Bool"
compatible_types = {
bool: {},
}
####################
# - Properties
####################
raw_value: bpy.props.BoolProperty(
name="Boolean",
description="Represents a boolean",
default=False,
)
####################
# - Socket UI
####################
def draw_label_row(self, label_col_row: bpy.types.UILayout, text: str) -> None:
label_col_row.label(text=text)
label_col_row.prop(self, "raw_value", text="")
def draw_value(self, label_col_row: bpy.types.UILayout) -> None:
pass
####################
# - Computation of Default Value
####################
@property
def default_value(self) -> str:
return self.raw_value
@default_value.setter
def default_value(self, value: typ.Any) -> None:
# (Guard) Value Compatibility
if not self.is_compatible(value):
msg = f"Tried setting socket ({self}) to incompatible value ({value}) of type {type(value)}"
raise ValueError(msg)
self.raw_value = bool(value)
####################
# - Socket Configuration
####################
class BoolSocketDef(pyd.BaseModel):
socket_type: contracts.SocketType = contracts.SocketType.Bool
label: str
default_value: bool = False
def init(self, bl_socket: BoolBLSocket) -> None:
bl_socket.raw_value = self.default_value
####################
# - Blender Registration
####################
BL_REGISTER = [
BoolBLSocket,
]

View File

@ -37,9 +37,6 @@ class TextBLSocket(base.BLSocket):
"""
label_col_row.prop(self, "raw_value", text=text)
def draw_value(self, label_col_row: bpy.types.UILayout) -> None:
pass
####################
# - Computation of Default Value
####################

View File

@ -32,7 +32,6 @@ BL_REGISTER = [
*source_socket.BL_REGISTER,
*temporal_shape_socket.BL_REGISTER,
*structure_socket.BL_REGISTER,
*monitor_socket.BL_REGISTER,
*fdtd_sim_socket.BL_REGISTER,
*sim_grid_socket.BL_REGISTER,
*sim_grid_axis_socket.BL_REGISTER,

View File

@ -22,7 +22,7 @@ class MaxwellMediumBLSocket(base.BLSocket):
name="Permittivity",
description="Represents a simple, real permittivity.",
default=0.0,
precision=4,
precision=6,
)
####################
@ -33,7 +33,7 @@ class MaxwellMediumBLSocket(base.BLSocket):
specifying the active unit.
"""
col_row = col.row(align=True)
col_row.prop(self, "rel_permittivity", text="ϵr")
col_row.prop(self, "rel_permittivity", text="Re(eps_r)")
####################
# - Computation of Default Value

View File

@ -32,6 +32,14 @@ class RealNumberBLSocket(base.BLSocket):
precision=6,
)
####################
# - Socket UI
####################
def draw_label_row(self, label_col_row: bpy.types.UILayout, text: str) -> None:
"""Draw the value of the real number.
"""
label_col_row.prop(self, "raw_value", text=text)
####################
# - Computation of Default Value
####################

View File

@ -11,21 +11,15 @@ PhysicalLengthSocketDef = length_socket.PhysicalLengthSocketDef
PhysicalAreaSocketDef = area_socket.PhysicalAreaSocketDef
PhysicalVolumeSocketDef = volume_socket.PhysicalVolumeSocketDef
from . import point_3d_socket
PhysicalPoint3DSocketDef = point_3d_socket.PhysicalPoint3DSocketDef
from . import size_3d_socket
PhysicalSize3DSocketDef = size_3d_socket.PhysicalSize3DSocketDef
from . import mass_socket
PhysicalMassSocketDef = mass_socket.PhysicalMassSocketDef
from . import speed_socket
from . import accel_scalar_socket
from . import force_scalar_socket
from . import accel_socket
from . import force_socket
PhysicalSpeedSocketDef = speed_socket.PhysicalSpeedSocketDef
PhysicalAccelScalarSocketDef = accel_scalar_socket.PhysicalAccelScalarSocketDef
PhysicalForceScalarSocketDef = force_scalar_socket.PhysicalForceScalarSocketDef
PhysicalAccelSocketDef = accel_socket.PhysicalAccelSocketDef
PhysicalForceSocketDef = force_socket.PhysicalForceSocketDef
from . import pol_socket
PhysicalPolSocketDef = pol_socket.PhysicalPolSocketDef
@ -48,15 +42,11 @@ BL_REGISTER = [
*area_socket.BL_REGISTER,
*volume_socket.BL_REGISTER,
*point_3d_socket.BL_REGISTER,
*size_3d_socket.BL_REGISTER,
*mass_socket.BL_REGISTER,
*speed_socket.BL_REGISTER,
*accel_scalar_socket.BL_REGISTER,
*force_scalar_socket.BL_REGISTER,
*accel_socket.BL_REGISTER,
*force_socket.BL_REGISTER,
*pol_socket.BL_REGISTER,

View File

@ -1,56 +0,0 @@
import typing as typ
import bpy
import pydantic as pyd
from .. import base
from ... import contracts
####################
# - Blender Socket
####################
class PhysicalAccelScalarBLSocket(base.BLSocket):
socket_type = contracts.SocketType.PhysicalAccelScalar
bl_label = "PhysicalAccel"
use_units = True
####################
# - Properties
####################
raw_value: bpy.props.FloatProperty(
name="Unitless Acceleration",
description="Represents the unitless part of the acceleration",
default=0.0,
precision=6,
)
####################
# - Default Value
####################
@property
def default_value(self) -> None:
return self.raw_value * self.unit
@default_value.setter
def default_value(self, value: typ.Any) -> None:
self.raw_value = self.value_as_unit(value)
####################
# - Socket Configuration
####################
class PhysicalAccelScalarSocketDef(pyd.BaseModel):
socket_type: contracts.SocketType = contracts.SocketType.PhysicalAccelScalar
label: str
default_unit: typ.Any | None = None
def init(self, bl_socket: PhysicalAccelScalarBLSocket) -> None:
if self.default_unit:
bl_socket.unit = self.default_unit
####################
# - Blender Registration
####################
BL_REGISTER = [
PhysicalAccelScalarBLSocket,
]

View File

@ -0,0 +1,41 @@
import typing as typ
import pydantic as pyd
from .. import base
from ... import contracts
####################
# - Blender Socket
####################
class PhysicalAccelBLSocket(base.BLSocket):
socket_type = contracts.SocketType.PhysicalAccel
bl_label = "PhysicalAccel"
####################
# - Default Value
####################
@property
def default_value(self) -> None:
pass
@default_value.setter
def default_value(self, value: typ.Any) -> None:
pass
####################
# - Socket Configuration
####################
class PhysicalAccelSocketDef(pyd.BaseModel):
socket_type: contracts.SocketType = contracts.SocketType.PhysicalAccel
label: str
def init(self, bl_socket: PhysicalAccelBLSocket) -> None:
pass
####################
# - Blender Registration
####################
BL_REGISTER = [
PhysicalAccelBLSocket,
]

View File

@ -1,6 +1,5 @@
import typing as typ
import bpy
import pydantic as pyd
from .. import base
@ -12,28 +11,17 @@ from ... import contracts
class PhysicalAngleBLSocket(base.BLSocket):
socket_type = contracts.SocketType.PhysicalAngle
bl_label = "PhysicalAngle"
use_units = True
####################
# - Properties
####################
raw_value: bpy.props.FloatProperty(
name="Unitless Acceleration",
description="Represents the unitless part of the acceleration",
default=0.0,
precision=4,
)
####################
# - Default Value
####################
@property
def default_value(self) -> None:
return self.raw_value * self.unit
pass
@default_value.setter
def default_value(self, value: typ.Any) -> None:
self.raw_value = self.value_as_unit(value)
pass
####################
# - Socket Configuration
@ -42,11 +30,8 @@ class PhysicalAngleSocketDef(pyd.BaseModel):
socket_type: contracts.SocketType = contracts.SocketType.PhysicalAngle
label: str
default_unit: typ.Any | None = None
def init(self, bl_socket: PhysicalAngleBLSocket) -> None:
if self.default_unit:
bl_socket.unit = self.default_unit
pass
####################
# - Blender Registration

View File

@ -38,6 +38,9 @@ class PhysicalAreaBLSocket(base.BLSocket):
# - Socket UI
####################
def draw_label_row(self, label_col_row: bpy.types.UILayout, text: str) -> None:
"""Draw the value of the area, including a toggle for
specifying the active unit.
"""
label_col_row.label(text=text)
label_col_row.prop(self, "raw_unit", text="")

View File

@ -1,56 +0,0 @@
import typing as typ
import bpy
import pydantic as pyd
from .. import base
from ... import contracts
####################
# - Blender Socket
####################
class PhysicalForceScalarBLSocket(base.BLSocket):
socket_type = contracts.SocketType.PhysicalForceScalar
bl_label = "PhysicalForceScalar"
use_units = True
####################
# - Properties
####################
raw_value: bpy.props.FloatProperty(
name="Unitless Force",
description="Represents the unitless part of the force",
default=0.0,
precision=6,
)
####################
# - Default Value
####################
@property
def default_value(self) -> None:
return self.raw_value * self.unit
@default_value.setter
def default_value(self, value: typ.Any) -> None:
self.raw_value = self.value_as_unit(value)
####################
# - Socket Configuration
####################
class PhysicalForceScalarSocketDef(pyd.BaseModel):
socket_type: contracts.SocketType = contracts.SocketType.PhysicalForceScalar
label: str
default_unit: typ.Any | None = None
def init(self, bl_socket: PhysicalForceScalarBLSocket) -> None:
if self.default_unit:
bl_socket.unit = self.default_unit
####################
# - Blender Registration
####################
BL_REGISTER = [
PhysicalForceScalarBLSocket,
]

View File

@ -0,0 +1,41 @@
import typing as typ
import pydantic as pyd
from .. import base
from ... import contracts
####################
# - Blender Socket
####################
class PhysicalForceBLSocket(base.BLSocket):
socket_type = contracts.SocketType.PhysicalForce
bl_label = "PhysicalForce"
####################
# - Default Value
####################
@property
def default_value(self) -> None:
pass
@default_value.setter
def default_value(self, value: typ.Any) -> None:
pass
####################
# - Socket Configuration
####################
class PhysicalForceSocketDef(pyd.BaseModel):
socket_type: contracts.SocketType = contracts.SocketType.PhysicalForce
label: str
def init(self, bl_socket: PhysicalForceBLSocket) -> None:
pass
####################
# - Blender Registration
####################
BL_REGISTER = [
PhysicalForceBLSocket,
]

View File

@ -1,6 +1,5 @@
import typing as typ
import bpy
import pydantic as pyd
from .. import base
@ -12,28 +11,17 @@ from ... import contracts
class PhysicalFreqBLSocket(base.BLSocket):
socket_type = contracts.SocketType.PhysicalFreq
bl_label = "PhysicalFreq"
use_units = True
####################
# - Properties
####################
raw_value: bpy.props.FloatProperty(
name="Unitless Frequency",
description="Represents the unitless part of the frequency",
default=0.0,
precision=6,
)
####################
# - Default Value
####################
@property
def default_value(self) -> None:
return self.raw_value * self.unit
pass
@default_value.setter
def default_value(self, value: typ.Any) -> None:
self.raw_value = self.value_as_unit(value)
pass
####################
# - Socket Configuration

View File

@ -1,6 +1,5 @@
import typing as typ
import bpy
import pydantic as pyd
from .. import base
@ -12,28 +11,17 @@ from ... import contracts
class PhysicalLengthBLSocket(base.BLSocket):
socket_type = contracts.SocketType.PhysicalLength
bl_label = "PhysicalLength"
use_units = True
####################
# - Properties
####################
raw_value: bpy.props.FloatProperty(
name="Unitless Force",
description="Represents the unitless part of the force",
default=0.0,
precision=6,
)
####################
# - Default Value
####################
@property
def default_value(self) -> None:
return self.raw_value * self.unit
pass
@default_value.setter
def default_value(self, value: typ.Any) -> None:
self.raw_value = self.value_as_unit(value)
pass
####################
# - Socket Configuration
@ -42,11 +30,8 @@ class PhysicalLengthSocketDef(pyd.BaseModel):
socket_type: contracts.SocketType = contracts.SocketType.PhysicalLength
label: str
default_unit: typ.Any | None = None
def init(self, bl_socket: PhysicalLengthBLSocket) -> None:
if self.default_unit:
bl_socket.unit = self.default_unit
pass
####################
# - Blender Registration

View File

@ -1,67 +0,0 @@
import typing as typ
import bpy
import sympy as sp
import sympy.physics.units as spu
import pydantic as pyd
from .. import base
from ... import contracts
class PhysicalPoint3DBLSocket(base.BLSocket):
socket_type = contracts.SocketType.PhysicalPoint3D
bl_label = "Physical Volume"
use_units = True
compatible_types = {
sp.Expr: {
lambda self, v: v.is_real,
lambda self, v: len(v.free_symbols) == 0,
lambda self, v: any(
contracts.is_exactly_expressed_as_unit(v, unit)
for unit in self.units.values()
)
},
}
####################
# - Properties
####################
raw_value: bpy.props.FloatVectorProperty(
name="Unitless 3D Point (global coordinate system)",
description="Represents the unitless part of the 3D point",
size=3,
default=(0.0, 0.0, 0.0),
precision=4,
)
####################
# - Computation of Default Value
####################
@property
def default_value(self) -> sp.Expr:
return sp.Matrix(tuple(self.raw_value)) * self.unit
@default_value.setter
def default_value(self, value: typ.Any) -> None:
self.raw_value = self.value_as_unit(value)
####################
# - Socket Configuration
####################
class PhysicalPoint3DSocketDef(pyd.BaseModel):
socket_type: contracts.SocketType = contracts.SocketType.PhysicalPoint3D
label: str
default_unit: typ.Any | None = None
def init(self, bl_socket: PhysicalPoint3DBLSocket) -> None:
if self.default_unit:
bl_socket.unit = self.default_unit
####################
# - Blender Registration
####################
BL_REGISTER = [
PhysicalPoint3DBLSocket,
]

View File

@ -1,67 +0,0 @@
import typing as typ
import bpy
import sympy as sp
import sympy.physics.units as spu
import pydantic as pyd
from .. import base
from ... import contracts
class PhysicalSize3DBLSocket(base.BLSocket):
socket_type = contracts.SocketType.PhysicalSize3D
bl_label = "Physical Volume"
use_units = True
compatible_types = {
sp.Expr: {
lambda self, v: v.is_real,
lambda self, v: len(v.free_symbols) == 0,
lambda self, v: any(
contracts.is_exactly_expressed_as_unit(v, unit)
for unit in self.units.values()
)
},
}
####################
# - Properties
####################
raw_value: bpy.props.FloatVectorProperty(
name="Unitless 3D Size",
description="Represents the unitless part of the 3D size",
size=3,
default=(1.0, 1.0, 1.0),
precision=4,
)
####################
# - Computation of Default Value
####################
@property
def default_value(self) -> sp.Expr:
return sp.Matrix(tuple(self.raw_value)) * self.unit
@default_value.setter
def default_value(self, value: typ.Any) -> None:
self.raw_value = self.value_as_unit(value)
####################
# - Socket Configuration
####################
class PhysicalSize3DSocketDef(pyd.BaseModel):
socket_type: contracts.SocketType = contracts.SocketType.PhysicalSize3D
label: str
default_unit: typ.Any | None = None
def init(self, bl_socket: PhysicalSize3DBLSocket) -> None:
if self.default_unit:
bl_socket.unit = self.default_unit
####################
# - Blender Registration
####################
BL_REGISTER = [
PhysicalSize3DBLSocket,
]

View File

@ -1,6 +1,5 @@
import typing as typ
import bpy
import pydantic as pyd
from .. import base
@ -12,28 +11,17 @@ from ... import contracts
class PhysicalTimeBLSocket(base.BLSocket):
socket_type = contracts.SocketType.PhysicalTime
bl_label = "PhysicalTime"
use_units = True
####################
# - Properties
####################
raw_value: bpy.props.FloatProperty(
name="Unitless Force",
description="Represents the unitless part of the force",
default=0.0,
precision=6,
)
####################
# - Default Value
####################
@property
def default_value(self) -> None:
return self.raw_value * self.unit
pass
@default_value.setter
def default_value(self, value: typ.Any) -> None:
self.raw_value = self.value_as_unit(value)
pass
####################
# - Socket Configuration
@ -42,11 +30,8 @@ class PhysicalTimeSocketDef(pyd.BaseModel):
socket_type: contracts.SocketType = contracts.SocketType.PhysicalTime
label: str
default_unit: typ.Any | None = None
def init(self, bl_socket: PhysicalTimeBLSocket) -> None:
if self.default_unit:
bl_socket.unit = self.default_unit
pass
####################
# - Blender Registration

View File

@ -5,6 +5,9 @@ import sympy as sp
import sympy.physics.units as spu
import pydantic as pyd
sp.printing.str.StrPrinter._default_settings['abbrev'] = True
## When we str() a unit expression, use abbrevied units.
from .. import base
from ... import contracts

View File

@ -1,4 +1,3 @@
tidy3d==2.5.2
pydantic==2.6.0
sympy==1.12
scipy==1.12.0

BIN
code/demo.blend (Stored with Git LFS)

Binary file not shown.