Skip to content

Commit c7fb254

Browse files
authored
Introduce an example of a custom message handler (#569)
1 parent f4e90d4 commit c7fb254

File tree

1 file changed

+99
-0
lines changed

1 file changed

+99
-0
lines changed

examples/MessageHandler.py

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
import Sofa
2+
import Sofa.Helper
3+
4+
RED = "\033[31m"
5+
ORANGE = "\033[38;5;214m"
6+
GREEN = "\033[32m"
7+
RESET = "\033[0m"
8+
9+
10+
class ExempleMessageHandler(Sofa.Helper.MessageHandler):
11+
"""A custom message handler that prints messages in the console and counts the number of errors, warnings and infos."""
12+
13+
def __init__(self):
14+
super().__init__()
15+
self.num_errors = 0
16+
self.num_warnings = 0
17+
self.num_infos = 0
18+
19+
def process(self, msg):
20+
"""Prints the message in the console and count the number of errors, warnings and infos."""
21+
if msg["type"] == "Error":
22+
self.print_error(msg["sender"], msg["message"])
23+
self.num_errors += 1
24+
elif msg["type"] == "Warning":
25+
self.print_warning(msg["sender"], msg["message"])
26+
self.num_warnings += 1
27+
elif msg["type"] == "Info":
28+
self.print_info(msg["sender"], msg["message"])
29+
self.num_infos += 1
30+
else:
31+
print(f"{msg["type"]} {msg['message']}")
32+
33+
@staticmethod
34+
def print_error(sender, message):
35+
"""Prints a string with [ERROR] in red"""
36+
print(f"🚨{RED}[ERROR]{RESET} [👤{sender}] 📨{message}")
37+
38+
@staticmethod
39+
def print_warning(sender, message):
40+
"""Prints a string with [WARNING] in orange"""
41+
print(f"⚠️{ORANGE}[WARNING]{RESET} [👤{sender}] 📨{message}")
42+
43+
@staticmethod
44+
def print_info(sender, message):
45+
"""Prints a string with [INFO] in green"""
46+
print(f"ℹ️{GREEN}[INFO]{RESET} [👤{sender}] 📨{message}")
47+
48+
49+
with ExempleMessageHandler() as msg_handler:
50+
def createScene(root):
51+
52+
root.addObject("RequiredPlugin", pluginName=[
53+
'Sofa.Component.Constraint.Projective',
54+
'Sofa.Component.Engine.Select',
55+
'Sofa.Component.LinearSolver.Direct',
56+
'Sofa.Component.Mass',
57+
'Sofa.Component.ODESolver.Backward',
58+
'Sofa.Component.SolidMechanics.FEM.Elastic',
59+
'Sofa.Component.StateContainer',
60+
'Sofa.Component.Topology.Container.Grid',
61+
'Sofa.Component.Visual'
62+
])
63+
64+
root.addObject('VisualStyle', displayFlags="showBehaviorModels showForceFields")
65+
66+
root.addObject('DefaultAnimationLoop')
67+
root.addObject('DefaultVisualManagerLoop')
68+
69+
root.addObject('EulerImplicitSolver', rayleighStiffness=0.1, rayleighMass=0.1, printLog=False)
70+
root.addObject('SparseLDLSolver', template="CompressedRowSparseMatrixd")
71+
72+
root.addObject('MechanicalObject', name="DoFs")
73+
root.addObject('MeshMatrixMass', name="mass", totalMass=320)
74+
root.addObject('RegularGridTopology', name="grid",
75+
nx=4, ny=4, nz=20, xmin=-9, xmax=-6, ymin=0, ymax=3, zmin=0, zmax=19)
76+
root.addObject('BoxROI', name="box", box=[-10, -1, -0.0001, -5, 4, 0.0001])
77+
root.addObject('FixedProjectiveConstraint', indices="@box.indices")
78+
root.addObject('HexahedronFEMForceField', name="FEM", youngModulus=4000, poissonRatio=0.3, method="large")
79+
80+
return root
81+
82+
83+
def main():
84+
root = Sofa.Core.Node("root")
85+
createScene(root)
86+
Sofa.Simulation.initRoot(root)
87+
88+
for iteration in range(10):
89+
Sofa.Simulation.animate(root, root.dt.value)
90+
91+
print("Simulation is done.")
92+
93+
print(f"Number of errors: {msg_handler.num_errors}")
94+
print(f"Number of warnings: {msg_handler.num_warnings}")
95+
print(f"Number of infos: {msg_handler.num_infos}")
96+
97+
98+
if __name__ == '__main__':
99+
main()

0 commit comments

Comments
 (0)