pointpca2 0.4.2__tar.gz → 0.4.4__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.
- {pointpca2-0.4.2 → pointpca2-0.4.4}/Cargo.lock +2 -1
- {pointpca2-0.4.2 → pointpca2-0.4.4}/Cargo.toml +2 -1
- {pointpca2-0.4.2 → pointpca2-0.4.4}/PKG-INFO +1 -1
- {pointpca2-0.4.2 → pointpca2-0.4.4}/python/pointpca2/__init__.py +27 -15
- {pointpca2-0.4.2 → pointpca2-0.4.4}/src/lib.rs +20 -24
- pointpca2-0.4.4/src/utils.rs +20 -0
- {pointpca2-0.4.2 → pointpca2-0.4.4}/.gitignore +0 -0
- {pointpca2-0.4.2 → pointpca2-0.4.4}/LICENSE +0 -0
- {pointpca2-0.4.2 → pointpca2-0.4.4}/README.md +0 -0
- {pointpca2-0.4.2 → pointpca2-0.4.4}/environment.yml +0 -0
- {pointpca2-0.4.2 → pointpca2-0.4.4}/examples/example_compute_predictors.py +0 -0
- {pointpca2-0.4.2 → pointpca2-0.4.4}/examples/pcs/amphoriskos_vox10.ply +0 -0
- {pointpca2-0.4.2 → pointpca2-0.4.4}/examples/pcs/tmc13_amphoriskos_vox10_dec_geom01_text01_octree-predlift.ply +0 -0
- {pointpca2-0.4.2 → pointpca2-0.4.4}/pyproject.toml +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[package]
|
|
2
2
|
name = "pointpca2"
|
|
3
|
-
version = "0.4.
|
|
3
|
+
version = "0.4.4"
|
|
4
4
|
edition = "2021"
|
|
5
5
|
|
|
6
6
|
[lib]
|
|
@@ -10,6 +10,7 @@ crate-type = ["cdylib"]
|
|
|
10
10
|
[dependencies]
|
|
11
11
|
nalgebra = "0.32.5"
|
|
12
12
|
numpy = "0.15"
|
|
13
|
+
rayon = "1.10.0"
|
|
13
14
|
|
|
14
15
|
[dependencies.pointpca2-rs]
|
|
15
16
|
git = "https://github.com/akaTsunemori/pointpca2-rs.git"
|
|
@@ -2,30 +2,30 @@ import numpy as np
|
|
|
2
2
|
from .pointpca2 import compute_pointpca2 as __pointpca2_internal
|
|
3
3
|
|
|
4
4
|
|
|
5
|
-
def __preprocess_point_cloud(
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
colors = np.array(colors, dtype=np.double)
|
|
5
|
+
def __preprocess_point_cloud(
|
|
6
|
+
points: np.ndarray,
|
|
7
|
+
colors: np.ndarray,
|
|
8
|
+
) -> tuple[np.ndarray, np.ndarray]:
|
|
10
9
|
if points.shape != colors.shape:
|
|
11
10
|
raise Exception("Points and colors must have the same shape.")
|
|
11
|
+
if colors.max() <= 1 and colors.min() >= 0 and colors.dtype is np.double:
|
|
12
|
+
colors *= 255
|
|
12
13
|
if points.dtype != np.double:
|
|
13
14
|
points = points.astype(np.double)
|
|
14
|
-
if colors.max() <= 1 and colors.min() >= 0 and colors.dtype == np.double:
|
|
15
|
-
colors *= 255
|
|
16
15
|
if colors.dtype != np.uint8:
|
|
17
16
|
colors = colors.astype(np.uint8)
|
|
18
17
|
return points, colors
|
|
19
18
|
|
|
20
19
|
|
|
21
20
|
def compute_pointpca2(
|
|
22
|
-
points_reference,
|
|
23
|
-
colors_reference,
|
|
24
|
-
points_test,
|
|
25
|
-
colors_test,
|
|
21
|
+
points_reference: np.ndarray,
|
|
22
|
+
colors_reference: np.ndarray,
|
|
23
|
+
points_test: np.ndarray,
|
|
24
|
+
colors_test: np.ndarray,
|
|
26
25
|
search_size=81,
|
|
26
|
+
max_workers=0,
|
|
27
27
|
verbose=False,
|
|
28
|
-
):
|
|
28
|
+
) -> np.ndarray:
|
|
29
29
|
"""
|
|
30
30
|
Compute PointPCA2 from reference and test point clouds.
|
|
31
31
|
|
|
@@ -42,7 +42,13 @@ def compute_pointpca2(
|
|
|
42
42
|
search_size : int, optional
|
|
43
43
|
The k-nearest-neighbors search size.
|
|
44
44
|
Default is 81.
|
|
45
|
-
|
|
45
|
+
max_workers : int, optional
|
|
46
|
+
Sets the number of threads to be used in the thread-pool.
|
|
47
|
+
If you specify a non-zero number of threads using this parameter, then the
|
|
48
|
+
resulting thread-pools are guaranteed to start at most this number of threads.
|
|
49
|
+
If max_workers is 0, then the number of logical CPUs will be used.
|
|
50
|
+
Default is 0.
|
|
51
|
+
verbose : bool, optional
|
|
46
52
|
Whether to display verbose information or not.
|
|
47
53
|
Default is False.
|
|
48
54
|
|
|
@@ -57,7 +63,7 @@ def compute_pointpca2(
|
|
|
57
63
|
the array will eventually be converted to np.double.
|
|
58
64
|
|
|
59
65
|
For the colors arguments, it is expected that the colors are
|
|
60
|
-
on the [0, 1] range, or [0, 255]. Other ranges are not supported.
|
|
66
|
+
on the [0, 1] range (np.double), or [0, 255]. Other ranges are not supported.
|
|
61
67
|
Any dtype is accepted, but the array will eventually be converted
|
|
62
68
|
to np.uint8.
|
|
63
69
|
|
|
@@ -69,6 +75,12 @@ def compute_pointpca2(
|
|
|
69
75
|
points_a, colors_a = __preprocess_point_cloud(points_reference, colors_reference)
|
|
70
76
|
points_b, colors_b = __preprocess_point_cloud(points_test, colors_test)
|
|
71
77
|
predictors = __pointpca2_internal(
|
|
72
|
-
points_a,
|
|
78
|
+
points_a,
|
|
79
|
+
colors_a,
|
|
80
|
+
points_b,
|
|
81
|
+
colors_b,
|
|
82
|
+
search_size,
|
|
83
|
+
max_workers,
|
|
84
|
+
verbose,
|
|
73
85
|
)
|
|
74
86
|
return predictors
|
|
@@ -1,20 +1,16 @@
|
|
|
1
1
|
extern crate nalgebra as na;
|
|
2
2
|
extern crate numpy;
|
|
3
3
|
extern crate pointpca2_rs;
|
|
4
|
+
extern crate rayon;
|
|
5
|
+
|
|
6
|
+
mod utils;
|
|
4
7
|
|
|
5
|
-
use na::DMatrix;
|
|
6
8
|
use numpy::PyArray1;
|
|
7
9
|
use numpy::PyReadonlyArray2;
|
|
8
10
|
use pyo3::prelude::*;
|
|
9
11
|
use pyo3::wrap_pyfunction;
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
where
|
|
13
|
-
T: numpy::Element + na::Scalar,
|
|
14
|
-
{
|
|
15
|
-
let data: Vec<T> = x.as_array().iter().cloned().collect();
|
|
16
|
-
DMatrix::from_row_slice(x.shape()[0], x.shape()[1], &data)
|
|
17
|
-
}
|
|
12
|
+
use utils::as_dmatrix;
|
|
13
|
+
use utils::build_thread_pool;
|
|
18
14
|
|
|
19
15
|
#[pyfunction]
|
|
20
16
|
fn compute_pointpca2<'py>(
|
|
@@ -24,24 +20,24 @@ fn compute_pointpca2<'py>(
|
|
|
24
20
|
points_b: PyReadonlyArray2<'py, f64>,
|
|
25
21
|
colors_b: PyReadonlyArray2<'py, u8>,
|
|
26
22
|
search_size: usize,
|
|
23
|
+
max_workers: usize,
|
|
27
24
|
verbose: bool,
|
|
28
25
|
) -> &'py PyArray1<f64> {
|
|
29
|
-
let
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
26
|
+
let points_a = as_dmatrix(points_a);
|
|
27
|
+
let colors_a = as_dmatrix(colors_a);
|
|
28
|
+
let points_b = as_dmatrix(points_b);
|
|
29
|
+
let colors_b = as_dmatrix(colors_b);
|
|
30
|
+
let pool = build_thread_pool(max_workers);
|
|
31
|
+
let pooled_predictors = pool.install(|| {
|
|
32
|
+
pointpca2_rs::compute_pointpca2(
|
|
33
|
+
points_a,
|
|
34
|
+
colors_a,
|
|
35
|
+
points_b,
|
|
36
|
+
colors_b,
|
|
37
|
+
search_size,
|
|
38
|
+
verbose,
|
|
35
39
|
)
|
|
36
|
-
};
|
|
37
|
-
let pooled_predictors = pointpca2_rs::compute_pointpca2(
|
|
38
|
-
points_a,
|
|
39
|
-
colors_a,
|
|
40
|
-
points_b,
|
|
41
|
-
colors_b,
|
|
42
|
-
search_size,
|
|
43
|
-
verbose,
|
|
44
|
-
);
|
|
40
|
+
});
|
|
45
41
|
let py_array = PyArray1::from_iter(_py, pooled_predictors.iter().cloned());
|
|
46
42
|
py_array
|
|
47
43
|
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
use na::DMatrix;
|
|
2
|
+
use numpy::PyReadonlyArray2;
|
|
3
|
+
use rayon::ThreadPool;
|
|
4
|
+
use rayon::ThreadPoolBuilder;
|
|
5
|
+
|
|
6
|
+
pub fn as_dmatrix<T>(x: PyReadonlyArray2<T>) -> DMatrix<T>
|
|
7
|
+
where
|
|
8
|
+
T: numpy::Element + na::Scalar,
|
|
9
|
+
{
|
|
10
|
+
let data: Vec<T> = x.as_array().iter().cloned().collect();
|
|
11
|
+
DMatrix::from_row_slice(x.shape()[0], x.shape()[1], &data)
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
pub fn build_thread_pool(max_workers: usize) -> ThreadPool {
|
|
15
|
+
let pool = ThreadPoolBuilder::new()
|
|
16
|
+
.num_threads(max_workers)
|
|
17
|
+
.build()
|
|
18
|
+
.expect("Failed to build thread pool");
|
|
19
|
+
pool
|
|
20
|
+
}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|