Skip to content

feature: scene support plot3d #2730

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from
Open

Conversation

majinge7846
Copy link
Contributor

@majinge7846 majinge7846 commented Aug 11, 2025

Greptile Summary

This PR adds 3D visualization support for Scene objects in the Tidy3D framework. The implementation introduces a new plot_scene_3d function that enables users to visualize Scene geometries in Jupyter notebooks using the existing 3D plotting infrastructure.

The core approach involves creating a compatibility layer between Scene objects and the existing plot_sim_3d visualization system. Since Scene objects lack simulation-specific properties like grid specifications, the implementation serializes the Scene to HDF5 format, modifies the JSON metadata to include scene-specific properties (size, center, and an empty grid_spec), compresses the data, and passes it to the existing 3D viewer.

The changes span three files: adding the function to the viz module's public API (__init__.py), implementing the core plot_scene_3d function and modifying plot_sim_3d to handle pre-encoded data (plot_sim_3d.py), and adding a convenient plot_3d method to the Scene class (scene.py). This design maintains separation of concerns by keeping complex visualization logic in the dedicated viz module while providing an intuitive interface on the Scene class.

The implementation reuses the existing JavaScript-based 3D viewer infrastructure, avoiding code duplication while extending visualization capabilities to Scene objects that represent geometric and material properties common to all simulation types.

Important Files Changed

File Changes Summary
Filename Score Overview
tidy3d/components/viz/__init__.py 4/5 Adds plot_scene_3d to public API exports and imports
tidy3d/components/scene.py 1/5 Critical indentation issue makes plot_3d a standalone function instead of class method
tidy3d/components/viz/plot_sim_3d.py 2/5 Implements plot_scene_3d with variable scope issues and misleading parameter names

Confidence score: 1/5

  • This PR has critical implementation issues that make it completely unsafe to merge
  • Score reflects fundamental problems including incorrect indentation that completely breaks the intended Scene method functionality and variable scope errors
  • Pay close attention to tidy3d/components/scene.py where the indentation issue makes the method unusable and tidy3d/components/viz/plot_sim_3d.py where variable scope issues will cause runtime errors

Sequence Diagram

sequenceDiagram
    participant User
    participant Scene
    participant plot_scene_3d
    participant BytesIO
    participant h5py
    participant JSON
    participant gzip
    participant base64
    participant plot_sim_3d
    participant IPython
    participant Browser
    
    User->>Scene: "plot_3d(width=800, height=800)"
    Scene->>plot_scene_3d: "plot_scene_3d(self, width, height)"
    
    plot_scene_3d->>BytesIO: "BytesIO()"
    plot_scene_3d->>Scene: "to_hdf5(buffer)"
    plot_scene_3d->>h5py: "File(buffer, 'r')"
    
    loop "for each item in HDF5"
        h5py->>plot_scene_3d: "visititems(copy_item)"
        alt "if name == 'JSON_STRING'"
            plot_scene_3d->>JSON: "loads(json_str)"
            plot_scene_3d->>JSON: "update with scene.size, scene.center, empty grid_spec"
            plot_scene_3d->>JSON: "dumps(json_data)"
        end
    end
    
    plot_scene_3d->>gzip: "GzipFile(fileobj=gz_buffer, mode='wb')"
    plot_scene_3d->>base64: "b64encode(gz_buffer.read())"
    plot_scene_3d->>plot_sim_3d: "plot_sim_3d(sim_base64, width, height, is_gz_base64=True)"
    
    plot_sim_3d->>IPython: "from IPython.display import HTML, display"
    plot_sim_3d->>Browser: "display(HTML(html_code))"
    
    Note over Browser: "JavaScript injector creates iframe"
    Note over Browser: "Iframe loads viewer from tidy3d.simulation.cloud"
    Note over Browser: "PostMessage API transfers simulation data"
    
    Browser-->>User: "3D visualization rendered"
Loading

Copy link

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR adds 3D plotting support for Scene objects by introducing a new plot_scene_3d function that adapts Scene data for visualization through the existing simulation viewer infrastructure.

  • Adds plot_scene_3d function that converts Scene objects to a format compatible with the 3D viewer
  • Modifies plot_sim_3d to accept pre-encoded data via a new is_gz_base64 parameter
  • Adds a plot_3d method to the Scene class for convenient 3D visualization

Reviewed Changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 5 comments.

File Description
tidy3d/components/viz/plot_sim_3d.py Implements plot_scene_3d function and modifies plot_sim_3d to support pre-encoded data
tidy3d/components/viz/init.py Exports the new plot_scene_3d function
tidy3d/components/scene.py Adds plot_3d method to Scene class

Copy link

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

3 files reviewed, 4 comments

Edit Code Review Bot Settings | Greptile

Copy link

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

3 files reviewed, no comments

Edit Code Review Bot Settings | Greptile

Copy link
Contributor

Diff Coverage

Diff: origin/develop...HEAD, staged and unstaged changes

  • tidy3d/components/scene.py (50.0%): Missing lines 1970
  • tidy3d/components/viz/init.py (100%)
  • tidy3d/components/viz/plot_sim_3d.py (15.6%): Missing lines 9-12,14,17-19,22-24,26-33,35,38-43,45-47,49-50,53-56,59-60,83

Summary

  • Total: 48 lines
  • Missing: 39 lines
  • Coverage: 18%

tidy3d/components/scene.py

Lines 1966-1971

  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/plot_sim_3d.py

Lines 5-64

   5 from tidy3d.exceptions import SetupError
   6 
   7 
   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."""

Lines 79-87

  79         sim.to_hdf5_gz(buffer)
  80         buffer.seek(0)
  81         base64 = b64encode(buffer.read()).decode("utf-8")
  82     else:
! 83         base64 = sim
  84 
  85     js_code = """
  86         /**
  87         * Simulation Viewer Injector

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant