Skip to content

Commit b79642e

Browse files
committed
The mesh analysis has been restructured.
A new feature has been added to mesh plotting: dart ID visualization. Only the flip action is available. New topological checks are performed after actions.
1 parent 1d771bf commit b79642e

File tree

16 files changed

+299
-89
lines changed

16 files changed

+299
-89
lines changed

environment/actions/smoothing.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,19 @@
22

33
from mesh_model.mesh_struct.mesh import Mesh
44
from mesh_model.mesh_struct.mesh_elements import Node
5-
from mesh_model.mesh_analysis.global_mesh_analysis import GlobalMeshAnalysis
5+
from mesh_model.mesh_analysis.global_mesh_analysis import NodeAnalysis
6+
from view.mesh_plotter.mesh_plots import plot_mesh
7+
68

79
def smoothing_mean(mesh: Mesh) -> True:
810
for i in range (20):
911
#plot_mesh(mesh)
1012
for i, n_info in enumerate (mesh.nodes, start=0):
1113
if n_info[2] >=0:
1214
node_to_smooth = Node(mesh, i)
13-
if not on_boundary(node_to_smooth):
14-
list_darts = adjacent_darts(node_to_smooth)
15+
na = NodeAnalysis(node_to_smooth)
16+
if not na.on_boundary():
17+
list_darts = na.adjacent_darts()
1518
sum_x = 0.0
1619
sum_y = 0.0
1720
nb_nodes = 0.0
@@ -21,4 +24,7 @@ def smoothing_mean(mesh: Mesh) -> True:
2124
sum_x += n.x()
2225
sum_y += n.y()
2326
nb_nodes += 1
27+
if nb_nodes == 0:
28+
plot_mesh(mesh)
29+
raise ValueError("Isolated vertex ")
2430
node_to_smooth.set_xy(sum_x/nb_nodes, sum_y/nb_nodes)

environment/actions/triangular_actions.py

Lines changed: 109 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
from __future__ import annotations
22

3+
from copy import deepcopy
4+
35
from mesh_model.mesh_analysis.trimesh_analysis import TriMeshTopoAnalysis, TriMeshGeoAnalysis
46
from mesh_model.mesh_struct.mesh_elements import Node, Dart
57
from view.mesh_plotter.mesh_plots import plot_mesh
@@ -17,8 +19,16 @@ def flip_edge_ids(mesh_analysis, id1: int, id2: int) -> True:
1719

1820

1921
def flip_edge(mesh_analysis, n1: Node, n2: Node) -> True:
22+
"""
23+
Lors de la bascule d'arete, les relations beta2 ne sont pas impactées, seulement beta1.
24+
:param mesh_analysis:
25+
:param n1:
26+
:param n2:
27+
:return:
28+
"""
29+
valid_action = True
2030
found, d = mesh_analysis.mesh.find_inner_edge(n1, n2)
21-
31+
mesh_before = deepcopy(mesh_analysis.mesh)
2232
if found:
2333
topo, geo = mesh_analysis.isSplitOk(d)
2434
if not geo or not topo:
@@ -55,8 +65,11 @@ def flip_edge(mesh_analysis, n1: Node, n2: Node) -> True:
5565
d211.set_face(f1)
5666
d11.set_face(f2)
5767

58-
check_mesh(mesh_analysis)
59-
return True, topo, geo
68+
topo = check_mesh(mesh_analysis, mesh_before)
69+
if not topo:
70+
mesh_analysis.mesh = deepcopy(mesh_before)
71+
valid_action = False
72+
return valid_action, topo, geo
6073

6174

6275
def split_edge_ids(mesh_analysis, id1: int, id2: int) -> True:
@@ -101,7 +114,8 @@ def collapse_edge_ids(mesh_analysis, id1: int, id2: int) -> True:
101114

102115

103116
def collapse_edge(mesh_analysis, n1: Node, n2: Node) -> True:
104-
found, d = mesh_analysis.mesh.find_inner_edge(n1, n2)
117+
mesh = mesh_analysis.mesh
118+
found, d = mesh.find_inner_edge(n1, n2)
105119

106120
if found:
107121
topo, geo = mesh_analysis.isCollapseOk(d)
@@ -110,11 +124,13 @@ def collapse_edge(mesh_analysis, n1: Node, n2: Node) -> True:
110124
else:
111125
return False, False, True # the geometrical criteria is True because if the dart is not found, it means it's a boundary dart
112126

113-
_, d1, d11, d21, d211, n1, n2, n3, n4 = mesh_analysis.mesh.active_triangles(d)
127+
d2, d1, d11, d21, d211, n1, n2, n3, n4 = mesh.active_triangles(d)
114128

115129
d212 = d21.get_beta(2) #T1
116130
d2112 = d211.get_beta(2) #T2
117131
d12 = d1.get_beta(2) #T3
132+
if not mesh.is_dart_active(d12):
133+
print("error")
118134
d112 = d11.get_beta(2) #T4
119135

120136
#Delete the darts around selected dart
@@ -127,27 +143,33 @@ def collapse_edge(mesh_analysis, n1: Node, n2: Node) -> True:
127143
#Check if nodes n3 and n4 are not linked to deleted dart
128144

129145
if n3.get_dart().id == d11.id:
130-
if d12 is not None:
146+
if mesh.is_dart_active(d12):
131147
n3.set_dart(d12)
132148
else:
133149
n3.set_dart(d112.get_beta(1))
134150
if n4.get_dart().id == d211.id:
135-
if d212 is not None:
151+
if mesh.is_dart_active(d212):
136152
n4.set_dart(d212)
137153
else:
138154
n4.set_dart(d2112.get_beta(1))
155+
if n1.get_dart().id == d.id or n1.get_dart().id == d21.id:
156+
if mesh.is_dart_active(d112):
157+
n1.set_dart(d112)
158+
else:
159+
n1.set_dart(d2112)
160+
139161

140162
#Update node relations
141-
if d12 is not None:
163+
if mesh.is_dart_active(d12):
142164
d121 = d12.get_beta(1)
143165
d121.set_node(n1)
144166
ds = d121
145167
while ds is not None and ds != d2112:
146168
i+=1
147169
d2s = ds.get_beta(2)
148-
if d2s is None:
170+
if not mesh.is_dart_active(d2s):
149171
ds = d2112
150-
while ds is not None:
172+
while mesh.is_dart_active(ds):
151173
i+=1
152174
ds.set_node(n1)
153175
ds1 = ds.get_beta(1)
@@ -173,14 +195,14 @@ def collapse_edge(mesh_analysis, n1: Node, n2: Node) -> True:
173195
ds2 = ds.get_beta(2)
174196
"""
175197
#update beta2 relations
176-
if d112 is not None:
198+
if mesh.is_dart_active(d112):
177199
d112.set_beta(2, d12)
178-
if d12 is not None:
200+
if mesh.is_dart_active(d12):
179201
d12.set_beta(2, d112)
180202

181-
if d212 is not None:
203+
if mesh.is_dart_active(d212):
182204
d212.set_beta(2, d2112)
183-
if d2112 is not None:
205+
if mesh.is_dart_active(d2112):
184206
d2112.set_beta(2, d212)
185207

186208
#delete n2 node
@@ -189,19 +211,87 @@ def collapse_edge(mesh_analysis, n1: Node, n2: Node) -> True:
189211
check_mesh(mesh_analysis)
190212
return True, topo, geo
191213

192-
def check_mesh(mesh_analysis):
214+
def check_mesh(mesh_analysis, mesh_before=None) -> bool:
193215
for dart_info in mesh_analysis.mesh.active_darts():
194216
#Check beta2 relation
195217
d = dart_info[0]
196218
d2 = dart_info[2]
219+
# if associated twin dart no longer exist
197220
if d2 >= 0 and mesh_analysis.mesh.dart_info[d2, 0] < 0:
221+
return False
222+
# if beta2 relation is not symetrical
223+
elif d2 >= 0 and mesh_analysis.mesh.dart_info[d2, 2] != d:
224+
return False
225+
# null dart
226+
elif d2>=0 and mesh_analysis.mesh.dart_info[d2, 3] == mesh_analysis.mesh.dart_info[d, 3]:
227+
return False
228+
#if adjacent face is the same
229+
elif d2>=0 and mesh_analysis.mesh.dart_info[d2, 4] == mesh_analysis.mesh.dart_info[d, 4]:
230+
return False
231+
232+
233+
d1 = mesh_analysis.mesh.dart_info[d,1]
234+
d11 = mesh_analysis.mesh.dart_info[d1,1]
235+
236+
#Check beta1
237+
if mesh_analysis.mesh.dart_info[d11,1]!=d :
238+
return False
239+
240+
if d2 >= 0 :
241+
d = Dart(mesh_analysis.mesh, d)
242+
d2, d1, d11, d21, d211, n1, n2, n3, n4 = mesh_analysis.mesh.active_triangles(d)
243+
if len(set([n1.id, n2.id, n3.id, n4.id])) < 4:
244+
return False
245+
return True
246+
247+
248+
def check_mesh_debug(mesh_analysis, mesh_before=None)->True:
249+
for dart_info in mesh_analysis.mesh.active_darts():
250+
#Check beta2 relation
251+
d = dart_info[0]
252+
d2 = dart_info[2]
253+
# if associated twin dart no longer exist
254+
if d2 >= 0 and mesh_analysis.mesh.dart_info[d2, 0] < 0:
255+
plot_mesh(mesh_analysis.mesh)
256+
if mesh_before is not None:
257+
plot_mesh(mesh_before)
198258
raise ValueError("error beta2")
259+
# if beta2 relation is not symetrical
199260
elif d2 >= 0 and mesh_analysis.mesh.dart_info[d2, 2] != d:
261+
plot_mesh(mesh_analysis.mesh)
262+
if mesh_before is not None:
263+
plot_mesh(mesh_before)
200264
raise ValueError("error beta2")
265+
# null dart
266+
elif d2>=0 and mesh_analysis.mesh.dart_info[d2, 3] == mesh_analysis.mesh.dart_info[d, 3]:
267+
plot_mesh(mesh_analysis.mesh)
268+
if mesh_before is not None:
269+
plot_mesh(mesh_before)
270+
raise ValueError("same node for twin darts")
271+
#if adjacent face is the same
272+
elif d2>=0 and mesh_analysis.mesh.dart_info[d2, 4] == mesh_analysis.mesh.dart_info[d, 4]:
273+
plot_mesh(mesh_analysis.mesh)
274+
if mesh_before is not None:
275+
plot_mesh(mesh_before)
276+
raise ValueError("same adjacent face")
277+
278+
279+
d1 = mesh_analysis.mesh.dart_info[d,1]
280+
d11 = mesh_analysis.mesh.dart_info[d1,1]
201281

202282
#Check beta1
203-
d = Dart(mesh_analysis.mesh, d)
204-
d1 = d.get_beta(1)
205-
d11 = d1.get_beta(1)
206-
if d11.get_beta(1)!=d :
283+
if mesh_analysis.mesh.dart_info[d11,1]!=d :
284+
plot_mesh(mesh_analysis.mesh)
285+
if mesh_before is not None:
286+
plot_mesh(mesh_before)
207287
raise ValueError("error beta1")
288+
289+
if d2 >= 0 :
290+
d = Dart(mesh_analysis.mesh, d)
291+
d2, d1, d11, d21, d211, n1, n2, n3, n4 = mesh_analysis.mesh.active_triangles(d)
292+
293+
if len(set([n1.id, n2.id, n3.id, n4.id])) < 4:
294+
plot_mesh(mesh_analysis.mesh)
295+
if mesh_before is not None:
296+
plot_mesh(mesh_before)
297+
raise ValueError("same traingle for two faces")
Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
{
2-
"env_name": "Quadmesh-v0",
3-
"mesh_size": 16,
2+
"env_name": "Trimesh-v0",
3+
"mesh_size": 10,
44
"max_episode_steps": 20,
5-
"n_darts_selected": 10,
6-
"deep": 8,
5+
"n_darts_selected": 11,
6+
"deep": 6,
77
"action_restriction": false,
88
"with_degree_observation": false
99
}
Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
from trimesh_env.wrappers.clip_reward import ClipReward
2-
from trimesh_env.wrappers.discrete_actions import DiscreteActions
3-
from trimesh_env.wrappers.reacher_weighted_reward import ReacherRewardWrapper
4-
from trimesh_env.wrappers.relative_position import RelativePosition
1+
from environment.gymnasium_envs.quadmesh_env.wrappers.clip_reward import ClipReward
2+
from environment.gymnasium_envs.quadmesh_env.wrappers.discrete_actions import DiscreteActions
3+
from environment.gymnasium_envs.quadmesh_env.wrappers.reacher_weighted_reward import ReacherRewardWrapper
4+
from environment.gymnasium_envs.quadmesh_env.wrappers.relative_position import RelativePosition
5+
from environment.gymnasium_envs.quadmesh_env.wrappers.dummy_vertices_observation import

environment/gymnasium_envs/trimesh_full_env/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,5 @@
55
id="Trimesh-v0",
66
entry_point="environment.gymnasium_envs.trimesh_full_env.envs:TriMeshEnvFull",
77
max_episode_steps=100,
8-
kwargs={"mesh": None, "mesh_size": 30, "n_darts_selected": 20, "deep": 6, "with_degree_obs": True, "action_restriction": False},
8+
kwargs={"mesh": None, "mesh_size": 7, "n_darts_selected": 20, "deep": 6, "with_degree_obs": False, "action_restriction": False},
99
)

0 commit comments

Comments
 (0)