|
| 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