feat: More sockets, nodes, fixes.
We're starting to have a very advanced socket-based language for defining nodes. It's very practical already. The priorities are 1. All the nodes! 2. Sockets, including default values, as needed. 3. Library constants, mediums. 4. Output socket previews w/geonodes, geonodes structures. 5. Utilities including arrays (and selected array multi-input) The code is still very spaghetti. This is very much still the "first, make it run" part of the system design.blender-plugin-mvp
parent
586d6fa74b
commit
7344913c0e
|
@ -79,6 +79,7 @@ class TreeType(BlenderTypeEnum):
|
|||
class SocketType(BlenderTypeEnum):
|
||||
# Base
|
||||
Any = enum.auto()
|
||||
Bool = enum.auto()
|
||||
Text = enum.auto()
|
||||
FilePath = enum.auto()
|
||||
|
||||
|
@ -104,11 +105,19 @@ 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()
|
||||
PhysicalAccel = enum.auto()
|
||||
PhysicalForce = enum.auto()
|
||||
PhysicalAccelScalar = enum.auto()
|
||||
PhysicalForceScalar = enum.auto()
|
||||
PhysicalAccel3DVector = enum.auto()
|
||||
PhysicalForce3DVector = enum.auto()
|
||||
|
||||
PhysicalPol = enum.auto()
|
||||
|
||||
|
@ -220,6 +229,72 @@ 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",
|
||||
"values": {
|
||||
|
@ -247,7 +322,7 @@ SocketType_to_units = {
|
|||
"MI_H": spu.mile / spu.hour,
|
||||
},
|
||||
},
|
||||
SocketType.PhysicalAccel: {
|
||||
SocketType.PhysicalAccelScalar: {
|
||||
"default": "UM_S_SQ",
|
||||
"values": {
|
||||
"PM_S_SQ": spu.picometer / spu.second**2,
|
||||
|
@ -259,7 +334,29 @@ SocketType_to_units = {
|
|||
"FT_S_SQ": spu.feet / spu.second**2,
|
||||
},
|
||||
},
|
||||
SocketType.PhysicalForce: {
|
||||
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: {
|
||||
"default": "UNEWT",
|
||||
"values": {
|
||||
"KG_M_S_SQ": spu.kg * spu.m/spu.second**2,
|
||||
|
@ -294,6 +391,7 @@ 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
|
||||
|
||||
|
@ -315,10 +413,16 @@ 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.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.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.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
|
||||
|
|
|
@ -371,12 +371,23 @@ class MaxwellSimTreeNode(bpy.types.Node):
|
|||
Blender's own node socket object.
|
||||
"""
|
||||
|
||||
# (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)
|
||||
if input_socket_name in self.input_sockets:
|
||||
# Check Nicely that it 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]
|
||||
|
||||
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,
|
||||
|
@ -392,17 +403,35 @@ class MaxwellSimTreeNode(bpy.types.Node):
|
|||
Blender's own node socket object.
|
||||
"""
|
||||
|
||||
# (Guard) Socket Exists
|
||||
if output_socket_name not in self.output_sockets:
|
||||
msg = f"Input socket with name {output_socket_name} does not exist"
|
||||
raise ValueError(msg)
|
||||
|
||||
return self.outputs[self.output_sockets[output_socket_name].label]
|
||||
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"
|
||||
raise ValueError(msg)
|
||||
|
||||
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()
|
||||
|
|
|
@ -11,16 +11,21 @@ class NumberConstantNode(base.MaxwellSimTreeNode):
|
|||
bl_label = "Numerical Constant"
|
||||
#bl_icon = constants.ICON_SIM_INPUT
|
||||
|
||||
input_sockets = {
|
||||
"value": sockets.ComplexNumberSocketDef(
|
||||
label="Complex",
|
||||
), ## TODO: Dynamic number socket!
|
||||
}
|
||||
output_sockets = {
|
||||
"value": sockets.ComplexNumberSocketDef(
|
||||
label="Complex",
|
||||
), ## TODO: Dynamic number socket!
|
||||
input_sockets = {}
|
||||
input_socket_sets = {
|
||||
"real": {
|
||||
"value": sockets.RealNumberSocketDef(
|
||||
label="Real",
|
||||
),
|
||||
},
|
||||
"complex": {
|
||||
"value": sockets.ComplexNumberSocketDef(
|
||||
label="Complex",
|
||||
),
|
||||
},
|
||||
}
|
||||
output_sockets = {}
|
||||
output_socket_sets = input_socket_sets
|
||||
|
||||
####################
|
||||
# - Callbacks
|
||||
|
|
|
@ -1,5 +1,75 @@
|
|||
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 = []
|
||||
BL_NODES = {}
|
||||
BL_REGISTER = [
|
||||
PhysicalConstantNode,
|
||||
]
|
||||
BL_NODES = {
|
||||
contracts.NodeType.PhysicalConstant: (
|
||||
contracts.NodeCategory.MAXWELLSIM_INPUTS_CONSTANTS
|
||||
)
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ 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"),
|
||||
},
|
||||
|
@ -36,14 +37,20 @@ 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": sockets.PhysicalAccelSocketDef(label="PhysicalAccel"),
|
||||
"physical_force": sockets.PhysicalForceSocketDef(label="PhysicalForce"),
|
||||
"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_pol": sockets.PhysicalPolSocketDef(label="PhysicalPol"),
|
||||
"physical_freq": sockets.PhysicalFreqSocketDef(label="PhysicalFreq"),
|
||||
"physical_spec_power_dist": sockets.PhysicalSpecPowerDistSocketDef(label="PhysicalSpecPowerDist"),
|
||||
|
@ -62,18 +69,21 @@ 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.MaxwellMediumSocketDef(label="MaxwellMedium"),
|
||||
"maxwell_structure": sockets.MaxwellStructureSocketDef(label="MaxwellMedium"),
|
||||
"maxwell_bound_box": sockets.MaxwellBoundBoxSocketDef(label="MaxwellBoundBox"),
|
||||
"maxwell_bound_face": sockets.MaxwellBoundFaceSocketDef(label="MaxwellBoundFace"),
|
||||
"maxwell_monitor": sockets.MaxwellMonitorSocketDef(label="MaxwellMonitor"),
|
||||
"maxwell_monitor": sockets.MaxwellFDTDSimSocketDef(label="MaxwellFDTDSim"),
|
||||
"maxwell_monitor": sockets.MaxwellSimGridSocketDef(label="MaxwellSimGrid"),
|
||||
"maxwell_monitor": sockets.MaxwellSimGridAxisSocketDef(label="MaxwellSimGridAxis"),
|
||||
"maxwell_fdtd_sim": sockets.MaxwellFDTDSimSocketDef(label="MaxwellFDTDSim"),
|
||||
"maxwell_sim_grid": sockets.MaxwellSimGridSocketDef(label="MaxwellSimGrid"),
|
||||
"maxwell_sim_grid_axis": sockets.MaxwellSimGridAxisSocketDef(label="MaxwellSimGridAxis"),
|
||||
},
|
||||
}
|
||||
|
||||
output_sockets = {}
|
||||
output_socket_sets = input_socket_sets
|
||||
output_socket_sets = {
|
||||
k + " Output": v
|
||||
for k, v in input_socket_sets.items()
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -16,21 +16,11 @@ class FDTDSimNode(base.MaxwellSimTreeNode):
|
|||
# - Sockets
|
||||
####################
|
||||
input_sockets = {
|
||||
"run_time": sockets.RealNumberSocketDef(
|
||||
"run_time": sockets.PhysicalTimeSocketDef(
|
||||
label="Run Time",
|
||||
default_value=1.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,
|
||||
"size": sockets.PhysicalSize3DSocketDef(
|
||||
label="Size",
|
||||
),
|
||||
"ambient_medium": sockets.MaxwellMediumSocketDef(
|
||||
label="Ambient Medium",
|
||||
|
@ -56,17 +46,15 @@ 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")
|
||||
_run_time = self.compute_input("run_time")
|
||||
_size = self.compute_input("size")
|
||||
ambient_medium = self.compute_input("ambient_medium")
|
||||
structures = [self.compute_input("structure")]
|
||||
sources = [self.compute_input("source")]
|
||||
bound = self.compute_input("bound")
|
||||
|
||||
size = (
|
||||
self.compute_input("size_x"),
|
||||
self.compute_input("size_y"),
|
||||
self.compute_input("size_z"),
|
||||
)
|
||||
run_time = spu.convert_to(_run_time, spu.second) / spu.second
|
||||
size = tuple(spu.convert_to(_size, spu.um) / spu.um)
|
||||
|
||||
return td.Simulation(
|
||||
size=size,
|
||||
|
|
|
@ -16,17 +16,14 @@ class PointDipoleSourceNode(base.MaxwellSimTreeNode):
|
|||
# - Sockets
|
||||
####################
|
||||
input_sockets = {
|
||||
"center_x": sockets.RealNumberSocketDef(
|
||||
label="Center X",
|
||||
default_value=0.0,
|
||||
#"polarization": sockets.PhysicalPolSocketDef(
|
||||
# label="Polarization",
|
||||
#), ## TODO: Exactly how to go about this...
|
||||
"temporal_shape": sockets.MaxwellTemporalShapeSocketDef(
|
||||
label="Temporal Shape",
|
||||
),
|
||||
"center_y": sockets.RealNumberSocketDef(
|
||||
label="Center Y",
|
||||
default_value=0.0,
|
||||
),
|
||||
"center_z": sockets.RealNumberSocketDef(
|
||||
label="Center Z",
|
||||
default_value=0.0,
|
||||
"center": sockets.PhysicalPoint3DSocketDef(
|
||||
label="Center",
|
||||
),
|
||||
}
|
||||
output_sockets = {
|
||||
|
@ -40,19 +37,19 @@ class PointDipoleSourceNode(base.MaxwellSimTreeNode):
|
|||
####################
|
||||
@base.computes_output_socket("source")
|
||||
def compute_source(self: contracts.NodeTypeProtocol) -> td.PointDipole:
|
||||
center = (
|
||||
self.compute_input("center_x"),
|
||||
self.compute_input("center_y"),
|
||||
self.compute_input("center_z"),
|
||||
)
|
||||
temporal_shape = self.compute_input("temporal_shape")
|
||||
|
||||
cheating_pulse = td.GaussianPulse(freq0=200e12, fwidth=20e12)
|
||||
_center = self.compute_input("center")
|
||||
center = tuple(spu.convert_to(_center, spu.um) / spu.um)
|
||||
|
||||
cheating_pol = "Ex"
|
||||
## TODO: Fix
|
||||
|
||||
return td.PointDipole(
|
||||
center=center,
|
||||
source_time=cheating_pulse,
|
||||
source_time=temporal_shape,
|
||||
interpolate=True,
|
||||
polarization="Ex",
|
||||
polarization=cheating_pol,
|
||||
)
|
||||
|
||||
|
||||
|
|
|
@ -1,6 +1,82 @@
|
|||
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 = []
|
||||
BL_NODES = {}
|
||||
|
||||
BL_REGISTER = [
|
||||
GaussianPulseTemporalShapeNode,
|
||||
]
|
||||
BL_NODES = {
|
||||
contracts.NodeType.GaussianPulseTemporalShape: (
|
||||
contracts.NodeCategory.MAXWELLSIM_SOURCES_TEMPORALSHAPES
|
||||
)
|
||||
}
|
||||
|
|
|
@ -18,29 +18,11 @@ class BoxStructureNode(base.MaxwellSimTreeNode):
|
|||
"medium": sockets.MaxwellMediumSocketDef(
|
||||
label="Medium",
|
||||
),
|
||||
"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,
|
||||
),
|
||||
"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,
|
||||
"size": sockets.PhysicalSize3DSocketDef(
|
||||
label="Size",
|
||||
),
|
||||
}
|
||||
output_sockets = {
|
||||
|
@ -55,16 +37,11 @@ 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_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"),
|
||||
)
|
||||
_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)
|
||||
|
||||
return td.Structure(
|
||||
geometry=td.Box(
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
from . import basic
|
||||
AnySocketDef = basic.AnySocketDef
|
||||
BoolSocketDef = basic.BoolSocketDef
|
||||
TextSocketDef = basic.TextSocketDef
|
||||
FilePathSocketDef = basic.FilePathSocketDef
|
||||
|
||||
|
@ -21,10 +22,12 @@ PhysicalAngleSocketDef = physical.PhysicalAngleSocketDef
|
|||
PhysicalLengthSocketDef = physical.PhysicalLengthSocketDef
|
||||
PhysicalAreaSocketDef = physical.PhysicalAreaSocketDef
|
||||
PhysicalVolumeSocketDef = physical.PhysicalVolumeSocketDef
|
||||
PhysicalPoint3DSocketDef = physical.PhysicalPoint3DSocketDef
|
||||
PhysicalSize3DSocketDef = physical.PhysicalSize3DSocketDef
|
||||
PhysicalMassSocketDef = physical.PhysicalMassSocketDef
|
||||
PhysicalSpeedSocketDef = physical.PhysicalSpeedSocketDef
|
||||
PhysicalAccelSocketDef = physical.PhysicalAccelSocketDef
|
||||
PhysicalForceSocketDef = physical.PhysicalForceSocketDef
|
||||
PhysicalAccelScalarSocketDef = physical.PhysicalAccelScalarSocketDef
|
||||
PhysicalForceScalarSocketDef = physical.PhysicalForceScalarSocketDef
|
||||
PhysicalPolSocketDef = physical.PhysicalPolSocketDef
|
||||
PhysicalFreqSocketDef = physical.PhysicalFreqSocketDef
|
||||
PhysicalSpecRelPermDistSocketDef = physical.PhysicalSpecRelPermDistSocketDef
|
||||
|
|
|
@ -127,10 +127,16 @@ class BLSocket(bpy.types.NodeSocket):
|
|||
the value with the new unit.
|
||||
"""
|
||||
if hasattr(self, "raw_value") and hasattr(self, "unit"):
|
||||
self.raw_value = spu.convert_to(
|
||||
self.raw_value * self._unit_previous,
|
||||
self.unit,
|
||||
) / 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,
|
||||
) / self.unit
|
||||
|
||||
self._unit_previous = self.unit
|
||||
|
||||
|
@ -187,6 +193,9 @@ 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)
|
||||
|
||||
|
@ -208,6 +217,9 @@ 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,
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
from . import any_socket
|
||||
AnySocketDef = any_socket.AnySocketDef
|
||||
|
||||
from . import bool_socket
|
||||
BoolSocketDef = bool_socket.BoolSocketDef
|
||||
|
||||
from . import text_socket
|
||||
TextSocketDef = text_socket.TextSocketDef
|
||||
|
||||
|
@ -10,6 +13,7 @@ FilePathSocketDef = file_path_socket.FilePathSocketDef
|
|||
|
||||
BL_REGISTER = [
|
||||
*any_socket.BL_REGISTER,
|
||||
*bool_socket.BL_REGISTER,
|
||||
*text_socket.BL_REGISTER,
|
||||
*file_path_socket.BL_REGISTER,
|
||||
]
|
||||
|
|
|
@ -0,0 +1,73 @@
|
|||
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,
|
||||
]
|
|
@ -37,6 +37,9 @@ 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
|
||||
####################
|
||||
|
|
|
@ -32,6 +32,7 @@ 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,
|
||||
|
|
|
@ -22,7 +22,7 @@ class MaxwellMediumBLSocket(base.BLSocket):
|
|||
name="Permittivity",
|
||||
description="Represents a simple, real permittivity.",
|
||||
default=0.0,
|
||||
precision=6,
|
||||
precision=4,
|
||||
)
|
||||
|
||||
####################
|
||||
|
@ -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="Re(eps_r)")
|
||||
col_row.prop(self, "rel_permittivity", text="ϵr")
|
||||
|
||||
####################
|
||||
# - Computation of Default Value
|
||||
|
|
|
@ -32,14 +32,6 @@ 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
|
||||
####################
|
||||
|
|
|
@ -11,15 +11,21 @@ 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_socket
|
||||
from . import force_socket
|
||||
from . import accel_scalar_socket
|
||||
from . import force_scalar_socket
|
||||
PhysicalSpeedSocketDef = speed_socket.PhysicalSpeedSocketDef
|
||||
PhysicalAccelSocketDef = accel_socket.PhysicalAccelSocketDef
|
||||
PhysicalForceSocketDef = force_socket.PhysicalForceSocketDef
|
||||
PhysicalAccelScalarSocketDef = accel_scalar_socket.PhysicalAccelScalarSocketDef
|
||||
PhysicalForceScalarSocketDef = force_scalar_socket.PhysicalForceScalarSocketDef
|
||||
|
||||
from . import pol_socket
|
||||
PhysicalPolSocketDef = pol_socket.PhysicalPolSocketDef
|
||||
|
@ -42,11 +48,15 @@ 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_socket.BL_REGISTER,
|
||||
*force_socket.BL_REGISTER,
|
||||
*accel_scalar_socket.BL_REGISTER,
|
||||
*force_scalar_socket.BL_REGISTER,
|
||||
|
||||
*pol_socket.BL_REGISTER,
|
||||
|
||||
|
|
|
@ -9,8 +9,8 @@ from ... import contracts
|
|||
####################
|
||||
# - Blender Socket
|
||||
####################
|
||||
class PhysicalAccelBLSocket(base.BLSocket):
|
||||
socket_type = contracts.SocketType.PhysicalAccel
|
||||
class PhysicalAccelScalarBLSocket(base.BLSocket):
|
||||
socket_type = contracts.SocketType.PhysicalAccelScalar
|
||||
bl_label = "PhysicalAccel"
|
||||
use_units = True
|
||||
|
||||
|
@ -24,17 +24,6 @@ class PhysicalAccelBLSocket(base.BLSocket):
|
|||
precision=6,
|
||||
)
|
||||
|
||||
####################
|
||||
# - 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_unit", text="")
|
||||
|
||||
def draw_value(self, col: bpy.types.UILayout) -> None:
|
||||
col_row = col.row(align=True)
|
||||
col_row.prop(self, "raw_value", text="")
|
||||
|
||||
####################
|
||||
# - Default Value
|
||||
####################
|
||||
|
@ -49,16 +38,19 @@ class PhysicalAccelBLSocket(base.BLSocket):
|
|||
####################
|
||||
# - Socket Configuration
|
||||
####################
|
||||
class PhysicalAccelSocketDef(pyd.BaseModel):
|
||||
socket_type: contracts.SocketType = contracts.SocketType.PhysicalAccel
|
||||
class PhysicalAccelScalarSocketDef(pyd.BaseModel):
|
||||
socket_type: contracts.SocketType = contracts.SocketType.PhysicalAccelScalar
|
||||
label: str
|
||||
|
||||
def init(self, bl_socket: PhysicalAccelBLSocket) -> None:
|
||||
pass
|
||||
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 = [
|
||||
PhysicalAccelBLSocket,
|
||||
PhysicalAccelScalarBLSocket,
|
||||
]
|
|
@ -1,5 +1,6 @@
|
|||
import typing as typ
|
||||
|
||||
import bpy
|
||||
import pydantic as pyd
|
||||
|
||||
from .. import base
|
||||
|
@ -11,17 +12,28 @@ 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:
|
||||
pass
|
||||
return self.raw_value * self.unit
|
||||
|
||||
@default_value.setter
|
||||
def default_value(self, value: typ.Any) -> None:
|
||||
pass
|
||||
self.raw_value = self.value_as_unit(value)
|
||||
|
||||
####################
|
||||
# - Socket Configuration
|
||||
|
@ -30,8 +42,11 @@ 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:
|
||||
pass
|
||||
if self.default_unit:
|
||||
bl_socket.unit = self.default_unit
|
||||
|
||||
####################
|
||||
# - Blender Registration
|
||||
|
|
|
@ -38,9 +38,6 @@ 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="")
|
||||
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
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,
|
||||
]
|
|
@ -1,41 +0,0 @@
|
|||
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,
|
||||
]
|
|
@ -1,5 +1,6 @@
|
|||
import typing as typ
|
||||
|
||||
import bpy
|
||||
import pydantic as pyd
|
||||
|
||||
from .. import base
|
||||
|
@ -11,17 +12,28 @@ 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:
|
||||
pass
|
||||
return self.raw_value * self.unit
|
||||
|
||||
@default_value.setter
|
||||
def default_value(self, value: typ.Any) -> None:
|
||||
pass
|
||||
self.raw_value = self.value_as_unit(value)
|
||||
|
||||
####################
|
||||
# - Socket Configuration
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import typing as typ
|
||||
|
||||
import bpy
|
||||
import pydantic as pyd
|
||||
|
||||
from .. import base
|
||||
|
@ -11,17 +12,28 @@ 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:
|
||||
pass
|
||||
return self.raw_value * self.unit
|
||||
|
||||
@default_value.setter
|
||||
def default_value(self, value: typ.Any) -> None:
|
||||
pass
|
||||
self.raw_value = self.value_as_unit(value)
|
||||
|
||||
####################
|
||||
# - Socket Configuration
|
||||
|
@ -30,8 +42,11 @@ 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:
|
||||
pass
|
||||
if self.default_unit:
|
||||
bl_socket.unit = self.default_unit
|
||||
|
||||
####################
|
||||
# - Blender Registration
|
||||
|
|
|
@ -0,0 +1,67 @@
|
|||
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,
|
||||
]
|
|
@ -0,0 +1,67 @@
|
|||
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,
|
||||
]
|
|
@ -1,5 +1,6 @@
|
|||
import typing as typ
|
||||
|
||||
import bpy
|
||||
import pydantic as pyd
|
||||
|
||||
from .. import base
|
||||
|
@ -11,17 +12,28 @@ 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:
|
||||
pass
|
||||
return self.raw_value * self.unit
|
||||
|
||||
@default_value.setter
|
||||
def default_value(self, value: typ.Any) -> None:
|
||||
pass
|
||||
self.raw_value = self.value_as_unit(value)
|
||||
|
||||
####################
|
||||
# - Socket Configuration
|
||||
|
@ -30,8 +42,11 @@ 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:
|
||||
pass
|
||||
if self.default_unit:
|
||||
bl_socket.unit = self.default_unit
|
||||
|
||||
####################
|
||||
# - Blender Registration
|
||||
|
|
|
@ -5,9 +5,6 @@ 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
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
tidy3d==2.5.2
|
||||
pydantic==2.6.0
|
||||
sympy==1.12
|
||||
scipy==1.12.0
|
||||
|
|
BIN
code/demo.blend (Stored with Git LFS)
BIN
code/demo.blend (Stored with Git LFS)
Binary file not shown.
Loading…
Reference in New Issue