svr-roughness 0.3.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.
- svr_roughness-0.3.0/LICENSE +21 -0
- svr_roughness-0.3.0/PKG-INFO +139 -0
- svr_roughness-0.3.0/README.md +99 -0
- svr_roughness-0.3.0/pyproject.toml +38 -0
- svr_roughness-0.3.0/setup.cfg +4 -0
- svr_roughness-0.3.0/src/svr_roughness/__init__.py +35 -0
- svr_roughness-0.3.0/src/svr_roughness/__main__.py +37 -0
- svr_roughness-0.3.0/src/svr_roughness/_algorithm.py +408 -0
- svr_roughness-0.3.0/src/svr_roughness/analyze.py +71 -0
- svr_roughness-0.3.0/src/svr_roughness/config.py +81 -0
- svr_roughness-0.3.0/src/svr_roughness/io.py +265 -0
- svr_roughness-0.3.0/src/svr_roughness/py.typed +1 -0
- svr_roughness-0.3.0/src/svr_roughness/result.py +141 -0
- svr_roughness-0.3.0/src/svr_roughness/roughness.py +63 -0
- svr_roughness-0.3.0/src/svr_roughness.egg-info/PKG-INFO +139 -0
- svr_roughness-0.3.0/src/svr_roughness.egg-info/SOURCES.txt +18 -0
- svr_roughness-0.3.0/src/svr_roughness.egg-info/dependency_links.txt +1 -0
- svr_roughness-0.3.0/src/svr_roughness.egg-info/entry_points.txt +2 -0
- svr_roughness-0.3.0/src/svr_roughness.egg-info/requires.txt +3 -0
- svr_roughness-0.3.0/src/svr_roughness.egg-info/top_level.txt +1 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 HAM Lab, Iowa State University
|
|
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,139 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: svr-roughness
|
|
3
|
+
Version: 0.3.0
|
|
4
|
+
Summary: Surface roughness metrics from scanner point clouds
|
|
5
|
+
Author: Sullivan Hart, HAM Lab, Iowa State University
|
|
6
|
+
License: MIT License
|
|
7
|
+
|
|
8
|
+
Copyright (c) 2026 HAM Lab, Iowa State University
|
|
9
|
+
|
|
10
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
11
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
12
|
+
in the Software without restriction, including without limitation the rights
|
|
13
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
14
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
15
|
+
furnished to do so, subject to the following conditions:
|
|
16
|
+
|
|
17
|
+
The above copyright notice and this permission notice shall be included in all
|
|
18
|
+
copies or substantial portions of the Software.
|
|
19
|
+
|
|
20
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
21
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
22
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
23
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
24
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
25
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
26
|
+
SOFTWARE.
|
|
27
|
+
Keywords: roughness,point-cloud,ply,surface-metrology
|
|
28
|
+
Classifier: Development Status :: 4 - Beta
|
|
29
|
+
Classifier: Intended Audience :: Science/Research
|
|
30
|
+
Classifier: Programming Language :: Python :: 3
|
|
31
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
32
|
+
Classifier: Topic :: Scientific/Engineering
|
|
33
|
+
Requires-Python: >=3.10
|
|
34
|
+
Description-Content-Type: text/markdown
|
|
35
|
+
License-File: LICENSE
|
|
36
|
+
Requires-Dist: numpy>=1.24
|
|
37
|
+
Requires-Dist: opencv-python-headless>=4.8
|
|
38
|
+
Requires-Dist: scipy>=1.10
|
|
39
|
+
Dynamic: license-file
|
|
40
|
+
|
|
41
|
+
# svr-roughness
|
|
42
|
+
|
|
43
|
+
`svr-roughness` is a reusable Python library for SurfInspect-compatible surface
|
|
44
|
+
roughness analysis from industrial scan outputs. Use `svr_roughness` as the
|
|
45
|
+
consistent Python import name.
|
|
46
|
+
|
|
47
|
+
The core API is file-type agnostic: roughness is computed from an `Nx3` NumPy-like XYZ point array in millimeters. Svr is calculated from signed distances to a smoothed, triangulated reference surface and a KD-tree variogram modeled on SurfInspect. The regular grid remains available for Sa/Sq and visualization. Reference mesh resolution and smoothing default to 0.30 mm, matching the supplied SurfInspect A2 reference closely. At most 10,000 variogram points are used by default to bound memory on industrial scans; set `max_svr_points` higher when full point coverage is required.
|
|
48
|
+
|
|
49
|
+
```python
|
|
50
|
+
config = RoughnessConfig(
|
|
51
|
+
mesh_resolution_mm=0.30,
|
|
52
|
+
mesh_smoothing_mm=0.30,
|
|
53
|
+
svr_points=10,
|
|
54
|
+
svr_span_mm=0.50,
|
|
55
|
+
)
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Install
|
|
59
|
+
|
|
60
|
+
From this repository:
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
python -m pip install ./svr-roughness
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
For deployment from inside `SurfaceRoughnessPi`:
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
python -m pip install ../svr-roughness
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Python API
|
|
73
|
+
|
|
74
|
+
Use `analyze_points()` when your scanner or upstream software already gives you XYZ points:
|
|
75
|
+
|
|
76
|
+
```python
|
|
77
|
+
import numpy as np
|
|
78
|
+
from svr_roughness import analyze_points
|
|
79
|
+
|
|
80
|
+
points_xyz_mm = np.asarray(points) # shape (N, 3), columns x/y/z, units mm
|
|
81
|
+
result = analyze_points(points_xyz_mm, grid_mm=0.30, short_cutoff_mm=0.6, long_cutoff_mm=8.0)
|
|
82
|
+
|
|
83
|
+
print(result.sa_um, result.sq_um, result.svr_um)
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Use `analyze_file()` as a convenience adapter for supported files:
|
|
87
|
+
|
|
88
|
+
```python
|
|
89
|
+
from svr_roughness import RoughnessConfig, analyze_file
|
|
90
|
+
|
|
91
|
+
config = RoughnessConfig(grid_mm=0.30, short_cutoff_mm=0.6, long_cutoff_mm=8.0)
|
|
92
|
+
result = analyze_file("scan.ply", config=config)
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
Supported file loaders (all are converted to an `Nx3` NumPy array):
|
|
96
|
+
|
|
97
|
+
- ASCII and binary little-endian `.ply` point clouds
|
|
98
|
+
- ASCII and binary `.pcd` point clouds
|
|
99
|
+
- ASCII and binary `.stl` mesh vertices
|
|
100
|
+
- `.obj` vertex meshes
|
|
101
|
+
- comma-, tab-, or whitespace-delimited `.csv`, `.tsv`, `.xyz`, and `.txt`
|
|
102
|
+
- `.npy` and `.npz` NumPy arrays
|
|
103
|
+
|
|
104
|
+
STL files are converted to their unique mesh vertices before analysis. For production mesh metrology, prefer scanner point clouds or add controlled surface sampling before calling `analyze_points()`.
|
|
105
|
+
|
|
106
|
+
## Result Output
|
|
107
|
+
|
|
108
|
+
```python
|
|
109
|
+
result.save_grid_npz("output/roughness/latest_grid.npz")
|
|
110
|
+
result.save_metrics_json("output/roughness/latest_metrics.json")
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
`save_metrics_json()` writes:
|
|
114
|
+
|
|
115
|
+
- `sa_um`
|
|
116
|
+
- `sq_um`
|
|
117
|
+
- `svr_um`
|
|
118
|
+
- point counts, grid dimensions, grid coverage, and filter cutoffs
|
|
119
|
+
|
|
120
|
+
`save_grid_npz()` writes:
|
|
121
|
+
|
|
122
|
+
- `grid_raw`
|
|
123
|
+
- `grid_filled`
|
|
124
|
+
- `grid_filtered`
|
|
125
|
+
- `valid_raw`
|
|
126
|
+
- `valid_filled`
|
|
127
|
+
- `grid_origin`
|
|
128
|
+
- plane basis arrays
|
|
129
|
+
|
|
130
|
+
## Command line
|
|
131
|
+
|
|
132
|
+
The package also includes a no-code command for scanner integrations:
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
svr-roughness scan.ply --grid-mm 0.30 --metrics-out metrics.json --grid-out grid.npz
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
Coordinates are assumed to be millimeters, and metrics are reported in
|
|
139
|
+
micrometers. Unit conversion should happen before calling the library.
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# svr-roughness
|
|
2
|
+
|
|
3
|
+
`svr-roughness` is a reusable Python library for SurfInspect-compatible surface
|
|
4
|
+
roughness analysis from industrial scan outputs. Use `svr_roughness` as the
|
|
5
|
+
consistent Python import name.
|
|
6
|
+
|
|
7
|
+
The core API is file-type agnostic: roughness is computed from an `Nx3` NumPy-like XYZ point array in millimeters. Svr is calculated from signed distances to a smoothed, triangulated reference surface and a KD-tree variogram modeled on SurfInspect. The regular grid remains available for Sa/Sq and visualization. Reference mesh resolution and smoothing default to 0.30 mm, matching the supplied SurfInspect A2 reference closely. At most 10,000 variogram points are used by default to bound memory on industrial scans; set `max_svr_points` higher when full point coverage is required.
|
|
8
|
+
|
|
9
|
+
```python
|
|
10
|
+
config = RoughnessConfig(
|
|
11
|
+
mesh_resolution_mm=0.30,
|
|
12
|
+
mesh_smoothing_mm=0.30,
|
|
13
|
+
svr_points=10,
|
|
14
|
+
svr_span_mm=0.50,
|
|
15
|
+
)
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Install
|
|
19
|
+
|
|
20
|
+
From this repository:
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
python -m pip install ./svr-roughness
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
For deployment from inside `SurfaceRoughnessPi`:
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
python -m pip install ../svr-roughness
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Python API
|
|
33
|
+
|
|
34
|
+
Use `analyze_points()` when your scanner or upstream software already gives you XYZ points:
|
|
35
|
+
|
|
36
|
+
```python
|
|
37
|
+
import numpy as np
|
|
38
|
+
from svr_roughness import analyze_points
|
|
39
|
+
|
|
40
|
+
points_xyz_mm = np.asarray(points) # shape (N, 3), columns x/y/z, units mm
|
|
41
|
+
result = analyze_points(points_xyz_mm, grid_mm=0.30, short_cutoff_mm=0.6, long_cutoff_mm=8.0)
|
|
42
|
+
|
|
43
|
+
print(result.sa_um, result.sq_um, result.svr_um)
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Use `analyze_file()` as a convenience adapter for supported files:
|
|
47
|
+
|
|
48
|
+
```python
|
|
49
|
+
from svr_roughness import RoughnessConfig, analyze_file
|
|
50
|
+
|
|
51
|
+
config = RoughnessConfig(grid_mm=0.30, short_cutoff_mm=0.6, long_cutoff_mm=8.0)
|
|
52
|
+
result = analyze_file("scan.ply", config=config)
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Supported file loaders (all are converted to an `Nx3` NumPy array):
|
|
56
|
+
|
|
57
|
+
- ASCII and binary little-endian `.ply` point clouds
|
|
58
|
+
- ASCII and binary `.pcd` point clouds
|
|
59
|
+
- ASCII and binary `.stl` mesh vertices
|
|
60
|
+
- `.obj` vertex meshes
|
|
61
|
+
- comma-, tab-, or whitespace-delimited `.csv`, `.tsv`, `.xyz`, and `.txt`
|
|
62
|
+
- `.npy` and `.npz` NumPy arrays
|
|
63
|
+
|
|
64
|
+
STL files are converted to their unique mesh vertices before analysis. For production mesh metrology, prefer scanner point clouds or add controlled surface sampling before calling `analyze_points()`.
|
|
65
|
+
|
|
66
|
+
## Result Output
|
|
67
|
+
|
|
68
|
+
```python
|
|
69
|
+
result.save_grid_npz("output/roughness/latest_grid.npz")
|
|
70
|
+
result.save_metrics_json("output/roughness/latest_metrics.json")
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
`save_metrics_json()` writes:
|
|
74
|
+
|
|
75
|
+
- `sa_um`
|
|
76
|
+
- `sq_um`
|
|
77
|
+
- `svr_um`
|
|
78
|
+
- point counts, grid dimensions, grid coverage, and filter cutoffs
|
|
79
|
+
|
|
80
|
+
`save_grid_npz()` writes:
|
|
81
|
+
|
|
82
|
+
- `grid_raw`
|
|
83
|
+
- `grid_filled`
|
|
84
|
+
- `grid_filtered`
|
|
85
|
+
- `valid_raw`
|
|
86
|
+
- `valid_filled`
|
|
87
|
+
- `grid_origin`
|
|
88
|
+
- plane basis arrays
|
|
89
|
+
|
|
90
|
+
## Command line
|
|
91
|
+
|
|
92
|
+
The package also includes a no-code command for scanner integrations:
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
svr-roughness scan.ply --grid-mm 0.30 --metrics-out metrics.json --grid-out grid.npz
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
Coordinates are assumed to be millimeters, and metrics are reported in
|
|
99
|
+
micrometers. Unit conversion should happen before calling the library.
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=68", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "svr-roughness"
|
|
7
|
+
version = "0.3.0"
|
|
8
|
+
description = "Surface roughness metrics from scanner point clouds"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.10"
|
|
11
|
+
license = { file = "LICENSE" }
|
|
12
|
+
authors = [
|
|
13
|
+
{ name = "Sullivan Hart" },
|
|
14
|
+
{ name = "HAM Lab, Iowa State University" }
|
|
15
|
+
]
|
|
16
|
+
dependencies = [
|
|
17
|
+
"numpy>=1.24",
|
|
18
|
+
"opencv-python-headless>=4.8",
|
|
19
|
+
"scipy>=1.10"
|
|
20
|
+
]
|
|
21
|
+
keywords = ["roughness", "point-cloud", "ply", "surface-metrology"]
|
|
22
|
+
classifiers = [
|
|
23
|
+
"Development Status :: 4 - Beta",
|
|
24
|
+
"Intended Audience :: Science/Research",
|
|
25
|
+
"Programming Language :: Python :: 3",
|
|
26
|
+
"Programming Language :: Python :: 3 :: Only",
|
|
27
|
+
"Topic :: Scientific/Engineering"
|
|
28
|
+
]
|
|
29
|
+
|
|
30
|
+
[project.scripts]
|
|
31
|
+
svr-roughness = "svr_roughness.__main__:main"
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
[tool.setuptools.packages.find]
|
|
35
|
+
where = ["src"]
|
|
36
|
+
|
|
37
|
+
[tool.setuptools.package-data]
|
|
38
|
+
svr_roughness = ["py.typed"]
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"""Surface roughness analysis for scanner point clouds."""
|
|
2
|
+
|
|
3
|
+
from .analyze import (
|
|
4
|
+
analyze_file,
|
|
5
|
+
analyze_ply,
|
|
6
|
+
analyze_points,
|
|
7
|
+
compute_roughness,
|
|
8
|
+
compute_roughness_from_ply,
|
|
9
|
+
)
|
|
10
|
+
from .config import RoughnessConfig
|
|
11
|
+
from .io import load_ascii_ply, load_delimited, load_obj, load_pcd, load_ply, load_points, load_stl_vertices
|
|
12
|
+
from .result import PlaneFit, RoughnessGrid, RoughnessResult, format_report
|
|
13
|
+
from ._algorithm import svr_map, svr_surface
|
|
14
|
+
|
|
15
|
+
__all__ = [
|
|
16
|
+
"PlaneFit",
|
|
17
|
+
"RoughnessConfig",
|
|
18
|
+
"RoughnessGrid",
|
|
19
|
+
"RoughnessResult",
|
|
20
|
+
"analyze_file",
|
|
21
|
+
"analyze_ply",
|
|
22
|
+
"analyze_points",
|
|
23
|
+
"compute_roughness",
|
|
24
|
+
"compute_roughness_from_ply",
|
|
25
|
+
"format_report",
|
|
26
|
+
"load_ascii_ply",
|
|
27
|
+
"load_delimited",
|
|
28
|
+
"load_obj",
|
|
29
|
+
"load_pcd",
|
|
30
|
+
"load_ply",
|
|
31
|
+
"load_points",
|
|
32
|
+
"load_stl_vertices",
|
|
33
|
+
"svr_map",
|
|
34
|
+
"svr_surface",
|
|
35
|
+
]
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import argparse
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
|
|
6
|
+
from .analyze import analyze_file
|
|
7
|
+
from .config import RoughnessConfig
|
|
8
|
+
from .result import format_report
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def main() -> None:
|
|
12
|
+
parser = argparse.ArgumentParser(description="Calculate surface roughness from a point-cloud file.")
|
|
13
|
+
parser.add_argument("input", type=Path, help="Input PLY, PCD, STL, OBJ, CSV, XYZ, TXT, TSV, NPY, or NPZ file")
|
|
14
|
+
parser.add_argument("--grid-mm", type=float, default=0.30)
|
|
15
|
+
parser.add_argument("--short-cutoff-mm", type=float, default=0.0)
|
|
16
|
+
parser.add_argument("--long-cutoff-mm", type=float, default=0.0)
|
|
17
|
+
parser.add_argument("--metrics-out", type=Path)
|
|
18
|
+
parser.add_argument("--grid-out", type=Path)
|
|
19
|
+
args = parser.parse_args()
|
|
20
|
+
|
|
21
|
+
result = analyze_file(
|
|
22
|
+
args.input,
|
|
23
|
+
RoughnessConfig(
|
|
24
|
+
grid_mm=args.grid_mm,
|
|
25
|
+
short_cutoff_mm=args.short_cutoff_mm,
|
|
26
|
+
long_cutoff_mm=args.long_cutoff_mm,
|
|
27
|
+
),
|
|
28
|
+
)
|
|
29
|
+
print(format_report(result))
|
|
30
|
+
if args.metrics_out:
|
|
31
|
+
result.save_metrics_json(args.metrics_out)
|
|
32
|
+
if args.grid_out:
|
|
33
|
+
result.save_grid_npz(args.grid_out)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
if __name__ == "__main__":
|
|
37
|
+
main()
|