poly-paint is a native C++ application that recreates a reference image with
evolving, semi-transparent polygons. Load an image, choose the initial
population and evolution settings, then let the optimizer iteratively improve a
polygon-based approximation that can be exported as a PNG.
Try poly-paint in your browser.
- Opens a target image through a native file picker and displays both the original and current polygon approximation.
- Evolves polygon collections in the background and reports the generation and best similarity score as it runs.
- Supports randomized and contrast-aware "best guess" starting populations.
- Lets you choose 50, 100, 500, or 1,000 polygons; set parent and offspring population sizes; optionally pause at a generation limit; and pause, resume, or stop a run.
- Provides canvas zoom and saves the current approximation to a PNG file.
- Uses Google Highway for runtime-dispatched, cross-platform SIMD pixel kernels.
The following reference image can be approximated by an evolving polygon collection:
The project requires CMake and a C++23-capable compiler. The first configure step fetches the project dependencies from GitHub.
cmake --preset clang-release
cmake --build --preset build-clang-release
./build/clang-release/poly_paint
ctest --test-dir build/clang-release --output-on-failurecmake --preset msvc-release
cmake --build --preset build-msvc-release
.\build\msvc-release\Release\poly_paint.exeRun the core regression tests for the MSVC build:
ctest --test-dir build\msvc-release -C Release --output-on-failureInstall and activate the Emscripten SDK,
then configure CMake through emcmake so it uses the WebAssembly toolchain:
source /path/to/emsdk/emsdk_env.sh
emcmake cmake --preset wasm-release
cmake --build --preset build-wasm-releaseThe deployable page and its JavaScript, WebAssembly, and worker files are
written to build/wasm-release. Test it locally with the included server:
python3 web/serve.py build/wasm-releaseThen open http://127.0.0.1:8080/poly_paint.html. The local server adds the cross-origin isolation headers required by the application's worker threads. Opening the generated HTML directly from disk will not work.
Deploy every generated file from build/wasm-release together. The build also
copies a _headers file for static hosts that support that convention. On
other servers, configure these response headers for the application and its
assets:
Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corp
Cross-Origin-Resource-Policy: same-origin
The server must serve .wasm files as application/wasm. The browser build
uses WebGL 2 and WebAssembly threads, provides a browser-native image picker,
and downloads PNG exports instead of writing to the visitor's filesystem.
The interface is built with Dear ImGui, GLFW, and OpenGL 3.3. Image loading and PNG export use stb, Google Highway provides portable SIMD, and evolution work is coordinated on background threads.
Released under the MIT License.

