remove reliance on pngwriter (slow), grab buffer directly from imgate filter

This commit is contained in:
Felix Pankratz 2025-07-26 16:49:27 +02:00
parent cfeb818190
commit a0376ae9a4

View File

@ -11,6 +11,7 @@ import pyvista as pv
import kitty import kitty
import numpy as np
class TerminalPlotter(pv.Plotter): class TerminalPlotter(pv.Plotter):
def __init__(self, width, height, **kwargs): def __init__(self, width, height, **kwargs):
@ -21,11 +22,9 @@ class TerminalPlotter(pv.Plotter):
# setup vtk rendering chain # 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.ReadFrontBufferOn()
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 # enable transparency
self.set_background([0.0, 0.0, 0.0]) self.set_background([0.0, 0.0, 0.0])
self.ren_win.SetAlphaBitPlanes(1) self.ren_win.SetAlphaBitPlanes(1)
@ -80,14 +79,25 @@ class TerminalPlotter(pv.Plotter):
termios.tcsetattr(fd, termios.TCSADRAIN, old_settings) termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
async def _render_loop(self): async def _render_loop(self):
import time
while self._running: while self._running:
start = time.perf_counter()
# keep renedring the scene # keep renedring the scene
self.ren_win.Render() self.ren_win.Render()
# 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()
np_image = numpy_support.vtk_to_numpy(vtk_array).reshape(height, width, 4)
np_image = np_image[::-1] # Flip vertically
np_image = np.ascontiguousarray(np_image) # Ensure memory layout is C-contiguous
print("Render & copy:", time.perf_counter() - start)
#await kitty.draw_to_terminal(np_image, width, height, compress=True)
await kitty.draw_to_terminal(np_image, width, height, use_shm=True)
print("Draw:", time.perf_counter() - start)
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)
@ -100,3 +110,13 @@ class TerminalPlotter(pv.Plotter):
] ]
await asyncio.wait(tasks, return_when=asyncio.FIRST_COMPLETED) await asyncio.wait(tasks, return_when=asyncio.FIRST_COMPLETED)
self._running = False self._running = False
async def main():
plotter = TerminalPlotter(1000, 1000)
mesh = pv.Sphere()
plotter.add_mesh(mesh)
await plotter.run()
if __name__ == '__main__':
import cProfile
cProfile.run("asyncio.run(main())", "profile")