regex fix
This commit is contained in:
@ -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:
|
||||
|
||||
@ -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
|
||||
@ -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)
|
||||
|
||||
@ -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)
|
||||
|
||||
|
||||
@ -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")
|
||||
|
||||
@ -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>", sdf_block)
|
||||
content = content.replace("<COLOR_BLOCK>", color_block)
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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(
|
||||
|
||||
Reference in New Issue
Block a user