oscillode/blender_maxwell/node_trees/maxwell_sim_nodes/sockets/physical/unit_system_socket.py

297 lines
9.7 KiB
Python

import typing as typ
import bpy
import sympy as sp
import pydantic as pyd
from .. import base
from ... import contracts
def contract_units_to_items(socket_type):
return [
(
unit_key,
str(unit),
f"{socket_type}-compatible unit",
)
for unit_key, unit in contracts.SocketType_to_units[
socket_type
]["values"].items()
]
def default_unit_key_for(socket_type):
return contracts.SocketType_to_units[
socket_type
]["default"]
####################
# - Blender Socket
####################
class PhysicalUnitSystemBLSocket(base.BLSocket):
socket_type = contracts.SocketType.PhysicalUnitSystem
bl_label = "PhysicalUnitSystem"
####################
# - Properties
####################
show_definition: bpy.props.BoolProperty(
name="Show Unit System Definition",
description="Toggle to show unit system definition",
default=False,
update=(lambda self, context: self.trigger_updates()),
)
unit_time: bpy.props.EnumProperty(
name="Time Unit",
description="Unit of time",
items=contract_units_to_items(contracts.SocketType.PhysicalTime),
default=default_unit_key_for(contracts.SocketType.PhysicalTime),
update=(lambda self, context: self.trigger_updates()),
)
unit_angle: bpy.props.EnumProperty(
name="Angle Unit",
description="Unit of angle",
items=contract_units_to_items(contracts.SocketType.PhysicalAngle),
default=default_unit_key_for(contracts.SocketType.PhysicalAngle),
update=(lambda self, context: self.trigger_updates()),
)
unit_length: bpy.props.EnumProperty(
name="Length Unit",
description="Unit of length",
items=contract_units_to_items(contracts.SocketType.PhysicalLength),
default=default_unit_key_for(contracts.SocketType.PhysicalLength),
update=(lambda self, context: self.trigger_updates()),
)
unit_area: bpy.props.EnumProperty(
name="Area Unit",
description="Unit of area",
items=contract_units_to_items(contracts.SocketType.PhysicalArea),
default=default_unit_key_for(contracts.SocketType.PhysicalArea),
update=(lambda self, context: self.trigger_updates()),
)
unit_volume: bpy.props.EnumProperty(
name="Volume Unit",
description="Unit of time",
items=contract_units_to_items(contracts.SocketType.PhysicalVolume),
default=default_unit_key_for(contracts.SocketType.PhysicalVolume),
update=(lambda self, context: self.trigger_updates()),
)
unit_point_2d: bpy.props.EnumProperty(
name="Point2D Unit",
description="Unit of 2D points",
items=contract_units_to_items(contracts.SocketType.PhysicalPoint2D),
default=default_unit_key_for(contracts.SocketType.PhysicalPoint2D),
update=(lambda self, context: self.trigger_updates()),
)
unit_point_3d: bpy.props.EnumProperty(
name="Point3D Unit",
description="Unit of 3D points",
items=contract_units_to_items(contracts.SocketType.PhysicalPoint3D),
default=default_unit_key_for(contracts.SocketType.PhysicalPoint3D),
update=(lambda self, context: self.trigger_updates()),
)
unit_size_2d: bpy.props.EnumProperty(
name="Size2D Unit",
description="Unit of 2D sizes",
items=contract_units_to_items(contracts.SocketType.PhysicalSize2D),
default=default_unit_key_for(contracts.SocketType.PhysicalSize2D),
update=(lambda self, context: self.trigger_updates()),
)
unit_size_3d: bpy.props.EnumProperty(
name="Size3D Unit",
description="Unit of 3D sizes",
items=contract_units_to_items(contracts.SocketType.PhysicalSize3D),
default=default_unit_key_for(contracts.SocketType.PhysicalSize3D),
update=(lambda self, context: self.trigger_updates()),
)
unit_mass: bpy.props.EnumProperty(
name="Mass Unit",
description="Unit of mass",
items=contract_units_to_items(contracts.SocketType.PhysicalMass),
default=default_unit_key_for(contracts.SocketType.PhysicalMass),
update=(lambda self, context: self.trigger_updates()),
)
unit_speed: bpy.props.EnumProperty(
name="Speed Unit",
description="Unit of speed",
items=contract_units_to_items(contracts.SocketType.PhysicalSpeed),
default=default_unit_key_for(contracts.SocketType.PhysicalSpeed),
update=(lambda self, context: self.trigger_updates()),
)
unit_accel_scalar: bpy.props.EnumProperty(
name="Accel Unit",
description="Unit of acceleration",
items=contract_units_to_items(contracts.SocketType.PhysicalAccelScalar),
default=default_unit_key_for(contracts.SocketType.PhysicalAccelScalar),
update=(lambda self, context: self.trigger_updates()),
)
unit_force_scalar: bpy.props.EnumProperty(
name="Force Scalar Unit",
description="Unit of scalar force",
items=contract_units_to_items(contracts.SocketType.PhysicalForceScalar),
default=default_unit_key_for(contracts.SocketType.PhysicalForceScalar),
update=(lambda self, context: self.trigger_updates()),
)
unit_accel_3d_vector: bpy.props.EnumProperty(
name="Accel3D Unit",
description="Unit of 3D vector acceleration",
items=contract_units_to_items(contracts.SocketType.PhysicalAccel3DVector),
default=default_unit_key_for(contracts.SocketType.PhysicalAccel3DVector),
update=(lambda self, context: self.trigger_updates()),
)
unit_force_3d_vector: bpy.props.EnumProperty(
name="Force3D Unit",
description="Unit of 3D vector force",
items=contract_units_to_items(contracts.SocketType.PhysicalForce3DVector),
default=default_unit_key_for(contracts.SocketType.PhysicalForce3DVector),
update=(lambda self, context: self.trigger_updates()),
)
unit_freq: bpy.props.EnumProperty(
name="Freq Unit",
description="Unit of frequency",
items=contract_units_to_items(contracts.SocketType.PhysicalFreq),
default=default_unit_key_for(contracts.SocketType.PhysicalFreq),
update=(lambda self, context: self.trigger_updates()),
)
unit_vac_wl: bpy.props.EnumProperty(
name="VacWL Unit",
description="Unit of vacuum wavelength",
items=contract_units_to_items(contracts.SocketType.PhysicalVacWL),
default=default_unit_key_for(contracts.SocketType.PhysicalVacWL),
update=(lambda self, context: self.trigger_updates()),
)
####################
# - UI
####################
def draw_label_row(self, label_col_row: bpy.types.UILayout, text) -> None:
label_col_row.label(text=text)
label_col_row.prop(self, "show_definition", toggle=True, text="", icon="MOD_LENGTH")
def draw_value(self, col: bpy.types.UILayout) -> None:
if self.show_definition:
col_row=col.row(align=True)
col_row.alignment = "EXPAND"
col_row.prop(self, "unit_time", text="")
col_row.prop(self, "unit_angle", text="")
col_row=col.row(align=True)
col_row.alignment = "EXPAND"
col_row.prop(self, "unit_length", text="")
col_row.prop(self, "unit_area", text="")
col_row.prop(self, "unit_volume", text="")
col_row=col.row(align=True)
col_row.alignment = "EXPAND"
col_row.label(text="Point")
col_row.prop(self, "unit_point_2d", text="")
col_row.prop(self, "unit_point_3d", text="")
col_row=col.row(align=True)
col_row.alignment = "EXPAND"
col_row.label(text="Size")
col_row.prop(self, "unit_size_2d", text="")
col_row.prop(self, "unit_size_3d", text="")
col_row=col.row(align=True)
col_row.alignment = "EXPAND"
col_row.label(text="Mass")
col_row.prop(self, "unit_mass", text="")
col_row=col.row(align=True)
col_row.alignment = "EXPAND"
col_row.label(text="Vel")
col_row.prop(self, "unit_speed", text="")
#col_row.prop(self, "unit_vel_2d_vector", text="")
#col_row.prop(self, "unit_vel_3d_vector", text="")
col_row=col.row(align=True)
col_row.label(text="Accel")
col_row.prop(self, "unit_accel_scalar", text="")
#col_row.prop(self, "unit_accel_2d_vector", text="")
col_row.prop(self, "unit_accel_3d_vector", text="")
col_row=col.row(align=True)
col_row.label(text="Force")
col_row.prop(self, "unit_force_scalar", text="")
#col_row.prop(self, "unit_force_2d_vector", text="")
col_row.prop(self, "unit_force_3d_vector", text="")
col_row=col.row(align=True)
col_row.alignment = "EXPAND"
col_row.label(text="Freq")
col_row.prop(self, "unit_freq", text="")
col_row=col.row(align=True)
col_row.alignment = "EXPAND"
col_row.label(text="Vac WL")
col_row.prop(self, "unit_vac_wl", text="")
####################
# - Default Value
####################
@property
def default_value(self) -> sp.Expr:
ST = contracts.SocketType
SM = lambda socket_type: contracts.SocketType_to_units[
socket_type
]["values"]
return {
socket_type: SM(socket_type)[socket_unit_prop]
for socket_type, socket_unit_prop in [
(ST.PhysicalTime, self.unit_time),
(ST.PhysicalAngle, self.unit_angle),
(ST.PhysicalLength, self.unit_length),
(ST.PhysicalArea, self.unit_area),
(ST.PhysicalVolume, self.unit_volume),
(ST.PhysicalPoint2D, self.unit_point_2d),
(ST.PhysicalPoint3D, self.unit_point_3d),
(ST.PhysicalSize2D, self.unit_size_2d),
(ST.PhysicalSize3D, self.unit_size_3d),
(ST.PhysicalMass, self.unit_mass),
(ST.PhysicalSpeed, self.unit_speed),
(ST.PhysicalAccelScalar, self.unit_accel_scalar),
(ST.PhysicalForceScalar, self.unit_force_scalar),
(ST.PhysicalAccel3DVector, self.unit_accel_3d_vector),
(ST.PhysicalForce3DVector, self.unit_force_3d_vector),
(ST.PhysicalFreq, self.unit_freq),
(ST.PhysicalVacWL, self.unit_vac_wl),
]
}
@default_value.setter
def default_value(self, value: typ.Any) -> None:
pass
####################
# - Socket Configuration
####################
class PhysicalUnitSystemSocketDef(pyd.BaseModel):
socket_type: contracts.SocketType = contracts.SocketType.PhysicalUnitSystem
label: str
show_by_default: bool = False
def init(self, bl_socket: PhysicalUnitSystemBLSocket) -> None:
bl_socket.show_definition = self.show_by_default
####################
# - Blender Registration
####################
BL_REGISTER = [
PhysicalUnitSystemBLSocket,
]