Metadata-Version: 2.4
Name: edge-mender
Version: 0.1.0
Summary: A Topology Repair Algorithm for Voxel Boundary Meshes
Author-email: Matthew Vine <mattvine03@gmail.com>
License-Expression: MIT
Keywords: mesh,manifold,topology,voxel,3d,geometry
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: numpy>=2.3.4
Requires-Dist: scipy>=1.16.3
Requires-Dist: trimesh>=4.9.0
Provides-Extra: utils
Requires-Dist: connected-components-3d>=3.26.1; extra == "utils"
Requires-Dist: fill-voids>=2.1.1; extra == "utils"
Requires-Dist: itk>=5.4.5; extra == "utils"
Requires-Dist: itk-cuberille>=2.7.2; extra == "utils"
Requires-Dist: manifold3d>=3.3.2; extra == "utils"
Requires-Dist: panda3d>=1.10.15; extra == "utils"
Requires-Dist: pandas>=2.3.3; extra == "utils"
Requires-Dist: pyvista>=0.46.4; extra == "utils"
Provides-Extra: dev
Requires-Dist: edge_mender[utils]; extra == "dev"
Requires-Dist: fast-simplification>=0.1.12; extra == "dev"
Requires-Dist: networkx>=3.6; extra == "dev"
Requires-Dist: pre-commit>=4.5.0; extra == "dev"
Requires-Dist: pytest>=9.0.1; extra == "dev"
Requires-Dist: pytest-cov>=7.0.0; extra == "dev"
Requires-Dist: pytest-mock>=3.15.1; extra == "dev"
Requires-Dist: ruff>=0.14.7; extra == "dev"
Requires-Dist: uv>=0.9.14; extra == "dev"
Provides-Extra: examples
Requires-Dist: edge_mender[utils]; extra == "examples"
Requires-Dist: ipykernel>=7.1.0; extra == "examples"
Requires-Dist: ipywidgets>=8.1.8; extra == "examples"
Requires-Dist: networkx>=3.6; extra == "examples"
Requires-Dist: trame>=3.12.0; extra == "examples"
Requires-Dist: trame-server>=3.8.1; extra == "examples"
Requires-Dist: trame-vtk>=2.10.0; extra == "examples"
Requires-Dist: trame-vuetify>=3.1.0; extra == "examples"
Provides-Extra: eval
Requires-Dist: edge_mender[examples,utils]; extra == "eval"
Requires-Dist: nibabel>=5.3.2; extra == "eval"
Requires-Dist: openpyxl>=3.1.5; extra == "eval"
Requires-Dist: tqdm>=4.67.1; extra == "eval"
Dynamic: license-file

# EdgeMender: A Topology Repair Algorithm for Voxel Boundary Meshes

[![pre-commit](https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit)](https://github.com/pre-commit/pre-commit)
[![uv](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/uv/main/assets/badge/v0.json)](https://github.com/astral-sh/uv)
[![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff)
[![Actions status](https://github.com/MattTheCuber/edge-mender/actions/workflows/tests.yml/badge.svg)](https://github.com/MattTheCuber/edge-mender/actions)
<!-- Pytest Coverage Comment:Begin -->
<a href="https://github.com/MattTheCuber/edge-mender/blob/master/README.md"><img alt="Coverage" src="https://img.shields.io/badge/Coverage-100%25-brightgreen.svg" /></a><details><summary>Coverage Report </summary><table><tr><th>File</th><th>Stmts</th><th>Miss</th><th>Cover</th><th>Missing</th></tr><tbody><tr><td colspan="5"><b>edge_mender</b></td></tr><tr><td>&nbsp; &nbsp;<a href="https://github.com/MattTheCuber/edge-mender/blob/master/edge_mender/__init__.py">__init__.py</a></td><td>2</td><td>0</td><td>100%</td><td>&nbsp;</td></tr><tr><td>&nbsp; &nbsp;<a href="https://github.com/MattTheCuber/edge-mender/blob/master/edge_mender/data_factory.py">data_factory.py</a></td><td>135</td><td>0</td><td>100%</td><td>&nbsp;</td></tr><tr><td>&nbsp; &nbsp;<a href="https://github.com/MattTheCuber/edge-mender/blob/master/edge_mender/edge_mender.py">edge_mender.py</a></td><td>172</td><td>0</td><td>100%</td><td>&nbsp;</td></tr><tr><td>&nbsp; &nbsp;<a href="https://github.com/MattTheCuber/edge-mender/blob/master/edge_mender/geometry_helper.py">geometry_helper.py</a></td><td>43</td><td>0</td><td>100%</td><td>&nbsp;</td></tr><tr><td>&nbsp; &nbsp;<a href="https://github.com/MattTheCuber/edge-mender/blob/master/edge_mender/mesh_generator.py">mesh_generator.py</a></td><td>74</td><td>0</td><td>100%</td><td>&nbsp;</td></tr><tr><td>&nbsp; &nbsp;<a href="https://github.com/MattTheCuber/edge-mender/blob/master/edge_mender/visualizer.py">visualizer.py</a></td><td>46</td><td>0</td><td>100%</td><td>&nbsp;</td></tr><tr><td><b>TOTAL</b></td><td><b>472</b></td><td><b>0</b></td><td><b>100%</b></td><td>&nbsp;</td></tr></tbody></table></details>
<!-- Pytest Coverage Comment:End -->

This tool repairs non-manifold edges in voxel boundary meshes to fix downstream operations such as smoothing. Non-manifold edges are defined as edges shared by four faces. Voxel boundary meshes are 3D surface representations of a data set where the faces and vertices perfectly snap to cells in a structured voxel grid. Common uses for this algorithm are repairing output from [Cuberille](https://github.com/InsightSoftwareConsortium/ITKCuberille), [Surface Nets](https://vtk.org/doc/nightly/html/classvtkSurfaceNets3D.html) before smoothing, and non-adaptive [Dual Contouring](https://github.com/Kryolyz/Dual_Contouring_Voxel) implementation without vertex adjustment. The algorithm procedure works for quad meshes, but this implementation is currently limited to triangular meshes (see [#3](https://github.com/MattTheCuber/edge-mender/issues/3)). This algorithm requires input meshes to have proper and consistent winding order.

The three algorithms listed above are provided in the [`mesh_generator`](edge_mender/mesh_generator.py) module. A set of test data sets are provided in the [`data_factory`](edge_mender/data_factory.py) module. A visualization tool is also provided in the [`visualizer`](edge_mender/visualizer.py) module. The [`results`](results) folder contains the [evaluation notebook](results/evaluate.ipynb) and the [example notebook](example.ipynb) demonstrates the tool in use.

## Usage Instructions

`pip install git+https://github.com/MattTheCuber/edge-mender`

```py
from edge_mender import EdgeMender

mesh: trimesh.Trimesh = ...

mender = EdgeMender(mesh)
mender.repair()
```

For a walkthrough example, see the [example notebook](example.ipynb).

## Contributor Instructions

1. Clone the repository using `git clone https://github.com/MattTheCuber/edge-mender.git`
2. Initialize the submodule using `git submodule update --init`
3. [Install uv](https://docs.astral.sh/uv/getting-started/installation)
4. Create a virtual environment using `uv venv`
5. Install all development dependencies using `uv sync --all-extras`
6. Run `pre-commit install`
7. Create a branch and start writing code!
