Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 13 additions & 13 deletions .github/workflows/testing-and-deployment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,14 @@ jobs:
# fail fast and early to avoid clogging GH Actions
smoke_testing:
runs-on: ubuntu-latest
name: Smoke Testing
name: Source distribution testing
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6

- name: Set up Python
uses: actions/setup-python@v5
uses: actions/setup-python@v6
with:
python-version: '3.12'
python-version: '3.13'

- name: Setup headless display
uses: pyvista/setup-headless-display-action@v4
Expand All @@ -44,7 +44,7 @@ jobs:
cd tests && python -m pytest -v

- name: Upload sdist
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v5
with:
path: ./dist/*.tar.gz
name: fast-simplification-sdist
Expand All @@ -55,12 +55,12 @@ jobs:
needs: smoke_testing

steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6

- name: Setup Python
uses: actions/setup-python@v5
uses: actions/setup-python@v6
with:
python-version: '3.12'
python-version: '3.13'

- name: Setup headless display
uses: pyvista/setup-headless-display-action@v4
Expand Down Expand Up @@ -88,18 +88,18 @@ jobs:
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-2025, macos-14, macos-13]
os: [ubuntu-latest, ubuntu-24.04-arm, windows-latest, macos-latest, macos-15-intel]

steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6

- name: Build wheels
uses: pypa/cibuildwheel@v2.23.3
uses: pypa/cibuildwheel@v3.3.0

- name: List generated wheels
run: ls ./wheelhouse/*

- uses: actions/upload-artifact@v4
- uses: actions/upload-artifact@v5
with:
path: ./wheelhouse/*.whl
name: fast-simplification-wheel-${{ matrix.os }}
Expand All @@ -116,7 +116,7 @@ jobs:
id-token: write # this permission is mandatory for trusted publishing
contents: write # required to create a release
steps:
- uses: actions/download-artifact@v4
- uses: actions/download-artifact@v7
- name: Flatten directory structure
run: |
mkdir -p dist/
Expand Down
4 changes: 2 additions & 2 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ ci:

repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.14.7
rev: v0.14.10
hooks:
- id: ruff
args: [--fix, --exit-non-zero-on-fix]
Expand Down Expand Up @@ -57,6 +57,6 @@ repos:

# this validates our github workflow files
- repo: https://github.com/python-jsonschema/check-jsonschema
rev: 0.35.0
rev: 0.36.0
hooks:
- id: check-github-workflows
76 changes: 45 additions & 31 deletions fast_simplification/simplify.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,19 @@
"""Simplification library."""

from typing import TYPE_CHECKING

import numpy as np
from numpy.typing import NDArray

from . import _simplify
from .utils import ascontiguous

if TYPE_CHECKING:
try:
from pyvista.core.pointset import PolyData
except ModuleNotFoundError:
pass


def _check_args(target_reduction, target_count, n_faces):
"""Check arguments."""
Expand All @@ -27,14 +36,17 @@ def _check_args(target_reduction, target_count, n_faces):

@ascontiguous
def simplify(
points,
triangles,
target_reduction=None,
target_count=None,
agg=7,
verbose=False,
return_collapses=False,
lossless=False,
points: NDArray[np.float64],
triangles: NDArray[np.int32],
target_reduction: float | None = None,
target_count: int | None = None,
agg: float = 7.0,
verbose: bool = False,
return_collapses: bool = False,
lossless: bool = False,
) -> (
tuple[NDArray[np.float64], NDArray[np.int64]]
| tuple[NDArray[np.float64], NDArray[np.int64], NDArray[np.int64]]
):
"""Simplify a triangular mesh.

Expand All @@ -54,21 +66,18 @@ def simplify(
target_count : int, optional
Target number of triangles to reduce mesh to. This may be
used in place of ``target_reduction``, but both cannot be set.
agg : int, optional
Controls how aggressively to decimate the mesh. A value of 10
will result in a fast decimation at the expense of mesh
quality and shape. A value of 0 will attempt to preserve the
original mesh geometry at the expense of time. Setting a low
value may result in being unable to reach the
``target_reduction`` or ``target_count``.
agg : float, default: 7.0
Controls how aggressively to decimate the mesh. A value of 10 will
result in a fast decimation at the expense of mesh quality and shape.
A value of 0 will attempt to preserve the original mesh geometry at the
expense of time. Setting a low value may result in being unable to
reach the ``target_reduction`` or ``target_count``.
verbose : bool, optional
Enable verbose output when simplifying the mesh.
return_collapses : bool, optional
If True, return the history of collapses as a
``(n_collapses, 2)`` array of indices.
``collapses[i] = [i0, i1]`` means that durint the i-th
collapse, the vertex ``i1`` was collapsed into the vertex
``i0``.
If True, return the history of collapses as a ``(n_collapses, 2)``
array of indices. ``collapses[i] = [i0, i1]`` means that durint the
i-th collapse, the vertex ``i1`` was collapsed into the vertex ``i0``.
lossless : bool, optional
If True, simplify the mesh losslessly.

Expand Down Expand Up @@ -158,28 +167,33 @@ def simplify(
return points, faces


def simplify_mesh(mesh, target_reduction=None, target_count=None, agg=7, verbose=False):
def simplify_mesh(
mesh: "PolyData",
target_reduction: float | None = None,
target_count: int | None = None,
agg: float = 7.0,
verbose: bool = False,
):
"""Simplify a pyvista mesh.

Parameters
----------
mesh : pyvista.PolyData
PyVista mesh.
target_reduction : float
Fraction of the original mesh to remove. If set to ``0.9``,
Fraction of the original mesh to remove. If set to ``0.9``,
this function will try to reduce the data set to 10% of its
original size and will remove 90% of the input triangles. Use
this parameter or ``target_count``.
target_count : int, optional
Target number of triangles to reduce mesh to. This may be
used in place of ``target_reduction``, but both cannot be set.
agg : int, optional
Controls how aggressively to decimate the mesh. A value of 10
will result in a fast decimation at the expense of mesh
quality and shape. A value of 0 will attempt to preserve the
original mesh geometry at the expense of time. Setting a low
value may result in being unable to reach the
``target_reduction`` or ``target_count``.
Target number of triangles to reduce mesh to. This may be used in
place of ``target_reduction``, but both cannot be set.
agg : float, default: 7.0
Controls how aggressively to decimate the mesh. A value of ``10.0`` will
result in a fast decimation at the expense of mesh quality and shape.
A value of ``0.0`` will attempt to preserve the original mesh geometry at the
expense of time. Setting a low value may result in being unable to
reach the ``target_reduction`` or ``target_count``.
verbose : bool, optional
Enable verbose output when simplifying the mesh.

Expand Down
21 changes: 20 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,31 @@ requires = [

[tool.cibuildwheel]
archs = ["auto64"] # 64-bit only
skip = "cp314-* pp* *musllinux*" # Build CPython 3.9 - 3.13
before-build = "pip install abi3audit"
build = "cp310-* cp311-*" # 3.11+ are abi3 wheels
skip = "*musllinux*"
test-command = "pytest {project}/tests"
test-requires = "pyvista pytest"

[tool.cibuildwheel.linux]
repair-wheel-command = [
"auditwheel repair -w {dest_dir} {wheel}",
"bash tools/audit_wheel.sh {wheel}"
]

[tool.cibuildwheel.macos]
archs = ["native"]
repair-wheel-command = [
"delocate-wheel --require-archs {delocate_archs} -w {dest_dir} -v {wheel}",
"bash tools/audit_wheel.sh {wheel}"
]

[tool.cibuildwheel.windows]
before-build = "pip install delvewheel abi3audit"
repair-wheel-command = [
"delvewheel repair -w {dest_dir} {wheel}",
"bash tools/audit_wheel.sh {wheel}"
]

[tool.codespell]
ignore-words-list = 'THIRDPARTY'
Expand Down
30 changes: 28 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,19 @@
import builtins
from io import open as io_open
import os
import platform
import sys

from setuptools import Extension, setup
from setuptools.command.build_ext import build_ext as _build_ext
from wheel.bdist_wheel import bdist_wheel

filepath = os.path.dirname(__file__)

# Define macros for cython
macros = []
ext_kwargs = {}
setup_kwargs = {"cmdclass": {}}
if os.name == "nt": # windows
extra_compile_args = ["/openmp", "/O2", "/w", "/GS"]
elif os.name == "posix": # linux org mac os
Expand All @@ -28,6 +32,24 @@
macros.append(("IS64BITPLATFORM", None))


# https://github.com/joerick/python-abi3-package-sample/blob/main/setup.py
class bdist_wheel_abi3(bdist_wheel): # noqa: D101
def get_tag(self): # noqa: D102
python, abi, plat = super().get_tag()

if python.startswith("cp"):
return "cp311", "abi3", plat

return python, abi, plat


if sys.version_info.minor >= 11 and platform.python_implementation() == "CPython":
# Can create an abi3 wheel (typed memoryviews first available in 3.11)!
macros.append(("Py_LIMITED_API", "0x030B0000"))
ext_kwargs["py_limited_api"] = True
setup_kwargs["cmdclass"]["bdist_wheel"] = bdist_wheel_abi3


# Get version from version info
__version__ = None
version_file = os.path.join(filepath, "fast_simplification", "_version.py")
Expand Down Expand Up @@ -59,6 +81,8 @@ def build_extensions(self):
_build_ext.build_extensions(self)


setup_kwargs["cmdclass"]["build_ext"] = build_ext

setup(
name="fast_simplification",
packages=["fast_simplification"],
Expand All @@ -73,32 +97,34 @@ def build_extensions(self):
"Development Status :: 4 - Beta",
"Intended Audience :: Science/Research",
"License :: OSI Approved :: MIT License",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Programming Language :: Python :: 3.14",
],
url="https://github.com/pyvista/fast-simplification",
python_requires=">=3.9",
# Build cython modules
cmdclass={"build_ext": build_ext},
ext_modules=[
Extension(
"fast_simplification._simplify",
["fast_simplification/_simplify.pyx"],
language="c++",
extra_compile_args=extra_compile_args,
define_macros=macros,
**ext_kwargs,
),
Extension(
"fast_simplification._replay",
["fast_simplification/_replay.pyx"],
language="c++",
extra_compile_args=extra_compile_args,
define_macros=macros,
**ext_kwargs,
),
],
keywords="fast-simplification decimation",
install_requires=["numpy"],
**setup_kwargs,
)
9 changes: 9 additions & 0 deletions tools/audit_wheel.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#!/bin/bash -eo pipefail
set -x

PY_MINOR=$(python -c "import sys; print(sys.version_info.minor)")
if [ "$PY_MINOR" -lt 11 ]; then
echo "Not checking abi3audit for Python $PY_MINOR < 3.11"
exit 0
fi
abi3audit --strict --report --verbose "$1"