Skip to content

Commit 3fd39ff

Browse files
majinge7846yaugenst-flex
authored andcommitted
feat(plotting): plot3d for scene
1 parent 0a8b215 commit 3fd39ff

File tree

4 files changed

+81
-8
lines changed

4 files changed

+81
-8
lines changed

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2222
- Support for gradients with respect to the `conductivity` of a `CustomMedium`.
2323
- Added `VerticalNaturalConvectionCoeffModel`, a model for heat transfer due to natural convection from a vertical plate. It can be used in `ConvectionBC` to compute the heat transfer coefficient from fluid properties, using standard Nusselt number correlations for both laminar and turbulent flow.
2424
- Added `BroadbandModeABCSpec` class for setting broadband absorbing boundary conditions that can absorb waveguide modes over a specified frequency range using a pole-residue pair model.
25+
- `Scene.plot_3d()` method to make 3D rendering of scene.
2526

2627
### Changed
2728
- Validate mode solver object for large number of grid points on the modal plane.
2829
- Adaptive minimum spacing for `PolySlab` integration is now wavelength relative and a minimum discretization is set for computing gradients for cylinders.
2930
- The `TerminalComponentModeler` defaults to the pseudo wave definition of scattering parameters. The new field `s_param_def` can be used to switch between either pseudo or power wave definitions.
30-
- Add support for `np.unwrap` in `tidy3d.plugins.autograd`.
3131

3232
### Fixed
3333
- Fixed missing amplitude factor and handling of negative normal direction case when making adjoint sources from `DiffractionMonitor`.

tidy3d/components/scene.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@
6969
equal_aspect,
7070
plot_params_fluid,
7171
plot_params_structure,
72+
plot_scene_3d,
7273
polygon_path,
7374
)
7475

@@ -1955,3 +1956,15 @@ def _pcolormesh_shape_doping_box(
19551956
alpha=alpha,
19561957
clip_box=ax.bbox,
19571958
)
1959+
1960+
def plot_3d(self, width=800, height=800) -> None:
1961+
"""Render 3D plot of ``Scene`` (in jupyter notebook only).
1962+
Parameters
1963+
----------
1964+
width : float = 800
1965+
width of the 3d view dom's size
1966+
height : float = 800
1967+
height of the 3d view dom's size
1968+
1969+
"""
1970+
return plot_scene_3d(self, width=width, height=height)

tidy3d/components/viz/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
plot_params_structure,
2424
plot_params_symmetry,
2525
)
26-
from .plot_sim_3d import plot_sim_3d
26+
from .plot_sim_3d import plot_scene_3d, plot_sim_3d
2727
from .styles import (
2828
ARROW_ALPHA,
2929
ARROW_COLOR_ABSORBER,
@@ -81,6 +81,7 @@
8181
"plot_params_source",
8282
"plot_params_structure",
8383
"plot_params_symmetry",
84+
"plot_scene_3d",
8485
"plot_sim_3d",
8586
"polygon_patch",
8687
"polygon_path",

tidy3d/components/viz/plot_sim_3d.py

Lines changed: 65 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,63 @@
55
from tidy3d.exceptions import SetupError
66

77

8-
def plot_sim_3d(sim, width=800, height=800) -> None:
9-
"""Make 3D display of simulation in ipyython notebook."""
8+
def plot_scene_3d(scene, width=800, height=800) -> None:
9+
import gzip
10+
import json
11+
from base64 import b64encode
12+
from io import BytesIO
13+
14+
import h5py
15+
16+
# Serialize scene to HDF5 in-memory
17+
buffer = BytesIO()
18+
scene.to_hdf5(buffer)
19+
buffer.seek(0)
20+
21+
# Open source HDF5 for reading and prepare modified copy
22+
with h5py.File(buffer, "r") as src:
23+
buffer2 = BytesIO()
24+
with h5py.File(buffer2, "w") as dst:
25+
26+
def copy_item(name, obj):
27+
if isinstance(obj, h5py.Group):
28+
dst.create_group(name)
29+
for k, v in obj.attrs.items():
30+
dst[name].attrs[k] = v
31+
elif isinstance(obj, h5py.Dataset):
32+
data = obj[()]
33+
if name == "JSON_STRING":
34+
# Parse and update JSON string
35+
json_str = (
36+
data.decode("utf-8") if isinstance(data, (bytes, bytearray)) else data
37+
)
38+
json_data = json.loads(json_str)
39+
json_data["size"] = list(scene.size)
40+
json_data["center"] = list(scene.center)
41+
json_data["grid_spec"] = {}
42+
new_str = json.dumps(json_data)
43+
dst.create_dataset(name, data=new_str.encode("utf-8"))
44+
else:
45+
dst.create_dataset(name, data=data)
46+
for k, v in obj.attrs.items():
47+
dst[name].attrs[k] = v
48+
49+
src.visititems(copy_item)
50+
buffer2.seek(0)
51+
52+
# Gzip the modified HDF5
53+
gz_buffer = BytesIO()
54+
with gzip.GzipFile(fileobj=gz_buffer, mode="wb") as gz:
55+
gz.write(buffer2.read())
56+
gz_buffer.seek(0)
57+
58+
# Base64 encode and display with gzipped flag
59+
sim_base64 = b64encode(gz_buffer.read()).decode("utf-8")
60+
plot_sim_3d(sim_base64, width=width, height=height, is_gz_base64=True)
61+
62+
63+
def plot_sim_3d(sim, width=800, height=800, is_gz_base64=False) -> None:
64+
"""Make 3D display of simulation in ipython notebook."""
1065

1166
try:
1267
from IPython.display import HTML, display
@@ -19,10 +74,14 @@ def plot_sim_3d(sim, width=800, height=800) -> None:
1974
from base64 import b64encode
2075
from io import BytesIO
2176

22-
buffer = BytesIO()
23-
sim.to_hdf5_gz(buffer)
24-
buffer.seek(0)
25-
base64 = b64encode(buffer.read()).decode("utf-8")
77+
if not is_gz_base64:
78+
buffer = BytesIO()
79+
sim.to_hdf5_gz(buffer)
80+
buffer.seek(0)
81+
base64 = b64encode(buffer.read()).decode("utf-8")
82+
else:
83+
base64 = sim
84+
2685
js_code = """
2786
/**
2887
* Simulation Viewer Injector

0 commit comments

Comments
 (0)