Skip to content

Commit 3b02c5b

Browse files
author
Robin Oval
committed
disconnected mesh and network elements based on compas.topology.connected_components
mesh and network explode
1 parent c94b97f commit 3b02c5b

File tree

4 files changed

+229
-1
lines changed

4 files changed

+229
-1
lines changed

src/compas/datastructures/mesh/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
from .bbox import *
1717
from .descent import *
1818
from .duality import *
19+
from .explode import *
1920
from .geodesics import *
2021
from .join import *
2122
from .laplacian import *
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
from __future__ import print_function
2+
from __future__ import absolute_import
3+
from __future__ import division
4+
5+
from compas.topology import connected_components
6+
7+
__all__ = [
8+
'mesh_disconnected_vertices',
9+
'mesh_disconnected_faces',
10+
'mesh_explode',
11+
]
12+
13+
def mesh_disconnected_vertices(mesh):
14+
"""Get the disconnected vertex groups in a mesh.
15+
16+
Parameters
17+
----------
18+
mesh : Mesh
19+
A mesh.
20+
21+
Returns
22+
-------
23+
parts : list
24+
The list of disconnected vertex groups.
25+
26+
"""
27+
28+
return connected_components(mesh.adjacency)
29+
30+
def mesh_disconnected_faces(mesh):
31+
"""Get the disconnected face groups in a mesh.
32+
33+
Parameters
34+
----------
35+
mesh : Mesh
36+
A mesh.
37+
38+
Returns
39+
-------
40+
parts : list
41+
The list of disconnected face groups.
42+
43+
"""
44+
45+
parts = mesh_disconnected_vertices(mesh)
46+
47+
return [set([fkey for vkey in part for fkey in mesh.vertex_faces(vkey)]) for part in parts]
48+
49+
def mesh_explode(mesh, cls=None):
50+
"""Explode a mesh into its disconnected parts.
51+
52+
Parameters
53+
----------
54+
mesh : Mesh
55+
A mesh.
56+
57+
Returns
58+
-------
59+
exploded_meshes : list
60+
The list of the meshes from the exploded mesh parts.
61+
62+
"""
63+
64+
if cls is None:
65+
cls = type(mesh)
66+
67+
parts = mesh_disconnected_faces(mesh)
68+
69+
exploded_meshes = []
70+
71+
for part in parts:
72+
73+
vertex_keys = list(set([vkey for fkey in part for vkey in mesh.face_vertices(fkey)]))
74+
vertices = [mesh.vertex_coordinates(vkey) for vkey in vertex_keys]
75+
76+
key_to_index = {vkey: i for i, vkey in enumerate(vertex_keys)}
77+
faces = [ [key_to_index[vkey] for vkey in mesh.face_vertices(fkey)] for fkey in part]
78+
79+
exploded_meshes.append(cls.from_vertices_and_faces(vertices, faces))
80+
81+
return exploded_meshes
82+
83+
# ==============================================================================
84+
# Main
85+
# ==============================================================================
86+
87+
if __name__ == '__main__':
88+
89+
from compas.datastructures import Mesh
90+
91+
vertices = [
92+
[0.0, 0.0, 0.0],
93+
[1.0, 0.0, 0.0],
94+
[2.0, 0.0, 0.0],
95+
[2.0, 0.0, 0.0],
96+
[3.0, 0.0, 0.0],
97+
[0.0, 1.0, 0.0],
98+
[1.0, 1.0, 0.0],
99+
[2.0, 1.0, 0.0],
100+
[2.0, 1.0, 0.0],
101+
[3.0, 1.0, 0.0],
102+
]
103+
104+
faces = [
105+
[0, 1, 6, 5],
106+
[1, 2, 7, 6],
107+
[3, 4, 9, 8]
108+
]
109+
110+
mesh = Mesh.from_vertices_and_faces(vertices, faces)
111+
112+
print(mesh_disconnected_vertices(mesh))
113+
print(mesh_disconnected_faces(mesh))
114+
print(mesh_explode(mesh))

src/compas/datastructures/network/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@
88
from .combinatorics import *
99
from .complementarity import *
1010
from .duality import *
11+
from .explode import *
1112
from .parallelisation import *
1213
from ._planarity import *
1314
from .smoothing import *
1415
from .transformations import *
1516

16-
1717
__all__ = [name for name in dir() if not name.startswith('_')]
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
from __future__ import print_function
2+
from __future__ import absolute_import
3+
from __future__ import division
4+
5+
from compas.topology import connected_components
6+
7+
__all__ = [
8+
'network_disconnected_vertices',
9+
'network_disconnected_edges',
10+
'network_explode'
11+
]
12+
13+
def network_disconnected_vertices(network):
14+
"""Get the disconnected vertex groups in a network.
15+
16+
Parameters
17+
----------
18+
network : Network
19+
A network.
20+
21+
Returns
22+
-------
23+
list
24+
The list of disconnected vertex groups.
25+
26+
"""
27+
28+
return connected_components(network.adjacency)
29+
30+
def network_disconnected_edges(network):
31+
"""Get the disconnected edge groups in a network.
32+
33+
Parameters
34+
----------
35+
network : Network
36+
A network.
37+
38+
Returns
39+
-------
40+
parts : list
41+
The list of disconnected edge groups.
42+
43+
"""
44+
45+
46+
parts = network_disconnected_vertices(network)
47+
48+
return [[(u, v) for u in part for v in network.vertex_neighbors(u) if u < v] for part in parts]
49+
50+
51+
def network_explode(network, cls=None):
52+
"""Explode a network into its disconnected parts.
53+
54+
Parameters
55+
----------
56+
network : Network
57+
A network.
58+
59+
Returns
60+
-------
61+
exploded_networks : list
62+
The list of the networks from the exploded network parts.
63+
64+
"""
65+
66+
if cls is None:
67+
cls = type(network)
68+
69+
parts = network_disconnected_edges(network)
70+
71+
exploded_networks = []
72+
73+
for part in parts:
74+
75+
vertex_keys = list(set([vkey for edge in part for vkey in edge]))
76+
vertices = [network.vertex_coordinates(vkey) for vkey in vertex_keys]
77+
78+
key_to_index = {vkey: i for i, vkey in enumerate(vertex_keys)}
79+
edges = [ (key_to_index[u], key_to_index[v]) for u, v in part]
80+
81+
exploded_networks.append(cls.from_vertices_and_edges(vertices, edges))
82+
83+
return exploded_networks
84+
85+
86+
87+
# ==============================================================================
88+
# Main
89+
# ==============================================================================
90+
91+
if __name__ == "__main__":
92+
93+
from compas.datastructures import Network
94+
95+
vertices = [
96+
[0.0, 0.0, 0.0],
97+
[1.0, 0.0, 0.0],
98+
[2.0, 0.0, 0.0],
99+
[3.0, 0.0, 0.0],
100+
[4.0, 0.0, 0.0],
101+
]
102+
103+
edges = [
104+
(0, 1),
105+
(2, 3),
106+
(3, 4),
107+
]
108+
109+
network = Network.from_vertices_and_edges(vertices, edges)
110+
111+
print(network_disconnected_vertices(network))
112+
print(network_disconnected_edges(network))
113+
print(network_explode(network))

0 commit comments

Comments
 (0)