You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Make modmesh's 2D drawing API produce a deterministic image of a World that both the live pilot widget and an offscreen renderer share. This is the foundation for the AI-friendly drawing work: the corpus images an AI model reasons about must be the same pixels a user sees, by construction.
Today R2DWidget renders a World only inside paintEvent (private paintWorld, coupled to widget state). There is no shared render routine, no offscreen QImage path, and no pixel-level test. This milestone closes those gaps and adds the overlay and text representations the experiment's input arms need (A2 overlay, A3 basic state, A4 state+diagnostics; A1 is the raw rendered image).
The work is split into small PRs (each < 500 LOC). PR3 is the gate: nothing downstream is trusted until a known World renders to expected pixels.
PR2 - Offscreen QImage renderer + Python binding. Render a World to a QImage via the PR1 routine with no event loop, and expose a 2D image capture binding (the current capture is R3DWidget-only). Antialiasing toggle for deterministic corpus images. pilot: Add offscreen 2D world renderer and Python binding (issue #754 PR2) #900
PR3 - Real pixel test (gate). Replace the misleading skipped test at tests/test_pilot.py:47. Build a known World, render via PR2, assert non-blank pixels and that known endpoints map to expected pixels under the view transform.
PR5 - World.describe_state(level="basic") (arm A3). Serialize shapes and control points to structured text - only what is also visible in the image, just as text. Add World::describe_state for visible 2D geometry #902
PR6 - describe_state(level="+diagnostics") (arm A4). PR5 plus derived facts: intersections (reusing the polygon_boolean sweep-line) and degeneracies. The "oracle-ish" arm, kept separate so its advantage is attributable to information, not legibility.
Build and prove the 2D World->image rendering path
Related to #754.
Intention
Make modmesh's 2D drawing API produce a deterministic image of a
Worldthat both the live pilot widget and an offscreen renderer share. This is the foundation for the AI-friendly drawing work: the corpus images an AI model reasons about must be the same pixels a user sees, by construction.Today
R2DWidgetrenders aWorldonly insidepaintEvent(privatepaintWorld, coupled to widget state). There is no shared render routine, no offscreenQImagepath, and no pixel-level test. This milestone closes those gaps and adds the overlay and text representations the experiment's input arms need (A2 overlay, A3 basic state, A4 state+diagnostics; A1 is the raw rendered image).The work is split into small PRs (each < 500 LOC). PR3 is the gate: nothing downstream is trusted until a known
Worldrenders to expected pixels.PR list
paint(QPainter&, World&, view)routine. Move the body ofR2DWidget::paintWorldinto a free function with explicit arguments. Pure refactor, pixels unchanged, existing tests stay green. pilot: Extract world render logic into RWorldRenderer2d (issue #754 PR1) #899QImagerenderer + Python binding. Render aWorldto aQImagevia the PR1 routine with no event loop, and expose a 2D image capture binding (the current capture isR3DWidget-only). Antialiasing toggle for deterministic corpus images. pilot: Add offscreen 2D world renderer and Python binding (issue #754 PR2) #900tests/test_pilot.py:47. Build a knownWorld, render via PR2, assert non-blank pixels and that known endpoints map to expected pixels under the view transform.World.describe_state(level="basic")(arm A3). Serialize shapes and control points to structured text - only what is also visible in the image, just as text. Add World::describe_state for visible 2D geometry #902describe_state(level="+diagnostics")(arm A4). PR5 plus derived facts: intersections (reusing thepolygon_booleansweep-line) and degeneracies. The "oracle-ish" arm, kept separate so its advantage is attributable to information, not legibility.