Skip to content

Commit a9d9afc

Browse files
author
pv
committed
ADD map_pattern_to_mesh method
1 parent f66b827 commit a9d9afc

File tree

2 files changed

+113
-89
lines changed

2 files changed

+113
-89
lines changed
Lines changed: 4 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -1,57 +1,11 @@
1-
from itertools import filterfalse
21
from pathlib import Path
32

43
from compas.colors import Color
54
from compas.datastructures import Mesh
65
from compas_viewer import Viewer
76
from compas_viewer.config import Config
8-
from tessagon.adaptors.list_adaptor import ListAdaptor
9-
from tessagon.types.brick_tessagon import BrickTessagon
10-
from tessagon.types.dissected_hex_quad_tessagon import DissectedHexQuadTessagon
11-
from tessagon.types.dissected_hex_tri_tessagon import DissectedHexTriTessagon
12-
from tessagon.types.dissected_square_tessagon import DissectedSquareTessagon
13-
from tessagon.types.dissected_triangle_tessagon import DissectedTriangleTessagon
14-
from tessagon.types.dodeca_tessagon import DodecaTessagon
15-
from tessagon.types.floret_tessagon import FloretTessagon
16-
from tessagon.types.hex_big_tri_tessagon import HexBigTriTessagon
17-
from tessagon.types.hex_tessagon import HexTessagon
18-
from tessagon.types.hex_tri_tessagon import HexTriTessagon
19-
from tessagon.types.octo_tessagon import OctoTessagon
20-
from tessagon.types.pythagorean_tessagon import PythagoreanTessagon
21-
from tessagon.types.rhombus_tessagon import RhombusTessagon
22-
from tessagon.types.square_tessagon import SquareTessagon
23-
from tessagon.types.square_tri_tessagon import SquareTriTessagon
24-
from tessagon.types.tri_tessagon import TriTessagon
25-
from tessagon.types.weave_tessagon import WeaveTessagon
26-
from tessagon.types.zig_zag_tessagon import ZigZagTessagon
277

28-
from compas_libigl.mapping import map_mesh
29-
from compas_libigl.parametrisation import trimesh_lsc_mapping
30-
31-
TESSAGON_TYPES = {
32-
1: ("Hex", HexTessagon),
33-
2: ("Tri", TriTessagon),
34-
3: ("Octo", OctoTessagon),
35-
4: ("Square", SquareTessagon),
36-
5: ("Rhombus", RhombusTessagon),
37-
6: ("HexTri", HexTriTessagon),
38-
7: ("DissectedSquare", DissectedSquareTessagon),
39-
8: ("DissectedTriangle", DissectedTriangleTessagon),
40-
9: ("DissectedHexQuad", DissectedHexQuadTessagon),
41-
10: ("DissectedHexTri", DissectedHexTriTessagon),
42-
11: ("Floret", FloretTessagon),
43-
12: ("Pythagorean", PythagoreanTessagon),
44-
13: ("Brick", BrickTessagon),
45-
14: ("Weave", WeaveTessagon),
46-
15: ("ZigZag", ZigZagTessagon),
47-
16: ("HexBigTri", HexBigTriTessagon),
48-
17: ("Dodeca", DodecaTessagon),
49-
18: ("SquareTri", SquareTriTessagon),
50-
}
51-
52-
# Pattern selection - change this value to use a different pattern
53-
54-
PATTERN_TYPE = 15
8+
from compas_libigl.mapping import map_pattern_to_mesh
559

5610
# ==============================================================================
5711
# Input geometry: 3D Mesh
@@ -63,62 +17,23 @@
6317
x, y, z = mesh.vertex_attributes(vertex, "xyz") # type: ignore
6418
mesh.vertex_attributes(vertex, "xyz", [x, -z, y])
6519

66-
mesh.translate([2, 2, 0.5])
67-
68-
v, f = mesh.to_vertices_and_faces()
69-
70-
# ==============================================================================
71-
# Input geometry: 2D Pattern creation using Tessagon library, can be other mesh.
72-
# ==============================================================================
73-
74-
options = {
75-
"function": lambda u, v: [u * 1, v * 1, 0],
76-
"u_range": [-0.25, 1.25],
77-
"v_range": [-0.25, 1.25],
78-
"u_num": 20,
79-
"v_num": 20,
80-
"u_cyclic": False,
81-
"v_cyclic": False,
82-
"adaptor_class": ListAdaptor,
83-
}
84-
85-
# Get pattern name and class based on selected pattern type
86-
pattern_name, pattern_class = TESSAGON_TYPES[PATTERN_TYPE]
87-
88-
# Create the selected tessagon pattern
89-
tessagon = pattern_class(**options)
90-
tessagon_mesh = tessagon.create_mesh()
91-
pv = tessagon_mesh["vert_list"]
92-
pf = tessagon_mesh["face_list"]
93-
9420
# ==============================================================================
9521
# Mapping: 3D Mesh, 2D Pattern, UV
9622
# ==============================================================================
97-
98-
mv, mf = map_mesh((v, f), (pv, pf), clip_boundaries=True, tolerance=1e-6)
99-
mesh_mapped = Mesh.from_vertices_and_faces(mv, mf)
100-
101-
print(len(mv))
23+
mesh_mapped = map_pattern_to_mesh("ZigZag", mesh, clip_boundaries=True, tolerance=1e-6, pattern_u=10, pattern_v=10)
10224

10325
# ==============================================================================
10426
# Viewer
10527
# ==============================================================================
10628

10729
config = Config()
108-
config.camera.target = [2, 2, 0.25]
109-
config.camera.position = [5, 2, 1.5]
30+
config.camera.target = [0, 0, 0]
31+
config.camera.position = [0.75, 0, 0.75]
11032

11133
viewer = Viewer(config=config)
11234

11335
viewer.scene.add(mesh, name="mesh", show_faces=False, linecolor=Color.grey(), opacity=0.2)
114-
viewer.scene.add(Mesh.from_vertices_and_faces(pv, pf), name="pattern2d")
11536
viewer.scene.add(mesh_mapped, name="mesh_mapped", facecolor=Color.red())
11637

117-
# To see where the pattern is mapped:
118-
uv = trimesh_lsc_mapping((v, f))
119-
mesh_flattened = mesh.copy()
120-
for i in range(mesh.number_of_vertices()):
121-
mesh_flattened.vertex_attributes(i, "xyz", [uv[i][0], uv[i][1], 0])
122-
viewer.scene.add(mesh_flattened, name="mesh_flattened", show_lines=False, opacity=0.5)
12338

12439
viewer.show()

src/compas_libigl/mapping.py

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,27 @@
11
import numpy as np
2+
from compas.datastructures import Mesh
3+
from tessagon.adaptors.list_adaptor import ListAdaptor
4+
from tessagon.types.brick_tessagon import BrickTessagon
5+
from tessagon.types.dissected_hex_quad_tessagon import DissectedHexQuadTessagon
6+
from tessagon.types.dissected_hex_tri_tessagon import DissectedHexTriTessagon
7+
from tessagon.types.dissected_square_tessagon import DissectedSquareTessagon
8+
from tessagon.types.dissected_triangle_tessagon import DissectedTriangleTessagon
9+
from tessagon.types.dodeca_tessagon import DodecaTessagon
10+
from tessagon.types.floret_tessagon import FloretTessagon
11+
from tessagon.types.hex_big_tri_tessagon import HexBigTriTessagon
12+
from tessagon.types.hex_tessagon import HexTessagon
13+
from tessagon.types.hex_tri_tessagon import HexTriTessagon
14+
from tessagon.types.octo_tessagon import OctoTessagon
15+
from tessagon.types.pythagorean_tessagon import PythagoreanTessagon
16+
from tessagon.types.rhombus_tessagon import RhombusTessagon
17+
from tessagon.types.square_tessagon import SquareTessagon
18+
from tessagon.types.square_tri_tessagon import SquareTriTessagon
19+
from tessagon.types.tri_tessagon import TriTessagon
20+
from tessagon.types.weave_tessagon import WeaveTessagon
21+
from tessagon.types.zig_zag_tessagon import ZigZagTessagon
222

323
from compas_libigl import _mapping
24+
from compas_libigl._types_std import VectorVectorInt # noqa: F401
425

526

627
def map_mesh(target_mesh, pattern_mesh, clip_boundaries=True, tolerance=1e-6):
@@ -45,3 +66,91 @@ def map_mesh(target_mesh, pattern_mesh, clip_boundaries=True, tolerance=1e-6):
4566

4667
# Return the result as a tuple
4768
return pattern_v_numpy_copy, pattern_f_numpy_cleaned
69+
70+
71+
def map_pattern_to_mesh(name, mesh, clip_boundaries=True, tolerance=1e-6, pattern_u=16, pattern_v=16):
72+
"""
73+
Map a 2D pattern mesh onto a 3D target.
74+
75+
Parameters
76+
----------
77+
name : str
78+
The name of the pattern to be created. Options are:
79+
"Hex",
80+
"Tri",
81+
"Octo",
82+
"Square",
83+
"Rhombus",
84+
"HexTri",
85+
"DissectedSquare",
86+
"DissectedTriangle",
87+
"DissectedHexQuad",
88+
"DissectedHexTri",
89+
"Floret",
90+
"Pythagorean",
91+
"Brick",
92+
"Weave",
93+
"ZigZag",
94+
"HexBigTri",
95+
"Dodeca",
96+
"SquareTri"
97+
mesh : compas.datastructures.Mesh
98+
The target mesh.
99+
clip_boundaries : bool
100+
Whether to clip the pattern mesh to the boundaries of the target mesh.
101+
tolerance : float
102+
The tolerance for point comparison, to remove duplicates.
103+
pattern_u : int
104+
The number of pattern vertices in the u direction.
105+
pattern_v : int
106+
The number of pattern vertices in the v direction.
107+
108+
Returns
109+
-------
110+
compas.datastructures.Mesh
111+
The mapped pattern mesh.
112+
"""
113+
114+
TESSAGON_TYPES = {
115+
"Hex": HexTessagon,
116+
"Tri": TriTessagon,
117+
"Octo": OctoTessagon,
118+
"Square": SquareTessagon,
119+
"Rhombus": RhombusTessagon,
120+
"HexTri": HexTriTessagon,
121+
"DissectedSquare": DissectedSquareTessagon,
122+
"DissectedTriangle": DissectedTriangleTessagon,
123+
"DissectedHexQuad": DissectedHexQuadTessagon,
124+
"DissectedHexTri": DissectedHexTriTessagon,
125+
"Floret": FloretTessagon,
126+
"Pythagorean": PythagoreanTessagon,
127+
"Brick": BrickTessagon,
128+
"Weave": WeaveTessagon,
129+
"ZigZag": ZigZagTessagon,
130+
"HexBigTri": HexBigTriTessagon,
131+
"Dodeca": DodecaTessagon,
132+
"SquareTri": SquareTriTessagon,
133+
}
134+
135+
options = {
136+
"function": lambda u, v: [u * 1, v * 1, 0],
137+
"u_range": [-0.255, 1.33],
138+
"v_range": [-0.34, 1.33],
139+
"u_num": pattern_u,
140+
"v_num": pattern_v,
141+
"u_cyclic": False,
142+
"v_cyclic": False,
143+
"adaptor_class": ListAdaptor,
144+
}
145+
146+
# Create the selected tessagon pattern
147+
pattern_class = TESSAGON_TYPES[name]
148+
tessagon = pattern_class(**options)
149+
tessagon_mesh = tessagon.create_mesh()
150+
pv = tessagon_mesh["vert_list"]
151+
pf = tessagon_mesh["face_list"]
152+
153+
v, f = mesh.to_vertices_and_faces()
154+
mv, mf = map_mesh((v, f), (pv, pf), clip_boundaries=clip_boundaries, tolerance=tolerance)
155+
156+
return Mesh.from_vertices_and_faces(mv, mf)

0 commit comments

Comments
 (0)