#!/usr/bin/env python3 import re import sys import termios import tty from base64 import standard_b64encode from io import BytesIO def draw_to_terminal(buffer: BytesIO) -> None: write_chunked(a="T", i=1, f=100, q=2, data=buffer.getvalue()) def serialize_gr_command(**cmd) -> bytes: payload = cmd.pop("payload", None) cmd = ",".join(f"{k}={v}" for k, v in cmd.items()) ans = [] w = ans.append w(b"\033_G"), w(cmd.encode("ascii")) if payload: w(b";") w(payload) w(b"\033\\") return b"".join(ans) def write_chunked(**cmd) -> None: data = standard_b64encode(cmd.pop("data")) while data: chunk, data = data[:4096], data[4096:] m = 1 if data else 0 sys.stdout.buffer.write(serialize_gr_command(payload=chunk, m=m, **cmd)) sys.stdout.flush() cmd.clear() def hide_cursor() -> None: sys.stdout.write("\x1b[?25l") sys.stdout.flush() def show_cursor() -> None: sys.stdout.write("\x1b[?25h") sys.stdout.flush() def set_position(y: int, x: int) -> None: sys.stdout.write(f"\x1b[{y};{x}H") sys.stdout.flush() def get_position() -> tuple[int, int]: # Save the current terminal settings fd = sys.stdin.fileno() old_settings = termios.tcgetattr(fd) try: # Set terminal to raw mode tty.setraw(fd) # Send the ESC[6n command to request cursor position sys.stdout.write("\x1b[6n") sys.stdout.flush() # Read the response: ESC [ row ; col R response = "" while True: ch = sys.stdin.read(1) response += ch if ch == "R": break finally: # Restore the terminal settings termios.tcsetattr(fd, termios.TCSANOW, old_settings) # Parse the response using regex match = re.search(r"\[(\d+);(\d+)R", response) if match: y, x = map(int, match.groups()) return y, x else: raise ValueError("Failed to parse cursor position response") if __name__ == "__main__": import pyvista as pv s = pv.Sphere() pl = pv.Plotter() pl.add_mesh(s) b = BytesIO() pl.show() pl.screenshot(b) # i = Image.new("RGB", (100, 100), (0, 0, 0)) # d = ImageDraw.Draw(i) # d.ellipse([(5, 5), (95, 95)]) # d.ellipse([(10, 10), (90, 90)]) # d.line(((50, 0), (50, 100))) # d.line(((0, 50), (100, 50))) draw_to_terminal(b)