Skip to content

Commit 7ce97a0

Browse files
author
pv
committed
ADD normals, boundary, and grouping.
1 parent a9d9afc commit 7ce97a0

File tree

8 files changed

+160
-95
lines changed

8 files changed

+160
-95
lines changed

docs/examples/example_mapping.py

Lines changed: 45 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,23 @@
11
from pathlib import Path
22

33
from compas.colors import Color
4+
from compas.geometry import Polyline
45
from compas.datastructures import Mesh
56
from compas_viewer import Viewer
67
from compas_viewer.config import Config
78
from tessagon.adaptors.list_adaptor import ListAdaptor
8-
from tessagon.types.hex_tessagon import HexTessagon
9+
from tessagon.types.zig_zag_tessagon import ZigZagTessagon
910

1011
from compas_libigl.mapping import map_mesh
1112
from compas_libigl.parametrisation import trimesh_lsc_mapping
1213

14+
from compas import json_dump
15+
1316
# ==============================================================================
1417
# Input geometry: 3D Mesh
1518
# ==============================================================================
1619

17-
mesh = Mesh.from_obj(Path(__file__).parent.parent.parent / "data" / "minimal_surface.obj")
20+
mesh = Mesh.from_off(Path(__file__).parent.parent.parent / "data" / "beetle.off")
1821

1922
for vertex in mesh.vertices():
2023
x, y, z = mesh.vertex_attributes(vertex, "xyz") # type: ignore
@@ -32,24 +35,52 @@
3235
"function": lambda u, v: [u * 1, v * 1, 0],
3336
"u_range": [-0.255, 1.33],
3437
"v_range": [-0.34, 1.33],
35-
"u_num": 16,
36-
"v_num": 10,
38+
"u_num": 20,
39+
"v_num": 20,
3740
"u_cyclic": False,
3841
"v_cyclic": False,
3942
"adaptor_class": ListAdaptor,
4043
}
41-
tessagon = HexTessagon(**options)
44+
tessagon = ZigZagTessagon(**options)
4245
tessagon_mesh = tessagon.create_mesh()
4346
pv = tessagon_mesh["vert_list"]
4447
pf = tessagon_mesh["face_list"]
4548

4649
# ==============================================================================
4750
# Mapping: 3D Mesh, 2D Pattern, UV
51+
# mv - mapped vertices
52+
# mf - mapped faces
53+
# mn - mapped normals
54+
# mg - mapped boundaries (True or False)
55+
# mb - mapped groups for polygons with holes (list of int)
4856
# ==============================================================================
49-
50-
mv, mf = map_mesh((v, f), (pv, pf))
57+
mv, mf, mn, mb, mg = map_mesh((v, f), (pv, pf))
5158
mesh_mapped = Mesh.from_vertices_and_faces(mv, mf)
5259

60+
61+
# ==============================================================================
62+
# Offset mesh by normals, normals are interpolated from the original mesh.
63+
# ==============================================================================
64+
mesh_mapped_offset = mesh_mapped.copy()
65+
for i in range(mesh_mapped.number_of_vertices()):
66+
mesh_mapped_offset.vertex_attributes(i, "xyz", mesh_mapped.vertex_attributes(i, "xyz") - mn[i]*0.001)
67+
68+
# ==============================================================================
69+
# Get Boundary Polylines
70+
# ==============================================================================
71+
boundaries = []
72+
for i in range(len(mb)):
73+
if not mb[i]:
74+
continue
75+
points = []
76+
for j in range(len(mf[i])):
77+
id = mf[i][j]
78+
points.append(mesh_mapped.vertex_attributes(id, "xyz") + mn[id]*0.002)
79+
points.append(points[0])
80+
polyline = Polyline(points)
81+
boundaries.append(polyline)
82+
83+
5384
# ==============================================================================
5485
# Viewer
5586
# ==============================================================================
@@ -59,15 +90,20 @@
5990
config.camera.position = [5, 2, 1.5]
6091

6192
viewer = Viewer(config=config)
62-
viewer.scene.add(mesh, name="mesh", show_faces=False, linecolor=Color.grey(), opacity=0.2)
93+
# viewer.scene.add(mesh, name="mesh", show_faces=False, linecolor=Color.grey(), opacity=0.2)
6394
viewer.scene.add(Mesh.from_vertices_and_faces(pv, pf), name="pattern2d")
64-
viewer.scene.add(mesh_mapped, name="mesh_mapped", facecolor=Color.red())
95+
viewer.scene.add(mesh_mapped, name="mesh_mapped", facecolor=Color.pink())
96+
viewer.scene.add(mesh_mapped_offset, name="mesh_mapped", facecolor=Color.blue())
97+
for boundary in boundaries:
98+
viewer.scene.add(boundary, name="boundary", linecolor=Color.yellow(), linewidth=3)
6599

66100
# To see where the pattern is mapped:
67101
uv = trimesh_lsc_mapping((v, f))
68102
mesh_flattened = mesh.copy()
69103
for i in range(mesh.number_of_vertices()):
70104
mesh_flattened.vertex_attributes(i, "xyz", [uv[i][0], uv[i][1], 0])
71105

106+
json_dump([Mesh.from_vertices_and_faces(pv, pf), mesh_mapped, mesh_mapped_offset, boundaries, mesh_flattened], "mesh_flattened.json")
107+
72108
viewer.scene.add(mesh_flattened, name="mesh_flattened")
73109
viewer.show()

docs/examples/example_mapping_all_patterns.py renamed to docs/examples/example_mapping_patterns.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,13 @@
77

88
from compas_libigl.mapping import map_pattern_to_mesh
99

10+
11+
1012
# ==============================================================================
1113
# Input geometry: 3D Mesh
1214
# ==============================================================================
1315

14-
mesh = Mesh.from_off(Path(__file__).parent.parent.parent / "data" / "beetle.off")
16+
mesh = Mesh.from_obj(Path(__file__).parent.parent.parent / "data" / "minimal_surface.obj")
1517

1618
for vertex in mesh.vertices():
1719
x, y, z = mesh.vertex_attributes(vertex, "xyz") # type: ignore
@@ -20,7 +22,8 @@
2022
# ==============================================================================
2123
# Mapping: 3D Mesh, 2D Pattern, UV
2224
# ==============================================================================
23-
mesh_mapped = map_pattern_to_mesh("ZigZag", mesh, clip_boundaries=True, tolerance=1e-6, pattern_u=10, pattern_v=10)
25+
26+
mesh_mapped = map_pattern_to_mesh("ZigZag", mesh, clip_boundaries=True, tolerance=1e-6, pattern_u=16, pattern_v=16)
2427

2528
# ==============================================================================
2629
# Viewer
@@ -32,8 +35,7 @@
3235

3336
viewer = Viewer(config=config)
3437

35-
viewer.scene.add(mesh, name="mesh", show_faces=False, linecolor=Color.grey(), opacity=0.2)
38+
# viewer.scene.add(mesh, name="mesh", show_faces=False, linecolor=Color.grey(), opacity=0.2)
3639
viewer.scene.add(mesh_mapped, name="mesh_mapped", facecolor=Color.red())
3740

38-
3941
viewer.show()

mesh_flattened.json

Lines changed: 1 addition & 0 deletions
Large diffs are not rendered by default.

src/compas_libigl/mapping.py

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
from tessagon.types.zig_zag_tessagon import ZigZagTessagon
2222

2323
from compas_libigl import _mapping
24+
from compas_libigl._types_std import VectorBool # noqa: F401
25+
from compas_libigl._types_std import VectorInt # noqa: F401
2426
from compas_libigl._types_std import VectorVectorInt # noqa: F401
2527

2628

@@ -50,7 +52,7 @@ def map_mesh(target_mesh, pattern_mesh, clip_boundaries=True, tolerance=1e-6):
5052
Returns
5153
-------
5254
tuple
53-
A tuple containing (vertices, faces) of the mapped pattern mesh.
55+
A tuple containing: mesh vertices, normals, grouping of polygons (to form holes), boundary flags.
5456
"""
5557
# Unpack mesh tuples
5658
v, f = target_mesh
@@ -62,10 +64,12 @@ def map_mesh(target_mesh, pattern_mesh, clip_boundaries=True, tolerance=1e-6):
6264
pattern_v_numpy = np.array(pv, dtype=np.float64)
6365

6466
# Perform the mapping
65-
pattern_v_numpy_copy, pattern_f_numpy_cleaned = _mapping.map_mesh_with_automatic_parameterization(v_numpy, f_numpy, pattern_v_numpy, pf, clip_boundaries, tolerance)
67+
pv_numpy_copy, pf_numpy_cleaned, p_normals, pattern_is_boundary, pattern_groups = _mapping.map_mesh_with_automatic_parameterization(
68+
v_numpy, f_numpy, pattern_v_numpy, pf, clip_boundaries, tolerance
69+
)
6670

6771
# Return the result as a tuple
68-
return pattern_v_numpy_copy, pattern_f_numpy_cleaned
72+
return pv_numpy_copy, pf_numpy_cleaned, p_normals, pattern_is_boundary, pattern_groups
6973

7074

7175
def map_pattern_to_mesh(name, mesh, clip_boundaries=True, tolerance=1e-6, pattern_u=16, pattern_v=16):
@@ -151,6 +155,6 @@ def map_pattern_to_mesh(name, mesh, clip_boundaries=True, tolerance=1e-6, patter
151155
pf = tessagon_mesh["face_list"]
152156

153157
v, f = mesh.to_vertices_and_faces()
154-
mv, mf = map_mesh((v, f), (pv, pf), clip_boundaries=clip_boundaries, tolerance=tolerance)
158+
mapped_vertices, mapped_faces, mapped_normals, mapped_is_boundary, mapped_groups = map_mesh((v, f), (pv, pf), clip_boundaries=clip_boundaries, tolerance=tolerance)
155159

156-
return Mesh.from_vertices_and_faces(mv, mf)
160+
return Mesh.from_vertices_and_faces(mapped_vertices, mapped_faces)

0 commit comments

Comments
 (0)