"""YAML 材料定義 → Mitsuba BSDF dict 変換モジュール."""
from __future__ import annotations
from sm_tias_lightsim.scene.schema import (
DielectricMaterial,
DiffuseMaterial,
MaterialConfig,
ThinDielectricMaterial,
)
def _to_rgb(value: float | tuple[float, float, float]) -> list[float]:
"""スカラまたは RGB タプルを 3 要素の float リストに正規化する.
lights.py / materials.py 共通のヘルパ.このモジュールが正本で,
lights.py はここから import して重複を回避する.
Args:
value: スカラ(全チャンネル同値)または RGB タプル.
Returns:
3 要素の float リスト.
"""
if isinstance(value, (int, float)):
return [float(value)] * 3
return list(value)
def build_material_dict(material: MaterialConfig) -> dict:
"""1 MaterialConfig を Mitsuba BSDF dict に変換する.
Args:
material: SceneConfig.materials の値(DiffuseMaterial 等).
Returns:
Mitsuba BSDF dict.
- diffuse → {"type": "diffuse", "reflectance": {"type":"rgb","value":[r,g,b]}}
- dielectric → {"type": "dielectric", "int_ior": ..., "ext_ior": ...}
- thindielectric → {"type": "thindielectric", "int_ior": ..., "ext_ior": ...}
Raises:
ValueError: 未対応の材料タイプが指定された場合.
"""
if isinstance(material, DiffuseMaterial):
return {
"type": "diffuse",
"reflectance": {
"type": "rgb",
"value": _to_rgb(material.reflectance),
},
}
if isinstance(material, DielectricMaterial):
return {
"type": "dielectric",
"int_ior": material.int_ior,
"ext_ior": material.ext_ior,
}
if isinstance(material, ThinDielectricMaterial):
return {
"type": "thindielectric",
"int_ior": material.int_ior,
"ext_ior": material.ext_ior,
}
msg = f"Unsupported material type: {type(material).__name__}"
raise ValueError(msg)