2024-02-14 12:33:40 +01:00
|
|
|
import typing as typ
|
|
|
|
import json
|
|
|
|
from pathlib import Path
|
|
|
|
|
|
|
|
import bpy
|
|
|
|
import sympy as sp
|
|
|
|
import pydantic as pyd
|
2024-02-26 16:16:06 +01:00
|
|
|
import tidy3d as td
|
2024-02-14 12:33:40 +01:00
|
|
|
|
2024-03-10 11:56:37 +01:00
|
|
|
from .... import contracts as ct
|
2024-02-14 12:33:40 +01:00
|
|
|
from .... import sockets
|
|
|
|
from ... import base
|
|
|
|
|
|
|
|
####################
|
|
|
|
# - Operators
|
|
|
|
####################
|
|
|
|
class JSONFileExporterSaveJSON(bpy.types.Operator):
|
|
|
|
bl_idname = "blender_maxwell.json_file_exporter_save_json"
|
|
|
|
bl_label = "Save the JSON of what's linked into a JSONFileExporterNode."
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
def poll(cls, context):
|
|
|
|
return True
|
|
|
|
|
|
|
|
def execute(self, context):
|
|
|
|
node = context.node
|
|
|
|
node.export_data_as_json()
|
|
|
|
return {'FINISHED'}
|
|
|
|
|
|
|
|
####################
|
|
|
|
# - Node
|
|
|
|
####################
|
2024-03-10 11:56:37 +01:00
|
|
|
class JSONFileExporterNode(base.MaxwellSimNode):
|
|
|
|
node_type = ct.NodeType.JSONFileExporter
|
2024-02-14 12:33:40 +01:00
|
|
|
|
|
|
|
bl_label = "JSON File Exporter"
|
|
|
|
#bl_icon = constants.ICON_SIM_INPUT
|
|
|
|
|
|
|
|
input_sockets = {
|
2024-03-10 11:56:37 +01:00
|
|
|
"Data": sockets.AnySocketDef(),
|
|
|
|
"JSON Path": sockets.FilePathSocketDef(
|
|
|
|
default_path=Path("simulation.json")
|
2024-02-14 12:33:40 +01:00
|
|
|
),
|
2024-03-10 11:56:37 +01:00
|
|
|
"JSON Indent": sockets.IntegerNumberSocketDef(
|
|
|
|
default_value=4,
|
2024-02-14 12:33:40 +01:00
|
|
|
),
|
|
|
|
}
|
2024-03-10 11:56:37 +01:00
|
|
|
output_sockets = {
|
2024-03-11 16:35:41 +01:00
|
|
|
"JSON String": sockets.StringSocketDef(),
|
2024-03-10 11:56:37 +01:00
|
|
|
}
|
2024-02-14 12:33:40 +01:00
|
|
|
|
|
|
|
####################
|
|
|
|
# - UI Layout
|
|
|
|
####################
|
|
|
|
def draw_operators(
|
|
|
|
self,
|
|
|
|
context: bpy.types.Context,
|
|
|
|
layout: bpy.types.UILayout,
|
|
|
|
) -> None:
|
2024-03-10 11:56:37 +01:00
|
|
|
layout.operator(JSONFileExporterSaveJSON.bl_idname, text="Save JSON")
|
2024-02-14 12:33:40 +01:00
|
|
|
|
|
|
|
####################
|
|
|
|
# - Methods
|
|
|
|
####################
|
|
|
|
def export_data_as_json(self) -> None:
|
2024-03-10 11:56:37 +01:00
|
|
|
if (json_str := self.compute_output("JSON String")):
|
|
|
|
data_dict = json.loads(json_str)
|
|
|
|
with self._compute_input("JSON Path").open("w") as f:
|
|
|
|
indent = self._compute_input("JSON Indent")
|
|
|
|
json.dump(data_dict, f, ensure_ascii=False, indent=indent)
|
|
|
|
|
|
|
|
####################
|
|
|
|
# - Output Sockets
|
|
|
|
####################
|
|
|
|
@base.computes_output_socket(
|
|
|
|
"JSON String",
|
|
|
|
input_sockets={"Data"},
|
|
|
|
)
|
|
|
|
def compute_json_string(self, input_sockets: dict[str, typ.Any]) -> str | None:
|
|
|
|
if not (data := input_sockets["Data"]):
|
|
|
|
return None
|
|
|
|
|
|
|
|
# Tidy3D Objects: Call .json()
|
|
|
|
if hasattr(data, "json"):
|
|
|
|
return data.json()
|
|
|
|
|
|
|
|
# Pydantic Models: Call .model_dump_json()
|
|
|
|
elif isinstance(data, pyd.BaseModel):
|
|
|
|
return data.model_dump_json()
|
|
|
|
|
|
|
|
else:
|
|
|
|
json.dumps(data)
|
2024-02-14 12:33:40 +01:00
|
|
|
|
|
|
|
|
|
|
|
####################
|
|
|
|
# - Blender Registration
|
|
|
|
####################
|
|
|
|
BL_REGISTER = [
|
|
|
|
JSONFileExporterSaveJSON,
|
2024-02-26 16:16:06 +01:00
|
|
|
JSONFileExporterNode,
|
2024-02-14 12:33:40 +01:00
|
|
|
]
|
|
|
|
BL_NODES = {
|
2024-03-10 11:56:37 +01:00
|
|
|
ct.NodeType.JSONFileExporter: (
|
|
|
|
ct.NodeCategory.MAXWELLSIM_OUTPUTS_EXPORTERS
|
2024-02-14 12:33:40 +01:00
|
|
|
)
|
|
|
|
}
|