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

297 lines
9.7 KiB
Python
Raw Normal View History

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,
]