💎 rendering magic

This commit is contained in:
Felix Pankratz 2025-07-22 23:10:39 +02:00
parent 1d6ccaf5bb
commit 901c1e2a17
2 changed files with 9 additions and 18 deletions

View File

@ -12,7 +12,7 @@ import fcntl
async def draw_to_terminal(buffer: BytesIO) -> None: async def draw_to_terminal(buffer: BytesIO) -> None:
"""Display a PNG image in the terminal.""" """Display a PNG image in the terminal."""
await _write_chunked(a="T", i=1, f=100, q=2, data=buffer.getvalue()) await _write_chunked(a="T", i=1, f=100, q=2, data=buffer)
async def get_terminal_cell_size() -> tuple[int, int]: async def get_terminal_cell_size() -> tuple[int, int]:

View File

@ -21,15 +21,20 @@ class TerminalPlotter(pv.Plotter):
self.width = width self.width = width
self.height = height self.height = height
self._running = True self._running = True
# setup vtk rendering chain
self.w2i_filter = vtk.vtkWindowToImageFilter() self.w2i_filter = vtk.vtkWindowToImageFilter()
self.w2i_filter.SetInputBufferTypeToRGBA() self.w2i_filter.SetInputBufferTypeToRGBA()
self.w2i_filter.ReadFrontBufferOff() self.w2i_filter.ReadFrontBufferOff()
self.w2i_filter.SetInput(self.ren_win) self.w2i_filter.SetInput(self.ren_win)
self.writer = vtk.vtkPNGWriter()
self.writer.WriteToMemoryOn()
self.writer.SetInputConnection(self.w2i_filter.GetOutputPort())
# enable transparency
self.set_background([0.0, 0.0, 0.0]) self.set_background([0.0, 0.0, 0.0])
# transparency
self.ren_win.SetAlphaBitPlanes(1) self.ren_win.SetAlphaBitPlanes(1)
self.ren_win.SetMultiSamples(0) self.ren_win.SetMultiSamples(0)
async def initialize(self): async def initialize(self):
h_pix, _ = await kitty.get_terminal_cell_size() h_pix, _ = await kitty.get_terminal_cell_size()
self.rows, _ = kitty.get_terminal_size() self.rows, _ = kitty.get_terminal_size()
@ -84,22 +89,8 @@ class TerminalPlotter(pv.Plotter):
# Update the filter to grab the current buffer # Update the filter to grab the current buffer
self.w2i_filter.Modified() self.w2i_filter.Modified()
self.w2i_filter.Update() self.w2i_filter.Update()
self.writer.Write()
vtk_image = self.w2i_filter.GetOutput() await kitty.draw_to_terminal(self.writer.GetResult())
width, height, _ = vtk_image.GetDimensions()
vtk_array = vtk_image.GetPointData().GetScalars()
arr = numpy_support.vtk_to_numpy(vtk_array)
# Reshape the array to height x width x channels (probably 3 or 4)
arr = arr.reshape(height, width, -1)
# Flip vertically because VTK's origin is bottom-left
arr = np.flip(arr, axis=0)
img = Image.fromarray(arr)
buffer: BytesIO = BytesIO()
img.save(buffer, format="PNG")
await kitty.draw_to_terminal(buffer)
kitty.set_position(self.start_y, self.start_x) kitty.set_position(self.start_y, self.start_x)
self.camera.Azimuth(1) self.camera.Azimuth(1)