Skip to content

Commit 4eaa01a

Browse files
committed
New set of quadrangular actions (flip, split, collapse, cleanup)
File reorganisation to integrate a quadrangular environment.
1 parent 018b517 commit 4eaa01a

File tree

111 files changed

+1425
-388
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

111 files changed

+1425
-388
lines changed

actions/quadrangular_actions.py

Lines changed: 202 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,202 @@
1+
from __future__ import annotations
2+
3+
from mesh_model.mesh_struct.mesh import Mesh
4+
from mesh_model.mesh_struct.mesh_elements import Dart, Node
5+
from mesh_model.mesh_analysis.mesh_analysis import adjacent_darts, degree, mesh_check
6+
from mesh_model.mesh_analysis.quadmesh_analysis import isFlipOk, isCollapseOk, isSplitOk, isCleanupOk
7+
8+
9+
def flip_edge_ids(mesh: Mesh, id1: int, id2: int) -> True:
10+
return flip_edge(mesh, Node(mesh, id1), Node(mesh, id2))
11+
12+
13+
def flip_edge(mesh: Mesh, n1: Node, n2: Node) -> (True, True, True):
14+
found, d = mesh.find_inner_edge(n1, n2)
15+
16+
if found:
17+
topo, geo = isFlipOk(d)
18+
if not geo or not topo:
19+
return False, topo, geo
20+
else:
21+
return False, False, False
22+
23+
d2, d1, d11, d111, d21, d211, d2111, n1, n2, n3, n4, n5, n6 = mesh.active_quadrangles(d)
24+
25+
f1 = d.get_face()
26+
f2 = d2.get_face()
27+
28+
# Update beta 1
29+
d.set_beta(1, d11)
30+
d111.set_beta(1, d21)
31+
d21.set_beta(1, d)
32+
d2.set_beta(1, d211)
33+
d2111.set_beta(1, d1)
34+
d1.set_beta(1, d2)
35+
36+
37+
if n1.get_dart().id == d.id:
38+
n1.set_dart(d21)
39+
if n2.get_dart().id == d2.id:
40+
n2.set_dart(d1)
41+
42+
if f1.get_dart().id == d1.id:
43+
f1.set_dart(d)
44+
45+
if f2.get_dart().id == d21.id:
46+
f2.set_dart(d2)
47+
48+
d.set_node(n5)
49+
d2.set_node(n3)
50+
d21.set_face(f1)
51+
d1.set_face(f2)
52+
53+
return True, topo, geo
54+
55+
56+
def split_edge_ids(mesh: Mesh, id1: int, id2: int) -> True:
57+
return split_edge(mesh, Node(mesh, id1), Node(mesh, id2))
58+
59+
60+
def split_edge(mesh: Mesh, n1: Node, n2: Node) -> True:
61+
found, d = mesh.find_inner_edge(n1, n2)
62+
63+
if found:
64+
topo, geo = isSplitOk(d)
65+
if not geo or not topo:
66+
return False, topo, geo
67+
else:
68+
return False, True, False
69+
70+
d2, d1, d11, d111, d21, d211, d2111, n1, n2, n3, n4, n5, n6 = mesh.active_quadrangles(d)
71+
d1112 = d111.get_beta(2)
72+
d212 = d21.get_beta(2)
73+
74+
# create a new node in the middle of [n1, n2]
75+
N10 = mesh.add_node((n1.x() + n2.x()) / 2, (n1.y() + n2.y()) / 2)
76+
77+
# modify existing triangles
78+
d.set_node(N10)
79+
d21.set_node(N10)
80+
81+
# create a new quadrangle
82+
f5 = mesh.add_quad(n1, n5, N10, n4)
83+
84+
# update beta2 relations
85+
mesh.set_face_beta2(f5,[d111,d1112,d21,d212])
86+
87+
adj_n1 = adjacent_darts(n1)
88+
adj_n2 = adjacent_darts(N10)
89+
90+
deg1 = degree(n1)
91+
deg2 = degree(N10)
92+
93+
return True, topo, geo
94+
95+
96+
def collapse_edge_ids(mesh: Mesh, id1: int, id2: int) -> True:
97+
return collapse_edge(mesh, Node(mesh, id1), Node(mesh, id2))
98+
99+
100+
def collapse_edge(mesh: Mesh, n1: Node, n2: Node) -> True:
101+
found, d = mesh.find_inner_edge(n1, n2)
102+
if found:
103+
topo, geo = isCollapseOk(d)
104+
if not geo or not topo:
105+
return False, topo, geo
106+
else:
107+
return False, False, False
108+
109+
d2, d1, d11, d111, d21, d211, d2111, n1, n2, n3, n4, n5, n6 = mesh.active_quadrangles(d)
110+
111+
d1112 = d111.get_beta(2)
112+
d12 = d1.get_beta(2)
113+
d112 = d11.get_beta(2)
114+
115+
# Move n3 node in the middle of [n3, n1]
116+
n3.set_xy((n3.x() + n1.x()) / 2, (n1.y() + n3.y()) / 2)
117+
118+
#Delete the face F5
119+
f5 = d.get_face()
120+
mesh.del_quad(d, d1, d11, d111, f5)
121+
122+
n_from = n1
123+
n_to = n3
124+
adj_darts = adjacent_darts(n_from)
125+
126+
for d in adj_darts:
127+
if d.get_node() == n_from:
128+
d.set_node(n_to)
129+
mesh.del_node(n_from)
130+
131+
#Update beta2 relations
132+
if d2 is not None:
133+
d2.set_beta(2, d12)
134+
d21 = d2.get_beta(1)
135+
d21.set_node(n3)
136+
if d1112 is not None:
137+
d1112.set_beta(2, d112)
138+
d1112.set_node(n3)
139+
if d12 is not None:
140+
d12.set_beta(2, d2)
141+
if d112 is not None:
142+
d112.set_beta(2, d1112)
143+
144+
return mesh_check(mesh), topo, geo
145+
146+
147+
def cleanup_edge_ids(mesh: Mesh, id1: int, id2: int) -> True:
148+
return cleanup_edge(mesh, Node(mesh, id1), Node(mesh, id2))
149+
150+
def cleanup_edge(mesh: Mesh, n1: Node, n2: Node) -> True:
151+
found, d = mesh.find_inner_edge(n1, n2)
152+
if found:
153+
topo, geo = isCleanupOk(d)
154+
if not geo or not topo:
155+
return False, topo, geo
156+
else:
157+
return False, False, False
158+
159+
parallel_darts = mesh.find_parallel_darts(d)
160+
161+
last_dart = parallel_darts[-1]
162+
ld1 = last_dart.get_beta(1)
163+
ld11 = ld1.get_beta(1)
164+
ld111 = ld11.get_beta(1)
165+
last_node = ld111.get_node()
166+
node_to = ld11.get_node()
167+
adj_darts = adjacent_darts(last_node)
168+
mesh.del_node(last_node)
169+
170+
for da in adj_darts:
171+
if da.get_node() == last_node:
172+
da.set_node(node_to)
173+
174+
for d in parallel_darts:
175+
f = d.get_face()
176+
d1 = d.get_beta(1)
177+
d11 = d1.get_beta(1)
178+
d111 = d11.get_beta(1)
179+
180+
n_from = d.get_node()
181+
n_to = d1.get_node()
182+
183+
# update beta 2 relations
184+
d12 = d1.get_beta(2)
185+
d1112 = d111.get_beta(2)
186+
if d1112 is not None:
187+
d1112.set_beta(2, d12)
188+
if d12 is not None:
189+
d12.set_beta(2, d1112)
190+
191+
mesh.del_quad(d, d1, d11, d111, f)
192+
193+
194+
195+
adj_darts = adjacent_darts(n_from)
196+
197+
for d in adj_darts:
198+
if d.get_node() == n_from:
199+
d.set_node(n_to)
200+
mesh.del_node(n_from)
201+
202+
return mesh_check(mesh), topo, geo

actions/triangular_actions.py

Lines changed: 4 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22

33
from mesh_model.mesh_struct.mesh import Mesh
44
from mesh_model.mesh_struct.mesh_elements import Dart, Node
5-
from mesh_model.mesh_analysis import isFlipOk, isCollapseOk, isSplitOk
5+
from mesh_model.mesh_analysis.mesh_analysis import mesh_check
6+
from mesh_model.mesh_analysis.trimesh_analysis import isFlipOk, isCollapseOk, isSplitOk
67

78

89
def flip_edge_ids(mesh: Mesh, id1: int, id2: int) -> True:
@@ -78,11 +79,11 @@ def split_edge(mesh: Mesh, n1: Node, n2: Node) -> True:
7879
F4 = mesh.add_triangle(N5, n1, n4)
7980

8081
# update beta2 relations
81-
mesh.set_face_beta2(F3, (d1, d2))
82+
mesh.set_face_beta2(F3, [d1, d2])
8283
d2b2 = d2.get_beta(2)
8384
d2b21 = d2b2.get_beta(1)
8485
mesh.set_beta2(d2b21)
85-
mesh.set_face_beta2(F4, (d, d21))
86+
mesh.set_face_beta2(F4, [d, d21])
8687
db2 = d.get_beta(2)
8788
db21 = db2.get_beta(1)
8889
mesh.set_beta2(db21)
@@ -157,45 +158,3 @@ def collapse_edge(mesh: Mesh, n1: Node, n2: Node) -> True:
157158
mesh.del_node(n2)
158159

159160
return mesh_check(mesh), topo, geo
160-
161-
162-
def check_beta2_relation(mesh: Mesh) -> bool:
163-
for dart_info in mesh.active_darts():
164-
d = dart_info[0]
165-
d2 = dart_info[2]
166-
if d2 >= 0 and mesh.dart_info[d2, 0] < 0:
167-
raise ValueError("error beta2")
168-
elif d2 >= 0 and mesh.dart_info[d2, 2] != d:
169-
raise ValueError("error beta2")
170-
return True
171-
172-
173-
def check_double(mesh: Mesh) -> bool:
174-
for dart_info in mesh.active_darts():
175-
d = Dart(mesh, dart_info[0])
176-
d2 = Dart(mesh, dart_info[2]) if dart_info[2] >= 0 else None
177-
n1 = dart_info[3]
178-
if d2 is None:
179-
d1 = d.get_beta(1)
180-
n2 = d1.get_node().id
181-
else:
182-
n2 = d2.get_node().id
183-
for dart_info2 in mesh.active_darts():
184-
ds = Dart(mesh, dart_info2[0])
185-
ds2 = Dart(mesh, dart_info2[2]) if dart_info2[2] >= 0 else None
186-
if d != ds and d != ds2:
187-
ns1 = dart_info2[3]
188-
if ds2 is None:
189-
ds1 = ds.get_beta(1)
190-
ns2 = ds1.get_node().id
191-
else:
192-
ns2 = ds2.get_node().id
193-
194-
if n1 == ns1 and n2 == ns2:
195-
raise ValueError("double error")
196-
elif n2 == ns1 and n1 == ns2:
197-
return False
198-
return True
199-
200-
def mesh_check(mesh: Mesh) -> bool:
201-
return check_double(mesh) and check_beta2_relation(mesh)
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
from gymnasium.envs.registration import register
2+
from environment.gymnasium_envs.quadmesh_env.envs.quadmesh import QuadMeshEnv
3+
4+
register(
5+
id="Quadmesh-v0",
6+
entry_point="environment.gymnasium_envs.quadmesh_env.envs:QuadMeshEnv",
7+
max_episode_steps=100,
8+
kwargs={"mesh": None, "mesh_size": 30, "n_darts_selected": 20, "deep": 6, "with_degree_obs": True, "action_restriction": False},
9+
)
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
from environment.gymnasium_envs.trimesh_full_env.envs.trimesh import TriMeshEnvFull

0 commit comments

Comments
 (0)