Skip to content

Commit a20b1ea

Browse files
committed
Latest from sibernetic repo
1 parent 3f0e427 commit a20b1ea

File tree

1 file changed

+190
-79
lines changed

1 file changed

+190
-79
lines changed

SiberneticReplay.py

Lines changed: 190 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -8,47 +8,110 @@
88
import pyvista as pv
99
import sys
1010
import os
11+
import time
12+
import json
13+
import numpy as np
14+
import matplotlib.pyplot as plt
1115

12-
last_mesh = None
1316

14-
all_points = []
15-
all_point_types = []
17+
last_meshes = {}
1618

17-
boundary_points = []
18-
boundary_point_types = [3, 3.1]
19+
replay_speed = 0.05 # seconds between frames
20+
replaying = False
1921

20-
point_size = 5
21-
boundary_point_size = 3
22+
all_points = []
23+
all_point_types = []
2224

23-
boundary_color = "#eeeeee"
2425

2526
plotter = None
26-
27-
offset_ = 50
28-
29-
color_range = {1.1: "blue", 2.2: "turquoise"}
27+
offset_ = 0
28+
slider = None
29+
30+
show_boundary = False
31+
32+
33+
def get_color_info_for_type(type_):
34+
"""
35+
Get color, info string and point size for a given point type
36+
returns: color, info, size
37+
"""
38+
39+
if type_ == 1.1:
40+
return "#8BEBFC", "liquid 1", 5
41+
elif type_ == 1.2:
42+
return "#3ACFF0", "liquid 2", 5
43+
elif type_ == 2.1:
44+
return "yellow", "elastic 1", 5
45+
elif type_ == 2.2:
46+
return "#FF0000", "elastic 2", 5
47+
elif type_ > 2 and type_ < 3:
48+
return "#00cc00", "elastic variable", 5
49+
elif type_ == 3:
50+
return "grey", "boundary 0", 3
51+
elif type_ == 3.1:
52+
return "black", "boundary 1", 7
53+
else:
54+
return "orange", "unknown", 5
3055

3156

3257
def add_sibernetic_model(
3358
pl,
3459
position_file="Sibernetic/position_buffer.txt",
60+
report_file=None,
3561
swap_y_z=False,
36-
offset=50,
62+
offset=0,
3763
include_boundary=False,
3864
):
39-
global all_points, all_point_types, last_mesh, plotter, offset_
65+
global all_points, all_point_types, last_meshes, plotter, offset_, slider, show_boundary
4066

4167
offset_ = offset
4268
plotter = pl
69+
show_boundary = include_boundary
4370

44-
points = []
71+
points = {}
4572
types = []
4673

4774
line_count = 0
4875
pcount = 0
4976
time_count = 0
5077
logStep = None
5178

79+
report_data = None
80+
count_point_types = {}
81+
82+
if report_file is not None:
83+
sim_dir = os.path.dirname(os.path.abspath(report_file))
84+
report_data = json.load(open(report_file, "r"))
85+
print(report_data)
86+
position_file = os.path.join(sim_dir, "position_buffer.txt")
87+
88+
if "worm" in report_data["configuration"]:
89+
muscle_activation_file = os.path.join(
90+
sim_dir, "muscles_activity_buffer.txt"
91+
)
92+
print("Loading muscle activation file from: %s" % muscle_activation_file)
93+
musc_dat = np.loadtxt(muscle_activation_file, delimiter="\t").T
94+
print(musc_dat)
95+
print(musc_dat.shape)
96+
# plt.imshow(musc_dat, interpolation="none", aspect="auto", cmap="YlOrRd")
97+
98+
f, ax = plt.subplots(tight_layout=True)
99+
ax.imshow(musc_dat, interpolation="none", aspect="auto", cmap="YlOrRd")
100+
# ax.set_ylim([-1, 1])
101+
ax.set_xlabel("Time (s)")
102+
_ = ax.set_ylabel("Muscle")
103+
104+
h_chart = pv.ChartMPL(f, size=(0.35, 0.35), loc=(0.02, 0.06))
105+
h_chart.title = None
106+
h_chart.border_color = "white"
107+
h_chart.show_title = False
108+
h_chart.background_color = (1.0, 1.0, 1.0, 0.4)
109+
pl.add_chart(
110+
h_chart,
111+
)
112+
113+
first_pass_complete = False
114+
52115
for line in open(position_file):
53116
ws = line.split()
54117
# print(ws)
@@ -65,40 +128,34 @@ def add_sibernetic_model(
65128

66129
if len(ws) == 4:
67130
type_ = float(ws[3])
131+
if type_ not in points:
132+
points[type_] = []
68133

69-
if type_ not in boundary_point_types:
70-
if swap_y_z:
71-
points.append([float(ws[1]), 1 * float(ws[0]), float(ws[2])])
72-
else:
73-
points.append([float(ws[0]), float(ws[1]), float(ws[2])])
74-
75-
types.append(type_)
134+
if not first_pass_complete:
135+
if type_ not in count_point_types:
136+
count_point_types[type_] = 0
137+
count_point_types[type_] += 1
76138

139+
if swap_y_z:
140+
points[type_].append([float(ws[1]), 1 * float(ws[0]), float(ws[2])])
77141
else:
78-
if include_boundary:
79-
if swap_y_z:
80-
boundary_points.append(
81-
[float(ws[1]), 1 * float(ws[0]), float(ws[2])]
82-
)
83-
else:
84-
boundary_points.append(
85-
[float(ws[0]), float(ws[1]), float(ws[2])]
86-
)
87-
88-
# types.append(type_)
142+
points[type_].append([float(ws[0]), float(ws[1]), float(ws[2])])
143+
144+
types.append(type_)
89145

90146
if logStep is not None:
91147
pcount += 1
92148

93149
if pcount == numOfBoundaryP + numOfElasticP + numOfLiquidP:
150+
first_pass_complete = True
94151
print(
95-
"End of one batch of %i added, %i total points at line %i, time: %i"
96-
% (len(points), pcount, line_count, time_count)
152+
"End of one batch of %i total points (%i types), at line %i, time: %i"
153+
% (pcount, len(points), line_count, time_count)
97154
)
98155
all_points.append(points)
99156
all_point_types.append(types)
100157

101-
points = []
158+
points = {}
102159
types = []
103160
pcount = 0
104161
numOfBoundaryP = 0
@@ -107,10 +164,8 @@ def add_sibernetic_model(
107164

108165
line_count += 1
109166

110-
# all_points_np = np.array(all_points)
111-
112167
print(
113-
"Loaded positions with %i elastic, %i liquid and %i boundary points (%i total), %i lines"
168+
"Loaded positions with %i elastic, %i liquid and %i boundary points (%i total), over %i lines"
114169
% (
115170
numOfElasticP,
116171
numOfLiquidP,
@@ -120,62 +175,106 @@ def add_sibernetic_model(
120175
)
121176
)
122177

123-
if include_boundary:
124-
bound_mesh = pv.PolyData(boundary_points)
125-
bound_mesh.translate((offset_, -50, -100), inplace=True)
126-
127-
plotter.add_mesh(
128-
bound_mesh,
129-
render_points_as_spheres=True,
130-
color=boundary_color,
131-
point_size=boundary_point_size,
132-
)
133-
134178
print("Num of time points found: %i" % len(all_points))
179+
print("Count of point types found: %s" % dict(sorted(count_point_types.items())))
135180

136181
create_mesh(0)
137182

138-
plotter.remove_scalar_bar("types")
139-
140183
max_time = len(all_points) - 1
141-
pl.add_slider_widget(create_mesh, rng=[0, max_time], value=0, title="Time point")
142-
pl.add_timer_event(max_steps=5, duration=2, callback=create_mesh)
143184

185+
slider = pl.add_slider_widget(
186+
create_mesh, rng=[0, max_time], value=0, title="Time point", style="modern"
187+
)
188+
189+
pl.add_checkbox_button_widget(play_animation, value=False)
144190

145-
def create_mesh(step):
146-
import time
147191

192+
def play_animation(play):
193+
global plotter, last_meshes, all_points, all_point_types, replaying, slider
194+
print("Playing animation: %s" % play)
195+
196+
if not play:
197+
replaying = False
198+
print("Animation stopped.")
199+
return
200+
else:
201+
replaying = True
202+
print("Animation started.")
203+
204+
if last_meshes is None:
205+
print("No meshes to animate. Please load a model first.")
206+
return
207+
208+
for i in range(len(all_points)):
209+
if not replaying:
210+
break
211+
curr_time = slider.GetSliderRepresentation().GetValue()
212+
213+
print(
214+
" --- Animating step %i (curr_time: %s) of %i, %s"
215+
% (i, curr_time, len(all_points), play)
216+
)
217+
next_time = curr_time + 1
218+
slider.GetSliderRepresentation().SetValue(next_time)
219+
220+
create_mesh(next_time)
221+
plotter.update()
222+
plotter.render()
223+
time.sleep(replay_speed)
224+
225+
226+
def create_mesh(step):
148227
step_count = step
149228
value = step_count
150-
global all_points, all_point_types, last_mesh, plotter, offset_
229+
global all_points, last_meshes, plotter, offset_, replaying, show_boundary
151230

152231
index = int(value)
232+
if index >= len(all_points):
233+
print(
234+
"Index %i out of bounds for all_points with length %i"
235+
% (index, len(all_points))
236+
)
237+
replaying = False
238+
return
153239

154-
print("Changing to time point: %s (%s) " % (index, value))
155-
curr_points = all_points[index]
156-
curr_types = all_point_types[index]
240+
print(" -- Creating new mesh at time point: %s (%s) " % (index, value))
241+
curr_points_dict = all_points[index]
157242

158-
print("Plotting %i points with %i types" % (len(curr_points), len(curr_types)))
243+
print(" Plotting %i point types" % (len(curr_points_dict)))
159244

160-
if last_mesh is None:
161-
last_mesh = pv.PolyData(curr_points)
162-
last_mesh["types"] = curr_types
163-
last_mesh.translate((0, -1000, 0), inplace=True)
164-
print(last_mesh)
245+
for type_, curr_points in curr_points_dict.items():
246+
color, info, size = get_color_info_for_type(type_)
247+
is_boundary = "boundary" in info
248+
if show_boundary is False and is_boundary:
249+
continue
165250

166-
# last_actor =
167-
plotter.add_mesh(
168-
last_mesh,
169-
render_points_as_spheres=True,
170-
cmap=[c for c in color_range.values()],
171-
point_size=point_size,
251+
print(
252+
" - Plotting %i points of type '%s' (%s), color: %s, size: %i"
253+
% (len(curr_points), type_, info, color, size)
172254
)
173-
else:
174-
last_mesh.points = curr_points
175-
last_mesh.translate((offset_, -50, -100), inplace=True)
255+
256+
if len(curr_points) == 0:
257+
continue
258+
if type_ not in last_meshes:
259+
last_meshes[type_] = pv.PolyData(curr_points)
260+
last_meshes[type_].translate((0, 0, 0), inplace=True)
261+
262+
# last_actor =
263+
plotter.add_mesh(
264+
last_meshes[type_],
265+
render_points_as_spheres=True,
266+
point_size=size,
267+
color=color,
268+
)
269+
else:
270+
if not is_boundary:
271+
last_meshes[type_].points = curr_points
272+
last_meshes[type_].translate((offset_, 0, 0), inplace=True)
273+
else:
274+
print("Boundary points not translated")
176275

177276
plotter.render()
178-
time.sleep(0.1)
277+
# time.sleep(0.1)
179278

180279
return
181280

@@ -184,6 +283,7 @@ def create_mesh(step):
184283
plotter = pv.Plotter()
185284

186285
position_file = "buffers/position_buffer.txt" # can be overwritten by arg
286+
report_file = None
187287

188288
if not os.path.isfile(position_file):
189289
position_file = (
@@ -198,14 +298,25 @@ def create_mesh(step):
198298
print("Run with -b to display boundary box")
199299

200300
if len(sys.argv) > 1 and os.path.isfile(sys.argv[1]):
201-
position_file = sys.argv[1]
301+
if "json" in sys.argv[1]:
302+
position_file = None
303+
report_file = sys.argv[1]
304+
else:
305+
position_file = sys.argv[1]
202306

203307
add_sibernetic_model(
204-
plotter, position_file, swap_y_z=True, include_boundary=include_boundary
308+
plotter,
309+
position_file,
310+
report_file,
311+
swap_y_z=True,
312+
include_boundary=include_boundary,
205313
)
206314
plotter.set_background("white")
207315
plotter.add_axes()
208-
# plotter.set_viewup([0, 0, 10])
316+
plotter.camera_position = "zx"
317+
plotter.camera.roll = 90
318+
plotter.camera.elevation = 45
319+
print(plotter.camera_position)
209320

210321
if "-nogui" not in sys.argv:
211322
plotter.show()

0 commit comments

Comments
 (0)