torch-pointcloud 0.0.1__py3-none-any.whl

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.
Files changed (149) hide show
  1. torch_pointcloud/__init__.py +23 -0
  2. torch_pointcloud/config.py +63 -0
  3. torch_pointcloud/datasets/__init__.py +18 -0
  4. torch_pointcloud/datasets/concat.py +161 -0
  5. torch_pointcloud/datasets/kitti.py +544 -0
  6. torch_pointcloud/datasets/mix.py +56 -0
  7. torch_pointcloud/datasets/modelnet.py +679 -0
  8. torch_pointcloud/datasets/nuscenes.py +849 -0
  9. torch_pointcloud/datasets/parislille3d.py +177 -0
  10. torch_pointcloud/datasets/pointcloud.py +78 -0
  11. torch_pointcloud/datasets/repeat.py +27 -0
  12. torch_pointcloud/datasets/s3dis.py +886 -0
  13. torch_pointcloud/datasets/scannet.py +1427 -0
  14. torch_pointcloud/datasets/scanobjectnn.py +238 -0
  15. torch_pointcloud/datasets/semantic3d.py +206 -0
  16. torch_pointcloud/datasets/semantickitti.py +417 -0
  17. torch_pointcloud/datasets/shapenetpart.py +326 -0
  18. torch_pointcloud/datasets/sunrgbd.py +487 -0
  19. torch_pointcloud/datasets/toronto3d.py +207 -0
  20. torch_pointcloud/datasets/utils.py +334 -0
  21. torch_pointcloud/inferers/__init__.py +10 -0
  22. torch_pointcloud/inferers/_utils.py +78 -0
  23. torch_pointcloud/inferers/inferer.py +88 -0
  24. torch_pointcloud/inferers/knn_window.py +355 -0
  25. torch_pointcloud/inferers/part_refinement.py +164 -0
  26. torch_pointcloud/inferers/potential_sphere.py +287 -0
  27. torch_pointcloud/inferers/simple.py +41 -0
  28. torch_pointcloud/inferers/sliding_window.py +498 -0
  29. torch_pointcloud/inferers/tta.py +221 -0
  30. torch_pointcloud/inferers/voxel_partition.py +157 -0
  31. torch_pointcloud/layers/__init__.py +101 -0
  32. torch_pointcloud/layers/_modules.py +42 -0
  33. torch_pointcloud/layers/act.py +31 -0
  34. torch_pointcloud/layers/affine.py +86 -0
  35. torch_pointcloud/layers/anchors.py +654 -0
  36. torch_pointcloud/layers/bev_backbone.py +210 -0
  37. torch_pointcloud/layers/conv2d_blocks.py +69 -0
  38. torch_pointcloud/layers/conv3d_blocks.py +66 -0
  39. torch_pointcloud/layers/dropouts.py +74 -0
  40. torch_pointcloud/layers/fps.py +41 -0
  41. torch_pointcloud/layers/geometric_affine.py +157 -0
  42. torch_pointcloud/layers/grid_pool.py +125 -0
  43. torch_pointcloud/layers/linear_blocks.py +75 -0
  44. torch_pointcloud/layers/norms.py +81 -0
  45. torch_pointcloud/layers/octree_attention.py +385 -0
  46. torch_pointcloud/layers/octree_blocks.py +178 -0
  47. torch_pointcloud/layers/pdnorm.py +81 -0
  48. torch_pointcloud/layers/point_patch_embed.py +77 -0
  49. torch_pointcloud/layers/pointconv.py +168 -0
  50. torch_pointcloud/layers/pointconv_sa.py +296 -0
  51. torch_pointcloud/layers/pointnet2_blocks.py +595 -0
  52. torch_pointcloud/layers/pointnext_blocks.py +400 -0
  53. torch_pointcloud/layers/pools.py +266 -0
  54. torch_pointcloud/layers/pvcnn_blocks.py +180 -0
  55. torch_pointcloud/layers/rope.py +75 -0
  56. torch_pointcloud/layers/serialized_attention.py +378 -0
  57. torch_pointcloud/layers/serialized_pool.py +219 -0
  58. torch_pointcloud/layers/spconv_blocks.py +241 -0
  59. torch_pointcloud/layers/tnet.py +221 -0
  60. torch_pointcloud/layers/transformer.py +172 -0
  61. torch_pointcloud/layers/vfe.py +161 -0
  62. torch_pointcloud/layers/view.py +27 -0
  63. torch_pointcloud/layers/xconv.py +164 -0
  64. torch_pointcloud/lightning/__init__.py +17 -0
  65. torch_pointcloud/lightning/callbacks.py +200 -0
  66. torch_pointcloud/lightning/datamodule.py +229 -0
  67. torch_pointcloud/lightning/metrics.py +445 -0
  68. torch_pointcloud/lightning/module.py +443 -0
  69. torch_pointcloud/losses/__init__.py +25 -0
  70. torch_pointcloud/losses/_utils.py +11 -0
  71. torch_pointcloud/losses/anchor.py +551 -0
  72. torch_pointcloud/losses/center.py +494 -0
  73. torch_pointcloud/losses/chamfer.py +58 -0
  74. torch_pointcloud/losses/detr3d.py +474 -0
  75. torch_pointcloud/losses/lovasz.py +76 -0
  76. torch_pointcloud/losses/pointrcnn.py +356 -0
  77. torch_pointcloud/losses/sum.py +25 -0
  78. torch_pointcloud/losses/transfusion.py +295 -0
  79. torch_pointcloud/losses/votenet.py +264 -0
  80. torch_pointcloud/models/__init__.py +39 -0
  81. torch_pointcloud/models/_base.py +249 -0
  82. torch_pointcloud/models/_registry.py +506 -0
  83. torch_pointcloud/models/concerto.py +383 -0
  84. torch_pointcloud/models/detr3d.py +1127 -0
  85. torch_pointcloud/models/dgcnn.py +929 -0
  86. torch_pointcloud/models/kpconv.py +1596 -0
  87. torch_pointcloud/models/lion.py +1368 -0
  88. torch_pointcloud/models/octformer.py +1267 -0
  89. torch_pointcloud/models/point_bert.py +1133 -0
  90. torch_pointcloud/models/point_m2ae.py +1325 -0
  91. torch_pointcloud/models/point_mae.py +1108 -0
  92. torch_pointcloud/models/point_mamba.py +1207 -0
  93. torch_pointcloud/models/point_transformer.py +1119 -0
  94. torch_pointcloud/models/point_transformer_v2.py +1281 -0
  95. torch_pointcloud/models/point_transformer_v3.py +1740 -0
  96. torch_pointcloud/models/pointcnn.py +637 -0
  97. torch_pointcloud/models/pointconv.py +333 -0
  98. torch_pointcloud/models/pointgpt.py +875 -0
  99. torch_pointcloud/models/pointmlp.py +1039 -0
  100. torch_pointcloud/models/pointnet.py +660 -0
  101. torch_pointcloud/models/pointnet2.py +1112 -0
  102. torch_pointcloud/models/pointnext.py +2090 -0
  103. torch_pointcloud/models/pointpillars.py +610 -0
  104. torch_pointcloud/models/pointrcnn.py +1111 -0
  105. torch_pointcloud/models/pvcnn.py +514 -0
  106. torch_pointcloud/models/pvcnn2.py +913 -0
  107. torch_pointcloud/models/randlanet.py +997 -0
  108. torch_pointcloud/models/second.py +658 -0
  109. torch_pointcloud/models/sonata.py +328 -0
  110. torch_pointcloud/models/spformer_unet.py +572 -0
  111. torch_pointcloud/models/sphereformer.py +883 -0
  112. torch_pointcloud/models/spunet.py +576 -0
  113. torch_pointcloud/models/spvcnn.py +1213 -0
  114. torch_pointcloud/models/utonia.py +351 -0
  115. torch_pointcloud/models/votenet.py +721 -0
  116. torch_pointcloud/models/voxel_mamba.py +834 -0
  117. torch_pointcloud/models/voxelnext.py +608 -0
  118. torch_pointcloud/py.typed +0 -0
  119. torch_pointcloud/transforms/__init__.py +3 -0
  120. torch_pointcloud/transforms/functional.py +1674 -0
  121. torch_pointcloud/transforms/transforms.py +4293 -0
  122. torch_pointcloud/utils/__init__.py +1 -0
  123. torch_pointcloud/utils/box3d.py +643 -0
  124. torch_pointcloud/utils/cluster.py +563 -0
  125. torch_pointcloud/utils/conversion.py +753 -0
  126. torch_pointcloud/utils/data.py +229 -0
  127. torch_pointcloud/utils/diffusion.py +179 -0
  128. torch_pointcloud/utils/ensemble.py +118 -0
  129. torch_pointcloud/utils/geometry.py +489 -0
  130. torch_pointcloud/utils/heatmap.py +277 -0
  131. torch_pointcloud/utils/hilbert.py +216 -0
  132. torch_pointcloud/utils/imports.py +334 -0
  133. torch_pointcloud/utils/io.py +110 -0
  134. torch_pointcloud/utils/metrics.py +1191 -0
  135. torch_pointcloud/utils/misc.py +80 -0
  136. torch_pointcloud/utils/neighbors.py +50 -0
  137. torch_pointcloud/utils/octree.py +212 -0
  138. torch_pointcloud/utils/ops.py +457 -0
  139. torch_pointcloud/utils/optim.py +92 -0
  140. torch_pointcloud/utils/random.py +63 -0
  141. torch_pointcloud/utils/serialization.py +110 -0
  142. torch_pointcloud/utils/state_dict.py +240 -0
  143. torch_pointcloud/utils/types.py +90 -0
  144. torch_pointcloud/utils/voxelization.py +274 -0
  145. torch_pointcloud-0.0.1.dist-info/METADATA +206 -0
  146. torch_pointcloud-0.0.1.dist-info/RECORD +149 -0
  147. torch_pointcloud-0.0.1.dist-info/WHEEL +4 -0
  148. torch_pointcloud-0.0.1.dist-info/licenses/LICENSE +201 -0
  149. torch_pointcloud-0.0.1.dist-info/licenses/THIRD_PARTY_NOTICES.md +87 -0
@@ -0,0 +1,23 @@
1
+ """PyTorch library for 3D point cloud deep learning: models, datasets, transforms, and pretrained weights."""
2
+
3
+ from importlib.metadata import version as _version
4
+
5
+ from . import config, datasets, inferers, layers, losses, models, transforms, utils
6
+ from .models import create_model, list_models, register_model
7
+
8
+ __version__ = _version("torch_pointcloud")
9
+
10
+ __all__ = [
11
+ "__version__",
12
+ "config",
13
+ "create_model",
14
+ "datasets",
15
+ "inferers",
16
+ "layers",
17
+ "list_models",
18
+ "losses",
19
+ "models",
20
+ "register_model",
21
+ "transforms",
22
+ "utils",
23
+ ]
@@ -0,0 +1,63 @@
1
+ """Environment-variable configuration of cache, model, and data directories and randomness defaults.
2
+
3
+ This module contains the following global variables for configuration:
4
+
5
+ | Variable | Description | Default |
6
+ |----------|-------------|---------|
7
+ | `HOME_DIR` | The home directory of the user. | `Path.home().as_posix()` |
8
+ | `CACHE_DIR` | The cache directory for the package. | `Path(HOME_DIR, ".cache", "torch-pointcloud").as_posix()` |
9
+ | `MODELS_DIR` | The directory for the models. | `Path(CACHE_DIR, "models").as_posix()` |
10
+ | `DATA_DIR` | The directory for the data. | `"data"` |
11
+ | `RANDOM_SEED` | The random seed for the package. | `None` |
12
+ | `FPS_RANDOM_START` | Whether to start the random seed from the current time. | `None` |
13
+ | `KNN_DENSE_BUDGET` | The dense budget for the KNN. | `16_000_000` |
14
+ """
15
+
16
+ import os
17
+ from pathlib import Path
18
+ from typing import Optional
19
+
20
+
21
+ def asbool(value: Optional[str]) -> Optional[bool]:
22
+ """Parse an environment variable as a boolean.
23
+
24
+ Args:
25
+ value: The raw variable value, or None when it is unset.
26
+
27
+ Returns:
28
+ True when the value reads as `true`, `1`, `yes` or `y` (case-insensitive), False for anything
29
+ else, and None when the variable is unset.
30
+ """
31
+ if value is None:
32
+ return None
33
+
34
+ return value.strip().lower() in ["true", "1", "yes", "y"]
35
+
36
+
37
+ def asint(value: Optional[str]) -> Optional[int]:
38
+ """Parse an environment variable as an integer.
39
+
40
+ Args:
41
+ value: The raw variable value, or None when it is unset.
42
+
43
+ Returns:
44
+ The parsed integer, or None when the variable is unset or does not parse.
45
+ """
46
+ if value is None:
47
+ return None
48
+
49
+ try:
50
+ return int(value)
51
+ except ValueError:
52
+ return None
53
+
54
+
55
+ HOME_DIR = Path.home().as_posix()
56
+ CACHE_DIR = os.getenv("TORCH_POINTCLOUD_CACHE_DIR", Path(HOME_DIR, ".cache", "torch-pointcloud").as_posix())
57
+ MODELS_DIR = os.getenv("TORCH_POINTCLOUD_MODELS_DIR", Path(CACHE_DIR, "models").as_posix())
58
+ DATA_DIR = os.getenv("TORCH_POINTCLOUD_DATA_DIR", "data")
59
+
60
+ # Some variables to affect how random operations are performed.
61
+ RANDOM_SEED = asint(os.getenv("TORCH_POINTCLOUD_RANDOM_SEED", None))
62
+ FPS_RANDOM_START = asbool(os.getenv("TORCH_POINTCLOUD_FPS_RANDOM_START", None))
63
+ KNN_DENSE_BUDGET = asint(os.getenv("TORCH_POINTCLOUD_KNN_DENSE_BUDGET", None)) or 16_000_000
@@ -0,0 +1,18 @@
1
+ """Benchmark point cloud datasets with disk caching and download helpers."""
2
+
3
+ from .concat import ConcatDataset, SingleDatasetBatchSampler
4
+ from .kitti import KITTI
5
+ from .mix import MixDataset
6
+ from .modelnet import ModelNet10, ModelNet40, ModelNet40Hdf5, ModelNetNormalResampled
7
+ from .nuscenes import NuScenes, NuScenesMini
8
+ from .parislille3d import ParisLille3D
9
+ from .pointcloud import PointCloudDataset
10
+ from .repeat import RepeatDataset
11
+ from .s3dis import S3DIS, S3DISHdf5
12
+ from .scannet import ScanNet, ScanNet20, ScanNet200
13
+ from .scanobjectnn import ScanObjectNN
14
+ from .semantic3d import Semantic3D
15
+ from .semantickitti import SemanticKITTI
16
+ from .shapenetpart import ShapeNetPart
17
+ from .sunrgbd import SunRGBD
18
+ from .toronto3d import Toronto3D
@@ -0,0 +1,161 @@
1
+ """Concatenate several datasets into one flat index space for multi-dataset joint training."""
2
+
3
+ from bisect import bisect_right
4
+ from typing import Any, Iterator, List, Optional, Sequence
5
+
6
+ import torch
7
+ from torch.utils.data import Dataset, Sampler
8
+
9
+
10
+ class ConcatDataset(Dataset):
11
+ """Concatenates several datasets into one flat index space.
12
+
13
+ Each child dataset keeps its own `transform`, so datasets from different domains (e.g. ScanNet and
14
+ S3DIS) train jointly while stamping their own condition key and mapping to their native label space.
15
+ Pair it with `SingleDatasetBatchSampler` to keep every batch single-domain so per-dataset
16
+ normalization statistics (BatchNorm, PDNorm) stay clean.
17
+
18
+ Args:
19
+ datasets: The datasets to concatenate, in order. The first is treated as the main dataset by
20
+ `SingleDatasetBatchSampler` (its exhaustion ends the epoch).
21
+
22
+ Example:
23
+ ```python
24
+ from torch_pointcloud.datasets import ConcatDataset, S3DIS, ScanNet20
25
+
26
+ dataset = ConcatDataset([ScanNet20(root, split="train"), S3DIS(root, areas=["Area_1"])])
27
+ len(dataset) # len(scannet) + len(s3dis)
28
+ dataset.sizes # [len(scannet), len(s3dis)]
29
+ ```
30
+ """
31
+
32
+ def __init__(self, datasets: Sequence[Dataset]) -> None:
33
+ if len(datasets) == 0:
34
+ raise ValueError("ConcatDataset requires at least one dataset.")
35
+ self.datasets = list(datasets)
36
+ self.sizes = [len(d) for d in self.datasets] # type: ignore[arg-type]
37
+ self.cumulative_sizes: List[int] = []
38
+ total = 0
39
+ for size in self.sizes:
40
+ total += size
41
+ self.cumulative_sizes.append(total)
42
+
43
+ def __len__(self) -> int:
44
+ return self.cumulative_sizes[-1]
45
+
46
+ def __getitem__(self, index: int) -> Any:
47
+ if not -len(self) <= index < len(self):
48
+ raise IndexError(f"Index {index} is out of range for a dataset of length {len(self)}.")
49
+ if index < 0:
50
+ index += len(self)
51
+ dataset_index = bisect_right(self.cumulative_sizes, index)
52
+ start = self.cumulative_sizes[dataset_index - 1] if dataset_index > 0 else 0
53
+ return self.datasets[dataset_index][index - start]
54
+
55
+
56
+ class SingleDatasetBatchSampler(Sampler[List[int]]):
57
+ """Yields batches whose global indices all come from one dataset of a `ConcatDataset`.
58
+
59
+ Given the per-dataset sizes and one positive integer ratio per dataset, it partitions each dataset's
60
+ indices into batches of `batch_size` and interleaves the datasets round-robin weighted by the ratios.
61
+ Within a round the first dataset yields `ratios[0]` batches, the second `ratios[1]`, and so on. The
62
+ first (main) dataset drives the epoch length: when it
63
+ is exhausted the epoch ends, while the other datasets restart (reshuffled) as needed. Because every
64
+ yielded batch is drawn from a single dataset, per-batch normalization (BatchNorm, PDNorm) sees a
65
+ single domain.
66
+
67
+ Args:
68
+ sizes: Number of samples in each child dataset, in `ConcatDataset` order.
69
+ ratios: One positive integer sampling weight per dataset, aligned with `sizes`.
70
+ batch_size: Number of indices per batch.
71
+ shuffle: Shuffle each dataset's indices, reshuffling on restart.
72
+ drop_last: Drop each dataset's trailing partial batch.
73
+ generator: Optional `torch.Generator` for shuffling.
74
+
75
+ Shape:
76
+ Each yielded value is a `List[int]` of length `batch_size` (or fewer for a trailing batch when
77
+ `drop_last` is `False`).
78
+
79
+ Example:
80
+ ```python
81
+ from torch.utils.data import DataLoader
82
+
83
+ from torch_pointcloud.datasets import ConcatDataset, SingleDatasetBatchSampler
84
+
85
+ dataset = ConcatDataset([scannet, s3dis])
86
+ sampler = SingleDatasetBatchSampler(dataset.sizes, ratios=[2, 1], batch_size=4)
87
+ loader = DataLoader(dataset, batch_sampler=sampler)
88
+ ```
89
+ """
90
+
91
+ def __init__(
92
+ self,
93
+ sizes: Sequence[int],
94
+ ratios: Sequence[int],
95
+ batch_size: int,
96
+ shuffle: bool = True,
97
+ drop_last: bool = True,
98
+ generator: Optional[torch.Generator] = None,
99
+ ) -> None:
100
+ if len(sizes) != len(ratios):
101
+ raise ValueError(f"sizes and ratios must have the same length, got {len(sizes)} and {len(ratios)}.")
102
+ if any(r <= 0 for r in ratios):
103
+ raise ValueError(f"ratios must be positive integers, got {list(ratios)}.")
104
+ if batch_size <= 0:
105
+ raise ValueError(f"batch_size must be positive, got {batch_size}.")
106
+
107
+ self.sizes = list(sizes)
108
+ self.ratios = list(ratios)
109
+ self.batch_size = batch_size
110
+ self.shuffle = shuffle
111
+ self.drop_last = drop_last
112
+ self.generator = generator
113
+ self.offsets: List[int] = [sum(self.sizes[:i]) for i in range(len(self.sizes))]
114
+
115
+ def _num_batches(self, size: int) -> int:
116
+ if self.drop_last:
117
+ return size // self.batch_size
118
+ return (size + self.batch_size - 1) // self.batch_size
119
+
120
+ def _batches(self, dataset_index: int) -> List[List[int]]:
121
+ size = self.sizes[dataset_index]
122
+ offset = self.offsets[dataset_index]
123
+ if self.shuffle:
124
+ order = torch.randperm(size, generator=self.generator).tolist()
125
+ else:
126
+ order = list(range(size))
127
+
128
+ indices = [offset + i for i in order]
129
+ batches = [indices[start : start + self.batch_size] for start in range(0, size, self.batch_size)]
130
+
131
+ if self.drop_last and batches and len(batches[-1]) < self.batch_size:
132
+ batches.pop()
133
+ return batches
134
+
135
+ def __len__(self) -> int:
136
+ main = self._num_batches(self.sizes[0])
137
+ if main == 0:
138
+ return 0
139
+
140
+ full_rounds, remainder = divmod(main, self.ratios[0])
141
+ per_round = self.ratios[0] + sum(
142
+ self.ratios[i] for i in range(1, len(self.sizes)) if self._num_batches(self.sizes[i]) > 0
143
+ )
144
+ return full_rounds * per_round + remainder
145
+
146
+ def __iter__(self) -> Iterator[List[int]]:
147
+ iterators = [iter(self._batches(i)) for i in range(len(self.sizes))]
148
+ while True:
149
+ for dataset_index, ratio in enumerate(self.ratios):
150
+ for _ in range(ratio):
151
+ batch = next(iterators[dataset_index], None)
152
+ if batch is None:
153
+ if dataset_index == 0:
154
+ return
155
+
156
+ iterators[dataset_index] = iter(self._batches(dataset_index))
157
+ batch = next(iterators[dataset_index], None)
158
+ if batch is None:
159
+ break
160
+
161
+ yield batch