From 733114b941ff9353f92848b4f72b11a89324273b Mon Sep 17 00:00:00 2001 From: bk_office <2680813175@qq.com> Date: Mon, 27 Apr 2026 21:18:05 +0800 Subject: [PATCH] regex fix --- konabot/plugins/marchtoy/__init__.py | 6 ++-- konabot/plugins/marchtoy/command.py | 23 ++++++++---- konabot/plugins/marchtoy/gl_render.py | 14 ++++---- konabot/plugins/marchtoy/obj.py | 42 +++++++++------------- konabot/plugins/marchtoy/op.py | 2 +- konabot/plugins/marchtoy/scene.py | 13 ++++--- konabot/plugins/marchtoy/shaders/frag.glsl | 2 ++ konabot/plugins/marchtoy/utilities.py | 4 +-- 8 files changed, 58 insertions(+), 48 deletions(-) diff --git a/konabot/plugins/marchtoy/__init__.py b/konabot/plugins/marchtoy/__init__.py index 38026af..f2e5fb0 100644 --- a/konabot/plugins/marchtoy/__init__.py +++ b/konabot/plugins/marchtoy/__init__.py @@ -2,6 +2,7 @@ from nonebot import on_command from nonebot.adapters import Message from nonebot_plugin_alconna import UniMessage from nonebot.params import CommandArg + import konabot.plugins.marchtoy.gl_render as render # import konabot.plugins.marchtoy.cpu_render as render import io @@ -10,10 +11,11 @@ cmd_marchtoy = on_command("march") async def _(args: Message = CommandArg()): if cmd := args.extract_plain_text(): try: - img = await render.render(cmd, (512, 512)) + img = await render.render(cmd, (256, 256)) buffer = io.BytesIO() # img.show() - img.save(buffer, format="PNG") + # img.save("/mnt/d/output.png", format="GIF") + img.save(buffer, format="GIF") buffer.seek(0) await cmd_marchtoy.send(await UniMessage().image(raw=buffer).export()) except Exception as e: diff --git a/konabot/plugins/marchtoy/command.py b/konabot/plugins/marchtoy/command.py index 6ac5bce..9243299 100644 --- a/konabot/plugins/marchtoy/command.py +++ b/konabot/plugins/marchtoy/command.py @@ -16,6 +16,8 @@ example: from dataclasses import dataclass import regex as re from dataclasses import dataclass + + @dataclass class Command: id: str @@ -40,8 +42,10 @@ class CommandChainParser: class CommandParser: - CMD_PATTERN = r"^(([a-zA-Z0-9]+(?:\(([^()]*|(?1)+)(\s*\,\s*(?1))*\))?))" + CMD_PATTERN = r"^[a-zA-Z]+(?:\(([0-9.]+|(([a-zA-Z0-9]+(?:\(([^()]*|(?1)+)(\s*\,\s*(?1))*\))?)(\.(?1))*))(\s*\,\s*(?1))*\))?" ID_PATTERN = r"^[a-zA-Z]+(?=\(|\.|$)" + ARG_PATTERN = CommandChainParser.CHAIN_PATTERN + TRIM_PATTERN = r"^\s*\,\s*" def __init__(self, _command: str) -> None: self.command = _command @@ -53,10 +57,17 @@ class CommandParser: if query := re.match(CommandParser.CMD_PATTERN, self.command): cmd = query[0] if cmd_id_qry := re.match(CommandParser.ID_PATTERN, cmd): - cmd_id = cmd_id_qry[0] + id = cmd_id_qry[0] + cmd_args = cmd[len(id) + 1 : -1] # .replace(" ", "").split(",") + args: list[str] = [] self.command = self.command[len(cmd) + 1 :] - cmd_args = cmd[len(cmd_id) + 1 : -1]#.replace(" ", "").split(",") + while cmd_arg_qry := re.match(CommandParser.ARG_PATTERN, cmd_args): + arg = cmd_arg_qry[0] + args.append(arg) + cmd_args = cmd_args[len(arg) :] + if trim_qry := re.match(CommandParser.TRIM_PATTERN, cmd_args): + cmd_args = cmd_args[len(trim_qry[0]) :] # while "" in cmd_args: - # cmd_args.remove("") - return Command(cmd_id, cmd_args) - raise StopIteration + # cmd_args.remove("") + return Command(id, args) + raise StopIteration \ No newline at end of file diff --git a/konabot/plugins/marchtoy/gl_render.py b/konabot/plugins/marchtoy/gl_render.py index 04cd91d..68ad2d5 100644 --- a/konabot/plugins/marchtoy/gl_render.py +++ b/konabot/plugins/marchtoy/gl_render.py @@ -8,23 +8,23 @@ from PIL import Image from konabot.plugins.marchtoy.scene import Scene from nonebot import logger +PATH = pathlib.Path(__file__).parent / "shaders" +with (PATH / "vert.glsl").open(encoding='utf-8') as f: + VS_SRC = f.read() async def render(command: str, res: tuple[int, int]): fs = Scene(command).compile() - # logger.warning(fs) - PATH = pathlib.Path(__file__).parent / "shaders" - with (PATH / "vert.glsl").open(encoding='utf-8') as f: - vs = f.read() - ctx = moderngl.create_context(standalone=True) + + ctx = moderngl.create_context(standalone=True, backend="egl") ctx.gc_mode = "auto" try: program = ctx.program( - vertex_shader=vs, + vertex_shader=VS_SRC, fragment_shader=fs ) except Exception as e: raise Exception(f"cannot compile glsl: {e}") from e - uniform = program['u_resolution'] + uniform = program["u_resolution"] uniform.write(np.array(res, dtype=np.float32)) vertices = np.array([-1.0, -1.0, -1.0, 1.0, 1.0, -1.0, 1.0, 1.0], dtype=np.float32) indices = np.array([0, 1, 2, 1, 2, 3], dtype=np.int32) diff --git a/konabot/plugins/marchtoy/obj.py b/konabot/plugins/marchtoy/obj.py index b689a6c..e50bcad 100644 --- a/konabot/plugins/marchtoy/obj.py +++ b/konabot/plugins/marchtoy/obj.py @@ -82,7 +82,7 @@ class Object: self.transform: Transform = Transform() self.texture: Texture = Texture() - def parse_args(self, args: str): + def parse_args(self, args: list[str]): raise NotImplementedError def get_transformed(self, p: np.ndarray) -> np.ndarray: @@ -104,7 +104,7 @@ class Cube(Object): self.size = _size def parse_args(self, args: str): - self.size = ArgParser.as_vec3(ArgParser.to_params(args)) + self.size = ArgParser.as_vec3(args) def sdf_block_glsl(self) -> str: return f"sdCube({self.transform.p_expr()}, vec3({self.size[0]}, {self.size[1]}, {self.size[2]}))" @@ -116,7 +116,7 @@ class Sphere(Object): self.radius = _radius def parse_args(self, args: str): - self.radius = ArgParser.as_float(ArgParser.to_params(args)) + self.radius = ArgParser.as_float(args) def sdf_block_glsl(self) -> str: return f"sdSphere({self.transform.p_expr()}, {self.radius})" @@ -130,7 +130,7 @@ class Cylinder(Object): self.height = _height def parse_args(self, args: str): - param = ArgParser.as_vec2(ArgParser.to_params(args)) + param = ArgParser.as_vec2(args) self.radius = param[0] self.height = param[1] @@ -146,8 +146,8 @@ class Torus(Object): self.r1 = _r1 self.r2 = _r2 - def parse_args(self, args: str): - param = ArgParser.as_vec2(ArgParser.to_params(args)) + def parse_args(self, args: list[str]): + param = ArgParser.as_vec2(args) self.r1 = param[0] self.r2 = param[1] @@ -162,8 +162,8 @@ class Capsule(Object): self.h = _h self.r = _r - def parse_args(self, args: str): - param = ArgParser.as_vec2(ArgParser.to_params(args)) + def parse_args(self, args: list[str]): + param = ArgParser.as_vec2(args) self.h = param[0] self.r = param[1] @@ -178,25 +178,17 @@ class Smoothed(Object): self.block_b: str = "INF" self.k: float = _k - def parse_args(self, args: str): + def parse_args(self, args: list[str]): from konabot.plugins.marchtoy.scene import Scene - from konabot.plugins.marchtoy.command import CommandChainParser try: - args = args.replace(" ", "") - cmd_chain_a = next(CommandChainParser(args)) - args = args[len(cmd_chain_a):] - if trim := re.match(r"^[\s]*\,[\s]*", args): - args = args[len(trim[0]):] - cmd_chain_b = next(CommandChainParser(args)) - args = args[len(cmd_chain_b):] - if trim := re.match(r"^[\s]*\,[\s]*", args): - args = args[len(trim[0]):] - scene_a = Scene(cmd_chain_a) - scene_b = Scene(cmd_chain_b) + if not len(args) >= 2: + raise Exception("expecting at least 2 args") + scene_a = Scene(args[0]) + scene_b = Scene(args[1]) self.block_a = scene_a.canvas_objs[0][1] self.block_b = scene_b.canvas_objs[0][1] - # logger.warning(args) - # self.k = ArgParser.as_float(args) + if len(args) > 2: + self.k = ArgParser.as_float(args[2], 0.25) except Exception as e: raise Exception(f"cannot build smoothed object over {args}: {e}") @@ -211,6 +203,6 @@ class Camera(Object): self.focus = _focus self.transform.translate(5.0, 5.0, 5.0).lookat(0.0, 0.0, 0.0) - def parse_args(self, args: str): - self.focus = ArgParser.as_float(ArgParser.to_params(args)) + def parse_args(self, args: list[str]): + self.focus = ArgParser.as_float(args) diff --git a/konabot/plugins/marchtoy/op.py b/konabot/plugins/marchtoy/op.py index a896e42..2d82c1e 100644 --- a/konabot/plugins/marchtoy/op.py +++ b/konabot/plugins/marchtoy/op.py @@ -44,7 +44,7 @@ def color(obj: Object, args: list[str]): col = ArgParser.as_vec4(args) obj.texture.color = (col[0], col[1], col[2], col[3]) else: - raise Exception("unknown color") + raise Exception("invalid argument number") except: raise Exception("unknown color") diff --git a/konabot/plugins/marchtoy/scene.py b/konabot/plugins/marchtoy/scene.py index fe488b5..9954a9d 100644 --- a/konabot/plugins/marchtoy/scene.py +++ b/konabot/plugins/marchtoy/scene.py @@ -3,6 +3,10 @@ import pathlib import numpy as np from nonebot import logger +PATH = pathlib.Path(__file__).parent / "shaders" / "frag.glsl" +with PATH.open(encoding="utf-8") as f: + FS_SRC = f.read() + class Scene: def __init__(self, _instruction: str) -> None: from konabot.plugins.marchtoy.command import CommandChainParser, CommandParser @@ -57,10 +61,8 @@ class Scene: def __str__(self) -> str: return ", ".join([str(type(obj)) for obj in self.canvas_objs]) - def compile(self, fs_src: str = "frag.glsl") -> str: - PATH = pathlib.Path(__file__).parent / "shaders" / fs_src - with PATH.open(encoding="utf-8") as f: - content = f.read() + def compile(self) -> str: + sdf_block: str = "" color_block: str = "" @@ -76,7 +78,8 @@ class Scene: f"{color[0]}, {color[1]}, {color[2]}, {color[3]});\n" ) index += 1 - + + content = FS_SRC content = content.replace("", sdf_block) content = content.replace("", color_block) diff --git a/konabot/plugins/marchtoy/shaders/frag.glsl b/konabot/plugins/marchtoy/shaders/frag.glsl index 10af5d7..b006fff 100644 --- a/konabot/plugins/marchtoy/shaders/frag.glsl +++ b/konabot/plugins/marchtoy/shaders/frag.glsl @@ -1,8 +1,10 @@ #version 330 const float EPS = 0.001; const int MAX_ITER = 64; + uniform vec2 u_resolution; out vec4 fragColor; + struct sdQuery { float value; int obj_id; diff --git a/konabot/plugins/marchtoy/utilities.py b/konabot/plugins/marchtoy/utilities.py index a3103e2..4491654 100644 --- a/konabot/plugins/marchtoy/utilities.py +++ b/konabot/plugins/marchtoy/utilities.py @@ -34,8 +34,8 @@ class ArgParser: x = float(args[0]) return x except: - raise Exception(f"cannot parse {args}") - return default + # raise Exception(f"cannot parse {args}") + return default @staticmethod def as_vec2(