Changelog

All notable changes to this project will be documented in this file.

The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.

Unreleased

Changed

  • Replaced make with just and updated all development, test, and documentation commands accordingly. See the new justfile for details.

  • Updated Sphinx packages for documentation.

0.14.0 - (2026-05-11)

Added

  • numba is now an optional dependency. Install with pip install pointcloudset[numba] to enable JIT-accelerated clustering.

Fixed

  • Fixed a major bug on larger pointclouds when radiusoutlier used too much memory and the process was killed.

  • Fixed a similar bug with get_cluster where the process was killed on larger pointclouds due to too much memory usage.

  • Improved speed of clustering with numba by about 10x on larger pointclouds.

  • filter("radiusoutlier", ...) now uses KDTree neighbour counts directly instead of materializing per-point neighbour lists, preserving the expected outlier semantics while avoiding large temporary allocations on dense point clouds.

Changed

  • Internal refactor: moved the main PointCloud.get_cluster() implementation and chunk-budget helper from pointcloudset.pointcloud to pointcloudset.cluster to keep the PointCloud class focused. No user-facing behaviour changes.

  • PointCloud.get_cluster() now uses a KDTree + incremental union-find DBSCAN implementation. Core connectivity is built without materializing a global edge list, keeping memory bounded by per-point neighbourhood queries while preserving cluster labels and take_cluster(-1, labels) noise handling. The union-find inner loops are JIT-compiled with Numba when the optional numba extra is installed (pip install pointcloudset[numba]); a pure-Python fallback is used automatically when Numba is not available.

  • Replaced Makefile with a justfile (just task runner) for all development, test, and documentation commands. CI workflows updated accordingly.

0.13.0 - (2026-05-05)

Changed

  • BREAKING: PointCloud timestamps are now timezone-aware (tzinfo=UTC) instead of naive UTC. If your code compares or serializes timestamps, you must update datetime comparisons to use timezone-aware datetimes or call .replace(tzinfo=None) for naive equivalents.

  • Point cloud file IO is now handled natively for csv, las, xyz, and pcd.

  • csv and xyz text file handling now support both headered and headerless files; csv writes headers by default and xyz writes headerless output by default.

  • Reading functions now support normalize_xyz (default False): files with uppercase coordinate headers (X, Y, Z) now fail with a hint unless you pass normalize_xyz=True to convert them to lowercase x, y, z.

  • PointCloud now uses an internal native geometry view instead of depending on pyntcloud.

  • Access via PointCloud.points.xyz and PointCloud.points.centroid is now deprecated; use PointCloud.xyz and PointCloud.centroid directly.

  • Pandas support has been updated: pandas 2.x and 3.x are supported; pandas 1.x is no longer supported.

Removed

  • BREAKING: PointCloud.to_instance("pyntcloud") and PointCloud.from_instance("pyntcloud", ...) public API removed. The pyntcloud viewer format is no longer supported. Use pandas DataFrame methods directly or use a different viewer library.

  • pyntcloud is no longer a dependency.

0.12.1 - (2026-05-04)

Fixed

  • pointcloudset.__version__ is now resolved from installed package metadata instead of a hardcoded literal in __init__.py, preventing out-of-sync version strings.

  • Sphinx documentation version resolution now reads package metadata first and falls back to pyproject.toml, keeping published docs aligned with the package version source of truth.

0.12.0 - (2026-05-05)

Added

  • plane_segmentation accepts an optional seed parameter (default 42) so the RANSAC random state can be controlled by the caller.

  • plane_segmentation now refits the plane via SVD on all inliers after finding the best consensus set, producing a more accurate final model.

  • Input validation with clear ValueError messages for all three open3d replacements:

    • get_cluster: rejects eps <= 0, min_points < 1, and empty PointCloud.

    • take_cluster: rejects a cluster_labels whose length does not match the PointCloud, preventing silent index misalignment. Use cluster_number=-1 to retrieve noise points.

    • plane_segmentation: rejects distance_threshold <= 0, ransac_n < 3, ransac_n > len(pointcloud), num_iterations < 1, and empty PointCloud.

    • filter("radiusoutlier"): rejects nb_points < 1 and radius <= 0.

Fixed

  • PointCloud.plot() showing empty scatter points with Plotly 6.x: removed marker.line from the scatter3d update_traces call. marker.line is a 2D scatter property that Plotly 5.x silently ignored for 3D traces but Plotly 6.x passes to the WebGL renderer, making all points invisible.

  • plane_segmentation distance comparison changed from strict < to <= so points exactly at distance_threshold are included as inliers, consistent with the documented semantics.

Changed

  • removed open3d dependency entirely; replaced with scipy and scikit-learn

  • get_cluster now uses sklearn.cluster.DBSCAN instead of open3d

  • plane_segmentation now uses a pure-numpy SVD-based RANSAC implementation

  • distance-to-nearest diff now uses scipy.spatial.KDTree instead of open3d

  • filter("radiusoutlier", ...) now uses scipy.spatial.KDTree instead of open3d; neighbour queries run in parallel (workers=-1)

  • using numpy >2.2 version for modern features and better performance. Made possible by removing open3d dependency.

Removed

  • PointCloud.to_instance("open3d") and PointCloud.from_instance("open3d", ...) public API removed

  • open3d is no longer a dependency

0.11.0- (2025-05-22)

Added

  • support for exporting of las files

Changed

  • CLI exporting direct via pointcloudset and not via pyntcloud. Therefore currently only las and csv are supported

Fixed

  • wrong help for pointcloudset convert CLI: the bag file or mcap dir needs to come right after the command

0.10.1- (2025-04-28)

Changed

  • using uv for package management

  • using uv base image for docker images

  • using pyarrow for parquet files

0.10.0 - (2024-12-03)

Added

  • support for python 3.11 and open3d 0.18 (which still needs numpy <2)

  • testing for the latest 2 python versions which are supported by the latestt open3d

Changed

  • using pyproject.toml instead of setup.py and for all tool settings

  • no more conda dependency use pure pip and the pre-install the open3d requirments

  • use of official python:3.11-slim docker image

  • using pyproject.toml instead of environment.yml

  • using ruff instead of black and isort

  • github actions now use python base images

  • moved status to Beta

  • make pylas a dependencies, was optional before

Removed

  • conda dependency. It is not needed anymore and works just with pip

  • docker base image, not needed any more. Just use the python one and install the open3d dependencies

Changed

  • using ruff instead of flake8 and pylint

0.9.0 - (2023-03-30)

Added

  • added support for reading ROS2 mcap files

  • added a way to investigate the topic names of PointCloud2 messages inside ROS files with the CLI “$ pointcloudset topics test.bag”

Changed

  • changed the name of the CLI from pointcloudset-convert to pointcloudset like “$ pointcloudset convert -t /os1_cloud_node/points test.bag”

  • pointcloudset convert now defaults to generating a directory named after the bagfile with added _pointcloudset to the directory name

Fixed

  • using nbformat==5.7.0 to avoid error with open3d 0.17

  • deleted blackcellmagic due to errors and not being used

  • documentation of CLI where the examples where wrong

0.8.1 - (2023-03-23)

Added

  • tested with open3d 0.17

  • tested with dask 2023.3.1

  • tested with python 3.10.2 and new versions of pandas and numpy

Changed

  • updated open3d, dask version for the docker image

0.8.0 - (2022-11-13)

Added

  • support for ROS2 files (with SQLite backend). Read them in the same ways as ROS1 bag files

  • support for ROS2 conversion in pointcloudset-convert

0.7.0 - (2022-09-27)

Added

  • added version number to file metadata. If the native file format changes in the future.

  • added tests for large ROS bagfiles

Changed

  • using rosbags as ROS library. This avoids the conflicts of the test explorer and dependency on some poorly maintained libraries.

  • renamed CLI rosbagconvert to pointcloudset-convert since its specific for pointcloudset and not rosbag. Complete rewrite of CLI.

0.6.3 - (2022-06-08)

Fixed

  • added pycryptodomex dependency since the ROS packages do not install it but need it

0.6.2 - (2022-06-03)

Fixed

  • distrubted package installation

0.6.1 - (2022-06-03)

Added

  • bounding_box property for datasets

  • animate method for datasets as an experimental feature

  • limit_less and limit_greater methods to PointCloud

Changed

  • time format to include milliseconds

Fixed

  • better handling of agg with dict queries

0.6.0 - (2022-06-03)

Wrong version due to CI

0.5.1 - (2022-05-30)

Fixed

  • laspy in docker image based. Updated to > 2.00

Added

  • dask distributed library in docker image

0.5.0 - (2022-05-30)

Added

  • better support for data from terrestrial laser scanners

  • has_original_id for datasets. Returns true if all pointclouds have original_id

  • PointCloud.from_file now supports timestamp input or “from_file”

  • diff with “nearest” to calculate distance to nearest point from another pointcloud

Changed

  • time format to 24h PR #45

Fixed

  • fixed typehints after changed open3D API

  • plot overlay larger than length of px.colors.qualitative.Plotly Pr #45

Removed - tqdm dependency (now covered by rich)

0.4.3 - (2022-05-10)

Fixed

  • missing packaged in base image

0.4.2 - (2022-05-10)

Changed

  • better entry point for docker images

  • using pintcloudset docker images for github actions testing

  • streamlined docker images with new base image

Fixed

  • bug with dask 2022.5.0 where meta.json was also read not just the parquet files

0.4.1 - (2022-02-22)

Fixed

  • now raw tag for pypi in rst files

0.4.0 - (2022-02-22)

Added

  • rosbagconvert CLI to export individual frames to pointcloudset dataset or files like

    csv or las.

  • rosbagconvert has new options and structure

Changed

  • bag2daset has more functionallity and a new name: rosbagconvert

  • using rich instead of tqdm

  • using rich as a nice UI for the rosbagconvert

0.3.4 - (2022-02-18)

Fixed

  • now the docker containers runs also on arm64

Changed

  • used open3d version 0.14 as default, which comes with arm wheels

  • use dask version 2022.02 as minimum, as there was a bug with 2021.10 and reading files

  • using Python 3.9 as minimum

0.3.3 - (2021-09-27)

Fixed

  • point_size option had no effect when using overlays

  • writing of dataset with an empty point cloud at the start

0.3.2 - (2021-08-18)

Fixed

  • conda environment name was still “base” now is “pointcloudset”

  • automatic start of pointcloudset conda environment now working

Changed

  • use fixed version number of pointcloudset_base image

0.3.1 - (2021-08-17)

wrong release due to testing of github actions and bump2version

0.3.0 (2021-08-17)

Added

  • random_down_sample method for pointclouds.

Fixed

  • Better handling of plotting large point clouds: warn when number of points is above 300k (issue#18)

Changed

  • set conda environment name to “pointcloudset” not “base”

  • better CD of docker images

  • sticking to semantic versioning

0.2.3 (2021-07-12)

Added

  • empty PointCloud object (issue#6)

  • columns option to generate empty PointClouds with a specific schema (issue#6)

  • support for reading and writing Datasets with empty frames (issue#6)

  • check if all required files are written when saving a dataset