Skip to content

Voronoi: replace in-house tessellation with a real geometry library (CGAL / Voro++ / boost::polygon) #70

Description

@petlenz

Motivation

Both Voronoi generators are currently hand-rolled, with documented complexity / scale ceilings:

  • voronoi_generator_2d (include/rvegen/generators/voronoi_generator_2d.h): Sutherland–Hodgman half-plane clipping. Each cell starts as the bounding rectangle and is clipped against the bisector of every other seed — O(N²) per build, fine for hundreds of seeds, no external dep.
  • voronoi_generator_3d (include/rvegen/generators/voronoi_generator_3d.h): brute-force half-space-triplet vertex enumeration with Eigen PartialPivLU for the 3×3 solves. O(N⁵) — caps out around ~50 seeds. The header explicitly flags this: "beyond that, switch to a real Voronoi library (Voro++, CGAL)."

This sits in tension with our general preference for established geometry libraries over re-inventing primitives. The current code is correct (partition-of-unity invariant is tested in 2D and 3D), but it's a known scaling cliff and a maintenance burden when more sophisticated cases come up (weighted Voronoi / power diagrams, anisotropic seeds, periodic Voronoi on a torus, Laguerre cells for polydisperse grain packing, etc.).

Options

Library 2D 3D Bounded cells License Notes
CGAL Voronoi_diagram_2 ✅ via Periodic_3_regular_triangulation_3 + dual GPL / commercial dual Industrial-strength; periodic-3D support is the standout feature for RVE workflows. Heavyweight build dep.
Voro++ ✅ native ✅ native (this is its whole point) BSD-3 Header + small .cc; designed for exactly this use case; supports walls, periodicity, polydisperse (radical) cells. No 2D.
boost::polygon voronoi_diagram Requires our own clipping Boost (already in tree) Drop-in for 2D, integer-coord flavored — needs a small wrapper for double-precision unit-box coords. No 3D.
GTE (already vendored) Delaunay only (Delaunay2/3) Delaunay only Boost-like Would still leave us implementing the dual + clipping ourselves. Not a real fit.

Proposed scope

Not a single PR. Suggest splitting:

  1. 3D first (highest payoff — replaces the O(N⁵) ceiling). Most likely Voro++ for the BSD license and surgical scope. CGAL's periodic 3D Voronoi is the alternative if we want periodic polycrystal RVEs.
  2. 2D as a follow-up. Lower priority since current Sutherland–Hodgman is correct and scales fine for typical RVE sizes. boost::polygon is the obvious swap since Boost is already a tree dep.
  3. Keep the current implementations behind a compile-time / runtime knob for the first round so we can A/B them and confirm the new backends reproduce the partition-of-unity tests bit-for-bit before deleting the in-house code.

Acceptance criteria

  • Existing 2D and 3D partition-of-unity tests pass against the new backend.
  • New regression test exercising N = 200+ seeds in 3D in under a second (validates we actually escaped the O(N⁵) cliff).
  • voronoi_to_shapes(gen) / convex_polygon output shape stays the same — downstream svg_writer / vtk_legacy_writer paths don't change.
  • The dep choice doesn't break the header-only contract for non-polycrystal users — gate the new generator behind a CMake option (e.g. RVEGEN_WITH_VORO_PP=ON) so consumers who only need circles/spheres don't pay the dep cost.

Out of scope here

  • Weighted / Laguerre / periodic Voronoi — separate follow-up once the library is in.
  • Migration of the test suite to a different convex-polytope representation — keep voronoi_cell / convex_polygon as the public shape.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions