pointtorch 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pointtorch-0.1.0/LICENSE +21 -0
- pointtorch-0.1.0/PKG-INFO +94 -0
- pointtorch-0.1.0/README.md +17 -0
- pointtorch-0.1.0/pyproject.toml +82 -0
- pointtorch-0.1.0/setup.cfg +4 -0
- pointtorch-0.1.0/setup.py +3 -0
- pointtorch-0.1.0/src/pointtorch/__init__.py +3 -0
- pointtorch-0.1.0/src/pointtorch/config/__init__.py +5 -0
- pointtorch-0.1.0/src/pointtorch/config/_optional_dependencies.py +35 -0
- pointtorch-0.1.0/src/pointtorch/core/__init__.py +6 -0
- pointtorch-0.1.0/src/pointtorch/core/_point_cloud.py +149 -0
- pointtorch-0.1.0/src/pointtorch/core/_read.py +35 -0
- pointtorch-0.1.0/src/pointtorch/io/__init__.py +13 -0
- pointtorch-0.1.0/src/pointtorch/io/_base_point_cloud_reader.py +104 -0
- pointtorch-0.1.0/src/pointtorch/io/_base_point_cloud_writer.py +99 -0
- pointtorch-0.1.0/src/pointtorch/io/_csv_reader.py +84 -0
- pointtorch-0.1.0/src/pointtorch/io/_csv_writer.py +80 -0
- pointtorch-0.1.0/src/pointtorch/io/_hdf_reader.py +87 -0
- pointtorch-0.1.0/src/pointtorch/io/_hdf_writer.py +85 -0
- pointtorch-0.1.0/src/pointtorch/io/_las_reader.py +104 -0
- pointtorch-0.1.0/src/pointtorch/io/_las_writer.py +145 -0
- pointtorch-0.1.0/src/pointtorch/io/_point_cloud_io_data.py +19 -0
- pointtorch-0.1.0/src/pointtorch/io/_point_cloud_reader.py +51 -0
- pointtorch-0.1.0/src/pointtorch/io/_point_cloud_writer.py +52 -0
- pointtorch-0.1.0/src/pointtorch/operations/__init__.py +0 -0
- pointtorch-0.1.0/src/pointtorch/operations/numpy/__init__.py +9 -0
- pointtorch-0.1.0/src/pointtorch/operations/numpy/_make_labels_consecutive.py +64 -0
- pointtorch-0.1.0/src/pointtorch/operations/numpy/_voxel_downsampling.py +114 -0
- pointtorch-0.1.0/src/pointtorch/operations/torch/__init__.py +14 -0
- pointtorch-0.1.0/src/pointtorch/operations/torch/_knn_search.py +443 -0
- pointtorch-0.1.0/src/pointtorch/operations/torch/_make_labels_consecutive.py +63 -0
- pointtorch-0.1.0/src/pointtorch/operations/torch/_neighbor_search.py +122 -0
- pointtorch-0.1.0/src/pointtorch/operations/torch/_pack_batch.py +61 -0
- pointtorch-0.1.0/src/pointtorch/operations/torch/_radius_search.py +605 -0
- pointtorch-0.1.0/src/pointtorch/operations/torch/_ravel_index.py +119 -0
- pointtorch-0.1.0/src/pointtorch/operations/torch/_voxel_downsampling.py +135 -0
- pointtorch-0.1.0/src/pointtorch/py.typed +0 -0
- pointtorch-0.1.0/src/pointtorch.egg-info/PKG-INFO +94 -0
- pointtorch-0.1.0/src/pointtorch.egg-info/SOURCES.txt +40 -0
- pointtorch-0.1.0/src/pointtorch.egg-info/dependency_links.txt +1 -0
- pointtorch-0.1.0/src/pointtorch.egg-info/requires.txt +30 -0
- pointtorch-0.1.0/src/pointtorch.egg-info/top_level.txt +1 -0
pointtorch-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 ai4trees
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: pointtorch
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: A Python Package for Deep Learning on 3D Point Clouds Using PyTorch.
|
|
5
|
+
Author-email: Josafat-Mattias Burmeister <burmeister@uni-potsdam.de>
|
|
6
|
+
Maintainer-email: Josafat-Mattias Burmeister <burmeister@uni-potsdam.de>
|
|
7
|
+
License: MIT License
|
|
8
|
+
|
|
9
|
+
Copyright (c) 2024 ai4trees
|
|
10
|
+
|
|
11
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
12
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
13
|
+
in the Software without restriction, including without limitation the rights
|
|
14
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
15
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
16
|
+
furnished to do so, subject to the following conditions:
|
|
17
|
+
|
|
18
|
+
The above copyright notice and this permission notice shall be included in all
|
|
19
|
+
copies or substantial portions of the Software.
|
|
20
|
+
|
|
21
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
22
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
23
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
24
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
25
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
26
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
27
|
+
SOFTWARE.
|
|
28
|
+
|
|
29
|
+
Project-URL: Homepage, https://github.com/ai4trees/pointtorch
|
|
30
|
+
Project-URL: Documentation, https://ai4trees.github.io/pointtorch/
|
|
31
|
+
Project-URL: Repository, https://github.com/ai4trees/pointtorch.git
|
|
32
|
+
Project-URL: Issues, https://github.com/ai4trees/pointtorch/issues
|
|
33
|
+
Project-URL: Changelog, https://ai4trees.github.io/pointtorch/changelog
|
|
34
|
+
Keywords: point cloud,deep learning,pytorch
|
|
35
|
+
Classifier: Development Status :: 4 - Beta
|
|
36
|
+
Classifier: Intended Audience :: Science/Research
|
|
37
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
38
|
+
Classifier: Programming Language :: Python
|
|
39
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
40
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
41
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
42
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
43
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
44
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
45
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
46
|
+
Requires-Python: >=3.9
|
|
47
|
+
Description-Content-Type: text/markdown
|
|
48
|
+
License-File: LICENSE
|
|
49
|
+
Requires-Dist: h5py<4.0.0,>=3.5.0
|
|
50
|
+
Requires-Dist: laspy<3.0.0,>=2.0.0
|
|
51
|
+
Requires-Dist: laszip<3.0.0,>=0.2.0
|
|
52
|
+
Requires-Dist: numpy<3.0.0,>=1.21.0
|
|
53
|
+
Requires-Dist: pandas<3.0.0,>=2.0.0
|
|
54
|
+
Requires-Dist: tables<4.0.0,>=3.8.0
|
|
55
|
+
Requires-Dist: torch<2.5.0,>=2.0.0
|
|
56
|
+
Requires-Dist: torch-cluster<2.0.0,>=1.6.0
|
|
57
|
+
Requires-Dist: torch-scatter<3.0.0,>=2.0.2
|
|
58
|
+
Provides-Extra: dev
|
|
59
|
+
Requires-Dist: black; extra == "dev"
|
|
60
|
+
Requires-Dist: hypothesis; extra == "dev"
|
|
61
|
+
Requires-Dist: mypy; extra == "dev"
|
|
62
|
+
Requires-Dist: pandas-stubs; extra == "dev"
|
|
63
|
+
Requires-Dist: pylint; extra == "dev"
|
|
64
|
+
Requires-Dist: pytest; extra == "dev"
|
|
65
|
+
Requires-Dist: pytest-cov; extra == "dev"
|
|
66
|
+
Provides-Extra: docs
|
|
67
|
+
Requires-Dist: sphinx; extra == "docs"
|
|
68
|
+
Requires-Dist: sphinx-copybutton; extra == "docs"
|
|
69
|
+
Requires-Dist: sphinx-design; extra == "docs"
|
|
70
|
+
Requires-Dist: sphinx-docsearch; extra == "docs"
|
|
71
|
+
Requires-Dist: sphinxawesome-theme; extra == "docs"
|
|
72
|
+
Requires-Dist: sphinx-sitemap; extra == "docs"
|
|
73
|
+
Requires-Dist: sphinxcontrib-jsmath; extra == "docs"
|
|
74
|
+
Requires-Dist: sphinxcontrib-katex; extra == "docs"
|
|
75
|
+
Requires-Dist: sphinxcontrib-napoleon; extra == "docs"
|
|
76
|
+
Requires-Dist: sphinx_mdinclude; extra == "docs"
|
|
77
|
+
|
|
78
|
+
<img src="https://github.com/ai4trees/pointtorch/blob/main/docs/assets/pointtorch-logo-color.png?raw=true" alt="pointtorch" width="328" height="93">
|
|
79
|
+
|
|
80
|
+
## A Python Package for Deep Learning on 3D Point Clouds Using PyTorch.
|
|
81
|
+
|
|
82
|
+

|
|
83
|
+
[](https://opensource.org/licenses/MIT)
|
|
84
|
+
[](https://github.com/ai4trees/pointtorch/actions/workflows/code-quality-main.yml)
|
|
85
|
+
[](https://codecov.io/github/ai4trees/pointtorch?branch=main)
|
|
86
|
+

|
|
87
|
+
|
|
88
|
+
### Package Documentation
|
|
89
|
+
|
|
90
|
+
The documentation of our package is available [here](https://ai4trees.github.io/pointtorch/stable).
|
|
91
|
+
|
|
92
|
+
### Project Setup
|
|
93
|
+
|
|
94
|
+
The setup of our package is described in the [documentation](https://ai4trees.github.io/pointtorch/stable#get-started).
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
<img src="https://github.com/ai4trees/pointtorch/blob/main/docs/assets/pointtorch-logo-color.png?raw=true" alt="pointtorch" width="328" height="93">
|
|
2
|
+
|
|
3
|
+
## A Python Package for Deep Learning on 3D Point Clouds Using PyTorch.
|
|
4
|
+
|
|
5
|
+

|
|
6
|
+
[](https://opensource.org/licenses/MIT)
|
|
7
|
+
[](https://github.com/ai4trees/pointtorch/actions/workflows/code-quality-main.yml)
|
|
8
|
+
[](https://codecov.io/github/ai4trees/pointtorch?branch=main)
|
|
9
|
+

|
|
10
|
+
|
|
11
|
+
### Package Documentation
|
|
12
|
+
|
|
13
|
+
The documentation of our package is available [here](https://ai4trees.github.io/pointtorch/stable).
|
|
14
|
+
|
|
15
|
+
### Project Setup
|
|
16
|
+
|
|
17
|
+
The setup of our package is described in the [documentation](https://ai4trees.github.io/pointtorch/stable#get-started).
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools >=61.0.0", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "pointtorch"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
authors = [
|
|
9
|
+
{name = "Josafat-Mattias Burmeister", email = "burmeister@uni-potsdam.de"},
|
|
10
|
+
]
|
|
11
|
+
maintainers = [
|
|
12
|
+
{name = "Josafat-Mattias Burmeister", email = "burmeister@uni-potsdam.de"},
|
|
13
|
+
]
|
|
14
|
+
description = "A Python Package for Deep Learning on 3D Point Clouds Using PyTorch."
|
|
15
|
+
readme = "README.md"
|
|
16
|
+
license = { file = "LICENSE" }
|
|
17
|
+
classifiers = [
|
|
18
|
+
"Development Status :: 4 - Beta",
|
|
19
|
+
"Intended Audience :: Science/Research",
|
|
20
|
+
"License :: OSI Approved :: MIT License",
|
|
21
|
+
"Programming Language :: Python",
|
|
22
|
+
"Programming Language :: Python :: 3 :: Only",
|
|
23
|
+
"Programming Language :: Python :: 3.9",
|
|
24
|
+
"Programming Language :: Python :: 3.10",
|
|
25
|
+
"Programming Language :: Python :: 3.11",
|
|
26
|
+
"Programming Language :: Python :: 3.12",
|
|
27
|
+
"Programming Language :: Python :: 3.13",
|
|
28
|
+
"Topic :: Scientific/Engineering :: Artificial Intelligence",
|
|
29
|
+
]
|
|
30
|
+
keywords = ["point cloud", "deep learning", "pytorch"]
|
|
31
|
+
requires-python = ">=3.9"
|
|
32
|
+
dependencies = [
|
|
33
|
+
"h5py>=3.5.0, <4.0.0",
|
|
34
|
+
"laspy>=2.0.0, <3.0.0",
|
|
35
|
+
"laszip>=0.2.0, <3.0.0",
|
|
36
|
+
"numpy>=1.21.0, <3.0.0",
|
|
37
|
+
"pandas>=2.0.0, <3.0.0",
|
|
38
|
+
"tables>=3.8.0, <4.0.0",
|
|
39
|
+
"torch>=2.0.0, <2.5.0",
|
|
40
|
+
"torch-cluster>=1.6.0, <2.0.0",
|
|
41
|
+
"torch-scatter>=2.0.2, <3.0.0"
|
|
42
|
+
]
|
|
43
|
+
[project.optional-dependencies]
|
|
44
|
+
dev = [
|
|
45
|
+
"black",
|
|
46
|
+
"hypothesis",
|
|
47
|
+
"mypy",
|
|
48
|
+
"pandas-stubs",
|
|
49
|
+
"pylint",
|
|
50
|
+
"pytest",
|
|
51
|
+
"pytest-cov",
|
|
52
|
+
]
|
|
53
|
+
docs = [
|
|
54
|
+
"sphinx",
|
|
55
|
+
"sphinx-copybutton",
|
|
56
|
+
"sphinx-design",
|
|
57
|
+
"sphinx-docsearch",
|
|
58
|
+
"sphinxawesome-theme",
|
|
59
|
+
"sphinx-sitemap",
|
|
60
|
+
"sphinxcontrib-jsmath",
|
|
61
|
+
"sphinxcontrib-katex",
|
|
62
|
+
"sphinxcontrib-napoleon",
|
|
63
|
+
"sphinx_mdinclude",
|
|
64
|
+
]
|
|
65
|
+
|
|
66
|
+
[project.urls]
|
|
67
|
+
Homepage = "https://github.com/ai4trees/pointtorch"
|
|
68
|
+
Documentation = "https://ai4trees.github.io/pointtorch/"
|
|
69
|
+
Repository = "https://github.com/ai4trees/pointtorch.git"
|
|
70
|
+
Issues = "https://github.com/ai4trees/pointtorch/issues"
|
|
71
|
+
Changelog = "https://ai4trees.github.io/pointtorch/changelog"
|
|
72
|
+
|
|
73
|
+
[tool.semantic_release]
|
|
74
|
+
version_toml = [
|
|
75
|
+
"pyproject.toml:project.version"
|
|
76
|
+
]
|
|
77
|
+
branch = "main"
|
|
78
|
+
changelog_file = "CHANGELOG.md"
|
|
79
|
+
build_command = "python -m build"
|
|
80
|
+
|
|
81
|
+
[tool.setuptools.package-data]
|
|
82
|
+
pointtorch = ["*.typed"]
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
""" Utilities for configuring the package setup. """
|
|
2
|
+
|
|
3
|
+
__all__ = ["open3d_is_available", "pytorch3d_is_available"]
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def open3d_is_available():
|
|
7
|
+
"""
|
|
8
|
+
Returns: `True` if Open3D is installed and `False` otherwise.
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
open3d_available = False
|
|
12
|
+
try:
|
|
13
|
+
from open3d.ml import torch as _ # pylint: disable=import-outside-toplevel
|
|
14
|
+
|
|
15
|
+
open3d_available = True
|
|
16
|
+
except (ModuleNotFoundError, TypeError, Exception): # pylint: disable=broad-exception-caught
|
|
17
|
+
pass
|
|
18
|
+
|
|
19
|
+
return open3d_available
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def pytorch3d_is_available() -> bool:
|
|
23
|
+
"""
|
|
24
|
+
Returns: `True` if PyTorch3D is installed and `False` otherwise.
|
|
25
|
+
"""
|
|
26
|
+
|
|
27
|
+
pytorch3d_available = False
|
|
28
|
+
try:
|
|
29
|
+
import pytorch3d as _ # pylint: disable=import-outside-toplevel
|
|
30
|
+
|
|
31
|
+
pytorch3d_available = True
|
|
32
|
+
except (ModuleNotFoundError, TypeError):
|
|
33
|
+
pass
|
|
34
|
+
|
|
35
|
+
return pytorch3d_available
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
""" Point cloud object. """
|
|
2
|
+
|
|
3
|
+
__all__ = ["PointCloud", "PointCloudSeries"]
|
|
4
|
+
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
from typing import Dict, Hashable, Iterable, List, Optional, Union
|
|
7
|
+
|
|
8
|
+
import numpy as np
|
|
9
|
+
import numpy.typing as npt
|
|
10
|
+
import pandas as pd
|
|
11
|
+
|
|
12
|
+
from pointtorch.io import PointCloudIoData, PointCloudWriter
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class PointCloud(pd.DataFrame):
|
|
16
|
+
"""Point cloud object. Subclass of
|
|
17
|
+
`pd.DataFrame <https://pd.pydata.org/docs/reference/api/pd.DataFrame.html>`_
|
|
18
|
+
|
|
19
|
+
Args:
|
|
20
|
+
identifier: Point cloud identifier. Defaults to `None`.
|
|
21
|
+
x_max_resolution: Maximum resolution of the point cloud's x-coordinates in meter. Defaults to `None`.
|
|
22
|
+
y_max_resolution: Maximum resolution of the point cloud's y-coordinates in meter. Defaults to `None`.
|
|
23
|
+
z_max_resolution: Maximum resolution of the point cloud's z-coordinates in meter. Defaults to `None`.
|
|
24
|
+
|
|
25
|
+
For a documentation of other parameters, see the documentation of \
|
|
26
|
+
`pd.DataFrame <https://pd.pydata.org/docs/reference/api/pd.DataFrame.html>`_.
|
|
27
|
+
|
|
28
|
+
Attributes:
|
|
29
|
+
identifier: Point cloud identifier.
|
|
30
|
+
x_max_resolution: Maximum resolution of the point cloud's x-coordinates in meter.
|
|
31
|
+
y_max_resolution: Maximum resolution of the point cloud's y-coordinates in meter.
|
|
32
|
+
z_max_resolution: Maximum resolution of the point cloud's z-coordinates in meter.
|
|
33
|
+
"""
|
|
34
|
+
|
|
35
|
+
_metadata = ["identifier", "x_max_resolution", "y_max_resolution", "z_max_resolution"]
|
|
36
|
+
|
|
37
|
+
def __init__( # pylint: disable=too-many-positional-arguments
|
|
38
|
+
self,
|
|
39
|
+
data: Union[npt.ArrayLike, Iterable, Dict, pd.DataFrame],
|
|
40
|
+
index: Optional[Union[pd.Index, npt.NDArray[np.int64]]] = None,
|
|
41
|
+
columns: Optional[Union[pd.Index, npt.ArrayLike, List[str]]] = None,
|
|
42
|
+
dtype: Optional[np.dtype] = None,
|
|
43
|
+
copy: Optional[bool] = True,
|
|
44
|
+
identifier: Optional[str] = None,
|
|
45
|
+
x_max_resolution: Optional[float] = None,
|
|
46
|
+
y_max_resolution: Optional[float] = None,
|
|
47
|
+
z_max_resolution: Optional[float] = None,
|
|
48
|
+
) -> None:
|
|
49
|
+
super().__init__(data=data, index=index, columns=columns, dtype=dtype, copy=copy) # type: ignore[call-arg]
|
|
50
|
+
self.identifier = identifier
|
|
51
|
+
self.x_max_resolution = x_max_resolution
|
|
52
|
+
self.y_max_resolution = y_max_resolution
|
|
53
|
+
self.z_max_resolution = z_max_resolution
|
|
54
|
+
|
|
55
|
+
@property
|
|
56
|
+
def _constructor(self):
|
|
57
|
+
return PointCloud
|
|
58
|
+
|
|
59
|
+
@property
|
|
60
|
+
def _constructor_sliced(self):
|
|
61
|
+
return PointCloudSeries
|
|
62
|
+
|
|
63
|
+
def xyz(self) -> npt.NDArray[np.float64]:
|
|
64
|
+
"""
|
|
65
|
+
Returns:
|
|
66
|
+
x, y, and z coordinates of the points in the point cloud.
|
|
67
|
+
|
|
68
|
+
Raises:
|
|
69
|
+
RuntimeError: if "x", "y", or "z" are not in `self.columns`.
|
|
70
|
+
"""
|
|
71
|
+
|
|
72
|
+
if "x" not in self.columns or "y" not in self.columns or "z" not in self.columns:
|
|
73
|
+
raise RuntimeError("The point cloud does not contain xyz coordinates.")
|
|
74
|
+
|
|
75
|
+
return self[["x", "y", "z"]].astype(np.float64).to_numpy()
|
|
76
|
+
|
|
77
|
+
def to(self, file_path: Union[str, Path], columns: Optional[List[str]] = None) -> None:
|
|
78
|
+
"""
|
|
79
|
+
Writes the point cloud to a file.
|
|
80
|
+
|
|
81
|
+
Args:
|
|
82
|
+
file_path: Path of the output file.
|
|
83
|
+
columns: Point cloud columns to be written. The x, y, and z columns are always written.
|
|
84
|
+
|
|
85
|
+
Raises:
|
|
86
|
+
ValueError: If the point cloud format is not supported by the writer or if `columns` contains a column name
|
|
87
|
+
that is not existing in the point cloud.
|
|
88
|
+
"""
|
|
89
|
+
|
|
90
|
+
writer = PointCloudWriter()
|
|
91
|
+
point_cloud_data = PointCloudIoData(
|
|
92
|
+
self,
|
|
93
|
+
identifier=self.identifier,
|
|
94
|
+
x_max_resolution=self.x_max_resolution,
|
|
95
|
+
y_max_resolution=self.y_max_resolution,
|
|
96
|
+
z_max_resolution=self.z_max_resolution,
|
|
97
|
+
)
|
|
98
|
+
writer.write(point_cloud_data, file_path, columns=columns)
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
class PointCloudSeries(pd.Series):
|
|
102
|
+
"""
|
|
103
|
+
A data series that represents a point cloud column. Subclass of
|
|
104
|
+
`pd.Series <https://pd.pydata.org/pandas-docs/stable/reference/api/pd.Series.html>`_.
|
|
105
|
+
|
|
106
|
+
Args:
|
|
107
|
+
identifier: Point cloud identifier. Defaults to `None`.
|
|
108
|
+
x_max_resolution: Maximum resolution of the point cloud's x-coordinates in meter. Defaults to `None`.
|
|
109
|
+
y_max_resolution: Maximum resolution of the point cloud's y-coordinates in meter. Defaults to `None`.
|
|
110
|
+
z_max_resolution: Maximum resolution of the point cloud's z-coordinates in meter. Defaults to `None`.
|
|
111
|
+
|
|
112
|
+
For a documentation of other parameters, see the documentation of \
|
|
113
|
+
`pd.Series <https://pd.pydata.org/pandas-docs/stable/reference/api/pd.Series.html>`_.
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
Attributes:
|
|
117
|
+
identifier: Point cloud identifier.
|
|
118
|
+
x_max_resolution: Maximum resolution of the point cloud's x-coordinates in meter.
|
|
119
|
+
y_max_resolution: Maximum resolution of the point cloud's y-coordinates in meter.
|
|
120
|
+
z_max_resolution: Maximum resolution of the point cloud's z-coordinates in meter.
|
|
121
|
+
"""
|
|
122
|
+
|
|
123
|
+
_metadata = ["identifier", "x_max_resolution", "y_max_resolution", "z_max_resolution"]
|
|
124
|
+
|
|
125
|
+
def __init__( # pylint: disable=too-many-positional-arguments
|
|
126
|
+
self,
|
|
127
|
+
data: Optional[Union[npt.ArrayLike, Iterable, Dict, int, float, str]] = None,
|
|
128
|
+
index: Optional[Union[pd.Index, npt.NDArray[np.int64]]] = None,
|
|
129
|
+
dtype: Optional[Union[str, np.dtype, pd.api.extensions.ExtensionDtype]] = None,
|
|
130
|
+
name: Optional[Hashable] = None,
|
|
131
|
+
copy: Optional[bool] = True,
|
|
132
|
+
identifier: Optional[str] = None,
|
|
133
|
+
x_max_resolution: Optional[float] = None,
|
|
134
|
+
y_max_resolution: Optional[float] = None,
|
|
135
|
+
z_max_resolution: Optional[float] = None,
|
|
136
|
+
) -> None:
|
|
137
|
+
super().__init__(data=data, index=index, dtype=dtype, name=name, copy=copy) # type: ignore[call-arg]
|
|
138
|
+
self.identifier = identifier
|
|
139
|
+
self.x_max_resolution = x_max_resolution
|
|
140
|
+
self.y_max_resolution = y_max_resolution
|
|
141
|
+
self.z_max_resolution = z_max_resolution
|
|
142
|
+
|
|
143
|
+
@property
|
|
144
|
+
def _constructor(self):
|
|
145
|
+
return PointCloudSeries
|
|
146
|
+
|
|
147
|
+
@property
|
|
148
|
+
def _constructor_expanddim(self):
|
|
149
|
+
return PointCloud
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
""" Method for reading point cloud files. """
|
|
2
|
+
|
|
3
|
+
import pathlib
|
|
4
|
+
from typing import List, Optional, Union
|
|
5
|
+
|
|
6
|
+
from pointtorch.core._point_cloud import PointCloud
|
|
7
|
+
from pointtorch.io import PointCloudReader
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def read(file_path: Union[str, pathlib.Path], columns: Optional[List[str]] = None) -> PointCloud:
|
|
11
|
+
"""
|
|
12
|
+
Method for reading point cloud files.
|
|
13
|
+
|
|
14
|
+
Args:
|
|
15
|
+
file_path: Path of the point cloud file to be read.
|
|
16
|
+
columns: Name of the point cloud columns to be read. The x, y, and z columns are always read.
|
|
17
|
+
|
|
18
|
+
Returns:
|
|
19
|
+
Point cloud object.
|
|
20
|
+
|
|
21
|
+
Raises:
|
|
22
|
+
ValueError: If the point cloud format is not supported by the reader.
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
reader = PointCloudReader()
|
|
26
|
+
point_cloud_data = reader.read(file_path, columns=columns)
|
|
27
|
+
point_cloud = PointCloud(
|
|
28
|
+
point_cloud_data.data,
|
|
29
|
+
identifier=point_cloud_data.identifier,
|
|
30
|
+
x_max_resolution=point_cloud_data.x_max_resolution,
|
|
31
|
+
y_max_resolution=point_cloud_data.y_max_resolution,
|
|
32
|
+
z_max_resolution=point_cloud_data.z_max_resolution,
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
return point_cloud
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
""" Tools for reading and writing point cloud files. """
|
|
2
|
+
|
|
3
|
+
from ._csv_reader import *
|
|
4
|
+
from ._csv_writer import *
|
|
5
|
+
from ._hdf_reader import *
|
|
6
|
+
from ._hdf_writer import *
|
|
7
|
+
from ._las_reader import *
|
|
8
|
+
from ._las_writer import *
|
|
9
|
+
from ._point_cloud_io_data import *
|
|
10
|
+
from ._point_cloud_reader import *
|
|
11
|
+
from ._point_cloud_writer import *
|
|
12
|
+
|
|
13
|
+
__all__ = [name for name in globals().keys() if not name.startswith("_")]
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
""" Abstract base class for implementing point cloud file readers. """
|
|
2
|
+
|
|
3
|
+
__all__ = ["BasePointCloudReader"]
|
|
4
|
+
|
|
5
|
+
import abc
|
|
6
|
+
import pathlib
|
|
7
|
+
from typing import List, Optional, Tuple, Union
|
|
8
|
+
|
|
9
|
+
import pandas as pd
|
|
10
|
+
|
|
11
|
+
from ._point_cloud_io_data import PointCloudIoData
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class BasePointCloudReader(abc.ABC):
|
|
15
|
+
"""Abstract base class for implementing point cloud file readers."""
|
|
16
|
+
|
|
17
|
+
@abc.abstractmethod
|
|
18
|
+
def supported_file_formats(self) -> List[str]:
|
|
19
|
+
"""
|
|
20
|
+
Returns:
|
|
21
|
+
File formats supported by the point cloud file reader.
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
def read(self, file_path: Union[str, pathlib.Path], columns: Optional[List[str]] = None) -> PointCloudIoData:
|
|
25
|
+
"""
|
|
26
|
+
Reads a point cloud file.
|
|
27
|
+
|
|
28
|
+
Args:
|
|
29
|
+
file_path: Path of the point cloud file to be read.
|
|
30
|
+
columns: Name of the point cloud columns to be read. The x, y, and z columns are always read.
|
|
31
|
+
|
|
32
|
+
Returns:
|
|
33
|
+
Point cloud object.
|
|
34
|
+
|
|
35
|
+
Raises:
|
|
36
|
+
ValueError: If the point cloud format is not supported by the reader.
|
|
37
|
+
"""
|
|
38
|
+
|
|
39
|
+
if isinstance(file_path, str):
|
|
40
|
+
file_path = pathlib.Path(file_path)
|
|
41
|
+
|
|
42
|
+
file_format = file_path.suffix.lstrip(".")
|
|
43
|
+
if file_format not in self.supported_file_formats():
|
|
44
|
+
raise ValueError(f"The {file_format} format is not supported by the point cloud reader.")
|
|
45
|
+
|
|
46
|
+
identifier = self._read_identifier(file_path)
|
|
47
|
+
file_id = file_path.stem if identifier is None else identifier
|
|
48
|
+
|
|
49
|
+
if columns is not None:
|
|
50
|
+
columns = columns.copy()
|
|
51
|
+
|
|
52
|
+
# The x, y, z coordinates are always loaded.
|
|
53
|
+
for idx, coord in enumerate(["x", "y", "z"]):
|
|
54
|
+
if coord not in columns:
|
|
55
|
+
columns.insert(idx, coord)
|
|
56
|
+
|
|
57
|
+
point_cloud_df = self._read_points(file_path, columns=columns)
|
|
58
|
+
(x_max_resolution, y_max_resolution, z_max_resolution) = self._read_max_resolutions(file_path)
|
|
59
|
+
|
|
60
|
+
return PointCloudIoData(
|
|
61
|
+
point_cloud_df,
|
|
62
|
+
identifier=file_id,
|
|
63
|
+
x_max_resolution=x_max_resolution,
|
|
64
|
+
y_max_resolution=y_max_resolution,
|
|
65
|
+
z_max_resolution=z_max_resolution,
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
@abc.abstractmethod
|
|
69
|
+
def _read_points(self, file_path: pathlib.Path, columns: Optional[List[str]] = None) -> pd.DataFrame:
|
|
70
|
+
"""
|
|
71
|
+
Reads point data from a point cloud file. This method has to be overriden by child classes.
|
|
72
|
+
|
|
73
|
+
Args:
|
|
74
|
+
file_path: Path of the point cloud file to be read.
|
|
75
|
+
columns: Name of the point cloud columns to be read.
|
|
76
|
+
|
|
77
|
+
Returns:
|
|
78
|
+
Point cloud data.
|
|
79
|
+
"""
|
|
80
|
+
|
|
81
|
+
@staticmethod
|
|
82
|
+
@abc.abstractmethod
|
|
83
|
+
def _read_max_resolutions(file_path: pathlib.Path) -> Tuple[Optional[float], Optional[float], Optional[float]]:
|
|
84
|
+
"""
|
|
85
|
+
Reads the maximum resolution for each coordinate dimension from the point cloud file.
|
|
86
|
+
|
|
87
|
+
Args:
|
|
88
|
+
file_path: Path of the point cloud file to be read.
|
|
89
|
+
|
|
90
|
+
Returns:
|
|
91
|
+
Maximum resolution of the x-, y-, and z-coordinates of the point cloud.
|
|
92
|
+
"""
|
|
93
|
+
|
|
94
|
+
@staticmethod
|
|
95
|
+
def _read_identifier(file_path: pathlib.Path) -> Optional[str]: # pylint: disable=unused-argument
|
|
96
|
+
"""
|
|
97
|
+
Reads the point cloud identifier from the point cloud file. Storing a file identifier is not supported by all
|
|
98
|
+
file formats and :code:`None` may be returned when no file identifier is stored in a file.
|
|
99
|
+
|
|
100
|
+
Returns:
|
|
101
|
+
Point cloud identifier.
|
|
102
|
+
"""
|
|
103
|
+
|
|
104
|
+
return None
|