Skip to content

Commit 35ffbbe

Browse files
ADD reconstruction - this package takes the most memory.
1 parent 7fb5941 commit 35ffbbe

19 files changed

+1012
-0
lines changed

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,3 +229,4 @@ add_nanobind_module(booleans_ext src/booleans.cpp)
229229
add_nanobind_module(meshing_ext src/meshing.cpp)
230230
add_nanobind_module(intersections_ext src/intersections.cpp)
231231
add_nanobind_module(measure_ext src/measure.cpp)
232+
add_nanobind_module(reconstruction_ext src/reconstruction.cpp)
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
from pathlib import Path
2+
3+
from compas.geometry import Line
4+
from compas.geometry import Pointcloud
5+
from compas_viewer import Viewer
6+
from compas_viewer.config import Config
7+
from compas_viewer.scene import Collection
8+
from line_profiler import profile
9+
10+
from compas_cgal.reconstruction import pointset_normal_estimation
11+
from compas_cgal.reconstruction import pointset_reduction
12+
13+
14+
@profile
15+
def reconstruction_pointset_normal_estimation():
16+
# ==============================================================================
17+
# Input geometry
18+
# ==============================================================================
19+
20+
FILE = Path(__file__).parent.parent.parent / "data" / "forked_branch_1.ply"
21+
22+
cloud = Pointcloud.from_ply(FILE)
23+
reduced_cloud = Pointcloud(pointset_reduction(cloud, 10))
24+
points, vectors = pointset_normal_estimation(reduced_cloud, 16, True)
25+
26+
# ==============================================================================
27+
# Compute
28+
# ==============================================================================
29+
30+
lines = []
31+
line_scale = 10
32+
33+
for p, v in zip(points, vectors):
34+
line = Line(
35+
[p[0], p[1], p[2]],
36+
[
37+
p[0] + v[0] * line_scale,
38+
p[1] + v[1] * line_scale,
39+
p[2] + v[2] * line_scale,
40+
],
41+
)
42+
lines.append(line)
43+
44+
return lines
45+
46+
47+
lines = reconstruction_pointset_normal_estimation()
48+
49+
# ==============================================================================
50+
# Visualize
51+
# ==============================================================================
52+
53+
config = Config()
54+
config.camera.target = [600, 500, 200]
55+
config.camera.position = [600, -1000, 1500]
56+
config.camera.scale = 100
57+
config.renderer.gridsize = (20000, 20, 20000, 20)
58+
59+
viewer = Viewer(config=config)
60+
viewer.scene.add(Collection(lines))
61+
viewer.show()
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
Point Cloud Normal Estimation
2+
=============================
3+
4+
This example demonstrates how to estimate normals from a point cloud using COMPAS CGAL.
5+
6+
Key Features:
7+
8+
* Loading point clouds from PLY files
9+
* Point cloud density reduction
10+
* Normal estimation using k-nearest neighbors
11+
* Visualization of point normals as scaled lines
12+
13+
.. figure:: /_images/example_reconstruction_pointset_normal_estimation.png
14+
:figclass: figure
15+
:class: figure-img img-fluid
16+
17+
.. literalinclude:: example_reconstruction_pointset_normal_estimation.py
18+
:language: python
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
from pathlib import Path
2+
3+
from compas.geometry import Pointcloud
4+
from compas_viewer import Viewer
5+
from compas_viewer.config import Config
6+
from line_profiler import profile
7+
8+
from compas_cgal.reconstruction import pointset_outlier_removal
9+
10+
11+
@profile
12+
def reconstruction_pointset_outlier_removal():
13+
"""Remove outliers from a point set."""
14+
15+
# ==============================================================================
16+
# Input geometry
17+
# ==============================================================================
18+
19+
FILE = Path(__file__).parent.parent.parent / "data" / "forked_branch_1.ply"
20+
c1 = Pointcloud.from_ply(FILE)
21+
22+
# ==============================================================================
23+
# Compute
24+
# ==============================================================================
25+
26+
points = pointset_outlier_removal(c1, 30, 2.0)
27+
c2 = Pointcloud(points)
28+
c3 = c1.difference(c2)
29+
30+
return c2, c3
31+
32+
33+
c_outlier_removal_0, c_outlier_removal_1 = reconstruction_pointset_outlier_removal()
34+
35+
# ==============================================================================
36+
# Visualize
37+
# ==============================================================================
38+
39+
config = Config()
40+
config.camera.target = [600, 500, 200]
41+
config.camera.position = [600, -1000, 1500]
42+
config.camera.scale = 100
43+
config.renderer.gridsize = (20000, 20, 20000, 20)
44+
45+
viewer = Viewer(config=config)
46+
47+
viewer.scene.add(c_outlier_removal_0, pointcolor=(0.0, 0.0, 0.0))
48+
viewer.scene.add(c_outlier_removal_1, pointcolor=(1.0, 0.0, 0.0))
49+
50+
viewer.show()
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
Point Cloud Outlier Removal
2+
===========================
3+
4+
This example demonstrates how to remove outliers from a point cloud using COMPAS CGAL.
5+
6+
Key Features:
7+
8+
* Loading point clouds from PLY files
9+
* Removing outliers based on neighborhood analysis
10+
* Visualization of inliers and outliers with different colors
11+
* Point cloud difference computation
12+
13+
.. figure:: /_images/example_reconstruction_pointset_outlier_removal.png
14+
:figclass: figure
15+
:class: figure-img img-fluid
16+
17+
.. literalinclude:: example_reconstruction_pointset_outlier_removal.py
18+
:language: python
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
from pathlib import Path
2+
3+
from compas.geometry import Pointcloud
4+
from compas.geometry import Translation
5+
from compas.geometry import transform_points_numpy
6+
from compas_viewer import Viewer
7+
from compas_viewer.config import Config
8+
from line_profiler import profile
9+
10+
from compas_cgal.reconstruction import pointset_reduction
11+
12+
13+
@profile
14+
def reconstruction_pointset_reduction():
15+
"""Reduce the number of points in a point set."""
16+
17+
FILE = Path(__file__).parent.parent.parent / "data" / "forked_branch_1.ply"
18+
c = Pointcloud.from_ply(FILE)
19+
20+
points = Pointcloud(pointset_reduction(c, 50))
21+
transform_points_numpy(points, Translation.from_vector([-1000, 0, 0]))
22+
23+
c.transform(Translation.from_vector([-1000, 0, 0]))
24+
25+
return c, points
26+
27+
28+
c_reduction_0, c_reduction_1 = reconstruction_pointset_reduction()
29+
30+
config = Config()
31+
config.camera.target = [100, 500, 200]
32+
config.camera.position = [100, -1500, 2000]
33+
config.camera.scale = 100
34+
config.renderer.gridsize = (20000, 20, 20000, 20)
35+
36+
viewer = Viewer(config=config)
37+
viewer.scene.add(c_reduction_0, pointcolor=(0.0, 0.0, 0.0))
38+
viewer.scene.add(c_reduction_1, pointcolor=(1.0, 0.0, 0.0))
39+
40+
viewer.show()
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
Point Cloud Reduction
2+
=====================
3+
4+
This example demonstrates how to reduce the density of a point cloud using COMPAS CGAL.
5+
6+
Key Features:
7+
8+
* Loading point clouds from PLY files
9+
* Point cloud density reduction with specified percentage
10+
* Side-by-side visualization of original and reduced point clouds
11+
12+
.. figure:: /_images/example_reconstruction_pointset_reduction.png
13+
:figclass: figure
14+
:class: figure-img img-fluid
15+
16+
.. literalinclude:: example_reconstruction_pointset_reduction.py
17+
:language: python
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
from pathlib import Path
2+
3+
from compas.geometry import Pointcloud
4+
from compas.geometry import Translation
5+
from compas.geometry import transform_points_numpy
6+
from compas_viewer import Viewer
7+
from compas_viewer.config import Config
8+
from line_profiler import profile
9+
10+
from compas_cgal.reconstruction import pointset_smoothing
11+
12+
13+
@profile
14+
def reconstruction_pointset_smoothing():
15+
"""Smooth a point set."""
16+
17+
ply_file_path = Path(__file__).parent.parent.parent / "data" / "box.ply"
18+
original_points = Pointcloud.from_ply(ply_file_path)
19+
20+
smoothed_points = pointset_smoothing(original_points, 1000, 3)
21+
22+
return Pointcloud(original_points), Pointcloud(smoothed_points)
23+
24+
25+
c_smoothing_0, c_smoothing_1 = reconstruction_pointset_smoothing()
26+
27+
# ==============================================================================
28+
# Visualize
29+
# ==============================================================================
30+
31+
config = Config()
32+
config.camera.target = [0, 5000, -10000]
33+
config.camera.position = [0, -10000, 30000]
34+
config.camera.scale = 1000
35+
config.renderer.gridsize = (20000, 20, 20000, 20)
36+
37+
viewer = Viewer(config=config)
38+
viewer.scene.add(c_smoothing_0, pointcolor=(0.0, 0.0, 0.0))
39+
viewer.scene.add(c_smoothing_1, pointcolor=(1.0, 0.0, 0.0))
40+
viewer.show()
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
Point Cloud Smoothing
2+
=====================
3+
4+
This example demonstrates how to smooth a point cloud using COMPAS CGAL.
5+
6+
Key Features:
7+
8+
* Loading point clouds from PLY files
9+
* Point cloud smoothing with specified iterations and neighborhood size
10+
* Side-by-side visualization of original and smoothed point clouds
11+
12+
.. figure:: /_images/example_reconstruction_pointset_smoothing.png
13+
:figclass: figure
14+
:class: figure-img img-fluid
15+
16+
.. literalinclude:: example_reconstruction_pointset_smoothing.py
17+
:language: python
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import math
2+
from pathlib import Path
3+
4+
from compas.datastructures import Mesh
5+
from compas.geometry import Pointcloud
6+
from compas.geometry import Rotation
7+
from compas.geometry import Scale
8+
from compas_viewer import Viewer
9+
from line_profiler import profile
10+
11+
from compas_cgal.reconstruction import poisson_surface_reconstruction
12+
13+
14+
@profile
15+
def reconstruction_poisson_surface_reconstruction():
16+
FILE = Path(__file__).parent.parent.parent / "data" / "oni.xyz"
17+
18+
points = []
19+
normals = []
20+
with open(FILE, "r") as f:
21+
for line in f:
22+
x, y, z, nx, ny, nz = line.strip().split()
23+
points.append([float(x), float(y), float(z)])
24+
normals.append([float(nx), float(ny), float(nz)])
25+
26+
V, F = poisson_surface_reconstruction(points, normals)
27+
mesh = Mesh.from_vertices_and_faces(V, F)
28+
29+
c = Pointcloud(V)
30+
31+
return c, mesh
32+
33+
34+
points, mesh = reconstruction_poisson_surface_reconstruction()
35+
36+
# ==============================================================================
37+
# Visualize
38+
# ==============================================================================
39+
40+
viewer = Viewer()
41+
42+
viewer.renderer.camera.target = [0, 0, 0]
43+
viewer.renderer.camera.position = [0, -0.2, 2.0]
44+
45+
viewer.scene.add(points, pointsize=10, pointcolor=(255, 0, 0))
46+
viewer.scene.add(mesh, show_points=False)
47+
48+
viewer.show()

0 commit comments

Comments
 (0)