Skip to content

Commit 73891d6

Browse files
ADD-FIX curvature examples and environment.yml
1 parent 60c120c commit 73891d6

File tree

4 files changed

+151
-80
lines changed

4 files changed

+151
-80
lines changed

docs/examples/curvature.py

Lines changed: 0 additions & 80 deletions
This file was deleted.
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
import compas
2+
import numpy as np
3+
import compas_libigl as igl
4+
from compas.colors import Color
5+
from compas.colors.colormap import ColorMap
6+
from compas.datastructures import Mesh
7+
from compas.geometry import Point, Line, Vector
8+
from compas_viewer import Viewer
9+
from compas_viewer.scene import BufferGeometry
10+
11+
# ==============================================================================
12+
# Input geometry
13+
# ==============================================================================
14+
15+
mesh = Mesh.from_obj(compas.get("tubemesh.obj"))
16+
trimesh = mesh.copy()
17+
trimesh.quads_to_triangles()
18+
19+
# ==============================================================================
20+
# Gaussian Curvature
21+
# ==============================================================================
22+
23+
vertices, faces = trimesh.to_vertices_and_faces()
24+
gaussian_curvature = igl.trimesh_gaussian_curvature((vertices, faces))
25+
26+
# Get non-boundary vertex indices
27+
non_boundary_vertices = [i for i in range(len(vertices)) if not trimesh.is_vertex_on_boundary(i)]
28+
29+
# Prepare vertex colors based on Gaussian curvature (excluding boundary vertices)
30+
min_gaussian = min(gaussian_curvature[i] for i in non_boundary_vertices)
31+
max_gaussian = max(gaussian_curvature[i] for i in non_boundary_vertices)
32+
print(f"Gaussian curvature range: {min_gaussian:.3f} to {max_gaussian:.3f}")
33+
34+
# Scale factor for normal vectors
35+
normal_scale = -10
36+
37+
# Create two-color maps for negative and positive curvature
38+
cmap_negative = ColorMap.from_two_colors(Color.blue(), Color.yellow())
39+
cmap_positive = ColorMap.from_two_colors(Color.yellow(), Color.magenta())
40+
41+
# Convert mesh to numpy arrays for BufferGeometry
42+
vertices = np.array(vertices, dtype=np.float32)
43+
faces = np.array(faces, dtype=np.float32)
44+
45+
# Create vertex colors array (Nx4 for RGBA)
46+
vertex_colors = np.zeros((len(vertices), 4), dtype=np.float32)
47+
for i, k in enumerate(gaussian_curvature):
48+
if trimesh.is_vertex_on_boundary(i):
49+
# Set boundary vertices to a neutral color
50+
vertex_colors[i] = [0, 0, 0, 1.0]
51+
else:
52+
if k < 0:
53+
color = cmap_negative(k, minval=min_gaussian, maxval=0)
54+
else:
55+
color = cmap_positive(k, minval=0, maxval=max_gaussian)
56+
vertex_colors[i] = (color[0], color[1], color[2], 1.0)
57+
58+
# Create geometry for the mesh with vertex colors
59+
faces_for_buffer = np.array([vertices[f] for f in faces.astype(int)]).reshape(-1, 3)
60+
vertex_colors_for_buffer = np.array([vertex_colors[i] for i in faces.astype(int)]).reshape(-1, 4)
61+
62+
geometry = BufferGeometry(
63+
faces=faces_for_buffer,
64+
facecolor=vertex_colors_for_buffer
65+
)
66+
67+
# ==============================================================================
68+
# Visualization
69+
# ==============================================================================
70+
71+
viewer = Viewer()
72+
viewer.scene.add(geometry)
73+
74+
# Add normal vectors colored by Gaussian curvature
75+
for vertex_idx, point in enumerate(vertices):
76+
if not trimesh.is_vertex_on_boundary(vertex_idx):
77+
point = Point(*point)
78+
normal = Vector(*trimesh.vertex_normal(vertex_idx))
79+
k = gaussian_curvature[vertex_idx]
80+
81+
# Scale normal by absolute curvature value
82+
scaled_normal = normal.scaled(normal_scale * k)
83+
84+
viewer.scene.add(
85+
Line(point, point + scaled_normal),
86+
linecolor=Color.black(),
87+
linewidth=2
88+
)
89+
viewer.show()
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
import compas
2+
import numpy as np
3+
import compas_libigl as igl
4+
from compas.colors import Color
5+
from compas.colors.colormap import ColorMap
6+
from compas.datastructures import Mesh
7+
from compas.geometry import Line, Point, Vector
8+
from compas_viewer import Viewer
9+
from compas_viewer.scene import BufferGeometry
10+
11+
# ==============================================================================
12+
# Input geometry
13+
# ==============================================================================
14+
15+
mesh = Mesh.from_obj(compas.get("tubemesh.obj"))
16+
trimesh = mesh.copy()
17+
trimesh.quads_to_triangles()
18+
19+
# ==============================================================================
20+
# Principal Curvature
21+
# ==============================================================================
22+
23+
vertices, faces = trimesh.to_vertices_and_faces()
24+
PD1, PD2, PV1, PV2 = igl.trimesh_principal_curvature((vertices, faces))
25+
26+
# ==============================================================================
27+
# Visualization
28+
# ==============================================================================
29+
30+
viewer = Viewer()
31+
32+
# Add the colored mesh
33+
viewer.scene.add(mesh)
34+
35+
# Scale factor for principal direction lines
36+
principal_scale = 0.3
37+
38+
# Add principal direction lines
39+
for vertex_idx, point in enumerate(vertices):
40+
if not trimesh.is_vertex_on_boundary(vertex_idx):
41+
point = Point(*point)
42+
43+
# Scale lines by curvature magnitude
44+
pd1 = Vector(*PD1[vertex_idx]).scaled(principal_scale * abs(PV1[vertex_idx]))
45+
pd2 = Vector(*PD2[vertex_idx]).scaled(principal_scale * abs(PV2[vertex_idx]))
46+
47+
# Maximum principal direction (black)
48+
viewer.scene.add(
49+
Line(point - pd1, point + pd1),
50+
linecolor=Color.black(),
51+
linewidth=2
52+
)
53+
# Minimum principal direction (black)
54+
viewer.scene.add(
55+
Line(point - pd2, point + pd2),
56+
linecolor=Color.black(),
57+
linewidth=2
58+
)
59+
60+
61+
viewer.show()

environment.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,6 @@ dependencies:
66
- git
77
- cmake>=3.14
88
- compas
9+
- invoke
910
- pip:
1011
- -e .[dev]

0 commit comments

Comments
 (0)